diff --git a/reactos/iface/addsys/w32ksvc.db b/reactos/iface/addsys/w32ksvc.db index f821cb711bf..37c0bfce1ac 100644 --- a/reactos/iface/addsys/w32ksvc.db +++ b/reactos/iface/addsys/w32ksvc.db @@ -464,7 +464,7 @@ NtUserQueryWindow 2 NtUserReleaseDC 2 NtUserRealChildWindowFromPoint 3 NtUserRedrawWindow 4 -NtUserRegisterClassExWOW 7 +NtUserRegisterClassEx 6 NtUserRegisterHotKey 4 NtUserRegisterTasklist 1 NtUserRegisterWindowMessage 1 diff --git a/reactos/include/csrss/csrss.h b/reactos/include/csrss/csrss.h index e819f2cf5ba..353afd3d6b6 100644 --- a/reactos/include/csrss/csrss.h +++ b/reactos/include/csrss/csrss.h @@ -70,6 +70,8 @@ typedef struct typedef struct { PCONTROLDISPATCHER CtrlDispatcher; + UNICODE_STRING DesktopName; + UNICODE_STRING Title; } CSRSS_ALLOC_CONSOLE_REQUEST, *PCSRSS_ALLOC_CONSOLE_REQUEST; typedef struct @@ -533,6 +535,7 @@ typedef struct typedef struct { + HDESK hDesktop; HWND DesktopWindow; ULONG Width; ULONG Height; @@ -544,6 +547,7 @@ typedef struct typedef struct { + HDESK hDesktop; HWND DesktopWindow; } CSRSS_HIDE_DESKTOP_REQUEST, *PCSRSS_HIDE_DESKTOP_REQUEST; @@ -615,6 +619,16 @@ typedef struct HANDLE InputWaitHandle; } CSRSS_GET_INPUT_WAIT_HANDLE_REPLY, *PCSRSS_GET_INPUT_WAIT_HANDLE_REPLY; +typedef struct +{ + HWINSTA hWindowStation; +} CSRSS_REGISTER_SYSTEM_CLASSES_REQUEST, *PCSRSS_REGISTER_SYSTEM_CLASSES_REQUEST; + +typedef struct +{ + HWINSTA hWindowStation; +} CSRSS_REGISTER_SYSTEM_CLASSES_REPLY, *PCSRSS_REGISTER_SYSTEM_CALSSES_REPLY; + #define CSRSS_MAX_WRITE_CONSOLE_REQUEST \ (MAX_MESSAGE_DATA - sizeof(ULONG) - sizeof(CSRSS_WRITE_CONSOLE_REQUEST)) @@ -687,6 +701,7 @@ typedef struct #define CSRSS_GET_CONSOLE_OUTPUT_CP (0x33) #define CSRSS_SET_CONSOLE_OUTPUT_CP (0x34) #define CSRSS_GET_INPUT_WAIT_HANDLE (0x35) +#define CSRSS_REGISTER_SYSTEM_CLASSES (0x36) /* Keep in sync with definition below. */ #define CSRSS_REQUEST_HEADER_SIZE (LPC_MESSAGE_BASE_SIZE + sizeof(ULONG)) @@ -752,6 +767,7 @@ typedef struct CSRSS_GET_CONSOLE_OUTPUT_CP_REQUEST GetConsoleOutputCodePage; CSRSS_SET_CONSOLE_OUTPUT_CP_REQUEST SetConsoleOutputCodePage; CSRSS_GET_INPUT_WAIT_HANDLE_REQUEST GetConsoleInputWaitHandle; + CSRSS_REGISTER_SYSTEM_CLASSES_REQUEST RegisterSystemClassesRequest; } Data; }; }; @@ -807,6 +823,7 @@ typedef struct CSRSS_GET_CONSOLE_OUTPUT_CP_REPLY GetConsoleOutputCodePage; CSRSS_SET_CONSOLE_OUTPUT_CP_REPLY SetConsoleOutputCodePage; CSRSS_GET_INPUT_WAIT_HANDLE_REPLY GetConsoleInputWaitHandle; + CSRSS_REGISTER_SYSTEM_CLASSES_REPLY RegisterSystemClassesReply; } Data; }; }; diff --git a/reactos/include/user32/regcontrol.h b/reactos/include/user32/regcontrol.h index b4fbce79018..bc1fec58c07 100644 --- a/reactos/include/user32/regcontrol.h +++ b/reactos/include/user32/regcontrol.h @@ -1,4 +1,4 @@ -/* $Id: regcontrol.h,v 1.8 2004/05/16 19:31:06 navaraf Exp $ +/* $Id: regcontrol.h,v 1.9 2004/12/21 21:38:25 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS User32 @@ -26,8 +26,6 @@ struct builtin_class_descr HBRUSH brush; /* brush or system color */ }; -extern BOOL FASTCALL ControlsInit(LPCWSTR ClassName); - extern const struct builtin_class_descr BUTTON_builtin_class; extern const struct builtin_class_descr COMBO_builtin_class; extern const struct builtin_class_descr COMBOLBOX_builtin_class; @@ -42,4 +40,7 @@ extern const struct builtin_class_descr MENU_builtin_class; extern const struct builtin_class_descr SCROLL_builtin_class; extern const struct builtin_class_descr STATIC_builtin_class; +extern BOOL STDCALL PrivateCsrssRegisterBuiltinSystemWindowClasses(HWINSTA hWindowStation); +extern ATOM STDCALL PrivateCsrssRegisterSystemWindowClass(HWINSTA hWindowStation, WNDCLASSEXW *lpwcx, WNDPROC lpfnWndProcA); + #endif /* ROS_REGCONTROL_H */ diff --git a/reactos/include/win32k/ntuser.h b/reactos/include/win32k/ntuser.h index 23b7f5326cd..7e8adef876e 100644 --- a/reactos/include/win32k/ntuser.h +++ b/reactos/include/win32k/ntuser.h @@ -164,6 +164,7 @@ NtUserCallNextHookEx( #define NOPARAM_ROUTINE_ANYPOPUP 0xffff0006 #define NOPARAM_ROUTINE_CSRSS_INITIALIZED 0xffff0007 #define NOPARAM_ROUTINE_GDI_QUERY_TABLE 0xffff0008 +#define NOPARAM_ROUTINE_IS_GUI_ACTIVE 0xffff0009 DWORD STDCALL NtUserCallNoParam( @@ -1167,14 +1168,13 @@ NtUserRedrawWindow #define REGISTERCLASS_ALL (REGISTERCLASS_ANSI | REGISTERCLASS_SYSTEM) RTL_ATOM STDCALL -NtUserRegisterClassExWOW( +NtUserRegisterClassEx( CONST WNDCLASSEXW* lpwcx, PUNICODE_STRING ClassName, - PUNICODE_STRING ClassNameCopy, PUNICODE_STRING MenuName, WNDPROC wpExtra, DWORD Flags, - DWORD Unknown7); + HWINSTA hWindowStation OPTIONAL); BOOL STDCALL diff --git a/reactos/lib/kernel32/misc/console.c b/reactos/lib/kernel32/misc/console.c index 8cd65be4e07..f327bdb6f0f 100644 --- a/reactos/lib/kernel32/misc/console.c +++ b/reactos/lib/kernel32/misc/console.c @@ -1,4 +1,4 @@ -/* $Id: console.c,v 1.87 2004/12/18 13:33:09 weiden Exp $ +/* $Id: console.c,v 1.88 2004/12/21 21:38:25 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries @@ -1344,10 +1344,14 @@ ReadConsoleW(HANDLE hConsoleInput, */ BOOL STDCALL AllocConsole(VOID) { + PUNICODE_STRING DesktopName, Title; CSRSS_API_REQUEST Request; CSRSS_API_REPLY Reply; NTSTATUS Status; HANDLE hStdError; + ULONG BufSize; + PVOID BufferBase, BufferTargetBase; + PWCHAR szDest, szTargetDest; if(NtCurrentPeb()->ProcessParameters->hConsole) { @@ -1355,6 +1359,54 @@ BOOL STDCALL AllocConsole(VOID) SetLastErrorByStatus (STATUS_OBJECT_NAME_EXISTS); return FALSE; } + + DesktopName = &NtCurrentPeb()->ProcessParameters->DesktopInfo; + Title = &NtCurrentPeb()->ProcessParameters->WindowTitle; + + BufSize = ((DesktopName->Length >= sizeof(WCHAR)) ? DesktopName->Length + sizeof(WCHAR) : 0); + BufSize += ((Title->Length >= sizeof(WCHAR)) ? Title->Length + sizeof(WCHAR) : 0); + + if(BufSize > 0) + { + Status = CsrCaptureParameterBuffer(NULL, BufSize, &BufferBase, &BufferTargetBase); + if(!NT_SUCCESS(Status)) + { + SetLastErrorByStatus(Status); + return FALSE; + } + szDest = BufferBase; + szTargetDest = BufferTargetBase; + + if(DesktopName->Length >= sizeof(WCHAR)) + { + memcpy(szDest, DesktopName->Buffer, DesktopName->Length); + szDest = (PWSTR)((ULONG_PTR)szDest + DesktopName->Length); + *(szDest++) = L'\0'; + Request.Data.AllocConsoleRequest.DesktopName.Length = DesktopName->Length; + Request.Data.AllocConsoleRequest.DesktopName.MaximumLength = DesktopName->Length + sizeof(WCHAR); + Request.Data.AllocConsoleRequest.DesktopName.Buffer = szTargetDest; + szTargetDest = (PWSTR)((ULONG_PTR)szTargetDest + DesktopName->Length + sizeof(WCHAR)); + } + else + { + RtlInitUnicodeString(&Request.Data.AllocConsoleRequest.DesktopName, NULL); + } + + if(Title->Length >= sizeof(WCHAR)) + { + memcpy(szDest, Title->Buffer, Title->Length); + szDest = (PWSTR)((ULONG_PTR)szDest + Title->Length); + *(szDest++) = L'\0'; + Request.Data.AllocConsoleRequest.Title.Length = Title->Length; + Request.Data.AllocConsoleRequest.Title.MaximumLength = Title->Length + sizeof(WCHAR); + Request.Data.AllocConsoleRequest.Title.Buffer = szTargetDest; + szTargetDest = (PWSTR)((ULONG_PTR)szTargetDest + Title->Length + sizeof(WCHAR)); + } + else + { + RtlInitUnicodeString(&Request.Data.AllocConsoleRequest.Title, NULL); + } + } Request.Data.AllocConsoleRequest.CtrlDispatcher = (PCONTROLDISPATCHER) &ConsoleControlDispatcher; @@ -1362,9 +1414,20 @@ BOOL STDCALL AllocConsole(VOID) Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) ); if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) ) { - SetLastErrorByStatus ( Status ); + if(BufSize > 0) + { + CsrReleaseParameterBuffer(BufferBase); + } + SetLastErrorByStatus ( Status ); return FALSE; } + + if(BufSize > 0) + { + CsrReleaseParameterBuffer(BufferBase); + } + + /* FIXME - thread-safe exchange!!! */ NtCurrentPeb()->ProcessParameters->hConsole = Reply.Data.AllocConsoleReply.Console; SetStdHandle( STD_INPUT_HANDLE, Reply.Data.AllocConsoleReply.InputHandle ); SetStdHandle( STD_OUTPUT_HANDLE, Reply.Data.AllocConsoleReply.OutputHandle ); @@ -1554,7 +1617,7 @@ IntPeekConsoleInput(HANDLE hConsoleInput, LPDWORD lpNumberOfEventsRead, BOOL bUnicode) { - PCSRSS_API_REQUEST Request; + CSRSS_API_REQUEST Request; CSRSS_API_REPLY Reply; NTSTATUS Status; PVOID BufferBase; @@ -1576,34 +1639,24 @@ IntPeekConsoleInput(HANDLE hConsoleInput, return FALSE; } - Request = RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CSRSS_API_REQUEST)); - if(Request == NULL) - { - CsrReleaseParameterBuffer(BufferBase); - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - return FALSE; - } + Request.Type = CSRSS_PEEK_CONSOLE_INPUT; + Request.Data.PeekConsoleInputRequest.ConsoleHandle = hConsoleInput; + Request.Data.PeekConsoleInputRequest.Unicode = bUnicode; + Request.Data.PeekConsoleInputRequest.Length = nLength; + Request.Data.PeekConsoleInputRequest.InputRecord = (INPUT_RECORD*)BufferTargetBase; - Request->Type = CSRSS_PEEK_CONSOLE_INPUT; - Request->Data.PeekConsoleInputRequest.ConsoleHandle = hConsoleInput; - Request->Data.PeekConsoleInputRequest.Unicode = bUnicode; - Request->Data.PeekConsoleInputRequest.Length = nLength; - Request->Data.PeekConsoleInputRequest.InputRecord = (INPUT_RECORD*)BufferTargetBase; - - Status = CsrClientCallServer(Request, &Reply, + Status = CsrClientCallServer(&Request, &Reply, sizeof(CSRSS_API_REQUEST), sizeof(CSRSS_API_REPLY)); if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status)) { - RtlFreeHeap(GetProcessHeap(), 0, Request); CsrReleaseParameterBuffer(BufferBase); return FALSE; } memcpy(lpBuffer, BufferBase, sizeof(INPUT_RECORD) * Reply.Data.PeekConsoleInputReply.Length); - RtlFreeHeap(GetProcessHeap(), 0, Request); CsrReleaseParameterBuffer(BufferBase); if(lpNumberOfEventsRead != NULL) @@ -1869,7 +1922,7 @@ IntReadConsoleOutput(HANDLE hConsoleOutput, PSMALL_RECT lpReadRegion, BOOL bUnicode) { - PCSRSS_API_REQUEST Request; + CSRSS_API_REQUEST Request; CSRSS_API_REPLY Reply; PVOID BufferBase; PVOID BufferTargetBase; @@ -1890,31 +1943,22 @@ IntReadConsoleOutput(HANDLE hConsoleOutput, SetLastErrorByStatus(Status); return FALSE; } - - Request = RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CSRSS_API_REQUEST)); - if(Request == NULL) - { - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - CsrReleaseParameterBuffer(BufferBase); - return FALSE; - } - Request->Type = CSRSS_READ_CONSOLE_OUTPUT; - Request->Data.ReadConsoleOutputRequest.ConsoleHandle = hConsoleOutput; - Request->Data.ReadConsoleOutputRequest.Unicode = bUnicode; - Request->Data.ReadConsoleOutputRequest.BufferSize = dwBufferSize; - Request->Data.ReadConsoleOutputRequest.BufferCoord = dwBufferCoord; - Request->Data.ReadConsoleOutputRequest.ReadRegion = *lpReadRegion; - Request->Data.ReadConsoleOutputRequest.CharInfo = (PCHAR_INFO)BufferTargetBase; + Request.Type = CSRSS_READ_CONSOLE_OUTPUT; + Request.Data.ReadConsoleOutputRequest.ConsoleHandle = hConsoleOutput; + Request.Data.ReadConsoleOutputRequest.Unicode = bUnicode; + Request.Data.ReadConsoleOutputRequest.BufferSize = dwBufferSize; + Request.Data.ReadConsoleOutputRequest.BufferCoord = dwBufferCoord; + Request.Data.ReadConsoleOutputRequest.ReadRegion = *lpReadRegion; + Request.Data.ReadConsoleOutputRequest.CharInfo = (PCHAR_INFO)BufferTargetBase; - Status = CsrClientCallServer(Request, &Reply, + Status = CsrClientCallServer(&Request, &Reply, sizeof(CSRSS_API_REQUEST), sizeof(CSRSS_API_REPLY)); if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status)) { SetLastErrorByStatus(Status); - RtlFreeHeap(GetProcessHeap(), 0, Request); CsrReleaseParameterBuffer(BufferBase); return FALSE; } @@ -1923,8 +1967,7 @@ IntReadConsoleOutput(HANDLE hConsoleOutput, SizeY = Reply.Data.ReadConsoleOutputReply.ReadRegion.Bottom - Reply.Data.ReadConsoleOutputReply.ReadRegion.Top + 1; memcpy(lpBuffer, BufferBase, sizeof(CHAR_INFO) * SizeX * SizeY); - - RtlFreeHeap(GetProcessHeap(), 0, Request); + CsrReleaseParameterBuffer(BufferBase); *lpReadRegion = Reply.Data.ReadConsoleOutputReply.ReadRegion; @@ -1980,7 +2023,7 @@ IntWriteConsoleOutput(HANDLE hConsoleOutput, PSMALL_RECT lpWriteRegion, BOOL bUnicode) { - PCSRSS_API_REQUEST Request; + CSRSS_API_REQUEST Request; CSRSS_API_REPLY Reply; NTSTATUS Status; ULONG Size; @@ -1998,37 +2041,27 @@ IntWriteConsoleOutput(HANDLE hConsoleOutput, SetLastErrorByStatus(Status); return(FALSE); } - - Request = RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, - sizeof(CSRSS_API_REQUEST)); - if (Request == NULL) - { - CsrReleaseParameterBuffer(BufferBase); - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - return FALSE; - } - Request->Type = CSRSS_WRITE_CONSOLE_OUTPUT; - Request->Data.WriteConsoleOutputRequest.ConsoleHandle = hConsoleOutput; - Request->Data.WriteConsoleOutputRequest.Unicode = bUnicode; - Request->Data.WriteConsoleOutputRequest.BufferSize = dwBufferSize; - Request->Data.WriteConsoleOutputRequest.BufferCoord = dwBufferCoord; - Request->Data.WriteConsoleOutputRequest.WriteRegion = *lpWriteRegion; - Request->Data.WriteConsoleOutputRequest.CharInfo = + + Request.Type = CSRSS_WRITE_CONSOLE_OUTPUT; + Request.Data.WriteConsoleOutputRequest.ConsoleHandle = hConsoleOutput; + Request.Data.WriteConsoleOutputRequest.Unicode = bUnicode; + Request.Data.WriteConsoleOutputRequest.BufferSize = dwBufferSize; + Request.Data.WriteConsoleOutputRequest.BufferCoord = dwBufferCoord; + Request.Data.WriteConsoleOutputRequest.WriteRegion = *lpWriteRegion; + Request.Data.WriteConsoleOutputRequest.CharInfo = (CHAR_INFO*)BufferTargetBase; - Status = CsrClientCallServer(Request, &Reply, + Status = CsrClientCallServer(&Request, &Reply, sizeof(CSRSS_API_REQUEST), sizeof(CSRSS_API_REPLY)); if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status)) { CsrReleaseParameterBuffer(BufferBase); - RtlFreeHeap(GetProcessHeap(), 0, Request); SetLastErrorByStatus(Status); return FALSE; } - - RtlFreeHeap(GetProcessHeap(), 0, Request); + CsrReleaseParameterBuffer(BufferBase); *lpWriteRegion = Reply.Data.WriteConsoleOutputReply.WriteRegion; diff --git a/reactos/lib/ntdll/csr/lpc.c b/reactos/lib/ntdll/csr/lpc.c index dfe442f88cc..d844514021b 100644 --- a/reactos/lib/ntdll/csr/lpc.c +++ b/reactos/lib/ntdll/csr/lpc.c @@ -1,4 +1,4 @@ -/* $Id: lpc.c,v 1.13 2004/07/03 17:13:09 hbirr Exp $ +/* $Id: lpc.c,v 1.14 2004/12/21 21:38:26 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -71,7 +71,10 @@ CsrCaptureParameterBuffer(PVOID ParameterBuffer, { return(STATUS_NO_MEMORY); } - memcpy(Block, ParameterBuffer, ParameterBufferSize); + if(ParameterBuffer != NULL) + { + memcpy(Block, ParameterBuffer, ParameterBufferSize); + } *ClientAddress = Block; *ServerAddress = Block - CsrSectionMapBase + CsrSectionMapServerBase; return(STATUS_SUCCESS); diff --git a/reactos/lib/user32/controls/regcontrol.c b/reactos/lib/user32/controls/regcontrol.c index 661498789dd..601d865aba7 100644 --- a/reactos/lib/user32/controls/regcontrol.c +++ b/reactos/lib/user32/controls/regcontrol.c @@ -1,4 +1,4 @@ -/* $Id: regcontrol.c,v 1.20 2004/08/15 21:36:26 chorns Exp $ +/* $Id: regcontrol.c,v 1.21 2004/12/21 21:38:26 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS User32 @@ -10,60 +10,18 @@ */ #include "user32.h" -#include #include "user32/regcontrol.h" -#include "win32k/ntuser.h" -static void RegisterBuiltinClass(const struct builtin_class_descr *Descr) -{ - WNDCLASSEXW wc; - UNICODE_STRING ClassName; - UNICODE_STRING MenuName; - - wc.cbSize = sizeof(WNDCLASSEXW); - wc.lpszClassName = Descr->name; - wc.lpfnWndProc = Descr->procW; - wc.style = Descr->style; - wc.hInstance = User32Instance; - wc.hIcon = NULL; - wc.hIconSm = NULL; - wc.hCursor = LoadCursorW(NULL, Descr->cursor); - wc.hbrBackground = Descr->brush; - wc.lpszMenuName = NULL; - wc.cbClsExtra = 0; - wc.cbWndExtra = Descr->extra; - - MenuName.Length = - MenuName.MaximumLength = 0; - MenuName.Buffer = NULL; - - if (IS_ATOM(Descr->name)) - { - ClassName.Length = - ClassName.MaximumLength = 0; - ClassName.Buffer = (LPWSTR)Descr->name; - } else - { - RtlInitUnicodeString(&ClassName, Descr->name); - } - - NtUserRegisterClassExWOW( - &wc, - &ClassName, - &ClassName, - &MenuName, - Descr->procA, - REGISTERCLASS_SYSTEM, - 0); -} +#define NDEBUG +#include /*********************************************************************** - * ControlsInit + * PrivateCsrssRegisterBuiltinSystemWindowClasses * - * Register the classes for the builtin controls + * Register the classes for the builtin controls - Private to CSRSS! */ -BOOL FASTCALL -ControlsInit(LPCWSTR ClassName) +BOOL STDCALL +PrivateCsrssRegisterBuiltinSystemWindowClasses(HWINSTA hWindowStation) { static const struct builtin_class_descr *ClassDescriptions[] = { @@ -85,42 +43,102 @@ ControlsInit(LPCWSTR ClassName) &ICONTITLE_builtin_class, &STATIC_builtin_class }; - unsigned i; - BOOL Register; + const struct builtin_class_descr *Descr; + int i; + + for (i = 0; i < sizeof(ClassDescriptions) / sizeof(ClassDescriptions[0]); i++) + { + WNDCLASSEXW wc; + UNICODE_STRING ClassName; + UNICODE_STRING MenuName; - Register = FALSE; - if (IS_ATOM(ClassName)) - { - for (i = 0; - ! Register && i < sizeof(ClassDescriptions) / sizeof(ClassDescriptions[0]); - i++) - { - if (IS_ATOM(ClassDescriptions[i]->name)) - { - Register = (ClassName == ClassDescriptions[i]->name); - } - } - } - else - { - for (i = 0; - ! Register && i < sizeof(ClassDescriptions) / sizeof(ClassDescriptions[0]); - i++) - { - if (! IS_ATOM(ClassDescriptions[i]->name)) - { - Register = (0 == _wcsicmp(ClassName, ClassDescriptions[i]->name)); - } - } + Descr = ClassDescriptions[i]; + + wc.cbSize = sizeof(WNDCLASSEXW); + wc.lpszClassName = Descr->name; + wc.lpfnWndProc = Descr->procW; + wc.style = Descr->style; + wc.hInstance = User32Instance; + wc.hIcon = NULL; + wc.hIconSm = NULL; + /* don't load the cursor or icons! the system classes will load cursors + and icons from the resources when duplicating the classes into the + process class list - which happens when creating a window or + overwriting the classes using RegisterClass! */ + wc.hCursor = (HCURSOR)Descr->cursor; + wc.hbrBackground = Descr->brush; + wc.lpszMenuName = NULL; + wc.cbClsExtra = 0; + wc.cbWndExtra = Descr->extra; + + MenuName.Length = + MenuName.MaximumLength = 0; + MenuName.Buffer = NULL; + + if (IS_ATOM(Descr->name)) + { + ClassName.Length = + ClassName.MaximumLength = 0; + ClassName.Buffer = (LPWSTR)Descr->name; + } else + { + RtlInitUnicodeString(&ClassName, Descr->name); + } + + if(!NtUserRegisterClassEx( + &wc, + &ClassName, + &MenuName, + Descr->procA, + REGISTERCLASS_SYSTEM, + hWindowStation)) + { + if(IS_ATOM(Descr->name)) + { + DPRINT("Failed to register builtin class %ws\n", Descr->name); + } + else + { + DPRINT("Failed to register builtin class (Atom 0x%x)\n", Descr->name); + } + return FALSE; + } } - if (Register) - { - for (i = 0; i < sizeof(ClassDescriptions) / sizeof(ClassDescriptions[0]); i++) - { - RegisterBuiltinClass(ClassDescriptions[i]); - } - } - - return Register; + return TRUE; +} + + +/*********************************************************************** + * PrivateCsrssRegisterSystemWindowClass + * + * Register a system window class - Private to CSRSS! + */ +ATOM STDCALL +PrivateCsrssRegisterSystemWindowClass(HWINSTA hWindowStation, WNDCLASSEXW *lpwcx, WNDPROC lpfnWndProcA) +{ + UNICODE_STRING ClassName; + UNICODE_STRING MenuName; + + MenuName.Length = + MenuName.MaximumLength = 0; + MenuName.Buffer = NULL; + + if (IS_ATOM(lpwcx->lpszClassName)) + { + ClassName.Length = + ClassName.MaximumLength = 0; + ClassName.Buffer = (LPWSTR)lpwcx->lpszClassName; + } else + { + RtlInitUnicodeString(&ClassName, lpwcx->lpszClassName); + } + + return NtUserRegisterClassEx( + lpwcx, + &ClassName, + &MenuName, + lpfnWndProcA, + REGISTERCLASS_SYSTEM, + hWindowStation); } diff --git a/reactos/lib/user32/misc/misc.c b/reactos/lib/user32/misc/misc.c index 694ec5b7971..41fd62a09bf 100644 --- a/reactos/lib/user32/misc/misc.c +++ b/reactos/lib/user32/misc/misc.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: misc.c,v 1.12 2004/12/06 08:41:38 ion Exp $ +/* $Id: misc.c,v 1.13 2004/12/21 21:38:26 weiden Exp $ * * PROJECT: ReactOS user32.dll * FILE: lib/user32/misc/misc.c @@ -64,6 +64,13 @@ PrivateCsrssInitialized(VOID) NtUserCallNoParam(NOPARAM_ROUTINE_CSRSS_INITIALIZED); } +BOOL +STDCALL +PrivateCsrssIsGUIActive(VOID) +{ + return (BOOL)NtUserCallNoParam(NOPARAM_ROUTINE_IS_GUI_ACTIVE); +} + /* * @implemented diff --git a/reactos/lib/user32/user32.def b/reactos/lib/user32/user32.def index dd92c3563d8..07718b504dc 100644 --- a/reactos/lib/user32/user32.def +++ b/reactos/lib/user32/user32.def @@ -521,10 +521,6 @@ PostQuitMessage@4 PostThreadMessageA@16 PostThreadMessageW@16 PrintWindow@12 -PrivateCsrssAcquireOrReleaseInputOwnership@4 -PrivateCsrssRegisterPrimitive@0 -PrivateCsrssManualGuiCheck@4 -PrivateCsrssInitialized@0 PrivateExtractIconExA@20 PrivateExtractIconExW@20 PrivateExtractIconsA@32 @@ -742,4 +738,13 @@ wsprintfW wvsprintfA@12 wvsprintfW@12 +; REACTOS PRIVATE FUNCTIONS +PrivateCsrssRegisterBuiltinSystemWindowClasses@4 NONAME +PrivateCsrssRegisterSystemWindowClass@12 NONAME +PrivateCsrssAcquireOrReleaseInputOwnership@4 NONAME +PrivateCsrssRegisterPrimitive@0 NONAME +PrivateCsrssManualGuiCheck@4 NONAME +PrivateCsrssInitialized@0 NONAME +PrivateCsrssIsGUIActive@0 NONAME + ; EOF diff --git a/reactos/lib/user32/windows/class.c b/reactos/lib/user32/windows/class.c index 250f99f460f..dbfd1f7e42c 100644 --- a/reactos/lib/user32/windows/class.c +++ b/reactos/lib/user32/windows/class.c @@ -1,4 +1,4 @@ -/* $Id: class.c,v 1.53 2004/12/17 09:56:10 gvg Exp $ +/* $Id: class.c,v 1.54 2004/12/21 21:38:26 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS user32.dll @@ -40,8 +40,6 @@ static BOOL GetClassInfoExCommon( str = (LPWSTR)lpszClass; else { - extern BOOL ControlsInitialized; - if (unicode) { str = HEAP_strdupW ( lpszClass, wcslen(lpszClass) ); @@ -63,12 +61,6 @@ static BOOL GetClassInfoExCommon( return FALSE; } } - - /* Register built-in controls if not already done */ - if ( !ControlsInitialized ) - { - ControlsInitialized = ControlsInit(str); - } } str2.Length = str3.Length = 0; @@ -458,14 +450,13 @@ RegisterClassExA(CONST WNDCLASSEXA *lpwcx) RtlCreateUnicodeStringFromAsciiz(&ClassName, lpwcx->lpszClassName); } - Atom = NtUserRegisterClassExWOW( + Atom = NtUserRegisterClassEx( (WNDCLASSEXW*)&WndClass, &ClassName, - &ClassName, &MenuName, NULL, REGISTERCLASS_ANSI, - 0); + NULL); if (!IS_ATOM(lpwcx->lpszMenuName)) RtlFreeUnicodeString(&MenuName); @@ -533,14 +524,13 @@ RegisterClassExW(CONST WNDCLASSEXW *lpwcx) RtlInitUnicodeString(&ClassName, lpwcx->lpszClassName); } - return (ATOM)NtUserRegisterClassExWOW( + return (ATOM)NtUserRegisterClassEx( &WndClass, &ClassName, - &ClassName, &MenuName, NULL, 0, - 0); + NULL); } /* diff --git a/reactos/lib/user32/windows/window.c b/reactos/lib/user32/windows/window.c index 9e312bf853b..a78d90be2bf 100644 --- a/reactos/lib/user32/windows/window.c +++ b/reactos/lib/user32/windows/window.c @@ -1,4 +1,4 @@ -/* $Id: window.c,v 1.121 2004/12/16 03:57:35 rcampbell Exp $ +/* $Id: window.c,v 1.122 2004/12/21 21:38:26 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS user32.dll @@ -20,8 +20,6 @@ #define NDEBUG #include -BOOL ControlsInitialized = FALSE; - LRESULT DefWndNCPaint(HWND hWnd, HRGN hRgn); /* FUNCTIONS *****************************************************************/ @@ -194,12 +192,6 @@ CreateWindowExA(DWORD dwExStyle, } } - /* Register built-in controls if not already done */ - if (! ControlsInitialized) - { - ControlsInitialized = ControlsInit(ClassName.Buffer); - } - if (dwExStyle & WS_EX_MDICHILD) { if (!IS_ATOM(lpClassName)) @@ -279,12 +271,6 @@ CreateWindowExW(DWORD dwExStyle, WNDCLASSEXW wce; HANDLE Handle; - /* Register built-in controls if not already done */ - if (! ControlsInitialized) - { - ControlsInitialized = ControlsInit(lpClassName); - } - if (dwExStyle & WS_EX_MDICHILD) return CreateMDIWindowW(lpClassName, lpWindowName, dwStyle, x, y, nWidth, nHeight, hWndParent, hInstance, (LPARAM)lpParam); diff --git a/reactos/subsys/csrss/include/desktopbg.h b/reactos/subsys/csrss/include/desktopbg.h index 1a8cdc8d48a..0e94e4c2f8c 100644 --- a/reactos/subsys/csrss/include/desktopbg.h +++ b/reactos/subsys/csrss/include/desktopbg.h @@ -1,4 +1,4 @@ -/* $Id: desktopbg.h,v 1.2 2004/01/11 17:31:15 gvg Exp $ +/* $Id: desktopbg.h,v 1.3 2004/12/21 21:38:26 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries @@ -15,6 +15,7 @@ CSR_API(CsrCreateDesktop); CSR_API(CsrShowDesktop); CSR_API(CsrHideDesktop); +CSR_API(CsrRegisterSystemClasses); BOOL FASTCALL DtbgIsDesktopVisible(VOID); diff --git a/reactos/subsys/csrss/win32csr/desktopbg.c b/reactos/subsys/csrss/win32csr/desktopbg.c index 21a11722400..87557ec2318 100644 --- a/reactos/subsys/csrss/win32csr/desktopbg.c +++ b/reactos/subsys/csrss/win32csr/desktopbg.c @@ -1,4 +1,4 @@ -/* $Id: desktopbg.c,v 1.12 2004/12/01 18:38:04 weiden Exp $ +/* $Id: desktopbg.c,v 1.13 2004/12/21 21:38:26 weiden Exp $ * * reactos/subsys/csrss/win32csr/desktopbg.c * @@ -21,6 +21,7 @@ #include #include +#include #include "api.h" #include "desktopbg.h" @@ -28,6 +29,8 @@ #define NDEBUG #include +extern BOOL STDCALL PrivateCsrssIsGUIActive(VOID); + #define DESKTOP_WINDOW_ATOM 32880 #define PM_SHOW_DESKTOP 1 @@ -53,9 +56,6 @@ typedef struct tagPRIVATE_NOTIFY_DESKTOP }; } PRIVATE_NOTIFY_DESKTOP, *PPRIVATE_NOTIFY_DESKTOP; -static BOOL Initialized = FALSE; -static HWND VisibleDesktopWindow = NULL; - static LRESULT CALLBACK DtbgWindowProc(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam) { @@ -99,27 +99,29 @@ DtbgWindowProc(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam) case PM_SHOW_DESKTOP: { LRESULT Result; + + DPRINT("Show desktop: 0x%x (%d:%d)\n", Wnd, nmh->ShowDesktop.Width, nmh->ShowDesktop.Height); - Result = ! SetWindowPos(Wnd, - NULL, 0, 0, - nmh->ShowDesktop.Width, - nmh->ShowDesktop.Height, - SWP_NOACTIVATE | SWP_NOZORDER | SWP_SHOWWINDOW); + Result = SetWindowPos(Wnd, + NULL, 0, 0, + nmh->ShowDesktop.Width, + nmh->ShowDesktop.Height, + SWP_NOACTIVATE | SWP_NOZORDER | SWP_SHOWWINDOW); UpdateWindow(Wnd); - VisibleDesktopWindow = Wnd; return Result; } case PM_HIDE_DESKTOP: { LRESULT Result; + + DPRINT("Hide desktop: 0x%x\n", Wnd); - Result = ! SetWindowPos(Wnd, - NULL, 0, 0, 0, 0, - SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE | - SWP_HIDEWINDOW); + Result = SetWindowPos(Wnd, + NULL, 0, 0, 0, 0, + SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE | + SWP_HIDEWINDOW); UpdateWindow(Wnd); - VisibleDesktopWindow = NULL; return Result; } @@ -133,38 +135,6 @@ DtbgWindowProc(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam) return 0; } -static BOOL FASTCALL -DtbgInit() -{ - WNDCLASSEXW Class; - ATOM ClassAtom; - - /* - * Create the desktop window class - */ - Class.cbSize = sizeof(WNDCLASSEXW); - Class.style = 0; - Class.lpfnWndProc = DtbgWindowProc; - Class.cbClsExtra = 0; - Class.cbWndExtra = 0; - Class.hInstance = (HINSTANCE) GetModuleHandleW(NULL); - Class.hIcon = NULL; - Class.hCursor = NULL; - Class.hbrBackground = GetSysColorBrush(COLOR_BACKGROUND); - Class.lpszMenuName = NULL; - Class.lpszClassName = (LPCWSTR) DESKTOP_WINDOW_ATOM; - ClassAtom = RegisterClassExW(&Class); - if ((ATOM) 0 == ClassAtom) - { - DPRINT1("Unable to register desktop background class (error %d)\n", - GetLastError()); - return FALSE; - } - VisibleDesktopWindow = NULL; - - return TRUE; -} - static DWORD STDCALL DtbgDesktopThread(PVOID Data) { @@ -200,6 +170,8 @@ DtbgDesktopThread(PVOID Data) ThreadData->Status = STATUS_SUCCESS; SetEvent(ThreadData->Event); + + DPRINT("Desktop thread running... (wnd: 0x%x, PID:%d)\n", BackgroundWnd, GetCurrentProcessId()); while (GetMessageW(&msg, NULL, 0, 0)) { @@ -207,28 +179,75 @@ DtbgDesktopThread(PVOID Data) DispatchMessageW(&msg); } + DPRINT("Desktop thread terminating... (wnd: 0x%x)\n", BackgroundWnd); + return 1; } +CSR_API(CsrRegisterSystemClasses) +{ + WNDCLASSEXW wc; + + /* The hWindowStation handle is only valid while processing this request! */ + + /* + * This routine is called when creating an interactive window station. It sets + * up all system window classes so applications and csrss can use them later. + */ + + DPRINT("CsrRegisterSystemClasses\n"); + + Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY); + Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - LPC_MESSAGE_BASE_SIZE; + + /* + * Register the system window classes (buttons, edit controls, ...) that are + * managed by user32 + */ + if(!PrivateCsrssRegisterBuiltinSystemWindowClasses(Request->Data.RegisterSystemClassesRequest.hWindowStation)) + { + DPRINT1("Unable to register builtin system window classes: LastError: %d\n", GetLastError()); + return Reply->Status = STATUS_UNSUCCESSFUL; + } + + /* + * Register the desktop window class + */ + wc.cbSize = sizeof(WNDCLASSEXW); + wc.style = 0; + wc.lpfnWndProc = DtbgWindowProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = (HINSTANCE) GetModuleHandleW(NULL); + wc.hIcon = NULL; + wc.hCursor = NULL; + wc.hbrBackground = GetSysColorBrush(COLOR_BACKGROUND); + wc.lpszMenuName = NULL; + wc.lpszClassName = (LPCWSTR) DESKTOP_WINDOW_ATOM; + /* we don't support an ansi version of the window procedure, so don't specify it! */ + if(!PrivateCsrssRegisterSystemWindowClass(Request->Data.RegisterSystemClassesRequest.hWindowStation, + &wc, + NULL)) + { + DPRINT1("Unable to register the desktop window class: LastError: %d\n", GetLastError()); + return Reply->Status = STATUS_UNSUCCESSFUL; + } + + Reply->Data.RegisterSystemClassesReply.hWindowStation = Request->Data.RegisterSystemClassesRequest.hWindowStation; + + return Reply->Status = STATUS_SUCCESS; +} + CSR_API(CsrCreateDesktop) { DTBG_THREAD_DATA ThreadData; HANDLE ThreadHandle; - DPRINT("CsrCreateDesktop\n"); + DPRINT("CsrCreateDesktop (PID:%d)\n", GetCurrentProcessId()); Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY); Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - LPC_MESSAGE_BASE_SIZE; - if (! Initialized) - { - Initialized = TRUE; - if (! DtbgInit()) - { - return Reply->Status = STATUS_UNSUCCESSFUL; - } - } - /* * the desktop handle we got from win32k is in the scope of CSRSS so we can just use it */ @@ -252,8 +271,10 @@ CSR_API(CsrCreateDesktop) DPRINT1("Failed to create desktop window thread.\n"); return Reply->Status = STATUS_UNSUCCESSFUL; } + /* FIXME - we should wait on the thread handle as well, it may happen that the + thread crashes or doesn't start at all, we should catch this case + instead of waiting forever! */ CloseHandle(ThreadHandle); - WaitForSingleObject(ThreadData.Event, INFINITE); CloseHandle(ThreadData.Event); @@ -265,10 +286,21 @@ CSR_API(CsrCreateDesktop) CSR_API(CsrShowDesktop) { PRIVATE_NOTIFY_DESKTOP nmh; - DPRINT("CsrShowDesktop\n"); + + /* The hDesktop handle is only valid during processing this request! */ + DPRINT("CsrShowDesktop (hwnd: 0x%x) (PID:%d)\n", Request->Data.ShowDesktopRequest.DesktopWindow, GetCurrentProcessId()); + Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY); Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - LPC_MESSAGE_BASE_SIZE; + + /* We need to set the desktop for this thread to be able to send the messages + to the desktop thread! */ + if(!SetThreadDesktop(Request->Data.ShowDesktopRequest.hDesktop)) + { + DPRINT1("CsrShowDesktop: Failed to set thread desktop!\n"); + return Reply->Status = STATUS_UNSUCCESSFUL; + } nmh.hdr.hwndFrom = Request->Data.ShowDesktopRequest.DesktopWindow; nmh.hdr.idFrom = 0; @@ -281,7 +313,9 @@ CSR_API(CsrShowDesktop) WM_NOTIFY, (WPARAM)nmh.hdr.hwndFrom, (LPARAM)&nmh) - ? STATUS_UNSUCCESSFUL : STATUS_SUCCESS; + ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL; + + DPRINT("CsrShowDesktop: SendMessageW (Status: 0x%x), LastError: %d\n", Reply->Status, GetLastError()); return Reply->Status; } @@ -289,10 +323,21 @@ CSR_API(CsrShowDesktop) CSR_API(CsrHideDesktop) { PRIVATE_NOTIFY_DESKTOP nmh; - DPRINT("CsrHideDesktop\n"); + + /* The hDesktop handle is only valid while processing this request! */ + + DPRINT1("CsrHideDesktop (hwnd: 0x%x) (PID:%d)\n", Request->Data.ShowDesktopRequest.DesktopWindow, GetCurrentProcessId()); Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY); Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - LPC_MESSAGE_BASE_SIZE; + + /* We need to set the desktop for this thread to be able to send the messages + to the desktop thread! */ + if(!SetThreadDesktop(Request->Data.ShowDesktopRequest.hDesktop)) + { + DPRINT1("CsrShowDesktop: Failed to set thread desktop!\n"); + return Reply->Status = STATUS_UNSUCCESSFUL; + } nmh.hdr.hwndFrom = Request->Data.ShowDesktopRequest.DesktopWindow; nmh.hdr.idFrom = 0; @@ -302,7 +347,7 @@ CSR_API(CsrHideDesktop) WM_NOTIFY, (WPARAM)nmh.hdr.hwndFrom, (LPARAM)&nmh) - ? STATUS_UNSUCCESSFUL : STATUS_SUCCESS; + ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL; return Reply->Status; } @@ -310,12 +355,10 @@ CSR_API(CsrHideDesktop) BOOL FASTCALL DtbgIsDesktopVisible(VOID) { - if (NULL != VisibleDesktopWindow && ! IsWindowVisible(VisibleDesktopWindow)) - { - VisibleDesktopWindow = NULL; - } - - return NULL != VisibleDesktopWindow; + /* FIXME - This is a hack, it's not possible to determine whether a desktop + is visible or not unless a handle is supplied! we just check through + a private api if we're running in GUI mode */ + return PrivateCsrssIsGUIActive(); } /* EOF */ diff --git a/reactos/subsys/csrss/win32csr/dllmain.c b/reactos/subsys/csrss/win32csr/dllmain.c index 758cbdbd161..fb03f3c9451 100644 --- a/reactos/subsys/csrss/win32csr/dllmain.c +++ b/reactos/subsys/csrss/win32csr/dllmain.c @@ -1,4 +1,4 @@ -/* $Id: dllmain.c,v 1.7 2004/08/22 20:52:28 navaraf Exp $ +/* $Id: dllmain.c,v 1.8 2004/12/21 21:38:26 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries @@ -71,6 +71,7 @@ static CSRSS_API_DEFINITION Win32CsrApiDefinitions[] = CSRSS_DEFINE_API(CSRSS_SET_CONSOLE_CP, CsrSetConsoleCodePage), CSRSS_DEFINE_API(CSRSS_GET_CONSOLE_OUTPUT_CP, CsrGetConsoleOutputCodePage), CSRSS_DEFINE_API(CSRSS_SET_CONSOLE_OUTPUT_CP, CsrSetConsoleOutputCodePage), + CSRSS_DEFINE_API(CSRSS_REGISTER_SYSTEM_CLASSES, CsrRegisterSystemClasses), { 0, 0, 0, NULL } }; diff --git a/reactos/subsys/win32k/include/class.h b/reactos/subsys/win32k/include/class.h index d532003c41d..b8b49e4568c 100644 --- a/reactos/subsys/win32k/include/class.h +++ b/reactos/subsys/win32k/include/class.h @@ -73,6 +73,14 @@ ClassReferenceClassByNameOrAtom( LPCWSTR ClassNameOrAtom, HINSTANCE hInstance); +PWNDCLASS_OBJECT FASTCALL +IntCreateClass( + CONST WNDCLASSEXW *lpwcx, + DWORD Flags, + WNDPROC wpExtra, + PUNICODE_STRING MenuName, + RTL_ATOM Atom); + struct _WINDOW_OBJECT; ULONG FASTCALL IntGetClassLong(struct _WINDOW_OBJECT *WindowObject, ULONG Offset, BOOL Ansi); diff --git a/reactos/subsys/win32k/include/desktop.h b/reactos/subsys/win32k/include/desktop.h index 58949bf6d7e..a830f6f6be2 100644 --- a/reactos/subsys/win32k/include/desktop.h +++ b/reactos/subsys/win32k/include/desktop.h @@ -45,7 +45,7 @@ PDESKTOP_OBJECT FASTCALL IntGetActiveDesktop(VOID); NTSTATUS FASTCALL -IntShowDesktop(PDESKTOP_OBJECT Desktop, ULONG Width, ULONG Height); +IntShowDesktop(PDESKTOP_OBJECT Desktop); NTSTATUS FASTCALL IntHideDesktop(PDESKTOP_OBJECT Desktop); diff --git a/reactos/subsys/win32k/include/guicheck.h b/reactos/subsys/win32k/include/guicheck.h index 5bbb9951d96..650757b79d2 100644 --- a/reactos/subsys/win32k/include/guicheck.h +++ b/reactos/subsys/win32k/include/guicheck.h @@ -9,6 +9,7 @@ BOOL FASTCALL IntCreatePrimarySurface(); VOID FASTCALL IntDestroyPrimarySurface(); NTSTATUS FASTCALL InitGuiCheckImpl (VOID); +BOOL FASTCALL IntIsGUIActive(VOID); #endif /* _WIN32K_GUICHECK_H */ diff --git a/reactos/subsys/win32k/main/dllmain.c b/reactos/subsys/win32k/main/dllmain.c index 63eac2351f4..c6652c80f29 100644 --- a/reactos/subsys/win32k/main/dllmain.c +++ b/reactos/subsys/win32k/main/dllmain.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: dllmain.c,v 1.83 2004/12/12 01:40:37 weiden Exp $ +/* $Id: dllmain.c,v 1.84 2004/12/21 21:38:26 weiden Exp $ * * Entry Point for win32k.sys */ @@ -88,8 +88,6 @@ Win32kProcessCallback (struct _EPROCESS *Process, CleanupMonitorImpl(); GDI_CleanupForProcess(Process); - - IntGraphicsCheck(FALSE); /* * Deregister logon application automatically @@ -194,6 +192,8 @@ Win32kThreadCallback (struct _ETHREAD *Thread, { ObDereferenceObject(Win32Thread->Desktop); } + + IntGraphicsCheck(FALSE); } return STATUS_SUCCESS; diff --git a/reactos/subsys/win32k/ntuser/class.c b/reactos/subsys/win32k/ntuser/class.c index 8fa555c8d16..140d9e8340b 100644 --- a/reactos/subsys/win32k/ntuser/class.c +++ b/reactos/subsys/win32k/ntuser/class.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: class.c,v 1.62 2004/12/11 21:19:40 weiden Exp $ +/* $Id: class.c,v 1.63 2004/12/21 21:38:26 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -370,14 +370,13 @@ IntCreateClass( } RTL_ATOM STDCALL -NtUserRegisterClassExWOW( +NtUserRegisterClassEx( CONST WNDCLASSEXW* lpwcx, PUNICODE_STRING ClassName, - PUNICODE_STRING ClassNameCopy, PUNICODE_STRING MenuName, - WNDPROC wpExtra, /* FIXME: Windows uses this parameter for something different. */ + WNDPROC wpAnsiWindowProc OPTIONAL, /* FIXME: Windows uses this parameter for something different. */ DWORD Flags, - DWORD Unknown7) + HWINSTA hWindowStation OPTIONAL) /* * FUNCTION: @@ -423,7 +422,32 @@ NtUserRegisterClassExWOW( return (RTL_ATOM)0; } - WinStaObject = PsGetWin32Thread()->Desktop->WindowStation; + if(Flags & REGISTERCLASS_SYSTEM) + { + if(PsGetCurrentProcess() != CsrProcess) + { + DPRINT1("Process (ID: %d) attempted to register a system window class!\n", PsGetCurrentProcessId()); + SetLastWin32Error(ERROR_ACCESS_DENIED); + return (RTL_ATOM)0; + } + + Status = ObReferenceObjectByHandle(hWindowStation, + 0, + ExWindowStationObjectType, + UserMode, + (PVOID*)&WinStaObject, + NULL); + + if(!NT_SUCCESS(Status)) + { + SetLastNtError(Status); + return (RTL_ATOM)0; + } + } + else + { + WinStaObject = PsGetWin32Thread()->Desktop->WindowStation; + } if (ClassName->Length > 0) { @@ -436,7 +460,11 @@ NtUserRegisterClassExWOW( { DPRINT1("Failed adding class name (%S) to atom table\n", ClassName->Buffer); - SetLastNtError(Status); + SetLastNtError(Status); + if(Flags & REGISTERCLASS_SYSTEM) + { + ObDereferenceObject(WinStaObject); + } return((RTL_ATOM)0); } } @@ -444,13 +472,17 @@ NtUserRegisterClassExWOW( { Atom = (RTL_ATOM)(ULONG)ClassName->Buffer; } - ClassObject = IntCreateClass(&SafeClass, Flags, wpExtra, MenuName, Atom); + ClassObject = IntCreateClass(&SafeClass, Flags, wpAnsiWindowProc, MenuName, Atom); if (ClassObject == NULL) { if (ClassName->Length) { RtlDeleteAtomFromAtomTable(WinStaObject->AtomTable, Atom); } + if(Flags & REGISTERCLASS_SYSTEM) + { + ObDereferenceObject(WinStaObject); + } DPRINT("Failed creating window class object\n"); return((RTL_ATOM)0); } @@ -462,6 +494,11 @@ NtUserRegisterClassExWOW( IntLockGlobalClassList(); InsertTailList(&GlobalClassListHead, &ClassObject->GlobalListEntry); IntUnlockGlobalClassList(); + + if(Flags & REGISTERCLASS_SYSTEM) + { + ObDereferenceObject(WinStaObject); + } return(Atom); } diff --git a/reactos/subsys/win32k/ntuser/desktop.c b/reactos/subsys/win32k/ntuser/desktop.c index 90fbd10ce82..a291c6009ce 100644 --- a/reactos/subsys/win32k/ntuser/desktop.c +++ b/reactos/subsys/win32k/ntuser/desktop.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * $Id: desktop.c,v 1.28 2004/12/12 01:40:37 weiden Exp $ + * $Id: desktop.c,v 1.29 2004/12/21 21:38:27 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -47,7 +47,6 @@ ObFindHandleForObject(IN PEPROCESS Process, /* Currently active desktop */ PDESKTOP_OBJECT InputDesktop = NULL; -HDESK InputDesktopHandle = NULL; HDC ScreenDeviceContext = NULL; BOOL g_PaintDesktopVersion = FALSE; @@ -448,42 +447,94 @@ BOOL FASTCALL IntDesktopUpdatePerUserSettings(BOOL bEnable) /* PUBLIC FUNCTIONS ***********************************************************/ NTSTATUS FASTCALL -IntShowDesktop(PDESKTOP_OBJECT Desktop, ULONG Width, ULONG Height) +IntShowDesktop(PDESKTOP_OBJECT Desktop) { CSRSS_API_REQUEST Request; CSRSS_API_REPLY Reply; + NTSTATUS Status; + SIZEL DesktopSize; + PDC dc; + HDC hDC; + + IntGraphicsCheck(TRUE); + + hDC = IntGetScreenDC(); + if(hDC != NULL && (dc = DC_LockDc(hDC))) + { + BITMAPOBJ *BitmapObj = BITMAPOBJ_LockBitmap(dc->w.hBitmap); + if(BitmapObj != NULL) + { + DesktopSize.cx = BitmapObj->SurfObj.sizlBitmap.cx; + DesktopSize.cy = BitmapObj->SurfObj.sizlBitmap.cy; + BITMAPOBJ_UnlockBitmap(dc->w.hBitmap); + } + DC_UnlockDc(hDC); + } + else + { + DPRINT1("Failed to query screen size!\n"); + IntGraphicsCheck(FALSE); + return STATUS_UNSUCCESSFUL; + } + + DPRINT1("IntShowDesktop: 0x%x, %d, %d\n", Desktop->DesktopWindow, DesktopSize.cx, DesktopSize.cy); + + Status = CsrInsertObject((PVOID)Desktop, + NULL, + GENERIC_ALL, + 0, + NULL, + (HANDLE*)&Request.Data.ShowDesktopRequest.hDesktop); + if (NT_SUCCESS(Status)) + { + Request.Type = CSRSS_SHOW_DESKTOP; + Request.Data.ShowDesktopRequest.DesktopWindow = Desktop->DesktopWindow; + Request.Data.ShowDesktopRequest.Width = DesktopSize.cx; + Request.Data.ShowDesktopRequest.Height = DesktopSize.cy; - Request.Type = CSRSS_SHOW_DESKTOP; - Request.Data.ShowDesktopRequest.DesktopWindow = Desktop->DesktopWindow; - Request.Data.ShowDesktopRequest.Width = Width; - Request.Data.ShowDesktopRequest.Height = Height; + Status = CsrNotify(&Request, &Reply); + + CsrCloseHandle(Request.Data.ShowDesktopRequest.hDesktop); + } + + if(!NT_SUCCESS(Status)) + { + DPRINT1("IntShowDesktop: Failed to notify CSRSS!\n"); + IntGraphicsCheck(FALSE); + } - return CsrNotify(&Request, &Reply); + return Status; } NTSTATUS FASTCALL IntHideDesktop(PDESKTOP_OBJECT Desktop) { -#if 0 CSRSS_API_REQUEST Request; CSRSS_API_REPLY Reply; + NTSTATUS Status; + + Status = CsrInsertObject((PVOID)Desktop, + NULL, + GENERIC_ALL, + 0, + NULL, + (HANDLE*)&Request.Data.HideDesktopRequest.hDesktop); + if(NT_SUCCESS(Status)) + { + Request.Type = CSRSS_HIDE_DESKTOP; + Request.Data.HideDesktopRequest.DesktopWindow = Desktop->DesktopWindow; - Request.Type = CSRSS_HIDE_DESKTOP; - Request.Data.HideDesktopRequest.DesktopWindow = Desktop->DesktopWindow; - - return NotifyCsrss(&Request, &Reply); -#else - PWINDOW_OBJECT DesktopWindow; - - DesktopWindow = IntGetWindowObject(Desktop->DesktopWindow); - if (! DesktopWindow) - { - return ERROR_INVALID_WINDOW_HANDLE; - } - DesktopWindow->Style &= ~WS_VISIBLE; - - return STATUS_SUCCESS; -#endif + Status = CsrNotify(&Request, &Reply); + + CsrCloseHandle(Request.Data.HideDesktopRequest.hDesktop); + } + + if(NT_SUCCESS(Status)) + { + IntGraphicsCheck(FALSE); + } + + return Status; } /* @@ -796,30 +847,15 @@ NtUserOpenInputDesktop( BOOL fInherit, ACCESS_MASK dwDesiredAccess) { - PDESKTOP_OBJECT Object; NTSTATUS Status; HDESK Desktop; DPRINT("About to open input desktop\n"); - /* Get a pointer to the desktop object */ - - Status = IntValidateDesktopHandle( - InputDesktopHandle, - UserMode, - 0, - &Object); - - if (!NT_SUCCESS(Status)) - { - DPRINT("Validation of input desktop handle (0x%X) failed\n", InputDesktop); - return (HDESK)0; - } - /* Create a new handle to the object */ Status = ObOpenObjectByPointer( - Object, + InputDesktop, 0, NULL, dwDesiredAccess, @@ -827,8 +863,6 @@ NtUserOpenInputDesktop( UserMode, (HANDLE*)&Desktop); - ObDereferenceObject(Object); - if (NT_SUCCESS(Status)) { DPRINT("Successfully opened input desktop\n"); @@ -1055,7 +1089,7 @@ NtUserPaintDesktop(HDC hDC) BOOL STDCALL NtUserSwitchDesktop(HDESK hDesktop) { - PDESKTOP_OBJECT DesktopObject; + PDESKTOP_OBJECT DesktopObject, PreviousDesktop; NTSTATUS Status; DPRINT("About to switch desktop (0x%X)\n", hDesktop); @@ -1090,12 +1124,26 @@ NtUserSwitchDesktop(HDESK hDesktop) /* FIXME: Connect to input device */ /* Set the active desktop in the desktop's window station. */ - DesktopObject->WindowStation->ActiveDesktop = DesktopObject; + PreviousDesktop = InterlockedExchangePointer(&DesktopObject->WindowStation->ActiveDesktop, DesktopObject); + if(PreviousDesktop != DesktopObject) + { + /* FIXME - nasty hack... */ - /* Set the global state. */ - InputDesktop = DesktopObject; - InputDesktopHandle = hDesktop; - InputWindowStation = DesktopObject->WindowStation; + if(PreviousDesktop != NULL) + { + IntHideDesktop(PreviousDesktop); + } + + /* Set the global state. */ + InputDesktop = DesktopObject; + InputWindowStation = DesktopObject->WindowStation; + + /* FIXME - HACK! This is only because we want GUI on demand! */ + if(IntIsGUIActive()) + { + IntShowDesktop(DesktopObject); + } + } ObDereferenceObject(DesktopObject); diff --git a/reactos/subsys/win32k/ntuser/guicheck.c b/reactos/subsys/win32k/ntuser/guicheck.c index dd19e56bc9c..f78b2802146 100644 --- a/reactos/subsys/win32k/ntuser/guicheck.c +++ b/reactos/subsys/win32k/ntuser/guicheck.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: guicheck.c,v 1.20 2004/08/08 17:57:34 weiden Exp $ +/* $Id: guicheck.c,v 1.21 2004/12/21 21:38:27 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -79,6 +79,12 @@ RemoveGuiApp(PW32PROCESS W32Data) } } +BOOL FASTCALL +IntIsGUIActive(VOID) +{ + return NrGuiAppsRunning > 0; +} + BOOL FASTCALL IntGraphicsCheck(BOOL Create) { diff --git a/reactos/subsys/win32k/ntuser/misc.c b/reactos/subsys/win32k/ntuser/misc.c index bb9c67cdcac..a1021b13ac0 100644 --- a/reactos/subsys/win32k/ntuser/misc.c +++ b/reactos/subsys/win32k/ntuser/misc.c @@ -1,4 +1,4 @@ -/* $Id: misc.c,v 1.92 2004/12/12 23:08:11 navaraf Exp $ +/* $Id: misc.c,v 1.93 2004/12/21 21:38:27 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -134,6 +134,10 @@ NtUserCallNoParam(DWORD Routine) case NOPARAM_ROUTINE_GDI_QUERY_TABLE: Result = (DWORD)GDI_MapHandleTable(NtCurrentProcess()); break; + + case NOPARAM_ROUTINE_IS_GUI_ACTIVE: + Result = (DWORD)IntIsGUIActive(); + break; default: DPRINT1("Calling invalid routine number 0x%x in NtUserCallNoParam\n", Routine); diff --git a/reactos/subsys/win32k/ntuser/winsta.c b/reactos/subsys/win32k/ntuser/winsta.c index d06aceac0b1..16ded6073fb 100644 --- a/reactos/subsys/win32k/ntuser/winsta.c +++ b/reactos/subsys/win32k/ntuser/winsta.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * $Id: winsta.c,v 1.68 2004/12/12 01:40:38 weiden Exp $ + * $Id: winsta.c,v 1.69 2004/12/21 21:38:27 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -199,6 +199,11 @@ IntInitializeDesktopGraphics(VOID) NtUserAcquireOrReleaseInputOwnership(FALSE); + /* FIXME - HACK - this is to restore the previously visible desktop! */ + if(IntGetActiveDesktop() != NULL) + { + IntShowDesktop(IntGetActiveDesktop()); + } return TRUE; } @@ -222,6 +227,39 @@ IntGetScreenDC(VOID) return ScreenDeviceContext; } +NTSTATUS FASTCALL +IntRegisterSystemWindowClasses(PWINSTATION_OBJECT WinStaObject) +{ + CSRSS_API_REQUEST Request; + CSRSS_API_REPLY Reply; + HWINSTA hWindowStation; + NTSTATUS Status; + + /* + * Create a valid handle for CSRSS + */ + + Status = CsrInsertObject((PVOID)WinStaObject, + NULL, + GENERIC_ALL, + 0, + NULL, + (HANDLE*)&hWindowStation); + if (!NT_SUCCESS(Status)) + { + return Status; + } + + Request.Type = CSRSS_REGISTER_SYSTEM_CLASSES; + Request.Data.RegisterSystemClassesRequest.hWindowStation = hWindowStation; + + Status = CsrNotify(&Request, &Reply); + + CsrCloseHandle(hWindowStation); + + return Status; +} + /* PUBLIC FUNCTIONS ***********************************************************/ /* @@ -342,23 +380,6 @@ NtUserCreateWindowStation( return 0; } - Status = ObInsertObject( - (PVOID)WindowStationObject, - NULL, - STANDARD_RIGHTS_REQUIRED, - 0, - NULL, - (PVOID*)&WindowStation); - - if (!NT_SUCCESS(Status)) - { - DPRINT("Failed creating window station (%wZ)\n", &WindowStationName); - ExFreePool(WindowStationName.Buffer); - SetLastNtError(STATUS_INSUFFICIENT_RESOURCES); - ObDereferenceObject(WindowStationObject); - return 0; - } - /* * Initialize the new window station object */ @@ -383,6 +404,8 @@ NtUserCreateWindowStation( SetLastNtError(STATUS_INSUFFICIENT_RESOURCES); return 0; } + + WindowStationObject->ActiveDesktop = NULL; InitHotKeys(WindowStationObject); @@ -403,12 +426,50 @@ NtUserCreateWindowStation( CurInfo->DblClickHeight = 4; WindowStationObject->SystemCursor = CurInfo; - + if (!IntSetupCurIconHandles(WindowStationObject)) { DPRINT1("Setting up the Cursor/Icon Handle table failed!\n"); /* FIXME: Complain more loudly? */ } + + Status = ObInsertObject( + (PVOID)WindowStationObject, + NULL, + STANDARD_RIGHTS_REQUIRED, + 0, + NULL, + (PVOID*)&WindowStation); + + if (!NT_SUCCESS(Status)) + { + DPRINT("Failed creating window station (%wZ)\n", &WindowStationName); + ExFreePool(WindowStationName.Buffer); + SetLastNtError(STATUS_INSUFFICIENT_RESOURCES); + ObDereferenceObject(WindowStationObject); + return 0; + } + + /* Register the system window classes by CSRSS. This works even though CSRSS + is not assigned to a window station (because it can't!). The desktop + background windows however will be created by CSRSS when needed. This is + NOT a hack because CSRSS can manage multiple desktops in different window + stations, so whenever CSRSS uses win32 api, the window station is determined + by the desktop the calling thread is attached to. The reason it works is that + we pass the window station handle to NtUserRegisterClass when registering + a system window class - which is only possible in the context of CSRSS so + no other application can mess with this. We need to pass that handle so + it knows where to register the classes in - basically because at this point + CSRSS can't be assigned to any desktop - which would be required to register + regular window classes. This is NOT a hack, it's the only clean and consistent + way to do what we need to do. + + - Thomas */ + if(!NT_SUCCESS(IntRegisterSystemWindowClasses(WindowStationObject))) + { + DPRINT1("Registering the desktop window class failed!\n"); + /* FIXME: Complain more loudly? */ + } DPRINT("Window station successfully created (%wZ)\n", &WindowStationName); ExFreePool(WindowStationName.Buffer); diff --git a/reactos/subsys/win32k/objects/dc.c b/reactos/subsys/win32k/objects/dc.c index 07f7f1c621b..2645b0d2561 100644 --- a/reactos/subsys/win32k/objects/dc.c +++ b/reactos/subsys/win32k/objects/dc.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: dc.c,v 1.153 2004/12/13 05:23:59 royce Exp $ +/* $Id: dc.c,v 1.154 2004/12/21 21:38:27 weiden Exp $ * * DC.C - Device context functions * @@ -664,7 +664,6 @@ IntCreatePrimarySurface() /* FIXME - why does EngEraseSurface() sometimes crash? EngEraseSurface(SurfObj, &SurfaceRect, 0); */ EngUnlockSurface(SurfObj); - IntShowDesktop(IntGetActiveDesktop(), SurfSize.cx, SurfSize.cy); break; }