/* 
 * Implementation of VER.DLL
 * 
 * Copyright 1996,1997 Marcus Meissner
 * Copyright 1997 David Cuthbert
 */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include "windows.h"
#include "win.h"
#include "winerror.h"
#include "heap.h"
#include "ver.h"
#include "lzexpand.h"
#include "module.h"
#include "neexe.h"
#include "debug.h"
#include "xmalloc.h"
#include "winreg.h"

#define LZREAD(what) \
  if (sizeof(*what)!=LZRead32(lzfd,what,sizeof(*what))) return 0;
#define LZTELL(lzfd) LZSeek32(lzfd, 0, SEEK_CUR);

/******************************************************************************
 *
 *   void  ver_dstring(
 *      char const * prologue,
 *      char const * teststring,
 *      char const * epilogue )
 *
 *   This function will print via dprintf[_]ver to stddeb the prologue string,
 *   followed by the address of teststring and the string it contains if
 *   teststring is non-null or "(null)" otherwise, and then the epilogue
 *   string followed by a new line.
 *
 *   Revision history
 *      30-May-1997 Dave Cuthbert (dacut@ece.cmu.edu)
 *         Original implementation as dprintf[_]ver_string
 *      05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
 *         Fixed problem that caused bug with tools/make_debug -- renaming
 *         this function should fix the problem.
 *      15-Feb-1998 Dimitrie Paun (dimi@cs.toronto.edu)
 *         Modified it to make it print the message using only one
 *         dprintf[_]ver call.
 *
 *****************************************************************************/

static void  ver_dstring(
    char const * prologue,
    char const * teststring,
    char const * epilogue )
{
    dprintf_info(ver, "%s %p (\"%s\") %s\n", prologue, 
		(void const *) teststring, 
		teststring ? teststring : "(null)",
		epilogue);
}

/******************************************************************************
 *
 *   This function will print via dprintf[_]ver to stddeb debug info regarding
 *   the file info structure vffi.
 *      15-Feb-1998 Dimitrie Paun (dimi@cs.toronto.edu)
 *      Added this function to clean up the code.
 *
 *****************************************************************************/
static void print_vffi_debug(VS_FIXEDFILEINFO *vffi)
{
        dbg_decl_str(ver, 1024);

	dprintf_info(ver," structversion=0x%lx.0x%lx, fileversion=0x%lx.0x%lx, productversion=0x%lx.0x%lx, flagmask=0x%lx, flags=%s%s%s%s%s%s\n",
		    (vffi->dwStrucVersion>>16),vffi->dwStrucVersion&0xFFFF,
		    vffi->dwFileVersionMS,vffi->dwFileVersionLS,
		    vffi->dwProductVersionMS,vffi->dwProductVersionLS,
		    vffi->dwFileFlagsMask,
		    (vffi->dwFileFlags & VS_FF_DEBUG) ? "DEBUG," : "",
		    (vffi->dwFileFlags & VS_FF_PRERELEASE) ? "PRERELEASE," : "",
		    (vffi->dwFileFlags & VS_FF_PATCHED) ? "PATCHED," : "",
		    (vffi->dwFileFlags & VS_FF_PRIVATEBUILD) ? "PRIVATEBUILD," : "",
		    (vffi->dwFileFlags & VS_FF_INFOINFERRED) ? "INFOINFERRED," : "",
		    (vffi->dwFileFlags & VS_FF_SPECIALBUILD) ? "SPECIALBUILD," : ""
		    );

	dsprintf(ver," OS=0x%lx.0x%lx ",
		(vffi->dwFileOS&0xFFFF0000)>>16,
		vffi->dwFileOS&0x0000FFFF
	);
	switch (vffi->dwFileOS&0xFFFF0000) {
	case VOS_DOS:dsprintf(ver,"DOS,");break;
	case VOS_OS216:dsprintf(ver,"OS/2-16,");break;
	case VOS_OS232:dsprintf(ver,"OS/2-32,");break;
	case VOS_NT:dsprintf(ver,"NT,");break;
	case VOS_UNKNOWN:
	default:
		dsprintf(ver,"UNKNOWN(0x%lx),",vffi->dwFileOS&0xFFFF0000);break;
	}
	switch (vffi->dwFileOS & 0xFFFF) {
	case VOS__BASE:dsprintf(ver,"BASE");break;
	case VOS__WINDOWS16:dsprintf(ver,"WIN16");break;
	case VOS__WINDOWS32:dsprintf(ver,"WIN32");break;
	case VOS__PM16:dsprintf(ver,"PM16");break;
	case VOS__PM32:dsprintf(ver,"PM32");break;
	default:dsprintf(ver,"UNKNOWN(0x%lx)",vffi->dwFileOS&0xFFFF);break;
	}
	dprintf_info(ver, "(%s)\n", dbg_str(ver));

	dbg_reset_str(ver);
	switch (vffi->dwFileType) {
	default:
	case VFT_UNKNOWN:
		dsprintf(ver,"filetype=Unknown(0x%lx)",vffi->dwFileType);
		break;
	case VFT_APP:dsprintf(ver,"filetype=APP,");break;
	case VFT_DLL:dsprintf(ver,"filetype=DLL,");break;
	case VFT_DRV:
		dsprintf(ver,"filetype=DRV,");
		switch(vffi->dwFileSubtype) {
		default:
		case VFT2_UNKNOWN:
			dsprintf(ver,"UNKNOWN(0x%lx)",vffi->dwFileSubtype);
			break;
		case VFT2_DRV_PRINTER:
			dsprintf(ver,"PRINTER");
			break;
		case VFT2_DRV_KEYBOARD:
			dsprintf(ver,"KEYBOARD");
			break;
		case VFT2_DRV_LANGUAGE:
			dsprintf(ver,"LANGUAGE");
			break;
		case VFT2_DRV_DISPLAY:
			dsprintf(ver,"DISPLAY");
			break;
		case VFT2_DRV_MOUSE:
			dsprintf(ver,"MOUSE");
			break;
		case VFT2_DRV_NETWORK:
			dsprintf(ver,"NETWORK");
			break;
		case VFT2_DRV_SYSTEM:
			dsprintf(ver,"SYSTEM");
			break;
		case VFT2_DRV_INSTALLABLE:
			dsprintf(ver,"INSTALLABLE");
			break;
		case VFT2_DRV_SOUND:
			dsprintf(ver,"SOUND");
			break;
		case VFT2_DRV_COMM:
			dsprintf(ver,"COMM");
			break;
		case VFT2_DRV_INPUTMETHOD:
			dsprintf(ver,"INPUTMETHOD");
			break;
		}
		break;
	case VFT_FONT:
		dsprintf(ver,"filetype=FONT.");
		switch (vffi->dwFileSubtype) {
		default:
			dsprintf(ver,"UNKNOWN(0x%lx)",vffi->dwFileSubtype);
			break;
		case VFT2_FONT_RASTER:dsprintf(ver,"RASTER");break;
		case VFT2_FONT_VECTOR:dsprintf(ver,"VECTOR");break;
		case VFT2_FONT_TRUETYPE:dsprintf(ver,"TRUETYPE");break;
		}
		break;
	case VFT_VXD:dsprintf(ver,"filetype=VXD");break;
	case VFT_STATIC_LIB:dsprintf(ver,"filetype=STATIC_LIB");break;
	}
	dprintf_info(ver, "%s\n", dbg_str(ver));

	dprintf_info(ver, "  filedata=0x%lx.0x%lx\n",
		    vffi->dwFileDateMS,vffi->dwFileDateLS);
}

/******************************************************************************
 *
 *   int  testFileExistence(
 *      char const * path,
 *      char const * file )
 *
 *   Tests whether a given path/file combination exists.  If the file does
 *   not exist, the return value is zero.  If it does exist, the return
 *   value is non-zero.
 *
 *   Revision history
 *      30-May-1997 Dave Cuthbert (dacut@ece.cmu.edu)
 *         Original implementation
 *
 *****************************************************************************/

static int  testFileExistence(
   char const * path,
   char const * file )
{
    char  filename[1024];
    int  filenamelen;
    OFSTRUCT  fileinfo;
    int  retval;

    fileinfo.cBytes = sizeof(OFSTRUCT);

    strcpy(filename, path);
    filenamelen = strlen(filename);

    /* Add a trailing \ if necessary */
    if(filenamelen) {
	if(filename[filenamelen - 1] != '\\')
	    strcat(filename, "\\");
    }
    else /* specify the current directory */
	strcpy(filename, ".\\");

    /* Create the full pathname */
    strcat(filename, file);

    if(OpenFile32(filename, &fileinfo, OF_EXIST) == HFILE_ERROR32)
	retval = 0;
    else
	retval = 1;

    return  retval;
}

/******************************************************************************
 *
 *   int  testFileExclusiveExistence(
 *      char const * path,
 *      char const * file )
 *
 *   Tests whether a given path/file combination exists and ensures that no
 *   other programs have handles to the given file.  If the file does not
 *   exist or is open, the return value is zero.  If it does exist, the
 *   return value is non-zero.
 *
 *   Revision history
 *      30-May-1997 Dave Cuthbert (dacut@ece.cmu.edu)
 *         Original implementation
 *
 *****************************************************************************/

static int  testFileExclusiveExistence(
   char const * path,
   char const * file )
{
    char  filename[1024];
    int  filenamelen;
    OFSTRUCT  fileinfo;
    int  retval;

    fileinfo.cBytes = sizeof(OFSTRUCT);

    strcpy(filename, path);
    filenamelen = strlen(filename);

    /* Add a trailing \ if necessary */
    if(filenamelen) {
	if(filename[filenamelen - 1] != '\\')
	    strcat(filename, "\\");
    }
    else /* specify the current directory */
	strcpy(filename, ".\\");

    /* Create the full pathname */
    strcat(filename, file);

    if(OpenFile32(filename, &fileinfo, OF_EXIST | OF_SHARE_EXCLUSIVE) ==
       HFILE_ERROR32)
	retval = 0;
    else
	retval = 1;

    return retval;
}


static int read_xx_header(HFILE32 lzfd) {
	IMAGE_DOS_HEADER	mzh;
	char			magic[3];

	LZSeek32(lzfd,0,SEEK_SET);
	if (sizeof(mzh)!=LZRead32(lzfd,&mzh,sizeof(mzh)))
		return 0;
	if (mzh.e_magic!=IMAGE_DOS_SIGNATURE)
		return 0;
	LZSeek32(lzfd,mzh.e_lfanew,SEEK_SET);
	if (2!=LZRead32(lzfd,magic,2))
		return 0;
	LZSeek32(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';
	fprintf(stderr,"misc/ver.c:read_ne_header:can't handle %s files.\n",magic);
	return 0;
}


static int find_ne_resource(
	HFILE32 lzfd,SEGPTR typeid,SEGPTR resid,
	BYTE **resdata,int *reslen,DWORD *off
) {
	IMAGE_OS2_HEADER nehd;
	NE_TYPEINFO	ti;
	NE_NAMEINFO	ni;
	int		i;
	WORD		shiftcount;
	DWORD		nehdoffset;

	nehdoffset = LZTELL(lzfd);
	LZREAD(&nehd);
	if (nehd.resource_tab_offset==nehd.rname_tab_offset) {
		dprintf_info(ver,"no resources in NE dll\n");
		return 0;
	}
	LZSeek32(lzfd,nehd.resource_tab_offset+nehdoffset,SEEK_SET);
	LZREAD(&shiftcount);
	dprintf_info(ver,"shiftcount is %d\n",shiftcount);
	dprintf_info(ver,"reading resource typeinfo dir.\n");

	if (!HIWORD(typeid)) typeid = (SEGPTR)(LOWORD(typeid) | 0x8000);
	if (!HIWORD(resid))  resid  = (SEGPTR)(LOWORD(resid) | 0x8000);
	while (1) {
		int	skipflag;

		LZREAD(&ti);
		if (!ti.type_id)
			return 0;
		dprintf_info(ver,"    ti.typeid =%04x,count=%d\n",ti.type_id,ti.count);

		skipflag=0;
		if (!HIWORD(typeid)) {
			if ((ti.type_id&0x8000)&&(typeid!=ti.type_id))
				skipflag=1;
		} else {
			if (ti.type_id & 0x8000) {
				skipflag=1; 
			} else {
				BYTE	len;
				char	*str;
				DWORD	whereleft;

				whereleft = LZTELL(lzfd);
				LZSeek32(
					lzfd,
					nehdoffset+nehd.resource_tab_offset+ti.type_id,
					SEEK_SET
				);
				LZREAD(&len);
				str=xmalloc(len);
				if (len!=LZRead32(lzfd,str,len))
					return 0;
				dprintf_info(ver,"read %s to compare it with %s\n",
					str,(char*)PTR_SEG_TO_LIN(typeid)
				);
				if (lstrcmpi32A(str,(char*)PTR_SEG_TO_LIN(typeid)))
					skipflag=1;
				free(str);
				LZSeek32(lzfd,whereleft,SEEK_SET);
			}
		}
		if (skipflag) {
			LZSeek32(lzfd,ti.count*sizeof(ni),SEEK_CUR);
			continue;
		}
		for (i=0;i<ti.count;i++) {
			WORD	*rdata;
			int	len;

			LZREAD(&ni);
			dprintf_info(ver,"	ni.id=%4x,offset=%d,length=%d\n",
				ni.id,ni.offset,ni.length
			);
			skipflag=1;
			if (!HIWORD(resid)) {
				if (ni.id == resid)
					skipflag=0;
			} else {
				if (!(ni.id & 0x8000)) {
					BYTE	len;
					char	*str;
					DWORD	whereleft;

					whereleft = LZTELL(lzfd);
					  LZSeek32(
						lzfd,
						nehdoffset+nehd.resource_tab_offset+ni.id,
						SEEK_SET
					);
					LZREAD(&len);
					str=xmalloc(len);
					if (len!=LZRead32(lzfd,str,len))
						return 0;
					dprintf_info(ver,"read %s to compare it with %s\n",
						str,(char*)PTR_SEG_TO_LIN(typeid)
					);
					if (!lstrcmpi32A(str,(char*)PTR_SEG_TO_LIN(typeid)))
						skipflag=0;
					free(str);
					LZSeek32(lzfd,whereleft,SEEK_SET);
				}
			}
			if (skipflag)
				continue;
			LZSeek32(lzfd,((int)ni.offset<<shiftcount),SEEK_SET);
			*off	= (int)ni.offset<<shiftcount;
			len	= ni.length<<shiftcount;
			rdata=(WORD*)xmalloc(len);
			if (len!=LZRead32(lzfd,rdata,len)) {
				free(rdata);
				return 0;
			}
			dprintf_info(ver,"resource found.\n");
			*resdata= (BYTE*)rdata;
			*reslen	= len;
			return 1;
		}
	}
}

/* Loads the specified PE resource.
 * FIXME: shouldn't load the whole image
 */
static int
find_pe_resource(
	HFILE32 lzfd,LPWSTR typeid,LPWSTR resid,
	BYTE **resdata,int *reslen,DWORD *off
) {
	IMAGE_NT_HEADERS pehd;
	int		i;
	UINT32		nrofsections;
	DWORD		imagesize,pehdoffset;
	BYTE		*image;
	IMAGE_DATA_DIRECTORY		resdir;
	LPIMAGE_RESOURCE_DIRECTORY	resourcedir,xresdir;
	LPIMAGE_RESOURCE_DATA_ENTRY	xresdata;
	LPIMAGE_SECTION_HEADER		sections;

	pehdoffset = LZTELL(lzfd);
	LZREAD(&pehd);
	resdir = pehd.OptionalHeader.DataDirectory[IMAGE_FILE_RESOURCE_DIRECTORY];
	dprintf_info(ver,"find_pe_resource(.,%p,%p,....)\n",typeid,resid);
	if (!resdir.Size) {
		fprintf(stderr,"misc/ver.c:find_pe_resource() no resource directory found in PE file.\n");
		return 0;
	}
	imagesize = pehd.OptionalHeader.SizeOfImage;
	image = HeapAlloc(GetProcessHeap(),0,imagesize);
	nrofsections = pehd.FileHeader.NumberOfSections;

	sections = (LPIMAGE_SECTION_HEADER)HeapAlloc(GetProcessHeap(),0,pehd.FileHeader.NumberOfSections*sizeof(IMAGE_SECTION_HEADER));
	LZSeek32(lzfd,
		pehdoffset+
		sizeof(DWORD)+	/* Signature */
		sizeof(IMAGE_FILE_HEADER)+	
		pehd.FileHeader.SizeOfOptionalHeader,
		SEEK_SET
	);
	if (	nrofsections*sizeof(IMAGE_SECTION_HEADER)!=
		LZRead32(lzfd,sections,nrofsections*sizeof(IMAGE_SECTION_HEADER))
	) {
		HeapFree(GetProcessHeap(),0,image);
		return 0;
	}
	for (i=0;i<nrofsections;i++) {
		if (sections[i].Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA)
			continue;
		LZSeek32(lzfd,sections[i].PointerToRawData,SEEK_SET);
		if (	sections[i].SizeOfRawData!=
			LZRead32(lzfd,image+sections[i].VirtualAddress,sections[i].SizeOfRawData)
		)
			continue;
	}
	resourcedir = (LPIMAGE_RESOURCE_DIRECTORY)(image+resdir.VirtualAddress);
	xresdir = GetResDirEntryW(resourcedir,typeid,(DWORD)resourcedir,FALSE);
	if (!xresdir) {
		dprintf_info(ver,"...no typeid entry found for %p\n",typeid);
		HeapFree(GetProcessHeap(),0,image);
		return 0;
	}
	xresdir = GetResDirEntryW(xresdir,resid,(DWORD)resourcedir,FALSE);
	if (!xresdir) {
		dprintf_info(ver,"...no resid entry found for %p\n",resid);
		HeapFree(GetProcessHeap(),0,image);
		return 0;
	}
	
	xresdir = GetResDirEntryW(xresdir,0,(DWORD)resourcedir,TRUE);
	if (!xresdir) {
		dprintf_info(ver,"...no 0 (default language) entry found for %p\n",resid);
		HeapFree(GetProcessHeap(),0,image);
		return 0;
	}
	xresdata = (LPIMAGE_RESOURCE_DATA_ENTRY)xresdir;
	*reslen	= xresdata->Size;
	*resdata= (LPBYTE)xmalloc(*reslen);
	memcpy(*resdata,image+xresdata->OffsetToData,*reslen);
	/* find physical address for virtual offset */
	for (i=0;i<nrofsections;i++) {
		if (sections[i].Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA)
			continue;
		if (	(xresdata->OffsetToData >= sections[i].VirtualAddress)&&
			(xresdata->OffsetToData < sections[i].VirtualAddress+sections[i].SizeOfRawData)
		) {
			*off = (DWORD)(xresdata->OffsetToData)-(DWORD)(sections[i].VirtualAddress)+(DWORD)(sections[i].PointerToRawData);
			break;
		}
	}
	HeapFree(GetProcessHeap(),0,image);
	HeapFree(GetProcessHeap(),0,sections);
	return 1;
}

/* GetFileResourceSize				[VER.2] */
DWORD WINAPI GetFileResourceSize(LPCSTR filename,SEGPTR restype,SEGPTR resid,
                                 LPDWORD off)
{
	HFILE32			lzfd;
	OFSTRUCT		ofs;
	BYTE			*resdata = NULL;
	int			reslen=0;
	int			res=0;

	dprintf_info(ver,"GetFileResourceSize(%s,%lx,%lx,%p)\n",
		filename,(LONG)restype,(LONG)resid,off
	);
	lzfd=LZOpenFile32A(filename,&ofs,OF_READ);
	if (!lzfd)
		return 0;
	switch (read_xx_header(lzfd)) {
	case 0:
	    res=0;
	    break;
	case IMAGE_OS2_SIGNATURE:
	    res=find_ne_resource(lzfd,restype,resid,&resdata,&reslen,off);
	    break;
	case IMAGE_NT_SIGNATURE:
	    res=find_pe_resource(lzfd,(LPWSTR)restype,(LPWSTR)resid,&resdata,&reslen,off);
	    break;
	}
	if (!res) {
	    LZClose32(lzfd);
	    return 0;
	}
	if (resdata)
		free(resdata);
	LZClose32(lzfd);
	return reslen;
}

/* GetFileResource				[VER.3] */
DWORD WINAPI GetFileResource(LPCSTR filename,SEGPTR restype,SEGPTR resid,
                             DWORD off,DWORD datalen,LPVOID data )
{
	HFILE32			lzfd;
	OFSTRUCT		ofs;
	BYTE			*resdata=NULL;
	int			res=0;
	int			reslen=datalen;

	dprintf_info(ver,"GetFileResource(%s,%lx,%lx,%ld,%ld,%p)\n",
		filename,(LONG)restype,(LONG)resid,off,datalen,data
	);

	lzfd=LZOpenFile32A(filename,&ofs,OF_READ);
	if (lzfd==0)
		return 0;
	if (!off) {
		switch (read_xx_header(lzfd)) {
		case 0:	res=0;
			break;
		case IMAGE_OS2_SIGNATURE:
			res= find_ne_resource(lzfd,restype,resid,&resdata,&reslen,&off);
			break;
		case IMAGE_NT_SIGNATURE:
			res= find_pe_resource(lzfd,(LPWSTR)restype,(LPWSTR)resid,&resdata,&reslen,&off);
			break;
		}
		LZClose32(lzfd);
		if (!res)
			return 0;
		if (reslen>datalen) reslen = datalen;
		memcpy(data,resdata,reslen);
		free(resdata);
		return reslen;
	}
	LZSeek32(lzfd,off,SEEK_SET);
	reslen = LZRead32(lzfd,data,datalen);
	LZClose32(lzfd);
	return reslen;
}

/* GetFileVersionInfoSize			[VER.6] */
DWORD WINAPI GetFileVersionInfoSize16(LPCSTR filename,LPDWORD handle)
{
	DWORD	len,ret,isuni=0;
	BYTE	buf[144];
	VS_FIXEDFILEINFO *vffi;

	dprintf_info(ver,"GetFileVersionInfoSize16(%s,%p)\n",filename,handle);
	len=GetFileResourceSize(filename,VS_FILE_INFO,VS_VERSION_INFO,handle);
	if (!len)
		return 0;
	ret=GetFileResource(
		filename,VS_FILE_INFO,VS_VERSION_INFO,*handle,sizeof(buf),buf
	);
	if (!ret)
		return 0;

	vffi=(VS_FIXEDFILEINFO*)(buf+0x14);
	if (vffi->dwSignature != VS_FFI_SIGNATURE) {
		/* unicode resource */
		if (vffi->dwSignature == 0x004f0049) {
			isuni = 1;
			vffi = (VS_FIXEDFILEINFO*)(buf+0x28);
		} else {
			fprintf(stderr,"vffi->dwSignature is 0x%08lx, but not 0x%08lx!\n",
				vffi->dwSignature,VS_FFI_SIGNATURE
			);
			return 0;
		}
	}
	if (*(WORD*)buf < len)
		len = *(WORD*)buf;

	if(debugging_info(ver))
	  print_vffi_debug(vffi);

	return len;
}

/* GetFileVersionInfoSize32A			[VERSION.1] */
DWORD WINAPI GetFileVersionInfoSize32A(LPCSTR filename,LPDWORD handle)
{
	dprintf_info(ver,"GetFileVersionInfoSize32A(%s,%p)\n",filename,handle);
	return GetFileVersionInfoSize16(filename,handle);
}

/* GetFileVersionInfoSize32W			[VERSION.2] */
DWORD WINAPI GetFileVersionInfoSize32W( LPCWSTR filename, LPDWORD handle )
{
    LPSTR xfn = HEAP_strdupWtoA( GetProcessHeap(), 0, filename );
    DWORD ret = GetFileVersionInfoSize16( xfn, handle );
    HeapFree( GetProcessHeap(), 0, xfn );
    return ret;
}

/* GetFileVersionInfo				[VER.7] */
DWORD  WINAPI GetFileVersionInfo16(LPCSTR filename,DWORD handle,DWORD datasize,
                                   LPVOID data)
{
	dprintf_info(ver,"GetFileVersionInfo16(%s,%ld,%ld,%p)\n",
		filename,handle,datasize,data
	);
	return GetFileResource(
		filename,VS_FILE_INFO,VS_VERSION_INFO,handle,datasize,data
	);
}

/* GetFileVersionInfoA				[VERSION.0] */
DWORD  WINAPI GetFileVersionInfo32A(LPCSTR filename,DWORD handle,
                                    DWORD datasize,LPVOID data)
{
	return GetFileVersionInfo16(filename,handle,datasize,data);
}

/* GetFileVersionInfoW				[VERSION.3] */
DWORD WINAPI GetFileVersionInfo32W( LPCWSTR filename, DWORD handle,
                                    DWORD datasize, LPVOID data)
{
    LPSTR fn = HEAP_strdupWtoA( GetProcessHeap(), 0, filename );
    DWORD ret = GetFileVersionInfo16( fn, handle, datasize, data );
    HeapFree( GetProcessHeap(), 0, fn );
    return ret;
}

/*****************************************************************************
 *
 *   VerFindFile() [VER.8]
 *   Determines where to install a file based on whether it locates another
 *   version of the file in the system.  The values VerFindFile returns are
 *   used in a subsequent call to the VerInstallFile function.
 *
 *   Revision history:
 *      30-May-1997   Dave Cuthbert (dacut@ece.cmu.edu)
 *         Reimplementation of VerFindFile from original stub.
 *
 ****************************************************************************/

DWORD WINAPI VerFindFile16(
    UINT16 flags,
    LPCSTR lpszFilename,
    LPCSTR lpszWinDir,
    LPCSTR lpszAppDir,
    LPSTR lpszCurDir,
    UINT16 *lpuCurDirLen,
    LPSTR lpszDestDir,
    UINT16 *lpuDestDirLen )
{
    DWORD  retval;
    char  curDir[256];
    char  destDir[256];
    unsigned int  curDirSizeReq;
    unsigned int  destDirSizeReq;

    retval = 0;

    /* Print out debugging information */
    dprintf_info(ver, "VerFindFile() called with parameters:\n"
		"\tflags = %x", flags);
    if(flags & VFFF_ISSHAREDFILE)
	dprintf_info(ver, " (VFFF_ISSHAREDFILE)\n");
    else
	dprintf_info(ver, "\n");

    ver_dstring("\tlpszFilename = ", lpszFilename, "");
    ver_dstring("\tlpszWinDir = ", lpszWinDir, "");
    ver_dstring("\tlpszAppDir = ", lpszAppDir, "");

    dprintf_info(ver, "\tlpszCurDir = %p\n", lpszCurDir);
    if(lpuCurDirLen)
	dprintf_info(ver, "\tlpuCurDirLen = %p (%u)\n",
		    lpuCurDirLen, *lpuCurDirLen);
    else
	dprintf_info(ver, "\tlpuCurDirLen = (null)\n");

    dprintf_info(ver, "\tlpszDestDir = %p\n", lpszDestDir);
    if(lpuDestDirLen)
	dprintf_info(ver, "\tlpuDestDirLen = %p (%u)\n",
		    lpuDestDirLen, *lpuDestDirLen);

    /* Figure out where the file should go; shared files default to the
       system directory */

    strcpy(curDir, "");
    strcpy(destDir, "");

    if(flags & VFFF_ISSHAREDFILE) {
	GetSystemDirectory32A(destDir, 256);

	/* Were we given a filename?  If so, try to find the file. */
	if(lpszFilename) {
	    if(testFileExistence(destDir, lpszFilename)) {
		strcpy(curDir, destDir);

		if(!testFileExclusiveExistence(destDir, lpszFilename))
		    retval |= VFF_FILEINUSE;
	    }
	    else if(lpszAppDir && testFileExistence(lpszAppDir,
						    lpszFilename)) {
		strcpy(curDir, lpszAppDir);
		retval |= VFF_CURNEDEST;

		if(!testFileExclusiveExistence(lpszAppDir, lpszFilename))
		    retval |= VFF_FILEINUSE;
	    }
	}
    }
    else if(!(flags & VFFF_ISSHAREDFILE)) { /* not a shared file */
	if(lpszAppDir) {
	    char  systemDir[256];
	    GetSystemDirectory32A(systemDir, 256);

	    strcpy(destDir, lpszAppDir);

	    if(lpszFilename) {
		if(testFileExistence(lpszAppDir, lpszFilename)) {
		    strcpy(curDir, lpszAppDir);

		    if(!testFileExclusiveExistence(lpszAppDir, lpszFilename))
			retval |= VFF_FILEINUSE;
		}
		else if(testFileExistence(systemDir, lpszFilename)) {
		    strcpy(curDir, systemDir);
		    retval |= VFF_CURNEDEST;

		    if(!testFileExclusiveExistence(systemDir, lpszFilename))
			retval |= VFF_FILEINUSE;
		}
	    }
	}
    }

    curDirSizeReq = strlen(curDir) + 1;
    destDirSizeReq = strlen(destDir) + 1;



    /* Make sure that the pointers to the size of the buffers are
       valid; if not, do NOTHING with that buffer.  If that pointer
       is valid, then make sure that the buffer pointer is valid, too! */

    if(lpuDestDirLen && lpszDestDir) {
	if(*lpuDestDirLen < destDirSizeReq) {
	    retval |= VFF_BUFFTOOSMALL;
	    strncpy(lpszDestDir, destDir, *lpuDestDirLen - 1);
	    lpszDestDir[*lpuDestDirLen - 1] = '\0';
	}
	else
	    strcpy(lpszDestDir, destDir);

	*lpuDestDirLen = destDirSizeReq;
    }
    
    if(lpuCurDirLen && lpszCurDir) {
	if(*lpuCurDirLen < curDirSizeReq) {
	    retval |= VFF_BUFFTOOSMALL;
	    strncpy(lpszCurDir, curDir, *lpuCurDirLen - 1);
	    lpszCurDir[*lpuCurDirLen - 1] = '\0';
	}
	else
	    strcpy(lpszCurDir, curDir);

	*lpuCurDirLen = curDirSizeReq;
    }

    dprintf_info(ver, "VerFindFile() ret = %lu (%s%s%s)\n", retval,
		(retval & VFF_CURNEDEST) ? "VFF_CURNEDEST " : "",
		(retval & VFF_FILEINUSE) ? "VFF_FILEINUSE " : "",
		(retval & VFF_BUFFTOOSMALL) ? "VFF_BUFFTOOSMALL " : "");

    ver_dstring("\t(Exit) lpszCurDir = ", lpszCurDir, "");
    if(lpuCurDirLen)
	dprintf_info(ver, "\t(Exit) lpuCurDirLen = %p (%u)\n",
		    lpuCurDirLen, *lpuCurDirLen);
    else
	dprintf_info(ver, "\t(Exit) lpuCurDirLen = (null)\n");

    ver_dstring("\t(Exit) lpszDestDir = ", lpszDestDir, "");
    if(lpuDestDirLen)
	dprintf_info(ver, "\t(Exit) lpuDestDirLen = %p (%u)\n",
		    lpuDestDirLen, *lpuDestDirLen);

    return retval;
}

/* VerFindFileA						[VERSION.5] */
DWORD WINAPI VerFindFile32A(
	UINT32 flags,LPCSTR filename,LPCSTR windir,LPCSTR appdir,
	LPSTR curdir,UINT32 *pcurdirlen,LPSTR destdir,UINT32 *pdestdirlen )
{
    UINT16 curdirlen, destdirlen;
    DWORD ret;
    
    curdirlen = (UINT16)*pcurdirlen;
    destdirlen= (UINT16)*pdestdirlen;

    ret = VerFindFile16(flags,filename,windir,appdir,
                        curdir,&curdirlen,destdir,&destdirlen);
    *pcurdirlen = curdirlen;
    *pdestdirlen = destdirlen;
    return ret;
}

/* VerFindFileW						[VERSION.6] */
DWORD WINAPI VerFindFile32W(
	UINT32 flags,LPCWSTR filename,LPCWSTR windir,LPCWSTR appdir,
	LPWSTR curdir,UINT32 *pcurdirlen,LPWSTR destdir,UINT32 *pdestdirlen )
{
    UINT16 curdirlen, destdirlen;
    LPSTR wfn,wwd,wad,wdd,wcd;
    DWORD ret;

    wfn = HEAP_strdupWtoA( GetProcessHeap(), 0, filename );
    wwd = HEAP_strdupWtoA( GetProcessHeap(), 0, windir );
    wad = HEAP_strdupWtoA( GetProcessHeap(), 0, appdir );
    wcd = HeapAlloc( GetProcessHeap(), 0, *pcurdirlen );
    wdd = HeapAlloc( GetProcessHeap(), 0, *pdestdirlen );
    ret = VerFindFile16(flags,wfn,wwd,wad,wcd,&curdirlen,wdd,&destdirlen);
    lstrcpynAtoW(curdir,wcd,*pcurdirlen);
    lstrcpynAtoW(destdir,wdd,*pdestdirlen);
    *pcurdirlen = strlen(wcd);
    *pdestdirlen = strlen(wdd);
    HeapFree( GetProcessHeap(), 0, wfn );
    HeapFree( GetProcessHeap(), 0, wwd );
    HeapFree( GetProcessHeap(), 0, wad );
    HeapFree( GetProcessHeap(), 0, wcd );
    HeapFree( GetProcessHeap(), 0, wdd );
    return ret;
}

/* VerInstallFile					[VER.9] */
DWORD WINAPI VerInstallFile16(
	UINT16 flags,LPCSTR srcfilename,LPCSTR destfilename,LPCSTR srcdir,
 	LPCSTR destdir,LPCSTR curdir,LPSTR tmpfile,UINT16 *tmpfilelen )
{
    UINT32	filelen;
    DWORD ret= VerInstallFile32A(flags,srcfilename,destfilename,srcdir,
                                 destdir,curdir,tmpfile,&filelen);

    *tmpfilelen = filelen;
    return ret;
}

/* VerInstallFileA				[VERSION.7] */
static LPBYTE
_fetch_versioninfo(LPSTR fn,VS_FIXEDFILEINFO **vffi) {
    DWORD	alloclen;
    LPBYTE	buf;
    DWORD	ret;

    alloclen = 1000;
    buf= xmalloc(alloclen);
    while (1) {
    	ret = GetFileVersionInfo32A(fn,0,alloclen,buf);
	if (!ret) {
	    free(buf);
	    return 0;
	}
	if (alloclen<*(WORD*)buf) {
	    free(buf);
	    alloclen = *(WORD*)buf;
	    buf = xmalloc(alloclen);
	} else {
	    *vffi = (VS_FIXEDFILEINFO*)(buf+0x14);
	    if ((*vffi)->dwSignature == 0x004f0049) /* hack to detect unicode */
	    	*vffi = (VS_FIXEDFILEINFO*)(buf+0x28);
	    if ((*vffi)->dwSignature != VS_FFI_SIGNATURE)
	    	fprintf(stderr,"_fetch_versioninfo:bad VS_FIXEDFILEINFO signature 0x%08lx\n",(*vffi)->dwSignature);
	    return buf;
	}
    }
}

static DWORD
_error2vif(DWORD error) {
    switch (error) {
    case ERROR_ACCESS_DENIED:
    	return VIF_ACCESSVIOLATION;
    case ERROR_SHARING_VIOLATION:
    	return VIF_SHARINGVIOLATION;
    default:
    	return 0;
    }
}

/* VerInstallFile32A
 */

DWORD WINAPI VerInstallFile32A(
	UINT32 flags,LPCSTR srcfilename,LPCSTR destfilename,LPCSTR srcdir,
 	LPCSTR destdir,LPCSTR curdir,LPSTR tmpfile,UINT32 *tmpfilelen )
{
    LPCSTR pdest;
    char	destfn[260],tmpfn[260],srcfn[260];
    HFILE32	hfsrc,hfdst;
    DWORD	attr,ret,xret,tmplast;
    LPBYTE	buf1,buf2;
    OFSTRUCT	ofs;

    fprintf(stddeb,"VerInstallFile(%x,%s,%s,%s,%s,%s,%p,%d)\n",
	    flags,srcfilename,destfilename,srcdir,destdir,curdir,tmpfile,*tmpfilelen
    );
    xret = 0;
    sprintf(srcfn,"%s\\%s",srcdir,srcfilename);
    if (!destdir || !*destdir) pdest = srcdir;
    else pdest = destdir;
    sprintf(destfn,"%s\\%s",pdest,destfilename);
    hfsrc=LZOpenFile32A(srcfn,&ofs,OF_READ);
    if (hfsrc==HFILE_ERROR32)
    	return VIF_CANNOTREADSRC;
    sprintf(tmpfn,"%s\\%s",pdest,destfilename);
    tmplast=strlen(pdest)+1;
    attr = GetFileAttributes32A(tmpfn);
    if (attr!=-1) {
	if (attr & FILE_ATTRIBUTE_READONLY) {
	    LZClose32(hfsrc);
	    return VIF_WRITEPROT;
	}
	/* FIXME: check if file currently in use and return VIF_FILEINUSE */
    }
    attr = -1;
    if (flags & VIFF_FORCEINSTALL) {
    	if (tmpfile[0]) {
	    sprintf(tmpfn,"%s\\%s",pdest,tmpfile);
	    tmplast = strlen(pdest)+1;
	    attr = GetFileAttributes32A(tmpfn);
	    /* if it exists, it has been copied by the call before.
	     * we jump over the copy part... 
	     */
	}
    }
    if (attr == -1) {
    	char	*s;

	GetTempFileName32A(pdest,"ver",0,tmpfn); /* should not fail ... */
	s=strrchr(tmpfn,'\\');
	if (s)
	    tmplast = s-tmpfn;
	else
	    tmplast = 0;
	hfdst = OpenFile32(tmpfn,&ofs,OF_CREATE);
	if (hfdst == HFILE_ERROR32) {
	    LZClose32(hfsrc);
	    return VIF_CANNOTCREATE; /* | translated dos error */
	}
	ret = LZCopy32(hfsrc,hfdst);
	_lclose32(hfdst);
	if (((long) ret) < 0) {
	    /* translate LZ errors into VIF_xxx */
	    switch (ret) {
	    case LZERROR_BADINHANDLE:
	    case LZERROR_READ:
	    case LZERROR_BADVALUE:
	    case LZERROR_UNKNOWNALG:
		ret = VIF_CANNOTREADSRC;
		break;
	    case LZERROR_BADOUTHANDLE:
	    case LZERROR_WRITE:
		ret = VIF_OUTOFMEMORY; /* FIXME: correct? */
		break;
	    case LZERROR_GLOBALLOC:
	    case LZERROR_GLOBLOCK:
		ret = VIF_OUTOFSPACE;
		break;
	    default: /* unknown error, should not happen */
		ret = 0;
		break;
	    }
	    if (ret) {
		LZClose32(hfsrc);
		return ret;
	    }
	}
    }
    xret = 0;
    if (!(flags & VIFF_FORCEINSTALL)) {
	VS_FIXEDFILEINFO *destvffi,*tmpvffi;
    	buf1 = _fetch_versioninfo(destfn,&destvffi);
	if (buf1) {
	    buf2 = _fetch_versioninfo(tmpfn,&tmpvffi);
	    if (buf2) {
	    	char	*tbuf1,*tbuf2;
		UINT32	len1,len2;

		len1=len2=40;

		/* compare file versions */
		if ((destvffi->dwFileVersionMS > tmpvffi->dwFileVersionMS)||
		    ((destvffi->dwFileVersionMS==tmpvffi->dwFileVersionMS)&&
		     (destvffi->dwFileVersionLS > tmpvffi->dwFileVersionLS)
		    )
		)
		    xret |= VIF_MISMATCH|VIF_SRCOLD;
		/* compare filetypes and filesubtypes */
		if ((destvffi->dwFileType!=tmpvffi->dwFileType) ||
		    (destvffi->dwFileSubtype!=tmpvffi->dwFileSubtype)
		)
		    xret |= VIF_MISMATCH|VIF_DIFFTYPE;
		if (VerQueryValue32A(buf1,"\\VarFileInfo\\Translation",(LPVOID*)&tbuf1,&len1) &&
		    VerQueryValue32A(buf2,"\\VarFileInfo\\Translation",(LPVOID*)&tbuf2,&len2)
		) {
		    /* irgendwas mit tbuf1 und tbuf2 machen 
		     * generiert DIFFLANG|MISMATCH
		     */
		}
		free(buf2);
	    } else
		xret=VIF_MISMATCH|VIF_SRCOLD;
	    free(buf1);
	}
    }
    if (xret) {
	if (*tmpfilelen<strlen(tmpfn+tmplast)) {
	    xret|=VIF_BUFTOSMALL;
	    DeleteFile32A(tmpfn);
	} else {
	    strcpy(tmpfile,tmpfn+tmplast);
	    *tmpfilelen = strlen(tmpfn+tmplast)+1;
	    xret|=VIF_TEMPFILE;
	}
    } else {
    	if (-1!=GetFileAttributes32A(destfn))
	    if (!DeleteFile32A(destfn)) {
		xret|=_error2vif(GetLastError())|VIF_CANNOTDELETE;
		DeleteFile32A(tmpfn);
		LZClose32(hfsrc);
		return xret;
	    }
	if ((!(flags & VIFF_DONTDELETEOLD))	&& 
	    curdir				&& 
	    *curdir				&&
	    lstrcmpi32A(curdir,pdest)
	) {
	    char curfn[260];

	    sprintf(curfn,"%s\\%s",curdir,destfilename);
	    if (-1!=GetFileAttributes32A(curfn)) {
		/* FIXME: check if in use ... if it is, VIF_CANNOTDELETECUR */
		if (!DeleteFile32A(curfn))
	    	    xret|=_error2vif(GetLastError())|VIF_CANNOTDELETECUR;
	    }
	}
	if (!MoveFile32A(tmpfn,destfn)) {
	    xret|=_error2vif(GetLastError())|VIF_CANNOTRENAME;
	    DeleteFile32A(tmpfn);
	}
    }
    LZClose32(hfsrc);
    return xret;
}

/* VerInstallFileW				[VERSION.8] */
DWORD WINAPI VerInstallFile32W(
	UINT32 flags,LPCWSTR srcfilename,LPCWSTR destfilename,LPCWSTR srcdir,
	LPCWSTR destdir,LPCWSTR curdir,LPWSTR tmpfile,UINT32 *tmpfilelen )
{
    LPSTR wsrcf,wsrcd,wdestf,wdestd,wtmpf,wcurd;
    DWORD ret;

    wsrcf  = HEAP_strdupWtoA( GetProcessHeap(), 0, srcfilename );
    wsrcd  = HEAP_strdupWtoA( GetProcessHeap(), 0, srcdir );
    wdestf = HEAP_strdupWtoA( GetProcessHeap(), 0, destfilename );
    wdestd = HEAP_strdupWtoA( GetProcessHeap(), 0, destdir );
    wtmpf  = HEAP_strdupWtoA( GetProcessHeap(), 0, tmpfile );
    wcurd  = HEAP_strdupWtoA( GetProcessHeap(), 0, curdir );
    ret = VerInstallFile32A(flags,wsrcf,wdestf,wsrcd,wdestd,wcurd,wtmpf,tmpfilelen);
    if (!ret)
    	lstrcpynAtoW(tmpfile,wtmpf,*tmpfilelen);
    HeapFree( GetProcessHeap(), 0, wsrcf );
    HeapFree( GetProcessHeap(), 0, wsrcd );
    HeapFree( GetProcessHeap(), 0, wdestf );
    HeapFree( GetProcessHeap(), 0, wdestd );
    HeapFree( GetProcessHeap(), 0, wtmpf );
    if (wcurd) 
    	HeapFree( GetProcessHeap(), 0, wcurd );
    return ret;
}


struct dbA {
	WORD	nextoff;
	WORD	datalen;
/* in memory structure... */
	char	name[1]; 	/* padded to dword alignment */
/* .... 
	char	data[datalen];     padded to dword alignment
	BYTE	subdirdata[];      until nextoff
 */
};

#define DATA_OFFSET_A(db) ((4+(strlen((db)->name)+4))&~3)

struct dbW {
	WORD	nextoff;
	WORD	datalen;
	WORD	btext;		/* type of data */
/* in memory structure... */
	WCHAR	name[1]; 	/* padded to dword alignment */
/* .... 
	WCHAR	data[datalen];     padded to dword alignment
	BYTE	subdirdata[];      until nextoff
 */
};

/* WORD nextoffset;
 * WORD datalength;
 * WORD btype;
 * WCHAR szKey[]; (zero terminated)
 * PADDING (round up to nearest 32bit boundary)
 */
#define DATA_OFFSET_W(db) ((2+2+2+((lstrlen32W((db)->name)+1)*2+3))&~3)

/* this one used for Win16 resources, which are always in ASCII format */
static BYTE*
_find_dataA(BYTE *block,LPCSTR str, int buff_remain) {
	char	*nextslash;
	int	substrlen, inc_size;
	struct	dbA	*db;

	while (*str && *str=='\\')
		str++;
	if (NULL!=(nextslash=strchr(str,'\\')))
		substrlen=nextslash-str;
	else
		substrlen=strlen(str);
	if (nextslash!=NULL) {
		while (*nextslash && *nextslash=='\\')
			nextslash++;
		if (!*nextslash)
			nextslash=NULL;
	} else if (*str == 0)
		return NULL;


	while (1) {
		db=(struct dbA*)block;
		dprintf_info(ver,"db=%p,db->nextoff=%d,db->datalen=%d,db->name=%s\n",
			db,db->nextoff,db->datalen,db->name
		);
		if ((!db->nextoff) || (buff_remain<=0)) /* no more entries ? */
			return NULL;

		dprintf_info(ver,"comparing with %s\n",db->name);
		if (!lstrncmpi32A(db->name,str,substrlen)) {
			if (nextslash) {
				inc_size=DATA_OFFSET_A(db)+((db->datalen+3)&~3);
				return _find_dataA(block+inc_size,nextslash,
							db->nextoff-inc_size);
			} else
				return block;
		}
		inc_size	 = ((db->nextoff+3)&~3);
		block		+= inc_size;
		buff_remain	-= inc_size;
	}
}

/* this one used for Win32 resources, which are always in UNICODE format */
extern LPWSTR __cdecl CRTDLL_wcschr(LPCWSTR str,WCHAR xchar);
static BYTE*
_find_dataW(BYTE *block,LPCWSTR str, int buff_remain) {
	LPWSTR	nextslash;
	int	substrlen, inc_size;
	struct	dbW	*db;


	while (*str && *str=='\\')
		str++;
	if (NULL!=(nextslash=CRTDLL_wcschr(str,'\\')))
		substrlen=nextslash-str;
	else
		substrlen=lstrlen32W(str);
	if (nextslash!=NULL) {
		while (*nextslash && *nextslash=='\\')
			nextslash++;
		if (!*nextslash)
			nextslash=NULL;
	} else if (*str == 0)
		return NULL;


	while (1) {
		char	*xs,*vs;
		db=(struct dbW*)block;
		xs= HEAP_strdupWtoA(GetProcessHeap(),0,db->name);
		if (db->datalen) {
			if (db->btext)
				vs = HEAP_strdupWtoA(GetProcessHeap(),0,(WCHAR*)((block+DATA_OFFSET_W(db))));
			else
				vs = HEAP_strdupA(GetProcessHeap(),0,"not a string");
		} else
			vs = HEAP_strdupA(GetProcessHeap(),0,"no data");

		dprintf_info(ver,"db->nextoff=%d,db->name=%s,db->data=\"%s\"\n",
			db->nextoff,xs,vs
		);
		HeapFree(GetProcessHeap(),0,vs);
		HeapFree(GetProcessHeap(),0,xs);
		if ((!db->nextoff) || (buff_remain<=0)) /* no more entries ? */
			return NULL;

		if (!lstrncmpi32W(db->name,str,substrlen)) {
			if (nextslash) {
				/* DATA_OFFSET_W(db) (padded to 32bit already)
				 * DATA[datalength]
				 * PADDING (round up to nearest 32bit boundary)
				 * -->	next level structs
				 */
				inc_size=DATA_OFFSET_W(db)+((db->datalen+3)&~3);
				return _find_dataW( block+inc_size ,nextslash,
							db->nextoff-inc_size);
			} else
				return block;
		}
		/* skip over this block, round up to nearest 32bit boundary */
		inc_size	=  ((db->nextoff+3)&~3);
		block		+= inc_size;
		buff_remain	-= inc_size;
	}
}

/* VerQueryValue 			[VER.11] */
/* take care, 'buffer' is NOT a SEGPTR, it just points to one */
DWORD WINAPI VerQueryValue16(SEGPTR segblock,LPCSTR subblock,SEGPTR *buffer,
                             UINT16 *buflen)
{
	LPSTR	s;
	BYTE	*block=PTR_SEG_TO_LIN(segblock),*b;

	dprintf_info(ver,"VerQueryValue16(%p,%s,%p,%d)\n",
		block,subblock,buffer,*buflen
	);

	s=(char*)xmalloc(strlen("VS_VERSION_INFO\\")+strlen(subblock)+1);
	strcpy(s,"VS_VERSION_INFO\\");strcat(s,subblock);
	/* check for UNICODE version */
	if (	(*(DWORD*)(block+0x14) != VS_FFI_SIGNATURE) && 
		(*(DWORD*)(block+0x28) == VS_FFI_SIGNATURE)
	) {
		struct	dbW	*db;
		LPWSTR	wstr;
		LPSTR	xs;

		wstr = HEAP_strdupAtoW(GetProcessHeap(),0,s);
		b=_find_dataW(block,wstr,*(WORD*)block);
		HeapFree(GetProcessHeap(),0,wstr);
		if (!b) {
			fprintf(stderr,"key %s not found in versionresource.\n",s);
			*buflen=0;
			free (s);
			return 0;
		}
		db=(struct dbW*)b;
		b	= b+DATA_OFFSET_W(db);
		*buflen	= db->datalen;
		if (db->btext) {
		    xs = HEAP_strdupWtoA(GetProcessHeap(),0,(WCHAR*)b);
		    dprintf_info(ver,"->%s\n",xs);
		    HeapFree(GetProcessHeap(),0,xs);
		} else
		    dprintf_info(ver,"->%p\n",b);
	} else {
		struct	dbA	*db;
		b=_find_dataA(block,s,*(WORD*)block);
		if (!b) {
			fprintf(stderr,"key %s not found in versionresource.\n",s);
			*buflen=0;
			free (s);
			return 0;
		}
		db=(struct dbA*)b;
		b	= b+DATA_OFFSET_A(db);
		*buflen	= db->datalen;
		/* the string is only printable, if it is below \\StringFileInfo*/
		if (!lstrncmpi32A("VS_VERSION_INFO\\StringFileInfo\\",s,strlen("VS_VERSION_INFO\\StringFileInfo\\")))
		    dprintf_info(ver,"	-> %s=%s\n",subblock,b);
		else
		    dprintf_info(ver,"	-> %s=%p\n",subblock,b);
	}
	*buffer	= (b-block)+segblock;
	free(s);
	return 1;
}

DWORD WINAPI VerQueryValue32A(LPVOID vblock,LPCSTR subblock,
                              LPVOID *vbuffer,UINT32 *buflen)
{
	BYTE	*b,*block=(LPBYTE)vblock,**buffer=(LPBYTE*)vbuffer;
	LPSTR	s;

	dprintf_info(ver,"VerQueryValue32A(%p,%s,%p,%d)\n",
		block,subblock,buffer,*buflen
	);

	s=(char*)xmalloc(strlen("VS_VERSION_INFO\\")+strlen(subblock)+1);
	strcpy(s,"VS_VERSION_INFO\\");strcat(s,subblock);

	/* check for UNICODE version */
	if (	(*(DWORD*)(block+0x14) != VS_FFI_SIGNATURE) && 
		(*(DWORD*)(block+0x28) == VS_FFI_SIGNATURE)
	) {
		LPWSTR	wstr;
		LPSTR	xs;
		struct	dbW	*db;

		wstr = HEAP_strdupAtoW(GetProcessHeap(),0,s);
		b=_find_dataW(block,wstr,*(WORD*)block);
		HeapFree(GetProcessHeap(),0,wstr);
		if (!b) {
			fprintf(stderr,"key %s not found in versionresource.\n",s);
			*buflen=0;
			free (s);
			return 0;
		}
		db	= (struct dbW*)b;
		*buflen	= db->datalen;
		b	= b+DATA_OFFSET_W(db);
		if (db->btext) {
		    xs = HEAP_strdupWtoA(GetProcessHeap(),0,(WCHAR*)b);
		    dprintf_info(ver,"->%s\n",xs);
		    HeapFree(GetProcessHeap(),0,xs);
		} else
		    dprintf_info(ver,"->%p\n",b);
		/* This is a leak.  */
		b = HEAP_strdupWtoA(GetProcessHeap(),0,(WCHAR*)b);
	} else {
		struct	dbA	*db;
		b=_find_dataA(block,s,*(WORD*)block);
		if (!b) {
			fprintf(stderr,"key %s not found in versionresource.\n",subblock);
			*buflen=0;
			free (s);
			return 0;
		}
		db=(struct dbA*)b;
		*buflen	= db->datalen;
		b	= b+DATA_OFFSET_A(db);

		/* the string is only printable, if it is below \\StringFileInfo*/
		if (!lstrncmpi32A("VS_VERSION_INFO\\StringFileInfo\\",s,strlen("VS_VERSION_INFO\\StringFileInfo\\")))
		    dprintf_info(ver,"	-> %s=%s\n",subblock,b);
		else
		    dprintf_info(ver,"	-> %s=%p\n",subblock,b);
	}
	*buffer	= b;
	free(s);
	return 1;
}

DWORD WINAPI VerQueryValue32W(LPVOID vblock,LPCWSTR subblock,LPVOID *vbuffer,
                              UINT32 *buflen)
{
	LPSTR		sb;
	DWORD		ret;

	sb = HEAP_strdupWtoA( GetProcessHeap(), 0, subblock );
	ret = VerQueryValue32A(vblock,sb,vbuffer,buflen);
        HeapFree( GetProcessHeap(), 0, sb );
	return 1;
}
/* 20 GETFILEVERSIONINFORAW */
