mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
SM/CSR: move win32k.sys loading from the SM to the Win32 user mode server.
svn path=/trunk/; revision=15729
This commit is contained in:
parent
114fa63aa5
commit
da87b75712
13 changed files with 492 additions and 457 deletions
|
@ -30,5 +30,11 @@ SmQueryInformation (IN HANDLE SmApiPort,
|
|||
IN OUT PVOID Data,
|
||||
IN ULONG DataLength,
|
||||
IN OUT PULONG ReturnedDataLength OPTIONAL);
|
||||
|
||||
/* smlib/lookupss.c */
|
||||
NTSTATUS STDCALL
|
||||
SmLookupSubsystem (IN PWSTR Name,
|
||||
IN OUT PWSTR Data,
|
||||
IN OUT PULONG DataLength,
|
||||
IN OUT PULONG DataType,
|
||||
IN PVOID Environment OPTIONAL);
|
||||
#endif /* ndef INCLUDE_SM_HELPER_H */
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#if !defined(INCLUDE_SM_NS_H)
|
||||
#define INCLUDE_SM_NS_H
|
||||
|
||||
/* $Id: helper.h 13689 2005-02-20 16:46:10Z ea $ */
|
||||
/* $Id$ */
|
||||
|
||||
#define SM_REGISTRY_ROOT_NAME L"\\Session Manager"
|
||||
#define SM_REGISTRY_SUBSYSTEMS_NAME L"SubSystems"
|
||||
|
|
|
@ -4,3 +4,4 @@ SmCompleteSession@12
|
|||
SmConnectApiPort@16
|
||||
SmExecuteProgram@8
|
||||
SmQueryInformation@20
|
||||
SmLookupSubsystem@20
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: compses.c 13731 2005-02-23 23:37:06Z ea $
|
||||
/* $Id$
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS system libraries
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: connect.c 14015 2005-03-13 17:00:19Z ea $
|
||||
/* $Id$
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS system libraries
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: execpgm.c 13731 2005-02-23 23:37:06Z ea $
|
||||
/* $Id$
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS system libraries
|
||||
|
|
155
reactos/lib/smlib/lookupss.c
Normal file
155
reactos/lib/smlib/lookupss.c
Normal file
|
@ -0,0 +1,155 @@
|
|||
/* $Id$
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS system libraries
|
||||
* FILE: lib/smlib/lookupss.c
|
||||
*/
|
||||
#define NTOS_MODE_USER
|
||||
#include <ntos.h>
|
||||
#include <sm/helper.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
/**********************************************************************
|
||||
* NAME EXPORTED
|
||||
* SmLookupSubsystem/6
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Read from the registry key
|
||||
* \Registry\SYSTEM\CurrentControlSet\Control\Session Manager\Subsystems
|
||||
* the value which name is Name.
|
||||
*
|
||||
* ARGUMENTS
|
||||
* Name: name of the program to run, that is a value's name in
|
||||
* the SM registry key Subsystems;
|
||||
* Data: what the registry gave back for Name;
|
||||
* DataLength: how much Data the registry returns;
|
||||
* DataType: what is Data?
|
||||
* Environment: set it if you want this function to use it
|
||||
* to possibly expand Data before giving it back; if set
|
||||
* to NULL, no expansion will be performed.
|
||||
*/
|
||||
NTSTATUS STDCALL
|
||||
SmLookupSubsystem (IN PWSTR Name,
|
||||
IN OUT PWSTR Data,
|
||||
IN OUT PULONG DataLength,
|
||||
IN OUT PULONG DataType,
|
||||
IN PVOID Environment OPTIONAL)
|
||||
{
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
UNICODE_STRING usKeyName = {0};
|
||||
OBJECT_ATTRIBUTES Oa = {0};
|
||||
HANDLE hKey = (HANDLE) 0;
|
||||
|
||||
DPRINT("SM: %s(Name='%S') called\n", __FUNCTION__, Name);
|
||||
/*
|
||||
* Prepare the key name to scan and
|
||||
* related object attributes.
|
||||
*/
|
||||
RtlInitUnicodeString (& usKeyName,
|
||||
L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\SubSystems");
|
||||
|
||||
InitializeObjectAttributes (& Oa,
|
||||
& usKeyName,
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
NULL,
|
||||
NULL);
|
||||
/*
|
||||
* Open the key. This MUST NOT fail, if the
|
||||
* request is for a legitimate subsystem.
|
||||
*/
|
||||
Status = NtOpenKey (& hKey,
|
||||
MAXIMUM_ALLOWED,
|
||||
& Oa);
|
||||
if(NT_SUCCESS(Status))
|
||||
{
|
||||
UNICODE_STRING usValueName = {0};
|
||||
PWCHAR KeyValueInformation = NULL;
|
||||
ULONG KeyValueInformationLength = 1024;
|
||||
ULONG ResultLength = 0L;
|
||||
PKEY_VALUE_PARTIAL_INFORMATION kvpi = NULL;
|
||||
|
||||
KeyValueInformation = RtlAllocateHeap (RtlGetProcessHeap(),
|
||||
0,
|
||||
KeyValueInformationLength);
|
||||
if (NULL == KeyValueInformation)
|
||||
{
|
||||
return STATUS_NO_MEMORY;
|
||||
}
|
||||
kvpi = (PKEY_VALUE_PARTIAL_INFORMATION) KeyValueInformation;
|
||||
RtlInitUnicodeString (& usValueName, Name);
|
||||
Status = NtQueryValueKey (hKey,
|
||||
& usValueName,
|
||||
KeyValuePartialInformation,
|
||||
KeyValueInformation,
|
||||
KeyValueInformationLength,
|
||||
& ResultLength);
|
||||
if(NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("nkvpi.TitleIndex = %ld\n", kvpi->TitleIndex);
|
||||
DPRINT("kvpi.Type = %ld\n", kvpi->Type);
|
||||
DPRINT("kvpi.DataLength = %ld\n", kvpi->DataLength);
|
||||
|
||||
if((NULL != Data) && (NULL != DataLength) && (NULL != DataType))
|
||||
{
|
||||
*DataType = kvpi->Type;
|
||||
if((NULL != Environment) && (REG_EXPAND_SZ == *DataType))
|
||||
{
|
||||
UNICODE_STRING Source;
|
||||
PWCHAR DestinationBuffer = NULL;
|
||||
UNICODE_STRING Destination;
|
||||
ULONG Length = 0;
|
||||
|
||||
DPRINT("SM: %s: value will be expanded\n", __FUNCTION__);
|
||||
|
||||
DestinationBuffer = RtlAllocateHeap (RtlGetProcessHeap(),
|
||||
0,
|
||||
(2 * KeyValueInformationLength));
|
||||
if (NULL == DestinationBuffer)
|
||||
{
|
||||
Status = STATUS_NO_MEMORY;
|
||||
}
|
||||
else
|
||||
{
|
||||
Source.Length = kvpi->DataLength;
|
||||
Source.MaximumLength = kvpi->DataLength;
|
||||
Source.Buffer = (PWCHAR) & kvpi->Data;
|
||||
|
||||
Destination.Length = 0;
|
||||
Destination.MaximumLength = (2 * KeyValueInformationLength);
|
||||
Destination.Buffer = DestinationBuffer;
|
||||
|
||||
Status = RtlExpandEnvironmentStrings_U (Environment,
|
||||
& Source,
|
||||
& Destination,
|
||||
& Length);
|
||||
if(NT_SUCCESS(Status))
|
||||
{
|
||||
*DataLength = min(*DataLength, Destination.Length);
|
||||
RtlCopyMemory (Data, Destination.Buffer, *DataLength);
|
||||
}
|
||||
RtlFreeHeap (RtlGetProcessHeap(), 0, DestinationBuffer);
|
||||
}
|
||||
}else{
|
||||
DPRINT("SM: %s: value won't be expanded\n", __FUNCTION__);
|
||||
*DataLength = min(*DataLength, kvpi->DataLength);
|
||||
RtlCopyMemory (Data, & kvpi->Data, *DataLength);
|
||||
}
|
||||
*DataType = kvpi->Type;
|
||||
}else{
|
||||
DPRINT1("SM: %s: Data or DataLength or DataType is NULL!\n", __FUNCTION__);
|
||||
Status = STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
}else{
|
||||
DPRINT1("%s: NtQueryValueKey failed (Status=0x%08lx)\n", __FUNCTION__, Status);
|
||||
}
|
||||
RtlFreeHeap (RtlGetProcessHeap(), 0, KeyValueInformation);
|
||||
NtClose (hKey);
|
||||
}else{
|
||||
DPRINT1("%s: NtOpenKey failed (Status=0x%08lx)\n", __FUNCTION__, Status);
|
||||
}
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* EOF */
|
|
@ -4,4 +4,5 @@
|
|||
<file>connect.c</file>
|
||||
<file>execpgm.c</file>
|
||||
<file>compses.c</file>
|
||||
<file>lookupss.c</file>
|
||||
</module>
|
||||
|
|
|
@ -52,6 +52,8 @@ typedef struct _COMMAND_LINE_ARGUMENT
|
|||
|
||||
} COMMAND_LINE_ARGUMENT, *PCOMMAND_LINE_ARGUMENT;
|
||||
|
||||
PRTL_USER_PROCESS_PARAMETERS RtlProcessParameters = NULL;
|
||||
|
||||
/**********************************************************************
|
||||
* NAME PRIVATE
|
||||
* CsrpParseCommandLine/3
|
||||
|
@ -150,7 +152,6 @@ CsrpFreeCommandLine (HANDLE ProcessHeap,
|
|||
|
||||
VOID STDCALL NtProcessStartup(PPEB Peb)
|
||||
{
|
||||
PRTL_USER_PROCESS_PARAMETERS RtlProcessParameters = NULL;
|
||||
COMMAND_LINE_ARGUMENT CmdLineArg = {0};
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@ HANDLE CsrObjectDirectory = (HANDLE) 0;
|
|||
UNICODE_STRING CsrDirectoryName;
|
||||
|
||||
extern HANDLE CsrssApiHeap;
|
||||
extern PRTL_USER_PROCESS_PARAMETERS RtlProcessParameters;
|
||||
|
||||
static unsigned InitCompleteProcCount;
|
||||
static CSRPLUGIN_INIT_COMPLETE_PROC *InitCompleteProcs = NULL;
|
||||
|
@ -306,7 +307,7 @@ CsrpCreateListenPort (IN LPWSTR Name,
|
|||
/* === INIT ROUTINES === */
|
||||
|
||||
/**********************************************************************
|
||||
* CsrpCreateCallbackPort/0
|
||||
* CsrpCreateHeap/2
|
||||
*/
|
||||
static NTSTATUS
|
||||
CsrpCreateHeap (ULONG argc, PWSTR* argv)
|
||||
|
@ -327,7 +328,7 @@ CsrpCreateHeap (ULONG argc, PWSTR* argv)
|
|||
}
|
||||
|
||||
/**********************************************************************
|
||||
* CsrpCreateCallbackPort/0
|
||||
* CsrpCreateCallbackPort/2
|
||||
*/
|
||||
static NTSTATUS
|
||||
CsrpCreateCallbackPort (ULONG argc, PWSTR* argv)
|
||||
|
@ -401,7 +402,47 @@ CsrpRegisterSubsystem (ULONG argc, PWSTR* argv)
|
|||
}
|
||||
|
||||
/**********************************************************************
|
||||
* CsrpCreateApiPort/0
|
||||
* CsrpLoadKernelModeDriver/2
|
||||
*/
|
||||
static NTSTATUS
|
||||
CsrpLoadKernelModeDriver (ULONG argc, PWSTR* argv)
|
||||
{
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
WCHAR Data [MAX_PATH + 1];
|
||||
ULONG DataLength = sizeof Data;
|
||||
ULONG DataType = 0;
|
||||
|
||||
|
||||
DPRINT("SM: %s called\n", __FUNCTION__);
|
||||
|
||||
Status = SmLookupSubsystem (L"Kmode",
|
||||
Data,
|
||||
& DataLength,
|
||||
& DataType,
|
||||
RtlProcessParameters->Environment);
|
||||
if((STATUS_SUCCESS == Status) && (DataLength > sizeof Data[0]))
|
||||
{
|
||||
WCHAR ImagePath [MAX_PATH + 1] = {0};
|
||||
SYSTEM_LOAD_AND_CALL_IMAGE ImageInfo;
|
||||
|
||||
wcscpy (ImagePath, L"\\??\\");
|
||||
wcscat (ImagePath, Data);
|
||||
RtlZeroMemory (& ImageInfo, sizeof ImageInfo);
|
||||
RtlInitUnicodeString (& ImageInfo.ModuleName, ImagePath);
|
||||
Status = NtSetSystemInformation(SystemLoadAndCallImage,
|
||||
& ImageInfo,
|
||||
sizeof ImageInfo);
|
||||
if(!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("WIN: %s: loading Kmode failed (Status=0x%08lx)\n",
|
||||
__FUNCTION__, Status);
|
||||
}
|
||||
}
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* CsrpCreateApiPort/2
|
||||
*/
|
||||
static NTSTATUS
|
||||
CsrpCreateApiPort (ULONG argc, PWSTR* argv)
|
||||
|
@ -500,6 +541,7 @@ struct {
|
|||
{TRUE, CsrpCreateHeap, "create the CSR heap"},
|
||||
{TRUE, CsrpCreateApiPort, "create the api port \\Windows\\ApiPort"},
|
||||
{TRUE, CsrpParseCommandLine, "parse the command line"},
|
||||
{TRUE, CsrpLoadKernelModeDriver, "load Kmode driver"},
|
||||
{TRUE, CsrpInitVideo, "initialize video"},
|
||||
{TRUE, CsrpApiRegisterDef, "initialize api definitions"},
|
||||
{TRUE, CsrpCCTS, "connect client to server"},
|
||||
|
|
|
@ -98,46 +98,6 @@ SmpRegisterSmss(VOID)
|
|||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* SmpLoadKernelModeSubsystem/0
|
||||
*/
|
||||
static NTSTATUS
|
||||
SmpLoadKernelModeSubsystem (VOID)
|
||||
{
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
WCHAR Data [MAX_PATH + 1];
|
||||
ULONG DataLength = sizeof Data;
|
||||
ULONG DataType = 0;
|
||||
|
||||
|
||||
DPRINT("SM: %s called\n", __FUNCTION__);
|
||||
|
||||
Status = SmLookupSubsystem (L"Kmode",
|
||||
Data,
|
||||
& DataLength,
|
||||
& DataType,
|
||||
TRUE);
|
||||
if((STATUS_SUCCESS == Status) && (DataLength > sizeof Data[0]))
|
||||
{
|
||||
WCHAR ImagePath [MAX_PATH + 1] = {0};
|
||||
SYSTEM_LOAD_AND_CALL_IMAGE ImageInfo;
|
||||
|
||||
wcscpy (ImagePath, L"\\??\\");
|
||||
wcscat (ImagePath, Data);
|
||||
RtlZeroMemory (& ImageInfo, sizeof ImageInfo);
|
||||
RtlInitUnicodeString (& ImageInfo.ModuleName, ImagePath);
|
||||
Status = NtSetSystemInformation(SystemLoadAndCallImage,
|
||||
& ImageInfo,
|
||||
sizeof ImageInfo);
|
||||
if(!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("SM: %s: loading Kmode failed (Status=0x%08lx)\n",
|
||||
__FUNCTION__, Status);
|
||||
}
|
||||
}
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* SmpLoadRequiredSubsystems/0
|
||||
*/
|
||||
|
@ -157,7 +117,7 @@ SmpLoadRequiredSubsystems (VOID)
|
|||
Data,
|
||||
& DataLength,
|
||||
& DataType,
|
||||
FALSE);
|
||||
NULL);
|
||||
if((STATUS_SUCCESS == Status) && (DataLength > sizeof Data[0]))
|
||||
{
|
||||
PWCHAR Name = NULL;
|
||||
|
@ -206,9 +166,6 @@ SmLoadSubsystems(VOID)
|
|||
/* SM self registers */
|
||||
Status = SmpRegisterSmss();
|
||||
if(!NT_SUCCESS(Status)) return Status;
|
||||
/* Load Kmode subsystem (aka win32k.sys) */
|
||||
Status = SmpLoadKernelModeSubsystem();
|
||||
if(!NT_SUCCESS(Status)) return Status;
|
||||
/* Load Required subsystems (Debug Windows) */
|
||||
Status = SmpLoadRequiredSubsystems();
|
||||
if(!NT_SUCCESS(Status)) return Status;
|
||||
|
|
|
@ -135,128 +135,6 @@ SmCreateUserProcess (LPWSTR ImagePath,
|
|||
return Status;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* NAME
|
||||
* SmLookupSubsystem/5
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Read from the registry key
|
||||
* \Registry\SYSTEM\CurrentControlSet\Control\Session Manager\Subsystems
|
||||
* the value which name is Name.
|
||||
*
|
||||
* ARGUMENTS
|
||||
* Name: name of the program to run, that is a value's name in
|
||||
* the SM registry key Subsystems;
|
||||
* Data: what the registry gave back for Name;
|
||||
* DataLength: how much Data the registry returns;
|
||||
* DataType: what is Data?
|
||||
* Expand: set it TRUE if you want this function to use the env
|
||||
* to possibly expand Data before giving it back.
|
||||
*/
|
||||
NTSTATUS STDCALL
|
||||
SmLookupSubsystem (IN PWSTR Name,
|
||||
IN OUT PWSTR Data,
|
||||
IN OUT PULONG DataLength,
|
||||
IN OUT PULONG DataType,
|
||||
IN BOOLEAN Expand)
|
||||
{
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
UNICODE_STRING usKeyName = {0};
|
||||
OBJECT_ATTRIBUTES Oa = {0};
|
||||
HANDLE hKey = (HANDLE) 0;
|
||||
|
||||
DPRINT("SM: %s(Name='%S') called\n", __FUNCTION__, Name);
|
||||
/*
|
||||
* Prepare the key name to scan and
|
||||
* related object attributes.
|
||||
*/
|
||||
RtlInitUnicodeString (& usKeyName,
|
||||
L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\SubSystems");
|
||||
|
||||
InitializeObjectAttributes (& Oa,
|
||||
& usKeyName,
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
NULL,
|
||||
NULL);
|
||||
/*
|
||||
* Open the key. This MUST NOT fail, if the
|
||||
* request is for a legitimate subsystem.
|
||||
*/
|
||||
Status = NtOpenKey (& hKey,
|
||||
MAXIMUM_ALLOWED,
|
||||
& Oa);
|
||||
if(NT_SUCCESS(Status))
|
||||
{
|
||||
UNICODE_STRING usValueName = {0};
|
||||
WCHAR KeyValueInformation [1024] = {L'\0'};
|
||||
ULONG ResultLength = 0L;
|
||||
PKEY_VALUE_PARTIAL_INFORMATION
|
||||
kvpi = (PKEY_VALUE_PARTIAL_INFORMATION) KeyValueInformation;
|
||||
|
||||
|
||||
RtlInitUnicodeString (& usValueName, Name);
|
||||
Status = NtQueryValueKey (hKey,
|
||||
& usValueName,
|
||||
KeyValuePartialInformation,
|
||||
KeyValueInformation,
|
||||
sizeof KeyValueInformation,
|
||||
& ResultLength);
|
||||
if(NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("nkvpi.TitleIndex = %ld\n", kvpi->TitleIndex);
|
||||
DPRINT("kvpi.Type = %ld\n", kvpi->Type);
|
||||
DPRINT("kvpi.DataLength = %ld\n", kvpi->DataLength);
|
||||
|
||||
if((NULL != Data) && (NULL != DataLength) && (NULL != DataType))
|
||||
{
|
||||
*DataType = kvpi->Type;
|
||||
if((Expand) && (REG_EXPAND_SZ == *DataType))
|
||||
{
|
||||
UNICODE_STRING Source;
|
||||
WCHAR DestinationBuffer [2048] = {0};
|
||||
UNICODE_STRING Destination;
|
||||
ULONG Length = 0;
|
||||
|
||||
DPRINT("SM: %s: value will be expanded\n", __FUNCTION__);
|
||||
|
||||
Source.Length = kvpi->DataLength;
|
||||
Source.MaximumLength = kvpi->DataLength;
|
||||
Source.Buffer = (PWCHAR) & kvpi->Data;
|
||||
|
||||
Destination.Length = 0;
|
||||
Destination.MaximumLength = sizeof DestinationBuffer;
|
||||
Destination.Buffer = DestinationBuffer;
|
||||
|
||||
Status = RtlExpandEnvironmentStrings_U (SmSystemEnvironment,
|
||||
& Source,
|
||||
& Destination,
|
||||
& Length);
|
||||
if(NT_SUCCESS(Status))
|
||||
{
|
||||
*DataLength = min(*DataLength, Destination.Length);
|
||||
RtlCopyMemory (Data, Destination.Buffer, *DataLength);
|
||||
}
|
||||
|
||||
}else{
|
||||
DPRINT("SM: %s: value won't be expanded\n", __FUNCTION__);
|
||||
*DataLength = min(*DataLength, kvpi->DataLength);
|
||||
RtlCopyMemory (Data, & kvpi->Data, *DataLength);
|
||||
}
|
||||
*DataType = kvpi->Type;
|
||||
}else{
|
||||
DPRINT1("SM: %s: Data or DataLength or DataType is NULL!\n", __FUNCTION__);
|
||||
Status = STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
}else{
|
||||
DPRINT1("%s: NtQueryValueKey failed (Status=0x%08lx)\n", __FUNCTION__, Status);
|
||||
}
|
||||
NtClose (hKey);
|
||||
}else{
|
||||
DPRINT1("%s: NtOpenKey failed (Status=0x%08lx)\n", __FUNCTION__, Status);
|
||||
}
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* SmExecPgm/1 API
|
||||
|
@ -298,7 +176,7 @@ SMAPI(SmExecPgm)
|
|||
Data,
|
||||
& DataLength,
|
||||
& DataType,
|
||||
TRUE); /* expand */
|
||||
SmSystemEnvironment /* expand */);
|
||||
if(NT_SUCCESS(Status))
|
||||
{
|
||||
/* Is the subsystem definition non-empty? */
|
||||
|
|
|
@ -61,12 +61,6 @@ NTSTATUS STDCALL SmCreateUserProcess(LPWSTR ImagePath,
|
|||
BOOLEAN WaitForIt,
|
||||
PLARGE_INTEGER Timeout OPTIONAL,
|
||||
PRTL_PROCESS_INFO UserProcessInfo OPTIONAL);
|
||||
NTSTATUS STDCALL
|
||||
SmLookupSubsystem (IN PWSTR Name,
|
||||
IN OUT PWSTR Data,
|
||||
IN OUT PULONG DataLength,
|
||||
IN OUT PULONG DataType,
|
||||
IN BOOLEAN Expand);
|
||||
NTSTATUS FASTCALL SmExecPgm(PSM_PORT_MESSAGE);
|
||||
|
||||
/* smapicomp.c */
|
||||
|
|
Loading…
Reference in a new issue