Copying System32 DLL using MSYS breaks the 64bit being of the library - cp

Under Windows 7 64bit, the *32.dll from System32 are 64bit libraries (according to Dependency Walker - depends.exe x64). A strange issue I noticed is that doing - for example - cp /c/System32/ws2_32.dll /c/mingw64/some/lib/libws2_32.dll in the MSYS Shell is breaking/converting the DLL to 32bit file (still according to Dependency Walker)... While copying/renaming it through Windows Explorer keep it unchanged... Still weird. If anyone has an explanation...
Or did I miss something about cp command usage...
Note: I already tried options like --preserve=all or --symbolic-link.
Thanks.

cp is somehow (either directly or due to the parent process that you're running it from) running as a 32-bit process. File System redirection is kicking in and you're actually copying ws2_32.dll from the C:\Windows\SysWOW64 directory instead - where it already exists as a 32-bit DLL.
32-bit applications can access the native system directory by substituting %windir%\Sysnative for %windir%\System32. WOW64 recognizes Sysnative as a special alias used to indicate that the file system should not redirect the access.

Related

Resolve PROGRAMFILES variable from 32bit app in Win64 OS?

As explained in MSDN's WOW64 Implementation Details, the variable %PROGRAMFILES%,
in a 32-bit-process on a 64-bit-Windows OS, resolves to C:\Program Files (x86)
in a 64-bit-process on a 64-bit-Windows OS, resolves to C:\Program Files
You can verify this e.g. with a Delphi 10.1 program, compiled both with the 32-bit Windows Target Platform and with the 64-bit Windows Target Platform:
MyShellExecute('%PROGRAMFILES%');
So, from a 32-bit Delphi Application executed in a Windows-64bit-OS, how can I get BOTH:
the ProgramFiles directory for 32-bit-Programs (C:\Program Files (x86))
the ProgramFiles directory for 64-bit-Programs (C:\Program Files)
Use the following environment variables:
ProgramW6432 to obtain the 64 bit program files directory.
ProgramFiles(x86) to obtain the 32 bit program files directory.
These return the same values in both 32 and 64 bit processes.
Of course, relying on environment variables is always a little brittle. It's always possible for your parent process to have modified these variables before creating your process.
To make your program more robust you should use known folder IDs instead. Use FOLDERID_ProgramFilesX64 and FOLDERID_ProgramFilesX86.

"Exception TDBXError in module xxx.exe at xxx. Unable to load dbxmys.dll (errorCode126). It may be missing from the system path."

I have installed MySQL on a client machine, created and populated the databases – MySQL is up and running. I then copied dbxmys.dll and libmysql.dll from my machine to the Windows/system32 folder of the client and copied the compiled project EXE file. On executing the project I get the error
"Exception TDBXError in module xxx.exe at yyy. Unable to load
dbxmys.dll (errorCode126). It may be missing from the system path."
I have also tried to copy dbxmys.dll and libmysql.dll to the same folder as the executable but that did not work either.
Most plausible explanation, as so often has been the case, is that your have a 32 bit process on a 64 bit machine. In that case the file system redirector means that 32 bit processes that access System32 get redirected to the 32 bit system directory, SysWOW64. That's where you should put the files, if indeed the system directory is where they need to go.
Another possible failure mode could be that you have 64 bit DLLs and a 32 bit process. Or vice cersa.
That said, the system directory is for, well, system files. And applications should not modify it. So, putting the DLLs in the application directory would seem to be the right thing to do. You tried that without success. Hard to say why it failed. Perhaps there are further dependencies. Debug this using Dependency Walker in Profile mode.

JNA UnsatisfiedLinkError, but jna.library.path is set

I'm using the following code to load a dll in JNA (irrelevant code is left out):
public class JNAMain {
public interface PointShapeBuffer extends Library { ... }
public static void main(String[] args){
System.setProperty("jna.library.path", "c:\\jnadll");
System.setProperty("java.library.path", "c:\\jnadll");
PointShapeBuffer jna = (PointShapeBuffer) Native.loadLibrary("FileGDBAPI", PointShapeBuffer.class);
}
}
And I get the following error:
Exception in thread "main" java.lang.UnsatisfiedLinkError: Unable to load library 'FileGDBAPI': The specified module could not be found.
I've also tried setting the VM args. Any suggestions would be great.
Edit: For reference, I am using a publicly available library found here (registration is required).
In my experience you usally see this error when calling 32bit native dlls from a 64bit jvm on 64bit Win7. Win7 works differently for 64bit and 32bit applications.
On 64bit Win7 you can call functions in native 32bit dll's, but you need to use a 32bit JVM.
Download and install 32bit Java Runtime Environment (JRE). You can install a 32bit and 64bit jvm on the same machine, just make sure they are installed in seperate directories.
Ensure you run the 32bit JRE instead of the default 64bit JVM when you execute your program. Either A) change your CLASSPATH and JAVA_HOME environment variables to point to the 32bit jvm, or write a script to set the CLASSPATH and JAVA_HOME and launch you application.
The reason for this is 32bit dll's are incompatible with 64bit applications, and 64bit Win7 uses a 32bit emulator to run 32bit applications. Although Windows Libraries might be called named xxxx32.dll (e.g. user32.dll) the libraries in the System32 folder on a 64bit Win7 are 64bit libraries, not 32bit, and the libraries in SysWOW64 are 32bit libraries, confusing right?!?
You can also place the library in the 32bit system folder (SysWOW64) and make the JNI call from within a 32bit JVM.
Check out the following link for a full explanantion as how 64bit Win7 handles libraries;
http://www.samlogic.net/articles/32-64-bit-windows-folder-x86-syswow64.htm
And if you really want to help yourself get to sleep, trying starting on this ;)
http://msdn.microsoft.com/en-us/windows/hardware/gg463051.aspx
Change your:
Native.loadLibrary("FileGDBAPI", PointShapeBuffer.class);
to:
Native.loadLibrary("C:\\jnadll\\FileGDBAPI.dll", PointShapeBuffer.class);
If you dive into the jna source code enough you will find a nice little hook in the NativeLibrary class:
/** Use standard library search paths to find the library. */
private static String findLibraryPath(String libName, List searchPath) {
//
// If a full path to the library was specified, don't search for it
//
if (new File(libName).isAbsolute()) {
return libName;
}
...
So it will catch if you just passed an absolute path and not even use the searchPath. This was why you dont have to worry about jna.library.lib.
You need to specify the folder containing your DLL, not the DLL's actual path.
e.g. for baz.dll at c:\foo\bar\baz.dll, the path should be set to c:\\foo\\bar. (note in Java if you're using backspaces you'll have to escape them with backslashes)
You might want to download the latest version with jna.jar and platform.jar and just include those. No need to set the path then.
Like it was already mentioned in some comments: checks your Dependencies of your DLL/Library. Best Tool for this is Dependency Walker (http://www.dependencywalker.com/). Only if all your Dependencies are fulfilled, jna finds your DLL.... took me quite long to figure this out
it is may be because there is the conflation into the lebweb kit. I am not sure but that has to be that only now u can do one thing try this.
$ dpkg -l | grep -i jna
try this command and if u getting this output
ii libjna-java 3.2.7-4 Dynamic access of native libraries from Java without JNI
or any other output then this u need to remove then that jna from the system because if program itself have jna jar with that then there is no need of system jna for the same. so do something like this.
sudo apt-get autoremove libjna-java
and try for restart that application again. it will run and it is not running then try to install new version of libwebkit-gtk.
hope this will help. this helped me.

delphi 2009 compile packages

i truly don't get it.
trying to recompile the qr5 packages, and is impossible with this Delphi.
build the QR5Run_Rad6.bpl, everything is fine.
when i install QR5Design_RAD6.bpl an error message appears
"its not possible to run the program since qr5run_rad.bpl is missing in your computer. try again installing your program to solve this problem."
just did!
clean build compile doesn't work in any order. closed the ide and reopened , still doesn't work.
what else is left?
clean all related dcp and bpl
QR5Design_RAD6.bpl <> qr5run_rad.bpl
And more importantly, the qr5run_rad.bpl needs to be found on the systempath in order for the IDE to find it so it can be used by the design time package.
In other words: you need to build the qr5run_rad.bpl as well as the QR5Design_RAD6.bpl. And you need to make sure that the qr5run_rad.bpl ends up in a folder that is on your system path, not just any old folder where you have the sources and/or dcu's.
In addition to what Marjan wrote:
Windows uses these places when looking for a DLL (or BPL, which is a DLL):
The directory from which the application loaded.
The system directory. Use the GetSystemDirectory function to get the path of this directory.
The 16-bit system directory. There is no function that obtains the path of this directory, but it is searched.
The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.
The current directory.
The directories that are listed in the PATH environment variable. Note that this does not include the per-application path specified by the App Paths registry key. The App Paths key is not used when computing the DLL search path.
Delphi puts BPL files in a directory like C:\Documents and Settings\All Users\Documents\RAD Studio\8.0\Bpl which it adds to your PATH when Delphi is installed. For Delphi 2009, that Path would probably be C:\Documents and Settings\All Users\Documents\RAD Studio\6.0\Bpl on a Windows XP machine.
--jeroen

How to access the ProgramFiles environment variable from nmake on x64 machines?

I try to get the path to the ProgramFiles environmental variable, that is supposed to expand to C:\Program Files (x86) on a x64 machine and to C:\Program Files on a x86 machine.
The problems is that in the nmake file if I do:
all:
echo $(PROGRAMFILES)
This will expand to C:\Program Files everytime and this is wrong.
Environment details from a x64 machine:
ProgramFiles(x86)=C:\Program Files (x86)
ProgramW6432=C:\Program Files
:: this one is special, if will return different results based on current process x86/x64
ProgramFiles=C:\Program Files (x86) or C:\Program Files
PROCESSOR_ARCHITECTURE=x86 or x64
Now the updated question is how to get the location of x86 program files inside nmake, in a way this will work on both x86 and x64 machines?
This expression seems to work on 64-bit Windows 7, with nmake running in both 32-bit and 64-bit:
%%PROGRAMFILES(x86)%%
e.g.
LC = %%PROGRAMFILES(x86)%%\Microsoft SDKs\Windows\v7.0A\bin\lc.exe
If you're on an x64 machine it is totally legal that %ProgramFiles% points to C:\Program Files - from within a 64-bit program's environment.
The variable you have to use to get the x86 counterpart is %ProgramFiles(x86)%.
Which one to use can be determined by evaluating the current OS's architecture that is set in the PROCESSOR_ARCHITECTURE environment variable (which is e.g. set to AMD64). Or simply try to get %ProgramFiles(x86)% and if it is empty get the content of %ProgramFiles%.
Another approach would be to start a 32-bit cmd.exe and run your make there. It is located in C:\Windows\SysWOW64.

Resources