Windows NT Driver >> C/C++
StartIO
參考資訊:
1. Source Code
StartIO提供一個序列化的機制,讓使用者可以依照順序處理IRP,這個機制對於某些只能序列執行的硬體相當有幫助,省去用軟體實現序列化的程式碼,使用的步驟:
1. IoMarkIrpPending()
2. IoStartNextPacket()
main.c
#include <wdm.h> #define DEV_NAME L"\\Device\\MyDriver" #define SYM_NAME L"\\DosDevices\\MyDriver" char szBuffer[255]={0}; VOID StartIo(struct _DEVICE_OBJECT *pOurDevice, struct _IRP *pIrp) { ULONG dwLen=0; PIO_STACK_LOCATION psk = IoGetCurrentIrpStackLocation(pIrp); switch(psk->MajorFunction){ case IRP_MJ_READ: dwLen = strlen(szBuffer)+1; strcpy(pIrp->AssociatedIrp.SystemBuffer, szBuffer); DbgPrint("StartIo, IRP_MJ_READ"); break; case IRP_MJ_WRITE: dwLen = psk->Parameters.Write.Length; strcpy(szBuffer, pIrp->AssociatedIrp.SystemBuffer); DbgPrint("StartIo, IRP_MJ_WRITE"); DbgPrint("Buffer: %s, Length: %d", szBuffer, dwLen); break; } pIrp->IoStatus.Status = STATUS_SUCCESS; pIrp->IoStatus.Information = dwLen; IoCompleteRequest(pIrp, IO_NO_INCREMENT); IoStartNextPacket(pOurDevice, FALSE); } void Unload(PDRIVER_OBJECT pOurDriver) { UNICODE_STRING usSymboName; RtlInitUnicodeString(&usSymboName, L"\\DosDevices\\MyDriver"); IoDeleteSymbolicLink(&usSymboName); IoDeleteDevice(pOurDriver->DeviceObject); } NTSTATUS IrpFile(PDEVICE_OBJECT pOurDevice, PIRP pIrp) { PIO_STACK_LOCATION psk = IoGetCurrentIrpStackLocation(pIrp); switch(psk->MajorFunction){ case IRP_MJ_CREATE: DbgPrint("IRP_MJ_CREATE"); break; case IRP_MJ_WRITE: DbgPrint("IrpFile, IRP_MJ_WRITE"); IoMarkIrpPending(pIrp); IoStartPacket(pOurDevice, pIrp, 0, NULL); return STATUS_PENDING; case IRP_MJ_READ: DbgPrint("IrpFile, IRP_MJ_READ"); IoMarkIrpPending(pIrp); IoStartPacket(pOurDevice, pIrp, 0, NULL); return STATUS_PENDING; case IRP_MJ_CLOSE: DbgPrint("IRP_MJ_CLOSE"); break; } IoCompleteRequest(pIrp, IO_NO_INCREMENT); return STATUS_SUCCESS; } NTSTATUS DriverEntry(PDRIVER_OBJECT pOurDriver, PUNICODE_STRING pOurRegistry) { PDEVICE_OBJECT pOurDevice=NULL; UNICODE_STRING usDeviceName; UNICODE_STRING usSymboName; pOurDriver->MajorFunction[IRP_MJ_CREATE] = pOurDriver->MajorFunction[IRP_MJ_WRITE] = pOurDriver->MajorFunction[IRP_MJ_READ] = pOurDriver->MajorFunction[IRP_MJ_CLOSE] = IrpFile; pOurDriver->DriverStartIo = StartIo; pOurDriver->DriverUnload = Unload; RtlInitUnicodeString(&usDeviceName, L"\\Device\\MyDriver"); IoCreateDevice(pOurDriver, 0, &usDeviceName, FILE_DEVICE_UNKNOWN, 0, FALSE, &pOurDevice); RtlInitUnicodeString(&usSymboName, L"\\DosDevices\\MyDriver"); IoCreateSymbolicLink(&usSymboName, &usDeviceName); pOurDevice->Flags&= ~DO_DEVICE_INITIALIZING; pOurDevice->Flags|= DO_BUFFERED_IO; return STATUS_SUCCESS; }
IrpFile()IRP_MJ_READ和IRP_MJ_WRITE使用StartIO方式處理
app.c
#define INITGUID #include <windows.h> #include <winioctl.h> #include <strsafe.h> #include <setupapi.h> #include <stdio.h> #include <stdlib.h> int __cdecl main(int argc, char* argv[]) { DWORD len=0; DWORD dwRet=0; HANDLE hFile=NULL; char szBuffer[255]={0}; hFile = CreateFile("\\\\.\\MyDriver", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); if (hFile == INVALID_HANDLE_VALUE) { printf("failed to open mydriver\n"); return -1; } sprintf_s(szBuffer, sizeof(szBuffer), "I am error"); len = strlen(szBuffer)+1; printf("WR: %s\n", szBuffer); printf("Length: %d\n", len); WriteFile(hFile, szBuffer, len, &dwRet, NULL); memset(szBuffer, 0, sizeof(szBuffer)); ReadFile(hFile, szBuffer, sizeof(szBuffer), &dwRet, NULL); printf("RD: %s\n", szBuffer); printf("Length: %d\n", dwRet); CloseHandle(hFile); return 0; }
結果