locked
Minimal C++ metro style application fails app certification?

    Question

  • If I create a C++ metro style application using the minimal application template, compile and deploy it without any changes, it will fail certification when run through the Windows App Certification Kit.  It fails the "Use of Supported Platform APIs" due to calls such as GetModuleFileName, LoadLibrary, VirtualQuery, and lstrlen.  Is this a bug in the developer preview, or am I doing something wrong?

    I am not sure how useful existing C++ code will be when we can't even make simple calls such as LoadLibrary from metro apps.  In my case, I am trying to make calls into a library that is installed with a driver.  How are we expected to handle cases like this?

    Tuesday, October 11, 2011 12:00 AM

Answers

  • Are you trying with a debug build of your app?  Debug binaries happen to use some API that will not pass App Certification Kit.  This is by design since developers are not expected to ship debug apps.  Can you please try with a release build of your app and let us know if the problem persists.

     

    Thanks

    Raman Sharma, Visual C++

    • Marked as answer by Thunk Monkey Tuesday, October 11, 2011 12:46 AM
    Tuesday, October 11, 2011 12:28 AM
  • But the problem is that the developer has no way of ensuring that the arbitrary DLL will be present in System32.  Classic apps could do that since they could themselves install that DLL in System32.  But for Metro style apps, the new deployment model doesn’t allow apps to install files in random locations. 

    And for the DLLs that Windows itself puts in System32, well you need a way (import lib) to dynamically link to them.  And if Windows provides an import lib for this DLL in the SDK then obviously they feel it is safe to call into this DLL from a metro style app.

    Thanks

    Raman Sharma, Visual C++

    Thursday, October 13, 2011 9:17 PM
  • Yes, my original question regarding certification and debug builds has been answered.

    Regarding dynamic linking, it is my understanding that LoadPackagedLibrary cannot load DLLs from a folder such as System32.  However, as I mentioned, my metro app can load arbitrary DLLs from System32 and pass certification if it uses load-time dynamic linking:

    http://msdn.microsoft.com/en-us/library/windows/desktop/ms684184(v=vs.85).aspx

    This seems to break the model of apps only being allowed to load DLLs from their package.

    LoadPackagedLibrary is limited to loading only modules that are referenced by the app package manifest:  http://msdn.microsoft.com/en-us/library/hh447159(v=VS.85).aspx.

    Aside from LoadPackagedLibrary, dynamic linking to DLLs in the System32 directory is allowed because there are a number of Windows API functions that can be called from metro-style apps.  These are marked in the windows header files as described above.  To actually use them at runtime, you do need the ability to link to the DLLs where they live; this is why you can link to DLLs in System32. 

    Although you can load arbitrary DLLs in the System32 directory, we strongly recommend that you only link to DLLs that ship with Windows because:

    1. If you link to a 3rd party DLL inside System32, but that DLL that doesn't exist on one of your user's machines, your application will fail to load as documented in the MSDN reference page.

    2. The System32 directory is not a place for 3rd parties to place their DLLs (except for .NET assemblies that that install into the GAC).  This is enforced by the ACL on the \Windows directory that limits write access to specific privileged & admin accounts and by the Windows Client Software Logo requirements (http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=3859). 

    #2 means that your metro-style application's installer will not be able to copy DLLs into System32.

    Thus, you can use dynamic linking to call the Windows API functions that are marked safe for metro-style applications, but you should not rely on calling other functions from other DLLs.

    Sincerely,

    Dan

    Friday, October 14, 2011 6:15 PM
    Moderator

All replies

  • Are you trying with a debug build of your app?  Debug binaries happen to use some API that will not pass App Certification Kit.  This is by design since developers are not expected to ship debug apps.  Can you please try with a release build of your app and let us know if the problem persists.

     

    Thanks

    Raman Sharma, Visual C++

    • Marked as answer by Thunk Monkey Tuesday, October 11, 2011 12:46 AM
    Tuesday, October 11, 2011 12:28 AM
  • Yes, trying to certify a debug build was the issue.  Thank you.

    Regarding my second question, can LoadPackagedLibrary be used as a substitude for LoadLibrary in some cases?  Can it load DLLs from System32?

    Tuesday, October 11, 2011 12:50 AM
  • LoadPackagedLibrary allows you to load only the DLLs that you have packaged along with your app.  It doesn't work for DLLs present on random location on the filesystem.

    What is your specific scenario and what are you trying to do?

    Thanks

    Raman Sharma, Visual C++

    Tuesday, October 11, 2011 1:05 AM
  • I am trying to call functions exported from a DLL installed with a driver.  In this case, the DLL is in System32.
    Tuesday, October 11, 2011 1:16 AM
  • That is not a supported scenario for metro style apps.  Your app cannot use LoadLibrary-like API to load DLLs from System32.

    Raman

    Tuesday, October 11, 2011 5:08 PM
  • It seems I can use load-time dynamic linking to load a DLL from System32 and make calls without failing certification.  Is this officially supported?
    • Edited by Thunk Monkey Wednesday, October 12, 2011 1:38 AM
    Wednesday, October 12, 2011 1:38 AM
  • In your original question, if you run the App Certification Kit on a debug build of your metro-style app, you will get a failure for "Use Supported Platform APIs".  You likely will also have gotten one for "Opt into Windows security features" because the SAFESEH flag was not set. 

    These are by design.  The SAFESEH compiler flag can't be used with the Edit and Continue compiler flag, and since EnC is used in debug builds, the SAFESEH flag is omitted.

    If you run the App Certification Kit on your release build, both of these errors will not show up unless you specifically call these functions in your code or you remove the SAFESEH flag.

    Back to your follow up questions on dynamic linking:

    Some Windows API functions like LoadPackagedLibrary can be used directly from metro-style applications; these are marked in the header files with #ifdefs that use the WINAPI_PARTITION_APP symbol.  You can use load-time dynamic linking by linking to the SDK import libraries to reference these. 

    There are other Windows API functions like LoadLibrary that cannot be used from metro-style applications; these are marked with WINAPI_PARITITON_DESKTOP.  If you try to use them, you'll get a "C3861: identifier not found" compiler error.  Suppose you try to get around the compiler error by copying the function declaration into your own code, you can get your app to compile and link.  When you run the App Certification Kit, it will fail the "Use Supported Platform APIs".

    So basically, if you start with a project template, you'll have the right symbols defined so the headers will #ifdef in or out the Windows API functions you can/can't use.  The App Certification Kit will help you test for this.

    I hope this helps.

    Dan

     

     

    Thursday, October 13, 2011 4:00 AM
    Moderator
  • Yes, my original question regarding certification and debug builds has been answered.

    Regarding dynamic linking, it is my understanding that LoadPackagedLibrary cannot load DLLs from a folder such as System32.  However, as I mentioned, my metro app can load arbitrary DLLs from System32 and pass certification if it uses load-time dynamic linking:

    http://msdn.microsoft.com/en-us/library/windows/desktop/ms684184(v=vs.85).aspx

    This seems to break the model of apps only being allowed to load DLLs from their package.

    Thursday, October 13, 2011 8:20 PM
  • But the problem is that the developer has no way of ensuring that the arbitrary DLL will be present in System32.  Classic apps could do that since they could themselves install that DLL in System32.  But for Metro style apps, the new deployment model doesn’t allow apps to install files in random locations. 

    And for the DLLs that Windows itself puts in System32, well you need a way (import lib) to dynamically link to them.  And if Windows provides an import lib for this DLL in the SDK then obviously they feel it is safe to call into this DLL from a metro style app.

    Thanks

    Raman Sharma, Visual C++

    Thursday, October 13, 2011 9:17 PM
  • Yes, my original question regarding certification and debug builds has been answered.

    Regarding dynamic linking, it is my understanding that LoadPackagedLibrary cannot load DLLs from a folder such as System32.  However, as I mentioned, my metro app can load arbitrary DLLs from System32 and pass certification if it uses load-time dynamic linking:

    http://msdn.microsoft.com/en-us/library/windows/desktop/ms684184(v=vs.85).aspx

    This seems to break the model of apps only being allowed to load DLLs from their package.

    LoadPackagedLibrary is limited to loading only modules that are referenced by the app package manifest:  http://msdn.microsoft.com/en-us/library/hh447159(v=VS.85).aspx.

    Aside from LoadPackagedLibrary, dynamic linking to DLLs in the System32 directory is allowed because there are a number of Windows API functions that can be called from metro-style apps.  These are marked in the windows header files as described above.  To actually use them at runtime, you do need the ability to link to the DLLs where they live; this is why you can link to DLLs in System32. 

    Although you can load arbitrary DLLs in the System32 directory, we strongly recommend that you only link to DLLs that ship with Windows because:

    1. If you link to a 3rd party DLL inside System32, but that DLL that doesn't exist on one of your user's machines, your application will fail to load as documented in the MSDN reference page.

    2. The System32 directory is not a place for 3rd parties to place their DLLs (except for .NET assemblies that that install into the GAC).  This is enforced by the ACL on the \Windows directory that limits write access to specific privileged & admin accounts and by the Windows Client Software Logo requirements (http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=3859). 

    #2 means that your metro-style application's installer will not be able to copy DLLs into System32.

    Thus, you can use dynamic linking to call the Windows API functions that are marked safe for metro-style applications, but you should not rely on calling other functions from other DLLs.

    Sincerely,

    Dan

    Friday, October 14, 2011 6:15 PM
    Moderator