static HRESULT WINAPI IAssemblyCacheImpl_QueryAssemblyInfo(IAssemblyCache *iface, DWORD dwFlags, LPCWSTR pszAssemblyName, ASSEMBLY_INFO *pAsmInfo) { IAssemblyCacheImpl *cache = impl_from_IAssemblyCache(iface); IAssemblyName *asmname, *next = NULL; IAssemblyEnum *asmenum = NULL; HRESULT hr; TRACE("(%p, %d, %s, %p)\n", iface, dwFlags, debugstr_w(pszAssemblyName), pAsmInfo); if (pAsmInfo) { if (pAsmInfo->cbAssemblyInfo == 0) pAsmInfo->cbAssemblyInfo = sizeof(ASSEMBLY_INFO); else if (pAsmInfo->cbAssemblyInfo != sizeof(ASSEMBLY_INFO)) return E_INVALIDARG; } hr = CreateAssemblyNameObject(&asmname, pszAssemblyName, CANOF_PARSE_DISPLAY_NAME, NULL); if (FAILED(hr)) return hr; cache_lock( cache ); hr = CreateAssemblyEnum(&asmenum, NULL, asmname, ASM_CACHE_GAC, NULL); if (FAILED(hr)) goto done; for (;;) { hr = IAssemblyEnum_GetNextAssembly(asmenum, NULL, &next, 0); if (hr != S_OK) { hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); goto done; } hr = IAssemblyName_IsEqual(asmname, next, ASM_CMPF_IL_ALL); if (hr == S_OK) break; } if (!pAsmInfo) goto done; hr = IAssemblyName_GetPath(next, pAsmInfo->pszCurrentAssemblyPathBuf, &pAsmInfo->cchBuf); pAsmInfo->dwAssemblyFlags = ASSEMBLYINFO_FLAG_INSTALLED; done: IAssemblyName_Release(asmname); if (next) IAssemblyName_Release(next); if (asmenum) IAssemblyEnum_Release(asmenum); cache_unlock( cache ); return hr; }
static ULONG WINAPI IAssemblyCacheImpl_AddRef(IAssemblyCache *iface) { IAssemblyCacheImpl *This = impl_from_IAssemblyCache(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 *cache = impl_from_IAssemblyCache(iface); ULONG refCount = InterlockedDecrement( &cache->ref ); TRACE("(%p)->(ref before = %u)\n", cache, refCount + 1); if (!refCount) { CloseHandle( cache->lock ); HeapFree( GetProcessHeap(), 0, cache ); } return refCount; }
static HRESULT WINAPI IAssemblyCacheImpl_QueryInterface(IAssemblyCache *iface, REFIID riid, LPVOID *ppobj) { IAssemblyCacheImpl *This = impl_from_IAssemblyCache(iface); TRACE("(%p, %s, %p)\n", This, debugstr_guid(riid), ppobj); *ppobj = NULL; if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IAssemblyCache)) { IAssemblyCache_AddRef(iface); *ppobj = &This->IAssemblyCache_iface; return S_OK; } WARN("(%p, %s, %p): not found\n", This, debugstr_guid(riid), ppobj); return E_NOINTERFACE; }
static HRESULT WINAPI IAssemblyCacheImpl_InstallAssembly(IAssemblyCache *iface, DWORD dwFlags, LPCWSTR pszManifestFilePath, LPCFUSION_INSTALL_REFERENCE pRefData) { static const WCHAR format[] = {'%','s','\\','%','s','\\','%','s','_','_','%','s','\\',0}; static const WCHAR format_v40[] = {'%','s','\\','%','s','\\','v','4','.','0','_','%','s','_','_','%','s','\\',0}; static const WCHAR ext_exe[] = {'.','e','x','e',0}; static const WCHAR ext_dll[] = {'.','d','l','l',0}; IAssemblyCacheImpl *cache = impl_from_IAssemblyCache(iface); ASSEMBLY *assembly; const WCHAR *extension, *filename, *src_dir; WCHAR *name = NULL, *token = NULL, *version = NULL, *asmpath = NULL; WCHAR asmdir[MAX_PATH], *p, **external_files = NULL, *dst_dir = NULL; PEKIND architecture; char *clr_version; DWORD i, count = 0, src_len, dst_len = sizeof(format_v40)/sizeof(format_v40[0]); HRESULT hr; TRACE("(%p, %d, %s, %p)\n", iface, dwFlags, debugstr_w(pszManifestFilePath), pRefData); if (!pszManifestFilePath || !*pszManifestFilePath) return E_INVALIDARG; if (!(extension = strrchrW(pszManifestFilePath, '.'))) return HRESULT_FROM_WIN32(ERROR_INVALID_NAME); if (lstrcmpiW(extension, ext_exe) && lstrcmpiW(extension, ext_dll)) return HRESULT_FROM_WIN32(ERROR_INVALID_NAME); if (GetFileAttributesW(pszManifestFilePath) == INVALID_FILE_ATTRIBUTES) return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); hr = assembly_create(&assembly, pszManifestFilePath); if (FAILED(hr)) { hr = COR_E_ASSEMBLYEXPECTED; goto done; } hr = assembly_get_name(assembly, &name); if (FAILED(hr)) goto done; hr = assembly_get_pubkey_token(assembly, &token); if (FAILED(hr)) goto done; hr = assembly_get_version(assembly, &version); if (FAILED(hr)) goto done; hr = assembly_get_runtime_version(assembly, &clr_version); if (FAILED(hr)) goto done; hr = assembly_get_external_files(assembly, &external_files, &count); if (FAILED(hr)) goto done; cache_lock( cache ); architecture = assembly_get_architecture(assembly); get_assembly_directory(asmdir, MAX_PATH, clr_version, architecture); dst_len += strlenW(asmdir) + strlenW(name) + strlenW(version) + strlenW(token); if (!(dst_dir = HeapAlloc(GetProcessHeap(), 0, dst_len * sizeof(WCHAR)))) { hr = E_OUTOFMEMORY; goto done; } if (!strcmp(clr_version, "v4.0.30319")) dst_len = sprintfW(dst_dir, format_v40, asmdir, name, version, token); else dst_len = sprintfW(dst_dir, format, asmdir, name, version, token); create_full_path(dst_dir); hr = assembly_get_path(assembly, &asmpath); if (FAILED(hr)) goto done; if ((p = strrchrW(asmpath, '\\'))) { filename = p + 1; src_dir = asmpath; src_len = filename - asmpath; } else { filename = asmpath; src_dir = NULL; src_len = 0; } hr = copy_file(src_dir, src_len, dst_dir, dst_len, filename); if (FAILED(hr)) goto done; for (i = 0; i < count; i++) { hr = copy_file(src_dir, src_len, dst_dir, dst_len, external_files[i]); if (FAILED(hr)) break; } done: HeapFree(GetProcessHeap(), 0, name); HeapFree(GetProcessHeap(), 0, token); HeapFree(GetProcessHeap(), 0, version); HeapFree(GetProcessHeap(), 0, asmpath); HeapFree(GetProcessHeap(), 0, dst_dir); for (i = 0; i < count; i++) HeapFree(GetProcessHeap(), 0, external_files[i]); HeapFree(GetProcessHeap(), 0, external_files); assembly_release(assembly); cache_unlock( cache ); return hr; }
static HRESULT WINAPI IAssemblyCacheImpl_UninstallAssembly(IAssemblyCache *iface, DWORD dwFlags, LPCWSTR pszAssemblyName, LPCFUSION_INSTALL_REFERENCE pRefData, ULONG *pulDisposition) { HRESULT hr; IAssemblyCacheImpl *cache = impl_from_IAssemblyCache(iface); IAssemblyName *asmname, *next = NULL; IAssemblyEnum *asmenum = NULL; WCHAR *p, *path = NULL; ULONG disp; DWORD len; TRACE("(%p, 0%08x, %s, %p, %p)\n", iface, dwFlags, debugstr_w(pszAssemblyName), pRefData, pulDisposition); if (pRefData) { FIXME("application reference not supported\n"); return E_NOTIMPL; } hr = CreateAssemblyNameObject( &asmname, pszAssemblyName, CANOF_PARSE_DISPLAY_NAME, NULL ); if (FAILED( hr )) return hr; cache_lock( cache ); hr = CreateAssemblyEnum( &asmenum, NULL, asmname, ASM_CACHE_GAC, NULL ); if (FAILED( hr )) goto done; hr = IAssemblyEnum_GetNextAssembly( asmenum, NULL, &next, 0 ); if (hr == S_FALSE) { if (pulDisposition) *pulDisposition = IASSEMBLYCACHE_UNINSTALL_DISPOSITION_ALREADY_UNINSTALLED; goto done; } hr = IAssemblyName_GetPath( next, NULL, &len ); if (hr != HRESULT_FROM_WIN32( ERROR_INSUFFICIENT_BUFFER )) goto done; if (!(path = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) { hr = E_OUTOFMEMORY; goto done; } hr = IAssemblyName_GetPath( next, path, &len ); if (FAILED( hr )) goto done; if (DeleteFileW( path )) { if ((p = strrchrW( path, '\\' ))) { *p = 0; RemoveDirectoryW( path ); if ((p = strrchrW( path, '\\' ))) { *p = 0; RemoveDirectoryW( path ); } } disp = IASSEMBLYCACHE_UNINSTALL_DISPOSITION_UNINSTALLED; hr = S_OK; } else { disp = IASSEMBLYCACHE_UNINSTALL_DISPOSITION_ALREADY_UNINSTALLED; hr = S_FALSE; } if (pulDisposition) *pulDisposition = disp; done: IAssemblyName_Release( asmname ); if (next) IAssemblyName_Release( next ); if (asmenum) IAssemblyEnum_Release( asmenum ); HeapFree( GetProcessHeap(), 0, path ); cache_unlock( cache ); return hr; }
static HRESULT WINAPI IAssemblyCacheImpl_InstallAssembly(IAssemblyCache *iface, DWORD dwFlags, LPCWSTR pszManifestFilePath, LPCFUSION_INSTALL_REFERENCE pRefData) { static const WCHAR format[] = {'%','s','\\','%','s','\\','%','s','_','_','%','s','\\',0}; static const WCHAR ext_exe[] = {'.','e','x','e',0}; static const WCHAR ext_dll[] = {'.','d','l','l',0}; IAssemblyCacheImpl *cache = impl_from_IAssemblyCache(iface); ASSEMBLY *assembly; LPWSTR filename; LPWSTR name = NULL; LPWSTR token = NULL; LPWSTR version = NULL; LPWSTR asmpath = NULL; WCHAR path[MAX_PATH]; WCHAR asmdir[MAX_PATH]; LPWSTR ext; HRESULT hr; TRACE("(%p, %d, %s, %p)\n", iface, dwFlags, debugstr_w(pszManifestFilePath), pRefData); if (!pszManifestFilePath || !*pszManifestFilePath) return E_INVALIDARG; if (!(ext = strrchrW(pszManifestFilePath, '.'))) return HRESULT_FROM_WIN32(ERROR_INVALID_NAME); if (lstrcmpiW(ext, ext_exe) && lstrcmpiW(ext, ext_dll)) return HRESULT_FROM_WIN32(ERROR_INVALID_NAME); if (GetFileAttributesW(pszManifestFilePath) == INVALID_FILE_ATTRIBUTES) return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); hr = assembly_create(&assembly, pszManifestFilePath); if (FAILED(hr)) { hr = COR_E_ASSEMBLYEXPECTED; goto done; } hr = assembly_get_name(assembly, &name); if (FAILED(hr)) goto done; hr = assembly_get_pubkey_token(assembly, &token); if (FAILED(hr)) goto done; hr = assembly_get_version(assembly, &version); if (FAILED(hr)) goto done; cache_lock( cache ); get_assembly_directory(asmdir, MAX_PATH, assembly_get_architecture(assembly)); sprintfW(path, format, asmdir, name, version, token); create_full_path(path); hr = assembly_get_path(assembly, &asmpath); if (FAILED(hr)) goto done; filename = PathFindFileNameW(asmpath); strcatW(path, filename); if (!CopyFileW(asmpath, path, FALSE)) hr = HRESULT_FROM_WIN32(GetLastError()); done: HeapFree(GetProcessHeap(), 0, name); HeapFree(GetProcessHeap(), 0, token); HeapFree(GetProcessHeap(), 0, version); HeapFree(GetProcessHeap(), 0, asmpath); assembly_release(assembly); cache_unlock( cache ); return hr; }