home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Borland Programmer's Resource
/
Borland_Programmers_Resource_CD_1995.iso
/
code
/
smpi
/
readme.txt
< prev
next >
Wrap
Text File
|
1995-05-18
|
8KB
|
218 lines
This sample program consists of two parts. First, all the necessary
source code is provided to compile a Win32 sample program that sends
an IOCtl_SCSI_MINIPORT request with a custom ControlCode to the SCSI
miniport driver. Second, a detailed description is provided that
explains what changes the driver writer has to make to a SCSI
miniport driver to allow it to properly recognize and handle the
corresponding IOCtl request from the Win32 sample program.
Part 1 - Win32 sample
The SCSI Miniport IOCtl sample, SMPI.C, demonstrates how a Win32
application sends a user defined IOCtl Control Code to a SCSI
miniport driver. This is a simple program that is composed of four
steps.
Step 1, a handle is obtained to the SCSI miniport driver using the
Win32 API, CreateFile. The name of the file to be opened is
\\.\Scsi0:. As an alternative, a drive letter can be substituted for
\\.\Scsi0: (e.g. - \\.\C:). This will map to the appropriate SCSI
miniport driver that is responsible for C:.
Step 2, the SRB_IO_CONTROL structure is filled out. The following
items must be completed :
HeaderLength - must be the size of an SRB_IO_CONTROL structure
ControlCode - while strictly optional, this entry should be
considered mandatory. The ControlCode value is used to
further sub-divide IOCTL_SCSI_MINIPORT requests. The
contents of ControlCode are defined by the SCSI miniport
driver writer.
Length - the size of the data buffer immediately following the
SRB_IO_CONTROL structure. If no additional data buffer
is used, then this must be set to 0.
The following items of the SRB_IO_CONTROL structure are optional :
Signature - these 8 bytes are available to help prevent IOCtl
conflicts between various vendors
Timeout - indicates the minimum time in seconds before the
request has timed out. There is no maximum Timeout for
IOCTL_SCSI_MINIPORT. Note, for IOCTL_SCSI_PASS_THROUGH,
the maximum time out value is 108000 seconds (30 minutes).
ReturnCode - this entry is filled in by the SCSI miniport to
inform the Win32 application of the results of the
requested action. The contents of ReturnCode are defined
by the SCSI miniport Driver writer.
In the SMPI.C sample, two customer defined ControlCodes are used,
SMP_RETURN_3F and SMP_PRINT_STRING. The first requires
no additional data buffer. The second requires that a contiguous
data buffer be appended at the end of the SRB_IO_CONTROL structure.
The ControlCodes are defined by the SCSI miniport driver (see below).
Step 3, send the SRB_IO_CONTROL structure to the SCSI miniport driver
via the DeviceIoControl Win32 API. The dwIoControlCode must be
IOCTL_SCSI_MINIPORT. This particular dwIoControlCode is not
currently defined in any of the Win32 SDK header files and must be
defined in your own personal header file. It is defined in the
Windows NT DDK header file, NTDDSCSI.H. Including a Windows NT
DDK header file in a Win32 source file has been avoided strictly to
demonstrate the ability to write a Win32 application that accesses a
device driver without having the Windows NT DDK.
Step 4, close the handle to the SCSI miniport driver.
In SMPI.C, steps 2 and 3 are repeated to demonstrate the two
ControlCodes, SMP_RETURN_3F and SMP_PRINT_STRING. The
first requires no extra data buffer and so 'length' is set to 0. The
second does require additional buffer space. The value of 100 is
used as it makes the buffer large enough to handle up to 100 bytes of
data returned by the SCSI miniport driver.
When strings are manipulated via the _memXXX functions, the
terminating null is not used. When using strXXX commands, the
terminating null is used. strlen does not include the terminating
null in it's total.
Part 2 - SCSI Miniport Driver
The SCSI miniport driver writer is free to define the ControlCode to
any value. Microsoft has provided a template for defining such
values and the driver writer can use this template for determining
their ControlCode values, but are not obligated to do so. In this
sample, SMP_RETURN_3F was defined using the template and
SMP_PRINT_STRING was defined with a random number.
If the microsoft template is to be used, then the Windows NT DDK
header file, DEVIOCTL.H, should be consulted before defining a new
IOCtl. Also, the "Kernel-mode Driver Design Guide" contains
additional information on page B-12. There are two documentation
errors on this page. First, the bit pattern should be :
bit(s) purpose
------ -------
0,1 Transfer type
2-12 Function Code
13 Customer bit
14,15 Required Access
16-30 Device type
31 Common bit
The second documentation error states that the Function Code values
can be 0x00 to 0x7F for Microsoft defined IOCtls and 0x80 to 0xFF for
user defined IOCtls. This should be 0x000 to 0x7FF for Microsoft
defined IOCtls and 0x800 to 0xFFF for user defined IOCtls. The
Function Code field defines the function and the Customer bit
determines whether the function is defined by Microsoft or a
customer.
The following should be added to the SCSI minport driver's header
file :
//
// IOCtl definitions
//
//
// Define the various device type values. Note that values used by Microsoft
// Corporation are in the range 0x0000 - 0x7FFF, and 0x8000 - 0xFFFF are
// reserved for use by customers.
//
#define IOCTL_SCSI_MINIPORT_IO_CONTROL 0x8001
//
// Macro definition for defining IOCTL and FSCTL function control codes.
// Note that function codes 0x000 - 0x7FF are reserved for Microsoft
// Corporation, and 0x800 - 0xFFF are reserved for customers.
//
#define RETURNCODE0x0000003F 0x850
#define SMP_RETURN_3F CTL_CODE(IOCTL_SCSI_MINIPORT_IO_CONTROL, RETURNCODE0x0000003F, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define SMP_PRINT_STRING 0x80000001
PCHAR Signature="MyDrvr";
PCHAR DrvrString="This string was placed in the data area by the SCSI miniport driver\n";
typedef struct {
SRB_IO_CONTROL sic;
UCHAR ucDataBuffer[512];
} SRB_BUFFER, *PSRB_BUFFER;
The following should be added to the SCSI miniport driver's source
code :
#include <miniport.h>
#include <devioctl.h>
#include <ntddscsi.h>
#include "mydriver.h"
and the following should be added to the SCSI miniport driver's
StartIo routine :
case SRB_FUNCTION_IO_CONTROL:
if (!memcmp(((PSRB_IO_CONTROL)(Srb->DataBuffer))->Signature,Signature,strlen(Signature))) {
DebugPrint((1,"MyDriverStartIo: MiniportIOCtl not supported\n"));
Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
ScsiPortNotification(RequestComplete,
CardPtr,
Srb);
break;
}
DebugPrint((1,"MyDriverStartIo: Miniport IOCtl received\n"));
DebugPrint((3,"MyDriverStartIo: Srb->DataBuffer->ControlCode = %Xh\n",
((PSRB_IO_CONTROL)(Srb->DataBuffer))->ControlCode));
switch (((PSRB_IO_CONTROL)(Srb->DataBuffer))->ControlCode) {
case SMP_RETURN_3F :
Srb->SrbStatus = SRB_STATUS_SUCCESS;
((PSRB_IO_CONTROL)(Srb->DataBuffer))->ReturnCode =
(ULONG) 0x0000003FL;
ScsiPortNotification(RequestComplete,
CardPtr,
Srb);
break;
case SMP_PRINT_STRING :
Srb->SrbStatus = SRB_STATUS_SUCCESS;
DebugPrint((0,"%s",((PSRB_BUFFER)(Srb->DataBuffer))->ucDataBuffer));
strcpy(((PSRB_BUFFER)(Srb->DataBuffer))->ucDataBuffer,DrvrString);
ScsiPortNotification(RequestComplete,
CardPtr,
Srb);
break;
default :
DebugPrint((1,"MyDriverStartIo: MiniportIOCtl not supported\n"));
Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
ScsiPortNotification(RequestComplete,
CardPtr,
Srb);
break;
} // end switch
break;