?? pnp.cpp
字號:
#include "vcp4usb.h"
// globale Data
LIST_ENTRY gDevList;
KMUTEX gDevListMutex;
//#pragma code_seg("PAGE") // start PAGE section
//
NTSTATUS Vcp4usbAddDevice(IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT pdo)
{
NTSTATUS status;
PDEVICE_OBJECT fdo;
HANDLE hReg;
PLIST_ENTRY pListEntry;
ULONG instanceNo;
UNICODE_STRING ntDeviceName;
UNICODE_STRING instanceStr;
WCHAR instanceNumberBuffer[10];
WCHAR * pRegName;
DPrint(DBG_PNP, ("AddDevice\n"));
// get registry key (&hReg)
status = IoOpenDeviceRegistryKey(pdo, PLUGPLAY_REGKEY_DEVICE, STANDARD_RIGHTS_READ, &hReg);
if (!NT_SUCCESS(status))
return status;
// determine instance number
instanceNo = 0;
pListEntry = gDevList.Flink;
while (pListEntry != &gDevList)
{
if (instanceNo < ((PVCP4USB_DEVICE_EXTENSION)pListEntry)->instanceNo)
break;
instanceNo = ((PVCP4USB_DEVICE_EXTENSION)pListEntry)->instanceNo + 1;
pListEntry = pListEntry->Flink;
}
// build device name
RtlZeroMemory(&ntDeviceName, sizeof(UNICODE_STRING));
ntDeviceName.MaximumLength = 128*sizeof(WCHAR);
ntDeviceName.Buffer = (PWSTR)ExAllocatePool(NonPagedPool, (128+1)*sizeof(WCHAR));
if (ntDeviceName.Buffer == NULL)
{
DPrint(DBG_PNP, ("ntDeviceName.Buffer == NULL\n"));
ZwClose(hReg);
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlZeroMemory(ntDeviceName.Buffer, (128+1)*sizeof(WCHAR));
RtlAppendUnicodeToString(&ntDeviceName, VCP4USB_DEVICE_NAME);
RtlInitUnicodeString(&instanceStr, NULL);
instanceStr.MaximumLength = sizeof(instanceNumberBuffer);
instanceStr.Buffer = instanceNumberBuffer;
RtlIntegerToUnicodeString(instanceNo, 10, &instanceStr);
RtlAppendUnicodeStringToString(&ntDeviceName, &instanceStr);
// Create our Functional Device Object in fdo
status = IoCreateDevice(DriverObject,
sizeof(VCP4USB_DEVICE_EXTENSION),
&ntDeviceName,
FILE_DEVICE_SERIAL_PORT,
0,
TRUE, // exclusive
&fdo);
if( !NT_SUCCESS(status))
{
DPrint(DBG_PNP, ("IoCreateDevice faild.\n"));
ZwClose(hReg);
ExFreePool(ntDeviceName.Buffer);
return status;
}
// Remember fdo in our device extension
PVCP4USB_DEVICE_EXTENSION dx = (PVCP4USB_DEVICE_EXTENSION)fdo->DeviceExtension;
dx->instanceNo = instanceNo;
dx->fdo = fdo;
InsertHeadList(pListEntry, &dx->listEntry); // ??
// init
dx->pThreadObj = NULL;
KeInitializeEvent(&dx->eventThreadExit, NotificationEvent, FALSE);
KeInitializeEvent(&dx->eventThreadExiting, NotificationEvent, FALSE);
dx->bIsConnected = FALSE;
dx->bReadPending = FALSE;
dx->bWritePending = FALSE;
dx->pTxBuf = NULL;
dx->curLenTx = 0;
dx->pRxBuf = NULL;
dx->curLenRx = 0;
dx->needLenRx = 0;
KeInitializeEvent(&dx->eventWriteStart, NotificationEvent, FALSE);
KeInitializeEvent(&dx->eventReadEnd, NotificationEvent, FALSE);
KeInitializeEvent(&dx->eventReadStart, NotificationEvent, FALSE);
KeInitializeSpinLock(&dx->spinLock);
dx->irpReadPending = NULL;
dx->irpWritePending = NULL;
dx->eventMask = 0;
dx->historyEvents = 0;
RtlZeroMemory(&dx->curTimeouts, sizeof(SERIAL_TIMEOUTS));
RtlZeroMemory(&dx->curHandflow, sizeof(SERIAL_HANDFLOW));
dx->pWaitCtrlIrp = NULL;
InitTimer(&dx->readIntervalTimer, DpcReadIntervalTimeout, dx);
InitTimer(&dx->readTotalTimer, DpcReadTotalTimeout, dx);
InitTimer(&dx->writeTotalTimer, DpcWriteTotalTimeout, dx);
dx->NextStackDevice = NULL;
RtlCopyMemory(&dx->ntDeviceName, &ntDeviceName, sizeof(UNICODE_STRING));
DPrint(DBG_PNP, ("Device name:%ws\n", ntDeviceName.Buffer));
// Create Win32 App device name
pRegName = (WCHAR*)ExAllocatePool(NonPagedPool, (128+1)*sizeof(WCHAR));
if (pRegName == NULL)
{
DPrint(DBG_PNP, ("pRegName == NULL\n"));
ZwClose(hReg);
ExFreePool(ntDeviceName.Buffer);
IoDeleteDevice(fdo);
return STATUS_INSUFFICIENT_RESOURCES;
}
status = GetRegistryKeyValue(hReg, L"PortName", pRegName, 128*sizeof(WCHAR));
if (!NT_SUCCESS(status))
{
DPrint(DBG_PNP, ("GetRegistryKeyValue return:%d.\n", status));
ZwClose(hReg);
ExFreePool(ntDeviceName.Buffer);
ExFreePool(pRegName);
IoDeleteDevice(fdo);
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlZeroMemory(&dx->dosDeviceName, sizeof(UNICODE_STRING));
dx->dosDeviceName.MaximumLength = 128*sizeof(WCHAR);
dx->dosDeviceName.Buffer = (PWSTR)ExAllocatePool(NonPagedPool, (128+1)*sizeof(WCHAR));
if (dx->dosDeviceName.Buffer == NULL)
{
DPrint(DBG_PNP, ("dx->dosDeviceName.Buffer == NULL\n"));
ZwClose(hReg);
ExFreePool(ntDeviceName.Buffer);
ExFreePool(pRegName);
IoDeleteDevice(fdo);
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlAppendUnicodeToString(&dx->dosDeviceName, L"\\DosDevices\\");
RtlAppendUnicodeToString(&dx->dosDeviceName, pRegName);//dosDeviceName == \\DosDevices\\COM3
status = IoCreateSymbolicLink(&dx->dosDeviceName, &ntDeviceName);
if( !NT_SUCCESS(status))
{
DPrint(DBG_PNP, ("IoCreateSymbolicLink faild.\n"));
ZwClose(hReg);
ExFreePool(ntDeviceName.Buffer);
ExFreePool(dx->dosDeviceName.Buffer);
IoDeleteDevice(fdo);
return status;
}
DPrint(DBG_PNP, ("Create dos device name:%ws\n", dx->dosDeviceName.Buffer));
//register port in DeviceMap
status = RtlWriteRegistryValue(RTL_REGISTRY_DEVICEMAP,
SERIAL_DEVICE_MAP, ntDeviceName.Buffer, REG_SZ,
pRegName, (wcslen(pRegName) + 1) * sizeof(WCHAR));
if( !NT_SUCCESS(status))
{
DPrint(DBG_PNP, ("RtlWriteRegistryValue faild.\n"));
}
// cleanup
ZwClose(hReg);
ExFreePool(pRegName);
// Attach to the driver stack below us
dx->NextStackDevice = IoAttachDeviceToDeviceStack(fdo, pdo);
if (dx->NextStackDevice == NULL)
{
DPrint(DBG_PNP, ("IoAttachDeviceToDeviceStack faild.\n"));
ExFreePool(ntDeviceName.Buffer);
IoDeleteDevice(fdo);
return STATUS_NO_SUCH_DEVICE;
}
// Set fdo flags appropriately
fdo->Flags |= DO_BUFFERED_IO;// | DO_POWER_PAGABLE;
// finished
fdo->Flags &= ~DO_DEVICE_INITIALIZING;
return STATUS_SUCCESS;
}
//
NTSTATUS Vcp4usbPnp(IN PDEVICE_OBJECT fdo, IN PIRP Irp)
{
DPrint(DBG_PNP, ("Pnp\n"));
PVCP4USB_DEVICE_EXTENSION dx=(PVCP4USB_DEVICE_EXTENSION)fdo->DeviceExtension;
// Remember minor function
PIO_STACK_LOCATION IrpStack = IoGetCurrentIrpStackLocation(Irp);
ULONG MinorFunction = IrpStack->MinorFunction;
// Just pass to lower driver
IoSkipCurrentIrpStackLocation(Irp);
NTSTATUS status = IoCallDriver( dx->NextStackDevice, Irp);
// Device removed
switch (MinorFunction)
{
case IRP_MN_REMOVE_DEVICE:
//unregister port in DeviceMap
RtlDeleteRegistryValue(RTL_REGISTRY_DEVICEMAP,
SERIAL_DEVICE_MAP, dx->ntDeviceName.Buffer);
// free device name buffer
ExFreePool(dx->ntDeviceName.Buffer);
IoDeleteSymbolicLink(&dx->dosDeviceName);
ExFreePool(dx->dosDeviceName.Buffer);
RemoveEntryList(&dx->listEntry);
// disable device interface
// unattach from stack
if (dx->NextStackDevice)
IoDetachDevice(dx->NextStackDevice);
// delete our fdo
IoDeleteDevice(fdo);
RemoveEntryList(&dx->listEntry);
InitializeListHead(&gDevList);
break;
default:
break;
} // end switch (MinorFunction)
return status;
}
//
NTSTATUS Vcp4usbPower(IN PDEVICE_OBJECT fdo, IN PIRP Irp)
{
DPrint(DBG_POWER, ("Power\n"));
PVCP4USB_DEVICE_EXTENSION dx = (PVCP4USB_DEVICE_EXTENSION)fdo->DeviceExtension;
// Just pass to lower driver
PoStartNextPowerIrp( Irp);
IoSkipCurrentIrpStackLocation(Irp);
return PoCallDriver( dx->NextStackDevice, Irp);
}
NTSTATUS GetRegistryKeyValue(IN HANDLE regHandle, IN PWCHAR keyName, IN PVOID data, IN ULONG dataLength)
{
UNICODE_STRING keyNameString;
ULONG length;
PKEY_VALUE_PARTIAL_INFORMATION pInfo;
NTSTATUS status = STATUS_INSUFFICIENT_RESOURCES;
RtlInitUnicodeString(&keyNameString, keyName);
length = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + dataLength;
pInfo = (PKEY_VALUE_PARTIAL_INFORMATION)ExAllocatePool(NonPagedPool, length);
if (pInfo != NULL)
{
status = ZwQueryValueKey(regHandle, &keyNameString, KeyValuePartialInformation, pInfo, length, &length);
if (NT_SUCCESS(status))
{
if (dataLength >= pInfo->DataLength)
RtlCopyMemory(data, &pInfo->Data, pInfo->DataLength);
else
status = STATUS_BUFFER_TOO_SMALL;
}
ExFreePool(pInfo);
}
return status;
}
//#pragma code_seg() // end PAGE section
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -