/* 
 * Implementation of VER.DLL
 * 
 * Copyright 1996,1997 Marcus Meissner
 * Copyright 1997 David Cuthbert
 */
#include <stdlib.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 )
{
    TRACE(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);

	TRACE(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;
	}
	TRACE(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;
	}
	TRACE(ver, "%s\n", dbg_str(ver));

	TRACE(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';
	WARN(ver,"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) {
		TRACE(ver,"no resources in NE dll\n");
		return 0;
	}
	LZSeek32(lzfd,nehd.resource_tab_offset+nehdoffset,SEEK_SET);
	LZREAD(&shiftcount);
	TRACE(ver,"shiftcount is %d\n",shiftcount);
	TRACE(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;
		TRACE(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;
				TRACE(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);
			TRACE(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;
					TRACE(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;
			}
			TRACE(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];
	TRACE(ver,"(.,%p,%p,....)\n",typeid,resid);
	if (!resdir.Size) {
		WARN(ver,"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)
		) {
			HeapFree(GetProcessHeap(),0,image);
			return 0;
		}
	}
	resourcedir = (LPIMAGE_RESOURCE_DIRECTORY)(image+resdir.VirtualAddress);
	xresdir = GetResDirEntryW(resourcedir,typeid,(DWORD)resourcedir,FALSE);
	if (!xresdir) {
		TRACE(ver,"...no typeid entry found for %p\n",typeid);
		HeapFree(GetProcessHeap(),0,image);
		return 0;
	}
	xresdir = GetResDirEntryW(xresdir,resid,(DWORD)resourcedir,FALSE);
	if (!xresdir) {
		TRACE(ver,"...no resid entry found for %p\n",resid);
		HeapFree(GetProcessHeap(),0,image);
		return 0;
	}
	
	xresdir = GetResDirEntryW(xresdir,0,(DWORD)resourcedir,TRUE);
	if (!xresdir) {
		TRACE(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;

	TRACE(ver,"(%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;

	TRACE(ver,"(%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;

	TRACE(ver,"(%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 {
			WARN(ver,"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(TRACE_ON(ver))
	  print_vffi_debug(vffi);

	return len;
}

/* GetFileVersionInfoSize32A			[VERSION.1] */
DWORD WINAPI GetFileVersionInfoSize32A(LPCSTR filename,LPDWORD handle)
{
	TRACE(ver,"(%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)
{
	TRACE(ver,"(%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 */
    TRACE(ver, "called with parameters:\n"
		 "\tflags = %x", flags);
    if(flags & VFFF_ISSHAREDFILE)
	TRACE(ver, " (VFFF_ISSHAREDFILE)\n");
    else
	TRACE(ver, "\n");

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

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

    TRACE(ver, "\tlpszDestDir = %p\n", lpszDestDir);
    if(lpuDestDirLen)
	TRACE(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;
    }

    TRACE(ver, "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)
	TRACE(ver, "\t(Exit) lpuCurDirLen = %p (%u)\n",
		    lpuCurDirLen, *lpuCurDirLen);
    else
	TRACE(ver, "\t(Exit) lpuCurDirLen = (null)\n");

    ver_dstring("\t(Exit) lpszDestDir = ", lpszDestDir, "");
    if(lpuDestDirLen)
	TRACE(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;
}

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)
	    	WARN(ver,"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 [VERSION.7]
 */
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;

    TRACE(ver,"(%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;
		TRACE(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;

		TRACE(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");

		TRACE(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;

	TRACE(ver,"(%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) {
			WARN(ver,"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);
		    TRACE(ver,"->%s\n",xs);
		    HeapFree(GetProcessHeap(),0,xs);
		} else
		    TRACE(ver,"->%p\n",b);
	} else {
		struct	dbA	*db;
		b=_find_dataA(block,s,*(WORD*)block);
		if (!b) {
			WARN(ver,"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\\")))
		    TRACE(ver,"	-> %s=%s\n",subblock,b);
		else
		    TRACE(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;

	TRACE(ver,"(%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) {
			WARN(ver,"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);
		    TRACE(ver,"->%s\n",xs);
		    HeapFree(GetProcessHeap(),0,xs);
		} else
		    TRACE(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) {
			WARN(ver,"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\\")))
		    TRACE(ver,"	-> %s=%s\n",subblock,b);
		else
		    TRACE(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 */
