Ignore:
Timestamp:
Jan 6, 2000, 9:10:07 PM (26 years ago)
Author:
sandervl
Message:

VerQueryValue32A and merged with latest Wine sources (991212)

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:53 sandervl Exp $ */
     1/* $Id: version.cpp,v 1.9 2000-01-06 20:10:07 sandervl Exp $ */
    22
    33/*
     
    2222#include <heapstring.h>
    2323#include <version.h>
    24 #include <lzexpand.h>
    25 #include <win\winreg.h>
    26 
    2724
    2825ODINDEBUGCHANNEL(VERSION)
    2926
    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)
     27BOOL GetFileVersionInfoA(LPSTR lpszFile, DWORD dwHandle, DWORD cbBuf, LPVOID lpvData)
    30528{
    30629  return GetVersionStruct((char *)lpszFile,
     
    30932}
    31033
    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)
     34BOOL GetFileVersionInfoW(LPWSTR lpszFile, DWORD dwHandle, DWORD cbBuf, LPVOID lpvData)
    32835{
    32936  BOOL rc;
     
    33542}
    33643
    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)
     44DWORD GetFileVersionInfoSizeA(LPSTR lpszFile, LPDWORD lpdwHandle)
    35245{
    35346  if(lpdwHandle)
     
    35851
    35952
    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)
     53DWORD GetFileVersionInfoSizeW(LPWSTR lpszFile, LPDWORD lpdwHandle)
    37454{
    37555  char  *astring = UnicodeToAsciiString((LPWSTR)lpszFile);
    37656  DWORD rc;
    377 
    37857
    37958  if(lpdwHandle)
     
    38766
    38867
    389 /*****************************************************************************
    390  * Name      :
    391  * Purpose   :
    392  * Parameters:
    393  * Variables :
    394  * Result    :
    395  * Remark    :
    396  * Status    : UNTESTED STUB
    397  *
    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 STUB
    453  *
    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 tested
    466         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         else
    483         {
    484           *lplpBuffer = malloc(len+1); // no free, memory leak
    485           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 another
    529  *   version of the file in the system.  The values VerFindFile returns are
    530  *   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 the
    560      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       else
    580         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   else
    592     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           else
    611             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 are
    629      valid; if not, do NOTHING with that buffer.  If that pointer
    630      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     else
    644       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     else
    661       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 STUB
    685  *
    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 STUB
    744  *
    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     else
    781       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    else
    824        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 machen
    887            * generiert DIFFLANG|MISMATCH
    888            */
    889       }
    890       free(buf2);
    891        } else
    892       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 STUB
    945  *
    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.