/* Unit test suite for SHLWAPI ordinal functions
 *
 * Copyright 2004 Jon Griffiths
 *
 * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include <stdio.h>

#define COBJMACROS
#define CONST_VTABLE
#include "wine/test.h"
#include "winbase.h"
#include "winerror.h"
#include "winuser.h"
#include "ole2.h"
#include "oaidl.h"
#include "ocidl.h"
#include "mlang.h"
#include "shlwapi.h"
#include "docobj.h"
#include "shobjidl.h"
#include "shlobj.h"

/* Function ptrs for ordinal calls */
static HMODULE hShlwapi;
static BOOL is_win2k_and_lower;
static BOOL is_win9x;

static int (WINAPI *pSHSearchMapInt)(const int*,const int*,int,int);
static HRESULT (WINAPI *pGetAcceptLanguagesA)(LPSTR,LPDWORD);

static HANDLE (WINAPI *pSHAllocShared)(LPCVOID,DWORD,DWORD);
static LPVOID (WINAPI *pSHLockShared)(HANDLE,DWORD);
static BOOL   (WINAPI *pSHUnlockShared)(LPVOID);
static BOOL   (WINAPI *pSHFreeShared)(HANDLE,DWORD);
static HRESULT(WINAPIV *pSHPackDispParams)(DISPPARAMS*,VARIANTARG*,UINT,...);
static HRESULT(WINAPI *pIConnectionPoint_SimpleInvoke)(IConnectionPoint*,DISPID,DISPPARAMS*);
static HRESULT(WINAPI *pIConnectionPoint_InvokeWithCancel)(IConnectionPoint*,DISPID,DISPPARAMS*,DWORD,DWORD);
static HRESULT(WINAPI *pConnectToConnectionPoint)(IUnknown*,REFIID,BOOL,IUnknown*, LPDWORD,IConnectionPoint **);
static HRESULT(WINAPI *pSHPropertyBag_ReadLONG)(IPropertyBag *,LPCWSTR,LPLONG);
static LONG   (WINAPI *pSHSetWindowBits)(HWND, INT, UINT, UINT);
static INT    (WINAPI *pSHFormatDateTimeA)(const FILETIME UNALIGNED*, DWORD*, LPSTR, UINT);
static INT    (WINAPI *pSHFormatDateTimeW)(const FILETIME UNALIGNED*, DWORD*, LPWSTR, UINT);
static DWORD  (WINAPI *pSHGetObjectCompatFlags)(IUnknown*, const CLSID*);
static BOOL   (WINAPI *pGUIDFromStringA)(LPSTR, CLSID *);
static HRESULT (WINAPI *pIUnknown_QueryServiceExec)(IUnknown*, REFIID, const GUID*, DWORD, DWORD, VARIANT*, VARIANT*);
static HRESULT (WINAPI *pIUnknown_ProfferService)(IUnknown*, REFGUID, IServiceProvider*, DWORD*);
static HWND    (WINAPI *pSHCreateWorkerWindowA)(LONG, HWND, DWORD, DWORD, HMENU, LONG_PTR);
static HRESULT (WINAPI *pSHIShellFolder_EnumObjects)(LPSHELLFOLDER, HWND, SHCONTF, IEnumIDList**);
static DWORD   (WINAPI *pSHGetIniStringW)(LPCWSTR, LPCWSTR, LPWSTR, DWORD, LPCWSTR);
static BOOL    (WINAPI *pSHSetIniStringW)(LPCWSTR, LPCWSTR, LPCWSTR, LPCWSTR);
static HKEY    (WINAPI *pSHGetShellKey)(DWORD, LPCWSTR, BOOL);
static HRESULT (WINAPI *pSKGetValueW)(DWORD, LPCWSTR, LPCWSTR, DWORD*, void*, DWORD*);
static HRESULT (WINAPI *pSKSetValueW)(DWORD, LPCWSTR, LPCWSTR, DWORD, void*, DWORD);
static HRESULT (WINAPI *pSKDeleteValueW)(DWORD, LPCWSTR, LPCWSTR);
static HRESULT (WINAPI *pSKAllocValueW)(DWORD, LPCWSTR, LPCWSTR, DWORD*, void**, DWORD*);

static HMODULE hmlang;
static HRESULT (WINAPI *pLcidToRfc1766A)(LCID, LPSTR, INT);

static HMODULE hshell32;
static HRESULT (WINAPI *pSHGetDesktopFolder)(IShellFolder**);

static const CHAR ie_international[] = {
    'S','o','f','t','w','a','r','e','\\',
    'M','i','c','r','o','s','o','f','t','\\',
    'I','n','t','e','r','n','e','t',' ','E','x','p','l','o','r','e','r','\\',
    'I','n','t','e','r','n','a','t','i','o','n','a','l',0};
static const CHAR acceptlanguage[] = {
    'A','c','c','e','p','t','L','a','n','g','u','a','g','e',0};

static int strcmp_wa(LPCWSTR strw, const char *stra)
{
    CHAR buf[512];
    WideCharToMultiByte(CP_ACP, 0, strw, -1, buf, sizeof(buf), NULL, NULL);
    return lstrcmpA(stra, buf);
}

typedef struct {
    int id;
    const void *args[5];
} call_entry_t;

typedef struct {
    call_entry_t *calls;
    int count;
    int alloc;
} call_trace_t;

static void init_call_trace(call_trace_t *ctrace)
{
    ctrace->alloc = 10;
    ctrace->count = 0;
    ctrace->calls = HeapAlloc(GetProcessHeap(), 0, sizeof(call_entry_t) * ctrace->alloc);
}

static void free_call_trace(const call_trace_t *ctrace)
{
    HeapFree(GetProcessHeap(), 0, ctrace->calls);
}

static void add_call(call_trace_t *ctrace, int id, const void *arg0,
    const void *arg1, const void *arg2, const void *arg3, const void *arg4)
{
    call_entry_t call;

    call.id = id;
    call.args[0] = arg0;
    call.args[1] = arg1;
    call.args[2] = arg2;
    call.args[3] = arg3;
    call.args[4] = arg4;

    if (ctrace->count == ctrace->alloc)
    {
        ctrace->alloc *= 2;
        ctrace->calls = HeapReAlloc(GetProcessHeap(),0, ctrace->calls, ctrace->alloc*sizeof(call_entry_t));
    }

    ctrace->calls[ctrace->count++] = call;
}

static void ok_trace_(call_trace_t *texpected, call_trace_t *tgot, int line)
{
    if (texpected->count == tgot->count)
    {
        INT i;
        /* compare */
        for (i = 0; i < texpected->count; i++)
        {
            call_entry_t *expected = &texpected->calls[i];
            call_entry_t *got = &tgot->calls[i];
            INT j;

            ok_(__FILE__, line)(expected->id == got->id, "got different ids %d: %d, %d\n", i+1, expected->id, got->id);

            for (j = 0; j < 5; j++)
            {
                ok_(__FILE__, line)(expected->args[j] == got->args[j], "got different args[%d] for %d: %p, %p\n", j, i+1,
                   expected->args[j], got->args[j]);
            }
        }
    }
    else
        ok_(__FILE__, line)(0, "traces length mismatch\n");
}

#define ok_trace(a, b) ok_trace_(a, b, __LINE__)

/* trace of actually made calls */
static call_trace_t trace_got;

static void test_GetAcceptLanguagesA(void)
{
    static LPCSTR table[] = {"de,en-gb;q=0.7,en;q=0.3",
                             "de,en;q=0.3,en-gb;q=0.7", /* sorting is ignored */
                             "winetest",    /* content is ignored */
                             "de-de,de;q=0.5",
                             "de",
                             NULL};

    DWORD exactsize;
    char original[512];
    char language[32];
    char buffer[64];
    HKEY hroot = NULL;
    LONG res_query = ERROR_SUCCESS;
    LONG lres;
    HRESULT hr;
    DWORD maxlen = sizeof(buffer) - 2;
    DWORD len;
    LCID lcid;
    LPCSTR entry;
    INT i = 0;

    if (!pGetAcceptLanguagesA) {
        win_skip("GetAcceptLanguagesA is not available\n");
        return;
    }

    lcid = GetUserDefaultLCID();

    /* Get the original Value */
    lres = RegOpenKeyA(HKEY_CURRENT_USER, ie_international, &hroot);
    if (lres) {
        skip("RegOpenKey(%s) failed: %d\n", ie_international, lres);
        return;
    }
    len = sizeof(original);
    original[0] = 0;
    res_query = RegQueryValueExA(hroot, acceptlanguage, 0, NULL, (PBYTE)original, &len);

    RegDeleteValue(hroot, acceptlanguage);

    /* Some windows versions use "lang-COUNTRY" as default */
    memset(language, 0, sizeof(language));
    len = GetLocaleInfoA(lcid, LOCALE_SISO639LANGNAME, language, sizeof(language));

    if (len) {
        lstrcat(language, "-");
        memset(buffer, 0, sizeof(buffer));
        len = GetLocaleInfoA(lcid, LOCALE_SISO3166CTRYNAME, buffer, sizeof(buffer) - len - 1);
        lstrcat(language, buffer);
    }
    else
    {
        /* LOCALE_SNAME has additional parts in some languages. Try only as last chance */
        memset(language, 0, sizeof(language));
        len = GetLocaleInfoA(lcid, LOCALE_SNAME, language, sizeof(language));
    }

    /* get the default value */
    len = maxlen;
    memset(buffer, '#', maxlen);
    buffer[maxlen] = 0;
    hr = pGetAcceptLanguagesA( buffer, &len);

    if (hr != S_OK) {
        win_skip("GetAcceptLanguagesA failed with 0x%x\n", hr);
        goto restore_original;
    }

    if (lstrcmpA(buffer, language)) {
        /* some windows versions use "lang" or "lang-country" as default */
        language[0] = 0;
        if (pLcidToRfc1766A) {
            hr = pLcidToRfc1766A(lcid, language, sizeof(language));
            ok(hr == S_OK, "LcidToRfc1766A returned 0x%x and %s\n", hr, language);
        }
    }

    ok(!lstrcmpA(buffer, language),
        "have '%s' (searching for '%s')\n", language, buffer);

    if (lstrcmpA(buffer, language)) {
        win_skip("no more ideas, how to build the default language '%s'\n", buffer);
        goto restore_original;
    }

    trace("detected default: %s\n", language);
    while ((entry = table[i])) {

        exactsize = lstrlenA(entry);

        lres = RegSetValueExA(hroot, acceptlanguage, 0, REG_SZ, (const BYTE *) entry, exactsize + 1);
        ok(!lres, "got %d for RegSetValueExA: %s\n", lres, entry);

        /* len includes space for the terminating 0 before vista/w2k8 */
        len = exactsize + 2;
        memset(buffer, '#', maxlen);
        buffer[maxlen] = 0;
        hr = pGetAcceptLanguagesA( buffer, &len);
        ok(((hr == E_INVALIDARG) && (len == 0)) ||
            (SUCCEEDED(hr) &&
            ((len == exactsize) || (len == exactsize+1)) &&
            !lstrcmpA(buffer, entry)),
            "+2_#%d: got 0x%x with %d and %s\n", i, hr, len, buffer);

        len = exactsize + 1;
        memset(buffer, '#', maxlen);
        buffer[maxlen] = 0;
        hr = pGetAcceptLanguagesA( buffer, &len);
        ok(((hr == E_INVALIDARG) && (len == 0)) ||
            (SUCCEEDED(hr) &&
            ((len == exactsize) || (len == exactsize+1)) &&
            !lstrcmpA(buffer, entry)),
            "+1_#%d: got 0x%x with %d and %s\n", i, hr, len, buffer);

        len = exactsize;
        memset(buffer, '#', maxlen);
        buffer[maxlen] = 0;
        hr = pGetAcceptLanguagesA( buffer, &len);

        /* There is no space for the string in the registry.
           When the buffer is large enough, the default language is returned

           When the buffer is too small for that fallback, win7_32 and w2k8_64
           and above fail with HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER), but
           recent os succeed and return a partial result while
           older os succeed and overflow the buffer */

        ok(((hr == E_INVALIDARG) && (len == 0)) ||
            (((hr == S_OK) && !lstrcmpA(buffer, language)  && (len == lstrlenA(language))) ||
            ((hr == S_OK) && !memcmp(buffer, language, len)) ||
            ((hr == __HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)) && !len)),
            "==_#%d: got 0x%x with %d and %s\n", i, hr, len, buffer);

        if (exactsize > 1) {
            len = exactsize - 1;
            memset(buffer, '#', maxlen);
            buffer[maxlen] = 0;
            hr = pGetAcceptLanguagesA( buffer, &len);
            ok(((hr == E_INVALIDARG) && (len == 0)) ||
                (((hr == S_OK) && !lstrcmpA(buffer, language)  && (len == lstrlenA(language))) ||
                ((hr == S_OK) && !memcmp(buffer, language, len)) ||
                ((hr == __HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)) && !len)),
                "-1_#%d: got 0x%x with %d and %s\n", i, hr, len, buffer);
        }

        len = 1;
        memset(buffer, '#', maxlen);
        buffer[maxlen] = 0;
        hr = pGetAcceptLanguagesA( buffer, &len);
        ok(((hr == E_INVALIDARG) && (len == 0)) ||
            (((hr == S_OK) && !lstrcmpA(buffer, language)  && (len == lstrlenA(language))) ||
            ((hr == S_OK) && !memcmp(buffer, language, len)) ||
            ((hr == __HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)) && !len)),
            "=1_#%d: got 0x%x with %d and %s\n", i, hr, len, buffer);

        len = maxlen;
        hr = pGetAcceptLanguagesA( NULL, &len);

        /* w2k3 and below: E_FAIL and untouched len,
           since w2k8: S_OK and needed size (excluding 0) */
        ok( ((hr == S_OK) && (len == exactsize)) ||
            ((hr == E_FAIL) && (len == maxlen)),
            "NULL,max #%d: got 0x%x with %d and %s\n", i, hr, len, buffer);

        i++;
    }

    /* without a value in the registry, a default language is returned */
    RegDeleteValue(hroot, acceptlanguage);

    len = maxlen;
    memset(buffer, '#', maxlen);
    buffer[maxlen] = 0;
    hr = pGetAcceptLanguagesA( buffer, &len);
    ok( ((hr == S_OK) && (len == lstrlenA(language))),
        "max: got 0x%x with %d and %s (expected S_OK with %d and '%s'\n",
        hr, len, buffer, lstrlenA(language), language);

    len = 2;
    memset(buffer, '#', maxlen);
    buffer[maxlen] = 0;
    hr = pGetAcceptLanguagesA( buffer, &len);
    ok( (((hr == S_OK) || (hr == E_INVALIDARG)) && !memcmp(buffer, language, len)) ||
        ((hr == __HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)) && !len),
        "=2: got 0x%x with %d and %s\n", hr, len, buffer);

    len = 1;
    memset(buffer, '#', maxlen);
    buffer[maxlen] = 0;
    hr = pGetAcceptLanguagesA( buffer, &len);
    /* When the buffer is too small, win7_32 and w2k8_64 and above fail with
       HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER), other versions suceed
       and return a partial 0 terminated result while other versions
       fail with E_INVALIDARG and return a partial unterminated result */
    ok( (((hr == S_OK) || (hr == E_INVALIDARG)) && !memcmp(buffer, language, len)) ||
        ((hr == __HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)) && !len),
        "=1: got 0x%x with %d and %s\n", hr, len, buffer);

    len = 0;
    memset(buffer, '#', maxlen);
    buffer[maxlen] = 0;
    hr = pGetAcceptLanguagesA( buffer, &len);
    /* w2k3 and below: E_FAIL, since w2k8: E_INVALIDARG */
    ok((hr == E_FAIL) || (hr == E_INVALIDARG),
        "got 0x%x (expected E_FAIL or E_INVALIDARG)\n", hr);

    memset(buffer, '#', maxlen);
    buffer[maxlen] = 0;
    hr = pGetAcceptLanguagesA( buffer, NULL);
    /* w2k3 and below: E_FAIL, since w2k8: E_INVALIDARG */
    ok((hr == E_FAIL) || (hr == E_INVALIDARG),
        "got 0x%x (expected E_FAIL or E_INVALIDARG)\n", hr);


    hr = pGetAcceptLanguagesA( NULL, NULL);
    /* w2k3 and below: E_FAIL, since w2k8: E_INVALIDARG */
    ok((hr == E_FAIL) || (hr == E_INVALIDARG),
        "got 0x%x (expected E_FAIL or E_INVALIDARG)\n", hr);

restore_original:
    if (!res_query) {
        len = lstrlenA(original);
        lres = RegSetValueExA(hroot, acceptlanguage, 0, REG_SZ, (const BYTE *) original, len ? len + 1: 0);
        ok(!lres, "RegSetValueEx(%s) failed: %d\n", original, lres);
    }
    else
    {
        RegDeleteValue(hroot, acceptlanguage);
    }
    RegCloseKey(hroot);
}

static void test_SHSearchMapInt(void)
{
  int keys[8], values[8];
  int i = 0;

  if (!pSHSearchMapInt)
    return;

  memset(keys, 0, sizeof(keys));
  memset(values, 0, sizeof(values));
  keys[0] = 99; values[0] = 101;

  /* NULL key/value lists crash native, so skip testing them */

  /* 1 element */
  i = pSHSearchMapInt(keys, values, 1, keys[0]);
  ok(i == values[0], "Len 1, expected %d, got %d\n", values[0], i);

  /* Key doesn't exist */
  i = pSHSearchMapInt(keys, values, 1, 100);
  ok(i == -1, "Len 1 - bad key, expected -1, got %d\n", i);

  /* Len = 0 => not found */
  i = pSHSearchMapInt(keys, values, 0, keys[0]);
  ok(i == -1, "Len 1 - passed len 0, expected -1, got %d\n", i);

  /* 2 elements, len = 1 */
  keys[1] = 98; values[1] = 102;
  i = pSHSearchMapInt(keys, values, 1, keys[1]);
  ok(i == -1, "Len 1 - array len 2, expected -1, got %d\n", i);

  /* 2 elements, len = 2 */
  i = pSHSearchMapInt(keys, values, 2, keys[1]);
  ok(i == values[1], "Len 2, expected %d, got %d\n", values[1], i);

  /* Searches forward */
  keys[2] = 99; values[2] = 103;
  i = pSHSearchMapInt(keys, values, 3, keys[0]);
  ok(i == values[0], "Len 3, expected %d, got %d\n", values[0], i);
}

static void test_alloc_shared(void)
{
    DWORD procid;
    HANDLE hmem;
    int val;
    int* p;
    BOOL ret;

    procid=GetCurrentProcessId();
    hmem=pSHAllocShared(NULL,10,procid);
    ok(hmem!=NULL,"SHAllocShared(NULL...) failed: %u\n", GetLastError());
    ret = pSHFreeShared(hmem, procid);
    ok( ret, "SHFreeShared failed: %u\n", GetLastError());

    val=0x12345678;
    hmem=pSHAllocShared(&val,4,procid);
    ok(hmem!=NULL,"SHAllocShared(NULL...) failed: %u\n", GetLastError());

    p=pSHLockShared(hmem,procid);
    ok(p!=NULL,"SHLockShared failed: %u\n", GetLastError());
    if (p!=NULL)
        ok(*p==val,"Wrong value in shared memory: %d instead of %d\n",*p,val);
    ret = pSHUnlockShared(p);
    ok( ret, "SHUnlockShared failed: %u\n", GetLastError());

    ret = pSHFreeShared(hmem, procid);
    ok( ret, "SHFreeShared failed: %u\n", GetLastError());
}

static void test_fdsa(void)
{
    typedef struct
    {
        DWORD num_items;       /* Number of elements inserted */
        void *mem;             /* Ptr to array */
        DWORD blocks_alloced;  /* Number of elements allocated */
        BYTE inc;              /* Number of elements to grow by when we need to expand */
        BYTE block_size;       /* Size in bytes of an element */
        BYTE flags;            /* Flags */
    } FDSA_info;

    BOOL (WINAPI *pFDSA_Initialize)(DWORD block_size, DWORD inc, FDSA_info *info, void *mem,
                                    DWORD init_blocks);
    BOOL (WINAPI *pFDSA_Destroy)(FDSA_info *info);
    DWORD (WINAPI *pFDSA_InsertItem)(FDSA_info *info, DWORD where, const void *block);
    BOOL (WINAPI *pFDSA_DeleteItem)(FDSA_info *info, DWORD where);

    FDSA_info info;
    int block_size = 10, init_blocks = 4, inc = 2;
    DWORD ret;
    char *mem;

    pFDSA_Initialize = (void *)GetProcAddress(hShlwapi, (LPSTR)208);
    pFDSA_Destroy    = (void *)GetProcAddress(hShlwapi, (LPSTR)209);
    pFDSA_InsertItem = (void *)GetProcAddress(hShlwapi, (LPSTR)210);
    pFDSA_DeleteItem = (void *)GetProcAddress(hShlwapi, (LPSTR)211);

    mem = HeapAlloc(GetProcessHeap(), 0, block_size * init_blocks);
    memset(&info, 0, sizeof(info));

    ok(pFDSA_Initialize(block_size, inc, &info, mem, init_blocks), "FDSA_Initialize rets FALSE\n");
    ok(info.num_items == 0, "num_items = %d\n", info.num_items);
    ok(info.mem == mem, "mem = %p\n", info.mem);
    ok(info.blocks_alloced == init_blocks, "blocks_alloced = %d\n", info.blocks_alloced);
    ok(info.inc == inc, "inc = %d\n", info.inc);
    ok(info.block_size == block_size, "block_size = %d\n", info.block_size);
    ok(info.flags == 0, "flags = %d\n", info.flags);

    ret = pFDSA_InsertItem(&info, 1234, "1234567890");
    ok(ret == 0, "ret = %d\n", ret);
    ok(info.num_items == 1, "num_items = %d\n", info.num_items);
    ok(info.mem == mem, "mem = %p\n", info.mem);
    ok(info.blocks_alloced == init_blocks, "blocks_alloced = %d\n", info.blocks_alloced);
    ok(info.inc == inc, "inc = %d\n", info.inc);
    ok(info.block_size == block_size, "block_size = %d\n", info.block_size);
    ok(info.flags == 0, "flags = %d\n", info.flags);

    ret = pFDSA_InsertItem(&info, 1234, "abcdefghij");
    ok(ret == 1, "ret = %d\n", ret);

    ret = pFDSA_InsertItem(&info, 1, "klmnopqrst");
    ok(ret == 1, "ret = %d\n", ret);

    ret = pFDSA_InsertItem(&info, 0, "uvwxyzABCD");
    ok(ret == 0, "ret = %d\n", ret);
    ok(info.mem == mem, "mem = %p\n", info.mem);
    ok(info.flags == 0, "flags = %d\n", info.flags);

    /* This next InsertItem will cause shlwapi to allocate its own mem buffer */
    ret = pFDSA_InsertItem(&info, 0, "EFGHIJKLMN");
    ok(ret == 0, "ret = %d\n", ret);
    ok(info.mem != mem, "mem = %p\n", info.mem);
    ok(info.blocks_alloced == init_blocks + inc, "blocks_alloced = %d\n", info.blocks_alloced);
    ok(info.flags == 0x1, "flags = %d\n", info.flags);

    ok(!memcmp(info.mem, "EFGHIJKLMNuvwxyzABCD1234567890klmnopqrstabcdefghij", 50), "mem %s\n", (char*)info.mem);

    ok(pFDSA_DeleteItem(&info, 2), "rets FALSE\n");
    ok(info.mem != mem, "mem = %p\n", info.mem);
    ok(info.blocks_alloced == init_blocks + inc, "blocks_alloced = %d\n", info.blocks_alloced);
    ok(info.flags == 0x1, "flags = %d\n", info.flags);

    ok(!memcmp(info.mem, "EFGHIJKLMNuvwxyzABCDklmnopqrstabcdefghij", 40), "mem %s\n", (char*)info.mem);

    ok(pFDSA_DeleteItem(&info, 3), "rets FALSE\n");
    ok(info.mem != mem, "mem = %p\n", info.mem);
    ok(info.blocks_alloced == init_blocks + inc, "blocks_alloced = %d\n", info.blocks_alloced);
    ok(info.flags == 0x1, "flags = %d\n", info.flags);

    ok(!memcmp(info.mem, "EFGHIJKLMNuvwxyzABCDklmnopqrst", 30), "mem %s\n", (char*)info.mem);

    ok(!pFDSA_DeleteItem(&info, 4), "does not ret FALSE\n");

    /* As shlwapi has allocated memory internally, Destroy will ret FALSE */
    ok(!pFDSA_Destroy(&info), "FDSA_Destroy does not ret FALSE\n");


    /* When Initialize is called with inc = 0, set it to 1 */
    ok(pFDSA_Initialize(block_size, 0, &info, mem, init_blocks), "FDSA_Initialize rets FALSE\n");
    ok(info.inc == 1, "inc = %d\n", info.inc);

    /* This time, because shlwapi hasn't had to allocate memory
       internally, Destroy rets non-zero */
    ok(pFDSA_Destroy(&info), "FDSA_Destroy rets FALSE\n");


    HeapFree(GetProcessHeap(), 0, mem);
}


typedef struct SHELL_USER_SID {
    SID_IDENTIFIER_AUTHORITY sidAuthority;
    DWORD                    dwUserGroupID;
    DWORD                    dwUserID;
} SHELL_USER_SID, *PSHELL_USER_SID;
typedef struct SHELL_USER_PERMISSION {
    SHELL_USER_SID susID;
    DWORD          dwAccessType;
    BOOL           fInherit;
    DWORD          dwAccessMask;
    DWORD          dwInheritMask;
    DWORD          dwInheritAccessMask;
} SHELL_USER_PERMISSION, *PSHELL_USER_PERMISSION;
static void test_GetShellSecurityDescriptor(void)
{
    SHELL_USER_PERMISSION supCurrentUserFull = {
        { {SECURITY_NULL_SID_AUTHORITY}, 0, 0 },
        ACCESS_ALLOWED_ACE_TYPE, FALSE,
        GENERIC_ALL, 0, 0 };
#define MY_INHERITANCE 0xBE /* invalid value to proof behavior */
    SHELL_USER_PERMISSION supEveryoneDenied = {
        { {SECURITY_WORLD_SID_AUTHORITY}, SECURITY_WORLD_RID, 0 },
        ACCESS_DENIED_ACE_TYPE, TRUE,
        GENERIC_WRITE, MY_INHERITANCE | 0xDEADBA00, GENERIC_READ };
    PSHELL_USER_PERMISSION rgsup[2] = {
        &supCurrentUserFull, &supEveryoneDenied,
    };
    SECURITY_DESCRIPTOR* psd;
    SECURITY_DESCRIPTOR* (WINAPI*pGetShellSecurityDescriptor)(PSHELL_USER_PERMISSION*,int);
    void *pChrCmpIW = GetProcAddress(hShlwapi, "ChrCmpIW");

    pGetShellSecurityDescriptor=(void*)GetProcAddress(hShlwapi,(char*)475);

    if(!pGetShellSecurityDescriptor)
    {
        win_skip("GetShellSecurityDescriptor not available\n");
        return;
    }

    if(pChrCmpIW && pChrCmpIW == pGetShellSecurityDescriptor) /* win2k */
    {
        win_skip("Skipping for GetShellSecurityDescriptor, same ordinal used for ChrCmpIW\n");
        return;
    }

    psd = pGetShellSecurityDescriptor(NULL, 2);
    ok(psd==NULL ||
       broken(psd==INVALID_HANDLE_VALUE), /* IE5 */
       "GetShellSecurityDescriptor should fail\n");
    psd = pGetShellSecurityDescriptor(rgsup, 0);
    ok(psd==NULL, "GetShellSecurityDescriptor should fail, got %p\n", psd);

    SetLastError(0xdeadbeef);
    psd = pGetShellSecurityDescriptor(rgsup, 2);
    if (psd == NULL && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
    {
        /* The previous calls to GetShellSecurityDescriptor don't set the last error */
        win_skip("GetShellSecurityDescriptor is not implemented\n");
        return;
    }
    if (psd == INVALID_HANDLE_VALUE)
    {
        win_skip("GetShellSecurityDescriptor is broken on IE5\n");
        return;
    }
    ok(psd!=NULL, "GetShellSecurityDescriptor failed\n");
    if (psd!=NULL)
    {
        BOOL bHasDacl = FALSE, bDefaulted, ret;
        PACL pAcl;
        DWORD dwRev;
        SECURITY_DESCRIPTOR_CONTROL control;

        ok(IsValidSecurityDescriptor(psd), "returned value is not valid SD\n");

        ret = GetSecurityDescriptorControl(psd, &control, &dwRev);
        ok(ret, "GetSecurityDescriptorControl failed with error %u\n", GetLastError());
        ok(0 == (control & SE_SELF_RELATIVE), "SD should be absolute\n");

        ret = GetSecurityDescriptorDacl(psd, &bHasDacl, &pAcl, &bDefaulted);
        ok(ret, "GetSecurityDescriptorDacl failed with error %u\n", GetLastError());

        ok(bHasDacl, "SD has no DACL\n");
        if (bHasDacl)
        {
            ok(!bDefaulted, "DACL should not be defaulted\n");

            ok(pAcl != NULL, "NULL DACL!\n");
            if (pAcl != NULL)
            {
                ACL_SIZE_INFORMATION asiSize;

                ok(IsValidAcl(pAcl), "DACL is not valid\n");

                ret = GetAclInformation(pAcl, &asiSize, sizeof(asiSize), AclSizeInformation);
                ok(ret, "GetAclInformation failed with error %u\n", GetLastError());

                ok(asiSize.AceCount == 3, "Incorrect number of ACEs: %d entries\n", asiSize.AceCount);
                if (asiSize.AceCount == 3)
                {
                    ACCESS_ALLOWED_ACE *paaa; /* will use for DENIED too */

                    ret = GetAce(pAcl, 0, (LPVOID*)&paaa);
                    ok(ret, "GetAce failed with error %u\n", GetLastError());
                    ok(paaa->Header.AceType == ACCESS_ALLOWED_ACE_TYPE, 
                            "Invalid ACE type %d\n", paaa->Header.AceType); 
                    ok(paaa->Header.AceFlags == 0, "Invalid ACE flags %x\n", paaa->Header.AceFlags);
                    ok(paaa->Mask == GENERIC_ALL, "Invalid ACE mask %x\n", paaa->Mask);

                    ret = GetAce(pAcl, 1, (LPVOID*)&paaa);
                    ok(ret, "GetAce failed with error %u\n", GetLastError());
                    ok(paaa->Header.AceType == ACCESS_DENIED_ACE_TYPE, 
                            "Invalid ACE type %d\n", paaa->Header.AceType); 
                    /* first one of two ACEs generated from inheritable entry - without inheritance */
                    ok(paaa->Header.AceFlags == 0, "Invalid ACE flags %x\n", paaa->Header.AceFlags);
                    ok(paaa->Mask == GENERIC_WRITE, "Invalid ACE mask %x\n", paaa->Mask);

                    ret = GetAce(pAcl, 2, (LPVOID*)&paaa);
                    ok(ret, "GetAce failed with error %u\n", GetLastError());
                    ok(paaa->Header.AceType == ACCESS_DENIED_ACE_TYPE, 
                            "Invalid ACE type %d\n", paaa->Header.AceType); 
                    /* second ACE - with inheritance */
                    ok(paaa->Header.AceFlags == MY_INHERITANCE,
                            "Invalid ACE flags %x\n", paaa->Header.AceFlags);
                    ok(paaa->Mask == GENERIC_READ, "Invalid ACE mask %x\n", paaa->Mask);
                }
            }
        }

        LocalFree(psd);
    }
}

static void test_SHPackDispParams(void)
{
    DISPPARAMS params;
    VARIANT vars[10];
    HRESULT hres;

    if(!pSHPackDispParams)
        win_skip("SHPackSidpParams not available\n");

    memset(&params, 0xc0, sizeof(params));
    memset(vars, 0xc0, sizeof(vars));
    hres = pSHPackDispParams(&params, vars, 1, VT_I4, 0xdeadbeef);
    ok(hres == S_OK, "SHPackDispParams failed: %08x\n", hres);
    ok(params.cArgs == 1, "params.cArgs = %d\n", params.cArgs);
    ok(params.cNamedArgs == 0, "params.cNamedArgs = %d\n", params.cArgs);
    ok(params.rgdispidNamedArgs == NULL, "params.rgdispidNamedArgs = %p\n", params.rgdispidNamedArgs);
    ok(params.rgvarg == vars, "params.rgvarg = %p\n", params.rgvarg);
    ok(V_VT(vars) == VT_I4, "V_VT(var) = %d\n", V_VT(vars));
    ok(V_I4(vars) == 0xdeadbeef, "failed %x\n", V_I4(vars));

    memset(&params, 0xc0, sizeof(params));
    hres = pSHPackDispParams(&params, NULL, 0, 0);
    ok(hres == S_OK, "SHPackDispParams failed: %08x\n", hres);
    ok(params.cArgs == 0, "params.cArgs = %d\n", params.cArgs);
    ok(params.cNamedArgs == 0, "params.cNamedArgs = %d\n", params.cArgs);
    ok(params.rgdispidNamedArgs == NULL, "params.rgdispidNamedArgs = %p\n", params.rgdispidNamedArgs);
    ok(params.rgvarg == NULL, "params.rgvarg = %p\n", params.rgvarg);

    memset(vars, 0xc0, sizeof(vars));
    memset(&params, 0xc0, sizeof(params));
    hres = pSHPackDispParams(&params, vars, 4, VT_BSTR, (void*)0xdeadbeef, VT_EMPTY, 10,
            VT_I4, 100, VT_DISPATCH, (void*)0xdeadbeef);
    ok(hres == S_OK, "SHPackDispParams failed: %08x\n", hres);
    ok(params.cArgs == 4, "params.cArgs = %d\n", params.cArgs);
    ok(params.cNamedArgs == 0, "params.cNamedArgs = %d\n", params.cArgs);
    ok(params.rgdispidNamedArgs == NULL, "params.rgdispidNamedArgs = %p\n", params.rgdispidNamedArgs);
    ok(params.rgvarg == vars, "params.rgvarg = %p\n", params.rgvarg);
    ok(V_VT(vars) == VT_DISPATCH, "V_VT(vars[0]) = %x\n", V_VT(vars));
    ok(V_I4(vars) == 0xdeadbeef, "V_I4(vars[0]) = %x\n", V_I4(vars));
    ok(V_VT(vars+1) == VT_I4, "V_VT(vars[1]) = %d\n", V_VT(vars+1));
    ok(V_I4(vars+1) == 100, "V_I4(vars[1]) = %x\n", V_I4(vars+1));
    ok(V_VT(vars+2) == VT_I4, "V_VT(vars[2]) = %d\n", V_VT(vars+2));
    ok(V_I4(vars+2) == 10, "V_I4(vars[2]) = %x\n", V_I4(vars+2));
    ok(V_VT(vars+3) == VT_BSTR, "V_VT(vars[3]) = %d\n", V_VT(vars+3));
    ok(V_BSTR(vars+3) == (void*)0xdeadbeef, "V_BSTR(vars[3]) = %p\n", V_BSTR(vars+3));
}

typedef struct _disp
{
    IDispatch IDispatch_iface;
    LONG   refCount;
} Disp;

static inline Disp *impl_from_IDispatch(IDispatch *iface)
{
    return CONTAINING_RECORD(iface, Disp, IDispatch_iface);
}

typedef struct _contain
{
    IConnectionPointContainer IConnectionPointContainer_iface;
    LONG   refCount;

    UINT  ptCount;
    IConnectionPoint **pt;
} Contain;

static inline Contain *impl_from_IConnectionPointContainer(IConnectionPointContainer *iface)
{
    return CONTAINING_RECORD(iface, Contain, IConnectionPointContainer_iface);
}

typedef struct _cntptn
{
    IConnectionPoint IConnectionPoint_iface;
    LONG refCount;

    Contain *container;
    GUID  id;
    UINT  sinkCount;
    IUnknown **sink;
} ConPt;

static inline ConPt *impl_from_IConnectionPoint(IConnectionPoint *iface)
{
    return CONTAINING_RECORD(iface, ConPt, IConnectionPoint_iface);
}

typedef struct _enum
{
    IEnumConnections IEnumConnections_iface;
    LONG   refCount;

    UINT idx;
    ConPt *pt;
} EnumCon;

static inline EnumCon *impl_from_IEnumConnections(IEnumConnections *iface)
{
    return CONTAINING_RECORD(iface, EnumCon, IEnumConnections_iface);
}

typedef struct _enumpt
{
    IEnumConnectionPoints IEnumConnectionPoints_iface;
    LONG   refCount;

    int idx;
    Contain *container;
} EnumPt;

static inline EnumPt *impl_from_IEnumConnectionPoints(IEnumConnectionPoints *iface)
{
    return CONTAINING_RECORD(iface, EnumPt, IEnumConnectionPoints_iface);
}


static HRESULT WINAPI Disp_QueryInterface(
        IDispatch* This,
        REFIID riid,
        void **ppvObject)
{
    *ppvObject = NULL;

    if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDispatch))
    {
        *ppvObject = This;
    }

    if (*ppvObject)
    {
        IUnknown_AddRef(This);
        return S_OK;
    }

    trace("no interface\n");
    return E_NOINTERFACE;
}

static ULONG WINAPI Disp_AddRef(IDispatch* This)
{
    Disp *iface = impl_from_IDispatch(This);
    return InterlockedIncrement(&iface->refCount);
}

static ULONG WINAPI Disp_Release(IDispatch* This)
{
    Disp *iface = impl_from_IDispatch(This);
    ULONG ret;

    ret = InterlockedDecrement(&iface->refCount);
    if (ret == 0)
        HeapFree(GetProcessHeap(),0,This);
    return ret;
}

static HRESULT WINAPI Disp_GetTypeInfoCount(
        IDispatch* This,
        UINT *pctinfo)
{
    return ERROR_SUCCESS;
}

static HRESULT WINAPI Disp_GetTypeInfo(
        IDispatch* This,
        UINT iTInfo,
        LCID lcid,
        ITypeInfo **ppTInfo)
{
    return ERROR_SUCCESS;
}

static HRESULT WINAPI Disp_GetIDsOfNames(
        IDispatch* This,
        REFIID riid,
        LPOLESTR *rgszNames,
        UINT cNames,
        LCID lcid,
        DISPID *rgDispId)
{
    return ERROR_SUCCESS;
}

static HRESULT WINAPI Disp_Invoke(
        IDispatch* This,
        DISPID dispIdMember,
        REFIID riid,
        LCID lcid,
        WORD wFlags,
        DISPPARAMS *pDispParams,
        VARIANT *pVarResult,
        EXCEPINFO *pExcepInfo,
        UINT *puArgErr)
{
    trace("%p %x %p %x %x %p %p %p %p\n",This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr);

    ok(dispIdMember == 0xa0 || dispIdMember == 0xa1, "Unknown dispIdMember\n");
    ok(pDispParams != NULL, "Invoked with NULL pDispParams\n");
    ok(wFlags == DISPATCH_METHOD, "Wrong flags %x\n",wFlags);
    ok(lcid == 0,"Wrong lcid %x\n",lcid);
    if (dispIdMember == 0xa0)
    {
        ok(pDispParams->cArgs == 0, "params.cArgs = %d\n", pDispParams->cArgs);
        ok(pDispParams->cNamedArgs == 0, "params.cNamedArgs = %d\n", pDispParams->cArgs);
        ok(pDispParams->rgdispidNamedArgs == NULL, "params.rgdispidNamedArgs = %p\n", pDispParams->rgdispidNamedArgs);
        ok(pDispParams->rgvarg == NULL, "params.rgvarg = %p\n", pDispParams->rgvarg);
    }
    else if (dispIdMember == 0xa1)
    {
        ok(pDispParams->cArgs == 2, "params.cArgs = %d\n", pDispParams->cArgs);
        ok(pDispParams->cNamedArgs == 0, "params.cNamedArgs = %d\n", pDispParams->cArgs);
        ok(pDispParams->rgdispidNamedArgs == NULL, "params.rgdispidNamedArgs = %p\n", pDispParams->rgdispidNamedArgs);
        ok(V_VT(pDispParams->rgvarg) == VT_BSTR, "V_VT(var) = %d\n", V_VT(pDispParams->rgvarg));
        ok(V_I4(pDispParams->rgvarg) == 0xdeadcafe , "failed %p\n", V_BSTR(pDispParams->rgvarg));
        ok(V_VT(pDispParams->rgvarg+1) == VT_I4, "V_VT(var) = %d\n", V_VT(pDispParams->rgvarg+1));
        ok(V_I4(pDispParams->rgvarg+1) == 0xdeadbeef, "failed %x\n", V_I4(pDispParams->rgvarg+1));
    }

    return ERROR_SUCCESS;
}

static const IDispatchVtbl disp_vtbl = {
    Disp_QueryInterface,
    Disp_AddRef,
    Disp_Release,

    Disp_GetTypeInfoCount,
    Disp_GetTypeInfo,
    Disp_GetIDsOfNames,
    Disp_Invoke
};

static HRESULT WINAPI Enum_QueryInterface(
        IEnumConnections* This,
        REFIID riid,
        void **ppvObject)
{
    *ppvObject = NULL;

    if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IEnumConnections))
    {
        *ppvObject = This;
    }

    if (*ppvObject)
    {
        IUnknown_AddRef(This);
        return S_OK;
    }

    trace("no interface\n");
    return E_NOINTERFACE;
}

static ULONG WINAPI Enum_AddRef(IEnumConnections* This)
{
    EnumCon *iface = impl_from_IEnumConnections(This);
    return InterlockedIncrement(&iface->refCount);
}

static ULONG WINAPI Enum_Release(IEnumConnections* This)
{
    EnumCon *iface = impl_from_IEnumConnections(This);
    ULONG ret;

    ret = InterlockedDecrement(&iface->refCount);
    if (ret == 0)
        HeapFree(GetProcessHeap(),0,This);
    return ret;
}

static HRESULT WINAPI Enum_Next(
        IEnumConnections* This,
        ULONG cConnections,
        LPCONNECTDATA rgcd,
        ULONG *pcFetched)
{
    EnumCon *iface = impl_from_IEnumConnections(This);

    if (cConnections > 0 && iface->idx < iface->pt->sinkCount)
    {
        rgcd->pUnk = iface->pt->sink[iface->idx];
        IUnknown_AddRef(iface->pt->sink[iface->idx]);
        rgcd->dwCookie=0xff;
        if (pcFetched)
            *pcFetched = 1;
        iface->idx++;
        return S_OK;
    }

    return E_FAIL;
}

static HRESULT WINAPI Enum_Skip(
        IEnumConnections* This,
        ULONG cConnections)
{
    return E_FAIL;
}

static HRESULT WINAPI Enum_Reset(
        IEnumConnections* This)
{
    return E_FAIL;
}

static HRESULT WINAPI Enum_Clone(
        IEnumConnections* This,
        IEnumConnections **ppEnum)
{
    return E_FAIL;
}

static const IEnumConnectionsVtbl enum_vtbl = {

    Enum_QueryInterface,
    Enum_AddRef,
    Enum_Release,
    Enum_Next,
    Enum_Skip,
    Enum_Reset,
    Enum_Clone
};

static HRESULT WINAPI ConPt_QueryInterface(
        IConnectionPoint* This,
        REFIID riid,
        void **ppvObject)
{
    *ppvObject = NULL;

    if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IConnectionPoint))
    {
        *ppvObject = This;
    }

    if (*ppvObject)
    {
        IUnknown_AddRef(This);
        return S_OK;
    }

    trace("no interface\n");
    return E_NOINTERFACE;
}

static ULONG WINAPI ConPt_AddRef(
        IConnectionPoint* This)
{
    ConPt *iface = impl_from_IConnectionPoint(This);
    return InterlockedIncrement(&iface->refCount);
}

static ULONG WINAPI ConPt_Release(
        IConnectionPoint* This)
{
    ConPt *iface = impl_from_IConnectionPoint(This);
    ULONG ret;

    ret = InterlockedDecrement(&iface->refCount);
    if (ret == 0)
    {
        if (iface->sinkCount > 0)
        {
            int i;
            for (i = 0; i < iface->sinkCount; i++)
            {
                if (iface->sink[i])
                    IUnknown_Release(iface->sink[i]);
            }
            HeapFree(GetProcessHeap(),0,iface->sink);
        }
        HeapFree(GetProcessHeap(),0,This);
    }
    return ret;
}

static HRESULT WINAPI ConPt_GetConnectionInterface(
        IConnectionPoint* This,
        IID *pIID)
{
    static int i = 0;
    ConPt *iface = impl_from_IConnectionPoint(This);
    if (i==0)
    {
        i++;
        return E_FAIL;
    }
    else
        memcpy(pIID,&iface->id,sizeof(GUID));
    return S_OK;
}

static HRESULT WINAPI ConPt_GetConnectionPointContainer(
        IConnectionPoint* This,
        IConnectionPointContainer **ppCPC)
{
    ConPt *iface = impl_from_IConnectionPoint(This);

    *ppCPC = &iface->container->IConnectionPointContainer_iface;
    return S_OK;
}

static HRESULT WINAPI ConPt_Advise(
        IConnectionPoint* This,
        IUnknown *pUnkSink,
        DWORD *pdwCookie)
{
    ConPt *iface = impl_from_IConnectionPoint(This);

    if (iface->sinkCount == 0)
        iface->sink = HeapAlloc(GetProcessHeap(),0,sizeof(IUnknown*));
    else
        iface->sink = HeapReAlloc(GetProcessHeap(),0,iface->sink,sizeof(IUnknown*)*(iface->sinkCount+1));
    iface->sink[iface->sinkCount] = pUnkSink;
    IUnknown_AddRef(pUnkSink);
    iface->sinkCount++;
    *pdwCookie = iface->sinkCount;
    return S_OK;
}

static HRESULT WINAPI ConPt_Unadvise(
        IConnectionPoint* This,
        DWORD dwCookie)
{
    ConPt *iface = impl_from_IConnectionPoint(This);

    if (dwCookie > iface->sinkCount)
        return E_FAIL;
    else
    {
        IUnknown_Release(iface->sink[dwCookie-1]);
        iface->sink[dwCookie-1] = NULL;
    }
    return S_OK;
}

static HRESULT WINAPI ConPt_EnumConnections(
        IConnectionPoint* This,
        IEnumConnections **ppEnum)
{
    EnumCon *ec;

    ec = HeapAlloc(GetProcessHeap(),0,sizeof(EnumCon));
    ec->IEnumConnections_iface.lpVtbl = &enum_vtbl;
    ec->refCount = 1;
    ec->pt = impl_from_IConnectionPoint(This);
    ec->idx = 0;
    *ppEnum = &ec->IEnumConnections_iface;

    return S_OK;
}

static const IConnectionPointVtbl point_vtbl = {
    ConPt_QueryInterface,
    ConPt_AddRef,
    ConPt_Release,

    ConPt_GetConnectionInterface,
    ConPt_GetConnectionPointContainer,
    ConPt_Advise,
    ConPt_Unadvise,
    ConPt_EnumConnections
};

static HRESULT WINAPI EnumPt_QueryInterface(
        IEnumConnectionPoints* This,
        REFIID riid,
        void **ppvObject)
{
    *ppvObject = NULL;

    if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IEnumConnectionPoints))
    {
        *ppvObject = This;
    }

    if (*ppvObject)
    {
        IUnknown_AddRef(This);
        return S_OK;
    }

    trace("no interface\n");
    return E_NOINTERFACE;
}

static ULONG WINAPI EnumPt_AddRef(IEnumConnectionPoints* This)
{
    EnumPt *iface = impl_from_IEnumConnectionPoints(This);
    return InterlockedIncrement(&iface->refCount);
}

static ULONG WINAPI EnumPt_Release(IEnumConnectionPoints* This)
{
    EnumPt *iface = impl_from_IEnumConnectionPoints(This);
    ULONG ret;

    ret = InterlockedDecrement(&iface->refCount);
    if (ret == 0)
        HeapFree(GetProcessHeap(),0,This);
    return ret;
}

static HRESULT WINAPI EnumPt_Next(
        IEnumConnectionPoints* This,
        ULONG cConnections,
        IConnectionPoint **rgcd,
        ULONG *pcFetched)
{
    EnumPt *iface = impl_from_IEnumConnectionPoints(This);

    if (cConnections > 0 && iface->idx < iface->container->ptCount)
    {
        *rgcd = iface->container->pt[iface->idx];
        IUnknown_AddRef(iface->container->pt[iface->idx]);
        if (pcFetched)
            *pcFetched = 1;
        iface->idx++;
        return S_OK;
    }

    return E_FAIL;
}

static HRESULT WINAPI EnumPt_Skip(
        IEnumConnectionPoints* This,
        ULONG cConnections)
{
    return E_FAIL;
}

static HRESULT WINAPI EnumPt_Reset(
        IEnumConnectionPoints* This)
{
    return E_FAIL;
}

static HRESULT WINAPI EnumPt_Clone(
        IEnumConnectionPoints* This,
        IEnumConnectionPoints **ppEnumPt)
{
    return E_FAIL;
}

static const IEnumConnectionPointsVtbl enumpt_vtbl = {

    EnumPt_QueryInterface,
    EnumPt_AddRef,
    EnumPt_Release,
    EnumPt_Next,
    EnumPt_Skip,
    EnumPt_Reset,
    EnumPt_Clone
};

static HRESULT WINAPI Contain_QueryInterface(
        IConnectionPointContainer* This,
        REFIID riid,
        void **ppvObject)
{
    *ppvObject = NULL;

    if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IConnectionPointContainer))
    {
        *ppvObject = This;
    }

    if (*ppvObject)
    {
        IUnknown_AddRef(This);
        return S_OK;
    }

    trace("no interface\n");
    return E_NOINTERFACE;
}

static ULONG WINAPI Contain_AddRef(
        IConnectionPointContainer* This)
{
    Contain *iface = impl_from_IConnectionPointContainer(This);
    return InterlockedIncrement(&iface->refCount);
}

static ULONG WINAPI Contain_Release(
        IConnectionPointContainer* This)
{
    Contain *iface = impl_from_IConnectionPointContainer(This);
    ULONG ret;

    ret = InterlockedDecrement(&iface->refCount);
    if (ret == 0)
    {
        if (iface->ptCount > 0)
        {
            int i;
            for (i = 0; i < iface->ptCount; i++)
                IUnknown_Release(iface->pt[i]);
            HeapFree(GetProcessHeap(),0,iface->pt);
        }
        HeapFree(GetProcessHeap(),0,This);
    }
    return ret;
}

static HRESULT WINAPI Contain_EnumConnectionPoints(
        IConnectionPointContainer* This,
        IEnumConnectionPoints **ppEnum)
{
    EnumPt *ec;

    ec = HeapAlloc(GetProcessHeap(),0,sizeof(EnumPt));
    ec->IEnumConnectionPoints_iface.lpVtbl = &enumpt_vtbl;
    ec->refCount = 1;
    ec->idx= 0;
    ec->container = impl_from_IConnectionPointContainer(This);
    *ppEnum = &ec->IEnumConnectionPoints_iface;

    return S_OK;
}

static HRESULT WINAPI Contain_FindConnectionPoint(
        IConnectionPointContainer* This,
        REFIID riid,
        IConnectionPoint **ppCP)
{
    Contain *iface = impl_from_IConnectionPointContainer(This);
    ConPt *pt;

    if (!IsEqualIID(riid, &IID_NULL) || iface->ptCount ==0)
    {
        pt = HeapAlloc(GetProcessHeap(),0,sizeof(ConPt));
        pt->IConnectionPoint_iface.lpVtbl = &point_vtbl;
        pt->refCount = 1;
        pt->sinkCount = 0;
        pt->sink = NULL;
        pt->container = iface;
        pt->id = IID_IDispatch;

        if (iface->ptCount == 0)
            iface->pt =HeapAlloc(GetProcessHeap(),0,sizeof(IUnknown*));
        else
            iface->pt = HeapReAlloc(GetProcessHeap(),0,iface->pt,sizeof(IUnknown*)*(iface->ptCount+1));
        iface->pt[iface->ptCount] = &pt->IConnectionPoint_iface;
        iface->ptCount++;

        *ppCP = &pt->IConnectionPoint_iface;
    }
    else
    {
        *ppCP = iface->pt[0];
        IUnknown_AddRef((IUnknown*)*ppCP);
    }

    return S_OK;
}

static const IConnectionPointContainerVtbl contain_vtbl = {
    Contain_QueryInterface,
    Contain_AddRef,
    Contain_Release,

    Contain_EnumConnectionPoints,
    Contain_FindConnectionPoint
};

static void test_IConnectionPoint(void)
{
    HRESULT rc;
    ULONG ref;
    IConnectionPoint *point;
    Contain *container;
    Disp *dispatch;
    DWORD cookie = 0xffffffff;
    DISPPARAMS params;
    VARIANT vars[10];

    if (!pIConnectionPoint_SimpleInvoke || !pConnectToConnectionPoint)
    {
        win_skip("IConnectionPoint Apis not present\n");
        return;
    }

    container = HeapAlloc(GetProcessHeap(),0,sizeof(Contain));
    container->IConnectionPointContainer_iface.lpVtbl = &contain_vtbl;
    container->refCount = 1;
    container->ptCount = 0;
    container->pt = NULL;

    dispatch = HeapAlloc(GetProcessHeap(),0,sizeof(Disp));
    dispatch->IDispatch_iface.lpVtbl = &disp_vtbl;
    dispatch->refCount = 1;

    rc = pConnectToConnectionPoint((IUnknown*)dispatch, &IID_NULL, TRUE, (IUnknown*)container, &cookie, &point);
    ok(rc == S_OK, "pConnectToConnectionPoint failed with %x\n",rc);
    ok(point != NULL, "returned ConnectionPoint is NULL\n");
    ok(cookie != 0xffffffff, "invalid cookie returned\n");

    rc = pIConnectionPoint_SimpleInvoke(point,0xa0,NULL);
    ok(rc == S_OK, "pConnectToConnectionPoint failed with %x\n",rc);

    if (pSHPackDispParams)
    {
        memset(&params, 0xc0, sizeof(params));
        memset(vars, 0xc0, sizeof(vars));
        rc = pSHPackDispParams(&params, vars, 2, VT_I4, 0xdeadbeef, VT_BSTR, 0xdeadcafe);
        ok(rc == S_OK, "SHPackDispParams failed: %08x\n", rc);

        rc = pIConnectionPoint_SimpleInvoke(point,0xa1,&params);
        ok(rc == S_OK, "pConnectToConnectionPoint failed with %x\n",rc);
    }
    else
        win_skip("pSHPackDispParams not present\n");

    rc = pConnectToConnectionPoint(NULL, &IID_NULL, FALSE, (IUnknown*)container, &cookie, NULL);
    ok(rc == S_OK, "pConnectToConnectionPoint failed with %x\n",rc);

/* MSDN says this should be required but it crashs on XP
    IUnknown_Release(point);
*/
    ref = IUnknown_Release((IUnknown*)container);
    ok(ref == 0, "leftover IConnectionPointContainer reference %i\n",ref);
    ref = IUnknown_Release((IUnknown*)dispatch);
    ok(ref == 0, "leftover IDispatch reference %i\n",ref);
}

typedef struct _propbag
{
    IPropertyBag IPropertyBag_iface;
    LONG   refCount;

} PropBag;

static inline PropBag *impl_from_IPropertyBag(IPropertyBag *iface)
{
    return CONTAINING_RECORD(iface, PropBag, IPropertyBag_iface);
}


static HRESULT WINAPI Prop_QueryInterface(
        IPropertyBag* This,
        REFIID riid,
        void **ppvObject)
{
    *ppvObject = NULL;

    if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IPropertyBag))
    {
        *ppvObject = This;
    }

    if (*ppvObject)
    {
        IUnknown_AddRef(This);
        return S_OK;
    }

    trace("no interface\n");
    return E_NOINTERFACE;
}

static ULONG WINAPI Prop_AddRef(
        IPropertyBag* This)
{
    PropBag *iface = impl_from_IPropertyBag(This);
    return InterlockedIncrement(&iface->refCount);
}

static ULONG WINAPI Prop_Release(
        IPropertyBag* This)
{
    PropBag *iface = impl_from_IPropertyBag(This);
    ULONG ret;

    ret = InterlockedDecrement(&iface->refCount);
    if (ret == 0)
        HeapFree(GetProcessHeap(),0,This);
    return ret;
}

static HRESULT WINAPI Prop_Read(
        IPropertyBag* This,
        LPCOLESTR pszPropName,
        VARIANT *pVar,
        IErrorLog *pErrorLog)
{
    V_VT(pVar) = VT_BLOB|VT_BYREF;
    V_BYREF(pVar) = (LPVOID)0xdeadcafe;
    return S_OK;
}

static HRESULT WINAPI Prop_Write(
        IPropertyBag* This,
        LPCOLESTR pszPropName,
        VARIANT *pVar)
{
    return S_OK;
}


static const IPropertyBagVtbl prop_vtbl = {
    Prop_QueryInterface,
    Prop_AddRef,
    Prop_Release,

    Prop_Read,
    Prop_Write
};

static void test_SHPropertyBag_ReadLONG(void)
{
    PropBag *pb;
    HRESULT rc;
    LONG out;
    static const WCHAR szName1[] = {'n','a','m','e','1',0};

    if (!pSHPropertyBag_ReadLONG)
    {
        win_skip("SHPropertyBag_ReadLONG not present\n");
        return;
    }

    pb = HeapAlloc(GetProcessHeap(),0,sizeof(PropBag));
    pb->refCount = 1;
    pb->IPropertyBag_iface.lpVtbl = &prop_vtbl;

    out = 0xfeedface;
    rc = pSHPropertyBag_ReadLONG(NULL, szName1, &out);
    ok(rc == E_INVALIDARG || broken(rc == 0), "incorrect return %x\n",rc);
    ok(out == 0xfeedface, "value should not have changed\n");
    rc = pSHPropertyBag_ReadLONG(&pb->IPropertyBag_iface, NULL, &out);
    ok(rc == E_INVALIDARG || broken(rc == 0) || broken(rc == 1), "incorrect return %x\n",rc);
    ok(out == 0xfeedface, "value should not have changed\n");
    rc = pSHPropertyBag_ReadLONG(&pb->IPropertyBag_iface, szName1, NULL);
    ok(rc == E_INVALIDARG || broken(rc == 0) || broken(rc == 1), "incorrect return %x\n",rc);
    ok(out == 0xfeedface, "value should not have changed\n");
    rc = pSHPropertyBag_ReadLONG(&pb->IPropertyBag_iface, szName1, &out);
    ok(rc == DISP_E_BADVARTYPE || broken(rc == 0) || broken(rc == 1), "incorrect return %x\n",rc);
    ok(out == 0xfeedface  || broken(out == 0xfeedfa00), "value should not have changed %x\n",out);
    IUnknown_Release((IUnknown*)pb);
}



static void test_SHSetWindowBits(void)
{
    HWND hwnd;
    DWORD style, styleold;
    WNDCLASSA clsA;

    if(!pSHSetWindowBits)
    {
        win_skip("SHSetWindowBits is not available\n");
        return;
    }

    clsA.style = 0;
    clsA.lpfnWndProc = DefWindowProcA;
    clsA.cbClsExtra = 0;
    clsA.cbWndExtra = 0;
    clsA.hInstance = GetModuleHandleA(NULL);
    clsA.hIcon = 0;
    clsA.hCursor = LoadCursorA(0, IDC_ARROW);
    clsA.hbrBackground = NULL;
    clsA.lpszMenuName = NULL;
    clsA.lpszClassName = "Shlwapi test class";
    RegisterClassA(&clsA);

    hwnd = CreateWindowA("Shlwapi test class", "Test", WS_VISIBLE, 0, 0, 100, 100,
                          NULL, NULL, GetModuleHandle(NULL), 0);
    ok(IsWindow(hwnd), "failed to create window\n");

    /* null window */
    SetLastError(0xdeadbeef);
    style = pSHSetWindowBits(NULL, GWL_STYLE, 0, 0);
    ok(style == 0, "expected 0 retval, got %d\n", style);
    ok(GetLastError() == ERROR_INVALID_WINDOW_HANDLE ||
        broken(GetLastError() == 0xdeadbeef), /* Win9x/WinMe */
        "expected ERROR_INVALID_WINDOW_HANDLE, got %d\n", GetLastError());

    /* zero mask, zero flags */
    styleold = GetWindowLongA(hwnd, GWL_STYLE);
    style = pSHSetWindowBits(hwnd, GWL_STYLE, 0, 0);
    ok(styleold == style, "expected old style\n");
    ok(styleold == GetWindowLongA(hwnd, GWL_STYLE), "expected to keep old style\n");

    /* test mask */
    styleold = GetWindowLongA(hwnd, GWL_STYLE);
    ok(styleold & WS_VISIBLE, "expected WS_VISIBLE\n");
    style = pSHSetWindowBits(hwnd, GWL_STYLE, WS_VISIBLE, 0);

    ok(style == styleold, "expected previous style, got %x\n", style);
    ok((GetWindowLongA(hwnd, GWL_STYLE) & WS_VISIBLE) == 0, "expected updated style\n");

    /* test mask, unset style bit used */
    styleold = GetWindowLongA(hwnd, GWL_STYLE);
    style = pSHSetWindowBits(hwnd, GWL_STYLE, WS_VISIBLE, 0);
    ok(style == styleold, "expected previous style, got %x\n", style);
    ok(styleold == GetWindowLongA(hwnd, GWL_STYLE), "expected to keep old style\n");

    /* set back with flags */
    styleold = GetWindowLongA(hwnd, GWL_STYLE);
    style = pSHSetWindowBits(hwnd, GWL_STYLE, WS_VISIBLE, WS_VISIBLE);
    ok(style == styleold, "expected previous style, got %x\n", style);
    ok(GetWindowLongA(hwnd, GWL_STYLE) & WS_VISIBLE, "expected updated style\n");

    /* reset and try to set without a mask */
    pSHSetWindowBits(hwnd, GWL_STYLE, WS_VISIBLE, 0);
    ok((GetWindowLongA(hwnd, GWL_STYLE) & WS_VISIBLE) == 0, "expected updated style\n");
    styleold = GetWindowLongA(hwnd, GWL_STYLE);
    style = pSHSetWindowBits(hwnd, GWL_STYLE, 0, WS_VISIBLE);
    ok(style == styleold, "expected previous style, got %x\n", style);
    ok((GetWindowLongA(hwnd, GWL_STYLE) & WS_VISIBLE) == 0, "expected updated style\n");

    DestroyWindow(hwnd);

    UnregisterClassA("Shlwapi test class", GetModuleHandleA(NULL));
}

static void test_SHFormatDateTimeA(void)
{
    FILETIME UNALIGNED filetime;
    CHAR buff[100], buff2[100], buff3[100];
    SYSTEMTIME st;
    DWORD flags;
    INT ret;

    if(!pSHFormatDateTimeA)
    {
        win_skip("pSHFormatDateTimeA isn't available\n");
        return;
    }

if (0)
{
    /* crashes on native */
    pSHFormatDateTimeA(NULL, NULL, NULL, 0);
}

    GetLocalTime(&st);
    SystemTimeToFileTime(&st, &filetime);
    /* SHFormatDateTime expects input as utc */
    LocalFileTimeToFileTime(&filetime, &filetime);

    /* no way to get required buffer length here */
    SetLastError(0xdeadbeef);
    ret = pSHFormatDateTimeA(&filetime, NULL, NULL, 0);
    ok(ret == 0, "got %d\n", ret);
    ok(GetLastError() == 0xdeadbeef || broken(GetLastError() == ERROR_SUCCESS /* Win7 */),
        "expected 0xdeadbeef, got %d\n", GetLastError());

    SetLastError(0xdeadbeef);
    buff[0] = 'a'; buff[1] = 0;
    ret = pSHFormatDateTimeA(&filetime, NULL, buff, 0);
    ok(ret == 0, "got %d\n", ret);
    ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
    ok(buff[0] == 'a', "expected same string, got %s\n", buff);

    /* flags needs to have FDTF_NOAUTOREADINGORDER for these tests to succeed on Vista+ */

    /* all combinations documented as invalid succeeded */
    flags = FDTF_NOAUTOREADINGORDER | FDTF_SHORTTIME | FDTF_LONGTIME;
    SetLastError(0xdeadbeef);
    ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff));
    ok(ret == lstrlenA(buff)+1, "got %d\n", ret);
    ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());

    flags = FDTF_NOAUTOREADINGORDER | FDTF_SHORTDATE | FDTF_LONGDATE;
    SetLastError(0xdeadbeef);
    ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff));
    ok(ret == lstrlenA(buff)+1, "got %d\n", ret);
    ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());

    flags =  FDTF_SHORTDATE | FDTF_LTRDATE | FDTF_RTLDATE;
    SetLastError(0xdeadbeef);
    ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff));
    ok(ret == lstrlenA(buff)+1, "got %d\n", ret);
    ok(GetLastError() == 0xdeadbeef ||
        broken(GetLastError() == ERROR_INVALID_FLAGS), /* Win9x/WinMe */
        "expected 0xdeadbeef, got %d\n", GetLastError());

    /* now check returned strings */
    flags = FDTF_NOAUTOREADINGORDER | FDTF_SHORTTIME;
    ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff));
    ok(ret == lstrlenA(buff)+1, "got %d\n", ret);
    ret = GetTimeFormat(LOCALE_USER_DEFAULT, TIME_NOSECONDS, &st, NULL, buff2, sizeof(buff2));
    ok(ret == lstrlenA(buff2)+1, "got %d\n", ret);
    ok(lstrcmpA(buff, buff2) == 0, "expected (%s), got (%s)\n", buff2, buff);

    flags = FDTF_NOAUTOREADINGORDER | FDTF_LONGTIME;
    ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff));
    ok(ret == lstrlenA(buff)+1, "got %d\n", ret);
    ret = GetTimeFormat(LOCALE_USER_DEFAULT, 0, &st, NULL, buff2, sizeof(buff2));
    ok(ret == lstrlenA(buff2)+1, "got %d\n", ret);
    ok(lstrcmpA(buff, buff2) == 0, "expected (%s), got (%s)\n", buff2, buff);

    /* both time flags */
    flags = FDTF_NOAUTOREADINGORDER | FDTF_LONGTIME | FDTF_SHORTTIME;
    ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff));
    ok(ret == lstrlenA(buff)+1, "got %d\n", ret);
    ret = GetTimeFormat(LOCALE_USER_DEFAULT, 0, &st, NULL, buff2, sizeof(buff2));
    ok(ret == lstrlenA(buff2)+1, "got %d\n", ret);
    ok(lstrcmpA(buff, buff2) == 0, "expected (%s), got (%s)\n", buff2, buff);

    flags = FDTF_NOAUTOREADINGORDER | FDTF_SHORTDATE;
    ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff));
    ok(ret == lstrlenA(buff)+1, "got %d\n", ret);
    ret = GetDateFormat(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &st, NULL, buff2, sizeof(buff2));
    ok(ret == lstrlenA(buff2)+1, "got %d\n", ret);
    ok(lstrcmpA(buff, buff2) == 0, "expected (%s), got (%s)\n", buff2, buff);

    flags = FDTF_NOAUTOREADINGORDER | FDTF_LONGDATE;
    ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff));
    ok(ret == lstrlenA(buff)+1, "got %d\n", ret);
    ret = GetDateFormat(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL, buff2, sizeof(buff2));
    ok(ret == lstrlenA(buff2)+1, "got %d\n", ret);
    ok(lstrcmpA(buff, buff2) == 0, "expected (%s), got (%s)\n", buff2, buff);

    /* both date flags */
    flags = FDTF_NOAUTOREADINGORDER | FDTF_LONGDATE | FDTF_SHORTDATE;
    ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff));
    ok(ret == lstrlenA(buff)+1, "got %d\n", ret);
    ret = GetDateFormat(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL, buff2, sizeof(buff2));
    ok(ret == lstrlenA(buff2)+1, "got %d\n", ret);
    ok(lstrcmpA(buff, buff2) == 0, "expected (%s), got (%s)\n", buff2, buff);

    /* various combinations of date/time flags */
    flags = FDTF_NOAUTOREADINGORDER | FDTF_LONGDATE | FDTF_SHORTTIME;
    ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff));
    ok(ret == lstrlenA(buff)+1, "got %d, length %d\n", ret, lstrlenA(buff)+1);
    ret = GetTimeFormat(LOCALE_USER_DEFAULT, TIME_NOSECONDS, &st, NULL, buff3, sizeof(buff3));
    ok(ret == lstrlenA(buff3)+1, "got %d\n", ret);
    ok(lstrcmpA(buff3, buff + lstrlenA(buff) - lstrlenA(buff3)) == 0,
       "expected (%s), got (%s) for time part\n",
       buff3, buff + lstrlenA(buff) - lstrlenA(buff3));
    ret = GetDateFormat(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL, buff2, sizeof(buff2));
    ok(ret == lstrlenA(buff2)+1, "got %d\n", ret);
    buff[lstrlenA(buff2)] = '\0';
    ok(lstrcmpA(buff2, buff) == 0, "expected (%s) got (%s) for date part\n",
       buff2, buff);

    flags = FDTF_NOAUTOREADINGORDER | FDTF_LONGDATE | FDTF_LONGTIME;
    ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff));
    ok(ret == lstrlenA(buff)+1, "got %d\n", ret);
    ret = GetTimeFormat(LOCALE_USER_DEFAULT, 0, &st, NULL, buff3, sizeof(buff3));
    ok(ret == lstrlenA(buff3)+1, "got %d\n", ret);
    ok(lstrcmpA(buff3, buff + lstrlenA(buff) - lstrlenA(buff3)) == 0,
       "expected (%s), got (%s) for time part\n",
       buff3, buff + lstrlenA(buff) - lstrlenA(buff3));
    ret = GetDateFormat(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL, buff2, sizeof(buff2));
    ok(ret == lstrlenA(buff2)+1, "got %d\n", ret);
    buff[lstrlenA(buff2)] = '\0';
    ok(lstrcmpA(buff2, buff) == 0, "expected (%s) got (%s) for date part\n",
       buff2, buff);

    flags = FDTF_NOAUTOREADINGORDER | FDTF_SHORTDATE | FDTF_SHORTTIME;
    ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff));
    ok(ret == lstrlenA(buff)+1, "got %d\n", ret);
    ret = GetDateFormat(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &st, NULL, buff2, sizeof(buff2));
    ok(ret == lstrlenA(buff2)+1, "got %d\n", ret);
    strcat(buff2, " ");
    ret = GetTimeFormat(LOCALE_USER_DEFAULT, TIME_NOSECONDS, &st, NULL, buff3, sizeof(buff3));
    ok(ret == lstrlenA(buff3)+1, "got %d\n", ret);
    strcat(buff2, buff3);
    ok(lstrcmpA(buff, buff2) == 0, "expected (%s), got (%s)\n", buff2, buff);

    flags = FDTF_NOAUTOREADINGORDER | FDTF_SHORTDATE | FDTF_LONGTIME;
    ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff));
    ok(ret == lstrlenA(buff)+1, "got %d\n", ret);
    ret = GetDateFormat(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &st, NULL, buff2, sizeof(buff2));
    ok(ret == lstrlenA(buff2)+1, "got %d\n", ret);
    strcat(buff2, " ");
    ret = GetTimeFormat(LOCALE_USER_DEFAULT, 0, &st, NULL, buff3, sizeof(buff3));
    ok(ret == lstrlenA(buff3)+1, "got %d\n", ret);
    strcat(buff2, buff3);
    ok(lstrcmpA(buff, buff2) == 0, "expected (%s), got (%s)\n", buff2, buff);
}

static void test_SHFormatDateTimeW(void)
{
    FILETIME UNALIGNED filetime;
    WCHAR buff[100], buff2[100], buff3[100], *p1, *p2;
    SYSTEMTIME st;
    DWORD flags;
    INT ret;
    static const WCHAR spaceW[] = {' ',0};
#define UNICODE_LTR_MARK 0x200e

    if(!pSHFormatDateTimeW)
    {
        win_skip("pSHFormatDateTimeW isn't available\n");
        return;
    }

if (0)
{
    /* crashes on native */
    pSHFormatDateTimeW(NULL, NULL, NULL, 0);
}

    GetLocalTime(&st);
    SystemTimeToFileTime(&st, &filetime);
    /* SHFormatDateTime expects input as utc */
    LocalFileTimeToFileTime(&filetime, &filetime);

    /* no way to get required buffer length here */
    SetLastError(0xdeadbeef);
    ret = pSHFormatDateTimeW(&filetime, NULL, NULL, 0);
    ok(ret == 0, "expected 0, got %d\n", ret);
    ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());

    SetLastError(0xdeadbeef);
    buff[0] = 'a'; buff[1] = 0;
    ret = pSHFormatDateTimeW(&filetime, NULL, buff, 0);
    ok(ret == 0, "expected 0, got %d\n", ret);
    ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
    ok(buff[0] == 'a', "expected same string\n");

    /* all combinations documented as invalid succeeded */
    flags = FDTF_SHORTTIME | FDTF_LONGTIME;
    SetLastError(0xdeadbeef);
    ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR));
    ok(ret == lstrlenW(buff)+1 || ret == lstrlenW(buff),
       "expected %d or %d, got %d\n", lstrlenW(buff)+1, lstrlenW(buff), ret);
    ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());

    flags = FDTF_SHORTDATE | FDTF_LONGDATE;
    SetLastError(0xdeadbeef);
    ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR));
    ok(ret == lstrlenW(buff)+1 || ret == lstrlenW(buff),
       "expected %d or %d, got %d\n", lstrlenW(buff)+1, lstrlenW(buff), ret);
    ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());

    flags = FDTF_SHORTDATE | FDTF_LTRDATE | FDTF_RTLDATE;
    SetLastError(0xdeadbeef);
    buff[0] = 0; /* NT4 doesn't clear the buffer on failure */
    ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR));
    ok(ret == lstrlenW(buff)+1 || ret == lstrlenW(buff),
       "expected %d or %d, got %d\n", lstrlenW(buff)+1, lstrlenW(buff), ret);
    ok(GetLastError() == 0xdeadbeef ||
        broken(GetLastError() == ERROR_INVALID_FLAGS), /* Win9x/WinMe/NT4 */
        "expected 0xdeadbeef, got %d\n", GetLastError());

    /* now check returned strings */
    flags = FDTF_SHORTTIME;
    ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR));
    ok(ret == lstrlenW(buff)+1 || ret == lstrlenW(buff),
       "expected %d or %d, got %d\n", lstrlenW(buff)+1, lstrlenW(buff), ret);
    SetLastError(0xdeadbeef);
    ret = GetTimeFormatW(LOCALE_USER_DEFAULT, TIME_NOSECONDS, &st, NULL, buff2, sizeof(buff2)/sizeof(WCHAR));
    if (ret == 0 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
    {
        win_skip("Needed W-functions are not implemented\n");
        return;
    }
    ok(ret == lstrlenW(buff2)+1, "expected %d, got %d\n", lstrlenW(buff2)+1, ret);
    ok(lstrcmpW(buff, buff2) == 0, "expected equal strings\n");

    flags = FDTF_LONGTIME;
    ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR));
    ok(ret == lstrlenW(buff)+1 || ret == lstrlenW(buff),
       "expected %d or %d, got %d\n", lstrlenW(buff)+1, lstrlenW(buff), ret);
    ret = GetTimeFormatW(LOCALE_USER_DEFAULT, 0, &st, NULL, buff2, sizeof(buff2)/sizeof(WCHAR));
    ok(ret == lstrlenW(buff2)+1, "expected %d, got %d\n", lstrlenW(buff2)+1, ret);
    ok(lstrcmpW(buff, buff2) == 0, "expected equal strings\n");

    /* both time flags */
    flags = FDTF_LONGTIME | FDTF_SHORTTIME;
    ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR));
    ok(ret == lstrlenW(buff)+1 || ret == lstrlenW(buff),
       "expected %d or %d, got %d\n", lstrlenW(buff)+1, lstrlenW(buff), ret);
    ret = GetTimeFormatW(LOCALE_USER_DEFAULT, 0, &st, NULL, buff2, sizeof(buff2)/sizeof(WCHAR));
    ok(ret == lstrlenW(buff2)+1, "expected %d, got %d\n", lstrlenW(buff2)+1, ret);
    ok(lstrcmpW(buff, buff2) == 0, "expected equal string\n");

    flags = FDTF_SHORTDATE;
    ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR));
    ok(ret == lstrlenW(buff)+1 || ret == lstrlenW(buff),
       "expected %d or %d, got %d\n", lstrlenW(buff)+1, lstrlenW(buff), ret);
    ret = GetDateFormatW(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &st, NULL, buff2, sizeof(buff2)/sizeof(WCHAR));
    ok(ret == lstrlenW(buff2)+1, "expected %d, got %d\n", lstrlenW(buff2)+1, ret);
    ok(lstrcmpW(buff, buff2) == 0, "expected equal strings\n");

    flags = FDTF_LONGDATE;
    ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR));
    ok(ret == lstrlenW(buff)+1 || ret == lstrlenW(buff),
       "expected %d or %d, got %d\n", lstrlenW(buff)+1, lstrlenW(buff), ret);
    ret = GetDateFormatW(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL, buff2, sizeof(buff2)/sizeof(WCHAR));
    ok(ret == lstrlenW(buff2)+1, "expected %d, got %d\n", lstrlenW(buff2)+1, ret);
    ok(lstrcmpW(buff, buff2) == 0, "expected equal strings\n");

    /* both date flags */
    flags = FDTF_LONGDATE | FDTF_SHORTDATE;
    ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR));
    ok(ret == lstrlenW(buff)+1 || ret == lstrlenW(buff),
       "expected %d or %d, got %d\n", lstrlenW(buff)+1, lstrlenW(buff), ret);
    ret = GetDateFormatW(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL, buff2, sizeof(buff2)/sizeof(WCHAR));
    ok(ret == lstrlenW(buff2)+1, "expected %d, got %d\n", lstrlenW(buff2)+1, ret);
    ok(lstrcmpW(buff, buff2) == 0, "expected equal strings\n");

    /* various combinations of date/time flags */
    flags = FDTF_LONGDATE | FDTF_SHORTTIME;
    ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR));
    ok(ret == lstrlenW(buff)+1 || ret == lstrlenW(buff),
       "expected %d or %d, got %d\n", lstrlenW(buff)+1, lstrlenW(buff), ret);
    ret = GetTimeFormatW(LOCALE_USER_DEFAULT, TIME_NOSECONDS, &st, NULL, buff3, sizeof(buff3)/sizeof(WCHAR));
    ok(ret == lstrlenW(buff3)+1, "expected %d, got %d\n", lstrlenW(buff3)+1, ret);
    ok(lstrcmpW(buff3, buff + lstrlenW(buff) - lstrlenW(buff3)) == 0,
       "expected (%s), got (%s) for time part\n",
       wine_dbgstr_w(buff3), wine_dbgstr_w(buff + lstrlenW(buff) - lstrlenW(buff3)));
    ret = GetDateFormatW(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL, buff2, sizeof(buff2)/sizeof(WCHAR));
    ok(ret == lstrlenW(buff2)+1, "expected %d, got %d\n", lstrlenW(buff2)+1, ret);
    p1 = buff;
    p2 = buff2;
    while (*p2 != '\0')
    {
        while (*p1 == UNICODE_LTR_MARK)
            p1++;
        while (*p2 == UNICODE_LTR_MARK)
            p2++;
        p1++;
        p2++;
    }
    *p1 = '\0';
    ok(lstrcmpW(buff2, buff) == 0, "expected (%s) got (%s) for date part\n",
       wine_dbgstr_w(buff2), wine_dbgstr_w(buff));

    flags = FDTF_LONGDATE | FDTF_LONGTIME;
    ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR));
    ok(ret == lstrlenW(buff)+1 || ret == lstrlenW(buff),
       "expected %d or %d, got %d\n", lstrlenW(buff)+1, lstrlenW(buff), ret);
    ret = GetTimeFormatW(LOCALE_USER_DEFAULT, 0, &st, NULL, buff3, sizeof(buff3)/sizeof(WCHAR));
    ok(ret == lstrlenW(buff3)+1, "expected %d, got %d\n", lstrlenW(buff3)+1, ret);
    ok(lstrcmpW(buff3, buff + lstrlenW(buff) - lstrlenW(buff3)) == 0,
       "expected (%s), got (%s) for time part\n",
       wine_dbgstr_w(buff3), wine_dbgstr_w(buff + lstrlenW(buff) - lstrlenW(buff3)));
    ret = GetDateFormatW(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL, buff2, sizeof(buff2)/sizeof(WCHAR));
    ok(ret == lstrlenW(buff2)+1, "expected %d, got %d\n", lstrlenW(buff2)+1, ret);
    p1 = buff;
    p2 = buff2;
    while (*p2 != '\0')
    {
        while (*p1 == UNICODE_LTR_MARK)
            p1++;
        while (*p2 == UNICODE_LTR_MARK)
            p2++;
        p1++;
        p2++;
    }
    *p1 = '\0';
    ok(lstrcmpW(buff2, buff) == 0, "expected (%s) got (%s) for date part\n",
       wine_dbgstr_w(buff2), wine_dbgstr_w(buff));

    flags = FDTF_SHORTDATE | FDTF_SHORTTIME;
    ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR));
    ok(ret == lstrlenW(buff)+1 || ret == lstrlenW(buff),
       "expected %d or %d, got %d\n", lstrlenW(buff)+1, lstrlenW(buff), ret);
    ret = GetDateFormatW(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &st, NULL, buff2, sizeof(buff2)/sizeof(WCHAR));
    ok(ret == lstrlenW(buff2)+1, "expected %d, got %d\n", lstrlenW(buff2)+1, ret);
    lstrcatW(buff2, spaceW);
    ret = GetTimeFormatW(LOCALE_USER_DEFAULT, TIME_NOSECONDS, &st, NULL, buff3, sizeof(buff3)/sizeof(WCHAR));
    ok(ret == lstrlenW(buff3)+1, "expected %d, got %d\n", lstrlenW(buff3)+1, ret);
    lstrcatW(buff2, buff3);
    ok(lstrcmpW(buff, buff2) == 0, "expected equal strings\n");

    flags = FDTF_SHORTDATE | FDTF_LONGTIME;
    ret = pSHFormatDateTimeW(&filetime, &flags, buff, sizeof(buff)/sizeof(WCHAR));
    ok(ret == lstrlenW(buff)+1 || ret == lstrlenW(buff),
       "expected %d or %d, got %d\n", lstrlenW(buff)+1, lstrlenW(buff), ret);
    ret = GetDateFormatW(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &st, NULL, buff2, sizeof(buff2)/sizeof(WCHAR));
    ok(ret == lstrlenW(buff2)+1, "expected %d, got %d\n", lstrlenW(buff2)+1, ret);
    lstrcatW(buff2, spaceW);
    ret = GetTimeFormatW(LOCALE_USER_DEFAULT, 0, &st, NULL, buff3, sizeof(buff3)/sizeof(WCHAR));
    ok(ret == lstrlenW(buff3)+1, "expected %d, got %d\n", lstrlenW(buff3)+1, ret);
    lstrcatW(buff2, buff3);
    ok(lstrcmpW(buff, buff2) == 0, "expected equal strings\n");
}

static void test_SHGetObjectCompatFlags(void)
{
    struct compat_value {
        CHAR nameA[30];
        DWORD value;
    };

    struct compat_value values[] = {
        { "OTNEEDSSFCACHE", 0x1 },
        { "NO_WEBVIEW", 0x2 },
        { "UNBINDABLE", 0x4 },
        { "PINDLL", 0x8 },
        { "NEEDSFILESYSANCESTOR", 0x10 },
        { "NOTAFILESYSTEM", 0x20 },
        { "CTXMENU_NOVERBS", 0x40 },
        { "CTXMENU_LIMITEDQI", 0x80 },
        { "COCREATESHELLFOLDERONLY", 0x100 },
        { "NEEDSSTORAGEANCESTOR", 0x200 },
        { "NOLEGACYWEBVIEW", 0x400 },
        { "CTXMENU_XPQCMFLAGS", 0x1000 },
        { "NOIPROPERTYSTORE", 0x2000 }
    };

    static const char compat_path[] = "Software\\Microsoft\\Windows\\CurrentVersion\\ShellCompatibility\\Objects";
    void *pColorAdjustLuma = GetProcAddress(hShlwapi, "ColorAdjustLuma");
    CHAR keyA[39]; /* {CLSID} */
    HKEY root;
    DWORD ret;
    int i;

    if (!pSHGetObjectCompatFlags)
    {
        win_skip("SHGetObjectCompatFlags isn't available\n");
        return;
    }

    if (pColorAdjustLuma && pColorAdjustLuma == pSHGetObjectCompatFlags) /* win2k */
    {
        win_skip("Skipping SHGetObjectCompatFlags, same ordinal used for ColorAdjustLuma\n");
        return;
    }

    /* null args */
    ret = pSHGetObjectCompatFlags(NULL, NULL);
    ok(ret == 0, "got %d\n", ret);

    ret = RegOpenKeyA(HKEY_LOCAL_MACHINE, compat_path, &root);
    if (ret != ERROR_SUCCESS)
    {
        skip("No compatibility class data found\n");
        return;
    }

    for (i = 0; RegEnumKeyA(root, i, keyA, sizeof(keyA)) == ERROR_SUCCESS; i++)
    {
        HKEY clsid_key;

        if (RegOpenKeyA(root, keyA, &clsid_key) == ERROR_SUCCESS)
        {
            CHAR valueA[30];
            DWORD expected = 0, got, length = sizeof(valueA);
            CLSID clsid;
            int v;

            for (v = 0; RegEnumValueA(clsid_key, v, valueA, &length, NULL, NULL, NULL, NULL) == ERROR_SUCCESS; v++)
            {
                int j;

                for (j = 0; j < sizeof(values)/sizeof(struct compat_value); j++)
                    if (lstrcmpA(values[j].nameA, valueA) == 0)
                    {
                        expected |= values[j].value;
                        break;
                    }

                length = sizeof(valueA);
            }

            pGUIDFromStringA(keyA, &clsid);
            got = pSHGetObjectCompatFlags(NULL, &clsid);
            ok(got == expected, "got 0x%08x, expected 0x%08x. Key %s\n", got, expected, keyA);

            RegCloseKey(clsid_key);
        }
    }

    RegCloseKey(root);
}

typedef struct {
    IOleCommandTarget IOleCommandTarget_iface;
    LONG ref;
} IOleCommandTargetImpl;

static inline IOleCommandTargetImpl *impl_from_IOleCommandTarget(IOleCommandTarget *iface)
{
    return CONTAINING_RECORD(iface, IOleCommandTargetImpl, IOleCommandTarget_iface);
}

static const IOleCommandTargetVtbl IOleCommandTargetImpl_Vtbl;

static IOleCommandTarget* IOleCommandTargetImpl_Construct(void)
{
    IOleCommandTargetImpl *obj;

    obj = HeapAlloc(GetProcessHeap(), 0, sizeof(*obj));
    obj->IOleCommandTarget_iface.lpVtbl = &IOleCommandTargetImpl_Vtbl;
    obj->ref = 1;

    return &obj->IOleCommandTarget_iface;
}

static HRESULT WINAPI IOleCommandTargetImpl_QueryInterface(IOleCommandTarget *iface, REFIID riid, void **ppvObj)
{
    IOleCommandTargetImpl *This = impl_from_IOleCommandTarget(iface);

    if (IsEqualIID(riid, &IID_IUnknown) ||
        IsEqualIID(riid, &IID_IOleCommandTarget))
    {
        *ppvObj = This;
    }

    if(*ppvObj)
    {
        IUnknown_AddRef(iface);
        return S_OK;
    }

    return E_NOINTERFACE;
}

static ULONG WINAPI IOleCommandTargetImpl_AddRef(IOleCommandTarget *iface)
{
    IOleCommandTargetImpl *This = impl_from_IOleCommandTarget(iface);
    return InterlockedIncrement(&This->ref);
}

static ULONG WINAPI IOleCommandTargetImpl_Release(IOleCommandTarget *iface)
{
    IOleCommandTargetImpl *This = impl_from_IOleCommandTarget(iface);
    ULONG ref = InterlockedDecrement(&This->ref);

    if (!ref)
    {
        HeapFree(GetProcessHeap(), 0, This);
        return 0;
    }
    return ref;
}

static HRESULT WINAPI IOleCommandTargetImpl_QueryStatus(
    IOleCommandTarget *iface, const GUID *group, ULONG cCmds, OLECMD prgCmds[], OLECMDTEXT *pCmdText)
{
    return E_NOTIMPL;
}

static HRESULT WINAPI IOleCommandTargetImpl_Exec(
    IOleCommandTarget *iface,
    const GUID *CmdGroup,
    DWORD nCmdID,
    DWORD nCmdexecopt,
    VARIANT *pvaIn,
    VARIANT *pvaOut)
{
    add_call(&trace_got, 3, CmdGroup, (void*)(DWORD_PTR)nCmdID, (void*)(DWORD_PTR)nCmdexecopt, pvaIn, pvaOut);
    return S_OK;
}

static const IOleCommandTargetVtbl IOleCommandTargetImpl_Vtbl =
{
    IOleCommandTargetImpl_QueryInterface,
    IOleCommandTargetImpl_AddRef,
    IOleCommandTargetImpl_Release,
    IOleCommandTargetImpl_QueryStatus,
    IOleCommandTargetImpl_Exec
};

typedef struct {
    IServiceProvider IServiceProvider_iface;
    LONG ref;
} IServiceProviderImpl;

static inline IServiceProviderImpl *impl_from_IServiceProvider(IServiceProvider *iface)
{
    return CONTAINING_RECORD(iface, IServiceProviderImpl, IServiceProvider_iface);
}

typedef struct {
    IProfferService IProfferService_iface;
    LONG ref;
} IProfferServiceImpl;

static inline IProfferServiceImpl *impl_from_IProfferService(IProfferService *iface)
{
    return CONTAINING_RECORD(iface, IProfferServiceImpl, IProfferService_iface);
}


static const IServiceProviderVtbl IServiceProviderImpl_Vtbl;
static const IProfferServiceVtbl IProfferServiceImpl_Vtbl;

static IServiceProvider* IServiceProviderImpl_Construct(void)
{
    IServiceProviderImpl *obj;

    obj = HeapAlloc(GetProcessHeap(), 0, sizeof(*obj));
    obj->IServiceProvider_iface.lpVtbl = &IServiceProviderImpl_Vtbl;
    obj->ref = 1;

    return &obj->IServiceProvider_iface;
}

static IProfferService* IProfferServiceImpl_Construct(void)
{
    IProfferServiceImpl *obj;

    obj = HeapAlloc(GetProcessHeap(), 0, sizeof(*obj));
    obj->IProfferService_iface.lpVtbl = &IProfferServiceImpl_Vtbl;
    obj->ref = 1;

    return &obj->IProfferService_iface;
}

static HRESULT WINAPI IServiceProviderImpl_QueryInterface(IServiceProvider *iface, REFIID riid, void **ppvObj)
{
    IServiceProviderImpl *This = impl_from_IServiceProvider(iface);

    if (IsEqualIID(riid, &IID_IUnknown) ||
        IsEqualIID(riid, &IID_IServiceProvider))
    {
        *ppvObj = This;
    }

    if(*ppvObj)
    {
        IUnknown_AddRef(iface);
        /* native uses redefined IID_IServiceProvider symbol, so we can't compare pointers */
        if (IsEqualIID(riid, &IID_IServiceProvider))
            add_call(&trace_got, 1, iface, &IID_IServiceProvider, 0, 0, 0);
        return S_OK;
    }

    return E_NOINTERFACE;
}

static ULONG WINAPI IServiceProviderImpl_AddRef(IServiceProvider *iface)
{
    IServiceProviderImpl *This = impl_from_IServiceProvider(iface);
    return InterlockedIncrement(&This->ref);
}

static ULONG WINAPI IServiceProviderImpl_Release(IServiceProvider *iface)
{
    IServiceProviderImpl *This = impl_from_IServiceProvider(iface);
    ULONG ref = InterlockedDecrement(&This->ref);

    if (!ref)
    {
        HeapFree(GetProcessHeap(), 0, This);
        return 0;
    }
    return ref;
}

static HRESULT WINAPI IServiceProviderImpl_QueryService(
    IServiceProvider *iface, REFGUID service, REFIID riid, void **ppv)
{
    /* native uses redefined pointer for IID_IOleCommandTarget, not one from uuid.lib */
    if (IsEqualIID(riid, &IID_IOleCommandTarget))
    {
        add_call(&trace_got, 2, iface, service, &IID_IOleCommandTarget, 0, 0);
        *ppv = IOleCommandTargetImpl_Construct();
    }
    if (IsEqualIID(riid, &IID_IProfferService))
    {
        if (IsEqualIID(service, &IID_IProfferService))
            add_call(&trace_got, 2, &IID_IProfferService, &IID_IProfferService, 0, 0, 0);
        *ppv = IProfferServiceImpl_Construct();
    }
    return S_OK;
}

static const IServiceProviderVtbl IServiceProviderImpl_Vtbl =
{
    IServiceProviderImpl_QueryInterface,
    IServiceProviderImpl_AddRef,
    IServiceProviderImpl_Release,
    IServiceProviderImpl_QueryService
};

static void test_IUnknown_QueryServiceExec(void)
{
    IServiceProvider *provider = IServiceProviderImpl_Construct();
    static const GUID dummy_serviceid = { 0xdeadbeef };
    static const GUID dummy_groupid = { 0xbeefbeef };
    call_trace_t trace_expected;
    HRESULT hr;

    /* on <=W2K platforms same ordinal used for another export with different
       prototype, so skipping using this indirect condition */
    if (is_win2k_and_lower)
    {
        win_skip("IUnknown_QueryServiceExec is not available\n");
        return;
    }

    /* null source pointer */
    hr = pIUnknown_QueryServiceExec(NULL, &dummy_serviceid, &dummy_groupid, 0, 0, 0, 0);
    ok(hr == E_FAIL, "got 0x%08x\n", hr);

    /* expected trace:
       IUnknown_QueryServiceExec( ptr1, serviceid, groupid, arg1, arg2, arg3, arg4);
         -> IUnknown_QueryInterface( ptr1, &IID_IServiceProvider, &prov );
         -> IServiceProvider_QueryService( prov, serviceid, &IID_IOleCommandTarget, &obj );
         -> IOleCommandTarget_Exec( obj, groupid, arg1, arg2, arg3, arg4 );
    */
    init_call_trace(&trace_expected);

    add_call(&trace_expected, 1, provider, &IID_IServiceProvider, 0, 0, 0);
    add_call(&trace_expected, 2, provider, &dummy_serviceid, &IID_IOleCommandTarget, 0, 0);
    add_call(&trace_expected, 3, &dummy_groupid, (void*)0x1, (void*)0x2, (void*)0x3, (void*)0x4);

    init_call_trace(&trace_got);
    hr = pIUnknown_QueryServiceExec((IUnknown*)provider, &dummy_serviceid, &dummy_groupid, 0x1, 0x2, (void*)0x3, (void*)0x4);
    ok(hr == S_OK, "got 0x%08x\n", hr);

    ok_trace(&trace_expected, &trace_got);

    free_call_trace(&trace_expected);
    free_call_trace(&trace_got);

    IServiceProvider_Release(provider);
}


static HRESULT WINAPI IProfferServiceImpl_QueryInterface(IProfferService *iface, REFIID riid, void **ppvObj)
{
    IProfferServiceImpl *This = impl_from_IProfferService(iface);

    if (IsEqualIID(riid, &IID_IUnknown) ||
        IsEqualIID(riid, &IID_IProfferService))
    {
        *ppvObj = This;
    }
    else if (IsEqualIID(riid, &IID_IServiceProvider))
    {
        *ppvObj = IServiceProviderImpl_Construct();
        add_call(&trace_got, 1, iface, &IID_IServiceProvider, 0, 0, 0);
        return S_OK;
    }

    if(*ppvObj)
    {
        IUnknown_AddRef(iface);
        return S_OK;
    }

    return E_NOINTERFACE;
}

static ULONG WINAPI IProfferServiceImpl_AddRef(IProfferService *iface)
{
    IProfferServiceImpl *This = impl_from_IProfferService(iface);
    return InterlockedIncrement(&This->ref);
}

static ULONG WINAPI IProfferServiceImpl_Release(IProfferService *iface)
{
    IProfferServiceImpl *This = impl_from_IProfferService(iface);
    ULONG ref = InterlockedDecrement(&This->ref);

    if (!ref)
    {
        HeapFree(GetProcessHeap(), 0, This);
        return 0;
    }
    return ref;
}

static HRESULT WINAPI IProfferServiceImpl_ProfferService(IProfferService *iface,
    REFGUID service, IServiceProvider *pService, DWORD *pCookie)
{
    *pCookie = 0xdeadbeef;
    add_call(&trace_got, 3, service, pService, pCookie, 0, 0);
    return S_OK;
}

static HRESULT WINAPI IProfferServiceImpl_RevokeService(IProfferService *iface, DWORD cookie)
{
    add_call(&trace_got, 4, (void*)(DWORD_PTR)cookie, 0, 0, 0, 0);
    return S_OK;
}

static const IProfferServiceVtbl IProfferServiceImpl_Vtbl =
{
    IProfferServiceImpl_QueryInterface,
    IProfferServiceImpl_AddRef,
    IProfferServiceImpl_Release,
    IProfferServiceImpl_ProfferService,
    IProfferServiceImpl_RevokeService
};

static void test_IUnknown_ProfferService(void)
{
    IServiceProvider *provider = IServiceProviderImpl_Construct();
    IProfferService *proff = IProfferServiceImpl_Construct();
    static const GUID dummy_serviceid = { 0xdeadbeef };
    call_trace_t trace_expected;
    HRESULT hr;
    DWORD cookie;

    /* on <=W2K platforms same ordinal used for another export with different
       prototype, so skipping using this indirect condition */
    if (is_win2k_and_lower)
    {
        win_skip("IUnknown_ProfferService is not available\n");
        return;
    }

    /* null source pointer */
    hr = pIUnknown_ProfferService(NULL, &dummy_serviceid, 0, 0);
    ok(hr == E_FAIL, "got 0x%08x\n", hr);

    /* expected trace:
       IUnknown_ProfferService( ptr1, serviceid, arg1, arg2);
         -> IUnknown_QueryInterface( ptr1, &IID_IServiceProvider, &provider );
         -> IServiceProvider_QueryService( provider, &IID_IProfferService, &IID_IProfferService, &proffer );

         if (service pointer not null):
             -> IProfferService_ProfferService( proffer, serviceid, arg1, arg2 );
         else
             -> IProfferService_RevokeService( proffer, *arg2 );
    */
    init_call_trace(&trace_expected);

    add_call(&trace_expected, 1, proff, &IID_IServiceProvider, 0, 0, 0);
    add_call(&trace_expected, 2, &IID_IProfferService, &IID_IProfferService, 0, 0, 0);
    add_call(&trace_expected, 3, &dummy_serviceid, provider, &cookie, 0, 0);

    init_call_trace(&trace_got);
    cookie = 0;
    hr = pIUnknown_ProfferService((IUnknown*)proff, &dummy_serviceid, provider, &cookie);
    ok(hr == S_OK, "got 0x%08x\n", hr);
    ok(cookie == 0xdeadbeef, "got %x\n", cookie);

    ok_trace(&trace_expected, &trace_got);
    free_call_trace(&trace_got);
    free_call_trace(&trace_expected);

    /* same with ::Revoke path */
    init_call_trace(&trace_expected);

    add_call(&trace_expected, 1, proff, &IID_IServiceProvider, 0, 0, 0);
    add_call(&trace_expected, 2, &IID_IProfferService, &IID_IProfferService, 0, 0, 0);
    add_call(&trace_expected, 4, (void*)(DWORD_PTR)cookie, 0, 0, 0, 0);

    init_call_trace(&trace_got);
    ok(cookie != 0, "got %x\n", cookie);
    hr = pIUnknown_ProfferService((IUnknown*)proff, &dummy_serviceid, 0, &cookie);
    ok(hr == S_OK, "got 0x%08x\n", hr);
    ok(cookie == 0, "got %x\n", cookie);
    ok_trace(&trace_expected, &trace_got);
    free_call_trace(&trace_got);
    free_call_trace(&trace_expected);

    IServiceProvider_Release(provider);
    IProfferService_Release(proff);
}

static void test_SHCreateWorkerWindowA(void)
{
    WNDCLASSA cliA;
    char classA[20];
    HWND hwnd;
    LONG_PTR ret;
    BOOL res;

    if (is_win2k_and_lower)
    {
        win_skip("SHCreateWorkerWindowA not available\n");
        return;
    }

    hwnd = pSHCreateWorkerWindowA(0, NULL, 0, 0, 0, 0);
    ok(hwnd != 0, "expected window\n");

    GetClassName(hwnd, classA, 20);
    ok(lstrcmpA(classA, "WorkerA") == 0, "expected WorkerA class, got %s\n", classA);

    ret = GetWindowLongPtrA(hwnd, 0);
    ok(ret == 0, "got %ld\n", ret);

    /* class info */
    memset(&cliA, 0, sizeof(cliA));
    res = GetClassInfoA(GetModuleHandle("shlwapi.dll"), "WorkerA", &cliA);
    ok(res, "failed to get class info\n");
    ok(cliA.style == 0, "got 0x%08x\n", cliA.style);
    ok(cliA.cbClsExtra == 0, "got %d\n", cliA.cbClsExtra);
    ok(cliA.cbWndExtra == sizeof(LONG_PTR), "got %d\n", cliA.cbWndExtra);
    ok(cliA.lpszMenuName == 0, "got %s\n", cliA.lpszMenuName);

    DestroyWindow(hwnd);

    /* set extra bytes */
    hwnd = pSHCreateWorkerWindowA(0, NULL, 0, 0, 0, 0xdeadbeef);
    ok(hwnd != 0, "expected window\n");

    GetClassName(hwnd, classA, 20);
    ok(lstrcmpA(classA, "WorkerA") == 0, "expected WorkerA class, got %s\n", classA);

    ret = GetWindowLongPtrA(hwnd, 0);
    ok(ret == 0xdeadbeef, "got %ld\n", ret);

    /* test exstyle */
    ret = GetWindowLongA(hwnd, GWL_EXSTYLE);
    ok(ret == WS_EX_WINDOWEDGE ||
       ret == (WS_EX_WINDOWEDGE|WS_EX_LAYOUTRTL) /* systems with RTL locale */, "0x%08lx\n", ret);

    DestroyWindow(hwnd);

    hwnd = pSHCreateWorkerWindowA(0, NULL, WS_EX_TOOLWINDOW, 0, 0, 0);
    ret = GetWindowLongA(hwnd, GWL_EXSTYLE);
    ok(ret == (WS_EX_WINDOWEDGE|WS_EX_TOOLWINDOW) ||
       ret == (WS_EX_WINDOWEDGE|WS_EX_TOOLWINDOW|WS_EX_LAYOUTRTL) /* systems with RTL locale */, "0x%08lx\n", ret);
    DestroyWindow(hwnd);
}

static HRESULT WINAPI SF_QueryInterface(IShellFolder *iface,
        REFIID riid, void **ppv)
{
    /* SHIShellFolder_EnumObjects doesn't QI the object for IShellFolder */
    ok(!IsEqualGUID(&IID_IShellFolder, riid),
            "Unexpected QI for IShellFolder\n");
    return E_NOINTERFACE;
}

static ULONG WINAPI SF_AddRef(IShellFolder *iface)
{
    return 2;
}

static ULONG WINAPI SF_Release(IShellFolder *iface)
{
    return 1;
}

static HRESULT WINAPI SF_ParseDisplayName(IShellFolder *iface,
        HWND owner, LPBC reserved, LPOLESTR displayName, ULONG *eaten,
        LPITEMIDLIST *idl, ULONG *attr)
{
    ok(0, "Didn't expect ParseDisplayName\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI SF_EnumObjects(IShellFolder *iface,
        HWND owner, SHCONTF flags, IEnumIDList **enm)
{
    *enm = (IEnumIDList*)0xcafebabe;
    return S_OK;
}

static HRESULT WINAPI SF_BindToObject(IShellFolder *iface,
        LPCITEMIDLIST idl, LPBC reserved, REFIID riid, void **obj)
{
    ok(0, "Didn't expect BindToObject\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI SF_BindToStorage(IShellFolder *iface,
        LPCITEMIDLIST idl, LPBC reserved, REFIID riid, void **obj)
{
    ok(0, "Didn't expect BindToStorage\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI SF_CompareIDs(IShellFolder *iface,
        LPARAM lparam, LPCITEMIDLIST idl1, LPCITEMIDLIST idl2)
{
    ok(0, "Didn't expect CompareIDs\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI SF_CreateViewObject(IShellFolder *iface,
        HWND owner, REFIID riid, void **out)
{
    ok(0, "Didn't expect CreateViewObject\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI SF_GetAttributesOf(IShellFolder *iface,
        UINT cidl, LPCITEMIDLIST *idl, SFGAOF *inOut)
{
    ok(0, "Didn't expect GetAttributesOf\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI SF_GetUIObjectOf(IShellFolder *iface,
        HWND owner, UINT cidl, LPCITEMIDLIST *idls, REFIID riid, UINT *inOut,
        void **out)
{
    ok(0, "Didn't expect GetUIObjectOf\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI SF_GetDisplayNameOf(IShellFolder *iface,
        LPCITEMIDLIST idl, SHGDNF flags, STRRET *name)
{
    ok(0, "Didn't expect GetDisplayNameOf\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI SF_SetNameOf(IShellFolder *iface,
        HWND hwnd, LPCITEMIDLIST idl, LPCOLESTR name, SHGDNF flags,
        LPITEMIDLIST *idlOut)
{
    ok(0, "Didn't expect SetNameOf\n");
    return E_NOTIMPL;
}

static IShellFolderVtbl ShellFolderVtbl = {
    SF_QueryInterface,
    SF_AddRef,
    SF_Release,
    SF_ParseDisplayName,
    SF_EnumObjects,
    SF_BindToObject,
    SF_BindToStorage,
    SF_CompareIDs,
    SF_CreateViewObject,
    SF_GetAttributesOf,
    SF_GetUIObjectOf,
    SF_GetDisplayNameOf,
    SF_SetNameOf
};

static IShellFolder ShellFolder = { &ShellFolderVtbl };

static void test_SHIShellFolder_EnumObjects(void)
{
    IEnumIDList *enm;
    HRESULT hres;
    IShellFolder *folder;

    if(!pSHIShellFolder_EnumObjects || is_win2k_and_lower){
        win_skip("SHIShellFolder_EnumObjects not available\n");
        return;
    }

    if(0){
        /* NULL object crashes on Windows */
        pSHIShellFolder_EnumObjects(NULL, NULL, 0, NULL);
    }

    /* SHIShellFolder_EnumObjects doesn't QI the object for IShellFolder */
    enm = (IEnumIDList*)0xdeadbeef;
    hres = pSHIShellFolder_EnumObjects(&ShellFolder, NULL, 0, &enm);
    ok(hres == S_OK, "SHIShellFolder_EnumObjects failed: 0x%08x\n", hres);
    ok(enm == (IEnumIDList*)0xcafebabe, "Didn't get expected enumerator location, instead: %p\n", enm);

    /* SHIShellFolder_EnumObjects isn't strict about the IShellFolder object */
    hres = pSHGetDesktopFolder(&folder);
    ok(hres == S_OK, "SHGetDesktopFolder failed: 0x%08x\n", hres);

    enm = NULL;
    hres = pSHIShellFolder_EnumObjects(folder, NULL, 0, &enm);
    ok(hres == S_OK, "SHIShellFolder_EnumObjects failed: 0x%08x\n", hres);
    ok(enm != NULL, "Didn't get an enumerator\n");
    if(enm)
        IEnumIDList_Release(enm);

    IShellFolder_Release(folder);
}

static void write_inifile(LPCWSTR filename)
{
    DWORD written;
    HANDLE file;

    static const char data[] =
        "[TestApp]\r\n"
        "AKey=1\r\n"
        "AnotherKey=asdf\r\n";

    file = CreateFileW(filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
    if(file == INVALID_HANDLE_VALUE)
        return;

    WriteFile(file, data, sizeof(data), &written, NULL);

    CloseHandle(file);
}

#define verify_inifile(f, e) r_verify_inifile(__LINE__, f, e)
static void r_verify_inifile(unsigned l, LPCWSTR filename, LPCSTR exp)
{
    HANDLE file;
    CHAR buf[1024];
    DWORD read;

    file = CreateFileW(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
    if(file == INVALID_HANDLE_VALUE)
        return;

    ReadFile(file, buf, sizeof(buf) * sizeof(CHAR), &read, NULL);
    buf[read] = '\0';

    CloseHandle(file);

    ok_(__FILE__,l)(!strcmp(buf, exp), "Expected:\n%s\nGot:\n%s\n", exp,
            buf);
}

static void test_SHGetIniString(void)
{
    DWORD ret;
    WCHAR out[64] = {0};

    static const WCHAR TestAppW[] = {'T','e','s','t','A','p','p',0};
    static const WCHAR TestIniW[] = {'C',':','\\','t','e','s','t','.','i','n','i',0};
    static const WCHAR AKeyW[] = {'A','K','e','y',0};
    static const WCHAR AnotherKeyW[] = {'A','n','o','t','h','e','r','K','e','y',0};
    static const WCHAR JunkKeyW[] = {'J','u','n','k','K','e','y',0};

    if(!pSHGetIniStringW || is_win2k_and_lower){
        win_skip("SHGetIniStringW is not available\n");
        return;
    }

    write_inifile(TestIniW);

    if(0){
        /* these crash on Windows */
        pSHGetIniStringW(NULL, NULL, NULL, 0, NULL);
        pSHGetIniStringW(NULL, AKeyW, out, sizeof(out), TestIniW);
        pSHGetIniStringW(TestAppW, AKeyW, NULL, sizeof(out), TestIniW);
    }

    ret = pSHGetIniStringW(TestAppW, AKeyW, out, 0, TestIniW);
    ok(ret == 0, "SHGetIniStringW should have given 0, instead: %d\n", ret);

    /* valid arguments */
    ret = pSHGetIniStringW(TestAppW, NULL, out, sizeof(out), TestIniW);
    ok(broken(ret == 0) || /* win 98 */
            ret == 4, "SHGetIniStringW should have given 4, instead: %d\n", ret);
    ok(!lstrcmpW(out, AKeyW), "Expected %s, got: %s\n",
                wine_dbgstr_w(AKeyW), wine_dbgstr_w(out));

    ret = pSHGetIniStringW(TestAppW, AKeyW, out, sizeof(out), TestIniW);
    ok(broken(ret == 0) || /* win 98 */
                ret == 1, "SHGetIniStringW should have given 1, instead: %d\n", ret);
    ok(broken(*out == 0) || /*win 98 */
        !strcmp_wa(out, "1"), "Expected L\"1\", got: %s\n", wine_dbgstr_w(out));

    ret = pSHGetIniStringW(TestAppW, AnotherKeyW, out, sizeof(out), TestIniW);
    ok(broken(ret == 0) || /* win 98 */
            ret == 4, "SHGetIniStringW should have given 4, instead: %d\n", ret);
    ok(broken(*out == 0) || /* win 98 */
            !strcmp_wa(out, "asdf"), "Expected L\"asdf\", got: %s\n", wine_dbgstr_w(out));

    ret = pSHGetIniStringW(TestAppW, JunkKeyW, out, sizeof(out), TestIniW);
    ok(ret == 0, "SHGetIniStringW should have given 0, instead: %d\n", ret);
    ok(*out == 0, "Expected L\"\", got: %s\n", wine_dbgstr_w(out));

    DeleteFileW(TestIniW);
}

static void test_SHSetIniString(void)
{
    BOOL ret;

    static const WCHAR TestAppW[] = {'T','e','s','t','A','p','p',0};
    static const WCHAR AnotherAppW[] = {'A','n','o','t','h','e','r','A','p','p',0};
    static const WCHAR TestIniW[] = {'C',':','\\','t','e','s','t','.','i','n','i',0};
    static const WCHAR AKeyW[] = {'A','K','e','y',0};
    static const WCHAR NewKeyW[] = {'N','e','w','K','e','y',0};
    static const WCHAR AValueW[] = {'A','V','a','l','u','e',0};

    if(!pSHSetIniStringW || is_win2k_and_lower){
        win_skip("SHSetIniStringW is not available\n");
        return;
    }

    write_inifile(TestIniW);

    ret = pSHSetIniStringW(TestAppW, AKeyW, AValueW, TestIniW);
    ok(ret == TRUE, "SHSetIniStringW should not have failed\n");
    todo_wine /* wine sticks an extra \r\n at the end of the file */
        verify_inifile(TestIniW, "[TestApp]\r\nAKey=AValue\r\nAnotherKey=asdf\r\n");

    ret = pSHSetIniStringW(TestAppW, AKeyW, NULL, TestIniW);
    ok(ret == TRUE, "SHSetIniStringW should not have failed\n");
    verify_inifile(TestIniW, "[TestApp]\r\nAnotherKey=asdf\r\n");

    ret = pSHSetIniStringW(AnotherAppW, NewKeyW, AValueW, TestIniW);
    ok(ret == TRUE, "SHSetIniStringW should not have failed\n");
    verify_inifile(TestIniW, "[TestApp]\r\nAnotherKey=asdf\r\n[AnotherApp]\r\nNewKey=AValue\r\n");

    ret = pSHSetIniStringW(TestAppW, NULL, AValueW, TestIniW);
    ok(ret == TRUE, "SHSetIniStringW should not have failed\n");
    verify_inifile(TestIniW, "[AnotherApp]\r\nNewKey=AValue\r\n");

    DeleteFileW(TestIniW);
}

enum _shellkey_flags {
    SHKEY_Root_HKCU = 0x1,
    SHKEY_Root_HKLM = 0x2,
    SHKEY_Key_Explorer  = 0x00,
    SHKEY_Key_Shell = 0x10,
    SHKEY_Key_ShellNoRoam = 0x20,
    SHKEY_Key_Classes = 0x30,
    SHKEY_Subkey_Default = 0x0000,
    SHKEY_Subkey_ResourceName = 0x1000,
    SHKEY_Subkey_Handlers = 0x2000,
    SHKEY_Subkey_Associations = 0x3000,
    SHKEY_Subkey_Volatile = 0x4000,
    SHKEY_Subkey_MUICache = 0x5000,
    SHKEY_Subkey_FileExts = 0x6000
};

static void test_SHGetShellKey(void)
{
    static const WCHAR ShellFoldersW[] = { 'S','h','e','l','l',' ','F','o','l','d','e','r','s',0 };
    static const WCHAR WineTestW[] = { 'W','i','n','e','T','e','s','t',0 };

    void *pPathBuildRootW = GetProcAddress(hShlwapi, "PathBuildRootW");
    DWORD *alloc_data, data, size;
    HKEY hkey;
    HRESULT hres;

    if (!pSHGetShellKey)
    {
        win_skip("SHGetShellKey(ordinal 491) isn't available\n");
        return;
    }

    /* some win2k */
    if (pPathBuildRootW && pPathBuildRootW == pSHGetShellKey)
    {
        win_skip("SHGetShellKey(ordinal 491) used for PathBuildRootW\n");
        return;
    }

    if (is_win9x || is_win2k_and_lower)
    {
        win_skip("Ordinal 491 used for another call, skipping SHGetShellKey tests\n");
        return;
    }

    /* Vista+ limits SHKEY enumeration values */
    SetLastError(0xdeadbeef);
    hkey = pSHGetShellKey(SHKEY_Key_Explorer, ShellFoldersW, FALSE);
    if (hkey)
    {
        /* Tests not working on Vista+ */
        RegCloseKey(hkey);

        hkey = pSHGetShellKey(SHKEY_Root_HKLM|SHKEY_Key_Classes, NULL, FALSE);
        ok(hkey != NULL, "hkey = NULL\n");
        RegCloseKey(hkey);
    }

    hkey = pSHGetShellKey(SHKEY_Root_HKCU|SHKEY_Key_Explorer, ShellFoldersW, FALSE);
    ok(hkey != NULL, "hkey = NULL\n");
    RegCloseKey(hkey);

    hkey = pSHGetShellKey(SHKEY_Root_HKLM|SHKEY_Key_Explorer, ShellFoldersW, FALSE);
    ok(hkey != NULL, "hkey = NULL\n");
    RegCloseKey(hkey);

    hkey = pSHGetShellKey(SHKEY_Root_HKLM, WineTestW, FALSE);
    ok(hkey == NULL, "hkey != NULL\n");

    hkey = pSHGetShellKey(SHKEY_Root_HKLM, WineTestW, TRUE);
    ok(hkey != NULL, "Can't create key\n");
    RegCloseKey(hkey);

    hkey = pSHGetShellKey(SHKEY_Root_HKLM, NULL, FALSE);
    ok(hkey != NULL, "Can't create key\n");
    ok(SUCCEEDED(RegDeleteKeyW(hkey, WineTestW)), "Can't delte key\n");
    RegCloseKey(hkey);

    if (!pSKGetValueW || !pSKSetValueW || !pSKDeleteValueW || !pSKAllocValueW)
    {
        win_skip("SKGetValueW, SKSetValueW, SKDeleteValueW or SKAllocValueW not available\n");
        return;
    }

    hres = pSKGetValueW(SHKEY_Root_HKLM, WineTestW, NULL, NULL, &data, &size);
    ok(hres == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "hres = %x\n", hres);

    data = 1234;
    hres = pSKSetValueW(SHKEY_Root_HKLM, WineTestW, NULL, REG_DWORD, &data, sizeof(DWORD));
    ok(hres == S_OK, "hres = %x\n", hres);

    size = 1;
    hres = pSKGetValueW(SHKEY_Root_HKLM, WineTestW, NULL, NULL, NULL, &size);
    ok(hres == S_OK, "hres = %x\n", hres);
    ok(size == sizeof(DWORD), "size = %d\n", size);

    data = 0xdeadbeef;
    hres = pSKGetValueW(SHKEY_Root_HKLM, WineTestW, NULL, NULL, &data, &size);
    ok(hres == S_OK, "hres = %x\n", hres);
    ok(size == sizeof(DWORD), "size = %d\n", size);
    ok(data == 1234, "data = %d\n", data);

    hres = pSKAllocValueW(SHKEY_Root_HKLM, WineTestW, NULL, NULL, (void**)&alloc_data, &size);
    ok(hres == S_OK, "hres= %x\n", hres);
    ok(size == sizeof(DWORD), "size = %d\n", size);
    if (SUCCEEDED(hres))
    {
        ok(*alloc_data == 1234, "*alloc_data = %d\n", *alloc_data);
        LocalFree(alloc_data);
    }

    hres = pSKDeleteValueW(SHKEY_Root_HKLM, WineTestW, NULL);
    ok(hres == S_OK, "hres = %x\n", hres);

    hres = pSKDeleteValueW(SHKEY_Root_HKLM, WineTestW, NULL);
    ok(hres == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "hres = %x\n", hres);

    hres = pSKGetValueW(SHKEY_Root_HKLM, WineTestW, NULL, NULL, &data, &size);
    ok(hres == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "hres = %x\n", hres);

    hkey = pSHGetShellKey(SHKEY_Root_HKLM, NULL, FALSE);
    ok(hkey != NULL, "Can't create key\n");
    ok(SUCCEEDED(RegDeleteKeyW(hkey, WineTestW)), "Can't delte key\n");
    RegCloseKey(hkey);
}

static void init_pointers(void)
{
#define MAKEFUNC(f, ord) (p##f = (void*)GetProcAddress(hShlwapi, (LPSTR)(ord)))
    MAKEFUNC(SHAllocShared, 7);
    MAKEFUNC(SHLockShared, 8);
    MAKEFUNC(SHUnlockShared, 9);
    MAKEFUNC(SHFreeShared, 10);
    MAKEFUNC(GetAcceptLanguagesA, 14);
    MAKEFUNC(SHSetWindowBits, 165);
    MAKEFUNC(ConnectToConnectionPoint, 168);
    MAKEFUNC(SHSearchMapInt, 198);
    MAKEFUNC(SHCreateWorkerWindowA, 257);
    MAKEFUNC(GUIDFromStringA, 269);
    MAKEFUNC(SHPackDispParams, 282);
    MAKEFUNC(IConnectionPoint_InvokeWithCancel, 283);
    MAKEFUNC(IConnectionPoint_SimpleInvoke, 284);
    MAKEFUNC(SHGetIniStringW, 294);
    MAKEFUNC(SHSetIniStringW, 295);
    MAKEFUNC(SHFormatDateTimeA, 353);
    MAKEFUNC(SHFormatDateTimeW, 354);
    MAKEFUNC(SHIShellFolder_EnumObjects, 404);
    MAKEFUNC(SHGetObjectCompatFlags, 476);
    MAKEFUNC(IUnknown_QueryServiceExec, 484);
    MAKEFUNC(SHGetShellKey, 491);
    MAKEFUNC(SHPropertyBag_ReadLONG, 496);
    MAKEFUNC(IUnknown_ProfferService, 514);
    MAKEFUNC(SKGetValueW, 516);
    MAKEFUNC(SKSetValueW, 517);
    MAKEFUNC(SKDeleteValueW, 518);
    MAKEFUNC(SKAllocValueW, 519);
#undef MAKEFUNC
}

START_TEST(ordinal)
{
    hShlwapi = GetModuleHandleA("shlwapi.dll");
    is_win2k_and_lower = GetProcAddress(hShlwapi, "StrChrNW") == 0;
    is_win9x = GetProcAddress(hShlwapi, (LPSTR)99) == 0; /* StrCpyNXA */

    /* SHCreateStreamOnFileEx was introduced in shlwapi v6.0 */
    if(!GetProcAddress(hShlwapi, "SHCreateStreamOnFileEx")){
        win_skip("Too old shlwapi version\n");
        return;
    }

    init_pointers();

    hmlang = LoadLibraryA("mlang.dll");
    pLcidToRfc1766A = (void *)GetProcAddress(hmlang, "LcidToRfc1766A");

    hshell32 = LoadLibraryA("shell32.dll");
    pSHGetDesktopFolder = (void *)GetProcAddress(hshell32, "SHGetDesktopFolder");

    test_GetAcceptLanguagesA();
    test_SHSearchMapInt();
    test_alloc_shared();
    test_fdsa();
    test_GetShellSecurityDescriptor();
    test_SHPackDispParams();
    test_IConnectionPoint();
    test_SHPropertyBag_ReadLONG();
    test_SHSetWindowBits();
    test_SHFormatDateTimeA();
    test_SHFormatDateTimeW();
    test_SHGetObjectCompatFlags();
    test_IUnknown_QueryServiceExec();
    test_IUnknown_ProfferService();
    test_SHCreateWorkerWindowA();
    test_SHIShellFolder_EnumObjects();
    test_SHGetIniString();
    test_SHSetIniString();
    test_SHGetShellKey();

    FreeLibrary(hshell32);
    FreeLibrary(hmlang);
}
