Reserve extra space for conversions.

This commit is contained in:
Paul Vriens 2005-08-29 14:17:27 +00:00 committed by Alexandre Julliard
parent 0628c7eba6
commit 31d0e7421e
2 changed files with 84 additions and 9 deletions

View file

@ -450,6 +450,27 @@ DWORD WINAPI GetFileVersionInfoSizeW( LPCWSTR filename, LPDWORD handle )
SetLastError(ERROR_RESOURCE_DATA_NOT_FOUND);
return 0;
}
/* We have a 16bit resource.
*
* XP/W2K/W2K3 uses a buffer which is more than the actual needed space:
*
* (info->wLength - sizeof(VS_FIXEDFILEINFO)) * 4
*
* This extra buffer is used for ANSI to Unicode conversions in W-Calls.
* info->wLength should be the same as len. Currently it isn't but that
* doesn't seem to be a problem (len is bigger then info->wLength).
*/
len = (len - sizeof(VS_FIXEDFILEINFO)) * 4;
}
else
{
/* We have a 32bit resource.
*
* XP/W2K/W2K3 uses a buffer which is 2 times the actual needed space + 4 bytes "FE2X"
* This extra buffer is used for Unicode to ANSI conversions in A-Calls
*/
len = (len * 2) + 4;
}
SetLastError(0);
@ -485,6 +506,7 @@ BOOL WINAPI GetFileVersionInfoW( LPCWSTR filename, DWORD handle,
DWORD datasize, LPVOID data )
{
DWORD len;
VS_VERSION_INFO_STRUCT32* vvis = (VS_VERSION_INFO_STRUCT32*)data;
TRACE("(%s,%ld,size=%ld,data=%p)\n",
debugstr_w(filename), handle, datasize, data );
@ -518,11 +540,21 @@ BOOL WINAPI GetFileVersionInfoW( LPCWSTR filename, DWORD handle,
SetLastError(ERROR_RESOURCE_DATA_NOT_FOUND);
return FALSE;
}
/* We have a 16bit resource. */
}
else
{
DWORD convbuf;
/* We have a 32bit resource.
*
* XP/W2K/W2K3 uses a buffer which is 2 times the actual needed space + 4 bytes "FE2X"
* This extra buffer is used for Unicode to ANSI conversions in A-Calls
*/
/* If we end up here we have found either 16bit or 32bit
* version information
*/
convbuf = datasize - vvis->wLength;
memcpy( ((char*)(data))+vvis->wLength, "FE2X", convbuf > 4 ? 4 : convbuf );
}
SetLastError(0);
return TRUE;

View file

@ -261,6 +261,21 @@ static void test_32bit_win(void)
WCHAR WineFileDescriptionW[] = { 'W','i','n','e',' ','v','e','r','s','i','o','n',' ','t','e','s','t', 0 };
BOOL is_unicode_enabled = TRUE;
/* A copy from dlls/version/info.c */
typedef struct
{
WORD wLength;
WORD wValueLength;
WORD wType;
WCHAR szKey[1];
#if 0 /* variable length structure */
/* DWORD aligned */
BYTE Value[];
/* DWORD aligned */
VS_VERSION_INFO_STRUCT32 Children[];
#endif
} VS_VERSION_INFO_STRUCT32;
/* If we call GetFileVersionInfoA on a system that supports Unicode (NT/W2K/XP/W2K3 by default)
* then the versioninfo will contain Unicode strings.
* Wine however always converts a VersionInfo32 to VersionInfo16 when called through GetFileVersionInfoA
@ -296,12 +311,40 @@ static void test_32bit_win(void)
ok( !memcmp(pVersionInfoA, pVersionInfoW, retvalA), "Both structs should be the same, they aren't\n");
}
/* The structs are the same but that will mysteriously change with the next calls on Windows (not on Wine).
* The structure on windows is way bigger then needed, so there must be something to it. As we do not
* seem to need this bigger structure, we can leave that as is.
* The change in the Windows structure is in this not needed part.
/* The structs on Windows are bigger then just the struct for the basic information. The total struct
* contains also an empty part, which is used for converted strings. The converted strings are a result
* of calling VerQueryValueA on a 32bit resource and calling VerQueryValueW on a 16bit resource.
* The first WORD of the structure (wLength) shows the size of the base struct. The total struct size depends
* on the Windows version:
*
* Although the structures contain Unicode strings, VerQueryValueA will always return normal strings,
* 16bits resource (numbers are from a sample app):
*
* Windows Version Retrieved with A/W wLength StructSize
* ====================================================================================
* Win98 A 0x01B4 (436) 436
* NT4 A/W 0x01B4 (436) 2048 ???
* W2K/XP/W2K3 A/W 0x01B4 (436) 1536 which is (436 - sizeof(VS_FIXEDFILEINFO)) * 4
*
* 32bits resource (numbers are from this test executable version_crosstest.exe):
* Windows Version Retrieved with A/W wLength StructSize
* =============================================================
* Win98 A 0x01E0 (480) 848 (structure data doesn't seem correct)
* NT4 A/W 0x0350 (848) 1272 (848 * 1.5)
* W2K/XP/W2K3 A/W 0x0350 (848) 1700 which is (848 * 2) + 4
*
* Wine will follow the implementation (eventually) of W2K/XP/W2K3
*/
/* Now some tests for the above (only if we are unicode enabled) */
if (is_unicode_enabled)
{
VS_VERSION_INFO_STRUCT32 *vvis = (VS_VERSION_INFO_STRUCT32 *)pVersionInfoW;
ok ( retvalW == ((vvis->wLength * 2) + 4) || retvalW == (vvis->wLength * 1.5),
"Structure is not of the correct size\n");
}
/* Although the 32bit resource structures contain Unicode strings, VerQueryValueA will always return normal strings,
* VerQueryValueW will always return Unicode ones. (That means everything returned for StringFileInfo requests).
*/
@ -367,7 +410,7 @@ START_TEST(info)
test_info_size();
test_info();
/* Test GetFileVersionInfoSize[AW] and GetFileVersionInfo[AW] on a 32 bit windows executable */
/* Test several AW-calls on a 32 bit windows executable */
trace("Testing 32 bit windows application\n");
test_32bit_win();
}