home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / tolkit45.zip / os2tk45 / samples / mm / mcispy / mdm.c < prev    next >
C/C++ Source or Header  |  1999-05-11  |  25KB  |  714 lines

  1. /*********************** START OF SPECIFICATIONS *******************************
  2. *
  3. * SOURCE FILE NAME: MDM.C
  4. *
  5. * DESCRIPTIVE NAME:  OS/2 2.x Media Device Manager Proxy DLL Source.
  6. *
  7. *              DISCLAIMER OF WARRANTIES.  The following [enclosed] code is
  8. *              sample code created by IBM Corporation. This sample code is not
  9. *              part of any standard or IBM product and is provided to you solely
  10. *              for  the purpose of assisting you in the development of your
  11. *              applications.  The code is provided "AS IS", without
  12. *              warranty of any kind.  IBM shall not be liable for any damages
  13. *              arising out of your use of the sample code, even if they have been
  14. *              advised of the possibility of   such damages.
  15. *
  16. * FUNCTION:    The Source defines stub or proxy routines for three OS/2
  17. *              APIs namely mciSendCommand(),mciSendString(), and
  18. *              mdmDriverNotify(). The True Worker routines for these APIs
  19. *              reside in MDM.DLL (Already provided by the system). When
  20. *              this source is built another MDM.DLL is created, which
  21. *              has forwarding entries to the System provided MDM.DLL.
  22. *              Note that the above three APIs are not only exported here
  23. *              but are also imported from the true MDM.DLL.
  24. *
  25. * INSTALLATION:
  26. *              In order to begin monitoring MCI messages the existing
  27. *              MDM.DLL must be renamed to MCI.DLL. To do this use a tool
  28. *              called DLLRNAME. DLLRNAME is provided as part of IBM
  29. *              CSET/2 compiler. ex DLLRNAME d:\mmos2\dll\mdm.dll mdm=mci
  30. *              is the command you would actually type if the true MDM.DLL
  31. *              resides on drive D:.
  32. *              Then Copy the stub MDM.DLL (this source product) to d:\toolkt
  33. *              \DLL\MDM.DLL.
  34. *              If MDM.DLL cannot be renamed or replaced then the DLL may be
  35. *              in use because of system sounds. Temporarily Deinstall System
  36. *              sounds by running \mmos2\install\DINSTSND.CMD. Yoy may have
  37. *              to reboot after this. After the reboot you can replace the
  38. *              MDM.DLL.
  39. *
  40. *
  41. * NOTES:       Linker Warnnings of imported export records can be ignored.
  42. *              Save a copy of your MDM.DLL before you begin the replacement.
  43. *
  44. *********************** END OF SPECIFICATIONS ********************************/
  45. #define INCL_BASE                      /* OS/2 Base definitions           */
  46. #define INCL_DOS                       /* DosCall Definitions include     */
  47. #define INCL_WIN                       /* PM      Definitions include     */
  48. #include <os2.h>                       /* OS/2 2.x System include         */
  49. #include <string.h>                    /* C String Functions include      */
  50. #include <stdio.h>                     /* C Standard Functions include    */
  51. #include <stdlib.h>                    /* C Thread Functions include      */
  52. #include <process.h>                   /* C Thread Functions include      */
  53. #include <os2me.h>                     /* Multimedia System include       */
  54. #include "mdm.h"                       /* Component Private Definitions   */
  55.  
  56. THREAD_BLOCK      *pThreadBlk;      /* A thread Parameter block struct   */
  57. PIB               *PIDInfo;         /* Process Information Block         */
  58. TIB               *TIDInfo;         /* Thread Information Block          */
  59.  
  60. #pragma data_seg(SHR_SEG)
  61. HAB               hab=0;            /* Handle to an anchor block (thrd)  */
  62. HWND              hwndSpyWin;       /* Spy Application Window Handle     */
  63. OPEN_LIST         OpenList;         /* Device Ids of open list           */
  64. DRIVERENTRY       mdmSendCmd;       /* SendCommand Address in true MDM   */
  65. SENDSTR           mdmSendStr;       /* SendString Address in true MDM    */
  66. HMTX              hmtxProcSem;      /* Thread Block Serialization Sem.   */
  67. PVOID             pvNotPacket;      /* Shared Memory Packet              */
  68. BOOL              fGlobalInit = FALSE; /* Initialization Flag       */
  69. BOOL              fSpyRegistered = FALSE; /* Spy Application Registered State  */
  70. BOOL              fHookInp = FALSE;       /* Spy Application Registered State  */
  71. BOOL              fSpySysSounds = FALSE; /* Spy Application Registered State  */
  72. ULONG             ulCount = 0;             /* Number of Attachments   */
  73. ULONG             ulSysSndPID = 0;         /* Number of Attachments   */
  74.  
  75.  
  76. /****************************START OF SPECIFICATIONS *************************
  77. *
  78. * FUNCTION:    mciSendCommand() API Intercept Routine
  79. *
  80. * ARGUMENTS:
  81. *
  82. * RETURN:
  83. *
  84. * DESCRIPTION: Proxy For mciSendCommand. Worker is in MCI.DLL
  85. *
  86. *
  87. * OS/2 API's USED:  mciSendCommand() MMPM/2 Command Interface API
  88. **************************************************************************/
  89. ULONG APIENTRY mciSendCommand  (USHORT   wDeviceID,
  90.                                 USHORT   wMessage,
  91.                                 ULONG    dwParam1,
  92.                                 PVOID    dwParam2,
  93.                                 USHORT   wUserParm)
  94.  
  95. {
  96.   ULONG    rc = 0;                     /* API Return Code */
  97.   USHORT   i;                          /* Counter         */
  98.   ULONG    ulPostCount;
  99.  
  100.   /* At application initilization time (MCISPY.EXE) registers
  101.   ** itself by calling the Exported API RegisterSpy, and passing
  102.   ** the PM Window Handle for Notifications. The Stub DLL stores
  103.   ** the Window handle and sets an intertnal flag to indicate
  104.   ** the successful registration.
  105.   */
  106.  
  107.   if (fSpyRegistered)
  108.    {
  109.       /* Grab the Serialization Semaphore */
  110.  
  111.       DosRequestMutexSem(hmtxProcSem, SEM_INDEFINITE_WAIT);
  112.  
  113.       /* Fill up the thread block parameters in Shared memory */
  114.  
  115.       pThreadBlk->wDevID = wDeviceID;
  116.       pThreadBlk->wMsg =   wMessage;
  117.       pThreadBlk->dwParam1 =dwParam1;
  118.       pThreadBlk->dwParam2 =(ULONG)dwParam2;
  119.       pThreadBlk->wUserParm =wUserParm;
  120.  
  121.      /* Update Process Information */
  122.       DosGetInfoBlocks(&(TIDInfo), &(PIDInfo));
  123.       pThreadBlk->ulPID = PIDInfo->pib_ulpid;
  124.  
  125.       if (pThreadBlk->ulPID != ulSysSndPID)
  126.        {
  127.          /* Send the Message to the MCISPY application */
  128.          WinSendMsg (hwndSpyWin,WM_COMMAND,
  129.                      MPFROM2SHORT (SPY_NOTIFY,pThreadBlk->wMsg),(MPARAM) 0) ;
  130.        }
  131.       else
  132.        {
  133.          DosPostEventSem (pThreadBlk->SysSndsEvtSem);
  134.          DosWaitEventSem (pThreadBlk->SysSndsSyncSem, SEM_INDEFINITE_WAIT);      /* Set Thread Sem */
  135.          DosResetEventSem (pThreadBlk->SysSndsSyncSem, &ulPostCount);
  136.        }
  137.       /* Release The Serialization Semaphore    */
  138.  
  139.       DosReleaseMutexSem(hmtxProcSem);
  140.    }
  141.  
  142.    /* Forward the Call to the true Worker in MCI.DLL */
  143.  
  144.    if (!rc)
  145.     {
  146.        rc = mdmSendCmd (wDeviceID,wMessage,dwParam1,dwParam2,wUserParm);
  147.     }
  148.  
  149.     /*
  150.     ** In order to provide useful application options like instance
  151.     ** based filtering of MCI messages, MCI_OPEN and MCI_CLOSE messages
  152.     ** are counted.
  153.     ** CAVEATS. Automatic Identification of devices, Element Opens are
  154.     **          Ignored.
  155.     */
  156.  
  157.    if (! LOUSHORT(rc) && (wMessage == MCI_OPEN))
  158.     {
  159.        MCI_OPEN_PARMS  *pOpenParms;
  160.  
  161.        DosRequestMutexSem(hmtxProcSem, SEM_INDEFINITE_WAIT);
  162.        pOpenParms = (MCI_OPEN_PARMS *)dwParam2;
  163.        if (dwParam1 & MCI_OPEN_TYPE_ID)
  164.         {
  165.           /* Store the Device Type  */
  166.           OpenList.ulOpenList[OpenList.ulNumOpen].usDevTyp = LOUSHORT(pOpenParms->pszDeviceType);
  167.         }
  168.        /* Store the PID, Device ID */
  169.  
  170.        /* Update Process Information */
  171.        DosGetInfoBlocks(&(TIDInfo), &(PIDInfo));
  172.        OpenList.ulOpenList[OpenList.ulNumOpen].ulDevId = pOpenParms->usDeviceID;
  173.        OpenList.ulOpenList[OpenList.ulNumOpen].ulPID = PIDInfo->pib_ulpid;
  174.        OpenList.ulNumOpen++;
  175.        DosReleaseMutexSem(hmtxProcSem);
  176.     }
  177.    if (! LOUSHORT(rc) && (wMessage == MCI_CLOSE))
  178.     {
  179.        DosRequestMutexSem(hmtxProcSem, SEM_INDEFINITE_WAIT);
  180.        for (i=0; i < OpenList.ulNumOpen; i++)
  181.         {
  182.          if (OpenList.ulOpenList[i].ulDevId == wDeviceID)
  183.           {
  184.              OpenList.ulOpenList[i].ulDevId = 0;
  185.              OpenList.ulOpenList[i].fExclude = FALSE;
  186.              break;
  187.           }
  188.         }
  189.         OpenList.ulNumOpen--;
  190.        DosReleaseMutexSem(hmtxProcSem);
  191.     }
  192.     if (fSpyRegistered && (LOUSHORT(rc) != MCIERR_SUCCESS))
  193.      {
  194.         DosRequestMutexSem(hmtxProcSem, SEM_INDEFINITE_WAIT);
  195.         pThreadBlk->ulReturnCode = rc;
  196.         WinSendMsg (hwndSpyWin,WM_COMMAND,MPFROM2SHORT (SPY_ERRRC,pThreadBlk->wMsg),
  197.                     (MPARAM) 0) ;
  198.         DosReleaseMutexSem(hmtxProcSem);
  199.      }
  200.  
  201.    return (rc);
  202. }
  203.  
  204.  
  205. /****************************START OF SPECIFICATIONS *************************
  206. *
  207. * FUNCTION:    mciSendString
  208. *
  209. * ARGUMENTS: Published API Arguments
  210. *
  211. * RETURN:
  212. *
  213. * DESCRIPTION: Proxy for mciSendString(). Worker is in MCI.DLL
  214. *              .
  215. *
  216. * OS/2 API's USED:  mciSendString() MMPM/2 Command Interface API
  217. *
  218. **************************************************************************/
  219. ULONG APIENTRY  mciSendString   (PSZ     lpstrCommandBuf,
  220.                                  PSZ     lpstrReturnString,
  221.                                  USHORT  wReturnLength,
  222.                                  HWND    hCallBack,
  223.                                  USHORT  wUserParm )
  224.  
  225. {
  226.  
  227.   ULONG    rc = 0;                      /* API return Code      */
  228.   SZ       szTemp[2048];                /* Temporary Buffer     */
  229.   PCHAR    pchWord;                     /* Tokenized Word Ptr   */
  230.   PCHAR    pchDevType;                  /* Device Type          */
  231.   char     tokensep[] = " \t,\n";       /* Token Seperators     */
  232.   PCHAR    pchAlias;                    /* PCH Alias            */
  233.   USHORT   i;                           /* Loop Index           */
  234.  
  235.   /* Grab The Serialization Semaphore  */
  236.  
  237.   DosRequestMutexSem(hmtxProcSem, SEM_INDEFINITE_WAIT);
  238.  
  239.   /* Copy the InComing String Command for later use */
  240.  
  241.   strcpy (szTemp,(char *)lpstrCommandBuf);
  242.  
  243.   /* Release the Serialization Semaphore */
  244.  
  245.   DosReleaseMutexSem(hmtxProcSem);
  246.  
  247.   if (fSpyRegistered)
  248.    {
  249.  
  250.       DosRequestMutexSem(hmtxProcSem, SEM_INDEFINITE_WAIT);
  251.       pThreadBlk->wUserParm = wUserParm;
  252.  
  253.      /* Update Process Information */
  254.       DosGetInfoBlocks(&(TIDInfo), &(PIDInfo));
  255.       pThreadBlk->ulPID = PIDInfo->pib_ulpid;
  256.  
  257.       strcpy (pThreadBlk->szCmd,(char *)lpstrCommandBuf);
  258.  
  259.       /* Send the Message to the MCISPY application */
  260.  
  261.       WinSendMsg (hwndSpyWin,WM_COMMAND,MPFROM2SHORT (SPY_STRING,0),
  262.                   (MPARAM) 0) ;
  263.  
  264.       DosReleaseMutexSem(hmtxProcSem);
  265.    }
  266.  
  267.   /*
  268.   ** Forward the call to the true API worker in MCI.DLL
  269.   */
  270.   if(!rc)
  271.      rc = mdmSendStr (lpstrCommandBuf,lpstrReturnString,wReturnLength,
  272.                       hCallBack,wUserParm );
  273.  
  274.   if (!LOUSHORT(rc))
  275.    {
  276.       DosRequestMutexSem(hmtxProcSem, SEM_INDEFINITE_WAIT);
  277.  
  278.       /* Get The First token in the command string */
  279.       pchWord = strtok (szTemp,tokensep);
  280.  
  281.       if (strcmpi (pchWord,"open") == 0)
  282.       {
  283.          /* Next Token is the device type */
  284.  
  285.          /* CAVEATS: Element opens will be ignored and the filter will not
  286.          ** Work.
  287.          */
  288.          pchDevType = strtok(NULL,tokensep);
  289.  
  290.          while ((pchWord = strtok(NULL,tokensep)) != NULL)
  291.            {
  292.              if (strcmpi (pchWord,"alias") == 0)
  293.               {
  294.                 /* look ahead to get the alias */
  295.  
  296.                 pchAlias = strtok(NULL,tokensep);
  297.  
  298.                 /* Retrieve the Alias, PID and Device Type */
  299.  
  300.                 strcpy (OpenList.szAlias[OpenList.ulNumOpen].szAlias,pchAlias);
  301.                 strcpy (OpenList.szAlias[OpenList.ulNumOpen].szDevTyp,pchDevType);
  302.  
  303.                 /* Update Process Information */
  304.                 DosGetInfoBlocks(&(TIDInfo), &(PIDInfo));
  305.                 pThreadBlk->ulPID = PIDInfo->pib_ulpid;
  306.                 OpenList.szAlias[OpenList.ulNumOpen].ulPID = PIDInfo->pib_ulpid;
  307.                 OpenList.ulNumOpen++;
  308.                 break;
  309.               }
  310.            }
  311.       } /* "open" */
  312.       else if (strcmpi (pchWord,"close") == 0)
  313.       {
  314.          pchWord = strtok (NULL,tokensep);   /* This should be the alias */
  315.  
  316.          for (i=0; i < OpenList.ulNumOpen; i++)
  317.            {
  318.             if (strcmpi (pchWord,OpenList.szAlias[i].szAlias) == 0)
  319.              {
  320.                strcpy (OpenList.szAlias[i].szAlias,"");
  321.                OpenList.szAlias[i].fExclude = FALSE;
  322.                OpenList.ulNumOpen--;
  323.                break;
  324.              }
  325.            }
  326.       }/* "close" */
  327.       DosReleaseMutexSem(hmtxProcSem);
  328.    }
  329.  
  330.   if (fSpyRegistered && (LOUSHORT(rc) != MCIERR_SUCCESS))
  331.    {
  332.  
  333.       DosRequestMutexSem(hmtxProcSem, SEM_INDEFINITE_WAIT);
  334.       pThreadBlk->ulReturnCode = rc;
  335.       WinSendMsg (hwndSpyWin,WM_COMMAND,MPFROM2SHORT (SPY_ERRRC,pThreadBlk->wMsg),
  336.                   (MPARAM) 0) ;
  337.       DosReleaseMutexSem(hmtxProcSem);
  338.    }
  339.   return (rc);
  340. }
  341.  
  342.  
  343. #pragma linkage (RegisterSpy,system)
  344.  
  345. /****************************START OF SPECIFICATIONS *************************
  346. *
  347. * FUNCTION:    RegisterSpy()
  348. *
  349. * ARGUMENTS:  Window Handle and REGISTER/DEREGISTER Flag.
  350. *
  351. * RETURN:
  352. *
  353. * DESCRIPTION: Monitor System Queue to retrieve RM messages.
  354. *
  355. **************************************************************************/
  356.  
  357. APIRET APIENTRY RegisterSpy (HWND hwndspy,ULONG ulApiMode)
  358. {
  359.  
  360.   if (ulApiMode && fSpyRegistered)
  361.       return (100);
  362.  
  363.  
  364.   if (ulApiMode)
  365.    {
  366.      DosRequestMutexSem(hmtxProcSem, SEM_INDEFINITE_WAIT);
  367.      fSpyRegistered = TRUE;
  368.      hwndSpyWin = hwndspy;
  369.      DosReleaseMutexSem(hmtxProcSem);
  370.    }
  371.    else
  372.    {
  373.      /* Release Our Input hook. But the DLL Still can't be freed. See
  374.      ** PM Refererence for more details.
  375.      */
  376.      fSpyRegistered = FALSE;
  377.      hwndSpyWin = 0;
  378.    }
  379.  
  380.    return (0);
  381. }
  382.  
  383. /****************************START OF SPECIFICATIONS *************************
  384. *
  385. * FUNCTION:    QueryOpenInstance()
  386. *
  387. * ARGUMENTS: Pointer to an OPEN_LIST structure.
  388. *
  389. * RETURN:
  390. *
  391. * DESCRIPTION: Return Open Instance Info to the application.
  392. *              .
  393. *
  394. * OS/2 API's USED:
  395. *
  396. **************************************************************************/
  397.  
  398. APIRET APIENTRY QueryOpenInstance (OPEN_LIST * pulList,BOOL fAlias)
  399. {
  400.   USHORT i ;
  401.  
  402.   /* Obtain the serialization semaphore */
  403. //  DosRequestMutexSem(hmtxProcSem, SEM_INDEFINITE_WAIT);
  404.  
  405.   if (fAlias)
  406.   {
  407.      pulList->ulNumOpen =OpenList.ulNumOpen;
  408.  
  409.      for (i=0; i < MAXOPENS; i++)
  410.        {
  411.          pulList->ulOpenList[i].usDevTyp = OpenList.ulOpenList[i].usDevTyp;
  412.          pulList->ulOpenList[i].ulDevId =  OpenList.ulOpenList[i].ulDevId;
  413.          pulList->ulOpenList[i].ulPID =    OpenList.ulOpenList[i].ulPID;
  414.        }
  415.   }
  416.   else
  417.   {
  418.      pulList->ulNumOpen =OpenList.ulNumOpen;
  419.      for (i=0; i < MAXOPENS; i++)
  420.        {
  421.           strcpy (pulList->szAlias[i].szAlias,OpenList.szAlias[i].szAlias);
  422.           strcpy (pulList->szAlias[i].szDevTyp,OpenList.szAlias[i].szDevTyp);
  423.           pulList->szAlias[i].ulPID = OpenList.szAlias[i].ulPID ;
  424.        }
  425.  
  426.   }
  427.   /* Give up the Serialization Semaphore */
  428.  // DosReleaseMutexSem(hmtxProcSem);
  429.   return 0;
  430.  
  431. }
  432.  
  433. /****************************START OF SPECIFICATIONS *************************
  434. *
  435. * FUNCTION:    _DLL_InitTerm()
  436. *
  437. * ARGUMENTS: ModuleHandle, Init or Term Flag
  438. *
  439. * RETURN:
  440. *
  441. * DESCRIPTION: Initilize the DLL Global Structures appropriately.
  442. *              .
  443. *
  444. * OS/2 API's USED:
  445. *
  446. **************************************************************************/
  447.  
  448. #pragma linkage (_DLL_InitTerm,system)
  449. unsigned long _System _DLL_InitTerm (ULONG hModule,ULONG ulFlag)
  450. {
  451.   ULONG    rc = 0;                     /* API Return Code    */
  452.   SZ       LoadError[255];             /* DosLaodModule Err  */
  453.   HMODULE  ModuleHandle;               /* Module Handle      */
  454.   PFN      tProcAddr = NULL;           /* NULL PFN           */
  455.   BOOL     fSysSndsInit = FALSE;       /* System Sounds      */
  456.  
  457.   switch (ulFlag)
  458.     {
  459.      if (ulFlag == 1) return (1L);
  460.  
  461.      case 0:
  462.  
  463.       /* Initialize The C Run Time Library Functions  */
  464.  
  465.        if (_CRT_init() != 0)
  466.            return 0L;
  467.  
  468.        if (!fGlobalInit)
  469.         {
  470.            /* Create The Global Serialization Semaphore */
  471.            DosCreateMutexSem(NULL,&hmtxProcSem,DC_SEM_SHARED,FALSE);
  472.  
  473.            /* Open the Serialization Semaphore   */
  474.            DosOpenMutexSem (NULL,&hmtxProcSem);
  475.  
  476.            /* Obtain the serialization semaphore */
  477.            DosRequestMutexSem(hmtxProcSem, SEM_INDEFINITE_WAIT);
  478.  
  479.            rc = DosLoadModule(LoadError, sizeof(LoadError),"MCI",
  480.                               &ModuleHandle);
  481.  
  482.            if (rc)
  483.             {
  484.               DosBeep (500,1500);
  485.               DosExit (0,0);
  486.             }
  487.            rc = DosQueryProcAddr(ModuleHandle, 0L,"mciSendString", &(tProcAddr));
  488.  
  489.            if (rc)
  490.             {
  491.               DosBeep (500,1500);
  492.               DosExit (0,0);
  493.             }
  494.            mdmSendStr = (SENDSTR)tProcAddr;
  495.            tProcAddr = NULL;
  496.            rc = DosQueryProcAddr(ModuleHandle, 0L,"mciSendCommand", &(tProcAddr));
  497.            if (rc)
  498.             {
  499.               DosBeep (500,1500);
  500.               DosExit (0,0);
  501.             }
  502.            mdmSendCmd = (DRIVERENTRY)tProcAddr;
  503.  
  504.            rc = DosAllocSharedMem (&pvNotPacket,(PSZ)"\\SHAREMEM\\SPYPACK.DAT",
  505.                                    4096,OBJ_TILE |PAG_READ | PAG_WRITE | PAG_COMMIT );
  506.  
  507.            /*
  508.             ** If error interrupt try again
  509.             */
  510.            if (rc == (ULONG)183)
  511.             {
  512.                rc = DosAllocSharedMem (&pvNotPacket,(PSZ)"\\SHAREMEM\\SPYPACK.DAT",
  513.                                        4096,PAG_READ | PAG_WRITE);
  514.             }
  515.           fGlobalInit = TRUE;
  516.  
  517.           /* Obtain the Shared memory object */
  518.           rc = DosGetNamedSharedMem ((PPVOID)&(pThreadBlk),
  519.                                    (PSZ)"\\SHAREMEM\\SPYPACK.DAT",
  520.                                    PAG_READ | PAG_WRITE );
  521.  
  522.  
  523.           /* Update Process Information */
  524.  
  525.           DosGetInfoBlocks(&(TIDInfo), &(PIDInfo));
  526.           pThreadBlk->ulPID = PIDInfo->pib_ulpid;
  527.  
  528.           /* Save System Sounds PID Information */
  529.  
  530.           ulSysSndPID =PIDInfo->pib_ulpid;
  531.  
  532.          /* This needs to be done because of System Sounds.
  533.          ** You cannot install the hook at this DLL's initilization
  534.          ** because desktop may not be created yet.
  535.          */
  536.           DosCreateEventSem(NULL,&(pThreadBlk->SysSndsEvtSem),DC_SEM_SHARED,FALSE);
  537.           DosCreateEventSem(NULL,&(pThreadBlk->SysSndsSyncSem),DC_SEM_SHARED,FALSE);
  538.  
  539.          _beginthread(SystemSoundsThread,
  540.                      (PVOID)NULL,
  541.                      (ULONG)16000,
  542.                      (PVOID)pThreadBlk);
  543.  
  544.           fSysSndsInit = TRUE;
  545.  
  546.           /* Set up the Global System Wide Input Hook */
  547.           hab = WinInitialize(0);
  548.  
  549.           /* Resource Change messages are posted directly to the
  550.           ** Application. In order to intercept those messages we
  551.           ** register an Input hook on the system queue.
  552.           */
  553.  
  554.           WinSetHook (hab,NULLHANDLE,HK_INPUT,(PFN)InputHookProc,hModule);
  555.           fHookInp = TRUE;
  556.  
  557.          /* Give up the Serialization Semaphore */
  558.          DosReleaseMutexSem(hmtxProcSem);
  559.          }
  560.  
  561.       /* Open the Serialization Semaphore   */
  562.       DosOpenMutexSem (NULL,&hmtxProcSem);
  563.  
  564.       /* Obtain the serialization semaphore */
  565.       DosRequestMutexSem(hmtxProcSem, SEM_INDEFINITE_WAIT);
  566.  
  567.      if (!fSysSndsInit)
  568.       {
  569.          /* Obtain the Shared memory object */
  570.          rc = DosGetNamedSharedMem ((PPVOID)&(pThreadBlk),
  571.                                   (PSZ)"\\SHAREMEM\\SPYPACK.DAT",
  572.                                   PAG_READ | PAG_WRITE );
  573.  
  574.          /* Update Process Information */
  575.          DosGetInfoBlocks(&(TIDInfo), &(PIDInfo));
  576.          pThreadBlk->ulPID = PIDInfo->pib_ulpid;
  577.       }
  578.      ulCount++;
  579.      /* Give up the Serialization Semaphore */
  580.      DosReleaseMutexSem(hmtxProcSem);
  581.  
  582.     break;
  583.  
  584.      case 1:
  585.       _CRT_term();
  586.        ulCount--;
  587.       DosCloseMutexSem (hmtxProcSem);
  588.       break;
  589.     }
  590.     return 1L;
  591. }
  592.  
  593. /****************************START OF SPECIFICATIONS *************************
  594. *
  595. * FUNCTION:    InputHookProc()
  596. *
  597. * ARGUMENTS:  See Function.
  598. *
  599. * RETURN:
  600. *
  601. * DESCRIPTION: Monitor System Queue to retrieve RM messages.
  602. *
  603. **************************************************************************/
  604. BOOL APIENTRY  InputHookProc   (HAB   hab,  PQMSG pQmsg, ULONG ulfs)
  605. {
  606.  
  607.   if (fSpyRegistered)
  608.    {
  609.       if (fSpySysSounds)
  610.        {
  611.           /* Update the PID of the calling Process */
  612.           DosGetInfoBlocks(&(TIDInfo), &(PIDInfo));
  613.           pThreadBlk->ulPID = PIDInfo->pib_ulpid;
  614.           pThreadBlk->wMsg     =  (USHORT)pQmsg->msg;
  615.           pThreadBlk->dwParam1 =  (ULONG)pQmsg->mp1;
  616.           pThreadBlk->dwParam2 =  (ULONG)pQmsg->mp2;
  617.  
  618.           switch (pQmsg->msg)
  619.             {
  620.              case MM_MCIPASSDEVICE:
  621.                pThreadBlk->wDevID =    SHORT1FROMMP(pQmsg->mp1);
  622.                pThreadBlk->dwParam2 =  SHORT1FROMMP(pQmsg->mp2);
  623.               /* Send a Resource Change Message to the Application */
  624.               WinSendMsg (hwndSpyWin,WM_COMMAND,MPFROM2SHORT(SPY_DEVICE,0),
  625.                           (MPARAM)pQmsg->mp2);
  626.               break;
  627.  
  628.              case MM_MCINOTIFY:
  629.              case MM_MCICUEPOINT:
  630.              case MM_MCIPLAYLISTMESSAGE:
  631.              case MM_MCIEVENT:
  632.                pThreadBlk->wDevID =    SHORT1FROMMP(pQmsg->mp2);
  633.                pThreadBlk->wUserParm = SHORT2FROMMP(pQmsg->mp1);
  634.                pThreadBlk->dwParam1 =  SHORT1FROMMP(pQmsg->mp1);
  635.               /* Send a Resource Change Message to the Application */
  636.               WinSendMsg (hwndSpyWin,WM_COMMAND,MPFROM2SHORT(SPY_NOTIFY,(USHORT)pQmsg->msg),
  637.                           (MPARAM)pQmsg->mp2);
  638.               break;
  639.  
  640.              case MM_MCIPOSITIONCHANGE:
  641.                pThreadBlk->dwParam1 = (ULONG)pQmsg->mp2;
  642.                pThreadBlk->dwParam2 = (ULONG)pQmsg->mp2;
  643.                pThreadBlk->wUserParm = SHORT1FROMMP(pQmsg->mp1);
  644.                pThreadBlk->wDevID =    SHORT2FROMMP(pQmsg->mp1);
  645.  
  646.               /* Send a Resource Change Message to the Application */
  647.               WinSendMsg (hwndSpyWin,WM_COMMAND,MPFROM2SHORT(SPY_NOTIFY,(USHORT)pQmsg->msg),
  648.                           (MPARAM)pQmsg->mp2);
  649.               break;
  650.             }
  651.        } /* SpySystemSounds */
  652.    } /* Spy is Registered */
  653.    return (FALSE);    /* let any other hook process it */
  654. }/* Input Hook Proc */
  655.  
  656.  
  657. /*********************************************************************/
  658. /*********************************************************************/
  659. VOID _Optlink SystemSoundsThread(PVOID ptemp)
  660. {
  661.   THREAD_BLOCK        *pThreadBlock;
  662.   ULONG               ulPostCount;
  663.   HMQ                 hmq=0;
  664.   pThreadBlock = (THREAD_BLOCK *)ptemp;
  665.  
  666.   DosWaitEventSem (pThreadBlock->SysSndsEvtSem, SEM_INDEFINITE_WAIT);      /* Set Thread Sem */
  667.   if (!hmq)
  668.    {
  669.       hmq = WinCreateMsgQueue(hab, 0); /* Create a msg queue to send SystemSounds Msgs */
  670.    }
  671.   /**************************************************************************/
  672.   /* Loop and wait for work to do...                                        */
  673.   /*                                                                        */
  674.   /**************************************************************************/
  675.   /* Run this code once, then block */
  676.   while (1)
  677.     {
  678.     DosWaitEventSem (pThreadBlock->SysSndsEvtSem, SEM_INDEFINITE_WAIT);      /* Set Thread Sem */
  679.     DosResetEventSem (pThreadBlock->SysSndsEvtSem, &ulPostCount);
  680.     WinSendMsg (hwndSpyWin,WM_COMMAND,MPFROM2SHORT (SPY_NOTIFY,pThreadBlock->wMsg),
  681.                 (MPARAM) 0) ;
  682.     DosPostEventSem (pThreadBlock->SysSndsSyncSem);
  683.     }
  684.  
  685. }
  686.  
  687.  
  688. /****************************START OF SPECIFICATIONS *************************
  689. *
  690. * FUNCTION:    SpySystemSounds()
  691. *
  692. * ARGUMENTS: Toggle Flag to Enable/Disable System Sounds Monitor.
  693. *
  694. * RETURN:
  695. *
  696. * DESCRIPTION: Toggle Monitoring System Sounds.
  697. *              .
  698. **************************************************************************/
  699.  
  700. APIRET APIENTRY SpySystemSounds (BOOL fAlias)
  701. {
  702.   if (fAlias)
  703.   {
  704.     fSpySysSounds = TRUE;
  705.   }
  706.   else
  707.   {
  708.     fSpySysSounds = FALSE;
  709.   }
  710.   return 0;
  711. }
  712.  
  713.  
  714.