fusion: Implement IAssemblyNameImpl_GetDisplayName more completely.
This commit is contained in:
parent
c411b45da9
commit
11dea57f69
|
@ -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 \
|
||||
|
|
|
@ -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 (dwDisplayFlags == 0)
|
||||
{
|
||||
if (!name->displayname || !*name->displayname)
|
||||
return FUSION_E_INVALID_NAME;
|
||||
|
||||
lstrcpyW(szDisplayName, name->displayname);
|
||||
*pccDisplayName = lstrlenW(szDisplayName) + 1;
|
||||
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};
|
||||
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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
size = MAX_PATH;
|
||||
str[0] = '\0';
|
||||
|
|
Loading…
Reference in New Issue