Author: ion
Date: Mon Jan 16 21:27:50 2012
New Revision: 54986
URL:
http://svn.reactos.org/svn/reactos?rev=54986&view=rev
Log:
[KERNEL32]: Reimplement BasePushProcessParameters for future extensibility, also cleanup
some code paths and fix a few bugs.
[KERNEL32]: Add some more SXS and CSRSS structures.
Modified:
trunk/reactos/dll/win32/kernel32/client/proc.c
trunk/reactos/dll/win32/kernel32/include/kernel32.h
trunk/reactos/include/ndk/rtltypes.h
trunk/reactos/include/reactos/subsys/csrss/csrss.h
Modified: trunk/reactos/dll/win32/kernel32/client/proc.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/client/…
==============================================================================
--- trunk/reactos/dll/win32/kernel32/client/proc.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/kernel32/client/proc.c [iso-8859-1] Mon Jan 16 21:27:50 2012
@@ -774,57 +774,33 @@
}
}
-VOID
-WINAPI
-BasepCopyHandles(IN PRTL_USER_PROCESS_PARAMETERS Params,
- IN PRTL_USER_PROCESS_PARAMETERS PebParams,
- IN BOOL InheritHandles)
-{
- DPRINT("BasepCopyHandles %p %p, %d\n", Params, PebParams, InheritHandles);
-
- /* Copy the handle if we are inheriting or if it's a console handle */
- if ((InheritHandles) || (IsConsoleHandle(PebParams->StandardInput)))
- {
- Params->StandardInput = PebParams->StandardInput;
- }
-
- if ((InheritHandles) || (IsConsoleHandle(PebParams->StandardOutput)))
- {
- Params->StandardOutput = PebParams->StandardOutput;
- }
-
- if ((InheritHandles) || (IsConsoleHandle(PebParams->StandardError)))
- {
- Params->StandardError = PebParams->StandardError;
- }
-}
-
-NTSTATUS
-WINAPI
-BasePushProcessParameters(IN HANDLE ProcessHandle,
- IN PPEB Peb,
- IN LPWSTR ApplicationPathName,
+BOOLEAN
+WINAPI
+BasePushProcessParameters(IN ULONG ParameterFlags,
+ IN HANDLE ProcessHandle,
+ IN PPEB RemotePeb,
+ IN LPCWSTR ApplicationPathName,
IN LPWSTR lpCurrentDirectory,
IN LPWSTR lpCommandLine,
IN LPVOID lpEnvironment,
- IN SIZE_T EnvSize,
IN LPSTARTUPINFOW StartupInfo,
IN DWORD CreationFlags,
- IN BOOL InheritHandles)
+ IN BOOL InheritHandles,
+ IN ULONG ImageSubsystem,
+ IN PVOID AppCompatData,
+ IN ULONG AppCompatDataSize)
{
WCHAR FullPath[MAX_PATH + 5];
- LPWSTR Remaining;
- LPWSTR DllPathString;
- PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
- PRTL_USER_PROCESS_PARAMETERS RemoteParameters = NULL;
+ PWCHAR Remaining, DllPathString, ScanChar;
+ PRTL_USER_PROCESS_PARAMETERS ProcessParameters, RemoteParameters;
+ PVOID RemoteAppCompatData;
UNICODE_STRING DllPath, ImageName, CommandLine, CurrentDirectory;
+ UNICODE_STRING Desktop, Shell, Runtime, Title;
NTSTATUS Status;
- PWCHAR ScanChar;
ULONG EnviroSize;
SIZE_T Size;
- UNICODE_STRING Desktop, Shell, Runtime, Title;
- PPEB OurPeb = NtCurrentPeb();
- LPVOID Environment = lpEnvironment;
+ BOOLEAN HavePebLock = FALSE, Result;
+ PPEB Peb = NtCurrentPeb();
DPRINT("BasePushProcessParameters\n");
/* Get the full path name */
@@ -835,9 +811,14 @@
if ((Size) && (Size <= (MAX_PATH + 4)))
{
/* Get the DLL Path */
- DllPathString = BaseComputeProcessDllPath(ApplicationPathName,
- Environment);
- if (!DllPathString) return STATUS_NO_MEMORY;
+ DllPathString = BaseComputeProcessDllPath((LPWSTR)ApplicationPathName,
+ lpEnvironment);
+ if (!DllPathString)
+ {
+ /* Fail */
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ return FALSE;
+ }
/* Initialize Strings */
RtlInitUnicodeString(&DllPath, DllPathString);
@@ -846,14 +827,18 @@
else
{
/* Get the DLL Path */
- DllPathString = BaseComputeProcessDllPath(FullPath, Environment);
- if (!DllPathString) return STATUS_NO_MEMORY;
+ DllPathString = BaseComputeProcessDllPath(FullPath, lpEnvironment);
+ if (!DllPathString)
+ {
+ /* Fail */
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ return FALSE;
+ }
/* Initialize Strings */
RtlInitUnicodeString(&DllPath, DllPathString);
RtlInitUnicodeString(&ImageName, FullPath);
}
- DPRINT("DllPath: %wZ, ImageName: %wZ\n", DllPath, ImageName);
/* Initialize Strings */
RtlInitUnicodeString(&CommandLine, lpCommandLine);
@@ -889,38 +874,50 @@
Runtime.Buffer = (LPWSTR)StartupInfo->lpReserved2;
Runtime.MaximumLength = Runtime.Length = StartupInfo->cbReserved2;
+ /* Enforce no app compat data if the pointer was NULL */
+ if (!AppCompatData) AppCompatDataSize = 0;
+
/* Create the Parameter Block */
- DPRINT("Creating Process Parameters: %wZ %wZ %wZ %wZ %wZ %wZ %wZ\n",
- &ImageName, &DllPath, &CommandLine, &Desktop, &Title,
&Shell,
- &Runtime);
+ ProcessParameters = NULL;
Status = RtlCreateProcessParameters(&ProcessParameters,
&ImageName,
&DllPath,
lpCurrentDirectory ?
&CurrentDirectory : NULL,
&CommandLine,
- Environment,
+ lpEnvironment,
&Title,
&Desktop,
&Shell,
&Runtime);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to create process parameters!\n");
- return Status;
- }
+ if (!NT_SUCCESS(Status)) goto FailPath;
/* Clear the current directory handle if not inheriting */
if (!InheritHandles) ProcessParameters->CurrentDirectory.Handle = NULL;
+ /* Check if the user passed in an environment */
+ if (lpEnvironment)
+ {
+ /* We should've made it part of the parameters block, enforce this */
+ ASSERT(ProcessParameters->Environment == lpEnvironment);
+ lpEnvironment = ProcessParameters->Environment;
+ }
+ else
+ {
+ /* The user did not, so use the one from the current PEB */
+ HavePebLock = TRUE;
+ RtlAcquirePebLock();
+ lpEnvironment = Peb->ProcessParameters->Environment;
+ }
+
/* Save pointer and start lookup */
- Environment = ScanChar = ProcessParameters->Environment;
- if (Environment)
+ ScanChar = lpEnvironment;
+ if (lpEnvironment)
{
/* Find the environment size */
- while (*ScanChar) ScanChar += wcslen(ScanChar) + 1;
- EnviroSize = (ULONG_PTR)ScanChar - (ULONG_PTR)Environment;
- DPRINT("EnvironmentSize %ld\n", EnviroSize);
+ while ((ScanChar[0]) || (ScanChar[1])) ++ScanChar;
+ ScanChar += (2 * sizeof(UNICODE_NULL));
+ EnviroSize = (ULONG_PTR)ScanChar - (ULONG_PTR)lpEnvironment;
/* Allocate and Initialize new Environment Block */
Size = EnviroSize;
@@ -931,23 +928,25 @@
&Size,
MEM_COMMIT,
PAGE_READWRITE);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to allocate Environment Block\n");
- return Status;
- }
+ if (!NT_SUCCESS(Status)) goto FailPath;
/* Write the Environment Block */
Status = ZwWriteVirtualMemory(ProcessHandle,
ProcessParameters->Environment,
- Environment,
+ lpEnvironment,
EnviroSize,
NULL);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to write Environment Block\n");
- return Status;
- }
+
+ /* No longer need the PEB lock anymore */
+ if (HavePebLock)
+ {
+ /* Release it */
+ RtlReleasePebLock();
+ HavePebLock = FALSE;
+ }
+
+ /* Check if the write failed */
+ if (!NT_SUCCESS(Status)) goto FailPath;
}
/* Write new parameters */
@@ -965,7 +964,6 @@
if (StartupInfo->dwFlags &
(STARTF_USESTDHANDLES | STARTF_USEHOTKEY | STARTF_SHELLPRIVATE))
{
- DPRINT("Using Standard Handles\n");
ProcessParameters->StandardInput = StartupInfo->hStdInput;
ProcessParameters->StandardOutput = StartupInfo->hStdOutput;
ProcessParameters->StandardError = StartupInfo->hStdError;
@@ -987,17 +985,28 @@
else
{
/* Inherit our Console Handle */
- ProcessParameters->ConsoleHandle =
OurPeb->ProcessParameters->ConsoleHandle;
-
- /* Is the shell trampling on our Handles? */
+ ProcessParameters->ConsoleHandle =
Peb->ProcessParameters->ConsoleHandle;
+
+ /* Make sure that the shell isn't trampling on our handles first */
if (!(StartupInfo->dwFlags &
(STARTF_USESTDHANDLES | STARTF_USEHOTKEY | STARTF_SHELLPRIVATE)))
{
- /* Use handles from PEB, if inheriting or they are console */
- DPRINT("Copying handles from parent\n");
- BasepCopyHandles(ProcessParameters,
- OurPeb->ProcessParameters,
- InheritHandles);
+ /* Copy the handle if we are inheriting or if it's a console handle */
+ if ((InheritHandles) ||
+ (IsConsoleHandle(Peb->ProcessParameters->StandardInput)))
+ {
+ ProcessParameters->StandardInput =
Peb->ProcessParameters->StandardInput;
+ }
+ if ((InheritHandles) ||
+ (IsConsoleHandle(Peb->ProcessParameters->StandardOutput)))
+ {
+ ProcessParameters->StandardOutput =
Peb->ProcessParameters->StandardOutput;
+ }
+ if ((InheritHandles) ||
+ (IsConsoleHandle(Peb->ProcessParameters->StandardError)))
+ {
+ ProcessParameters->StandardError =
Peb->ProcessParameters->StandardError;
+ }
}
}
@@ -1009,30 +1018,27 @@
}
/* See if the first 1MB should be reserved */
- if ((ULONG_PTR)ApplicationPathName & 1)
+ if (ParameterFlags & 1)
{
ProcessParameters->Flags |= RTL_USER_PROCESS_PARAMETERS_RESERVE_1MB;
}
/* See if the first 16MB should be reserved */
- if ((ULONG_PTR)ApplicationPathName & 2)
+ if (ParameterFlags & 2)
{
ProcessParameters->Flags |= RTL_USER_PROCESS_PARAMETERS_RESERVE_16MB;
}
/* Allocate memory for the parameter block */
Size = ProcessParameters->Length;
+ RemoteParameters = NULL;
Status = NtAllocateVirtualMemory(ProcessHandle,
(PVOID*)&RemoteParameters,
0,
&Size,
MEM_COMMIT,
PAGE_READWRITE);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to allocate Parameters Block\n");
- return Status;
- }
+ if (!NT_SUCCESS(Status)) goto FailPath;
/* Set the allocated size */
ProcessParameters->MaximumLength = Size;
@@ -1053,33 +1059,71 @@
ProcessParameters,
ProcessParameters->Length,
NULL);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to write Parameters Block\n");
- return Status;
- }
+ if (!NT_SUCCESS(Status)) goto FailPath;
/* Write the PEB Pointer */
Status = NtWriteVirtualMemory(ProcessHandle,
- &Peb->ProcessParameters,
+ &RemotePeb->ProcessParameters,
&RemoteParameters,
sizeof(PVOID),
NULL);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to write Parameters Block\n");
- return Status;
- }
-
- /* FIXME: Write Peb->ImageSubSystem */
-
-
+ if (!NT_SUCCESS(Status)) goto FailPath;
+
+ /* Check if there's any app compat data to write */
+ RemoteAppCompatData = NULL;
+ if (AppCompatData)
+ {
+ /* Allocate some space for the application compatibility data */
+ Size = AppCompatDataSize;
+ Status = NtAllocateVirtualMemory(ProcessHandle,
+ &RemoteAppCompatData,
+ 0,
+ &Size,
+ MEM_COMMIT,
+ PAGE_READWRITE);
+ if (!NT_SUCCESS(Status)) goto FailPath;
+
+ /* Write the application compatibility data */
+ Status = NtWriteVirtualMemory(ProcessHandle,
+ RemoteAppCompatData,
+ AppCompatData,
+ AppCompatDataSize,
+ NULL);
+ if (!NT_SUCCESS(Status)) goto FailPath;
+ }
+
+ /* Write the PEB Pointer to the app compat data (might be NULL) */
+ Status = NtWriteVirtualMemory(ProcessHandle,
+ &RemotePeb->pShimData,
+ &RemoteAppCompatData,
+ sizeof(PVOID),
+ NULL);
+ if (!NT_SUCCESS(Status)) goto FailPath;
+
+ /* Now write Peb->ImageSubSystem */
+ if (ImageSubsystem)
+ {
+ NtWriteVirtualMemory(ProcessHandle,
+ &RemotePeb->ImageSubsystem,
+ &ImageSubsystem,
+ sizeof(ImageSubsystem),
+ NULL);
+ }
+
+ /* Success path */
+ Result = TRUE;
+
+Quickie:
/* Cleanup */
+ if (HavePebLock) RtlReleasePebLock();
RtlFreeHeap(RtlGetProcessHeap(), 0, DllPath.Buffer);
- RtlDestroyProcessParameters(ProcessParameters);
-
- DPRINT("Completed\n");
- return STATUS_SUCCESS;
+ if (ProcessParameters) RtlDestroyProcessParameters(ProcessParameters);
+ return Result;
+FailPath:
+ DPRINT1("Failure to create proecss parameters: %lx\n", Status);
+ BaseSetLastNTError(Status);
+ Result = FALSE;
+ goto Quickie;
}
VOID
@@ -3058,29 +3102,26 @@
/* Create Process Environment */
RemotePeb = ProcessBasicInfo.PebBaseAddress;
- Status = BasePushProcessParameters(hProcess,
- RemotePeb,
- (LPWSTR)lpApplicationName,
- CurrentDirectory,
- (QuotesNeeded || CmdLineIsAppName || Escape) ?
- QuotedCmdLine : lpCommandLine,
- lpEnvironment,
- EnvSize,
- &StartupInfo,
- dwCreationFlags,
- bInheritHandles);
+ Ret = BasePushProcessParameters(0,
+ hProcess,
+ RemotePeb,
+ (LPWSTR)lpApplicationName,
+ CurrentDirectory,
+ (QuotesNeeded || CmdLineIsAppName || Escape) ?
+ QuotedCmdLine : lpCommandLine,
+ lpEnvironment,
+ &StartupInfo,
+ dwCreationFlags,
+ bInheritHandles,
+ 0,
+ NULL,
+ 0);
+ if (!Ret) goto Cleanup;
/* Cleanup Environment */
if (lpEnvironment && !(dwCreationFlags & CREATE_UNICODE_ENVIRONMENT))
{
RtlDestroyEnvironment(lpEnvironment);
- }
-
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Could not initialize Process Environment\n");
- BaseSetLastNTError(Status);
- goto Cleanup;
}
/* Close the section */
Modified: trunk/reactos/dll/win32/kernel32/include/kernel32.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/include…
==============================================================================
--- trunk/reactos/dll/win32/kernel32/include/kernel32.h [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/kernel32/include/kernel32.h [iso-8859-1] Mon Jan 16 21:27:50
2012
@@ -450,6 +450,19 @@
LARGE_INTEGER ViewBase;
} BASE_MSG_SXS_HANDLES, *PBASE_MSG_SXS_HANDLES;
+typedef struct _SXS_WIN32_NT_PATH_PAIR
+{
+ PUNICODE_STRING Win32;
+ PUNICODE_STRING Nt;
+} SXS_WIN32_NT_PATH_PAIR, *PSXS_WIN32_NT_PATH_PAIR;
+
+typedef struct _SXS_OVERRIDE_MANIFEST
+{
+ PCWCH Name;
+ PVOID Address;
+ ULONG Size;
+} SXS_OVERRIDE_MANIFEST, *PSXS_OVERRIDE_MANIFEST;
+
NTSTATUS
NTAPI
BasepConfigureAppCertDlls(
@@ -464,6 +477,15 @@
extern LIST_ENTRY BasepAppCertDllsList;
extern RTL_CRITICAL_SECTION gcsAppCert;
+BOOL
+WINAPI
+BaseUpdateVDMEntry(
+ IN ULONG UpdateIndex,
+ IN OUT PHANDLE WaitHandle,
+ IN ULONG IndexInfo,
+ IN ULONG BinaryType
+);
+
VOID
WINAPI
BaseMarkFileForDelete(
@@ -471,3 +493,10 @@
IN ULONG FileAttributes
);
+/* FIXME: This is EXPORTED! It should go in an external kernel32.h header */
+VOID
+WINAPI
+BasepFreeAppCompatData(
+ IN PVOID AppCompatData,
+ IN PVOID AppCompatSxsData
+);
Modified: trunk/reactos/include/ndk/rtltypes.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/ndk/rtltypes.h?rev…
==============================================================================
--- trunk/reactos/include/ndk/rtltypes.h [iso-8859-1] (original)
+++ trunk/reactos/include/ndk/rtltypes.h [iso-8859-1] Mon Jan 16 21:27:50 2012
@@ -1380,6 +1380,26 @@
PVOID *Trace;
} RTL_TRACE_BLOCK, *PRTL_TRACE_BLOCK;
+//
+// Auto-Managed Rtl* String Buffer
+//
+typedef struct _RTL_BUFFER
+{
+ PUCHAR Buffer;
+ PUCHAR StaticBuffer;
+ SIZE_T Size;
+ SIZE_T StaticSize;
+ SIZE_T ReservedForAllocatedSize;
+ PVOID ReservedForIMalloc;
+} RTL_BUFFER, *PRTL_BUFFER;
+
+typedef struct _RTL_UNICODE_STRING_BUFFER
+{
+ UNICODE_STRING String;
+ RTL_BUFFER ByteBuffer;
+ WCHAR MinimumStaticBufferForTerminalNul;
+} RTL_UNICODE_STRING_BUFFER, *PRTL_UNICODE_STRING_BUFFER;
+
#ifndef NTOS_MODE_USER
//
Modified: trunk/reactos/include/reactos/subsys/csrss/csrss.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/reactos/subsys/csr…
==============================================================================
--- trunk/reactos/include/reactos/subsys/csrss/csrss.h [iso-8859-1] (original)
+++ trunk/reactos/include/reactos/subsys/csrss/csrss.h [iso-8859-1] Mon Jan 16 21:27:50
2012
@@ -31,11 +31,46 @@
ULONG Dummy;
} CSRSS_CONNECT_PROCESS, *PCSRSS_CONNECT_PROCESS;
-typedef struct
-{
- HANDLE NewProcessId;
- ULONG Flags;
- BOOL bInheritHandles;
+typedef struct _BASE_SXS_CREATEPROCESS_MSG
+{
+ ULONG Flags;
+ ULONG ProcessParameterFlags;
+ HANDLE FileHandle;
+ UNICODE_STRING SxsWin32ExePath;
+ UNICODE_STRING SxsNtExePath;
+ SIZE_T OverrideManifestOffset;
+ ULONG OverrideManifestSize;
+ SIZE_T OverridePolicyOffset;
+ ULONG OverridePolicySize;
+ PVOID PEManifestAddress;
+ ULONG PEManifestSize;
+ UNICODE_STRING CultureFallbacks;
+ ULONG Unknown[7];
+ UNICODE_STRING AssemblyName;
+} BASE_SXS_CREATEPROCESS_MSG, *PBASE_SXS_CREATEPROCESS_MSG;
+
+typedef struct
+{
+ //
+ // NT-type structure (BASE_CREATEPROCESS_MSG)
+ //
+ HANDLE ProcessHandle;
+ HANDLE ThreadHandle;
+ CLIENT_ID ClientId;
+ ULONG CreationFlags;
+ ULONG VdmBinaryType;
+ ULONG VdmTask;
+ HANDLE hVDM;
+ BASE_SXS_CREATEPROCESS_MSG Sxs;
+ PVOID PebAddressNative;
+ ULONG PebAddressWow64;
+ USHORT ProcessorArchitecture;
+ //
+ // ReactOS Data
+ //
+ HANDLE NewProcessId;
+ ULONG Flags;
+ BOOL bInheritHandles;
} CSRSS_CREATE_PROCESS, *PCSRSS_CREATE_PROCESS;
typedef struct
@@ -547,6 +582,38 @@
HANDLE hParent;
ULONG ExitCode;
} CSRSS_GET_VDM_EXIT_CODE, *PCSRSS_GET_VDM_EXIT_CODE;
+
+typedef struct
+{
+ ULONG iTask;
+ HANDLE ConsoleHandle;
+ ULONG BinaryType;
+ HANDLE WaitObjectForParent;
+ HANDLE StdIn;
+ HANDLE StdOut;
+ HANDLE StdErr;
+ ULONG CodePage;
+ ULONG dwCreationFlags;
+ PCHAR CmdLine;
+ PCHAR appName;
+ PCHAR PifFile;
+ PCHAR CurDirectory;
+ PCHAR Env;
+ ULONG EnvLen;
+ PVOID StartupInfo;
+ PCHAR Desktop;
+ ULONG DesktopLen;
+ PCHAR Title;
+ ULONG TitleLen;
+ PCHAR Reserved;
+ ULONG ReservedLen;
+ USHORT CmdLen;
+ USHORT AppLen;
+ USHORT PifLen;
+ USHORT CurDirectoryLen;
+ USHORT CurDrive;
+ USHORT VDMState;
+} CSRSS_CHECK_VDM, *PCSRSS_CHECK_VDM;
#define CSR_API_MESSAGE_HEADER_SIZE(Type) (FIELD_OFFSET(CSR_API_MESSAGE, Data) +
sizeof(Type))
#define CSRSS_MAX_WRITE_CONSOLE (LPC_MAX_DATA_LENGTH -
CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE))
@@ -632,6 +699,7 @@
#define SOUND_SENTRY (0x50)
#define UPDATE_VDM_ENTRY (0x51)
#define GET_VDM_EXIT_CODE (0x52)
+#define CHECK_VDM (0x53)
/* Keep in sync with definition below. */
#define CSRSS_HEADER_SIZE (sizeof(PORT_MESSAGE) + sizeof(ULONG) + sizeof(NTSTATUS))
@@ -718,6 +786,7 @@
CSRSS_SOUND_SENTRY SoundSentryRequest;
CSRSS_UPDATE_VDM_ENTRY UpdateVdmEntry;
CSRSS_GET_VDM_EXIT_CODE GetVdmExitCode;
+ CSRSS_CHECK_VDM CheckVdm;
} Data;
} CSR_API_MESSAGE, *PCSR_API_MESSAGE;