Split a .wim File into Multiple Parts
The following code example demonstrates how to split an image into multiple parts, by using the WIMSplitFile function.
Example
#include <stdio.h>
#include <windows.h>
#include <wimgapi.h>
#include <strsafe.h>
//
// Callback function:
//
DWORD
WINAPI
SampleSplitCallback(
DWORD dwMsgId, // Message ID
WPARAM wParam, // Usually a file name
LPARAM lParam, // Usually an error codeb
PVOID pvUnused
)
{
PLARGE_INTEGER pliChunkSize = NULL;
PWSTR *ppszFileName = NULL;
switch (dwMsgId)
{
case WIM_MSG_SPLIT:
// This message is sent when each split .wim file is successful.
// You can change a split .wim file name or size by using this message.
//
ppszFileName = (PWSTR*)wParam;
pliChunkSize = (PLARGE_INTEGER)lParam;
wprintf(L"Current chunk name: %s\n", *ppszFileName);
wprintf(L"Current chunk size: %I64d\n", pliChunkSize->QuadPart);
// Example that shows changing the chunk size to 5MB:
// pliChunkSize->QuadPart = 5 * 1024 * 1024;
// Example that shows changing the filename:
#if 0 // To use this code in the example, remove the #if block
{
static WCHAR szBuffer[MAX_PATH] = {0};
static INT iCurrentPart = 0;
StringCbPrintfW(szBuffer, sizeof(szBuffer), L"file%x.swm", iCurrentPart++);
*ppszFileName = szBuffer;
}
#endif
break;
}
return WIM_MSG_SUCCESS;
}
//
// Main function:
//
int __cdecl
wmain(DWORD argc, PWSTR argv[])
{
BOOL bRet = TRUE;
HANDLE hWim = NULL;
DWORD dwCreateFlags = 0;
DWORD dwCreationResult = 0;
LARGE_INTEGER liChunkSize = {0};
DWORD dwError = 0;
PWSTR pszSourceFile = L"C:\\capture.wim"; // Source .wim file
PWSTR pszTargetFile = L"C:\\sample_split.swm"; // Destination split .wim file
PWSTR pszTmpDir = L"C:\\tmp"; // Temporary directory: OPTIONAL
WIM_INFO WimInfo = {0};
// Specify split chunk size in bytes.
//
if ((argc != 2) ||
!(liChunkSize.QuadPart = _wtol(argv[1])))
{
wprintf(L"need split chunk size in bytes\n");
dwError = ERROR_INVALID_PARAMETER;
bRet = FALSE;
}
// Register the Callback function.
//
if (bRet &&
WIMRegisterMessageCallback(NULL,
(FARPROC)SampleSplitCallback,
NULL) == INVALID_CALLBACK_VALUE)
{
dwError = GetLastError();
bRet = FALSE;
wprintf(L"Cannot set callback\n");
}
// 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;
// Open the source .wim file.
//
if (bRet)
{
hWim = WIMCreateFile(pszSourceFile,
WIM_GENERIC_READ,
WIM_OPEN_EXISTING,
dwCreateFlags,
0,
&dwCreationResult);
if (!hWim)
{
dwError = GetLastError();
bRet = FALSE;
wprintf(L"Cannot open src WIM file\n");
}
}
if (bRet)
{
bRet = WIMGetAttributes(hWim, &WimInfo, sizeof(WimInfo));
if (!bRet)
{
dwError = GetLastError();
wprintf(L"WIMGetAttributes failed\n");
}
}
// Verify if the .wim file has already been split.
//
if (bRet && WimInfo.TotalParts != 1)
{
dwError = ERROR_INVALID_PARAMETER;
bRet = FALSE;
wprintf(L"The .wim file has already been splitted. Cannot split it again.");
}
// Split the .wim file.
//
if (bRet)
{
bRet = WIMSplitFile(hWim, pszTargetFile, &liChunkSize, 0);
if (!bRet)
{
dwError = GetLastError();
wprintf(L"Split failed\n");
if (dwError == ERROR_MORE_DATA)
{
wprintf(L"Need bigger chunk size to split\n");
}
}
}
// When you are finished, close the handle that you created in the previous steps.
//
if (hWim)
{
WIMCloseHandle(hWim);
}
WIMUnregisterMessageCallback(NULL, (FARPROC)SampleSplitCallback);
wprintf(L"Returning status: 0x%x\n", dwError);
return dwError;
}