Anyone planning on looking into this in the near term? It could be fixed relatively easily in MZ_Exec() if I knew of some way to get the environment variables and their values. I'm not sure if the same kind of fix would apply to fixing CreateProcess().
Chris
From: "Eric POUECH" Eric.Pouech@wanadoo.fr Date: 2002/09/24 Tue PM 04:48:24 EDT To: cmorgan@alum.wpi.edu, wine-devel@winehq.com Subject: Re: another MZ_Exec() problem...
Inside of MZ_Exec() I call out to CreateProcessA() if the executable is PE. I've set the lpEnvironment parameter of CreateProcessA() to null to have it inherit the environment of the caller but this isn't working correctly. The path and other environment variables aren't being inherited. Ideas on how to either get CreateProcessA() to inherit properly or where I can find the environment settings? I noticed the env_ptr in the parmeter block but I'm unsure if this is what I'm looking for or where to find more information about it.
moreover, explicit env heritage (ie passed in CreateProcess) is currently bugged A+
I've been looking into exactly what is broken with environment passing in CreateProcess() and the functions it uses. What appears to be breaking things at this point is just what Eric mentioned, that we mess with the PATH environment variable inside of fork_and_exec() and then we call out to execve() with this modified environment. It appears that we really do need to mess with the PATH environment variable to ensure that execve() finds things in the correct unix path locations. I was thinking that before we execve() that we could copy the current PATH into a variable called __PATH. We would then restore PATH in PROCESS_InitWine() from this __PATH. Any thoughts or other ideas on how to solve the environment passing problem, maybe passing the data via wineserver?
Thanks, Chris
From: "Eric POUECH" Eric.Pouech@wanadoo.fr Date: 2002/09/24 Tue PM 04:48:24 EDT To: cmorgan@alum.wpi.edu, wine-devel@winehq.com Subject: Re: another MZ_Exec() problem...
Inside of MZ_Exec() I call out to CreateProcessA() if the executable is PE. I've set the lpEnvironment parameter of CreateProcessA() to null to have it inherit the environment of the caller but this isn't working correctly. The path and other environment variables aren't being inherited. Ideas on how to either get CreateProcessA() to inherit properly or where I can find the environment settings? I noticed the env_ptr in the parmeter block but I'm unsure if this is what I'm looking for or where to find more information about it.
moreover, explicit env heritage (ie passed in CreateProcess) is currently bugged A+
Chris Morgan cmorgan@alum.wpi.edu writes:
I've been looking into exactly what is broken with environment passing in CreateProcess() and the functions it uses. What appears to be breaking things at this point is just what Eric mentioned, that we mess with the PATH environment variable inside of fork_and_exec() and then we call out to execve() with this modified environment. It appears that we really do need to mess with the PATH environment variable to ensure that execve() finds things in the correct unix path locations. I was thinking that before we execve() that we could copy the current PATH into a variable called __PATH. We would then restore PATH in PROCESS_InitWine() from this __PATH.
Yes, I wrote a patch some time ago to do this, here it is. I think it should still work but I haven't tested it. Let me know if it works for you and I'll put it in.
Index: files/directory.c =================================================================== RCS file: /opt/cvs-commit/wine/files/directory.c,v retrieving revision 1.54 diff -u -r1.54 directory.c --- files/directory.c 13 Sep 2002 18:52:01 -0000 1.54 +++ files/directory.c 8 Oct 2002 15:09:58 -0000 @@ -160,17 +160,21 @@ DRIVE_Chdir( drive, DIR_Windows.short_name + 2 ); }
- PROFILE_GetWineIniString(wineW, pathW, path_dirW, longpath, MAX_PATHNAME_LEN); - if (strchrW(longpath, '/')) + /* Set the environment variables */ + + /* set PATH only if not set already */ + if (!GetEnvironmentVariableW( path_capsW, longpath, MAX_PATHNAME_LEN )) { - MESSAGE("Fix your wine config to use DOS drive syntax in [wine] 'Path=' statement! (no '/' allowed)\n"); - PROFILE_UsageWineIni(); - ExitProcess(1); + PROFILE_GetWineIniString(wineW, pathW, path_dirW, longpath, MAX_PATHNAME_LEN); + if (strchrW(longpath, '/')) + { + MESSAGE("Fix your wine config to use DOS drive syntax in [wine] 'Path=' statement! (no '/' allowed)\n"); + PROFILE_UsageWineIni(); + ExitProcess(1); + } + SetEnvironmentVariableW( path_capsW, longpath ); }
- /* Set the environment variables */ - - SetEnvironmentVariableW( path_capsW, longpath ); SetEnvironmentVariableW( temp_capsW, tmp_dir.short_name ); SetEnvironmentVariableW( tmp_capsW, tmp_dir.short_name ); SetEnvironmentVariableW( windirW, DIR_Windows.short_name ); Index: memory/environ.c =================================================================== RCS file: /opt/cvs-commit/wine/memory/environ.c,v retrieving revision 1.37 diff -u -r1.37 environ.c --- memory/environ.c 24 Sep 2002 18:29:40 -0000 1.37 +++ memory/environ.c 8 Oct 2002 15:10:07 -0000 @@ -152,7 +152,11 @@ /* Compute the total size of the Unix environment */
size = sizeof(BYTE) + sizeof(WORD) + sizeof(ENV_program_name); - for (e = environ; *e; e++) size += strlen(*e) + 1; + for (e = environ; *e; e++) + { + if (!memcmp( *e, "PATH=", 5 )) continue; + size += strlen(*e) + 1; + }
/* Now allocate the environment */
@@ -164,7 +168,10 @@
for (e = environ; *e; e++) { - strcpy( p, *e ); + /* skip Unix PATH and store WINEPATH as PATH */ + if (!memcmp( *e, "PATH=", 5 )) continue; + if (!memcmp( *e, "WINEPATH=", 9 )) strcpy( p, *e + 4 ); + else strcpy( p, *e ); p += strlen(p) + 1; }
Index: scheduler/process.c =================================================================== RCS file: /opt/cvs-commit/wine/scheduler/process.c,v retrieving revision 1.200 diff -u -r1.200 process.c --- scheduler/process.c 3 Oct 2002 19:54:57 -0000 1.200 +++ scheduler/process.c 8 Oct 2002 15:10:10 -0000 @@ -820,9 +820,16 @@ /* now put the Windows environment strings */ for (p = env; *p; p += strlen(p) + 1) { - if (memcmp( p, "PATH=", 5 ) && - memcmp( p, "HOME=", 5 ) && - memcmp( p, "WINEPREFIX=", 11 )) *envptr++ = (char *)p; + if (!memcmp( p, "PATH=", 5 )) /* store PATH as WINEPATH */ + { + char *winepath = malloc( strlen(p) + 5 ); + strcpy( winepath, "WINE" ); + strcpy( winepath + 4, p ); + *envptr++ = winepath; + } + else if (memcmp( p, "HOME=", 5 ) && + memcmp( p, "WINEPATH=", 9 ) && + memcmp( p, "WINEPREFIX=", 11 )) *envptr++ = (char *)p; } *envptr = 0; }