-added better LIST_FOR_EACH macros (ripped from wine) and fix their usage

-make hotkeys session global (they dont belong in winsta)

svn path=/trunk/; revision=17923
This commit is contained in:
Gunnar Dalsnes 2005-09-18 23:06:15 +00:00
parent 17fba5a631
commit 5eaa4fda83
9 changed files with 88 additions and 151 deletions

View file

@ -17,12 +17,21 @@
#endif
#define EXPORTED __declspec(dllexport)
#define IMPORTED __declspec(dllimport)
#define LIST_FOR_EACH(entry, head) \
for(entry = (head)->Flink; entry != (head); entry = entry->Flink)
#define LIST_FOR_EACH_SAFE(tmp_entry, head, ptr, type, field) \
for ((tmp_entry)=(head)->Flink; (tmp_entry)!=(head) && \
((ptr) = CONTAINING_RECORD(tmp_entry,type,field)) && \
((tmp_entry) = (tmp_entry)->Flink); )
/* iterate through the list using a list entry */
#define LIST_FOR_EACH(elem, list, type, field) \
for ((elem) = CONTAINING_RECORD((list)->Flink, type, field); \
&(elem)->field != (list); \
(elem) = CONTAINING_RECORD((elem)->field.Flink, type, field))
/* iterate through the list using a list entry, with safety against removal */
#define LIST_FOR_EACH_SAFE(cursor, cursor2, list, type, field) \
for ((cursor) = CONTAINING_RECORD((list)->Flink, type, field), \
(cursor2) = CONTAINING_RECORD((cursor)->field.Flink, type, field); \
&(cursor)->field != (list); \
(cursor) = (cursor2), \
(cursor2) = CONTAINING_RECORD((cursor)->field.Flink, type, field))
#define OPTHDROFFSET(a) ((LPVOID)((BYTE *)a + \
((PIMAGE_DOS_HEADER)a)->e_lfanew + \
sizeof (IMAGE_NT_SIGNATURE) + \

View file

@ -161,7 +161,6 @@ FsRtlpCheckLockForReadOrWriteAccess(
KIRQL oldirql;
PFILE_LOCK_TOC LockToc;
PFILE_LOCK_GRANTED Granted;
PLIST_ENTRY EnumEntry;
LARGE_INTEGER EndOffset;
ASSERT(FileLock);
@ -177,10 +176,8 @@ FsRtlpCheckLockForReadOrWriteAccess(
KeAcquireSpinLock(&LockToc->SpinLock, &oldirql);
LIST_FOR_EACH(EnumEntry, &LockToc->GrantedListHead)
LIST_FOR_EACH(Granted, &LockToc->GrantedListHead, FILE_LOCK_GRANTED, ListEntry)
{
Granted = CONTAINING_RECORD(EnumEntry, FILE_LOCK_GRANTED, ListEntry);
//if overlapping
if(IsOverlappingLock(&Granted->Lock, FileOffset, &EndOffset))
{
@ -358,12 +355,12 @@ FsRtlpFastUnlockAllByKey(
{
KIRQL oldirql;
PFILE_LOCK_TOC LockToc;
PLIST_ENTRY EnumEntry;
PFILE_LOCK_GRANTED Granted;
PFILE_LOCK_GRANTED Granted, tmp;
BOOLEAN Unlock = FALSE;
//must make local copy since FILE_LOCK struct is allowed to be paged
BOOLEAN GotUnlockRoutine;
LIST_ENTRY UnlockedListHead;
PLIST_ENTRY EnumEntry;
ASSERT(FileLock);
LockToc = FileLock->LockInformation;
@ -377,7 +374,7 @@ FsRtlpFastUnlockAllByKey(
GotUnlockRoutine = FileLock->UnlockRoutine != NULL;
KeAcquireSpinLock(&LockToc->SpinLock, &oldirql);
LIST_FOR_EACH_SAFE(EnumEntry, &LockToc->GrantedListHead, Granted, FILE_LOCK_GRANTED, ListEntry)
LIST_FOR_EACH_SAFE(Granted, tmp, &LockToc->GrantedListHead, FILE_LOCK_GRANTED, ListEntry)
{
if (Granted->Lock.Process == Process &&
@ -506,17 +503,14 @@ FsRtlpAddLock(
IN PVOID Context
)
{
PLIST_ENTRY EnumEntry;
PFILE_LOCK_GRANTED Granted;
LARGE_INTEGER EndOffset;
EndOffset.QuadPart = FileOffset->QuadPart + Length->QuadPart - 1;
//loop and try to find conflicking locks
LIST_FOR_EACH(EnumEntry, &LockToc->GrantedListHead)
LIST_FOR_EACH(Granted, &LockToc->GrantedListHead, FILE_LOCK_GRANTED, ListEntry)
{
Granted = CONTAINING_RECORD(EnumEntry,FILE_LOCK_GRANTED, ListEntry);
if (IsOverlappingLock(&Granted->Lock, FileOffset, &EndOffset))
{
//we found a locks that overlap with the new lock
@ -578,13 +572,13 @@ FsRtlpCompletePendingLocks(
{
//walk pending list, FIFO order, try 2 complete locks
PLIST_ENTRY EnumEntry;
PIRP Irp;
PIRP Irp, tmp;
PIO_STACK_LOCATION Stack;
LIST_ENTRY CompletedListHead;
InitializeListHead(&CompletedListHead);
LIST_FOR_EACH_SAFE(EnumEntry, &LockToc->PendingListHead, Irp, IRP, Tail.Overlay.ListEntry)
LIST_FOR_EACH_SAFE(Irp, tmp, &LockToc->PendingListHead, IRP, Tail.Overlay.ListEntry)
{
Stack = IoGetCurrentIrpStackLocation(Irp);
if (FsRtlpAddLock(LockToc,
@ -676,8 +670,7 @@ FsRtlpUnlockSingle(
{
KIRQL oldirql;
PFILE_LOCK_TOC LockToc;
PFILE_LOCK_GRANTED Granted;
PLIST_ENTRY EnumEntry;
PFILE_LOCK_GRANTED Granted, tmp;
ASSERT(FileLock);
LockToc = FileLock->LockInformation;
@ -689,7 +682,7 @@ FsRtlpUnlockSingle(
KeAcquireSpinLock(&LockToc->SpinLock, &oldirql );
LIST_FOR_EACH_SAFE(EnumEntry, &LockToc->GrantedListHead, Granted,FILE_LOCK_GRANTED,ListEntry)
LIST_FOR_EACH_SAFE(Granted, tmp, &LockToc->GrantedListHead, FILE_LOCK_GRANTED,ListEntry)
{
//must be exact match
@ -778,7 +771,6 @@ FsRtlpDumpFileLocks(
PFILE_LOCK_TOC LockToc;
PFILE_LOCK_GRANTED Granted;
PIRP Irp;
PLIST_ENTRY EnumEntry;
PIO_STACK_LOCATION Stack;
ASSERT(FileLock);
@ -794,10 +786,8 @@ FsRtlpDumpFileLocks(
KeAcquireSpinLock(&LockToc->SpinLock, &oldirql);
LIST_FOR_EACH(EnumEntry, &LockToc->GrantedListHead)
LIST_FOR_EACH(Granted, &LockToc->GrantedListHead, FILE_LOCK_GRANTED , ListEntry)
{
Granted = CONTAINING_RECORD(EnumEntry, FILE_LOCK_GRANTED , ListEntry);
DPRINT1("%s, start: %I64x, len: %I64x, end: %I64x, key: %i, proc: 0x%p, fob: 0x%p\n",
Granted->Lock.ExclusiveLock ? "EXCL" : "SHRD",
Granted->Lock.StartingByte.QuadPart,
@ -812,9 +802,8 @@ FsRtlpDumpFileLocks(
DPRINT1("Dumping pending file locks, FIFO order\n");
LIST_FOR_EACH(EnumEntry, &LockToc->PendingListHead)
LIST_FOR_EACH(Irp, &LockToc->PendingListHead, IRP , Tail.Overlay.ListEntry)
{
Irp = CONTAINING_RECORD(EnumEntry, IRP , Tail.Overlay.ListEntry);
Stack = IoGetCurrentIrpStackLocation(Irp);
DPRINT1("%s, start: %I64x, len: %I64x, end: %I64x, key: %i, proc: 0x%p, fob: 0x%p\n",

View file

@ -120,13 +120,10 @@ FsRtlpFindNotifyEntry(
PVOID FsContext
)
{
PLIST_ENTRY EnumEntry;
PNOTIFY_ENTRY NotifyEntry;
LIST_FOR_EACH(EnumEntry, NotifyList)
LIST_FOR_EACH(NotifyEntry, NotifyList, NOTIFY_ENTRY, ListEntry)
{
NotifyEntry = CONTAINING_RECORD(EnumEntry, NOTIFY_ENTRY, ListEntry);
if (NotifyEntry->FsContext == FsContext)
{
return NotifyEntry;
@ -310,15 +307,15 @@ FsRtlpWatchedDirectoryWasDeleted(
)
{
LIST_ENTRY CompletedListHead;
PLIST_ENTRY EnumEntry, TmpEntry;
PNOTIFY_ENTRY NotifyEntry;
PLIST_ENTRY TmpEntry;
PNOTIFY_ENTRY NotifyEntry, tmp;
PIRP Irp;
InitializeListHead(&CompletedListHead);
ExAcquireFastMutex((PFAST_MUTEX)NotifySync);
LIST_FOR_EACH_SAFE(EnumEntry, NotifyList, NotifyEntry, NOTIFY_ENTRY, ListEntry )
LIST_FOR_EACH_SAFE(NotifyEntry, tmp, NotifyList, NOTIFY_ENTRY, ListEntry )
{
if (NotifyEntry->Fcb == Fcb)
{
@ -654,8 +651,8 @@ FsRtlNotifyFullReportChange (
{
USHORT FullDirLen;
STRING RelativeName;
PNOTIFY_ENTRY NotifyEntry, tmp;
PLIST_ENTRY EnumEntry;
PNOTIFY_ENTRY NotifyEntry;
PIRP Irp;
LIST_ENTRY CompletedListHead;
USHORT NameLenU;
@ -676,7 +673,7 @@ FsRtlNotifyFullReportChange (
ExAcquireFastMutex((PFAST_MUTEX)NotifySync);
LIST_FOR_EACH_SAFE(EnumEntry, NotifyList, NotifyEntry, NOTIFY_ENTRY, ListEntry )
LIST_FOR_EACH_SAFE(NotifyEntry, tmp, NotifyList, NOTIFY_ENTRY, ListEntry )
{
ASSERT(NotifyEntry->Unicode == FsRtlpIsUnicodePath(FullTargetName));

View file

@ -15,23 +15,22 @@ typedef struct _HOT_KEY_ITEM
} HOT_KEY_ITEM, *PHOT_KEY_ITEM;
NTSTATUS FASTCALL
InitHotKeys(PWINSTATION_OBJECT WinStaObject);
InitHotkeyImpl();
NTSTATUS FASTCALL
CleanupHotKeys(PWINSTATION_OBJECT WinStaObject);
//NTSTATUS FASTCALL
//CleanupHotKeys(PWINSTATION_OBJECT WinStaObject);
BOOL
GetHotKey (PWINSTATION_OBJECT WinStaObject,
UINT fsModifiers,
BOOL FASTCALL
GetHotKey (UINT fsModifiers,
UINT vk,
struct _ETHREAD **Thread,
HWND *hWnd,
int *id);
VOID
VOID FASTCALL
UnregisterWindowHotKeys(PWINDOW_OBJECT Window);
VOID
VOID FASTCALL
UnregisterThreadHotKeys(struct _ETHREAD *Thread);
#endif /* _WIN32K_HOTKEY_H */

View file

@ -41,7 +41,6 @@ typedef struct _WINSTATION_OBJECT
ULONG Flags;
struct _DESKTOP_OBJECT* ActiveDesktop;
/* FIXME: Clipboard */
LIST_ENTRY HotKeyListHead;
} WINSTATION_OBJECT, *PWINSTATION_OBJECT;
extern WINSTATION_OBJECT *InputWindowStation;

View file

@ -352,6 +352,13 @@ DriverEntry (
return STATUS_UNSUCCESSFUL;
}
Status = InitHotkeyImpl();
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to initialize hotkey implementation!\n");
return STATUS_UNSUCCESSFUL;
}
Status = InitWindowStationImpl();
if (!NT_SUCCESS(Status))
{

View file

@ -27,6 +27,18 @@
* 02-11-2003 EK Created
*/
/*
FIXME: Hotkey notifications are triggered by keyboard input (physical or programatically)
and since only desktops on WinSta0 can recieve input in seems very wrong to allow
windows/threads on destops not belonging to WinSta0 to set hotkeys (recieve notifications).
-Gunnar
*/
/* INCLUDES ******************************************************************/
#include <w32k.h>
@ -36,47 +48,40 @@
/* GLOBALS *******************************************************************/
LIST_ENTRY gHotkeyList;
/* FUNCTIONS *****************************************************************/
NTSTATUS FASTCALL
InitHotKeys(PWINSTATION_OBJECT WinStaObject)
InitHotkeyImpl()
{
InitializeListHead(&WinStaObject->HotKeyListHead);
InitializeListHead(&gHotkeyList);
return STATUS_SUCCESS;
}
#if 0 //not used
NTSTATUS FASTCALL
CleanupHotKeys(PWINSTATION_OBJECT WinStaObject)
CleanupHotKeys()
{
return STATUS_SUCCESS;
}
#endif
BOOL
GetHotKey (PWINSTATION_OBJECT WinStaObject,
UINT fsModifiers,
BOOL FASTCALL
GetHotKey (UINT fsModifiers,
UINT vk,
struct _ETHREAD **Thread,
HWND *hWnd,
int *id)
{
PLIST_ENTRY Entry;
PHOT_KEY_ITEM HotKeyItem;
if(!WinStaObject)
LIST_FOR_EACH(HotKeyItem, &gHotkeyList, HOT_KEY_ITEM, ListEntry)
{
return FALSE;
}
Entry = WinStaObject->HotKeyListHead.Flink;
while (Entry != &WinStaObject->HotKeyListHead)
{
HotKeyItem = (PHOT_KEY_ITEM) CONTAINING_RECORD(Entry,
HOT_KEY_ITEM,
ListEntry);
if (HotKeyItem->fsModifiers == fsModifiers &&
HotKeyItem->vk == vk)
{
@ -89,37 +94,21 @@ GetHotKey (PWINSTATION_OBJECT WinStaObject,
if (id != NULL)
*id = HotKeyItem->id;
return TRUE;
}
Entry = Entry->Flink;
}
return FALSE;
}
VOID
VOID FASTCALL
UnregisterWindowHotKeys(PWINDOW_OBJECT Window)
{
PLIST_ENTRY Entry;
PHOT_KEY_ITEM HotKeyItem;
PWINSTATION_OBJECT WinStaObject = NULL;
if(Window->OwnerThread && Window->OwnerThread->ThreadsProcess)
WinStaObject = Window->OwnerThread->Tcb.Win32Thread->Desktop->WindowStation;
if(!WinStaObject)
return;
Entry = WinStaObject->HotKeyListHead.Flink;
while (Entry != &WinStaObject->HotKeyListHead)
PHOT_KEY_ITEM HotKeyItem, tmp;
LIST_FOR_EACH_SAFE(HotKeyItem, tmp, &gHotkeyList, HOT_KEY_ITEM, ListEntry)
{
HotKeyItem = (PHOT_KEY_ITEM) CONTAINING_RECORD (Entry,
HOT_KEY_ITEM,
ListEntry);
Entry = Entry->Flink;
if (HotKeyItem->hWnd == Window->hSelf)
{
RemoveEntryList (&HotKeyItem->ListEntry);
@ -130,26 +119,13 @@ UnregisterWindowHotKeys(PWINDOW_OBJECT Window)
}
VOID
VOID FASTCALL
UnregisterThreadHotKeys(struct _ETHREAD *Thread)
{
PLIST_ENTRY Entry;
PHOT_KEY_ITEM HotKeyItem;
PWINSTATION_OBJECT WinStaObject = NULL;
PHOT_KEY_ITEM HotKeyItem, tmp;
if(Thread->Tcb.Win32Thread && Thread->Tcb.Win32Thread->Desktop)
WinStaObject = Thread->Tcb.Win32Thread->Desktop->WindowStation;
if(!WinStaObject)
return;
Entry = WinStaObject->HotKeyListHead.Flink;
while (Entry != &WinStaObject->HotKeyListHead)
LIST_FOR_EACH_SAFE(HotKeyItem, tmp, &gHotkeyList, HOT_KEY_ITEM, ListEntry)
{
HotKeyItem = (PHOT_KEY_ITEM) CONTAINING_RECORD (Entry,
HOT_KEY_ITEM,
ListEntry);
Entry = Entry->Flink;
if (HotKeyItem->Thread == Thread)
{
RemoveEntryList (&HotKeyItem->ListEntry);
@ -160,27 +136,18 @@ UnregisterThreadHotKeys(struct _ETHREAD *Thread)
}
static BOOL
IsHotKey (PWINSTATION_OBJECT WinStaObject,
UINT fsModifiers,
UINT vk)
static
BOOL FASTCALL
IsHotKey (UINT fsModifiers, UINT vk)
{
PLIST_ENTRY Entry;
PHOT_KEY_ITEM HotKeyItem;
Entry = WinStaObject->HotKeyListHead.Flink;
while (Entry != &WinStaObject->HotKeyListHead)
LIST_FOR_EACH(HotKeyItem, &gHotkeyList, HOT_KEY_ITEM, ListEntry)
{
HotKeyItem = (PHOT_KEY_ITEM) CONTAINING_RECORD (Entry,
HOT_KEY_ITEM,
ListEntry);
if (HotKeyItem->fsModifiers == fsModifiers &&
HotKeyItem->vk == vk)
if (HotKeyItem->fsModifiers == fsModifiers && HotKeyItem->vk == vk)
{
return TRUE;
}
Entry = Entry->Flink;
}
return FALSE;
@ -195,7 +162,6 @@ NtUserRegisterHotKey(HWND hWnd,
{
PHOT_KEY_ITEM HotKeyItem;
PWINDOW_OBJECT Window;
PWINSTATION_OBJECT WinStaObject = NULL;
PETHREAD HotKeyThread;
DECLARE_RETURN(BOOL);
@ -215,17 +181,8 @@ NtUserRegisterHotKey(HWND hWnd,
HotKeyThread = Window->OwnerThread;
}
if(HotKeyThread->ThreadsProcess && HotKeyThread->ThreadsProcess->Win32Process)
WinStaObject = HotKeyThread->Tcb.Win32Thread->Desktop->WindowStation;
if(!WinStaObject)
{
RETURN( FALSE);
}
/* Check for existing hotkey */
if (IsHotKey (WinStaObject, fsModifiers, vk))
if (IsHotKey (fsModifiers, vk))
{
RETURN( FALSE);
}
@ -242,8 +199,7 @@ NtUserRegisterHotKey(HWND hWnd,
HotKeyItem->fsModifiers = fsModifiers;
HotKeyItem->vk = vk;
InsertHeadList (&WinStaObject->HotKeyListHead,
&HotKeyItem->ListEntry);
InsertHeadList (&gHotkeyList, &HotKeyItem->ListEntry);
RETURN( TRUE);
@ -255,13 +211,10 @@ CLEANUP:
BOOL STDCALL
NtUserUnregisterHotKey(HWND hWnd,
int id)
NtUserUnregisterHotKey(HWND hWnd, int id)
{
PLIST_ENTRY Entry;
PHOT_KEY_ITEM HotKeyItem;
PWINDOW_OBJECT Window;
PWINSTATION_OBJECT WinStaObject = NULL;
DECLARE_RETURN(BOOL);
DPRINT("Enter NtUserUnregisterHotKey\n");
@ -272,30 +225,15 @@ NtUserUnregisterHotKey(HWND hWnd,
RETURN( FALSE);
}
if(Window->OwnerThread->ThreadsProcess && Window->OwnerThread->ThreadsProcess->Win32Process)
WinStaObject = Window->OwnerThread->Tcb.Win32Thread->Desktop->WindowStation;
if(!WinStaObject)
LIST_FOR_EACH(HotKeyItem, &gHotkeyList, HOT_KEY_ITEM, ListEntry)
{
RETURN( FALSE);
}
Entry = WinStaObject->HotKeyListHead.Flink;
while (Entry != &WinStaObject->HotKeyListHead)
{
HotKeyItem = (PHOT_KEY_ITEM) CONTAINING_RECORD (Entry,
HOT_KEY_ITEM,
ListEntry);
if (HotKeyItem->hWnd == hWnd &&
HotKeyItem->id == id)
if (HotKeyItem->hWnd == hWnd && HotKeyItem->id == id)
{
RemoveEntryList (&HotKeyItem->ListEntry);
ExFreePool (HotKeyItem);
RETURN( TRUE);
}
Entry = Entry->Flink;
}
RETURN( FALSE);

View file

@ -642,6 +642,8 @@ KeyboardThreadMain(PVOID StartContext)
if(NextKeyInput.MakeCode == 0x2E)/* Ctrl-C */
{
DPRINT1("Ctrl-C pressed\n");
/* FIXME: this seems wrong! this bypass hotkeys and all and the winhellos CRTL+C hotkey test
dont work (anymore) */
co_MsqPostKeyboardMessage(WM_COPY,0,0);
continue;
}
@ -697,8 +699,7 @@ KeyboardThreadMain(PVOID StartContext)
KeyInput.Flags & KEY_E0 ? 0xE0 :
(KeyInput.Flags & KEY_E1 ? 0xE1 : 0));
if (GetHotKey(InputWindowStation,
ModifierState,
if (GetHotKey(ModifierState,
msg.wParam,
&Thread,
&hWnd,

View file

@ -535,8 +535,6 @@ NtUserCreateWindowStation(
return 0;
}
InitHotKeys(WindowStationObject);
CurInfo->Enabled = FALSE;
CurInfo->ButtonsDown = 0;
CurInfo->CursorClipInfo.IsClipped = FALSE;