Just following up on this one - Mark posted some feedback on my original patch, which I think is now addressed. https://issues.apache.org/jira/browse/DAEMON-401. If someone is able to take a look, that would be much appreciated. I'm happy to make any other changes, or run any necessary test cases.
Thanks! Jon On Tue, Apr 16, 2019 at 11:04 AM Jonathan Gallimore < jonathan.gallim...@gmail.com> wrote: > My attachment might be scrubbed off by the mailing list. Its available > here: https://gist.github.com/jgallimore/aa84b1d580a8ba579e960a709ac1d235. > > Thanks > > Jon > > On Tue, Apr 16, 2019 at 11:02 AM Jonathan Gallimore < > jonathan.gallim...@gmail.com> wrote: > >> Hi, >> >> I've been looking at an issue where using a JNI library built with MSVC >> 14 with TomEE under Windows 2016 as a service with commons-daemon isn't >> able to pick up environment variables set for the service using getenv(). >> >> I note from >> https://github.com/apache/commons-daemon/tree/master/src/native/windows >> that the build chain is VC 6 and Platform SDK for Windows Server 2003 R2 - >> the build with that fails with and error on this line for me: >> https://github.com/apache/commons-daemon/blob/master/src/native/windows/src/log.c#L61 >> - >> if I change "10000000ULL" to "10000000i64", it compiles and links ok. >> >> Doing a "dumpbin /headers prunsrv.exe" on the 1.1.0 release shows a >> linker version of 9.00, and looking at the imports, it uses msvcrt.dll (as >> opposed to msvcrt800.dll). I'd like to get my build chain as close as >> possible to what's actually used to create the binaries that are >> distributed. Is there a more recent buildchain (DDK?) that uses a later >> compiler/linker, but still uses msvcrt.dll rather than msvcrtXX.dll? >> >> While digging further into the issue, it appears that different runtime >> DLLs effectively get their own copy of the environment, and the JNI library >> built with VC14 is using ucrtbase.dll for getenv, while commons-daemon is >> adding entries from to the environment using _wputenv in msvcrt.dll. The >> attached code demonstrates this. This article looks related as well: >> https://docs.microsoft.com/en-us/cpp/c-runtime-library/potential-errors-passing-crt-objects-across-dll-boundaries?view=vs-2019 >> >> I have experimented with dynamically loading ucrtbase.dll and calling its >> _wputenv() in addition to the _wputenv() call in msvcrt in commons-daemon, >> and doing nothing if the library or function isn't present. I need to do >> more testing on this, but my setInprocEnvironment() function looks like >> this: >> >> static void setInprocEnvironment() >> { >> LPWSTR p, e; >> HINSTANCE hinstUcrtLib; >> WPUTENV wputenv_ucrt; >> >> if (!SO_ENVIRONMENT) >> return; /* Nothing to do */ >> >> hinstUcrtLib = LoadLibrary(TEXT("ucrtbase.dll")); >> >> if (hinstUcrtLib != NULL) { >> wputenv_ucrt = (WPUTENV) GetProcAddress(hinstUcrtLib, "_wputenv"); >> } >> >> for (p = SO_ENVIRONMENT; *p; p++) { >> e = apxExpandStrW(gPool, p); >> _wputenv(e); >> >> if (wputenv_ucrt != NULL) { >> wputenv_ucrt(e); >> } >> >> apxFree(e); >> while (*p) >> p++; >> } >> >> if (hinstUcrtLib != NULL) { >> FreeLibrary(hinstUcrtLib); >> } >> } >> >> This does work for my specific use-case, but I don't know if this is a >> "good" approach, or something that the community would consider adopting. >> I'd be grateful for feedback, and I'm happy to try different approaches and >> create patches - I probably just need some pointers. >> >> I did also try calling SetEnvironmentVariableW() (which didn't work, >> although its possible I made a mistake, so I can certainly try it again). >> Compiling commons-daemon with VC14 did appear to work, but that has the >> issue of loading in specific versions of msvcrtXX.dll which sounds rather >> undesirable. >> >> Many thanks >> >> Jon >> >