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.

286 lines
6.9 KiB

  1. #include "pch.h"
  2. #include "loader.h"
  3. #define MAX_RESOURCE_LENGTH 2048
  4. #define MIGWIZSUBDIR TEXT("usmt\\")
  5. #define MINIMUM_DISK_SPACE 3000000
  6. // Globals
  7. static PTSTR g_lpszDestPath = NULL;
  8. static PTSTR g_lpszModulePath = NULL;
  9. PTSTR
  10. GetModulePath( VOID )
  11. {
  12. if (g_lpszModulePath == NULL)
  13. {
  14. TCHAR lpszPath[MAX_PATH + 1];
  15. DWORD dwResult;
  16. // Build the path where this exe resides
  17. dwResult = GetModuleFileName( NULL, lpszPath, MAX_PATH );
  18. if (dwResult > 0 &&
  19. dwResult < MAX_PATH)
  20. {
  21. LPTSTR ptr;
  22. TCHAR *lastWack = NULL;
  23. ptr = lpszPath;
  24. while (*ptr)
  25. {
  26. if (*ptr == TEXT('\\'))
  27. {
  28. lastWack = ptr;
  29. }
  30. ptr = CharNext( ptr );
  31. }
  32. if (lastWack)
  33. {
  34. *(lastWack + 1) = 0;
  35. g_lpszModulePath = (PTSTR)ALLOC( (lstrlen(lpszPath) + 1) * sizeof(TCHAR) );
  36. if (g_lpszModulePath)
  37. {
  38. lstrcpy( g_lpszModulePath, lpszPath );
  39. }
  40. }
  41. }
  42. }
  43. return g_lpszModulePath;
  44. }
  45. DWORD
  46. pConvertDriveToBit (
  47. PCTSTR driveString
  48. )
  49. {
  50. DWORD bit = 0;
  51. TCHAR driveLetter;
  52. if (driveString && *driveString) {
  53. driveLetter = (TCHAR)_totlower (*driveString);
  54. if (driveLetter >= TEXT('a') && driveLetter <= TEXT('z')) {
  55. bit = 0x1 << (driveLetter - TEXT('a'));
  56. }
  57. }
  58. return bit;
  59. }
  60. BOOL
  61. pCreateMigwizDir( PCTSTR lpszPath )
  62. {
  63. BOOL fResult = FALSE;
  64. if (g_lpszDestPath != NULL)
  65. {
  66. FREE( g_lpszDestPath );
  67. }
  68. g_lpszDestPath = (PTSTR)ALLOC( (lstrlen(lpszPath) + lstrlen(MIGWIZSUBDIR) + 1) * sizeof(TCHAR) );
  69. if (g_lpszDestPath)
  70. {
  71. lstrcpy( g_lpszDestPath, lpszPath );
  72. lstrcat( g_lpszDestPath, MIGWIZSUBDIR );
  73. if (!CreateDirectory( g_lpszDestPath, NULL ))
  74. {
  75. if (GetLastError() != ERROR_ALREADY_EXISTS)
  76. {
  77. FREE( g_lpszDestPath );
  78. g_lpszDestPath = NULL;
  79. return FALSE;
  80. }
  81. }
  82. fResult = TRUE;
  83. }
  84. return fResult;
  85. }
  86. PTSTR
  87. GetDestPath( VOID )
  88. {
  89. DWORD sectPerClust;
  90. DWORD bytesPerSect;
  91. DWORD freeClusters;
  92. DWORD totalClusters;
  93. ULONGLONG maxFreeDiskSpace = 0;
  94. ULONGLONG freeDiskSpace = 0;
  95. TCHAR szPath[MAX_PATH + 1];
  96. PTSTR lpDriveList = NULL;
  97. PCTSTR lpDrive;
  98. DWORD dwListLen;
  99. if (g_lpszDestPath == NULL)
  100. {
  101. // If %TEMP% has enough space, use it
  102. if (GetTempPath( MAX_PATH, szPath ))
  103. {
  104. TCHAR szTmpPath[4] = TEXT("?:\\");
  105. szTmpPath[0] = szPath[0];
  106. if (GetDiskFreeSpace( szTmpPath, &sectPerClust, &bytesPerSect, &freeClusters, &totalClusters ))
  107. {
  108. freeDiskSpace = Int32x32To64( (sectPerClust * bytesPerSect), freeClusters );
  109. if (freeDiskSpace > MINIMUM_DISK_SPACE)
  110. {
  111. if (pCreateMigwizDir(szPath))
  112. {
  113. return g_lpszDestPath;
  114. }
  115. }
  116. }
  117. }
  118. // Otherwise use the first drive with the enough space
  119. dwListLen = GetLogicalDriveStrings( 0, NULL ) + 1;
  120. lpDriveList = (PTSTR)ALLOC( dwListLen );
  121. GetLogicalDriveStrings( dwListLen, lpDriveList );
  122. lpDrive = lpDriveList;
  123. while (*lpDrive) {
  124. if (GetDriveType( lpDrive ) == DRIVE_FIXED)
  125. {
  126. if (GetDiskFreeSpace( lpDrive, &sectPerClust, &bytesPerSect, &freeClusters, &totalClusters ))
  127. {
  128. freeDiskSpace = Int32x32To64( (sectPerClust * bytesPerSect), freeClusters );
  129. if (freeDiskSpace > MINIMUM_DISK_SPACE)
  130. {
  131. if (pCreateMigwizDir( lpDrive ))
  132. {
  133. // We have a winner! Let's bail.
  134. break;
  135. }
  136. }
  137. }
  138. }
  139. // Advance to the next drive in the drive list
  140. lpDrive = _tcschr( lpDrive, 0 ) + 1;
  141. }
  142. FREE(lpDriveList);
  143. }
  144. return g_lpszDestPath;
  145. }
  146. PTSTR
  147. JoinText( PTSTR lpStr1, PTSTR lpStr2, TCHAR chSeparator )
  148. {
  149. PTSTR lpResult;
  150. DWORD dwSize1;
  151. DWORD dwSize2;
  152. DWORD dwSize;
  153. BOOL fAddSep = TRUE;
  154. dwSize1 = lstrlen(lpStr1);
  155. if (lpStr1[dwSize1 - 1] == chSeparator)
  156. {
  157. fAddSep = FALSE;
  158. }
  159. dwSize2 = lstrlen(lpStr2);
  160. if (lpStr2[0] == chSeparator)
  161. {
  162. fAddSep = FALSE;
  163. }
  164. dwSize = dwSize1 + dwSize2 + (fAddSep ? 1 : 0);
  165. lpResult = (PTSTR)ALLOC((dwSize+1) * sizeof(TCHAR));
  166. if (lpResult)
  167. {
  168. lstrcpy( lpResult, lpStr1 );
  169. if (fAddSep)
  170. {
  171. lpResult[dwSize1] = chSeparator;
  172. dwSize1 += 1;
  173. }
  174. lstrcpy( lpResult+dwSize1, lpStr2 );
  175. }
  176. return lpResult;
  177. }
  178. PTSTR
  179. GetResourceString( HINSTANCE hInstance, DWORD dwResID )
  180. {
  181. TCHAR szTmpString[MAX_RESOURCE_LENGTH];
  182. DWORD dwStringLength;
  183. PTSTR lpszResultString = NULL;
  184. dwStringLength = LoadString( hInstance,
  185. dwResID,
  186. szTmpString,
  187. MAX_RESOURCE_LENGTH );
  188. if (dwStringLength > 0)
  189. {
  190. lpszResultString = (PTSTR)ALLOC( (dwStringLength+1) * sizeof(TCHAR) );
  191. if (lpszResultString)
  192. {
  193. lstrcpy( lpszResultString, szTmpString );
  194. }
  195. }
  196. return lpszResultString;
  197. }
  198. PSTR
  199. GetResourceStringA( HINSTANCE hInstance, DWORD dwResID )
  200. {
  201. CHAR szTmpString[MAX_RESOURCE_LENGTH];
  202. DWORD dwStringLength;
  203. PSTR lpszResultString = NULL;
  204. dwStringLength = LoadStringA( hInstance,
  205. dwResID,
  206. szTmpString,
  207. MAX_RESOURCE_LENGTH );
  208. if (dwStringLength > 0)
  209. {
  210. lpszResultString = (PSTR)ALLOC( (dwStringLength+1) * sizeof(CHAR) );
  211. if (lpszResultString)
  212. {
  213. lstrcpyA( lpszResultString, szTmpString );
  214. }
  215. }
  216. return lpszResultString;
  217. }
  218. PWSTR
  219. GetResourceStringW( HINSTANCE hInstance, DWORD dwResID )
  220. {
  221. WCHAR szTmpString[MAX_RESOURCE_LENGTH];
  222. DWORD dwStringLength;
  223. PWSTR lpszResultString = NULL;
  224. dwStringLength = LoadStringW( hInstance,
  225. dwResID,
  226. szTmpString,
  227. MAX_RESOURCE_LENGTH );
  228. if (dwStringLength > 0)
  229. {
  230. lpszResultString = (PWSTR)ALLOC( (dwStringLength+1) * sizeof(WCHAR) );
  231. if (lpszResultString)
  232. {
  233. lstrcpyW( lpszResultString, szTmpString );
  234. }
  235. }
  236. return lpszResultString;
  237. }
  238. VOID
  239. UtilFree( VOID )
  240. {
  241. if (g_lpszDestPath)
  242. {
  243. FREE( g_lpszDestPath );
  244. g_lpszDestPath = NULL;
  245. }
  246. }