Changeset 2347 for trunk/src/version/version.cpp
- Timestamp:
- Jan 6, 2000, 9:10:07 PM (26 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/version/version.cpp
r1422 r2347 1 /* $Id: version.cpp,v 1. 8 1999-10-23 23:01:53sandervl Exp $ */1 /* $Id: version.cpp,v 1.9 2000-01-06 20:10:07 sandervl Exp $ */ 2 2 3 3 /* … … 22 22 #include <heapstring.h> 23 23 #include <version.h> 24 #include <lzexpand.h>25 #include <win\winreg.h>26 27 24 28 25 ODINDEBUGCHANNEL(VERSION) 29 26 30 /***************************************************************************** 31 * Name : 32 * Purpose : 33 * Parameters: 34 * Variables : 35 * Result : 36 * Remark : 37 * Status : UNTESTED STUB 38 * 39 * Author : Patrick Haller [Tue, 1998/06/16 23:00] 40 *****************************************************************************/ 41 42 VS_VERSION_INFO_STRUCT16 *VersionInfo16_FindChild(VS_VERSION_INFO_STRUCT16 *info, 43 LPCSTR szKey, 44 UINT cbKey ) 45 { 46 VS_VERSION_INFO_STRUCT16 *child = VersionInfo16_Children( info ); 47 48 while ( (DWORD)child < (DWORD)info + info->wLength ) 49 { 50 if ( !strnicmp( child->szKey, szKey, cbKey ) ) 51 return child; 52 53 if (!(child->wLength)) return NULL; 54 child = VersionInfo16_Next( child ); 55 } 56 57 return NULL; 58 } 59 60 61 /***************************************************************************** 62 * Name : 63 * Purpose : 64 * Parameters: 65 * Variables : 66 * Result : 67 * Remark : 68 * Status : UNTESTED STUB 69 * 70 * Author : Patrick Haller [Tue, 1998/06/16 23:00] 71 *****************************************************************************/ 72 73 VS_VERSION_INFO_STRUCT32 *VersionInfo32_FindChild(VS_VERSION_INFO_STRUCT32 *info, 74 LPCWSTR szKey, 75 UINT cbKey ) 76 { 77 VS_VERSION_INFO_STRUCT32 *child = VersionInfo32_Children( info ); 78 79 while ( (DWORD)child < (DWORD)info + info->wLength ) 80 { 81 if ( !lstrcmpniW( child->szKey, szKey, cbKey ) ) 82 return child; 83 84 child = VersionInfo32_Next( child ); 85 } 86 87 return NULL; 88 } 89 90 91 /****************************************************************************** 92 * 93 * void ver_dstring( 94 * char const * prologue, 95 * char const * teststring, 96 * char const * epilogue ) 97 * 98 * This function will print via dprintf[_]ver to stddeb the prologue string, 99 * followed by the address of teststring and the string it contains if 100 * teststring is non-null or "(null)" otherwise, and then the epilogue 101 * string followed by a new line. 102 * 103 * Revision history 104 * 30-May-1997 Dave Cuthbert (dacut@ece.cmu.edu) 105 * Original implementation as dprintf[_]ver_string 106 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu) 107 * Fixed problem that caused bug with tools/make_debug -- renaming 108 * this function should fix the problem. 109 * 15-Feb-1998 Dimitrie Paun (dimi@cs.toronto.edu) 110 * Modified it to make it print the message using only one 111 * dprintf[_]ver call. 112 * 113 *****************************************************************************/ 114 115 static void ver_dstring(char const * prologue, 116 char const * teststring, 117 char const * epilogue ) 118 { 119 dprintf(("VERSION: ver_dstring(%s, %s, %s)\n", 120 prologue, 121 teststring, 122 epilogue)); 123 } 124 125 126 /****************************************************************************** 127 * 128 * int testFileExistence( 129 * char const * path, 130 * char const * file ) 131 * 132 * Tests whether a given path/file combination exists. If the file does 133 * not exist, the return value is zero. If it does exist, the return 134 * value is non-zero. 135 * 136 * Revision history 137 * 30-May-1997 Dave Cuthbert (dacut@ece.cmu.edu) 138 * Original implementation 139 * 140 *****************************************************************************/ 141 142 static int testFileExistence(char const * path, 143 char const * file ) 144 { 145 char filename[1024]; 146 int filenamelen; 147 OFSTRUCT fileinfo; 148 int retval; 149 150 fileinfo.cBytes = sizeof(OFSTRUCT); 151 152 strcpy(filename, path); 153 filenamelen = strlen(filename); 154 155 /* Add a trailing \ if necessary */ 156 if(filenamelen) 157 { 158 if(filename[filenamelen - 1] != '\\') 159 strcat(filename, "\\"); 160 } 161 else /* specify the current directory */ 162 strcpy(filename, ".\\"); 163 164 /* Create the full pathname */ 165 strcat(filename, file); 166 167 if(OpenFile(filename, &fileinfo, OF_EXIST) == HFILE_ERROR) 168 retval = 0; 169 else 170 retval = 1; 171 172 return retval; 173 } 174 175 176 /****************************************************************************** 177 * 178 * int testFileExclusiveExistence( 179 * char const * path, 180 * char const * file ) 181 * 182 * Tests whether a given path/file combination exists and ensures that no 183 * other programs have handles to the given file. If the file does not 184 * exist or is open, the return value is zero. If it does exist, the 185 * return value is non-zero. 186 * 187 * Revision history 188 * 30-May-1997 Dave Cuthbert (dacut@ece.cmu.edu) 189 * Original implementation 190 * 191 *****************************************************************************/ 192 193 static int testFileExclusiveExistence(char const * path, 194 char const * file ) 195 { 196 char filename[1024]; 197 int filenamelen; 198 OFSTRUCT fileinfo; 199 int retval; 200 201 fileinfo.cBytes = sizeof(OFSTRUCT); 202 203 strcpy(filename, path); 204 filenamelen = strlen(filename); 205 206 /* Add a trailing \ if necessary */ 207 if(filenamelen) 208 { 209 if(filename[filenamelen - 1] != '\\') 210 strcat(filename, "\\"); 211 } 212 else /* specify the current directory */ 213 strcpy(filename, ".\\"); 214 215 /* Create the full pathname */ 216 strcat(filename, file); 217 218 if(OpenFile(filename, 219 &fileinfo, 220 OF_EXIST | OF_SHARE_EXCLUSIVE) == HFILE_ERROR) 221 retval = 0; 222 else 223 retval = 1; 224 225 return retval; 226 } 227 228 229 static LPBYTE _fetch_versioninfo(LPSTR fn,VS_FIXEDFILEINFO **vffi) 230 { 231 DWORD alloclen; 232 LPBYTE buf; 233 DWORD ret; 234 235 alloclen = 1000; 236 buf = (LPBYTE)malloc(alloclen); 237 238 while (1) 239 { 240 ret = GetFileVersionInfoA(fn, 241 0, 242 alloclen, 243 buf); 244 if (!ret) 245 { 246 free(buf); 247 return 0; 248 } 249 250 if (alloclen<*(WORD*)buf) 251 { 252 free(buf); 253 alloclen = *(WORD*)buf; 254 buf = (LPBYTE)malloc(alloclen); 255 } 256 else 257 { 258 *vffi = (VS_FIXEDFILEINFO*)(buf+0x14); 259 260 if ((*vffi)->dwSignature == 0x004f0049) /* hack to detect unicode */ 261 *vffi = (VS_FIXEDFILEINFO*)(buf+0x28); 262 263 if ((*vffi)->dwSignature != VS_FFI_SIGNATURE) 264 dprintf(("VERSION: _fetch_versioninfo: Bad VS_FIXEDFILEINFO signature 0x%08lx\n", 265 (*vffi)->dwSignature)); 266 267 return buf; 268 } 269 } 270 } 271 272 static DWORD _error2vif(DWORD error) 273 { 274 switch (error) 275 { 276 case ERROR_ACCESS_DENIED: 277 return VIF_ACCESSVIOLATION; 278 279 case ERROR_SHARING_VIOLATION: 280 return VIF_SHARINGVIOLATION; 281 282 default: 283 return 0; 284 } 285 } 286 287 288 289 /***************************************************************************** 290 * Name : 291 * Purpose : 292 * Parameters: 293 * Variables : 294 * Result : 295 * Remark : 296 * Status : UNTESTED STUB 297 * 298 * Author : Patrick Haller [Tue, 1998/06/16 23:00] 299 *****************************************************************************/ 300 301 ODINFUNCTION4(BOOL,GetFileVersionInfoA,LPSTR, lpszFile, 302 DWORD, dwHandle, 303 DWORD, cbBuf, 304 LPVOID,lpvData) 27 BOOL GetFileVersionInfoA(LPSTR lpszFile, DWORD dwHandle, DWORD cbBuf, LPVOID lpvData) 305 28 { 306 29 return GetVersionStruct((char *)lpszFile, … … 309 32 } 310 33 311 312 /***************************************************************************** 313 * Name : 314 * Purpose : 315 * Parameters: 316 * Variables : 317 * Result : 318 * Remark : 319 * Status : UNTESTED STUB 320 * 321 * Author : Patrick Haller [Tue, 1998/06/16 23:00] 322 *****************************************************************************/ 323 324 ODINFUNCTION4(BOOL,GetFileVersionInfoW,LPWSTR, lpszFile, 325 DWORD, dwHandle, 326 DWORD, cbBuf, 327 LPVOID, lpvData) 34 BOOL GetFileVersionInfoW(LPWSTR lpszFile, DWORD dwHandle, DWORD cbBuf, LPVOID lpvData) 328 35 { 329 36 BOOL rc; … … 335 42 } 336 43 337 338 /***************************************************************************** 339 * Name : 340 * Purpose : 341 * Parameters: 342 * Variables : 343 * Result : 344 * Remark : 345 * Status : UNTESTED STUB 346 * 347 * Author : Patrick Haller [Tue, 1998/06/16 23:00] 348 *****************************************************************************/ 349 350 ODINFUNCTION2(DWORD,GetFileVersionInfoSizeA,LPSTR, lpszFile, 351 LPDWORD, lpdwHandle) 44 DWORD GetFileVersionInfoSizeA(LPSTR lpszFile, LPDWORD lpdwHandle) 352 45 { 353 46 if(lpdwHandle) … … 358 51 359 52 360 /***************************************************************************** 361 * Name : 362 * Purpose : 363 * Parameters: 364 * Variables : 365 * Result : 366 * Remark : 367 * Status : UNTESTED STUB 368 * 369 * Author : Patrick Haller [Tue, 1998/06/16 23:00] 370 *****************************************************************************/ 371 372 ODINFUNCTION2(DWORD,GetFileVersionInfoSizeW,LPWSTR, lpszFile, 373 LPDWORD, lpdwHandle) 53 DWORD GetFileVersionInfoSizeW(LPWSTR lpszFile, LPDWORD lpdwHandle) 374 54 { 375 55 char *astring = UnicodeToAsciiString((LPWSTR)lpszFile); 376 56 DWORD rc; 377 378 57 379 58 if(lpdwHandle) … … 387 66 388 67 389 /*****************************************************************************390 * Name :391 * Purpose :392 * Parameters:393 * Variables :394 * Result :395 * Remark :396 * Status : UNTESTED STUB397 *398 * Author : Patrick Haller [Tue, 1998/06/16 23:00]399 *****************************************************************************/400 401 ODINFUNCTION4(BOOL,VerQueryValueW, LPVOID, pBlock,402 LPWSTR, lpSubBlock,403 LPVOID*, lplpBuffer,404 UINT*, puLen)405 {406 VS_VERSION_INFO_STRUCT32 *info = (VS_VERSION_INFO_STRUCT32 *)pBlock;407 if ( VersionInfoIs16( info ) )408 {409 dprintf(("VERSION: called on NE resource!\n"));410 return FALSE;411 }412 413 while ( *lpSubBlock )414 {415 /* Find next path component */416 LPCWSTR lpNextSlash;417 for ( lpNextSlash = lpSubBlock; *lpNextSlash; lpNextSlash++ )418 if ( *lpNextSlash == '\\' )419 break;420 421 /* Skip empty components */422 if ( lpNextSlash == lpSubBlock )423 {424 lpSubBlock++;425 continue;426 }427 428 /* We have a non-empty component: search info for key */429 info = VersionInfo32_FindChild( info, lpSubBlock, lpNextSlash-lpSubBlock );430 if ( !info )431 return FALSE;432 433 /* Skip path component */434 lpSubBlock = (LPWSTR)lpNextSlash;435 }436 437 /* Return value */438 *lplpBuffer = VersionInfo32_Value( info );439 *puLen = info->wValueLength;440 441 return TRUE;442 }443 444 445 /*****************************************************************************446 * Name :447 * Purpose :448 * Parameters:449 * Variables :450 * Result :451 * Remark :452 * Status : UNTESTED STUB453 *454 * Author : Patrick Haller [Tue, 1998/06/16 23:00]455 *****************************************************************************/456 457 ODINFUNCTION4(BOOL,VerQueryValueA,LPVOID, pBlock,458 LPSTR, lpSubBlock,459 LPVOID*, lplpBuffer,460 UINT*, puLen )461 {462 VS_VERSION_INFO_STRUCT16 *info = (VS_VERSION_INFO_STRUCT16 *)pBlock;463 if ( !VersionInfoIs16( info ) )464 {465 // this is a quick hack, not much tested466 WCHAR *ustring = (WCHAR *)malloc(strlen((char *)lpSubBlock)*2+2);467 LPVOID ubuffer;468 char *abuffer;469 UINT len = *puLen * 2;470 BOOL rc;471 472 dprintf(("VERSION: called on PE unicode resource!\n" ));473 474 AsciiToUnicode((char *)lpSubBlock, ustring);475 rc = VerQueryValueW( pBlock, (LPWSTR)ustring, &ubuffer, &len);476 if(rc == 0) {477 free(ustring);478 return 0;479 }480 if(lpSubBlock[0] == '\\' && lpSubBlock[1] == 0)481 *lplpBuffer = ubuffer;482 else483 {484 *lplpBuffer = malloc(len+1); // no free, memory leak485 UnicodeToAsciiN((WCHAR *)ubuffer, (char *)*lplpBuffer, len);486 }487 *puLen = len;488 free(ustring);489 return rc;490 }491 492 while ( *lpSubBlock )493 {494 /* Find next path component */495 LPCSTR lpNextSlash;496 for ( lpNextSlash = lpSubBlock; *lpNextSlash; lpNextSlash++ )497 if ( *lpNextSlash == '\\' )498 break;499 500 /* Skip empty components */501 if ( lpNextSlash == lpSubBlock )502 {503 lpSubBlock++;504 continue;505 }506 507 /* We have a non-empty component: search info for key */508 info = VersionInfo16_FindChild( info, lpSubBlock, lpNextSlash-lpSubBlock );509 if ( !info ) return FALSE;510 511 /* Skip path component */512 lpSubBlock = (LPSTR)lpNextSlash;513 }514 515 /* Return value */516 *lplpBuffer = VersionInfo16_Value( info );517 *puLen = info->wValueLength;518 519 return TRUE;520 }521 522 523 524 525 /*****************************************************************************526 *527 * VerFindFile() [VER.8]528 * Determines where to install a file based on whether it locates another529 * version of the file in the system. The values VerFindFile returns are530 * used in a subsequent call to the VerInstallFile function.531 *532 * Revision history:533 * 30-May-1997 Dave Cuthbert (dacut@ece.cmu.edu)534 * Reimplementation of VerFindFile from original stub.535 *536 ****************************************************************************/537 538 ODINFUNCTION8(DWORD,VerFindFileA,DWORD, flags,539 LPSTR, lpszFilename,540 LPSTR, lpszWinDir,541 LPSTR, lpszAppDir,542 LPSTR, lpszCurDir,543 PUINT, lpuCurDirLen,544 LPSTR, lpszDestDir,545 PUINT, lpuDestDirLen )546 {547 DWORD retval;548 char curDir[256];549 char destDir[256];550 unsigned int curDirSizeReq;551 unsigned int destDirSizeReq;552 553 retval = 0;554 555 ver_dstring("\tlpszFilename = ", lpszFilename, "");556 ver_dstring("\tlpszWinDir = ", lpszWinDir, "");557 ver_dstring("\tlpszAppDir = ", lpszAppDir, "");558 559 /* Figure out where the file should go; shared files default to the560 system directory */561 562 strcpy(curDir, "");563 strcpy(destDir, "");564 565 if(flags & VFFF_ISSHAREDFILE)566 {567 GetSystemDirectoryA(destDir, 256);568 569 /* Were we given a filename? If so, try to find the file. */570 if(lpszFilename)571 {572 if(testFileExistence(destDir, lpszFilename))573 {574 strcpy(curDir, destDir);575 576 if(!testFileExclusiveExistence(destDir, lpszFilename))577 retval |= VFF_FILEINUSE;578 }579 else580 if(lpszAppDir && testFileExistence(lpszAppDir,581 lpszFilename))582 {583 strcpy(curDir, lpszAppDir);584 retval |= VFF_CURNEDEST;585 586 if(!testFileExclusiveExistence(lpszAppDir, lpszFilename))587 retval |= VFF_FILEINUSE;588 }589 }590 }591 else592 if(!(flags & VFFF_ISSHAREDFILE))593 { /* not a shared file */594 if(lpszAppDir)595 {596 char systemDir[256];597 GetSystemDirectoryA(systemDir, 256);598 599 strcpy(destDir, lpszAppDir);600 601 if(lpszFilename)602 {603 if(testFileExistence(lpszAppDir, lpszFilename))604 {605 strcpy(curDir, lpszAppDir);606 607 if(!testFileExclusiveExistence(lpszAppDir, lpszFilename))608 retval |= VFF_FILEINUSE;609 }610 else611 if(testFileExistence(systemDir, lpszFilename))612 {613 strcpy(curDir, systemDir);614 retval |= VFF_CURNEDEST;615 616 if(!testFileExclusiveExistence(systemDir, lpszFilename))617 retval |= VFF_FILEINUSE;618 }619 }620 }621 }622 623 curDirSizeReq = strlen(curDir) + 1;624 destDirSizeReq = strlen(destDir) + 1;625 626 627 628 /* Make sure that the pointers to the size of the buffers are629 valid; if not, do NOTHING with that buffer. If that pointer630 is valid, then make sure that the buffer pointer is valid, too! */631 632 if(lpuDestDirLen && lpszDestDir)633 {634 if(*lpuDestDirLen < destDirSizeReq)635 {636 retval |= VFF_BUFFTOOSMALL;637 if (*lpuDestDirLen)638 {639 strncpy(lpszDestDir, destDir, *lpuDestDirLen - 1);640 lpszDestDir[*lpuDestDirLen - 1] = '\0';641 }642 }643 else644 strcpy(lpszDestDir, destDir);645 646 *lpuDestDirLen = destDirSizeReq;647 }648 649 if(lpuCurDirLen && lpszCurDir)650 {651 if(*lpuCurDirLen < curDirSizeReq)652 {653 retval |= VFF_BUFFTOOSMALL;654 if (*lpuCurDirLen)655 {656 strncpy(lpszCurDir, curDir, *lpuCurDirLen - 1);657 lpszCurDir[*lpuCurDirLen - 1] = '\0';658 }659 }660 else661 strcpy(lpszCurDir, curDir);662 663 *lpuCurDirLen = curDirSizeReq;664 }665 666 dprintf(("VERSION: VerFindFileA ret = %lu (%s%s%s)\n", retval,667 (retval & VFF_CURNEDEST) ? "VFF_CURNEDEST " : "",668 (retval & VFF_FILEINUSE) ? "VFF_FILEINUSE " : "",669 (retval & VFF_BUFFTOOSMALL) ? "VFF_BUFFTOOSMALL " : ""));670 671 ver_dstring("\t(Exit) lpszCurDir = ", lpszCurDir, "");672 673 return retval;674 }675 676 677 /*****************************************************************************678 * Name :679 * Purpose :680 * Parameters:681 * Variables :682 * Result :683 * Remark :684 * Status : UNTESTED STUB685 *686 * Author : Patrick Haller [Tue, 1998/06/16 23:00]687 *****************************************************************************/688 689 ODINFUNCTION8(DWORD,VerFindFileW,DWORD, flags,690 LPWSTR, lpszFilename,691 LPWSTR, lpszWinDir,692 LPWSTR, lpszAppDir,693 LPWSTR, lpszCurDir,694 PUINT, lpuCurDirLen,695 LPWSTR, lpszDestDir,696 PUINT, lpuDestDirLen )697 {698 UINT curdirlen,699 destdirlen;700 LPSTR wfn,701 wwd,702 wad,703 wdd,704 wcd;705 DWORD ret;706 707 wfn = UnicodeToAsciiString(lpszFilename );708 wwd = UnicodeToAsciiString(lpszWinDir );709 wad = UnicodeToAsciiString(lpszAppDir );710 wcd = (LPSTR)HeapAlloc( GetProcessHeap(), 0, *lpuCurDirLen );711 wdd = (LPSTR)HeapAlloc( GetProcessHeap(), 0, *lpuDestDirLen );712 713 ret = VerFindFileA(flags,714 wfn,715 wwd,716 wad,717 wcd,718 &curdirlen,719 wdd,720 &destdirlen);721 722 AsciiToUnicodeN(wcd,lpszCurDir,*lpuCurDirLen);723 AsciiToUnicodeN(wdd,lpszDestDir,*lpuDestDirLen);724 *lpuCurDirLen = strlen(wcd);725 *lpuDestDirLen = strlen(wdd);726 727 FreeAsciiString(wfn );728 FreeAsciiString(wwd );729 FreeAsciiString(wad );730 FreeAsciiString(wcd );731 FreeAsciiString(wdd );732 return ret;733 }734 735 736 /*****************************************************************************737 * Name :738 * Purpose :739 * Parameters:740 * Variables :741 * Result :742 * Remark :743 * Status : UNTESTED STUB744 *745 * Author : Patrick Haller [Tue, 1998/06/16 23:00]746 *****************************************************************************/747 748 ODINFUNCTION8(DWORD,VerInstallFileA,DWORD, flags,749 LPSTR, srcfilename,750 LPSTR, destfilename,751 LPSTR, srcdir,752 LPSTR, destdir,753 LPSTR, curdir,754 LPSTR, tmpfile,755 PUINT, tmpfilelen )756 {757 LPCSTR pdest;758 char destfn[260],759 tmpfn[260],760 srcfn[260];761 HFILE hfsrc,762 hfdst;763 DWORD attr,764 ret,765 xret,766 tmplast;767 LPBYTE buf1,buf2;768 OFSTRUCT ofs;769 770 771 xret = 0;772 773 sprintf(srcfn,774 "%s\\%s",775 srcdir,776 srcfilename);777 778 if (!destdir || !*destdir)779 pdest = srcdir;780 else781 pdest = destdir;782 783 sprintf(destfn,784 "%s\\%s",785 pdest,786 destfilename);787 788 hfsrc=LZOpenFileA(srcfn,789 &ofs,790 OF_READ);791 792 if (hfsrc==HFILE_ERROR)793 return VIF_CANNOTREADSRC;794 795 sprintf(tmpfn,"%s\\%s",pdest,destfilename);796 tmplast=strlen(pdest)+1;797 attr = GetFileAttributesA(tmpfn);798 if (attr!=-1) {799 if (attr & FILE_ATTRIBUTE_READONLY) {800 LZClose(hfsrc);801 return VIF_WRITEPROT;802 }803 /* FIXME: check if file currently in use and return VIF_FILEINUSE */804 }805 attr = -1;806 if (flags & VIFF_FORCEINSTALL) {807 if (tmpfile[0]) {808 sprintf(tmpfn,"%s\\%s",pdest,tmpfile);809 tmplast = strlen(pdest)+1;810 attr = GetFileAttributesA(tmpfn);811 /* if it exists, it has been copied by the call before.812 * we jump over the copy part...813 */814 }815 }816 if (attr == -1) {817 char *s;818 819 GetTempFileNameA(pdest,"ver",0,tmpfn); /* should not fail ... */820 s=strrchr(tmpfn,'\\');821 if (s)822 tmplast = s-tmpfn;823 else824 tmplast = 0;825 hfdst = OpenFile(tmpfn,&ofs,OF_CREATE);826 if (hfdst == HFILE_ERROR) {827 LZClose(hfsrc);828 return VIF_CANNOTCREATE; /* | translated dos error */829 }830 ret = LZCopy(hfsrc,hfdst);831 _lclose(hfdst);832 if (((long) ret) < 0) {833 /* translate LZ errors into VIF_xxx */834 switch (ret) {835 case LZERROR_BADINHANDLE:836 case LZERROR_READ:837 case LZERROR_BADVALUE:838 case LZERROR_UNKNOWNALG:839 ret = VIF_CANNOTREADSRC;840 break;841 case LZERROR_BADOUTHANDLE:842 case LZERROR_WRITE:843 ret = VIF_OUTOFMEMORY; /* FIXME: correct? */844 break;845 case LZERROR_GLOBALLOC:846 case LZERROR_GLOBLOCK:847 ret = VIF_OUTOFSPACE;848 break;849 default: /* unknown error, should not happen */850 ret = 0;851 break;852 }853 if (ret) {854 LZClose(hfsrc);855 return ret;856 }857 }858 }859 xret = 0;860 if (!(flags & VIFF_FORCEINSTALL)) {861 VS_FIXEDFILEINFO *destvffi,*tmpvffi;862 buf1 = _fetch_versioninfo(destfn,&destvffi);863 if (buf1) {864 buf2 = _fetch_versioninfo(tmpfn,&tmpvffi);865 if (buf2) {866 char *tbuf1,*tbuf2;867 UINT len1,len2;868 869 len1=len2=40;870 871 /* compare file versions */872 if ((destvffi->dwFileVersionMS > tmpvffi->dwFileVersionMS)||873 ((destvffi->dwFileVersionMS==tmpvffi->dwFileVersionMS)&&874 (destvffi->dwFileVersionLS > tmpvffi->dwFileVersionLS)875 )876 )877 xret |= VIF_MISMATCH|VIF_SRCOLD;878 /* compare filetypes and filesubtypes */879 if ((destvffi->dwFileType!=tmpvffi->dwFileType) ||880 (destvffi->dwFileSubtype!=tmpvffi->dwFileSubtype)881 )882 xret |= VIF_MISMATCH|VIF_DIFFTYPE;883 if (VerQueryValueA(buf1,"\\VarFileInfo\\Translation",(LPVOID*)&tbuf1,&len1) &&884 VerQueryValueA(buf2,"\\VarFileInfo\\Translation",(LPVOID*)&tbuf2,&len2)885 ) {886 /* irgendwas mit tbuf1 und tbuf2 machen887 * generiert DIFFLANG|MISMATCH888 */889 }890 free(buf2);891 } else892 xret=VIF_MISMATCH|VIF_SRCOLD;893 free(buf1);894 }895 }896 if (xret) {897 if (*tmpfilelen<strlen(tmpfn+tmplast)) {898 xret|=VIF_BUFFTOOSMALL;899 DeleteFileA(tmpfn);900 } else {901 strcpy(tmpfile,tmpfn+tmplast);902 *tmpfilelen = strlen(tmpfn+tmplast)+1;903 xret|=VIF_TEMPFILE;904 }905 } else {906 if (-1!=GetFileAttributesA(destfn))907 if (!DeleteFileA(destfn)) {908 xret|=_error2vif(GetLastError())|VIF_CANNOTDELETE;909 DeleteFileA(tmpfn);910 LZClose(hfsrc);911 return xret;912 }913 if ((!(flags & VIFF_DONTDELETEOLD)) &&914 curdir &&915 *curdir &&916 lstrcmpiA(curdir,pdest)917 ) {918 char curfn[260];919 920 sprintf(curfn,"%s\\%s",curdir,destfilename);921 if (-1!=GetFileAttributesA(curfn)) {922 /* FIXME: check if in use ... if it is, VIF_CANNOTDELETECUR */923 if (!DeleteFileA(curfn))924 xret|=_error2vif(GetLastError())|VIF_CANNOTDELETECUR;925 }926 }927 if (!MoveFileA(tmpfn,destfn)) {928 xret|=_error2vif(GetLastError())|VIF_CANNOTRENAME;929 DeleteFileA(tmpfn);930 }931 }932 LZClose(hfsrc);933 return xret;934 }935 936 937 /*****************************************************************************938 * Name :939 * Purpose :940 * Parameters:941 * Variables :942 * Result :943 * Remark :944 * Status : UNTESTED STUB945 *946 * Author : Patrick Haller [Tue, 1998/06/16 23:00]947 *****************************************************************************/948 949 ODINFUNCTION8(DWORD,VerInstallFileW,DWORD, flags,950 LPWSTR, srcfilename,951 LPWSTR, destfilename,952 LPWSTR, srcdir,953 LPWSTR, destdir,954 LPWSTR, curdir,955 LPWSTR, tmpfile,956 PUINT, tmpfilelen )957 {958 LPSTR wsrcf,959 wsrcd,960 wdestf,961 wdestd,962 wtmpf,963 wcurd;964 DWORD ret;965 966 wsrcf = UnicodeToAsciiString(srcfilename );967 wsrcd = UnicodeToAsciiString(srcdir );968 wdestf = UnicodeToAsciiString(destfilename );969 wdestd = UnicodeToAsciiString(destdir );970 wtmpf = UnicodeToAsciiString(tmpfile );971 wcurd = UnicodeToAsciiString(curdir );972 973 ret = VerInstallFileA(flags,974 wsrcf,975 wdestf,976 wsrcd,977 wdestd,978 wcurd,979 wtmpf,980 tmpfilelen);981 if (!ret)982 AsciiToUnicodeN(wtmpf,983 tmpfile,984 *tmpfilelen);985 986 FreeAsciiString(wsrcf);987 FreeAsciiString(wsrcd);988 FreeAsciiString(wdestf);989 FreeAsciiString(wdestd);990 FreeAsciiString(wtmpf);991 992 if (wcurd)993 FreeAsciiString(wcurd);994 995 return ret;996 }997 998 999
Note:
See TracChangeset
for help on using the changeset viewer.