windows-nt/Source/XPSP1/NT/base/ntsetup/legacy/dll/cf.c
2020-09-26 16:20:57 +08:00

396 lines
9.9 KiB
C

#include "precomp.h"
#pragma hdrstop
/*++
Copyright (c) 1990 Microsoft Corporation
Module Name:
cf.c
Abstract:
1. Contains code to perform simple text substitutions on a text file.
2. Contains code to append text entries to a text file.
This module has no external dependencies and is not statically linked
to any part of Setup.
Author:
Ted Miller (tedm) July 1991
--*/
BOOL WriteData(HANDLE Handle,PVOID Data,DWORD DataSize);
BOOL
ConfigFileSubstWorker(
IN LPSTR File,
IN DWORD NumSubsts,
IN LPSTR *Substs
)
{
LPSTR CharPtr,old;
LPSTR FileBuf=NULL,FileBufEnd;
DWORD *StrLenArray;
DWORD FileLength = 0xffffffff;
HANDLE FileHandle = (HANDLE)(-1);
DWORD rcID;
BOOL Match;
DWORD x,i;
char CRLF[2];
BOOL IsCFGFile;
#define ORIGINAL_TEXT(i) Substs[(2*i)]
#define REPLACEMENT_TEXT(i) Substs[(2*i)+1]
#define ORIGINAL_TEXT_LENGTH(i) StrLenArray[i]
CRLF[0] = '\r';
CRLF[1] = '\n';
if((StrLenArray = SAlloc(NumSubsts * sizeof(DWORD))) == NULL) {
SetErrorText(IDS_ERROR_DLLOOM);
return(FALSE);
}
for(i=0; i<NumSubsts; i++) {
ORIGINAL_TEXT_LENGTH(i) = lstrlen(ORIGINAL_TEXT(i));
}
if(((FileHandle = CreateFile(File,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,0,NULL)) == (HANDLE)(-1))
|| ((FileLength = GetFileSize(FileHandle,NULL)) == 0xffffffff)
|| ((FileBuf = SAlloc(FileLength+1)) == NULL)
|| (ReadFile(FileHandle,FileBuf,FileLength,&i,NULL) == FALSE))
{
if(FileBuf != NULL) {
rcID = IDS_ERROR_READFAILED;
SFree(FileBuf);
} else if(FileLength != 0xffffffff) {
rcID = IDS_ERROR_DLLOOM;
} else if(FileHandle != (HANDLE)-1) {
rcID = IDS_ERROR_NOSIZE;
} else {
rcID = IDS_ERROR_BADFILE;
}
if(rcID != IDS_ERROR_BADFILE) {
CloseHandle(FileHandle);
}
SFree(StrLenArray);
SetErrorText(rcID);
return(FALSE);
}
CloseHandle(FileHandle);
if((FileHandle = CreateFile(File,GENERIC_WRITE,0,NULL,TRUNCATE_EXISTING,0,NULL)) == (HANDLE)(-1)) { // truncate
SFree(StrLenArray);
SFree(FileBuf);
SetErrorText(IDS_ERROR_BADFILE);
return(FALSE);
}
FileBufEnd = FileBuf + FileLength - 1;
if(*FileBufEnd != '\n') {
*(FileBufEnd+1) = '\n';
}
for(CharPtr = FileBuf; CharPtr <= FileBufEnd; CharPtr++) {
if(*CharPtr == '\n') {
*CharPtr = '\0';
}
}
if((x = lstrlen(File)) > 4) {
IsCFGFile = !lstrcmpi(&File[x-4],".cfg");
}
CharPtr = FileBuf-1;
while(++CharPtr <= FileBufEnd) { // skips NUL
while(*CharPtr) {
if(*CharPtr == '\r') {
CharPtr++;
continue;
}
// ignore comments in .cfg files
if(IsCFGFile && (*CharPtr == '/') && (*(CharPtr+1) == '/')) {
old = CharPtr;
while(*CharPtr && (*CharPtr != '\r')) {
CharPtr++;
}
if(!WriteData(FileHandle,old,(DWORD)(CharPtr - old))) {
goto xxx_err1;
}
if(*CharPtr == '\r') {
CharPtr++;
}
continue;
}
Match = FALSE;
for(i=0; i<NumSubsts && !Match; i++) {
if(!strncmp(ORIGINAL_TEXT(i),CharPtr,ORIGINAL_TEXT_LENGTH(i))) {
Match = TRUE;
if(!WriteData(FileHandle,REPLACEMENT_TEXT(i),lstrlen(REPLACEMENT_TEXT(i)))) {
goto xxx_err1;
}
CharPtr += ORIGINAL_TEXT_LENGTH(i);
}
}
if(!Match) {
if(!WriteData(FileHandle,CharPtr,1)) {
goto xxx_err1;
}
CharPtr++;
}
}
if(!WriteData(FileHandle,CRLF,sizeof(CRLF))) {
goto xxx_err1;
}
}
xxx_err1:
FlushFileBuffers(FileHandle);
CloseHandle(FileHandle);
SFree(StrLenArray);
SFree(FileBuf);
return(TRUE);
}
BOOL
BinaryFileSubstWorker(
IN LPSTR File,
IN DWORD NumSubsts,
IN LPSTR *Substs
)
{
LPSTR CharPtr;
LPSTR FileBuf=NULL;
DWORD *StrLenArray;
DWORD FileLength = 0xffffffff;
HANDLE FileHandle = (HANDLE)(-1);
DWORD rcID;
BOOL Match;
DWORD i;
if((StrLenArray = SAlloc(NumSubsts * sizeof(DWORD))) == NULL) {
SetErrorText(IDS_ERROR_DLLOOM);
return(FALSE);
}
// make sure original and replacement text are the same length
// within a given pair
for(i=0; i<NumSubsts; i++) {
ORIGINAL_TEXT_LENGTH(i) = lstrlen(ORIGINAL_TEXT(i));
if(ORIGINAL_TEXT_LENGTH(i) != (DWORD)lstrlen(REPLACEMENT_TEXT(i))) {
SFree(StrLenArray);
SetErrorText(IDS_ERROR_BADARGS);
return(FALSE);
}
}
if(((FileHandle = CreateFile(File,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,0,NULL)) == (HANDLE)(-1))
|| ((FileLength = GetFileSize(FileHandle,NULL)) == 0xffffffff)
|| ((FileBuf = SAlloc(FileLength)) == NULL)
|| (ReadFile(FileHandle,FileBuf,FileLength,&i,NULL) == FALSE))
{
if(FileBuf != NULL) {
rcID = IDS_ERROR_READFAILED;
SFree(FileBuf);
} else if(FileLength != 0xffffffff) {
rcID = IDS_ERROR_DLLOOM;
} else if(FileHandle != (HANDLE)-1) {
rcID = IDS_ERROR_NOSIZE;
} else {
rcID = IDS_ERROR_BADFILE;
}
if(rcID != IDS_ERROR_BADFILE) {
CloseHandle(FileHandle);
}
SFree(StrLenArray);
SetErrorText(rcID);
return(FALSE);
}
CloseHandle(FileHandle);
if((FileHandle = CreateFile(File,GENERIC_WRITE,0,NULL,TRUNCATE_EXISTING,0,NULL)) == (HANDLE)(-1)) { // truncate
SFree(StrLenArray);
SFree(FileBuf);
SetErrorText(IDS_ERROR_BADFILE);
return(FALSE);
}
for(CharPtr=FileBuf; CharPtr<FileBuf+FileLength; ) {
for(Match=FALSE,i=0; i<NumSubsts && !Match; i++) {
if(!strncmp(ORIGINAL_TEXT(i),CharPtr,ORIGINAL_TEXT_LENGTH(i))) {
Match = TRUE;
if(!WriteData(FileHandle,REPLACEMENT_TEXT(i),lstrlen(REPLACEMENT_TEXT(i)))) {
goto xxx_err2;
}
CharPtr += ORIGINAL_TEXT_LENGTH(i);
}
}
if(!Match) {
if(!WriteData(FileHandle,CharPtr,1)) {
goto xxx_err2;
}
CharPtr++;
}
}
xxx_err2:
FlushFileBuffers(FileHandle);
CloseHandle(FileHandle);
SFree(StrLenArray);
SFree(FileBuf);
return(TRUE);
}
BOOL
ConfigFileAppendWorker(
IN LPSTR File,
IN DWORD NumSubsts,
IN LPSTR *Substs
)
{
HANDLE FileHandle;
DWORD rcID;
DWORD i;
char CRLF[2];
DWORD OriginalAttributes;
OFSTRUCT ReOpen;
CRLF[0] = '\r';
CRLF[1] = '\n';
// See if file exists, if it doesn't open it with create option. else
// Open existing after modifying attributes to FILE_ATTRIBUTE_NORMAL
if (OpenFile(File,&ReOpen,OF_EXIST) == -1) {
OriginalAttributes = FILE_ATTRIBUTE_NORMAL;
FileHandle = CreateFile(
File,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
CREATE_NEW,
OriginalAttributes,
NULL
);
if (FileHandle == (HANDLE)-1) {
SetErrorText(IDS_ERROR_BADFILE);
return(FALSE);
}
}
else {
// 1. Modify Attributes
if (!(
((OriginalAttributes = GetFileAttributes(File)) != -1L)
&&
(
OriginalAttributes == FILE_ATTRIBUTE_NORMAL
||
SetFileAttributes(File, FILE_ATTRIBUTE_NORMAL)
)
)
) {
SetErrorText(IDS_ERROR_BADFILE);
return(FALSE);
}
// 2. Open the file
if((FileHandle = CreateFile(
File,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
0,
NULL
)) == (HANDLE)(-1)) {
rcID = IDS_ERROR_BADFILE;
SetErrorText(rcID);
return(FALSE);
}
// 3. Shift file pointer to end
if(SetFilePointer(
FileHandle, // The File Handle
0L, // Distance to move, low dword
0L, // Distance to move, high dword
FILE_END // Move Method, (relative to eof)
) == (DWORD)-1L){
rcID = IDS_ERROR_BADFILE;
CloseHandle(FileHandle);
SetErrorText(rcID);
return(FALSE);
}
} // end of else
// Append all the text entries to the end of the file
for (i = 0; i < NumSubsts; i++)
if(!WriteData (FileHandle, Substs[i], lstrlen(Substs[i])) ||
!WriteData(FileHandle,CRLF,sizeof(CRLF)))
break;
// Clean up
FlushFileBuffers(FileHandle);
CloseHandle(FileHandle);
// reset the attributes to the previous attributes
if(!(OriginalAttributes == FILE_ATTRIBUTE_NORMAL ||
SetFileAttributes(File, OriginalAttributes)))
SetErrorText(IDS_ERROR_BADFILE);
return(TRUE);
}
BOOL
WriteData(
IN HANDLE Handle,
IN PVOID Data,
IN DWORD DataSize
)
{
BOOL rc;
DWORD bw;
if(!(rc = WriteFile(Handle,Data,DataSize,&bw,NULL))) {
SetErrorText(IDS_ERROR_WRITE);
}
return(rc);
}