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