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

400 lines
9.4 KiB
C

/*
* Module Name: WSFSLIB.C
*
* Library/DLL: Common library functions for handling working set tuner files.
*
*
* Description:
*
* Library routines called by the working set tuner programs to open and
* read working set tuner files. These functions may be useful to ISVs, etc.,
*
* This is an OS/2 2.x specific file
*
* IBM/Microsoft Confidential
*
* Copyright (c) IBM Corporation 1987, 1989
* Copyright (c) Microsoft Corporation 1987, 1989
*
* All Rights Reserved
*
* Modification History:
*
* 03/26/90 - created
*
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <windows.h>
#include <time.h>
#include <wserror.h>
#include <wsdata.h>
#include <wsfslib.h>
#define MAXLINE 128
BOOL fWsIndicator = FALSE;
/*
* Function declarations and prototypes.
*/
/*
*
***EP WsWSPOpen
*
* Effects:
*
* Opens a WSP file, and reads and validates the file header.
*
* Returns:
*
* Returns 0. If an error is encountered, exits with ERROR via an
* indirect call through pfnExit.
*/
USHORT FAR PASCAL
WsWSPOpen( PSZ pszFileName, FILE **phFile, PFN pfnExit, wsphdr_t *pWspHdr,
INT iExitCode, INT iOpenPrintCode )
{
ULONG rc = NO_ERROR;
INT iRet = 0;
ULONG cbRead = 0;
size_t stRead = 0;
/* Open module's input WSP file. */
if ((*phFile = fopen(pszFileName, "rb")) == NULL)
{
iRet = (*pfnExit)(iExitCode, iOpenPrintCode, MSG_FILE_OPEN, rc,
pszFileName);
return((USHORT)iRet);
}
/* Read WSP file header. */
stRead = fread((PVOID) pWspHdr, (ULONG) sizeof(*pWspHdr),1, *phFile);
if(!stRead)
{
iRet = (*pfnExit)(ERROR, PRINT_MSG, MSG_FILE_OPEN, rc,
pszFileName);
return((USHORT)iRet);
}
/* Read module pathname (directly follows file header). */
#ifdef DEBUG
printf("WspHdr (%s): ulTime 0x%lx, ulSnaps 0x%lx, OffBits 0x%lx\n",
// szModPath, pWspHdr->wsphdr_ulTimeStamp,
pszFileName, pWspHdr->wsphdr_ulTimeStamp, // mdg 4/98
pWspHdr->wsphdr_ulSnaps, pWspHdr->wsphdr_ulOffBits);
#endif /* DEBUG */
/* Validate the WSP file header. */
if (_strcmpi(pWspHdr->wsphdr_chSignature, "WSP"))
(*pfnExit)(ERROR, PRINT_MSG, MSG_FILE_BAD_HDR, (ULONG)-1, pszFileName);
return(NO_ERROR);
}
/*
*
***EP WsTMIOpen
*
* Effects:
*
* Opens a TMI file, and reads and validates the file header.
*
* Returns:
*
* Returns the number of records in the TMI file. If an error is
* encountered, exits with ERROR via an indirect call through pfnExit.
*/
ULONG FAR PASCAL
WsTMIOpen( PSZ pszFileName, FILE **phFile, PFN pfnExit, USHORT usId, PCHAR pch)
{
//ULONG ulTmp;
ULONG rc = NO_ERROR;
ULONG cbRead = 0;
ULONG cFxns = 0;
CHAR szLineTMI[MAXLINE]; // Line from TMI file
CHAR szTDFID[8]; // TDF Identifier string
ULONG ulTDFID = 0; // TDF Identifier
/* Open TMI file (contains function names, etc., in ASCII). */
if ((*phFile = fopen(pszFileName, "rt")) == NULL)
{
(*pfnExit)(NOEXIT, PRINT_MSG, MSG_FILE_OPEN, rc,
pszFileName);
return(MSG_FILE_OPEN);
}
/* Validate TMI file. */
if (fgets(szLineTMI, MAXLINE, *phFile) == NULL){
(*pfnExit)(ERROR, PRINT_MSG, MSG_FILE_READ, rc,
pszFileName);
}
// # fxns
if (fgets(szLineTMI, MAXLINE, *phFile) == NULL){
(*pfnExit)(ERROR, PRINT_MSG, MSG_FILE_READ, rc,
pszFileName);
}
szLineTMI[strlen(szLineTMI) - 1] = '\0';
if (sscanf(szLineTMI,"/* Total Symbols= %u */", &cFxns) != 1){
(*pfnExit)(ERROR, PRINT_MSG, MSG_FILE_READ, rc,
pszFileName);
}
// MODNAME
if (fgets(szLineTMI, MAXLINE, *phFile) == NULL)
(*pfnExit)(ERROR, PRINT_MSG, MSG_FILE_READ, rc,
pszFileName);
// MAJOR
if (fgets(szLineTMI, MAXLINE, *phFile) == NULL)
(*pfnExit)(ERROR, PRINT_MSG, MSG_FILE_READ, rc,
pszFileName);
// TDFID
if (fgets(szLineTMI, MAXLINE, *phFile) == NULL)
(*pfnExit)(ERROR, PRINT_MSG, MSG_FILE_READ, rc,
pszFileName);
if (sscanf(szLineTMI, "TDFID = %s", szTDFID) != 1)
(*pfnExit)(ERROR, PRINT_MSG, MSG_FILE_READ, rc,
pszFileName);
ulTDFID = strtoul(szTDFID, (char **) 0, 0);
/* Check identifier field */
if (ulTDFID != (ULONG) usId)
(*pfnExit)(ERROR, PRINT_MSG, MSG_FILE_BAD_HDR, (ULONG)-1,
pszFileName);
return(cFxns);
}
/*
*
***EP WsTMIReadRec
*
* Effects:
*
* Reads a record from a TMI file, including the variable length function
* name.
*
* Returns:
*
* Function size, in bytes, from this record. If an error is
* encountered, exits with ERROR via an indirect call through pfnExit.
*/
ULONG FAR PASCAL
WsTMIReadRec( PSZ *ppszFxnName, PULONG pulFxnIndex, PULONG pulFxnAddr,
FILE *hFile, PFN pfnExit, PCHAR pch)
{
ULONG rc;
ULONG cbFxn;
UINT uiFxnAddrObj; // object portion of function address
ULONG cbFxnName; // size in bytes of function name
// Read in function name, etc.
rc = fscanf(hFile, "%ld %x:%lx 0x%lx %ul", // mdg 98/4
pulFxnIndex, &uiFxnAddrObj, pulFxnAddr, &cbFxn,
&cbFxnName);
if (rc != 5)
(*pfnExit)(ERROR, PRINT_MSG, MSG_FILE_READ, rc, "TMI file");
*ppszFxnName = malloc( 1 + cbFxnName ); // Allocate space for function name
if (*ppszFxnName == NULL) // Abort if no mem
(*pfnExit)(ERROR, PRINT_MSG, MSG_NO_MEM, 1 + cbFxnName, "TMI file");
rc = fgetc( hFile ); // Skip leading blank space
fgets( *ppszFxnName, cbFxnName + 1, hFile );
rc = fgetc( hFile );
if (rc != '\n' || strlen( *ppszFxnName ) != cbFxnName)
(*pfnExit)(ERROR, PRINT_MSG, MSG_FILE_READ, rc, "TMI file");
return(cbFxn);
}
LPVOID APIENTRY AllocAndLockMem(DWORD cbMem, HGLOBAL *hMem)
{
//
// Changed to GHND from GMEM_MOVABLE
//
*hMem = GlobalAlloc(GHND, cbMem);
if(!*hMem) {
return(NULL);
}
return(GlobalLock(*hMem));
}
BOOL APIENTRY UnlockAndFreeMem(HGLOBAL hMem)
{
BOOL fRet;
fRet = GlobalUnlock(hMem);
if (fRet) {
return(fRet);
}
if (!GlobalFree(hMem)) {
return(FALSE);
}
return(TRUE);
}
void
ConvertAppToOem( unsigned argc, char* argv[] )
/*++
Routine Description:
Converts the command line from ANSI to OEM, and force the app
to use OEM APIs
Arguments:
argc - Standard C argument count.
argv - Standard C argument strings.
Return Value:
None.
--*/
{
unsigned i;
for( i=0; i<argc; i++ ) {
CharToOem( argv[i], argv[i] );
}
SetFileApisToOEM();
}
/*
*
***EP WsIndicator
*
* Effects:
*
* Displays a progress indicator on the console. Doesn't use stdout which may be
* redirected.
*
* Parameters:
*
* eFunc Description nVal
* WSINDF_NEW, Start new indicator Value of 100% limit
* WSINDF_PROGRESS, Set progress of current indicator Value of progress toward limit
* WSINDF_FINISH Mark indicator as finished -ignored-
* -invalid- Do nothing
*
* In all valid cases, pszLabel sets string to display before indicator. If NULL,
* uses last set string.
*
* Returns:
*
* Function size, in bytes, from this record. If an error is
* encountered, exits with ERROR via an indirect call through pfnExit.
*/
VOID FAR PASCAL
WsProgress( WsIndicator_e eFunc, const char *pszLbl, unsigned long nVal )
{
static unsigned long
nLimit = 0, nCurrent = 0;
static const char *
pszLabel = "";
static unsigned nLabelLen = 0;
static char bStarted = FALSE;
static unsigned nLastLen = 0;
static HANDLE hConsole = NULL;
DWORD pnChars;
switch (eFunc)
{
case WSINDF_NEW:
if (bStarted)
WsIndicator( WSINDF_FINISH, NULL, 0 );
bStarted = TRUE;
nLimit = nVal;
nCurrent = 0;
nLastLen = ~0; // Force redraw
WsIndicator ( WSINDF_PROGRESS, pszLbl, 0 );
break;
case WSINDF_PROGRESS:
if (!bStarted)
break;
if (pszLbl != NULL)
{
pszLabel = pszLbl;
nLabelLen = strlen( pszLabel );
}
if (nVal > nCurrent) // Compare to current progress (ignore reverses)
if (nVal <= nLimit)
nCurrent = nVal;
else
nCurrent = nLimit;
{ // Calculate an indicator string and print it
unsigned nLen = (unsigned) ((40.1 * (double)nCurrent) / nLimit);
char * pszBuf;
if (nLastLen == nLen) // Optimization - Don't redraw if result would be the same
{
if (pszLbl == NULL)
break;
}
else
nLastLen = nLen;
if (hConsole == NULL)
{
hConsole = CreateFile( "CONOUT$", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL );
if (hConsole == NULL) // Couldn't get the console for some reason?
break;
}
WriteConsole( hConsole, "\r", 1, &pnChars, NULL );
WriteConsole( hConsole, pszLabel, nLabelLen, &pnChars, NULL );
WriteConsole( hConsole, " ", 1, &pnChars, NULL );
pszBuf = malloc( nLen + 1 );
if (pszBuf == NULL) // No memory? Oh, well...
break;
memset( pszBuf, '-', nLen );
pszBuf[nLen] = '\0';
WriteConsole( hConsole, pszBuf, nLen, &pnChars, NULL );
free( pszBuf);
}
break;
case WSINDF_FINISH:
if (!bStarted)
break;
WsIndicator( WSINDF_PROGRESS, pszLbl, nLimit );
if (hConsole != NULL)
{
WriteConsole( hConsole, "\n", 1, &pnChars, NULL );
CloseHandle( hConsole );
hConsole = NULL;
}
bStarted = FALSE;
}
}