Link to home
Start Free TrialLog in
Avatar of nils pipenbrinck
nils pipenbrinck

asked on

modules vs. instances

Hi.

What's the exact difference between a module handle and a instance handle?

I just want to know 'cause I just answerd to a question where I once again simply advised to pass a instance handle to a function that want's a module handle. I do that quite often.

so please explain me what exactly those booth "magic numbers" are, and how they are related.

thanks,
  nils
Avatar of ScottyDawg
ScottyDawg

so far, I've only found the following in the docs:

Take special care to distinguish HMODULE and HINSTANCE types. Even with STRICT enabled, they are defined as the same base type. Most kernel module management functions use HINSTANCE types, but there are a few API functions that return or accept only HMODULE types.

Still no absolute definition though...

ASKER CERTIFIED SOLUTION
Avatar of Madshi
Madshi

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Yeh they are interchangable in usage on Win32 env.
Yes, HINSTANCE and HMODULE seems to be same in Win32. I looked this from startup routines. Startup routine calls WinMain( GetModuleHandle( 0 ), 0, ...)

JMu
Avatar of nils pipenbrinck

ASKER

ok..

thanks folks..  

They are not always interchangable.

The HINSTANCE identifies the initial module that started the process, usually an EXE, and a HMODULE identifies modules that are loaded into the process, like DLLs.  Since an HINSTANCE identifies a module, just like a HMODULE, it can always be used just like an HMODULE.  (i.e. an HISNTANCE IS an HMODULE.)  

However, an HMODULE cannot always be used as an HINSTANCE.  Every process has exactly one HINSTANCE whereas it may have any number of associated HMODULES.  For this reason the HINSTANCE serves a a unique identifier to the process.  There are many times where windows expects an HINSTANCE to be used to specify a process, in those cases another HMODULE from that process cannot be used.  For example, when registering a window class.
Nietod, here is an extract from the win32 help file about "DllEntryPoint":

"The DllEntryPoint function is an optional method of entry into a dynamic-link library (DLL). If the function is used, it is called by the system when processes and threads are initialized and terminated, or upon calls to the LoadLibrary and FreeLibrary functions. DllEntryPoint is a placeholder for the library-defined function name. The actual name must be specified at build time. For more information, see the documentation included with your development tools.

BOOL WINAPI DllEntryPoint(

    HINSTANCE hinstDLL,      // handle to DLL module
    DWORD fdwReason,      // reason for calling function
    LPVOID lpvReserved       // reserved
   );      
 

Parameters

hinstDLL

A handle to the DLL. The value is the base address of the DLL. The HINSTANCE of a DLL is the same as the HMODULE of the DLL, so hinstDLL can be used in subsequent calls to the GetModuleFileName function and other functions that require a module handle."

So as you can see here there is a HInstance value for each DLL, too. So what you said is not right. Each DLL has both a HModule and a HInstance value, same with the Application module. And always the HModule and HInstance value of any module is exactly identical.

Regards, Madshi.
That parameter only identifies the module, not the process it is mapped into.  So it really is an HMODULE.  i.e it is missnamed.

>> And always the HModule and HInstance value
>> of any module is exactly identical
It isn't a mater of "value", it is a matter of use.  Both are used to identify a module, but an HINSTANCE also identifies the process, other module handles don't.  There are times when only the process's HISTANCE can be used and other module handles will not work.  I can't think of any that apply anymore (16 bit had more pronounced differences), but I'm sure there still are some.  A 16 bit example would be that the HINSTANCES were stored in the process data base (PDB).  You could search the PDB for a program's HISTANCE, but not for a DLL's HMODULE.
The following is from a VC help topic on the subject, but clearly it is a bit dated.

****************************

The Microsoft Windows graphical environment defines two types of executable files: applications and dynamic-link libraries (DLLs). The code in both types is normally sharable. Multiple instances of an application or multiple users of a DLL can share code loaded by the first instance. Most Windows-based applications and DLLs also contain resources that are sharable in the same manner. When Windows loads an application or a DLL into memory for the first time, it assigns a unique identifier, called a module handle, or an hModule, to the shared code and resources.

When Windows loads an application, it creates a unique execution context for the application to distinguish it from other running copies of the same application. This execution context is given an identifier called an instance handle, or an hInstance. Part of the execution context for an application is its automatic data segment, where the application's static data, stack, and local heap reside. Two running copies of an application share code, but each has its own data segment. DLLs differ from applications in that all instances of a DLL share the same execution context, and therefore share a common data segment.

Part of the execution context of an application is defined by a set of CPU registers and a stack. This portion of the execution context (a task context) is given a special identifier called a task handle, or an hTask. Every loaded application has its own task handle, but task handles are never associated with DLLs. Therefore, the automatic data segment of a DLL never contains a stack.

Windows can easily obtain a module handle from an instance handle because an execution context is always associated with only one module. Because a module can have more than one running instance, however, obtaining an instance handle given only the module handle is impossible.

**************************************

Module and instance handles are used inconsistently in the Microsoft Windows Software Development Kit (SDK) documentation. For example, LoadLibrary is documented to return an hInstance, but FreeLibrary takes an hModule. How can you free a library if Windows provides no obvious way to convert an hInstance to an hModule?

A number of the Windows-based application programming interfaces (APIs) that are documented as accepting only a module handle are defined incorrectly: Most can take an instance handle or a module handle. FreeLibrary, for example, can accept either a module handle or an instance handle. The following APIs are documented incorrectly; the following short descriptions of what the function does are correct:
In WinMain you get a HInstance value for your process. With "GetModuleHandle(NULL)" you get a HModule value for your process.

In DllEntryPoint you get a HInstance value for your DLL. With "GetModuleHandle(MyDllName)" you get a HModule value for your DLL.

Both a HInstance and HModule can be obtained for both a process and a DLL and both values are just 32bit ordinals with the same value.

In *EVERY* API you can give in either a HModule value or a HInstance value, it doesn't matter at all, because both are just 32bit ordinals (with exactly the same value).

In other words there is no (real) difference between e.g. "int" and "long" in 32bit Windows any longer. And there is no difference between "HInstance" and "HModule" any longer, either. Just different type names for the same purpose.

Of course you can't give in a DLL value (neither HModule or HInstance) if the API expects a process value (either HModule or HInstance). But that has nothing to do with any (non-existing) difference between HModule/HInstance.
I hope it's right what I told about "int" and "long". I'm a Delphi programmer and there it's "integer" and "longint", which was different in 16bit Windows, but which is exactly the same in 32bit Windows.
>> just 32bit ordinals (with exactly the same value).
That is not true. every HMODULE within a process has a different value.

You are being fooled by the fact that the HMODULE for the for the main moduel (EXE) is tha same as the process's HISNTANCE.  That is not true for any other HMODULE within the process.

>> In *EVERY* API you can give in either a
>> HModule value or a HInstance value, it
>> doesn't matter at all, because both are
>> just 32bit ordinals (with exactly the
>> same value).
I suppose you can also specify a brush handle too, since it to is a 32 bit ordinal.   Right?  wrong.

An HINSTANCE is an HMODULE, but the reverse is not true.  Read the docs on it.

>> if the API expects a process value
>> (either HModule or HInstance). But that has
>> nothing to do with any (non-existing) difference
>> between HModule/HInstance.
If they are the same, you could pass both.  they are not the same.  The HISTANCE has properties that an HMODULE doesn't.  The binary nature used to store the two value may be the same, but that is irrelaevant.  a character pointer and an integer pointer use the same binary method to store the pointer, but they are not interchangable.  The difference is in how the data is interpreted.
Hey, a real "fight"... That's fun...   :-)

>> That is not true. every HMODULE within a process has a different value.

Of course, that's not what I meant. I  mean the HInstance value of the process has the same value as the HModule value of the process. And the HInstance value of "kernel32.dll" in our process has the same value of the HModule value of "kernel32.dll". Of course our process has a different HInstance=HModule value than the kernel32 dll has.

>> That is not true for any other HMODULE within the process.

You are wrong here!! Please read the extract from the documentation about DllEntryPoint again, that I posted in my second comment:

"hinstDLL
A handle to the DLL. The value is the base address of the DLL. The HINSTANCE of a DLL is the same as the HMODULE of the DLL, so hinstDLL can be used in subsequent calls to the GetModuleFileName function and other functions that require a module handle."

>> I suppose you can also specify a brush handle too, since it to is a 32 bit ordinal.   Right?  wrong.

Bah! Of course not... I just wanted to say that HInstance and HModule are 100% identical 32bit ordinals.

>> An HINSTANCE is an HMODULE, but the reverse is not true.  Read the docs on it.

I have read the docs on it. Nietod, please test it, if you don't believe me. Write a little dll and check the HInstance value you get from DllEntryPoint. Then call GetModuleHandle and compare the two 32bit values. They're 100% identical. There simply is no difference between HModule/HInstance in 32bit Windows.

>> The HISTANCE has properties that an HMODULE doesn't.  The binary nature used to store the two value may be the same, but that is irrelaevant.  a character pointer and an integer pointer use the same binary method to store the pointer, but they are not interchangable.  The difference is in how the data is interpreted.

It seems to me that you simply don't know what a HInstance (= HModule) value in reality is (sorry, not meant as an offense)! Do you know that Windows internally maps each module (no difference between process or DLL) into the process' memory/address context with something like CreateFileMapping/MapViewOfFile(Ex)? And the result of MapViewOfFile(Ex) - that is the pointer to beginning of the file image - is exactly the HModule (= HInstance) value. So if both values are simply pointers to the beginning of the fileMapping in the process' memory, where is the difference, that you want to see? What I said is valid for both process modules and DLL modules. You can typecast every HInstance or HModule value into a pointer and - voilà - you have a pointer to a valid PE image header.
>> The HISTANCE has properties that an HMODULE doesn't.

That's the big mistake. HINSTANCE is just a pointer to the fileMapping. HMODULE is also a pointer to the fileMapping. So there are no properties that HINSTANCE has that HMODULE doesn't have. Both are pointers to the same target.
I jump into middle this debate with a comment.

But how do you get HINSTANCE? The only place I know to get HINSTANCE is parameter of WinMain. And RTL passes GetModuleHandle( NULL ) as a HINSTANCE.

Now I remembered that you can get HINSTANCE of window by calling GetWindowLong( hwnd, GWL_HINSTANCE ). So, when you RegisterClass(), you use HINSTANCE of the application which is the HMODULE of the application by GetModuleHandle( NULL ).

To me it looks like that HMODULE of the application is the same as the HINSTANCE of the application.

JMu
Hi JMu, welcome to the debate...   :-)

You can get a HInstance from WinMain, from DllEntryPoint and from GetWindowLong. The HInstance you get from GetWindowLong seems to be always the application HInstance, not the DLL HInstance. Probably, because Windows doesn't know which module has created (registered) the window (class).

IMO you're right with what you said.
(Probably, because Windows doesn't know which module has created (registered) the window (class)..........)

.......... or perhaps to hold 16bit compatibility...
>> Please read the extract from the
>> documentation about DllEntryPoint again

You are referring to

>> The HINSTANCE of a DLL is the same as the
>> HMODULE of the DLL, so hinstDLL can be
>> used in subsequent calls to the GetModuleFileName
>> function and other functions that require a module
>> handle."
Which microsoft acknowledges to be wrong.  The article I posted points out the the type names HINSTANCE and HMODULE are used inconsistently at times (And I believe mentions that instance in particular.)  The article specifically focus on expressing the deferences between the two.  If there isn't a difference, I doubt they would bother writting an article like that.

>> I just wanted to say that HInstance
>> and HModule are 100% identical 32bit ordinals
Not always.  This is only true for an EXE module (or the initial module, at least)   Alll subsequent modules in the process will use the same instance handle but different module handles.

>> check the HInstance value you get from DllEntryPoint
the parameter passed to DllEntryPoint is a module handle, not an instance handle.  (this is specifally states in the article on module and instance handles.)  

>> GetModuleHandle and compare the two 32bit
>> values. They're 100% identical
right that proves that instance handles and module handles are different.  Compare that value with the program's instance handle.  That is different!

>> into the process' memory/address context
>> with something like CreateFileMapping/MapViewOfFile(Ex)?
>> And the result of MapViewOfFile(Ex)
Not really.  The loader just allocates memory for the file at the load address (or if that address isn't avaialbe at a different address) then it reads the file into (virtual) memory.  Then it does its fix-ups.

>> that is the pointer to beginning of the file
>> image - is exactly the HModule (= HInstance)
>> value
Currently that is true, but it is certainly not guaranteed to remain true.  The only guarantees you have are

1. that the HMODULES identifies modules (EXEs or DLLs).
2. The HINSTANCE identifies the process.
3. That the HINSTANCE is the same as the HMODULE of the initial module.

They may change the nature of these values at any time, but they will keep the meaning the same.

>>  if both values are simply pointers to the
>> beginning of the fileMapping in the process'
>> memory, where is the difference, that you
>> want to see?
The difference is in function!!!  A pointer to a single character and a pointer to an NUL terminated charracter array are also the same.  But I can't use them the same.  I can use the character string poihter anywhere I use a pointer to a character, but I cannot use the pointer to a character everywhere I can use a NUL terminated character array.  

The OS uses the HINSTANCE differently than other HMODULES  It attachs extra meaning to it by virtue of what it does with it.  for example in win16 iyou could look up infirmation based on HINSTANCE, but not on HMODULE.  (These features are gone in win32).

>> You can typecast every HInstance or
>> HModule value into a pointer and - voilà -
>> you have a pointer to a valid PE image heade
Sure.  You can typecast any pointer type to another type.  but it doesn't always make sense to use it.  You can typecast a brush pointer to an instance handle too  But it doesn't identify the process.  Casting an HMODULE from a DLL to an instance handle does not idenfity the process.

>> HINSTANCE is just a pointer to the fileMapping.
No its a load address.

>> So there are no properties that HINSTANCE
>> has that HMODULE doesn't have.
Through the way it is used.  A C File stream (FILE) is really a pointer to an integer.  Are you saying that it is in every way equivelent to a pointer to an integer?  It has no properties that are not found in every pointer to an integer?  Of course not.  It has additional properties due to the way in which it cn be used.  The same is true for an HISNTANCE.  We assign additional meaning to it because it can be used in additional ways.

>> HMODULE of the application is the
>> same as the HINSTANCE of the application.
Right.  That is the special case.  it is not true for a DLL.

>> HInstance from WinMain, from DllEntryPoint
>> and from GetWindowLong
The VC docs clearly say that DllEntryPoint does not pass a module handle.  They pass an instance handle.  (The docs you found are know to be in error.  Unless you think the docs that report the error are wrong.)   That should be clear from the parameter's function and you own test.

>> The HInstance you get from GetWindowLong
>> seems to be always the application HInstance,
>> not the DLL
Again this was originally missdocumented.  The handle returned is the handle specified to RegisterClass().  But this handle should be the handle to the module that contains the window procedure.  I.e. it should be a module handle, not the instance handle.  
>> Not really.  The loader just allocates memory for the file at the load address (or if that address isn't avaialbe at a different address) then it reads the file into (virtual) memory.  Then it does its fix-ups.

Do you know Jeffrey Richter's book about Windows programming (Microsoft Press)? There he explicitly sais (and proves) that EXEs and DLLs modules are loaded into the process' memory by the use of memory mapped files. But in the end that makes no difference in our discussion.

>> Currently that is true, but it is certainly not guaranteed to remain true.

In 100000 places in the MSDN library (okay, a bit exaggerated :-) it is explicitly said that a module handle or a hinstance handle is nothing but a pointer to the PE header. And nowhere I found a hint that this could change. So I'm very sure this won't never ever change in 32bit Windows programming. Big parts of the system rely on this fact and countless 3rd party programs, too. And all low-level books, too. (The Microsoft books, too).

>> The article I posted points out the the type names HINSTANCE and HMODULE are used inconsistently at times (And I believe mentions that instance in particular.)  The article specifically focus on expressing the deferences between the two.  If there isn't a difference, I doubt they would bother writting an article like that.

Could you give me a link to this article or a reference number? I looked in the MSDN and didn't found it.
Thank you... (P.S: BTW, the part between the "******" sounds like being valid only for 16bit).

>> The difference is in function!!!  A pointer to a single character and a pointer to an NUL terminated charracter array are also the same.  But I can't use them the same.  I can use the character string poihter anywhere I use a pointer to a character, but I cannot use the pointer to a character everywhere I can use a NUL terminated character array.  

But we're talking about pointers to PE headers. There is no data stored behind the module in the process' memory (like e.g. a NUL char).

>> The OS uses the HINSTANCE differently than other HMODULES  It attachs extra meaning to it by virtue of what it does with it.  for example in win16 iyou could look up infirmation based on HINSTANCE, but not on HMODULE.  (These features are gone in win32).

Then tell me some functions, where you have to give in a HInstance handle, where you can't give in a HModule handle. Where is it that the OS handles HInstance differently?

>> Sure.  You can typecast any pointer type to another type.  but it doesn't always make sense to use it.

Not always. But casting a HModule (or HInstance) to a PE header *does* make sense (e.g. for getting access to the ordinal kernel export functions, the only way to get access to them is by parsing the PE header, because GetProcAddress doesn't work with kernel32 ordinal exports).

>> You can typecast a brush pointer to an instance handle too  But it doesn't identify the process.  Casting an HMODULE from a DLL to an instance handle does not idenfity the process.

Right, and I never said it would do. The HInstance of a DLL identifies the DLL, not the process.

>> Through the way it is used.  A C File stream (FILE) is really a pointer to an integer.  Are you saying that it is in every way equivelent to a pointer to an integer?  It has no properties that are not found in every pointer to an integer?  Of course not.

If there were some file APIs which accept (only) a pointer to an integer and some others that accept (only) a C file stream, then I would say: They are equivalent. Except one thing: A pointer to an integer can be used for much more purposes than for file streams.

I though do understand what you mean. But tell me: Where are the additional ways we can use a HInstance handle?

>> The VC docs clearly say that DllEntryPoint does not pass a module handle.  They pass an instance handle.

According to your understanding that would mean that DllEntryPoint would give us the HInstance handle of the process, right?

Well, I tested it and I got - the DLL instance (or in your understanding the DLL HModule handle). I got "0xD50000". The process' HInstance value is "0x40000".

Well, let me see if I understand what you mean:

(1) A process has a HModule handle and a HInstance handle. Both have the same value. But the HInstance handle has additional meaning somehow (which??)
(2) A DLL has only a HModule handle, no HInstance handle. Almost all (or even all) APIs that want to have a HInstance handle, want to have in reality a HModule handle.

Right?

Okay, here comes my sight in short:

(1) Each module (process and DLL) has a HModule handle and a HInstance handle. Both have the same value and exactly the same meaning (-> pointer to the file image in memory). So it doesn't matter whether the APIs want a HModule or a HInstance handle at all.

I can't believe that all the Microsoft documentations and all the headers are wrong. And that there is just one little hidden article (that I even didn't find in the MSDN) that mentions that. Are the Microsoft programmers dumb? If even the Microsoft programmers make the mistake to mix up HModule and HInstance, shouldn't that be a strong indicator, that there is really no (at least no significant) difference between those two types?
In Windows there are a lots of things that carries it's age. The HINSTANCE/HMODULE is one of them. It was understandable in 16 bits Windows where all memory was shared that they had different meaning. Two running Notepads shared the memory (one HMODULE) and two separate instances of it existed. Separate instances had to have different values.

Now things are different. Microsoft have made Win32 compatible with Win16, but this makes things a bit messy now. This HINSTANCE/HMODULE is one example of this. Microsoft should have been dropped the HINSTANCE, but they didn't (or couldn't) because every Windows program has WinMain.

nils pipenbrinck, I think that Madshi should get his points.

JMu
>> There he explicitly sais (and proves) that
>> EXEs and DLLs modules are loaded into the
>> process' memory by the use of memory
>> mapped files
Where does he say this?  I think you are missunderstanding it.  Consider some important facts.  if it was memory mapped through ordinary means, their would have to be a swap file on disk for the the memory mapping. Where is that file?  The EXE or DLL file.  No.  The EXE's and DLL's memory is  swapped to the regular virtual memory file just like any other block of "regular" memory in a process.  Why?  Well the memory has to be modifiable to support fix-ups and dynamic linking  You woudln't want the modified memory to be swapped out to the original file.  

>> it is explicitly said that a module handle
>> or a hinstance handle is nothing but a
>> pointer to the PE header
Can you find one place where it says that it okay to make this assumption?  No.  You can also find out what HDC, HBRUSH, HPEN, HFILE etc all are too.  But those HAVE changed in the past.  You won't any support for making assumptions about the nature of ANY handle.  MS uses handles for only one reason.  Then want to hide implimentation details from you to allow them the possibility of modifying the implimentation.  

>> Big parts of the system rely on this fact
>> and countless 3rd party programs, too.
The OS can relly on this.  That is their right.  And they have made changes to the nature of handles--bit changes before--that is their right and their problem.  I don't doubt that some 3rd parts programs do to.  But not good ones.  

>> Could you give me a link to this article or a reference number?
Q81496

>> the part between the "******" sounds like
>> being valid only for 16bit).

the part beween the **** is the article   The rest is me.  It was written for win32, but before win95.  It was last reviewed 1996 (under win95).  The discussion of the implimentation details is obviously windows 3.1 information.  Win 9x and NT handle much of the implimentation differently.  however, the fact remains that the OS was designed to assign different purposes to the two handles as this article makes clear.  

>> But we're talking about pointers to PE headers
You may be.  I am not.  I am talking about handles not pointers.  I would not make assumptions as to what they point to if they indeed point to anything.  

Do you think a master key and a ordinary key are identical.  they both are made of metal and both have cuts in them to accept the lock tumblers.  Are they the same?  The master key can be used for something the ordinary key can't--to open any door.  I can't see how they are the same.

>> Then tell me some functions, where you
>> have to give in a HInstance handle, where
>> you can't give in a HModule handle.
I can't think of any that exist in win32.  In win16 you could search the PDB for an hinstance, but not for a hmodule.  There were probably other cases too.  There may not be any cases anymore in win32.  Although that doesn't mean there won't be in the future.  The distinction between the two types of handles exists, MS certainly can add features that make use of it.

>> for getting access to the ordinal kernel export functions,
MS actually suggests that you use the handle in this way?  I find that a little hard to beleive.  Where is there an example?

>> The HInstance of a DLL identifies the DLL, not the process.
Read the article!  An instance IS a process.  They use the term "instance" to mean "process."  HINSTANCE identifies a process, not a module withing a process.  HMODULE idenfitfies a module (DLL/EXE) within a process.  So an HINSTANCE always identifies a process.  (Just bear in mind that some things labeled as HINSTANCE are really HMODULE.  The authors screwed up the labeling (typing), but their is a clear cut distinction.)

>> A pointer to an integer can
>> be used for much more purposes
>> than for file streams.
Good point.  It works both ways.  They are the same data types, but we assign different meanings to them because other parts of the computer/OS are designed to work with them differently.  

>> According to your understanding that
>> would mean that DllEntryPoint would
>> give us the HInstance handle of
>> the process, right?
No, it is passed an HMODULE for the DLL module.  It is just labeled wrong.  The API is full of places where the two are switched.  The programmer's were careless in their use of the type names, but not in the way they use the values.

>> he DLL instance (or in your understanding
>> the DLL HModule handle). I got
>> "0xD50000". The process' HInstance value is "0x40000".
so they are not interchangable.  When a procedure needs the instance handle it won't get the right value when you pass some module handle. (except the module handle for the EXE.)

>> (1) A process has a HModule handle and
>> a HInstance handle. Both have the same
>> value. But the HInstance handle has
>> additional meaning somehow (which??)
exactly.  It identifies the process.  At least theoretically.  Under win32 most processes have the same value for HINSTANCE so it doesn't do a very good job of it.  But there is no gaurantee that will be true in the future.  Under win16 you coulld truly use HINSTANCE to identify a process, but you could not use an HMODULE to do so.  The system didn't trach HMODULE the same way as HINSTANCE.  

>> 2) A DLL has only a HModule handle,
>> no HInstance handle.
each process has an HINSTANCE.  The DLL "has" the HINSTANCE of the process(es) it is mapped into.  This is numerically different than its own HMODULE and may be used in different ways.

>> Almost all (or even all) APIs that want to have
>> a HInstance handle, want to have in reality a HModule handle
All that I can thing of want HMODULE.  These days it is used only for loading resources and obtaining procedure addresses, both of which need to identify a module, not a process.  and HINSTANCE doesn't globall identify a process (currently) so it has been replaced with process IDs and handles, at least in terms of current use.  

>> 1) Each module (process and DLL) has a
>> HModule handle and a HInstance handle.
>> Both have the same value and exactly
>> the same meaning
No.  HINSTANCE is not associated with a particular module.  So it is wrong to say that a DLL has an HINSTANCE, it has an HMODULE.  The confusion is caused by the fact that the EXE'S HMODULE is the process's HINSTANCE.  But though-out all the modules in a process, the HISNTANCE is the same (it is the same as the EXE's HMODULE), but the HMODULE varies.

>> Microsoft documentations and all the headers
>> are wrong
This can't be the first time you've run across a mistake in the windows API.

>> Are the Microsoft
>> programmers dumb?
No but when it comes to mainining millions of lines of code written by hundreds of programmers its easy to make this kind of mistake.  Just because the programs that designed the process management system (task databse, loader etc) had a clear idea of the these two values, ti doesn't mean that the programmers that wrote GetProcAddress() did.  And unfortunately, the two types can be interchanged without a compilation warning so these problems can easily go unnoticed.  (i.e. if you pass the right binary value, it doesn't natter if it has the wrong type.)
>> It was understandable in 16 bits Windows
>> where all memory was shared that they
>> had different meaning.
The difference was certainly more important under win16, because HISNTANCE had real uses.  But I don't know that MS has abandoned the concept yet.

>> nils pipenbrinck, I think that Madshi should get his points.
He already has.
In the top of this article Q81496 stands this:

"The information in this article applies to:
Microsoft Windows Software Development Kit (SDK) for Windows versions 3.0 and 3.1"

That is 16bit Windows or am I missing something? I searched in the document for "32" and there was *NO* match!!

>> Read the article!  An instance IS a process.  They use the term "instance" to mean "process."  HINSTANCE identifies a process, not a module withing a process.  HMODULE idenfitfies a module (DLL/EXE) within a process.  So an HINSTANCE always identifies a process.  (Just bear in mind that some things labeled as HINSTANCE are really HMODULE.  The authors screwed up the labeling (typing), but their is a clear cut distinction.)

I do understand what you mean. But I don't believe that. Your *only* source is a small article about 16bit programming. Or do you have any other sources?

>> Where does he say this?  I think you are missunderstanding it.

No, no. It is 100% clear. In the beginning of the chapter about memory mapped files he sais that Windows loads EXE files and DLLs by the use of memory mapped files. I can't tell you the page number, because I've the german version of the book.

>> Consider some important facts.  if it was memory mapped through ordinary means, their would have to be a swap file on disk for the the memory mapping.

No. Exe and Dll memory mapping works with the original files. No swap file involved.

>> Where is that file?  The EXE or DLL file.  No.

YES!

>> Well the memory has to be modifiable to support fix-ups and dynamic linking  You woudln't want the modified memory to be swapped out to the original file.

Read this extract from MSDN:

"Under Windows NT, the Win32 loader simply sits on top of the memory mapped file subsystem, and so when the loader needs to load a PE executable, it simply calls down into the existing memory mapped file code. Therefore, it is extremely easy for to support SEC_IMAGE in CreateFileMapping() under Windows NT."

This flag SEC_IMAGE does the trick. Changes that are made are *not* saved to disk.

>> Can you find one place where it says that it okay to make this assumption?  No.  You can also find out what HDC, HBRUSH, HPEN, HFILE etc all are too.  But those HAVE changed in the past.  You won't any support for making assumptions about the nature of ANY handle.  MS uses handles for only one reason.  Then want to hide implimentation details from you to allow them the possibility of modifying the implimentation.  

Yes, but they don't even try to hide the fact, that HModule/HInstance is a pointer. It is written everywhere. And nowhere it is written that this will be changed perhaps. In various other situations Microsoft claims that they might change type structures. E.g. we should not use the PACE structure. But even the PACE structure remained the same from WinNT4 to Win2000. So if Microsoft doesn't say anywhere that it will change the fact, that HModule/HInstance are pointers, then I think we can rely on that. I think there are even Microsoft demo sources that use HModule/HInstance as a pointer. I would bet with you that HModule/HInstance remain pointer for all future 32bit Windows versions...  :-)

>> I don't doubt that some 3rd parts programs do to.  But not good ones.

But sometimes you have to do some low level stuff and then you don't have any other choice. The APIs are simply too weak. So many things we programmers need to do that are not documented. So a lot of programs use undocumented functions. And as a result (to remain compatibility with all the programs) Microsoft had to remain a lot of structures in the past (like PACE) and I'm quite sure they will do in the future. Not ALL structures. Who needs to access e.g. a HFONT structure? But some. Exactly those structures that are often used by 3rd party programs, because these programs have no other choice than using these structures.

>> >> for getting access to the ordinal kernel export functions,
>> MS actually suggests that you use the handle in this way?  I find that a little hard to beleive.  Where is there an example?

No, Microsoft doesn't like that. That's why they hacked GetProcAddress the way that you can't use it on kernel32 ordinals. Parsing the PE header is a suggestion from Matt Pietrek.
Well, perhaps that was a bad example. I do need all this low level stuff for several tasks like e.g. exception stack tracing / debugging / disassembling / API interception / ... and such...

>> Do you think a master key and a ordinary key are identical.  they both are made of metal and both have cuts in them to accept the lock tumblers.  Are they the same?  The master key can be used for something the ordinary key can't--to open any door.  I can't see how they are the same.

In this example I surely do agree with you. But my sight is this: Microsoft has exchanged the locks, so now all keys are master keys. So we have now master keys and ordinary keys, but that's only what is written on them. In reality/practise there is no difference anymore.
>> That is 16bit Windows or am I missing something?
That vast majority of the windows documentation was written under 16 bit.  I don't ignore it just because of that.  Admitidly the discussion of the implimentation details in that article is dated, but not the general facts about  the handle types.  

>> our *only* source is a small article about 16bit
>> programming. Or do you have any other sources?
I can't find any article that indicates that these two types are now considered identical.  I think it would be assume that two types that were considered different in win 16 are now identicle simply because we've changed to 32 bits and haven't been explicitly told they are different.  Do you assume that HPEN and HBRUSH are the same.  Can you find an article that indicates they are not?

>> "Under Windows NT, the Win32 loader simply
>> sits on top of the memory mapped file subsystem,
>> and so when the loader needs to load a PE
>> executable, it simply calls down into the existing
>> memory mapped file code. Therefore, it is extremely
>> easy for to support SEC_IMAGE in CreateFileMapping()
>> under Windows NT."
This isn't "really" memory mapping.  It sounds like they are using the memory mappiing code to get the image in memory and then break the memory mapping ties.  (to prevent changes to disk.)  It sounds like some sort of short-cut.  Where did this come from?  I'm not familiar with it.

>> So if Microsoft doesn't say anywhere that it will
>> change the fact, that HModule/HInstance are
>> pointers, then I think we can rely on that.
Did you not program in win16?  If you did you wouldn't say that.  The conversion from win16 to 32 was a nightmare for many programs because of those sorts of assumptuons.  Too many programmers werepoking around in window's internals and it made their code impossible to compile  or run under win32.  Not only was it a problem for them, but it was a problem for microsoft.  In a few instances microsoft was not able to make all the changes they wanted to the OS because too make programs had relied on implimentation details that MS wanted to change.  In other words, some programmers' playing around not only made it harder for themselves, but for all programmers.

>> Who needs to access e.g. a HFONT structure?
1000s of win 16 programmers.  All of whom regretted it eventually.  :-)

>>  Microsoft doesn't like that.
Didn't think so.  They don't want people poking around doing things wrong because in the long run it may limit their freedom to improve the OS.

Look you can make these assumptions if you want.  Many programmers did before, but many regreted it.

>> Microsoft has exchanged the locks, so
>> now all keys are master keys
First of all, I'm no sure all the locks have been changed, although I can't think of one that wasn't.  Secondly, they reserve the right to change the locks back.

>> In reality/practise there is no difference anymore.
The difference is how they are intended to be used and interpreted.
>> That vast majority of the windows documentation was written under 16 bit.  I don't ignore it just because of that.  Admitidly the discussion of the implimentation details in that article is dated, but not the general facts about  the handle types.

If all the 32bit documentations about HInstance/HModule was wrong, Microsoft would have at least published just one other article that is written for win32 about this issue. That's my opinion. But Microsoft has not. There's just this one very old article (it was written 92, okay, last reviewed 96, but which is still an eternaty in computer life). So I do ignore it.

>> I can't find any article that indicates that these two types are now considered identical.  I think it would be assume that two types that were considered different in win 16 are now identicle simply because we've changed to 32 bits and haven't been explicitly told they are different.  Do you assume that HPEN and HBRUSH are the same.  Can you find an article that indicates they are not?

Nowhere there is a hint that HPEN and HBRUSH would be identical.
But if you search in the MSDN for HInstance, you'll find thousands of articles and documentations where HInstance is treated like being identical to HModule (you would say: incorrect documentations). But most of these articles/documentations are much newer than your old 16bit article. So if your article would be still valid for 32bit, the newer articles/documentation would surely acknowledge (and clearly say so) that there was a difference between HInstance/HModule.
I just found a documentation about DllMain from 1998 (written, not last reviewed) where the same paragraph is in again: "The HINSTANCE of a DLL is the same as the HMODULE of the DLL, so hinstDLL can be used in subsequent calls to the GetModuleFileName function and other functions that require a module handle."
So do you believe in ONE old 16bit article? Or do you believe in hundreds or thousands of newer articles/documentations about 32bit? I do believe in the latter...

>> This isn't "really" memory mapping.  It sounds like they are using the memory mappiing code to get the image in memory and then break the memory mapping ties.  (to prevent changes to disk.)  It sounds like some sort of short-cut.  Where did this come from?  I'm not familiar with it.

Look for SEC_IMAGE in the MSDN. The extract I posted is from the first matched article.
Well, Jeffrey Richter claims it is "real" memory mapping.

>> Did you not program in win16?  If you did you wouldn't say that.

Yes, I did.

>> The conversion from win16 to 32 was a nightmare for many programs because of those sorts of assumptuons.  Too many programmers werepoking around in window's internals and it made their code impossible to compile  or run under win32.  Not only was it a problem for them, but it was a problem for microsoft.  In a few instances microsoft was not able to make all the changes they wanted to the OS because too make programs had relied on implimentation details that MS wanted to change.  In other words, some programmers' playing around not only made it harder for themselves, but for all programmers.

Yes, I see especially the problems for Microsoft. But it's Microsoft's own guilt!! Look, there are 1000 situations where you need a specific API urgently - and it simply isn't there. E.g. you create process with ShellExecuteEx. You get a process handle back. Nice. Now you need to know to which process ID this handle belongs. But there is *NO* chance with documented APIs to get this information. That's really a SHAME! (Don't you think so?). And so it's Microsoft's self-made problem, if programmers then go and use undocumented functions to realize what they need and what Microsoft doesn't offer with documented means.
I don't claim absolutey for sure that HInstance/HModule will hold their current meaning in 64bit (or even later) programming. But they will remain this way in 32bit programming...
And as far as I can see there will be no major changes in the APIs for 64bit Windows, just a few extensions. Nothing comparable with the major API changes from 16 to 32 bit. Remember, in those old days there changed so much, real multitasking, protected memory, virtual memory, memory mapped files and all this new stuff. What is so new in 64bit Windows? Nothing, just the pointers are a bit longer...
So I have good hope, that HInstance/HModule (and all the other types) will remain their meaning in 64bit programming, too.

>> First of all, I'm no sure all the locks have been changed, although I can't think of one that wasn't.  Secondly, they reserve the right to change the locks back.

Yes, they have the right. But Microsoft made a big mistake (in your opinion, not in my opinion) in saying the master key is for this lock and the ordinal key is for this lock, while all the keys fit in all the locks. Nobody understands all this stuff. So everybody is mixing the keys. So Microsoft can't change the locks back, if they want to remain 3rd party compatibility. Even if you were right. In my opinion Microsoft even documented (more or less) that the keys are equal now and so Microsoft can't change that back at all. And why should they? The meaning of HInstance is gone. It doesn't serve for differencing processes anymore. I think HInstance is just there in 32bit Windows for 16bit compatibility (and made equal to HModule).

But in the end what is the difference of our disagreement (and I begin thinking that we won't come to the same opinion... :-) ?

There seems to be no API which needs an HInstance value. So to the original question we can answer: Give in the HModule or HInstance of the process if you want to identify the process module. Give in the HModule of a DLL to identify the DLL. (You would say: There is no *own* HInstance of the dll, the documentation is wrong, so the value you get from DllMain/DllEntryPoint is the HModule / I would say: You can also give in the HInstance of a DLL to identify it. The only way to get the HInstance of the DLL is the value you get from DllMain/DllEntryPoint. But in the end your and my program code will look the same, right?).

Just one addition: In Delphi (and also BCB, I guess) DLL projects you normally have no direct access to DllMain/DllEntryPoint. All the parameters of DllMain (and also of WinMain for applications) are copied into global variables for later use. And guess how the variable is called in which the value from DllMain/DllEntryPoint is saved to: "HInstance"!   :-)

So probably you would say: Borland makes the same mistake as I do?
>> you'll find thousands of articles and
>> documentations where HInstance is treated
>> like being identical to HModule (you would say:
>> incorrect documentations)
That is okay.  The reverse is not.  Can you find examples where a module handle of an DLL is being used as in instance handle for the processes? I doubt it.  MS was inconsistent at times in the type names, but not in their function.

>> If all the 32bit documentations about
>> HInstance/HModule was wrong, Microsoft
>> would have at least published just one other
>> article that is written for win32 about this issue.
They haven't done that on any other topic.  When things have changed they document it.  When they stay the same they don't.  Otherwise there wiould be millions of articles that just say "this hasn't changed".  

That is the reason documents are reviewed.  When they find ones that are incorrect, they remove or change them.  They don't reveiw them so that can write new ones that say things haven't changed.

>> Nowhere there is a hint that HPEN and
>> HBRUSH would be identical.
Both may be passed to DeleteObject() and GetObject().  Both HISNTANCE and HMODULE may be passed to GetProcAddress() and  LoadResource().  Both sets of handles have similar properties and can be used interchangable at times.  But not always.  

> So do you believe in ONE old 16bit article?
>> Or do you believe in hundreds or thousands
>> of newer articles/documentations about 32bit?
>> I do believe in the latter..
I would beleive in even a single article that says that any HMODULE may be used in place of HINSTANCE in all cases.  That article does not exist.  That was not true before and MS does no intend for this to be true at this time, and likely not ever.  If you can find an article that probes that wrong...

>> while all the keys fit in all the locks.
>> Nobody understands all this stuff
Well that was obviously the original source of confussion for some of the MS programmers too.  (Hence the incorrect type names being used.)  But that is not limited to this case.  You can use SetBrushOrg() on a pen.  Heck you can SetBrushOrg() on an HISNTANCE.  

>> In my opinion Microsoft even
>> documented (more or less) that the keys are equal now
where?  There isn't 1 case where they use a DLL's module handle as a process's instance handle.  

>> All the parameters of DllMain
The article says that this is the wrong type name.  The article indicates the conceptual dufferences so that you can be more consistent.  (For example, I declare DllMain to accept an instance handle.  My library actually differentiates between the two.)
>> Can you find examples where a module handle of an DLL is being used as in instance handle for the processes?

Did you still not get what I mean? I never (never never) said, that you can use a DLL module handle as a process instance handle!!

The big thing where we disagree is that you say, a module has no own HInstance handle, but I say, a module DOES have its own HInstance handle (which is equal to the module's HModule handle).

>> They haven't done that on any other topic.  When things have changed they document it.  When they stay the same they don't.  Otherwise there wiould be millions of articles that just say "this hasn't changed".  

But how do you explain then, that *newer* documentations (that were clearly written after your old article) still use HInstance though they want HModule? My explanation: Because in 32bit Windows HModule *is* identical to HInstance now. (Again: I do NOT mean, a DLL-module's HModule is identical to a process-module's HInstance. I mean, a DLL-module's HInstance is identical to the DLL-module's HModule).

Another thing: They reviewed the article 1996. So if it would be valid for 32bit programming, too - why didn't they simply change the top of the article to something like:

"The information in this article applies to: Microsoft Windows Software Development Kit (SDK) versions 3.1, 3.11, Windows 95, Windows NT4"  ???

>> Both HISNTANCE and HMODULE may be passed to GetProcAddress() and  LoadResource().  Both sets of handles have similar properties and can be used interchangable at times.  But not always.

But not always? You still didn't find any example for that in 32bit programming...

>> There isn't 1 case where they use a DLL's module handle as a process's instance handle.

And again: I never said there would be. Do you still misunderstanding me?

>> For example, I declare DllMain to accept an instance handle.

I don't understand that! In your last comment you said, DllMain would get a HModule. So why are you declaring it as an instance handle now?

>> >> In my opinion Microsoft even documented (more or less) that the keys are equal now
>> Where?

Well, e.g. in all the APIs. E.g. in LoadImage it is written:

"hinst
Identifies an instance of the module that contains the image to be loaded. To load an OEM image, set this parameter to zero."

This shows clearly that modules (not only process modules, but DLL modules, too) *DO* have their own instance handle (which is of course identical to their module handle).

Of course you say now: "But in the article it is written that the APIs are documented incorrectly". But I say: A lot of documentations are newer than this article about 16bit programming - and those newer documentations still use HInstance for dll modules, too.

>> All the parameters of DllMain
>> The article says that this is the wrong type name.

No, that's not right. The article does not say ANYTHING about DllMain/DllEntryPoint!
>> The big thing where we disagree is that you
>> say, a module has no own HInstance handle,
Microsoft--not you--defined the concept of instance handle.  A d that definition is NOT just any module handle.  It is the module handle of the initial module loaded into a process.  That is by definition.

>> that *newer* documentations (that were
>> clearly written after your old
>> article) still use HInstance though they want
>> HModule?
The article lists dozens of cases where the mistake was made.  No effort was made to fix those in win16 or win32.  They have not corrected miss labeled types.  That doesn't mean they are not misslabeled.  The article makes it clear that MS believes they are misslabled.

>> why didn't they simply change the top of the
>> article to something like:
I've never seen them make changes like that.  They usually just delete and rewrite the article, sometimes they put in addendums.  In any case, a lot of the article is 3.1 specific.   but the concepts aren't.

>> But not always? You still didn't find any example
>> for that in 32bit programming...
You cannot prove the NULL hypothesis.  Its clear that they had a difference at one time and there is no evidence that MS has decided to remove that difference.  That means there may be differences currently and there may be differences in the future.  

>> >> There isn't 1 case where they use a DLL's
>> >> module handle as a process's instance handle.
>>
>> And again: I never said there would be. Do you
>> still misunderstanding me?
Haven't you said that the parameter passed to a DLL can be used as an instance handle?  

By definition an instance handle is a handle used to identify a process.  Are you or are you not saying that is what is passed to a DLL?

>> I declare DllMain to accept an instance handle.
opps. I meant module.

>> But I say: A lot of documentations are newer
>> than this article about 16bit programming - and
>> those newer documentations still use HInstance
>> for dll modules, too.
Okay forget the article.  You assume that the documentation is correct then.  Then under win16 the documentation said that HINSTANCE and HMODULE were interchangable.  Was that true?

No.  It was a mistake then.  Why isn't it a mistake now?  

>> The article does not say ANYTHING
>> about DllMain/DllEntryPoint!
It probably doesn't include that because its not part of the API.  The text of the article makes clear what is passed.  
>> Microsoft--not you--defined the concept of instance handle.  A d that definition is NOT just any module handle.  It is the module handle of the initial module loaded into a process.  That is by definition.

Where is this definition?

Nietod, I finally forced myself to read this article completely - and you know what? I think you missed some important points...   :-)

Let me tell you how I understood this article (with cites of your article):

Definition of HInstance:
(1) cite: "When Windows loads an application, it creates a unique execution context for the application to distinguish it from other running copies of the same application. This execution context is given an identifier called an instance handle, or an hInstance."
Here it seems that a instance handle is only used for processes.
(2) cite: "LoadLibrary: Loads a DLL. If the DLL is not already loaded, LoadLibrary creates a module and an execution context for it. If the DLL is already loaded, LoadLibrary simply increments the module's usage count (no new execution context is created because
 all instances of a DLL share the same execution context). In both cases, the function returns the hInstance for the DLL."
Please note especially the last sentence. LoadLibrary returns a HINSTANCE for the DLL. This is an extract from the article, you're talking about all the time!!

So I think in 16bit it was this way:

Every time a process or a dll is loaded the first time, a HModule (unique identifier) handle is allocated for this process or dll. A second instance of the same process or dll has the same HModule. But a second instance of the same process or dll has a different HInstance handle! And that is valid for both process and dll modules!

Do you agree with that?

If not: How do you explain the paragraph about LoadLibrary in this article?

If yes: That means, that you were wrong in saying, that HInstance is only used for process modules. Right?
A little addition about modules and memory mapped files:

There is an article "DLLs for Beginners" in the MSDN, here is an extract:

"So, to satisfy the above requirement—that is, to be reentrant (accessible from more than one thread at a time) and to have only one copy of the DLL physically loaded into memory—Win32 uses memory mapping. Through memory mapping, Win32 is able to load the DLL once into the global heap and then map the address range of the DLL into the address space of each application that loads it. Figure 1 depicts how a DLL is mapped to the address space of two different applications simultaneously (Process 1 and Process 2)."
Few comments from a lurker.

Q81496 was last reviewed December 8, 1999.

It say also this "DLLs differ from applications in that all instances of a DLL share the same execution context, and therefore share a common data segment." This is not true anymore. It's 16bit technique.

Also "For example, calling GetWindowWord with GWW_HINSTANCE obtains the instance handle of the application or the DLL that created a window. This instance handle can then be used to determine the module filename of the application that created the window. No equivalent way exists to do this using module handles." I think this is true in Win32 too.

So, because now Windows does not share memory between modules, the HMODULE of the EXE/DLL is the HINSTANCE of the EXE/DLL and vice versa. If this is not true for all cases, the programs will break.

Q81496 is ancient history.

JMu
I forget to mention, that if you load a dll into memory for the second time, I think it will get a new HMODULE. This differs from the first HMODULE. Just quessing. Should I test this? Maybe later. I go sauna now.

JMu
The memory mapping stuff is what I would call a use of virtual memory.  I use the term "mapping" when it is swapped to a file.  I'm not sure what the official terms really are.  Most likely there isn;'t anything "official" on it...
>> In both cases, the function returns the
>> hInstance for the DLL.
Not sure what to sauy about that.....

>> you were wrong in saying, that HInstance is
>> only used for process modules.
Well, that certianly was my understanding.  I need to some more research.
JMu, thanx for supporting my opinion...  :-)

>> I forget to mention, that if you load a dll into memory for the second time, I think it will get a new HMODULE.

If you call LoadLibrary two times, you get the same HModule value again, and the reference count of the DLL is increased. So we have no chance to load the same library two times at different memory locations into your process.

nietod, do you have the 16bit documentation of DllEntryPoint? I couldn't find it. It would be interesting to see what Microsoft has written there about the HInstance parameter. They surely didn't write, what is now written in the 32bit documentation. Let me quote it a last time:   :-)

"hInst: The value is the base address of the DLL. The HINSTANCE of a DLL is the same as the HMODULE of the DLL."

This two sentences are definetely no old crap from the 16bit world, they're new (if we call 32bit "new"). They were written after this article was written. And they clearly say: "HInstance = HModule = BaseAddress".
So IMO Microsoft has also officially documented that we may typecast a HModule to a pointer to a PE header. What do you think?

Well, I'm curious what your research will bring. Please keep us informed...   (-:
>> what your research will bring.
You don't want to know.  I've looked in Undocumented Windows and Windows 95 Unleashed and found info that clearly contradicts what I said.  And what you said, And what microsoft said, and each other.  If keep reading they probably contradict themselves too....

it is a mess,  All sources agree on that.
Hehe...  :-)  What does this info say?

And what now? Do we give up?
>> Do we give up?
At least for the moment.  I need to see if I can unearth some win16 books.  I haven't seen any in 3 moves, but they migth shed some light on this.