Exemplo n.º 1
0
//.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- CheckAndCreateRegistryPath -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.
//
DtStatus  CheckAndCreateRegistryPath(
    WDFDRIVER  Driver,
    DtString*  pItemPath)
{
    DtStringChar*  pRegistryPath;
    DtString  RegistryPath;
    DtString  FullKeyName;
    UInt  PathLength;
    DtStatus  Status;
    Int  i;
    DT_STRING_DECL(ParamItemName, "\\Parameters");

    // Build the full path
    pRegistryPath = WdfDriverGetRegistryPath(Driver);
    PathLength = wcslen(pRegistryPath); 

    DT_STRING_INIT_CONST(RegistryPath, pRegistryPath, PathLength);

    // Allocate a new DtString buffer for the complete path inclusive a '\0' character and
    // extra '\'
    if (!DT_SUCCESS(DtStringAlloc(&FullKeyName, PathLength+
                                                  DtStringGetStringLength(&ParamItemName)+
                                                   DtStringGetStringLength(pItemPath)+2)))
        return STATUS_NO_MEMORY;

    DtStringAppendDtString(&FullKeyName, &RegistryPath);
    DtStringAppendDtString(&FullKeyName, &ParamItemName);

    if (RtlCheckRegistryKey(RTL_REGISTRY_ABSOLUTE, FullKeyName.Buffer) != STATUS_SUCCESS)
        RtlCreateRegistryKey(RTL_REGISTRY_ABSOLUTE, FullKeyName.Buffer);

    Status = DT_STATUS_OK;

    i = 1;
    // Get all subitems from pItemPath and check if the registry entry exist.
    // If not, create the registry entry.
    // This function is needed, because Wuindows only allows us to create one registry entry
    // at a time and not a complete path.
    while (Status == DT_STATUS_OK)
    {
        DtStringAppendChars(&FullKeyName, "\\");
        Status = DtStringAppendSubstring(&FullKeyName, pItemPath, i, '\\');
        if (DT_SUCCESS(Status))
        {
            if (RtlCheckRegistryKey(RTL_REGISTRY_ABSOLUTE, FullKeyName.Buffer) 
                                                                        != STATUS_SUCCESS)
                RtlCreateRegistryKey(RTL_REGISTRY_ABSOLUTE, FullKeyName.Buffer);
        }
        i++;
    }
    DtStringFree(&FullKeyName);
    return DT_STATUS_OK;    
}
Exemplo n.º 2
0
NTSTATUS
RamDiskEvtDeviceAdd(
    IN WDFDRIVER Driver,
    IN PWDFDEVICE_INIT DeviceInit
    )
/*++
Routine Description:

    EvtDeviceAdd is called by the framework in response to AddDevice
    call from the PnP manager. We create and initialize a device object to
    represent a new instance of the device.

Arguments:

    Driver - Handle to a framework driver object created in DriverEntry

    DeviceInit - Pointer to a framework-allocated WDFDEVICE_INIT structure.

Return Value:

    NTSTATUS

--*/
{
    WDF_OBJECT_ATTRIBUTES   deviceAttributes;
    NTSTATUS                status;
    WDFDEVICE               device;
    WDF_OBJECT_ATTRIBUTES   queueAttributes;
    WDF_IO_QUEUE_CONFIG     ioQueueConfig;
    PDEVICE_EXTENSION       pDeviceExtension;
    PQUEUE_EXTENSION        pQueueContext = NULL;
    WDFQUEUE                queue;
    DECLARE_CONST_UNICODE_STRING(ntDeviceName, NT_DEVICE_NAME);

    PAGED_CODE();

    UNREFERENCED_PARAMETER(Driver);

    //
    // Storage drivers have to name their FDOs. Since we are not unique'fying
    // the device name, we wouldn't be able to install more than one instance
    // of this ramdisk driver.
    //
    status = WdfDeviceInitAssignName(DeviceInit, &ntDeviceName);
    if (!NT_SUCCESS(status)) {
        return status;
    }

    WdfDeviceInitSetDeviceType(DeviceInit, FILE_DEVICE_DISK);
    WdfDeviceInitSetIoType(DeviceInit, WdfDeviceIoDirect);
    WdfDeviceInitSetExclusive(DeviceInit, FALSE);

    //
    // Since this is a pure software only driver, there is no need to register
    // any PNP/Power event callbacks. Framework will respond to these
    // events appropriately.
    //
    WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&deviceAttributes, DEVICE_EXTENSION);
    deviceAttributes.EvtCleanupCallback = RamDiskEvtDeviceContextCleanup;

    status = WdfDeviceCreate(&DeviceInit, &deviceAttributes, &device);
    if (!NT_SUCCESS(status)) {
        return status;
    }

    //
    // Now that the WDF device object has been created, set up any context
    // that it requires.
    //

    pDeviceExtension = DeviceGetExtension(device);

    //
    // Configure a default queue so that requests that are not
    // configure-fowarded using WdfDeviceConfigureRequestDispatching to goto
    // other queues get dispatched here.
    //
    WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE (
        &ioQueueConfig,
        WdfIoQueueDispatchSequential
        );

    ioQueueConfig.EvtIoDeviceControl = RamDiskEvtIoDeviceControl;
    ioQueueConfig.EvtIoRead          = RamDiskEvtIoRead;
    ioQueueConfig.EvtIoWrite         = RamDiskEvtIoWrite;

    WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&queueAttributes, QUEUE_EXTENSION);

    //
    // By default, Static Driver Verifier (SDV) displays a warning if it 
    // doesn't find the EvtIoStop callback on a power-managed queue. 
    // The 'assume' below causes SDV to suppress this warning. If the driver 
    // has not explicitly set PowerManaged to WdfFalse, the framework creates
    // power-managed queues when the device is not a filter driver.  Normally 
    // the EvtIoStop is required for power-managed queues, but for this driver
    // it is not needed b/c the driver doesn't hold on to the requests or 
    // forward them to other drivers. This driver completes the requests 
    // directly in the queue's handlers. If the EvtIoStop callback is not 
    // implemented, the framework waits for all driver-owned requests to be
    // done before moving in the Dx/sleep states or before removing the 
    // device, which is the correct behavior for this type of driver.
    // If the requests were taking an indeterminate amount of time to complete,
    // or if the driver forwarded the requests to a lower driver/another stack,
    // the queue should have an EvtIoStop/EvtIoResume.
    //
    __analysis_assume(ioQueueConfig.EvtIoStop != 0);
    status = WdfIoQueueCreate( device,
                               &ioQueueConfig,
                               &queueAttributes,
                               &queue );
    __analysis_assume(ioQueueConfig.EvtIoStop == 0);
    if (!NT_SUCCESS(status)) {
        return status;
    }

     // Context is the Queue handle
    pQueueContext = QueueGetExtension(queue);

    //
    // Set the context for our default queue as our device extension.
    //
    pQueueContext->DeviceExtension = pDeviceExtension;

#if KMDF_VERSION_MINOR >= 9

    //
    // Enable forward progress on the queue we just created.
    // NOTE: If you are planning to use this code without forward progress,
    // comment out the call to SetForwardProgressOnQueue below. 
    //
    status = SetForwardProgressOnQueue(queue);
    if (!NT_SUCCESS(status)) {
        return status;
    }

#endif

    //
    // Now do any RAM-Disk specific initialization
    //
    pDeviceExtension->DiskRegInfo.DriveLetter.Buffer =
        (PWSTR) &pDeviceExtension->DriveLetterBuffer;
    pDeviceExtension->DiskRegInfo.DriveLetter.MaximumLength =
        sizeof(pDeviceExtension->DriveLetterBuffer);

    //
    // Get the disk parameters from the registry
    //
    RamDiskQueryDiskRegParameters(
        WdfDriverGetRegistryPath(WdfDeviceGetDriver(device)),
        &pDeviceExtension->DiskRegInfo
        );

    //
    // Allocate memory for the disk image.
    //
    pDeviceExtension->DiskImage = ExAllocatePoolWithTag(
        NonPagedPool,
        pDeviceExtension->DiskRegInfo.DiskSize,
        RAMDISK_TAG
        );

    if (pDeviceExtension->DiskImage) {

        UNICODE_STRING deviceName;
        UNICODE_STRING win32Name;

        RamDiskFormatDisk(pDeviceExtension);

        status = STATUS_SUCCESS;

        //
        // Now try to create a symbolic link for the drive letter.
        //
        RtlInitUnicodeString(&win32Name, DOS_DEVICE_NAME);
        RtlInitUnicodeString(&deviceName, NT_DEVICE_NAME);

        pDeviceExtension->SymbolicLink.Buffer = (PWSTR)
            &pDeviceExtension->DosDeviceNameBuffer;
        pDeviceExtension->SymbolicLink.MaximumLength =
            sizeof(pDeviceExtension->DosDeviceNameBuffer);
        pDeviceExtension->SymbolicLink.Length = win32Name.Length;

        RtlCopyUnicodeString(&pDeviceExtension->SymbolicLink, &win32Name);
        RtlAppendUnicodeStringToString(&pDeviceExtension->SymbolicLink,
                                       &pDeviceExtension->DiskRegInfo.DriveLetter);

        status = WdfDeviceCreateSymbolicLink(device,
                                             &pDeviceExtension->SymbolicLink);
    }

    return status;
}
Exemplo n.º 3
0
//-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DriverParametersSubKeyDelete -.-.-.-.-.-.-.-.-.-.-.-.-.-.-
//
NTSTATUS  DriverParametersSubKeyDelete(
    WDFDRIVER  Driver,
    DtString*  pKeyName)
{
    NTSTATUS  NtStatus = STATUS_SUCCESS;
    DtStringChar*  pRegistryPath;
    DtString  RegistryPath;
    DtString  FullKeyName;
    UInt  PathLength;
    HANDLE  hKey;
    OBJECT_ATTRIBUTES  ObjectAttributes;
    KEY_BASIC_INFORMATION*  pKeyInfo;
    ULONG  Size;
    ULONG  ResultSize;
    Int  Index;
    
    DT_STRING_DECL(ParamItemName, "\\Parameters\\");

    DT_ASSERT(KeGetCurrentIrql()<=PASSIVE_LEVEL);

    // Build the full path
    pRegistryPath = WdfDriverGetRegistryPath(Driver);
    PathLength = wcslen(pRegistryPath); 

    DT_STRING_INIT_CONST(RegistryPath, pRegistryPath, PathLength);

    // Allocate struct for key information result
    Size = sizeof(KEY_BASIC_INFORMATION)+100;
    pKeyInfo = DtMemAllocPool(DtPoolNonPaged, Size, SAL_TAG);
    if (pKeyInfo == NULL)
        return STATUS_NO_MEMORY;

    // Allocate a new DtString buffer for the complete path inclusive a '\0' character
    // and extra '\\'
    if (!DT_SUCCESS(DtStringAlloc(&FullKeyName, PathLength+
                                                  DtStringGetStringLength(&ParamItemName)+
                                                  DtStringGetStringLength(pKeyName)+
                                                  100+1+1)))
    {
        DtMemFreePool(pKeyInfo, SAL_TAG);
        return STATUS_NO_MEMORY;
    }

    DtStringAppendDtString(&FullKeyName, &RegistryPath);
    DtStringAppendDtString(&FullKeyName, &ParamItemName);
    DtStringAppendDtString(&FullKeyName, pKeyName);

    // Initialize key to open
    InitializeObjectAttributes(&ObjectAttributes, &FullKeyName, OBJ_KERNEL_HANDLE, NULL,
                                                                                    NULL);
    
    NtStatus = ZwOpenKey(&hKey, KEY_ENUMERATE_SUB_KEYS , &ObjectAttributes);
    
    if (NT_SUCCESS(NtStatus)) 
    {
        Index = 0;
        NtStatus = STATUS_SUCCESS;
        // Enumerate all keys
        while (NtStatus != STATUS_NO_MORE_ENTRIES)
        {
            NtStatus = ZwEnumerateKey(hKey, Index, KeyBasicInformation, pKeyInfo, Size,
                                                                             &ResultSize);
            if (NT_SUCCESS(NtStatus))
            {
                DtString SubKey;

                // Build key to delete
                pKeyInfo->Name[pKeyInfo->NameLength/2] = L'\0';
                DT_STRING_INIT_CONST(SubKey, pKeyInfo->Name, ((USHORT)pKeyInfo->NameLength/2));

                DtStringClear(&FullKeyName);
                DtStringAppendDtString(&FullKeyName, pKeyName);
                DtStringAppendChars(&FullKeyName, "\\");
                DtStringAppendDtString(&FullKeyName, &SubKey);
                
                DtDbgOut(MAX, SAL, "Delete SubKey %S.", FullKeyName.Buffer);
                NtStatus = DriverParametersKeyDelete(Driver, &FullKeyName);
                if (!NT_SUCCESS(NtStatus))
                    DtDbgOut(ERR, SAL, "Error deleting SubKey %S. Error: %x", 
                                                            FullKeyName.Buffer, NtStatus);
            }
            // In case deletion failed, skip this entry
            if (!NT_SUCCESS(NtStatus)) 
                Index++;
        }
        NtStatus = ZwDeleteKey(hKey);
        ZwClose(hKey);
    }
    DtMemFreePool(pKeyInfo, SAL_TAG);
    DtStringFree(&FullKeyName);
    return NtStatus;
}
Exemplo n.º 4
0
// 添加设备
NTSTATUS RamDiskEvtDeviceAdd(IN WDFDRIVER Driver,IN PWDFDEVICE_INIT DeviceInit)
{
    WDF_OBJECT_ATTRIBUTES   deviceAttributes;
    NTSTATUS                status;
    WDFDEVICE               device;
    WDF_OBJECT_ATTRIBUTES   queueAttributes;
    WDF_IO_QUEUE_CONFIG     ioQueueConfig;
    PDEVICE_EXTENSION       pDeviceExtension;
    PQUEUE_EXTENSION        pQueueContext = NULL;
    WDFQUEUE                queue;
    //设备名
    DECLARE_CONST_UNICODE_STRING(ntDeviceName, NT_DEVICE_NAME);

    PAGED_CODE();

    UNREFERENCED_PARAMETER(Driver);

    //检查指定名称状态
    status = WdfDeviceInitAssignName(DeviceInit, &ntDeviceName);
    if (!NT_SUCCESS(status))
    {
        return status;
    }
    //指定设备类型
    WdfDeviceInitSetDeviceType(DeviceInit, FILE_DEVICE_DISK);
    //IO类型
    WdfDeviceInitSetIoType(DeviceInit, WdfDeviceIoDirect);
    //是否独占
    WdfDeviceInitSetExclusive(DeviceInit, FALSE);
    //初始化
    WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&deviceAttributes, DEVICE_EXTENSION);
    //设定cleanup 函数指针
    deviceAttributes.EvtCleanupCallback = RamDiskEvtDeviceContextCleanup;
    //获取创建设备状态
    status = WdfDeviceCreate(&DeviceInit, &deviceAttributes, &device);
    if (!NT_SUCCESS(status))
    {
        return status;
    }

    pDeviceExtension = DeviceGetExtension(device);

    //
    // Configure a default queue so that requests that are not
    // configure-fowarded using WdfDeviceConfigureRequestDispatching to goto
    // other queues get dispatched here.
    //
    WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE (&ioQueueConfig,WdfIoQueueDispatchSequential);

    ioQueueConfig.EvtIoDeviceControl = RamDiskEvtIoDeviceControl;
    ioQueueConfig.EvtIoRead          = RamDiskEvtIoRead;
    ioQueueConfig.EvtIoWrite         = RamDiskEvtIoWrite;

    WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&queueAttributes, QUEUE_EXTENSION);

    status = WdfIoQueueCreate( device,&ioQueueConfig,&queueAttributes,&queue );

    if (!NT_SUCCESS(status))
    {
        return status;
    }

    //获得设备扩展
    pQueueContext = QueueGetExtension(queue);

    //设置队列的设备扩展为该设备
    pQueueContext->DeviceExtension = pDeviceExtension;

    status = SetForwardProgressOnQueue(queue);
    if (!NT_SUCCESS(status))
    {
        return status;
    }

    //设备初始化
    pDeviceExtension->DiskRegInfo.DriveLetter.Buffer = (PWSTR) &pDeviceExtension->DriveLetterBuffer;
    pDeviceExtension->DiskRegInfo.DriveLetter.MaximumLength = sizeof(pDeviceExtension->DriveLetterBuffer);

    //从注册表获取信息
    RamDiskQueryDiskRegParameters(WdfDriverGetRegistryPath(WdfDeviceGetDriver(device)),&pDeviceExtension->DiskRegInfo);

    //内存分配 要使用分页内存
    pDeviceExtension->DiskImage = ExAllocatePoolWithTag(PagedPool,pDeviceExtension->DiskRegInfo.DiskSize,RAMDISK_TAG);

    if (pDeviceExtension->DiskImage)
    {
        //成功分配
        UNICODE_STRING deviceName;
        UNICODE_STRING win32Name;

        RamDiskFormatDisk(pDeviceExtension);
        //格式化
        status = STATUS_SUCCESS;

        //创建符号链接
        RtlInitUnicodeString(&win32Name, DOS_DEVICE_NAME);
        RtlInitUnicodeString(&deviceName, NT_DEVICE_NAME);

        //符号链接初始化
        pDeviceExtension->SymbolicLink.Buffer = (PWSTR)&pDeviceExtension->DosDeviceNameBuffer;
        pDeviceExtension->SymbolicLink.MaximumLength = sizeof(pDeviceExtension->DosDeviceNameBuffer);
        pDeviceExtension->SymbolicLink.Length = win32Name.Length;

        RtlCopyUnicodeString(&pDeviceExtension->SymbolicLink, &win32Name);
        RtlAppendUnicodeStringToString(&pDeviceExtension->SymbolicLink,&pDeviceExtension->DiskRegInfo.DriveLetter);
        //创建符号链接
        status = WdfDeviceCreateSymbolicLink(device,&pDeviceExtension->SymbolicLink);
    }

    return status;
}
Exemplo n.º 5
0
NTSTATUS
RamDiskEvtDeviceAdd(
    IN WDFDRIVER Driver,
    IN PWDFDEVICE_INIT DeviceInit
    )
/*++
Routine Description:

    EvtDeviceAdd is called by the framework in response to AddDevice
    call from the PnP manager. We create and initialize a device object to
    represent a new instance of the device.

Arguments:

    Driver - Handle to a framework driver object created in DriverEntry

    DeviceInit - Pointer to a framework-allocated WDFDEVICE_INIT structure.

Return Value:

    NTSTATUS

--*/
{
    WDF_OBJECT_ATTRIBUTES   deviceAttributes;
    NTSTATUS                status;
    WDFDEVICE               device;
    WDF_OBJECT_ATTRIBUTES   queueAttributes;
    WDF_IO_QUEUE_CONFIG     ioQueueConfig;
    PDEVICE_EXTENSION       pDeviceExtension;
    PQUEUE_EXTENSION        pQueueContext = NULL;
    WDFQUEUE                queue;
    DECLARE_CONST_UNICODE_STRING(ntDeviceName, NT_DEVICE_NAME);

    PAGED_CODE();

    UNREFERENCED_PARAMETER(Driver);

    //
    // Storage drivers have to name their FDOs. Since we are not unique'fying
    // the device name, we wouldn't be able to install more than one instance
    // of this ramdisk driver.
    //
    status = WdfDeviceInitAssignName(DeviceInit, &ntDeviceName);
    if (!NT_SUCCESS(status)) {
        return status;
    }

    WdfDeviceInitSetDeviceType(DeviceInit, FILE_DEVICE_DISK);
    WdfDeviceInitSetIoType(DeviceInit, WdfDeviceIoDirect);
    WdfDeviceInitSetExclusive(DeviceInit, FALSE);

    //
    // Since this is a pure software only driver, there is no need to register
    // any PNP/Power event callbacks. Framework will respond to these
    // events appropriately.
    //
    WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&deviceAttributes, DEVICE_EXTENSION);
    deviceAttributes.EvtCleanupCallback = RamDiskEvtDeviceContextCleanup;

    status = WdfDeviceCreate(&DeviceInit, &deviceAttributes, &device);
    if (!NT_SUCCESS(status)) {
        return status;
    }

    //
    // Now that the WDF device object has been created, set up any context
    // that it requires.
    //

    pDeviceExtension = DeviceGetExtension(device);

    //
    // Configure a default queue so that requests that are not
    // configure-fowarded using WdfDeviceConfigureRequestDispatching to goto
    // other queues get dispatched here.
    //
    WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE (
        &ioQueueConfig,
        WdfIoQueueDispatchSequential
        );

    ioQueueConfig.EvtIoDeviceControl = RamDiskEvtIoDeviceControl;
    ioQueueConfig.EvtIoRead          = RamDiskEvtIoRead;
    ioQueueConfig.EvtIoWrite         = RamDiskEvtIoWrite;

    WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&queueAttributes, QUEUE_EXTENSION);

    status = WdfIoQueueCreate( device,
                               &ioQueueConfig,
                               &queueAttributes,
                               &queue );
    if (!NT_SUCCESS(status)) {
        return status;
    }

     // Context is the Queue handle
    pQueueContext = QueueGetExtension(queue);

    //
    // Set the context for our default queue as our device extension.
    //
    pQueueContext->DeviceExtension = pDeviceExtension;

    //
    // Enable forward progress on the queue we just created.
    // NOTE: If you are planning to use this code without forward progress,
    // comment out the call to SetForwardProgressOnQueue below. 
    //
    status = SetForwardProgressOnQueue(queue);
    if (!NT_SUCCESS(status)) {
        return status;
    }

    //
    // Now do any RAM-Disk specific initialization
    //
    pDeviceExtension->DiskRegInfo.DriveLetter.Buffer =
        (PWSTR) &pDeviceExtension->DriveLetterBuffer;
    pDeviceExtension->DiskRegInfo.DriveLetter.MaximumLength =
        sizeof(pDeviceExtension->DriveLetterBuffer);

    //
    // Get the disk parameters from the registry
    //
    RamDiskQueryDiskRegParameters(
        WdfDriverGetRegistryPath(WdfDeviceGetDriver(device)),
        &pDeviceExtension->DiskRegInfo
        );

    //
    // Allocate memory for the disk image.
    //
    pDeviceExtension->DiskImage = ExAllocatePoolWithTag(
        NonPagedPool,
        pDeviceExtension->DiskRegInfo.DiskSize,
        RAMDISK_TAG
        );

    if (pDeviceExtension->DiskImage) {

        UNICODE_STRING deviceName;
        UNICODE_STRING win32Name;

        RamDiskFormatDisk(pDeviceExtension);

        status = STATUS_SUCCESS;

        //
        // Now try to create a symbolic link for the drive letter.
        //
        RtlInitUnicodeString(&win32Name, DOS_DEVICE_NAME);
        RtlInitUnicodeString(&deviceName, NT_DEVICE_NAME);

        pDeviceExtension->SymbolicLink.Buffer = (PWSTR)
            &pDeviceExtension->DosDeviceNameBuffer;
        pDeviceExtension->SymbolicLink.MaximumLength =
            sizeof(pDeviceExtension->DosDeviceNameBuffer);
        pDeviceExtension->SymbolicLink.Length = win32Name.Length;

        RtlCopyUnicodeString(&pDeviceExtension->SymbolicLink, &win32Name);
        RtlAppendUnicodeStringToString(&pDeviceExtension->SymbolicLink,
                                       &pDeviceExtension->DiskRegInfo.DriveLetter);

        status = WdfDeviceCreateSymbolicLink(device,
                                             &pDeviceExtension->SymbolicLink);
    }

    return status;
}