1827 lines
45 KiB
C
1827 lines
45 KiB
C
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
*
|
|
* The contents of this file are subject to the Netscape Public
|
|
* License Version 1.1 (the "License"); you may not use this file
|
|
* except in compliance with the License. You may obtain a copy of
|
|
* the License at http://www.mozilla.org/NPL/
|
|
*
|
|
* Software distributed under the License is distributed on an "AS
|
|
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
|
* implied. See the License for the specific language governing
|
|
* rights and limitations under the License.
|
|
*
|
|
* The Original Code is Mozilla Communicator client code,
|
|
* released March 31, 1998.
|
|
*
|
|
* The Initial Developer of the Original Code is Netscape Communications
|
|
* Corporation. Portions created by Netscape are
|
|
* Copyright (C) 1998 Netscape Communications Corporation. All
|
|
* Rights Reserved.
|
|
*
|
|
* Contributor(s):
|
|
* Daniel Veditz <dveditz@netscape.com>
|
|
*/
|
|
/* ====================================================================
|
|
* VerReg.c
|
|
* XP Version Registry functions (prototype)
|
|
* ====================================================================
|
|
*/
|
|
|
|
/* --------------------------------------------------------------------
|
|
* Install 'Navigator' produces a tree of:
|
|
*
|
|
* /Components/Netscape/Web/Navigator/
|
|
* ...Path="c:\netscape\program\netscape.exe"
|
|
* ...Version=4.0.0.0
|
|
*
|
|
* --------------------------------------------------------------------
|
|
*/
|
|
#include <fcntl.h>
|
|
#include <errno.h>
|
|
|
|
#if defined(XP_WIN)
|
|
#include <io.h>
|
|
#endif
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
#ifdef STANDALONE_REGISTRY
|
|
#include <stdlib.h>
|
|
#include <assert.h>
|
|
#endif /*STANDALONE_REGISTRY*/
|
|
|
|
#include "reg.h"
|
|
#include "NSReg.h"
|
|
#include "VerReg.h"
|
|
|
|
#ifdef XP_MAC
|
|
#include <Folders.h>
|
|
#endif
|
|
|
|
/* -------- local defines ---------------
|
|
*/
|
|
#define MAXREGVERLEN 32 /* Version=12345.12345.12345.12345 */
|
|
|
|
#define VERSTR "Version"
|
|
#define CHKSTR "Check"
|
|
#define PATHSTR "Path"
|
|
#define DIRSTR "Directory"
|
|
#define NAVHOME "Navigator Home"
|
|
#define REFCSTR "RefCount"
|
|
#define SHAREDSTR "Shared"
|
|
#define PACKAGENAMESTR "PackageName"
|
|
#define SHAREDFILESSTR "/Shared Files"
|
|
|
|
#define VERSION_NAME "Communicator"
|
|
#define NAVIGATOR_NODE "/Netscape"
|
|
#define CURRENT_VER "Current Navigator"
|
|
|
|
#define PATH_ROOT(p) ( ((p) && *(p)==PATHDEL) ? ROOTKEY_VERSIONS : curver )
|
|
#define UNIX_ROOT(p) ( ((p) && *(p)==PATHDEL) ? ROOTKEY_VERSIONS : unixver )
|
|
|
|
|
|
/* ---------------------------------------------------------------------
|
|
* Global variables
|
|
* ---------------------------------------------------------------------
|
|
*/
|
|
static int isInited = 0;
|
|
static RKEY curver = 0;
|
|
static char gCurstr[MAXREGNAMELEN];
|
|
|
|
static HREG vreg = 0;
|
|
|
|
static char *app_dir = NULL;
|
|
|
|
char *verRegName = NULL;
|
|
|
|
|
|
#if defined(XP_UNIX)
|
|
/* Extra Unix variables to deal with two registries
|
|
* "vreg" is always the writable registry.
|
|
* If "vreg" is the local registry then "unixreg" will
|
|
* be the global registry read-only (unless we couldn't
|
|
* open it).
|
|
*/
|
|
#if !defined(STANDALONE_REGISTRY)
|
|
static HREG unixreg = 0;
|
|
static RKEY unixver = 0;
|
|
#endif
|
|
XP_Bool bGlobalRegistry = FALSE;
|
|
#endif
|
|
|
|
#ifndef STANDALONE_REGISTRY
|
|
PRLock *vr_lock = NULL;
|
|
#endif
|
|
|
|
|
|
/* ---------------------------------------------------------------------
|
|
* local functions
|
|
* ---------------------------------------------------------------------
|
|
*/
|
|
static REGERR vr_Init(void);
|
|
static XP_Bool vr_CompareDirs( char *dir1, char *dir2 );
|
|
static REGERR vr_SetCurrentNav( char *product, char *programPath, char *versionStr);
|
|
static REGERR vr_ParseVersion(char *verstr, VERSION *result);
|
|
|
|
#ifdef USE_CHECKSUM
|
|
static REGERR vr_GetCheck(char *path, int32 *check);
|
|
#endif
|
|
|
|
static REGERR vr_SetPathname(HREG reg, RKEY key, char *entry, char *dir);
|
|
static REGERR vr_GetPathname(HREG reg, RKEY key, char *entry, char *buf, uint32 sizebuf);
|
|
|
|
static REGERR vr_FindKey(char *name, HREG *hreg, RKEY *key);
|
|
|
|
static REGERR vr_GetUninstallItemPath(char *regPackageName, char *regbuf, uint32 regbuflen);
|
|
static REGERR vr_convertPackageName(char *regPackageName, char *convertedPackageName, uint32 convertedDataLength);
|
|
static REGERR vr_unmanglePackageName(char *mangledPackageName, char *regPackageName, uint32 regPackageLength);
|
|
|
|
#ifdef XP_MAC
|
|
static void vr_MacAliasFromPath(const char * fileName, void ** alias, int32 * length);
|
|
static char * vr_PathFromMacAlias(const void * alias, uint32 aliasLength);
|
|
#endif
|
|
|
|
/* --------------------------------------------------------------------- */
|
|
|
|
static REGERR vr_Init(void)
|
|
{
|
|
|
|
REGERR err = REGERR_OK;
|
|
char *regname = vr_findVerRegName();
|
|
#if defined(XP_UNIX) || defined(STANDALONE_REGISTRY)
|
|
char curstr[MAXREGNAMELEN];
|
|
RKEY navKey;
|
|
#endif
|
|
#ifdef XP_UNIX
|
|
char *regbuf = NULL;
|
|
#endif
|
|
|
|
#ifndef STANDALONE_REGISTRY
|
|
if (vr_lock == NULL)
|
|
return REGERR_FAIL;
|
|
#endif
|
|
PR_Lock(vr_lock);
|
|
|
|
if (!isInited)
|
|
{
|
|
#ifdef XP_UNIX
|
|
/* need browser directory to find the correct registry */
|
|
if (app_dir != NULL) {
|
|
regbuf = (char*)XP_ALLOC( 10 + XP_STRLEN(app_dir) );
|
|
if (regbuf != NULL ) {
|
|
XP_STRCPY( regbuf, app_dir );
|
|
XP_STRCAT( regbuf, "registry" );
|
|
}
|
|
else {
|
|
err = REGERR_MEMORY;
|
|
}
|
|
}
|
|
if ( err != REGERR_OK )
|
|
goto done;
|
|
|
|
if (bGlobalRegistry)
|
|
regname = regbuf;
|
|
#endif
|
|
|
|
/* Open version registry */
|
|
err = NR_RegOpen( regname, &vreg );
|
|
|
|
#ifndef STANDALONE_REGISTRY
|
|
if (err == REGERR_OK)
|
|
{
|
|
/* find/set the current nav node */
|
|
err = vr_SetCurrentNav( VERSION_NAME, app_dir, NULL );
|
|
if ( REGERR_OK != err ) {
|
|
/* couldn't find or set current nav -- big problems! */
|
|
NR_RegClose( vreg );
|
|
goto done;
|
|
}
|
|
}
|
|
|
|
#ifdef XP_UNIX
|
|
/* try to open shared Unix registry, but not an error if you can't */
|
|
unixreg = NULL;
|
|
if (!bGlobalRegistry && err == REGERR_OK ) {
|
|
unixver = 0;
|
|
if (NR_RegOpen( regbuf, &unixreg ) == REGERR_OK) {
|
|
if (NR_RegGetKey( unixreg, ROOTKEY_VERSIONS, NAVIGATOR_NODE,
|
|
&navKey) == REGERR_OK)
|
|
{
|
|
if (NR_RegGetEntryString( unixreg, navKey, CURRENT_VER,
|
|
curstr, sizeof(curstr)) == REGERR_OK )
|
|
{
|
|
NR_RegGetKey( unixreg, navKey, curstr, &unixver );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
if (err == REGERR_OK) {
|
|
/* successfully opened! */
|
|
isInited = 1;
|
|
}
|
|
goto done;
|
|
#else
|
|
if (err != REGERR_OK)
|
|
goto done;
|
|
|
|
/* Determine 'curver' key and ensure correct structure by adding */
|
|
|
|
/* ...find top-level "Navigator" node (add if missing) */
|
|
err = NR_RegAddKey( vreg, ROOTKEY_VERSIONS, NAVIGATOR_NODE, &navKey );
|
|
if (err != REGERR_OK)
|
|
goto done;
|
|
|
|
/* ...look for "Current Version" entry */
|
|
err = NR_RegGetEntryString( vreg, navKey, CURRENT_VER, curstr,
|
|
sizeof(curstr) );
|
|
if ( err == REGERR_NOFIND ) {
|
|
/* If not found create one with the built-in version */
|
|
err = NR_RegSetEntryString( vreg, navKey, CURRENT_VER, VERSION_NAME );
|
|
XP_STRCPY( curstr, VERSION_NAME );
|
|
}
|
|
if ( err != REGERR_OK )
|
|
goto done;
|
|
|
|
/* ...look for "curstr" child key of the navigator node */
|
|
err = NR_RegAddKey( vreg, navKey, curstr, &curver );
|
|
|
|
if (err == REGERR_OK) {
|
|
/* successfully opened! */
|
|
isInited = 1;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
done:
|
|
PR_Unlock(vr_lock);
|
|
#if defined(XP_UNIX) && !defined(STANDALONE_REGISTRY)
|
|
XP_FREEIF(regbuf);
|
|
#endif
|
|
return err;
|
|
|
|
} /* Init */
|
|
|
|
|
|
|
|
#ifdef XP_PC
|
|
#define VR_FILE_SEP '\\'
|
|
#endif
|
|
#ifdef XP_MAC
|
|
#define VR_FILE_SEP ':'
|
|
#endif
|
|
#ifdef XP_BEOS
|
|
#define VR_FILE_SEP '/'
|
|
#endif
|
|
#ifdef XP_UNIX
|
|
#define VR_FILE_SEP '/'
|
|
#endif
|
|
|
|
static XP_Bool vr_CompareDirs( char *dir1, char *dir2 )
|
|
{
|
|
int len1,len2;
|
|
|
|
if (!dir1 || !dir2) return FALSE;
|
|
|
|
len1 = XP_STRLEN( dir1 );
|
|
len2 = XP_STRLEN( dir2 );
|
|
|
|
if ( dir1[len1-1] == VR_FILE_SEP )
|
|
len1--;
|
|
if ( dir2[len2-1] == VR_FILE_SEP )
|
|
len2--;
|
|
|
|
if ( len1 != len2 )
|
|
return FALSE;
|
|
|
|
#ifdef XP_UNIX
|
|
return ( XP_STRNCMP(dir1, dir2, len1) == 0 );
|
|
#else
|
|
return ( XP_STRNCASECMP(dir1, dir2, len1) == 0 );
|
|
#endif
|
|
}
|
|
|
|
|
|
REGERR vr_ParseVersion(char *verstr, VERSION *result)
|
|
{
|
|
|
|
result->major = result->minor = result->release = result->build = 0;
|
|
result->major = atoi(verstr);
|
|
while (*verstr && *verstr != '.')
|
|
verstr++;
|
|
if (*verstr)
|
|
{
|
|
verstr++;
|
|
result->minor = atoi(verstr);
|
|
while (*verstr && *verstr != '.')
|
|
verstr++;
|
|
if (*verstr)
|
|
{
|
|
verstr++;
|
|
result->release = atoi(verstr);
|
|
while (*verstr && *verstr != '.')
|
|
verstr++;
|
|
if (*verstr)
|
|
{
|
|
verstr++;
|
|
result->build = atoi(verstr);
|
|
while (*verstr && *verstr != '.')
|
|
verstr++;
|
|
}
|
|
}
|
|
}
|
|
|
|
return REGERR_OK;
|
|
|
|
} /* ParseVersion */
|
|
|
|
|
|
|
|
#ifdef USE_CHECKSUM
|
|
#define BLKSIZ 16384
|
|
|
|
static REGERR vr_GetCheck(char *path, int32 *check)
|
|
{
|
|
|
|
int fh;
|
|
char *buf;
|
|
int actual;
|
|
char *p;
|
|
int i;
|
|
int chk;
|
|
|
|
XP_ASSERT(path);
|
|
XP_ASSERT(check);
|
|
|
|
*check = chk = 0;
|
|
|
|
#ifdef NEED_XP_FIXES
|
|
/* open file for read */
|
|
fh = open(path, O_RDONLY| O_BINARY);
|
|
if (fh < 0)
|
|
{
|
|
switch (errno)
|
|
{
|
|
case ENOENT: /* file not found */
|
|
return REGERR_NOFILE;
|
|
|
|
case EACCES: /* file in use */
|
|
|
|
#ifdef EMFILE
|
|
case EMFILE: /* too many files open */
|
|
#endif
|
|
default:
|
|
return REGERR_FAIL;
|
|
}
|
|
}
|
|
|
|
buf = malloc(BLKSIZ);
|
|
if (!buf)
|
|
{
|
|
close(fh);
|
|
return REGERR_MEMORY;
|
|
}
|
|
|
|
do
|
|
{
|
|
/* read a block */
|
|
actual = read(fh, buf, BLKSIZ);
|
|
/* add to checksum */
|
|
for (p=buf, i=0; i<actual; i++, p++)
|
|
chk += *p;
|
|
|
|
/* if the block was partial, we're done, else loop */
|
|
} while (actual == BLKSIZ);
|
|
|
|
/* close file */
|
|
close(fh);
|
|
free(buf);
|
|
#endif
|
|
|
|
/* return calculated checksum */
|
|
*check = chk;
|
|
|
|
return REGERR_OK;
|
|
|
|
} /* GetCheck */
|
|
|
|
#endif /* USE_CHECKSUM */
|
|
|
|
|
|
|
|
static REGERR vr_SetPathname(HREG reg, RKEY key, char *entry, char *dir)
|
|
{
|
|
REGERR err;
|
|
int32 datalen = XP_STRLEN(dir)+1; /* include '\0' */
|
|
|
|
err = NR_RegSetEntry( reg, key, entry, REGTYPE_ENTRY_FILE, dir, datalen);
|
|
|
|
return err;
|
|
}
|
|
|
|
|
|
|
|
static REGERR vr_GetPathname(HREG reg, RKEY key, char *entry, char *buf, uint32 sizebuf)
|
|
{
|
|
REGERR err;
|
|
REGINFO info;
|
|
|
|
info.size = sizeof(REGINFO);
|
|
|
|
#ifndef XP_MAC
|
|
err = NR_RegGetEntry( reg, key, entry, (void*)buf, &sizebuf );
|
|
return err;
|
|
#else
|
|
|
|
err = NR_RegGetEntryInfo( reg, key, entry, &info );
|
|
|
|
if (err != REGERR_OK)
|
|
return err;
|
|
|
|
if (info.entryType == REGTYPE_ENTRY_FILE ||
|
|
info.entryType == REGTYPE_ENTRY_STRING_UTF )
|
|
{
|
|
err = NR_RegGetEntry( reg, key, entry, (void*)buf, &sizebuf );
|
|
}
|
|
else if (info.entryType == REGTYPE_ENTRY_BYTES)
|
|
{
|
|
|
|
extern char * nr_PathFromMacAlias(const void * alias, uint32 aliasLength);
|
|
|
|
#define MAC_ALIAS_BUFFER_SIZE 4000
|
|
char stackBuf[MAC_ALIAS_BUFFER_SIZE];
|
|
uint32 stackBufSize = MAC_ALIAS_BUFFER_SIZE;
|
|
char * tempBuf;
|
|
|
|
err = NR_RegGetEntry( reg, key, entry, (void*)stackBuf, &stackBufSize );
|
|
|
|
if (err != REGERR_OK)
|
|
return err;
|
|
|
|
tempBuf = nr_PathFromMacAlias(stackBuf, stackBufSize);
|
|
|
|
if (tempBuf == NULL)
|
|
{
|
|
/* don't change error w/out changing vr_SetCurrentNav to match */
|
|
buf[0] = '\0';
|
|
err = REGERR_NOFILE;
|
|
}
|
|
else
|
|
{
|
|
if (XP_STRLEN(tempBuf) > sizebuf)
|
|
err = REGERR_BUFTOOSMALL;
|
|
else
|
|
XP_STRCPY(buf, tempBuf);
|
|
|
|
XP_FREE(tempBuf);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* what did we put here?? */
|
|
err = REGERR_BADTYPE;
|
|
}
|
|
|
|
return err;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
/* create default tree with 'installation' under Navigator */
|
|
/* set Current to the installation string */
|
|
static REGERR vr_SetCurrentNav( char *installation, char *programPath, char *versionStr)
|
|
{
|
|
REGERR err;
|
|
REGENUM state;
|
|
RKEY navKey;
|
|
int bFound;
|
|
int nCopy;
|
|
char regname[MAXREGNAMELEN];
|
|
char dirbuf[MAXREGNAMELEN];
|
|
|
|
err = NR_RegAddKey( vreg, ROOTKEY_VERSIONS, NAVIGATOR_NODE, &navKey );
|
|
if (err != REGERR_OK)
|
|
goto done;
|
|
|
|
/* ...look for "Current Version" entry */
|
|
err = NR_RegGetEntryString( vreg, navKey, CURRENT_VER, gCurstr, sizeof(gCurstr));
|
|
if ( err == REGERR_NOFIND )
|
|
{
|
|
/* No current installation, we can simply add a new one */
|
|
err = NR_RegAddKey( vreg, navKey, installation, &curver );
|
|
|
|
/* ... add Path and Version properties */
|
|
if ( err == REGERR_OK )
|
|
{
|
|
err = vr_SetPathname( vreg, curver, NAVHOME, programPath );
|
|
if ( REGERR_OK == err && versionStr != NULL && *versionStr != '\0')
|
|
{
|
|
err = NR_RegSetEntryString( vreg, curver, VERSTR, versionStr );
|
|
}
|
|
}
|
|
|
|
if ( REGERR_OK == err ) {
|
|
/* successfully added, make it the current version */
|
|
err = NR_RegSetEntryString(vreg, navKey, CURRENT_VER, installation);
|
|
}
|
|
|
|
if (err != REGERR_OK)
|
|
goto done;
|
|
}
|
|
else if ( REGERR_OK == err )
|
|
{
|
|
/* found one: if we're lucky we got the right one */
|
|
bFound = FALSE;
|
|
err = NR_RegGetKey( vreg, navKey, gCurstr, &curver );
|
|
if ( REGERR_OK == err ) {
|
|
err = vr_GetPathname( vreg, curver, NAVHOME, dirbuf, sizeof(dirbuf) );
|
|
if ( REGERR_OK == err ) {
|
|
bFound = vr_CompareDirs(dirbuf, programPath);
|
|
}
|
|
else if ( REGERR_NOFIND == err ) {
|
|
/* assume this is the right one since it's 'Current' */
|
|
err = vr_SetPathname( vreg, curver, NAVHOME, programPath );
|
|
bFound = TRUE;
|
|
}
|
|
}
|
|
|
|
/* Look for an existing installation if not found */
|
|
state = 0;
|
|
while (!bFound && ((err == REGERR_OK) || (err == REGERR_NOFILE)) ) {
|
|
err = NR_RegEnumSubkeys( vreg, navKey, &state, gCurstr,
|
|
sizeof(gCurstr), REGENUM_NORMAL );
|
|
|
|
if (REGERR_OK == err ) {
|
|
err = vr_GetPathname( vreg, state, NAVHOME, dirbuf, sizeof(dirbuf) );
|
|
if (REGERR_OK == err ) {
|
|
if (vr_CompareDirs( dirbuf, programPath )) {
|
|
bFound = TRUE;
|
|
curver = (RKEY)state;
|
|
}
|
|
}
|
|
else if ( err == REGERR_NOFIND ) {
|
|
/* wasn't a navigator node */
|
|
err = REGERR_OK;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* found the right one, make it current */
|
|
if (bFound) {
|
|
err = NR_RegSetEntryString( vreg, navKey, CURRENT_VER, gCurstr );
|
|
/* update version (curver already set) */
|
|
if ( REGERR_OK == err && versionStr != NULL && *versionStr != '\0' ) {
|
|
err = NR_RegSetEntryString( vreg, curver, VERSTR, versionStr );
|
|
}
|
|
}
|
|
/* otherwise if no current installation matches */
|
|
else if ( err == REGERR_NOMORE )
|
|
{
|
|
/* look for an empty slot to put new installation */
|
|
nCopy = 1;
|
|
XP_STRCPY( regname, installation );
|
|
do {
|
|
err = NR_RegGetKey( vreg, navKey, regname, &curver );
|
|
if (err == REGERR_OK) {
|
|
nCopy++;
|
|
sprintf( regname, "%s #%d", installation, nCopy );
|
|
}
|
|
} while (err==REGERR_OK);
|
|
|
|
if (err != REGERR_NOFIND)
|
|
goto done; /* real error, bail */
|
|
|
|
/* found an unused name -- add it */
|
|
err = NR_RegAddKey( vreg, navKey, regname, &curver );
|
|
if ( err != REGERR_OK )
|
|
goto done;
|
|
|
|
/* add path and version properties */
|
|
err = vr_SetPathname( vreg, curver, NAVHOME, programPath );
|
|
if ( REGERR_OK == err && versionStr != NULL && *versionStr != '\0' ) {
|
|
err = NR_RegSetEntryString( vreg, curver, VERSTR, versionStr );
|
|
}
|
|
|
|
if ( REGERR_OK == err ) {
|
|
/* everything's OK, make it current */
|
|
err = NR_RegSetEntryString(vreg,navKey,CURRENT_VER,regname);
|
|
}
|
|
}
|
|
}
|
|
done:
|
|
return err;
|
|
}
|
|
|
|
|
|
|
|
|
|
/* assumes registries are open (only use after vr_Init() returns OK).
|
|
* For UNIX look first in the global, then in the local if not found
|
|
* -- returns both hreg and key of the named node (if found)
|
|
*/
|
|
static REGERR vr_FindKey(char *component_path, HREG *hreg, RKEY *key)
|
|
{
|
|
REGERR err;
|
|
RKEY rootkey;
|
|
|
|
#if !defined(STANDALONE_REGISTRY) && defined(XP_UNIX)
|
|
if (unixreg != NULL) {
|
|
*hreg = unixreg;
|
|
rootkey = UNIX_ROOT(component_path);
|
|
if (rootkey)
|
|
err = NR_RegGetKey( *hreg, rootkey, component_path, key );
|
|
else
|
|
err = REGERR_NOFIND;
|
|
}
|
|
if (unixreg == NULL || err == REGERR_NOFIND )
|
|
#endif
|
|
{
|
|
*hreg = vreg;
|
|
rootkey = PATH_ROOT(component_path);
|
|
if (rootkey)
|
|
err = NR_RegGetKey( *hreg, rootkey, component_path, key );
|
|
else
|
|
err = REGERR_NOFIND;
|
|
}
|
|
|
|
return err;
|
|
}
|
|
|
|
|
|
|
|
/* ---------------------------------------------------------------------
|
|
* Interface
|
|
* ---------------------------------------------------------------------
|
|
*/
|
|
|
|
#ifdef XP_MAC
|
|
#pragma export on
|
|
#endif
|
|
|
|
#ifndef STANDALONE_REGISTRY
|
|
VR_INTERFACE(REGERR) VR_PackRegistry(void *userData, nr_RegPackCallbackFunc fn)
|
|
{
|
|
REGERR err;
|
|
|
|
/* make sure vreg (src) is open */
|
|
err = vr_Init();
|
|
if (err != REGERR_OK)
|
|
return err;
|
|
|
|
err = NR_RegPack( vreg, userData, fn );
|
|
|
|
return err;
|
|
|
|
} /* PackRegistry */
|
|
#endif /* STANDALONE_REGISTRY */
|
|
|
|
|
|
VR_INTERFACE(REGERR) VR_CreateRegistry( char *installation, char *programPath, char *versionStr )
|
|
{
|
|
REGERR err;
|
|
char * regname = vr_findVerRegName();
|
|
#ifdef XP_UNIX
|
|
char * regbuf = NULL;
|
|
#endif
|
|
|
|
if ( installation == NULL || *installation == '\0' )
|
|
return REGERR_PARAM;
|
|
|
|
#ifdef XP_UNIX
|
|
#ifndef STANDALONE_REGISTRY
|
|
if (bGlobalRegistry)
|
|
#endif
|
|
{
|
|
regbuf = (char*)XP_ALLOC( 10 + XP_STRLEN(programPath) );
|
|
if (regbuf == NULL)
|
|
return REGERR_MEMORY;
|
|
|
|
XP_STRCPY( regbuf, programPath );
|
|
XP_STRCAT( regbuf, "registry" );
|
|
regname = regbuf;
|
|
}
|
|
#endif /* XP_UNIX */
|
|
|
|
PR_Lock(vr_lock);
|
|
|
|
/* automatically creates it if not found */
|
|
err = NR_RegOpen( regname, &vreg );
|
|
if (err == REGERR_OK)
|
|
{
|
|
/* create default tree with 'installation' under Navigator */
|
|
/* set Current to the installation string */
|
|
|
|
err = vr_SetCurrentNav( installation, programPath, versionStr );
|
|
|
|
if ( REGERR_OK == err )
|
|
isInited = 1;
|
|
else
|
|
NR_RegClose( vreg );
|
|
}
|
|
|
|
PR_Unlock(vr_lock);
|
|
|
|
#if defined(XP_UNIX)
|
|
XP_FREEIF( regbuf );
|
|
#endif
|
|
return err;
|
|
|
|
} /* CreateRegistry */
|
|
|
|
|
|
VR_INTERFACE(REGERR) VR_Close(void)
|
|
{
|
|
REGERR err = REGERR_OK;
|
|
|
|
#ifndef STANDALONE_REGISTRY
|
|
if (vr_lock == NULL)
|
|
return REGERR_FAIL;
|
|
#endif
|
|
|
|
PR_Lock(vr_lock);
|
|
|
|
if (isInited) {
|
|
#if !defined(STANDALONE_REGISTRY) && defined(XP_UNIX)
|
|
if ( unixreg != NULL )
|
|
NR_RegClose( unixreg );
|
|
#endif
|
|
err = NR_RegClose( vreg );
|
|
isInited = 0;
|
|
}
|
|
|
|
PR_Unlock(vr_lock);
|
|
|
|
return err;
|
|
} /* Close */
|
|
|
|
|
|
|
|
VR_INTERFACE(REGERR) VR_GetVersion(char *component_path, VERSION *result)
|
|
{
|
|
REGERR err;
|
|
RKEY key;
|
|
HREG hreg;
|
|
VERSION ver;
|
|
char buf[MAXREGNAMELEN];
|
|
|
|
err = vr_Init();
|
|
if (err != REGERR_OK)
|
|
return err;
|
|
|
|
hreg = vreg;
|
|
|
|
err = vr_FindKey( component_path, &hreg, &key );
|
|
if (err != REGERR_OK)
|
|
return err;
|
|
|
|
err = NR_RegGetEntryString( hreg, key, VERSTR, buf, sizeof(buf) );
|
|
if (err != REGERR_OK)
|
|
return err;
|
|
|
|
vr_ParseVersion(buf, &ver);
|
|
|
|
memcpy(result, &ver, sizeof(VERSION));
|
|
|
|
return REGERR_OK;
|
|
|
|
} /* GetVersion */
|
|
|
|
|
|
|
|
VR_INTERFACE(REGERR) VR_GetPath(char *component_path, uint32 sizebuf, char *buf)
|
|
{
|
|
REGERR err;
|
|
RKEY key;
|
|
HREG hreg;
|
|
|
|
err = vr_Init();
|
|
if (err != REGERR_OK)
|
|
return err;
|
|
|
|
hreg = vreg;
|
|
|
|
err = vr_FindKey( component_path, &hreg, &key );
|
|
if (err != REGERR_OK)
|
|
return err;
|
|
|
|
err = vr_GetPathname( hreg, key, PATHSTR, buf, sizebuf );
|
|
|
|
return err;
|
|
|
|
} /* GetPath */
|
|
|
|
|
|
|
|
VR_INTERFACE(REGERR) VR_SetDefaultDirectory(char *component_path, char *directory)
|
|
{
|
|
REGERR err;
|
|
RKEY rootkey;
|
|
RKEY key;
|
|
|
|
err = vr_Init();
|
|
if (err != REGERR_OK)
|
|
return err;
|
|
|
|
rootkey = PATH_ROOT(component_path);
|
|
|
|
err = NR_RegGetKey( vreg, rootkey, component_path, &key );
|
|
if (err != REGERR_OK)
|
|
return err;
|
|
|
|
err = vr_SetPathname( vreg, key, DIRSTR, directory );
|
|
|
|
return err;
|
|
}
|
|
|
|
|
|
|
|
VR_INTERFACE(REGERR) VR_GetDefaultDirectory(char *component_path, uint32 sizebuf, char *buf)
|
|
{
|
|
REGERR err;
|
|
RKEY key;
|
|
HREG hreg;
|
|
|
|
err = vr_Init();
|
|
if (err != REGERR_OK)
|
|
return err;
|
|
|
|
hreg = vreg;
|
|
|
|
err = vr_FindKey( component_path, &hreg, &key );
|
|
if (err != REGERR_OK)
|
|
return err;
|
|
|
|
err = vr_GetPathname( hreg, key, DIRSTR, buf, sizebuf );
|
|
|
|
return err;
|
|
}
|
|
|
|
|
|
|
|
VR_INTERFACE(REGERR) VR_Install(char *component_path, char *filepath, char *version, int bDirectory)
|
|
{
|
|
REGERR err;
|
|
RKEY rootKey;
|
|
RKEY key;
|
|
|
|
/* Initialize the registry in case this is first call */
|
|
err = vr_Init();
|
|
if (err != REGERR_OK)
|
|
return err;
|
|
|
|
/* Use curver if path is relative */
|
|
rootKey = PATH_ROOT(component_path);
|
|
|
|
/* Make sure path components (keys) exist by calling Add */
|
|
/* (special "" component must always exist, and Add fails) */
|
|
if ( component_path != NULL && *component_path == '\0' ) {
|
|
err = NR_RegGetKey( vreg, rootKey, component_path, &key );
|
|
}
|
|
else {
|
|
err = NR_RegAddKey( vreg, rootKey, component_path, &key );
|
|
}
|
|
if (err != REGERR_OK)
|
|
return err;
|
|
|
|
if ( version != NULL && *version != '\0' ) {
|
|
/* Add "Version" entry with values like "4.0.0.0" */
|
|
err = NR_RegSetEntryString( vreg, key, VERSTR, version );
|
|
if (err != REGERR_OK)
|
|
goto abort;
|
|
}
|
|
|
|
if ( filepath != NULL && *filepath != '\0' ) {
|
|
/* add "Path" entry */
|
|
err = vr_SetPathname( vreg, key, (bDirectory)?DIRSTR:PATHSTR, filepath );
|
|
|
|
if (err != REGERR_OK)
|
|
goto abort;
|
|
}
|
|
|
|
return REGERR_OK;
|
|
|
|
abort:
|
|
NR_RegDeleteKey( vreg, rootKey, component_path );
|
|
return err;
|
|
|
|
} /* Install */
|
|
|
|
|
|
|
|
VR_INTERFACE(REGERR) VR_Remove(char *component_path)
|
|
{
|
|
REGERR err;
|
|
RKEY rootkey;
|
|
|
|
err = vr_Init();
|
|
if (err != REGERR_OK)
|
|
return err;
|
|
|
|
rootkey = PATH_ROOT(component_path);
|
|
|
|
return NR_RegDeleteKey( vreg, rootkey, component_path );
|
|
|
|
} /* Remove */
|
|
|
|
VR_INTERFACE(REGERR) VR_Enum(char *component_path, REGENUM *state,
|
|
char *buffer, uint32 buflen)
|
|
{
|
|
REGERR err;
|
|
RKEY rootkey;
|
|
RKEY key;
|
|
|
|
err = vr_Init();
|
|
if (err != REGERR_OK)
|
|
return err;
|
|
|
|
if ( component_path == NULL )
|
|
rootkey = ROOTKEY_VERSIONS;
|
|
else
|
|
rootkey = PATH_ROOT(component_path);
|
|
|
|
err = NR_RegGetKey( vreg, rootkey, component_path, &key );
|
|
if (err != REGERR_OK)
|
|
return err;
|
|
|
|
err = NR_RegEnumSubkeys( vreg, key, state, buffer, buflen, REGENUM_DEPTH_FIRST);
|
|
|
|
return err;
|
|
|
|
} /* Enum */
|
|
|
|
VR_INTERFACE(REGERR) VR_InRegistry(char *component_path)
|
|
{
|
|
REGERR err;
|
|
RKEY key;
|
|
HREG hreg;
|
|
|
|
err = vr_Init();
|
|
if (err != REGERR_OK)
|
|
return err;
|
|
|
|
return vr_FindKey( component_path, &hreg, &key );
|
|
} /* InRegistry */
|
|
|
|
|
|
|
|
VR_INTERFACE(REGERR) VR_ValidateComponent(char *component_path)
|
|
{
|
|
REGERR err;
|
|
RKEY key;
|
|
char path[MAXREGPATHLEN];
|
|
HREG hreg;
|
|
|
|
|
|
#ifdef USE_CHECKSUM
|
|
char buf[MAXREGNAMELEN];
|
|
long calculatedCheck;
|
|
int storedCheck;
|
|
#endif
|
|
|
|
err = vr_Init();
|
|
if (err != REGERR_OK)
|
|
return err;
|
|
|
|
err = vr_FindKey( component_path, &hreg, &key );
|
|
if ( err != REGERR_OK )
|
|
return err;
|
|
|
|
err = VR_GetPath( component_path, sizeof(path), path );
|
|
if ( err != REGERR_OK ) {
|
|
if ( err == REGERR_NOFIND ) {
|
|
err = REGERR_NOPATH;
|
|
}
|
|
return err;
|
|
}
|
|
|
|
{
|
|
struct stat statStruct;
|
|
|
|
if ( stat ( path, &statStruct ) != 0 ) {
|
|
err = REGERR_NOFILE;
|
|
}
|
|
}
|
|
if (err != REGERR_OK)
|
|
return err;
|
|
|
|
|
|
#if defined(USE_CHECKSUM) && !defined(XP_UNIX)
|
|
err = NR_RegGetEntryString( vreg, key, CHKSTR, buf, sizeof(buf) );
|
|
if (err != REGERR_OK)
|
|
return err;
|
|
|
|
storedCheck = atoi(buf);
|
|
|
|
err = vr_GetCheck(filepath, &calculatedCheck);
|
|
if (err != REGERR_OK)
|
|
return err;
|
|
|
|
if (storedCheck != calculatedCheck)
|
|
{
|
|
return REGERR_BADCHECK;
|
|
}
|
|
#endif /* USE_CHECKSUM */
|
|
|
|
return REGERR_OK;
|
|
|
|
} /* CheckEntry */
|
|
|
|
|
|
|
|
VR_INTERFACE(REGERR) VR_SetRegDirectory(const char *path)
|
|
{
|
|
char *tmp;
|
|
|
|
tmp = XP_STRDUP(path);
|
|
if (NULL == tmp) {
|
|
return REGERR_MEMORY;
|
|
}
|
|
|
|
PR_Lock(vr_lock);
|
|
|
|
XP_FREEIF(app_dir);
|
|
app_dir = tmp;
|
|
|
|
PR_Unlock(vr_lock);
|
|
|
|
return REGERR_OK;
|
|
}
|
|
|
|
|
|
|
|
VR_INTERFACE(REGERR) VR_SetRefCount(char *component_path, int refcount)
|
|
{
|
|
REGERR err;
|
|
RKEY rootKey;
|
|
RKEY key = 0;
|
|
char rcstr[MAXREGNAMELEN];
|
|
|
|
err = vr_Init();
|
|
if (err != REGERR_OK)
|
|
return err;
|
|
|
|
/* Use curver if path is relative */
|
|
rootKey = PATH_ROOT(component_path);
|
|
|
|
/* Make sure path components (keys) exist by calling Add */
|
|
/* (special "" component must always exist, and Add fails) */
|
|
if ( component_path != NULL && *component_path == '\0' ) {
|
|
err = REGERR_PARAM;
|
|
}
|
|
else {
|
|
err = NR_RegAddKey( vreg, rootKey, component_path, &key );
|
|
}
|
|
|
|
if (err != REGERR_OK)
|
|
return err;
|
|
|
|
*rcstr = '\0';
|
|
/* itoa(refcount, rcstr, 10); */
|
|
XP_SPRINTF(rcstr, "%d", refcount);
|
|
|
|
if ( rcstr != NULL && *rcstr != '\0' ) {
|
|
/* Add "RefCount" */
|
|
err = NR_RegSetEntryString( vreg, key, REFCSTR, rcstr );
|
|
}
|
|
|
|
return err;
|
|
} /* SetRefCount */
|
|
|
|
|
|
|
|
VR_INTERFACE(REGERR) VR_GetRefCount(char *component_path, int *result)
|
|
{
|
|
REGERR err;
|
|
RKEY rootkey;
|
|
RKEY key;
|
|
char buf[MAXREGNAMELEN];
|
|
|
|
*result = -1;
|
|
|
|
err = vr_Init();
|
|
if (err != REGERR_OK)
|
|
return err;
|
|
|
|
/* "Uninstall" only happens in the writable registry, so no
|
|
* need to search the shared one on Unix using vr_FindKey()
|
|
*/
|
|
rootkey = PATH_ROOT(component_path);
|
|
err = NR_RegGetKey( vreg, rootkey, component_path, &key );
|
|
if (err != REGERR_OK)
|
|
return err;
|
|
|
|
err = NR_RegGetEntryString( vreg, key, REFCSTR, buf, sizeof(buf) );
|
|
if (err != REGERR_OK)
|
|
return err;
|
|
|
|
*result = atoi( buf );
|
|
|
|
return REGERR_OK;
|
|
|
|
} /* GetRefCount */
|
|
|
|
#ifdef XP_MAC
|
|
#pragma export reset
|
|
#endif
|
|
|
|
static REGERR vr_GetUninstallItemPath(char *regPackageName, char *regbuf, uint32 regbuflen)
|
|
{
|
|
XP_Bool bSharedUninstall = FALSE;
|
|
XP_Bool bNavPackage = FALSE;
|
|
uint32 len = 0;
|
|
uint32 sharedstrlen = 0;
|
|
uint32 curstrlen = 0;
|
|
uint32 curregbuflen = 0;
|
|
|
|
/* determine install type */
|
|
if (*regPackageName == '\0') {
|
|
bNavPackage = TRUE;
|
|
}
|
|
else if ( *regPackageName == PATHDEL) {
|
|
bSharedUninstall = TRUE;
|
|
}
|
|
|
|
/* create uninstall path prefix */
|
|
len = XP_STRLEN(REG_UNINSTALL_DIR);
|
|
if (len < regbuflen)
|
|
{
|
|
XP_STRCPY( regbuf, REG_UNINSTALL_DIR );
|
|
}
|
|
else
|
|
{
|
|
return REGERR_BUFTOOSMALL;
|
|
}
|
|
if (bSharedUninstall)
|
|
{
|
|
sharedstrlen = XP_STRLEN(SHAREDSTR);
|
|
if (sharedstrlen < (regbuflen - len))
|
|
XP_STRCAT( regbuf, SHAREDSTR );
|
|
else
|
|
return REGERR_BUFTOOSMALL;
|
|
}
|
|
else
|
|
{
|
|
curstrlen = XP_STRLEN(gCurstr);
|
|
if (curstrlen < (regbuflen - len))
|
|
XP_STRCAT( regbuf, gCurstr );
|
|
else
|
|
return REGERR_BUFTOOSMALL;
|
|
if (1 < (regbuflen - len - curstrlen))
|
|
XP_STRCAT( regbuf, "/" );
|
|
else
|
|
return REGERR_BUFTOOSMALL;
|
|
}
|
|
|
|
/* add final uninstall node name */
|
|
len = 0;
|
|
curregbuflen = XP_STRLEN(regbuf);
|
|
if ( bNavPackage ) {
|
|
len = XP_STRLEN(UNINSTALL_NAV_STR);
|
|
if (len < (regbuflen - curregbuflen))
|
|
XP_STRCAT( regbuf, UNINSTALL_NAV_STR );
|
|
else
|
|
return REGERR_BUFTOOSMALL;
|
|
}
|
|
else {
|
|
len = XP_STRLEN(regPackageName);
|
|
if (len < (regbuflen - curregbuflen))
|
|
XP_STRCAT( regbuf, regPackageName );
|
|
else
|
|
return REGERR_BUFTOOSMALL;
|
|
}
|
|
return REGERR_OK;
|
|
}
|
|
|
|
|
|
/**
|
|
* Replaces all '/' with '_',in the given string.If an '_' already exists in the
|
|
* given string, it is escaped by adding another '_' to it.
|
|
*/
|
|
static REGERR vr_convertPackageName(char *regPackageName, char *convertedPackageName, uint32 convertedDataLength)
|
|
{
|
|
uint32 length = 0;
|
|
uint32 i;
|
|
uint32 j = 0;
|
|
|
|
length = XP_STRLEN(regPackageName);
|
|
|
|
if (convertedDataLength <= length)
|
|
return REGERR_BUFTOOSMALL;
|
|
|
|
for (i=0, j=0; i<length; i++, j++)
|
|
{
|
|
if (j < (convertedDataLength-1))
|
|
{
|
|
convertedPackageName[j] = regPackageName[i];
|
|
}
|
|
else
|
|
{
|
|
return REGERR_BUFTOOSMALL;
|
|
}
|
|
if (regPackageName[i] == '_')
|
|
{
|
|
if ((j+1) < (convertedDataLength-1))
|
|
{
|
|
convertedPackageName[j+1] = '_';
|
|
}
|
|
else
|
|
{
|
|
return REGERR_BUFTOOSMALL;
|
|
}
|
|
j = j + 1;
|
|
}
|
|
}
|
|
|
|
if (convertedPackageName[j-1] == '/')
|
|
convertedPackageName[j-1] = '\0';
|
|
else
|
|
{
|
|
if (j < convertedDataLength)
|
|
{
|
|
convertedPackageName[j] = '\0';
|
|
}
|
|
else
|
|
{
|
|
return REGERR_BUFTOOSMALL;
|
|
}
|
|
}
|
|
|
|
length = 0;
|
|
length = XP_STRLEN(convertedPackageName);
|
|
for (i=1; i<length; i++)
|
|
{
|
|
if (convertedPackageName[i] == '/')
|
|
convertedPackageName[i] = '_';
|
|
}
|
|
|
|
return REGERR_OK;
|
|
}
|
|
|
|
static REGERR vr_unmanglePackageName(char *mangledPackageName, char *regPackageName, uint32 regPackageLength)
|
|
{
|
|
uint32 length = 0;
|
|
uint32 i = 0;
|
|
uint32 j = 0;
|
|
|
|
length = XP_STRLEN(mangledPackageName);
|
|
|
|
if (regPackageLength <= length)
|
|
return REGERR_BUFTOOSMALL;
|
|
|
|
while (i < length)
|
|
{
|
|
if ((mangledPackageName[i] != '_') || (i == length-1)){
|
|
if (j < (regPackageLength - 1))
|
|
regPackageName[j] = mangledPackageName[i];
|
|
else
|
|
return REGERR_BUFTOOSMALL;
|
|
j = j + 1;
|
|
i = i + 1;
|
|
} else if (mangledPackageName[i + 1] != '_') {
|
|
if (j < (regPackageLength - 1))
|
|
regPackageName[j] = '/';
|
|
else
|
|
return REGERR_BUFTOOSMALL;
|
|
j = j + 1;
|
|
i = i + 1;
|
|
} else {
|
|
if (j < (regPackageLength - 1))
|
|
regPackageName[j] = '_';
|
|
else
|
|
return REGERR_BUFTOOSMALL;
|
|
j = j + 1;
|
|
i = i + 2;
|
|
}
|
|
}
|
|
if (j < regPackageLength)
|
|
regPackageName[j] = '\0';
|
|
else
|
|
return REGERR_BUFTOOSMALL;
|
|
return REGERR_OK;
|
|
}
|
|
|
|
#ifdef XP_MAC
|
|
#pragma export on
|
|
#endif
|
|
|
|
VR_INTERFACE(REGERR) VR_UninstallCreateNode(char *regPackageName, char *userPackageName)
|
|
{
|
|
REGERR err;
|
|
RKEY key = 0;
|
|
char *regbuf;
|
|
uint32 regbuflen = 0;
|
|
|
|
err = vr_Init();
|
|
if (err != REGERR_OK)
|
|
return err;
|
|
|
|
if ( regPackageName == NULL )
|
|
err = REGERR_PARAM;
|
|
|
|
if ( userPackageName == NULL)
|
|
err = REGERR_PARAM;
|
|
|
|
regbuflen = 256 + XP_STRLEN(regPackageName);
|
|
regbuf = (char*)XP_ALLOC( regbuflen );
|
|
if (regbuf != NULL )
|
|
{
|
|
err = vr_GetUninstallItemPath(regPackageName, regbuf, regbuflen);
|
|
if (err != REGERR_OK)
|
|
{
|
|
XP_FREE(regbuf);
|
|
return err;
|
|
}
|
|
err = NR_RegAddKey( vreg, ROOTKEY_PRIVATE, regbuf, &key );
|
|
XP_FREE(regbuf);
|
|
}
|
|
else
|
|
{
|
|
err = REGERR_MEMORY;
|
|
}
|
|
|
|
if (err == REGERR_OK)
|
|
err = NR_RegSetEntryString(vreg, key, PACKAGENAMESTR, userPackageName);
|
|
|
|
return err;
|
|
|
|
} /* UninstallCreateNode */
|
|
|
|
VR_INTERFACE(REGERR) VR_GetUninstallUserName(char *regPackageName, char *outbuf, uint32 buflen)
|
|
{
|
|
REGERR err;
|
|
RKEY key = 0;
|
|
char *regbuf = NULL;
|
|
char *convertedName = NULL;
|
|
uint32 convertedDataLength = 0;
|
|
uint32 regbuflen = 0;
|
|
|
|
err = vr_Init();
|
|
if (err != REGERR_OK)
|
|
return err;
|
|
|
|
if ( regPackageName == NULL || *regPackageName == '\0' || outbuf == NULL )
|
|
return REGERR_PARAM;
|
|
|
|
convertedDataLength = 2 * XP_STRLEN(regPackageName) + 1;
|
|
convertedName = (char*)XP_ALLOC(convertedDataLength);
|
|
if (convertedName == NULL ) {
|
|
err = REGERR_MEMORY;
|
|
return err;
|
|
}
|
|
|
|
err = vr_convertPackageName(regPackageName, convertedName, convertedDataLength);
|
|
if (err != REGERR_OK) {
|
|
XP_FREE(convertedName);
|
|
return err;
|
|
}
|
|
regbuflen = 256 + XP_STRLEN(convertedName);
|
|
regbuf = (char*)XP_ALLOC( regbuflen );
|
|
if (regbuf == NULL ) {
|
|
err = REGERR_MEMORY;
|
|
} else {
|
|
err = vr_GetUninstallItemPath(convertedName, regbuf, regbuflen);
|
|
if (err == REGERR_OK) {
|
|
err = NR_RegGetKey( vreg, ROOTKEY_PRIVATE, regbuf, &key );
|
|
}
|
|
XP_FREE(regbuf);
|
|
}
|
|
|
|
if (err == REGERR_OK)
|
|
err = NR_RegGetEntryString( vreg, key, PACKAGENAMESTR, outbuf, buflen );
|
|
|
|
XP_FREE(convertedName);
|
|
return err;
|
|
|
|
} /* GetUninstallName */
|
|
|
|
VR_INTERFACE(REGERR) VR_UninstallAddFileToList(char *regPackageName, char *vrName)
|
|
{
|
|
REGERR err;
|
|
RKEY key = 0;
|
|
char *regbuf;
|
|
uint32 regbuflen = 0;
|
|
uint32 curregbuflen = 0;
|
|
uint32 len = 0;
|
|
|
|
err = vr_Init();
|
|
if (err != REGERR_OK)
|
|
return err;
|
|
|
|
if ( regPackageName == NULL )
|
|
err = REGERR_PARAM;
|
|
|
|
if ( vrName == NULL )
|
|
err = REGERR_PARAM;
|
|
|
|
regbuflen = 256 + XP_STRLEN(regPackageName);
|
|
regbuf = (char*)XP_ALLOC( regbuflen );
|
|
if (regbuf != NULL )
|
|
{
|
|
err = vr_GetUninstallItemPath(regPackageName, regbuf, regbuflen);
|
|
if (err == REGERR_OK)
|
|
{
|
|
curregbuflen = XP_STRLEN(regbuf);
|
|
len = XP_STRLEN(SHAREDFILESSTR);
|
|
if (len < (regbuflen - curregbuflen))
|
|
{
|
|
XP_STRCAT(regbuf, SHAREDFILESSTR);
|
|
err = NR_RegAddKey( vreg, ROOTKEY_PRIVATE, regbuf, &key );
|
|
}
|
|
else
|
|
err = REGERR_BUFTOOSMALL;
|
|
}
|
|
XP_FREEIF(regbuf);
|
|
}
|
|
else
|
|
{
|
|
err = REGERR_MEMORY;
|
|
}
|
|
|
|
if (err == REGERR_OK)
|
|
err = NR_RegSetEntryString( vreg, key, vrName, "");
|
|
|
|
return err;
|
|
|
|
} /* UninstallAddFileToList */
|
|
|
|
VR_INTERFACE(REGERR) VR_UninstallFileExistsInList(char *regPackageName, char *vrName)
|
|
{
|
|
REGERR err;
|
|
RKEY key = 0;
|
|
char *regbuf;
|
|
char sharedfilesstr[MAXREGNAMELEN];
|
|
uint32 regbuflen = 0;
|
|
uint32 curregbuflen = 0;
|
|
uint32 len = 0;
|
|
|
|
err = vr_Init();
|
|
if (err != REGERR_OK)
|
|
return err;
|
|
|
|
if ( regPackageName == NULL )
|
|
err = REGERR_PARAM;
|
|
|
|
if ( vrName == NULL )
|
|
err = REGERR_PARAM;
|
|
|
|
regbuflen = 256 + XP_STRLEN(regPackageName);
|
|
regbuf = (char*)XP_ALLOC( regbuflen );
|
|
if (regbuf != NULL )
|
|
{
|
|
err = vr_GetUninstallItemPath(regPackageName, regbuf, regbuflen);
|
|
if (err == REGERR_OK)
|
|
{
|
|
curregbuflen = XP_STRLEN(regbuf);
|
|
len = XP_STRLEN(SHAREDFILESSTR);
|
|
if (len < (regbuflen - curregbuflen))
|
|
{
|
|
XP_STRCAT(regbuf, SHAREDFILESSTR);
|
|
err = NR_RegGetKey( vreg, ROOTKEY_PRIVATE, regbuf, &key );
|
|
}
|
|
else
|
|
err = REGERR_BUFTOOSMALL;
|
|
}
|
|
XP_FREEIF(regbuf);
|
|
}
|
|
else
|
|
{
|
|
err = REGERR_MEMORY;
|
|
}
|
|
|
|
if (err == REGERR_OK)
|
|
err = NR_RegGetEntryString( vreg, key, vrName, sharedfilesstr,
|
|
sizeof(sharedfilesstr) );
|
|
return err;
|
|
|
|
} /* UninstallFileExistsInList */
|
|
|
|
VR_INTERFACE(REGERR) VR_UninstallEnumSharedFiles(char *component_path, REGENUM *state,
|
|
char *buffer, uint32 buflen)
|
|
{
|
|
REGERR err;
|
|
RKEY key = 0;
|
|
char *regbuf;
|
|
char *converted_component_path;
|
|
uint32 convertedDataLength = 0;
|
|
uint32 regbuflen = 0;
|
|
uint32 curregbuflen = 0;
|
|
uint32 len = 0;
|
|
|
|
err = vr_Init();
|
|
if (err != REGERR_OK)
|
|
return err;
|
|
|
|
if ( component_path == NULL )
|
|
return REGERR_PARAM;
|
|
|
|
convertedDataLength = 2 * XP_STRLEN(component_path) + 1;
|
|
converted_component_path = (char*)XP_ALLOC(convertedDataLength);
|
|
if (converted_component_path == NULL ) {
|
|
err = REGERR_MEMORY;
|
|
return err;
|
|
}
|
|
err = vr_convertPackageName(component_path, converted_component_path, convertedDataLength);
|
|
if (err != REGERR_OK)
|
|
{
|
|
XP_FREEIF(converted_component_path);
|
|
return err;
|
|
}
|
|
|
|
regbuflen = 256 + XP_STRLEN(converted_component_path);
|
|
regbuf = (char*)XP_ALLOC( regbuflen );
|
|
if (regbuf != NULL )
|
|
{
|
|
err = vr_GetUninstallItemPath(converted_component_path, regbuf, regbuflen);
|
|
if (err == REGERR_OK)
|
|
{
|
|
curregbuflen = XP_STRLEN(regbuf);
|
|
len = XP_STRLEN(SHAREDFILESSTR);
|
|
if (len < (regbuflen - curregbuflen))
|
|
{
|
|
XP_STRCAT(regbuf, SHAREDFILESSTR);
|
|
err = NR_RegGetKey( vreg, ROOTKEY_PRIVATE, regbuf, &key );
|
|
}
|
|
else
|
|
err = REGERR_BUFTOOSMALL;
|
|
}
|
|
XP_FREE(regbuf);
|
|
}
|
|
else
|
|
{
|
|
err = REGERR_MEMORY;
|
|
}
|
|
|
|
XP_FREE(converted_component_path);
|
|
|
|
if (err == REGERR_OK)
|
|
err = NR_RegEnumEntries( vreg, key, state, buffer, buflen, NULL);
|
|
|
|
return err;
|
|
|
|
} /* UninstallEnumSharedFiles */
|
|
|
|
VR_INTERFACE(REGERR) VR_UninstallDeleteFileFromList(char *component_path, char *vrName)
|
|
{
|
|
REGERR err;
|
|
RKEY key = 0;
|
|
char *regbuf;
|
|
char *converted_component_path;
|
|
uint32 convertedDataLength = 0;
|
|
uint32 regbuflen = 0;
|
|
uint32 curregbuflen = 0;
|
|
uint32 len = 0;
|
|
|
|
err = vr_Init();
|
|
if (err != REGERR_OK)
|
|
return err;
|
|
|
|
if ( component_path == NULL )
|
|
err = REGERR_PARAM;
|
|
|
|
if ( vrName == NULL )
|
|
err = REGERR_PARAM;
|
|
|
|
convertedDataLength = 2 * XP_STRLEN(component_path) + 1;
|
|
converted_component_path = (char*)XP_ALLOC(convertedDataLength);
|
|
if (converted_component_path == NULL ) {
|
|
err = REGERR_MEMORY;
|
|
return err;
|
|
}
|
|
err = vr_convertPackageName(component_path, converted_component_path, convertedDataLength);
|
|
if (err != REGERR_OK)
|
|
{
|
|
XP_FREEIF(converted_component_path);
|
|
return err;
|
|
}
|
|
|
|
regbuflen = 256 + XP_STRLEN(converted_component_path);
|
|
regbuf = (char*)XP_ALLOC( regbuflen );
|
|
if (regbuf != NULL )
|
|
{
|
|
err = vr_GetUninstallItemPath(converted_component_path, regbuf, regbuflen);
|
|
if (err == REGERR_OK)
|
|
{
|
|
curregbuflen = XP_STRLEN(regbuf);
|
|
len = XP_STRLEN(SHAREDFILESSTR);
|
|
if (len < (regbuflen - curregbuflen))
|
|
{
|
|
XP_STRCAT(regbuf, SHAREDFILESSTR);
|
|
err = NR_RegGetKey( vreg, ROOTKEY_PRIVATE, regbuf, &key );
|
|
}
|
|
else
|
|
err = REGERR_BUFTOOSMALL;
|
|
}
|
|
XP_FREE(regbuf);
|
|
}
|
|
else
|
|
{
|
|
err = REGERR_MEMORY;
|
|
}
|
|
|
|
XP_FREE(converted_component_path);
|
|
|
|
if (err == REGERR_OK)
|
|
err = NR_RegDeleteEntry( vreg, key, vrName);
|
|
|
|
return err;
|
|
|
|
} /* UninstallDeleteFileFromList */
|
|
|
|
VR_INTERFACE(REGERR) VR_UninstallDeleteSharedFilesKey(char *component_path)
|
|
{
|
|
REGERR err;
|
|
char *regbuf;
|
|
char *converted_component_path;
|
|
uint32 convertedDataLength = 0;
|
|
uint32 regbuflen = 0;
|
|
uint32 curregbuflen = 0;
|
|
uint32 len = 0;
|
|
|
|
err = vr_Init();
|
|
if (err != REGERR_OK)
|
|
return err;
|
|
|
|
if ( component_path == NULL )
|
|
err = REGERR_PARAM;
|
|
|
|
convertedDataLength = 2 * XP_STRLEN(component_path) + 1;
|
|
converted_component_path = (char*)XP_ALLOC(convertedDataLength);
|
|
if (converted_component_path == NULL ) {
|
|
err = REGERR_MEMORY;
|
|
return err;
|
|
}
|
|
err = vr_convertPackageName(component_path, converted_component_path, convertedDataLength);
|
|
if (err != REGERR_OK)
|
|
{
|
|
XP_FREEIF(converted_component_path);
|
|
return err;
|
|
}
|
|
|
|
regbuflen = 256 + XP_STRLEN(converted_component_path);
|
|
regbuf = (char*)XP_ALLOC( regbuflen );
|
|
if (regbuf != NULL )
|
|
{
|
|
err = vr_GetUninstallItemPath(converted_component_path, regbuf, regbuflen);
|
|
if (err == REGERR_OK)
|
|
{
|
|
curregbuflen = XP_STRLEN(regbuf);
|
|
len = XP_STRLEN(SHAREDFILESSTR);
|
|
if (len < (regbuflen - curregbuflen))
|
|
{
|
|
XP_STRCAT(regbuf, SHAREDFILESSTR);
|
|
err = NR_RegDeleteKey( vreg, ROOTKEY_PRIVATE, regbuf );
|
|
}
|
|
else
|
|
err = REGERR_BUFTOOSMALL;
|
|
}
|
|
XP_FREE(regbuf);
|
|
}
|
|
else
|
|
{
|
|
err = REGERR_MEMORY;
|
|
}
|
|
|
|
XP_FREE(converted_component_path);
|
|
return err;
|
|
|
|
} /* UninstallDeleteSharedFilesKey */
|
|
|
|
VR_INTERFACE(REGERR) VR_UninstallDestroy(char *component_path)
|
|
{
|
|
REGERR err;
|
|
char *regbuf;
|
|
char *converted_component_path;
|
|
uint32 convertedDataLength = 0;
|
|
uint32 regbuflen = 0;
|
|
|
|
err = vr_Init();
|
|
if (err != REGERR_OK)
|
|
return err;
|
|
|
|
if ( component_path == NULL )
|
|
err = REGERR_PARAM;
|
|
|
|
convertedDataLength = 2 * XP_STRLEN(component_path) + 1;
|
|
converted_component_path = (char*)XP_ALLOC(convertedDataLength);
|
|
if (converted_component_path == NULL ) {
|
|
err = REGERR_MEMORY;
|
|
return err;
|
|
}
|
|
err = vr_convertPackageName(component_path, converted_component_path, convertedDataLength);
|
|
if (err != REGERR_OK)
|
|
{
|
|
XP_FREEIF(converted_component_path);
|
|
return err;
|
|
}
|
|
|
|
regbuflen = 256 + XP_STRLEN(converted_component_path);
|
|
regbuf = (char*)XP_ALLOC( regbuflen );
|
|
if (regbuf != NULL )
|
|
{
|
|
err = vr_GetUninstallItemPath(converted_component_path, regbuf, regbuflen);
|
|
if (err == REGERR_OK)
|
|
{
|
|
err = NR_RegDeleteKey( vreg, ROOTKEY_PRIVATE, regbuf );
|
|
}
|
|
else
|
|
{
|
|
err = REGERR_BUFTOOSMALL;
|
|
}
|
|
XP_FREE(regbuf);
|
|
}
|
|
else
|
|
{
|
|
err = REGERR_MEMORY;
|
|
}
|
|
|
|
XP_FREE(converted_component_path);
|
|
return err;
|
|
|
|
} /* UninstallDestroy */
|
|
|
|
VR_INTERFACE(REGERR) VR_EnumUninstall(REGENUM *state, char* userPackageName,
|
|
int32 len1, char*regPackageName, int32 len2, XP_Bool bSharedList)
|
|
{
|
|
REGERR err;
|
|
RKEY key;
|
|
RKEY key1;
|
|
char regbuf[MAXREGPATHLEN+1] = {0};
|
|
char temp[MAXREGPATHLEN+1] = {0};
|
|
|
|
err = vr_Init();
|
|
if (err != REGERR_OK)
|
|
return err;
|
|
|
|
XP_STRCPY( regbuf, REG_UNINSTALL_DIR );
|
|
if (bSharedList)
|
|
{
|
|
XP_STRCAT( regbuf, SHAREDSTR );
|
|
}
|
|
else
|
|
{
|
|
XP_STRCAT( regbuf, gCurstr );
|
|
}
|
|
|
|
err = NR_RegGetKey( vreg, ROOTKEY_PRIVATE, regbuf, &key );
|
|
if (err != REGERR_OK)
|
|
return err;
|
|
|
|
*regbuf = '\0';
|
|
*userPackageName = '\0';
|
|
err = NR_RegEnumSubkeys( vreg, key, state, regbuf, sizeof(regbuf), REGENUM_CHILDREN);
|
|
|
|
if (err == REGERR_OK && !bSharedList )
|
|
{
|
|
if (XP_STRCMP(regbuf, UNINSTALL_NAV_STR) == 0)
|
|
{
|
|
/* skip Communicator package, get the next one instead */
|
|
err = NR_RegEnumSubkeys( vreg, key, state, regbuf, sizeof(regbuf), REGENUM_CHILDREN);
|
|
}
|
|
}
|
|
if (err != REGERR_OK)
|
|
return err;
|
|
|
|
err = NR_RegGetKey( vreg, key, regbuf, &key1 );
|
|
if (err != REGERR_OK)
|
|
return err;
|
|
|
|
err = NR_RegGetEntryString( vreg, key1, PACKAGENAMESTR, userPackageName, len1);
|
|
|
|
if (err != REGERR_OK)
|
|
{
|
|
*userPackageName = '\0';
|
|
return err;
|
|
}
|
|
|
|
if (len2 <= (int32)XP_STRLEN(regbuf))
|
|
{
|
|
err = REGERR_BUFTOOSMALL;
|
|
*userPackageName = '\0';
|
|
return err;
|
|
}
|
|
|
|
*regPackageName = '\0';
|
|
if (bSharedList)
|
|
{
|
|
XP_STRCPY(temp, "/");
|
|
XP_STRCAT(temp, regbuf);
|
|
*regbuf = '\0';
|
|
XP_STRCPY(regbuf, temp);
|
|
}
|
|
|
|
err = vr_unmanglePackageName(regbuf, regPackageName, len2);
|
|
return err;
|
|
|
|
} /* EnumUninstall */
|
|
|
|
#ifdef XP_MAC
|
|
#pragma export reset
|
|
#endif
|
|
|
|
/* EOF: VerReg.c */
|