Trolleule Posted December 24, 2015 Posted December 24, 2015 (edited) Hey,i'm working with a dll which comes with Windows 10 (Pro x64) called dismapi.dll, which is located under C:\Windows\system32\dismapi.dll.I tested some of it's functions with my compiled script on Windows 10 (x86) and it worked properly, but when i run my script on my x64 system with#AutoIt3Wrapper_UseX64=y directive set, it doesn't work anymore (AutoIT breaks on line 1255 in DISM.au3). Without this directive it works.Is there something i have to change to get it work? Thanks for help...(You can use my attach. If you use WIndows 10, it will work directly, on Windows 8 you might have to adjust the dism api path ($ghdismapi) in DISM.au3. On Windows 7, you will need Windows ADK to get DISM.) _DLLStructDisplay.au3 is only for debug.https://msdn.microsoft.com/de-de/library/windows/desktop/hh825837.aspx Misc.au3_DLLStructDisplay.au3DismConstants.au3DismExample.au3DISM.au3 Edited December 26, 2015 by Trolleule
Danp2 Posted December 24, 2015 Posted December 24, 2015 AutoIT breaks on line 1255 in DISM.au3Your description is very vague. What you you mean by "breaks"? Does it give an error message? Crash? Or ???Also, this line is commented code. Post the section of code that is problematic so that we can see exactly which line the error is occurring. Latest Webdriver UDF Release Webdriver Wiki FAQs
Trolleule Posted December 24, 2015 Author Posted December 24, 2015 (edited) sorry, it's line 1251. AutoIT crashes on this line, where i try to read the pointer in a array of WCHAR.MsgBox(0, "ProductName", GetPCWSTR($tImageInfo_sub, "ProductName")) The function GetPCWSTR can be found in Misc.au3 and looks like:Func GetPCWSTR(ByRef $struct, $sElementName) ; avoids memory access conflicts Local $char_struct Local $anz = 0 ; counter for signs Local $ptr = DllStructGetData($struct, $sElementName) ; ptr Do $char_struct = DllStructCreate("WCHAR", $ptr + $anz) ; get memory location $anz += 2 Until DllStructGetData($char_struct, 1) = Chr(0) ; end of string Local $PCWSTR_struct = DllStructCreate("WCHAR[" & $anz / 2 & "]", $ptr) ; create struct with correct amount of bytes Local $PCWSTR = DllStructGetData($PCWSTR_struct, 1) _DISM_Delete($PCWSTR_struct) ; free resources Return $PCWSTR ; return string EndFuncThe problem only occurs when i use 64-bit AutoIT and 64-bit dll version. I think some of the data types are not compatible with 64-bit anymore, although the first 6 elements are readable properly:MsgBox(0, "ImageType", _DISM_GetImageType(DllStructGetData($tImageInfo_sub, "ImageType"))) MsgBox(0, "ImageIndex", DllStructGetData($tImageInfo_sub, "ImageIndex")) MsgBox(0, "ImageName", GetPCWSTR($tImageInfo_sub, "ImageName")) MsgBox(0, "ImageDescription", GetPCWSTR($tImageInfo_sub, "ImageDescription")) MsgBox(0, "ImageSize", DllStructGetData($tImageInfo_sub, "ImageSize")) MsgBox(0, "Architecture", DllStructGetData($tImageInfo_sub, "Architecture")) MsgBox(0, "ProductName", GetPCWSTR($tImageInfo_sub, "ProductName")) ; autoit crashesEDIT: The exact line where it crashes is in Misc.au3$char_struct = DllStructCreate("WCHAR", $ptr + $anz) ; get memory location, when i try to read the pointer of "ProductName" in DISM.au3 on line 1251.I'm not able to read one char of this pointer :S Edited December 24, 2015 by Trolleule
Danp2 Posted December 24, 2015 Posted December 24, 2015 Based on your latest post, it sounds like the issue isn't in the DLLCall like you originally suggested. What's the definition of $tImageInfo_sub? Latest Webdriver UDF Release Webdriver Wiki FAQs
Trolleule Posted December 25, 2015 Author Posted December 25, 2015 (edited) Local $tagDismImageInfo = "INT ImageType;UINT ImageIndex;PTR ImageName;PTR ImageDescription;UINT64 ImageSize;UINT Architecture;PTR ProductName;PTR EditionId;PTR InstallationType;" & _ "PTR Hal;PTR ProductType;PTR ProductSuite;UINT MajorVersion;UINT MinorVersion;UINT Build;UINT SpBuild;UINT SpLevel;INT Bootable;PTR SystemRoot;" & _ "PTR Language;UINT LanguageCount;UINT DefaultLanguageIndex;PTR CustomizedInfo" Local $tImageInfo_sub = DllStructCreate($tagDismImageInfo, $pImageInfo)My first expection was to change some of these data types... otherwise it might be more complicated :SPerhaps you can test it. You only need Windows ADK + some .wim file. Thanks in advance!EDIT: Try this DISM.au3, it's better to understand (i updated the DISM.au3 in my first post too) DISM.au3 Edited December 25, 2015 by Trolleule
Danp2 Posted December 25, 2015 Posted December 25, 2015 Have you looked at this thread? It appears to work in both x32 and x64, Latest Webdriver UDF Release Webdriver Wiki FAQs
Trolleule Posted December 25, 2015 Author Posted December 25, 2015 (edited) Sure But DISM API is more powerfull! You can't delete packages with wimgapi.dll. Edited December 25, 2015 by Trolleule
Trolleule Posted December 25, 2015 Author Posted December 25, 2015 A friend tested it in C++, the x64 dismapi.dll works properly.Are there some debug techniques i can use to check what is wrong with pointers or a possibility to read the pointer byte by byte?
Danp2 Posted December 26, 2015 Posted December 26, 2015 Looking at the output from _DLLStructDisplay, it appears that the high / low orders are reversed for elements 7 - 11 and 19. Reverse the order and Autoit no longer crashes. Latest Webdriver UDF Release Webdriver Wiki FAQs
Trolleule Posted December 26, 2015 Author Posted December 26, 2015 (edited) ui that sounds nice. What do you mean with reverse? ->Local $tagDismImageInfo = "INT ImageType;UINT ImageIndex;PTR ImageName;PTR ImageDescription;UINT64 ImageSize;UINT Architecture;" & _ "PTR;SystemRoot;PTR ProductType;PTR Hal;PTR InstallationType;PTR EditionId;PTR ProductName;" & _ "PTR ProductSuite;UINT MajorVersion;UINT MinorVersion;UINT Build;UINT SpBuild;UINT SpLevel;INT Bootable;" & _ "PTR Language;UINT LanguageCount;UINT DefaultLanguageIndex;PTR CustomizedInfo"instead ofLocal $tagDismImageInfo = "INT ImageType;UINT ImageIndex;PTR ImageName;PTR ImageDescription;UINT64 ImageSize;UINT Architecture;" & _ "PTR ProductName;PTR EditionId;PTR InstallationType;PTR Hal;PTR ProductType;PTR ProductSuite;" & _ "UINT MajorVersion;UINT MinorVersion;UINT Build;UINT SpBuild;UINT SpLevel;INT Bootable;PTR SystemRoot;" & _ "PTR Language;UINT LanguageCount;UINT DefaultLanguageIndex;PTR CustomizedInfo"?Reversed:Normal: Edited December 26, 2015 by Trolleule
Danp2 Posted December 26, 2015 Posted December 26, 2015 No, reverse the actual high / low order values. Here's how I did it:MsgBox(0, "ProductName", GetPCWSTR($tImageInfo, "ProductName", True))Func GetPCWSTR(ByRef $struct, $sElementName, $lSwap = False) ; avoids memory access conflicts Local $char_struct Local $anz = 0 ; counter for signs Local $ptr = DllStructGetData($struct, $sElementName) ; ptr If $lSwap Then $ptr = '0x' & hex(_WinAPI_LoDWord($ptr), 8) & hex(_WinAPI_HiDWord($ptr), 8) EndIf Do $char_struct = DllStructCreate("WCHAR", $ptr + $anz) ; get memory location $anz += 2 Until DllStructGetData($char_struct, 1) = Chr(0) ; end of string Local $PCWSTR_struct = DllStructCreate("WCHAR[" & $anz / 2 & "]", $ptr) ; create struct with correct amount of bytes Local $PCWSTR = DllStructGetData($PCWSTR_struct, 1) _DISM_Delete($PCWSTR_struct) ; free resources Return $PCWSTR ; return string EndFuncYou'll need to add "#include <WinAPIMisc.au3>" to Misc.au3. Latest Webdriver UDF Release Webdriver Wiki FAQs
Trolleule Posted December 26, 2015 Author Posted December 26, 2015 (edited) big thanks! Now i can read from pointer, but something is strange:ConsoleWrite("ImageType: " & DllStructGetData($tImageInfo, "ImageType") & @CRLF) ; ok ConsoleWrite("ImageIndex: " & DllStructGetData($tImageInfo, "ImageIndex") & @CRLF) ; ok ConsoleWrite("ImageName: " & GetPCWSTR($tImageInfo, "ImageName") & @CRLF) ; ok ConsoleWrite("ImageDescription: " & GetPCWSTR($tImageInfo, "ImageDescription") & @CRLF) ; ok ConsoleWrite("ImageSize: " & DllStructGetData($tImageInfo, "ImageSize") & @CRLF) ; ok ConsoleWrite("Architecture: " & DllStructGetData($tImageInfo, "Architecture") & @CRLF) ; ok ConsoleWrite("ProductName: " & GetPCWSTR($tImageInfo, "ProductName", True) & @CRLF) ; x86: Betriebssystem Microsoft® Windows® x64: Professional ConsoleWrite("EditionId: " & GetPCWSTR($tImageInfo, "EditionId", True) & @CRLF) ; x86: Professional x64: Client ConsoleWrite("InstallationType: " & GetPCWSTR($tImageInfo, "InstallationType", True) & @CRLF) ; x86: Client x64: ConsoleWrite("Hal: " & GetPCWSTR($tImageInfo, "Hal", True) & @CRLF) ; x86: x64: WinNT ConsoleWrite("ProductType: " & GetPCWSTR($tImageInfo, "ProductType", True) & @CRLF) ; x86: WinNT x64: Terminal Server ConsoleWrite("ProductSuite: " & DLLStructGetData($tImageInfo, "ProductSuite") & @CRLF) ; x86: Terminal Server x64: 0x0000000A000000C8 (PCWSTR will crash AutoIT) ConsoleWrite("MajorVersion: " & DllStructGetData($tImageInfo, "MajorVersion") & @CRLF) ; x86: 10 x64: 0 ConsoleWrite("MinorVersion: " & DllStructGetData($tImageInfo, "MinorVersion") & @CRLF) ; x86: 0 x64: 10586 ConsoleWrite("Build: " & DllStructGetData($tImageInfo, "Build") & @CRLF) ; x86: 10586 x64: 0 ConsoleWrite("SpBuild: " & DllStructGetData($tImageInfo, "SpBuild") & @CRLF) ; x86: 0 x64: 0 ConsoleWrite("SpLevel: " & DllStructGetData($tImageInfo, "SpLevel") & @CRLF) ; x86: 0 x64: 1 ConsoleWrite("Bootable: " & DllStructGetData($tImageInfo, "Bootable") & @CRLF) ; x86: 1 x64: -1950295936 ConsoleWrite("SystemRoot: " & GetPCWSTR($tImageInfo, "SystemRoot", True) & @CRLF) ; x86: WINDOWS x64: ??o ConsoleWrite("Language: " & DllStructGetData($tImageInfo, "Language") & @CRLF) ; x86: ok x64: 0x000000010000006F ConsoleWrite("LanguageCount: " & DllStructGetData($tImageInfo, "LanguageCount") & @CRLF) ; x86: 1 x64: 0 ConsoleWrite("DefaultLanguageIndex: " & DllStructGetData($tImageInfo, "DefaultLanguageIndex") & @CRLF) ; x86: 0 x64: 2291066752 ConsoleWrite("CustomizedInfo: " & DllStructGetData($tImageInfo, "CustomizedInfo") & @CRLF) ; x86: ok x64: 0x000000000000006Fthe order is messy. "ProductName" keeps information of "EditionId" and so on, but i think if we can get the order right, the rest would be right too...Do you know why this happens and do you have a solution? EDIT:I tested around and campe up with this:Local $tagDismImageInfo = "INT ImageType;UINT ImageIndex;PTR ImageName;PTR ImageDescription;UINT64 ImageSize;" & _ "UINT Architecture;PTR EditionId;PTR InstallationType;" & _ "PTR Hal;PTR ProductType;PTR ProductSuite;UINT MajorVersion;UINT MinorVersion;" & _ "UINT Build;UINT SpBuild;UINT SpLevel;UINT Bootable;INT SystemRoot;" & _ "PTR Language;PTR LanguageCount;UINT DefaultLanguageIndex;UINT CustomizedInfo;PTR ProductName" ConsoleWrite("ImageType: " & DllStructGetData($tImageInfo, "ImageType") & @CRLF) ConsoleWrite("ImageIndex: " & DllStructGetData($tImageInfo, "ImageIndex") & @CRLF) ConsoleWrite("ImageName: " & GetPCWSTR($tImageInfo, "ImageName") & @CRLF) ConsoleWrite("ImageDescription: " & GetPCWSTR($tImageInfo, "ImageDescription") & @CRLF) ConsoleWrite("ImageSize: " & DllStructGetData($tImageInfo, "ImageSize") & @CRLF) ConsoleWrite("Architecture: " & DllStructGetData($tImageInfo, "Architecture") & @CRLF) ConsoleWrite("ProductName: " & DllStructGetData($tImageInfo, "ProductName") & @CRLF) ConsoleWrite("EditionId: " & GetPCWSTR($tImageInfo, "EditionId", True) & @CRLF) ConsoleWrite("InstallationType: " & GetPCWSTR($tImageInfo, "InstallationType", True) & @CRLF) ConsoleWrite("Hal: " & GetPCWSTR($tImageInfo, "Hal", True) & @CRLF) ConsoleWrite("ProductType: " & GetPCWSTR($tImageInfo, "ProductType", True) & @CRLF) ConsoleWrite("ProductSuite: " & GetPCWSTR($tImageInfo, "ProductSuite", True) & @CRLF) ConsoleWrite("MajorVersion: " & DllStructGetData($tImageInfo, "MajorVersion") & @CRLF) ConsoleWrite("MinorVersion: " & DllStructGetData($tImageInfo, "MinorVersion") & @CRLF) ConsoleWrite("Build: " & DllStructGetData($tImageInfo, "Build") & @CRLF) ConsoleWrite("SpBuild: " & DllStructGetData($tImageInfo, "SpBuild") & @CRLF) ConsoleWrite("SpLevel: " & DllStructGetData($tImageInfo, "SpLevel") & @CRLF) ConsoleWrite("Bootable: " & DllStructGetData($tImageInfo, "Bootable") & @CRLF) ConsoleWrite("SystemRoot: " & DllStructGetData($tImageInfo, "SystemRoot") & @CRLF) ConsoleWrite("Language: " & GetPCWSTR($tImageInfo, "Language", True) & @CRLF) ConsoleWrite("LanguageCount: " & DllStructGetData($tImageInfo, "LanguageCount") & @CRLF) ConsoleWrite("DefaultLanguageIndex: " & DllStructGetData($tImageInfo, "DefaultLanguageIndex") & @CRLF) ConsoleWrite("CustomizedInfo: " & DllStructGetData($tImageInfo, "CustomizedInfo") & @CRLF)You can see, the order is wrong, but this gives the best results...Output:ImageType: 0ImageIndex: 1ImageName: Windows 10 Pro Technical PreviewImageDescription: Windows 10 Pro Technical PreviewImageSize: 13298258120Architecture: 9EditionId: ProfessionalInstallationType: ClientHal: ProductType: WinNTProductSuite: Terminal ServerMajorVersion: 224MinorVersion: 10Build: 0SpBuild: 10586SpLevel: 0Bootable: 0SystemRoot: 1Language: ?°ÃLanguageCount: 0x00000001000000E0DefaultLanguageIndex: 0CustomizedInfo: 572084256Something is really strange :S Edited December 26, 2015 by Trolleule
Trolleule Posted December 26, 2015 Author Posted December 26, 2015 Fuck...i got it and i don't know why I only add "align 4" to my struct, default is "align 8". Now it works properly and without Lo/Hi reverse.$tagDismImageInfo = "align 4;INT ImageType;UINT ImageIndex;PTR ImageName;PTR ImageDescription;UINT64 ImageSize;" & _ "UINT Architecture;PTR ProductName;PTR EditionId;PTR InstallationType;" & _ "PTR Hal;PTR ProductType;PTR ProductSuite;UINT MajorVersion;UINT MinorVersion;UINT Build;UINT SpBuild;" & _ "UINT SpLevel;INT Bootable;PTR SystemRoot;" & _ "PTR Language;UINT LanguageCount;UINT DefaultLanguageIndex;PTR CustomizedInfo"Big thanks Danp2! I think i have to change the topic title to mark this as resolved right?
Danp2 Posted December 26, 2015 Posted December 26, 2015 Nice find! Glad you were able to figure out the proper solution. Latest Webdriver UDF Release Webdriver Wiki FAQs
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