Add version information (16 and 32 bit) to core built-in dlls:
krnl386.exe/kernel32.dll, user.exe/user32.dll, gdi.exe/gdi32.dll.
Provide a way for reading version information using standard API:
GetFileVersionInfoSize -> GetFileVersionInfo -> VerQueryValue.
diff --git a/dlls/gdi/.cvsignore b/dlls/gdi/.cvsignore
index e52ce27..e290b63 100644
--- a/dlls/gdi/.cvsignore
+++ b/dlls/gdi/.cvsignore
@@ -3,3 +3,5 @@
Makefile
printdrv.glue.c
thunk.glue.c
+version.res
+version16.res
diff --git a/dlls/gdi/Makefile.in b/dlls/gdi/Makefile.in
index c6172c8..7648a9c 100644
--- a/dlls/gdi/Makefile.in
+++ b/dlls/gdi/Makefile.in
@@ -14,6 +14,10 @@
thunk.c \
wing.c
+RC_SRCS= \
+ version.rc \
+ version16.rc
+
GLUE = printdrv.c thunk.c
EXTRA_OBJS = \
@@ -35,5 +39,12 @@
$(EXTRA_OBJS): dummy
@cd `dirname $@` && $(MAKE) `basename $@`
+# Special rules for 16-bit resource files
+
+version16.res: version16.rc
+ $(LDPATH) $(WRC) $(DIVINCL) -o $@ -w16 -m -r $(SRCDIR)/version16.rc
+
+gdi.spec.c: version16.res
+
### Dependencies:
diff --git a/dlls/gdi/gdi.spec b/dlls/gdi/gdi.spec
index 0084277..075e820 100644
--- a/dlls/gdi/gdi.spec
+++ b/dlls/gdi/gdi.spec
@@ -3,6 +3,7 @@
heap 65488 # 65536 - 16 (instance data) - 32 (stock objects)
file gdi.exe
owner gdi32
+rsrc version16.res
1 pascal SetBkColor(word long) SetBkColor16
2 pascal16 SetBkMode(word word) SetBkMode16
diff --git a/dlls/gdi/gdi32.spec b/dlls/gdi/gdi32.spec
index 63255b4..6c3a943 100644
--- a/dlls/gdi/gdi32.spec
+++ b/dlls/gdi/gdi32.spec
@@ -1,6 +1,7 @@
name gdi32
type win32
init MAIN_GdiInit
+rsrc version.res
import advapi32.dll
import kernel32.dll
diff --git a/dlls/gdi/version.rc b/dlls/gdi/version.rc
new file mode 100644
index 0000000..59a3f67
--- /dev/null
+++ b/dlls/gdi/version.rc
@@ -0,0 +1,5 @@
+#define WINE_FILEVERSION_STR "1.0"
+#define WINE_FILEDESCRIPTION_STR "Wine core dll"
+#define WINE_FILENAME_STR "gdi32.dll"
+
+#include "wine/wine_common_ver.rc"
diff --git a/dlls/gdi/version16.rc b/dlls/gdi/version16.rc
new file mode 100644
index 0000000..1300216
--- /dev/null
+++ b/dlls/gdi/version16.rc
@@ -0,0 +1,5 @@
+#define WINE_FILEVERSION_STR "1.0"
+#define WINE_FILEDESCRIPTION_STR "Wine core dll"
+#define WINE_FILENAME_STR "gdi.exe"
+
+#include "wine/wine_common_ver.rc"
diff --git a/dlls/kernel/.cvsignore b/dlls/kernel/.cvsignore
index fb77b90..d53018b 100644
--- a/dlls/kernel/.cvsignore
+++ b/dlls/kernel/.cvsignore
@@ -2,3 +2,4 @@
Makefile
kernel.res
utthunk.glue.c
+version16.res
diff --git a/dlls/kernel/Makefile.in b/dlls/kernel/Makefile.in
index 04d15a8..2e66ffc 100644
--- a/dlls/kernel/Makefile.in
+++ b/dlls/kernel/Makefile.in
@@ -38,4 +38,11 @@
kernel.res: $(MC_SRCS:.mc=.mc.rc)
+# Special rules for 16-bit resource files
+
+version16.res: version16.rc
+ $(LDPATH) $(WRC) $(DIVINCL) -o $@ -w16 -m -r $(SRCDIR)/version16.rc
+
+kernel.spec.c: version16.res
+
### Dependencies:
diff --git a/dlls/kernel/kernel.rc b/dlls/kernel/kernel.rc
index e2ca5b9..0b0d955 100644
--- a/dlls/kernel/kernel.rc
+++ b/dlls/kernel/kernel.rc
@@ -1,3 +1,5 @@
#include "locale_rc.rc"
#include "messages/winerr_enu.mc.rc"
+
+#include "version.rc"
diff --git a/dlls/kernel/kernel.spec b/dlls/kernel/kernel.spec
index b4e40d5..bb184a4 100644
--- a/dlls/kernel/kernel.spec
+++ b/dlls/kernel/kernel.spec
@@ -2,6 +2,7 @@
type win16
file krnl386.exe
owner kernel32
+rsrc version16.res
# 1-207 are the basic functions, those are (with minor variations)
# present in win31, win95 and nt351
diff --git a/dlls/kernel/kernel32.spec b/dlls/kernel/kernel32.spec
index b5a4013..81adeab 100644
--- a/dlls/kernel/kernel32.spec
+++ b/dlls/kernel/kernel32.spec
@@ -973,6 +973,7 @@
@ stdcall LoadModule16(str long) LoadModule16
@ stdcall LoadResource16(long long) LoadResource16
@ stdcall LockResource16(long) LockResource16
+@ stdcall SizeofResource16(long long) SizeofResource16
@ stdcall WinExec16(str long) WinExec16
@ stdcall GlobalFlags16(long) GlobalFlags16
@ stdcall GlobalReAlloc16(long long long) GlobalReAlloc16
diff --git a/dlls/kernel/version.rc b/dlls/kernel/version.rc
new file mode 100644
index 0000000..092b8d3
--- /dev/null
+++ b/dlls/kernel/version.rc
@@ -0,0 +1,5 @@
+#define WINE_FILEVERSION_STR "1.0"
+#define WINE_FILEDESCRIPTION_STR "Wine core dll"
+#define WINE_FILENAME_STR "kernel32.dll"
+
+#include "wine/wine_common_ver.rc"
diff --git a/dlls/kernel/version16.rc b/dlls/kernel/version16.rc
new file mode 100644
index 0000000..7ed894c
--- /dev/null
+++ b/dlls/kernel/version16.rc
@@ -0,0 +1,5 @@
+#define WINE_FILEVERSION_STR "1.0"
+#define WINE_FILEDESCRIPTION_STR "Wine core dll"
+#define WINE_FILENAME_STR "krnl386.exe"
+
+#include "wine/wine_common_ver.rc"
diff --git a/dlls/user/Makefile.in b/dlls/user/Makefile.in
index 561e354..0fef135 100644
--- a/dlls/user/Makefile.in
+++ b/dlls/user/Makefile.in
@@ -26,7 +26,8 @@
RC_SRCS = \
resources/display.rc \
resources/mouse.rc \
- resources/user32.rc
+ resources/user32.rc \
+ resources/version16.rc
GLUE = thunk.c
@@ -54,8 +55,13 @@
resources/mouse.res: resources/mouse.rc
$(LDPATH) $(WRC) $(DIVINCL) -o $@ -w16 -m -r $(SRCDIR)/resources/mouse.rc
+resources/version16.res: resources/version16.rc
+ $(LDPATH) $(WRC) $(DIVINCL) -o $@ -w16 -m -r $(SRCDIR)/resources/version16.rc
+
display.spec.c: resources/display.res
mouse.spec.c: resources/mouse.res
+user.spec.c: resources/version16.res
+
### Dependencies:
diff --git a/dlls/user/resources/.cvsignore b/dlls/user/resources/.cvsignore
index aa07d40..703d7e8 100644
--- a/dlls/user/resources/.cvsignore
+++ b/dlls/user/resources/.cvsignore
@@ -1,3 +1,4 @@
display.res
mouse.res
user32.res
+version16.res
diff --git a/dlls/user/resources/user32.rc b/dlls/user/resources/user32.rc
index 2acce58..90bbcd0 100644
--- a/dlls/user/resources/user32.rc
+++ b/dlls/user/resources/user32.rc
@@ -49,3 +49,5 @@
#include "resources/user32_Wa.rc"
#include "resources/user32_Ja.rc"
#include "resources/user32_Zh.rc"
+
+#include "resources/version.rc"
diff --git a/dlls/user/resources/version.rc b/dlls/user/resources/version.rc
new file mode 100644
index 0000000..f8d682c
--- /dev/null
+++ b/dlls/user/resources/version.rc
@@ -0,0 +1,5 @@
+#define WINE_FILEVERSION_STR "1.0"
+#define WINE_FILEDESCRIPTION_STR "Wine core dll"
+#define WINE_FILENAME_STR "user32.dll"
+
+#include "wine/wine_common_ver.rc"
diff --git a/dlls/user/resources/version16.rc b/dlls/user/resources/version16.rc
new file mode 100644
index 0000000..dab8c9d
--- /dev/null
+++ b/dlls/user/resources/version16.rc
@@ -0,0 +1,5 @@
+#define WINE_FILEVERSION_STR "1.0"
+#define WINE_FILEDESCRIPTION_STR "Wine core dll"
+#define WINE_FILENAME_STR "user.exe"
+
+#include "wine/wine_common_ver.rc"
diff --git a/dlls/user/user.spec b/dlls/user/user.spec
index 8ad4d72..2a68554 100644
--- a/dlls/user/user.spec
+++ b/dlls/user/user.spec
@@ -3,6 +3,7 @@
heap 65520
file user.exe
owner user32
+rsrc resources/version16.res
1 pascal16 MessageBox(word str str word) MessageBox16
2 stub OldExitWindows
diff --git a/dlls/version/info.c b/dlls/version/info.c
index e77ca71..eaf817a 100644
--- a/dlls/version/info.c
+++ b/dlls/version/info.c
@@ -260,6 +260,160 @@
info16->wLength, info16, child16 );
}
+/***********************************************************************
+ * VERSION_GetFileVersionInfo_PE [internal]
+ *
+ * NOTE: returns size of the PE VERSION resource.
+ * FIXME: handle is not used.
+ */
+static DWORD WINAPI VERSION_GetFileVersionInfo_PE( LPCSTR filename, LPDWORD handle,
+ DWORD datasize, LPVOID data )
+{
+ VS_FIXEDFILEINFO *vffi;
+ DWORD len;
+ BYTE *buf;
+ HMODULE hModule;
+ HRSRC hRsrc;
+ HGLOBAL hMem;
+ BOOL do_free_library = FALSE;
+
+ TRACE("(%s,%p)\n", debugstr_a(filename), handle );
+
+ hModule = GetModuleHandleA(filename);
+ if(!hModule)
+ {
+ hModule = LoadLibraryExA(filename, 0, LOAD_LIBRARY_AS_DATAFILE);
+ do_free_library = TRUE;
+ }
+ if(!hModule)
+ {
+ WARN("Could not load %s\n", debugstr_a(filename));
+ return 0;
+ }
+ hRsrc = FindResourceW(hModule,
+ MAKEINTRESOURCEW(VS_VERSION_INFO),
+ MAKEINTRESOURCEW(VS_FILE_INFO));
+ if(!hRsrc)
+ {
+ WARN("Could not find VS_VERSION_INFO in %s\n", debugstr_a(filename));
+ if(do_free_library) FreeLibrary(hModule);
+ return 0;
+ }
+ len = SizeofResource(hModule, hRsrc);
+ hMem = LoadResource(hModule, hRsrc);
+ if(!hMem)
+ {
+ WARN("Could not load VS_VERSION_INFO from %s\n", debugstr_a(filename));
+ if(do_free_library) FreeLibrary(hModule);
+ return 0;
+ }
+ buf = LockResource(hMem);
+
+ 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 ( TRACE_ON(ver) )
+ print_vffi_debug( vffi );
+
+ if(data)
+ {
+ if(datasize >= len)
+ memcpy(data, buf, len);
+ else
+ len = 0;
+ }
+END:
+ FreeResource(hMem);
+ if(do_free_library) FreeLibrary(hModule);
+
+ return len;
+}
+
+/***********************************************************************
+ * VERSION_GetFileVersionInfo_16 [internal]
+ *
+ * NOTE: returns size of the 16-bit VERSION resource.
+ * FIXME: handle is not used.
+ */
+static DWORD WINAPI VERSION_GetFileVersionInfo_16( LPCSTR filename, LPDWORD handle,
+ DWORD datasize, LPVOID data )
+{
+ VS_FIXEDFILEINFO *vffi;
+ DWORD len;
+ BYTE *buf;
+ HMODULE16 hModule;
+ HRSRC16 hRsrc;
+ HGLOBAL16 hMem;
+ BOOL do_free_library = FALSE;
+
+ TRACE("(%s,%p)\n", debugstr_a(filename), handle );
+
+ hModule = GetModuleHandle16(filename);
+ if(hModule < 32)
+ {
+ hModule = LoadLibrary16(filename);
+ do_free_library = TRUE;
+ }
+ if(hModule < 32)
+ {
+ WARN("Could not load %s\n", debugstr_a(filename));
+ return 0;
+ }
+ hRsrc = FindResource16(hModule,
+ MAKEINTRESOURCEA(VS_VERSION_INFO),
+ MAKEINTRESOURCEA(VS_FILE_INFO));
+ if(!hRsrc)
+ {
+ WARN("Could not find VS_VERSION_INFO in %s\n", debugstr_a(filename));
+ if(do_free_library) FreeLibrary16(hModule);
+ return 0;
+ }
+ len = SizeofResource16(hModule, hRsrc);
+ hMem = LoadResource16(hModule, hRsrc);
+ if(!hMem)
+ {
+ WARN("Could not load VS_VERSION_INFO from %s\n", debugstr_a(filename));
+ if(do_free_library) FreeLibrary16(hModule);
+ return 0;
+ }
+ buf = LockResource16(hMem);
+
+ if(!VersionInfoIs16(buf))
+ goto END;
+
+ vffi = (VS_FIXEDFILEINFO *)VersionInfo16_Value( (VS_VERSION_INFO_STRUCT16 *)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 ( TRACE_ON(ver) )
+ print_vffi_debug( vffi );
+
+ if(data)
+ {
+ if(datasize >= len)
+ memcpy(data, buf, len);
+ else
+ len = 0;
+ }
+END:
+ FreeResource16(hMem);
+ if(do_free_library) FreeLibrary16(hModule);
+
+ return len;
+}
/***********************************************************************
* GetFileVersionInfoSizeA [VERSION.2]
@@ -272,6 +426,11 @@
TRACE("(%s,%p)\n", debugstr_a(filename), handle );
+ len = VERSION_GetFileVersionInfo_PE(filename, handle, 0, NULL);
+ if(len) return len;
+ len = VERSION_GetFileVersionInfo_16(filename, handle, 0, NULL);
+ if(len) return len;
+
len = GetFileResourceSize16( filename,
MAKEINTRESOURCEA(VS_FILE_INFO),
MAKEINTRESOURCEA(VS_VERSION_INFO),
@@ -329,11 +488,16 @@
TRACE("(%s,%ld,size=%ld,data=%p)\n",
debugstr_a(filename), handle, datasize, data );
+ if(VERSION_GetFileVersionInfo_PE(filename, &handle, datasize, data))
+ goto DO_CONVERT;
+ if(VERSION_GetFileVersionInfo_16(filename, &handle, datasize, data))
+ 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
&& !VersionInfoIs16( data ) )
@@ -361,6 +525,11 @@
TRACE("(%s,%ld,size=%ld,data=%p)\n",
debugstr_w(filename), handle, datasize, data );
+ if(VERSION_GetFileVersionInfo_PE(fn, &handle, datasize, data))
+ goto END;
+ if(VERSION_GetFileVersionInfo_16(fn, &handle, datasize, data))
+ goto END;
+
if ( !GetFileResource16( fn, MAKEINTRESOURCEA(VS_FILE_INFO),
MAKEINTRESOURCEA(VS_VERSION_INFO),
handle, datasize, data ) )
@@ -373,7 +542,7 @@
ERR("Cannot access NE resource in %s\n", debugstr_a(fn) );
retv = FALSE;
}
-
+END:
HeapFree( GetProcessHeap(), 0, fn );
return retv;
}
diff --git a/include/wine/wine_common_ver.rc b/include/wine/wine_common_ver.rc
new file mode 100644
index 0000000..c7abb74
--- /dev/null
+++ b/include/wine/wine_common_ver.rc
@@ -0,0 +1,47 @@
+#include "winver.h"
+
+#ifndef WINE_FILEVERSION
+#define WINE_FILEVERSION 1,0,0,0
+#endif
+
+#ifndef WINE_FILEVERSION_STR
+#define WINE_FILEVERSION_STR "1.0"
+#endif
+
+#ifndef WINE_FILEDESCRIPTION_STR
+#define WINE_FILEDESCRIPTION_STR "Wine core dll"
+#endif
+
+#ifndef WINE_FILENAME_STR
+#define WINE_FILENAME_STR ""
+#endif
+
+VS_VERSION_INFO VERSIONINFO
+FILEVERSION WINE_FILEVERSION
+PRODUCTVERSION 1,0,0,0
+FILEFLAGSMASK 0
+FILEFLAGS 0
+FILEOS VOS_UNKNOWN
+FILETYPE VFT_DLL
+FILESUBTYPE VFT2_UNKNOWN
+{
+ BLOCK "StringFileInfo"
+ {
+ BLOCK "040904E4" /* LANG_ENGLISH/SUBLANG_DEFAULT, CP 1252 */
+ {
+ VALUE "CompanyName", "Wine Team"
+ VALUE "FileDescription", WINE_FILEDESCRIPTION_STR
+ VALUE "FileVersion", WINE_FILEVERSION_STR
+ VALUE "InternalName", WINE_FILENAME_STR
+ VALUE "LegalCopyright", "Copyright (c) 1993-2001 the Wine project authors " \
+ "(see the file AUTHORS for a complete list)"
+ VALUE "OriginalFilename", WINE_FILENAME_STR
+ VALUE "ProductName", "Wine"
+ VALUE "ProductVersion", "1.0"
+ }
+ }
+ BLOCK "VarFileInfo"
+ {
+ VALUE "Translation", 0x0409, 0x04E4 /* LANG_ENGLISH/SUBLANG_DEFAULT, CP 1252 */
+ }
+}