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