Вот я тут маленько наэксперементировался - у меня все прекрасно работает:
Wnaspi32:
| Код | unit wnaspi32; //unit wnaspi32.h version ?.?? //translation version 1.0 //compatible with Delphi 2.0-4.0 //by daNIL,danila@starlab.ifmo.ru //please, send me any comments or suggestions //about this file
(**************************************************************************** * * * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY * * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * * IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR * * PURPOSE. * * * * Copyright (C) 1993-95 Microsoft Corporation. All Rights Reserved. * * * ****************************************************************************)
//*************************************************************************** // // Name: WNASPI32.H // // Description: ASPI for Win32 definitions ('C' Language) // //***************************************************************************
interface
uses Windows;
//typedef void *LPSRB; //typedef void (*PFNPOST)();??????? type LPSRB = Pointer;
function SendASPI32Command(LPSRB:Pointer):DWORD;cdecl; function GetASPI32SupportInfo:DWORD;cdecl;
const
SENSE_LEN = 14; // Default sense buffer length
SRB_DIR_SCSI = $00; // Direction determined by SCSI command SRB_DIR_IN = $08; // Transfer from SCSI target to host SRB_DIR_OUT = $10; // Transfer from host to SCSI target SRB_POSTING = $01; // Enable ASPI posting SRB_EVENT_NOTIFY = $40; // Enable ASPI event notification SRB_ENABLE_RESIDUAL_COUNT = $04; // Enable residual byte count reporting SRB_DATA_SG_LIST = $02; // Data buffer points to scatter-gather list
WM_ASPIPOST = $4D42; // ASPI Post message
//*************************************************************************** // %%% ASPI Command Definitions %%% //***************************************************************************
SC_HA_INQUIRY = $00; // Host adapter inquiry SC_GET_DEV_TYPE = $01; // Get device type SC_EXEC_SCSI_CMD = $02; // Execute SCSI command SC_ABORT_SRB = $03; // Abort an SRB SC_RESET_DEV = $04; // SCSI bus device reset SC_GET_DISK_INFO = $06; // Get Disk information
//*************************************************************************** // %%% SRB Status %%% //***************************************************************************
SS_PENDING = $00; // SRB being processed SS_COMP = $01; // SRB completed without error SS_ABORTED = $02; // SRB aborted SS_ABORT_FAIL = $03; // Unable to abort SRB SS_ERR = $04; // SRB completed with error
SS_INVALID_CMD = $80; // Invalid ASPI command SS_INVALID_HA = $81; // Invalid host adapter number SS_NO_DEVICE = $82; // SCSI device not installed
SS_INVALID_SRB = $E0; // Invalid parameter set in SRB SS_FAILED_INIT = $E4; // ASPI for windows failed init SS_ASPI_IS_BUSY = $E5; // No resources available to execute cmd SS_BUFFER_TO_BIG = $E6; // Buffer size to big to handle!
//*************************************************************************** // %%% Host Adapter Status %%% //***************************************************************************
HASTAT_OK = $00; // Host adapter did not detect an // error HASTAT_SEL_TO = $11; // Selection Timeout HASTAT_DO_DU = $12; // Data overrun data underrun HASTAT_BUS_FREE = $13; // Unexpected bus free HASTAT_PHASE_ERR = $14; // Target bus phase sequence // failure HASTAT_TIMEOUT = $09; // Timed out while SRB was waiting to beprocessed. HASTAT_COMMAND_TIMEOUT = $0B; // While processing the SRB, the // adapter timed out. HASTAT_MESSAGE_REJECT = $0D; // While processing SRB, the // adapter received a MESSAGE // REJECT. HASTAT_BUS_RESET = $0E; // A bus reset was detected. HASTAT_PARITY_ERROR = $0F; // A parity error was detected. HASTAT_REQUEST_SENSE_FAILED = $10; // The adapter failed in issuing // REQUEST SENSE.
//*************************************************************************** // %%% SRB - HOST ADAPTER INQUIRY - SC_HA_INQUIRY %%% //*************************************************************************** type
SRB_HAInquiry = record SRB_Cmd, // ASPI command code = SC_HA_INQUIRY SRB_Status, // ASPI command status byte SRB_HaId, // ASPI host adapter number SRB_Flags:BYTE; // ASPI request flags SRB_Hdr_Rsvd:DWORD; // Reserved, MUST = 0 HA_Count, // Number of host adapters present HA_SCSI_ID, // SCSI ID of host adapter HA_ManagerId, // String describing the manager HA_Identifier, // String describing the host adapter HA_Unique:array[0..15]of byte; // Host Adapter Unique parameters HA_Rsvd1:WORD; end;
PSRB_HAInquiry = ^SRB_HAInquiry; TSRB_HAInquiry = SRB_HAInquiry;
//*************************************************************************** // %%% SRB - GET DEVICE TYPE - SC_GET_DEV_TYPE %%% //*************************************************************************** SRB_GDEVBlock = record SRB_Cmd, // ASPI command code = SC_GET_DEV_TYPE SRB_Status, // ASPI command status byte SRB_HaId, // ASPI host adapter number SRB_Flags:BYTE; // Reserved SRB_Hdr_Rsvd:DWORD; // Reserved SRB_Target, // Target's SCSI ID SRB_Lun, // Target's LUN number SRB_DeviceType, // Target's peripheral device type SRB_Rsvd1:BYTE; end;
TSRB_GDEVBlock = SRB_GDEVBlock; PSRB_GDEVBlock = ^SRB_GDEVBlock;
//*************************************************************************** // %%% SRB - EXECUTE SCSI COMMAND - SC_EXEC_SCSI_CMD %%% //***************************************************************************
SRB_ExecSCSICmd = record SRB_Cmd, // ASPI command code = SC_EXEC_SCSI_CMD SRB_Status, // ASPI command status byte SRB_HaId, // ASPI host adapter number SRB_Flags:BYTE; // ASPI request flags SRB_Hdr_Rsvd:DWORD; // Reserved SRB_Target, // Target's SCSI ID SRB_Lun:BYTE; // Target's LUN number SRB_Rsvd1:WORD; // Reserved for Alignment SRB_BufLen:DWORD; // Data Allocation Length SRB_BufPointer:Pointer; // Data Buffer Pointer SRB_SenseLen, // Sense Allocation Length SRB_CDBLen, // CDB Length SRB_HaStat, // Host Adapter Status SRB_TargStat:BYTE; // Target Status SRB_PostProc, // Post routine SRB_Rsvd2:Pointer; // Reserved SRB_Rsvd3, // Reserved for alignment CDBByte:array[0..15]of byte; // SCSI CDB SenseArea:array[0..SENSE_LEN+1]of byte; // Request Sense buffer end;
TSRB_ExecSCSICmd = SRB_ExecSCSICmd; PSRB_ExecSCSICmd = ^SRB_ExecSCSICmd;
//*************************************************************************** // %%% SRB - ABORT AN SRB - SC_ABORT_SRB %%% //*************************************************************************** SRB_Abort = record SRB_Cmd, // ASPI command code = SC_EXEC_SCSI_CMD SRB_Status, // ASPI command status byte SRB_HaId, // ASPI host adapter number SRB_Flags:BYTE; // Reserved SRB_Hdr_Rsvd:DWORD; // Reserved SRB_ToAbort:Pointer; // Pointer to SRB to abort end;
TSRB_Abort = SRB_Abort; PSRB_Abort = ^SRB_Abort;
//*************************************************************************** // %%% SRB - BUS DEVICE RESET - SC_RESET_DEV %%% //*************************************************************************** SRB_BusDeviceReset = record SRB_Cmd, // ASPI command code = SC_EXEC_SCSI_CMD SRB_Status, // ASPI command status byte SRB_HaId, // ASPI host adapter number SRB_Flags:BYTE; // Reserved SRB_Hdr_Rsvd:DWORD; // Reserved SRB_Target, // Target's SCSI ID SRB_Lun:BYTE; // Target's LUN number SRB_Rsvd1:array[0..11]of byte; // Reserved for Alignment SRB_HaStat, // Host Adapter Status SRB_TargStat:BYTE; // Target Status SRB_PostProc, // Post routine SRB_Rsvd2:Pointer; // Reserved SRB_Rsvd3, // Reserved CDBByte:array[0..15]of byte; // SCSI CDB end;
TSRB_BusDeviceReset = SRB_BusDeviceReset; PSRB_BusDeviceReset = ^SRB_BusDeviceReset;
//*************************************************************************** // %%% SRB - GET DISK INFORMATION - SC_GET_DISK_INFO %%% //*************************************************************************** SRB_GetDiskInfo = record SRB_Cmd, // ASPI command code = SC_EXEC_SCSI_CMD SRB_Status, // ASPI command status byte SRB_HaId, // ASPI host adapter number SRB_Flags:BYTE; // Reserved SRB_Hdr_Rsvd:DWORD; // Reserved SRB_Target, // Target's SCSI ID SRB_Lun, // Target's LUN number SRB_DriveFlags, // Driver flags SRB_Int13HDriveInfo, // Host Adapter Status SRB_Heads, // Preferred number of heads translation SRB_Sectors:BYTE; // Preferred number of sectors translation SRB_Rsvd1:array[0..9]of byte; // Reserved end;
TSRB_GetDiskInfo = SRB_GetDiskInfo; PSRB_GetDiskInfo = ^SRB_GetDiskInfo;
implementation
const WNASPI = 'wnaspi32.dll';
function SendASPI32Command;external WNASPI name 'SendASPI32Command'; function GetASPI32SupportInfo;external WNASPI name 'GetASPI32SupportInfo';
end. |
Прога:
| Код | type TCDOperation = (cdoStop, cdoResume, cdoEject, cdoInject);
function CDOperation(Adapter, Target: Byte; Operation: TCDOperation): byte; const CDROM_OP = $1B; var Exec: SRB_ExecSCSICmd; hEventASPI: THandle; dwStatus: DWORD; i: integer; begin Result := 0; ZeroMemory(@Exec, SizeOf(SRB_ExecSCSICmd)); with Exec do begin SRB_Cmd := SC_EXEC_SCSI_CMD; SRB_HaId := Adapter; SRB_Target := Target; SRB_Flags := SRB_DIR_OUT or SRB_EVENT_NOTIFY; SRB_SenseLen := SENSE_LEN; SRB_PostProc := Pointer(hEventASPI); SRB_CDBLen := 12; CDBByte[0] := CDROM_OP; CDBByte[1] := $00; CDBByte[4] := Byte(Operation); end; hEventASPI := CreateEvent(nil, True, False, nil); ResetEvent(hEventASPI); dwStatus := SendASPI32Command(@Exec); if dwStatus = SS_COMP then CloseHandle(hEventASPI); if dwStatus = SS_PENDING then if WaitForSingleObject(hEventASPI, INFINITE) <> WAIT_TIMEOUT then CloseHandle(hEventASPI);
Result := Exec.SRB_Status; end;
procedure TForm1.FormCreate(Sender: TObject); const DTYPE_CDROM = 5; type //В модуле не правильно определена данная структура, поэтому я ее маленько подправил SRB_HAInquiry = record SRB_Cmd, // ASPI command code = SC_HA_INQUIRY SRB_Status, // ASPI command status byte SRB_HaId, // ASPI host adapter number SRB_Flags:BYTE; // ASPI request flags SRB_Hdr_Rsvd:DWORD; // Reserved, MUST = 0 HA_Count, // Number of host adapters present HA_SCSI_ID: BYTE; // SCSI ID of host adapter HA_ManagerId, // String describing the manager HA_Identifier, // String describing the host adapter HA_Unique:array[0..15]of byte; // Host Adapter Unique parameters HA_Rsvd1:WORD; end; var haInq: SRB_HAInquiry; dwStatus, dwGetASPI: DWORD; byNumDevice, Target: Byte; i, j: integer; devType: SRB_GDEVBlock; begin dwGetASPI := GetASPI32SupportInfo; case LongRec(dwGetASPI).Bytes[3] of SS_COMP: byNumDevice := LongRec(dwGetASPI).Bytes[0]; SS_FAILED_INIT: begin MessageDlg('Óñòðîéñòâ íå îáíàðóæåíî!', mtConfirmation, [mbOk], 0); Exit; end; end; ZeroMemory(@haInq, SizeOf(SRB_HAInquiry)); haInq.SRB_Cmd := SC_HA_INQUIRY; dwStatus := SendASPI32Command(@haInq); while not Boolean(haInq.SRB_Status) do Application.ProcessMessages;
if dwStatus = SS_COMP then begin Target := haInq.HA_Count; end;
for i := 0 to byNumDevice - 1 do begin for j := 0 to Target - 1 do begin ZeroMemory(@devType, SizeOf(SRB_GDEVBlock)); devType.SRB_Cmd := SC_GET_DEV_TYPE; devType.SRB_HaId := i; devType.SRB_Target := j; SendASPI32Command(@DevType); if devType.SRB_Status <> SS_COMP then continue; if devType.SRB_DeviceType = DTYPE_CDROM then CDOperation(i, j, cdoResume); end; end; end; | |