xref: /third_party/lzma/CPP/Windows/FileSystem.cpp (revision 370b324c)
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
15extern bool g_IsNT;
16#endif
17
18namespace NWindows {
19namespace NFile {
20namespace NSystem {
21
22#ifdef _WIN32
23
24bool 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
60UINT 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
74typedef BOOL (WINAPI * Func_GetDiskFreeSpaceExA)(
75  LPCSTR lpDirectoryName,                  // directory name
76  PULARGE_INTEGER lpFreeBytesAvailable,    // bytes available to caller
77  PULARGE_INTEGER lpTotalNumberOfBytes,    // bytes on disk
78  PULARGE_INTEGER lpTotalNumberOfFreeBytes // free bytes on disk
79);
80
81typedef BOOL (WINAPI * Func_GetDiskFreeSpaceExW)(
82  LPCWSTR lpDirectoryName,                 // directory name
83  PULARGE_INTEGER lpFreeBytesAvailable,    // bytes available to caller
84  PULARGE_INTEGER lpTotalNumberOfBytes,    // bytes on disk
85  PULARGE_INTEGER lpTotalNumberOfFreeBytes // free bytes on disk
86);
87
88bool MyGetDiskFreeSpace(CFSTR rootPath, UInt64 &clusterSize, UInt64 &totalSize, UInt64 &freeSize)
89{
90  DWORD numSectorsPerCluster, bytesPerSector, numFreeClusters, numClusters;
91  bool sizeIsDetected = false;
92  #ifndef _UNICODE
93  if (!g_IsNT)
94  {
95    const
96    Func_GetDiskFreeSpaceExA f = Z7_GET_PROC_ADDRESS(
97    Func_GetDiskFreeSpaceExA, GetModuleHandle(TEXT("kernel32.dll")),
98        "GetDiskFreeSpaceExA");
99    if (f)
100    {
101      ULARGE_INTEGER freeBytesToCaller2, totalSize2, freeSize2;
102      sizeIsDetected = BOOLToBool(f(fs2fas(rootPath), &freeBytesToCaller2, &totalSize2, &freeSize2));
103      totalSize = totalSize2.QuadPart;
104      freeSize = freeSize2.QuadPart;
105    }
106    if (!::GetDiskFreeSpace(fs2fas(rootPath), &numSectorsPerCluster, &bytesPerSector, &numFreeClusters, &numClusters))
107      return false;
108  }
109  else
110  #endif
111  {
112    const
113    Func_GetDiskFreeSpaceExW f = Z7_GET_PROC_ADDRESS(
114    Func_GetDiskFreeSpaceExW, GetModuleHandle(TEXT("kernel32.dll")),
115        "GetDiskFreeSpaceExW");
116    if (f)
117    {
118      ULARGE_INTEGER freeBytesToCaller2, totalSize2, freeSize2;
119      sizeIsDetected = BOOLToBool(f(fs2us(rootPath), &freeBytesToCaller2, &totalSize2, &freeSize2));
120      totalSize = totalSize2.QuadPart;
121      freeSize = freeSize2.QuadPart;
122    }
123    if (!::GetDiskFreeSpaceW(fs2us(rootPath), &numSectorsPerCluster, &bytesPerSector, &numFreeClusters, &numClusters))
124      return false;
125  }
126  clusterSize = (UInt64)bytesPerSector * (UInt64)numSectorsPerCluster;
127  if (!sizeIsDetected)
128  {
129    totalSize = clusterSize * (UInt64)numClusters;
130    freeSize = clusterSize * (UInt64)numFreeClusters;
131  }
132  return true;
133}
134
135#endif
136
137}}}
138
139#endif
140