From 635f76b085c46f4056684fd185217c495ee432ee Mon Sep 17 00:00:00 2001 From: Christian Costa Date: Thu, 16 May 2013 01:09:01 +0200 Subject: [PATCH] d3dx9_36: Fix ID3DXFileDataImpl_GetName + add some tests. --- dlls/d3dx9_36/tests/xfile.c | 83 +++++++++++++++++++++++++++++++++++++++++++++ dlls/d3dx9_36/xfile.c | 15 ++++++-- 2 files changed, 96 insertions(+), 2 deletions(-) diff --git a/dlls/d3dx9_36/tests/xfile.c b/dlls/d3dx9_36/tests/xfile.c index 49c96ea505f..4ac521b9983 100644 --- a/dlls/d3dx9_36/tests/xfile.c +++ b/dlls/d3dx9_36/tests/xfile.c @@ -55,6 +55,13 @@ static char objects[] = "1; 2; 3;\n" "}\n"; +static char object_noname[] = +"xof 0302txt 0064\n" +"Header\n" +"{\n" +"1; 2; 3;\n" +"}\n"; + static void test_templates(void) { ID3DXFile *d3dxfile; @@ -128,6 +135,81 @@ static void test_lock_unlock(void) d3dxfile->lpVtbl->Release(d3dxfile); } +static void test_getname(void) +{ + ID3DXFile *d3dxfile; + D3DXF_FILELOADMEMORY memory; + ID3DXFileEnumObject *enum_object; + ID3DXFileData *data_object; + SIZE_T length; + char name[100]; + HRESULT ret; + + ret = D3DXFileCreate(&d3dxfile); + ok(ret == S_OK, "D3DXCreateFile failed with %#x\n", ret); + + ret = d3dxfile->lpVtbl->RegisterTemplates(d3dxfile, templates, sizeof(templates) - 1); + ok(ret == S_OK, "RegisterTemplates failed with %#x\n", ret); + + /* Check object with name */ + memory.lpMemory = objects; + memory.dSize = sizeof(objects) - 1; + ret = d3dxfile->lpVtbl->CreateEnumObject(d3dxfile, &memory, D3DXF_FILELOAD_FROMMEMORY, &enum_object); + ok(ret == S_OK, "CreateEnumObject failed with %#x\n", ret); + ret = enum_object->lpVtbl->GetChild(enum_object, 0, &data_object); + ok(ret == S_OK, "GetChild failed with %#x\n", ret); + + ret = data_object->lpVtbl->GetName(data_object, NULL, NULL); + ok(ret == D3DXFERR_BADVALUE, "GetName returned %#x, expected %#x\n", ret, D3DXFERR_BADVALUE); + ret = data_object->lpVtbl->GetName(data_object, name, NULL); + ok(ret == D3DXFERR_BADVALUE, "GetName returned %#x, expected %#x\n", ret, D3DXFERR_BADVALUE); + ret = data_object->lpVtbl->GetName(data_object, NULL, &length); + ok(ret == S_OK, "GetName failed with %#x\n", ret); + ok(length == 7, "Returned length should be 7 instead of %ld\n", length); + length = sizeof(name); + ret = data_object->lpVtbl->GetName(data_object, name, &length); + ok(ret == S_OK, "GetName failed with %#x\n", ret); + ok(length == 7, "Returned length should be 7 instead of %ld\n", length); + ok(!strcmp(name, "Object"), "Returned string should be 'Object' intead of '%s'\n", name); + length = 3; + ret = data_object->lpVtbl->GetName(data_object, name, &length); + ok(ret== D3DXFERR_BADVALUE, "GetName returned %#x, expected %#x\n", ret, D3DXFERR_BADVALUE); + + data_object->lpVtbl->Release(data_object); + enum_object->lpVtbl->Release(enum_object); + + /* Check object without name */ + memory.lpMemory = object_noname; + memory.dSize = sizeof(object_noname) - 1; + ret = d3dxfile->lpVtbl->CreateEnumObject(d3dxfile, &memory, D3DXF_FILELOAD_FROMMEMORY, &enum_object); + ok(ret == S_OK, "CreateEnumObject failed with %#x\n", ret); + ret = enum_object->lpVtbl->GetChild(enum_object, 0, &data_object); + ok(ret == S_OK, "GetChild failed with %#x\n", ret); + + /* Contrary to d3dxof, d3dx9_36 returns an empty string with a null byte when no name is available. + * If the input size is 0, it returns a length of 1 without touching the buffer */ + ret = data_object->lpVtbl->GetName(data_object, NULL, &length); + ok(ret == S_OK, "GetName failed with %#x\n", ret); + ok(length == 1, "Returned length should be 1 instead of %ld\n", length); + length = 0; + name[0] = 0x7f; + ret = data_object->lpVtbl->GetName(data_object, name, &length); + ok(ret == S_OK, "GetName failed with %#x\n", ret); + ok(length == 1, "Returned length should be 1 instead of %ld\n", length); + ok(name[0] == 0x7f, "First character is %#x instead of 0x7f\n", name[0]); + length = sizeof(name); + name[0] = 0x7f; + ret = data_object->lpVtbl->GetName(data_object, name, &length); + ok(ret == S_OK, "GetName failed with %#x\n", ret); + ok(length == 1, "Returned length should be 1 instead of %ld\n", length); + ok(name[0] == 0, "First character is %#x instead of 0x00\n", name[0]); + + data_object->lpVtbl->Release(data_object); + enum_object->lpVtbl->Release(enum_object); + d3dxfile->lpVtbl->Release(d3dxfile); + +} + static inline void debugstr_guid(char* buf, const GUID *id) { sprintf(buf, "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}", @@ -278,5 +360,6 @@ START_TEST(xfile) { test_templates(); test_lock_unlock(); + test_getname(); test_dump(); } diff --git a/dlls/d3dx9_36/xfile.c b/dlls/d3dx9_36/xfile.c index 81f9da35dda..9c57277f8ad 100644 --- a/dlls/d3dx9_36/xfile.c +++ b/dlls/d3dx9_36/xfile.c @@ -38,6 +38,8 @@ static HRESULT error_dxfile_to_d3dxfile(HRESULT error) return D3DXFERR_BADFILEFLOATSIZE; case DXFILEERR_PARSEERROR: return D3DXFERR_PARSEERROR; + case DXFILEERR_BADVALUE: + return D3DXFERR_BADVALUE; default: FIXME("Cannot map error %#x\n", error); return E_FAIL; @@ -151,8 +153,8 @@ static HRESULT WINAPI ID3DXFileDataImpl_GetName(ID3DXFileData *iface, char *name TRACE("(%p)->(%p, %p)\n", iface, name, size); - if (!name || !size) - return E_POINTER; + if (!size) + return D3DXFERR_BADVALUE; dxfile_size = *size; @@ -160,6 +162,15 @@ static HRESULT WINAPI ID3DXFileDataImpl_GetName(ID3DXFileData *iface, char *name if (ret != DXFILE_OK) return error_dxfile_to_d3dxfile(ret); + if (!dxfile_size) + { + /* Contrary to d3dxof, d3dx9_36 returns an empty string with a null byte when no name is available. + * If the input size is 0, it returns a length of 1 without touching the buffer */ + dxfile_size = 1; + if (name && *size) + name[0] = 0; + } + *size = dxfile_size; return S_OK; -- 2.11.4.GIT