unit Unit25;<br><br>interface<br><br>uses<br> Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,<br> Dialogs, StdCtrls, ComCtrls;<br><br>type<br> TForm25 = class(TForm)<br> Memo1: TMemo;<br> Button1: TButton;<br> Button2: TButton;<br> ProgressBar1: TProgressBar;<br> procedure Button1Click(Sender: TObject);<br> procedure Button2Click(Sender: TObject);<br> private<br> { Private declarations }<br> protected<br> public<br> { Public declarations }<br> end;<br><br>var<br> Form25: TForm25;<br><br>implementation<br><br>{$R *.dfm}<br><br>uses<br> WImgApi;<br><br>//Callback function:<br>//<br>var<br> n : Integer;<br>function SampleCaptureCallback(<br> msgId : DWORD; // message ID<br> param1 : WParam; // usually file name<br> param2 : LParam; // usually error code<br> UserData : Pointer<br> ): DWORD; stdcall;<br>var<br> Msg : PWideChar;<br> FilePath : PWideChar;<br> Percent : DWORD;<br> ErrorCode : DWORD;<br> Msg_Back : PDWORD;<br> finddata : WIN32_FIND_DATA;<br> filecount : DWORD;<br>begin<br> //first parameter: full file path for if WIM_MSG_PROCESS, message string for others<br> Msg := PWideChar(param1);<br> filePath := PWideChar(param1);<br> percent := param1;<br><br> //second parameter: message back to caller if WIM_MSG_PROCESS, error code for others<br> errorCode := param2;<br> filecount := param2;<br> msg_back := PDWORD(param2);<br><br> OutputDebugString(PChar(Format('Msgid=%d, wParam=%d, lParam=%d',<br> [msgid-WIM_MSG, param1, param2])));<br> PostMessage(Form25.Handle, msgid, param1, param2);<br> Result := WIM_MSG_SUCCESS;<br>// Exit;<br> case msgId of<br> WIM_MSG_PROCESS:<br> begin<br> //This message is sent for each file, capturing to see if callee intends to<br> //capture the file or not.<br> //<br> //If you do not intend to capture this file, then assign FALSE in msg_back<br> //but still returns WIM_MSG_SUCCESS<br> //Default is TRUE.<br> //<br><br> //In this sample, simply print out file name being applied<br> //<br><br> Form25.Memo1.Lines.Add(Format('FilePath: %s', [filePath]));<br> end;<br><br> WIM_MSG_SETRANGE:<br> begin<br> Form25.Memo1.Lines.Add(Format('FileCount: %d', [filecount]));<br> end;<br><br> WIM_MSG_SETPOS:<br> begin<br> Form25.Memo1.Lines.Add(Format('CurrentFiles: %d', [filecount]));<br> end;<br><br> WIM_MSG_PROGRESS:<br> begin<br> Form25.ProgressBar1.Position := Percent;<br> Form25.Memo1.Lines.Add(Format('estimated time: %d', [filecount div 1000]));<br> end;<br><br> WIM_MSG_STEPIT:<br> begin<br> Form25.Memo1.Lines.Add(Format('n=%d',[n]));<br> inc(n);<br> end;<br><br> WIM_MSG_FILEINFO:<br> begin<br> Form25.Memo1.Lines.Add(Format('FilePath: %s', [filePath]));<br> end;<br><br> WIM_MSG_ERROR:<br> begin<br> //This message is sent upon failure error case<br> //<br> Form25.Memo1.Lines.Add(Format('ERROR: %s [err = %d]', [msg, errorCode]));<br> end;<br><br> WIM_MSG_RETRY:<br> begin<br> //This message is sent when file is being reapplied because of<br> //network timeout. Retry is done up to five times.<br> //<br> Form25.Memo1.Lines.Add(Format('RETRY: %s [err = %d]', [msg, errorCode]));<br> end;<br><br> WIM_MSG_INFO:<br> begin<br> //This message is sent when informational message is available<br> //<br> Form25.Memo1.Lines.Add(Format('INFO: %s [err = %d]', [msg, errorCode]));<br> end;<br><br> WIM_MSG_WARNING:<br> begin<br> //This message is sent when warning message is available<br> //<br> Form25.Memo1.Lines.Add(Format('WARNING: %s [err = %d]/n', [msg, errorCode]));<br> end;<br><br><br> WIM_MSG_COMPRESS:<br> begin<br> Form25.Memo1.Lines.Add(Format('WIM_MSG_COMPRESS',[]));<br> end;<br> WIM_MSG_CHK_PROCESS:<br> begin<br> Form25.Memo1.Lines.Add(Format('WIM_MSG_CHK_PROCESS',[]));<br> end;<br> WIM_MSG_SCANNING:<br> begin<br> Form25.Memo1.Lines.Add(Format('dirs: %d files: %d',[param1, param2]));<br> end;<br> WIM_MSG_ALIGNMENT:<br> begin<br> Form25.Memo1.Lines.Add(Format('FilePath: %s', [filePath]));<br> end;<br><br> else<br> Form25.Memo1.Lines.Add(Format('UnknowMsg %0.4X %d %d', [msgid, param1, param2]));<br><br><br> end;<br><br>end;<br><br>procedure SampleCaptureCleanup(hwim: THandle; himg: THandle; callback: Pointer);<br>var<br> err : DWORD;<br>begin<br> err := GetLastError();<br><br> //Do not overwrite the original error code<br> //<br> if (himg <> 0) and not WIMCloseHandle (himg) and // close Image file first<br> (err = ERROR_SUCCESS) then<br><br> err := GetLastError();<br><br> if (hwim <> 0) and<br> not WIMCloseHandle (hwim) and // close WIM file last<br> (err = ERROR_SUCCESS) then<br><br> err := GetLastError();<br><br><br> if (callback <>nil) and<br> not WIMUnregisterMessageCallback(0, callback ) and<br> (err = ERROR_SUCCESS) then<br><br> err := GetLastError();<br><br><br> SetLastError (err);<br>end;<br><br>type<br> TApplyThread = class(TThread)<br><br> protected<br> procedure Execute; override;<br> end;<br><br>procedure TApplyThread.Execute;<br>var<br> hWim : THandle;<br> hImg : THandle;<br> created : DWORD;<br> oFlag : DWORD;<br> oAccess: DWORD;<br><br> callback : Pointer;<br>hWimInfo: WIM_INFO;<br>imgIndex: DWORD;<br> wimFile : WideString; // target WIM file<br> tmpDir : WideString; // temporary directory: OPTIONAL<br> ApplayDir: WideString; // capture directory or drive<br><br>begin<br> FreeOnTerminate := True;<br> wimFile := 'C:/sample_image.wim';<br> tmpDir := 'C:/Temp';<br> ApplayDir:= 'C:/Src';<br><br> callback := @SampleCaptureCallback;<br> <br> //Set up access mode and open flag<br> //<br> oFlag := WIM_GENERIC_READ;<br> oAccess := WIM_OPEN_EXISTING;<br><br> //Register callback<br> //<br> if WIMRegisterMessageCallback(0,callback,nil)=INVALID_CALLBACK_VALUE then<br> begin<br> Form25.Memo1.Lines.Add('Cannot set callback');<br> Exit;<br> end;<br><br><br> //Call SampleCleanup() upon exit from here<br> //<br> hWim := WIMCreateFile ( PWideChar(wimFile), // existing WIM file to append to<br> WIM_GENERIC_READ, // access mode<br> WIM_OPEN_EXISTING, // open flag<br> WIM_FLAG_VERIFY, // recommended flag for file corruption check<br> 0,<br> @created );<br><br> if (hWim =0) then<br> begin<br> Form25.Memo1.Lines.Add('Cannot open WIM file');<br> SampleCaptureCleanup(hWim, hImg, callback);<br> exit;<br> end;<br><br> //set temporary directory to work in<br> //OPTIONAL, but recommended for large WIM file<br> //<br> //WIMSetTemporaryPath (hWim, tmpDir); // OK to fail.<br><br> //Now capture or append image<br> //<br> if (not WIMGetAttributes( hWim, @hWimInfo, sizeof(hWimInfo))) then<br> begin<br> Form25.Memo1.Lines.Add('WIMGetAttributes failed');<br><br> SampleCaptureCleanup(hWim, hImg, callback);<br> //SampleApplyCleanup(hWim, hImg, callback);<br> end;<br><br> imgIndex := 1;<br> if (hWimInfo.ImageCount < imgIndex) then<br> begin<br> Form25.Memo1.Lines.Add(Format('There is no index %d in the WIM file', [imgIndex]));<br><br> SampleCaptureCleanup(hWim, hImg, callback);<br>// SampleApplyCleanup(hWim, hImg, callback);<br> end;<br><br> //set temporary directory to work in<br> //REQUIRED for apply<br> //<br> if (not WIMSetTemporaryPath (hWim, PWideChar(tmpDir))) then<br> begin<br> Form25.Memo1.Lines.Add('cannot set temp path to work in');<br><br> SampleCaptureCleanup(hWim, hImg, callback);<br> // SampleApplyCleanup(hWim, hImg, callback);<br> end;<br><br> //Now apply the image<br> //<br> hImg := WIMLoadImage ( hWim, imgIndex );<br> if ( hImg = 0) then<br> begin<br> Form25.Memo1.Lines.Add(Format('Cannot load imagex %d from src WIM file', [imgIndex]));<br><br> SampleCaptureCleanup(hWim, hImg, callback);<br>// SampleApplyCleanup(hWim, hImg, callback);<br> end;<br> n := 0;<br>// if (not WIMExportImage ( hImg,<br>// hWim, // apply directory or drive<br>// WIM_EXPORT_ALLOW_DUPLICATES ))<br> if (not WIMApplyImage ( hImg,<br> PWideChar(ApplayDir), // apply directory or drive<br> WIM_FLAG_FILEINFO or WIM_FLAG_VERIFY))<br> then<br> begin <br> Form25.Memo1.Lines.Add('Applying image failed');<br> end;<br><br> //Now we are done<br> //<br> SampleCaptureCleanup (hWim, hImg, callback);<br><br> if (GetLastError() <> ERROR_SUCCESS) then<br> begin<br> Form25.Memo1.Lines.Add('Cannot Applay image');<br> end;<br>end;<br><br>procedure TForm25.Button1Click(Sender: TObject);<br>var<br> t : TApplyThread;<br>begin<br> t := TApplyThread.Create(False);<br>end;<br><br>procedure TForm25.Button2Click(Sender: TObject);<br>var<br> hWim : THandle;<br> hImg : THandle;<br> created : DWORD;<br> oFlag : DWORD;<br> oAccess: DWORD;<br><br> callback : Pointer;<br><br> wimFile : WideString; // target WIM file<br> captureDir: WideString; // capture directory or drive<br>begin<br> //generic capture/append call sequence<br> //<br> //w = WIMCreateFile()<br> //WIMSetTemporaryPath() - optional<br> //i = WIMCaptureImage()<br> //WIMCloseHandle(i)<br> //WIMCloseHandle(w)<br> //<br><br> wimFile := 'C:/sample_image.wim';<br> captureDir:= 'C:/Src';<br><br> callback := @SampleCaptureCallback;<br><br> //Set up access mode and open flag<br> //<br> oFlag := WIM_CREATE_ALWAYS;<br> oAccess := WIM_GENERIC_WRITE;<br><br> //Register callback<br> //<br> if WIMRegisterMessageCallback(0,callback,nil)=INVALID_CALLBACK_VALUE then<br> begin<br> Memo1.Lines.Add('Cannot set callback');<br> Exit;<br> end;<br><br><br> //Call SampleCleanup() upon exit from here<br> //<br> hWim := WIMCreateFile ( PWideChar(wimFile), // existing WIM file to append to<br> oAccess, // access mode<br> oFlag, // open flag<br> 0, // WIM_FLAG_VERIFY, // recommended flag for file corruption check<br> WIM_COMPRESS_XPRESS, // or WIM_COMPRESS_LZX or WIM_COMPRESS_NONE<br> @created );<br><br> if (hWim =0) then<br> begin<br> Memo1.Lines.Add('Cannot open WIM file');<br> SampleCaptureCleanup(hWim, hImg, callback);<br> exit;<br> end;<br><br> //set temporary directory to work in<br> //OPTIONAL, but recommended for large WIM file<br> //<br> //WIMSetTemporaryPath (hWim, tmpDir); // OK to fail.<br><br> //Now capture or append image<br> //<br> hImg := WIMCaptureImage ( hWim,<br> PWideChar(captureDir), // capture directory or drive<br> 0); // WIM_FLAG_VERIFY<br><br> //Now we are done<br> //<br> SampleCaptureCleanup (hWim, hImg, callback);<br><br> if (GetLastError() <> ERROR_SUCCESS) then<br> begin<br> Memo1.Lines.Add('Cannot capture image');<br> end;<br> end;<br><br>end.