windows-nt/Source/XPSP1/NT/base/tools/instaler/ini.c
2020-09-26 16:20:57 +08:00

383 lines
9.6 KiB
C

/*++
Copyright (c) 1992 Microsoft Corporation
Module Name:
ini.c
Abstract:
This module implements the functions to save references to .INI file
sections and values for the INSTALER program. Part of each reference is
a a backup copy of sections and values for an .INI file.
Author:
Steve Wood (stevewo) 22-Aug-1994
Revision History:
--*/
#include "instaler.h"
BOOLEAN
CreateIniFileReference(
PWSTR Name,
PINI_FILE_REFERENCE *ReturnedReference
)
{
PINI_FILE_REFERENCE p;
PINI_SECTION_REFERENCE p1;
PINI_VARIABLE_REFERENCE p2;
PWSTR SectionName;
PWSTR VariableName;
PWSTR VariableValue;
UNICODE_STRING UnicodeString;
PLIST_ENTRY Head, Next;
ULONG n, n1;
BOOLEAN Result;
HANDLE FindHandle;
WIN32_FIND_DATA FindFileData;
p = FindIniFileReference( Name );
if (p != NULL) {
*ReturnedReference = p;
return TRUE;
}
p = AllocMem( sizeof( *p ) );
if (p == NULL) {
return FALSE;
}
p->Name = Name;
InitializeListHead( &p->SectionReferencesListHead );
InsertTailList( &IniReferenceListHead, &p->Entry );
FindHandle = FindFirstFile( Name, &FindFileData );
if (FindHandle == INVALID_HANDLE_VALUE) {
p->Created = TRUE;
*ReturnedReference = p;
return TRUE;
}
FindClose( FindHandle );
p->BackupLastWriteTime = FindFileData.ftLastWriteTime;
GrowTemporaryBuffer( n = 0xF000 );
SectionName = TemporaryBuffer;
Result = TRUE;
n1 = GetPrivateProfileStringW( NULL,
NULL,
L"",
SectionName,
n,
Name
);
if (n1 == 0 || n1 == n-2) {
Result = FALSE;
}
else {
while (*SectionName != UNICODE_NULL) {
p1 = AllocMem( sizeof( *p1 ) );
if (p1 == NULL) {
Result = FALSE;
break;
}
RtlInitUnicodeString( &UnicodeString, SectionName );
p1->Name = AddName( &UnicodeString );
if (FindIniSectionReference( p, p1->Name, FALSE )) {
FreeMem( &p1 );
}
else {
InitializeListHead( &p1->VariableReferencesListHead );
InsertTailList( &p->SectionReferencesListHead, &p1->Entry );
}
while (*SectionName++ != UNICODE_NULL) {
}
}
}
VariableName = TemporaryBuffer;
Head = &p->SectionReferencesListHead;
Next = Head->Flink;
while (Result && (Head != Next)) {
p1 = CONTAINING_RECORD( Next, INI_SECTION_REFERENCE, Entry );
n1 = GetPrivateProfileSectionW( p1->Name,
VariableName,
n,
Name
);
if (n1 == n-2) {
Result = FALSE;
break;
}
while (*VariableName != UNICODE_NULL) {
VariableValue = VariableName;
while (*VariableValue != UNICODE_NULL && *VariableValue != L'=') {
VariableValue += 1;
}
if (*VariableValue != L'=') {
Result = FALSE;
break;
}
*VariableValue++ = UNICODE_NULL;
p2 = AllocMem( sizeof( *p2 ) + ((wcslen( VariableValue ) + 1) * sizeof( WCHAR )) );
if (p2 == NULL) {
Result = FALSE;
break;
}
RtlInitUnicodeString( &UnicodeString, VariableName );
p2->Name = AddName( &UnicodeString );
p2->OriginalValue = (PWSTR)(p2+1);
wcscpy( p2->OriginalValue, VariableValue );
InsertTailList( &p1->VariableReferencesListHead, &p2->Entry );
VariableName = VariableValue;
while (*VariableName++ != UNICODE_NULL) {
}
}
Next = Next->Flink;
}
if (Result) {
*ReturnedReference = p;
}
else {
DestroyIniFileReference( p );
}
return Result;
}
BOOLEAN
DestroyIniFileReference(
PINI_FILE_REFERENCE p
)
{
PLIST_ENTRY Next, Head;
PINI_SECTION_REFERENCE p1;
Head = &p->SectionReferencesListHead;
Next = Head->Flink;
while (Head != Next) {
p1 = CONTAINING_RECORD( Next, INI_SECTION_REFERENCE, Entry );
Next = Next->Flink;
DestroyIniSectionReference( p1 );
}
RemoveEntryList( &p->Entry );
FreeMem( &p );
return TRUE;
}
BOOLEAN
DestroyIniSectionReference(
PINI_SECTION_REFERENCE p1
)
{
PLIST_ENTRY Next, Head;
PINI_VARIABLE_REFERENCE p2;
Head = &p1->VariableReferencesListHead;
Next = Head->Flink;
while (Head != Next) {
p2 = CONTAINING_RECORD( Next, INI_VARIABLE_REFERENCE, Entry );
Next = Next->Flink;
DestroyIniVariableReference( p2 );
}
RemoveEntryList( &p1->Entry );
FreeMem( &p1 );
return TRUE;
}
BOOLEAN
DestroyIniVariableReference(
PINI_VARIABLE_REFERENCE p2
)
{
RemoveEntryList( &p2->Entry );
FreeMem( &p2 );
return TRUE;
}
PINI_FILE_REFERENCE
FindIniFileReference(
PWSTR Name
)
{
PINI_FILE_REFERENCE p;
PLIST_ENTRY Next, Head;
Head = &IniReferenceListHead;
Next = Head->Flink;
while (Head != Next) {
p = CONTAINING_RECORD( Next, INI_FILE_REFERENCE, Entry );
if (p->Name == Name) {
return p;
}
Next = Next->Flink;
}
return NULL;
}
PINI_SECTION_REFERENCE
FindIniSectionReference(
PINI_FILE_REFERENCE p,
PWSTR Name,
BOOLEAN CreateOkay
)
{
PLIST_ENTRY Next, Head;
PINI_SECTION_REFERENCE p1;
Head = &p->SectionReferencesListHead;
Next = Head->Flink;
while (Head != Next) {
p1 = CONTAINING_RECORD( Next, INI_SECTION_REFERENCE, Entry );
if (p1->Name == Name) {
return p1;
}
Next = Next->Flink;
}
if (CreateOkay) {
p1 = AllocMem( sizeof( *p1 ) );
if (p1 != NULL) {
p1->Created = TRUE;
p1->Name = Name;
InitializeListHead( &p1->VariableReferencesListHead );
InsertTailList( &p->SectionReferencesListHead, &p1->Entry );
}
}
else {
p1 = NULL;
}
return p1;
}
PINI_VARIABLE_REFERENCE
FindIniVariableReference(
PINI_SECTION_REFERENCE p1,
PWSTR Name,
BOOLEAN CreateOkay
)
{
PLIST_ENTRY Next, Head;
PINI_VARIABLE_REFERENCE p2;
Head = &p1->VariableReferencesListHead;
Next = Head->Flink;
while (Head != Next) {
p2 = CONTAINING_RECORD( Next, INI_VARIABLE_REFERENCE, Entry );
if (p2->Name == Name) {
return p2;
}
Next = Next->Flink;
}
if (CreateOkay) {
p2 = AllocMem( sizeof( *p2 ) );
if (p2 != NULL) {
p2->Created = TRUE;
p2->Name = Name;
InsertTailList( &p1->VariableReferencesListHead, &p2->Entry );
}
}
else {
p2 = NULL;
}
return p2;
}
VOID
DumpIniFileReferenceList(
FILE *LogFile
)
{
PINI_FILE_REFERENCE p;
PINI_SECTION_REFERENCE p1;
PINI_VARIABLE_REFERENCE p2;
PLIST_ENTRY Head, Next;
PLIST_ENTRY Head1, Next1;
PLIST_ENTRY Head2, Next2;
POFFSET Variables;
POFFSET Sections;
Head = &IniReferenceListHead;
Next = Head->Blink;
while (Head != Next) {
p = CONTAINING_RECORD( Next, INI_FILE_REFERENCE, Entry );
Sections = 0;
Head1 = &p->SectionReferencesListHead;
Next1 = Head1->Blink;
while (Head1 != Next1) {
p1 = CONTAINING_RECORD( Next1, INI_SECTION_REFERENCE, Entry );
Variables = 0;
Head2 = &p1->VariableReferencesListHead;
Next2 = Head2->Blink;
while (Head2 != Next2) {
p2 = CONTAINING_RECORD( Next2, INI_VARIABLE_REFERENCE, Entry );
if (p2->Created || p2->Deleted || p2->Modified) {
ImlAddIniVariableRecord( pImlNew,
p2->Created ? CreateNewVariable :
p2->Deleted ? DeleteOldVariable : ModifyOldVariable,
p2->Name,
p2->OriginalValue,
p2->Value,
&Variables
);
}
Next2 = Next2->Blink;
}
if (Variables != 0) {
ImlAddIniSectionRecord( pImlNew,
p1->Created ? CreateNewSection :
p1->Deleted ? DeleteOldSection : ModifySectionVariables,
p1->Name,
Variables,
&Sections
);
}
Next1 = Next1->Blink;
}
if (Sections != 0) {
ImlAddIniRecord( pImlNew,
p->Created ? CreateNewIniFile : ModifyOldIniFile,
p->Name,
&p->BackupLastWriteTime,
Sections
);
}
Next = Next->Blink;
}
return;
}