ltabb 8ed5afe62c Free the lizard
git-svn-id: svn://10.0.0.236/trunk@10 18797224-902f-48f8-a5cc-f745e15eee43
1998-03-28 02:44:41 +00:00

1148 lines
27 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.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/* ====================================================================
* 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
#ifndef STANDALONE_REGISTRY
#include "xp_mcom.h"
#include "xp_core.h"
#ifndef NSPR20
#include "prosdep.h"
#else
#ifdef XP_MAC
#include <Folders.h>
#include "prosdep.h"
#else
#include "md/prosdep.h"
#endif
#endif
#include "prmon.h"
#ifdef BROKEN
#include "su_folderspec.h"
#endif
#else
#ifdef XP_MAC
#include <types.h>
#include <stat.h>
#else
#include <sys/types.h>
#include <sys/stat.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#endif
#include "reg.h"
#include "NSReg.h"
#include "VerReg.h"
/* -------- 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 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 HREG vreg = 0;
#if !defined(STANDALONE_REGISTRY) && 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).
*/
static HREG unixreg = 0;
static RKEY unixver = 0;
XP_Bool bGlobalRegistry = FALSE;
#endif
#ifndef STANDALONE_REGISTRY
PRMonitor *vr_monitor = NULL;
#endif
/* ---------------------------------------------------------------------
* local functions
* ---------------------------------------------------------------------
*/
static REGERR vr_Init(void);
static REGERR vr_BuildVersion(VERSION *pVer, char *buf);
static 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);
#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 = "";
char curstr[MAXREGNAMELEN];
RKEY navKey;
#ifndef STANDALONE_REGISTRY
char *curPath = NULL;
#ifdef XP_UNIX
char *regbuf = NULL;
#endif
PR_EnterMonitor(vr_monitor);
#endif
if (!isInited)
{
#ifndef STANDALONE_REGISTRY
#ifdef BROKEN
curPath = FE_GetDirectoryPath(eCommunicatorFolder);
#else
/* can't use Version Registry interface until "BROKEN" works */
err = REGERR_FAIL;
goto done;
#endif
#ifdef XP_UNIX
if (curPath != NULL) {
regbuf = (char*)XP_ALLOC( 10 + XP_STRLEN(curPath) );
if (regbuf != NULL ) {
XP_STRCPY( regbuf, curPath );
XP_STRCAT( regbuf, "registry" );
}
}
if ( curPath == NULL || regbuf == NULL ) {
err = REGERR_MEMORY;
goto done;
}
if (bGlobalRegistry)
regname = regbuf;
#endif
#endif
/* Open version registry */
err = NR_RegOpen( regname, &vreg );
#ifndef STANDALONE_REGISTRY
if (err == REGERR_NOFILE) {
/* create it if not found */
err = VR_CreateRegistry( VERSION_NAME, curPath, "" );
}
else if (err == REGERR_OK) {
/* otherwise find/set the current nav node */
err = vr_SetCurrentNav( VERSION_NAME, curPath, NULL );
}
#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:
#ifndef STANDALONE_REGISTRY
PR_ExitMonitor(vr_monitor);
XP_FREEIF(curPath);
#ifdef XP_UNIX
XP_FREEIF(regbuf);
#endif
#endif
return err;
} /* Init */
#ifdef XP_PC
#define VR_FILE_SEP '\\'
#endif
#ifdef XP_MAC
#define VR_FILE_SEP ':'
#endif
#ifdef XP_UNIX
#define VR_FILE_SEP '/'
#endif
static Bool vr_CompareDirs( char *dir1, char *dir2 )
{
int len1,len2;
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 */
case EMFILE: /* too many files open */
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)
{
/* save in platform/OS charset, so use BYTES. */
REGERR err;
void * alias = dir;
int32 datalen = XP_STRLEN(dir)+1; /* include '\0' */
#ifdef XP_MAC
alias = NULL;
vr_MacAliasFromPath(dir, &alias, &datalen);
#endif
err = NR_RegSetEntry( reg, key, entry, REGTYPE_ENTRY_BYTES, alias, datalen);
#ifdef XP_MAC
XP_FREEIF(alias);
#endif
return err;
}
static REGERR vr_GetPathname(HREG reg, RKEY key, char *entry, char *buf, uint32 sizebuf)
{
/* stored as BYTES since it's platform OS charset */
#ifndef XP_MAC
REGERR err;
err = NR_RegGetEntry( reg, key, entry, (void*)buf, &sizebuf );
return err;
#else
REGERR err;
REGINFO info;
info.size = sizeof(REGINFO);
err = NR_RegGetEntryInfo( reg, key, entry,&info );
if (err != REGERR_OK)
return err;
if (info.entryType == REGTYPE_ENTRY_STRING_UTF) /* Assume that it is a file name */
err = NR_RegGetEntry( reg, key, entry, (void*)buf, &sizebuf );
else
{
#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 = vr_PathFromMacAlias(stackBuf, stackBufSize);
if (tempBuf == NULL)
err = REGERR_FAIL;
else
if (XP_STRLEN(tempBuf) > sizebuf)
err = REGERR_BUFTOOSMALL;
else
XP_STRCPY(buf, tempBuf);
XP_FREEIF(tempBuf);
}
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 curstr[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, curstr, sizeof(curstr));
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) {
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, curstr, &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 = NR_RegEnumSubkeys( vreg, navKey, &state, curstr,
sizeof(curstr), 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, curstr );
/* update version (curver already set) */
if ( REGERR_OK == err && versionStr != NULL ) {
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 ) {
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;
}
#ifdef XP_MAC
#include <Aliases.h>
#include <TextUtils.h>
#include <Memory.h>
#include "FullPath.h"
/* returns an alias as a malloc'd pointer.
* On failure, *alias is NULL
*/
static void vr_MacAliasFromPath(const char * fileName, void ** alias, int32 * length)
{
OSErr err;
FSSpec fs;
AliasHandle macAlias;
*alias = NULL;
*length = 0;
c2pstr((char*)fileName);
err = FSMakeFSSpec(0, 0, (unsigned char *)fileName, &fs);
p2cstr((unsigned char *)fileName);
if ( err != noErr )
return;
err = NewAlias(NULL, &fs, &macAlias);
if ( (err != noErr) || ( macAlias == NULL ))
return;
*length = GetHandleSize( (Handle) macAlias );
*alias = XP_ALLOC( *length );
if ( *alias == NULL )
{
DisposeHandle((Handle)macAlias);
return;
}
HLock( (Handle) macAlias );
XP_MEMCPY(*alias, *macAlias , *length);
HUnlock( (Handle) macAlias );
DisposeHandle( (Handle) macAlias);
return;
}
/* resolves an alias, and returns a full path to the Mac file
* If the alias changed, it would be nice to update our alias pointers
*/
static char * vr_PathFromMacAlias(const void * alias, uint32 aliasLength)
{
OSErr err;
AliasHandle h = NULL;
Handle fullPath = NULL;
short fullPathLength;
char * cpath = NULL;
FSSpec fs;
Boolean ignore; /* Change flag, it would be nice to change the alias on disk
if the file location changed */
/* Copy the alias to a handle and resolve it */
h = (AliasHandle) NewHandle(aliasLength);
if ( h == NULL)
goto fail;
HLock( (Handle) h);
XP_MEMCPY( *h, alias, aliasLength );
HUnlock( (Handle) h);
err = ResolveAlias(NULL, h, &fs, &ignore);
if (err != noErr)
goto fail;
/* if the file is inside the trash, assume that user has deleted
it and that we do not want to look at it */
{
short vRefNum;
long dirID;
err = FindFolder(fs.vRefNum, kTrashFolderType, false, &vRefNum, &dirID);
if (err == noErr)
if (dirID == fs.parID) /* File is inside the trash */
goto fail;
}
/* Get the full path and create a char * out of it */
err = GetFullPath(fs.vRefNum, fs.parID,fs.name, &fullPathLength, &fullPath);
if ( (err != noErr) || (fullPath == NULL) )
goto fail;
cpath = (char*) XP_ALLOC(fullPathLength + 1);
if ( cpath == NULL)
goto fail;
HLock( fullPath );
XP_MEMCPY(cpath, *fullPath, fullPathLength);
cpath[fullPathLength] = 0;
HUnlock( fullPath );
/* Drop through */
fail:
if (h != NULL)
DisposeHandle( (Handle) h);
if (fullPath != NULL)
DisposeHandle( fullPath);
return cpath;
}
#endif
/* 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);
err = NR_RegGetKey( *hreg, rootkey, component_path, key );
}
if (unixreg == NULL || err == REGERR_NOFIND )
#endif
{
*hreg = vreg;
rootkey = PATH_ROOT(component_path);
err = NR_RegGetKey( *hreg, rootkey, component_path, key );
}
return err;
}
/* ---------------------------------------------------------------------
* Interface
* ---------------------------------------------------------------------
*/
VR_INTERFACE(REGERR) VR_PackRegistry(void)
{
REGERR err;
/* make sure vreg (src) is open */
err = vr_Init();
if (err != REGERR_OK)
return err;
err = NR_RegPack( vreg );
return err;
} /* PackRegistry */
VR_INTERFACE(REGERR) VR_CreateRegistry( char *installation, char *programPath, char *versionStr )
{
FILEHANDLE fh;
REGERR err;
XP_StatStruct st;
char * regname = "";
#if !defined(STANDALONE_REGISTRY) && defined(XP_UNIX)
char * regbuf = NULL;
#endif
if ( installation == NULL || *installation == '\0' )
return REGERR_PARAM;
#if !defined(STANDALONE_REGISTRY) && defined(XP_UNIX)
if (bGlobalRegistry)
{
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
#ifdef STANDALONE_REGISTRY
/* standalone registry automatically creates it if not found */
fh = XP_FileOpen( regname, xpRegistry, XP_FILE_UPDATE_BIN );
#else
if ( ( XP_Stat ( regname, &st, xpRegistry ) == 0) )
fh = XP_FileOpen( regname, xpRegistry, XP_FILE_UPDATE_BIN );
else
/* create a new empty registry */
fh = XP_FileOpen( regname, xpRegistry, XP_FILE_WRITE_BIN );
#endif
if (fh == NULL) {
err = REGERR_FAIL;
goto done;
}
XP_FileClose(fh);
err = NR_RegOpen( regname, &vreg );
if (err != REGERR_OK)
goto done;
/* 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;
done:
#if !defined(STANDALONE_REGISTRY) && defined(XP_UNIX)
XP_FREEIF( regbuf );
#endif
return err;
} /* CreateRegistry */
#ifdef XP_MAC
#pragma export on
#endif
VR_INTERFACE(REGERR) VR_Close(void)
{
REGERR err = REGERR_OK;
#ifndef STANDALONE_REGISTRY
PR_EnterMonitor(vr_monitor);
#endif
if (isInited) {
#if !defined(STANDALONE_REGISTRY) && defined(XP_UNIX)
if ( unixreg != NULL )
NR_RegClose( unixreg );
#endif
err = NR_RegClose( vreg );
isInited = 0;
}
#ifndef STANDALONE_REGISTRY
PR_ExitMonitor(vr_monitor);
#endif
return err;
} /* Close */
VR_INTERFACE(REGERR) VR_GetVersion(char *component_path, VERSION *result)
{
REGERR err;
RKEY rootkey;
RKEY key;
HREG hreg;
VERSION ver;
char buf[MAXREGNAMELEN];
err = vr_Init();
if (err != REGERR_OK)
return err;
hreg = vreg;
#if !defined(STANDALONE_REGISTRY) && defined(XP_UNIX)
err = vr_FindKey( component_path, &hreg, &key );
#else
rootkey = PATH_ROOT(component_path);
err = NR_RegGetKey( vreg, rootkey, component_path, &key );
#endif
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 rootkey;
RKEY key;
HREG hreg;
err = vr_Init();
if (err != REGERR_OK)
return err;
hreg = vreg;
#if !defined(STANDALONE_REGISTRY) && defined(XP_UNIX)
err = vr_FindKey( component_path, &hreg, &key );
#else
rootkey = PATH_ROOT(component_path);
err = NR_RegGetKey( vreg, rootkey, component_path, &key );
#endif
if (err != REGERR_OK)
return err;
err = vr_GetPathname( hreg, key, PATHSTR, buf, sizebuf );
return err;
} /* GetPath */
#ifdef XP_MAC
#pragma export reset
#endif
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 = NR_RegSetEntryString( vreg, key, DIRSTR, directory ); */
err = vr_SetPathname( vreg, key, DIRSTR, directory );
return err;
}
VR_INTERFACE(REGERR) VR_GetDefaultDirectory(char *component_path, uint32 sizebuf, char *buf)
{
REGERR err;
RKEY rootkey;
RKEY key;
HREG hreg;
err = vr_Init();
if (err != REGERR_OK)
return err;
hreg = vreg;
#if !defined(STANDALONE_REGISTRY) && defined(XP_UNIX)
err = vr_FindKey( component_path, &hreg, &key );
#else
rootkey = PATH_ROOT(component_path);
err = NR_RegGetKey( vreg, rootkey, component_path, &key );
#endif
if (err != REGERR_OK)
return err;
/* err = NR_RegGetEntryString( vreg, key, DIRSTR, buf, sizebuf ); */
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(REGENUM *state, char *buffer, uint32 buflen)
{
REGERR err;
err = vr_Init();
if (err != REGERR_OK)
return err;
return NR_RegEnumSubkeys( vreg, ROOTKEY_VERSIONS, state, buffer, buflen, REGENUM_DESCEND);
}
#ifdef XP_MAC
#pragma export on
#endif
VR_INTERFACE(REGERR) VR_InRegistry(char *component_path)
{
REGERR err;
RKEY rootkey;
RKEY key;
HREG hreg;
err = vr_Init();
if (err != REGERR_OK)
return err;
#if !defined(STANDALONE_REGISTRY) && defined(XP_UNIX)
return vr_FindKey( component_path, &hreg, &key );
#else
rootkey = PATH_ROOT(component_path);
return NR_RegGetKey( vreg, rootkey, component_path, &key );
#endif
} /* InRegistry */
VR_INTERFACE(REGERR) VR_ValidateComponent(char *component_path)
{
REGERR err;
RKEY rootkey;
RKEY key;
HREG hreg;
char path[MAXREGPATHLEN];
char *url = NULL;
char *urlPath;
XP_StatStruct s;
#ifdef USE_CHECKSUM
char buf[MAXREGNAMELEN];
long calculatedCheck;
int storedCheck;
#endif
err = vr_Init();
if (err != REGERR_OK)
return err;
#if !defined(STANDALONE_REGISTRY) && defined(XP_UNIX)
err = vr_FindKey( component_path, &hreg, &key );
#else
rootkey = PATH_ROOT(component_path);
err = NR_RegGetKey( vreg, rootkey, component_path, &key );
#endif
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;
}
urlPath = path;
#ifndef STANDALONE_REGISTRY
url = XP_PlatformFileToURL(path);
if ( url == NULL )
return REGERR_MEMORY;
urlPath = url+7;
#endif
if ( XP_Stat( urlPath, &s, xpURL ) != 0 ) {
err = REGERR_NOFILE;
}
XP_FREEIF(url);
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)
{
/* printf("File %s checksum was %d, not %d as expected.\n",
filepath, calculatedCheck, storedCheck);
*/
return REGERR_BADCHECK;
}
#endif /* USE_CHECKSUM */
return REGERR_OK;
} /* CheckEntry */
#ifdef XP_MAC
#pragma export reset
#endif
/* EOF: VerReg.c */