📄 init.c
字号:
*/
static NTSTATUS
CsrpCreateHeap (int argc, char ** argv, char ** envp)
{
DPRINT("CSR: %s called\n", __FUNCTION__);
CsrssApiHeap = RtlCreateHeap(HEAP_GROWABLE,
NULL,
65536,
65536,
NULL,
NULL);
if (CsrssApiHeap == NULL)
{
return STATUS_UNSUCCESSFUL;
}
return STATUS_SUCCESS;
}
/**********************************************************************
* CsrpCreateCallbackPort/3
*/
static NTSTATUS
CsrpCreateCallbackPort (int argc, char ** argv, char ** envp)
{
DPRINT("CSR: %s called\n", __FUNCTION__);
return CsrpCreateListenPort (L"\\Windows\\SbApiPort",
& hSbApiPort,
ServerSbApiPortThread);
}
/**********************************************************************
* CsrpRegisterSubsystem/3
*/
static NTSTATUS
CsrpRegisterSubsystem (int argc, char ** argv, char ** envp)
{
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))
{
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;
}
/**********************************************************************
* EnvpToUnicodeString/2
*/
static ULONG FASTCALL
EnvpToUnicodeString (char ** envp, PUNICODE_STRING UnicodeEnv)
{
ULONG CharCount = 0;
ULONG Index = 0;
ANSI_STRING AnsiEnv;
UnicodeEnv->Buffer = NULL;
for (Index=0; NULL != envp[Index]; Index++)
{
CharCount += strlen (envp[Index]);
++ CharCount;
}
++ CharCount;
AnsiEnv.Buffer = RtlAllocateHeap (RtlGetProcessHeap(), 0, CharCount);
if (NULL != AnsiEnv.Buffer)
{
PCHAR WritePos = AnsiEnv.Buffer;
for (Index=0; NULL != envp[Index]; Index++)
{
strcpy (WritePos, envp[Index]);
WritePos += strlen (envp[Index]) + 1;
}
/* FIXME: the last (double) nullterm should perhaps not be included in Length
* but only in MaximumLength. -Gunnar */
AnsiEnv.Buffer [CharCount-1] = '\0';
AnsiEnv.Length = CharCount;
AnsiEnv.MaximumLength = CharCount;
RtlAnsiStringToUnicodeString (UnicodeEnv, & AnsiEnv, TRUE);
RtlFreeHeap (RtlGetProcessHeap(), 0, AnsiEnv.Buffer);
}
return CharCount;
}
/**********************************************************************
* CsrpLoadKernelModeDriver/3
*/
static NTSTATUS
CsrpLoadKernelModeDriver (int argc, char ** argv, char ** envp)
{
NTSTATUS Status = STATUS_SUCCESS;
WCHAR Data [MAX_PATH + 1];
ULONG DataLength = sizeof Data;
ULONG DataType = 0;
UNICODE_STRING Environment;
DPRINT("SM: %s called\n", __FUNCTION__);
EnvpToUnicodeString (envp, & Environment);
Status = SmLookupSubsystem (L"Kmode",
Data,
& DataLength,
& DataType,
Environment.Buffer);
RtlFreeUnicodeString (& Environment);
if((STATUS_SUCCESS == Status) && (DataLength > sizeof Data[0]))
{
WCHAR ImagePath [MAX_PATH + 1] = {0};
UNICODE_STRING ModuleName;
wcscpy (ImagePath, L"\\??\\");
wcscat (ImagePath, Data);
RtlInitUnicodeString (& ModuleName, ImagePath);
Status = NtSetSystemInformation(/* FIXME: SystemLoadAndCallImage */
SystemExtendServiceTableInformation,
& ModuleName,
sizeof ModuleName);
if(!NT_SUCCESS(Status))
{
DPRINT("WIN: %s: loading Kmode failed (Status=0x%08lx)\n",
__FUNCTION__, Status);
}
}
return Status;
}
/**********************************************************************
* CsrpCreateApiPort/2
*/
static NTSTATUS
CsrpCreateApiPort (int argc, char ** argv, char ** envp)
{
DPRINT("CSR: %s called\n", __FUNCTION__);
CsrInitProcessData();
return CsrpCreateListenPort(L"\\Windows\\ApiPort", &hApiPort,
(PTHREAD_START_ROUTINE)ClientConnectionThread);
}
/**********************************************************************
* CsrpApiRegisterDef/0
*/
static NTSTATUS
CsrpApiRegisterDef (int argc, char ** argv, char ** envp)
{
return CsrApiRegisterDefinitions(NativeDefinitions);
}
/**********************************************************************
* CsrpCCTS/2
*/
static NTSTATUS
CsrpCCTS (int argc, char ** argv, char ** envp)
{
ULONG Dummy;
ULONG DummyLength = sizeof(Dummy);
return CsrClientConnectToServer(L"\\Windows",
0, &Dummy, &DummyLength, NULL);
}
/**********************************************************************
* CsrpRunWinlogon/0
*
* Start the logon process (winlogon.exe).
*
* TODO: this should be moved in CsrpCreateSession/x (one per session)
* TODO: in its own desktop (one logon desktop per winstation).
*/
static NTSTATUS
CsrpRunWinlogon (int argc, char ** argv, char ** envp)
{
NTSTATUS Status = STATUS_SUCCESS;
UNICODE_STRING ImagePath;
UNICODE_STRING CommandLine;
PRTL_USER_PROCESS_PARAMETERS ProcessParameters = NULL;
RTL_USER_PROCESS_INFORMATION ProcessInfo;
DPRINT("CSR: %s called\n", __FUNCTION__);
/* initialize the process parameters */
RtlInitUnicodeString (& ImagePath, L"\\SystemRoot\\system32\\winlogon.exe");
RtlInitUnicodeString (& CommandLine, L"");
RtlCreateProcessParameters(& ProcessParameters,
& ImagePath,
NULL,
NULL,
& CommandLine,
NULL,
NULL,
NULL,
NULL,
NULL);
/* Create the winlogon process */
Status = RtlCreateUserProcess (& ImagePath,
OBJ_CASE_INSENSITIVE,
ProcessParameters,
NULL,
NULL,
NULL,
FALSE,
NULL,
NULL,
& ProcessInfo);
/* Cleanup */
RtlDestroyProcessParameters (ProcessParameters);
if (!NT_SUCCESS(Status))
{
DPRINT1("SM: %s: loading winlogon.exe failed (Status=%08lx)\n",
__FUNCTION__, Status);
}
ZwResumeThread(ProcessInfo.ThreadHandle, NULL);
return Status;
}
static NTSTATUS
CsrpCreateHardErrorPort (int argc, char ** argv, char ** envp)
{
return NtSetDefaultHardErrorPort(hApiPort);
}
typedef NTSTATUS (* CSR_INIT_ROUTINE)(int,char**,char**);
struct {
BOOL Required;
CSR_INIT_ROUTINE EntryPoint;
PCHAR ErrorMessage;
} InitRoutine [] = {
{TRUE, CsrpCreateCallbackPort, "create the callback port \\Windows\\SbApiPort"},
{TRUE, CsrpRegisterSubsystem, "register with SM"},
{TRUE, CsrpCreateHeap, "create the CSR heap"},
{TRUE, CsrpCreateApiPort, "create the api port \\Windows\\ApiPort"},
{TRUE, CsrpCreateHardErrorPort, "create the hard error port"},
{TRUE, CsrpCreateObjectDirectory,"create the object directory \\Windows"},
{TRUE, CsrpLoadKernelModeDriver, "load Kmode driver"},
{TRUE, CsrpInitVideo, "initialize video"},
{TRUE, CsrpApiRegisterDef, "initialize api definitions"},
{TRUE, CsrpCCTS, "connect client to server"},
{TRUE, CsrpInitWin32Csr, "load usermode dll"},
{TRUE, CsrpRunWinlogon, "run WinLogon"},
};
/**********************************************************************
* NAME
* CsrServerInitialization
*
* DESCRIPTION
* Initialize the Win32 environment subsystem server.
*
* RETURN VALUE
* TRUE: Initialization OK; otherwise FALSE.
*/
BOOL STDCALL
CsrServerInitialization (
int argc,
char ** argv,
char ** envp
)
{
UINT i = 0;
NTSTATUS Status = STATUS_SUCCESS;
DPRINT("CSR: %s called\n", __FUNCTION__);
for (i=0; i < (sizeof InitRoutine / sizeof InitRoutine[0]); i++)
{
Status = InitRoutine[i].EntryPoint(argc,argv,envp);
if(!NT_SUCCESS(Status))
{
DPRINT1("CSR: %s: failed to %s (Status=%08lx)\n",
__FUNCTION__,
InitRoutine[i].ErrorMessage,
Status);
if (InitRoutine[i].Required)
{
return FALSE;
}
}
}
if (CallInitComplete())
{
Status = SmCompleteSession (hSmApiPort,hSbApiPort,hApiPort);
return TRUE;
}
return FALSE;
}
/* EOF */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -