2

I am writing an AHK script that uses audio devices. I'm using the Vista Audio library, and I have added some more functions to get additional data about the devices beyond their name. These functions are to get the device description and device icon:

GetDeviceDesc(device)
{
    static PKEY_Device_DeviceDesc
    if !VarSetCapacity(PKEY_Device_DeviceDesc)
        VarSetCapacity(PKEY_Device_DeviceDesc, 20)
        ,VA_GUID(PKEY_Device_DeviceDesc :="{A45C254E-DF1C-4EFD-8020-67D146A850E0}")
        ,NumPut(2, PKEY_Device_DeviceDesc, 16)
    VarSetCapacity(prop, 16)
    VA_IMMDevice_OpenPropertyStore(device, 0, store)
    ; store->GetValue(.., [out] prop)
    DllCall(NumGet(NumGet(store+0)+5*A_PtrSize), "ptr", store, "ptr", &PKEY_Device_DeviceDesc, "ptr", &prop)
    ObjRelease(store)
    VA_WStrOut(deviceDesc := NumGet(prop,8))
    return deviceDesc
}

GetDeviceIcon(device)
{
    static PKEY_DrvPkg_Icon
    if !VarSetCapacity(PKEY_DrvPkg_Icon)
        VarSetCapacity(PKEY_DrvPkg_Icon, 20)
        ,VA_GUID(PKEY_DrvPkg_Icon :="{CF73BB51-3ABF-44A2-85E0-9A3DC7A12132}")
        ,NumPut(4, PKEY_DrvPkg_Icon, 16)
    VarSetCapacity(prop, 16)
    VA_IMMDevice_OpenPropertyStore(device, 0, store)
    ; store->GetValue(.., [out] prop)
    DllCall(NumGet(NumGet(store+0)+5*A_PtrSize), "ptr", store, "ptr", &PKEY_DrvPkg_Icon, "ptr", &prop)
    ObjRelease(store)
    VA_WStrOut(deviceIcon := NumGet(prop,8))
    return deviceIcon
}

Both functions are slightly modified versions of the VA_GetDeviceName function from VA.ahk:

VA_GetDeviceName(device)
{
    static PKEY_Device_FriendlyName
    if !VarSetCapacity(PKEY_Device_FriendlyName)
        VarSetCapacity(PKEY_Device_FriendlyName, 20)
        ,VA_GUID(PKEY_Device_FriendlyName :="{A45C254E-DF1C-4EFD-8020-67D146A850E0}")
        ,NumPut(14, PKEY_Device_FriendlyName, 16)
    VarSetCapacity(prop, 16)
    VA_IMMDevice_OpenPropertyStore(device, 0, store)
    ; store->GetValue(.., [out] prop)
    DllCall(NumGet(NumGet(store+0)+5*A_PtrSize), "ptr", store, "ptr", &PKEY_Device_FriendlyName, "ptr", &prop)
    ObjRelease(store)
    VA_WStrOut(deviceName := NumGet(prop,8))
    return deviceName
}

The first of my functions, to get the device description works, but the other to get the icon path returns nothing. In addition to trying to get the DrvPkg_Icon, I have also attempted to get the DeviceClass_Icon and DeviceClass_IconPath with no success.

I have the PKEY reference here and the IProperty method number reference here.

I can't figure out what I'm doing wrong. Is it possible that the code is working correctly and that these values are empty (according to the WinAPI documentation, a device is only guaranteed to have a friendly name, a description, and an interface friendly description)? In which case is there another way for me to get the device icons?

I just don't get why it's not working. Thank you

Scott Mikutsky
  • 746
  • 7
  • 21
  • 1
    The call to `IPropertyStore::GetValue` seems to write a propvariant structure of the type `VT_EMPTY` to `&prop`, and the documentation for `IPropertyStore::GetValue` seems to indicate that this means that the referenced key wasn't present in the property store. Maybe something goes wrong when you try to define the key, or the key just doesn't exist (no idea if the the latter is even possible). – 0x464e Oct 25 '20 at 23:54
  • 1
    You can get all properties from an IPropertyStore (call IPropertyStore::GetCount and IPropertyStore::GetAt from 0 to count - 1). That being said, my experience is icons are located on device interfaces, not devices itself (as PKEY_Devices_Icon). You can use this WinRT API: https://learn.microsoft.com/en-us/uwp/api/windows.devices.enumeration.deviceinformation?view=winrt-19041 to get all devices information – Simon Mourier Oct 26 '20 at 06:41

0 Answers0