Segn 发表于 2022-5-18 13:47

UWP无法访问KMDF驱动程序

本帖最后由 Segn 于 2022-5-24 15:58 编辑

我正在学习KMDF驱动程序与UWP应用开发,尝试通过UWP应用与KMDF驱动程序通信,根据[面向应用开发人员的硬件支持应用 (HSA) 步骤 - Windows drivers | Microsoft Docs](https://docs.microsoft.com/zh-cn/windows-hardware/drivers/devapps/hardware-support-app--hsa--steps-for-app-developers)实现了,但是对驱动和UWP进行了一些更新后,UWP访问KMDF驱动会发生异常(拒绝访问。(Exception from HRESULT:0x80070005))
我不知道是否是在对UWP应用和驱动的更新过程中修改了什么发生了错误,因此我重新编写了一个驱动程序及其对应的UWP应用,同样发生了这个异常,下面是关于驱动程序和UWP应用的部分配置。
我想知道是什么导致了这个问题,如何解决这个问题?
驱动程序添加接口与自定义功能:
```cpp
      WDFSTRING symbolicLinkString = NULL;
      UNICODE_STRING symbolicLinkName = SymbolicName;//符号链接名称
      DEVPROP_BOOLEAN isRestricted;
      status = WdfDeviceCreateDeviceInterface(
                Device,
                (LPGUID)&GUID_DEVINTERFACE_HSADrvSample,//设备接口GUID
                NULL); // Reference String
      if (!NT_SUCCESS(status)) {
                KdPrint(("HSADrvSample:\tWdfDeviceCreateDeviceInterface failed with errorcode:%x\n", status));
                goto Error;
      }
      if (g_pIoSetDeviceInterfacePropertyData != NULL) {
                status = WdfStringCreate(NULL,
                        WDF_NO_OBJECT_ATTRIBUTES,
                        &symbolicLinkString);
                if (!NT_SUCCESS(status)) {
                        KdPrint(("HSADrvSample:\tWdfStringCreate failed with errorcode:%x\n", status));
                        goto Error;
                }
                status = WdfDeviceRetrieveDeviceInterfaceString(
                        Device,
                        (LPGUID)&GUID_DEVINTERFACE_HSADrvSample,
                        NULL,
                        symbolicLinkString);
                if (!NT_SUCCESS(status)) {
                        KdPrint(("HSADrvSample:\tWdfDeviceRetrieveDeviceInterfaceString failed with errorcode:%x\n", status));
                        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(("HSADrvSample:\tIoSetDeviceInterfacePropertyData failed with errorcode:%x\n", status));
                        goto Error;
                }

#if defined(NTDDI_WIN10_RS2) && (NTDDI_VERSION >= NTDDI_WIN10_RS2)
                static const wchar_t customCapabilities[] = L"ColinTest.HSADrvSample_2022051717171\0";//自定义功能名称
                status = g_pIoSetDeviceInterfacePropertyData(&symbolicLinkName,
                        &DEVPKEY_DeviceInterface_UnrestrictedAppCapabilities,
                        0,
                        0,
                        DEVPROP_TYPE_STRING_LIST,
                        sizeof(customCapabilities),
                        (PVOID)&customCapabilities);
                if (!NT_SUCCESS(status)) {
                        KdPrint(("HSADrvSample:\tIoSetDeviceInterfacePropertyData failed with errorcode:%x\n", status));
                        goto Error;
                }
#endif

                WdfObjectDelete(symbolicLinkString);
      }
Error:
      if (symbolicLinkString != NULL) {
                WdfObjectDelete(symbolicLinkString);
      }
```
驱动程序INF文件
```INF
;
; HSADrvSample.inf
;


Signature="$WINDOWS NT$"
Class=Sample ; TODO: edit Class
ClassGuid={78A1C341-4539-11d3-B88D-00C04FAD5171} ; TODO: edit ClassGuid
Provider=%ManufacturerName%
CatalogFile=HSADrvSample.cat
DriverVer = 05/18/2022,10.15.24.838
PnpLockDown=1


DefaultDestDir = 12
HSADrvSample_Device_CoInstaller_CopyFiles = 11

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


Addreg=SampleClassReg


HKR,,,0,%ClassName%
HKR,,Icon,,-5


1 = %DiskName%,,,""


HSADrvSample.sys= 1,,
WdfCoInstaller01011.dll=1 ; make sure the number matches with SourceDisksNames

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


%ManufacturerName%=Standard,NTamd64


%HSADrvSample.DeviceDesc%=HSADrvSample_Device, Root\HSADrvSample ; TODO: edit hw-id


CopyFiles=Drivers_Dir


HSADrvSample.sys

;-------------- Service installation

AddService = HSADrvSample,%SPSVCINST_ASSOCSERVICE%, HSADrvSample_Service_Inst

; -------------- HSADrvSample driver install sections

DisplayName    = %HSADrvSample.SVCDESC%
ServiceType    = 1               ; SERVICE_KERNEL_DRIVER
StartType      = 3               ; SERVICE_DEMAND_START
ErrorControl   = 1               ; SERVICE_ERROR_NORMAL
ServiceBinary= %12%\HSADrvSample.sys

;
;--- HSADrvSample_Device Coinstaller installation ------
;


AddReg=HSADrvSample_Device_CoInstaller_AddReg
CopyFiles=HSADrvSample_Device_CoInstaller_CopyFiles


HKR,,CoInstallers32,0x00010000, "WdfCoInstaller01011.dll,WdfCoInstaller"


WdfCoInstaller01011.dll


KmdfService =HSADrvSample, HSADrvSample_wdfsect

KmdfLibraryVersion = 1.11


SPSVCINST_ASSOCSERVICE= 0x00000002
ManufacturerName="Colin" ;TODO: Replace with your manufacturer name
ClassName="Samples" ; TODO: edit ClassName
DiskName = "HSADrvSample Installation Disk"
HSADrvSample.DeviceDesc = "HSADrvSample Device"
HSADrvSample.SVCDESC = "HSADrvSample Service"
```
UWP包应用清单添加自定义功能:
```html
<Capabilities>
                        <Capability Name="internetClient" />
                        <uap4:CustomCapability Name="ColinTest.HSADrvSample_2022051717171"/>
</Capabilities>
```
UWP应用SCCD文件:
```html
<?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>
                </CustomCapabilities>
      <AuthorizedEntities AllowAny="true"/>
      <Catalog>0000</Catalog>
</CustomCapabilityDescriptor>
```
UWP调用:
```C#
            var selector = CustomDevice.GetDeviceSelector(DeviceInterfaceGuid);
            Note.Text = "选择器:" + selector;
            var enumDevice = DeviceInformation.FindAllAsync(selector).AsTask();
            Task.WaitAll(enumDevice);
            Note.Text = "找到了" + enumDevice.Result.Count + "个设备";
            var DeviceID = enumDevice.Result.Id;
            Note.Text = "设备ID:" + DeviceID;
            try
            {
                var Device = CustomDevice.FromIdAsync(DeviceID, DeviceAccessMode.ReadWrite, DeviceSharingMode.Shared).AsTask();
                Task.WaitAll(Device);
                Note.Text = "设备打开成功";
            }
            catch (Exception ex)
            {
                Note.Text = ex.Message;
            }
```
运行结果:

Segn 发表于 2022-5-23 15:49

事实上,我犯了一个低级错误。
函数`g_pIoSetDeviceInterfacePropertyData`需要在`DriverEntry`中配置。
但是我没有,这导致了我设置的`CustomCapabilityName`没有生效。
```cpp
    UNICODE_STRING funcName;

    RtlInitUnicodeString(&funcName, L"IoSetDeviceInterfacePropertyData");
    g_pIoSetDeviceInterfacePropertyData = (PFN_IO_SET_DEVICE_INTERFACE_PROPERTY_DATA)(ULONG_PTR)
      MmGetSystemRoutineAddress(&funcName);
```
但是,为什么UWP应用在最开始能够访问我的驱动程序?
我想这仍是一个未解之谜......

N0exp 发表于 2022-5-26 11:53

大佬,我最近在学UMDF驱动,有些问题可以请教一下吗?

Segn 发表于 2022-5-26 14:05

N0exp 发表于 2022-5-26 11:53
大佬,我最近在学UMDF驱动,有些问题可以请教一下吗?

我也是新手,还没有接触UMDF驱动,不过你可以把你的问题说一下

N0exp 发表于 2022-5-26 14:25

Segn 发表于 2022-5-26 14:05
我也是新手,还没有接触UMDF驱动,不过你可以把你的问题说一下

就是UMDF驱动安装后提示,此设备软件现已安装,但可能无法正确运行,然后设备那有一个感叹号

Segn 发表于 2022-5-26 14:39

N0exp 发表于 2022-5-26 14:25
就是UMDF驱动安装后提示,此设备软件现已安装,但可能无法正确运行,然后设备那有一个感叹号

我并没有遇到过类似的错误,但我建议检查下驱动代码和INF文件
页: [1]
查看完整版本: UWP无法访问KMDF驱动程序