645 lines
20 KiB
C++
645 lines
20 KiB
C++
|
////////////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// File: shimdbc.cpp
|
||
|
//
|
||
|
// History: 19-Nov-99 markder Created.
|
||
|
// 1-Feb-00 markder Revised to read/write to ShimDB.
|
||
|
// 1-Apr-00 vadimb Revised to work with apphelp entries
|
||
|
// 13-Dec-00 markder Version 2
|
||
|
// 13-Dec-00 vadimb Version 2.00.10 MSI support
|
||
|
// 03-Dec-01 vadimb Version 2.01.13 Fix Memory patch write routine
|
||
|
// 15-Feb-01 markder/vadimb 2.01.14 Fix Install section format for migdb
|
||
|
// 07-Feb-01 vadimb Version 2.01.15 MSI support (nested DATA)
|
||
|
// 21-Feb-01 vadimb Version 2.01.16 16-bit module name attribute,
|
||
|
// fix 16-bit description
|
||
|
// 06-Mar-01 markder Version 2.02.11 MSI filter support
|
||
|
// 12-Mar-01 vadimb Version 2.03.00 Migration support, part deux
|
||
|
// 28-Mar-01 markder Version 2.04.00 Driver DB support, NtCompat support
|
||
|
// 29-Mar-01 vadimb Version 2.04.11 Driver DB indexing
|
||
|
// 11-Apr-01 dmunsil Version 2.04.12 Driver DB support, NtCompat support
|
||
|
// 12-Apr-01 vadimb Version 2.04.13 MSI shimming support
|
||
|
// 18-Apr-01 vadimb Version 2.04.15 MSI dynamic shim bugfix
|
||
|
// 15-Jan-02 jdoherty Version 2.04.59 Add ID to additional tags.
|
||
|
// 19-Mar-02 kinshu Version 2.04.63 Bug# 529272
|
||
|
// 22-Mar-02 markder Version 2.05.00 Multi-language database support
|
||
|
// 22-Apr-02 rparsons Version 2.05.01 Fix regression in patch write routine
|
||
|
// 08-Apr-02 maonis Version 2.05.02 Adding 2 new OS_SKU tags to recognize
|
||
|
// TabletPC and eHome
|
||
|
// 22-May-02 vadimb Version 2.05.03 Add OS_SKU to msi package entries
|
||
|
|
||
|
//
|
||
|
// Desc: This file contains the entry point and main functions
|
||
|
// of the Shim database compiler.
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
#include "stdafx.h"
|
||
|
#include "resource.h"
|
||
|
#include "typeinfo.h"
|
||
|
#include "registry.h"
|
||
|
#include "ntcompat.h"
|
||
|
#include "chm.h"
|
||
|
#include "mig.h"
|
||
|
#include "make.h"
|
||
|
#include "stats.h"
|
||
|
|
||
|
#ifdef _DEBUG
|
||
|
#define new DEBUG_NEW
|
||
|
#undef THIS_FILE
|
||
|
static char THIS_FILE[] = __FILE__;
|
||
|
#endif
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////////
|
||
|
// Global variables
|
||
|
////////////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
#ifdef USE_CWIN
|
||
|
CWinApp theApp; // Needed for MFC
|
||
|
#endif // USE_CWIN
|
||
|
|
||
|
BOOL g_bQuiet = FALSE; // Quiet mode
|
||
|
TCHAR g_szVersion[] = _T("v2.05.04a"); // Version string
|
||
|
BOOL g_bStrict = FALSE; // Strict checking
|
||
|
CStringArray g_rgErrors; // Error message stack
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////////
|
||
|
// Forward declarations of functions
|
||
|
////////////////////////////////////////////////////////////////////////////////////
|
||
|
void PrintHelp();
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// Func: main
|
||
|
//
|
||
|
// Desc: Entry point.
|
||
|
//
|
||
|
extern "C" int __cdecl _tmain(int argc, TCHAR* argv[])
|
||
|
{
|
||
|
int nRetCode = 1;
|
||
|
int i;
|
||
|
DOUBLE flOSVersion = 0.0;
|
||
|
|
||
|
SdbDatabase* pDatabase = new SdbDatabase();
|
||
|
CString csOutputFile;
|
||
|
CString csOutputDir;
|
||
|
CString csInputDir;
|
||
|
CString csTemp;
|
||
|
CString csMigDBFile;
|
||
|
CString csMakefile;
|
||
|
SdbMakefile Makefile;
|
||
|
SdbInputFile* pInputFile = NULL;
|
||
|
SdbInputFile* pRefFile = NULL;
|
||
|
SdbOutputFile* pOutputFile = NULL;
|
||
|
SdbOutputFile* pOtherFile = NULL;
|
||
|
|
||
|
BOOL bCreateHTMLHelpFiles = FALSE;
|
||
|
BOOL bCreateRegistryFiles = FALSE;
|
||
|
BOOL bAddExeStubs = FALSE;
|
||
|
BOOL bCreateMigDBFiles = FALSE;
|
||
|
BOOL bUseNameInAppHelpURL = FALSE;
|
||
|
LONG nPrintStatistics = 0;
|
||
|
|
||
|
//
|
||
|
// Initialize MFC and print and error on failure
|
||
|
//
|
||
|
|
||
|
if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0)) {
|
||
|
PrintError(_T("Fatal Error: MFC initialization failed\n"));
|
||
|
goto eh;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Print banner
|
||
|
//
|
||
|
if (!g_bQuiet) {
|
||
|
Print(_T("\nMicrosoft Application Compatibility Database Compiler %s\n"), g_szVersion);
|
||
|
Print(_T("Copyright (C) Microsoft Corp 2000-2002. All rights reserved.\n\n"));
|
||
|
}
|
||
|
|
||
|
if (argc < 2) {
|
||
|
PrintHelp();
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Initialize COM
|
||
|
//
|
||
|
if (FAILED(CoInitialize(NULL))) {
|
||
|
PrintError(_T("Could not initialize COM to get the MSXML object.\n"));
|
||
|
goto eh;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Create default files (populated by command switches)
|
||
|
//
|
||
|
pInputFile = new SdbInputFile();
|
||
|
pRefFile = new SdbInputFile();
|
||
|
pOutputFile = new SdbOutputFile();
|
||
|
|
||
|
//
|
||
|
// Determine compile mode
|
||
|
//
|
||
|
pOutputFile->m_dwFilter = GetFilter(argv[1]);
|
||
|
|
||
|
//
|
||
|
// Parse command line
|
||
|
//
|
||
|
for (i = 2; i < argc; i++) {
|
||
|
if (argv[i][0] == _T('-') || argv[i][0] == _T('/')) {
|
||
|
switch (argv[i][1]) {
|
||
|
case '?':
|
||
|
PrintHelp();
|
||
|
return 0;
|
||
|
|
||
|
case 'a':
|
||
|
case 'A':
|
||
|
if (argv[i][2] == _T('n') ||
|
||
|
argv[i][2] == _T('N')) {
|
||
|
bUseNameInAppHelpURL = TRUE;
|
||
|
}
|
||
|
|
||
|
if (i < argc - 1) {
|
||
|
pRefFile->m_csName = MakeFullPath(argv[++i]);
|
||
|
Makefile.m_rgInputFiles.Add(pRefFile);
|
||
|
} else {
|
||
|
PrintError(_T("Error -- not enough parameters.\n"));
|
||
|
goto eh;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case 'f':
|
||
|
case 'F':
|
||
|
if (i < argc - 1) {
|
||
|
csTemp = argv[++i];
|
||
|
} else {
|
||
|
PrintError(_T("Error -- not enough parameters.\n"));
|
||
|
goto eh;
|
||
|
}
|
||
|
|
||
|
if (csTemp.Right(1) != _T("\\")) {
|
||
|
csTemp += _T("\\");
|
||
|
}
|
||
|
|
||
|
pOutputFile->m_mapParameters.SetAt(
|
||
|
_T("INCLUDE FILES"), csTemp );
|
||
|
|
||
|
break;
|
||
|
|
||
|
case 'h':
|
||
|
case 'H':
|
||
|
bCreateHTMLHelpFiles = TRUE;
|
||
|
break;
|
||
|
|
||
|
case 'l':
|
||
|
case 'L':
|
||
|
Makefile.m_csLangID = argv[++i];
|
||
|
Makefile.m_csLangID.MakeUpper();
|
||
|
break;
|
||
|
|
||
|
case 'm':
|
||
|
case 'M':
|
||
|
bCreateMigDBFiles = TRUE;
|
||
|
break;
|
||
|
|
||
|
case 'o':
|
||
|
case 'O':
|
||
|
if (argv[i][2] == _T('v') ||
|
||
|
argv[i][2] == _T('V')) {
|
||
|
Makefile.m_flOSVersion = _tcstod(argv[++i], NULL);
|
||
|
}
|
||
|
if (argv[i][2] == _T('p') ||
|
||
|
argv[i][2] == _T('P')) {
|
||
|
Makefile.m_dwOSPlatform = GetOSPlatform(argv[++i]);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case 'q':
|
||
|
case 'Q':
|
||
|
g_bQuiet = TRUE;
|
||
|
break;
|
||
|
|
||
|
case 'r':
|
||
|
case 'R':
|
||
|
bCreateRegistryFiles = TRUE;
|
||
|
if (argv[i][2] == _T('s') ||
|
||
|
argv[i][2] == _T('S')) {
|
||
|
bAddExeStubs = TRUE;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case 'k':
|
||
|
case 'K':
|
||
|
if (i < argc - 1) {
|
||
|
Makefile.AddHistoryKeywords(argv[++i]);
|
||
|
} else {
|
||
|
PrintError(_T("Error -- not enough parameters.\n"));
|
||
|
goto eh;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case 's':
|
||
|
case 'S':
|
||
|
g_bStrict = TRUE;
|
||
|
break;
|
||
|
|
||
|
case 'v':
|
||
|
case 'V':
|
||
|
nPrintStatistics = 1;
|
||
|
if (argv[i][2] == _T('s') ||
|
||
|
argv[i][2] == _T('S')) {
|
||
|
nPrintStatistics = 2;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case 'x':
|
||
|
case 'X':
|
||
|
if (i < argc - 1) {
|
||
|
csMakefile = MakeFullPath(argv[++i]);
|
||
|
if (!Makefile.ReadMakefile(csMakefile)) {
|
||
|
PrintErrorStack();
|
||
|
goto eh;
|
||
|
}
|
||
|
} else {
|
||
|
PrintError(_T("Error -- not enough parameters.\n"));
|
||
|
goto eh;
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
} else {
|
||
|
//
|
||
|
// The last entry is the output file.
|
||
|
//
|
||
|
if (pInputFile->m_csName.IsEmpty()) {
|
||
|
pInputFile->m_csName = MakeFullPath(argv[i]);
|
||
|
} else if (pOutputFile->m_csName.IsEmpty()) {
|
||
|
pOutputFile->m_csName = MakeFullPath(argv[i]);
|
||
|
} else {
|
||
|
PrintError(_T("Too many parameters.\n"));
|
||
|
goto eh;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Add default lang map entry
|
||
|
//
|
||
|
SdbLangMap* pNewMap = new SdbLangMap();
|
||
|
pNewMap->m_csName = _T("---");
|
||
|
pNewMap->m_dwCodePage = 1252;
|
||
|
pNewMap->m_lcid = 0x409;
|
||
|
|
||
|
Makefile.m_rgLangMaps.Add(pNewMap);
|
||
|
|
||
|
//
|
||
|
// Determine input/output directory
|
||
|
//
|
||
|
for (i = pInputFile->m_csName.GetLength() - 1; i >= 0; i--) {
|
||
|
if (pInputFile->m_csName.GetAt(i) == _T('\\')) {
|
||
|
csInputDir = pInputFile->m_csName.Left(i + 1);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
for (i = pOutputFile->m_csName.GetLength() - 1; i >= 0; i--) {
|
||
|
if (pOutputFile->m_csName.GetAt(i) == _T('\\')) {
|
||
|
csOutputDir = pOutputFile->m_csName.Left(i + 1);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Strip .SDB from output file to allow easy extension concatenation
|
||
|
//
|
||
|
csTemp = pOutputFile->m_csName.Right(4);
|
||
|
if (0 == csTemp.CompareNoCase(_T(".sdb"))) {
|
||
|
csOutputFile = pOutputFile->m_csName.Left(
|
||
|
pOutputFile->m_csName.GetLength() - 4);
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Add additional output files if necessary
|
||
|
//
|
||
|
if (bCreateHTMLHelpFiles) {
|
||
|
pOtherFile = new SdbOutputFile();
|
||
|
Makefile.m_rgOutputFiles.Add(pOtherFile);
|
||
|
|
||
|
pOtherFile->m_OutputType = SDB_OUTPUT_TYPE_HTMLHELP;
|
||
|
pOtherFile->m_csName = csOutputDir + _T("apps.chm");
|
||
|
|
||
|
if (bUseNameInAppHelpURL) {
|
||
|
pOtherFile->m_mapParameters.SetAt(_T("USE NAME IN APPHELP URL"), _T("TRUE"));
|
||
|
}
|
||
|
|
||
|
pOtherFile->m_mapParameters.SetAt(_T("HTMLHELP TEMPLATE"), _T("WindowsXP"));
|
||
|
}
|
||
|
|
||
|
if (bCreateMigDBFiles) {
|
||
|
|
||
|
//
|
||
|
// INX file
|
||
|
//
|
||
|
if (pOutputFile->m_dwFilter == SDB_FILTER_FIX) {
|
||
|
pOtherFile = new SdbOutputFile();
|
||
|
Makefile.m_rgOutputFiles.Add(pOtherFile);
|
||
|
|
||
|
pOtherFile->m_OutputType = SDB_OUTPUT_TYPE_MIGDB_INX;
|
||
|
pOtherFile->m_csName = csOutputDir + _T("MigApp.inx");
|
||
|
}
|
||
|
|
||
|
if (pOutputFile->m_dwFilter == SDB_FILTER_APPHELP) {
|
||
|
//
|
||
|
// TXT file
|
||
|
//
|
||
|
pOtherFile = new SdbOutputFile();
|
||
|
Makefile.m_rgOutputFiles.Add(pOtherFile);
|
||
|
|
||
|
pOtherFile->m_OutputType = SDB_OUTPUT_TYPE_MIGDB_TXT;
|
||
|
pOtherFile->m_csName = csOutputDir + _T("MigApp.txt");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (bCreateRegistryFiles) {
|
||
|
|
||
|
pOtherFile = new SdbOutputFile();
|
||
|
Makefile.m_rgOutputFiles.Add(pOtherFile);
|
||
|
|
||
|
pOtherFile->m_OutputType = SDB_OUTPUT_TYPE_WIN2K_REGISTRY;
|
||
|
pOtherFile->m_csName = csOutputFile;
|
||
|
|
||
|
if (bAddExeStubs) {
|
||
|
pOtherFile->m_mapParameters.SetAt(_T("ADD EXE STUBS"), _T("TRUE"));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// If default input/output files weren't used, delete them
|
||
|
//
|
||
|
if (pInputFile->m_csName.IsEmpty()) {
|
||
|
delete pInputFile;
|
||
|
} else {
|
||
|
Makefile.m_rgInputFiles.Add(pInputFile);
|
||
|
}
|
||
|
|
||
|
if (pOutputFile->m_csName.IsEmpty()) {
|
||
|
delete pOutputFile;
|
||
|
} else {
|
||
|
Makefile.m_rgOutputFiles.Add(pOutputFile);
|
||
|
}
|
||
|
|
||
|
pInputFile = NULL;
|
||
|
pOutputFile = NULL;
|
||
|
|
||
|
//
|
||
|
// Check for at least one input and one output file
|
||
|
//
|
||
|
if (Makefile.m_rgInputFiles.GetSize() == 0) {
|
||
|
PrintError(_T("No input file(s) specified.\n"));
|
||
|
goto eh;
|
||
|
}
|
||
|
|
||
|
if (Makefile.m_rgOutputFiles.GetSize() == 0) {
|
||
|
PrintError(_T("No output file(s) specified.\n"));
|
||
|
goto eh;
|
||
|
}
|
||
|
|
||
|
pDatabase->m_pCurrentMakefile = &Makefile;
|
||
|
|
||
|
//
|
||
|
// Ensure that there is a valid LangMap specified
|
||
|
//
|
||
|
if (Makefile.GetLangMap(Makefile.m_csLangID) == NULL) {
|
||
|
PrintError(_T("No LANG_MAP available for \"%s\".\n"), Makefile.m_csLangID);
|
||
|
goto eh;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Read input file(s)
|
||
|
//
|
||
|
for (i = 0; i < Makefile.m_rgInputFiles.GetSize(); i++) {
|
||
|
|
||
|
pInputFile = (SdbInputFile *) Makefile.m_rgInputFiles[i];
|
||
|
|
||
|
Print(_T(" Reading XML file - %s"), pInputFile->m_csName);
|
||
|
|
||
|
pDatabase->m_pCurrentInputFile = pInputFile;
|
||
|
|
||
|
if (!ReadDatabase(pInputFile, pDatabase)) {
|
||
|
PrintErrorStack();
|
||
|
goto eh;
|
||
|
}
|
||
|
|
||
|
Print(_T("%s\n"), pInputFile->m_bSourceUpdated ? _T(" - updated") : _T("") );
|
||
|
|
||
|
pDatabase->m_pCurrentInputFile = NULL;
|
||
|
}
|
||
|
|
||
|
Print(_T("\n"));
|
||
|
|
||
|
//
|
||
|
// Propagate filters
|
||
|
//
|
||
|
pDatabase->PropagateFilter(SDB_FILTER_DEFAULT);
|
||
|
|
||
|
//
|
||
|
// Write output file(s)
|
||
|
//
|
||
|
for (i = 0; i < Makefile.m_rgOutputFiles.GetSize(); i++) {
|
||
|
|
||
|
pOutputFile = (SdbOutputFile *) Makefile.m_rgOutputFiles[i];
|
||
|
|
||
|
Print(_T("%27s - %s\n"),
|
||
|
pOutputFile->GetFriendlyNameForType(),
|
||
|
pOutputFile->m_csName);
|
||
|
|
||
|
pDatabase->m_pCurrentOutputFile = pOutputFile;
|
||
|
g_dwCurrentWriteFilter = pOutputFile->m_dwFilter;
|
||
|
g_dtCurrentWriteRevisionCutoff = pOutputFile->m_dtRevisionCutoff;
|
||
|
|
||
|
switch (pOutputFile->m_OutputType) {
|
||
|
|
||
|
case SDB_OUTPUT_TYPE_SDB:
|
||
|
|
||
|
if (!WriteDatabase(pOutputFile, pDatabase)) {
|
||
|
PrintErrorStack();
|
||
|
goto eh;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case SDB_OUTPUT_TYPE_HTMLHELP:
|
||
|
|
||
|
if (!ChmWriteProject(pOutputFile,
|
||
|
pDatabase)) {
|
||
|
PrintErrorStack();
|
||
|
goto eh;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case SDB_OUTPUT_TYPE_MIGDB_TXT:
|
||
|
|
||
|
if (!WriteMigDBFile(NULL,
|
||
|
pDatabase,
|
||
|
pDatabase,
|
||
|
pOutputFile->m_csName)) {
|
||
|
PrintErrorStack();
|
||
|
goto eh;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case SDB_OUTPUT_TYPE_MIGDB_INX:
|
||
|
|
||
|
if (!WriteMigDBFile(pDatabase,
|
||
|
pDatabase,
|
||
|
NULL,
|
||
|
pOutputFile->m_csName)) {
|
||
|
PrintErrorStack();
|
||
|
goto eh;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case SDB_OUTPUT_TYPE_WIN2K_REGISTRY:
|
||
|
|
||
|
csTemp.Empty();
|
||
|
pOutputFile->m_mapParameters.Lookup(_T("ADD EXE STUBS"), csTemp);
|
||
|
if (!WriteRegistryFiles(pDatabase,
|
||
|
pOutputFile->m_csName + _T(".reg"),
|
||
|
pOutputFile->m_csName + _T(".inx"),
|
||
|
csTemp == _T("TRUE"))) {
|
||
|
PrintErrorStack();
|
||
|
goto eh;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case SDB_OUTPUT_TYPE_REDIR_MAP:
|
||
|
|
||
|
csTemp.Empty();
|
||
|
pOutputFile->m_mapParameters.Lookup(_T("TEMPLATE"), csTemp);
|
||
|
|
||
|
if (csTemp.IsEmpty()) {
|
||
|
PrintError (_T("REDIR_MAP output type requires TEMPLATE parameter\n"));
|
||
|
goto eh;
|
||
|
}
|
||
|
|
||
|
if (!WriteRedirMapFile(pOutputFile->m_csName, csTemp, pDatabase)) {
|
||
|
PrintErrorStack();
|
||
|
goto eh;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case SDB_OUTPUT_TYPE_NTCOMPAT_INF:
|
||
|
|
||
|
if (!NtCompatWriteInfAdditions(pOutputFile, pDatabase)) {
|
||
|
PrintErrorStack();
|
||
|
goto eh;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case SDB_OUTPUT_TYPE_NTCOMPAT_MESSAGE_INF:
|
||
|
|
||
|
if (!NtCompatWriteMessageInf(pOutputFile, pDatabase)) {
|
||
|
PrintErrorStack();
|
||
|
goto eh;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case SDB_OUTPUT_TYPE_APPHELP_REPORT:
|
||
|
|
||
|
if (!WriteAppHelpReport(pOutputFile, pDatabase)) {
|
||
|
PrintErrorStack();
|
||
|
goto eh;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
}
|
||
|
|
||
|
pDatabase->m_pCurrentOutputFile = NULL;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Indicate success and print statistics
|
||
|
//
|
||
|
|
||
|
nRetCode = 0;
|
||
|
Print(_T("\nCompilation successful.\n\n"));
|
||
|
|
||
|
|
||
|
Print(_T(" Executables: %d\n"), pDatabase->m_rgExes.GetSize() +
|
||
|
pDatabase->m_rgWildcardExes.GetSize());
|
||
|
Print(_T(" Shims: %d\n"), pDatabase->m_Library.m_rgShims.GetSize());
|
||
|
Print(_T(" Patches: %d\n"), pDatabase->m_Library.m_rgPatches.GetSize());
|
||
|
Print(_T(" Files: %d\n"), pDatabase->m_Library.m_rgFiles.GetSize());
|
||
|
Print(_T(" Layers: %d\n\n"), pDatabase->m_Library.m_rgLayers.GetSize());
|
||
|
|
||
|
Print(_T(" AppHelp Instances: %d\n"), pDatabase->m_rgAppHelps.GetSize());
|
||
|
Print(_T(" Localized Vendors: %d\n"), pDatabase->m_rgContactInfo.GetSize());
|
||
|
Print(_T(" Templates: %d\n"), pDatabase->m_rgMessageTemplates.GetSize());
|
||
|
|
||
|
Print(_T("\n"));
|
||
|
|
||
|
//
|
||
|
// Print statistics if requested
|
||
|
//
|
||
|
if (nPrintStatistics > 0) {
|
||
|
DumpVerboseStats(pDatabase, nPrintStatistics == 2);
|
||
|
}
|
||
|
|
||
|
eh:
|
||
|
if (pDatabase) {
|
||
|
delete pDatabase;
|
||
|
}
|
||
|
|
||
|
CoUninitialize();
|
||
|
|
||
|
return nRetCode;
|
||
|
}
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// Func: PrintHelp
|
||
|
//
|
||
|
// Desc: Prints the tool's help information.
|
||
|
//
|
||
|
void PrintHelp()
|
||
|
{
|
||
|
Print(_T(" Usage:\n\n"));
|
||
|
Print(_T(" ShimDBC [mode] [command switches] [input file] [output file]\n\n"));
|
||
|
Print(_T(" Modes:\n\n"));
|
||
|
Print(_T(" Fix Compiles a Fix database (e.g., sysmain.sdb).\n\n"));
|
||
|
Print(_T(" AppHelp Compiles an AppHelp database (e.g., apphelp.sdb).\n\n"));
|
||
|
Print(_T(" MSI Compiles an MSI database (e.g., msimain.sdb).\n\n"));
|
||
|
Print(_T(" Driver Compiles a Driver database (e.g., drvmain.sdb).\n\n"));
|
||
|
Print(_T(" Command switches:\n\n"));
|
||
|
Print(_T(" -a <file path> Specifies the reference XML for the AppHelp database\n"));
|
||
|
Print(_T(" This is usually the fix database (AppHelp mode only)\n\n"));
|
||
|
Print(_T(" -h Creates HTMLHelp files in the output file's directory\n"));
|
||
|
Print(_T(" used to create .CHM files. (AppHelp mode only)\n\n"));
|
||
|
Print(_T(" -f <file path> Include FILE binaries in database <file path> is\n"));
|
||
|
Print(_T(" directory to grab binaries from. (Fix mode only)\n\n"));
|
||
|
Print(_T(" -k <keyword> Specifies a <HISTORY> keyword to filter on.\n\n"));
|
||
|
Print(_T(" -m Writes out Migration support files\n\n"));
|
||
|
Print(_T(" -ov <version> Specifies what OS version to compile for.\n\n"));
|
||
|
Print(_T(" -op <platform> Specifies what OS platform to compile for.\n\n"));
|
||
|
Print(_T(" -l <language> Specifies the language to compile for.\n\n"));
|
||
|
Print(_T(" -q Quiet mode.\n\n"));
|
||
|
Print(_T(" -r[s] Creates Win2k-style registry files for use in\n"));
|
||
|
Print(_T(" migration or Win2k update packages. If -rs is used,\n"));
|
||
|
Print(_T(" then shimming stubs are added. (Fix mode only)\n\n"));
|
||
|
Print(_T(" -s Strict compile, additional checking is performed.\n\n"));
|
||
|
Print(_T(" -v[s] Verbose statistics. -vs indicates summary form.\n\n"));
|
||
|
Print(_T(" -x <file path> Use the makefile specified.\n\n"));
|
||
|
}
|
||
|
|
||
|
extern "C" BOOL
|
||
|
ShimdbcExecute(
|
||
|
LPCWSTR lpszCmdLine
|
||
|
)
|
||
|
{
|
||
|
LPWSTR* argv;
|
||
|
int argc = 0;
|
||
|
|
||
|
argv = CommandLineToArgvW(lpszCmdLine, &argc);
|
||
|
|
||
|
return 1 - _tmain(argc, argv);
|
||
|
}
|
||
|
|