Jump to content



Photo

WIMGAPI UDF


  • Please log in to reply
24 replies to this topic

#1 Homes32

Homes32

    Wayfarer

  • Active Members
  • Pip
  • 51 posts

Posted 30 March 2011 - 03:32 PM

A UDF for manipulating Windows Image Files (.wim) without ImageX.exe

This 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.dll

Functions 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_UnregisterMessageCallback





have fun!
Homes32

Sample Usage
AutoIt         
#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   ;==>Cleanup


History
v1 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_GetImageInformation


Previous Downloads: 312

Attached Files


Edited by Homes32, 09 May 2012 - 07:16 PM.








#2 MrCreatoR

MrCreatoR

    Must AutoIt!

  • MVPs
  • 3,244 posts

Posted 30 March 2011 - 04:03 PM

Any description on what is the purpose of this UDF (for those ho didn't heard about the WIMGAPI)?
Using OS: Win 7 Professional, Using AutoIt Ver(s): 3.3.6.1 / 3.3.8.1

Posted Image AutoIt Russian CommunityPosted Image 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 ProgramPosted Image UDFs: 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 UDFPosted Image 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 DemoLike the examples/UDFs? Please rate the topic (up-right corner of the post header: Rating Posted Image)* === My topics === *

==========================================================Posted Image==========================================================

AutoIt is simple, subtle, elegant. © AutoIt Team


#3 Homes32

Homes32

    Wayfarer

  • Active Members
  • Pip
  • 51 posts

Posted 30 March 2011 - 04:25 PM

Any description on what is the purpose of this UDF (for those ho didn't heard about the WIMGAPI)?

added.

#4 MrCreatoR

MrCreatoR

    Must AutoIt!

  • MVPs
  • 3,244 posts

Posted 30 March 2011 - 04:31 PM

added.


Thanks.
Using OS: Win 7 Professional, Using AutoIt Ver(s): 3.3.6.1 / 3.3.8.1

Posted Image AutoIt Russian CommunityPosted Image 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 ProgramPosted Image UDFs: 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 UDFPosted Image 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 DemoLike the examples/UDFs? Please rate the topic (up-right corner of the post header: Rating Posted Image)* === My topics === *

==========================================================Posted Image==========================================================

AutoIt is simple, subtle, elegant. © AutoIt Team


#5 spudw2k

spudw2k

    i dunno what i'm doing

  • Active Members
  • PipPipPipPipPipPip
  • 1,154 posts

Posted 30 March 2011 - 09:44 PM

I assume this is Vista and later as I cannot seem to find those DLLs on XP or 2k3?

 

Things I've Made: AUHistory â—Š Deck of Cards â—Š HideIt â—Š ICUâ—Š IconFreezerâ—Š IpodEjector â—Š LinkDownloader â—Š MD5 Folder Enumerator â—Š PingTool â—Š QuickNIC â—Š ReadOCR â—Š RemoteIT â—Š SchTasksGui â—Š SpyCam

 

Misc Code Snippets: ADODB Example â—Š Detect SafeMode â—Š Local Admins â—Š MakeChoice â—Š Recursive File List â—Š Remove Sizebox Style â—Š Retrieve PNPDeviceID â—Š Retreive SysListView32 Contents â—Š Set IE Homepage â—Š System UpTime â—Š Tickle Expired Password â—Š Transpose Array

 

Projects: Scan Engine Builder â—Š SpeeDBurner

 

Cool Stuff: AutoItObject UDF â—Š Extract Icon From Proc â—Š GuiCtrlFontRotate â—Š Hex Edit Funcs â—Š Run binary â—Š _Service_UDF

 


#6 Homes32

Homes32

    Wayfarer

  • Active Members
  • Pip
  • 51 posts

Posted 31 March 2011 - 12:14 AM

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.

#7 JohnOne

JohnOne

    John

  • Active Members
  • PipPipPipPipPipPip
  • 8,954 posts

Posted 31 March 2011 - 09:13 AM

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

#8 Catdaddy

Catdaddy

    Seeker

  • Active Members
  • 33 posts

Posted 31 March 2011 - 03:53 PM

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.

#9 Homes32

Homes32

    Wayfarer

  • Active Members
  • Pip
  • 51 posts

Posted 05 April 2011 - 12:45 AM

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.

#10 Homes32

Homes32

    Wayfarer

  • Active Members
  • Pip
  • 51 posts

Posted 25 April 2011 - 03:03 PM

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: 0xc0000005
which is a Access Violation error.

tracing the _WIM_GetImageInformation func it always crashes at this line
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***     Return SetError(@error, _WinAPI_GetLastError(), $aReturn) EndFunc   ;==>_WIM_GetImageInformation


according 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.
Homes32

Steps to Reproduce
If 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:
AutoIt         
#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 by Homes32, 27 April 2011 - 01:38 PM.


#11 Homes32

Homes32

    Wayfarer

  • Active Members
  • Pip
  • 51 posts

Posted 27 April 2011 - 01:39 PM

* updated above post to hopefully provide more information for anybody willing to help figure this out. *

#12 JFX

JFX

    Polymath

  • Active Members
  • PipPipPipPip
  • 207 posts

Posted 11 July 2011 - 09:35 AM

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?

#13 JFX

JFX

    Polymath

  • Active Members
  • PipPipPipPip
  • 207 posts

Posted 11 July 2011 - 11:49 AM

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)


#14 jaberwocky6669

jaberwocky6669

    Dull light.

  • Active Members
  • PipPipPipPipPipPip
  • 2,118 posts

Posted 11 July 2011 - 11:59 AM

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:

AutoIt         
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 by LaCastiglione, 11 July 2011 - 11:59 AM.


#15 Catdaddy

Catdaddy

    Seeker

  • Active Members
  • 33 posts

Posted 13 July 2011 - 02:19 AM

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.

#16 Homes32

Homes32

    Wayfarer

  • Active Members
  • Pip
  • 51 posts

Posted 13 July 2011 - 11:45 PM

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:

AutoIt         
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 by Homes32, 13 July 2011 - 11:46 PM.


#17 IntGen

IntGen

    Seeker

  • New Members
  • 1 posts

Posted 09 August 2011 - 11:18 AM

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!

#18 Homes32

Homes32

    Wayfarer

  • Active Members
  • Pip
  • 51 posts

Posted 09 August 2011 - 02:32 PM

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

http://www.autoitscript.com/forum/topic/126637-dllcallbacks-and-gui-freeze/page__p__878905#entry878905
http://www.autoitscript.com/forum/topic/117172-getting-callbacks-from-gximage-comdll-or-wimgapidll/
http://www.autoitscript.com/forum/topic/75106-progress-bar-when-applying-wim-image-file/page__p__547249__hl__wimgapi+udf__fromsearch__1#entry547249
http://www.autoitscript.com/forum/topic/75106-progress-bar-when-applying-wim-image-file/page__p__547249__hl__wimgapi+udf__fromsearch__1#entry547249

#19 Homes32

Homes32

    Wayfarer

  • Active Members
  • Pip
  • 51 posts

Posted 07 December 2011 - 08:39 PM

forgot to upload v3 with fixed _WIM_GetImageInformation
thanks JFX for helping figure this out! :D

#20 Wader

Wader

    Seeker

  • Active Members
  • 18 posts

Posted 03 May 2012 - 04:57 PM

Do you have an example of the _WIM_ApplyImage() function. The code documentation seems to be a copy of the capture function.




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users