locked
Certification fails for Windows Store App with ATL-based library

    Question

  • I have 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 stackoverflow.com here,

    I have added a bug report on microsoft connect with a small sample code that reproduces this issue.

    • Edited by yms_2009 Thursday, December 20, 2012 5:07 PM
    Wednesday, December 19, 2012 2:53 PM

Answers

  • It looks there is a specific regression in VS 2012 Update 1 where the ATL was updated to use a Windows XP supported API which now triggers the WACK failure. The workaround is to add the following code to your application so it overrides the version in ATLS.LIB:

    #if (_ATL_NTDDI_MIN >= NTDDI_VISTA)
    namespace ATL
    {
    BOOL _AtlInitializeCriticalSectionEx(__out LPCRITICAL_SECTION lpCriticalSection, __in DWORD dwSpinCount, __in DWORD Flags)
    {
         return InitializeCriticalSectionEx(lpCriticalSection, dwSpinCount, Flags);
    }
    }
    #endif

    This is being looked at for a future update.





    Friday, December 21, 2012 8:04 PM

All replies

  • You should be able to identify where the call comes from by running in a debugger and breaking on GetModuleHandleW.

    --Rob

    Wednesday, December 19, 2012 8:13 PM
    Owner
  • I have edited my previous answer on the StackOverflow post with a possible explanation.  In all likelihood, this looks like a bug.  If what I mentioned seems to be the case, can you please file a connect bug: http://connect.microsoft.com/

    Raman Sharma | Program Manager, Visual C++ | @rasharm_msft

    (if my post has answered your question, please consider using the 'mark as answer' feature in the forums to help others)

    Wednesday, December 19, 2012 10:50 PM
  • Are you using VS 2012 RTM or VS 2012 Update 1?

    Wednesday, December 19, 2012 11:36 PM
  • It looks there is a specific regression in VS 2012 Update 1 where the ATL was updated to use a Windows XP supported API which now triggers the WACK failure. The workaround is to add the following code to your application so it overrides the version in ATLS.LIB:

    #if (_ATL_NTDDI_MIN >= NTDDI_VISTA)
    namespace ATL
    {
    BOOL _AtlInitializeCriticalSectionEx(__out LPCRITICAL_SECTION lpCriticalSection, __in DWORD dwSpinCount, __in DWORD Flags)
    {
         return InitializeCriticalSectionEx(lpCriticalSection, dwSpinCount, Flags);
    }
    }
    #endif

    This is being looked at for a future update.





    Friday, December 21, 2012 8:04 PM