예제 #1
0
파일: driver.c 프로젝트: kcrazy/winekit
NTSTATUS
FmCreateDosDevicesSymbolicLink(
                              WDFDEVICE       Device,
                              PFM_DEVICE_DATA FmDeviceData
                              )
{
    NTSTATUS        status;
    UNICODE_STRING  comPort;
    UNICODE_STRING  pdoName;
    UNICODE_STRING  symbolicLink;
    WDFKEY          hKey = NULL;
    DECLARE_CONST_UNICODE_STRING(valueName, L"PortName");
    WDFSTRING       string = NULL;
    WDFMEMORY       memory;
    WDF_OBJECT_ATTRIBUTES  memoryAttributes;
    size_t          bufferLength;


    PAGED_CODE();

    symbolicLink.Buffer = NULL;

    //
    // Open the device registry and read the "PortName" value written by the
    // class installer.
    //
    status = WdfDeviceOpenRegistryKey(Device,
                                      PLUGPLAY_REGKEY_DEVICE,
                                      STANDARD_RIGHTS_ALL,
                                      NULL, // PWDF_OBJECT_ATTRIBUTES
                                      &hKey);

    if (!NT_SUCCESS (status)) {
        goto Error;
    }
    status = WdfStringCreate(
                            NULL,
                            WDF_NO_OBJECT_ATTRIBUTES ,
                            &string
                            );

    if (!NT_SUCCESS(status)) {
        goto Error;
    }

    //
    // Retrieve the value of ValueName from registry
    //
    status = WdfRegistryQueryString(
                                   hKey,
                                   &valueName,
                                   string
                                   );


    if (!NT_SUCCESS (status)) {
        goto Error;
    }

    //
    // Retrieve the UNICODE_STRING from string object
    //
    WdfStringGetUnicodeString(
                             string,
                             &comPort
                             );

    WdfRegistryClose(hKey);
    hKey = NULL;

    symbolicLink.Length=0;
    symbolicLink.MaximumLength = sizeof(OBJECT_DIRECTORY) + comPort.MaximumLength;

    symbolicLink.Buffer = ExAllocatePoolWithTag(PagedPool,
                                                symbolicLink.MaximumLength + sizeof(WCHAR),
                                                'wkaF');

    if (symbolicLink.Buffer == NULL) {
        status = STATUS_INSUFFICIENT_RESOURCES;
        goto Error;
    }
    RtlZeroMemory(symbolicLink.Buffer, symbolicLink.MaximumLength);
    RtlAppendUnicodeToString(&symbolicLink, OBJECT_DIRECTORY);
    RtlAppendUnicodeStringToString(&symbolicLink, &comPort);
    //
    // This DDI will get the underlying PDO name and create a symbolic to that
    // because our FDO doesn't have a name.
    //
    status = WdfDeviceCreateSymbolicLink(Device,
                                         &symbolicLink);

    if (!NT_SUCCESS(status)) {
        goto Error;
    }

    WDF_OBJECT_ATTRIBUTES_INIT(&memoryAttributes);
    memoryAttributes.ParentObject = Device;

    status = WdfDeviceAllocAndQueryProperty(Device,
                                            DevicePropertyPhysicalDeviceObjectName,
                                            PagedPool,
                                            &memoryAttributes,
                                            &memory);
    if (!NT_SUCCESS(status)) {
        //
        // We expect a zero length buffer. Anything else is fatal.
        //
        goto Error;
    }

    pdoName.Buffer = WdfMemoryGetBuffer(memory, &bufferLength);

    if (pdoName.Buffer == NULL) {
        status = STATUS_INSUFFICIENT_RESOURCES;
        goto Error;

    }
    pdoName.MaximumLength = (USHORT) bufferLength;
    pdoName.Length = (USHORT) bufferLength - sizeof(UNICODE_NULL);

    status = RtlWriteRegistryValue(RTL_REGISTRY_DEVICEMAP,
                                   L"SERIALCOMM",
                                   pdoName.Buffer,
                                   REG_SZ,
                                   comPort.Buffer,
                                   comPort.Length);

    if (!NT_SUCCESS(status)) {
        goto Error;
    }
    FmDeviceData->Flags |= REG_VALUE_CREATED_FLAG;
    //
    // Store it so it can be deleted later.
    //

    FmDeviceData->PdoName = pdoName;

    Error:

    if (symbolicLink.Buffer != NULL) {
        ExFreePool(symbolicLink.Buffer);
    }

    if (hKey != NULL) {
        WdfRegistryClose(hKey);
    }
    if (string != NULL) {
        WdfObjectDelete(string);
    }

    return status;
}
예제 #2
0
//-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- DriverParametersKeyRead -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.
//
NTSTATUS  DriverParametersKeyRead(
    WDFDRIVER  Driver,
    DtString*  pKeyName,
    DtString*  pValueName,
    Int64*  pBinValue,
    DtString*  pStrValue)
{
    NTSTATUS  NtStatus;
    WDFKEY  ParametersKey;
    WDFKEY  Key = NULL;
    WDFSTRING WdfString = NULL;   
    DtString  RegStrValue;

    DT_ASSERT(KeGetCurrentIrql()<=PASSIVE_LEVEL);


    // Only one value can be requested
    DT_ASSERT((pBinValue!=NULL && pStrValue==NULL)||(pBinValue==NULL && pStrValue!=NULL));

    // Open the drivers parameters key (under services)
    NtStatus = WdfDriverOpenParametersRegistryKey(Driver, KEY_READ,
                                                WDF_NO_OBJECT_ATTRIBUTES, &ParametersKey);
    if (!NT_SUCCESS(NtStatus))
    {
        DtDbgOut(ERR, SAL, "WdfDriverOpenParametersRegistryKey failed. Error: 0x%x", 
                                                                                NtStatus);
        return NtStatus;
    }

    // Open subkey
    NtStatus = WdfRegistryOpenKey(ParametersKey, pKeyName, KEY_READ, 
                                                          WDF_NO_OBJECT_ATTRIBUTES, &Key);
    if (!NT_SUCCESS(NtStatus))
    {
        if (NtStatus == STATUS_OBJECT_NAME_NOT_FOUND)
            DtDbgOut(MAX, SAL, "WdfRegistryOpenKey error:'STATUS_OBJECT_NAME_NOT_FOUND'");
        else
            DtDbgOut(ERR, SAL, "WdfRegistryOpenKey failed. Error: 0x%x", NtStatus);
    }

    if (NT_SUCCESS(NtStatus))
    {
        // Read string or binary value
        if (pStrValue != NULL)
        {
            // Set string attributes with the key as parent object, so that the string 
            // object is freed when the key object is destroyed. If we donot do this the
            // string object is freed when the driver unloads, meaning that the each call 
            // to DriverParametersKeyRead result in an increase of memory usage, only 
            // to be freed on the unload.
            WDF_OBJECT_ATTRIBUTES  WdfStringAttr;
            WDF_OBJECT_ATTRIBUTES_INIT(&WdfStringAttr);
            WdfStringAttr.ParentObject = Key;
            NtStatus = WdfStringCreate(pStrValue, &WdfStringAttr, &WdfString);

            // Read string from registry
            if (NT_SUCCESS(NtStatus))
                NtStatus = WdfRegistryQueryString(Key, pValueName, WdfString);

            // Convert WdfString to DtString
            if (NT_SUCCESS(NtStatus))
                WdfStringGetUnicodeString(WdfString, &RegStrValue);

            // Make a copy of the string
            if (NT_SUCCESS(NtStatus))
                NtStatus = DtStringClear(pStrValue);
            if (NT_SUCCESS(NtStatus))
                NtStatus = DtStringAppendDtString(pStrValue, &RegStrValue);
        }
        else
            NtStatus = WdfRegistryQueryValue(Key, pValueName, sizeof(Int64), pBinValue,
                                                                              NULL, NULL);

        if (!NT_SUCCESS(NtStatus))
        {
            if (NtStatus == STATUS_OBJECT_NAME_NOT_FOUND)
                DtDbgOut(MAX, SAL, "WdfRegistryQueryValue error:"
                                                        "'STATUS_OBJECT_NAME_NOT_FOUND'");
            else
                DtDbgOut(ERR, SAL, "WdfRegistryQueryValue failed. Error: 0x%x", NtStatus);
        }
    }
    if (Key != NULL)
        WdfRegistryClose(Key);
    WdfRegistryClose(ParametersKey);
    return NtStatus;
}