windows-nt/Source/XPSP1/NT/sdktools/structo/sofile.c
2020-09-26 16:20:57 +08:00

557 lines
15 KiB
C

/****************************** Module Header ******************************\
* Module Name: sofile.c
*
* Copyright (c) 1985-96, Microsoft Corporation
*
* 04/09/96 GerardoB Created
\***************************************************************************/
#include "structo.h"
/*********************************************************************
* soWriteOutputFileHeader
*
\***************************************************************************/
BOOL soWriteOutputFileHeader (PWORKINGFILES pwf)
{
char ** ppszHeader;
/*
* If building list only, done
*/
if (pwf->dwOptions & SOWF_LISTONLY) {
return TRUE;
}
if ( !soWriteFile(pwf->hfileOutput, "/*********************************************************************\\\r\n")
|| !soWriteFile(pwf->hfileOutput, "* File: %s\r\n", pwf->pszOutputFile)
|| !soWriteFile(pwf->hfileOutput, "* Generated by StructO on %s at %s\r\n", __DATE__, __TIME__)
|| !soWriteFile(pwf->hfileOutput, "\\*********************************************************************/\r\n\r\n")) {
return FALSE;
}
if (pwf->dwOptions & SOWF_INLCLUDEPRECOMPH) {
if (!soWriteFile(pwf->hfileOutput, gszPrecomph)) {
return FALSE;
}
}
/*
* structure definitions for generated tables
*/
ppszHeader = gpszHeader;
while (*ppszHeader != NULL) {
if (!soWriteFile(pwf->hfileOutput, *ppszHeader)
|| !soWriteFile(pwf->hfileOutput, "\r\n")) {
return FALSE;
}
ppszHeader++;
}
return TRUE;
}
/*********************************************************************
* soUnmapFile
*
\***************************************************************************/
void soUnmapFile (PFILEMAP pfm)
{
if (pfm->pmapStart != NULL) {
UnmapViewOfFile(pfm->pmap);
pfm->pmapStart = NULL;
pfm->pmap = NULL;
pfm->pmapEnd = NULL;
}
if (pfm->hmap != NULL) {
CloseHandle(pfm->hmap);
pfm->hmap = NULL;
}
if (pfm->hfile != INVALID_HANDLE_VALUE) {
CloseHandle(pfm->hfile);
pfm->hfile = INVALID_HANDLE_VALUE;
}
}
/*********************************************************************
* soMapFile
*
\***************************************************************************/
BOOL soMapFile (char * pszFile, PFILEMAP pfm)
{
DWORD dwFileSize;
pfm->hfile = CreateFile(pszFile, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, NULL);
if (pfm->hfile == INVALID_HANDLE_VALUE) {
soLogMsg(SOLM_APIERROR, "CreateFile");
goto CleanupAndFail;
}
dwFileSize = GetFileSize(pfm->hfile, NULL);
if (dwFileSize == 0xFFFFFFFF) {
soLogMsg(SOLM_APIERROR, "GetFileSize");
goto CleanupAndFail;
}
pfm->hmap = CreateFileMapping(pfm->hfile, NULL, PAGE_READONLY, 0, 0, NULL);
if (pfm->hmap == NULL) {
soLogMsg(SOLM_APIERROR, "CreateFileMapping");
goto CleanupAndFail;
}
pfm->pmapStart = MapViewOfFile(pfm->hmap, FILE_MAP_READ, 0, 0, 0);
if (pfm->pmapStart == NULL) {
soLogMsg(SOLM_APIERROR, "MapViewOfFile");
goto CleanupAndFail;
}
pfm->pmap = pfm->pmapStart;
pfm->pmapEnd = pfm->pmapStart + dwFileSize;
return TRUE;
CleanupAndFail:
soLogMsg(SOLM_ERROR, "soMapFile failed. File: '%s'", pszFile);
soUnmapFile (pfm);
return FALSE;
}
/*********************************************************************
* soBuildStructsList
*
\***************************************************************************/
BOOL soBuildStructsList (PWORKINGFILES pwf)
{
static char gszEOL [] = "\r\n";
char * pmap, * pStruct;
FILEMAP fm;
PSTRUCTLIST psl;
PVOID pTemp;
UINT uAlloc, uCount, uSize;
soLogMsg (SOLM_NOEOL, "Building structs list from %s ...", pwf->pszStructsFile);
if (!soMapFile (pwf->pszStructsFile, &fm)) {
goto CleanupAndFail;
}
/*
* Let's guess a number of structures
*/
#define SO_LISTSIZE 20
uAlloc = SO_LISTSIZE;
/*
* Allocate list
*/
pwf->psl = (PSTRUCTLIST) LocalAlloc(LPTR, sizeof(STRUCTLIST) * (uAlloc + 1));
if (pwf->psl == NULL) {
soLogMsg(SOLM_APIERROR, "LocalAlloc");
goto CleanupAndFail;
}
/*
* Load structure names
*/
pmap = fm.pmapStart;
psl = pwf->psl;
uCount = 0;
while (pmap < fm.pmapEnd) {
/*
* Name should start at first column
*/
if (!soIsIdentifierChar(*pmap)) {
/*
* Skip this line
*/
pmap = soFindTag(pmap, fm.pmapEnd, gszEOL);
if (pmap == NULL) {
break;
}
pmap += sizeof(gszEOL) - 1;
continue;
}
/*
* Find the name
*/
pStruct = soGetIdentifier (pmap, fm.pmapEnd, &uSize);
if (pStruct == NULL) {
soLogMsg(SOLM_ERROR, "soGetIdentifier failed.");
goto CleanupAndFail;
}
/*
* Grow the list if needed
*/
if (uCount >= uAlloc) {
soLogMsg (SOLM_APPEND, ".");
uAlloc += SO_LISTSIZE;
pTemp = LocalReAlloc(pwf->psl, sizeof(STRUCTLIST) * (uAlloc + 1), LMEM_MOVEABLE | LMEM_ZEROINIT);
if (pTemp == NULL) {
soLogMsg(SOLM_APIERROR, "LocalReAlloc");
goto CleanupAndFail;
}
pwf->psl = (PSTRUCTLIST)pTemp;
psl = pwf->psl + uCount;
}
/*
* Copy it
*/
psl->uSize = uSize;
psl->pszName = soCopyTagName (pStruct, uSize);
if (psl->pszName == NULL) {
goto CleanupAndFail;
}
psl++;
uCount++;
pmap = pStruct + uSize;
}
/*
* Make sure it found at least one struct
*/
if (uCount == 0) {
soLogMsg(SOLM_ERROR, "Failed to get structure name");
goto CleanupAndFail;
}
/*
* Let's save some memory
*/
if (uCount < uAlloc) {
pTemp = LocalReAlloc(pwf->psl, sizeof(STRUCTLIST) * (uCount + 1), LMEM_MOVEABLE | LMEM_ZEROINIT);
if (pTemp == NULL) {
soLogMsg(SOLM_APIERROR, "LocalReAlloc");
goto CleanupAndFail;
}
pwf->psl = (PSTRUCTLIST)pTemp;
}
soUnmapFile (&fm);
soLogMsg (SOLM_NOLABEL, ".");
return TRUE;
CleanupAndFail:
soLogMsg(SOLM_ERROR, "soBuildStructsList failed. File: '%s'", pwf->pszStructsFile);
soUnmapFile (&fm);
/*
* The process is going away so never mind the heap
*/
return FALSE;
}
/*********************************************************************
* soIncludeInputFile
*
* Add #include <pszInputFile Name>.<pszIncInputFileExt> to output file
\***************************************************************************/
BOOL soIncludeInputFile (PWORKINGFILES pwf)
{
BOOL fRet;
char * pszIncFile, * pDot;
UINT uInputFileNameSize;
/*
* If building list only, done
*/
if (pwf->dwOptions & SOWF_LISTONLY) {
return TRUE;
}
/*
* Allocate a buffer to build the name
*/
uInputFileNameSize = lstrlen(pwf->pszInputFile);
pszIncFile = (char *) LocalAlloc(LPTR,
uInputFileNameSize + lstrlen(pwf->pszIncInputFileExt) + 2);
if (pszIncFile == NULL) {
soLogMsg(SOLM_APIERROR, "LocalAlloc");
return FALSE;
}
/*
* Copy file name
*/
pDot = soFindChar (pwf->pszInputFile, pwf->pszInputFile + uInputFileNameSize, '.');
if (pDot == NULL) {
strcpy(pszIncFile, pwf->pszInputFile);
strcat(pszIncFile, ".");
} else {
strncpy(pszIncFile, pwf->pszInputFile, (UINT)(pDot - pwf->pszInputFile + 1));
}
/*
* Copy extension and write it to output file
*/
strcat(pszIncFile, pwf->pszIncInputFileExt);
fRet = soWriteFile(pwf->hfileOutput, gszIncInput, pszIncFile);
LocalFree(pszIncFile);
return fRet;
}
/*********************************************************************
* soOpenWorkingFiles
*
\***************************************************************************/
BOOL soOpenWorkingFiles (PWORKINGFILES pwf)
{
char szTempPath [MAX_PATH];
char szTempFile [MAX_PATH];
DWORD dwFileSize;
/*
* Load the structures list if provided and not built already
*/
if ((pwf->pszStructsFile != NULL) && (pwf->psl == NULL)) {
if (!soBuildStructsList(pwf)) {
goto CleanupAndFail;
}
}
/*
* Map input file
*/
if (!soMapFile (pwf->pszInputFile, (PFILEMAP) &(pwf->hfileInput))) {
goto CleanupAndFail;
}
/*
* Open output file if not open already
*/
if (pwf->hfileOutput == INVALID_HANDLE_VALUE) {
pwf->hfileOutput = CreateFile(pwf->pszOutputFile, GENERIC_WRITE, 0, NULL,
(pwf->dwOptions & SOWF_APPENDOUTPUT ? OPEN_EXISTING : CREATE_ALWAYS),
FILE_ATTRIBUTE_NORMAL, NULL);
if (pwf->hfileOutput == INVALID_HANDLE_VALUE) {
soLogMsg(SOLM_APIERROR, "CreateFile");
soLogMsg(SOLM_ERROR, "Failed to open output file: %s", pwf->pszOutputFile);
goto CleanupAndFail;
}
if (pwf->dwOptions & SOWF_APPENDOUTPUT) {
if (0xFFFFFFFF == SetFilePointer (pwf->hfileOutput, 0, 0, FILE_END)) {
soLogMsg(SOLM_APIERROR, "SetFilePointer");
goto CleanupAndFail;
}
} else {
if (!soWriteOutputFileHeader(pwf)) {
goto CleanupAndFail;
}
}
}
/*
* #include input file if requested
*/
if (pwf->dwOptions & SOWF_INCLUDEINPUTFILE) {
if (!soIncludeInputFile(pwf)) {
goto CleanupAndFail;
}
}
/*
* Create temp file if not created already
*/
if (pwf->hfileTemp == INVALID_HANDLE_VALUE) {
if (!GetTempPath(sizeof(szTempPath) - 1, szTempPath)) {
soLogMsg(SOLM_APIERROR, "GetTempPath");
goto CleanupAndFail;
}
if (!GetTempFileName(szTempPath, "sot", 0, szTempFile)) {
soLogMsg(SOLM_APIERROR, "GetTempFileName");
soLogMsg(SOLM_ERROR, "Failed to get temp file name. szTempPath: %s.", szTempPath);
goto CleanupAndFail;
}
pwf->hfileTemp = CreateFile(szTempFile, GENERIC_WRITE | GENERIC_READ, 0, NULL,
CREATE_ALWAYS, FILE_FLAG_DELETE_ON_CLOSE, NULL);
if (pwf->hfileTemp == INVALID_HANDLE_VALUE) {
soLogMsg(SOLM_APIERROR, "CreateFile");
soLogMsg(SOLM_ERROR, "Failed to create temp file: '%s'", szTempFile);
goto CleanupAndFail;
}
if (!soWriteFile(pwf->hfileTemp, "%s", gszTableDef)) {
goto CleanupAndFail;
}
}
return TRUE;
CleanupAndFail:
soLogMsg(SOLM_ERROR, "soOpenWorkingFiles Failed");
soCloseWorkingFiles (pwf, SOCWF_CLEANUP);
return FALSE;
}
/*********************************************************************
* soCloseWorkingFiles
*
\***************************************************************************/
BOOL soCloseWorkingFiles (PWORKINGFILES pwf, DWORD dwFlags)
{
if (dwFlags & SOCWF_CLEANUP) {
if (pwf->hfileTemp != INVALID_HANDLE_VALUE) {
CloseHandle(pwf->hfileTemp);
pwf->hfileTemp = INVALID_HANDLE_VALUE;
}
if (pwf->hfileOutput != INVALID_HANDLE_VALUE) {
CloseHandle(pwf->hfileOutput);
pwf->hfileOutput = INVALID_HANDLE_VALUE;
}
if (pwf->psl != NULL) {
// Never mind cleanning the heap. The process is going away.
}
}
soUnmapFile((PFILEMAP) &(pwf->hfileInput));
return TRUE;
}
/*********************************************************************
* soWriteFile
*
\***************************************************************************/
BOOL __cdecl soWriteFile(HANDLE hfile, char *pszfmt, ...)
{
static char gszbuff [1024+1];
BOOL fRet = TRUE;
va_list va;
DWORD dwWritten;
va_start(va, pszfmt);
vsprintf(gszbuff, pszfmt, va);
if (!WriteFile(hfile, gszbuff, strlen(gszbuff), &dwWritten, NULL)) {
soLogMsg(SOLM_APIERROR, "WriteFile");
soLogMsg(SOLM_ERROR, "buffer not written: %s.", gszbuff);
fRet = FALSE;
}
va_end(va);
return fRet;
}
/*********************************************************************
* soCopyStructuresTable
*
\***************************************************************************/
BOOL soCopyStructuresTable (PWORKINGFILES pwf)
{
static char szTemp[1024];
char ** ppszTail;
DWORD dwFileSize, dwRead, dwWritten;
PSTRUCTLIST psl;
UINT uLoops;
soLogMsg (SOLM_NOEOL, "Writting structs table ...");
/*
* If there are no structures, bail.
* If there was a struct list, fail
*/
if (pwf->uTablesCount == 0) {
if (pwf->psl != NULL) {
soLogMsg(SOLM_ERROR, "None of the structures in '%s' was found", pwf->pszStructsFile);
return FALSE;
} else {
return TRUE;
}
}
/*
* If building list only, done
*/
if (pwf->dwOptions & SOWF_LISTONLY) {
soLogMsg (SOLM_DEFAULT, "%d Structures found.", pwf->uTablesCount);
return TRUE;
}
/*
* Let them know if we didn't find any of the structures in the list
*/
if (pwf->psl != NULL) {
psl = pwf->psl;
while (psl->uSize != 0) {
if (psl->uCount == 0) {
soLogMsg(SOLM_WARNING, "Structure not found: %s", psl->pszName);
}
psl++;
}
}
if (!soWriteFile(pwf->hfileTemp, "%s", gszTableEnd)) {
goto MsgAndFail;
}
/*
* Move to beginning of temp file
*/
dwFileSize = GetFileSize(pwf->hfileTemp, NULL);
if (dwFileSize == 0xFFFFFFFF) {
soLogMsg(SOLM_APIERROR, "GetFileSize");
goto MsgAndFail;
}
if (0xFFFFFFFF == SetFilePointer (pwf->hfileTemp, 0, 0, FILE_BEGIN)) {
soLogMsg(SOLM_APIERROR, "SetFilePointer");
goto MsgAndFail;
}
/*
* Append temp file to output file
*/
uLoops = 0;
while (dwFileSize != 0) {
if (!ReadFile(pwf->hfileTemp, szTemp, sizeof(szTemp), &dwRead, NULL)) {
soLogMsg(SOLM_APIERROR, "ReadFile");
goto MsgAndFail;
}
if (!WriteFile(pwf->hfileOutput, szTemp, dwRead, &dwWritten, NULL)) {
soLogMsg(SOLM_APIERROR, "WriteFile");
goto MsgAndFail;
}
dwFileSize -= dwRead;
if (++uLoops == 50) {
uLoops = 0;
soLogMsg (SOLM_APPEND, ".");
}
}
soLogMsg (SOLM_NOLABEL, ".");
soLogMsg (SOLM_DEFAULT, "%d Tables generated.", pwf->uTablesCount);
/*
* Write file tail (code)
*/
ppszTail = gpszTail;
while (*ppszTail != NULL) {
if (!soWriteFile(pwf->hfileOutput, *ppszTail)
|| !soWriteFile(pwf->hfileOutput, "\r\n")) {
return FALSE;
}
ppszTail++;
}
return TRUE;
MsgAndFail:
soLogMsg(SOLM_ERROR, "soCopyStructuresTable failed.");
return FALSE;
}