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.

483 lines
10 KiB

  1. /*++
  2. Copyright (c) 1998-2000 Microsoft Corporation
  3. Module Name:
  4. sif.c
  5. Abstract:
  6. This module contains the following routines for manipulating the sif file in
  7. which Plug and Play migration data will be stored:
  8. AsrCreatePnpStateFileW
  9. AsrCreatePnpStateFileA
  10. Author:
  11. Jim Cavalaris (jamesca) 07-Mar-2000
  12. Environment:
  13. User-mode only.
  14. Revision History:
  15. 07-March-2000 jamesca
  16. Creation and initial implementation.
  17. --*/
  18. //
  19. // includes
  20. //
  21. #include "precomp.h"
  22. #include "debug.h"
  23. #include "pnpsif.h"
  24. #include <pnpmgr.h>
  25. #include <setupbat.h>
  26. //
  27. // definitions
  28. //
  29. // Maximum length of a line in the sif file
  30. #define MAX_SIF_LINE 4096
  31. //
  32. // private prototypes
  33. //
  34. BOOL
  35. CreateSifFileW(
  36. IN PCWSTR FilePath,
  37. IN BOOL CreateNew,
  38. OUT LPHANDLE SifHandle
  39. );
  40. BOOL
  41. WriteSifSection(
  42. IN CONST HANDLE SifHandle,
  43. IN PCTSTR SectionName,
  44. IN PCTSTR SectionData,
  45. IN BOOL Ansi
  46. );
  47. //
  48. // routines
  49. //
  50. BOOL
  51. AsrCreatePnpStateFileW(
  52. IN PCWSTR lpFilePath
  53. )
  54. /*++
  55. Routine Description:
  56. Creates the ASR PNP state file (asrpnp.sif) at the specified file-path
  57. during an ASR backup operation. This sif file is retrieved from the ASR
  58. floppy disk during the setupldr phase of a clean install, and in used during
  59. text mode setup.
  60. Arguments:
  61. lpFilePath - Specifies the path to the file where the state file is to be
  62. created.
  63. Return Value:
  64. TRUE if successful, FALSE otherwise. Upon failure, additional information
  65. can be retrieved by calling GetLastError().
  66. --*/
  67. {
  68. BOOL result = TRUE;
  69. BOOL bAnsiSif = TRUE; // always write ANSI sif files.
  70. LPTSTR buffer = NULL;
  71. HANDLE sifHandle = NULL;
  72. //
  73. // Create an empty sif file using the supplied path name.
  74. //
  75. result = CreateSifFileW(lpFilePath,
  76. TRUE, // create a new asrpnp.sif file
  77. &sifHandle);
  78. if (!result) {
  79. //
  80. // LastError already set by CreateSifFile.
  81. //
  82. DBGTRACE( DBGF_ERRORS,
  83. (TEXT("AsrCreatePnpStateFile: CreateSifFileW failed for file %ws, error=0x%08lx\n"),
  84. lpFilePath, GetLastError()));
  85. return FALSE;
  86. }
  87. //
  88. // Do the device instance migration stuff...
  89. //
  90. if (MigrateDeviceInstanceData(&buffer)) {
  91. //
  92. // Write the device instance section to the sif file.
  93. //
  94. result = WriteSifSection(sifHandle,
  95. WINNT_DEVICEINSTANCES,
  96. buffer,
  97. bAnsiSif); // Write sif section as ANSI
  98. if (!result) {
  99. DBGTRACE( DBGF_ERRORS,
  100. (TEXT("AsrCreatePnpStateFile: WriteSifSection failed for [%s], error=0x%08lx\n"),
  101. WINNT_DEVICEINSTANCES, GetLastError()));
  102. }
  103. //
  104. // Free the allocated buffer.
  105. //
  106. LocalFree(buffer);
  107. buffer = NULL;
  108. } else {
  109. DBGTRACE( DBGF_ERRORS,
  110. (TEXT("AsrCreatePnpStateFile: MigrateDeviceInstanceData failed, error=0x%08lx\n"),
  111. GetLastError()));
  112. }
  113. //
  114. // Do the class key migration stuff...
  115. //
  116. if (MigrateClassKeys(&buffer)) {
  117. //
  118. // Write the class key section to the sif file.
  119. //
  120. result = WriteSifSection(sifHandle,
  121. WINNT_CLASSKEYS,
  122. buffer,
  123. bAnsiSif); // Write sif section as ANSI
  124. if (!result) {
  125. DBGTRACE( DBGF_ERRORS,
  126. (TEXT("AsrCreatePnpStateFile: WriteSifSection failed for [%s], error=0x%08lx\n"),
  127. WINNT_CLASSKEYS, GetLastError()));
  128. }
  129. //
  130. // Free the allocated buffer.
  131. //
  132. LocalFree(buffer);
  133. buffer = NULL;
  134. } else {
  135. DBGTRACE( DBGF_ERRORS,
  136. (TEXT("AsrCreatePnpStateFile: MigrateClassKeys failed, error=0x%08lx\n"),
  137. GetLastError()));
  138. }
  139. //
  140. // Do the hash value migration stuff...
  141. //
  142. if (MigrateHashValues(&buffer)) {
  143. //
  144. // Write the hash value section to the sif file.
  145. //
  146. result = WriteSifSection(sifHandle,
  147. WINNT_DEVICEHASHVALUES,
  148. buffer,
  149. bAnsiSif); // Write sif section as ANSI?
  150. if (!result) {
  151. DBGTRACE( DBGF_ERRORS,
  152. (TEXT("AsrCreatePnpStateFile: WriteSifSection failed for [%s], error=0x%08lx\n"),
  153. WINNT_DEVICEHASHVALUES, GetLastError()));
  154. }
  155. //
  156. // Free the allocated buffer.
  157. //
  158. LocalFree(buffer);
  159. buffer = NULL;
  160. } else {
  161. DBGTRACE( DBGF_ERRORS,
  162. (TEXT("AsrCreatePnpStateFile: MigrateHashValues failed, error=0x%08lx\n"),
  163. GetLastError()));
  164. }
  165. //
  166. // Close the sif file.
  167. //
  168. if (sifHandle) {
  169. CloseHandle(sifHandle);
  170. }
  171. //
  172. // Reset the last error as successful in case we encountered a non-fatal
  173. // error along the way.
  174. //
  175. SetLastError(ERROR_SUCCESS);
  176. return TRUE;
  177. } // AsrCreatePnpStateFile()
  178. BOOL
  179. AsrCreatePnpStateFileA(
  180. IN PCSTR lpFilePath
  181. )
  182. /*++
  183. Routine Description:
  184. None.
  185. Arguments:
  186. None.
  187. Return Value:
  188. None.
  189. --*/
  190. {
  191. WCHAR wszFilePath[MAX_PATH + 1];
  192. //
  193. // Validate arguments.
  194. //
  195. if (!ARGUMENT_PRESENT(lpFilePath) ||
  196. strlen(lpFilePath) > MAX_PATH) {
  197. SetLastError(ERROR_INVALID_PARAMETER);
  198. return FALSE;
  199. }
  200. //
  201. // Convert the file path to a wide string.
  202. //
  203. memset(wszFilePath, 0, MAX_PATH + 1);
  204. if (!(MultiByteToWideChar(CP_ACP,
  205. 0,
  206. lpFilePath,
  207. -1,
  208. wszFilePath,
  209. MAX_PATH + 1))) {
  210. SetLastError(ERROR_INVALID_PARAMETER);
  211. return FALSE;
  212. }
  213. //
  214. // Return the result of calling the wide char version
  215. //
  216. return AsrCreatePnpStateFileW(wszFilePath);
  217. } // AsrCreatePnpStateFileA()
  218. BOOL
  219. CreateSifFileW(
  220. IN PCWSTR lpFilePath,
  221. IN BOOL bCreateNew,
  222. OUT LPHANDLE lpSifHandle
  223. )
  224. /*++
  225. Routine Description:
  226. None.
  227. Arguments:
  228. None.
  229. Return Value:
  230. None.
  231. --*/
  232. {
  233. HANDLE sifhandle = NULL;
  234. //
  235. // Validate arguments.
  236. //
  237. if (!ARGUMENT_PRESENT(lpFilePath) ||
  238. (wcslen(lpFilePath) > MAX_PATH) ||
  239. !ARGUMENT_PRESENT(lpSifHandle)) {
  240. SetLastError(ERROR_INVALID_PARAMETER);
  241. return FALSE;
  242. }
  243. //
  244. // Initialize output paramaters.
  245. //
  246. *lpSifHandle = NULL;
  247. //
  248. // Create the file. The handle will be closed by the caller, once they are
  249. // finished with it.
  250. //
  251. sifhandle = CreateFileW(lpFilePath,
  252. GENERIC_WRITE | GENERIC_READ,
  253. FILE_SHARE_READ,
  254. NULL,
  255. bCreateNew ? CREATE_ALWAYS : OPEN_EXISTING,
  256. FILE_FLAG_BACKUP_SEMANTICS,
  257. NULL);
  258. if ((sifhandle == NULL) ||
  259. (sifhandle == INVALID_HANDLE_VALUE)) {
  260. //
  261. // LastError already set by CreateFile.
  262. //
  263. return FALSE;
  264. }
  265. //
  266. // Return the sif handle to the caller only if successful.
  267. //
  268. *lpSifHandle = sifhandle;
  269. return TRUE;
  270. } // CreateSifFileW()
  271. BOOL
  272. WriteSifSection(
  273. IN CONST HANDLE SifHandle,
  274. IN PCTSTR SectionName,
  275. IN PCTSTR SectionData,
  276. IN BOOL Ansi
  277. )
  278. /*++
  279. Routine Description:
  280. None.
  281. Arguments:
  282. None.
  283. Return Value:
  284. None.
  285. --*/
  286. {
  287. BYTE buffer[(MAX_SIF_LINE+1)*sizeof(WCHAR)];
  288. DWORD dwSize, dwTempSize;
  289. PCTSTR p;
  290. //
  291. // Validate the arguments
  292. //
  293. if (!ARGUMENT_PRESENT(SifHandle) ||
  294. !ARGUMENT_PRESENT(SectionName) ||
  295. !ARGUMENT_PRESENT(SectionData)) {
  296. SetLastError(ERROR_INVALID_PARAMETER);
  297. return FALSE;
  298. }
  299. //
  300. // Write the section name to the sif file.
  301. //
  302. if (Ansi) {
  303. //
  304. // Write ANSI strings to the sif file
  305. //
  306. #if UNICODE
  307. wsprintfA((LPSTR)buffer, (LPCSTR)"[%ls]\r\n", SectionName);
  308. #else // ANSI
  309. wsprintfA((LPSTR)buffer, (LPCSTR)"[%s]\r\n", SectionName);
  310. #endif // UNICODE/ANSI
  311. dwSize = strlen((PSTR)buffer);
  312. } else {
  313. //
  314. // Write Unicode strings to the sif file
  315. //
  316. #if UNICODE
  317. wsprintfW((LPWSTR)buffer, (LPCWSTR)L"[%ws]\r\n", SectionName);
  318. #else // ANSI
  319. wsprintfW((LPWSTR)buffer, (LPCWSTR)L"[%S]\r\n", SectionName);
  320. #endif // UNICODE/ANSI
  321. dwSize = wcslen((PWSTR)buffer) * sizeof(WCHAR);
  322. }
  323. if (!WriteFile(SifHandle, buffer, dwSize, &dwTempSize, NULL)) {
  324. //
  325. // LastError already set by WriteFile
  326. //
  327. return FALSE;
  328. }
  329. DBGTRACE( DBGF_INFO,
  330. (TEXT("[%s]\n"), SectionName));
  331. //
  332. // Write the multi-sz section data to the file.
  333. //
  334. p = SectionData;
  335. while (*p) {
  336. if (Ansi) {
  337. //
  338. // Write ANSI strings to the sif file
  339. //
  340. #if UNICODE
  341. wsprintfA((LPSTR)buffer, (LPCSTR)"%ls\r\n", p);
  342. #else // ANSI
  343. wsprintfA((LPSTR)buffer, (LPCSTR)"%s\r\n", p);
  344. #endif // UNICODE/ANSI
  345. dwSize = strlen((PSTR)buffer);
  346. } else {
  347. //
  348. // Write Unicode strings to the sif file
  349. //
  350. #if UNICODE
  351. wsprintfW((LPWSTR)buffer, (LPCWSTR)L"%ws\r\n", p);
  352. #else // ANSI
  353. wsprintfW((LPWSTR)buffer, (LPCWSTR)L"%S\r\n", p);
  354. #endif // UNICODE/ANSI
  355. dwSize = wcslen((PWSTR)buffer) * sizeof(WCHAR);
  356. }
  357. if (!WriteFile(SifHandle, buffer, dwSize, &dwTempSize, NULL)) {
  358. //
  359. // LastError already set by WriteFile
  360. //
  361. return FALSE;
  362. }
  363. DBGTRACE( DBGF_INFO,
  364. (TEXT("%s\n"), p));
  365. //
  366. // Find the next string in the multi-sz
  367. //
  368. p += lstrlen(p) + 1;
  369. }
  370. return TRUE;
  371. } // WriteSifSection()
  372.