- Simplified the converting of environment variables.

svn path=/trunk/; revision=9407
This commit is contained in:
Hartmut Birr 2004-05-15 20:25:09 +00:00
parent 4b6ab2d1c6
commit aa82813f06

View file

@ -1,4 +1,4 @@
/* $Id: create.c,v 1.84 2004/05/15 19:24:59 hbirr Exp $ /* $Id: create.c,v 1.85 2004/05/15 20:25:09 hbirr Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries * PROJECT: ReactOS system libraries
@ -100,19 +100,16 @@ VOID STDCALL RtlRosR32AttribsToNativeAttribsNamed
/* /*
* @implemented * @implemented
*/ */
BOOL STDCALL CreateProcessA BOOL STDCALL CreateProcessA(LPCSTR lpApplicationName,
( LPSTR lpCommandLine,
LPCSTR lpApplicationName, LPSECURITY_ATTRIBUTES lpProcessAttributes,
LPSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpThreadAttributes,
LPSECURITY_ATTRIBUTES lpProcessAttributes, BOOL bInheritHandles,
LPSECURITY_ATTRIBUTES lpThreadAttributes, DWORD dwCreationFlags,
BOOL bInheritHandles, LPVOID lpEnvironment,
DWORD dwCreationFlags, LPCSTR lpCurrentDirectory,
LPVOID lpEnvironment, LPSTARTUPINFOA lpStartupInfo,
LPCSTR lpCurrentDirectory, LPPROCESS_INFORMATION lpProcessInformation)
LPSTARTUPINFOA lpStartupInfo,
LPPROCESS_INFORMATION lpProcessInformation
)
/* /*
* FUNCTION: The CreateProcess function creates a new process and its * FUNCTION: The CreateProcess function creates a new process and its
* primary thread. The new process executes the specified executable file * primary thread. The new process executes the specified executable file
@ -130,185 +127,159 @@ BOOL STDCALL CreateProcessA
* lpProcessInformation = Pointer to process information * lpProcessInformation = Pointer to process information
*/ */
{ {
PWCHAR pwcEnv = NULL; UNICODE_STRING wstrApplicationName;
UNICODE_STRING wstrApplicationName; UNICODE_STRING wstrCurrentDirectory;
UNICODE_STRING wstrCurrentDirectory; UNICODE_STRING wstrCommandLine;
UNICODE_STRING wstrCommandLine; UNICODE_STRING wstrReserved;
UNICODE_STRING wstrReserved; UNICODE_STRING wstrDesktop;
UNICODE_STRING wstrDesktop; UNICODE_STRING wstrTitle;
UNICODE_STRING wstrTitle; UNICODE_STRING wstrEnvVar;
ANSI_STRING strApplicationName; ANSI_STRING strApplicationName;
ANSI_STRING strCurrentDirectory; ANSI_STRING strCurrentDirectory;
ANSI_STRING strCommandLine; ANSI_STRING strCommandLine;
ANSI_STRING strReserved; ANSI_STRING strReserved;
ANSI_STRING strDesktop; ANSI_STRING strDesktop;
ANSI_STRING strTitle; ANSI_STRING strTitle;
BOOL bRetVal; BOOL bRetVal;
STARTUPINFOW wsiStartupInfo; STARTUPINFOW wsiStartupInfo;
NTSTATUS STDCALL_FUNC (*pTrue) NTSTATUS STDCALL_FUNC (*pTrue)
( (
UNICODE_STRING *, UNICODE_STRING *,
ANSI_STRING *, ANSI_STRING *,
BOOLEAN BOOLEAN
); );
ULONG STDCALL_FUNC (*pRtlMbStringToUnicodeSize)(ANSI_STRING *); ULONG STDCALL_FUNC (*pRtlMbStringToUnicodeSize)(ANSI_STRING *);
DPRINT("CreateProcessA(%s)\n", lpApplicationName); DPRINT("dwCreationFlags %x, lpEnvironment %x, lpCurrentDirectory %x, "
"lpStartupInfo %x, lpProcessInformation %x\n",
dwCreationFlags, lpEnvironment, lpCurrentDirectory,
lpStartupInfo, lpProcessInformation);
DPRINT /* multibyte strings are ANSI */
( if(bIsFileApiAnsi)
"dwCreationFlags %x, lpEnvironment %x, lpCurrentDirectory %x, " {
"lpStartupInfo %x, lpProcessInformation %x\n", pTrue = RtlAnsiStringToUnicodeString;
dwCreationFlags, pRtlMbStringToUnicodeSize = RtlAnsiStringToUnicodeSize;
lpEnvironment, }
lpCurrentDirectory, /* multibyte strings are OEM */
lpStartupInfo, else
lpProcessInformation {
); pTrue = RtlOemStringToUnicodeString;
pRtlMbStringToUnicodeSize = RtlOemStringToUnicodeSize;
}
/* invalid parameter */ /* invalid parameter */
if(lpStartupInfo == NULL) if(lpStartupInfo == NULL)
{ {
SetLastError(ERROR_INVALID_PARAMETER); SetLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
/* multibyte strings are ANSI */ /* convert the environment */
if(bIsFileApiAnsi) if(lpEnvironment && !(dwCreationFlags & CREATE_UNICODE_ENVIRONMENT))
{ {
pTrue = RtlAnsiStringToUnicodeString; PCHAR pcScan;
pRtlMbStringToUnicodeSize = RtlAnsiStringToUnicodeSize; SIZE_T nEnvLen = 0;
} ANSI_STRING strEnvVar;
/* multibyte strings are OEM */ NTSTATUS Status;
else
{
pTrue = RtlOemStringToUnicodeString;
pRtlMbStringToUnicodeSize = RtlOemStringToUnicodeSize;
}
/* convert the environment */ /* scan the environment to calculate its Unicode size */
if(lpEnvironment && !(dwCreationFlags & CREATE_UNICODE_ENVIRONMENT)) pcScan = lpEnvironment;
{ do
PCHAR pcScan; {
SIZE_T nEnvLen = 0; pcScan += strlen(pcScan) + 1;
UNICODE_STRING wstrEnvVar; }
ANSI_STRING strEnvVar; while (*pcScan);
/* scan the environment to calculate its Unicode size */ nEnvLen = (ULONG_PTR)pcScan - (ULONG_PTR)lpEnvironment + 1;
for(pcScan = lpEnvironment; *pcScan; pcScan += strEnvVar.Length + sizeof(char))
{ /* environment too large */
/* add the size of the current variable */ if(nEnvLen > ~((USHORT)0))
RtlInitAnsiString(&strEnvVar, pcScan); {
nEnvLen += pRtlMbStringToUnicodeSize(&strEnvVar) + sizeof(WCHAR); SetLastError(ERROR_OUTOFMEMORY);
} return FALSE;
}
/* add the size of the final NUL character */ strEnvVar.Buffer = lpEnvironment;
nEnvLen += sizeof(WCHAR); strEnvVar.MaximumLength = strEnvVar.Length = nEnvLen;
/* environment too large */ Status = K32MbStrToWcStr(pTrue, &wstrEnvVar, &strEnvVar, TRUE);
if(nEnvLen > ~((USHORT)0))
{
SetLastError(ERROR_OUTOFMEMORY);
return FALSE;
}
/* allocate the Unicode environment */ /* failure */
pwcEnv = (PWCHAR)RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, nEnvLen); if (!NT_SUCCESS(Status))
{
SetLastError(ERROR_OUTOFMEMORY);
return FALSE;
}
}
/* failure */ /* convert the strings */
if(pwcEnv == NULL) RtlInitAnsiString(&strCommandLine, lpCommandLine);
{ RtlInitAnsiString(&strApplicationName, (LPSTR)lpApplicationName);
SetLastError(ERROR_OUTOFMEMORY); RtlInitAnsiString(&strCurrentDirectory, (LPSTR)lpCurrentDirectory);
return FALSE; RtlInitAnsiString(&strReserved, (LPSTR)lpStartupInfo->lpReserved);
} RtlInitAnsiString(&strDesktop, (LPSTR)lpStartupInfo->lpDesktop);
RtlInitAnsiString(&strTitle, (LPSTR)lpStartupInfo->lpTitle);
wstrEnvVar.Buffer = pwcEnv; K32MbStrToWcStr(pTrue, &wstrCommandLine, &strCommandLine, TRUE);
wstrEnvVar.Length = 0; K32MbStrToWcStr(pTrue, &wstrApplicationName, &strApplicationName, TRUE);
wstrEnvVar.MaximumLength = nEnvLen; K32MbStrToWcStr(pTrue, &wstrCurrentDirectory, &strCurrentDirectory, TRUE);
K32MbStrToWcStr(pTrue, &wstrReserved, &strReserved, TRUE);
K32MbStrToWcStr(pTrue, &wstrDesktop, &strDesktop, TRUE);
K32MbStrToWcStr(pTrue, &wstrTitle, &strTitle, TRUE);
/* scan the environment to convert it */ /* convert the startup information */
for(pcScan = lpEnvironment; *pcScan; pcScan += strEnvVar.Length + sizeof(char)) memcpy(&wsiStartupInfo, lpStartupInfo, sizeof(wsiStartupInfo));
{
/* convert the current variable */
RtlInitAnsiString(&strEnvVar, pcScan);
K32MbStrToWcStr(pTrue, &wstrEnvVar, &strEnvVar, FALSE);
/* advance the buffer to the next variable */ wsiStartupInfo.lpReserved = wstrReserved.Buffer;
wstrEnvVar.Buffer += (wstrEnvVar.Length / sizeof(WCHAR) + 1); wsiStartupInfo.lpDesktop = wstrDesktop.Buffer;
wstrEnvVar.MaximumLength -= (wstrEnvVar.Length + sizeof(WCHAR)); wsiStartupInfo.lpTitle = wstrTitle.Buffer;
wstrEnvVar.Length = 0;
}
/* final NUL character */ DPRINT("wstrApplicationName %wZ\n", &wstrApplicationName);
wstrEnvVar.Buffer[0] = 0; DPRINT("wstrCommandLine %wZ\n", &wstrCommandLine);
} DPRINT("wstrCurrentDirectory %wZ\n", &wstrCurrentDirectory);
DPRINT("wstrReserved %wZ\n", &wstrReserved);
DPRINT("wstrDesktop %wZ\n", &wstrDesktop);
DPRINT("wstrTitle %wZ\n", &wstrTitle);
/* convert the strings */ DPRINT("wstrApplicationName.Buffer %p\n", wstrApplicationName.Buffer);
RtlInitAnsiString(&strCommandLine, lpCommandLine); DPRINT("wstrCommandLine.Buffer %p\n", wstrCommandLine.Buffer);
RtlInitAnsiString(&strApplicationName, (LPSTR)lpApplicationName); DPRINT("wstrCurrentDirectory.Buffer %p\n", wstrCurrentDirectory.Buffer);
RtlInitAnsiString(&strCurrentDirectory, (LPSTR)lpCurrentDirectory); DPRINT("wstrReserved.Buffer %p\n", wstrReserved.Buffer);
RtlInitAnsiString(&strReserved, (LPSTR)lpStartupInfo->lpReserved); DPRINT("wstrDesktop.Buffer %p\n", wstrDesktop.Buffer);
RtlInitAnsiString(&strDesktop, (LPSTR)lpStartupInfo->lpDesktop); DPRINT("wstrTitle.Buffer %p\n", wstrTitle.Buffer);
RtlInitAnsiString(&strTitle, (LPSTR)lpStartupInfo->lpTitle);
K32MbStrToWcStr(pTrue, &wstrCommandLine, &strCommandLine, TRUE); DPRINT("sizeof(STARTUPINFOA) %lu\n", sizeof(STARTUPINFOA));
K32MbStrToWcStr(pTrue, &wstrApplicationName, &strApplicationName, TRUE); DPRINT("sizeof(STARTUPINFOW) %lu\n", sizeof(STARTUPINFOW));
K32MbStrToWcStr(pTrue, &wstrCurrentDirectory, &strCurrentDirectory, TRUE);
K32MbStrToWcStr(pTrue, &wstrReserved, &strReserved, TRUE);
K32MbStrToWcStr(pTrue, &wstrDesktop, &strDesktop, TRUE);
K32MbStrToWcStr(pTrue, &wstrTitle, &strTitle, TRUE);
/* convert the startup information */ /* call the Unicode function */
memcpy(&wsiStartupInfo, lpStartupInfo, sizeof(wsiStartupInfo)); bRetVal = CreateProcessW(wstrApplicationName.Buffer,
wstrCommandLine.Buffer,
lpProcessAttributes,
lpThreadAttributes,
bInheritHandles,
dwCreationFlags,
!lpEnvironment || (dwCreationFlags & CREATE_UNICODE_ENVIRONMENT) ? lpEnvironment : wstrEnvVar.Buffer,
wstrCurrentDirectory.Buffer,
&wsiStartupInfo,
lpProcessInformation);
wsiStartupInfo.lpReserved = wstrReserved.Buffer; RtlFreeUnicodeString(&wstrApplicationName);
wsiStartupInfo.lpDesktop = wstrDesktop.Buffer; RtlFreeUnicodeString(&wstrCommandLine);
wsiStartupInfo.lpTitle = wstrTitle.Buffer; RtlFreeUnicodeString(&wstrCurrentDirectory);
RtlFreeUnicodeString(&wstrReserved);
RtlFreeUnicodeString(&wstrDesktop);
RtlFreeUnicodeString(&wstrTitle);
DPRINT("wstrApplicationName %wZ\n", &wstrApplicationName); if (lpEnvironment && !(dwCreationFlags & CREATE_UNICODE_ENVIRONMENT))
DPRINT("wstrCommandLine %wZ\n", &wstrCommandLine); {
DPRINT("wstrCurrentDirectory %wZ\n", &wstrCurrentDirectory); RtlFreeUnicodeString(&wstrEnvVar);
DPRINT("wstrReserved %wZ\n", &wstrReserved); }
DPRINT("wstrDesktop %wZ\n", &wstrDesktop);
DPRINT("wstrTitle %wZ\n", &wstrTitle);
DPRINT("wstrApplicationName.Buffer %p\n", wstrApplicationName.Buffer); return bRetVal;
DPRINT("wstrCommandLine.Buffer %p\n", wstrCommandLine.Buffer);
DPRINT("wstrCurrentDirectory.Buffer %p\n", wstrCurrentDirectory.Buffer);
DPRINT("wstrReserved.Buffer %p\n", wstrReserved.Buffer);
DPRINT("wstrDesktop.Buffer %p\n", wstrDesktop.Buffer);
DPRINT("wstrTitle.Buffer %p\n", wstrTitle.Buffer);
DPRINT("sizeof(STARTUPINFOA) %lu\n", sizeof(STARTUPINFOA));
DPRINT("sizeof(STARTUPINFOW) %lu\n", sizeof(STARTUPINFOW));
/* call the Unicode function */
bRetVal = CreateProcessW
(
wstrApplicationName.Buffer,
wstrCommandLine.Buffer,
lpProcessAttributes,
lpThreadAttributes,
bInheritHandles,
dwCreationFlags,
dwCreationFlags & CREATE_UNICODE_ENVIRONMENT ? lpEnvironment : pwcEnv,
wstrCurrentDirectory.Buffer,
&wsiStartupInfo,
lpProcessInformation
);
RtlFreeUnicodeString(&wstrApplicationName);
RtlFreeUnicodeString(&wstrCommandLine);
RtlFreeUnicodeString(&wstrCurrentDirectory);
RtlFreeUnicodeString(&wstrReserved);
RtlFreeUnicodeString(&wstrDesktop);
RtlFreeUnicodeString(&wstrTitle);
RtlFreeHeap(GetProcessHeap(), 0, pwcEnv);
return bRetVal;
} }