[PATCH 2/8] explorerframe: Add initial NamespaceTreeControl stub and register the dll.

David Hedberg david.hedberg at gmail.com
Thu Jul 29 14:10:16 CDT 2010


Note that native explorerframe.dll does not contain
Dll(Un)RegisterServer, but I'm hoping this is an acceptable solution
for registering the CLSID.
---
 configure.ac                            |    1 +
 dlls/explorerframe/Makefile.in          |    4 +-
 dlls/explorerframe/eframe.rc            |   22 ++
 dlls/explorerframe/explorerframe.inf    |   16 ++
 dlls/explorerframe/explorerframe.spec   |    2 +
 dlls/explorerframe/explorerframe_main.c |   86 ++++++++
 dlls/explorerframe/explorerframe_main.h |    4 +
 dlls/explorerframe/nstc.c               |  355 +++++++++++++++++++++++++++++++
 dlls/explorerframe/tests/Makefile.in    |   11 +
 dlls/explorerframe/tests/nstc.c         |  100 +++++++++
 tools/wine.inf.in                       |    1 +
 11 files changed, 601 insertions(+), 1 deletions(-)
 create mode 100644 dlls/explorerframe/eframe.rc
 create mode 100644 dlls/explorerframe/explorerframe.inf
 create mode 100644 dlls/explorerframe/nstc.c
 create mode 100644 dlls/explorerframe/tests/Makefile.in
 create mode 100644 dlls/explorerframe/tests/nstc.c

diff --git a/configure.ac b/configure.ac
index 1fad01c..fd07b21 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2359,6 +2359,7 @@ WINE_CONFIG_DLL(dxgi,,[dxgi])
 WINE_CONFIG_TEST(dlls/dxgi/tests)
 WINE_CONFIG_LIB(dxguid)
 WINE_CONFIG_DLL(explorerframe,,[explorerframe])
+WINE_CONFIG_TEST(dlls/explorerframe/tests)
 WINE_CONFIG_DLL(faultrep)
 WINE_CONFIG_DLL(fltlib)
 WINE_CONFIG_DLL(fusion)
diff --git a/dlls/explorerframe/Makefile.in b/dlls/explorerframe/Makefile.in
index 8c68535..b5e7a42 100644
--- a/dlls/explorerframe/Makefile.in
+++ b/dlls/explorerframe/Makefile.in
@@ -7,9 +7,11 @@ IMPORTS   = uuid shell32 kernel32 user32
 DELAYIMPORTS = ole32
 
 C_SRCS = \
-	explorerframe_main.c
+	explorerframe_main.c \
+	nstc.c
 
 RC_SRCS = \
+	eframe.rc \
 	version.rc
 
 @MAKE_DLL_RULES@
\ No newline at end of file
diff --git a/dlls/explorerframe/eframe.rc b/dlls/explorerframe/eframe.rc
new file mode 100644
index 0000000..f8cd529
--- /dev/null
+++ b/dlls/explorerframe/eframe.rc
@@ -0,0 +1,22 @@
+/*
+ * ExplorerFrame main resource file
+ * 
+ * Copyright 2010 David Hedberg
+ *
+ * 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
+ */
+
+/* @makedep: explorerframe.inf */
+REGINST REGINST explorerframe.inf
diff --git a/dlls/explorerframe/explorerframe.inf b/dlls/explorerframe/explorerframe.inf
new file mode 100644
index 0000000..a57878a
--- /dev/null
+++ b/dlls/explorerframe/explorerframe.inf
@@ -0,0 +1,16 @@
+[version]
+Signature="$CHICAGO$"
+
+[RegisterDll]
+AddReg=Classes.Reg
+
+[UnregisterDll]
+DelReg=Classes.Reg
+
+[Classes.Reg]
+HKCR,"CLSID\%CLSID_NamespaceTreeControl%",,,"Shell Name Space ListView"
+HKCR,"CLSID\%CLSID_NamespaceTreeControl%\InProcServer32",,,"%MODULE%"
+HKCR,"CLSID\%CLSID_NamespaceTreeControl%\InProcServer32","ThreadingModel",,"Apartment"
+
+[Strings]
+MODULE="explorerframe.dll"
diff --git a/dlls/explorerframe/explorerframe.spec b/dlls/explorerframe/explorerframe.spec
index 0bff42f..3ffa7f9 100644
--- a/dlls/explorerframe/explorerframe.spec
+++ b/dlls/explorerframe/explorerframe.spec
@@ -7,3 +7,5 @@
 @ stdcall -private DllCanUnloadNow()
 @ stdcall -private DllGetClassObject(ptr ptr ptr)
 @ stdcall -private DllGetVersion(ptr)
+@ stdcall -private DllRegisterServer()
+@ stdcall -private DllUnregisterServer()
diff --git a/dlls/explorerframe/explorerframe_main.c b/dlls/explorerframe/explorerframe_main.c
index d8c7749..a377168 100644
--- a/dlls/explorerframe/explorerframe_main.c
+++ b/dlls/explorerframe/explorerframe_main.c
@@ -19,6 +19,7 @@
  */
 
 #include <stdarg.h>
+#include <stdio.h>
 
 #define COBJMACROS
 
@@ -28,6 +29,8 @@
 #include "winuser.h"
 #include "winerror.h"
 #include "shlwapi.h"
+#include "advpub.h"
+#include "shobjidl.h"
 
 #include "wine/unicode.h"
 #include "wine/debug.h"
@@ -193,6 +196,89 @@ static const IClassFactoryVtbl EFCF_Vtbl =
  */
 HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void **ppv)
 {
+    static IClassFactoryImpl NSTCClassFactory = {&EFCF_Vtbl, NamespaceTreeControl_Constructor};
+
     TRACE("%s, %s, %p\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
+
+    if(IsEqualGUID(&CLSID_NamespaceTreeControl, rclsid))
+        return IClassFactory_QueryInterface(FACTORY(&NSTCClassFactory), riid, ppv);
+
     return CLASS_E_CLASSNOTAVAILABLE;
 }
+
+/*************************************************************************
+ *          Register/Unregister DLL, based on shdocvw/factory.c
+ */
+static HRESULT reg_install(LPCSTR section, STRTABLEA *strtable)
+{
+    HRESULT (WINAPI *pRegInstall)(HMODULE hm, LPCSTR pszSection, const STRTABLEA* pstTable);
+    HMODULE hadvpack;
+    HRESULT hres;
+
+    static const WCHAR advpackW[] = {'a','d','v','p','a','c','k','.','d','l','l',0};
+
+    hadvpack = LoadLibraryW(advpackW);
+    pRegInstall = (void *)GetProcAddress(hadvpack, "RegInstall");
+
+    hres = pRegInstall(explorerframe_hinstance, section, strtable);
+
+    FreeLibrary(hadvpack);
+    return hres;
+}
+
+#define INF_SET_CLSID(clsid)                  \
+    do                                        \
+    {                                         \
+        static CHAR name[] = "CLSID_" #clsid; \
+                                              \
+        pse[i].pszName = name;                \
+        clsids[i++] = &CLSID_ ## clsid;       \
+    } while (0)
+
+static HRESULT register_server(BOOL doregister)
+{
+    STRTABLEA strtable;
+    STRENTRYA pse[1];
+    static CLSID const *clsids[1];
+    unsigned int i = 0;
+    HRESULT hres;
+
+    INF_SET_CLSID(NamespaceTreeControl);
+
+    for(i = 0; i < sizeof(pse)/sizeof(pse[0]); i++)
+    {
+        pse[i].pszValue = HeapAlloc(GetProcessHeap(), 0, 39);
+        sprintf(pse[i].pszValue, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
+                clsids[i]->Data1, clsids[i]->Data2, clsids[i]->Data3, clsids[i]->Data4[0],
+                clsids[i]->Data4[1], clsids[i]->Data4[2], clsids[i]->Data4[3], clsids[i]->Data4[4],
+                clsids[i]->Data4[5], clsids[i]->Data4[6], clsids[i]->Data4[7]);
+    }
+
+    strtable.cEntries = sizeof(pse)/sizeof(pse[0]);
+    strtable.pse = pse;
+
+    hres = reg_install(doregister ? "RegisterDll" : "UnregisterDll", &strtable);
+
+    for(i=0; i < sizeof(pse)/sizeof(pse[0]); i++)
+        HeapFree(GetProcessHeap(), 0, pse[i].pszValue);
+
+    return hres;
+}
+
+#undef INF_SET_CLSID
+
+/*************************************************************************
+ *          DllRegisterServer (ExplorerFrame.@)
+ */
+HRESULT WINAPI DllRegisterServer(void)
+{
+    return register_server(TRUE);
+}
+
+/*************************************************************************
+ *          DllUnregisterServer (ExplorerFrame.@)
+ */
+HRESULT WINAPI DllUnregisterServer(void)
+{
+    return register_server(FALSE);
+}
diff --git a/dlls/explorerframe/explorerframe_main.h b/dlls/explorerframe/explorerframe_main.h
index 45be664..1abf85a 100644
--- a/dlls/explorerframe/explorerframe_main.h
+++ b/dlls/explorerframe/explorerframe_main.h
@@ -21,10 +21,14 @@
 #ifndef __WINE_EXPLORERFRAME_H
 #define __WINE_EXPLORERFRAME_H
 
+#include "shlobj.h"
+
 extern HINSTANCE explorerframe_hinstance;
 
 extern LONG EFRAME_refCount;
 static inline void EFRAME_LockModule(void) { InterlockedIncrement( &EFRAME_refCount ); }
 static inline void EFRAME_UnlockModule(void) { InterlockedDecrement( &EFRAME_refCount ); }
 
+HRESULT NamespaceTreeControl_Constructor(IUnknown *pUnkOuter, REFIID riid, LPVOID *ppv);
+
 #endif /* __WINE_EXPLORERFRAME_H */
diff --git a/dlls/explorerframe/nstc.c b/dlls/explorerframe/nstc.c
new file mode 100644
index 0000000..8068e37
--- /dev/null
+++ b/dlls/explorerframe/nstc.c
@@ -0,0 +1,355 @@
+/*
+ * NamespaceTreeControl implementation.
+ *
+ * Copyright 2010 David Hedberg
+ *
+ * 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 <stdarg.h>
+
+#define COBJMACROS
+
+#include "winerror.h"
+#include "windef.h"
+#include "winbase.h"
+
+#include "wine/debug.h"
+
+#include "explorerframe_main.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(nstc);
+
+typedef struct {
+    const INameSpaceTreeControl2Vtbl *lpVtbl;
+    LONG ref;
+} NSTC2Impl;
+
+/**************************************************************************
+ * INameSpaceTreeControl2 Implementation
+ */
+static HRESULT WINAPI NSTC2_fnQueryInterface(INameSpaceTreeControl2* iface,
+                                             REFIID riid,
+                                             void **ppvObject)
+{
+    NSTC2Impl *This = (NSTC2Impl*)iface;
+    TRACE("%p (%s, %p)\n", This, debugstr_guid(riid), ppvObject);
+
+    *ppvObject = NULL;
+    if(IsEqualIID(riid, &IID_INameSpaceTreeControl2) ||
+       IsEqualIID(riid, &IID_INameSpaceTreeControl) ||
+       IsEqualIID(riid, &IID_IUnknown))
+    {
+        *ppvObject = This;
+    }
+
+    if(*ppvObject)
+    {
+        IUnknown_AddRef((IUnknown*)*ppvObject);
+        return S_OK;
+    }
+
+    return E_NOINTERFACE;
+}
+
+static ULONG WINAPI NSTC2_fnAddRef(INameSpaceTreeControl2* iface)
+{
+    NSTC2Impl *This = (NSTC2Impl*)iface;
+    LONG ref = InterlockedIncrement(&This->ref);
+
+    TRACE("%p - ref %d\n", This, ref);
+
+    return ref;
+}
+
+static ULONG WINAPI NSTC2_fnRelease(INameSpaceTreeControl2* iface)
+{
+    NSTC2Impl *This = (NSTC2Impl*)iface;
+    LONG ref = InterlockedDecrement(&This->ref);
+
+    TRACE("%p - ref: %d\n", This, ref);
+
+    if(!ref)
+    {
+        TRACE("Freeing.\n");
+        HeapFree(GetProcessHeap(), 0, This);
+        EFRAME_UnlockModule();
+        return 0;
+    }
+
+    return ref;
+}
+
+static HRESULT WINAPI NSTC2_fnInitialize(INameSpaceTreeControl2* iface,
+                                         HWND hwndParent,
+                                         RECT *prc,
+                                         NSTCSTYLE nstcsFlags)
+{
+    NSTC2Impl *This = (NSTC2Impl*)iface;
+    FIXME("stub, %p (%p, %p, %x)\n", This, hwndParent, prc, nstcsFlags);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI NSTC2_fnTreeAdvise(INameSpaceTreeControl2* iface,
+                                         IUnknown *punk,
+                                         DWORD *pdwCookie)
+{
+    NSTC2Impl *This = (NSTC2Impl*)iface;
+    FIXME("stub, %p (%p, %p)\n", This, punk, pdwCookie);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI NSTC2_fnTreeUnadvise(INameSpaceTreeControl2* iface,
+                                           DWORD dwCookie)
+{
+    NSTC2Impl *This = (NSTC2Impl*)iface;
+    FIXME("stub, %p (%x)\n", This, dwCookie);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI NSTC2_fnInsertRoot(INameSpaceTreeControl2* iface,
+                                         int iIndex,
+                                         IShellItem *psiRoot,
+                                         SHCONTF grfEnumFlags,
+                                         NSTCROOTSTYLE grfRootStyle,
+                                         IShellItemFilter *pif)
+{
+    NSTC2Impl *This = (NSTC2Impl*)iface;
+    FIXME("stub, %p, %p, %x, %x, %p\n",
+          This, psiRoot, grfEnumFlags, grfRootStyle, pif);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI NSTC2_fnAppendRoot(INameSpaceTreeControl2* iface,
+                                         IShellItem *psiRoot,
+                                         SHCONTF grfEnumFlags,
+                                         NSTCROOTSTYLE grfRootStyle,
+                                         IShellItemFilter *pif)
+{
+    NSTC2Impl *This = (NSTC2Impl*)iface;
+    FIXME("stub, %p, %p, %x, %x, %p\n",
+          This, psiRoot, grfEnumFlags, grfRootStyle, pif);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI NSTC2_fnRemoveRoot(INameSpaceTreeControl2* iface,
+                                         IShellItem *psiRoot)
+{
+    NSTC2Impl *This = (NSTC2Impl*)iface;
+    FIXME("stub, %p (%p)\n", This, psiRoot);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI NSTC2_fnRemoveAllRoots(INameSpaceTreeControl2* iface)
+{
+    NSTC2Impl *This = (NSTC2Impl*)iface;
+    FIXME("stub, %p\n", This);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI NSTC2_fnGetRootItems(INameSpaceTreeControl2* iface,
+                                           IShellItemArray **ppsiaRootItems)
+{
+    NSTC2Impl *This = (NSTC2Impl*)iface;
+    FIXME("stub, %p (%p)\n", This, ppsiaRootItems);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI NSTC2_fnSetItemState(INameSpaceTreeControl2* iface,
+                                           IShellItem *psi,
+                                           NSTCITEMSTATE nstcisMask,
+                                           NSTCITEMSTATE nstcisFlags)
+{
+    NSTC2Impl *This = (NSTC2Impl*)iface;
+    FIXME("stub, %p (%p, %x, %x)\n", This, psi, nstcisMask, nstcisFlags);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI NSTC2_fnGetItemState(INameSpaceTreeControl2* iface,
+                                           IShellItem *psi,
+                                           NSTCITEMSTATE nstcisMask,
+                                           NSTCITEMSTATE *pnstcisFlags)
+{
+    NSTC2Impl *This = (NSTC2Impl*)iface;
+    FIXME("stub, %p (%p, %x, %p)\n", This, psi, nstcisMask, pnstcisFlags);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI NSTC2_fnGetSelectedItems(INameSpaceTreeControl2* iface,
+                                               IShellItemArray **psiaItems)
+{
+    NSTC2Impl *This = (NSTC2Impl*)iface;
+    FIXME("stub, %p (%p)\n", This, psiaItems);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI NSTC2_fnGetItemCustomState(INameSpaceTreeControl2* iface,
+                                                 IShellItem *psi,
+                                                 int *piStateNumber)
+{
+    NSTC2Impl *This = (NSTC2Impl*)iface;
+    FIXME("stub, %p (%p, %p)\n", This, psi, piStateNumber);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI NSTC2_fnSetItemCustomState(INameSpaceTreeControl2* iface,
+                                                 IShellItem *psi,
+                                                 int iStateNumber)
+{
+    NSTC2Impl *This = (NSTC2Impl*)iface;
+    FIXME("stub, %p (%p, %d)\n", This, psi, iStateNumber);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI NSTC2_fnEnsureItemVisible(INameSpaceTreeControl2* iface,
+                                                IShellItem *psi)
+{
+    NSTC2Impl *This = (NSTC2Impl*)iface;
+    FIXME("stub, %p (%p)\n", This, psi);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI NSTC2_fnSetTheme(INameSpaceTreeControl2* iface,
+                                       LPCWSTR pszTheme)
+{
+    NSTC2Impl *This = (NSTC2Impl*)iface;
+    FIXME("stub, %p (%p)\n", This, pszTheme);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI NSTC2_fnGetNextItem(INameSpaceTreeControl2* iface,
+                                          IShellItem *psi,
+                                          NSTCGNI nstcgi,
+                                          IShellItem **ppsiNext)
+{
+    NSTC2Impl *This = (NSTC2Impl*)iface;
+    FIXME("stub, %p (%p, %x, %p)\n", This, psi, nstcgi, ppsiNext);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI NSTC2_fnHitTest(INameSpaceTreeControl2* iface,
+                                      POINT *ppt,
+                                      IShellItem **ppsiOut)
+{
+    NSTC2Impl *This = (NSTC2Impl*)iface;
+    FIXME("stub, %p (%p, %p)\n", This, ppsiOut, ppt);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI NSTC2_fnGetItemRect(INameSpaceTreeControl2* iface,
+                                          IShellItem *psi,
+                                          RECT *prect)
+{
+    NSTC2Impl *This = (NSTC2Impl*)iface;
+    FIXME("stub, %p (%p, %p)\n", This, psi, prect);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI NSTC2_fnCollapseAll(INameSpaceTreeControl2* iface)
+{
+    NSTC2Impl *This = (NSTC2Impl*)iface;
+    FIXME("stub, %p\n", This);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI NSTC2_fnSetControlStyle(INameSpaceTreeControl2* iface,
+                                              NSTCSTYLE nstcsMask,
+                                              NSTCSTYLE nstcsStyle)
+{
+    NSTC2Impl *This = (NSTC2Impl*)iface;
+    FIXME("stub, %p (%x, %x)\n", This, nstcsMask, nstcsStyle);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI NSTC2_fnGetControlStyle(INameSpaceTreeControl2* iface,
+                                              NSTCSTYLE nstcsMask,
+                                              NSTCSTYLE *pnstcsStyle)
+{
+    NSTC2Impl *This = (NSTC2Impl*)iface;
+    FIXME("stub, %p (%x, %p)\n", This, nstcsMask, pnstcsStyle);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI NSTC2_fnSetControlStyle2(INameSpaceTreeControl2* iface,
+                                               NSTCSTYLE2 nstcsMask,
+                                               NSTCSTYLE2 nstcsStyle)
+{
+    NSTC2Impl *This = (NSTC2Impl*)iface;
+    FIXME("stub, %p (%x, %x)\n", This, nstcsMask, nstcsStyle);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI NSTC2_fnGetControlStyle2(INameSpaceTreeControl2* iface,
+                                               NSTCSTYLE2 nstcsMask,
+                                               NSTCSTYLE2 *pnstcsStyle)
+{
+    NSTC2Impl *This = (NSTC2Impl*)iface;
+    FIXME("stub, %p (%x, %p)\n", This, nstcsMask, pnstcsStyle);
+    return E_NOTIMPL;
+}
+
+static const INameSpaceTreeControl2Vtbl vt_INameSpaceTreeControl2 = {
+    NSTC2_fnQueryInterface,
+    NSTC2_fnAddRef,
+    NSTC2_fnRelease,
+    NSTC2_fnInitialize,
+    NSTC2_fnTreeAdvise,
+    NSTC2_fnTreeUnadvise,
+    NSTC2_fnAppendRoot,
+    NSTC2_fnInsertRoot,
+    NSTC2_fnRemoveRoot,
+    NSTC2_fnRemoveAllRoots,
+    NSTC2_fnGetRootItems,
+    NSTC2_fnSetItemState,
+    NSTC2_fnGetItemState,
+    NSTC2_fnGetSelectedItems,
+    NSTC2_fnGetItemCustomState,
+    NSTC2_fnSetItemCustomState,
+    NSTC2_fnEnsureItemVisible,
+    NSTC2_fnSetTheme,
+    NSTC2_fnGetNextItem,
+    NSTC2_fnHitTest,
+    NSTC2_fnGetItemRect,
+    NSTC2_fnCollapseAll,
+    NSTC2_fnSetControlStyle,
+    NSTC2_fnGetControlStyle,
+    NSTC2_fnSetControlStyle2,
+    NSTC2_fnGetControlStyle2
+};
+
+HRESULT NamespaceTreeControl_Constructor(IUnknown *pUnkOuter, REFIID riid, void **ppv)
+{
+    NSTC2Impl *nstc;
+    HRESULT ret;
+
+    TRACE ("%p %s %p\n", pUnkOuter, debugstr_guid(riid), ppv);
+
+    if(!ppv)
+        return E_POINTER;
+    if(pUnkOuter)
+        return CLASS_E_NOAGGREGATION;
+
+    EFRAME_LockModule();
+
+    nstc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(NSTC2Impl));
+    nstc->ref = 1;
+    nstc->lpVtbl = &vt_INameSpaceTreeControl2;
+
+    ret = INameSpaceTreeControl_QueryInterface((INameSpaceTreeControl*)nstc, riid, ppv);
+    INameSpaceTreeControl_Release((INameSpaceTreeControl*)nstc);
+
+    TRACE("--(%p)\n", ppv);
+    return ret;
+}
diff --git a/dlls/explorerframe/tests/Makefile.in b/dlls/explorerframe/tests/Makefile.in
new file mode 100644
index 0000000..3385029
--- /dev/null
+++ b/dlls/explorerframe/tests/Makefile.in
@@ -0,0 +1,11 @@
+TOPSRCDIR = @top_srcdir@
+TOPOBJDIR = ../../..
+SRCDIR    = @srcdir@
+VPATH     = @srcdir@
+TESTDLL   = explorerframe.dll
+IMPORTS   = uuid shell32 ole32 oleaut32 user32 advapi32 kernel32
+
+C_SRCS = \
+	nstc.c
+
+ at MAKE_TEST_RULES@
diff --git a/dlls/explorerframe/tests/nstc.c b/dlls/explorerframe/tests/nstc.c
new file mode 100644
index 0000000..fdb9d15
--- /dev/null
+++ b/dlls/explorerframe/tests/nstc.c
@@ -0,0 +1,100 @@
+/*
+ *    Unit tests for the NamespaceTree Control
+ *
+ * Copyright 2010 David Hedberg
+ *
+ * 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
+
+#include "shlobj.h"
+#include "wine/test.h"
+
+static HWND hwnd;
+
+/* "Intended for internal use" */
+#define TVS_EX_NOSINGLECOLLAPSE 0x1
+
+static void test_initialization(void)
+{
+    INameSpaceTreeControl2 *pnstc;
+    HRESULT hr;
+
+    hr = CoCreateInstance(&CLSID_NamespaceTreeControl, NULL, CLSCTX_INPROC_SERVER,
+                          &IID_INameSpaceTreeControl, (void**)&pnstc);
+    ok(hr == S_OK, "Failed to initialize control (0x%08x)\n", hr);
+
+    INameSpaceTreeControl_Release(pnstc);
+}
+
+static BOOL have_INameSpaceTreeControl(void)
+{
+    INameSpaceTreeControl2 *pnstc;
+    HRESULT hr;
+
+    hr = CoCreateInstance(&CLSID_NamespaceTreeControl, NULL, CLSCTX_INPROC_SERVER,
+                          &IID_INameSpaceTreeControl, (void**)&pnstc);
+
+    ok(hr == S_OK || hr == REGDB_E_CLASSNOTREG, "Got (0x%08x)\n", hr);
+    return SUCCEEDED(hr);
+}
+
+/* Set up a window for the tests */
+static LRESULT CALLBACK nstctest_wndproc(HWND hWnd, UINT uMessage,
+                                         WPARAM wParam, LPARAM lParam)
+{
+    return DefWindowProcW(hWnd, uMessage, wParam, lParam);
+}
+
+static void setup_window(void)
+{
+    WNDCLASSW wc;
+    static const WCHAR nstctest_wnd_name[] =
+        {'n','s','t','c','t','e','s','t','_','w','n','d',0};
+
+    ZeroMemory(&wc, sizeof(WNDCLASSW));
+    wc.lpfnWndProc      = nstctest_wndproc;
+    wc.lpszClassName    = nstctest_wnd_name;
+    RegisterClassW(&wc);
+    hwnd = CreateWindowExW(0, nstctest_wnd_name, NULL, WS_TABSTOP,
+                           0, 0, 200, 200, NULL, 0, 0, NULL);
+    ok(hwnd != NULL, "Failed to create window for test.\n");
+}
+
+static void destroy_window(void)
+{
+    DestroyWindow(hwnd);
+}
+
+START_TEST(nstc)
+{
+    OleInitialize(NULL);
+
+    if(!have_INameSpaceTreeControl())
+    {
+        skip("No NamespaceTree Control registered.\n");
+        OleUninitialize();
+        return;
+    }
+    setup_window();
+
+    test_initialization();
+
+    destroy_window();
+    OleUninitialize();
+}
diff --git a/tools/wine.inf.in b/tools/wine.inf.in
index c11e6e1..0b0886c 100644
--- a/tools/wine.inf.in
+++ b/tools/wine.inf.in
@@ -2505,6 +2505,7 @@ HKLM,%CurrentVersion%\Telephony\Country List\998,"SameAreaRule",,"G"
 11,,dsound.dll,1
 11,,dswave.dll,1
 11,,dxdiagn.dll,1
+11,,explorerframe.dll,1
 11,,gameux.dll,1
 11,,hhctrl.ocx,1
 11,,hlink.dll,1
-- 
1.7.2




More information about the wine-patches mailing list