locked
LoadLibraryW blocked? Seriously?

    Question

  • In testing my application for Metro certification, I found that I would NOT be able to sell my app to future Windows 8 customers, because LoadLibraryW and all the other equivalent functions are blocked. There are legitimate uses for this! Could someone please explain why these very useful features are disabled, especially when they are still necessary to interop with older code? In many cases, it is desirable to load a third-party/legacy DLL into an application. I am extremely disappointed to see this was blocked. Seems like you are making a mistake -- making a disabled version of Windows, and limiting it to the function of a managed phone (such as WP), and preventing it from harnessing the full capability of the hardware (what if we just want to target PCs and NOT tablets?)
    • Edited by IDWNet Tuesday, September 20, 2011 2:31 AM
    Tuesday, September 20, 2011 2:18 AM

Answers

  • Are you compiling as debug or release?  Always run the certification test on a release build.  Running on debug builds can produce false-positives like that.

    --Rob

    • Marked as answer by IDWNet Friday, September 23, 2011 4:03 AM
    Thursday, September 22, 2011 1:10 AM
    Owner

All replies

  • Check out LoadPackagedLibrary.

    http://msdn.microsoft.com/en-us/library/windows/apps/hh447159(v=VS.85).aspx

    If you look at the list. FreeLibrary is still an allowed function, so there must have been a way to load a library.

    Tuesday, September 20, 2011 10:12 AM
  • Where can I find the list of allowed functions, and how can I prevent the internals of the compiler from generating a call to LoadLibrary? Any app (including the sample DirectX app) generates this forbidden call automatically.
    Tuesday, September 20, 2011 7:46 PM
  • The allowed Win32 and COM API are documented at http://msdn.microsoft.com/en-us/library/windows/apps/br205757(v=VS.85).aspx .  Disallowed functions will be automatically dropped from the headers for Metro style apps so apps which try to use them won't compile.

    I'm not sure what you mean by preventing the internals of the compiler from generating a call to LoadLibrary.  If you are concerned about static linking to system DLLs or DLLs included in your app package then those links will work fine.  If they didn't then no applications would run. 

    --Rob

     

    Tuesday, September 20, 2011 8:41 PM
    Owner
  • What I mean is that my code never actually CALLS the LoadLibrary function, but somehow the certification system doesn't like my code because it calls LoadLibrary, leading me to believe the compiler must be sticking it in there somewhere (it does say it's being called in my library, even though I'm NOT calling it).
    Tuesday, September 20, 2011 8:43 PM
  • Do you use a form of /DELAYLOAD? That's historically been a compiler feature that uses LoadLibrary, e.g. you link in some compiler-vendor provided code into your PE file so at runtime it executes, dynamically patching up your IAT via LoadLibrary() plus the appropriate GetProcAddress() calls. So even though *you* don't directly call LoadLibrary, your binary does have a reference to LoadLibrary.

    You have 3 options for code linkage:

    1. Import Reference - link your EXE/DLL with the target library. Your IAT will have references to the target

    2. Delay Load (new) - Windows 8's Loader has new(!) support to handle a 'delay load' import. This is effectively a deferred form of #1 - you still specify the relationship @ link-time, your PE file contains references to the target, etc but Windows will delay loading the target until 1st use

    3. LoadPackagedLibrary(fn) - akin to LoadLibrary except (a) fn cannot be an absolute filename, (b) fn cannot be a relative pathname containing ".." as a path element and (c) fn must be in your package graph.

    1+2 are 'static', in that you know about them @ build-time and your EXE/DLL contains a reference to the target. 3 is 'dynamic' in that it's just code only determinable at runtime; the target cannot be determined by static analysis of your binary.

    3 is also restricted to packaged DLLs - it will fail if you try to load something outside your package graph! Yes, LoadPackagedLibrary("kernel32") will fail. Directly loading a system DLL (by definition never packaged) must be loaded via 1 or 2. [Windows itself uses LoadLibrary in certain subsystems, e.g. WinRT DLLs are loaded for you via LoadLibrary, not LoadPackagedLibrary]

    1 is great for things you always need. 2 is great for things you optionally need (e.g. printing or other less-commonly-used modules). 3 is great for conditional code, e.g. a game with low-, medium- and hi-res graphics you want to use one, but which depend variables like machine and/or user configuration:

    HMODULE h;
    switch (resolution) {
        case HIGH: h = LoadPackagedLibrary("map-hires"); break;
        case LOW: h = LoadPackagedLibrary("map-lores"); break;
        case MEDIUM:
        default:
            h = LoadPackagedLibrary("map-medres"); break;
    }
    

     


    The architect must be a prophet...a prophet in the true sense of the term...if he can't see at least ten years ahead don't call him an architect - Frank Lloyd Wright

    Howard Kapustein [MSFT] -- Looking for the Spike...

    Wednesday, September 21, 2011 8:33 PM
  • Are you compiling as debug or release?  Always run the certification test on a release build.  Running on debug builds can produce false-positives like that.

    --Rob

    • Marked as answer by IDWNet Friday, September 23, 2011 4:03 AM
    Thursday, September 22, 2011 1:10 AM
    Owner