微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

从WM_DEVICECHANGE LParam

如何解决从WM_DEVICECHANGE LParam

因此,我正在为学校PC构建一个可跟踪所有插入设备的应用程序。 每当插入或移除设备时,我都设法使用RegisterDeviceNotification()在主线程中获得通知。 我所能得到的只是LParam,这是设备唯一的指针。

我找不到有关如何使用该LParam获取设备的友好名称的任何信息。 我可以找到的唯一资源是2006年的this CodeProject(使用C ++)。

我在pinvoke.net上找不到任何内容,我发现的唯一内容(我不记得确切的位置)是使用ManagementObjectSearcher获取此数据,但它会找到空数据。 (这是代码

ManagementObjectSearcher searcher = new ManagementObjectSearcher("Select Name from Win32_PnpEntity");

            foreach (ManagementObject devices in searcher.Get())
            {
                foreach (var v in devices.Properties)
                {
                    Console.WriteLine(v.Value);
                }
            }

            searcher.dispose();

有人可以帮我弄清楚如何获得设备的友好名称吗?

解决方法

演示代码:

struct DeviceName : public LIST_ENTRY 
{
    ULONG InterfaceHash;
    WCHAR Name[];

    void* operator new(size_t cb,size_t len)
    {
        return LocalAlloc(0,cb + len);
    }

    void operator delete(void* pv)
    {
        LocalFree(pv);
    }
};

volatile const UCHAR guz = 0;
CONFIGRET GetFriendlyNameByDevNode(DeviceName** pp,DEVINST dnDevInst)
{
    CONFIGRET status;

    ULONG cb = 32;

    DEVPROPTYPE PropertyType;

    do 
    {
        if (DeviceName* p = new(cb) DeviceName)
        {
            status = CM_Get_DevNode_PropertyW(
                dnDevInst,&DEVPKEY_DeviceInterface_FriendlyName,&PropertyType,(PBYTE)p->Name,&cb,0);

            if (status == CR_SUCCESS)
            {
                if (PropertyType == DEVPROP_TYPE_STRING)
                {
                    *pp = p;
                    return CR_SUCCESS;
                }
                else
                {
                    status = CR_WRONG_TYPE;
                }
            }

            delete p;
        }
        else
        {
            status = CR_OUT_OF_MEMORY;
        }

    } while (CR_BUFFER_SMALL == status);

    return status;
}

CONFIGRET GetFriendlyNameByInterface(DeviceName** pp,PCWSTR pszDeviceInterface)
{
    // RTCu must be disabled !
    ULONG cb = 0,rcb = 64;

    PVOID stack = alloca(guz);
    DEVPROPTYPE PropertyType;

    CONFIGRET status;

    union {
        PVOID pv;
        PWSTR DeviceID;
        PBYTE pb;
    };

    do 
    {
        if (cb < rcb)
        {
            rcb = cb = RtlPointerToOffset(pv = alloca(rcb - cb),stack);
        }

    } while (CR_BUFFER_SMALL == (status = CM_Get_Device_Interface_PropertyW(
        pszDeviceInterface,&DEVPKEY_Device_InstanceId,pb,&rcb,0)));

    if (status == CR_SUCCESS)
    {
        if (PropertyType == DEVPROP_TYPE_STRING)
        {
            DEVINST dnDevInst;

            status = CM_Locate_DevNodeW(&dnDevInst,DeviceID,CM_LOCATE_DEVNODE_NORMAL);

            return status == CR_SUCCESS ? GetFriendlyNameByDevNode(pp,dnDevInst) : status;
        }
        else
        {
            status = CR_WRONG_TYPE;
        }
    }

    return status;
}

        case WM_DESTROY:
            if (_hDevNot)
            {
                UnregisterDeviceNotification(_hDevNot);

                PLIST_ENTRY head = &_DevListHead,entry = head->Flink;

                while (entry != head)
                {
                    DeviceName* p = static_cast<DeviceName*>(entry);

                    entry = entry->Flink;

                    delete p;
                }
            }
            break;

        case WM_DEVICECHANGE:
            switch (wParam)
            {
            case DBT_DEVICEREMOVECOMPLETE:
            case DBT_DEVICEARRIVAL:
                if (reinterpret_cast<PDEV_BROADCAST_DEVICEINTERFACE>(lParam)->dbcc_devicetype == DBT_DEVTYP_DEVICEINTERFACE)
                {
                    DeviceName* p;
                    ULONG InterfaceHash;
                    UNICODE_STRING dbcc_name;
                    RtlInitUnicodeString(&dbcc_name,reinterpret_cast<PDEV_BROADCAST_DEVICEINTERFACE>(lParam)->dbcc_name);
                    RtlHashUnicodeString(&dbcc_name,FALSE,HASH_STRING_ALGORITHM_DEFAULT,&InterfaceHash);

                    if (wParam == DBT_DEVICEARRIVAL)
                    {
                        if (CR_SUCCESS == GetFriendlyNameByInterface(&p,dbcc_name.Buffer))
                        {
                            p->InterfaceHash = InterfaceHash;
                            InsertHeadList(&_DevListHead,p);
                            DbgPrint("inserted %S ( %wZ )\n",p->Name,&dbcc_name);
                        }
                    }
                    else
                    {

                        PLIST_ENTRY head = &_DevListHead,entry = head;

                        while ((entry = entry->Flink) != head)
                        {
                            if (static_cast<DeviceName*>(entry)->InterfaceHash == InterfaceHash)
                            {
                                DbgPrint("removed %S ( %wZ )\n",static_cast<DeviceName*>(entry)->Name,&dbcc_name);

                                RemoveEntryList(entry);
                                delete static_cast<DeviceName*>(entry);
                                break;
                            }
                        }
                    }
                }
                break;
            }
            return 0;

        case WM_CREATE:
            InitializeListHead(&_DevListHead);
            static DEV_BROADCAST_DEVICEINTERFACE dbd = { sizeof(dbd),DBT_DEVTYP_DEVICEINTERFACE };
            _hDevNot = RegisterDeviceNotificationW(hwnd,DEVICE_NOTIFY_WINDOW_HANDLE|DEVICE_NOTIFY_ALL_INTERFACE_CLASSES);
            break;

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?