Click to See Complete Forum and Search --> : Device Driver IRP problem


Roger Allen
June 8th, 1999, 06:55 AM
Hi,
I am writing a device driver to control a hardware device. The problem I have is that to configure the device correctly
for a read/write operation, I need to pass in the structure ReadInfo. This works OK, but in the driver I dont know where
the pointer of this structure is made available to me in the routine that handles the IRP generated by NT.

Here is the code to talk to the driver :


BOOL IoctlResult; // returned by IOCTL. It is true if the read succeeds.
// parameters are used in the IOCTL call
HANDLE hndDriver; // Handle to device, obtain from CreateFile
DPAS_SPECTRA ReadInfo ; // infor for spectra read
LONG IoctlCode = IOCTL_DPAS_READ_SPECTRA ;
ULONG DataLength;
DWORD ReturnedLength; // Number of bytes returned

// open the DPAS Driver
hndDriver = CreateFile(
"\\\\.\\DPas", // Open the Device "file"
GENERIC_WRITE,
FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL
);

if (hndDriver == INVALID_HANDLE_VALUE) // Was the device opened?
{
TRACE("Failed to open DPas driver!") ;
return NULL ;
}

// struct DPAS_SPECTRA
// {
// USHORT scan[NUM_DIODES] ; // rturned scan data
// int size ; // size of this structure
// double integration_time ; // integration time for scan (in seconds)
// int scans_to_throw_away ; // number of scans to throw away before averaging begins
// int scans_to_average ; // number of spectra to average, then return
// int number_of_diodes ; // number of diodes in returned scan
// int number_of_scans_averaged ; // number of scans avereged in return scan
// } ;
ReadInfo.size = sizeof(DPAS_SPECTRA) ;
ReadInfo.integration_time = 0.07 ;
ReadInfo.scans_to_throw_away = 0 ;
ReadInfo.scans_to_average = 1 ;
ReadInfo.number_of_diodes = NUM_DIODES ;

DataLength = sizeof(DataBuffer) ;

IoctlResult = DeviceIoControl(
hndDriver, // Handle to device
IoctlCode, // IO Control code for Read
&ReadInfo, // Buffer to driver.
sizeof(ReadInfo), // Length of buffer in bytes.
NULL, // Buffer from driver.
0, // Length of buffer in bytes.
&ReturnedLength, // Bytes placed in DataBuffer.
NULL // NULL means wait till op. completes.
);
if (ReturnedLength != DataLength)
TRACE("Only returned %1ld bytes!\n", ReturnedLength) ;
if (!IoctlResult) // Did the IOCTL succeed?
TRACE("Ioctl failed with code %ld\n", GetLastError()) ;

if (!CloseHandle(hndDriver)) // Close the Device "file".
TRACE("Failed to close device.");




this is the code that deals with the IRP (snippet)

NTSTATUS DPasIoctlReadPort(
IN PLOCAL_DEVICE_INFO pLDI,
IN PIRP pIrp,
IN PIO_STACK_LOCATION IrpStack,
IN ULONG IoctlCode)
{

// NOTE: Use METHOD_BUFFERED ioctls.
PULONG pIOBuffer; // Pointer to transfer buffer
// (treated as an array of longs).
ULONG InBufferSize; // Amount of data avail. from caller.
ULONG OutBufferSize; // Max data that caller can accept.
ULONG DataBufferSize;

// Size of buffer containing data from application
// this should be the size of my "ReadInfo" object passed to this routine
// but where do I get the pointer to the "ReadInfo" object ?
InBufferSize = IrpStack->Parameters.DeviceIoControl.InputBufferLength;








Can anybody tell me where I can get hold of the pointer to the input data supplied to the IRP by my DeviceIoControl call ?

Thanks in advance.


Roger Allen

June 8th, 1999, 08:17 AM
Since all IRP_MJ_DEVICE_CONTROL requests use buffered I/O, you can use the following lines to get a pointer to your DPAS_SPECTRA structure:


DPAS_SPECTRA *pReadInfo;
pReadInfo = pIrp->AssociatedIrp.SystemBuffer





More information is available in the Windows NT 4.0 DDK documentation (Chapter 3.2.4 Setting Up Access to User Buffer).

Roger Allen
June 8th, 1999, 08:39 AM
Thanks,
It works fine now.


Roger Allen