653 lines
21 KiB
C
653 lines
21 KiB
C
#include "symutil.h"
|
|
|
|
|
|
typedef struct _FILE_INFO {
|
|
DWORD TimeDateStamp;
|
|
DWORD CheckSum;
|
|
TCHAR szName[MAX_PATH];
|
|
} FILE_INFO, *PFILE_INFO;
|
|
|
|
|
|
typedef struct _COMMAND_ARGS {
|
|
LPTSTR szDir; // Directory where source files exist
|
|
LPTSTR szFileName; // File name(s) to copy
|
|
FILE * hSymCDLog; // SymbolsCD log file
|
|
BOOL Recurse; // Recurse in subdirectories
|
|
LPTSTR szSymPath; // Directory where symbols exist
|
|
LPTSTR szExcludeFileName; // File name with list of files to exclude
|
|
// from symbol checking
|
|
LPTSTR szListFileName; // File containing a list of files to check
|
|
DWORD Split; // TRUE - check for split images
|
|
// FALSE - check for non-split images
|
|
BOOL Verbose; // Print info for every file checked,
|
|
// not just the ones that fail
|
|
LPTSTR szErrorFilterList; // Don't print errors for these files
|
|
LPTSTR szCDIncludeList; // Full path to symbols that should get
|
|
// written to the list that is used for creating
|
|
// the symbol CD. Originally used for
|
|
// international incremental builds
|
|
} COM_ARGS, *PCOM_ARGS;
|
|
|
|
typedef struct _FILE_COUNTS {
|
|
DWORD NumPassedFiles;
|
|
DWORD NumIgnoredFiles;
|
|
DWORD NumFailedFiles;
|
|
} FILE_COUNTS, *PFILE_COUNTS;
|
|
|
|
// Prototypes
|
|
|
|
PCOM_ARGS
|
|
GetCommandLineArgs(
|
|
int argc,
|
|
char **argv
|
|
);
|
|
|
|
VOID
|
|
Usage (
|
|
VOID
|
|
);
|
|
|
|
DWORD
|
|
CheckDirectory(
|
|
LPTSTR szDir,
|
|
LPTSTR szFName,
|
|
LPTSTR szSymPath,
|
|
FILE* hSymCDLog,
|
|
PEXCLUDE_LIST pExcludeList,
|
|
PFILE_COUNTS pFileCounts,
|
|
DWORD Split
|
|
);
|
|
|
|
DWORD
|
|
CheckAllDirectories(
|
|
LPTSTR szDir,
|
|
LPTSTR szFName,
|
|
LPTSTR szSymPath,
|
|
FILE* hSymCDLog,
|
|
PEXCLUDE_LIST pExcludeList,
|
|
PFILE_COUNTS pFileCounts,
|
|
DWORD Split
|
|
);
|
|
|
|
BOOL
|
|
CorrectPath(
|
|
LPTSTR szFileName,
|
|
LPTSTR szPathName,
|
|
LPTSTR szCorrectPath
|
|
);
|
|
|
|
// Global variables
|
|
|
|
BOOL Verbose = 0;
|
|
BOOL Retail = TRUE;
|
|
|
|
int
|
|
_cdecl
|
|
main( int argc, char **argv)
|
|
{
|
|
PCOM_ARGS pArgs;
|
|
DWORD NumBadFiles=0;
|
|
DWORD NumExcludeFiles=0;
|
|
|
|
DWORD i;
|
|
PEXCLUDE_LIST pExcludeList = NULL;
|
|
FILE_COUNTS FileCounts;
|
|
|
|
SYM_ERR SymErr;
|
|
TCHAR ErrMsg[MAX_SYM_ERR];
|
|
HFILE hListFile;
|
|
|
|
P_LIST FileList;
|
|
|
|
pArgs = GetCommandLineArgs(argc, argv);
|
|
Verbose = (BOOL)pArgs->Verbose;
|
|
|
|
memset( &SymErr, 0, sizeof(SymErr) );
|
|
memset( &FileCounts, 0, sizeof(FILE_COUNTS) );
|
|
|
|
if ( pArgs->szExcludeFileName != NULL ) {
|
|
pExcludeList = GetExcludeList(pArgs->szExcludeFileName);
|
|
}
|
|
|
|
if ( pArgs->szErrorFilterList != NULL ) {
|
|
pErrorFilterList = GetExcludeList(pArgs->szErrorFilterList);
|
|
}
|
|
|
|
if ( pArgs->szCDIncludeList != NULL ) {
|
|
pCDIncludeList = GetList( pArgs->szCDIncludeList );
|
|
}
|
|
|
|
// This is the section for creating the symbols CD.
|
|
if ( pArgs->szListFileName != NULL ) {
|
|
|
|
FileList = GetList(pArgs->szListFileName);
|
|
if ( FileList == NULL ) {
|
|
printf(" Cannot open the file list %s\n", pArgs->szListFileName);
|
|
exit(1);
|
|
}
|
|
|
|
if ( FileList->dNumFiles == 0 ) goto finish;
|
|
|
|
// Do the first one, so we don't have to check for it inside the loop
|
|
if ( CorrectPath(FileList->List[0].FName, FileList->List[0].Path, pArgs->szDir) ) {
|
|
NumBadFiles += CheckDirectory(
|
|
pArgs->szDir,
|
|
FileList->List[0].FName,
|
|
pArgs->szSymPath,
|
|
pArgs->hSymCDLog,
|
|
pExcludeList,
|
|
&FileCounts,
|
|
pArgs->Split
|
|
);
|
|
}
|
|
|
|
for ( i=1; i< FileList->dNumFiles; i++) {
|
|
|
|
// There may be some duplicates in the list ... skip them
|
|
// Also, only check the files that are in the path given on the command line
|
|
|
|
if ( (_tcsicmp(FileList->List[i].Path, FileList->List[i-1].Path) != 0) &&
|
|
CorrectPath(FileList->List[i].FName, FileList->List[i].Path, pArgs->szDir) ) {
|
|
|
|
NumBadFiles += CheckDirectory(
|
|
pArgs->szDir,
|
|
FileList->List[i].FName,
|
|
pArgs->szSymPath,
|
|
pArgs->hSymCDLog,
|
|
pExcludeList,
|
|
&FileCounts,
|
|
pArgs->Split
|
|
);
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
if ( !pArgs->Recurse ) {
|
|
NumBadFiles += CheckDirectory(
|
|
pArgs->szDir,
|
|
pArgs->szFileName,
|
|
pArgs->szSymPath,
|
|
pArgs->hSymCDLog,
|
|
pExcludeList,
|
|
&FileCounts,
|
|
pArgs->Split
|
|
);
|
|
} else {
|
|
NumBadFiles += CheckAllDirectories(
|
|
pArgs->szDir,
|
|
pArgs->szFileName,
|
|
pArgs->szSymPath,
|
|
pArgs->hSymCDLog,
|
|
pExcludeList,
|
|
&FileCounts,
|
|
pArgs->Split
|
|
);
|
|
}
|
|
|
|
// CheckDirectory just returns the number of failed and passed. If
|
|
// no files failed or passed, then report that we couldn't find the
|
|
// file.
|
|
|
|
if ( (FileCounts.NumFailedFiles + FileCounts.NumPassedFiles) == 0 ) {
|
|
_tcscpy( SymErr.szFileName, pArgs->szFileName );
|
|
SymErr.Verbose=pArgs->Verbose;
|
|
if (InExcludeList(SymErr.szFileName, pExcludeList) ) {
|
|
LogError(ErrMsg, &SymErr, IMAGE_PASSED );
|
|
FileCounts.NumPassedFiles=1;
|
|
} else {
|
|
LogError(ErrMsg, &SymErr, FILE_NOT_FOUND);
|
|
FileCounts.NumFailedFiles=1;
|
|
}
|
|
if ( _tcscmp(ErrMsg, "") != 0 ) {
|
|
printf("SYMCHK: %s",ErrMsg);
|
|
}
|
|
}
|
|
}
|
|
|
|
finish:
|
|
|
|
if (pArgs->hSymCDLog) fclose(pArgs->hSymCDLog);
|
|
|
|
free(pArgs->szDir);
|
|
free(pArgs->szFileName);
|
|
free(pArgs);
|
|
|
|
printf("\nSYMCHK: FAILED files = %d\n",FileCounts.NumFailedFiles);
|
|
printf("SYMCHK: PASSED + IGNORED files = %d\n",FileCounts.NumPassedFiles);
|
|
|
|
if ( FileCounts.NumFailedFiles > 0 ) {
|
|
return(1);
|
|
} else {
|
|
return(0);
|
|
}
|
|
}
|
|
|
|
DWORD
|
|
CheckAllDirectories(
|
|
LPTSTR szDir,
|
|
LPTSTR szFName,
|
|
LPTSTR szSymPath,
|
|
FILE* hSymCDLog,
|
|
PEXCLUDE_LIST pExcludeList,
|
|
PFILE_COUNTS pFileCounts,
|
|
DWORD Split
|
|
)
|
|
|
|
{
|
|
HANDLE hFindFile;
|
|
TCHAR szCurPath[_MAX_PATH];
|
|
BOOL Found = FALSE;
|
|
DWORD NumBadFiles=0;
|
|
|
|
WIN32_FIND_DATA FindFileData;
|
|
LPTSTR szF = NULL;
|
|
LPTSTR szE = NULL;
|
|
|
|
FILE_COUNTS FileCounts;
|
|
|
|
NumBadFiles += CheckDirectory(szDir,
|
|
szFName,
|
|
szSymPath,
|
|
hSymCDLog,
|
|
pExcludeList,
|
|
pFileCounts,
|
|
Split
|
|
);
|
|
|
|
// Look for all the subdirectories
|
|
_tcscpy(szCurPath, szDir);
|
|
_tcscat(szCurPath, _T("\\*.*") );
|
|
|
|
Found = TRUE;
|
|
hFindFile = FindFirstFile((LPCTSTR)szCurPath, &FindFileData);
|
|
if ( hFindFile == INVALID_HANDLE_VALUE) {
|
|
Found = FALSE;
|
|
}
|
|
|
|
while ( Found ) {
|
|
if ( FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
|
|
|
|
if ( !_tcscmp(FindFileData.cFileName, _T(".")) ||
|
|
!_tcscmp(FindFileData.cFileName, _T("..")) ||
|
|
!_tcsicmp(FindFileData.cFileName, _T("symbols")) ) {
|
|
// Don't process these directories
|
|
} else {
|
|
// Get the current path that we are searching in
|
|
_tcscpy(szCurPath, szDir);
|
|
_tcscat(szCurPath, _T("\\"));
|
|
_tcscat(szCurPath, FindFileData.cFileName);
|
|
|
|
NumBadFiles += CheckAllDirectories(
|
|
szCurPath,
|
|
szFName,
|
|
szSymPath,
|
|
hSymCDLog,
|
|
pExcludeList,
|
|
pFileCounts,
|
|
Split
|
|
);
|
|
}
|
|
}
|
|
Found = FindNextFile(hFindFile, &FindFileData);
|
|
}
|
|
FindClose(hFindFile);
|
|
return(NumBadFiles);
|
|
}
|
|
|
|
DWORD
|
|
CheckDirectory(
|
|
LPTSTR szDir,
|
|
LPTSTR szFName,
|
|
LPTSTR szSymPath,
|
|
FILE * hSymCDLog,
|
|
PEXCLUDE_LIST pExcludeList,
|
|
PFILE_COUNTS pFileCounts,
|
|
DWORD Split
|
|
)
|
|
|
|
{
|
|
HANDLE hFindFile;
|
|
TCHAR szFileName[_MAX_PATH];
|
|
TCHAR szCurPath[_MAX_PATH];
|
|
TCHAR szCurFileName[_MAX_PATH];
|
|
BOOL Found;
|
|
DWORD NumBadFiles=0;
|
|
DWORD NumGoodFiles=0;
|
|
|
|
WIN32_FIND_DATA FindFileData;
|
|
SYM_ERR SymErr;
|
|
TCHAR ErrMsg[MAX_SYM_ERR];
|
|
|
|
memset( &SymErr, 0, sizeof(SymErr) );
|
|
|
|
// Create the file name
|
|
_tcscpy(szFileName, szDir);
|
|
_tcscat(szFileName, _T("\\") );
|
|
_tcscat(szFileName, szFName);
|
|
|
|
// Get the current path that we are searching in
|
|
_tcscpy(szCurPath, szDir);
|
|
|
|
Found = TRUE;
|
|
hFindFile = FindFirstFile((LPCTSTR)szFileName, &FindFileData);
|
|
if ( hFindFile == INVALID_HANDLE_VALUE ) {
|
|
Found = FALSE;
|
|
}
|
|
|
|
while ( Found ) {
|
|
// Found a file, not a directory
|
|
if ( !(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ) {
|
|
|
|
_tcscpy(szCurFileName, szCurPath);
|
|
_tcscat(szCurFileName,_T("\\") );
|
|
_tcscat(szCurFileName, FindFileData.cFileName );
|
|
|
|
// Its not in the exclude list, go ahead and test it
|
|
|
|
if (!InExcludeList(FindFileData.cFileName,pExcludeList ) ) {
|
|
|
|
if ( !CheckSymbols( ErrMsg,
|
|
szSymPath,
|
|
szCurFileName,
|
|
hSymCDLog,
|
|
Split,
|
|
Verbose,
|
|
NULL ) ) {
|
|
pFileCounts->NumFailedFiles++;
|
|
NumBadFiles++;
|
|
} else {
|
|
pFileCounts->NumPassedFiles++;
|
|
}
|
|
}
|
|
|
|
// It is in the exclude list, add it to NumPassed Files
|
|
else {
|
|
pFileCounts->NumPassedFiles++;
|
|
_tcscpy(SymErr.szFileName, szCurFileName);
|
|
SymErr.Verbose = Verbose;
|
|
LogError(ErrMsg, &SymErr, IMAGE_PASSED);
|
|
}
|
|
if ( _tcscmp(ErrMsg,"") != 0 ) {
|
|
printf("SYMCHK: %s", ErrMsg);
|
|
}
|
|
}
|
|
Found = FindNextFile(hFindFile, &FindFileData);
|
|
}
|
|
FindClose(hFindFile);
|
|
return(NumBadFiles);
|
|
}
|
|
|
|
|
|
VOID
|
|
Usage (
|
|
VOID
|
|
)
|
|
|
|
{
|
|
puts("\n"
|
|
"Usage: symchk [switches] file /s sympath \n\n"
|
|
" file Name of file(s) or directory to check.\n"
|
|
" Can include wildcards.\n\n"
|
|
" [/b] For NT4 Service Packs -- don't complain if\n"
|
|
" there is no CodeView data\n"
|
|
" [/e file] File containing a list of files to exclude.\n"
|
|
" This file can have one name per line. Comment\n"
|
|
" lines begin with a ; . \n\n"
|
|
" [/p] Check that private information is removed.\n"
|
|
" [/c dest] Create an inf for the symbols CD\n\n"
|
|
" [/r] Recurse into subdirectories. This uses the\n"
|
|
" Windows 2000 build model and assumes that the\n"
|
|
" first subdirectory to traverse into is the retail\n"
|
|
" directory. Example sympath: \"E:\\binaries\\symbols\" .\n"
|
|
" All subdirectories except \"symbols\" will be checked.\n\n"
|
|
" /s sympath symbol path delimited by ; . Checks sympath\n"
|
|
" and sympath\\ext for each string in the path, \n"
|
|
" where ext is the extension of the executable.\n\n"
|
|
" [/t] Fail if a DBG file is involved. Fails if the image points\n"
|
|
" to a dbg file or if it contains data that can be stripped\n"
|
|
" into a dbg file. Default is to fail if data can be stripped\n"
|
|
" into a dbg file, but don't fail if the image points to a\n"
|
|
" dbg file.\n\n"
|
|
" [/u] Fail if image points to a dbg file. Don't fail if image\n"
|
|
" contains data that can be split into a dbg file.\n\n"
|
|
" [/v] Give verbose information\n"
|
|
" [/x] Used with /c. Perform symbol checking on these files and\n"
|
|
" add the correct symbols to the symbol CD's inf, but\n"
|
|
" don't write error messages for the ones that are wrong.\n\n"
|
|
);
|
|
|
|
exit(1);
|
|
|
|
// The purpose of /x is to not log errors for symbols in symbad.txt. However, symchk
|
|
// should check all of the files in symbad.txt when it is creating the list of file
|
|
// in case some of them actually have correct symbols and symbad hasn't been updated yet.
|
|
}
|
|
|
|
|
|
PCOM_ARGS
|
|
GetCommandLineArgs(
|
|
int argc,
|
|
char **argv
|
|
)
|
|
|
|
{
|
|
PCOM_ARGS pArgs;
|
|
int i,cur,length;
|
|
TCHAR c;
|
|
BOOL NeedSecond = FALSE;
|
|
BOOL Exclude = FALSE;
|
|
|
|
LPTSTR szFileArg = NULL;
|
|
TCHAR szDrive[_MAX_DRIVE + 1];
|
|
TCHAR szDir[_MAX_DIR + 1];
|
|
TCHAR szFileName[_MAX_FNAME + 1];
|
|
TCHAR szExt[_MAX_EXT + 1];
|
|
TCHAR szNameExt[_MAX_FNAME + _MAX_EXT + 1];
|
|
LPTSTR szSymCDLog = NULL;
|
|
LPTSTR szSymbolsCDFile = NULL;
|
|
|
|
HANDLE fHandle;
|
|
WIN32_FIND_DATA FindFileData;
|
|
|
|
if (argc == 1) Usage();
|
|
|
|
if (!(pArgs = (PCOM_ARGS)malloc(sizeof(COM_ARGS))))
|
|
{
|
|
printf("No memory");
|
|
exit(1);
|
|
}
|
|
|
|
memset( pArgs, 0, sizeof(COM_ARGS) );
|
|
pArgs->Split = 0;
|
|
pArgs->szListFileName = NULL;
|
|
pArgs->szCDIncludeList = NULL;
|
|
|
|
CheckPrivate = FALSE;
|
|
|
|
for (i=1; i<argc; i++) {
|
|
|
|
if (!NeedSecond) {
|
|
if ( (argv[i][0] == '/') || (argv[i][0] == '-') ) {
|
|
length = _tcslen(argv[i]) -1;
|
|
|
|
for (cur=1; cur <= length; cur++) {
|
|
c = argv[i][cur];
|
|
|
|
switch (c) {
|
|
case 'c': NeedSecond = TRUE;
|
|
break;
|
|
case 'b': CheckCodeView=FALSE;
|
|
NeedSecond = FALSE;
|
|
break;
|
|
case 'e': Exclude = TRUE;
|
|
NeedSecond = TRUE;
|
|
if ( length > cur) Usage();
|
|
break;
|
|
case 'l': NeedSecond = TRUE;
|
|
break;
|
|
case 'p': NeedSecond = FALSE;
|
|
CheckPrivate = TRUE;
|
|
break;
|
|
case 'r': pArgs->Recurse = TRUE;
|
|
Recurse = TRUE;
|
|
break;
|
|
case 's': NeedSecond = TRUE;
|
|
if ( length > cur) Usage();
|
|
break;
|
|
case 't':
|
|
pArgs->Split |= ERROR_IF_NOT_SPLIT;
|
|
pArgs->Split |= ERROR_IF_SPLIT;
|
|
break;
|
|
case 'u': pArgs->Split |= ERROR_IF_SPLIT;
|
|
break;
|
|
case 'v': pArgs->Verbose = TRUE;
|
|
break;
|
|
case 'x': NeedSecond = TRUE;
|
|
break;
|
|
case 'y': NeedSecond = TRUE;
|
|
break;
|
|
default: Usage();
|
|
}
|
|
}
|
|
} else {
|
|
if (szFileArg != NULL) Usage();
|
|
szFileArg = argv[i];
|
|
}
|
|
} else {
|
|
NeedSecond = FALSE;
|
|
switch (c) {
|
|
case 'c': szSymbolsCDFile = argv[i];
|
|
break;
|
|
case 'e': pArgs->szExcludeFileName = argv[i];
|
|
break;
|
|
case 'l': pArgs->szListFileName = argv[i];
|
|
break;
|
|
case 's': pArgs->szSymPath = argv[i];
|
|
break;
|
|
case 'x': pArgs->szErrorFilterList = argv[i];
|
|
break;
|
|
case 'y': pArgs->szCDIncludeList = argv[i];
|
|
break;
|
|
default: Usage();
|
|
|
|
}
|
|
}
|
|
}
|
|
if ( pArgs->Split == 0 ) {
|
|
// This has always been the default behavior
|
|
pArgs->Split = ERROR_IF_NOT_SPLIT;
|
|
}
|
|
|
|
if ( szFileArg == NULL ) Usage();
|
|
|
|
// make the Symbol Copy log for the Support Tools CD
|
|
if ( szSymbolsCDFile != NULL ) {
|
|
|
|
if ( (pArgs->hSymCDLog = fopen(szSymbolsCDFile, "a+")) == NULL ) {
|
|
printf("Cannot open %s for appending\n",szSymbolsCDFile);
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
|
|
// Get the filenames so they are correct
|
|
_tsplitpath( szFileArg, szDrive, szDir, szFileName, szExt );
|
|
|
|
// Get current directory if they didn't enter a directory
|
|
if ( !_tcscmp(szDrive, "") && !_tcscmp(szDir,"") ) {
|
|
GetCurrentDirectory(_MAX_DIR, szDir);
|
|
}
|
|
|
|
// If szFileName and szExt are "" then put *.* in them
|
|
if ( !_tcscmp(szFileName,"") && !_tcscmp(szExt,"") ) {
|
|
_tcscpy(szFileName,"*");
|
|
}
|
|
|
|
// User may have entered a directory with an implies * for the
|
|
// file name.
|
|
fHandle = FindFirstFile( szFileArg, &FindFileData );
|
|
|
|
_tcscpy(szNameExt, szFileName);
|
|
_tcscat(szNameExt, szExt);
|
|
|
|
// If its a directory and the name of the directory matches
|
|
// the filename.ext from the command line parameter, then the user
|
|
// entered a directory, so add * to the end.
|
|
|
|
if ( (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
|
|
(_tcscmp( szNameExt, FindFileData.cFileName )== 0) ) {
|
|
|
|
// Move the filename to be the dir
|
|
_tcscat( szDir, "\\");
|
|
_tcscat( szDir, szFileName);
|
|
|
|
// Put the file name as *
|
|
_tcscpy(szFileName, "*");
|
|
}
|
|
|
|
pArgs->szDir=(LPTSTR) malloc( sizeof(TCHAR)* _MAX_PATH + 1 );
|
|
_tmakepath( pArgs->szDir, szDrive, szDir, NULL, NULL);
|
|
|
|
pArgs->szFileName = (LPTSTR) malloc( sizeof(TCHAR) * _MAX_PATH + 1 );
|
|
_tmakepath(pArgs->szFileName, NULL, NULL, szFileName, szExt);
|
|
|
|
|
|
// Check that everything has been entered
|
|
if (NeedSecond ||
|
|
(pArgs->szFileName == NULL) ||
|
|
(pArgs->szDir == NULL) ||
|
|
(pArgs->szSymPath == NULL) )
|
|
{
|
|
Usage();
|
|
}
|
|
|
|
return (pArgs);
|
|
}
|
|
|
|
BOOL
|
|
CorrectPath(
|
|
LPTSTR szFileName,
|
|
LPTSTR szPathName,
|
|
LPTSTR szCorrectPath
|
|
)
|
|
{
|
|
// To return TRUE, szPathName should equal szCorrectPath + \ + szFileName
|
|
// The only hitch is that there could be extraneous \'s
|
|
|
|
TCHAR CorrectPathx[_MAX_PATH + _MAX_FNAME + _MAX_EXT + 1];
|
|
TCHAR PathNamex[_MAX_PATH + _MAX_FNAME + _MAX_EXT + 1];
|
|
|
|
LONG length, index, i;
|
|
|
|
// Get rid of any extra \'s
|
|
length = _tcslen(szPathName);
|
|
PathNamex[0] = szPathName[0];
|
|
index = 1;
|
|
for (i=1; i<=length; i++) {
|
|
if ( (szPathName[i-1] != '\\') || (szPathName[i] != '\\') ) {
|
|
PathNamex[index] = szPathName[i];
|
|
index++;
|
|
}
|
|
}
|
|
|
|
length = _tcslen(szCorrectPath);
|
|
CorrectPathx[0] = szCorrectPath[0];
|
|
index = 1;
|
|
for (i=1; i<=length; i++) {
|
|
if ( (szCorrectPath[i-1] != '\\') || (szCorrectPath[i] != '\\') ) {
|
|
CorrectPathx[index] = szCorrectPath[i];
|
|
index++;
|
|
}
|
|
}
|
|
|
|
// Make sure that the correct path doesn't end in a '\'
|
|
length = _tcslen(CorrectPathx);
|
|
if ( CorrectPathx[length-1] == '\\' ) CorrectPathx[length-1] = '\0';
|
|
|
|
_tcscat(CorrectPathx,"\\");
|
|
_tcscat(CorrectPathx,szFileName);
|
|
|
|
if ( _tcsicmp(CorrectPathx, szPathName) == 0) return TRUE;
|
|
else return FALSE;
|
|
}
|