diff --git a/misc/Makefile.in b/misc/Makefile.in index 87aa9d079ce..0a0466ba332 100644 --- a/misc/Makefile.in +++ b/misc/Makefile.in @@ -31,7 +31,6 @@ C_SRCS = \ tapi32.c \ toolhelp.c \ tweak.c \ - ver.c \ version.c \ w32scomb.c \ w32skrnl.c \ diff --git a/misc/ver.c b/misc/ver.c deleted file mode 100644 index 592d7aa94ad..00000000000 --- a/misc/ver.c +++ /dev/null @@ -1,1470 +0,0 @@ -/* - * Implementation of VER.DLL - * - * Copyright 1996,1997 Marcus Meissner - * Copyright 1997 David Cuthbert - */ -#include -#include -#include -#include -#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=%u.%u, fileversion=%u.%u.%u.%u, productversion=%u.%u.%u.%u, flagmask=0x%lx, flags=%s%s%s%s%s%s\n", - HIWORD(vffi->dwStrucVersion),LOWORD(vffi->dwStrucVersion), - HIWORD(vffi->dwFileVersionMS),LOWORD(vffi->dwFileVersionMS), - HIWORD(vffi->dwFileVersionLS),LOWORD(vffi->dwFileVersionLS), - HIWORD(vffi->dwProductVersionMS),LOWORD(vffi->dwProductVersionMS), - HIWORD(vffi->dwProductVersionLS),LOWORD(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%x.0x%x ", - HIWORD(vffi->dwFileOS), - LOWORD(vffi->dwFileOS) - ); - 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 (LOWORD(vffi->dwFileOS)) { - 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%x)",LOWORD(vffi->dwFileOS));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;iSize; - *resdata= (LPBYTE)xmalloc(*reslen); - memcpy(*resdata,image+xresdata->OffsetToData,*reslen); - /* find physical address for virtual offset */ - for (i=0;iOffsetToData >= 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); - TRACE(ver,"-- found at off=%lu\n",*off); - 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,type=0x%lx,id=0x%lx,off=%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,type=0x%lx,id=0x%lx,off=%ld,len=%ld,date=%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); - TRACE(ver,"--[1] len=%u\n", reslen); - return reslen; - } - LZSeek32(lzfd,off,SEEK_SET); - reslen = LZRead32(lzfd,data,datalen); - LZClose32(lzfd); - TRACE(ver,"--[2] len=%u\n", reslen); - 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,size=%ld,data=%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 (*tmpfilelenname)+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 VER_VerQueryValueA(LPVOID,LPCSTR, LPVOID *,UINT32 *, BOOL32 *); - -DWORD WINAPI VER_VerQueryValueW(LPVOID vblock,LPCWSTR subblock, - LPVOID *vbuffer,UINT32 *buflen, BOOL32 * bIsString) -{ - BYTE *b,*block=(LPBYTE)vblock,**buffer=(LPBYTE*)vbuffer; - - TRACE(ver,"(%p,%s,%p,%d)\n", - block,debugstr_w(subblock),buffer,*buflen - ); - - /* check for UNICODE version */ - if ( (*(DWORD*)(block+0x14) != VS_FFI_SIGNATURE) && - (*(DWORD*)(block+0x28) == VS_FFI_SIGNATURE) - ) { - struct dbW *db; - LPWSTR s; - LPWSTR vs_version_info = HEAP_strdupAtoW (GetProcessHeap(),0,"VS_VERSION_INFO\\"); - s=(LPWSTR)xmalloc(2*lstrlen32W(vs_version_info)+2*lstrlen32W(subblock)+2); - lstrcpy32W(s,vs_version_info); - lstrcat32W(s,subblock); - - - b=_find_dataW(block,s,*(WORD*)block); - if (!b) { - WARN(ver,"key %s not found in versionresource.\n",debugstr_w(s)); - *buflen=0; - free (s); - return 0; - } - db = (struct dbW*)b; - *buflen = db->datalen; - b = b+DATA_OFFSET_W(db); - if (db->btext) { - TRACE(ver,"%s->%s\n",debugstr_w(subblock), debugstr_w((LPWSTR)b)); - if (bIsString) *bIsString = TRUE; - } else - TRACE(ver,"%s->%p\n",debugstr_w(subblock),b); - free (s); - *buffer = b; - } else { - BOOL32 bMyIsString = FALSE, ret; - LPSTR subblock_a; - - if (!bIsString) return FALSE; - - subblock_a = HEAP_strdupWtoA (GetProcessHeap(),0,subblock); - ret = VER_VerQueryValueA( vblock, subblock_a, vbuffer, buflen, &bMyIsString); - free (subblock_a); - - if (bMyIsString) - { /* This is a leak. */ - *buffer = (LPBYTE) HEAP_strdupAtoW(GetProcessHeap(),0,*buffer); - } - return ret; - } - return 1; -} -DWORD WINAPI VER_VerQueryValueA(LPVOID vblock,LPCSTR subblock, - LPVOID *vbuffer,UINT32 *buflen, BOOL32 * bIsString) -{ BYTE *b,*block=(LPBYTE)vblock,**buffer=(LPBYTE*)vbuffer; - - TRACE(ver,"(%p,%s,%p,%d)\n", - block,subblock,buffer,*buflen - ); - - /* check for UNICODE version */ - if ( (*(DWORD*)(block+0x14) != VS_FFI_SIGNATURE) && - (*(DWORD*)(block+0x28) == VS_FFI_SIGNATURE) - ) { - BOOL32 bMyIsString = FALSE, ret; - LPWSTR subblock_w; - - if (!bIsString) return FALSE; - - subblock_w = HEAP_strdupAtoW (GetProcessHeap(),0,subblock); - ret = VER_VerQueryValueW( vblock, subblock_w, vbuffer, buflen, &bMyIsString); - free (subblock_w); - - if (bMyIsString) - { /* This is a leak. */ - *buffer = (LPBYTE)HEAP_strdupWtoA(GetProcessHeap(),0,(LPWSTR) *buffer); - } - return ret; - } else { - struct dbA *db; - LPSTR s; - s=(char*)xmalloc(strlen("VS_VERSION_INFO\\")+strlen(subblock)+1); - strcpy(s,"VS_VERSION_INFO\\");strcat(s,subblock); - - 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); - if (bIsString) *bIsString = TRUE; - } else - TRACE(ver,"%s->%p\n",subblock,b); - free(s); - *buffer = b; - } - return TRUE; - -} -DWORD WINAPI VerQueryValue32A(LPVOID vblock,LPCSTR subblock, - LPVOID *vbuffer,UINT32 *buflen) -{ return VER_VerQueryValueA(vblock,subblock, vbuffer,buflen, NULL); -} - -DWORD WINAPI VerQueryValue32W(LPVOID vblock,LPCWSTR subblock,LPVOID *vbuffer, - UINT32 *buflen) -{ return VER_VerQueryValueW(vblock,subblock, vbuffer,buflen, NULL); -}