diff --git a/dlls/fusion/Makefile.in b/dlls/fusion/Makefile.in index f7c47f8cc5c..21792c8aa65 100644 --- a/dlls/fusion/Makefile.in +++ b/dlls/fusion/Makefile.in @@ -6,6 +6,7 @@ MODULE = fusion.dll IMPORTS = kernel32 C_SRCS = \ + asmcache.c \ asmname.c \ fusion.c \ fusion_main.c diff --git a/dlls/fusion/asmcache.c b/dlls/fusion/asmcache.c new file mode 100644 index 00000000000..36c29f230f6 --- /dev/null +++ b/dlls/fusion/asmcache.c @@ -0,0 +1,237 @@ +/* + * IAssemblyCache implementation + * + * Copyright 2008 James Hawkins + * + * 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 "ole2.h" +#include "fusion.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(fusion); + +/* IAssemblyCache */ + +typedef struct { + const IAssemblyCacheVtbl *lpIAssemblyCacheVtbl; + + LONG ref; +} IAssemblyCacheImpl; + +static HRESULT WINAPI IAssemblyCacheImpl_QueryInterface(IAssemblyCache *iface, + REFIID riid, LPVOID *ppobj) +{ + IAssemblyCacheImpl *This = (IAssemblyCacheImpl *)iface; + + TRACE("(%p, %s, %p)\n", This, debugstr_guid(riid), ppobj); + + *ppobj = NULL; + + if (IsEqualIID(riid, &IID_IUnknown) || + IsEqualIID(riid, &IID_IAssemblyCache)) + { + IUnknown_AddRef(iface); + *ppobj = This; + return S_OK; + } + + WARN("(%p, %s, %p): not found\n", This, debugstr_guid(riid), ppobj); + return E_NOINTERFACE; +} + +static ULONG WINAPI IAssemblyCacheImpl_AddRef(IAssemblyCache *iface) +{ + IAssemblyCacheImpl *This = (IAssemblyCacheImpl *)iface; + ULONG refCount = InterlockedIncrement(&This->ref); + + TRACE("(%p)->(ref before = %u)\n", This, refCount - 1); + + return refCount; +} + +static ULONG WINAPI IAssemblyCacheImpl_Release(IAssemblyCache *iface) +{ + IAssemblyCacheImpl *This = (IAssemblyCacheImpl *)iface; + ULONG refCount = InterlockedDecrement(&This->ref); + + TRACE("(%p)->(ref before = %u)\n", This, refCount + 1); + + if (!refCount) + HeapFree(GetProcessHeap(), 0, This); + + return refCount; +} + +static HRESULT WINAPI IAssemblyCacheImpl_UninstallAssembly(IAssemblyCache *iface, + DWORD dwFlags, + LPCWSTR pszAssemblyName, + LPCFUSION_INSTALL_REFERENCE pRefData, + ULONG *pulDisposition) +{ + FIXME("(%p, %d, %s, %p, %p) stub!\n", iface, dwFlags, + debugstr_w(pszAssemblyName), pRefData, pulDisposition); + + return E_NOTIMPL; +} + +static HRESULT WINAPI IAssemblyCacheImpl_QueryAssemblyInfo(IAssemblyCache *iface, + DWORD dwFlags, + LPCWSTR pszAssemblyName, + ASSEMBLY_INFO *pAsmInfo) +{ + FIXME("(%p, %d, %s, %p) stub!\n", iface, dwFlags, + debugstr_w(pszAssemblyName), pAsmInfo); + + return E_NOTIMPL; +} + +static HRESULT WINAPI IAssemblyCacheImpl_CreateAssemblyCacheItem(IAssemblyCache *iface, + DWORD dwFlags, + PVOID pvReserved, + IAssemblyCacheItem **ppAsmItem, + LPCWSTR pszAssemblyName) +{ + FIXME("(%p, %d, %p, %p, %s) stub!\n", iface, dwFlags, pvReserved, + ppAsmItem, debugstr_w(pszAssemblyName)); + + return E_NOTIMPL; +} + +static HRESULT WINAPI IAssemblyCacheImpl_CreateAssemblyScavenger(IAssemblyCache *iface, + IUnknown **ppUnkReserved) +{ + FIXME("(%p, %p) stub!\n", iface, ppUnkReserved); + return E_NOTIMPL; +} + +static HRESULT WINAPI IAssemblyCacheImpl_InstallAssembly(IAssemblyCache *iface, + DWORD dwFlags, + LPCWSTR pszManifestFilePath, + LPCFUSION_INSTALL_REFERENCE pRefData) +{ + FIXME("(%p, %d, %s, %p) stub!\n", iface, dwFlags, + debugstr_w(pszManifestFilePath), pRefData); + + return E_NOTIMPL; +} + +static const IAssemblyCacheVtbl AssemblyCacheVtbl = { + IAssemblyCacheImpl_QueryInterface, + IAssemblyCacheImpl_AddRef, + IAssemblyCacheImpl_Release, + IAssemblyCacheImpl_UninstallAssembly, + IAssemblyCacheImpl_QueryAssemblyInfo, + IAssemblyCacheImpl_CreateAssemblyCacheItem, + IAssemblyCacheImpl_CreateAssemblyScavenger, + IAssemblyCacheImpl_InstallAssembly +}; + +/* IAssemblyCacheItem */ + +typedef struct { + const IAssemblyCacheItemVtbl *lpIAssemblyCacheItemVtbl; + + LONG ref; +} IAssemblyCacheItemImpl; + +static HRESULT WINAPI IAssemblyCacheItemImpl_QueryInterface(IAssemblyCacheItem *iface, + REFIID riid, LPVOID *ppobj) +{ + IAssemblyCacheItemImpl *This = (IAssemblyCacheItemImpl *)iface; + + TRACE("(%p, %s, %p)\n", This, debugstr_guid(riid), ppobj); + + *ppobj = NULL; + + if (IsEqualIID(riid, &IID_IUnknown) || + IsEqualIID(riid, &IID_IAssemblyCacheItem)) + { + IUnknown_AddRef(iface); + *ppobj = This; + return S_OK; + } + + WARN("(%p, %s, %p): not found\n", This, debugstr_guid(riid), ppobj); + return E_NOINTERFACE; +} + +static ULONG WINAPI IAssemblyCacheItemImpl_AddRef(IAssemblyCacheItem *iface) +{ + IAssemblyCacheItemImpl *This = (IAssemblyCacheItemImpl *)iface; + ULONG refCount = InterlockedIncrement(&This->ref); + + TRACE("(%p)->(ref before = %u)\n", This, refCount - 1); + + return refCount; +} + +static ULONG WINAPI IAssemblyCacheItemImpl_Release(IAssemblyCacheItem *iface) +{ + IAssemblyCacheItemImpl *This = (IAssemblyCacheItemImpl *)iface; + ULONG refCount = InterlockedDecrement(&This->ref); + + TRACE("(%p)->(ref before = %u)\n", This, refCount + 1); + + if (!refCount) + HeapFree(GetProcessHeap(), 0, This); + + return refCount; +} + +static HRESULT WINAPI IAssemblyCacheItemImpl_CreateStream(IAssemblyCacheItem *iface, + DWORD dwFlags, + LPCWSTR pszStreamName, + DWORD dwFormat, + DWORD dwFormatFlags, + IStream **ppIStream, + ULARGE_INTEGER *puliMaxSize) +{ + FIXME("(%p, %d, %s, %d, %d, %p, %p) stub!\n", iface, dwFlags, + debugstr_w(pszStreamName), dwFormat, dwFormatFlags, ppIStream, puliMaxSize); + + return E_NOTIMPL; +} + +static HRESULT WINAPI IAssemblyCacheItemImpl_Commit(IAssemblyCacheItem *iface, + DWORD dwFlags, + ULONG *pulDisposition) +{ + FIXME("(%p, %d, %p) stub!\n", iface, dwFlags, pulDisposition); + return E_NOTIMPL; +} + +static HRESULT WINAPI IAssemblyCacheItemImpl_AbortItem(IAssemblyCacheItem *iface) +{ + FIXME("(%p) stub!\n", iface); + return E_NOTIMPL; +} + +static const IAssemblyCacheItemVtbl AssemblyCacheItemVtbl = { + IAssemblyCacheItemImpl_QueryInterface, + IAssemblyCacheItemImpl_AddRef, + IAssemblyCacheItemImpl_Release, + IAssemblyCacheItemImpl_CreateStream, + IAssemblyCacheItemImpl_Commit, + IAssemblyCacheItemImpl_AbortItem +}; diff --git a/include/fusion.idl b/include/fusion.idl index 0596192b500..6f140828db9 100644 --- a/include/fusion.idl +++ b/include/fusion.idl @@ -65,7 +65,65 @@ typedef enum _tagAssemblyComparisonResult ] interface IAssemblyCache : IUnknown { + typedef struct _FUSION_INSTALL_REFERENCE_ + { + DWORD cbSize; + DWORD dwFlags; + GUID guidScheme; + LPCWSTR szIdentifier; + LPCWSTR szNonCannonicalData; + } FUSION_INSTALL_REFERENCE, *LPFUSION_INSTALL_REFERENCE; + typedef const FUSION_INSTALL_REFERENCE *LPCFUSION_INSTALL_REFERENCE; + + typedef struct _ASSEMBLY_INFO + { + ULONG cbAssemblyInfo; + DWORD dwAssemblyFlags; + ULARGE_INTEGER uliAssemblySizeInKB; + LPWSTR pszCurrentAssemblyPathBuf; + ULONG cchBuf; + } ASSEMBLY_INFO; + + cpp_quote("#define IASSEMBLYCACHE_INSTALL_FLAG_REFRESH 0x00000001") + cpp_quote("#define IASSEMBLYCACHE_INSTALL_FLAG_FORCE_REFRESH 0x00000002") + + cpp_quote("#define IASSEMBLYCACHE_UNINSTALL_DISPOSITION_UNINSTALLED 1") + cpp_quote("#define IASSEMBLYCACHE_UNINSTALL_DISPOSITION_STILL_IN_USE 2") + cpp_quote("#define IASSEMBLYCACHE_UNINSTALL_DISPOSITION_ALREADY_UNINSTALLED 3") + cpp_quote("#define IASSEMBLYCACHE_UNINSTALL_DISPOSITION_DELETE_PENDING 4") + cpp_quote("#define IASSEMBLYCACHE_UNINSTALL_DISPOSITION_HAS_INSTALL_REFERENCES 5") + cpp_quote("#define IASSEMBLYCACHE_UNINSTALL_DISPOSITION_REFERENCE_NOT_FOUND 6") + + cpp_quote("#define QUERYASMINFO_FLAG_VALIDATE 0x00000001") + cpp_quote("#define QUERYASMINFO_FLAG_GETSIZE 0x00000002") + + cpp_quote("#define ASSEMBLYINFO_FLAG_INSTALLED 0x00000001") + cpp_quote("#define ASSEMBLYINFO_FLAG_PAYLOADRESIDENT 0x00000002") + + HRESULT UninstallAssembly( + [in] DWORD dwFlags, + [in] LPCWSTR pszAssemblyName, + [in] LPCFUSION_INSTALL_REFERENCE pRefData, + [out, optional] ULONG *pulDisposition); + + HRESULT QueryAssemblyInfo( + [in] DWORD dwFlags, + [in] LPCWSTR pszAssemblyName, + [in, out] ASSEMBLY_INFO *pAsmInfo); + + HRESULT CreateAssemblyCacheItem( + [in] DWORD dwFlags, + [in] PVOID pvReserved, + [out] IAssemblyCacheItem **ppAsmItem, + [in, optional] LPCWSTR pszAssemblyName); + + HRESULT CreateAssemblyScavenger([out] IUnknown **ppUnkReserved); + + HRESULT InstallAssembly( + [in] DWORD dwFlags, + [in] LPCWSTR pszManifestFilePath, + [in] LPCFUSION_INSTALL_REFERENCE pRefData); } [ @@ -76,7 +134,31 @@ interface IAssemblyCache : IUnknown ] interface IAssemblyCacheItem : IUnknown { + cpp_quote("#define STREAM_FORMAT_COMPLIB_MODULE 0") + cpp_quote("#define STREAM_FORMAT_COMPLIB_MANIFEST 1") + cpp_quote("#define STREAM_FORMAT_WIN32_MODULE 2") + cpp_quote("#define STREAM_FORMAT_WIN32_MANIFEST 4") + cpp_quote("#define IASSEMBLYCACHEITEM_COMMIT_FLAG_REFRESH 0x00000001") + cpp_quote("#define IASSEMBLYCACHEITEM_COMMIT_FLAG_FORCE_REFRESH 0x00000002") + + cpp_quote("#define IASSEMBLYCACHEITEM_COMMIT_DISPOSITION_INSTALLED 1") + cpp_quote("#define IASSEMBLYCACHEITEM_COMMIT_DISPOSITION_REFRESHED 2") + cpp_quote("#define IASSEMBLYCACHEITEM_COMMIT_DISPOSITION_ALREADY_INSTALLED 3") + + HRESULT CreateStream( + [in] DWORD dwFlags, + [in] LPCWSTR pszStreamName, + [in] DWORD dwFormat, + [in] DWORD dwFormatFlags, + [out] IStream **ppIStream, + [in, optional] ULARGE_INTEGER *puliMaxSize); + + HRESULT Commit( + [in] DWORD dwFlags, + [out, optional] ULONG *pulDisposition); + + HRESULT AbortItem(); } [