Consider the following code:

import core.sys.windows.windows;
import core.sys.windows.shlobj;
import core.sys.windows.wtypes;

import std.exception;

pragma(lib, "Ole32");

void main()
{
    OleInitialize(null);
    scope(exit) OleUninitialize();
    IShellFolder desktop;
    LPITEMIDLIST pidlRecycleBin;

enforce(SUCCEEDED(SHGetDesktopFolder(&desktop)), "Failed to get desktop shell folder");
    assert(desktop);
    scope(exit) desktop.Release();
enforce(SUCCEEDED(SHGetSpecialFolderLocation(null, CSIDL_BITBUCKET, &pidlRecycleBin)), "Failed to get recycle bin location");
    assert(pidlRecycleBin);
    scope(exit) ILFree(pidlRecycleBin);

    IShellFolder2 recycleBin;
enforce(SUCCEEDED(desktop.BindToObject(pidlRecycleBin, null, &IID_IShellFolder2, cast(LPVOID *)&recycleBin)), "Failed to get recycle bin shell folder");
    assert(recycleBin);
    scope(exit) recycleBin.Release();

    IEnumIDList enumFiles;
with(SHCONTF) enforce(SUCCEEDED(recycleBin.EnumObjects(null, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS | SHCONTF_INCLUDEHIDDEN, &enumFiles)), "Failed to enumerate objects in recycle bin");
    enumFiles.Release();
}

For me this code crashes with error:

object.Error@(0): Access Violation
----------------
0x75B4EBB8 in SHELL32_CLocationContextMenu_Create
0x004023A9
0x0040493B
0x004048B5
0x0040474E
0x00402C9A
0x0040250B
0x75816359 in BaseThreadInitThunk
0x76F07C24 in RtlGetAppContainerNamedObjectPath
0x76F07BF4 in RtlGetAppContainerNamedObjectPath

However if I change the type of recycleBin variable to IShellFolder (not IShellFolder2), the crash does not happen.

Does IShellFolder2 require some special handling?

Reply via email to