-
Notifications
You must be signed in to change notification settings - Fork 151
/
WofHelper.cpp
83 lines (61 loc) · 2.1 KB
/
WofHelper.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#pragma once
#include "WofHelper.h"
#include "handle.h"
#include "FileHelper.h"
#pragma warning(push)
#pragma warning(disable: 28251)
BOOL IsWofCompress(LPCWSTR FilePath)
{
CHFile hFile = CreateFile(FilePath, /*0x181*/GENERIC_READ, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0x0A000000, 0);
if (hFile.IsInvalid())
return FALSE;
ExternalBacking Buffer = {};
DWORD BytesReturned = 0;
return DeviceIoControl(hFile, FSCTL_GET_EXTERNAL_BACKING/*0x90310*/, NULL, 0, &Buffer, sizeof(ExternalBacking), &BytesReturned, NULL);
}
LSTATUS UnWofCompressFile(LPCWSTR FilePath)
{
CHFile hFile = CreateFile(FilePath, 0x181, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0x0A000000, 0);
if (hFile.IsInvalid())
return GetLastError_s();
DWORD BytesReturned = 0;
if (!DeviceIoControl(hFile, FSCTL_DELETE_EXTERNAL_BACKING/*0x90314*/, NULL, 0, NULL, 0, &BytesReturned, NULL))
return GetLastError_s();
return ERROR_SUCCESS;
}
LSTATUS WofCompressFile(LPCWSTR FilePath, DWORD CompressType)
{
if (IsWofCompress(FilePath))
{
return ERROR_SUCCESS;
}
CHFile hFile = CreateFile(FilePath, 0x81, FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, 0x0A000000, 0);
if (hFile.IsInvalid())
return GetLastError_s();
ExternalBacking Temp = { WOF_EXTERNAL_INFO{ 1, 2 }, WIM_PROVIDER_EXTERNAL_INFO{ 1, CompressType } };
DWORD Ret = 0;
return DeviceIoControl(hFile, FSCTL_SET_EXTERNAL_BACKING, &Temp, 0x14, NULL, 0, &Ret, NULL) ? ERROR_SUCCESS : GetLastError_s();
}
LSTATUS UnWofCompressRoot(CString RootPath)
{
WIN32_FIND_DATA FindData;
CHFileFind hFileFind = FindFirstFile(RootPath, &FindData);
if (hFileFind.IsInvalid())
return GetLastError_s();
RootPath.ReleaseBufferSetLength(RootPath.ReverseFind(L'\\') + 1);
do
{
if (FindData.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)
{
if (_IsDots(FindData.cFileName))
continue;
UnWofCompressRoot(RootPath + FindData.cFileName + L"\\*");
}
else
{
UnWofCompressFile(RootPath + FindData.cFileName);
}
} while (FindNextFile(hFileFind, &FindData));
return ERROR_SUCCESS;
}
#pragma warning(pop)