mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
793 lines
16 KiB
793 lines
16 KiB
/*++
|
|
|
|
Copyright (c) 1989 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
monrqust.c
|
|
|
|
Abstract:
|
|
|
|
This module contains the Mon requests thread and
|
|
the handler for Mon requests.
|
|
|
|
Author:
|
|
|
|
Michael Jarus (mjarus) 21-Jan-1992
|
|
|
|
Environment:
|
|
|
|
User Mode Only
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#define WIN32_ONLY
|
|
#include "os2ses.h"
|
|
#include "event.h"
|
|
#include "trans.h"
|
|
#include "monitor.h"
|
|
#include "mon.h"
|
|
#include <stdio.h>
|
|
|
|
|
|
USHORT RegSize[] = { MIN_KBD_MON_BUFFER, 127 };
|
|
USHORT RWSize[] = { sizeof(KBD_MON_PACKAGE),
|
|
sizeof(MOU_MON_PACKAGE) };
|
|
|
|
extern CRITICAL_SECTION QueueInputCriticalSection;
|
|
|
|
DWORD
|
|
MonQueueClose(IN HANDLE hMon);
|
|
|
|
DWORD
|
|
InitMonitor()
|
|
{
|
|
RtlZeroMemory(&MonBuffTable[0].MonHeader, sizeof(MonBuffTable));
|
|
MonQueue = NULL;
|
|
|
|
MonitorEvent = CreateEventW(
|
|
NULL,
|
|
FALSE, /* auto reset */
|
|
TRUE,
|
|
NULL);
|
|
|
|
if (MonitorEvent == NULL)
|
|
{
|
|
#if DBG
|
|
DbgPrint("OS2SES(InitMonitor): unable to create event for Monitor\n");
|
|
#endif
|
|
return 1L;
|
|
}
|
|
|
|
KbdLastKeyDown = FALSE;
|
|
|
|
LastKbdMon = NULL;
|
|
LastMouMon = NULL;
|
|
|
|
return(0L);
|
|
}
|
|
|
|
|
|
BOOL
|
|
ServeMonRequest(IN PMONREQUEST PReq,
|
|
OUT PVOID PStatus,
|
|
IN PVOID pMsg,
|
|
OUT PULONG pReply)
|
|
{
|
|
DWORD Rc;
|
|
|
|
Rc = *(PDWORD) PStatus = 0;
|
|
|
|
switch (PReq->Request)
|
|
{
|
|
case MONOpen:
|
|
Rc = *(PDWORD) PStatus = MonOpen(PReq->d.OpenClose.MonDevice,
|
|
&(PReq->d.OpenClose.hMON));
|
|
break;
|
|
|
|
case MONReg:
|
|
Rc = *(PDWORD) PStatus = MonReg(&(PReq->d.Reg));
|
|
break;
|
|
|
|
case MONRead:
|
|
Rc = *(PDWORD) PStatus = MonRead(&(PReq->d.rwParms),
|
|
pReply,
|
|
pMsg);
|
|
break;
|
|
|
|
case MONWrite:
|
|
Rc = *(PDWORD) PStatus = MonWrite(&(PReq->d.rwParms),
|
|
pReply,
|
|
pMsg);
|
|
break;
|
|
|
|
case MONClose:
|
|
Rc = *(PDWORD) PStatus = MonClose(PReq->d.OpenClose.hMON);
|
|
break;
|
|
|
|
default:
|
|
Rc = *(PDWORD) PStatus = ERROR_MON_INVALID_PARMS;
|
|
#if DBG
|
|
IF_OD2_DEBUG( OS2_EXE )
|
|
{
|
|
DbgPrint("OS2SES(MonRequest): Unknown Mon request = %X\n",
|
|
PReq->Request);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
return(TRUE); // Continue
|
|
}
|
|
|
|
|
|
DWORD
|
|
MonOpen(IN MONDEVNUMBER DevType,
|
|
OUT PHANDLE hMon)
|
|
{
|
|
DWORD Rc;
|
|
|
|
/*
|
|
* allocate buffer for header & queue
|
|
*/
|
|
|
|
if (DevType == KbdDevice)
|
|
{
|
|
Rc = InitQueue((PKEY_EVENT_QUEUE *)hMon);
|
|
} else if (DevType == MouseDevice)
|
|
{
|
|
Rc = InitMouQueue((PMOU_EVENT_QUEUE *)hMon);
|
|
} else /* if (DevType == Lpt1Device) */
|
|
{
|
|
#if DBG
|
|
IF_OD2_DEBUG( MON )
|
|
IF_OD2_DEBUG( OS2_EXE )
|
|
DbgPrint("OS2SES(MonOpen): illegal device\n");
|
|
#endif
|
|
|
|
return(ERROR_MONITOR_NOT_SUPPORTED);
|
|
}
|
|
|
|
if (Rc)
|
|
{
|
|
#if DBG
|
|
IF_OD2_DEBUG( MON )
|
|
DbgPrint("OS2SES(MonOpen): unable to allocate handle\n");
|
|
#endif
|
|
|
|
return(ERROR_NOT_ENOUGH_MEMORY);
|
|
}
|
|
|
|
((PKEY_EVENT_QUEUE)*hMon)->MonHdr.DevType = DevType;
|
|
((PKEY_EVENT_QUEUE)*hMon)->MonHdr.MonStat = MON_STAT_OPEN; // Mon-Open
|
|
((PKEY_EVENT_QUEUE)*hMon)->MonHdr.NextMon = NULL;
|
|
|
|
#if DBG
|
|
IF_OD2_DEBUG( MON )
|
|
{
|
|
DbgPrint("OS2SES(MonOpen): return address %lx\n", *hMon);
|
|
}
|
|
#endif
|
|
|
|
return(0L);
|
|
}
|
|
|
|
|
|
DWORD
|
|
MonReg(IN PMON_REG MonReg)
|
|
{
|
|
DWORD Rc;
|
|
BOOL NewReg = FALSE;
|
|
PMON_HEADER NextMon, NewMonHeader;
|
|
PKEY_EVENT_QUEUE hMon;
|
|
|
|
/*
|
|
* make sure buffer are not used for other monitor
|
|
*/
|
|
|
|
if ((FindMonitorBuffer(MonReg->In, MonReg->ProcessId)) ||
|
|
(FindMonitorBuffer(MonReg->Out, MonReg->ProcessId)))
|
|
{
|
|
#if DBG
|
|
IF_OD2_DEBUG( MON )
|
|
DbgPrint("OS2SES(MonReg): buffer already reg\n");
|
|
#endif
|
|
|
|
return ERROR_MON_INVALID_PARMS;
|
|
}
|
|
|
|
hMon = (PKEY_EVENT_QUEUE)MonReg->hMON;
|
|
|
|
#if DBG
|
|
IF_OD2_DEBUG( MON )
|
|
{
|
|
DbgPrint("OS2SES(MonReg): hMon address %lx\n", hMon);
|
|
}
|
|
#endif
|
|
|
|
if ((MonReg->InSize < RegSize[hMon->MonHdr.DevType]) ||
|
|
(MonReg->OutSize < RegSize[hMon->MonHdr.DevType]))
|
|
{
|
|
#if DBG
|
|
IF_OD2_DEBUG( MON )
|
|
DbgPrint("OS2SES(MonReg): buffer too small\n");
|
|
#endif
|
|
|
|
return ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
|
|
if (hMon->MonHdr.MonStat != MON_STAT_OPEN)
|
|
{
|
|
/*
|
|
* queue in use, allocate new one
|
|
*/
|
|
|
|
#if DBG
|
|
IF_OD2_DEBUG( MON )
|
|
{
|
|
DbgPrint("OS2SES(MonReg): allocate new queue\n");
|
|
}
|
|
#endif
|
|
|
|
NewReg = TRUE;
|
|
|
|
if ((Rc = MonOpen(hMon->MonHdr.DevType,
|
|
(PHANDLE)&NewMonHeader)))
|
|
{
|
|
#if DBG
|
|
DbgPrint("OS2SES(MonReg): unable to allocate handle\n");
|
|
#endif
|
|
return Rc;
|
|
}
|
|
|
|
NextMon = (PMON_HEADER)hMon;
|
|
|
|
while (NextMon->NextMon != NULL)
|
|
{
|
|
NextMon = NextMon->NextMon;
|
|
}
|
|
|
|
#if DBG
|
|
IF_OD2_DEBUG( MON )
|
|
{
|
|
DbgPrint("OS2SES(MonReg): find place\n");
|
|
}
|
|
#endif
|
|
|
|
} else
|
|
NewMonHeader = (PMON_HEADER)hMon;
|
|
|
|
NewMonHeader->MonReg = *MonReg;
|
|
|
|
/*
|
|
* add monitor to the device-queue
|
|
*/
|
|
|
|
Rc = AddMonitor(NewMonHeader, (PMON_HEADER *)
|
|
((NewMonHeader->DevType == KbdDevice) ?
|
|
(PMON_HEADER *) &KbdMonQueue : (PMON_HEADER *) &MouMonQueue));
|
|
|
|
if (Rc)
|
|
{
|
|
#if DBG
|
|
IF_OD2_DEBUG( MON )
|
|
DbgPrint("OS2SES(MonReg): unable to register\n");
|
|
#endif
|
|
|
|
if (NewReg)
|
|
{
|
|
HeapFree(HandleHeap, 0,
|
|
(LPSTR) NewMonHeader->MemoryStartAddress);
|
|
}
|
|
|
|
return(Rc);
|
|
}
|
|
|
|
/*
|
|
* add buffer to table of monitor-buffer
|
|
*/
|
|
|
|
AddMonitorBuffer(MonReg->In, NewMonHeader, MonReg->ProcessId);
|
|
AddMonitorBuffer(MonReg->Out, NewMonHeader, MonReg->ProcessId);
|
|
|
|
NewMonHeader->MonStat = MON_STAT_REG; // Mon-Open-And-Reg
|
|
|
|
if (NewReg)
|
|
{
|
|
NextMon->NextMon = NewMonHeader;
|
|
}
|
|
|
|
MonReg->InSize = RWSize[NewMonHeader->DevType];
|
|
MonReg->OutSize = RWSize[NewMonHeader->DevType];
|
|
|
|
return(0L);
|
|
}
|
|
|
|
|
|
DWORD
|
|
MonRead(IN OUT PMON_RW rwParms,
|
|
OUT PULONG pReply,
|
|
IN PVOID pMsg)
|
|
{
|
|
PMON_HEADER MonHeader;
|
|
USHORT Length = 0;
|
|
DWORD MonBuf, Rc;
|
|
|
|
/*
|
|
* check legalty of BUFFER-In, Size of DataBuffer and Monitor state
|
|
*/
|
|
|
|
if (!(MonBuf = FindMonitorBuffer(rwParms->MonBuffer, rwParms->ProcessId)) ||
|
|
(MonBuf == -1L))
|
|
{
|
|
#if DBG
|
|
IF_OD2_DEBUG( MON )
|
|
DbgPrint("OS2SES(MonRead): unable to find buffer\n");
|
|
#endif
|
|
|
|
return(ERROR_MON_INVALID_PARMS);
|
|
}
|
|
|
|
MonHeader = (PMON_HEADER)MonBuf;
|
|
|
|
if (MonHeader->MonReg.In != rwParms->MonBuffer)
|
|
{
|
|
#if DBG
|
|
IF_OD2_DEBUG( MON )
|
|
DbgPrint("OS2SES(MonRead): illegal monitor buffer\n");
|
|
#endif
|
|
|
|
return(ERROR_MON_INVALID_PARMS);
|
|
}
|
|
|
|
if (rwParms->Length < RWSize[MonHeader->DevType])
|
|
{
|
|
#if DBG
|
|
IF_OD2_DEBUG( MON )
|
|
DbgPrint("OS2SES(MonRead): buffer too small\n");
|
|
#endif
|
|
|
|
return(ERROR_MON_BUFFER_TOO_SMALL);
|
|
}
|
|
|
|
if (MonHeader->MonStat != MON_STAT_REG)
|
|
{
|
|
#if DBG
|
|
IF_OD2_DEBUG( MON )
|
|
DbgPrint("OS2SES(MonRead): state not ok\n");
|
|
#endif
|
|
|
|
//ASSERT(FALSE);
|
|
|
|
// return(ERROR_MON_INVALID_PARMS);
|
|
}
|
|
|
|
/*
|
|
* read event if available
|
|
*/
|
|
|
|
MonHeader->MonStat = MON_STAT_READ;
|
|
|
|
Rc = GetMonInput(
|
|
RWSize[MonHeader->DevType],
|
|
(PKEY_EVENT_QUEUE)MonHeader,
|
|
rwParms,
|
|
pMsg,
|
|
pReply
|
|
);
|
|
|
|
if ( *pReply != 0 )
|
|
{
|
|
MonHeader->MonStat = MON_STAT_REG;
|
|
}
|
|
|
|
return (Rc);
|
|
}
|
|
|
|
|
|
DWORD
|
|
MonWrite(IN PMON_RW rwParms,
|
|
OUT PULONG pReply,
|
|
IN PVOID pMsg)
|
|
{
|
|
PMON_HEADER MonHeader;
|
|
USHORT Length = 0;
|
|
DWORD MonBuf, Rc;
|
|
|
|
UNREFERENCED_PARAMETER(pMsg);
|
|
UNREFERENCED_PARAMETER(pReply);
|
|
|
|
/*
|
|
* check legalty of BUFFER-Out, Size of DataBuffer and Monitor state
|
|
*/
|
|
|
|
if (!(MonBuf = FindMonitorBuffer(rwParms->MonBuffer, rwParms->ProcessId)) ||
|
|
(MonBuf == -1L))
|
|
{
|
|
#if DBG
|
|
IF_OD2_DEBUG( MON )
|
|
DbgPrint("OS2SES(MonWrite): unable to find buffer\n");
|
|
#endif
|
|
|
|
return(ERROR_MON_INVALID_PARMS);
|
|
}
|
|
|
|
MonHeader = (PMON_HEADER)MonBuf;
|
|
|
|
if (MonHeader->MonReg.Out != rwParms->MonBuffer)
|
|
{
|
|
#if DBG
|
|
IF_OD2_DEBUG( MON )
|
|
DbgPrint("OS2SES(MonWrite): illegal monitor buffer\n");
|
|
#endif
|
|
|
|
return(ERROR_MON_INVALID_PARMS);
|
|
}
|
|
|
|
if (rwParms->Length < RWSize[MonHeader->DevType])
|
|
{
|
|
#if DBG
|
|
IF_OD2_DEBUG( MON )
|
|
DbgPrint("OS2SES(MonWrite): buffer too small\n");
|
|
#endif
|
|
|
|
return(ERROR_MON_INVALID_PARMS);
|
|
}
|
|
|
|
if (rwParms->Length > RWSize[MonHeader->DevType]) // BUGBUG
|
|
{
|
|
#if DBG
|
|
IF_OD2_DEBUG( MON )
|
|
DbgPrint("OS2SES(MonWrite): buffer too big\n");
|
|
#endif
|
|
|
|
return(ERROR_MON_DATA_TOO_LARGE);
|
|
}
|
|
|
|
if (MonHeader->MonStat == MON_STAT_OPEN)
|
|
{
|
|
#if DBG
|
|
IF_OD2_DEBUG( MON )
|
|
DbgPrint("OS2SES(MonWrite): state not ok\n");
|
|
#endif
|
|
|
|
return(ERROR_MON_INVALID_PARMS);
|
|
}
|
|
|
|
/*
|
|
* write event
|
|
*/
|
|
|
|
#if DBG
|
|
IF_OD2_DEBUG( MON )
|
|
{
|
|
DbgPrint("OS2SES(MonWrite): (before) from queue %lx, to queue %lx\n",
|
|
MonHeader, MonHeader->NextQueue );
|
|
}
|
|
#endif
|
|
|
|
Rc = PutMonInput(
|
|
RWSize[MonHeader->DevType],
|
|
(PKEY_EVENT_QUEUE)MonHeader->NextQueue,
|
|
1,
|
|
//rwParms,
|
|
(PKBD_MON_PACKAGE)&(rwParms->ioBuff[0]),
|
|
pMsg,
|
|
pReply);
|
|
|
|
// BUGBUG if not enough place
|
|
|
|
return( Rc );
|
|
}
|
|
|
|
|
|
DWORD
|
|
MonClose(IN HANDLE hMon)
|
|
{
|
|
PMON_HEADER NextMon, MonHeader = (PMON_HEADER)hMon;
|
|
|
|
while (MonHeader)
|
|
{
|
|
NextMon = MonHeader->NextMon;
|
|
MonQueueClose((HANDLE)MonHeader);
|
|
MonHeader = NextMon;
|
|
}
|
|
|
|
return(0L);
|
|
}
|
|
|
|
|
|
DWORD
|
|
MonQueueClose(IN HANDLE hMon)
|
|
{
|
|
PMON_HEADER MonHeader = (PMON_HEADER)hMon;
|
|
|
|
if (MonHeader->MonStat >= MON_STAT_REG)
|
|
{
|
|
/*
|
|
* Monitor are reg - DeReg :
|
|
* remove monitor & delete entried in table
|
|
*/
|
|
|
|
RemoveMonitor(MonHeader, (PMON_HEADER *)
|
|
((MonHeader->DevType == KbdDevice) ?
|
|
(PMON_HEADER *) &KbdMonQueue :
|
|
(PMON_HEADER *) &MouMonQueue));
|
|
|
|
DelMonitorBuffer(MonHeader);
|
|
}
|
|
|
|
/*
|
|
* Free header from heap
|
|
*/
|
|
|
|
HeapFree(HandleHeap, 0,
|
|
(LPSTR) MonHeader->MemoryStartAddress);
|
|
|
|
return(0L);
|
|
}
|
|
|
|
|
|
DWORD
|
|
FindMonitorBuffer(IN PVOID Buffer,
|
|
IN ULONG ProcessId)
|
|
{
|
|
ULONG i, FreeCount = 0;
|
|
|
|
for ( i = 0 ; i < MON_BUFFER_TABLE_SIZE ; i++ )
|
|
{
|
|
if ((MonBuffTable[i].Buffer == Buffer) &&
|
|
(MonBuffTable[i].ProcessId == ProcessId))
|
|
{
|
|
return((DWORD)MonBuffTable[i].MonHeader);
|
|
} else if (!MonBuffTable[i].Buffer)
|
|
{
|
|
FreeCount++;
|
|
}
|
|
|
|
}
|
|
|
|
if (FreeCount < 2)
|
|
{
|
|
return((DWORD)-1L); // no place for new 2 buffers
|
|
}
|
|
|
|
return(0L);
|
|
}
|
|
|
|
|
|
DWORD
|
|
AddMonitorBuffer(IN PVOID Buffer,
|
|
IN PMON_HEADER MonHeader,
|
|
IN ULONG ProcessId)
|
|
{
|
|
ULONG i, FindCount = 0;
|
|
|
|
for ( i = 0 ; i < MON_BUFFER_TABLE_SIZE ; i++ )
|
|
{
|
|
if (!MonBuffTable[i].Buffer)
|
|
{
|
|
MonBuffTable[i].Buffer = Buffer;
|
|
MonBuffTable[i].MonHeader = MonHeader;
|
|
MonBuffTable[i].ProcessId = ProcessId;
|
|
|
|
return((DWORD)MonBuffTable[i].MonHeader);
|
|
}
|
|
}
|
|
|
|
ASSERT( FALSE );
|
|
|
|
return(0L);
|
|
}
|
|
|
|
|
|
DWORD
|
|
DelMonitorBuffer(IN PMON_HEADER MonHeader)
|
|
{
|
|
ULONG i, FindCount = 0;
|
|
|
|
for ( i = 0 ; i < MON_BUFFER_TABLE_SIZE ; i++ )
|
|
{
|
|
if (MonBuffTable[i].MonHeader == MonHeader)
|
|
{
|
|
RtlZeroMemory(&(MonBuffTable[i]), sizeof(MON_BUFFER_TABLE));
|
|
FindCount++;
|
|
}
|
|
}
|
|
|
|
ASSERT( FindCount == 2 );
|
|
|
|
return(0L);
|
|
}
|
|
|
|
|
|
DWORD
|
|
NewKbdQueue(IN PKEY_EVENT_QUEUE NewKbdQueue)
|
|
{
|
|
|
|
if (WaitForSingleObject( MonitorEvent, INFINITE ))
|
|
{
|
|
return(ERROR_MONITOR_NOT_SUPPORTED);
|
|
}
|
|
|
|
if (LastKbdMon != NULL)
|
|
{
|
|
LastKbdMon->MonHdr.NextQueue = (PMON_HEADER)NewKbdQueue;
|
|
} else
|
|
KbdMonQueue = NewKbdQueue;
|
|
|
|
SetEvent( MonitorEvent );
|
|
|
|
return(0L);
|
|
}
|
|
|
|
|
|
DWORD AddMonitor(IN PMON_HEADER NewMonHeader,
|
|
IN PMON_HEADER *pMonQueue)
|
|
{
|
|
PMON_HEADER MonHeader, LastMonHeader = NULL;
|
|
USHORT Index;
|
|
#if DBG
|
|
PMON_HEADER DbgMonHeader;
|
|
#endif
|
|
|
|
/*
|
|
* Positioning in chain
|
|
* --------------------
|
|
* 1st registered as FIRST
|
|
* ...
|
|
* last registered as FIRST
|
|
* last registered as DEFAULT
|
|
* ...
|
|
* 1st registered as DEFAULT
|
|
* last registered as END
|
|
* ...
|
|
* 1st registered as END
|
|
*/
|
|
|
|
if (NewMonHeader->MonReg.Pos > MONITOR_END)
|
|
{
|
|
/*
|
|
* ignore MONITOR_SPECIAL
|
|
*/
|
|
|
|
NewMonHeader->MonReg.Pos -= 3;
|
|
NewMonHeader->Flag = 1;
|
|
}
|
|
|
|
/*
|
|
* Translate Position:
|
|
* FIRST = 0
|
|
* DEFAULT = 1
|
|
* END = 2
|
|
* device (kbd/mouse) = 3
|
|
*
|
|
* when looking for the place, DEFAULT is assign also to FIRST
|
|
*/
|
|
|
|
if (NewMonHeader->MonReg.Pos < MONITOR_END)
|
|
{
|
|
/*
|
|
* XOR MONITOR_FIRST & MONITOR_DEFAULT
|
|
*/
|
|
|
|
NewMonHeader->MonReg.Pos = 1 - NewMonHeader->MonReg.Pos;
|
|
}
|
|
|
|
Index = (USHORT)NewMonHeader->MonReg.Pos;
|
|
|
|
if (Index == 0)
|
|
{
|
|
Index = 1; // last FIRST is equivalent to 1st DEFAULT
|
|
}
|
|
|
|
if (WaitForSingleObject( MonitorEvent, INFINITE ))
|
|
{
|
|
return(ERROR_MONITOR_NOT_SUPPORTED);
|
|
}
|
|
|
|
MonHeader = *pMonQueue;
|
|
|
|
/*
|
|
* find the place in chain
|
|
*/
|
|
|
|
while (MonHeader->MonReg.Pos < (ULONG)Index)
|
|
{
|
|
LastMonHeader = MonHeader;
|
|
MonHeader = MonHeader->NextQueue;
|
|
|
|
}
|
|
|
|
NewMonHeader->NextQueue = MonHeader;
|
|
|
|
if (LastMonHeader == NULL)
|
|
{
|
|
NewMonHeader->NextQueue = *pMonQueue;
|
|
*pMonQueue = NewMonHeader;
|
|
} else
|
|
{
|
|
NewMonHeader->NextQueue = LastMonHeader->NextQueue;
|
|
LastMonHeader->NextQueue = NewMonHeader;
|
|
}
|
|
|
|
if ((MonHeader->MonReg.Pos == 3) && // we add the last queue in chain for Kbd
|
|
(*pMonQueue == (PMON_HEADER)KbdMonQueue ))
|
|
{
|
|
LastKbdMon = (PKEY_EVENT_QUEUE)NewMonHeader;
|
|
}
|
|
|
|
SetEvent( MonitorEvent );
|
|
|
|
#if DBG
|
|
DbgMonHeader = *pMonQueue;
|
|
|
|
IF_OD2_DEBUG( MON )
|
|
{
|
|
while (DbgMonHeader->NextQueue)
|
|
{
|
|
DbgPrint("OS2SES(AddMonitor): Current %lx, next %lx\n", DbgMonHeader, DbgMonHeader->NextQueue);
|
|
|
|
DbgMonHeader = DbgMonHeader->NextQueue;
|
|
}
|
|
|
|
DbgPrint("OS2SES(MonReg): %lx ... %lx, (%lx) %lx, %lx (%lx) ... %lx, %lx\n",
|
|
KbdMonQueue, LastMonHeader,
|
|
(LastMonHeader) ? LastMonHeader->NextQueue : NULL,
|
|
NewMonHeader, NewMonHeader->NextQueue, MonHeader, LastKbdMon, KbdQueue);
|
|
}
|
|
#endif
|
|
|
|
return(0L);
|
|
}
|
|
|
|
|
|
DWORD
|
|
RemoveMonitor(IN PMON_HEADER OldMonHeader,
|
|
IN PMON_HEADER *pMonQueue)
|
|
{
|
|
PMON_HEADER MonHeader, LastMonHeader = NULL;
|
|
|
|
if (WaitForSingleObject( MonitorEvent, INFINITE ))
|
|
{
|
|
return(ERROR_MONITOR_NOT_SUPPORTED);
|
|
}
|
|
|
|
MonHeader = *pMonQueue;
|
|
|
|
/*
|
|
* find the place in chain
|
|
*/
|
|
|
|
while (MonHeader != NULL && MonHeader != OldMonHeader)
|
|
{
|
|
LastMonHeader = MonHeader;
|
|
MonHeader = MonHeader->NextQueue;
|
|
}
|
|
|
|
if (MonHeader == NULL)
|
|
{
|
|
return(0);
|
|
}
|
|
|
|
if (LastMonHeader == NULL)
|
|
{
|
|
*pMonQueue = MonHeader->NextQueue;
|
|
} else
|
|
LastMonHeader->NextQueue = MonHeader->NextQueue;
|
|
|
|
if ((OldMonHeader->NextQueue->MonReg.Index == 3) && // we remove the last queue in chain for Kbd
|
|
(*pMonQueue == (PMON_HEADER)KbdMonQueue ))
|
|
{
|
|
if (LastMonHeader == NULL)
|
|
{
|
|
LastKbdMon = NULL;
|
|
} else
|
|
LastKbdMon = (PKEY_EVENT_QUEUE)LastMonHeader;
|
|
}
|
|
|
|
SetEvent( MonitorEvent );
|
|
|
|
return(0L);
|
|
}
|