FRESERVE.CPP
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:16k
源码类别:

Windows编程

开发平台:

Visual C++

  1. /*+==========================================================================
  2.   File:      FRESERVE.CPP
  3.   Summary:   Implementation file for a DLL COM Component server providing
  4.              a Ball-related COM Component: Ball. Access to Class Factories
  5.              is provided in this module.  This server also supports self
  6.              registration and unregistration. FRESERVE is a thread-safe
  7.              server for the COBall COM objects.
  8.              For a comprehensive tutorial code tour of FRESERVE's contents
  9.              and offerings see the accompanying FRESERVE.TXT file. For
  10.              more specific technical details on the internal workings see
  11.              the comments dispersed throughout the FRESERVE source code.
  12.              FRESERVE is functioned by the multi-threaded server, FRECLIEN.
  13.              For more details see FRECLIEN.TXT in the sibling FRECLIEN
  14.              directory.
  15.   Classes:   none.
  16.   Functions: DllMain, DllGetClassObject, DllCanUnloadNow, DllRegisterServer,
  17.              DllUnregisterServer.
  18.   Origin:    4-6-96: atrent - Editor-inheritance from DLLSERVE.CPP in
  19.                the DLLSERVE OLE Tutorial Code Sample.
  20. ----------------------------------------------------------------------------
  21.   This file is part of the Microsoft OLE Tutorial Code Samples.
  22.   Copyright (C) Microsoft Corporation, 1996.  All rights reserved.
  23.   This source code is intended only as a supplement to Microsoft
  24.   Development Tools and/or on-line documentation.  See these other
  25.   materials for detailed information regarding Microsoft code samples.
  26.   THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  27.   KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  28.   IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  29.   PARTICULAR PURPOSE.
  30. ==========================================================================+*/
  31. /*---------------------------------------------------------------------------
  32.   We include WINDOWS.H for all Win32 applications.
  33.   We include OLE2.H because we will be making calls to the OLE Libraries
  34.     in future exploitation of this DLL skeleton.
  35.   We include INITGUID.H only once (here) in the entire DLL because we
  36.     will be defining GUIDs and want them as constants in the data segment.
  37.   We include APPUTIL.H because we will be building this DLL using
  38.     the convenient Virtual Window and Dialog classes and other
  39.     utility functions in the APPUTIL Library (ie, APPUTIL.LIB).
  40.   We include IBALL.H and BALLGUID.H for the common ball-related Interface
  41.     class, GUID, and CLSID specifications.
  42.   We include FRESERVE.H because it has the main declerations of all the
  43.     car related interfaces and their GUIDs.  It also has the _DLLEXPORT_
  44.     controlled import and export specifications.
  45.   We include SERVER.H because it has the necessary internal class and
  46.     resource definitions for this DLL.
  47.   We include FACTORY.H because it has the necessary internal class factory
  48.     declarations for this DLL component server.
  49. ---------------------------------------------------------------------------*/
  50. #include "preserve.h"
  51. #include "factory.h"
  52. // Global variable definitions. Some Initialized in DllMain() below.
  53. // We encapsulate the control of this COM server (eg, lock and object
  54. // counting) in a server control C++ object.  Here is it's pointer.
  55. CServer* g_pServer = NULL;
  56. /*F+F++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  57.   Function: UnicodeOk
  58.   Summary:  Checks if the platform will handle unicode versions of
  59.             Win32 string API calls.
  60.   Args:     void
  61.   Returns:  BOOL
  62.               TRUE if unicode support; FALSE if not.
  63. ------------------------------------------------------------------------F-F*/
  64. BOOL UnicodeOk(void)
  65. {
  66.   BOOL bOk = TRUE;
  67.   TCHAR szUserName[MAX_STRING_LENGTH];
  68.   DWORD dwSize = MAX_STRING_LENGTH;
  69.   if (!GetUserName(szUserName, &dwSize))
  70.     bOk = ERROR_CALL_NOT_IMPLEMENTED == GetLastError() ? FALSE : TRUE;
  71.   return bOk;
  72. }
  73. /*F+F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F
  74.   Function: DllMain
  75.   Summary:  Like WinMain is for an EXE application, this DllMain function
  76.             is the main entry point for this DLL.  It is called when the
  77.             DLL is loaded by a process, and when new threads are created
  78.             by a process that has already loaded this DLL.  DllMain is
  79.             also called when threads of a process that has loaded the DLL
  80.             exit cleanly and when the process itself unloads the DLL.
  81.             If you want to use C runtime libraries, keep this function
  82.             named "DllMain" and you won't have to do anything special to
  83.             initialize the runtime libraries.
  84.             When fdwReason == DLL_PROCESS_ATTACH, the return value is used
  85.             to determine if the DLL should remain loaded, or should be
  86.             immediately unloaded depending upon whether the DLL could be
  87.             initialized properly.  For all other values of fdwReason, the
  88.             return value is ignored.
  89.   Args:     HINSTANCE hDLLInst,
  90.               Instance handle of the DLL.
  91.             DWORD fdwReason,
  92.               Process attach/detach or thread attach/detach.
  93.               Reason for calling.
  94.             LPVOID lpvReserved)
  95.               Reserved and not used.
  96.   Returns:  BOOL,
  97.               Return value is used only when fdwReason == DLL_PROCESS_ATTACH.
  98.               TRUE  -  Used to signify that the DLL should remain loaded.
  99.               FALSE -  Used to signify that the DLL should be
  100.                 immediately unloaded.
  101. F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F-F*/
  102. BOOL WINAPI DllMain(
  103.               HINSTANCE hDllInst,
  104.               DWORD fdwReason,
  105.               LPVOID lpvReserved)
  106. {
  107.   BOOL bResult = TRUE;
  108.   // Dispatch this main call based on the reason it was called.
  109.   switch (fdwReason)
  110.   {
  111.     case DLL_PROCESS_ATTACH:
  112.       // The DLL is being loaded for the first time by a given process.
  113.       // Perform per-process initialization here.  If the initialization
  114.       // is successful, return TRUE; if unsuccessful, return FALSE.
  115.       bResult = FALSE;
  116.       if (UnicodeOk())
  117.       {
  118.         // Instantiate the CServer utility class.
  119.         g_pServer = new CServer;
  120.         if (NULL != g_pServer)
  121.         {
  122.           // Remember the DLL Instance handle.
  123.           g_pServer->m_hDllInst = hDllInst;
  124.           bResult = TRUE;
  125.         }
  126.       }
  127.       break;
  128.     case DLL_PROCESS_DETACH:
  129.       // The DLL is being unloaded by a given process.  Do any
  130.       // per-process clean up here, such as undoing what was done in
  131.       // DLL_PROCESS_ATTACH.  The return value is ignored.
  132.       DELETE_POINTER(g_pServer);
  133.       break;
  134.     case DLL_THREAD_ATTACH:
  135.       // A thread is being created in a process that has already loaded
  136.       // this DLL.  Perform any per-thread initialization here.  The
  137.       // return value is ignored.
  138.       break;
  139.     case DLL_THREAD_DETACH:
  140.       // A thread is exiting cleanly in a process that has already
  141.       // loaded this DLL.  Perform any per-thread clean up here.  The
  142.       // return value is ignored.
  143.       break;
  144.     default:
  145.       break;
  146.   }
  147.   return (bResult);
  148. }
  149. /*F+F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F
  150.   Function: DllGetClassObject
  151.   Summary:  The standard exported function that the COM service library
  152.             uses to obtain an object class of the class factory for a
  153.             specified component provided by this server DLL.
  154.   Args:     REFCLSID rclsid,
  155.               [in] The CLSID of the requested Component.
  156.             REFIID riid,
  157.               [in] The requested interface on the Class Factory.
  158.             PPVOID ppv)
  159.               [in/out] The output interface pointer to the Class Factory.
  160.   Returns:  HRESULT
  161.               E_FAIL if requested component isn't supported.
  162.               E_OUTOFMEMORY if out of memory.
  163.               Error code out of the QueryInterface.
  164. F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F-F*/
  165. STDAPI DllGetClassObject(
  166.          REFCLSID rclsid,
  167.          REFIID riid,
  168.          PPVOID ppv)
  169. {
  170.   HRESULT hr = CLASS_E_CLASSNOTAVAILABLE;
  171.   IUnknown* pCob = NULL;
  172.   if (CLSID_Ball == rclsid)
  173.   {
  174.     hr = E_OUTOFMEMORY;
  175.     pCob = new CFBall(NULL, g_pServer);
  176.   }
  177.   if (NULL != pCob)
  178.   {
  179.     g_pServer->ObjectsUp();
  180.     hr = pCob->QueryInterface(riid, ppv);
  181.     if (FAILED(hr))
  182.     {
  183.       g_pServer->ObjectsDown();
  184.       DELETE_POINTER(pCob);
  185.     }
  186.   }
  187.   return hr;
  188. }
  189. /*F+F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F
  190.   Function: DllCanUnloadNow
  191.   Summary:  The standard exported function that the COM service library
  192.             uses to determine if this server DLL can be unloaded.
  193.   Args:     void.
  194.   Returns:  HRESULT
  195.               S_OK if this DLL server can be unloaded.
  196.               S_FALSE if this DLL can not be unloaded.
  197. F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F-F*/
  198. STDAPI DllCanUnloadNow(void)
  199. {
  200.   HRESULT hr;
  201.   // We return S_OK of there are no longer any living objects AND
  202.   // there are no outstanding client locks on this server.
  203.   hr = g_pServer->CanUnloadNow();
  204.   return hr;
  205. }
  206. /*F+F++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  207.   Function: SetRegKeyValue
  208.   Summary:  Internal utility function to set a Key, Subkey, and value
  209.             in the system Registry under HKEY_CLASSES_ROOT.
  210.   Args:     LPTSTR pszKey,
  211.             LPTSTR pszSubkey,
  212.             LPTSTR pszValue)
  213.   Returns:  BOOL
  214.               TRUE if success; FALSE if not.
  215. ------------------------------------------------------------------------F-F*/
  216. BOOL SetRegKeyValue(
  217.        LPTSTR pszKey,
  218.        LPTSTR pszSubkey,
  219.        LPTSTR pszValue)
  220. {
  221.   BOOL bOk = FALSE;
  222.   LONG ec;
  223.   HKEY hKey;
  224.   TCHAR szKey[MAX_STRING_LENGTH];
  225.   lstrcpy(szKey, pszKey);
  226.   if (NULL != pszSubkey)
  227.   {
  228.     lstrcat(szKey, TEXT("\"));
  229.     lstrcat(szKey, pszSubkey);
  230.   }
  231.   ec = RegCreateKeyEx(
  232.          HKEY_CLASSES_ROOT,
  233.          szKey,
  234.          0,
  235.          NULL,
  236.          REG_OPTION_NON_VOLATILE,
  237.          KEY_ALL_ACCESS,
  238.          NULL,
  239.          &hKey,
  240.          NULL);
  241.   if (NULL != pszValue && ERROR_SUCCESS == ec)
  242.   {
  243.     ec = RegSetValueEx(
  244.            hKey,
  245.            NULL,
  246.            0,
  247.            REG_SZ,
  248.            (BYTE *)pszValue,
  249.            (lstrlen(pszValue)+1)*sizeof(TCHAR));
  250.     if (ERROR_SUCCESS == ec)
  251.       bOk = TRUE;
  252.     RegCloseKey(hKey);
  253.   }
  254.   return bOk;
  255. }
  256. /*F+F++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  257.   Function: AddRegNamedValue
  258.   Summary:  Internal utility function to add a named data value to an
  259.             existing Key (with optional Subkey) in the system Registry
  260.             under HKEY_CLASSES_ROOT.
  261.   Args:     LPTSTR pszKey,
  262.             LPTSTR pszSubkey,
  263.             LPTSTR pszValueName,
  264.             LPTSTR pszValue)
  265.   Returns:  BOOL
  266.               TRUE if success; FALSE if not.
  267. ------------------------------------------------------------------------F-F*/
  268. BOOL AddRegNamedValue(
  269.        LPTSTR pszKey,
  270.        LPTSTR pszSubkey,
  271.        LPTSTR pszValueName,
  272.        LPTSTR pszValue)
  273. {
  274.   BOOL bOk = FALSE;
  275.   LONG ec;
  276.   HKEY hKey;
  277.   TCHAR szKey[MAX_STRING_LENGTH];
  278.   lstrcpy(szKey, pszKey);
  279.   if (NULL != pszSubkey)
  280.   {
  281.     lstrcat(szKey, TEXT("\"));
  282.     lstrcat(szKey, pszSubkey);
  283.   }
  284.   ec = RegOpenKeyEx(
  285.          HKEY_CLASSES_ROOT,
  286.          szKey,
  287.          0,
  288.          KEY_ALL_ACCESS,
  289.          &hKey);
  290.   if (NULL != pszValue && ERROR_SUCCESS == ec)
  291.   {
  292.     ec = RegSetValueEx(
  293.            hKey,
  294.            pszValueName,
  295.            0,
  296.            REG_SZ,
  297.            (BYTE *)pszValue,
  298.            (lstrlen(pszValue)+1)*sizeof(TCHAR));
  299.     if (ERROR_SUCCESS == ec)
  300.       bOk = TRUE;
  301.     RegCloseKey(hKey);
  302.   }
  303.   return bOk;
  304. }
  305. /*F+F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F
  306.   Function: DllRegisterServer
  307.   Summary:  The standard exported function that can be called to command
  308.             this DLL server to register itself in the system registry.
  309.   Args:     void.
  310.   Returns:  HRESULT
  311.               NOERROR
  312. F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F-F*/
  313. STDAPI DllRegisterServer(void)
  314. {
  315.   HRESULT  hr = NOERROR;
  316.   TCHAR    szID[GUID_SIZE+1];
  317.   TCHAR    szCLSID[GUID_SIZE+1];
  318.   TCHAR    szModulePath[MAX_PATH];
  319.   // Obtain the path to this module's executable file for later use.
  320.   GetModuleFileName(
  321.     g_pServer->m_hDllInst,
  322.     szModulePath,
  323.     sizeof(szModulePath)/sizeof(TCHAR));
  324.   /*-------------------------------------------------------------------------
  325.     Create registry entries for the DllBall Component.
  326.   -------------------------------------------------------------------------*/
  327.   // Create some base key strings.
  328.   StringFromGUID2(CLSID_Ball, szID, GUID_SIZE);
  329.   lstrcpy(szCLSID, TEXT("CLSID\"));
  330.   lstrcat(szCLSID, szID);
  331.   // Create ProgID keys.
  332.   SetRegKeyValue(
  333.     TEXT("DllBall1.0"),
  334.     NULL,
  335.     TEXT("DllBall Component - FRESERVE Code Sample"));
  336.   SetRegKeyValue(
  337.     TEXT("DllBall1.0"),
  338.     TEXT("CLSID"),
  339.     szID);
  340.   // Create VersionIndependentProgID keys.
  341.   SetRegKeyValue(
  342.     TEXT("DllBall"),
  343.     NULL,
  344.     TEXT("DllBall Component - FRESERVE Code Sample"));
  345.   SetRegKeyValue(
  346.     TEXT("DllBall"),
  347.     TEXT("CurVer"),
  348.     TEXT("DllBall1.0"));
  349.   SetRegKeyValue(
  350.     TEXT("DllBall"),
  351.     TEXT("CLSID"),
  352.     szID);
  353.   // Create entries under CLSID.
  354.   SetRegKeyValue(
  355.     szCLSID,
  356.     NULL,
  357.     TEXT("DllBall Component - FRESERVE Code Sample"));
  358.   SetRegKeyValue(
  359.     szCLSID,
  360.     TEXT("ProgID"),
  361.     TEXT("DllBall1.0"));
  362.   SetRegKeyValue(
  363.     szCLSID,
  364.     TEXT("VersionIndependentProgID"),
  365.     TEXT("DllBall"));
  366.   SetRegKeyValue(
  367.     szCLSID,
  368.     TEXT("NotInsertable"),
  369.     NULL);
  370.   SetRegKeyValue(
  371.     szCLSID,
  372.     TEXT("InprocServer32"),
  373.     szModulePath);
  374.   AddRegNamedValue(
  375.     szCLSID,
  376.     TEXT("InprocServer32"),
  377.     TEXT("ThreadingModel"),
  378.     TEXT("Free"));
  379.   return hr;
  380. }
  381. /*F+F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F
  382.   Function: DllUnregisterServer
  383.   Summary:  The standard exported function that can be called to command
  384.             this DLL server to unregister itself from the system Registry.
  385.   Args:     void.
  386.   Returns:  HRESULT
  387.               NOERROR
  388. F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F-F*/
  389. STDAPI DllUnregisterServer(void)
  390. {
  391.   HRESULT  hr = NOERROR;
  392.   TCHAR    szID[GUID_SIZE+1];
  393.   TCHAR    szCLSID[GUID_SIZE+1];
  394.   TCHAR    szTemp[GUID_SIZE+1];
  395.   /*-------------------------------------------------------------------------
  396.     Delete registry entries for the Ball Component.
  397.   -------------------------------------------------------------------------*/
  398.   //Create some base key strings.
  399.   StringFromGUID2(CLSID_Ball, szID, GUID_SIZE);
  400.   lstrcpy(szCLSID, TEXT("CLSID\"));
  401.   lstrcat(szCLSID, szID);
  402.   RegDeleteKey(HKEY_CLASSES_ROOT, TEXT("DllBall\CurVer"));
  403.   RegDeleteKey(HKEY_CLASSES_ROOT, TEXT("DllBall\CLSID"));
  404.   RegDeleteKey(HKEY_CLASSES_ROOT, TEXT("DllBall"));
  405.   RegDeleteKey(HKEY_CLASSES_ROOT, TEXT("DllBall1.0\CLSID"));
  406.   RegDeleteKey(HKEY_CLASSES_ROOT, TEXT("DllBall1.0"));
  407.   wsprintf(szTemp, TEXT("%s\%s"), szCLSID, TEXT("ProgID"));
  408.   RegDeleteKey(HKEY_CLASSES_ROOT, szTemp);
  409.   wsprintf(szTemp, TEXT("%s\%s"), szCLSID, TEXT("VersionIndependentProgID"));
  410.   RegDeleteKey(HKEY_CLASSES_ROOT, szTemp);
  411.   wsprintf(szTemp, TEXT("%s\%s"), szCLSID, TEXT("NotInsertable"));
  412.   RegDeleteKey(HKEY_CLASSES_ROOT, szTemp);
  413.   wsprintf(szTemp, TEXT("%s\%s"), szCLSID, TEXT("InprocServer32"));
  414.   RegDeleteKey(HKEY_CLASSES_ROOT, szTemp);
  415.   RegDeleteKey(HKEY_CLASSES_ROOT, szCLSID);
  416.   return hr;
  417. }