Author: ion
Date: Wed Feb 15 19:53:31 2012
New Revision: 55615

URL: http://svn.reactos.org/svn/reactos?rev=55615&view=rev
Log:
[CSRSRV]: Remove the CSRAPI Heap and just use the CSR Heap. In the future there 
will be separate DLLs each with their own heap, but now it's all one DLL.
[CSRSRV]: Port CsrSbApiRequestThread, CsrSbApiHandleConnectionRequest and all 
the Sb* APIs from CSRSRV2. Comment out parts that can't work yet.
[CSRSRV]; Port CsrSbApiPortInitialize, CsrSetProcessSecurity, 
CsrCreateLocalSystemSD, and almost all of CsrServerInitialization. 
Initialization is almost identical to CSRSRV2 now.
[CSRSRV]: Kill "Complete" routine support, nobody was using this.

Modified:
    trunk/reactos/subsystems/win32/csrss/csrsrv/api/process.c
    trunk/reactos/subsystems/win32/csrss/csrsrv/api/wapi.c
    trunk/reactos/subsystems/win32/csrss/csrsrv/init.c
    trunk/reactos/subsystems/win32/csrss/include/api.h
    trunk/reactos/subsystems/win32/csrss/win32csr/dllmain.c

Modified: trunk/reactos/subsystems/win32/csrss/csrsrv/api/process.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/csrss/csrsrv/api/process.c?rev=55615&r1=55614&r2=55615&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/csrss/csrsrv/api/process.c [iso-8859-1] 
(original)
+++ trunk/reactos/subsystems/win32/csrss/csrsrv/api/process.c [iso-8859-1] Wed 
Feb 15 19:53:31 2012
@@ -83,7 +83,7 @@
    }
    if (pProcessData == NULL)
    {
-      pProcessData = RtlAllocateHeap(CsrssApiHeap,
+      pProcessData = RtlAllocateHeap(CsrHeap,
                                     HEAP_ZERO_MEMORY,
                                     sizeof(CSRSS_PROCESS_DATA));
       if (pProcessData)
@@ -109,7 +109,7 @@
          if (!NT_SUCCESS(Status))
          {
             ProcessData[hash] = pProcessData->next;
-           RtlFreeHeap(CsrssApiHeap, 0, pProcessData);
+           RtlFreeHeap(CsrHeap, 0, pProcessData);
            pProcessData = NULL;
          }
          else
@@ -187,7 +187,7 @@
 
       *pPrevLink = pProcessData->next;
 
-      RtlFreeHeap(CsrssApiHeap, 0, pProcessData);
+      RtlFreeHeap(CsrHeap, 0, pProcessData);
       UNLOCK;
       if (Process)
         {

Modified: trunk/reactos/subsystems/win32/csrss/csrsrv/api/wapi.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/csrss/csrsrv/api/wapi.c?rev=55615&r1=55614&r2=55615&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/csrss/csrsrv/api/wapi.c [iso-8859-1] 
(original)
+++ trunk/reactos/subsystems/win32/csrss/csrsrv/api/wapi.c [iso-8859-1] Wed Feb 
15 19:53:31 2012
@@ -19,10 +19,17 @@
 
 extern HANDLE hApiPort;
 
-HANDLE CsrssApiHeap = (HANDLE) 0;
-
 static unsigned ApiDefinitionsCount = 0;
 static PCSRSS_API_DEFINITION ApiDefinitions = NULL;
+
+PCHAR CsrServerSbApiName[5] =
+{
+    "SbCreateSession",
+    "SbTerminateSession",
+    "SbForeignSessionComplete",
+    "SbCreateProcess",
+    "Unknown Csr Sb Api Number"
+};
 
 /* FUNCTIONS *****************************************************************/
 
@@ -41,7 +48,7 @@
       NewCount++;
     }
 
-  New = RtlAllocateHeap(CsrssApiHeap, 0,
+  New = RtlAllocateHeap(CsrHeap, 0,
                         (ApiDefinitionsCount + NewCount)
                         * sizeof(CSRSS_API_DEFINITION));
   if (NULL == New)
@@ -53,7 +60,7 @@
     {
       RtlCopyMemory(New, ApiDefinitions,
                     ApiDefinitionsCount * sizeof(CSRSS_API_DEFINITION));
-      RtlFreeHeap(CsrssApiHeap, 0, ApiDefinitions);
+      RtlFreeHeap(CsrHeap, 0, ApiDefinitions);
     }
   RtlCopyMemory(New + ApiDefinitionsCount, NewDefinitions,
                 NewCount * sizeof(CSRSS_API_DEFINITION));
@@ -180,7 +187,6 @@
 
     /* Multiply by 1024 entries and round to page size */
     CsrSrvSharedSectionSize = ROUND_UP(Size * 1024, CsrNtSysInfo.PageSize);
-    DPRINT1("Size: %lx\n", CsrSrvSharedSectionSize);
 
     /* Create the Secion */
     SectionSize.LowPart = CsrSrvSharedSectionSize;
@@ -980,115 +986,391 @@
     RtlExitUserThread(STATUS_SUCCESS);
 }
 
-/**********************************************************************
- * NAME
- *     ServerSbApiPortThread/1
- *
- * DESCRIPTION
- *     Handle connection requests from SM to the port
- *     "\Windows\SbApiPort". We will accept only one
- *     connection request (from the SM).
- */
-DWORD WINAPI
-ServerSbApiPortThread (HANDLE hSbApiPortListen)
-{
-    HANDLE          hConnectedPort = (HANDLE) 0;
-    SB_API_MSG    Request;
-    PVOID           Context = NULL;
-    NTSTATUS        Status = STATUS_SUCCESS;
-    PPORT_MESSAGE Reply = NULL;
-
-    DPRINT("CSR: %s called\n", __FUNCTION__);
-
-    RtlZeroMemory(&Request, sizeof(PORT_MESSAGE));
-    Status = NtListenPort (hSbApiPortListen, & Request.h);
-
+/* SESSION MANAGER FUNCTIONS**************************************************/
+
+/*++
+ * @name CsrSbCreateSession
+ *
+ * The CsrSbCreateSession API is called by the Session Manager whenever a new
+ * session is created.
+ *
+ * @param ApiMessage
+ *        Pointer to the Session Manager API Message.
+ *
+ * @return TRUE in case of success, FALSE othwerwise.
+ *
+ * @remarks The CsrSbCreateSession routine will initialize a new CSR NT
+ *          Session and allocate a new CSR Process for the subsystem process.
+ *
+ *--*/
+BOOLEAN
+NTAPI
+CsrSbCreateSession(IN PSB_API_MSG ApiMessage)
+{
+    PSB_CREATE_SESSION_MSG CreateSession = &ApiMessage->CreateSession;
+    HANDLE hProcess, hThread;
+//    PCSR_PROCESS CsrProcess;
+    NTSTATUS Status;
+    KERNEL_USER_TIMES KernelTimes;
+    //PCSR_THREAD CsrThread;
+    //PVOID ProcessData;
+    //ULONG i;
+
+    /* Save the Process and Thread Handles */
+    hProcess = CreateSession->ProcessInfo.ProcessHandle;
+    hThread = CreateSession->ProcessInfo.ThreadHandle;
+
+#if 0
+    /* Lock the Processes */
+    CsrAcquireProcessLock();
+
+    /* Allocate a new process */
+    CsrProcess = CsrAllocateProcess();
+    if (!CsrProcess)
+    {
+        /* Fail */
+        ApiMessage->ReturnValue = STATUS_NO_MEMORY;
+        CsrReleaseProcessLock();
+        return TRUE;
+    }
+#endif
+
+    /* Set the exception port */
+    Status = NtSetInformationProcess(hProcess,
+                                     ProcessExceptionPort,
+                                     &hApiPort,//&CsrApiPort,
+                                     sizeof(HANDLE));
+
+    /* Check for success */
     if (!NT_SUCCESS(Status))
     {
-        DPRINT1("CSR: %s: NtListenPort(SB) failed (Status=0x%08lx)\n",
-                __FUNCTION__, Status);
-    } else {
-        DPRINT("-- 1\n");
-        Status = NtAcceptConnectPort(&hConnectedPort,
-                                     NULL,
-                                     &Request.h,
-                                     TRUE,
-                                     NULL,
-                                     NULL);
-        if(!NT_SUCCESS(Status))
-        {
-            DPRINT1("CSR: %s: NtAcceptConnectPort() failed (Status=0x%08lx)\n",
-                    __FUNCTION__, Status);
-        } else {
-            DPRINT("-- 2\n");
-            Status = NtCompleteConnectPort (hConnectedPort);
-            if(!NT_SUCCESS(Status))
+        /* Fail the request */
+#if 0
+        CsrDeallocateProcess(CsrProcess);
+        CsrReleaseProcessLock();
+#endif
+        /* Strange as it seems, NTSTATUSes are actually returned */
+        return (BOOLEAN)STATUS_NO_MEMORY;
+    }
+
+    /* Get the Create Time */
+    Status = NtQueryInformationThread(hThread,
+                                      ThreadTimes,
+                                      &KernelTimes,
+                                      sizeof(KERNEL_USER_TIMES),
+                                      NULL);
+
+    /* Check for success */
+    if (!NT_SUCCESS(Status))
+    {
+        /* Fail the request */
+#if 0
+        CsrDeallocateProcess(CsrProcess);
+        CsrReleaseProcessLock();
+#endif
+
+        /* Strange as it seems, NTSTATUSes are actually returned */
+        return (BOOLEAN)Status;
+    }
+
+    /* Allocate a new Thread */
+#if 0
+    CsrThread = CsrAllocateThread(CsrProcess);
+    if (!CsrThread)
+    {
+        /* Fail the request */
+        CsrDeallocateProcess(CsrProcess);
+        CsrReleaseProcessLock();
+
+        ApiMessage->ReturnValue = STATUS_NO_MEMORY;
+        return TRUE;
+    }
+
+    /* Setup the Thread Object */
+    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);
+
+    /* Setup Process Data */
+    CsrProcess->ClientId = CreateSession->ProcessInfo.ClientId;
+    CsrProcess->ProcessHandle = hProcess;
+    CsrProcess->NtSession = CsrAllocateNtSession(CreateSession->SessionId);
+
+    /* Set the Process Priority */
+    CsrSetBackgroundPriority(CsrProcess);
+
+    /* Get the first data location */
+    ProcessData = &CsrProcess->ServerData[CSR_SERVER_DLL_MAX];
+
+    /* Loop every DLL */
+    for (i = 0; i < CSR_SERVER_DLL_MAX; i++)
+    {
+        /* Check if the DLL is loaded and has Process Data */
+        if (CsrLoadedServerDll[i] && CsrLoadedServerDll[i]->SizeOfProcessData)
+        {
+            /* Write the pointer to the data */
+            CsrProcess->ServerData[i] = ProcessData;
+
+            /* Move to the next data location */
+            ProcessData = (PVOID)((ULONG_PTR)ProcessData +
+                                  CsrLoadedServerDll[i]->SizeOfProcessData);
+        }
+        else
+        {
+            /* Nothing for this Process */
+            CsrProcess->ServerData[i] = NULL;
+        }
+    }
+
+    /* Insert the Process */
+    CsrInsertProcess(NULL, NULL, CsrProcess);
+#endif
+    /* Activate the Thread */
+    ApiMessage->ReturnValue = NtResumeThread(hThread, NULL);
+
+    /* Release lock and return */
+//    CsrReleaseProcessLock();
+    return TRUE;
+}
+
+/*++
+ * @name CsrSbForeignSessionComplete
+ *
+ * The CsrSbForeignSessionComplete API is called by the Session Manager
+ * whenever a foreign session is completed (ie: terminated).
+ *
+ * @param ApiMessage
+ *        Pointer to the Session Manager API Message.
+ *
+ * @return TRUE in case of success, FALSE othwerwise.
+ *
+ * @remarks The CsrSbForeignSessionComplete API is not yet implemented.
+ *
+ *--*/
+BOOLEAN
+NTAPI
+CsrSbForeignSessionComplete(IN PSB_API_MSG ApiMessage)
+{
+    /* Deprecated/Unimplemented in NT */
+    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;
+}
+
+PSB_API_ROUTINE CsrServerSbApiDispatch[5] =
+{
+    CsrSbCreateSession,
+    CsrSbTerminateSession,
+    CsrSbForeignSessionComplete,
+    CsrSbCreateProcess,
+    NULL
+};
+
+/*++
+ * @name CsrSbApiHandleConnectionRequest
+ *
+ * The CsrSbApiHandleConnectionRequest routine handles and accepts a new
+ * connection request to the SM API LPC Port.
+ *
+ * @param ApiMessage
+ *        Pointer to the incoming CSR API Message which contains the
+ *        connection request.
+ *
+ * @return STATUS_SUCCESS in case of success, or status code which caused
+ *         the routine to error.
+ *
+ * @remarks None.
+ *
+ *--*/
+NTSTATUS
+NTAPI
+CsrSbApiHandleConnectionRequest(IN PSB_API_MSG Message)
+{
+    NTSTATUS Status;
+    REMOTE_PORT_VIEW RemotePortView;
+    HANDLE hPort;
+
+    /* Set the Port View Structure Length */
+    RemotePortView.Length = sizeof(REMOTE_PORT_VIEW);
+
+    /* Accept the connection */
+    Status = NtAcceptConnectPort(&hPort,
+                                 NULL,
+                                 (PPORT_MESSAGE)Message,
+                                 TRUE,
+                                 NULL,
+                                 &RemotePortView);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("CSRSS: Sb Accept Connection failed %lx\n", Status);
+        return Status;
+    }
+
+    /* Complete the Connection */
+    Status = NtCompleteConnectPort(hPort);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("CSRSS: Sb Complete Connection failed %lx\n",Status);
+    }
+
+    /* Return status */
+    return Status;
+}
+
+/*++
+ * @name CsrSbApiRequestThread
+ *
+ * The CsrSbApiRequestThread routine handles incoming messages or connection
+ * requests on the SM API LPC Port.
+ *
+ * @param Parameter
+ *        System-default user-defined parameter. Unused.
+ *
+ * @return The thread exit code, if the thread is terminated.
+ *
+ * @remarks Before listening on the port, the routine will first attempt
+ *          to connect to the user subsystem.
+ *
+ *--*/
+VOID
+NTAPI
+CsrSbApiRequestThread(IN PVOID Parameter)
+{
+    NTSTATUS Status;
+    SB_API_MSG ReceiveMsg;
+    PSB_API_MSG ReplyMsg = NULL;
+    PVOID PortContext;
+    ULONG MessageType;
+
+    /* Start the loop */
+    while (TRUE)
+    {
+        /* Wait for a message to come in */
+        Status = NtReplyWaitReceivePort(CsrSbApiPort,
+                                        &PortContext,
+                                        &ReplyMsg->h,
+                                        &ReceiveMsg.h);
+
+        /* Check if we didn't get 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.h.u2.s2.Type;
+
+        /* Check if this is a connection request */
+        if (MessageType == LPC_CONNECTION_REQUEST)
+        {
+            /* Handle connection request */
+            CsrSbApiHandleConnectionRequest(&ReceiveMsg);
+
+            /* Start over */
+            ReplyMsg = NULL;
+            continue;
+        }
+
+        /* Check if the port died */
+        if (MessageType == LPC_PORT_CLOSED)
+        {
+            /* Close the handle if we have one */
+            if (PortContext) NtClose((HANDLE)PortContext);
+
+            /* Client died, start over */
+            ReplyMsg = NULL;
+            continue;
+        }
+        else if (MessageType == LPC_CLIENT_DIED)
+        {
+            /* Client died, start over */
+            ReplyMsg = NULL;
+            continue;
+        }
+
+        /*
+         * 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.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.ApiNumber < SbpMaxApiNumber)
+        {
+            /* Call the API */
+            if (!CsrServerSbApiDispatch[ReceiveMsg.ApiNumber](&ReceiveMsg))
             {
-                DPRINT1("CSR: %s: NtCompleteConnectPort() failed 
(Status=0x%08lx)\n",
-                        __FUNCTION__, Status);
-            } else {
-                DPRINT("-- 3\n");
-                /*
-                 * Tell the init thread the SM gave the
-                 * green light for boostrapping.
-                 */
-                Status = NtSetEvent (hBootstrapOk, NULL);
-                if(!NT_SUCCESS(Status))
-                {
-                    DPRINT1("CSR: %s: NtSetEvent failed (Status=0x%08lx)\n",
-                            __FUNCTION__, Status);
-                }
-                /* Wait for messages from the SM */
-                DPRINT("-- 4\n");
-                while (TRUE)
-                {
-                    Status = NtReplyWaitReceivePort(hConnectedPort,
-                                                    Context,
-                                                    Reply,
-                                                    &Request.h);
-                    if(!NT_SUCCESS(Status))
-                    {
-                        DPRINT1("CSR: %s: NtReplyWaitReceivePort failed 
(Status=0x%08lx)\n",
-                                __FUNCTION__, Status);
-                        break;
-                    }
-
-                    switch (Request.h.u2.s2.Type) //fix .h 
PORT_MESSAGE_TYPE(Request))
-                    {
-                        /* TODO */
-                        case LPC_PORT_CLOSED:
-                        case LPC_CLIENT_DIED:
-                            DPRINT1("CSR: SMSS died\n");
-                            Reply = NULL;
-                            break;
-
-                        default:
-                        DPRINT1("CSR: %s received message (type=%d)\n",
-                                __FUNCTION__, Request.h.u2.s2.Type);
-
-                        if (Request.ApiNumber == SbpCreateSession)
-                        {
-                            DPRINT("Session create... legacy CSRSS resuming 
thread as minimum work done\n");
-                            Request.ReturnValue = 
NtResumeThread(Request.CreateSession.ProcessInfo.ThreadHandle, NULL);
-                        }
-                        else
-                        {
-                            DPRINT1("CSR: %d Not implemented in legacy 
CSRSS... faking success\n", Request.ApiNumber);
-                            Request.ReturnValue = STATUS_SUCCESS;
-                        }
-                        Reply = &Request.h;
-                    }
-                    DPRINT("-- 5\n");
-                }
+                /* It failed, so return nothing */
+                ReplyMsg = NULL;
             }
         }
-    }
-
-    DPRINT("CSR: %s: terminating!\n", __FUNCTION__);
-    if(hConnectedPort) NtClose (hConnectedPort);
-    NtClose (hSbApiPortListen);
-    NtTerminateThread (NtCurrentThread(), Status);
-    return 0;
+        else
+        {
+            /* We don't support this API Number */
+            ReplyMsg->ReturnValue = STATUS_NOT_IMPLEMENTED;
+        }
+    }
 }
 
 /* EOF */

Modified: trunk/reactos/subsystems/win32/csrss/csrsrv/init.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/csrss/csrsrv/init.c?rev=55615&r1=55614&r2=55615&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/csrss/csrsrv/init.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/csrss/csrsrv/init.c [iso-8859-1] Wed Feb 15 
19:53:31 2012
@@ -17,12 +17,13 @@
 HANDLE CsrHeap = (HANDLE) 0;
 HANDLE CsrObjectDirectory = (HANDLE) 0;
 UNICODE_STRING CsrDirectoryName;
-extern HANDLE CsrssApiHeap;
+UNICODE_STRING CsrSbApiPortName;
+HANDLE CsrSbApiPort = 0;
+PCSR_THREAD CsrSbApiRequestThreadPtr;
 static unsigned ServerProcCount;
 static CSRPLUGIN_SERVER_PROCS *ServerProcs = NULL;
+HANDLE CsrSmApiPort;
 HANDLE hSbApiPort = (HANDLE) 0;
-HANDLE hBootstrapOk = (HANDLE) 0;
-HANDLE hSmApiPort = (HANDLE) 0;
 HANDLE hApiPort = (HANDLE) 0;
 ULONG CsrDebug = 0xFFFFFFFF;
 ULONG CsrMaxApiRequestThreads;
@@ -31,6 +32,8 @@
 HANDLE BNOLinksDirectory;
 HANDLE SessionObjectDirectory;
 HANDLE DosDevicesDirectory;
+HANDLE CsrInitializationEvent;
+SYSTEM_BASIC_INFORMATION CsrNtSysInfo;
 
 /* PRIVATE FUNCTIONS 
**********************************************************/
 
@@ -41,7 +44,7 @@
 
   DPRINT("CSR: %s called\n", __FUNCTION__);
 
-  NewProcs = RtlAllocateHeap(CsrssApiHeap, 0,
+  NewProcs = RtlAllocateHeap(CsrHeap, 0,
                              (ServerProcCount + 1)
                              * sizeof(CSRPLUGIN_SERVER_PROCS));
   if (NULL == NewProcs)
@@ -52,33 +55,13 @@
     {
       RtlCopyMemory(NewProcs, ServerProcs,
                     ServerProcCount * sizeof(CSRPLUGIN_SERVER_PROCS));
-      RtlFreeHeap(CsrssApiHeap, 0, ServerProcs);
+      RtlFreeHeap(CsrHeap, 0, ServerProcs);
     }
   NewProcs[ServerProcCount] = *Procs;
   ServerProcs = NewProcs;
   ServerProcCount++;
 
   return STATUS_SUCCESS;
-}
-
-/**********************************************************************
- * CallInitComplete/0
- */
-static BOOL FASTCALL
-CallInitComplete(void)
-{
-  BOOL Ok;
-  unsigned i;
-
-  DPRINT("CSR: %s called\n", __FUNCTION__);
-
-  Ok = TRUE;
-  for (i = 0; i < ServerProcCount && Ok; i++)
-    {
-      Ok = (*ServerProcs[i].InitCompleteProc)();
-    }
-
-  return Ok;
 }
 
 BOOL
@@ -167,7 +150,7 @@
       return Status;
     }
   Exports.CsrEnumProcessesProc = CsrEnumProcesses;
-  if (! (*InitProc)(&ApiDefinitions, &ServerProcs, &Exports, CsrssApiHeap))
+  if (! (*InitProc)(&ApiDefinitions, &ServerProcs, &Exports, CsrHeap))
     {
       return STATUS_UNSUCCESSFUL;
     }
@@ -233,12 +216,12 @@
                                *Port,
                                &ServerThread,
                                &ClientId);
-    
+
     if (ListenThread == (PVOID)ClientConnectionThread)
     {
         CsrAddStaticServerThread(ServerThread, &ClientId, 0);
     }
-    
+
     NtResumeThread(ServerThread, NULL);
     NtClose(ServerThread);
        return Status;
@@ -254,94 +237,118 @@
 NTAPI
 CsrSrvCreateSharedSection(IN PCHAR ParameterValue);
 
-/**********************************************************************
- * CsrpCreateHeap/3
- */
-static NTSTATUS
-CsrpCreateHeap (VOID)
-{
-       DPRINT("CSR: %s called\n", __FUNCTION__);
-
-    CsrHeap = RtlGetProcessHeap();
-       CsrssApiHeap = RtlCreateHeap(HEAP_GROWABLE,
-                                      NULL,
-                                      65536,
-                                      65536,
-                                      NULL,
-                                      NULL);
-       if (CsrssApiHeap == NULL)
-       {
-               return STATUS_UNSUCCESSFUL;
-       }
-    
-       return STATUS_SUCCESS;
-}
-
-/**********************************************************************
- * CsrpRegisterSubsystem/3
- */
-BOOLEAN g_ModernSm;
-static NTSTATUS
-CsrpRegisterSubsystem (VOID)
-{
-       NTSTATUS           Status = STATUS_SUCCESS;
-       OBJECT_ATTRIBUTES  BootstrapOkAttributes;
-       UNICODE_STRING     Name;
-
-       DPRINT("CSR: %s called\n", __FUNCTION__);
-
-       /*
-        * Create the event object the callback port
-        * thread will signal *if* the SM will
-        * authorize us to bootstrap.
-        */
-       RtlInitUnicodeString (& Name, L"\\CsrssBooting");
-       InitializeObjectAttributes(& BootstrapOkAttributes,
-                                  & Name,
-                                  0, NULL, NULL);
-       Status = NtCreateEvent (& hBootstrapOk,
-                               EVENT_ALL_ACCESS,
-                               & BootstrapOkAttributes,
-                               SynchronizationEvent,
-                               FALSE);
-       if(!NT_SUCCESS(Status))
-       {
-               DPRINT("CSR: %s: NtCreateEvent failed (Status=0x%08lx)\n",
-                       __FUNCTION__, Status);
-               return Status;
-       }
-       /*
-        * Let's tell the SM a new environment
-        * subsystem server is in the system.
-        */
-       RtlInitUnicodeString (& Name, L"\\Windows\\SbApiPort");
-       DPRINT("CSR: %s: registering with SM for\n  IMAGE_SUBSYSTEM_WINDOWS_CUI 
== 3\n", __FUNCTION__);
-       Status = SmConnectApiPort (& Name,
-                                  hSbApiPort,
-                                  IMAGE_SUBSYSTEM_WINDOWS_CUI,
-                                  & hSmApiPort);
-    if (!NT_SUCCESS(Status))
-    {
-        Status = SmConnectToSm(&Name, hSbApiPort, IMAGE_SUBSYSTEM_WINDOWS_GUI, 
&hSmApiPort);
-        g_ModernSm = TRUE;
-    }
-       if(!NT_SUCCESS(Status))
-       {
-               DPRINT("CSR: %s unable to connect to the SM (Status=0x%08lx)\n",
-                       __FUNCTION__, Status);
-               NtClose (hBootstrapOk);
-               return Status;
-       }
-       /*
-        *  Wait for SM to reply OK... If the SM
-        *  won't answer, we hang here forever!
-        */
-       DPRINT("CSR: %s: waiting for SM to OK boot...\n", __FUNCTION__);
-       Status = NtWaitForSingleObject (hBootstrapOk,
-                                       FALSE,
-                                       NULL);
-       NtClose (hBootstrapOk);
-       return Status;
+/*++
+ * @name CsrSetProcessSecurity
+ *
+ * The CsrSetProcessSecurity routine protects access to the CSRSS process
+ * from unauthorized tampering.
+ *
+ * @param None.
+ *
+ * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
+ *         othwerwise.
+ *
+ * @remarks None.
+ *
+ *--*/
+NTSTATUS
+NTAPI
+CsrSetProcessSecurity(VOID)
+{
+    NTSTATUS Status;
+    HANDLE hToken, hProcess = NtCurrentProcess();
+    ULONG Length;
+    PTOKEN_USER TokenInfo = NULL;
+    PSECURITY_DESCRIPTOR ProcSd = NULL;
+    PACL Dacl;
+    PSID UserSid;
+
+    /* Open our token */
+    Status = NtOpenProcessToken(hProcess, TOKEN_QUERY, &hToken);
+    if (!NT_SUCCESS(Status)) goto Quickie;
+
+    /* Get the Token User Length */
+    NtQueryInformationToken(hToken, TokenUser, NULL, 0, &Length);
+
+    /* Allocate space for it */
+    TokenInfo = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, Length);
+    if (!TokenInfo)
+    {
+        Status = STATUS_NO_MEMORY;
+        goto Quickie;
+    }
+
+    /* Now query the data */
+    Status = NtQueryInformationToken(hToken, TokenUser, TokenInfo, Length, 
&Length);
+    NtClose(hToken);
+    if (!NT_SUCCESS(Status)) goto Quickie;
+
+    /* Now check the SID Length */
+    UserSid = TokenInfo->User.Sid;
+    Length = RtlLengthSid(UserSid) + sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE);
+
+    /* Allocate a buffer for the Security Descriptor, with SID and DACL */
+    ProcSd = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, 
SECURITY_DESCRIPTOR_MIN_LENGTH + Length);
+    if (!ProcSd)
+    {
+        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))
+    {
+        DPRINT1("CSRSS: SD creation failed - status = %lx\n", Status);
+        goto Quickie;
+    }
+
+    /* Create the DACL for it*/
+    Status = RtlCreateAcl(Dacl, Length, ACL_REVISION2);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("CSRSS: DACL creation failed - status = %lx\n", Status);
+        goto Quickie;
+    }
+
+    /* Create the ACE */
+    Status = RtlAddAccessAllowedAce(Dacl,
+                                    ACL_REVISION,
+                                    PROCESS_VM_READ | PROCESS_VM_WRITE |
+                                    PROCESS_VM_OPERATION | PROCESS_DUP_HANDLE |
+                                    PROCESS_TERMINATE | PROCESS_SUSPEND_RESUME 
|
+                                    PROCESS_QUERY_INFORMATION | READ_CONTROL,
+                                    UserSid);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("CSRSS: ACE creation failed - status = %lx\n", Status);
+        goto Quickie;
+    }
+
+    /* Clear the DACL in the SD */
+    Status = RtlSetDaclSecurityDescriptor(ProcSd, TRUE, Dacl, FALSE);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("CSRSS: set DACL failed - status = %lx\n", Status);
+        goto Quickie;
+    }
+
+    /* Write the SD into the Process */
+    Status = NtSetSecurityObject(hProcess, DACL_SECURITY_INFORMATION, ProcSd);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("CSRSS: set process DACL failed - status = %lx\n", Status);
+        goto Quickie;
+    }
+
+    /* Free the memory and return */
+Quickie:
+    if (ProcSd) RtlFreeHeap(CsrHeap, 0, ProcSd);
+    RtlFreeHeap(CsrHeap, 0, TokenInfo);
+    return Status;
 }
 
 /*++
@@ -764,11 +771,9 @@
     {
         /* Split Name and Value */
         ParameterName = Arguments[i];
-        DPRINT1("Name: %s\n", ParameterName);
         ParameterValue = NULL;
         ParameterValue = strchr(ParameterName, '=');
         if (ParameterValue) *ParameterValue++ = ANSI_NULL;
-        DPRINT1("Name=%s, Value=%s\n", ParameterName, ParameterValue);
 
         /* Check for Object Directory */
         if (!_stricmp(ParameterName, "ObjectDirectory"))
@@ -898,21 +903,218 @@
     return Status;
 }
 
-/* PUBLIC FUNCTIONS 
***********************************************************/
-
+/*++
+ * @name CsrCreateLocalSystemSD
+ *
+ * The CsrCreateLocalSystemSD routine creates a Security Descriptor for
+ * the local account with PORT_ALL_ACCESS.
+ *
+ * @param LocalSystemSd
+ *        Pointer to a pointer to the security descriptor to create.
+ *
+ * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
+ *         othwerwise.
+ *
+ * @remarks None.
+ *
+ *--*/
 NTSTATUS
 NTAPI
-CsrServerInitialization(ULONG ArgumentCount,
-                        PCHAR Arguments[])
-{
-       NTSTATUS  Status = STATUS_SUCCESS;
-
-       DPRINT("CSR: %s called\n", __FUNCTION__);
-
-    Status = CsrpCreateHeap();
-    if (!NT_SUCCESS(Status))
-    {
-        DPRINT1("CSRSRV failed in %s with status %lx\n", "CsrpCreateHeap", 
Status);
+CsrCreateLocalSystemSD(OUT PSECURITY_DESCRIPTOR *LocalSystemSd)
+{
+    SID_IDENTIFIER_AUTHORITY NtSidAuthority = {SECURITY_NT_AUTHORITY};
+    PSID SystemSid;
+    ULONG Length;
+    PSECURITY_DESCRIPTOR SystemSd;
+    PACL Dacl;
+    NTSTATUS Status;
+
+    /* Initialize the System SID */
+    RtlAllocateAndInitializeSid(&NtSidAuthority, 1,
+                                SECURITY_LOCAL_SYSTEM_RID,
+                                0, 0, 0, 0, 0, 0, 0,
+                                &SystemSid);
+
+    /* Get the length of the SID */
+    Length = RtlLengthSid(SystemSid) + sizeof(ACL) + 
sizeof(ACCESS_ALLOWED_ACE);
+
+    /* Allocate a buffer for the Security Descriptor, with SID and DACL */
+    SystemSd = RtlAllocateHeap(CsrHeap, 0, SECURITY_DESCRIPTOR_MIN_LENGTH + 
Length);
+
+    /* Set the pointer to the DACL */
+    Dacl = (PACL)((ULONG_PTR)SystemSd + SECURITY_DESCRIPTOR_MIN_LENGTH);
+
+    /* Now create the SD itself */
+    Status = RtlCreateSecurityDescriptor(SystemSd, 
SECURITY_DESCRIPTOR_REVISION);
+    if (!NT_SUCCESS(Status))
+    {
+        /* Fail */
+        RtlFreeHeap(CsrHeap, 0, SystemSd);
+        return Status;
+    }
+
+    /* Create the DACL for it*/
+    RtlCreateAcl(Dacl, Length, ACL_REVISION2);
+
+    /* Create the ACE */
+    Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, PORT_ALL_ACCESS, 
SystemSid);
+    if (!NT_SUCCESS(Status))
+    {
+        /* Fail */
+        RtlFreeHeap(CsrHeap, 0, SystemSd);
+        return Status;
+    }
+
+    /* Clear the DACL in the SD */
+    Status = RtlSetDaclSecurityDescriptor(SystemSd, TRUE, Dacl, FALSE);
+    if (!NT_SUCCESS(Status))
+    {
+        /* Fail */
+        RtlFreeHeap(CsrHeap, 0, SystemSd);
+        return Status;
+    }
+
+    /* Free the SID and return*/
+    RtlFreeSid(SystemSid);
+    *LocalSystemSd = SystemSd;
+    return Status;
+}
+
+/*++
+ * @name CsrSbApiPortInitialize
+ *
+ * The CsrSbApiPortInitialize routine initializes the LPC Port used for
+ * communications with the Session Manager (SM) and initializes the static
+ * thread that will handle connection requests and APIs.
+ *
+ * @param None
+ *
+ * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL
+ *         othwerwise.
+ *
+ * @remarks None.
+ *
+ *--*/
+NTSTATUS
+NTAPI
+CsrSbApiPortInitialize(VOID)
+{
+    ULONG Size;
+    PSECURITY_DESCRIPTOR PortSd;
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    NTSTATUS Status;
+    HANDLE hRequestThread;
+    CLIENT_ID ClientId;
+
+    /* Calculate how much space we'll need for the Port Name */
+    Size = CsrDirectoryName.Length + sizeof(SB_PORT_NAME) + sizeof(WCHAR);
+
+    /* 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 */
+    Status = CsrCreateLocalSystemSD(&PortSd);
+    if (!NT_SUCCESS(Status)) return Status;
+
+    /* Initialize the Attributes */
+    InitializeObjectAttributes(&ObjectAttributes,
+                               &CsrSbApiPortName,
+                               0,
+                               NULL,
+                               PortSd);
+
+    /* Create the Port Object */
+    Status = NtCreatePort(&CsrSbApiPort,
+                          &ObjectAttributes,
+                          sizeof(SB_CONNECTION_INFO),
+                          sizeof(SB_API_MSG),
+                          32 * sizeof(SB_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);
+        }
+    }
+
+    return Status;
+}
+
+/* PUBLIC FUNCTIONS 
***********************************************************/
+
+NTSTATUS
+NTAPI
+CsrServerInitialization(IN ULONG ArgumentCount,
+                        IN PCHAR Arguments[])
+{
+    NTSTATUS Status = STATUS_SUCCESS;
+    DPRINT("CSRSRV: %s called\n", __FUNCTION__);
+
+    /* Create the Init Event */
+    Status = NtCreateEvent(&CsrInitializationEvent,
+                           EVENT_ALL_ACCESS,
+                           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 */
+    Status = CsrSetProcessSecurity();
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("CSRSRV:%s: CsrSetProcessSecurity failed (Status=%08lx)\n",
+                __FUNCTION__, Status);
+        return Status;
     }
 
     /* Parse the command line */
@@ -923,51 +1125,71 @@
                 __FUNCTION__, Status);
         return Status;
     }
-    
+
     CsrInitProcessData();
 
+    Status = CsrApiRegisterDefinitions(NativeDefinitions);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("CSRSRV failed in %s with status %lx\n", 
"CsrApiRegisterDefinitions", Status);
+    }
+
     Status = CsrpCreateListenPort(L"\\Windows\\ApiPort", &hApiPort, 
(PTHREAD_START_ROUTINE)ClientConnectionThread);
     if (!NT_SUCCESS(Status))
     {
         DPRINT1("CSRSRV failed in %s with status %lx\n", "CsrpCreateApiPort", 
Status);
     }
 
-    Status = CsrApiRegisterDefinitions(NativeDefinitions);
-    if (!NT_SUCCESS(Status))
-    {
-        DPRINT1("CSRSRV failed in %s with status %lx\n", 
"CsrApiRegisterDefinitions", Status);
-    }
-
     Status = CsrpInitWin32Csr();
     if (!NT_SUCCESS(Status))
     {
         DPRINT1("CSRSRV failed in %s with status %lx\n", "CsrpInitWin32Csr", 
Status);
     }
 
-    Status = CsrpCreateListenPort(L"\\Windows\\SbApiPort", &hSbApiPort, 
ServerSbApiPortThread);
-    if (!NT_SUCCESS(Status))
-    {
-        DPRINT1("CSRSRV failed in %s with status %lx\n", 
"CsrpCreateCallbackPort", Status);
-    }
-
-    Status = CsrpRegisterSubsystem();
-    if (!NT_SUCCESS(Status))
-    {
-        DPRINT1("CSRSRV failed in %s with status %lx\n", 
"CsrpRegisterSubsystem", Status);
-    }
-
+    /* Initialize the API Port for SM communication */
+    Status = CsrSbApiPortInitialize();
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("CSRSRV:%s: CsrSbApiPortInitialize failed (Status=%08lx)\n",
+                __FUNCTION__, Status);
+        return Status;
+    }
+
+    /* We're all set! Connect to SM! */
+    Status = SmConnectToSm(&CsrSbApiPortName,
+                           CsrSbApiPort,
+                           IMAGE_SUBSYSTEM_WINDOWS_GUI,
+                           &CsrSmApiPort);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("CSRSRV:%s: SmConnectToSm failed (Status=%08lx)\n",
+                __FUNCTION__, Status);
+        return Status;
+    }
+
+    /* Finito! Signal the event */
+    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 */
     Status = NtSetDefaultHardErrorPort(hApiPort);
     if (!NT_SUCCESS(Status))
     {
-        DPRINT1("CSRSRV failed in %s with status %lx\n", 
"CsrpCreateHardErrorPort", Status);
-    }
-    
-       if (CallInitComplete())
-       {
-               return STATUS_SUCCESS;
-       }
-    
-       return STATUS_UNSUCCESSFUL;
+        DPRINT1("CSRSRV:%s: NtSetDefaultHardErrorPort failed (Status=%08lx)\n",
+                __FUNCTION__, Status);
+        return Status;
+    }
+
+    /* Return status */
+    return Status;
 }
 
 BOOL

Modified: trunk/reactos/subsystems/win32/csrss/include/api.h
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/csrss/include/api.h?rev=55615&r1=55614&r2=55615&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/csrss/include/api.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/csrss/include/api.h [iso-8859-1] Wed Feb 15 
19:53:31 2012
@@ -121,14 +121,18 @@
 CSR_API(CsrGetShutdownParameters);
 CSR_API(CsrSetShutdownParameters);
 
+PCSR_THREAD
+NTAPI
+CsrAllocateThread(IN PCSRSS_PROCESS_DATA CsrProcess);
+
 /* api/wapi.c */
 NTSTATUS FASTCALL CsrApiRegisterDefinitions(PCSRSS_API_DEFINITION 
NewDefinitions);
 VOID FASTCALL CsrApiCallHandler(PCSRSS_PROCESS_DATA ProcessData,
                                 PCSR_API_MESSAGE Request);
-DWORD WINAPI ServerSbApiPortThread (PVOID PortHandle);
+VOID WINAPI CsrSbApiRequestThread (PVOID PortHandle);
 VOID NTAPI ClientConnectionThread(HANDLE ServerPort);
 
-extern HANDLE CsrssApiHeap;
+extern HANDLE CsrSbApiPort;
 
 /* api/process.c */
 typedef NTSTATUS (WINAPI *CSRSS_ENUM_PROCESS_PROC)(PCSRSS_PROCESS_DATA 
ProcessData,

Modified: trunk/reactos/subsystems/win32/csrss/win32csr/dllmain.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/csrss/win32csr/dllmain.c?rev=55615&r1=55614&r2=55615&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/csrss/win32csr/dllmain.c [iso-8859-1] 
(original)
+++ trunk/reactos/subsystems/win32/csrss/win32csr/dllmain.c [iso-8859-1] Wed 
Feb 15 19:53:31 2012
@@ -335,14 +335,14 @@
 Win32CsrInitialization(PCSRSS_API_DEFINITION *ApiDefinitions,
                        PCSRPLUGIN_SERVER_PROCS ServerProcs,
                        PCSRSS_EXPORTED_FUNCS Exports,
-                       HANDLE CsrssApiHeap)
+                       HANDLE CsrHeap)
 {
     HANDLE ServerThread;
     CLIENT_ID ClientId;
     NTSTATUS Status;
 
     CsrExports = *Exports;
-    Win32CsrApiHeap = CsrssApiHeap;
+    Win32CsrApiHeap = CsrHeap;
     
     CsrpInitVideo();
 


Reply via email to