home *** CD-ROM | disk | FTP | other *** search
- #pragma message("Merge Database Utility. Copyright (c) 1997 Microsoft Corp.")
- #if 0 // makefile definitions, to build: %vcbin%\nmake -fMsiMerg.cpp
- DESCRIPTION = Merge Database Utility
- MODULENAME = MsiMerg
- SUBSYSTEM = console
- FILEVERSION = Msi
- LINKLIBS = OLE32.lib
- !include <MsiTool.Mak>
- !if 0 #nmake skips the rest of this file
- #endif // end of makefile definitions
-
- #define W32DOWS_LEAN_AND_MEAN // faster compile
- #define W32
- #define MSI
-
- #include <windows.h>
- #ifndef RC_INVOKED // start of source code
- #include <tchar.h> // define UNICODE=1 on nmake command line to build UNICODE
- #include "MsiQuery.h" // MSI API
-
- //________________________________________________________________________________
- //
- // Constants and globals
- //________________________________________________________________________________
-
- const TCHAR szHelp[] = TEXT("Msi Merge Tool --- Merge Two Databases\n\nMsiMerg(d).exe {base db} {ref db}\n");
- const TCHAR szTable[] = TEXT("_MergeErrors");
-
- const int cchDisplayBuf = 4096;
- HANDLE g_hStdOut;
- TCHAR g_rgchBuffer[4096];
-
- //________________________________________________________________________________
- //
- // Function prototypes
- //________________________________________________________________________________
-
- void Display(LPCTSTR szMessage);
- void ErrorExit(UINT iError, LPCTSTR szMessage);
- void CheckError(UINT iError, LPCTSTR szMessage);
- void Merge(TCHAR* szBaseDb, TCHAR* szRefDb);
-
- //_____________________________________________________________________________________________________
- //
- // main
- //_____________________________________________________________________________________________________
-
- extern "C" int __cdecl _tmain(int argc, TCHAR* argv[])
- {
- // Determine handle
- g_hStdOut = ::GetStdHandle(STD_OUTPUT_HANDLE);
- if (g_hStdOut == INVALID_HANDLE_VALUE)
- g_hStdOut = 0; // non-zero if stdout redirected or piped
-
- if (argc == 2 && ((_tcscmp(argv[1], TEXT("-?")) == 0) || (_tcscmp(argv[1], TEXT("/?")) == 0)))
- ErrorExit( 0, szHelp);
-
- // Check for enough arguments and valid options
- CheckError(argc != 3, TEXT("msimerg(d).exe {base db} {ref db}"));
- Merge(argv[1], argv[2]);
- ErrorExit(0, TEXT("Done"));
- return 0;
- }
-
-
- //________________________________________________________________________________
- //
- // Merge function
- // Merge(...);
- //________________________________________________________________________________
-
- void Merge(TCHAR* szBaseDb, TCHAR* szRefDb)
- {
- PMSIHANDLE hBaseDb = 0;
- PMSIHANDLE hRefDb = 0;
-
- CheckError(MSI::MsiOpenDatabase(szBaseDb, MSIDBOPEN_TRANSACT, &hBaseDb), TEXT("Error Opening Base Database"));
- CheckError(MSI::MsiOpenDatabase(szRefDb, MSIDBOPEN_READONLY, &hRefDb), TEXT("Error Opening Reference Databaes"));
- UINT uiError = MSI::MsiDatabaseMerge(hBaseDb, hRefDb, szTable);
- CheckError(MSI::MsiDatabaseCommit(hBaseDb), TEXT("Error Saving Database"));
- CheckError(uiError, TEXT("Error Merging Database, Check _MergeErrors Table for Merge conflicts"));
- }
-
- //________________________________________________________________________________
- //
- // Error handling and Display functions:
- // Display(...);
- // ErrorExit(...);
- // CheckError(...);
- //
- //________________________________________________________________________________
-
- void Display(LPCTSTR szMessage)
- {
- if (szMessage)
- {
- int cbOut = _tcsclen(szMessage);;
- if (g_hStdOut)
- {
- #ifdef UNICODE
- char rgchTemp[cchDisplayBuf];
- if (W32::GetFileType(g_hStdOut) == FILE_TYPE_CHAR)
- {
- W32::WideCharToMultiByte(CP_ACP, 0, szMessage, cbOut, rgchTemp, sizeof(rgchTemp), 0, 0);
- szMessage = (LPCWSTR)rgchTemp;
- }
- else
- cbOut *= 2; // write Unicode if not console device
- #endif
- DWORD cbWritten;
- W32::WriteFile(g_hStdOut, szMessage, cbOut, &cbWritten, 0);
- }
- else
- W32::MessageBox(0, szMessage, W32::GetCommandLine(), MB_OK);
- }
- }
-
-
- void ErrorExit(UINT iError, LPCTSTR szMessage)
- {
- if (szMessage)
- {
- int cbOut;
- TCHAR szBuffer[256]; // errors only, not used for display output
- if (iError == 0)
- cbOut = lstrlen(szMessage);
- else
- {
- LPCTSTR szTemplate = (iError & 0x80000000L)
- ? TEXT("Error 0x%X. %s\n")
- : TEXT("Error %i. %s\n");
- cbOut = wsprintf(szBuffer, szTemplate, iError, szMessage);
- szMessage = szBuffer;
- }
- if (g_hStdOut)
- {
- #ifdef UNICODE
- char rgchTemp[cchDisplayBuf];
- if (W32::GetFileType(g_hStdOut) == FILE_TYPE_CHAR)
- {
- W32::WideCharToMultiByte(CP_ACP, 0, szMessage, cbOut, rgchTemp, sizeof(rgchTemp), 0, 0);
- szMessage = (LPCWSTR)rgchTemp;
- }
- else
- cbOut *= 2; // write Unicode if not console device
- #endif // UNICODE
- DWORD cbWritten;
- W32::WriteFile(g_hStdOut, szMessage, cbOut, &cbWritten, 0);
- }
- else
- W32::MessageBox(0, szMessage, W32::GetCommandLine(), MB_OK);
- }
- MSI::MsiCloseAllHandles();
- W32::ExitProcess(szMessage != 0);
- }
-
- void CheckError(UINT iError, LPCTSTR szMessage)
- {
- if (iError != ERROR_SUCCESS)
- ErrorExit(iError, szMessage);
- }
-
- #else // RC_INVOKED, end of source code, start of resources
- #endif // RC_INVOKED
- #if 0
- !endif // makefile terminator
- #endif
-