fusion: Implement IAssemblyNameImpl_GetDisplayName more completely.

This commit is contained in:
Owen Rudge 2010-07-20 18:02:36 +01:00 committed by Alexandre Julliard
parent c411b45da9
commit 11dea57f69
3 changed files with 216 additions and 17 deletions

View File

@ -3,7 +3,7 @@ TOPOBJDIR = ../..
SRCDIR = @srcdir@
VPATH = @srcdir@
MODULE = fusion.dll
IMPORTS = advapi32 dbghelp kernel32 shlwapi version
IMPORTS = advapi32 dbghelp kernel32 shlwapi version user32
C_SRCS = \
asmcache.c \

View File

@ -43,6 +43,7 @@ typedef struct {
LPWSTR displayname;
LPWSTR name;
LPWSTR culture;
LPWSTR procarch;
WORD version[4];
DWORD versize;
@ -53,6 +54,16 @@ typedef struct {
LONG ref;
} IAssemblyNameImpl;
static const WCHAR separator[] = {',',' ',0};
static const WCHAR version[] = {'V','e','r','s','i','o','n',0};
static const WCHAR culture[] = {'C','u','l','t','u','r','e',0};
static const WCHAR pubkey[] =
{'P','u','b','l','i','c','K','e','y','T','o','k','e','n',0};
static const WCHAR procarch[] = {'p','r','o','c','e','s','s','o','r',
'A','r','c','h','i','t','e','c','t','u','r','e',0};
#define CHARS_PER_PUBKEY 16
static HRESULT WINAPI IAssemblyNameImpl_QueryInterface(IAssemblyName *iface,
REFIID riid, LPVOID *ppobj)
{
@ -208,16 +219,120 @@ static HRESULT WINAPI IAssemblyNameImpl_GetDisplayName(IAssemblyName *iface,
DWORD dwDisplayFlags)
{
IAssemblyNameImpl *name = (IAssemblyNameImpl *)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 (!name->displayname || !*name->displayname)
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;
lstrcpyW(szDisplayName, name->displayname);
*pccDisplayName = lstrlenW(szDisplayName) + 1;
/* 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};
int 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;
}
@ -347,8 +462,6 @@ static HRESULT parse_culture(IAssemblyNameImpl *name, LPWSTR culture)
return S_OK;
}
#define CHARS_PER_PUBKEY 16
static BOOL is_hex(WCHAR c)
{
return ((c >= 'a' && c <= 'f') ||
@ -397,12 +510,6 @@ static HRESULT parse_display_name(IAssemblyNameImpl *name, LPCWSTR szAssemblyNam
HRESULT hr = S_OK;
BOOL done = FALSE;
static const WCHAR separator[] = {',',' ',0};
static const WCHAR version[] = {'V','e','r','s','i','o','n',0};
static const WCHAR culture[] = {'C','u','l','t','u','r','e',0};
static const WCHAR pubkey[] =
{'P','u','b','l','i','c','K','e','y','T','o','k','e','n',0};
if (!szAssemblyName)
return S_OK;
@ -462,6 +569,11 @@ static HRESULT parse_display_name(IAssemblyNameImpl *name, LPCWSTR szAssemblyNam
hr = parse_culture(name, ptr);
else if (!lstrcmpW(str, pubkey))
hr = parse_pubkey(name, ptr);
else if (!lstrcmpW(str, procarch))
{
name->procarch = strdupW(ptr);
hr = S_OK;
}
if (FAILED(hr))
goto done;

View File

@ -718,6 +718,96 @@ static void test_CreateAssemblyNameObject(void)
IAssemblyName_Release(name);
/* Processor architecture tests */
to_widechar(namestr, "wine, processorArchitecture=x86");
name = NULL;
hr = pCreateAssemblyNameObject(&name, namestr, CANOF_PARSE_DISPLAY_NAME, NULL);
ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
ok(name != NULL, "Expected non-NULL name\n");
size = MAX_PATH;
hr = IAssemblyName_GetDisplayName(name, str, &size, ASM_DISPLAYF_PROCESSORARCHITECTURE);
ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
WideCharToMultiByte(CP_ACP, 0, str, -1, string1, MAX_PATH, NULL, NULL);
if (lstrcmpA(string1, "wine") == 0)
win_skip("processorArchitecture not supported on .NET 1.x\n");
else
{
ok_aw("wine, processorArchitecture=x86", str);
ok(size == 32, "Expected 32, got %d\n", size);
IAssemblyName_Release(name);
/* amd64 */
to_widechar(namestr, "wine, processorArchitecture=AMD64");
name = NULL;
hr = pCreateAssemblyNameObject(&name, namestr, CANOF_PARSE_DISPLAY_NAME, NULL);
size = MAX_PATH;
hr = IAssemblyName_GetDisplayName(name, str, &size, ASM_DISPLAYF_PROCESSORARCHITECTURE);
ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
ok_aw("wine, processorArchitecture=AMD64", str);
ok(size == 34, "Expected 34, got %d\n", size);
IAssemblyName_Release(name);
/* ia64 */
to_widechar(namestr, "wine, processorArchitecture=IA64");
name = NULL;
hr = pCreateAssemblyNameObject(&name, namestr, CANOF_PARSE_DISPLAY_NAME, NULL);
size = MAX_PATH;
hr = IAssemblyName_GetDisplayName(name, str, &size, ASM_DISPLAYF_PROCESSORARCHITECTURE);
ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
ok_aw("wine, processorArchitecture=IA64", str);
ok(size == 33, "Expected 33, got %d\n", size);
IAssemblyName_Release(name);
/* msil */
to_widechar(namestr, "wine, processorArchitecture=MSIL");
name = NULL;
hr = pCreateAssemblyNameObject(&name, namestr, CANOF_PARSE_DISPLAY_NAME, NULL);
size = MAX_PATH;
hr = IAssemblyName_GetDisplayName(name, str, &size, ASM_DISPLAYF_PROCESSORARCHITECTURE);
ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
ok_aw("wine, processorArchitecture=MSIL", str);
ok(size == 33, "Expected 33, got %d\n", size);
IAssemblyName_Release(name);
}
/* Pulling out various different values */
to_widechar(namestr, "wine, Version=1.2.3.4, Culture=en, PublicKeyToken=1234567890abcdef");
name = NULL;
hr = pCreateAssemblyNameObject(&name, namestr, CANOF_PARSE_DISPLAY_NAME, NULL);
ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
ok(name != NULL, "Expected non-NULL name\n");
size = MAX_PATH;
hr = IAssemblyName_GetDisplayName(name, str, &size, ASM_DISPLAYF_VERSION | ASM_DISPLAYF_CULTURE);
ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
ok_aw("wine, Version=1.2.3.4, Culture=en", str);
ok(size == 34, "Expected 34, got %d\n", size);
size = MAX_PATH;
hr = IAssemblyName_GetDisplayName(name, str, &size, ASM_DISPLAYF_CULTURE | ASM_DISPLAYF_PUBLIC_KEY_TOKEN);
ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
ok_aw("wine, Culture=en, PublicKeyToken=1234567890abcdef", str);
ok(size == 50, "Expected 50, got %d\n", size);
size = MAX_PATH;
hr = IAssemblyName_GetDisplayName(name, str, &size, ASM_DISPLAYF_FULL);
ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
ok_aw("wine, Version=1.2.3.4, Culture=en, PublicKeyToken=1234567890abcdef", str);
ok(size == 67, "Expected 67, got %d\n", size);
IAssemblyName_Release(name);
/* invalid property */
to_widechar(namestr, "wine, BadProp=42");
name = NULL;
@ -729,11 +819,8 @@ static void test_CreateAssemblyNameObject(void)
str[0] = '\0';
hr = IAssemblyName_GetDisplayName(name, str, &size, ASM_DISPLAYF_FULL);
ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
todo_wine
{
ok_aw("wine", str);
ok(size == 5, "Expected 5, got %d\n", size);
}
ok_aw("wine", str);
ok(size == 5, "Expected 5, got %d\n", size);
size = MAX_PATH;
str[0] = '\0';