From: Dmitry Timoshkov dmitry@baikal.ru
Signed-off-by: Dmitry Timoshkov dmitry@baikal.ru --- dlls/shdocvw/Makefile.in | 2 +- dlls/shdocvw/shdocvw_main.c | 56 +++++++++++++++++++++-- dlls/shdocvw/tests/shdocvw.c | 81 ++++++++++++++++++++++++++++++++++ dlls/shell32/tests/shlfolder.c | 8 ++-- 4 files changed, 139 insertions(+), 8 deletions(-)
diff --git a/dlls/shdocvw/Makefile.in b/dlls/shdocvw/Makefile.in index d38782eaf22..bea902a7357 100644 --- a/dlls/shdocvw/Makefile.in +++ b/dlls/shdocvw/Makefile.in @@ -1,7 +1,7 @@ MODULE = shdocvw.dll IMPORTLIB = shdocvw IMPORTS = uuid shlwapi advapi32 -DELAYIMPORTS = version ole32 oleaut32 ieframe +DELAYIMPORTS = version ole32 oleaut32 ieframe shell32
SOURCES = \ shdocvw.rc \ diff --git a/dlls/shdocvw/shdocvw_main.c b/dlls/shdocvw/shdocvw_main.c index 6556223e1d7..a6c118c718e 100644 --- a/dlls/shdocvw/shdocvw_main.c +++ b/dlls/shdocvw/shdocvw_main.c @@ -431,11 +431,61 @@ DWORD WINAPI ParseURLFromOutsideSourceA(LPCSTR url, LPSTR out, LPDWORD plen, LPD /****************************************************************** * IEParseDisplayNameWithBCW (SHDOCVW.218) */ -HRESULT WINAPI IEParseDisplayNameWithBCW(DWORD codepage, LPCWSTR lpszDisplayName, LPBC pbc, LPITEMIDLIST *ppidl) +HRESULT WINAPI IEParseDisplayNameWithBCW(DWORD codepage, LPCWSTR name, IBindCtx *pbc, LPITEMIDLIST *ppidl) { +#include <pshpack1.h> + struct ie_pidl_data + { + BYTE type; /* 0x61 - PT_IESPECIAL1 */ + BYTE dummy1; /* 0x80 */ + DWORD dummy2; /* 0 */ + WCHAR name[1]; /* terminated by double \0 */ + } *ie_data; +#include <poppack.h> + HRESULT hr; + LPITEMIDLIST parent, child, next, ret; + DWORD size, len; + PARSEDURLW res; + /* Guessing at parameter 3 based on IShellFolder's ParseDisplayName */ - FIXME("stub: 0x%lx %s %p %p\n",codepage,debugstr_w(lpszDisplayName),pbc,ppidl); - return E_FAIL; + FIXME("%lu %s %p %p: semi-stub\n", codepage, debugstr_w(name), pbc, ppidl); + + /* Make sure that it's correct URL */ + res.cbSize = sizeof(res); + hr = ParseURLW(name, &res); + if (hr != S_OK) return E_FAIL; + + hr = SHGetFolderLocation(0, CSIDL_INTERNET, 0, 0, &parent); + if (hr != S_OK) return hr; + + len = wcslen(name) + 1; + size = FIELD_OFFSET(struct ie_pidl_data, name) + (len + 2) * sizeof(WCHAR); + + child = SHAlloc(size + sizeof(*next)); + if (!child) return E_OUTOFMEMORY; + + child->mkid.cb = size; + ie_data = (struct ie_pidl_data *)child->mkid.abID; + ie_data->type = 0x61; + ie_data->dummy1 = 0x80; + ie_data->dummy2 = 0; + wcscpy(ie_data->name, name); + ie_data->name[len] = 0; + ie_data->name[len + 1] = 0; + + next = (LPITEMIDLIST)((char *)child + child->mkid.cb); + next->mkid.cb = 0; + next->mkid.abID[0] = 0; + + ret = ILCombine(parent, child); + + SHFree(parent); + SHFree(child); + + if (!ret) return E_OUTOFMEMORY; + + *ppidl = ret; + return S_OK; }
/****************************************************************** diff --git a/dlls/shdocvw/tests/shdocvw.c b/dlls/shdocvw/tests/shdocvw.c index fcfd4a644db..da917cfe0db 100644 --- a/dlls/shdocvw/tests/shdocvw.c +++ b/dlls/shdocvw/tests/shdocvw.c @@ -18,6 +18,7 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
+#define COBJMACROS
#include <stdarg.h>
@@ -26,6 +27,8 @@ #include "winreg.h" #include "wininet.h" #include "winnls.h" +#include "shtypes.h" +#include "shlobj.h"
#include "wine/test.h"
@@ -35,6 +38,7 @@ static HMODULE hshdocvw; static HRESULT (WINAPI *pURLSubRegQueryA)(LPCSTR, LPCSTR, DWORD, LPVOID, DWORD, DWORD); static DWORD (WINAPI *pParseURLFromOutsideSourceA)(LPCSTR, LPSTR, LPDWORD, LPDWORD); static DWORD (WINAPI *pParseURLFromOutsideSourceW)(LPCWSTR, LPWSTR, LPDWORD, LPDWORD); +static HRESULT (WINAPI *pIEParseDisplayNameWithBCW)(DWORD, LPCWSTR, LPBC, LPITEMIDLIST *);
static const char appdata[] = "AppData"; static const char common_appdata[] = "Common AppData"; @@ -76,6 +80,7 @@ static void init_functions(void) pURLSubRegQueryA = (void *) GetProcAddress(hshdocvw, (LPSTR) 151); pParseURLFromOutsideSourceA = (void *) GetProcAddress(hshdocvw, (LPSTR) 169); pParseURLFromOutsideSourceW = (void *) GetProcAddress(hshdocvw, (LPSTR) 170); + pIEParseDisplayNameWithBCW = (void *) GetProcAddress(hshdocvw, (LPSTR) 218); }
/* ################ */ @@ -351,11 +356,87 @@ static void test_ParseURLFromOutsideSourceW(void)
/* ################ */
+static void test_IE_pidl(LPITEMIDLIST pidl, const WCHAR *name) +{ +#include <pshpack1.h> + struct ie_pidl_data + { + BYTE type; /* 0x61 - PT_IESPECIAL1 */ + BYTE dummy1; /* 0x80 */ + DWORD dummy2; /* 0 */ + WCHAR name[1]; /* terminated by double \0 */ + } *data; +#include <poppack.h> + + while (pidl->mkid.cb) + { + int len; + + if (pidl->mkid.abID[0] == 0x1f) + { + GUID *guid = (GUID *)&pidl->mkid.abID[2]; + ok(IsEqualGUID(guid, &CLSID_Internet), "got %s\n", wine_dbgstr_guid(guid)); + ok(pidl->mkid.abID[1] == 0, "got %#x\n", pidl->mkid.abID[1]); + len = sizeof(GUID) + 4; + ok(pidl->mkid.cb == len, "expected %d, got %d\n", len, pidl->mkid.cb); + } + else if (pidl->mkid.abID[0] == 0x61) + { + data = (struct ie_pidl_data *)pidl->mkid.abID; + ok(data->dummy1 == 0x80, "got %#x\n", data->dummy1); + ok(data->dummy2 == 0, "got %#lx\n", data->dummy2); + ok(!wcscmp(data->name, name), "got %s\n", wine_dbgstr_w(data->name)); + len = wcslen(data->name) + 1; + ok(data->name[len] == 0, "got %d\n", data->name[len]); + ok(data->name[len + 1] == 0, "got %d\n", data->name[len + 1]); + len = FIELD_OFFSET(struct ie_pidl_data, name) + (len + 2) * sizeof(WCHAR); + ok(pidl->mkid.cb == len, "expected %d, got %d\n", len, pidl->mkid.cb); + } + + pidl = (LPITEMIDLIST)((char *)pidl + pidl->mkid.cb); + } +} + +static void test_IEParseDisplayNameWithBCW(void) +{ + HRESULT hr; + IBindCtx *ctx; + LPITEMIDLIST pidl; + + if (!pIEParseDisplayNameWithBCW) + { + skip("IEParseDisplayNameWithBCW not found\n"); + return; + } + + hr = CreateBindCtx(0, &ctx); + ok(hr == S_OK, "got %#lx\n", hr); + + hr = pIEParseDisplayNameWithBCW(0, L"custom://url", ctx, &pidl); + ok(hr == S_OK, "got %#lx\n", hr); + test_IE_pidl(pidl, L"custom://url"); + SHFree(pidl); + + hr = pIEParseDisplayNameWithBCW(0, L"readme.txt", ctx, &pidl); + ok(hr == E_FAIL, "got %#lx\n", hr); + + hr = pIEParseDisplayNameWithBCW(0, L"ftp://url.org/readme.txt", ctx, &pidl); + ok(hr == S_OK, "got %#lx\n", hr); + test_IE_pidl(pidl, L"ftp://url.org/readme.txt"); + SHFree(pidl); + + if (0) /* hangs */ + hr = pIEParseDisplayNameWithBCW(0, L"file://readme.txt", ctx, &pidl); + + IBindCtx_Release(ctx); +} + START_TEST(shdocvw) { init_functions(); test_URLSubRegQueryA(); test_ParseURLFromOutsideSourceA(); test_ParseURLFromOutsideSourceW(); + test_IEParseDisplayNameWithBCW(); FreeLibrary(hshdocvw); } diff --git a/dlls/shell32/tests/shlfolder.c b/dlls/shell32/tests/shlfolder.c index f1cae84257a..21152f98484 100644 --- a/dlls/shell32/tests/shlfolder.c +++ b/dlls/shell32/tests/shlfolder.c @@ -213,10 +213,10 @@ static struct {{'t','e','s','t','\',0}, 0x80070002}, {{'s','u','b','\','d','i','r',0}, 0x80070002}, {{'s','u','b','/','d','i','r',0}, E_INVALIDARG, 1}, - {{'h','t','t','p',':',0}, S_OK, 1}, - {{'h','t','t','p',':','t','e','s','t',0}, S_OK, 1}, - {{'h','t','t','p',':','\','t','e','s','t',0}, S_OK, 1}, - {{'x','x',':',0}, S_OK, 1}, + {{'h','t','t','p',':',0}, S_OK}, + {{'h','t','t','p',':','t','e','s','t',0}, S_OK}, + {{'h','t','t','p',':','\','t','e','s','t',0}, S_OK}, + {{'x','x',':',0}, S_OK}, };
static void test_ParseDisplayName(void)