PageRenderTime 134ms CodeModel.GetById 18ms app.highlight 106ms RepoModel.GetById 1ms app.codeStats 0ms

/modules/libreg/src/VerReg.c

http://github.com/zpao/v8monkey
C | 1766 lines | 1289 code | 335 blank | 142 comment | 448 complexity | 585a667d7e1ccfc5071bd565b7513bc6 MD5 | raw file
   1/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
   2 *
   3 * ***** BEGIN LICENSE BLOCK *****
   4 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
   5 *
   6 * The contents of this file are subject to the Mozilla Public License Version
   7 * 1.1 (the "License"); you may not use this file except in compliance with
   8 * the License. You may obtain a copy of the License at
   9 * http://www.mozilla.org/MPL/
  10 *
  11 * Software distributed under the License is distributed on an "AS IS" basis,
  12 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  13 * for the specific language governing rights and limitations under the
  14 * License.
  15 *
  16 * The Original Code is Mozilla Communicator client code, released
  17 * March 31, 1998.
  18 *
  19 * The Initial Developer of the Original Code is
  20 * Netscape Communications Corporation.
  21 * Portions created by the Initial Developer are Copyright (C) 1998
  22 * the Initial Developer. All Rights Reserved.
  23 *
  24 * Contributor(s):
  25 *   Daniel Veditz <dveditz@netscape.com>
  26 *
  27 * Alternatively, the contents of this file may be used under the terms of
  28 * either the GNU General Public License Version 2 or later (the "GPL"), or
  29 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  30 * in which case the provisions of the GPL or the LGPL are applicable instead
  31 * of those above. If you wish to allow use of your version of this file only
  32 * under the terms of either the GPL or the LGPL, and not to allow others to
  33 * use your version of this file under the terms of the MPL, indicate your
  34 * decision by deleting the provisions above and replace them with the notice
  35 * and other provisions required by the GPL or the LGPL. If you do not delete
  36 * the provisions above, a recipient may use your version of this file under
  37 * the terms of any one of the MPL, the GPL or the LGPL.
  38 *
  39 * ***** END LICENSE BLOCK ***** */
  40/* ====================================================================
  41 * VerReg.c
  42 * XP Version Registry functions (prototype)
  43 * ====================================================================
  44 */
  45
  46/* --------------------------------------------------------------------
  47 * Install 'Navigator' produces a tree of:
  48 *
  49 *      /Components/Netscape/Web/Navigator/
  50 *              ...Path="c:\netscape\program\netscape.exe"
  51 *              ...Version=4.0.0.0
  52 *
  53 * --------------------------------------------------------------------
  54 */
  55#include <fcntl.h>
  56#include <errno.h>
  57
  58#if defined(XP_WIN) 
  59#include <io.h>
  60#endif
  61
  62#if defined(XP_OS2)
  63#include <sys/types.h>
  64#include <sys/stat.h>
  65#endif
  66
  67#include <stdio.h>
  68#include <string.h>
  69
  70#ifdef STANDALONE_REGISTRY
  71#include <stdlib.h>
  72#include <assert.h>
  73#endif /*STANDALONE_REGISTRY*/
  74
  75#include "reg.h"
  76#include "NSReg.h"
  77#include "VerReg.h"
  78
  79/* -------- local defines --------------- 
  80*/
  81#define MAXREGVERLEN 32     /* Version=12345.12345.12345.12345 */
  82
  83#define VERSTR          "Version"
  84#define CHKSTR          "Check"
  85#define PATHSTR         "Path"
  86#define DIRSTR          "Directory"
  87#define NAVHOME         "InstallDir"
  88#define REFCSTR         "RefCount"
  89#define SHAREDSTR       "Shared"
  90#define PACKAGENAMESTR  "PackageName"
  91#define SHAREDFILESSTR  "/Shared Files"
  92
  93#define VERSION_NAME    "Mozilla"
  94#define NAVIGATOR_NODE  "/mozilla.org"
  95#define CURRENT_VER     "CurrentVersion"
  96
  97#define PATH_ROOT(p)   ( ((p) && *(p)==PATHDEL) ? ROOTKEY_VERSIONS : curver )
  98#define UNIX_ROOT(p)   ( ((p) && *(p)==PATHDEL) ? ROOTKEY_VERSIONS : unixver )
  99
 100 
 101/* ---------------------------------------------------------------------
 102 * Global variables
 103 * ---------------------------------------------------------------------
 104 */
 105static int isInited = 0;
 106static RKEY curver = 0;
 107static char gCurstr[MAXREGNAMELEN];
 108
 109static HREG vreg = 0;
 110
 111static char *app_dir = NULL;
 112
 113char *verRegName = NULL;
 114
 115
 116#if defined(XP_UNIX) && !defined(XP_MACOSX)
 117/* Extra Unix variables to deal with two registries 
 118 *   "vreg" is always the writable registry.
 119 *   If "vreg" is the local registry then "unixreg" will
 120 *   be the global registry read-only (unless we couldn't
 121 *   open it).
 122 */
 123#if !defined(STANDALONE_REGISTRY)
 124static HREG unixreg = 0;
 125static RKEY unixver = 0;
 126#endif
 127XP_Bool bGlobalRegistry = FALSE;
 128#endif
 129
 130#ifndef STANDALONE_REGISTRY
 131PRLock *vr_lock = NULL;
 132#endif
 133
 134
 135/* ---------------------------------------------------------------------
 136 * local functions
 137 * ---------------------------------------------------------------------
 138 */
 139static REGERR vr_Init(void);
 140static XP_Bool vr_CompareDirs( char *dir1, char *dir2 );
 141static REGERR vr_SetCurrentNav( char *product, char *programPath, char *versionStr);
 142static REGERR vr_ParseVersion(char *verstr, VERSION *result);
 143
 144#ifdef USE_CHECKSUM
 145static REGERR vr_GetCheck(char *path, int32 *check);
 146#endif
 147
 148static REGERR vr_SetPathname(HREG reg, RKEY key, char *entry, char *dir);
 149static REGERR vr_GetPathname(HREG reg, RKEY key, char *entry, char *buf, uint32 sizebuf);
 150
 151static REGERR vr_FindKey(char *name, HREG *hreg, RKEY *key);
 152
 153static REGERR vr_GetUninstallItemPath(char *regPackageName, char *regbuf, uint32 regbuflen);
 154static REGERR vr_convertPackageName(char *regPackageName, char *convertedPackageName, uint32 convertedDataLength);
 155static REGERR vr_unmanglePackageName(char *mangledPackageName, char *regPackageName, uint32 regPackageLength);
 156
 157/* --------------------------------------------------------------------- */
 158
 159static REGERR vr_Init(void)
 160{
 161
 162    REGERR  err = REGERR_OK;
 163    char    *regname = vr_findVerRegName();
 164#if defined(XP_UNIX) && !defined(XP_MACOSX) || defined(STANDALONE_REGISTRY)
 165    char    curstr[MAXREGNAMELEN];
 166    RKEY    navKey;
 167#endif
 168#if defined(XP_UNIX) && !defined(XP_MACOSX)
 169    char    *regbuf = NULL;
 170#endif
 171
 172#ifndef STANDALONE_REGISTRY
 173    if (vr_lock == NULL)
 174        return REGERR_FAIL;
 175#endif
 176    PR_Lock(vr_lock);
 177
 178    if (!isInited)
 179    {
 180#if defined(XP_UNIX) && !defined(XP_MACOSX)
 181        /* need browser directory to find the correct registry */
 182        if (app_dir != NULL) {
 183            regbuf = (char*)XP_ALLOC( 10 + XP_STRLEN(app_dir) );
 184            if (regbuf != NULL ) {
 185                XP_STRCPY( regbuf, app_dir );
 186                XP_STRCAT( regbuf, "/registry" );
 187            } 
 188            else {
 189                err = REGERR_MEMORY;
 190            }
 191        } 
 192        if ( err != REGERR_OK )
 193            goto done;
 194
 195        if (bGlobalRegistry) 
 196            regname = regbuf;
 197#endif
 198
 199        /* Open version registry */
 200        err = NR_RegOpen( regname, &vreg );
 201
 202#ifndef STANDALONE_REGISTRY
 203        if (err == REGERR_OK) 
 204        {
 205            /* find/set the current nav node */
 206            err = vr_SetCurrentNav( VERSION_NAME, app_dir, NULL );
 207            if ( REGERR_OK != err ) {
 208                /* couldn't find or set current nav -- big problems! */
 209                NR_RegClose( vreg );
 210                goto done;
 211            }
 212        }
 213
 214#if defined(XP_UNIX) && !defined(XP_MACOSX)
 215        /* try to open shared Unix registry, but not an error if you can't */
 216        unixreg = NULL;
 217        if (!bGlobalRegistry && err == REGERR_OK ) {
 218            unixver = 0;
 219            if (NR_RegOpen( regbuf, &unixreg ) == REGERR_OK) {
 220                if (NR_RegGetKey( unixreg, ROOTKEY_VERSIONS, NAVIGATOR_NODE, 
 221                    &navKey) == REGERR_OK) 
 222                {
 223                    if (NR_RegGetEntryString( unixreg, navKey, CURRENT_VER,
 224                        curstr, sizeof(curstr)) == REGERR_OK ) 
 225                    {
 226                        NR_RegGetKey( unixreg, navKey, curstr, &unixver );
 227                    }
 228                }
 229            }
 230        }
 231#endif
 232
 233        if (err == REGERR_OK) {
 234            /* successfully opened! */
 235            isInited = 1;
 236        }
 237        goto done;
 238#else
 239        if (err != REGERR_OK)
 240            goto done;
 241
 242        /* Determine 'curver' key and ensure correct structure by adding */
 243
 244        /* ...find top-level "Navigator" node (add if missing) */
 245        err = NR_RegAddKey( vreg, ROOTKEY_VERSIONS, NAVIGATOR_NODE, &navKey );
 246        if (err != REGERR_OK)
 247            goto done;
 248
 249        /* ...look for "Current Version" entry */
 250        err = NR_RegGetEntryString( vreg, navKey, CURRENT_VER, curstr,
 251                                    sizeof(curstr) );
 252        if ( err == REGERR_NOFIND ) {
 253            /* If not found create one with the built-in version */
 254            err = NR_RegSetEntryString( vreg, navKey, CURRENT_VER, VERSION_NAME );
 255            XP_STRCPY( curstr, VERSION_NAME );
 256        }
 257        if ( err != REGERR_OK )
 258            goto done;
 259
 260        /* ...look for "curstr" child key of the navigator node */
 261        err = NR_RegAddKey( vreg, navKey, curstr, &curver );
 262
 263        if (err == REGERR_OK) {
 264            /* successfully opened! */
 265            isInited = 1;
 266        }
 267#endif
 268    }
 269
 270done:
 271    PR_Unlock(vr_lock);
 272#if defined(XP_UNIX) && !defined(XP_MACOSX) && !defined(STANDALONE_REGISTRY)
 273    XP_FREEIF(regbuf);
 274#endif
 275    return err;
 276
 277}   /* Init */
 278
 279
 280
 281#if defined(XP_WIN) || defined(XP_OS2)
 282#define VR_FILE_SEP '\\'
 283#elif defined(XP_UNIX) || defined(XP_BEOS)
 284#define VR_FILE_SEP '/'
 285#endif
 286
 287static XP_Bool vr_CompareDirs( char *dir1, char *dir2 )
 288{
 289    int len1,len2;
 290   
 291    XP_ASSERT( dir1 && dir2 );
 292    if (!dir1 || !dir2) return FALSE;
 293
 294    len1 = XP_STRLEN( dir1 );
 295    len2 = XP_STRLEN( dir2 );
 296
 297    if ( dir1[len1-1] == VR_FILE_SEP )
 298        len1--;
 299    if ( dir2[len2-1] == VR_FILE_SEP )
 300        len2--;
 301
 302    if ( len1 != len2 )
 303        return FALSE;
 304
 305#if defined(XP_UNIX) && !defined(XP_MACOSX)
 306    return ( XP_STRNCMP(dir1, dir2, len1) == 0 );
 307#else
 308    return ( XP_STRNCASECMP(dir1, dir2, len1) == 0 );
 309#endif
 310}
 311
 312
 313REGERR vr_ParseVersion(char *verstr, VERSION *result)
 314{
 315
 316    result->major = result->minor = result->release = result->build = 0;
 317    result->major = atoi(verstr);
 318    while (*verstr && *verstr != '.')
 319        verstr++;
 320    if (*verstr)
 321    {
 322        verstr++;
 323        result->minor = atoi(verstr);
 324        while (*verstr && *verstr != '.')
 325            verstr++;
 326        if (*verstr)
 327        {
 328            verstr++;
 329            result->release = atoi(verstr);
 330            while (*verstr && *verstr != '.')
 331                verstr++;
 332            if (*verstr)
 333            {
 334                verstr++;
 335                result->build = atoi(verstr);
 336                while (*verstr && *verstr != '.')
 337                    verstr++;
 338            }
 339        }
 340    }
 341
 342    return REGERR_OK;
 343
 344}   /* ParseVersion */
 345
 346
 347
 348#ifdef USE_CHECKSUM
 349#define BLKSIZ 16384
 350
 351static REGERR vr_GetCheck(char *path, int32 *check)
 352{
 353
 354    int fh;
 355    char *buf;
 356    int actual;
 357    char *p;
 358    int i;
 359    int chk;
 360
 361    XP_ASSERT(path);
 362    XP_ASSERT(check);
 363    
 364    *check = chk = 0;
 365
 366#ifdef NEED_XP_FIXES
 367    /* open file for read */
 368    fh = open(path, O_RDONLY| O_BINARY);
 369    if (fh < 0)
 370    {
 371        switch (errno)
 372        { 
 373        case ENOENT:    /* file not found */
 374            return REGERR_NOFILE;
 375
 376        case EACCES:    /* file in use */
 377        
 378#ifdef EMFILE        
 379        case EMFILE:    /* too many files open */
 380#endif
 381        default:
 382            return REGERR_FAIL;
 383        }
 384    }
 385
 386    buf = malloc(BLKSIZ);
 387    if (!buf)
 388    {
 389        close(fh);
 390        return REGERR_MEMORY;
 391    }
 392
 393    do
 394    {
 395        /* read a block */
 396        actual = read(fh, buf, BLKSIZ);
 397        /* add to checksum */
 398        for (p=buf, i=0; i<actual; i++, p++)
 399            chk += *p;
 400
 401        /* if the block was partial, we're done, else loop */
 402    } while (actual == BLKSIZ);
 403
 404    /* close file */
 405    close(fh);
 406    free(buf);
 407#endif
 408
 409    /* return calculated checksum */
 410    *check = chk;
 411
 412    return REGERR_OK;
 413
 414}   /* GetCheck */
 415
 416#endif /* USE_CHECKSUM */
 417
 418
 419
 420static REGERR vr_SetPathname(HREG reg, RKEY key, char *entry, char *dir)
 421{
 422    REGERR err;
 423    int32  datalen = XP_STRLEN(dir)+1; /* include '\0' */
 424
 425    err = NR_RegSetEntry( reg, key, entry, REGTYPE_ENTRY_FILE, dir, datalen);
 426
 427    return err;
 428}
 429
 430
 431
 432static REGERR vr_GetPathname(HREG reg, RKEY key, char *entry, char *buf, uint32 sizebuf)
 433{
 434    return NR_RegGetEntry( reg, key, entry, (void*)buf, &sizebuf );
 435}
 436
 437
 438
 439/* create default tree with 'installation' under Navigator */
 440/* set Current to the installation string */
 441static REGERR vr_SetCurrentNav( char *installation, char *programPath, char *versionStr)
 442{
 443    REGERR      err;
 444    REGENUM     state;
 445    RKEY        navKey;
 446    int         bFound;
 447    int         nCopy;
 448    char        regname[MAXREGNAMELEN];
 449    char        dirbuf[MAXREGNAMELEN];
 450
 451    XP_ASSERT( installation ); /* required */
 452    XP_ASSERT( programPath );  /* required */
 453    if ( !installation || !programPath )
 454        return REGERR_PARAM;
 455
 456    err = NR_RegAddKey( vreg, ROOTKEY_VERSIONS, NAVIGATOR_NODE, &navKey );
 457    if (err != REGERR_OK)
 458        goto done;
 459
 460    /* ...look for "Current Version" entry */
 461    err = NR_RegGetEntryString( vreg, navKey, CURRENT_VER, gCurstr, sizeof(gCurstr));
 462    if ( err == REGERR_NOFIND )
 463    {
 464        /* No current installation, we can simply add a new one  */
 465        err = NR_RegAddKey( vreg, navKey, installation, &curver );
 466
 467        /* ... add Path and Version properties */
 468        if ( err == REGERR_OK ) 
 469        {
 470            err = vr_SetPathname( vreg, curver, NAVHOME, programPath );
 471            if ( REGERR_OK == err && versionStr != NULL && *versionStr != '\0')
 472            {
 473                err = NR_RegSetEntryString( vreg, curver, VERSTR, versionStr );
 474            }
 475        }
 476
 477        if ( REGERR_OK == err ) {
 478            /* successfully added, make it the current version */
 479            err = NR_RegSetEntryString(vreg, navKey, CURRENT_VER, installation);
 480        }
 481
 482        if (err != REGERR_OK)
 483            goto done;
 484    }
 485    else if ( REGERR_OK == err )
 486    {
 487        /* found one: if we're lucky we got the right one */
 488        bFound = FALSE;
 489        err = NR_RegGetKey( vreg, navKey, gCurstr, &curver );
 490        if ( REGERR_OK == err ) {
 491            err = vr_GetPathname( vreg, curver, NAVHOME, dirbuf, sizeof(dirbuf) );
 492            if ( REGERR_OK == err ) {
 493                bFound = vr_CompareDirs(dirbuf, programPath);
 494            }
 495            else if ( REGERR_NOFIND == err ) {
 496                /* assume this is the right one since it's 'Current' */
 497                err = vr_SetPathname( vreg, curver, NAVHOME, programPath );
 498                bFound = TRUE;
 499            }
 500        }
 501        
 502        /* Look for an existing installation if not found */
 503        state = 0;
 504        while (!bFound && ((err == REGERR_OK) || (err == REGERR_NOFILE)) ) {
 505            err = NR_RegEnumSubkeys( vreg, navKey, &state, gCurstr,
 506                    sizeof(gCurstr), REGENUM_NORMAL );
 507
 508            if (REGERR_OK == err ) {
 509                err = vr_GetPathname( vreg, state, NAVHOME, dirbuf, sizeof(dirbuf) );
 510                if (REGERR_OK == err ) {
 511                    if (vr_CompareDirs( dirbuf, programPath )) {
 512                        bFound = TRUE;
 513                        curver = (RKEY)state;
 514                    }
 515                }
 516                else if ( err == REGERR_NOFIND ) {
 517                    /* wasn't a navigator node */
 518                    err = REGERR_OK;
 519                }
 520            }
 521        }
 522
 523        /* found the right one, make it current */
 524        if (bFound) {
 525            err = NR_RegSetEntryString( vreg, navKey, CURRENT_VER, gCurstr );
 526            /* update version (curver already set) */
 527            if ( REGERR_OK == err && versionStr != NULL && *versionStr != '\0' ) {
 528                err = NR_RegSetEntryString( vreg, curver, VERSTR, versionStr );
 529            }
 530        }
 531        /* otherwise if no current installation matches */
 532        else if ( err == REGERR_NOMORE )
 533        {
 534            /* look for an empty slot to put new installation */
 535            nCopy = 1;
 536            XP_STRCPY( regname, installation );
 537            do {
 538                err = NR_RegGetKey( vreg, navKey, regname, &curver );
 539                if (err == REGERR_OK) {
 540                    nCopy++;
 541                    sprintf( regname, "%s #%d", installation, nCopy );
 542                }
 543            } while (err==REGERR_OK);
 544
 545            if (err != REGERR_NOFIND)
 546                goto done;  /* real error, bail */
 547
 548            /* found an unused name -- add it */
 549            err = NR_RegAddKey( vreg, navKey, regname, &curver );
 550            if ( err != REGERR_OK )
 551                goto done;
 552
 553            /* add path and version properties */
 554            err = vr_SetPathname( vreg, curver, NAVHOME, programPath );
 555            if ( REGERR_OK == err && versionStr != NULL && *versionStr != '\0' ) {
 556                err = NR_RegSetEntryString( vreg, curver, VERSTR, versionStr );
 557            }
 558
 559            if ( REGERR_OK == err ) {
 560                /* everything's OK, make it current */
 561                err = NR_RegSetEntryString(vreg,navKey,CURRENT_VER,regname);
 562            }
 563        }
 564    }
 565done:
 566    return err;
 567}
 568
 569
 570
 571
 572/* assumes registries are open (only use after vr_Init() returns OK).
 573 * For UNIX look first in the global, then in the local if not found
 574 * -- returns both hreg and key of the named node (if found)
 575 */
 576static REGERR vr_FindKey(char *component_path, HREG *hreg, RKEY *key)
 577{
 578    REGERR err = REGERR_NOFIND;
 579    RKEY rootkey;
 580
 581#if !defined(STANDALONE_REGISTRY) && defined(XP_UNIX) && !defined(XP_MACOSX)
 582    if (unixreg != NULL) {
 583        *hreg = unixreg;
 584        rootkey = UNIX_ROOT(component_path);
 585        if (rootkey)
 586            err = NR_RegGetKey( *hreg, rootkey, component_path, key );
 587        else
 588            err = REGERR_NOFIND;
 589    }
 590    if (unixreg == NULL || err == REGERR_NOFIND ) 
 591#endif
 592    {
 593        *hreg = vreg;
 594        rootkey = PATH_ROOT(component_path);
 595        if (rootkey)
 596            err = NR_RegGetKey( *hreg, rootkey, component_path, key );
 597        else
 598            err = REGERR_NOFIND;
 599    }
 600
 601    return err;
 602}
 603
 604
 605
 606/* ---------------------------------------------------------------------
 607 * Interface
 608 * ---------------------------------------------------------------------
 609 */
 610
 611#ifndef STANDALONE_REGISTRY
 612VR_INTERFACE(REGERR) VR_PackRegistry(void *userData, nr_RegPackCallbackFunc fn)
 613{
 614    REGERR err;
 615
 616    /* make sure vreg (src) is open */
 617    err = vr_Init();
 618    if (err != REGERR_OK)
 619        return err;
 620
 621    err = NR_RegPack( vreg, userData, fn );
 622
 623    return err;
 624
 625}   /* PackRegistry */
 626#endif /* STANDALONE_REGISTRY */
 627
 628
 629VR_INTERFACE(REGERR) VR_CreateRegistry( char *installation, char *programPath, char *versionStr )
 630{
 631    REGERR      err;
 632    char *      regname = vr_findVerRegName();
 633#if defined(XP_UNIX) && !defined(XP_MACOSX)
 634    char *      regbuf = NULL;
 635#endif
 636
 637    if ( installation == NULL || *installation == '\0' )
 638        return REGERR_PARAM;
 639
 640#if defined(XP_UNIX) && !defined(XP_MACOSX)
 641#ifndef STANDALONE_REGISTRY
 642    if (bGlobalRegistry)
 643#endif 
 644    {
 645        regbuf = (char*)XP_ALLOC( 10 + XP_STRLEN(programPath) );
 646        if (regbuf == NULL) 
 647            return REGERR_MEMORY;
 648
 649        XP_STRCPY( regbuf, programPath );
 650        XP_STRCAT( regbuf, "registry" );
 651        regname = regbuf;
 652    }
 653#endif /* XP_UNIX */
 654
 655    PR_Lock(vr_lock);
 656
 657    /* automatically creates it if not found */
 658    err = NR_RegOpen( regname, &vreg );
 659    if (err == REGERR_OK) 
 660    {
 661        /* create default tree with 'installation' under Navigator */
 662        /* set Current to the installation string */
 663
 664        err = vr_SetCurrentNav( installation, programPath, versionStr );
 665
 666        if ( REGERR_OK == err )
 667            isInited = 1;
 668        else
 669            NR_RegClose( vreg );
 670    }
 671
 672    PR_Unlock(vr_lock);
 673
 674#if defined(XP_UNIX) && !defined(XP_MACOSX)
 675    XP_FREEIF( regbuf );
 676#endif
 677    return err;
 678
 679}   /* CreateRegistry */
 680
 681
 682VR_INTERFACE(REGERR) VR_Close(void)
 683{
 684    REGERR err = REGERR_OK;
 685
 686#ifndef STANDALONE_REGISTRY
 687    if (vr_lock == NULL)
 688        return REGERR_FAIL;
 689#endif
 690
 691    PR_Lock(vr_lock);
 692
 693    if (isInited) {
 694#if !defined(STANDALONE_REGISTRY) && defined(XP_UNIX) && !defined(XP_MACOSX)
 695        if ( unixreg != NULL )
 696            NR_RegClose( unixreg );
 697#endif
 698        err = NR_RegClose( vreg );
 699        isInited = 0;
 700    }
 701
 702    PR_Unlock(vr_lock);
 703
 704    return err;
 705}   /* Close */
 706
 707
 708
 709VR_INTERFACE(REGERR) VR_GetVersion(char *component_path, VERSION *result)
 710{
 711    REGERR  err;
 712    RKEY    key;
 713    HREG    hreg;
 714    VERSION ver;
 715    char    buf[MAXREGNAMELEN];
 716
 717    err = vr_Init();
 718    if (err != REGERR_OK)
 719        return err;
 720
 721    hreg = vreg;
 722
 723    err = vr_FindKey( component_path, &hreg, &key );
 724    if (err != REGERR_OK)
 725        return err;
 726
 727    err = NR_RegGetEntryString( hreg, key, VERSTR, buf, sizeof(buf) );
 728    if (err != REGERR_OK)
 729        return err;
 730
 731    vr_ParseVersion(buf, &ver);
 732
 733    memcpy(result, &ver, sizeof(VERSION));
 734
 735    return REGERR_OK;
 736
 737}   /* GetVersion */
 738
 739
 740
 741VR_INTERFACE(REGERR) VR_GetPath(char *component_path, uint32 sizebuf, char *buf)
 742{
 743    REGERR err;
 744    RKEY key;
 745    HREG hreg;
 746
 747    err = vr_Init();
 748    if (err != REGERR_OK)
 749        return err;
 750
 751    hreg = vreg;
 752
 753    err = vr_FindKey( component_path, &hreg, &key );
 754    if (err != REGERR_OK)
 755        return err;
 756    
 757    err = vr_GetPathname( hreg, key, PATHSTR, buf, sizebuf );
 758
 759    return err;
 760
 761}   /* GetPath */
 762
 763
 764
 765VR_INTERFACE(REGERR) VR_SetDefaultDirectory(char *component_path, char *directory)
 766{
 767    REGERR err;
 768    RKEY rootkey;
 769    RKEY key;
 770
 771    err = vr_Init();
 772    if (err != REGERR_OK)
 773        return err;
 774
 775    rootkey = PATH_ROOT(component_path);
 776
 777    err = NR_RegGetKey( vreg, rootkey, component_path, &key );
 778    if (err != REGERR_OK)
 779        return err;
 780    
 781    err = vr_SetPathname( vreg, key, DIRSTR, directory );
 782
 783    return err;
 784}
 785
 786
 787
 788VR_INTERFACE(REGERR) VR_GetDefaultDirectory(char *component_path, uint32 sizebuf, char *buf)
 789{
 790    REGERR err;
 791    RKEY key;
 792    HREG hreg;
 793
 794    err = vr_Init();
 795    if (err != REGERR_OK)
 796        return err;
 797
 798    hreg = vreg;
 799
 800    err = vr_FindKey( component_path, &hreg, &key );
 801    if (err != REGERR_OK)
 802        return err;
 803
 804    err = vr_GetPathname( hreg, key, DIRSTR, buf, sizebuf );
 805
 806    return err;
 807}
 808
 809
 810
 811VR_INTERFACE(REGERR) VR_Install(char *component_path, char *filepath, char *version, int bDirectory)
 812{
 813    REGERR err;
 814    RKEY rootKey;
 815    RKEY key;
 816
 817    /* Initialize the registry in case this is first call */
 818    err = vr_Init();
 819    if (err != REGERR_OK)
 820        return err;
 821
 822    /* Use curver if path is relative */
 823    rootKey = PATH_ROOT(component_path);
 824
 825    /* Make sure path components (keys) exist by calling Add */
 826    /* (special "" component must always exist, and Add fails) */
 827    if ( component_path != NULL && *component_path == '\0' ) {
 828        err = NR_RegGetKey( vreg, rootKey, component_path, &key );
 829    }
 830    else {
 831        err = NR_RegAddKey( vreg, rootKey, component_path, &key );
 832    }
 833    if (err != REGERR_OK)
 834        return err;
 835
 836    if ( version != NULL && *version != '\0' ) {
 837        /* Add "Version" entry with values like "4.0.0.0" */
 838        err = NR_RegSetEntryString( vreg, key, VERSTR, version );
 839        if (err != REGERR_OK)
 840            goto abort;
 841    }
 842
 843    if ( filepath != NULL && *filepath != '\0' ) {
 844        /* add "Path" entry */
 845        err = vr_SetPathname( vreg, key, (bDirectory)?DIRSTR:PATHSTR, filepath );
 846
 847        if (err != REGERR_OK)
 848            goto abort;
 849    }
 850
 851    return REGERR_OK;
 852
 853abort:
 854    NR_RegDeleteKey( vreg, rootKey, component_path );
 855    return err;
 856
 857}   /* Install */
 858
 859
 860
 861VR_INTERFACE(REGERR) VR_Remove(char *component_path)
 862{
 863    REGERR err;
 864    RKEY rootkey;
 865
 866    err = vr_Init();
 867    if (err != REGERR_OK)
 868        return err;
 869
 870    rootkey = PATH_ROOT(component_path);
 871
 872    return NR_RegDeleteKey( vreg, rootkey, component_path );
 873
 874}   /* Remove */
 875
 876VR_INTERFACE(REGERR) VR_Enum(char *component_path, REGENUM *state, 
 877                                         char *buffer, uint32 buflen)
 878{
 879    REGERR  err;
 880    RKEY    rootkey;
 881    RKEY    key;
 882
 883    err = vr_Init();
 884    if (err != REGERR_OK)
 885        return err;
 886
 887    if ( component_path == NULL )
 888        rootkey = ROOTKEY_VERSIONS;
 889    else
 890        rootkey = PATH_ROOT(component_path);
 891
 892    err = NR_RegGetKey( vreg, rootkey, component_path, &key );
 893    if (err != REGERR_OK)
 894        return err;
 895
 896    err = NR_RegEnumSubkeys( vreg, key, state, buffer, buflen, REGENUM_DEPTH_FIRST);
 897
 898    return err;
 899
 900}   /* Enum */
 901
 902VR_INTERFACE(REGERR) VR_InRegistry(char *component_path)
 903{
 904    REGERR err;
 905    RKEY key;
 906    HREG hreg;
 907
 908    err = vr_Init();
 909    if (err != REGERR_OK)
 910        return err;
 911
 912    return vr_FindKey( component_path, &hreg, &key );
 913}   /* InRegistry */
 914
 915
 916
 917VR_INTERFACE(REGERR) VR_ValidateComponent(char *component_path)
 918{
 919    REGERR err;
 920    RKEY key;
 921    char path[MAXREGPATHLEN];
 922    HREG hreg;
 923
 924
 925#ifdef USE_CHECKSUM
 926    char buf[MAXREGNAMELEN];
 927    long calculatedCheck;
 928    int storedCheck;
 929#endif
 930
 931    err = vr_Init();
 932    if (err != REGERR_OK)
 933        return err;
 934
 935    err = vr_FindKey( component_path, &hreg, &key );
 936    if ( err != REGERR_OK )
 937        return err;
 938
 939    err = VR_GetPath( component_path, sizeof(path), path );
 940    if ( err != REGERR_OK ) {
 941        if ( err == REGERR_NOFIND ) {
 942            err = REGERR_NOPATH;
 943        }
 944        return err;
 945    }
 946
 947    {
 948        uint32 len;
 949        struct stat  statStruct;
 950
 951        /* directories are stored with a trailing separator -- if we */
 952        /* have one of these we have to remove it for stat to work */
 953        len = strlen(path);
 954        if ( path[len-1] == VR_FILE_SEP )
 955            path[len-1] = 0;
 956
 957        if ( stat ( path, &statStruct ) != 0 ) {
 958            err = REGERR_NOFILE;
 959        }
 960    }
 961    if (err != REGERR_OK)
 962        return err;
 963
 964
 965#if defined(USE_CHECKSUM) && !defined(XP_UNIX)
 966    err = NR_RegGetEntryString( vreg, key, CHKSTR, buf, sizeof(buf) );
 967    if (err != REGERR_OK)
 968        return err;
 969
 970    storedCheck = atoi(buf);
 971
 972    err = vr_GetCheck(filepath, &calculatedCheck);
 973    if (err != REGERR_OK)
 974        return err;
 975
 976    if (storedCheck != calculatedCheck)
 977    {
 978        return REGERR_BADCHECK;
 979    }
 980#endif /* USE_CHECKSUM */
 981
 982    return REGERR_OK;
 983
 984}   /* CheckEntry */
 985
 986
 987
 988VR_INTERFACE(REGERR) VR_SetRegDirectory(const char *path)
 989{
 990    char *tmp;
 991
 992    tmp = XP_STRDUP(path);
 993    if (NULL == tmp) {
 994        return REGERR_MEMORY;
 995    }
 996
 997    PR_Lock(vr_lock);
 998
 999    XP_FREEIF(app_dir);
1000    app_dir = tmp;
1001    
1002    PR_Unlock(vr_lock);
1003
1004    return REGERR_OK;
1005}
1006
1007
1008
1009VR_INTERFACE(REGERR) VR_SetRefCount(char *component_path, int refcount)
1010{
1011    REGERR err;
1012    RKEY rootKey;
1013    RKEY key = 0;
1014    char rcstr[MAXREGNAMELEN];
1015
1016    err = vr_Init();
1017    if (err != REGERR_OK)
1018        return err;
1019
1020    /* Use curver if path is relative */
1021    rootKey = PATH_ROOT(component_path);
1022
1023    /* Make sure path components (keys) exist by calling Add */
1024    /* (special "" component must always exist, and Add fails) */
1025    if ( component_path != NULL && *component_path == '\0' ) {
1026        err = REGERR_PARAM;
1027    }
1028    else {
1029        err = NR_RegAddKey( vreg, rootKey, component_path, &key );
1030    }
1031    
1032    if (err != REGERR_OK)
1033        return err;
1034
1035    *rcstr = '\0';
1036    /* itoa(refcount, rcstr, 10); */
1037    XP_SPRINTF(rcstr, "%d", refcount);
1038    
1039    if ( rcstr != NULL && *rcstr != '\0' ) {
1040        /* Add "RefCount" */
1041        err = NR_RegSetEntryString( vreg, key, REFCSTR, rcstr );
1042    }
1043    
1044    return err;
1045}   /* SetRefCount */
1046
1047
1048
1049VR_INTERFACE(REGERR) VR_GetRefCount(char *component_path, int *result)
1050{
1051    REGERR  err;
1052    RKEY    rootkey;
1053    RKEY    key;
1054    char    buf[MAXREGNAMELEN];
1055
1056    *result = -1; 
1057
1058    err = vr_Init();
1059    if (err != REGERR_OK)
1060        return err;
1061
1062    /* "Uninstall" only happens in the writable registry, so no
1063     * need to search the shared one on Unix using vr_FindKey()
1064     */
1065    rootkey = PATH_ROOT(component_path);
1066    err = NR_RegGetKey( vreg, rootkey, component_path, &key );
1067    if (err != REGERR_OK)
1068        return err;
1069
1070    err = NR_RegGetEntryString( vreg, key, REFCSTR, buf, sizeof(buf) );
1071    if (err != REGERR_OK)
1072        return err;
1073
1074    *result = atoi( buf );
1075
1076    return REGERR_OK;
1077
1078}   /* GetRefCount */
1079
1080static REGERR vr_GetUninstallItemPath(char *regPackageName, char *regbuf, uint32 regbuflen)
1081{
1082    XP_Bool bSharedUninstall = FALSE;
1083    XP_Bool bNavPackage = FALSE;
1084    uint32 len = 0;
1085    uint32 sharedstrlen = 0;
1086    uint32 curstrlen = 0;
1087    uint32 curregbuflen = 0;
1088
1089    /* determine install type */
1090    if (*regPackageName == '\0') {
1091        bNavPackage = TRUE;
1092    }
1093    else if ( *regPackageName == PATHDEL) {
1094        bSharedUninstall = TRUE;
1095    }
1096
1097    /* create uninstall path prefix */
1098    len = XP_STRLEN(REG_UNINSTALL_DIR);
1099    if (len < regbuflen)
1100    {
1101        XP_STRCPY( regbuf, REG_UNINSTALL_DIR );
1102    }
1103    else
1104    {
1105        return REGERR_BUFTOOSMALL;
1106    }
1107    if (bSharedUninstall)
1108    {
1109        sharedstrlen = XP_STRLEN(SHAREDSTR);
1110        if (sharedstrlen < (regbuflen - len))
1111            XP_STRCAT( regbuf, SHAREDSTR );
1112        else 
1113            return REGERR_BUFTOOSMALL;
1114    }
1115    else
1116    {
1117        curstrlen = XP_STRLEN(gCurstr);
1118        if (curstrlen < (regbuflen - len))
1119            XP_STRCAT( regbuf, gCurstr );
1120        else 
1121            return REGERR_BUFTOOSMALL;
1122        if (1 < (regbuflen - len - curstrlen))
1123            XP_STRCAT( regbuf, "/" );
1124        else 
1125            return REGERR_BUFTOOSMALL;
1126    }  
1127
1128    /* add final uninstall node name */
1129    len = 0;
1130    curregbuflen = XP_STRLEN(regbuf);
1131    if ( bNavPackage ) {
1132        len = XP_STRLEN(UNINSTALL_NAV_STR);
1133        if (len < (regbuflen - curregbuflen))
1134            XP_STRCAT( regbuf, UNINSTALL_NAV_STR );
1135        else 
1136            return REGERR_BUFTOOSMALL;
1137    }
1138    else {
1139        len = XP_STRLEN(regPackageName);
1140        if (len < (regbuflen - curregbuflen))
1141            XP_STRCAT( regbuf, regPackageName );
1142        else 
1143            return REGERR_BUFTOOSMALL;
1144    }
1145    return REGERR_OK;
1146}
1147
1148
1149/**
1150 * Replaces all '/' with '_',in the given string.If an '_' already exists in the
1151 * given string, it is escaped by adding another '_' to it.
1152 */
1153static REGERR vr_convertPackageName(char *regPackageName, char *convertedPackageName, uint32 convertedDataLength)
1154{
1155    uint32 length = 0;
1156    uint32 i;
1157    uint32 j = 0;
1158
1159    length = XP_STRLEN(regPackageName);
1160    
1161    if (convertedDataLength <= length)
1162        return REGERR_BUFTOOSMALL;
1163
1164    for (i=0, j=0; i<length; i++, j++)
1165    {
1166        if (j < (convertedDataLength-1))
1167        {
1168            convertedPackageName[j] = regPackageName[i];
1169        }
1170        else
1171        {
1172            return REGERR_BUFTOOSMALL;
1173        }
1174        if (regPackageName[i] == '_')
1175        {
1176            if ((j+1) < (convertedDataLength-1))
1177            {
1178                convertedPackageName[j+1] = '_';
1179            }
1180            else
1181            {
1182                return REGERR_BUFTOOSMALL;
1183            }
1184            j = j + 1;
1185        }
1186    }
1187
1188    if (convertedPackageName[j-1] == '/')
1189        convertedPackageName[j-1] = '\0';
1190    else
1191    {
1192        if (j < convertedDataLength)
1193        {
1194            convertedPackageName[j] = '\0';
1195        }
1196        else
1197        {
1198            return REGERR_BUFTOOSMALL;
1199        }
1200    }
1201
1202    length = 0;
1203    length = XP_STRLEN(convertedPackageName);
1204    for (i=1; i<length; i++)
1205    {
1206        if (convertedPackageName[i] == '/')
1207            convertedPackageName[i] = '_';
1208    }
1209
1210    return REGERR_OK;
1211}
1212
1213static REGERR vr_unmanglePackageName(char *mangledPackageName, char *regPackageName, uint32 regPackageLength)
1214{
1215    uint32 length = 0;
1216    uint32 i = 0;
1217    uint32 j = 0;
1218
1219    length = XP_STRLEN(mangledPackageName);
1220    
1221    if (regPackageLength <= length)
1222        return REGERR_BUFTOOSMALL;
1223
1224    while (i < length)
1225    {
1226        if ((mangledPackageName[i] != '_') || (i == length-1)){
1227            if (j < (regPackageLength - 1))
1228                regPackageName[j] = mangledPackageName[i];
1229            else
1230                return REGERR_BUFTOOSMALL;
1231            j = j + 1;  
1232            i = i + 1;
1233        } else if (mangledPackageName[i + 1] != '_') { 
1234            if (j < (regPackageLength - 1))
1235                regPackageName[j] = '/';
1236            else
1237                return REGERR_BUFTOOSMALL;
1238            j = j + 1;
1239            i = i + 1;
1240        } else {
1241            if (j < (regPackageLength - 1))
1242                regPackageName[j] = '_';
1243            else
1244                return REGERR_BUFTOOSMALL;
1245            j = j + 1;
1246            i = i + 2;
1247        }
1248    }
1249    if (j < regPackageLength)
1250        regPackageName[j] = '\0';
1251    else
1252        return REGERR_BUFTOOSMALL;
1253    return REGERR_OK;
1254}
1255
1256VR_INTERFACE(REGERR) VR_UninstallCreateNode(char *regPackageName, char *userPackageName)
1257{
1258    REGERR err;
1259    RKEY key = 0;
1260    char *regbuf;
1261    uint32 regbuflen = 0;
1262
1263    err = vr_Init();
1264    if (err != REGERR_OK)
1265        return err;
1266
1267    if ( regPackageName == NULL )
1268        err = REGERR_PARAM;
1269   
1270    if ( userPackageName == NULL)
1271        err = REGERR_PARAM;
1272
1273    regbuflen = 256 + XP_STRLEN(regPackageName);
1274    regbuf = (char*)XP_ALLOC( regbuflen );
1275    if (regbuf != NULL )
1276    {
1277        err = vr_GetUninstallItemPath(regPackageName, regbuf, regbuflen);  
1278        if (err != REGERR_OK)
1279        {
1280            XP_FREE(regbuf);
1281            return err;
1282        }
1283        err = NR_RegAddKey( vreg, ROOTKEY_PRIVATE, regbuf, &key );
1284        XP_FREE(regbuf);
1285    }
1286    else
1287    {
1288        err = REGERR_MEMORY;
1289    }
1290
1291    if (err == REGERR_OK)
1292        err = NR_RegSetEntryString(vreg, key, PACKAGENAMESTR, userPackageName);
1293  
1294    return err;
1295
1296}   /* UninstallCreateNode */
1297
1298VR_INTERFACE(REGERR) VR_GetUninstallUserName(char *regPackageName, char *outbuf, uint32 buflen)
1299{
1300    REGERR err;
1301    RKEY key = 0;
1302    char *regbuf = NULL;
1303    char *convertedName = NULL;
1304    uint32 convertedDataLength = 0;
1305    uint32 regbuflen = 0;
1306
1307    err = vr_Init();
1308    if (err != REGERR_OK)
1309        return err;
1310
1311    if ( regPackageName == NULL || *regPackageName == '\0' || outbuf == NULL )
1312        return REGERR_PARAM;
1313   
1314    convertedDataLength = 2 * XP_STRLEN(regPackageName) + 1;
1315    convertedName = (char*)XP_ALLOC(convertedDataLength);
1316    if (convertedName == NULL ) {
1317        err = REGERR_MEMORY;
1318        return err;
1319    }
1320  
1321    err = vr_convertPackageName(regPackageName, convertedName, convertedDataLength);
1322    if (err != REGERR_OK) {
1323        XP_FREE(convertedName);
1324        return err;
1325    }
1326    regbuflen = 256 + XP_STRLEN(convertedName);
1327    regbuf = (char*)XP_ALLOC( regbuflen );
1328    if (regbuf == NULL ) {
1329        err = REGERR_MEMORY;
1330    } else {
1331        err = vr_GetUninstallItemPath(convertedName, regbuf, regbuflen);
1332        if (err == REGERR_OK) {
1333            err = NR_RegGetKey( vreg, ROOTKEY_PRIVATE, regbuf, &key );
1334        }
1335        XP_FREE(regbuf);
1336    }
1337
1338    if (err == REGERR_OK)
1339        err = NR_RegGetEntryString( vreg, key, PACKAGENAMESTR, outbuf, buflen );
1340  
1341    XP_FREE(convertedName);
1342    return err;
1343
1344}   /* GetUninstallName */
1345
1346VR_INTERFACE(REGERR) VR_UninstallAddFileToList(char *regPackageName, char *vrName)
1347{
1348    REGERR err;
1349    RKEY key = 0;
1350    char *regbuf;
1351    uint32 regbuflen = 0;
1352    uint32 curregbuflen = 0;
1353    uint32 len = 0;
1354    
1355    err = vr_Init();
1356    if (err != REGERR_OK)
1357        return err;
1358
1359    if ( regPackageName == NULL )
1360        err = REGERR_PARAM;
1361
1362    if ( vrName == NULL )
1363        err = REGERR_PARAM;
1364
1365    regbuflen = 256 + XP_STRLEN(regPackageName);
1366    regbuf = (char*)XP_ALLOC( regbuflen );
1367    if (regbuf != NULL )
1368    {
1369        err = vr_GetUninstallItemPath(regPackageName, regbuf, regbuflen);
1370        if (err == REGERR_OK)
1371        {
1372            curregbuflen = XP_STRLEN(regbuf);
1373            len = XP_STRLEN(SHAREDFILESSTR);
1374            if (len < (regbuflen - curregbuflen))
1375            {
1376                XP_STRCAT(regbuf, SHAREDFILESSTR);
1377                err = NR_RegAddKey( vreg, ROOTKEY_PRIVATE, regbuf, &key );
1378            }
1379            else
1380                err = REGERR_BUFTOOSMALL;
1381        }
1382        XP_FREEIF(regbuf);
1383    }
1384    else
1385    {
1386        err = REGERR_MEMORY;
1387    }
1388
1389    if (err == REGERR_OK)
1390        err = NR_RegSetEntryString( vreg, key, vrName, "");
1391  
1392    return err;
1393
1394}   /* UninstallAddFileToList */
1395
1396VR_INTERFACE(REGERR) VR_UninstallFileExistsInList(char *regPackageName, char *vrName)
1397{
1398    REGERR err;
1399    RKEY key = 0;
1400    char *regbuf;
1401    char  sharedfilesstr[MAXREGNAMELEN];
1402    uint32 regbuflen = 0;
1403    uint32 curregbuflen = 0;
1404    uint32 len = 0;
1405    
1406    err = vr_Init();
1407    if (err != REGERR_OK)
1408        return err;
1409
1410    if ( regPackageName == NULL )
1411        err = REGERR_PARAM;
1412
1413    if ( vrName == NULL )
1414        err = REGERR_PARAM;
1415
1416    regbuflen = 256 + XP_STRLEN(regPackageName);
1417    regbuf = (char*)XP_ALLOC( regbuflen );
1418    if (regbuf != NULL )
1419    {
1420        err = vr_GetUninstallItemPath(regPackageName, regbuf, regbuflen);
1421        if (err == REGERR_OK)
1422        {
1423            curregbuflen = XP_STRLEN(regbuf);
1424            len = XP_STRLEN(SHAREDFILESSTR);
1425            if (len < (regbuflen - curregbuflen))
1426            {
1427                XP_STRCAT(regbuf, SHAREDFILESSTR);
1428                err = NR_RegGetKey( vreg, ROOTKEY_PRIVATE, regbuf, &key );
1429            }
1430            else
1431                err = REGERR_BUFTOOSMALL;
1432        }
1433        XP_FREEIF(regbuf);
1434    }
1435    else
1436    {
1437        err = REGERR_MEMORY;
1438    }
1439    
1440    if (err == REGERR_OK)
1441        err = NR_RegGetEntryString( vreg, key, vrName, sharedfilesstr,
1442                                    sizeof(sharedfilesstr) );
1443    return err;
1444
1445}   /* UninstallFileExistsInList */
1446
1447VR_INTERFACE(REGERR) VR_UninstallEnumSharedFiles(char *component_path, REGENUM *state, 
1448                                         char *buffer, uint32 buflen)
1449{
1450    REGERR err;
1451    RKEY key = 0;
1452    char *regbuf;
1453    char *converted_component_path;
1454    uint32 convertedDataLength = 0;
1455    uint32 regbuflen = 0;
1456    uint32 curregbuflen = 0;
1457    uint32 len = 0;
1458 
1459    err = vr_Init();
1460    if (err != REGERR_OK)
1461        return err;
1462
1463    if ( component_path == NULL )
1464        return REGERR_PARAM;
1465
1466    convertedDataLength = 2 * XP_STRLEN(component_path) + 1;
1467    converted_component_path = (char*)XP_ALLOC(convertedDataLength);
1468    if (converted_component_path == NULL ) {
1469        err = REGERR_MEMORY;
1470        return err;
1471    }
1472    err = vr_convertPackageName(component_path, converted_component_path, convertedDataLength);
1473    if (err != REGERR_OK)
1474    {
1475        XP_FREEIF(converted_component_path);
1476        return err;
1477    }
1478
1479    regbuflen = 256 + XP_STRLEN(converted_component_path);
1480    regbuf = (char*)XP_ALLOC( regbuflen );
1481    if (regbuf != NULL )
1482    {
1483        err = vr_GetUninstallItemPath(converted_component_path, regbuf, regbuflen); 
1484        if (err == REGERR_OK)
1485        {
1486            curregbuflen = XP_STRLEN(regbuf);
1487            len = XP_STRLEN(SHAREDFILESSTR);
1488            if (len < (regbuflen - curregbuflen))
1489            {
1490                 XP_STRCAT(regbuf, SHAREDFILESSTR);
1491                 err = NR_RegGetKey( vreg, ROOTKEY_PRIVATE, regbuf, &key );
1492            }
1493            else
1494                err = REGERR_BUFTOOSMALL;
1495        }
1496        XP_FREE(regbuf);
1497    }
1498    else
1499    {
1500        err = REGERR_MEMORY;
1501    }
1502    
1503    XP_FREE(converted_component_path);
1504
1505    if (err == REGERR_OK)
1506        err = NR_RegEnumEntries( vreg, key, state, buffer, buflen, NULL);
1507
1508    return err;
1509
1510}   /* UninstallEnumSharedFiles */
1511
1512VR_INTERFACE(REGERR) VR_UninstallDeleteFileFromList(char *component_path, char *vrName)
1513{
1514    REGERR err;
1515    RKEY key = 0;
1516    char *regbuf;
1517    char *converted_component_path;
1518    uint32 convertedDataLength = 0;
1519    uint32 regbuflen = 0;
1520    uint32 curregbuflen = 0;
1521    uint32 len = 0;
1522        
1523    err = vr_Init();
1524    if (err != REGERR_OK)
1525        return err;
1526
1527    if ( component_path == NULL )
1528        err = REGERR_PARAM;
1529
1530    if ( vrName == NULL )
1531        err = REGERR_PARAM;
1532
1533    convertedDataLength = 2 * XP_STRLEN(component_path) + 1;
1534    converted_component_path = (char*)XP_ALLOC(convertedDataLength);
1535    if (converted_component_path == NULL ) {
1536        err = REGERR_MEMORY;
1537        return err;
1538    }
1539    err = vr_convertPackageName(component_path, converted_component_path, convertedDataLength);
1540    if (err != REGERR_OK)
1541    {
1542        XP_FREEIF(converted_component_path);
1543        return err;
1544    }
1545
1546    regbuflen = 256 + XP_STRLEN(converted_component_path);
1547    regbuf = (char*)XP_ALLOC( regbuflen );
1548    if (regbuf != NULL )
1549    {
1550        err = vr_GetUninstallItemPath(converted_component_path, regbuf, regbuflen);  
1551         if (err == REGERR_OK)
1552        {
1553            curregbuflen = XP_STRLEN(regbuf);
1554            len = XP_STRLEN(SHAREDFILESSTR);
1555            if (len < (regbuflen - curregbuflen))
1556            {
1557                XP_STRCAT(regbuf, SHAREDFILESSTR);
1558                err = NR_RegGetKey( vreg, ROOTKEY_PRIVATE, regbuf, &key );
1559            }
1560            else
1561                err = REGERR_BUFTOOSMALL;
1562        }
1563        XP_FREE(regbuf);
1564    }
1565    else
1566    {
1567        err = REGERR_MEMORY;
1568    }
1569    
1570    XP_FREE(converted_component_path);
1571
1572    if (err == REGERR_OK)
1573        err = NR_RegDeleteEntry( vreg, key, vrName);
1574
1575    return err;
1576
1577}   /* UninstallDeleteFileFromList */
1578
1579VR_INTERFACE(REGERR) VR_UninstallDeleteSharedFilesKey(char *component_path)
1580{
1581    REGERR err;
1582    char *regbuf;
1583    char *converted_component_path;
1584    uint32 convertedDataLength = 0;
1585    uint32 regbuflen = 0;
1586    uint32 curregbuflen = 0;
1587    uint32 len = 0;
1588        
1589    err = vr_Init();
1590    if (err != REGERR_OK)
1591        return err;
1592
1593    if ( component_path == NULL )
1594        err = REGERR_PARAM;
1595
1596    convertedDataLength = 2 * XP_STRLEN(component_path) + 1;
1597    converted_component_path = (char*)XP_ALLOC(convertedDataLength);
1598    if (converted_component_path == NULL ) {
1599        err = REGERR_MEMORY;
1600        return err;
1601    }
1602    err = vr_convertPackageName(component_path, converted_component_path, convertedDataLength);
1603    if (err != REGERR_OK)
1604    {
1605        XP_FREEIF(converted_component_path);
1606        return err;
1607    }
1608
1609    regbuflen = 256 + XP_STRLEN(converted_component_path);
1610    regbuf = (char*)XP_ALLOC( regbuflen );
1611    if (regbuf != NULL )
1612    {
1613        err = vr_GetUninstallItemPath(converted_component_path, regbuf, regbuflen); 
1614        if (err == REGERR_OK)
1615        {
1616            curregbuflen = XP_STRLEN(regbuf);
1617            len = XP_STRLEN(SHAREDFILESSTR);
1618            if (len < (regbuflen - curregbuflen))
1619            {
1620                XP_STRCAT(regbuf, SHAREDFILESSTR);
1621                err = NR_RegDeleteKey( vreg, ROOTKEY_PRIVATE, regbuf );
1622            }
1623            else
1624                err = REGERR_BUFTOOSMALL;
1625        }
1626        XP_FREE(regbuf);
1627    }
1628    else
1629    {
1630        err = REGERR_MEMORY;
1631    }
1632
1633    XP_FREE(converted_component_path);
1634    return err;
1635
1636}   /* UninstallDeleteSharedFilesKey */
1637
1638VR_INTERFACE(REGERR) VR_UninstallDestroy(char *component_path)
1639{
1640    REGERR err;
1641    char *regbuf;
1642    char *converted_component_path;
1643    uint32 convertedDataLength = 0;
1644    uint32 regbuflen = 0;
1645        
1646    err = vr_Init();
1647    if (err != REGERR_OK)
1648        return err;
1649
1650    if ( component_path == NULL )
1651        err = REGERR_PARAM;
1652    
1653    convertedDataLength = 2 * XP_STRLEN(component_path) + 1;
1654    converted_component_path = (char*)XP_ALLOC(convertedDataLength);
1655    if (converted_component_path == NULL ) {
1656        err = REGERR_MEMORY;
1657        return err;
1658    }
1659    err = vr_convertPackageName(component_path, converted_component_path, convertedDataLength);
1660    if (err != REGERR_OK)
1661    {
1662        XP_FREEIF(converted_component_path);
1663        return err;
1664    }
1665
1666    regbuflen = 256 + XP_STRLEN(converted_component_path);
1667    regbuf = (char*)XP_ALLOC( regbuflen );
1668    if (regbuf != NULL )
1669    {
1670        err = vr_GetUninstallItemPath(converted_component_path, regbuf, regbuflen);  
1671        if (err == REGERR_OK)
1672        {
1673            err = NR_RegDeleteKey( vreg, ROOTKEY_PRIVATE, regbuf );
1674        }
1675        else
1676        {
1677            err = REGERR_BUFTOOSMALL;
1678        }
1679        XP_FREE(regbuf);
1680    }
1681    else
1682    {
1683        err = REGERR_MEMORY;
1684    }
1685    
1686    XP_FREE(converted_component_path);
1687    return err;
1688
1689}   /* UninstallDestroy */
1690
1691VR_INTERFACE(REGERR) VR_EnumUninstall(REGENUM *state, char* userPackageName,
1692                                    int32 len1, char*regPackageName, int32 len2, XP_Bool bSharedList)
1693{
1694    REGERR err;
1695    RKEY key;
1696    RKEY key1;
1697    char regbuf[MAXREGPATHLEN+1] = {0};
1698    char temp[MAXREGPATHLEN+1] = {0};
1699   
1700    err = vr_Init();
1701    if (err != REGERR_OK)
1702        return err;
1703
1704    XP_STRCPY( regbuf, REG_UNINSTALL_DIR );
1705    if (bSharedList)
1706    {
1707        XP_STRCAT( regbuf, SHAREDSTR );
1708    }
1709    else
1710    {
1711        XP_STRCAT( regbuf, gCurstr );
1712    }  
1713                   
1714    err = NR_RegGetKey( vreg, ROOTKEY_PRIVATE, regbuf, &key );
1715    if (err != REGERR_OK)
1716        return err;
1717
1718    *regbuf = '\0';
1719    *userPackageName = '\0';
1720    err = NR_RegEnumSubkeys( vreg, key, state, regbuf, sizeof(regbuf), REGENUM_CHILDREN);
1721
1722    if (err == REGERR_OK && !bSharedList )
1723    {
1724        if (XP_STRCMP(regbuf, UNINSTALL_NAV_STR) == 0)
1725        {
1726            /* skip Communicator package, get the next one instead */
1727            err = NR_RegEnumSubkeys( vreg, key, state, regbuf, sizeof(regbuf), REGENUM_CHILDREN);
1728        }
1729    }
1730    if (err != REGERR_OK)
1731        return err;
1732
1733    err = NR_RegGetKey( vreg, key, regbuf, &key1 );
1734    if (err != REGERR_OK)
1735        return err;
1736
1737    err = NR_RegGetEntryString( vreg, key1, PACKAGENAMESTR, userPackageName, len1);
1738
1739    if (err != REGERR_OK)
1740    {
1741        *userPackageName = '\0';
1742        return err;
1743    }
1744
1745    if (len2 <= (int32)XP_STRLEN(regbuf))
1746    {
1747        err =  REGERR_BUFTOOSMALL;
1748        *userPackageName = '\0';
1749        return err;
1750    }
1751    
1752    *regPackageName = '\0';
1753    if (bSharedList)
1754    {
1755        XP_STRCPY(temp, "/");
1756        XP_STRCAT(temp, regbuf);
1757        *regbuf = '\0';
1758        XP_STRCPY(regbuf, temp);
1759    }
1760
1761    err = vr_unmanglePackageName(regbuf, regPackageName, len2);
1762    return err;
1763
1764}   /* EnumUninstall */
1765
1766/* EOF: VerReg.c */