-/* $Id: smss.c 12852 2005-01-06 13:58:04Z mf $\r
- *\r
- * client.c - Session Manager client Management\r
- * \r
- * ReactOS Operating System\r
- * \r
- * --------------------------------------------------------------------\r
- *\r
- * This software is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License as\r
- * published by the Free Software Foundation; either version 2 of the\r
- * License, or (at your option) any later version.\r
- *\r
- * This software is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
- * General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this software; see the file COPYING.LIB. If not, write\r
- * to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge,\r
- * MA 02139, USA. \r
- *\r
- * --------------------------------------------------------------------\r
- */\r
-#define NTOS_MODE_USER\r
-#include <ntos.h>\r
-#include "smss.h"\r
-#include <sm/helper.h>\r
-\r
-#define NDEBUG\r
-#include <debug.h>\r
-\r
-/* Private ADT */\r
-\r
-\r
-struct _SM_CLIENT_DIRECTORY\r
-{\r
- RTL_CRITICAL_SECTION Lock;\r
- ULONG Count;\r
- PSM_CLIENT_DATA Client;\r
- PSM_CLIENT_DATA CandidateClient;\r
-\r
-} SmpClientDirectory;\r
-\r
-\r
-/**********************************************************************\r
- * SmInitializeClientManagement/0\r
- */\r
-NTSTATUS\r
-SmInitializeClientManagement (VOID)\r
-{\r
- DPRINT("SM: %s called\n", __FUNCTION__);\r
- RtlInitializeCriticalSection(& SmpClientDirectory.Lock);\r
- SmpClientDirectory.Count = 0;\r
- SmpClientDirectory.Client = NULL;\r
- SmpClientDirectory.CandidateClient = NULL;\r
- return STATUS_SUCCESS;\r
-\r
-}\r
-/**********************************************************************\r
- * SmpSetClientInitialized/1\r
- */\r
-VOID FASTCALL\r
-SmpSetClientInitialized (PSM_CLIENT_DATA Client)\r
-{\r
- Client->Flags |= SM_CLIENT_FLAG_INITIALIZED;\r
-}\r
-/**********************************************************************\r
- * SmpLookupClient/2 PRIVATE\r
- *\r
- * DESCRIPTION\r
- * Lookup the subsystem server descriptor given its image ID.\r
- *\r
- * ARGUMENTS\r
- * SubsystemId: IMAGE_SUBSYSTEM_xxx\r
- * Parent: optional: caller provided storage for the\r
- * the pointer to the SM_CLIENT_DATA which\r
- * Next field contains the value returned by\r
- * the function (on success).\r
- *\r
- * RETURN VALUES\r
- * NULL on error; otherwise a pointer to the SM_CLIENT_DATA\r
- * looked up object.\r
- *\r
- * WARNING\r
- * SmpClientDirectory.Lock must be held by the caller.\r
- */\r
-static PSM_CLIENT_DATA FASTCALL\r
-SmpLookupClient (USHORT SubsystemId,\r
- PSM_CLIENT_DATA * Parent)\r
-{\r
- PSM_CLIENT_DATA Client = NULL;\r
-\r
- DPRINT("SM: %s(%d) called\n", __FUNCTION__, SubsystemId);\r
- \r
- if(NULL != Parent)\r
- {\r
- *Parent = NULL;\r
- }\r
- if (SmpClientDirectory.Count > 0)\r
- {\r
- Client = SmpClientDirectory.Client;\r
- while (NULL != Client)\r
- {\r
- if (SubsystemId == Client->SubsystemId)\r
- {\r
- break;\r
- }\r
- if(NULL != Parent)\r
- {\r
- *Parent = Client;\r
- }\r
- Client = Client->Next;\r
- }\r
- }\r
- return Client;\r
-}\r
-/**********************************************************************\r
- * SmBeginClientInitialization/1\r
- *\r
- * DESCRIPTION\r
- * Check if the candidate client matches the begin session\r
- * message from the subsystem process.\r
- *\r
- * ARGUMENTS\r
- * Request: message received by \SmApiPort\r
- * ClientData:\r
- * \r
- * RETURN VALUES\r
- * NTSTATUS\r
- */\r
-NTSTATUS STDCALL\r
-SmBeginClientInitialization (IN PSM_PORT_MESSAGE Request,\r
- OUT PSM_CLIENT_DATA * ClientData)\r
-{\r
- NTSTATUS Status = STATUS_SUCCESS;\r
- PSM_CONNECT_DATA ConnectData = SmpGetConnectData (Request);\r
- ULONG SbApiPortNameSize = SM_CONNECT_DATA_SIZE(*Request);\r
-\r
-\r
- DPRINT("SM: %s called\n", __FUNCTION__);\r
- \r
- RtlEnterCriticalSection (& SmpClientDirectory.Lock);\r
- /*\r
- * Is there a subsystem bootstrap in progress?\r
- */\r
- if (SmpClientDirectory.CandidateClient)\r
- {\r
- PROCESS_BASIC_INFORMATION pbi;\r
- \r
- RtlZeroMemory (& pbi, sizeof pbi);\r
- Status = NtQueryInformationProcess (Request->Header.ClientId.UniqueProcess,\r
- ProcessBasicInformation,\r
- & pbi,\r
- sizeof pbi,\r
- NULL);\r
- if (NT_SUCCESS(Status))\r
- {\r
- SmpClientDirectory.CandidateClient->ServerProcessId =\r
- (ULONG) pbi.UniqueProcessId;\r
- }\r
- }\r
- else\r
- {\r
- RtlFreeHeap (SmpHeap, 0, SmpClientDirectory.CandidateClient);\r
- DPRINT1("SM: %s: subsys booting with no descriptor!\n", __FUNCTION__);\r
- Status = STATUS_NOT_FOUND;\r
- RtlLeaveCriticalSection (& SmpClientDirectory.Lock);\r
- return Status; \r
- }\r
- /*\r
- * Check if a client for the ID already exist.\r
- */\r
- if (SmpLookupClient(ConnectData->SubSystemId, NULL))\r
- {\r
- DPRINT("SM: %s: attempt to register again subsystem %d.\n",\r
- __FUNCTION__,\r
- ConnectData->SubSystemId);\r
- return STATUS_UNSUCCESSFUL;\r
- }\r
- DPRINT("SM: %s: registering subsystem ID=%d \n",\r
- __FUNCTION__, ConnectData->SubSystemId);\r
-\r
- /*\r
- * Initialize the client data\r
- */\r
- SmpClientDirectory.CandidateClient->SubsystemId = ConnectData->SubSystemId;\r
- /* SM && DBG auto-initializes; other subsystems are required to call\r
- * SM_API_COMPLETE_SESSION via SMDLL. */\r
- if ((IMAGE_SUBSYSTEM_NATIVE == SmpClientDirectory.CandidateClient->SubsystemId) ||\r
- (IMAGE_SUBSYSTEM_UNKNOWN == SmpClientDirectory.CandidateClient->SubsystemId))\r
- {\r
- SmpSetClientInitialized (SmpClientDirectory.CandidateClient);\r
- }\r
- if (SbApiPortNameSize > 0)\r
- {\r
- RtlCopyMemory (SmpClientDirectory.CandidateClient->SbApiPortName,\r
- ConnectData->SbName,\r
- SbApiPortNameSize);\r
- }\r
- /*\r
- * Insert the new descriptor in the\r
- * client directory.\r
- */\r
- if (NULL == SmpClientDirectory.Client)\r
- {\r
- SmpClientDirectory.Client = SmpClientDirectory.CandidateClient;\r
- } else {\r
- PSM_CLIENT_DATA pCD = NULL;\r
-\r
- for (pCD=SmpClientDirectory.Client;\r
- (NULL != pCD->Next);\r
- pCD = pCD->Next);\r
- pCD->Next = SmpClientDirectory.CandidateClient;\r
- }\r
- SmpClientDirectory.CandidateClient->Next = NULL;\r
- /*\r
- * Increment the number of active subsystems.\r
- */\r
- ++ SmpClientDirectory.Count;\r
- /*\r
- * Notify to the caller the reference to the client data.\r
- */\r
- if (ClientData) \r
- {\r
- *ClientData = SmpClientDirectory.CandidateClient;\r
- }\r
- /*\r
- * Free the slot for the candidate subsystem.\r
- */\r
- SmpClientDirectory.CandidateClient = NULL;\r
-\r
- RtlLeaveCriticalSection (& SmpClientDirectory.Lock);\r
- \r
- return STATUS_SUCCESS;\r
-}\r
-/**********************************************************************\r
- * SmCompleteClientInitialization/1\r
- *\r
- * DESCRIPTION\r
- * Lookup the subsystem server descriptor given the process ID\r
- * of the subsystem server process.\r
- */\r
-NTSTATUS STDCALL\r
-SmCompleteClientInitialization (ULONG ProcessId)\r
-{\r
- NTSTATUS Status = STATUS_SUCCESS;\r
- PSM_CLIENT_DATA Client = NULL;\r
-\r
- DPRINT("SM: %s called\n", __FUNCTION__);\r
-\r
- RtlEnterCriticalSection (& SmpClientDirectory.Lock);\r
- if (SmpClientDirectory.Count > 0)\r
- {\r
- Client = SmpClientDirectory.Client;\r
- while (NULL != Client)\r
- {\r
- if (ProcessId == Client->ServerProcessId)\r
- {\r
- SmpSetClientInitialized (Client);\r
- break;\r
- }\r
- Client = Client->Next;\r
- }\r
- Status = STATUS_NOT_FOUND;\r
- }\r
- RtlLeaveCriticalSection (& SmpClientDirectory.Lock);\r
- return Status;\r
-}\r
-\r
-/**********************************************************************\r
- * SmpCreateClient/1\r
- *\r
- * DESCRIPTION\r
- * Create a "candidate" client. Client descriptor will enter the\r
- * client directory only at the end of the registration\r
- * procedure. Otherwise, we will kill the associated process.\r
- *\r
- * ARGUMENTS\r
- * ProcessHandle: handle of the subsystem server process.\r
- *\r
- * RETURN VALUE\r
- * NTSTATUS:\r
- */\r
-NTSTATUS STDCALL\r
-SmCreateClient (PRTL_PROCESS_INFO ProcessInfo, PWSTR ProgramName)\r
-{\r
- NTSTATUS Status = STATUS_SUCCESS;\r
-\r
- \r
- DPRINT("SM: %s(%lx) called\n", __FUNCTION__, ProcessInfo->ProcessHandle);\r
- RtlEnterCriticalSection (& SmpClientDirectory.Lock);\r
- /*\r
- * Check if the candidate client slot is empty.\r
- */\r
- if (NULL != SmpClientDirectory.CandidateClient)\r
- {\r
- DPRINT1("SM: %s: CandidateClient pending!\n", __FUNCTION__);\r
- RtlLeaveCriticalSection (& SmpClientDirectory.Lock);\r
- return STATUS_UNSUCCESSFUL;\r
- }\r
- /*\r
- * Allocate the storage for client data\r
- */\r
- SmpClientDirectory.CandidateClient =\r
- RtlAllocateHeap (SmpHeap,\r
- HEAP_ZERO_MEMORY,\r
- sizeof (SM_CLIENT_DATA));\r
- if (NULL == SmpClientDirectory.CandidateClient)\r
- {\r
- DPRINT("SM: %s(%lx): out of memory!\n",\r
- __FUNCTION__, ProcessInfo->ProcessHandle);\r
- Status = STATUS_NO_MEMORY;\r
- }\r
- else\r
- {\r
- /* Initialize the candidate client. */\r
- RtlInitializeCriticalSection(& SmpClientDirectory.CandidateClient->Lock);\r
- SmpClientDirectory.CandidateClient->ServerProcess =\r
- (HANDLE) ProcessInfo->ProcessHandle;\r
- SmpClientDirectory.CandidateClient->ServerProcessId = \r
- (ULONG) ProcessInfo->ClientId.UniqueProcess;\r
- }\r
- /*\r
- * Copy the program name\r
- */\r
- RtlCopyMemory (SmpClientDirectory.CandidateClient->ProgramName,\r
- ProgramName,\r
- SM_SB_NAME_MAX_LENGTH);\r
- RtlLeaveCriticalSection (& SmpClientDirectory.Lock);\r
- return Status;\r
-}\r
-\r
-/**********************************************************************\r
- * SmpDestroyClient/1\r
- *\r
- * 1. close any handle\r
- * 2. kill client process\r
- * 3. release resources\r
- */\r
-NTSTATUS STDCALL\r
-SmDestroyClient (ULONG SubsystemId)\r
-{\r
- NTSTATUS Status = STATUS_SUCCESS;\r
- PSM_CLIENT_DATA Parent = NULL;\r
- PSM_CLIENT_DATA Client = NULL;\r
-\r
- DPRINT("SM: %s called\n", __FUNCTION__);\r
-\r
- RtlEnterCriticalSection (& SmpClientDirectory.Lock);\r
- Client = SmpLookupClient (SubsystemId, & Parent);\r
- if(NULL == Client)\r
- {\r
- DPRINT1("SM: %s: del req for non existent subsystem (id=%d)\n",\r
- __FUNCTION__, SubsystemId);\r
- Status = STATUS_NOT_FOUND;\r
- }\r
- else\r
- {\r
- /* 1st in the list? */\r
- if(NULL == Parent)\r
- {\r
- SmpClientDirectory.Client = Client->Next;\r
- }\r
- else\r
- {\r
- if(NULL != Parent)\r
- {\r
- Parent->Next = Client->Next;\r
- } else {\r
- DPRINT1("SM: %s: n-th has no parent!\n", __FUNCTION__);\r
- Status = STATUS_UNSUCCESSFUL; /* FIXME */\r
- }\r
- }\r
- /* TODO: send shutdown or kill */\r
- NtTerminateProcess (Client->ServerProcess, 0); //FIXME\r
- RtlFreeHeap (SmpHeap, 0, Client);\r
- -- SmpClientDirectory.Count;\r
- }\r
- RtlLeaveCriticalSection (& SmpClientDirectory.Lock);\r
- return Status;\r
-}\r
-\r
-/* === Utilities for SmQryInfo === */\r
-\r
-/**********************************************************************\r
- * SmGetClientBasicInformation/1\r
- */\r
-NTSTATUS FASTCALL\r
-SmGetClientBasicInformation (PSM_BASIC_INFORMATION i)\r
-{\r
- INT Index = 0;\r
- PSM_CLIENT_DATA ClientData = NULL;\r
-\r
- DPRINT("SM: %s called\n", __FUNCTION__);\r
-\r
- RtlEnterCriticalSection (& SmpClientDirectory.Lock);\r
-\r
- i->SubSystemCount = SmpClientDirectory.Count;\r
- i->Unused = 0;\r
- \r
- if (SmpClientDirectory.Count > 0)\r
- {\r
- ClientData = SmpClientDirectory.Client;\r
- while ((NULL != ClientData) && (Index < SM_QRYINFO_MAX_SS_COUNT))\r
- {\r
- i->SubSystem[Index].Id = ClientData->SubsystemId;\r
- i->SubSystem[Index].Flags = ClientData->Flags;\r
- i->SubSystem[Index].ProcessId = ClientData->ServerProcessId;\r
- ClientData = ClientData->Next;\r
- }\r
- }\r
-\r
- RtlLeaveCriticalSection (& SmpClientDirectory.Lock);\r
- return STATUS_SUCCESS;\r
-}\r
-\r
-/**********************************************************************\r
- * SmGetSubSystemInformation/1\r
- */\r
-NTSTATUS FASTCALL\r
-SmGetSubSystemInformation (PSM_SUBSYSTEM_INFORMATION i)\r
-{\r
- NTSTATUS Status = STATUS_SUCCESS;\r
- PSM_CLIENT_DATA ClientData = NULL;\r
- \r
- DPRINT("SM: %s called\n", __FUNCTION__);\r
-\r
- RtlEnterCriticalSection (& SmpClientDirectory.Lock);\r
- ClientData = SmpLookupClient (i->SubSystemId, NULL);\r
- if (NULL == ClientData)\r
- {\r
- Status = STATUS_NOT_FOUND;\r
- }\r
- else\r
- {\r
- i->Flags = ClientData->Flags;\r
- i->ProcessId = ClientData->ServerProcessId;\r
- RtlCopyMemory (i->NameSpaceRootNode,\r
- ClientData->SbApiPortName,\r
- (SM_QRYINFO_MAX_ROOT_NODE * sizeof(i->NameSpaceRootNode[0])));\r
- }\r
- RtlLeaveCriticalSection (& SmpClientDirectory.Lock);\r
- return Status;\r
-}\r
-\r
-/* EOF */\r
+/* $Id$
+ *
+ * client.c - Session Manager client Management
+ *
+ * ReactOS Operating System
+ *
+ * --------------------------------------------------------------------
+ *
+ * This software 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 software 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 software; see the file COPYING.LIB. If not, write
+ * to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
+ * MA 02139, USA.
+ *
+ * --------------------------------------------------------------------
+ */
+#define NTOS_MODE_USER
+#include <ntos.h>
+#include "smss.h"
+#include <sm/helper.h>
+
+#define NDEBUG
+#include <debug.h>
+
+/* Private ADT */
+
+
+struct _SM_CLIENT_DIRECTORY
+{
+ RTL_CRITICAL_SECTION Lock;
+ ULONG Count;
+ PSM_CLIENT_DATA Client;
+ PSM_CLIENT_DATA CandidateClient;
+
+} SmpClientDirectory;
+
+
+/**********************************************************************
+ * SmInitializeClientManagement/0
+ */
+NTSTATUS
+SmInitializeClientManagement (VOID)
+{
+ DPRINT("SM: %s called\n", __FUNCTION__);
+ RtlInitializeCriticalSection(& SmpClientDirectory.Lock);
+ SmpClientDirectory.Count = 0;
+ SmpClientDirectory.Client = NULL;
+ SmpClientDirectory.CandidateClient = NULL;
+ return STATUS_SUCCESS;
+
+}
+/**********************************************************************
+ * SmpSetClientInitialized/1
+ */
+VOID FASTCALL
+SmpSetClientInitialized (PSM_CLIENT_DATA Client)
+{
+ Client->Flags |= SM_CLIENT_FLAG_INITIALIZED;
+}
+/**********************************************************************
+ * SmpLookupClient/2 PRIVATE
+ *
+ * DESCRIPTION
+ * Lookup the subsystem server descriptor given its image ID.
+ *
+ * ARGUMENTS
+ * SubsystemId: IMAGE_SUBSYSTEM_xxx
+ * Parent: optional: caller provided storage for the
+ * the pointer to the SM_CLIENT_DATA which
+ * Next field contains the value returned by
+ * the function (on success).
+ *
+ * RETURN VALUES
+ * NULL on error; otherwise a pointer to the SM_CLIENT_DATA
+ * looked up object.
+ *
+ * WARNING
+ * SmpClientDirectory.Lock must be held by the caller.
+ */
+static PSM_CLIENT_DATA FASTCALL
+SmpLookupClient (USHORT SubsystemId,
+ PSM_CLIENT_DATA * Parent)
+{
+ PSM_CLIENT_DATA Client = NULL;
+
+ DPRINT("SM: %s(%d) called\n", __FUNCTION__, SubsystemId);
+
+ if(NULL != Parent)
+ {
+ *Parent = NULL;
+ }
+ if (SmpClientDirectory.Count > 0)
+ {
+ Client = SmpClientDirectory.Client;
+ while (NULL != Client)
+ {
+ if (SubsystemId == Client->SubsystemId)
+ {
+ break;
+ }
+ if(NULL != Parent)
+ {
+ *Parent = Client;
+ }
+ Client = Client->Next;
+ }
+ }
+ return Client;
+}
+/**********************************************************************
+ * SmBeginClientInitialization/1
+ *
+ * DESCRIPTION
+ * Check if the candidate client matches the begin session
+ * message from the subsystem process.
+ *
+ * ARGUMENTS
+ * Request: message received by \SmApiPort
+ * ClientData:
+ *
+ * RETURN VALUES
+ * NTSTATUS
+ */
+NTSTATUS STDCALL
+SmBeginClientInitialization (IN PSM_PORT_MESSAGE Request,
+ OUT PSM_CLIENT_DATA * ClientData)
+{
+ NTSTATUS Status = STATUS_SUCCESS;
+ PSM_CONNECT_DATA ConnectData = SmpGetConnectData (Request);
+ ULONG SbApiPortNameSize = SM_CONNECT_DATA_SIZE(*Request);
+
+
+ DPRINT("SM: %s called\n", __FUNCTION__);
+
+ RtlEnterCriticalSection (& SmpClientDirectory.Lock);
+ /*
+ * Is there a subsystem bootstrap in progress?
+ */
+ if (SmpClientDirectory.CandidateClient)
+ {
+ PROCESS_BASIC_INFORMATION pbi;
+
+ RtlZeroMemory (& pbi, sizeof pbi);
+ Status = NtQueryInformationProcess (Request->Header.ClientId.UniqueProcess,
+ ProcessBasicInformation,
+ & pbi,
+ sizeof pbi,
+ NULL);
+ if (NT_SUCCESS(Status))
+ {
+ SmpClientDirectory.CandidateClient->ServerProcessId =
+ (ULONG) pbi.UniqueProcessId;
+ }
+ }
+ else
+ {
+ RtlFreeHeap (SmpHeap, 0, SmpClientDirectory.CandidateClient);
+ DPRINT1("SM: %s: subsys booting with no descriptor!\n", __FUNCTION__);
+ Status = STATUS_NOT_FOUND;
+ RtlLeaveCriticalSection (& SmpClientDirectory.Lock);
+ return Status;
+ }
+ /*
+ * Check if a client for the ID already exist.
+ */
+ if (SmpLookupClient(ConnectData->SubSystemId, NULL))
+ {
+ DPRINT("SM: %s: attempt to register again subsystem %d.\n",
+ __FUNCTION__,
+ ConnectData->SubSystemId);
+ return STATUS_UNSUCCESSFUL;
+ }
+ DPRINT("SM: %s: registering subsystem ID=%d \n",
+ __FUNCTION__, ConnectData->SubSystemId);
+
+ /*
+ * Initialize the client data
+ */
+ SmpClientDirectory.CandidateClient->SubsystemId = ConnectData->SubSystemId;
+ /* SM && DBG auto-initializes; other subsystems are required to call
+ * SM_API_COMPLETE_SESSION via SMDLL. */
+ if ((IMAGE_SUBSYSTEM_NATIVE == SmpClientDirectory.CandidateClient->SubsystemId) ||
+ (IMAGE_SUBSYSTEM_UNKNOWN == SmpClientDirectory.CandidateClient->SubsystemId))
+ {
+ SmpSetClientInitialized (SmpClientDirectory.CandidateClient);
+ }
+ if (SbApiPortNameSize > 0)
+ {
+ RtlCopyMemory (SmpClientDirectory.CandidateClient->SbApiPortName,
+ ConnectData->SbName,
+ SbApiPortNameSize);
+ }
+ /*
+ * Insert the new descriptor in the
+ * client directory.
+ */
+ if (NULL == SmpClientDirectory.Client)
+ {
+ SmpClientDirectory.Client = SmpClientDirectory.CandidateClient;
+ } else {
+ PSM_CLIENT_DATA pCD = NULL;
+
+ for (pCD=SmpClientDirectory.Client;
+ (NULL != pCD->Next);
+ pCD = pCD->Next);
+ pCD->Next = SmpClientDirectory.CandidateClient;
+ }
+ SmpClientDirectory.CandidateClient->Next = NULL;
+ /*
+ * Increment the number of active subsystems.
+ */
+ ++ SmpClientDirectory.Count;
+ /*
+ * Notify to the caller the reference to the client data.
+ */
+ if (ClientData)
+ {
+ *ClientData = SmpClientDirectory.CandidateClient;
+ }
+ /*
+ * Free the slot for the candidate subsystem.
+ */
+ SmpClientDirectory.CandidateClient = NULL;
+
+ RtlLeaveCriticalSection (& SmpClientDirectory.Lock);
+
+ return STATUS_SUCCESS;
+}
+/**********************************************************************
+ * SmCompleteClientInitialization/1
+ *
+ * DESCRIPTION
+ * Lookup the subsystem server descriptor given the process ID
+ * of the subsystem server process.
+ */
+NTSTATUS STDCALL
+SmCompleteClientInitialization (ULONG ProcessId)
+{
+ NTSTATUS Status = STATUS_SUCCESS;
+ PSM_CLIENT_DATA Client = NULL;
+
+ DPRINT("SM: %s called\n", __FUNCTION__);
+
+ RtlEnterCriticalSection (& SmpClientDirectory.Lock);
+ if (SmpClientDirectory.Count > 0)
+ {
+ Client = SmpClientDirectory.Client;
+ while (NULL != Client)
+ {
+ if (ProcessId == Client->ServerProcessId)
+ {
+ SmpSetClientInitialized (Client);
+ break;
+ }
+ Client = Client->Next;
+ }
+ Status = STATUS_NOT_FOUND;
+ }
+ RtlLeaveCriticalSection (& SmpClientDirectory.Lock);
+ return Status;
+}
+
+/**********************************************************************
+ * SmpCreateClient/1
+ *
+ * DESCRIPTION
+ * Create a "candidate" client. Client descriptor will enter the
+ * client directory only at the end of the registration
+ * procedure. Otherwise, we will kill the associated process.
+ *
+ * ARGUMENTS
+ * ProcessHandle: handle of the subsystem server process.
+ *
+ * RETURN VALUE
+ * NTSTATUS:
+ */
+NTSTATUS STDCALL
+SmCreateClient (PRTL_PROCESS_INFO ProcessInfo, PWSTR ProgramName)
+{
+ NTSTATUS Status = STATUS_SUCCESS;
+
+
+ DPRINT("SM: %s(%lx) called\n", __FUNCTION__, ProcessInfo->ProcessHandle);
+ RtlEnterCriticalSection (& SmpClientDirectory.Lock);
+ /*
+ * Check if the candidate client slot is empty.
+ */
+ if (NULL != SmpClientDirectory.CandidateClient)
+ {
+ DPRINT1("SM: %s: CandidateClient pending!\n", __FUNCTION__);
+ RtlLeaveCriticalSection (& SmpClientDirectory.Lock);
+ return STATUS_UNSUCCESSFUL;
+ }
+ /*
+ * Allocate the storage for client data
+ */
+ SmpClientDirectory.CandidateClient =
+ RtlAllocateHeap (SmpHeap,
+ HEAP_ZERO_MEMORY,
+ sizeof (SM_CLIENT_DATA));
+ if (NULL == SmpClientDirectory.CandidateClient)
+ {
+ DPRINT("SM: %s(%lx): out of memory!\n",
+ __FUNCTION__, ProcessInfo->ProcessHandle);
+ Status = STATUS_NO_MEMORY;
+ }
+ else
+ {
+ /* Initialize the candidate client. */
+ RtlInitializeCriticalSection(& SmpClientDirectory.CandidateClient->Lock);
+ SmpClientDirectory.CandidateClient->ServerProcess =
+ (HANDLE) ProcessInfo->ProcessHandle;
+ SmpClientDirectory.CandidateClient->ServerProcessId =
+ (ULONG) ProcessInfo->ClientId.UniqueProcess;
+ }
+ /*
+ * Copy the program name
+ */
+ RtlCopyMemory (SmpClientDirectory.CandidateClient->ProgramName,
+ ProgramName,
+ SM_SB_NAME_MAX_LENGTH);
+ RtlLeaveCriticalSection (& SmpClientDirectory.Lock);
+ return Status;
+}
+
+/**********************************************************************
+ * SmpDestroyClient/1
+ *
+ * 1. close any handle
+ * 2. kill client process
+ * 3. release resources
+ */
+NTSTATUS STDCALL
+SmDestroyClient (ULONG SubsystemId)
+{
+ NTSTATUS Status = STATUS_SUCCESS;
+ PSM_CLIENT_DATA Parent = NULL;
+ PSM_CLIENT_DATA Client = NULL;
+
+ DPRINT("SM: %s called\n", __FUNCTION__);
+
+ RtlEnterCriticalSection (& SmpClientDirectory.Lock);
+ Client = SmpLookupClient (SubsystemId, & Parent);
+ if(NULL == Client)
+ {
+ DPRINT1("SM: %s: del req for non existent subsystem (id=%d)\n",
+ __FUNCTION__, SubsystemId);
+ Status = STATUS_NOT_FOUND;
+ }
+ else
+ {
+ /* 1st in the list? */
+ if(NULL == Parent)
+ {
+ SmpClientDirectory.Client = Client->Next;
+ }
+ else
+ {
+ if(NULL != Parent)
+ {
+ Parent->Next = Client->Next;
+ } else {
+ DPRINT1("SM: %s: n-th has no parent!\n", __FUNCTION__);
+ Status = STATUS_UNSUCCESSFUL; /* FIXME */
+ }
+ }
+ /* TODO: send shutdown or kill */
+ NtTerminateProcess (Client->ServerProcess, 0); //FIXME
+ RtlFreeHeap (SmpHeap, 0, Client);
+ -- SmpClientDirectory.Count;
+ }
+ RtlLeaveCriticalSection (& SmpClientDirectory.Lock);
+ return Status;
+}
+
+/* === Utilities for SmQryInfo === */
+
+/**********************************************************************
+ * SmGetClientBasicInformation/1
+ */
+NTSTATUS FASTCALL
+SmGetClientBasicInformation (PSM_BASIC_INFORMATION i)
+{
+ INT Index = 0;
+ PSM_CLIENT_DATA ClientData = NULL;
+
+ DPRINT("SM: %s called\n", __FUNCTION__);
+
+ RtlEnterCriticalSection (& SmpClientDirectory.Lock);
+
+ i->SubSystemCount = SmpClientDirectory.Count;
+ i->Unused = 0;
+
+ if (SmpClientDirectory.Count > 0)
+ {
+ ClientData = SmpClientDirectory.Client;
+ while ((NULL != ClientData) && (Index < SM_QRYINFO_MAX_SS_COUNT))
+ {
+ i->SubSystem[Index].Id = ClientData->SubsystemId;
+ i->SubSystem[Index].Flags = ClientData->Flags;
+ i->SubSystem[Index].ProcessId = ClientData->ServerProcessId;
+ ClientData = ClientData->Next;
+ }
+ }
+
+ RtlLeaveCriticalSection (& SmpClientDirectory.Lock);
+ return STATUS_SUCCESS;
+}
+
+/**********************************************************************
+ * SmGetSubSystemInformation/1
+ */
+NTSTATUS FASTCALL
+SmGetSubSystemInformation (PSM_SUBSYSTEM_INFORMATION i)
+{
+ NTSTATUS Status = STATUS_SUCCESS;
+ PSM_CLIENT_DATA ClientData = NULL;
+
+ DPRINT("SM: %s called\n", __FUNCTION__);
+
+ RtlEnterCriticalSection (& SmpClientDirectory.Lock);
+ ClientData = SmpLookupClient (i->SubSystemId, NULL);
+ if (NULL == ClientData)
+ {
+ Status = STATUS_NOT_FOUND;
+ }
+ else
+ {
+ i->Flags = ClientData->Flags;
+ i->ProcessId = ClientData->ServerProcessId;
+ RtlCopyMemory (i->NameSpaceRootNode,
+ ClientData->SbApiPortName,
+ (SM_QRYINFO_MAX_ROOT_NODE * sizeof(i->NameSpaceRootNode[0])));
+ }
+ RtlLeaveCriticalSection (& SmpClientDirectory.Lock);
+ return Status;
+}
+
+/* EOF */
-/* $Id: smss.c 12852 2005-01-06 13:58:04Z mf $\r
- *\r
- * debug.c - Session Manager debug messages switch and router\r
- * \r
- * ReactOS Operating System\r
- * \r
- * --------------------------------------------------------------------\r
- *\r
- * This software is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License as\r
- * published by the Free Software Foundation; either version 2 of the\r
- * License, or (at your option) any later version.\r
- *\r
- * This software is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
- * General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this software; see the file COPYING.LIB. If not, write\r
- * to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge,\r
- * MA 02139, USA. \r
- *\r
- * --------------------------------------------------------------------\r
- */\r
-#define NTOS_MODE_USER\r
-#include <ntos.h>\r
-#include <rosrtl/string.h>\r
-#include "smss.h"\r
-\r
-#define NDEBUG\r
-#include <debug.h>\r
-\r
-\r
-/* GLOBALS ***********************************************************/\r
-\r
-HANDLE DbgSsApiPort = (HANDLE) 0;\r
-HANDLE DbgUiApiPort = (HANDLE) 0;\r
-\r
-/* FUNCTIONS *********************************************************/\r
-\r
-static VOID STDCALL\r
-DbgSsApiPortThread (PVOID dummy)\r
-{\r
- NTSTATUS Status = STATUS_SUCCESS;\r
- LPC_MAX_MESSAGE Request = {{0}};\r
- \r
- while (TRUE)\r
- {\r
- Status = NtListenPort (DbgSsApiPort, & Request.Header);\r
- if (!NT_SUCCESS(Status))\r
- {\r
- DPRINT1("SM: %s: NtListenPort() failed! (Status==x%08lx)\n", __FUNCTION__, Status);\r
- break;\r
- }\r
- /* TODO */\r
- }\r
- NtTerminateThread(NtCurrentThread(),Status);\r
-}\r
-\r
-static VOID STDCALL\r
-DbgUiApiPortThread (PVOID dummy)\r
-{\r
- NTSTATUS Status = STATUS_SUCCESS;\r
- LPC_MAX_MESSAGE Request = {{0}};\r
- \r
- while (TRUE)\r
- {\r
- Status = NtListenPort (DbgUiApiPort, & Request.Header);\r
- if (!NT_SUCCESS(Status))\r
- {\r
- DPRINT1("SM: %s: NtListenPort() failed! (Status==x%08lx)\n", __FUNCTION__, Status);\r
- break;\r
- }\r
- /* TODO */\r
- }\r
- NtTerminateThread(NtCurrentThread(),Status);\r
-}\r
-\r
-static NTSTATUS STDCALL\r
-SmpCreatePT (IN OUT PHANDLE hPort,\r
- IN LPWSTR wcPortName,\r
- IN ULONG ulMaxDataSize,\r
- IN ULONG ulMaxMessageSize,\r
- IN ULONG ulPoolCharge OPTIONAL,\r
- IN VOID (STDCALL * procServingThread)(PVOID) OPTIONAL,\r
- IN OUT PHANDLE phServingThread OPTIONAL)\r
-{\r
- NTSTATUS Status = STATUS_SUCCESS;\r
- UNICODE_STRING PortName = {0};\r
- OBJECT_ATTRIBUTES ObjectAttributes;\r
- HANDLE Thread = (HANDLE) 0;\r
- CLIENT_ID Cid = {0, 0};\r
-\r
- RtlInitUnicodeString (& PortName, wcPortName);\r
- InitializeObjectAttributes (& ObjectAttributes,\r
- & PortName,\r
- PORT_ALL_ACCESS,\r
- NULL,\r
- NULL);\r
- Status = NtCreatePort (hPort,\r
- & ObjectAttributes,\r
- ulMaxDataSize,\r
- ulMaxMessageSize,\r
- ulPoolCharge);\r
- if(STATUS_SUCCESS != Status)\r
- {\r
- return Status;\r
- }\r
- /* Create thread for DbgSsApiPort */\r
- RtlCreateUserThread(NtCurrentProcess(),\r
- NULL,\r
- FALSE,\r
- 0,\r
- NULL,\r
- NULL,\r
- (PTHREAD_START_ROUTINE) procServingThread,\r
- hPort,\r
- & Thread,\r
- & Cid);\r
- if((HANDLE) 0 == Thread)\r
- {\r
- NtClose(*hPort);\r
- Status = STATUS_UNSUCCESSFUL;\r
- }\r
- if(NULL != phServingThread)\r
- {\r
- *phServingThread = Thread;\r
- }\r
- return Status;\r
-}\r
-\r
-NTSTATUS\r
-SmInitializeDbgSs (VOID)\r
-{\r
- NTSTATUS Status = STATUS_SUCCESS;\r
- HANDLE hDbgSsApiPortThread = (HANDLE) 0;\r
-\r
- DPRINT("SM: %s called\n", __FUNCTION__);\r
-\r
- /* Create the \DbgSsApiPort object (LPC) */\r
- Status = SmpCreatePT(& DbgSsApiPort,\r
- SM_DBGSS_PORT_NAME,\r
- 0, /* MaxDataSize */\r
- 0, /* MaxMessageSize */\r
- 0, /* PoolCharge */\r
- DbgSsApiPortThread,\r
- & hDbgSsApiPortThread);\r
- if(!NT_SUCCESS(Status))\r
- {\r
- DPRINT("SM: %s: DBGSS port not created\n",__FUNCTION__);\r
- return Status;\r
- }\r
- /* Create the \DbgUiApiPort object (LPC) */\r
- Status = SmpCreatePT(& DbgUiApiPort,\r
- SM_DBGUI_PORT_NAME,\r
- 0, /* MaxDataSize */\r
- 0, /* MaxMessageSize */\r
- 0, /* PoolCharge */\r
- DbgUiApiPortThread,\r
- NULL);\r
- if(!NT_SUCCESS(Status))\r
- {\r
- DPRINT("SM: %s: DBGUI port not created\n",__FUNCTION__);\r
- NtClose (hDbgSsApiPortThread);\r
- NtClose (DbgSsApiPort);\r
- return Status;\r
- }\r
- return STATUS_SUCCESS;\r
-}\r
-\r
-/* EOF */\r
-\r
+/* $Id$
+ *
+ * debug.c - Session Manager debug messages switch and router
+ *
+ * ReactOS Operating System
+ *
+ * --------------------------------------------------------------------
+ *
+ * This software 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 software 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 software; see the file COPYING.LIB. If not, write
+ * to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
+ * MA 02139, USA.
+ *
+ * --------------------------------------------------------------------
+ */
+#define NTOS_MODE_USER
+#include <ntos.h>
+#include <rosrtl/string.h>
+#include "smss.h"
+
+#define NDEBUG
+#include <debug.h>
+
+
+/* GLOBALS ***********************************************************/
+
+HANDLE DbgSsApiPort = (HANDLE) 0;
+HANDLE DbgUiApiPort = (HANDLE) 0;
+
+/* FUNCTIONS *********************************************************/
+
+static VOID STDCALL
+DbgSsApiPortThread (PVOID dummy)
+{
+ NTSTATUS Status = STATUS_SUCCESS;
+ LPC_MAX_MESSAGE Request = {{0}};
+
+ while (TRUE)
+ {
+ Status = NtListenPort (DbgSsApiPort, & Request.Header);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("SM: %s: NtListenPort() failed! (Status==x%08lx)\n", __FUNCTION__, Status);
+ break;
+ }
+ /* TODO */
+ }
+ NtTerminateThread(NtCurrentThread(),Status);
+}
+
+static VOID STDCALL
+DbgUiApiPortThread (PVOID dummy)
+{
+ NTSTATUS Status = STATUS_SUCCESS;
+ LPC_MAX_MESSAGE Request = {{0}};
+
+ while (TRUE)
+ {
+ Status = NtListenPort (DbgUiApiPort, & Request.Header);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("SM: %s: NtListenPort() failed! (Status==x%08lx)\n", __FUNCTION__, Status);
+ break;
+ }
+ /* TODO */
+ }
+ NtTerminateThread(NtCurrentThread(),Status);
+}
+
+static NTSTATUS STDCALL
+SmpCreatePT (IN OUT PHANDLE hPort,
+ IN LPWSTR wcPortName,
+ IN ULONG ulMaxDataSize,
+ IN ULONG ulMaxMessageSize,
+ IN ULONG ulPoolCharge OPTIONAL,
+ IN VOID (STDCALL * procServingThread)(PVOID) OPTIONAL,
+ IN OUT PHANDLE phServingThread OPTIONAL)
+{
+ NTSTATUS Status = STATUS_SUCCESS;
+ UNICODE_STRING PortName = {0};
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ HANDLE Thread = (HANDLE) 0;
+ CLIENT_ID Cid = {0, 0};
+
+ RtlInitUnicodeString (& PortName, wcPortName);
+ InitializeObjectAttributes (& ObjectAttributes,
+ & PortName,
+ PORT_ALL_ACCESS,
+ NULL,
+ NULL);
+ Status = NtCreatePort (hPort,
+ & ObjectAttributes,
+ ulMaxDataSize,
+ ulMaxMessageSize,
+ ulPoolCharge);
+ if(STATUS_SUCCESS != Status)
+ {
+ return Status;
+ }
+ /* Create thread for DbgSsApiPort */
+ RtlCreateUserThread(NtCurrentProcess(),
+ NULL,
+ FALSE,
+ 0,
+ NULL,
+ NULL,
+ (PTHREAD_START_ROUTINE) procServingThread,
+ hPort,
+ & Thread,
+ & Cid);
+ if((HANDLE) 0 == Thread)
+ {
+ NtClose(*hPort);
+ Status = STATUS_UNSUCCESSFUL;
+ }
+ if(NULL != phServingThread)
+ {
+ *phServingThread = Thread;
+ }
+ return Status;
+}
+
+NTSTATUS
+SmInitializeDbgSs (VOID)
+{
+ NTSTATUS Status = STATUS_SUCCESS;
+ HANDLE hDbgSsApiPortThread = (HANDLE) 0;
+
+ DPRINT("SM: %s called\n", __FUNCTION__);
+
+ /* Create the \DbgSsApiPort object (LPC) */
+ Status = SmpCreatePT(& DbgSsApiPort,
+ SM_DBGSS_PORT_NAME,
+ 0, /* MaxDataSize */
+ 0, /* MaxMessageSize */
+ 0, /* PoolCharge */
+ DbgSsApiPortThread,
+ & hDbgSsApiPortThread);
+ if(!NT_SUCCESS(Status))
+ {
+ DPRINT("SM: %s: DBGSS port not created\n",__FUNCTION__);
+ return Status;
+ }
+ /* Create the \DbgUiApiPort object (LPC) */
+ Status = SmpCreatePT(& DbgUiApiPort,
+ SM_DBGUI_PORT_NAME,
+ 0, /* MaxDataSize */
+ 0, /* MaxMessageSize */
+ 0, /* PoolCharge */
+ DbgUiApiPortThread,
+ NULL);
+ if(!NT_SUCCESS(Status))
+ {
+ DPRINT("SM: %s: DBGUI port not created\n",__FUNCTION__);
+ NtClose (hDbgSsApiPortThread);
+ NtClose (DbgSsApiPort);
+ return Status;
+ }
+ return STATUS_SUCCESS;
+}
+
+/* EOF */
+
-/* $Id: init.c 13449 2005-02-06 21:55:07Z ea $\r
- *\r
- * initdosdev.c - Define symbolic links to kernel devices (MS-DOS names).\r
- * \r
- * ReactOS Operating System\r
- * \r
- * --------------------------------------------------------------------\r
- *\r
- * This software is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License as\r
- * published by the Free Software Foundation; either version 2 of the\r
- * License, or (at your option) any later version.\r
- *\r
- * This software is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
- * General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this software; see the file COPYING.LIB. If not, write\r
- * to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge,\r
- * MA 02139, USA. \r
- *\r
- * --------------------------------------------------------------------\r
- */\r
-\r
-#include "smss.h"\r
-\r
-#define NDEBUG\r
-#include <debug.h>\r
-\r
-static NTSTATUS STDCALL\r
-SmpDosDevicesQueryRoutine(PWSTR ValueName,\r
- ULONG ValueType,\r
- PVOID ValueData,\r
- ULONG ValueLength,\r
- PVOID Context,\r
- PVOID EntryContext)\r
-{\r
- OBJECT_ATTRIBUTES ObjectAttributes;\r
- UNICODE_STRING DeviceName;\r
- UNICODE_STRING LinkName;\r
- HANDLE LinkHandle;\r
- WCHAR LinkBuffer[80];\r
- NTSTATUS Status;\r
-\r
- DPRINT("ValueName '%S' Type %lu Length %lu\n", ValueName, ValueType, ValueLength);\r
- DPRINT("ValueData '%S'\n", (PWSTR)ValueData);\r
-\r
- if (ValueType != REG_SZ)\r
- {\r
- return(STATUS_SUCCESS);\r
- }\r
-\r
- swprintf(LinkBuffer,\r
- L"\\??\\%s",\r
- ValueName);\r
- RtlInitUnicodeString(&LinkName,\r
- LinkBuffer);\r
- RtlInitUnicodeString(&DeviceName,\r
- (PWSTR)ValueData);\r
-\r
- DPRINT("SM: Linking %wZ --> %wZ\n",\r
- &LinkName,\r
- &DeviceName);\r
-\r
- /* create symbolic link */\r
- InitializeObjectAttributes(&ObjectAttributes,\r
- &LinkName,\r
- OBJ_PERMANENT,\r
- NULL,\r
- NULL);\r
- Status = NtCreateSymbolicLinkObject(&LinkHandle,\r
- SYMBOLIC_LINK_ALL_ACCESS,\r
- &ObjectAttributes,\r
- &DeviceName);\r
- if (!NT_SUCCESS(Status))\r
- {\r
- DPRINT1("%s: NtCreateSymbolicLink( %wZ --> %wZ ) failed!\n",\r
- __FUNCTION__,\r
- &LinkName,\r
- &DeviceName);\r
- }\r
- NtClose(LinkHandle);\r
-\r
- return(Status);\r
-}\r
-\r
-\r
-NTSTATUS\r
-SmInitDosDevices(VOID)\r
-{\r
- RTL_QUERY_REGISTRY_TABLE QueryTable[2];\r
- NTSTATUS Status;\r
-\r
- RtlZeroMemory(&QueryTable,\r
- sizeof(QueryTable));\r
-\r
- QueryTable[0].QueryRoutine = SmpDosDevicesQueryRoutine;\r
-\r
- Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,\r
- L"\\Session Manager\\DOS Devices",\r
- QueryTable,\r
- NULL,\r
- NULL);\r
- return(Status);\r
-}\r
-\r
-/* EOF */\r
+/* $Id$
+ *
+ * initdosdev.c - Define symbolic links to kernel devices (MS-DOS names).
+ *
+ * ReactOS Operating System
+ *
+ * --------------------------------------------------------------------
+ *
+ * This software 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 software 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 software; see the file COPYING.LIB. If not, write
+ * to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
+ * MA 02139, USA.
+ *
+ * --------------------------------------------------------------------
+ */
+
+#include "smss.h"
+
+#define NDEBUG
+#include <debug.h>
+
+static NTSTATUS STDCALL
+SmpDosDevicesQueryRoutine(PWSTR ValueName,
+ ULONG ValueType,
+ PVOID ValueData,
+ ULONG ValueLength,
+ PVOID Context,
+ PVOID EntryContext)
+{
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ UNICODE_STRING DeviceName;
+ UNICODE_STRING LinkName;
+ HANDLE LinkHandle;
+ WCHAR LinkBuffer[80];
+ NTSTATUS Status;
+
+ DPRINT("ValueName '%S' Type %lu Length %lu\n", ValueName, ValueType, ValueLength);
+ DPRINT("ValueData '%S'\n", (PWSTR)ValueData);
+
+ if (ValueType != REG_SZ)
+ {
+ return(STATUS_SUCCESS);
+ }
+
+ swprintf(LinkBuffer,
+ L"\\??\\%s",
+ ValueName);
+ RtlInitUnicodeString(&LinkName,
+ LinkBuffer);
+ RtlInitUnicodeString(&DeviceName,
+ (PWSTR)ValueData);
+
+ DPRINT("SM: Linking %wZ --> %wZ\n",
+ &LinkName,
+ &DeviceName);
+
+ /* create symbolic link */
+ InitializeObjectAttributes(&ObjectAttributes,
+ &LinkName,
+ OBJ_PERMANENT,
+ NULL,
+ NULL);
+ Status = NtCreateSymbolicLinkObject(&LinkHandle,
+ SYMBOLIC_LINK_ALL_ACCESS,
+ &ObjectAttributes,
+ &DeviceName);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("%s: NtCreateSymbolicLink( %wZ --> %wZ ) failed!\n",
+ __FUNCTION__,
+ &LinkName,
+ &DeviceName);
+ }
+ NtClose(LinkHandle);
+
+ return(Status);
+}
+
+
+NTSTATUS
+SmInitDosDevices(VOID)
+{
+ RTL_QUERY_REGISTRY_TABLE QueryTable[2];
+ NTSTATUS Status;
+
+ RtlZeroMemory(&QueryTable,
+ sizeof(QueryTable));
+
+ QueryTable[0].QueryRoutine = SmpDosDevicesQueryRoutine;
+
+ Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,
+ L"\\Session Manager\\DOS Devices",
+ QueryTable,
+ NULL,
+ NULL);
+ return(Status);
+}
+
+/* EOF */
-/* $Id: init.c 13449 2005-02-06 21:55:07Z ea $\r
- *\r
- * initenv.c - Environment initialization\r
- * \r
- * ReactOS Operating System\r
- * \r
- * --------------------------------------------------------------------\r
- *\r
- * This software is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License as\r
- * published by the Free Software Foundation; either version 2 of the\r
- * License, or (at your option) any later version.\r
- *\r
- * This software is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
- * General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this software; see the file COPYING.LIB. If not, write\r
- * to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge,\r
- * MA 02139, USA. \r
- *\r
- * --------------------------------------------------------------------\r
- */\r
-\r
-#include "smss.h"\r
-\r
-#define NDEBUG\r
-#include <debug.h>\r
-\r
-/* GLOBALS */\r
-\r
-PWSTR SmSystemEnvironment = NULL;\r
-\r
-\r
-/* FUNCTIONS */\r
-\r
-NTSTATUS \r
-SmCreateEnvironment(VOID)\r
-{\r
- return RtlCreateEnvironment(FALSE, &SmSystemEnvironment);\r
-}\r
-\r
-\r
-static NTSTATUS\r
-SmpSetEnvironmentVariable(PVOID Context,\r
- PWSTR ValueName,\r
- PVOID ValueData)\r
-{\r
- UNICODE_STRING EnvVariable;\r
- UNICODE_STRING EnvValue;\r
-\r
- RtlInitUnicodeString(&EnvVariable,\r
- ValueName);\r
- RtlInitUnicodeString(&EnvValue,\r
- (PWSTR)ValueData);\r
- RtlSetEnvironmentVariable(Context,\r
- &EnvVariable,\r
- &EnvValue);\r
-\r
- return(STATUS_SUCCESS);\r
-}\r
-\r
-\r
-static NTSTATUS STDCALL\r
-SmpEnvironmentQueryRoutine(PWSTR ValueName,\r
- ULONG ValueType,\r
- PVOID ValueData,\r
- ULONG ValueLength,\r
- PVOID Context,\r
- PVOID EntryContext)\r
-{\r
- DPRINT("ValueName '%S' Type %lu Length %lu\n", ValueName, ValueType, ValueLength);\r
- DPRINT("ValueData '%S'\n", (PWSTR)ValueData);\r
-\r
- if (ValueType != REG_SZ)\r
- {\r
- return(STATUS_SUCCESS);\r
- }\r
- return SmpSetEnvironmentVariable(Context,ValueName,ValueData);\r
-}\r
-\r
-\r
-NTSTATUS\r
-SmSetEnvironmentVariables(VOID)\r
-{\r
- RTL_QUERY_REGISTRY_TABLE QueryTable[2];\r
- WCHAR ValueBuffer[MAX_PATH];\r
- NTSTATUS Status;\r
-\r
- /*\r
- * The following environment variables must be set prior to reading\r
- * other variables from the registry.\r
- *\r
- * Variables (example):\r
- * SystemRoot = "C:\reactos"\r
- * SystemDrive = "C:"\r
- */\r
-\r
- /* Copy system root into value buffer */\r
- wcscpy(ValueBuffer,\r
- SharedUserData->NtSystemRoot);\r
-\r
- /* Set SystemRoot = "C:\reactos" */\r
- SmpSetEnvironmentVariable(&SmSystemEnvironment,L"SystemRoot",ValueBuffer);\r
-\r
- /* Cut off trailing path */\r
- ValueBuffer[2] = 0;\r
-\r
- /* Set SystemDrive = "C:" */\r
- SmpSetEnvironmentVariable(&SmSystemEnvironment,L"SystemDrive",ValueBuffer);\r
-\r
- /* Read system environment from the registry. */\r
- RtlZeroMemory(&QueryTable,\r
- sizeof(QueryTable));\r
-\r
- QueryTable[0].QueryRoutine = SmpEnvironmentQueryRoutine;\r
-\r
- Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,\r
- L"\\Session Manager\\Environment",\r
- QueryTable,\r
- &SmSystemEnvironment,\r
- SmSystemEnvironment);\r
-\r
- return(Status);\r
-}\r
-\r
-/**********************************************************************\r
- * Set environment variables from registry\r
- */\r
-NTSTATUS\r
-SmUpdateEnvironment(VOID)\r
-{\r
- /* TODO */\r
- return STATUS_SUCCESS;\r
-}\r
-\r
-/* EOF */\r
+/* $Id$
+ *
+ * initenv.c - Environment initialization
+ *
+ * ReactOS Operating System
+ *
+ * --------------------------------------------------------------------
+ *
+ * This software 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 software 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 software; see the file COPYING.LIB. If not, write
+ * to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
+ * MA 02139, USA.
+ *
+ * --------------------------------------------------------------------
+ */
+
+#include "smss.h"
+
+#define NDEBUG
+#include <debug.h>
+
+/* GLOBALS */
+
+PWSTR SmSystemEnvironment = NULL;
+
+
+/* FUNCTIONS */
+
+NTSTATUS
+SmCreateEnvironment(VOID)
+{
+ return RtlCreateEnvironment(FALSE, &SmSystemEnvironment);
+}
+
+
+static NTSTATUS
+SmpSetEnvironmentVariable(PVOID Context,
+ PWSTR ValueName,
+ PVOID ValueData)
+{
+ UNICODE_STRING EnvVariable;
+ UNICODE_STRING EnvValue;
+
+ RtlInitUnicodeString(&EnvVariable,
+ ValueName);
+ RtlInitUnicodeString(&EnvValue,
+ (PWSTR)ValueData);
+ RtlSetEnvironmentVariable(Context,
+ &EnvVariable,
+ &EnvValue);
+
+ return(STATUS_SUCCESS);
+}
+
+
+static NTSTATUS STDCALL
+SmpEnvironmentQueryRoutine(PWSTR ValueName,
+ ULONG ValueType,
+ PVOID ValueData,
+ ULONG ValueLength,
+ PVOID Context,
+ PVOID EntryContext)
+{
+ DPRINT("ValueName '%S' Type %lu Length %lu\n", ValueName, ValueType, ValueLength);
+ DPRINT("ValueData '%S'\n", (PWSTR)ValueData);
+
+ if (ValueType != REG_SZ)
+ {
+ return(STATUS_SUCCESS);
+ }
+ return SmpSetEnvironmentVariable(Context,ValueName,ValueData);
+}
+
+
+NTSTATUS
+SmSetEnvironmentVariables(VOID)
+{
+ RTL_QUERY_REGISTRY_TABLE QueryTable[2];
+ WCHAR ValueBuffer[MAX_PATH];
+ NTSTATUS Status;
+
+ /*
+ * The following environment variables must be set prior to reading
+ * other variables from the registry.
+ *
+ * Variables (example):
+ * SystemRoot = "C:\reactos"
+ * SystemDrive = "C:"
+ */
+
+ /* Copy system root into value buffer */
+ wcscpy(ValueBuffer,
+ SharedUserData->NtSystemRoot);
+
+ /* Set SystemRoot = "C:\reactos" */
+ SmpSetEnvironmentVariable(&SmSystemEnvironment,L"SystemRoot",ValueBuffer);
+
+ /* Cut off trailing path */
+ ValueBuffer[2] = 0;
+
+ /* Set SystemDrive = "C:" */
+ SmpSetEnvironmentVariable(&SmSystemEnvironment,L"SystemDrive",ValueBuffer);
+
+ /* Read system environment from the registry. */
+ RtlZeroMemory(&QueryTable,
+ sizeof(QueryTable));
+
+ QueryTable[0].QueryRoutine = SmpEnvironmentQueryRoutine;
+
+ Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,
+ L"\\Session Manager\\Environment",
+ QueryTable,
+ &SmSystemEnvironment,
+ SmSystemEnvironment);
+
+ return(Status);
+}
+
+/**********************************************************************
+ * Set environment variables from registry
+ */
+NTSTATUS
+SmUpdateEnvironment(VOID)
+{
+ /* TODO */
+ return STATUS_SUCCESS;
+}
+
+/* EOF */
-/* $Id: init.c 13449 2005-02-06 21:55:07Z ea $\r
- *\r
- * initenv.c - Create the SM private heap\r
- * \r
- * ReactOS Operating System\r
- * \r
- * --------------------------------------------------------------------\r
- *\r
- * This software is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License as\r
- * published by the Free Software Foundation; either version 2 of the\r
- * License, or (at your option) any later version.\r
- *\r
- * This software is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
- * General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this software; see the file COPYING.LIB. If not, write\r
- * to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge,\r
- * MA 02139, USA. \r
- *\r
- * --------------------------------------------------------------------\r
- */\r
-\r
-#include "smss.h"\r
-\r
-#define NDEBUG\r
-#include <debug.h>\r
-\r
-HANDLE SmpHeap = NULL;\r
-\r
-NTSTATUS\r
-SmCreateHeap(VOID)\r
-{\r
- /* Create our own heap */\r
- SmpHeap = RtlCreateHeap(HEAP_GROWABLE,\r
- NULL,\r
- 65536,\r
- 65536,\r
- NULL,\r
- NULL);\r
- return (NULL == SmpHeap) ? STATUS_UNSUCCESSFUL : STATUS_SUCCESS;\r
-}\r
-\r
-/* EOF */\r
+/* $Id$
+ *
+ * initenv.c - Create the SM private heap
+ *
+ * ReactOS Operating System
+ *
+ * --------------------------------------------------------------------
+ *
+ * This software 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 software 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 software; see the file COPYING.LIB. If not, write
+ * to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
+ * MA 02139, USA.
+ *
+ * --------------------------------------------------------------------
+ */
+
+#include "smss.h"
+
+#define NDEBUG
+#include <debug.h>
+
+HANDLE SmpHeap = NULL;
+
+NTSTATUS
+SmCreateHeap(VOID)
+{
+ /* Create our own heap */
+ SmpHeap = RtlCreateHeap(HEAP_GROWABLE,
+ NULL,
+ 65536,
+ 65536,
+ NULL,
+ NULL);
+ return (NULL == SmpHeap) ? STATUS_UNSUCCESSFUL : STATUS_SUCCESS;
+}
+
+/* EOF */
-/* $Id: init.c 13449 2005-02-06 21:55:07Z ea $\r
- *\r
- * initmv.c - Process the file rename list\r
- * \r
- * ReactOS Operating System\r
- * \r
- * --------------------------------------------------------------------\r
- *\r
- * This software is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License as\r
- * published by the Free Software Foundation; either version 2 of the\r
- * License, or (at your option) any later version.\r
- *\r
- * This software is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
- * General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this software; see the file COPYING.LIB. If not, write\r
- * to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge,\r
- * MA 02139, USA. \r
- *\r
- * --------------------------------------------------------------------\r
- */\r
- \r
-\r
-#include "smss.h"\r
-\r
-#define NDEBUG\r
-#include <debug.h>\r
-\r
-NTSTATUS\r
-SmProcessFileRenameList(VOID)\r
-{\r
- DPRINT("SmProcessFileRenameList() called\n");\r
-\r
- /* FIXME: implement it! */\r
-/*\r
- * open HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\FileRenameOperations\r
- * for each item in its value\r
- * clone the old file in the new name,\r
- * delete the source.\r
- *\r
- */\r
-\r
- DPRINT("SmProcessFileRenameList() done\n");\r
-\r
- return(STATUS_SUCCESS);\r
-}\r
-\r
-/* EOF */\r
+/* $Id$
+ *
+ * initmv.c - Process the file rename list
+ *
+ * ReactOS Operating System
+ *
+ * --------------------------------------------------------------------
+ *
+ * This software 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 software 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 software; see the file COPYING.LIB. If not, write
+ * to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
+ * MA 02139, USA.
+ *
+ * --------------------------------------------------------------------
+ */
+
+
+#include "smss.h"
+
+#define NDEBUG
+#include <debug.h>
+
+NTSTATUS
+SmProcessFileRenameList(VOID)
+{
+ DPRINT("SmProcessFileRenameList() called\n");
+
+ /* FIXME: implement it! */
+/*
+ * open HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\FileRenameOperations
+ * for each item in its value
+ * clone the old file in the new name,
+ * delete the source.
+ *
+ */
+
+ DPRINT("SmProcessFileRenameList() done\n");
+
+ return(STATUS_SUCCESS);
+}
+
+/* EOF */
-/* $Id: init.c 13449 2005-02-06 21:55:07Z ea $\r
- *\r
- * initobdir.c - Session Manager object directories\r
- * \r
- * ReactOS Operating System\r
- * \r
- * --------------------------------------------------------------------\r
- *\r
- * This software is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License as\r
- * published by the Free Software Foundation; either version 2 of the\r
- * License, or (at your option) any later version.\r
- *\r
- * This software is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
- * General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this software; see the file COPYING.LIB. If not, write\r
- * to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge,\r
- * MA 02139, USA. \r
- *\r
- * --------------------------------------------------------------------\r
- */\r
-#include "smss.h"\r
-\r
-#define NDEBUG\r
-#include <debug.h>\r
-\r
-static NTSTATUS STDCALL\r
-SmpObjectDirectoryQueryRoutine(PWSTR ValueName,\r
- ULONG ValueType,\r
- PVOID ValueData,\r
- ULONG ValueLength,\r
- PVOID Context,\r
- PVOID EntryContext)\r
-{\r
- OBJECT_ATTRIBUTES ObjectAttributes;\r
- UNICODE_STRING UnicodeString;\r
- HANDLE WindowsDirectory;\r
- NTSTATUS Status = STATUS_SUCCESS;\r
-\r
-#ifndef NDEBUG\r
- DbgPrint("ValueName '%S' Type %lu Length %lu\n", ValueName, ValueType, ValueLength);\r
- DbgPrint("ValueData '%S'\n", (PWSTR)ValueData);\r
-#endif\r
- if (ValueType != REG_SZ)\r
- {\r
- return(STATUS_SUCCESS);\r
- }\r
-\r
- RtlInitUnicodeString(&UnicodeString,\r
- (PWSTR)ValueData);\r
-\r
- InitializeObjectAttributes(&ObjectAttributes,\r
- &UnicodeString,\r
- 0,\r
- NULL,\r
- NULL);\r
-\r
- Status = ZwCreateDirectoryObject(&WindowsDirectory,\r
- 0,\r
- &ObjectAttributes);\r
-\r
- return(Status);\r
-}\r
-\r
-\r
-NTSTATUS\r
-SmCreateObjectDirectories(VOID)\r
-{\r
- RTL_QUERY_REGISTRY_TABLE QueryTable[2];\r
- NTSTATUS Status;\r
-\r
- RtlZeroMemory(&QueryTable,\r
- sizeof(QueryTable));\r
-\r
- QueryTable[0].Name = L"ObjectDirectories";\r
- QueryTable[0].QueryRoutine = SmpObjectDirectoryQueryRoutine;\r
-\r
- Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,\r
- SM_REGISTRY_ROOT_NAME,\r
- QueryTable,\r
- NULL,\r
- NULL);\r
-\r
- return(Status);\r
-}\r
-\r
-/* EOF */\r
+/* $Id$
+ *
+ * initobdir.c - Session Manager object directories
+ *
+ * ReactOS Operating System
+ *
+ * --------------------------------------------------------------------
+ *
+ * This software 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 software 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 software; see the file COPYING.LIB. If not, write
+ * to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
+ * MA 02139, USA.
+ *
+ * --------------------------------------------------------------------
+ */
+#include "smss.h"
+
+#define NDEBUG
+#include <debug.h>
+
+static NTSTATUS STDCALL
+SmpObjectDirectoryQueryRoutine(PWSTR ValueName,
+ ULONG ValueType,
+ PVOID ValueData,
+ ULONG ValueLength,
+ PVOID Context,
+ PVOID EntryContext)
+{
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ UNICODE_STRING UnicodeString;
+ HANDLE WindowsDirectory;
+ NTSTATUS Status = STATUS_SUCCESS;
+
+#ifndef NDEBUG
+ DbgPrint("ValueName '%S' Type %lu Length %lu\n", ValueName, ValueType, ValueLength);
+ DbgPrint("ValueData '%S'\n", (PWSTR)ValueData);
+#endif
+ if (ValueType != REG_SZ)
+ {
+ return(STATUS_SUCCESS);
+ }
+
+ RtlInitUnicodeString(&UnicodeString,
+ (PWSTR)ValueData);
+
+ InitializeObjectAttributes(&ObjectAttributes,
+ &UnicodeString,
+ 0,
+ NULL,
+ NULL);
+
+ Status = ZwCreateDirectoryObject(&WindowsDirectory,
+ 0,
+ &ObjectAttributes);
+
+ return(Status);
+}
+
+
+NTSTATUS
+SmCreateObjectDirectories(VOID)
+{
+ RTL_QUERY_REGISTRY_TABLE QueryTable[2];
+ NTSTATUS Status;
+
+ RtlZeroMemory(&QueryTable,
+ sizeof(QueryTable));
+
+ QueryTable[0].Name = L"ObjectDirectories";
+ QueryTable[0].QueryRoutine = SmpObjectDirectoryQueryRoutine;
+
+ Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,
+ SM_REGISTRY_ROOT_NAME,
+ QueryTable,
+ NULL,
+ NULL);
+
+ return(Status);
+}
+
+/* EOF */
-/* $Id: init.c 13449 2005-02-06 21:55:07Z ea $\r
- *\r
- * initpage.c - \r
- * \r
- * ReactOS Operating System\r
- * \r
- * --------------------------------------------------------------------\r
- *\r
- * This software is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License as\r
- * published by the Free Software Foundation; either version 2 of the\r
- * License, or (at your option) any later version.\r
- *\r
- * This software is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
- * General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this software; see the file COPYING.LIB. If not, write\r
- * to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge,\r
- * MA 02139, USA. \r
- *\r
- * --------------------------------------------------------------------\r
- */\r
-#include "smss.h"\r
-#include <rosrtl/string.h>\r
-#include <wchar.h>\r
-\r
-#define NDEBUG\r
-#include <debug.h>\r
-\r
-static NTSTATUS STDCALL\r
-SmpPagingFilesQueryRoutine(PWSTR ValueName,\r
- ULONG ValueType,\r
- PVOID ValueData,\r
- ULONG ValueLength,\r
- PVOID Context,\r
- PVOID EntryContext)\r
-{\r
- UNICODE_STRING FileName;\r
- LARGE_INTEGER InitialSize;\r
- LARGE_INTEGER MaximumSize;\r
- NTSTATUS Status;\r
- LPWSTR p;\r
-\r
- DPRINT("ValueName '%S' Type %lu Length %lu\n", ValueName, ValueType, ValueLength);\r
- DPRINT("ValueData '%S'\n", (PWSTR)ValueData);\r
-\r
- if (ValueType != REG_SZ)\r
- {\r
- return(STATUS_SUCCESS);\r
- }\r
-\r
- /*\r
- * Format: "<path>[ <initial_size>[ <maximum_size>]]"\r
- */\r
- if ((p = wcschr(ValueData, ' ')) != NULL)\r
- {\r
- *p = L'\0';\r
- InitialSize.QuadPart = wcstoul(p + 1, &p, 0) * 256 * 4096;\r
- if (*p == ' ')\r
- {\r
- MaximumSize.QuadPart = wcstoul(p + 1, NULL, 0) * 256 * 4096;\r
- }\r
- else\r
- MaximumSize = InitialSize;\r
- }\r
- else\r
- {\r
- InitialSize.QuadPart = 50 * 4096;\r
- MaximumSize.QuadPart = 80 * 4096;\r
- }\r
-\r
- if (!RtlDosPathNameToNtPathName_U ((LPWSTR)ValueData,\r
- &FileName,\r
- NULL,\r
- NULL))\r
- {\r
- return (STATUS_SUCCESS);\r
- }\r
-\r
- DPRINT("SMSS: Created paging file %wZ with size %dKB\n",\r
- &FileName, InitialSize.QuadPart / 1024);\r
- Status = NtCreatePagingFile(&FileName,\r
- &InitialSize,\r
- &MaximumSize,\r
- 0);\r
-\r
- RtlFreeUnicodeString(&FileName);\r
-\r
- return(STATUS_SUCCESS);\r
-}\r
-\r
-\r
-NTSTATUS\r
-SmCreatePagingFiles(VOID)\r
-{\r
- RTL_QUERY_REGISTRY_TABLE QueryTable[2];\r
- NTSTATUS Status;\r
-\r
- DPRINT("SM: creating system paging files\n");\r
- /*\r
- * Disable paging file on MiniNT/Live CD.\r
- */\r
- if (RtlCheckRegistryKey(RTL_REGISTRY_CONTROL, L"MiniNT") == STATUS_SUCCESS)\r
- {\r
- return STATUS_SUCCESS;\r
- }\r
-\r
- RtlZeroMemory(&QueryTable,\r
- sizeof(QueryTable));\r
-\r
- QueryTable[0].Name = L"PagingFiles";\r
- QueryTable[0].QueryRoutine = SmpPagingFilesQueryRoutine;\r
-\r
- Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,\r
- L"\\Session Manager\\Memory Management",\r
- QueryTable,\r
- NULL,\r
- NULL);\r
-\r
- return(Status);\r
-}\r
-\r
-\r
-/* EOF */\r
+/* $Id$
+ *
+ * initpage.c -
+ *
+ * ReactOS Operating System
+ *
+ * --------------------------------------------------------------------
+ *
+ * This software 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 software 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 software; see the file COPYING.LIB. If not, write
+ * to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
+ * MA 02139, USA.
+ *
+ * --------------------------------------------------------------------
+ */
+#include "smss.h"
+#include <rosrtl/string.h>
+#include <wchar.h>
+
+#define NDEBUG
+#include <debug.h>
+
+static NTSTATUS STDCALL
+SmpPagingFilesQueryRoutine(PWSTR ValueName,
+ ULONG ValueType,
+ PVOID ValueData,
+ ULONG ValueLength,
+ PVOID Context,
+ PVOID EntryContext)
+{
+ UNICODE_STRING FileName;
+ LARGE_INTEGER InitialSize;
+ LARGE_INTEGER MaximumSize;
+ NTSTATUS Status;
+ LPWSTR p;
+
+ DPRINT("ValueName '%S' Type %lu Length %lu\n", ValueName, ValueType, ValueLength);
+ DPRINT("ValueData '%S'\n", (PWSTR)ValueData);
+
+ if (ValueType != REG_SZ)
+ {
+ return(STATUS_SUCCESS);
+ }
+
+ /*
+ * Format: "<path>[ <initial_size>[ <maximum_size>]]"
+ */
+ if ((p = wcschr(ValueData, ' ')) != NULL)
+ {
+ *p = L'\0';
+ InitialSize.QuadPart = wcstoul(p + 1, &p, 0) * 256 * 4096;
+ if (*p == ' ')
+ {
+ MaximumSize.QuadPart = wcstoul(p + 1, NULL, 0) * 256 * 4096;
+ }
+ else
+ MaximumSize = InitialSize;
+ }
+ else
+ {
+ InitialSize.QuadPart = 50 * 4096;
+ MaximumSize.QuadPart = 80 * 4096;
+ }
+
+ if (!RtlDosPathNameToNtPathName_U ((LPWSTR)ValueData,
+ &FileName,
+ NULL,
+ NULL))
+ {
+ return (STATUS_SUCCESS);
+ }
+
+ DPRINT("SMSS: Created paging file %wZ with size %dKB\n",
+ &FileName, InitialSize.QuadPart / 1024);
+ Status = NtCreatePagingFile(&FileName,
+ &InitialSize,
+ &MaximumSize,
+ 0);
+
+ RtlFreeUnicodeString(&FileName);
+
+ return(STATUS_SUCCESS);
+}
+
+
+NTSTATUS
+SmCreatePagingFiles(VOID)
+{
+ RTL_QUERY_REGISTRY_TABLE QueryTable[2];
+ NTSTATUS Status;
+
+ DPRINT("SM: creating system paging files\n");
+ /*
+ * Disable paging file on MiniNT/Live CD.
+ */
+ if (RtlCheckRegistryKey(RTL_REGISTRY_CONTROL, L"MiniNT") == STATUS_SUCCESS)
+ {
+ return STATUS_SUCCESS;
+ }
+
+ RtlZeroMemory(&QueryTable,
+ sizeof(QueryTable));
+
+ QueryTable[0].Name = L"PagingFiles";
+ QueryTable[0].QueryRoutine = SmpPagingFilesQueryRoutine;
+
+ Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,
+ L"\\Session Manager\\Memory Management",
+ QueryTable,
+ NULL,
+ NULL);
+
+ return(Status);
+}
+
+
+/* EOF */
-/* $Id: init.c 13449 2005-02-06 21:55:07Z ea $\r
- *\r
- * initenv.c - Hive loading\r
- * \r
- * ReactOS Operating System\r
- * \r
- * --------------------------------------------------------------------\r
- *\r
- * This software is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License as\r
- * published by the Free Software Foundation; either version 2 of the\r
- * License, or (at your option) any later version.\r
- *\r
- * This software is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
- * General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this software; see the file COPYING.LIB. If not, write\r
- * to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge,\r
- * MA 02139, USA. \r
- *\r
- * --------------------------------------------------------------------\r
- */\r
-\r
-#include "smss.h"\r
-\r
-#define NDEBUG\r
-#include <debug.h>\r
-\r
-NTSTATUS\r
-SmInitializeRegistry(VOID)\r
-{\r
- DPRINT("SM: %s: initializing registry\n", __FUNCTION__);\r
-\r
- /* Load remaining registry hives */\r
- return NtInitializeRegistry(FALSE);\r
-}\r
-\r
-/* EOF */\r
+/* $Id$
+ *
+ * initenv.c - Hive loading
+ *
+ * ReactOS Operating System
+ *
+ * --------------------------------------------------------------------
+ *
+ * This software 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 software 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 software; see the file COPYING.LIB. If not, write
+ * to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
+ * MA 02139, USA.
+ *
+ * --------------------------------------------------------------------
+ */
+
+#include "smss.h"
+
+#define NDEBUG
+#include <debug.h>
+
+NTSTATUS
+SmInitializeRegistry(VOID)
+{
+ DPRINT("SM: %s: initializing registry\n", __FUNCTION__);
+
+ /* Load remaining registry hives */
+ return NtInitializeRegistry(FALSE);
+}
+
+/* EOF */
-/* $Id: init.c 13449 2005-02-06 21:55:07Z ea $\r
- *\r
- * initrun.c - Run all programs in the boot execution list\r
- * \r
- * ReactOS Operating System\r
- * \r
- * --------------------------------------------------------------------\r
- *\r
- * This software is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License as\r
- * published by the Free Software Foundation; either version 2 of the\r
- * License, or (at your option) any later version.\r
- *\r
- * This software is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
- * General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this software; see the file COPYING.LIB. If not, write\r
- * to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge,\r
- * MA 02139, USA. \r
- *\r
- * --------------------------------------------------------------------\r
- */\r
-\r
-#include "smss.h"\r
-\r
-#define NDEBUG\r
-#include <debug.h>\r
-\r
-//HANDLE Children[2] = {0, 0}; /* csrss, winlogon */\r
-\r
-\r
-/**********************************************************************\r
- * SmpRunBootAppsQueryRoutine/6\r
- */\r
-static NTSTATUS STDCALL\r
-SmpRunBootAppsQueryRoutine(PWSTR ValueName,\r
- ULONG ValueType,\r
- PVOID ValueData,\r
- ULONG ValueLength,\r
- PVOID Context,\r
- PVOID EntryContext)\r
-{\r
- WCHAR Description [MAX_PATH];\r
- WCHAR ImageName [MAX_PATH];\r
- WCHAR ImagePath [MAX_PATH];\r
- WCHAR CommandLine [MAX_PATH];\r
- PWSTR p1, p2;\r
- ULONG len;\r
- NTSTATUS Status;\r
-\r
- DPRINT("ValueName '%S' Type %lu Length %lu\n", ValueName, ValueType, ValueLength);\r
- DPRINT("ValueData '%S'\n", (PWSTR)ValueData);\r
-\r
- if (ValueType != REG_SZ)\r
- {\r
- return(STATUS_SUCCESS);\r
- }\r
-\r
- /* Extract the description */\r
- p1 = wcschr((PWSTR)ValueData, L' ');\r
- len = p1 - (PWSTR)ValueData;\r
- memcpy(Description,ValueData, len * sizeof(WCHAR));\r
- Description[len] = 0;\r
-\r
- /* Extract the image name */\r
- p1++;\r
- p2 = wcschr(p1, L' ');\r
- if (p2 != NULL)\r
- len = p2 - p1;\r
- else\r
- len = wcslen(p1);\r
- memcpy(ImageName, p1, len * sizeof(WCHAR));\r
- ImageName[len] = 0;\r
-\r
- /* Extract the command line */\r
- if (p2 == NULL)\r
- {\r
- CommandLine[0] = 0;\r
- }\r
- else\r
- {\r
- p2++;\r
- wcscpy(CommandLine, p2);\r
- }\r
-\r
- DPRINT("Running %S...\n", Description);\r
- DPRINT("ImageName: '%S'\n", ImageName);\r
- DPRINT("CommandLine: '%S'\n", CommandLine);\r
-\r
- /* initialize executable path */\r
- wcscpy(ImagePath, L"\\SystemRoot\\system32\\");\r
- wcscat(ImagePath, ImageName);\r
- wcscat(ImagePath, L".exe");\r
-\r
- /* Create NT process */\r
- Status = SmCreateUserProcess (ImagePath,\r
- CommandLine,\r
- TRUE, /* wait */\r
- NULL, NULL);\r
- if (!NT_SUCCESS(Status))\r
- {\r
- DPRINT1("SM: %s: running '$S' failed (Status=0x%08lx)\n",\r
- __FUNCTION__, Status);\r
- }\r
- return(STATUS_SUCCESS);\r
-}\r
-\r
-\r
-/**********************************************************************\r
- * SmRunBootApplications/0\r
- * \r
- * DESCRIPTION\r
- *\r
- * Run native applications listed in the registry.\r
- *\r
- * Key:\r
- * \Registry\Machine\SYSTEM\CurrentControlSet\Control\Session Manager\r
- *\r
- * Value (format: "<description> <executable> <command line>":\r
- * BootExecute = "autocheck autochk *"\r
- */\r
-NTSTATUS\r
-SmRunBootApplications(VOID)\r
-{\r
- RTL_QUERY_REGISTRY_TABLE QueryTable[2];\r
- NTSTATUS Status;\r
-\r
- RtlZeroMemory(&QueryTable,\r
- sizeof(QueryTable));\r
-\r
- QueryTable[0].Name = L"BootExecute";\r
- QueryTable[0].QueryRoutine = SmpRunBootAppsQueryRoutine;\r
-\r
- Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,\r
- L"\\Session Manager",\r
- QueryTable,\r
- NULL,\r
- NULL);\r
- if (!NT_SUCCESS(Status))\r
- {\r
- DPRINT1("%s: RtlQueryRegistryValues() failed! (Status %lx)\n", \r
- __FUNCTION__,\r
- Status);\r
- }\r
-\r
- return(Status);\r
-}\r
-\r
-\r
-/* EOF */\r
+/* $Id$
+ *
+ * initrun.c - Run all programs in the boot execution list
+ *
+ * ReactOS Operating System
+ *
+ * --------------------------------------------------------------------
+ *
+ * This software 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 software 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 software; see the file COPYING.LIB. If not, write
+ * to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
+ * MA 02139, USA.
+ *
+ * --------------------------------------------------------------------
+ */
+
+#include "smss.h"
+
+#define NDEBUG
+#include <debug.h>
+
+//HANDLE Children[2] = {0, 0}; /* csrss, winlogon */
+
+
+/**********************************************************************
+ * SmpRunBootAppsQueryRoutine/6
+ */
+static NTSTATUS STDCALL
+SmpRunBootAppsQueryRoutine(PWSTR ValueName,
+ ULONG ValueType,
+ PVOID ValueData,
+ ULONG ValueLength,
+ PVOID Context,
+ PVOID EntryContext)
+{
+ WCHAR Description [MAX_PATH];
+ WCHAR ImageName [MAX_PATH];
+ WCHAR ImagePath [MAX_PATH];
+ WCHAR CommandLine [MAX_PATH];
+ PWSTR p1, p2;
+ ULONG len;
+ NTSTATUS Status;
+
+ DPRINT("ValueName '%S' Type %lu Length %lu\n", ValueName, ValueType, ValueLength);
+ DPRINT("ValueData '%S'\n", (PWSTR)ValueData);
+
+ if (ValueType != REG_SZ)
+ {
+ return(STATUS_SUCCESS);
+ }
+
+ /* Extract the description */
+ p1 = wcschr((PWSTR)ValueData, L' ');
+ len = p1 - (PWSTR)ValueData;
+ memcpy(Description,ValueData, len * sizeof(WCHAR));
+ Description[len] = 0;
+
+ /* Extract the image name */
+ p1++;
+ p2 = wcschr(p1, L' ');
+ if (p2 != NULL)
+ len = p2 - p1;
+ else
+ len = wcslen(p1);
+ memcpy(ImageName, p1, len * sizeof(WCHAR));
+ ImageName[len] = 0;
+
+ /* Extract the command line */
+ if (p2 == NULL)
+ {
+ CommandLine[0] = 0;
+ }
+ else
+ {
+ p2++;
+ wcscpy(CommandLine, p2);
+ }
+
+ DPRINT("Running %S...\n", Description);
+ DPRINT("ImageName: '%S'\n", ImageName);
+ DPRINT("CommandLine: '%S'\n", CommandLine);
+
+ /* initialize executable path */
+ wcscpy(ImagePath, L"\\SystemRoot\\system32\\");
+ wcscat(ImagePath, ImageName);
+ wcscat(ImagePath, L".exe");
+
+ /* Create NT process */
+ Status = SmCreateUserProcess (ImagePath,
+ CommandLine,
+ TRUE, /* wait */
+ NULL, NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("SM: %s: running '$S' failed (Status=0x%08lx)\n",
+ __FUNCTION__, Status);
+ }
+ return(STATUS_SUCCESS);
+}
+
+
+/**********************************************************************
+ * SmRunBootApplications/0
+ *
+ * DESCRIPTION
+ *
+ * Run native applications listed in the registry.
+ *
+ * Key:
+ * \Registry\Machine\SYSTEM\CurrentControlSet\Control\Session Manager
+ *
+ * Value (format: "<description> <executable> <command line>":
+ * BootExecute = "autocheck autochk *"
+ */
+NTSTATUS
+SmRunBootApplications(VOID)
+{
+ RTL_QUERY_REGISTRY_TABLE QueryTable[2];
+ NTSTATUS Status;
+
+ RtlZeroMemory(&QueryTable,
+ sizeof(QueryTable));
+
+ QueryTable[0].Name = L"BootExecute";
+ QueryTable[0].QueryRoutine = SmpRunBootAppsQueryRoutine;
+
+ Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,
+ L"\\Session Manager",
+ QueryTable,
+ NULL,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("%s: RtlQueryRegistryValues() failed! (Status %lx)\n",
+ __FUNCTION__,
+ Status);
+ }
+
+ return(Status);
+}
+
+
+/* EOF */
-/* $Id: init.c 13449 2005-02-06 21:55:07Z ea $\r
- *\r
- * initss.c - Load the subsystems\r
- * \r
- * ReactOS Operating System\r
- * \r
- * --------------------------------------------------------------------\r
- *\r
- * This software is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License as\r
- * published by the Free Software Foundation; either version 2 of the\r
- * License, or (at your option) any later version.\r
- *\r
- * This software is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
- * General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this software; see the file COPYING.LIB. If not, write\r
- * to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge,\r
- * MA 02139, USA. \r
- *\r
- * --------------------------------------------------------------------\r
- */\r
-\r
-\r
-#include "smss.h"\r
-\r
-#include <rosrtl/string.h>\r
-\r
-#define NDEBUG\r
-#include <debug.h>\r
-\r
-/* SM handle for its own \SmApiPort */\r
-HANDLE hSmApiPort = (HANDLE) 0;\r
-\r
-\r
-/* TODO:\r
- *\r
- * a) look if a special option is set for smss.exe in\r
- * HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\r
- */\r
-\r
-/**********************************************************************\r
- * SmpRegisterSmss/0\r
- *\r
- * DESCRIPTION\r
- * Make smss register with itself for IMAGE_SUBSYSTEM_NATIVE\r
- * (programmatically). This also opens hSmApiPort to be used\r
- * in loading required subsystems.\r
- */\r
-\r
-static NTSTATUS\r
-SmpRegisterSmss(VOID)\r
-{\r
- NTSTATUS Status = STATUS_SUCCESS;\r
- RTL_PROCESS_INFO ProcessInfo;\r
-\r
- \r
- DPRINT("SM: %s called\n",__FUNCTION__);\r
- \r
- RtlZeroMemory (& ProcessInfo, sizeof ProcessInfo);\r
- ProcessInfo.Size = sizeof ProcessInfo;\r
- ProcessInfo.ProcessHandle = (HANDLE) SmSsProcessId;\r
- ProcessInfo.ClientId.UniqueProcess = (HANDLE) SmSsProcessId;\r
- DPRINT("SM: %s: ProcessInfo.ProcessHandle=%lx\n",\r
- __FUNCTION__,ProcessInfo.ProcessHandle);\r
- Status = SmCreateClient (& ProcessInfo, L"Session Manager");\r
- if (NT_SUCCESS(Status))\r
- {\r
- UNICODE_STRING SbApiPortName = {0,0,NULL};\r
- \r
- RtlInitUnicodeString (& SbApiPortName, L""); \r
- Status = SmConnectApiPort(& SbApiPortName,\r
- (HANDLE) -1, /* SM has no SB port */\r
- IMAGE_SUBSYSTEM_NATIVE,\r
- & hSmApiPort);\r
- if(!NT_SUCCESS(Status))\r
- {\r
- DPRINT("SM: %s: SMLIB!SmConnectApiPort failed (Status=0x%08lx)\n",\r
- __FUNCTION__,Status);\r
- return Status;\r
- }\r
- DPRINT("SM self registered\n");\r
- }\r
- else\r
- {\r
- DPRINT1("SM: %s: SmCreateClient failed (Status=0x%08lx)\n",\r
- __FUNCTION__, Status);\r
- }\r
- /*\r
- * Note that you don't need to call complete session\r
- * because connection handling code autocompletes\r
- * the client structure for IMAGE_SUBSYSTEM_NATIVE.\r
- */\r
- return Status;\r
-}\r
-\r
-\r
-/**********************************************************************\r
- * SmpLoadKernelModeSubsystem/0\r
- */\r
-static NTSTATUS\r
-SmpLoadKernelModeSubsystem (VOID)\r
-{\r
- NTSTATUS Status = STATUS_SUCCESS;\r
- WCHAR Data [MAX_PATH + 1];\r
- ULONG DataLength = sizeof Data;\r
- ULONG DataType = 0;\r
-\r
-\r
- DPRINT("SM: %s called\n", __FUNCTION__);\r
-\r
- Status = SmLookupSubsystem (L"Kmode",\r
- Data,\r
- & DataLength,\r
- & DataType,\r
- TRUE);\r
- if((STATUS_SUCCESS == Status) && (DataLength > sizeof Data[0]))\r
- {\r
- WCHAR ImagePath [MAX_PATH + 1] = {0};\r
- SYSTEM_LOAD_AND_CALL_IMAGE ImageInfo;\r
-\r
- wcscpy (ImagePath, L"\\??\\");\r
- wcscat (ImagePath, Data);\r
- RtlZeroMemory (& ImageInfo, sizeof ImageInfo);\r
- RtlInitUnicodeString (& ImageInfo.ModuleName, ImagePath);\r
- Status = NtSetSystemInformation(SystemLoadAndCallImage,\r
- & ImageInfo,\r
- sizeof ImageInfo);\r
- if(!NT_SUCCESS(Status))\r
- {\r
- DPRINT("SM: %s: loading Kmode failed (Status=0x%08lx)\n",\r
- __FUNCTION__, Status);\r
- }\r
- }\r
- return Status;\r
-}\r
-\r
-/**********************************************************************\r
- * SmpLoadRequiredSubsystems/0\r
- */\r
-static NTSTATUS\r
-SmpLoadRequiredSubsystems (VOID)\r
-{\r
- NTSTATUS Status = STATUS_SUCCESS;\r
- WCHAR Data [MAX_PATH + 1];\r
- ULONG DataLength = sizeof Data;\r
- ULONG DataType = 0;\r
-\r
- \r
- DPRINT("SM: %s called\n", __FUNCTION__);\r
-\r
- RtlZeroMemory (Data, DataLength);\r
- Status = SmLookupSubsystem (L"Required",\r
- Data,\r
- & DataLength,\r
- & DataType,\r
- FALSE);\r
- if((STATUS_SUCCESS == Status) && (DataLength > sizeof Data[0]))\r
- {\r
- PWCHAR Name = NULL;\r
- ULONG Offset = 0;\r
- \r
- for (Name = Data; (Offset < DataLength); )\r
- {\r
- if(L'\0' != *Name)\r
- {\r
- UNICODE_STRING Program;\r
-\r
- /* Run the current program */\r
- RtlInitUnicodeString (& Program, Name);\r
- Status = SmExecuteProgram (hSmApiPort, & Program);\r
- if(!NT_SUCCESS(Status))\r
- {\r
- DPRINT1("SM: %s failed to run '%S' program (Status=0x%08lx)\n",\r
- __FUNCTION__, Name, Status);\r
- }\r
- /* Look for the next program */\r
- while ((L'\0' != *Name) && (Offset < DataLength))\r
- {\r
- ++ Name;\r
- ++ Offset;\r
- }\r
- }\r
- ++ Name;\r
- ++ Offset;\r
- }\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-/**********************************************************************\r
- * SmLoadSubsystems/0\r
- */\r
-NTSTATUS\r
-SmLoadSubsystems(VOID)\r
-{\r
- NTSTATUS Status = STATUS_SUCCESS;\r
-\r
- \r
- DPRINT("SM: loading subsystems\n");\r
-\r
- /* SM self registers */\r
- Status = SmpRegisterSmss();\r
- if(!NT_SUCCESS(Status)) return Status;\r
- /* Load Kmode subsystem (aka win32k.sys) */\r
- Status = SmpLoadKernelModeSubsystem();\r
- if(!NT_SUCCESS(Status)) return Status;\r
- /* Load Required subsystems (Debug Windows) */\r
- Status = SmpLoadRequiredSubsystems();\r
- if(!NT_SUCCESS(Status)) return Status;\r
- /* done */\r
- return Status;\r
-}\r
-\r
-/* EOF */\r
+/* $Id$
+ *
+ * initss.c - Load the subsystems
+ *
+ * ReactOS Operating System
+ *
+ * --------------------------------------------------------------------
+ *
+ * This software 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 software 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 software; see the file COPYING.LIB. If not, write
+ * to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
+ * MA 02139, USA.
+ *
+ * --------------------------------------------------------------------
+ */
+
+
+#include "smss.h"
+
+#include <rosrtl/string.h>
+
+#define NDEBUG
+#include <debug.h>
+
+/* SM handle for its own \SmApiPort */
+HANDLE hSmApiPort = (HANDLE) 0;
+
+
+/* TODO:
+ *
+ * a) look if a special option is set for smss.exe in
+ * HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options
+ */
+
+/**********************************************************************
+ * SmpRegisterSmss/0
+ *
+ * DESCRIPTION
+ * Make smss register with itself for IMAGE_SUBSYSTEM_NATIVE
+ * (programmatically). This also opens hSmApiPort to be used
+ * in loading required subsystems.
+ */
+
+static NTSTATUS
+SmpRegisterSmss(VOID)
+{
+ NTSTATUS Status = STATUS_SUCCESS;
+ RTL_PROCESS_INFO ProcessInfo;
+
+
+ DPRINT("SM: %s called\n",__FUNCTION__);
+
+ RtlZeroMemory (& ProcessInfo, sizeof ProcessInfo);
+ ProcessInfo.Size = sizeof ProcessInfo;
+ ProcessInfo.ProcessHandle = (HANDLE) SmSsProcessId;
+ ProcessInfo.ClientId.UniqueProcess = (HANDLE) SmSsProcessId;
+ DPRINT("SM: %s: ProcessInfo.ProcessHandle=%lx\n",
+ __FUNCTION__,ProcessInfo.ProcessHandle);
+ Status = SmCreateClient (& ProcessInfo, L"Session Manager");
+ if (NT_SUCCESS(Status))
+ {
+ UNICODE_STRING SbApiPortName = {0,0,NULL};
+
+ RtlInitUnicodeString (& SbApiPortName, L"");
+ Status = SmConnectApiPort(& SbApiPortName,
+ (HANDLE) -1, /* SM has no SB port */
+ IMAGE_SUBSYSTEM_NATIVE,
+ & hSmApiPort);
+ if(!NT_SUCCESS(Status))
+ {
+ DPRINT("SM: %s: SMLIB!SmConnectApiPort failed (Status=0x%08lx)\n",
+ __FUNCTION__,Status);
+ return Status;
+ }
+ DPRINT("SM self registered\n");
+ }
+ else
+ {
+ DPRINT1("SM: %s: SmCreateClient failed (Status=0x%08lx)\n",
+ __FUNCTION__, Status);
+ }
+ /*
+ * Note that you don't need to call complete session
+ * because connection handling code autocompletes
+ * the client structure for IMAGE_SUBSYSTEM_NATIVE.
+ */
+ return Status;
+}
+
+
+/**********************************************************************
+ * SmpLoadKernelModeSubsystem/0
+ */
+static NTSTATUS
+SmpLoadKernelModeSubsystem (VOID)
+{
+ NTSTATUS Status = STATUS_SUCCESS;
+ WCHAR Data [MAX_PATH + 1];
+ ULONG DataLength = sizeof Data;
+ ULONG DataType = 0;
+
+
+ DPRINT("SM: %s called\n", __FUNCTION__);
+
+ Status = SmLookupSubsystem (L"Kmode",
+ Data,
+ & DataLength,
+ & DataType,
+ TRUE);
+ if((STATUS_SUCCESS == Status) && (DataLength > sizeof Data[0]))
+ {
+ WCHAR ImagePath [MAX_PATH + 1] = {0};
+ SYSTEM_LOAD_AND_CALL_IMAGE ImageInfo;
+
+ wcscpy (ImagePath, L"\\??\\");
+ wcscat (ImagePath, Data);
+ RtlZeroMemory (& ImageInfo, sizeof ImageInfo);
+ RtlInitUnicodeString (& ImageInfo.ModuleName, ImagePath);
+ Status = NtSetSystemInformation(SystemLoadAndCallImage,
+ & ImageInfo,
+ sizeof ImageInfo);
+ if(!NT_SUCCESS(Status))
+ {
+ DPRINT("SM: %s: loading Kmode failed (Status=0x%08lx)\n",
+ __FUNCTION__, Status);
+ }
+ }
+ return Status;
+}
+
+/**********************************************************************
+ * SmpLoadRequiredSubsystems/0
+ */
+static NTSTATUS
+SmpLoadRequiredSubsystems (VOID)
+{
+ NTSTATUS Status = STATUS_SUCCESS;
+ WCHAR Data [MAX_PATH + 1];
+ ULONG DataLength = sizeof Data;
+ ULONG DataType = 0;
+
+
+ DPRINT("SM: %s called\n", __FUNCTION__);
+
+ RtlZeroMemory (Data, DataLength);
+ Status = SmLookupSubsystem (L"Required",
+ Data,
+ & DataLength,
+ & DataType,
+ FALSE);
+ if((STATUS_SUCCESS == Status) && (DataLength > sizeof Data[0]))
+ {
+ PWCHAR Name = NULL;
+ ULONG Offset = 0;
+
+ for (Name = Data; (Offset < DataLength); )
+ {
+ if(L'\0' != *Name)
+ {
+ UNICODE_STRING Program;
+
+ /* Run the current program */
+ RtlInitUnicodeString (& Program, Name);
+ Status = SmExecuteProgram (hSmApiPort, & Program);
+ if(!NT_SUCCESS(Status))
+ {
+ DPRINT1("SM: %s failed to run '%S' program (Status=0x%08lx)\n",
+ __FUNCTION__, Name, Status);
+ }
+ /* Look for the next program */
+ while ((L'\0' != *Name) && (Offset < DataLength))
+ {
+ ++ Name;
+ ++ Offset;
+ }
+ }
+ ++ Name;
+ ++ Offset;
+ }
+ }
+
+ return Status;
+}
+
+/**********************************************************************
+ * SmLoadSubsystems/0
+ */
+NTSTATUS
+SmLoadSubsystems(VOID)
+{
+ NTSTATUS Status = STATUS_SUCCESS;
+
+
+ DPRINT("SM: loading subsystems\n");
+
+ /* SM self registers */
+ Status = SmpRegisterSmss();
+ if(!NT_SUCCESS(Status)) return Status;
+ /* Load Kmode subsystem (aka win32k.sys) */
+ Status = SmpLoadKernelModeSubsystem();
+ if(!NT_SUCCESS(Status)) return Status;
+ /* Load Required subsystems (Debug Windows) */
+ Status = SmpLoadRequiredSubsystems();
+ if(!NT_SUCCESS(Status)) return Status;
+ /* done */
+ return Status;
+}
+
+/* EOF */
-/* $Id: init.c 13449 2005-02-06 21:55:07Z ea $\r
- *\r
- * initwkdll.c - Load the well known DLLs\r
- * \r
- * ReactOS Operating System\r
- * \r
- * --------------------------------------------------------------------\r
- *\r
- * This software is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License as\r
- * published by the Free Software Foundation; either version 2 of the\r
- * License, or (at your option) any later version.\r
- *\r
- * This software is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
- * General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this software; see the file COPYING.LIB. If not, write\r
- * to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge,\r
- * MA 02139, USA. \r
- *\r
- * --------------------------------------------------------------------\r
- */\r
-\r
-#include "smss.h"\r
-\r
-#define NDEBUG\r
-#include <debug.h>\r
-\r
-static NTSTATUS STDCALL\r
-SmpKnownDllsQueryRoutine(PWSTR ValueName,\r
- ULONG ValueType,\r
- PVOID ValueData,\r
- ULONG ValueLength,\r
- PVOID Context,\r
- PVOID EntryContext)\r
-{\r
- OBJECT_ATTRIBUTES ObjectAttributes;\r
- IO_STATUS_BLOCK IoStatusBlock;\r
- UNICODE_STRING ImageName;\r
- HANDLE FileHandle;\r
- HANDLE SectionHandle;\r
- NTSTATUS Status;\r
-\r
- DPRINT("ValueName '%S' Type %lu Length %lu\n", ValueName, ValueType, ValueLength);\r
- DPRINT("ValueData '%S' Context %p EntryContext %p\n", (PWSTR)ValueData, Context, EntryContext);\r
-\r
- /* Ignore the 'DllDirectory' value */\r
- if (!_wcsicmp(ValueName, L"DllDirectory"))\r
- return STATUS_SUCCESS;\r
-\r
- /* Open the DLL image file */\r
- RtlInitUnicodeString(&ImageName,\r
- ValueData);\r
- InitializeObjectAttributes(&ObjectAttributes,\r
- &ImageName,\r
- OBJ_CASE_INSENSITIVE,\r
- (HANDLE)Context,\r
- NULL);\r
- Status = NtOpenFile(&FileHandle,\r
- SYNCHRONIZE | FILE_EXECUTE | FILE_READ_DATA,\r
- &ObjectAttributes,\r
- &IoStatusBlock,\r
- FILE_SHARE_READ,\r
- FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE);\r
- if (!NT_SUCCESS(Status))\r
- {\r
- DPRINT1("NtOpenFile() failed (Status %lx)\n", Status);\r
- return STATUS_SUCCESS;\r
- }\r
-\r
- DPRINT("Opened file %wZ successfully\n", &ImageName);\r
-\r
- /* Check for valid image checksum */\r
- Status = LdrVerifyImageMatchesChecksum (FileHandle,\r
- 0,\r
- 0,\r
- 0);\r
- if (Status == STATUS_IMAGE_CHECKSUM_MISMATCH)\r
- {\r
- /* Raise a hard error (crash the system/BSOD) */\r
- NtRaiseHardError (Status,\r
- 0,\r
- 0,\r
- 0,\r
- 0,\r
- 0);\r
- }\r
- else if (!NT_SUCCESS(Status))\r
- {\r
- DPRINT1("Failed to check the image checksum\n");\r
-\r
- NtClose(SectionHandle);\r
- NtClose(FileHandle);\r
-\r
- return STATUS_SUCCESS;\r
- }\r
-\r
- InitializeObjectAttributes(&ObjectAttributes,\r
- &ImageName,\r
- OBJ_CASE_INSENSITIVE | OBJ_PERMANENT,\r
- (HANDLE)EntryContext,\r
- NULL);\r
- Status = NtCreateSection(&SectionHandle,\r
- SECTION_ALL_ACCESS,\r
- &ObjectAttributes,\r
- NULL,\r
- PAGE_EXECUTE,\r
- SEC_IMAGE,\r
- FileHandle);\r
- if (NT_SUCCESS(Status))\r
- {\r
- DPRINT("Created section successfully\n");\r
- NtClose(SectionHandle);\r
- }\r
-\r
- NtClose(FileHandle);\r
-\r
- return STATUS_SUCCESS;\r
-}\r
-\r
-\r
-NTSTATUS\r
-SmLoadKnownDlls(VOID)\r
-{\r
- RTL_QUERY_REGISTRY_TABLE QueryTable[2];\r
- OBJECT_ATTRIBUTES ObjectAttributes;\r
- IO_STATUS_BLOCK IoStatusBlock;\r
- UNICODE_STRING DllDosPath;\r
- UNICODE_STRING DllNtPath;\r
- UNICODE_STRING Name;\r
- HANDLE ObjectDirHandle;\r
- HANDLE FileDirHandle;\r
- HANDLE SymlinkHandle;\r
- NTSTATUS Status;\r
-\r
-\r
- DPRINT("SM: loading well-known DLLs\n");\r
-\r
- DPRINT("SmLoadKnownDlls() called\n");\r
-\r
- /* Create 'KnownDlls' object directory */\r
- RtlInitUnicodeString(&Name,\r
- L"\\KnownDlls");\r
- InitializeObjectAttributes(&ObjectAttributes,\r
- &Name,\r
- OBJ_PERMANENT | OBJ_CASE_INSENSITIVE | OBJ_OPENIF,\r
- NULL,\r
- NULL);\r
- Status = NtCreateDirectoryObject(&ObjectDirHandle,\r
- DIRECTORY_ALL_ACCESS,\r
- &ObjectAttributes);\r
- if (!NT_SUCCESS(Status))\r
- {\r
- DPRINT1("NtCreateDirectoryObject() failed (Status %lx)\n", Status);\r
- return Status;\r
- }\r
-\r
- RtlInitUnicodeString(&DllDosPath, NULL);\r
-\r
- RtlZeroMemory(&QueryTable,\r
- sizeof(QueryTable));\r
-\r
- QueryTable[0].Name = L"DllDirectory";\r
- QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;\r
- QueryTable[0].EntryContext = &DllDosPath;\r
-\r
- Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,\r
- L"\\Session Manager\\KnownDlls",\r
- QueryTable,\r
- NULL,\r
- SmSystemEnvironment);\r
- if (!NT_SUCCESS(Status))\r
- {\r
- DPRINT1("RtlQueryRegistryValues() failed (Status %lx)\n", Status);\r
- return Status;\r
- }\r
-\r
- DPRINT("DllDosPath: '%wZ'\n", &DllDosPath);\r
-\r
- if (!RtlDosPathNameToNtPathName_U(DllDosPath.Buffer,\r
- &DllNtPath,\r
- NULL,\r
- NULL))\r
- {\r
- DPRINT1("RtlDosPathNameToNtPathName_U() failed\n");\r
- return STATUS_OBJECT_NAME_INVALID;\r
- }\r
-\r
- DPRINT("DllNtPath: '%wZ'\n", &DllNtPath);\r
-\r
- /* Open the dll path directory */\r
- InitializeObjectAttributes(&ObjectAttributes,\r
- &DllNtPath,\r
- OBJ_CASE_INSENSITIVE,\r
- NULL,\r
- NULL);\r
- Status = NtOpenFile(&FileDirHandle,\r
- SYNCHRONIZE | FILE_READ_DATA,\r
- &ObjectAttributes,\r
- &IoStatusBlock,\r
- FILE_SHARE_READ | FILE_SHARE_WRITE,\r
- FILE_SYNCHRONOUS_IO_NONALERT | FILE_DIRECTORY_FILE);\r
- if (!NT_SUCCESS(Status))\r
- {\r
- DPRINT1("NtOpenFile(%wZ) failed (Status %lx)\n", &DllNtPath, Status);\r
- return Status;\r
- }\r
-\r
- /* Link 'KnownDllPath' the dll path directory */\r
- RtlInitUnicodeString(&Name,\r
- L"KnownDllPath");\r
- InitializeObjectAttributes(&ObjectAttributes,\r
- &Name,\r
- OBJ_PERMANENT | OBJ_CASE_INSENSITIVE | OBJ_OPENIF,\r
- ObjectDirHandle,\r
- NULL);\r
- Status = NtCreateSymbolicLinkObject(&SymlinkHandle,\r
- SYMBOLIC_LINK_ALL_ACCESS,\r
- &ObjectAttributes,\r
- &DllDosPath);\r
- if (!NT_SUCCESS(Status))\r
- {\r
- DPRINT1("NtCreateSymbolicLink() failed (Status %lx)\n", Status);\r
- return Status;\r
- }\r
-\r
- NtClose(SymlinkHandle);\r
-\r
- RtlZeroMemory(&QueryTable,\r
- sizeof(QueryTable));\r
-\r
- QueryTable[0].QueryRoutine = SmpKnownDllsQueryRoutine;\r
- QueryTable[0].EntryContext = ObjectDirHandle;\r
-\r
- Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,\r
- L"\\Session Manager\\KnownDlls",\r
- QueryTable,\r
- (PVOID)FileDirHandle,\r
- NULL);\r
- if (!NT_SUCCESS(Status))\r
- {\r
- DPRINT1("RtlQueryRegistryValues() failed (Status %lx)\n", Status);\r
- }\r
-\r
- DPRINT("SmLoadKnownDlls() done\n");\r
-\r
- return Status;\r
-}\r
-\r
-\r
-/* EOF */\r
+/* $Id$
+ *
+ * initwkdll.c - Load the well known DLLs
+ *
+ * ReactOS Operating System
+ *
+ * --------------------------------------------------------------------
+ *
+ * This software 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 software 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 software; see the file COPYING.LIB. If not, write
+ * to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
+ * MA 02139, USA.
+ *
+ * --------------------------------------------------------------------
+ */
+
+#include "smss.h"
+
+#define NDEBUG
+#include <debug.h>
+
+static NTSTATUS STDCALL
+SmpKnownDllsQueryRoutine(PWSTR ValueName,
+ ULONG ValueType,
+ PVOID ValueData,
+ ULONG ValueLength,
+ PVOID Context,
+ PVOID EntryContext)
+{
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ IO_STATUS_BLOCK IoStatusBlock;
+ UNICODE_STRING ImageName;
+ HANDLE FileHandle;
+ HANDLE SectionHandle;
+ NTSTATUS Status;
+
+ DPRINT("ValueName '%S' Type %lu Length %lu\n", ValueName, ValueType, ValueLength);
+ DPRINT("ValueData '%S' Context %p EntryContext %p\n", (PWSTR)ValueData, Context, EntryContext);
+
+ /* Ignore the 'DllDirectory' value */
+ if (!_wcsicmp(ValueName, L"DllDirectory"))
+ return STATUS_SUCCESS;
+
+ /* Open the DLL image file */
+ RtlInitUnicodeString(&ImageName,
+ ValueData);
+ InitializeObjectAttributes(&ObjectAttributes,
+ &ImageName,
+ OBJ_CASE_INSENSITIVE,
+ (HANDLE)Context,
+ NULL);
+ Status = NtOpenFile(&FileHandle,
+ SYNCHRONIZE | FILE_EXECUTE | FILE_READ_DATA,
+ &ObjectAttributes,
+ &IoStatusBlock,
+ FILE_SHARE_READ,
+ FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("NtOpenFile() failed (Status %lx)\n", Status);
+ return STATUS_SUCCESS;
+ }
+
+ DPRINT("Opened file %wZ successfully\n", &ImageName);
+
+ /* Check for valid image checksum */
+ Status = LdrVerifyImageMatchesChecksum (FileHandle,
+ 0,
+ 0,
+ 0);
+ if (Status == STATUS_IMAGE_CHECKSUM_MISMATCH)
+ {
+ /* Raise a hard error (crash the system/BSOD) */
+ NtRaiseHardError (Status,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0);
+ }
+ else if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to check the image checksum\n");
+
+ NtClose(SectionHandle);
+ NtClose(FileHandle);
+
+ return STATUS_SUCCESS;
+ }
+
+ InitializeObjectAttributes(&ObjectAttributes,
+ &ImageName,
+ OBJ_CASE_INSENSITIVE | OBJ_PERMANENT,
+ (HANDLE)EntryContext,
+ NULL);
+ Status = NtCreateSection(&SectionHandle,
+ SECTION_ALL_ACCESS,
+ &ObjectAttributes,
+ NULL,
+ PAGE_EXECUTE,
+ SEC_IMAGE,
+ FileHandle);
+ if (NT_SUCCESS(Status))
+ {
+ DPRINT("Created section successfully\n");
+ NtClose(SectionHandle);
+ }
+
+ NtClose(FileHandle);
+
+ return STATUS_SUCCESS;
+}
+
+
+NTSTATUS
+SmLoadKnownDlls(VOID)
+{
+ RTL_QUERY_REGISTRY_TABLE QueryTable[2];
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ IO_STATUS_BLOCK IoStatusBlock;
+ UNICODE_STRING DllDosPath;
+ UNICODE_STRING DllNtPath;
+ UNICODE_STRING Name;
+ HANDLE ObjectDirHandle;
+ HANDLE FileDirHandle;
+ HANDLE SymlinkHandle;
+ NTSTATUS Status;
+
+
+ DPRINT("SM: loading well-known DLLs\n");
+
+ DPRINT("SmLoadKnownDlls() called\n");
+
+ /* Create 'KnownDlls' object directory */
+ RtlInitUnicodeString(&Name,
+ L"\\KnownDlls");
+ InitializeObjectAttributes(&ObjectAttributes,
+ &Name,
+ OBJ_PERMANENT | OBJ_CASE_INSENSITIVE | OBJ_OPENIF,
+ NULL,
+ NULL);
+ Status = NtCreateDirectoryObject(&ObjectDirHandle,
+ DIRECTORY_ALL_ACCESS,
+ &ObjectAttributes);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("NtCreateDirectoryObject() failed (Status %lx)\n", Status);
+ return Status;
+ }
+
+ RtlInitUnicodeString(&DllDosPath, NULL);
+
+ RtlZeroMemory(&QueryTable,
+ sizeof(QueryTable));
+
+ QueryTable[0].Name = L"DllDirectory";
+ QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
+ QueryTable[0].EntryContext = &DllDosPath;
+
+ Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,
+ L"\\Session Manager\\KnownDlls",
+ QueryTable,
+ NULL,
+ SmSystemEnvironment);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("RtlQueryRegistryValues() failed (Status %lx)\n", Status);
+ return Status;
+ }
+
+ DPRINT("DllDosPath: '%wZ'\n", &DllDosPath);
+
+ if (!RtlDosPathNameToNtPathName_U(DllDosPath.Buffer,
+ &DllNtPath,
+ NULL,
+ NULL))
+ {
+ DPRINT1("RtlDosPathNameToNtPathName_U() failed\n");
+ return STATUS_OBJECT_NAME_INVALID;
+ }
+
+ DPRINT("DllNtPath: '%wZ'\n", &DllNtPath);
+
+ /* Open the dll path directory */
+ InitializeObjectAttributes(&ObjectAttributes,
+ &DllNtPath,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
+ Status = NtOpenFile(&FileDirHandle,
+ SYNCHRONIZE | FILE_READ_DATA,
+ &ObjectAttributes,
+ &IoStatusBlock,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ FILE_SYNCHRONOUS_IO_NONALERT | FILE_DIRECTORY_FILE);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("NtOpenFile(%wZ) failed (Status %lx)\n", &DllNtPath, Status);
+ return Status;
+ }
+
+ /* Link 'KnownDllPath' the dll path directory */
+ RtlInitUnicodeString(&Name,
+ L"KnownDllPath");
+ InitializeObjectAttributes(&ObjectAttributes,
+ &Name,
+ OBJ_PERMANENT | OBJ_CASE_INSENSITIVE | OBJ_OPENIF,
+ ObjectDirHandle,
+ NULL);
+ Status = NtCreateSymbolicLinkObject(&SymlinkHandle,
+ SYMBOLIC_LINK_ALL_ACCESS,
+ &ObjectAttributes,
+ &DllDosPath);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("NtCreateSymbolicLink() failed (Status %lx)\n", Status);
+ return Status;
+ }
+
+ NtClose(SymlinkHandle);
+
+ RtlZeroMemory(&QueryTable,
+ sizeof(QueryTable));
+
+ QueryTable[0].QueryRoutine = SmpKnownDllsQueryRoutine;
+ QueryTable[0].EntryContext = ObjectDirHandle;
+
+ Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,
+ L"\\Session Manager\\KnownDlls",
+ QueryTable,
+ (PVOID)FileDirHandle,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("RtlQueryRegistryValues() failed (Status %lx)\n", Status);
+ }
+
+ DPRINT("SmLoadKnownDlls() done\n");
+
+ return Status;
+}
+
+
+/* EOF */
-/* $Id: print.c 12852 2005-01-06 13:58:04Z mf $\r
- *\r
- * print.c - Print on the blue screen\r
- * \r
- * ReactOS Operating System\r
- * \r
- * --------------------------------------------------------------------\r
- *\r
- * This software is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License as\r
- * published by the Free Software Foundation; either version 2 of the\r
- * License, or (at your option) any later version.\r
- *\r
- * This software is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
- * General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this software; see the file COPYING.LIB. If not, write\r
- * to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge,\r
- * MA 02139, USA. \r
- *\r
- * --------------------------------------------------------------------\r
- */\r
-#define NTOS_MODE_USER\r
-#include <ntos.h>\r
-\r
-VOID STDCALL DisplayString(LPCWSTR lpwString)\r
-{\r
- UNICODE_STRING us;\r
- \r
- RtlInitUnicodeString (&us, lpwString);\r
- ZwDisplayString (&us);\r
-}\r
-\r
-VOID STDCALL PrintString (char* fmt, ...)\r
-{\r
- char buffer[512];\r
- va_list ap;\r
- UNICODE_STRING UnicodeString;\r
- ANSI_STRING AnsiString;\r
- \r
- va_start(ap, fmt);\r
- vsprintf(buffer, fmt, ap);\r
- va_end(ap);\r
- \r
- RtlInitAnsiString (&AnsiString, buffer);\r
- RtlAnsiStringToUnicodeString (&UnicodeString,\r
- &AnsiString,\r
- TRUE);\r
- NtDisplayString(&UnicodeString);\r
- RtlFreeUnicodeString (&UnicodeString);\r
-}\r
-\r
-/* EOF */\r
+/* $Id$
+ *
+ * print.c - Print on the blue screen
+ *
+ * ReactOS Operating System
+ *
+ * --------------------------------------------------------------------
+ *
+ * This software 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 software 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 software; see the file COPYING.LIB. If not, write
+ * to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
+ * MA 02139, USA.
+ *
+ * --------------------------------------------------------------------
+ */
+#define NTOS_MODE_USER
+#include <ntos.h>
+
+VOID STDCALL DisplayString(LPCWSTR lpwString)
+{
+ UNICODE_STRING us;
+
+ RtlInitUnicodeString (&us, lpwString);
+ ZwDisplayString (&us);
+}
+
+VOID STDCALL PrintString (char* fmt, ...)
+{
+ char buffer[512];
+ va_list ap;
+ UNICODE_STRING UnicodeString;
+ ANSI_STRING AnsiString;
+
+ va_start(ap, fmt);
+ vsprintf(buffer, fmt, ap);
+ va_end(ap);
+
+ RtlInitAnsiString (&AnsiString, buffer);
+ RtlAnsiStringToUnicodeString (&UnicodeString,
+ &AnsiString,
+ TRUE);
+ NtDisplayString(&UnicodeString);
+ RtlFreeUnicodeString (&UnicodeString);
+}
+
+/* EOF */
-/* $Id: $\r
- *\r
- * smapicomp.c - SM_API_COMPLETE_SESSION\r
- *\r
- * Reactos Session Manager\r
- *\r
- * --------------------------------------------------------------------\r
- *\r
- * This software is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License as\r
- * published by the Free Software Foundation; either version 2 of the\r
- * License, or (at your option) any later version.\r
- *\r
- * This software is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
- * General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this software; see the file COPYING.LIB. If not, write\r
- * to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge,\r
- * MA 02139, USA. \r
- *\r
- * --------------------------------------------------------------------\r
- */\r
-#include "smss.h"\r
-\r
-#define NDEBUG\r
-#include <debug.h>\r
-\r
-\r
-/**********************************************************************\r
- * SmCompSes/1 API\r
- */\r
-SMAPI(SmCompSes)\r
-{\r
- NTSTATUS Status = STATUS_SUCCESS;\r
-\r
- DPRINT("SM: %s called\n", __FUNCTION__);\r
-\r
- DPRINT("SM: %s: ClientId.UniqueProcess=%lx\n",\r
- __FUNCTION__, Request->Header.ClientId.UniqueProcess);\r
- Status = SmCompleteClientInitialization ((ULONG) Request->Header.ClientId.UniqueProcess);\r
- if (!NT_SUCCESS(Status))\r
- {\r
- DPRINT1("SM: %s: NtQueryInformationProcess failed (Status=0x%08lx)\n",\r
- __FUNCTION__, Status);\r
- }\r
- Request->SmHeader.Status = Status;\r
- return STATUS_SUCCESS;\r
-}\r
-\r
-\r
-/* EOF */\r
+/* $Id$
+ *
+ * smapicomp.c - SM_API_COMPLETE_SESSION
+ *
+ * Reactos Session Manager
+ *
+ * --------------------------------------------------------------------
+ *
+ * This software 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 software 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 software; see the file COPYING.LIB. If not, write
+ * to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
+ * MA 02139, USA.
+ *
+ * --------------------------------------------------------------------
+ */
+#include "smss.h"
+
+#define NDEBUG
+#include <debug.h>
+
+
+/**********************************************************************
+ * SmCompSes/1 API
+ */
+SMAPI(SmCompSes)
+{
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ DPRINT("SM: %s called\n", __FUNCTION__);
+
+ DPRINT("SM: %s: ClientId.UniqueProcess=%lx\n",
+ __FUNCTION__, Request->Header.ClientId.UniqueProcess);
+ Status = SmCompleteClientInitialization ((ULONG) Request->Header.ClientId.UniqueProcess);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("SM: %s: NtQueryInformationProcess failed (Status=0x%08lx)\n",
+ __FUNCTION__, Status);
+ }
+ Request->SmHeader.Status = Status;
+ return STATUS_SUCCESS;
+}
+
+
+/* EOF */
-/* $Id$\r
- *\r
- * smapiexec.c - SM_API_EXECUTE_PROGRAM\r
- *\r
- * Reactos Session Manager\r
- *\r
- * --------------------------------------------------------------------\r
- *\r
- * This software is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License as\r
- * published by the Free Software Foundation; either version 2 of the\r
- * License, or (at your option) any later version.\r
- *\r
- * This software is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
- * General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this software; see the file COPYING.LIB. If not, write\r
- * to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge,\r
- * MA 02139, USA. \r
- *\r
- * --------------------------------------------------------------------\r
- */\r
-#include "smss.h"\r
-\r
-#define NDEBUG\r
-#include <debug.h>\r
-\r
-/**********************************************************************\r
- * SmCreateUserProcess/5\r
- *\r
- * DESCRIPTION\r
- *\r
- * ARGUMENTS\r
- * ImagePath: bsolute path of the image to run;\r
- * CommandLine: arguments and options for ImagePath;\r
- * WaitForIt: TRUE for boot time processes and FALSE for\r
- * subsystems bootstrapping;\r
- * Timeout: optional: used if WaitForIt==TRUE;\r
- * ProcessHandle: optional: a duplicated handle for\r
- the child process (storage provided by the caller).\r
- *\r
- * RETURN VALUE\r
- * NTSTATUS:\r
- *\r
- */\r
-NTSTATUS STDCALL\r
-SmCreateUserProcess (LPWSTR ImagePath,\r
- LPWSTR CommandLine,\r
- BOOLEAN WaitForIt,\r
- PLARGE_INTEGER Timeout OPTIONAL,\r
- PRTL_PROCESS_INFO UserProcessInfo OPTIONAL)\r
-{\r
- UNICODE_STRING ImagePathString = {0};\r
- UNICODE_STRING CommandLineString = {0};\r
- PRTL_USER_PROCESS_PARAMETERS ProcessParameters = NULL;\r
- RTL_PROCESS_INFO ProcessInfo = {0};\r
- PRTL_PROCESS_INFO pProcessInfo = & ProcessInfo;\r
- NTSTATUS Status = STATUS_SUCCESS;\r
-\r
- DPRINT("SM: %s called\n", __FUNCTION__);\r
- \r
- if (NULL != UserProcessInfo)\r
- {\r
- pProcessInfo = UserProcessInfo;\r
- }\r
-\r
- RtlInitUnicodeString (& ImagePathString, ImagePath);\r
- RtlInitUnicodeString (& CommandLineString, CommandLine);\r
-\r
- RtlCreateProcessParameters(& ProcessParameters,\r
- & ImagePathString,\r
- NULL,\r
- NULL,\r
- & CommandLineString,\r
- SmSystemEnvironment,\r
- NULL,\r
- NULL,\r
- NULL,\r
- NULL);\r
-\r
- Status = RtlCreateUserProcess (& ImagePathString,\r
- OBJ_CASE_INSENSITIVE,\r
- ProcessParameters,\r
- NULL,\r
- NULL,\r
- NULL,\r
- FALSE,\r
- NULL,\r
- NULL,\r
- pProcessInfo);\r
- \r
- RtlDestroyProcessParameters (ProcessParameters);\r
- \r
- if (!NT_SUCCESS(Status))\r
- {\r
- DPRINT1("SM: %s: Running \"%S\" failed (Status=0x%08lx)\n",\r
- __FUNCTION__, ImagePathString.Buffer, Status);\r
- return Status;\r
- }\r
- /*\r
- * It the caller is *not* interested in the child info,\r
- * resume it immediately.\r
- */\r
- if (NULL == UserProcessInfo)\r
- {\r
- Status = NtResumeThread (ProcessInfo.ThreadHandle, NULL);\r
- if(!NT_SUCCESS(Status))\r
- {\r
- DPRINT1("SM: %s: NtResumeThread failed (Status=0x%08lx)\n",\r
- __FUNCTION__, Status);\r
- }\r
- }\r
- else\r
- {\r
- HANDLE DupProcessHandle = (HANDLE) 0;\r
- \r
- Status = NtDuplicateObject (NtCurrentProcess(),\r
- pProcessInfo->ProcessHandle,\r
- NtCurrentProcess(),\r
- & DupProcessHandle,\r
- PROCESS_ALL_ACCESS,\r
- 0, 0);\r
- if(!NT_SUCCESS(Status))\r
- {\r
- DPRINT1("SM: %s: NtDuplicateObject failed (Status=0x%08lx)\n",\r
- __FUNCTION__, Status);\r
- }\r
- pProcessInfo->ProcessHandle = DupProcessHandle;\r
- \r
- }\r
-\r
- /* Wait for process termination */\r
- if (WaitForIt)\r
- {\r
- Status = NtWaitForSingleObject (pProcessInfo->ProcessHandle,\r
- FALSE,\r
- Timeout);\r
- if (!NT_SUCCESS(Status))\r
- {\r
- DPRINT1("SM: %s: NtWaitForSingleObject failed with Status=0x%08lx\n",\r
- __FUNCTION__, Status);\r
- }\r
- \r
- }\r
- return Status;\r
-}\r
-\r
-/**********************************************************************\r
- * NAME\r
- * SmLookupSubsystem/5\r
- *\r
- * DESCRIPTION\r
- * Read from the registry key\r
- * \Registry\SYSTEM\CurrentControlSet\Control\Session Manager\Subsystems\r
- * the value which name is Name.\r
- *\r
- * ARGUMENTS\r
- * Name: name of the program to run, that is a value's name in\r
- * the SM registry key Subsystems;\r
- * Data: what the registry gave back for Name;\r
- * DataLength: how much Data the registry returns;\r
- * DataType: what is Data?\r
- * Expand: set it TRUE if you want this function to use the env\r
- * to possibly expand Data before giving it back.\r
- */\r
-NTSTATUS STDCALL\r
-SmLookupSubsystem (IN PWSTR Name,\r
- IN OUT PWSTR Data,\r
- IN OUT PULONG DataLength,\r
- IN OUT PULONG DataType,\r
- IN BOOLEAN Expand)\r
-{\r
- NTSTATUS Status = STATUS_SUCCESS;\r
- UNICODE_STRING usKeyName = {0};\r
- OBJECT_ATTRIBUTES Oa = {0};\r
- HANDLE hKey = (HANDLE) 0;\r
-\r
- DPRINT("SM: %s(Name='%S') called\n", __FUNCTION__, Name);\r
- /*\r
- * Prepare the key name to scan and\r
- * related object attributes.\r
- */\r
- RtlInitUnicodeString (& usKeyName,\r
- L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\SubSystems");\r
-\r
- InitializeObjectAttributes (& Oa,\r
- & usKeyName,\r
- OBJ_CASE_INSENSITIVE,\r
- NULL,\r
- NULL);\r
- /*\r
- * Open the key. This MUST NOT fail, if the\r
- * request is for a legitimate subsystem.\r
- */\r
- Status = NtOpenKey (& hKey,\r
- MAXIMUM_ALLOWED,\r
- & Oa);\r
- if(NT_SUCCESS(Status))\r
- {\r
- UNICODE_STRING usValueName = {0};\r
- WCHAR KeyValueInformation [1024] = {L'\0'};\r
- ULONG ResultLength = 0L;\r
- PKEY_VALUE_PARTIAL_INFORMATION\r
- kvpi = (PKEY_VALUE_PARTIAL_INFORMATION) KeyValueInformation;\r
-\r
- \r
- RtlInitUnicodeString (& usValueName, Name);\r
- Status = NtQueryValueKey (hKey,\r
- & usValueName,\r
- KeyValuePartialInformation,\r
- KeyValueInformation,\r
- sizeof KeyValueInformation,\r
- & ResultLength);\r
- if(NT_SUCCESS(Status))\r
- {\r
- DPRINT("nkvpi.TitleIndex = %ld\n", kvpi->TitleIndex);\r
- DPRINT("kvpi.Type = %ld\n", kvpi->Type);\r
- DPRINT("kvpi.DataLength = %ld\n", kvpi->DataLength);\r
-\r
- if((NULL != Data) && (NULL != DataLength) && (NULL != DataType))\r
- {\r
- *DataType = kvpi->Type;\r
- if((Expand) && (REG_EXPAND_SZ == *DataType))\r
- {\r
- UNICODE_STRING Source;\r
- WCHAR DestinationBuffer [2048] = {0};\r
- UNICODE_STRING Destination;\r
- ULONG Length = 0;\r
-\r
- DPRINT("SM: %s: value will be expanded\n", __FUNCTION__);\r
-\r
- Source.Length = kvpi->DataLength;\r
- Source.MaximumLength = kvpi->DataLength;\r
- Source.Buffer = (PWCHAR) & kvpi->Data;\r
-\r
- Destination.Length = 0;\r
- Destination.MaximumLength = sizeof DestinationBuffer;\r
- Destination.Buffer = DestinationBuffer;\r
-\r
- Status = RtlExpandEnvironmentStrings_U (SmSystemEnvironment,\r
- & Source,\r
- & Destination,\r
- & Length);\r
- if(NT_SUCCESS(Status))\r
- {\r
- *DataLength = min(*DataLength, Destination.Length);\r
- RtlCopyMemory (Data, Destination.Buffer, *DataLength); \r
- }\r
- \r
- }else{\r
- DPRINT("SM: %s: value won't be expanded\n", __FUNCTION__);\r
- *DataLength = min(*DataLength, kvpi->DataLength);\r
- RtlCopyMemory (Data, & kvpi->Data, *DataLength);\r
- }\r
- *DataType = kvpi->Type;\r
- }else{\r
- DPRINT1("SM: %s: Data or DataLength or DataType is NULL!\n", __FUNCTION__);\r
- Status = STATUS_INVALID_PARAMETER;\r
- }\r
- }else{\r
- DPRINT1("%s: NtQueryValueKey failed (Status=0x%08lx)\n", __FUNCTION__, Status);\r
- }\r
- NtClose (hKey);\r
- }else{\r
- DPRINT1("%s: NtOpenKey failed (Status=0x%08lx)\n", __FUNCTION__, Status);\r
- }\r
- return Status;\r
-}\r
-\r
-\r
-/**********************************************************************\r
- * SmExecPgm/1 API\r
- */\r
-SMAPI(SmExecPgm)\r
-{\r
- PSM_PORT_MESSAGE_EXECPGM ExecPgm = NULL;\r
- WCHAR Name [SM_EXEXPGM_MAX_LENGTH + 1];\r
- NTSTATUS Status = STATUS_SUCCESS;\r
-\r
- DPRINT("SM: %s called\n",__FUNCTION__);\r
-\r
- if(NULL == Request)\r
- {\r
- DPRINT1("SM: %s: Request == NULL!\n", __FUNCTION__);\r
- return STATUS_INVALID_PARAMETER;\r
- }\r
- DPRINT("SM: %s called from CID(%lx|%lx)\n",\r
- __FUNCTION__, Request->Header.ClientId.UniqueProcess,\r
- Request->Header.ClientId.UniqueThread);\r
- ExecPgm = & Request->Request.ExecPgm;\r
- /* Check if the name lenght is valid */\r
- if((ExecPgm->NameLength > 0) &&\r
- (ExecPgm->NameLength <= SM_EXEXPGM_MAX_LENGTH) &&\r
- TRUE /* TODO: check LPC payload size */)\r
- {\r
- WCHAR Data [MAX_PATH + 1] = {0};\r
- ULONG DataLength = sizeof Data;\r
- ULONG DataType = REG_EXPAND_SZ;\r
-\r
- \r
- RtlZeroMemory (Name, sizeof Name);\r
- RtlCopyMemory (Name,\r
- ExecPgm->Name,\r
- (sizeof ExecPgm->Name[0] * ExecPgm->NameLength));\r
- DPRINT("SM: %s: Name='%S'\n", __FUNCTION__, Name);\r
- /* Lookup Name in the registry */\r
- Status = SmLookupSubsystem (Name,\r
- Data,\r
- & DataLength,\r
- & DataType,\r
- TRUE); /* expand */\r
- if(NT_SUCCESS(Status))\r
- {\r
- /* Is the subsystem definition non-empty? */\r
- if (DataLength > sizeof Data[0])\r
- {\r
- WCHAR ImagePath [MAX_PATH + 1] = {0};\r
- PWCHAR CommandLine = ImagePath;\r
- RTL_PROCESS_INFO ProcessInfo = {0};\r
-\r
- wcscpy (ImagePath, L"\\??\\");\r
- wcscat (ImagePath, Data);\r
- /*\r
- * Look for the beginning of the command line.\r
- */\r
- for (; (*CommandLine != L'\0') && (*CommandLine != L' ');\r
- CommandLine ++);\r
- for (; *CommandLine == L' '; CommandLine ++)\r
- {\r
- *CommandLine = L'\0';\r
- }\r
- /*\r
- * Create a native process (suspended).\r
- */\r
- ProcessInfo.Size = sizeof ProcessInfo;\r
- Request->SmHeader.Status =\r
- SmCreateUserProcess(ImagePath,\r
- CommandLine,\r
- FALSE, /* wait */\r
- NULL, /* timeout */\r
- & ProcessInfo);\r
- if (NT_SUCCESS(Request->SmHeader.Status))\r
- {\r
- Status = SmCreateClient (& ProcessInfo, Name);\r
- if (NT_SUCCESS(Status))\r
- {\r
- Status = NtResumeThread (ProcessInfo.ThreadHandle, NULL);\r
- if (!NT_SUCCESS(Status))\r
- {\r
- //Status = SmDestroyClient TODO\r
- }\r
- } else {\r
- DPRINT1("SM: %s: SmCreateClient failed (Status=0x%08lx)\n",\r
- __FUNCTION__, Status);\r
- }\r
- }\r
- }\r
- else\r
- {\r
- /*\r
- * OK, the definition is empty, but check\r
- * if it is the name of an embedded subsystem.\r
- */\r
- if(0 == _wcsicmp(L"DEBUG", Name))\r
- {\r
- /*\r
- * Initialize the embedded DBGSS.\r
- */\r
- Request->SmHeader.Status = SmInitializeDbgSs();\r
- }\r
- else\r
- {\r
- /*\r
- * Badly defined subsystem. Check the registry!\r
- */\r
- Request->SmHeader.Status = STATUS_NOT_FOUND;\r
- }\r
- }\r
- } else {\r
- /* It couldn't lookup the Name! */\r
- Request->SmHeader.Status = Status;\r
- }\r
- }\r
- return Status;\r
-}\r
-\r
-/* EOF */\r
+/* $Id$
+ *
+ * smapiexec.c - SM_API_EXECUTE_PROGRAM
+ *
+ * Reactos Session Manager
+ *
+ * --------------------------------------------------------------------
+ *
+ * This software 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 software 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 software; see the file COPYING.LIB. If not, write
+ * to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
+ * MA 02139, USA.
+ *
+ * --------------------------------------------------------------------
+ */
+#include "smss.h"
+
+#define NDEBUG
+#include <debug.h>
+
+/**********************************************************************
+ * SmCreateUserProcess/5
+ *
+ * DESCRIPTION
+ *
+ * ARGUMENTS
+ * ImagePath: bsolute path of the image to run;
+ * CommandLine: arguments and options for ImagePath;
+ * WaitForIt: TRUE for boot time processes and FALSE for
+ * subsystems bootstrapping;
+ * Timeout: optional: used if WaitForIt==TRUE;
+ * ProcessHandle: optional: a duplicated handle for
+ the child process (storage provided by the caller).
+ *
+ * RETURN VALUE
+ * NTSTATUS:
+ *
+ */
+NTSTATUS STDCALL
+SmCreateUserProcess (LPWSTR ImagePath,
+ LPWSTR CommandLine,
+ BOOLEAN WaitForIt,
+ PLARGE_INTEGER Timeout OPTIONAL,
+ PRTL_PROCESS_INFO UserProcessInfo OPTIONAL)
+{
+ UNICODE_STRING ImagePathString = {0};
+ UNICODE_STRING CommandLineString = {0};
+ PRTL_USER_PROCESS_PARAMETERS ProcessParameters = NULL;
+ RTL_PROCESS_INFO ProcessInfo = {0};
+ PRTL_PROCESS_INFO pProcessInfo = & ProcessInfo;
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ DPRINT("SM: %s called\n", __FUNCTION__);
+
+ if (NULL != UserProcessInfo)
+ {
+ pProcessInfo = UserProcessInfo;
+ }
+
+ RtlInitUnicodeString (& ImagePathString, ImagePath);
+ RtlInitUnicodeString (& CommandLineString, CommandLine);
+
+ RtlCreateProcessParameters(& ProcessParameters,
+ & ImagePathString,
+ NULL,
+ NULL,
+ & CommandLineString,
+ SmSystemEnvironment,
+ NULL,
+ NULL,
+ NULL,
+ NULL);
+
+ Status = RtlCreateUserProcess (& ImagePathString,
+ OBJ_CASE_INSENSITIVE,
+ ProcessParameters,
+ NULL,
+ NULL,
+ NULL,
+ FALSE,
+ NULL,
+ NULL,
+ pProcessInfo);
+
+ RtlDestroyProcessParameters (ProcessParameters);
+
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("SM: %s: Running \"%S\" failed (Status=0x%08lx)\n",
+ __FUNCTION__, ImagePathString.Buffer, Status);
+ return Status;
+ }
+ /*
+ * It the caller is *not* interested in the child info,
+ * resume it immediately.
+ */
+ if (NULL == UserProcessInfo)
+ {
+ Status = NtResumeThread (ProcessInfo.ThreadHandle, NULL);
+ if(!NT_SUCCESS(Status))
+ {
+ DPRINT1("SM: %s: NtResumeThread failed (Status=0x%08lx)\n",
+ __FUNCTION__, Status);
+ }
+ }
+ else
+ {
+ HANDLE DupProcessHandle = (HANDLE) 0;
+
+ Status = NtDuplicateObject (NtCurrentProcess(),
+ pProcessInfo->ProcessHandle,
+ NtCurrentProcess(),
+ & DupProcessHandle,
+ PROCESS_ALL_ACCESS,
+ 0, 0);
+ if(!NT_SUCCESS(Status))
+ {
+ DPRINT1("SM: %s: NtDuplicateObject failed (Status=0x%08lx)\n",
+ __FUNCTION__, Status);
+ }
+ pProcessInfo->ProcessHandle = DupProcessHandle;
+
+ }
+
+ /* Wait for process termination */
+ if (WaitForIt)
+ {
+ Status = NtWaitForSingleObject (pProcessInfo->ProcessHandle,
+ FALSE,
+ Timeout);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("SM: %s: NtWaitForSingleObject failed with Status=0x%08lx\n",
+ __FUNCTION__, Status);
+ }
+
+ }
+ return Status;
+}
+
+/**********************************************************************
+ * NAME
+ * SmLookupSubsystem/5
+ *
+ * DESCRIPTION
+ * Read from the registry key
+ * \Registry\SYSTEM\CurrentControlSet\Control\Session Manager\Subsystems
+ * the value which name is Name.
+ *
+ * ARGUMENTS
+ * Name: name of the program to run, that is a value's name in
+ * the SM registry key Subsystems;
+ * Data: what the registry gave back for Name;
+ * DataLength: how much Data the registry returns;
+ * DataType: what is Data?
+ * Expand: set it TRUE if you want this function to use the env
+ * to possibly expand Data before giving it back.
+ */
+NTSTATUS STDCALL
+SmLookupSubsystem (IN PWSTR Name,
+ IN OUT PWSTR Data,
+ IN OUT PULONG DataLength,
+ IN OUT PULONG DataType,
+ IN BOOLEAN Expand)
+{
+ NTSTATUS Status = STATUS_SUCCESS;
+ UNICODE_STRING usKeyName = {0};
+ OBJECT_ATTRIBUTES Oa = {0};
+ HANDLE hKey = (HANDLE) 0;
+
+ DPRINT("SM: %s(Name='%S') called\n", __FUNCTION__, Name);
+ /*
+ * Prepare the key name to scan and
+ * related object attributes.
+ */
+ RtlInitUnicodeString (& usKeyName,
+ L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\SubSystems");
+
+ InitializeObjectAttributes (& Oa,
+ & usKeyName,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
+ /*
+ * Open the key. This MUST NOT fail, if the
+ * request is for a legitimate subsystem.
+ */
+ Status = NtOpenKey (& hKey,
+ MAXIMUM_ALLOWED,
+ & Oa);
+ if(NT_SUCCESS(Status))
+ {
+ UNICODE_STRING usValueName = {0};
+ WCHAR KeyValueInformation [1024] = {L'\0'};
+ ULONG ResultLength = 0L;
+ PKEY_VALUE_PARTIAL_INFORMATION
+ kvpi = (PKEY_VALUE_PARTIAL_INFORMATION) KeyValueInformation;
+
+
+ RtlInitUnicodeString (& usValueName, Name);
+ Status = NtQueryValueKey (hKey,
+ & usValueName,
+ KeyValuePartialInformation,
+ KeyValueInformation,
+ sizeof KeyValueInformation,
+ & ResultLength);
+ if(NT_SUCCESS(Status))
+ {
+ DPRINT("nkvpi.TitleIndex = %ld\n", kvpi->TitleIndex);
+ DPRINT("kvpi.Type = %ld\n", kvpi->Type);
+ DPRINT("kvpi.DataLength = %ld\n", kvpi->DataLength);
+
+ if((NULL != Data) && (NULL != DataLength) && (NULL != DataType))
+ {
+ *DataType = kvpi->Type;
+ if((Expand) && (REG_EXPAND_SZ == *DataType))
+ {
+ UNICODE_STRING Source;
+ WCHAR DestinationBuffer [2048] = {0};
+ UNICODE_STRING Destination;
+ ULONG Length = 0;
+
+ DPRINT("SM: %s: value will be expanded\n", __FUNCTION__);
+
+ Source.Length = kvpi->DataLength;
+ Source.MaximumLength = kvpi->DataLength;
+ Source.Buffer = (PWCHAR) & kvpi->Data;
+
+ Destination.Length = 0;
+ Destination.MaximumLength = sizeof DestinationBuffer;
+ Destination.Buffer = DestinationBuffer;
+
+ Status = RtlExpandEnvironmentStrings_U (SmSystemEnvironment,
+ & Source,
+ & Destination,
+ & Length);
+ if(NT_SUCCESS(Status))
+ {
+ *DataLength = min(*DataLength, Destination.Length);
+ RtlCopyMemory (Data, Destination.Buffer, *DataLength);
+ }
+
+ }else{
+ DPRINT("SM: %s: value won't be expanded\n", __FUNCTION__);
+ *DataLength = min(*DataLength, kvpi->DataLength);
+ RtlCopyMemory (Data, & kvpi->Data, *DataLength);
+ }
+ *DataType = kvpi->Type;
+ }else{
+ DPRINT1("SM: %s: Data or DataLength or DataType is NULL!\n", __FUNCTION__);
+ Status = STATUS_INVALID_PARAMETER;
+ }
+ }else{
+ DPRINT1("%s: NtQueryValueKey failed (Status=0x%08lx)\n", __FUNCTION__, Status);
+ }
+ NtClose (hKey);
+ }else{
+ DPRINT1("%s: NtOpenKey failed (Status=0x%08lx)\n", __FUNCTION__, Status);
+ }
+ return Status;
+}
+
+
+/**********************************************************************
+ * SmExecPgm/1 API
+ */
+SMAPI(SmExecPgm)
+{
+ PSM_PORT_MESSAGE_EXECPGM ExecPgm = NULL;
+ WCHAR Name [SM_EXEXPGM_MAX_LENGTH + 1];
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ DPRINT("SM: %s called\n",__FUNCTION__);
+
+ if(NULL == Request)
+ {
+ DPRINT1("SM: %s: Request == NULL!\n", __FUNCTION__);
+ return STATUS_INVALID_PARAMETER;
+ }
+ DPRINT("SM: %s called from CID(%lx|%lx)\n",
+ __FUNCTION__, Request->Header.ClientId.UniqueProcess,
+ Request->Header.ClientId.UniqueThread);
+ ExecPgm = & Request->Request.ExecPgm;
+ /* Check if the name lenght is valid */
+ if((ExecPgm->NameLength > 0) &&
+ (ExecPgm->NameLength <= SM_EXEXPGM_MAX_LENGTH) &&
+ TRUE /* TODO: check LPC payload size */)
+ {
+ WCHAR Data [MAX_PATH + 1] = {0};
+ ULONG DataLength = sizeof Data;
+ ULONG DataType = REG_EXPAND_SZ;
+
+
+ RtlZeroMemory (Name, sizeof Name);
+ RtlCopyMemory (Name,
+ ExecPgm->Name,
+ (sizeof ExecPgm->Name[0] * ExecPgm->NameLength));
+ DPRINT("SM: %s: Name='%S'\n", __FUNCTION__, Name);
+ /* Lookup Name in the registry */
+ Status = SmLookupSubsystem (Name,
+ Data,
+ & DataLength,
+ & DataType,
+ TRUE); /* expand */
+ if(NT_SUCCESS(Status))
+ {
+ /* Is the subsystem definition non-empty? */
+ if (DataLength > sizeof Data[0])
+ {
+ WCHAR ImagePath [MAX_PATH + 1] = {0};
+ PWCHAR CommandLine = ImagePath;
+ RTL_PROCESS_INFO ProcessInfo = {0};
+
+ wcscpy (ImagePath, L"\\??\\");
+ wcscat (ImagePath, Data);
+ /*
+ * Look for the beginning of the command line.
+ */
+ for (; (*CommandLine != L'\0') && (*CommandLine != L' ');
+ CommandLine ++);
+ for (; *CommandLine == L' '; CommandLine ++)
+ {
+ *CommandLine = L'\0';
+ }
+ /*
+ * Create a native process (suspended).
+ */
+ ProcessInfo.Size = sizeof ProcessInfo;
+ Request->SmHeader.Status =
+ SmCreateUserProcess(ImagePath,
+ CommandLine,
+ FALSE, /* wait */
+ NULL, /* timeout */
+ & ProcessInfo);
+ if (NT_SUCCESS(Request->SmHeader.Status))
+ {
+ Status = SmCreateClient (& ProcessInfo, Name);
+ if (NT_SUCCESS(Status))
+ {
+ Status = NtResumeThread (ProcessInfo.ThreadHandle, NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ //Status = SmDestroyClient TODO
+ }
+ } else {
+ DPRINT1("SM: %s: SmCreateClient failed (Status=0x%08lx)\n",
+ __FUNCTION__, Status);
+ }
+ }
+ }
+ else
+ {
+ /*
+ * OK, the definition is empty, but check
+ * if it is the name of an embedded subsystem.
+ */
+ if(0 == _wcsicmp(L"DEBUG", Name))
+ {
+ /*
+ * Initialize the embedded DBGSS.
+ */
+ Request->SmHeader.Status = SmInitializeDbgSs();
+ }
+ else
+ {
+ /*
+ * Badly defined subsystem. Check the registry!
+ */
+ Request->SmHeader.Status = STATUS_NOT_FOUND;
+ }
+ }
+ } else {
+ /* It couldn't lookup the Name! */
+ Request->SmHeader.Status = Status;
+ }
+ }
+ return Status;
+}
+
+/* EOF */
-/* $Id$\r
- *\r
- * smapiquery.c - SM_API_QUERY_INFORMATION\r
- *\r
- * Reactos Session Manager\r
- *\r
- * --------------------------------------------------------------------\r
- *\r
- * This software is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License as\r
- * published by the Free Software Foundation; either version 2 of the\r
- * License, or (at your option) any later version.\r
- *\r
- * This software is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
- * General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this software; see the file COPYING.LIB. If not, write\r
- * to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge,\r
- * MA 02139, USA. \r
- *\r
- * --------------------------------------------------------------------\r
- */\r
-#include "smss.h"\r
-\r
-#define NDEBUG\r
-#include <debug.h>\r
-\r
-\r
-/**********************************************************************\r
- * SmQryInfo/1 API\r
- */\r
-SMAPI(SmQryInfo)\r
-{\r
- NTSTATUS Status = STATUS_SUCCESS;\r
-\r
- DPRINT("SM: %s called\n", __FUNCTION__);\r
-\r
- switch (Request->Request.QryInfo.SmInformationClass)\r
- {\r
- case SmBasicInformation:\r
- if(Request->Request.QryInfo.DataLength != sizeof (SM_BASIC_INFORMATION))\r
- {\r
- Request->Reply.QryInfo.DataLength = sizeof (SM_BASIC_INFORMATION);\r
- Request->SmHeader.Status = STATUS_INFO_LENGTH_MISMATCH;\r
- }else{\r
- Request->SmHeader.Status =\r
- SmGetClientBasicInformation (& Request->Reply.QryInfo.BasicInformation);\r
- }\r
- break;\r
- case SmSubSystemInformation:\r
- if(Request->Request.QryInfo.DataLength != sizeof (SM_SUBSYSTEM_INFORMATION))\r
- {\r
- Request->Reply.QryInfo.DataLength = sizeof (SM_SUBSYSTEM_INFORMATION);\r
- Request->SmHeader.Status = STATUS_INFO_LENGTH_MISMATCH;\r
- }else{\r
- Request->SmHeader.Status =\r
- SmGetSubSystemInformation (& Request->Reply.QryInfo.SubSystemInformation);\r
- }\r
- break;\r
- default:\r
- Request->SmHeader.Status = STATUS_NOT_IMPLEMENTED;\r
- break;\r
- }\r
- return Status;\r
-}\r
-\r
-\r
-/* EOF */\r
+/* $Id$
+ *
+ * smapiquery.c - SM_API_QUERY_INFORMATION
+ *
+ * Reactos Session Manager
+ *
+ * --------------------------------------------------------------------
+ *
+ * This software 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 software 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 software; see the file COPYING.LIB. If not, write
+ * to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
+ * MA 02139, USA.
+ *
+ * --------------------------------------------------------------------
+ */
+#include "smss.h"
+
+#define NDEBUG
+#include <debug.h>
+
+
+/**********************************************************************
+ * SmQryInfo/1 API
+ */
+SMAPI(SmQryInfo)
+{
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ DPRINT("SM: %s called\n", __FUNCTION__);
+
+ switch (Request->Request.QryInfo.SmInformationClass)
+ {
+ case SmBasicInformation:
+ if(Request->Request.QryInfo.DataLength != sizeof (SM_BASIC_INFORMATION))
+ {
+ Request->Reply.QryInfo.DataLength = sizeof (SM_BASIC_INFORMATION);
+ Request->SmHeader.Status = STATUS_INFO_LENGTH_MISMATCH;
+ }else{
+ Request->SmHeader.Status =
+ SmGetClientBasicInformation (& Request->Reply.QryInfo.BasicInformation);
+ }
+ break;
+ case SmSubSystemInformation:
+ if(Request->Request.QryInfo.DataLength != sizeof (SM_SUBSYSTEM_INFORMATION))
+ {
+ Request->Reply.QryInfo.DataLength = sizeof (SM_SUBSYSTEM_INFORMATION);
+ Request->SmHeader.Status = STATUS_INFO_LENGTH_MISMATCH;
+ }else{
+ Request->SmHeader.Status =
+ SmGetSubSystemInformation (& Request->Reply.QryInfo.SubSystemInformation);
+ }
+ break;
+ default:
+ Request->SmHeader.Status = STATUS_NOT_IMPLEMENTED;
+ break;
+ }
+ return Status;
+}
+
+
+/* EOF */