home *** CD-ROM | disk | FTP | other *** search
/ Power GUI Programming with VisualAge C++ / powergui.iso / trialva / ibmcppw / samples / compiler / sample05 / dll / sample05.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-02-20  |  11.6 KB  |  296 lines

  1. #pragma strings( readonly )
  2. /******************************************************************************/
  3. /*                                                                            */
  4. /* SAMPLE05.C                                                                 */
  5. /*                                                                            */
  6. /* COPYRIGHT:                                                                 */
  7. /* ----------                                                                 */
  8. /* Copyright (C) International Business Machines Corp., 1991, 1996.           */
  9. /*                                                                            */
  10. /* DISCLAIMER OF WARRANTIES:                                                  */
  11. /* -------------------------                                                  */
  12. /* The following [enclosed] code is sample code created by IBM                */
  13. /* Corporation.  This sample code is not part of any standard IBM product     */
  14. /* and is provided to you solely for the purpose of assisting you in the      */
  15. /* development of your applications.  The code is provided "AS IS",           */
  16. /* without warranty of any kind.  IBM shall not be liable for any damages     */
  17. /* arising out of your use of the sample code, even if they have been         */
  18. /* advised of the possibility of such damages.                                */
  19. /*                                                                            */
  20. /* This example provides 5 external entrypoints of which 2 are exported for   */
  21. /* use by client processes.  The entrypoints are:                             */
  22. /*                                                                            */
  23. /* _DLL_InitTerm - Initialization/Termination function for the DLL that is    */
  24. /*                 invoked by the loader.  When the /Ge- compile option is    */
  25. /*                 used the linker is told that this is the function to       */
  26. /*                 execute when the DLL is first loaded and last freed for    */
  27. /*                 each process.                                              */
  28. /*                                                                            */
  29. /* DLLREGISTER  - Called by _DLL_InitTerm for each process that loads the     */
  30. /*                DLL.                                                        */
  31. /*                                                                            */
  32. /* DLLINCREMENT - Accepts a count from its client and adds this value to      */
  33. /*                the process and system totals.                              */
  34. /*                                                                            */
  35. /* DLLSTATS     - Dumps process and system totals on behalf of its client.    */
  36. /*                                                                            */
  37. /* DLLDEREGISTER- Called by _DLL_InitTerm for each process that frees the     */
  38. /*                DLL.                                                        */
  39. /*                                                                            */
  40. /******************************************************************************/
  41.  
  42. #include <windows.h>
  43. #include <stdio.h>
  44. #include "sample05.h"
  45.  
  46. static unsigned long DLLREGISTER( void );
  47. static unsigned long DLLDEREGISTER( void );
  48.  
  49. #define SHARED_SEMAPHORE_NAME "DLL.LCK"
  50.  
  51. /* The following data will be per-process data.  It will not be shared among  */
  52. /* different processes.                                                       */
  53.  
  54. static HANDLE hmtxSharedSem;         /* Shared semaphore                      */
  55. static unsigned long ulProcessTotal; /* Total of increments for a process     */
  56. static DWORD pid;                    /* Process identifier                    */
  57.  
  58. /* This is the global data segment that is shared by every process.           */
  59.  
  60. #pragma data_seg( GLOBAL_SEG )
  61.  
  62. static unsigned long ulProcessCount;        /* total number of processes      */
  63. static unsigned long ulGrandTotal;          /* Grand total of increments      */
  64.  
  65. /* _DLL_InitTerm() - called by the loader for DLL initialization/termination  */
  66. /* This function must return a non-zero value if successful and a zero value  */
  67. /* if unsuccessful.                                                           */
  68.  
  69. unsigned long __stdcall _DLL_InitTerm( HINSTANCE hModule,
  70.                                      DWORD ulFlag, LPVOID dummy)
  71.    {
  72.    ULONG rc;
  73.  
  74.    /* If ulFlag is DLL_PROCESS_ATTACH then initialization is required:        */
  75.    /*    If the shared memory pointer is NULL then the DLL is being loaded    */
  76.    /*    for the first time so acquire the named shared storage for the       */
  77.    /*    process control structures.  A linked list of process control        */
  78.    /*    structures will be maintained.  Each time a new process loads this   */
  79.    /*    DLL, a new process control structure is created and it is inserted   */
  80.    /*    at the end of the list by calling DLLREGISTER.                       */
  81.    /*                                                                         */
  82.    /* If ulFlag is DLL_PROCESS_DETTACH then termination is required:          */
  83.    /*    Call DLLDEREGISTER which will remove the process control structure   */
  84.    /*    and free the shared memory block from its virtual address space.     */
  85.  
  86.    switch( ulFlag )
  87.       {
  88.       case DLL_PROCESS_ATTACH:
  89.          _rmem_init();
  90.          if ( !ulProcessCount )
  91.             {
  92.             /* Create the shared mutex semaphore.                             */
  93.  
  94.             if (( hmtxSharedSem = CreateMutex(NULL,
  95.                                               FALSE,
  96.                                               SHARED_SEMAPHORE_NAME)) == NULL)
  97.                {
  98.                printf( "CreateMutex  rc = %lu\n", GetLastError() );
  99.                return FALSE;
  100.                }
  101.             }
  102.  
  103.          /* Register the current process.                                     */
  104.  
  105.          if ( DLLREGISTER( ) )
  106.             return FALSE;
  107.  
  108.          break;
  109.  
  110.       case DLL_PROCESS_DETACH:
  111.          /* De-register the current process.                                  */
  112.  
  113.          if ( DLLDEREGISTER( ) )
  114.             return 0;
  115.  
  116.          _rmem_term();
  117.          break;
  118.  
  119.       default:
  120.          return 0;
  121.       }
  122.  
  123.    /* Indicate success.  Non-zero means success!!!                            */
  124.  
  125.    return TRUE;
  126.    }
  127.  
  128. /* DLLREGISTER - Registers the current process so that it can use this        */
  129. /*               subsystem.  Called by _DLL_InitTerm when the DLL is first    */
  130. /*               loaded for the current process.                              */
  131.  
  132. static unsigned long DLLREGISTER( void )
  133.    {
  134.    unsigned long rc;
  135.  
  136.    /* Get the process id       */
  137.  
  138.     pid = GetCurrentProcessId();
  139.  
  140.    /* Open the shared mutex semaphore for this process.                       */
  141.  
  142.    if ( ( hmtxSharedSem = OpenMutex(SYNCHRONIZE,
  143.                                     TRUE,
  144.                                     SHARED_SEMAPHORE_NAME ) ) == NULL)
  145.       {
  146.       printf( "OpenMutex rc = %lu\n", rc = GetLastError() );
  147.       return rc;
  148.       }
  149.  
  150.    /* Acquire the shared mutex semaphore.                                     */
  151.  
  152.    if ( WaitForSingleObject( hmtxSharedSem,
  153.                                    INFINITE )  == 0xFFFFFFFF )
  154.       {
  155.       printf( "WaitFor SingleObject rc = %lu\n", rc = GetLastError() );
  156.       CloseHandle( hmtxSharedSem );
  157.       return rc;
  158.       }
  159.  
  160.    /* Increment the count of processes registered.                            */
  161.  
  162.    ++ulProcessCount;
  163.  
  164.    /* Initialize the per-process data.                                        */
  165.  
  166.    ulProcessTotal = 0;
  167.  
  168.    /* Tell the user that the current process has been registered.             */
  169.  
  170.    printf( "\nProcess %lu has been registered.\n\n", pid );
  171.  
  172.    /* Release the shared mutex semaphore.                                     */
  173.  
  174.    if ( ReleaseMutex( hmtxSharedSem ) == FALSE )
  175.       {
  176.       printf( "ReleaseMutex rc = %lu\n", rc = GetLastError() );
  177.       return rc;
  178.       }
  179.  
  180.    return 0;
  181.    }
  182.  
  183. /* DLLINCREMENT - Increments the process and global totals on behalf of the   */
  184. /*                calling program.                                            */
  185.  
  186. int _Export DLLINCREMENT( int incount )
  187.    {
  188.    unsigned long rc;               /* return code from DOS APIs               */
  189.  
  190.    /* Acquire the shared mutex semaphore.                                     */
  191.  
  192.    if ( WaitForSingleObject( hmtxSharedSem,
  193.                                 INFINITE )  == 0xFFFFFFFF )
  194.       {
  195.       printf( "WaitForSingleObject rc = %lu\n", rc = GetLastError());
  196.       return rc;
  197.       }
  198.  
  199.    /* Increment the counts the process and grand totals.                      */
  200.  
  201.    ulProcessTotal += incount;
  202.    ulGrandTotal += incount;
  203.  
  204.    /* Tell the user that the increment was successful.                        */
  205.  
  206.    printf( "\nThe increment for process %lu was successful.\n\n", pid );
  207.  
  208.    /* Release the shared mutex semaphore.                                     */
  209.  
  210.    if ( ReleaseMutex( hmtxSharedSem )  == FALSE )
  211.       {
  212.       printf( "ReleaseMutex rc = %lu\n", rc = GetLastError() );
  213.       return rc;
  214.       }
  215.  
  216.    return 0;
  217.    }
  218.  
  219. /* DLLSTATS  - Prints process and grand totals.                               */
  220.  
  221. int _Export DLLSTATS( void )
  222.    {
  223.    unsigned long rc;
  224.  
  225.    /* Acquire the shared mutex semaphore.                                     */
  226.  
  227.    if ( WaitForSingleObject( hmtxSharedSem,
  228.                                    INFINITE )  == 0xFFFFFFFF )
  229.       {
  230.       printf( "WaitForSingleObject rc = %lu\n", rc = GetLastError());
  231.       return rc;
  232.       }
  233.  
  234.    /* Print out per-process and global information.                           */
  235.  
  236.    printf( "\nCurrent process identifier     = %lu\n", pid );
  237.    printf( "Current process total          = %lu\n", ulProcessTotal );
  238.    printf( "Number of processes registered = %lu\n", ulProcessCount );
  239.    printf( "Grand Total                    = %lu\n\n", ulGrandTotal );
  240.  
  241.    /* Release the shared mutex semaphore.                                     */
  242.  
  243.    if ( ReleaseMutex( hmtxSharedSem ) == FALSE )
  244.       {
  245.       printf( "ReleaseMutex rc = %lu\n", rc = GetLastError() );
  246.       return rc;
  247.       }
  248.  
  249.    return 0;
  250.    }
  251.  
  252. /* DLLDEREGISTER - Deregisters the current process from this subsystem.       */
  253. /*                 Called by _DLL_InitTerm when the DLL is freed for the      */
  254. /*                 last time by the current process.                          */
  255.  
  256. static unsigned long DLLDEREGISTER( void )
  257.    {
  258.    unsigned long rc;
  259.  
  260.    /* Acquire the shared mutex semaphore.                                     */
  261.  
  262.    if ( ( rc = WaitForSingleObject( hmtxSharedSem,
  263.                                    INFINITE ) ) == 0xFFFFFFFF )
  264.       {
  265.       printf( "WaitForSingleObject rc = %lu\n", GetLastError());
  266.       return rc;
  267.       }
  268.  
  269.    /* Decrement the count of processes registered.                            */
  270.  
  271.    --ulProcessCount;
  272.  
  273.    /* Tell the user that the current process has been deregistered.           */
  274.  
  275.    printf( "\nProcess %lu has been deregistered.\n\n", pid );
  276.  
  277.    /* Release the shared mutex semaphore.                                     */
  278.  
  279.    if ( ReleaseMutex( hmtxSharedSem ) == FALSE )
  280.       {
  281.       printf( "ReleaseMutex rc = %lu\n", rc= GetLastError() );
  282.       return rc;
  283.       }
  284.  
  285.    /* Close the shared mutex semaphore for this process.                      */
  286.  
  287.    if ( CloseHandle( hmtxSharedSem )  == FALSE )
  288.       {
  289.       printf( "CloseHandle   rc = %lu\n", rc = GetLastError() );
  290.       return rc;
  291.       }
  292.  
  293.    return 0;
  294.    }
  295.  
  296.