ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

install.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.