home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / sysmgmt / msi / msimerg / msimerg.cpp < prev    next >
C/C++ Source or Header  |  1997-10-13  |  5KB  |  168 lines

  1. #pragma message("Merge Database Utility.  Copyright (c) 1997 Microsoft Corp.")
  2. #if 0  // makefile definitions, to build: %vcbin%\nmake -fMsiMerg.cpp
  3. DESCRIPTION = Merge Database Utility
  4. MODULENAME = MsiMerg
  5. SUBSYSTEM = console
  6. FILEVERSION = Msi
  7. LINKLIBS = OLE32.lib
  8. !include <MsiTool.Mak>
  9. !if 0  #nmake skips the rest of this file
  10. #endif // end of makefile definitions
  11.  
  12. #define W32DOWS_LEAN_AND_MEAN  // faster compile
  13. #define W32
  14. #define MSI
  15.  
  16. #include <windows.h>
  17. #ifndef RC_INVOKED    // start of source code
  18. #include <tchar.h>    // define UNICODE=1 on nmake command line to build UNICODE
  19. #include "MsiQuery.h" // MSI API
  20.  
  21. //________________________________________________________________________________
  22. //
  23. // Constants and globals
  24. //________________________________________________________________________________
  25.  
  26. const TCHAR szHelp[] = TEXT("Msi Merge Tool --- Merge Two Databases\n\nMsiMerg(d).exe {base db} {ref db}\n");
  27. const TCHAR szTable[] = TEXT("_MergeErrors");
  28.  
  29. const int cchDisplayBuf = 4096;                                        
  30. HANDLE g_hStdOut;
  31. TCHAR g_rgchBuffer[4096];
  32.  
  33. //________________________________________________________________________________
  34. //
  35. // Function prototypes
  36. //________________________________________________________________________________
  37.  
  38. void Display(LPCTSTR szMessage);
  39. void ErrorExit(UINT iError, LPCTSTR szMessage);
  40. void CheckError(UINT iError, LPCTSTR szMessage);
  41. void Merge(TCHAR* szBaseDb, TCHAR* szRefDb);
  42.  
  43. //_____________________________________________________________________________________________________
  44. //
  45. // main 
  46. //_____________________________________________________________________________________________________
  47.  
  48. extern "C" int __cdecl _tmain(int argc, TCHAR* argv[])
  49. {
  50.     // Determine handle
  51.     g_hStdOut = ::GetStdHandle(STD_OUTPUT_HANDLE);
  52.     if (g_hStdOut == INVALID_HANDLE_VALUE)
  53.         g_hStdOut = 0;  // non-zero if stdout redirected or piped
  54.     
  55.     if (argc == 2 && ((_tcscmp(argv[1], TEXT("-?")) == 0) || (_tcscmp(argv[1], TEXT("/?")) == 0)))
  56.         ErrorExit( 0, szHelp);
  57.  
  58.     // Check for enough arguments and valid options
  59.     CheckError(argc != 3, TEXT("msimerg(d).exe {base db} {ref db}"));
  60.     Merge(argv[1], argv[2]);
  61.     ErrorExit(0, TEXT("Done"));
  62.     return 0;
  63. }
  64.  
  65.  
  66. //________________________________________________________________________________
  67. //
  68. // Merge function
  69. //    Merge(...);
  70. //________________________________________________________________________________
  71.  
  72. void Merge(TCHAR* szBaseDb, TCHAR* szRefDb)
  73. {
  74.     PMSIHANDLE hBaseDb = 0;
  75.     PMSIHANDLE hRefDb = 0;
  76.  
  77.     CheckError(MSI::MsiOpenDatabase(szBaseDb, MSIDBOPEN_TRANSACT, &hBaseDb), TEXT("Error Opening Base Database"));
  78.     CheckError(MSI::MsiOpenDatabase(szRefDb, MSIDBOPEN_READONLY, &hRefDb), TEXT("Error Opening Reference Databaes"));
  79.     UINT uiError = MSI::MsiDatabaseMerge(hBaseDb, hRefDb, szTable);
  80.     CheckError(MSI::MsiDatabaseCommit(hBaseDb), TEXT("Error Saving Database"));
  81.     CheckError(uiError, TEXT("Error Merging Database, Check _MergeErrors Table for Merge conflicts"));
  82. }
  83.  
  84. //________________________________________________________________________________
  85. //
  86. // Error handling and Display functions:
  87. //    Display(...);
  88. //       ErrorExit(...);
  89. //    CheckError(...);
  90. //
  91. //________________________________________________________________________________
  92.  
  93. void Display(LPCTSTR szMessage)
  94. {
  95.     if (szMessage)
  96.     {
  97.         int cbOut = _tcsclen(szMessage);;
  98.         if (g_hStdOut)
  99.         {
  100. #ifdef UNICODE
  101.             char rgchTemp[cchDisplayBuf];
  102.             if (W32::GetFileType(g_hStdOut) == FILE_TYPE_CHAR)
  103.             {
  104.                 W32::WideCharToMultiByte(CP_ACP, 0, szMessage, cbOut, rgchTemp, sizeof(rgchTemp), 0, 0);
  105.                 szMessage = (LPCWSTR)rgchTemp;
  106.             }
  107.             else
  108.                 cbOut *= 2;   // write Unicode if not console device
  109. #endif
  110.             DWORD cbWritten;
  111.             W32::WriteFile(g_hStdOut, szMessage, cbOut, &cbWritten, 0);
  112.         }
  113.         else
  114.             W32::MessageBox(0, szMessage, W32::GetCommandLine(), MB_OK);
  115.     }
  116. }
  117.  
  118.  
  119. void ErrorExit(UINT iError, LPCTSTR szMessage)
  120. {
  121.     if (szMessage)
  122.     {
  123.         int cbOut;
  124.         TCHAR szBuffer[256];  // errors only, not used for display output
  125.         if (iError == 0)
  126.             cbOut = lstrlen(szMessage);
  127.         else
  128.         {
  129.             LPCTSTR szTemplate = (iError & 0x80000000L)
  130.                                         ? TEXT("Error 0x%X. %s\n")
  131.                                         : TEXT("Error %i. %s\n");
  132.             cbOut = wsprintf(szBuffer, szTemplate, iError, szMessage);
  133.             szMessage = szBuffer;
  134.         }
  135.         if (g_hStdOut)
  136.         {
  137. #ifdef UNICODE
  138.             char rgchTemp[cchDisplayBuf];
  139.             if (W32::GetFileType(g_hStdOut) == FILE_TYPE_CHAR)
  140.             {
  141.                 W32::WideCharToMultiByte(CP_ACP, 0, szMessage, cbOut, rgchTemp, sizeof(rgchTemp), 0, 0);
  142.                 szMessage = (LPCWSTR)rgchTemp;
  143.             }
  144.             else
  145.                 cbOut *= 2;   // write Unicode if not console device
  146. #endif // UNICODE
  147.             DWORD cbWritten;
  148.             W32::WriteFile(g_hStdOut, szMessage, cbOut, &cbWritten, 0);
  149.         }
  150.         else
  151.             W32::MessageBox(0, szMessage, W32::GetCommandLine(), MB_OK);
  152.     }
  153.     MSI::MsiCloseAllHandles();
  154.     W32::ExitProcess(szMessage != 0);
  155. }
  156.  
  157. void CheckError(UINT iError, LPCTSTR szMessage)
  158. {
  159.     if (iError != ERROR_SUCCESS)
  160.         ErrorExit(iError, szMessage);
  161. }
  162.  
  163. #else // RC_INVOKED, end of source code, start of resources
  164. #endif // RC_INVOKED
  165. #if 0 
  166. !endif // makefile terminator
  167. #endif
  168.