- Changed BasepConvertUnicodeEnvironment to obtain the calculated length.

- Optimized the calculation of the environment length.  
- Disable the execution of vdm for com-files, because it breaks the execution of batch files.
- Removed an unused variable.


svn path=/trunk/; revision=16926
This commit is contained in:
Hartmut Birr 2005-07-31 21:27:56 +00:00
parent bec5197e46
commit 2f708e9f44

View file

@ -80,7 +80,8 @@ BaseProcessStartup(PPROCESS_START_ROUTINE lpStartAddress)
NTSTATUS NTSTATUS
STDCALL STDCALL
BasepNotifyCsrOfCreation(ULONG dwCreationFlags, BasepNotifyCsrOfCreation(ULONG dwCreationFlags,
IN HANDLE ProcessId) IN HANDLE ProcessId,
IN BOOL InheritHandles)
{ {
ULONG Request = CREATE_PROCESS; ULONG Request = CREATE_PROCESS;
CSR_API_MESSAGE CsrRequest; CSR_API_MESSAGE CsrRequest;
@ -92,6 +93,7 @@ BasepNotifyCsrOfCreation(ULONG dwCreationFlags,
/* Fill out the request */ /* Fill out the request */
CsrRequest.Data.CreateProcessRequest.NewProcessId = ProcessId; CsrRequest.Data.CreateProcessRequest.NewProcessId = ProcessId;
CsrRequest.Data.CreateProcessRequest.Flags = dwCreationFlags; CsrRequest.Data.CreateProcessRequest.Flags = dwCreationFlags;
CsrRequest.Data.CreateProcessRequest.bInheritHandles = InheritHandles;
/* Call CSR */ /* Call CSR */
Status = CsrClientCallServer(&CsrRequest, Status = CsrClientCallServer(&CsrRequest,
@ -164,10 +166,10 @@ BasepCreateFirstThread(HANDLE ProcessHandle,
*/ */
PVOID PVOID
STDCALL STDCALL
BasepConvertUnicodeEnvironment(IN PVOID lpEnvironment) BasepConvertUnicodeEnvironment(OUT SIZE_T* EnvSize,
IN PVOID lpEnvironment)
{ {
PCHAR pcScan; PCHAR pcScan;
SIZE_T EnvSize = 0;
ANSI_STRING AnsiEnv; ANSI_STRING AnsiEnv;
UNICODE_STRING UnicodeEnv; UNICODE_STRING UnicodeEnv;
NTSTATUS Status; NTSTATUS Status;
@ -175,31 +177,43 @@ BasepConvertUnicodeEnvironment(IN PVOID lpEnvironment)
DPRINT("BasepConvertUnicodeEnvironment\n"); DPRINT("BasepConvertUnicodeEnvironment\n");
/* Scan the environment to calculate its Unicode size */ /* Scan the environment to calculate its Unicode size */
AnsiEnv.Buffer = pcScan = lpEnvironment; AnsiEnv.Buffer = pcScan = (PCHAR)lpEnvironment;
while (*pcScan) while (*pcScan++); while (*pcScan)
{
pcScan += strlen(pcScan) + 1;
}
/* Create our ANSI String */ /* Create our ANSI String */
AnsiEnv.Length = (ULONG_PTR)pcScan - (ULONG_PTR)lpEnvironment + 1; if (pcScan == (PCHAR)lpEnvironment)
{
AnsiEnv.Length = 2 * sizeof(CHAR);
}
else
{
AnsiEnv.Length = (ULONG_PTR)pcScan - (ULONG_PTR)lpEnvironment + sizeof(CHAR);
}
AnsiEnv.MaximumLength = AnsiEnv.Length + 1; AnsiEnv.MaximumLength = AnsiEnv.Length + 1;
/* Allocate memory for the Unicode Environment */ /* Allocate memory for the Unicode Environment */
UnicodeEnv.Buffer = NULL; UnicodeEnv.Buffer = NULL;
EnvSize = AnsiEnv.MaximumLength * sizeof(WCHAR); *EnvSize = AnsiEnv.MaximumLength * sizeof(WCHAR);
Status = NtAllocateVirtualMemory(NtCurrentProcess(), Status = NtAllocateVirtualMemory(NtCurrentProcess(),
(PVOID)&UnicodeEnv.Buffer, (PVOID)&UnicodeEnv.Buffer,
0, 0,
&EnvSize, EnvSize,
MEM_COMMIT, MEM_COMMIT,
PAGE_READWRITE); PAGE_READWRITE);
/* Failure */ /* Failure */
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
SetLastError(Status); SetLastError(Status);
*EnvSize = 0;
return NULL; return NULL;
} }
/* Use the allocated size */ /* Use the allocated size */
UnicodeEnv.MaximumLength = EnvSize; UnicodeEnv.MaximumLength = *EnvSize;
/* Convert */ /* Convert */
RtlAnsiStringToUnicodeString(&UnicodeEnv, &AnsiEnv, FALSE); RtlAnsiStringToUnicodeString(&UnicodeEnv, &AnsiEnv, FALSE);
@ -332,7 +346,8 @@ BasepInitializeEnvironment(HANDLE ProcessHandle,
LPWSTR ApplicationPathName, LPWSTR ApplicationPathName,
LPWSTR lpCurrentDirectory, LPWSTR lpCurrentDirectory,
LPWSTR lpCommandLine, LPWSTR lpCommandLine,
LPVOID Environment, LPVOID lpEnvironment,
SIZE_T EnvSize,
LPSTARTUPINFOW StartupInfo, LPSTARTUPINFOW StartupInfo,
DWORD CreationFlags, DWORD CreationFlags,
BOOL InheritHandles) BOOL InheritHandles)
@ -350,6 +365,7 @@ BasepInitializeEnvironment(HANDLE ProcessHandle,
ULONG Size; ULONG Size;
UNICODE_STRING Desktop, Shell, Runtime, Title; UNICODE_STRING Desktop, Shell, Runtime, Title;
PPEB OurPeb = NtCurrentPeb(); PPEB OurPeb = NtCurrentPeb();
LPVOID Environment = lpEnvironment;
DPRINT("BasepInitializeEnvironment\n"); DPRINT("BasepInitializeEnvironment\n");
@ -437,10 +453,28 @@ BasepInitializeEnvironment(HANDLE ProcessHandle,
/* Find the environment size */ /* Find the environment size */
if (ScanChar) if (ScanChar)
{ {
while (*ScanChar) while (*ScanChar++); if (EnvSize && Environment == lpEnvironment)
{
/* Calculate the size of the block */ /* its a converted ansi environment, bypass the length calculation */
EnviroSize = (ULONG)((ULONG_PTR)ScanChar - (ULONG_PTR)Environment); EnviroSize = EnvSize;
}
else
{
while (*ScanChar)
{
ScanChar += wcslen(ScanChar) + 1;
}
/* Calculate the size of the block */
if (ScanChar == Environment)
{
EnviroSize = 2 * sizeof(WCHAR);
}
else
{
EnviroSize = (ULONG)((ULONG_PTR)ScanChar - (ULONG_PTR)Environment + sizeof(WCHAR));
}
}
DPRINT("EnvironmentSize %ld\n", EnviroSize); DPRINT("EnvironmentSize %ld\n", EnviroSize);
/* Allocate and Initialize new Environment Block */ /* Allocate and Initialize new Environment Block */
@ -513,7 +547,7 @@ BasepInitializeEnvironment(HANDLE ProcessHandle,
BasepCopyHandles(ProcessParameters, BasepCopyHandles(ProcessParameters,
OurPeb->ProcessParameters, OurPeb->ProcessParameters,
InheritHandles); InheritHandles);
} }
} }
/* Also set the Console Flag */ /* Also set the Console Flag */
@ -741,7 +775,6 @@ CreateProcessW(LPCWSTR lpApplicationName,
LPWSTR BatchCommandLine; LPWSTR BatchCommandLine;
ULONG CmdLineLength; ULONG CmdLineLength;
UNICODE_STRING CommandLineString; UNICODE_STRING CommandLineString;
LPWSTR TempBuffer;
PWCHAR Extension; PWCHAR Extension;
LPWSTR QuotedCmdLine = NULL; LPWSTR QuotedCmdLine = NULL;
LPWSTR ScanString; LPWSTR ScanString;
@ -754,6 +787,7 @@ CreateProcessW(LPCWSTR lpApplicationName,
CLIENT_ID ClientId; CLIENT_ID ClientId;
PPEB OurPeb = NtCurrentPeb(); PPEB OurPeb = NtCurrentPeb();
PPEB RemotePeb; PPEB RemotePeb;
SIZE_T EnvSize = 0;
DPRINT("CreateProcessW: lpApplicationName: %S lpCommandLine: %S" DPRINT("CreateProcessW: lpApplicationName: %S lpCommandLine: %S"
" lpEnvironment: %p lpCurrentDirectory: %S dwCreationFlags: %lx\n", " lpEnvironment: %p lpCurrentDirectory: %S dwCreationFlags: %lx\n",
@ -838,13 +872,6 @@ CreateProcessW(LPCWSTR lpApplicationName,
PriorityClass.Foreground = FALSE; PriorityClass.Foreground = FALSE;
PriorityClass.PriorityClass = BasepConvertPriorityClass(dwCreationFlags); PriorityClass.PriorityClass = BasepConvertPriorityClass(dwCreationFlags);
/* Convert the environment */
if(lpEnvironment && !(dwCreationFlags & CREATE_UNICODE_ENVIRONMENT))
{
lpEnvironment = BasepConvertUnicodeEnvironment(lpEnvironment);
if (!lpEnvironment) return FALSE;
}
/* Get the application name and do all the proper formating necessary */ /* Get the application name and do all the proper formating necessary */
GetAppName: GetAppName:
/* See if we have an application name (oh please let us have one!) */ /* See if we have an application name (oh please let us have one!) */
@ -1042,8 +1069,9 @@ GetAppName:
case STATUS_INVALID_IMAGE_PROTECT: case STATUS_INVALID_IMAGE_PROTECT:
case STATUS_INVALID_IMAGE_NOT_MZ: case STATUS_INVALID_IMAGE_NOT_MZ:
/* If it's a DOS app, use VDM #if 0
if ((BasepCheckDosApp(&ApplicationName))) */ /* If it's a DOS app, use VDM */
if ((BasepCheckDosApp(&ApplicationName)))
{ {
DPRINT1("Launching VDM...\n"); DPRINT1("Launching VDM...\n");
RtlFreeHeap(GetProcessHeap(), 0, NameBuffer); RtlFreeHeap(GetProcessHeap(), 0, NameBuffer);
@ -1058,8 +1086,8 @@ GetAppName:
lpCurrentDirectory, lpCurrentDirectory,
lpStartupInfo, lpStartupInfo,
lpProcessInformation); lpProcessInformation);
} }
#endif
/* It's a batch file */ /* It's a batch file */
Extension = &ApplicationName.Buffer[ApplicationName.Length / Extension = &ApplicationName.Buffer[ApplicationName.Length /
sizeof(WCHAR) - 4]; sizeof(WCHAR) - 4];
@ -1103,10 +1131,8 @@ GetAppName:
lpApplicationName = NULL; lpApplicationName = NULL;
/* Free memory */ /* Free memory */
RtlFreeHeap(GetProcessHeap(), 0, TempBuffer);
RtlFreeHeap(GetProcessHeap(), 0, ApplicationName.Buffer); RtlFreeHeap(GetProcessHeap(), 0, ApplicationName.Buffer);
ApplicationName.Buffer = NULL; ApplicationName.Buffer = NULL;
TempBuffer = NULL;
goto GetAppName; goto GetAppName;
break; break;
@ -1287,6 +1313,13 @@ GetAppName:
sizeof(ProcessBasicInfo), sizeof(ProcessBasicInfo),
NULL); NULL);
/* Convert the environment */
if(lpEnvironment && !(dwCreationFlags & CREATE_UNICODE_ENVIRONMENT))
{
lpEnvironment = BasepConvertUnicodeEnvironment(&EnvSize, lpEnvironment);
if (!lpEnvironment) return FALSE;
}
/* Create Process Environment */ /* Create Process Environment */
RemotePeb = ProcessBasicInfo.PebBaseAddress; RemotePeb = ProcessBasicInfo.PebBaseAddress;
Status = BasepInitializeEnvironment(hProcess, Status = BasepInitializeEnvironment(hProcess,
@ -1296,9 +1329,17 @@ GetAppName:
(QuotesNeeded || CmdLineIsAppName) ? (QuotesNeeded || CmdLineIsAppName) ?
QuotedCmdLine : lpCommandLine, QuotedCmdLine : lpCommandLine,
lpEnvironment, lpEnvironment,
EnvSize,
lpStartupInfo, lpStartupInfo,
dwCreationFlags, dwCreationFlags,
bInheritHandles); bInheritHandles);
/* Cleanup Environment */
if (lpEnvironment && !(dwCreationFlags & CREATE_UNICODE_ENVIRONMENT))
{
RtlDestroyEnvironment(lpEnvironment);
}
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT1("Could not initialize Process Environment\n"); DPRINT1("Could not initialize Process Environment\n");
@ -1357,7 +1398,8 @@ GetAppName:
/* Notify CSRSS */ /* Notify CSRSS */
Status = BasepNotifyCsrOfCreation(dwCreationFlags, Status = BasepNotifyCsrOfCreation(dwCreationFlags,
(HANDLE)ProcessBasicInfo.UniqueProcessId); (HANDLE)ProcessBasicInfo.UniqueProcessId,
bInheritHandles);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
@ -1371,12 +1413,6 @@ GetAppName:
NtResumeThread(hThread, &Dummy); NtResumeThread(hThread, &Dummy);
} }
/* Cleanup Environment */
if (lpEnvironment && !(dwCreationFlags & CREATE_UNICODE_ENVIRONMENT))
{
RtlDestroyEnvironment(lpEnvironment);
}
/* Return Data */ /* Return Data */
lpProcessInformation->dwProcessId = (DWORD)ClientId.UniqueProcess; lpProcessInformation->dwProcessId = (DWORD)ClientId.UniqueProcess;
lpProcessInformation->dwThreadId = (DWORD)ClientId.UniqueThread; lpProcessInformation->dwThreadId = (DWORD)ClientId.UniqueThread;