NTSTATUS NTAPI SmpExecuteInitialCommand(IN ULONG MuSessionId, IN PUNICODE_STRING InitialCommand, IN HANDLE InitialCommandProcess, OUT PHANDLE ReturnPid) { NTSTATUS Status; RTL_USER_PROCESS_INFORMATION ProcessInfo; UNICODE_STRING Arguments, ImageFileDirectory, ImageFileName; ULONG Flags = 0; /* Check if we haven't yet connected to ourselves */ if (!SmApiPort) { /* Connect to ourselves, as a client */ Status = SmConnectToSm(0, 0, 0, &SmApiPort); if (!NT_SUCCESS(Status)) { DPRINT1("SMSS: Unable to connect to SM - Status == %lx\n", Status); return Status; } } /* Parse the initial command line */ Status = SmpParseCommandLine(InitialCommand, &Flags, &ImageFileName, &ImageFileDirectory, &Arguments); if (Flags & SMP_INVALID_PATH) { /* Fail if it doesn't exist */ DPRINT1("SMSS: Initial command image (%wZ) not found\n", &ImageFileName); if (ImageFileName.Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, ImageFileName.Buffer); return STATUS_OBJECT_NAME_NOT_FOUND; } /* And fail if any other reason is also true */ if (!NT_SUCCESS(Status)) { DPRINT1("SMSS: SmpParseCommandLine( %wZ ) failed - Status == %lx\n", InitialCommand, Status); return Status; } /* Execute the initial command -- but defer its full execution */ Status = SmpExecuteImage(&ImageFileName, &ImageFileDirectory, InitialCommand, MuSessionId, SMP_DEFERRED_FLAG, &ProcessInfo); /* Free any buffers we had lying around */ if (ImageFileName.Buffer) { RtlFreeHeap(RtlGetProcessHeap(), 0, ImageFileName.Buffer); } if (ImageFileDirectory.Buffer) { RtlFreeHeap(RtlGetProcessHeap(), 0, ImageFileDirectory.Buffer); } if (Arguments.Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, Arguments.Buffer); /* Bail out if we couldn't execute the initial command */ if (!NT_SUCCESS(Status)) return Status; /* Now duplicate the handle to this process */ Status = NtDuplicateObject(NtCurrentProcess(), ProcessInfo.ProcessHandle, NtCurrentProcess(), InitialCommandProcess, PROCESS_ALL_ACCESS, 0, 0); if (!NT_SUCCESS(Status)) { /* Kill it utterly if duplication failed */ DPRINT1("SMSS: DupObject Failed. Status == %lx\n", Status); NtTerminateProcess(ProcessInfo.ProcessHandle, Status); NtResumeThread(ProcessInfo.ThreadHandle, NULL); NtClose(ProcessInfo.ThreadHandle); NtClose(ProcessInfo.ProcessHandle); return Status; } /* Return PID to the caller, and set this as the initial command PID */ if (ReturnPid) *ReturnPid = ProcessInfo.ClientId.UniqueProcess; if (!MuSessionId) SmpInitialCommandProcessId = ProcessInfo.ClientId.UniqueProcess; /* Now call our server execution function to wrap up its initialization */ Status = SmExecPgm(SmApiPort, &ProcessInfo, FALSE); if (!NT_SUCCESS(Status)) DPRINT1("SMSS: SmExecPgm Failed. Status == %lx\n", Status); return Status; }
/*++ * @name CsrServerInitialization * @implemented NT4 * * The CsrServerInitialization routine is the native (not Server) entrypoint * of this Server DLL. It serves as the entrypoint for CSRSS. * * @param ArgumentCount * Number of arguments on the command line. * * @param Arguments * Array of arguments from the command line. * * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL otherwise. * * @remarks None. * *--*/ NTSTATUS NTAPI CsrServerInitialization(IN ULONG ArgumentCount, IN PCHAR Arguments[]) { NTSTATUS Status = STATUS_SUCCESS; /* 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=0x%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=0x%08lx)\n", __FUNCTION__, Status); return Status; } /* Set up Session Support */ Status = CsrInitializeNtSessionList(); if (!NT_SUCCESS(Status)) { DPRINT1("CSRSRV:%s: CsrInitializeSessions failed (Status=0x%08lx)\n", __FUNCTION__, Status); return Status; } /* Set up Process Support and allocate the CSR Root Process */ Status = CsrInitializeProcessStructure(); if (!NT_SUCCESS(Status)) { DPRINT1("CSRSRV:%s: CsrInitializeProcessStructure failed (Status=0x%08lx)\n", __FUNCTION__, Status); return Status; } /* Parse the command line */ Status = CsrParseServerCommandLine(ArgumentCount, Arguments); if (!NT_SUCCESS(Status)) { DPRINT1("CSRSRV:%s: CsrParseServerCommandLine failed (Status=0x%08lx)\n", __FUNCTION__, Status); return Status; } /* Finish to initialize the CSR Root Process */ Status = CsrInitCsrRootProcess(); if (!NT_SUCCESS(Status)) { DPRINT1("CSRSRV:%s: CsrInitCsrRootProcess failed (Status=0x%08lx)\n", __FUNCTION__, Status); return Status; } /* Now initialize our API Port */ Status = CsrApiPortInitialize(); if (!NT_SUCCESS(Status)) { DPRINT1("CSRSRV:%s: CsrApiPortInitialize failed (Status=0x%08lx)\n", __FUNCTION__, Status); return Status; } /* Initialize the API Port for SM communication */ Status = CsrSbApiPortInitialize(); if (!NT_SUCCESS(Status)) { DPRINT1("CSRSRV:%s: CsrSbApiPortInitialize failed (Status=0x%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=0x%08lx)\n", __FUNCTION__, Status); return Status; } /* Have us handle Hard Errors */ Status = NtSetDefaultHardErrorPort(CsrApiPort); if (!NT_SUCCESS(Status)) { DPRINT1("CSRSRV:%s: NtSetDefaultHardErrorPort failed (Status=0x%08lx)\n", __FUNCTION__, Status); return Status; } /* Return status */ return Status; }