UWP 应用程序使用 "CustomDevice.FromIdAsync" 访问 KMDF driver 被拒绝

UWP application use "CustomDevice.FromIdAsync" access KMDF driver is denied

I found a similar , but it probably didn't help me much.

我正在学习通过 UWP 访问驱动器设备,前两天,程序工作正常,但是今天,打开设备时 UWP 错误关闭,错误消息是 “访问被拒绝。HRESULT 异常:0x80070005”

不知道是不是更新过程中修改了什么导致了这个问题。我只有一个可以打开驱动设备的虚拟机的快照。在这个快照上,当我更新UWP应用程序时,我也可以打开驱动设备,但是更新driver后,UWP应用程序无法再打开driver设备。

这是否意味着 driver 有问题?

之后我新建了一个KMDF工程和一个UWP工程,只打印了一些信息,安装到虚拟机后出现同样的错误

值得注意的是,当我在DbgView中看到UWP访问驱动设备时,触发了EvtDeviceFileCreate事件回调,但是马上触发了EvtDeviceClose事件回调,我想,设备接口应该没有问题。

此外,一开始,我使用设备管理器“添加旧硬件”来加载 driver,然后我尝试使用 devcon 安装 driver,两者可以安装driver,但是好像有点不一样,我不确定这是否也会有影响,虽然这两种安装方式目前都没有解决我遇到的问题。

以下是 UWP 应用和 drivers 的一些设置。

注册设备接口并添加自定义功能:

这部分我参考了微软官方的示例kmdf_fx2

    WDFSTRING symbolicLinkString = NULL;
    UNICODE_STRING symbolicLinkName = SymbolicName;
    DEVPROP_BOOLEAN isRestricted;
    status = WdfDeviceCreateDeviceInterface(
        hDevice,
        (LPGUID)&GUID_INTERFACE_HSADRVSAMPLE1,
        NULL); // Reference String
    if (!NT_SUCCESS(status)) {
        KdPrint(("WdfDeviceCreateDeviceInterface Fail\n"));
        goto Error;
    }
    if (g_pIoSetDeviceInterfacePropertyData != NULL) {
        status = WdfStringCreate(NULL,
            WDF_NO_OBJECT_ATTRIBUTES,
            &symbolicLinkString);
        if (!NT_SUCCESS(status)) {
            KdPrint(("WdfStringCreate Fail\n"));
            goto Error;
        }
        status = WdfDeviceRetrieveDeviceInterfaceString(
            hDevice,
            (LPGUID)&GUID_INTERFACE_HSADRVSAMPLE1,
            NULL,
            symbolicLinkString);
        if (!NT_SUCCESS(status)) {
            KdPrint(("WdfDeviceRetrieveDeviceInterfaceString Fail\n"));
            goto Error;
        }
        WdfStringGetUnicodeString(symbolicLinkString, &symbolicLinkName);
        isRestricted = DEVPROP_TRUE;
        status = g_pIoSetDeviceInterfacePropertyData(
            &symbolicLinkName,
            &DEVPKEY_DeviceInterface_Restricted,
            0,
            0,
            DEVPROP_TYPE_BOOLEAN,
            sizeof(isRestricted),
            &isRestricted);
        if (!NT_SUCCESS(status)) {
            KdPrint(("g_pIoSetDeviceInterfacePropertyData Fail\n"));
            goto Error;
        }

#if defined(NTDDI_WIN10_RS2) && (NTDDI_VERSION >= NTDDI_WIN10_RS2)
        static const wchar_t customCapabilities[] = L"ColinTest.HSADrvSample_2022051717171[=12=]";
        status = g_pIoSetDeviceInterfacePropertyData(
            &symbolicLinkName,
            &DEVPKEY_DeviceInterface_UnrestrictedAppCapabilities,
            0,
            0,
            DEVPROP_TYPE_STRING_LIST,
            sizeof(customCapabilities),
            (PVOID)&customCapabilities);
        if (!NT_SUCCESS(status)) {
            KdPrint(("g_pIoSetDeviceInterfacePropertyData Fail\n"));
            goto Error;
        }
#endif

        WdfObjectDelete(symbolicLinkString);
    }
Error:
    if (symbolicLinkString != NULL) {
        WdfObjectDelete(symbolicLinkString);
    }

Driver INF:

;
; HSADrvSample1.inf
;

[Version]
Signature="$WINDOWS NT$"
Class=Test ; TODO: edit Class
ClassGuid={160303BD-D84C-4819-B962-9B1BDBB52310} ; TODO: edit ClassGuid
Provider=%ManufacturerName%
CatalogFile=HSADrvSample1.cat
DriverVer = 05/19/2022,9.21.50.151
PnpLockDown=1

[DestinationDirs]
DefaultDestDir = 12
HSADrvSample1_Device_CoInstaller_CopyFiles = 11

; ================= Class section =====================

[ClassInstall32]
Addreg=SampleClassReg

[SampleClassReg]
HKR,,,0,%ClassName%
HKR,,Icon,,-5

[SourceDisksNames]
1 = %DiskName%,,,""

[SourceDisksFiles]
HSADrvSample1.sys  = 1,,
WdfCoInstaller01011.dll=1 ; make sure the number matches with SourceDisksNames

;*****************************************
; Install Section
;*****************************************

[Manufacturer]
%ManufacturerName%=Standard,NTamd64

[Standard.NTamd64]
%HSADrvSample1.DeviceDesc%=HSADrvSample1_Device, Root\HSADrvSample1 ; TODO: edit hw-id

[HSADrvSample1_Device.NT]
CopyFiles=Drivers_Dir

[Drivers_Dir]
HSADrvSample1.sys

;-------------- Service installation
[HSADrvSample1_Device.NT.Services]
AddService = HSADrvSample1,%SPSVCINST_ASSOCSERVICE%, HSADrvSample1_Service_Inst

; -------------- HSADrvSample1 driver install sections
[HSADrvSample1_Service_Inst]
DisplayName    = %HSADrvSample1.SVCDESC%
ServiceType    = 1               ; SERVICE_KERNEL_DRIVER
StartType      = 3               ; SERVICE_DEMAND_START
ErrorControl   = 1               ; SERVICE_ERROR_NORMAL
ServiceBinary  = %12%\HSADrvSample1.sys

;
;--- HSADrvSample1_Device Coinstaller installation ------
;

[HSADrvSample1_Device.NT.CoInstallers]
AddReg=HSADrvSample1_Device_CoInstaller_AddReg
CopyFiles=HSADrvSample1_Device_CoInstaller_CopyFiles

[HSADrvSample1_Device_CoInstaller_AddReg]
HKR,,CoInstallers32,0x00010000, "WdfCoInstaller01011.dll,WdfCoInstaller"

[HSADrvSample1_Device_CoInstaller_CopyFiles]
WdfCoInstaller01011.dll

[HSADrvSample1_Device.NT.Wdf]
KmdfService =  HSADrvSample1, HSADrvSample1_wdfsect
[HSADrvSample1_wdfsect]
KmdfLibraryVersion = 1.11

[Strings]
SPSVCINST_ASSOCSERVICE= 0x00000002
ManufacturerName="Colin" ;TODO: Replace with your manufacturer name
ClassName="Test" ; TODO: edit ClassName
DiskName = "HSADrvSample1 Installation Disk"
HSADrvSample1.DeviceDesc = "HSADrvSample1 Device"
HSADrvSample1.SVCDESC = "HSADrvSample1 Service"

SCCD文件:

文件按照官方文档配置Hardware Support App (HSA): Steps for App Developers,文件已经设置为content.

<?xml version="1.0" encoding="utf-8"?>
<CustomCapabilityDescriptor xmlns="http://schemas.microsoft.com/appx/2018/sccd" xmlns:s="http://schemas.microsoft.com/appx/2018/sccd">
    <CustomCapabilities>
        <CustomCapability Name="ColinTest.HSADrvSample_2022051717171"></CustomCapability>
    <AuthorizedEntities>
        <AuthorizedEntity AppPackageFamilyName="Colin.HSA.APP_4a8dxf1xdwf12" CertificateSignatureHash="2d6e4f1418bc13447bb8c10067d0af418cb8a2f9e14c014e03a1e0ec811735af"></AuthorizedEntity>
    </AuthorizedEntities>
    <Catalog>FFFF</Catalog>
</CustomCapabilityDescriptor>

部分Package.appxmanifest:

  <Capabilities>
    <Capability Name="internetClient" />
      <uap4:CustomCapability Name="ColinTest.HSADrvSample_2022051717171"/>
  </Capabilities>

部分UWP代码:

string selector = CustomDevice.GetDeviceSelector(DeviceInterfaceGuid);
            DeviceInformationCollection enumDevice = await DeviceInformation.FindAllAsync(selector);
            string DeviceID = enumDevice[0].Id;
            try
            {
                CustomDevice Device = await CustomDevice.FromIdAsync(DeviceID, DeviceAccessMode.ReadWrite, DeviceSharingMode.Shared);
                if (null != Device)
                {
                    Note.Text = "Open successfully";
                }
            }
            catch (Exception ex)
            {
                Note.Text = "Failed to open!" + ex.Message;
            }

我想知道我在哪一步遇到了错误?如何解决?


At the suggestion of @Nico Zhu - MSFT, I checked the CustomCapabilityName again.

我的代码中有三个地方与CustomCapabilityName有关,但它们都是相同的。 为了测试问题是否出在这里,我重置 名称。

  1. Driver代码
static const wchar_t customCapabilities[] = L"Test.hsaTestCustomCapability_1653011401000[=17=]";
  1. CustomCapability.SCCD
<?xml version="1.0" encoding="utf-8"?>
<CustomCapabilityDescriptor xmlns="http://schemas.microsoft.com/appx/2018/sccd" xmlns:s="http://schemas.microsoft.com/appx/2018/sccd">
    <CustomCapabilities>
        <CustomCapability Name="Test.hsaTestCustomCapability_1653011401000"></CustomCapability>
    </CustomCapabilities>
    <AuthorizedEntities AllowAny="true"/>
    <Catalog>0000</Catalog>
</CustomCapabilityDescriptor>
  1. Package.appxmanifest
  <Capabilities>
    <Capability Name="internetClient" />
      <uap4:CustomCapability Name="Test.hsaTestCustomCapability_1653011401000"/>
  </Capabilities>

之后,我卸载之前安装的应用程序和drivers,重新启动并安装了最新版本的程序,但我仍然无法访问它。

我的SDK和WDK版本是10.0.19041.0,测试机OS版本是Windows10 Pro Build19041.vb_release.191206-1406

我想我犯了一个low-level错误,设置设备接口属性的函数g_pIoSetDeviceInterfacePropertyData需要在DriverEntry中设置。 但是我没有,导致我设置的CustomCapabilityName没有生效

    UNICODE_STRING funcName;

    RtlInitUnicodeString(&funcName, L"IoSetDeviceInterfacePropertyData");
    g_pIoSetDeviceInterfacePropertyData = (PFN_IO_SET_DEVICE_INTERFACE_PROPERTY_DATA)(ULONG_PTR)
        MmGetSystemRoutineAddress(&funcName);

不过,驱动在最初始的版本为什么能正常运行,至今仍是未解之谜...