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.

382 lines
9.6 KiB

  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. ini.c
  5. Abstract:
  6. This module implements the functions to save references to .INI file
  7. sections and values for the INSTALER program. Part of each reference is
  8. a a backup copy of sections and values for an .INI file.
  9. Author:
  10. Steve Wood (stevewo) 22-Aug-1994
  11. Revision History:
  12. --*/
  13. #include "instaler.h"
  14. BOOLEAN
  15. CreateIniFileReference(
  16. PWSTR Name,
  17. PINI_FILE_REFERENCE *ReturnedReference
  18. )
  19. {
  20. PINI_FILE_REFERENCE p;
  21. PINI_SECTION_REFERENCE p1;
  22. PINI_VARIABLE_REFERENCE p2;
  23. PWSTR SectionName;
  24. PWSTR VariableName;
  25. PWSTR VariableValue;
  26. UNICODE_STRING UnicodeString;
  27. PLIST_ENTRY Head, Next;
  28. ULONG n, n1;
  29. BOOLEAN Result;
  30. HANDLE FindHandle;
  31. WIN32_FIND_DATA FindFileData;
  32. p = FindIniFileReference( Name );
  33. if (p != NULL) {
  34. *ReturnedReference = p;
  35. return TRUE;
  36. }
  37. p = AllocMem( sizeof( *p ) );
  38. if (p == NULL) {
  39. return FALSE;
  40. }
  41. p->Name = Name;
  42. InitializeListHead( &p->SectionReferencesListHead );
  43. InsertTailList( &IniReferenceListHead, &p->Entry );
  44. FindHandle = FindFirstFile( Name, &FindFileData );
  45. if (FindHandle == INVALID_HANDLE_VALUE) {
  46. p->Created = TRUE;
  47. *ReturnedReference = p;
  48. return TRUE;
  49. }
  50. FindClose( FindHandle );
  51. p->BackupLastWriteTime = FindFileData.ftLastWriteTime;
  52. GrowTemporaryBuffer( n = 0xF000 );
  53. SectionName = TemporaryBuffer;
  54. Result = TRUE;
  55. n1 = GetPrivateProfileStringW( NULL,
  56. NULL,
  57. L"",
  58. SectionName,
  59. n,
  60. Name
  61. );
  62. if (n1 == 0 || n1 == n-2) {
  63. Result = FALSE;
  64. }
  65. else {
  66. while (*SectionName != UNICODE_NULL) {
  67. p1 = AllocMem( sizeof( *p1 ) );
  68. if (p1 == NULL) {
  69. Result = FALSE;
  70. break;
  71. }
  72. RtlInitUnicodeString( &UnicodeString, SectionName );
  73. p1->Name = AddName( &UnicodeString );
  74. if (FindIniSectionReference( p, p1->Name, FALSE )) {
  75. FreeMem( &p1 );
  76. }
  77. else {
  78. InitializeListHead( &p1->VariableReferencesListHead );
  79. InsertTailList( &p->SectionReferencesListHead, &p1->Entry );
  80. }
  81. while (*SectionName++ != UNICODE_NULL) {
  82. }
  83. }
  84. }
  85. VariableName = TemporaryBuffer;
  86. Head = &p->SectionReferencesListHead;
  87. Next = Head->Flink;
  88. while (Result && (Head != Next)) {
  89. p1 = CONTAINING_RECORD( Next, INI_SECTION_REFERENCE, Entry );
  90. n1 = GetPrivateProfileSectionW( p1->Name,
  91. VariableName,
  92. n,
  93. Name
  94. );
  95. if (n1 == n-2) {
  96. Result = FALSE;
  97. break;
  98. }
  99. while (*VariableName != UNICODE_NULL) {
  100. VariableValue = VariableName;
  101. while (*VariableValue != UNICODE_NULL && *VariableValue != L'=') {
  102. VariableValue += 1;
  103. }
  104. if (*VariableValue != L'=') {
  105. Result = FALSE;
  106. break;
  107. }
  108. *VariableValue++ = UNICODE_NULL;
  109. p2 = AllocMem( sizeof( *p2 ) + ((wcslen( VariableValue ) + 1) * sizeof( WCHAR )) );
  110. if (p2 == NULL) {
  111. Result = FALSE;
  112. break;
  113. }
  114. RtlInitUnicodeString( &UnicodeString, VariableName );
  115. p2->Name = AddName( &UnicodeString );
  116. p2->OriginalValue = (PWSTR)(p2+1);
  117. wcscpy( p2->OriginalValue, VariableValue );
  118. InsertTailList( &p1->VariableReferencesListHead, &p2->Entry );
  119. VariableName = VariableValue;
  120. while (*VariableName++ != UNICODE_NULL) {
  121. }
  122. }
  123. Next = Next->Flink;
  124. }
  125. if (Result) {
  126. *ReturnedReference = p;
  127. }
  128. else {
  129. DestroyIniFileReference( p );
  130. }
  131. return Result;
  132. }
  133. BOOLEAN
  134. DestroyIniFileReference(
  135. PINI_FILE_REFERENCE p
  136. )
  137. {
  138. PLIST_ENTRY Next, Head;
  139. PINI_SECTION_REFERENCE p1;
  140. Head = &p->SectionReferencesListHead;
  141. Next = Head->Flink;
  142. while (Head != Next) {
  143. p1 = CONTAINING_RECORD( Next, INI_SECTION_REFERENCE, Entry );
  144. Next = Next->Flink;
  145. DestroyIniSectionReference( p1 );
  146. }
  147. RemoveEntryList( &p->Entry );
  148. FreeMem( &p );
  149. return TRUE;
  150. }
  151. BOOLEAN
  152. DestroyIniSectionReference(
  153. PINI_SECTION_REFERENCE p1
  154. )
  155. {
  156. PLIST_ENTRY Next, Head;
  157. PINI_VARIABLE_REFERENCE p2;
  158. Head = &p1->VariableReferencesListHead;
  159. Next = Head->Flink;
  160. while (Head != Next) {
  161. p2 = CONTAINING_RECORD( Next, INI_VARIABLE_REFERENCE, Entry );
  162. Next = Next->Flink;
  163. DestroyIniVariableReference( p2 );
  164. }
  165. RemoveEntryList( &p1->Entry );
  166. FreeMem( &p1 );
  167. return TRUE;
  168. }
  169. BOOLEAN
  170. DestroyIniVariableReference(
  171. PINI_VARIABLE_REFERENCE p2
  172. )
  173. {
  174. RemoveEntryList( &p2->Entry );
  175. FreeMem( &p2 );
  176. return TRUE;
  177. }
  178. PINI_FILE_REFERENCE
  179. FindIniFileReference(
  180. PWSTR Name
  181. )
  182. {
  183. PINI_FILE_REFERENCE p;
  184. PLIST_ENTRY Next, Head;
  185. Head = &IniReferenceListHead;
  186. Next = Head->Flink;
  187. while (Head != Next) {
  188. p = CONTAINING_RECORD( Next, INI_FILE_REFERENCE, Entry );
  189. if (p->Name == Name) {
  190. return p;
  191. }
  192. Next = Next->Flink;
  193. }
  194. return NULL;
  195. }
  196. PINI_SECTION_REFERENCE
  197. FindIniSectionReference(
  198. PINI_FILE_REFERENCE p,
  199. PWSTR Name,
  200. BOOLEAN CreateOkay
  201. )
  202. {
  203. PLIST_ENTRY Next, Head;
  204. PINI_SECTION_REFERENCE p1;
  205. Head = &p->SectionReferencesListHead;
  206. Next = Head->Flink;
  207. while (Head != Next) {
  208. p1 = CONTAINING_RECORD( Next, INI_SECTION_REFERENCE, Entry );
  209. if (p1->Name == Name) {
  210. return p1;
  211. }
  212. Next = Next->Flink;
  213. }
  214. if (CreateOkay) {
  215. p1 = AllocMem( sizeof( *p1 ) );
  216. if (p1 != NULL) {
  217. p1->Created = TRUE;
  218. p1->Name = Name;
  219. InitializeListHead( &p1->VariableReferencesListHead );
  220. InsertTailList( &p->SectionReferencesListHead, &p1->Entry );
  221. }
  222. }
  223. else {
  224. p1 = NULL;
  225. }
  226. return p1;
  227. }
  228. PINI_VARIABLE_REFERENCE
  229. FindIniVariableReference(
  230. PINI_SECTION_REFERENCE p1,
  231. PWSTR Name,
  232. BOOLEAN CreateOkay
  233. )
  234. {
  235. PLIST_ENTRY Next, Head;
  236. PINI_VARIABLE_REFERENCE p2;
  237. Head = &p1->VariableReferencesListHead;
  238. Next = Head->Flink;
  239. while (Head != Next) {
  240. p2 = CONTAINING_RECORD( Next, INI_VARIABLE_REFERENCE, Entry );
  241. if (p2->Name == Name) {
  242. return p2;
  243. }
  244. Next = Next->Flink;
  245. }
  246. if (CreateOkay) {
  247. p2 = AllocMem( sizeof( *p2 ) );
  248. if (p2 != NULL) {
  249. p2->Created = TRUE;
  250. p2->Name = Name;
  251. InsertTailList( &p1->VariableReferencesListHead, &p2->Entry );
  252. }
  253. }
  254. else {
  255. p2 = NULL;
  256. }
  257. return p2;
  258. }
  259. VOID
  260. DumpIniFileReferenceList(
  261. FILE *LogFile
  262. )
  263. {
  264. PINI_FILE_REFERENCE p;
  265. PINI_SECTION_REFERENCE p1;
  266. PINI_VARIABLE_REFERENCE p2;
  267. PLIST_ENTRY Head, Next;
  268. PLIST_ENTRY Head1, Next1;
  269. PLIST_ENTRY Head2, Next2;
  270. POFFSET Variables;
  271. POFFSET Sections;
  272. Head = &IniReferenceListHead;
  273. Next = Head->Blink;
  274. while (Head != Next) {
  275. p = CONTAINING_RECORD( Next, INI_FILE_REFERENCE, Entry );
  276. Sections = 0;
  277. Head1 = &p->SectionReferencesListHead;
  278. Next1 = Head1->Blink;
  279. while (Head1 != Next1) {
  280. p1 = CONTAINING_RECORD( Next1, INI_SECTION_REFERENCE, Entry );
  281. Variables = 0;
  282. Head2 = &p1->VariableReferencesListHead;
  283. Next2 = Head2->Blink;
  284. while (Head2 != Next2) {
  285. p2 = CONTAINING_RECORD( Next2, INI_VARIABLE_REFERENCE, Entry );
  286. if (p2->Created || p2->Deleted || p2->Modified) {
  287. ImlAddIniVariableRecord( pImlNew,
  288. p2->Created ? CreateNewVariable :
  289. p2->Deleted ? DeleteOldVariable : ModifyOldVariable,
  290. p2->Name,
  291. p2->OriginalValue,
  292. p2->Value,
  293. &Variables
  294. );
  295. }
  296. Next2 = Next2->Blink;
  297. }
  298. if (Variables != 0) {
  299. ImlAddIniSectionRecord( pImlNew,
  300. p1->Created ? CreateNewSection :
  301. p1->Deleted ? DeleteOldSection : ModifySectionVariables,
  302. p1->Name,
  303. Variables,
  304. &Sections
  305. );
  306. }
  307. Next1 = Next1->Blink;
  308. }
  309. if (Sections != 0) {
  310. ImlAddIniRecord( pImlNew,
  311. p->Created ? CreateNewIniFile : ModifyOldIniFile,
  312. p->Name,
  313. &p->BackupLastWriteTime,
  314. Sections
  315. );
  316. }
  317. Next = Next->Blink;
  318. }
  319. return;
  320. }