Announcement

Collapse
No announcement yet.

CallNextHookEx under 9x

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • CallNextHookEx under 9x

    I encounted one strange moment with CallNextHookEx under 9x
    (see Source code forum).
    Under NT if to start some keyboard hooks all works fine and all DLL work together (to do this it's necessary to make additional Spy Exe & DLL and to change DLL-name Hook.dll to Hook1.Dll + C:\HookWnd.Id to C:\HookWnd1.Id).
    But under 9x result of CallNextHookEx for normal codes (ncode >=0) is GPF.
    Perhaps, there are some additional rules/restrictions for global hooks under 9x.
    Does anybody knows about it ? (I don't see warnings in MSDN)

  • #2
    Semen --

    According to MSDN Knowledge Base articles Q179905 and Q125677, the hook handle needs to be shared among all of the instances of the DLL, i.e. you will need to use something like a memory-mapped file so that all of the instances of the DLL use the same hook handle. (And since you'll have to do that, you could use the same mechanism to get rid of the HookWnd.ID file.)

    Also, the Win32.HLP example (Monitoring System Events) shows that if the nCode value is less than zero it must be passed directly to CallNextHookEx, so your code should do that too.

    --Eric



    ------------------
    Perfect Sync: Perfect Sync Development Tools
    Email: mailto:[email protected][email protected]</A>

    "Not my circus, not my monkeys."

    Comment


    • #3
      I now see that you have modified your original code to handle nCode < 0. It can make it difficult to follow a discussion like this when you alter a message without noting the things that have been changed.

      --Eric

      ------------------
      Perfect Sync: Perfect Sync Development Tools
      Email: mailto:[email protected][email protected]</A>



      [This message has been edited by Eric Pearson (edited May 08, 2000).]
      "Not my circus, not my monkeys."

      Comment


      • #4
        Eric --
        I changed If ncode < 0 before posting this message and in any case from the begining I transfered all messages, w/o exclusion.

        After your message I decided to test under Win98 and encounted, that even if to delete all in HookProc and to leave Function = CallNextHookEx only, it will be GPF.
        If ncode < 0 - in this part all works correctly.

        Exactly this (problems in DUMMY proc) surprises me.
        I know, what happends - recycling -- but do not understand, what's wrong. (and why there are no problems under NT)
        Dummy DLL
        Code:
           #Compile Dll "Hook.Dll"
           #Register None
           #Dim All
           #Include "Win32Api.Inc"
        
           Global hHook As Long
           Function LibMain(ByVal hInstance As Long, ByVal fwdReason As Long, _
              ByVal lpvReserved As Long) Export As Long
              Static hInstDLL As Long
              Select Case fwdReason
                 Case %DLL_PROCESS_ATTACH
                    hInstDLL = hInstance
                    hHook = SetWindowsHookEx (%WH_KEYBOARD, _
                       CodePtr(HookProc), ByVal hInstance, ByVal 0)
                    LibMain = 1
                 Case %DLL_PROCESS_DETACH
                    UnhookWindowsHookEx hHook
                    LibMain = 1
              End Select
           End Function
        
           Function HookProc(ByVal nCode As Long, ByVal wParam As Long, ByVal lParam As Long) Export As Long
              If nCode < 0 Then ' Process is not allowed
                 Function = CallNextHookEx(hHook, nCode, wParam, ByVal lParam) ' because declared as Any
              Else
                 Beep
                 Function = CallNextHookEx(hHook, nCode, wParam, ByVal lParam)
              End If
           End Function
        
           Function SetHookKbdWindow Alias "SetHookKbdWindow" (hWnd As Long) Export As Long
           End Function

        [This message has been edited by Semen Matusovski (edited May 08, 2000).]

        Comment


        • #5
          Semen --

          > I changed If ncode < 0 before posting this message
          > and in any case from the begining I transfered all
          > messages, w/o exclusion.

          I understand that. All I am saying is that when you go back and edit your messages as frequently as you do, it can be very difficult to follow the discussion. In fact, you added a great deal to your most recent message in just the time it took me to compose this! In a "discussion" thread it would be much better (IMO) if you at least added a short message to the end of the thread, stating "I have modified my original code to include several changes". When you edit a message, the "new" icon is not displayed so unless the reader checks carefully, it is easy to miss that something has been changed.

          Back to the real issues...

          If I am reading the MSDN docs correctly, I suspect that your calls to CallNextHookEx are failing on NT systems. We know that they are failing on 98 systems because of the GPF, but because CallNextHookEx does not update GetLastError, the only way to find out whether or not the function is actually working on NT systems (as opposed to simply not generating a GPF) would be to install multiple keyboard hooks and perform some experiments.

          As I said, the hook handle needs to be shared among all instances of the DLL. Just making it a GLOBAL variable is not sufficient.

          I am also skeptical about the practice of setting the hook in the %DLL_PROCESS_ATTACH code. If you add a BEEP to that CASE you will see that a new instance of your DLL is being loaded every time you click on a different application. In other words, whenever a new application -- any application -- is given the foreground and begins processing keystrokes, the operating system loads a new instance of your hook DLL. So I am pretty sure that your code actually creates a new system hook for every app, instead of sharing one hook with all processes. You are not really creating a system-wide hook, you are creating a one-process hook for every application. I believe that you would need to test for an existing hook handle (i.e. test the value of the hook handle variable that is shared between the DLL instances) and only set the hook if the value is zero.

          -- Eric


          ------------------
          Perfect Sync: Perfect Sync Development Tools
          Email: mailto:[email protected][email protected]</A>

          "Not my circus, not my monkeys."

          Comment


          • #6
            Eric --
            CallNextHookEx works under NT - I made a copy of SPY DLL and received messages in both hooks.

            About place ...
            I reconstructed a code, and it seems to me that it works without GPF.
            I need additional tests and then re-post on Source Code forum.

            [This message has been edited by Semen Matusovski (edited May 08, 2000).]

            Comment


            • #7
              > CallNextHookEx works under NT - I made a copy of
              > SPY DLL and received messages in both hooks.

              That's interesting. I read some newsgroup messages about NULL working for the first parameter of CallNextHookEx on NT systems. Maybe NT simply ignores the first parameter? That would explain a lot.

              In any event, to answer your question...

              I believe that you need to create a single hook and share its handle via an IPC mechanism such as a memory-mapped file. (Did you read the KB articles I mentioned above?) You could use a disk file (as you did in your original code) to communicate between instances, but it would be very error-prone. And every time an application got the foreground and needed to link you your DLL, it would take some time for the DLL to read the file, so using a file would slow things down quite a bit. (By the way, don't you need to delete those files at some point, so when you run the program at a later date they won't fool the program?)

              -- Eric


              ------------------
              Perfect Sync: Perfect Sync Development Tools
              Email: mailto:[email protected][email protected]</A>

              "Not my circus, not my monkeys."

              Comment


              • #8
                Eric --
                I changed sample #1 on Source code forum.
                If it's interesting for you, you can test.
                It works under 95b.
                Hope (but should to test) that under NT also.
                Just now I want to reconstruct by the same way sample #2 w/o exiting to NT.

                ------------------

                Comment


                • #9
                  Semen, you did it again! You completely changed your message (7:47am) in the time it took me to compose my last response! Please pardon my criticism, but it seems to me that you are posting your messages before you are really ready to do so! If you want to have a coherent "dialog" using this BBS, it simply won't work if you keep doing that!

                  > I need additional tests and then re-post on Source Code forum.

                  IMO it would be much more appropriate to post it here, for other people to test. The Source Code forum is supposed to be for "finished" code.

                  -- Eric


                  [This message has been edited by Eric Pearson (edited May 08, 2000).]
                  "Not my circus, not my monkeys."

                  Comment


                  • #10
                    Eric --
                    I'm sorry, but I can't do nothing with myself. (it's 100% true)
                    At first I write, then I look, what I wrote and correct.
                    So, it's better to wait 5 minutes after appearence on BBS.

                    ------------------

                    Comment


                    • #11
                      Semen --

                      With all due respect, the problem is not limited to a five minute window. For the benefit of lurkers, I am not talking about the correction of typos, my objection was to a complete change of content.

                      If you want people to help you, you should not make it difficult to do so by making rules like "don't respond to my messages unless they are a certain age". Please consider editing your message offline and posting them when they are truly ready. And please do not significantly edit messages that people have already responded to. It makes the respondent look like they did not read your message carefully.

                      I will not comment further about this, I will simply stop responding to messages where it takes place.

                      -- Eric


                      ------------------
                      Perfect Sync: Perfect Sync Development Tools
                      Email: mailto:[email protected][email protected]</A>

                      "Not my circus, not my monkeys."

                      Comment

                      Working...
                      X