⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pnp.cpp

📁 USBconvert232 USB转232驱动源程序
💻 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 + -