PRB: JournalPlayback Hook Can Cause Windows NT to Hang
ID: Q124835
|
The information in this article applies to:
-
Microsoft Win32 Application Programming Interface (API), included with:
-
Microsoft Windows NT, versions 3.1, 3.5
SYMPTOMS
Incorrect use of the delay return value from a journal playback hook can
cause Windows NT to hang temporarily.
CAUSE
The menu loop in Windows NT calls PeekMessage() with the PM_NOREMOVE flag,
does some processing, and then removes the message from the queue. This
sequence is repeated until the menu goes away. When JournalPlayback is
occurring, the PeekMessage( PM_NOREMOVE ) results in a callback to the
application's JournalPlaybackProc with an HC_ACTION code. The subsequent
PeekMessage( PM_REMOVE ) also calls the JournalPlaybackProc with an
HC_ACTION code. If the peek is successful, it is followed by an HC_SKIP
callback.
In order to have playback from a journal playback hook occur at a certain
rate, Microsoft designed it so that the value returned by the
JournalPlaybackProc can be non-zero. This value represents the number of
clock-ticks the system should wait before processing the event. What the
documentation doesn't make clear is that when the delay has expired,
another callback to the JournalPlaybackProc is made to obtain the same
event again; the event provided with the previous non-zero delay is not
used at all. All subsequent HC_ACTION calls that request the same event
should be returned with a zero delay value. Only after an HC_SKIP callback
has been made, may an HC_ACTION callback return a non-zero delay value
again. Some applications do not do this correctly, and simply alternate
between returning a delay and returning a non-delay.
This alternating delay/no delay method made the Windows NT menu loop hang
because the PeekMessage( PM_NOREMOVE ) would get an input event (with no
delay), then the PeekMessage( PM_REMOVE ) would get a non-zero return
value from the JournalPlaybackProc. This represents no message -- so
instead of issuing an HC_SKIP callback to the JournalPlaybackProc to
advance to the next event, the Windows NT menu loop code simply looped back
to the PeekMessage( PM_NOREMOVE ) getting stuck in an infinite loop.
RESOLUTION
To work around this problem, make sure the JournalPlaybackProc correctly
returns the delay only for the first request for an event.
Windows version 3.1 and Windows 95 do not have this problem.
STATUS
This behavior is by design.
MORE INFORMATION
The following sample code demonstrates correct and incorrect methods of
handling delays in a journal playback hook.
Sample Code
LRESULT CALLBACK JournalPlaybackProc(
int nCode,
WPARAM wParam,
LPARAM lParam)
{
static BOOL fDelay;
static EVENTMSG event;
static LRESULT ticks_delay;
BOOL fCallNextHook = FALSE;
LRESULT lResult = 0;
switch( nCode )
{
case HC_SKIP:
fDelay = TRUE; // <<<< CORRECT PLACE TO RESET fDelay
// Get the next event from the list. If the routine returns
// FALSE, then we are done - release the hook.
if( !GetNextEvent( &event, &ticks_delay ))
SetJournalHook( FALSE, NULL );
break;
case HC_GETNEXT:
{
// Structure information returned from previous GetNextEvent
// call.
LPEVENTMSG lpEvent = (LPEVENTMSG) lParam;
// Set the event
*lpEvent = event;
if( fDelay )
{
// Toggle pause variable so that the next call will not
// pause. Return the pause length specified by
// ticks_delay since this is the first time the event
// has been requested.
fDelay = FALSE; // <<<< CORRECT PLACE TO CLEAR fDelay
return( ticks_delay );
}
break;
}
case HC_SYSMODALOFF:
// System modal dialog is going away. Something was
// corrupted. Windows took care of removing our
// JournalPlayback hook, so no need to call
// SetJournalHook( FALSE ).
fCallNextHook = TRUE;
break;
case HC_SYSMODALON:
default:
// Something is not right here. Let the next hook handle
// it.
fCallNextHook = TRUE;
break;
}
// If the event was not processed by our code, call next hook.
if( fCallNextHook )
lResult = CallNextHookEx( s_journalHook, nCode, wParam,
lParam );
// fDelay = TRUE; // <<<< WRONG PLACE TO RESET bDelay !!!
return lResult;
}
Additional query words:
Keywords : kbcode kbHook kbNTOS310 kbNTOS350 kbGrpUser
Version : winnt:3.1,3.5
Platform : winnt
Issue type : kbprb