* 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
{\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
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
\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