Leaked source code of windows server 2003
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.

490 lines
14 KiB

  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. iml.c
  5. Abstract:
  6. This module contains routines for creating and accessing Installation
  7. Modification Log files (.IML)
  8. Author:
  9. Steve Wood (stevewo) 15-Jan-1996
  10. Revision History:
  11. --*/
  12. #include "instutil.h"
  13. #include "iml.h"
  14. PWSTR
  15. FormatImlPath(
  16. PWSTR DirectoryPath,
  17. PWSTR InstallationName
  18. )
  19. {
  20. PWSTR imlPath;
  21. ULONG n;
  22. n = wcslen( DirectoryPath ) + wcslen( InstallationName ) + 8;
  23. imlPath = HeapAlloc( GetProcessHeap(), 0, (n * sizeof( WCHAR )) );
  24. if (imlPath != NULL) {
  25. _snwprintf( imlPath, n, L"%s%s.IML", DirectoryPath, InstallationName );
  26. //
  27. // Make sure we NULL terminate it
  28. //
  29. imlPath[n - 1] = 0;
  30. }
  31. return imlPath;
  32. }
  33. PINSTALLATION_MODIFICATION_LOGFILE
  34. CreateIml(
  35. PWSTR ImlPath,
  36. BOOLEAN IncludeCreateFileContents
  37. )
  38. {
  39. HANDLE FileHandle;
  40. PINSTALLATION_MODIFICATION_LOGFILE pIml;
  41. pIml = NULL;
  42. FileHandle = CreateFile( ImlPath,
  43. GENERIC_READ | GENERIC_WRITE,
  44. FILE_SHARE_READ,
  45. NULL,
  46. OPEN_ALWAYS,
  47. 0,
  48. NULL
  49. );
  50. if (FileHandle == INVALID_HANDLE_VALUE) {
  51. return NULL;
  52. }
  53. pIml = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof( *pIml ) );
  54. if (pIml == NULL) {
  55. CloseHandle( FileHandle );
  56. return NULL;
  57. }
  58. pIml->Signature = IML_SIGNATURE;
  59. pIml->FileHandle = FileHandle;
  60. pIml->FileOffset = ROUND_UP( sizeof( *pIml ), 8 );
  61. if (IncludeCreateFileContents) {
  62. pIml->Flags = IML_FLAG_CONTAINS_NEWFILECONTENTS;
  63. }
  64. SetFilePointer( pIml->FileHandle, pIml->FileOffset, NULL, FILE_BEGIN );
  65. return pIml;
  66. }
  67. PINSTALLATION_MODIFICATION_LOGFILE
  68. LoadIml(
  69. PWSTR ImlPath
  70. )
  71. {
  72. HANDLE FileHandle, MappingHandle;
  73. PINSTALLATION_MODIFICATION_LOGFILE pIml;
  74. pIml = NULL;
  75. FileHandle = CreateFile( ImlPath,
  76. GENERIC_READ,
  77. FILE_SHARE_READ,
  78. NULL,
  79. OPEN_EXISTING,
  80. 0,
  81. NULL
  82. );
  83. if (FileHandle != INVALID_HANDLE_VALUE) {
  84. MappingHandle = CreateFileMapping( FileHandle,
  85. NULL,
  86. PAGE_READONLY,
  87. 0,
  88. 0,
  89. NULL
  90. );
  91. CloseHandle( FileHandle );
  92. if (MappingHandle != NULL) {
  93. pIml = MapViewOfFile( MappingHandle,
  94. FILE_MAP_READ,
  95. 0,
  96. 0,
  97. 0
  98. );
  99. CloseHandle( MappingHandle );
  100. if (pIml != NULL) {
  101. if (pIml->Signature != IML_SIGNATURE) {
  102. UnmapViewOfFile( pIml );
  103. pIml = NULL;
  104. SetLastError( ERROR_BAD_FORMAT );
  105. }
  106. }
  107. }
  108. }
  109. return pIml;
  110. }
  111. BOOLEAN
  112. CloseIml(
  113. PINSTALLATION_MODIFICATION_LOGFILE pIml
  114. )
  115. {
  116. HANDLE FileHandle;
  117. BOOLEAN Result;
  118. ULONG BytesWritten;
  119. if (pIml->FileHandle == NULL) {
  120. if (!UnmapViewOfFile( pIml )) {
  121. return FALSE;
  122. }
  123. else {
  124. Result = TRUE;
  125. }
  126. }
  127. else {
  128. FileHandle = pIml->FileHandle;
  129. pIml->FileHandle = NULL;
  130. if (!SetEndOfFile( FileHandle ) ||
  131. SetFilePointer( FileHandle, 0, NULL, FILE_BEGIN ) != 0 ||
  132. !WriteFile( FileHandle,
  133. pIml,
  134. sizeof( *pIml ),
  135. &BytesWritten,
  136. NULL
  137. ) ||
  138. BytesWritten != sizeof( *pIml )
  139. ) {
  140. Result = FALSE;
  141. }
  142. else {
  143. Result = TRUE;
  144. }
  145. CloseHandle( FileHandle );
  146. }
  147. return Result;
  148. }
  149. POFFSET
  150. ImlWrite(
  151. PINSTALLATION_MODIFICATION_LOGFILE pIml,
  152. PVOID p,
  153. ULONG Size
  154. )
  155. {
  156. POFFSET Result;
  157. ULONG BytesWritten;
  158. if (!WriteFile( pIml->FileHandle,
  159. p,
  160. Size,
  161. &BytesWritten,
  162. NULL
  163. ) ||
  164. BytesWritten != Size
  165. ) {
  166. return 0;
  167. }
  168. Result = pIml->FileOffset;
  169. pIml->FileOffset += ROUND_UP( Size, 8 );
  170. SetFilePointer( pIml->FileHandle,
  171. pIml->FileOffset,
  172. NULL,
  173. FILE_BEGIN
  174. );
  175. return Result;
  176. }
  177. POFFSET
  178. ImlWriteString(
  179. PINSTALLATION_MODIFICATION_LOGFILE pIml,
  180. PWSTR Name
  181. )
  182. {
  183. if (Name == NULL) {
  184. return 0;
  185. }
  186. else {
  187. return ImlWrite( pIml, Name, (wcslen( Name ) + 1) * sizeof( WCHAR ) );
  188. }
  189. }
  190. POFFSET
  191. ImlWriteFileContents(
  192. PINSTALLATION_MODIFICATION_LOGFILE pIml,
  193. PWSTR FileName
  194. )
  195. {
  196. HANDLE hFindFirst, hFile, hMapping;
  197. WIN32_FIND_DATA FindFileData;
  198. PVOID p;
  199. IML_FILE_RECORD_CONTENTS ImlFileContentsRecord;
  200. hFindFirst = FindFirstFile( FileName, &FindFileData );
  201. if (hFindFirst == INVALID_HANDLE_VALUE) {
  202. return 0;
  203. }
  204. FindClose( hFindFirst );
  205. ImlFileContentsRecord.LastWriteTime = FindFileData.ftLastWriteTime;
  206. ImlFileContentsRecord.FileAttributes = FindFileData.dwFileAttributes;
  207. if (!(ImlFileContentsRecord.FileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
  208. ImlFileContentsRecord.FileSize = FindFileData.nFileSizeLow;
  209. hFile = CreateFile( FileName,
  210. GENERIC_READ,
  211. FILE_SHARE_READ,
  212. NULL,
  213. OPEN_EXISTING,
  214. 0,
  215. NULL
  216. );
  217. if (hFile == INVALID_HANDLE_VALUE) {
  218. printf( "*** CreateFile( '%ws' ) failed (%u)\n", FileName, GetLastError() );
  219. return 0;
  220. }
  221. if (ImlFileContentsRecord.FileSize != 0) {
  222. hMapping = CreateFileMapping( hFile,
  223. NULL,
  224. PAGE_READONLY,
  225. 0,
  226. 0,
  227. NULL
  228. );
  229. CloseHandle( hFile );
  230. hFile = NULL;
  231. if (hMapping == NULL) {
  232. printf( "*** CreateFileMapping( '%ws' ) failed (%u)\n", FileName, GetLastError() );
  233. return 0;
  234. }
  235. p = MapViewOfFile( hMapping,
  236. FILE_MAP_READ,
  237. 0,
  238. 0,
  239. 0
  240. );
  241. CloseHandle( hMapping );
  242. if (p == NULL) {
  243. printf( "*** MapViewOfFile( '%ws' ) failed (%u)\n", FileName, GetLastError() );
  244. return 0;
  245. }
  246. }
  247. else {
  248. CloseHandle( hFile );
  249. p = NULL;
  250. }
  251. }
  252. else {
  253. ImlFileContentsRecord.FileSize = 0;
  254. p = NULL;
  255. }
  256. ImlFileContentsRecord.Contents = ImlWrite( pIml, p, ImlFileContentsRecord.FileSize );
  257. if (p != NULL) {
  258. UnmapViewOfFile( p );
  259. }
  260. return ImlWrite( pIml,
  261. &ImlFileContentsRecord,
  262. sizeof( ImlFileContentsRecord )
  263. );
  264. }
  265. BOOLEAN
  266. ImlAddFileRecord(
  267. PINSTALLATION_MODIFICATION_LOGFILE pIml,
  268. IML_FILE_ACTION Action,
  269. PWSTR Name,
  270. PWSTR BackupFileName,
  271. PFILETIME BackupLastWriteTime,
  272. DWORD BackupFileAttributes
  273. )
  274. {
  275. IML_FILE_RECORD ImlFileRecord;
  276. IML_FILE_RECORD_CONTENTS ImlFileContentsRecord;
  277. memset( &ImlFileRecord, 0, sizeof( ImlFileRecord ) );
  278. ImlFileRecord.Action = Action;
  279. ImlFileRecord.Name = ImlWriteString( pIml, Name );
  280. if (Action == CreateNewFile) {
  281. if ((pIml->Flags & IML_FLAG_CONTAINS_NEWFILECONTENTS) != 0) {
  282. ImlFileRecord.NewFile = ImlWriteFileContents( pIml, Name );
  283. }
  284. }
  285. else
  286. if (Action == ModifyOldFile ||
  287. Action == DeleteOldFile
  288. ) {
  289. if (BackupFileName != NULL) {
  290. ImlFileRecord.OldFile = ImlWriteFileContents( pIml, BackupFileName );
  291. }
  292. if (Action == ModifyOldFile &&
  293. (pIml->Flags & IML_FLAG_CONTAINS_NEWFILECONTENTS) != 0
  294. ) {
  295. ImlFileRecord.NewFile = ImlWriteFileContents( pIml, Name );
  296. }
  297. }
  298. else {
  299. ImlFileContentsRecord.LastWriteTime = *BackupLastWriteTime;
  300. ImlFileContentsRecord.FileAttributes = BackupFileAttributes;
  301. ImlFileContentsRecord.FileSize = 0;
  302. ImlFileContentsRecord.Contents = 0;
  303. ImlFileRecord.OldFile = ImlWrite( pIml,
  304. &ImlFileContentsRecord,
  305. sizeof( ImlFileContentsRecord )
  306. );
  307. }
  308. ImlFileRecord.Next = pIml->FileRecords;
  309. pIml->FileRecords = ImlWrite( pIml, &ImlFileRecord, sizeof( ImlFileRecord ) );
  310. pIml->NumberOfFileRecords += 1;
  311. return TRUE;
  312. }
  313. BOOLEAN
  314. ImlAddValueRecord(
  315. PINSTALLATION_MODIFICATION_LOGFILE pIml,
  316. IML_VALUE_ACTION Action,
  317. PWSTR Name,
  318. DWORD ValueType,
  319. ULONG ValueLength,
  320. PVOID ValueData,
  321. DWORD BackupValueType,
  322. ULONG BackupValueLength,
  323. PVOID BackupValueData,
  324. POFFSET *Values
  325. )
  326. {
  327. IML_VALUE_RECORD ImlValueRecord;
  328. IML_VALUE_RECORD_CONTENTS ImlValueContentsRecord;
  329. memset( &ImlValueRecord, 0, sizeof( ImlValueRecord ) );
  330. ImlValueRecord.Action = Action;
  331. ImlValueRecord.Name = ImlWriteString( pIml, Name );
  332. if (Action != DeleteOldValue) {
  333. ImlValueContentsRecord.Type = ValueType;
  334. ImlValueContentsRecord.Length = ValueLength;
  335. ImlValueContentsRecord.Data = ImlWrite( pIml, ValueData, ValueLength );
  336. ImlValueRecord.NewValue = ImlWrite( pIml,
  337. &ImlValueContentsRecord,
  338. sizeof( ImlValueContentsRecord )
  339. );
  340. }
  341. if (Action != CreateNewValue) {
  342. ImlValueContentsRecord.Type = BackupValueType;
  343. ImlValueContentsRecord.Length = BackupValueLength;
  344. ImlValueContentsRecord.Data = ImlWrite( pIml, BackupValueData, BackupValueLength );
  345. ImlValueRecord.OldValue = ImlWrite( pIml,
  346. &ImlValueContentsRecord,
  347. sizeof( ImlValueContentsRecord )
  348. );
  349. }
  350. ImlValueRecord.Next = *Values;
  351. *Values = ImlWrite( pIml, &ImlValueRecord, sizeof( ImlValueRecord ) );
  352. return TRUE;
  353. }
  354. BOOLEAN
  355. ImlAddKeyRecord(
  356. PINSTALLATION_MODIFICATION_LOGFILE pIml,
  357. IML_KEY_ACTION Action,
  358. PWSTR Name,
  359. POFFSET Values
  360. )
  361. {
  362. IML_KEY_RECORD ImlKeyRecord;
  363. memset( &ImlKeyRecord, 0, sizeof( ImlKeyRecord ) );
  364. ImlKeyRecord.Action = Action;
  365. ImlKeyRecord.Name = ImlWriteString( pIml, Name );
  366. ImlKeyRecord.Values = Values;
  367. ImlKeyRecord.Next = pIml->KeyRecords;
  368. pIml->KeyRecords = ImlWrite( pIml, &ImlKeyRecord, sizeof( ImlKeyRecord ) );
  369. pIml->NumberOfKeyRecords += 1;
  370. return TRUE;
  371. }
  372. BOOLEAN
  373. ImlAddIniVariableRecord(
  374. PINSTALLATION_MODIFICATION_LOGFILE pIml,
  375. IML_INIVARIABLE_ACTION Action,
  376. PWSTR Name,
  377. PWSTR OldValue,
  378. PWSTR NewValue,
  379. POFFSET *Variables
  380. )
  381. {
  382. IML_INIVARIABLE_RECORD ImlIniVariableRecord;
  383. memset( &ImlIniVariableRecord, 0, sizeof( ImlIniVariableRecord ) );
  384. ImlIniVariableRecord.Action = Action;
  385. ImlIniVariableRecord.Name = ImlWriteString( pIml, Name );
  386. ImlIniVariableRecord.OldValue = ImlWriteString( pIml, OldValue );
  387. ImlIniVariableRecord.NewValue = ImlWriteString( pIml, NewValue );
  388. ImlIniVariableRecord.Next = *Variables;
  389. *Variables = ImlWrite( pIml, &ImlIniVariableRecord, sizeof( ImlIniVariableRecord ) );
  390. return TRUE;
  391. }
  392. BOOLEAN
  393. ImlAddIniSectionRecord(
  394. PINSTALLATION_MODIFICATION_LOGFILE pIml,
  395. IML_INISECTION_ACTION Action,
  396. PWSTR Name,
  397. POFFSET Variables,
  398. POFFSET *Sections
  399. )
  400. {
  401. IML_INISECTION_RECORD ImlIniSectionRecord;
  402. memset( &ImlIniSectionRecord, 0, sizeof( ImlIniSectionRecord ) );
  403. ImlIniSectionRecord.Action = Action;
  404. ImlIniSectionRecord.Name = ImlWriteString( pIml, Name );
  405. ImlIniSectionRecord.Variables = Variables;
  406. ImlIniSectionRecord.Next = *Sections;
  407. *Sections = ImlWrite( pIml, &ImlIniSectionRecord, sizeof( ImlIniSectionRecord ) );
  408. return TRUE;
  409. }
  410. BOOLEAN
  411. ImlAddIniRecord(
  412. PINSTALLATION_MODIFICATION_LOGFILE pIml,
  413. IML_INI_ACTION Action,
  414. PWSTR Name,
  415. PFILETIME BackupLastWriteTime,
  416. POFFSET Sections
  417. )
  418. {
  419. IML_INI_RECORD ImlIniRecord;
  420. memset( &ImlIniRecord, 0, sizeof( ImlIniRecord ) );
  421. ImlIniRecord.Action = Action;
  422. ImlIniRecord.Name = ImlWriteString( pIml, Name );
  423. ImlIniRecord.LastWriteTime = *BackupLastWriteTime;
  424. ImlIniRecord.Sections = Sections;
  425. ImlIniRecord.Next = pIml->IniRecords;
  426. pIml->IniRecords = ImlWrite( pIml, &ImlIniRecord, sizeof( ImlIniRecord ) );
  427. pIml->NumberOfIniRecords += 1;
  428. return TRUE;
  429. }