Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

148 lines
4.8 KiB

#include <private.h>
#include <errno.h>
#include <strsafe.h>
//
// Invokes symchk.exe to validate symbols
//
BOOL CheckSymbols(LPSTR SourceFileName,
LPSTR TmpPath,
LPSTR ExcludeFileName,
BOOL DbgControl,
// ErrMsg is MAX_SYM_ERR * sizeof(CHAR) in length
LPSTR ErrMsg,
size_t ErrMsgLen) {
BOOL bReturn = TRUE;
DWORD dwReturn;
FILE *pfErrors;
INT iReturn;
TCHAR szBuf[ MAX_PATH*4 ];
TCHAR szTempPath[MAX_PATH+1];
TCHAR szTempFileName[MAX_PATH+1];
TCHAR *pChar;
UINT uiReturn;
//
// Find the temp dir
//
dwReturn = GetTempPath(MAX_PATH+1, szTempPath);
if (dwReturn == 0) {
// GetTempPath failed, just use the current directory.
StringCbCopy(szTempPath,sizeof(szTempPath),".");
}
//
// Get a temp file to pipe output to
//
uiReturn= GetTempFileName(szTempPath, "BNP", 0, szTempFileName);
if (uiReturn == 0) {
StringCbCopy(ErrMsg, ErrMsgLen, "Unable to get temporary file name");
return(FALSE);
}
//
// Build the command line
//
StringCbPrintfA(szBuf,
sizeof(szBuf),
"symchk.exe %s /s %s /f ",
SourceFileName,
TmpPath);
// Optional flags
if ( DbgControl ) {
StringCbCat( szBuf, sizeof(szBuf), " /t");
}
if ( ExcludeFileName != NULL ) {
StringCbCat( szBuf, sizeof(szBuf), " /e ");
StringCbCat( szBuf, sizeof(szBuf), ExcludeFileName );
}
// Redirect the output to a file
StringCbCat( szBuf, sizeof(szBuf), " > ");
StringCbCat( szBuf, sizeof(szBuf), szTempFileName);
// From Oct 2001 MSDN:
// You must explicitly flush (using fflush or _flushall) or close any stream before calling system
// It doesn't specify if stdin, stderr, and stdout are included here, so call it just to
// be safe.
_flushall();
//
// Spawn off symchk.exe - this is a security risk since we don't specifically specify the path
// to symchk.exe. However, we can't guarentee that it exists nor that
// if we find it dynamically that the correct one will be used so I'm not
// certain that we can do this any differently.
//
iReturn = system(szBuf);
// Check for Error line in the output file
if (iReturn != 0) {
bReturn = FALSE;
// symchk error return value
if (iReturn == 1) {
// open the error file
pfErrors = fopen(szTempFileName, "r");
// if the file couldn't be opened
if (pfErrors == NULL) {
StringCbCopy(ErrMsg, ErrMsgLen, "Can't open symchk error file");
// parse the error file
} else {
if ( fgets( ErrMsg, ErrMsgLen, pfErrors ) == NULL) {
if ( feof(pfErrors) || ferror(pfErrors) ) {
StringCbCopy(ErrMsg, ErrMsgLen, "Can't read symchk error file");
} else {
StringCbCopy(ErrMsg, ErrMsgLen, "Unexpected error");
}
} else if ( (pChar = strchr(ErrMsg,'\n')) != NULL ) {
// remove \n
pChar = '\0';
// message is too short to be meaningful
if (strlen(ErrMsg) <= 8) {
StringCbCopy(ErrMsg, ErrMsgLen, "Unknown Error");
}
}
fclose(pfErrors);
}
// system defined errors
} else if (errno == E2BIG ||
errno == ENOENT ||
errno == ENOMEM) {
pChar = strerror(errno);
StringCbCopy(ErrMsg, ErrMsgLen, pChar);
// system defined errors intentionally ignored
} else if (errno == ENOEXEC) {
// If we return FALSE, binplace is going to start returning up the call stack, so just print
// our own error message and pretend everything is fine by returning TRUE.
fprintf(stderr,"BINPLACE : error BNP2404: Unable to call symchk.exe, not checking symbols.\n");
bReturn = TRUE;
// unknown error
} else {
StringCbPrintfA(ErrMsg, ErrMsgLen, "Unexpected error. SymChk returned 0x%x.",iReturn);
}
}
// cleanup the temp file and return
if ( DeleteFile(szTempFileName) == 0 ) {
fprintf(stderr,"BINPLACE : warning BNP2440: Unable to delete temp file \"%s\". Error 0x%x\n.",
szTempFileName, GetLastError());
}
return(bReturn);
}