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.

341 lines
9.7 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. appparsecui.cpp
  5. Abstract:
  6. Command line interface for appparse
  7. History:
  8. 06/27/2000 t-michkr Created
  9. --*/
  10. #include <windows.h>
  11. #include <shellapi.h>
  12. #include <shlwapi.h>
  13. #include <shfolder.h>
  14. #include <conio.h>
  15. #include <stdio.h>
  16. #include <string.h>
  17. #include "appparse.h"
  18. // These are needed for command line compiling
  19. #define stricmp _stricmp
  20. #define strnicmp _strnicmp
  21. #define getche _getche
  22. // Print a help screen to the console.
  23. void PrintHelp()
  24. {
  25. printf("Display application import information.\n");
  26. printf("APPPARSE target [outputfile]");
  27. printf("[/C] [/R] [/S] [/A] [/V] [/K:func]\n");
  28. printf(" target Specifies the target filename or directory to be profiled.\n");
  29. printf(" A valid directory or binary file must be specified. In the case of:\n");
  30. printf(" DIRECTORY - All binary files in the directory will be profiled.\n");
  31. printf(" FILENAME - The file and its dependencies will be profiled.\n");
  32. printf("\n");
  33. printf(" outputfile Specifies output file name. Default is [targetfile].XML.\n");
  34. printf(" /C Ignore output file, and send output to console.\n");
  35. printf(" /R Raw format. (No XML tags, default for non-XML output file.)\n");
  36. printf(" /S Profile subfolders. Only valid when target is a directory.\n");
  37. printf(" /A API logging only.\n");
  38. printf("\n");
  39. printf("Advanced Features\n");
  40. printf(" /V Verbose\n");
  41. printf(" /K:func Only return those functions matching the key func (case insensitive, wildcards)\n");
  42. printf("\n\n");
  43. printf("Example: appparse \"C:\\Program Files\\foo /V /K:Create*\n");
  44. }
  45. // Get a default Output file name for a path, trim dir and extension info.
  46. char* GetOutputFileName(const char* szPath)
  47. {
  48. int iOffset = strlen(szPath);
  49. char* szTemp = 0;
  50. // If its a drive, use the volume name for output file.
  51. if(szPath[strlen(szPath)-1] == ':' ||
  52. (szPath[strlen(szPath)-1] == '\\' &&
  53. szPath[strlen(szPath)-2] == ':'))
  54. {
  55. char szBuffer[MAX_PATH];
  56. if(GetVolumeInformation(szPath, szBuffer, MAX_PATH, 0, 0, 0, 0, 0))
  57. {
  58. szTemp = new char[strlen(szBuffer)+strlen(".xml")+1];
  59. strcpy(szTemp, szBuffer);
  60. strcat(szTemp, ".xml");
  61. return szTemp;
  62. }
  63. }
  64. for(; iOffset >= 0; iOffset--)
  65. {
  66. if(szPath[iOffset] == '\\')
  67. {
  68. if(iOffset == static_cast<int>(strlen(szPath)))
  69. {
  70. strcpy(szTemp, szPath);
  71. break;
  72. }
  73. szTemp = new char[strlen(szPath)-iOffset + 5];
  74. strcpy(szTemp, &szPath[iOffset+1]);
  75. break;
  76. }
  77. }
  78. if(iOffset < 0)
  79. {
  80. szTemp = new char[strlen(szPath) + 5];
  81. strcpy(szTemp, szPath);
  82. }
  83. for(iOffset = strlen(szTemp); iOffset >= static_cast<int>((strlen(szTemp)-4)); iOffset--)
  84. {
  85. if(szTemp[iOffset] == '.')
  86. {
  87. szTemp[iOffset] = '\0';
  88. break;
  89. }
  90. }
  91. strcat(szTemp, ".xml");
  92. return szTemp;
  93. }
  94. int __cdecl main(int argc, char** argv)
  95. {
  96. char* szAppName, szOutput[MAX_PATH];
  97. bool fRaw = false, fAPILogging = false, fVerbose = false,
  98. fRecurse = false;
  99. char* szSearch = "*";
  100. FILE* pFile = 0;
  101. if(argc < 2)
  102. {
  103. PrintHelp();
  104. return 0;
  105. }
  106. if(strnicmp(argv[1], "/?", strlen("/?"))==0)
  107. {
  108. PrintHelp();
  109. return 0;
  110. }
  111. // Get command line options
  112. szAppName = argv[1];
  113. int i = 2;
  114. // Check for output file
  115. if(argc > 2 && *argv[i] != '/')
  116. {
  117. // Output file specified.
  118. strcpy(szOutput,argv[i]);
  119. if(!strchr(szOutput, '.'))
  120. strcat(szOutput, ".xml");
  121. else
  122. {
  123. // Switch to raw output if non XML extension specified.
  124. if(szOutput[strlen(szOutput)-4] != '.'
  125. || szOutput[strlen(szOutput)-3] != 'x'
  126. || szOutput[strlen(szOutput)-2] != 'm'
  127. || szOutput[strlen(szOutput)-1] != 'l')
  128. {
  129. fRaw = true;
  130. }
  131. }
  132. i++;
  133. }
  134. else
  135. {
  136. // No output specified, just use appname
  137. strcpy(szOutput,GetOutputFileName(szAppName));
  138. }
  139. // Loop through all command line options.
  140. for(; i < argc; i++)
  141. {
  142. // Output to console
  143. if(strnicmp(argv[i], "/C", 2)==0)
  144. {
  145. pFile = stdout;
  146. }
  147. // Raw mode, no XML tags.
  148. else if(strnicmp(argv[i], "/R", 2)==0)
  149. {
  150. fRaw = true;
  151. }
  152. // Recurse into subdirectories for directory profiling
  153. else if(strnicmp(argv[i], "/S", 2)==0)
  154. {
  155. fRecurse = true;
  156. }
  157. // Do not print import module info, just functions.
  158. else if(strnicmp(argv[i], "/A", 2)==0)
  159. {
  160. fAPILogging = true;
  161. }
  162. // Verbose mode, print out extended information
  163. else if(strnicmp(argv[i], "/V", 2)==0)
  164. {
  165. fVerbose = true;
  166. }
  167. // Use a search key
  168. else if(strnicmp(argv[i], "/K:", 3)==0)
  169. {
  170. if(strlen(argv[i]) == 3)
  171. {
  172. if(i == (argc - 1))
  173. {
  174. printf("Missing search string\n");
  175. return 0;
  176. }
  177. else
  178. {
  179. szSearch = argv[i+1];
  180. i++;
  181. }
  182. }
  183. else
  184. {
  185. szSearch = &((argv[i])[3]);
  186. }
  187. }
  188. // Print help
  189. else if(strnicmp(argv[i], "/?", 2)==0)
  190. {
  191. PrintHelp();
  192. return 0;
  193. }
  194. else
  195. {
  196. printf("Unrecognized option, %s\n", argv[i]);
  197. return 0;
  198. }
  199. }
  200. // If pFile wasn't already set to stdout
  201. if(!pFile)
  202. {
  203. // Check if it already exists
  204. if(GetFileAttributes(szOutput) != -1)
  205. {
  206. printf("Output file already exists, overwrite? ");
  207. if(getche() != 'y')
  208. return 0;
  209. }
  210. // Try to open file
  211. pFile = fopen(szOutput, "wt+");
  212. if(!pFile)
  213. {
  214. printf("\nUnable to open output file %s\n", szOutput);
  215. // Try in My Documents folder
  216. char szBuffer[MAX_PATH+1];
  217. HRESULT hr = SHGetFolderPath(0, CSIDL_PERSONAL,0,
  218. 0, szBuffer);
  219. if(SUCCEEDED(hr))
  220. {
  221. if((strlen(szBuffer) + strlen(szOutput) + 1) < MAX_PATH)
  222. {
  223. strcat(szBuffer, "\\");
  224. strcat(szBuffer, szOutput);
  225. if(GetFileAttributes(szBuffer) != -1)
  226. {
  227. printf("%s already exists, overwrite? ", szBuffer);
  228. if(getche() != 'y')
  229. return 0;
  230. }
  231. pFile = fopen(szBuffer, "wt+");
  232. if(!pFile)
  233. {
  234. printf("\nUnable to open output file %s\n", szBuffer);
  235. hr = E_FAIL;
  236. }
  237. else
  238. strcpy(szOutput, szBuffer);
  239. }
  240. else
  241. hr = E_FAIL;
  242. }
  243. if(FAILED(hr))
  244. {
  245. // Try in "temp" directory
  246. char szBuffer[MAX_PATH + 1];
  247. if(GetTempPath(MAX_PATH, szBuffer))
  248. {
  249. if((strlen(szBuffer) + strlen(szOutput) + 1) < MAX_PATH)
  250. {
  251. strcat(szBuffer, szOutput);
  252. if(GetFileAttributes(szBuffer) != -1)
  253. {
  254. printf("%s already exists, overwrite? ", szBuffer);
  255. if(getche() != 'y')
  256. return 0;
  257. }
  258. pFile = fopen(szBuffer, "wt+");
  259. if(!pFile)
  260. {
  261. printf("\nUnable to open output file\n");
  262. return 0;
  263. }
  264. else
  265. strcpy(szOutput, szBuffer);
  266. }
  267. else
  268. {
  269. printf("\nUnable to open output file\n");
  270. return 0;
  271. }
  272. }
  273. else
  274. {
  275. printf("\nUnable to open output file\n");
  276. return 0;
  277. }
  278. }
  279. }
  280. }
  281. printf("\nProfiling . . .\n");
  282. DWORD dwError = AppParse(szAppName, pFile, fRaw, fAPILogging, fRecurse, fVerbose,
  283. szSearch, 0);
  284. switch(dwError)
  285. {
  286. case ERROR_SUCCESS:
  287. if(pFile != stdout)
  288. printf("Output successfully written to %s.\n", szOutput);
  289. break;
  290. case ERROR_FILE_NOT_FOUND:
  291. printf("The system was not able to find the file specified.\n");
  292. break;
  293. default:
  294. printf("Unknown error\n");
  295. break;
  296. }
  297. if(pFile && pFile != stdout)
  298. fclose(pFile);
  299. return 0;
  300. }