268 lines
8.4 KiB
C
268 lines
8.4 KiB
C
|
/*++
|
||
|
|
||
|
Copyright (c) 1992 Microsoft Corporation
|
||
|
|
||
|
Module Name:
|
||
|
|
||
|
splitsym.c
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
This is the main source file for the SPLITSYM utility program. This
|
||
|
program can be used to split the debugging information contained in
|
||
|
an executable image file into a separate .DBG file and strip it from
|
||
|
the image file. Allow stripped image files to be distributed which
|
||
|
significantly reduces disk space requirements, but allows full
|
||
|
debugging by accesing the associated .DBG files over the network
|
||
|
when needed.
|
||
|
|
||
|
Author:
|
||
|
|
||
|
Steve Wood (stevewo) 03-May-1993
|
||
|
|
||
|
Revision History:
|
||
|
|
||
|
--*/
|
||
|
|
||
|
#include <private.h>
|
||
|
#include <splitsymx.h>
|
||
|
|
||
|
|
||
|
BOOL fVerbose;
|
||
|
BOOL fRecurse;
|
||
|
ULONG SplitFlags = 0;
|
||
|
|
||
|
UCHAR RecurseDirectory[ MAX_PATH ];
|
||
|
|
||
|
UCHAR CurrentImageName[ MAX_PATH ];
|
||
|
|
||
|
UCHAR SymbolPath[ MAX_PATH ];
|
||
|
UCHAR RSDSDllPath[ MAX_PATH ];
|
||
|
|
||
|
UCHAR DbgFileName[ MAX_PATH ];
|
||
|
|
||
|
VOID
|
||
|
SplitSymbolsInTree(
|
||
|
LPSTR RootPath
|
||
|
);
|
||
|
|
||
|
void
|
||
|
Usage( void )
|
||
|
{
|
||
|
fputs ( "usage: SPLITSYM [-?] [-v] [-p] [-a] [-s symbol directory] [-r directory] image-names...\n"
|
||
|
" [-?] display this message\n"
|
||
|
" [-v] verbose output\n"
|
||
|
" [-p] remove private debug info when creating .dbg file\n"
|
||
|
" [-a] extract all debug info into .dbg file\n"
|
||
|
" [-m] RSDS dll to load, default is mspdb70.dll\n"
|
||
|
" [-r directory] - recursively process all image files.\n"
|
||
|
" [-s symbol directory] - where to put .DBG files.\n"
|
||
|
" Default is same place as image file.\n",
|
||
|
stderr );
|
||
|
exit( 1 );
|
||
|
}
|
||
|
|
||
|
int __cdecl
|
||
|
main(
|
||
|
int argc,
|
||
|
char *argv[],
|
||
|
char *envp[]
|
||
|
)
|
||
|
{
|
||
|
char c, *s;
|
||
|
LPSTR FilePart;
|
||
|
|
||
|
if (argc <= 1) {
|
||
|
Usage();
|
||
|
}
|
||
|
|
||
|
strcpy(RSDSDllPath, "mspdb70.dll");
|
||
|
|
||
|
SymbolPath[ 0 ] = '\0';
|
||
|
while (--argc) {
|
||
|
s = *++argv;
|
||
|
if (*s == '/' || *s == '-') {
|
||
|
while (c = *++s)
|
||
|
switch (toupper( c )) {
|
||
|
case '?':
|
||
|
Usage();
|
||
|
break;
|
||
|
|
||
|
case 'M':
|
||
|
if (--argc) {
|
||
|
strcpy( (PCHAR) RSDSDllPath, *++argv );
|
||
|
}
|
||
|
else {
|
||
|
fprintf( stderr, "SPLITSYM: Argument to /%c switch missing\n", c );
|
||
|
Usage();
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case 'V':
|
||
|
fVerbose = TRUE;
|
||
|
break;
|
||
|
|
||
|
case 'R':
|
||
|
if (--argc) {
|
||
|
fRecurse = TRUE;
|
||
|
strcpy( (PCHAR) RecurseDirectory, *++argv );
|
||
|
}
|
||
|
else {
|
||
|
fprintf( stderr, "SPLITSYM: Argument to /%c switch missing\n", c );
|
||
|
Usage();
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case 'S':
|
||
|
if (--argc) {
|
||
|
strcpy( (PCHAR) SymbolPath, *++argv );
|
||
|
}
|
||
|
else {
|
||
|
fprintf( stderr, "SPLITSYM: Argument to /%c switch missing\n", c );
|
||
|
Usage();
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case 'P':
|
||
|
SplitFlags |= SPLITSYM_REMOVE_PRIVATE;
|
||
|
break;
|
||
|
|
||
|
case 'A':
|
||
|
SplitFlags |= SPLITSYM_EXTRACT_ALL;
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
fprintf( stderr, "SPLITSYM: Invalid switch - /%c\n", c );
|
||
|
Usage();
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
if (fRecurse) {
|
||
|
fprintf( stderr, "SPLITSYM: May not specify specific file names with /R switch.\n" );
|
||
|
Usage();
|
||
|
}
|
||
|
else
|
||
|
if (!GetFullPathNameA( s, sizeof( CurrentImageName ), (PCHAR) CurrentImageName, &FilePart )) {
|
||
|
fprintf( stderr, "SPLITSYM: invalid file name - %s (%u)\n", s, GetLastError() );
|
||
|
}
|
||
|
else {
|
||
|
if (SplitSymbolsX( (PCHAR) CurrentImageName, (PCHAR) SymbolPath, (PCHAR) DbgFileName,
|
||
|
SplitFlags, RSDSDllPath, NULL, 0L )) {
|
||
|
if (fVerbose) {
|
||
|
fprintf( stdout,
|
||
|
"SPLITSYM: %16s symbols split into %s\n",
|
||
|
FilePart,
|
||
|
DbgFileName
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
if (GetLastError() != ERROR_BAD_EXE_FORMAT &&
|
||
|
GetLastError() != ERROR_ALREADY_ASSIGNED
|
||
|
) {
|
||
|
fprintf( stderr, "SPLITSYM: Unable to split symbols from '%s' into '%s' (%u)\n",
|
||
|
CurrentImageName,
|
||
|
DbgFileName,
|
||
|
GetLastError()
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (fRecurse) {
|
||
|
SplitSymbolsInTree( (PCHAR) RecurseDirectory );
|
||
|
}
|
||
|
|
||
|
exit( 0 );
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
#define MAX_DEPTH 32
|
||
|
|
||
|
VOID
|
||
|
SplitSymbolsInTree(
|
||
|
LPSTR RootPath
|
||
|
)
|
||
|
{
|
||
|
LPSTR FilePart;
|
||
|
PUCHAR Prefix = (PUCHAR) "";
|
||
|
CHAR PathBuffer[ MAX_PATH ];
|
||
|
ULONG Depth;
|
||
|
PCHAR PathTail[ MAX_DEPTH ];
|
||
|
PCHAR FindHandle[ MAX_DEPTH ];
|
||
|
LPWIN32_FIND_DATA FindFileData;
|
||
|
UCHAR FindFileBuffer[ MAX_PATH + sizeof( WIN32_FIND_DATA ) ];
|
||
|
|
||
|
strcpy( PathBuffer, RootPath );
|
||
|
FindFileData = (LPWIN32_FIND_DATA)FindFileBuffer;
|
||
|
Depth = 0;
|
||
|
while (TRUE) {
|
||
|
startDirectorySearch:
|
||
|
PathTail[ Depth ] = strchr( PathBuffer, '\0' );
|
||
|
if (PathTail[ Depth ] > PathBuffer && PathTail[ Depth ][ -1 ] != '\\') {
|
||
|
*(PathTail[ Depth ])++ = '\\';
|
||
|
}
|
||
|
|
||
|
strcpy( PathTail[ Depth ], "*.*" );
|
||
|
FindHandle[ Depth ] = (PCHAR) FindFirstFile( PathBuffer, FindFileData );
|
||
|
if (FindHandle[ Depth ] != INVALID_HANDLE_VALUE) {
|
||
|
do {
|
||
|
if (FindFileData->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
|
||
|
if (strcmp( FindFileData->cFileName, "." ) &&
|
||
|
strcmp( FindFileData->cFileName, ".." ) &&
|
||
|
Depth < MAX_DEPTH
|
||
|
) {
|
||
|
sprintf( PathTail[ Depth ], "%s\\", FindFileData->cFileName );
|
||
|
Depth++;
|
||
|
goto startDirectorySearch;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
if (!(FindFileData->dwFileAttributes & FILE_ATTRIBUTE_READONLY)) {
|
||
|
strcpy( PathTail[ Depth ], FindFileData->cFileName );
|
||
|
if (!GetFullPathNameA( PathBuffer, sizeof( CurrentImageName ), (PCHAR) CurrentImageName, &FilePart )) {
|
||
|
fprintf( stderr, "SPLITSYM: invalid file name - %s (%u)\n", PathBuffer, GetLastError() );
|
||
|
}
|
||
|
else {
|
||
|
if (SplitSymbolsX( (PCHAR) CurrentImageName, (PCHAR) SymbolPath, (PCHAR) DbgFileName,
|
||
|
SplitFlags, RSDSDllPath, NULL, 0L )) {
|
||
|
if (fVerbose) {
|
||
|
fprintf( stdout,
|
||
|
"SPLITSYM: %16s symbols split into %s\n",
|
||
|
FilePart,
|
||
|
DbgFileName
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
if (GetLastError() != ERROR_BAD_EXE_FORMAT ) {
|
||
|
fprintf( stderr, "SPLITSYM: Unable to split symbols from '%s' into '%s' (%u)\n",
|
||
|
CurrentImageName,
|
||
|
DbgFileName,
|
||
|
GetLastError()
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
restartDirectorySearch:
|
||
|
;
|
||
|
}
|
||
|
while (FindNextFile( FindHandle[ Depth ], FindFileData ));
|
||
|
FindClose( FindHandle[ Depth ] );
|
||
|
|
||
|
if (Depth == 0) {
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
Depth--;
|
||
|
goto restartDirectorySearch;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return;
|
||
|
}
|