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
22bool MyGetVolumeInformation(
23    CFSTR rootPath,
24    UString &volumeName,
25    LPDWORD volumeSerialNumber,
26    LPDWORD maximumComponentLength,
27    LPDWORD fileSystemFlags,
28    UString &fileSystemName)
29{
30  BOOL res;
31  #ifndef _UNICODE
32  if (!g_IsNT)
33  {
34    TCHAR v[MAX_PATH + 2]; v[0] = 0;
35    TCHAR f[MAX_PATH + 2]; f[0] = 0;
36    res = GetVolumeInformation(fs2fas(rootPath),
37        v, MAX_PATH,
38        volumeSerialNumber, maximumComponentLength, fileSystemFlags,
39        f, MAX_PATH);
40    volumeName = MultiByteToUnicodeString(v);
41    fileSystemName = MultiByteToUnicodeString(f);
42  }
43  else
44  #endif
45  {
46    WCHAR v[MAX_PATH + 2]; v[0] = 0;
47    WCHAR f[MAX_PATH + 2]; f[0] = 0;
48    res = GetVolumeInformationW(fs2us(rootPath),
49        v, MAX_PATH,
50        volumeSerialNumber, maximumComponentLength, fileSystemFlags,
51        f, MAX_PATH);
52    volumeName = v;
53    fileSystemName = f;
54  }
55  return BOOLToBool(res);
56}
57
58UINT MyGetDriveType(CFSTR pathName)
59{
60  #ifndef _UNICODE
61  if (!g_IsNT)
62  {
63    return GetDriveType(fs2fas(pathName));
64  }
65  else
66  #endif
67  {
68    return GetDriveTypeW(fs2us(pathName));
69  }
70}
71
72typedef BOOL (WINAPI * GetDiskFreeSpaceExA_Pointer)(
73  LPCSTR lpDirectoryName,                  // directory name
74  PULARGE_INTEGER lpFreeBytesAvailable,    // bytes available to caller
75  PULARGE_INTEGER lpTotalNumberOfBytes,    // bytes on disk
76  PULARGE_INTEGER lpTotalNumberOfFreeBytes // free bytes on disk
77);
78
79typedef BOOL (WINAPI * GetDiskFreeSpaceExW_Pointer)(
80  LPCWSTR lpDirectoryName,                 // directory name
81  PULARGE_INTEGER lpFreeBytesAvailable,    // bytes available to caller
82  PULARGE_INTEGER lpTotalNumberOfBytes,    // bytes on disk
83  PULARGE_INTEGER lpTotalNumberOfFreeBytes // free bytes on disk
84);
85
86bool MyGetDiskFreeSpace(CFSTR rootPath, UInt64 &clusterSize, UInt64 &totalSize, UInt64 &freeSize)
87{
88  DWORD numSectorsPerCluster, bytesPerSector, numFreeClusters, numClusters;
89  bool sizeIsDetected = false;
90  #ifndef _UNICODE
91  if (!g_IsNT)
92  {
93    GetDiskFreeSpaceExA_Pointer pGetDiskFreeSpaceEx = (GetDiskFreeSpaceExA_Pointer)GetProcAddress(
94        GetModuleHandle(TEXT("kernel32.dll")), "GetDiskFreeSpaceExA");
95    if (pGetDiskFreeSpaceEx)
96    {
97      ULARGE_INTEGER freeBytesToCaller2, totalSize2, freeSize2;
98      sizeIsDetected = BOOLToBool(pGetDiskFreeSpaceEx(fs2fas(rootPath), &freeBytesToCaller2, &totalSize2, &freeSize2));
99      totalSize = totalSize2.QuadPart;
100      freeSize = freeSize2.QuadPart;
101    }
102    if (!::GetDiskFreeSpace(fs2fas(rootPath), &numSectorsPerCluster, &bytesPerSector, &numFreeClusters, &numClusters))
103      return false;
104  }
105  else
106  #endif
107  {
108    GetDiskFreeSpaceExW_Pointer pGetDiskFreeSpaceEx = (GetDiskFreeSpaceExW_Pointer)GetProcAddress(
109        GetModuleHandle(TEXT("kernel32.dll")), "GetDiskFreeSpaceExW");
110    if (pGetDiskFreeSpaceEx)
111    {
112      ULARGE_INTEGER freeBytesToCaller2, totalSize2, freeSize2;
113      sizeIsDetected = BOOLToBool(pGetDiskFreeSpaceEx(fs2us(rootPath), &freeBytesToCaller2, &totalSize2, &freeSize2));
114      totalSize = totalSize2.QuadPart;
115      freeSize = freeSize2.QuadPart;
116    }
117    if (!::GetDiskFreeSpaceW(fs2us(rootPath), &numSectorsPerCluster, &bytesPerSector, &numFreeClusters, &numClusters))
118      return false;
119  }
120  clusterSize = (UInt64)bytesPerSector * (UInt64)numSectorsPerCluster;
121  if (!sizeIsDetected)
122  {
123    totalSize = clusterSize * (UInt64)numClusters;
124    freeSize = clusterSize * (UInt64)numFreeClusters;
125  }
126  return true;
127}
128
129}}}
130
131#endif
132