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.

411 lines
8.4 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1997 - 1999
  6. //
  7. // File: util.cxx
  8. //
  9. //--------------------------------------------------------------------------
  10. #include "precomp.h"
  11. #include "shlguid.h"
  12. // FileExists function
  13. #define _dwGFAFail 0xFFFFFFFF
  14. #define _nMaxLines 1000
  15. // Reg functions
  16. #define nMAX_REGROOT 7
  17. #define nREGROOT_SZ 24
  18. BOOL DirectoryExists( LPWSTR szDir )
  19. {
  20. DWORD dwAttr = GetFileAttributes( szDir );
  21. if( _dwGFAFail == dwAttr )
  22. return FALSE;
  23. return (BOOL)( dwAttr & FILE_ATTRIBUTE_DIRECTORY );
  24. }
  25. BOOL FileExists( LPWSTR szFile )
  26. {
  27. DWORD dwAttr = GetFileAttributes( szFile );
  28. if( _dwGFAFail == dwAttr )
  29. return FALSE;
  30. return (BOOL)( !(dwAttr & FILE_ATTRIBUTE_DIRECTORY) );
  31. }
  32. VOID StripPath( LPWSTR szFullPath )
  33. {
  34. LPWSTR lpc = GetFileName( szFullPath );
  35. if( !lpc )
  36. return;
  37. lstrcpy( szFullPath, lpc );
  38. }
  39. VOID StripPathW( LPWSTR wszFullPath )
  40. {
  41. LPWSTR lpwc = GetFileNameW( wszFullPath );
  42. if( !lpwc || lpwc == wszFullPath )
  43. return;
  44. SzCpyW( wszFullPath, lpwc );
  45. }
  46. VOID StripFile( LPWSTR szFullPath )
  47. {
  48. LPWSTR lpc = GetFileName( szFullPath );
  49. if( !lpc )
  50. return;
  51. *lpc = cNIL;
  52. }
  53. VOID StripExt( LPWSTR szFullPath )
  54. {
  55. LPWSTR lpc = GetFileName(szFullPath);
  56. if( !lpc )
  57. return;
  58. while( *lpc && *lpc != cPERIOD )
  59. {
  60. lpc++;
  61. }
  62. if( *lpc == cPERIOD )
  63. *lpc = cNIL;
  64. }
  65. LPWSTR GetFileName( LPWSTR lpszFullPath )
  66. {
  67. LPWSTR lpszFileName;
  68. if( !lpszFullPath)
  69. return lpNIL;
  70. for (lpszFileName = lpszFullPath; *lpszFullPath; lpszFullPath++)
  71. {
  72. if (*lpszFullPath == cBACKSLASH)
  73. lpszFileName = lpszFullPath + 1;
  74. }
  75. return lpszFileName;
  76. }
  77. LPWSTR GetFileNameW( LPWSTR wszFullPath )
  78. {
  79. LPWSTR lpwc;
  80. if( !wszFullPath || wszFullPath[0] == 0)
  81. return lpNIL;
  82. lpwc = wszFullPath + CchWsz(wszFullPath) - 1;
  83. while( *lpwc != (WCHAR)cBACKSLASH && lpwc != wszFullPath )
  84. lpwc--;
  85. if( lpwc == wszFullPath )
  86. return wszFullPath;
  87. return ++lpwc;
  88. }
  89. BOOL bNoTrailingSlash( LPWSTR szPath )
  90. {
  91. LPWSTR lpc;
  92. WCHAR cLast;
  93. for( lpc = szPath; *lpc; cLast = *lpc, lpc++ )
  94. ;
  95. return ( cLast != cBACKSLASH );
  96. }
  97. BOOL GetUniqueName( LPWSTR szPath, LPWSTR szBase, BOOL fFile )
  98. {
  99. INT nTry;
  100. LPWSTR lpFileName;
  101. WCHAR szFormat[cbMAX_SZ];
  102. if( bNoTrailingSlash(szPath) )
  103. lstrcat( szPath, szBACKSLASH );
  104. lpFileName = szPath + lstrlen(szPath);
  105. lstrcpy( lpFileName, szBase );
  106. nTry = 0;
  107. while( 0xffffffff != GetFileAttributes(szPath) )
  108. {
  109. wcscpy( szFormat, g_DuplicateFileTemplate );
  110. wsprintf( lpFileName, szFormat, ++nTry, szBase );
  111. }
  112. return TRUE;
  113. }
  114. DWORD GetDirectorySize( LPWSTR szFolder )
  115. {
  116. BOOL bRet;
  117. HANDLE hFind;
  118. DWORD dwSize = 0L;
  119. WCHAR szBaseDir[MAX_PATH];
  120. WCHAR szSpec[MAX_PATH];
  121. WIN32_FIND_DATA findData;
  122. // get base directory ending with backslash
  123. lstrcpy( szBaseDir, szFolder );
  124. if( bNoTrailingSlash(szBaseDir) )
  125. lstrcat( szBaseDir, szBACKSLASH );
  126. // form search string
  127. lstrcpy( szSpec, szBaseDir );
  128. lstrcat( szSpec, L"*.*" );
  129. hFind = FindFirstFile(
  130. szSpec,
  131. &findData
  132. );
  133. bRet = ( hFind != INVALID_HANDLE_VALUE );
  134. while( bRet )
  135. {
  136. WCHAR szObj[cbMAX_SZ];
  137. lstrcpy( szObj, szBaseDir );
  138. lstrcat( szObj, findData.cFileName );
  139. if( findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
  140. {
  141. // weed out "." and ".."
  142. if( *(findData.cFileName) != cPERIOD )
  143. dwSize += GetDirectorySize( szObj );
  144. }
  145. else
  146. {
  147. HANDLE hFile = CreateFile(
  148. szObj,
  149. GENERIC_READ,
  150. FILE_SHARE_READ,
  151. NULL,
  152. OPEN_EXISTING,
  153. FILE_ATTRIBUTE_NORMAL,
  154. NULL
  155. );
  156. if( INVALID_HANDLE_VALUE != hFile )
  157. {
  158. //REVIEW: won't work for REALLY large files
  159. dwSize += GetFileSize( hFile, NULL );
  160. CloseHandle( hFile );
  161. }
  162. }
  163. bRet = FindNextFile( hFind, &findData );
  164. }
  165. if (hFind != INVALID_HANDLE_VALUE)
  166. {
  167. FindClose(hFind);
  168. }
  169. return dwSize;
  170. }
  171. LPWSTR SzToWsz( LPCSTR lpsz )
  172. {
  173. INT nSzLen = lstrlenA(lpsz);
  174. LPWSTR lpwsz = (LPWSTR) MemAlloc((nSzLen+1)*sizeof(WCHAR));
  175. if (lpwsz){
  176. MultiByteToWideChar(
  177. CP_ACP,
  178. 0L,
  179. lpsz,
  180. nSzLen,
  181. lpwsz,
  182. nSzLen+1
  183. );
  184. }
  185. return lpwsz;
  186. }
  187. LPSTR WszToSz( LPCWSTR lpwsz )
  188. {
  189. int err;
  190. int Length;
  191. LPSTR lpsz;
  192. Length = WideCharToMultiByte(CP_ACP,
  193. 0L,
  194. lpwsz,
  195. -1,
  196. 0,
  197. 0,
  198. NULL,
  199. NULL
  200. );
  201. lpsz = (LPSTR) MemAlloc(1+Length);
  202. if (!lpsz)
  203. {
  204. return 0;
  205. }
  206. if ( !WideCharToMultiByte(CP_ACP,
  207. 0L,
  208. lpwsz,
  209. Length,
  210. lpsz,
  211. 1+Length,
  212. NULL,
  213. NULL
  214. ))
  215. {
  216. MemFree( lpsz );
  217. return 0;
  218. }
  219. return lpsz;
  220. }
  221. INT SzLenW( LPCWSTR lpwsz )
  222. {
  223. WCHAR *pwc = (WCHAR *)lpwsz;
  224. if( !lpwsz )
  225. return 0;
  226. while( *pwc++ != 0 )
  227. ;
  228. return (INT)(--pwc - lpwsz);
  229. }
  230. LPWSTR SzCpyW( LPWSTR lpsz1, LPCWSTR lpsz2 )
  231. {
  232. LPWSTR lpwsz = lpsz1;
  233. while( *lpsz2 )
  234. *lpsz1++ = *lpsz2++;
  235. *lpsz1 = 0;
  236. return lpwsz;
  237. }
  238. INT SzCmpN( LPCSTR lpsz1, LPCSTR lpsz2, INT nLen )
  239. {
  240. while( *lpsz1 && *lpsz2 && *lpsz1 == *lpsz2 && --nLen > 0 )
  241. {
  242. lpsz1++;
  243. lpsz2++;
  244. }
  245. return ( *lpsz1 - *lpsz2 );
  246. }
  247. BOOL IsRoomForFile( __int64 dwFileSize, LPWSTR szPath )
  248. {
  249. BOOL fRet;
  250. ULARGE_INTEGER MyDiskFreeBytes;
  251. ULARGE_INTEGER DiskFreeBytes;
  252. ULARGE_INTEGER DiskTotalBytes;
  253. fRet = GetDiskFreeSpaceEx(
  254. szPath,
  255. &MyDiskFreeBytes,
  256. &DiskTotalBytes,
  257. &DiskFreeBytes
  258. );
  259. if( fRet )
  260. {
  261. fRet = ( MyDiskFreeBytes.QuadPart >= (ULONGLONG) dwFileSize );
  262. }
  263. return fRet;
  264. }
  265. __int64 _Get100nsIntervalsFrom1601To1970( VOID )
  266. {
  267. __int64 ilrg100nsPerSec = 10000000; // 100-ns intervals per second (10^7)
  268. __int64 ilrg100nsPerMin = 60*ilrg100nsPerSec;
  269. __int64 ilrgDays = 369*365 + 89; // 369 years (89 are leap years).
  270. __int64 ilrgMin = ilrgDays*24*60;
  271. __int64 ilrgRet;
  272. ilrgRet = ilrgMin * ilrg100nsPerMin;
  273. return ilrgRet;
  274. }
  275. BOOL FileTimeToUnixTime( IN LPFILETIME lpFileTime,
  276. OUT LPDWORD pdwUnixTime )
  277. {
  278. LARGE_INTEGER lrgTime
  279. = { lpFileTime->dwLowDateTime, lpFileTime->dwHighDateTime };
  280. __int64 ilrgFileTime = *((__int64*)lpFileTime);
  281. __int64 ilrgIntervalsTil1970 = _Get100nsIntervalsFrom1601To1970();
  282. __int64 ilrgIntsSince1970;
  283. __int64 ilrgSecSince1970;
  284. __int64 ilrg100nsPerSec = 10000000;
  285. __int64 ilrgRem;
  286. // Get the intervals since 1970
  287. ilrgIntsSince1970 = ilrgFileTime - ilrgIntervalsTil1970;
  288. // Convert to seconds since 1970
  289. ilrgSecSince1970 = ilrgIntsSince1970/ilrg100nsPerSec;
  290. if (ilrgSecSince1970 >= 0xffffffff)
  291. {
  292. return FALSE;
  293. }
  294. *pdwUnixTime = (DWORD)ilrgSecSince1970;
  295. return TRUE;
  296. }
  297. BOOL UnixTimeToFileTime( DWORD dwUnixTime, LPFILETIME lpFileTime )
  298. {
  299. __int64 ilrg100nsPerSec = 10000000; // 100-ns intervals/second (10^7)
  300. __int64 ilrgIntervalsSince1601;
  301. __int64 ilrgIntervalsSince1970;
  302. __int64 ilrgIntervalsTil1970 = _Get100nsIntervalsFrom1601To1970();
  303. // Get the intervals since 1970
  304. ilrgIntervalsSince1970 = dwUnixTime * ilrg100nsPerSec;
  305. // Get the intervals since 1601
  306. ilrgIntervalsSince1601 = ilrgIntervalsTil1970 + ilrgIntervalsSince1970;
  307. *lpFileTime = *((FILETIME*)&ilrgIntervalsSince1601);
  308. return TRUE;
  309. }