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/p... ============================================================================== --- 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/csrs... ============================================================================== --- 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;