static HRESULT WINAPI IAssemblyNameImpl_IsEqual(IAssemblyName *iface, IAssemblyName *pName, DWORD flags) { IAssemblyNameImpl *name1 = impl_from_IAssemblyName(iface); IAssemblyNameImpl *name2 = impl_from_IAssemblyName(pName); TRACE("(%p, %p, 0x%08x)\n", iface, pName, flags); if (!pName) return S_FALSE; if (flags & ~ASM_CMPF_IL_ALL) FIXME("unsupported flags\n"); if ((flags & ASM_CMPF_NAME) && strcmpW(name1->name, name2->name)) return S_FALSE; if (name1->versize && name2->versize) { if ((flags & ASM_CMPF_MAJOR_VERSION) && name1->version[0] != name2->version[0]) return S_FALSE; if ((flags & ASM_CMPF_MINOR_VERSION) && name1->version[1] != name2->version[1]) return S_FALSE; if ((flags & ASM_CMPF_BUILD_NUMBER) && name1->version[2] != name2->version[2]) return S_FALSE; if ((flags & ASM_CMPF_REVISION_NUMBER) && name1->version[3] != name2->version[3]) return S_FALSE; } if ((flags & ASM_CMPF_PUBLIC_KEY_TOKEN) && name1->haspubkey && name2->haspubkey && memcmp(name1->pubkey, name2->pubkey, sizeof(name1->pubkey))) return S_FALSE; if ((flags & ASM_CMPF_CULTURE) && name1->culture && name2->culture && strcmpW(name1->culture, name2->culture)) return S_FALSE; return S_OK; }
static HRESULT WINAPI IAssemblyNameImpl_GetName(IAssemblyName *iface, LPDWORD lpcwBuffer, WCHAR *pwzName) { IAssemblyNameImpl *name = impl_from_IAssemblyName(iface); DWORD len; TRACE("(%p, %p, %p)\n", iface, lpcwBuffer, pwzName); if (name->name) len = strlenW(name->name) + 1; else len = 0; if (*lpcwBuffer < len) { *lpcwBuffer = len; return E_NOT_SUFFICIENT_BUFFER; } if (!name->name) lpcwBuffer[0] = 0; else strcpyW(pwzName, name->name); *lpcwBuffer = len; return S_OK; }
static ULONG WINAPI IAssemblyNameImpl_AddRef(IAssemblyName *iface) { IAssemblyNameImpl *This = impl_from_IAssemblyName(iface); ULONG refCount = InterlockedIncrement(&This->ref); TRACE("(%p)->(ref before = %u)\n", This, refCount - 1); return refCount; }
static ULONG WINAPI IAssemblyNameImpl_Release(IAssemblyName *iface) { IAssemblyNameImpl *This = impl_from_IAssemblyName(iface); ULONG refCount = InterlockedDecrement(&This->ref); TRACE("(%p)->(ref before = %u)\n", This, refCount + 1); if (!refCount) { HeapFree(GetProcessHeap(), 0, This->path); HeapFree(GetProcessHeap(), 0, This->displayname); HeapFree(GetProcessHeap(), 0, This->name); HeapFree(GetProcessHeap(), 0, This->culture); HeapFree(GetProcessHeap(), 0, This->procarch); HeapFree(GetProcessHeap(), 0, This); } return refCount; }
static HRESULT WINAPI IAssemblyNameImpl_GetVersion(IAssemblyName *iface, LPDWORD pdwVersionHi, LPDWORD pdwVersionLow) { IAssemblyNameImpl *name = impl_from_IAssemblyName(iface); TRACE("(%p, %p, %p)\n", iface, pdwVersionHi, pdwVersionLow); *pdwVersionHi = 0; *pdwVersionLow = 0; if (name->versize != 4) return FUSION_E_INVALID_NAME; *pdwVersionHi = (name->version[0] << 16) + name->version[1]; *pdwVersionLow = (name->version[2] << 16) + name->version[3]; return S_OK; }
static HRESULT WINAPI IAssemblyNameImpl_QueryInterface(IAssemblyName *iface, REFIID riid, LPVOID *ppobj) { IAssemblyNameImpl *This = impl_from_IAssemblyName(iface); TRACE("(%p, %s, %p)\n", This, debugstr_guid(riid), ppobj); *ppobj = NULL; if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IAssemblyName)) { IAssemblyName_AddRef(iface); *ppobj = This; return S_OK; } WARN("(%p, %s, %p): not found\n", This, debugstr_guid(riid), ppobj); return E_NOINTERFACE; }
static HRESULT WINAPI IAssemblyNameImpl_GetDisplayName(IAssemblyName *iface, LPOLESTR szDisplayName, LPDWORD pccDisplayName, DWORD dwDisplayFlags) { IAssemblyNameImpl *name = impl_from_IAssemblyName(iface); WCHAR verstr[30]; DWORD size; LPWSTR cultureval = 0; static const WCHAR equals[] = {'=',0}; TRACE("(%p, %p, %p, %d)\n", iface, szDisplayName, pccDisplayName, dwDisplayFlags); if (dwDisplayFlags == 0) { if (!name->displayname || !*name->displayname) return FUSION_E_INVALID_NAME; size = min(*pccDisplayName, lstrlenW(name->displayname) + 1); lstrcpynW(szDisplayName, name->displayname, size); *pccDisplayName = size; return S_OK; } if (!name->name || !*name->name) return FUSION_E_INVALID_NAME; /* Verify buffer size is sufficient */ size = lstrlenW(name->name) + 1; if ((dwDisplayFlags & ASM_DISPLAYF_VERSION) && (name->versize > 0)) { static const WCHAR spec[] = {'%','d',0}; static const WCHAR period[] = {'.',0}; DWORD i; wsprintfW(verstr, spec, name->version[0]); for (i = 1; i < name->versize; i++) { WCHAR value[6]; wsprintfW(value, spec, name->version[i]); lstrcatW(verstr, period); lstrcatW(verstr, value); } size += lstrlenW(separator) + lstrlenW(version) + lstrlenW(equals) + lstrlenW(verstr); } if ((dwDisplayFlags & ASM_DISPLAYF_CULTURE) && (name->culture)) { static const WCHAR neutral[] = {'n','e','u','t','r','a','l', 0}; cultureval = (lstrlenW(name->culture) == 2) ? name->culture : (LPWSTR) neutral; size += lstrlenW(separator) + lstrlenW(culture) + lstrlenW(equals) + lstrlenW(cultureval); } if ((dwDisplayFlags & ASM_DISPLAYF_PUBLIC_KEY_TOKEN) && (name->haspubkey)) size += lstrlenW(separator) + lstrlenW(pubkey) + lstrlenW(equals) + CHARS_PER_PUBKEY; if ((dwDisplayFlags & ASM_DISPLAYF_PROCESSORARCHITECTURE) && (name->procarch)) size += lstrlenW(separator) + lstrlenW(procarch) + lstrlenW(equals) + lstrlenW(name->procarch); if (size > *pccDisplayName) return S_FALSE; /* Construct the string */ lstrcpyW(szDisplayName, name->name); if ((dwDisplayFlags & ASM_DISPLAYF_VERSION) && (name->versize > 0)) { lstrcatW(szDisplayName, separator); lstrcatW(szDisplayName, version); lstrcatW(szDisplayName, equals); lstrcatW(szDisplayName, verstr); } if ((dwDisplayFlags & ASM_DISPLAYF_CULTURE) && (name->culture)) { lstrcatW(szDisplayName, separator); lstrcatW(szDisplayName, culture); lstrcatW(szDisplayName, equals); lstrcatW(szDisplayName, cultureval); } if ((dwDisplayFlags & ASM_DISPLAYF_PUBLIC_KEY_TOKEN) && (name->haspubkey)) { WCHAR pkt[CHARS_PER_PUBKEY + 1]; static const WCHAR spec[] = {'%','0','x','%','0','x','%','0','x', '%','0','x','%','0','x','%','0','x','%','0','x','%','0','x',0}; lstrcatW(szDisplayName, separator); lstrcatW(szDisplayName, pubkey); lstrcatW(szDisplayName, equals); wsprintfW(pkt, spec, name->pubkey[0], name->pubkey[1], name->pubkey[2], name->pubkey[3], name->pubkey[4], name->pubkey[5], name->pubkey[6], name->pubkey[7]); lstrcatW(szDisplayName, pkt); } if ((dwDisplayFlags & ASM_DISPLAYF_PROCESSORARCHITECTURE) && (name->procarch)) { lstrcatW(szDisplayName, separator); lstrcatW(szDisplayName, procarch); lstrcatW(szDisplayName, equals); lstrcatW(szDisplayName, name->procarch); } *pccDisplayName = size; return S_OK; }
static HRESULT WINAPI IAssemblyNameImpl_GetProperty(IAssemblyName *iface, DWORD PropertyId, LPVOID pvProperty, LPDWORD pcbProperty) { IAssemblyNameImpl *name = impl_from_IAssemblyName(iface); TRACE("(%p, %d, %p, %p)\n", iface, PropertyId, pvProperty, pcbProperty); *((LPWSTR)pvProperty) = '\0'; switch (PropertyId) { case ASM_NAME_NULL_PUBLIC_KEY: case ASM_NAME_NULL_PUBLIC_KEY_TOKEN: if (name->haspubkey) return S_OK; return S_FALSE; case ASM_NAME_NULL_CUSTOM: return S_OK; case ASM_NAME_NAME: *pcbProperty = 0; if (name->name) { lstrcpyW(pvProperty, name->name); *pcbProperty = (lstrlenW(name->name) + 1) * 2; } break; case ASM_NAME_MAJOR_VERSION: *pcbProperty = 0; *((WORD *)pvProperty) = name->version[0]; if (name->versize >= 1) *pcbProperty = sizeof(WORD); break; case ASM_NAME_MINOR_VERSION: *pcbProperty = 0; *((WORD *)pvProperty) = name->version[1]; if (name->versize >= 2) *pcbProperty = sizeof(WORD); break; case ASM_NAME_BUILD_NUMBER: *pcbProperty = 0; *((WORD *)pvProperty) = name->version[2]; if (name->versize >= 3) *pcbProperty = sizeof(WORD); break; case ASM_NAME_REVISION_NUMBER: *pcbProperty = 0; *((WORD *)pvProperty) = name->version[3]; if (name->versize >= 4) *pcbProperty = sizeof(WORD); break; case ASM_NAME_CULTURE: *pcbProperty = 0; if (name->culture) { lstrcpyW(pvProperty, name->culture); *pcbProperty = (lstrlenW(name->culture) + 1) * 2; } break; case ASM_NAME_PUBLIC_KEY_TOKEN: *pcbProperty = 0; if (name->haspubkey) { memcpy(pvProperty, name->pubkey, sizeof(DWORD) * 2); *pcbProperty = sizeof(DWORD) * 2; } break; default: *pcbProperty = 0; break; } return S_OK; }
/* Internal methods */ static inline IAssemblyNameImpl *unsafe_impl_from_IAssemblyName(IAssemblyName *iface) { assert(iface->lpVtbl == &AssemblyNameVtbl); return impl_from_IAssemblyName(iface); }
static HRESULT WINAPI IAssemblyNameImpl_GetProperty(IAssemblyName *iface, DWORD PropertyId, LPVOID pvProperty, LPDWORD pcbProperty) { IAssemblyNameImpl *name = impl_from_IAssemblyName(iface); DWORD size; TRACE("(%p, %d, %p, %p)\n", iface, PropertyId, pvProperty, pcbProperty); size = *pcbProperty; switch (PropertyId) { case ASM_NAME_NULL_PUBLIC_KEY: case ASM_NAME_NULL_PUBLIC_KEY_TOKEN: if (name->haspubkey) return S_OK; return S_FALSE; case ASM_NAME_NULL_CUSTOM: return S_OK; case ASM_NAME_NAME: *pcbProperty = 0; if (name->name) { *pcbProperty = (lstrlenW(name->name) + 1) * 2; if (size < *pcbProperty) return STRSAFE_E_INSUFFICIENT_BUFFER; lstrcpyW(pvProperty, name->name); } break; case ASM_NAME_MAJOR_VERSION: *pcbProperty = 0; if (name->versize >= 1) { *pcbProperty = sizeof(WORD); if (size < *pcbProperty) return STRSAFE_E_INSUFFICIENT_BUFFER; *((WORD *)pvProperty) = name->version[0]; } break; case ASM_NAME_MINOR_VERSION: *pcbProperty = 0; if (name->versize >= 2) { *pcbProperty = sizeof(WORD); if (size < *pcbProperty) return STRSAFE_E_INSUFFICIENT_BUFFER; *((WORD *)pvProperty) = name->version[1]; } break; case ASM_NAME_BUILD_NUMBER: *pcbProperty = 0; if (name->versize >= 3) { *pcbProperty = sizeof(WORD); if (size < *pcbProperty) return STRSAFE_E_INSUFFICIENT_BUFFER; *((WORD *)pvProperty) = name->version[2]; } break; case ASM_NAME_REVISION_NUMBER: *pcbProperty = 0; if (name->versize >= 4) { *pcbProperty = sizeof(WORD); if (size < *pcbProperty) return STRSAFE_E_INSUFFICIENT_BUFFER; *((WORD *)pvProperty) = name->version[3]; } break; case ASM_NAME_CULTURE: *pcbProperty = 0; if (name->culture) { *pcbProperty = (lstrlenW(name->culture) + 1) * 2; if (size < *pcbProperty) return STRSAFE_E_INSUFFICIENT_BUFFER; lstrcpyW(pvProperty, name->culture); } break; case ASM_NAME_PUBLIC_KEY_TOKEN: *pcbProperty = 0; if (name->haspubkey) { *pcbProperty = sizeof(DWORD) * 2; if (size < *pcbProperty) return STRSAFE_E_INSUFFICIENT_BUFFER; memcpy(pvProperty, name->pubkey, sizeof(DWORD) * 2); } break; case ASM_NAME_ARCHITECTURE: *pcbProperty = 0; if (name->pekind != peNone) { *pcbProperty = sizeof(PEKIND); if (size < *pcbProperty) return STRSAFE_E_INSUFFICIENT_BUFFER; *((PEKIND *)pvProperty) = name->pekind; } break; default: *pcbProperty = 0; break; } return S_OK; }