/*
 * Unit tests to document shdocvw's 'Shell Instance Objects' features
 *
 * Copyright 2005 Michael Jung
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

/* At least since Windows 2000 it's possible to add FolderShortcut objects
 * by creating some registry entries. Those objects, which refer to some
 * point in the filesystem, can be registered in the shell namespace like other 
 * shell namespace extensions. Icons, names and filesystem location can be
 * configured. This is documented at http://www.virtualplastic.net/html/ui_shell.html
 * You can also google for a tool called "ShellObjectEditor" by "Tropical 
 * Technologies". This mechanism would be cool for wine, since we could 
 * map Gnome's virtual devices to FolderShortcuts and have them appear in the
 * file dialogs. These unit tests are meant to document how this mechanism
 * works on windows.
 *
 * Search MSDN for "Creating Shell Extensions with Shell Instance Objects" for
 * more documentation.*/

#include <stdarg.h>

#define COBJMACROS

#include "windef.h"
#include "winbase.h"
#include "winreg.h"

#include "shlobj.h"
#include "shobjidl.h"
#include "shlguid.h"
#include "ole2.h"

#include "wine/unicode.h"
#include "wine/test.h"

/* The following definitions and helper functions are meant to make the de-/registration
 * of the various necessary registry keys easier. */

struct registry_value {
    const char  *szName;
    const DWORD dwType;
    const char  *szValue;
    const DWORD dwValue;
};

#define REG_VALUE_ADDR(x) ((x->dwType==REG_SZ)?(const BYTE *)x->szValue:(const BYTE *)&x->dwValue)
#define REG_VALUE_SIZE(x) ((x->dwType==REG_SZ)?strlen(x->szValue)+1:sizeof(DWORD))

struct registry_key {
    const char                  *szName;
    const struct registry_value *pValues;
    const unsigned int          cValues;
    const struct registry_key   *pSubKeys;
    const unsigned int          cSubKeys;
};

static const struct registry_value ShellFolder_values[] = {
    { "WantsFORPARSING", REG_SZ,    "",   0          },
    { "Attributes",      REG_DWORD, NULL, 0xF8000100 }
};

static const struct registry_value Instance_values[] = {
    { "CLSID", REG_SZ, "{0AFACED1-E828-11D1-9187-B532F1E9575D}", 0 }
};

static const struct registry_value InitPropertyBag_values[] = {
    { "Attributes", REG_DWORD, NULL,   0x00000015 },
    { "Target",     REG_SZ,    "C:\\", 0          }
};

static const struct registry_key Instance_keys[] = {
    { "InitPropertyBag", InitPropertyBag_values, 2, NULL, 0 }
};

static const struct registry_value InProcServer32_values[] = {
    { NULL,             REG_SZ, "shdocvw.dll", 0 },
    { "ThreadingModel", REG_SZ, "Apartment",   0 }
};

static const struct registry_value DefaultIcon_values[] = {
    { NULL, REG_SZ,"shell32.dll,8", 0 }
};

static const struct registry_key ShortcutCLSID_keys[] = {
    { "DefaultIcon",    DefaultIcon_values,    1, NULL,          0 },
    { "InProcServer32", InProcServer32_values, 2, NULL,          0 },
    { "Instance",       Instance_values,       1, Instance_keys, 1 },
    { "ShellFolder",    ShellFolder_values,    2, NULL,          0 }
};

static const struct registry_value ShortcutCLSID_values[] = {
    { NULL, REG_SZ, "WineTest", 0 }
};

static const struct registry_key HKEY_CLASSES_ROOT_keys[] = {
    { "CLSID\\{9B352EBF-2765-45C1-B4C6-85CC7F7ABC64}", ShortcutCLSID_values, 1, ShortcutCLSID_keys, 4}
};

/* register_keys - helper function, which recursively creates the registry keys and values in 
 * parameter 'keys' in the registry under hRootKey. */
static BOOL register_keys(HKEY hRootKey, const struct registry_key *keys, unsigned int numKeys) {
    HKEY hKey;
    unsigned int iKey, iValue;

    for (iKey = 0; iKey < numKeys; iKey++) {
        if (ERROR_SUCCESS == RegCreateKeyExA(hRootKey, keys[iKey].szName, 0, NULL, 0, 
                                             KEY_WRITE, NULL, &hKey, NULL))
        {
            for (iValue = 0; iValue < keys[iKey].cValues; iValue++) {
                const struct registry_value * value = &keys[iKey].pValues[iValue];
                if (ERROR_SUCCESS != RegSetValueExA(hKey, value->szName, 0, value->dwType,
                                                    REG_VALUE_ADDR(value), REG_VALUE_SIZE(value)))
                {
                    RegCloseKey(hKey);
                    return FALSE;
                }
            }
            
            if (!register_keys(hKey, keys[iKey].pSubKeys, keys[iKey].cSubKeys)) {
                RegCloseKey(hKey);
                return FALSE;
            }
            
            RegCloseKey(hKey);
        }
    }
        
    return TRUE;
}

/* unregister_keys - clean up after register_keys */
static void unregister_keys(HKEY hRootKey, const struct registry_key *keys, unsigned int numKeys) {
    HKEY hKey;
    unsigned int iKey;

    for (iKey = 0; iKey < numKeys; iKey++) {
        if (ERROR_SUCCESS == RegOpenKeyExA(hRootKey, keys[iKey].szName, 0, DELETE, &hKey)) {
            unregister_keys(hKey, keys[iKey].pSubKeys, keys[iKey].cSubKeys);
            RegCloseKey(hKey);
        }
        RegDeleteKeyA(hRootKey, keys[iKey].szName);
    }
}
    
static void test_ShortcutFolder(void) {
    LPSHELLFOLDER pDesktopFolder, pWineTestFolder;
    IPersistFolder3 *pWineTestPersistFolder;
    LPITEMIDLIST pidlWineTestFolder, pidlCurFolder;
    HRESULT hr;
    CLSID clsid;
    const CLSID CLSID_WineTest = 
        { 0x9b352ebf, 0x2765, 0x45c1, { 0xb4, 0xc6, 0x85, 0xcc, 0x7f, 0x7a, 0xbc, 0x64 } };
    WCHAR wszWineTestFolder[] = {
        ':',':','{','9','B','3','5','2','E','B','F','-','2','7','6','5','-','4','5','C','1','-',
        'B','4','C','6','-','8','5','C','C','7','F','7','A','B','C','6','4','}',0 };

    /* First, we register all the necessary registry keys/values for our 'WineTest'
     * shell object. */
    register_keys(HKEY_CLASSES_ROOT, HKEY_CLASSES_ROOT_keys, 1);

    hr = SHGetDesktopFolder(&pDesktopFolder);
    ok (SUCCEEDED(hr), "SHGetDesktopFolder failed! hr = %08lx\n", hr);
    if (FAILED(hr)) goto cleanup;

    /* Convert the wszWineTestFolder string to an ITEMIDLIST. */
    hr = IShellFolder_ParseDisplayName(pDesktopFolder, NULL, NULL, wszWineTestFolder, NULL, 
                                       &pidlWineTestFolder, NULL);
    ok (SUCCEEDED(hr), "IShellFolder::ParseDisplayName failed! hr = %08lx\n", hr);
    if (FAILED(hr)) {
        IShellFolder_Release(pDesktopFolder);
        goto cleanup;
    }

    /* Bind to a WineTest folder object. There has to be some support for this in shdocvw.dll.
     * This isn't implemented in wine yet.*/
    hr = IShellFolder_BindToObject(pDesktopFolder, pidlWineTestFolder, NULL, &IID_IShellFolder, 
                                   (LPVOID*)&pWineTestFolder);
    IShellFolder_Release(pDesktopFolder);
    ILFree(pidlWineTestFolder);
    ok (SUCCEEDED(hr), "IShellFolder::BindToObject(WineTestFolder) failed! hr = %08lx\n", hr);
    if (FAILED(hr)) goto cleanup;

    hr = IShellFolder_QueryInterface(pWineTestFolder, &IID_IPersistFolder3, (LPVOID*)&pWineTestPersistFolder);
    ok (SUCCEEDED(hr), "IShellFolder::QueryInterface(IPersistFolder3) failed! hr = %08lx\n", hr);
    IShellFolder_Release(pWineTestFolder);
    if (FAILED(hr)) goto cleanup;

    /* The resulting folder object has the FolderShortcut CLSID, instead of it's own. */
    hr = IPersistFolder3_GetClassID(pWineTestPersistFolder, &clsid);
    ok (SUCCEEDED(hr), "IPersist::GetClassID failed! hr = %08lx\n", hr);
    ok (IsEqualCLSID(&CLSID_FolderShortcut, &clsid), "GetClassId returned wrong CLSID!\n"); 
  
    pidlCurFolder = (LPITEMIDLIST)0xdeadbeef;
    hr = IPersistFolder3_GetCurFolder(pWineTestPersistFolder, &pidlCurFolder);
    ok (SUCCEEDED(hr), "IPersistFolder3::GetCurFolder failed! hr = %08lx\n", hr);
    ok (pidlCurFolder->mkid.cb == 20 && ((LPSHITEMID)((BYTE*)pidlCurFolder+20))->cb == 0 && 
        IsEqualCLSID(&CLSID_WineTest, (REFCLSID)((LPBYTE)pidlCurFolder+4)), 
        "GetCurFolder returned unexpected pidl!\n");
    
    IPersistFolder3_Release(pWineTestPersistFolder);
    
cleanup:
    unregister_keys(HKEY_CLASSES_ROOT, HKEY_CLASSES_ROOT_keys, 1);
}    
    
START_TEST(shortcut)
{
    OleInitialize(NULL);
    test_ShortcutFolder();
    OleUninitialize();
}
