Apply an Image from a .wim File
The following code example demonstrates how to apply an image from a .wim file, by using the WIMApplyImage function.
Example
#include <stdio.h>
#include <windows.h>
#include <wimgapi.h>
//
// Callback function:
//
DWORD
WINAPI
SampleApplyCallback(
DWORD dwMsgId, // Message ID
WPARAM wParam, // Usually a file name
LPARAM lParam, // Usually an error code
PVOID pvIgnored // Used to maintain caller context. Not used in this code sample.
)
{
PBOOL pbCancel = NULL;
switch (dwMsgId)
{
case WIM_MSG_PROGRESS:
// Prints out the current progress percentage.
//
wprintf(L"%d %%\n", (DWORD)wParam);
break;
case WIM_MSG_PROCESS:
// This message is sent for each file. It reports whether the calling client
// is trying to apply the file.
//
// Prints out the file name that is being processed:
//
wprintf(L"FilePath: %s\n", (PWSTR)wParam);
// To cancel processing on this file, use:
//
// pbCancel = (PBOOL)lParam;
// *pbCancel = TRUE;
break;
case WIM_MSG_ERROR:
// This message is sent when a failure error case is reported.
//
wprintf(L"ERROR: %s [err = %d]\n", (PWSTR)wParam, (DWORD)lParam);
break;
case WIM_MSG_RETRY:
// This message is sent when the file is being reapplied because of a
// network timeout. Retry is attempted up to five times.
//
wprintf(L"RETRY: %s [err = %d]\n", (PWSTR)wParam, (DWORD)lParam);
break;
case WIM_MSG_INFO:
// This message is sent when an informational message is available.
//
wprintf(L"INFO: %s [err = %d]\n", (PWSTR)wParam, (DWORD)lParam);
break;
case WIM_MSG_WARNING:
// This message is sent when a warning message is available.
//
wprintf(L"WARNING: %s [err = %d]\n", (PWSTR)wParam, (DWORD)lParam);
break;
}
//
// To abort image processing, return WIM_MSG_ABORT_IMAGE. Not all message types
// check for this status. When you decide to cancel an image, it may take repeated
// returns of this status before WIMGAPI can perform the cancelation.
//
return WIM_MSG_SUCCESS;
}
//
// Main Function:
//
int __cdecl
wmain(DWORD argc, PWSTR argv[])
{
BOOL bRet = TRUE;
HANDLE hWim = NULL,
hImage = NULL;
DWORD dwCreateFlags = 0,
dwCreateResult = 0,
dwImageIndex = 0,
dwError = 0;
PWSTR pszWimFile = L"C:\\capture.wim"; // Source .wim file
PWSTR pszTmpDir = L"C:\\tmp"; // Temporary directory
PWSTR pszApplyDir = L"C:\\restore"; // The directory or drive to which the image is applied
BOOL bListOnly = FALSE; // List the directories and files in the image.
WIM_INFO WimInfo = {0};
// An image index number is required to apply the image or to display the image info.
//
if (argc < 2 ||
argc > 3 ||
!(dwImageIndex = _wtoi(argv[1])))
{
wprintf(L"need image Index (1-based)\n");
dwError = ERROR_INVALID_PARAMETER;
bRet = FALSE;
}
// Display the list of directories and files in the image instead of applying the image.
//
if (bRet &&
argc == 3)
{
if (*argv[2] != L'd')
{
wprintf(L"need 'd' for directory/file listing\n");
dwError = ERROR_INVALID_PARAMETER;
bRet = FALSE;
}
bListOnly = TRUE;
}
// Register the callback function.
//
if (bRet &&
WIMRegisterMessageCallback(NULL,
(FARPROC)SampleApplyCallback,
NULL) == INVALID_CALLBACK_VALUE)
{
bRet = FALSE;
dwError = GetLastError();
wprintf(L"Cannot set callback\n");
}
// Open the .wim file.
//
if (bRet)
{
// If the image was captured with WIM_FLAG_VERIFY, you can use whole-file verification.
// The verification will add time to the operation, but can be used to catch .wim file corruption.
// To enable whole-file verification, use:
//
// dwCreateFlags |= WIM_FLAG_VERIFY;
hWim = WIMCreateFile(pszWimFile, // Existing .wim file to append the image to
WIM_GENERIC_READ, // Access mode
WIM_OPEN_EXISTING, // Open disposition
dwCreateFlags,
0, // Compression type is ignored for WIM_OPEN_EXISTING.
&dwCreateResult);
if (!hWim)
{
dwError = GetLastError();
bRet = FALSE;
wprintf(L"Cannot open .wim file\n");
}
}
//
// Note: To attach split .wim files (SWM) to this session, use:
// WIMSetReferenceFile(hWim, pszFileName, dwFlags)
//
if (bRet)
{
bRet = WIMGetAttributes(hWim, &WimInfo, sizeof(WimInfo));
if (!bRet)
{
dwError = GetLastError();
wprintf(L"WIMGetAttributes failed\n");
}
}
if (bRet)
{
if (WimInfo.ImageCount < dwImageIndex)
{
dwError = ERROR_INVALID_PARAMETER;
bRet = FALSE;
wprintf(L"There is no index %d in the WIM file\n", dwImageIndex);
}
}
// Set the temporary working directory.
//
if (bRet)
{
bRet = WIMSetTemporaryPath(hWim, pszTmpDir);
if (!bRet)
{
dwError = GetLastError();
wprintf(L"cannot set temp path to work in\n");
}
}
// Retrieve the image handle for the image at the given index.
//
if (bRet)
{
hImage = WIMLoadImage(hWim, dwImageIndex);
if (!hImage)
{
dwError = GetLastError();
bRet = FALSE;
wprintf(L"Cannot load image %d from src WIM file\n", dwImageIndex);
}
}
// Finally, apply the image.
//
if (bRet)
{
DWORD dwApplyFlags = 0;
if (bListOnly)
{
dwApplyFlags |= WIM_FLAG_NO_APPLY;
}
// Optionally, you can enable per-file verification. Per-file verification will perform redundant
// hash checks to detect .wim file corruption. The check will add time to the apply operation.
// To enable per-file verification, use:
//
// dwApplyFlags |= WIM_FLAG_VERIFY;
bRet = WIMApplyImage(hImage, pszApplyDir, dwApplyFlags);
if (!bRet)
{
dwError = GetLastError()
wprintf(L"Applying image failed\n");
}
}
if (hImage) WIMCloseHandle(hImage);
if (hWim) WIMCloseHandle(hWim);
WIMUnregisterMessageCallback(NULL, (FARPROC)SampleApplyCallback);
wprintf(L"Returning status: 0x%x\n", dwError);
return dwError;
}