Back to index

lightning-sunbird  0.9+nobinonly
VerReg.c
Go to the documentation of this file.
00001 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
00002  *
00003  * ***** BEGIN LICENSE BLOCK *****
00004  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00005  *
00006  * The contents of this file are subject to the Mozilla Public License Version
00007  * 1.1 (the "License"); you may not use this file except in compliance with
00008  * the License. You may obtain a copy of the License at
00009  * http://www.mozilla.org/MPL/
00010  *
00011  * Software distributed under the License is distributed on an "AS IS" basis,
00012  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00013  * for the specific language governing rights and limitations under the
00014  * License.
00015  *
00016  * The Original Code is Mozilla Communicator client code, released
00017  * March 31, 1998.
00018  *
00019  * The Initial Developer of the Original Code is
00020  * Netscape Communications Corporation.
00021  * Portions created by the Initial Developer are Copyright (C) 1998
00022  * the Initial Developer. All Rights Reserved.
00023  *
00024  * Contributor(s):
00025  *   Daniel Veditz <dveditz@netscape.com>
00026  *
00027  * Alternatively, the contents of this file may be used under the terms of
00028  * either the GNU General Public License Version 2 or later (the "GPL"), or
00029  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00030  * in which case the provisions of the GPL or the LGPL are applicable instead
00031  * of those above. If you wish to allow use of your version of this file only
00032  * under the terms of either the GPL or the LGPL, and not to allow others to
00033  * use your version of this file under the terms of the MPL, indicate your
00034  * decision by deleting the provisions above and replace them with the notice
00035  * and other provisions required by the GPL or the LGPL. If you do not delete
00036  * the provisions above, a recipient may use your version of this file under
00037  * the terms of any one of the MPL, the GPL or the LGPL.
00038  *
00039  * ***** END LICENSE BLOCK ***** */
00040 /* ====================================================================
00041  * VerReg.c
00042  * XP Version Registry functions (prototype)
00043  * ====================================================================
00044  */
00045 
00046 /* --------------------------------------------------------------------
00047  * Install 'Navigator' produces a tree of:
00048  *
00049  *      /Components/Netscape/Web/Navigator/
00050  *              ...Path="c:\netscape\program\netscape.exe"
00051  *              ...Version=4.0.0.0
00052  *
00053  * --------------------------------------------------------------------
00054  */
00055 #include <fcntl.h>
00056 #include <errno.h>
00057 
00058 #if defined(XP_WIN) 
00059 #include <io.h>
00060 #endif
00061 
00062 #if defined(XP_OS2)
00063 #include <sys/types.h>
00064 #include <sys/stat.h>
00065 #endif
00066 
00067 #include <stdio.h>
00068 #include <string.h>
00069 
00070 #ifdef STANDALONE_REGISTRY
00071 #include <stdlib.h>
00072 #include <assert.h>
00073 #endif /*STANDALONE_REGISTRY*/
00074 
00075 #include "reg.h"
00076 #include "NSReg.h"
00077 #include "VerReg.h"
00078 
00079 #if defined(XP_MAC) || defined(XP_MACOSX)
00080 #include <Folders.h>
00081 #endif
00082 
00083 /* -------- local defines --------------- 
00084 */
00085 #define MAXREGVERLEN 32     /* Version=12345.12345.12345.12345 */
00086 
00087 #define VERSTR          "Version"
00088 #define CHKSTR          "Check"
00089 #define PATHSTR         "Path"
00090 #define DIRSTR          "Directory"
00091 #define NAVHOME         "InstallDir"
00092 #define REFCSTR         "RefCount"
00093 #define SHAREDSTR       "Shared"
00094 #define PACKAGENAMESTR  "PackageName"
00095 #define SHAREDFILESSTR  "/Shared Files"
00096 
00097 #define VERSION_NAME    "Mozilla"
00098 #define NAVIGATOR_NODE  "/mozilla.org"
00099 #define CURRENT_VER     "CurrentVersion"
00100 
00101 #define PATH_ROOT(p)   ( ((p) && *(p)==PATHDEL) ? ROOTKEY_VERSIONS : curver )
00102 #define UNIX_ROOT(p)   ( ((p) && *(p)==PATHDEL) ? ROOTKEY_VERSIONS : unixver )
00103 
00104  
00105 /* ---------------------------------------------------------------------
00106  * Global variables
00107  * ---------------------------------------------------------------------
00108  */
00109 static int isInited = 0;
00110 static RKEY curver = 0;
00111 static char gCurstr[MAXREGNAMELEN];
00112 
00113 static HREG vreg = 0;
00114 
00115 static char *app_dir = NULL;
00116 
00117 char *verRegName = NULL;
00118 
00119 
00120 #if defined(XP_UNIX) && !defined(XP_MACOSX)
00121 /* Extra Unix variables to deal with two registries 
00122  *   "vreg" is always the writable registry.
00123  *   If "vreg" is the local registry then "unixreg" will
00124  *   be the global registry read-only (unless we couldn't
00125  *   open it).
00126  */
00127 #if !defined(STANDALONE_REGISTRY)
00128 static HREG unixreg = 0;
00129 static RKEY unixver = 0;
00130 #endif
00131 XP_Bool bGlobalRegistry = FALSE;
00132 #endif
00133 
00134 #ifndef STANDALONE_REGISTRY
00135 PRLock *vr_lock = NULL;
00136 #endif
00137 
00138 
00139 /* ---------------------------------------------------------------------
00140  * local functions
00141  * ---------------------------------------------------------------------
00142  */
00143 static REGERR vr_Init(void);
00144 static XP_Bool vr_CompareDirs( char *dir1, char *dir2 );
00145 static REGERR vr_SetCurrentNav( char *product, char *programPath, char *versionStr);
00146 static REGERR vr_ParseVersion(char *verstr, VERSION *result);
00147 
00148 #ifdef USE_CHECKSUM
00149 static REGERR vr_GetCheck(char *path, int32 *check);
00150 #endif
00151 
00152 static REGERR vr_SetPathname(HREG reg, RKEY key, char *entry, char *dir);
00153 static REGERR vr_GetPathname(HREG reg, RKEY key, char *entry, char *buf, uint32 sizebuf);
00154 
00155 static REGERR vr_FindKey(char *name, HREG *hreg, RKEY *key);
00156 
00157 static REGERR vr_GetUninstallItemPath(char *regPackageName, char *regbuf, uint32 regbuflen);
00158 static REGERR vr_convertPackageName(char *regPackageName, char *convertedPackageName, uint32 convertedDataLength);
00159 static REGERR vr_unmanglePackageName(char *mangledPackageName, char *regPackageName, uint32 regPackageLength);
00160 
00161 #if defined(XP_MAC) || defined(XP_MACOSX)
00162 static void vr_MacAliasFromPath(const char * fileName, void ** alias, int32 * length);
00163 static char * vr_PathFromMacAlias(const void * alias, uint32 aliasLength);
00164 #endif
00165 
00166 /* --------------------------------------------------------------------- */
00167 
00168 static REGERR vr_Init(void)
00169 {
00170 
00171     REGERR  err = REGERR_OK;
00172     char    *regname = vr_findVerRegName();
00173 #if defined(XP_UNIX) && !defined(XP_MACOSX) || defined(STANDALONE_REGISTRY)
00174     char    curstr[MAXREGNAMELEN];
00175     RKEY    navKey;
00176 #endif
00177 #if defined(XP_UNIX) && !defined(XP_MACOSX)
00178     char    *regbuf = NULL;
00179 #endif
00180 
00181 #ifndef STANDALONE_REGISTRY
00182     if (vr_lock == NULL)
00183         return REGERR_FAIL;
00184 #endif
00185     PR_Lock(vr_lock);
00186 
00187     if (!isInited)
00188     {
00189 #if defined(XP_UNIX) && !defined(XP_MACOSX)
00190         /* need browser directory to find the correct registry */
00191         if (app_dir != NULL) {
00192             regbuf = (char*)XP_ALLOC( 10 + XP_STRLEN(app_dir) );
00193             if (regbuf != NULL ) {
00194                 XP_STRCPY( regbuf, app_dir );
00195                 XP_STRCAT( regbuf, "/registry" );
00196             } 
00197             else {
00198                 err = REGERR_MEMORY;
00199             }
00200         } 
00201         if ( err != REGERR_OK )
00202             goto done;
00203 
00204         if (bGlobalRegistry) 
00205             regname = regbuf;
00206 #endif
00207 
00208         /* Open version registry */
00209         err = NR_RegOpen( regname, &vreg );
00210 
00211 #ifndef STANDALONE_REGISTRY
00212         if (err == REGERR_OK) 
00213         {
00214             /* find/set the current nav node */
00215             err = vr_SetCurrentNav( VERSION_NAME, app_dir, NULL );
00216             if ( REGERR_OK != err ) {
00217                 /* couldn't find or set current nav -- big problems! */
00218                 NR_RegClose( vreg );
00219                 goto done;
00220             }
00221         }
00222 
00223 #if defined(XP_UNIX) && !defined(XP_MACOSX)
00224         /* try to open shared Unix registry, but not an error if you can't */
00225         unixreg = NULL;
00226         if (!bGlobalRegistry && err == REGERR_OK ) {
00227             unixver = 0;
00228             if (NR_RegOpen( regbuf, &unixreg ) == REGERR_OK) {
00229                 if (NR_RegGetKey( unixreg, ROOTKEY_VERSIONS, NAVIGATOR_NODE, 
00230                     &navKey) == REGERR_OK) 
00231                 {
00232                     if (NR_RegGetEntryString( unixreg, navKey, CURRENT_VER,
00233                         curstr, sizeof(curstr)) == REGERR_OK ) 
00234                     {
00235                         NR_RegGetKey( unixreg, navKey, curstr, &unixver );
00236                     }
00237                 }
00238             }
00239         }
00240 #endif
00241 
00242         if (err == REGERR_OK) {
00243             /* successfully opened! */
00244             isInited = 1;
00245         }
00246         goto done;
00247 #else
00248         if (err != REGERR_OK)
00249             goto done;
00250 
00251         /* Determine 'curver' key and ensure correct structure by adding */
00252 
00253         /* ...find top-level "Navigator" node (add if missing) */
00254         err = NR_RegAddKey( vreg, ROOTKEY_VERSIONS, NAVIGATOR_NODE, &navKey );
00255         if (err != REGERR_OK)
00256             goto done;
00257 
00258         /* ...look for "Current Version" entry */
00259         err = NR_RegGetEntryString( vreg, navKey, CURRENT_VER, curstr,
00260                                     sizeof(curstr) );
00261         if ( err == REGERR_NOFIND ) {
00262             /* If not found create one with the built-in version */
00263             err = NR_RegSetEntryString( vreg, navKey, CURRENT_VER, VERSION_NAME );
00264             XP_STRCPY( curstr, VERSION_NAME );
00265         }
00266         if ( err != REGERR_OK )
00267             goto done;
00268 
00269         /* ...look for "curstr" child key of the navigator node */
00270         err = NR_RegAddKey( vreg, navKey, curstr, &curver );
00271 
00272         if (err == REGERR_OK) {
00273             /* successfully opened! */
00274             isInited = 1;
00275         }
00276 #endif
00277     }
00278 
00279 done:
00280     PR_Unlock(vr_lock);
00281 #if defined(XP_UNIX) && !defined(XP_MACOSX) && !defined(STANDALONE_REGISTRY)
00282     XP_FREEIF(regbuf);
00283 #endif
00284     return err;
00285 
00286 }   /* Init */
00287 
00288 
00289 
00290 #if defined(XP_WIN) || defined(XP_OS2)
00291 #define VR_FILE_SEP '\\'
00292 #endif
00293 #if defined(XP_MAC) || defined(XP_MACOSX)
00294 #define VR_FILE_SEP ':'
00295 #endif
00296 #ifdef XP_BEOS
00297 #define VR_FILE_SEP '/'
00298 #endif
00299 #ifdef XP_UNIX
00300 #define VR_FILE_SEP '/'
00301 #endif
00302 
00303 static XP_Bool vr_CompareDirs( char *dir1, char *dir2 )
00304 {
00305     int len1,len2;
00306    
00307     XP_ASSERT( dir1 && dir2 );
00308     if (!dir1 || !dir2) return FALSE;
00309 
00310     len1 = XP_STRLEN( dir1 );
00311     len2 = XP_STRLEN( dir2 );
00312 
00313     if ( dir1[len1-1] == VR_FILE_SEP )
00314         len1--;
00315     if ( dir2[len2-1] == VR_FILE_SEP )
00316         len2--;
00317 
00318     if ( len1 != len2 )
00319         return FALSE;
00320 
00321 #if defined(XP_UNIX) && !defined(XP_MACOSX)
00322     return ( XP_STRNCMP(dir1, dir2, len1) == 0 );
00323 #else
00324     return ( XP_STRNCASECMP(dir1, dir2, len1) == 0 );
00325 #endif
00326 }
00327 
00328 
00329 REGERR vr_ParseVersion(char *verstr, VERSION *result)
00330 {
00331 
00332     result->major = result->minor = result->release = result->build = 0;
00333     result->major = atoi(verstr);
00334     while (*verstr && *verstr != '.')
00335         verstr++;
00336     if (*verstr)
00337     {
00338         verstr++;
00339         result->minor = atoi(verstr);
00340         while (*verstr && *verstr != '.')
00341             verstr++;
00342         if (*verstr)
00343         {
00344             verstr++;
00345             result->release = atoi(verstr);
00346             while (*verstr && *verstr != '.')
00347                 verstr++;
00348             if (*verstr)
00349             {
00350                 verstr++;
00351                 result->build = atoi(verstr);
00352                 while (*verstr && *verstr != '.')
00353                     verstr++;
00354             }
00355         }
00356     }
00357 
00358     return REGERR_OK;
00359 
00360 }   /* ParseVersion */
00361 
00362 
00363 
00364 #ifdef USE_CHECKSUM
00365 #define BLKSIZ 16384
00366 
00367 static REGERR vr_GetCheck(char *path, int32 *check)
00368 {
00369 
00370     int fh;
00371     char *buf;
00372     int actual;
00373     char *p;
00374     int i;
00375     int chk;
00376 
00377     XP_ASSERT(path);
00378     XP_ASSERT(check);
00379     
00380     *check = chk = 0;
00381 
00382 #ifdef NEED_XP_FIXES
00383     /* open file for read */
00384     fh = open(path, O_RDONLY| O_BINARY);
00385     if (fh < 0)
00386     {
00387         switch (errno)
00388         { 
00389         case ENOENT:    /* file not found */
00390             return REGERR_NOFILE;
00391 
00392         case EACCES:    /* file in use */
00393         
00394 #ifdef EMFILE        
00395         case EMFILE:    /* too many files open */
00396 #endif
00397         default:
00398             return REGERR_FAIL;
00399         }
00400     }
00401 
00402     buf = malloc(BLKSIZ);
00403     if (!buf)
00404     {
00405         close(fh);
00406         return REGERR_MEMORY;
00407     }
00408 
00409     do
00410     {
00411         /* read a block */
00412         actual = read(fh, buf, BLKSIZ);
00413         /* add to checksum */
00414         for (p=buf, i=0; i<actual; i++, p++)
00415             chk += *p;
00416 
00417         /* if the block was partial, we're done, else loop */
00418     } while (actual == BLKSIZ);
00419 
00420     /* close file */
00421     close(fh);
00422     free(buf);
00423 #endif
00424 
00425     /* return calculated checksum */
00426     *check = chk;
00427 
00428     return REGERR_OK;
00429 
00430 }   /* GetCheck */
00431 
00432 #endif /* USE_CHECKSUM */
00433 
00434 
00435 
00436 static REGERR vr_SetPathname(HREG reg, RKEY key, char *entry, char *dir)
00437 {
00438     REGERR err;
00439     int32  datalen = XP_STRLEN(dir)+1; /* include '\0' */
00440 
00441     err = NR_RegSetEntry( reg, key, entry, REGTYPE_ENTRY_FILE, dir, datalen);
00442 
00443     return err;
00444 }
00445 
00446 
00447 
00448 static REGERR vr_GetPathname(HREG reg, RKEY key, char *entry, char *buf, uint32 sizebuf)
00449 {
00450     REGERR  err;
00451     REGINFO info;
00452     
00453     info.size = sizeof(REGINFO);
00454         
00455 #if !defined(XP_MAC) && !defined(XP_MACOSX)
00456         err = NR_RegGetEntry( reg, key, entry, (void*)buf, &sizebuf );
00457         return err;
00458 #else
00459     
00460     err = NR_RegGetEntryInfo( reg, key, entry, &info );
00461     
00462     if (err != REGERR_OK)
00463         return err;
00464     
00465     if (info.entryType == REGTYPE_ENTRY_FILE ||
00466         info.entryType == REGTYPE_ENTRY_STRING_UTF )
00467     {
00468         err = NR_RegGetEntry( reg, key, entry, (void*)buf, &sizebuf );  
00469     }
00470     else if (info.entryType == REGTYPE_ENTRY_BYTES)
00471     {
00472 
00473         extern char * nr_PathFromMacAlias(const void * alias, uint32 aliasLength);
00474 
00475         #define MAC_ALIAS_BUFFER_SIZE 4000
00476         char stackBuf[MAC_ALIAS_BUFFER_SIZE];
00477         uint32 stackBufSize = MAC_ALIAS_BUFFER_SIZE;
00478         char * tempBuf;
00479 
00480         err = NR_RegGetEntry( reg, key, entry, (void*)stackBuf, &stackBufSize );
00481 
00482         if (err != REGERR_OK)
00483             return err;
00484 
00485         tempBuf = nr_PathFromMacAlias(stackBuf, stackBufSize);
00486 
00487         if (tempBuf == NULL) 
00488         {
00489             /* don't change error w/out changing vr_SetCurrentNav to match */
00490             buf[0] = '\0';
00491             err = REGERR_NOFILE;
00492          }
00493         else 
00494         {
00495             if (XP_STRLEN(tempBuf) > sizebuf)
00496                 err = REGERR_BUFTOOSMALL;
00497             else
00498                 XP_STRCPY(buf, tempBuf);
00499 
00500             XP_FREE(tempBuf);
00501         }
00502     }
00503     else
00504     {
00505         /* what did we put here?? */
00506         err = REGERR_BADTYPE;
00507     }
00508     
00509     return err;
00510 
00511 #endif 
00512     
00513 }
00514 
00515 
00516 
00517 /* create default tree with 'installation' under Navigator */
00518 /* set Current to the installation string */
00519 static REGERR vr_SetCurrentNav( char *installation, char *programPath, char *versionStr)
00520 {
00521     REGERR      err;
00522     REGENUM     state;
00523     RKEY        navKey;
00524     int         bFound;
00525     int         nCopy;
00526     char        regname[MAXREGNAMELEN];
00527     char        dirbuf[MAXREGNAMELEN];
00528 
00529     XP_ASSERT( installation ); /* required */
00530     XP_ASSERT( programPath );  /* required */
00531     if ( !installation || !programPath )
00532         return REGERR_PARAM;
00533 
00534     err = NR_RegAddKey( vreg, ROOTKEY_VERSIONS, NAVIGATOR_NODE, &navKey );
00535     if (err != REGERR_OK)
00536         goto done;
00537 
00538     /* ...look for "Current Version" entry */
00539     err = NR_RegGetEntryString( vreg, navKey, CURRENT_VER, gCurstr, sizeof(gCurstr));
00540     if ( err == REGERR_NOFIND )
00541     {
00542         /* No current installation, we can simply add a new one  */
00543         err = NR_RegAddKey( vreg, navKey, installation, &curver );
00544 
00545         /* ... add Path and Version properties */
00546         if ( err == REGERR_OK ) 
00547         {
00548             err = vr_SetPathname( vreg, curver, NAVHOME, programPath );
00549             if ( REGERR_OK == err && versionStr != NULL && *versionStr != '\0')
00550             {
00551                 err = NR_RegSetEntryString( vreg, curver, VERSTR, versionStr );
00552             }
00553         }
00554 
00555         if ( REGERR_OK == err ) {
00556             /* successfully added, make it the current version */
00557             err = NR_RegSetEntryString(vreg, navKey, CURRENT_VER, installation);
00558         }
00559 
00560         if (err != REGERR_OK)
00561             goto done;
00562     }
00563     else if ( REGERR_OK == err )
00564     {
00565         /* found one: if we're lucky we got the right one */
00566         bFound = FALSE;
00567         err = NR_RegGetKey( vreg, navKey, gCurstr, &curver );
00568         if ( REGERR_OK == err ) {
00569             err = vr_GetPathname( vreg, curver, NAVHOME, dirbuf, sizeof(dirbuf) );
00570             if ( REGERR_OK == err ) {
00571                 bFound = vr_CompareDirs(dirbuf, programPath);
00572             }
00573             else if ( REGERR_NOFIND == err ) {
00574                 /* assume this is the right one since it's 'Current' */
00575                 err = vr_SetPathname( vreg, curver, NAVHOME, programPath );
00576                 bFound = TRUE;
00577             }
00578         }
00579         
00580         /* Look for an existing installation if not found */
00581         state = 0;
00582         while (!bFound && ((err == REGERR_OK) || (err == REGERR_NOFILE)) ) {
00583             err = NR_RegEnumSubkeys( vreg, navKey, &state, gCurstr,
00584                     sizeof(gCurstr), REGENUM_NORMAL );
00585 
00586             if (REGERR_OK == err ) {
00587                 err = vr_GetPathname( vreg, state, NAVHOME, dirbuf, sizeof(dirbuf) );
00588                 if (REGERR_OK == err ) {
00589                     if (vr_CompareDirs( dirbuf, programPath )) {
00590                         bFound = TRUE;
00591                         curver = (RKEY)state;
00592                     }
00593                 }
00594                 else if ( err == REGERR_NOFIND ) {
00595                     /* wasn't a navigator node */
00596                     err = REGERR_OK;
00597                 }
00598             }
00599         }
00600 
00601         /* found the right one, make it current */
00602         if (bFound) {
00603             err = NR_RegSetEntryString( vreg, navKey, CURRENT_VER, gCurstr );
00604             /* update version (curver already set) */
00605             if ( REGERR_OK == err && versionStr != NULL && *versionStr != '\0' ) {
00606                 err = NR_RegSetEntryString( vreg, curver, VERSTR, versionStr );
00607             }
00608         }
00609         /* otherwise if no current installation matches */
00610         else if ( err == REGERR_NOMORE )
00611         {
00612             /* look for an empty slot to put new installation */
00613             nCopy = 1;
00614             XP_STRCPY( regname, installation );
00615             do {
00616                 err = NR_RegGetKey( vreg, navKey, regname, &curver );
00617                 if (err == REGERR_OK) {
00618                     nCopy++;
00619                     sprintf( regname, "%s #%d", installation, nCopy );
00620                 }
00621             } while (err==REGERR_OK);
00622 
00623             if (err != REGERR_NOFIND)
00624                 goto done;  /* real error, bail */
00625 
00626             /* found an unused name -- add it */
00627             err = NR_RegAddKey( vreg, navKey, regname, &curver );
00628             if ( err != REGERR_OK )
00629                 goto done;
00630 
00631             /* add path and version properties */
00632             err = vr_SetPathname( vreg, curver, NAVHOME, programPath );
00633             if ( REGERR_OK == err && versionStr != NULL && *versionStr != '\0' ) {
00634                 err = NR_RegSetEntryString( vreg, curver, VERSTR, versionStr );
00635             }
00636 
00637             if ( REGERR_OK == err ) {
00638                 /* everything's OK, make it current */
00639                 err = NR_RegSetEntryString(vreg,navKey,CURRENT_VER,regname);
00640             }
00641         }
00642     }
00643 done:
00644     return err;
00645 }
00646 
00647 
00648 
00649 
00650 /* assumes registries are open (only use after vr_Init() returns OK).
00651  * For UNIX look first in the global, then in the local if not found
00652  * -- returns both hreg and key of the named node (if found)
00653  */
00654 static REGERR vr_FindKey(char *component_path, HREG *hreg, RKEY *key)
00655 {
00656     REGERR err = REGERR_NOFIND;
00657     RKEY rootkey;
00658 
00659 #if !defined(STANDALONE_REGISTRY) && defined(XP_UNIX) && !defined(XP_MACOSX)
00660     if (unixreg != NULL) {
00661         *hreg = unixreg;
00662         rootkey = UNIX_ROOT(component_path);
00663         if (rootkey)
00664             err = NR_RegGetKey( *hreg, rootkey, component_path, key );
00665         else
00666             err = REGERR_NOFIND;
00667     }
00668     if (unixreg == NULL || err == REGERR_NOFIND ) 
00669 #endif
00670     {
00671         *hreg = vreg;
00672         rootkey = PATH_ROOT(component_path);
00673         if (rootkey)
00674             err = NR_RegGetKey( *hreg, rootkey, component_path, key );
00675         else
00676             err = REGERR_NOFIND;
00677     }
00678 
00679     return err;
00680 }
00681 
00682 
00683 
00684 /* ---------------------------------------------------------------------
00685  * Interface
00686  * ---------------------------------------------------------------------
00687  */
00688 
00689 #ifdef XP_MAC
00690 #pragma export on
00691 #endif
00692 
00693 #ifndef STANDALONE_REGISTRY
00694 VR_INTERFACE(REGERR) VR_PackRegistry(void *userData, nr_RegPackCallbackFunc fn)
00695 {
00696     REGERR err;
00697 
00698     /* make sure vreg (src) is open */
00699     err = vr_Init();
00700     if (err != REGERR_OK)
00701         return err;
00702 
00703     err = NR_RegPack( vreg, userData, fn );
00704 
00705     return err;
00706 
00707 }   /* PackRegistry */
00708 #endif /* STANDALONE_REGISTRY */
00709 
00710 
00711 VR_INTERFACE(REGERR) VR_CreateRegistry( char *installation, char *programPath, char *versionStr )
00712 {
00713     REGERR      err;
00714     char *      regname = vr_findVerRegName();
00715 #if defined(XP_UNIX) && !defined(XP_MACOSX)
00716     char *      regbuf = NULL;
00717 #endif
00718 
00719     if ( installation == NULL || *installation == '\0' )
00720         return REGERR_PARAM;
00721 
00722 #if defined(XP_UNIX) && !defined(XP_MACOSX)
00723 #ifndef STANDALONE_REGISTRY
00724     if (bGlobalRegistry)
00725 #endif 
00726     {
00727         regbuf = (char*)XP_ALLOC( 10 + XP_STRLEN(programPath) );
00728         if (regbuf == NULL) 
00729             return REGERR_MEMORY;
00730 
00731         XP_STRCPY( regbuf, programPath );
00732         XP_STRCAT( regbuf, "registry" );
00733         regname = regbuf;
00734     }
00735 #endif /* XP_UNIX */
00736 
00737     PR_Lock(vr_lock);
00738 
00739     /* automatically creates it if not found */
00740     err = NR_RegOpen( regname, &vreg );
00741     if (err == REGERR_OK) 
00742     {
00743         /* create default tree with 'installation' under Navigator */
00744         /* set Current to the installation string */
00745 
00746         err = vr_SetCurrentNav( installation, programPath, versionStr );
00747 
00748         if ( REGERR_OK == err )
00749             isInited = 1;
00750         else
00751             NR_RegClose( vreg );
00752     }
00753 
00754     PR_Unlock(vr_lock);
00755 
00756 #if defined(XP_UNIX) && !defined(XP_MACOSX)
00757     XP_FREEIF( regbuf );
00758 #endif
00759     return err;
00760 
00761 }   /* CreateRegistry */
00762 
00763 
00764 VR_INTERFACE(REGERR) VR_Close(void)
00765 {
00766     REGERR err = REGERR_OK;
00767 
00768 #ifndef STANDALONE_REGISTRY
00769     if (vr_lock == NULL)
00770         return REGERR_FAIL;
00771 #endif
00772 
00773     PR_Lock(vr_lock);
00774 
00775     if (isInited) {
00776 #if !defined(STANDALONE_REGISTRY) && defined(XP_UNIX) && !defined(XP_MACOSX)
00777         if ( unixreg != NULL )
00778             NR_RegClose( unixreg );
00779 #endif
00780         err = NR_RegClose( vreg );
00781         isInited = 0;
00782     }
00783 
00784     PR_Unlock(vr_lock);
00785 
00786     return err;
00787 }   /* Close */
00788 
00789 
00790 
00791 VR_INTERFACE(REGERR) VR_GetVersion(char *component_path, VERSION *result)
00792 {
00793     REGERR  err;
00794     RKEY    key;
00795     HREG    hreg;
00796     VERSION ver;
00797     char    buf[MAXREGNAMELEN];
00798 
00799     err = vr_Init();
00800     if (err != REGERR_OK)
00801         return err;
00802 
00803     hreg = vreg;
00804 
00805     err = vr_FindKey( component_path, &hreg, &key );
00806     if (err != REGERR_OK)
00807         return err;
00808 
00809     err = NR_RegGetEntryString( hreg, key, VERSTR, buf, sizeof(buf) );
00810     if (err != REGERR_OK)
00811         return err;
00812 
00813     vr_ParseVersion(buf, &ver);
00814 
00815     memcpy(result, &ver, sizeof(VERSION));
00816 
00817     return REGERR_OK;
00818 
00819 }   /* GetVersion */
00820 
00821 
00822 
00823 VR_INTERFACE(REGERR) VR_GetPath(char *component_path, uint32 sizebuf, char *buf)
00824 {
00825     REGERR err;
00826     RKEY key;
00827     HREG hreg;
00828 
00829     err = vr_Init();
00830     if (err != REGERR_OK)
00831         return err;
00832 
00833     hreg = vreg;
00834 
00835     err = vr_FindKey( component_path, &hreg, &key );
00836     if (err != REGERR_OK)
00837         return err;
00838     
00839     err = vr_GetPathname( hreg, key, PATHSTR, buf, sizebuf );
00840 
00841     return err;
00842 
00843 }   /* GetPath */
00844 
00845 
00846 
00847 VR_INTERFACE(REGERR) VR_SetDefaultDirectory(char *component_path, char *directory)
00848 {
00849     REGERR err;
00850     RKEY rootkey;
00851     RKEY key;
00852 
00853     err = vr_Init();
00854     if (err != REGERR_OK)
00855         return err;
00856 
00857     rootkey = PATH_ROOT(component_path);
00858 
00859     err = NR_RegGetKey( vreg, rootkey, component_path, &key );
00860     if (err != REGERR_OK)
00861         return err;
00862     
00863     err = vr_SetPathname( vreg, key, DIRSTR, directory );
00864 
00865     return err;
00866 }
00867 
00868 
00869 
00870 VR_INTERFACE(REGERR) VR_GetDefaultDirectory(char *component_path, uint32 sizebuf, char *buf)
00871 {
00872     REGERR err;
00873     RKEY key;
00874     HREG hreg;
00875 
00876     err = vr_Init();
00877     if (err != REGERR_OK)
00878         return err;
00879 
00880     hreg = vreg;
00881 
00882     err = vr_FindKey( component_path, &hreg, &key );
00883     if (err != REGERR_OK)
00884         return err;
00885 
00886     err = vr_GetPathname( hreg, key, DIRSTR, buf, sizebuf );
00887 
00888     return err;
00889 }
00890 
00891 
00892 
00893 VR_INTERFACE(REGERR) VR_Install(char *component_path, char *filepath, char *version, int bDirectory)
00894 {
00895     REGERR err;
00896     RKEY rootKey;
00897     RKEY key;
00898 
00899     /* Initialize the registry in case this is first call */
00900     err = vr_Init();
00901     if (err != REGERR_OK)
00902         return err;
00903 
00904     /* Use curver if path is relative */
00905     rootKey = PATH_ROOT(component_path);
00906 
00907     /* Make sure path components (keys) exist by calling Add */
00908     /* (special "" component must always exist, and Add fails) */
00909     if ( component_path != NULL && *component_path == '\0' ) {
00910         err = NR_RegGetKey( vreg, rootKey, component_path, &key );
00911     }
00912     else {
00913         err = NR_RegAddKey( vreg, rootKey, component_path, &key );
00914     }
00915     if (err != REGERR_OK)
00916         return err;
00917 
00918     if ( version != NULL && *version != '\0' ) {
00919         /* Add "Version" entry with values like "4.0.0.0" */
00920         err = NR_RegSetEntryString( vreg, key, VERSTR, version );
00921         if (err != REGERR_OK)
00922             goto abort;
00923     }
00924 
00925     if ( filepath != NULL && *filepath != '\0' ) {
00926         /* add "Path" entry */
00927         err = vr_SetPathname( vreg, key, (bDirectory)?DIRSTR:PATHSTR, filepath );
00928 
00929         if (err != REGERR_OK)
00930             goto abort;
00931     }
00932 
00933     return REGERR_OK;
00934 
00935 abort:
00936     NR_RegDeleteKey( vreg, rootKey, component_path );
00937     return err;
00938 
00939 }   /* Install */
00940 
00941 
00942 
00943 VR_INTERFACE(REGERR) VR_Remove(char *component_path)
00944 {
00945     REGERR err;
00946     RKEY rootkey;
00947 
00948     err = vr_Init();
00949     if (err != REGERR_OK)
00950         return err;
00951 
00952     rootkey = PATH_ROOT(component_path);
00953 
00954     return NR_RegDeleteKey( vreg, rootkey, component_path );
00955 
00956 }   /* Remove */
00957 
00958 VR_INTERFACE(REGERR) VR_Enum(char *component_path, REGENUM *state, 
00959                                          char *buffer, uint32 buflen)
00960 {
00961     REGERR  err;
00962     RKEY    rootkey;
00963     RKEY    key;
00964 
00965     err = vr_Init();
00966     if (err != REGERR_OK)
00967         return err;
00968 
00969     if ( component_path == NULL )
00970         rootkey = ROOTKEY_VERSIONS;
00971     else
00972         rootkey = PATH_ROOT(component_path);
00973 
00974     err = NR_RegGetKey( vreg, rootkey, component_path, &key );
00975     if (err != REGERR_OK)
00976         return err;
00977 
00978     err = NR_RegEnumSubkeys( vreg, key, state, buffer, buflen, REGENUM_DEPTH_FIRST);
00979 
00980     return err;
00981 
00982 }   /* Enum */
00983 
00984 VR_INTERFACE(REGERR) VR_InRegistry(char *component_path)
00985 {
00986     REGERR err;
00987     RKEY key;
00988     HREG hreg;
00989 
00990     err = vr_Init();
00991     if (err != REGERR_OK)
00992         return err;
00993 
00994     return vr_FindKey( component_path, &hreg, &key );
00995 }   /* InRegistry */
00996 
00997 
00998 
00999 VR_INTERFACE(REGERR) VR_ValidateComponent(char *component_path)
01000 {
01001     REGERR err;
01002     RKEY key;
01003     char path[MAXREGPATHLEN];
01004     HREG hreg;
01005 
01006 
01007 #ifdef USE_CHECKSUM
01008     char buf[MAXREGNAMELEN];
01009     long calculatedCheck;
01010     int storedCheck;
01011 #endif
01012 
01013     err = vr_Init();
01014     if (err != REGERR_OK)
01015         return err;
01016 
01017     err = vr_FindKey( component_path, &hreg, &key );
01018     if ( err != REGERR_OK )
01019         return err;
01020 
01021     err = VR_GetPath( component_path, sizeof(path), path );
01022     if ( err != REGERR_OK ) {
01023         if ( err == REGERR_NOFIND ) {
01024             err = REGERR_NOPATH;
01025         }
01026         return err;
01027     }
01028 
01029     {
01030         uint32 len;
01031         struct stat  statStruct;
01032 
01033         /* directories are stored with a trailing separator -- if we */
01034         /* have one of these we have to remove it for stat to work */
01035         len = strlen(path);
01036         if ( path[len-1] == VR_FILE_SEP )
01037             path[len-1] = 0;
01038 
01039         if ( stat ( path, &statStruct ) != 0 ) {
01040             err = REGERR_NOFILE;
01041         }
01042     }
01043     if (err != REGERR_OK)
01044         return err;
01045 
01046 
01047 #if defined(USE_CHECKSUM) && !defined(XP_UNIX)
01048     err = NR_RegGetEntryString( vreg, key, CHKSTR, buf, sizeof(buf) );
01049     if (err != REGERR_OK)
01050         return err;
01051 
01052     storedCheck = atoi(buf);
01053 
01054     err = vr_GetCheck(filepath, &calculatedCheck);
01055     if (err != REGERR_OK)
01056         return err;
01057 
01058     if (storedCheck != calculatedCheck)
01059     {
01060         return REGERR_BADCHECK;
01061     }
01062 #endif /* USE_CHECKSUM */
01063 
01064     return REGERR_OK;
01065 
01066 }   /* CheckEntry */
01067 
01068 
01069 
01070 VR_INTERFACE(REGERR) VR_SetRegDirectory(const char *path)
01071 {
01072     char *tmp;
01073 
01074     tmp = XP_STRDUP(path);
01075     if (NULL == tmp) {
01076         return REGERR_MEMORY;
01077     }
01078 
01079     PR_Lock(vr_lock);
01080 
01081     XP_FREEIF(app_dir);
01082     app_dir = tmp;
01083     
01084     PR_Unlock(vr_lock);
01085 
01086     return REGERR_OK;
01087 }
01088 
01089 
01090 
01091 VR_INTERFACE(REGERR) VR_SetRefCount(char *component_path, int refcount)
01092 {
01093     REGERR err;
01094     RKEY rootKey;
01095     RKEY key = 0;
01096     char rcstr[MAXREGNAMELEN];
01097 
01098     err = vr_Init();
01099     if (err != REGERR_OK)
01100         return err;
01101 
01102     /* Use curver if path is relative */
01103     rootKey = PATH_ROOT(component_path);
01104 
01105     /* Make sure path components (keys) exist by calling Add */
01106     /* (special "" component must always exist, and Add fails) */
01107     if ( component_path != NULL && *component_path == '\0' ) {
01108         err = REGERR_PARAM;
01109     }
01110     else {
01111         err = NR_RegAddKey( vreg, rootKey, component_path, &key );
01112     }
01113     
01114     if (err != REGERR_OK)
01115         return err;
01116 
01117     *rcstr = '\0';
01118     /* itoa(refcount, rcstr, 10); */
01119     XP_SPRINTF(rcstr, "%d", refcount);
01120     
01121     if ( rcstr != NULL && *rcstr != '\0' ) {
01122         /* Add "RefCount" */
01123         err = NR_RegSetEntryString( vreg, key, REFCSTR, rcstr );
01124     }
01125     
01126     return err;
01127 }   /* SetRefCount */
01128 
01129 
01130 
01131 VR_INTERFACE(REGERR) VR_GetRefCount(char *component_path, int *result)
01132 {
01133     REGERR  err;
01134     RKEY    rootkey;
01135     RKEY    key;
01136     char    buf[MAXREGNAMELEN];
01137 
01138     *result = -1; 
01139 
01140     err = vr_Init();
01141     if (err != REGERR_OK)
01142         return err;
01143 
01144     /* "Uninstall" only happens in the writable registry, so no
01145      * need to search the shared one on Unix using vr_FindKey()
01146      */
01147     rootkey = PATH_ROOT(component_path);
01148     err = NR_RegGetKey( vreg, rootkey, component_path, &key );
01149     if (err != REGERR_OK)
01150         return err;
01151 
01152     err = NR_RegGetEntryString( vreg, key, REFCSTR, buf, sizeof(buf) );
01153     if (err != REGERR_OK)
01154         return err;
01155 
01156     *result = atoi( buf );
01157 
01158     return REGERR_OK;
01159 
01160 }   /* GetRefCount */
01161 
01162 #ifdef XP_MAC
01163 #pragma export reset
01164 #endif
01165 
01166 static REGERR vr_GetUninstallItemPath(char *regPackageName, char *regbuf, uint32 regbuflen)
01167 {
01168     XP_Bool bSharedUninstall = FALSE;
01169     XP_Bool bNavPackage = FALSE;
01170     uint32 len = 0;
01171     uint32 sharedstrlen = 0;
01172     uint32 curstrlen = 0;
01173     uint32 curregbuflen = 0;
01174 
01175     /* determine install type */
01176     if (*regPackageName == '\0') {
01177         bNavPackage = TRUE;
01178     }
01179     else if ( *regPackageName == PATHDEL) {
01180         bSharedUninstall = TRUE;
01181     }
01182 
01183     /* create uninstall path prefix */
01184     len = XP_STRLEN(REG_UNINSTALL_DIR);
01185     if (len < regbuflen)
01186     {
01187         XP_STRCPY( regbuf, REG_UNINSTALL_DIR );
01188     }
01189     else
01190     {
01191         return REGERR_BUFTOOSMALL;
01192     }
01193     if (bSharedUninstall)
01194     {
01195         sharedstrlen = XP_STRLEN(SHAREDSTR);
01196         if (sharedstrlen < (regbuflen - len))
01197             XP_STRCAT( regbuf, SHAREDSTR );
01198         else 
01199             return REGERR_BUFTOOSMALL;
01200     }
01201     else
01202     {
01203         curstrlen = XP_STRLEN(gCurstr);
01204         if (curstrlen < (regbuflen - len))
01205             XP_STRCAT( regbuf, gCurstr );
01206         else 
01207             return REGERR_BUFTOOSMALL;
01208         if (1 < (regbuflen - len - curstrlen))
01209             XP_STRCAT( regbuf, "/" );
01210         else 
01211             return REGERR_BUFTOOSMALL;
01212     }  
01213 
01214     /* add final uninstall node name */
01215     len = 0;
01216     curregbuflen = XP_STRLEN(regbuf);
01217     if ( bNavPackage ) {
01218         len = XP_STRLEN(UNINSTALL_NAV_STR);
01219         if (len < (regbuflen - curregbuflen))
01220             XP_STRCAT( regbuf, UNINSTALL_NAV_STR );
01221         else 
01222             return REGERR_BUFTOOSMALL;
01223     }
01224     else {
01225         len = XP_STRLEN(regPackageName);
01226         if (len < (regbuflen - curregbuflen))
01227             XP_STRCAT( regbuf, regPackageName );
01228         else 
01229             return REGERR_BUFTOOSMALL;
01230     }
01231     return REGERR_OK;
01232 }
01233 
01234 
01239 static REGERR vr_convertPackageName(char *regPackageName, char *convertedPackageName, uint32 convertedDataLength)
01240 {
01241     uint32 length = 0;
01242     uint32 i;
01243     uint32 j = 0;
01244 
01245     length = XP_STRLEN(regPackageName);
01246     
01247     if (convertedDataLength <= length)
01248         return REGERR_BUFTOOSMALL;
01249 
01250     for (i=0, j=0; i<length; i++, j++)
01251     {
01252         if (j < (convertedDataLength-1))
01253         {
01254             convertedPackageName[j] = regPackageName[i];
01255         }
01256         else
01257         {
01258             return REGERR_BUFTOOSMALL;
01259         }
01260         if (regPackageName[i] == '_')
01261         {
01262             if ((j+1) < (convertedDataLength-1))
01263             {
01264                 convertedPackageName[j+1] = '_';
01265             }
01266             else
01267             {
01268                 return REGERR_BUFTOOSMALL;
01269             }
01270             j = j + 1;
01271         }
01272     }
01273 
01274     if (convertedPackageName[j-1] == '/')
01275         convertedPackageName[j-1] = '\0';
01276     else
01277     {
01278         if (j < convertedDataLength)
01279         {
01280             convertedPackageName[j] = '\0';
01281         }
01282         else
01283         {
01284             return REGERR_BUFTOOSMALL;
01285         }
01286     }
01287 
01288     length = 0;
01289     length = XP_STRLEN(convertedPackageName);
01290     for (i=1; i<length; i++)
01291     {
01292         if (convertedPackageName[i] == '/')
01293             convertedPackageName[i] = '_';
01294     }
01295 
01296     return REGERR_OK;
01297 }
01298 
01299 static REGERR vr_unmanglePackageName(char *mangledPackageName, char *regPackageName, uint32 regPackageLength)
01300 {
01301     uint32 length = 0;
01302     uint32 i = 0;
01303     uint32 j = 0;
01304 
01305     length = XP_STRLEN(mangledPackageName);
01306     
01307     if (regPackageLength <= length)
01308         return REGERR_BUFTOOSMALL;
01309 
01310     while (i < length)
01311     {
01312         if ((mangledPackageName[i] != '_') || (i == length-1)){
01313             if (j < (regPackageLength - 1))
01314                 regPackageName[j] = mangledPackageName[i];
01315             else
01316                 return REGERR_BUFTOOSMALL;
01317             j = j + 1;  
01318             i = i + 1;
01319         } else if (mangledPackageName[i + 1] != '_') { 
01320             if (j < (regPackageLength - 1))
01321                 regPackageName[j] = '/';
01322             else
01323                 return REGERR_BUFTOOSMALL;
01324             j = j + 1;
01325             i = i + 1;
01326         } else {
01327             if (j < (regPackageLength - 1))
01328                 regPackageName[j] = '_';
01329             else
01330                 return REGERR_BUFTOOSMALL;
01331             j = j + 1;
01332             i = i + 2;
01333         }
01334     }
01335     if (j < regPackageLength)
01336         regPackageName[j] = '\0';
01337     else
01338         return REGERR_BUFTOOSMALL;
01339     return REGERR_OK;
01340 }
01341 
01342 #ifdef XP_MAC
01343 #pragma export on
01344 #endif
01345 
01346 VR_INTERFACE(REGERR) VR_UninstallCreateNode(char *regPackageName, char *userPackageName)
01347 {
01348     REGERR err;
01349     RKEY key = 0;
01350     char *regbuf;
01351     uint32 regbuflen = 0;
01352 
01353     err = vr_Init();
01354     if (err != REGERR_OK)
01355         return err;
01356 
01357     if ( regPackageName == NULL )
01358         err = REGERR_PARAM;
01359    
01360     if ( userPackageName == NULL)
01361         err = REGERR_PARAM;
01362 
01363     regbuflen = 256 + XP_STRLEN(regPackageName);
01364     regbuf = (char*)XP_ALLOC( regbuflen );
01365     if (regbuf != NULL )
01366     {
01367         err = vr_GetUninstallItemPath(regPackageName, regbuf, regbuflen);  
01368         if (err != REGERR_OK)
01369         {
01370             XP_FREE(regbuf);
01371             return err;
01372         }
01373         err = NR_RegAddKey( vreg, ROOTKEY_PRIVATE, regbuf, &key );
01374         XP_FREE(regbuf);
01375     }
01376     else
01377     {
01378         err = REGERR_MEMORY;
01379     }
01380 
01381     if (err == REGERR_OK)
01382         err = NR_RegSetEntryString(vreg, key, PACKAGENAMESTR, userPackageName);
01383   
01384     return err;
01385 
01386 }   /* UninstallCreateNode */
01387 
01388 VR_INTERFACE(REGERR) VR_GetUninstallUserName(char *regPackageName, char *outbuf, uint32 buflen)
01389 {
01390     REGERR err;
01391     RKEY key = 0;
01392     char *regbuf = NULL;
01393     char *convertedName = NULL;
01394     uint32 convertedDataLength = 0;
01395     uint32 regbuflen = 0;
01396 
01397     err = vr_Init();
01398     if (err != REGERR_OK)
01399         return err;
01400 
01401     if ( regPackageName == NULL || *regPackageName == '\0' || outbuf == NULL )
01402         return REGERR_PARAM;
01403    
01404     convertedDataLength = 2 * XP_STRLEN(regPackageName) + 1;
01405     convertedName = (char*)XP_ALLOC(convertedDataLength);
01406     if (convertedName == NULL ) {
01407         err = REGERR_MEMORY;
01408         return err;
01409     }
01410   
01411     err = vr_convertPackageName(regPackageName, convertedName, convertedDataLength);
01412     if (err != REGERR_OK) {
01413         XP_FREE(convertedName);
01414         return err;
01415     }
01416     regbuflen = 256 + XP_STRLEN(convertedName);
01417     regbuf = (char*)XP_ALLOC( regbuflen );
01418     if (regbuf == NULL ) {
01419         err = REGERR_MEMORY;
01420     } else {
01421         err = vr_GetUninstallItemPath(convertedName, regbuf, regbuflen);
01422         if (err == REGERR_OK) {
01423             err = NR_RegGetKey( vreg, ROOTKEY_PRIVATE, regbuf, &key );
01424         }
01425         XP_FREE(regbuf);
01426     }
01427 
01428     if (err == REGERR_OK)
01429         err = NR_RegGetEntryString( vreg, key, PACKAGENAMESTR, outbuf, buflen );
01430   
01431     XP_FREE(convertedName);
01432     return err;
01433 
01434 }   /* GetUninstallName */
01435 
01436 VR_INTERFACE(REGERR) VR_UninstallAddFileToList(char *regPackageName, char *vrName)
01437 {
01438     REGERR err;
01439     RKEY key = 0;
01440     char *regbuf;
01441     uint32 regbuflen = 0;
01442     uint32 curregbuflen = 0;
01443     uint32 len = 0;
01444     
01445     err = vr_Init();
01446     if (err != REGERR_OK)
01447         return err;
01448 
01449     if ( regPackageName == NULL )
01450         err = REGERR_PARAM;
01451 
01452     if ( vrName == NULL )
01453         err = REGERR_PARAM;
01454 
01455     regbuflen = 256 + XP_STRLEN(regPackageName);
01456     regbuf = (char*)XP_ALLOC( regbuflen );
01457     if (regbuf != NULL )
01458     {
01459         err = vr_GetUninstallItemPath(regPackageName, regbuf, regbuflen);
01460         if (err == REGERR_OK)
01461         {
01462             curregbuflen = XP_STRLEN(regbuf);
01463             len = XP_STRLEN(SHAREDFILESSTR);
01464             if (len < (regbuflen - curregbuflen))
01465             {
01466                 XP_STRCAT(regbuf, SHAREDFILESSTR);
01467                 err = NR_RegAddKey( vreg, ROOTKEY_PRIVATE, regbuf, &key );
01468             }
01469             else
01470                 err = REGERR_BUFTOOSMALL;
01471         }
01472         XP_FREEIF(regbuf);
01473     }
01474     else
01475     {
01476         err = REGERR_MEMORY;
01477     }
01478 
01479     if (err == REGERR_OK)
01480         err = NR_RegSetEntryString( vreg, key, vrName, "");
01481   
01482     return err;
01483 
01484 }   /* UninstallAddFileToList */
01485 
01486 VR_INTERFACE(REGERR) VR_UninstallFileExistsInList(char *regPackageName, char *vrName)
01487 {
01488     REGERR err;
01489     RKEY key = 0;
01490     char *regbuf;
01491     char  sharedfilesstr[MAXREGNAMELEN];
01492     uint32 regbuflen = 0;
01493     uint32 curregbuflen = 0;
01494     uint32 len = 0;
01495     
01496     err = vr_Init();
01497     if (err != REGERR_OK)
01498         return err;
01499 
01500     if ( regPackageName == NULL )
01501         err = REGERR_PARAM;
01502 
01503     if ( vrName == NULL )
01504         err = REGERR_PARAM;
01505 
01506     regbuflen = 256 + XP_STRLEN(regPackageName);
01507     regbuf = (char*)XP_ALLOC( regbuflen );
01508     if (regbuf != NULL )
01509     {
01510         err = vr_GetUninstallItemPath(regPackageName, regbuf, regbuflen);
01511         if (err == REGERR_OK)
01512         {
01513             curregbuflen = XP_STRLEN(regbuf);
01514             len = XP_STRLEN(SHAREDFILESSTR);
01515             if (len < (regbuflen - curregbuflen))
01516             {
01517                 XP_STRCAT(regbuf, SHAREDFILESSTR);
01518                 err = NR_RegGetKey( vreg, ROOTKEY_PRIVATE, regbuf, &key );
01519             }
01520             else
01521                 err = REGERR_BUFTOOSMALL;
01522         }
01523         XP_FREEIF(regbuf);
01524     }
01525     else
01526     {
01527         err = REGERR_MEMORY;
01528     }
01529     
01530     if (err == REGERR_OK)
01531         err = NR_RegGetEntryString( vreg, key, vrName, sharedfilesstr,
01532                                     sizeof(sharedfilesstr) );
01533     return err;
01534 
01535 }   /* UninstallFileExistsInList */
01536 
01537 VR_INTERFACE(REGERR) VR_UninstallEnumSharedFiles(char *component_path, REGENUM *state, 
01538                                          char *buffer, uint32 buflen)
01539 {
01540     REGERR err;
01541     RKEY key = 0;
01542     char *regbuf;
01543     char *converted_component_path;
01544     uint32 convertedDataLength = 0;
01545     uint32 regbuflen = 0;
01546     uint32 curregbuflen = 0;
01547     uint32 len = 0;
01548  
01549     err = vr_Init();
01550     if (err != REGERR_OK)
01551         return err;
01552 
01553     if ( component_path == NULL )
01554         return REGERR_PARAM;
01555 
01556     convertedDataLength = 2 * XP_STRLEN(component_path) + 1;
01557     converted_component_path = (char*)XP_ALLOC(convertedDataLength);
01558     if (converted_component_path == NULL ) {
01559         err = REGERR_MEMORY;
01560         return err;
01561     }
01562     err = vr_convertPackageName(component_path, converted_component_path, convertedDataLength);
01563     if (err != REGERR_OK)
01564     {
01565         XP_FREEIF(converted_component_path);
01566         return err;
01567     }
01568 
01569     regbuflen = 256 + XP_STRLEN(converted_component_path);
01570     regbuf = (char*)XP_ALLOC( regbuflen );
01571     if (regbuf != NULL )
01572     {
01573         err = vr_GetUninstallItemPath(converted_component_path, regbuf, regbuflen); 
01574         if (err == REGERR_OK)
01575         {
01576             curregbuflen = XP_STRLEN(regbuf);
01577             len = XP_STRLEN(SHAREDFILESSTR);
01578             if (len < (regbuflen - curregbuflen))
01579             {
01580                  XP_STRCAT(regbuf, SHAREDFILESSTR);
01581                  err = NR_RegGetKey( vreg, ROOTKEY_PRIVATE, regbuf, &key );
01582             }
01583             else
01584                 err = REGERR_BUFTOOSMALL;
01585         }
01586         XP_FREE(regbuf);
01587     }
01588     else
01589     {
01590         err = REGERR_MEMORY;
01591     }
01592     
01593     XP_FREE(converted_component_path);
01594 
01595     if (err == REGERR_OK)
01596         err = NR_RegEnumEntries( vreg, key, state, buffer, buflen, NULL);
01597 
01598     return err;
01599 
01600 }   /* UninstallEnumSharedFiles */
01601 
01602 VR_INTERFACE(REGERR) VR_UninstallDeleteFileFromList(char *component_path, char *vrName)
01603 {
01604     REGERR err;
01605     RKEY key = 0;
01606     char *regbuf;
01607     char *converted_component_path;
01608     uint32 convertedDataLength = 0;
01609     uint32 regbuflen = 0;
01610     uint32 curregbuflen = 0;
01611     uint32 len = 0;
01612         
01613     err = vr_Init();
01614     if (err != REGERR_OK)
01615         return err;
01616 
01617     if ( component_path == NULL )
01618         err = REGERR_PARAM;
01619 
01620     if ( vrName == NULL )
01621         err = REGERR_PARAM;
01622 
01623     convertedDataLength = 2 * XP_STRLEN(component_path) + 1;
01624     converted_component_path = (char*)XP_ALLOC(convertedDataLength);
01625     if (converted_component_path == NULL ) {
01626         err = REGERR_MEMORY;
01627         return err;
01628     }
01629     err = vr_convertPackageName(component_path, converted_component_path, convertedDataLength);
01630     if (err != REGERR_OK)
01631     {
01632         XP_FREEIF(converted_component_path);
01633         return err;
01634     }
01635 
01636     regbuflen = 256 + XP_STRLEN(converted_component_path);
01637     regbuf = (char*)XP_ALLOC( regbuflen );
01638     if (regbuf != NULL )
01639     {
01640         err = vr_GetUninstallItemPath(converted_component_path, regbuf, regbuflen);  
01641          if (err == REGERR_OK)
01642         {
01643             curregbuflen = XP_STRLEN(regbuf);
01644             len = XP_STRLEN(SHAREDFILESSTR);
01645             if (len < (regbuflen - curregbuflen))
01646             {
01647                 XP_STRCAT(regbuf, SHAREDFILESSTR);
01648                 err = NR_RegGetKey( vreg, ROOTKEY_PRIVATE, regbuf, &key );
01649             }
01650             else
01651                 err = REGERR_BUFTOOSMALL;
01652         }
01653         XP_FREE(regbuf);
01654     }
01655     else
01656     {
01657         err = REGERR_MEMORY;
01658     }
01659     
01660     XP_FREE(converted_component_path);
01661 
01662     if (err == REGERR_OK)
01663         err = NR_RegDeleteEntry( vreg, key, vrName);
01664 
01665     return err;
01666 
01667 }   /* UninstallDeleteFileFromList */
01668 
01669 VR_INTERFACE(REGERR) VR_UninstallDeleteSharedFilesKey(char *component_path)
01670 {
01671     REGERR err;
01672     char *regbuf;
01673     char *converted_component_path;
01674     uint32 convertedDataLength = 0;
01675     uint32 regbuflen = 0;
01676     uint32 curregbuflen = 0;
01677     uint32 len = 0;
01678         
01679     err = vr_Init();
01680     if (err != REGERR_OK)
01681         return err;
01682 
01683     if ( component_path == NULL )
01684         err = REGERR_PARAM;
01685 
01686     convertedDataLength = 2 * XP_STRLEN(component_path) + 1;
01687     converted_component_path = (char*)XP_ALLOC(convertedDataLength);
01688     if (converted_component_path == NULL ) {
01689         err = REGERR_MEMORY;
01690         return err;
01691     }
01692     err = vr_convertPackageName(component_path, converted_component_path, convertedDataLength);
01693     if (err != REGERR_OK)
01694     {
01695         XP_FREEIF(converted_component_path);
01696         return err;
01697     }
01698 
01699     regbuflen = 256 + XP_STRLEN(converted_component_path);
01700     regbuf = (char*)XP_ALLOC( regbuflen );
01701     if (regbuf != NULL )
01702     {
01703         err = vr_GetUninstallItemPath(converted_component_path, regbuf, regbuflen); 
01704         if (err == REGERR_OK)
01705         {
01706             curregbuflen = XP_STRLEN(regbuf);
01707             len = XP_STRLEN(SHAREDFILESSTR);
01708             if (len < (regbuflen - curregbuflen))
01709             {
01710                 XP_STRCAT(regbuf, SHAREDFILESSTR);
01711                 err = NR_RegDeleteKey( vreg, ROOTKEY_PRIVATE, regbuf );
01712             }
01713             else
01714                 err = REGERR_BUFTOOSMALL;
01715         }
01716         XP_FREE(regbuf);
01717     }
01718     else
01719     {
01720         err = REGERR_MEMORY;
01721     }
01722 
01723     XP_FREE(converted_component_path);
01724     return err;
01725 
01726 }   /* UninstallDeleteSharedFilesKey */
01727 
01728 VR_INTERFACE(REGERR) VR_UninstallDestroy(char *component_path)
01729 {
01730     REGERR err;
01731     char *regbuf;
01732     char *converted_component_path;
01733     uint32 convertedDataLength = 0;
01734     uint32 regbuflen = 0;
01735         
01736     err = vr_Init();
01737     if (err != REGERR_OK)
01738         return err;
01739 
01740     if ( component_path == NULL )
01741         err = REGERR_PARAM;
01742     
01743     convertedDataLength = 2 * XP_STRLEN(component_path) + 1;
01744     converted_component_path = (char*)XP_ALLOC(convertedDataLength);
01745     if (converted_component_path == NULL ) {
01746         err = REGERR_MEMORY;
01747         return err;
01748     }
01749     err = vr_convertPackageName(component_path, converted_component_path, convertedDataLength);
01750     if (err != REGERR_OK)
01751     {
01752         XP_FREEIF(converted_component_path);
01753         return err;
01754     }
01755 
01756     regbuflen = 256 + XP_STRLEN(converted_component_path);
01757     regbuf = (char*)XP_ALLOC( regbuflen );
01758     if (regbuf != NULL )
01759     {
01760         err = vr_GetUninstallItemPath(converted_component_path, regbuf, regbuflen);  
01761         if (err == REGERR_OK)
01762         {
01763             err = NR_RegDeleteKey( vreg, ROOTKEY_PRIVATE, regbuf );
01764         }
01765         else
01766         {
01767             err = REGERR_BUFTOOSMALL;
01768         }
01769         XP_FREE(regbuf);
01770     }
01771     else
01772     {
01773         err = REGERR_MEMORY;
01774     }
01775     
01776     XP_FREE(converted_component_path);
01777     return err;
01778 
01779 }   /* UninstallDestroy */
01780 
01781 VR_INTERFACE(REGERR) VR_EnumUninstall(REGENUM *state, char* userPackageName,
01782                                     int32 len1, char*regPackageName, int32 len2, XP_Bool bSharedList)
01783 {
01784     REGERR err;
01785     RKEY key;
01786     RKEY key1;
01787     char regbuf[MAXREGPATHLEN+1] = {0};
01788     char temp[MAXREGPATHLEN+1] = {0};
01789    
01790     err = vr_Init();
01791     if (err != REGERR_OK)
01792         return err;
01793 
01794     XP_STRCPY( regbuf, REG_UNINSTALL_DIR );
01795     if (bSharedList)
01796     {
01797         XP_STRCAT( regbuf, SHAREDSTR );
01798     }
01799     else
01800     {
01801         XP_STRCAT( regbuf, gCurstr );
01802     }  
01803                    
01804     err = NR_RegGetKey( vreg, ROOTKEY_PRIVATE, regbuf, &key );
01805     if (err != REGERR_OK)
01806         return err;
01807 
01808     *regbuf = '\0';
01809     *userPackageName = '\0';
01810     err = NR_RegEnumSubkeys( vreg, key, state, regbuf, sizeof(regbuf), REGENUM_CHILDREN);
01811 
01812     if (err == REGERR_OK && !bSharedList )
01813     {
01814         if (XP_STRCMP(regbuf, UNINSTALL_NAV_STR) == 0)
01815         {
01816             /* skip Communicator package, get the next one instead */
01817             err = NR_RegEnumSubkeys( vreg, key, state, regbuf, sizeof(regbuf), REGENUM_CHILDREN);
01818         }
01819     }
01820     if (err != REGERR_OK)
01821         return err;
01822 
01823     err = NR_RegGetKey( vreg, key, regbuf, &key1 );
01824     if (err != REGERR_OK)
01825         return err;
01826 
01827     err = NR_RegGetEntryString( vreg, key1, PACKAGENAMESTR, userPackageName, len1);
01828 
01829     if (err != REGERR_OK)
01830     {
01831         *userPackageName = '\0';
01832         return err;
01833     }
01834 
01835     if (len2 <= (int32)XP_STRLEN(regbuf))
01836     {
01837         err =  REGERR_BUFTOOSMALL;
01838         *userPackageName = '\0';
01839         return err;
01840     }
01841     
01842     *regPackageName = '\0';
01843     if (bSharedList)
01844     {
01845         XP_STRCPY(temp, "/");
01846         XP_STRCAT(temp, regbuf);
01847         *regbuf = '\0';
01848         XP_STRCPY(regbuf, temp);
01849     }
01850 
01851     err = vr_unmanglePackageName(regbuf, regPackageName, len2);
01852     return err;
01853 
01854 }   /* EnumUninstall */
01855 
01856 #ifdef XP_MAC
01857 #pragma export reset
01858 #endif
01859 
01860 /* EOF: VerReg.c */