home *** CD-ROM | disk | FTP | other *** search
- /***************************************************************************/
- /*** File...........: DEV.C ***/
- /*** ***/
- /*** Description....: Generic Win32 sample how to access SCSI class ***/
- /*** drivers using user-defined IOCTLs and the ***/
- /*** IOCTL_SCSI_PASS_THROUGH ioctl. ***/
- /*** ***/
- /*** Copyright......: DMC Denmark ***/
- /*** Author.........: Thomas Nielsen (TN) ***/
- /*** Edition........: 4 ***/
- /*** ***/
- /*** Created........: 31/03-1993 ***/
- /*** Last modified..: 03/04-1993 ***/
- /*** ***/
- /*** History........: 31/03 - Creation of file ***/
- /*** 01/04 - Adding Inquiry function ***/
- /*** 02/04 - Cleaning up & adding comments ***/
- /***************************************************************************/
-
- #include <windows.h>
- #include <memory.h>
-
- #include <ntddscsi.h>
- #include <devioctl.h>
- #include <ntddscsi.h>
- #include <ntdddisk.h>
-
- typedef struct
- {
- SCSI_PASS_THROUGH sptCmd;
- UCHAR ucSenseBuf[32]; /* Allocated sense data buffer */
- UCHAR ucDataBuf[2048]; /* Allocated data buffer */
- } PASS_THROUGH_STRUCT;
-
-
-
- /*** Local prototypes ***/
-
- static DWORD Inquiry(HANDLE hDev, UCHAR *DataBuffer);
- static DWORD TestUnitReady(HANDLE hDev);
- static DWORD SendScsi (HANDLE hDev,
- UCHAR *cdb,
- int cdbLength,
- BOOL TransferDirection,
- UCHAR *buffer,
- ULONG BufSize);
-
-
-
- /***************************************************************************/
- /*** Syntax.........: TestUnitReady ***/
- /*** ***/
- /*** Scope..........: Global ***/
- /*** ***/
- /*** Description....: Returns the status of the scanner ***/
- /*** (Simply sends a SCSI TestUnitReady cdb (0x00) ***/
- /*** ***/
- /*** Parameters.....: hDev - Handle to device ***/
- /*** ***/
- /*** Return value...: SCSI status code (0,2,8) ***/
- /*** ***/
- /*** External ref...: ***/
- /***************************************************************************/
-
- static DWORD TestUnitReady(HANDLE hDev)
- {
- UCHAR cdb[6];
- memset(cdb, 0, sizeof(cdb));
-
- cdb[0] = 0x0; /* SCSI opcode for TUR = 0x00 */
-
- /* Pass the request with no data buffer, and no data transfered during */
- /* The DATA IN phase */
- return SendScsi(hDev, cdb, 6, FALSE, NULL, 0);
- }
-
-
- /***************************************************************************/
- /*** Syntax.........: Inquiry ***/
- /*** ***/
- /*** Scope..........: Global ***/
- /*** ***/
- /*** Description....: Sends an inquriy (0x12) and reads in the ***/
- /*** retuned data during the DATA IN phase. ***/
- /*** The length of the inquiry data may differ from ***/
- /*** device to device. ***/
- /*** ***/
- /*** Parameters.....: hDev - Handle to device ***/
- /*** *DataBuffer - buffer to hold the data returned ***/
- /*** ***/
- /*** Return value...: SCSI status code ***/
- /*** ***/
- /*** External ref...: ***/
- /***************************************************************************/
-
- static DWORD Inquiry(HANDLE hDev, UCHAR *DataBuffer)
- {
- UCHAR cdb[6]; /* Inquiry is a 6-bytes command */
- memset(cdb, 0, sizeof(cdb)); /* Zero the SCSI cdb */
-
- cdb[0] = 0x12; /* Inquiry SCSI op-code */
- cdb[4] = 0x24; /* Length of inquiry data */
-
- /* Pass the request to the IOCTL_SCSI_PASS_THROUGH control */
- return SendScsi(hDev, cdb, 6, TRUE, DataBuffer, 24);
- }
-
-
- /***************************************************************************/
- /*** Syntax.........: SendScsi ***/
- /*** ***/
- /*** Scope..........: Global ***/
- /*** ***/
- /*** Description....: Initializes the IOCTL_SCSI_PASS_THROGH structure, ***/
- /*** according to the TransferDirection flag and ***/
- /*** pass the request to the SCSI class driver via tha ***/
- /*** DeviceIoControl API call ***/
- /*** ***/
- /*** Parameters.....: hDev - Handle to device ***/
- /*** cdb - SCSI command block ***/
- /*** cdbLength - Length of cdb ***/
- /*** TransferDirection - Flag specifying data in/out ***/
- /*** buffer - Holds the data returned/send ***/
- /*** BufSize - size of databuffer ***/
- /*** ***/
- /*** Return value...: SCSI status code ***/
- /*** ***/
- /*** External ref...: ***/
- /***************************************************************************/
-
- static DWORD SendScsi (HANDLE hDev, UCHAR *cdb, int cdbLength, BOOL TransferDirection,
- UCHAR *buffer, ULONG BufSize)
- {
- PASS_THROUGH_STRUCT spt;
- DWORD bRc,
- cbReturnedData;
-
- memset(&spt, 0, sizeof(spt)); /* Zero the structure */
-
- /* Fill out the structure */
- spt.sptCmd.Length = sizeof(SCSI_PASS_THROUGH);
- spt.sptCmd.ScsiStatus = 0; /* We assume no error has occured (-: */
- spt.sptCmd.DataBufferOffset = spt.ucDataBuf - (UCHAR*)&spt;
- spt.sptCmd.SenseInfoOffset = spt.ucSenseBuf - (UCHAR*)&spt;
- spt.sptCmd.SenseInfoLength = sizeof(spt.ucSenseBuf);
- spt.sptCmd.PathId = 0; /* Obsolent - initialized by the class driver */
- spt.sptCmd.TargetId = 0x03; /* Also obsolent */
- spt.sptCmd.Lun = 0;
- spt.sptCmd.DataTransferLength = 2048; /* I think..... */
- spt.sptCmd.CdbLength = cdbLength;
- spt.sptCmd.TimeOutValue = 10;
- spt.sptCmd.DataIn = TransferDirection;
-
- memcpy(spt.sptCmd.Cdb, cdb, cdbLength); /* Zero SCSI cdb */
-
- /* If we want to send data during the DATA OUT phase */
- if (buffer != NULL && TransferDirection == FALSE)
- memcpy(spt.ucDataBuf, buffer, BufSize);
-
-
- /* Pass the request to the SCSI class driver using the IOCTL_SCSI */
- /* _PASS_THROUGH structure. The syntax for DeviceIoControl can */
- /* be found in the Win32 help system. */
-
- bRc = DeviceIoControl(hDev, // device handle
- IOCTL_SCSI_PASS_THROUGH, // io control code
- &spt, // input buffer
- 3048, // input buffer length
- &spt, // output buffer
- 3048, // output buffer length
- &cbReturnedData, // # bytes returned
- NULL); // synchronous call
-
-
- /* Copy the data received during the DATA IN phase to the return buffer */
- if (buffer != NULL && TransferDirection == TRUE)
- memcpy(buffer, spt.ucDataBuf, sizeof(spt.ucDataBuf));
-
- return spt.sptCmd.ScsiStatus; /* Return SCSI status code */
- }
-
- int PASCAL WinMain (
-
- HINSTANCE hinstCurrent,
- HINSTANCE hinstPrevious,
- LPSTR lpCmdLine,
- int nCmdShow)
- { /* WinMain() */
-
- HANDLE hDev;
- DWORD stat;
- UCHAR ReturnData[2048]; /* Buffer for retuned data during DATA IN phase */
-
- /* Get a handle to the Scanner device. The first found device will */
- /* be named "Scanner0", the next "Scanner1", etc. Do not use */
- /* overlapped IO control */
-
- hDev = CreateFile("\\\\.\\Scanner0", GENERIC_READ | GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
- OPEN_EXISTING, 0, NULL);
-
-
- /* If we got a valid handle to the device - the proceed.... */
- if (hDev != INVALID_HANDLE_VALUE)
- {
-
- stat = TestUnitReady(hDev);
- stat = Inquiry(hDev, ReturnData);
-
- CloseHandle(hDev);
- }
-
- return 0;
- } /* WinMain() */
-