Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygeninstall.c
Go to the documentation of this file.
00001 /* 00002 * Implementation of VERSION.DLL - File Installer routines 00003 * 00004 * Copyright 1996,1997 Marcus Meissner 00005 * Copyright 1997 David Cuthbert 00006 * 00007 * This library is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2.1 of the License, or (at your option) any later version. 00011 * 00012 * This library is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with this library; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00020 * 00021 * TODO 00022 * o Check the installation functions. 00023 */ 00024 00025 #include <stdlib.h> 00026 #include <stdarg.h> 00027 #include <stdio.h> 00028 #include <string.h> 00029 00030 #include "windef.h" 00031 #include "winbase.h" 00032 #include "winver.h" 00033 #include "winnls.h" 00034 #include "wine/unicode.h" 00035 #include "winerror.h" 00036 #include "lzexpand.h" 00037 #include "wine/debug.h" 00038 00039 WINE_DEFAULT_DEBUG_CHANNEL(ver); 00040 00041 00042 /****************************************************************************** 00043 * testFileExistenceA 00044 * 00045 * Tests whether a given path/file combination exists. If the file does 00046 * not exist, the return value is zero. If it does exist, the return 00047 * value is non-zero. 00048 * 00049 * Revision history 00050 * 30-May-1997 Dave Cuthbert (dacut@ece.cmu.edu) 00051 * Original implementation 00052 * 00053 */ 00054 static int testFileExistenceA( char const * path, char const * file, BOOL excl ) 00055 { 00056 char filename[1024]; 00057 int filenamelen; 00058 OFSTRUCT fileinfo; 00059 00060 fileinfo.cBytes = sizeof(OFSTRUCT); 00061 00062 strcpy(filename, path); 00063 filenamelen = strlen(filename); 00064 00065 /* Add a trailing \ if necessary */ 00066 if(filenamelen) { 00067 if(filename[filenamelen - 1] != '\\') 00068 strcat(filename, "\\"); 00069 } 00070 else /* specify the current directory */ 00071 strcpy(filename, ".\\"); 00072 00073 /* Create the full pathname */ 00074 strcat(filename, file); 00075 00076 return (OpenFile(filename, &fileinfo, 00077 OF_EXIST | (excl ? OF_SHARE_EXCLUSIVE : 0)) != HFILE_ERROR); 00078 } 00079 00080 /****************************************************************************** 00081 * testFileExistenceW 00082 */ 00083 static int testFileExistenceW( const WCHAR *path, const WCHAR *file, BOOL excl ) 00084 { 00085 char *filename; 00086 DWORD pathlen, filelen; 00087 int ret; 00088 OFSTRUCT fileinfo; 00089 00090 fileinfo.cBytes = sizeof(OFSTRUCT); 00091 00092 pathlen = WideCharToMultiByte( CP_ACP, 0, path, -1, NULL, 0, NULL, NULL ); 00093 filelen = WideCharToMultiByte( CP_ACP, 0, file, -1, NULL, 0, NULL, NULL ); 00094 filename = HeapAlloc( GetProcessHeap(), 0, pathlen+filelen+2 ); 00095 00096 WideCharToMultiByte( CP_ACP, 0, path, -1, filename, pathlen, NULL, NULL ); 00097 /* Add a trailing \ if necessary */ 00098 if (pathlen > 1) 00099 { 00100 if (filename[pathlen-2] != '\\') strcpy( &filename[pathlen-1], "\\" ); 00101 } 00102 else /* specify the current directory */ 00103 strcpy(filename, ".\\"); 00104 00105 WideCharToMultiByte( CP_ACP, 0, file, -1, filename+strlen(filename), filelen, NULL, NULL ); 00106 00107 ret = (OpenFile(filename, &fileinfo, 00108 OF_EXIST | (excl ? OF_SHARE_EXCLUSIVE : 0)) != HFILE_ERROR); 00109 HeapFree( GetProcessHeap(), 0, filename ); 00110 return ret; 00111 } 00112 00113 /***************************************************************************** 00114 * VerFindFileA [VERSION.@] 00115 * 00116 * Determines where to install a file based on whether it locates another 00117 * version of the file in the system. The values VerFindFile returns are 00118 * used in a subsequent call to the VerInstallFile function. 00119 * 00120 * Revision history: 00121 * 30-May-1997 Dave Cuthbert (dacut@ece.cmu.edu) 00122 * Reimplementation of VerFindFile from original stub. 00123 */ 00124 DWORD WINAPI VerFindFileA( 00125 DWORD flags, 00126 LPCSTR lpszFilename, 00127 LPCSTR lpszWinDir, 00128 LPCSTR lpszAppDir, 00129 LPSTR lpszCurDir, 00130 PUINT lpuCurDirLen, 00131 LPSTR lpszDestDir, 00132 PUINT lpuDestDirLen ) 00133 { 00134 DWORD retval = 0; 00135 const char *curDir; 00136 const char *destDir; 00137 unsigned int curDirSizeReq; 00138 unsigned int destDirSizeReq; 00139 char systemDir[MAX_PATH]; 00140 00141 /* Print out debugging information */ 00142 TRACE("flags = %x filename=%s windir=%s appdir=%s curdirlen=%p(%u) destdirlen=%p(%u)\n", 00143 flags, debugstr_a(lpszFilename), debugstr_a(lpszWinDir), debugstr_a(lpszAppDir), 00144 lpuCurDirLen, lpuCurDirLen ? *lpuCurDirLen : 0, 00145 lpuDestDirLen, lpuDestDirLen ? *lpuDestDirLen : 0 ); 00146 00147 /* Figure out where the file should go; shared files default to the 00148 system directory */ 00149 00150 GetSystemDirectoryA(systemDir, sizeof(systemDir)); 00151 curDir = ""; 00152 destDir = ""; 00153 00154 if(flags & VFFF_ISSHAREDFILE) 00155 { 00156 destDir = systemDir; 00157 /* Were we given a filename? If so, try to find the file. */ 00158 if(lpszFilename) 00159 { 00160 if(testFileExistenceA(destDir, lpszFilename, FALSE)) curDir = destDir; 00161 else if(lpszAppDir && testFileExistenceA(lpszAppDir, lpszFilename, FALSE)) 00162 { 00163 curDir = lpszAppDir; 00164 retval |= VFF_CURNEDEST; 00165 } 00166 } 00167 } 00168 else /* not a shared file */ 00169 { 00170 if(lpszAppDir) 00171 { 00172 destDir = lpszAppDir; 00173 if(lpszFilename) 00174 { 00175 if(testFileExistenceA(destDir, lpszFilename, FALSE)) curDir = destDir; 00176 else if(testFileExistenceA(systemDir, lpszFilename, FALSE)) 00177 { 00178 curDir = systemDir; 00179 retval |= VFF_CURNEDEST; 00180 } 00181 } 00182 } 00183 } 00184 00185 /* Check to see if the file exists and is in use by another application */ 00186 if (lpszFilename && testFileExistenceA(curDir, lpszFilename, FALSE)) { 00187 if (lpszFilename && !testFileExistenceA(curDir, lpszFilename, TRUE)) 00188 retval |= VFF_FILEINUSE; 00189 } 00190 00191 curDirSizeReq = strlen(curDir) + 1; 00192 destDirSizeReq = strlen(destDir) + 1; 00193 00194 /* Make sure that the pointers to the size of the buffers are 00195 valid; if not, do NOTHING with that buffer. If that pointer 00196 is valid, then make sure that the buffer pointer is valid, too! */ 00197 00198 if(lpuDestDirLen && lpszDestDir) 00199 { 00200 if (*lpuDestDirLen < destDirSizeReq) retval |= VFF_BUFFTOOSMALL; 00201 lstrcpynA(lpszDestDir, destDir, *lpuDestDirLen); 00202 *lpuDestDirLen = destDirSizeReq; 00203 } 00204 if(lpuCurDirLen && lpszCurDir) 00205 { 00206 if(*lpuCurDirLen < curDirSizeReq) retval |= VFF_BUFFTOOSMALL; 00207 lstrcpynA(lpszCurDir, curDir, *lpuCurDirLen); 00208 *lpuCurDirLen = curDirSizeReq; 00209 } 00210 00211 TRACE("ret = %u (%s%s%s) curdir=%s destdir=%s\n", retval, 00212 (retval & VFF_CURNEDEST) ? "VFF_CURNEDEST " : "", 00213 (retval & VFF_FILEINUSE) ? "VFF_FILEINUSE " : "", 00214 (retval & VFF_BUFFTOOSMALL) ? "VFF_BUFFTOOSMALL " : "", 00215 debugstr_a(lpszCurDir), debugstr_a(lpszDestDir)); 00216 00217 return retval; 00218 } 00219 00220 /***************************************************************************** 00221 * VerFindFileW [VERSION.@] 00222 */ 00223 DWORD WINAPI VerFindFileW( DWORD flags,LPCWSTR lpszFilename,LPCWSTR lpszWinDir, 00224 LPCWSTR lpszAppDir, LPWSTR lpszCurDir,PUINT lpuCurDirLen, 00225 LPWSTR lpszDestDir,PUINT lpuDestDirLen ) 00226 { 00227 static const WCHAR emptyW; 00228 DWORD retval = 0; 00229 const WCHAR *curDir; 00230 const WCHAR *destDir; 00231 unsigned int curDirSizeReq; 00232 unsigned int destDirSizeReq; 00233 WCHAR systemDir[MAX_PATH]; 00234 00235 /* Print out debugging information */ 00236 TRACE("flags = %x filename=%s windir=%s appdir=%s curdirlen=%p(%u) destdirlen=%p(%u)\n", 00237 flags, debugstr_w(lpszFilename), debugstr_w(lpszWinDir), debugstr_w(lpszAppDir), 00238 lpuCurDirLen, lpuCurDirLen ? *lpuCurDirLen : 0, 00239 lpuDestDirLen, lpuDestDirLen ? *lpuDestDirLen : 0 ); 00240 00241 /* Figure out where the file should go; shared files default to the 00242 system directory */ 00243 00244 GetSystemDirectoryW(systemDir, sizeof(systemDir)/sizeof(WCHAR)); 00245 curDir = &emptyW; 00246 destDir = &emptyW; 00247 00248 if(flags & VFFF_ISSHAREDFILE) 00249 { 00250 destDir = systemDir; 00251 /* Were we given a filename? If so, try to find the file. */ 00252 if(lpszFilename) 00253 { 00254 if(testFileExistenceW(destDir, lpszFilename, FALSE)) curDir = destDir; 00255 else if(lpszAppDir && testFileExistenceW(lpszAppDir, lpszFilename, FALSE)) 00256 { 00257 curDir = lpszAppDir; 00258 retval |= VFF_CURNEDEST; 00259 } 00260 } 00261 } 00262 else /* not a shared file */ 00263 { 00264 if(lpszAppDir) 00265 { 00266 destDir = lpszAppDir; 00267 if(lpszFilename) 00268 { 00269 if(testFileExistenceW(destDir, lpszFilename, FALSE)) curDir = destDir; 00270 else if(testFileExistenceW(systemDir, lpszFilename, FALSE)) 00271 { 00272 curDir = systemDir; 00273 retval |= VFF_CURNEDEST; 00274 } 00275 } 00276 } 00277 } 00278 00279 if (lpszFilename && !testFileExistenceW(curDir, lpszFilename, TRUE)) 00280 retval |= VFF_FILEINUSE; 00281 00282 curDirSizeReq = strlenW(curDir) + 1; 00283 destDirSizeReq = strlenW(destDir) + 1; 00284 00285 /* Make sure that the pointers to the size of the buffers are 00286 valid; if not, do NOTHING with that buffer. If that pointer 00287 is valid, then make sure that the buffer pointer is valid, too! */ 00288 00289 if(lpuDestDirLen && lpszDestDir) 00290 { 00291 if (*lpuDestDirLen < destDirSizeReq) retval |= VFF_BUFFTOOSMALL; 00292 lstrcpynW(lpszDestDir, destDir, *lpuDestDirLen); 00293 *lpuDestDirLen = destDirSizeReq; 00294 } 00295 if(lpuCurDirLen && lpszCurDir) 00296 { 00297 if(*lpuCurDirLen < curDirSizeReq) retval |= VFF_BUFFTOOSMALL; 00298 lstrcpynW(lpszCurDir, curDir, *lpuCurDirLen); 00299 *lpuCurDirLen = curDirSizeReq; 00300 } 00301 00302 TRACE("ret = %u (%s%s%s) curdir=%s destdir=%s\n", retval, 00303 (retval & VFF_CURNEDEST) ? "VFF_CURNEDEST " : "", 00304 (retval & VFF_FILEINUSE) ? "VFF_FILEINUSE " : "", 00305 (retval & VFF_BUFFTOOSMALL) ? "VFF_BUFFTOOSMALL " : "", 00306 debugstr_w(lpszCurDir), debugstr_w(lpszDestDir)); 00307 return retval; 00308 } 00309 00310 static LPBYTE 00311 _fetch_versioninfo(LPSTR fn,VS_FIXEDFILEINFO **vffi) { 00312 DWORD alloclen; 00313 LPBYTE buf; 00314 DWORD ret; 00315 00316 alloclen = 1000; 00317 buf=HeapAlloc(GetProcessHeap(), 0, alloclen); 00318 if(buf == NULL) { 00319 WARN("Memory exausted while fetching version info!\n"); 00320 return NULL; 00321 } 00322 while (1) { 00323 ret = GetFileVersionInfoA(fn,0,alloclen,buf); 00324 if (!ret) { 00325 HeapFree(GetProcessHeap(), 0, buf); 00326 return NULL; 00327 } 00328 if (alloclen<*(WORD*)buf) { 00329 alloclen = *(WORD*)buf; 00330 HeapFree(GetProcessHeap(), 0, buf); 00331 buf = HeapAlloc(GetProcessHeap(), 0, alloclen); 00332 if(buf == NULL) { 00333 WARN("Memory exausted while fetching version info!\n"); 00334 return NULL; 00335 } 00336 } else { 00337 *vffi = (VS_FIXEDFILEINFO*)(buf+0x14); 00338 if ((*vffi)->dwSignature == 0x004f0049) /* hack to detect unicode */ 00339 *vffi = (VS_FIXEDFILEINFO*)(buf+0x28); 00340 if ((*vffi)->dwSignature != VS_FFI_SIGNATURE) 00341 WARN("Bad VS_FIXEDFILEINFO signature 0x%08x\n",(*vffi)->dwSignature); 00342 return buf; 00343 } 00344 } 00345 } 00346 00347 static DWORD 00348 _error2vif(DWORD error) { 00349 switch (error) { 00350 case ERROR_ACCESS_DENIED: 00351 return VIF_ACCESSVIOLATION; 00352 case ERROR_SHARING_VIOLATION: 00353 return VIF_SHARINGVIOLATION; 00354 default: 00355 return 0; 00356 } 00357 } 00358 00359 00360 /****************************************************************************** 00361 * VerInstallFileA [VERSION.@] 00362 */ 00363 DWORD WINAPI VerInstallFileA( 00364 DWORD flags,LPCSTR srcfilename,LPCSTR destfilename,LPCSTR srcdir, 00365 LPCSTR destdir,LPCSTR curdir,LPSTR tmpfile,PUINT tmpfilelen ) 00366 { 00367 LPCSTR pdest; 00368 char destfn[260],tmpfn[260],srcfn[260]; 00369 HFILE hfsrc,hfdst; 00370 DWORD attr,xret,tmplast; 00371 LONG ret; 00372 LPBYTE buf1,buf2; 00373 OFSTRUCT ofs; 00374 00375 TRACE("(%x,%s,%s,%s,%s,%s,%p,%d)\n", 00376 flags,srcfilename,destfilename,srcdir,destdir,curdir,tmpfile,*tmpfilelen 00377 ); 00378 xret = 0; 00379 sprintf(srcfn,"%s\\%s",srcdir,srcfilename); 00380 if (!destdir || !*destdir) pdest = srcdir; 00381 else pdest = destdir; 00382 sprintf(destfn,"%s\\%s",pdest,destfilename); 00383 hfsrc=LZOpenFileA(srcfn,&ofs,OF_READ); 00384 if (hfsrc < 0) 00385 return VIF_CANNOTREADSRC; 00386 sprintf(tmpfn,"%s\\%s",pdest,destfilename); 00387 tmplast=strlen(pdest)+1; 00388 attr = GetFileAttributesA(tmpfn); 00389 if (attr != INVALID_FILE_ATTRIBUTES) { 00390 if (attr & FILE_ATTRIBUTE_READONLY) { 00391 LZClose(hfsrc); 00392 return VIF_WRITEPROT; 00393 } 00394 /* FIXME: check if file currently in use and return VIF_FILEINUSE */ 00395 } 00396 attr = INVALID_FILE_ATTRIBUTES; 00397 if (flags & VIFF_FORCEINSTALL) { 00398 if (tmpfile[0]) { 00399 sprintf(tmpfn,"%s\\%s",pdest,tmpfile); 00400 tmplast = strlen(pdest)+1; 00401 attr = GetFileAttributesA(tmpfn); 00402 /* if it exists, it has been copied by the call before. 00403 * we jump over the copy part... 00404 */ 00405 } 00406 } 00407 if (attr == INVALID_FILE_ATTRIBUTES) { 00408 char *s; 00409 00410 GetTempFileNameA(pdest,"ver",0,tmpfn); /* should not fail ... */ 00411 s=strrchr(tmpfn,'\\'); 00412 if (s) 00413 tmplast = s-tmpfn; 00414 else 00415 tmplast = 0; 00416 hfdst = OpenFile(tmpfn,&ofs,OF_CREATE); 00417 if (hfdst == HFILE_ERROR) { 00418 LZClose(hfsrc); 00419 return VIF_CANNOTCREATE; /* | translated dos error */ 00420 } 00421 ret = LZCopy(hfsrc,hfdst); 00422 _lclose(hfdst); 00423 if (ret < 0) { 00424 /* translate LZ errors into VIF_xxx */ 00425 switch (ret) { 00426 case LZERROR_BADINHANDLE: 00427 case LZERROR_READ: 00428 case LZERROR_BADVALUE: 00429 case LZERROR_UNKNOWNALG: 00430 xret = VIF_CANNOTREADSRC; 00431 break; 00432 case LZERROR_BADOUTHANDLE: 00433 case LZERROR_WRITE: 00434 xret = VIF_OUTOFSPACE; 00435 break; 00436 case LZERROR_GLOBALLOC: 00437 case LZERROR_GLOBLOCK: 00438 xret = VIF_OUTOFMEMORY; 00439 break; 00440 default: /* unknown error, should not happen */ 00441 FIXME("Unknown LZCopy error %d, ignoring.\n", ret); 00442 xret = 0; 00443 break; 00444 } 00445 if (xret) { 00446 LZClose(hfsrc); 00447 return xret; 00448 } 00449 } 00450 } 00451 xret = 0; 00452 if (!(flags & VIFF_FORCEINSTALL)) { 00453 VS_FIXEDFILEINFO *destvffi,*tmpvffi; 00454 buf1 = _fetch_versioninfo(destfn,&destvffi); 00455 if (buf1) { 00456 buf2 = _fetch_versioninfo(tmpfn,&tmpvffi); 00457 if (buf2) { 00458 char *tbuf1,*tbuf2; 00459 static const CHAR trans_array[] = "\\VarFileInfo\\Translation"; 00460 UINT len1,len2; 00461 00462 len1=len2=40; 00463 00464 /* compare file versions */ 00465 if ((destvffi->dwFileVersionMS > tmpvffi->dwFileVersionMS)|| 00466 ((destvffi->dwFileVersionMS==tmpvffi->dwFileVersionMS)&& 00467 (destvffi->dwFileVersionLS > tmpvffi->dwFileVersionLS) 00468 ) 00469 ) 00470 xret |= VIF_MISMATCH|VIF_SRCOLD; 00471 /* compare filetypes and filesubtypes */ 00472 if ((destvffi->dwFileType!=tmpvffi->dwFileType) || 00473 (destvffi->dwFileSubtype!=tmpvffi->dwFileSubtype) 00474 ) 00475 xret |= VIF_MISMATCH|VIF_DIFFTYPE; 00476 if (VerQueryValueA(buf1,trans_array,(LPVOID*)&tbuf1,&len1) && 00477 VerQueryValueA(buf2,trans_array,(LPVOID*)&tbuf2,&len2) 00478 ) { 00479 /* Do something with tbuf1 and tbuf2 00480 * generates DIFFLANG|MISMATCH 00481 */ 00482 } 00483 HeapFree(GetProcessHeap(), 0, buf2); 00484 } else 00485 xret=VIF_MISMATCH|VIF_SRCOLD; 00486 HeapFree(GetProcessHeap(), 0, buf1); 00487 } 00488 } 00489 if (xret) { 00490 if (*tmpfilelen<strlen(tmpfn+tmplast)) { 00491 xret|=VIF_BUFFTOOSMALL; 00492 DeleteFileA(tmpfn); 00493 } else { 00494 strcpy(tmpfile,tmpfn+tmplast); 00495 *tmpfilelen = strlen(tmpfn+tmplast)+1; 00496 xret|=VIF_TEMPFILE; 00497 } 00498 } else { 00499 if (INVALID_FILE_ATTRIBUTES!=GetFileAttributesA(destfn)) 00500 if (!DeleteFileA(destfn)) { 00501 xret|=_error2vif(GetLastError())|VIF_CANNOTDELETE; 00502 DeleteFileA(tmpfn); 00503 LZClose(hfsrc); 00504 return xret; 00505 } 00506 if ((!(flags & VIFF_DONTDELETEOLD)) && 00507 curdir && 00508 *curdir && 00509 lstrcmpiA(curdir,pdest) 00510 ) { 00511 char curfn[260]; 00512 00513 sprintf(curfn,"%s\\%s",curdir,destfilename); 00514 if (INVALID_FILE_ATTRIBUTES != GetFileAttributesA(curfn)) { 00515 /* FIXME: check if in use ... if it is, VIF_CANNOTDELETECUR */ 00516 if (!DeleteFileA(curfn)) 00517 xret|=_error2vif(GetLastError())|VIF_CANNOTDELETECUR; 00518 } 00519 } 00520 if (!MoveFileA(tmpfn,destfn)) { 00521 xret|=_error2vif(GetLastError())|VIF_CANNOTRENAME; 00522 DeleteFileA(tmpfn); 00523 } 00524 } 00525 LZClose(hfsrc); 00526 return xret; 00527 } 00528 00529 00530 /****************************************************************************** 00531 * VerInstallFileW [VERSION.@] 00532 */ 00533 DWORD WINAPI VerInstallFileW( 00534 DWORD flags,LPCWSTR srcfilename,LPCWSTR destfilename,LPCWSTR srcdir, 00535 LPCWSTR destdir,LPCWSTR curdir,LPWSTR tmpfile,PUINT tmpfilelen ) 00536 { 00537 LPSTR wsrcf = NULL, wsrcd = NULL, wdestf = NULL, wdestd = NULL, wtmpf = NULL, wcurd = NULL; 00538 DWORD ret = 0; 00539 UINT len; 00540 00541 if (srcfilename) 00542 { 00543 len = WideCharToMultiByte( CP_ACP, 0, srcfilename, -1, NULL, 0, NULL, NULL ); 00544 if ((wsrcf = HeapAlloc( GetProcessHeap(), 0, len ))) 00545 WideCharToMultiByte( CP_ACP, 0, srcfilename, -1, wsrcf, len, NULL, NULL ); 00546 else 00547 ret = VIF_OUTOFMEMORY; 00548 } 00549 if (srcdir && !ret) 00550 { 00551 len = WideCharToMultiByte( CP_ACP, 0, srcdir, -1, NULL, 0, NULL, NULL ); 00552 if ((wsrcd = HeapAlloc( GetProcessHeap(), 0, len ))) 00553 WideCharToMultiByte( CP_ACP, 0, srcdir, -1, wsrcd, len, NULL, NULL ); 00554 else 00555 ret = VIF_OUTOFMEMORY; 00556 } 00557 if (destfilename && !ret) 00558 { 00559 len = WideCharToMultiByte( CP_ACP, 0, destfilename, -1, NULL, 0, NULL, NULL ); 00560 if ((wdestf = HeapAlloc( GetProcessHeap(), 0, len ))) 00561 WideCharToMultiByte( CP_ACP, 0, destfilename, -1, wdestf, len, NULL, NULL ); 00562 else 00563 ret = VIF_OUTOFMEMORY; 00564 } 00565 if (destdir && !ret) 00566 { 00567 len = WideCharToMultiByte( CP_ACP, 0, destdir, -1, NULL, 0, NULL, NULL ); 00568 if ((wdestd = HeapAlloc( GetProcessHeap(), 0, len ))) 00569 WideCharToMultiByte( CP_ACP, 0, destdir, -1, wdestd, len, NULL, NULL ); 00570 else 00571 ret = VIF_OUTOFMEMORY; 00572 } 00573 if (curdir && !ret) 00574 { 00575 len = WideCharToMultiByte( CP_ACP, 0, curdir, -1, NULL, 0, NULL, NULL ); 00576 if ((wcurd = HeapAlloc( GetProcessHeap(), 0, len ))) 00577 WideCharToMultiByte( CP_ACP, 0, curdir, -1, wcurd, len, NULL, NULL ); 00578 else 00579 ret = VIF_OUTOFMEMORY; 00580 } 00581 if (!ret) 00582 { 00583 len = *tmpfilelen * sizeof(WCHAR); 00584 wtmpf = HeapAlloc( GetProcessHeap(), 0, len ); 00585 if (!wtmpf) 00586 ret = VIF_OUTOFMEMORY; 00587 } 00588 if (!ret) 00589 ret = VerInstallFileA(flags,wsrcf,wdestf,wsrcd,wdestd,wcurd,wtmpf,&len); 00590 if (!ret) 00591 *tmpfilelen = MultiByteToWideChar( CP_ACP, 0, wtmpf, -1, tmpfile, *tmpfilelen ); 00592 else if (ret & VIF_BUFFTOOSMALL) 00593 *tmpfilelen = len; /* FIXME: not correct */ 00594 00595 HeapFree( GetProcessHeap(), 0, wsrcf ); 00596 HeapFree( GetProcessHeap(), 0, wsrcd ); 00597 HeapFree( GetProcessHeap(), 0, wdestf ); 00598 HeapFree( GetProcessHeap(), 0, wdestd ); 00599 HeapFree( GetProcessHeap(), 0, wtmpf ); 00600 HeapFree( GetProcessHeap(), 0, wcurd ); 00601 return ret; 00602 } Generated on Sun May 27 2012 04:19:20 for ReactOS by
1.7.6.1
|