⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 aspi_hlio.cpp

📁 PS2游戏硬盘直灌(HDL)的Windows下VC的源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* * 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 + -