Try to avoid loading 16-bit DLLs into memory for accessing version info
Dmitry Timoshkov
dmitry at baikal.ru
Thu Jul 29 07:54:23 CDT 2004
Hello,
Changelog:
Dmitry Timoshkov <dmitry at codeweavers.com>
Try to avoid loading 16-bit DLLs into memory for accessing
version info, this might lead to undesired side effects like
loading a bunch of other 16-bit DLLs.
--- cvs/hq/wine/dlls/version/info.c 2004-06-23 16:08:40.000000000 +0900
+++ wine/dlls/version/info.c 2004-07-29 21:41:36.000000000 +0900
@@ -285,7 +285,7 @@ void ConvertVersionInfo32To16( VS_VERSIO
* VERSION_GetFileVersionInfo_PE [internal]
*
* NOTE: returns size of the PE VERSION resource or 0xFFFFFFFF
- * in the case if file exists, but VERSION_INFO not found.
+ * in the case if file is a PE module, but VERSION_INFO not found.
* FIXME: handle is not used.
*/
static DWORD VERSION_GetFileVersionInfo_PE( LPCWSTR filename, LPDWORD handle,
@@ -367,10 +367,10 @@ END:
* FIXME: handle is not used.
*/
static DWORD VERSION_GetFileVersionInfo_16( LPCSTR filename, LPDWORD handle,
- DWORD datasize, LPVOID data )
+ DWORD datasize, LPVOID data )
{
VS_FIXEDFILEINFO *vffi;
- DWORD len;
+ DWORD len, offset;
BYTE *buf;
HMODULE16 hModule;
HRSRC16 hRsrc;
@@ -378,6 +378,50 @@ static DWORD VERSION_GetFileVersionInfo_
TRACE("(%s,%p)\n", debugstr_a(filename), handle );
+ /* first try without loading a 16-bit module */
+ len = GetFileResourceSize16( filename,
+ MAKEINTRESOURCEA(VS_FILE_INFO),
+ MAKEINTRESOURCEA(VS_VERSION_INFO),
+ &offset );
+ if (len)
+ {
+ if (!data) return len;
+
+ len = GetFileResource16( filename,
+ MAKEINTRESOURCEA(VS_FILE_INFO),
+ MAKEINTRESOURCEA(VS_VERSION_INFO),
+ offset, datasize, data );
+ if (len)
+ {
+ if ( handle ) *handle = offset;
+
+ if ( VersionInfoIs16( data ) )
+ vffi = (VS_FIXEDFILEINFO *)VersionInfo16_Value( (VS_VERSION_INFO_STRUCT16 *)data );
+ else
+ vffi = (VS_FIXEDFILEINFO *)VersionInfo32_Value( (VS_VERSION_INFO_STRUCT32 *)data );
+
+ if ( vffi->dwSignature == VS_FFI_SIGNATURE )
+ {
+ if ( ((VS_VERSION_INFO_STRUCT16 *)data)->wLength < len )
+ len = ((VS_VERSION_INFO_STRUCT16 *)data)->wLength;
+
+ if ( TRACE_ON(ver) )
+ print_vffi_debug( vffi );
+
+ if ( datasize >= sizeof(VS_VERSION_INFO_STRUCT16)
+ && datasize >= ((VS_VERSION_INFO_STRUCT16 *)data)->wLength
+ && !VersionInfoIs16( data ) )
+ {
+ /* convert resource from PE format to NE format */
+ ConvertVersionInfo32To16( (VS_VERSION_INFO_STRUCT32 *)data,
+ (VS_VERSION_INFO_STRUCT16 *)data );
+ }
+ return len;
+ }
+ }
+ }
+
+ /* this might be a builtin 16-bit module */
hModule = LoadLibrary16(filename);
if(hModule < 32)
{
@@ -440,11 +484,9 @@ END:
*/
DWORD WINAPI GetFileVersionInfoSizeW( LPCWSTR filename, LPDWORD handle )
{
- DWORD ret, offset, len = (filename && strlenW(filename)) ? strlenW(filename) + 1: MAX_PATH;
+ DWORD len = (filename && strlenW(filename)) ? strlenW(filename) + 1: MAX_PATH;
LPSTR filenameA = NULL;
LPWSTR filenameW;
- VS_FIXEDFILEINFO *vffi;
- BYTE buf[144];
TRACE("(%s,%p)\n", debugstr_w(filename), handle );
@@ -461,7 +503,7 @@ DWORD WINAPI GetFileVersionInfoSizeW( LP
}
len = VERSION_GetFileVersionInfo_PE(filenameW, handle, 0, NULL);
- /* 0xFFFFFFFF means: file exists, but VERSION_INFO not found */
+ /* 0xFFFFFFFF means: file is a PE module, but VERSION_INFO not found */
if(len == 0xFFFFFFFF)
{
if ( handle ) *handle = 0L;
@@ -487,44 +529,8 @@ DWORD WINAPI GetFileVersionInfoSizeW( LP
{
SetLastError(ERROR_RESOURCE_DATA_NOT_FOUND);
len = 0;
- goto End;
- }
- if(len) goto End;
-
- /* FIXME: last error not handled after this point
- */
- len = GetFileResourceSize16( filenameA,
- MAKEINTRESOURCEA(VS_FILE_INFO),
- MAKEINTRESOURCEA(VS_VERSION_INFO),
- &offset );
- if (!len) goto End;
-
- ret = GetFileResource16( filenameA,
- MAKEINTRESOURCEA(VS_FILE_INFO),
- MAKEINTRESOURCEA(VS_VERSION_INFO),
- offset, sizeof( buf ), buf );
- if (!ret) goto End;
-
- if ( handle ) *handle = offset;
-
- if ( VersionInfoIs16( buf ) )
- vffi = (VS_FIXEDFILEINFO *)VersionInfo16_Value( (VS_VERSION_INFO_STRUCT16 *)buf );
- else
- vffi = (VS_FIXEDFILEINFO *)VersionInfo32_Value( (VS_VERSION_INFO_STRUCT32 *)buf );
-
- if ( vffi->dwSignature != VS_FFI_SIGNATURE )
- {
- WARN("vffi->dwSignature is 0x%08lx, but not 0x%08lx!\n",
- vffi->dwSignature, VS_FFI_SIGNATURE );
- len = 0;
- goto End;
}
- if ( ((VS_VERSION_INFO_STRUCT16 *)buf)->wLength < len )
- len = ((VS_VERSION_INFO_STRUCT16 *)buf)->wLength;
-
- if ( TRACE_ON(ver) )
- print_vffi_debug( vffi );
End:
HeapFree( GetProcessHeap(), 0, filenameW);
if (filenameA)
@@ -559,21 +565,25 @@ BOOL WINAPI GetFileVersionInfoA( LPCSTR
if(filename) RtlCreateUnicodeStringFromAsciiz(&filenameW, filename);
else filenameW.Buffer = NULL;
len = VERSION_GetFileVersionInfo_PE(filenameW.Buffer, &handle, datasize, data);
- /* 0xFFFFFFFF means: file exists, but VERSION_INFO not found */
+ /* 0xFFFFFFFF means: file is a PE module, but VERSION_INFO not found */
RtlFreeUnicodeString(&filenameW);
if(len == 0xFFFFFFFF) return FALSE;
if(len)
goto DO_CONVERT;
+
+ /* first try without loading a 16-bit module */
+ if ( GetFileResource16( filename, MAKEINTRESOURCEA(VS_FILE_INFO),
+ MAKEINTRESOURCEA(VS_VERSION_INFO),
+ handle, datasize, data ) )
+ return TRUE;
+
+ /* this might be a builtin 16-bit module */
len = VERSION_GetFileVersionInfo_16(filename, &handle, datasize, data);
/* 0xFFFFFFFF means: file exists, but VERSION_INFO not found */
if(len == 0xFFFFFFFF) return FALSE;
if(len)
goto DO_CONVERT;
- if ( !GetFileResource16( filename, MAKEINTRESOURCEA(VS_FILE_INFO),
- MAKEINTRESOURCEA(VS_VERSION_INFO),
- handle, datasize, data ) )
- return FALSE;
DO_CONVERT:
if ( datasize >= sizeof(VS_VERSION_INFO_STRUCT16)
&& datasize >= ((VS_VERSION_INFO_STRUCT16 *)data)->wLength
@@ -593,20 +603,22 @@ DO_CONVERT:
BOOL WINAPI GetFileVersionInfoW( LPCWSTR filename, DWORD handle,
DWORD datasize, LPVOID data )
{
- DWORD len = WideCharToMultiByte( CP_ACP, 0, filename, -1, NULL, 0, NULL, NULL );
- LPSTR fn = HeapAlloc( GetProcessHeap(), 0, len );
+ DWORD len;
+ LPSTR fn;
DWORD retv = TRUE;
- WideCharToMultiByte( CP_ACP, 0, filename, -1, fn, len, NULL, NULL );
-
TRACE("(%s,%ld,size=%ld,data=%p)\n",
debugstr_w(filename), handle, datasize, data );
- if(VERSION_GetFileVersionInfo_PE(filename, &handle, datasize, data))
- goto END;
- if(VERSION_GetFileVersionInfo_16(fn, &handle, datasize, data))
- goto END;
+ len = VERSION_GetFileVersionInfo_PE(filename, &handle, datasize, data);
+ /* 0xFFFFFFFF means: file is a PE module, but VERSION_INFO not found */
+ if (len == 0xFFFFFFFF) return FALSE;
+ len = WideCharToMultiByte( CP_ACP, 0, filename, -1, NULL, 0, NULL, NULL );
+ fn = HeapAlloc( GetProcessHeap(), 0, len );
+ WideCharToMultiByte( CP_ACP, 0, filename, -1, fn, len, NULL, NULL );
+
+ /* first try without loading a 16-bit module */
if ( !GetFileResource16( fn, MAKEINTRESOURCEA(VS_FILE_INFO),
MAKEINTRESOURCEA(VS_VERSION_INFO),
handle, datasize, data ) )
@@ -619,7 +631,14 @@ BOOL WINAPI GetFileVersionInfoW( LPCWSTR
ERR("Cannot access NE resource in %s\n", debugstr_a(fn) );
retv = FALSE;
}
-END:
+
+ /* this might be a builtin 16-bit module */
+ if (!retv)
+ {
+ len = VERSION_GetFileVersionInfo_16(fn, &handle, datasize, data);
+ retv = len && len != 0xFFFFFFFF;
+ }
+
HeapFree( GetProcessHeap(), 0, fn );
return retv;
}
More information about the wine-patches
mailing list