fusion: Implement IAssemblyNameImpl_GetDisplayName more completely.
This commit is contained in:
parent
c411b45da9
commit
11dea57f69
|
@ -3,7 +3,7 @@ TOPOBJDIR = ../..
|
||||||
SRCDIR = @srcdir@
|
SRCDIR = @srcdir@
|
||||||
VPATH = @srcdir@
|
VPATH = @srcdir@
|
||||||
MODULE = fusion.dll
|
MODULE = fusion.dll
|
||||||
IMPORTS = advapi32 dbghelp kernel32 shlwapi version
|
IMPORTS = advapi32 dbghelp kernel32 shlwapi version user32
|
||||||
|
|
||||||
C_SRCS = \
|
C_SRCS = \
|
||||||
asmcache.c \
|
asmcache.c \
|
||||||
|
|
|
@ -43,6 +43,7 @@ typedef struct {
|
||||||
LPWSTR displayname;
|
LPWSTR displayname;
|
||||||
LPWSTR name;
|
LPWSTR name;
|
||||||
LPWSTR culture;
|
LPWSTR culture;
|
||||||
|
LPWSTR procarch;
|
||||||
|
|
||||||
WORD version[4];
|
WORD version[4];
|
||||||
DWORD versize;
|
DWORD versize;
|
||||||
|
@ -53,6 +54,16 @@ typedef struct {
|
||||||
LONG ref;
|
LONG ref;
|
||||||
} IAssemblyNameImpl;
|
} 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,
|
static HRESULT WINAPI IAssemblyNameImpl_QueryInterface(IAssemblyName *iface,
|
||||||
REFIID riid, LPVOID *ppobj)
|
REFIID riid, LPVOID *ppobj)
|
||||||
{
|
{
|
||||||
|
@ -208,16 +219,120 @@ static HRESULT WINAPI IAssemblyNameImpl_GetDisplayName(IAssemblyName *iface,
|
||||||
DWORD dwDisplayFlags)
|
DWORD dwDisplayFlags)
|
||||||
{
|
{
|
||||||
IAssemblyNameImpl *name = (IAssemblyNameImpl *)iface;
|
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,
|
TRACE("(%p, %p, %p, %d)\n", iface, szDisplayName,
|
||||||
pccDisplayName, dwDisplayFlags);
|
pccDisplayName, dwDisplayFlags);
|
||||||
|
|
||||||
|
if (dwDisplayFlags == 0)
|
||||||
|
{
|
||||||
if (!name->displayname || !*name->displayname)
|
if (!name->displayname || !*name->displayname)
|
||||||
return FUSION_E_INVALID_NAME;
|
return FUSION_E_INVALID_NAME;
|
||||||
|
|
||||||
lstrcpyW(szDisplayName, name->displayname);
|
size = min(*pccDisplayName, lstrlenW(name->displayname) + 1);
|
||||||
*pccDisplayName = lstrlenW(szDisplayName) + 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;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -347,8 +462,6 @@ static HRESULT parse_culture(IAssemblyNameImpl *name, LPWSTR culture)
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CHARS_PER_PUBKEY 16
|
|
||||||
|
|
||||||
static BOOL is_hex(WCHAR c)
|
static BOOL is_hex(WCHAR c)
|
||||||
{
|
{
|
||||||
return ((c >= 'a' && c <= 'f') ||
|
return ((c >= 'a' && c <= 'f') ||
|
||||||
|
@ -397,12 +510,6 @@ static HRESULT parse_display_name(IAssemblyNameImpl *name, LPCWSTR szAssemblyNam
|
||||||
HRESULT hr = S_OK;
|
HRESULT hr = S_OK;
|
||||||
BOOL done = FALSE;
|
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)
|
if (!szAssemblyName)
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
|
||||||
|
@ -462,6 +569,11 @@ static HRESULT parse_display_name(IAssemblyNameImpl *name, LPCWSTR szAssemblyNam
|
||||||
hr = parse_culture(name, ptr);
|
hr = parse_culture(name, ptr);
|
||||||
else if (!lstrcmpW(str, pubkey))
|
else if (!lstrcmpW(str, pubkey))
|
||||||
hr = parse_pubkey(name, ptr);
|
hr = parse_pubkey(name, ptr);
|
||||||
|
else if (!lstrcmpW(str, procarch))
|
||||||
|
{
|
||||||
|
name->procarch = strdupW(ptr);
|
||||||
|
hr = S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
goto done;
|
goto done;
|
||||||
|
|
|
@ -718,6 +718,96 @@ static void test_CreateAssemblyNameObject(void)
|
||||||
|
|
||||||
IAssemblyName_Release(name);
|
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 */
|
/* invalid property */
|
||||||
to_widechar(namestr, "wine, BadProp=42");
|
to_widechar(namestr, "wine, BadProp=42");
|
||||||
name = NULL;
|
name = NULL;
|
||||||
|
@ -729,11 +819,8 @@ static void test_CreateAssemblyNameObject(void)
|
||||||
str[0] = '\0';
|
str[0] = '\0';
|
||||||
hr = IAssemblyName_GetDisplayName(name, str, &size, ASM_DISPLAYF_FULL);
|
hr = IAssemblyName_GetDisplayName(name, str, &size, ASM_DISPLAYF_FULL);
|
||||||
ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
|
ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
|
||||||
todo_wine
|
|
||||||
{
|
|
||||||
ok_aw("wine", str);
|
ok_aw("wine", str);
|
||||||
ok(size == 5, "Expected 5, got %d\n", size);
|
ok(size == 5, "Expected 5, got %d\n", size);
|
||||||
}
|
|
||||||
|
|
||||||
size = MAX_PATH;
|
size = MAX_PATH;
|
||||||
str[0] = '\0';
|
str[0] = '\0';
|
||||||
|
|
Loading…
Reference in New Issue