Jump to content

Working with WinRT Objects in memory


 Share

Recommended Posts

Hi folks,

Attached below is one way of attacking WinRT Objects.  These are essentially COM objects, however they don't have an IDispatch interface so ObjCreate() cannot be used.  It is possible to expose them using ObjCreateInterface though. Alternately, DllCallAddress() may be used to access an object's functions directly from memory.

I'm using the latter mainly because that's the path I started down first!

To make sense of whats in the attachment...

  • WinRTCore,au3  - Internal helper functions for interface libraries
  • Iblah.au3  - Interface libraries. Essentially these wrap the functions in an interface's vtable
    • Includes tags which may be used with ObjCreateInterface (these are largely untested though!)
    • Includes enum definitions that relate to the interface
  • WinRT.au3 - Core high level functions that sit on top of interface libraries
    • Includes Async and Collection implementations etc. So basic high level functionality.
  • WinRT_blah.au3 - High level functions that sit on top of interface libraries

Ok I may have over-engineered this a bit... I'm unsure if its the best appproach, but its something to go off for the next WinRT object that I'll need to attack :)

Original post:

Spoiler

Hi folks,

So long story short - with Win11 starting to ignore a display's EDID, I was looking for a way to get to a displays displayID block.
I'm nowhere close to achieving this yet, but have made some inroads.

Basically it seems I need to get to this: https://learn.microsoft.com/en-us/uwp/api/windows.devices.display.displaymonitor.getdescriptor?view=winrt-26100 - And that brings us to WinRT.

So we're basically dealing with COM objects without an iDispatch interface. This is unhelpful for us as it effectively takes away use of AutoIt's Object datatype. But fun fact -  If we know how an object is structured in memory, it seems we can access its methods via the DllCallAddress() function. This is space that I'm currently stumbling around in.

I'm not going to pretend I'm an expert in this - but here's a starting point if its useful to anyone :) 
And of course happy to talk more detail about whats going on, but be prepared some text walls!

#AutoIt3Wrapper_UseX64=Y

#include <winapi.au3>
#include <array.au3>

; Reqires at least Win8 - Tested on Win 11 23H2
; This demo is not robust at all, there is pitiful error checking!!

; Com error code reference:
; https://learn.microsoft.com/en-us/windows/win32/com/com-error-codes-1

Global $hDLLComBase = DllOpen("Combase.dll")
Global Const $PTR_LEN = @AutoItX64 ? 8 : 4

Global Const $sIUnknown = "{00000000-0000-0000-C000-000000000046}"
Global Const $sIInspectable = "{AF86E2E0-B12D-4c6a-9C5A-D7AA65101E90}"
Global Const $sIActivationFactory = "{00000035-0000-0000-C000-000000000046}"
Global Const $sIDisplayMonitorStatics = "{6EAE698F-A228-4C05-821D-B695D667DE8E}"

; We can request a pointer to a different interface, but I've started at the beginning
Local $pObject = RoGetActivationFactory("Windows.Devices.Display.DisplayMonitor", $sIUnknown)

; QueryInterface should set @error if the interface is not supported.
ConsoleWrite("IUnknown::QueryInterface failure test:" & @CRLF)
Local $pDummy = IUnknown_QueryInterface($pObject, "{00000000-0000-0000-0000-000000000000}")
If @error Then DispError() ; @errror should be E_NOINTERFACE.
ConsoleWrite(@CRLF)

; Worked my way through the other IUnknown functions..
; The reference count should increment and decrement
ConsoleWrite("IUnknown::AddRef and IUnknown::RemoveRef test:" & @CRLF)
For $i = 1 To 5
    ConsoleWrite("RefCount: " & IUnknown_AddRef($pObject) & @CRLF)
Next
For $i = 1 To 5
    ConsoleWrite("RefCount: " & IUnknown_RemoveRef($pObject) & @CRLF)
Next
ConsoleWrite(@CRLF)

; We can see what Interfaces are available via IInspectable
; Its a WinRT object, so IInspectable definately should exist!
Local $pIInspectable = IUnknown_QueryInterface($pObject, $sIInspectable)
Local $aIIDs = IInspectable_GetIids($pIInspectable)

; I find IActivationFactory and IDisplayMonitorStatics on my system.
; OLE View also shows me {9B0AFA0D-CF76-4FEA-BDC5-88F6DD7A6986}. No idea what this is or where it comes from???
ConsoleWrite("IInspectable::GetIids test: " & @CRLF)
ConsoleWrite("Retrieve supported interfaces of the object - (excluding IUnknown & IInspectable)" & @CRLF)
For $i = 0 To UBound($aIIDs) - 1
    ConsoleWrite(" " & $aIIDs[$i] & @CRLF)
Next
ConsoleWrite(@CRLF)

; We're on a factory interface - so no suprise that this fails (works as documented).
ConsoleWrite("IInspectable::GetRuntimeClassName failure test:" & @CRLF)
$sClassName = IInspectable_GetRuntimeClassName($pIInspectable)
If @error Then DispError() ; @errror should be E_ILLEGAL_METHOD_CALL.
ConsoleWrite(@CRLF)

; IUnknown and IIspectable by and large seem to work - So I next attack ActivationFactory
ConsoleWrite("IActivationFactory::ActivateInstance test:" & @CRLF)
; Get the correct interface
$pActFactory = IUnknown_QueryInterface($pObject, $sIActivationFactory)
Local $pInst = IActivationFactory_ActivateInstance($pActFactory)
If @error Then DispError() ; I Get E_NOTIMPL. I guess thats all we can do for now unless I've stuffed up the function.
;  Could also RoGetActivationFactory be doing something here?? - anyway I don't really know what I'm doing, so moving on...

; On to IDisplayMonitorStatics.  This presumably inherits from IInspectable.
; From what I can gather I should be able to these funcs to enum monitors.
; Doco is hard to find, but OLE View has this...
;~ [Guid("6eae698f-a228-4c05-821d-b695d667de8e")]
;~ interface IDisplayMonitorStatics
;~ {
;~    /* Methods */
;~    string GetDeviceSelector();
;~    IAsyncOperation`1 FromIdAsync(string deviceId);
;~    IAsyncOperation`1 FromInterfaceIdAsync(string deviceInterfaceId);
;~ }

ConsoleWrite(@CRLF & "IDisplayMonitorStatics test:" & @CRLF)
$pDispMonStatics = IUnknown_QueryInterface($pObject, $sIDisplayMonitorStatics)

; Not sure if OLEView is wrong, most likely I'm missing something!
; But the GetDeviceSelector func seems to output the HString via a parameter - its not the return value
$sSelector = IDisplayMonitorStatics_GetDeviceSelector($pDispMonStatics)
ConsoleWrite($sSelector & @CRLF) ;Should output a AQS string
ConsoleWrite(@CRLF)

; Thats all I've got for now!

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Func IUnknown_QueryInterface($pThis, $sIID)
    Local $pVTable = GetPtrAt($pThis)
    Local $pFunc = GetPtrAt($pVTable)
    Local $tIID = CreateGUID($sIID)

    Local $aRet = DllCallAddress("long", $pFunc, "ptr", $pThis, "struct*", $tIID, "ptr*", 0)
    Return SetError($aRet[0], 0, $aRet[3])
EndFunc   ;==>IUnknown_QueryInterface

Func IUnknown_AddRef($pThis)
    Local $pVTable = GetPtrAt($pThis)
    Local $pFunc = GetPtrAt(Ptr($pVTable + $PTR_LEN))

    Local $aRet = DllCallAddress("long", $pFunc, "ptr", $pThis)
    Return $aRet[0]
EndFunc   ;==>IUnknown_AddRef

Func IUnknown_RemoveRef($pThis)
    Local $pVTable = GetPtrAt($pThis)
    Local $pFunc = GetPtrAt(Ptr($pVTable + 2 * $PTR_LEN))

    Local $aRet = DllCallAddress("long", $pFunc, "ptr", $pThis)
    Return $aRet[0]
EndFunc   ;==>IUnknown_RemoveRef

Func IInspectable_GetIids($pThis)
    Local $pVTable = GetPtrAt($pThis)
    Local $pFunc = GetPtrAt(Ptr($pVTable + 3 * $PTR_LEN))

    Local $aRet = DllCallAddress("long", $pFunc, "ptr", $pThis, "long*", 0, "ptr*", 0)

    Local $iCount = $aRet[2], $asIIDs[2]
    For $i = 0 To $iCount - 1
        $asIIDs[$i] = ReadGUIDAt(Ptr($aRet[3] + ($i * 16)))
    Next

    CoTaskMemFree($aRet[3])

    Return SetError($aRet[0], 0, $asIIDs)
EndFunc   ;==>IInspectable_GetIids

Func IInspectable_GetRuntimeClassName($pThis)
    Local $pVTable = GetPtrAt($pThis)
    Local $pFunc = GetPtrAt(Ptr($pVTable + 4 * $PTR_LEN))
    Local $aRet = DllCallAddress("long", $pFunc, "ptr", $pThis, "handle*", 0)
    Local $sClassName = ReadHString($aRet[2])
    DeleteHString($aRet[2])

    Return SetError($aRet[0], 0, $sClassName)
EndFunc   ;==>IInspectable_GetRuntimeClassName

Func IInspectable_GetTrustLevel($pThis)
    Local $pVTable = GetPtrAt($pThis)
    Local $pFunc = GetPtrAt(Ptr($pVTable + 5 * $PTR_LEN))

    Local $aRet = DllCallAddress("long", $pFunc, "ptr", $pThis, "int*", 0)

    Return SetError($aRet[0], 0, $aRet[2])
EndFunc   ;==>IInspectable_GetTrustLevel

Func IActivationFactory_ActivateInstance($pThis)
    Local $pVTable = GetPtrAt($pThis)
    Local $pFunc = GetPtrAt(Ptr($pVTable + 6 * $PTR_LEN))

    Local $aRet = DllCallAddress("long", $pFunc, "ptr", $pThis, "ptr*", 0)

    Return SetError($aRet[0], 0, $aRet[2])
EndFunc   ;==>IActivationFactory_ActivateInstance

Func IDisplayMonitorStatics_GetDeviceSelector($pThis)
    Local $pVTable = GetPtrAt($pThis)
    Local $pFunc = GetPtrAt(Ptr($pVTable + 6 * $PTR_LEN))

    Local $aRet = DllCallAddress("long", $pFunc, "ptr", $pThis, "ptr*", 0, "ptr*", 0)

    Local $sSelector = ReadHString($aRet[2])
    DeleteHString($aRet[2])

    Return SetError($aRet[0], 0, $sSelector)
EndFunc   ;==>IDisplayMonitorStatics_GetDeviceSelector


Func DispError($iError = @error)
    Local Const $iMaxWidth = 0xFF
    Local $iFlags = $FORMAT_MESSAGE_FROM_SYSTEM

    Local $tBuff = DllStructCreate(StringFormat("wchar[%d]", $iMaxWidth))
    Local $pBuff = DllStructGetPtr($tBuff)

    Local $iCount = _WinAPI_FormatMessage($iFlags, 0, $iError, 0, $pBuff, $iMaxWidth, 0)
    ConsoleWrite("[0x" & Hex($iError) & "] " & StringStripWS(DllStructGetData($tBuff, 1), 3) & @CRLF)
EndFunc   ;==>DispError

Func RoGetActivationFactory($sClassID, $sIID)
    Local $hsClassID = CreateHString($sClassID)
    Local $tIID = CreateGUID($sIID)
    Local $aRes = DllCall($hDLLComBase, "long", "RoGetActivationFactory", "handle", $hsClassID, "ptr", DllStructGetPtr($tIID), "ptr*", 0)
    DeleteHString($hsClassID)
    Return $aRes[3]
EndFunc   ;==>RoGetActivationFactory

Func CreateHString($sString)
    Local $aRes = DllCall($hDLLComBase, "int", "WindowsCreateString", "wstr", $sString, "uint", StringLen($sString), "ptr*", 0)
    If Not @error Then Return $aRes[3]
EndFunc   ;==>CreateHString

Func DeleteHString(ByRef $hString)
    Local $aRes = DllCall($hDLLComBase, "int", "WindowsDeleteString", "ptr", $hString)
    If Not @error Then $hString = 0
EndFunc   ;==>DeleteHString

Func ReadHString(ByRef $hString)
    Local $aRes = DllCall($hDLLComBase, "wstr", "WindowsGetStringRawBuffer", "ptr", $hString, "int*", 0)
    If Not @error Then Return $aRes[0]
EndFunc   ;==>ReadHString

Func CreateGUID($sGUID)
    Local $tGUID = DllStructCreate($tagGUID)
    $aGUID = StringSplit(StringRegExpReplace($sGUID, "[{}]", ""), "-", 2)
    If UBound($aGUID) <> 5 Then Return False

    $tGUID.Data1 = Dec($aGUID[0])
    $tGUID.Data2 = Dec($aGUID[1])
    $tGUID.Data3 = Dec($aGUID[2])
    $tGUID.Data4 = Binary("0x" & $aGUID[3] & $aGUID[4])

    Return $tGUID
EndFunc   ;==>CreateGUID

Func ReadGUIDAt($pGUID)
    Local $tGUID = DllStructCreate($tagGUID, $pGUID)
    Local $sGUID = "{"

    $sGUID &= Hex($tGUID.Data1, 8) & "-"
    $sGUID &= Hex($tGUID.Data2, 4) & "-"
    $sGUID &= Hex($tGUID.Data3, 4) & "-"
    $sGUID &= StringMid($tGUID.Data4, 3, 4) & "-"
    $sGUID &= StringMid($tGUID.Data4, 7, 12) & "}"

    Return $sGUID
EndFunc   ;==>ReadGUIDAt

Func GetPtrAt($pPtr)
    Local $tPtr = DllStructCreate("ptr ptr", $pPtr)
    Return $tPtr.ptr
EndFunc   ;==>GetPtrAt

Func CoTaskMemFree($pBlock)
    DllCall("ole32.dll", "none", "CoTaskMemFree", "ptr", $pBlock)
EndFunc   ;==>CoTaskMemFree

 

 

WinRT_Demo_v1.zip

Edited by MattyD
Link to comment
Share on other sites

Ah yes  - I originally looked at that and decided it wasn't going to play..
But now I can make a bit more sense of the doco - and yeah, you're right - it'll probably work.

Here's an IInspectable::GetIIds example with ObjCreateInterface.

#include <winapi.au3>
#include <array.au3>

Global $hDLLComBase = DllOpen("Combase.dll")

Global Const $sIUnknown = "{00000000-0000-0000-C000-000000000046}"
Global Const $sIInspectable = "{AF86E2E0-B12D-4c6a-9C5A-D7AA65101E90}"


Local $tagIInspectabe = _
        "GetIids hresult(ulong*; ptr*); " & _
        "GetRuntimeClassName hresult(ptr*); " & _
        "GetTrustLevel hresult(long*);"

Local $pObject = RoGetActivationFactory("Windows.Devices.Display.DisplayMonitor", $sIUnknown)
$oIInspectable = ObjCreateInterface($pObject, $sIInspectable, $tagIInspectabe, True)

Local $iCount, $pIIDS
$oIInspectable.GetIids($iCount, $pIIDS)

Local $asIIDs[$iCount]
For $i = 0 To $iCount - 1
    $asIIDs[$i] = ReadGUIDAt(Ptr($pIIDS + ($i * 16)))
Next
CoTaskMemFree($pIIDS)
_ArrayDisplay($asIIDs)

;;;;;;;;;;;;;;;;;;;;;;;;;;


Func RoGetActivationFactory($sClassID, $sIID)
    Local $hsClassID = CreateHString($sClassID)
    Local $tIID = CreateGUID($sIID)
    Local $aRes = DllCall($hDLLComBase, "long", "RoGetActivationFactory", "handle", $hsClassID, "ptr", DllStructGetPtr($tIID), "ptr*", 0)
    DeleteHString($hsClassID)
    Return $aRes[3]
EndFunc   ;==>RoGetActivationFactory

Func CreateHString($sString)
    Local $aRes = DllCall($hDLLComBase, "int", "WindowsCreateString", "wstr", $sString, "uint", StringLen($sString), "ptr*", 0)
    If Not @error Then Return $aRes[3]
EndFunc   ;==>CreateHString

Func DeleteHString(ByRef $hString)
    Local $aRes = DllCall($hDLLComBase, "int", "WindowsDeleteString", "ptr", $hString)
    If Not @error Then $hString = 0
EndFunc   ;==>DeleteHString

Func ReadHString(ByRef $hString)
    Local $aRes = DllCall($hDLLComBase, "wstr", "WindowsGetStringRawBuffer", "ptr", $hString, "int*", 0)
    If Not @error Then Return $aRes[0]
EndFunc   ;==>ReadHString

Func CreateGUID($sGUID)
    Local $tGUID = DllStructCreate($tagGUID)
    $aGUID = StringSplit(StringRegExpReplace($sGUID, "[{}]", ""), "-", 2)
    If UBound($aGUID) <> 5 Then Return False

    $tGUID.Data1 = Dec($aGUID[0])
    $tGUID.Data2 = Dec($aGUID[1])
    $tGUID.Data3 = Dec($aGUID[2])
    $tGUID.Data4 = Binary("0x" & $aGUID[3] & $aGUID[4])

    Return $tGUID
EndFunc   ;==>CreateGUID

Func ReadGUIDAt($pGUID)
    Local $tGUID = DllStructCreate($tagGUID, $pGUID)
    Local $sGUID = "{"

    $sGUID &= Hex($tGUID.Data1, 8) & "-"
    $sGUID &= Hex($tGUID.Data2, 4) & "-"
    $sGUID &= Hex($tGUID.Data3, 4) & "-"
    $sGUID &= StringMid($tGUID.Data4, 3, 4) & "-"
    $sGUID &= StringMid($tGUID.Data4, 7, 12) & "}"

    Return $sGUID
EndFunc   ;==>ReadGUIDAt

Func CoTaskMemFree($pBlock)
    DllCall("ole32.dll", "none", "CoTaskMemFree", "ptr", $pBlock)
EndFunc   ;==>CoTaskMemFree

 

Link to comment
Share on other sites

Func DispError($iError = @error, $iScriptLineNumber = @ScriptLineNumber)
    Local Const $iMaxWidth = 0xFF
    Local $iFlags = $FORMAT_MESSAGE_FROM_SYSTEM
    Local $tBuff = DllStructCreate(StringFormat("wchar[%d]", $iMaxWidth))
    Local $pBuff = DllStructGetPtr($tBuff)
    Local $iCount = _WinAPI_FormatMessage($iFlags, 0, $iError, 0, $pBuff, $iMaxWidth, 0)
    ConsoleWrite('(' & $iScriptLineNumber & ",0) [0x" & Hex($iError) & "] " & StringStripWS(DllStructGetData($tBuff, 1), 3) & @CRLF)
EndFunc   ;==>DispError

..that way I can jump to the line in the script. 

Spoiler
>"D:\Utilities\AutoIt3\SciTE\..\AutoIt3.exe" "D:\Utilities\AutoIt3\SciTE\AutoIt3Wrapper\AutoIt3Wrapper.au3" /run /prod /ErrorStdOut /in "D:\Users\Tester\Downloads\ITaskbarList\ITaskbarList\212222-working-with-winrt-objects-in-memory\au3.212222-working-with-winrt.au3" /UserParams    
+>11:52:28 Starting AutoIt3Wrapper (pid=37728) 23.402.1150.10 from:SciTE.exe (4.4.6.0)  Keyboard:00000409  OS:WIN_11/2009  CPU:X64 OS:X64  Environment(Language:0409)  CodePage:0  utf8.auto.check:4
+>         SciTEDir => D:\Utilities\AutoIt3\SciTE   UserDir => C:\Users\Tester\AppData\Local\AutoIt v3\SciTE\AutoIt3Wrapper   SCITE_USERHOME => C:\Users\Tester\AppData\Local\AutoIt v3\SciTE 
>Running AU3Check (3.3.17.0)  from:D:\Utilities\AutoIt3  input:D:\Users\Tester\Downloads\ITaskbarList\ITaskbarList\212222-working-with-winrt-objects-in-memory\au3.212222-working-with-winrt.au3
+>11:52:29 AU3Check ended. rc:0
>Running:(3.3.16.1):D:\Utilities\AutoIt3\autoit3_x64.exe "D:\Users\Tester\Downloads\ITaskbarList\ITaskbarList\212222-working-with-winrt-objects-in-memory\au3.212222-working-with-winrt.au3"    
+>Setting Hotkeys...--> Press Ctrl+Alt+Break to Restart. --> Press Ctrl+BREAK to Stop.
IUnknown::QueryInterface failure test:
(26,0) [0x80004002] No such interface supported

IUnknown::AddRef and IUnknown::RemoveRef test:
RefCount: 3
RefCount: 4
RefCount: 5
RefCount: 6
RefCount: 7
RefCount: 6
RefCount: 5
RefCount: 4
RefCount: 3
RefCount: 2

IInspectable::GetIids test: 
Retrieve supported interfaces of the object - (excluding IUnknown & IInspectable)
 {00000035-0000-0000-C000-000000000046}
 {6EAE698F-A228-4C05-821D-B695D667DE8E}

IInspectable::GetRuntimeClassName failure test:
(57,0) [0x8000000E] A method was called at an unexpected time.

IActivationFactory::ActivateInstance test:
(65,0) [0x80004001] Not implemented

IDisplayMonitorStatics test:
(System.Devices.InterfaceClassGuid:="{E6F07B5F-EE97-4a90-B076-33F57BF4EAA7}" AND System.Devices.InterfaceEnabled:=System.StructuredQueryType.Boolean#True) OR System.Devices.ChallengeAep:=System.StructuredQueryType.Boolean#False

>
+>11:52:29 AutoIt3 ended. rc:0
+>11:52:29 AutoIt3Wrapper Finished.
>Exit code: 0    Time: 1.28

and that is what I got ( in case this info is useful )

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting.
autoit_scripter_blue_userbar.png

Link to comment
Share on other sites

Thanks mate, I didn't know you could do that with the line numbers in scite, that's quite handy :)- The output is also the same as what I see on my end.

For anyone following along, I threw a it more time at this today and made a bit more progress. I think that I may have managed to populate a collection of displaymonitor objects. Gotta say that the Rust doco has been invaluable for deciphering those vtables.

#AutoIt3Wrapper_UseX64=Y
#Tidy_Parameters=/sf

#include <winapi.au3>
#include <array.au3>

; Com error code reference:
; https://learn.microsoft.com/en-us/windows/win32/com/com-error-codes-1

Global $hDLLComBase = DllOpen("Combase.dll")
Global Const $PTR_LEN = @AutoItX64 ? 8 : 4

Global Const $sIUnknown = "{00000000-0000-0000-C000-000000000046}"
Global Const $sIInspectable = "{AF86E2E0-B12D-4c6a-9C5A-D7AA65101E90}"
Global Const $sIActivationFactory = "{00000035-0000-0000-C000-000000000046}"
Global Const $sIDisplayMonitorStatics = "{6EAE698F-A228-4C05-821D-B695D667DE8E}"
Global Const $sIDeviceInformationStatics = "{C17F100E-3A46-4A78-8013-769DC9B97390}"
Global Const $sIAsyncInfo = "{00000036-0000-0000-C000-000000000046}"

Global Enum $ASync_Started = 0, $ASync_Completed, $ASync_Canceled, $ASync_Error

ConsoleWrite("Get AQS String" & @CRLF)
ConsoleWrite('Get "Windows.Devices.Display.DisplayMonitor" Activation Factory, IDisplayMonitorStatics' & @CRLF)
$pMonStatics = RoGetActivationFactory("Windows.Devices.Display.DisplayMonitor", $sIDisplayMonitorStatics)
DispError()
ConsoleWrite("Call IDisplayMonitorStatics::GetDeviceSelector" & @CRLF)
$sDevSelector = IDisplayMonitorStatics_GetDeviceSelector($pMonStatics)
DispError()
ConsoleWrite($sDevSelector & @CRLF)
ConsoleWrite(@CRLF)

ConsoleWrite("Get Device Collection:" & @CRLF)
ConsoleWrite('Get "Windows.Devices.Enumeration.DeviceInformation" Activation Factory, IDeviceInformationStatics' & @CRLF)
$pDevInfo = RoGetActivationFactory("Windows.Devices.Enumeration.DeviceInformation", $sIDeviceInformationStatics)
DispError()
ConsoleWrite("Call IDeviceInformationStatics::FindAllAsyncAqsFilter with AQS string that we aquired earlier" & @CRLF)
$pAsync = IDeviceInformationStatics_FindAllAsyncAqsFilter($pDevInfo, $sDevSelector)
DispError()
ConsoleWrite("Wait for ASync routine..." & @CRLF)
ConsoleWrite("Get AsyncInfo Interface:" & @CRLF)
$pAsyncInfo = IUnknown_QueryInterface($pAsync, $sIAsyncInfo)
DispError()
Do
    Sleep(10)
Until IASyncInfo_Status($pAsyncInfo)
ConsoleWrite("Async Finished. We want the status to be 1 - i.e. 'completed':" & @CRLF)
ConsoleWrite("Async status=" & IASyncInfo_Status($pAsyncInfo) & @CRLF)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Func CoTaskMemFree($pBlock)
    DllCall("ole32.dll", "none", "CoTaskMemFree", "ptr", $pBlock)
EndFunc   ;==>CoTaskMemFree

Func CreateGUID($sGUID)
    Local $tGUID = DllStructCreate($tagGUID)
    $aGUID = StringSplit(StringRegExpReplace($sGUID, "[{}]", ""), "-", 2)
    If UBound($aGUID) <> 5 Then Return False

    $tGUID.Data1 = Dec($aGUID[0])
    $tGUID.Data2 = Dec($aGUID[1])
    $tGUID.Data3 = Dec($aGUID[2])
    $tGUID.Data4 = Binary("0x" & $aGUID[3] & $aGUID[4])

    Return $tGUID
EndFunc   ;==>CreateGUID

Func CreateHString($sString)
    Local $aRes = DllCall($hDLLComBase, "int", "WindowsCreateString", "wstr", $sString, "uint", StringLen($sString), "ptr*", 0)
    If Not @error Then Return $aRes[3]
EndFunc   ;==>CreateHString

Func DeleteHString(ByRef $hString)
    Local $aRes = DllCall($hDLLComBase, "int", "WindowsDeleteString", "ptr", $hString)
    If Not @error Then $hString = 0
EndFunc   ;==>DeleteHString

Func DispError($iError = @error, $iScriptLineNumber = @ScriptLineNumber)
    Local Const $iMaxWidth = 0xFF
    Local $iFlags = $FORMAT_MESSAGE_FROM_SYSTEM
    Local $tBuff = DllStructCreate(StringFormat("wchar[%d]", $iMaxWidth))
    Local $pBuff = DllStructGetPtr($tBuff)
    Local $iCount = _WinAPI_FormatMessage($iFlags, 0, $iError, 0, $pBuff, $iMaxWidth, 0)
    ConsoleWrite('(' & $iScriptLineNumber & ",0) [0x" & Hex($iError) & "] " & StringStripWS(DllStructGetData($tBuff, 1), 3) & @CRLF)
EndFunc   ;==>DispError

Func GetPtrAt($pPtr)
    Local $tPtr = DllStructCreate("ptr ptr", $pPtr)
    Return $tPtr.ptr
EndFunc   ;==>GetPtrAt

Func IActivationFactory_ActivateInstance($pThis)
    Local $pVTable = GetPtrAt($pThis)
    Local $pFunc = GetPtrAt(Ptr($pVTable + 6 * $PTR_LEN))

    Local $aRet = DllCallAddress("long", $pFunc, "ptr", $pThis, "ptr*", 0)

    Return SetError($aRet[0], 0, $aRet[2])
EndFunc   ;==>IActivationFactory_ActivateInstance

Func IASyncInfo_Cancel($pThis)
    Local $pVTable = GetPtrAt($pThis)
    Local $pFunc = GetPtrAt(Ptr($pVTable + 9 * $PTR_LEN))

    Local $aRet = DllCallAddress("long", $pFunc, "ptr", $pThis)

    Return SetError($aRet[0])
EndFunc   ;==>IASyncInfo_Cancel

Func IASyncInfo_Close($pThis)
    Local $pVTable = GetPtrAt($pThis)
    Local $pFunc = GetPtrAt(Ptr($pVTable + 10 * $PTR_LEN))

    Local $aRet = DllCallAddress("long", $pFunc, "ptr", $pThis)

    Return SetError($aRet[0])
EndFunc   ;==>IASyncInfo_Close

Func IASyncInfo_ErrorCode($pThis)
    Local $pVTable = GetPtrAt($pThis)
    Local $pFunc = GetPtrAt(Ptr($pVTable + 8 * $PTR_LEN))

    Local $aRet = DllCallAddress("long", $pFunc, "ptr", $pThis, "long*", 0)

    Return SetError($aRet[0], 0, $aRet[2])
EndFunc   ;==>IASyncInfo_ErrorCode

Func IASyncInfo_ID($pThis)
    Local $pVTable = GetPtrAt($pThis)
    Local $pFunc = GetPtrAt(Ptr($pVTable + 6 * $PTR_LEN))

    Local $aRet = DllCallAddress("long", $pFunc, "ptr", $pThis, "uint*", 0)

    Return SetError($aRet[0], 0, $aRet[2])
EndFunc   ;==>IASyncInfo_ID

Func IASyncInfo_Status($pThis)
    Local $pVTable = GetPtrAt($pThis)
    Local $pFunc = GetPtrAt(Ptr($pVTable + 7 * $PTR_LEN))

    Local $aRet = DllCallAddress("long", $pFunc, "ptr", $pThis, "uint*", 0)

    Return SetError($aRet[0], 0, $aRet[2])
EndFunc   ;==>IASyncInfo_Status

Func IDeviceInformationStatics_FindAllAsyncAqsFilter($pThis, $sFilter)
    Local $pVTable = GetPtrAt($pThis)
    Local $pFunc = GetPtrAt(Ptr($pVTable + 10 * $PTR_LEN))
    Local $hsFilter = CreateHString($sFilter)

    Local $aRet = DllCallAddress("long", $pFunc, "ptr", $pThis, "ptr", $hsFilter, "ptr*", 0)

    DeleteHString($hsFilter)
    Return SetError($aRet[0], 0, $aRet[3])
EndFunc   ;==>IDeviceInformationStatics_FindAllAsyncAqsFilter

Func IDisplayMonitorStatics_FromIdAsync($pThis)
    Local $pVTable = GetPtrAt($pThis)
    Local $pFunc = GetPtrAt(Ptr($pVTable + 7 * $PTR_LEN))

    Local $aRet = DllCallAddress("long", $pFunc, "ptr", $pThis, "ptr*", 0, "ptr*", 0)

    Local $sSelector = ReadHString($aRet[2])
    DeleteHString($aRet[2])

    Return SetError($aRet[0], 0, $sSelector)
EndFunc   ;==>IDisplayMonitorStatics_FromIdAsync

Func IDisplayMonitorStatics_GetDeviceSelector($pThis)
    Local $pVTable = GetPtrAt($pThis)
    Local $pFunc = GetPtrAt(Ptr($pVTable + 6 * $PTR_LEN))

    Local $aRet = DllCallAddress("long", $pFunc, "ptr", $pThis, "ptr*", 0)

    Local $sSelector = ReadHString($aRet[2])
    DeleteHString($aRet[2])

    Return SetError($aRet[0], 0, $sSelector)
EndFunc   ;==>IDisplayMonitorStatics_GetDeviceSelector

Func IInspectable_GetIids($pThis)
    Local $pVTable = GetPtrAt($pThis)
    Local $pFunc = GetPtrAt(Ptr($pVTable + 3 * $PTR_LEN))

    Local $aRet = DllCallAddress("long", $pFunc, "ptr", $pThis, "long*", 0, "ptr*", 0)

    Local $iCount = $aRet[2], $asIIDs[$iCount]
    For $i = 0 To $iCount - 1
        $asIIDs[$i] = ReadGUIDAt(Ptr($aRet[3] + ($i * 16)))
    Next

    CoTaskMemFree($aRet[3])

    Return SetError($aRet[0], 0, $asIIDs)
EndFunc   ;==>IInspectable_GetIids

Func IInspectable_GetRuntimeClassName($pThis)
    Local $pVTable = GetPtrAt($pThis)
    Local $pFunc = GetPtrAt(Ptr($pVTable + 4 * $PTR_LEN))
    Local $aRet = DllCallAddress("long", $pFunc, "ptr", $pThis, "handle*", 0)
    Local $sClassName = ReadHString($aRet[2])
    DeleteHString($aRet[2])

    Return SetError($aRet[0], 0, $sClassName)
EndFunc   ;==>IInspectable_GetRuntimeClassName

Func IInspectable_GetTrustLevel($pThis)
    Local $pVTable = GetPtrAt($pThis)
    Local $pFunc = GetPtrAt(Ptr($pVTable + 5 * $PTR_LEN))

    Local $aRet = DllCallAddress("long", $pFunc, "ptr", $pThis, "int*", 0)

    Return SetError($aRet[0], 0, $aRet[2])
EndFunc   ;==>IInspectable_GetTrustLevel

Func IUnknown_AddRef($pThis)
    Local $pVTable = GetPtrAt($pThis)
    Local $pFunc = GetPtrAt(Ptr($pVTable + $PTR_LEN))

    Local $aRet = DllCallAddress("long", $pFunc, "ptr", $pThis)
    Return $aRet[0]
EndFunc   ;==>IUnknown_AddRef


Func IUnknown_QueryInterface($pThis, $sIID)
    Local $pVTable = GetPtrAt($pThis)
    Local $pFunc = GetPtrAt($pVTable)
    Local $tIID = CreateGUID($sIID)

    Local $aRet = DllCallAddress("long", $pFunc, "ptr", $pThis, "struct*", $tIID, "ptr*", 0)
    Return SetError($aRet[0], 0, $aRet[3])
EndFunc   ;==>IUnknown_QueryInterface

Func IUnknown_RemoveRef($pThis)
    Local $pVTable = GetPtrAt($pThis)
    Local $pFunc = GetPtrAt(Ptr($pVTable + 2 * $PTR_LEN))

    Local $aRet = DllCallAddress("long", $pFunc, "ptr", $pThis)
    Return $aRet[0]
EndFunc   ;==>IUnknown_RemoveRef

Func ReadGUIDAt($pGUID)
    Local $tGUID = DllStructCreate($tagGUID, $pGUID)
    Local $sGUID = "{"

    $sGUID &= Hex($tGUID.Data1, 8) & "-"
    $sGUID &= Hex($tGUID.Data2, 4) & "-"
    $sGUID &= Hex($tGUID.Data3, 4) & "-"
    $sGUID &= StringMid($tGUID.Data4, 3, 4) & "-"
    $sGUID &= StringMid($tGUID.Data4, 7, 12) & "}"

    Return $sGUID
EndFunc   ;==>ReadGUIDAt

Func ReadHString(ByRef $hString)
    Local $aRes = DllCall($hDLLComBase, "wstr", "WindowsGetStringRawBuffer", "ptr", $hString, "int*", 0)
    If Not @error Then Return $aRes[0]
EndFunc   ;==>ReadHString

Func RoActivateInstance($sClassID)
    $hsClassID = CreateHString($sClassID)
    Local $aRes = DllCall($hDLLComBase, "long", "RoActivateInstance", "handle", $hsClassID, "ptr*", 0)
    DeleteHString($hsClassID)
    Return SetError($aRes[0], 0, $aRes[2])
EndFunc   ;==>RoActivateInstance

Func RoGetActivationFactory($sClassID, $sIID)
    Local $hsClassID = CreateHString($sClassID)
    Local $tIID = CreateGUID($sIID)
    Local $aRes = DllCall($hDLLComBase, "long", "RoGetActivationFactory", "handle", $hsClassID, "ptr", DllStructGetPtr($tIID), "ptr*", 0)
    DeleteHString($hsClassID)
    Return SetError($aRes[0], 0, $aRes[3])
EndFunc   ;==>RoGetActivationFactory
Link to comment
Share on other sites

SleepOnTimer(0, 0) ; init. the timer
Do
    If Not SleepOnTimer(10, 5000) Then ExitLoop ; if time longer than expected, exit the loop
Until IASyncInfo_Status($pAsyncInfo)
ConsoleWrite("Async Finished. We want the status to be 1 - i.e. 'completed':" & @CRLF)
ConsoleWrite("Async status=" & IASyncInfo_Status($pAsyncInfo) & @CRLF)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Func SleepOnTimer($iSleepMs, $iTimeoutMs)
    Local Static $hTimer = TimerInit()
    If Not $iTimeoutMs Then
        $hTimer = TimerInit() ; init / reset to now
        Return 0
    EndIf
    Sleep($iSleepMs)
    If TimerDiff($hTimer) > $iTimeoutMs Then Return SetError(1, TimerDiff($hTimer), 0)
    Return TimerDiff($hTimer)
EndFunc

Since I don't know much but this may take a long time in WinXP or some other failure, I thought that the SleepOnTimer() would be a good idea. We are waiting anyway, might as well give it some safety.

And my report of the console: 

Spoiler
>"D:\Utilities\AutoIt3\SciTE\..\AutoIt3.exe" "D:\Utilities\AutoIt3\SciTE\AutoIt3Wrapper\AutoIt3Wrapper.au3" /run /prod /ErrorStdOut /in "D:\Users\Tester\Downloads\ITaskbarList\ITaskbarList\212222-working-with-winrt-objects-in-memory\au3.212222-working-with-winrt_v3.au3" /UserParams    
+>12:20:44 Starting AutoIt3Wrapper (pid=37900) 23.402.1150.10 from:SciTE.exe (4.4.6.0)  Keyboard:00000409  OS:WIN_11/2009  CPU:X64 OS:X64  Environment(Language:0409)  CodePage:0  utf8.auto.check:4
+>         SciTEDir => D:\Utilities\AutoIt3\SciTE   UserDir => C:\Users\Tester\AppData\Local\AutoIt v3\SciTE\AutoIt3Wrapper   SCITE_USERHOME => C:\Users\Tester\AppData\Local\AutoIt v3\SciTE 
>Running AU3Check (3.3.17.0)  from:D:\Utilities\AutoIt3  input:D:\Users\Tester\Downloads\ITaskbarList\ITaskbarList\212222-working-with-winrt-objects-in-memory\au3.212222-working-with-winrt_v3.au3
+>12:20:44 AU3Check ended. rc:0
>Running:(3.3.16.1):D:\Utilities\AutoIt3\autoit3_x64.exe "D:\Users\Tester\Downloads\ITaskbarList\ITaskbarList\212222-working-with-winrt-objects-in-memory\au3.212222-working-with-winrt_v3.au3"    
+>Setting Hotkeys...--> Press Ctrl+Alt+Break to Restart. --> Press Ctrl+BREAK to Stop.
Get AQS String
Get "Windows.Devices.Display.DisplayMonitor" Activation Factory, IDisplayMonitorStatics
(25,0) [0x00000000] The operation completed successfully.
Call IDisplayMonitorStatics::GetDeviceSelector
(28,0) [0x00000000] The operation completed successfully.
(System.Devices.InterfaceClassGuid:="{E6F07B5F-EE97-4a90-B076-33F57BF4EAA7}" AND System.Devices.InterfaceEnabled:=System.StructuredQueryType.Boolean#True) OR System.Devices.ChallengeAep:=System.StructuredQueryType.Boolean#False

Get Device Collection:
Get "Windows.Devices.Enumeration.DeviceInformation" Activation Factory, IDeviceInformationStatics
(35,0) [0x00000000] The operation completed successfully.
Call IDeviceInformationStatics::FindAllAsyncAqsFilter with AQS string that we aquired earlier
(38,0) [0x00000000] The operation completed successfully.
Wait for ASync routine...
Get AsyncInfo Interface:
(42,0) [0x00000000] The operation completed successfully.
Async Finished. We want the status to be 1 - i.e. 'completed':
Async status=1
>
+>12:20:44 AutoIt3 ended. rc:0
+>12:20:44 AutoIt3Wrapper Finished.
>Exit code: 0    Time: 1.371

Do let me know if these console output are welcomed/useful to this project, otherwise am spamming the thread :) 

Edited by argumentum
clarify

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting.
autoit_scripter_blue_userbar.png

Link to comment
Share on other sites

Yep absolutely agree.  Resource management and error handling had already gone out the window, so I decided the slap-dash approach was good enough for a demo! I'll have a proper run at putting something together soon and report back.

Think I'm starting to get a handle on things too, so shouldn't need that console output. But thanks, I did appreciate the support :)

Lastly, I finally managed to pull those descriptor blobs! Well the EDID of my screen anyway.The DisplayID block - if present - needs to be a particular version for windows to use it, so I guess it's not surprising that mine doesn't show.
 

#AutoIt3Wrapper_UseX64=Y
#Tidy_Parameters=/sf

#include <winapi.au3>
#include <array.au3>

; Com error code reference:
; https://learn.microsoft.com/en-us/windows/win32/com/com-error-codes-1

Global $hDLLComBase = DllOpen("Combase.dll")
Global Const $PTR_LEN = @AutoItX64 ? 8 : 4

Global Const $sIUnknown = "{00000000-0000-0000-C000-000000000046}"
Global Const $sIInspectable = "{AF86E2E0-B12D-4c6a-9C5A-D7AA65101E90}"
Global Const $sIActivationFactory = "{00000035-0000-0000-C000-000000000046}"
Global Const $sIDisplayMonitorStatics = "{6EAE698F-A228-4C05-821D-B695D667DE8E}"
Global Const $sIDeviceInformationStatics = "{C17F100E-3A46-4A78-8013-769DC9B97390}"
Global Const $sIAsyncInfo = "{00000036-0000-0000-C000-000000000046}"
Global Const $sIDeviceInformation = "{ABA0FB95-4398-489D-8E44-E6130927011F}"
Global Const $sIDisplayMonitor = "{1f6b15d4-1d01-4c51-87e2-6f954a772b59}"

Global Enum $Async_Started = 0, $Async_Completed, $Async_Canceled, $Async_Error

ConsoleWrite("Get AQS String" & @CRLF)
ConsoleWrite('Get "Windows.Devices.Display.DisplayMonitor" Activation Factory, IDisplayMonitorStatics' & @CRLF)
$pMonStatics = RoGetActivationFactory("Windows.Devices.Display.DisplayMonitor", $sIDisplayMonitorStatics)
DispError()
ConsoleWrite("Call IDisplayMonitorStatics::GetDeviceSelector" & @CRLF)
$sDevSelector = IDisplayMonitorStatics_GetDeviceSelector($pMonStatics)
DispError()
ConsoleWrite($sDevSelector & @CRLF)
ConsoleWrite(@CRLF)

ConsoleWrite("Get Device Collection:" & @CRLF)
ConsoleWrite('Get "Windows.Devices.Enumeration.DeviceInformation" Activation Factory, IDeviceInformationStatics' & @CRLF)
$pDevInfoFact = RoGetActivationFactory("Windows.Devices.Enumeration.DeviceInformation", $sIDeviceInformationStatics)
DispError()
ConsoleWrite("Call IDeviceInformationStatics::FindAllAsyncAqsFilter with AQS string that we aquired earlier" & @CRLF)
$pAsync = IDeviceInformationStatics_FindAllAsyncAqsFilter($pDevInfoFact, $sDevSelector)
DispError()
ConsoleWrite("Wait for Async routine..." & @CRLF)
ConsoleWrite("Get AsyncInfo Interface:" & @CRLF)
$pAsyncInfo = IUnknown_QueryInterface($pAsync, $sIAsyncInfo)
DispError()
Do
    Sleep(10)
Until IAsyncInfo_Status($pAsyncInfo)
ConsoleWrite("Async Finished. We want the status to be 1 - i.e. 'completed':" & @CRLF)
ConsoleWrite("Async status=" & IAsyncInfo_Status($pAsyncInfo) & @CRLF)
ConsoleWrite("GetResult of Async:" & @CRLF)
$pDevInfoCol = IAsyncOperation_GetResults($pAsync)
DispError()
ConsoleWrite("Collection size=" & IVectorView_Size($pDevInfoCol) & @CRLF)
ConsoleWrite(@CRLF)

ConsoleWrite("Get First DisplayMonitor Obj" & @CRLF)
ConsoleWrite("Get the fisrt item of our collection:" & @CRLF)
$pDevinfo = IVectorView_GetAt($pDevInfoCol, 0)
DispError()
ConsoleWrite("Get the name:" & @CRLF)
$sDevName = IDeviceInformation_Name($pDevinfo)
DispError()
ConsoleWrite("Device Name = " & $sDevName & @CRLF)

ConsoleWrite("Get Device Interface ID:" & @CRLF)
$sDevInterfaceId = IDeviceInformation_Id($pDevinfo)
DispError()
ConsoleWrite($sDevInterfaceId & @CRLF)
ConsoleWrite("Get DisplayMonitor from Device Interface Id:" & @CRLF)
$pAsync2 = IDisplayMonitorStatics_FromInterfaceIdAsync($pMonStatics, $sDevInterfaceId)
DispError()
ConsoleWrite("Kick off Async..." & @CRLF)
$pAsyncInfo2 = IUnknown_QueryInterface($pAsync2, $sIAsyncInfo)
DispError()
Do
    Sleep(10)
Until IAsyncInfo_Status($pAsyncInfo2)
ConsoleWrite("Get the object." & @CRLF)
$pMonitor = IAsyncOperation_GetResults($pAsync2)
DispError()
ConsoleWrite("Confirm what we have (cause we can!)" & @CRLF)
ConsoleWrite(IInspectable_GetRuntimeClassName($pMonitor) & @CRLF)
DispError()

ConsoleWrite(@CRLF)
ConsoleWrite("Get descriptors..." & @CRLF)
ConsoleWrite("Display EDID:" & @CRLF)
ConsoleWrite(IDisplayMonitor_GetDescriptor($pMonitor, 0) & @CRLF)
ConsoleWrite("Display DisplayID:" & @CRLF)
ConsoleWrite(IDisplayMonitor_GetDescriptor($pMonitor, 1) & @CRLF)
ConsoleWrite(@CRLF)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Func CoTaskMemFree($pBlock)
    DllCall("ole32.dll", "none", "CoTaskMemFree", "ptr", $pBlock)
EndFunc   ;==>CoTaskMemFree

Func CreateGUID($sGUID)
    Local $tGUID = DllStructCreate($tagGUID)
    $aGUID = StringSplit(StringRegExpReplace($sGUID, "[{}]", ""), "-", 2)
    If UBound($aGUID) <> 5 Then Return False

    $tGUID.Data1 = Dec($aGUID[0])
    $tGUID.Data2 = Dec($aGUID[1])
    $tGUID.Data3 = Dec($aGUID[2])
    $tGUID.Data4 = Binary("0x" & $aGUID[3] & $aGUID[4])

    Return $tGUID
EndFunc   ;==>CreateGUID

Func CreateHString($sString)
    Local $aCall = DllCall($hDLLComBase, "int", "WindowsCreateString", "wstr", $sString, "uint", StringLen($sString), "ptr*", 0)
    If Not @error Then Return $aCall[3]
EndFunc   ;==>CreateHString

Func DeleteHString(ByRef $hString)
    Local $aCall = DllCall($hDLLComBase, "int", "WindowsDeleteString", "ptr", $hString)
    If Not @error Then $hString = 0
EndFunc   ;==>DeleteHString

Func DispError($iError = @error, $iScriptLineNumber = @ScriptLineNumber)
    Local Const $iMaxWidth = 0xFF
    Local $iFlags = $FORMAT_MESSAGE_FROM_SYSTEM
    Local $tBuff = DllStructCreate(StringFormat("wchar[%d]", $iMaxWidth))
    Local $pBuff = DllStructGetPtr($tBuff)
    Local $iCount = _WinAPI_FormatMessage($iFlags, 0, $iError, 0, $pBuff, $iMaxWidth, 0)
    ConsoleWrite('(' & $iScriptLineNumber & ",0) [0x" & Hex($iError) & "] " & StringStripWS(DllStructGetData($tBuff, 1), 3) & @CRLF)
EndFunc   ;==>DispError

Func GetPtrAt($pPtr)
    Local $tPtr = DllStructCreate("ptr ptr", $pPtr)
    Return $tPtr.ptr
EndFunc   ;==>GetPtrAt

Func IActivationFactory_ActivateInstance($pThis)
    Local $pVTable = GetPtrAt($pThis)
    Local $pFunc = GetPtrAt(Ptr($pVTable + 6 * $PTR_LEN))

    Local $aCall = DllCallAddress("long", $pFunc, "ptr", $pThis, "ptr*", 0)

    Return SetError($aCall[0], 0, $aCall[2])
EndFunc   ;==>IActivationFactory_ActivateInstance

Func IAsyncInfo_Cancel($pThis)
    Local $pVTable = GetPtrAt($pThis)
    Local $pFunc = GetPtrAt(Ptr($pVTable + 9 * $PTR_LEN))

    Local $aCall = DllCallAddress("long", $pFunc, "ptr", $pThis)

    Return SetError($aCall[0])
EndFunc   ;==>IAsyncInfo_Cancel

Func IAsyncInfo_Close($pThis)
    Local $pVTable = GetPtrAt($pThis)
    Local $pFunc = GetPtrAt(Ptr($pVTable + 10 * $PTR_LEN))

    Local $aCall = DllCallAddress("long", $pFunc, "ptr", $pThis)

    Return SetError($aCall[0])
EndFunc   ;==>IAsyncInfo_Close

Func IAsyncInfo_ErrorCode($pThis)
    Local $pVTable = GetPtrAt($pThis)
    Local $pFunc = GetPtrAt(Ptr($pVTable + 8 * $PTR_LEN))

    Local $aCall = DllCallAddress("long", $pFunc, "ptr", $pThis, "long*", 0)

    Return SetError($aCall[0], 0, $aCall[2])
EndFunc   ;==>IAsyncInfo_ErrorCode

Func IAsyncInfo_ID($pThis)
    Local $pVTable = GetPtrAt($pThis)
    Local $pFunc = GetPtrAt(Ptr($pVTable + 6 * $PTR_LEN))

    Local $aCall = DllCallAddress("long", $pFunc, "ptr", $pThis, "uint*", 0)

    Return SetError($aCall[0], 0, $aCall[2])
EndFunc   ;==>IAsyncInfo_ID

Func IAsyncInfo_Status($pThis)
    Local $pVTable = GetPtrAt($pThis)
    Local $pFunc = GetPtrAt(Ptr($pVTable + 7 * $PTR_LEN))

    Local $aCall = DllCallAddress("long", $pFunc, "ptr", $pThis, "uint*", 0)

    Return SetError($aCall[0], 0, $aCall[2])
EndFunc   ;==>IAsyncInfo_Status

Func IAsyncOperation_GetResults($pThis)
    Local $pVTable = GetPtrAt($pThis)
    Local $pFunc = GetPtrAt(Ptr($pVTable + 8 * $PTR_LEN))

    Local $aCall = DllCallAddress("long", $pFunc, "ptr", $pThis, "ptr*", 0)

    Return SetError($aCall[0], 0, $aCall[2])
EndFunc   ;==>IAsyncOperation_GetResults

Func IDeviceInformation_EnclosureLocation($pThis)
    Local $pVTable = GetPtrAt($pThis)
    Local $pFunc = GetPtrAt(Ptr($pVTable + 10 * $PTR_LEN))

    Local $aCall = DllCallAddress("long", $pFunc, "ptr", $pThis, "ptr*", 0)

    Return SetError($aCall[0], 0, $aCall[2])
EndFunc   ;==>IDeviceInformation_EnclosureLocation


Func IDeviceInformation_Id($pThis)
    Local $pVTable = GetPtrAt($pThis)
    Local $pFunc = GetPtrAt(Ptr($pVTable + 6 * $PTR_LEN))

    Local $aCall = DllCallAddress("long", $pFunc, "ptr", $pThis, "ptr*", 0)
    Local $sID = ReadHString($aCall[2])
    DeleteHString($aCall[2])

    Return SetError($aCall[0], 0, $sID)
EndFunc   ;==>IDeviceInformation_Id

Func IDeviceInformation_IsDefault($pThis)
    Local $pVTable = GetPtrAt($pThis)
    Local $pFunc = GetPtrAt(Ptr($pVTable + 9 * $PTR_LEN))

    Local $aCall = DllCallAddress("long", $pFunc, "ptr", $pThis, "bool*", 0)

    Return SetError($aCall[0], 0, $aCall[2] = True)
EndFunc   ;==>IDeviceInformation_IsDefault

Func IDeviceInformation_IsEnabled($pThis)
    Local $pVTable = GetPtrAt($pThis)
    Local $pFunc = GetPtrAt(Ptr($pVTable + 8 * $PTR_LEN))

    Local $aCall = DllCallAddress("long", $pFunc, "ptr", $pThis, "bool*", 0)

    Return SetError($aCall[0], 0, $aCall[2] = True)
EndFunc   ;==>IDeviceInformation_IsEnabled

Func IDeviceInformation_Name($pThis)
    Local $pVTable = GetPtrAt($pThis)
    Local $pFunc = GetPtrAt(Ptr($pVTable + 7 * $PTR_LEN))

    Local $aCall = DllCallAddress("long", $pFunc, "ptr", $pThis, "ptr*", 0)
    Local $sName = ReadHString($aCall[2])
    DeleteHString($aCall[2])

    Return SetError($aCall[0], 0, $sName)
EndFunc   ;==>IDeviceInformation_Name

Func IDeviceInformation_Properties($pThis)
    Local $pVTable = GetPtrAt($pThis)
    Local $pFunc = GetPtrAt(Ptr($pVTable + 11 * $PTR_LEN))

    Local $aCall = DllCallAddress("long", $pFunc, "ptr", $pThis, "ptr*", 0)

    Return SetError($aCall[0], 0, $aCall[2])
EndFunc   ;==>IDeviceInformation_Properties

Func IDeviceInformationStatics_FindAllAsyncAqsFilter($pThis, $sFilter)
    Local $pVTable = GetPtrAt($pThis)
    Local $pFunc = GetPtrAt(Ptr($pVTable + 10 * $PTR_LEN))
    Local $hsFilter = CreateHString($sFilter)

    Local $aCall = DllCallAddress("long", $pFunc, "ptr", $pThis, "ptr", $hsFilter, "ptr*", 0)

    DeleteHString($hsFilter)
    Return SetError($aCall[0], 0, $aCall[3])
EndFunc   ;==>IDeviceInformationStatics_FindAllAsyncAqsFilter


Func IDisplayMonitor_GetDescriptor($pThis, $iKind)
    Local $pVTable = GetPtrAt($pThis)
    Local $pFunc = GetPtrAt(Ptr($pVTable + 25 * $PTR_LEN))
    Local $aCall = DllCallAddress("long", $pFunc, "ptr", $pThis, "long", $iKind, "long*", 0, "ptr*", 0)
    Local $tData
    $tData = DllStructCreate(StringFormat("byte Data[%d]", $aCall[3]), $aCall[4])
    Return SetError($aCall[0], 0, IsDllStruct($tData) ? $tData.Data : Binary("0x"))
EndFunc   ;==>IDisplayMonitor_GetDescriptor

Func IDisplayMonitorStatics_FromInterfaceIdAsync($pThis, $sDevInterfaceId)
    Local $pVTable = GetPtrAt($pThis)
    Local $pFunc = GetPtrAt(Ptr($pVTable + 8 * $PTR_LEN))
    $hsDevIface = CreateHString($sDevInterfaceId)
    Local $aCall = DllCallAddress("long", $pFunc, "ptr", $pThis, "ptr", $hsDevIface, "ptr*", 0)
    DeleteHString($hsDevIface)

    Return SetError($aCall[0], 0, $aCall[3])
EndFunc   ;==>IDisplayMonitorStatics_FromInterfaceIdAsync


Func IDisplayMonitorStatics_GetDeviceSelector($pThis)
    Local $pVTable = GetPtrAt($pThis)
    Local $pFunc = GetPtrAt(Ptr($pVTable + 6 * $PTR_LEN))

    Local $aCall = DllCallAddress("long", $pFunc, "ptr", $pThis, "ptr*", 0)

    Local $sSelector = ReadHString($aCall[2])
    DeleteHString($aCall[2])

    Return SetError($aCall[0], 0, $sSelector)
EndFunc   ;==>IDisplayMonitorStatics_GetDeviceSelector

Func IInspectable_GetIids($pThis)
    Local $pVTable = GetPtrAt($pThis)
    Local $pFunc = GetPtrAt(Ptr($pVTable + 3 * $PTR_LEN))

    Local $aCall = DllCallAddress("long", $pFunc, "ptr", $pThis, "long*", 0, "ptr*", 0)
    Local $pGUIDArray = $aCall[3], $iError = $aCall[0], $iCount = $aCall[2], $asIIDs[$iCount]
    For $i = 0 To $iCount - 1
        $aCall = DllCall($hDLLComBase, "int", "StringFromIID", "ptr", Ptr($pGUIDArray + ($i * 16)), "wstr*", 0)
        $asIIDs[$i] = $aCall[2]
    Next

    CoTaskMemFree($pGUIDArray)

    Return SetError($aCall[0], 0, $asIIDs)
EndFunc   ;==>IInspectable_GetIids

Func IInspectable_GetRuntimeClassName($pThis)
    Local $pVTable = GetPtrAt($pThis)
    Local $pFunc = GetPtrAt(Ptr($pVTable + 4 * $PTR_LEN))
    Local $aCall = DllCallAddress("long", $pFunc, "ptr", $pThis, "handle*", 0)
    Local $sClassName = ReadHString($aCall[2])
    DeleteHString($aCall[2])

    Return SetError($aCall[0], 0, $sClassName)
EndFunc   ;==>IInspectable_GetRuntimeClassName

Func IInspectable_GetTrustLevel($pThis)
    Local $pVTable = GetPtrAt($pThis)
    Local $pFunc = GetPtrAt(Ptr($pVTable + 5 * $PTR_LEN))

    Local $aCall = DllCallAddress("long", $pFunc, "ptr", $pThis, "int*", 0)

    Return SetError($aCall[0], 0, $aCall[2])
EndFunc   ;==>IInspectable_GetTrustLevel

Func IUnknown_AddRef($pThis)
    Local $pVTable = GetPtrAt($pThis)
    Local $pFunc = GetPtrAt(Ptr($pVTable + $PTR_LEN))

    Local $aCall = DllCallAddress("long", $pFunc, "ptr", $pThis)
    Return $aCall[0]
EndFunc   ;==>IUnknown_AddRef


Func IUnknown_QueryInterface($pThis, $sIID)
    Local $pVTable = GetPtrAt($pThis)
    Local $pFunc = GetPtrAt($pVTable)
    Local $tIID = CreateGUID($sIID)

    Local $aCall = DllCallAddress("long", $pFunc, "ptr", $pThis, "struct*", $tIID, "ptr*", 0)
    Return SetError($aCall[0], 0, $aCall[3])
EndFunc   ;==>IUnknown_QueryInterface

Func IUnknown_Release($pThis)
    Local $pVTable = GetPtrAt($pThis)
    Local $pFunc = GetPtrAt(Ptr($pVTable + 2 * $PTR_LEN))

    Local $aCall = DllCallAddress("long", $pFunc, "ptr", $pThis)
    Return $aCall[0]
EndFunc   ;==>IUnknown_Release

Func IVectorView_GetAt($pThis, $iIndex)
    Local $pVTable = GetPtrAt($pThis)
    Local $pFunc = GetPtrAt(Ptr($pVTable + 6 * $PTR_LEN))

    Local $aCall = DllCallAddress("long", $pFunc, "ptr", $pThis, "uint", $iIndex, "ptr*", 0)

    Return SetError($aCall[0], 0, $aCall[3])
EndFunc   ;==>IVectorView_GetAt

Func IVectorView_Size($pThis)
    Local $pVTable = GetPtrAt($pThis)
    Local $pFunc = GetPtrAt(Ptr($pVTable + 7 * $PTR_LEN))

    Local $aCall = DllCallAddress("long", $pFunc, "ptr", $pThis, "uint*", 0)

    Return SetError($aCall[0], 0, $aCall[2])
EndFunc   ;==>IVectorView_Size

Func ReadGUIDAt($pGUID)
    Local $tGUID = DllStructCreate($tagGUID, $pGUID)
    Local $sGUID = "{"

    $sGUID &= Hex($tGUID.Data1, 8) & "-"
    $sGUID &= Hex($tGUID.Data2, 4) & "-"
    $sGUID &= Hex($tGUID.Data3, 4) & "-"
    $sGUID &= StringMid($tGUID.Data4, 3, 4) & "-"
    $sGUID &= StringMid($tGUID.Data4, 7, 12) & "}"

    Return $sGUID
EndFunc   ;==>ReadGUIDAt

Func ReadHString(ByRef $hString)
    Local $aCall = DllCall($hDLLComBase, "wstr", "WindowsGetStringRawBuffer", "ptr", $hString, "int*", 0)
    If Not @error Then Return $aCall[0]
EndFunc   ;==>ReadHString

Func RoActivateInstance($sClassID)
    $hsClassID = CreateHString($sClassID)
    Local $aCall = DllCall($hDLLComBase, "long", "RoActivateInstance", "handle", $hsClassID, "ptr*", 0)
    DeleteHString($hsClassID)
    Return SetError($aCall[0], 0, $aCall[2])
EndFunc   ;==>RoActivateInstance

Func RoGetActivationFactory($sClassID, $sIID)
    Local $hsClassID = CreateHString($sClassID)
    Local $tIID = CreateGUID($sIID)
    Local $aCall = DllCall($hDLLComBase, "long", "RoGetActivationFactory", "handle", $hsClassID, "ptr", DllStructGetPtr($tIID), "ptr*", 0)
    DeleteHString($hsClassID)
    Return SetError($aCall[0], 0, $aCall[3])
EndFunc   ;==>RoGetActivationFactory

 

Link to comment
Share on other sites

2 hours ago, MattyD said:

Lastly, I finally managed to pull those descriptor blobs! Well the EDID of my screen anyway.The DisplayID block - if present - needs to be a particular version for windows to use it, so I guess it's not surprising that mine doesn't show.

I pulled both my monitors ( on 23H2 ), no blob that I can see either.

Spoiler
...
ConsoleWrite("Collection size=" & IVectorView_Size($pDevInfoCol) & @CRLF)
ConsoleWrite(@CRLF)

For $iIndex = 0 To IVectorView_Size($pDevInfoCol) - 1
    ConsoleWrite("=== ------------------- Mon. # " & $iIndex + 1 & " ----------------------- ===" & @CRLF)

    ConsoleWrite("Get First DisplayMonitor Obj" & @CRLF)
    ConsoleWrite("Get the fisrt item of our collection:" & @CRLF)
    $pDevinfo = IVectorView_GetAt($pDevInfoCol, $iIndex)
    DispError()
    ConsoleWrite("Get the name:" & @CRLF)
    $sDevName = IDeviceInformation_Name($pDevinfo)
    DispError()
    ConsoleWrite("Device Name = " & $sDevName & @CRLF)

    ConsoleWrite("Get Device Interface ID:" & @CRLF)
    $sDevInterfaceId = IDeviceInformation_Id($pDevinfo)
    DispError()
    ConsoleWrite($sDevInterfaceId & @CRLF)
    ConsoleWrite("Get DisplayMonitor from Device Interface Id:" & @CRLF)
    $pAsync2 = IDisplayMonitorStatics_FromInterfaceIdAsync($pMonStatics, $sDevInterfaceId)
    DispError()
    ConsoleWrite("Kick off Async..." & @CRLF)
    $pAsyncInfo2 = IUnknown_QueryInterface($pAsync2, $sIAsyncInfo)
    DispError()
    Do
        Sleep(10)
    Until IAsyncInfo_Status($pAsyncInfo2)
    ConsoleWrite("Get the object." & @CRLF)
    $pMonitor = IAsyncOperation_GetResults($pAsync2)
    DispError()
    ConsoleWrite("Confirm what we have (cause we can!)" & @CRLF)
    ConsoleWrite(IInspectable_GetRuntimeClassName($pMonitor) & @CRLF)
    DispError()

    ConsoleWrite(@CRLF)
    ConsoleWrite("Get descriptors..." & @CRLF)
    ConsoleWrite("Display EDID:" & @CRLF)
    ConsoleWrite(IDisplayMonitor_GetDescriptor($pMonitor, 0) & @CRLF)
    ConsoleWrite("Display DisplayID:" & @CRLF)
    ConsoleWrite(IDisplayMonitor_GetDescriptor($pMonitor, 1) & @CRLF)
    ConsoleWrite(@CRLF)

Next
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
...

and yes, very nice.

In case anyone playing with those PiKVM needing a Display EDID that works by pulling one of yours, here are mine.

Spoiler
>"D:\Utilities\AutoIt3\SciTE\..\AutoIt3.exe" "D:\Utilities\AutoIt3\SciTE\AutoIt3Wrapper\AutoIt3Wrapper.au3" /run /prod /ErrorStdOut /in "D:\Users\Tester\Downloads\ITaskbarList\ITaskbarList\212222-working-with-winrt-objects-in-memory\au3.212222-working-with-winrt_v4.au3" /UserParams    
+>11:13:18 Starting AutoIt3Wrapper (pid=35632) 23.402.1150.10 from:SciTE.exe (4.4.6.0)  Keyboard:00000409  OS:WIN_11/2009  CPU:X64 OS:X64  Environment(Language:0409)  CodePage:0  utf8.auto.check:4
+>         SciTEDir => D:\Utilities\AutoIt3\SciTE   UserDir => C:\Users\Tester\AppData\Local\AutoIt v3\SciTE\AutoIt3Wrapper   SCITE_USERHOME => C:\Users\Tester\AppData\Local\AutoIt v3\SciTE 
>Running AU3Check (3.3.17.0)  from:D:\Utilities\AutoIt3  input:D:\Users\Tester\Downloads\ITaskbarList\ITaskbarList\212222-working-with-winrt-objects-in-memory\au3.212222-working-with-winrt_v4.au3
+>11:13:18 AU3Check ended. rc:0
>Running:(3.3.16.1):D:\Utilities\AutoIt3\autoit3_x64.exe "D:\Users\Tester\Downloads\ITaskbarList\ITaskbarList\212222-working-with-winrt-objects-in-memory\au3.212222-working-with-winrt_v4.au3"    
+>Setting Hotkeys...--> Press Ctrl+Alt+Break to Restart. --> Press Ctrl+BREAK to Stop.
Get AQS String
Get "Windows.Devices.Display.DisplayMonitor" Activation Factory, IDisplayMonitorStatics
(27,0) [0x00000000] The operation completed successfully.
Call IDisplayMonitorStatics::GetDeviceSelector
(30,0) [0x00000000] The operation completed successfully.
(System.Devices.InterfaceClassGuid:="{E6F07B5F-EE97-4a90-B076-33F57BF4EAA7}" AND System.Devices.InterfaceEnabled:=System.StructuredQueryType.Boolean#True) OR System.Devices.ChallengeAep:=System.StructuredQueryType.Boolean#False

Get Device Collection:
Get "Windows.Devices.Enumeration.DeviceInformation" Activation Factory, IDeviceInformationStatics
(37,0) [0x00000000] The operation completed successfully.
Call IDeviceInformationStatics::FindAllAsyncAqsFilter with AQS string that we aquired earlier
(40,0) [0x00000000] The operation completed successfully.
Wait for Async routine...
Get AsyncInfo Interface:
(44,0) [0x00000000] The operation completed successfully.
Async Finished. We want the status to be 1 - i.e. 'completed':
Async status=1
GetResult of Async:
(52,0) [0x00000000] The operation completed successfully.
Collection size=2

=== ------------------- Mon. # 1 ----------------------- ===
Get First DisplayMonitor Obj
Get the fisrt item of our collection:
(63,0) [0x00000000] The operation completed successfully.
Get the name:
(66,0) [0x00000000] The operation completed successfully.
Device Name = Generic Monitor (LS27A800U)
Get Device Interface ID:
(71,0) [0x00000000] The operation completed successfully.
\\?\DISPLAY#SAM71A4#5&2464ea33&0&UID4353#{e6f07b5f-ee97-4a90-b076-33f57bf4eaa7}
Get DisplayMonitor from Device Interface Id:
(75,0) [0x00000000] The operation completed successfully.
Kick off Async...
(78,0) [0x00000000] The operation completed successfully.
Get the object.
(84,0) [0x00000000] The operation completed successfully.
Confirm what we have (cause we can!)
Windows.Devices.Display.DisplayMonitor
(87,0) [0x00000000] The operation completed successfully.

Get descriptors...
Display EDID:
0x00FFFFFFFFFFFF004C2DA47132575843351F0104B53C22783A0495AE5241AE260F5054BFEF80714F810081C08180A9C0B300950001014DD000A0F0703E803020350055502100001A000000FD001E4B1E873C000A202020202020000000FC004C53323741383030550A202020000000FF0048345A524330313330300A202001DB02031CF0475F101F041303122309070783010000E305C000E3060501023A801871382D40582C450055502100001E565E00A0A0A029503020350055502100001A04740030F2705A80B0588A0055502100001E00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000036
Display DisplayID:


=== ------------------- Mon. # 2 ----------------------- ===
Get First DisplayMonitor Obj
Get the fisrt item of our collection:
(63,0) [0x00000000] The operation completed successfully.
Get the name:
(66,0) [0x00000000] The operation completed successfully.
Device Name = Generic Monitor (LG ULTRAWIDE)
Get Device Interface ID:
(71,0) [0x00000000] The operation completed successfully.
\\?\DISPLAY#GSM76F9#5&2464ea33&0&UID4352#{e6f07b5f-ee97-4a90-b076-33f57bf4eaa7}
Get DisplayMonitor from Device Interface Id:
(75,0) [0x00000000] The operation completed successfully.
Kick off Async...
(78,0) [0x00000000] The operation completed successfully.
Get the object.
(84,0) [0x00000000] The operation completed successfully.
Confirm what we have (cause we can!)
Windows.Devices.Display.DisplayMonitor
(87,0) [0x00000000] The operation completed successfully.

Get descriptors...
Display EDID:
0x00FFFFFFFFFFFF001E6DF97607110800051C010380502278EACA95A6554EA1260F5054256B807140818081C0A9C0B300D1C08100D1CFCD4600A0A0381F4030203A001E4E3100001A003A801871382D40582C4500132A2100001E000000FD00384B1E5A18000A202020202020000000FC004C4720554C545241574944450A01E302031AF12309070747100403011F13128301000065030C0014008C0AD08A20E02D10103E96001E4E31000018295900A0A038274030203A001E4E3100001A000000000000000000000000000000000000000000000000000000000000000000000000000000FF003830354E544E48464A3634370A000000000000000000000090
Display DisplayID:


>
+>11:13:18 AutoIt3 ended. rc:0
+>11:13:18 AutoIt3Wrapper Finished.
>Exit code: 0    Time: 1.316

 

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting.
autoit_scripter_blue_userbar.png

Link to comment
Share on other sites

Ok so I've uploaded something that's still pretty rough...

I'll fix any glaring mistakes, but TBH I'll probably not develop this much further - at least in the immediate future.

Anyway, I figure it might help someone in the future who's going down this particular rabbit hole :)

 

Edit - My console output for the demo script if its of interest...

Spoiler


>Handy funcs for development:
(8,0) [0x00000000] The operation completed successfully.

(10,0) Supported Interfaces:
Class: Windows.Foundation.Collections.IVectorView`1<Windows.Devices.Enumeration.DeviceInformation>
{E170688F-3495-5BF6-AAB5-9CAC17E0F10F}
{00000038-0000-0000-C000-000000000046}
{DD9F8A5D-EC98-5F4B-A3EA-9C8B5AD53C4B}

(11,0) Class: Windows.Foundation.Collections.IVectorView`1<Windows.Devices.Enumeration.DeviceInformation>

>List Monitors...
+----------------------------------------
+ Get Display:  Generic Monitor (S22D300)
+----------------------------------------

Name: S22D300

DeviceID         : \\?\DISPLAY#SAM0B3F#4&10d8532f&0&UID4145#{e6f07b5f-ee97-4a90-b076-33f57bf4eaa7}
Adapter DeviceID : \\?\PCI#VEN_8086&DEV_46A8&SUBSYS_0B0C1028&REV_0C#3&11583659&1&10#{5b45201d-f2f2-4f3b-85bb-30ff1f953599}
Adapter LUID     : 83394
Adapter TargetID : 4145

Connection Kind    : Wired
Physical Connector : HDMI
Usage              : Standard

Native Resolution     : [ 1920, 1080 ]
Screen Size in Inches : [ 18.779528, 10.551181 ]
DPI (X, Y)            : [ 102.238991, 102.358208 ]

Dolby Vision in HDR Supported : False

Chroma (R,G,B,W):
[ 0.646984, 0.333508 ]
[ 0.321789, 0.626477 ]
[ 0.157727, 0.061047 ]
[ 0.313000, 0.329602 ]

Luminance in nits (max, min, MaxFALL): [ 270, 0.5, 270 ]

EDID: 0x00FFFFFFFFFFFF004C2D3F0B35415A5A1819010380301B782A9561A55552A0280F5054BFEF80714F81C0810081809500A9C0B3000101023A801871382D40582C4500DD0C1100001E011D007251D01E206E285500DD0C1100001E000000FD00324B1E5111000A202020202020000000FC00533232443330300A202020202001A0020311B14690041F13120365030C001000011D00BC52D01E20B8285540DD0C1100001E8C0AD090204031200C405500DD0C110000188C0AD08A20E02D10103E9600DD0C11000018000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000050
DisplayId:

+----------------------------------------
+ Get Display:  NB225283
+----------------------------------------

Name:

DeviceID         : \\?\DISPLAY#SHP14E2#4&10d8532f&0&UID8388688#{e6f07b5f-ee97-4a90-b076-33f57bf4eaa7}
Adapter DeviceID : \\?\PCI#VEN_8086&DEV_46A8&SUBSYS_0B0C1028&REV_0C#3&11583659&1&10#{5b45201d-f2f2-4f3b-85bb-30ff1f953599}
Adapter LUID     : 83394
Adapter TargetID : 8388688

Connection Kind    : Internal
Physical Connector : Unknown
Usage              : Standard

Native Resolution     : [ 1920, 1080 ]
Screen Size in Inches : [ 12.165355, 6.850394 ]
DPI (X, Y)            : [ 157.825241, 157.655167 ]

Dolby Vision in HDR Supported : False

Chroma (R,G,B,W):
[ 0.640148, 0.329602 ]
[ 0.300305, 0.600109 ]
[ 0.149914, 0.060070 ]
[ 0.313000, 0.328625 ]

Luminance in nits (max, min, MaxFALL): [ 270, 0.5, 270 ]

EDID: 0x00FFFFFFFFFFFF004D10E214000000000E1D0104A51F11780EDE50A3544C99260F5054000000010101010101010101010101010101011A3680A070381E403020350035AE10000018482B80A070381E403020350035AE10000018000000FE005436594D34814C513134304D3100000000000241031E011200000A010A202000A70000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
DisplayId:

 

Edited by MattyD
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...