Homes32 Posted March 30, 2011 Posted March 30, 2011 (edited) A UDF for manipulating Windows Image Files (.wim) without ImageX.exeThis UDF allows you to use the Windows Imaging API directly (wimgapi.dll) so you don't have to use a command line program such as ImageX. Benefits are wimgapi.dll is shipped with windows 7 so users don't have to download the 1gb+ AIK to manage wim files. The UDF also allows you to utilize callback functions so you can show detailed progress info to your users.wimfltr.sys/wimmount.sys required for mount/unmount only.working with both 32 and 64 bit builds.its pretty well documented but you should still read the MS Imaging API documentation and be familiar how wimgapi.dll works to get the most out of this UDF.functions marked with an (*) are only available with newer versions of wimgapi.dllFunctions Included:_WIM_ApplyImage_WIM_CaptureImage_WIM_CloseHandle_WIM_CreateFile_WIM_DeleteImage_WIM_DeleteImageMounts *_WIM_ExportImage_WIM_ExtractImagePath *_WIM_GetImageAttributes_WIM_GetImageCount_WIM_GetImageInformation_WIM_LoadImage_WIM_MountImage_WIM_RegisterLogFile *_WIM_RegisterMessageCallback_WIM_RemountImage *_WIM_SetBootImage_WIM_SetImageInformation_WIM_SetReferenceFile_WIM_SetTemporaryPath_WIM_Shutdown_WIM_Startup_WIM_UnMountImage_WIM_UnRegisterLogFile *_WIM_UnregisterMessageCallbackhave fun!Homes32Sample Usageexpandcollapse popup#include <Wimgapi.au3> ; functions for WIM Global $swimfile, $hWim, $hImage, $filepath, $Percent, $rTime, $pCallBack Global $gsWimDLL = @SystemDir & "wimgapi.dll" ; path to wimgapi.dll $ProgramName = "WIM Demo" ; Fire up wimgapi.dll $aResult = _WIM_Startup() If @error = 2 Then MsgBox(16, $ProgramName, "Error loading library: " & "(" & $aResult & "," & @error & ", " & $gsWimDLL & ")" & @CRLF & @CRLF & "The file could not be found.") Exit (2) ElseIf @error = 1 Then MsgBox(16, $ProgramName, "Error loading library: " & "(" & $aResult & "," & @error & ", " & $gsWimDLL & ")" & @CRLF & @CRLF & "Wrong DLL. Make sure you are using the right arch (x86/x64)") Exit (254) EndIf ; your code here ; ex. ; Capture("C:toolz", "c:test.wim", "My Test IMG", "Test Desc", 1) ; Cleanup() ; Apply ;----------------------------- Func Apply($sWimFile, $iImageIndex, $sTarget) ProgressOn('Apply', '', '', -1, -1, 19) ; Register callbacks so we get progress information for the capture process. ; WARNING: This does not work very well with Apply do to the way autoit handles callbacks. ; See the following post for more info: ; http://www.autoitscript.com/forum/topic/127075-wimgapi-udf/page__view__findpost__p__917049 $pCallBack = DllCallbackRegister('CallBack', 'int', 'dword;WPARAM;LPARAM;dword') _WIM_RegisterMessageCallback(0, DllCallbackGetPtr($pCallBack), 0) ; load .wim file with read access $hWim = _WIM_CreateFile($sWimFile, $WIM_GENERIC_READ, $WIM_OPEN_EXISTING, 0, 0, 0) If $hWim = 0 Then MsgBox(48, $ProgramName, "Error: Failed to load image. (" & $hWim & "," & @error & "," & @extended & ")") Cleanup() Exit (252) EndIf ; set our temp path $aResult = _WIM_SetTemporaryPath($hWim, $sTarget) ; load the image index $hImage = _WIM_LoadImage($hWim, $iImageIndex) ; Apply the image $aResult = _WIM_ApplyImage($hImage, $sTarget) If $aResult = 0 Then MsgBox(48, $ProgramName, "Error: Failed to apply image. Make sure your path exists! (" & $aResult & "," & @error & "," & @extended & ")") Cleanup() ProgressOff() EndFunc ; Mount ;----------------------------- Func Mount($sMountPath, $sWimFile, $iImageIndex, $RW) $aResult = _WIM_MountImage($sMountPath, $sWimFile, $iImageIndex, $RW) If $aResult = 0 Then MsgBox(48, $ProgramName, "Mount Error: (" & $aResult & "," & @error & "," & @extended & ")") Cleanup() Exit (253) ; mount error EndIf Cleanup() EndFunc ; UnMount ;----------------------------- Func UnMount($sMountPath, $iCommit) $aResult = _WIM_UnMountImage($sMountPath, 0, 0, $iCommit) If $aResult = 0 Then MsgBox(48, $ProgramName, "UnMount Error: (" & $aResult & "," & @error & "," & @extended & ")") Cleanup() Exit (254) ; Unmount error EndIf Cleanup() EndFunc ; GetInfo ;----------------------------- Func GetInfo($sWimFile) ; load .wim file with read access $hWim = _WIM_CreateFile($sWimFile, $WIM_GENERIC_READ, $WIM_OPEN_EXISTING, 0, 0, 0) If $hWim = 0 Then MsgBox(48, $ProgramName, "Error: Failed to load image. (" & $hWim & "," & @error & "," & @extended & ")") Cleanup() Exit (252) EndIf ; set our temp path $aResult = _WIM_SetTemporaryPath($hWim, @TempDir) ; read wim attributes $aWimAttribs = _WIM_GetImageAttributes($hWim) ; read info from the image $aXML = _WIM_GetImageInformation($hWim) ; Cleanup any open handles Cleanup() ; make our output pretty Switch $aWimAttribs[4] Case $WIM_COMPRESS_NONE $aWimAttribs[4] = "NONE" Case $WIM_COMPRESS_XPRESS $aWimAttribs[4] = "XPRESS" Case $WIM_COMPRESS_LZX $aWimAttribs[4] = "LZX" EndSwitch Local $outFile = @ScriptDir & "wiminfo.txt" If FileExists($outFile) Then FileDelete($outFile) FileWrite($outFile, @CRLF & $ProgramName & @CRLF & @CRLF & @CRLF & @CRLF & _ "WIM Information:" & @CRLF & _ "----------------" & @CRLF & _ "Wim Path: : " & $aWimAttribs[1] & @CRLF & _ "GUID : " & $aWimAttribs[2] & @CRLF & _ "Image Count: " & $aWimAttribs[3] & @CRLF & _ "Compression: " & $aWimAttribs[4] & @CRLF & _ "Part Number: " & $aWimAttribs[5] & "/" & $aWimAttribs[6] & @CRLF & _ "Boot Index : " & $aWimAttribs[7] & @CRLF & _ "Attributes : " & $aWimAttribs[8] & @CRLF & @CRLF & @CRLF & _ "Available Image Choices:" & @CRLF & _ "------------------------" & @CRLF & _ $aXML[1]) EndFunc ;==>GetInfo ; Extract ;----------------------------- Func Extract($sWimFile, $iImageIndex, $sFilePath, $sExtractTo) ; load .wim file with read access $hWim = _WIM_CreateFile($sWimFile, $WIM_GENERIC_READ, $WIM_OPEN_EXISTING, 0, 0, 0) If $hWim = 0 Then MsgBox(48, $ProgramName, "Error: Failed to load image. (" & $hWim & "," & @error & "," & @extended & ")") Cleanup() Exit (252) EndIf ; set our temp path $aResult = _WIM_SetTemporaryPath($hWim, @TempDir) ; load the image index $hImage = _WIM_LoadImage($hWim, $iImageIndex) ; extract the file $aResult = _WIM_ExtractImagePath($hImage, $sFilePath, $sExtractTo) If $aResult = 0 Then MsgBox(48, $ProgramName, "Error: Failed to extract from image. Make sure your path exists! (" & $aResult & "," & @error & "," & @extended & ")") Cleanup() EndFunc ; Capture ;----------------------------- Func Capture($Path, $sWimFile, $sImageName, $sImageDesc, $Compress) ProgressOn('Capture', '', '', -1, -1, 19) ; Register callbacks so we get progress information for the capture process. $pCallBack = DllCallbackRegister('CallBack', 'int', 'dword;WPARAM;LPARAM;dword') _WIM_RegisterMessageCallback(0, DllCallbackGetPtr($pCallBack), 0) ; first we need to create a blank .wim file with write access and our compression options $hWim = _WIM_CreateFile($sWimFile, $WIM_GENERIC_WRITE, $WIM_CREATE_ALWAYS, 0, $Compress, 0) If $hWim = 0 Then MsgBox(48, $ProgramName, "Error: Failed to create image. (" & $hWim & "," & @error & "," & @extended & ")") Cleanup() Exit (252) ; image create failed EndIf ; set our temp path $aResult = _WIM_SetTemporaryPath($hWim, @TempDir) ; start the image capture!!! $hImage = _WIM_CaptureImage($hWim, $Path, 0) If $hImage = 0 Then MsgBox(48, $ProgramName, "Error: Failed to capture image. (" & $hImage & "," & @error & "," & @extended & ")") Cleanup() Exit (251) ; image capture failed EndIf ; add our name and description to the XML data - ChrW(65279) is the BOM $sXML = ChrW(65279) & "<IMAGE><NAME>" & $sImageName & "</NAME><DESCRIPTION>" & $sImageDesc & "</DESCRIPTION></IMAGE>" _WIM_SetImageInformation($hImage, $sXML) _WIM_SetBootImage($hWim, 1) Cleanup() ; free resources ProgressOff() EndFunc ;==>Capture ; ================================================================================================================== ; Function: CallBack ; Description: Very Basic Sample Callback function for capture progress ; Usage: CallBack($msgId, $param1, $param2, $b) ; Author: Homes32 ; ================================================================================================================== Func CallBack($msgId, $param1, $param2, $unused) Switch $msgId Case $WIM_MSG_PROGRESS ; get progress % and time remaining $Percent = $param1 If $param2 = 0 Then $rTime = "" Else $rTime = StringFormat('Remaining: %i sec.', $param2 / 1000) EndIf Case $WIM_MSG_PROCESS ; get the file name being processed $Struct = DllStructCreate("ushort[1024]", $param1) $sFilePath = "" $i = 1 While 1 $Tmp = DllStructGetData($Struct, 1, $i) If $Tmp = 0 Then ExitLoop $sFilePath &= ChrW($Tmp) $i += 1 WEnd EndSwitch ProgressSet($Percent, StringFormat('%3i%% completed. %snn %s', $Percent, $rTime, $filePath), 'Capture ' & $sWimFile) Return $WIM_MSG_SUCCESS EndFunc ;==>CallBack Func Cleanup() ; Cleanup any open handles If $hImage Then _WIM_CloseHandle($hImage) If $hWim Then _WIM_CloseHandle($hWim) If $pCallBack Then ; Cleanup our callbacks $aResult = _WIM_UnregisterMessageCallback(0, DllCallbackGetPtr($pCallBack)) DllCallbackFree($pCallBack) EndIf _WIM_Shutdown() ; shutdown wimgapi.dll EndFunc ;==>CleanupHistoryv1 3-30-2011 * 1st release v2 4-4-2011 * cleaned up the documention * added the following functions _WIM_DeleteImage _WIM_DeleteImageMounts _WIM_ExportImage _WIM_RemountImage _WIM_SetReferenceFile v3 9-19-2011 * Fixed Access Violation crash in _WIM_GetImageInformationPrevious Downloads: 312WimgapiUDF.zip Edited May 9, 2012 by Homes32 AZJIO, i2i8 and KLM 3
MrCreatoR Posted March 30, 2011 Posted March 30, 2011 Any description on what is the purpose of this UDF (for those ho didn't heard about the WIMGAPI)?  Spoiler Using OS: Win 7 Professional, Using AutoIt Ver(s): 3.3.6.1 / 3.3.8.1  AutoIt Russian Community My Work... Spoiler Projects: ATT - Application Translate Tool {new}| BlockIt - Block files & folders {new}| SIP - Selected Image Preview {new}| SISCABMAN - SciTE Abbreviations Manager {new}| AutoIt Path Switcher | AutoIt Menu for Opera! | YouTube Download Center! | Desktop Icons Restorator | Math Tasks | KeyBoard & Mouse Cleaner | CaptureIt - Capture Images Utility | CheckFileSize ProgramUDFs: OnAutoItErrorRegister - Handle AutoIt critical errors {new}| AutoIt Syntax Highlight {new}| Opera Library! | Winamp Library | GetFolderToMenu | Custom_InputBox()! | _FileRun UDF | _CheckInput() UDF | _GUIInputSetOnlyNumbers() UDF | _FileGetValidName() UDF | _GUICtrlCreateRadioCBox UDF | _GuiCreateGrid() | _PathSplitByRegExp() | _GUICtrlListView_MoveItems - UDF | GUICtrlSetOnHover_UDF! | _ControlTab UDF! | _MouseSetOnEvent() UDF! | _ProcessListEx - UDF | GUICtrl_SetResizing - UDF! | Mod. for _IniString UDFs | _StringStripChars UDF | _ColorIsDarkShade UDF | _ColorConvertValue UDF | _GUICtrlTab_CoverBackground | CUI_App_UDF | _IncludeScripts UDF | _AutoIt3ExecuteCode | _DragList UDF | Mod. for _ListView_Progress | _ListView_SysLink | _GenerateRandomNumbers | _BlockInputEx | _IsPressedEx | OnAutoItExit Handler | _GUICtrlCreateTFLabel UDF | WinControlSetEvent UDF | Mod. for _DirGetSizeEx UDF Examples: ScreenSaver Demo - Matrix included | Gui Drag Without pause the script | _WinAttach()! | Turn Off/On Monitor | ComboBox Handler Example | Mod. for "Thinking Box" | Cool "About" Box | TasksBar Imitation Demo Like the Projects/UDFs/Examples? Please rate the topic (up-right corner of the post header: Rating ) * === My topics === * ================================================== ==================================================    AutoIt is simple, subtle, elegant. © AutoIt Team
Homes32 Posted March 30, 2011 Author Posted March 30, 2011 Any description on what is the purpose of this UDF (for those ho didn't heard about the WIMGAPI)?added.
MrCreatoR Posted March 30, 2011 Posted March 30, 2011 added.Thanks.  Spoiler Using OS: Win 7 Professional, Using AutoIt Ver(s): 3.3.6.1 / 3.3.8.1  AutoIt Russian Community My Work... Spoiler Projects: ATT - Application Translate Tool {new}| BlockIt - Block files & folders {new}| SIP - Selected Image Preview {new}| SISCABMAN - SciTE Abbreviations Manager {new}| AutoIt Path Switcher | AutoIt Menu for Opera! | YouTube Download Center! | Desktop Icons Restorator | Math Tasks | KeyBoard & Mouse Cleaner | CaptureIt - Capture Images Utility | CheckFileSize ProgramUDFs: OnAutoItErrorRegister - Handle AutoIt critical errors {new}| AutoIt Syntax Highlight {new}| Opera Library! | Winamp Library | GetFolderToMenu | Custom_InputBox()! | _FileRun UDF | _CheckInput() UDF | _GUIInputSetOnlyNumbers() UDF | _FileGetValidName() UDF | _GUICtrlCreateRadioCBox UDF | _GuiCreateGrid() | _PathSplitByRegExp() | _GUICtrlListView_MoveItems - UDF | GUICtrlSetOnHover_UDF! | _ControlTab UDF! | _MouseSetOnEvent() UDF! | _ProcessListEx - UDF | GUICtrl_SetResizing - UDF! | Mod. for _IniString UDFs | _StringStripChars UDF | _ColorIsDarkShade UDF | _ColorConvertValue UDF | _GUICtrlTab_CoverBackground | CUI_App_UDF | _IncludeScripts UDF | _AutoIt3ExecuteCode | _DragList UDF | Mod. for _ListView_Progress | _ListView_SysLink | _GenerateRandomNumbers | _BlockInputEx | _IsPressedEx | OnAutoItExit Handler | _GUICtrlCreateTFLabel UDF | WinControlSetEvent UDF | Mod. for _DirGetSizeEx UDF Examples: ScreenSaver Demo - Matrix included | Gui Drag Without pause the script | _WinAttach()! | Turn Off/On Monitor | ComboBox Handler Example | Mod. for "Thinking Box" | Cool "About" Box | TasksBar Imitation Demo Like the Projects/UDFs/Examples? Please rate the topic (up-right corner of the post header: Rating ) * === My topics === * ================================================== ==================================================    AutoIt is simple, subtle, elegant. © AutoIt Team
spudw2k Posted March 30, 2011 Posted March 30, 2011 I assume this is Vista and later as I cannot seem to find those DLLs on XP or 2k3? Spoiler Things I've Made: Always On Top Tool ◊ AU History â—ŠÂ Deck of Cards â—Š HideIt â—Š ICU â—Š Icon Freezer â—Š Ipod Ejector â—Š Junos Configuration Explorer â—Š Link Downloader â—Š MD5 Folder Enumerator â—Š PassGen â—ŠÂ Ping Tool â—Š Quick NIC â—Š Read OCR â—Š RemoteIT â—Š SchTasksGui â—Š SpyCam â—Š System Scan Report Tool â—Š System UpTime â—Š Transparency Machine ◊ VMWare ESX Builder Misc Code Snippets: ADODB Example â—Š CheckHover ◊ Detect SafeMode â—Š DynEnumArray â—Š GetNetStatData ◊ HashArray â—Š IsBetweenDates â—Š Local Admins â—Š Make Choice â—Š Recursive File List â—Š Remove Sizebox Style â—Š Retrieve PNPDeviceID â—Š Retrieve SysListView32 Contents â—Š Set IE Homepage â—Š Tickle Expired Password â—Š Transpose Array Projects: Drive Space Usage GUI â—ŠÂ LEDkIT â—Š Plasma_kIt â—ŠÂ Scan Engine Builder â—Š SpeeDBurner â—Š SubnetCalc Cool Stuff: AutoItObject UDF â—Š Extract Icon From Proc â—Š GuiCtrlFontRotate â—Š Hex Edit Funcs â—Š Run binary â—Š Service_UDF Â
Homes32 Posted March 31, 2011 Author Posted March 31, 2011 I assume this is Vista and later as I cannot seem to find those DLLs on XP or 2k3?correct. for xp you will still need to download the AIK from Microsoft.
JohnOne Posted March 31, 2011 Posted March 31, 2011 The primary purpose of Imaging APIs (Wimgapi.dll) is to programmatically capture, modify, and apply images for deployment in a manufacturing or corporate IT environment. Wimgapi.dll is now included by default in Windows 7. ImageX is an implementation of the Imaging APIs.http://msdn.microsoft.com/en-us/library/dd851933.aspx AutoIt Absolute Beginners  Require a serial  Pause Script  Video Tutorials by Morthawt  ipify Monkey's are, like, natures humans.
Catdaddy Posted March 31, 2011 Posted March 31, 2011 This is incredibly cool. I've been using GimageX for a while, and it works great. But this will help me to automate my imaging even more with my own custom scripts. Thank you very much for this UDF.
Homes32 Posted April 5, 2011 Author Posted April 5, 2011 This is incredibly cool. I've been using GimageX for a while, and it works great. But this will help me to automate my imaging even more with my own custom scripts. Thank you very much for this UDF.Glad you find it useful. its always nice to be able to give something back to a community that has been so helpful.UDF updated to v2. see 1st post.
Homes32 Posted April 25, 2011 Author Posted April 25, 2011 (edited) I've run into an issue with getting info from a wim image. Autoit will crash and the windows event log will always show Exception code: 0xc0000005which is a Access Violation error.tracing the _WIM_GetImageInformation func it always crashes at this lineFunc _WIM_GetImageInformation($hImage) Local $aReturn[2] ; array to hold the return data Local $ppvImageInfo = DllStructCreate("ptr") ; Buffer for XML Data Local $pcbImageInfo = DllStructCreate("int") ; Size of buffer in bytes Local $aResult = DllCall($ghwimgapi, "bool", "WIMGetImageInformation", _ "handle", $hImage, _ "ptr", DllStructGetPtr($ppvImageInfo), _ "ptr", DllStructGetPtr($pcbImageInfo)) If @error Then Return SetError(@error, @extended, 0) ; create a struct so we have access to the buffer where the XML data is stored Local $xml = DllStructCreate("wchar [" & DllStructGetData($pcbImageInfo, 1) & "]", DllStructGetData($ppvImageInfo, 1)) $aReturn[0] = $aResult[0] $aReturn[1] = DllStructGetData($xml, 1) ; <-- ***CRASH OCCURES HERE*** Return SetError(@error, _WinAPI_GetLastError(), $aReturn) EndFunc ;==>_WIM_GetImageInformationaccording to the return codes the structs get created correctly and the size of $xml is always correct, yet quite regularly reading data from $xml fails miserably.this doesn't happen every time the command is run but you can always reproduce by running the script several times in a row. the frequency seems random.can anyone give me some insite as to what may be going wrong here?some code to get everything up and running for anyone wanting to take a crack at this.make sure to download the UDF from the above link.thanks.Homes32Steps to ReproduceIf required change the path to the WIM file. In my tests the crashes were not specific to any particular WIM file.Run the following code several times in a row using F5 from SCITE or compile the code and use a cmd/bat to run several times in a row.It doesn't matter if you compile or use x68 vs x64, autoit will always have a hard crash at a seemingly random interval.Test code:expandcollapse popup#include <Wimgapi.au3> ; functions for WIM Global $swimfile, $hWim, $hImage, $filepath, $rTime, $pCallBack Global $gsWimDLL = @SystemDir & "\wimgapi.dll" ; path to wimgapi.dll $ProgramName = "WIM Demo" ; Fire up wimgapi.dll $aResult = _WIM_Startup() If @error = 2 Then MsgBox(16, $ProgramName, "Error loading library: " & "(" & $aResult & "," & @error & ", " & $gsWimDLL & ")" & @CRLF & @CRLF & "The file could not be found.") Exit (2) ElseIf @error = 1 Then MsgBox(16, $ProgramName, "Error loading library: " & "(" & $aResult & "," & @error & ", " & $gsWimDLL & ")" & @CRLF & @CRLF & "Wrong DLL. Make sure you are using the right arch (x86/x64)") Exit (254) EndIf GetInfo("C:\Images\Win7_32_EN_DVD\SOURCES\BOOT.WIM") ; Change this path to your WIM file ; GetInfo ;----------------------------- Func GetInfo($sWimFile) ; load .wim file with read access $hWim = _WIM_CreateFile($sWimFile, $WIM_GENERIC_READ, $WIM_OPEN_EXISTING, 0, 0, 0) If $hWim = 0 Then MsgBox(48, $ProgramName, "Error: Failed to load image. (" & $hWim & "," & @error & "," & @extended & ")") Cleanup() Exit (252) EndIf ; set our temp path $aResult = _WIM_SetTemporaryPath($hWim, @TempDir) ; read wim attributes $aWimAttribs = _WIM_GetImageAttributes($hWim) ; read info from the image $aXML = _WIM_GetImageInformation($hWim) ; Cleanup any open handles Cleanup() ; make our output pretty Switch $aWimAttribs[4] Case $WIM_COMPRESS_NONE $aWimAttribs[4] = "NONE" Case $WIM_COMPRESS_XPRESS $aWimAttribs[4] = "XPRESS" Case $WIM_COMPRESS_LZX $aWimAttribs[4] = "LZX" EndSwitch Local $outFile = @ScriptDir & "\wiminfo.txt" If FileExists($outFile) Then FileDelete($outFile) FileWrite($outFile, @CRLF & $ProgramName & @CRLF & @CRLF & @CRLF & @CRLF & _ "WIM Information:" & @CRLF & _ "----------------" & @CRLF & _ "Wim Path: : " & $aWimAttribs[1] & @CRLF & _ "GUID : " & $aWimAttribs[2] & @CRLF & _ "Image Count: " & $aWimAttribs[3] & @CRLF & _ "Compression: " & $aWimAttribs[4] & @CRLF & _ "Part Number: " & $aWimAttribs[5] & "/" & $aWimAttribs[6] & @CRLF & _ "Boot Index : " & $aWimAttribs[7] & @CRLF & _ "Attributes : " & $aWimAttribs[8] & @CRLF & @CRLF & @CRLF & _ "Available Image Choices:" & @CRLF & _ "------------------------" & @CRLF & _ $aXML[1]) EndFunc ;==>GetInfo Func Cleanup() ; Cleanup any open handles If $hImage Then _WIM_CloseHandle($hImage) If $hWim Then _WIM_CloseHandle($hWim) If $pCallBack Then ; Cleanup our callbacks $aResult = _WIM_UnregisterMessageCallback(0, DllCallbackGetPtr($pCallBack)) DllCallbackFree($pCallBack) EndIf _WIM_Shutdown() ; shutdown wimgapi.dll EndFunc ;==>Cleanup Edited April 27, 2011 by Homes32
Homes32 Posted April 27, 2011 Author Posted April 27, 2011 * updated above post to hopefully provide more information for anybody willing to help figure this out. *
JFX Posted July 11, 2011 Posted July 11, 2011 Thanks a lot for this UDF.can anyone give me some insite as to what may be going wrong here?I second this question, could anyone help here?Or more general question: Why could a DllStructGetData crash on a successfully created DllStruct?
JFX Posted July 11, 2011 Posted July 11, 2011 hmm, it seems works that way Func _WIM_GetImageInformation($hImage) Local $aReturn[2] ; array to hold the return data Local $ppvImageInfo = DllStructCreate("ptr") ; Buffer for XML Data Local $pcbImageInfo = DllStructCreate("int") ; Size of buffer in bytes Local $aResult = DllCall($ghwimgapi, "bool", "WIMGetImageInformation", _ "handle", $hImage, _ "ptr", DllStructGetPtr($ppvImageInfo), _ "ptr", DllStructGetPtr($pcbImageInfo)) If @error Then Return SetError(@error, @extended, 0) ; create a struct so we have access to the buffer where the XML data is stored Local $xml = DllStructCreate("byte [" & DllStructGetData($pcbImageInfo, 1) & "]", DllStructGetData($ppvImageInfo, 1)) $aReturn[0] = $aResult[0] $aReturn[1] = BinaryToString(DllStructGetData($xml, 1),2) Return SetError(@error, _WinAPI_GetLastError(), $aReturn) EndFunc The output file should be UTF 16, too. $hFile = FileOpen($outFile, 32 + 9) FileWrite($hFile, @CRLF & $ProgramName & @CRLF & @CRLF & @CRLF & @CRLF & _ "WIM Information:" & @CRLF & _ "----------------" & @CRLF & _ "Wim Path: : " & $aWimAttribs[1] & @CRLF & _ "GUID : " & $aWimAttribs[2] & @CRLF & _ "Image Count: " & $aWimAttribs[3] & @CRLF & _ "Compression: " & $aWimAttribs[4] & @CRLF & _ "Part Number: " & $aWimAttribs[5] & "/" & $aWimAttribs[6] & @CRLF & _ "Boot Index : " & $aWimAttribs[7] & @CRLF & _ "Attributes : " & $aWimAttribs[8] & @CRLF & @CRLF & @CRLF & _ "Available Image Choices:" & @CRLF & _ "------------------------" & @CRLF & _ $aXML[1]) FileClose($hFile)
jaberwacky Posted July 11, 2011 Posted July 11, 2011 (edited) I have a theory and this might be a stretch becuase I don't know much about Dll calls and this image stuff but MSDN says to free it with LocalFree. So it's worth trying: Func _WIM_GetImageInformation($hImage) Local $aReturn[2] ; array to hold the return data Local $ppvImageInfo = DllStructCreate("ptr") ; Buffer for XML Data Local $pcbImageInfo = DllStructCreate("int") ; Size of buffer in bytes Local $aResult = DllCall($ghwimgapi, "bool", "WIMGetImageInformation", _ "handle", $hImage, _ "ptr", DllStructGetPtr($ppvImageInfo), _ "ptr", DllStructGetPtr($pcbImageInfo)) If @error Then Return SetError(@error, @extended, 0) ; create a struct so we have access to the buffer where the XML data is stored Local $xml = DllStructCreate("wchar [" & DllStructGetData($pcbImageInfo, 1) & "]", DllStructGetData($ppvImageInfo, 1)) $aReturn[0] = $aResult[0] $aReturn[1] = DllStructGetData($xml, 1) ; <-- ***CRASH OCCURES HERE*** local_free($xml) Return SetError(@error, _WinAPI_GetLastError(), $aReturn) EndFunc ;==>_WIM_GetImageInformation Func local_free(ByRef $hMem) DllCall("Kernel32.dll", "handle", "LocalFree", "handle", $hMem) EndFunc ;==>local_free Edited July 11, 2011 by LaCastiglione Helpful Posts and Websites: AutoIt3 Variables and Function Parameters MHz | AutoIt Wiki | Using the GUIToolTip UDF BrewManNH | Can't find what you're looking for on the Forum?
Catdaddy Posted July 13, 2011 Posted July 13, 2011 Homes32, Great UDF! I'm having trouble with the callback routine to get an accurate progress percentage. When I try and run your sample script I get a variable used before declared error for $Percent. I was hoping maybe you could shed some light on it. Thanks.
Homes32 Posted July 13, 2011 Author Posted July 13, 2011 (edited) I have a theory and this might be a stretch becuase I don't know much about Dll calls and this image stuff but MSDN says to free it with LocalFree. So it's worth trying: Func _WIM_GetImageInformation($hImage) Local $aReturn[2] ; array to hold the return data Local $ppvImageInfo = DllStructCreate("ptr") ; Buffer for XML Data Local $pcbImageInfo = DllStructCreate("int") ; Size of buffer in bytes Local $aResult = DllCall($ghwimgapi, "bool", "WIMGetImageInformation", _ "handle", $hImage, _ "ptr", DllStructGetPtr($ppvImageInfo), _ "ptr", DllStructGetPtr($pcbImageInfo)) If @error Then Return SetError(@error, @extended, 0) ; create a struct so we have access to the buffer where the XML data is stored Local $xml = DllStructCreate("wchar [" & DllStructGetData($pcbImageInfo, 1) & "]", DllStructGetData($ppvImageInfo, 1)) $aReturn[0] = $aResult[0] $aReturn[1] = DllStructGetData($xml, 1) ; <-- ***CRASH OCCURES HERE*** local_free($xml) Return SetError(@error, _WinAPI_GetLastError(), $aReturn) EndFunc ;==>_WIM_GetImageInformation Func local_free(ByRef $hMem) DllCall("Kernel32.dll", "handle", "LocalFree", "handle", $hMem) EndFunc ;==>local_free Hi LaCastiglione, thanks for replying. I tried something like this already. the Crash actually occurs During DllStructGetData($xml, 1) so local_free($xml) will never be called. Homes32, Great UDF! I'm having trouble with the callback routine to get an accurate progress percentage. When I try and run your sample script I get a variable used before declared error for $Percent. I was hoping maybe you could shed some light on it. Thanks. oops. my bad. just add $Percent as Global at the top. I also updated the sample code to fix this. thanks. Homes32 Edited July 13, 2011 by Homes32
IntGen Posted August 9, 2011 Posted August 9, 2011 Hi! I try to catch $WIM_MSG_PROGRESS from _WIM_ApplyImage. But I can't. Can you provide example func Apply($sWimFile, $iImageIndex, $Path) with working progress bar? Thank you!
Homes32 Posted August 9, 2011 Author Posted August 9, 2011 Hi!I try to catch $WIM_MSG_PROGRESS from _WIM_ApplyImage. But I can't. Can you provide example func Apply($sWimFile, $iImageIndex, $Path) with working progress bar?Thank you!sorry. but currently the limitations of Autoit's callback implementation prevent this from working correctly. I'm sure it also doesn't help that the apply functions of wimgapi.dll are multi-threaded.as far as I know nobody has every gotten the progress to work with /apply
Homes32 Posted December 7, 2011 Author Posted December 7, 2011 forgot to upload v3 with fixed _WIM_GetImageInformationthanks JFX for helping figure this out!
Wader Posted May 3, 2012 Posted May 3, 2012 Do you have an example of the _WIM_ApplyImage() function. The code documentation seems to be a copy of the capture function.
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