RESEND: Try to avoid loading 16-bit DLLs into memory for accessing version info
Dmitry Timoshkov
dmitry at baikal.ru
Fri Jul 30 05:41:40 CDT 2004
Hello,
this version of the patch should have fixed the problems reported.
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-30 19:23:54.000000000 +0900
@@ -285,11 +285,9 @@ 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.
- * FIXME: handle is not used.
+ * in the case the file is a PE module, but VERSION_INFO not found.
*/
-static DWORD VERSION_GetFileVersionInfo_PE( LPCWSTR filename, LPDWORD handle,
- DWORD datasize, LPVOID data )
+static DWORD VERSION_GetFileVersionInfo_PE( LPCWSTR filename, DWORD datasize, LPVOID data )
{
VS_FIXEDFILEINFO *vffi;
DWORD len;
@@ -298,7 +296,7 @@ static DWORD VERSION_GetFileVersionInfo_
HRSRC hRsrc;
HGLOBAL hMem;
- TRACE("(%s,%p)\n", debugstr_w(filename), handle );
+ TRACE("%s\n", debugstr_w(filename));
hModule = GetModuleHandleW(filename);
if(!hModule)
@@ -351,7 +349,6 @@ static DWORD VERSION_GetFileVersionInfo_
else
len = 0xFFFFFFFF;
}
- SetLastError(0);
END:
FreeResource(hMem);
FreeLibrary(hModule);
@@ -363,21 +360,61 @@ END:
* VERSION_GetFileVersionInfo_16 [internal]
*
* NOTE: returns size of the 16-bit VERSION resource or 0xFFFFFFFF
- * in the case if file exists, but VERSION_INFO not found.
- * FIXME: handle is not used.
+ * in the case the file exists, but VERSION_INFO not found.
*/
-static DWORD VERSION_GetFileVersionInfo_16( LPCSTR filename, LPDWORD handle,
- DWORD datasize, LPVOID data )
+static DWORD VERSION_GetFileVersionInfo_16( LPCSTR filename, DWORD datasize, LPVOID data )
{
VS_FIXEDFILEINFO *vffi;
- DWORD len;
+ DWORD len, offset;
BYTE *buf;
HMODULE16 hModule;
HRSRC16 hRsrc;
HGLOBAL16 hMem;
- TRACE("(%s,%p)\n", debugstr_a(filename), handle );
+ TRACE("%s\n", debugstr_a(filename));
+
+ /* 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 ( 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,95 +477,39 @@ END:
*/
DWORD WINAPI GetFileVersionInfoSizeW( LPCWSTR filename, LPDWORD handle )
{
- DWORD ret, offset, len = (filename && strlenW(filename)) ? strlenW(filename) + 1: MAX_PATH;
- LPSTR filenameA = NULL;
- LPWSTR filenameW;
- VS_FIXEDFILEINFO *vffi;
- BYTE buf[144];
+ DWORD len;
TRACE("(%s,%p)\n", debugstr_w(filename), handle );
- filenameW = HeapAlloc( GetProcessHeap(), 0, sizeof(WCHAR) * len );
- if (filename && strlenW(filename))
- strcpyW(filenameW, filename);
- else {
- DWORD nSize = GetModuleFileNameW(NULL, filenameW, len);
- if (!nSize || nSize >= len)
- {
- len = 0;
- goto End;
- }
- }
+ if (handle) *handle = 0;
- len = VERSION_GetFileVersionInfo_PE(filenameW, handle, 0, NULL);
- /* 0xFFFFFFFF means: file exists, but VERSION_INFO not found */
+ len = VERSION_GetFileVersionInfo_PE(filename, 0, NULL);
+ /* 0xFFFFFFFF means: file is a PE module, but VERSION_INFO not found */
if(len == 0xFFFFFFFF)
{
- if ( handle ) *handle = 0L;
SetLastError(ERROR_RESOURCE_DATA_NOT_FOUND);
- len = 0;
- goto End;
- }
- if(len) {
- if ( handle ) *handle = 0L;
- goto End;
+ return 0;
}
- /* FIXME: handle not set correctly after this point
- */
-
- len = WideCharToMultiByte( CP_ACP, 0, filename, -1, NULL, 0, NULL, NULL );
- filenameA = HeapAlloc( GetProcessHeap(), 0, len );
- WideCharToMultiByte( CP_ACP, 0, filename, -1, filenameA, len, NULL, NULL );
-
- len = VERSION_GetFileVersionInfo_16(filenameA, handle, 0, NULL);
- /* 0xFFFFFFFF means: file exists, but VERSION_INFO not found */
- if(len == 0xFFFFFFFF)
+ if (!len)
{
- SetLastError(ERROR_RESOURCE_DATA_NOT_FOUND);
- len = 0;
- goto End;
- }
- if(len) goto End;
+ LPSTR filenameA;
- /* 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 );
+ len = WideCharToMultiByte( CP_ACP, 0, filename, -1, NULL, 0, NULL, NULL );
+ filenameA = HeapAlloc( GetProcessHeap(), 0, len );
+ WideCharToMultiByte( CP_ACP, 0, filename, -1, filenameA, len, NULL, NULL );
- 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;
+ len = VERSION_GetFileVersionInfo_16(filenameA, 0, NULL);
+ HeapFree( GetProcessHeap(), 0, filenameA );
+ /* 0xFFFFFFFF means: file exists, but VERSION_INFO not found */
+ if (!len || len == 0xFFFFFFFF)
+ {
+ SetLastError(ERROR_RESOURCE_DATA_NOT_FOUND);
+ return 0;
+ }
}
- 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)
- HeapFree( GetProcessHeap(), 0, filenameA);
+ SetLastError(0);
return len;
}
@@ -558,23 +539,26 @@ 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 */
+ len = VERSION_GetFileVersionInfo_PE(filenameW.Buffer, datasize, data);
+ /* 0xFFFFFFFF means: file is a PE module, but VERSION_INFO not found */
RtlFreeUnicodeString(&filenameW);
- if(len == 0xFFFFFFFF) return FALSE;
- if(len)
- goto DO_CONVERT;
- 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 ) )
+ if (len == 0xFFFFFFFF)
+ {
+ SetLastError(ERROR_RESOURCE_DATA_NOT_FOUND);
return FALSE;
-DO_CONVERT:
+ }
+
+ if (!len)
+ {
+ len = VERSION_GetFileVersionInfo_16(filename, datasize, data);
+ /* 0xFFFFFFFF means: file exists, but VERSION_INFO not found */
+ if (!len || len == 0xFFFFFFFF)
+ {
+ SetLastError(ERROR_RESOURCE_DATA_NOT_FOUND);
+ return FALSE;
+ }
+ }
+
if ( datasize >= sizeof(VS_VERSION_INFO_STRUCT16)
&& datasize >= ((VS_VERSION_INFO_STRUCT16 *)data)->wLength
&& !VersionInfoIs16( data ) )
@@ -584,6 +568,7 @@ DO_CONVERT:
(VS_VERSION_INFO_STRUCT16 *)data );
}
+ SetLastError(0);
return TRUE;
}
@@ -593,35 +578,48 @@ 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 retv = TRUE;
-
- WideCharToMultiByte( CP_ACP, 0, filename, -1, fn, len, NULL, NULL );
+ DWORD len;
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, datasize, data);
+ /* 0xFFFFFFFF means: file is a PE module, but VERSION_INFO not found */
+ if (len == 0xFFFFFFFF)
+ {
+ SetLastError(ERROR_RESOURCE_DATA_NOT_FOUND);
+ return FALSE;
+ }
- if ( !GetFileResource16( fn, MAKEINTRESOURCEA(VS_FILE_INFO),
- MAKEINTRESOURCEA(VS_VERSION_INFO),
- handle, datasize, data ) )
- retv = FALSE;
+ if (!len)
+ {
+ LPSTR filenameA;
+
+ len = WideCharToMultiByte( CP_ACP, 0, filename, -1, NULL, 0, NULL, NULL );
+ filenameA = HeapAlloc( GetProcessHeap(), 0, len );
+ WideCharToMultiByte( CP_ACP, 0, filename, -1, filenameA, len, NULL, NULL );
+
+ len = VERSION_GetFileVersionInfo_16(filenameA, datasize, data);
+ HeapFree( GetProcessHeap(), 0, filenameA );
+ /* 0xFFFFFFFF means: file exists, but VERSION_INFO not found */
+ if (!len || len == 0xFFFFFFFF)
+ {
+ SetLastError(ERROR_RESOURCE_DATA_NOT_FOUND);
+ return FALSE;
+ }
+ }
- else if ( datasize >= sizeof(VS_VERSION_INFO_STRUCT16)
- && datasize >= ((VS_VERSION_INFO_STRUCT16 *)data)->wLength
- && VersionInfoIs16( data ) )
+ if ( datasize >= sizeof(VS_VERSION_INFO_STRUCT16) &&
+ datasize >= ((VS_VERSION_INFO_STRUCT16 *)data)->wLength &&
+ VersionInfoIs16( data ) )
{
- ERR("Cannot access NE resource in %s\n", debugstr_a(fn) );
- retv = FALSE;
+ ERR("Cannot access NE resource in %s\n", debugstr_w(filename) );
+ SetLastError(ERROR_RESOURCE_DATA_NOT_FOUND);
+ return FALSE;
}
-END:
- HeapFree( GetProcessHeap(), 0, fn );
- return retv;
+
+ SetLastError(0);
+ return TRUE;
}
More information about the wine-patches
mailing list