Popular Post MattyD Posted August 29 Popular Post Share Posted August 29 (edited) 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... WinRT.au3 - Core high level functions that sit on top of interface libraries Includes Async and Collection implementations etc. So basic high level functionality. WinRTCore.au3 - Internal helper functions for interface libraries Interface Folder - Interface libraries (there are over 850 of these!). Essentially these wrap the functions in an interface's vtable Includes tags which may be used with ObjCreateInterface Enums Folder - Contains map datatypes that can be used to convert enumeration strings to their numeric type, or vice versa Classes Folder - doesn't actually contain code - A class file includes interface and enum files that belong to a class. Namespaces Folder - doesn't actually contain code - A namespace file includes classes that are related. Bonus: I've also uploaded a rudimentary WinRT Class Explorer if it happens to be useful to anyone. Bonus2: I've added a tool that installs/removes calltips for interface libraries. 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! expandcollapse popup#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 Libraries - Latest ClassExplorer.zip Edited October 26 by MattyD Gianni, KaFu, Danyfirex and 3 others 3 3 Link to comment Share on other sites More sharing options...
ahmet Posted August 29 Share Posted August 29 Does ObjaCreateInterface do something similar? Link to comment Share on other sites More sharing options...
MattyD Posted August 29 Author Share Posted August 29 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. expandcollapse popup#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 More sharing options...
argumentum Posted August 29 Share Posted August 29 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 expandcollapse popup>"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. Link to comment Share on other sites More sharing options...
MattyD Posted August 31 Author Share Posted August 31 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. expandcollapse popup#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 Danyfirex and argumentum 2 Link to comment Share on other sites More sharing options...
argumentum Posted August 31 Share Posted August 31 (edited) 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 August 31 by argumentum clarify Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting. Link to comment Share on other sites More sharing options...
MattyD Posted September 2 Author Share Posted September 2 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. expandcollapse popup#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 Danyfirex and argumentum 2 Link to comment Share on other sites More sharing options...
argumentum Posted September 2 Share Posted September 2 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 expandcollapse popup... 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 expandcollapse popup>"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 MattyD 1 Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting. Link to comment Share on other sites More sharing options...
MattyD Posted September 5 Author Share Posted September 5 (edited) 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 September 5 by MattyD argumentum 1 Link to comment Share on other sites More sharing options...
MattyD Posted September 19 Author Share Posted September 19 a quick update - I had discovered WinRT objects are all described in metadata files living in system32\WinMetaData - So my thought was I could write something that generates the beginnings of those Interface libraries (i.e. the functions that wrap an interface) . Not sure how much of a reality this will be, but I've started to attack the object that extracts the metadata anyhow. There's enough code there I think to add it to the zip! That second "TypeLib" example demonstrates more or less where I'm up to. Change the search string to pull all objects that match Gianni and argumentum 2 Link to comment Share on other sites More sharing options...
MattyD Posted September 27 Author Share Posted September 27 Hi all My first attempt at a generator is now largely going, so here are ~320 odd interface libraries for anyone looking to tackle Windows.Devices.xxxx classes! The ObjCreateInterface() tags should also now work if people would rather go down that route. I still have plenty of development to do here, so just expect some bugs and a bit of fluidity between uploads. Link to comment Share on other sites More sharing options...
MattyD Posted September 29 Author Share Posted September 29 Hi all - just uploaded v1.3 I'm still only dealing with Windows.Devices for now... I missed a bunch of interfaces last time around, so we're now in the vicinity ~850 with the latest upload. Enumeration defs have been moved out of the interface libraries, and are now defined externally (see enums folder) New class files - These group together all the interface and enumeration files that belong to a class into a single file New Namespace files - These group related class files together into one place. These are what you should include in your script! (along with WinRT.au3) removed the winrt_blah files - these were libraries built on top of classes, which are now out of scope for this project! I still have them if anyone would like a copy... MetaDataImport, DisplayMonitor and DeviceInformation, I'll also eventually write up some documentation - but that'll be a little while off yet. In the meantime I'm more than happy to answer any questions. I realize the examples may be a bit opaque at the minute... Link to comment Share on other sites More sharing options...
MattyD Posted October 5 Author Share Posted October 5 Hi all - a new version is up. I've made some massive changes behind the scenes to the generator script, so I'm hoping this will fix more things than it'll break! A few notes... The upload includes more interfaces that were hiding in the metadata under the "Activatable" custom attribute. Enums with a value > 0x7FFFFFFF used to cause the script to crash - So to get around this we now need to use _WinRT_GetEnum($mMap, $iValue) to resolve numeric enums to their string representation. Fixed a number of functions that I was mishandling when the return value was "none". Better handling of functions that pass arrays in or out (when its not a return value). - I'm still not 100% happy with this yet, so be warned implementation will probably change down the track. I still need to properly tackle paramatised interfaces, so that's another area that's likely to change. argumentum 1 Link to comment Share on other sites More sharing options...
Gianni Posted October 6 Share Posted October 6 Hi @MattyD,First of all, thank you for this work you are doing. From a first look at the WinRT UDF, I see that the _WinRT_WaitForAsync function is used to block the execution of the main script until the expected event is raised (or expires). I would like to ask you if there is a way to use something similar to the AutoIt ObjEvent() function as an alternative (or maybe, even better, use that function directly). That is, give the user the possibility to pass the name of their own function attached to an event that will be called asynchronously when that event occurs? I apologize in advance if I misunderstood the mechanism of the _WinRT_WaitForAsync() function ... bye and thank you Chimp small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt.... Link to comment Share on other sites More sharing options...
MattyD Posted October 6 Author Share Posted October 6 (edited) Hey Gianni, thanks for the support. I'm learning as I go here, and in short this is something that I'll need to look in to. Registration shouldn't be an issue - objects have "add" and "remove" handler methods for this. Basically we need to figure out how to create the delegate to register. Regarding _WinRT_WaitForAsync(), this works by polling the Async object's Status property, then calling its GetResult method which points you somewhere. So point being there's no callbacks involved in this process. But you could also theoretically register a AsyncOperationCompletedHandler delegate, which would presumably fire on the completion of the operation. So I guess we need to discover how to create delegate objects, then we can look at triggering user functions! Edited October 6 by MattyD clarity Gianni 1 Link to comment Share on other sites More sharing options...
MattyD Posted October 26 Author Share Posted October 26 Hi all, I haven't had a ton of time to throw at this of late, so just an incremental tonight (while I can still remember what's changed!). The generation script is largely the same as last go around. Fixed tags for some interfaces (functions with no params were incorrectly generated, invalidating the tag.) WaitForAsync now accepts AsyncAction objects (previously it'd only work with AsyncOperation objects) I'm trawling through all the inbuilt metadata files now, so there's literally thousands of libraries in this latest upload. I've hit the size limit for posting here, hence the sourceforge link up the top! Updated the "calltips installer" script - this is now included in the zip file. Updated the "class explorer" script to something that's hopefully a bit more presentable - this one is still a separate download. argumentum and Gianni 2 Link to comment Share on other sites More sharing options...
argumentum Posted October 26 Share Posted October 26 nice !. Added a Dark mode coloring for my setup Spoiler expandcollapse popup... Global $g_IsDarkMode = IsDarkMode() Init() ... Func GetItemColour($iItem) Local $tItem, $tName Local $sFile, $pScope, $iTypeDef, $aProps, $iCol = $g_IsDarkMode ? 0xCCCCCC : 0x000000 $tItem = DllStructCreate($tagLVITEM) $tName = DllStructCreate("wchar Text[260]") $tItem.Text = DllStructGetPtr($tName) $tItem.TextMax = 260 GUICtrlSendMsg($hTypeDefs, $LVM_GETITEMTEXTW, $iItem, DllStructGetPtr($tItem)) $sFile = _MetaData_GetMetaDataFile($tName.Text) $pScope = _MetaData_OpenScope($pDispenser, $sFile) $iTypeDef = _MetaData_FindTypeDef($pScope, $tName.Text) $aProps = _MetaData_GetTypeDefProps($pScope, $iTypeDef) If BitAND($aProps[1], 0x20) Then $iCol = $g_IsDarkMode ? 0xd47f7f : 0xAA0000 Else Switch _MetaData_GetTokenName($pScope, $aProps[2]) Case "System.Object" $iCol = $g_IsDarkMode ? 0x6666cc : 0x0000AA Case "System.Enum" $iCol = 0x0080AA Case "System.ValueType" $iCol = 0xAAAA00 Case "System.MulticastDelegate" $iCol = 0x008000 Case "System.Attribute" $iCol = 0x800080 Case Else ;~ ConsoleWrite( _MetaData_GetTokenName($pScope, $aProps[2]) & @CRLF) EndSwitch EndIf _WinRT_DeleteObject($pScope) Return $iCol EndFunc ;==>GetItemColour Func IsDarkMode() ; https://www.autoitscript.com/forum/topic/139260-autoit-snippets/?do=findComment&comment=1520332 ; https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getsyscolor Return (PerceivedBrightnessOfColor(_WinAPI_GetSysColor($COLOR_WINDOWTEXT)) _ > PerceivedBrightnessOfColor(_WinAPI_GetSysColor($COLOR_WINDOW))) ; if the text is perceived as brighter than the background then Return True EndFunc ;==>IsDarkMode Func PerceivedBrightnessOfColor($color) ; https://learn.microsoft.com/en-us/windows/apps/desktop/modernize/apply-windows-themes#know-when-dark-mode-is-enabled ; This function performs a quick calculation of the perceived brightness of a color, and takes into consideration ; ways that different channels in an RGB color value contribute to how bright it looks to the human eye. Local $a = StringSplit(Hex($color, 6), ""), $r = 2 * Dec($a[1] & $a[2]), $g = 5 * Dec($a[3] & $a[4]), $b = 1 * Dec($a[5] & $a[6]) Return ($r + $g + $b) EndFunc ;==>PerceivedBrightnessOfColor MattyD 1 Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting. Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now