Следующий код в драйвере обрабатывающий IRP запрос:
#define CtlCodeCopy CTL_CODE(FILE_DEVICE_UNKNOWN, 0x801, METHOD_OUT_DIRECT, FILE_ANY_ACCESS)
- генерирует исключение при обращении к выходному буферу режма ядра, а именно функция ProbeForRead :
NTSTATUS Handler801(IN PDEVICE_OBJECT pDeviceObject, IN PIRP Irp, PIO_STACK_LOCATION pSL)
{
DbgPrint("Handler801");
PVOID pOutBuff = MmGetSystemAddressForMdlSafe (Irp->MdlAddress,HighPagePriority);
if (pOutBuff != NULL)
{
__try
{
ProbeForRead(pOutBuff, Irp->MdlAddress->ByteCount, TYPE_ALIGNMENT(char));
DbgPrint("Handler801 : __try");
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
DbgPrint("Handler801 : __except");
return STATUS_MEMORY_NOT_ALLOCATED;
}
}
Irp->IoStatus.Information = 0 ;
return STATUS_SUCCESS;
}
Указатель pOutBuff не NULL, почему функция ProbeForRead вызывает исключение не пойму.
Вот лог DebugView - содержимое структур IO_STACK_LOCATION и IRP, тут всё в порядке:
00000000 0.00000000 DriverDeviceControl
00000001 0.00000301 OutputBufferLength=4096
00000002 0.00000425 InputBufferLength=4096
00000003 0.00000555 IoControlCode=2236422
00000004 0.00000669 Type3InputBuffer=0
00000005 0.00000815 Irp->MdlAddress->ByteCount=4096
00000006 0.00000939 Irp->MdlAddress->Size=32
00000007 0.00001070 Irp->MdlAddress->ByteOffset=0
00000008 0.00001207 Irp->MdlAddress->StartVa=17305600
00000009 0.00001321 IoCtl=801
Вот текст программы посылающей запрос драйверу:
hDevice = CreateFile("\\\\.\\MyDevice0", // drive to open
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | // share mode
FILE_SHARE_WRITE,
NULL, // default security attributes
OPEN_EXISTING, // disposition
0, // file attributes
NULL); // do not copy file attributes
if (hDevice == INVALID_HANDLE_VALUE) // cannot open the drive
{ return;}
...
LPVOID lpReserv = VirtualAlloc(NULL,
SystemInfo.dwAllocationGranularity,
MEM_RESERVE,
PAGE_READWRITE);
LPVOID lpCommitIn = VirtualAlloc(lpReserv,
SystemInfo.dwPageSize,
MEM_COMMIT,
PAGE_READWRITE);
LPVOID lpCommitOut = VirtualAlloc((LPVOID) ((DWORD)lpReserv + SystemInfo.dwPageSize),
SystemInfo.dwPageSize,
MEM_COMMIT,
PAGE_READWRITE);
...
BOOL bResult = DeviceIoControl(hDevice, // device to be queried
CtlCodeCopy, // operation to perform
lpCommitIn, // input buffer
SystemInfo.dwPageSize, // input buffer
lpCommitOut, // output buffer
SystemInfo.dwPageSize, // output buffer
&junk, // # bytes returned
(LPOVERLAPPED) NULL); // synchronous I/O
... Do something ...
CloseHandle(hDevice);
VirtualFree(lpCommitOut,0,MEM_DECOMMIT);
VirtualFree(lpCommitIn,0,MEM_DECOMMIT);
VirtualFree(lpReserv,0,MEM_RELEASE);
return ;