1*f6dc9357SAndroid Build Coastguard Worker // Windows/FileSystem.cpp
2*f6dc9357SAndroid Build Coastguard Worker
3*f6dc9357SAndroid Build Coastguard Worker #include "StdAfx.h"
4*f6dc9357SAndroid Build Coastguard Worker
5*f6dc9357SAndroid Build Coastguard Worker #ifndef UNDER_CE
6*f6dc9357SAndroid Build Coastguard Worker
7*f6dc9357SAndroid Build Coastguard Worker #ifndef _UNICODE
8*f6dc9357SAndroid Build Coastguard Worker #include "../Common/StringConvert.h"
9*f6dc9357SAndroid Build Coastguard Worker #endif
10*f6dc9357SAndroid Build Coastguard Worker
11*f6dc9357SAndroid Build Coastguard Worker #include "FileSystem.h"
12*f6dc9357SAndroid Build Coastguard Worker #include "Defs.h"
13*f6dc9357SAndroid Build Coastguard Worker
14*f6dc9357SAndroid Build Coastguard Worker #ifndef _UNICODE
15*f6dc9357SAndroid Build Coastguard Worker extern bool g_IsNT;
16*f6dc9357SAndroid Build Coastguard Worker #endif
17*f6dc9357SAndroid Build Coastguard Worker
18*f6dc9357SAndroid Build Coastguard Worker namespace NWindows {
19*f6dc9357SAndroid Build Coastguard Worker namespace NFile {
20*f6dc9357SAndroid Build Coastguard Worker namespace NSystem {
21*f6dc9357SAndroid Build Coastguard Worker
22*f6dc9357SAndroid Build Coastguard Worker #ifdef _WIN32
23*f6dc9357SAndroid Build Coastguard Worker
MyGetVolumeInformation(CFSTR rootPath,UString & volumeName,LPDWORD volumeSerialNumber,LPDWORD maximumComponentLength,LPDWORD fileSystemFlags,UString & fileSystemName)24*f6dc9357SAndroid Build Coastguard Worker bool MyGetVolumeInformation(
25*f6dc9357SAndroid Build Coastguard Worker CFSTR rootPath,
26*f6dc9357SAndroid Build Coastguard Worker UString &volumeName,
27*f6dc9357SAndroid Build Coastguard Worker LPDWORD volumeSerialNumber,
28*f6dc9357SAndroid Build Coastguard Worker LPDWORD maximumComponentLength,
29*f6dc9357SAndroid Build Coastguard Worker LPDWORD fileSystemFlags,
30*f6dc9357SAndroid Build Coastguard Worker UString &fileSystemName)
31*f6dc9357SAndroid Build Coastguard Worker {
32*f6dc9357SAndroid Build Coastguard Worker BOOL res;
33*f6dc9357SAndroid Build Coastguard Worker #ifndef _UNICODE
34*f6dc9357SAndroid Build Coastguard Worker if (!g_IsNT)
35*f6dc9357SAndroid Build Coastguard Worker {
36*f6dc9357SAndroid Build Coastguard Worker TCHAR v[MAX_PATH + 2]; v[0] = 0;
37*f6dc9357SAndroid Build Coastguard Worker TCHAR f[MAX_PATH + 2]; f[0] = 0;
38*f6dc9357SAndroid Build Coastguard Worker res = GetVolumeInformation(fs2fas(rootPath),
39*f6dc9357SAndroid Build Coastguard Worker v, MAX_PATH,
40*f6dc9357SAndroid Build Coastguard Worker volumeSerialNumber, maximumComponentLength, fileSystemFlags,
41*f6dc9357SAndroid Build Coastguard Worker f, MAX_PATH);
42*f6dc9357SAndroid Build Coastguard Worker volumeName = MultiByteToUnicodeString(v);
43*f6dc9357SAndroid Build Coastguard Worker fileSystemName = MultiByteToUnicodeString(f);
44*f6dc9357SAndroid Build Coastguard Worker }
45*f6dc9357SAndroid Build Coastguard Worker else
46*f6dc9357SAndroid Build Coastguard Worker #endif
47*f6dc9357SAndroid Build Coastguard Worker {
48*f6dc9357SAndroid Build Coastguard Worker WCHAR v[MAX_PATH + 2]; v[0] = 0;
49*f6dc9357SAndroid Build Coastguard Worker WCHAR f[MAX_PATH + 2]; f[0] = 0;
50*f6dc9357SAndroid Build Coastguard Worker res = GetVolumeInformationW(fs2us(rootPath),
51*f6dc9357SAndroid Build Coastguard Worker v, MAX_PATH,
52*f6dc9357SAndroid Build Coastguard Worker volumeSerialNumber, maximumComponentLength, fileSystemFlags,
53*f6dc9357SAndroid Build Coastguard Worker f, MAX_PATH);
54*f6dc9357SAndroid Build Coastguard Worker volumeName = v;
55*f6dc9357SAndroid Build Coastguard Worker fileSystemName = f;
56*f6dc9357SAndroid Build Coastguard Worker }
57*f6dc9357SAndroid Build Coastguard Worker return BOOLToBool(res);
58*f6dc9357SAndroid Build Coastguard Worker }
59*f6dc9357SAndroid Build Coastguard Worker
MyGetDriveType(CFSTR pathName)60*f6dc9357SAndroid Build Coastguard Worker UINT MyGetDriveType(CFSTR pathName)
61*f6dc9357SAndroid Build Coastguard Worker {
62*f6dc9357SAndroid Build Coastguard Worker #ifndef _UNICODE
63*f6dc9357SAndroid Build Coastguard Worker if (!g_IsNT)
64*f6dc9357SAndroid Build Coastguard Worker {
65*f6dc9357SAndroid Build Coastguard Worker return GetDriveType(fs2fas(pathName));
66*f6dc9357SAndroid Build Coastguard Worker }
67*f6dc9357SAndroid Build Coastguard Worker else
68*f6dc9357SAndroid Build Coastguard Worker #endif
69*f6dc9357SAndroid Build Coastguard Worker {
70*f6dc9357SAndroid Build Coastguard Worker return GetDriveTypeW(fs2us(pathName));
71*f6dc9357SAndroid Build Coastguard Worker }
72*f6dc9357SAndroid Build Coastguard Worker }
73*f6dc9357SAndroid Build Coastguard Worker
74*f6dc9357SAndroid Build Coastguard Worker #if !defined(Z7_WIN32_WINNT_MIN) || Z7_WIN32_WINNT_MIN < 0x0400
75*f6dc9357SAndroid Build Coastguard Worker // GetDiskFreeSpaceEx requires Windows95-OSR2, NT4
76*f6dc9357SAndroid Build Coastguard Worker #define Z7_USE_DYN_GetDiskFreeSpaceEx
77*f6dc9357SAndroid Build Coastguard Worker #endif
78*f6dc9357SAndroid Build Coastguard Worker
79*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_USE_DYN_GetDiskFreeSpaceEx
80*f6dc9357SAndroid Build Coastguard Worker typedef BOOL (WINAPI * Func_GetDiskFreeSpaceExA)(
81*f6dc9357SAndroid Build Coastguard Worker LPCSTR lpDirectoryName, // directory name
82*f6dc9357SAndroid Build Coastguard Worker PULARGE_INTEGER lpFreeBytesAvailable, // bytes available to caller
83*f6dc9357SAndroid Build Coastguard Worker PULARGE_INTEGER lpTotalNumberOfBytes, // bytes on disk
84*f6dc9357SAndroid Build Coastguard Worker PULARGE_INTEGER lpTotalNumberOfFreeBytes // free bytes on disk
85*f6dc9357SAndroid Build Coastguard Worker );
86*f6dc9357SAndroid Build Coastguard Worker
87*f6dc9357SAndroid Build Coastguard Worker typedef BOOL (WINAPI * Func_GetDiskFreeSpaceExW)(
88*f6dc9357SAndroid Build Coastguard Worker LPCWSTR lpDirectoryName, // directory name
89*f6dc9357SAndroid Build Coastguard Worker PULARGE_INTEGER lpFreeBytesAvailable, // bytes available to caller
90*f6dc9357SAndroid Build Coastguard Worker PULARGE_INTEGER lpTotalNumberOfBytes, // bytes on disk
91*f6dc9357SAndroid Build Coastguard Worker PULARGE_INTEGER lpTotalNumberOfFreeBytes // free bytes on disk
92*f6dc9357SAndroid Build Coastguard Worker );
93*f6dc9357SAndroid Build Coastguard Worker #endif
94*f6dc9357SAndroid Build Coastguard Worker
MyGetDiskFreeSpace(CFSTR rootPath,UInt64 & clusterSize,UInt64 & totalSize,UInt64 & freeSize)95*f6dc9357SAndroid Build Coastguard Worker bool MyGetDiskFreeSpace(CFSTR rootPath, UInt64 &clusterSize, UInt64 &totalSize, UInt64 &freeSize)
96*f6dc9357SAndroid Build Coastguard Worker {
97*f6dc9357SAndroid Build Coastguard Worker DWORD numSectorsPerCluster, bytesPerSector, numFreeClusters, numClusters;
98*f6dc9357SAndroid Build Coastguard Worker bool sizeIsDetected = false;
99*f6dc9357SAndroid Build Coastguard Worker #ifndef _UNICODE
100*f6dc9357SAndroid Build Coastguard Worker if (!g_IsNT)
101*f6dc9357SAndroid Build Coastguard Worker {
102*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_USE_DYN_GetDiskFreeSpaceEx
103*f6dc9357SAndroid Build Coastguard Worker const
104*f6dc9357SAndroid Build Coastguard Worker Func_GetDiskFreeSpaceExA f = Z7_GET_PROC_ADDRESS(
105*f6dc9357SAndroid Build Coastguard Worker Func_GetDiskFreeSpaceExA, GetModuleHandle(TEXT("kernel32.dll")),
106*f6dc9357SAndroid Build Coastguard Worker "GetDiskFreeSpaceExA");
107*f6dc9357SAndroid Build Coastguard Worker if (f)
108*f6dc9357SAndroid Build Coastguard Worker #endif
109*f6dc9357SAndroid Build Coastguard Worker {
110*f6dc9357SAndroid Build Coastguard Worker ULARGE_INTEGER freeBytesToCaller2, totalSize2, freeSize2;
111*f6dc9357SAndroid Build Coastguard Worker sizeIsDetected = BOOLToBool(
112*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_USE_DYN_GetDiskFreeSpaceEx
113*f6dc9357SAndroid Build Coastguard Worker f
114*f6dc9357SAndroid Build Coastguard Worker #else
115*f6dc9357SAndroid Build Coastguard Worker GetDiskFreeSpaceExA
116*f6dc9357SAndroid Build Coastguard Worker #endif
117*f6dc9357SAndroid Build Coastguard Worker (fs2fas(rootPath), &freeBytesToCaller2, &totalSize2, &freeSize2));
118*f6dc9357SAndroid Build Coastguard Worker totalSize = totalSize2.QuadPart;
119*f6dc9357SAndroid Build Coastguard Worker freeSize = freeSize2.QuadPart;
120*f6dc9357SAndroid Build Coastguard Worker }
121*f6dc9357SAndroid Build Coastguard Worker if (!::GetDiskFreeSpace(fs2fas(rootPath), &numSectorsPerCluster, &bytesPerSector, &numFreeClusters, &numClusters))
122*f6dc9357SAndroid Build Coastguard Worker return false;
123*f6dc9357SAndroid Build Coastguard Worker }
124*f6dc9357SAndroid Build Coastguard Worker else
125*f6dc9357SAndroid Build Coastguard Worker #endif
126*f6dc9357SAndroid Build Coastguard Worker {
127*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_USE_DYN_GetDiskFreeSpaceEx
128*f6dc9357SAndroid Build Coastguard Worker const
129*f6dc9357SAndroid Build Coastguard Worker Func_GetDiskFreeSpaceExW f = Z7_GET_PROC_ADDRESS(
130*f6dc9357SAndroid Build Coastguard Worker Func_GetDiskFreeSpaceExW, GetModuleHandle(TEXT("kernel32.dll")),
131*f6dc9357SAndroid Build Coastguard Worker "GetDiskFreeSpaceExW");
132*f6dc9357SAndroid Build Coastguard Worker if (f)
133*f6dc9357SAndroid Build Coastguard Worker #endif
134*f6dc9357SAndroid Build Coastguard Worker {
135*f6dc9357SAndroid Build Coastguard Worker ULARGE_INTEGER freeBytesToCaller2, totalSize2, freeSize2;
136*f6dc9357SAndroid Build Coastguard Worker sizeIsDetected = BOOLToBool(
137*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_USE_DYN_GetDiskFreeSpaceEx
138*f6dc9357SAndroid Build Coastguard Worker f
139*f6dc9357SAndroid Build Coastguard Worker #else
140*f6dc9357SAndroid Build Coastguard Worker GetDiskFreeSpaceExW
141*f6dc9357SAndroid Build Coastguard Worker #endif
142*f6dc9357SAndroid Build Coastguard Worker (fs2us(rootPath), &freeBytesToCaller2, &totalSize2, &freeSize2));
143*f6dc9357SAndroid Build Coastguard Worker totalSize = totalSize2.QuadPart;
144*f6dc9357SAndroid Build Coastguard Worker freeSize = freeSize2.QuadPart;
145*f6dc9357SAndroid Build Coastguard Worker }
146*f6dc9357SAndroid Build Coastguard Worker if (!::GetDiskFreeSpaceW(fs2us(rootPath), &numSectorsPerCluster, &bytesPerSector, &numFreeClusters, &numClusters))
147*f6dc9357SAndroid Build Coastguard Worker return false;
148*f6dc9357SAndroid Build Coastguard Worker }
149*f6dc9357SAndroid Build Coastguard Worker clusterSize = (UInt64)bytesPerSector * (UInt64)numSectorsPerCluster;
150*f6dc9357SAndroid Build Coastguard Worker if (!sizeIsDetected)
151*f6dc9357SAndroid Build Coastguard Worker {
152*f6dc9357SAndroid Build Coastguard Worker totalSize = clusterSize * (UInt64)numClusters;
153*f6dc9357SAndroid Build Coastguard Worker freeSize = clusterSize * (UInt64)numFreeClusters;
154*f6dc9357SAndroid Build Coastguard Worker }
155*f6dc9357SAndroid Build Coastguard Worker return true;
156*f6dc9357SAndroid Build Coastguard Worker }
157*f6dc9357SAndroid Build Coastguard Worker
158*f6dc9357SAndroid Build Coastguard Worker #endif
159*f6dc9357SAndroid Build Coastguard Worker
160*f6dc9357SAndroid Build Coastguard Worker /*
161*f6dc9357SAndroid Build Coastguard Worker bool Is_File_LimitedBy_4GB(CFSTR _path, bool &isFsDetected)
162*f6dc9357SAndroid Build Coastguard Worker {
163*f6dc9357SAndroid Build Coastguard Worker isFsDetected = false;
164*f6dc9357SAndroid Build Coastguard Worker FString path (_path);
165*f6dc9357SAndroid Build Coastguard Worker path.DeleteFrom(NName::GetRootPrefixSize(path));
166*f6dc9357SAndroid Build Coastguard Worker // GetVolumeInformation supports super paths.
167*f6dc9357SAndroid Build Coastguard Worker // NName::If_IsSuperPath_RemoveSuperPrefix(path);
168*f6dc9357SAndroid Build Coastguard Worker if (!path.IsEmpty())
169*f6dc9357SAndroid Build Coastguard Worker {
170*f6dc9357SAndroid Build Coastguard Worker DWORD volumeSerialNumber, maximumComponentLength, fileSystemFlags;
171*f6dc9357SAndroid Build Coastguard Worker UString volName, fileSystemName;
172*f6dc9357SAndroid Build Coastguard Worker if (MyGetVolumeInformation(path, volName,
173*f6dc9357SAndroid Build Coastguard Worker &volumeSerialNumber, &maximumComponentLength, &fileSystemFlags,
174*f6dc9357SAndroid Build Coastguard Worker fileSystemName))
175*f6dc9357SAndroid Build Coastguard Worker {
176*f6dc9357SAndroid Build Coastguard Worker isFsDetected = true;
177*f6dc9357SAndroid Build Coastguard Worker if (fileSystemName.IsPrefixedBy_Ascii_NoCase("fat"))
178*f6dc9357SAndroid Build Coastguard Worker return true;
179*f6dc9357SAndroid Build Coastguard Worker }
180*f6dc9357SAndroid Build Coastguard Worker }
181*f6dc9357SAndroid Build Coastguard Worker return false;
182*f6dc9357SAndroid Build Coastguard Worker }
183*f6dc9357SAndroid Build Coastguard Worker */
184*f6dc9357SAndroid Build Coastguard Worker
185*f6dc9357SAndroid Build Coastguard Worker }}}
186*f6dc9357SAndroid Build Coastguard Worker
187*f6dc9357SAndroid Build Coastguard Worker #endif
188