we have a 32-bit .dll working on a remote 32-bit machine without a problem. We have moved our systems to another machine (64bit), also this .dll was moved.
However this .dll is working in the new machine without crash, but not working as intended (returning a custom error message, whose reason is not understandable). Normally it should produce the same result with the other machine. I have used Dependency Walker to check for missing dll's that this dll is depending on. Placed the 32-bit versions of the missing dll's under SysWOW64, but no good.
By the way our dll might not be just depending on another dll, it might be also be depending on any other file type(for example an .ini, etc.). On Windows is there any way that we can keep track of a dll's access of other files, i.e. can we see which files this dll is using?
Does anyone have any opinion about this case?
Related
I've deployed many games over the years on Windows and always shipped the necessary SDL.dll along with the game, in the game's folder.
This has always worked fine, and continues to work for well over 99% of people.
However, I'm starting to see reports of "The code execution cannot continue because SDL.dll was not found" from a few users. They all seem to be on Windows 10. And they confirm that the DLL is indeed in the game folder as it should be, and they're running the game directly from inside the folder, and not through a shortcut that would break the working directory.
I also have reports from other Windows 10 users who are not having this problem.
I did some research and found that this kind of error can be misleading, and may be triggered if the DLL itself loads another system DLL that is not found.
I used DependencyWalker on my EXE and found the SDL.dll depends on:
ADVAPI32.DLL
GDI32.DLL
KERNEL32.DLL
NTDL.DLL
MSVCRT.DLL
USER32.DLL
WINMM.DLL
Those all seem pretty standard. Would they be missing from certain Windows 10 installs for some reason?
Other ideas is that Windows 10 is moving to a signed DLL requirement (just a guess) or that the way Windows 10 handles library load paths has changed.
But again, this is working for other people on Windows 10.
Other details: DLL and EXE are both 32-bit. The systems in question are most likely 64-bit.
In this case, it turns out to be a really stupid end-user mistake.
I'm answering it here just in case anyone else runs into it.
When a user double-clicks a ZIP file, it LOOKS like they've opened a folder and are viewing the files.
They can even run the game from inside this ZIP browsing view.
But of course, Windows can't find DLLs that are also inside the ZIP file.
Thus, this behavior on Windows is pretty confusing to end users. The solution is to extract the ZIP first before running the game.
Forgive me if the title is not so accurate.
I have met some problem when I am doing something related to COM server and registry redirection and not quite sure is my understanding is correct or not. Hoping anyone could share some light on it. Thanks in advance.
Basically a COM server has been registered in the registry before anyone can use its service. On a 64bit Windows OS, there could be 2 possible views in the registry table, one is for default and the other for the WOW64 view. For example, first registry key is: COMPUTER\HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID{GUID}\LocalServer32 and the other is: COMPUTER\HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Classes\CLSID{GUID}\LocalServer32.
And depends on the process bitness (64bit vs. 32bit) that either one can be read by default, and also we can use KEY_WOW64_64KEY or KEY_WOW64_32KEY (as: http://msdn.microsoft.com/en-us/library/windows/desktop/aa384129(v=vs.85).aspx) to access the other alternative registry key.
What I need is that, I want to get the LocalServer32 executable file by reading the registry key and this can work. The problem is that, for the executable file path I read back, do I need to do the file path translation (in order to get the correct value) depending on which view I get the value from? For example, if the file path is got from COMPUTER\HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Classes\CLSID{GUID}\LocalServer32 and the file path is: C:\Windows\System32\abc.exe, do I need to translate the path to: C:\Windows\SysWow64\abc.exe? Or do I need to translate C:\Program Files\abc.exe to C:\Program Files(x86).exe?
Another question is that, if, for some registry key for COM, the values set in the two Views are different (for example, one has C:\Program Files\abc.exe and the other has C:\Program Files(x86)\abc.exe), then when the COM server is started, how could svchost.exe know which one to start, C:\Program Files\abc.exe or C:\Program Files(x86)\abc.exe? Does anyone know the logic for svchost.exe to determine this? Use the first one if it exists otherwise use the second one?
Thanks a lot.
A 64-bit version of Windows already has all the features in place to make it unnecessary for you to take care of it yourself. You just need to keep the rules in mind when you troubleshoot problems.
First is the registry redirector, it ensures that a 32-bit client program cannot accidentally read keys that contain configuration information that's only appropriate for 64-bit programs. You already know it, most of the HKLM\Software registry accesses are redirected to HKLM\Software\Wow6432Node. This redirection is already in place when the COM server is registered, a 32-bit installer is automatically redirected to write the keys to Wow6432Node instead. The installer is completely unaware that Wow6432Node even exists. Everything falls together automatically, the installer is redirected and the COM server client is redirected as well. All that you care about is knowing where to look to verify that the install was done properly, you do have to look at HKLM\Software\Wow6432Node\Classes\CLSID with Regedit.exe to find the keys back.
File redirection works much the same way, any access to c:\windows\system32 is redirected to c:\windows\syswow64, from c:\program files to c:\program files (x86). And very similarly, a 32-bit installer doesn't have to know beans about this, it can simply use the legacy 32-bit path names. Same for any 32-bit client program, it will be redirected the same way. All that you care about is knowing where to look for a file to verify the installer.
This can only go wrong if bitness is mixed, a 64-bit program reading registry keys or files installed by a 32-bit program. Or the other way around. Like it does with your troubleshooting tools, like Explorer, Regedit and SysInternals' Process Monitor. In general something that should be strongly avoided in COM, most servers are in-process servers and running 32-bit code in a 64-bit process is not possible. The biggest reason that the registry and file redirectors exist in the first place.
Our application has up to now only used 32 bit binaries, it was enough.
Slowly we see the need to introduce 64bit versions (in addition to the 32 bit version) for some components, mostly for interfacing with other 64bit components that we didn't write ourselves.
One question that popped up was whether we want to name the 64bit components (EXE + DLLs) identically to their 32bit counterparts and put them in a another directory, or whether to name them differently (e.g. tool.exefor 32bit and tool64.exe for 64bit) and leave them in the same directory.
Microsoft has seemingly gone the route of different directories and identical names for most of the Windows components (WoW64), and if the whole application were 64 bit, we'd also have the case to just use the Program Files vs. the Program Files (x86) directory.
However, in our case we have a largely 32bit application that uses some 64bit components (executables) to do 64bit stuff and for some of these we also have a 32bit version that is also used.
So, do we rename components and put them in the same binary directory or do we keep the binary name the same and put it into a subdirectory?
What are the pros and cons?
If we're talking about a single application, all of its files should be kept in a single directory, per the bitiness. Meaning, either PF, or PF(x86). But not spread around.
Regarding components, ask yourself this.
Are these components used interchangeably, or do are they used in parallel?
If it's one the former, then have them the same name, this will simplify your deployment. But if it's possible that both are used at once, for example, a DLL that is used by both 32-bit process, and your 64-bit helper process, then split the names. Otherwise you will need to split up your directory structure.
Now I had to link to the 64 bit boost library DLLs.
Boost 64 bit DLLs have the same name as their 32 bit counterparts and there is no built-in way in Boost Build to change the output name, creating additional work if you would want them in the same directory.
Looking around, it seems that e.g. Qt doesn't include any platform or bitness tags in their DLL which would again generate problems if you would need 32bit and 64bit in the same directory.
So, it would seem that if you have 3rd party DLL dependencies in your application, and you need both the 32bit and 64bit application installed at the same time, then, no matter how you name the executable (or your DLL) itself, putting them into different directories seems a good idea because then it's easy to work with 3rd party stuff that doesn't "tag" its DLLs with the bitness, because there really isn't a good way of loading different DLLs with the same name from the same directory (unless you put them into System32 / SysWOW64, which you shouldn't).
My program dynamically loads a number of DLL's using LoadLibrary and (on literally all machines) these load successfully, on one machine some of these DLL's do not get loaded. I added code to trace lasterror and this reports "0x43 The network name cannot be found.".
The machine in question is running Windows 7 Enterprise x64, the DLL is a 32 bit DLL, this shouldn't be an issue and (in fact) this is my development environment.
I also tried converting the name of the DLL (which includes the path) to a short filename and used that in the call to LoadLibrary, I still got the same error.
Any ideas?
//*eggbox
Download Procmon let it run and filter for you dll name. This will immediately give you the locations where the dll was searched and which access path did return 0x43.
You get even the call stacks if you have the pdbs for your code as well (C/C++ only no managed code).
Run the program through Dependency Walker in its Profile mode and let that fine tool tell you exactly what is going wrong.
I always thought .dll is working the same way as .so in linux,
but some article says not.
Does windows ensure that memory will contain only one copy the same dll as in linux?
I don't have a clue to check it myself in windows,so I can only ask here.
UPDATE
Anyone knows how do verify this manually?
Here's a short description: DLL Hell, basically in modern Windows it use a technique called Memory Mapping where the DLL is loaded once, if both processes try to load the DLL from the same directory. So to answer your question, it is working the same was as in Linux.
If the DLL can be loaded at the same base virtual address in two processes then there will only be one copy of the DLL in physical memory.
Since Windows does not use position independent code, if a DLL cannot load at its preferred base address it will be rebased and thus not be able to share physical memory with other instances.