xref: /aosp_15_r20/external/lzma/CPP/Windows/FileSystem.cpp (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
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