2005-01-06 13:58:04 +00:00
|
|
|
/* $Id$
|
1999-12-11 01:42:44 +00:00
|
|
|
*
|
2005-02-13 22:55:28 +00:00
|
|
|
* smapi.c - \SmApiPort LPC port message management
|
1999-12-01 15:18:54 +00:00
|
|
|
*
|
2005-02-13 22:55:28 +00:00
|
|
|
* Reactos Session Manager
|
1999-12-01 15:18:54 +00:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "smss.h"
|
2005-02-13 22:55:28 +00:00
|
|
|
#include <rosrtl/string.h>
|
1999-12-01 15:18:54 +00:00
|
|
|
|
2005-02-24 22:20:43 +00:00
|
|
|
#define NDEBUG
|
2005-02-13 22:55:28 +00:00
|
|
|
#include <debug.h>
|
1999-12-01 15:18:54 +00:00
|
|
|
|
2002-05-24 07:52:09 +00:00
|
|
|
/* GLOBAL VARIABLES *********************************************************/
|
|
|
|
|
|
|
|
static HANDLE SmApiPort = INVALID_HANDLE_VALUE;
|
|
|
|
|
2005-02-12 09:08:52 +00:00
|
|
|
/* SM API *******************************************************************/
|
2005-02-06 21:55:07 +00:00
|
|
|
|
|
|
|
SMAPI(SmInvalid)
|
|
|
|
{
|
2005-02-13 22:55:28 +00:00
|
|
|
DPRINT("SM: %s called\n",__FUNCTION__);
|
2005-04-10 19:08:23 +00:00
|
|
|
Request->SmHeader.Status = STATUS_NOT_IMPLEMENTED;
|
2005-02-06 21:55:07 +00:00
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* SM API Table */
|
|
|
|
typedef NTSTATUS (FASTCALL * SM_PORT_API)(PSM_PORT_MESSAGE);
|
|
|
|
|
|
|
|
SM_PORT_API SmApi [] =
|
|
|
|
{
|
|
|
|
SmInvalid, /* unused */
|
2005-02-19 22:58:18 +00:00
|
|
|
SmCompSes, /* smapicomp.c */
|
2005-02-06 21:55:07 +00:00
|
|
|
SmInvalid, /* obsolete */
|
|
|
|
SmInvalid, /* unknown */
|
2005-03-20 22:55:05 +00:00
|
|
|
SmExecPgm, /* smapiexec.c */
|
|
|
|
SmQryInfo /* smapyqry.c */
|
2005-02-06 21:55:07 +00:00
|
|
|
};
|
|
|
|
|
2005-05-08 04:07:56 +00:00
|
|
|
/* TODO: optimize this address computation (it should be done
|
2005-03-20 22:55:05 +00:00
|
|
|
* with a macro) */
|
|
|
|
PSM_CONNECT_DATA FASTCALL SmpGetConnectData (PSM_PORT_MESSAGE Request)
|
|
|
|
{
|
|
|
|
PLPC_MAX_MESSAGE LpcMaxMessage = (PLPC_MAX_MESSAGE) Request;
|
|
|
|
return (PSM_CONNECT_DATA) & LpcMaxMessage->Data[0];
|
|
|
|
}
|
|
|
|
|
2005-02-19 22:58:18 +00:00
|
|
|
#if !defined(__USE_NT_LPC__)
|
|
|
|
NTSTATUS STDCALL
|
|
|
|
SmpHandleConnectionRequest (PSM_PORT_MESSAGE Request);
|
|
|
|
#endif
|
|
|
|
|
2005-03-20 22:55:05 +00:00
|
|
|
/**********************************************************************
|
|
|
|
* SmpCallback/2
|
|
|
|
*
|
|
|
|
* The SM calls back a previously connected subsystem process to
|
|
|
|
* authorizes it to bootstrap (initialize). The SM connects to a
|
|
|
|
* named LPC port which name was sent in the connection data by the
|
|
|
|
* candidate subsystem server process.
|
|
|
|
*/
|
|
|
|
static NTSTATUS
|
|
|
|
SmpCallbackServer (PSM_PORT_MESSAGE Request,
|
|
|
|
PSM_CLIENT_DATA ClientData)
|
|
|
|
{
|
|
|
|
NTSTATUS Status = STATUS_SUCCESS;
|
|
|
|
PSM_CONNECT_DATA ConnectData = SmpGetConnectData (Request);
|
|
|
|
UNICODE_STRING CallbackPortName;
|
|
|
|
ULONG CallbackPortNameLength = SM_SB_NAME_MAX_LENGTH; /* TODO: compute length */
|
2005-04-10 19:08:23 +00:00
|
|
|
SB_CONNECT_DATA SbConnectData;
|
|
|
|
ULONG SbConnectDataLength = sizeof SbConnectData;
|
2005-05-08 04:07:56 +00:00
|
|
|
|
2005-03-20 22:55:05 +00:00
|
|
|
DPRINT("SM: %s called\n", __FUNCTION__);
|
|
|
|
|
2005-04-10 19:08:23 +00:00
|
|
|
if(IMAGE_SUBSYSTEM_NATIVE == ConnectData->SubSystemId)
|
2005-03-20 22:55:05 +00:00
|
|
|
{
|
|
|
|
DPRINT("SM: %s: we do not need calling back SM!\n",
|
|
|
|
__FUNCTION__);
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
RtlCopyMemory (ClientData->SbApiPortName,
|
|
|
|
ConnectData->SbName,
|
|
|
|
CallbackPortNameLength);
|
|
|
|
RtlInitUnicodeString (& CallbackPortName,
|
|
|
|
ClientData->SbApiPortName);
|
2005-04-10 19:08:23 +00:00
|
|
|
|
|
|
|
SbConnectData.SmApiMax = (sizeof SmApi / sizeof SmApi[0]);
|
2005-03-20 22:55:05 +00:00
|
|
|
Status = NtConnectPort (& ClientData->SbApiPort,
|
|
|
|
& CallbackPortName,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
2005-04-10 19:08:23 +00:00
|
|
|
& SbConnectData,
|
|
|
|
& SbConnectDataLength);
|
2005-03-20 22:55:05 +00:00
|
|
|
return Status;
|
|
|
|
}
|
2005-02-19 22:58:18 +00:00
|
|
|
|
|
|
|
/**********************************************************************
|
|
|
|
* NAME
|
|
|
|
* SmpApiConnectedThread/1
|
|
|
|
*
|
|
|
|
* DESCRIPTION
|
|
|
|
* Entry point for the listener thread of LPC port "\SmApiPort".
|
|
|
|
*/
|
|
|
|
VOID STDCALL
|
2005-03-13 17:01:59 +00:00
|
|
|
SmpApiConnectedThread(PVOID pConnectedPort)
|
2005-02-19 22:58:18 +00:00
|
|
|
{
|
|
|
|
NTSTATUS Status = STATUS_SUCCESS;
|
|
|
|
PVOID Unknown = NULL;
|
|
|
|
PLPC_MESSAGE Reply = NULL;
|
|
|
|
SM_PORT_MESSAGE Request = {{0}};
|
2005-03-13 17:01:59 +00:00
|
|
|
HANDLE ConnectedPort = * (PHANDLE) pConnectedPort;
|
2005-02-19 22:58:18 +00:00
|
|
|
|
2005-03-20 22:55:05 +00:00
|
|
|
DPRINT("SM: %s called\n", __FUNCTION__);
|
2005-02-19 22:58:18 +00:00
|
|
|
|
|
|
|
while (TRUE)
|
|
|
|
{
|
|
|
|
DPRINT("SM: %s: waiting for message\n",__FUNCTION__);
|
|
|
|
|
2005-03-13 17:01:59 +00:00
|
|
|
Status = NtReplyWaitReceivePort(ConnectedPort,
|
2005-02-19 22:58:18 +00:00
|
|
|
(PULONG) & Unknown,
|
|
|
|
Reply,
|
|
|
|
(PLPC_MESSAGE) & Request);
|
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
DPRINT("SM: %s: message received (type=%d)\n",
|
|
|
|
__FUNCTION__,
|
|
|
|
PORT_MESSAGE_TYPE(Request));
|
|
|
|
|
|
|
|
switch (Request.Header.MessageType)
|
|
|
|
{
|
|
|
|
case LPC_CONNECTION_REQUEST:
|
|
|
|
SmpHandleConnectionRequest (&Request);
|
|
|
|
Reply = NULL;
|
|
|
|
break;
|
|
|
|
case LPC_DEBUG_EVENT:
|
|
|
|
// DbgSsHandleKmApiMsg (&Request, 0);
|
|
|
|
Reply = NULL;
|
|
|
|
break;
|
|
|
|
case LPC_PORT_CLOSED:
|
|
|
|
Reply = NULL;
|
|
|
|
break;
|
|
|
|
default:
|
2005-04-10 19:08:23 +00:00
|
|
|
if ((Request.SmHeader.ApiIndex) &&
|
|
|
|
(Request.SmHeader.ApiIndex < (sizeof SmApi / sizeof SmApi[0])))
|
2005-02-19 22:58:18 +00:00
|
|
|
{
|
2005-04-10 19:08:23 +00:00
|
|
|
Status = SmApi[Request.SmHeader.ApiIndex](&Request);
|
2005-02-19 22:58:18 +00:00
|
|
|
Reply = (PLPC_MESSAGE) & Request;
|
|
|
|
} else {
|
2005-04-10 19:08:23 +00:00
|
|
|
Request.SmHeader.Status = STATUS_NOT_IMPLEMENTED;
|
2005-02-19 22:58:18 +00:00
|
|
|
Reply = (PLPC_MESSAGE) & Request;
|
|
|
|
}
|
|
|
|
}
|
2005-03-13 17:01:59 +00:00
|
|
|
} else {
|
|
|
|
/* LPC failed */
|
|
|
|
break;
|
2005-02-19 22:58:18 +00:00
|
|
|
}
|
|
|
|
}
|
2005-03-13 17:01:59 +00:00
|
|
|
NtClose (ConnectedPort);
|
|
|
|
NtTerminateThread (NtCurrentThread(), Status);
|
2005-02-19 22:58:18 +00:00
|
|
|
}
|
2002-05-24 07:52:09 +00:00
|
|
|
|
2005-02-06 21:55:07 +00:00
|
|
|
/**********************************************************************
|
|
|
|
* NAME
|
2005-02-19 22:58:18 +00:00
|
|
|
* SmpHandleConnectionRequest/1
|
|
|
|
*
|
|
|
|
* ARGUMENTS
|
|
|
|
* Request: LPC connection request message
|
2005-02-06 21:55:07 +00:00
|
|
|
*
|
|
|
|
* REMARKS
|
|
|
|
* Quoted in http://support.microsoft.com/kb/258060/EN-US/
|
|
|
|
*/
|
|
|
|
NTSTATUS STDCALL
|
2005-02-19 22:58:18 +00:00
|
|
|
SmpHandleConnectionRequest (PSM_PORT_MESSAGE Request)
|
2005-02-06 21:55:07 +00:00
|
|
|
{
|
2005-03-20 22:55:05 +00:00
|
|
|
PSM_CONNECT_DATA ConnectData = SmpGetConnectData (Request);
|
2005-02-13 22:55:28 +00:00
|
|
|
NTSTATUS Status = STATUS_SUCCESS;
|
2005-03-13 17:01:59 +00:00
|
|
|
BOOL Accept = FALSE;
|
2005-02-13 22:55:28 +00:00
|
|
|
PSM_CLIENT_DATA ClientData = NULL;
|
2005-03-13 17:01:59 +00:00
|
|
|
HANDLE hClientDataApiPort = (HANDLE) 0;
|
|
|
|
PHANDLE ClientDataApiPort = & hClientDataApiPort;
|
|
|
|
HANDLE hClientDataApiPortThread = (HANDLE) 0;
|
|
|
|
PHANDLE ClientDataApiPortThread = & hClientDataApiPortThread;
|
2005-02-13 22:55:28 +00:00
|
|
|
PVOID Context = NULL;
|
2005-05-08 04:07:56 +00:00
|
|
|
|
2005-03-20 22:55:05 +00:00
|
|
|
DPRINT("SM: %s called:\n SubSystemID=%d\n SbName=\"%S\"\n",
|
2005-04-10 19:08:23 +00:00
|
|
|
__FUNCTION__, ConnectData->SubSystemId, ConnectData->SbName);
|
2005-02-13 22:55:28 +00:00
|
|
|
|
2005-03-13 17:01:59 +00:00
|
|
|
if(sizeof (SM_CONNECT_DATA) == Request->Header.DataSize)
|
2005-02-13 22:55:28 +00:00
|
|
|
{
|
2005-04-10 19:08:23 +00:00
|
|
|
if(IMAGE_SUBSYSTEM_UNKNOWN == ConnectData->SubSystemId)
|
2005-02-19 22:58:18 +00:00
|
|
|
{
|
2005-03-13 17:01:59 +00:00
|
|
|
/*
|
2005-03-20 22:55:05 +00:00
|
|
|
* This is not a call to register an image set,
|
|
|
|
* but a simple connection request from a process
|
2005-03-13 17:01:59 +00:00
|
|
|
* that will use the SM API.
|
|
|
|
*/
|
2005-03-20 22:55:05 +00:00
|
|
|
DPRINT("SM: %s: simple request\n", __FUNCTION__);
|
2005-03-13 17:01:59 +00:00
|
|
|
ClientDataApiPort = & hClientDataApiPort;
|
|
|
|
ClientDataApiPortThread = & hClientDataApiPortThread;
|
|
|
|
Accept = TRUE;
|
|
|
|
} else {
|
2005-03-20 22:55:05 +00:00
|
|
|
DPRINT("SM: %s: request to register an image set\n", __FUNCTION__);
|
2005-03-13 17:01:59 +00:00
|
|
|
/*
|
2005-03-20 22:55:05 +00:00
|
|
|
* Reject GUIs classes: only odd subsystem IDs are
|
|
|
|
* allowed to register here (tty mode images).
|
2005-03-13 17:01:59 +00:00
|
|
|
*/
|
2005-04-10 19:08:23 +00:00
|
|
|
if(1 == (ConnectData->SubSystemId % 2))
|
2005-03-13 17:01:59 +00:00
|
|
|
{
|
2005-04-10 19:08:23 +00:00
|
|
|
DPRINT("SM: %s: id = %d\n", __FUNCTION__, ConnectData->SubSystemId);
|
2005-03-13 17:01:59 +00:00
|
|
|
/*
|
2005-03-20 22:55:05 +00:00
|
|
|
* SmCreateClient/2 is called here explicitly to *fail*.
|
|
|
|
* If it succeeds, there is something wrong in the
|
|
|
|
* connection request. An environment subsystem *never*
|
|
|
|
* registers twice. (security issue)
|
2005-03-13 17:01:59 +00:00
|
|
|
*/
|
2005-03-20 22:55:05 +00:00
|
|
|
Status = SmCreateClient (Request, & ClientData);
|
|
|
|
if(STATUS_SUCCESS == Status)
|
|
|
|
{
|
|
|
|
DPRINT("SM: %s: ClientData = 0x%08lx\n",
|
|
|
|
__FUNCTION__, ClientData);
|
|
|
|
/*
|
|
|
|
* OK: the client is an environment subsystem
|
|
|
|
* willing to manage a free image type.
|
|
|
|
*/
|
|
|
|
ClientDataApiPort = & ClientData->ApiPort;
|
|
|
|
ClientDataApiPortThread = & ClientData->ApiPortThread;
|
|
|
|
/*
|
|
|
|
* Call back the candidate environment subsystem
|
2005-05-08 04:07:56 +00:00
|
|
|
* server (use the port name sent in in the
|
2005-03-20 22:55:05 +00:00
|
|
|
* connection request message).
|
|
|
|
*/
|
|
|
|
Status = SmpCallbackServer (Request, ClientData);
|
|
|
|
if(NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
DPRINT("SM: %s: SmpCallbackServer OK\n",
|
|
|
|
__FUNCTION__);
|
|
|
|
Accept = TRUE;
|
|
|
|
} else {
|
|
|
|
DPRINT("SM: %s: SmpCallbackServer failed (Status=%08lx)\n",
|
|
|
|
__FUNCTION__, Status);
|
2005-04-10 19:08:23 +00:00
|
|
|
Status = SmDestroyClient (ConnectData->SubSystemId);
|
2005-03-20 22:55:05 +00:00
|
|
|
}
|
|
|
|
}
|
2005-03-13 17:01:59 +00:00
|
|
|
}
|
2005-02-19 22:58:18 +00:00
|
|
|
}
|
|
|
|
}
|
2005-03-20 22:55:05 +00:00
|
|
|
DPRINT("SM: %s: before NtAcceptConnectPort\n", __FUNCTION__);
|
2005-03-13 17:01:59 +00:00
|
|
|
#if defined(__USE_NT_LPC__)
|
|
|
|
Status = NtAcceptConnectPort (ClientDataApiPort,
|
|
|
|
Context,
|
|
|
|
(PLPC_MESSAGE) Request,
|
|
|
|
Accept,
|
|
|
|
NULL,
|
|
|
|
NULL);
|
2005-02-19 22:58:18 +00:00
|
|
|
#else /* ReactOS LPC */
|
2005-03-13 17:01:59 +00:00
|
|
|
Status = NtAcceptConnectPort (ClientDataApiPort,
|
|
|
|
SmApiPort, // ROS LPC requires the listen port here
|
|
|
|
Context,
|
|
|
|
Accept,
|
|
|
|
NULL,
|
|
|
|
NULL);
|
|
|
|
#endif
|
|
|
|
if(Accept)
|
2005-02-19 22:58:18 +00:00
|
|
|
{
|
2005-03-13 17:01:59 +00:00
|
|
|
if(!NT_SUCCESS(Status))
|
2005-02-13 22:55:28 +00:00
|
|
|
{
|
2005-02-19 22:58:18 +00:00
|
|
|
DPRINT1("SM: %s: NtAcceptConnectPort() failed (Status=0x%08lx)\n",
|
2005-03-13 17:01:59 +00:00
|
|
|
__FUNCTION__, Status);
|
2005-02-19 22:58:18 +00:00
|
|
|
return Status;
|
|
|
|
} else {
|
2005-03-13 17:01:59 +00:00
|
|
|
DPRINT("SM: %s: completing conn req\n", __FUNCTION__);
|
|
|
|
Status = NtCompleteConnectPort (*ClientDataApiPort);
|
2005-02-19 22:58:18 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
DPRINT1("SM: %s: NtCompleteConnectPort() failed (Status=0x%08lx)\n",
|
|
|
|
__FUNCTION__, Status);
|
|
|
|
return Status;
|
|
|
|
}
|
2005-03-13 17:01:59 +00:00
|
|
|
#if !defined(__USE_NT_LPC__) /* ReactOS LPC */
|
|
|
|
DPRINT("SM: %s: server side comm port thread (ROS LPC)\n", __FUNCTION__);
|
2005-02-19 22:58:18 +00:00
|
|
|
Status = RtlCreateUserThread(NtCurrentProcess(),
|
|
|
|
NULL,
|
|
|
|
FALSE,
|
|
|
|
0,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
(PTHREAD_START_ROUTINE) SmpApiConnectedThread,
|
2005-03-13 17:01:59 +00:00
|
|
|
ClientDataApiPort,
|
|
|
|
ClientDataApiPortThread,
|
2005-02-19 22:58:18 +00:00
|
|
|
NULL);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
DPRINT1("SM: %s: Unable to create server thread (Status=0x%08lx)\n",
|
|
|
|
__FUNCTION__, Status);
|
|
|
|
return Status;
|
|
|
|
}
|
2005-03-13 17:01:59 +00:00
|
|
|
#endif
|
2005-02-13 22:55:28 +00:00
|
|
|
}
|
2005-03-13 17:01:59 +00:00
|
|
|
Status = STATUS_SUCCESS;
|
2005-02-13 22:55:28 +00:00
|
|
|
}
|
2005-03-13 17:01:59 +00:00
|
|
|
DPRINT("SM: %s done\n", __FUNCTION__);
|
2005-02-13 22:55:28 +00:00
|
|
|
return Status;
|
2005-02-06 21:55:07 +00:00
|
|
|
}
|
1999-12-01 15:18:54 +00:00
|
|
|
|
2005-02-06 21:55:07 +00:00
|
|
|
/**********************************************************************
|
|
|
|
* NAME
|
|
|
|
* SmpApiThread/1
|
|
|
|
*
|
2005-02-19 22:58:18 +00:00
|
|
|
* DECRIPTION
|
|
|
|
* Due to differences in LPC implementation between NT and ROS,
|
|
|
|
* we need a thread to listen for connection request that
|
|
|
|
* creates a new thread for each connected port. This is not
|
|
|
|
* necessary in NT LPC, because server side connected ports are
|
2005-05-08 04:07:56 +00:00
|
|
|
* never used to receive requests.
|
2005-02-06 21:55:07 +00:00
|
|
|
*/
|
1999-12-01 15:18:54 +00:00
|
|
|
VOID STDCALL
|
2005-02-19 22:58:18 +00:00
|
|
|
SmpApiThread (HANDLE ListeningPort)
|
1999-12-01 15:18:54 +00:00
|
|
|
{
|
2005-02-06 21:55:07 +00:00
|
|
|
NTSTATUS Status = STATUS_SUCCESS;
|
2005-02-19 22:58:18 +00:00
|
|
|
LPC_MAX_MESSAGE Request = {{0}};
|
2005-03-20 22:55:05 +00:00
|
|
|
|
|
|
|
DPRINT("SM: %s called\n", __FUNCTION__);
|
2005-05-08 04:07:56 +00:00
|
|
|
|
2005-02-06 21:55:07 +00:00
|
|
|
while (TRUE)
|
2002-05-24 07:52:09 +00:00
|
|
|
{
|
2005-02-19 22:58:18 +00:00
|
|
|
Status = NtListenPort (ListeningPort, & Request.Header);
|
|
|
|
if (!NT_SUCCESS(Status))
|
2005-02-06 21:55:07 +00:00
|
|
|
{
|
2005-02-19 22:58:18 +00:00
|
|
|
DPRINT1("SM: %s: NtListenPort() failed! (Status==x%08lx)\n", __FUNCTION__, Status);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
Status = SmpHandleConnectionRequest ((PSM_PORT_MESSAGE) & Request);
|
|
|
|
if(!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
DPRINT1("SM: %s: SmpHandleConnectionRequest failed (Status=0x%08lx)\n",
|
|
|
|
__FUNCTION__, Status);
|
|
|
|
break;
|
2005-02-06 21:55:07 +00:00
|
|
|
}
|
2002-05-24 07:52:09 +00:00
|
|
|
}
|
2005-02-19 22:58:18 +00:00
|
|
|
/* Cleanup */
|
|
|
|
NtClose(ListeningPort);
|
|
|
|
/* DIE */
|
|
|
|
NtTerminateThread(NtCurrentThread(), Status);
|
2002-05-24 07:52:09 +00:00
|
|
|
}
|
|
|
|
|
2005-02-12 09:08:52 +00:00
|
|
|
|
|
|
|
/* LPC PORT INITIALIZATION **************************************************/
|
|
|
|
|
|
|
|
|
2005-02-06 21:55:07 +00:00
|
|
|
/**********************************************************************
|
|
|
|
* NAME
|
2005-02-12 09:08:52 +00:00
|
|
|
* SmCreateApiPort/0
|
2005-02-06 21:55:07 +00:00
|
|
|
*
|
|
|
|
* DECRIPTION
|
|
|
|
*/
|
2002-05-24 07:52:09 +00:00
|
|
|
NTSTATUS
|
2005-02-12 09:08:52 +00:00
|
|
|
SmCreateApiPort(VOID)
|
2002-05-24 07:52:09 +00:00
|
|
|
{
|
2005-02-19 22:58:18 +00:00
|
|
|
OBJECT_ATTRIBUTES ObjectAttributes = {0};
|
|
|
|
UNICODE_STRING UnicodeString = {0};
|
|
|
|
NTSTATUS Status = STATUS_SUCCESS;
|
2002-05-24 07:52:09 +00:00
|
|
|
|
2003-11-17 02:12:52 +00:00
|
|
|
RtlRosInitUnicodeStringFromLiteral(&UnicodeString,
|
2002-05-24 07:52:09 +00:00
|
|
|
L"\\SmApiPort");
|
|
|
|
InitializeObjectAttributes(&ObjectAttributes,
|
|
|
|
&UnicodeString,
|
|
|
|
PORT_ALL_ACCESS,
|
|
|
|
NULL,
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
Status = NtCreatePort(&SmApiPort,
|
|
|
|
&ObjectAttributes,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
return(Status);
|
1999-12-01 15:18:54 +00:00
|
|
|
}
|
2005-02-19 22:58:18 +00:00
|
|
|
/*
|
|
|
|
* Create one thread for the named LPC
|
|
|
|
* port \SmApiPort
|
|
|
|
*/
|
2002-05-24 07:52:09 +00:00
|
|
|
RtlCreateUserThread(NtCurrentProcess(),
|
|
|
|
NULL,
|
|
|
|
FALSE,
|
|
|
|
0,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
2005-02-06 21:55:07 +00:00
|
|
|
(PTHREAD_START_ROUTINE)SmpApiThread,
|
2002-05-24 07:52:09 +00:00
|
|
|
(PVOID)SmApiPort,
|
|
|
|
NULL,
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
return(Status);
|
1999-12-01 15:18:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* EOF */
|