windows-nt/Source/XPSP1/NT/windows/appcompat/tools/grabmi/grabmi.cpp
2020-09-26 16:20:57 +08:00

429 lines
15 KiB
C++

//+--------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 2000
//
// File: GrabMI.cpp
//
// Contents: Code for generating matching information for files in a given
// directory and it's subdirectories.
//
// History: 18-Jul-00 jdoherty Created.
// 16-Dec-00 jdoherty Modified to use SDBAPI routines.
// 29-Dec-00 prashkud Modified to take space in the filepath
//
//
//
//---------------------------------------------------------------------------
#include <windows.h>
#include <TCHAR.h>
#include <stdio.h>
#include <conio.h>
#ifdef __cplusplus
extern "C" {
#include "shimdb.h"
typedef BOOL
(SDBAPI*PFNSdbGrabMatchingInfoA)(
LPCSTR szMatchingPath,
DWORD dwFilter,
LPCSTR szFile
);
typedef BOOL
(SDBAPI*PFNSdbGrabMatchingInfoW)(
LPCWSTR szMatchingPath,
DWORD dwFilter,
LPCWSTR szFile
);
}
#endif
typedef GMI_RESULT
(SDBAPI *PFNSdbGrabMatchingInfoExA)(
LPCSTR szMatchingPath, // path to begin gathering information
DWORD dwFilterAndFlags, // specifies the types of files to be added to matching
LPCSTR szFile, // full path to file where information will be stored
PFNGMIProgressCallback pfnCallback,
LPVOID lpvCallbackParameter
);
typedef GMI_RESULT
(SDBAPI *PFNSdbGrabMatchingInfoExW)(
LPCWSTR szMatchingPath, // path to begin gathering information
DWORD dwFilterAndFlags, // specifies the types of files to be added to matching
LPCWSTR szFile, // full path to file where information will be stored
PFNGMIProgressCallback pfnCallback,
LPVOID lpvCallbackParameter
);
//
// Filters needed for SdbGrabMatchingInfo
//
/*
#define GRABMI_FILTER_NORMAL 0
#define GRABMI_FILTER_PRIVACY 1
#define GRABMI_FILTER_DRIVERS 2
#define GRABMI_FILTER_VERBOSE 3
#define GRABMI_FILTER_SYSTEM 4
#define GRABMI_FILTER_THISFILEONLY 5
*/
void ProperUsage();
BOOL CALLBACK _GrabmiCallback(
LPVOID lpvCallbackParam, // application-defined parameter
LPCTSTR lpszRoot, // root directory path
LPCTSTR lpszRelative, // relative path
PATTRINFO pAttrInfo, // attributes
LPCWSTR pwszXML // resulting xml
)
{
static int State = 0;
static TCHAR szIcon[] = TEXT("||//--\\\\");
State = ++State % (ARRAYSIZE(szIcon)-1);
_tcprintf(TEXT("%c\r"), szIcon[State]);
return TRUE;
}
int __cdecl main(int argc, TCHAR* argv[])
{
TCHAR szRootDir[MAX_PATH] = {'\0'}; // original root directory for matching
TCHAR szFile[MAX_PATH] = {'\0'}; // File to store information to
TCHAR szCommandLine[MAX_PATH]={'\0'}; // command line passed to winexec
TCHAR szMessage[MAX_PATH]={'\0'}; // error message to display
DWORD dwFilter = GRABMI_FILTER_NORMAL; // specifies filter for matching
DWORD dwFilterFlags = 0;
BOOL bDestinationSelected = FALSE;
BOOL bDisplayFile = TRUE;
OSVERSIONINFO VersionInfo;
int iRetCode = 0;
BOOL bUseApphelp = FALSE;
static int Cnt = 0;
PFNSdbGrabMatchingInfoExA pfnGrabA = NULL;
PFNSdbGrabMatchingInfoExW pfnGrabW = NULL;
HMODULE hLib;
VersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
if (GetVersionEx(&VersionInfo) == FALSE) {
wsprintf (szMessage, TEXT("Unable to get version info.\n"));
goto eh;
}
// check OS version to load the correct version
// of sdbapi
// set to debug 9x binaries on WinXP
// VersionInfo.dwPlatformId = VER_PLATFORM_WIN32_WINDOWS;
switch (VersionInfo.dwPlatformId) {
case VER_PLATFORM_WIN32_NT:
if (VersionInfo.dwMajorVersion >= 5) {
if (VersionInfo.dwMajorVersion == 5) { // Check minor version for WinXP
bUseApphelp = VersionInfo.dwMinorVersion >= 1;
} else {
bUseApphelp = TRUE;
}
}
hLib = LoadLibrary(bUseApphelp ? TEXT("apphelp.dll") : TEXT("sdbapiu.dll"));
if (hLib == NULL) {
wsprintf (szMessage, TEXT("Could not load sdbapiu.dll.\n"));
goto eh;
}
pfnGrabW = (PFNSdbGrabMatchingInfoExW)GetProcAddress(hLib, TEXT("SdbGrabMatchingInfoEx"));
if (pfnGrabW == NULL) {
wsprintf (szMessage, TEXT("Unable to get proc address for SdbGrabMatchingInfo\n"));
goto eh;
}
break;
case VER_PLATFORM_WIN32_WINDOWS:
hLib = LoadLibraryA(TEXT("sdbapi.dll"));
if (hLib == NULL) {
wsprintf (szMessage, TEXT("Could not load sdbapi.dll.\n"));
goto eh;
}
pfnGrabA = (PFNSdbGrabMatchingInfoExA)GetProcAddress(hLib, TEXT("SdbGrabMatchingInfoEx"));
if (pfnGrabA == NULL) {
wsprintf (szMessage, TEXT("Unable to get proc address for SdbGrabMatchingInfo\n"));
goto eh;
}
break;
default:
wsprintf (szMessage, TEXT("Unknown platform\n"));
goto eh;
}
// Parse the command line for flags
if( argc >= 2) {
int i = 1;
while (i < argc){
LPCTSTR pch = argv[i];
TCHAR ch = *pch;
if (ch == TEXT('-') || ch == TEXT('/')) {
ch = *++pch;
++pch;
switch(_totupper(ch)) {
case TEXT('F'):
if (*pch == TEXT('\0')) {
++i;
if (i < argc && _istalnum(*argv[i])) {
pch = argv[i];
} else {
// error - missing filename
wsprintf (szMessage, TEXT("You must provide a file with a .txt extension to save to.\n") );
goto HandleUsage;
}
}
lstrcpy(szFile, pch);
bDestinationSelected=TRUE;
break;
case TEXT('?'):
case TEXT('H'): // help ?
HandleUsage:
ProperUsage();
goto eh;
case TEXT('D'):
dwFilter = GRABMI_FILTER_DRIVERS;
break;
case TEXT('O'):
dwFilter = GRABMI_FILTER_THISFILEONLY;
break;
case TEXT('V'):
dwFilter = GRABMI_FILTER_VERBOSE;
break;
case TEXT('Q'):
bDisplayFile = FALSE;
break;
case TEXT('P'):
dwFilter = GRABMI_FILTER_PRIVACY;
break;
case TEXT('S'):
dwFilter = GRABMI_FILTER_SYSTEM;
break;
case TEXT('A'):
dwFilterFlags |= GRABMI_FILTER_APPEND;
break;
case TEXT('N'):
dwFilterFlags |= GRABMI_FILTER_NOCLOSE;
break;
default:
// unrecognized arg goes here
wsprintf(szMessage, TEXT("Unrecognized argument, RTFM: %s\n"), argv[i]);
goto HandleUsage;
break;
}
} else {
// unnamed argument
if (++Cnt > 1) {
// error - more than one file specified -- we do not support it for now
//
wsprintf(szMessage, TEXT("More than one file specified %s\n"), argv[i]);
goto HandleUsage;
}
lstrcpy(szRootDir, argv[i]);
}
++i;
}
}
if (!bDestinationSelected) {
GetSystemDirectory( szFile, MAX_PATH );
LPTSTR pchBackslash;
pchBackslash = _tcschr(szFile, TEXT('\\'));
lstrcpy (pchBackslash, TEXT("\\matchinginfo.txt"));
bDestinationSelected=TRUE;
}
if ( (_tcsicmp(szRootDir ,TEXT(".")) == 0) || szRootDir[0] == '\0' ) {
// The root path wasn't specified. Get the current path or
// the path to the drivers depending on command line
if (dwFilter == GRABMI_FILTER_DRIVERS && (_tcsicmp(szRootDir ,TEXT(".")) != 0)) {
GetSystemDirectory( szRootDir, MAX_PATH );
lstrcat( szRootDir, TEXT("\\drivers") );
} else {
GetCurrentDirectory( MAX_PATH, szRootDir );
}
}
// if we are using sdbapiu.dll we need to call it with
// unicode parameters
if (VersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) {
WCHAR wszRootDir[MAX_PATH] ={'\0'};
WCHAR wszFile[MAX_PATH] ={'\0'};
int cchWideChar;
cchWideChar = MultiByteToWideChar(
CP_ACP,
0,
szRootDir,
-1,
NULL,
0 );
//
// check for error!!!
//
if ((DWORD)cchWideChar > MAX_PATH) {
wsprintf (szMessage, TEXT("Unable to convert szRootDir to wszRootDir.\n"));
goto eh;
}
MultiByteToWideChar(
CP_ACP,
0,
szRootDir,
-1,
wszRootDir,
cchWideChar );
cchWideChar = MultiByteToWideChar(
CP_ACP,
0,
szFile,
-1,
NULL,
0 );
//
// check for error!!!
//
if ((DWORD)cchWideChar > MAX_PATH) {
wsprintf (szMessage, TEXT("Unable to convert szFile to wszFile.\n"));
goto eh;
}
MultiByteToWideChar(
CP_ACP,
0,
szFile,
-1,
wszFile,
cchWideChar );
// now make call to SdbGrabMatchingInfo with Unicode parameters
if ((pfnGrabW (wszRootDir, dwFilter|dwFilterFlags, wszFile, _GrabmiCallback, NULL)) != GMI_SUCCESS) {
wsprintf (szMessage, TEXT("Unable to grab matching information from %s.\n"), szRootDir);
goto eh;
}
wsprintf (szMessage, TEXT("Matching information retrieved successfully.\n"));
}
else if (VersionInfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS){
// otherwise call SdbGrabMatchingInfo as normal
if ((pfnGrabA (szRootDir, dwFilter|dwFilterFlags, szFile, _GrabmiCallback, NULL)) != GMI_SUCCESS) {
wsprintf (szMessage, TEXT("Unable to grab matching information from %s.\n"), szRootDir);
goto eh;
}
wsprintf (szMessage, TEXT("Matching information retrieved successfully.\n"));
}
else {
wsprintf (szMessage, TEXT("Unknown OS Platform.\n"));
goto eh;
}
if (bDisplayFile) {
if (VersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) {
lstrcpy (szCommandLine, TEXT("notepad "));
}
else {
lstrcpy (szCommandLine, TEXT("write "));
}
lstrcat (szCommandLine, szFile);
WinExec (szCommandLine, SW_SHOW);
}
eh:
if (*szMessage) {
_tprintf (TEXT("%s"), szMessage);
iRetCode = 1;
}
return iRetCode;
}
/*++
Function Description:
This function simply prints out the proper usage for GrabMI.
Arguments:
Return Value:
VOID.
History:
jdoherty Created 8/2/00
--*/
void ProperUsage()
{
_tprintf (TEXT("\nGrabMI can be used in one of the following ways:\n")
TEXT(" *** The following flags can be used with other flags: \n")
TEXT(" -f, -a, -n, and -h \n")
TEXT(" otherwise the last flag specified will be the one used.\n")
TEXT(" *** By default information will be stored in %%systemdrive%%\\matchinginfo.txt\n\n")
TEXT(" grabmi [path to start generating info ie. c:\\progs]\n")
TEXT(" Grabs matching information from the path specified. Limits the\n")
TEXT(" information gathered to 10 miscellaneous files per directory,\n")
TEXT(" and includes all files with extensions .icd, .exe, .dll, \n")
TEXT(" .msi, ._mp\n\n")
TEXT(" grabmi [-d]\n")
TEXT(" Grabs matching information from %%windir%%\\system32\\drivers. \n")
TEXT(" The format of the information is slightly different in this case\n")
TEXT(" and only information for *.sys files will be grabbed.\n\n")
TEXT(" grabmi [-f drive:\\filename.txt]\n")
TEXT(" The matching information is stored in a file specified by the user.\n\n")
TEXT(" grabmi [-h or -?]\n")
TEXT(" Displays this help.\n\n")
TEXT(" grabmi [-o]\n")
TEXT(" Grabs information for the file specified. If a file was not specified \n")
TEXT(" the call will fail. If the destination file exists then the information\n")
TEXT(" will be concatenated to the end of the existing file.\n\n")
TEXT(" grabmi [-p]\n")
TEXT(" Grabs information for files with .icd, .exe, .dll, .msi, ._mp extensions. \n")
TEXT(" No more, no less.\n\n")
TEXT(" grabmi [-q]\n")
TEXT(" Grabs matching information and does not display the file when completed.\n\n")
TEXT(" grabmi [-s]\n")
TEXT(" Grabs information for the following system files: \n")
TEXT(" advapi32.dll, gdi32.dll, ntdll.dll, kernel32.dll, winsock.dll\n")
TEXT(" ole32.dll, oleaut32.dll, shell32.dll, user32.dll, and wininet.dll \n\n")
TEXT(" grabmi [-v]\n")
TEXT(" Grabs matching information for all files. \n\n")
TEXT(" grabmi [-a]\n")
TEXT(" Appends new matching information to the existing matching\n")
TEXT(" information file. \n\n")
TEXT(" grabmi [-n]\n")
TEXT(" Allows to append more information to the file later (see -a). \n\n")
TEXT("Grab Matching Information Help\n"));
return;
}