Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

220 lines
6.8 KiB

  1. #include "shellprv.h"
  2. #pragma hdrstop
  3. #include "netview.h"
  4. // drivesx.c
  5. DWORD PathGetClusterSize(LPCTSTR pszPath);
  6. // get connection information including disconnected drives
  7. //
  8. // in:
  9. // pszDev device name "A:" "LPT1:", etc.
  10. // bConvertClosed
  11. // if FALSE closed or error drives will be converted to
  12. // WN_SUCCESS return codes. if TRUE return not connected
  13. // and error state values (ie, the caller knows about not
  14. // connected and error state drives)
  15. //
  16. // out:
  17. // lpPath filled with net name if return is WN_SUCCESS (or not connected/error)
  18. // returns:
  19. // WN_* error code
  20. DWORD GetConnection(LPCTSTR pszDev, LPTSTR pszPath, UINT cchPath, BOOL bConvertClosed)
  21. {
  22. DWORD err;
  23. int iType = DriveType(DRIVEID(pszDev));
  24. if (DRIVE_REMOVABLE == iType || DRIVE_FIXED == iType || DRIVE_CDROM == iType || DRIVE_RAMDISK == iType)
  25. err = WN_NOT_CONNECTED;
  26. else
  27. {
  28. err = SHWNetGetConnection((LPTSTR)pszDev, pszPath, &cchPath);
  29. if (!bConvertClosed)
  30. if (err == WN_CONNECTION_CLOSED || err == WN_DEVICE_ERROR)
  31. err = WN_SUCCESS;
  32. }
  33. return err;
  34. }
  35. // this is called for every drive at init time so it must
  36. // be sure to not trigget things like the phantom B: drive support
  37. //
  38. // in:
  39. // iDrive zero based drive number (0 = A, 1 = B)
  40. //
  41. // returns:
  42. // 0 not a net drive
  43. // 1 is a net drive, properly connected
  44. // 2 disconnected/error state connection
  45. STDAPI_(int) IsNetDrive(int iDrive)
  46. {
  47. if ((iDrive >= 0) && (iDrive < 26))
  48. {
  49. DWORD err;
  50. TCHAR szDrive[4], szConn[MAX_PATH]; // this really should be WNBD_MAX_LENGTH
  51. PathBuildRoot(szDrive, iDrive);
  52. err = GetConnection(szDrive, szConn, ARRAYSIZE(szConn), TRUE);
  53. if (err == WN_SUCCESS)
  54. return 1;
  55. if (err == WN_CONNECTION_CLOSED || err == WN_DEVICE_ERROR)
  56. if ((GetLogicalDrives() & (1 << iDrive)) == 0)
  57. return 2;
  58. }
  59. return 0;
  60. }
  61. typedef BOOL (WINAPI* PFNISPATHSHARED)(LPCTSTR pszPath, BOOL fRefresh);
  62. HMODULE g_hmodShare = (HMODULE)-1;
  63. PFNISPATHSHARED g_pfnIsPathShared = NULL;
  64. // ask the share provider if this path is shared
  65. BOOL IsShared(LPNCTSTR pszPath, BOOL fUpdateCache)
  66. {
  67. TCHAR szPath[MAX_PATH];
  68. // See if we have already tried to load this in this context
  69. if (g_hmodShare == (HMODULE)-1)
  70. {
  71. LONG cb = sizeof(szPath);
  72. g_hmodShare = NULL; // asume failure
  73. SHRegQueryValue(HKEY_CLASSES_ROOT, TEXT("Network\\SharingHandler"), szPath, &cb);
  74. if (szPath[0])
  75. {
  76. g_hmodShare = LoadLibrary(szPath);
  77. if (g_hmodShare)
  78. g_pfnIsPathShared = (PFNISPATHSHARED)GetProcAddress(g_hmodShare, "IsPathSharedW");
  79. }
  80. }
  81. if (g_pfnIsPathShared)
  82. {
  83. #ifdef ALIGNMENT_SCENARIO
  84. ualstrcpyn(szPath, pszPath, ARRAYSIZE(szPath));
  85. return g_pfnIsPathShared(szPath, fUpdateCache);
  86. #else
  87. return g_pfnIsPathShared(pszPath, fUpdateCache);
  88. #endif
  89. }
  90. return FALSE;
  91. }
  92. // invalidate the DriveType cache for one entry, or all
  93. STDAPI_(void) InvalidateDriveType(int iDrive)
  94. {}
  95. #define ROUND_TO_CLUSER(qw, dwCluster) ((((qw) + (dwCluster) - 1) / dwCluster) * dwCluster)
  96. //
  97. // GetCompresedFileSize is NT only, so we only implement the SHGetCompressedFileSizeW
  98. // version. This will return the size of the file on disk rounded to the cluster size.
  99. //
  100. STDAPI_(DWORD) SHGetCompressedFileSizeW(LPCWSTR pszFileName, LPDWORD pFileSizeHigh)
  101. {
  102. DWORD dwClusterSize;
  103. ULARGE_INTEGER ulSizeOnDisk;
  104. if (!pszFileName || !pszFileName[0])
  105. {
  106. ASSERT(FALSE);
  107. *pFileSizeHigh = 0;
  108. return 0;
  109. }
  110. dwClusterSize = PathGetClusterSize(pszFileName);
  111. ulSizeOnDisk.LowPart = GetCompressedFileSizeW(pszFileName, &ulSizeOnDisk.HighPart);
  112. if ((ulSizeOnDisk.LowPart == (DWORD)-1) && (GetLastError() != NO_ERROR))
  113. {
  114. WIN32_FILE_ATTRIBUTE_DATA fad;
  115. TraceMsg(TF_WARNING, "GetCompressedFileSize failed on %s (lasterror = %x)", pszFileName, GetLastError());
  116. if (GetFileAttributesExW(pszFileName, GetFileExInfoStandard, &fad))
  117. {
  118. // use the normal size, but round it to the cluster size
  119. ulSizeOnDisk.LowPart = fad.nFileSizeLow;
  120. ulSizeOnDisk.HighPart = fad.nFileSizeHigh;
  121. ROUND_TO_CLUSER(ulSizeOnDisk.QuadPart, dwClusterSize);
  122. }
  123. else
  124. {
  125. // since both GetCompressedFileSize and GetFileAttributesEx failed, we
  126. // just return zero
  127. ulSizeOnDisk.QuadPart = 0;
  128. }
  129. }
  130. // for files < one cluster, GetCompressedFileSize returns real size so we need
  131. // to round it up to one cluster
  132. if (ulSizeOnDisk.QuadPart < dwClusterSize)
  133. {
  134. ulSizeOnDisk.QuadPart = dwClusterSize;
  135. }
  136. *pFileSizeHigh = ulSizeOnDisk.HighPart;
  137. return ulSizeOnDisk.LowPart;
  138. }
  139. STDAPI_(BOOL) SHGetDiskFreeSpaceEx(LPCTSTR pszDirectoryName,
  140. PULARGE_INTEGER pulFreeBytesAvailableToCaller,
  141. PULARGE_INTEGER pulTotalNumberOfBytes,
  142. PULARGE_INTEGER pulTotalNumberOfFreeBytes)
  143. {
  144. BOOL bRet = GetDiskFreeSpaceEx(pszDirectoryName, pulFreeBytesAvailableToCaller, pulTotalNumberOfBytes, pulTotalNumberOfFreeBytes);
  145. if (bRet)
  146. {
  147. #ifdef DEBUG
  148. if (pulTotalNumberOfFreeBytes)
  149. {
  150. DWORD dw, dwSize = sizeof(dw);
  151. if (ERROR_SUCCESS == SHRegGetUSValue(TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\DiskSpace"),
  152. pszDirectoryName, NULL, &dw, &dwSize, TRUE, NULL, 0))
  153. {
  154. pulTotalNumberOfFreeBytes->QuadPart = dw * (ULONGLONG)0x100000; // convert to MB
  155. }
  156. }
  157. #endif
  158. }
  159. return bRet;
  160. }
  161. #ifdef UNICODE
  162. BOOL SHGetDiskFreeSpaceExA(LPCSTR pszDirectoryName,
  163. PULARGE_INTEGER pulFreeBytesAvailableToCaller,
  164. PULARGE_INTEGER pulTotalNumberOfBytes,
  165. PULARGE_INTEGER pulTotalNumberOfFreeBytes)
  166. {
  167. TCHAR szName[MAX_PATH];
  168. SHAnsiToTChar(pszDirectoryName, szName, SIZECHARS(szName));
  169. return SHGetDiskFreeSpaceEx(szName, pulFreeBytesAvailableToCaller, pulTotalNumberOfBytes, pulTotalNumberOfFreeBytes);
  170. }
  171. #else
  172. BOOL SHGetDiskFreeSpaceExW(LPCWSTR pszDirectoryName,
  173. PULARGE_INTEGER pulFreeBytesAvailableToCaller,
  174. PULARGE_INTEGER pulTotalNumberOfBytes,
  175. PULARGE_INTEGER pulTotalNumberOfFreeBytes)
  176. {
  177. TCHAR szName[MAX_PATH];
  178. SHUnicodeToTChar(pszDirectoryName, szName, SIZECHARS(szName));
  179. return SHGetDiskFreeSpaceEx(szName, pulFreeBytesAvailableToCaller, pulTotalNumberOfBytes, pulTotalNumberOfFreeBytes);
  180. }
  181. #endif