Repository navigation
Expand file tree
/
Copy pathDiskUsage.cpp
More file actions
120 lines (94 loc) · 3.25 KB
/
Copy pathDiskUsage.cpp
File metadata and controls
120 lines (94 loc) · 3.25 KB
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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#include "DiskUsage.h"
// Fallbacks for older Windows SDKs that might be used on CI runners
#ifndef FILE_ATTRIBUTE_RECALL_ON_OPEN
#define FILE_ATTRIBUTE_RECALL_ON_OPEN 0x00040000
#endif
#ifndef FILE_ATTRIBUTE_RECALL_ON_DATA_ACCESS
#define FILE_ATTRIBUTE_RECALL_ON_DATA_ACCESS 0x00400000
#endif
#ifndef FILE_ATTRIBUTE_UNPINNED
#define FILE_ATTRIBUTE_UNPINNED 0x00100000
#endif
SM_UINT64 SM_MakeFileSize(DWORD low, DWORD high)
{
return (SM_UINT64)low + ((SM_UINT64)high << 32);
}
SM_UINT64 SM_GetLogicalFileSize(const SM_FILE_SIZE_INFO *info)
{
return info->logical_size;
}
static int SM_IsCloudPlaceholder(DWORD attributes)
{
DWORD flags =
FILE_ATTRIBUTE_OFFLINE |
FILE_ATTRIBUTE_RECALL_ON_OPEN |
FILE_ATTRIBUTE_RECALL_ON_DATA_ACCESS |
FILE_ATTRIBUTE_UNPINNED;
return (attributes & flags) != 0;
}
int SM_ShouldLoadAllocatedSize(DWORD attributes)
{
DWORD flags =
FILE_ATTRIBUTE_COMPRESSED |
FILE_ATTRIBUTE_REPARSE_POINT |
FILE_ATTRIBUTE_SPARSE_FILE;
return !SM_IsCloudPlaceholder(attributes) && (attributes & flags) != 0;
}
static SM_UINT64 SM_LegacyClusterSize(SM_UINT64 logical_size, SM_UINT64 cluster_mask, int aligned)
{
SM_UINT64 cluster_size = cluster_mask + 1;
if (logical_size == 0 || cluster_size == 0)
return logical_size;
if (logical_size > ((SM_UINT64)-1) - cluster_mask)
return logical_size;
if (aligned)
return (logical_size + cluster_mask) & ~cluster_mask;
return ((logical_size + cluster_mask) / cluster_size) * cluster_size;
}
SM_UINT64 SM_ChooseDisplayedFileSize(const SM_FILE_SIZE_INFO *info, SM_UINT64 cluster_mask, int aligned)
{
if (SM_IsCloudPlaceholder(info->attributes))
return 0;
if (info->has_allocated_size && SM_ShouldLoadAllocatedSize(info->attributes))
return info->allocated_size;
return SM_LegacyClusterSize(info->logical_size, cluster_mask, aligned);
}
typedef DWORD (WINAPI *SM_GetCompressedFileSizeWFunc)(LPCWSTR filename, LPDWORD high_size);
static SM_GetCompressedFileSizeWFunc SM_GetCompressedFileSizeWProc(void)
{
static const SM_GetCompressedFileSizeWFunc get_compressed_size = []() {
HMODULE kernel = GetModuleHandleW(L"KERNEL32.DLL");
return kernel == NULL ? nullptr
: reinterpret_cast<SM_GetCompressedFileSizeWFunc>(GetProcAddress(kernel, "GetCompressedFileSizeW"));
}();
return get_compressed_size;
}
int SM_LoadFileSizeInfoW(const wchar_t *path, const WIN32_FIND_DATAW *finddata, SM_FILE_SIZE_INFO *info)
{
DWORD high_size = 0;
DWORD low_size;
SM_GetCompressedFileSizeWFunc get_compressed_size;
if (path == NULL || finddata == NULL || info == NULL)
return 0;
info->logical_size = SM_MakeFileSize(finddata->nFileSizeLow, finddata->nFileSizeHigh);
info->allocated_size = 0;
info->attributes = finddata->dwFileAttributes;
info->has_allocated_size = 0;
if (SM_IsCloudPlaceholder(info->attributes)) {
info->allocated_size = 0;
info->has_allocated_size = 1;
return 1;
}
if (!SM_ShouldLoadAllocatedSize(info->attributes))
return 1;
get_compressed_size = SM_GetCompressedFileSizeWProc();
if (get_compressed_size == NULL)
return 1;
SetLastError(ERROR_SUCCESS);
low_size = get_compressed_size(path, &high_size);
if (low_size != 0xFFFFFFFFUL || GetLastError() == ERROR_SUCCESS) {
info->allocated_size = SM_MakeFileSize(low_size, high_size);
info->has_allocated_size = 1;
}
return 1;
}