问题描述:

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

[email protected]

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.

网友答案:

Hope this link can help you. It's from MSDN. http://ecn.channel9.msdn.com/events/Win8CppEvent/PortingToMetro.pptx

相关阅读:
Top