|
|
1.1 ! root 1: This sample program consists of two parts. First, all the necessary ! 2: source code is provided to compile a Win32 sample program that sends ! 3: an IOCtl_SCSI_MINIPORT request with a custom ControlCode to the SCSI ! 4: miniport driver. Second, a detailed description is provided that ! 5: explains what changes the driver writer has to make to a SCSI ! 6: miniport driver to allow it to properly recognize and handle the ! 7: corresponding IOCtl request from the Win32 sample program. ! 8: ! 9: Part 1 - Win32 sample ! 10: ! 11: The SCSI Miniport IOCtl sample, SMPI.C, demonstrates how a Win32 ! 12: application sends a user defined IOCtl Control Code to a SCSI ! 13: miniport driver. This is a simple program that is composed of four ! 14: steps. ! 15: ! 16: Step 1, a handle is obtained to the SCSI miniport driver using the ! 17: Win32 API, CreateFile. The name of the file to be opened is ! 18: \\.\Scsi0:. As an alternative, a drive letter can be substituted for ! 19: \\.\Scsi0: (e.g. - \\.\C:). This will map to the appropriate SCSI ! 20: miniport driver that is responsible for C:. ! 21: ! 22: Step 2, the SRB_IO_CONTROL structure is filled out. The following ! 23: items must be completed : ! 24: ! 25: HeaderLength - must be the size of an SRB_IO_CONTROL structure ! 26: ControlCode - while strictly optional, this entry should be ! 27: considered mandatory. The ControlCode value is used to ! 28: further sub-divide IOCTL_SCSI_MINIPORT requests. The ! 29: contents of ControlCode are defined by the SCSI miniport ! 30: driver writer. ! 31: Length - the size of the data buffer immediately following the ! 32: SRB_IO_CONTROL structure. If no additional data buffer ! 33: is used, then this must be set to 0. ! 34: ! 35: The following items of the SRB_IO_CONTROL structure are optional : ! 36: ! 37: Signature - these 8 bytes are available to help prevent IOCtl ! 38: conflicts between various vendors ! 39: Timeout - indicates the minimum time in seconds before the ! 40: request has timed out. There is no maximum Timeout for ! 41: IOCTL_SCSI_MINIPORT. Note, for IOCTL_SCSI_PASS_THROUGH, ! 42: the maximum time out value is 108000 seconds (30 minutes). ! 43: ReturnCode - this entry is filled in by the SCSI miniport to ! 44: inform the Win32 application of the results of the ! 45: requested action. The contents of ReturnCode are defined ! 46: by the SCSI miniport Driver writer. ! 47: ! 48: In the SMPI.C sample, two customer defined ControlCodes are used, ! 49: SMP_RETURN_3F and SMP_PRINT_STRING. The first requires ! 50: no additional data buffer. The second requires that a contiguous ! 51: data buffer be appended at the end of the SRB_IO_CONTROL structure. ! 52: The ControlCodes are defined by the SCSI miniport driver (see below). ! 53: ! 54: Step 3, send the SRB_IO_CONTROL structure to the SCSI miniport driver ! 55: via the DeviceIoControl Win32 API. The dwIoControlCode must be ! 56: IOCTL_SCSI_MINIPORT. This particular dwIoControlCode is not ! 57: currently defined in any of the Win32 SDK header files and must be ! 58: defined in your own personal header file. It is defined in the ! 59: Windows NT DDK header file, NTDDSCSI.H. Including a Windows NT ! 60: DDK header file in a Win32 source file has been avoided strictly to ! 61: demonstrate the ability to write a Win32 application that accesses a ! 62: device driver without having the Windows NT DDK. ! 63: ! 64: Step 4, close the handle to the SCSI miniport driver. ! 65: ! 66: In SMPI.C, steps 2 and 3 are repeated to demonstrate the two ! 67: ControlCodes, SMP_RETURN_3F and SMP_PRINT_STRING. The ! 68: first requires no extra data buffer and so 'length' is set to 0. The ! 69: second does require additional buffer space. The value of 100 is ! 70: used as it makes the buffer large enough to handle up to 100 bytes of ! 71: data returned by the SCSI miniport driver. ! 72: ! 73: When strings are manipulated via the _memXXX functions, the ! 74: terminating null is not used. When using strXXX commands, the ! 75: terminating null is used. strlen does not include the terminating ! 76: null in it's total. ! 77: ! 78: Part 2 - SCSI Miniport Driver ! 79: ! 80: The SCSI miniport driver writer is free to define the ControlCode to ! 81: any value. Microsoft has provided a template for defining such ! 82: values and the driver writer can use this template for determining ! 83: their ControlCode values, but are not obligated to do so. In this ! 84: sample, SMP_RETURN_3F was defined using the template and ! 85: SMP_PRINT_STRING was defined with a random number. ! 86: ! 87: If the microsoft template is to be used, then the Windows NT DDK ! 88: header file, DEVIOCTL.H, should be consulted before defining a new ! 89: IOCtl. Also, the "Kernel-mode Driver Design Guide" contains ! 90: additional information on page B-12. There are two documentation ! 91: errors on this page. First, the bit pattern should be : ! 92: ! 93: bit(s) purpose ! 94: ------ ------- ! 95: 0,1 Transfer type ! 96: 2-12 Function Code ! 97: 13 Customer bit ! 98: 14,15 Required Access ! 99: 16-30 Device type ! 100: 31 Common bit ! 101: ! 102: The second documentation error states that the Function Code values ! 103: can be 0x00 to 0x7F for Microsoft defined IOCtls and 0x80 to 0xFF for ! 104: user defined IOCtls. This should be 0x000 to 0x7FF for Microsoft ! 105: defined IOCtls and 0x800 to 0xFFF for user defined IOCtls. The ! 106: Function Code field defines the function and the Customer bit ! 107: determines whether the function is defined by Microsoft or a ! 108: customer. ! 109: ! 110: The following should be added to the SCSI minport driver's header ! 111: file : ! 112: ! 113: // ! 114: // IOCtl definitions ! 115: // ! 116: ! 117: // ! 118: // Define the various device type values. Note that values used by Microsoft ! 119: // Corporation are in the range 0x0000 - 0x7FFF, and 0x8000 - 0xFFFF are ! 120: // reserved for use by customers. ! 121: // ! 122: ! 123: #define IOCTL_SCSI_MINIPORT_IO_CONTROL 0x8001 ! 124: ! 125: // ! 126: // Macro definition for defining IOCTL and FSCTL function control codes. ! 127: // Note that function codes 0x000 - 0x7FF are reserved for Microsoft ! 128: // Corporation, and 0x800 - 0xFFF are reserved for customers. ! 129: // ! 130: ! 131: #define RETURNCODE0x0000003F 0x850 ! 132: ! 133: #define SMP_RETURN_3F CTL_CODE(IOCTL_SCSI_MINIPORT_IO_CONTROL, RETURNCODE0x0000003F, METHOD_BUFFERED, FILE_ANY_ACCESS) ! 134: #define SMP_PRINT_STRING 0x80000001 ! 135: ! 136: PCHAR Signature="MyDrvr"; ! 137: PCHAR DrvrString="This string was placed in the data area by the SCSI miniport driver\n"; ! 138: ! 139: typedef struct { ! 140: SRB_IO_CONTROL sic; ! 141: UCHAR ucDataBuffer[512]; ! 142: } SRB_BUFFER, *PSRB_BUFFER; ! 143: ! 144: The following should be added to the SCSI miniport driver's source ! 145: code : ! 146: ! 147: #include <miniport.h> ! 148: #include <devioctl.h> ! 149: #include <ntddscsi.h> ! 150: #include "mydriver.h" ! 151: ! 152: and the following should be added to the SCSI miniport driver's ! 153: StartIo routine : ! 154: ! 155: case SRB_FUNCTION_IO_CONTROL: ! 156: ! 157: if (!memcmp(((PSRB_IO_CONTROL)(Srb->DataBuffer))->Signature,Signature,strlen(Signature))) { ! 158: ! 159: DebugPrint((1,"MyDriverStartIo: MiniportIOCtl not supported\n")); ! 160: ! 161: Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST; ! 162: ! 163: ScsiPortNotification(RequestComplete, ! 164: CardPtr, ! 165: Srb); ! 166: break; ! 167: } ! 168: ! 169: ! 170: DebugPrint((1,"MyDriverStartIo: Miniport IOCtl received\n")); ! 171: ! 172: DebugPrint((3,"MyDriverStartIo: Srb->DataBuffer->ControlCode = %Xh\n", ! 173: ((PSRB_IO_CONTROL)(Srb->DataBuffer))->ControlCode)); ! 174: ! 175: switch (((PSRB_IO_CONTROL)(Srb->DataBuffer))->ControlCode) { ! 176: ! 177: case SMP_RETURN_3F : ! 178: ! 179: Srb->SrbStatus = SRB_STATUS_SUCCESS; ! 180: ! 181: ((PSRB_IO_CONTROL)(Srb->DataBuffer))->ReturnCode = ! 182: (ULONG) 0x0000003FL; ! 183: ! 184: ScsiPortNotification(RequestComplete, ! 185: CardPtr, ! 186: Srb); ! 187: break; ! 188: ! 189: case SMP_PRINT_STRING : ! 190: ! 191: Srb->SrbStatus = SRB_STATUS_SUCCESS; ! 192: ! 193: DebugPrint((0,"%s",((PSRB_BUFFER)(Srb->DataBuffer))->ucDataBuffer)); ! 194: ! 195: strcpy(((PSRB_BUFFER)(Srb->DataBuffer))->ucDataBuffer,DrvrString); ! 196: ! 197: ScsiPortNotification(RequestComplete, ! 198: CardPtr, ! 199: Srb); ! 200: break; ! 201: ! 202: default : ! 203: ! 204: DebugPrint((1,"MyDriverStartIo: MiniportIOCtl not supported\n")); ! 205: ! 206: Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST; ! 207: ! 208: ScsiPortNotification(RequestComplete, ! 209: CardPtr, ! 210: Srb); ! 211: break; ! 212: ! 213: } // end switch ! 214: ! 215: break; ! 216: ! 217:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.