Back to index

lightning-sunbird  0.9+nobinonly
Defines | Functions | Variables
reg.c File Reference
#include <stdio.h>
#include <string.h>
#include "prtypes.h"
#include "prlog.h"
#include "prerror.h"
#include "prprf.h"
#include "reg.h"
#include "NSReg.h"
#include "VerReg.h"

Go to the source code of this file.

Defines

#define SELF_REPAIR   1

Functions

static void nr_AddNode (REGFILE *pReg)
static void nr_DeleteNode (REGFILE *pReg)
static REGFILEvr_findRegFile (const char *filename)
static REGERR nr_OpenFile (const char *path, FILEHANDLE *fh)
static REGERR nr_CloseFile (FILEHANDLE *fh)
static REGERR nr_ReadFile (FILEHANDLE fh, REGOFF offset, int32 len, void *buffer)
static REGERR nr_WriteFile (FILEHANDLE fh, REGOFF offset, int32 len, void *buffer)
static REGERR nr_LockRange (FILEHANDLE fh, REGOFF offset, int32 len)
static REGERR nr_UnlockRange (FILEHANDLE fh, REGOFF offset, int32 len)
static int32 nr_GetFileLength (FILEHANDLE fh)
static uint32 nr_ReadLong (char *buffer)
static uint16 nr_ReadShort (char *buffer)
static void nr_WriteLong (uint32 num, char *buffer)
static void nr_WriteShort (uint16 num, char *buffer)
static REGERR nr_ReadHdr (REGFILE *reg)
static REGERR nr_WriteHdr (REGFILE *reg)
static REGERR nr_CreateRoot (REGFILE *reg)
static REGERR nr_Lock (REGFILE *reg)
static REGERR nr_Unlock (REGFILE *reg)
static REGERR nr_ReadDesc (REGFILE *reg, REGOFF offset, REGDESC *desc)
static REGERR nr_ReadName (REGFILE *reg, REGDESC *desc, uint32 buflen, char *buf)
static REGERR nr_ReadData (REGFILE *reg, REGDESC *desc, uint32 buflen, char *buf)
static REGERR nr_WriteDesc (REGFILE *reg, REGDESC *desc)
static REGERR nr_WriteString (REGFILE *reg, char *string, REGDESC *desc)
static REGERR nr_WriteData (REGFILE *reg, char *string, uint32 len, REGDESC *desc)
static REGERR nr_AppendDesc (REGFILE *reg, REGDESC *desc, REGOFF *result)
static REGERR nr_AppendName (REGFILE *reg, char *name, REGDESC *desc)
static REGERR nr_AppendString (REGFILE *reg, char *string, REGDESC *desc)
static REGERR nr_AppendData (REGFILE *reg, char *string, uint32 len, REGDESC *desc)
static XP_Bool nr_IsValidUTF8 (char *string)
static REGERR nr_NextName (const char *pPath, char *buf, uint32 bufsize, const char **newPath)
static REGERR nr_RemoveName (char *path)
static REGERR nr_CatName (REGFILE *reg, REGOFF node, char *path, uint32 bufsize, REGDESC *desc)
static REGERR nr_ReplaceName (REGFILE *reg, REGOFF node, char *path, uint32 bufsize, REGDESC *desc)
static REGERR nr_Find (REGFILE *reg, REGOFF offParent, const char *pPath, REGDESC *pDesc, REGOFF *pPrev, REGOFF *pParent, XP_Bool raw)
static REGERR nr_FindAtLevel (REGFILE *reg, REGOFF offFirst, const char *pName, REGDESC *pDesc, REGOFF *pOffPrev)
static REGERR nr_CreateSubKey (REGFILE *reg, REGOFF parent, REGDESC *pDesc, char *name)
static REGERR nr_CreateEntryString (REGFILE *reg, REGDESC *pParent, char *name, char *value)
static REGERR nr_CreateEntry (REGFILE *reg, REGDESC *pParent, char *name, uint16 type, char *buffer, uint32 length)
static REGOFF nr_TranslateKey (REGFILE *reg, RKEY key)
static REGERR nr_InitStdRkeys (REGFILE *reg)
static XP_Bool nr_ProtectedNode (REGFILE *reg, REGOFF key)
static REGERR nr_RegAddKey (REGFILE *reg, RKEY key, char *path, RKEY *newKey, XP_Bool raw)
static REGERR nr_RegDeleteKey (REGFILE *reg, RKEY key, char *path, XP_Bool raw)
static REGERR nr_RegOpen (const char *filename, HREG *hReg)
static REGERR nr_RegClose (HREG hReg)
static char * nr_GetUsername ()
static const char * nr_GetRegName (const char *name)
static int nr_RegSetBufferSize (HREG hReg, int bufsize)
 VR_INTERFACE (REGERR)
 VR_INTERFACE (void)

Variables

static PRLockreglist_lock = NULL
static REGFILERegList = NULL
static int32 regStartCount = 0
char * globalRegName = NULL
static char * user_name = NULL
PRLockvr_lock

Define Documentation

Definition at line 60 of file reg.c.


Function Documentation

static void nr_AddNode ( REGFILE pReg) [static]

Definition at line 378 of file reg.c.

{
    /* add node to head of list */
    pReg->next = RegList;
    pReg->prev = NULL;

    RegList = pReg;

    if ( pReg->next != NULL ) {
        pReg->next->prev = pReg;
    }
}

Here is the caller graph for this function:

static REGERR nr_AppendData ( REGFILE reg,
char *  string,
uint32  len,
REGDESC desc 
) [static]

Definition at line 1241 of file reg.c.

{
    REGERR err;

    XP_ASSERT(reg);
    XP_ASSERT(string);
    XP_ASSERT(desc);

    if (reg->readOnly)
        return REGERR_READONLY;

    if ( len == 0 )
        return REGERR_PARAM;

    if ( len > MAXREGVALUELEN )
        return REGERR_NAMETOOLONG;

    /* save the string */
    err = nr_WriteFile(reg->fh, reg->hdr.avail, len, string);
    if (err == REGERR_OK)
    {
        desc->value     = reg->hdr.avail;
        desc->valuelen  = len;
        desc->valuebuf  = len;

        reg->hdr.avail += len;
        reg->hdrDirty   = 1;
#if NOCACHE_HDR
        err = nr_WriteHdr(reg);
#endif
    }

    return err;

}   /* nr_AppendData */

Here is the call graph for this function:

Here is the caller graph for this function:

static REGERR nr_AppendDesc ( REGFILE reg,
REGDESC desc,
REGOFF result 
) [static]

Definition at line 1068 of file reg.c.

{

    REGERR err;
    char descBuf[ DESC_SIZE ];

    XP_ASSERT(reg);
    XP_ASSERT(desc);
    XP_ASSERT(result);

    *result = 0;

    if (reg->readOnly)
        return REGERR_READONLY;

    desc->location = reg->hdr.avail;

    /* convert to XP int format */
    nr_WriteLong ( desc->location,  descBuf + DESC_LOCATION );
    nr_WriteLong ( desc->name,      descBuf + DESC_NAME );
    nr_WriteShort( desc->namelen,   descBuf + DESC_NAMELEN );
    nr_WriteShort( desc->type,      descBuf + DESC_TYPE );
    nr_WriteLong ( desc->left,      descBuf + DESC_LEFT );
    nr_WriteLong ( desc->value,     descBuf + DESC_VALUE );
    nr_WriteLong ( desc->valuelen,  descBuf + DESC_VALUELEN );
    nr_WriteLong ( desc->parent,    descBuf + DESC_PARENT );

    if ( TYPE_IS_ENTRY(desc->type) ) {
        XP_ASSERT( 0 == desc->down );
        nr_WriteLong( desc->valuebuf,  descBuf + DESC_VALUEBUF );
    }
    else {  /* TYPE is KEY */
        XP_ASSERT( 0 == desc->valuebuf );
        nr_WriteLong( desc->down,      descBuf + DESC_DOWN );
    }

    err = nr_WriteFile(reg->fh, reg->hdr.avail, DESC_SIZE, descBuf);

    if (err == REGERR_OK)
    {
        *result = reg->hdr.avail;
        reg->hdr.avail += DESC_SIZE;
        reg->hdrDirty = 1;
#if NOCACHE_HDR
        err = nr_WriteHdr(reg);
#endif
    }

    return err;

}   /* AppendDesc */

Here is the call graph for this function:

Here is the caller graph for this function:

static REGERR nr_AppendName ( REGFILE reg,
char *  name,
REGDESC desc 
) [static]

Definition at line 1122 of file reg.c.

{
    REGERR err;
    int len;
    char *p;

    XP_ASSERT(reg);
    XP_ASSERT(name);
    XP_ASSERT(desc);

    if (!nr_IsValidUTF8(name))
        return REGERR_BADUTF8;
    if (reg->readOnly)
        return REGERR_READONLY;

    len = XP_STRLEN(name) + 1;

    /* check for valid name parameter */
    if ( len == 1 )
        return REGERR_PARAM;

    if ( len > MAXREGNAMELEN )
        return REGERR_NAMETOOLONG;

    for ( p = name; (*p != 0); p++ ) {
        if ( INVALID_NAME_CHAR(*p) )
            return REGERR_BADNAME;
    }

    /* save the name */
    err = nr_WriteFile(reg->fh, reg->hdr.avail, len, name);

    /* if write successful update the desc and hdr */
    if (err == REGERR_OK)
    {
        desc->namelen = (uint16)len;
        desc->name = reg->hdr.avail;
        reg->hdr.avail += len;
        reg->hdrDirty = 1;
#if NOCACHE_HDR
        err = nr_WriteHdr(reg);
#endif
    }

    return err;

}   /* nr_AppendName */

Here is the call graph for this function:

Here is the caller graph for this function:

static REGERR nr_AppendString ( REGFILE reg,
char *  string,
REGDESC desc 
) [static]

Definition at line 1224 of file reg.c.

{
    uint32 len;

    XP_ASSERT(string);
    if (!nr_IsValidUTF8(string))
        return REGERR_BADUTF8;
    if (reg->readOnly)
        return REGERR_READONLY;
    len = XP_STRLEN(string) + 1;

    return nr_AppendData( reg, string, len, desc );

}   /* nr_AppendString */

Here is the call graph for this function:

Here is the caller graph for this function:

static REGERR nr_CatName ( REGFILE reg,
REGOFF  node,
char *  path,
uint32  bufsize,
REGDESC desc 
) [static]

Definition at line 1412 of file reg.c.

{
    REGERR err = REGERR_OK;

    char   *p;
    uint32 len = XP_STRLEN(path);

    if (len > 0)
    {
        p = &path[len-1];
        if (*p != PATHDEL)
        {
            if ( len < bufsize ) {
                p++;
                *p = PATHDEL;
                len++;
            }
            else
                err = REGERR_BUFTOOSMALL;
        }
        p++;    /* point one past PATHDEL */
    }
    else
        p = path;

    if ( err == REGERR_OK ) {
        err = nr_ReadDesc( reg, node, desc );
        if ( err == REGERR_OK ) {
            err = nr_ReadName( reg, desc, bufsize-len, p );
        }
    }

    return err;

}   /* CatName */

Here is the call graph for this function:

static REGERR nr_CloseFile ( FILEHANDLE fh) [static]

Definition at line 525 of file reg.c.

{
    /* NOTE: 'fh' is a pointer, unlike other Close functions
     *       This is necessary so that nr_CloseFile can set it to NULL
     */

    XP_ASSERT( fh != NULL );
    if ( VALID_FILEHANDLE(*fh) )
        XP_FileClose(*fh);
    (*fh) = NULL;
    return REGERR_OK;

}   /* CloseFile */

Here is the caller graph for this function:

static REGERR nr_CreateEntry ( REGFILE reg,
REGDESC pParent,
char *  name,
uint16  type,
char *  buffer,
uint32  length 
) [static]

Definition at line 1776 of file reg.c.

{
    REGDESC desc;
    REGERR  err;

    XP_ASSERT(reg);
    XP_ASSERT(pParent);
    XP_ASSERT(name);
    XP_ASSERT(value);

    XP_MEMSET( &desc, 0, sizeof(REGDESC) );

    err = nr_AppendName(reg, name, &desc);
    if (err != REGERR_OK)
        return err;

    err = nr_AppendData(reg, value, length, &desc);
    if (err != REGERR_OK)
        return err;

    desc.type = type;
    desc.left = pParent->value;
    desc.down = 0;
    desc.parent = pParent->location;

    err = nr_AppendDesc(reg, &desc, &pParent->value);
    if (err != REGERR_OK)
        return err;

    /* printf("nr_AddEntry: %s=%s @0x%lx\n", name, value, pParent->value); */

    return nr_WriteDesc(reg, pParent);

}   /* nr_CreateEntry */

Here is the call graph for this function:

static REGERR nr_CreateEntryString ( REGFILE reg,
REGDESC pParent,
char *  name,
char *  value 
) [static]

Definition at line 1739 of file reg.c.

{
    REGDESC desc;
    REGERR  err;

    XP_ASSERT(reg);
    XP_ASSERT(pParent);
    XP_ASSERT(name);
    XP_ASSERT(value);

    XP_MEMSET( &desc, 0, sizeof(REGDESC) );

    err = nr_AppendName(reg, name, &desc);
    if (err != REGERR_OK)
        return err;

    err = nr_AppendString(reg, value, &desc);
    if (err != REGERR_OK)
        return err;

    desc.type = REGTYPE_ENTRY_STRING_UTF;
    desc.left = pParent->value;
    desc.down = 0;
    desc.parent = pParent->location;

    err = nr_AppendDesc(reg, &desc, &pParent->value);
    if (err != REGERR_OK)
        return err;

    /* printf("nr_AddEntry: %s=%s @0x%lx\n", name, value, pParent->value); */

    return nr_WriteDesc(reg, pParent);

}   /* nr_CreateEntryString */

Here is the call graph for this function:

static REGERR nr_CreateRoot ( REGFILE reg) [static]

Definition at line 866 of file reg.c.

{
    /* Called when an empty file is detected by ReadHdr */
    REGERR err;
    REGDESC root;

    XP_ASSERT(reg);

    /* Create 'hdr' */
    reg->hdr.magic      = MAGIC_NUMBER;
    reg->hdr.verMajor   = MAJOR_VERSION;
    reg->hdr.verMinor   = MINOR_VERSION;
    reg->hdr.root       = 0;
    reg->hdr.avail      = HDRRESERVE;

    /* Create root descriptor */
    root.location   = 0;
    root.left       = 0;
    root.value      = 0;
    root.down       = 0;
    root.type       = REGTYPE_KEY;
    root.valuelen   = 0;
    root.valuebuf   = 0;
    root.parent     = 0;

    err = nr_AppendName(reg, ROOTKEY_STR, &root);
    if (err != REGERR_OK)
        return err;

    err = nr_AppendDesc(reg, &root, &reg->hdr.root);
    if (err != REGERR_OK)
        return err;

    return nr_WriteHdr(reg);    /* actually commit to disk */

    /* Create standard top-level nodes */

}   /* CreateRoot */

Here is the call graph for this function:

Here is the caller graph for this function:

static REGERR nr_CreateSubKey ( REGFILE reg,
REGOFF  parent,
REGDESC pDesc,
char *  name 
) [static]

Definition at line 1690 of file reg.c.

{
    /* nr_CreateSubKey does NO error checking--callers *MUST*
     * ensure that there are no duplicates
     */
    REGDESC desc;
    REGERR err;

    XP_ASSERT(reg);
    XP_ASSERT(pDesc);
    XP_ASSERT(name);

    err = nr_AppendName(reg, name, &desc);
    if (err != REGERR_OK)
        return err;

    desc.type = REGTYPE_KEY;
    desc.left = 0;
    desc.down = 0;
    desc.value = 0;
    desc.valuelen = 0;
    desc.valuebuf = 0;
    desc.parent   = parent;

    if ( parent == pDesc->location ) {
        /* It's a parent desc, so no siblings */
        err = nr_AppendDesc(reg, &desc, &pDesc->down);
    }
    else {
        /* It's a sibling desc */
        XP_ASSERT( pDesc->left == 0 ); /* not the end of chain! */
        err = nr_AppendDesc(reg, &desc, &pDesc->left);
    }
    if (err != REGERR_OK)
        return err;

    /* write out the fixed up parent/sibling desc */
    err = nr_WriteDesc(reg, pDesc);
    COPYDESC(pDesc, &desc);

    return err;

}   /* nr_CreateSubKey */

Here is the call graph for this function:

Here is the caller graph for this function:

static void nr_DeleteNode ( REGFILE pReg) [static]

Definition at line 391 of file reg.c.

{
    /* if at head of list... */
    if ( pReg->prev == NULL ) {
        RegList = pReg->next;
    }
    else {
        pReg->prev->next = pReg->next;
    }

    if ( pReg->next != NULL ) {
        pReg->next->prev = pReg->prev;
    }

    /* free memory */
#ifndef STANDALONE_REGISTRY
    if ( pReg->lock != NULL )
        PR_DestroyLock( pReg->lock );
#endif
    XP_FREEIF( pReg->filename );
    XP_FREE( pReg );
}

Here is the call graph for this function:

Here is the caller graph for this function:

static REGERR nr_Find ( REGFILE reg,
REGOFF  offParent,
const char *  pPath,
REGDESC pDesc,
REGOFF pPrev,
REGOFF pParent,
XP_Bool  raw 
) [static]

Definition at line 1547 of file reg.c.

{

    REGERR  err;
    REGDESC desc;
    REGOFF  offPrev = 0;
    char    namebuf[MAXREGNAMELEN];
    const char    *p;

    XP_ASSERT( pPath != NULL );
    XP_ASSERT( offParent >= HDRRESERVE );
    XP_ASSERT( VALID_FILEHANDLE( reg->fh ) );

    if (pPrev)
        *pPrev = 0;
    if (pParent)
        *pParent = 0;

    /* read starting desc */
    err = nr_ReadDesc( reg, offParent, &desc);

    if (raw == TRUE) {
        if ( err == REGERR_OK ) {
            /* save current location as parent of next segment */
            offParent = desc.location;
            /* look for name at next level down */
            err = nr_FindAtLevel(reg, desc.down, pPath, &desc, &offPrev);
        }
    }
    else {
        /* Walk 'path', reading keys into 'desc' */
        p = pPath;
        while ( err == REGERR_OK ) 
        {
            err = nr_NextName(p, namebuf, sizeof(namebuf), &p);

            if ( err == REGERR_OK ) {
                /* save current location as parent of next segment */
                offParent = desc.location;
                /* look for name at next level down */
                err = nr_FindAtLevel(reg, desc.down, namebuf, &desc, &offPrev);
            }
        }
    }

    if ( (raw == FALSE && err == REGERR_NOMORE) ||
            (raw == TRUE && err == REGERR_OK) ) {
        /* we found all the segments of the path--success! */
        err = REGERR_OK;

        if (pDesc) {
            COPYDESC(pDesc, &desc);
        }
        if (pPrev) {
            *pPrev = offPrev;
        }
        if (pParent) {
            *pParent = offParent;
        }
    }
    
    return err;

}   /* nr_Find */

Here is the call graph for this function:

Here is the caller graph for this function:

static REGERR nr_FindAtLevel ( REGFILE reg,
REGOFF  offFirst,
const char *  pName,
REGDESC pDesc,
REGOFF pOffPrev 
) [static]

Definition at line 1635 of file reg.c.

{
    char    namebuf[MAXREGNAMELEN];
    REGDESC desc;
    REGERR  err;
    REGOFF  prev = 0;

    /* Note: offset=0 when there's no 'down' or 'left' */
    XP_ASSERT(reg);
    XP_ASSERT(offset < reg->hdr.avail);
    XP_ASSERT(pName);
    XP_ASSERT(*pName);

    while ( offset != 0 )
    {
        /* get name of next node */
        err = nr_ReadDesc(reg, offset, &desc);
        if (err != REGERR_OK)
            return err;

        err = nr_ReadName(reg, &desc, sizeof(namebuf), namebuf);
        if (err != REGERR_OK)
            return err;

        /* check to see if it's the one we want */
        if (XP_STRCMP(namebuf, pName) == 0) {
            /* Found it! Signaled by non-zero offset */
            break;
        }

        /* advance to the next node */
        prev = offset;
        offset = desc.left;
    }

    if ( pDesc != NULL && (prev || offset)) {
        /* prev and offset BOTH null means we never loaded a desc */
        COPYDESC( pDesc, &desc );
    }
    if ( pOffPrev != NULL ) {
        *pOffPrev = prev;
    }

    if ( offset != 0 ) /* if we found one */
        return REGERR_OK;
    else
        return REGERR_NOFIND;
}   /* FindAtLevel */

Here is the call graph for this function:

Here is the caller graph for this function:

static int32 nr_GetFileLength ( FILEHANDLE  fh) [static]

Definition at line 652 of file reg.c.

{
    int32 length;
    int32 curpos;

    curpos = XP_FileTell(fh);
    XP_FileSeek(fh, 0, SEEK_END);
    length = XP_FileTell(fh);
    XP_FileSeek(fh, curpos, SEEK_SET);
    return length;

}   /* GetFileLength */

Here is the caller graph for this function:

static const char * nr_GetRegName ( const char *  name) [static]

Definition at line 2327 of file reg.c.

{
    if (name == NULL || *name == '\0') {
        XP_ASSERT( globalRegName != NULL );
        return globalRegName;
    } else {
        return name;
    }
}

Here is the caller graph for this function:

static char * nr_GetUsername ( ) [static]

Definition at line 2318 of file reg.c.

{
  if (NULL == user_name) {
    return "default";
  } else {
    return user_name;
  }
}

Here is the caller graph for this function:

static REGERR nr_InitStdRkeys ( REGFILE reg) [static]

Definition at line 1909 of file reg.c.

{
    REGERR      err = REGERR_OK;
    RKEY        key;

    XP_ASSERT( reg != NULL );

    /* initialize to invalid key values */
    XP_MEMSET( &reg->rkeys, 0, sizeof(STDNODES) );

    /* Add each key before looking it up.  Adding an already
     * existing key is harmless, and these MUST exist.
     */

    /* ROOTKEY_USERS */
    err = nr_RegAddKey( reg, reg->hdr.root, ROOTKEY_USERS_STR, &key, FALSE );
    if ( err != REGERR_OK )
        return err;
    reg->rkeys.users = key;

    /* ROOTKEY_COMMON */
    err = nr_RegAddKey( reg, reg->hdr.root, ROOTKEY_COMMON_STR, &key, FALSE );
    if ( err != REGERR_OK ) 
        return err;
    reg->rkeys.common = key;

    /* ROOTKEY_VERSIONS */
    err = nr_RegAddKey( reg, reg->hdr.root, ROOTKEY_VERSIONS_STR, &key, FALSE );
    if ( err != REGERR_OK )
        return err;
    reg->rkeys.versions = key;

    /* ROOTKEY_CURRENT_USER */
    /* delay until first use -- see nr_TranslateKey */

    /* ROOTKEY_PRIVATE */
    err = nr_RegAddKey( reg, reg->hdr.root, ROOTKEY_PRIVATE_STR, &key, FALSE );
    if ( err != REGERR_OK ) 
        return err;
    reg->rkeys.privarea = key;

    return err;
}   /* nr_InitStdRkeys */

Here is the call graph for this function:

Here is the caller graph for this function:

static XP_Bool nr_IsValidUTF8 ( char *  string) [static]

Definition at line 1277 of file reg.c.

{
    int follow = 0;
    char *c;
    unsigned char ch;

    XP_ASSERT(string);
    if ( !string )
        return FALSE;

    for ( c = string; *c != '\0'; c++ )
    {
        ch = (unsigned char)*c;
        if( follow == 0 )
        {
            /* expecting an initial byte */
            if ( ch <= 0x7F )
            {
                /* standard byte -- do nothing */
            }
            else if ((0xC0 & ch) == 0x80)
            {
                /* follow byte illegal here */
                return FALSE;
            }
            else if ((0xE0 & ch) == 0xC0)
            {
                follow = 1;
            }
            else if ((0xF0 & ch) == 0xE0)
            {
                follow = 2;
            }
            else
            { 
                /* unexpected (unsupported) initial byte */
                return FALSE;
            }
        }
        else 
        {
            XP_ASSERT( follow > 0 );
            if ((0xC0 & ch) == 0x80)
            {
                /* expecting follow byte and found one */
                follow--;
            }
            else 
            {
                /* invalid state */
                return FALSE;
            }
        }
    } /* for */

    if ( follow != 0 )
    {
        /* invalid state -- interrupted character */
        return FALSE;
    }
    
    return TRUE;
}   /* checks if a string is UTF-8 encoded */

Here is the caller graph for this function:

static REGERR nr_Lock ( REGFILE reg) [static]

Definition at line 907 of file reg.c.

{
    REGERR status;

    /* lock file */
    status = nr_LockRange(reg->fh, 0, sizeof(REGHDR));

    if (status == REGERR_OK)
    {
        /* lock the object */
        PR_Lock( reg->lock );

#if NOCACHE_HDR
        /* try to refresh header info */
        status = nr_ReadHdr(reg);
        if ( status != REGERR_OK ) {
            PR_Unlock( reg->lock );
        }
#endif
    }

    return status;
}   /* Lock */

Here is the call graph for this function:

static REGERR nr_LockRange ( FILEHANDLE  fh,
REGOFF  offset,
int32  len 
) [static]

Definition at line 631 of file reg.c.

{
    /* TODO: Implement XP lock function with built-in retry. */

    return REGERR_OK;

}   /* LockRange */

Here is the caller graph for this function:

static REGERR nr_NextName ( const char *  pPath,
char *  buf,
uint32  bufsize,
const char **  newPath 
) [static]

Definition at line 1357 of file reg.c.

{
    uint32 len = 0;
    REGERR err = REGERR_OK;

    /* initialization and validation */
    XP_ASSERT(buf);

    *newPath = NULL;
    *buf = '\0';

    if ( pPath==NULL || *pPath=='\0' )
        return REGERR_NOMORE;

    /* ... skip an initial path delimiter */
    if ( *pPath == PATHDEL ) {
        pPath++;

        if ( *pPath == '\0' )
            return REGERR_NOMORE;
    }

    /* ... missing name segment or initial blank are errors*/
    if ( *pPath == PATHDEL || *pPath == ' ' )
        return REGERR_BADNAME;

    /* copy first path segment into return buf */
    while ( *pPath != '\0' && *pPath != PATHDEL )
    {
        if ( len == bufsize ) {
            err = REGERR_NAMETOOLONG;
            break;
        }
        if ( *pPath < ' ' && *pPath > 0 )
            return REGERR_BADNAME;

        *buf++ = *pPath++;
        len++;
    }
    *buf = '\0';

    /* ... name segment can't end with blanks, either */
    if ( ' ' == *(buf-1) )
        return REGERR_BADNAME;

    /* return a pointer to the start of the next segment */
    *newPath = pPath;

    return err;

}   /* nr_NextName */

Here is the caller graph for this function:

static REGERR nr_OpenFile ( const char *  path,
FILEHANDLE fh 
) [static]

Definition at line 489 of file reg.c.

{
    PR_ASSERT( path != NULL );
    PR_ASSERT( fh != NULL );

    /* Open the file for exclusive random read/write */
    *fh = XP_FileOpen(path, XP_FILE_UPDATE_BIN);
    if ( !VALID_FILEHANDLE(*fh) )
    {
        XP_StatStruct st;
        if ( XP_Stat( path, &st ) != 0 )
        {
            /* file doesn't exist, so create */
            *fh = XP_FileOpen(path, XP_FILE_TRUNCATE_BIN);
        }
    }

    if ( !VALID_FILEHANDLE(*fh) )
    {
      /* For whatever reason we failed every attempt of getting */
      /* a read/write registry. Let's try a read-only registry. */
      (*fh) = XP_FileOpen(path, XP_FILE_READ_BIN);
      if ( VALID_FILEHANDLE(*fh) )
        return REGERR_READONLY;
      else
        /* we are in big trouble now */
        return REGERR_FAIL;
    }

    /* succeded in getting a read/write registry */
    return REGERR_OK;

}   /* OpenFile */

Here is the caller graph for this function:

static XP_Bool nr_ProtectedNode ( REGFILE reg,
REGOFF  key 
) [static]

Definition at line 1955 of file reg.c.

{
    if ( (key == reg->hdr.root) ||
         (key == reg->rkeys.users) ||
         (key == reg->rkeys.versions) ||
         (key == reg->rkeys.common) ||
         (key == reg->rkeys.current_user) )
    {
        return TRUE;
    }
    else
        return FALSE;
}

Here is the caller graph for this function:

static REGERR nr_ReadData ( REGFILE reg,
REGDESC desc,
uint32  buflen,
char *  buf 
) [static]

Definition at line 1010 of file reg.c.

{

    REGERR err;

    XP_ASSERT(reg);
    XP_ASSERT(desc->value > 0);
    XP_ASSERT(desc->value < reg->hdr.avail);
    XP_ASSERT(buflen > 0);
    XP_ASSERT(buf);

    if ( desc->valuelen > buflen )
        return REGERR_BUFTOOSMALL;

    err = nr_ReadFile(reg->fh, desc->value, desc->valuelen, buf);

    return err;

}   /* nr_ReadData */

Here is the call graph for this function:

static REGERR nr_ReadDesc ( REGFILE reg,
REGOFF  offset,
REGDESC desc 
) [static]

Definition at line 942 of file reg.c.

{

    REGERR err;
    char descBuf[ DESC_SIZE ];

    XP_ASSERT(reg);
    XP_ASSERT(offset >= HDRRESERVE);
    XP_ASSERT(offset < reg->hdr.avail);
    XP_ASSERT(desc);

    err = nr_ReadFile(reg->fh, offset, DESC_SIZE, &descBuf);
    if (err == REGERR_OK)
    {
        desc->location  = nr_ReadLong ( descBuf + DESC_LOCATION );
        desc->name      = nr_ReadLong ( descBuf + DESC_NAME );
        desc->namelen   = nr_ReadShort( descBuf + DESC_NAMELEN );
        desc->type      = nr_ReadShort( descBuf + DESC_TYPE );
        desc->left      = nr_ReadLong ( descBuf + DESC_LEFT );
        desc->value     = nr_ReadLong ( descBuf + DESC_VALUE );
        desc->valuelen  = nr_ReadLong ( descBuf + DESC_VALUELEN );
        desc->parent    = nr_ReadLong ( descBuf + DESC_PARENT );

        if ( TYPE_IS_ENTRY(desc->type) ) {
            desc->down = 0;
            desc->valuebuf  = nr_ReadLong( descBuf + DESC_VALUEBUF );
        }
        else {  /* TYPE is KEY */
            desc->down      = nr_ReadLong( descBuf + DESC_DOWN );
            desc->valuebuf  = 0;
        }

        if (desc->location != offset)
            err = REGERR_BADLOCN;
        else if ( desc->type & REGTYPE_DELETED )
            err = REGERR_DELETED;
    }

    return err;

}   /* ReadDesc */

Here is the call graph for this function:

Here is the caller graph for this function:

static REGERR nr_ReadFile ( FILEHANDLE  fh,
REGOFF  offset,
int32  len,
void buffer 
) [static]

Definition at line 541 of file reg.c.

{
#if VERIFY_READ
    #define        FILLCHAR  0xCC
    unsigned char* p;
    unsigned char* dbgend = (unsigned char*)buffer+len;
#endif

    int32 readlen;
    REGERR err = REGERR_OK;

    XP_ASSERT(len > 0);
    XP_ASSERT(buffer != NULL);
    XP_ASSERT(fh != NULL);

#if VERIFY_READ
    XP_MEMSET(buffer, FILLCHAR, len);
#endif

    if (XP_FileSeek(fh, offset, SEEK_SET) != 0 ) {
        err = REGERR_FAIL;
    }
    else {
        readlen = XP_FileRead(buffer, len, fh );
        /* PR_READ() returns an unreliable length, check EOF separately */
        if (readlen < 0) {
#if !defined(STANDALONE_REGISTRY) || (!defined(XP_MAC) && !defined(XP_MACOSX))
    #if defined(STANDALONE_REGISTRY)
            if (errno == EBADF) /* bad file handle, not open for read, etc. */
    #else
            if (PR_GetError() == PR_BAD_DESCRIPTOR_ERROR)
    #endif
                err = REGERR_FAIL;
            else
#endif
                err = REGERR_BADREAD;
        }
        else if (readlen < len) {
#if VERIFY_READ
            /* PR_READ() says we hit EOF but return length is unreliable. */
            /* If buffer has new data beyond what PR_READ() says it got */
            /* we'll assume the read was OK--this is a gamble but */
            /* missing errors will cause fewer problems than too many. */
            p = (unsigned char*)buffer + readlen;
            while ( (p < dbgend) && (*p == (unsigned char)FILLCHAR) ) {
                p++;
            }

            /* really was EOF if it's all FILLCHAR's */
            if ( p == dbgend ) {
                err = REGERR_BADREAD;
            }
#else
            err = REGERR_BADREAD;
#endif
        }
    }

    return err;

}   /* ReadFile */

Here is the caller graph for this function:

static REGERR nr_ReadHdr ( REGFILE reg) [static]

Definition at line 765 of file reg.c.

{

    int err;
    long filelength;
    char hdrBuf[sizeof(REGHDR)];

    XP_ASSERT(reg);
    reg->hdrDirty = 0;

    err = nr_ReadFile(reg->fh, 0, sizeof(REGHDR), &hdrBuf);

    switch (err)
    {
    case REGERR_BADREAD:
        /* header doesn't exist, so create one */
        err = nr_CreateRoot(reg);
        break;

    case REGERR_OK:
        /* header read successfully -- convert */
        reg->hdr.magic    = nr_ReadLong ( hdrBuf + HDR_MAGIC );
        reg->hdr.verMajor = nr_ReadShort( hdrBuf + HDR_VERMAJOR );
        reg->hdr.verMinor = nr_ReadShort( hdrBuf + HDR_VERMINOR );
        reg->hdr.avail    = nr_ReadLong ( hdrBuf + HDR_AVAIL );
        reg->hdr.root     = nr_ReadLong ( hdrBuf + HDR_ROOT );

        /* check to see if it's the right file type */
        if (reg->hdr.magic != MAGIC_NUMBER) {
            err = REGERR_BADMAGIC;
            break;
        }

        /* Check registry version
         * If the major version is bumped we're incompatible
         * (minor version just means some new features were added)
         *
         * Upgrade code will go here in the future...
         */
        if ( reg->hdr.verMajor > MAJOR_VERSION ) {
            err = REGERR_REGVERSION;
            break;
        }

#if SELF_REPAIR
        if ( reg->inInit && !(reg->readOnly) ) {
            filelength = nr_GetFileLength(reg->fh);
            if (reg->hdr.avail != filelength)
            {
                reg->hdr.avail = filelength;
                reg->hdrDirty = 1;
#if NOCACHE_HDR
                err = nr_WriteHdr(reg);
#endif
            }
        }
#endif  /* SELF_REPAIR */
        break;

    default:
        /* unexpected error from nr_ReadFile()*/
        XP_ASSERT(FALSE);
        err = REGERR_FAIL;
        break;
    }   /* switch */

    return err;

}   /* ReadHdr */

Here is the call graph for this function:

Here is the caller graph for this function:

static uint32 nr_ReadLong ( char *  buffer) [static]

Definition at line 697 of file reg.c.

{
    uint32 val;
    uint8 *p = (uint8*)buffer;

    val = *p
        + (uint32)(*(p+1) * 0x100L)
        + (uint32)(*(p+2) * 0x10000L )
        + (uint32)(*(p+3) * 0x1000000L );

    return val;
}

Here is the caller graph for this function:

static REGERR nr_ReadName ( REGFILE reg,
REGDESC desc,
uint32  buflen,
char *  buf 
) [static]

Definition at line 986 of file reg.c.

{

    REGERR err;

    XP_ASSERT(reg);
    XP_ASSERT(desc->name > 0);
    XP_ASSERT(desc->name < reg->hdr.avail);
    XP_ASSERT(buflen > 0);
    XP_ASSERT(buf);

    if ( desc->namelen > buflen )
        return REGERR_BUFTOOSMALL;

    err = nr_ReadFile(reg->fh, desc->name, desc->namelen, buf);

    buf[buflen-1] = '\0';   /* avoid runaways */

    return err;

}   /* ReadName */

Here is the call graph for this function:

Here is the caller graph for this function:

static uint16 nr_ReadShort ( char *  buffer) [static]

Definition at line 685 of file reg.c.

{
    uint16 val;
    uint8 *p = (uint8*)buffer;
 
    val = (uint16)(*p + (uint16)( *(p+1) * 0x100 ));

    return val;
}

Here is the caller graph for this function:

static REGERR nr_RegAddKey ( REGFILE reg,
RKEY  key,
char *  path,
RKEY newKey,
XP_Bool  raw 
) [static]

Definition at line 1971 of file reg.c.

{
    REGERR      err;
    REGDESC     desc;
    REGOFF      start;
    REGOFF      parent;
    char        namebuf[MAXREGNAMELEN];
    char        *p;

    XP_ASSERT( regStartCount > 0 );
    XP_ASSERT( reg != NULL );
    XP_ASSERT( path != NULL );
    XP_ASSERT( *path != '\0' );
    XP_ASSERT( VALID_FILEHANDLE( reg->fh ) );

    /* have to translate again in case this is an internal call */
    start = nr_TranslateKey( reg, key );
    if ( start == 0 )
        return REGERR_PARAM;

    /* Get starting desc */
    err = nr_ReadDesc( reg, start, &desc );

    if (raw == TRUE) {
        if ( err == REGERR_OK) {
            /* look for name at next level down */
            parent = desc.location;
            err = nr_FindAtLevel(reg, desc.down, path, &desc, 0);

            /* if key is not found */
            if ( err == REGERR_NOFIND ) {
                /* add it as a sub-key to the last found key */
                err = nr_CreateSubKey(reg, parent, &desc, path);
            }
        }
    }
    else {
        /* Walk 'path', reading keys into 'desc' */
        p = path;
        while ( err == REGERR_OK ) {

            /* get next name on the path */
            err = nr_NextName(p, namebuf, sizeof(namebuf), &p);
            if ( err == REGERR_OK ) {
                /* look for name at next level down */
                parent = desc.location;
                err = nr_FindAtLevel(reg, desc.down, namebuf, &desc, 0);

                /* if key is not found */
                if ( err == REGERR_NOFIND ) {
                    /* add it as a sub-key to the last found key */
                    err = nr_CreateSubKey(reg, parent, &desc, namebuf);
                }
            }
        }
    }

    /* it's good to have processed the whole path */
    if ( (raw == FALSE && err == REGERR_NOMORE) ||
         (raw == TRUE && err == REGERR_OK) ) 
    {
        err = REGERR_OK;

        /* return new key if the caller wants it */
        if ( newKey != NULL ) {
            *newKey = desc.location;
        }
    }

    return err;

}   /* nr_RegAddKey */

Here is the call graph for this function:

Here is the caller graph for this function:

static REGERR nr_RegClose ( HREG  hReg) [static]

Definition at line 2259 of file reg.c.

{
    REGERR      err = REGERR_OK;
    REGHANDLE*  reghnd = (REGHANDLE*)hReg;
    REGFILE*    reg;
    XP_Bool     needDelete = FALSE;

    XP_ASSERT( regStartCount > 0 );

    /* verify handle */
    err = VERIFY_HREG( hReg );
    if ( err != REGERR_OK )
        return err;

    reg = reghnd->pReg;

    PR_Lock( reg->lock );
    if ( err == REGERR_OK )
    {
        XP_ASSERT( VALID_FILEHANDLE(reg->fh) );

        /* save changed header info */
        if ( reg->hdrDirty ) {
            nr_WriteHdr( reg );
        }

        /* lower REGFILE user count */
        reg->refCount--;

        /* if registry is no longer in use */
        if ( reg->refCount < 1 ) 
        {
            /* ...then close the file */
            nr_CloseFile( &(reg->fh) );

            /* ...and mark REGFILE node for deletion from list */
            needDelete = TRUE;
        }
        else
        {
            /* ...otherwise make sure any writes are flushed */
            XP_FileFlush( reg->fh );
        }

        reghnd->magic = 0;    /* prevent accidental re-use */  
        PR_Unlock( reg->lock );

        if ( needDelete )
            nr_DeleteNode( reg );

        XP_FREE( reghnd );
    }

    return err;

}   /* nr_RegClose */

Here is the call graph for this function:

static REGERR nr_RegDeleteKey ( REGFILE reg,
RKEY  key,
char *  path,
XP_Bool  raw 
) [static]

Definition at line 2047 of file reg.c.

{
    REGERR      err;
    REGOFF      start;
    REGDESC     desc;
    REGDESC     predecessor;
    REGOFF      offPrev;
    REGOFF      offParent;
    REGOFF*     link;

    XP_ASSERT( regStartCount > 0 );
    XP_ASSERT( reg != NULL );
    XP_ASSERT( VALID_FILEHANDLE( reg->fh ) );

    start = nr_TranslateKey( reg, key );
    if ( path == NULL || *path == '\0' || start == 0 )
        return REGERR_PARAM;

    /* find the specified key */
    err = nr_Find( reg, start, path, &desc, &offPrev, &offParent, raw );
    if ( err == REGERR_OK ) {

        XP_ASSERT( !TYPE_IS_ENTRY( desc.type ) );

        /* make sure it's childless and not a top-level key */
        if ( (desc.down == 0) && !nr_ProtectedNode( reg, desc.location ) ) {

            /* Are we the first on our level? */
            if ( offPrev == 0 ) {
                /* Yes: link to parent's "down" pointer */
                err = nr_ReadDesc( reg, offParent, &predecessor );
                link = &(predecessor.down);
            }
            else {
                /* No: link using predecessor's "left" pointer */
                err = nr_ReadDesc( reg, offPrev, &predecessor );
                link = &(predecessor.left);
            }

            /* If we read the predecessor desc OK */
            if (err == REGERR_OK) {
                XP_ASSERT( *link == desc.location );

                /* link predecessor to next, removing current node from chain */
                *link = desc.left;

                /* Write the updated predecessor */
                err = nr_WriteDesc( reg, &predecessor );
                if ( err == REGERR_OK ) {
                    /* Mark key deleted to prevent bogus use by anyone
                     * who is holding an RKEY for that node
                     */
                    desc.type |= REGTYPE_DELETED;
                    err = nr_WriteDesc( reg, &desc );
                }
            }
        }
        else {
            /* specified node is protected from deletion */
            err = REGERR_FAIL;
        }
    }

    return err;

}   /* nr_RegDeleteKey */

Here is the call graph for this function:

static REGERR nr_RegOpen ( const char *  filename,
HREG hReg 
) [static]

Definition at line 2142 of file reg.c.

{
    REGERR    status = REGERR_OK;
    REGFILE   *pReg;
    REGHANDLE *pHandle;

    XP_ASSERT( regStartCount > 0 );

    /* initialize output handle in case of error */
    if ( hReg == NULL ) {
        return REGERR_PARAM;
    }
    *hReg = NULL;
    
    /* Look for named file in list of open registries */
    filename = nr_GetRegName( filename );
    if (filename == NULL) {
        filename = "";
    }
    pReg = vr_findRegFile( filename );

    /* if registry not already open */
    if (pReg == NULL) {

        /* ...then open it */
        pReg = (REGFILE*)XP_ALLOC( sizeof(REGFILE) );
        if ( pReg == NULL ) {
            status = REGERR_MEMORY;
            goto bail;
        }
        XP_MEMSET(pReg, 0, sizeof(REGFILE));

        pReg->inInit = TRUE;
        pReg->filename = XP_STRDUP(filename);
        if (pReg->filename == NULL) {
            XP_FREE( pReg );
            status = REGERR_MEMORY;
            goto bail;
        }

        status = nr_OpenFile( filename, &(pReg->fh) );
        if (status == REGERR_READONLY) {
            /* Open, but read only */
            pReg->readOnly = TRUE;
            status = REGERR_OK;
        }
        if ( status != REGERR_OK ) {
            XP_FREE( pReg->filename );
            XP_FREE( pReg );

            goto bail;
        }

        /* ...read and validate the header */
        status = nr_ReadHdr( pReg );
        if ( status != REGERR_OK ) {
            nr_CloseFile( &(pReg->fh) );
            XP_FREE( pReg->filename );
            XP_FREE( pReg );
            goto bail;
        }

        /* ...other misc initialization */
        pReg->refCount = 0;

#ifndef STANDALONE_REGISTRY
        pReg->uniqkey = PR_Now();
#endif

        status = nr_InitStdRkeys( pReg );
        if ( status == REGERR_OK ) {
            /* ...and add it to the list */
            nr_AddNode( pReg );
        }
        else {
            nr_CloseFile( &(pReg->fh) );
            XP_FREE( pReg->filename );
            XP_FREE( pReg );
            goto bail;
        }

#ifndef STANDALONE_REGISTRY
        pReg->lock = PR_NewLock();
#endif

        /* now done with everything that needs to protect the header */
        pReg->inInit = FALSE;
    }

    /* create a new handle to the regfile */
    pHandle = (REGHANDLE*)XP_ALLOC( sizeof(REGHANDLE) );
    if ( pHandle == NULL ) {
        /* we can't create the handle */
        if ( pReg->refCount == 0 ) {
            /* we've just opened it so close it and remove node */
            nr_CloseFile( &(pReg->fh) );
            nr_DeleteNode( pReg );
        }

        status = REGERR_MEMORY;
        goto bail;
    }

    pHandle->magic   = MAGIC_NUMBER;
    pHandle->pReg    = pReg;

    /* success: bump the reference count and return the handle */
    pReg->refCount++;
    *hReg = (void*)pHandle;

bail:
    return status;

}   /* nr_RegOpen */

Here is the call graph for this function:

static int nr_RegSetBufferSize ( HREG  hReg,
int  bufsize 
) [static]

Definition at line 2116 of file reg.c.

{
    REGERR      err = REGERR_OK;
    REGHANDLE*  reghnd = (REGHANDLE*)hReg;
    REGFILE*    reg;
    XP_Bool     needDelete = FALSE;
    int         newSize;

    /* verify handle */
    err = VERIFY_HREG( hReg );
    if ( err != REGERR_OK )
        return -1;

    reg = reghnd->pReg;

    PR_Lock( reg->lock );
 
    newSize = XP_FileSetBufferSize( reg->fh, bufsize );

    PR_Unlock( reg->lock );

    return newSize;
}
static REGERR nr_RemoveName ( char *  path) [static]

Definition at line 1492 of file reg.c.

{
    /* Typical inputs:
     * path = "/Machine/4.0/"   output = "/Machine"
     * path = "/Machine"        output = ""
     * path = ""                output = REGERR_NOMORE
     *
     * NOTE! It is EXREMELY important that names be in UTF-8; otherwise
     * the backwards path search will fail for multi-byte/Unicode names
     */

    int len = XP_STRLEN(path);
    char *p;
    if (len < 1)
        return REGERR_NOMORE;

    p = &path[len-1];
    /* if last char is '/', ignore it */
    if (*p == PATHDEL)
        p--;

    while ((p > path) && (*p != PATHDEL))
        p--;

/*  if (*p != PATHDEL)
        return REGERR_NOMORE;
*/

    *p = '\0';
    return REGERR_OK;

}   /* RemoveName */
static REGERR nr_ReplaceName ( REGFILE reg,
REGOFF  node,
char *  path,
uint32  bufsize,
REGDESC desc 
) [static]

Definition at line 1450 of file reg.c.

{
    /* NOTE! It is EXREMELY important that names be in UTF-8; otherwise
     * the backwards path search will fail for multi-byte/Unicode names
     */

    char   *p;
    uint32 len;
    REGERR err;

    XP_ASSERT(path);

    len = XP_STRLEN(path);
    if ( len > bufsize )
        return REGERR_PARAM;

    if ( len > 0 ) {
        p = &path[len-1];

        while ((p > path) && (*p != PATHDEL)) {
            --p;
            --len;
        }
        if ( *p == PATHDEL ) {
            p++; 
            len++;
        }
    }
    else
        p = path;


    err = nr_ReadDesc( reg, node, desc );
    if ( err == REGERR_OK ) {
        err = nr_ReadName( reg, desc, bufsize-len, p );
    }

    return err;

}   /* ReplaceName */

Here is the call graph for this function:

static REGOFF nr_TranslateKey ( REGFILE reg,
RKEY  key 
) [static]

Definition at line 1833 of file reg.c.

{
    REGOFF retKey = 0;

    /* if it's a special key  */
    if ( key < HDRRESERVE )  {
        /* ...translate it */
        switch (key)
        {
            case ROOTKEY:
                retKey = reg->hdr.root;
                break;

            case ROOTKEY_VERSIONS:
                retKey = reg->rkeys.versions;
                break;

            case ROOTKEY_USERS:
                retKey = reg->rkeys.users;
                break;

            case ROOTKEY_COMMON:
                retKey = reg->rkeys.common;
                break;

#ifndef STANDALONE_REGISTRY
            case ROOTKEY_CURRENT_USER:
                if ( reg->rkeys.current_user == 0 ) {
                    /* not initialized--find the current user key */
                    RKEY    userkey = 0;
                    REGERR  err;
                    char*   profName;

                    profName = nr_GetUsername();
                    if ( NULL != profName ) {
                        /* Don't assign a slot for missing or magic profile */
                        if ( '\0' == *profName ||
                            0 == XP_STRCMP(ASW_MAGIC_PROFILE_NAME, profName)) 
                        {
                            err = REGERR_FAIL;
                        } else {
                            err = nr_RegAddKey( reg, reg->rkeys.users, profName, &userkey, FALSE );
                        }
                        XP_FREE(profName);
                    }
                    else {
                        err = nr_RegAddKey( reg, reg->rkeys.users, "default", &userkey, FALSE );
                    }

                    if ( err == REGERR_OK ) {
                        reg->rkeys.current_user = userkey;
                    }
                }
                retKey = reg->rkeys.current_user;
                break;
#endif /* !STANDALONE_REGISTRY */

            case ROOTKEY_PRIVATE:
                retKey = reg->rkeys.privarea;
                break;

            default:
                /* not a valid key */
                retKey = 0;
                break;
        }
    }
    else {
        /* ...otherwise it's fine as-is */
        retKey = (REGOFF)key;
    }
    return ( retKey );
}  /* nr_TranslateKey */

Here is the call graph for this function:

Here is the caller graph for this function:

static REGERR nr_Unlock ( REGFILE reg) [static]

Definition at line 933 of file reg.c.

{
    PR_Unlock( reg->lock );

    return nr_UnlockRange(reg->fh, 0, sizeof(REGHDR));
}   /* Unlock */

Here is the call graph for this function:

static REGERR nr_UnlockRange ( FILEHANDLE  fh,
REGOFF  offset,
int32  len 
) [static]

Definition at line 641 of file reg.c.

{
    /* TODO: Implement XP unlock function with built-in retry. */

    return REGERR_OK;

}   /* UnlockRange */

Here is the caller graph for this function:

static REGERR nr_WriteData ( REGFILE reg,
char *  string,
uint32  len,
REGDESC desc 
) [static]

Definition at line 1189 of file reg.c.

{
    REGERR err;

    XP_ASSERT(reg);
    XP_ASSERT(string);
    XP_ASSERT(desc);

    if (reg->readOnly)
        return REGERR_READONLY;

    if ( len == 0 )
        return REGERR_PARAM;

    if ( len > MAXREGVALUELEN )
        return REGERR_NAMETOOLONG;

    /* save the data in the same place if it fits */
    if ( len <= desc->valuebuf ) {
        err = nr_WriteFile( reg->fh, desc->value, len, string );
        if ( err == REGERR_OK ) {
            desc->valuelen = len;
        }
    }
    else {
        /* otherwise append new data */
        err = nr_AppendData( reg, string, len, desc );
    }

    return err;

}   /* nr_WriteData */

Here is the call graph for this function:

Here is the caller graph for this function:

static REGERR nr_WriteDesc ( REGFILE reg,
REGDESC desc 
) [static]

Definition at line 1032 of file reg.c.

{
    char descBuf[ DESC_SIZE ];

    XP_ASSERT(reg);
    XP_ASSERT(desc);
    XP_ASSERT( desc->location >= HDRRESERVE );
    XP_ASSERT( desc->location < reg->hdr.avail );

    if (reg->readOnly)
        return REGERR_READONLY;

    /* convert to XP int format */
    nr_WriteLong ( desc->location,  descBuf + DESC_LOCATION );
    nr_WriteLong ( desc->name,      descBuf + DESC_NAME );
    nr_WriteShort( desc->namelen,   descBuf + DESC_NAMELEN );
    nr_WriteShort( desc->type,      descBuf + DESC_TYPE );
    nr_WriteLong ( desc->left,      descBuf + DESC_LEFT );
    nr_WriteLong ( desc->value,     descBuf + DESC_VALUE );
    nr_WriteLong ( desc->valuelen,  descBuf + DESC_VALUELEN );
    nr_WriteLong ( desc->parent,    descBuf + DESC_PARENT );

    if ( TYPE_IS_ENTRY(desc->type) ) {
        XP_ASSERT( 0 == desc->down );
        nr_WriteLong( desc->valuebuf,  descBuf + DESC_VALUEBUF );
    }
    else {  /* TYPE is KEY */
        XP_ASSERT( 0 == desc->valuebuf );
        nr_WriteLong( desc->down,      descBuf + DESC_DOWN );
    }

    return nr_WriteFile(reg->fh, desc->location, DESC_SIZE, descBuf);
}   /* nr_WriteDesc */

Here is the call graph for this function:

Here is the caller graph for this function:

static REGERR nr_WriteFile ( FILEHANDLE  fh,
REGOFF  offset,
int32  len,
void buffer 
) [static]

Definition at line 605 of file reg.c.

{

    /* Note: 'offset' will commonly be the end of the file, in which
     * case this function extends the file to 'offset'+'len'. This may
     * be a two-step operation on some platforms.
     */
    XP_ASSERT(len > 0);
    XP_ASSERT(buffer);
    XP_ASSERT(fh != NULL);

    if (XP_FileSeek(fh, offset, SEEK_SET) != 0)
        return REGERR_FAIL;

    if ((int32)XP_FileWrite(buffer, len, fh) != len)
    {
        /* disk full or some other catastrophic error */
        return REGERR_FAIL;
    }

    return REGERR_OK;

}   /* WriteFile */

Here is the caller graph for this function:

static REGERR nr_WriteHdr ( REGFILE reg) [static]

Definition at line 837 of file reg.c.

{
    REGERR err;
    char hdrBuf[sizeof(REGHDR)];

    XP_ASSERT(reg);

    if (reg->readOnly)
        return REGERR_READONLY;

    /* convert to XP int format */
    nr_WriteLong ( reg->hdr.magic,    hdrBuf + HDR_MAGIC );
    nr_WriteShort( reg->hdr.verMajor, hdrBuf + HDR_VERMAJOR );
    nr_WriteShort( reg->hdr.verMinor, hdrBuf + HDR_VERMINOR );
    nr_WriteLong ( reg->hdr.avail,    hdrBuf + HDR_AVAIL );
    nr_WriteLong ( reg->hdr.root,     hdrBuf + HDR_ROOT );

    /* err = nr_WriteFile(reg->fh, 0, sizeof(REGHDR), &reg->hdr); */
    err = nr_WriteFile(reg->fh, 0, sizeof(hdrBuf), &hdrBuf);

    if (err == REGERR_OK)
        reg->hdrDirty = 0;

    return err;

}   /* WriteHdr */

Here is the call graph for this function:

Here is the caller graph for this function:

static void nr_WriteLong ( uint32  num,
char *  buffer 
) [static]

Definition at line 712 of file reg.c.

{
    uint8 *p = (uint8*)buffer;
    *p++ = (uint8)(num & 0x000000FF);
    num /= 0x100;
    *p++ = (uint8)(num & 0x000000FF);
    num /= 0x100;
    *p++ = (uint8)(num & 0x000000FF);
    num /= 0x100;
    *p   = (uint8)(num & 0x000000FF);
}

Here is the caller graph for this function:

static void nr_WriteShort ( uint16  num,
char *  buffer 
) [static]

Definition at line 726 of file reg.c.

{
    uint8 *p = (uint8*)buffer;

    *p = (uint8)(num & 0x00FF);
    *(p+1) = (uint8)(num / 0x100);
}

Here is the caller graph for this function:

static REGERR nr_WriteString ( REGFILE reg,
char *  string,
REGDESC desc 
) [static]

Definition at line 1172 of file reg.c.

{
    uint32 len;

    XP_ASSERT(string);
    if (!nr_IsValidUTF8(string))
        return REGERR_BADUTF8;
    if (reg->readOnly)
        return REGERR_READONLY;
    len = XP_STRLEN(string) + 1;

    return nr_WriteData( reg, string, len, desc );

}   /* nr_WriteString */

Here is the call graph for this function:

static REGFILE * vr_findRegFile ( const char *  filename) [static]

Definition at line 414 of file reg.c.

{
    REGFILE *pReg;

    pReg = RegList;
    while( pReg != NULL ) {
#if defined(XP_UNIX) && !defined(XP_MACOSX) || defined XP_BEOS
        if ( 0 == XP_STRCMP( filename, pReg->filename ) ) {
#else
        if ( 0 == XP_STRCASECMP( filename, pReg->filename ) ) {
#endif
            break;
        }
        pReg = pReg->next;
    }

    return pReg;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 2356 of file reg.c.

{
    /* XXX: does this need locking? */

    if ( name == NULL )
        return REGERR_PARAM;

    *name = XP_STRDUP(nr_GetUsername());

    if ( NULL == *name )
        return REGERR_MEMORY;

    return REGERR_OK;
}

Here is the call graph for this function:

Definition at line 4118 of file reg.c.

{
    REGFILE* pReg;
    XP_Bool  bDestroyLocks = FALSE;

    /* people should track whether NR_StartupRegistry() was successful
     * and not call this if it fails... but they won't so we'll try to
     * handle that case gracefully.
     */
#ifndef STANDALONE_REGISTRY
    if ( reglist_lock == NULL ) 
        return;  /* was not started successfully */
#else
    if ( regStartCount == 0 )
        return;  /* was not started successfully */
#endif

    PR_Lock( reglist_lock );

    --regStartCount;
    if ( regStartCount == 0 )
    {
        /* shutdown for real. */

        /* close any forgotten open registries */
        while ( RegList != NULL ) 
        {
            pReg = RegList;
            if ( pReg->hdrDirty ) {
                nr_WriteHdr( pReg );
            }
            nr_CloseFile( &(pReg->fh) );
            nr_DeleteNode( pReg );
        }
    
        XP_FREEIF(user_name);
        XP_FREEIF(globalRegName);
        XP_FREEIF(verRegName);

        bDestroyLocks = TRUE;
    }

    PR_Unlock( reglist_lock );

#ifndef STANDALONE_REGISTRY    
    if ( bDestroyLocks ) 
    {
        PR_DestroyLock( reglist_lock );
        reglist_lock = NULL;

        PR_DestroyLock(vr_lock);
        vr_lock = NULL;
    }
#endif

}   /* NR_ShutdownRegistry */

Here is the call graph for this function:


Variable Documentation

Definition at line 156 of file reg.c.

REGFILE* RegList = NULL [static]

Definition at line 154 of file reg.c.

PRLock* reglist_lock = NULL [static]

Definition at line 151 of file reg.c.

int32 regStartCount = 0 [static]

Definition at line 155 of file reg.c.

char* user_name = NULL [static]

Definition at line 157 of file reg.c.

Definition at line 135 of file VerReg.c.