I have a Windows library developed in C++ that uses ATL collections, ATL CString and COM interfaces with CComPtr heavily. I removed all non-winrt-allowed API calls from the library, and it builds fine, so I wrapped the library in a C++/CX ref-class and I am trying to use it from a Windows Store App. The application runs fine, but the Win-Store App certification fails with the following error:
Error Found: The supported APIs test detected the following errors:
API GetModuleHandleW in kernel32.dll is not supported for this
application type. MyLibrary.dll calls this API. API
InitializeCriticalSectionAndSpinCount in kernel32.dll is not supported
for this application type. MyLibrary.dll calls this API.
The VS project for my library is configured for Windows Store with the following settings:
These settings activate/deactivate the required macros (WINAPI_FAMILY as WINAPI_FAMILY_APP for example) in the SDK as expected.
I am 100% sure I am not calling GetModuleHandleW or InitializeCriticalSectionAndSpinCount directly in my library, so I thought this issue must be coming from a method of some ATL class that was not filtered properly in the Windows 8 SDK.
Diving into ATL header files was not very useful, since everything looks properly filtered there, for example see this fragment from ATL::CComCriticalSection::Init
#if !defined(_ATL_USE_WINAPI_FAMILY_DESKTOP_APP) || defined(_ATL_STATIC_LIB_IMPL)
if (!_AtlInitializeCriticalSectionEx(&m_sec, 0, 0))
#else
if (!InitializeCriticalSectionAndSpinCount(&m_sec, 0))
#endif
In order to prove my theory, I took an hex-editor and edited out GetModuleHandleW from my Kernel32.lib file, which gives me the following linking error:
atls.lib(atlwinverapi.obj) : error LNK2001: unresolved external symbol
__imp__GetModuleHandleW#4
So it seems my theory is not wrong. Note that I am doing all this using release builds, since debug builds do not pass the certification.
Now the question:
Is there any way for me to know exactly which class inside ATL is sabotaging my library other than looking at the header files?
Same question in MSDN forums
I have added a bug report on microsoft connect with a small sample code that reproduces this issue.
Here is what I guess. Look at the file atlwinverapi.h. There the macro _ATL_NTDDI_MIN is conditionally defined one way for x86/x64 and another way for ARM.
I think this might have changed during the recent VSUpdate that added XP support. Now in the file atlwinverapi.cpp (which goes into atls.lib I guess), in the method _AtlInitializeCriticalSectionEx, you will notice that it's calling InitializeCriticalSectionAndSpinCount if _ATL_NTDDI_MIN < NTDDI_VISTA.
I am assuming your building x86 or x64 that's why you are seeing this problem. If you build for ARM, you will not see this problem.
Of course you will not be able to run WACK on ARM but you can run dumpbin /imports on your binary and see if it still uses those non-compliant API.
Related
I regularly use log4cplus, but I have encountered a new problem.
I have a windows application which uses a dll (LoadLibrary)
They are built on different compilers, but use dlls with the same name (including log4cplus.dll) also built on different compilers. The app and all the dlls it uses are built in one environment (vs2008). The dll and all the dlls it uses are built on another environment (vs2013).
LoadLibrary failed until I changed the application to pass the LOAD_WITH_ALTERED_SEARCH_PATH flag to LoadLibraryEx, which appears to allow the dll to load its own dependencies successfully, except now I get these runtime errors
log4cplus:ERROR PropertyConfigurator::configureAppenders()- Cannot find AppenderFactory: log4cplus::RollingFileAppender
log4cplus:ERROR PropertyConfigurator::configureAppenders()- Cannot find AppenderFactory: log4cplus::ConsoleAppender
log4cplus:ERROR PropertyConfigurator::configureLogger()- Invalid appender: ROLLING
Logging works for all applications built in either environment.
Logging also works for this app and dll both built in the same environment.
I changed the dll to statically link log4cplusS.lib, but I still get the same errors.
First off, use the same compiler for everything. It is basically impossible to make things work when using different compiler versions. Once you are compiling everything with the same compiler, try to solve other problems, if any still remain.
I need to use ZwLoadDriver function from ntddk.h. I installed Windows Software Development Kit (SDK) for Windows 8. Set all includes (#include <ntddk.h>). And I have lots of errors like type/sruct redefinition, ... already has a body. I think that my headers from the SDK mixes with the ones from the DDK. How to fix this ?
The DDK should only ever be used to develop a driver. It is water and fire in user mode, lots of declarations overlap with the SDK headers.
Using NtLoadDriver() from user mode is undocumented, no header is available to get a declaration and there is no import library available for ntdll.dll. It is a native operating system api function, even its argument uses a non-standard format for the registry key. The native OS is very different from the Win32 api. If you really, really want to do this then you'll have to write your own declaration and use GetProcAddress() to get the entrypoint in ntdll.dll
But loading drivers from user mode code is already well supported in Windows. Best to use the documented and supported way, OpenSCManager + CreateService. A sample project is available here.
You shouldn't do this. DDK headers are exclusively for driver development and shouldn't be included in applications source code. If you need to load driver, you should use the NtLoadDriver function which is a user mode version of ZwLoadDriver. Read more here and here.
Also from here:
"User-mode applications use the native system services routines by calling the entry points in the Ntdll.dll dynamic link library. These entry points convert calls to Nt and Zw routines into system calls that are trapped to kernel mode. To access these entry points, a user-mode application statically links to the Ntdll.lib library, which is available in the WDK. The routines that are implemented in Ntdll.lib are stubs that dynamically link to the entry points in Ntdll.dll at run time".
I have a pretty annoying compiling problem.
I am trying to do a System.loadlibrary on a C++ DLL in VS2010, which in turns uses a C DLL compiled in VS2008.
The error I am getting is:
java.lang.UnsatisfiedLinkError: The application has failed to start because
its side-by-side configuration is incorrect
This occurs whenever my C++ DLL tries to do a call to a function in the C DLL. Both compiles just fine, and both are in a folder accessible by Java Applet.
Is this possible to solve somehow? Do you need any more info?
You should try and use the dependency walker on your DLLs.
From the side-by-side error I assume that one of the c runtime redist packages or one of the noredist packages is missing.
But the dep walker should show you this.
If this does not help you can get some more information from the event log of Windows since side by side errors are logged there, or you need to use sxstrace for more info.
Have you installed the runtimes of VC2010 and VC2008?
Additionally you have to make sure the manifests of both DLLs are correctly configured so that the correct version of the used library can be loaded.
See also: http://msdn.microsoft.com/en-us/library/ms235342.aspx
I am working on a wxWidgets console application that I want to call into = a C# DLL from, via the CLR. Unfortunately, the application hiccups in the wxWidgets application initialization code because OleInitialize is failing. The error I'm seeing is a pop-up simply stating "Cannot initialize OLE."
It seems that this problem is usually avoided by setting the apartment style for threads by applying a directive to the application's entry point but I'm really struggling with what entry point I'm looking for. My C# code is a DLL: there's no specific entry point. The code compiled with /CLR exists in a .lib which is linked into my wxWidgets application. wxWidgets actually defines the WinMain in their code, and allows me to override behaviors via implementing wxApp.
Other suggestions include disabling OLE support in wxWidgets but In my release, 2.8.6, setting wxUSE_OLE, wxUSE_CLIPBOARD, wxUSE_DATAOBJ, wxUSE_DRAG_AND_DROP to 0 creates unresolved externals while compiling wxWidgets.
Has enjoy encountered this before and found an effective work around? Can anyone provide any clarification on what entry point I need to be modifying?
As mentioned in my question, this is a problem involving the thread style settings between the C++ application and the CLR defaults. This was apparently a bug, once upon a time, and Microsoft has released a fix:
http://msdn.microsoft.com/en-us/library/s6bz81ya.aspx
Recompiling the executable the uses the CLR-enabled .lib with /CLRTHREADATTRIBUTE:STA was sufficient to eliminate the errors I was seeing.
I'm working on a piece of C++ software which runs on all Windows versions between Windows XP and Windows Vista. In my code, I developed a DLL which links against a standard library (the Qt library). Once my software is deployed, it's not unusual that the user doesn't have the exact same Qt build on his system but a slightly different configuration. There might be features disabled (so their Qt build doesn't export the same set of symbols) or the library might even be changed in ways which make the library binary incompatible to the original.
At some point, I'm loading my DLL via a LoadLibrary() call. This pulls in whatever Qt library is on the user's system. If I'm lucky, their Qt build is compatible with what I used while developing my DLLs, so LoadLibrary() succeeds. However, depending on the changes they did to their Qt build, the LoadLibrary() call sometimes fails with
"The specified Module could not be found."; this usually happens if their Qt build consists of less DLLs than my Qt build. So my DLL attempts to load e.g. QtFoo.dll but since this dll is not part of their Qt build, loading my DLL fails.
"The specified Procedure could not be found."; this usually happens if they changes their Qt build so that certain features are disabled, which results in less exported symbols.
My question is: how can I catch these errors gracefully? Right I'm simply using GetLastError() and then print either of the above two messages. However, it would be much more useful if I knew which module could not be found, or which procedure is missing. I noticed that when running an application in the explorer which links against a missing DLL, explorer manages to yield a nice 'The application foo could not be loaded since the required library blah.dll is missing'. Is there maybe some API available to get more information about why a LoadLibrary() call failed exactly?
Short of attaching a debugger to your process, I don't think you can. The message that typically pops up when this happens is generated internally by LoadLibrary. SetErrorMode is used in a lot of apps to inhibit messages of this form, I'm gessing that somewhere in your apps framework, its calling SetErrorMode to inhibit the OS message.
The only app ive seen generate its own verbose messages about dll load failures is MS DevStudio - which is attached as a debugger and so has access to a special stream of debug events.
At some point, I'm loading my DLL via
a LoadLibrary() call. This pulls in
whatever Qt library is on the user's
system.
Don't do this! The kind of errors you have are the lucky kind, just as easily it could corrupt memory and crash.
The canonical way of shipping a Qt application is either shipping the DLLs or linking statically. Check out the Qt deployment guide in the help files.
Later edit:
After reading your comments, I still do not recommend that you use this approach, since you can't be sure that the DLLs are binary compatible even if they load, which could lead to hard to track errors.
Nevertheless, I believe that you could intercept the LoadLibrary calls and see which ones fail. The MS Detours library can be used for this. Also see this Stackoverflow question.
To expand jeffamaphone's answer, you can try retrieving the file version details before calling LoadLibrary. You can do this using the following function:
BOOL GetFileDetails(LPCTSTR lpszPath, LPDWORD lpMajorVersion,
LPDWORD lpMinorVersion)
{
DWORD dwVersionHandle;
DWORD dwVersionSize = GetFileVersionInfoSize((LPTSTR)lpszPath,
&dwVersionHandle);
if (dwVersionSize == 0)
return FALSE;
LPBYTE lpVersion = new BYTE[dwVersionSize];
if (!GetFileVersionInfo((LPTSTR)lpszPath, dwVersionHandle,
dwVersionSize, lpVersion))
{
delete [] lpVersion;
return FALSE;
}
VS_FIXEDFILEINFO *pVersionInfo = NULL;
UINT nLength;
if (!VerQueryValue(lpVersion, _T("\\"), (LPVOID *)&pVersionInfo, &nLength))
{
delete [] lpVersion;
return FALSE;
}
*lpMajorVersion = pVersionInfo->dwFileVersionMS;
*lpMinorVersion = pVersionInfo->dwFileVersionLS;
return TRUE;
}
You can then check the major/minor version numbers against ones you're expecting.
Can MapAndLoad from ImageHLP.DLL may help. It returns a LOADED_IMAGE structure.
Can you be more proactive and check the version of the QT binaries you need before you call LoadLibrary()? Then you can just warn your user they don't have the version your app needs, and maybe even provide a link to the install point for them.
You can also have windows check for this by using a manifest file. This file contains the information on the requirements on the used libraries' versions. More accurate and complete info is on the msdn site.
Take a look at the answer to this question about how to use LoadLibrary with a manifest file.
The Qt documentation briefly mentions the usage of a manifest file for VS2005; for earlier versions you would have to create it for your own.