2010-07-31 20:02:45 +02:00
|
|
|
/*
|
|
|
|
* ExplorerFrame main functions
|
|
|
|
*
|
|
|
|
* 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>
|
2010-07-31 20:02:50 +02:00
|
|
|
#include <stdio.h>
|
2010-07-31 20:02:45 +02:00
|
|
|
|
|
|
|
#define COBJMACROS
|
|
|
|
|
|
|
|
#include "windef.h"
|
|
|
|
#include "winbase.h"
|
2010-07-31 20:02:50 +02:00
|
|
|
#include "winuser.h"
|
2010-07-31 20:02:45 +02:00
|
|
|
#include "winreg.h"
|
|
|
|
#include "shlwapi.h"
|
2010-07-31 20:02:50 +02:00
|
|
|
#include "shobjidl.h"
|
2010-12-10 15:02:43 +01:00
|
|
|
#include "rpcproxy.h"
|
2010-07-31 20:02:45 +02:00
|
|
|
|
|
|
|
#include "wine/debug.h"
|
|
|
|
|
|
|
|
#include "explorerframe_main.h"
|
|
|
|
|
|
|
|
WINE_DEFAULT_DEBUG_CHANNEL(explorerframe);
|
|
|
|
|
|
|
|
HINSTANCE explorerframe_hinstance;
|
|
|
|
LONG EFRAME_refCount = 0;
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
* DllMain (ExplorerFrame.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI DllMain(HINSTANCE hinst, DWORD fdwReason, LPVOID fImpLoad)
|
|
|
|
{
|
2022-02-10 08:42:20 +01:00
|
|
|
TRACE("%p, 0x%lx, %p\n", hinst, fdwReason, fImpLoad);
|
2010-07-31 20:02:45 +02:00
|
|
|
switch (fdwReason)
|
|
|
|
{
|
|
|
|
case DLL_PROCESS_ATTACH:
|
|
|
|
DisableThreadLibraryCalls(hinst);
|
|
|
|
explorerframe_hinstance = hinst;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
* DllCanUnloadNow (ExplorerFrame.@)
|
|
|
|
*/
|
|
|
|
HRESULT WINAPI DllCanUnloadNow(void)
|
|
|
|
{
|
2022-02-10 08:42:20 +01:00
|
|
|
TRACE("refCount is %ld\n", EFRAME_refCount);
|
2010-07-31 20:02:45 +02:00
|
|
|
return EFRAME_refCount ? S_FALSE : S_OK;
|
|
|
|
}
|
2010-07-31 20:02:46 +02:00
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
* DllGetVersion (ExplorerFrame.@)
|
|
|
|
*/
|
|
|
|
HRESULT WINAPI DllGetVersion(DLLVERSIONINFO *info)
|
|
|
|
{
|
|
|
|
TRACE("%p\n", info);
|
|
|
|
if(info->cbSize == sizeof(DLLVERSIONINFO) ||
|
|
|
|
info->cbSize == sizeof(DLLVERSIONINFO2))
|
|
|
|
{
|
|
|
|
/* Windows 7 */
|
|
|
|
info->dwMajorVersion = 6;
|
|
|
|
info->dwMinorVersion = 1;
|
|
|
|
info->dwBuildNumber = 7600;
|
|
|
|
info->dwPlatformID = DLLVER_PLATFORM_WINDOWS;
|
|
|
|
if(info->cbSize == sizeof(DLLVERSIONINFO2))
|
|
|
|
{
|
|
|
|
DLLVERSIONINFO2 *info2 = (DLLVERSIONINFO2*)info;
|
|
|
|
info2->dwFlags = 0;
|
|
|
|
info2->ullVersion = MAKEDLLVERULL(info->dwMajorVersion,
|
|
|
|
info->dwMinorVersion,
|
|
|
|
info->dwBuildNumber,
|
|
|
|
16385); /* "hotfix number" */
|
|
|
|
}
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
WARN("wrong DLLVERSIONINFO size from app.\n");
|
|
|
|
return E_INVALIDARG;
|
|
|
|
}
|
2010-07-31 20:02:48 +02:00
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
* Implement the ExplorerFrame class factory
|
|
|
|
*/
|
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
2011-01-20 01:59:16 +01:00
|
|
|
IClassFactory IClassFactory_iface;
|
2010-07-31 20:02:48 +02:00
|
|
|
HRESULT (*cf)(IUnknown*, REFIID, void**);
|
|
|
|
LONG ref;
|
|
|
|
} IClassFactoryImpl;
|
|
|
|
|
2011-01-20 01:59:16 +01:00
|
|
|
static inline IClassFactoryImpl *impl_from_IClassFactory(IClassFactory *iface)
|
|
|
|
{
|
|
|
|
return CONTAINING_RECORD(iface, IClassFactoryImpl, IClassFactory_iface);
|
|
|
|
}
|
|
|
|
|
2010-07-31 20:02:48 +02:00
|
|
|
/*************************************************************************
|
2011-01-20 01:59:16 +01:00
|
|
|
* EFCF_QueryInterface
|
2010-07-31 20:02:48 +02:00
|
|
|
*/
|
|
|
|
static HRESULT WINAPI EFCF_QueryInterface(IClassFactory* iface,
|
|
|
|
REFIID riid, void **ppobj)
|
|
|
|
{
|
|
|
|
TRACE("%p (%s %p)\n", iface, debugstr_guid(riid), ppobj);
|
|
|
|
|
|
|
|
if(!ppobj)
|
|
|
|
return E_POINTER;
|
|
|
|
|
|
|
|
if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IClassFactory, riid))
|
|
|
|
{
|
|
|
|
*ppobj = iface;
|
|
|
|
IClassFactory_AddRef(iface);
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
WARN("Interface not supported.\n");
|
|
|
|
|
|
|
|
*ppobj = NULL;
|
|
|
|
return E_NOINTERFACE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
2011-01-20 01:59:16 +01:00
|
|
|
* EFCF_AddRef
|
2010-07-31 20:02:48 +02:00
|
|
|
*/
|
|
|
|
static ULONG WINAPI EFCF_AddRef(IClassFactory *iface)
|
|
|
|
{
|
|
|
|
EFRAME_LockModule();
|
|
|
|
|
|
|
|
return 2; /* non-heap based object */
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
2011-01-20 01:59:16 +01:00
|
|
|
* EFCF_Release
|
2010-07-31 20:02:48 +02:00
|
|
|
*/
|
|
|
|
static ULONG WINAPI EFCF_Release(IClassFactory *iface)
|
|
|
|
{
|
|
|
|
EFRAME_UnlockModule();
|
|
|
|
|
|
|
|
return 1; /* non-heap based object */
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
* EFCF_CreateInstance (IClassFactory)
|
|
|
|
*/
|
|
|
|
static HRESULT WINAPI EFCF_CreateInstance(IClassFactory *iface, IUnknown *pOuter,
|
|
|
|
REFIID riid, void **ppobj)
|
|
|
|
{
|
2011-01-20 01:59:16 +01:00
|
|
|
IClassFactoryImpl *This = impl_from_IClassFactory(iface);
|
2010-07-31 20:02:48 +02:00
|
|
|
return This->cf(pOuter, riid, ppobj);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
* EFCF_LockServer (IClassFactory)
|
|
|
|
*/
|
|
|
|
static HRESULT WINAPI EFCF_LockServer(IClassFactory *iface, BOOL dolock)
|
|
|
|
{
|
|
|
|
TRACE("%p (%d)\n", iface, dolock);
|
|
|
|
|
|
|
|
if (dolock)
|
|
|
|
EFRAME_LockModule();
|
|
|
|
else
|
|
|
|
EFRAME_UnlockModule();
|
|
|
|
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const IClassFactoryVtbl EFCF_Vtbl =
|
|
|
|
{
|
|
|
|
EFCF_QueryInterface,
|
|
|
|
EFCF_AddRef,
|
|
|
|
EFCF_Release,
|
|
|
|
EFCF_CreateInstance,
|
|
|
|
EFCF_LockServer
|
|
|
|
};
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
* DllGetClassObject (ExplorerFrame.@)
|
|
|
|
*/
|
|
|
|
HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void **ppv)
|
|
|
|
{
|
2011-01-20 01:59:16 +01:00
|
|
|
static IClassFactoryImpl NSTCClassFactory = {{&EFCF_Vtbl}, NamespaceTreeControl_Constructor};
|
2012-11-02 10:26:26 +01:00
|
|
|
static IClassFactoryImpl TaskbarListFactory = {{&EFCF_Vtbl}, TaskbarList_Constructor};
|
2010-07-31 20:02:48 +02:00
|
|
|
|
|
|
|
TRACE("%s, %s, %p\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
|
|
|
|
|
|
|
|
if(IsEqualGUID(&CLSID_NamespaceTreeControl, rclsid))
|
2011-01-20 01:59:16 +01:00
|
|
|
return IClassFactory_QueryInterface(&NSTCClassFactory.IClassFactory_iface, riid, ppv);
|
2010-07-31 20:02:48 +02:00
|
|
|
|
2012-11-02 10:26:26 +01:00
|
|
|
if(IsEqualGUID(&CLSID_TaskbarList, rclsid))
|
|
|
|
return IClassFactory_QueryInterface(&TaskbarListFactory.IClassFactory_iface, riid, ppv);
|
|
|
|
|
2010-07-31 20:02:48 +02:00
|
|
|
return CLASS_E_CLASSNOTAVAILABLE;
|
|
|
|
}
|