home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / MJHKGEN.LZH / MJHKGEN.C next >
Text File  |  1991-05-05  |  12KB  |  276 lines

  1. /***************************************************************************/
  2. /*                                                                         */
  3. /* PROGRAM NAME: MJHKGEN - Generic System Input Queue Hook                 */
  4. /* -------------                                                           */
  5. /*  Allow a Generic Hook to be installed.  This program accepts three      */
  6. /*  parameters: 1) Key To Intercept (only will intercept F1 through F9),   */
  7. /*              2) Command To Execute,                                     */
  8. /*              3) Argument String to pass to the Command To Execute.      */
  9. /*  The parameters are then put in a shared memory segment for access by   */
  10. /*  the MJHKGENP.DLL hook procedure "GenericHookProc".  If the hook is     */
  11. /*  "set" and the Key To Intercept is pressed then GenericHookProc will    */
  12. /*  execute the Command To Execute via DosExecPgm passing the Argument     */
  13. /*  String as parameters.                                                  */
  14. /*                                                                         */
  15. /* IN ORDER TO BE ABLE TO READ ALL THE COMMENTS IN THIS                    */
  16. /* PROGRAM, READ THE SOURCE FILES INCLUDED SEPARATELY.                     */
  17. /*                                                                         */
  18. /* AUTHOR:  Michael R. Jones (Fidonet Net Mail address 1:202/204)          */
  19. /* -------                                                                 */
  20. /*                                                                         */
  21. /* LOG:  04/29/91 Program Creation                                         */
  22. /* ----                                                                    */
  23. /*                                                                         */
  24. /* RESTRICTIONS:  None.  This program is Public Domain.  Please note that  */
  25. /* -------------         this program is not complete.  It was written as  */
  26. /*                       a sample System Queue Input Hook for the IdleNews */
  27. /*                       Newsletter. It works but isn't production ready.  */
  28. /***************************************************************************/
  29.  
  30. #define INCL_DOS
  31. #define INCL_ERRORS
  32. #define INCL_PM
  33. #include <os2.h>
  34.  
  35. #include <stdio.h>
  36. #include <string.h>
  37.  
  38. #include "mjhkgen.h"
  39.  
  40. HAB              hab;
  41. HMODULE          hmodule = (HMODULE)NULL;
  42. PFN              pfnInputHook;
  43. SEL              selSharedMJHKGEN = (SEL)NULL;
  44.  
  45. MRESULT EXPENTRY GenericHookWndProc( HWND, USHORT, MPARAM, MPARAM );
  46. VOID APIENTRY ProgramTermination( VOID );
  47.  
  48. VOID cdecl main( argc, argv, envp )
  49. int       argc;
  50. char      **argv;
  51. char      **envp;
  52.   {
  53.   HMQ              hmq;
  54.   HPOINTER         hptrIcon;
  55.   HWND             hwndDlg;
  56.   PBYTE            pbyte;
  57.   PSZ              pszPeriod;
  58.   QMSG             qmsg;
  59.   USHORT           usBaseErrorCode;          /* Base (DOS) error code.     */
  60.   USHORT           usArgSize[4];
  61.  
  62.   if( argc < 3 ) return;       /* At least the first 2 arguments are req'd */
  63.  
  64.   pszPeriod = strstr( argv[2], "." );     /* Find the period in executable */
  65.  
  66.   usArgSize[0]   = strlen( argv[1] ) + 1;    /* Get the sizes of all the   */
  67.   usArgSize[1]   = strlen( argv[2] ) + 1;    /* arguments including an     */
  68.   if( pszPeriod == (PSZ)NULL )               /* argument constructed here  */
  69.     usArgSize[2] = usArgSize[1];             /* representing the simple    */
  70.   else                                       /* command name per CMD.EXE   */
  71.     usArgSize[2] = pszPeriod - argv[2] + 1;  /* conventions.  The total of */
  72.   if( argc > 3 )                             /* the sizes becomes the size */
  73.     usArgSize[3] = strlen( argv[3] ) + 1;    /* of the shared memory       */
  74.   else                                       /* allocated.                 */
  75.     usArgSize[3] = 1;
  76.  
  77.   usBaseErrorCode
  78.     = DosAllocShrSeg( usArgSize[0]           /* Include room for an extra  */
  79.                         + usArgSize[1]       /* NULL which terminates the  */
  80.                         + usArgSize[2]       /* argument block used by     */
  81.                         + usArgSize[3]       /* DosExecPgm in the hook     */
  82.                         + 1,                 /* procedure.                 */
  83.                       "\\SHAREMEM\\MJHKGEN", /* Shared Memory Name         */
  84.                       &selSharedMJHKGEN );   /* Selector for shared memory */
  85.  
  86.   if( usBaseErrorCode                        /* Only allow one copy of     */
  87.        == ERROR_ALREADY_EXISTS ) return;     /* this program to run.       */
  88.  
  89.   strcpy( MAKEP(selSharedMJHKGEN, 0),        /* Load F1 through F9 argument*/
  90.           argv[1] );
  91.  
  92.   strcpy( MAKEP(selSharedMJHKGEN,            /* Load Command To Execute    */
  93.                 usArgSize[0]),
  94.           argv[2] );
  95.  
  96.   memcpy( MAKEP(selSharedMJHKGEN,            /* Load Simple Command Name   */
  97.                 usArgSize[0] + usArgSize[1]),
  98.           argv[2],
  99.           usArgSize[2] - 1 );
  100.  
  101.   pbyte = MAKEP(selSharedMJHKGEN,            /* Add trailing NULL          */
  102.                 usArgSize[0]
  103.                  + usArgSize[1]
  104.                  + usArgSize[2]
  105.                  - 1);
  106.   *pbyte = NULL;
  107.  
  108.   if( argc > 3 )                             /* Load Argument String       */
  109.     strcpy( MAKEP(selSharedMJHKGEN,
  110.                   usArgSize[0]
  111.                    + usArgSize[1]
  112.                    + usArgSize[2]),
  113.             argv[3] );
  114.   else
  115.     {
  116.     pbyte = MAKEP(selSharedMJHKGEN,          /* Load NULL for Arg. String  */
  117.                   usArgSize[0]
  118.                    + usArgSize[1]
  119.                    + usArgSize[2]);
  120.     *pbyte = NULL;
  121.     }
  122.  
  123.   pbyte = MAKEP(selSharedMJHKGEN,            /* End Argument Block w/ NULL */
  124.                 usArgSize[0]
  125.                  + usArgSize[1]
  126.                  + usArgSize[2]
  127.                  + usArgSize[3]);
  128.   *pbyte = NULL;
  129.  
  130.   hab = WinInitialize( NULL );
  131.   hmq = WinCreateMsgQueue( hab, 0 );
  132.  
  133.   DosExitList( EXLST_ADD | 0xFF00,           /* Ensure proper pgm. ending  */
  134.                (PFNEXITLIST)ProgramTermination );
  135.  
  136.   DosLoadModule( NULL,                       /* Load the DLL module        */
  137.                  0,                          /* containing the Hook        */
  138.                  "MJHKGENP",                 /* procedure (must use a DLL).*/
  139.                  &hmodule );                 /* Get module handle          */
  140.  
  141.   DosGetProcAddr( hmodule,                   /* Get address of Hook Proc.  */
  142.                   "GENERICHOOKPROC",         /* for the WinSetHook and     */
  143.                   &pfnInputHook );           /* WinReleaseHook calls.      */
  144.  
  145.   WinSetHook( hab,                           /* Anchor block handle        */
  146.               (HMQ)NULL,                     /* NULL means hook all PM apps*/
  147.               HK_INPUT,                      /* Type of hook: Input Queue. */
  148.               pfnInputHook,                  /* Address of hook procedure. */
  149.               hmodule );                     /* DLL module handle.         */
  150.  
  151.   WinRegisterClass( hab,
  152.                     CLIENTCLASS,
  153.                     GenericHookWndProc,
  154.                     (ULONG)0,                /* No class styles needed     */
  155.                     (USHORT)0 );             /* No window words needed     */
  156.  
  157.   hwndDlg = WinLoadDlg( HWND_DESKTOP,        /* Load the dialog window     */
  158.                         HWND_DESKTOP,        /* which allows turning the   */
  159.                         NULL,                /* hook on and off.  This     */
  160.                         NULL,                /* window also provides a     */
  161.                         ID_MJHKGENDLG,       /* visual notification that a */
  162.                         NULL );              /* hook may be active (if set)*/
  163.  
  164.   hptrIcon = WinQuerySysPointer( HWND_DESKTOP, 
  165.                                  SPTR_APPICON,  /* Get standard icon       */
  166.                                  FALSE );       /* No icon copy needed     */
  167.  
  168.   WinSendMsg( hwndDlg,                       /* Attach the icon to the     */
  169.               WM_SETICON,                    /* frame window.              */
  170.               (MPARAM)hptrIcon,
  171.               (MPARAM)NULL );
  172.  
  173.   while( WinGetMsg( hab, &qmsg, (HWND)NULL, 0, 0 ) )
  174.     WinDispatchMsg( hab, &qmsg );
  175.  
  176.   WinReleaseHook( hab,                       /* Make sure hook is released */
  177.                   (HMQ)NULL,
  178.                   HK_INPUT,
  179.                   pfnInputHook,
  180.                   hmodule );
  181.  
  182.   WinDestroyWindow( hwndDlg );
  183.  
  184.   WinDestroyMsgQueue( hmq );
  185.  
  186.   WinTerminate( hab );
  187.  
  188.   return;
  189.   }
  190.  
  191.  
  192. /***************************************************************************|
  193. | Generic Hook Window Procedure                                             |
  194. |***************************************************************************/
  195.  
  196. MRESULT EXPENTRY GenericHookWndProc( hwnd, msg, mp1, mp2 )
  197. HWND         hwnd;
  198. USHORT       msg;
  199. MPARAM       mp1;
  200. MPARAM       mp2;
  201.   {
  202.   HWND             hwndCheckBox;
  203.   HWND             hwndFrame;
  204.   USHORT           usCheckedState;
  205.  
  206.   switch(msg)
  207.     {
  208.  
  209.     case WM_CONTROL:
  210.       if(    (SHORT1FROMMP(mp1) != ID_MJHKGENCB)  /* Only care about CLICK */
  211.           || (SHORT2FROMMP(mp1) != BN_CLICKED) )  /* Check Box messages.   */
  212.         break;
  213.       usCheckedState                               /* Query if check box is*/
  214.         = SHORT1FROMMR( WinSendMsg( hwndCheckBox,  /* set or not after     */
  215.                                     BM_QUERYCHECK, /* activity in the check*/
  216.                                     (MPARAM)NULL,  /* box.                 */
  217.                                     (MPARAM)NULL ) );
  218.       if( usCheckedState == 1 )
  219.         WinSetHook( hab,                   /* Check box is checked so make */
  220.                     (HMQ)NULL,             /* sure hook is "set" to capture*/
  221.                     HK_INPUT,              /* input messages for filtering.*/
  222.                     pfnInputHook,
  223.                     hmodule );
  224.       else
  225.         WinReleaseHook( hab,               /* Check box is not checked so  */
  226.                         (HMQ)NULL,         /* make sure hook is not "set"  */
  227.                         HK_INPUT,          /* so input messages are not    */
  228.                         pfnInputHook,      /* intercepted by the hook      */
  229.                         hmodule );         /* procedure.                   */
  230.       break;
  231.  
  232.     case WM_ERASEBACKGROUND:
  233.       return( (MRESULT)TRUE );
  234.  
  235.     case WM_INITDLG:
  236.       hwndFrame = WinQueryWindow( hwnd,       /* Get dialog frame handle   */
  237.                                   QW_PARENT,
  238.                                   FALSE );
  239.  
  240.       WinSetWindowText( hwndFrame,            /* Set title bar text        */
  241.                         "Generic Hook" );
  242.  
  243.       hwndCheckBox
  244.         = WinWindowFromID( hwnd,              /* Get Check Box handle      */
  245.                            ID_MJHKGENCB );
  246.  
  247.       WinSendMsg( hwndCheckBox,               /* Set initial state of the  */
  248.                   BM_SETCHECK,                /* check box to be "checked".*/
  249.                   MPFROMSHORT(1),
  250.                   (MPARAM)NULL );
  251.       break;
  252.  
  253.     }
  254.  
  255.   return( WinDefWindowProc( hwnd, msg, mp1, mp2 ) );
  256.   }
  257.  
  258.  
  259. /***************************************************************************|
  260. | Exit List processing at program termination                               |
  261. |***************************************************************************/
  262.  
  263. VOID APIENTRY ProgramTermination( )
  264.   {
  265.  
  266.   if( hmodule != (HMODULE)NULL )       /* Unfortunately does not free the  */
  267.     DosFreeModule( hmodule );          /* DLL because System Input Queue   */
  268.                                        /* hooks cannot be freed.           */
  269.  
  270.   if( selSharedMJHKGEN != (SEL)NULL )  /* Free shared memory segment.      */
  271.     DosFreeSeg( selSharedMJHKGEN );    /* At least this works!             */
  272.  
  273.   DosExitList( EXLST_EXIT,             /* Required to end ExitList process.*/
  274.                (PFNEXITLIST)ProgramTermination );
  275.   }
  276.