|
|
/*++
Copyright (c) 1993-1994 Microsoft Corporation
Module Name: fileutl.c
Abstract: Routines for getting data from ini file
Author: HonWah Chan (a-honwah) October, 1993
Revision History: --*/
#include "initodat.h"
#include "strids.h"
#include "common.h"
#include "winerror.h"
NTSTATUS DatReadMultiSzFile( #ifdef FE_SB
UINT uCodePage, #endif
PUNICODE_STRING FileName, PVOID * ValueBuffer, PULONG ValueLength ) { NTSTATUS Status = STATUS_SUCCESS; UNICODE_STRING NtFileName; LPWSTR s; UNICODE_STRING MultiSource; UNICODE_STRING MultiValue; REG_UNICODE_FILE MultiSzFile; ULONG MultiSzFileSize;
ZeroMemory(& NtFileName, sizeof(UNICODE_STRING)); if (ValueBuffer == NULL || ValueLength == NULL) { Status = STATUS_INVALID_PARAMETER; goto Cleanup; }
FileName->Buffer[FileName->Length / sizeof(WCHAR)] = UNICODE_NULL; RtlDosPathNameToNtPathName_U(FileName->Buffer, & NtFileName, NULL, NULL);
#ifdef FE_SB
Status = DatLoadAsciiFileAsUnicode(uCodePage, & NtFileName, & MultiSzFile); #else
Status = DatLoadAsciiFileAsUnicode(& NtFileName, & MultiSzFile); #endif
if (! NT_SUCCESS(Status)) { goto Cleanup; }
MultiSzFileSize = (ULONG) (MultiSzFile.EndOfFile - MultiSzFile.NextLine + 1); * ValueLength = 0; * ValueBuffer = ALLOCMEM((MultiSzFileSize + 2) * sizeof(WCHAR)); if (* ValueBuffer == NULL) { Status = STATUS_NO_MEMORY; goto Cleanup; }
MultiSource.Buffer = MultiSzFile.NextLine; if (MultiSzFileSize * sizeof(WCHAR) <= MAXUSHORT) { MultiSource.Length = MultiSource.MaximumLength = (USHORT) MultiSzFileSize * sizeof(WCHAR); } else { MultiSource.Length = MultiSource.MaximumLength = MAXUSHORT; }
while (DatGetMultiString(& MultiSource, & MultiValue)) { RtlMoveMemory((PUCHAR) * ValueBuffer + * ValueLength, MultiValue.Buffer, MultiValue.Length); * ValueLength += MultiValue.Length;
s = MultiSource.Buffer; while (* s != L'"' && * s != L',' && ((s - MultiSource.Buffer) * sizeof(WCHAR)) < MultiSource.Length) s ++; if (((s - MultiSource.Buffer) * sizeof(WCHAR)) == MultiSource.Length || * s == L',' || * s == L';') { ((PWSTR) * ValueBuffer)[* ValueLength / sizeof(WCHAR)] = UNICODE_NULL; * ValueLength += sizeof(UNICODE_NULL); if (* s == L';') { break; } } if ((MultiSzFile.EndOfFile - MultiSource.Buffer) * sizeof(WCHAR) >= MAXUSHORT) { MultiSource.Length = MultiSource.MaximumLength = MAXUSHORT; } else { MultiSource.Length = MultiSource.MaximumLength = (USHORT)((MultiSzFile.EndOfFile - MultiSource.Buffer) * sizeof(WCHAR)); } }
((PWSTR) * ValueBuffer)[ * ValueLength / sizeof(WCHAR)] = UNICODE_NULL; * ValueLength += sizeof(UNICODE_NULL);
// Virtual memory for reading of MultiSzFile freed at process
// death?
Cleanup: if (NtFileName.Buffer != NULL) FREEMEM(NtFileName.Buffer); if (MultiSzFile.FileContents != NULL) FREEMEM(MultiSzFile.FileContents); return Status; }
NTSTATUS DatLoadAsciiFileAsUnicode( #ifdef FE_SB
UINT uCodePage, #endif
PUNICODE_STRING FileName, PREG_UNICODE_FILE UnicodeFile ) { NTSTATUS Status = STATUS_SUCCESS; OBJECT_ATTRIBUTES ObjectAttributes; IO_STATUS_BLOCK IoStatus; HANDLE File = NULL; FILE_BASIC_INFORMATION FileDateTimeInfo; FILE_STANDARD_INFORMATION FileInformation; SIZE_T BufferSize; ULONG i, i1, LineCount; PVOID BufferBase = NULL; LPSTR szSource = NULL; LPSTR Src = NULL; LPSTR Src1; LPWSTR Dst = NULL;
ZeroMemory(& FileDateTimeInfo, sizeof(FILE_BASIC_INFORMATION)); InitializeObjectAttributes(& ObjectAttributes, FileName, OBJ_CASE_INSENSITIVE, (HANDLE) NULL, NULL); Status = NtOpenFile(& File, SYNCHRONIZE | GENERIC_READ, & ObjectAttributes, & IoStatus, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE); if (! NT_SUCCESS(Status)) { goto Cleanup; }
Status = NtQueryInformationFile(File, & IoStatus, (PVOID) & FileInformation, sizeof(FileInformation), FileStandardInformation); if (NT_SUCCESS(Status)) { if (FileInformation.EndOfFile.HighPart) { Status = STATUS_BUFFER_OVERFLOW; } } if (! NT_SUCCESS(Status)) { goto Cleanup; }
#ifdef FE_SB
BufferSize = FileInformation.EndOfFile.LowPart + 1; #else
BufferSize = FileInformation.EndOfFile.LowPart + 1; #endif
szSource = ALLOCMEM(BufferSize + 2); BufferBase = ALLOCMEM((BufferSize + 2) * sizeof(WCHAR)); if (BufferBase != NULL && szSource != NULL) { Src = (LPSTR) szSource; Dst = (PWSTR) BufferBase; Status = NtReadFile(File, NULL, NULL, NULL, & IoStatus, Src, FileInformation.EndOfFile.LowPart, NULL, NULL); if (NT_SUCCESS(Status)) { Status = IoStatus.Status; if (NT_SUCCESS(Status)) { if (IoStatus.Information != FileInformation.EndOfFile.LowPart) { Status = STATUS_END_OF_FILE; } else { Status = NtQueryInformationFile(File, & IoStatus, (PVOID) & FileDateTimeInfo, sizeof(FileDateTimeInfo), FileBasicInformation); } } } } else { Status = STATUS_NO_MEMORY; } if (! NT_SUCCESS(Status)) { goto Cleanup; }
i = 0; while (i < FileInformation.EndOfFile.LowPart) { if (i > 1 && (Src[-2] == ' ' || Src[-2] == '\t') && Src[-1] == '\\' && (*Src == '\r' || *Src == '\n')) { if (Dst[-1] == L'\\') { -- Dst; } while (Dst > (PWSTR) BufferBase) { if (Dst[-1] > L' ') { break; } Dst --; } LineCount = 0; while (i < FileInformation.EndOfFile.LowPart) { if (*Src == '\n') { i ++; Src ++; LineCount ++; } else if (*Src == '\r' && (i+1) < FileInformation.EndOfFile.LowPart && Src[ 1 ] == '\n') { i += 2; Src += 2; LineCount++; } else { break; } }
if (LineCount > 1) { * Dst ++ = L'\n'; } else { * Dst ++ = L' '; while (i < FileInformation.EndOfFile.LowPart && (* Src == ' ' || * Src == '\t')) { i ++; Src ++; } } if (i >= FileInformation.EndOfFile.LowPart) { break; } } else if ((* Src == '\r' && Src[1] == '\n') || * Src == '\n') { while (TRUE) { while (i < FileInformation.EndOfFile.LowPart && (* Src == '\r' || * Src == '\n')) { i ++; Src ++; } Src1 = Src; i1 = i; while (i1 < FileInformation.EndOfFile.LowPart && (* Src1 == ' ' || * Src1 == '\t')) { i1 ++; Src1 ++; } if (i1 < FileInformation.EndOfFile.LowPart && (* Src1 == '\r' && Src1[1] == '\n') || * Src1 == '\n') { Src = Src1; i = i1; } else { break; } } * Dst ++ = L'\n'; } else { #ifdef FE_SB
WCHAR UnicodeCharacter; LONG cbCharSize = IsDBCSLeadByteEx(uCodePage, * Src) ? 2 : 1;
if (MultiByteToWideChar(uCodePage, 0, Src, cbCharSize, & UnicodeCharacter, 1) == 0) { //
// Check for error - The only time this will happen is if there is
// a leadbyte without a trail byte.
//
UnicodeCharacter = 0x0020; } i += cbCharSize; Src += cbCharSize; * Dst ++ = UnicodeCharacter; #else
i ++; * Dst ++ = RtlAnsiCharToUnicodeChar(& Src); #endif
} }
if (NT_SUCCESS(Status)) { * Dst = UNICODE_NULL; UnicodeFile->FileContents = BufferBase; UnicodeFile->EndOfFile = Dst; UnicodeFile->BeginLine = NULL; UnicodeFile->EndOfLine = NULL; UnicodeFile->NextLine = BufferBase; UnicodeFile->LastWriteTime = FileDateTimeInfo.LastWriteTime; }
Cleanup: if (! NT_SUCCESS(Status)) { if (BufferBase != NULL) FREEMEM(BufferBase); } if (szSource != NULL) FREEMEM(szSource); if (File != NULL) NtClose(File); return(Status); }
//
// Define an upcase macro for temporary use by the upcase routines
//
#define upcase(C) (WCHAR )(((C) >= 'a' && (C) <= 'z' ? (C) - ('a' - 'A') : (C)))
BOOLEAN DatGetMultiString( PUNICODE_STRING ValueString, PUNICODE_STRING MultiString ) /*++
Routine Description: This routine parses multi-strings of the form "foo" "bar" "bletch"
Each time it is called, it strips the first string in quotes from the input string, and returns it as the multi-string. INPUT ValueString: "foo" "bar" "bletch" OUTPUT ValueString: "bar" "bletch" MultiString: foo
Arguments: ValueString - Supplies the string from which the multi-string will be parsed - Returns the remaining string after the multi-string is removed MultiString - Returns the multi-string removed from ValueString
Return Value: TRUE - multi-string found and removed. FALSE - no more multi-strings remaining. --*/
{ BOOLEAN bReturn = FALSE; DWORD dwLength = ValueString->Length / sizeof(WCHAR);
if (ValueString->Length != dwLength * sizeof(WCHAR)) { // ValueString->Length should not be odd number, bail out.
goto Cleanup; } //
// Find the first quote mark.
//
while ((ValueString->Length > 0) && (* (ValueString->Buffer) != L'"')) { ++ ValueString->Buffer; ValueString->Length -= sizeof(WCHAR); ValueString->MaximumLength -= sizeof(WCHAR); }
if (ValueString->Length == 0) { goto Cleanup; }
//
// We have found the start of the multi-string. Now find the end,
// building up our return MultiString as we go.
//
++ ValueString->Buffer; ValueString->Length -= sizeof(WCHAR); ValueString->MaximumLength -= sizeof(WCHAR); MultiString->Buffer = ValueString->Buffer; MultiString->Length = 0; MultiString->MaximumLength = 0; while ((ValueString->Length > 0) && (* (ValueString->Buffer) != L'"')) { ++ ValueString->Buffer; ValueString->Length -= sizeof(WCHAR); ValueString->MaximumLength -= sizeof(WCHAR); MultiString->Length += sizeof(WCHAR); MultiString->MaximumLength += sizeof(WCHAR); }
if (ValueString->Length == 0) { goto Cleanup; }
++ ValueString->Buffer; ValueString->Length -= sizeof(WCHAR); ValueString->MaximumLength -= sizeof(WCHAR); bReturn = TRUE;
Cleanup: return bReturn; }
#define EXTENSION_DELIMITER L'.'
BOOL OutputIniData( PUNICODE_STRING FileName, LPWSTR OutFileCandidate, DWORD dwOutFile, PVOID pValueBuffer, ULONG ValueLength ) { HANDLE hOutFile = NULL; LPWSTR lpExtension = NULL; DWORD nAmtWritten; BOOL bSuccess = FALSE; DWORD ErrorCode; HRESULT hError;
// If output file not specified, derive from input file name
if (OutFileCandidate[0] == L'\0') { if ((DWORD) (lstrlenW(FileName->Buffer) + 5) <= dwOutFile) { LPWSTR lpDelimiter;
hError = StringCchCopyW(OutFileCandidate, dwOutFile, FileName->Buffer); if (FAILED(hError)) goto Cleanup;
lpDelimiter = wcschr(OutFileCandidate, EXTENSION_DELIMITER); if (lpDelimiter != NULL) { nAmtWritten = dwOutFile - ((DWORD) (lpDelimiter - OutFileCandidate)); hError = StringCchCopyW(lpDelimiter, nAmtWritten, L".dat"); if (FAILED(hError)) goto Cleanup; } else { hError = StringCchCatW(OutFileCandidate, dwOutFile, L".dat"); if (FAILED(hError)) goto Cleanup; } } else { goto Cleanup; } } hOutFile = (HANDLE) CreateFileW(OutFileCandidate, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (hOutFile == NULL || hOutFile == INVALID_HANDLE_VALUE) { ErrorCode = GetLastError(); printf(GetFormatResource(LC_CANT_CREATE), ErrorCode); if (ErrorCode == ERROR_ACCESS_DENIED) printf("%ws\n", GetStringResource(LC_ACCESS_DENIED)); goto Cleanup; } bSuccess = WriteFile(hOutFile, pValueBuffer, ValueLength, & nAmtWritten, NULL); bSuccess = bSuccess && (nAmtWritten == ValueLength); CloseHandle(hOutFile); if (! bSuccess) { ErrorCode = GetLastError(); printf(GetFormatResource(LC_CANT_WRITE), ErrorCode); if (ErrorCode == ERROR_DISK_FULL) printf("%ws\n", GetStringResource(LC_DISK_FULL)); }
Cleanup: return bSuccess; }
|