home *** CD-ROM | disk | FTP | other *** search
/ PC Press 1997 July / Sezamfile97_2.iso / windows / program / activex / axtsamp.exe / TSBRANCH.EXE / DLLSKEL / DLLSKEL.CPP next >
C/C++ Source or Header  |  1997-01-12  |  13KB  |  332 lines

  1. /*+==========================================================================
  2.   File:      DLLSKEL.CPP
  3.  
  4.   Summary:   Implementation file for the general DLL skeleton
  5.              that can be used as a point of departure for more complex
  6.              COM Win32 DLLs.  It is used as a skeletal base for
  7.              the ActiveX Tutorial series of code samples.
  8.  
  9.              DLLSKEL.CPP contains the DllMain entry function for the DLL.
  10.              As a simple skeleton, this DLL contains only two
  11.              representative exported function calls: DllHelloBox and
  12.              DllAboutBox.
  13.  
  14.              For a comprehensive tutorial code tour of DLLSKEL's
  15.              contents and offerings see the tutorial DLLSKEL.HTM file.
  16.              For more specific technical details on the internal workings
  17.              see the comments dispersed throughout the DLLSKEL source code.
  18.  
  19.   Classes:   none.
  20.  
  21.   Functions: DllMain, DllHelloBox, DllAboutBox
  22.  
  23.   Origin:    12-9-96: atrent - Created and revised via editor-inheritance
  24.                of DLLSKEL.C in the Win32 SDK FRMWORK code samples.
  25.  
  26. ----------------------------------------------------------------------------
  27.   This file is part of the Microsoft ActiveX Tutorial Code Samples.
  28.  
  29.   Copyright (C) Microsoft Corporation, 1997.  All rights reserved.
  30.  
  31.   This source code is intended only as a supplement to Microsoft
  32.   Development Tools and/or on-line documentation.  See these other
  33.   materials for detailed information regarding Microsoft code samples.
  34.  
  35.   THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  36.   KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  37.   IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  38.   PARTICULAR PURPOSE.
  39. ==========================================================================+*/
  40.  
  41. /*---------------------------------------------------------------------------
  42.   We include WINDOWS.H for all Win32 applications.
  43.   We include OLE2.H because we will be calling the COM/OLE Libraries
  44.     in future exploitation of this DLL skeleton.
  45.   We include APPUTIL.H because we will be building this DLL using
  46.     the convenient Virtual Window and Dialog classes and other
  47.     utility functions in the APPUTIL Library (ie, APPUTIL.LIB).
  48.   We include DLLSKELI.H because it has internal class declarations and
  49.     resource ID definitions specific for this DLL.
  50.   We include DLLSKEL.H because it has the necessary STDENTRY function
  51.     prototypes.  The _DLLEXPORT_ #define is used to tell DLLSKEL.H to
  52.     define the appropriate functions as exported from this DLL.
  53.     Otherwise, DLLSKEL.H is included by users of this DLL who do not
  54.     define _DLLEXPORT_ so that the appropriate functions are then
  55.     declared as imports rather than defined as exports.
  56. ---------------------------------------------------------------------------*/
  57. #include <windows.h>
  58. #include <ole2.h>
  59. #include <apputil.h>
  60. #include "dllskeli.h"
  61. #define _DLLEXPORT_
  62. #include "dllskel.h"
  63.  
  64.  
  65. // Global variable definitions. Some Initialized in DllMain() below.
  66.  
  67. // We define a static global variable to point to file-mapped shared memory.
  68. // This memory is shared by all loaded instances of this DLL.
  69. static void* g_pvShared = NULL;
  70. // Handle to file mapping object.
  71. static HANDLE g_hMapObj = NULL;
  72.  
  73. // We encapsulate some of the global instance data for clarity.  Here is a
  74. // pointer to the DllData object.
  75. CDllData* g_pDll;
  76.  
  77.  
  78. /*F+F++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  79.   Function: UnicodeOk
  80.  
  81.   Summary:  Checks if the platform will handle unicode versions of
  82.             Win32 string API calls.
  83.  
  84.   Args:     void
  85.  
  86.   Returns:  BOOL
  87.               TRUE if unicode support; FALSE if not.
  88. ------------------------------------------------------------------------F-F*/
  89. BOOL UnicodeOk(void)
  90. {
  91.   BOOL bOk = TRUE;
  92.   TCHAR szUserName[MAX_STRING_LENGTH];
  93.   DWORD dwSize = MAX_STRING_LENGTH;
  94.  
  95.   if (!GetUserName(szUserName, &dwSize))
  96.     bOk = ERROR_CALL_NOT_IMPLEMENTED == GetLastError() ? FALSE : TRUE;
  97.  
  98.   return bOk;
  99. }
  100.  
  101.  
  102. #if defined(UNICODE)
  103. #define DLLSKELSHARED_STR L"DLLSkelShared"
  104. #else
  105. #define DLLSKELSHARED_STR "DLLSkelShared"
  106. #endif
  107.  
  108.  
  109. /*F+F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F
  110.   Function: DllMain
  111.  
  112.   Summary:  Like WinMain is for an EXE application, this DllMain function
  113.             is the main entry point for this DLL.  It is called when the
  114.             DLL is loaded by a process, and when new threads are created
  115.             by a process that has already loaded this DLL.  DllMain is also
  116.             called when threads of a process that has loaded the DLL exit
  117.             cleanly and when the process itself unloads the DLL.
  118.  
  119.             If you want to use C runtime libraries, keep this function
  120.             named "DllMain" and you won't have to do anything special to
  121.             initialize the runtime libraries.
  122.  
  123.             When fdwReason == DLL_PROCESS_ATTACH, the return value is used
  124.             to determine if the DLL should remain loaded, or should be
  125.             immediately unloaded depending upon whether the DLL could be
  126.             initialized properly.  For all other values of fdwReason,
  127.             the return value is ignored.
  128.  
  129.   Args:     HINSTANCE hDllInst,
  130.               Instance handle of the DLL.
  131.             DWORD fdwReason,
  132.               Process attach/detach or thread attach/detach.
  133.               Reason for calling.
  134.             LPVOID lpvReserved)
  135.               Reserved and not used.
  136.  
  137.   Returns:  BOOL,
  138.               Return value is used only when fdwReason == DLL_PROCESS_ATTACH.
  139.               TRUE  -  Used to signify that the DLL should remain loaded.
  140.               FALSE -  Used to signify that the DLL should be
  141.                 immediately unloaded.
  142. F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F-F*/
  143. BOOL WINAPI DllMain(
  144.               HINSTANCE hDllInst,
  145.               DWORD fdwReason,
  146.               LPVOID lpvReserved)
  147. {
  148.   BOOL bResult = TRUE;
  149.  
  150.   // Dispatch this call based on the reason it was called.
  151.   switch (fdwReason)
  152.   {
  153.     case DLL_PROCESS_ATTACH:
  154.       // The DLL is being loaded for the first time by a given process.
  155.       // Perform per-process initialization here.  If the initialization
  156.       // is successful, return TRUE; if unsuccessful, return FALSE.
  157.       bResult = FALSE;
  158.       if (UnicodeOk())
  159.       {
  160.         // Instantiate a DLL global data encapsulator class.
  161.         g_pDll = new CDllData;
  162.         if (NULL != g_pDll)
  163.         {
  164.           // Remember the DLL Instance handle.
  165.           g_pDll->hDllInst = hDllInst;
  166.           // Create a MsgBox object.
  167.           g_pDll->pMsgBox = new CMsgBox;
  168.           if (NULL != g_pDll->pMsgBox)
  169.           {
  170.             BOOL fFirst;
  171.             int iSharedSize = sizeof(CDllShared);
  172.  
  173.             // Create a named file mapping object.
  174.             g_hMapObj = CreateFileMapping(
  175.                           (HANDLE) 0xFFFFFFFF,     // Use paging file
  176.                           NULL,                    // No security attributes
  177.                           PAGE_READWRITE,          // Read/Write access
  178.                           0,                       // Mem Size: high 32 bits
  179.                           iSharedSize,             // Mem Size: low 32 bits
  180.                           DLLSKELSHARED_STR);      // Name of map object
  181.             if (NULL != g_hMapObj)
  182.             {
  183.               // Determine if this is the first create of the file mapping.
  184.               fFirst = (ERROR_ALREADY_EXISTS != GetLastError());
  185.  
  186.               // Now get a pointer to the file-mapped shared memory.
  187.               g_pvShared = MapViewOfFile(
  188.                              g_hMapObj,        // File Map obj to view
  189.                              FILE_MAP_WRITE,   // Read/Write access
  190.                              0,                // high: map from beginning
  191.                              0,                // low:
  192.                              0);               // default: map entire file
  193.               if (NULL != g_pvShared)
  194.               {
  195.                 CDllShared* pShared = (CDllShared*) g_pvShared;
  196.  
  197.                 if (fFirst)
  198.                 {
  199.                   // If this is the first attaching process, init the
  200.                   // shared memory.
  201.                   memset(g_pvShared, 0, iSharedSize);
  202.                   pShared->iUserCount = 1;
  203.                 }
  204.                 else
  205.                 {
  206.                   // Increment the cummulative global count of all
  207.                   // attached processes (ie, the count of DLL users).
  208.                   InterlockedIncrement((LONG*) &pShared->iUserCount);
  209.                 }
  210.                 // Save a local instance copy of this user instance
  211.                 // count. Each user process has its own g_pDll instance
  212.                 // data and can thus remember it's user instance count.
  213.                 g_pDll->iUserCount = pShared->iUserCount;
  214.                 bResult = TRUE;
  215.               }
  216.             }
  217.           }
  218.         }
  219.       }
  220.       break;
  221.  
  222.     case DLL_PROCESS_DETACH:
  223.       // The DLL is being unloaded by a given process.  Do any
  224.       // per-process clean up here, such as undoing what was done in
  225.       // DLL_PROCESS_ATTACH.  The return value is ignored.
  226.       // Unmap any shared memory from the process's address space.
  227.       UnmapViewOfFile(g_pvShared);
  228.       // Close the process's handle to the file-mapping object.
  229.       CloseHandle(g_hMapObj);
  230.       if (NULL != g_pDll)
  231.       {
  232.         // Delete the message box and global DLL instance data.
  233.         DELETE_POINTER(g_pDll->pMsgBox);
  234.         DELETE_POINTER(g_pDll);
  235.       }
  236.       break;
  237.  
  238.     case DLL_THREAD_ATTACH:
  239.       // A thread is being created in a process that has already loaded
  240.       // this DLL.  Perform any per-thread initialization here.  The
  241.       // return value is ignored.
  242.       break;
  243.  
  244.     case DLL_THREAD_DETACH:
  245.       // A thread is exiting cleanly in a process that has already
  246.       // loaded this DLL.  Perform any per-thread clean up here.  The
  247.       // return value is ignored.
  248.       break;
  249.  
  250.     default:
  251.       break;
  252.   }
  253.  
  254.   return (bResult);
  255. }
  256.  
  257.  
  258. /*F+F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F
  259.   Function: DllHelloBox
  260.  
  261.   Summary:  One of the exported service functions of this DLL.  In this
  262.             simple code sample, DllHelloBox uses a critical section to
  263.             govern access to incrementing a global count of the number
  264.             of times this function was called.  A message box is shown
  265.             to display the instance handle of this DLL and the number
  266.             of times this DllHelloBox has been called.  See DLLSKEL.HTM
  267.             for more details.
  268.  
  269.   Args:     HWND hWnd)
  270.               Handle of the window that is to be parent of message box.
  271.  
  272.   Returns:  BOOL,
  273.               Always returns TRUE.
  274. F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F-F*/
  275. STDENTRY_(BOOL) DllHelloBox(
  276.                   HWND hWnd)
  277. {
  278.   int iHelloCount;
  279.   CDllShared* pShared = (CDllShared*) g_pvShared;
  280.  
  281.   // Increment the cummulative global count of all Hellos.
  282.   InterlockedIncrement((LONG*) &pShared->iHelloCount);
  283.   iHelloCount = pShared->iHelloCount;
  284.  
  285.   // Now show the user a -Notice- message box and load the display strings
  286.   // out of this DLL's resources.  Use the format string to show the
  287.   // user instance count of this loaded DLL and the shared hello count.
  288.   g_pDll->pMsgBox->Init(g_pDll->hDllInst, hWnd);
  289.   g_pDll->pMsgBox->NoteFmtID(
  290.             IDS_HELLOCOUNTFMT,
  291.             g_pDll->iUserCount,
  292.             iHelloCount);
  293.  
  294.   return TRUE;
  295. }
  296.  
  297.  
  298. /*F+F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F+++F
  299.   Function: DllAboutBox
  300.  
  301.   Summary:  One of the exported service functions of this DLL.  In this
  302.             simple code sample, DllAboutBox showcases use of the
  303.             CAboutBox class (from the APPUTIL utility library).  It also
  304.             illustrates how to implement this dialog using resources
  305.             stored in this DLL itself.  See DLLSKEL.HTM for details on
  306.             how this DLLSKEL.DLL is exploited by the DLLUSER.EXE
  307.             application.
  308.  
  309.   Args:     HWND hWnd)
  310.               Handle of window that is to be parent of the dialog window.
  311.  
  312.   Returns:  BOOL,
  313.               Always returns TRUE.
  314. F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F---F-F*/
  315. STDENTRY_(BOOL) DllAboutBox(
  316.                   HWND hWnd)
  317. {
  318.   // Define one of those nifty APPUTIL CAboutBox modal dialog objects.
  319.   CAboutBox dlgAboutBox;
  320.  
  321.   // Show the standard About Box dialog for this DLL by telling the dialog
  322.   // C++ object to show itself by invoking its ShowDialog method.
  323.   // Pass it this DLL instance and the parent window handle.  Use a dialog
  324.   // resource ID for the dialog stored in this DLL module's resources.
  325.   dlgAboutBox.ShowDialog(
  326.     g_pDll->hDllInst,
  327.     MAKEINTRESOURCE(IDD_ABOUTBOX),
  328.     hWnd);
  329.  
  330.   return TRUE;
  331. }
  332.