From 3ed5986dd68ddbaaecf9676f808e9c062f27f914 Mon Sep 17 00:00:00 2001
From: Alexandre Julliard <julliard@winehq.org>
Date: Thu, 1 Oct 2009 13:57:08 +0200
Subject: [PATCH] version: Make ver.dll into a stand-alone 16-bit module.

---
 .gitignore                                    |   1 -
 configure                                     |   9 +
 configure.ac                                  |   1 +
 dlls/Makefile.in                              |   4 -
 dlls/ver.dll16/Makefile.in                    |  14 +
 .../ver.spec => ver.dll16/ver.dll16.spec}     |   0
 dlls/ver.dll16/version.c                      | 558 ++++++++++++++++++
 dlls/version/Makefile.in                      |   5 -
 dlls/version/ver16.c                          | 182 ------
 9 files changed, 582 insertions(+), 192 deletions(-)
 create mode 100644 dlls/ver.dll16/Makefile.in
 rename dlls/{version/ver.spec => ver.dll16/ver.dll16.spec} (100%)
 create mode 100644 dlls/ver.dll16/version.c
 delete mode 100644 dlls/version/ver16.c

diff --git a/.gitignore b/.gitignore
index f69a938eba9..6d85393fb25 100644
--- a/.gitignore
+++ b/.gitignore
@@ -120,7 +120,6 @@ dlls/shdocvw/shdocvw_v1.tlb
 dlls/stdole2.tlb/std_ole_v2.tlb
 dlls/stdole32.tlb/std_ole_v1.tlb
 dlls/user.exe16
-dlls/ver.dll16
 dlls/wineps16.drv16
 dlls/wprocs.dll16
 include/activaut.h
diff --git a/configure b/configure
index 9233a42a4db..dd41b9cd551 100755
--- a/configure
+++ b/configure
@@ -16867,6 +16867,14 @@ ALL_MAKEFILE_DEPENDS="$ALL_MAKEFILE_DEPENDS
 dlls/vdmdbg/Makefile: dlls/vdmdbg/Makefile.in dlls/Makedll.rules"
 ac_config_files="$ac_config_files dlls/vdmdbg/Makefile"
 
+ALL_MAKEFILES="$ALL_MAKEFILES \\
+	dlls/ver.dll16/Makefile"
+test "x$enable_win16" != xno && ALL_DLL_DIRS="$ALL_DLL_DIRS \\
+	ver.dll16"
+ALL_MAKEFILE_DEPENDS="$ALL_MAKEFILE_DEPENDS
+dlls/ver.dll16/Makefile: dlls/ver.dll16/Makefile.in dlls/Makedll.rules"
+ac_config_files="$ac_config_files dlls/ver.dll16/Makefile"
+
 ALL_MAKEFILES="$ALL_MAKEFILES \\
 	dlls/version/Makefile"
 test "x$enable_version" != xno && ALL_DLL_DIRS="$ALL_DLL_DIRS \\
@@ -19105,6 +19113,7 @@ do
     "dlls/uxtheme/tests/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/uxtheme/tests/Makefile" ;;
     "dlls/vdhcp.vxd/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/vdhcp.vxd/Makefile" ;;
     "dlls/vdmdbg/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/vdmdbg/Makefile" ;;
+    "dlls/ver.dll16/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/ver.dll16/Makefile" ;;
     "dlls/version/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/version/Makefile" ;;
     "dlls/version/tests/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/version/tests/Makefile" ;;
     "dlls/vmm.vxd/Makefile") CONFIG_FILES="$CONFIG_FILES dlls/vmm.vxd/Makefile" ;;
diff --git a/configure.ac b/configure.ac
index 3d32d28142e..8777f15f451 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2471,6 +2471,7 @@ WINE_CONFIG_MAKEFILE([dlls/uxtheme/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DL
 WINE_CONFIG_MAKEFILE([dlls/uxtheme/tests/Makefile],[dlls/Maketest.rules],[dlls],[ALL_TEST_DIRS],[enable_tests])
 WINE_CONFIG_MAKEFILE([dlls/vdhcp.vxd/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL_DIRS],[enable_win16])
 WINE_CONFIG_MAKEFILE([dlls/vdmdbg/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL_DIRS])
+WINE_CONFIG_MAKEFILE([dlls/ver.dll16/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL_DIRS],[enable_win16])
 WINE_CONFIG_MAKEFILE([dlls/version/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL_DIRS])
 WINE_CONFIG_MAKEFILE([dlls/version/tests/Makefile],[dlls/Maketest.rules],[dlls],[ALL_TEST_DIRS],[enable_tests])
 WINE_CONFIG_MAKEFILE([dlls/vmm.vxd/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL_DIRS],[enable_win16])
diff --git a/dlls/Makefile.in b/dlls/Makefile.in
index 40b96d0276e..8e0837dbd2c 100644
--- a/dlls/Makefile.in
+++ b/dlls/Makefile.in
@@ -24,7 +24,6 @@ WIN16_FILES = \
 	mmsystem.dll16 \
 	setupx.dll16 \
 	user.exe16 \
-	ver.dll16 \
 	wineps16.drv16 \
 	wprocs.dll16
 
@@ -51,9 +50,6 @@ setupx.dll16:
 user.exe16:
 	echo "user32.dll" >$@
 
-ver.dll16:
-	echo "version.dll" >$@
-
 wprocs.dll16:
 	echo "winedos.dll" >$@
 
diff --git a/dlls/ver.dll16/Makefile.in b/dlls/ver.dll16/Makefile.in
new file mode 100644
index 00000000000..6d0c30a26cd
--- /dev/null
+++ b/dlls/ver.dll16/Makefile.in
@@ -0,0 +1,14 @@
+TOPSRCDIR = @top_srcdir@
+TOPOBJDIR = ../..
+SRCDIR    = @srcdir@
+VPATH     = @srcdir@
+MODULE    = ver.dll16
+IMPORTS   = version lz32 kernel32
+
+EXTRADLLFLAGS = -Wb,--subsystem,win16,--main-module,version.dll
+
+C_SRCS = version.c
+
+@MAKE_DLL_RULES@
+
+@DEPENDENCIES@  # everything below this line is overwritten by make depend
diff --git a/dlls/version/ver.spec b/dlls/ver.dll16/ver.dll16.spec
similarity index 100%
rename from dlls/version/ver.spec
rename to dlls/ver.dll16/ver.dll16.spec
diff --git a/dlls/ver.dll16/version.c b/dlls/ver.dll16/version.c
new file mode 100644
index 00000000000..950b650ca3f
--- /dev/null
+++ b/dlls/ver.dll16/version.c
@@ -0,0 +1,558 @@
+/*
+ * Implementation of VER.DLL
+ *
+ * Copyright 1996, 1997 Marcus Meissner
+ * Copyright 1997 David Cuthbert
+ * Copyright 1999 Ulrich Weigand
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+
+#define NONAMELESSUNION
+#define NONAMELESSSTRUCT
+#include "windef.h"
+#include "wine/winbase16.h"
+#include "winver.h"
+#include "lzexpand.h"
+#include "wine/unicode.h"
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(ver);
+
+#ifndef SEEK_SET
+#define SEEK_SET   0
+#define SEEK_CUR   1
+#define SEEK_END   2
+#endif
+
+/**********************************************************************
+ *  find_entry_by_id
+ *
+ * Find an entry by id in a resource directory
+ * Copied from loader/pe_resource.c
+ */
+static const IMAGE_RESOURCE_DIRECTORY *find_entry_by_id( const IMAGE_RESOURCE_DIRECTORY *dir,
+                                                         WORD id, const void *root )
+{
+    const IMAGE_RESOURCE_DIRECTORY_ENTRY *entry;
+    int min, max, pos;
+
+    entry = (const IMAGE_RESOURCE_DIRECTORY_ENTRY *)(dir + 1);
+    min = dir->NumberOfNamedEntries;
+    max = min + dir->NumberOfIdEntries - 1;
+    while (min <= max)
+    {
+        pos = (min + max) / 2;
+        if (entry[pos].u1.s2.Id == id)
+            return (const IMAGE_RESOURCE_DIRECTORY *)((const char *)root + entry[pos].u2.s3.OffsetToDirectory);
+        if (entry[pos].u1.s2.Id > id) max = pos - 1;
+        else min = pos + 1;
+    }
+    return NULL;
+}
+
+
+/**********************************************************************
+ *  find_entry_default
+ *
+ * Find a default entry in a resource directory
+ * Copied from loader/pe_resource.c
+ */
+static const IMAGE_RESOURCE_DIRECTORY *find_entry_default( const IMAGE_RESOURCE_DIRECTORY *dir,
+                                                           const void *root )
+{
+    const IMAGE_RESOURCE_DIRECTORY_ENTRY *entry;
+
+    entry = (const IMAGE_RESOURCE_DIRECTORY_ENTRY *)(dir + 1);
+    return (const IMAGE_RESOURCE_DIRECTORY *)((const char *)root + entry->u2.s3.OffsetToDirectory);
+}
+
+
+/**********************************************************************
+ *  find_entry_by_name
+ *
+ * Find an entry by name in a resource directory
+ * Copied from loader/pe_resource.c
+ */
+static const IMAGE_RESOURCE_DIRECTORY *find_entry_by_name( const IMAGE_RESOURCE_DIRECTORY *dir,
+                                                           LPCSTR name, const void *root )
+{
+    const IMAGE_RESOURCE_DIRECTORY *ret = NULL;
+    LPWSTR nameW;
+    DWORD namelen;
+
+    if (!HIWORD(name)) return find_entry_by_id( dir, LOWORD(name), root );
+    if (name[0] == '#')
+    {
+        return find_entry_by_id( dir, atoi(name+1), root );
+    }
+
+    namelen = MultiByteToWideChar( CP_ACP, 0, name, -1, NULL, 0 );
+    if ((nameW = HeapAlloc( GetProcessHeap(), 0, namelen * sizeof(WCHAR) )))
+    {
+        const IMAGE_RESOURCE_DIRECTORY_ENTRY *entry;
+        const IMAGE_RESOURCE_DIR_STRING_U *str;
+        int min, max, res, pos;
+
+        MultiByteToWideChar( CP_ACP, 0, name, -1, nameW, namelen );
+        namelen--;  /* remove terminating null */
+        entry = (const IMAGE_RESOURCE_DIRECTORY_ENTRY *)(dir + 1);
+        min = 0;
+        max = dir->NumberOfNamedEntries - 1;
+        while (min <= max)
+        {
+            pos = (min + max) / 2;
+            str = (const IMAGE_RESOURCE_DIR_STRING_U *)((const char *)root + entry[pos].u1.s1.NameOffset);
+            res = strncmpiW( nameW, str->NameString, str->Length );
+            if (!res && namelen == str->Length)
+            {
+                ret = (const IMAGE_RESOURCE_DIRECTORY *)((const char *)root + entry[pos].u2.s3.OffsetToDirectory);
+                break;
+            }
+            if (res < 0) max = pos - 1;
+            else min = pos + 1;
+        }
+        HeapFree( GetProcessHeap(), 0, nameW );
+    }
+    return ret;
+}
+
+
+/***********************************************************************
+ *           read_xx_header         [internal]
+ */
+static int read_xx_header( HFILE lzfd )
+{
+    IMAGE_DOS_HEADER mzh;
+    char magic[3];
+
+    LZSeek( lzfd, 0, SEEK_SET );
+    if ( sizeof(mzh) != LZRead( lzfd, (LPSTR)&mzh, sizeof(mzh) ) )
+        return 0;
+    if ( mzh.e_magic != IMAGE_DOS_SIGNATURE )
+        return 0;
+
+    LZSeek( lzfd, mzh.e_lfanew, SEEK_SET );
+    if ( 2 != LZRead( lzfd, magic, 2 ) )
+        return 0;
+
+    LZSeek( lzfd, mzh.e_lfanew, SEEK_SET );
+
+    if ( magic[0] == 'N' && magic[1] == 'E' )
+        return IMAGE_OS2_SIGNATURE;
+    if ( magic[0] == 'P' && magic[1] == 'E' )
+        return IMAGE_NT_SIGNATURE;
+
+    magic[2] = '\0';
+    WARN("Can't handle %s files.\n", magic );
+    return 0;
+}
+
+/***********************************************************************
+ *           find_ne_resource         [internal]
+ */
+static BOOL find_ne_resource( HFILE lzfd, LPCSTR typeid, LPCSTR resid,
+                                DWORD *resLen, DWORD *resOff )
+{
+    IMAGE_OS2_HEADER nehd;
+    NE_TYPEINFO *typeInfo;
+    NE_NAMEINFO *nameInfo;
+    DWORD nehdoffset;
+    LPBYTE resTab;
+    DWORD resTabSize;
+    int count;
+
+    /* Read in NE header */
+    nehdoffset = LZSeek( lzfd, 0, SEEK_CUR );
+    if ( sizeof(nehd) != LZRead( lzfd, (LPSTR)&nehd, sizeof(nehd) ) ) return 0;
+
+    resTabSize = nehd.ne_restab - nehd.ne_rsrctab;
+    if ( !resTabSize )
+    {
+        TRACE("No resources in NE dll\n" );
+        return FALSE;
+    }
+
+    /* Read in resource table */
+    resTab = HeapAlloc( GetProcessHeap(), 0, resTabSize );
+    if ( !resTab ) return FALSE;
+
+    LZSeek( lzfd, nehd.ne_rsrctab + nehdoffset, SEEK_SET );
+    if ( resTabSize != LZRead( lzfd, (char*)resTab, resTabSize ) )
+    {
+        HeapFree( GetProcessHeap(), 0, resTab );
+        return FALSE;
+    }
+
+    /* Find resource */
+    typeInfo = (NE_TYPEINFO *)(resTab + 2);
+
+    if (HIWORD(typeid) != 0)  /* named type */
+    {
+        BYTE len = strlen( typeid );
+        while (typeInfo->type_id)
+        {
+            if (!(typeInfo->type_id & 0x8000))
+            {
+                BYTE *p = resTab + typeInfo->type_id;
+                if ((*p == len) && !strncasecmp( (char*)p+1, typeid, len )) goto found_type;
+            }
+            typeInfo = (NE_TYPEINFO *)((char *)(typeInfo + 1) +
+                                       typeInfo->count * sizeof(NE_NAMEINFO));
+        }
+    }
+    else  /* numeric type id */
+    {
+        WORD id = LOWORD(typeid) | 0x8000;
+        while (typeInfo->type_id)
+        {
+            if (typeInfo->type_id == id) goto found_type;
+            typeInfo = (NE_TYPEINFO *)((char *)(typeInfo + 1) +
+                                       typeInfo->count * sizeof(NE_NAMEINFO));
+        }
+    }
+    TRACE("No typeid entry found for %p\n", typeid );
+    HeapFree( GetProcessHeap(), 0, resTab );
+    return FALSE;
+
+ found_type:
+    nameInfo = (NE_NAMEINFO *)(typeInfo + 1);
+
+    if (HIWORD(resid) != 0)  /* named resource */
+    {
+        BYTE len = strlen( resid );
+        for (count = typeInfo->count; count > 0; count--, nameInfo++)
+        {
+            BYTE *p = resTab + nameInfo->id;
+            if (nameInfo->id & 0x8000) continue;
+            if ((*p == len) && !strncasecmp( (char*)p+1, resid, len )) goto found_name;
+        }
+    }
+    else  /* numeric resource id */
+    {
+        WORD id = LOWORD(resid) | 0x8000;
+        for (count = typeInfo->count; count > 0; count--, nameInfo++)
+            if (nameInfo->id == id) goto found_name;
+    }
+    TRACE("No resid entry found for %p\n", typeid );
+    HeapFree( GetProcessHeap(), 0, resTab );
+    return FALSE;
+
+ found_name:
+    /* Return resource data */
+    if ( resLen ) *resLen = nameInfo->length << *(WORD *)resTab;
+    if ( resOff ) *resOff = nameInfo->offset << *(WORD *)resTab;
+
+    HeapFree( GetProcessHeap(), 0, resTab );
+    return TRUE;
+}
+
+/***********************************************************************
+ *           find_pe_resource         [internal]
+ */
+static BOOL find_pe_resource( HFILE lzfd, LPCSTR typeid, LPCSTR resid,
+                                DWORD *resLen, DWORD *resOff )
+{
+    IMAGE_NT_HEADERS pehd;
+    DWORD pehdoffset;
+    PIMAGE_DATA_DIRECTORY resDataDir;
+    PIMAGE_SECTION_HEADER sections;
+    LPBYTE resSection;
+    DWORD resSectionSize;
+    const void *resDir;
+    const IMAGE_RESOURCE_DIRECTORY *resPtr;
+    const IMAGE_RESOURCE_DATA_ENTRY *resData;
+    int i, nSections;
+    BOOL ret = FALSE;
+
+    /* Read in PE header */
+    pehdoffset = LZSeek( lzfd, 0, SEEK_CUR );
+    if ( sizeof(pehd) != LZRead( lzfd, (LPSTR)&pehd, sizeof(pehd) ) ) return 0;
+
+    resDataDir = pehd.OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_RESOURCE;
+    if ( !resDataDir->Size )
+    {
+        TRACE("No resources in PE dll\n" );
+        return FALSE;
+    }
+
+    /* Read in section table */
+    nSections = pehd.FileHeader.NumberOfSections;
+    sections = HeapAlloc( GetProcessHeap(), 0,
+                          nSections * sizeof(IMAGE_SECTION_HEADER) );
+    if ( !sections ) return FALSE;
+
+    LZSeek( lzfd, pehdoffset +
+                    sizeof(DWORD) + /* Signature */
+                    sizeof(IMAGE_FILE_HEADER) +
+                    pehd.FileHeader.SizeOfOptionalHeader, SEEK_SET );
+
+    if ( nSections * sizeof(IMAGE_SECTION_HEADER) !=
+         LZRead( lzfd, (LPSTR)sections, nSections * sizeof(IMAGE_SECTION_HEADER) ) )
+    {
+        HeapFree( GetProcessHeap(), 0, sections );
+        return FALSE;
+    }
+
+    /* Find resource section */
+    for ( i = 0; i < nSections; i++ )
+        if (    resDataDir->VirtualAddress >= sections[i].VirtualAddress
+             && resDataDir->VirtualAddress <  sections[i].VirtualAddress +
+                                              sections[i].SizeOfRawData )
+            break;
+
+    if ( i == nSections )
+    {
+        HeapFree( GetProcessHeap(), 0, sections );
+        TRACE("Couldn't find resource section\n" );
+        return FALSE;
+    }
+
+    /* Read in resource section */
+    resSectionSize = sections[i].SizeOfRawData;
+    resSection = HeapAlloc( GetProcessHeap(), 0, resSectionSize );
+    if ( !resSection )
+    {
+        HeapFree( GetProcessHeap(), 0, sections );
+        return FALSE;
+    }
+
+    LZSeek( lzfd, sections[i].PointerToRawData, SEEK_SET );
+    if ( resSectionSize != LZRead( lzfd, (char*)resSection, resSectionSize ) ) goto done;
+
+    /* Find resource */
+    resDir = resSection + (resDataDir->VirtualAddress - sections[i].VirtualAddress);
+
+    resPtr = resDir;
+    resPtr = find_entry_by_name( resPtr, typeid, resDir );
+    if ( !resPtr )
+    {
+        TRACE("No typeid entry found for %p\n", typeid );
+        goto done;
+    }
+    resPtr = find_entry_by_name( resPtr, resid, resDir );
+    if ( !resPtr )
+    {
+        TRACE("No resid entry found for %p\n", resid );
+        goto done;
+    }
+    resPtr = find_entry_default( resPtr, resDir );
+    if ( !resPtr )
+    {
+        TRACE("No default language entry found for %p\n", resid );
+        goto done;
+    }
+
+    /* Find resource data section */
+    resData = (const IMAGE_RESOURCE_DATA_ENTRY*)resPtr;
+    for ( i = 0; i < nSections; i++ )
+        if (    resData->OffsetToData >= sections[i].VirtualAddress
+             && resData->OffsetToData <  sections[i].VirtualAddress +
+                                         sections[i].SizeOfRawData )
+            break;
+
+    if ( i == nSections )
+    {
+        TRACE("Couldn't find resource data section\n" );
+        goto done;
+    }
+
+    /* Return resource data */
+    if ( resLen ) *resLen = resData->Size;
+    if ( resOff ) *resOff = resData->OffsetToData - sections[i].VirtualAddress
+                            + sections[i].PointerToRawData;
+    ret = TRUE;
+
+ done:
+    HeapFree( GetProcessHeap(), 0, resSection );
+    HeapFree( GetProcessHeap(), 0, sections );
+    return ret;
+}
+
+
+/***********************************************************************
+ *           find_resource         [internal]
+ */
+static DWORD find_resource( HFILE lzfd, LPCSTR type, LPCSTR id, DWORD *reslen, DWORD *offset )
+{
+    DWORD magic = read_xx_header( lzfd );
+
+    switch (magic)
+    {
+    case IMAGE_OS2_SIGNATURE:
+        if (!find_ne_resource( lzfd, type, id, reslen, offset )) magic = 0;
+        break;
+    case IMAGE_NT_SIGNATURE:
+        if (!find_pe_resource( lzfd, type, id, reslen, offset )) magic = 0;
+        break;
+    }
+    return magic;
+}
+
+
+/*************************************************************************
+ * GetFileResourceSize                     [VER.2]
+ */
+DWORD WINAPI GetFileResourceSize16( LPCSTR lpszFileName, LPCSTR lpszResType,
+                                    LPCSTR lpszResId, LPDWORD lpdwFileOffset )
+{
+    HFILE lzfd;
+    OFSTRUCT ofs;
+    DWORD reslen = 0;
+
+    TRACE("(%s,type=%p,id=%p,off=%p)\n",
+          debugstr_a(lpszFileName), lpszResType, lpszResId, lpszResId );
+
+    lzfd = LZOpenFileA( (LPSTR)lpszFileName, &ofs, OF_READ );
+    if (lzfd >= 0)
+    {
+        if (!find_resource( lzfd, lpszResType, lpszResId, &reslen, lpdwFileOffset )) reslen = 0;
+        LZClose( lzfd );
+    }
+    return reslen;
+}
+
+
+/*************************************************************************
+ * GetFileResource                         [VER.3]
+ */
+DWORD WINAPI GetFileResource16( LPCSTR lpszFileName, LPCSTR lpszResType,
+                                LPCSTR lpszResId, DWORD dwFileOffset,
+                                DWORD dwResLen, LPVOID lpvData )
+{
+    HFILE lzfd;
+    OFSTRUCT ofs;
+    DWORD reslen = dwResLen;
+
+    TRACE("(%s,type=%p,id=%p,off=%d,len=%d,data=%p)\n",
+		debugstr_a(lpszFileName), lpszResType, lpszResId,
+                dwFileOffset, dwResLen, lpvData );
+
+    lzfd = LZOpenFileA( (LPSTR)lpszFileName, &ofs, OF_READ );
+    if ( lzfd < 0 ) return 0;
+
+    if ( !dwFileOffset )
+    {
+        if (!find_resource( lzfd, lpszResType, lpszResId, &reslen, &dwFileOffset ))
+        {
+            LZClose( lzfd );
+            return 0;
+        }
+    }
+
+    LZSeek( lzfd, dwFileOffset, SEEK_SET );
+    reslen = LZRead( lzfd, lpvData, min( reslen, dwResLen ) );
+    LZClose( lzfd );
+
+    return reslen;
+}
+
+/*************************************************************************
+ * GetFileVersionInfoSize                  [VER.6]
+ */
+DWORD WINAPI GetFileVersionInfoSize16( LPCSTR lpszFileName, LPDWORD lpdwHandle )
+{
+    TRACE("(%s, %p)\n", debugstr_a(lpszFileName), lpdwHandle );
+    return GetFileVersionInfoSizeA( lpszFileName, lpdwHandle );
+}
+
+/*************************************************************************
+ * GetFileVersionInfo                      [VER.7]
+ */
+DWORD WINAPI GetFileVersionInfo16( LPCSTR lpszFileName, DWORD handle,
+                                   DWORD cbBuf, LPVOID lpvData )
+{
+    TRACE("(%s, %08x, %d, %p)\n",
+                debugstr_a(lpszFileName), handle, cbBuf, lpvData );
+
+    return GetFileVersionInfoA( lpszFileName, handle, cbBuf, lpvData );
+}
+
+/*************************************************************************
+ * VerFindFile                             [VER.8]
+ */
+DWORD WINAPI VerFindFile16( UINT16 flags, LPSTR lpszFilename,
+                            LPSTR lpszWinDir, LPSTR lpszAppDir,
+                            LPSTR lpszCurDir, UINT16 *lpuCurDirLen,
+                            LPSTR lpszDestDir, UINT16 *lpuDestDirLen )
+{
+    UINT curDirLen, destDirLen;
+    DWORD retv = VerFindFileA( flags, lpszFilename, lpszWinDir, lpszAppDir,
+                                 lpszCurDir, &curDirLen, lpszDestDir, &destDirLen );
+
+    *lpuCurDirLen = (UINT16)curDirLen;
+    *lpuDestDirLen = (UINT16)destDirLen;
+    return retv;
+}
+
+/*************************************************************************
+ * VerInstallFile                          [VER.9]
+ */
+DWORD WINAPI VerInstallFile16( UINT16 flags,
+                               LPSTR lpszSrcFilename, LPSTR lpszDestFilename,
+                               LPSTR lpszSrcDir, LPSTR lpszDestDir, LPSTR lpszCurDir,
+                               LPSTR lpszTmpFile, UINT16 *lpwTmpFileLen )
+{
+    UINT filelen;
+    DWORD retv = VerInstallFileA( flags, lpszSrcFilename, lpszDestFilename,
+                                    lpszSrcDir, lpszDestDir, lpszCurDir,
+                                    lpszTmpFile, &filelen);
+
+    *lpwTmpFileLen = (UINT16)filelen;
+    return retv;
+}
+
+/*************************************************************************
+ * VerLanguageName                        [VER.10]
+ */
+DWORD WINAPI VerLanguageName16( UINT16 uLang, LPSTR lpszLang, UINT16 cbLang )
+{
+    return VerLanguageNameA( uLang, lpszLang, cbLang );
+}
+
+/*************************************************************************
+ * VerQueryValue                          [VER.11]
+ */
+DWORD WINAPI VerQueryValue16( SEGPTR spvBlock, LPSTR lpszSubBlock,
+                              SEGPTR *lpspBuffer, UINT16 *lpcb )
+{
+    LPVOID lpvBlock = MapSL( spvBlock );
+    LPVOID buffer = lpvBlock;
+    UINT buflen;
+    DWORD retv;
+
+    TRACE("(%p, %s, %p, %p)\n",
+                lpvBlock, debugstr_a(lpszSubBlock), lpspBuffer, lpcb );
+
+    retv = VerQueryValueA( lpvBlock, lpszSubBlock, &buffer, &buflen );
+    if ( !retv ) return FALSE;
+
+    if ( OFFSETOF( spvBlock ) + ((char *) buffer - (char *) lpvBlock) >= 0x10000 )
+    {
+        FIXME("offset %08X too large relative to %04X:%04X\n",
+               (char *) buffer - (char *) lpvBlock, SELECTOROF( spvBlock ), OFFSETOF( spvBlock ) );
+        return FALSE;
+    }
+
+    if (lpcb) *lpcb = buflen;
+    *lpspBuffer = (SEGPTR) ((char *) spvBlock + ((char *) buffer - (char *) lpvBlock));
+
+    return retv;
+}
diff --git a/dlls/version/Makefile.in b/dlls/version/Makefile.in
index 9fc0fbec52b..7f7ce74415b 100644
--- a/dlls/version/Makefile.in
+++ b/dlls/version/Makefile.in
@@ -13,11 +13,6 @@ C_SRCS = \
 
 RC_SRCS = version.rc
 
-C_SRCS16 = \
-	ver16.c
-
-SPEC_SRCS16 = ver.spec
-
 @MAKE_DLL_RULES@
 
 @DEPENDENCIES@  # everything below this line is overwritten by make depend
diff --git a/dlls/version/ver16.c b/dlls/version/ver16.c
deleted file mode 100644
index f399cd2bad8..00000000000
--- a/dlls/version/ver16.c
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * Implementation of VER.DLL
- *
- * Copyright 1999 Ulrich Weigand
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include <stdarg.h>
-
-#include "windef.h"
-#include "wine/winbase16.h"
-#include "winver.h"
-#include "lzexpand.h"
-#include "wine/debug.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(ver);
-
-
-extern DWORD find_resource( HFILE lzfd, LPCSTR type, LPCSTR id, DWORD *reslen, DWORD *offset );
-
-/*************************************************************************
- * GetFileResourceSize                     [VER.2]
- */
-DWORD WINAPI GetFileResourceSize16( LPCSTR lpszFileName, LPCSTR lpszResType,
-                                    LPCSTR lpszResId, LPDWORD lpdwFileOffset )
-{
-    HFILE lzfd;
-    OFSTRUCT ofs;
-    DWORD reslen = 0;
-
-    TRACE("(%s,type=%p,id=%p,off=%p)\n",
-          debugstr_a(lpszFileName), lpszResType, lpszResId, lpszResId );
-
-    lzfd = LZOpenFileA( (LPSTR)lpszFileName, &ofs, OF_READ );
-    if (lzfd >= 0)
-    {
-        if (!find_resource( lzfd, lpszResType, lpszResId, &reslen, lpdwFileOffset )) reslen = 0;
-        LZClose( lzfd );
-    }
-    return reslen;
-}
-
-
-/*************************************************************************
- * GetFileResource                         [VER.3]
- */
-DWORD WINAPI GetFileResource16( LPCSTR lpszFileName, LPCSTR lpszResType,
-                                LPCSTR lpszResId, DWORD dwFileOffset,
-                                DWORD dwResLen, LPVOID lpvData )
-{
-    HFILE lzfd;
-    OFSTRUCT ofs;
-    DWORD reslen = dwResLen;
-
-    TRACE("(%s,type=%p,id=%p,off=%d,len=%d,data=%p)\n",
-		debugstr_a(lpszFileName), lpszResType, lpszResId,
-                dwFileOffset, dwResLen, lpvData );
-
-    lzfd = LZOpenFileA( (LPSTR)lpszFileName, &ofs, OF_READ );
-    if ( lzfd < 0 ) return 0;
-
-    if ( !dwFileOffset )
-    {
-        if (!find_resource( lzfd, lpszResType, lpszResId, &reslen, &dwFileOffset ))
-        {
-            LZClose( lzfd );
-            return 0;
-        }
-    }
-
-    LZSeek( lzfd, dwFileOffset, 0 /* SEEK_SET */ );
-    reslen = LZRead( lzfd, lpvData, min( reslen, dwResLen ) );
-    LZClose( lzfd );
-
-    return reslen;
-}
-
-/*************************************************************************
- * GetFileVersionInfoSize                  [VER.6]
- */
-DWORD WINAPI GetFileVersionInfoSize16( LPCSTR lpszFileName, LPDWORD lpdwHandle )
-{
-    TRACE("(%s, %p)\n", debugstr_a(lpszFileName), lpdwHandle );
-    return GetFileVersionInfoSizeA( lpszFileName, lpdwHandle );
-}
-
-/*************************************************************************
- * GetFileVersionInfo                      [VER.7]
- */
-DWORD WINAPI GetFileVersionInfo16( LPCSTR lpszFileName, DWORD handle,
-                                   DWORD cbBuf, LPVOID lpvData )
-{
-    TRACE("(%s, %08x, %d, %p)\n",
-                debugstr_a(lpszFileName), handle, cbBuf, lpvData );
-
-    return GetFileVersionInfoA( lpszFileName, handle, cbBuf, lpvData );
-}
-
-/*************************************************************************
- * VerFindFile                             [VER.8]
- */
-DWORD WINAPI VerFindFile16( UINT16 flags, LPSTR lpszFilename,
-                            LPSTR lpszWinDir, LPSTR lpszAppDir,
-                            LPSTR lpszCurDir, UINT16 *lpuCurDirLen,
-                            LPSTR lpszDestDir, UINT16 *lpuDestDirLen )
-{
-    UINT curDirLen, destDirLen;
-    DWORD retv = VerFindFileA( flags, lpszFilename, lpszWinDir, lpszAppDir,
-                                 lpszCurDir, &curDirLen, lpszDestDir, &destDirLen );
-
-    *lpuCurDirLen = (UINT16)curDirLen;
-    *lpuDestDirLen = (UINT16)destDirLen;
-    return retv;
-}
-
-/*************************************************************************
- * VerInstallFile                          [VER.9]
- */
-DWORD WINAPI VerInstallFile16( UINT16 flags,
-                               LPSTR lpszSrcFilename, LPSTR lpszDestFilename,
-                               LPSTR lpszSrcDir, LPSTR lpszDestDir, LPSTR lpszCurDir,
-                               LPSTR lpszTmpFile, UINT16 *lpwTmpFileLen )
-{
-    UINT filelen;
-    DWORD retv = VerInstallFileA( flags, lpszSrcFilename, lpszDestFilename,
-                                    lpszSrcDir, lpszDestDir, lpszCurDir,
-                                    lpszTmpFile, &filelen);
-
-    *lpwTmpFileLen = (UINT16)filelen;
-    return retv;
-}
-
-/*************************************************************************
- * VerLanguageName                        [VER.10]
- */
-DWORD WINAPI VerLanguageName16( UINT16 uLang, LPSTR lpszLang, UINT16 cbLang )
-{
-    return VerLanguageNameA( uLang, lpszLang, cbLang );
-}
-
-/*************************************************************************
- * VerQueryValue                          [VER.11]
- */
-DWORD WINAPI VerQueryValue16( SEGPTR spvBlock, LPSTR lpszSubBlock,
-                              SEGPTR *lpspBuffer, UINT16 *lpcb )
-{
-    LPVOID lpvBlock = MapSL( spvBlock );
-    LPVOID buffer = lpvBlock;
-    UINT buflen;
-    DWORD retv;
-
-    TRACE("(%p, %s, %p, %p)\n",
-                lpvBlock, debugstr_a(lpszSubBlock), lpspBuffer, lpcb );
-
-    retv = VerQueryValueA( lpvBlock, lpszSubBlock, &buffer, &buflen );
-    if ( !retv ) return FALSE;
-
-    if ( OFFSETOF( spvBlock ) + ((char *) buffer - (char *) lpvBlock) >= 0x10000 )
-    {
-        FIXME("offset %08X too large relative to %04X:%04X\n",
-               (char *) buffer - (char *) lpvBlock, SELECTOROF( spvBlock ), OFFSETOF( spvBlock ) );
-        return FALSE;
-    }
-
-    if (lpcb) *lpcb = buflen;
-    *lpspBuffer = (SEGPTR) ((char *) spvBlock + ((char *) buffer - (char *) lpvBlock));
-
-    return retv;
-}
-- 
GitLab