int TestUnitReady ( void ) { // to be returned by this function int iRetCode; // instantiate the SRB appropriate for SC_EXEC_SCSI_CMD SRB_ExecSCSICmd srbExec; // start filling it with all zeroes memset ( &srbExec, 0, sizeof ( SRB_ExecSCSICmd ) ); // ASPI command code srbExec . SRB_Cmd = SC_EXEC_SCSI_CMD; // specify the host adapter number, as assigned by the ASPI manager srbExec . SRB_HaId = Adap_Id; // SC_EXEC_SCSI_CMD is an asynchronous ASPI command, so the function // returns immediately, and the event notify method is chosen to signal // the command completion to the application program srbExec . SRB_Flags = SRB_EVENT_NOTIFY; // SCSI2 device id of the target (LUN left to zero) srbExec . SRB_Target = myDevice_Id; // SENSE_LEN is defined into WNASPI32.H srbExec . SRB_SenseLen = SENSE_LEN; // CDB is the SCSI2 Command Descriptor Block (not to be confused with the // SRB); 6 is the lenght of the SCSI2 command, TestUnitReady in this case srbExec . SRB_CDBLen = 6; // this assigns the handle to the event notification object srbExec . SRB_PostProc = ( LPVOID ) hEventSRB; // TestUnitReady is a 6 bytes long SCSI2 command, that have ben set to zero // by the above memset; the first byte is the SCSI2 command code srbExec . CDBByte [ 0 ] = SCSI_TST_U_RDY; // reset the event notification object ResetEvent ( hEventSRB ); // finally call the ASPI function pfnSendASPI32Command ( ( LPSRB ) &srbExec ); // if the command returns immediately with a SS_PENDING state it is // time to wait for a single object if ( srbExec . SRB_Status == SS_PENDING ) WaitForSingleObject ( hEventSRB, INFINITE ); // the event has been signalled: test the ASPI status byte if ( srbExec.SRB_Status == SS_COMP ) iRetCode = 0; // OK // check what happened (sense data automatically returned in the SenseArea) else { SenseKey = srbExec . SenseArea [ 2 ]; SenseKey = SenseKey & 15; ASC = srbExec . SenseArea [ 12 ]; ASCQ = srbExec . SenseArea [ 13 ]; AddToLogFile ( "TestUnitReady ", SenseKey, ASC, ASCQ ); switch ( SenseKey ) { case 0x01: iRetCode = 0; // not a good practice, but OK... break; case 0x06: // Power On reset or Bus Device reset if ( ASC == 0x29 && ASCQ == 0x00 ) { iRetCode = 1; break; } default: DisplayStatus ( "TestUnitReady", srbExec . SRB_Status, srbExec . SRB_HaStat, srbExec . SRB_TargStat ); iRetCode = 99; } } return iRetCode; }