/*++ Copyright (c) 2000 Microsoft Corporation Module Name: appparsecui.cpp Abstract: Command line interface for appparse History: 06/27/2000 t-michkr Created --*/ #include #include #include #include #include #include #include #include "appparse.h" // These are needed for command line compiling #define stricmp _stricmp #define strnicmp _strnicmp #define getche _getche // Print a help screen to the console. void PrintHelp() { printf("Display application import information.\n"); printf("APPPARSE target [outputfile]"); printf("[/C] [/R] [/S] [/A] [/V] [/K:func]\n"); printf(" target Specifies the target filename or directory to be profiled.\n"); printf(" A valid directory or binary file must be specified. In the case of:\n"); printf(" DIRECTORY - All binary files in the directory will be profiled.\n"); printf(" FILENAME - The file and its dependencies will be profiled.\n"); printf("\n"); printf(" outputfile Specifies output file name. Default is [targetfile].XML.\n"); printf(" /C Ignore output file, and send output to console.\n"); printf(" /R Raw format. (No XML tags, default for non-XML output file.)\n"); printf(" /S Profile subfolders. Only valid when target is a directory.\n"); printf(" /A API logging only.\n"); printf("\n"); printf("Advanced Features\n"); printf(" /V Verbose\n"); printf(" /K:func Only return those functions matching the key func (case insensitive, wildcards)\n"); printf("\n\n"); printf("Example: appparse \"C:\\Program Files\\foo /V /K:Create*\n"); } // Get a default Output file name for a path, trim dir and extension info. char* GetOutputFileName(const char* szPath) { int iOffset = strlen(szPath); char* szTemp = 0; // If its a drive, use the volume name for output file. if(szPath[strlen(szPath)-1] == ':' || (szPath[strlen(szPath)-1] == '\\' && szPath[strlen(szPath)-2] == ':')) { char szBuffer[MAX_PATH]; if(GetVolumeInformation(szPath, szBuffer, MAX_PATH, 0, 0, 0, 0, 0)) { szTemp = new char[strlen(szBuffer)+strlen(".xml")+1]; strcpy(szTemp, szBuffer); strcat(szTemp, ".xml"); return szTemp; } } for(; iOffset >= 0; iOffset--) { if(szPath[iOffset] == '\\') { if(iOffset == static_cast(strlen(szPath))) { strcpy(szTemp, szPath); break; } szTemp = new char[strlen(szPath)-iOffset + 5]; strcpy(szTemp, &szPath[iOffset+1]); break; } } if(iOffset < 0) { szTemp = new char[strlen(szPath) + 5]; strcpy(szTemp, szPath); } for(iOffset = strlen(szTemp); iOffset >= static_cast((strlen(szTemp)-4)); iOffset--) { if(szTemp[iOffset] == '.') { szTemp[iOffset] = '\0'; break; } } strcat(szTemp, ".xml"); return szTemp; } int __cdecl main(int argc, char** argv) { char* szAppName, szOutput[MAX_PATH]; bool fRaw = false, fAPILogging = false, fVerbose = false, fRecurse = false; char* szSearch = "*"; FILE* pFile = 0; if(argc < 2) { PrintHelp(); return 0; } if(strnicmp(argv[1], "/?", strlen("/?"))==0) { PrintHelp(); return 0; } // Get command line options szAppName = argv[1]; int i = 2; // Check for output file if(argc > 2 && *argv[i] != '/') { // Output file specified. strcpy(szOutput,argv[i]); if(!strchr(szOutput, '.')) strcat(szOutput, ".xml"); else { // Switch to raw output if non XML extension specified. if(szOutput[strlen(szOutput)-4] != '.' || szOutput[strlen(szOutput)-3] != 'x' || szOutput[strlen(szOutput)-2] != 'm' || szOutput[strlen(szOutput)-1] != 'l') { fRaw = true; } } i++; } else { // No output specified, just use appname strcpy(szOutput,GetOutputFileName(szAppName)); } // Loop through all command line options. for(; i < argc; i++) { // Output to console if(strnicmp(argv[i], "/C", 2)==0) { pFile = stdout; } // Raw mode, no XML tags. else if(strnicmp(argv[i], "/R", 2)==0) { fRaw = true; } // Recurse into subdirectories for directory profiling else if(strnicmp(argv[i], "/S", 2)==0) { fRecurse = true; } // Do not print import module info, just functions. else if(strnicmp(argv[i], "/A", 2)==0) { fAPILogging = true; } // Verbose mode, print out extended information else if(strnicmp(argv[i], "/V", 2)==0) { fVerbose = true; } // Use a search key else if(strnicmp(argv[i], "/K:", 3)==0) { if(strlen(argv[i]) == 3) { if(i == (argc - 1)) { printf("Missing search string\n"); return 0; } else { szSearch = argv[i+1]; i++; } } else { szSearch = &((argv[i])[3]); } } // Print help else if(strnicmp(argv[i], "/?", 2)==0) { PrintHelp(); return 0; } else { printf("Unrecognized option, %s\n", argv[i]); return 0; } } // If pFile wasn't already set to stdout if(!pFile) { // Check if it already exists if(GetFileAttributes(szOutput) != -1) { printf("Output file already exists, overwrite? "); if(getche() != 'y') return 0; } // Try to open file pFile = fopen(szOutput, "wt+"); if(!pFile) { printf("\nUnable to open output file %s\n", szOutput); // Try in My Documents folder char szBuffer[MAX_PATH+1]; HRESULT hr = SHGetFolderPath(0, CSIDL_PERSONAL,0, 0, szBuffer); if(SUCCEEDED(hr)) { if((strlen(szBuffer) + strlen(szOutput) + 1) < MAX_PATH) { strcat(szBuffer, "\\"); strcat(szBuffer, szOutput); if(GetFileAttributes(szBuffer) != -1) { printf("%s already exists, overwrite? ", szBuffer); if(getche() != 'y') return 0; } pFile = fopen(szBuffer, "wt+"); if(!pFile) { printf("\nUnable to open output file %s\n", szBuffer); hr = E_FAIL; } else strcpy(szOutput, szBuffer); } else hr = E_FAIL; } if(FAILED(hr)) { // Try in "temp" directory char szBuffer[MAX_PATH + 1]; if(GetTempPath(MAX_PATH, szBuffer)) { if((strlen(szBuffer) + strlen(szOutput) + 1) < MAX_PATH) { strcat(szBuffer, szOutput); if(GetFileAttributes(szBuffer) != -1) { printf("%s already exists, overwrite? ", szBuffer); if(getche() != 'y') return 0; } pFile = fopen(szBuffer, "wt+"); if(!pFile) { printf("\nUnable to open output file\n"); return 0; } else strcpy(szOutput, szBuffer); } else { printf("\nUnable to open output file\n"); return 0; } } else { printf("\nUnable to open output file\n"); return 0; } } } } printf("\nProfiling . . .\n"); DWORD dwError = AppParse(szAppName, pFile, fRaw, fAPILogging, fRecurse, fVerbose, szSearch, 0); switch(dwError) { case ERROR_SUCCESS: if(pFile != stdout) printf("Output successfully written to %s.\n", szOutput); break; case ERROR_FILE_NOT_FOUND: printf("The system was not able to find the file specified.\n"); break; default: printf("Unknown error\n"); break; } if(pFile && pFile != stdout) fclose(pFile); return 0; }