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 / marshal2 / marshal2.cpp < prev    next >
C/C++ Source or Header  |  1997-08-30  |  14KB  |  445 lines

  1. /*+==========================================================================
  2.   File:      MARSHAL2.CPP
  3.  
  4.   Summary:   Main implementation file for MARSHAL2.DLL, a COM marshaling
  5.              server for the ICar, IUtility, and ICruise interfaces. This
  6.              module provides the main Win32 DLL framework including
  7.              explicit definitions for the DllMain, DllRegisterServer, and
  8.              DllUnregisterServer exported functions.
  9.  
  10.              For a comprehensive tutorial code tour of MARSHAL2's contents
  11.              and offerings see the tutorial MARSHAL2.HTM file. For more
  12.              specific technical details on the internal workings see the
  13.              comments dispersed throughout the MARSHAL2 source code.
  14.  
  15.   Classes:   none.
  16.  
  17.   Functions: DllMain, DllRegisterServer, DllUnregisterServer.
  18.  
  19.   Origin:    5-5-97: atrent - Editor-inheritance from DLLSERVE.CPP in
  20.                the DLLSERVE Tutorial Code Sample.
  21.  
  22. ----------------------------------------------------------------------------
  23.   This file is part of the Microsoft COM Tutorial Code Samples.
  24.  
  25.   Copyright (C) Microsoft Corporation, 1997.  All rights reserved.
  26.  
  27.   This source code is intended only as a supplement to Microsoft
  28.   Development Tools and/or on-line documentation.  See these other
  29.   materials for detailed information regarding Microsoft code samples.
  30.  
  31.   THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  32.   KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  33.   IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  34.   PARTICULAR PURPOSE.
  35. ==========================================================================+*/
  36.  
  37. /*---------------------------------------------------------------------------
  38.   We include WINDOWS.H for all Win32 applications.
  39.   We include OLE2.H because we will be calling the COM/OLE Libraries.
  40.   We include APPUTIL.H because we will be building this DLL using
  41.     the convenient Virtual Window and Dialog classes and other
  42.   We include MICARS.H for the interface declarations that were produced
  43.     by the MIDL comilation.  In particular this module needs the
  44.     interface IID declarations.
  45. ---------------------------------------------------------------------------*/
  46. #include <windows.h>
  47. #include <ole2.h>
  48. #include <apputil.h>
  49. #include "micars.h"
  50.  
  51.  
  52. // Global save variable for this module's instance handle.
  53. HINSTANCE g_hDllInst = NULL;
  54.  
  55.  
  56. /*F+F++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  57.   Function: UnicodeOk
  58.  
  59.   Summary:  Checks if the platform will handle unicode versions of
  60.             Win32 string API calls.
  61.  
  62.   Args:     void
  63.  
  64.   Returns:  BOOL
  65.               TRUE if unicode support; FALSE if not.
  66. ------------------------------------------------------------------------F-F*/
  67. BOOL UnicodeOk(void)
  68. {
  69.   BOOL bOk = TRUE;
  70.   TCHAR szUserName[MAX_STRING_LENGTH];
  71.   DWORD dwSize = MAX_STRING_LENGTH;
  72.  
  73.   if (!GetUserName(szUserName, &dwSize))
  74.     bOk = ERROR_CALL_NOT_IMPLEMENTED == GetLastError() ? FALSE : TRUE;
  75.  
  76.   return bOk;
  77. }
  78.  
  79.  
  80. /*F+F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F
  81.   Function: DllMain
  82.  
  83.   Summary:  Like WinMain is for an EXE application, this DllMain function
  84.             is the main entry point for this DLL.  It is called when the
  85.             DLL is loaded by a process, and when new threads are created
  86.             by a process that has already loaded this DLL.  DllMain is also
  87.             called when threads of a process that has loaded the DLL exit
  88.             cleanly and when the process itself unloads the DLL.
  89.  
  90.             If you want to use C runtime libraries, keep this function
  91.             named "DllMain" and you won't have to do anything special to
  92.             initialize the runtime libraries.
  93.  
  94.             When fdwReason == DLL_PROCESS_ATTACH, the return value is used
  95.             to determine if the DLL should remain loaded, or should be
  96.             immediately unloaded depending upon whether the DLL could be
  97.             initialized properly.  For all other values of fdwReason,
  98.             the return value is ignored.
  99.  
  100.   Args:     HINSTANCE hDLLInst,
  101.               Instance handle of the DLL.
  102.             DWORD fdwReason,
  103.               Process attach/detach or thread attach/detach.
  104.               Reason for calling.
  105.             LPVOID lpvReserved)
  106.               Reserved and not used.
  107.  
  108.   Returns:  BOOL,
  109.               Return value is used only when fdwReason == DLL_PROCESS_ATTACH.
  110.               TRUE  -  Used to signify that the DLL should remain loaded.
  111.               FALSE -  Used to signify that the DLL should be
  112.                 immediately unloaded.
  113. F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F-F*/
  114. BOOL WINAPI DllMain(
  115.               HINSTANCE hDllInst,
  116.               DWORD fdwReason,
  117.               LPVOID lpvReserved)
  118. {
  119.   BOOL bResult = TRUE;
  120.  
  121.   // Dispatch this main call based on the reason it was called.
  122.   switch (fdwReason)
  123.   {
  124.     case DLL_PROCESS_ATTACH:
  125.       // The DLL is being loaded for the first time by a given process.
  126.       // Perform per-process initialization here.  If the initialization
  127.       // is successful, return TRUE; if unsuccessful, return FALSE.
  128.       g_hDllInst = hDllInst;
  129.       bResult = UnicodeOk();
  130.       break;
  131.  
  132.     case DLL_PROCESS_DETACH:
  133.       // The DLL is being unloaded by a given process.  Do any
  134.       // per-process clean up here, such as undoing what was done in
  135.       // DLL_PROCESS_ATTACH.  The return value is ignored.
  136.       break;
  137.  
  138.     case DLL_THREAD_ATTACH:
  139.       // A thread is being created in a process that has already loaded
  140.       // this DLL.  Perform any per-thread initialization here.  The
  141.       // return value is ignored.
  142.       break;
  143.  
  144.     case DLL_THREAD_DETACH:
  145.       // A thread is exiting cleanly in a process that has already
  146.       // loaded this DLL.  Perform any per-thread clean up here.  The
  147.       // return value is ignored.
  148.       break;
  149.  
  150.     default:
  151.       break;
  152.   }
  153.  
  154.   return (bResult);
  155. }
  156.  
  157.  
  158. /*F+F++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  159.   Function: SetRegKeyValue
  160.  
  161.   Summary:  Internal utility function to set a Key, Subkey, and value
  162.             in the system Registry.
  163.  
  164.   Args:     LPTSTR pszKey,
  165.             LPTSTR pszSubkey,
  166.             LPTSTR pszValue)
  167.  
  168.   Returns:  BOOL
  169.               TRUE if success; FALSE if not.
  170. ------------------------------------------------------------------------F-F*/
  171. BOOL SetRegKeyValue(
  172.        LPTSTR pszKey,
  173.        LPTSTR pszSubkey,
  174.        LPTSTR pszValue)
  175. {
  176.   BOOL bOk = FALSE;
  177.   LONG ec;
  178.   HKEY hKey;
  179.   TCHAR szKey[MAX_STRING_LENGTH];
  180.  
  181.   lstrcpy(szKey, pszKey);
  182.  
  183.   if (NULL != pszSubkey)
  184.   {
  185.     lstrcat(szKey, TEXT("\\"));
  186.     lstrcat(szKey, pszSubkey);
  187.   }
  188.  
  189.   ec = RegCreateKeyEx(
  190.          HKEY_CLASSES_ROOT,
  191.          szKey,
  192.          0,
  193.          NULL,
  194.          REG_OPTION_NON_VOLATILE,
  195.          KEY_ALL_ACCESS,
  196.          NULL,
  197.          &hKey,
  198.          NULL);
  199.  
  200.   if (NULL != pszValue && ERROR_SUCCESS == ec)
  201.   {
  202.     ec = RegSetValueEx(
  203.            hKey,
  204.            NULL,
  205.            0,
  206.            REG_SZ,
  207.            (BYTE *)pszValue,
  208.            (lstrlen(pszValue)+1)*sizeof(TCHAR));
  209.     if (ERROR_SUCCESS == ec)
  210.       bOk = TRUE;
  211.     RegCloseKey(hKey);
  212.   }
  213.  
  214.   return bOk;
  215. }
  216.  
  217.  
  218. /*F+F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F
  219.   Function: DllRegisterServer
  220.  
  221.   Summary:  The standard exported function that can be called to command
  222.             this DLL server to register itself in the system registry.
  223.  
  224.   Args:     void.
  225.  
  226.   Returns:  HRESULT
  227.               NOERROR
  228. F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F-F*/
  229. STDAPI DllRegisterServer(void)
  230. {
  231.   HRESULT  hr = NOERROR;
  232.   TCHAR    szID[GUID_SIZE+1];
  233.   TCHAR    szIFace[GUID_SIZE+32];
  234.   TCHAR    szCLSID[GUID_SIZE+32];
  235.   TCHAR    szModulePath[MAX_PATH];
  236.  
  237.   // Obtain the path to this module's executable file for later use.
  238.   GetModuleFileName(
  239.     g_hDllInst,
  240.     szModulePath,
  241.     sizeof(szModulePath)/sizeof(TCHAR));
  242.  
  243.   /*-------------------------------------------------------------------------
  244.     Create registry entries for the ICar Interface.
  245.   -------------------------------------------------------------------------*/
  246.   // Create some base key strings.
  247.   StringFromGUID2(IID_ICar, szID, GUID_SIZE);
  248.   lstrcpy(szIFace, TEXT("Interface\\"));
  249.   lstrcat(szIFace, szID);
  250.   lstrcpy(szCLSID, TEXT("CLSID\\"));
  251.   lstrcat(szCLSID, szID);
  252.  
  253.   // Create the HKEY_CLASSES_ROOT\Interface entries.
  254.   SetRegKeyValue(
  255.     szIFace,
  256.     NULL,
  257.     TEXT("ICar"));
  258.   SetRegKeyValue(
  259.     szIFace,
  260.     TEXT("ProxyStubClsid32"),
  261.     szID);
  262.   SetRegKeyValue(
  263.     szIFace,
  264.     TEXT("NumMethods"),
  265.     TEXT("7"));
  266.  
  267.   // Create the HKEY_CLASSES_ROOT\CLSID entries.
  268.   SetRegKeyValue(
  269.     szCLSID,
  270.     NULL,
  271.     TEXT("ICar Proxy/Stub Factory"));
  272.   SetRegKeyValue(
  273.     szCLSID,
  274.     TEXT("InprocServer32"),
  275.     szModulePath);
  276.  
  277.   /*-------------------------------------------------------------------------
  278.     Create registry entries for the IUtility Interface.
  279.   -------------------------------------------------------------------------*/
  280.   // Create some base key strings.
  281.   StringFromGUID2(IID_IUtility, szID, GUID_SIZE);
  282.   lstrcpy(szIFace, TEXT("Interface\\"));
  283.   lstrcat(szIFace, szID);
  284.   lstrcpy(szCLSID, TEXT("CLSID\\"));
  285.   lstrcat(szCLSID, szID);
  286.  
  287.   // Create the HKEY_CLASSES_ROOT\Interface entries.
  288.   SetRegKeyValue(
  289.     szIFace,
  290.     NULL,
  291.     TEXT("IUtility"));
  292.   SetRegKeyValue(
  293.     szIFace,
  294.     TEXT("ProxyStubClsid32"),
  295.     szID);
  296.   SetRegKeyValue(
  297.     szIFace,
  298.     TEXT("NumMethods"),
  299.     TEXT("5"));
  300.  
  301.   // Create the HKEY_CLASSES_ROOT\CLSID entries.
  302.   SetRegKeyValue(
  303.     szCLSID,
  304.     NULL,
  305.     TEXT("IUtility Proxy/Stub Factory"));
  306.   SetRegKeyValue(
  307.     szCLSID,
  308.     TEXT("InprocServer32"),
  309.     szModulePath);
  310.  
  311.   /*-------------------------------------------------------------------------
  312.     Create registry entries for the ICruise Interface.
  313.   -------------------------------------------------------------------------*/
  314.   // Create some base key strings.
  315.   StringFromGUID2(IID_ICruise, szID, GUID_SIZE);
  316.   lstrcpy(szIFace, TEXT("Interface\\"));
  317.   lstrcat(szIFace, szID);
  318.   lstrcpy(szCLSID, TEXT("CLSID\\"));
  319.   lstrcat(szCLSID, szID);
  320.  
  321.   // Create the HKEY_CLASSES_ROOT\Interface entries.
  322.   SetRegKeyValue(
  323.     szIFace,
  324.     NULL,
  325.     TEXT("ICruise"));
  326.   SetRegKeyValue(
  327.     szIFace,
  328.     TEXT("ProxyStubClsid32"),
  329.     szID);
  330.   SetRegKeyValue(
  331.     szIFace,
  332.     TEXT("NumMethods"),
  333.     TEXT("5"));
  334.  
  335.   // Create the HKEY_CLASSES_ROOT\CLSID entries.
  336.   SetRegKeyValue(
  337.     szCLSID,
  338.     NULL,
  339.     TEXT("ICruise Proxy/Stub Factory"));
  340.   SetRegKeyValue(
  341.     szCLSID,
  342.     TEXT("InprocServer32"),
  343.     szModulePath);
  344.  
  345.   return hr;
  346. }
  347.  
  348.  
  349. /*F+F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F
  350.   Function: DllUnregisterServer
  351.  
  352.   Summary:  The standard exported function that can be called to command
  353.             this DLL server to unregister itself from the system Registry.
  354.  
  355.   Args:     void.
  356.  
  357.   Returns:  HRESULT
  358.               NOERROR
  359. F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F-F*/
  360. STDAPI DllUnregisterServer(void)
  361. {
  362.   HRESULT  hr = NOERROR;
  363.   TCHAR    szID[GUID_SIZE+1];
  364.   TCHAR    szIFace[GUID_SIZE+32];
  365.   TCHAR    szCLSID[GUID_SIZE+32];
  366.   TCHAR    szTemp[MAX_PATH+GUID_SIZE];
  367.  
  368.   /*-------------------------------------------------------------------------
  369.     Delete registry entries for the ICar Interface.
  370.   -------------------------------------------------------------------------*/
  371.   //Create some base key strings.
  372.   StringFromGUID2(IID_ICar, szID, GUID_SIZE);
  373.   lstrcpy(szIFace, TEXT("Interface\\"));
  374.   lstrcat(szIFace, szID);
  375.   lstrcpy(szCLSID, TEXT("CLSID\\"));
  376.   lstrcat(szCLSID, szID);
  377.  
  378.   lstrcpy(szTemp, szCLSID);
  379.   lstrcat(szTemp, TEXT("\\InprocServer32"));
  380.   RegDeleteKey(HKEY_CLASSES_ROOT, szTemp);
  381.  
  382.   lstrcpy(szTemp, szIFace);
  383.   lstrcat(szTemp, TEXT("\\ProxyStubClsid32"));
  384.   RegDeleteKey(HKEY_CLASSES_ROOT, szTemp);
  385.  
  386.   lstrcpy(szTemp, szIFace);
  387.   lstrcat(szTemp, TEXT("\\NumMethods"));
  388.   RegDeleteKey(HKEY_CLASSES_ROOT, szTemp);
  389.  
  390.   RegDeleteKey(HKEY_CLASSES_ROOT, szCLSID);
  391.   RegDeleteKey(HKEY_CLASSES_ROOT, szIFace);
  392.  
  393.   /*-------------------------------------------------------------------------
  394.     Delete registry entries for the IUtility Interface.
  395.   -------------------------------------------------------------------------*/
  396.   //Create some base key strings.
  397.   StringFromGUID2(IID_IUtility, szID, GUID_SIZE);
  398.   lstrcpy(szIFace, TEXT("Interface\\"));
  399.   lstrcat(szIFace, szID);
  400.   lstrcpy(szCLSID, TEXT("CLSID\\"));
  401.   lstrcat(szCLSID, szID);
  402.  
  403.   lstrcpy(szTemp, szCLSID);
  404.   lstrcat(szTemp, TEXT("\\InprocServer32"));
  405.   RegDeleteKey(HKEY_CLASSES_ROOT, szTemp);
  406.  
  407.   lstrcpy(szTemp, szIFace);
  408.   lstrcat(szTemp, TEXT("\\ProxyStubClsid32"));
  409.   RegDeleteKey(HKEY_CLASSES_ROOT, szTemp);
  410.  
  411.   lstrcpy(szTemp, szIFace);
  412.   lstrcat(szTemp, TEXT("\\NumMethods"));
  413.   RegDeleteKey(HKEY_CLASSES_ROOT, szTemp);
  414.  
  415.   RegDeleteKey(HKEY_CLASSES_ROOT, szCLSID);
  416.   RegDeleteKey(HKEY_CLASSES_ROOT, szIFace);
  417.  
  418.   /*-------------------------------------------------------------------------
  419.     Delete registry entries for the ICruise Interface.
  420.   -------------------------------------------------------------------------*/
  421.   //Create some base key strings.
  422.   StringFromGUID2(IID_ICruise, szID, GUID_SIZE);
  423.   lstrcpy(szIFace, TEXT("Interface\\"));
  424.   lstrcat(szIFace, szID);
  425.   lstrcpy(szCLSID, TEXT("CLSID\\"));
  426.   lstrcat(szCLSID, szID);
  427.  
  428.   lstrcpy(szTemp, szCLSID);
  429.   lstrcat(szTemp, TEXT("\\InprocServer32"));
  430.   RegDeleteKey(HKEY_CLASSES_ROOT, szTemp);
  431.  
  432.   lstrcpy(szTemp, szIFace);
  433.   lstrcat(szTemp, TEXT("\\ProxyStubClsid32"));
  434.   RegDeleteKey(HKEY_CLASSES_ROOT, szTemp);
  435.  
  436.   lstrcpy(szTemp, szIFace);
  437.   lstrcat(szTemp, TEXT("\\NumMethods"));
  438.   RegDeleteKey(HKEY_CLASSES_ROOT, szTemp);
  439.  
  440.   RegDeleteKey(HKEY_CLASSES_ROOT, szCLSID);
  441.   RegDeleteKey(HKEY_CLASSES_ROOT, szIFace);
  442.  
  443.   return hr;
  444. }
  445.