-/* $Id$
- *
- * init.c - ReactOS/Win32 Console+User Enviroment Subsystem Server - Initialization
- *
- * ReactOS Operating System
- *
- * --------------------------------------------------------------------
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * --------------------------------------------------------------------
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS User API Server DLL
+ * FILE: win32ss/user/winsrv/init.c
+ * PURPOSE: Initialization
+ * PROGRAMMERS: Dmitry Philippov (shedon@mail.ru)
+ * Hermes Belusca-Maito (hermes.belusca@sfr.fr)
*/
+
+/* INCLUDES *******************************************************************/
+
#include "winsrv.h"
+#include "api.h"
-//#define NDEBUG
+#define NDEBUG
#include <debug.h>
-HANDLE WinSrvApiPort = NULL;
+/* GLOBALS ********************************************************************/
-/**********************************************************************
- * NAME PRIVATE
- * ConStaticServerThread/1
- */
-VOID WINAPI ConStaticServerThread (PVOID x)
+HINSTANCE UserServerDllInstance = NULL;
+
+/* Memory */
+HANDLE UserServerHeap = NULL; // Our own heap.
+
+// Windows Server 2003 table from http://j00ru.vexillium.org/csrss_list/api_list.html#Windows_2k3
+PCSR_API_ROUTINE UserServerApiDispatchTable[UserpMaxApiNumber - USERSRV_FIRST_API_NUMBER] =
+{
+ SrvExitWindowsEx,
+ // SrvEndTask,
+ // SrvLogon,
+ SrvRegisterServicesProcess, // Not present in Win7
+ // SrvActivateDebugger,
+ // SrvGetThreadConsoleDesktop, // Not present in Win7
+ // SrvDeviceEvent,
+ SrvRegisterLogonProcess, // Not present in Win7
+ // SrvCreateSystemThreads,
+ // SrvRecordShutdownReason,
+ // SrvCancelShutdown, // Added in Vista
+ // SrvConsoleHandleOperation, // Added in Win7
+ // SrvGetSetShutdownBlockReason, // Added in Vista
+};
+
+BOOLEAN UserServerApiServerValidTable[UserpMaxApiNumber - USERSRV_FIRST_API_NUMBER] =
{
- NTSTATUS Status = STATUS_SUCCESS;
- PPORT_MESSAGE Request = (PPORT_MESSAGE) x;
- PPORT_MESSAGE Reply = NULL;
- ULONG MessageType = 0;
-
- DPRINT("WINSRV: %s(%08lx) called\n", __FUNCTION__, x);
-
- MessageType = Request->u2.s2.Type;
- DPRINT("WINSRV: %s(%08lx) received a message (Type=%d)\n",
- __FUNCTION__, x, MessageType);
- switch (MessageType)
- {
- default:
- Reply = Request;
- Status = NtReplyPort (WinSrvApiPort, Reply);
- break;
- }
+ FALSE, // SrvExitWindowsEx
+ // FALSE, // SrvEndTask
+ // FALSE, // SrvLogon
+ FALSE, // SrvRegisterServicesProcess
+ // FALSE, // SrvActivateDebugger
+ // TRUE, // SrvGetThreadConsoleDesktop
+ // FALSE, // SrvDeviceEvent
+ FALSE, // SrvRegisterLogonProcess
+ // FALSE, // SrvCreateSystemThreads
+ // FALSE, // SrvRecordShutdownReason
+ // FALSE, // SrvCancelShutdown
+ // FALSE, // SrvConsoleHandleOperation
+ // FALSE, // SrvGetSetShutdownBlockReason
+};
+
+PCHAR UserServerApiNameTable[UserpMaxApiNumber - USERSRV_FIRST_API_NUMBER] =
+{
+ "SrvExitWindowsEx",
+ // "SrvEndTask",
+ // "SrvLogon",
+ "SrvRegisterServicesProcess",
+ // "SrvActivateDebugger",
+ // "SrvGetThreadConsoleDesktop",
+ // "SrvDeviceEvent",
+ "SrvRegisterLogonProcess",
+ // "SrvCreateSystemThreads",
+ // "SrvRecordShutdownReason",
+ // "SrvCancelShutdown",
+ // "SrvConsoleHandleOperation",
+ // "SrvGetSetShutdownBlockReason",
+};
+
+
+/* FUNCTIONS ******************************************************************/
+
+// PUSER_SOUND_SENTRY. Used in basesrv.dll
+BOOL WINAPI _UserSoundSentry(VOID)
+{
+ // TODO: Do something.
+ return TRUE;
+}
+
+ULONG
+InitializeVideoAddressSpace(VOID)
+{
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ UNICODE_STRING PhysMemName = RTL_CONSTANT_STRING(L"\\Device\\PhysicalMemory");
+ NTSTATUS Status;
+ HANDLE PhysMemHandle;
+ PVOID BaseAddress;
+ LARGE_INTEGER Offset;
+ SIZE_T ViewSize;
+ CHAR IVTAndBda[1024+256];
+
+ /* Free the 1MB pre-reserved region. In reality, ReactOS should simply support us mapping the view into the reserved area, but it doesn't. */
+ BaseAddress = 0;
+ ViewSize = 1024 * 1024;
+ Status = ZwFreeVirtualMemory(NtCurrentProcess(),
+ &BaseAddress,
+ &ViewSize,
+ MEM_RELEASE);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Couldn't unmap reserved memory (%x)\n", Status);
+ return 0;
+ }
+
+ /* Open the physical memory section */
+ InitializeObjectAttributes(&ObjectAttributes,
+ &PhysMemName,
+ 0,
+ NULL,
+ NULL);
+ Status = ZwOpenSection(&PhysMemHandle,
+ SECTION_ALL_ACCESS,
+ &ObjectAttributes);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Couldn't open \\Device\\PhysicalMemory\n");
+ return 0;
+ }
+
+ /* Map the BIOS and device registers into the address space */
+ Offset.QuadPart = 0xa0000;
+ ViewSize = 0x100000 - 0xa0000;
+ BaseAddress = (PVOID)0xa0000;
+ Status = ZwMapViewOfSection(PhysMemHandle,
+ NtCurrentProcess(),
+ &BaseAddress,
+ 0,
+ ViewSize,
+ &Offset,
+ &ViewSize,
+ ViewUnmap,
+ 0,
+ PAGE_EXECUTE_READWRITE);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Couldn't map physical memory (%x)\n", Status);
+ ZwClose(PhysMemHandle);
+ return 0;
+ }
+
+ /* Close physical memory section handle */
+ ZwClose(PhysMemHandle);
+
+ if (BaseAddress != (PVOID)0xa0000)
+ {
+ DPRINT1("Couldn't map physical memory at the right address (was %x)\n",
+ BaseAddress);
+ return 0;
+ }
+
+ /* Allocate some low memory to use for the non-BIOS
+ * parts of the v86 mode address space
+ */
+ BaseAddress = (PVOID)0x1;
+ ViewSize = 0xa0000 - 0x1000;
+ Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
+ &BaseAddress,
+ 0,
+ &ViewSize,
+ MEM_RESERVE | MEM_COMMIT,
+ PAGE_EXECUTE_READWRITE);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to allocate virtual memory (Status %x)\n", Status);
+ return 0;
+ }
+ if (BaseAddress != (PVOID)0x0)
+ {
+ DPRINT1("Failed to allocate virtual memory at right address (was %x)\n",
+ BaseAddress);
+ return 0;
+ }
+
+ /* Get the real mode IVT and BDA from the kernel */
+ Status = NtVdmControl(VdmInitialize, IVTAndBda);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("NtVdmControl failed (status %x)\n", Status);
+ return 0;
+ }
+
+ /* Return success */
+ return 1;
}
/**********************************************************************
- * NAME PRIVATE
- * UserStaticServerThread/1
+ * CsrpInitVideo/3
+ *
+ * TODO: we need a virtual device for sessions other than
+ * TODO: the console one
*/
-VOID WINAPI UserStaticServerThread (PVOID x)
+NTSTATUS
+CsrpInitVideo(VOID)
{
- NTSTATUS Status = STATUS_SUCCESS;
- PPORT_MESSAGE Request = (PPORT_MESSAGE) x;
- PPORT_MESSAGE Reply = NULL;
- ULONG MessageType = 0;
-
- DPRINT("WINSRV: %s(%08lx) called\n", __FUNCTION__, x);
-
- MessageType = Request->u2.s2.Type;
- DPRINT("WINSRV: %s(%08lx) received a message (Type=%d)\n",
- __FUNCTION__, x, MessageType);
- switch (MessageType)
- {
- default:
- Reply = Request;
- Status = NtReplyPort (WinSrvApiPort, Reply);
- break;
- }
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\??\\DISPLAY1");
+ IO_STATUS_BLOCK Iosb;
+ HANDLE VideoHandle = (HANDLE) 0;
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ DPRINT("CSR: %s called\n", __FUNCTION__);
+
+ InitializeVideoAddressSpace();
+
+ InitializeObjectAttributes(&ObjectAttributes,
+ &DeviceName,
+ 0,
+ NULL,
+ NULL);
+ Status = NtOpenFile(&VideoHandle,
+ FILE_ALL_ACCESS,
+ &ObjectAttributes,
+ &Iosb,
+ 0,
+ 0);
+ if (NT_SUCCESS(Status))
+ {
+ NtClose(VideoHandle);
+ }
+
+ return Status;
}
-/*=====================================================================
- * PUBLIC API
- *===================================================================*/
+VOID
+WINAPI
+PrivateCsrssManualGuiCheck(LONG Check)
+{
+ NtUserCallOneParam(Check, ONEPARAM_ROUTINE_CSRSS_GUICHECK);
+}
+
+/*** HACK from win32csr... ***/
+static HHOOK hhk = NULL;
+
+LRESULT
+CALLBACK
+KeyboardHookProc(int nCode,
+ WPARAM wParam,
+ LPARAM lParam)
+{
+ return CallNextHookEx(hhk, nCode, wParam, lParam);
+}
+/*** END - HACK from win32csr... ***/
-NTSTATUS WINAPI ConServerDllInitialization (ULONG ArgumentCount,
- LPWSTR *Argument)
+DWORD
+WINAPI
+CreateSystemThreads(PVOID pParam)
{
- NTSTATUS Status = STATUS_SUCCESS;
-
- DPRINT("WINSRV: %s called\n", __FUNCTION__);
-
- // Get the listening port from csrsrv.dll
- WinSrvApiPort = CsrQueryApiPort ();
- if (NULL == WinSrvApiPort)
- {
- return STATUS_UNSUCCESSFUL;
- }
- // Register our message dispatcher
- Status = CsrAddStaticServerThread (ConStaticServerThread);
- if (NT_SUCCESS(Status))
- {
- //TODO: perform the real console server internal initialization here
- }
- return Status;
+ NtUserCallOneParam((DWORD)pParam, ONEPARAM_ROUTINE_CREATESYSTEMTHREADS);
+ DPRINT1("This thread should not terminate!\n");
+ return 0;
}
-NTSTATUS WINAPI UserServerDllInitialization (ULONG ArgumentCount,
- LPWSTR *Argument)
+CSR_SERVER_DLL_INIT(UserServerDllInitialization)
{
- NTSTATUS Status = STATUS_SUCCESS;
-
- DPRINT("WINSRV: %s called\n", __FUNCTION__);
-
- // Get the listening port from csrsrv.dll
- WinSrvApiPort = CsrQueryApiPort ();
- if (NULL == WinSrvApiPort)
- {
- return STATUS_UNSUCCESSFUL;
- }
- // Register our message dispatcher
- Status = CsrAddStaticServerThread (UserStaticServerThread);
- if (NT_SUCCESS(Status))
- {
- //TODO: perform the real user server internal initialization here
- }
- return Status;
+/*** From win32csr... ***/
+ HANDLE ServerThread;
+ CLIENT_ID ClientId;
+ NTSTATUS Status;
+ UINT i;
+/*** END - From win32csr... ***/
+
+ /* Initialize the memory */
+ UserServerHeap = RtlGetProcessHeap();
+
+ /* Initialize the video */
+ CsrpInitVideo();
+ NtUserInitialize(0, NULL, NULL);
+ PrivateCsrssManualGuiCheck(0);
+
+ /* Setup the DLL Object */
+ LoadedServerDll->ApiBase = USERSRV_FIRST_API_NUMBER;
+ LoadedServerDll->HighestApiSupported = UserpMaxApiNumber;
+ LoadedServerDll->DispatchTable = UserServerApiDispatchTable;
+ LoadedServerDll->ValidTable = UserServerApiServerValidTable;
+ LoadedServerDll->NameTable = UserServerApiNameTable;
+ LoadedServerDll->SizeOfProcessData = 0;
+ LoadedServerDll->ConnectCallback = NULL;
+ LoadedServerDll->DisconnectCallback = NULL;
+ LoadedServerDll->HardErrorCallback = UserServerHardError;
+ LoadedServerDll->ShutdownProcessCallback = NULL;
+
+ UserServerDllInstance = LoadedServerDll->ServerHandle;
+
+/*** From win32csr... See r54125 ***/
+ /* Start the Raw Input Thread and the Desktop Thread */
+ for (i = 0; i < 2; ++i)
+ {
+ Status = RtlCreateUserThread(NtCurrentProcess(), NULL, TRUE, 0, 0, 0, (PTHREAD_START_ROUTINE)CreateSystemThreads, (PVOID)i, &ServerThread, &ClientId);
+ if (NT_SUCCESS(Status))
+ {
+ NtResumeThread(ServerThread, NULL);
+ NtClose(ServerThread);
+ }
+ else
+ DPRINT1("Cannot start Raw Input Thread!\n");
+ }
+/*** END - From win32csr... ***/
+
+ /* All done */
+ return STATUS_SUCCESS;
+}
+
+BOOL
+WINAPI
+DllMain(IN HINSTANCE hInstanceDll,
+ IN DWORD dwReason,
+ IN LPVOID lpReserved)
+{
+ UNREFERENCED_PARAMETER(hInstanceDll);
+ UNREFERENCED_PARAMETER(dwReason);
+ UNREFERENCED_PARAMETER(lpReserved);
+
+ if (DLL_PROCESS_ATTACH == dwReason)
+ {
+ DPRINT1("WINSRV - HACK: Use keyboard hook hack\n");
+/*** HACK from win32csr... ***/
+//
+// HACK HACK HACK ReactOS to BOOT! Initialization BUG ALERT! See bug 5655.
+//
+ hhk = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookProc, NULL, 0);
+// BUG ALERT! BUG ALERT! BUG ALERT! BUG ALERT! BUG ALERT! BUG ALERT! BUG ALERT!
+// BUG ALERT! BUG ALERT! BUG ALERT! BUG ALERT! BUG ALERT! BUG ALERT! BUG ALERT!
+// BUG ALERT! BUG ALERT! BUG ALERT! BUG ALERT! BUG ALERT! BUG ALERT! BUG ALERT!
+
+/*** END - HACK from win32csr... ***/
+ }
+
+ return TRUE;
}
/* EOF */