From bd50edb2a5a99e31e324bae989f1656554a8a760 Mon Sep 17 00:00:00 2001 From: Dmitry Chapyshev Date: Wed, 6 Feb 2008 17:29:28 +0000 Subject: [PATCH] - Import atl.dll from Wine - Add atl to bootcd svn path=/trunk/; revision=32163 --- reactos/baseaddress.rbuild | 1 + reactos/boot/bootdata/packages/reactos.dff | 1 + reactos/dll/win32/atl/atl.rbuild | 27 + reactos/dll/win32/atl/atl.rgs | 17 + reactos/dll/win32/atl/atl.spec | 52 + reactos/dll/win32/atl/atl_ax.c | 1306 ++++++++++++++++++++ reactos/dll/win32/atl/atl_main.c | 568 +++++++++ reactos/dll/win32/atl/atlbase.h | 166 +++ reactos/dll/win32/atl/atliface.idl | 79 ++ reactos/dll/win32/atl/atlwin.h | 53 + reactos/dll/win32/atl/registrar.c | 848 +++++++++++++ reactos/dll/win32/atl/rsrc.rc | 20 + reactos/dll/win32/win32.rbuild | 3 + 13 files changed, 3141 insertions(+) create mode 100644 reactos/dll/win32/atl/atl.rbuild create mode 100644 reactos/dll/win32/atl/atl.rgs create mode 100644 reactos/dll/win32/atl/atl.spec create mode 100644 reactos/dll/win32/atl/atl_ax.c create mode 100644 reactos/dll/win32/atl/atl_main.c create mode 100644 reactos/dll/win32/atl/atlbase.h create mode 100644 reactos/dll/win32/atl/atliface.idl create mode 100644 reactos/dll/win32/atl/atlwin.h create mode 100644 reactos/dll/win32/atl/registrar.c create mode 100644 reactos/dll/win32/atl/rsrc.rc diff --git a/reactos/baseaddress.rbuild b/reactos/baseaddress.rbuild index 00e2219ab93..5ea80b4f744 100644 --- a/reactos/baseaddress.rbuild +++ b/reactos/baseaddress.rbuild @@ -1,6 +1,7 @@ + diff --git a/reactos/boot/bootdata/packages/reactos.dff b/reactos/boot/bootdata/packages/reactos.dff index 8cbd4fd09c1..34c00fea385 100644 --- a/reactos/boot/bootdata/packages/reactos.dff +++ b/reactos/boot/bootdata/packages/reactos.dff @@ -167,6 +167,7 @@ dll\win32\acledit\acledit.dll 1 dll\win32\aclui\aclui.dll 1 dll\win32\advapi32\advapi32.dll 1 dll\win32\advpack\advpack.dll 1 +dll\win32\atl\atl.dll 1 dll\win32\authz\authz.dll 1 dll\win32\avifil32\avifil32.dll 1 dll\win32\beepmidi\beepmidi.dll 1 diff --git a/reactos/dll/win32/atl/atl.rbuild b/reactos/dll/win32/atl/atl.rbuild new file mode 100644 index 00000000000..e4fe52b6fa7 --- /dev/null +++ b/reactos/dll/win32/atl/atl.rbuild @@ -0,0 +1,27 @@ + + + . + include/reactos/wine + + + + 0x600 + 0x600 + 0x501 + wine + ole32 + oleaut32 + user32 + gdi32 + advapi32 + kernel32 + uuid + ntdll + atl_ax.c + atl_main.c + registrar.c + rsrc.rc + atliface.idl + . + atl.spec + \ No newline at end of file diff --git a/reactos/dll/win32/atl/atl.rgs b/reactos/dll/win32/atl/atl.rgs new file mode 100644 index 00000000000..8b1d476b20d --- /dev/null +++ b/reactos/dll/win32/atl/atl.rgs @@ -0,0 +1,17 @@ +HKCR +{ + ATL.Registrar = s 'Registrar Class' + { + CLSID = s '%CLSID_ATLRegistrar%' + } + NoRemove CLSID { + ForceRemove '%CLSID_ATLRegistrar%' = s 'Registrar Class' + { + ProgID = s 'ATL.Registrar' + InprocServer32 = s '%MODULE%' + { + val ThreadingModel = s 'Both' + } + } + } +} diff --git a/reactos/dll/win32/atl/atl.spec b/reactos/dll/win32/atl/atl.spec new file mode 100644 index 00000000000..27fb1710314 --- /dev/null +++ b/reactos/dll/win32/atl/atl.spec @@ -0,0 +1,52 @@ +1 stdcall -private DllCanUnloadNow() +2 stdcall -private DllGetClassObject(ptr ptr ptr) +3 stdcall -private DllRegisterServer() +4 stdcall -private DllUnregisterServer() +10 stdcall AtlAdvise(ptr ptr ptr ptr) +11 stdcall AtlUnadvise(ptr ptr long) +12 stdcall AtlFreeMarshalStream(ptr) +13 stdcall AtlMarshalPtrInProc(ptr ptr ptr) +14 stdcall AtlUnmarshalPtr(ptr ptr ptr) +15 stdcall AtlModuleGetClassObject(ptr ptr ptr ptr) +16 stdcall AtlModuleInit(ptr long long) +17 stdcall AtlModuleRegisterClassObjects(ptr long long) +18 stdcall AtlModuleRegisterServer(ptr long ptr) +19 stdcall AtlModuleRegisterTypeLib(ptr wstr) +20 stdcall AtlModuleRevokeClassObjects(ptr) +21 stdcall AtlModuleTerm(ptr) +22 stdcall AtlModuleUnregisterServer(ptr ptr) +23 stdcall AtlModuleUpdateRegistryFromResourceD(ptr wstr long ptr ptr) +24 stub AtlWaitWithMessageLoop +25 stub AtlSetErrorInfo +26 stub AtlCreateTargetDC +27 stdcall AtlHiMetricToPixel(ptr ptr) +28 stdcall AtlPixelToHiMetric(ptr ptr) +29 stub AtlDevModeW2A +30 stdcall AtlComPtrAssign(ptr ptr) +31 stdcall AtlComQIPtrAssign(ptr ptr ptr) +32 stdcall AtlInternalQueryInterface(ptr ptr ptr ptr) +34 stub AtlGetVersion +35 stub AtlAxDialogBoxW +36 stub AtlAxDialogBoxA +37 stdcall AtlAxCreateDialogW(long wstr long ptr long) +38 stdcall AtlAxCreateDialogA(long str long ptr long) +39 stdcall AtlAxCreateControl(ptr ptr ptr ptr) +40 stdcall AtlAxCreateControlEx(ptr ptr ptr ptr ptr ptr ptr) +41 stdcall AtlAxAttachControl(ptr ptr ptr) +42 stdcall AtlAxWinInit() +43 stdcall AtlModuleAddCreateWndData(ptr ptr ptr) +44 stdcall AtlModuleExtractCreateWndData(ptr) +45 stdcall AtlModuleRegisterWndClassInfoW(ptr ptr ptr) +46 stub AtlModuleRegisterWndClassInfoA +47 stdcall AtlAxGetControl(long ptr) +48 stdcall AtlAxGetHost(long ptr) +49 stub AtlRegisterClassCategoriesHelper +50 stdcall AtlIPersistStreamInit_Load(ptr ptr ptr ptr) +51 stdcall AtlIPersistStreamInit_Save(ptr long ptr ptr ptr) +52 stub AtlIPersistPropertyBag_Load +53 stub AtlIPersistPropertyBag_Save +54 stub AtlGetObjectSourceInterface +55 stub AtlModuleUnRegisterTypeLib +56 stdcall AtlModuleLoadTypeLib(ptr wstr ptr ptr) +57 stdcall AtlModuleUnregisterServerEx(ptr long ptr) +58 stdcall AtlModuleAddTermFunc(ptr ptr long) diff --git a/reactos/dll/win32/atl/atl_ax.c b/reactos/dll/win32/atl/atl_ax.c new file mode 100644 index 00000000000..6ffccdec683 --- /dev/null +++ b/reactos/dll/win32/atl/atl_ax.c @@ -0,0 +1,1306 @@ +/* + * Active Template Library ActiveX functions (atl.dll) + * + * Copyright 2006 Andrey Turkin + * + * 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 +#include + +#define COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "winerror.h" +#include "winuser.h" +#include "wine/debug.h" +#include "objbase.h" +#include "objidl.h" +#include "ole2.h" +#include "exdisp.h" +#include "atlbase.h" +#include "atliface.h" +#include "atlwin.h" + +#include "wine/unicode.h" + +WINE_DEFAULT_DEBUG_CHANNEL(atl); + +typedef struct IOCS { + const IOleClientSiteVtbl *lpOleClientSiteVtbl; + const IOleContainerVtbl *lpOleContainerVtbl; + const IOleInPlaceSiteWindowlessVtbl *lpOleInPlaceSiteWindowlessVtbl; + const IOleInPlaceFrameVtbl *lpOleInPlaceFrameVtbl; + const IOleControlSiteVtbl *lpOleControlSiteVtbl; + + LONG ref; + HWND hWnd; + IOleObject *control; + RECT size; + WNDPROC OrigWndProc; + BOOL fActive, fInPlace, fWindowless; +} IOCS; + +/********************************************************************** + * AtlAxWin class window procedure + */ +static LRESULT CALLBACK AtlAxWin_wndproc( HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam ) +{ + if ( wMsg == WM_CREATE ) + { + DWORD len = GetWindowTextLengthW( hWnd ) + 1; + WCHAR *ptr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) ); + if (!ptr) + return 1; + GetWindowTextW( hWnd, ptr, len ); + AtlAxCreateControlEx( ptr, hWnd, NULL, NULL, NULL, NULL, NULL ); + HeapFree( GetProcessHeap(), 0, ptr ); + return 0; + } + return DefWindowProcW( hWnd, wMsg, wParam, lParam ); +} + +/*********************************************************************** + * AtlAxWinInit [ATL.@] + * Initializes the control-hosting code: registering the AtlAxWin, + * AtlAxWin7 and AtlAxWinLic7 window classes and some messages. + * + * RETURNS + * TRUE or FALSE + */ + +BOOL WINAPI AtlAxWinInit(void) +{ + WNDCLASSEXW wcex; + const WCHAR AtlAxWin[] = {'A','t','l','A','x','W','i','n',0}; + + FIXME("semi-stub\n"); + + if ( FAILED( OleInitialize(NULL) ) ) + return FALSE; + + wcex.cbSize = sizeof(wcex); + wcex.style = 0; + wcex.cbClsExtra = 0; + wcex.cbWndExtra = 0; + wcex.hInstance = GetModuleHandleW( NULL ); + wcex.hIcon = NULL; + wcex.hCursor = NULL; + wcex.hbrBackground = NULL; + wcex.lpszMenuName = NULL; + wcex.hIconSm = 0; + + wcex.lpfnWndProc = AtlAxWin_wndproc; + wcex.lpszClassName = AtlAxWin; + if ( !RegisterClassExW( &wcex ) ) + return FALSE; + + return TRUE; +} + +/*********************************************************************** + * Atl container component implementation + */ + + +static ULONG WINAPI IOCS_AddRef(IOCS *This) +{ + ULONG ref = InterlockedIncrement(&This->ref); + + TRACE( "(%p) : AddRef from %d\n", This, ref - 1 ); + + return ref; +} + +#define THIS2IOLECLIENTSITE(This) ((IOleClientSite*)&This->lpOleClientSiteVtbl) +#define THIS2IOLECONTAINER(This) ((IOleContainer*)&This->lpOleContainerVtbl) +#define THIS2IOLEINPLACESITEWINDOWLESS(This) ((IOleInPlaceSiteWindowless*)&This->lpOleInPlaceSiteWindowlessVtbl) +#define THIS2IOLEINPLACEFRAME(This) ((IOleInPlaceFrame*)&This->lpOleInPlaceFrameVtbl) +#define THIS2IOLECONTROLSITE(This) ((IOleControlSite*)&This->lpOleControlSiteVtbl) + +static HRESULT WINAPI IOCS_QueryInterface(IOCS *This, REFIID riid, void **ppv) +{ + *ppv = NULL; + + if ( IsEqualIID( &IID_IUnknown, riid ) + || IsEqualIID( &IID_IOleClientSite, riid ) ) + { + *ppv = THIS2IOLECLIENTSITE(This); + } else if ( IsEqualIID( &IID_IOleContainer, riid ) ) + { + *ppv = THIS2IOLECONTAINER(This); + } else if ( IsEqualIID( &IID_IOleInPlaceSite, riid ) || IsEqualIID( &IID_IOleInPlaceSiteEx, riid ) || IsEqualIID( &IID_IOleInPlaceSiteWindowless, riid ) ) + { + *ppv = THIS2IOLEINPLACESITEWINDOWLESS(This); + } else if ( IsEqualIID( &IID_IOleInPlaceFrame, riid ) ) + { + *ppv = THIS2IOLEINPLACEFRAME(This); + } else if ( IsEqualIID( &IID_IOleControlSite, riid ) ) + { + *ppv = THIS2IOLECONTROLSITE(This); + } + + if (*ppv) + { + IOCS_AddRef( This ); + return S_OK; + } + + WARN("unsupported interface %s\n", debugstr_guid( riid ) ); + *ppv = NULL; + return E_NOINTERFACE; +} + +static HRESULT IOCS_Detach( IOCS *This ); +static ULONG WINAPI IOCS_Release(IOCS *This) +{ + ULONG ref = InterlockedDecrement(&This->ref); + + TRACE( "(%p) : ReleaseRef to %d\n", This, ref ); + + if (!ref) + { + IOCS_Detach( This ); + HeapFree( GetProcessHeap(), 0, This ); + } + + return ref; +} + +#define DEFINE_THIS(cls,ifc,iface) ((cls*)((BYTE*)(iface)-offsetof(cls,lp ## ifc ## Vtbl))) + +/****** IOleClientSite *****/ +#undef IFACE2THIS +#define IFACE2THIS(iface) DEFINE_THIS(IOCS,OleClientSite, iface) +static HRESULT WINAPI OleClientSite_QueryInterface(IOleClientSite *iface, REFIID riid, void **ppv) +{ + IOCS *This = IFACE2THIS(iface); + return IOCS_QueryInterface(This, riid, ppv); +} +static ULONG WINAPI OleClientSite_AddRef(IOleClientSite *iface) +{ + IOCS *This = IFACE2THIS(iface); + return IOCS_AddRef(This); +} +static ULONG WINAPI OleClientSite_Release(IOleClientSite *iface) +{ + IOCS *This = IFACE2THIS(iface); + return IOCS_Release(This); +} +static HRESULT WINAPI OleClientSite_SaveObject(IOleClientSite *iface) +{ + IOCS *This = IFACE2THIS(iface); + FIXME( "(%p) - stub\n", This ); + return E_NOTIMPL; +} +static HRESULT WINAPI OleClientSite_GetMoniker(IOleClientSite *iface, DWORD dwAssign, DWORD dwWhichMoniker, IMoniker **ppmk) +{ + IOCS *This = IFACE2THIS(iface); + + FIXME( "(%p, 0x%x, 0x%x, %p)\n", This, dwAssign, dwWhichMoniker, ppmk ); + return E_NOTIMPL; +} +static HRESULT WINAPI OleClientSite_GetContainer(IOleClientSite *iface, IOleContainer **ppContainer) +{ + IOCS *This = IFACE2THIS(iface); + TRACE( "(%p, %p)\n", This, ppContainer ); + return OleClientSite_QueryInterface( iface, &IID_IOleContainer, (void**)ppContainer ); +} +static HRESULT WINAPI OleClientSite_ShowObject(IOleClientSite *iface) +{ + IOCS *This = IFACE2THIS(iface); + FIXME( "(%p) - stub\n", This ); + return S_OK; +} +static HRESULT WINAPI OleClientSite_OnShowWindow(IOleClientSite *iface, BOOL fShow) +{ + IOCS *This = IFACE2THIS(iface); + FIXME( "(%p, %s) - stub\n", This, fShow ? "TRUE" : "FALSE" ); + return E_NOTIMPL; +} +static HRESULT WINAPI OleClientSite_RequestNewObjectLayout(IOleClientSite *iface) +{ + IOCS *This = IFACE2THIS(iface); + FIXME( "(%p) - stub\n", This ); + return E_NOTIMPL; +} +#undef IFACE2THIS + + +/****** IOleContainer *****/ +#define IFACE2THIS(iface) DEFINE_THIS(IOCS, OleContainer, iface) +static HRESULT WINAPI OleContainer_QueryInterface( IOleContainer* iface, REFIID riid, void** ppv) +{ + IOCS *This = IFACE2THIS(iface); + return IOCS_QueryInterface( This, riid, ppv ); +} +static ULONG WINAPI OleContainer_AddRef(IOleContainer* iface) +{ + IOCS *This = IFACE2THIS(iface); + return IOCS_AddRef(This); +} +static ULONG WINAPI OleContainer_Release(IOleContainer* iface) +{ + IOCS *This = IFACE2THIS(iface); + return IOCS_Release(This); +} +static HRESULT WINAPI OleContainer_ParseDisplayName(IOleContainer* iface, IBindCtx* pbc, + LPOLESTR pszDisplayName, ULONG* pchEaten, IMoniker** ppmkOut) +{ + IOCS *This = IFACE2THIS(iface); + FIXME( "(%p,%p,%s,%p,%p) - stub\n", This, pbc, debugstr_w(pszDisplayName), pchEaten, ppmkOut ); + return E_NOTIMPL; +} +static HRESULT WINAPI OleContainer_EnumObjects(IOleContainer* iface, DWORD grfFlags, IEnumUnknown** ppenum) +{ + IOCS *This = IFACE2THIS(iface); + FIXME( "(%p, %u, %p) - stub\n", This, grfFlags, ppenum ); + return E_NOTIMPL; +} +static HRESULT WINAPI OleContainer_LockContainer(IOleContainer* iface, BOOL fLock) +{ + IOCS *This = IFACE2THIS(iface); + FIXME( "(%p, %s) - stub\n", This, fLock?"TRUE":"FALSE" ); + return E_NOTIMPL; +} +#undef IFACE2THIS + + +/****** IOleInPlaceSiteWindowless *******/ +#define IFACE2THIS(iface) DEFINE_THIS(IOCS, OleInPlaceSiteWindowless, iface) +static HRESULT WINAPI OleInPlaceSiteWindowless_QueryInterface(IOleInPlaceSiteWindowless *iface, REFIID riid, void **ppv) +{ + IOCS *This = IFACE2THIS(iface); + return IOCS_QueryInterface(This, riid, ppv); +} +static ULONG WINAPI OleInPlaceSiteWindowless_AddRef(IOleInPlaceSiteWindowless *iface) +{ + IOCS *This = IFACE2THIS(iface); + return IOCS_AddRef(This); +} +static ULONG WINAPI OleInPlaceSiteWindowless_Release(IOleInPlaceSiteWindowless *iface) +{ + IOCS *This = IFACE2THIS(iface); + return IOCS_Release(This); +} +static HRESULT WINAPI OleInPlaceSiteWindowless_GetWindow(IOleInPlaceSiteWindowless* iface, HWND* phwnd) +{ + IOCS *This = IFACE2THIS(iface); + + TRACE("(%p,%p)\n", This, phwnd); + *phwnd = This->hWnd; + return S_OK; +} +static HRESULT WINAPI OleInPlaceSiteWindowless_ContextSensitiveHelp(IOleInPlaceSiteWindowless* iface, BOOL fEnterMode) +{ + IOCS *This = IFACE2THIS(iface); + FIXME("(%p,%d) - stub\n", This, fEnterMode); + return E_NOTIMPL; +} +static HRESULT WINAPI OleInPlaceSiteWindowless_CanInPlaceActivate(IOleInPlaceSiteWindowless *iface) +{ + IOCS *This = IFACE2THIS(iface); + TRACE("(%p)\n", This); + return S_OK; +} +static HRESULT WINAPI OleInPlaceSiteWindowless_OnInPlaceActivate(IOleInPlaceSiteWindowless *iface) +{ + IOCS *This = IFACE2THIS(iface); + + TRACE("(%p)\n", This); + + This->fInPlace = TRUE; + return S_OK; +} +static HRESULT WINAPI OleInPlaceSiteWindowless_OnUIActivate(IOleInPlaceSiteWindowless *iface) +{ + IOCS *This = IFACE2THIS(iface); + + TRACE("(%p)\n", This); + + return S_OK; +} +static HRESULT WINAPI OleInPlaceSiteWindowless_GetWindowContext(IOleInPlaceSiteWindowless *iface, + IOleInPlaceFrame **ppFrame, IOleInPlaceUIWindow **ppDoc, LPRECT lprcPosRect, + LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO lpFrameInfo) +{ + IOCS *This = IFACE2THIS(iface); + + TRACE("(%p,%p,%p,%p,%p,%p)\n", This, ppFrame, ppDoc, lprcPosRect, lprcClipRect, lpFrameInfo); + + if ( lprcClipRect ) + memcpy(lprcClipRect, &This->size, sizeof(RECT)); + if ( lprcPosRect ) + memcpy(lprcPosRect, &This->size, sizeof(RECT)); + + if ( ppFrame ) + { + IOCS_QueryInterface( This, &IID_IOleInPlaceFrame, (void**) ppFrame ); + } + + if ( ppDoc ) + *ppDoc = NULL; + + if ( lpFrameInfo ) + { + lpFrameInfo->fMDIApp = FALSE; + lpFrameInfo->hwndFrame = This->hWnd; + lpFrameInfo->haccel = NULL; + lpFrameInfo->cAccelEntries = 0; + } + + return S_OK; +} +static HRESULT WINAPI OleInPlaceSiteWindowless_Scroll(IOleInPlaceSiteWindowless *iface, SIZE scrollExtent) +{ + IOCS *This = IFACE2THIS(iface); + FIXME("(%p) - stub\n", This); + return E_NOTIMPL; +} +static HRESULT WINAPI OleInPlaceSiteWindowless_OnUIDeactivate(IOleInPlaceSiteWindowless *iface, BOOL fUndoable) +{ + IOCS *This = IFACE2THIS(iface); + FIXME("(%p,%d) - stub\n", This, fUndoable); + return E_NOTIMPL; +} +static HRESULT WINAPI OleInPlaceSiteWindowless_OnInPlaceDeactivate(IOleInPlaceSiteWindowless *iface) +{ + IOCS *This = IFACE2THIS(iface); + + TRACE("(%p)\n", This); + + This->fInPlace = This->fWindowless = FALSE; + return S_OK; +} +static HRESULT WINAPI OleInPlaceSiteWindowless_DiscardUndoState(IOleInPlaceSiteWindowless *iface) +{ + IOCS *This = IFACE2THIS(iface); + FIXME("(%p) - stub\n", This); + return E_NOTIMPL; +} +static HRESULT WINAPI OleInPlaceSiteWindowless_DeactivateAndUndo(IOleInPlaceSiteWindowless *iface) +{ + IOCS *This = IFACE2THIS(iface); + FIXME("(%p) - stub\n", This); + return E_NOTIMPL; +} +static HRESULT WINAPI OleInPlaceSiteWindowless_OnPosRectChange(IOleInPlaceSiteWindowless *iface, LPCRECT lprcPosRect) +{ + IOCS *This = IFACE2THIS(iface); + FIXME("(%p,%p) - stub\n", This, lprcPosRect); + return E_NOTIMPL; +} +static HRESULT WINAPI OleInPlaceSiteWindowless_OnInPlaceActivateEx( IOleInPlaceSiteWindowless *iface, BOOL* pfNoRedraw, DWORD dwFlags) +{ + IOCS *This = IFACE2THIS(iface); + + TRACE("\n"); + + This->fActive = This->fInPlace = TRUE; + if ( dwFlags & ACTIVATE_WINDOWLESS ) + This->fWindowless = TRUE; + return S_OK; +} +static HRESULT WINAPI OleInPlaceSiteWindowless_OnInPlaceDeactivateEx( IOleInPlaceSiteWindowless *iface, BOOL fNoRedraw) +{ + IOCS *This = IFACE2THIS(iface); + + TRACE("\n"); + + This->fActive = This->fInPlace = This->fWindowless = FALSE; + return S_OK; +} +static HRESULT WINAPI OleInPlaceSiteWindowless_RequestUIActivate( IOleInPlaceSiteWindowless *iface) +{ + FIXME("\n"); + return E_NOTIMPL; +} +static HRESULT WINAPI OleInPlaceSiteWindowless_CanWindowlessActivate( IOleInPlaceSiteWindowless *iface) +{ + FIXME("\n"); + return S_OK; +} +static HRESULT WINAPI OleInPlaceSiteWindowless_GetCapture( IOleInPlaceSiteWindowless *iface) +{ + FIXME("\n"); + return E_NOTIMPL; +} +static HRESULT WINAPI OleInPlaceSiteWindowless_SetCapture( IOleInPlaceSiteWindowless *iface, BOOL fCapture) +{ + FIXME("\n"); + return E_NOTIMPL; +} +static HRESULT WINAPI OleInPlaceSiteWindowless_GetFocus( IOleInPlaceSiteWindowless *iface) +{ + FIXME("\n"); + return E_NOTIMPL; +} +static HRESULT WINAPI OleInPlaceSiteWindowless_SetFocus( IOleInPlaceSiteWindowless *iface, BOOL fFocus) +{ + FIXME("\n"); + return E_NOTIMPL; +} +static HRESULT WINAPI OleInPlaceSiteWindowless_GetDC( IOleInPlaceSiteWindowless *iface, LPCRECT pRect, DWORD grfFlags, HDC* phDC) +{ + FIXME("\n"); + return E_NOTIMPL; +} +static HRESULT WINAPI OleInPlaceSiteWindowless_ReleaseDC( IOleInPlaceSiteWindowless *iface, HDC hDC) +{ + FIXME("\n"); + return E_NOTIMPL; +} +static HRESULT WINAPI OleInPlaceSiteWindowless_InvalidateRect( IOleInPlaceSiteWindowless *iface, LPCRECT pRect, BOOL fErase) +{ + FIXME("\n"); + return E_NOTIMPL; +} +static HRESULT WINAPI OleInPlaceSiteWindowless_InvalidateRgn( IOleInPlaceSiteWindowless *iface, HRGN hRGN, BOOL fErase) +{ + FIXME("\n"); + return E_NOTIMPL; +} +static HRESULT WINAPI OleInPlaceSiteWindowless_ScrollRect( IOleInPlaceSiteWindowless *iface, INT dx, INT dy, LPCRECT pRectScroll, LPCRECT pRectClip) +{ + FIXME("\n"); + return E_NOTIMPL; +} +static HRESULT WINAPI OleInPlaceSiteWindowless_AdjustRect( IOleInPlaceSiteWindowless *iface, LPRECT prc) +{ + FIXME("\n"); + return E_NOTIMPL; +} +static HRESULT WINAPI OleInPlaceSiteWindowless_OnDefWindowMessage( IOleInPlaceSiteWindowless *iface, UINT msg, WPARAM wParam, LPARAM lParam, LRESULT* plResult) +{ + FIXME("\n"); + return E_NOTIMPL; +} +#undef IFACE2THIS + + +/****** IOleInPlaceFrame *******/ +#define IFACE2THIS(iface) DEFINE_THIS(IOCS, OleInPlaceFrame, iface) +static HRESULT WINAPI OleInPlaceFrame_QueryInterface(IOleInPlaceFrame *iface, REFIID riid, void **ppv) +{ + IOCS *This = IFACE2THIS(iface); + return IOCS_QueryInterface(This, riid, ppv); +} +static ULONG WINAPI OleInPlaceFrame_AddRef(IOleInPlaceFrame *iface) +{ + IOCS *This = IFACE2THIS(iface); + return IOCS_AddRef(This); +} +static ULONG WINAPI OleInPlaceFrame_Release(IOleInPlaceFrame *iface) +{ + IOCS *This = IFACE2THIS(iface); + return IOCS_Release(This); +} +static HRESULT WINAPI OleInPlaceFrame_GetWindow(IOleInPlaceFrame *iface, HWND *phWnd) +{ + IOCS *This = IFACE2THIS(iface); + + TRACE( "(%p,%p)\n", This, phWnd ); + + *phWnd = This->hWnd; + return S_OK; +} + +static HRESULT WINAPI OleInPlaceFrame_ContextSensitiveHelp(IOleInPlaceFrame *iface, BOOL fEnterMode) +{ + IOCS *This = IFACE2THIS(iface); + + FIXME( "(%p,%d) - stub\n", This, fEnterMode ); + return E_NOTIMPL; +} + +static HRESULT WINAPI OleInPlaceFrame_GetBorder(IOleInPlaceFrame *iface, LPRECT lprectBorder) +{ + IOCS *This = IFACE2THIS(iface); + + FIXME( "(%p,%p) - stub\n", This, lprectBorder ); + return E_NOTIMPL; +} + +static HRESULT WINAPI OleInPlaceFrame_RequestBorderSpace(IOleInPlaceFrame *iface, LPCBORDERWIDTHS pborderwidths) +{ + IOCS *This = IFACE2THIS(iface); + + FIXME( "(%p,%p) - stub\n", This, pborderwidths ); + return E_NOTIMPL; +} + +static HRESULT WINAPI OleInPlaceFrame_SetBorderSpace(IOleInPlaceFrame *iface, LPCBORDERWIDTHS pborderwidths) +{ + IOCS *This = IFACE2THIS(iface); + + FIXME( "(%p,%p) - stub\n", This, pborderwidths ); + return E_NOTIMPL; +} + +static HRESULT WINAPI OleInPlaceFrame_SetActiveObject(IOleInPlaceFrame *iface, IOleInPlaceActiveObject *pActiveObject, LPCOLESTR pszObjName) +{ + IOCS *This = IFACE2THIS(iface); + + FIXME( "(%p,%p,%s) - stub\n", This, pActiveObject, debugstr_w(pszObjName) ); + return S_OK; +} + +static HRESULT WINAPI OleInPlaceFrame_InsertMenus(IOleInPlaceFrame *iface, HMENU hmenuShared, LPOLEMENUGROUPWIDTHS lpMenuWidths) +{ + IOCS *This = IFACE2THIS(iface); + + FIXME( "(%p,%p,%p) - stub\n", This, hmenuShared, lpMenuWidths ); + return E_NOTIMPL; +} + +static HRESULT WINAPI OleInPlaceFrame_SetMenu(IOleInPlaceFrame *iface, HMENU hmenuShared, HOLEMENU holemenu, HWND hwndActiveObject) +{ + IOCS *This = IFACE2THIS(iface); + + FIXME( "(%p,%p,%p,%p) - stub\n", This, hmenuShared, holemenu, hwndActiveObject ); + return E_NOTIMPL; +} +static HRESULT WINAPI OleInPlaceFrame_RemoveMenus(IOleInPlaceFrame *iface, HMENU hmenuShared) +{ + IOCS *This = IFACE2THIS(iface); + + FIXME( "(%p, %p) - stub\n", This, hmenuShared ); + return E_NOTIMPL; +} + +static HRESULT WINAPI OleInPlaceFrame_SetStatusText(IOleInPlaceFrame *iface, LPCOLESTR pszStatusText) +{ + IOCS *This = IFACE2THIS(iface); + + FIXME( "(%p, %s) - stub\n", This, debugstr_w( pszStatusText ) ); + return E_NOTIMPL; +} + +static HRESULT WINAPI OleInPlaceFrame_EnableModeless(IOleInPlaceFrame *iface, BOOL fEnable) +{ + IOCS *This = IFACE2THIS(iface); + + FIXME( "(%p, %d) - stub\n", This, fEnable ); + return E_NOTIMPL; +} + +static HRESULT WINAPI OleInPlaceFrame_TranslateAccelerator(IOleInPlaceFrame *iface, LPMSG lpmsg, WORD wID) +{ + IOCS *This = IFACE2THIS(iface); + + FIXME( "(%p, %p, %x) - stub\n", This, lpmsg, wID ); + return E_NOTIMPL; +} +#undef IFACE2THIS + + +/****** IOleControlSite *******/ +#define IFACE2THIS(iface) DEFINE_THIS(IOCS, OleControlSite, iface) +static HRESULT WINAPI OleControlSite_QueryInterface(IOleControlSite *iface, REFIID riid, void **ppv) +{ + IOCS *This = IFACE2THIS(iface); + return IOCS_QueryInterface(This, riid, ppv); +} +static ULONG WINAPI OleControlSite_AddRef(IOleControlSite *iface) +{ + IOCS *This = IFACE2THIS(iface); + return IOCS_AddRef(This); +} +static ULONG WINAPI OleControlSite_Release(IOleControlSite *iface) +{ + IOCS *This = IFACE2THIS(iface); + return IOCS_Release(This); +} +static HRESULT WINAPI OleControlSite_OnControlInfoChanged( IOleControlSite* This) +{ + FIXME( "\n" ); + return E_NOTIMPL; +} +static HRESULT WINAPI OleControlSite_LockInPlaceActive( IOleControlSite* This, BOOL fLock) +{ + FIXME( "\n" ); + return E_NOTIMPL; +} +static HRESULT WINAPI OleControlSite_GetExtendedControl( IOleControlSite* This, IDispatch** ppDisp) +{ + FIXME( "\n" ); + return E_NOTIMPL; +} +static HRESULT WINAPI OleControlSite_TransformCoords( IOleControlSite* This, POINTL* pPtlHimetric, POINTF* pPtfContainer, DWORD dwFlags) +{ + FIXME( "\n" ); + return E_NOTIMPL; +} +static HRESULT WINAPI OleControlSite_TranslateAccelerator( IOleControlSite* This, MSG* pMsg, DWORD grfModifiers) +{ + FIXME( "\n" ); + return E_NOTIMPL; +} +static HRESULT WINAPI OleControlSite_OnFocus( IOleControlSite* This, BOOL fGotFocus) +{ + FIXME( "\n" ); + return E_NOTIMPL; +} +static HRESULT WINAPI OleControlSite_ShowPropertyFrame( IOleControlSite* This) +{ + FIXME( "\n" ); + return E_NOTIMPL; +} +#undef IFACE2THIS + + + +static const IOleClientSiteVtbl OleClientSite_vtbl = { + OleClientSite_QueryInterface, + OleClientSite_AddRef, + OleClientSite_Release, + OleClientSite_SaveObject, + OleClientSite_GetMoniker, + OleClientSite_GetContainer, + OleClientSite_ShowObject, + OleClientSite_OnShowWindow, + OleClientSite_RequestNewObjectLayout +}; +static const IOleContainerVtbl OleContainer_vtbl = { + OleContainer_QueryInterface, + OleContainer_AddRef, + OleContainer_Release, + OleContainer_ParseDisplayName, + OleContainer_EnumObjects, + OleContainer_LockContainer +}; +static const IOleInPlaceSiteWindowlessVtbl OleInPlaceSiteWindowless_vtbl = { + OleInPlaceSiteWindowless_QueryInterface, + OleInPlaceSiteWindowless_AddRef, + OleInPlaceSiteWindowless_Release, + OleInPlaceSiteWindowless_GetWindow, + OleInPlaceSiteWindowless_ContextSensitiveHelp, + OleInPlaceSiteWindowless_CanInPlaceActivate, + OleInPlaceSiteWindowless_OnInPlaceActivate, + OleInPlaceSiteWindowless_OnUIActivate, + OleInPlaceSiteWindowless_GetWindowContext, + OleInPlaceSiteWindowless_Scroll, + OleInPlaceSiteWindowless_OnUIDeactivate, + OleInPlaceSiteWindowless_OnInPlaceDeactivate, + OleInPlaceSiteWindowless_DiscardUndoState, + OleInPlaceSiteWindowless_DeactivateAndUndo, + OleInPlaceSiteWindowless_OnPosRectChange, + OleInPlaceSiteWindowless_OnInPlaceActivateEx, + OleInPlaceSiteWindowless_OnInPlaceDeactivateEx, + OleInPlaceSiteWindowless_RequestUIActivate, + OleInPlaceSiteWindowless_CanWindowlessActivate, + OleInPlaceSiteWindowless_GetCapture, + OleInPlaceSiteWindowless_SetCapture, + OleInPlaceSiteWindowless_GetFocus, + OleInPlaceSiteWindowless_SetFocus, + OleInPlaceSiteWindowless_GetDC, + OleInPlaceSiteWindowless_ReleaseDC, + OleInPlaceSiteWindowless_InvalidateRect, + OleInPlaceSiteWindowless_InvalidateRgn, + OleInPlaceSiteWindowless_ScrollRect, + OleInPlaceSiteWindowless_AdjustRect, + OleInPlaceSiteWindowless_OnDefWindowMessage +}; +static const IOleInPlaceFrameVtbl OleInPlaceFrame_vtbl = +{ + OleInPlaceFrame_QueryInterface, + OleInPlaceFrame_AddRef, + OleInPlaceFrame_Release, + OleInPlaceFrame_GetWindow, + OleInPlaceFrame_ContextSensitiveHelp, + OleInPlaceFrame_GetBorder, + OleInPlaceFrame_RequestBorderSpace, + OleInPlaceFrame_SetBorderSpace, + OleInPlaceFrame_SetActiveObject, + OleInPlaceFrame_InsertMenus, + OleInPlaceFrame_SetMenu, + OleInPlaceFrame_RemoveMenus, + OleInPlaceFrame_SetStatusText, + OleInPlaceFrame_EnableModeless, + OleInPlaceFrame_TranslateAccelerator +}; +static const IOleControlSiteVtbl OleControlSite_vtbl = +{ + OleControlSite_QueryInterface, + OleControlSite_AddRef, + OleControlSite_Release, + OleControlSite_OnControlInfoChanged, + OleControlSite_LockInPlaceActive, + OleControlSite_GetExtendedControl, + OleControlSite_TransformCoords, + OleControlSite_TranslateAccelerator, + OleControlSite_OnFocus, + OleControlSite_ShowPropertyFrame +}; + +static HRESULT IOCS_Detach( IOCS *This ) /* remove subclassing */ +{ + if ( This->hWnd ) + { + SetWindowLongPtrW( This->hWnd, GWLP_WNDPROC, (ULONG_PTR) This->OrigWndProc ); + SetWindowLongPtrW( This->hWnd, GWLP_USERDATA, (LONG_PTR) NULL ); + This->hWnd = NULL; + } + if ( This->control ) + { + IOleObject *control = This->control; + + This->control = NULL; + IOleObject_SetClientSite( control, NULL ); + IOleObject_Release( control ); + } + return S_OK; +} + +static void IOCS_OnSize( IOCS* This, LPCRECT rect ) +{ + SIZEL inPix, inHi; + + This->size.left = rect->left; This->size.right = rect->right; This->size.top = rect->top; This->size.bottom = rect->bottom; + + if ( !This->control ) + return; + + inPix.cx = rect->right - rect->left; + inPix.cy = rect->bottom - rect->top; + AtlPixelToHiMetric( &inPix, &inHi ); + IOleObject_SetExtent( This->control, DVASPECT_CONTENT, &inHi ); + + if ( This->fInPlace ) + { + IOleInPlaceObject *wl; + + if ( SUCCEEDED( IOleObject_QueryInterface( This->control, &IID_IOleInPlaceObject, (void**)&wl ) ) ) + { + IOleInPlaceObject_SetObjectRects( wl, rect, rect ); + IOleInPlaceObject_Release( wl ); + } + } +} + +static void IOCS_OnShow( IOCS *This, BOOL fShow ) +{ + if (!This->control || This->fActive || !fShow ) + return; + + This->fActive = TRUE; +} + +static void IOCS_OnDraw( IOCS *This ) +{ + IViewObject *view; + + if ( !This->control || !This->fWindowless ) + return; + + if ( SUCCEEDED( IOleObject_QueryInterface( This->control, &IID_IViewObject, (void**)&view ) ) ) + { + HDC dc = GetDC( This->hWnd ); + RECTL rect; + + rect.left = This->size.left; rect.top = This->size.top; + rect.bottom = This->size.bottom; rect.right = This->size.right; + + IViewObject_Draw( view, DVASPECT_CONTENT, ~0, NULL, NULL, 0, dc, &rect, &rect, NULL, 0 ); + IViewObject_Release( view ); + ReleaseDC( This->hWnd, dc ); + } +} + +static LRESULT IOCS_OnWndProc( IOCS *This, HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) +{ + WNDPROC OrigWndProc = This->OrigWndProc; + + switch( uMsg ) + { + case WM_DESTROY: + IOCS_Detach( This ); + break; + case WM_SIZE: + { + RECT r; + r.left = r.top = 0; + r.right = LOWORD( lParam ); + r.bottom = HIWORD( lParam ); + IOCS_OnSize( This, &r ); + } + break; + case WM_SHOWWINDOW: + IOCS_OnShow( This, (BOOL) wParam ); + break; + case WM_PAINT: + IOCS_OnDraw( This ); + break; + } + + return CallWindowProcW( OrigWndProc, hWnd, uMsg, wParam, lParam ); +} + +static LRESULT CALLBACK AtlHost_wndproc( HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam ) +{ + IOCS *This = (IOCS*) GetWindowLongPtrW( hWnd, GWLP_USERDATA ); + return IOCS_OnWndProc( This, hWnd, wMsg, wParam, lParam ); +} + +static HRESULT IOCS_Attach( IOCS *This, HWND hWnd, IUnknown *pUnkControl ) /* subclass hWnd */ +{ + This->hWnd = hWnd; + IUnknown_QueryInterface( pUnkControl, &IID_IOleObject, (void**)&This->control ); + IOleObject_SetClientSite( This->control, THIS2IOLECLIENTSITE( This ) ); + SetWindowLongPtrW( hWnd, GWLP_USERDATA, (ULONG_PTR) This ); + This->OrigWndProc = (WNDPROC)SetWindowLongPtrW( hWnd, GWLP_WNDPROC, (ULONG_PTR) AtlHost_wndproc ); + + return S_OK; +} + +static HRESULT IOCS_Init( IOCS *This ) +{ + RECT rect; + static const WCHAR AXWIN[] = {'A','X','W','I','N',0}; + + IOleObject_SetHostNames( This->control, AXWIN, AXWIN ); + + GetClientRect( This->hWnd, &rect ); + IOCS_OnSize( This, &rect ); + IOleObject_DoVerb( This->control, OLEIVERB_INPLACEACTIVATE, NULL, THIS2IOLECLIENTSITE( This ), 0, This->hWnd, &rect ); + + return S_OK; +} + +/********************************************************************** + * Create new instance of Atl host component and attach it to window * + */ +static HRESULT IOCS_Create( HWND hWnd, IUnknown *pUnkControl, IOCS **ppSite ) +{ + HRESULT hr; + IOCS *This; + + *ppSite = NULL; + This = HeapAlloc(GetProcessHeap(), 0, sizeof(IOCS)); + + if (!This) + return E_OUTOFMEMORY; + + This->lpOleClientSiteVtbl = &OleClientSite_vtbl; + This->lpOleContainerVtbl = &OleContainer_vtbl; + This->lpOleInPlaceSiteWindowlessVtbl = &OleInPlaceSiteWindowless_vtbl; + This->lpOleInPlaceFrameVtbl = &OleInPlaceFrame_vtbl; + This->lpOleControlSiteVtbl = &OleControlSite_vtbl; + This->ref = 1; + + This->OrigWndProc = NULL; + This->hWnd = NULL; + This->fWindowless = This->fActive = This->fInPlace = FALSE; + + hr = IOCS_Attach( This, hWnd, pUnkControl ); + if ( SUCCEEDED( hr ) ) + hr = IOCS_Init( This ); + if ( SUCCEEDED( hr ) ) + *ppSite = This; + else + IOCS_Release( This ); + + return hr; +} + + +/*********************************************************************** + * AtlAxCreateControl [ATL.@] + */ +HRESULT WINAPI AtlAxCreateControl(LPCOLESTR lpszName, HWND hWnd, + IStream *pStream, IUnknown **ppUnkContainer) +{ + return AtlAxCreateControlEx( lpszName, hWnd, pStream, ppUnkContainer, + NULL, NULL, NULL ); +} + +/*********************************************************************** + * AtlAxCreateControlEx [ATL.@] + * + * REMARKS + * See http://www.codeproject.com/com/cwebpage.asp for some background + * + */ +HRESULT WINAPI AtlAxCreateControlEx(LPCOLESTR lpszName, HWND hWnd, + IStream *pStream, IUnknown **ppUnkContainer, IUnknown **ppUnkControl, + REFIID iidSink, IUnknown *punkSink) +{ + CLSID controlId; + HRESULT hRes; + IOleObject *pControl; + IUnknown *pUnkControl; + IPersistStreamInit *pPSInit; + IUnknown *pContainer; + enum {IsGUID=0,IsHTML=1,IsURL=2} content; + + TRACE("(%s %p %p %p %p %p %p)\n", debugstr_w(lpszName), hWnd, pStream, + ppUnkContainer, ppUnkControl, iidSink, punkSink); + + hRes = CLSIDFromString( (LPOLESTR) lpszName, &controlId ); + if ( FAILED(hRes) ) + hRes = CLSIDFromProgID( lpszName, &controlId ); + if ( SUCCEEDED( hRes ) ) + content = IsGUID; + else { + /* FIXME - check for MSHTML: prefix! */ + content = IsURL; + memcpy( &controlId, &CLSID_WebBrowser, sizeof(controlId) ); + } + + hRes = CoCreateInstance( &controlId, 0, CLSCTX_ALL, &IID_IOleObject, + (void**) &pControl ); + if ( FAILED( hRes ) ) + { + WARN( "cannot create ActiveX control %s instance - error 0x%08x\n", + debugstr_guid( &controlId ), hRes ); + return hRes; + } + + hRes = IOleObject_QueryInterface( pControl, &IID_IPersistStreamInit, (void**) &pPSInit ); + if ( SUCCEEDED( hRes ) ) + { + if (!pStream) + IPersistStreamInit_InitNew( pPSInit ); + else + IPersistStreamInit_Load( pPSInit, pStream ); + IPersistStreamInit_Release( pPSInit ); + } else + WARN("cannot get IID_IPersistStreamInit out of control\n"); + + IOleObject_QueryInterface( pControl, &IID_IUnknown, (void**) &pUnkControl ); + IOleObject_Release( pControl ); + + + hRes = AtlAxAttachControl( pUnkControl, hWnd, &pContainer ); + if ( FAILED( hRes ) ) + WARN("cannot attach control to window\n"); + + if ( content == IsURL ) + { + IWebBrowser2 *browser; + + hRes = IOleObject_QueryInterface( pControl, &IID_IWebBrowser2, (void**) &browser ); + if ( !browser ) + WARN( "Cannot query IWebBrowser2 interface: %08x\n", hRes ); + else { + VARIANT url; + + IWebBrowser2_put_Visible( browser, VARIANT_TRUE ); /* it seems that native does this on URL (but do not on MSHTML:! why? */ + + V_VT(&url) = VT_BSTR; + V_BSTR(&url) = SysAllocString( lpszName ); + + hRes = IWebBrowser2_Navigate2( browser, &url, NULL, NULL, NULL, NULL ); + if ( FAILED( hRes ) ) + WARN( "IWebBrowser2::Navigate2 failed: %08x\n", hRes ); + SysFreeString( V_BSTR(&url) ); + + IWebBrowser2_Release( browser ); + } + } + + if (ppUnkContainer) + { + *ppUnkContainer = pContainer; + if ( pContainer ) + IUnknown_AddRef( pContainer ); + } + if (ppUnkControl) + { + *ppUnkControl = pUnkControl; + if ( pUnkControl ) + IUnknown_AddRef( pUnkControl ); + } + + if ( pUnkControl ) + IUnknown_Release( pUnkControl ); + if ( pContainer ) + IUnknown_Release( pContainer ); + + return S_OK; +} + +/*********************************************************************** + * AtlAxAttachControl [ATL.@] + */ +HRESULT WINAPI AtlAxAttachControl(IUnknown* pControl, HWND hWnd, IUnknown** ppUnkContainer) +{ + IOCS *pUnkContainer; + HRESULT hr; + + TRACE( "%p %p %p\n", pControl, hWnd, ppUnkContainer ); + + *ppUnkContainer = NULL; + + hr = IOCS_Create( hWnd, pControl, &pUnkContainer ); + if ( SUCCEEDED( hr ) ) + { + *ppUnkContainer = (IUnknown*) pUnkContainer; + } + + return hr; +} + +/********************************************************************** + * Helper function for AX_ConvertDialogTemplate + */ +static inline BOOL advance_array(WORD **pptr, DWORD *palloc, DWORD *pfilled, const WORD *data, DWORD size) +{ + if ( (*pfilled + size) > *palloc ) + { + *palloc = ((*pfilled+size) + 0xFF) & ~0xFF; + *pptr = HeapReAlloc( GetProcessHeap(), 0, *pptr, *palloc * sizeof(WORD) ); + if (!*pptr) + return FALSE; + } + RtlMoveMemory( *pptr+*pfilled, data, size * sizeof(WORD) ); + *pfilled += size; + return TRUE; +} + +/********************************************************************** + * Convert ActiveX control templates to AtlAxWin class instances + */ +static LPDLGTEMPLATEW AX_ConvertDialogTemplate(LPCDLGTEMPLATEW src_tmpl) +{ +#define GET_WORD(x) (*(const WORD *)(x)) +#define GET_DWORD(x) (*(const DWORD *)(x)) +#define PUT_BLOCK(x,y) do {if (!advance_array(&output, &allocated, &filled, (x), (y))) return NULL;} while (0) +#define PUT_WORD(x) do {WORD w = (x);PUT_BLOCK(&w, 1);} while(0) +#define PUT_DWORD(x) do {DWORD w = (x);PUT_BLOCK(&w, 2);} while(0) + const WORD *tmp, *src = (const WORD *)src_tmpl; + WORD *output; + DWORD allocated, filled; /* in WORDs */ + BOOL ext; + WORD signature, dlgver, rescount; + DWORD style; + + filled = 0; allocated = 256; + output = HeapAlloc( GetProcessHeap(), 0, allocated * sizeof(WORD) ); + if (!output) + return NULL; + + /* header */ + tmp = src; + signature = GET_WORD(src); + dlgver = GET_WORD(src + 1); + if (signature == 1 && dlgver == 0xFFFF) + { + ext = TRUE; + src += 6; + style = GET_DWORD(src); + src += 2; + rescount = GET_WORD(src++); + src += 4; + if ( GET_WORD(src) == 0xFFFF ) /* menu */ + src += 2; + else + src += strlenW(src) + 1; + if ( GET_WORD(src) == 0xFFFF ) /* class */ + src += 2; + else + src += strlenW(src) + 1; + src += strlenW(src) + 1; /* title */ + if ( style & (DS_SETFONT | DS_SHELLFONT) ) + { + src += 3; + src += strlenW(src) + 1; + } + } else { + ext = FALSE; + style = GET_DWORD(src); + src += 4; + rescount = GET_WORD(src++); + src += 4; + if ( GET_WORD(src) == 0xFFFF ) /* menu */ + src += 2; + else + src += strlenW(src) + 1; + if ( GET_WORD(src) == 0xFFFF ) /* class */ + src += 2; + else + src += strlenW(src) + 1; + src += strlenW(src) + 1; /* title */ + if ( style & DS_SETFONT ) + { + src++; + src += strlenW(src) + 1; + } + } + PUT_BLOCK(tmp, src-tmp); + + while(rescount--) + { + src = (const WORD *)( ( ((ULONG_PTR)src) + 3) & ~3); /* align on DWORD boundary */ + filled = (filled + 1) & ~1; /* depends on DWORD-aligned allocation unit */ + + tmp = src; + if (ext) + src += 11; + else + src += 9; + PUT_BLOCK(tmp, src-tmp); + + tmp = src; + if ( GET_WORD(src) == 0xFFFF ) /* class */ + { + src += 2; + } else + { + src += strlenW(src) + 1; + } + src += strlenW(src) + 1; /* title */ + if ( GET_WORD(tmp) == '{' ) /* all this mess created because of this line */ + { + static const WCHAR AtlAxWin[9]={'A','t','l','A','x','W','i','n',0}; + PUT_BLOCK(AtlAxWin, sizeof(AtlAxWin)/sizeof(WCHAR)); + PUT_BLOCK(tmp, strlenW(tmp)+1); + } else + PUT_BLOCK(tmp, src-tmp); + + if ( GET_WORD(src) ) + { + WORD size = (GET_WORD(src)+sizeof(WORD)-1) / sizeof(WORD); /* quite ugly :( Maybe use BYTE* instead of WORD* everywhere ? */ + PUT_BLOCK(src, size); + src+=size; + } + else + { + PUT_WORD(0); + src++; + } + } + return (LPDLGTEMPLATEW) output; +} + +/*********************************************************************** + * AtlAxCreateDialogA [ATL.@] + * + * Creates a dialog window + * + * PARAMS + * hInst [I] Application instance + * name [I] Dialog box template name + * owner [I] Dialog box parent HWND + * dlgProc [I] Dialog box procedure + * param [I] This value will be passed to dlgProc as WM_INITDIALOG's message lParam + * + * RETURNS + * Window handle of dialog window. + */ +HWND WINAPI AtlAxCreateDialogA(HINSTANCE hInst, LPCSTR name, HWND owner, DLGPROC dlgProc ,LPARAM param) +{ + HWND res = NULL; + int length; + WCHAR *nameW; + + if ( HIWORD(name) == 0 ) + return AtlAxCreateDialogW( hInst, (LPCWSTR) name, owner, dlgProc, param ); + + length = MultiByteToWideChar( CP_ACP, 0, name, -1, NULL, 0 ); + nameW = HeapAlloc( GetProcessHeap(), 0, length * sizeof(WCHAR) ); + if (nameW) + { + MultiByteToWideChar( CP_ACP, 0, name, -1, nameW, length ); + res = AtlAxCreateDialogW( hInst, nameW, owner, dlgProc, param ); + HeapFree( GetProcessHeap(), 0, nameW ); + } + return res; +} + +/*********************************************************************** + * AtlAxCreateDialogW [ATL.@] + * + * See AtlAxCreateDialogA + * + */ +HWND WINAPI AtlAxCreateDialogW(HINSTANCE hInst, LPCWSTR name, HWND owner, DLGPROC dlgProc ,LPARAM param) +{ + HRSRC hrsrc; + HGLOBAL hgl; + LPCDLGTEMPLATEW ptr; + LPDLGTEMPLATEW newptr; + HWND res; + + FIXME("(%p %s %p %p %lx) - not tested\n", hInst, debugstr_w(name), owner, dlgProc, param); + + hrsrc = FindResourceW( hInst, name, (LPWSTR)RT_DIALOG ); + if ( !hrsrc ) + return NULL; + hgl = LoadResource (hInst, hrsrc); + if ( !hgl ) + return NULL; + ptr = (LPCDLGTEMPLATEW)LockResource ( hgl ); + if (!ptr) + { + FreeResource( hgl ); + return NULL; + } + newptr = AX_ConvertDialogTemplate( ptr ); + if ( newptr ) + { + res = CreateDialogIndirectParamW( hInst, newptr, owner, dlgProc, param ); + HeapFree( GetProcessHeap(), 0, newptr ); + } else + res = NULL; + FreeResource ( hrsrc ); + return res; +} + +/*********************************************************************** + * AtlAxGetHost [ATL.@] + * + */ +HRESULT WINAPI AtlAxGetHost(HWND hWnd, IUnknown **pUnk) +{ + IOCS *This; + + TRACE( "(%p, %p)\n", hWnd, pUnk ); + + *pUnk = NULL; + + This = (IOCS*) GetWindowLongPtrW( hWnd, GWLP_USERDATA ); + if ( !This ) + { + WARN("No container attached to %p\n", hWnd ); + return E_FAIL; + } + + return IOCS_QueryInterface( This, &IID_IUnknown, (void**) pUnk ); +} + +/*********************************************************************** + * AtlAxGetControl [ATL.@] + * + */ +HRESULT WINAPI AtlAxGetControl(HWND hWnd, IUnknown **pUnk) +{ + IOCS *This; + + TRACE( "(%p, %p)\n", hWnd, pUnk ); + + *pUnk = NULL; + + This = (IOCS*) GetWindowLongPtrW( hWnd, GWLP_USERDATA ); + if ( !This || !This->control ) + { + WARN("No control attached to %p\n", hWnd ); + return E_FAIL; + } + + return IOleObject_QueryInterface( This->control, &IID_IUnknown, (void**) pUnk ); +} diff --git a/reactos/dll/win32/atl/atl_main.c b/reactos/dll/win32/atl/atl_main.c new file mode 100644 index 00000000000..374b0d26f24 --- /dev/null +++ b/reactos/dll/win32/atl/atl_main.c @@ -0,0 +1,568 @@ +/* + * Implementation of Active Template Library (atl.dll) + * + * Copyright 2004 Aric Stewart for CodeWeavers + * + * 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 +#include + +#define COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "winerror.h" +#include "wingdi.h" +#include "winuser.h" +#include "wine/debug.h" +#include "objbase.h" +#include "objidl.h" +#include "ole2.h" +#include "atlbase.h" +#include "atliface.h" +#include "atlwin.h" + +#include "wine/unicode.h" + +WINE_DEFAULT_DEBUG_CHANNEL(atl); + +HINSTANCE hInst; + +BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) +{ + TRACE("(0x%p, %d, %p)\n",hinstDLL,fdwReason,lpvReserved); + + if (fdwReason == DLL_PROCESS_ATTACH) { + DisableThreadLibraryCalls(hinstDLL); + hInst = hinstDLL; + } + return TRUE; +} + +#define ATLVer1Size 100 + +HRESULT WINAPI AtlModuleInit(_ATL_MODULEW* pM, _ATL_OBJMAP_ENTRYW* p, HINSTANCE h) +{ + INT i; + UINT size; + + FIXME("SEMI-STUB (%p %p %p)\n",pM,p,h); + + size = pM->cbSize; + if (size != sizeof(_ATL_MODULEW) && size != ATLVer1Size) + { + FIXME("Unknown structure version (size %i)\n",size); + return E_INVALIDARG; + } + + memset(pM,0,pM->cbSize); + pM->cbSize = size; + pM->m_hInst = h; + pM->m_hInstResource = h; + pM->m_hInstTypeLib = h; + pM->m_pObjMap = p; + pM->m_hHeap = GetProcessHeap(); + + InitializeCriticalSection(&pM->u.m_csTypeInfoHolder); + InitializeCriticalSection(&pM->m_csWindowCreate); + InitializeCriticalSection(&pM->m_csObjMap); + + /* call mains */ + i = 0; + if (pM->m_pObjMap != NULL && size > ATLVer1Size) + { + while (pM->m_pObjMap[i].pclsid != NULL) + { + TRACE("Initializing object %i %p\n",i,p[i].pfnObjectMain); + if (p[i].pfnObjectMain) + p[i].pfnObjectMain(TRUE); + i++; + } + } + + return S_OK; +} + +HRESULT WINAPI AtlModuleLoadTypeLib(_ATL_MODULEW *pM, LPCOLESTR lpszIndex, + BSTR *pbstrPath, ITypeLib **ppTypeLib) +{ + HRESULT hRes; + OLECHAR path[MAX_PATH+8]; /* leave some space for index */ + + TRACE("(%p, %s, %p, %p)\n", pM, debugstr_w(lpszIndex), pbstrPath, ppTypeLib); + + if (!pM) + return E_INVALIDARG; + + GetModuleFileNameW(pM->m_hInstTypeLib, path, MAX_PATH); + if (lpszIndex) + lstrcatW(path, lpszIndex); + + hRes = LoadTypeLib(path, ppTypeLib); + if (FAILED(hRes)) + return hRes; + + *pbstrPath = SysAllocString(path); + + return S_OK; +} + +HRESULT WINAPI AtlModuleTerm(_ATL_MODULEW* pM) +{ + _ATL_TERMFUNC_ELEM *iter = pM->m_pTermFuncs, *tmp; + + TRACE("(%p)\n", pM); + + while(iter) { + iter->pFunc(iter->dw); + tmp = iter; + iter = iter->pNext; + HeapFree(GetProcessHeap(), 0, tmp); + } + + HeapFree(GetProcessHeap(), 0, pM); + + return S_OK; +} + +HRESULT WINAPI AtlModuleAddTermFunc(_ATL_MODULEW *pM, _ATL_TERMFUNC *pFunc, DWORD_PTR dw) +{ + _ATL_TERMFUNC_ELEM *termfunc_elem; + + TRACE("(%p %p %ld)\n", pM, pFunc, dw); + + termfunc_elem = HeapAlloc(GetProcessHeap(), 0, sizeof(_ATL_TERMFUNC_ELEM)); + termfunc_elem->pFunc = pFunc; + termfunc_elem->dw = dw; + termfunc_elem->pNext = pM->m_pTermFuncs; + + pM->m_pTermFuncs = termfunc_elem; + + return S_OK; +} + +HRESULT WINAPI AtlModuleRegisterClassObjects(_ATL_MODULEW *pM, DWORD dwClsContext, + DWORD dwFlags) +{ + HRESULT hRes = S_OK; + int i=0; + + TRACE("(%p %i %i)\n",pM, dwClsContext, dwFlags); + + if (pM == NULL) + return E_INVALIDARG; + + while(pM->m_pObjMap[i].pclsid != NULL) + { + IUnknown* pUnknown; + _ATL_OBJMAP_ENTRYW *obj = &(pM->m_pObjMap[i]); + HRESULT rc; + + TRACE("Registering object %i\n",i); + if (obj->pfnGetClassObject) + { + rc = obj->pfnGetClassObject(obj->pfnCreateInstance, &IID_IUnknown, + (LPVOID*)&pUnknown); + if (SUCCEEDED (rc) ) + { + CoRegisterClassObject(obj->pclsid, pUnknown, dwClsContext, + dwFlags, &obj->dwRegister); + if (pUnknown) + IUnknown_Release(pUnknown); + } + } + i++; + } + + return hRes; +} + +HRESULT WINAPI AtlModuleUnregisterServerEx(_ATL_MODULEW* pM, BOOL bUnRegTypeLib, const CLSID* pCLSID) +{ + FIXME("(%p, %i, %p) stub\n", pM, bUnRegTypeLib, pCLSID); + return S_OK; +} + + +IUnknown* WINAPI AtlComPtrAssign(IUnknown** pp, IUnknown *p) +{ + TRACE("(%p %p)\n", pp, p); + + if (p) IUnknown_AddRef(p); + if (*pp) IUnknown_Release(*pp); + *pp = p; + return p; +} + +IUnknown* WINAPI AtlComQIPtrAssign(IUnknown** pp, IUnknown *p, REFIID riid) +{ + IUnknown *new_p = NULL; + + TRACE("(%p %p %s)\n", pp, p, debugstr_guid(riid)); + + if (p) IUnknown_QueryInterface(p, riid, (void **)&new_p); + if (*pp) IUnknown_Release(*pp); + *pp = new_p; + return new_p; +} + + +HRESULT WINAPI AtlInternalQueryInterface(void* this, const _ATL_INTMAP_ENTRY* pEntries, REFIID iid, void** ppvObject) +{ + int i = 0; + HRESULT rc = E_NOINTERFACE; + TRACE("(%p, %p, %s, %p)\n",this, pEntries, debugstr_guid(iid), ppvObject); + + if (IsEqualGUID(iid,&IID_IUnknown)) + { + TRACE("Returning IUnknown\n"); + *ppvObject = ((LPSTR)this+pEntries[0].dw); + IUnknown_AddRef((IUnknown*)*ppvObject); + return S_OK; + } + + while (pEntries[i].pFunc != 0) + { + TRACE("Trying entry %i (%s %i %p)\n",i,debugstr_guid(pEntries[i].piid), + pEntries[i].dw, pEntries[i].pFunc); + + if (pEntries[i].piid && IsEqualGUID(iid,pEntries[i].piid)) + { + TRACE("MATCH\n"); + if (pEntries[i].pFunc == (_ATL_CREATORARGFUNC*)1) + { + TRACE("Offset\n"); + *ppvObject = ((LPSTR)this+pEntries[i].dw); + IUnknown_AddRef((IUnknown*)*ppvObject); + rc = S_OK; + } + else + { + TRACE("Function\n"); + rc = pEntries[i].pFunc(this, iid, ppvObject,0); + } + break; + } + i++; + } + TRACE("Done returning (0x%x)\n",rc); + return rc; +} + +/*********************************************************************** + * AtlModuleRegisterServer [ATL.@] + * + */ +HRESULT WINAPI AtlModuleRegisterServer(_ATL_MODULEW* pM, BOOL bRegTypeLib, const CLSID* clsid) +{ + int i; + HRESULT hRes; + + TRACE("%p %d %s\n", pM, bRegTypeLib, debugstr_guid(clsid)); + + if (pM == NULL) + return E_INVALIDARG; + + for (i = 0; pM->m_pObjMap[i].pclsid != NULL; i++) /* register CLSIDs */ + { + if (!clsid || IsEqualCLSID(pM->m_pObjMap[i].pclsid, clsid)) + { + const _ATL_OBJMAP_ENTRYW *obj = &pM->m_pObjMap[i]; + + TRACE("Registering clsid %s\n", debugstr_guid(obj->pclsid)); + hRes = obj->pfnUpdateRegistry(TRUE); /* register */ + if (FAILED(hRes)) + return hRes; + } + } + + if (bRegTypeLib) + { + hRes = AtlModuleRegisterTypeLib(pM, NULL); + if (FAILED(hRes)) + return hRes; + } + + return S_OK; +} + +/*********************************************************************** + * AtlAdvise [ATL.@] + */ +HRESULT WINAPI AtlAdvise(IUnknown *pUnkCP, IUnknown *pUnk, const IID *iid, LPDWORD pdw) +{ + FIXME("%p %p %p %p\n", pUnkCP, pUnk, iid, pdw); + return E_FAIL; +} + +/*********************************************************************** + * AtlUnadvise [ATL.@] + */ +HRESULT WINAPI AtlUnadvise(IUnknown *pUnkCP, const IID *iid, DWORD dw) +{ + FIXME("%p %p %d\n", pUnkCP, iid, dw); + return S_OK; +} + +/*********************************************************************** + * AtlFreeMarshalStream [ATL.@] + */ +HRESULT WINAPI AtlFreeMarshalStream(IStream *stm) +{ + FIXME("%p\n", stm); + return S_OK; +} + +/*********************************************************************** + * AtlMarshalPtrInProc [ATL.@] + */ +HRESULT WINAPI AtlMarshalPtrInProc(IUnknown *pUnk, const IID *iid, IStream **pstm) +{ + FIXME("%p %p %p\n", pUnk, iid, pstm); + return E_FAIL; +} + +/*********************************************************************** + * AtlUnmarshalPtr [ATL.@] + */ +HRESULT WINAPI AtlUnmarshalPtr(IStream *stm, const IID *iid, IUnknown **ppUnk) +{ + FIXME("%p %p %p\n", stm, iid, ppUnk); + return E_FAIL; +} + +/*********************************************************************** + * AtlModuleGetClassObject [ATL.@] + */ +HRESULT WINAPI AtlModuleGetClassObject(_ATL_MODULEW *pm, REFCLSID rclsid, + REFIID riid, LPVOID *ppv) +{ + int i; + HRESULT hres = CLASS_E_CLASSNOTAVAILABLE; + + TRACE("%p %s %s %p\n", pm, debugstr_guid(rclsid), debugstr_guid(riid), ppv); + + if (pm == NULL) + return E_INVALIDARG; + + for (i = 0; pm->m_pObjMap[i].pclsid != NULL; i++) + { + if (IsEqualCLSID(pm->m_pObjMap[i].pclsid, rclsid)) + { + _ATL_OBJMAP_ENTRYW *obj = &pm->m_pObjMap[i]; + + TRACE("found object %i\n", i); + if (obj->pfnGetClassObject) + { + if (!obj->pCF) + hres = obj->pfnGetClassObject(obj->pfnCreateInstance, + &IID_IUnknown, + (void **)&obj->pCF); + if (obj->pCF) + hres = IUnknown_QueryInterface(obj->pCF, riid, ppv); + break; + } + } + } + + WARN("no class object found for %s\n", debugstr_guid(rclsid)); + + return hres; +} + +/*********************************************************************** + * AtlModuleGetClassObject [ATL.@] + */ +HRESULT WINAPI AtlModuleRegisterTypeLib(_ATL_MODULEW *pm, LPCOLESTR lpszIndex) +{ + HRESULT hRes; + BSTR path; + ITypeLib *typelib; + + TRACE("%p %s\n", pm, debugstr_w(lpszIndex)); + + if (!pm) + return E_INVALIDARG; + + hRes = AtlModuleLoadTypeLib(pm, lpszIndex, &path, &typelib); + + if (SUCCEEDED(hRes)) + { + hRes = RegisterTypeLib(typelib, path, NULL); /* FIXME: pass help directory */ + ITypeLib_Release(typelib); + SysFreeString(path); + } + + return hRes; +} + +/*********************************************************************** + * AtlModuleRevokeClassObjects [ATL.@] + */ +HRESULT WINAPI AtlModuleRevokeClassObjects(_ATL_MODULEW *pm) +{ + FIXME("%p\n", pm); + return E_FAIL; +} + +/*********************************************************************** + * AtlModuleUnregisterServer [ATL.@] + */ +HRESULT WINAPI AtlModuleUnregisterServer(_ATL_MODULEW *pm, const CLSID *clsid) +{ + FIXME("%p %s\n", pm, debugstr_guid(clsid)); + return E_FAIL; +} + +/*********************************************************************** + * AtlModuleRegisterWndClassInfoW [ATL.@] + * + * PARAMS + * pm [IO] Information about the module registering the window. + * wci [IO] Information about the window being registered. + * pProc [O] Window procedure of the registered class. + * + * RETURNS + * Atom representing the registered class. + * + * NOTES + * Can be called multiple times without error, unlike RegisterClassEx(). + * + * If the class name is NULL, then a class with a name of "ATLxxxxxxxx" is + * registered, where the 'x's represent a unique value. + * + */ +ATOM WINAPI AtlModuleRegisterWndClassInfoW(_ATL_MODULEW *pm, _ATL_WNDCLASSINFOW *wci, WNDPROC *pProc) +{ + ATOM atom; + + FIXME("%p %p %p semi-stub\n", pm, wci, pProc); + + atom = wci->m_atom; + if (!atom) + { + WNDCLASSEXW wc; + + TRACE("wci->m_wc.lpszClassName = %s\n", debugstr_w(wci->m_wc.lpszClassName)); + + if (!wci->m_wc.lpszClassName) + { + static const WCHAR szFormat[] = {'A','T','L','%','0','8','x',0}; + sprintfW(wci->m_szAutoName, szFormat, (UINT)(UINT_PTR)wci); + TRACE("auto-generated class name %s\n", debugstr_w(wci->m_szAutoName)); + wci->m_wc.lpszClassName = wci->m_szAutoName; + } + + atom = GetClassInfoExW(pm->m_hInst, wci->m_wc.lpszClassName, &wc); + if (!atom) + atom = RegisterClassExW(&wci->m_wc); + + wci->pWndProc = wci->m_wc.lpfnWndProc; + wci->m_atom = atom; + } + *pProc = wci->pWndProc; + + TRACE("returning 0x%04x\n", atom); + return atom; +} + +void WINAPI AtlHiMetricToPixel(const SIZEL* lpHiMetric, SIZEL* lpPix) +{ + HDC dc = GetDC(NULL); + lpPix->cx = lpHiMetric->cx * GetDeviceCaps( dc, LOGPIXELSX ) / 100; + lpPix->cy = lpHiMetric->cy * GetDeviceCaps( dc, LOGPIXELSY ) / 100; + ReleaseDC( NULL, dc ); +} + +void WINAPI AtlPixelToHiMetric(const SIZEL* lpPix, SIZEL* lpHiMetric) +{ + HDC dc = GetDC(NULL); + lpHiMetric->cx = 100 * lpPix->cx / GetDeviceCaps( dc, LOGPIXELSX ); + lpHiMetric->cy = 100 * lpPix->cy / GetDeviceCaps( dc, LOGPIXELSY ); + ReleaseDC( NULL, dc ); +} + +/*********************************************************************** + * AtlModuleAddCreateWndData [ATL.@] + */ +void WINAPI AtlModuleAddCreateWndData(_ATL_MODULEW *pM, _AtlCreateWndData *pData, void* pvObject) +{ + TRACE("(%p, %p, %p)\n", pM, pData, pvObject); + + pData->m_pThis = pvObject; + pData->m_dwThreadID = GetCurrentThreadId(); + pData->m_pNext = pM->m_pCreateWndList; + pM->m_pCreateWndList = pData; +} + +/*********************************************************************** + * AtlModuleExtractCreateWndData [ATL.@] + * + * NOTE: I failed to find any good description of this function. + * Tests show that this function extracts one of _AtlCreateWndData + * records from the current thread from a list + * + */ +void* WINAPI AtlModuleExtractCreateWndData(_ATL_MODULEW *pM) +{ + _AtlCreateWndData **ppData; + + TRACE("(%p)\n", pM); + + for(ppData = &pM->m_pCreateWndList; *ppData!=NULL; ppData = &(*ppData)->m_pNext) + { + if ((*ppData)->m_dwThreadID == GetCurrentThreadId()) + { + _AtlCreateWndData *pData = *ppData; + *ppData = pData->m_pNext; + return pData->m_pThis; + } + } + return NULL; +} + +/* FIXME: should be in a header file */ +typedef struct ATL_PROPMAP_ENTRY +{ + LPCOLESTR szDesc; + DISPID dispid; + const CLSID* pclsidPropPage; + const IID* piidDispatch; + DWORD dwOffsetData; + DWORD dwSizeData; + VARTYPE vt; +} ATL_PROPMAP_ENTRY; + +/*********************************************************************** + * AtlIPersistStreamInit_Load [ATL.@] + */ +HRESULT WINAPI AtlIPersistStreamInit_Load( LPSTREAM pStm, ATL_PROPMAP_ENTRY *pMap, + void *pThis, IUnknown *pUnk) +{ + FIXME("(%p, %p, %p, %p)\n", pStm, pMap, pThis, pUnk); + + return S_OK; +} + +HRESULT WINAPI AtlIPersistStreamInit_Save(LPSTREAM pStm, BOOL fClearDirty, + ATL_PROPMAP_ENTRY *pMap, void *pThis, + IUnknown *pUnk) +{ + FIXME("(%p, %d, %p, %p, %p)\n", pStm, fClearDirty, pMap, pThis, pUnk); + + return S_OK; +} diff --git a/reactos/dll/win32/atl/atlbase.h b/reactos/dll/win32/atl/atlbase.h new file mode 100644 index 00000000000..ad7acfac835 --- /dev/null +++ b/reactos/dll/win32/atl/atlbase.h @@ -0,0 +1,166 @@ +/* + * Implementation of the Active Template Library (atl.dll) + * + * Copyright 2004 Aric Stewart for CodeWeavers + * + * 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 + */ + +#ifndef __WINE_ATLBASE_H__ +#define __WINE_ATLBASE_H__ + +#define COBJMACROS + +#include "atliface.h" + +typedef HRESULT (WINAPI _ATL_CREATORFUNC)(void* pv, REFIID riid, LPVOID* ppv); +typedef HRESULT (WINAPI _ATL_CREATORARGFUNC)(void* pv, REFIID riid, LPVOID* ppv, DWORD dw); +typedef HRESULT (WINAPI _ATL_MODULEFUNC)(DWORD dw); +typedef LPCSTR (WINAPI _ATL_DESCRIPTIONFUNCA)(); +typedef LPCWSTR (WINAPI _ATL_DESCRIPTIONFUNCW)(); +typedef const struct _ATL_CATMAP_ENTRY* (_ATL_CATMAPFUNC)(); +typedef void (WINAPI _ATL_TERMFUNC)(DWORD dw); + +typedef struct _ATL_OBJMAP_ENTRYA_TAG +{ + const CLSID* pclsid; + HRESULT (WINAPI *pfnUpdateRegistry)(BOOL bRegister); + _ATL_CREATORFUNC* pfnGetClassObject; + _ATL_CREATORFUNC* pfnCreateInstance; + IUnknown* pCF; + DWORD dwRegister; + _ATL_DESCRIPTIONFUNCA* pfnGetObjectDescription; + _ATL_CATMAPFUNC* pfnGetCategoryMap; + void (WINAPI *pfnObjectMain)(BOOL bStarting); +}_ATL_OBJMAP_ENTRYA; + +typedef struct _ATL_OBJMAP_ENTRYW_TAG +{ + const CLSID* pclsid; + HRESULT (WINAPI *pfnUpdateRegistry)(BOOL bRegister); + _ATL_CREATORFUNC* pfnGetClassObject; + _ATL_CREATORFUNC* pfnCreateInstance; + IUnknown* pCF; + DWORD dwRegister; + _ATL_DESCRIPTIONFUNCW* pfnGetObjectDescription; + _ATL_CATMAPFUNC* pfnGetCategoryMap; + void (WINAPI *pfnObjectMain)(BOOL bStarting); +} _ATL_OBJMAP_ENTRYW; + + +typedef struct _ATL_TERMFUNC_ELEM_TAG +{ + _ATL_TERMFUNC* pFunc; + DWORD_PTR dw; + struct _ATL_TERMFUNC_ELEM_TAG* pNext; +} _ATL_TERMFUNC_ELEM; + +typedef struct _AtlCreateWndData_TAG +{ + void* m_pThis; + DWORD m_dwThreadID; + struct _AtlCreateWndData_TAG* m_pNext; +} _AtlCreateWndData; + +typedef struct _ATL_MODULEA_TAG +{ + UINT cbSize; + HINSTANCE m_hInst; + HINSTANCE m_hInstResource; + HINSTANCE m_hInstTypeLib; + _ATL_OBJMAP_ENTRYA* m_pObjMap; + LONG m_nLockCnt; + HANDLE m_hHeap; + union + { + CRITICAL_SECTION m_csTypeInfoHolder; + CRITICAL_SECTION m_csStaticDataInit; + } u; + CRITICAL_SECTION m_csWindowCreate; + CRITICAL_SECTION m_csObjMap; + + DWORD dwAtlBuildVer; + _AtlCreateWndData* m_pCreateWndList; + BOOL m_bDestroyHeap; + GUID* pguidVer; + DWORD m_dwHeaps; + HANDLE* m_phHeaps; + int m_nHeap; + _ATL_TERMFUNC_ELEM* m_pTermFuncs; +} _ATL_MODULEA; + +typedef struct _ATL_MODULEW_TAG +{ + UINT cbSize; + HINSTANCE m_hInst; + HINSTANCE m_hInstResource; + HINSTANCE m_hInstTypeLib; + _ATL_OBJMAP_ENTRYW* m_pObjMap; + LONG m_nLockCnt; + HANDLE m_hHeap; + union + { + CRITICAL_SECTION m_csTypeInfoHolder; + CRITICAL_SECTION m_csStaticDataInit; + } u; + CRITICAL_SECTION m_csWindowCreate; + CRITICAL_SECTION m_csObjMap; + + DWORD dwAtlBuildVer; + _AtlCreateWndData* m_pCreateWndList; + BOOL m_bDestroyHeap; + GUID* pguidVer; + DWORD m_dwHeaps; + HANDLE* m_phHeaps; + int m_nHeap; + _ATL_TERMFUNC_ELEM* m_pTermFuncs; +} _ATL_MODULEW; + +typedef struct _ATL_INTMAP_ENTRY_TAG +{ + const IID* piid; + DWORD dw; + _ATL_CREATORARGFUNC* pFunc; +} _ATL_INTMAP_ENTRY; + +struct _ATL_REGMAP_ENTRY +{ + LPCOLESTR szKey; + LPCOLESTR szData; +}; + +HRESULT WINAPI AtlAdvise(IUnknown *pUnkCP, IUnknown *pUnk, const IID * iid, LPDWORD dpw); +HRESULT WINAPI AtlAxAttachControl(IUnknown*,HWND,IUnknown**); +HRESULT WINAPI AtlAxCreateControl(LPCOLESTR,HWND,IStream*,IUnknown**); +HRESULT WINAPI AtlAxCreateControlEx(LPCOLESTR,HWND,IStream*,IUnknown**,IUnknown**,REFIID,IUnknown*); +HRESULT WINAPI AtlFreeMarshalStream(IStream *pStream); +HRESULT WINAPI AtlInternalQueryInterface(void* pThis, const _ATL_INTMAP_ENTRY* pEntries, REFIID iid, void** ppvObject); +HRESULT WINAPI AtlMarshalPtrInProc(IUnknown *pUnk, const IID *iid, IStream **ppStream); +void WINAPI AtlModuleAddCreateWndData(_ATL_MODULEW *pM, _AtlCreateWndData *pData, void* pvObject); +HRESULT WINAPI AtlModuleAddTermFunc(_ATL_MODULEW *pM, _ATL_TERMFUNC *pFunc, DWORD_PTR dw); +void* WINAPI AtlModuleExtractCreateWndData(_ATL_MODULEW *pM); +HRESULT WINAPI AtlModuleInit(_ATL_MODULEW* pM, _ATL_OBJMAP_ENTRYW* p, HINSTANCE h); +HRESULT WINAPI AtlModuleLoadTypeLib(_ATL_MODULEW *pM, LPCOLESTR lpszIndex, BSTR *pbstrPath, ITypeLib **ppTypeLib); +HRESULT WINAPI AtlModuleRegisterClassObjects(_ATL_MODULEW* pM, DWORD dwClsContext, DWORD dwFlags); +HRESULT WINAPI AtlModuleRegisterServer(_ATL_MODULEW* pM, BOOL bRegTypeLib, const CLSID* pCLSID); +HRESULT WINAPI AtlModuleRegisterTypeLib(_ATL_MODULEW *pM, LPCOLESTR lpszIndex); +HRESULT WINAPI AtlModuleUnregisterServer(_ATL_MODULEW* pM, const CLSID* pCLSID); +HRESULT WINAPI AtlModuleUpdateRegistryFromResourceD(_ATL_MODULEW *pM, LPCOLESTR lpszRes, BOOL bRegister, struct _ATL_REGMAP_ENTRY *pMapEntries, IRegistrar *pReg ); +HRESULT WINAPI AtlModuleUnregisterServerEx(_ATL_MODULEW* pM, BOOL bUnRegTypeLib, const CLSID* pCLSID); +HRESULT WINAPI AtlModuleTerm(_ATL_MODULEW* pM); +HRESULT WINAPI AtlUnadvise(IUnknown *pUnkCP, const IID * iid, DWORD dw); +HRESULT WINAPI AtlUnmarshalPtr(IStream *pStream, const IID *iid, IUnknown **ppUnk); + +#endif /* __WINE_ATLBASE_H__ */ diff --git a/reactos/dll/win32/atl/atliface.idl b/reactos/dll/win32/atl/atliface.idl new file mode 100644 index 00000000000..bb5cb2e7aa6 --- /dev/null +++ b/reactos/dll/win32/atl/atliface.idl @@ -0,0 +1,79 @@ +/* + * Copyright 2005 Jacek Caban + * + * 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 + */ + +import "ocidl.idl"; + +cpp_quote("#ifdef ATL_INITGUID") +cpp_quote("#include \"initguid.h\"") +cpp_quote("#endif") + +[ + object, + oleautomation, + uuid(44EC053B-400F-11D0-9DCD-00A0C90391D3) +] +interface IRegistrar : IUnknown +{ + HRESULT AddReplacement( + [in] LPCOLESTR Key, + [in] LPCOLESTR item); + + HRESULT ClearReplacements(); + + HRESULT ResourceRegisterSz( + [in] LPCOLESTR resFileName, + [in] LPCOLESTR szID, + [in] LPCOLESTR szType); + + HRESULT ResourceUnregisterSz( + [in] LPCOLESTR resFileName, + [in] LPCOLESTR szID, + [in] LPCOLESTR szType); + + HRESULT FileRegister( + [in] LPCOLESTR fileName); + + HRESULT FileUnregister( + [in] LPCOLESTR fileName); + + HRESULT StringRegister( + [in] LPCOLESTR data); + + HRESULT StringUnregister( + [in] LPCOLESTR data); + + HRESULT ResourceRegister( + [in] LPCOLESTR resFileName, + [in] UINT nID, + [in] LPCOLESTR szType); + + HRESULT ResourceUnregister( + [in] LPCOLESTR resFileName, + [in] UINT nID, + [in] LPCOLESTR szType); +} + +cpp_quote("DEFINE_GUID(CLSID_ATLRegistrar,0x44ec053a,0x400f,0x11d0,0x9d,0xcd,0x00,0xa0,0xc9,0x03,0x91,0xd3);") + +cpp_quote("HRESULT WINAPI AtlAxCreateControl(LPCOLESTR,HWND,IStream*,IUnknown**);") +cpp_quote("HRESULT WINAPI AtlAxCreateControlEx(LPCOLESTR,HWND,IStream*,IUnknown**,IUnknown**,REFIID,IUnknown*);") +cpp_quote("BOOL WINAPI AtlAxWinInit(void);") + +cpp_quote("HWND WINAPI AtlAxCreateDialogW(HINSTANCE,LPCWSTR,HWND,DLGPROC,LPARAM);"); +cpp_quote("HWND WINAPI AtlAxCreateDialogA(HINSTANCE,LPCSTR,HWND,DLGPROC,LPARAM);"); +cpp_quote("#define AtlAxCreateDialog WINELIB_NAME_AW(AtlAxCreateDialog"); diff --git a/reactos/dll/win32/atl/atlwin.h b/reactos/dll/win32/atl/atlwin.h new file mode 100644 index 00000000000..4bd13599667 --- /dev/null +++ b/reactos/dll/win32/atl/atlwin.h @@ -0,0 +1,53 @@ +/* + * Active Template Library Window Functions + * + * Copyright 2006 Robert Shearman for CodeWeavers + * + * 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 + */ + +#ifndef __WINE_ATLWIN_H__ +#define __WINE_ATLWIN_H__ + +typedef struct _ATL_WNDCLASSINFOA_TAG +{ + WNDCLASSEXA m_wc; + LPCSTR m_lpszOrigName; + WNDPROC pWndProc; + LPCSTR m_lpszCursorID; + BOOL m_bSystemCursor; + ATOM m_atom; + CHAR m_szAutoName[14]; +} _ATL_WNDCLASSINFOA; + +typedef struct _ATL_WNDCLASSINFOW_TAG +{ + WNDCLASSEXW m_wc; + LPCWSTR m_lpszOrigName; + WNDPROC pWndProc; + LPCWSTR m_lpszCursorID; + BOOL m_bSystemCursor; + ATOM m_atom; + WCHAR m_szAutoName[14]; +} _ATL_WNDCLASSINFOW; + +ATOM WINAPI AtlModuleRegisterWndClassInfoA(_ATL_MODULEW *pm, _ATL_WNDCLASSINFOA *wci, WNDPROC *pProc); +ATOM WINAPI AtlModuleRegisterWndClassInfoW(_ATL_MODULEW *pm, _ATL_WNDCLASSINFOW *wci, WNDPROC *pProc); + +HDC WINAPI AtlCreateTargetDC(HDC hdc, DVTARGETDEVICE *ptd); +void WINAPI AtlHiMetricToPixel(const SIZEL *lpSizeInHiMetric, LPSIZEL lpSizeInPix); +void WINAPI AtlPixelToHiMetric(const SIZEL *lpSizeInPix, LPSIZEL lpSizeInHiMetric); + +#endif /* __WINE_ATLWIN_H__ */ diff --git a/reactos/dll/win32/atl/registrar.c b/reactos/dll/win32/atl/registrar.c new file mode 100644 index 00000000000..dd16aa0a01e --- /dev/null +++ b/reactos/dll/win32/atl/registrar.c @@ -0,0 +1,848 @@ +/* + * Copyright 2005 Jacek Caban + * + * 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 + +#define COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "winuser.h" +#include "winreg.h" +#include "objbase.h" +#include "oaidl.h" +#include "string.h" + +#define ATL_INITGUID +#include "atliface.h" +#include "atlbase.h" + +#include "wine/debug.h" +#include "wine/unicode.h" + +WINE_DEFAULT_DEBUG_CHANNEL(atl); + +static LONG dll_count; + +/************************************************************** + * ATLRegistrar implementation + */ + +static const struct { + WCHAR name[22]; + HKEY key; +} root_keys[] = { + {{'H','K','E','Y','_','C','L','A','S','S','E','S','_','R','O','O','T',0}, + HKEY_CLASSES_ROOT}, + {{'H','K','E','Y','_','C','U','R','R','E','N','T','_','U','S','E','R',0}, + HKEY_CURRENT_USER}, + {{'H','K','E','Y','_','L','O','C','A','L','_','M','A','C','H','I','N','E',0}, + HKEY_LOCAL_MACHINE}, + {{'H','K','E','Y','_','U','S','E','R','S',0}, + HKEY_USERS}, + {{'H','K','E','Y','_','P','E','R','F','O','R','M','A','N','C','E','_','D','A','T','A',0}, + HKEY_PERFORMANCE_DATA}, + {{'H','K','E','Y','_','D','Y','N','_','D','A','T','A',0}, + HKEY_DYN_DATA}, + {{'H','K','E','Y','_','C','U','R','R','E','N','T','_','C','O','N','F','I','G',0}, + HKEY_CURRENT_CONFIG}, + {{'H','K','C','R',0}, HKEY_CLASSES_ROOT}, + {{'H','K','C','U',0}, HKEY_CURRENT_USER}, + {{'H','K','L','M',0}, HKEY_LOCAL_MACHINE}, + {{'H','K','U',0}, HKEY_USERS}, + {{'H','K','P','D',0}, HKEY_PERFORMANCE_DATA}, + {{'H','K','D','D',0}, HKEY_DYN_DATA}, + {{'H','K','C','C',0}, HKEY_CURRENT_CONFIG} +}; + +typedef struct rep_list_str { + LPOLESTR key; + LPOLESTR item; + int key_len; + struct rep_list_str *next; +} rep_list; + +typedef struct { + const IRegistrarVtbl *lpVtbl; + LONG ref; + rep_list *rep; +} Registrar; + +typedef struct { + LPOLESTR str; + DWORD alloc; + DWORD len; +} strbuf; + +static void strbuf_init(strbuf *buf) +{ + buf->str = HeapAlloc(GetProcessHeap(), 0, 128*sizeof(WCHAR)); + buf->alloc = 128; + buf->len = 0; +} + +static void strbuf_write(LPCOLESTR str, strbuf *buf, int len) +{ + if(len == -1) + len = lstrlenW(str); + if(buf->len+len+1 >= buf->alloc) { + buf->alloc = (buf->len+len)<<1; + buf->str = HeapReAlloc(GetProcessHeap(), 0, buf->str, buf->alloc*sizeof(WCHAR)); + } + memcpy(buf->str+buf->len, str, len*sizeof(OLECHAR)); + buf->len += len; + buf->str[buf->len] = '\0'; +} + +static HRESULT get_word(LPCOLESTR *str, strbuf *buf) +{ + LPCOLESTR iter, iter2 = *str; + + buf->len = 0; + buf->str[0] = '\0'; + + while(isspaceW(*iter2)) + iter2++; + iter = iter2; + if(!*iter) { + *str = iter; + return S_OK; + } + + if(*iter == '}' || *iter == '=') { + strbuf_write(iter++, buf, 1); + }else if(*iter == '\'') { + iter2 = ++iter; + iter = strchrW(iter, '\''); + if(!iter) { + WARN("Unexpected end of script\n"); + *str = iter; + return DISP_E_EXCEPTION; + } + strbuf_write(iter2, buf, iter-iter2); + iter++; + }else { + while(*iter && !isspaceW(*iter)) + iter++; + strbuf_write(iter2, buf, iter-iter2); + } + + while(isspaceW(*iter)) + iter++; + *str = iter; + return S_OK; +} + +static HRESULT do_preprocess(const Registrar *This, LPCOLESTR data, strbuf *buf) +{ + LPCOLESTR iter, iter2 = data; + rep_list *rep_iter; + static const WCHAR wstr[] = {'%',0}; + + iter = strchrW(data, '%'); + while(iter) { + strbuf_write(iter2, buf, iter-iter2); + + iter2 = ++iter; + if(!*iter2) + return DISP_E_EXCEPTION; + iter = strchrW(iter2, '%'); + if(!iter) + return DISP_E_EXCEPTION; + + if(iter == iter2) { + strbuf_write(wstr, buf, 1); + }else { + for(rep_iter = This->rep; rep_iter; rep_iter = rep_iter->next) { + if(rep_iter->key_len == iter-iter2 + && !memicmp(iter2, rep_iter->key, rep_iter->key_len)) + break; + } + if(!rep_iter) { + WARN("Could not find replacement: %s\n", debugstr_wn(iter2, iter-iter2)); + return DISP_E_EXCEPTION; + } + + strbuf_write(rep_iter->item, buf, -1); + } + + iter2 = ++iter; + iter = strchrW(iter, '%'); + } + + strbuf_write(iter2, buf, -1); + TRACE("%s\n", debugstr_w(buf->str)); + + return S_OK; +} + +static HRESULT do_process_key(LPCOLESTR *pstr, HKEY parent_key, strbuf *buf, BOOL do_register) +{ + LPCOLESTR iter = *pstr; + HRESULT hres; + LONG lres; + HKEY hkey = 0; + strbuf name; + + enum { + NORMAL, + NO_REMOVE, + IS_VAL, + FORCE_REMOVE, + DO_DELETE + } key_type = NORMAL; + + static const WCHAR wstrNoRemove[] = {'N','o','R','e','m','o','v','e',0}; + static const WCHAR wstrForceRemove[] = {'F','o','r','c','e','R','e','m','o','v','e',0}; + static const WCHAR wstrDelete[] = {'D','e','l','e','t','e',0}; + static const WCHAR wstrval[] = {'v','a','l',0}; + + iter = *pstr; + hres = get_word(&iter, buf); + if(FAILED(hres)) + return hres; + strbuf_init(&name); + + while(buf->str[1] || buf->str[0] != '}') { + key_type = NORMAL; + if(!lstrcmpiW(buf->str, wstrNoRemove)) + key_type = NO_REMOVE; + else if(!lstrcmpiW(buf->str, wstrForceRemove)) + key_type = FORCE_REMOVE; + else if(!lstrcmpiW(buf->str, wstrval)) + key_type = IS_VAL; + else if(!lstrcmpiW(buf->str, wstrDelete)) + key_type = DO_DELETE; + + if(key_type != NORMAL) { + hres = get_word(&iter, buf); + if(FAILED(hres)) + break; + } + TRACE("name = %s\n", debugstr_w(buf->str)); + + if(do_register) { + if(key_type == IS_VAL) { + hkey = parent_key; + strbuf_write(buf->str, &name, -1); + }else if(key_type == DO_DELETE) { + TRACE("Deleting %s\n", debugstr_w(buf->str)); + lres = RegDeleteTreeW(parent_key, buf->str); + }else { + if(key_type == FORCE_REMOVE) + RegDeleteTreeW(parent_key, buf->str); + lres = RegCreateKeyW(parent_key, buf->str, &hkey); + if(lres != ERROR_SUCCESS) { + WARN("Could not create(open) key: %08x\n", lres); + hres = HRESULT_FROM_WIN32(lres); + break; + } + } + }else if(key_type != IS_VAL && key_type != DO_DELETE) { + strbuf_write(buf->str, &name, -1); + lres = RegOpenKeyW(parent_key, buf->str, &hkey); + if(lres != ERROR_SUCCESS) + WARN("Could not open key %s: %08x\n", debugstr_w(name.str), lres); + } + + if(key_type != DO_DELETE && *iter == '=') { + iter++; + hres = get_word(&iter, buf); + if(FAILED(hres)) + break; + if(buf->len != 1) { + WARN("Wrong registry type: %s\n", debugstr_w(buf->str)); + hres = DISP_E_EXCEPTION; + break; + } + if(do_register) { + switch(buf->str[0]) { + case 's': + hres = get_word(&iter, buf); + if(FAILED(hres)) + break; + lres = RegSetValueExW(hkey, name.len ? name.str : NULL, 0, REG_SZ, (PBYTE)buf->str, + (lstrlenW(buf->str)+1)*sizeof(WCHAR)); + if(lres != ERROR_SUCCESS) { + WARN("Could set value of key: %08x\n", lres); + hres = HRESULT_FROM_WIN32(lres); + break; + } + break; + case 'd': { + WCHAR *end; + DWORD dw; + if(*iter == '0' && iter[1] == 'x') { + iter += 2; + dw = strtolW(iter, &end, 16); + }else { + dw = strtolW(iter, &end, 10); + } + iter = end; + lres = RegSetValueExW(hkey, name.len ? name.str : NULL, 0, REG_DWORD, + (PBYTE)&dw, sizeof(dw)); + if(lres != ERROR_SUCCESS) { + WARN("Could set value of key: %08x\n", lres); + hres = HRESULT_FROM_WIN32(lres); + break; + } + break; + } + default: + WARN("Wrong resource type: %s\n", debugstr_w(buf->str)); + hres = DISP_E_EXCEPTION; + }; + if(FAILED(hres)) + break; + }else { + if(*iter == '-') + iter++; + hres = get_word(&iter, buf); + if(FAILED(hres)) + break; + } + }else if(key_type == IS_VAL) { + WARN("value not set!\n"); + hres = DISP_E_EXCEPTION; + break; + } + + if(key_type != IS_VAL && key_type != DO_DELETE && *iter == '{' && isspaceW(iter[1])) { + hres = get_word(&iter, buf); + if(FAILED(hres)) + break; + hres = do_process_key(&iter, hkey, buf, do_register); + if(FAILED(hres)) + break; + } + + TRACE("%x %x\n", do_register, key_type); + if(!do_register && (key_type == NORMAL || key_type == FORCE_REMOVE)) { + TRACE("Deleting %s\n", debugstr_w(name.str)); + RegDeleteKeyW(parent_key, name.str); + } + + if(hkey && key_type != IS_VAL) + RegCloseKey(hkey); + hkey = 0; + name.len = 0; + + hres = get_word(&iter, buf); + if(FAILED(hres)) + break; + } + + HeapFree(GetProcessHeap(), 0, name.str); + if(hkey && key_type != IS_VAL) + RegCloseKey(hkey); + *pstr = iter; + return hres; +} + +static HRESULT do_process_root_key(LPCOLESTR data, BOOL do_register) +{ + LPCOLESTR iter = data; + strbuf buf; + HRESULT hres = S_OK; + unsigned int i; + + strbuf_init(&buf); + hres = get_word(&iter, &buf); + if(FAILED(hres)) + return hres; + + while(*iter) { + if(!buf.len) { + WARN("ward.len == 0, failed\n"); + hres = DISP_E_EXCEPTION; + break; + } + for(i=0; i(%s %p\n", iface, debugstr_guid(riid), ppvObject); + + if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IRegistrar, riid)) { + IRegistrar_AddRef(iface); + *ppvObject = iface; + return S_OK; + } + return E_NOINTERFACE; +} + +static ULONG WINAPI Registrar_AddRef(IRegistrar *iface) +{ + Registrar *This = (Registrar*)iface; + ULONG ref = InterlockedIncrement(&This->ref); + TRACE("(%p) ->%d\n", This, ref); + return ref; +} + +static ULONG WINAPI Registrar_Release(IRegistrar *iface) +{ + Registrar *This = (Registrar*)iface; + ULONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p) ->%d\n", This, ref); + if(!ref) { + IRegistrar_ClearReplacements(iface); + HeapFree(GetProcessHeap(), 0, This); + InterlockedDecrement(&dll_count); + } + return ref; +} + +static HRESULT WINAPI Registrar_AddReplacement(IRegistrar *iface, LPCOLESTR Key, LPCOLESTR item) +{ + Registrar *This = (Registrar*)iface; + int len; + rep_list *new_rep; + + TRACE("(%p)->(%s %s)\n", This, debugstr_w(Key), debugstr_w(item)); + + new_rep = HeapAlloc(GetProcessHeap(), 0, sizeof(rep_list)); + + new_rep->key_len = lstrlenW(Key); + new_rep->key = HeapAlloc(GetProcessHeap(), 0, new_rep->key_len*sizeof(OLECHAR)+1); + memcpy(new_rep->key, Key, (new_rep->key_len+1)*sizeof(OLECHAR)); + + len = lstrlenW(item)+1; + new_rep->item = HeapAlloc(GetProcessHeap(), 0, len*sizeof(OLECHAR)); + memcpy(new_rep->item, item, len*sizeof(OLECHAR)); + + new_rep->next = This->rep; + This->rep = new_rep; + + return S_OK; +} + +static HRESULT WINAPI Registrar_ClearReplacements(IRegistrar *iface) +{ + Registrar *This = (Registrar*)iface; + rep_list *iter, *iter2; + + TRACE("(%p)\n", This); + + if(!This->rep) + return S_OK; + + iter = This->rep; + while(iter) { + iter2 = iter->next; + HeapFree(GetProcessHeap(), 0, iter->key); + HeapFree(GetProcessHeap(), 0, iter->item); + HeapFree(GetProcessHeap(), 0, iter); + iter = iter2; + } + + This->rep = NULL; + return S_OK; +} + +static HRESULT WINAPI Registrar_ResourceRegisterSz(IRegistrar* iface, LPCOLESTR resFileName, + LPCOLESTR szID, LPCOLESTR szType) +{ + Registrar *This = (Registrar*)iface; + TRACE("(%p)->(%s %s %s)\n", This, debugstr_w(resFileName), debugstr_w(szID), debugstr_w(szType)); + return resource_register(This, resFileName, szID, szType, TRUE); +} + +static HRESULT WINAPI Registrar_ResourceUnregisterSz(IRegistrar* iface, LPCOLESTR resFileName, + LPCOLESTR szID, LPCOLESTR szType) +{ + Registrar *This = (Registrar*)iface; + TRACE("(%p)->(%s %s %s)\n", This, debugstr_w(resFileName), debugstr_w(szID), debugstr_w(szType)); + return resource_register(This, resFileName, szID, szType, FALSE); +} + +static HRESULT WINAPI Registrar_FileRegister(IRegistrar* iface, LPCOLESTR fileName) +{ + Registrar *This = (Registrar*)iface; + TRACE("(%p)->(%s)\n", This, debugstr_w(fileName)); + return file_register(This, fileName, TRUE); +} + +static HRESULT WINAPI Registrar_FileUnregister(IRegistrar* iface, LPCOLESTR fileName) +{ + Registrar *This = (Registrar*)iface; + FIXME("(%p)->(%s)\n", This, debugstr_w(fileName)); + return file_register(This, fileName, FALSE); +} + +static HRESULT WINAPI Registrar_StringRegister(IRegistrar* iface, LPCOLESTR data) +{ + Registrar *This = (Registrar*)iface; + TRACE("(%p)->(%s)\n", This, debugstr_w(data)); + return string_register(This, data, TRUE); +} + +static HRESULT WINAPI Registrar_StringUnregister(IRegistrar* iface, LPCOLESTR data) +{ + Registrar *This = (Registrar*)iface; + TRACE("(%p)->(%s)\n", This, debugstr_w(data)); + return string_register(This, data, FALSE); +} + +static HRESULT WINAPI Registrar_ResourceRegister(IRegistrar* iface, LPCOLESTR resFileName, + UINT nID, LPCOLESTR szType) +{ + Registrar *This = (Registrar*)iface; + TRACE("(%p)->(%s %d %s)\n", iface, debugstr_w(resFileName), nID, debugstr_w(szType)); + return resource_register(This, resFileName, MAKEINTRESOURCEW(nID), szType, TRUE); +} + +static HRESULT WINAPI Registrar_ResourceUnregister(IRegistrar* iface, LPCOLESTR resFileName, + UINT nID, LPCOLESTR szType) +{ + Registrar *This = (Registrar*)iface; + TRACE("(%p)->(%s %d %s)\n", This, debugstr_w(resFileName), nID, debugstr_w(szType)); + return resource_register(This, resFileName, MAKEINTRESOURCEW(nID), szType, FALSE); +} + +static const IRegistrarVtbl RegistrarVtbl = { + Registrar_QueryInterface, + Registrar_AddRef, + Registrar_Release, + Registrar_AddReplacement, + Registrar_ClearReplacements, + Registrar_ResourceRegisterSz, + Registrar_ResourceUnregisterSz, + Registrar_FileRegister, + Registrar_FileUnregister, + Registrar_StringRegister, + Registrar_StringUnregister, + Registrar_ResourceRegister, + Registrar_ResourceUnregister, +}; + +static HRESULT Registrar_create(const IUnknown *pUnkOuter, REFIID riid, void **ppvObject) +{ + Registrar *ret; + + if(!IsEqualGUID(&IID_IUnknown, riid) && !IsEqualGUID(&IID_IRegistrar, riid)) + return E_NOINTERFACE; + + ret = HeapAlloc(GetProcessHeap(), 0, sizeof(Registrar)); + ret->lpVtbl = &RegistrarVtbl; + ret->ref = 1; + ret->rep = NULL; + *ppvObject = ret; + + InterlockedIncrement(&dll_count); + + return S_OK; +} + +/************************************************************** + * ClassFactory implementation + */ + +static HRESULT WINAPI RegistrarCF_QueryInterface(IClassFactory *iface, REFIID riid, void **ppvObject) +{ + TRACE("(%p)->(%s %p)\n", iface, debugstr_guid(riid), ppvObject); + + if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IRegistrar, riid)) { + *ppvObject = iface; + return S_OK; + } + + return E_NOINTERFACE; +} + +static ULONG WINAPI RegistrarCF_AddRef(IClassFactory *iface) +{ + InterlockedIncrement(&dll_count); + return 2; +} + +static ULONG WINAPI RegistrarCF_Release(IClassFactory *iface) +{ + InterlockedDecrement(&dll_count); + return 1; +} + +static HRESULT WINAPI RegistrarCF_CreateInstance(IClassFactory *iface, LPUNKNOWN pUnkOuter, + REFIID riid, void **ppvObject) +{ + TRACE("(%p)->(%s %p)\n", iface, debugstr_guid(riid), ppvObject); + return Registrar_create(pUnkOuter, riid, ppvObject); +} + +static HRESULT WINAPI RegistrarCF_LockServer(IClassFactory *iface, BOOL lock) +{ + TRACE("(%p)->(%x)\n", iface, lock); + + if(lock) + InterlockedIncrement(&dll_count); + else + InterlockedDecrement(&dll_count); + + return S_OK; +} + +static const IClassFactoryVtbl IRegistrarCFVtbl = { + RegistrarCF_QueryInterface, + RegistrarCF_AddRef, + RegistrarCF_Release, + RegistrarCF_CreateInstance, + RegistrarCF_LockServer +}; + +static IClassFactory RegistrarCF = { &IRegistrarCFVtbl }; + +/************************************************************** + * DllGetClassObject (ATL.2) + */ +HRESULT WINAPI DllGetClassObject(REFCLSID clsid, REFIID riid, LPVOID *ppvObject) +{ + TRACE("(%s %s %p)\n", debugstr_guid(clsid), debugstr_guid(riid), ppvObject); + + if(IsEqualGUID(&CLSID_ATLRegistrar, clsid)) { + *ppvObject = &RegistrarCF; + return S_OK; + } + + FIXME("Not supported class %s\n", debugstr_guid(clsid)); + return CLASS_E_CLASSNOTAVAILABLE; +} + +extern HINSTANCE hInst; + +static HRESULT do_register_dll_server(IRegistrar *pRegistrar, LPCOLESTR wszDll, + LPCOLESTR wszId, BOOL do_register, + const struct _ATL_REGMAP_ENTRY* pMapEntries) +{ + WCHAR buf[MAX_PATH]; + HRESULT hres; + const struct _ATL_REGMAP_ENTRY *pMapEntry; + + static const WCHAR wszModule[] = {'M','O','D','U','L','E',0}; + static const WCHAR wszRegistry[] = {'R','E','G','I','S','T','R','Y',0}; + static const WCHAR wszCLSID_ATLRegistrar[] = + {'C','L','S','I','D','_','A','T','L','R','e','g','i','s','t','r','a','r',0}; + + if (!pRegistrar) + Registrar_create(NULL, &IID_IRegistrar, (void**)&pRegistrar); + + IRegistrar_AddReplacement(pRegistrar, wszModule, wszDll); + + for (pMapEntry = pMapEntries; pMapEntry && pMapEntry->szKey; pMapEntry++) + IRegistrar_AddReplacement(pRegistrar, pMapEntry->szKey, pMapEntry->szData); + + StringFromGUID2(&CLSID_ATLRegistrar, buf, sizeof(buf)/sizeof(buf[0])); + IRegistrar_AddReplacement(pRegistrar, wszCLSID_ATLRegistrar, buf); + + if(do_register) + hres = IRegistrar_ResourceRegisterSz(pRegistrar, wszDll, wszId, wszRegistry); + else + hres = IRegistrar_ResourceUnregisterSz(pRegistrar, wszDll, wszId, wszRegistry); + + IRegistrar_Release(pRegistrar); + return hres; +} + +static HRESULT do_register_server(BOOL do_register) +{ + static const WCHAR wszDll[] = {'a','t','l','.','d','l','l',0}; + return do_register_dll_server(NULL, wszDll, MAKEINTRESOURCEW(101), do_register, NULL); +} + +/*********************************************************************** + * AtlModuleUpdateRegistryFromResourceD [ATL.@] + * + */ +HRESULT WINAPI AtlModuleUpdateRegistryFromResourceD(_ATL_MODULEW* pM, LPCOLESTR lpszRes, + BOOL bRegister, struct _ATL_REGMAP_ENTRY* pMapEntries, IRegistrar* pReg) +{ + HINSTANCE lhInst = pM->m_hInst; + /* everything inside this function below this point + * should go into atl71.AtlUpdateRegistryFromResourceD + */ + WCHAR module_name[MAX_PATH]; + + if(!GetModuleFileNameW(lhInst, module_name, MAX_PATH)) { + FIXME("hinst %p: did not get module name\n", + lhInst); + return E_FAIL; + } + + TRACE("%p (%s), %s, %d, %p, %p\n", hInst, debugstr_w(module_name), + debugstr_w(lpszRes), bRegister, pMapEntries, pReg); + + return do_register_dll_server(pReg, module_name, lpszRes, bRegister, pMapEntries); +} + +/*********************************************************************** + * DllRegisterServer (ATL.@) + */ +HRESULT WINAPI DllRegisterServer(void) +{ + TRACE("\n"); + return do_register_server(TRUE); +} + +/*********************************************************************** + * DllRegisterServer (ATL.@) + */ +HRESULT WINAPI DllUnregisterServer(void) +{ + TRACE("\n"); + return do_register_server(FALSE); +} + +/*********************************************************************** + * DllCanUnloadNow (ATL.@) + */ +HRESULT WINAPI DllCanUnloadNow(void) +{ + TRACE("dll_count = %u\n", dll_count); + return dll_count ? S_FALSE : S_OK; +} diff --git a/reactos/dll/win32/atl/rsrc.rc b/reactos/dll/win32/atl/rsrc.rc new file mode 100644 index 00000000000..c55953352c9 --- /dev/null +++ b/reactos/dll/win32/atl/rsrc.rc @@ -0,0 +1,20 @@ +/* + * Copyright 2005 Jacek Caban + * + * 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: atl.rgs */ +101 REGISTRY atl.rgs diff --git a/reactos/dll/win32/win32.rbuild b/reactos/dll/win32/win32.rbuild index 9ca948e56a6..2902b2628e9 100644 --- a/reactos/dll/win32/win32.rbuild +++ b/reactos/dll/win32/win32.rbuild @@ -13,6 +13,9 @@ + + +