diff --git a/reactos/include/reactos/subsys/csr/server.h b/reactos/include/reactos/subsys/csr/server.h
index ca63a6ddb6e..db3a506e657 100644
--- a/reactos/include/reactos/subsys/csr/server.h
+++ b/reactos/include/reactos/subsys/csr/server.h
@@ -18,7 +18,7 @@
typedef struct _CSR_NT_SESSION
{
ULONG ReferenceCount;
- LIST_ENTRY SessionList;
+ LIST_ENTRY SessionLink;
ULONG SessionId;
} CSR_NT_SESSION, *PCSR_NT_SESSION;
@@ -71,12 +71,21 @@ typedef enum _CSR_PROCESS_FLAGS
{
CsrProcessTerminating = 0x1,
CsrProcessSkipShutdown = 0x2,
+ CsrProcessNormalPriority = 0x10,
+ CsrProcessIdlePriority = 0x20,
+ CsrProcessHighPriority = 0x40,
+ CsrProcessRealtimePriority = 0x80,
CsrProcessCreateNewGroup = 0x100,
CsrProcessTerminated = 0x200,
CsrProcessLastThreadTerminated = 0x400,
CsrProcessIsConsoleApp = 0x800
} CSR_PROCESS_FLAGS, *PCSR_PROCESS_FLAGS;
+#define CsrProcessPriorityFlags (CsrProcessNormalPriority | \
+ CsrProcessIdlePriority | \
+ CsrProcessHighPriority | \
+ CsrProcessRealtimePriority)
+
typedef enum _CSR_THREAD_FLAGS
{
CsrThreadAltertable = 0x1,
@@ -252,75 +261,6 @@ typedef struct _CSR_WAIT_BLOCK
CSR_API_MESSAGE WaitApiMessage;
} CSR_WAIT_BLOCK, *PCSR_WAIT_BLOCK;
-/* FIXME: Put into new SM headers */
-typedef struct _SB_CREATE_SESSION
-{
- ULONG SessionId;
- RTL_USER_PROCESS_INFORMATION ProcessInfo;
-} SB_CREATE_SESSION, *PSB_CREATE_SESSION;
-
-typedef struct _SB_TERMINATE_SESSION
-{
- ULONG SessionId;
-} SB_TERMINATE_SESSION, *PSB_TERMINATE_SESSION;
-
-typedef struct _SB_FOREIGN_SESSION_COMPLETE
-{
- ULONG SessionId;
-} SB_FOREIGN_SESSION_COMPLETE, *PSB_FOREIGN_SESSION_COMPLETE;
-
-typedef struct _SB_CREATE_PROCESS
-{
- ULONG SessionId;
-} SB_CREATE_PROCESS, *PSB_CREATE_PROCESS;
-
-typedef struct _SB_CONNECTION_INFO
-{
- ULONG SubsystemId;
-} SB_CONNECTION_INFO, *PSB_CONNECTION_INFO;
-
-typedef struct _SB_API_MESSAGE
-{
- PORT_MESSAGE Header;
- union
- {
- SB_CONNECTION_INFO ConnectionInfo;
- struct
- {
- ULONG Opcode;
- NTSTATUS Status;
- union
- {
- SB_CREATE_SESSION SbCreateSession;
- SB_TERMINATE_SESSION SbTerminateSession;
- SB_FOREIGN_SESSION_COMPLETE SbForeignSessionComplete;
- SB_CREATE_PROCESS SbCreateProcess;
- };
- };
- };
-} SB_API_MESSAGE, *PSB_API_MESSAGE;
-
-typedef
-BOOLEAN
-(NTAPI *PSB_API_ROUTINE)(IN PSB_API_MESSAGE ApiMessage);
-
-NTSTATUS
-NTAPI
-SmSessionComplete(
- IN HANDLE hApiPort,
- IN ULONG SessionId,
- IN NTSTATUS Status
-);
-
-NTSTATUS
-NTAPI
-SmConnectToSm(
- IN PUNICODE_STRING SbApiPortName OPTIONAL,
- IN HANDLE hSbApiPort OPTIONAL,
- IN ULONG SubsystemType OPTIONAL,
- OUT PHANDLE hSmApiPort
-);
-
/* PROTOTYPES ****************************************************************/
NTSTATUS
diff --git a/reactos/subsystems/CMakeLists.txt b/reactos/subsystems/CMakeLists.txt
index 86b3cd1727b..9ae37a8221c 100644
--- a/reactos/subsystems/CMakeLists.txt
+++ b/reactos/subsystems/CMakeLists.txt
@@ -1,4 +1,5 @@
if(ARCH MATCHES i386)
add_subdirectory(ntvdm)
endif()
+add_subdirectory(csr)
add_subdirectory(win32)
diff --git a/reactos/subsystems/csr/CMakeLists.txt b/reactos/subsystems/csr/CMakeLists.txt
new file mode 100644
index 00000000000..29ccac1a8da
--- /dev/null
+++ b/reactos/subsystems/csr/CMakeLists.txt
@@ -0,0 +1,16 @@
+
+include_directories(
+ include
+ ${REACTOS_SOURCE_DIR}/include/reactos/subsys
+ ${REACTOS_SOURCE_DIR}/include/reactos/drivers)
+
+add_executable(csrss2 main.c csr.rc)
+
+set_module_type(csrss2 nativecui)
+target_link_libraries(csrss2 nt)
+add_importlibs(csrss2 ntdll csrsrv2)
+add_dependencies(csrss2 psdk bugcodes)
+add_cd_file(TARGET csrss2 DESTINATION reactos/system32 FOR all)
+
+add_subdirectory(csrsrv)
+
diff --git a/reactos/subsystems/csr/csr.rbuild b/reactos/subsystems/csr/csr.rbuild
deleted file mode 100644
index aec8f30fbab..00000000000
--- a/reactos/subsystems/csr/csr.rbuild
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
-
-
- .
- include/reactos/subsys
- nt
- ntdll
- csrsrv
- main.c
-
-
-
-
-
diff --git a/reactos/subsystems/csr/csrsrv/CMakeLists.txt b/reactos/subsystems/csr/csrsrv/CMakeLists.txt
new file mode 100644
index 00000000000..24ffd89a58e
--- /dev/null
+++ b/reactos/subsystems/csr/csrsrv/CMakeLists.txt
@@ -0,0 +1,30 @@
+
+include_directories(${REACTOS_SOURCE_DIR}/subsystems/win32/csrss/include)
+include_directories(${REACTOS_SOURCE_DIR}/include/reactos/subsys)
+
+spec2def(csrsrv2.dll csrsrv2.spec)
+
+list(APPEND SOURCE
+ api.c
+ init.c
+ process.c
+ server.c
+ session.c
+ thread.c
+ wait.c
+ csrsrv.rc
+ ${CMAKE_CURRENT_BINARY_DIR}/csrsrv2.def)
+
+add_library(csrsrv2 SHARED ${SOURCE})
+
+target_link_libraries(csrsrv2 ${PSEH_LIB} smlib)
+
+set_module_type(csrsrv2 nativedll)
+
+add_importlibs(csrsrv2 ntdll)
+
+add_pch(csrsrv2 srv.h)
+
+add_dependencies(csrsrv2 psdk bugcodes)
+add_cd_file(TARGET csrsrv2 DESTINATION reactos/system32 FOR all)
+add_importlib_target(csrsrv2.spec)
diff --git a/reactos/subsystems/csr/csrsrv/api.c b/reactos/subsystems/csr/csrsrv/api.c
index 123e6ff0486..75c19d47afd 100644
--- a/reactos/subsystems/csr/csrsrv/api.c
+++ b/reactos/subsystems/csr/csrsrv/api.c
@@ -21,15 +21,15 @@ UNICODE_STRING CsrApiPortName;
HANDLE CsrSbApiPort;
HANDLE CsrApiPort;
PCSR_THREAD CsrSbApiRequestThreadPtr;
-ULONG CsrpStaticThreadCount;
-ULONG CsrpDynamicThreadTotal;
+volatile LONG CsrpStaticThreadCount;
+volatile LONG CsrpDynamicThreadTotal;
/* PRIVATE FUNCTIONS *********************************************************/
/*++
- * @name CsrCheckRequestThreads
+ * @name CsrpCheckRequestThreads
*
- * The CsrCheckRequestThreads routine checks if there are no more threads
+ * The CsrpCheckRequestThreads routine checks if there are no more threads
* to handle CSR API Requests, and creates a new thread if possible, to
* avoid starvation.
*
@@ -43,14 +43,14 @@ ULONG CsrpDynamicThreadTotal;
*--*/
NTSTATUS
NTAPI
-CsrCheckRequestThreads(VOID)
+CsrpCheckRequestThreads(VOID)
{
HANDLE hThread;
CLIENT_ID ClientId;
NTSTATUS Status;
/* Decrease the count, and see if we're out */
- if (!(_InterlockedDecrement((PLONG)&CsrpStaticThreadCount)))
+ if (!(_InterlockedDecrement(&CsrpStaticThreadCount)))
{
/* Check if we've still got space for a Dynamic Thread */
if (CsrpDynamicThreadTotal < CsrMaxApiRequestThreads)
@@ -67,11 +67,11 @@ CsrCheckRequestThreads(VOID)
&hThread,
&ClientId);
/* Check success */
- if(NT_SUCCESS(Status))
+ if (NT_SUCCESS(Status))
{
/* Increase the thread counts */
- CsrpStaticThreadCount++;
- CsrpDynamicThreadTotal++;
+ _InterlockedIncrement(&CsrpStaticThreadCount);
+ _InterlockedIncrement(&CsrpDynamicThreadTotal);
/* Add a new server thread */
if (CsrAddStaticServerThread(hThread,
@@ -84,8 +84,8 @@ CsrCheckRequestThreads(VOID)
else
{
/* Failed to create a new static thread */
- CsrpStaticThreadCount--;
- CsrpDynamicThreadTotal--;
+ _InterlockedDecrement(&CsrpStaticThreadCount);
+ _InterlockedDecrement(&CsrpDynamicThreadTotal);
/* Terminate it */
NtTerminateThread(hThread,0);
@@ -131,16 +131,23 @@ CsrSbApiPortInitialize(VOID)
/* Calculate how much space we'll need for the Port Name */
Size = CsrDirectoryName.Length + sizeof(SB_PORT_NAME) + sizeof(WCHAR);
- /* Allocate space for it, and create it */
+ /* Create the buffer for it */
CsrSbApiPortName.Buffer = RtlAllocateHeap(CsrHeap, 0, Size);
+ if (!CsrSbApiPortName.Buffer) return STATUS_NO_MEMORY;
+
+ /* Setup the rest of the empty string */
CsrSbApiPortName.Length = 0;
CsrSbApiPortName.MaximumLength = (USHORT)Size;
+
+ /* Now append the full port name */
RtlAppendUnicodeStringToString(&CsrSbApiPortName, &CsrDirectoryName);
RtlAppendUnicodeToString(&CsrSbApiPortName, UNICODE_PATH_SEP);
RtlAppendUnicodeToString(&CsrSbApiPortName, SB_PORT_NAME);
+ if (CsrDebug & 2) DPRINT1("CSRSS: Creating %wZ port and associated thread\n", &CsrSbApiPortName);
/* Create Security Descriptor for this Port */
- CsrCreateLocalSystemSD(&PortSd);
+ Status = CsrCreateLocalSystemSD(&PortSd);
+ if (!NT_SUCCESS(Status)) return Status;
/* Initialize the Attributes */
InitializeObjectAttributes(&ObjectAttributes,
@@ -153,36 +160,36 @@ CsrSbApiPortInitialize(VOID)
Status = NtCreatePort(&CsrSbApiPort,
&ObjectAttributes,
sizeof(SB_CONNECTION_INFO),
- sizeof(SB_API_MESSAGE),
- 32 * sizeof(SB_API_MESSAGE));
- if(!NT_SUCCESS(Status))
- {
+ sizeof(PSB_API_MSG),
+ 32 * sizeof(PSB_API_MSG));
+ if (PortSd) RtlFreeHeap(CsrHeap, 0, PortSd);
+ if (NT_SUCCESS(Status))
+ {
+ /* Create the Thread to handle the API Requests */
+ Status = RtlCreateUserThread(NtCurrentProcess(),
+ NULL,
+ TRUE,
+ 0,
+ 0,
+ 0,
+ (PVOID)CsrSbApiRequestThread,
+ NULL,
+ &hRequestThread,
+ &ClientId);
+ if (NT_SUCCESS(Status))
+ {
+ /* Add it as a Static Server Thread */
+ CsrSbApiRequestThreadPtr = CsrAddStaticServerThread(hRequestThread,
+ &ClientId,
+ 0);
+
+ /* Activate it */
+ Status = NtResumeThread(hRequestThread, NULL);
+ }
}
- /* Create the Thread to handle the API Requests */
- Status = RtlCreateUserThread(NtCurrentProcess(),
- NULL,
- TRUE,
- 0,
- 0,
- 0,
- (PVOID)CsrSbApiRequestThread,
- NULL,
- &hRequestThread,
- &ClientId);
- if(!NT_SUCCESS(Status))
- {
-
- }
-
- /* Add it as a Static Server Thread */
- CsrSbApiRequestThreadPtr = CsrAddStaticServerThread(hRequestThread,
- &ClientId,
- 0);
-
- /* Activate it */
- return NtResumeThread(hRequestThread, NULL);
+ return Status;
}
/*++
@@ -215,13 +222,22 @@ CsrApiPortInitialize(VOID)
/* Calculate how much space we'll need for the Port Name */
Size = CsrDirectoryName.Length + sizeof(CSR_PORT_NAME) + sizeof(WCHAR);
- /* Allocate space for it, and create it */
+ /* Create the buffer for it */
CsrApiPortName.Buffer = RtlAllocateHeap(CsrHeap, 0, Size);
+ if (!CsrApiPortName.Buffer) return STATUS_NO_MEMORY;
+
+ /* Setup the rest of the empty string */
CsrApiPortName.Length = 0;
CsrApiPortName.MaximumLength = (USHORT)Size;
RtlAppendUnicodeStringToString(&CsrApiPortName, &CsrDirectoryName);
RtlAppendUnicodeToString(&CsrApiPortName, UNICODE_PATH_SEP);
RtlAppendUnicodeToString(&CsrApiPortName, CSR_PORT_NAME);
+ if (CsrDebug & 1)
+ {
+ DPRINT1("CSRSS: Creating %wZ port and associated threads\n", &CsrApiPortName);
+ DPRINT1("CSRSS: sizeof( CONNECTINFO ) == %ld sizeof( API_MSG ) == %ld\n",
+ sizeof(CSR_CONNECTION_INFO), sizeof(CSR_API_MESSAGE));
+ }
/* FIXME: Create a Security Descriptor */
@@ -238,68 +254,63 @@ CsrApiPortInitialize(VOID)
sizeof(CSR_CONNECTION_INFO),
sizeof(CSR_API_MESSAGE),
16 * PAGE_SIZE);
- if(!NT_SUCCESS(Status))
+ if (NT_SUCCESS(Status))
{
-
- }
-
- /* Create the event the Port Thread will use */
- Status = NtCreateEvent(&hRequestEvent,
- EVENT_ALL_ACCESS,
- NULL,
- SynchronizationEvent,
- FALSE);
- if(!NT_SUCCESS(Status))
- {
-
- }
-
- /* Create the Request Thread */
- Status = RtlCreateUserThread(NtCurrentProcess(),
- NULL,
- TRUE,
- 0,
- 0,
- 0,
- (PVOID)CsrApiRequestThread,
- (PVOID)hRequestEvent,
- &hThread,
- &ClientId);
- if(!NT_SUCCESS(Status))
- {
-
- }
-
- /* Add this as a static thread to CSRSRV */
- CsrAddStaticServerThread(hThread, &ClientId, CsrThreadIsServerThread);
-
- /* Get the Thread List Pointers */
- ListHead = &CsrRootProcess->ThreadList;
- NextEntry = ListHead->Flink;
-
- /* Start looping the list */
- while (NextEntry != ListHead)
- {
- /* Get the Thread */
- ServerThread = CONTAINING_RECORD(NextEntry, CSR_THREAD, Link);
-
- /* Start it up */
- Status = NtResumeThread(ServerThread->ThreadHandle, NULL);
-
- /* Is this a Server Thread? */
- if (ServerThread->Flags & CsrThreadIsServerThread)
+ /* Create the event the Port Thread will use */
+ Status = NtCreateEvent(&hRequestEvent,
+ EVENT_ALL_ACCESS,
+ NULL,
+ SynchronizationEvent,
+ FALSE);
+ if (NT_SUCCESS(Status))
{
- /* If so, then wait for it to initialize */
- NtWaitForSingleObject(hRequestEvent, FALSE, NULL);
+ /* Create the Request Thread */
+ Status = RtlCreateUserThread(NtCurrentProcess(),
+ NULL,
+ TRUE,
+ 0,
+ 0,
+ 0,
+ (PVOID)CsrApiRequestThread,
+ (PVOID)hRequestEvent,
+ &hThread,
+ &ClientId);
+ if (NT_SUCCESS(Status))
+ {
+ /* Add this as a static thread to CSRSRV */
+ CsrAddStaticServerThread(hThread, &ClientId, CsrThreadIsServerThread);
+
+ /* Get the Thread List Pointers */
+ ListHead = &CsrRootProcess->ThreadList;
+ NextEntry = ListHead->Flink;
+
+ /* Start looping the list */
+ while (NextEntry != ListHead)
+ {
+ /* Get the Thread */
+ ServerThread = CONTAINING_RECORD(NextEntry, CSR_THREAD, Link);
+
+ /* Start it up */
+ Status = NtResumeThread(ServerThread->ThreadHandle, NULL);
+
+ /* Is this a Server Thread? */
+ if (ServerThread->Flags & CsrThreadIsServerThread)
+ {
+ /* If so, then wait for it to initialize */
+ Status = NtWaitForSingleObject(hRequestEvent, FALSE, NULL);
+ ASSERT(NT_SUCCESS(Status));
+ }
+
+ /* Next thread */
+ NextEntry = NextEntry->Flink;
+ }
+
+ /* We don't need this anymore */
+ NtClose(hRequestEvent);
+ }
}
-
- /* Next thread */
- NextEntry = NextEntry->Flink;
}
- /* We don't need this anymore */
- NtClose(hRequestEvent);
-
/* Return */
return Status;
}
@@ -325,32 +336,29 @@ CsrApiRequestThread(IN PVOID Parameter)
{
PTEB Teb = NtCurrentTeb();
LARGE_INTEGER TimeOut;
- PCSR_THREAD CurrentThread;
+ PCSR_THREAD CurrentThread, CsrThread;
NTSTATUS Status;
- PCSR_API_MESSAGE ReplyMsg = NULL;
+ PCSR_API_MESSAGE ReplyMsg;
CSR_API_MESSAGE ReceiveMsg;
- PCSR_THREAD CsrThread;
PCSR_PROCESS CsrProcess;
PHARDERROR_MSG HardErrorMsg;
PVOID PortContext;
- ULONG MessageType;
- ULONG i;
PCSR_SERVER_DLL ServerDll;
PCLIENT_DIED_MSG ClientDiedMsg;
PDBGKM_MSG DebugMessage;
- ULONG ServerId, ApiId;
- ULONG Reply;
+ ULONG ServerId, ApiId, Reply, MessageType, i;
+ HANDLE ReplyPort;
- /* Probably because of the way GDI is loaded, this has to be done here */
- Teb->GdiClientPID = HandleToUlong(Teb->ClientId.UniqueProcess);
- Teb->GdiClientTID = HandleToUlong(Teb->ClientId.UniqueThread);
-
- /* Set up the timeout for the connect (30 seconds) */
- TimeOut.QuadPart = -30 * 1000 * 1000 * 10;
+ /* Setup LPC loop port and message */
+ ReplyMsg = NULL;
+ ReplyPort = CsrApiPort;
/* Connect to user32 */
while (!CsrConnectToUser())
{
+ /* Set up the timeout for the connect (30 seconds) */
+ TimeOut.QuadPart = -30 * 1000 * 1000 * 10;
+
/* Keep trying until we get a response */
Teb->Win32ClientInfo[0] = 0;
NtDelayExecution(FALSE, &TimeOut);
@@ -363,11 +371,12 @@ CsrApiRequestThread(IN PVOID Parameter)
if (Parameter)
{
/* Set it, to let stuff waiting on us load */
- NtSetEvent((HANDLE)Parameter, NULL);
+ Status = NtSetEvent((HANDLE)Parameter, NULL);
+ ASSERT(NT_SUCCESS(Status));
/* Increase the Thread Counts */
- _InterlockedIncrement((PLONG)&CsrpStaticThreadCount);
- _InterlockedIncrement((PLONG)&CsrpDynamicThreadTotal);
+ _InterlockedIncrement(&CsrpStaticThreadCount);
+ _InterlockedIncrement(&CsrpDynamicThreadTotal);
}
/* Now start the loop */
@@ -376,21 +385,49 @@ CsrApiRequestThread(IN PVOID Parameter)
/* Make sure the real CID is set */
Teb->RealClientId = Teb->ClientId;
+ /* Debug check */
+ if (Teb->CountOfOwnedCriticalSections)
+ {
+ DPRINT1("CSRSRV: FATAL ERROR. CsrThread is Idle while holding %lu critical sections\n",
+ Teb->CountOfOwnedCriticalSections);
+ DPRINT1("CSRSRV: Last Receive Message %lx ReplyMessage %lx\n",
+ &ReceiveMsg, ReplyMsg);
+ DbgBreakPoint();
+ }
+
/* Wait for a message to come through */
- Status = NtReplyWaitReceivePort(CsrApiPort,
+ Status = NtReplyWaitReceivePort(ReplyPort,
&PortContext,
- (PPORT_MESSAGE)ReplyMsg,
- (PPORT_MESSAGE)&ReceiveMsg);
+ &ReplyMsg->Header,
+ &ReceiveMsg.Header);
/* Check if we didn't get success */
- if(Status != STATUS_SUCCESS)
+ if (Status != STATUS_SUCCESS)
{
- /* If we only got a warning, keep going */
- if (NT_SUCCESS(Status)) continue;
+ /* Was it a failure or another success code? */
+ if (!NT_SUCCESS(Status))
+ {
+ /* Check for specific status cases */
+ if ((Status != STATUS_INVALID_CID) &&
+ (Status != STATUS_UNSUCCESSFUL) &&
+ ((Status == STATUS_INVALID_HANDLE) || (ReplyPort == CsrApiPort)))
+ {
+ /* Notify the debugger */
+ DPRINT1("CSRSS: ReceivePort failed - Status == %X\n", Status);
+ DPRINT1("CSRSS: ReplyPortHandle %lx CsrApiPort %lx\n", ReplyPort, CsrApiPort);
+ }
- /* We failed big time, so start out fresh */
- ReplyMsg = NULL;
- continue;
+ /* We failed big time, so start out fresh */
+ ReplyMsg = NULL;
+ ReplyPort = CsrApiPort;
+ continue;
+ }
+ else
+ {
+ /* A bizare "success" code, just try again */
+ DPRINT1("NtReplyWaitReceivePort returned \"success\" status 0x%x\n", Status);
+ continue;
+ }
}
/* Use whatever Client ID we got */
@@ -404,6 +441,7 @@ CsrApiRequestThread(IN PVOID Parameter)
{
/* Handle the Connection Request */
CsrApiHandleConnectionRequest(&ReceiveMsg);
+ ReplyPort = CsrApiPort;
ReplyMsg = NULL;
continue;
}
@@ -416,7 +454,7 @@ CsrApiRequestThread(IN PVOID Parameter)
&ReceiveMsg.Header.ClientId);
/* Did we find a thread? */
- if(!CsrThread)
+ if (!CsrThread)
{
/* This wasn't a CSR Thread, release lock */
CsrReleaseProcessLock();
@@ -425,6 +463,7 @@ CsrApiRequestThread(IN PVOID Parameter)
if (MessageType == LPC_EXCEPTION)
{
ReplyMsg = &ReceiveMsg;
+ ReplyPort = CsrApiPort;
ReplyMsg->Status = DBG_CONTINUE;
}
else if (MessageType == LPC_PORT_CLOSED ||
@@ -432,6 +471,7 @@ CsrApiRequestThread(IN PVOID Parameter)
{
/* The Client or Port are gone, loop again */
ReplyMsg = NULL;
+ ReplyPort = CsrApiPort;
}
else if (MessageType == LPC_ERROR_EVENT)
{
@@ -442,7 +482,7 @@ CsrApiRequestThread(IN PVOID Parameter)
HardErrorMsg->Response = ResponseNotHandled;
/* Check if there are free api threads */
- CsrCheckRequestThreads();
+ CsrpCheckRequestThreads();
if (CsrpStaticThreadCount)
{
/* Loop every Server DLL */
@@ -452,10 +492,10 @@ CsrApiRequestThread(IN PVOID Parameter)
ServerDll = CsrLoadedServerDll[i];
/* Check if it's valid and if it has a Hard Error Callback */
- if (ServerDll && ServerDll->HardErrorCallback)
+ if ((ServerDll) && (ServerDll->HardErrorCallback))
{
/* Call it */
- (*ServerDll->HardErrorCallback)(CsrThread, HardErrorMsg);
+ ServerDll->HardErrorCallback(NULL, HardErrorMsg);
/* If it's handled, get out of here */
if (HardErrorMsg->Response != ResponseNotHandled) break;
@@ -464,12 +504,13 @@ CsrApiRequestThread(IN PVOID Parameter)
}
/* Increase the thread count */
- _InterlockedIncrement((PLONG)&CsrpStaticThreadCount);
+ _InterlockedIncrement(&CsrpStaticThreadCount);
/* If the response was 0xFFFFFFFF, we'll ignore it */
if (HardErrorMsg->Response == 0xFFFFFFFF)
{
ReplyMsg = NULL;
+ ReplyPort = CsrApiPort;
}
else
{
@@ -480,6 +521,7 @@ CsrApiRequestThread(IN PVOID Parameter)
{
/* This is an API Message coming from a non-CSR Thread */
ReplyMsg = &ReceiveMsg;
+ ReplyPort = CsrApiPort;
ReplyMsg->Status = STATUS_ILLEGAL_FUNCTION;
}
else if (MessageType == LPC_DATAGRAM)
@@ -488,54 +530,76 @@ CsrApiRequestThread(IN PVOID Parameter)
ServerId = CSR_SERVER_ID_FROM_OPCODE(ReceiveMsg.Opcode);
/* Make sure that the ID is within limits, and the Server DLL loaded */
+ ServerDll = NULL;
if ((ServerId >= CSR_SERVER_DLL_MAX) ||
(!(ServerDll = CsrLoadedServerDll[ServerId])))
{
/* We are beyond the Maximum Server ID */
+ DPRINT1("CSRSS: %lx is invalid ServerDllIndex (%08x)\n",
+ ServerId, ServerDll);
+ DbgBreakPoint();
+ ReplyPort = CsrApiPort;
ReplyMsg = NULL;
+ continue;
}
- else
+
+ /* Get the API ID */
+ ApiId = CSR_API_ID_FROM_OPCODE(ReceiveMsg.Opcode);
+
+ /* Normalize it with our Base ID */
+ ApiId -= ServerDll->ApiBase;
+
+ /* Make sure that the ID is within limits, and the entry exists */
+ if (ApiId >= ServerDll->HighestApiSupported)
{
- /* Get the API ID */
- ApiId = CSR_API_ID_FROM_OPCODE(ReceiveMsg.Opcode);
-
- /* Normalize it with our Base ID */
- ApiId -= ServerDll->ApiBase;
-
- /* Make sure that the ID is within limits, and the entry exists */
- if ((ApiId >= ServerDll->HighestApiSupported))
- {
- /* We are beyond the Maximum API ID, or it doesn't exist */
- ReplyMsg = NULL;
- }
-
- /* Assume success */
- ReceiveMsg.Status = STATUS_SUCCESS;
-
- /* Validation complete, start SEH */
- _SEH2_TRY
- {
- /* Make sure we have enough threads */
- CsrCheckRequestThreads();
-
- /* Call the API and get the result */
- ReplyMsg = NULL;
- (ServerDll->DispatchTable[ApiId])(&ReceiveMsg, &Reply);
-
- /* Increase the static thread count */
- _InterlockedIncrement((PLONG)&CsrpStaticThreadCount);
- }
- _SEH2_EXCEPT(CsrUnhandledExceptionFilter(_SEH2_GetExceptionInformation()))
- {
- ReplyMsg = NULL;
- }
- _SEH2_END;
+ /* We are beyond the Maximum API ID, or it doesn't exist */
+ DPRINT1("CSRSS: %lx is invalid ApiTableIndex for %Z\n",
+ CSR_API_ID_FROM_OPCODE(ReceiveMsg.Opcode),
+ &ServerDll->Name);
+ ReplyPort = CsrApiPort;
+ ReplyMsg = NULL;
+ continue;
}
+
+ if (CsrDebug & 2)
+ {
+ DPRINT1("[%02x] CSRSS: [%02x,%02x] - %s Api called from %08x\n",
+ Teb->ClientId.UniqueThread,
+ ReceiveMsg.Header.ClientId.UniqueProcess,
+ ReceiveMsg.Header.ClientId.UniqueThread,
+ ServerDll->NameTable[ApiId],
+ NULL);
+ }
+
+ /* Assume success */
+ ReceiveMsg.Status = STATUS_SUCCESS;
+
+ /* Validation complete, start SEH */
+ _SEH2_TRY
+ {
+ /* Make sure we have enough threads */
+ CsrpCheckRequestThreads();
+
+ /* Call the API and get the result */
+ ReplyMsg = NULL;
+ ReplyPort = CsrApiPort;
+ ServerDll->DispatchTable[ApiId](&ReceiveMsg, &Reply);
+
+ /* Increase the static thread count */
+ _InterlockedIncrement(&CsrpStaticThreadCount);
+ }
+ _SEH2_EXCEPT(CsrUnhandledExceptionFilter(_SEH2_GetExceptionInformation()))
+ {
+ ReplyMsg = NULL;
+ ReplyPort = CsrApiPort;
+ }
+ _SEH2_END;
}
else
{
/* Some other ignored message type */
ReplyMsg = NULL;
+ ReplyPort = CsrApiPort;
}
/* Keep going */
@@ -553,7 +617,7 @@ CsrApiRequestThread(IN PVOID Parameter)
if (ClientDiedMsg->CreateTime.QuadPart == CsrThread->CreateTime.QuadPart)
{
/* Reference the thread */
- CsrThread->ReferenceCount++;
+ CsrLockedReferenceThread(CsrThread);
/* Destroy the thread in the API Message */
CsrDestroyThread(&ReceiveMsg.Header.ClientId);
@@ -572,11 +636,12 @@ CsrApiRequestThread(IN PVOID Parameter)
/* Release the lock and keep looping */
CsrReleaseProcessLock();
ReplyMsg = NULL;
+ ReplyPort = CsrApiPort;
continue;
}
/* Reference the thread and release the lock */
- CsrThread->ReferenceCount++;
+ CsrLockedReferenceThread(CsrThread);
CsrReleaseProcessLock();
/* Check if this was an exception */
@@ -592,6 +657,7 @@ CsrApiRequestThread(IN PVOID Parameter)
DebugMessage = (PDBGKM_MSG)&ReceiveMsg;
DebugMessage->ReturnedStatus = DBG_CONTINUE;
ReplyMsg = &ReceiveMsg;
+ ReplyPort = CsrApiPort;
/* Remove our extra reference */
CsrDereferenceThread(CsrThread);
@@ -605,7 +671,7 @@ CsrApiRequestThread(IN PVOID Parameter)
HardErrorMsg->Response = ResponseNotHandled;
/* Check if there are free api threads */
- CsrCheckRequestThreads();
+ CsrpCheckRequestThreads();
if (CsrpStaticThreadCount)
{
/* Loop every Server DLL */
@@ -615,10 +681,10 @@ CsrApiRequestThread(IN PVOID Parameter)
ServerDll = CsrLoadedServerDll[i];
/* Check if it's valid and if it has a Hard Error Callback */
- if (ServerDll && ServerDll->HardErrorCallback)
+ if ((ServerDll) && (ServerDll->HardErrorCallback))
{
/* Call it */
- (*ServerDll->HardErrorCallback)(CsrThread, HardErrorMsg);
+ ServerDll->HardErrorCallback(CsrThread, HardErrorMsg);
/* If it's handled, get out of here */
if (HardErrorMsg->Response != ResponseNotHandled) break;
@@ -627,17 +693,19 @@ CsrApiRequestThread(IN PVOID Parameter)
}
/* Increase the thread count */
- _InterlockedIncrement((PLONG)&CsrpStaticThreadCount);
+ _InterlockedIncrement(&CsrpStaticThreadCount);
/* If the response was 0xFFFFFFFF, we'll ignore it */
if (HardErrorMsg->Response == 0xFFFFFFFF)
{
ReplyMsg = NULL;
+ ReplyPort = CsrApiPort;
}
else
{
CsrDereferenceThread(CsrThread);
ReplyMsg = &ReceiveMsg;
+ ReplyPort = CsrApiPort;
}
}
else
@@ -655,8 +723,130 @@ CsrApiRequestThread(IN PVOID Parameter)
CsrDereferenceThread(CsrThread);
CsrReleaseProcessLock();
- /* FIXME: Handle the API */
+ /* This is an API call, get the Server ID */
+ ServerId = CSR_SERVER_ID_FROM_OPCODE(ReceiveMsg.Opcode);
+ /* Make sure that the ID is within limits, and the Server DLL loaded */
+ ServerDll = NULL;
+ if ((ServerId >= CSR_SERVER_DLL_MAX) ||
+ (!(ServerDll = CsrLoadedServerDll[ServerId])))
+ {
+ /* We are beyond the Maximum Server ID */
+ DPRINT1("CSRSS: %lx is invalid ServerDllIndex (%08x)\n",
+ ServerId, ServerDll);
+ DbgBreakPoint();
+
+ ReplyPort = CsrApiPort;
+ ReplyMsg = &ReceiveMsg;
+ ReplyMsg->Status = STATUS_ILLEGAL_FUNCTION;
+ CsrDereferenceThread(CsrThread);
+ continue;
+ }
+
+ /* Get the API ID */
+ ApiId = CSR_API_ID_FROM_OPCODE(ReceiveMsg.Opcode);
+
+ /* Normalize it with our Base ID */
+ ApiId -= ServerDll->ApiBase;
+
+ /* Make sure that the ID is within limits, and the entry exists */
+ if (ApiId >= ServerDll->HighestApiSupported)
+ {
+ /* We are beyond the Maximum API ID, or it doesn't exist */
+ DPRINT1("CSRSS: %lx is invalid ApiTableIndex for %Z\n",
+ CSR_API_ID_FROM_OPCODE(ReceiveMsg.Opcode),
+ &ServerDll->Name);
+
+ ReplyPort = CsrApiPort;
+ ReplyMsg = &ReceiveMsg;
+ ReplyMsg->Status = STATUS_ILLEGAL_FUNCTION;
+ CsrDereferenceThread(CsrThread);
+ continue;
+ }
+
+ if (CsrDebug & 2)
+ {
+ DPRINT1("[%02x] CSRSS: [%02x,%02x] - %s Api called from %08x\n",
+ Teb->ClientId.UniqueThread,
+ ReceiveMsg.Header.ClientId.UniqueProcess,
+ ReceiveMsg.Header.ClientId.UniqueThread,
+ ServerDll->NameTable[ApiId],
+ CsrThread);
+ }
+
+ /* Assume success */
+ ReplyMsg = &ReceiveMsg;
+ ReceiveMsg.Status = STATUS_SUCCESS;
+
+ /* Now we reply to a particular client */
+ ReplyPort = CsrThread->Process->ClientPort;
+
+ /* Check if there's a capture buffer */
+ if (ReceiveMsg.CsrCaptureData)
+ {
+ /* Capture the arguments */
+ if (!CsrCaptureArguments(CsrThread, &ReceiveMsg))
+ {
+ /* Ignore this message if we failed to get the arguments */
+ CsrDereferenceThread(CsrThread);
+ continue;
+ }
+ }
+
+ /* Validation complete, start SEH */
+ _SEH2_TRY
+ {
+ /* Make sure we have enough threads */
+ CsrpCheckRequestThreads();
+
+ Teb->CsrClientThread = CsrThread;
+
+ /* Call the API and get the result */
+ Reply = 0;
+ ServerDll->DispatchTable[ApiId](&ReceiveMsg, &Reply);
+
+ /* Increase the static thread count */
+ _InterlockedIncrement(&CsrpStaticThreadCount);
+
+ Teb->CsrClientThread = CurrentThread;
+
+ if (Reply == 3)
+ {
+ ReplyMsg = NULL;
+ if (ReceiveMsg.CsrCaptureData)
+ {
+ CsrReleaseCapturedArguments(&ReceiveMsg);
+ }
+ CsrDereferenceThread(CsrThread);
+ ReplyPort = CsrApiPort;
+ }
+ else if (Reply == 2)
+ {
+ NtReplyPort(ReplyPort, &ReplyMsg->Header);
+ ReplyPort = CsrApiPort;
+ ReplyMsg = NULL;
+ CsrDereferenceThread(CsrThread);
+ }
+ else if (Reply == 1)
+ {
+ ReplyPort = CsrApiPort;
+ ReplyMsg = NULL;
+ }
+ else
+ {
+ if (ReceiveMsg.CsrCaptureData)
+ {
+ CsrReleaseCapturedArguments(&ReceiveMsg);
+ }
+ CsrDereferenceThread(CsrThread);
+ }
+ }
+ _SEH2_EXCEPT(CsrUnhandledExceptionFilter(_SEH2_GetExceptionInformation()))
+ {
+ ReplyMsg = NULL;
+ ReplyPort = CsrApiPort;
+ }
+ _SEH2_END;
}
/* We're out of the loop for some reason, terminate! */
@@ -709,7 +899,7 @@ CsrApiHandleConnectionRequest(IN PCSR_API_MESSAGE ApiMessage)
if (CsrProcess)
{
/* Reference the Process */
- CsrProcess->ReferenceCount++;
+ CsrLockedReferenceProcess(CsrThread->Process);
/* Release the lock */
CsrReleaseProcessLock();
@@ -738,7 +928,7 @@ CsrApiHandleConnectionRequest(IN PCSR_API_MESSAGE ApiMessage)
}
/* Dereference the project */
- CsrProcess->ReferenceCount--;
+ CsrLockedDereferenceProcess(CsrProcess);
}
}
@@ -760,10 +950,21 @@ CsrApiHandleConnectionRequest(IN PCSR_API_MESSAGE ApiMessage)
AllowConnection,
NULL,
&RemotePortView);
-
- /* Check if the connection was established, or if we allowed it */
- if (NT_SUCCESS(Status) && AllowConnection)
+ if (!NT_SUCCESS(Status))
{
+ DPRINT1("CSRSS: NtAcceptConnectPort - failed. Status == %X\n", Status);
+ }
+ else if (AllowConnection)
+ {
+ if (CsrDebug & 2)
+ {
+ DPRINT1("CSRSS: ClientId: %lx.%lx has ClientView: Base=%p, Size=%lx\n",
+ ApiMessage->Header.ClientId.UniqueProcess,
+ ApiMessage->Header.ClientId.UniqueThread,
+ RemotePortView.ViewBase,
+ RemotePortView.ViewSize);
+ }
+
/* Set some Port Data in the Process */
CsrProcess->ClientPort = hPort;
CsrProcess->ClientViewBase = (ULONG_PTR)RemotePortView.ViewBase;
@@ -772,12 +973,16 @@ CsrApiHandleConnectionRequest(IN PCSR_API_MESSAGE ApiMessage)
/* Complete the connection */
Status = NtCompleteConnectPort(hPort);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("CSRSS: NtCompleteConnectPort - failed. Status == %X\n", Status);
+ }
}
-
- /* The accept or complete could've failed, let debug builds know */
- if (!NT_SUCCESS(Status))
+ else
{
- DPRINT1("CSRSS: Failure to accept connection. Status: %lx\n", Status);
+ DPRINT1("CSRSS: Rejecting Connection Request from ClientId: %lx.%lx\n",
+ ApiMessage->Header.ClientId.UniqueProcess,
+ ApiMessage->Header.ClientId.UniqueThread);
}
/* Return status to caller */
@@ -804,8 +1009,8 @@ NTAPI
CsrSbApiRequestThread(IN PVOID Parameter)
{
NTSTATUS Status;
- SB_API_MESSAGE ReceiveMsg;
- PSB_API_MESSAGE ReplyMsg = NULL;
+ SB_API_MSG ReceiveMsg;
+ PSB_API_MSG ReplyMsg = NULL;
PVOID PortContext;
ULONG MessageType;
@@ -815,22 +1020,23 @@ CsrSbApiRequestThread(IN PVOID Parameter)
/* Wait for a message to come in */
Status = NtReplyWaitReceivePort(CsrSbApiPort,
&PortContext,
- (PPORT_MESSAGE)ReplyMsg,
- (PPORT_MESSAGE)&ReceiveMsg);
+ &ReplyMsg->h,
+ &ReceiveMsg.h);
/* Check if we didn't get success */
- if(Status != STATUS_SUCCESS)
+ if (Status != STATUS_SUCCESS)
{
/* If we only got a warning, keep going */
if (NT_SUCCESS(Status)) continue;
/* We failed big time, so start out fresh */
ReplyMsg = NULL;
+ DPRINT1("CSRSS: ReceivePort failed - Status == %X\n", Status);
continue;
}
/* Save the message type */
- MessageType = ReceiveMsg.Header.u2.s2.Type;
+ MessageType = ReceiveMsg.h.u2.s2.Type;
/* Check if this is a connection request */
if (MessageType == LPC_CONNECTION_REQUEST)
@@ -864,16 +1070,20 @@ CsrSbApiRequestThread(IN PVOID Parameter)
* It's an API Message, check if it's within limits. If it's not, the
* NT Behaviour is to set this to the Maximum API.
*/
- if (ReceiveMsg.Opcode > 4) ReceiveMsg.Opcode = 4;
+ if (ReceiveMsg.ApiNumber > SbpMaxApiNumber)
+ {
+ ReceiveMsg.ApiNumber = SbpMaxApiNumber;
+ DPRINT1("CSRSS: %lx is invalid Sb ApiNumber\n", ReceiveMsg.ApiNumber);
+ }
/* Reuse the message */
ReplyMsg = &ReceiveMsg;
/* Make sure that the message is supported */
- if (ReceiveMsg.Opcode < 4)
+ if (ReceiveMsg.ApiNumber < SbpMaxApiNumber)
{
/* Call the API */
- if (!(CsrServerSbApiDispatch[ReceiveMsg.Opcode])(&ReceiveMsg))
+ if (!CsrServerSbApiDispatch[ReceiveMsg.ApiNumber](&ReceiveMsg))
{
/* It failed, so return nothing */
ReplyMsg = NULL;
@@ -882,7 +1092,7 @@ CsrSbApiRequestThread(IN PVOID Parameter)
else
{
/* We don't support this API Number */
- ReplyMsg->Status = STATUS_NOT_IMPLEMENTED;
+ ReplyMsg->ReturnValue = STATUS_NOT_IMPLEMENTED;
}
}
}
@@ -905,7 +1115,7 @@ CsrSbApiRequestThread(IN PVOID Parameter)
*--*/
NTSTATUS
NTAPI
-CsrSbApiHandleConnectionRequest(IN PSB_API_MESSAGE Message)
+CsrSbApiHandleConnectionRequest(IN PSB_API_MSG Message)
{
NTSTATUS Status;
REMOTE_PORT_VIEW RemotePortView;
@@ -921,7 +1131,6 @@ CsrSbApiHandleConnectionRequest(IN PSB_API_MESSAGE Message)
TRUE,
NULL,
&RemotePortView);
-
if (!NT_SUCCESS(Status))
{
DPRINT1("CSRSS: Sb Accept Connection failed %lx\n", Status);
@@ -929,7 +1138,8 @@ CsrSbApiHandleConnectionRequest(IN PSB_API_MESSAGE Message)
}
/* Complete the Connection */
- if (!NT_SUCCESS(Status = NtCompleteConnectPort(hPort)))
+ Status = NtCompleteConnectPort(hPort);
+ if (!NT_SUCCESS(Status))
{
DPRINT1("CSRSS: Sb Complete Connection failed %lx\n",Status);
}
@@ -979,6 +1189,7 @@ CsrCallServerFromServer(PCSR_API_MESSAGE ReceiveMsg,
(!(ServerDll = CsrLoadedServerDll[ServerId])))
{
/* We are beyond the Maximum Server ID */
+ DPRINT1("CSRSS: %lx is invalid ServerDllIndex (%08x)\n", ServerId, ServerDll);
ReplyMsg->Status = (ULONG)STATUS_ILLEGAL_FUNCTION;
return STATUS_ILLEGAL_FUNCTION;
}
@@ -992,14 +1203,26 @@ CsrCallServerFromServer(PCSR_API_MESSAGE ReceiveMsg,
/* Make sure that the ID is within limits, and the entry exists */
if ((ApiId >= ServerDll->HighestApiSupported) ||
- (ServerDll->ValidTable && !ServerDll->ValidTable[ApiId]))
+ ((ServerDll->ValidTable) && !(ServerDll->ValidTable[ApiId])))
{
/* We are beyond the Maximum API ID, or it doesn't exist */
+ DPRINT1("CSRSS: %lx (%s) is invalid ApiTableIndex for %Z or is an "
+ "invalid API to call from the server.\n",
+ ServerDll->ValidTable[ApiId],
+ ((ServerDll->NameTable) && (ServerDll->NameTable[ApiId])) ?
+ ServerDll->NameTable[ApiId] : "*** UNKNOWN ***", &ServerDll->Name);
+ DbgBreakPoint();
ReplyMsg->Status = (ULONG)STATUS_ILLEGAL_FUNCTION;
return STATUS_ILLEGAL_FUNCTION;
}
}
+ if (CsrDebug & 2)
+ {
+ DPRINT1("CSRSS: %s Api Request received from server process\n",
+ ServerDll->NameTable[ApiId]);
+ }
+
/* Validation complete, start SEH */
_SEH2_TRY
{
@@ -1044,6 +1267,7 @@ CsrConnectToUser(VOID)
STRING StartupName;
PTEB Teb = NtCurrentTeb();
PCSR_THREAD CsrThread;
+ BOOLEAN Connected;
/* Check if we didn't already find it */
if (!CsrClientThreadSetup)
@@ -1069,10 +1293,25 @@ CsrConnectToUser(VOID)
}
/* Connect to user32 */
- CsrClientThreadSetup();
+ _SEH2_TRY
+ {
+ Connected = CsrClientThreadSetup();
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Connected = FALSE;
+ } _SEH2_END;
+
+ if (!Connected)
+ {
+ DPRINT1("CSRSS: CsrConnectToUser failed\n");
+ return NULL;
+ }
/* Save pointer to this thread in TEB */
+ CsrAcquireProcessLock();
CsrThread = CsrLocateThreadInProcess(NULL, &Teb->ClientId);
+ CsrReleaseProcessLock();
if (CsrThread) Teb->CsrClientThread = CsrThread;
/* Return it */
@@ -1124,13 +1363,10 @@ NTAPI
CsrCaptureArguments(IN PCSR_THREAD CsrThread,
IN PCSR_API_MESSAGE ApiMessage)
{
- PCSR_CAPTURE_BUFFER LocalCaptureBuffer = NULL;
- ULONG LocalLength = 0;
- PCSR_CAPTURE_BUFFER RemoteCaptureBuffer = NULL;
+ PCSR_CAPTURE_BUFFER LocalCaptureBuffer = NULL, RemoteCaptureBuffer = NULL;
+ ULONG LocalLength = 0, PointerCount = 0;
SIZE_T BufferDistance = 0;
- ULONG PointerCount = 0;
- ULONG_PTR **PointerOffsets = NULL;
- ULONG_PTR *CurrentPointer = NULL;
+ ULONG_PTR **PointerOffsets = NULL, *CurrentPointer = NULL;
/* Use SEH to make sure this is valid */
_SEH2_TRY
@@ -1144,6 +1380,7 @@ CsrCaptureArguments(IN PCSR_THREAD CsrThread,
(((ULONG_PTR)LocalCaptureBuffer + LocalLength) >= CsrThread->Process->ClientViewBounds))
{
/* Return failure */
+ DPRINT1("*** CSRSS: CaptureBuffer outside of ClientView\n");
ApiMessage->Status = STATUS_INVALID_PARAMETER;
_SEH2_YIELD(return FALSE);
}
@@ -1153,6 +1390,8 @@ CsrCaptureArguments(IN PCSR_THREAD CsrThread,
LocalLength) ||(LocalLength > MAXWORD))
{
/* Return failure */
+ DPRINT1("*** CSRSS: CaptureBuffer %p has bad length\n", LocalCaptureBuffer);
+ DbgBreakPoint();
ApiMessage->Status = STATUS_INVALID_PARAMETER;
_SEH2_YIELD(return FALSE);
}
@@ -1205,7 +1444,9 @@ CsrCaptureArguments(IN PCSR_THREAD CsrThread,
else
{
/* Invalid pointer, fail */
- ApiMessage->Status = (ULONG)STATUS_INVALID_PARAMETER;
+ DPRINT1("*** CSRSS: CaptureBuffer MessagePointer outside of ClientView\n");
+ DbgBreakPoint();
+ ApiMessage->Status = STATUS_INVALID_PARAMETER;
}
}
@@ -1251,12 +1492,10 @@ VOID
NTAPI
CsrReleaseCapturedArguments(IN PCSR_API_MESSAGE ApiMessage)
{
- PCSR_CAPTURE_BUFFER RemoteCaptureBuffer;
- PCSR_CAPTURE_BUFFER LocalCaptureBuffer;
+ PCSR_CAPTURE_BUFFER RemoteCaptureBuffer, LocalCaptureBuffer;
SIZE_T BufferDistance;
ULONG PointerCount;
- ULONG_PTR **PointerOffsets;
- ULONG_PTR *CurrentPointer;
+ ULONG_PTR **PointerOffsets, *CurrentPointer;
/* Get the capture buffers */
RemoteCaptureBuffer = ApiMessage->CsrCaptureData;
@@ -1276,7 +1515,8 @@ CsrReleaseCapturedArguments(IN PCSR_API_MESSAGE ApiMessage)
while (PointerCount)
{
/* Get the current pointer */
- if ((CurrentPointer = *PointerOffsets++))
+ CurrentPointer = *PointerOffsets++;
+ if (CurrentPointer)
{
/* Add it to the CSR Message structure */
CurrentPointer += (ULONG_PTR)ApiMessage;
@@ -1290,9 +1530,7 @@ CsrReleaseCapturedArguments(IN PCSR_API_MESSAGE ApiMessage)
}
/* Copy the data back */
- RtlMoveMemory(LocalCaptureBuffer,
- RemoteCaptureBuffer,
- RemoteCaptureBuffer->Size);
+ RtlMoveMemory(LocalCaptureBuffer, RemoteCaptureBuffer, RemoteCaptureBuffer->Size);
/* Free our allocated buffer */
RtlFreeHeap(CsrHeap, 0, RemoteCaptureBuffer);
@@ -1331,10 +1569,8 @@ CsrValidateMessageBuffer(IN PCSR_API_MESSAGE ApiMessage,
{
PCSR_CAPTURE_BUFFER CaptureBuffer = ApiMessage->CsrCaptureData;
SIZE_T BufferDistance;
- ULONG PointerCount;
- ULONG_PTR **PointerOffsets;
- ULONG_PTR *CurrentPointer;
- ULONG i;
+ ULONG PointerCount, i;
+ ULONG_PTR **PointerOffsets, *CurrentPointer;
/* Make sure there are some arguments */
if (!ArgumentCount) return FALSE;
@@ -1379,6 +1615,8 @@ CsrValidateMessageBuffer(IN PCSR_API_MESSAGE ApiMessage,
}
/* Failure */
+ DbgPrint("CSRSRV: Bad message buffer %p\n", ApiMessage);
+ DbgBreakPoint();
return FALSE;
}
@@ -1405,7 +1643,7 @@ NTAPI
CsrValidateMessageString(IN PCSR_API_MESSAGE ApiMessage,
IN LPWSTR *MessageString)
{
- DPRINT("CSRSRV: %s called\n", __FUNCTION__);
+ DPRINT1("CSRSRV: %s called\n", __FUNCTION__);
return FALSE;
}
diff --git a/reactos/subsystems/csr/csrsrv/csrsrv.rbuild b/reactos/subsystems/csr/csrsrv/csrsrv.rbuild
deleted file mode 100644
index 3a215fda8a8..00000000000
--- a/reactos/subsystems/csr/csrsrv/csrsrv.rbuild
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
-
- .
- .
- include/reactos/subsys
- ntdll
- pseh
- api.c
- init.c
- process.c
- server.c
- session.c
- thread.c
- wait.c
- srv.h
-
diff --git a/reactos/subsystems/csr/csrsrv/csrsrv.spec b/reactos/subsystems/csr/csrsrv/csrsrv2.spec
similarity index 96%
rename from reactos/subsystems/csr/csrsrv/csrsrv.spec
rename to reactos/subsystems/csr/csrsrv/csrsrv2.spec
index 6b68980350b..e3794208fe9 100644
--- a/reactos/subsystems/csr/csrsrv/csrsrv.spec
+++ b/reactos/subsystems/csr/csrsrv/csrsrv2.spec
@@ -3,7 +3,7 @@
@ stdcall CsrConnectToUser()
@ stdcall CsrCreateProcess(ptr ptr ptr ptr long ptr)
@ stdcall CsrCreateRemoteThread(ptr ptr)
-@ stdcall CsrCreateThread(ptr ptr ptr)
+@ stdcall CsrCreateThread(ptr ptr ptr long)
@ stdcall CsrCreateWait(ptr ptr ptr ptr ptr ptr)
@ stdcall CsrDebugProcess(ptr)
@ stdcall CsrDebugProcessStop(ptr)
diff --git a/reactos/subsystems/csr/csrsrv/init.c b/reactos/subsystems/csr/csrsrv/init.c
index 02e14cdb791..77667a6f4f5 100644
--- a/reactos/subsystems/csr/csrsrv/init.c
+++ b/reactos/subsystems/csr/csrsrv/init.c
@@ -25,168 +25,14 @@ HANDLE SessionObjectDirectory;
HANDLE DosDevicesDirectory;
HANDLE CsrInitializationEvent;
SYSTEM_BASIC_INFORMATION CsrNtSysInfo;
+ULONG CsrDebug;
/* PRIVATE FUNCTIONS *********************************************************/
/*++
- * @name CsrPopulateDosDevicesDirectory
+ * @name CsrParseServerCommandLine
*
- * The CsrPopulateDosDevicesDirectory routine uses the DOS Device Map from the
- * Kernel to populate the Dos Devices Object Directory for the session.
- *
- * @param TODO.
- *
- * @return TODO.
- *
- * @remarks TODO.
- *
- *--*/
-NTSTATUS
-NTAPI
-CsrPopulateDosDevicesDirectory(IN HANDLE hDosDevicesDirectory,
- IN PPROCESS_DEVICEMAP_INFORMATION DeviceMap)
-{
- WCHAR SymLinkBuffer[0x1000];
- UNICODE_STRING GlobalString;
- OBJECT_ATTRIBUTES ObjectAttributes;
- HANDLE hDirectory = 0;
- NTSTATUS Status;
- ULONG ReturnLength = 0;
- ULONG BufferLength = 0x4000;
- ULONG Context;
- POBJECT_DIRECTORY_INFORMATION QueryBuffer;
- HANDLE hSymLink;
- UNICODE_STRING LinkTarget;
-
- /* Initialize the Global String */
- RtlInitUnicodeString(&GlobalString, GLOBAL_ROOT);
-
- /* Initialize the Object Attributes */
- InitializeObjectAttributes(&ObjectAttributes,
- &GlobalString,
- OBJ_CASE_INSENSITIVE,
- NULL,
- NULL);
-
- /* Open the directory */
- Status = NtOpenDirectoryObject(&hDirectory,
- DIRECTORY_QUERY,
- &ObjectAttributes);
- if (!NT_SUCCESS(Status)) return Status;
-
- /* Allocate memory */
- QueryBuffer = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, 0x4000);
- if (!QueryBuffer) return STATUS_NO_MEMORY;
-
- /* Start query loop */
- while (TRUE)
- {
- /* Query the Directory */
- Status = NtQueryDirectoryObject(hDirectory,
- QueryBuffer,
- BufferLength,
- FALSE,
- FALSE,
- &Context,
- &ReturnLength);
-
- /* Check for the status */
- if (NT_SUCCESS(Status))
- {
- /* Make sure it has a name */
- if (!QueryBuffer->Name.Buffer[0]) continue;
-
- /* Check if it's actually a symbolic link */
- if (wcscmp(QueryBuffer->TypeName.Buffer, SYMLINK_NAME))
- {
- /* It is, open it */
- InitializeObjectAttributes(&ObjectAttributes,
- &QueryBuffer->Name,
- OBJ_CASE_INSENSITIVE,
- NULL,
- hDirectory);
- Status = NtOpenSymbolicLinkObject(&hSymLink,
- SYMBOLIC_LINK_QUERY,
- &ObjectAttributes);
- if (NT_SUCCESS(Status))
- {
- /* Setup the Target String */
- LinkTarget.Length = 0;
- LinkTarget.MaximumLength = sizeof(SymLinkBuffer);
- LinkTarget.Buffer = SymLinkBuffer;
-
- /* Query the target */
- Status = NtQuerySymbolicLinkObject(hSymLink,
- &LinkTarget,
- &ReturnLength);
-
- /* Close the handle */
- NtClose(hSymLink);
-
- }
- }
- }
- /* FIXME: Loop never ends! */
- }
-}
-
-/*++
- * @name CsrLoadServerDllFromCommandLine
- *
- * The CsrLoadServerDllFromCommandLine routine loads a Server DLL from the
- * CSRSS command-line in the registry.
- *
- * @param KeyValue
- * Pointer to the specially formatted string for this Server DLL.
- *
- * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
- * othwerwise.
- *
- * @remarks None.
- *
- *--*/
-NTSTATUS
-NTAPI
-CsrLoadServerDllFromCommandLine(PCHAR KeyValue)
-{
- PCHAR EntryPoint = NULL;
- ULONG DllIndex = 0;
- PCHAR ServerString = KeyValue;
- NTSTATUS Status;
-
- /* Loop the command line */
- while (*ServerString)
- {
- /* Check for the Entry Point */
- if ((*ServerString == ':') && (!EntryPoint))
- {
- /* Found it. Add a nullchar and save it */
- *ServerString++ = '\0';
- EntryPoint = ServerString;
- }
-
- /* Check for the Dll Index */
- if (*ServerString++ == ',')
- {
- /* Convert it to a ULONG */
- Status = RtlCharToInteger(ServerString, 10, &DllIndex);
-
- /* Add a null char if it was valid */
- if (NT_SUCCESS(Status)) ServerString[-1] = '\0';
-
- /* We're done here */
- break;
- }
- }
-
- /* We've got the name, entrypoint and index, load it */
- return CsrLoadServerDll(KeyValue, EntryPoint, DllIndex);
-}
-
-/*++
- * @name CsrpParseCommandLine
- *
- * The CsrpParseCommandLine routine parses the CSRSS command-line in the
+ * The CsrParseServerCommandLine routine parses the CSRSS command-line in the
* registry and performs operations for each entry found.
*
* @param ArgumentCount
@@ -203,13 +49,14 @@ CsrLoadServerDllFromCommandLine(PCHAR KeyValue)
*--*/
NTSTATUS
FASTCALL
-CsrpParseCommandLine(IN ULONG ArgumentCount,
- IN PCHAR Arguments[])
+CsrParseServerCommandLine(IN ULONG ArgumentCount,
+ IN PCHAR Arguments[])
{
NTSTATUS Status;
- PCHAR ParameterName = NULL;
- PCHAR ParameterValue = NULL;
- ULONG i;
+ PCHAR ParameterName = NULL, ParameterValue = NULL, EntryPoint, ServerString;
+ ULONG i, DllIndex;
+ ANSI_STRING AnsiString;
+ OBJECT_ATTRIBUTES ObjectAttributes;
/* Set the Defaults */
CsrTotalPerProcessDataLength = 0;
@@ -224,8 +71,9 @@ CsrpParseCommandLine(IN ULONG ArgumentCount,
DPRINT1("CSRSS: CsrCreateSessionObjectDirectory failed (%lx)\n",
Status);
- /* It's not fatal if the SID is 0 */
- if (SessionId != 0) return Status;
+ /* It's not fatal if the session ID isn't zero */
+ if (SessionId) return Status;
+ ASSERT(NT_SUCCESS(Status));
}
/* Loop through every argument */
@@ -233,19 +81,48 @@ CsrpParseCommandLine(IN ULONG ArgumentCount,
{
/* Split Name and Value */
ParameterName = Arguments[i];
+ ParameterValue = NULL;
ParameterValue = strchr(ParameterName, L'=');
- *ParameterValue++ = '\0';
+ if (ParameterValue) *ParameterValue++ = '\0';
DPRINT("Name=%S, Value=%S\n", ParameterName, ParameterValue);
/* Check for Object Directory */
if (!_stricmp(ParameterName, "ObjectDirectory"))
{
- CsrCreateObjectDirectory(ParameterValue);
+ /* Check if a session ID is specified */
+ if (SessionId)
+ {
+ DPRINT1("Sessions not yet implemented\n");
+ ASSERT(SessionId);
+ }
+
+ /* Initialize the directory name */
+ RtlInitAnsiString(&AnsiString, ParameterValue);
+ Status = RtlAnsiStringToUnicodeString(&CsrDirectoryName,
+ &AnsiString,
+ TRUE);
+ ASSERT(NT_SUCCESS(Status) || SessionId != 0);
+ if (!NT_SUCCESS(Status)) return Status;
+
+ /* Create it */
+ InitializeObjectAttributes(&ObjectAttributes,
+ &CsrDirectoryName,
+ OBJ_OPENIF | OBJ_CASE_INSENSITIVE |
+ (SessionId) ? 0 : OBJ_PERMANENT,
+ NULL,
+ NULL);
+ Status = NtCreateDirectoryObject(&CsrObjectDirectory,
+ DIRECTORY_ALL_ACCESS,
+ &ObjectAttributes);
+ if (!NT_SUCCESS(Status)) return Status;
+
+ /* Secure it */
+ Status = CsrSetDirectorySecurity(CsrObjectDirectory);
+ if (!NT_SUCCESS(Status)) return Status;
}
- else if(!_stricmp(ParameterName, "SubSystemType"))
+ else if (!_stricmp(ParameterName, "SubSystemType"))
{
/* Ignored */
- Status = STATUS_SUCCESS;
}
else if (!_stricmp(ParameterName, "MaxRequestThreads"))
{
@@ -260,25 +137,69 @@ CsrpParseCommandLine(IN ULONG ArgumentCount,
}
else if (!_stricmp(ParameterName, "ProfileControl"))
{
- CsrProfileControl = (!_stricmp(ParameterValue, "On")) ? TRUE : FALSE;
+ /* Ignored */
}
else if (!_stricmp(ParameterName, "SharedSection"))
{
/* Craete the Section */
Status = CsrSrvCreateSharedSection(ParameterValue);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("CSRSS: *** Invalid syntax for %s=%s (Status == %X)\n",
+ ParameterName, ParameterValue, Status);
+ return Status;
+ }
/* Load us */
Status = CsrLoadServerDll("CSRSS", NULL, CSR_SRV_SERVER);
}
else if (!_stricmp(ParameterName, "ServerDLL"))
{
- /* Parse the Command-Line and load this DLL */
- Status = CsrLoadServerDllFromCommandLine(ParameterValue);
+ /* Loop the command line */
+ EntryPoint = NULL;
+ Status = STATUS_INVALID_PARAMETER;
+ ServerString = ParameterValue;
+ while (*ServerString)
+ {
+ /* Check for the Entry Point */
+ if ((*ServerString == ':') && (!EntryPoint))
+ {
+ /* Found it. Add a nullchar and save it */
+ *ServerString++ = ANSI_NULL;
+ EntryPoint = ServerString;
+ }
+
+ /* Check for the Dll Index */
+ if (*ServerString++ == ',') break;
+ }
+
+ /* Did we find something to load? */
+ if (!*ServerString)
+ {
+ DPRINT1("CSRSS: *** Invalid syntax for ServerDll=%s (Status == %X)\n",
+ ParameterValue, Status);
+ return Status;
+ }
+
+ /* Convert it to a ULONG */
+ Status = RtlCharToInteger(ServerString, 10, &DllIndex);
+
+ /* Add a null char if it was valid */
+ if (NT_SUCCESS(Status)) ServerString[-1] = ANSI_NULL;
+
+ /* Load it */
+ if (CsrDebug & 1) DPRINT1("CSRSS: Loading ServerDll=%s:%s\n", ParameterValue, EntryPoint);
+ Status = CsrLoadServerDll(ParameterValue, EntryPoint, DllIndex);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("CSRSS: *** Failed loading ServerDll=%s (Status == 0x%x)\n",
+ ParameterValue, Status);
+ return Status;
+ }
}
else if (!_stricmp(ParameterName, "Windows"))
{
/* Ignored */
- Status = STATUS_SUCCESS;
}
else
{
@@ -291,59 +212,6 @@ CsrpParseCommandLine(IN ULONG ArgumentCount,
return Status;
}
-/*++
- * @name CsrCreateObjectDirectory
- *
- * The CsrCreateObjectDirectory creates the Object Directory on the CSRSS
- * command-line from the registry.
- *
- * @param ObjectDirectory
- * Pointer to the name of the Object Directory to create.
- *
- * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
- * othwerwise.
- *
- * @remarks None.
- *
- *--*/
-NTSTATUS
-NTAPI
-CsrCreateObjectDirectory(IN PCHAR ObjectDirectory)
-{
- NTSTATUS Status = STATUS_SUCCESS;
- ANSI_STRING TempString;
- OBJECT_ATTRIBUTES DirectoryAttributes;
-
- DPRINT("CSRSRV:%s(%s) called\n", __FUNCTION__, ObjectDirectory);
-
- /* Convert the parameter to our Global Unicode name */
- RtlInitAnsiString(&TempString, ObjectDirectory);
- Status = RtlAnsiStringToUnicodeString(&CsrDirectoryName, &TempString, TRUE);
-
- /* Initialize the attributes for the Directory */
- InitializeObjectAttributes(&DirectoryAttributes,
- &CsrDirectoryName,
- OBJ_PERMANENT | OBJ_OPENIF | OBJ_CASE_INSENSITIVE,
- NULL,
- NULL);
-
- /* Create it */
- Status = NtCreateDirectoryObject(&CsrObjectDirectory,
- DIRECTORY_ALL_ACCESS,
- &DirectoryAttributes);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("CSRSRV:%s: fatal: NtCreateDirectoryObject failed (Status=0x%08lx)\n",
- __FUNCTION__, Status);
- }
-
- /* Set the Security */
- Status = CsrSetDirectorySecurity(CsrObjectDirectory);
-
- /* Return */
- return Status;
-}
-
/*++
* @name CsrCreateLocalSystemSD
*
@@ -365,86 +233,66 @@ CsrCreateLocalSystemSD(OUT PSECURITY_DESCRIPTOR *LocalSystemSd)
{
SID_IDENTIFIER_AUTHORITY NtSidAuthority = {SECURITY_NT_AUTHORITY};
PSID SystemSid;
- ULONG SidLength;
- PSECURITY_DESCRIPTOR SecurityDescriptor;
+ ULONG Length;
+ PSECURITY_DESCRIPTOR SystemSd;
PACL Dacl;
NTSTATUS Status;
/* Initialize the System SID */
- RtlAllocateAndInitializeSid(&NtSidAuthority,
- 1,
+ RtlAllocateAndInitializeSid(&NtSidAuthority, 1,
SECURITY_LOCAL_SYSTEM_RID,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
+ 0, 0, 0, 0, 0, 0, 0,
&SystemSid);
/* Get the length of the SID */
- SidLength = RtlLengthSid(SystemSid);
+ Length = RtlLengthSid(SystemSid) + sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE);
/* Allocate a buffer for the Security Descriptor, with SID and DACL */
- SecurityDescriptor = RtlAllocateHeap(CsrHeap,
- 0,
- SECURITY_DESCRIPTOR_MIN_LENGTH +
- sizeof(ACL) + SidLength +
- sizeof(ACCESS_ALLOWED_ACE));
+ SystemSd = RtlAllocateHeap(CsrHeap, 0, SECURITY_DESCRIPTOR_MIN_LENGTH + Length);
/* Set the pointer to the DACL */
- Dacl = (PACL)((ULONG_PTR)SecurityDescriptor + SECURITY_DESCRIPTOR_MIN_LENGTH);
+ Dacl = (PACL)((ULONG_PTR)SystemSd + SECURITY_DESCRIPTOR_MIN_LENGTH);
/* Now create the SD itself */
- Status = RtlCreateSecurityDescriptor(SecurityDescriptor,
- SECURITY_DESCRIPTOR_REVISION);
+ Status = RtlCreateSecurityDescriptor(SystemSd, SECURITY_DESCRIPTOR_REVISION);
if (!NT_SUCCESS(Status))
{
/* Fail */
- RtlFreeHeap(CsrHeap, 0, SecurityDescriptor);
+ RtlFreeHeap(CsrHeap, 0, SystemSd);
return Status;
}
/* Create the DACL for it*/
- RtlCreateAcl(Dacl,
- sizeof(ACL) + SidLength + sizeof(ACCESS_ALLOWED_ACE),
- ACL_REVISION2);
+ RtlCreateAcl(Dacl, Length, ACL_REVISION2);
/* Create the ACE */
- Status = RtlAddAccessAllowedAce(Dacl,
- ACL_REVISION,
- PORT_ALL_ACCESS,
- SystemSid);
+ Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, PORT_ALL_ACCESS, SystemSid);
if (!NT_SUCCESS(Status))
{
/* Fail */
- RtlFreeHeap(CsrHeap, 0, SecurityDescriptor);
+ RtlFreeHeap(CsrHeap, 0, SystemSd);
return Status;
}
/* Clear the DACL in the SD */
- Status = RtlSetDaclSecurityDescriptor(SecurityDescriptor,
- TRUE,
- Dacl,
- FALSE);
+ Status = RtlSetDaclSecurityDescriptor(SystemSd, TRUE, Dacl, FALSE);
if (!NT_SUCCESS(Status))
{
/* Fail */
- RtlFreeHeap(CsrHeap, 0, SecurityDescriptor);
+ RtlFreeHeap(CsrHeap, 0, SystemSd);
return Status;
}
/* Free the SID and return*/
RtlFreeSid(SystemSid);
- *LocalSystemSd = SecurityDescriptor;
+ *LocalSystemSd = SystemSd;
return Status;
}
/*++
- * @name CsrGetDosDevicesSd
+ * @name GetDosDevicesProtection
*
- * The CsrGetDosDevicesSd creates a security descriptor for the DOS Devices
+ * The GetDosDevicesProtection creates a security descriptor for the DOS Devices
* Object Directory.
*
* @param DosDevicesSd
@@ -459,7 +307,7 @@ CsrCreateLocalSystemSD(OUT PSECURITY_DESCRIPTOR *LocalSystemSd)
*--*/
NTSTATUS
NTAPI
-CsrGetDosDevicesSd(OUT PSECURITY_DESCRIPTOR DosDevicesSd)
+GetDosDevicesProtection(OUT PSECURITY_DESCRIPTOR DosDevicesSd)
{
SID_IDENTIFIER_AUTHORITY WorldAuthority = {SECURITY_WORLD_SID_AUTHORITY};
SID_IDENTIFIER_AUTHORITY CreatorAuthority = {SECURITY_CREATOR_SID_AUTHORITY};
@@ -474,61 +322,34 @@ CsrGetDosDevicesSd(OUT PSECURITY_DESCRIPTOR DosDevicesSd)
PACCESS_ALLOWED_ACE Ace;
HANDLE hKey;
NTSTATUS Status;
- ULONG ResultLength, SidLength;
+ ULONG ResultLength, SidLength, AclLength;
/* Create the SD */
RtlCreateSecurityDescriptor(DosDevicesSd, SECURITY_DESCRIPTOR_REVISION);
/* Initialize the System SID */
- RtlAllocateAndInitializeSid(&NtSidAuthority,
- 1,
+ RtlAllocateAndInitializeSid(&NtSidAuthority, 1,
SECURITY_LOCAL_SYSTEM_RID,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
+ 0, 0, 0, 0, 0, 0, 0,
&SystemSid);
/* Initialize the World SID */
- RtlAllocateAndInitializeSid(&WorldAuthority,
- 1,
+ RtlAllocateAndInitializeSid(&WorldAuthority, 1,
SECURITY_WORLD_RID,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
+ 0, 0, 0, 0, 0, 0, 0,
&WorldSid);
/* Initialize the Admin SID */
- RtlAllocateAndInitializeSid(&NtSidAuthority,
- 2,
+ RtlAllocateAndInitializeSid(&NtSidAuthority, 2,
SECURITY_BUILTIN_DOMAIN_RID,
DOMAIN_ALIAS_RID_ADMINS,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
+ 0, 0, 0, 0, 0, 0,
&AdminSid);
/* Initialize the Creator SID */
- RtlAllocateAndInitializeSid(&CreatorAuthority,
- 1,
+ RtlAllocateAndInitializeSid(&CreatorAuthority, 1,
SECURITY_CREATOR_OWNER_RID,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
+ 0, 0, 0, 0, 0, 0, 0,
&CreatorSid);
/* Open the Session Manager Key */
@@ -538,11 +359,10 @@ CsrGetDosDevicesSd(OUT PSECURITY_DESCRIPTOR DosDevicesSd)
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
- if (NT_SUCCESS(Status = NtOpenKey(&hKey,
- KEY_READ,
- &ObjectAttributes)))
+ Status = NtOpenKey(&hKey, KEY_READ, &ObjectAttributes);
+ if (NT_SUCCESS(Status))
{
- /* Read the ProtectionMode. See http://support.microsoft.com/kb/q218473/ */
+ /* Read the key value */
RtlInitUnicodeString(&KeyName, L"ProtectionMode");
Status = NtQueryValueKey(hKey,
&KeyName,
@@ -553,8 +373,8 @@ CsrGetDosDevicesSd(OUT PSECURITY_DESCRIPTOR DosDevicesSd)
/* Make sure it's what we expect it to be */
KeyValuePartialInfo = (PKEY_VALUE_PARTIAL_INFORMATION)KeyValueBuffer;
- if ((KeyValuePartialInfo->Type == REG_DWORD) &&
- (*(PULONG)KeyValuePartialInfo->Data != 0))
+ if ((KeyValuePartialInfo->Type == REG_DWORD) &&
+ (*(PULONG)KeyValuePartialInfo->Data))
{
/* Save the Protection Mode */
ProtectionMode = *(PULONG)KeyValuePartialInfo->Data;
@@ -570,110 +390,49 @@ CsrGetDosDevicesSd(OUT PSECURITY_DESCRIPTOR DosDevicesSd)
/* Calculate SID Lengths */
SidLength = RtlLengthSid(CreatorSid) + RtlLengthSid(SystemSid) +
RtlLengthSid(AdminSid);
+ AclLength = sizeof(ACL) + 3 * sizeof(ACCESS_ALLOWED_ACE) + SidLength;
/* Allocate memory for the DACL */
- Dacl = RtlAllocateHeap(CsrHeap,
- HEAP_ZERO_MEMORY,
- sizeof(ACL) + 3 * sizeof(ACCESS_ALLOWED_ACE) +
- SidLength);
+ Dacl = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, AclLength);
- /* Create it */
- Status = RtlCreateAcl(Dacl,
- sizeof(ACL) + 3 * sizeof(ACCESS_ALLOWED_ACE) +
- SidLength,
- ACL_REVISION2);
+ /* Build the ACL and add 3 ACEs */
+ Status = RtlCreateAcl(Dacl, AclLength, ACL_REVISION2);
+ Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, GENERIC_ALL, SystemSid);
+ Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, GENERIC_ALL, AdminSid);
+ Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, GENERIC_ALL, CreatorSid);
- /* Give full access to the System */
- Status = RtlAddAccessAllowedAce(Dacl,
- ACL_REVISION,
- GENERIC_ALL,
- SystemSid);
-
- /* Get the ACE back */
+ /* Edit the ACEs to make them inheritable */
Status = RtlGetAce(Dacl, 0, (PVOID*)&Ace);
-
- /* Add some flags to it for the Admin SID */
- Ace->Header.AceFlags |= (OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE);
-
- /* Add the ACE to the Admin SID */
- Status = RtlAddAccessAllowedAce(Dacl,
- ACL_REVISION,
- GENERIC_ALL,
- AdminSid);
-
- /* Get the ACE back */
+ Ace->Header.AceFlags |= OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE;
Status = RtlGetAce(Dacl, 1, (PVOID*)&Ace);
-
- /* Add some flags to it for the Creator SID */
- Ace->Header.AceFlags |= (OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE);
-
- /* Add the ACE to the Admin SID */
- Status = RtlAddAccessAllowedAce(Dacl,
- ACL_REVISION,
- GENERIC_ALL,
- CreatorSid);
-
- /* Get the ACE back */
+ Ace->Header.AceFlags |= OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE;
Status = RtlGetAce(Dacl, 2, (PVOID*)&Ace);
-
- /* Add some flags to it for the SD */
- Ace->Header.AceFlags |= (OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE |
- INHERIT_ONLY_ACE);
+ Ace->Header.AceFlags |= OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE;
/* Set this DACL with the SD */
- Status = RtlSetDaclSecurityDescriptor(DosDevicesSd,
- TRUE,
- Dacl,
- FALSE);
+ Status = RtlSetDaclSecurityDescriptor(DosDevicesSd, TRUE, Dacl, FALSE);
}
else
{
/* Calculate SID Lengths */
SidLength = RtlLengthSid(WorldSid) + RtlLengthSid(SystemSid);
+ AclLength = sizeof(ACL) + 3 * sizeof(ACCESS_ALLOWED_ACE) + SidLength;
/* Allocate memory for the DACL */
- Dacl = RtlAllocateHeap(CsrHeap,
- HEAP_ZERO_MEMORY,
- sizeof(ACL) + 3 * sizeof(ACCESS_ALLOWED_ACE) +
- SidLength);
+ Dacl = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, AclLength);
- /* Create it */
- Status = RtlCreateAcl(Dacl,
- sizeof(ACL) + 3 * sizeof(ACCESS_ALLOWED_ACE) +
- SidLength,
- ACL_REVISION2);
+ /* Build the ACL and add 3 ACEs */
+ Status = RtlCreateAcl(Dacl, AclLength, ACL_REVISION2);
+ Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE, WorldSid);
+ Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, GENERIC_ALL, SystemSid);
+ Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, GENERIC_ALL, WorldSid);
- /* Give RWE access to the World */
- Status = RtlAddAccessAllowedAce(Dacl,
- ACL_REVISION,
- GENERIC_READ | GENERIC_WRITE |
- GENERIC_EXECUTE,
- WorldSid);
-
- /* Give full access to the System */
- Status = RtlAddAccessAllowedAce(Dacl,
- ACL_REVISION,
- GENERIC_ALL,
- SystemSid);
-
- /* Give full access to the World */
- Status = RtlAddAccessAllowedAce(Dacl,
- ACL_REVISION,
- GENERIC_ALL,
- WorldSid);
-
- /* Get the ACE back */
+ /* Edit the last ACE to make it inheritable */
Status = RtlGetAce(Dacl, 2, (PVOID*)&Ace);
-
- /* Add some flags to it for the SD */
- Ace->Header.AceFlags |= (OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE |
- INHERIT_ONLY_ACE);
+ Ace->Header.AceFlags |= OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE;
/* Set this DACL with the SD */
- Status = RtlSetDaclSecurityDescriptor(DosDevicesSd,
- TRUE,
- Dacl,
- FALSE);
+ Status = RtlSetDaclSecurityDescriptor(DosDevicesSd, TRUE, Dacl, FALSE);
}
/* FIXME: failure cases! Fail: */
@@ -692,10 +451,10 @@ CsrGetDosDevicesSd(OUT PSECURITY_DESCRIPTOR DosDevicesSd)
}
/*++
- * @name CsrFreeDosDevicesSd
+ * @name FreeDosDevicesProtection
*
- * The CsrFreeDosDevicesSd frees the security descriptor that was created
- * by CsrGetDosDevicesSd
+ * The FreeDosDevicesProtection frees the security descriptor that was created
+ * by GetDosDevicesProtection
*
* @param DosDevicesSd
* Pointer to the security descriptor to free.
@@ -707,20 +466,20 @@ CsrGetDosDevicesSd(OUT PSECURITY_DESCRIPTOR DosDevicesSd)
*--*/
VOID
NTAPI
-CsrFreeDosDevicesSd(IN PSECURITY_DESCRIPTOR DosDevicesSd)
+FreeDosDevicesProtection(IN PSECURITY_DESCRIPTOR DosDevicesSd)
{
PACL Dacl;
BOOLEAN Present, Default;
NTSTATUS Status;
/* Get the DACL corresponding to this SD */
- Status = RtlGetDaclSecurityDescriptor(DosDevicesSd,
- &Present,
- &Dacl,
- &Default);
+ Status = RtlGetDaclSecurityDescriptor(DosDevicesSd, &Present, &Dacl, &Default);
+ ASSERT(NT_SUCCESS(Status));
+ ASSERT(Present);
+ ASSERT(Dacl != NULL);
/* Free it */
- if (NT_SUCCESS(Status) && Dacl) RtlFreeHeap(CsrHeap, 0, Dacl);
+ if ((NT_SUCCESS(Status)) && (Dacl)) RtlFreeHeap(CsrHeap, 0, Dacl);
}
/*++
@@ -742,34 +501,30 @@ NTSTATUS
NTAPI
CsrCreateSessionObjectDirectory(IN ULONG Session)
{
- WCHAR SessionBuffer[512];
- WCHAR BnoBuffer[512];
- UNICODE_STRING SessionString;
- UNICODE_STRING BnoString;
+ WCHAR SessionBuffer[512], BnoBuffer[512];
+ UNICODE_STRING SessionString, BnoString;
OBJECT_ATTRIBUTES ObjectAttributes;
HANDLE BnoHandle;
SECURITY_DESCRIPTOR DosDevicesSd;
NTSTATUS Status;
- /* Generate the Session BNOLINKS Directory */
+ /* Generate the Session BNOLINKS Directory name */
swprintf(SessionBuffer, L"%ws\\BNOLINKS", SESSION_ROOT);
RtlInitUnicodeString(&SessionString, SessionBuffer);
- /* Initialize the attributes for the Directory */
+ /* Create it */
InitializeObjectAttributes(&ObjectAttributes,
&SessionString,
- OBJ_PERMANENT | OBJ_OPENIF | OBJ_CASE_INSENSITIVE,
+ OBJ_OPENIF | OBJ_CASE_INSENSITIVE,
NULL,
NULL);
-
- /* Create it */
Status = NtCreateDirectoryObject(&BNOLinksDirectory,
DIRECTORY_ALL_ACCESS,
&ObjectAttributes);
if (!NT_SUCCESS(Status))
{
- DPRINT1("CSRSRV:%s: fatal: NtCreateDirectoryObject failed (Status=0x%08lx)\n",
- __FUNCTION__, Status);
+ DPRINT1("CSRSS: NtCreateDirectoryObject failed in "
+ "CsrCreateSessionObjectDirectory - status = %lx\n", Status);
return Status;
}
@@ -782,85 +537,74 @@ CsrCreateSessionObjectDirectory(IN ULONG Session)
{
/* Not the first, so the name will be slighly more complex */
swprintf(BnoBuffer, L"%ws\\%ld\\BaseNamedObjects", SESSION_ROOT, Session);
+ RtlInitUnicodeString(&BnoString, BnoBuffer);
}
else
{
/* Use the direct name */
- RtlCopyMemory(BnoBuffer, L"\\BaseNamedObjects", 36);
+ RtlInitUnicodeString(&BnoString, L"\\BaseNamedObjects");
}
- /* Create the Unicode String for the BNO SymLink */
- RtlInitUnicodeString(&BnoString, BnoBuffer);
-
- /* Initialize the attributes for the SymLink */
+ /* Create the symlink */
InitializeObjectAttributes(&ObjectAttributes,
&SessionString,
- OBJ_PERMANENT | OBJ_OPENIF | OBJ_CASE_INSENSITIVE,
+ OBJ_OPENIF | OBJ_CASE_INSENSITIVE,
BNOLinksDirectory,
NULL);
-
- /* Create it */
Status = NtCreateSymbolicLinkObject(&BnoHandle,
SYMBOLIC_LINK_ALL_ACCESS,
&ObjectAttributes,
&BnoString);
if (!NT_SUCCESS(Status))
{
- DPRINT1("CSRSRV:%s: fatal: NtCreateSymbolicLinkObject failed (Status=0x%08lx)\n",
- __FUNCTION__, Status);
+ DPRINT1("CSRSS: NtCreateSymbolicLinkObject failed in "
+ "CsrCreateSessionObjectDirectory - status = %lx\n", Status);
return Status;
}
/* Create the \DosDevices Security Descriptor */
- CsrGetDosDevicesSd(&DosDevicesSd);
+ Status = GetDosDevicesProtection(&DosDevicesSd);
+ if (!NT_SUCCESS(Status)) return Status;
/* Now create a directory for this session */
swprintf(SessionBuffer, L"%ws\\%ld", SESSION_ROOT, Session);
RtlInitUnicodeString(&SessionString, SessionBuffer);
- /* Initialize the attributes for the Directory */
+ /* Create the directory */
InitializeObjectAttributes(&ObjectAttributes,
&SessionString,
- OBJ_PERMANENT | OBJ_OPENIF | OBJ_CASE_INSENSITIVE,
+ OBJ_OPENIF | OBJ_CASE_INSENSITIVE,
0,
&DosDevicesSd);
-
- /* Create it */
Status = NtCreateDirectoryObject(&SessionObjectDirectory,
DIRECTORY_ALL_ACCESS,
&ObjectAttributes);
if (!NT_SUCCESS(Status))
{
- DPRINT1("CSRSRV:%s: fatal: NtCreateDirectoryObject failed (Status=0x%08lx)\n",
- __FUNCTION__, Status);
- /* Release the Security Descriptor */
- CsrFreeDosDevicesSd(&DosDevicesSd);
+ DPRINT1("CSRSS: NtCreateDirectoryObject failed in "
+ "CsrCreateSessionObjectDirectory - status = %lx\n", Status);
+ FreeDosDevicesProtection(&DosDevicesSd);
return Status;
}
/* Next, create a directory for this session's DOS Devices */
- /* Now create a directory for this session */
RtlInitUnicodeString(&SessionString, L"DosDevices");
-
- /* Initialize the attributes for the Directory */
InitializeObjectAttributes(&ObjectAttributes,
&SessionString,
- OBJ_PERMANENT | OBJ_OPENIF | OBJ_CASE_INSENSITIVE,
- 0,
+ OBJ_CASE_INSENSITIVE,
+ SessionObjectDirectory,
&DosDevicesSd);
-
- /* Create it */
Status = NtCreateDirectoryObject(&DosDevicesDirectory,
DIRECTORY_ALL_ACCESS,
&ObjectAttributes);
if (!NT_SUCCESS(Status))
{
- DPRINT1("CSRSRV:%s: fatal: NtCreateDirectoryObject failed (Status=0x%08lx)\n",
- __FUNCTION__, Status);
+ DPRINT1("CSRSS: NtCreateDirectoryObject failed in "
+ "CsrCreateSessionObjectDirectory - status = %lx\n", Status);
}
/* Release the Security Descriptor */
- CsrFreeDosDevicesSd(&DosDevicesSd);
+ FreeDosDevicesProtection(&DosDevicesSd);
/* Return */
return Status;
@@ -885,76 +629,54 @@ NTAPI
CsrSetProcessSecurity(VOID)
{
NTSTATUS Status;
- HANDLE hToken;
- ULONG ReturnLength;
- PTOKEN_USER TokenUserInformation;
- PSECURITY_DESCRIPTOR SecurityDescriptor;
+ HANDLE hToken, hProcess = NtCurrentProcess();
+ ULONG ReturnLength, Length;
+ PTOKEN_USER TokenInfo = NULL;
+ PSECURITY_DESCRIPTOR ProcSd = NULL;
PACL Dacl;
+ PSID UserSid;
/* Open our token */
- Status = NtOpenProcessToken(NtCurrentProcess(),
- TOKEN_QUERY,
- &hToken);
- if (!NT_SUCCESS(Status)) return Status;
+ Status = NtOpenProcessToken(hProcess, TOKEN_QUERY, &hToken);
+ if (!NT_SUCCESS(Status)) goto Quickie;
/* Get the Token User Length */
- NtQueryInformationToken(hToken,
- TokenUser,
- NULL,
- 0,
- &ReturnLength);
+ NtQueryInformationToken(hToken, TokenUser, NULL, 0, &Length);
/* Allocate space for it */
- TokenUserInformation = RtlAllocateHeap(CsrHeap,
- HEAP_ZERO_MEMORY,
- ReturnLength);
+ TokenInfo = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, Length);
+ if (!TokenInfo)
+ {
+ Status = STATUS_NO_MEMORY;
+ goto Quickie;
+ }
/* Now query the data */
- Status = NtQueryInformationToken(hToken,
- TokenUser,
- TokenUserInformation,
- ReturnLength,
- &ReturnLength);
-
- /* Close the handle */
+ Status = NtQueryInformationToken(hToken, TokenUser, TokenInfo, Length, &Length);
NtClose(hToken);
-
- /* Make sure that we got the data */
- if (!NT_SUCCESS(Status))
- {
- /* FAil */
- RtlFreeHeap(CsrHeap, 0, TokenUserInformation);
- return Status;
- }
+ if (!NT_SUCCESS(Status)) goto Quickie;
/* Now check the SID Length */
- ReturnLength = RtlLengthSid(TokenUserInformation->User.Sid);
+ UserSid = TokenInfo->User.Sid;
+ ReturnLength = RtlLengthSid(UserSid) + sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE);
/* Allocate a buffer for the Security Descriptor, with SID and DACL */
- SecurityDescriptor = RtlAllocateHeap(CsrHeap,
- HEAP_ZERO_MEMORY,
- SECURITY_DESCRIPTOR_MIN_LENGTH +
- sizeof(ACL) + ReturnLength +
- sizeof(ACCESS_ALLOWED_ACE));
-
- /* Set the pointer to the DACL */
- Dacl = (PACL)((ULONG_PTR)SecurityDescriptor + SECURITY_DESCRIPTOR_MIN_LENGTH);
-
- /* Now create the SD itself */
- Status = RtlCreateSecurityDescriptor(SecurityDescriptor,
- SECURITY_DESCRIPTOR_REVISION);
- if (!NT_SUCCESS(Status))
+ ProcSd = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, SECURITY_DESCRIPTOR_MIN_LENGTH + Length);
+ if (!ProcSd)
{
- /* Fail */
- RtlFreeHeap(CsrHeap, 0, SecurityDescriptor);
- RtlFreeHeap(CsrHeap, 0, TokenUserInformation);
- return Status;
+ Status = STATUS_NO_MEMORY;
+ goto Quickie;
}
+ /* Set the pointer to the DACL */
+ Dacl = (PACL)((ULONG_PTR)ProcSd + SECURITY_DESCRIPTOR_MIN_LENGTH);
+
+ /* Now create the SD itself */
+ Status = RtlCreateSecurityDescriptor(ProcSd, SECURITY_DESCRIPTOR_REVISION);
+ if (!NT_SUCCESS(Status)) goto Quickie;
+
/* Create the DACL for it*/
- RtlCreateAcl(Dacl,
- sizeof(ACL) + ReturnLength + sizeof(ACCESS_ALLOWED_ACE),
- ACL_REVISION2);
+ RtlCreateAcl(Dacl, Length, ACL_REVISION2);
/* Create the ACE */
Status = RtlAddAccessAllowedAce(Dacl,
@@ -963,36 +685,20 @@ CsrSetProcessSecurity(VOID)
PROCESS_VM_OPERATION | PROCESS_DUP_HANDLE |
PROCESS_TERMINATE | PROCESS_SUSPEND_RESUME |
PROCESS_QUERY_INFORMATION | READ_CONTROL,
- TokenUserInformation->User.Sid);
- if (!NT_SUCCESS(Status))
- {
- /* Fail */
- RtlFreeHeap(CsrHeap, 0, SecurityDescriptor);
- RtlFreeHeap(CsrHeap, 0, TokenUserInformation);
- return Status;
- }
+ UserSid);
+ if (!NT_SUCCESS(Status)) goto Quickie;
/* Clear the DACL in the SD */
- Status = RtlSetDaclSecurityDescriptor(SecurityDescriptor,
- TRUE,
- Dacl,
- FALSE);
- if (!NT_SUCCESS(Status))
- {
- /* Fail */
- RtlFreeHeap(CsrHeap, 0, SecurityDescriptor);
- RtlFreeHeap(CsrHeap, 0, TokenUserInformation);
- return Status;
- }
+ Status = RtlSetDaclSecurityDescriptor(ProcSd, TRUE, Dacl, FALSE);
+ if (!NT_SUCCESS(Status)) goto Quickie;
/* Write the SD into the Process */
- Status = NtSetSecurityObject(NtCurrentProcess(),
- DACL_SECURITY_INFORMATION,
- SecurityDescriptor);
+ Status = NtSetSecurityObject(hProcess, DACL_SECURITY_INFORMATION, ProcSd);
/* Free the memory and return */
- RtlFreeHeap(CsrHeap, 0, SecurityDescriptor);
- RtlFreeHeap(CsrHeap, 0, TokenUserInformation);
+Quickie:
+ if (ProcSd) RtlFreeHeap(CsrHeap, 0, ProcSd);
+ RtlFreeHeap(CsrHeap, 0, TokenInfo);
return Status;
}
@@ -1049,7 +755,6 @@ CsrServerInitialization(ULONG ArgumentCount,
ULONG i = 0;
PVOID ProcessData;
PCSR_SERVER_DLL ServerDll;
-
DPRINT("CSRSRV: %s called\n", __FUNCTION__);
/* Create the Init Event */
@@ -1058,22 +763,40 @@ CsrServerInitialization(ULONG ArgumentCount,
NULL,
SynchronizationEvent,
FALSE);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("CSRSRV:%s: NtCreateEvent failed (Status=%08lx)\n",
+ __FUNCTION__, Status);
+ return Status;
+ }
/* Cache System Basic Information so we don't always request it */
Status = NtQuerySystemInformation(SystemBasicInformation,
&CsrNtSysInfo,
sizeof(SYSTEM_BASIC_INFORMATION),
NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("CSRSRV:%s: NtQuerySystemInformation failed (Status=%08lx)\n",
+ __FUNCTION__, Status);
+ return Status;
+ }
/* Save our Heap */
CsrHeap = RtlGetProcessHeap();
/* Set our Security Descriptor to protect the process */
- CsrSetProcessSecurity();
+ Status = CsrSetProcessSecurity();
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("CSRSRV:%s: CsrSetProcessSecurity failed (Status=%08lx)\n",
+ __FUNCTION__, Status);
+ return Status;
+ }
/* Set up Session Support */
- Status = CsrInitializeNtSessions();
- if(!NT_SUCCESS(Status))
+ Status = CsrInitializeNtSessionList();
+ if (!NT_SUCCESS(Status))
{
DPRINT1("CSRSRV:%s: CsrInitializeSessions failed (Status=%08lx)\n",
__FUNCTION__, Status);
@@ -1081,27 +804,39 @@ CsrServerInitialization(ULONG ArgumentCount,
}
/* Set up Process Support */
- Status = CsrInitializeProcesses();
- if(!NT_SUCCESS(Status))
+ Status = CsrInitializeProcessStructure();
+ if (!NT_SUCCESS(Status))
{
- DPRINT1("CSRSRV:%s: CsrInitializeProcesses failed (Status=%08lx)\n",
+ DPRINT1("CSRSRV:%s: CsrInitializeProcessStructure failed (Status=%08lx)\n",
__FUNCTION__, Status);
return Status;
}
/* Parse the command line */
- CsrpParseCommandLine(ArgumentCount, Arguments);
+ Status = CsrParseServerCommandLine(ArgumentCount, Arguments);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("CSRSRV:%s: CsrParseServerCommandLine failed (Status=%08lx)\n",
+ __FUNCTION__, Status);
+ return Status;
+ }
/* All Server DLLs are now loaded, allocate a heap for the Root Process */
ProcessData = RtlAllocateHeap(CsrHeap,
HEAP_ZERO_MEMORY,
CsrTotalPerProcessDataLength);
+ if (!ProcessData)
+ {
+ DPRINT1("CSRSRV:%s: RtlAllocateHeap failed (Status=%08lx)\n",
+ __FUNCTION__, STATUS_NO_MEMORY);
+ return STATUS_NO_MEMORY;
+ }
/*
* Our Root Process was never officially initalized, so write the data
* for each Server DLL manually.
*/
- for(i = 0; i < CSR_SERVER_DLL_MAX; i++)
+ for (i = 0; i < CSR_SERVER_DLL_MAX; i++)
{
/* Get the current Server */
ServerDll = CsrLoadedServerDll[i];
@@ -1124,7 +859,7 @@ CsrServerInitialization(ULONG ArgumentCount,
}
/* Now initialize the Root Process manually as well */
- for(i = 0; i < CSR_SERVER_DLL_MAX; i++)
+ for (i = 0; i < CSR_SERVER_DLL_MAX; i++)
{
/* Get the current Server */
ServerDll = CsrLoadedServerDll[i];
@@ -1139,7 +874,7 @@ CsrServerInitialization(ULONG ArgumentCount,
/* Now initialize our API Port */
Status = CsrApiPortInitialize();
- if(!NT_SUCCESS(Status))
+ if (!NT_SUCCESS(Status))
{
DPRINT1("CSRSRV:%s: CsrApiPortInitialize failed (Status=%08lx)\n",
__FUNCTION__, Status);
@@ -1148,7 +883,7 @@ CsrServerInitialization(ULONG ArgumentCount,
/* Initialize the API Port for SM communication */
Status = CsrSbApiPortInitialize();
- if(!NT_SUCCESS(Status))
+ if (!NT_SUCCESS(Status))
{
DPRINT1("CSRSRV:%s: CsrSbApiPortInitialize failed (Status=%08lx)\n",
__FUNCTION__, Status);
@@ -1160,7 +895,7 @@ CsrServerInitialization(ULONG ArgumentCount,
CsrSbApiPort,
IMAGE_SUBSYSTEM_WINDOWS_GUI,
&CsrSmApiPort);
- if(!NT_SUCCESS(Status))
+ if (!NT_SUCCESS(Status))
{
DPRINT1("CSRSRV:%s: SmConnectToSm failed (Status=%08lx)\n",
__FUNCTION__, Status);
@@ -1168,19 +903,33 @@ CsrServerInitialization(ULONG ArgumentCount,
}
/* Finito! Signal the event */
- NtSetEvent(CsrInitializationEvent, NULL);
+ Status = NtSetEvent(CsrInitializationEvent, NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("CSRSRV:%s: NtSetEvent failed (Status=%08lx)\n",
+ __FUNCTION__, Status);
+ return Status;
+ }
+
+ /* Close the event handle now */
NtClose(CsrInitializationEvent);
/* Have us handle Hard Errors */
- NtSetDefaultHardErrorPort(CsrApiPort);
-
+ Status = NtSetDefaultHardErrorPort(CsrApiPort);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("CSRSRV:%s: NtSetDefaultHardErrorPort failed (Status=%08lx)\n",
+ __FUNCTION__, Status);
+ return Status;
+ }
+
/* Return status */
return Status;
}
/*++
* @name CsrPopulateDosDevices
- * @implemented NT5.1
+ * @unimplemented NT5.1
*
* The CsrPopulateDosDevices routine uses the DOS Device Map from the Kernel
* to populate the Dos Devices Object Directory for the session.
@@ -1196,35 +945,15 @@ VOID
NTAPI
CsrPopulateDosDevices(VOID)
{
- NTSTATUS Status;
- PROCESS_DEVICEMAP_INFORMATION OldDeviceMap;
- PROCESS_DEVICEMAP_INFORMATION NewDeviceMap;
-
- /* Query the Device Map */
- Status = NtQueryInformationProcess(NtCurrentProcess(),
- ProcessDeviceMap,
- &OldDeviceMap.Query,
- sizeof(PROCESS_DEVICEMAP_INFORMATION),
- NULL);
- if (!NT_SUCCESS(Status)) return;
-
- /* Set the new one */
- NewDeviceMap.Set.DirectoryHandle = DosDevicesDirectory;
- Status = NtSetInformationProcess(NtCurrentProcess(),
- ProcessDeviceMap,
- &NewDeviceMap,
- sizeof(ULONG));
- if (!NT_SUCCESS(Status)) return;
-
- /* Populate the Directory */
- CsrPopulateDosDevicesDirectory(DosDevicesDirectory, &OldDeviceMap);
+ DPRINT1("Deprecated API\n");
+ return;
}
BOOL
NTAPI
-DllMainCRTStartup(HANDLE hDll,
- DWORD dwReason,
- LPVOID lpReserved)
+DllMain(IN HANDLE hDll,
+ IN DWORD dwReason,
+ IN LPVOID lpReserved)
{
/* We don't do much */
UNREFERENCED_PARAMETER(hDll);
diff --git a/reactos/subsystems/csr/csrsrv/process.c b/reactos/subsystems/csr/csrsrv/process.c
index 1de2286b549..ea75dd720c8 100644
--- a/reactos/subsystems/csr/csrsrv/process.c
+++ b/reactos/subsystems/csr/csrsrv/process.c
@@ -22,6 +22,84 @@ ULONG CsrTotalPerProcessDataLength;
/* PRIVATE FUNCTIONS *********************************************************/
+/*++
+ * @name ProtectHandle
+ * @implemented NT5.2
+ *
+ * The ProtectHandle routine protects an object handle against closure.
+ *
+ * @return TRUE or FALSE.
+ *
+ * @remarks None.
+ *
+ *--*/
+BOOLEAN
+NTAPI
+ProtectHandle(IN HANDLE ObjectHandle)
+{
+ NTSTATUS Status;
+ OBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleInfo;
+
+ /* Query current state */
+ Status = NtQueryObject(ObjectHandle,
+ ObjectHandleFlagInformation,
+ &HandleInfo,
+ sizeof(HandleInfo),
+ NULL);
+ if (NT_SUCCESS(Status))
+ {
+ /* Enable protect from close */
+ HandleInfo.ProtectFromClose = TRUE;
+ Status = NtSetInformationObject(ObjectHandle,
+ ObjectHandleFlagInformation,
+ &HandleInfo,
+ sizeof(HandleInfo));
+ if (NT_SUCCESS(Status)) return TRUE;
+ }
+
+ /* We failed to or set the state */
+ return FALSE;
+}
+
+/*++
+ * @name UnProtectHandle
+ * @implemented NT5.2
+ *
+ * The UnProtectHandle routine unprotects an object handle against closure.
+ *
+ * @return TRUE or FALSE.
+ *
+ * @remarks None.
+ *
+ *--*/
+BOOLEAN
+NTAPI
+UnProtectHandle(IN HANDLE ObjectHandle)
+{
+ NTSTATUS Status;
+ OBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleInfo;
+
+ /* Query current state */
+ Status = NtQueryObject(ObjectHandle,
+ ObjectHandleFlagInformation,
+ &HandleInfo,
+ sizeof(HandleInfo),
+ NULL);
+ if (NT_SUCCESS(Status))
+ {
+ /* Disable protect from close */
+ HandleInfo.ProtectFromClose = FALSE;
+ Status = NtSetInformationObject(ObjectHandle,
+ ObjectHandleFlagInformation,
+ &HandleInfo,
+ sizeof(HandleInfo));
+ if (NT_SUCCESS(Status)) return TRUE;
+ }
+
+ /* We failed to or set the state */
+ return FALSE;
+}
+
/*++
* @name CsrAllocateProcess
* @implemented NT4
@@ -49,8 +127,9 @@ CsrAllocateProcess(VOID)
CsrProcess = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, TotalSize);
if (!CsrProcess) return NULL;
- /* Handle the Sequence Number */
+ /* Handle the Sequence Number and protect against overflow */
CsrProcess->SequenceNumber = CsrProcessSequenceCount++;
+ if (CsrProcessSequenceCount < 5) CsrProcessSequenceCount = 5;
/* Increase the reference count */
CsrProcess->ReferenceCount++;
@@ -66,7 +145,7 @@ CsrAllocateProcess(VOID)
* @name CsrServerInitialization
* @implemented NT4
*
- * The CsrInitializeProcesses routine sets up support for CSR Processes
+ * The CsrInitializeProcessStructure routine sets up support for CSR Processes
* and CSR Threads.
*
* @param None.
@@ -79,13 +158,14 @@ CsrAllocateProcess(VOID)
*--*/
NTSTATUS
NTAPI
-CsrInitializeProcesses(VOID)
+CsrInitializeProcessStructure(VOID)
{
NTSTATUS Status;
ULONG i;
/* Initialize the Lock */
Status = RtlInitializeCriticalSection(&CsrProcessLock);
+ if (!NT_SUCCESS(Status)) return Status;
/* Set up the Root Process */
CsrRootProcess = CsrAllocateProcess();
@@ -100,8 +180,7 @@ CsrInitializeProcesses(VOID)
for (i = 0; i < 256; i++) InitializeListHead(&CsrThreadHashTable[i]);
/* Initialize the Wait Lock */
- Status = RtlInitializeCriticalSection(&CsrWaitListsLock);
- return Status;
+ return RtlInitializeCriticalSection(&CsrWaitListsLock);
}
/*++
@@ -155,6 +234,7 @@ CsrInsertProcess(IN PCSR_PROCESS Parent OPTIONAL,
{
PCSR_SERVER_DLL ServerDll;
ULONG i;
+ ASSERT(ProcessStructureListLocked());
/* Set the parent */
CsrProcess->Parent = Parent;
@@ -194,15 +274,41 @@ VOID
NTAPI
CsrLockedDereferenceProcess(PCSR_PROCESS CsrProcess)
{
+ LONG LockCount;
+
/* Decrease reference count */
- if (!(--CsrProcess->ReferenceCount))
+ LockCount = --CsrProcess->ReferenceCount;
+ ASSERT(LockCount >= 0);
+ if (!LockCount)
{
/* Call the generic cleanup code */
- CsrAcquireProcessLock();
CsrProcessRefcountZero(CsrProcess);
+ CsrAcquireProcessLock();
}
}
+/*++
+ * @name CsrLockedReferenceProcess
+ *
+ * The CsrLockedReferenceProcess refences a CSR Process while the
+ * Process Lock is already being held.
+ *
+ * @param CsrProcess
+ * Pointer to the CSR Process to be referenced.
+ *
+ * @return None.
+ *
+ * @remarks This routine will return with the Process Lock held.
+ *
+ *--*/
+VOID
+NTAPI
+CsrLockedReferenceProcess(IN PCSR_PROCESS CsrProcess)
+{
+ /* Increment the reference count */
+ ++CsrProcess->ReferenceCount;
+}
+
/*++
* @name CsrRemoveProcess
*
@@ -211,7 +317,7 @@ CsrLockedDereferenceProcess(PCSR_PROCESS CsrProcess)
* of this removal.
*
* @param CsrProcess
- * Pointer to the CSR Process to remove.
+ * Pointer to the CSR Process to remove.
*
* @return None.
*
@@ -224,6 +330,7 @@ CsrRemoveProcess(IN PCSR_PROCESS CsrProcess)
{
PCSR_SERVER_DLL ServerDll;
ULONG i;
+ ASSERT(ProcessStructureListLocked());
/* Remove us from the Process List */
RemoveEntryList(&CsrProcess->ListLink);
@@ -279,7 +386,7 @@ CsrProcessRefcountZero(IN PCSR_PROCESS CsrProcess)
}
/* Close the Client Port if there is one */
- if (CsrProcess->ClientPort ) NtClose(CsrProcess->ClientPort);
+ if (CsrProcess->ClientPort) NtClose(CsrProcess->ClientPort);
/* Close the process handle */
NtClose(CsrProcess->ProcessHandle);
@@ -289,9 +396,9 @@ CsrProcessRefcountZero(IN PCSR_PROCESS CsrProcess)
}
/*++
- * @name CsrSetToNormalPriority
+ * @name CsrpSetToNormalPriority
*
- * The CsrSetToNormalPriority routine sets the current NT Process'
+ * The CsrpSetToNormalPriority routine sets the current NT Process'
* priority to the normal priority for CSR Processes.
*
* @param None.
@@ -304,7 +411,7 @@ CsrProcessRefcountZero(IN PCSR_PROCESS CsrProcess)
*--*/
VOID
NTAPI
-CsrSetToNormalPriority(VOID)
+CsrpSetToNormalPriority(VOID)
{
KPRIORITY BasePriority = (8 + 1) + 4;
@@ -316,9 +423,9 @@ CsrSetToNormalPriority(VOID)
}
/*++
- * @name CsrSetToShutdownPriority
+ * @name CsrpSetToShutdownPriority
*
- * The CsrSetToShutdownPriority routine sets the current NT Process'
+ * The CsrpSetToShutdownPriority routine sets the current NT Process'
* priority to the boosted priority for CSR Processes doing shutdown.
* Additonally, it acquires the Shutdown Privilege required for shutdown.
*
@@ -332,7 +439,7 @@ CsrSetToNormalPriority(VOID)
*--*/
VOID
NTAPI
-CsrSetToShutdownPriority(VOID)
+CsrpSetToShutdownPriority(VOID)
{
KPRIORITY SetBasePriority = (8 + 1) + 6;
BOOLEAN Old;
@@ -367,24 +474,20 @@ CsrSetToShutdownPriority(VOID)
*--*/
PCSR_PROCESS
NTAPI
-FindProcessForShutdown(PLUID CallerLuid)
+FindProcessForShutdown(IN PLUID CallerLuid)
{
- PLIST_ENTRY ListHead, NextEntry;
+ PLIST_ENTRY NextEntry;
LUID ProcessLuid;
NTSTATUS Status;
LUID SystemLuid = SYSTEM_LUID;
PCSR_PROCESS CsrProcess;
PCSR_THREAD CsrThread;
- BOOLEAN IsSystemLuid = FALSE, IsOurLuid = FALSE;
PCSR_PROCESS ReturnCsrProcess = NULL;
ULONG Level = 0;
/* Set the List Pointers */
- ListHead = &CsrRootProcess->ListLink;
- NextEntry = ListHead->Flink;
-
- /* Start looping */
- while (NextEntry != ListHead)
+ NextEntry = CsrRootProcess->ListLink.Flink;
+ while (NextEntry != &CsrRootProcess->ListLink)
{
/* Get the process */
CsrProcess = CONTAINING_RECORD(NextEntry, CSR_PROCESS, ListLink);
@@ -422,19 +525,19 @@ FindProcessForShutdown(PLUID CallerLuid)
}
/* Check if this is the System LUID */
- if ((IsSystemLuid = RtlEqualLuid(&ProcessLuid, &SystemLuid)))
+ if (RtlEqualLuid(&ProcessLuid, &SystemLuid))
{
/* Mark this process */
CsrProcess->ShutdownFlags |= CsrShutdownSystem;
}
- else if (!(IsOurLuid = RtlEqualLuid(&ProcessLuid, CallerLuid)))
+ else if (!RtlEqualLuid(&ProcessLuid, CallerLuid))
{
/* Our LUID doesn't match with the caller's */
CsrProcess->ShutdownFlags |= CsrShutdownOther;
}
/* Check if we're past the previous level */
- if (CsrProcess->ShutdownLevel > Level)
+ if ((CsrProcess->ShutdownLevel > Level) || !(ReturnCsrProcess))
{
/* Update the level */
Level = CsrProcess->ShutdownLevel;
@@ -468,7 +571,7 @@ FindProcessForShutdown(PLUID CallerLuid)
*
* @param Arguments
* Description of the parameter. Wrapped to more lines on ~70th
- * column.
+ * column.
*
* @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
* othwerwise.
@@ -509,19 +612,16 @@ CsrCreateProcess(IN HANDLE hProcess,
}
/* Allocate a new Process Object */
- if (!(CsrProcess = CsrAllocateProcess()))
+ CsrProcess = CsrAllocateProcess();
+ if (!CsrProcess)
{
/* Couldn't allocate Process */
CsrReleaseProcessLock();
return STATUS_NO_MEMORY;
}
- /* Setup Process Data */
- CsrProcess->ClientId = *ClientId;
- CsrProcess->ProcessHandle = hProcess;
- CsrProcess->ShutdownLevel = 0x280;
-
/* Inherit the Process Data */
+ CurrentProcess = CurrentThread->Process;
ProcessData = &CurrentProcess->ServerData[CSR_SERVER_DLL_MAX];
for (i = 0; i < CSR_SERVER_DLL_MAX; i++)
{
@@ -540,7 +640,7 @@ CsrCreateProcess(IN HANDLE hProcess,
ProcessData = (PVOID)((ULONG_PTR)ProcessData +
CsrLoadedServerDll[i]->SizeOfProcessData);
}
- else
+ else
{
/* No data for this Server */
CsrProcess->ServerData[i] = NULL;
@@ -575,13 +675,13 @@ CsrCreateProcess(IN HANDLE hProcess,
}
/* Check if this is a console process */
- if(Flags & CsrProcessIsConsoleApp) CsrProcess->Flags |= CsrProcessIsConsoleApp;
+ if (Flags & CsrProcessIsConsoleApp) CsrProcess->Flags |= CsrProcessIsConsoleApp;
/* Mask out non-debug flags */
- Flags &= ~(CsrProcessIsConsoleApp | CsrProcessCreateNewGroup);
+ Flags &= ~(CsrProcessIsConsoleApp | CsrProcessCreateNewGroup | CsrProcessPriorityFlags);
/* Check if every process will be debugged */
- if (!Flags && CurrentProcess->DebugFlags & CsrDebugProcessChildren)
+ if (!(Flags) && (CurrentProcess->DebugFlags & CsrDebugProcessChildren))
{
/* Pass it on to the current process */
CsrProcess->DebugFlags = CsrDebugProcessChildren;
@@ -589,13 +689,13 @@ CsrCreateProcess(IN HANDLE hProcess,
}
/* Check if Debugging was used on this process */
- if (Flags & (CsrDebugOnlyThisProcess | CsrDebugProcessChildren))
+ if ((Flags & (CsrDebugOnlyThisProcess | CsrDebugProcessChildren)) && (DebugCid))
{
/* Save the debug flag used */
CsrProcess->DebugFlags = Flags;
/* Save the CID */
- if (DebugCid) CsrProcess->DebugCid = *DebugCid;
+ CsrProcess->DebugCid = *DebugCid;
}
/* Check if we debugging is enabled */
@@ -606,6 +706,7 @@ CsrCreateProcess(IN HANDLE hProcess,
ProcessDebugPort,
&CsrApiPort,
sizeof(HANDLE));
+ ASSERT(NT_SUCCESS(Status));
if (!NT_SUCCESS(Status))
{
/* Failed */
@@ -621,10 +722,17 @@ CsrCreateProcess(IN HANDLE hProcess,
(PVOID)&KernelTimes,
sizeof(KernelTimes),
NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ /* Failed */
+ CsrDeallocateProcess(CsrProcess);
+ CsrReleaseProcessLock();
+ return STATUS_NO_MEMORY;
+ }
/* Allocate a CSR Thread Structure */
CsrThread = CsrAllocateThread(CsrProcess);
- if (CsrThread == NULL)
+ if (!CsrThread)
{
/* Failed */
CsrDeallocateProcess(CsrProcess);
@@ -636,6 +744,7 @@ CsrCreateProcess(IN HANDLE hProcess,
CsrThread->CreateTime = KernelTimes.CreateTime;
CsrThread->ClientId = *ClientId;
CsrThread->ThreadHandle = hThread;
+ ProtectHandle(hThread);
CsrThread->Flags = 0;
/* Insert the Thread into the Process */
@@ -645,6 +754,11 @@ CsrCreateProcess(IN HANDLE hProcess,
CsrReferenceNtSession(NtSession);
CsrProcess->NtSession = NtSession;
+ /* Setup Process Data */
+ CsrProcess->ClientId = *ClientId;
+ CsrProcess->ProcessHandle = hProcess;
+ CsrProcess->ShutdownLevel = 0x280;
+
/* Set the Priority to Background */
CsrSetBackgroundPriority(CsrProcess);
@@ -664,7 +778,7 @@ CsrCreateProcess(IN HANDLE hProcess,
* exported only for compatibility with older CSR Server DLLs.
*
* @param CsrProcess
- * Deprecated.
+ * Deprecated.
*
* @return Deprecated
*
@@ -673,7 +787,7 @@ CsrCreateProcess(IN HANDLE hProcess,
*--*/
NTSTATUS
NTAPI
-CsrDebugProcess(PCSR_PROCESS CsrProcess)
+CsrDebugProcess(IN PCSR_PROCESS CsrProcess)
{
/* CSR does not handle debugging anymore */
DPRINT("CSRSRV: %s(%08lx) called\n", __FUNCTION__, CsrProcess);
@@ -688,7 +802,7 @@ CsrDebugProcess(PCSR_PROCESS CsrProcess)
* exported only for compatibility with older CSR Server DLLs.
*
* @param CsrProcess
- * Deprecated.
+ * Deprecated.
*
* @return Deprecated
*
@@ -697,7 +811,7 @@ CsrDebugProcess(PCSR_PROCESS CsrProcess)
*--*/
NTSTATUS
NTAPI
-CsrDebugProcessStop(PCSR_PROCESS CsrProcess)
+CsrDebugProcessStop(IN PCSR_PROCESS CsrProcess)
{
/* CSR does not handle debugging anymore */
DPRINT("CSRSRV: %s(%08lx) called\n", __FUNCTION__, CsrProcess);
@@ -721,13 +835,17 @@ CsrDebugProcessStop(PCSR_PROCESS CsrProcess)
*--*/
VOID
NTAPI
-CsrDereferenceProcess(PCSR_PROCESS CsrProcess)
+CsrDereferenceProcess(IN PCSR_PROCESS CsrProcess)
{
+ LONG LockCount;
+
/* Acquire process lock */
CsrAcquireProcessLock();
/* Decrease reference count */
- if (!(--CsrProcess->ReferenceCount))
+ LockCount = --CsrProcess->ReferenceCount;
+ ASSERT(LockCount >= 0);
+ if (!LockCount)
{
/* Call the generic cleanup code */
CsrProcessRefcountZero(CsrProcess);
@@ -743,12 +861,12 @@ CsrDereferenceProcess(PCSR_PROCESS CsrProcess)
* @name CsrDestroyProcess
* @implemented NT4
*
- * The CsrDestroyProcess routine destroys the CSR Process corresponding to
+ * The CsrDestroyProcess routine destroys the CSR Process corresponding to
* a given Client ID.
*
* @param Cid
* Pointer to the Client ID Structure corresponding to the CSR
- * Process which is about to be destroyed.
+ * Process which is about to be destroyed.
*
* @param ExitStatus
* Unused.
@@ -767,17 +885,16 @@ CsrDestroyProcess(IN PCLIENT_ID Cid,
PCSR_THREAD CsrThread;
PCSR_PROCESS CsrProcess;
CLIENT_ID ClientId = *Cid;
- PLIST_ENTRY ListHead, NextEntry;
+ PLIST_ENTRY NextEntry;
/* Acquire lock */
CsrAcquireProcessLock();
/* Find the thread */
- CsrThread = CsrLocateThreadByClientId(&CsrProcess,
- &ClientId);
+ CsrThread = CsrLocateThreadByClientId(&CsrProcess, &ClientId);
/* Make sure we got one back, and that it's not already gone */
- if (!CsrThread || CsrProcess->Flags & CsrProcessTerminating)
+ if (!(CsrThread) || (CsrProcess->Flags & CsrProcessTerminating))
{
/* Release the lock and return failure */
CsrReleaseProcessLock();
@@ -788,20 +905,18 @@ CsrDestroyProcess(IN PCLIENT_ID Cid,
CsrProcess->Flags |= CsrProcessTerminating;
/* Get the List Pointers */
- ListHead = &CsrProcess->ThreadList;
- NextEntry = ListHead->Flink;
-
- /* Loop the list */
- while (NextEntry != ListHead)
+ NextEntry = CsrProcess->ThreadList.Flink;
+ while (NextEntry != &CsrProcess->ThreadList)
{
/* Get the current thread entry */
CsrThread = CONTAINING_RECORD(NextEntry, CSR_THREAD, Link);
- /* Move to the next entry */
- NextEntry = NextEntry->Flink;
-
/* Make sure the thread isn't already dead */
- if (CsrThread->Flags & CsrThreadTerminated) continue;
+ if (CsrThread->Flags & CsrThreadTerminated)
+ {
+ NextEntry = NextEntry->Flink;
+ continue;
+ }
/* Set the Terminated flag */
CsrThread->Flags |= CsrThreadTerminated;
@@ -826,6 +941,7 @@ CsrDestroyProcess(IN PCLIENT_ID Cid,
/* Dereference the thread */
CsrLockedDereferenceThread(CsrThread);
+ NextEntry = CsrProcess->ThreadList.Flink;
}
/* Release the Process Lock and return success */
@@ -843,7 +959,7 @@ CsrDestroyProcess(IN PCLIENT_ID Cid,
* Optional handle to the process whose LUID should be returned.
*
* @param Luid
- * Pointer to a LUID Pointer which will receive the CSR Process' LUID
+ * Pointer to a LUID Pointer which will receive the CSR Process' LUID
*
* @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
* othwerwise.
@@ -891,11 +1007,7 @@ CsrGetProcessLuid(HANDLE hProcess OPTIONAL,
Status = NtOpenProcessToken(hProcess,
TOKEN_QUERY,
&hToken);
- if (!NT_SUCCESS(Status))
- {
- /* Still no token, return the error */
- return Status;
- }
+ if (!NT_SUCCESS(Status)) return Status;
}
/* Now get the size we'll need for the Token Information */
@@ -906,7 +1018,8 @@ CsrGetProcessLuid(HANDLE hProcess OPTIONAL,
&Length);
/* Allocate memory for the Token Info */
- if (!(TokenStats = RtlAllocateHeap(CsrHeap, 0, Length)))
+ TokenStats = RtlAllocateHeap(CsrHeap, 0, Length);
+ if (!TokenStats)
{
/* Fail and close the token */
NtClose(hToken);
@@ -923,12 +1036,8 @@ CsrGetProcessLuid(HANDLE hProcess OPTIONAL,
/* Close the handle */
NtClose(hToken);
- /* Check for success */
- if (NT_SUCCESS(Status))
- {
- /* Return the LUID */
- *Luid = TokenStats->AuthenticationId;
- }
+ /* Check for success to return the LUID */
+ if (NT_SUCCESS(Status)) *Luid = TokenStats->AuthenticationId;
/* Free the query information */
RtlFreeHeap(CsrHeap, 0, TokenStats);
@@ -961,51 +1070,45 @@ CsrGetProcessLuid(HANDLE hProcess OPTIONAL,
NTSTATUS
NTAPI
CsrLockProcessByClientId(IN HANDLE Pid,
- OUT PCSR_PROCESS *CsrProcess OPTIONAL)
+ OUT PCSR_PROCESS *CsrProcess)
{
- PLIST_ENTRY ListHead, NextEntry;
+ PLIST_ENTRY NextEntry;
PCSR_PROCESS CurrentProcess = NULL;
NTSTATUS Status = STATUS_UNSUCCESSFUL;
/* Acquire the lock */
CsrAcquireProcessLock();
- /* Setup the List Pointers */
- ListHead = &CsrRootProcess->ListLink;
- NextEntry = ListHead;
+ /* Assume failure */
+ ASSERT(CsrProcess != NULL);
+ *CsrProcess = NULL;
- /* Start Loop */
- while (NextEntry != ListHead)
+ /* Setup the List Pointers */
+ NextEntry = CsrRootProcess->ListLink.Flink;
+ while (NextEntry != &CsrRootProcess->ListLink)
{
/* Get the Process */
CurrentProcess = CONTAINING_RECORD(NextEntry, CSR_PROCESS, ListLink);
/* Check for PID Match */
- if (CurrentProcess->ClientId.UniqueProcess == Pid)
- {
- /* Get out of here with success */
- Status = STATUS_SUCCESS;
- break;
- }
+ if (CurrentProcess->ClientId.UniqueProcess == Pid) break;
/* Next entry */
NextEntry = NextEntry->Flink;
}
- /* Did the loop find something? */
- if (NT_SUCCESS(Status))
- {
- /* Lock the found process */
- CurrentProcess->ReferenceCount++;
- }
- else
+ /* Check if we didn't find it in the list */
+ if (NextEntry == &CsrRootProcess->ListLink)
{
/* Nothing found, release the lock */
CsrReleaseProcessLock();
+ return Status;
}
- /* Return the status and process */
- if (CsrProcess) *CsrProcess = CurrentProcess;
+ /* Lock the found process and return it */
+ Status = STATUS_SUCCESS;
+ CurrentProcess->ReferenceCount++;
+ *CsrProcess = CurrentProcess;
return Status;
}
@@ -1093,16 +1196,16 @@ CsrSetBackgroundPriority(IN PCSR_PROCESS CsrProcess)
*--*/
NTSTATUS
NTAPI
-CsrShutdownProcesses(PLUID CallerLuid,
- ULONG Flags)
+CsrShutdownProcesses(IN PLUID CallerLuid,
+ IN ULONG Flags)
{
- PLIST_ENTRY ListHead, NextEntry;
- PCSR_PROCESS CsrProcess = NULL;
- NTSTATUS Status = STATUS_UNSUCCESSFUL;
- BOOLEAN FirstTry = TRUE;
- ULONG i = 0;
- PCSR_SERVER_DLL ServerDll = NULL;
- ULONG Result = 0;
+ PLIST_ENTRY NextEntry;
+ PCSR_PROCESS CsrProcess;
+ NTSTATUS Status;
+ BOOLEAN FirstTry;
+ ULONG i;
+ PCSR_SERVER_DLL ServerDll;
+ ULONG Result;
/* Acquire process lock */
CsrAcquireProcessLock();
@@ -1111,11 +1214,8 @@ CsrShutdownProcesses(PLUID CallerLuid,
CsrRootProcess->ShutdownFlags |= CsrShutdownSystem;
/* Get the list pointers */
- ListHead = &CsrRootProcess->ListLink;
- NextEntry = ListHead->Flink;
-
- /* Start the loop */
- while (NextEntry != ListHead)
+ NextEntry = CsrRootProcess->ListLink.Flink;
+ while (NextEntry != &CsrRootProcess->ListLink)
{
/* Get the Process */
CsrProcess = CONTAINING_RECORD(NextEntry, CSR_PROCESS, ListLink);
@@ -1129,73 +1229,81 @@ CsrShutdownProcesses(PLUID CallerLuid,
}
/* Set shudown Priority */
- CsrSetToShutdownPriority();
+ CsrpSetToShutdownPriority();
/* Start looping */
while (TRUE)
{
/* Find the next process to shutdown */
- if (!(CsrProcess = FindProcessForShutdown(CallerLuid)))
- {
- /* Done, quit */
- CsrReleaseProcessLock();
- Status = STATUS_SUCCESS;
- goto Quickie;
- }
+ CsrProcess = FindProcessForShutdown(CallerLuid);
+ if (!CsrProcess) break;
/* Increase reference to process */
CsrProcess->ReferenceCount++;
-LoopAgain:
- /* Loop all the servers */
- for (i = 0; i < CSR_SERVER_DLL_MAX; i++)
+ FirstTry = TRUE;
+ while (TRUE)
{
- /* Get the current server */
- ServerDll = CsrLoadedServerDll[i];
- if (ServerDll && ServerDll->ShutdownProcessCallback)
+ /* Loop all the servers */
+ for (i = 0; i < CSR_SERVER_DLL_MAX; i++)
{
- /* Release the lock, make the callback, and acquire it back */
- CsrReleaseProcessLock();
- Result = (*ServerDll->ShutdownProcessCallback)(CsrProcess,
- Flags,
- FirstTry);
- CsrAcquireProcessLock();
-
- /* Check the result */
- if (Result == CsrShutdownCsrProcess)
+ /* Get the current server */
+ ServerDll = CsrLoadedServerDll[i];
+ if ((ServerDll) && (ServerDll->ShutdownProcessCallback))
{
- /* The callback unlocked the process */
- break;
- }
- else if (Result == CsrShutdownNonCsrProcess)
- {
- /* A non-CSR process, the callback didn't touch it */
- continue;
- }
- else if (Result == CsrShutdownCancelled)
- {
- /* Shutdown was cancelled, unlock and exit */
+ /* Release the lock, make the callback, and acquire it back */
CsrReleaseProcessLock();
- Status = STATUS_CANCELLED;
- goto Quickie;
+ Result = (*ServerDll->ShutdownProcessCallback)(CsrProcess,
+ Flags,
+ FirstTry);
+ CsrAcquireProcessLock();
+
+ /* Check the result */
+ if (Result == CsrShutdownCsrProcess)
+ {
+ /* The callback unlocked the process */
+ break;
+ }
+ else if (Result == CsrShutdownCancelled)
+ {
+ /* Check if this was a forced shutdown */
+ if (Flags & EWX_FORCE)
+ {
+ DPRINT1("Process %x cancelled forced shutdown (Dll = %d)\n",
+ CsrProcess->ClientId.UniqueProcess, i);
+ DbgBreakPoint();
+ }
+
+ /* Shutdown was cancelled, unlock and exit */
+ CsrReleaseProcessLock();
+ Status = STATUS_CANCELLED;
+ goto Quickie;
+ }
}
}
- }
- /* No matches during the first try, so loop again */
- if (FirstTry && Result == CsrShutdownNonCsrProcess)
- {
- FirstTry = FALSE;
- goto LoopAgain;
+ /* No matches during the first try, so loop again */
+ if ((FirstTry) && (Result == CsrShutdownNonCsrProcess))
+ {
+ FirstTry = FALSE;
+ continue;
+ }
+
+ /* Second try, break out */
+ break;
}
/* We've reached the final loop here, so dereference */
if (i == CSR_SERVER_DLL_MAX) CsrLockedDereferenceProcess(CsrProcess);
}
+ /* Success path */
+ CsrReleaseProcessLock();
+ Status = STATUS_SUCCESS;
+
Quickie:
/* Return to normal priority */
- CsrSetToNormalPriority();
+ CsrpSetToNormalPriority();
return Status;
}
@@ -1206,7 +1314,7 @@ Quickie:
* The CsrUnlockProcess undoes a previous CsrLockProcessByClientId operation.
*
* @param CsrProcess
- * Pointer to a previously locked CSR Process.
+ * Pointer to a previously locked CSR Process.
*
* @return STATUS_SUCCESS.
*
@@ -1215,7 +1323,7 @@ Quickie:
*--*/
NTSTATUS
NTAPI
-CsrUnlockProcess(PCSR_PROCESS CsrProcess)
+CsrUnlockProcess(IN PCSR_PROCESS CsrProcess)
{
/* Dereference the process */
CsrLockedDereferenceProcess(CsrProcess);
diff --git a/reactos/subsystems/csr/csrsrv/server.c b/reactos/subsystems/csr/csrsrv/server.c
index 2faad8f6264..91699cd0d02 100644
--- a/reactos/subsystems/csr/csrsrv/server.c
+++ b/reactos/subsystems/csr/csrsrv/server.c
@@ -78,40 +78,57 @@ CsrLoadServerDll(IN PCHAR DllString,
{
NTSTATUS Status;
ANSI_STRING DllName;
- UNICODE_STRING TempString;
+ UNICODE_STRING TempString, ErrorString;
+ ULONG_PTR Parameters[2];
HANDLE hServerDll = NULL;
ULONG Size;
PCSR_SERVER_DLL ServerDll;
STRING EntryPointString;
PCSR_SERVER_DLL_INIT_CALLBACK ServerDllInitProcedure;
+ ULONG Response;
/* Check if it's beyond the maximum we support */
- if (ServerId >= CSR_SERVER_DLL_MAX) return(STATUS_TOO_MANY_NAMES);
+ if (ServerId >= CSR_SERVER_DLL_MAX) return STATUS_TOO_MANY_NAMES;
/* Check if it's already been loaded */
- if (CsrLoadedServerDll[ServerId]) return(STATUS_INVALID_PARAMETER);
+ if (CsrLoadedServerDll[ServerId]) return STATUS_INVALID_PARAMETER;
/* Convert the name to Unicode */
+ ASSERT(DllString != NULL);
RtlInitAnsiString(&DllName, DllString);
Status = RtlAnsiStringToUnicodeString(&TempString, &DllName, TRUE);
+ if (!NT_SUCCESS(Status)) return Status;
/* If we are loading ourselves, don't actually load us */
if (ServerId != CSR_SRV_SERVER)
{
/* Load the DLL */
Status = LdrLoadDll(NULL, 0, &TempString, &hServerDll);
+ if (!NT_SUCCESS(Status))
+ {
+ /* Setup error parameters */
+ Parameters[0] = (ULONG_PTR)&TempString;
+ Parameters[1] = (ULONG_PTR)&ErrorString;
+ RtlInitUnicodeString(&ErrorString, L"Default Load Path");
+
+ /* Send a hard error */
+ NtRaiseHardError(Status,
+ 2,
+ 3,
+ Parameters,
+ OptionOk,
+ &Response);
+ }
/* Get rid of the string */
RtlFreeUnicodeString(&TempString);
- if (!NT_SUCCESS(Status))
- {
- return Status;
- }
+ if (!NT_SUCCESS(Status)) return Status;
}
/* Allocate a CSR DLL Object */
Size = sizeof(CSR_SERVER_DLL) + DllName.MaximumLength;
- if (!(ServerDll = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, Size)))
+ ServerDll = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, Size);
+ if (!ServerDll)
{
if (hServerDll) LdrUnloadDll(hServerDll);
return STATUS_NO_MEMORY;
@@ -135,7 +152,7 @@ CsrLoadServerDll(IN PCHAR DllString,
if (hServerDll)
{
/* Initialize a string for the entrypoint, or use the default */
- RtlInitAnsiString(&EntryPointString,
+ RtlInitAnsiString(&EntryPointString,
!(EntryPoint) ? "ServerDllInitialization" :
EntryPoint);
@@ -255,6 +272,7 @@ CsrSrvClientConnect(IN OUT PCSR_API_MESSAGE ApiMessage,
NTSTATUS Status;
PCSR_CLIENT_CONNECT ClientConnect;
PCSR_SERVER_DLL ServerDll;
+ PCSR_PROCESS CurrentProcess = ((PCSR_THREAD)NtCurrentTeb()->CsrClientThread)->Process;
/* Load the Message, set default reply */
ClientConnect = (PCSR_CLIENT_CONNECT)&ApiMessage->CsrClientConnect;
@@ -287,7 +305,7 @@ CsrSrvClientConnect(IN OUT PCSR_API_MESSAGE ApiMessage,
if (ServerDll->ConnectCallback)
{
/* Call the callback */
- Status = (ServerDll->ConnectCallback)(((PCSR_THREAD)NtCurrentTeb()->CsrClientThread)->Process,
+ Status = (ServerDll->ConnectCallback)(CurrentProcess,
ClientConnect->ConnectionInfo,
&ClientConnect->ConnectionInfoSize);
}
@@ -328,12 +346,15 @@ CsrSrvCreateSharedSection(IN PCHAR ParameterValue)
ULONG ViewSize = 0;
PPEB Peb = NtCurrentPeb();
+ /* If there's no parameter, fail */
+ if (ParameterValue) return STATUS_INVALID_PARAMETER;
+
/* Find the first comma, and null terminate */
while (*SizeValue)
{
if (*SizeValue == ',')
{
- *SizeValue++ = '\0';
+ *SizeValue++ = ANSI_NULL;
break;
}
else
@@ -343,12 +364,10 @@ CsrSrvCreateSharedSection(IN PCHAR ParameterValue)
}
/* Make sure it's valid */
- if (!*SizeValue) return(STATUS_INVALID_PARAMETER);
+ if (!*SizeValue) return STATUS_INVALID_PARAMETER;
/* Convert it to an integer */
- Status = RtlCharToInteger(SizeValue,
- 0,
- &Size);
+ Status = RtlCharToInteger(SizeValue, 0, &Size);
if (!NT_SUCCESS(Status)) return Status;
/* Multiply by 1024 entries and round to page size */
@@ -377,7 +396,7 @@ CsrSrvCreateSharedSection(IN PCHAR ParameterValue)
ViewUnmap,
MEM_TOP_DOWN,
PAGE_EXECUTE_READWRITE);
- if(!NT_SUCCESS(Status))
+ if (!NT_SUCCESS(Status))
{
/* Fail */
NtClose(CsrSrvSharedSection);
@@ -390,7 +409,7 @@ CsrSrvCreateSharedSection(IN PCHAR ParameterValue)
CsrSrvSharedSectionHeap = CsrSrvSharedSectionBase;
/* Create the heap */
- if (!(RtlCreateHeap(HEAP_ZERO_MEMORY,
+ if (!(RtlCreateHeap(HEAP_ZERO_MEMORY | HEAP_CLASS_7,
CsrSrvSharedSectionHeap,
CsrSrvSharedSectionSize,
PAGE_SIZE,
@@ -398,8 +417,7 @@ CsrSrvCreateSharedSection(IN PCHAR ParameterValue)
0)))
{
/* Failure, unmap section and return */
- NtUnmapViewOfSection(NtCurrentProcess(),
- CsrSrvSharedSectionBase);
+ NtUnmapViewOfSection(NtCurrentProcess(), CsrSrvSharedSectionBase);
NtClose(CsrSrvSharedSection);
return STATUS_NO_MEMORY;
}
@@ -409,6 +427,7 @@ CsrSrvCreateSharedSection(IN PCHAR ParameterValue)
0,
CSR_SERVER_DLL_MAX *
sizeof(PVOID));
+ if (!CsrSrvSharedStaticServerData) return STATUS_NO_MEMORY;
/* Write the values to the PEB */
Peb->ReadOnlySharedMemoryBase = CsrSrvSharedSectionBase;
@@ -621,7 +640,7 @@ CsrUnhandledExceptionFilter(IN PEXCEPTION_POINTERS ExceptionInfo)
(DebuggerInfo.KernelDebuggerEnabled))
{
/* Call the Unhandled Exception Filter */
- if ((Result = RtlUnhandledExceptionFilter(ExceptionInfo)) !=
+ if ((Result = RtlUnhandledExceptionFilter(ExceptionInfo)) !=
EXCEPTION_CONTINUE_EXECUTION)
{
/* We're going to raise an error. Get Shutdown Privilege first */
@@ -656,7 +675,7 @@ CsrUnhandledExceptionFilter(IN PEXCEPTION_POINTERS ExceptionInfo)
OptionShutdownSystem,
&Response);
}
-
+
/* Just terminate us */
NtTerminateProcess(NtCurrentProcess(),
ExceptionInfo->ExceptionRecord->ExceptionCode);
diff --git a/reactos/subsystems/csr/csrsrv/session.c b/reactos/subsystems/csr/csrsrv/session.c
index bbbe3a09c5c..2ec08a66a4f 100644
--- a/reactos/subsystems/csr/csrsrv/session.c
+++ b/reactos/subsystems/csr/csrsrv/session.c
@@ -14,6 +14,7 @@
#include
/* DATA **********************************************************************/
+
RTL_CRITICAL_SECTION CsrNtSessionLock;
LIST_ENTRY CsrNtSessionList;
HANDLE CsrSmApiPort;
@@ -39,31 +40,28 @@ PCHAR CsrServerSbApiName[5] =
/* PRIVATE FUNCTIONS *********************************************************/
/*++
- * @name CsrInitializeNtSessions
+ * @name CsrInitializeNtSessionList
*
- * The CsrInitializeNtSessions routine sets up support for CSR Sessions.
+ * The CsrInitializeNtSessionList routine sets up support for CSR Sessions.
*
* @param None
*
- * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
- * othwerwise.
+ * @return None
*
* @remarks None.
*
*--*/
NTSTATUS
NTAPI
-CsrInitializeNtSessions(VOID)
+CsrInitializeNtSessionList(VOID)
{
- NTSTATUS Status;
DPRINT("CSRSRV: %s called\n", __FUNCTION__);
/* Initialize the Session List */
InitializeListHead(&CsrNtSessionList);
/* Initialize the Session Lock */
- Status = RtlInitializeCriticalSection(&CsrNtSessionLock);
- return Status;
+ return RtlInitializeCriticalSection(&CsrNtSessionLock);
}
/*++
@@ -72,7 +70,7 @@ CsrInitializeNtSessions(VOID)
* The CsrAllocateNtSession routine allocates a new CSR NT Session.
*
* @param SessionId
- * Session ID of the CSR NT Session to allocate.
+ * Session ID of the CSR NT Session to allocate.
*
* @return Pointer to the newly allocated CSR NT Session.
*
@@ -81,26 +79,27 @@ CsrInitializeNtSessions(VOID)
*--*/
PCSR_NT_SESSION
NTAPI
-CsrAllocateNtSession(ULONG SessionId)
+CsrAllocateNtSession(IN ULONG SessionId)
{
PCSR_NT_SESSION NtSession;
/* Allocate an NT Session Object */
- NtSession = RtlAllocateHeap(CsrHeap,
- 0,
- sizeof(CSR_NT_SESSION));
-
- /* Setup the Session Object */
+ NtSession = RtlAllocateHeap(CsrHeap, 0, sizeof(CSR_NT_SESSION));
if (NtSession)
{
+ /* Setup the Session Object */
NtSession->SessionId = SessionId;
NtSession->ReferenceCount = 1;
/* Insert it into the Session List */
CsrAcquireNtSessionLock();
- InsertHeadList(&CsrNtSessionList, &NtSession->SessionList);
+ InsertHeadList(&CsrNtSessionList, &NtSession->SessionLink);
CsrReleaseNtSessionLock();
}
+ else
+ {
+ ASSERT(NtSession != NULL);
+ }
/* Return the Session (or NULL) */
return NtSession;
@@ -112,7 +111,7 @@ CsrAllocateNtSession(ULONG SessionId)
* The CsrReferenceNtSession increases the reference count of a CSR NT Session.
*
* @param Session
- * Pointer to the CSR NT Session to reference.
+ * Pointer to the CSR NT Session to reference.
*
* @return None.
*
@@ -121,11 +120,16 @@ CsrAllocateNtSession(ULONG SessionId)
*--*/
VOID
NTAPI
-CsrReferenceNtSession(PCSR_NT_SESSION Session)
+CsrReferenceNtSession(IN PCSR_NT_SESSION Session)
{
/* Acquire the lock */
CsrAcquireNtSessionLock();
+ /* Sanity checks */
+ ASSERT(!IsListEmpty(&Session->SessionLink));
+ ASSERT(Session->SessionId != 0);
+ ASSERT(Session->ReferenceCount != 0);
+
/* Increase the reference count */
Session->ReferenceCount++;
@@ -140,8 +144,8 @@ CsrReferenceNtSession(PCSR_NT_SESSION Session)
* CSR NT Session.
*
* @param Session
- * Pointer to the CSR NT Session to reference.
- *
+ * Pointer to the CSR NT Session to reference.
+ *
* @param ExitStatus
* If this is the last reference to the session, this argument
* specifies the exit status.
@@ -154,17 +158,22 @@ CsrReferenceNtSession(PCSR_NT_SESSION Session)
*--*/
VOID
NTAPI
-CsrDereferenceNtSession(PCSR_NT_SESSION Session,
- NTSTATUS ExitStatus)
+CsrDereferenceNtSession(IN PCSR_NT_SESSION Session,
+ IN NTSTATUS ExitStatus)
{
/* Acquire the lock */
CsrAcquireNtSessionLock();
+ /* Sanity checks */
+ ASSERT(!IsListEmpty(&Session->SessionLink));
+ ASSERT(Session->SessionId != 0);
+ ASSERT(Session->ReferenceCount != 0);
+
/* Dereference the Session Object */
if (!(--Session->ReferenceCount))
{
/* Remove it from the list */
- RemoveEntryList(&Session->SessionList);
+ RemoveEntryList(&Session->SessionLink);
/* Release the lock */
CsrReleaseNtSessionLock();
@@ -202,9 +211,9 @@ CsrDereferenceNtSession(PCSR_NT_SESSION Session,
*--*/
BOOLEAN
NTAPI
-CsrSbCreateSession(IN PSB_API_MESSAGE ApiMessage)
+CsrSbCreateSession(IN PSB_API_MSG ApiMessage)
{
- PSB_CREATE_SESSION CreateSession = &ApiMessage->SbCreateSession;
+ PSB_CREATE_SESSION_MSG CreateSession = &ApiMessage->CreateSession;
HANDLE hProcess, hThread;
PCSR_PROCESS CsrProcess;
NTSTATUS Status;
@@ -221,18 +230,15 @@ CsrSbCreateSession(IN PSB_API_MESSAGE ApiMessage)
CsrAcquireProcessLock();
/* Allocate a new process */
- if (!(CsrProcess = CsrAllocateProcess()))
+ CsrProcess = CsrAllocateProcess();
+ if (!CsrProcess)
{
/* Fail */
- ApiMessage->Status = STATUS_NO_MEMORY;
+ ApiMessage->ReturnValue = STATUS_NO_MEMORY;
CsrReleaseProcessLock();
return TRUE;
}
- /* Setup Process Data */
- CsrProcess->ClientId = CreateSession->ProcessInfo.ClientId;
- CsrProcess->ProcessHandle = hProcess;
-
/* Set the exception port */
Status = NtSetInformationProcess(hProcess,
ProcessExceptionPort,
@@ -264,15 +270,17 @@ CsrSbCreateSession(IN PSB_API_MESSAGE ApiMessage)
CsrDeallocateProcess(CsrProcess);
CsrReleaseProcessLock();
+ /* Strange as it seems, NTSTATUSes are actually returned */
return (BOOLEAN)Status;
}
/* Allocate a new Thread */
- if (!(CsrThread = CsrAllocateThread(CsrProcess)))
+ CsrThread = CsrAllocateThread(CsrProcess);
+ if (!CsrThread)
{
/* Fail the request */
CsrDeallocateProcess(CsrProcess);
- ApiMessage->Status = STATUS_NO_MEMORY;
+ ApiMessage->ReturnValue = STATUS_NO_MEMORY;
CsrReleaseProcessLock();
return TRUE;
}
@@ -281,12 +289,15 @@ CsrSbCreateSession(IN PSB_API_MESSAGE ApiMessage)
CsrThread->CreateTime = KernelTimes.CreateTime;
CsrThread->ClientId = CreateSession->ProcessInfo.ClientId;
CsrThread->ThreadHandle = hThread;
+ ProtectHandle(hThread);
CsrThread->Flags = 0;
/* Insert it into the Process List */
CsrInsertThread(CsrProcess, CsrThread);
- /* Allocate a new Session */
+ /* Setup Process Data */
+ CsrProcess->ClientId = CreateSession->ProcessInfo.ClientId;
+ CsrProcess->ProcessHandle = hProcess;
CsrProcess->NtSession = CsrAllocateNtSession(CreateSession->SessionId);
/* Set the Process Priority */
@@ -319,7 +330,7 @@ CsrSbCreateSession(IN PSB_API_MESSAGE ApiMessage)
CsrInsertProcess(NULL, NULL, CsrProcess);
/* Activate the Thread */
- ApiMessage->Status = NtResumeThread(hThread, NULL);
+ ApiMessage->ReturnValue = NtResumeThread(hThread, NULL);
/* Release lock and return */
CsrReleaseProcessLock();
@@ -342,10 +353,55 @@ CsrSbCreateSession(IN PSB_API_MESSAGE ApiMessage)
*--*/
BOOLEAN
NTAPI
-CsrSbForeignSessionComplete(IN PSB_API_MESSAGE ApiMessage)
+CsrSbForeignSessionComplete(IN PSB_API_MSG ApiMessage)
{
/* Deprecated/Unimplemented in NT */
- ApiMessage->Status = STATUS_NOT_IMPLEMENTED;
+ ApiMessage->ReturnValue = STATUS_NOT_IMPLEMENTED;
return TRUE;
}
+
+/*++
+ * @name CsrSbTerminateSession
+ *
+ * The CsrSbTerminateSession API is called by the Session Manager
+ * whenever a foreign session should be destroyed.
+ *
+ * @param ApiMessage
+ * Pointer to the Session Manager API Message.
+ *
+ * @return TRUE in case of success, FALSE othwerwise.
+ *
+ * @remarks The CsrSbTerminateSession API is not yet implemented.
+ *
+ *--*/
+BOOLEAN
+NTAPI
+CsrSbTerminateSession(IN PSB_API_MSG ApiMessage)
+{
+ ApiMessage->ReturnValue = STATUS_NOT_IMPLEMENTED;
+ return TRUE;
+}
+
+/*++
+ * @name CsrSbCreateProcess
+ *
+ * The CsrSbCreateProcess API is called by the Session Manager
+ * whenever a foreign session is created and a new process should be started.
+ *
+ * @param ApiMessage
+ * Pointer to the Session Manager API Message.
+ *
+ * @return TRUE in case of success, FALSE othwerwise.
+ *
+ * @remarks The CsrSbCreateProcess API is not yet implemented.
+ *
+ *--*/
+BOOLEAN
+NTAPI
+CsrSbCreateProcess(IN PSB_API_MSG ApiMessage)
+{
+ ApiMessage->ReturnValue = STATUS_NOT_IMPLEMENTED;
+ return TRUE;
+}
+
/* EOF */
diff --git a/reactos/subsystems/csr/csrsrv/srv.h b/reactos/subsystems/csr/csrsrv/srv.h
index 8c55942630f..3f59a486d28 100644
--- a/reactos/subsystems/csr/csrsrv/srv.h
+++ b/reactos/subsystems/csr/csrsrv/srv.h
@@ -10,6 +10,7 @@
/* CSR Header */
#include
+#include
/* PSEH for SEH Support */
#include
@@ -38,6 +39,9 @@
#define CsrHashThread(t) \
(HandleToUlong(t)&(256 - 1))
+
+#define ProcessStructureListLocked() \
+ (CsrProcessLock.OwningThread == NtCurrentTeb()->ClientId.UniqueThread)
#define SM_REG_KEY \
L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Session Manager"
@@ -72,10 +76,18 @@ extern SYSTEM_BASIC_INFORMATION CsrNtSysInfo;
extern UNICODE_STRING CsrDirectoryName;
extern HANDLE CsrObjectDirectory;
extern PSB_API_ROUTINE CsrServerSbApiDispatch[5];
+extern ULONG CsrDebug;
/* FUNCTIONS *****************************************************************/
/* FIXME: Public APIs should go in the CSR Server Include */
+BOOLEAN
+NTAPI
+CsrCaptureArguments(
+ IN PCSR_THREAD CsrThread,
+ IN PCSR_API_MESSAGE ApiMessage
+);
+
NTSTATUS
NTAPI
CsrLoadServerDll(
@@ -91,6 +103,18 @@ CsrServerInitialization(
PCHAR Arguments[]
);
+BOOLEAN
+NTAPI
+UnProtectHandle(IN HANDLE ObjectHandle);
+
+VOID
+NTAPI
+CsrLockedReferenceProcess(IN PCSR_PROCESS CsrProcess);
+
+VOID
+NTAPI
+CsrLockedReferenceThread(IN PCSR_THREAD CsrThread);
+
NTSTATUS
NTAPI
CsrCreateSessionObjectDirectory(IN ULONG SessionId);
@@ -105,11 +129,11 @@ CsrSrvCreateSharedSection(IN PCHAR ParameterValue);
NTSTATUS
NTAPI
-CsrInitializeNtSessions(VOID);
+CsrInitializeNtSessionList(VOID);
NTSTATUS
NTAPI
-CsrInitializeProcesses(VOID);
+CsrInitializeProcessStructure(VOID);
NTSTATUS
NTAPI
@@ -121,19 +145,19 @@ CsrSbApiPortInitialize(VOID);
BOOLEAN
NTAPI
-CsrSbCreateSession(IN PSB_API_MESSAGE ApiMessage);
+CsrSbCreateSession(IN PSB_API_MSG ApiMessage);
BOOLEAN
NTAPI
-CsrSbTerminateSession(IN PSB_API_MESSAGE ApiMessage);
+CsrSbTerminateSession(IN PSB_API_MSG ApiMessage);
BOOLEAN
NTAPI
-CsrSbForeignSessionComplete(IN PSB_API_MESSAGE ApiMessage);
+CsrSbForeignSessionComplete(IN PSB_API_MSG ApiMessage);
BOOLEAN
NTAPI
-CsrSbCreateProcess(IN PSB_API_MESSAGE ApiMessage);
+CsrSbCreateProcess(IN PSB_API_MSG ApiMessage);
PCSR_PROCESS
NTAPI
@@ -254,6 +278,10 @@ NTSTATUS
NTAPI
CsrApiRequestThread(IN PVOID Parameter);
+BOOLEAN
+NTAPI
+ProtectHandle(IN HANDLE ObjectHandle);
+
PCSR_THREAD
NTAPI
CsrAddStaticServerThread(
@@ -275,7 +303,7 @@ CsrLocateThreadInProcess(
NTSTATUS
NTAPI
-CsrSbApiHandleConnectionRequest(IN PSB_API_MESSAGE Message);
+CsrSbApiHandleConnectionRequest(IN PSB_API_MSG Message);
NTSTATUS
NTAPI
diff --git a/reactos/subsystems/csr/csrsrv/status.h b/reactos/subsystems/csr/csrsrv/status.h
index c9ff9aa3aca..e619443abd3 100644
--- a/reactos/subsystems/csr/csrsrv/status.h
+++ b/reactos/subsystems/csr/csrsrv/status.h
@@ -59,7 +59,7 @@
* CsrMoveSatisfiedWait 753E7909 20 - wait.c - IMPLEMENTED
* CsrNotifyWait 753E782F 21 - wait.c - IMPLEMENTED
* CsrPopulateDosDevices 753E37A5 22 - init.c - IMPLEMENTED
- * CsrQueryApiPort 753E4E42 23 - api.c - UNIMPLEMENTED
+ * CsrQueryApiPort 753E4E42 23 - api.c - IMPLEMENTED
* CsrReferenceThread 753E61E5 24 - thread.c - IMPLEMENTED
* CsrRevertToSelf 753E615A 25 - thread.c - IMPLEMENTED
* CsrServerInitialization 753E3D75 26 - server.c - IMPLEMENTED
@@ -93,7 +93,7 @@
* - SMSS needs to be partly re-written to match some things done here.
* Among other things, SmConnectToSm, SmCompleteSession and the other
* Sm* Exported APIs have to be properly implemented, as well as the
- * callback calling and SM LPC APIs. [NOT DONE]
+ * callback calling and SM LPC APIs. [DONE!]
*
* - NTDLL needs to get the Csr* routines properly implemented. [DONE!]
*
diff --git a/reactos/subsystems/csr/csrsrv/thread.c b/reactos/subsystems/csr/csrsrv/thread.c
index ad71435589c..c03f61d82b0 100644
--- a/reactos/subsystems/csr/csrsrv/thread.c
+++ b/reactos/subsystems/csr/csrsrv/thread.c
@@ -47,7 +47,7 @@ CsrAllocateThread(IN PCSR_PROCESS CsrProcess)
/* Allocate the structure */
CsrThread = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, sizeof(CSR_THREAD));
- if (!CsrThread) return(NULL);
+ if (!CsrThread) return NULL;
/* Reference the Thread and Process */
CsrThread->ReferenceCount++;
@@ -86,24 +86,24 @@ CsrLocateThreadByClientId(OUT PCSR_PROCESS *Process OPTIONAL,
IN PCLIENT_ID ClientId)
{
ULONG i;
- PLIST_ENTRY ListHead, NextEntry;
+ PLIST_ENTRY NextEntry;
PCSR_THREAD FoundThread;
+ ASSERT(ProcessStructureListLocked());
/* Hash the Thread */
i = CsrHashThread(ClientId->UniqueThread);
-
+
/* Set the list pointers */
- ListHead = &CsrThreadHashTable[i];
- NextEntry = ListHead->Flink;
+ NextEntry = CsrThreadHashTable[i].Flink;
/* Star the loop */
- while (NextEntry != ListHead)
+ while (NextEntry != &CsrThreadHashTable[i])
{
/* Get the thread */
FoundThread = CONTAINING_RECORD(NextEntry, CSR_THREAD, HashLinks);
/* Compare the CID */
- if (FoundThread->ClientId.UniqueThread == ClientId->UniqueThread)
+ if (*(PULONGLONG)&FoundThread->ClientId == *(PULONGLONG)ClientId)
{
/* Match found, return the process */
*Process = FoundThread->Process;
@@ -123,7 +123,7 @@ CsrLocateThreadByClientId(OUT PCSR_PROCESS *Process OPTIONAL,
/*++
* @name CsrLocateThreadInProcess
*
- * The CsrLocateThreadInProcess routine locates the CSR Thread
+ * The CsrLocateThreadInProcess routine locates the CSR Thread
* corresponding to a Client ID inside a specific CSR Process.
*
* @param Process
@@ -146,18 +146,17 @@ NTAPI
CsrLocateThreadInProcess(IN PCSR_PROCESS CsrProcess OPTIONAL,
IN PCLIENT_ID Cid)
{
- PLIST_ENTRY ListHead, NextEntry;
+ PLIST_ENTRY NextEntry;
PCSR_THREAD FoundThread = NULL;
/* Use the Root Process if none was specified */
if (!CsrProcess) CsrProcess = CsrRootProcess;
/* Save the List pointers */
- ListHead = &CsrProcess->ThreadList;
- NextEntry = ListHead->Flink;
+ NextEntry = CsrProcess->ThreadList.Flink;
/* Start the Loop */
- while (NextEntry != ListHead)
+ while (NextEntry != &CsrProcess->ThreadList)
{
/* Get Thread Entry */
FoundThread = CONTAINING_RECORD(NextEntry, CSR_THREAD, Link);
@@ -196,6 +195,7 @@ CsrInsertThread(IN PCSR_PROCESS Process,
IN PCSR_THREAD Thread)
{
ULONG i;
+ ASSERT(ProcessStructureListLocked());
/* Insert it into the Regular List */
InsertTailList(&Process->ThreadList, &Thread->Link);
@@ -230,9 +230,32 @@ NTAPI
CsrDeallocateThread(IN PCSR_THREAD CsrThread)
{
/* Free the process object from the heap */
+ ASSERT(CsrThread->WaitBlock == NULL);
RtlFreeHeap(CsrHeap, 0, CsrThread);
}
+/*++
+ * @name CsrLockedReferenceThread
+ *
+ * The CsrLockedReferenceThread refences a CSR Thread while the
+ * Process Lock is already being held.
+ *
+ * @param CsrThread
+ * Pointer to the CSR Thread to be referenced.
+ *
+ * @return None.
+ *
+ * @remarks This routine will return with the Process Lock held.
+ *
+ *--*/
+VOID
+NTAPI
+CsrLockedReferenceThread(IN PCSR_THREAD CsrThread)
+{
+ /* Increment the reference count */
+ ++CsrThread->ReferenceCount;
+}
+
/*++
* @name CsrLockedDereferenceThread
*
@@ -249,10 +272,14 @@ CsrDeallocateThread(IN PCSR_THREAD CsrThread)
*--*/
VOID
NTAPI
-CsrLockedDereferenceThread(PCSR_THREAD CsrThread)
+CsrLockedDereferenceThread(IN PCSR_THREAD CsrThread)
{
+ LONG LockCount;
+
/* Decrease reference count */
- if (!(--CsrThread->ReferenceCount))
+ LockCount = --CsrThread->ReferenceCount;
+ ASSERT(LockCount >= 0);
+ if (!LockCount)
{
/* Call the generic cleanup code */
CsrThreadRefcountZero(CsrThread);
@@ -267,7 +294,7 @@ CsrLockedDereferenceThread(PCSR_THREAD CsrThread)
* removes the CSR Thread from the the Hash Table and Thread List.
*
* @param CsrThread
- * Pointer to the CSR Thread to remove.
+ * Pointer to the CSR Thread to remove.
*
* @return None.
*
@@ -283,11 +310,13 @@ VOID
NTAPI
CsrRemoveThread(IN PCSR_THREAD CsrThread)
{
+ ASSERT(ProcessStructureListLocked());
+
/* Remove it from the List */
RemoveEntryList(&CsrThread->Link);
/* Decreate the thread count of the process */
- CsrThread->Process->ThreadCount--;
+ --CsrThread->Process->ThreadCount;
/* Remove it from the Hash List as well */
if (CsrThread->HashLinks.Flink) RemoveEntryList(&CsrThread->HashLinks);
@@ -333,6 +362,7 @@ NTAPI
CsrThreadRefcountZero(IN PCSR_THREAD CsrThread)
{
PCSR_PROCESS CsrProcess = CsrThread->Process;
+ NTSTATUS Status;
/* Remove this thread */
CsrRemoveThread(CsrThread);
@@ -341,8 +371,10 @@ CsrThreadRefcountZero(IN PCSR_THREAD CsrThread)
CsrReleaseProcessLock();
/* Close the NT Thread Handle */
- NtClose(CsrThread->ThreadHandle);
-
+ UnProtectHandle(CsrThread->ThreadHandle);
+ Status = NtClose(CsrThread->ThreadHandle);
+ ASSERT(NT_SUCCESS(Status));
+
/* De-allocate the CSR Thread Object */
CsrDeallocateThread(CsrThread);
@@ -388,10 +420,12 @@ CsrAddStaticServerThread(IN HANDLE hThread,
CsrAcquireProcessLock();
/* Allocate the Server Thread */
- if ((CsrThread = CsrAllocateThread(CsrRootProcess)))
+ CsrThread = CsrAllocateThread(CsrRootProcess);
+ if (CsrThread)
{
/* Setup the Object */
CsrThread->ThreadHandle = hThread;
+ ProtectHandle(hThread);
CsrThread->ClientId = *ClientId;
CsrThread->Flags = ThreadFlags;
@@ -401,6 +435,10 @@ CsrAddStaticServerThread(IN HANDLE hThread,
/* Increment the thread count */
CsrRootProcess->ThreadCount++;
}
+ else
+ {
+ DPRINT1("CsrAddStaticServerThread: alloc failed for thread 0x%x\n", hThread);
+ }
/* Release the Process Lock and return */
CsrReleaseProcessLock();
@@ -420,7 +458,7 @@ CsrAddStaticServerThread(IN HANDLE hThread,
*
* @param ClientId
* Pointer to the Client ID structure of the NT Thread to associate
- * with this CSR Thread.
+ * with this CSR Thread.
*
* @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
* othwerwise.
@@ -444,13 +482,13 @@ CsrCreateRemoteThread(IN HANDLE hThread,
/* Get the Thread Create Time */
Status = NtQueryInformationThread(hThread,
ThreadTimes,
- (PVOID)&KernelTimes,
+ &KernelTimes,
sizeof(KernelTimes),
NULL);
+ if (!NT_SUCCESS(Status)) return Status;
/* Lock the Owner Process */
- Status = CsrLockProcessByClientId(&ClientId->UniqueProcess,
- &CsrProcess);
+ Status = CsrLockProcessByClientId(&ClientId->UniqueProcess, &CsrProcess);
/* Make sure the thread didn't terminate */
if (KernelTimes.ExitTime.QuadPart)
@@ -461,7 +499,8 @@ CsrCreateRemoteThread(IN HANDLE hThread,
}
/* Allocate a CSR Thread Structure */
- if (!(CsrThread = CsrAllocateThread(CsrProcess)))
+ CsrThread = CsrAllocateThread(CsrProcess);
+ if (!CsrThread)
{
DPRINT1("CSRSRV:%s: out of memory!\n", __FUNCTION__);
CsrUnlockProcess(CsrProcess);
@@ -483,6 +522,7 @@ CsrCreateRemoteThread(IN HANDLE hThread,
CsrThread->CreateTime = KernelTimes.CreateTime;
CsrThread->ClientId = *ClientId;
CsrThread->ThreadHandle = ThreadHandle;
+ ProtectHandle(ThreadHandle);
CsrThread->Flags = 0;
/* Insert the Thread into the Process */
@@ -508,7 +548,7 @@ CsrCreateRemoteThread(IN HANDLE hThread,
*
* @param ClientId
* Pointer to the Client ID structure of the NT Thread to associate
- * with this CSR Thread.
+ * with this CSR Thread.
*
* @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
* othwerwise.
@@ -520,33 +560,38 @@ NTSTATUS
NTAPI
CsrCreateThread(IN PCSR_PROCESS CsrProcess,
IN HANDLE hThread,
- IN PCLIENT_ID ClientId)
+ IN PCLIENT_ID ClientId,
+ IN BOOLEAN HaveClient)
{
NTSTATUS Status;
- PCSR_THREAD CsrThread;
+ PCSR_THREAD CsrThread, CurrentThread;
PCSR_PROCESS CurrentProcess;
- PCSR_THREAD CurrentThread = NtCurrentTeb()->CsrClientThread;
CLIENT_ID CurrentCid;
KERNEL_USER_TIMES KernelTimes;
-
DPRINT("CSRSRV: %s called\n", __FUNCTION__);
- /* Get the current thread and CID */
- CurrentCid = CurrentThread->ClientId;
-
- /* Acquire the Process Lock */
- CsrAcquireProcessLock();
-
- /* Get the current Process and make sure the Thread is valid with this CID */
- CurrentThread = CsrLocateThreadByClientId(&CurrentProcess,
- &CurrentCid);
-
- /* Something is wrong if we get an empty thread back */
- if (!CurrentThread)
+ if (HaveClient)
{
- DPRINT1("CSRSRV:%s: invalid thread!\n", __FUNCTION__);
- CsrReleaseProcessLock();
- return STATUS_THREAD_IS_TERMINATING;
+ /* Get the current thread and CID */
+ CurrentThread = NtCurrentTeb()->CsrClientThread;
+ CurrentCid = CurrentThread->ClientId;
+
+ /* Acquire the Process Lock */
+ CsrAcquireProcessLock();
+
+ /* Get the current Process and make sure the Thread is valid with this CID */
+ CurrentThread = CsrLocateThreadByClientId(&CurrentProcess, &CurrentCid);
+ if (!CurrentThread)
+ {
+ DPRINT1("CSRSRV:%s: invalid thread!\n", __FUNCTION__);
+ CsrReleaseProcessLock();
+ return STATUS_THREAD_IS_TERMINATING;
+ }
+ }
+ else
+ {
+ /* Acquire the Process Lock */
+ CsrAcquireProcessLock();
}
/* Get the Thread Create Time */
@@ -555,9 +600,15 @@ CsrCreateThread(IN PCSR_PROCESS CsrProcess,
(PVOID)&KernelTimes,
sizeof(KernelTimes),
NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ CsrReleaseProcessLock();
+ return Status;
+ }
/* Allocate a CSR Thread Structure */
- if (!(CsrThread = CsrAllocateThread(CsrProcess)))
+ CsrThread = CsrAllocateThread(CsrProcess);
+ if (!CsrThread)
{
DPRINT1("CSRSRV:%s: out of memory!\n", __FUNCTION__);
CsrReleaseProcessLock();
@@ -568,6 +619,7 @@ CsrCreateThread(IN PCSR_PROCESS CsrProcess,
CsrThread->CreateTime = KernelTimes.CreateTime;
CsrThread->ClientId = *ClientId;
CsrThread->ThreadHandle = hThread;
+ ProtectHandle(hThread);
CsrThread->Flags = 0;
/* Insert the Thread into the Process */
@@ -595,12 +647,13 @@ CsrCreateThread(IN PCSR_PROCESS CsrProcess,
*--*/
VOID
NTAPI
-CsrDereferenceThread(PCSR_THREAD CsrThread)
+CsrDereferenceThread(IN PCSR_THREAD CsrThread)
{
/* Acquire process lock */
CsrAcquireProcessLock();
/* Decrease reference count */
+ ASSERT(CsrThread->ReferenceCount > 0);
if (!(--CsrThread->ReferenceCount))
{
/* Call the generic cleanup code */
@@ -624,7 +677,7 @@ CsrDereferenceThread(PCSR_THREAD CsrThread)
* Pointer to the thread's startup routine.
*
* @param Flags
- * Initial CSR Thread Flags to set to the CSR Thread.
+ * Initial CSR Thread Flags to set to the CSR Thread.
*
* @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
* othwerwise.
@@ -648,7 +701,9 @@ CsrExecServerThread(IN PVOID ThreadHandler,
CsrAcquireProcessLock();
/* Allocate a CSR Thread in the Root Process */
- if (!(CsrThread = CsrAllocateThread(CsrRootProcess)))
+ ASSERT(CsrRootProcess != NULL);
+ CsrThread = CsrAllocateThread(CsrRootProcess);
+ if (!CsrThread)
{
/* Fail */
CsrReleaseProcessLock();
@@ -676,6 +731,7 @@ CsrExecServerThread(IN PVOID ThreadHandler,
/* Setup the Thread Object */
CsrThread->ThreadHandle = hThread;
+ ProtectHandle(hThread);
CsrThread->ClientId = ClientId;
CsrThread->Flags = Flags;
@@ -694,12 +750,12 @@ CsrExecServerThread(IN PVOID ThreadHandler,
* @name CsrDestroyThread
* @implemented NT4
*
- * The CsrDestroyThread routine destroys the CSR Thread corresponding to
+ * The CsrDestroyThread routine destroys the CSR Thread corresponding to
* a given Thread ID.
*
* @param Cid
* Pointer to the Client ID Structure corresponding to the CSR
- * Thread which is about to be destroyed.
+ * Thread which is about to be destroyed.
*
* @return STATUS_SUCCESS in case of success, STATUS_THREAD_IS_TERMINATING
* if the CSR Thread is already terminating.
@@ -766,7 +822,7 @@ CsrDestroyThread(IN PCLIENT_ID Cid)
* The CsrImpersonateClient will impersonate the given CSR Thread.
*
* @param CsrThread
- * Pointer to the CSR Thread to impersonate.
+ * Pointer to the CSR Thread to impersonate.
*
* @return TRUE if impersionation suceeded, false otherwise.
*
@@ -784,27 +840,21 @@ CsrImpersonateClient(IN PCSR_THREAD CsrThread)
if (!CsrThread) CsrThread = CurrentThread;
/* Still no thread, something is wrong */
- if (!CsrThread)
- {
- /* Failure */
- return FALSE;
- }
+ if (!CsrThread) return FALSE;
/* Make the call */
Status = NtImpersonateThread(NtCurrentThread(),
CsrThread->ThreadHandle,
&CsrSecurityQos);
-
if (!NT_SUCCESS(Status))
{
- /* Failure */
+ DPRINT1("CSRSS: Can't impersonate client thread - Status = %lx\n", Status);
+ if (Status != STATUS_BAD_IMPERSONATION_LEVEL) DbgBreakPoint();
return FALSE;
}
- /* Increase the impersonation count for the current thread */
+ /* Increase the impersonation count for the current thread and return */
if (CurrentThread) ++CurrentThread->ImpersonationCount;
-
- /* Return Success */
return TRUE;
}
@@ -814,7 +864,7 @@ CsrImpersonateClient(IN PCSR_THREAD CsrThread)
*
* The CsrRevertToSelf routine will attempt to remove an active impersonation.
*
- * @param None.
+ * @param None.
*
* @return TRUE if the reversion was succesful, false otherwise.
*
@@ -837,6 +887,8 @@ CsrRevertToSelf(VOID)
/* Make sure impersonation is on */
if (!CurrentThread->ImpersonationCount)
{
+ DPRINT1("CSRSS: CsrRevertToSelf called while not impersonating\n");
+ DbgBreakPoint();
return FALSE;
}
else if (--CurrentThread->ImpersonationCount > 0)
@@ -853,6 +905,7 @@ CsrRevertToSelf(VOID)
sizeof(HANDLE));
/* Return TRUE or FALSE */
+ ASSERT(NT_SUCCESS(Status));
return NT_SUCCESS(Status);
}
@@ -880,9 +933,9 @@ CsrRevertToSelf(VOID)
NTSTATUS
NTAPI
CsrLockThreadByClientId(IN HANDLE Tid,
- OUT PCSR_THREAD *CsrThread OPTIONAL)
+ OUT PCSR_THREAD *CsrThread)
{
- PLIST_ENTRY ListHead, NextEntry;
+ PLIST_ENTRY NextEntry;
PCSR_THREAD CurrentThread = NULL;
NTSTATUS Status = STATUS_UNSUCCESSFUL;
ULONG i;
@@ -890,15 +943,18 @@ CsrLockThreadByClientId(IN HANDLE Tid,
/* Acquire the lock */
CsrAcquireProcessLock();
+ /* Assume failure */
+ ASSERT(CsrThread != NULL);
+ *CsrThread = NULL;
+
/* Convert to Hash */
i = CsrHashThread(Tid);
/* Setup the List Pointers */
- ListHead = &CsrThreadHashTable[i];
- NextEntry = ListHead;
+ NextEntry = CsrThreadHashTable[i].Flink;
/* Start Loop */
- while (NextEntry != ListHead)
+ while (NextEntry != &CsrThreadHashTable[i])
{
/* Get the Process */
CurrentThread = CONTAINING_RECORD(NextEntry, CSR_THREAD, HashLinks);
@@ -907,8 +963,7 @@ CsrLockThreadByClientId(IN HANDLE Tid,
if ((CurrentThread->ClientId.UniqueThread == Tid) &&
!(CurrentThread->Flags & CsrThreadTerminated))
{
- /* Get out of here with success */
- Status = STATUS_SUCCESS;
+ /* Get out of here */
break;
}
@@ -916,20 +971,25 @@ CsrLockThreadByClientId(IN HANDLE Tid,
NextEntry = NextEntry->Flink;
}
+ /* Nothing found if we got back to the list */
+ if (NextEntry == &CsrThreadHashTable[i]) CurrentThread = NULL;
+
/* Did the loop find something? */
- if (NT_SUCCESS(Status))
+ if (CurrentThread)
{
/* Reference the found thread */
+ Status = STATUS_SUCCESS;
CurrentThread->ReferenceCount++;
+ *CsrThread = CurrentThread;
}
else
{
/* Nothing found, release the lock */
+ Status = STATUS_UNSUCCESSFUL;
CsrReleaseProcessLock();
}
- /* Return the status and thread */
- if (CsrThread) *CsrThread = CurrentThread;
+ /* Return the status */
return Status;
}
@@ -937,11 +997,11 @@ CsrLockThreadByClientId(IN HANDLE Tid,
* @name CsrReferenceThread
* @implemented NT4
*
- * The CsrReferenceThread routine increases the active reference count of
+ * The CsrReferenceThread routine increases the active reference count of
* a CSR Thread.
*
* @param CsrThread
- * Pointer to the CSR Thread whose reference count will be increased.
+ * Pointer to the CSR Thread whose reference count will be increased.
*
* @return None.
*
@@ -955,6 +1015,10 @@ CsrReferenceThread(PCSR_THREAD CsrThread)
/* Acquire process lock */
CsrAcquireProcessLock();
+ /* Sanity checks */
+ ASSERT(CsrThread->Flags & CsrThreadTerminated); // CSR_THREAD_DESTROYED in ASSERT
+ ASSERT(CsrThread->ReferenceCount != 0);
+
/* Increment reference count */
CsrThread->ReferenceCount++;
@@ -969,7 +1033,7 @@ CsrReferenceThread(PCSR_THREAD CsrThread)
* The CsrUnlockThread undoes a previous CsrLockThreadByClientId operation.
*
* @param CsrThread
- * Pointer to a previously locked CSR Thread.
+ * Pointer to a previously locked CSR Thread.
*
* @return STATUS_SUCCESS.
*
@@ -981,6 +1045,7 @@ NTAPI
CsrUnlockThread(PCSR_THREAD CsrThread)
{
/* Dereference the Thread */
+ ASSERT(ProcessStructureListLocked());
CsrLockedDereferenceThread(CsrThread);
/* Release the lock and return */
diff --git a/reactos/subsystems/csr/csrsrv/wait.c b/reactos/subsystems/csr/csrsrv/wait.c
index 08a840245d0..00d0bdf3108 100644
--- a/reactos/subsystems/csr/csrsrv/wait.c
+++ b/reactos/subsystems/csr/csrsrv/wait.c
@@ -62,7 +62,8 @@ CsrInitializeWait(IN CSR_WAIT_FUNCTION WaitFunction,
WaitApiMessage->Header.u1.s1.TotalLength;
/* Allocate the Wait Block */
- if (!(WaitBlock = RtlAllocateHeap(CsrHeap, 0, Size)))
+ WaitBlock = RtlAllocateHeap(CsrHeap, 0, Size);
+ if (!WaitBlock)
{
/* Fail */
WaitApiMessage->Status = STATUS_NO_MEMORY;
@@ -74,8 +75,9 @@ CsrInitializeWait(IN CSR_WAIT_FUNCTION WaitFunction,
WaitBlock->WaitThread = CsrWaitThread;
WaitBlock->WaitContext = WaitContext;
WaitBlock->WaitFunction = WaitFunction;
- InitializeListHead(&WaitBlock->UserWaitList);
- InitializeListHead(&WaitBlock->WaitList);
+ WaitBlock->UserWaitList.Flink = NULL;
+ WaitBlock->UserWaitList.Blink = NULL;
+ WaitBlock->WaitList = WaitBlock->UserWaitList;
/* Copy the message */
RtlMoveMemory(&WaitBlock->WaitApiMessage,
@@ -173,7 +175,7 @@ CsrNotifyWaitBlock(IN PCSR_WAIT_BLOCK WaitBlock,
WaitBlock->WaitFunction = NULL;
}
- /* The wait suceeded*/
+ /* The wait suceeded */
return TRUE;
}
@@ -237,10 +239,9 @@ CsrCreateWait(IN PLIST_ENTRY WaitList,
CsrAcquireWaitLock();
/* Make sure the thread wasn't destroyed */
- if (CsrWaitThread && (CsrWaitThread->Flags & CsrThreadTerminated))
+ if (CsrWaitThread->Flags & CsrThreadTerminated)
{
/* Fail the wait */
- CsrWaitThread->WaitBlock = NULL;
RtlFreeHeap(CsrHeap, 0, WaitBlock);
CsrReleaseWaitLock();
return FALSE;
@@ -275,7 +276,7 @@ VOID
NTAPI
CsrDereferenceWait(IN PLIST_ENTRY WaitList)
{
- PLIST_ENTRY ListHead, NextEntry;
+ PLIST_ENTRY NextEntry;
PCSR_WAIT_BLOCK WaitBlock;
/* Acquire the Process and Wait Locks */
@@ -283,11 +284,10 @@ CsrDereferenceWait(IN PLIST_ENTRY WaitList)
CsrAcquireWaitLock();
/* Set the list pointers */
- ListHead = WaitList;
- NextEntry = ListHead->Flink;
+ NextEntry = WaitList->Flink;
/* Start the loop */
- while (NextEntry != ListHead)
+ while (NextEntry != WaitList)
{
/* Get the wait block */
WaitBlock = CONTAINING_RECORD(NextEntry, CSR_WAIT_BLOCK, WaitList);
@@ -346,18 +346,17 @@ NTAPI
CsrMoveSatisfiedWait(IN PLIST_ENTRY NewEntry,
IN PLIST_ENTRY WaitList)
{
- PLIST_ENTRY ListHead, NextEntry;
+ PLIST_ENTRY NextEntry;
PCSR_WAIT_BLOCK WaitBlock;
/* Acquire the Wait Lock */
CsrAcquireWaitLock();
/* Set the List pointers */
- ListHead = WaitList;
- NextEntry = ListHead->Flink;
+ NextEntry = WaitList->Flink;
/* Start looping */
- while (NextEntry != ListHead)
+ while (NextEntry != WaitList)
{
/* Get the Wait block */
WaitBlock = CONTAINING_RECORD(NextEntry, CSR_WAIT_BLOCK, WaitList);
@@ -407,7 +406,7 @@ CsrNotifyWait(IN PLIST_ENTRY WaitList,
IN PVOID WaitArgument1,
IN PVOID WaitArgument2)
{
- PLIST_ENTRY ListHead, NextEntry;
+ PLIST_ENTRY NextEntry;
PCSR_WAIT_BLOCK WaitBlock;
BOOLEAN NotifySuccess = FALSE;
@@ -415,11 +414,10 @@ CsrNotifyWait(IN PLIST_ENTRY WaitList,
CsrAcquireWaitLock();
/* Set the List pointers */
- ListHead = WaitList;
- NextEntry = ListHead->Flink;
+ NextEntry = WaitList->Flink;
/* Start looping */
- while (NextEntry != ListHead)
+ while (NextEntry != WaitList)
{
/* Get the Wait block */
WaitBlock = CONTAINING_RECORD(NextEntry, CSR_WAIT_BLOCK, WaitList);
diff --git a/reactos/subsystems/csr/main.c b/reactos/subsystems/csr/main.c
index b52f028274f..af89bec210e 100644
--- a/reactos/subsystems/csr/main.c
+++ b/reactos/subsystems/csr/main.c
@@ -1,22 +1,3 @@
-/* $Id$
- * --------------------------------------------------------------------
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * --------------------------------------------------------------------
- */
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS CSR Sub System