386 lines
10 KiB
C
386 lines
10 KiB
C
/*++
|
||
|
||
Copyright (c) 1993-1994 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
initodat.c
|
||
|
||
Abstract:
|
||
|
||
Routines for converting Perf???.ini to Perf???.dat files.
|
||
|
||
Author:
|
||
|
||
HonWah Chan (a-honwah) October, 1993
|
||
|
||
Revision History:
|
||
|
||
--*/
|
||
|
||
#include "initodat.h"
|
||
#include "strids.h"
|
||
#include "common.h"
|
||
#include "tchar.h"
|
||
|
||
#define ALLOCMEM(x) HeapAlloc (GetProcessHeap(), HEAP_ZERO_MEMORY, (DWORD)(x))
|
||
#define FREEMEM(x) HeapFree (GetProcessHeap(), 0, (LPVOID)(x))
|
||
|
||
BOOL
|
||
MakeUpgradeFilename (
|
||
LPCTSTR szDataFileName,
|
||
LPTSTR szUpgradeFileName
|
||
)
|
||
{
|
||
BOOL bReturn = FALSE;
|
||
// note: assumes szUpgradeFileName buffer is large enough for result
|
||
TCHAR szDrive[_MAX_DRIVE];
|
||
TCHAR szDir[_MAX_DIR];
|
||
TCHAR szFileName[_MAX_FNAME];
|
||
TCHAR szExt[_MAX_EXT];
|
||
|
||
_tsplitpath(szDataFileName,
|
||
(LPTSTR)szDrive,
|
||
(LPTSTR)szDir,
|
||
(LPTSTR)szFileName,
|
||
(LPTSTR)szExt);
|
||
|
||
// see if the filename fits the "PERF[C|H]XXX" format
|
||
if (((szFileName[4] == TEXT('C')) || (szFileName[4] == TEXT('H'))) ||
|
||
((szFileName[4] == TEXT('c')) || (szFileName[4] == TEXT('h')))) {
|
||
// then it's the correct format so change the 4th letter up 1 letter
|
||
szFileName[4] += 1;
|
||
// and make a new path
|
||
_tmakepath (szUpgradeFileName,
|
||
(LPCTSTR)szDrive,
|
||
(LPCTSTR)szDir,
|
||
(LPCTSTR)szFileName,
|
||
(LPCTSTR)szExt);
|
||
bReturn = TRUE;
|
||
} else {
|
||
// bogus name so return false
|
||
}
|
||
return bReturn;
|
||
}
|
||
|
||
BOOL
|
||
GetFilesFromCommandLine (
|
||
IN LPTSTR lpCommandLine,
|
||
#ifdef FE_SB
|
||
OUT UINT *puCodePage,
|
||
#endif
|
||
OUT LPTSTR *lpFileNameI,
|
||
OUT LPTSTR *lpFileNameD
|
||
)
|
||
/*++
|
||
|
||
GetFilesFromCommandLine
|
||
|
||
parses the command line to retrieve the ini filename that should be
|
||
the first and only argument.
|
||
|
||
Arguments
|
||
|
||
lpCommandLine pointer to command line (returned by GetCommandLine)
|
||
lpFileNameI pointer to buffer that will receive address of the
|
||
validated input filename entered on the command line
|
||
lpFileNameD pointer to buffer that will receive address of the
|
||
optional output filename entered on the command line
|
||
|
||
Return Value
|
||
|
||
TRUE if a valid filename was returned
|
||
FALSE if the filename is not valid or missing
|
||
error is returned in GetLastError
|
||
|
||
--*/
|
||
{
|
||
INT iNumArgs;
|
||
|
||
HFILE hIniFile;
|
||
OFSTRUCT ofIniFile;
|
||
|
||
LPSTR lpIniFileName = NULL;
|
||
LPTSTR lpExeName = NULL;
|
||
LPTSTR lpIniName = NULL;
|
||
|
||
// check for valid arguments
|
||
|
||
if (lpCommandLine == NULL) return (FALSE);
|
||
if (*lpFileNameI == NULL) return (FALSE);
|
||
if (*lpFileNameD == NULL) return (FALSE);
|
||
|
||
// allocate memory for parsing operation
|
||
|
||
lpExeName = ALLOCMEM (FILE_NAME_BUFFER_SIZE * sizeof(TCHAR));
|
||
lpIniName = ALLOCMEM (FILE_NAME_BUFFER_SIZE * sizeof(TCHAR));
|
||
lpIniFileName = ALLOCMEM (FILE_NAME_BUFFER_SIZE);
|
||
|
||
if ((lpExeName == NULL) ||
|
||
(lpIniFileName == NULL) ||
|
||
(lpIniName == NULL)) {
|
||
if (lpExeName) FREEMEM (lpExeName);
|
||
if (lpIniFileName) FREEMEM (lpIniFileName);
|
||
if (lpIniName) FREEMEM (lpIniName);
|
||
return FALSE;
|
||
} else {
|
||
// get strings from command line
|
||
|
||
#ifdef FE_SB
|
||
iNumArgs = _stscanf (lpCommandLine, (LPCTSTR)TEXT(" %s %d %s %s "), lpExeName, puCodePage, lpIniName, *lpFileNameD);
|
||
#else
|
||
iNumArgs = _stscanf (lpCommandLine, (LPCTSTR)TEXT(" %s %s %s "), lpExeName, lpIniName, *lpFileNameD);
|
||
#endif
|
||
|
||
#ifdef FE_SB
|
||
if (iNumArgs < 3 || iNumArgs > 4) {
|
||
#else
|
||
if (iNumArgs < 2 || iNumArgs > 3) {
|
||
#endif
|
||
// wrong number of arguments
|
||
FREEMEM (lpExeName);
|
||
FREEMEM (lpIniFileName);
|
||
FREEMEM (lpIniName);
|
||
return FALSE;
|
||
} else {
|
||
// see if file specified exists
|
||
// file name is always an ANSI buffer
|
||
wcstombs (lpIniFileName, lpIniName, lstrlenW(lpIniName)+1);
|
||
FREEMEM (lpIniName);
|
||
FREEMEM (lpExeName);
|
||
hIniFile = OpenFile (lpIniFileName,
|
||
&ofIniFile,
|
||
OF_PARSE);
|
||
|
||
if (hIniFile != HFILE_ERROR) {
|
||
hIniFile = OpenFile (lpIniFileName,
|
||
&ofIniFile,
|
||
OF_EXIST);
|
||
|
||
if ((hIniFile && hIniFile != HFILE_ERROR) ||
|
||
(GetLastError() == ERROR_FILE_EXISTS)) {
|
||
// file exists, so return name and success
|
||
// return full pathname if found
|
||
mbstowcs (*lpFileNameI, ofIniFile.szPathName, lstrlenA(ofIniFile.szPathName)+1);
|
||
FREEMEM (lpIniFileName);
|
||
return TRUE;
|
||
} else {
|
||
// filename was on command line, but not valid so return
|
||
// false, but send name back for error message
|
||
mbstowcs (*lpFileNameI, lpIniFileName, lstrlenA(lpIniFileName)+1);
|
||
FREEMEM (lpIniFileName);
|
||
return FALSE;
|
||
}
|
||
} else {
|
||
FREEMEM (lpIniFileName);
|
||
return FALSE;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
BOOL VerifyIniData(
|
||
IN PVOID pValueBuffer,
|
||
IN ULONG ValueLength
|
||
)
|
||
/*++
|
||
|
||
VerifyIniData
|
||
This routine does some simple check to see if the ini file is good.
|
||
Basically, it is looking for (ID, Text) and checking that ID is an
|
||
integer. Mostly in case of missing comma or quote, the ID will be
|
||
an invalid integer.
|
||
|
||
--*/
|
||
{
|
||
INT iNumArg;
|
||
INT TextID;
|
||
LPTSTR lpID = NULL;
|
||
LPTSTR lpText = NULL;
|
||
LPTSTR lpLastID;
|
||
LPTSTR lpLastText;
|
||
LPTSTR lpInputBuffer = (LPTSTR) pValueBuffer;
|
||
LPTSTR lpBeginBuffer = (LPTSTR) pValueBuffer;
|
||
BOOL returnCode = TRUE;
|
||
UINT NumOfID = 0;
|
||
ULONG CurrentLength;
|
||
|
||
#pragma warning ( disable : 4127 )
|
||
while (TRUE) {
|
||
|
||
// save up the last items for summary display later
|
||
lpLastID = lpID;
|
||
lpLastText = lpText;
|
||
|
||
// increment to next ID and text location
|
||
lpID = lpInputBuffer;
|
||
CurrentLength = (ULONG)((PBYTE)lpID - (PBYTE)lpBeginBuffer + sizeof(WCHAR));
|
||
|
||
if (CurrentLength >= ValueLength)
|
||
break;
|
||
|
||
try {
|
||
lpText = lpID + lstrlen (lpID) + 1;
|
||
|
||
lpInputBuffer = lpText + lstrlen (lpText) + 1;
|
||
|
||
iNumArg = _stscanf (lpID, (LPCTSTR)TEXT("%d"), &TextID);
|
||
}
|
||
except (TRUE) {
|
||
iNumArg = -1;
|
||
}
|
||
|
||
if (iNumArg != 1) {
|
||
// bad ID
|
||
returnCode = FALSE;
|
||
break ;
|
||
}
|
||
NumOfID++;
|
||
}
|
||
#pragma warning ( default : 4127 )
|
||
|
||
if (returnCode == FALSE) {
|
||
DisplaySummaryError (lpLastID, lpLastText, NumOfID);
|
||
}
|
||
else {
|
||
DisplaySummary (lpLastID, lpLastText, NumOfID);
|
||
}
|
||
return (returnCode);
|
||
}
|
||
|
||
|
||
__cdecl main(
|
||
// int argc,
|
||
// char *argv[]
|
||
)
|
||
/*++
|
||
|
||
main
|
||
|
||
|
||
|
||
Arguments
|
||
|
||
|
||
ReturnValue
|
||
|
||
0 (ERROR_SUCCESS) if command was processed
|
||
Non-Zero if command error was detected.
|
||
|
||
--*/
|
||
{
|
||
LPTSTR lpCommandLine;
|
||
LPTSTR lpIniFile;
|
||
LPTSTR lpDatFile;
|
||
UNICODE_STRING IniFileName;
|
||
PVOID pValueBuffer;
|
||
ULONG ValueLength;
|
||
BOOL bStatus;
|
||
NTSTATUS NtStatus;
|
||
#if 0
|
||
// part of bogus filename change code
|
||
LPTSTR pchar ;
|
||
INT npos;
|
||
TCHAR ch = TEXT('f');
|
||
#endif
|
||
#ifdef FE_SB
|
||
UINT uCodePage=CP_ACP;
|
||
#endif
|
||
|
||
lpIniFile = ALLOCMEM (MAX_PATH * sizeof (TCHAR));
|
||
lpDatFile = ALLOCMEM (MAX_PATH * sizeof (TCHAR));
|
||
if (lpIniFile == NULL) return ERROR_OUTOFMEMORY;
|
||
if (lpDatFile == NULL) return ERROR_OUTOFMEMORY;
|
||
lstrcpy(lpDatFile, (LPCTSTR)TEXT("\0"));
|
||
|
||
lpCommandLine = GetCommandLine(); // get command line
|
||
if (lpCommandLine == NULL) {
|
||
NtStatus = GetLastError();
|
||
FREEMEM (lpIniFile);
|
||
FREEMEM (lpDatFile);
|
||
return NtStatus;
|
||
}
|
||
|
||
// read command line to determine what to do
|
||
|
||
#ifdef FE_SB // FE_SB
|
||
if (GetFilesFromCommandLine (lpCommandLine, &uCodePage, &lpIniFile, &lpDatFile)) {
|
||
|
||
if (!IsValidCodePage(uCodePage)) {
|
||
uCodePage = CP_ACP;
|
||
}
|
||
#else
|
||
if (GetFilesFromCommandLine (lpCommandLine, &lpIniFile, &lpDatFile)) {
|
||
#endif // FE_SB
|
||
|
||
|
||
|
||
// valid filename (i.e. ini file exists)
|
||
IniFileName.Buffer = lpIniFile;
|
||
IniFileName.MaximumLength =
|
||
IniFileName.Length = (WORD)((lstrlen (lpIniFile) + 1 ) * sizeof(WCHAR)) ;
|
||
#ifdef FE_SB
|
||
bStatus = DatReadMultiSzFile (uCodePage, &IniFileName,
|
||
#else
|
||
bStatus = DatReadMultiSzFile (&IniFileName,
|
||
#endif
|
||
&pValueBuffer,
|
||
&ValueLength);
|
||
|
||
if (bStatus) {
|
||
bStatus = VerifyIniData (pValueBuffer, ValueLength);
|
||
if (bStatus) {
|
||
bStatus = OutputIniData (&IniFileName,
|
||
lpDatFile,
|
||
pValueBuffer,
|
||
ValueLength);
|
||
#if 0
|
||
// this is a really bogus way to find "PERF" in the
|
||
// filename string
|
||
|
||
//Add the new file that'll be used in upgrade
|
||
// find the last "F" in the file name by reversing
|
||
// the string, finding the first "F"
|
||
// then go to the previous character and incrementing
|
||
// it. Finally reverse the characters in the file name
|
||
// returning it to the correct order.
|
||
//
|
||
// this creates the "upgrade" file with a slightly different
|
||
// filename that is used by Lodctr to insert the new system
|
||
// strings into the existing list of system strings.
|
||
//
|
||
_tcsrev(lpDatFile);
|
||
pchar = _tcschr(lpDatFile,ch);
|
||
npos = (INT)(pchar - lpDatFile) - 1;
|
||
lpDatFile[npos] = (TCHAR)((lpDatFile[npos]) + 1);
|
||
_tcsrev(lpDatFile);
|
||
#else
|
||
bStatus = MakeUpgradeFilename (
|
||
lpDatFile, lpDatFile);
|
||
|
||
#endif
|
||
if (bStatus) {
|
||
bStatus = OutputIniData (&IniFileName,
|
||
lpDatFile,
|
||
pValueBuffer,
|
||
ValueLength);
|
||
}
|
||
}
|
||
}
|
||
} else {
|
||
if (*lpIniFile) {
|
||
printf (GetFormatResource(LC_NO_INIFILE), lpIniFile);
|
||
} else {
|
||
//Incorrect Command Format
|
||
// display command line usage
|
||
DisplayCommandHelp(LC_FIRST_CMD_HELP, LC_LAST_CMD_HELP);
|
||
}
|
||
}
|
||
|
||
|
||
if (lpIniFile) FREEMEM (lpIniFile);
|
||
if (lpDatFile) FREEMEM (lpDatFile);
|
||
|
||
return (ERROR_SUCCESS); // success
|
||
}
|