SM: init system reading the registry
[reactos.git] / reactos / subsys / smss / client.c
index 533ceea..33dc6bf 100644 (file)
@@ -99,14 +99,18 @@ SmCompleteClientInitialization (HANDLE hProcess)
  * SIDE EFFECTS\r
  *     SmpClientDirectory.Lock is released only on success.\r
  */\r
-static PSM_CLIENT_DATA STDCALL\r
-SmpLookupClient (USHORT SubsystemId)\r
+static PSM_CLIENT_DATA FASTCALL\r
+SmpLookupClientUnsafe (USHORT           SubsystemId,\r
+                      PSM_CLIENT_DATA  * Parent)\r
 {\r
        PSM_CLIENT_DATA Client = NULL;\r
 \r
-       DPRINT("SM: %s called\n", __FUNCTION__);\r
-\r
-       RtlEnterCriticalSection (& SmpClientDirectory.Lock);\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
@@ -114,12 +118,31 @@ SmpLookupClient (USHORT SubsystemId)
                {\r
                        if (SubsystemId == Client->SubsystemId)\r
                        {\r
-                               RtlLeaveCriticalSection (& SmpClientDirectory.Lock);\r
-                               return Client;\r
+                               break;\r
+                       }\r
+                       if(NULL != Parent)\r
+                       {\r
+                               *Parent = Client;\r
                        }\r
                        Client = Client->Next;\r
                }\r
        }\r
+       return Client;\r
+}\r
+\r
+static PSM_CLIENT_DATA STDCALL\r
+SmpLookupClient (USHORT SubsystemId)\r
+{\r
+       PSM_CLIENT_DATA Client = NULL;\r
+\r
+       DPRINT("SM: %s called\n", __FUNCTION__);\r
+\r
+       RtlEnterCriticalSection (& SmpClientDirectory.Lock);\r
+       Client = SmpLookupClientUnsafe (SubsystemId, NULL);\r
+       if(NULL != Client)\r
+       {\r
+               RtlLeaveCriticalSection (& SmpClientDirectory.Lock);\r
+       }\r
        /*\r
         * Note that we do *not* release SmpClientDirectory.Lock here\r
         * because SmpLookupClient is called to FAIL when SubsystemId\r
@@ -135,7 +158,7 @@ NTSTATUS STDCALL
 SmCreateClient(PSM_PORT_MESSAGE Request, PSM_CLIENT_DATA * ClientData)\r
 {\r
        PSM_CLIENT_DATA pClient = NULL;\r
-       PSM_CONNECT_DATA ConnectData = (PSM_CONNECT_DATA) ((PBYTE) Request) + sizeof (LPC_REQUEST);\r
+       PSM_CONNECT_DATA ConnectData = SmpGetConnectData (Request);\r
        ULONG SbApiPortNameSize = SM_CONNECT_DATA_SIZE(*Request);\r
 \r
        DPRINT("SM: %s called\n", __FUNCTION__);\r
@@ -206,16 +229,51 @@ SmCreateClient(PSM_PORT_MESSAGE Request, PSM_CLIENT_DATA * ClientData)
 \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
-       /* TODO */\r
+       Client = SmpLookupClientUnsafe (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
+               RtlFreeHeap (SmpHeap, 0, Client);\r
+               -- SmpClientDirectory.Count;\r
+       }\r
        RtlLeaveCriticalSection (& SmpClientDirectory.Lock);\r
-       return STATUS_SUCCESS;\r
+       return Status;\r
 }\r
 \r
 /* EOF */\r