Using DISM_MOUNT_OPTIMIZE in the MountImage call leads to failure

Apr 14, 2014 at 4:44 PM
Hi All,
I have found that if you use the DISM_MOUNT_OPTIMIZE (line 1162 of DismApi.cs) as one of the flags passed to NativeMethods.DismMountImage for an offline image, you won't be able to use the OpenOfflineSession method. You'll get an HRESULT (converted Win32 error) indicating that the image is not available.

I wrote a C++ app that uses the DISM api directly and provided the DISM_MOUNT_OPTIMIZE flag to the MountImage call. The original win32 error is 0x10FE, here's the error description as it appears in the local variables window:
HRESULT_FROM_WIN32(ERROR_FILE_OFFLINE) : This file is currently not available for use on this computer.

I can't find an explanation for this bad behavior, but I'm guessing that OpenOfflineSession needs to have immediate access to all directories in the mounted image. Perhaps the 'optimized' flavor of a mounted image is just not adequate for the OpenOfflineSession to operate correctly.

Apr 14, 2014 at 5:57 PM
I forgot to mention - this is on a Windows 7 machine where I'm manipulating an offline image that happens to be an instance of WinPE.
Apr 15, 2014 at 9:58 PM
This is really interesting, I wonder why its not mentioned in the documentation. Do you think I should add an exception in this case? This will at least protect people using my managed API.
Apr 16, 2014 at 2:17 PM
Edited Apr 17, 2014 at 5:00 PM
Hi Jose,
I'd say that we probably need to allow callers of MountImage to specify the flags to be used - maybe eliminating the readOnly argument. The documentation for MountImage should warn people about the problem with DISM_MOUNT_OPTIMIZE. In the OpenOfflineSession I would check for 0x10FE and throw an exception that indicates that DISM_MOUNT_OPTIMIZE could be causing the error condition.

I'll code up the changes and test them out.

Here's my proposal for the MountImage change:
    public static void MountImage(string imageFilePath, string mountPath, int imageIndex, bool readOnly, Dism.DismProgressCallback progressCallback, object userData, uint additionalFlags = 0)
        uint flags = (readOnly ? DISM_MOUNT_READONLY : DISM_MOUNT_READWRITE) | additionalFlags;
        DismApi.MountImage(imageFilePath, mountPath, imageIndex, null, DismImageIdentifier.ImageIndex, flags, progressCallback, userData);
This would cause the least disruption to the other flavors of MountImage. Of course, we could provide access to the flags argument across the board. I don't know how often someone would really need to specify one of the flag values other than the readOnly/readWrite value.

Apr 18, 2014 at 1:47 PM
This is definitely a Windows 7 specific bug. I tried the C++ code I used to test MountImage with DISM_MOUNT_OPTIMIZE on a Win8.1 machine - no problems there.
Apr 18, 2014 at 6:53 PM
That's really interesting. I wonder if its a problem in wimgapi.dll or in the operating system itself. Can you try copying wimgapi.dll from your win8 machine to your win7 machine and seeing if it works?
Apr 18, 2014 at 8:52 PM
Hi Jose,
Unfortunately, the wimgapi.dll has dependencies on 24 API-MS-WIN* dll's. You really can't just copy wimgapi.dll. I've tried that debugging technique on other problems - it feels like pulling up the roots of a bush you want to remove from your garden ;-). Do you want a copy of the C++ project to try out?