I'm a starting programmer and I can't solve a problem I have now.
In MFC, I have a .lib binary file without the sources. I need to make a 64bit application that uses mentioned library file.
I thought about making 32bit console program and run one program from another, for example using IPC with WM_COPY~ (or something like that), but the .lib file needs so many attributes like array, struct, pointer, ...
Is there an easier way to use that 32bit library in my 64bit application?
Thanks
You don't have any other alternative; you cannot load a 32-bit assembly in a 64-bit program, so you'll need to create a 32 bit application that your 64 bit application can talk to somehow. There are lots of ways to do IPC, so find one that works for you.
Uhmm strange, you simply can't put a big elephant into your home fridge but you still can insert in there a big chicken. If you can't do similarly with your 32 bit lib file, tell me why any of your 32bit applications can still work in 64 bit systems ? (:D) what sort of lib is that ?
Related
So I have a Visual C++ application, in my code I use the CoCreateInstance function which is used to create a COM object and get an interface from the object:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms686615(v=vs.85).aspx
This function:
hr = CoCreateInstance(CLSID_CppCmnBL, NULL, CLSCTX_INPROC_SERVER,
IID_ICppCmnBL, reinterpret_cast<void**>(&m_pBL));
Works fine on a 32 bit version of windows but fails on a 64 bit version of windows.
I've looked everywhre, it seems there are issues registering 32 bit objects on a 64 bit system.
Related issues:
https://social.msdn.microsoft.com/Forums/en-US/3841717c-a736-46d0-b214-0b047efcd16c/32-bit-app-cocreateinstance-failed-on-64-bit-windows-with-error-0x80090006-invalid-signature?forum=vclanguage
http://forums.codeguru.com/showthread.php?400956-32-bit-app-CoCreateInstance-fails-on-64-bit
The exception I get is: System.AccessViolationException
Please do this:
Clarify the #/binaries involved.
I assumed you had one .exe (the one calling CoCreateInstance()), and one .dll (the Com/ActiveX object you're trying to instantiate). Is this correct?
Please run dumpbin /all on your binaries and post the results.
Please run dumpbin on all relevant binaries; especially the COM/ActiveX class.
A Win32 .dll should like something like this:
FILE HEADER VALUES
14C machine (x86)
3 number of sections
5355B2AD time date stamp Mon Apr 21 17:07:09 2014
0 file pointer to symbol table
0 number of symbols
E0 size of optional header
2102 characteristics
Executable
32 bit word machine
DLL
OPTIONAL HEADER VALUES
10B magic # (PE32)
Please clarify which binaries you've attempted to rebuild with your
MSVS 6 compiler.
MSVS 6 won't work with .Net; MSVS 6 won't build C++11 code ... but it should be fine if all you're trying to do is get a legacy app working. Again, I'm assuming there's only one .exe, and one .dll in the mix.
I'm assuming the .exe can be compiled as a 32-bit Win32 .exe (not a .Net .exe), and the .dll is a Win32, COM/ActiveX class. Both should have "PE32" headers in dumpbin. Please advise if otherwise.
I'm assuming you have control over, and can rebuild and debug, ALL of the relevant source code for this app. Please advise if otherwise.
You should be able to register a COM/ActiveX .dll with regsvr32.
If you can't, that's probably an indicator that "something is wrong", and I'd focus your troubleshooting efforts there.
I hope that helps!
I have a helper DLL that I'm using for a long time without any change in its signature and I copy it to system32 in order to use it in all my products, now I add a function to its export list and compile it, everything looks OK and I have a new DLL that contain specified function. My problem is when I copy it into system32 specified function is missing, it looks like somehow it will be copied from a cache and some old version of it will be loaded, so programs that depend on new function will be failed! does anyone know what is the problem?
Most likely you have a 64 bit system. You copy the file to the 64 bit system directory, system32. But, because of the file system redirector, your 32 bit application loads it from the 32 bit system directory, SysWOW64.
Solve the problem by copying to SysWOW64.
You probably know this, but I feel compelled to say it anyway. The system directory belongs to the system and you should not be writing to it.
Use this to command to clear the dll cache. This has been tested on Win XP and Win 7.
sfc /purgecache
Please note that you need to be an admin to run this command or "Run as administrator". Not a 100% sure if this will fix your problem.
I am trying ti make my own packer, and my packer works fine with executable compiled VC++ 6, but when I try to pack executable compiled with VC++ 8, the executable will crash.
So I wanted to know if there is any change in the PE structure in the new versions of C++?
There has been no change to the PE File format, and as commenters above point out it is not related to your problem.
It sounds like your packer is dependent on the VC++6 runtime libraries and as such when it unpacks something that is expecting VC++8 libraries bad things happen. The solution would be to make your packer runtime library independent.
BigBoote's "How to write your own packer" addresses this and suggests implementing your own trivial runtime.
http://www.stonedcoder.org/~kd/lib/61-267-1-PB.pdf
I have a 32bit/64bit COM DLLs in C++: mycom32.dll, mycom64.dll. Both of them are exactly the same but mycom32.dll is compiled for 32bit and mycom64.dll is compiled for 64bit.
That means that BOTH DLLs have the same UUID and the same CLSID!
Now, sometimes I want to use this COM from 32bit processes and sometimes I want to use this COM from 64bit processes.
Is it possible to load the correct DLL without creating two different CLSIDs and check during runtime if the process is 32bit/64bit?
It should be possible to register both of them without issue; this is part of what Registry Redirection is supposed to solve.
Here's a more detailed explanation of how this works.
I need to get the path to the native (rather than the WOW) program files directory from a 32bit WOW process.
When I pass CSIDL_PROGRAM_FILES (or CSIDL_PROGRAM_FILESX86) into SHGetSpecialFolderPath it returns the WOW (Program Files (x86)) folder path.
I'd prefer to avoid using an environment variable if possible.
I want to compare some values I read from the registry, if the values point to the path of either the WOW or native version of my app then my code does something, if not it does something else.
To figure out where the native and WOW versions of my app are expected to be I need to get the paths to "Program Files (x86)" and "Program Files".
I appreciate all the help and, especially, the warnings in this thread. However, I really do need this path and this is how I got it in the end:
(error checking removed for clarity, use at your own risk, etc)
WCHAR szNativeProgramFilesFolder[MAX_PATH];
ExpandEnvironmentStrings(L"%ProgramW6432%",
szNativeProgramFilesFolder,
ARRAYSIZE(szNativeProgramFilesFolder);
Let me quote Raymond Chen's excellent blogpost on the issue:
On 64-bit Windows, 32-bit programs run
in an emulation layer. This emulation
layer simulates the x86 architecture,
virtualizing the CPU, the file system,
the registry, the environment
variables, the system information
functions, all that stuff. If a 32-bit
program tries to look at the system,
it will see a 32-bit system. For
example, if the program calls the
GetSystemInfo function to see what
processor is running, it will be told
that it's running on a 32-bit
processor, with a 32-bit address
space, in a world with a 32-bit sky
and 32-bit birds in the 32-bit trees.
And that's the point of the emulation:
To keep the 32-bit program happy by
simulating a 32-bit execution
environment.
...
The question is "What is the way of
finding the x64 Program Files
directory from a 32-bit application?"
The answer is "It is better to work
with the system than against it." If
you're a 32-bit program, then you're
going to be fighting against the
emulator each time you try to interact
with the outside world. Instead, just
recompile your installer as a 64-bit
program. Have the 32-bit installer
detect that it's running on a 64-bit
system and launch the 64-bit installer
instead. The 64-bit installer will not
run in the 32-bit emulation layer, so
when it tries to copy a file or update
a registry key, it will see the real
64-bit file system and the real 64-bit
registry.
If you still want to do this, I recommend reading the comments on this blogpost as they contain some good hints.
You're on the right path - Use the KNOWNFOLDERID of FOLDERID_ProgramFilesX64
The SHGetKnownFolderPath function can be used to retrieve the full path of a given KnownFolder.
This is almost certainly a bad idea, according to a recent-ish post by the infamous Raymond Chen. See here for details. Bottom line, I think it can be done, but it's a lot of hard work and there's almost certainly an easier way.
Microsoft built the WOW emulation layer to make your life easier. Don't waste all their time and effort by fighting it :-).
Perhaps if you told us why you need the non-WOW Program Files directory, we could assist further.
I needed it to get the x64 Program Folder from a Logonscript and used:
Dim oWshShell : Set oWshShell = CreateObject("WScript.Shell")
Dim sProgramDirPath : sProgramDirPath =
oWshShell.ExpandEnvironmentStrings("%ProgramW6432%")
WScript.Echo sProgramDirPath
The best and universal way to get path to "Program Files", is to query it from the registry:
64-Bit-Process can query:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\ProgramFilesDir
to get "C:\Program Files"
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\ProgramFilesDir
to get "C:\Program Files (x86)"
32-Bit-Process (Wow64) can query:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\ProgramFilesDir
to get "C:\Program Files (x86)"
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\ProgramFilesDir with KEY_WOW64_64KEY option!
to get "C:\Program Files"
Pseudo-code:
OpenKey(hKey, HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion", KEY_READ | KEY_WOW64_64KEY);
QueryStringValue(hKey, L"ProgramFilesDir", sValue);