Thread: Can a windows DLL have more than one process attached?

Can a windows DLL have more than one process attached?

From
Tom Lane
Date:
In reviewing some recent patches I notice the following code added to
src/interfaces/libpq/libpqdll.c:

BOOL WINAPI
DllMain(HINSTANCE hinstDLL, DWORD fdwReason,       LPVOID lpReserved)
{   switch (fdwReason)   {       case DLL_PROCESS_ATTACH:           ...           if (netmsgModule == NULL)
 netmsgModule = LoadLibraryEx("netmsg.dll", NULL, LOAD_LIBRARY_AS_DATAFILE);           break;       case
DLL_PROCESS_DETACH:          if (netmsgModule != NULL)               FreeLibrary(netmsgModule);           ...
break;  }
 
}

where netmsgModule is

static HINSTANCE netmsgModule = NULL;

This sure looks to me like it will fail miserably if more than one
process can attach to the DLL concurrently: won't the first one to
detach release the netmsg library, breaking access to it for all the
remaining processes?

I don't know enough about Windows to know if there's really a problem
here, but the code looks fishy to me.  I'd expect to need a reference
count.  Comments anyone?
        regards, tom lane


Re: Can a windows DLL have more than one process attached?

From
"Ross J. Reedstrom"
Date:
On Tue, Nov 27, 2001 at 01:31:40PM -0500, Tom Lane wrote:
> In reviewing some recent patches I notice the following code added to
> src/interfaces/libpq/libpqdll.c:
> 
> BOOL WINAPI
> DllMain(HINSTANCE hinstDLL, DWORD fdwReason,
>         LPVOID lpReserved)
> {
>     switch (fdwReason)
>     {
>         case DLL_PROCESS_ATTACH:
>             ...
>             if (netmsgModule == NULL)
>                 netmsgModule = LoadLibraryEx("netmsg.dll", NULL, LOAD_LIBRARY_AS_DATAFILE);
>             break;
>         case DLL_PROCESS_DETACH:
>             if (netmsgModule != NULL)
>                 FreeLibrary(netmsgModule);
>             ...
>             break;
>     }
> }
> 
> where netmsgModule is
> 
> static HINSTANCE netmsgModule = NULL;
> 
> This sure looks to me like it will fail miserably if more than one
> process can attach to the DLL concurrently: won't the first one to
> detach release the netmsg library, breaking access to it for all the
> remaining processes?
> 
> I don't know enough about Windows to know if there's really a problem
> here, but the code looks fishy to me.  I'd expect to need a reference
> count.  Comments anyone?

I'm not much of a WinAPI coder, either, but ISTR something from the Wine
project, and found this:

http://www.allapi.net/apilist/apifunction.php?apifunction=FreeLibrary
FreeLibrary
The FreeLibrary function decrements the reference count of theloaded dynamic-link library (DLL) module.

So it's doing the reference counting.

'Offical' reference at:

http://msdn.microsoft.com/library/en-us/dllproc/dll_3cs9.asp?frame=false

However, there's another problem. According to the above, and:

http://msdn.microsoft.com/library/en-us/dllproc/dll_4abc.asp?frame=true

It is not safe to call FreeLibrary or LoadLibraryEx from DllMain.

Which points to:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/dll_8asu.asp
Warning  On attach, the body of your DLL entry-point functionshould perform only simple initialization tasks, such
assettingup thread local storage (TLS), creating objects, andopening files. You must not call LoadLibrary  in the
entry-pointfunction,because you may create dependency loops in the DLL loadorder. This can result in a DLL being used
beforethe systemhas executed its initialization code. Similarly, you must notcall the FreeLibrary  function in the
entry-pointfunction ondetach, because this can result in a DLL being used after thesystem has executed its termination
code.


Any real windows coders know if this is a problem?

Ross


Re: Can a windows DLL have more than one process attached?

From
Tom Lane
Date:
"Ross J. Reedstrom" <reedstrm@rice.edu> writes:
>     The FreeLibrary function decrements the reference count of the
>     loaded dynamic-link library (DLL) module.
> So it's doing the reference counting.

Yeah, but what increments the reference count?  I could believe the code
was okay if it did LoadLibraryEx (which presumably increments the count)
on *every* attach call, but it does that only once, whereas it'll do
FreeLibrary on each detach.

However, we may have worse problems.

> It is not safe to call FreeLibrary or LoadLibraryEx from DllMain.

This looks ugly, although I'm not sure if it's really a problem for us.
I don't see how our pointing to netmsg could create a dependency loop.

I'm also wondering just exactly how Microsoft expects one DLL to be able
to safely reference another, if it's unsafe to call FreeLibrary during
detach --- what else are you supposed to do, leak the reference count?

If this is a problem, a possible answer is not to try to cache the
netmsg reference at all, but just to load and unload that DLL at the
single point where it's used.  Since we only use it to translate
socket error reports, there's probably no big performance penalty
involved to do it that way.
        regards, tom lane


Re: Can a windows DLL have more than one process attached?

From
"Ross J. Reedstrom"
Date:
On Tue, Nov 27, 2001 at 01:01:47PM -0600, Ross J. Reedstrom wrote:
> 
> However, there's another problem. According to the above, and:
> 
> http://msdn.microsoft.com/library/en-us/dllproc/dll_4abc.asp?frame=true
> 
> It is not safe to call FreeLibrary or LoadLibraryEx from DllMain.
> 
> Which points to:
> 
> http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/dll_8asu.asp
> 
>     Warning  On attach, the body of your DLL entry-point function
>     should perform only simple initialization tasks, such as
>     setting up thread local storage (TLS), creating objects, and
>     opening files. You must not call LoadLibrary  in the entry-point
>     function, because you may create dependency loops in the DLL load
>     order. This can result in a DLL being used before the system
>     has executed its initialization code. Similarly, you must not
>     call the FreeLibrary  function in the entry-point function on
>     detach, because this can result in a DLL being used after the
>     system has executed its termination code.
> 
> 
> Any real windows coders know if this is a problem?
> 

Reading into this further, it seems to me that this code is attempting to
implement DLL dependencies. I'd think that the DLL loader is _supposed_
to handle that automatically (based on te docmuentation for LoadLibrary
mentioning that it can cause dependent libraries to also be loaded), but
I know even less about building win32 dlls than I do about coding them.
Are we mis-building somehow?

The warning above also sounds like the only problem is reference loops.

Ross


Re: Can a windows DLL have more than one process attached?

From
Tom Lane
Date:
"Ross J. Reedstrom" <reedstrm@rice.edu> writes:
> Reading into this further, it seems to me that this code is attempting to
> implement DLL dependencies. I'd think that the DLL loader is _supposed_
> to handle that automatically (based on te docmuentation for LoadLibrary
> mentioning that it can cause dependent libraries to also be loaded), but
> I know even less about building win32 dlls than I do about coding them.

Ditto.  But, looking at the cvs logs, it seems that the use of netmsg
was inserted rather hastily, and it may well be done completely the
wrong way.

I'm not sure that declaring a dependency to the DLL loader is the way we
want to go though; wouldn't that cause the system to refuse to run libpq
at all unless netmsg was available?  That's certainly not the behavior
we want, considering that netmsg is only a fallback source of error
strings in the first place, and that we can fall back to "no error text
available" if we can't load it.

Loading and unloading on-the-fly in winsock_strerror is looking better
and better to me.
        regards, tom lane


Re: Can a windows DLL have more than one process attached?

From
Tom Lane
Date:
Actually, the more I look at this, the more broken it looks.

(1) netmsgModule and winsock_strerror_buf are declared as static
variables in libpq/win32.h.  Unless Windows has some truly creative new
interpretation of static variables, this means that there'll be a
separate instance of these vars in each .c file that #includes win32.h.
Wasting half a K of space per .c file is the least of the consequences.

(2) Since libpqdll.c and fe-misc.c don't share the same instance of
netmsgModule, winsock_strerror will always see it as NULL regardless
of what DllMain has done or not done.

(3) Even if winsock_strerror saw netmsgModule, it doesn't pass it to
FormatMessage, which means (if I'm reading the documentation I found on
the net correctly) that the wrong message table would be searched.
I think that the "0" parameter should be netmsgModule instead.

Have we got any people who actually know the Windows platform and
can confirm or deny these points?

I'd be happy to change the code to something that looks reasonable to
me, but I'm in no position to test it.
        regards, tom lane


Re: Can a windows DLL have more than one process attached?

From
"Magnus Hagander"
Date:
> > It is not safe to call FreeLibrary or LoadLibraryEx from DllMain.
> 
> This looks ugly, although I'm not sure if it's really a problem for
us.
> I don't see how our pointing to netmsg could create a dependency loop.
Shouldn't happen in this case, no - it's probably a generic warning
message... Still, it's not recommended behaviour...


> I'm also wondering just exactly how Microsoft expects one DLL 
> to be able
> to safely reference another, if it's unsafe to call FreeLibrary during
> detach --- what else are you supposed to do, leak the reference count?
If you reference the library during compilation (e.g. you link with the
.LIB file that corresponds to the .DLL), the OS will handle that as part
of the CreateProcess() call.


As for the FreeLibrary problem, you also have to deal with:
There are cases in which the entry-point function is called for a
terminating thread even if the DLL never attached to the thread - for
example, the entry-point function was never called with the
DLL_THREAD_ATTACH value in the context of the thread in either of these
two situations: 
* The thread was the initial thread in the process, so the system called
the entry-point function with the DLL_PROCESS_ATTACH value. 
* The thread was already running when a call to the LoadLibrary function
was made, so the system never called the entry-point function for it. 


In general, depending on doing things in DllMain is not a good idea.
The fact that we do WSAStartup() in it is even deprecated in the docs
now, for the same reason: "Calling Win32 functions other than TLS,
object-creation, and file functions may result in problems that are
difficult to diagnose. For example, calling User, Shell, COM, RPC, and
Windows Sockets functions (or any functions that call these functions)
can cause access violation errors, because their DLLs call LoadLibrary
to load other system components".


The question is if it should be moved to the connection functions, or if
it shuold be left up to the application to do it. Moving it to the
connection functino would be easy, but each call to WSAStartup() should
have a corresponding WSACleanup() call...
Or if we should just leave it :-) Because it appears to work...

> If this is a problem, a possible answer is not to try to cache the
> netmsg reference at all, but just to load and unload that DLL at the
> single point where it's used.  Since we only use it to translate
> socket error reports, there's probably no big performance penalty
> involved to do it that way.
That's probably the best idea.


> (1) netmsgModule and winsock_strerror_buf are declared as static
> variables in libpq/win32.h.  Unless Windows has some truly creative
new
> interpretation of static variables, this means that there'll be a
> separate instance of these vars in each .c file that #includes
win32.h.
> Wasting half a K of space per .c file is the least of the
consequences.
static is static in Windows as well (it is C, after all...) If it's
declared static in the header file, there will be a separate instance in
each C file.

> I'd be happy to change the code to something that looks reasonable to
> me, but I'm in no position to test it.
I can probably do some testing - assuming the 7.2 client libs can still
talk to 7.1 servers, since I haven't any servers up on the new version
yet...

//Magnus


Re: Can a windows DLL have more than one process attached?

From
Tom Lane
Date:
"Magnus Hagander" <mha@sollentuna.net> writes:
> In general, depending on doing things in DllMain is not a good idea.
> The fact that we do WSAStartup() in it is even deprecated in the docs
> now, ...
> The question is if it should be moved to the connection functions, or if
> it shuold be left up to the application to do it. Moving it to the
> connection functino would be easy, but each call to WSAStartup() should
> have a corresponding WSACleanup() call...
> Or if we should just leave it :-) Because it appears to work...

Well, it's been that way since day one and we've not had any reports of
problems, so I'm inclined to leave it alone until we see a problem.

However, this netmsg.dll reference is new code in 7.2 and is evidently
not well tested :-(.

>> If this is a problem, a possible answer is not to try to cache the
>> netmsg reference at all, but just to load and unload that DLL at the
>> single point where it's used.  Since we only use it to translate
>> socket error reports, there's probably no big performance penalty
>> involved to do it that way.

> That's probably the best idea.

Okay, I'll make the changes and then ask you to test it.  Do you have a
copy of netmsg.dll?

> I can probably do some testing - assuming the 7.2 client libs can still
> talk to 7.1 servers, since I haven't any servers up on the new version
> yet...

Should work fine.  But the code we're interested in testing here is a
fallback code path --- it only gets exercised if the main system doesn't
have a string for the error message.  You might need to dike out the
first FormatMessage call in winsock_strerror in order to test.
        regards, tom lane


Re: Can a windows DLL have more than one process attached?

From
Mikhail Terekhov
Date:
> where netmsgModule is
> 
> static HINSTANCE netmsgModule = NULL;
> 

That is definitely my bug (cut&paste problem:(). There shouldn't be a
static variable in *.h files. Sorry :(.


> This sure looks to me like it will fail miserably if more than one
> process can attach to the DLL concurrently: won't the first one to
> detach release the netmsg library, breaking access to it for all the
> remaining processes?
> 

There is no problem here - LoadLibrary and FreeLibrary use reference
count (see references in the Ross's message).


> I don't know enough about Windows to know if there's really a problem
> here, but the code looks fishy to me.  I'd expect to need a reference
> count.  Comments anyone?
> 
Windows really does reference count here.


Regards,
Mikhail



Re: Can a windows DLL have more than one process attached?

From
Mikhail Terekhov
Date:
 
> http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/dll_8asu.asp
> 
>     Warning  On attach, the body of your DLL entry-point function
>     should perform only simple initialization tasks, such as
>     setting up thread local storage (TLS), creating objects, and
>     opening files. You must not call LoadLibrary  in the entry-point
>     function, because you may create dependency loops in the DLL load
>     order. This can result in a DLL being used before the system
>     has executed its initialization code. Similarly, you must not
>     call the FreeLibrary  function in the entry-point function on
>     detach, because this can result in a DLL being used after the
>     system has executed its termination code.
> 

I believe that in this particular case we are safe because we load netmsg.dll
as data (LOAD_LIBRARY_AS_DATAFILE).

Regards,
Mikhail



Re: Can a windows DLL have more than one process attached?

From
Mikhail Terekhov
Date:
Tom Lane wrote:

> "Ross J. Reedstrom" <reedstrm@rice.edu> writes:
>>    The FreeLibrary function decrements the reference count of the
>>    loaded dynamic-link library (DLL) module.
>>So it's doing the reference counting.
>>
> 
> Yeah, but what increments the reference count?  I could believe the code
> was okay if it did LoadLibraryEx (which presumably increments the count)
> on *every* attach call, but it does that only once, whereas it'll do
> FreeLibrary on each detach.


LoadLibrary increments reference count and FreeLibrary decrements it on every
call not just once.

> 
> However, we may have worse problems.
> 
> 
>>It is not safe to call FreeLibrary or LoadLibraryEx from DllMain.
>>
> 
> This looks ugly, although I'm not sure if it's really a problem for us.

What is the ugliness? We load this data only once at startup and release

on exit.


> I don't see how our pointing to netmsg could create a dependency loop.


There shouldn't be a dependency loop - we load netmsg as data not a code library.

> 
> If this is a problem, a possible answer is not to try to cache the
> netmsg reference at all, but just to load and unload that DLL at the
> single point where it's used.  Since we only use it to translate


That is really ugly in my opinion.

> socket error reports, there's probably no big performance penalty
> involved to do it that way.
> 

Regards,
Mikhail



Re: Can a windows DLL have more than one process attached?

From
Mikhail Terekhov
Date:
Magnus Hagander wrote:

>
> If you reference the library during compilation (e.g. you link with the
> .LIB file that corresponds to the .DLL), the OS will handle that as part
> of the CreateProcess() call.
> 


What if the required DLL is missing (as is the case with netmsg.dll) on some
system?

> 
> As for the FreeLibrary problem, you also have to deal with:
> There are cases in which the entry-point function is called for a
> terminating thread even if the DLL never attached to the thread - for
> example, the entry-point function was never called with the
> DLL_THREAD_ATTACH value in the context of the thread in either of these
> two situations: 
> * The thread was the initial thread in the process, so the system called
> the entry-point function with the DLL_PROCESS_ATTACH value. 
> * The thread was already running when a call to the LoadLibrary function
> was made, so the system never called the entry-point function for it. 
> 


That is why it is better to do such a global initialization/finalization on
DLL_PROCESS_ATTACH/DETACH.


> 
> In general, depending on doing things in DllMain is not a good idea.
> The fact that we do WSAStartup() in it is even deprecated in the docs
> now, for the same reason: "Calling Win32 functions other than TLS,
> object-creation, and file functions may result in problems that are
> difficult to diagnose. For example, calling User, Shell, COM, RPC, and
> Windows Sockets functions (or any functions that call these functions)
> can cause access violation errors, because their DLLs call LoadLibrary
> to load other system components".
> 


In netmsg.dll case it looks very like "file function" because we load it as data.
In case of WSAStartup() consider the following scenario:
Application doesn't load libpq.dll explicitly, OS loads it during CreateProcess()
call. Suppose there is some sockets problem exists. What happens with
the application? Will it start up at all? What if this application is
still useful even without connection to DB?

> 
> The question is if it should be moved to the connection functions, or if
> it shuold be left up to the application to do it. Moving it to the
> connection functino would be easy, but each call to WSAStartup() should
> have a corresponding WSACleanup() call...
> Or if we should just leave it :-) Because it appears to work...
> 


The rcommended way is to have initialization/finalization functions in DLL.

> 
>>If this is a problem, a possible answer is not to try to cache the

>>netmsg reference at all, but just to load and unload that DLL at the
>>single point where it's used.  Since we only use it to translate
>>socket error reports, there's probably no big performance penalty
>>involved to do it that way.
>>
> That's probably the best idea.
> 
> 
> 
>>(1) netmsgModule and winsock_strerror_buf are declared as static
>>variables in libpq/win32.h.  Unless Windows has some truly creative
>>

That was my copy/paste bug, sorry again.


Regards,
Mikhail



Re: Can a windows DLL have more than one process attached?

From
Hiroshi Inoue
Date:
Mikhail Terekhov wrote:
> 
> Magnus Hagander wrote:
> 
> >
> >>(1) netmsgModule and winsock_strerror_buf are declared as static
> >>variables in libpq/win32.h.  Unless Windows has some truly creative
> >>
> 
> That was my copy/paste bug, sorry again.

I've not followed this thread properly sorry.
What's the purpose of loading netmsg.dll ?
I got no error message for winsock errors under Windows-NT
using the module.

regards,
Hiroshi Inoue


Re: Can a windows DLL have more than one process attached?

From
Tom Lane
Date:
Hiroshi Inoue <Inoue@tpf.co.jp> writes:
> What's the purpose of loading netmsg.dll ?

To get error messages under some flavors of Windows; I forget which.

> I got no error message for winsock errors under Windows-NT
> using the module.

The code as it stood was broken (static variable problem: the handle
opened by libpqdll.c was not visible in fe-misc.c).  Would
you update from CVS and see if it works better?
        regards, tom lane


Re: Can a windows DLL have more than one process attached?

From
Hiroshi Inoue
Date:
Tom Lane wrote:
> 
> Hiroshi Inoue <Inoue@tpf.co.jp> writes:
> 
> > I got no error message for winsock errors under Windows-NT
> > using the module.
> 
> The code as it stood was broken (static variable problem: the handle
> opened by libpqdll.c was not visible in fe-misc.c).  Would
> you update from CVS and see if it works better?

I changed it by myself and have tested it since yesterday.
I also tested a simple sample program. However I've got no
message for winsock errors under Windows-NT 4.0. OTOH under
Windows 2000 I can get error messages for winsock errors
without loading netmsg.dll.

regards,
Hiroshi Inoue


Re: Can a windows DLL have more than one process attached?

From
Tom Lane
Date:
Hiroshi Inoue <Inoue@tpf.co.jp> writes:
> I changed it by myself and have tested it since yesterday.
> I also tested a simple sample program. However I've got no
> message for winsock errors under Windows-NT 4.0.

It appeared to me that the parameters passed to FormatMessage
were wrong, too (the handle for netmsg.dll needs to be passed in,
I'd think).  Perhaps that explains why it still doesn't work for
you?
        regards, tom lane


Re: Can a windows DLL have more than one process attached?

From
Hiroshi Inoue
Date:
Tom Lane wrote:
> 
> Hiroshi Inoue <Inoue@tpf.co.jp> writes:
> > I changed it by myself and have tested it since yesterday.
> > I also tested a simple sample program. However I've got no
> > message for winsock errors under Windows-NT 4.0.
> 
> It appeared to me that the parameters passed to FormatMessage
> were wrong, too (the handle for netmsg.dll needs to be passed in,
> I'd think).  

I did so from the first. I also tried the latest cvs version
but the result is the same. ISTM Mikhail Terekhov referred to
the fact 3 months ago but I couldn't find the conclusion.

regards,
Hiroshi Inoue


Re: Can a windows DLL have more than one process attached?

From
Mikhail Terekhov
Date:

Hiroshi Inoue wrote:

> I did so from the first. I also tried the latest cvs version
> but the result is the same. ISTM Mikhail Terekhov referred to
> the fact 3 months ago but I couldn't find the conclusion.
> 

Do you really have this DLL on your system?

Regards,
Mikhail



Re: Can a windows DLL have more than one process attached?

From
Mikhail Terekhov
Date:
After refreshing my memory I can say for sure that it never
worked on nt4 and w98, see
http://fts.postgresql.org/db/mw/msg.html?mid=1030825

The reason is very simple: on nt4 & w98 (don't know about 95)
netmsg.dll doesn't contain socket error messages! I just checked
this on my work computer nt4(sp6).

Regards,
Mikhail

Hiroshi Inoue wrote:

> Tom Lane wrote:
> 
>>Hiroshi Inoue <Inoue@tpf.co.jp> writes:
>>
>>>I changed it by myself and have tested it since yesterday.
>>>I also tested a simple sample program. However I've got no
>>>message for winsock errors under Windows-NT 4.0.
>>>
>>It appeared to me that the parameters passed to FormatMessage
>>were wrong, too (the handle for netmsg.dll needs to be passed in,
>>I'd think).  
>>
> 
> I did so from the first. I also tried the latest cvs version
> but the result is the same. ISTM Mikhail Terekhov referred to
> the fact 3 months ago but I couldn't find the conclusion.
> 
> regards,
> Hiroshi Inoue
> 
> ---------------------------(end of broadcast)---------------------------
> TIP 1: subscribe and unsubscribe commands go to majordomo@postgresql.org
> 



Re: Can a windows DLL have more than one process attached?

From
Tom Lane
Date:
Mikhail Terekhov <terekhov@emc.com> writes:
> The reason is very simple: on nt4 & w98 (don't know about 95)
> netmsg.dll doesn't contain socket error messages! I just checked
> this on my work computer nt4(sp6).

Ooops.  Well, are there any WINxx platforms where netmsg *does* have
something useful?  Or is the entire code path a waste of time?

Is there some other DLL we could look in instead?
        regards, tom lane


Re: Can a windows DLL have more than one process attached?

From
"Magnus Hagander"
Date:
> Mikhail Terekhov <terekhov@emc.com> writes:
> > The reason is very simple: on nt4 & w98 (don't know about 95)
> > netmsg.dll doesn't contain socket error messages! I just checked
> > this on my work computer nt4(sp6).
> 
> Ooops.  Well, are there any WINxx platforms where netmsg *does* have
> something useful?  Or is the entire code path a waste of time?

Never checked this before, but according to:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/netmgmt
/ntlmapi_5pwz.asp
(from the latest platform SDK - I think)
and
http://support.microsoft.com/directory/article.asp?ID=KB;EN-US;Q149409
(which references NT 3.51, so it's pretty old, but *probably* still
valid..)

It clearly states:
"
The error text for these messages is found in the message table file
named Netmsg.dll, which is found in %systemroot%\system32. This file
contains error messages in the range NERR_BASE (2100) through
MAX_NERR(NERR_BASE+899). These error codes are defined in the SDK header
file lmerr.h.
"

This means errors for the Net*** functions, which is the LAN Manager
client and server. This is *NOT* Windows Sockets. (And Winsock errors
are at >10000, so clearly does not fall withing
NERR_BASE<=n<=NERR_BASE+899).


So if that documentation is correct, then the entire path should be a
waste of time. But perhaps the original author has some other reference
that says it actually works with Winsock?


> Is there some other DLL we could look in instead?
I can't find a reference to one anywhere - except it's included by
default in at least Win2k and later (with no extra loading of DLLs)


//Magnus


Re: Can a windows DLL have more than one process attached?

From
Tom Lane
Date:
"Magnus Hagander" <mha@sollentuna.net> writes:
>> Is there some other DLL we could look in instead?

> I can't find a reference to one anywhere - except it's included by
> default in at least Win2k and later (with no extra loading of DLLs)

Well, we're down to the wire on 7.2, and I don't think there will be
any votes to postpone 7.2 release while we resolve this problem ;-).
So what I propose to do is remove the netmsg.dll code for now,
leaving only the FormatMessage(...FORMAT_MESSAGE_FROM_SYSTEM...) call
in winsock_strerror.  This is still better than what we had in 7.1.
We can look for a better answer for older Windows flavors to add in
7.3 or later.

Any objections?
        regards, tom lane