?? aspi_hlio.cpp
字號:
/* * aspi_hlio.c - ASPI high-level I/O * $Id: aspi_hlio.c,v 1.4 2004/12/04 10:20:53 b081 Exp $ * * Copyright 2004 Bobi B., w1zard0f07@yahoo.com * * This file is part of hdl_dump. * * hdl_dump is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * hdl_dump is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with hdl_dump; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */#include "aspi_hlio.h"#include <windows.h>#include <stdio.h>#include <time.h>#include "wnaspi32.h"#include "osal.h"#include "retcodes.h"/* after this timeout command is aborted */#define ASPI_TIMEOUT_IN_SEC 10/* types */typedef DWORD (*aspi_send_cmd_t) (LPSRB srb);typedef DWORD (*aspi_get_info_t) (void);/* globals */static int aspi_initialized = 0; /* reference counter */static HMODULE aspi_lib = NULL;static aspi_send_cmd_t aspi_send_cmd;static aspi_get_info_t aspi_get_info;/* NOTICE: those are not thread-safe */static int err_srb_status = 0, err_sense = 0, err_asc = 0, err_ascq = 0;/**************************************************************/static voidaspi_set_last_error (int srb_status, int sense_key, int asc, int ascq){ /* NOTICE: that is not thread-safe */ err_srb_status = srb_status; err_sense = sense_key; err_asc = asc; err_ascq = ascq;}/**************************************************************/static voidcopy_and_reduce_spaces (char *out, const char *in){ int last_were_space = 0; while (*in != '\0') { if (*in == ' ') { if (last_were_space) ++in; else *out++ = *in++; last_were_space = 1; } else { *out++ = *in++; last_were_space = 0; } } if (last_were_space) --out; *out = '\0';}/**************************************************************/intaspi_load (void){ int result; if (aspi_initialized) { ++aspi_initialized; return (RET_OK); }#if 0 /* try loading both sequentially */ aspi_lib = LoadLibrary ("WNASPINT.DLL"); if (aspi_lib == NULL)#endif aspi_lib = LoadLibrary ("WNASPI32.DLL"); if (aspi_lib != NULL) { aspi_send_cmd = (aspi_send_cmd_t) GetProcAddress (aspi_lib, "SendASPI32Command"); aspi_get_info = (aspi_get_info_t) GetProcAddress (aspi_lib, "GetASPI32SupportInfo"); if (aspi_send_cmd != NULL && aspi_get_info != NULL) { DWORD support_info = aspi_get_info (); if (HIBYTE (LOWORD (support_info)) == SS_COMP || HIBYTE (LOWORD (support_info)) == SS_NO_ADAPTERS) { result = RET_OK; aspi_initialized = 1; } else { /* give-up on error? */ result = RET_ERR; aspi_unload (); } } else { /* no such procedures in the DLL */ result = RET_ERR; aspi_unload (); } } else /* DLL not found */ result = RET_ERR; return (result);}/**************************************************************/intaspi_unload (void){ if (aspi_initialized) { --aspi_initialized; if (aspi_initialized == 0) { /* the old ASPI could crash if freed imediately after init; borrowed from don't remember where */ Sleep (200); /* unload and clean-up */ aspi_get_info = NULL; aspi_send_cmd = NULL; if (aspi_lib != NULL) { FreeLibrary (aspi_lib); aspi_lib = NULL; } return (RET_OK); } } return (RET_OK);}/**************************************************************/static intaspi_reset_device (int host, int scsi_id, int lun){ SRB_BusDeviceReset reset; int result; memset (&reset, 0, sizeof (SRB_BusDeviceReset)); reset.SRB_Cmd = SC_RESET_DEV; reset.SRB_HaId = host; reset.SRB_Target = scsi_id; reset.SRB_Lun = lun; result = aspi_send_cmd ((LPSRB) &reset); while (reset.SRB_Status == SS_PENDING) Sleep (1); if (reset.SRB_Status == SS_COMP) return (RET_OK); else { aspi_set_last_error (reset.SRB_Status, 0, 0, 0); return (RET_ERR); }}/**************************************************************/static intaspi_rescan_host (int host){ SRB_RescanPort rescan; memset (&rescan, 0, sizeof (SRB_RescanPort)); rescan.SRB_Cmd = SC_RESCAN_SCSI_BUS; rescan.SRB_HaId = host; aspi_send_cmd ((LPSRB) &rescan); if (rescan.SRB_Status == SS_COMP || rescan.SRB_Status == SS_NO_DEVICE) return (RET_OK); else { aspi_set_last_error (rescan.SRB_Status, 0, 0, 0); return (RET_ERR); }}/**************************************************************/#if 0 /* not used */static intaspi_exec (SRB_ExecSCSICmd *exec){ HANDLE event = CreateEvent (NULL, TRUE, FALSE, NULL); if (event != NULL) { /* wait for event */ exec->SRB_Flags |= SRB_EVENT_NOTIFY; exec->SRB_PostProc = (LPVOID) event; aspi_send_cmd ((LPSRB) exec); if (exec->SRB_Status == SS_PENDING) WaitForSingleObject (event, INFINITE); CloseHandle (event); } else { /* poll */ aspi_send_cmd ((LPSRB) exec); while (exec->SRB_Status == SS_PENDING) Sleep (1); /* don't 100% CPU, but Sleep (1) usually == Sleep (10) */ } /* process the result code */ if (exec->SRB_Status == SS_COMP) return (RET_OK); else { /* keep error details */ int sense = exec->SenseArea [2] & 0x0f; int asc = exec->SenseArea [12]; int ascq = exec->SenseArea [13]; aspi_set_last_error (exec->SRB_Status, sense, asc, ascq); return (RET_ERR); }}#endif/**************************************************************/static intaspi_exec_to (SRB_ExecSCSICmd *exec, DWORD timeout_in_ms){ int abort = 0; HANDLE event = CreateEvent (NULL, TRUE, FALSE, NULL); if (event != NULL) { /* wait for event */ exec->SRB_Flags |= SRB_EVENT_NOTIFY; exec->SRB_PostProc = (LPVOID) event; aspi_send_cmd ((LPSRB) exec); if (exec->SRB_Status == SS_PENDING) { DWORD ret = WaitForSingleObject (event, timeout_in_ms); if (ret == WAIT_OBJECT_0) ; /* ok; signaled before timeout has expired */ else if (ret == WAIT_TIMEOUT) abort = 1; } CloseHandle (event); } else { /* poll */ DWORD start = GetTickCount (); aspi_send_cmd ((LPSRB) exec); while (exec->SRB_Status == SS_PENDING) { DWORD elapsed = GetTickCount () - start; if (elapsed >= timeout_in_ms) { abort = 1; break; } Sleep (1); /* don't 100% CPU, but Sleep (1) usually == Sleep (10) */ } } if (abort) { /* operation should be aborted */ SRB_Abort abort; memset (&abort, 0, sizeof (SRB_Abort)); abort.SRB_Cmd = SC_ABORT_SRB; abort.SRB_HaId = exec->SRB_HaId; abort.SRB_ToAbort = (void*) exec; /* abort is synchronious - would not return until operation is aborted */ aspi_send_cmd ((LPSRB) &abort); } /* process the result code */ if (exec->SRB_Status == SS_COMP) return (RET_OK); else { /* keep error details */ int sense = exec->SenseArea [2] & 0x0f; int asc = exec->SenseArea [12]; int ascq = exec->SenseArea [13]; aspi_set_last_error (exec->SRB_Status, sense, asc, ascq); return (RET_ERR); }}/**************************************************************/static scsi_devices_list_t*aspi_dlist_alloc (void){ scsi_devices_list_t* list = (scsi_devices_list_t*) osal_alloc (sizeof (scsi_devices_list_t)); if (list != NULL) { memset (list, 0, sizeof (scsi_devices_list_t)); } return (list);}/**************************************************************/static intaspi_dlist_add (scsi_devices_list_t *list, int host, int scsi_id, int lun, int type, u_int32_t align, const char *name, u_int32_t sector_size, u_int32_t size_in_sectors){ scsi_device_t *dev; if (list->used == list->alloc) { scsi_device_t *tmp = (scsi_device_t*) osal_alloc ((list->alloc + 16) * sizeof (scsi_device_t)); if (tmp != NULL) { if (list->device != NULL) { memcpy (tmp, list->device, list->used * sizeof (scsi_device_t)); osal_free (list->device); } list->device = tmp; list->alloc += 16; } else return (RET_NO_MEM); } dev = list->device + list->used; dev->host = host; dev->scsi_id = scsi_id; dev->lun = lun; dev->type = type; dev->align = align; strcpy (dev->name, name); dev->sector_size = sector_size; dev->size_in_sectors = size_in_sectors; ++list->used; return (RET_OK);}/**************************************************************/voidaspi_dlist_free (scsi_devices_list_t *list){ if (list != NULL) { if (list->device) osal_free (list->device); osal_free (list); }}/**************************************************************/static intaspi_inquiry (int host, int scsi_id, int lun, char device_name [28 + 1]){ char buffer [37]; SRB_ExecSCSICmd exec; memset (&exec, 0, sizeof (SRB_ExecSCSICmd)); exec.SRB_Cmd = SC_EXEC_SCSI_CMD; exec.SRB_HaId = host; exec.SRB_Flags = SRB_DIR_IN; exec.SRB_Target = scsi_id; exec.SRB_Lun = lun; exec.SRB_BufLen = sizeof (buffer) - 1; exec.SRB_BufPointer = (unsigned char*) buffer; exec.SRB_SenseLen = SENSE_LEN; exec.SRB_CDBLen = 6; /* SPC-R11A.PDF, 7.5 INQUIRY command; mandatory */ exec.CDBByte [0] = SCSI_INQUIRY; exec.CDBByte [4] = sizeof (buffer) - 1; if (aspi_exec_to (&exec, ASPI_TIMEOUT_IN_SEC * 1000) == RET_OK && exec.SRB_Status == SS_COMP) { /* 8-15: vendor Id; 16-31: product Id; 32-35: product revision */ buffer [32] = '\0'; copy_and_reduce_spaces (device_name, buffer + 8); return (RET_OK); } else return (RET_ERR); /* aspi_exec_to would track error by itself */}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -