What's special about "c:\windows\system32" in the %PATH%? [duplicate] - windows

My VBA code can't access to my DLL in the C:\Windows\System32 folder on Windows 7 64bit and Word 2010 32bit.
Private Declare Function my_func Lib "mydll.dll" (ByVal param As String) As Long
Public Sub MyFuncTest
n = my_func("a")
End
I copied mydll.dll into C:\Windows\System32 and called MyFuncTest but got an error message like "Error 53: 'mydll.dll' not found".
However, I changed the declaration in code to:
Private Declare Function my_func Lib "C:\Users\myname\Documents\mydll.dll" (ByVal param As String) As Long
then I copied mydll.dll into C:\Users\myname\Documents, my account's Documents folder, and MyFuncTest successfully executed.
Changing "mydll.dll" to "C:\Windows\System32\mydll.dll" in the declaration did not work. And I tried accessing C:\Windows\System32\mydll.dll with FileSystemObject#FileExists method on the same VBA environment, but it returned False (not found).
There was no problem on Windows XP and Word 2003.
Can anyone help?

This is a 32 bit DLL and a 32 bit process running in the WOW64 emulator on 64 bit Windows. File redirection is in play and so when a 32 bit process looks in system32 it is actually redirected to the 32 bit system directory SysWOW64.
The simple and quick solution is to move the DLL to C:\Windows\SysWOW64. However, as Cody Gray points out in a comment, it is not recommended for you to place application DLLs in the system directory. Normal practice is to place the DLLs in your application folder in the program files directory and make sure that folder is in the DLL search path when the DLL needs to be loaded.

Seems like UAC is the problem. Try running the VBA script as Administrator. It may help you.

A recent developer suggested the following fix which allowed a 32bit .dll to be registered on a 64 bit machine
1) Open a DOS command window.
2) Navigate to C:\Windows\Microsoft.NET\Framework64\v2.0.50727
3) Enter the following and press enter.
regasm /codebase "C:\Users\myname\Documents\mydll.dll"

I have had exactly the same problem yesterday. The program run on my machine, but not on others.
In fact, the message fron Excel is wrong. He obviously find lhe dll file, but this dll is calling orher dll, missing in the system : MSVCR100D.dll and NTDLL.dll.
I found that by using Dependency Walker free software, able to examine which dll are call by a dll.

Related

Delphi 10.4 Firedac Error 314 on OSX Catalina

How do I correctly provide the libfbclient.dylib for running Firedac/Firebird in OSX to avoid crashing with this message (here in German):
EFDException: [FireDAC][Phys][FB]-314. Laden der Herstellerbibliothek [libfbclient.dylib or libfbembed.dylib] nicht möglich.
To avoid some questions upfront: The software I am compiling already runs fine on Windows and Linux, in OSX it just wouldn't find the libfbclient.dylib. Also all non DB related unit tests run fine on all three platforms. And I made sure that the dylibs have 64 bitness like the executable, I took them from a fresh firebird 3 installation on the same Mac. The project is an application server (Windows service or Linux/OSX daemon).
I create all components dynamically and usually store the fbclient and other required libraries in the a folder together with the executable as I never write things into customers system folders and try to avoid changing things like the system path whenever possible.
const
{$IFDEF MSWINDOWS}
CLIENTNAME = 'fbclient.dll';
{$ENDIF}
{$IFDEF LINUX}
CLIENTNAME = 'libfbclient.so';
{$ENDIF}
{$IFDEF OSX}
CLIENTNAME = 'libfbclient.dylib';
{$ENDIF}
...
fDBLink := TFDPhysFBDriverLink.create(nil);
fDBLink.vendorLib := IncludeTrailingPathDelimiter(extractFilePath(paramstr(0))) + CLIENTNAME;
The Embacadero documentations states the executable searches in the application folder first, so I also tried to omit setting the expicit verndorLib - no difference. I also tried the subfolder Contents/MacOS and the parent folder, also no difference.
As I am not very used to the Unix platform I have no idea if there are system commands that can help finding out why(!) Firedac cannot load the library.
UPDATE 1
Meanwhile I discovered that I instanciated a TFDPhysFBDriverLink Object with every database instance what caused the VendorLib path being detected as empty in FDDriver. After correction the error message contains the complete path to libfbclient.dylib and I verified that it really lives there. I debugged into the Firedac code to where the Library is loaded with LoadLibrary: The path is correct and still it returns 0 in OSX.
Finally I solved it.
The problem remaining after fixing the VendorLib path seems to be the libtommath.dylib dependency. Inspecting libfbclient.dylib with otool -L shows fulfilled depedencies to files living in the standard folders and one special one:
#rpath/lib/libtommath.dylib
To my knowledge rpath default is the path where the executable is living, so I tried this approach:
create a subfolder lib for the dylibs I bundle with my application
deploy libfbclient.dylib and libtommath.dylib in subfolder lib
change TFDPhysFBDriverLink's VendorLib to the new path (including /lib)
This works fine and is a solution easy to implement. In Linux this Problem did not arise as one of my installation dependencies is the libtommath package.

Semicolon in windows folder name prevents application from loading its dlls

My application (C++) loads its dll by linking against the stub library, the dll is then expected to reside in the same directory as the executable.
However I've had a report from a user who received the error message "System Error - The program can't start because xyz.dll is missing from your computer".
It turns out the reason is that he had my application installed in a path that contains a semicolon (which is supposed to be a valid character in ntfs file names)
I went on to try with a couple of other applications I have installed on my System and some (audacity, git, python, vlc) exhibit the same behaviour (append semicolon to folder name -> dlls can't be loaded) but most don't.
So now I'm wondering: Is this an error on my part? If so: what am I doing wrong? What would I have to do for the dll to be discovered even if its in a path with a semicolon?

QT 5.2 app cannot start (Bad allocation error) when Qt5Core.dll is in app directory

I have a funny problem on my machine
Windows 7 x64, using QT 5.2 for the GUI
I'm not able to start the app I always receive the error
First I thought I had a broken dll, so through some trial and error I found a solution:
I add the QT5Core.dll via enviroment path, and NOT directly to the app folder. Then the programm works. If I copy the dll back to the app Folder, Same problem as before!?!?!?1
I'm really confused, because the error only occurs on my machine?
Debugging doesn't really help,
In code, the error occures here:
MyApplication::MYApplication(int argc, char** argv, int version)
: QApplication(argc, argv, version) // <<< this call fails!
{ }
somebody can help me?
Why is the location of the qt5core.dll a problem?!?!?
UPDATE
I used the profiling function of depends and found the following behaviour:
Failing
GetProcAddress(0x76800000 [c:\windows\syswow64\KERNEL32.DLL], "CreateSymbolicLinkW") called from > "dirone\xxxx.EXE" at address 0x00FF2877 and returned 0x7688CCE9.
First chance exception 0xE06D7363 (Microsoft C++ Exception) occurred in "c:\windows\syswow64\KERNELBASE.DLL" at address 0x765CC41F.
Exception: "bad allocation"
Working
LoadLibraryW("C:\BuildPackages\QT\plugins\platforms\qwindows.dll") called from "dirtwo\QT5CORE.DLL" at address 0x66AA5154.
Loaded "c:\buildpackages\qt\plugins\platforms\QWINDOWS.DLL" at address
0x0F380000. Successfully hooked module.
somehow the path to the qwindows.dll is hardcoded into the dll (there is no environment path to this directory)
If I rename the qwindows.dll or delete it, startup failes again.
BUT the qwindows.dll is bundeld with our product. It is in a subdirectory ./platforms/
AND the files are the same (diff returns equal)
Somebody have some clue what I should try next?
Check if you already have some qt related environmental variables.
Crashes are usually due to this, remove those envronmental variables first. Check whether you have any other qt installed libraries.
it would be better if you can post the cal stacks.
Some other dlls are needed that reside in the directory of the qt5core.dll. When you add this path to the search path the dlls are found. When you simply copy the dll these dlls can not be found. You can check dependencies with the depends tool.
Candidates for the additional dlls are:
icuin51.dll and icuuc51.dll
Found the Problem:
The enviromentvariable:
QT_QPA_PLATFORM_PLUGIN_PATH=C:\BuildPackages\QT\plugins\platforms
was set to the path. If removing this variable, everything works as it should!

win32 API SearchPath fails

The win32 API SearchPath API fails to find the "telnet.exe" binary path even though its present in system32.
However when I did a search for notepad.exe, with the same code it returns the file path. What puzzles me here is that both notepad.exe and telnet.exe lies in the same directory i.e C:\windows\system32.
This is the code I have written
char path[MAX_PATH] = {0};
LPSTR* ptr = NULL;
DWORD dwRet = SearchPathA(NULL, "telnet.exe",
NULL, MAX_PATH, (LPSTR)path, ptr);
This would always return 0 and the GetLastError is 2 ( File not found)
Any idea what is happening here?
I am using windows 2008 R2 enterprise edition on an x64 machine
Thanks & Regards
Sunil
It's not working because you application is 32 bit and is being affected by the File System Redirector. Your application is not looking in C:\Windows\System32 but is instead being redirected to C:\Windows\SysWow64.
notepad.exe exists in both System32 and SysWow64, but telnet.exe only exists in System32. So you application does not find it when it searches the path.
You can disable this behavior for your application by calling Wow64DisasbleWow64FsRedirection. But note the warnings in the documentation links that indicate that this should only be disabled temporarily and then re-enabled.

How to retrieve correct path of either system32 or SysWOW64?

I have a 32-bit process that can run either in 32-bit or 64-bit Windows. So, naturally, if the process tried to access the file c:\windows\system32\file.ext, it would be redirected to c:\windows\SysWOW64\file.ext. So far so good - I don't want to disable the redirection.
My problem is that my process doesn't actually access the file - instead it just takes its path and writes it into a text file, and I want that text file to read SysWOW64 on a 64-bit system, and system32 on a 32-bit system. How can I do that?
The following code will return the correct system directory (system32\syswow64):
[DllImport("shell32.dll")]
public static extern bool SHGetSpecialFolderPath(
IntPtr hwndOwner, [Out]StringBuilder lpszPath, int nFolder, bool fCreate
);
public static string GetSystemDirectory()
{
StringBuilder path = new StringBuilder(260);
NativeMethods.SHGetSpecialFolderPath(IntPtr.Zero, path, 0x0029, false);
return path.ToString();
}
On x86 you'll get %windir%\System32
On X64 you'll get %windir%\SysWow64
Hope this is helpful
if I understood it correctly, you can use SHGetSpecialFolderPath passing CSIDL_SYSTEMX86 to the csidl parameter. The documentation for the valid csidl's states that a 32 bit process will get:
%windir%\system32 on a 32 bits OS
%windir%\syswow64 on a 64 bits OS
Best regards
System32 C:\Windows\System32 Windows System folder (system directory) for 64-bit files
SysWOW64 C:\Windows\SysWOW64 Windows System folder (system directory) for 32-bit files
Program Files C:\Program Files Folder for 64-bit program files
Program Files (x86) C:\Program Files (x86) Folder for 32-bit program files

Resources