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

📄 init.c

📁 modem driver for windows. Tools: winddk
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * UNIMODEM "Fakemodem" controllerless driver illustrative example
 *
 * (C) 2000 Microsoft Corporation
 * All Rights Reserved
 *
 */

#include "fakemodem.h"

#if DBG
ULONG DebugFlags=255;
#endif

UNICODE_STRING   DriverEntryRegPath;

#ifdef ALLOC_PRAGMA
#pragma alloc_text(INIT,DriverEntry)
#pragma alloc_text(PAGE,FakeModemAddDevice)
#endif


NTSTATUS
DriverEntry(
    IN PDRIVER_OBJECT DriverObject,
    IN PUNICODE_STRING RegistryPath
    )
{
    NTSTATUS status;

    RTL_QUERY_REGISTRY_TABLE paramTable[3];
    ULONG zero = 0;
    ULONG debugLevel = 0;
    ULONG shouldBreak = 0;
    PWCHAR path;

    D_INIT(DbgPrint("FAKEMODEM: DriverEntry\n");)

    // Since the registry path parameter is a "counted" UNICODE string, it
    // might not be zero terminated.  For a very short time allocate memory
    // to hold the registry path zero terminated so that we can use it to
    // delve into the registry.

    path = ALLOCATE_PAGED_POOL(RegistryPath->Length+sizeof(WCHAR));

    if (path != NULL) 
    {
        RtlZeroMemory(&paramTable[0],sizeof(paramTable));
        RtlZeroMemory(path,RegistryPath->Length+sizeof(WCHAR));
        RtlMoveMemory(path,RegistryPath->Buffer,RegistryPath->Length);

        paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
        paramTable[0].Name = L"BreakOnEntry";
        paramTable[0].EntryContext = &shouldBreak;
        paramTable[0].DefaultType = REG_DWORD;
        paramTable[0].DefaultData = &zero;
        paramTable[0].DefaultLength = sizeof(ULONG);

        paramTable[1].Flags = RTL_QUERY_REGISTRY_DIRECT;
        paramTable[1].Name = L"DebugFlags";
        paramTable[1].EntryContext = &debugLevel;
        paramTable[1].DefaultType = REG_DWORD;
        paramTable[1].DefaultData = &zero;
        paramTable[1].DefaultLength = sizeof(ULONG);


        // If the Debugflags registry key is not set then
        // provide full debugging information

        if (!NT_SUCCESS(RtlQueryRegistryValues(
                        RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL, 
                        path, &paramTable[0], NULL, NULL))) 
        {
            shouldBreak = 0;
            debugLevel = 255;
        }

        FREE_POOL(path);
    }

#if DBG
    DebugFlags = debugLevel;
#endif

    if (shouldBreak) 
    {
        DbgBreakPoint();
    }

    // Pnp driver entry point

    DriverObject->DriverExtension->AddDevice = FakeModemAddDevice;

    // Initialize the driver object with driver's entry points

    DriverObject->DriverUnload = FakeModemUnload;

    DriverObject->MajorFunction[IRP_MJ_CREATE]            = FakeModemOpen;
    DriverObject->MajorFunction[IRP_MJ_CLOSE]             = FakeModemClose;
    DriverObject->MajorFunction[IRP_MJ_CLEANUP]           = FakeModemCleanup;
    DriverObject->MajorFunction[IRP_MJ_WRITE]             = FakeModemWrite;
    DriverObject->MajorFunction[IRP_MJ_READ]              = FakeModemRead;
    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]    = FakeModemIoControl;
    DriverObject->MajorFunction[IRP_MJ_PNP]               = FakeModemPnP;
    DriverObject->MajorFunction[IRP_MJ_POWER]             = FakeModemPower;

    D_INIT(DbgPrint("FAKEMODEM: End of DriverEntry\n");)

    return STATUS_SUCCESS;
}

VOID
FakeModemUnload(
    IN PDRIVER_OBJECT DriverObject
    )
{
    D_INIT(DbgPrint("FAKEMODEM: FakeModemUnload()\n");)

    return;
}

NTSTATUS
FakeModemAddDevice(
    IN PDRIVER_OBJECT DriverObject,
    IN PDEVICE_OBJECT Pdo
    )
{
    NTSTATUS           status=STATUS_SUCCESS;
    PDEVICE_OBJECT     Fdo;
    PDEVICE_EXTENSION  DeviceExtension;
    UNICODE_STRING     DeviceName;

    D_INIT(DbgPrint("FAKEMODEM: Fakemodem Add Device\n");)

    // Create our functional device object (FDO)
    
    status=IoCreateDevice(DriverObject, sizeof(DEVICE_EXTENSION), NULL, 
            FILE_DEVICE_SERIAL_PORT, FILE_AUTOGENERATED_DEVICE_NAME, 
            FALSE, &Fdo);

    if (status != STATUS_SUCCESS) 
    {
        return status;
    }

    Fdo->Flags |= DO_BUFFERED_IO;
    DeviceExtension = Fdo->DeviceExtension;
    DeviceExtension->DeviceObject = Fdo;

    // Attach our FDO to the PDO supplied
    
    DeviceExtension->LowerDevice = IoAttachDeviceToDeviceStack(Fdo, Pdo);
    if (NULL == DeviceExtension->LowerDevice) 
    {
        // Could not attach

        IoDeleteDevice(Fdo);
        return STATUS_UNSUCCESSFUL;
    }

    //  Try to create a ComX for it. don't care if it fails
    //  modem.sys creates a name for device that unimodem will use
    

    FakeModemHandleSymbolicLink(Pdo, TRUE, 
            &DeviceExtension->InterfaceNameString, Fdo);

    //  Initialise the spinlock
    
    KeInitializeSpinLock(&DeviceExtension->SpinLock);

    //  Initialize the device extension

    DeviceExtension->ReferenceCount=1;
    DeviceExtension->Removing=FALSE;
    DeviceExtension->Started=FALSE;
    DeviceExtension->OpenCount=0;
    KeInitializeEvent(&DeviceExtension->RemoveEvent, NotificationEvent, FALSE);

    //  Initialize the read and write queues

    InitializeListHead(&DeviceExtension->ReadQueue);
    DeviceExtension->CurrentReadIrp=NULL;

    InitializeListHead(&DeviceExtension->WriteQueue);
    DeviceExtension->CurrentWriteIrp=NULL;

    InitializeListHead(&DeviceExtension->MaskQueue);
    DeviceExtension->CurrentMaskIrp=NULL;

    // Clear this flag so the device object can be used

    Fdo->Flags &= ~(DO_DEVICE_INITIALIZING);

    return STATUS_SUCCESS;

}

NTSTATUS 
GetRegistryKeyValue (
    IN HANDLE Handle,
    IN PWCHAR KeyNameString,
    IN ULONG KeyNameStringLength,
    IN PVOID Data,
    IN ULONG DataLength
    )
{
    UNICODE_STRING keyName;
    ULONG length;
    PKEY_VALUE_FULL_INFORMATION fullInfo;

    NTSTATUS ntStatus = STATUS_NO_MEMORY;

    RtlInitUnicodeString (&keyName, KeyNameString);

    length = sizeof(KEY_VALUE_FULL_INFORMATION) + KeyNameStringLength + 
        DataLength;

    fullInfo = ExAllocatePool(PagedPool, length);

    if (fullInfo) 
    {
        ntStatus = ZwQueryValueKey(Handle, &keyName, 
                KeyValueFullInformation, fullInfo, length, &length);

        if (NT_SUCCESS(ntStatus)) 
        {
            // If there is enough room in the data buffer, copy the output

            if (DataLength >= fullInfo->DataLength) 
            {
                RtlCopyMemory(Data, 
                        ((PUCHAR) fullInfo) + fullInfo->DataOffset, 
                        fullInfo->DataLength);
            }
        }

        ExFreePool(fullInfo);
    }

    return ntStatus;
}

NTSTATUS
FakeModemHandleSymbolicLink(
    PDEVICE_OBJECT      Pdo,
    BOOLEAN             Create,
    PUNICODE_STRING     InterfaceName,
    PDEVICE_OBJECT      Fdo
    )

{

    UNICODE_STRING     SymbolicLink;
    ULONG              StringLength;
    NTSTATUS           Status;
    WCHAR              ComPort[80];
    HANDLE             keyHandle;
    RTL_QUERY_REGISTRY_TABLE paramTable[1];

    D_INIT(DbgPrint("FAKEMODEM: HandleSymbolicLink\n");)

    Status = IoOpenDeviceRegistryKey(Pdo, PLUGPLAY_REGKEY_DEVICE, 
            STANDARD_RIGHTS_READ, &keyHandle);

    SymbolicLink.Length=0;
    SymbolicLink.MaximumLength=sizeof(WCHAR)*256;
    SymbolicLink.Buffer=ExAllocatePool(PagedPool,
            SymbolicLink.MaximumLength+sizeof(WCHAR));

    if (SymbolicLink.Buffer == NULL) 
    {
        ZwClose(keyHandle);
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    RtlZeroMemory(SymbolicLink.Buffer, SymbolicLink.MaximumLength);
    RtlAppendUnicodeToString(&SymbolicLink, L"\\");
    RtlAppendUnicodeToString(&SymbolicLink, OBJECT_DIRECTORY);
    RtlAppendUnicodeToString(&SymbolicLink, L"\\");

    Status=GetRegistryKeyValue(keyHandle, L"PortName", 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -