home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / com / tutsamp / register / register.cpp < prev    next >
C/C++ Source or Header  |  1997-08-05  |  9KB  |  292 lines

  1. /*+==========================================================================
  2.   File:      REGISTER.CPP
  3.  
  4.   Summary:   Implementation file for the REGISTER.EXE code sample
  5.              application.  REGISTER is a simple Win32 application that can
  6.              load a COM component server (either EXE or DLL) and command
  7.              it to register or unregister its components in the system
  8.              Registry.
  9.  
  10.              For a comprehensive tutorial code tour of REGISTER's contents
  11.              and offerings see the tutorial REGISTER.HTM file. For
  12.              more specific technical details on the internal workings see
  13.              the comments dispersed throughout the REGISTER source code.
  14.  
  15.   Classes:   CMainWindow.
  16.  
  17.   Functions: WinMain.
  18.  
  19.   Origin:    12-28-96: atrent - Based on SELFREG by Kraig Brockschmidt.
  20.  
  21. ----------------------------------------------------------------------------
  22.   This file is part of the Microsoft COM Tutorial Code Samples.
  23.  
  24.   Copyright (C) Microsoft Corporation, 1997.  All rights reserved.
  25.  
  26.   This source code is only intended as a supplement to Microsoft
  27.   Development Tools and/or on-line documentation.  See these other
  28.   materials for detailed information regarding Microsoft code samples.
  29.  
  30.   THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  31.   KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  32.   IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  33.   PARTICULAR PURPOSE.
  34. ==========================================================================+*/
  35.  
  36. /*---------------------------------------------------------------------------
  37.   We include WINDOWS.H for all Win32 applications.
  38.   We include OLE2.H because we will be calling the COM/OLE Libraries.
  39.   We include INITGUID.H only once (here) in the entire app because we
  40.     will be using GUIDs and want them as constants in the data segment.
  41.   We include APPUTIL.H because we will be building this application using
  42.     the utility functions in the APPUTIL Library (ie, APPUTIL.LIB).
  43.   We include REGISTER.H because it has resource definitions
  44.     specific to this REGISTER application.
  45. ---------------------------------------------------------------------------*/
  46. #include <windows.h>
  47. #include <ole2.h>
  48. #include <initguid.h>
  49. #include <apputil.h>
  50. #include "register.h"
  51.  
  52.  
  53. /*F+F++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  54.   Function: ErrorBoxID
  55.  
  56.   Summary:  Utility function to show an error message box dialog.
  57.             Parent window is desktop.
  58.  
  59.   Args;     HINSTANCE hInst,
  60.               Handle to app instance.
  61.             UINT uStrID
  62.               Resource ID of the error string to display.
  63.  
  64.   Returns:  int
  65.               TRUE if success; FALSE if not.
  66.               Result of the MessageBox call.
  67. ------------------------------------------------------------------------F-F*/
  68. int ErrorBoxID(
  69.       HINSTANCE hInst,
  70.       UINT uStrID)
  71. {
  72.   int iResult = FALSE;
  73.   CHAR szTitle[MAX_STRING];
  74.   CHAR szError[MAX_STRING];
  75.  
  76.   if (LoadStringA(hInst, IDS_ERROR_TITLE, szTitle, MAX_STRING))
  77.     if (LoadStringA(hInst, uStrID, szError, MAX_STRING))
  78.       iResult = MessageBoxA(
  79.                   NULL,
  80.                   szError,
  81.                   szTitle,
  82.                   MB_OK | MB_ICONEXCLAMATION);
  83.  
  84.   return (iResult);
  85. }
  86.  
  87.  
  88. /*F+F++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  89.   Function: SkipAnsiString
  90.  
  91.   Summary:  Utility function to scan an input ANSI string and either skip
  92.             white characters or skip non-white characters.
  93.  
  94.   Args;     LPSTR psz,
  95.               Input ANSI string to be scanned.
  96.             BOOL bSkip)
  97.               Input boolean determining whether to skip white space
  98.               or not.  TRUE means skip white space; FALSE means skip
  99.               non-white chars.
  100.  
  101.   Returns:  LPSTR
  102.               String pointer after the skip.
  103. ------------------------------------------------------------------------F-F*/
  104. LPSTR SkipAnsiString(
  105.          LPSTR psz,
  106.          BOOL bSkipWhite)
  107. {
  108.   char ch;
  109.   BOOL bWhite;
  110.  
  111.   while (ch = *psz)
  112.   {
  113.     bWhite = ('\n'==ch || '\r'==ch || '\t'==ch || ' '==ch);
  114.  
  115.     if ((bSkipWhite && !bWhite) || (!bSkipWhite && bWhite))
  116.       break;
  117.  
  118.     psz++;
  119.   }
  120.  
  121.   return psz;
  122. }
  123.  
  124.  
  125. /*F+F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F
  126.   Function: WinMain
  127.  
  128.   Summary:  The Windows main entry point function for this application.
  129.             Initializes the application, the COM Libraries, and starts
  130.             the main application message loop.
  131.  
  132.   Args:     HINSTANCE hInstance,
  133.               Instance handle; a new one for each invocation of this app.
  134.             HINSTANCE hPrevInstance,
  135.               Instance handle of the previous instance. NULL in Win32.
  136.             LPSTR lpCmdLine,
  137.               Windows passes a pointer to the application's
  138.               invocation command line.
  139.             int nCmdShow)
  140.               Bits telling the show state of the application.
  141.  
  142.   Returns:  int
  143.               msg.wParam (upon exit of message loop).
  144.               FALSE if this instance couldn't initialize and run.
  145. F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F-F*/
  146. extern "C" int PASCAL WinMain(
  147.                         HINSTANCE hInstance,
  148.                         HINSTANCE hPrevInstance,
  149.                         LPSTR pszCmdLine,
  150.                         int nCmdShow)
  151. {
  152.   int   iFail = FALSE;
  153.   BOOL  bEXE = FALSE;
  154.   BOOL  bUnreg = FALSE;
  155.   LPSTR psz;
  156.   char  ch;
  157.  
  158.   /*--------------------------------------------------------------------
  159.     Walk down the command line looking for /u and /e in any order.
  160.     The first non-whitespace character after whitespace that is not
  161.     a "/" is assumed to be the beginning of the server filename.
  162.     This is all done in ANSI because pszCmdLine is in ANSI.
  163.   --------------------------------------------------------------------*/
  164.   psz = pszCmdLine;
  165.  
  166.   while (ch = *psz)
  167.   {
  168.     BOOL    bStop = FALSE;
  169.  
  170.     switch (ch)
  171.     {
  172.       case '\t':
  173.       case '\n':
  174.       case '\r':
  175.       case ' ':
  176.         // Skip any white space.
  177.         psz = SkipAnsiString(psz, TRUE);
  178.         continue;
  179.  
  180.       case '/':
  181.       case '-':
  182.         // Check what option this is, then skip to next whitespace.
  183.         ch = *(++psz);
  184.         if ('u' == ch)
  185.           bUnreg = TRUE;
  186.         if ('e' == ch)
  187.           bEXE = TRUE;
  188.         psz = SkipAnsiString(psz, FALSE);
  189.         continue;
  190.  
  191.       default:
  192.         bStop = TRUE;
  193.         break;
  194.     }
  195.  
  196.     if (bStop)
  197.       break;
  198.  
  199.     psz++;
  200.   }
  201.  
  202.   if (0 != ch)
  203.   {
  204.     // If the command line was not null, launch the specified EXE or
  205.     // load the specified DLL and tell either to do their registration
  206.     // or unregistartion.
  207.     if (bEXE)
  208.     {
  209.       UINT uError;
  210.       CHAR szEXE[MAX_PATH];
  211.  
  212.       wsprintfA(
  213.         szEXE,
  214.         "%s %s",
  215.         psz,
  216.         bUnreg ? "/UNREGSERVER" : "/REGSERVER");
  217.  
  218.       // We WinExec the .EXE server passing /unregserver or /regserver.
  219.       uError = WinExec(szEXE, SW_HIDE);
  220.       if (uError < 32)
  221.       {
  222.         ErrorBoxID(hInstance, IDS_EXERUN_FAIL);
  223.         iFail = TRUE;
  224.       }
  225.       else
  226.       {
  227.         // Show a timed message box indicating registration success.
  228.         DelayBox(hInstance, MAKEINTRESOURCE(IDD_SUCCESS_MSG), NULL);
  229.       }
  230.     }
  231.     else
  232.     {
  233.       // Because we load the DLL server into our own (ie, REGISTER.EXE)
  234.       // process space, call to initialize the COM Library.  Use the
  235.       // SUCCEEDED macro to detect success.  If fail then exit app
  236.       // with error message.
  237.       if (SUCCEEDED(CoInitialize(NULL)))
  238.       {
  239.         HINSTANCE hMod;
  240.  
  241.         // Load the Server DLL into our process space.
  242.         hMod = LoadLibraryA(psz);
  243.  
  244.         if (NULL != hMod)
  245.         {
  246.           HRESULT (STDAPICALLTYPE *pfn)(void);
  247.  
  248.           if (bUnreg)
  249.           {
  250.             (FARPROC&)pfn = GetProcAddress(hMod, "DllUnregisterServer");
  251.  
  252.             if (NULL != pfn)
  253.               iFail = FAILED((*pfn)());
  254.  
  255.             if (iFail)
  256.               ErrorBoxID(hInstance, IDS_DLLUNREG_FAIL);
  257.             else
  258.             {
  259.               // Show a timed message box indicating registration success.
  260.               DelayBox(hInstance, MAKEINTRESOURCE(IDD_SUCCESS_MSG), NULL);
  261.             }
  262.           }
  263.           else
  264.           {
  265.             (FARPROC&)pfn = GetProcAddress(hMod, "DllRegisterServer");
  266.  
  267.             if (NULL != pfn)
  268.               iFail = FAILED((*pfn)());
  269.             if (iFail)
  270.               ErrorBoxID(hInstance, IDS_DLLREG_FAIL);
  271.             else
  272.             {
  273.               // Show a timed message box indicating registration success.
  274.               DelayBox(hInstance, MAKEINTRESOURCE(IDD_SUCCESS_MSG), NULL);
  275.             }
  276.           }
  277.           CoFreeLibrary(hMod);
  278.         }
  279.         else
  280.           ErrorBoxID(hInstance, IDS_LOADLIB_FAIL);
  281.  
  282.         // We're exiting this app so shut down the COM Library.
  283.         CoUninitialize();
  284.       }
  285.       else
  286.         ErrorBoxID(hInstance, IDS_COMINITFAILED);
  287.     }
  288.   }
  289.  
  290.   return iFail;
  291. }
  292.