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.

272 lines
9.1 KiB

  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. splitsym.c
  5. Abstract:
  6. This is the main source file for the SPLITSYM utility program. This
  7. program can be used to split the debugging information contained in
  8. an executable image file into a separate .DBG file and strip it from
  9. the image file. Allow stripped image files to be distributed which
  10. significantly reduces disk space requirements, but allows full
  11. debugging by accesing the associated .DBG files over the network
  12. when needed.
  13. Author:
  14. Steve Wood (stevewo) 03-May-1993
  15. Revision History:
  16. --*/
  17. #include <private.h>
  18. #include <splitsymx.h>
  19. #include <strsafe.h>
  20. BOOL fVerbose;
  21. BOOL fRecurse;
  22. ULONG SplitFlags = 0;
  23. UCHAR RecurseDirectory[MAX_PATH + 1];
  24. UCHAR CurrentImageName[ MAX_PATH ];
  25. UCHAR SymbolPath[MAX_PATH + 1];
  26. UCHAR RSDSDllPath[MAX_PATH + 1];
  27. UCHAR DbgFileName[ MAX_PATH ];
  28. VOID
  29. SplitSymbolsInTree(
  30. LPSTR RootPath
  31. );
  32. void
  33. Usage( void )
  34. {
  35. fputs ( "usage: SPLITSYM [-?] [-v] [-p] [-a] [-s symbol directory] [-r directory] image-names...\n"
  36. " [-?] display this message\n"
  37. " [-v] verbose output\n"
  38. " [-p] remove private debug info when creating .dbg file\n"
  39. " [-a] extract all debug info into .dbg file\n"
  40. " [-m] RSDS dll to load, default is mspdb70.dll\n"
  41. " [-r directory] - recursively process all image files.\n"
  42. " [-s symbol directory] - where to put .DBG files.\n"
  43. " Default is same place as image file.\n",
  44. stderr );
  45. exit( 1 );
  46. }
  47. int __cdecl
  48. main(
  49. int argc,
  50. char *argv[],
  51. char *envp[]
  52. )
  53. {
  54. char c, *s;
  55. LPSTR FilePart;
  56. CHAR PdbName[MAX_PATH] = "";
  57. if (argc <= 1) {
  58. Usage();
  59. }
  60. StringCchCopy(RSDSDllPath, MAX_PATH, "mspdb70.dll");
  61. SymbolPath[ 0 ] = '\0';
  62. while (--argc) {
  63. s = *++argv;
  64. if (*s == '/' || *s == '-') {
  65. while (c = *++s)
  66. switch (toupper( c )) {
  67. case '?':
  68. Usage();
  69. break;
  70. case 'M':
  71. if (--argc) {
  72. StringCchCopy(RSDSDllPath, MAX_PATH, *++argv );
  73. }
  74. else {
  75. fprintf( stderr, "SPLITSYM: Argument to /%c switch missing\n", c );
  76. Usage();
  77. }
  78. break;
  79. case 'V':
  80. fVerbose = TRUE;
  81. break;
  82. case 'R':
  83. if (--argc) {
  84. fRecurse = TRUE;
  85. StringCchCopy(RecurseDirectory, MAX_PATH, *++argv);
  86. }
  87. else {
  88. fprintf( stderr, "SPLITSYM: Argument to /%c switch missing\n", c );
  89. Usage();
  90. }
  91. break;
  92. case 'S':
  93. if (--argc) {
  94. StringCchCopy(SymbolPath, MAX_PATH, *++argv );
  95. }
  96. else {
  97. fprintf( stderr, "SPLITSYM: Argument to /%c switch missing\n", c );
  98. Usage();
  99. }
  100. break;
  101. case 'P':
  102. SplitFlags |= SPLITSYM_REMOVE_PRIVATE;
  103. break;
  104. case 'A':
  105. SplitFlags |= SPLITSYM_EXTRACT_ALL;
  106. break;
  107. default:
  108. fprintf( stderr, "SPLITSYM: Invalid switch - /%c\n", c );
  109. Usage();
  110. break;
  111. }
  112. }
  113. else {
  114. if (fRecurse) {
  115. fprintf( stderr, "SPLITSYM: May not specify specific file names with /R switch.\n" );
  116. Usage();
  117. }
  118. else
  119. if (!GetFullPathNameA( s, sizeof( CurrentImageName ), (PCHAR) CurrentImageName, &FilePart )) {
  120. fprintf( stderr, "SPLITSYM: invalid file name - %s (%u)\n", s, GetLastError() );
  121. }
  122. else {
  123. if (SplitSymbolsX( (PCHAR) CurrentImageName, (PCHAR) SymbolPath, (PCHAR) DbgFileName,
  124. sizeof(DbgFileName), SplitFlags, RSDSDllPath, PdbName, sizeof(PdbName) )) {
  125. if (fVerbose) {
  126. fprintf( stdout,
  127. "SPLITSYM: %16s symbols split into %s\n",
  128. FilePart,
  129. DbgFileName
  130. );
  131. }
  132. }
  133. else
  134. if (GetLastError() != ERROR_BAD_EXE_FORMAT &&
  135. GetLastError() != ERROR_ALREADY_ASSIGNED
  136. ) {
  137. fprintf( stderr, "SPLITSYM: Unable to split symbols from '%s' into '%s' (%u)\n",
  138. CurrentImageName,
  139. DbgFileName,
  140. GetLastError()
  141. );
  142. }
  143. }
  144. }
  145. }
  146. if (fRecurse) {
  147. SplitSymbolsInTree( (PCHAR) RecurseDirectory );
  148. }
  149. exit( 0 );
  150. return 0;
  151. }
  152. #define MAX_DEPTH 32
  153. VOID
  154. SplitSymbolsInTree(
  155. LPSTR RootPath
  156. )
  157. {
  158. LPSTR FilePart;
  159. PUCHAR Prefix = (PUCHAR) "";
  160. CHAR PathBuffer[MAX_PATH + 1];
  161. ULONG Depth;
  162. PCHAR PathTail[ MAX_DEPTH ];
  163. PCHAR FindHandle[ MAX_DEPTH ];
  164. LPWIN32_FIND_DATA FindFileData;
  165. UCHAR FindFileBuffer[ MAX_PATH + sizeof( WIN32_FIND_DATA ) ];
  166. CHAR PdbName[MAX_PATH] = "";
  167. StringCchCopy(PathBuffer, MAX_PATH, RootPath);
  168. FindFileData = (LPWIN32_FIND_DATA)FindFileBuffer;
  169. Depth = 0;
  170. while (TRUE) {
  171. startDirectorySearch:
  172. PathTail[ Depth ] = strchr( PathBuffer, '\0' );
  173. if (PathTail[ Depth ] > PathBuffer && PathTail[ Depth ][ -1 ] != '\\') {
  174. *(PathTail[ Depth ])++ = '\\';
  175. }
  176. StringCchCopy(PathTail[Depth], MAX_PATH - (PathTail[Depth] - PathBuffer), "*.*" );
  177. FindHandle[ Depth ] = (PCHAR) FindFirstFile( PathBuffer, FindFileData );
  178. if (FindHandle[ Depth ] != INVALID_HANDLE_VALUE) {
  179. do {
  180. if (FindFileData->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
  181. if (strcmp( FindFileData->cFileName, "." ) &&
  182. strcmp( FindFileData->cFileName, ".." ) &&
  183. Depth < MAX_DEPTH
  184. ) {
  185. StringCchPrintf(PathTail[ Depth ],
  186. MAX_PATH - (PathTail[Depth] - PathBuffer),
  187. "%s\\",
  188. FindFileData->cFileName );
  189. Depth++;
  190. goto startDirectorySearch;
  191. }
  192. }
  193. else
  194. if (!(FindFileData->dwFileAttributes & FILE_ATTRIBUTE_READONLY)) {
  195. StringCchCopy(PathTail[Depth], MAX_PATH - (PathTail[Depth] - PathBuffer), FindFileData->cFileName);
  196. if (!GetFullPathNameA( PathBuffer, sizeof( CurrentImageName ), (PCHAR) CurrentImageName, &FilePart )) {
  197. fprintf( stderr, "SPLITSYM: invalid file name - %s (%u)\n", PathBuffer, GetLastError() );
  198. }
  199. else {
  200. if (SplitSymbolsX( (PCHAR) CurrentImageName, (PCHAR) SymbolPath, (PCHAR) DbgFileName,
  201. sizeof(DbgFileName), SplitFlags, RSDSDllPath, PdbName, sizeof(PdbName) )) {
  202. if (fVerbose) {
  203. fprintf( stdout,
  204. "SPLITSYM: %16s symbols split into %s\n",
  205. FilePart,
  206. DbgFileName
  207. );
  208. }
  209. }
  210. else
  211. if (GetLastError() != ERROR_BAD_EXE_FORMAT ) {
  212. fprintf( stderr, "SPLITSYM: Unable to split symbols from '%s' into '%s' (%u)\n",
  213. CurrentImageName,
  214. DbgFileName,
  215. GetLastError()
  216. );
  217. }
  218. }
  219. }
  220. restartDirectorySearch:
  221. ;
  222. }
  223. while (FindNextFile( FindHandle[ Depth ], FindFileData ));
  224. FindClose( FindHandle[ Depth ] );
  225. if (Depth == 0) {
  226. break;
  227. }
  228. Depth--;
  229. goto restartDirectorySearch;
  230. }
  231. }
  232. return;
  233. }