mirror of
https://github.com/reactos/reactos.git
synced 2025-04-26 16:40:27 +00:00
-include/ndk/rtltypes.h: add MAX_ATOM_LEN define
-win32k: remove some NtUser syscalls and merge some NtUser syscalls -crt/include/internal/file.h: correct spelling -RtlAddAtomToAtomTable: check for max atom len -RtlQueryAtomInAtomTable: fix bug. somehow lock wasnt always released. -fix/reword windows classes impl. based on Wine. All but 2 winetests pass. -ntoskrnl/rtl/atom.c: add fixme about global atom table -remove desktop object lock -dont link windows into the class object -co_IntShellHookNotify: safely send notify messages -misc win32k reorg/cleanup svn path=/trunk/; revision=18022
This commit is contained in:
parent
ff4f5a654b
commit
5fa3cc8c0f
23 changed files with 780 additions and 881 deletions
|
@ -107,6 +107,8 @@
|
||||||
#define NLS_MB_OEM_CODE_PAGE_TAG NlsMbOemCodePageTag
|
#define NLS_MB_OEM_CODE_PAGE_TAG NlsMbOemCodePageTag
|
||||||
#define NLS_OEM_LEAD_BYTE_INFO NlsOemLeadByteInfo
|
#define NLS_OEM_LEAD_BYTE_INFO NlsOemLeadByteInfo
|
||||||
|
|
||||||
|
#define MAX_ATOM_LEN 255 /* TCHARS not including nullterm */
|
||||||
|
|
||||||
/* List Macros */
|
/* List Macros */
|
||||||
static __inline
|
static __inline
|
||||||
VOID
|
VOID
|
||||||
|
|
|
@ -212,7 +212,6 @@ NtUserCallOneParam(
|
||||||
#define TWOPARAM_ROUTINE_UNKNOWN 0x54
|
#define TWOPARAM_ROUTINE_UNKNOWN 0x54
|
||||||
#define TWOPARAM_ROUTINE_SHOWOWNEDPOPUPS 0x55
|
#define TWOPARAM_ROUTINE_SHOWOWNEDPOPUPS 0x55
|
||||||
#define TWOPARAM_ROUTINE_SWITCHTOTHISWINDOW 0x56
|
#define TWOPARAM_ROUTINE_SWITCHTOTHISWINDOW 0x56
|
||||||
#define TWOPARAM_ROUTINE_VALIDATERGN 0x57
|
|
||||||
#define TWOPARAM_ROUTINE_SETWNDCONTEXTHLPID 0x58
|
#define TWOPARAM_ROUTINE_SETWNDCONTEXTHLPID 0x58
|
||||||
#define TWOPARAM_ROUTINE_SETCARETPOS 0x60
|
#define TWOPARAM_ROUTINE_SETCARETPOS 0x60
|
||||||
#define TWOPARAM_ROUTINE_GETWINDOWINFO 0x61
|
#define TWOPARAM_ROUTINE_GETWINDOWINFO 0x61
|
||||||
|
@ -894,11 +893,6 @@ NtUserGetWOWClass(
|
||||||
DWORD Unknown0,
|
DWORD Unknown0,
|
||||||
DWORD Unknown1);
|
DWORD Unknown1);
|
||||||
|
|
||||||
BOOL
|
|
||||||
STDCALL
|
|
||||||
NtUserHideCaret(
|
|
||||||
HWND hWnd);
|
|
||||||
|
|
||||||
DWORD
|
DWORD
|
||||||
STDCALL
|
STDCALL
|
||||||
NtUserImpersonateDdeClientWindow(
|
NtUserImpersonateDdeClientWindow(
|
||||||
|
@ -935,20 +929,6 @@ NtUserInternalGetWindowText(
|
||||||
LPWSTR lpString,
|
LPWSTR lpString,
|
||||||
INT nMaxCount);
|
INT nMaxCount);
|
||||||
|
|
||||||
DWORD
|
|
||||||
STDCALL
|
|
||||||
NtUserInvalidateRect(
|
|
||||||
HWND hWnd,
|
|
||||||
CONST RECT *lpRect,
|
|
||||||
BOOL bErase);
|
|
||||||
|
|
||||||
DWORD
|
|
||||||
STDCALL
|
|
||||||
NtUserInvalidateRgn(
|
|
||||||
HWND hWnd,
|
|
||||||
HRGN hRgn,
|
|
||||||
BOOL bErase);
|
|
||||||
|
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
STDCALL
|
STDCALL
|
||||||
|
@ -1575,7 +1555,8 @@ NtUserSetWinEventHook(
|
||||||
BOOL
|
BOOL
|
||||||
STDCALL
|
STDCALL
|
||||||
NtUserShowCaret(
|
NtUserShowCaret(
|
||||||
HWND hWnd);
|
HWND hWnd,
|
||||||
|
BOOL bShow);
|
||||||
|
|
||||||
DWORD
|
DWORD
|
||||||
STDCALL
|
STDCALL
|
||||||
|
@ -1681,9 +1662,6 @@ NtUserUpdateInstance(
|
||||||
DWORD Unknown1,
|
DWORD Unknown1,
|
||||||
DWORD Unknown2);
|
DWORD Unknown2);
|
||||||
|
|
||||||
BOOL STDCALL
|
|
||||||
NtUserUpdateWindow( HWND hWnd );
|
|
||||||
|
|
||||||
DWORD
|
DWORD
|
||||||
STDCALL
|
STDCALL
|
||||||
NtUserUpdateLayeredWindow(
|
NtUserUpdateLayeredWindow(
|
||||||
|
@ -1715,10 +1693,6 @@ STDCALL
|
||||||
NtUserValidateHandleSecure(
|
NtUserValidateHandleSecure(
|
||||||
DWORD Unknown0);
|
DWORD Unknown0);
|
||||||
|
|
||||||
VOID STDCALL
|
|
||||||
NtUserValidateRect(HWND Wnd, const RECT* Rect);
|
|
||||||
|
|
||||||
|
|
||||||
DWORD
|
DWORD
|
||||||
STDCALL
|
STDCALL
|
||||||
NtUserVkKeyScanEx(
|
NtUserVkKeyScanEx(
|
||||||
|
|
|
@ -102,7 +102,7 @@ typedef struct _FDINFO
|
||||||
#define fdinfo_bucket_idx(i) ((i) >> FDINFO_ENTRIES_PER_BUCKET_SHIFT)
|
#define fdinfo_bucket_idx(i) ((i) >> FDINFO_ENTRIES_PER_BUCKET_SHIFT)
|
||||||
/* get position inside a bucket (0-31) from an fd */
|
/* get position inside a bucket (0-31) from an fd */
|
||||||
#define fdinfo_bucket_entry_idx(i) ((i) & (FDINFO_ENTRIES_PER_BUCKET - 1))
|
#define fdinfo_bucket_entry_idx(i) ((i) & (FDINFO_ENTRIES_PER_BUCKET - 1))
|
||||||
/* get bucket ptr. (ptr. to fist fdinfo inside a bucket) from an fd */
|
/* get bucket ptr. (ptr. to first fdinfo inside a bucket) from an fd */
|
||||||
#define fdinfo_bucket(i) ( __pioinfo[fdinfo_bucket_idx(i)])
|
#define fdinfo_bucket(i) ( __pioinfo[fdinfo_bucket_idx(i)])
|
||||||
/* get fdinfo ptr. from an fd */
|
/* get fdinfo ptr. from an fd */
|
||||||
#define fdinfo(i) (fdinfo_bucket(i) + fdinfo_bucket_entry_idx(i))
|
#define fdinfo(i) (fdinfo_bucket(i) + fdinfo_bucket_entry_idx(i))
|
||||||
|
|
|
@ -348,6 +348,12 @@ RtlAddAtomToAtomTable(IN PRTL_ATOM_TABLE AtomTable,
|
||||||
{
|
{
|
||||||
ULONG AtomNameLen = wcslen(AtomName);
|
ULONG AtomNameLen = wcslen(AtomName);
|
||||||
|
|
||||||
|
if (AtomNameLen > MAX_ATOM_LEN)
|
||||||
|
{
|
||||||
|
Status = STATUS_INVALID_PARAMETER;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
Entry = RtlpAllocAtomTableEntry(sizeof(RTL_ATOM_TABLE_ENTRY) -
|
Entry = RtlpAllocAtomTableEntry(sizeof(RTL_ATOM_TABLE_ENTRY) -
|
||||||
sizeof(Entry->Name) +
|
sizeof(Entry->Name) +
|
||||||
(AtomNameLen + 1) * sizeof(WCHAR));
|
(AtomNameLen + 1) * sizeof(WCHAR));
|
||||||
|
@ -390,7 +396,7 @@ RtlAddAtomToAtomTable(IN PRTL_ATOM_TABLE AtomTable,
|
||||||
Status = STATUS_OBJECT_NAME_INVALID;
|
Status = STATUS_OBJECT_NAME_INVALID;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
end:
|
||||||
RtlpUnlockAtomTable(AtomTable);
|
RtlpUnlockAtomTable(AtomTable);
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
|
@ -592,6 +598,8 @@ RtlQueryAtomInAtomTable(PRTL_ATOM_TABLE AtomTable,
|
||||||
PULONG NameLength)
|
PULONG NameLength)
|
||||||
{
|
{
|
||||||
ULONG Length;
|
ULONG Length;
|
||||||
|
BOOL Unlock = FALSE;
|
||||||
|
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
/* A RTL_ATOM_TABLE_ENTRY has a "WCHAR Name[1]" entry at the end.
|
/* A RTL_ATOM_TABLE_ENTRY has a "WCHAR Name[1]" entry at the end.
|
||||||
|
@ -616,6 +624,7 @@ RtlQueryAtomInAtomTable(PRTL_ATOM_TABLE AtomTable,
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
RtlpLockAtomTable(AtomTable);
|
RtlpLockAtomTable(AtomTable);
|
||||||
|
Unlock = TRUE;
|
||||||
|
|
||||||
Entry = RtlpGetAtomEntry(AtomTable,
|
Entry = RtlpGetAtomEntry(AtomTable,
|
||||||
(ULONG)((USHORT)Atom - 0xC000));
|
(ULONG)((USHORT)Atom - 0xC000));
|
||||||
|
@ -676,10 +685,7 @@ RtlQueryAtomInAtomTable(PRTL_ATOM_TABLE AtomTable,
|
||||||
Status = STATUS_INVALID_HANDLE;
|
Status = STATUS_INVALID_HANDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NULL != Entry && Entry != &NumberEntry.AtomTableEntry)
|
if (Unlock) RtlpUnlockAtomTable(AtomTable);
|
||||||
{
|
|
||||||
RtlpUnlockAtomTable(AtomTable);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
|
@ -108,7 +108,7 @@ GetCaretPos(LPPOINT lpPoint)
|
||||||
BOOL STDCALL
|
BOOL STDCALL
|
||||||
HideCaret(HWND hWnd)
|
HideCaret(HWND hWnd)
|
||||||
{
|
{
|
||||||
return (BOOL)NtUserHideCaret(hWnd);
|
return NtUserShowCaret(hWnd, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -139,7 +139,7 @@ SetCaretPos(int X,
|
||||||
BOOL STDCALL
|
BOOL STDCALL
|
||||||
ShowCaret(HWND hWnd)
|
ShowCaret(HWND hWnd)
|
||||||
{
|
{
|
||||||
return (BOOL)NtUserShowCaret(hWnd);
|
return NtUserShowCaret(hWnd, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -87,7 +87,14 @@ static BOOL GetClassInfoExCommon(
|
||||||
|
|
||||||
w.lpszMenuName = (LPCWSTR)&str2;
|
w.lpszMenuName = (LPCWSTR)&str2;
|
||||||
w.lpszClassName = (LPCWSTR)&str3;
|
w.lpszClassName = (LPCWSTR)&str3;
|
||||||
|
|
||||||
|
/* get info about system classes? */
|
||||||
|
if (!hInst) hInst = User32Instance;
|
||||||
|
|
||||||
retval = (BOOL)NtUserGetClassInfo(hInst, str, &w, TRUE, 0);
|
retval = (BOOL)NtUserGetClassInfo(hInst, str, &w, TRUE, 0);
|
||||||
|
|
||||||
|
w.hInstance = (hInst == User32Instance) ? 0 : hInst;
|
||||||
|
|
||||||
if ( !IS_ATOM(str) )
|
if ( !IS_ATOM(str) )
|
||||||
HEAP_free(str);
|
HEAP_free(str);
|
||||||
|
|
||||||
|
|
|
@ -157,7 +157,7 @@ InvalidateRect(
|
||||||
CONST RECT *lpRect,
|
CONST RECT *lpRect,
|
||||||
BOOL bErase)
|
BOOL bErase)
|
||||||
{
|
{
|
||||||
return NtUserInvalidateRect( hWnd, lpRect, bErase );
|
return RedrawWindow( hWnd, lpRect, 0, RDW_INVALIDATE | (bErase ? RDW_ERASE : 0) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -171,7 +171,7 @@ InvalidateRgn(
|
||||||
HRGN hRgn,
|
HRGN hRgn,
|
||||||
BOOL bErase)
|
BOOL bErase)
|
||||||
{
|
{
|
||||||
return NtUserInvalidateRgn( hWnd, hRgn, bErase );
|
return RedrawWindow(hWnd, NULL, hRgn, RDW_INVALIDATE | (bErase ? RDW_ERASE : 0) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -224,7 +224,7 @@ STDCALL
|
||||||
UpdateWindow(
|
UpdateWindow(
|
||||||
HWND hWnd)
|
HWND hWnd)
|
||||||
{
|
{
|
||||||
return NtUserUpdateWindow( hWnd );
|
return RedrawWindow( hWnd, NULL, 0, RDW_UPDATENOW | RDW_ALLCHILDREN );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -237,6 +237,8 @@ ValidateRect(
|
||||||
HWND hWnd,
|
HWND hWnd,
|
||||||
CONST RECT *lpRect)
|
CONST RECT *lpRect)
|
||||||
{
|
{
|
||||||
|
/* FIXME: should RDW_NOCHILDREN be included too? Ros used to,
|
||||||
|
but Wine dont so i removed it... */
|
||||||
return RedrawWindow(hWnd, lpRect, 0, RDW_VALIDATE);
|
return RedrawWindow(hWnd, lpRect, 0, RDW_VALIDATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -250,7 +252,9 @@ ValidateRgn(
|
||||||
HWND hWnd,
|
HWND hWnd,
|
||||||
HRGN hRgn)
|
HRGN hRgn)
|
||||||
{
|
{
|
||||||
return NtUserValidateRgn(hWnd, hRgn);
|
/* FIXME: should RDW_NOCHILDREN be included too? Ros used to,
|
||||||
|
but Wine dont so i removed it... */
|
||||||
|
return RedrawWindow( hWnd, NULL, hRgn, RDW_VALIDATE );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -221,7 +221,7 @@ CreateWindowExA(DWORD dwExStyle,
|
||||||
nHeight,
|
nHeight,
|
||||||
hWndParent,
|
hWndParent,
|
||||||
hMenu,
|
hMenu,
|
||||||
hInstance,
|
hInstance,
|
||||||
lpParam,
|
lpParam,
|
||||||
SW_SHOW,
|
SW_SHOW,
|
||||||
FALSE);
|
FALSE);
|
||||||
|
@ -304,7 +304,7 @@ CreateWindowExW(DWORD dwExStyle,
|
||||||
nHeight,
|
nHeight,
|
||||||
hWndParent,
|
hWndParent,
|
||||||
hMenu,
|
hMenu,
|
||||||
hInstance,
|
hInstance,
|
||||||
lpParam,
|
lpParam,
|
||||||
SW_SHOW,
|
SW_SHOW,
|
||||||
TRUE);
|
TRUE);
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <internal/debug.h>
|
#include <internal/debug.h>
|
||||||
|
|
||||||
|
|
||||||
/* PROTOTYPES ****************************************************************/
|
/* PROTOTYPES ****************************************************************/
|
||||||
|
|
||||||
static PRTL_ATOM_TABLE RtlpGetGlobalAtomTable(VOID);
|
static PRTL_ATOM_TABLE RtlpGetGlobalAtomTable(VOID);
|
||||||
|
@ -38,6 +39,12 @@ RtlQueryAtomListInAtomTable(IN PRTL_ATOM_TABLE AtomTable,
|
||||||
|
|
||||||
/* GLOBALS *******************************************************************/
|
/* GLOBALS *******************************************************************/
|
||||||
|
|
||||||
|
/* FIXME: this is WRONG! The global atom table should live in the WinSta struct
|
||||||
|
* and accessed thru win32k callouts.
|
||||||
|
* NOTE: There is a session/win32k global atom table also, but its private to
|
||||||
|
* win32k. Its used for RegisterWindowMessage() and for window classes.
|
||||||
|
* -Gunnar
|
||||||
|
*/
|
||||||
static PRTL_ATOM_TABLE GlobalAtomTable = NULL;
|
static PRTL_ATOM_TABLE GlobalAtomTable = NULL;
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
typedef struct _WNDCLASS_OBJECT
|
typedef struct _WNDCLASS_OBJECT
|
||||||
{
|
{
|
||||||
UINT cbSize;
|
UINT cbSize;
|
||||||
|
LONG refs; /* windows using this class (is 0 after class creation) */
|
||||||
UINT style;
|
UINT style;
|
||||||
WNDPROC lpfnWndProcA;
|
WNDPROC lpfnWndProcA;
|
||||||
WNDPROC lpfnWndProcW;
|
WNDPROC lpfnWndProcW;
|
||||||
|
@ -21,10 +22,8 @@ typedef struct _WNDCLASS_OBJECT
|
||||||
HICON hIconSm;
|
HICON hIconSm;
|
||||||
BOOL Unicode;
|
BOOL Unicode;
|
||||||
BOOL Global;
|
BOOL Global;
|
||||||
LIST_ENTRY ListEntry;
|
LIST_ENTRY ListEntry; /* linked into owning process */
|
||||||
PCHAR ExtraData;
|
PCHAR ExtraData;
|
||||||
/* list of windows */
|
|
||||||
LIST_ENTRY ClassWindowsListHead;
|
|
||||||
} WNDCLASS_OBJECT, *PWNDCLASS_OBJECT;
|
} WNDCLASS_OBJECT, *PWNDCLASS_OBJECT;
|
||||||
|
|
||||||
NTSTATUS FASTCALL
|
NTSTATUS FASTCALL
|
||||||
|
@ -33,24 +32,26 @@ InitClassImpl(VOID);
|
||||||
NTSTATUS FASTCALL
|
NTSTATUS FASTCALL
|
||||||
CleanupClassImpl(VOID);
|
CleanupClassImpl(VOID);
|
||||||
|
|
||||||
#define ClassDereferenceObject(ClassObj) \
|
void FASTCALL DestroyProcessClasses(PW32PROCESS Process );
|
||||||
ObmDereferenceObject(ClassObj)
|
|
||||||
|
|
||||||
BOOL FASTCALL
|
inline VOID FASTCALL
|
||||||
ClassReferenceClassByAtom(
|
ClassDerefObject(PWNDCLASS_OBJECT Class);
|
||||||
PWNDCLASS_OBJECT* Class,
|
|
||||||
|
inline VOID FASTCALL
|
||||||
|
ClassRefObject(PWNDCLASS_OBJECT Class);
|
||||||
|
|
||||||
|
PWNDCLASS_OBJECT FASTCALL
|
||||||
|
ClassGetClassByAtom(
|
||||||
RTL_ATOM Atom,
|
RTL_ATOM Atom,
|
||||||
HINSTANCE hInstance);
|
HINSTANCE hInstance);
|
||||||
|
|
||||||
BOOL FASTCALL
|
PWNDCLASS_OBJECT FASTCALL
|
||||||
ClassReferenceClassByName(
|
ClassGetClassByName(
|
||||||
PWNDCLASS_OBJECT *Class,
|
|
||||||
LPCWSTR ClassName,
|
LPCWSTR ClassName,
|
||||||
HINSTANCE hInstance);
|
HINSTANCE hInstance);
|
||||||
|
|
||||||
BOOL FASTCALL
|
PWNDCLASS_OBJECT FASTCALL
|
||||||
ClassReferenceClassByNameOrAtom(
|
ClassGetClassByNameOrAtom(
|
||||||
PWNDCLASS_OBJECT *Class,
|
|
||||||
LPCWSTR ClassNameOrAtom,
|
LPCWSTR ClassNameOrAtom,
|
||||||
HINSTANCE hInstance);
|
HINSTANCE hInstance);
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ typedef struct _DESKTOP_OBJECT
|
||||||
CSHORT Type;
|
CSHORT Type;
|
||||||
CSHORT Size;
|
CSHORT Size;
|
||||||
LIST_ENTRY ListEntry;
|
LIST_ENTRY ListEntry;
|
||||||
KSPIN_LOCK Lock;
|
|
||||||
UNICODE_STRING Name;
|
UNICODE_STRING Name;
|
||||||
/* Pointer to the associated window station. */
|
/* Pointer to the associated window station. */
|
||||||
struct _WINSTATION_OBJECT *WindowStation;
|
struct _WINSTATION_OBJECT *WindowStation;
|
||||||
|
|
|
@ -22,7 +22,7 @@ typedef struct _W32THREAD
|
||||||
|
|
||||||
typedef struct _W32PROCESS
|
typedef struct _W32PROCESS
|
||||||
{
|
{
|
||||||
LIST_ENTRY ClassListHead;
|
LIST_ENTRY ClassList;
|
||||||
LIST_ENTRY MenuListHead;
|
LIST_ENTRY MenuListHead;
|
||||||
FAST_MUTEX PrivateFontListLock;
|
FAST_MUTEX PrivateFontListLock;
|
||||||
LIST_ENTRY PrivateFontListHead;
|
LIST_ENTRY PrivateFontListHead;
|
||||||
|
|
|
@ -28,8 +28,6 @@ typedef struct _WINDOW_OBJECT
|
||||||
{
|
{
|
||||||
/* Pointer to the window class. */
|
/* Pointer to the window class. */
|
||||||
PWNDCLASS_OBJECT Class;
|
PWNDCLASS_OBJECT Class;
|
||||||
/* entry in the window list of the class object */
|
|
||||||
LIST_ENTRY ClassListEntry;
|
|
||||||
/* Extended style. */
|
/* Extended style. */
|
||||||
DWORD ExStyle;
|
DWORD ExStyle;
|
||||||
/* Window name. */
|
/* Window name. */
|
||||||
|
|
|
@ -70,7 +70,7 @@ Win32kProcessCallback(struct _EPROCESS *Process,
|
||||||
{
|
{
|
||||||
DPRINT("Creating W32 process PID:%d at IRQ level: %lu\n", Process->UniqueProcessId, KeGetCurrentIrql());
|
DPRINT("Creating W32 process PID:%d at IRQ level: %lu\n", Process->UniqueProcessId, KeGetCurrentIrql());
|
||||||
|
|
||||||
InitializeListHead(&Win32Process->ClassListHead);
|
InitializeListHead(&Win32Process->ClassList);
|
||||||
|
|
||||||
InitializeListHead(&Win32Process->MenuListHead);
|
InitializeListHead(&Win32Process->MenuListHead);
|
||||||
|
|
||||||
|
@ -100,6 +100,8 @@ Win32kProcessCallback(struct _EPROCESS *Process,
|
||||||
IntEngCleanupDriverObjs(Process, Win32Process);
|
IntEngCleanupDriverObjs(Process, Win32Process);
|
||||||
CleanupMonitorImpl();
|
CleanupMonitorImpl();
|
||||||
|
|
||||||
|
/* no process windows should exist at this point, or the function will assert! */
|
||||||
|
DestroyProcessClasses(Win32Process);
|
||||||
|
|
||||||
GDI_CleanupForProcess(Process);
|
GDI_CleanupForProcess(Process);
|
||||||
|
|
||||||
|
|
|
@ -9,17 +9,24 @@
|
||||||
* 10/15/2003 Created
|
* 10/15/2003 Created
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* INCLUDES ******************************************************************/
|
||||||
|
|
||||||
#include <w32k.h>
|
#include <w32k.h>
|
||||||
|
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
|
/* DEFINES *****************************************************************/
|
||||||
|
|
||||||
#define MIN_CARETBLINKRATE 100
|
#define MIN_CARETBLINKRATE 100
|
||||||
#define MAX_CARETBLINKRATE 10000
|
#define MAX_CARETBLINKRATE 10000
|
||||||
#define DEFAULT_CARETBLINKRATE 530
|
#define DEFAULT_CARETBLINKRATE 530
|
||||||
#define CARET_REGKEY L"\\Registry\\User\\.Default\\Control Panel\\Desktop"
|
#define CARET_REGKEY L"\\Registry\\User\\.Default\\Control Panel\\Desktop"
|
||||||
#define CARET_VALUENAME L"CursorBlinkRate"
|
#define CARET_VALUENAME L"CursorBlinkRate"
|
||||||
|
|
||||||
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
|
static
|
||||||
BOOL FASTCALL
|
BOOL FASTCALL
|
||||||
co_IntHideCaret(PTHRDCARETINFO CaretInfo)
|
co_IntHideCaret(PTHRDCARETINFO CaretInfo)
|
||||||
{
|
{
|
||||||
|
@ -69,6 +76,7 @@ IntSetCaretBlinkTime(UINT uMSeconds)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
UINT FASTCALL
|
UINT FASTCALL
|
||||||
IntQueryCaretBlinkRate(VOID)
|
IntQueryCaretBlinkRate(VOID)
|
||||||
{
|
{
|
||||||
|
@ -134,6 +142,7 @@ IntQueryCaretBlinkRate(VOID)
|
||||||
return (UINT)Val;
|
return (UINT)Val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
UINT FASTCALL
|
UINT FASTCALL
|
||||||
IntGetCaretBlinkTime(VOID)
|
IntGetCaretBlinkTime(VOID)
|
||||||
{
|
{
|
||||||
|
@ -158,6 +167,7 @@ IntGetCaretBlinkTime(VOID)
|
||||||
return Ret;
|
return Ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BOOL FASTCALL
|
BOOL FASTCALL
|
||||||
co_IntSetCaretPos(int X, int Y)
|
co_IntSetCaretPos(int X, int Y)
|
||||||
{
|
{
|
||||||
|
@ -197,6 +207,8 @@ IntSwitchCaretShowing(PVOID Info)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0 //unused
|
||||||
|
static
|
||||||
VOID FASTCALL
|
VOID FASTCALL
|
||||||
co_IntDrawCaret(HWND hWnd)
|
co_IntDrawCaret(HWND hWnd)
|
||||||
{
|
{
|
||||||
|
@ -210,9 +222,79 @@ co_IntDrawCaret(HWND hWnd)
|
||||||
ThreadQueue->CaretInfo->Showing = 1;
|
ThreadQueue->CaretInfo->Showing = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
BOOL FASTCALL co_UserHideCaret(PWINDOW_OBJECT Window OPTIONAL)
|
||||||
|
{
|
||||||
|
PUSER_MESSAGE_QUEUE ThreadQueue;
|
||||||
|
|
||||||
|
if (Window) ASSERT_REFS_CO(Window);
|
||||||
|
|
||||||
|
if(Window && Window->OwnerThread != PsGetCurrentThread())
|
||||||
|
{
|
||||||
|
SetLastWin32Error(ERROR_ACCESS_DENIED);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ThreadQueue = (PUSER_MESSAGE_QUEUE)PsGetWin32Thread()->MessageQueue;
|
||||||
|
|
||||||
|
if(Window && ThreadQueue->CaretInfo->hWnd != Window->hSelf)
|
||||||
|
{
|
||||||
|
SetLastWin32Error(ERROR_ACCESS_DENIED);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ThreadQueue->CaretInfo->Visible)
|
||||||
|
{
|
||||||
|
IntKillTimer(ThreadQueue->CaretInfo->hWnd, IDCARETTIMER, TRUE);
|
||||||
|
|
||||||
|
co_IntHideCaret(ThreadQueue->CaretInfo);
|
||||||
|
ThreadQueue->CaretInfo->Visible = 0;
|
||||||
|
ThreadQueue->CaretInfo->Showing = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BOOL FASTCALL co_UserShowCaret(PWINDOW_OBJECT Window OPTIONAL)
|
||||||
|
{
|
||||||
|
PUSER_MESSAGE_QUEUE ThreadQueue;
|
||||||
|
|
||||||
|
if (Window) ASSERT_REFS_CO(Window);
|
||||||
|
|
||||||
|
if(Window && Window->OwnerThread != PsGetCurrentThread())
|
||||||
|
{
|
||||||
|
SetLastWin32Error(ERROR_ACCESS_DENIED);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ThreadQueue = (PUSER_MESSAGE_QUEUE)PsGetWin32Thread()->MessageQueue;
|
||||||
|
|
||||||
|
if(Window && ThreadQueue->CaretInfo->hWnd != Window->hSelf)
|
||||||
|
{
|
||||||
|
SetLastWin32Error(ERROR_ACCESS_DENIED);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!ThreadQueue->CaretInfo->Visible)
|
||||||
|
{
|
||||||
|
ThreadQueue->CaretInfo->Visible = 1;
|
||||||
|
if(!ThreadQueue->CaretInfo->Showing)
|
||||||
|
{
|
||||||
|
co_IntSendMessage(ThreadQueue->CaretInfo->hWnd, WM_SYSTIMER, IDCARETTIMER, 0);
|
||||||
|
}
|
||||||
|
IntSetTimer(ThreadQueue->CaretInfo->hWnd, IDCARETTIMER, IntGetCaretBlinkTime(), NULL, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* SYSCALLS *****************************************************************/
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
STDCALL
|
STDCALL
|
||||||
NtUserCreateCaret(
|
NtUserCreateCaret(
|
||||||
|
@ -317,105 +399,10 @@ CLEANUP:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BOOL FASTCALL co_UserHideCaret(PWINDOW_OBJECT Window OPTIONAL)
|
|
||||||
{
|
|
||||||
PUSER_MESSAGE_QUEUE ThreadQueue;
|
|
||||||
|
|
||||||
if (Window) ASSERT_REFS_CO(Window);
|
|
||||||
|
|
||||||
if(Window && Window->OwnerThread != PsGetCurrentThread())
|
|
||||||
{
|
|
||||||
SetLastWin32Error(ERROR_ACCESS_DENIED);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
ThreadQueue = (PUSER_MESSAGE_QUEUE)PsGetWin32Thread()->MessageQueue;
|
|
||||||
|
|
||||||
if(Window && ThreadQueue->CaretInfo->hWnd != Window->hSelf)
|
|
||||||
{
|
|
||||||
SetLastWin32Error(ERROR_ACCESS_DENIED);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(ThreadQueue->CaretInfo->Visible)
|
|
||||||
{
|
|
||||||
IntKillTimer((Window ? Window->hSelf : 0), IDCARETTIMER, TRUE);
|
|
||||||
|
|
||||||
co_IntHideCaret(ThreadQueue->CaretInfo);
|
|
||||||
ThreadQueue->CaretInfo->Visible = 0;
|
|
||||||
ThreadQueue->CaretInfo->Showing = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
STDCALL
|
STDCALL
|
||||||
NtUserHideCaret(HWND hWnd OPTIONAL)
|
NtUserShowCaret(HWND hWnd OPTIONAL, BOOL bShow)
|
||||||
{
|
|
||||||
PWINDOW_OBJECT Window = NULL;
|
|
||||||
DECLARE_RETURN(BOOL);
|
|
||||||
BOOL ret;
|
|
||||||
|
|
||||||
DPRINT("Enter NtUserHideCaret\n");
|
|
||||||
UserEnterExclusive();
|
|
||||||
|
|
||||||
if(hWnd && !(Window = UserGetWindowObject(hWnd)))
|
|
||||||
{
|
|
||||||
RETURN(FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Window) UserRefObjectCo(Window);
|
|
||||||
ret = co_UserHideCaret(Window);
|
|
||||||
if (Window) UserDerefObjectCo(Window);
|
|
||||||
|
|
||||||
RETURN(ret);
|
|
||||||
|
|
||||||
CLEANUP:
|
|
||||||
DPRINT("Leave NtUserHideCaret, ret=%i\n",_ret_);
|
|
||||||
UserLeave();
|
|
||||||
END_CLEANUP;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
BOOL FASTCALL co_UserShowCaret(PWINDOW_OBJECT Window OPTIONAL)
|
|
||||||
{
|
|
||||||
PUSER_MESSAGE_QUEUE ThreadQueue;
|
|
||||||
|
|
||||||
if (Window) ASSERT_REFS_CO(Window);
|
|
||||||
|
|
||||||
if(Window && Window->OwnerThread != PsGetCurrentThread())
|
|
||||||
{
|
|
||||||
SetLastWin32Error(ERROR_ACCESS_DENIED);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
ThreadQueue = (PUSER_MESSAGE_QUEUE)PsGetWin32Thread()->MessageQueue;
|
|
||||||
|
|
||||||
if(Window && ThreadQueue->CaretInfo->hWnd != Window->hSelf)
|
|
||||||
{
|
|
||||||
SetLastWin32Error(ERROR_ACCESS_DENIED);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!ThreadQueue->CaretInfo->Visible)
|
|
||||||
{
|
|
||||||
ThreadQueue->CaretInfo->Visible = 1;
|
|
||||||
if(!ThreadQueue->CaretInfo->Showing)
|
|
||||||
{
|
|
||||||
co_IntSendMessage(ThreadQueue->CaretInfo->hWnd, WM_SYSTIMER, IDCARETTIMER, 0);
|
|
||||||
}
|
|
||||||
IntSetTimer((Window ? Window->hSelf : 0), IDCARETTIMER, IntGetCaretBlinkTime(), NULL, TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
BOOL
|
|
||||||
STDCALL
|
|
||||||
NtUserShowCaret(HWND hWnd OPTIONAL)
|
|
||||||
{
|
{
|
||||||
PWINDOW_OBJECT Window = NULL;
|
PWINDOW_OBJECT Window = NULL;
|
||||||
DECLARE_RETURN(BOOL);
|
DECLARE_RETURN(BOOL);
|
||||||
|
@ -430,7 +417,12 @@ NtUserShowCaret(HWND hWnd OPTIONAL)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Window) UserRefObjectCo(Window);
|
if (Window) UserRefObjectCo(Window);
|
||||||
ret = co_UserShowCaret(Window);
|
|
||||||
|
if (bShow)
|
||||||
|
ret = co_UserShowCaret(Window);
|
||||||
|
else
|
||||||
|
ret = co_UserHideCaret(Window);
|
||||||
|
|
||||||
if (Window) UserDerefObjectCo(Window);
|
if (Window) UserDerefObjectCo(Window);
|
||||||
|
|
||||||
RETURN(ret);
|
RETURN(ret);
|
||||||
|
|
|
@ -47,64 +47,85 @@ CleanupClassImpl(VOID)
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL FASTCALL
|
|
||||||
ClassReferenceClassByAtom(
|
/* return TRUE if class became destroyed */
|
||||||
PWNDCLASS_OBJECT* Class,
|
inline VOID FASTCALL
|
||||||
RTL_ATOM Atom,
|
ClassDerefObject(PWNDCLASS_OBJECT Class)
|
||||||
HINSTANCE hInstance)
|
|
||||||
{
|
{
|
||||||
PWNDCLASS_OBJECT Current, BestMatch = NULL;
|
ASSERT(Class->refs >= 1);
|
||||||
PLIST_ENTRY CurrentEntry;
|
Class->refs--;
|
||||||
PW32PROCESS Process = PsGetWin32Process();
|
|
||||||
|
|
||||||
CurrentEntry = Process->ClassListHead.Flink;
|
|
||||||
while (CurrentEntry != &Process->ClassListHead)
|
|
||||||
{
|
|
||||||
Current = CONTAINING_RECORD(CurrentEntry, WNDCLASS_OBJECT, ListEntry);
|
|
||||||
|
|
||||||
if (Current->Atom == Atom && (hInstance == NULL || Current->hInstance == hInstance))
|
|
||||||
{
|
|
||||||
*Class = Current;
|
|
||||||
ObmReferenceObject(Current);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Current->Atom == Atom && Current->Global)
|
|
||||||
BestMatch = Current;
|
|
||||||
|
|
||||||
CurrentEntry = CurrentEntry->Flink;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (BestMatch != NULL)
|
|
||||||
{
|
|
||||||
*Class = BestMatch;
|
|
||||||
ObmReferenceObject(BestMatch);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL FASTCALL
|
|
||||||
ClassReferenceClassByName(
|
inline VOID FASTCALL
|
||||||
PWNDCLASS_OBJECT *Class,
|
ClassRefObject(PWNDCLASS_OBJECT Class)
|
||||||
LPCWSTR ClassName,
|
|
||||||
HINSTANCE hInstance)
|
|
||||||
{
|
{
|
||||||
PWINSTATION_OBJECT WinStaObject;
|
ASSERT(Class->refs >= 0);
|
||||||
|
Class->refs++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
VOID FASTCALL DestroyClass(PWNDCLASS_OBJECT Class)
|
||||||
|
{
|
||||||
|
PWINSTATION_OBJECT WinSta;
|
||||||
|
WinSta = PsGetWin32Thread()->Desktop->WindowStation;
|
||||||
|
|
||||||
|
ASSERT(Class->refs == 0);
|
||||||
|
RemoveEntryList(&Class->ListEntry);
|
||||||
|
//FIXME: release ATOM
|
||||||
|
RtlDeleteAtomFromAtomTable(WinSta->AtomTable, Class->Atom);
|
||||||
|
ExFreePool(Class);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* clean all process classes. all process windows must cleaned first!! */
|
||||||
|
void FASTCALL DestroyProcessClasses(PW32PROCESS Process )
|
||||||
|
{
|
||||||
|
PWNDCLASS_OBJECT Class;
|
||||||
|
|
||||||
|
while (!IsListEmpty(&Process->ClassList))
|
||||||
|
{
|
||||||
|
Class = CONTAINING_RECORD(RemoveHeadList(&Process->ClassList), WNDCLASS_OBJECT, ListEntry);
|
||||||
|
DestroyClass(Class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PWNDCLASS_OBJECT FASTCALL
|
||||||
|
ClassGetClassByAtom(RTL_ATOM Atom, HINSTANCE hInstance)
|
||||||
|
{
|
||||||
|
PWNDCLASS_OBJECT Class;
|
||||||
|
PW32PROCESS Process = PsGetWin32Process();
|
||||||
|
|
||||||
|
LIST_FOR_EACH(Class, &Process->ClassList, WNDCLASS_OBJECT, ListEntry)
|
||||||
|
{
|
||||||
|
if (Class->Atom != Atom) continue;
|
||||||
|
|
||||||
|
if (!hInstance || Class->Global || Class->hInstance == hInstance) return Class;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PWNDCLASS_OBJECT FASTCALL
|
||||||
|
ClassGetClassByName(LPCWSTR ClassName, HINSTANCE hInstance)
|
||||||
|
{
|
||||||
|
PWINSTATION_OBJECT WinSta;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
BOOL Found;
|
RTL_ATOM Atom;
|
||||||
RTL_ATOM ClassAtom;
|
|
||||||
|
|
||||||
if (!ClassName || !PsGetWin32Thread()->Desktop)
|
if (!ClassName || !PsGetWin32Thread()->Desktop)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
WinStaObject = PsGetWin32Thread()->Desktop->WindowStation;
|
WinSta = PsGetWin32Thread()->Desktop->WindowStation;
|
||||||
|
|
||||||
Status = RtlLookupAtomInAtomTable(
|
Status = RtlLookupAtomInAtomTable(
|
||||||
WinStaObject->AtomTable,
|
WinSta->AtomTable,
|
||||||
(LPWSTR)ClassName,
|
(LPWSTR)ClassName,
|
||||||
&ClassAtom);
|
&Atom);
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
@ -112,369 +133,136 @@ ClassReferenceClassByName(
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
Found = ClassReferenceClassByAtom(Class, ClassAtom, hInstance);
|
return ClassGetClassByAtom(Atom, hInstance);
|
||||||
|
|
||||||
return Found;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL FASTCALL
|
|
||||||
ClassReferenceClassByNameOrAtom(
|
|
||||||
PWNDCLASS_OBJECT *Class,
|
|
||||||
LPCWSTR ClassNameOrAtom,
|
|
||||||
HINSTANCE hInstance)
|
|
||||||
{
|
|
||||||
BOOL Found;
|
|
||||||
|
|
||||||
if (IS_ATOM(ClassNameOrAtom))
|
|
||||||
Found = ClassReferenceClassByAtom(Class, (RTL_ATOM)((ULONG_PTR)ClassNameOrAtom), hInstance);
|
|
||||||
else
|
|
||||||
Found = ClassReferenceClassByName(Class, ClassNameOrAtom, hInstance);
|
|
||||||
|
|
||||||
return Found;
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD STDCALL
|
|
||||||
NtUserGetClassInfo(
|
|
||||||
HINSTANCE hInstance,
|
|
||||||
LPCWSTR lpClassName,
|
|
||||||
LPWNDCLASSEXW lpWndClassEx,
|
|
||||||
BOOL Ansi,
|
|
||||||
DWORD unknown3)
|
|
||||||
{
|
|
||||||
PWNDCLASS_OBJECT Class;
|
|
||||||
RTL_ATOM Atom;
|
|
||||||
DECLARE_RETURN(DWORD);
|
|
||||||
|
|
||||||
if (IS_ATOM(lpClassName))
|
|
||||||
DPRINT("NtUserGetClassInfo - %x (%lx)\n", lpClassName, hInstance);
|
|
||||||
else
|
|
||||||
DPRINT("NtUserGetClassInfo - %S (%lx)\n", lpClassName, hInstance);
|
|
||||||
|
|
||||||
UserEnterExclusive();
|
|
||||||
|
|
||||||
if (!ClassReferenceClassByNameOrAtom(&Class, lpClassName, hInstance))
|
|
||||||
{
|
|
||||||
SetLastWin32Error(ERROR_CLASS_DOES_NOT_EXIST);
|
|
||||||
RETURN(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
lpWndClassEx->cbSize = sizeof(WNDCLASSEXW);
|
|
||||||
lpWndClassEx->style = Class->style;
|
|
||||||
if (Ansi)
|
|
||||||
lpWndClassEx->lpfnWndProc = Class->lpfnWndProcA;
|
|
||||||
else
|
|
||||||
lpWndClassEx->lpfnWndProc = Class->lpfnWndProcW;
|
|
||||||
lpWndClassEx->cbClsExtra = Class->cbClsExtra;
|
|
||||||
lpWndClassEx->cbWndExtra = Class->cbWndExtra;
|
|
||||||
/* This is not typo, we're really not going to use Class->hInstance here. */
|
|
||||||
lpWndClassEx->hInstance = hInstance;
|
|
||||||
lpWndClassEx->hIcon = Class->hIcon;
|
|
||||||
lpWndClassEx->hCursor = Class->hCursor;
|
|
||||||
lpWndClassEx->hbrBackground = Class->hbrBackground;
|
|
||||||
if (Class->lpszMenuName.MaximumLength)
|
|
||||||
RtlCopyUnicodeString((PUNICODE_STRING)lpWndClassEx->lpszMenuName, &Class->lpszMenuName);
|
|
||||||
else
|
|
||||||
lpWndClassEx->lpszMenuName = Class->lpszMenuName.Buffer;
|
|
||||||
lpWndClassEx->lpszClassName = lpClassName;
|
|
||||||
lpWndClassEx->hIconSm = Class->hIconSm;
|
|
||||||
Atom = Class->Atom;
|
|
||||||
|
|
||||||
ObmDereferenceObject(Class);
|
|
||||||
|
|
||||||
RETURN(Atom);
|
|
||||||
|
|
||||||
CLEANUP:
|
|
||||||
DPRINT("Leave NtUserGetClassInfo, ret=%i\n",_ret_);
|
|
||||||
UserLeave();
|
|
||||||
END_CLEANUP;
|
|
||||||
}
|
|
||||||
|
|
||||||
ULONG FASTCALL
|
|
||||||
IntGetClassName(struct _WINDOW_OBJECT *WindowObject, LPWSTR lpClassName,
|
|
||||||
ULONG nMaxCount)
|
|
||||||
{
|
|
||||||
ULONG Length;
|
|
||||||
LPWSTR Name;
|
|
||||||
PWINSTATION_OBJECT WinStaObject;
|
|
||||||
NTSTATUS Status;
|
|
||||||
|
|
||||||
if(!PsGetWin32Thread()->Desktop)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
WinStaObject = PsGetWin32Thread()->Desktop->WindowStation;
|
|
||||||
|
|
||||||
Length = 0;
|
|
||||||
Status = RtlQueryAtomInAtomTable(WinStaObject->AtomTable,
|
|
||||||
WindowObject->Class->Atom, NULL, NULL,
|
|
||||||
NULL, &Length);
|
|
||||||
Length += sizeof(WCHAR);
|
|
||||||
Name = ExAllocatePoolWithTag(PagedPool, Length, TAG_STRING);
|
|
||||||
Status = RtlQueryAtomInAtomTable(WinStaObject->AtomTable,
|
|
||||||
WindowObject->Class->Atom, NULL, NULL,
|
|
||||||
Name, &Length);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT("IntGetClassName: RtlQueryAtomInAtomTable failed\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
Length /= sizeof(WCHAR);
|
|
||||||
if (Length > nMaxCount)
|
|
||||||
{
|
|
||||||
Length = nMaxCount;
|
|
||||||
}
|
|
||||||
wcsncpy(lpClassName, Name, Length);
|
|
||||||
/* FIXME: Check buffer size before doing this! */
|
|
||||||
*(lpClassName + Length) = 0;
|
|
||||||
ExFreePool(Name);
|
|
||||||
|
|
||||||
return Length;
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD STDCALL
|
|
||||||
NtUserGetClassName (
|
|
||||||
HWND hWnd,
|
|
||||||
LPWSTR lpClassName,
|
|
||||||
ULONG nMaxCount)
|
|
||||||
{
|
|
||||||
PWINDOW_OBJECT Window;
|
|
||||||
DECLARE_RETURN(DWORD);
|
|
||||||
|
|
||||||
UserEnterShared();
|
|
||||||
DPRINT("Enter NtUserGetClassName\n");
|
|
||||||
|
|
||||||
if (!(Window = UserGetWindowObject(hWnd)))
|
|
||||||
{
|
|
||||||
RETURN(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN( IntGetClassName(Window, lpClassName, nMaxCount));
|
|
||||||
|
|
||||||
CLEANUP:
|
|
||||||
DPRINT("Leave NtUserGetClassName, ret=%i\n",_ret_);
|
|
||||||
UserLeave();
|
|
||||||
END_CLEANUP;
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD STDCALL
|
|
||||||
NtUserGetWOWClass(DWORD Unknown0,
|
|
||||||
DWORD Unknown1)
|
|
||||||
{
|
|
||||||
UNIMPLEMENTED;
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
PWNDCLASS_OBJECT FASTCALL
|
PWNDCLASS_OBJECT FASTCALL
|
||||||
IntCreateClass(
|
ClassGetClassByNameOrAtom(LPCWSTR ClassNameOrAtom, HINSTANCE hInstance)
|
||||||
|
{
|
||||||
|
if (!ClassNameOrAtom) return NULL;
|
||||||
|
|
||||||
|
if (IS_ATOM(ClassNameOrAtom))
|
||||||
|
return ClassGetClassByAtom((RTL_ATOM)((ULONG_PTR)ClassNameOrAtom), hInstance);
|
||||||
|
else
|
||||||
|
return ClassGetClassByName(ClassNameOrAtom, hInstance);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static
|
||||||
|
BOOL FASTCALL
|
||||||
|
IntRegisterClass(
|
||||||
CONST WNDCLASSEXW *lpwcx,
|
CONST WNDCLASSEXW *lpwcx,
|
||||||
DWORD Flags,
|
DWORD Flags,
|
||||||
WNDPROC wpExtra,
|
WNDPROC wpExtra,
|
||||||
PUNICODE_STRING MenuName,
|
PUNICODE_STRING MenuName,
|
||||||
RTL_ATOM Atom)
|
RTL_ATOM Atom)
|
||||||
{
|
{
|
||||||
PWNDCLASS_OBJECT ClassObject;
|
PWNDCLASS_OBJECT Class;
|
||||||
ULONG objectSize;
|
ULONG objectSize;
|
||||||
BOOL Global;
|
BOOL Global;
|
||||||
|
|
||||||
Global = (Flags & REGISTERCLASS_SYSTEM) || (lpwcx->style & CS_GLOBALCLASS) ? TRUE : FALSE;
|
ASSERT(lpwcx);
|
||||||
|
ASSERT(Atom);
|
||||||
|
ASSERT(lpwcx->hInstance);
|
||||||
|
|
||||||
|
Global = (Flags & REGISTERCLASS_SYSTEM) || (lpwcx->style & CS_GLOBALCLASS);
|
||||||
|
|
||||||
/* Check for double registration of the class. */
|
/* Check for double registration of the class. */
|
||||||
if (PsGetWin32Process() != NULL)
|
Class = ClassGetClassByAtom(Atom, lpwcx->hInstance);
|
||||||
|
if (Class && Global == Class->Global)
|
||||||
{
|
{
|
||||||
if (ClassReferenceClassByAtom(&ClassObject, Atom, lpwcx->hInstance))
|
/* can max have one class of each type (global/local) */
|
||||||
{
|
SetLastWin32Error(ERROR_CLASS_ALREADY_EXISTS);
|
||||||
/*
|
return(FALSE);
|
||||||
* NOTE: We may also get a global class from
|
|
||||||
* ClassReferenceClassByAtom. This simple check
|
|
||||||
* prevents that we fail valid request.
|
|
||||||
*/
|
|
||||||
if (ClassObject->hInstance == lpwcx->hInstance)
|
|
||||||
{
|
|
||||||
SetLastWin32Error(ERROR_CLASS_ALREADY_EXISTS);
|
|
||||||
ObmDereferenceObject(ClassObject);
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
objectSize = sizeof(WNDCLASS_OBJECT) + lpwcx->cbClsExtra;
|
objectSize = sizeof(WNDCLASS_OBJECT) + lpwcx->cbClsExtra;
|
||||||
ClassObject = ObmCreateObject(&gHandleTable, NULL, otClass, objectSize);
|
|
||||||
if (ClassObject == 0)
|
//FIXME: allocate in session heap (or possibly desktop heap)
|
||||||
|
Class = ExAllocatePool(PagedPool, objectSize);
|
||||||
|
if (!Class)
|
||||||
{
|
{
|
||||||
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
|
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
|
||||||
return(NULL);
|
return(FALSE);
|
||||||
}
|
}
|
||||||
|
RtlZeroMemory(Class, objectSize);
|
||||||
|
|
||||||
|
Class->cbSize = lpwcx->cbSize;
|
||||||
|
Class->style = lpwcx->style;
|
||||||
|
Class->cbClsExtra = lpwcx->cbClsExtra;
|
||||||
|
Class->cbWndExtra = lpwcx->cbWndExtra;
|
||||||
|
Class->hInstance = lpwcx->hInstance;
|
||||||
|
Class->hIcon = lpwcx->hIcon;
|
||||||
|
Class->hCursor = lpwcx->hCursor;
|
||||||
|
Class->hbrBackground = lpwcx->hbrBackground;
|
||||||
|
Class->Unicode = !(Flags & REGISTERCLASS_ANSI);
|
||||||
|
Class->Global = Global;
|
||||||
|
Class->hIconSm = lpwcx->hIconSm;
|
||||||
|
Class->Atom = Atom;
|
||||||
|
|
||||||
ClassObject->cbSize = lpwcx->cbSize;
|
|
||||||
ClassObject->style = lpwcx->style;
|
|
||||||
ClassObject->cbClsExtra = lpwcx->cbClsExtra;
|
|
||||||
ClassObject->cbWndExtra = lpwcx->cbWndExtra;
|
|
||||||
ClassObject->hInstance = lpwcx->hInstance;
|
|
||||||
ClassObject->hIcon = lpwcx->hIcon;
|
|
||||||
ClassObject->hCursor = lpwcx->hCursor;
|
|
||||||
ClassObject->hbrBackground = lpwcx->hbrBackground;
|
|
||||||
ClassObject->Unicode = !(Flags & REGISTERCLASS_ANSI);
|
|
||||||
ClassObject->Global = Global;
|
|
||||||
ClassObject->hIconSm = lpwcx->hIconSm;
|
|
||||||
ClassObject->Atom = Atom;
|
|
||||||
if (wpExtra == NULL)
|
if (wpExtra == NULL)
|
||||||
{
|
{
|
||||||
if (Flags & REGISTERCLASS_ANSI)
|
if (Flags & REGISTERCLASS_ANSI)
|
||||||
{
|
{
|
||||||
ClassObject->lpfnWndProcA = lpwcx->lpfnWndProc;
|
Class->lpfnWndProcA = lpwcx->lpfnWndProc;
|
||||||
ClassObject->lpfnWndProcW = (WNDPROC)IntAddWndProcHandle(lpwcx->lpfnWndProc,FALSE);
|
Class->lpfnWndProcW = (WNDPROC)IntAddWndProcHandle(lpwcx->lpfnWndProc,FALSE);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ClassObject->lpfnWndProcW = lpwcx->lpfnWndProc;
|
Class->lpfnWndProcW = lpwcx->lpfnWndProc;
|
||||||
ClassObject->lpfnWndProcA = (WNDPROC)IntAddWndProcHandle(lpwcx->lpfnWndProc,TRUE);
|
Class->lpfnWndProcA = (WNDPROC)IntAddWndProcHandle(lpwcx->lpfnWndProc,TRUE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (Flags & REGISTERCLASS_ANSI)
|
if (Flags & REGISTERCLASS_ANSI)
|
||||||
{
|
{
|
||||||
ClassObject->lpfnWndProcA = lpwcx->lpfnWndProc;
|
Class->lpfnWndProcA = lpwcx->lpfnWndProc;
|
||||||
ClassObject->lpfnWndProcW = wpExtra;
|
Class->lpfnWndProcW = wpExtra;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ClassObject->lpfnWndProcW = lpwcx->lpfnWndProc;
|
Class->lpfnWndProcW = lpwcx->lpfnWndProc;
|
||||||
ClassObject->lpfnWndProcA = wpExtra;
|
Class->lpfnWndProcA = wpExtra;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MenuName->Length == 0)
|
if (MenuName->Length == 0)
|
||||||
{
|
{
|
||||||
ClassObject->lpszMenuName.Length =
|
Class->lpszMenuName.Length =
|
||||||
ClassObject->lpszMenuName.MaximumLength = 0;
|
Class->lpszMenuName.MaximumLength = 0;
|
||||||
ClassObject->lpszMenuName.Buffer = MenuName->Buffer;
|
Class->lpszMenuName.Buffer = MenuName->Buffer;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ClassObject->lpszMenuName.Length =
|
Class->lpszMenuName.Length =
|
||||||
ClassObject->lpszMenuName.MaximumLength = MenuName->MaximumLength;
|
Class->lpszMenuName.MaximumLength = MenuName->MaximumLength;
|
||||||
ClassObject->lpszMenuName.Buffer = ExAllocatePoolWithTag(PagedPool, ClassObject->lpszMenuName.MaximumLength, TAG_STRING);
|
Class->lpszMenuName.Buffer = ExAllocatePoolWithTag(PagedPool, Class->lpszMenuName.MaximumLength, TAG_STRING);
|
||||||
RtlCopyUnicodeString(&ClassObject->lpszMenuName, MenuName);
|
RtlCopyUnicodeString(&Class->lpszMenuName, MenuName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Extra class data */
|
/* Extra class data */
|
||||||
if (ClassObject->cbClsExtra != 0)
|
if (Class->cbClsExtra)
|
||||||
|
Class->ExtraData = (PCHAR)(Class + 1);
|
||||||
|
|
||||||
|
if (Global)
|
||||||
{
|
{
|
||||||
ClassObject->ExtraData = (PCHAR)(ClassObject + 1);
|
/* global classes go last (incl. system classes) */
|
||||||
RtlZeroMemory(ClassObject->ExtraData, (ULONG)ClassObject->cbClsExtra);
|
InsertTailList(&PsGetWin32Process()->ClassList, &Class->ListEntry);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ClassObject->ExtraData = NULL;
|
/* local classes have priority so we put them first */
|
||||||
|
InsertHeadList(&PsGetWin32Process()->ClassList, &Class->ListEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
InitializeListHead(&ClassObject->ClassWindowsListHead);
|
return TRUE;
|
||||||
|
|
||||||
return(ClassObject);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RTL_ATOM STDCALL
|
|
||||||
NtUserRegisterClassExWOW(
|
|
||||||
CONST WNDCLASSEXW* lpwcx,
|
|
||||||
PUNICODE_STRING ClassName,
|
|
||||||
PUNICODE_STRING ClassNameCopy,
|
|
||||||
PUNICODE_STRING MenuName,
|
|
||||||
WNDPROC wpExtra, /* FIXME: Windows uses this parameter for something different. */
|
|
||||||
DWORD Flags,
|
|
||||||
DWORD Unknown7)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* FUNCTION:
|
|
||||||
* Registers a new class with the window manager
|
|
||||||
* ARGUMENTS:
|
|
||||||
* lpwcx = Win32 extended window class structure
|
|
||||||
* bUnicodeClass = Whether to send ANSI or unicode strings
|
|
||||||
* to window procedures
|
|
||||||
* wpExtra = Extra window procedure, if this is not null, its used for the second window procedure for standard controls.
|
|
||||||
* RETURNS:
|
|
||||||
* Atom identifying the new class
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
WNDCLASSEXW SafeClass;
|
|
||||||
PWINSTATION_OBJECT WinStaObject;
|
|
||||||
PWNDCLASS_OBJECT ClassObject;
|
|
||||||
NTSTATUS Status;
|
|
||||||
RTL_ATOM Atom;
|
|
||||||
DECLARE_RETURN(RTL_ATOM);
|
|
||||||
|
|
||||||
DPRINT("Enter NtUserRegisterClassExWOW\n");
|
|
||||||
UserEnterExclusive();
|
|
||||||
|
|
||||||
if (!lpwcx)
|
|
||||||
{
|
|
||||||
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
|
||||||
RETURN( (RTL_ATOM)0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Flags & ~REGISTERCLASS_ALL)
|
|
||||||
{
|
|
||||||
SetLastWin32Error(ERROR_INVALID_FLAGS);
|
|
||||||
RETURN( (RTL_ATOM)0);
|
|
||||||
}
|
|
||||||
|
|
||||||
Status = MmCopyFromCaller(&SafeClass, lpwcx, sizeof(WNDCLASSEXW));
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
SetLastNtError(Status);
|
|
||||||
RETURN( (RTL_ATOM)0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Deny negative sizes */
|
|
||||||
if (lpwcx->cbClsExtra < 0 || lpwcx->cbWndExtra < 0)
|
|
||||||
{
|
|
||||||
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
|
||||||
RETURN( (RTL_ATOM)0);
|
|
||||||
}
|
|
||||||
|
|
||||||
WinStaObject = PsGetWin32Thread()->Desktop->WindowStation;
|
|
||||||
|
|
||||||
if (ClassName->Length > 0)
|
|
||||||
{
|
|
||||||
DPRINT("NtUserRegisterClassExWOW(%S)\n", ClassName->Buffer);
|
|
||||||
/* FIXME - Safely copy/verify the buffer first!!! */
|
|
||||||
Status = RtlAddAtomToAtomTable(WinStaObject->AtomTable,
|
|
||||||
ClassName->Buffer,
|
|
||||||
&Atom);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT1("Failed adding class name (%S) to atom table\n",
|
|
||||||
ClassName->Buffer);
|
|
||||||
SetLastNtError(Status);
|
|
||||||
RETURN((RTL_ATOM)0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Atom = (RTL_ATOM)(ULONG)ClassName->Buffer;
|
|
||||||
}
|
|
||||||
ClassObject = IntCreateClass(&SafeClass, Flags, wpExtra, MenuName, Atom);
|
|
||||||
if (ClassObject == NULL)
|
|
||||||
{
|
|
||||||
if (ClassName->Length)
|
|
||||||
{
|
|
||||||
RtlDeleteAtomFromAtomTable(WinStaObject->AtomTable, Atom);
|
|
||||||
}
|
|
||||||
DPRINT("Failed creating window class object\n");
|
|
||||||
RETURN((RTL_ATOM)0);
|
|
||||||
}
|
|
||||||
|
|
||||||
InsertTailList(&PsGetWin32Process()->ClassListHead, &ClassObject->ListEntry);
|
|
||||||
|
|
||||||
RETURN(Atom);
|
|
||||||
|
|
||||||
CLEANUP:
|
|
||||||
DPRINT("Leave NtUserRegisterClassExWOW, ret=%i\n",_ret_);
|
|
||||||
UserLeave();
|
|
||||||
END_CLEANUP;
|
|
||||||
}
|
|
||||||
|
|
||||||
ULONG FASTCALL
|
ULONG FASTCALL
|
||||||
IntGetClassLong(struct _WINDOW_OBJECT *Window, ULONG Offset, BOOL Ansi)
|
IntGetClassLong(PWINDOW_OBJECT Window, ULONG Offset, BOOL Ansi)
|
||||||
{
|
{
|
||||||
LONG Ret;
|
LONG Ret;
|
||||||
|
|
||||||
|
@ -540,28 +328,7 @@ IntGetClassLong(struct _WINDOW_OBJECT *Window, ULONG Offset, BOOL Ansi)
|
||||||
return(Ret);
|
return(Ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD STDCALL
|
static
|
||||||
NtUserGetClassLong(HWND hWnd, DWORD Offset, BOOL Ansi)
|
|
||||||
{
|
|
||||||
PWINDOW_OBJECT Window;
|
|
||||||
DECLARE_RETURN(DWORD);
|
|
||||||
|
|
||||||
DPRINT("Enter NtUserGetClassLong\n");
|
|
||||||
UserEnterExclusive();
|
|
||||||
|
|
||||||
if (!(Window = UserGetWindowObject(hWnd)))
|
|
||||||
{
|
|
||||||
RETURN(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN(IntGetClassLong(Window, Offset, Ansi));
|
|
||||||
|
|
||||||
CLEANUP:
|
|
||||||
DPRINT("Leave NtUserGetClassLong, ret=%i\n",_ret_);
|
|
||||||
UserLeave();
|
|
||||||
END_CLEANUP;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FASTCALL
|
void FASTCALL
|
||||||
co_IntSetClassLong(PWINDOW_OBJECT Window, ULONG Offset, LONG dwNewLong, BOOL Ansi)
|
co_IntSetClassLong(PWINDOW_OBJECT Window, ULONG Offset, LONG dwNewLong, BOOL Ansi)
|
||||||
{
|
{
|
||||||
|
@ -643,6 +410,144 @@ co_IntSetClassLong(PWINDOW_OBJECT Window, ULONG Offset, LONG dwNewLong, BOOL Ans
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* SYSCALLS *****************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
RTL_ATOM STDCALL
|
||||||
|
NtUserRegisterClassExWOW(
|
||||||
|
CONST WNDCLASSEXW* lpwcx,
|
||||||
|
PUNICODE_STRING ClassName,
|
||||||
|
PUNICODE_STRING ClassNameCopy,//huhuhuhu???
|
||||||
|
PUNICODE_STRING MenuName,
|
||||||
|
WNDPROC wpExtra,
|
||||||
|
DWORD Flags,
|
||||||
|
DWORD Unknown7)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* FUNCTION:
|
||||||
|
* Registers a new class with the window manager
|
||||||
|
* ARGUMENTS:
|
||||||
|
* lpwcx = Win32 extended window class structure
|
||||||
|
* bUnicodeClass = Whether to send ANSI or unicode strings
|
||||||
|
* to window procedures
|
||||||
|
* wpExtra = Extra window procedure, if this is not null, its used for the second window procedure for standard controls.
|
||||||
|
* RETURNS:
|
||||||
|
* Atom identifying the new class
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
WNDCLASSEXW SafeClass;
|
||||||
|
PWINSTATION_OBJECT WinSta;
|
||||||
|
NTSTATUS Status;
|
||||||
|
RTL_ATOM Atom;
|
||||||
|
DECLARE_RETURN(RTL_ATOM);
|
||||||
|
|
||||||
|
DPRINT("Enter NtUserRegisterClassExWOW\n");
|
||||||
|
UserEnterExclusive();
|
||||||
|
|
||||||
|
if (!lpwcx)
|
||||||
|
{
|
||||||
|
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
||||||
|
RETURN( (RTL_ATOM)0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Flags & ~REGISTERCLASS_ALL)
|
||||||
|
{
|
||||||
|
SetLastWin32Error(ERROR_INVALID_FLAGS);
|
||||||
|
RETURN( (RTL_ATOM)0);
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = MmCopyFromCaller(&SafeClass, lpwcx, sizeof(WNDCLASSEXW));
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
SetLastNtError(Status);
|
||||||
|
RETURN( (RTL_ATOM)0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Deny negative sizes */
|
||||||
|
if (lpwcx->cbClsExtra < 0 || lpwcx->cbWndExtra < 0)
|
||||||
|
{
|
||||||
|
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
||||||
|
RETURN( (RTL_ATOM)0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!lpwcx->hInstance)
|
||||||
|
{
|
||||||
|
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
||||||
|
RETURN( (RTL_ATOM)0);
|
||||||
|
}
|
||||||
|
|
||||||
|
WinSta = PsGetWin32Thread()->Desktop->WindowStation;
|
||||||
|
|
||||||
|
//FIXME: make ClassName ptr the atom, not buffer
|
||||||
|
if (ClassName->Length > 0)
|
||||||
|
{
|
||||||
|
DPRINT("NtUserRegisterClassExWOW(%S)\n", ClassName->Buffer);
|
||||||
|
/* FIXME - Safely copy/verify the buffer first!!! */
|
||||||
|
Status = RtlAddAtomToAtomTable(WinSta->AtomTable,
|
||||||
|
ClassName->Buffer,
|
||||||
|
&Atom);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("Failed adding class name (%S) to atom table\n",
|
||||||
|
ClassName->Buffer);
|
||||||
|
SetLastNtError(Status);
|
||||||
|
RETURN((RTL_ATOM)0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Atom = (RTL_ATOM)(ULONG)ClassName->Buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Atom)
|
||||||
|
{
|
||||||
|
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
||||||
|
RETURN(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!IntRegisterClass(&SafeClass, Flags, wpExtra, MenuName, Atom))
|
||||||
|
{
|
||||||
|
if (ClassName->Length)
|
||||||
|
{
|
||||||
|
RtlDeleteAtomFromAtomTable(WinSta->AtomTable, Atom);
|
||||||
|
}
|
||||||
|
DPRINT("Failed creating window class object\n");
|
||||||
|
RETURN((RTL_ATOM)0);
|
||||||
|
}
|
||||||
|
|
||||||
|
RETURN(Atom);
|
||||||
|
|
||||||
|
CLEANUP:
|
||||||
|
DPRINT("Leave NtUserRegisterClassExWOW, ret=%i\n",_ret_);
|
||||||
|
UserLeave();
|
||||||
|
END_CLEANUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
DWORD STDCALL
|
||||||
|
NtUserGetClassLong(HWND hWnd, DWORD Offset, BOOL Ansi)
|
||||||
|
{
|
||||||
|
PWINDOW_OBJECT Window;
|
||||||
|
DECLARE_RETURN(DWORD);
|
||||||
|
|
||||||
|
DPRINT("Enter NtUserGetClassLong\n");
|
||||||
|
UserEnterExclusive();
|
||||||
|
|
||||||
|
if (!(Window = UserGetWindowObject(hWnd)))
|
||||||
|
{
|
||||||
|
RETURN(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
RETURN(IntGetClassLong(Window, Offset, Ansi));
|
||||||
|
|
||||||
|
CLEANUP:
|
||||||
|
DPRINT("Leave NtUserGetClassLong, ret=%i\n",_ret_);
|
||||||
|
UserLeave();
|
||||||
|
END_CLEANUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
DWORD STDCALL
|
DWORD STDCALL
|
||||||
NtUserSetClassLong(HWND hWnd,
|
NtUserSetClassLong(HWND hWnd,
|
||||||
|
@ -689,56 +594,50 @@ NtUserSetClassWord(DWORD Unknown0,
|
||||||
BOOL STDCALL
|
BOOL STDCALL
|
||||||
NtUserUnregisterClass(
|
NtUserUnregisterClass(
|
||||||
LPCWSTR ClassNameOrAtom,
|
LPCWSTR ClassNameOrAtom,
|
||||||
HINSTANCE hInstance,
|
HINSTANCE hInstance, /* can be 0 */
|
||||||
DWORD Unknown)
|
DWORD Unknown)
|
||||||
{
|
{
|
||||||
PWNDCLASS_OBJECT Class;
|
PWNDCLASS_OBJECT Class;
|
||||||
PWINSTATION_OBJECT WinSta;
|
|
||||||
DECLARE_RETURN(BOOL);
|
DECLARE_RETURN(BOOL);
|
||||||
|
|
||||||
DPRINT("Enter NtUserUnregisterClass(%S)\n", ClassNameOrAtom);
|
DPRINT("Enter NtUserUnregisterClass(%S)\n", ClassNameOrAtom);
|
||||||
UserEnterExclusive();
|
UserEnterExclusive();
|
||||||
|
|
||||||
if (!ClassNameOrAtom || !PsGetWin32Thread()->Desktop)
|
if (!ClassNameOrAtom)
|
||||||
{
|
|
||||||
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
|
||||||
RETURN( FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
WinSta = PsGetWin32Thread()->Desktop->WindowStation;
|
|
||||||
|
|
||||||
if (!ClassReferenceClassByNameOrAtom(&Class, ClassNameOrAtom, hInstance))
|
|
||||||
{
|
{
|
||||||
SetLastWin32Error(ERROR_CLASS_DOES_NOT_EXIST);
|
SetLastWin32Error(ERROR_CLASS_DOES_NOT_EXIST);
|
||||||
RETURN( FALSE);
|
RETURN(FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Class->hInstance && Class->hInstance != hInstance)
|
if (!(Class = ClassGetClassByNameOrAtom(ClassNameOrAtom, hInstance)))
|
||||||
{
|
{
|
||||||
ClassDereferenceObject(Class);
|
|
||||||
SetLastWin32Error(ERROR_CLASS_DOES_NOT_EXIST);
|
SetLastWin32Error(ERROR_CLASS_DOES_NOT_EXIST);
|
||||||
RETURN( FALSE);
|
RETURN(FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!IsListEmpty(&Class->ClassWindowsListHead))
|
/* this was probably ment to prevent sysclass dereg
|
||||||
|
Seems wrong. Any class can have NULL hInst, not only sysclasses
|
||||||
|
|
||||||
|
*/
|
||||||
|
// if (Class->hInstance && Class->hInstance != hInstance)
|
||||||
|
// {
|
||||||
|
// SetLastWin32Error(ERROR_CLASS_DOES_NOT_EXIST);
|
||||||
|
// RETURN( FALSE);
|
||||||
|
// }
|
||||||
|
|
||||||
|
if (Class->refs)
|
||||||
{
|
{
|
||||||
/* Dereference the ClassReferenceClassByNameOrAtom() call */
|
/* NOTE: the class will not be freed when its refs become 0 ie. no more
|
||||||
ObmDereferenceObject(Class);
|
* windows are using it. I dunno why that is but its how Windows does it (and Wine).
|
||||||
|
* The class will hang around until the process exit. -Gunnar
|
||||||
|
*/
|
||||||
SetLastWin32Error(ERROR_CLASS_HAS_WINDOWS);
|
SetLastWin32Error(ERROR_CLASS_HAS_WINDOWS);
|
||||||
RETURN( FALSE);
|
RETURN(FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Dereference the ClassReferenceClassByNameOrAtom() call */
|
DestroyClass(Class);
|
||||||
ClassDereferenceObject(Class);
|
|
||||||
|
|
||||||
RemoveEntryList(&Class->ListEntry);
|
RETURN(TRUE);
|
||||||
|
|
||||||
RtlDeleteAtomFromAtomTable(WinSta->AtomTable, Class->Atom);
|
|
||||||
|
|
||||||
/* Free the object */
|
|
||||||
ClassDereferenceObject(Class);
|
|
||||||
|
|
||||||
RETURN( TRUE);
|
|
||||||
|
|
||||||
CLEANUP:
|
CLEANUP:
|
||||||
DPRINT("Leave NtUserUnregisterClass, ret=%i\n",_ret_);
|
DPRINT("Leave NtUserUnregisterClass, ret=%i\n",_ret_);
|
||||||
|
@ -746,4 +645,119 @@ CLEANUP:
|
||||||
END_CLEANUP;
|
END_CLEANUP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* NOTE: for system classes hInstance is not NULL here, but User32Instance */
|
||||||
|
DWORD STDCALL
|
||||||
|
NtUserGetClassInfo(
|
||||||
|
HINSTANCE hInstance,
|
||||||
|
LPCWSTR lpClassName,
|
||||||
|
LPWNDCLASSEXW lpWndClassEx,
|
||||||
|
BOOL Ansi,
|
||||||
|
DWORD unknown3)
|
||||||
|
{
|
||||||
|
PWNDCLASS_OBJECT Class;
|
||||||
|
RTL_ATOM Atom;
|
||||||
|
DECLARE_RETURN(DWORD);
|
||||||
|
|
||||||
|
if (IS_ATOM(lpClassName))
|
||||||
|
DPRINT("NtUserGetClassInfo - %x (%lx)\n", lpClassName, hInstance);
|
||||||
|
else
|
||||||
|
DPRINT("NtUserGetClassInfo - %S (%lx)\n", lpClassName, hInstance);
|
||||||
|
|
||||||
|
UserEnterExclusive();
|
||||||
|
|
||||||
|
if (!hInstance)
|
||||||
|
{
|
||||||
|
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
||||||
|
RETURN(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(Class = ClassGetClassByNameOrAtom(lpClassName, hInstance)))
|
||||||
|
{
|
||||||
|
SetLastWin32Error(ERROR_CLASS_DOES_NOT_EXIST);
|
||||||
|
RETURN(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
lpWndClassEx->cbSize = sizeof(WNDCLASSEXW);
|
||||||
|
lpWndClassEx->style = Class->style;
|
||||||
|
if (Ansi)
|
||||||
|
lpWndClassEx->lpfnWndProc = Class->lpfnWndProcA;
|
||||||
|
else
|
||||||
|
lpWndClassEx->lpfnWndProc = Class->lpfnWndProcW;
|
||||||
|
lpWndClassEx->cbClsExtra = Class->cbClsExtra;
|
||||||
|
lpWndClassEx->cbWndExtra = Class->cbWndExtra;
|
||||||
|
/* This is not typo, we're really not going to use Class->hInstance here. */
|
||||||
|
/* Well, i think its wrong so i changed it -Gunnar */
|
||||||
|
lpWndClassEx->hInstance = Class->hInstance;
|
||||||
|
lpWndClassEx->hIcon = Class->hIcon;
|
||||||
|
lpWndClassEx->hCursor = Class->hCursor;
|
||||||
|
lpWndClassEx->hbrBackground = Class->hbrBackground;
|
||||||
|
if (Class->lpszMenuName.MaximumLength)
|
||||||
|
RtlCopyUnicodeString((PUNICODE_STRING)lpWndClassEx->lpszMenuName, &Class->lpszMenuName);
|
||||||
|
else
|
||||||
|
lpWndClassEx->lpszMenuName = Class->lpszMenuName.Buffer;
|
||||||
|
lpWndClassEx->lpszClassName = lpClassName;
|
||||||
|
lpWndClassEx->hIconSm = Class->hIconSm;
|
||||||
|
Atom = Class->Atom;
|
||||||
|
|
||||||
|
RETURN(Atom);
|
||||||
|
|
||||||
|
CLEANUP:
|
||||||
|
DPRINT("Leave NtUserGetClassInfo, ret=%i\n",_ret_);
|
||||||
|
UserLeave();
|
||||||
|
END_CLEANUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
DWORD STDCALL
|
||||||
|
NtUserGetClassName (
|
||||||
|
HWND hWnd,
|
||||||
|
LPWSTR lpClassName,
|
||||||
|
ULONG nMaxCount /* in TCHARS */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PWINDOW_OBJECT Window;
|
||||||
|
DECLARE_RETURN(DWORD);
|
||||||
|
PWINSTATION_OBJECT WinSta;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
UserEnterShared();
|
||||||
|
DPRINT("Enter NtUserGetClassName\n");
|
||||||
|
|
||||||
|
if (!(Window = UserGetWindowObject(hWnd)))
|
||||||
|
{
|
||||||
|
RETURN(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
WinSta = PsGetWin32Thread()->Desktop->WindowStation;
|
||||||
|
|
||||||
|
nMaxCount *= sizeof(WCHAR);
|
||||||
|
|
||||||
|
//FIXME: wrap in SEH to protect lpClassName access
|
||||||
|
Status = RtlQueryAtomInAtomTable(WinSta->AtomTable,
|
||||||
|
Window->Class->Atom, NULL, NULL,
|
||||||
|
lpClassName, &nMaxCount);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
SetLastNtError(Status);
|
||||||
|
RETURN(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
RETURN(nMaxCount / sizeof(WCHAR));
|
||||||
|
|
||||||
|
CLEANUP:
|
||||||
|
DPRINT("Leave NtUserGetClassName, ret=%i\n",_ret_);
|
||||||
|
UserLeave();
|
||||||
|
END_CLEANUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD STDCALL
|
||||||
|
NtUserGetWOWClass(DWORD Unknown0,
|
||||||
|
DWORD Unknown1)
|
||||||
|
{
|
||||||
|
UNIMPLEMENTED;
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -95,30 +95,6 @@ PCURICON_OBJECT FASTCALL UserGetCurIconObject(HCURSOR hCurIcon)
|
||||||
return CurIcon;
|
return CurIcon;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
|
|
||||||
static
|
|
||||||
PCURICON_OBJECT FASTCALL IntGetCurIconObject(HCURSOR hCursor)
|
|
||||||
{
|
|
||||||
PCURICON_OBJECT Cursor;
|
|
||||||
|
|
||||||
if (!hCursor) return NULL;
|
|
||||||
|
|
||||||
Cursor = (PCURICON_OBJECT)UserGetObject(&gHandleTable, hCursor, otCursorIcon);
|
|
||||||
if (!Cursor)
|
|
||||||
{
|
|
||||||
SetLastWin32Error(ERROR_INVALID_CURSOR_HANDLE);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
ASSERT(USER_BODY_TO_HEADER(Cursor)->RefCount >= 0);
|
|
||||||
|
|
||||||
USER_BODY_TO_HEADER(Cursor)->RefCount++;
|
|
||||||
|
|
||||||
return Cursor;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#define COLORCURSORS_ALLOWED FALSE
|
#define COLORCURSORS_ALLOWED FALSE
|
||||||
HCURSOR FASTCALL
|
HCURSOR FASTCALL
|
||||||
|
@ -355,21 +331,17 @@ static BOOLEAN FASTCALL
|
||||||
ReferenceCurIconByProcess(PCURICON_OBJECT CurIcon)
|
ReferenceCurIconByProcess(PCURICON_OBJECT CurIcon)
|
||||||
{
|
{
|
||||||
PW32PROCESS Win32Process;
|
PW32PROCESS Win32Process;
|
||||||
PLIST_ENTRY Search;
|
|
||||||
PCURICON_PROCESS Current;
|
PCURICON_PROCESS Current;
|
||||||
|
|
||||||
Win32Process = PsGetWin32Process();
|
Win32Process = PsGetWin32Process();
|
||||||
|
|
||||||
Search = CurIcon->ProcessList.Flink;
|
LIST_FOR_EACH(Current, &CurIcon->ProcessList, CURICON_PROCESS, ListEntry)
|
||||||
while (Search != &CurIcon->ProcessList)
|
|
||||||
{
|
{
|
||||||
Current = CONTAINING_RECORD(Search, CURICON_PROCESS, ListEntry);
|
|
||||||
if (Current->Process == Win32Process)
|
if (Current->Process == Win32Process)
|
||||||
{
|
{
|
||||||
/* Already registered for this process */
|
/* Already registered for this process */
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
Search = Search->Flink;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Not registered yet */
|
/* Not registered yet */
|
||||||
|
@ -388,14 +360,10 @@ PCURICON_OBJECT FASTCALL
|
||||||
IntFindExistingCurIconObject(PWINSTATION_OBJECT WinSta, HMODULE hModule,
|
IntFindExistingCurIconObject(PWINSTATION_OBJECT WinSta, HMODULE hModule,
|
||||||
HRSRC hRsrc, LONG cx, LONG cy)
|
HRSRC hRsrc, LONG cx, LONG cy)
|
||||||
{
|
{
|
||||||
PLIST_ENTRY CurrentEntry;
|
|
||||||
PCURICON_OBJECT CurIcon;
|
PCURICON_OBJECT CurIcon;
|
||||||
|
|
||||||
CurrentEntry = gCurIconList.Flink;
|
LIST_FOR_EACH(CurIcon, &gCurIconList, CURICON_OBJECT, ListEntry)
|
||||||
while (CurrentEntry != &gCurIconList)
|
|
||||||
{
|
{
|
||||||
CurIcon = CONTAINING_RECORD(CurrentEntry, CURICON_OBJECT, ListEntry);
|
|
||||||
CurrentEntry = CurrentEntry->Flink;
|
|
||||||
|
|
||||||
// if(NT_SUCCESS(ObmReferenceObjectByPointer(Object, otCursorIcon))) //<- huh????
|
// if(NT_SUCCESS(ObmReferenceObjectByPointer(Object, otCursorIcon))) //<- huh????
|
||||||
// ObmReferenceObject( CurIcon);
|
// ObmReferenceObject( CurIcon);
|
||||||
|
@ -460,7 +428,6 @@ IntDestroyCurIconObject(PWINSTATION_OBJECT WinSta, PCURICON_OBJECT CurIcon, BOOL
|
||||||
PSYSTEM_CURSORINFO CurInfo;
|
PSYSTEM_CURSORINFO CurInfo;
|
||||||
HBITMAP bmpMask, bmpColor;
|
HBITMAP bmpMask, bmpColor;
|
||||||
BOOLEAN Ret;
|
BOOLEAN Ret;
|
||||||
PLIST_ENTRY Search;
|
|
||||||
PCURICON_PROCESS Current = NULL;
|
PCURICON_PROCESS Current = NULL;
|
||||||
PW32PROCESS W32Process = PsGetWin32Process();
|
PW32PROCESS W32Process = PsGetWin32Process();
|
||||||
|
|
||||||
|
@ -483,18 +450,15 @@ IntDestroyCurIconObject(PWINSTATION_OBJECT WinSta, PCURICON_OBJECT CurIcon, BOOL
|
||||||
|
|
||||||
/* Now find this process in the list of processes referencing this object and
|
/* Now find this process in the list of processes referencing this object and
|
||||||
remove it from that list */
|
remove it from that list */
|
||||||
Search = CurIcon->ProcessList.Flink;
|
LIST_FOR_EACH(Current, &CurIcon->ProcessList, CURICON_PROCESS, ListEntry)
|
||||||
while (Search != &CurIcon->ProcessList)
|
|
||||||
{
|
{
|
||||||
Current = CONTAINING_RECORD(Search, CURICON_PROCESS, ListEntry);
|
|
||||||
if (Current->Process == W32Process)
|
if (Current->Process == W32Process)
|
||||||
{
|
{
|
||||||
|
RemoveEntryList(&Current->ListEntry);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Search = Search->Flink;
|
|
||||||
}
|
}
|
||||||
ASSERT(Search != &CurIcon->ProcessList);
|
|
||||||
RemoveEntryList(Search);
|
|
||||||
ExFreeToPagedLookasideList(&gProcessLookasideList, Current);
|
ExFreeToPagedLookasideList(&gProcessLookasideList, Current);
|
||||||
|
|
||||||
/* If there are still processes referencing this object we can't destroy it yet */
|
/* If there are still processes referencing this object we can't destroy it yet */
|
||||||
|
@ -541,9 +505,7 @@ VOID FASTCALL
|
||||||
IntCleanupCurIcons(struct _EPROCESS *Process, PW32PROCESS Win32Process)
|
IntCleanupCurIcons(struct _EPROCESS *Process, PW32PROCESS Win32Process)
|
||||||
{
|
{
|
||||||
PWINSTATION_OBJECT WinSta;
|
PWINSTATION_OBJECT WinSta;
|
||||||
PLIST_ENTRY CurrentEntry;
|
PCURICON_OBJECT CurIcon, tmp;
|
||||||
PCURICON_OBJECT CurIcon;
|
|
||||||
PLIST_ENTRY ProcessEntry;
|
|
||||||
PCURICON_PROCESS ProcessData;
|
PCURICON_PROCESS ProcessData;
|
||||||
|
|
||||||
WinSta = IntGetWinStaObj();
|
WinSta = IntGetWinStaObj();
|
||||||
|
@ -552,27 +514,19 @@ IntCleanupCurIcons(struct _EPROCESS *Process, PW32PROCESS Win32Process)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
CurrentEntry = gCurIconList.Flink;
|
LIST_FOR_EACH_SAFE(CurIcon, tmp, &gCurIconList, CURICON_OBJECT, ListEntry)
|
||||||
while (CurrentEntry != &gCurIconList)
|
|
||||||
{
|
{
|
||||||
CurIcon = CONTAINING_RECORD(CurrentEntry, CURICON_OBJECT, ListEntry);
|
|
||||||
CurrentEntry = CurrentEntry->Flink;
|
|
||||||
|
|
||||||
|
|
||||||
// ObmReferenceObject(CurIcon);
|
// ObmReferenceObject(CurIcon);
|
||||||
// if(NT_SUCCESS(ObmReferenceObjectByPointer(Object, otCursorIcon)))
|
// if(NT_SUCCESS(ObmReferenceObjectByPointer(Object, otCursorIcon)))
|
||||||
{
|
{
|
||||||
ProcessEntry = CurIcon->ProcessList.Flink;
|
LIST_FOR_EACH(ProcessData, &CurIcon->ProcessList, CURICON_PROCESS, ListEntry)
|
||||||
while (ProcessEntry != &CurIcon->ProcessList)
|
|
||||||
{
|
{
|
||||||
ProcessData = CONTAINING_RECORD(ProcessEntry, CURICON_PROCESS, ListEntry);
|
|
||||||
if (Win32Process == ProcessData->Process)
|
if (Win32Process == ProcessData->Process)
|
||||||
{
|
{
|
||||||
RemoveEntryList(&CurIcon->ListEntry);
|
RemoveEntryList(&CurIcon->ListEntry);
|
||||||
IntDestroyCurIconObject(WinSta, CurIcon, TRUE);
|
IntDestroyCurIconObject(WinSta, CurIcon, TRUE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ProcessEntry = ProcessEntry->Flink;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ObmDereferenceObject(Object);
|
// ObmDereferenceObject(Object);
|
||||||
|
|
|
@ -96,18 +96,16 @@ IntDesktopObjectCreate(PVOID ObjectBody,
|
||||||
|
|
||||||
RtlInitUnicodeString(&UnicodeString, (RemainingPath + 1));
|
RtlInitUnicodeString(&UnicodeString, (RemainingPath + 1));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
KeInitializeSpinLock(&Desktop->Lock);
|
|
||||||
InitializeListHead(&Desktop->ShellHookWindows);
|
InitializeListHead(&Desktop->ShellHookWindows);
|
||||||
|
|
||||||
Desktop->WindowStation = (PWINSTATION_OBJECT)Parent;
|
Desktop->WindowStation = (PWINSTATION_OBJECT)Parent;
|
||||||
|
|
||||||
/* Put the desktop on the window station's list of associcated desktops */
|
/* Put the desktop on the window station's list of associcated desktops */
|
||||||
ExInterlockedInsertTailList(
|
// ExInterlocked
|
||||||
|
InsertTailList(
|
||||||
&Desktop->WindowStation->DesktopListHead,
|
&Desktop->WindowStation->DesktopListHead,
|
||||||
&Desktop->ListEntry,
|
&Desktop->ListEntry);//,
|
||||||
&Desktop->WindowStation->Lock);
|
// &Desktop->WindowStation->Lock);
|
||||||
|
|
||||||
return RtlCreateUnicodeString(&Desktop->Name, UnicodeString.Buffer);
|
return RtlCreateUnicodeString(&Desktop->Name, UnicodeString.Buffer);
|
||||||
}
|
}
|
||||||
|
@ -116,20 +114,41 @@ VOID STDCALL
|
||||||
IntDesktopObjectDelete(PVOID DeletedObject)
|
IntDesktopObjectDelete(PVOID DeletedObject)
|
||||||
{
|
{
|
||||||
PDESKTOP_OBJECT Desktop = (PDESKTOP_OBJECT)DeletedObject;
|
PDESKTOP_OBJECT Desktop = (PDESKTOP_OBJECT)DeletedObject;
|
||||||
KIRQL OldIrql;
|
|
||||||
|
|
||||||
DPRINT("Deleting desktop (0x%X)\n", Desktop);
|
DPRINT("Deleting desktop (0x%X)\n", Desktop);
|
||||||
|
|
||||||
/* Remove the desktop from the window station's list of associcated desktops */
|
/* Remove the desktop from the window station's list of associcated desktops */
|
||||||
KeAcquireSpinLock(&Desktop->WindowStation->Lock, &OldIrql);
|
|
||||||
RemoveEntryList(&Desktop->ListEntry);
|
RemoveEntryList(&Desktop->ListEntry);
|
||||||
KeReleaseSpinLock(&Desktop->WindowStation->Lock, OldIrql);
|
|
||||||
|
|
||||||
RtlFreeUnicodeString(&Desktop->Name);
|
RtlFreeUnicodeString(&Desktop->Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* PRIVATE FUNCTIONS **********************************************************/
|
/* PRIVATE FUNCTIONS **********************************************************/
|
||||||
|
|
||||||
|
static int GetSystemVersionString(LPWSTR buffer)
|
||||||
|
{
|
||||||
|
RTL_OSVERSIONINFOEXW versionInfo;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
versionInfo.dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOEXW);
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(RtlGetVersion((PRTL_OSVERSIONINFOW)&versionInfo)))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (versionInfo.dwMajorVersion <= 4)
|
||||||
|
len = swprintf(buffer,
|
||||||
|
L"ReactOS Version %d.%d %s Build %d",
|
||||||
|
versionInfo.dwMajorVersion, versionInfo.dwMinorVersion,
|
||||||
|
versionInfo.szCSDVersion, versionInfo.dwBuildNumber&0xFFFF);
|
||||||
|
else
|
||||||
|
len = swprintf(buffer,
|
||||||
|
L"ReactOS %s (Build %d)",
|
||||||
|
versionInfo.szCSDVersion, versionInfo.dwBuildNumber&0xFFFF);
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS FASTCALL
|
NTSTATUS FASTCALL
|
||||||
IntParseDesktopPath(PEPROCESS Process,
|
IntParseDesktopPath(PEPROCESS Process,
|
||||||
PUNICODE_STRING DesktopPath,
|
PUNICODE_STRING DesktopPath,
|
||||||
|
@ -562,6 +581,37 @@ IntHideDesktop(PDESKTOP_OBJECT Desktop)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static
|
||||||
|
HWND* FASTCALL
|
||||||
|
UserBuildShellHookHwndList(PDESKTOP_OBJECT Desktop)
|
||||||
|
{
|
||||||
|
ULONG entries=0;
|
||||||
|
PSHELL_HOOK_WINDOW Current;
|
||||||
|
HWND* list;
|
||||||
|
|
||||||
|
/* fixme: if we save nb elements in desktop, we dont have to loop to find nb entries */
|
||||||
|
LIST_FOR_EACH(Current, &Desktop->ShellHookWindows, SHELL_HOOK_WINDOW, ListEntry)
|
||||||
|
entries++;
|
||||||
|
|
||||||
|
if (!entries) return NULL;
|
||||||
|
|
||||||
|
list = ExAllocatePool(PagedPool, sizeof(HWND) * (entries + 1)); /* alloc one extra for nullterm */
|
||||||
|
if (list)
|
||||||
|
{
|
||||||
|
HWND* cursor = list;
|
||||||
|
|
||||||
|
LIST_FOR_EACH(Current, &Desktop->ShellHookWindows, SHELL_HOOK_WINDOW, ListEntry)
|
||||||
|
*cursor++ = Current->hWnd;
|
||||||
|
|
||||||
|
*cursor = NULL; /* nullterm list */
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Send the Message to the windows registered for ShellHook
|
* Send the Message to the windows registered for ShellHook
|
||||||
* notifications. The lParam contents depend on the Message. See
|
* notifications. The lParam contents depend on the Message. See
|
||||||
|
@ -570,9 +620,7 @@ IntHideDesktop(PDESKTOP_OBJECT Desktop)
|
||||||
VOID co_IntShellHookNotify(WPARAM Message, LPARAM lParam)
|
VOID co_IntShellHookNotify(WPARAM Message, LPARAM lParam)
|
||||||
{
|
{
|
||||||
PDESKTOP_OBJECT Desktop = IntGetActiveDesktop();
|
PDESKTOP_OBJECT Desktop = IntGetActiveDesktop();
|
||||||
PLIST_ENTRY Entry, Entry2;
|
HWND* HwndList;
|
||||||
PSHELL_HOOK_WINDOW Current;
|
|
||||||
KIRQL OldLevel;
|
|
||||||
|
|
||||||
static UINT MsgType = 0;
|
static UINT MsgType = 0;
|
||||||
|
|
||||||
|
@ -599,43 +647,23 @@ VOID co_IntShellHookNotify(WPARAM Message, LPARAM lParam)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We have to do some tricks because the list could change
|
HwndList = UserBuildShellHookHwndList(Desktop);
|
||||||
* between calls, and we can't keep the lock during the call
|
if (HwndList)
|
||||||
*/
|
|
||||||
|
|
||||||
KeAcquireSpinLock(&Desktop->Lock, &OldLevel);
|
|
||||||
Entry = Desktop->ShellHookWindows.Flink;
|
|
||||||
while (Entry != &Desktop->ShellHookWindows)
|
|
||||||
{
|
{
|
||||||
Current = CONTAINING_RECORD(Entry, SHELL_HOOK_WINDOW, ListEntry);
|
HWND* cursor = HwndList;
|
||||||
KeReleaseSpinLock(&Desktop->Lock, OldLevel);
|
|
||||||
|
|
||||||
DPRINT("Sending notify\n");
|
for (; *cursor; cursor++)
|
||||||
co_IntPostOrSendMessage(Current->hWnd,
|
|
||||||
MsgType,
|
|
||||||
Message,
|
|
||||||
lParam);
|
|
||||||
|
|
||||||
/* Loop again to find the window we were sending to. If it doesn't
|
|
||||||
* exist anymore, we just stop. This could leave an infinite loop
|
|
||||||
* if a window is removed and readded to the list. That's quite
|
|
||||||
* unlikely though.
|
|
||||||
*/
|
|
||||||
|
|
||||||
KeAcquireSpinLock(&Desktop->Lock, &OldLevel);
|
|
||||||
Entry2 = Desktop->ShellHookWindows.Flink;
|
|
||||||
while (Entry2 != Entry &&
|
|
||||||
Entry2 != &Desktop->ShellHookWindows)
|
|
||||||
{
|
{
|
||||||
Entry2 = Entry2->Flink;
|
DPRINT("Sending notify\n");
|
||||||
|
co_IntPostOrSendMessage(*cursor,
|
||||||
|
MsgType,
|
||||||
|
Message,
|
||||||
|
lParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Entry2 == Entry)
|
ExFreePool(HwndList);
|
||||||
Entry = Entry->Flink;
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
KeReleaseSpinLock(&Desktop->Lock, OldLevel);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -650,7 +678,6 @@ BOOL IntRegisterShellHookWindow(HWND hWnd)
|
||||||
{
|
{
|
||||||
PDESKTOP_OBJECT Desktop = PsGetWin32Thread()->Desktop;
|
PDESKTOP_OBJECT Desktop = PsGetWin32Thread()->Desktop;
|
||||||
PSHELL_HOOK_WINDOW Entry;
|
PSHELL_HOOK_WINDOW Entry;
|
||||||
KIRQL OldLevel;
|
|
||||||
|
|
||||||
DPRINT("IntRegisterShellHookWindow\n");
|
DPRINT("IntRegisterShellHookWindow\n");
|
||||||
|
|
||||||
|
@ -659,20 +686,16 @@ BOOL IntRegisterShellHookWindow(HWND hWnd)
|
||||||
*/
|
*/
|
||||||
IntDeRegisterShellHookWindow(hWnd);
|
IntDeRegisterShellHookWindow(hWnd);
|
||||||
|
|
||||||
Entry = ExAllocatePoolWithTag(NonPagedPool,
|
Entry = ExAllocatePoolWithTag(PagedPool,
|
||||||
sizeof(SHELL_HOOK_WINDOW),
|
sizeof(SHELL_HOOK_WINDOW),
|
||||||
TAG_WINSTA);
|
TAG_WINSTA);
|
||||||
/* We have to walk this structure with while holding a spinlock, so we
|
|
||||||
* need NonPagedPool */
|
|
||||||
|
|
||||||
if (!Entry)
|
if (!Entry)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
Entry->hWnd = hWnd;
|
Entry->hWnd = hWnd;
|
||||||
|
|
||||||
KeAcquireSpinLock(&Desktop->Lock, &OldLevel);
|
|
||||||
InsertTailList(&Desktop->ShellHookWindows, &Entry->ListEntry);
|
InsertTailList(&Desktop->ShellHookWindows, &Entry->ListEntry);
|
||||||
KeReleaseSpinLock(&Desktop->Lock, OldLevel);
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -685,31 +708,27 @@ BOOL IntRegisterShellHookWindow(HWND hWnd)
|
||||||
BOOL IntDeRegisterShellHookWindow(HWND hWnd)
|
BOOL IntDeRegisterShellHookWindow(HWND hWnd)
|
||||||
{
|
{
|
||||||
PDESKTOP_OBJECT Desktop = PsGetWin32Thread()->Desktop;
|
PDESKTOP_OBJECT Desktop = PsGetWin32Thread()->Desktop;
|
||||||
PLIST_ENTRY Entry;
|
|
||||||
PSHELL_HOOK_WINDOW Current;
|
PSHELL_HOOK_WINDOW Current;
|
||||||
KIRQL OldLevel;
|
|
||||||
|
|
||||||
KeAcquireSpinLock(&Desktop->Lock, &OldLevel);
|
LIST_FOR_EACH(Current, &Desktop->ShellHookWindows, SHELL_HOOK_WINDOW, ListEntry)
|
||||||
|
|
||||||
Entry = Desktop->ShellHookWindows.Flink;
|
|
||||||
while (Entry != &Desktop->ShellHookWindows)
|
|
||||||
{
|
{
|
||||||
Current = CONTAINING_RECORD(Entry, SHELL_HOOK_WINDOW, ListEntry);
|
|
||||||
if (Current->hWnd == hWnd)
|
if (Current->hWnd == hWnd)
|
||||||
{
|
{
|
||||||
RemoveEntryList(Entry);
|
RemoveEntryList(&Current->ListEntry);
|
||||||
KeReleaseSpinLock(&Desktop->Lock, OldLevel);
|
ExFreePool(Current);
|
||||||
ExFreePool(Entry);
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
Entry = Entry->Flink;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
KeReleaseSpinLock(&Desktop->Lock, OldLevel);
|
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* SYSCALLS *******************************************************************/
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* NtUserCreateDesktop
|
* NtUserCreateDesktop
|
||||||
*
|
*
|
||||||
|
@ -759,7 +778,7 @@ NtUserCreateDesktop(
|
||||||
CSR_API_MESSAGE Request;
|
CSR_API_MESSAGE Request;
|
||||||
DECLARE_RETURN(HDESK);
|
DECLARE_RETURN(HDESK);
|
||||||
|
|
||||||
DPRINT("Enter CreateDesktop: %wZ\n", lpszDesktopName);
|
DPRINT("Enter NtUserCreateDesktop: %wZ\n", lpszDesktopName);
|
||||||
UserEnterExclusive();
|
UserEnterExclusive();
|
||||||
|
|
||||||
Status = IntValidateWindowStationHandle(
|
Status = IntValidateWindowStationHandle(
|
||||||
|
@ -1035,6 +1054,10 @@ NtUserOpenInputDesktop(
|
||||||
PDESKTOP_OBJECT Object;
|
PDESKTOP_OBJECT Object;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
HDESK Desktop;
|
HDESK Desktop;
|
||||||
|
DECLARE_RETURN(HDESK);
|
||||||
|
|
||||||
|
DPRINT("Enter NtUserOpenInputDesktop\n");
|
||||||
|
UserEnterExclusive();
|
||||||
|
|
||||||
DPRINT("About to open input desktop\n");
|
DPRINT("About to open input desktop\n");
|
||||||
|
|
||||||
|
@ -1049,7 +1072,7 @@ NtUserOpenInputDesktop(
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT("Validation of input desktop handle (0x%X) failed\n", InputDesktop);
|
DPRINT("Validation of input desktop handle (0x%X) failed\n", InputDesktop);
|
||||||
return (HDESK)0;
|
RETURN((HDESK)0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create a new handle to the object */
|
/* Create a new handle to the object */
|
||||||
|
@ -1068,11 +1091,16 @@ NtUserOpenInputDesktop(
|
||||||
if (NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT("Successfully opened input desktop\n");
|
DPRINT("Successfully opened input desktop\n");
|
||||||
return (HDESK)Desktop;
|
RETURN((HDESK)Desktop);
|
||||||
}
|
}
|
||||||
|
|
||||||
SetLastNtError(Status);
|
SetLastNtError(Status);
|
||||||
return (HDESK)0;
|
RETURN((HDESK)0);
|
||||||
|
|
||||||
|
CLEANUP:
|
||||||
|
DPRINT("Leave NtUserOpenInputDesktop, ret=%i\n",_ret_);
|
||||||
|
UserLeave();
|
||||||
|
END_CLEANUP;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1102,6 +1130,10 @@ NtUserCloseDesktop(HDESK hDesktop)
|
||||||
{
|
{
|
||||||
PDESKTOP_OBJECT Object;
|
PDESKTOP_OBJECT Object;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
DECLARE_RETURN(BOOL);
|
||||||
|
|
||||||
|
DPRINT("Enter NtUserCloseDesktop\n");
|
||||||
|
UserEnterExclusive();
|
||||||
|
|
||||||
DPRINT("About to close desktop handle (0x%X)\n", hDesktop);
|
DPRINT("About to close desktop handle (0x%X)\n", hDesktop);
|
||||||
|
|
||||||
|
@ -1114,7 +1146,7 @@ NtUserCloseDesktop(HDESK hDesktop)
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT("Validation of desktop handle (0x%X) failed\n", hDesktop);
|
DPRINT("Validation of desktop handle (0x%X) failed\n", hDesktop);
|
||||||
return FALSE;
|
RETURN(FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
ObDereferenceObject(Object);
|
ObDereferenceObject(Object);
|
||||||
|
@ -1125,35 +1157,19 @@ NtUserCloseDesktop(HDESK hDesktop)
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
SetLastNtError(Status);
|
SetLastNtError(Status);
|
||||||
return FALSE;
|
RETURN(FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
RETURN(TRUE);
|
||||||
|
|
||||||
|
CLEANUP:
|
||||||
|
DPRINT("Leave NtUserCloseDesktop, ret=%i\n",_ret_);
|
||||||
|
UserLeave();
|
||||||
|
END_CLEANUP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int GetSystemVersionString(LPWSTR buffer)
|
|
||||||
{
|
|
||||||
RTL_OSVERSIONINFOEXW versionInfo;
|
|
||||||
int len;
|
|
||||||
|
|
||||||
versionInfo.dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOEXW);
|
|
||||||
|
|
||||||
if (!NT_SUCCESS(RtlGetVersion((PRTL_OSVERSIONINFOW)&versionInfo)))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (versionInfo.dwMajorVersion <= 4)
|
|
||||||
len = swprintf(buffer,
|
|
||||||
L"ReactOS Version %d.%d %s Build %d",
|
|
||||||
versionInfo.dwMajorVersion, versionInfo.dwMinorVersion,
|
|
||||||
versionInfo.szCSDVersion, versionInfo.dwBuildNumber&0xFFFF);
|
|
||||||
else
|
|
||||||
len = swprintf(buffer,
|
|
||||||
L"ReactOS %s (Build %d)",
|
|
||||||
versionInfo.szCSDVersion, versionInfo.dwBuildNumber&0xFFFF);
|
|
||||||
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* NtUserPaintDesktop
|
* NtUserPaintDesktop
|
||||||
|
@ -1179,6 +1195,10 @@ NtUserPaintDesktop(HDC hDC)
|
||||||
BOOL doPatBlt = TRUE;
|
BOOL doPatBlt = TRUE;
|
||||||
PWINDOW_OBJECT WndDesktop;
|
PWINDOW_OBJECT WndDesktop;
|
||||||
int len;
|
int len;
|
||||||
|
DECLARE_RETURN(BOOL);
|
||||||
|
|
||||||
|
UserEnterExclusive();
|
||||||
|
DPRINT("Enter NtUserPaintDesktop\n");
|
||||||
|
|
||||||
PWINSTATION_OBJECT WinSta = PsGetWin32Thread()->Desktop->WindowStation;
|
PWINSTATION_OBJECT WinSta = PsGetWin32Thread()->Desktop->WindowStation;
|
||||||
|
|
||||||
|
@ -1186,7 +1206,7 @@ NtUserPaintDesktop(HDC hDC)
|
||||||
|
|
||||||
hWndDesktop = IntGetDesktopWindow();
|
hWndDesktop = IntGetDesktopWindow();
|
||||||
if (!(WndDesktop = UserGetWindowObject(hWndDesktop)))
|
if (!(WndDesktop = UserGetWindowObject(hWndDesktop)))
|
||||||
return FALSE;
|
RETURN(FALSE);
|
||||||
|
|
||||||
DesktopBrush = (HBRUSH)IntGetClassLong(WndDesktop, GCL_HBRBACKGROUND, FALSE); //fixme: verify retval
|
DesktopBrush = (HBRUSH)IntGetClassLong(WndDesktop, GCL_HBRBACKGROUND, FALSE); //fixme: verify retval
|
||||||
|
|
||||||
|
@ -1277,7 +1297,12 @@ NtUserPaintDesktop(HDC hDC)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
RETURN(TRUE);
|
||||||
|
|
||||||
|
CLEANUP:
|
||||||
|
DPRINT("Leave NtUserPaintDesktop, ret=%i\n",_ret_);
|
||||||
|
UserLeave();
|
||||||
|
END_CLEANUP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1302,6 +1327,10 @@ NtUserSwitchDesktop(HDESK hDesktop)
|
||||||
{
|
{
|
||||||
PDESKTOP_OBJECT DesktopObject;
|
PDESKTOP_OBJECT DesktopObject;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
DECLARE_RETURN(BOOL);
|
||||||
|
|
||||||
|
UserEnterExclusive();
|
||||||
|
DPRINT("Enter NtUserSwitchDesktop\n");
|
||||||
|
|
||||||
DPRINT("About to switch desktop (0x%X)\n", hDesktop);
|
DPRINT("About to switch desktop (0x%X)\n", hDesktop);
|
||||||
|
|
||||||
|
@ -1314,7 +1343,7 @@ NtUserSwitchDesktop(HDESK hDesktop)
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT("Validation of desktop handle (0x%X) failed\n", hDesktop);
|
DPRINT("Validation of desktop handle (0x%X) failed\n", hDesktop);
|
||||||
return FALSE;
|
RETURN(FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1326,7 +1355,7 @@ NtUserSwitchDesktop(HDESK hDesktop)
|
||||||
{
|
{
|
||||||
ObDereferenceObject(DesktopObject);
|
ObDereferenceObject(DesktopObject);
|
||||||
DPRINT1("Switching desktop 0x%x denied because the work station is locked!\n", hDesktop);
|
DPRINT1("Switching desktop 0x%x denied because the work station is locked!\n", hDesktop);
|
||||||
return FALSE;
|
RETURN(FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME: Fail if the desktop belong to an invisible window station */
|
/* FIXME: Fail if the desktop belong to an invisible window station */
|
||||||
|
@ -1344,7 +1373,12 @@ NtUserSwitchDesktop(HDESK hDesktop)
|
||||||
|
|
||||||
ObDereferenceObject(DesktopObject);
|
ObDereferenceObject(DesktopObject);
|
||||||
|
|
||||||
return TRUE;
|
RETURN(TRUE);
|
||||||
|
|
||||||
|
CLEANUP:
|
||||||
|
DPRINT("Leave NtUserSwitchDesktop, ret=%i\n",_ret_);
|
||||||
|
UserLeave();
|
||||||
|
END_CLEANUP;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1376,18 +1410,22 @@ NtUserGetThreadDesktop(DWORD dwThreadId, DWORD Unknown1)
|
||||||
PDESKTOP_OBJECT DesktopObject;
|
PDESKTOP_OBJECT DesktopObject;
|
||||||
HDESK Ret, hThreadDesktop;
|
HDESK Ret, hThreadDesktop;
|
||||||
OBJECT_HANDLE_INFORMATION HandleInformation;
|
OBJECT_HANDLE_INFORMATION HandleInformation;
|
||||||
|
DECLARE_RETURN(HDESK);
|
||||||
|
|
||||||
|
UserEnterExclusive();
|
||||||
|
DPRINT("Enter NtUserGetThreadDesktop\n");
|
||||||
|
|
||||||
if(!dwThreadId)
|
if(!dwThreadId)
|
||||||
{
|
{
|
||||||
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
||||||
return 0;
|
RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = PsLookupThreadByThreadId((HANDLE)dwThreadId, &Thread);
|
Status = PsLookupThreadByThreadId((HANDLE)dwThreadId, &Thread);
|
||||||
if(!NT_SUCCESS(Status))
|
if(!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
||||||
return 0;
|
RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Thread->ThreadsProcess == PsGetCurrentProcess())
|
if(Thread->ThreadsProcess == PsGetCurrentProcess())
|
||||||
|
@ -1396,7 +1434,7 @@ NtUserGetThreadDesktop(DWORD dwThreadId, DWORD Unknown1)
|
||||||
in the same context */
|
in the same context */
|
||||||
Ret = Thread->Tcb.Win32Thread->hDesktop;
|
Ret = Thread->Tcb.Win32Thread->hDesktop;
|
||||||
ObDereferenceObject(Thread);
|
ObDereferenceObject(Thread);
|
||||||
return Ret;
|
RETURN(Ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get the desktop handle and the desktop of the thread */
|
/* get the desktop handle and the desktop of the thread */
|
||||||
|
@ -1405,7 +1443,7 @@ NtUserGetThreadDesktop(DWORD dwThreadId, DWORD Unknown1)
|
||||||
{
|
{
|
||||||
ObDereferenceObject(Thread);
|
ObDereferenceObject(Thread);
|
||||||
DPRINT1("Desktop information of thread 0x%x broken!?\n", dwThreadId);
|
DPRINT1("Desktop information of thread 0x%x broken!?\n", dwThreadId);
|
||||||
return NULL;
|
RETURN(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* we could just use DesktopObject instead of looking up the handle, but latter
|
/* we could just use DesktopObject instead of looking up the handle, but latter
|
||||||
|
@ -1425,7 +1463,7 @@ NtUserGetThreadDesktop(DWORD dwThreadId, DWORD Unknown1)
|
||||||
if(!NT_SUCCESS(Status))
|
if(!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
ObDereferenceObject(Thread);
|
ObDereferenceObject(Thread);
|
||||||
return NULL;
|
RETURN(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* lookup our handle table if we can find a handle to the desktop object,
|
/* lookup our handle table if we can find a handle to the desktop object,
|
||||||
|
@ -1435,7 +1473,12 @@ NtUserGetThreadDesktop(DWORD dwThreadId, DWORD Unknown1)
|
||||||
/* all done, we got a valid handle to the desktop */
|
/* all done, we got a valid handle to the desktop */
|
||||||
ObDereferenceObject(DesktopObject);
|
ObDereferenceObject(DesktopObject);
|
||||||
ObDereferenceObject(Thread);
|
ObDereferenceObject(Thread);
|
||||||
return Ret;
|
RETURN(Ret);
|
||||||
|
|
||||||
|
CLEANUP:
|
||||||
|
DPRINT("Leave NtUserGetThreadDesktop, ret=%i\n",_ret_);
|
||||||
|
UserLeave();
|
||||||
|
END_CLEANUP;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1451,6 +1494,10 @@ NtUserSetThreadDesktop(HDESK hDesktop)
|
||||||
PW32THREAD W32Thread;
|
PW32THREAD W32Thread;
|
||||||
PDESKTOP_OBJECT DesktopObject;
|
PDESKTOP_OBJECT DesktopObject;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
DECLARE_RETURN(BOOL);
|
||||||
|
|
||||||
|
UserEnterExclusive();
|
||||||
|
DPRINT("Enter NtUserSetThreadDesktop\n");
|
||||||
|
|
||||||
/* Validate the new desktop. */
|
/* Validate the new desktop. */
|
||||||
Status = IntValidateDesktopHandle(
|
Status = IntValidateDesktopHandle(
|
||||||
|
@ -1462,7 +1509,7 @@ NtUserSetThreadDesktop(HDESK hDesktop)
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT("Validation of desktop handle (0x%X) failed\n", hDesktop);
|
DPRINT("Validation of desktop handle (0x%X) failed\n", hDesktop);
|
||||||
return FALSE;
|
RETURN(FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
W32Thread = PsGetWin32Thread();
|
W32Thread = PsGetWin32Thread();
|
||||||
|
@ -1477,7 +1524,12 @@ NtUserSetThreadDesktop(HDESK hDesktop)
|
||||||
W32Thread->Desktop = DesktopObject;
|
W32Thread->Desktop = DesktopObject;
|
||||||
W32Thread->hDesktop = hDesktop;
|
W32Thread->hDesktop = hDesktop;
|
||||||
|
|
||||||
return TRUE;
|
RETURN(TRUE);
|
||||||
|
|
||||||
|
CLEANUP:
|
||||||
|
DPRINT("Leave NtUserSetThreadDesktop, ret=%i\n",_ret_);
|
||||||
|
UserLeave();
|
||||||
|
END_CLEANUP;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -510,21 +510,6 @@ NtUserCallTwoParam(
|
||||||
UNIMPLEMENTED
|
UNIMPLEMENTED
|
||||||
RETURN( 0);
|
RETURN( 0);
|
||||||
|
|
||||||
case TWOPARAM_ROUTINE_VALIDATERGN:
|
|
||||||
{
|
|
||||||
PWINDOW_OBJECT Window = UserGetWindowObject((HWND) Param1);
|
|
||||||
BOOL ret;
|
|
||||||
|
|
||||||
if (!Window)
|
|
||||||
RETURN(FALSE);
|
|
||||||
|
|
||||||
UserRefObjectCo(Window);
|
|
||||||
ret = co_UserValidateRgn(Window, (HRGN) Param2);
|
|
||||||
UserDerefObjectCo(Window);
|
|
||||||
|
|
||||||
RETURN((DWORD) ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
case TWOPARAM_ROUTINE_SETWNDCONTEXTHLPID:
|
case TWOPARAM_ROUTINE_SETWNDCONTEXTHLPID:
|
||||||
|
|
||||||
if(!(Window = UserGetWindowObject((HWND)Param1)))
|
if(!(Window = UserGetWindowObject((HWND)Param1)))
|
||||||
|
|
|
@ -292,11 +292,12 @@ co_IntPaintWindows(PWINDOW_OBJECT Window, ULONG Flags)
|
||||||
{
|
{
|
||||||
for (phWnd = List; *phWnd; ++phWnd)
|
for (phWnd = List; *phWnd; ++phWnd)
|
||||||
{
|
{
|
||||||
Window = IntGetWindowObject(*phWnd);
|
Window = UserGetWindowObject(*phWnd);
|
||||||
if (Window && (Window->Style & WS_VISIBLE))
|
if (Window && (Window->Style & WS_VISIBLE))
|
||||||
{
|
{
|
||||||
|
UserRefObjectCo(Window);
|
||||||
co_IntPaintWindows(Window, Flags);
|
co_IntPaintWindows(Window, Flags);
|
||||||
ObmDereferenceObject(Window);
|
UserDerefObjectCo(Window);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ExFreePool(List);
|
ExFreePool(List);
|
||||||
|
@ -414,31 +415,21 @@ IntInvalidateWindows(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags)
|
||||||
if (!(Flags & RDW_NOCHILDREN) && !(Window->Style & WS_MINIMIZE) &&
|
if (!(Flags & RDW_NOCHILDREN) && !(Window->Style & WS_MINIMIZE) &&
|
||||||
((Flags & RDW_ALLCHILDREN) || !(Window->Style & WS_CLIPCHILDREN)))
|
((Flags & RDW_ALLCHILDREN) || !(Window->Style & WS_CLIPCHILDREN)))
|
||||||
{
|
{
|
||||||
HWND *List, *phWnd;
|
|
||||||
PWINDOW_OBJECT Child;
|
PWINDOW_OBJECT Child;
|
||||||
|
|
||||||
if ((List = IntWinListChildren(Window)))
|
for (Child = Window->FirstChild; Child; Child = Child->NextSibling)
|
||||||
{
|
{
|
||||||
for (phWnd = List; *phWnd; ++phWnd)
|
if (Child->Style & WS_VISIBLE)
|
||||||
{
|
{
|
||||||
if(!(Child = UserGetWindowObject(*phWnd)))
|
/*
|
||||||
{
|
* Recursive call to update children UpdateRegion
|
||||||
continue;
|
*/
|
||||||
}
|
HRGN hRgnTemp = NtGdiCreateRectRgn(0, 0, 0, 0);
|
||||||
|
NtGdiCombineRgn(hRgnTemp, hRgn, 0, RGN_COPY);
|
||||||
if (Child->Style & WS_VISIBLE)
|
IntInvalidateWindows(Child, hRgnTemp, Flags);
|
||||||
{
|
NtGdiDeleteObject(hRgnTemp);
|
||||||
/*
|
|
||||||
* Recursive call to update children UpdateRegion
|
|
||||||
*/
|
|
||||||
HRGN hRgnTemp = NtGdiCreateRectRgn(0, 0, 0, 0);
|
|
||||||
NtGdiCombineRgn(hRgnTemp, hRgn, 0, RGN_COPY);
|
|
||||||
IntInvalidateWindows(Child, hRgnTemp, Flags);
|
|
||||||
NtGdiDeleteObject(hRgnTemp);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
ExFreePool(List);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -859,69 +850,6 @@ CLEANUP:
|
||||||
END_CLEANUP;
|
END_CLEANUP;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* NtUserInvalidateRect
|
|
||||||
*
|
|
||||||
* Status
|
|
||||||
* @implemented
|
|
||||||
*/
|
|
||||||
|
|
||||||
DWORD STDCALL
|
|
||||||
NtUserInvalidateRect(HWND hWnd, CONST RECT *Rect, BOOL Erase)
|
|
||||||
{
|
|
||||||
return NtUserRedrawWindow(hWnd, Rect, 0, RDW_INVALIDATE | (Erase ? RDW_ERASE : 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* NtUserInvalidateRgn
|
|
||||||
*
|
|
||||||
* Status
|
|
||||||
* @implemented
|
|
||||||
*/
|
|
||||||
|
|
||||||
DWORD STDCALL
|
|
||||||
NtUserInvalidateRgn(HWND hWnd, HRGN Rgn, BOOL Erase)
|
|
||||||
{
|
|
||||||
return NtUserRedrawWindow(hWnd, NULL, Rgn, RDW_INVALIDATE | (Erase ? RDW_ERASE : 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
BOOL FASTCALL
|
|
||||||
co_UserValidateRgn(PWINDOW_OBJECT Window, HRGN hRgn)
|
|
||||||
{
|
|
||||||
return co_UserRedrawWindow(Window, NULL, hRgn, RDW_VALIDATE | RDW_NOCHILDREN);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* NtUserValidateRgn
|
|
||||||
*
|
|
||||||
* Status
|
|
||||||
* @implemented
|
|
||||||
*/
|
|
||||||
|
|
||||||
BOOL STDCALL
|
|
||||||
NtUserValidateRgn(HWND hWnd, HRGN hRgn)
|
|
||||||
{
|
|
||||||
return NtUserRedrawWindow(hWnd, NULL, hRgn, RDW_VALIDATE | RDW_NOCHILDREN);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* NtUserUpdateWindow
|
|
||||||
*
|
|
||||||
* Status
|
|
||||||
* @implemented
|
|
||||||
*/
|
|
||||||
|
|
||||||
BOOL STDCALL
|
|
||||||
NtUserUpdateWindow(HWND hWnd)
|
|
||||||
{
|
|
||||||
return NtUserRedrawWindow(hWnd, NULL, 0, RDW_UPDATENOW | RDW_ALLCHILDREN);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
INT FASTCALL
|
INT FASTCALL
|
||||||
co_UserGetUpdateRgn(PWINDOW_OBJECT Window, HRGN hRgn, BOOL bErase)
|
co_UserGetUpdateRgn(PWINDOW_OBJECT Window, HRGN hRgn, BOOL bErase)
|
||||||
|
|
|
@ -293,8 +293,12 @@ static void IntSendDestroyMsg(HWND hWnd)
|
||||||
* IntDestroyWindow
|
* IntDestroyWindow
|
||||||
*
|
*
|
||||||
* Destroy storage associated to a window. "Internals" p.358
|
* Destroy storage associated to a window. "Internals" p.358
|
||||||
|
*
|
||||||
|
* This is the "functional" DestroyWindows function ei. all stuff
|
||||||
|
* done in CreateWindow is undone here and not in DestroyWindow:-P
|
||||||
|
|
||||||
*/
|
*/
|
||||||
static LRESULT co_IntDestroyWindow(PWINDOW_OBJECT Window,
|
static LRESULT co_UserFreeWindow(PWINDOW_OBJECT Window,
|
||||||
PW32PROCESS ProcessData,
|
PW32PROCESS ProcessData,
|
||||||
PW32THREAD ThreadData,
|
PW32THREAD ThreadData,
|
||||||
BOOLEAN SendMessages)
|
BOOLEAN SendMessages)
|
||||||
|
@ -343,7 +347,7 @@ static LRESULT co_IntDestroyWindow(PWINDOW_OBJECT Window,
|
||||||
IntSendDestroyMsg(Child->hSelf);
|
IntSendDestroyMsg(Child->hSelf);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
co_IntDestroyWindow(Child, ProcessData, ThreadData, SendMessages);
|
co_UserFreeWindow(Child, ProcessData, ThreadData, SendMessages);
|
||||||
|
|
||||||
UserDerefObject(Child);
|
UserDerefObject(Child);
|
||||||
}
|
}
|
||||||
|
@ -427,11 +431,8 @@ static LRESULT co_IntDestroyWindow(PWINDOW_OBJECT Window,
|
||||||
|
|
||||||
IntDestroyScrollBars(Window);
|
IntDestroyScrollBars(Window);
|
||||||
|
|
||||||
/* remove the window from the class object */
|
|
||||||
RemoveEntryList(&Window->ClassListEntry);
|
|
||||||
|
|
||||||
/* dereference the class */
|
/* dereference the class */
|
||||||
ClassDereferenceObject(Window->Class);
|
ClassDerefObject(Window->Class);
|
||||||
Window->Class = NULL;
|
Window->Class = NULL;
|
||||||
|
|
||||||
if(Window->WindowRegion)
|
if(Window->WindowRegion)
|
||||||
|
@ -1331,13 +1332,13 @@ co_IntCreateWindowEx(DWORD dwExStyle,
|
||||||
BOOL bUnicodeWindow)
|
BOOL bUnicodeWindow)
|
||||||
{
|
{
|
||||||
PWINSTATION_OBJECT WinSta;
|
PWINSTATION_OBJECT WinSta;
|
||||||
PWNDCLASS_OBJECT Class;
|
PWNDCLASS_OBJECT Class = NULL;
|
||||||
PWINDOW_OBJECT Window = NULL;
|
PWINDOW_OBJECT Window = NULL;
|
||||||
PWINDOW_OBJECT ParentWindow = NULL, OwnerWindow;
|
PWINDOW_OBJECT ParentWindow = NULL, OwnerWindow;
|
||||||
HWND ParentWindowHandle;
|
HWND ParentWindowHandle;
|
||||||
HWND OwnerWindowHandle;
|
HWND OwnerWindowHandle;
|
||||||
PMENU_OBJECT SystemMenu;
|
PMENU_OBJECT SystemMenu;
|
||||||
HANDLE Handle;
|
HWND hWnd;
|
||||||
POINT Pos;
|
POINT Pos;
|
||||||
SIZE Size;
|
SIZE Size;
|
||||||
#if 0
|
#if 0
|
||||||
|
@ -1352,7 +1353,6 @@ co_IntCreateWindowEx(DWORD dwExStyle,
|
||||||
CBT_CREATEWNDW CbtCreate;
|
CBT_CREATEWNDW CbtCreate;
|
||||||
LRESULT Result;
|
LRESULT Result;
|
||||||
BOOL MenuChanged;
|
BOOL MenuChanged;
|
||||||
BOOL ClassFound;
|
|
||||||
DECLARE_RETURN(HWND);
|
DECLARE_RETURN(HWND);
|
||||||
BOOL HasOwner;
|
BOOL HasOwner;
|
||||||
|
|
||||||
|
@ -1398,8 +1398,8 @@ co_IntCreateWindowEx(DWORD dwExStyle,
|
||||||
/* FIXME: parent must belong to the current process */
|
/* FIXME: parent must belong to the current process */
|
||||||
|
|
||||||
/* Check the class. */
|
/* Check the class. */
|
||||||
ClassFound = ClassReferenceClassByNameOrAtom(&Class, ClassName->Buffer, hInstance);
|
Class = ClassGetClassByNameOrAtom(ClassName->Buffer, hInstance);
|
||||||
if (!ClassFound)
|
if (!Class)
|
||||||
{
|
{
|
||||||
if (IS_ATOM(ClassName->Buffer))
|
if (IS_ATOM(ClassName->Buffer))
|
||||||
{
|
{
|
||||||
|
@ -1414,55 +1414,52 @@ co_IntCreateWindowEx(DWORD dwExStyle,
|
||||||
RETURN((HWND)0);
|
RETURN((HWND)0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ClassRefObject(Class);
|
||||||
|
|
||||||
/* Check the window station. */
|
/* Check the window station. */
|
||||||
if (PsGetWin32Thread()->Desktop == NULL)
|
if (PsGetWin32Thread()->Desktop == NULL)
|
||||||
{
|
{
|
||||||
ClassDereferenceObject(Class);
|
|
||||||
|
|
||||||
DPRINT("Thread is not attached to a desktop! Cannot create window!\n");
|
DPRINT("Thread is not attached to a desktop! Cannot create window!\n");
|
||||||
RETURN( (HWND)0);
|
RETURN( (HWND)0);
|
||||||
}
|
}
|
||||||
WinSta = PsGetWin32Thread()->Desktop->WindowStation;
|
WinSta = PsGetWin32Thread()->Desktop->WindowStation;
|
||||||
|
|
||||||
|
//FIXME: Reference thread/desktop instead
|
||||||
ObReferenceObjectByPointer(WinSta, KernelMode, ExWindowStationObjectType, 0);
|
ObReferenceObjectByPointer(WinSta, KernelMode, ExWindowStationObjectType, 0);
|
||||||
|
|
||||||
/* Create the window object. */
|
/* Create the window object. */
|
||||||
Window = (PWINDOW_OBJECT)
|
Window = (PWINDOW_OBJECT)
|
||||||
ObmCreateObject(&gHandleTable, &Handle,
|
ObmCreateObject(&gHandleTable, (PHANDLE)&hWnd,
|
||||||
otWindow, sizeof(WINDOW_OBJECT) + Class->cbWndExtra
|
otWindow, sizeof(WINDOW_OBJECT) + Class->cbWndExtra
|
||||||
);
|
);
|
||||||
|
|
||||||
DPRINT("Created object with handle %X\n", Handle);
|
DPRINT("Created object with handle %X\n", hWnd);
|
||||||
if (!Window)
|
if (!Window)
|
||||||
{
|
{
|
||||||
ObDereferenceObject(WinSta);
|
ObDereferenceObject(WinSta);
|
||||||
ClassDereferenceObject(Class);
|
|
||||||
SetLastNtError(STATUS_INSUFFICIENT_RESOURCES);
|
SetLastNtError(STATUS_INSUFFICIENT_RESOURCES);
|
||||||
RETURN( (HWND)0);
|
RETURN( (HWND)0);
|
||||||
}
|
}
|
||||||
|
|
||||||
UserRefObjectCo(Window);
|
UserRefObjectCo(Window);
|
||||||
|
|
||||||
|
|
||||||
ObDereferenceObject(WinSta);
|
ObDereferenceObject(WinSta);
|
||||||
|
|
||||||
if (NULL == PsGetWin32Thread()->Desktop->DesktopWindow)
|
if (NULL == PsGetWin32Thread()->Desktop->DesktopWindow)
|
||||||
{
|
{
|
||||||
/* If there is no desktop window yet, we must be creating it */
|
/* If there is no desktop window yet, we must be creating it */
|
||||||
PsGetWin32Thread()->Desktop->DesktopWindow = Handle;
|
PsGetWin32Thread()->Desktop->DesktopWindow = hWnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Fill out the structure describing it.
|
* Fill out the structure describing it.
|
||||||
*/
|
*/
|
||||||
Window->Class = Class;
|
Window->Class = Class;
|
||||||
|
|
||||||
InsertTailList(&Class->ClassWindowsListHead, &Window->ClassListEntry);
|
|
||||||
|
|
||||||
Window->SystemMenu = (HMENU)0;
|
Window->SystemMenu = (HMENU)0;
|
||||||
Window->ContextHelpId = 0;
|
Window->ContextHelpId = 0;
|
||||||
Window->IDMenu = 0;
|
Window->IDMenu = 0;
|
||||||
Window->Instance = hInstance;
|
Window->Instance = hInstance;
|
||||||
Window->hSelf = Handle;
|
Window->hSelf = hWnd;
|
||||||
if (0 != (dwStyle & WS_CHILD))
|
if (0 != (dwStyle & WS_CHILD))
|
||||||
{
|
{
|
||||||
Window->IDMenu = (UINT) hMenu;
|
Window->IDMenu = (UINT) hMenu;
|
||||||
|
@ -1505,19 +1502,11 @@ co_IntCreateWindowEx(DWORD dwExStyle,
|
||||||
Window->LastChild = NULL;
|
Window->LastChild = NULL;
|
||||||
Window->PrevSibling = NULL;
|
Window->PrevSibling = NULL;
|
||||||
Window->NextSibling = NULL;
|
Window->NextSibling = NULL;
|
||||||
|
Window->ExtraDataSize = Class->cbWndExtra;
|
||||||
|
|
||||||
/* extra window data */
|
/* extra window data */
|
||||||
if (Class->cbWndExtra != 0)
|
if (Class->cbWndExtra)
|
||||||
{
|
|
||||||
Window->ExtraData = (PCHAR)(Window + 1);
|
Window->ExtraData = (PCHAR)(Window + 1);
|
||||||
Window->ExtraDataSize = Class->cbWndExtra;
|
|
||||||
RtlZeroMemory(Window->ExtraData, Window->ExtraDataSize);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Window->ExtraData = NULL;
|
|
||||||
Window->ExtraDataSize = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
InitializeListHead(&Window->PropListHead);
|
InitializeListHead(&Window->PropListHead);
|
||||||
InitializeListHead(&Window->WndObjListHead);
|
InitializeListHead(&Window->WndObjListHead);
|
||||||
|
@ -1530,7 +1519,6 @@ co_IntCreateWindowEx(DWORD dwExStyle,
|
||||||
TAG_STRING);
|
TAG_STRING);
|
||||||
if (NULL == Window->WindowName.Buffer)
|
if (NULL == Window->WindowName.Buffer)
|
||||||
{
|
{
|
||||||
ClassDereferenceObject(Class);
|
|
||||||
DPRINT1("Failed to allocate mem for window name\n");
|
DPRINT1("Failed to allocate mem for window name\n");
|
||||||
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
|
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
|
||||||
RETURN( NULL);
|
RETURN( NULL);
|
||||||
|
@ -1612,13 +1600,10 @@ co_IntCreateWindowEx(DWORD dwExStyle,
|
||||||
Cs.dwExStyle = dwExStyle;
|
Cs.dwExStyle = dwExStyle;
|
||||||
CbtCreate.lpcs = &Cs;
|
CbtCreate.lpcs = &Cs;
|
||||||
CbtCreate.hwndInsertAfter = HWND_TOP;
|
CbtCreate.hwndInsertAfter = HWND_TOP;
|
||||||
if (co_HOOK_CallHooks(WH_CBT, HCBT_CREATEWND, (WPARAM) Handle, (LPARAM) &CbtCreate))
|
if (co_HOOK_CallHooks(WH_CBT, HCBT_CREATEWND, (WPARAM) hWnd, (LPARAM) &CbtCreate))
|
||||||
{
|
{
|
||||||
|
|
||||||
/* FIXME - Delete window object and remove it from the thread windows list */
|
/* FIXME - Delete window object and remove it from the thread windows list */
|
||||||
/* FIXME - delete allocated DCE */
|
/* FIXME - delete allocated DCE */
|
||||||
|
|
||||||
ClassDereferenceObject(Class);
|
|
||||||
DPRINT1("CBT-hook returned !0\n");
|
DPRINT1("CBT-hook returned !0\n");
|
||||||
RETURN( (HWND) NULL);
|
RETURN( (HWND) NULL);
|
||||||
}
|
}
|
||||||
|
@ -1827,7 +1812,6 @@ co_IntCreateWindowEx(DWORD dwExStyle,
|
||||||
if (Result == (LRESULT)-1)
|
if (Result == (LRESULT)-1)
|
||||||
{
|
{
|
||||||
/* FIXME: Cleanup. */
|
/* FIXME: Cleanup. */
|
||||||
ClassDereferenceObject(Class);
|
|
||||||
DPRINT("IntCreateWindowEx(): send CREATE message failed.\n");
|
DPRINT("IntCreateWindowEx(): send CREATE message failed.\n");
|
||||||
RETURN((HWND)0);
|
RETURN((HWND)0);
|
||||||
}
|
}
|
||||||
|
@ -1911,7 +1895,7 @@ co_IntCreateWindowEx(DWORD dwExStyle,
|
||||||
if ((!hWndParent) && (!HasOwner))
|
if ((!hWndParent) && (!HasOwner))
|
||||||
{
|
{
|
||||||
DPRINT("Sending CREATED notify\n");
|
DPRINT("Sending CREATED notify\n");
|
||||||
co_IntShellHookNotify(HSHELL_WINDOWCREATED, (LPARAM)Handle);
|
co_IntShellHookNotify(HSHELL_WINDOWCREATED, (LPARAM)hWnd);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1934,14 +1918,14 @@ co_IntCreateWindowEx(DWORD dwExStyle,
|
||||||
co_WinPosShowWindow(Window, dwShowMode);
|
co_WinPosShowWindow(Window, dwShowMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINT("IntCreateWindow(): = %X\n", Handle);
|
DPRINT("IntCreateWindow(): = %X\n", hWnd);
|
||||||
DPRINT("WindowObject->SystemMenu = 0x%x\n", Window->SystemMenu);
|
DPRINT("WindowObject->SystemMenu = 0x%x\n", Window->SystemMenu);
|
||||||
RETURN((HWND)Handle);
|
RETURN(hWnd);
|
||||||
|
|
||||||
CLEANUP:
|
CLEANUP:
|
||||||
if (Window) UserDerefObjectCo(Window);
|
if (Window) UserDerefObjectCo(Window);
|
||||||
if (ParentWindow) UserDerefObjectCo(ParentWindow);
|
if (ParentWindow) UserDerefObjectCo(ParentWindow);
|
||||||
|
if (!_ret_ && Class) ClassDerefObject(Class); /* only deref if failure (return 0) */
|
||||||
END_CLEANUP;
|
END_CLEANUP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2164,7 +2148,7 @@ BOOLEAN FASTCALL co_UserDestroyWindow(PWINDOW_OBJECT Window)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Destroy the window storage */
|
/* Destroy the window storage */
|
||||||
co_IntDestroyWindow(Window, PsGetWin32Process(), PsGetWin32Thread(), TRUE);
|
co_UserFreeWindow(Window, PsGetWin32Process(), PsGetWin32Thread(), TRUE);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -4208,14 +4192,6 @@ NtUserUpdateLayeredWindow(DWORD Unknown0,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* @implemented
|
|
||||||
*/
|
|
||||||
VOID STDCALL
|
|
||||||
NtUserValidateRect(HWND hWnd, const RECT* Rect)
|
|
||||||
{
|
|
||||||
return (VOID)NtUserRedrawWindow(hWnd, Rect, 0, RDW_VALIDATE | RDW_NOCHILDREN);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -107,6 +107,8 @@ IntWinStaObjectOpen(OB_OPEN_REASON Reason,
|
||||||
PWINSTATION_OBJECT WinSta = (PWINSTATION_OBJECT)ObjectBody;
|
PWINSTATION_OBJECT WinSta = (PWINSTATION_OBJECT)ObjectBody;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
DPRINT1("IntWinStaObjectOpen\n");
|
||||||
|
|
||||||
if (Reason == ObCreateHandle)
|
if (Reason == ObCreateHandle)
|
||||||
{
|
{
|
||||||
DPRINT("Creating window station (0x%X)\n", WinSta);
|
DPRINT("Creating window station (0x%X)\n", WinSta);
|
||||||
|
@ -115,10 +117,10 @@ IntWinStaObjectOpen(OB_OPEN_REASON Reason,
|
||||||
|
|
||||||
InitializeListHead(&WinSta->DesktopListHead);
|
InitializeListHead(&WinSta->DesktopListHead);
|
||||||
|
|
||||||
|
DPRINT1("Create winsta atomtable\n");
|
||||||
WinSta->AtomTable = NULL;
|
WinSta->AtomTable = NULL;
|
||||||
|
|
||||||
Status = RtlCreateAtomTable(37, &WinSta->AtomTable);
|
Status = RtlCreateAtomTable(37, &WinSta->AtomTable);
|
||||||
|
if (!NT_SUCCESS(Status)) DPRINT1("Error creating atom table\n");
|
||||||
WinSta->SystemMenuTemplate = (HANDLE)0;
|
WinSta->SystemMenuTemplate = (HANDLE)0;
|
||||||
|
|
||||||
DPRINT("Window station successfully created.\n");
|
DPRINT("Window station successfully created.\n");
|
||||||
|
|
|
@ -417,15 +417,12 @@ NtUserGetWindowPlacement 2
|
||||||
NtUserGetWindowLong 3
|
NtUserGetWindowLong 3
|
||||||
NtUserGetWindowRect 2
|
NtUserGetWindowRect 2
|
||||||
NtUserGetWOWClass 2
|
NtUserGetWOWClass 2
|
||||||
NtUserHideCaret 1
|
|
||||||
NtUserHiliteMenuItem 4
|
NtUserHiliteMenuItem 4
|
||||||
NtUserImpersonateDdeClientWindow 2
|
NtUserImpersonateDdeClientWindow 2
|
||||||
NtUserInitializeClientPfnArrays 4
|
NtUserInitializeClientPfnArrays 4
|
||||||
NtUserInitTask 11
|
NtUserInitTask 11
|
||||||
NtUserInsertMenuItem 4
|
NtUserInsertMenuItem 4
|
||||||
NtUserInternalGetWindowText 3
|
NtUserInternalGetWindowText 3
|
||||||
NtUserInvalidateRect 3
|
|
||||||
NtUserInvalidateRgn 3
|
|
||||||
NtUserIsClipboardFormatAvailable 1
|
NtUserIsClipboardFormatAvailable 1
|
||||||
NtUserKillSystemTimer 2
|
NtUserKillSystemTimer 2
|
||||||
NtUserKillTimer 2
|
NtUserKillTimer 2
|
||||||
|
@ -523,7 +520,7 @@ NtUserSetWindowsHookEx 6
|
||||||
NtUserSetWindowStationUser 4
|
NtUserSetWindowStationUser 4
|
||||||
NtUserSetWindowWord 3
|
NtUserSetWindowWord 3
|
||||||
NtUserSetWinEventHook 8
|
NtUserSetWinEventHook 8
|
||||||
NtUserShowCaret 1
|
NtUserShowCaret 2
|
||||||
NtUserShowScrollBar 3
|
NtUserShowScrollBar 3
|
||||||
NtUserShowWindow 2
|
NtUserShowWindow 2
|
||||||
NtUserShowWindowAsync 2
|
NtUserShowWindowAsync 2
|
||||||
|
@ -544,12 +541,10 @@ NtUserUnregisterClass 3
|
||||||
NtUserUnregisterHotKey 2
|
NtUserUnregisterHotKey 2
|
||||||
NtUserUpdateInputContext 3
|
NtUserUpdateInputContext 3
|
||||||
NtUserUpdateInstance 3
|
NtUserUpdateInstance 3
|
||||||
NtUserUpdateWindow 1
|
|
||||||
NtUserUpdateLayeredWindow 9
|
NtUserUpdateLayeredWindow 9
|
||||||
NtUserUpdatePerUserSystemParameters 2
|
NtUserUpdatePerUserSystemParameters 2
|
||||||
NtUserUserHandleGrantAccess 3
|
NtUserUserHandleGrantAccess 3
|
||||||
NtUserValidateHandleSecure 1
|
NtUserValidateHandleSecure 1
|
||||||
NtUserValidateRect 2
|
|
||||||
NtUserVkKeyScanEx 3
|
NtUserVkKeyScanEx 3
|
||||||
NtUserWaitForInputIdle 3
|
NtUserWaitForInputIdle 3
|
||||||
NtUserWaitForMsgAndEvent 1
|
NtUserWaitForMsgAndEvent 1
|
||||||
|
|
Loading…
Reference in a new issue