forked from seanofw/spacemonger1
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDiskUsage.cpp
More file actions
178 lines (139 loc) · 4.78 KB
/
Copy pathDiskUsage.cpp
File metadata and controls
178 lines (139 loc) · 4.78 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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
#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
typedef DWORD (WINAPI *SM_GetCompressedFileSizeFunc)(LPCSTR filename, LPDWORD high_size);
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);
}
static SM_GetCompressedFileSizeFunc SM_GetCompressedFileSizeProc(void)
{
static int initialized = 0;
static SM_GetCompressedFileSizeFunc get_compressed_size = NULL;
if (!initialized) {
HMODULE kernel = GetModuleHandle("KERNEL32.DLL");
if (kernel != NULL)
get_compressed_size = (SM_GetCompressedFileSizeFunc)GetProcAddress(kernel, "GetCompressedFileSizeA");
initialized = 1;
}
return get_compressed_size;
}
typedef DWORD (WINAPI *SM_GetCompressedFileSizeWFunc)(LPCWSTR filename, LPDWORD high_size);
static SM_GetCompressedFileSizeWFunc SM_GetCompressedFileSizeWProc(void)
{
static int initialized = 0;
static SM_GetCompressedFileSizeWFunc get_compressed_size = NULL;
if (!initialized) {
HMODULE kernel = GetModuleHandle("KERNEL32.DLL");
if (kernel != NULL)
get_compressed_size = (SM_GetCompressedFileSizeWFunc)GetProcAddress(kernel, "GetCompressedFileSizeW");
initialized = 1;
}
return get_compressed_size;
}
int SM_LoadFileSizeInfo(const char *path, const WIN32_FIND_DATA *finddata, SM_FILE_SIZE_INFO *info)
{
DWORD high_size = 0;
DWORD low_size;
SM_GetCompressedFileSizeFunc 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_GetCompressedFileSizeProc();
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;
}
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;
}