>From a0bee812bf1ae7d00a20eae283e781af7c04f7ed Mon Sep 17 00:00:00 2001
From: Nikolay Sivov <nsivov@codeweavers.com>
Date: Sat, 31 Dec 2011 00:46:43 +0300
Subject: [PATCH 02/10] Implement IWshCollection::Item() for Desktop folder case

---
 dlls/wshom.ocx/Makefile.in       |    2 +-
 dlls/wshom.ocx/shell.c           |   44 ++++++++++++++++++++++++++++++++++++-
 dlls/wshom.ocx/tests/Makefile.in |    2 +-
 dlls/wshom.ocx/tests/wshom.c     |   32 +++++++++++++++++++++++++-
 4 files changed, 74 insertions(+), 6 deletions(-)

diff --git a/dlls/wshom.ocx/Makefile.in b/dlls/wshom.ocx/Makefile.in
index 385fe73..6635e5d 100644
--- a/dlls/wshom.ocx/Makefile.in
+++ b/dlls/wshom.ocx/Makefile.in
@@ -1,5 +1,5 @@
 MODULE    = wshom.ocx
-IMPORTS   = uuid oleaut32
+IMPORTS   = uuid oleaut32 ole32 shell32
 
 C_SRCS = \
 	shell.c \
diff --git a/dlls/wshom.ocx/shell.c b/dlls/wshom.ocx/shell.c
index 525ee7f..2bd6a08 100644
--- a/dlls/wshom.ocx/shell.c
+++ b/dlls/wshom.ocx/shell.c
@@ -19,7 +19,10 @@
 #include "wshom_private.h"
 #include "wshom.h"
 
+#include "shlobj.h"
+
 #include "wine/debug.h"
+#include "wine/unicode.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(wshom);
 
@@ -167,8 +170,45 @@ static HRESULT WINAPI WshCollection_Invoke(IWshCollection *iface, DISPID dispIdM
 static HRESULT WINAPI WshCollection_Item(IWshCollection *iface, VARIANT *index, VARIANT *value)
 {
     WshCollection *This = impl_from_IWshCollection(iface);
-    FIXME("(%p)->(%s %p): stub\n", This, debugstr_variant(index), value);
-    return E_NOTIMPL;
+    static const WCHAR desktopW[] = {'D','e','s','k','t','o','p',0};
+    PIDLIST_ABSOLUTE pidl;
+    WCHAR pathW[MAX_PATH];
+    int kind = 0;
+    BSTR folder;
+    HRESULT hr;
+
+    TRACE("(%p)->(%s %p)\n", This, debugstr_variant(index), value);
+
+    if (V_VT(index) != VT_BSTR)
+    {
+        FIXME("only BSTR index supported, got %d\n", V_VT(index));
+        return E_NOTIMPL;
+    }
+
+    folder = V_BSTR(index);
+    if (!strcmpiW(folder, desktopW))
+        kind = CSIDL_DESKTOP;
+    else
+    {
+        FIXME("folder kind %s not supported\n", debugstr_w(folder));
+        return E_NOTIMPL;
+    }
+
+    hr = SHGetSpecialFolderLocation(NULL, kind, &pidl);
+    if (hr != S_OK) return hr;
+
+    if (SHGetPathFromIDListW(pidl, pathW))
+    {
+        V_VT(value) = VT_BSTR;
+        V_BSTR(value) = SysAllocString(pathW);
+        hr = V_BSTR(value) ? S_OK : E_OUTOFMEMORY;
+    }
+    else
+        hr = E_FAIL;
+
+    CoTaskMemFree(pidl);
+
+    return hr;
 }
 
 static HRESULT WINAPI WshCollection_Count(IWshCollection *iface, LONG *count)
diff --git a/dlls/wshom.ocx/tests/Makefile.in b/dlls/wshom.ocx/tests/Makefile.in
index e062b3c..1580050 100644
--- a/dlls/wshom.ocx/tests/Makefile.in
+++ b/dlls/wshom.ocx/tests/Makefile.in
@@ -1,5 +1,5 @@
 TESTDLL   = wshom.ocx
-IMPORTS   = ole32
+IMPORTS   = oleaut32 ole32
 
 C_SRCS = \
 	wshom.c
diff --git a/dlls/wshom.ocx/tests/wshom.c b/dlls/wshom.ocx/tests/wshom.c
index 414378f..2c2af45 100644
--- a/dlls/wshom.ocx/tests/wshom.c
+++ b/dlls/wshom.ocx/tests/wshom.c
@@ -26,11 +26,14 @@
 #include "wshom.h"
 #include "wine/test.h"
 
+DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
+
 #define EXPECT_HR(hr,hr_exp) \
     ok(hr == hr_exp, "got 0x%08x, expected 0x%08x\n", hr, hr_exp)
 
 static void test_wshshell(void)
 {
+    static const WCHAR desktopW[] = {'D','e','s','k','t','o','p',0};
     IWshShell3 *sh3;
     IDispatchEx *dispex;
     IWshCollection *coll;
@@ -40,6 +43,11 @@ static void test_wshshell(void)
     ITypeInfo *ti;
     HRESULT hr;
     TYPEATTR *tattr;
+    DISPPARAMS dp;
+    EXCEPINFO ei;
+    VARIANT arg, res;
+    BSTR str;
+    UINT err;
 
     hr = CoCreateInstance(&CLSID_WshShell, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
             &IID_IDispatch, (void**)&disp);
@@ -72,11 +80,31 @@ static void test_wshshell(void)
 
     hr = ITypeInfo_GetTypeAttr(ti, &tattr);
     EXPECT_HR(hr, S_OK);
-    ok(IsEqualIID(&tattr->guid, &IID_IWshCollection), "got \n");
+    ok(IsEqualIID(&tattr->guid, &IID_IWshCollection), "got wrong type guid\n");
     ITypeInfo_ReleaseTypeAttr(ti, tattr);
 
-    IWshShell3_Release(sh3);
+    /* try to call Item() with normal IDispatch procedure */
+    str = SysAllocString(desktopW);
+    V_VT(&arg) = VT_BSTR;
+    V_BSTR(&arg) = str;
+    dp.rgvarg = &arg;
+    dp.rgdispidNamedArgs = NULL;
+    dp.cArgs = 1;
+    dp.cNamedArgs = 0;
+    hr = IDispatch_Invoke(disp, DISPID_VALUE, &IID_NULL, 1033, DISPATCH_PROPERTYGET, &dp, &res, &ei, &err);
+    EXPECT_HR(hr, DISP_E_MEMBERNOTFOUND);
+
+    /* try Item() directly, it returns directory path apparently */
+    V_VT(&res) = VT_EMPTY;
+    hr = IWshCollection_Item(coll, &arg, &res);
+    EXPECT_HR(hr, S_OK);
+    SysFreeString(str);
+    ok(V_VT(&res) == VT_BSTR, "got res type %d\n", V_VT(&res));
+    VariantClear(&res);
 
+    IWshCollection_Release(coll);
+    IDispatch_Release(disp);
+    IWshShell3_Release(sh3);
     IUnknown_Release(shell);
 }
 
-- 
1.5.6.5


