123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501 |
- #include <stdio.h>
- #include <stddef.h>
- #include "NTScsi.h"
- typedef struct {
- BYTE ha;
- BYTE tgt;
- BYTE lun;
- BYTE driveLetter;
- BOOL bUsed;
- HANDLE hDevice;
- BYTE inqData[36];
- } NTSCSIDRIVE;
- typedef struct
- {
- BYTE numAdapters;
- NTSCSIDRIVE drive[26];
- } NTSCSIDRIVES;
- void GetDriveInformation( BYTE i, NTSCSIDRIVE *pDrive );
- static HANDLE GetFileHandle( BYTE i );
- static BOOL bNtScsiAvailable = FALSE;
- static NTSCSIDRIVES NtScsiDrives;
- static BOOL bUseNtScsi = FALSE;
- int NtScsiInit( void )
- {
- BYTE i;
- wchar_t buf[4] = {0};
- UINT uDriveType;
- int retVal = 0;
- if ( bNtScsiAvailable )
- {
- for( i = 2; i < 26; i++ ) if ( NtScsiDrives.drive[i].bUsed ) retVal++;
- bUseNtScsi = (retVal > 0 );
- return retVal;
- }
- memset( &NtScsiDrives, 0x00, sizeof(NtScsiDrives) );
- for( i = 0; i < 26; i++ )
- {
- NtScsiDrives.drive[i].hDevice = INVALID_HANDLE_VALUE;
- }
- for( i = 2; i < 26; i++ )
- {
- wsprintf( buf, L"%c:\\", (wchar_t)('A'+i) );
- uDriveType = GetDriveType( buf );
-
- if ( uDriveType == DRIVE_CDROM )
- {
- GetDriveInformation( i, &NtScsiDrives.drive[i] );
- if ( NtScsiDrives.drive[i].bUsed )
- retVal++;
- }
- }
- NtScsiDrives.numAdapters = NtScsiGetNumAdapters( );
- bNtScsiAvailable = TRUE;
- if ( retVal > 0 )
- {
- bUseNtScsi = TRUE;
- }
- return retVal;
- }
- int NtScsiDeInit( void )
- {
- BYTE i;
- if ( !bNtScsiAvailable )
- return 0;
- for( i = 2; i < 26; i++ )
- {
- if ( NtScsiDrives.drive[i].bUsed )
- {
- CloseHandle( NtScsiDrives.drive[i].hDevice );
- }
- }
- NtScsiDrives.numAdapters = NtScsiGetNumAdapters( );
- ZeroMemory( &NtScsiDrives, sizeof(NtScsiDrives) );
- bNtScsiAvailable = FALSE;
- return -1;
- }
- BYTE NtScsiGetNumAdapters( void )
- {
- BYTE buf[256] = {0};
- WORD i;
- BYTE numAdapters = 0;
-
-
-
- buf[0] = 1;
- for( i = 0; i < 26; i++ )
- {
- if ( NtScsiDrives.drive[i].bUsed )
- buf[NtScsiDrives.drive[i].ha] = 1;
- }
- for( i = 0; i <= 255; i++ )
- {
- if ( buf[i] )
- numAdapters++;
- }
- return numAdapters;
- }
- DWORD NtScsiGetASPI32SupportInfo( void )
- {
- DWORD retVal;
- if ( !NtScsiDrives.numAdapters )
- retVal = (DWORD)(MAKEWORD(0,SS_NO_ADAPTERS));
- else
- retVal = (DWORD)(MAKEWORD(NtScsiDrives.numAdapters,SS_COMP));
- return retVal;
- }
- DWORD NtScsiSendASPI32Command( LPSRB lpsrb )
- {
- if ( !lpsrb )
- return SS_ERR;
- switch( lpsrb->SRB_Cmd )
- {
- case SC_HA_INQUIRY:
- return NtScsiHandleHaInquiry( (LPSRB_HAINQUIRY)lpsrb );
- break;
- case SC_GET_DEV_TYPE:
- return NtScsiGetDeviceType( (LPSRB_GDEVBLOCK)lpsrb );
- break;
- case SC_EXEC_SCSI_CMD:
- return NtScsiExecSCSICommand( (LPSRB_EXECSCSICMD)lpsrb, FALSE );
- break;
- case SC_RESET_DEV:
- default:
- lpsrb->SRB_Status = SS_ERR;
- return SS_ERR;
- break;
- }
- return SS_ERR;
- }
- static HANDLE GetFileHandle( BYTE i )
- {
- wchar_t buf[12] = {0};
- HANDLE fh = NULL;
- OSVERSIONINFO osver;
- DWORD dwFlags;
- memset( &osver, 0x00, sizeof(osver) );
- osver.dwOSVersionInfoSize = sizeof(osver);
- GetVersionEx( &osver );
-
- dwFlags = GENERIC_READ;
- if ( (osver.dwPlatformId == VER_PLATFORM_WIN32_NT) && (osver.dwMajorVersion > 4) )
- {
- dwFlags |= GENERIC_WRITE;
- }
- wsprintf( buf, L"\\\\.\\%c:", (wchar_t)('A'+i) );
- fh = CreateFile( buf, dwFlags, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,OPEN_EXISTING, 0, NULL );
- if ( fh == INVALID_HANDLE_VALUE )
- {
-
- dwFlags ^= GENERIC_WRITE;
- fh = CreateFile( buf, dwFlags, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL );
- }
- if ( fh == INVALID_HANDLE_VALUE )
- {
- }
- else
- {
- }
- return fh;
- }
- void GetDriveInformation( BYTE i, NTSCSIDRIVE *pDrive )
- {
- HANDLE fh;
- char buf[2048] = {0};
- BOOL status;
- PSCSI_PASS_THROUGH_DIRECT_WITH_BUFFER pswb;
- PSCSI_ADDRESS pscsiAddr;
- ULONG length, returned;
- BYTE inqData[100] = {0};
- fh = GetFileHandle( i );
- if ( fh == INVALID_HANDLE_VALUE )
- {
- return;
- }
-
- ZeroMemory( &buf, 2048 );
- ZeroMemory( inqData, 100 );
- pswb = (PSCSI_PASS_THROUGH_DIRECT_WITH_BUFFER)buf;
- pswb->spt.Length = sizeof(SCSI_PASS_THROUGH_DIRECT);
- pswb->spt.CdbLength = 6;
- pswb->spt.SenseInfoLength = 24;
- pswb->spt.DataIn = SCSI_IOCTL_DATA_IN;
- pswb->spt.DataTransferLength = 100;
- pswb->spt.TimeOutValue = 2;
- pswb->spt.DataBuffer = inqData;
- pswb->spt.SenseInfoOffset = offsetof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER,ucSenseBuf );
- pswb->spt.Cdb[0] = 0x12;
- pswb->spt.Cdb[4] = 100;
- length = sizeof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER);
- status = DeviceIoControl( fh,
- IOCTL_SCSI_PASS_THROUGH_DIRECT,
- pswb,
- length,
- pswb,
- length,
- &returned,
- NULL );
- if ( !status )
- {
- CloseHandle( fh );
- return;
- }
- memcpy( pDrive->inqData, inqData, 36 );
-
- ZeroMemory( &buf, 2048 );
- pscsiAddr = (PSCSI_ADDRESS)buf;
- pscsiAddr->Length = sizeof(SCSI_ADDRESS);
- if ( DeviceIoControl( fh, IOCTL_SCSI_GET_ADDRESS, NULL, 0,
- pscsiAddr, sizeof(buf), &returned,
- NULL ) )
- {
- pDrive->bUsed = TRUE;
- pDrive->ha = pscsiAddr->PortNumber;
- pDrive->tgt = pscsiAddr->TargetId;
- pDrive->lun = pscsiAddr->Lun;
- pDrive->driveLetter = i;
- pDrive->hDevice = INVALID_HANDLE_VALUE;
- }
- else if (50 == GetLastError())
- {
- pDrive->bUsed = TRUE;
- pDrive->ha = i;
- pDrive->tgt = 0;
- pDrive->lun = 0;
- pDrive->driveLetter = i;
- pDrive->hDevice = INVALID_HANDLE_VALUE;
- }
- else
- {
- pDrive->bUsed = FALSE;
- }
- CloseHandle( fh );
- }
- DWORD NtScsiHandleHaInquiry( LPSRB_HAINQUIRY lpsrb )
- {
- DWORD *pMTL;
- lpsrb->HA_Count = NtScsiDrives.numAdapters;
- if ( lpsrb->SRB_HaId >= NtScsiDrives.numAdapters )
- {
- lpsrb->SRB_Status = SS_INVALID_HA;
- return SS_INVALID_HA;
- }
- lpsrb->HA_SCSI_ID = 7;
- memcpy( lpsrb->HA_ManagerId, "blahblahblahblah", 16 );
- memcpy( lpsrb->HA_Identifier, "blahblahblahblah", 16 );
- lpsrb->HA_Identifier[13] = (char)('0'+lpsrb->SRB_HaId);
- ZeroMemory( lpsrb->HA_Unique, 16 );
- lpsrb->HA_Unique[3] = 8;
- pMTL = (LPDWORD)&lpsrb->HA_Unique[4];
- *pMTL = 64 * 1024;
- lpsrb->SRB_Status = SS_COMP;
- return SS_COMP;
- }
- DWORD NtScsiGetDeviceType( LPSRB_GDEVBLOCK lpsrb )
- {
- lpsrb->SRB_Status = SS_NO_DEVICE;
- if ( NtScsiGetDeviceIndex( lpsrb->SRB_HaId, lpsrb->SRB_Target, lpsrb->SRB_Lun ) )
- lpsrb->SRB_Status = SS_COMP;
- if ( lpsrb->SRB_Status == SS_COMP )
- lpsrb->SRB_DeviceType = DTC_CDROM;
- else
- lpsrb->SRB_DeviceType = DTC_UNKNOWN;
- return lpsrb->SRB_Status;
- }
- BYTE NtScsiGetDeviceIndex( BYTE ha, BYTE tgt, BYTE lun )
- {
- BYTE i;
- for( i = 2; i < 26; i++ )
- {
- if ( NtScsiDrives.drive[i].bUsed )
- {
- NTSCSIDRIVE *lpd;
- lpd = &NtScsiDrives.drive[i];
- if ( (lpd->ha == ha) && (lpd->tgt == tgt) && (lpd->lun == lun) )
- return i;
- }
- }
- return 0;
- }
- DWORD NtScsiExecSCSICommand( LPSRB_EXECSCSICMD lpsrb, BOOL bBeenHereBefore )
- {
- BOOL status;
- SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER swb;
- ULONG length, returned;
- BYTE idx;
- idx = NtScsiGetDeviceIndex( lpsrb->SRB_HaId, lpsrb->SRB_Target, lpsrb->SRB_Lun );
- if ( idx == 0 )
- {
- lpsrb->SRB_Status = SS_ERR;
- return SS_ERR;
- }
- if ( lpsrb->CDBByte[0] == 0x12 )
- {
- lpsrb->SRB_Status = SS_COMP;
- memcpy( lpsrb->SRB_BufPointer, NtScsiDrives.drive[idx].inqData, 36 );
- return SS_COMP;
- }
- if ( NtScsiDrives.drive[idx].hDevice == INVALID_HANDLE_VALUE )
- NtScsiDrives.drive[idx].hDevice = GetFileHandle( NtScsiDrives.drive[idx].driveLetter );
- ZeroMemory( &swb, sizeof(swb) );
- swb.spt.Length = sizeof(SCSI_PASS_THROUGH);
- swb.spt.CdbLength = lpsrb->SRB_CDBLen;
- if ( lpsrb->SRB_Flags & SRB_DIR_IN )
- swb.spt.DataIn = SCSI_IOCTL_DATA_IN;
- else if ( lpsrb->SRB_Flags & SRB_DIR_OUT )
- swb.spt.DataIn = SCSI_IOCTL_DATA_OUT;
- else
- swb.spt.DataIn = SCSI_IOCTL_DATA_UNSPECIFIED;
- swb.spt.DataTransferLength = lpsrb->SRB_BufLen;
- swb.spt.TimeOutValue = 5;
- swb.spt.DataBuffer = lpsrb->SRB_BufPointer;
- swb.spt.SenseInfoOffset =
- offsetof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER, ucSenseBuf );
- memcpy( swb.spt.Cdb, lpsrb->CDBByte, lpsrb->SRB_CDBLen );
- length = sizeof(swb);
- status = DeviceIoControl( NtScsiDrives.drive[idx].hDevice,
- IOCTL_SCSI_PASS_THROUGH_DIRECT,
- &swb,
- length,
- &swb,
- length,
- &returned,
- NULL );
- if ( status )
- {
- lpsrb->SRB_Status = SS_COMP;
- }
- else
- {
- DWORD dwErrCode;
- lpsrb->SRB_Status = SS_ERR;
- lpsrb->SRB_TargStat = 0x0004;
- dwErrCode = GetLastError();
-
- if ( !bBeenHereBefore &&
- ((dwErrCode == ERROR_MEDIA_CHANGED) || (dwErrCode == ERROR_INVALID_HANDLE)) )
- {
- if ( dwErrCode != ERROR_INVALID_HANDLE )
- CloseHandle( NtScsiDrives.drive[idx].hDevice );
- GetDriveInformation( idx, &NtScsiDrives.drive[idx] );
- return NtScsiExecSCSICommand( lpsrb, TRUE );
- }
- }
- return lpsrb->SRB_Status;
- }
- BOOL UsingSCSIPT( void )
- {
- return bUseNtScsi;
- }
- void NtScsiOpenCDHandle( BYTE ha, BYTE tgt, BYTE lun )
- {
- BYTE idx;
- idx = NtScsiGetDeviceIndex( ha, tgt, lun );
- if ( idx && NtScsiDrives.drive[idx].hDevice == INVALID_HANDLE_VALUE )
- NtScsiDrives.drive[idx].hDevice = GetFileHandle( NtScsiDrives.drive[idx].driveLetter );
- }
|