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
>>
>

Reply via email to