Capture a Directory into a New .wim File
The following code example demonstrates how to capture a directory into a new .wim file, by using the WIMCaptureImage function.
Example
#include <stdio.h>
#include <windows.h>
#include <wimgapi.h>
//
// Callback function:
//
DWORD
WINAPI
SampleCaptureCallback(
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 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 capture the file.
//
// Prints out the file name 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 an error 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 dwFlags = 0,
dwDisposition = 0,
dwDesiredAccess = 0,
dwCreateFlags = 0,
dwCaptureFlags = 0,
dwCompressionType = 0,
dwCreationResult = 0,
dwError = 0;
PWSTR pszWimFile = L"C:\\sample_image.wim"; // Destination .wim file that you want to capture the image to
PWSTR pszTmpDir = L"C:\\tmp"; // Temporary directory: OPTIONAL
PWSTR pszCaptureDir = L"C:\\src"; // Capture directory or drive
// Inspect the caller's parameters.
//
if (argc < 1 || argc > 2)
{
dwError = ERROR_INVALID_PARAMETER;
bRet = FALSE;
}
if (bRet)
{
if (argc == 1)
{
// Use "capture" mode. Overwrite a pre-existing .wim file.
//
dwDisposition = WIM_CREATE_ALWAYS;
dwDesiredAccess = WIM_GENERIC_WRITE;
}
else if (*argv[1] == L'a')
{
// Use "append" mode. Add a new image index to a pre-existing
// .wim file if one is found.
//
dwDisposition = WIM_OPEN_EXISTING;
dwDesiredAccess = WIM_GENERIC_WRITE | WIM_GENERIC_READ;
}
else
{
wprintf(L"need 'a' to append\n");
dwError = ERROR_INVALID_PARAMETER;
bRet = FALSE;
}
}
// Register the Callback function.
//
if (bRet &&
WIMRegisterMessageCallback(NULL,
(FARPROC)SampleCaptureCallback,
NULL) == INVALID_CALLBACK_VALUE)
{
bRet = FALSE;
dwError = GetLastError();
wprintf(L"Cannot set callback\n");
}
// Open the .wim file
//
if (bRet)
{
// Use LZX compression ("/compress max"). Other possibilities include:
// WIM_COMPRESS_NONE - No compression
// WIM_COMPRESS_XPRESS - "Fast" compression
//
dwCompressionType = WIM_COMPRESS_LZX;
// Optionally, if the image was captured with WIM_FLAG_VERIFY,
// you can use whole-file verification. Whole-file
// verification performs extra hashing checks and generates extra hashes.
// It detects file corruption due to a bad disk or a
// faulty network connection, but it adds time to the operation due to
// extra I/O operations and extra hash checks.
// To enable whole-file verification, use:
//
// dwCreateFlags |= WIM_FLAG_VERIFY;
hWim = WIMCreateFile(pszWimFile,
dwDesiredAccess,
dwDisposition,
dwCreateFlags,
dwCompressionType,
&dwCreationResult);
if (!hWim)
{
bRet = FALSE;
dwError = GetLastError();
wprintf(L"Cannot open WIM file\n");
}
}
// WIMGAPI uses temporary files. You must specify where to store the files.
//
if (bRet)
{
bRet = WIMSetTemporyPath(hWim, pszTmpDir);
if (!bRet)
{
dwError = GetLastError();
wprintf(L"Cannot set temporary directory\n");
}
}
// 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 capture operation.
// To enable per-file verification, use:
//
// dwCaptureFlags |= WIM_FLAG_VERIFY;
// Finally, perform the capture operation.
//
if (bRet)
{
hImage = WIMCaptureImage(hWim, pszCaptureDir, dwCaptureFlags);
if (!hImage)
{
dwError = GetLastError();
wprintf(L"Cannot capture/append image\n");
}
}
// When you are finished, close the handles that you created in the previous steps.
// Note: you must close image handles before you close WIM handles.
//
if (hImage) WIMCloseHandle(hImage);
if (hWim) WIMCloseHandle(hWim);
WIMUnregisterMessageCallback(NULL, (FARPROC)SampleCaptureCallback);
wprintf(L"Returning status: 0x%x\n", dwError);
return dwError;
}