mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 03:15:11 +00:00
Per bug 3690:
Added new functions to the registry for reading / writing byte arrays of binary content and escaping registry keys that contain binary content. Modified code which reads/writes location of dll or javascript for components to use new ReadBytesUTF8/WriteBytesUTF8 and which uses or reads the keys to use EscapeKey and UnescapeKey. r=dveditz
This commit is contained in:
parent
71c6e11ea9
commit
d0199a10bc
@ -51,11 +51,17 @@ interface nsIRegistry : nsISupports
|
||||
string getStringUTF8(in nsRegistryKey baseKey, in string path);
|
||||
void setStringUTF8(in nsRegistryKey baseKey, in string path, in string value);
|
||||
|
||||
void getBytesUTF8(in nsRegistryKey baseKey, in string path, out PRUint32 length, [retval, array, size_is(length)] out PRUint8 valueArray);
|
||||
void setBytesUTF8(in nsRegistryKey baseKey, in string path, in PRUint32 length, [array, size_is(length)] in PRUint8 valueArray);
|
||||
PRInt32 getInt(in nsRegistryKey baseKey, in string path);
|
||||
void setInt(in nsRegistryKey baseKey, in string path, in PRInt32 value);
|
||||
PRInt64 getLongLong(in nsRegistryKey baseKey, in string path);
|
||||
void setLongLong(in nsRegistryKey baseKey, in string path, inout PRInt64 value);
|
||||
|
||||
/**
|
||||
* addSubtree() and friends need to be renamed to addKeyUTF8().
|
||||
* If you are using these forms make sure you pass UTF8 data
|
||||
*/
|
||||
nsRegistryKey addSubtree(in nsRegistryKey baseKey, in string path);
|
||||
void removeSubtree(in nsRegistryKey baseKey, in string path);
|
||||
nsRegistryKey getSubtree(in nsRegistryKey baseKey, in string path);
|
||||
@ -77,6 +83,13 @@ interface nsIRegistry : nsISupports
|
||||
PRUint32 getValueLength(in nsRegistryKey baseKey, in string path);
|
||||
void deleteValue(in nsRegistryKey baseKey, in string path);
|
||||
|
||||
/**
|
||||
* escapeKey() takes arbitrary binary data and converts it into
|
||||
* valid ASCII which can be used as registry key or value names
|
||||
*/
|
||||
void escapeKey([array, size_is(length)] in PRUint8 key, in PRUint32 terminator, inout PRUint32 length, [retval, array, size_is(length)] out PRUint8 escaped);
|
||||
void unescapeKey([array, size_is(length)] in PRUint8 escaped, in PRUint32 terminator, inout PRUint32 length, [retval, array, size_is(length)] out PRUint8 key);
|
||||
|
||||
attribute string currentUserName;
|
||||
|
||||
void pack();
|
||||
|
@ -73,9 +73,9 @@ struct nsRegistry : public nsIRegistry {
|
||||
protected:
|
||||
HREG mReg; // Registry handle.
|
||||
#ifdef EXTRA_THREADSAFE
|
||||
PRLock *mregLock; // libreg isn't threadsafe. Use locks to synchronize.
|
||||
PRLock *mregLock; // libreg isn't threadsafe. Use locks to synchronize.
|
||||
#endif
|
||||
char *mCurRegFile; // these are to prevent open from opening the registry again
|
||||
char *mCurRegFile; // these are to prevent open from opening the registry again
|
||||
nsWellKnownRegistry mCurRegID;
|
||||
|
||||
NS_IMETHOD Close();
|
||||
@ -167,7 +167,7 @@ struct nsRegistryNode : public nsIRegistryNode {
|
||||
protected:
|
||||
HREG mReg; // Handle to registry this node is part of.
|
||||
char mName[MAXREGPATHLEN]; // Buffer to hold name.
|
||||
RKEY mChildKey; // Key corresponding to mName
|
||||
RKEY mChildKey; // Key corresponding to mName
|
||||
#ifdef EXTRA_THREADSAFE
|
||||
PRLock *mregLock;
|
||||
#endif
|
||||
@ -735,6 +735,94 @@ NS_IMETHODIMP nsRegistry::SetStringUTF8( nsRegistryKey baseKey, const char *path
|
||||
return regerr2nsresult( err );
|
||||
}
|
||||
|
||||
/*---------------------------- nsRegistry::GetBytesUTF8 ------------------------------
|
||||
| This function is just shorthand for fetching a char array. We |
|
||||
| implement it "manually" using NR_RegGetEntry |
|
||||
------------------------------------------------------------------------------*/
|
||||
NS_IMETHODIMP nsRegistry::GetBytesUTF8( nsRegistryKey baseKey, const char *path, PRUint32* length, PRUint8** result) {
|
||||
nsresult rv = NS_OK;
|
||||
REGERR err = REGERR_OK;
|
||||
|
||||
if ( !result )
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
char regStr[MAXREGPATHLEN];
|
||||
|
||||
// initialize the return value
|
||||
*length = 0;
|
||||
*result = 0;
|
||||
|
||||
// Get info about the requested entry.
|
||||
PRUint32 type;
|
||||
rv = GetValueType( baseKey, path, &type );
|
||||
// See if that worked.
|
||||
if( rv == NS_OK )
|
||||
{
|
||||
// Make sure the entry is an PRInt8 array.
|
||||
if( type == Bytes )
|
||||
{
|
||||
// Attempt to get string into our fixed buffer
|
||||
PR_Lock(mregLock);
|
||||
uint32 length2 = sizeof regStr;
|
||||
err = NR_RegGetEntry( mReg,(RKEY)baseKey,NS_CONST_CAST(char*,path), regStr, &length2);
|
||||
PR_Unlock(mregLock);
|
||||
|
||||
if ( err == REGERR_OK )
|
||||
{
|
||||
*length = length2;
|
||||
*result = (PRUint8*)(nsCRT::strdup(regStr));
|
||||
if (!*result)
|
||||
{
|
||||
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
*length = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
*length = length2;
|
||||
}
|
||||
}
|
||||
else if ( err == REGERR_BUFTOOSMALL )
|
||||
{
|
||||
// find the real size and malloc it
|
||||
rv = GetValueLength( baseKey, path, length );
|
||||
// See if that worked.
|
||||
if( rv == NS_OK )
|
||||
{
|
||||
*result = NS_REINTERPRET_CAST(PRUint8*,nsAllocator::Alloc( *length ));
|
||||
if( *result )
|
||||
{
|
||||
// Get bytes from registry into result field.
|
||||
PR_Lock(mregLock);
|
||||
length2 = *length;
|
||||
err = NR_RegGetEntry( mReg,(RKEY)baseKey,NS_CONST_CAST(char*,path), *result, &length2);
|
||||
*length = length2;
|
||||
PR_Unlock(mregLock);
|
||||
// Convert status.
|
||||
rv = regerr2nsresult( err );
|
||||
if ( rv != NS_OK )
|
||||
{
|
||||
// Didn't get result, free buffer
|
||||
nsCRT::free( NS_REINTERPRET_CAST(char*, *result) );
|
||||
*result = 0;
|
||||
*length = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// They asked for the wrong type of value.
|
||||
rv = NS_ERROR_REG_BADTYPE;
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*---------------------------- nsRegistry::GetInt ------------------------------
|
||||
| This function is just shorthand for fetching a 1-element PRInt32 array. We |
|
||||
| implement it "manually" using NR_RegGetEntry |
|
||||
@ -788,6 +876,24 @@ NS_IMETHODIMP nsRegistry::GetLongLong( nsRegistryKey baseKey, const char *path,
|
||||
// Convert status.
|
||||
return regerr2nsresult( err );
|
||||
}
|
||||
/*---------------------------- nsRegistry::SetBytesUTF8 ------------------------------
|
||||
| Write out the value as a char array, using NR_RegSetEntry. |
|
||||
------------------------------------------------------------------------------*/
|
||||
NS_IMETHODIMP nsRegistry::SetBytesUTF8( nsRegistryKey baseKey, const char *path, PRUint32 length, PRUint8* value) {
|
||||
REGERR err = REGERR_OK;
|
||||
// Set the contents.
|
||||
PR_Lock(mregLock);
|
||||
err = NR_RegSetEntry( mReg,
|
||||
(RKEY)baseKey,
|
||||
(char*)path,
|
||||
REGTYPE_ENTRY_BYTES,
|
||||
(char*)value,
|
||||
length);
|
||||
PR_Unlock(mregLock);
|
||||
// Convert result.
|
||||
return regerr2nsresult( err );
|
||||
}
|
||||
|
||||
/*---------------------------- nsRegistry::SetInt ------------------------------
|
||||
| Write out the value as a one-element PRInt32 array, using NR_RegSetEntry. |
|
||||
------------------------------------------------------------------------------*/
|
||||
@ -862,8 +968,8 @@ NS_IMETHODIMP nsRegistry::RemoveSubtree( nsRegistryKey baseKey, const char *path
|
||||
nsresult rv = NS_OK;
|
||||
REGERR err = REGERR_OK;
|
||||
|
||||
// libreg doesn't delete keys if there are subkeys under the key
|
||||
// Hence we have to recurse through to delete the subtree
|
||||
// libreg doesn't delete keys if there are subkeys under the key
|
||||
// Hence we have to recurse through to delete the subtree
|
||||
|
||||
RKEY key;
|
||||
|
||||
@ -871,13 +977,13 @@ NS_IMETHODIMP nsRegistry::RemoveSubtree( nsRegistryKey baseKey, const char *path
|
||||
err = NR_RegGetKey(mReg, baseKey, (char *)path, &key);
|
||||
PR_Unlock(mregLock);
|
||||
if (err != REGERR_OK)
|
||||
{
|
||||
rv = regerr2nsresult( err );
|
||||
{
|
||||
rv = regerr2nsresult( err );
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
// Now recurse through and delete all keys under hierarchy
|
||||
|
||||
|
||||
char subkeyname[MAXREGPATHLEN+1];
|
||||
REGENUM state = 0;
|
||||
subkeyname[0] = '\0';
|
||||
@ -885,7 +991,7 @@ NS_IMETHODIMP nsRegistry::RemoveSubtree( nsRegistryKey baseKey, const char *path
|
||||
REGENUM_NORMAL) == REGERR_OK)
|
||||
{
|
||||
#ifdef DEBUG_dp
|
||||
printf("...recursing into %s\n", subkeyname);
|
||||
printf("...recursing into %s\n", subkeyname);
|
||||
#endif /* DEBUG_dp */
|
||||
// Even though this is not a "Raw" API the subkeys may still, in fact,
|
||||
// *be* raw. Since we're recursively deleting this will work either way.
|
||||
@ -899,15 +1005,15 @@ NS_IMETHODIMP nsRegistry::RemoveSubtree( nsRegistryKey baseKey, const char *path
|
||||
if (err == REGERR_OK)
|
||||
{
|
||||
#ifdef DEBUG_dp
|
||||
printf("...deleting %s\n", path);
|
||||
printf("...deleting %s\n", path);
|
||||
#endif /* DEBUG_dp */
|
||||
PR_Lock(mregLock);
|
||||
err = NR_RegDeleteKey(mReg, baseKey, (char *)path);
|
||||
PR_Unlock(mregLock);
|
||||
}
|
||||
|
||||
// Convert result.
|
||||
rv = regerr2nsresult( err );
|
||||
// Convert result.
|
||||
rv = regerr2nsresult( err );
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -919,8 +1025,8 @@ NS_IMETHODIMP nsRegistry::RemoveSubtreeRaw( nsRegistryKey baseKey, const char *k
|
||||
nsresult rv = NS_OK;
|
||||
REGERR err = REGERR_OK;
|
||||
|
||||
// libreg doesn't delete keys if there are subkeys under the key
|
||||
// Hence we have to recurse through to delete the subtree
|
||||
// libreg doesn't delete keys if there are subkeys under the key
|
||||
// Hence we have to recurse through to delete the subtree
|
||||
|
||||
RKEY key;
|
||||
char subkeyname[MAXREGPATHLEN+1];
|
||||
@ -931,18 +1037,18 @@ NS_IMETHODIMP nsRegistry::RemoveSubtreeRaw( nsRegistryKey baseKey, const char *k
|
||||
err = NR_RegGetKeyRaw(mReg, baseKey, (char *)keyname, &key);
|
||||
PR_Unlock(mregLock);
|
||||
if (err != REGERR_OK)
|
||||
{
|
||||
rv = regerr2nsresult( err );
|
||||
{
|
||||
rv = regerr2nsresult( err );
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
// Now recurse through and delete all keys under hierarchy
|
||||
|
||||
|
||||
subkeyname[0] = '\0';
|
||||
while (NR_RegEnumSubkeys(mReg, key, &state, subkeyname, n, REGENUM_NORMAL) == REGERR_OK)
|
||||
{
|
||||
#ifdef DEBUG_dp
|
||||
printf("...recursing into %s\n", subkeyname);
|
||||
printf("...recursing into %s\n", subkeyname);
|
||||
#endif /* DEBUG_dp */
|
||||
err = RemoveSubtreeRaw(key, subkeyname);
|
||||
if (err != REGERR_OK) break;
|
||||
@ -952,15 +1058,15 @@ NS_IMETHODIMP nsRegistry::RemoveSubtreeRaw( nsRegistryKey baseKey, const char *k
|
||||
if (err == REGERR_OK)
|
||||
{
|
||||
#ifdef DEBUG_dp
|
||||
printf("...deleting %s\n", keyname);
|
||||
printf("...deleting %s\n", keyname);
|
||||
#endif /* DEBUG_dp */
|
||||
PR_Lock(mregLock);
|
||||
err = NR_RegDeleteKeyRaw(mReg, baseKey, (char *)keyname);
|
||||
PR_Unlock(mregLock);
|
||||
}
|
||||
|
||||
// Convert result.
|
||||
rv = regerr2nsresult( err );
|
||||
// Convert result.
|
||||
rv = regerr2nsresult( err );
|
||||
return rv;
|
||||
}
|
||||
/*-------------------------- nsRegistry::GetSubtree ----------------------------
|
||||
@ -1196,6 +1302,157 @@ NS_IMETHODIMP nsRegistry::Pack() {
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*----------------------------- nsRegistry::EscapeKey -------------------------------
|
||||
| Escape a binary key so that the registry works OK, since it expects UTF8
|
||||
| with no slashes or control characters. This is probably better than raw.
|
||||
| If no escaping is required, then the method is successful and a null is
|
||||
| returned, indicating that the caller should use the original string.
|
||||
------------------------------------------------------------------------------*/
|
||||
static const char sEscapeKeyHex[] = "0123456789abcdef0123456789ABCDEF";
|
||||
NS_IMETHODIMP nsRegistry::EscapeKey(PRUint8* key, PRUint32 termination, PRUint32* length, PRUint8** escaped)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
char* value = (char*)key;
|
||||
char* b = value;
|
||||
char* e = b + *length;
|
||||
int escapees = 0;
|
||||
while (b < e) // Count characters outside legal range or slash
|
||||
{
|
||||
int c = *b++;
|
||||
if (c <= ' '
|
||||
|| c > '~'
|
||||
|| c == '/'
|
||||
|| c == '%')
|
||||
{
|
||||
escapees++;
|
||||
}
|
||||
}
|
||||
if (escapees == 0) // If no escapees, then no results
|
||||
{
|
||||
*length = 0;
|
||||
*escaped = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
// New length includes two extra chars for escapees.
|
||||
*length += escapees * 2;
|
||||
*escaped = (PRUint8*)nsAllocator::Alloc(*length + termination);
|
||||
if (*escaped == nsnull)
|
||||
{
|
||||
*length = 0;
|
||||
*escaped = nsnull;
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
char* n = (char*)*escaped;
|
||||
b = value;
|
||||
while (escapees && b < e)
|
||||
{
|
||||
char c = *b++;
|
||||
if (c < ' '
|
||||
|| c > '~'
|
||||
|| c == '/'
|
||||
|| c == '%')
|
||||
{
|
||||
*(n++) = '%';
|
||||
*(n++) = sEscapeKeyHex[ 0xF & (c >> 4) ];
|
||||
*(n++) = sEscapeKeyHex[ 0xF & c ];
|
||||
escapees--;
|
||||
}
|
||||
else
|
||||
{
|
||||
*(n++) = c;
|
||||
}
|
||||
}
|
||||
e += termination;
|
||||
if (b < e)
|
||||
{
|
||||
strncpy(n, b, e - b);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*----------------------------- nsRegistry::UnescapeKey -------------------------------
|
||||
| Unscape a binary key so that the registry works OK, since it expects UTF8
|
||||
| with no slashes or control characters. This is probably better than raw.
|
||||
| If no escaping is required, then the method is successful and a null is
|
||||
| returned, indicating that the caller should use the original string.
|
||||
------------------------------------------------------------------------------*/
|
||||
NS_IMETHODIMP nsRegistry::UnescapeKey(PRUint8* escaped, PRUint32 termination, PRUint32* length, PRUint8** key)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
char* value = (char*)escaped;
|
||||
char* b = value;
|
||||
char* e = b + *length;
|
||||
int escapees = 0;
|
||||
while (b < e) // Count characters outside legal range or slash
|
||||
{
|
||||
if (*b++ == '%')
|
||||
{
|
||||
escapees++;
|
||||
}
|
||||
}
|
||||
if (escapees == 0) // If no escapees, then no results
|
||||
{
|
||||
*length = 0;
|
||||
*key = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
// New length includes two extra chars for escapees.
|
||||
*length -= escapees * 2;
|
||||
*key = (PRUint8*)nsAllocator::Alloc(*length + termination);
|
||||
if (*key == nsnull)
|
||||
{
|
||||
*length = 0;
|
||||
*key = nsnull;
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
char* n = (char*)*key;
|
||||
b = value;
|
||||
while (escapees && b < e)
|
||||
{
|
||||
char c = *(b++);
|
||||
if (c == '%')
|
||||
{
|
||||
if (e - b >= 2)
|
||||
{
|
||||
char* c1 = strchr(sEscapeKeyHex, *(b++));
|
||||
char* c2 = strchr(sEscapeKeyHex, *(b++));
|
||||
if (c1 != nsnull
|
||||
&& c2 != nsnull)
|
||||
{
|
||||
*(n++) = ((c2 - sEscapeKeyHex) & 0xF)
|
||||
| (((c1 - sEscapeKeyHex) & 0xF) << 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
escapees = -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
escapees = -1;
|
||||
}
|
||||
escapees--;
|
||||
}
|
||||
else
|
||||
{
|
||||
*(n++) = c;
|
||||
}
|
||||
}
|
||||
if (escapees < 0)
|
||||
{
|
||||
nsAllocator::Free(*key);
|
||||
*length = 0;
|
||||
*key = nsnull;
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
e += termination;
|
||||
if (b < e)
|
||||
{
|
||||
strncpy(n, b, e - b);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*-------------- nsRegSubtreeEnumerator::nsRegSubtreeEnumerator ----------------
|
||||
| The ctor simply stashes all the information that will be needed to enumerate |
|
||||
| the subkeys. |
|
||||
@ -1437,7 +1694,7 @@ NS_IMETHODIMP nsRegistryNode::GetNameUTF8( char **result ) {
|
||||
}
|
||||
|
||||
/*-------------------------- nsRegistryNode::GetKey ----------------------------
|
||||
| Get the subkey corresponding to this node |
|
||||
| Get the subkey corresponding to this node |
|
||||
| using NR_RegEnumSubkeys. |
|
||||
------------------------------------------------------------------------------*/
|
||||
NS_IMETHODIMP nsRegistryNode::GetKey( nsRegistryKey *r_key ) {
|
||||
|
@ -123,32 +123,32 @@ extern PRBool gShuttingDown;
|
||||
nsresult
|
||||
|
||||
nsCreateInstanceByCID::operator()( const nsIID& aIID, void** aInstancePtr ) const
|
||||
{
|
||||
nsresult status = nsComponentManager::CreateInstance(mCID, mOuter, aIID, aInstancePtr);
|
||||
if ( !NS_SUCCEEDED(status) )
|
||||
*aInstancePtr = 0;
|
||||
{
|
||||
nsresult status = nsComponentManager::CreateInstance(mCID, mOuter, aIID, aInstancePtr);
|
||||
if ( !NS_SUCCEEDED(status) )
|
||||
*aInstancePtr = 0;
|
||||
|
||||
if ( mErrorPtr )
|
||||
*mErrorPtr = status;
|
||||
return status;
|
||||
}
|
||||
if ( mErrorPtr )
|
||||
*mErrorPtr = status;
|
||||
return status;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsCreateInstanceByProgID::operator()( const nsIID& aIID, void** aInstancePtr ) const
|
||||
{
|
||||
nsresult status;
|
||||
if ( mProgID )
|
||||
{
|
||||
if ( !NS_SUCCEEDED(status = nsComponentManager::CreateInstance(mProgID, mOuter, aIID, aInstancePtr)) )
|
||||
*aInstancePtr = 0;
|
||||
}
|
||||
else
|
||||
status = NS_ERROR_NULL_POINTER;
|
||||
{
|
||||
nsresult status;
|
||||
if ( mProgID )
|
||||
{
|
||||
if ( !NS_SUCCEEDED(status = nsComponentManager::CreateInstance(mProgID, mOuter, aIID, aInstancePtr)) )
|
||||
*aInstancePtr = 0;
|
||||
}
|
||||
else
|
||||
status = NS_ERROR_NULL_POINTER;
|
||||
|
||||
if ( mErrorPtr )
|
||||
*mErrorPtr = status;
|
||||
return status;
|
||||
}
|
||||
if ( mErrorPtr )
|
||||
*mErrorPtr = status;
|
||||
return status;
|
||||
}
|
||||
|
||||
/* prototypes for the Mac */
|
||||
PRBool PR_CALLBACK
|
||||
@ -211,7 +211,7 @@ nsCID_Destroy(nsHashKey *aKey, void *aData, void* closure)
|
||||
nsCID* entry = NS_STATIC_CAST(nsCID*, aData);
|
||||
// nasty hack. We "know" that kNoCID was entered into the hash table.
|
||||
if (entry != &kNoCID)
|
||||
delete entry;
|
||||
delete entry;
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
@ -260,11 +260,11 @@ nsresult nsComponentManagerImpl::Init(void)
|
||||
}
|
||||
|
||||
if (mLoaders == nsnull) {
|
||||
mLoaders = new nsSupportsHashtable(16, /* Thread safe */ PR_TRUE);
|
||||
if (mLoaders == nsnull)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
nsStringKey loaderKey(nativeComponentType);
|
||||
mLoaders->Put(&loaderKey, mNativeComponentLoader);
|
||||
mLoaders = new nsSupportsHashtable(16, /* Thread safe */ PR_TRUE);
|
||||
if (mLoaders == nsnull)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
nsStringKey loaderKey(nativeComponentType);
|
||||
mLoaders->Put(&loaderKey, mNativeComponentLoader);
|
||||
}
|
||||
|
||||
#ifdef USE_REGISTRY
|
||||
@ -306,12 +306,12 @@ nsresult nsComponentManagerImpl::Shutdown(void)
|
||||
#endif /* USE_REGISTRY */
|
||||
|
||||
// This is were the nsFileSpec was deleted, so I am
|
||||
// going to assign zero to
|
||||
mComponentsDir = 0;
|
||||
// going to assign zero to
|
||||
mComponentsDir = 0;
|
||||
|
||||
// Release all the component loaders
|
||||
if (mLoaders)
|
||||
delete mLoaders;
|
||||
delete mLoaders;
|
||||
|
||||
// we have an extra reference on this one, which is probably a good thing
|
||||
NS_IF_RELEASE(mNativeComponentLoader);
|
||||
@ -358,7 +358,7 @@ nsComponentManagerImpl::PlatformInit(void)
|
||||
// We need to create our registry. Since we are in the constructor
|
||||
// we haven't gone as far as registering the registry factory.
|
||||
// Hence, we hand create a registry.
|
||||
if (mRegistry == NULL) {
|
||||
if (mRegistry == NULL) {
|
||||
nsIFactory *registryFactory = NULL;
|
||||
rv = NS_RegistryGetFactory(®istryFactory);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
@ -452,15 +452,15 @@ nsComponentManagerImpl::PlatformInit(void)
|
||||
if (!mComponentsDir)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
char* componentDescriptor;
|
||||
mComponentsDir->GetPath(&componentDescriptor);
|
||||
if (!componentDescriptor)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
char* componentDescriptor;
|
||||
mComponentsDir->GetPath(&componentDescriptor);
|
||||
if (!componentDescriptor)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
mComponentsOffset = strlen(componentDescriptor);
|
||||
|
||||
if (componentDescriptor)
|
||||
nsAllocator::Free(componentDescriptor);
|
||||
mComponentsOffset = strlen(componentDescriptor);
|
||||
|
||||
if (componentDescriptor)
|
||||
nsAllocator::Free(componentDescriptor);
|
||||
|
||||
|
||||
|
||||
@ -549,6 +549,7 @@ nsComponentManagerImpl::PlatformVersionCheck(nsRegistryKey *aXPCOMRootKey)
|
||||
}
|
||||
|
||||
#if 0
|
||||
// If ever revived, this code is not fully updated to escape the dll location
|
||||
void
|
||||
nsComponentManagerImpl::PlatformSetFileInfo(nsRegistryKey key, PRUint32 lastModifiedTime, PRUint32 fileSize)
|
||||
{
|
||||
@ -561,7 +562,7 @@ nsComponentManagerImpl::PlatformSetFileInfo(nsRegistryKey key, PRUint32 lastModi
|
||||
*
|
||||
* Stores the dll name, last modified time, size and 0 for number of
|
||||
* components in dll in the registry at location
|
||||
* ROOTKEY_COMMON/Software/Mozilla/XPCOM/Components/dllname
|
||||
* ROOTKEY_COMMON/Software/Mozilla/XPCOM/Components/dllname
|
||||
*/
|
||||
nsresult
|
||||
nsComponentManagerImpl::PlatformMarkNoComponents(nsDll *dll)
|
||||
@ -576,7 +577,7 @@ nsComponentManagerImpl::PlatformMarkNoComponents(nsDll *dll)
|
||||
{
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
PlatformSetFileInfo(dllPathKey, dll->GetLastModifiedTime(), dll->GetSize());
|
||||
rv = mRegistry->SetInt(dllPathKey, componentCountValueName, 0);
|
||||
|
||||
@ -605,7 +606,9 @@ nsComponentManagerImpl::PlatformRegister(const char *cidString,
|
||||
{
|
||||
rv = mRegistry->SetStringUTF8(IDkey,progIDValueName, progID);
|
||||
}
|
||||
rv = mRegistry->SetStringUTF8(IDkey, inprocServerValueName, dll->GetPersistentDescriptorString());
|
||||
rv = mRegistry->SetBytesUTF8(IDkey, inprocServerValueName,
|
||||
strlen(dll->GetPersistentDescriptorString()) + 1,
|
||||
NS_REINTERPRET_CAST(char*, dll->GetPersistentDescriptorString()));
|
||||
|
||||
if (progID)
|
||||
{
|
||||
@ -631,10 +634,21 @@ nsComponentManagerImpl::PlatformRegister(const char *cidString,
|
||||
nsresult
|
||||
nsComponentManagerImpl::PlatformUnregister(const char *cidString,
|
||||
const char *aLibrary)
|
||||
{
|
||||
{
|
||||
nsresult rv;
|
||||
PRUint32 length = strlen(aLibrary);
|
||||
char* eLibrary;
|
||||
rv = mRegistry->EscapeKey((PRUint8*)aLibrary, 1, &length, (PRUint8**)&eLibrary);
|
||||
if (rv != NS_OK)
|
||||
{
|
||||
return rv;
|
||||
}
|
||||
if (eLibrary == nsnull) // No escaping required
|
||||
eLibrary = (char*)aLibrary;
|
||||
|
||||
|
||||
PR_ASSERT(mRegistry!=NULL);
|
||||
|
||||
nsresult rv;
|
||||
|
||||
nsRegistryKey cidKey;
|
||||
rv = mRegistry->AddSubtreeRaw(mCLSIDKey, cidString, &cidKey);
|
||||
@ -648,9 +662,9 @@ nsComponentManagerImpl::PlatformUnregister(const char *cidString,
|
||||
}
|
||||
|
||||
mRegistry->RemoveSubtree(mCLSIDKey, cidString);
|
||||
|
||||
|
||||
nsRegistryKey libKey;
|
||||
rv = mRegistry->GetSubtreeRaw(mXPCOMKey, aLibrary, &libKey);
|
||||
rv = mRegistry->GetSubtreeRaw(mXPCOMKey, eLibrary, &libKey);
|
||||
if(NS_FAILED(rv)) return rv;
|
||||
|
||||
// We need to reduce the ComponentCount by 1.
|
||||
@ -662,13 +676,16 @@ nsComponentManagerImpl::PlatformUnregister(const char *cidString,
|
||||
|
||||
if (nComponents <= 0)
|
||||
{
|
||||
rv = mRegistry->RemoveSubtreeRaw(mXPCOMKey, aLibrary);
|
||||
rv = mRegistry->RemoveSubtreeRaw(mXPCOMKey, eLibrary);
|
||||
}
|
||||
else
|
||||
{
|
||||
rv = mRegistry->SetInt(libKey, componentCountValueName, nComponents);
|
||||
}
|
||||
|
||||
if (eLibrary != aLibrary)
|
||||
nsAllocator::Free(eLibrary);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -688,8 +705,9 @@ nsComponentManagerImpl::PlatformFind(const nsCID &aCID, nsFactoryEntry* *result)
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsXPIDLCString library;
|
||||
rv = mRegistry->GetStringUTF8(cidKey, inprocServerValueName,
|
||||
getter_Copies(library));
|
||||
PRUint32 tmp;
|
||||
rv = mRegistry->GetBytesUTF8(cidKey, inprocServerValueName,
|
||||
&tmp, (PRUint8**)getter_Copies(library).operator char**());
|
||||
if (NS_FAILED(rv))
|
||||
{
|
||||
// Registry inconsistent. No File name for CLSID.
|
||||
@ -729,7 +747,7 @@ nsComponentManagerImpl::PlatformProgIDToCLSID(const char *aProgID, nsCID *aClass
|
||||
PR_ASSERT(mRegistry);
|
||||
|
||||
nsresult rv;
|
||||
|
||||
|
||||
nsRegistryKey progIDKey;
|
||||
rv = mRegistry->GetSubtreeRaw(mClassesKey, aProgID, &progIDKey);
|
||||
if (NS_FAILED(rv)) return NS_ERROR_FACTORY_NOT_REGISTERED;
|
||||
@ -750,7 +768,7 @@ nsresult
|
||||
nsComponentManagerImpl::PlatformCLSIDToProgID(const nsCID *aClass,
|
||||
char* *aClassName, char* *aProgID)
|
||||
{
|
||||
|
||||
|
||||
PR_ASSERT(aClass);
|
||||
PR_ASSERT(mRegistry);
|
||||
|
||||
@ -809,8 +827,9 @@ nsresult nsComponentManagerImpl::PlatformPrePopulateRegistry()
|
||||
|
||||
// Create the CID entry
|
||||
nsXPIDLCString library;
|
||||
rv = mRegistry->GetStringUTF8(cidKey, inprocServerValueName,
|
||||
getter_Copies(library));
|
||||
PRUint32 tmp;
|
||||
rv = mRegistry->GetBytesUTF8(cidKey, inprocServerValueName,
|
||||
&tmp, (PRUint8**)getter_Copies(library).operator char**());
|
||||
if (NS_FAILED(rv)) continue;
|
||||
nsCID aClass;
|
||||
|
||||
@ -864,7 +883,7 @@ nsresult nsComponentManagerImpl::PlatformPrePopulateRegistry()
|
||||
if (NS_FAILED(rv)) continue;
|
||||
|
||||
nsCID *aClass = new nsCID();
|
||||
if (!aClass) continue; // Protect against out of memory.
|
||||
if (!aClass) continue; // Protect against out of memory.
|
||||
if (!(aClass->Parse(cidString)))
|
||||
{
|
||||
delete aClass;
|
||||
@ -948,7 +967,7 @@ nsComponentManagerImpl::LoadFactory(nsFactoryEntry *aEntry,
|
||||
(const char *)aEntry->location, (const char *)aEntry->type));
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -1031,7 +1050,7 @@ nsComponentManagerImpl::GetClassObject(const nsCID &aClass, const nsIID &aIID,
|
||||
|
||||
PR_LOG(nsComponentManagerLog, PR_LOG_WARNING,
|
||||
("\t\tGetClassObject() %s", NS_SUCCEEDED(rv) ? "succeeded" : "FAILED"));
|
||||
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -1164,7 +1183,7 @@ nsComponentManagerImpl::CreateInstance(const nsCID &aClass,
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
*aResult = NULL;
|
||||
|
||||
|
||||
nsIFactory *factory = NULL;
|
||||
nsresult res = FindFactory(aClass, &factory);
|
||||
if (NS_SUCCEEDED(res))
|
||||
@ -1270,14 +1289,14 @@ nsComponentManagerImpl::RegistryLocationForSpec(nsIFile *aSpec,
|
||||
char *persistentDescriptor;
|
||||
|
||||
if (containedIn){
|
||||
|
||||
rv = aSpec->GetPath(&persistentDescriptor);
|
||||
|
||||
rv = aSpec->GetPath(&persistentDescriptor);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
char* relativeLocation = persistentDescriptor + mComponentsOffset + 1;
|
||||
|
||||
rv = MakeRegistryName(relativeLocation, XPCOM_RELCOMPONENT_PREFIX,
|
||||
char* relativeLocation = persistentDescriptor + mComponentsOffset + 1;
|
||||
|
||||
rv = MakeRegistryName(relativeLocation, XPCOM_RELCOMPONENT_PREFIX,
|
||||
aRegistryName);
|
||||
} else {
|
||||
/* absolute names include volume info on Mac, so persistent descriptor */
|
||||
@ -1400,11 +1419,11 @@ nsComponentManagerImpl::RegisterFactory(const nsCID &aClass,
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PR_LOG(nsComponentManagerLog, PR_LOG_WARNING,
|
||||
("\t\tFactory register succeeded progid=%s.",
|
||||
aProgID ? aProgID : "<none>"));
|
||||
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -1535,17 +1554,17 @@ nsComponentManagerImpl::RegisterComponentCommon(const nsCID &aClass,
|
||||
rv = AddComponentToRegistry(aClass, className, progID,
|
||||
aRegistryName, aType);
|
||||
if (NS_FAILED(rv)) {
|
||||
PR_LOG(nsComponentManagerLog, PR_LOG_ERROR,
|
||||
("\t\tadding %s %s to registry FAILED", className, progID));
|
||||
PR_LOG(nsComponentManagerLog, PR_LOG_ERROR,
|
||||
("\t\tadding %s %s to registry FAILED", className, progID));
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
rv = GetLoaderForType(aType, getter_AddRefs(loader));
|
||||
if (NS_FAILED(rv)) {
|
||||
PR_LOG(nsComponentManagerLog, PR_LOG_ERROR,
|
||||
("\t\tgetting loader for %s FAILED\n", aType));
|
||||
PR_LOG(nsComponentManagerLog, PR_LOG_ERROR,
|
||||
("\t\tgetting loader for %s FAILED\n", aType));
|
||||
goto out;
|
||||
}
|
||||
|
||||
@ -1556,7 +1575,7 @@ nsComponentManagerImpl::RegisterComponentCommon(const nsCID &aClass,
|
||||
}
|
||||
|
||||
if (entry) { // aReplace implicit from test above
|
||||
delete entry;
|
||||
delete entry;
|
||||
}
|
||||
|
||||
/* unless the fabric of the universe bends, we'll get entry back */
|
||||
@ -1565,7 +1584,7 @@ nsComponentManagerImpl::RegisterComponentCommon(const nsCID &aClass,
|
||||
|
||||
/* don't try to clean up, just drop everything and run */
|
||||
if (!sanity)
|
||||
return NS_ERROR_FACTORY_NOT_REGISTERED;
|
||||
return NS_ERROR_FACTORY_NOT_REGISTERED;
|
||||
|
||||
/* we've put the new entry in the hash table, so don't delete on error */
|
||||
newEntry = nsnull;
|
||||
@ -1578,10 +1597,10 @@ nsComponentManagerImpl::RegisterComponentCommon(const nsCID &aClass,
|
||||
) {
|
||||
rv = HashProgID(progID, aClass);
|
||||
if (NS_FAILED(rv)) {
|
||||
PR_LOG(nsComponentManagerLog, PR_LOG_ERROR,
|
||||
("\t\tHashProgID(%s) FAILED\n", progID));
|
||||
PR_LOG(nsComponentManagerLog, PR_LOG_ERROR,
|
||||
("\t\tHashProgID(%s) FAILED\n", progID));
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Let the loader do magic things now
|
||||
@ -1615,9 +1634,9 @@ nsComponentManagerImpl::GetLoaderForType(const char *aType,
|
||||
|
||||
loader = (nsIComponentLoader *)mLoaders->Get(&typeKey);
|
||||
if (loader) {
|
||||
// nsSupportsHashtable does the AddRef
|
||||
*aLoader = loader;
|
||||
return NS_OK;
|
||||
// nsSupportsHashtable does the AddRef
|
||||
*aLoader = loader;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsRegistryKey loaderKey;
|
||||
@ -1634,7 +1653,7 @@ nsComponentManagerImpl::GetLoaderForType(const char *aType,
|
||||
fprintf(stderr, "nCMI: constructing loader for type %s = %s\n", aType, progID);
|
||||
#endif
|
||||
|
||||
rv = CreateInstanceByProgID(progID, nsnull, NS_GET_IID(nsIComponentLoader), (void **)&loader);
|
||||
rv = CreateInstanceByProgID(progID, nsnull, NS_GET_IID(nsIComponentLoader), (void **)&loader);
|
||||
PR_FREEIF(progID);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
@ -1642,8 +1661,8 @@ nsComponentManagerImpl::GetLoaderForType(const char *aType,
|
||||
rv = loader->Init(this, mRegistry);
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
mLoaders->Put(&typeKey, loader);
|
||||
*aLoader = loader;
|
||||
mLoaders->Put(&typeKey, loader);
|
||||
*aLoader = loader;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
@ -1676,6 +1695,16 @@ nsComponentManagerImpl::AddComponentToRegistry(const nsCID &aClass,
|
||||
const char *aType)
|
||||
{
|
||||
nsresult rv;
|
||||
PRUint32 length = strlen(aRegistryName);
|
||||
char* eRegistryName;
|
||||
rv = mRegistry->EscapeKey((PRUint8*)aRegistryName, 1, &length, (PRUint8**)&eRegistryName);
|
||||
if (rv != NS_OK)
|
||||
{
|
||||
return rv;
|
||||
}
|
||||
if (eRegistryName == nsnull) // No escaping required
|
||||
eRegistryName = (char*)aRegistryName;
|
||||
|
||||
nsRegistryKey IDKey;
|
||||
PRInt32 nComponents = 0;
|
||||
|
||||
@ -1693,7 +1722,9 @@ nsComponentManagerImpl::AddComponentToRegistry(const nsCID &aClass,
|
||||
goto out;
|
||||
}
|
||||
|
||||
rv = mRegistry->SetStringUTF8(IDKey, inprocServerValueName, aRegistryName);
|
||||
rv = mRegistry->SetBytesUTF8(IDKey, inprocServerValueName,
|
||||
strlen(aRegistryName) + 1,
|
||||
(PRUint8*)aRegistryName);
|
||||
if (NS_FAILED(rv))
|
||||
goto out;
|
||||
|
||||
@ -1716,7 +1747,7 @@ nsComponentManagerImpl::AddComponentToRegistry(const nsCID &aClass,
|
||||
}
|
||||
|
||||
nsRegistryKey compKey;
|
||||
rv = mRegistry->AddSubtreeRaw(mXPCOMKey, aRegistryName, &compKey);
|
||||
rv = mRegistry->AddSubtreeRaw(mXPCOMKey, eRegistryName, &compKey);
|
||||
|
||||
// update component count
|
||||
rv = mRegistry->GetInt(compKey, componentCountValueName, &nComponents);
|
||||
@ -1728,6 +1759,8 @@ nsComponentManagerImpl::AddComponentToRegistry(const nsCID &aClass,
|
||||
out:
|
||||
// XXX if failed, undo registry adds or set invalid bit? How?
|
||||
nsCRT::free(cidString);
|
||||
if (eRegistryName != aRegistryName)
|
||||
nsAllocator::Free(eRegistryName);
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -1742,7 +1775,7 @@ nsComponentManagerImpl::UnregisterFactory(const nsCID &aClass,
|
||||
("nsComponentManager: UnregisterFactory(%s)", buf));
|
||||
delete [] buf;
|
||||
}
|
||||
|
||||
|
||||
nsIDKey key(aClass);
|
||||
nsresult res = NS_ERROR_FACTORY_NOT_REGISTERED;
|
||||
nsFactoryEntry *old = (nsFactoryEntry *) mFactories->Get(&key);
|
||||
@ -1790,9 +1823,9 @@ nsComponentManagerImpl::UnregisterComponent(const nsCID &aClass,
|
||||
rv = PlatformUnregister(cidString, registryName);
|
||||
delete [] cidString;
|
||||
#endif
|
||||
|
||||
|
||||
PR_ExitMonitor(mMon);
|
||||
|
||||
|
||||
PR_LOG(nsComponentManagerLog, PR_LOG_WARNING,
|
||||
("nsComponentManager: Factory unregister(%s) %s.", registryName,
|
||||
NS_SUCCEEDED(rv) ? "succeeded" : "FAILED"));
|
||||
@ -1821,18 +1854,18 @@ CanUnload_enumerate(nsHashKey *key, void *aData, void *aClosure)
|
||||
{
|
||||
nsIComponentLoader *loader = (nsIComponentLoader *)aData;
|
||||
struct CanUnload_closure *closure =
|
||||
(struct CanUnload_closure *)aClosure;
|
||||
(struct CanUnload_closure *)aClosure;
|
||||
|
||||
if (loader == closure->native) {
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "CanUnload_enumerate: skipping native\n");
|
||||
fprintf(stderr, "CanUnload_enumerate: skipping native\n");
|
||||
#endif
|
||||
return PR_TRUE;
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
closure->status = loader->UnloadAll(closure->when);
|
||||
if (NS_FAILED(closure->status))
|
||||
return PR_FALSE;
|
||||
return PR_FALSE;
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
@ -1854,7 +1887,7 @@ nsComponentManagerImpl::UnloadLibraries(nsIServiceManager *serviceMgr, PRInt32 a
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
PR_EnterMonitor(mMon);
|
||||
|
||||
|
||||
PR_LOG(nsComponentManagerLog, PR_LOG_ALWAYS,
|
||||
("nsComponentManager: Unloading Libraries."));
|
||||
|
||||
@ -1883,9 +1916,9 @@ nsComponentManagerImpl::UnloadLibraries(nsIServiceManager *serviceMgr, PRInt32 a
|
||||
* of all components. No default director is looked at.
|
||||
*
|
||||
* Directory and fullname are what NSPR will accept. For eg.
|
||||
* WIN y:/home/dp/mozilla/dist/bin
|
||||
* UNIX /home/dp/mozilla/dist/bin
|
||||
* MAC /Hard drive/mozilla/dist/apprunner
|
||||
* WIN y:/home/dp/mozilla/dist/bin
|
||||
* UNIX /home/dp/mozilla/dist/bin
|
||||
* MAC /Hard drive/mozilla/dist/apprunner
|
||||
*
|
||||
* This will take care not loading already registered dlls, finding and
|
||||
* registering new dlls, re-registration of modified dlls
|
||||
@ -1905,10 +1938,10 @@ AutoRegister_enumerate(nsHashKey *key, void *aData, void *aClosure)
|
||||
{
|
||||
nsIComponentLoader *loader = NS_STATIC_CAST(nsIComponentLoader *, aData);
|
||||
struct AutoReg_closure *closure =
|
||||
(struct AutoReg_closure *)aClosure;
|
||||
(struct AutoReg_closure *)aClosure;
|
||||
|
||||
if (loader == closure->native)
|
||||
return PR_TRUE;
|
||||
return PR_TRUE;
|
||||
|
||||
PR_ASSERT(NS_SUCCEEDED(closure->status));
|
||||
|
||||
@ -1922,7 +1955,7 @@ RegisterDeferred_enumerate(nsHashKey *key, void *aData, void *aClosure)
|
||||
{
|
||||
nsIComponentLoader *loader = NS_STATIC_CAST(nsIComponentLoader *, aData);
|
||||
struct AutoReg_closure *closure =
|
||||
(struct AutoReg_closure *)aClosure;
|
||||
(struct AutoReg_closure *)aClosure;
|
||||
PR_ASSERT(NS_SUCCEEDED(closure->status));
|
||||
|
||||
PRBool registered;
|
||||
@ -1947,7 +1980,7 @@ nsComponentManagerImpl::AutoRegister(PRInt32 when, nsIFile *inDirSpec)
|
||||
{
|
||||
// Use supplied components' directory
|
||||
dir = inDirSpec;
|
||||
|
||||
|
||||
// Set components' directory for AutoRegisterInterfces to query
|
||||
NS_WITH_SERVICE(nsIProperties, directoryService, NS_DIRECTORY_SERVICE_PROGID, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
@ -1976,12 +2009,12 @@ nsComponentManagerImpl::AutoRegister(PRInt32 when, nsIFile *inDirSpec)
|
||||
|
||||
rv = iim->AutoRegisterInterfaces();
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
return rv;
|
||||
|
||||
/* do the native loader first, so we can find other loaders */
|
||||
rv = mNativeComponentLoader->AutoRegisterComponents((PRInt32)when, dir);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
return rv;
|
||||
|
||||
/* XXX eagerly instantiate all known loaders */
|
||||
nsCOMPtr<nsIEnumerator> loaderEnum;
|
||||
@ -2043,14 +2076,14 @@ AutoRegisterComponent_enumerate(nsHashKey *key, void *aData, void *aClosure)
|
||||
PRBool didRegister;
|
||||
nsIComponentLoader *loader = (nsIComponentLoader *)aData;
|
||||
struct AutoReg_closure *closure =
|
||||
(struct AutoReg_closure *)aClosure;
|
||||
(struct AutoReg_closure *)aClosure;
|
||||
|
||||
closure->status = loader->AutoRegisterComponent(closure->when,
|
||||
closure->spec,
|
||||
&didRegister);
|
||||
closure->spec,
|
||||
&didRegister);
|
||||
|
||||
if (NS_SUCCEEDED(closure->status) && didRegister)
|
||||
return PR_FALSE; // Stop enumeration as we are done
|
||||
return PR_FALSE; // Stop enumeration as we are done
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
@ -2060,7 +2093,7 @@ AutoUnregisterComponent_enumerate(nsHashKey *key, void *aData, void *aClosure)
|
||||
PRBool didUnregister;
|
||||
nsIComponentLoader *loader = (nsIComponentLoader *)aData;
|
||||
struct AutoReg_closure *closure =
|
||||
(struct AutoReg_closure *)aClosure;
|
||||
(struct AutoReg_closure *)aClosure;
|
||||
|
||||
closure->status = loader->AutoUnregisterComponent(closure->when,
|
||||
closure->spec,
|
||||
@ -2088,7 +2121,7 @@ nsComponentManagerImpl::AutoRegisterComponent(PRInt32 when,
|
||||
*/
|
||||
mLoaders->Enumerate(AutoRegisterComponent_enumerate, &closure);
|
||||
return NS_FAILED(closure.status)
|
||||
? NS_ERROR_FACTORY_NOT_REGISTERED : NS_OK;
|
||||
? NS_ERROR_FACTORY_NOT_REGISTERED : NS_OK;
|
||||
|
||||
}
|
||||
|
||||
@ -2106,7 +2139,7 @@ nsComponentManagerImpl::AutoUnregisterComponent(PRInt32 when,
|
||||
mLoaders->Enumerate(AutoUnregisterComponent_enumerate, &closure);
|
||||
|
||||
return NS_FAILED(closure.status)
|
||||
? NS_ERROR_FACTORY_NOT_REGISTERED : NS_OK;
|
||||
? NS_ERROR_FACTORY_NOT_REGISTERED : NS_OK;
|
||||
|
||||
}
|
||||
|
||||
|
@ -170,8 +170,9 @@ protected:
|
||||
* alpha0.70 : using nsIFileSpec. PRTime -> PRUint32
|
||||
* alpha0.90 : using nsIComponentLoader, abs:/rel:/lib:, shaver-cleanup
|
||||
* alpha0.92 : restructured registry keys
|
||||
* alpha0.93 : changed component names to native strings instead of UTF8
|
||||
*/
|
||||
#define NS_XPCOM_COMPONENT_MANAGER_VERSION_STRING "alpha0.92"
|
||||
#define NS_XPCOM_COMPONENT_MANAGER_VERSION_STRING "alpha0.93"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
|
@ -51,11 +51,17 @@ interface nsIRegistry : nsISupports
|
||||
string getStringUTF8(in nsRegistryKey baseKey, in string path);
|
||||
void setStringUTF8(in nsRegistryKey baseKey, in string path, in string value);
|
||||
|
||||
void getBytesUTF8(in nsRegistryKey baseKey, in string path, out PRUint32 length, [retval, array, size_is(length)] out PRUint8 valueArray);
|
||||
void setBytesUTF8(in nsRegistryKey baseKey, in string path, in PRUint32 length, [array, size_is(length)] in PRUint8 valueArray);
|
||||
PRInt32 getInt(in nsRegistryKey baseKey, in string path);
|
||||
void setInt(in nsRegistryKey baseKey, in string path, in PRInt32 value);
|
||||
PRInt64 getLongLong(in nsRegistryKey baseKey, in string path);
|
||||
void setLongLong(in nsRegistryKey baseKey, in string path, inout PRInt64 value);
|
||||
|
||||
/**
|
||||
* addSubtree() and friends need to be renamed to addKeyUTF8().
|
||||
* If you are using these forms make sure you pass UTF8 data
|
||||
*/
|
||||
nsRegistryKey addSubtree(in nsRegistryKey baseKey, in string path);
|
||||
void removeSubtree(in nsRegistryKey baseKey, in string path);
|
||||
nsRegistryKey getSubtree(in nsRegistryKey baseKey, in string path);
|
||||
@ -77,6 +83,13 @@ interface nsIRegistry : nsISupports
|
||||
PRUint32 getValueLength(in nsRegistryKey baseKey, in string path);
|
||||
void deleteValue(in nsRegistryKey baseKey, in string path);
|
||||
|
||||
/**
|
||||
* escapeKey() takes arbitrary binary data and converts it into
|
||||
* valid ASCII which can be used as registry key or value names
|
||||
*/
|
||||
void escapeKey([array, size_is(length)] in PRUint8 key, in PRUint32 terminator, inout PRUint32 length, [retval, array, size_is(length)] out PRUint8 escaped);
|
||||
void unescapeKey([array, size_is(length)] in PRUint8 escaped, in PRUint32 terminator, inout PRUint32 length, [retval, array, size_is(length)] out PRUint8 key);
|
||||
|
||||
attribute string currentUserName;
|
||||
|
||||
void pack();
|
||||
|
@ -202,19 +202,35 @@ nsNativeComponentLoader::Init(nsIComponentManager *aCompMgr, nsISupports *aReg)
|
||||
// Get library name
|
||||
nsXPIDLCString library;
|
||||
rv = node->GetNameUTF8(getter_Copies(library));
|
||||
|
||||
if (NS_FAILED(rv)) continue;
|
||||
|
||||
char* uLibrary;
|
||||
char* eLibrary = (char*)library.operator const char*();
|
||||
PRUint32 length = strlen(eLibrary);
|
||||
rv = mRegistry->UnescapeKey((PRUint8*)eLibrary, 1, &length, (PRUint8**)&uLibrary);
|
||||
|
||||
if (NS_FAILED(rv)) continue;
|
||||
|
||||
if (uLibrary == nsnull)
|
||||
uLibrary = eLibrary;
|
||||
|
||||
// Get key associated with library
|
||||
nsRegistryKey libKey;
|
||||
rv = node->GetKey(&libKey);
|
||||
if (NS_FAILED(rv)) continue;
|
||||
if (!NS_FAILED(rv)) // Cannot continue here, because we have to free unescape
|
||||
{
|
||||
// Create nsDll with this name
|
||||
nsDll *dll = NULL;
|
||||
PRInt64 lastModTime;
|
||||
PRInt64 fileSize;
|
||||
GetRegistryDllInfo(libKey, &lastModTime, &fileSize);
|
||||
rv = CreateDll(NULL, uLibrary, &lastModTime, &fileSize, &dll);
|
||||
}
|
||||
if (uLibrary != eLibrary
|
||||
&& uLibrary != nsnull)
|
||||
nsAllocator::Free(uLibrary);
|
||||
|
||||
// Create nsDll with this name
|
||||
nsDll *dll = NULL;
|
||||
PRInt64 lastModTime;
|
||||
PRInt64 fileSize;
|
||||
GetRegistryDllInfo(libKey, &lastModTime, &fileSize);
|
||||
rv = CreateDll(NULL, library, &lastModTime, &fileSize, &dll);
|
||||
if (NS_FAILED(rv)) continue;
|
||||
}
|
||||
|
||||
@ -337,7 +353,7 @@ nsFreeLibrary(nsDll *dll, nsIServiceManager *serviceMgr, PRInt32 when)
|
||||
if (proc)
|
||||
{
|
||||
canUnload = proc(serviceMgr);
|
||||
rv = NS_OK; // No error status returned by call.
|
||||
rv = NS_OK; // No error status returned by call.
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -527,13 +543,13 @@ nsNativeComponentLoader::DumpLoadError(nsDll *dll,
|
||||
nsCAutoString errorMsg(aNsprErrorMsg);
|
||||
|
||||
#if defined(MOZ_DEMANGLE_SYMBOLS)
|
||||
// Demangle undefined symbols
|
||||
nsCAutoString undefinedMagicString("undefined symbol:");
|
||||
// Demangle undefined symbols
|
||||
nsCAutoString undefinedMagicString("undefined symbol:");
|
||||
|
||||
PRInt32 offset = errorMsg.Find(undefinedMagicString, PR_TRUE);
|
||||
PRInt32 offset = errorMsg.Find(undefinedMagicString, PR_TRUE);
|
||||
|
||||
if (offset != kNotFound)
|
||||
{
|
||||
if (offset != kNotFound)
|
||||
{
|
||||
nsCAutoString symbol(errorMsg);
|
||||
nsCAutoString demangledSymbol("");
|
||||
|
||||
@ -563,8 +579,8 @@ nsNativeComponentLoader::DumpLoadError(nsDll *dll,
|
||||
tmp += demangledSymbol;
|
||||
|
||||
errorMsg = tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // MOZ_DEMANGLE_SYMBOLS
|
||||
|
||||
// Do NSPR log
|
||||
@ -708,24 +724,24 @@ nsNativeComponentLoader::AutoRegisterComponent(PRInt32 when,
|
||||
|
||||
#ifdef XP_MAC // sdagley dougt fix
|
||||
// rjc - on Mac, check the file's type code (skip checking the creator code)
|
||||
|
||||
nsCOMPtr<nsILocalFileMac> localFileMac = do_QueryInterface(component);
|
||||
if (localFileMac)
|
||||
{
|
||||
OSType type;
|
||||
OSType creator;
|
||||
rv = localFileMac->GetFileTypeAndCreator(&type, &creator);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
// on Mac, Mozilla shared libraries are of type 'shlb'
|
||||
// Note: we don't check the creator (which for Mozilla is 'MOZZ')
|
||||
// so that 3rd party shared libraries will be noticed!
|
||||
if (type == 'shlb')
|
||||
{
|
||||
validExtension = PR_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsILocalFileMac> localFileMac = do_QueryInterface(component);
|
||||
if (localFileMac)
|
||||
{
|
||||
OSType type;
|
||||
OSType creator;
|
||||
rv = localFileMac->GetFileTypeAndCreator(&type, &creator);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
// on Mac, Mozilla shared libraries are of type 'shlb'
|
||||
// Note: we don't check the creator (which for Mozilla is 'MOZZ')
|
||||
// so that 3rd party shared libraries will be noticed!
|
||||
if (type == 'shlb')
|
||||
{
|
||||
validExtension = PR_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
char *leafName = NULL;
|
||||
@ -934,12 +950,25 @@ nsNativeComponentLoader::GetRegistryDllInfo(const char *aLocation,
|
||||
PRInt64 *fileSize)
|
||||
{
|
||||
nsresult rv;
|
||||
PRUint32 length = strlen(aLocation);
|
||||
char* eLocation;
|
||||
rv = mRegistry->EscapeKey((PRUint8*)aLocation, 1, &length, (PRUint8**)&eLocation);
|
||||
if (rv != NS_OK)
|
||||
{
|
||||
return rv;
|
||||
}
|
||||
if (eLocation == nsnull) // No escaping required
|
||||
eLocation = (char*)aLocation;
|
||||
|
||||
|
||||
nsRegistryKey key;
|
||||
rv = mRegistry->GetSubtreeRaw(mXPCOMKey, aLocation, &key);
|
||||
rv = mRegistry->GetSubtreeRaw(mXPCOMKey, eLocation, &key);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
return GetRegistryDllInfo(key, lastModifiedTime, fileSize);
|
||||
rv = GetRegistryDllInfo(key, lastModifiedTime, fileSize);
|
||||
if (aLocation != eLocation)
|
||||
nsAllocator::Free(eLocation);
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
@ -955,8 +984,7 @@ nsNativeComponentLoader::GetRegistryDllInfo(nsRegistryKey key,
|
||||
PRInt64 fsize;
|
||||
rv = mRegistry->GetLongLong(key, fileSizeValueName, &fsize);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
*fileSize = fsize;
|
||||
|
||||
*fileSize = fsize;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -966,20 +994,46 @@ nsNativeComponentLoader::SetRegistryDllInfo(const char *aLocation,
|
||||
PRInt64 *fileSize)
|
||||
{
|
||||
nsresult rv;
|
||||
PRUint32 length = strlen(aLocation);
|
||||
char* eLocation;
|
||||
rv = mRegistry->EscapeKey((PRUint8*)aLocation, 1, &length, (PRUint8**)&eLocation);
|
||||
if (rv != NS_OK)
|
||||
{
|
||||
return rv;
|
||||
}
|
||||
if (eLocation == nsnull) // No escaping required
|
||||
eLocation = (char*)aLocation;
|
||||
|
||||
nsRegistryKey key;
|
||||
rv = mRegistry->GetSubtreeRaw(mXPCOMKey, aLocation, &key);
|
||||
rv = mRegistry->GetSubtreeRaw(mXPCOMKey, eLocation, &key);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = mRegistry->SetLongLong(key, lastModValueName, lastModifiedTime);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
rv = mRegistry->SetLongLong(key, fileSizeValueName, fileSize);
|
||||
if (aLocation != eLocation)
|
||||
nsAllocator::Free(eLocation);
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsNativeComponentLoader::RemoveRegistryDllInfo(const char *aLocation)
|
||||
{
|
||||
return mRegistry->RemoveSubtree(mXPCOMKey, aLocation);
|
||||
nsresult rv;
|
||||
PRUint32 length = strlen(aLocation);
|
||||
char* eLocation;
|
||||
rv = mRegistry->EscapeKey((PRUint8*)aLocation, 1, &length, (PRUint8**)&eLocation);
|
||||
if (rv != NS_OK)
|
||||
{
|
||||
return rv;
|
||||
}
|
||||
if (eLocation == nsnull) // No escaping required
|
||||
eLocation = (char*)aLocation;
|
||||
|
||||
rv = mRegistry->RemoveSubtree(mXPCOMKey, eLocation);
|
||||
if (aLocation != eLocation)
|
||||
nsAllocator::Free(eLocation);
|
||||
return rv;
|
||||
}
|
||||
|
||||
//
|
||||
@ -988,18 +1042,18 @@ nsNativeComponentLoader::RemoveRegistryDllInfo(const char *aLocation)
|
||||
// be called in multiple situations:
|
||||
//
|
||||
// 1. Autoregister will create one for each dll it is trying to register. This
|
||||
// call will be passing a spec in.
|
||||
// {spec, NULL, 0, 0}
|
||||
// call will be passing a spec in.
|
||||
// {spec, NULL, 0, 0}
|
||||
//
|
||||
// 2. GetFactory() This will call CreateDll() with a null spec but will give
|
||||
// the registry represented name of the dll. If modtime and size are zero,
|
||||
// we will go the registry to find the right modtime and size.
|
||||
// {NULL, rel:libpref.so, 0, 0}
|
||||
// the registry represented name of the dll. If modtime and size are zero,
|
||||
// we will go the registry to find the right modtime and size.
|
||||
// {NULL, rel:libpref.so, 0, 0}
|
||||
//
|
||||
// 3. Prepopulation of dllCache A dll object created off a registry entry.
|
||||
// Specifically dll name is stored in rel: or abs: or lib: formats in the
|
||||
// registry along with its lastModTime and fileSize.
|
||||
// {NULL, rel:libpref.so, 8985659, 20987}
|
||||
// Specifically dll name is stored in rel: or abs: or lib: formats in the
|
||||
// registry along with its lastModTime and fileSize.
|
||||
// {NULL, rel:libpref.so, 8985659, 20987}
|
||||
nsresult
|
||||
nsNativeComponentLoader::CreateDll(nsIFile *aSpec, const char *aLocation,
|
||||
PRInt64 *modificationTime, PRInt64 *fileSize,
|
||||
|
@ -73,9 +73,9 @@ struct nsRegistry : public nsIRegistry {
|
||||
protected:
|
||||
HREG mReg; // Registry handle.
|
||||
#ifdef EXTRA_THREADSAFE
|
||||
PRLock *mregLock; // libreg isn't threadsafe. Use locks to synchronize.
|
||||
PRLock *mregLock; // libreg isn't threadsafe. Use locks to synchronize.
|
||||
#endif
|
||||
char *mCurRegFile; // these are to prevent open from opening the registry again
|
||||
char *mCurRegFile; // these are to prevent open from opening the registry again
|
||||
nsWellKnownRegistry mCurRegID;
|
||||
|
||||
NS_IMETHOD Close();
|
||||
@ -167,7 +167,7 @@ struct nsRegistryNode : public nsIRegistryNode {
|
||||
protected:
|
||||
HREG mReg; // Handle to registry this node is part of.
|
||||
char mName[MAXREGPATHLEN]; // Buffer to hold name.
|
||||
RKEY mChildKey; // Key corresponding to mName
|
||||
RKEY mChildKey; // Key corresponding to mName
|
||||
#ifdef EXTRA_THREADSAFE
|
||||
PRLock *mregLock;
|
||||
#endif
|
||||
@ -735,6 +735,94 @@ NS_IMETHODIMP nsRegistry::SetStringUTF8( nsRegistryKey baseKey, const char *path
|
||||
return regerr2nsresult( err );
|
||||
}
|
||||
|
||||
/*---------------------------- nsRegistry::GetBytesUTF8 ------------------------------
|
||||
| This function is just shorthand for fetching a char array. We |
|
||||
| implement it "manually" using NR_RegGetEntry |
|
||||
------------------------------------------------------------------------------*/
|
||||
NS_IMETHODIMP nsRegistry::GetBytesUTF8( nsRegistryKey baseKey, const char *path, PRUint32* length, PRUint8** result) {
|
||||
nsresult rv = NS_OK;
|
||||
REGERR err = REGERR_OK;
|
||||
|
||||
if ( !result )
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
char regStr[MAXREGPATHLEN];
|
||||
|
||||
// initialize the return value
|
||||
*length = 0;
|
||||
*result = 0;
|
||||
|
||||
// Get info about the requested entry.
|
||||
PRUint32 type;
|
||||
rv = GetValueType( baseKey, path, &type );
|
||||
// See if that worked.
|
||||
if( rv == NS_OK )
|
||||
{
|
||||
// Make sure the entry is an PRInt8 array.
|
||||
if( type == Bytes )
|
||||
{
|
||||
// Attempt to get string into our fixed buffer
|
||||
PR_Lock(mregLock);
|
||||
uint32 length2 = sizeof regStr;
|
||||
err = NR_RegGetEntry( mReg,(RKEY)baseKey,NS_CONST_CAST(char*,path), regStr, &length2);
|
||||
PR_Unlock(mregLock);
|
||||
|
||||
if ( err == REGERR_OK )
|
||||
{
|
||||
*length = length2;
|
||||
*result = (PRUint8*)(nsCRT::strdup(regStr));
|
||||
if (!*result)
|
||||
{
|
||||
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
*length = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
*length = length2;
|
||||
}
|
||||
}
|
||||
else if ( err == REGERR_BUFTOOSMALL )
|
||||
{
|
||||
// find the real size and malloc it
|
||||
rv = GetValueLength( baseKey, path, length );
|
||||
// See if that worked.
|
||||
if( rv == NS_OK )
|
||||
{
|
||||
*result = NS_REINTERPRET_CAST(PRUint8*,nsAllocator::Alloc( *length ));
|
||||
if( *result )
|
||||
{
|
||||
// Get bytes from registry into result field.
|
||||
PR_Lock(mregLock);
|
||||
length2 = *length;
|
||||
err = NR_RegGetEntry( mReg,(RKEY)baseKey,NS_CONST_CAST(char*,path), *result, &length2);
|
||||
*length = length2;
|
||||
PR_Unlock(mregLock);
|
||||
// Convert status.
|
||||
rv = regerr2nsresult( err );
|
||||
if ( rv != NS_OK )
|
||||
{
|
||||
// Didn't get result, free buffer
|
||||
nsCRT::free( NS_REINTERPRET_CAST(char*, *result) );
|
||||
*result = 0;
|
||||
*length = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// They asked for the wrong type of value.
|
||||
rv = NS_ERROR_REG_BADTYPE;
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*---------------------------- nsRegistry::GetInt ------------------------------
|
||||
| This function is just shorthand for fetching a 1-element PRInt32 array. We |
|
||||
| implement it "manually" using NR_RegGetEntry |
|
||||
@ -788,6 +876,24 @@ NS_IMETHODIMP nsRegistry::GetLongLong( nsRegistryKey baseKey, const char *path,
|
||||
// Convert status.
|
||||
return regerr2nsresult( err );
|
||||
}
|
||||
/*---------------------------- nsRegistry::SetBytesUTF8 ------------------------------
|
||||
| Write out the value as a char array, using NR_RegSetEntry. |
|
||||
------------------------------------------------------------------------------*/
|
||||
NS_IMETHODIMP nsRegistry::SetBytesUTF8( nsRegistryKey baseKey, const char *path, PRUint32 length, PRUint8* value) {
|
||||
REGERR err = REGERR_OK;
|
||||
// Set the contents.
|
||||
PR_Lock(mregLock);
|
||||
err = NR_RegSetEntry( mReg,
|
||||
(RKEY)baseKey,
|
||||
(char*)path,
|
||||
REGTYPE_ENTRY_BYTES,
|
||||
(char*)value,
|
||||
length);
|
||||
PR_Unlock(mregLock);
|
||||
// Convert result.
|
||||
return regerr2nsresult( err );
|
||||
}
|
||||
|
||||
/*---------------------------- nsRegistry::SetInt ------------------------------
|
||||
| Write out the value as a one-element PRInt32 array, using NR_RegSetEntry. |
|
||||
------------------------------------------------------------------------------*/
|
||||
@ -862,8 +968,8 @@ NS_IMETHODIMP nsRegistry::RemoveSubtree( nsRegistryKey baseKey, const char *path
|
||||
nsresult rv = NS_OK;
|
||||
REGERR err = REGERR_OK;
|
||||
|
||||
// libreg doesn't delete keys if there are subkeys under the key
|
||||
// Hence we have to recurse through to delete the subtree
|
||||
// libreg doesn't delete keys if there are subkeys under the key
|
||||
// Hence we have to recurse through to delete the subtree
|
||||
|
||||
RKEY key;
|
||||
|
||||
@ -871,13 +977,13 @@ NS_IMETHODIMP nsRegistry::RemoveSubtree( nsRegistryKey baseKey, const char *path
|
||||
err = NR_RegGetKey(mReg, baseKey, (char *)path, &key);
|
||||
PR_Unlock(mregLock);
|
||||
if (err != REGERR_OK)
|
||||
{
|
||||
rv = regerr2nsresult( err );
|
||||
{
|
||||
rv = regerr2nsresult( err );
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
// Now recurse through and delete all keys under hierarchy
|
||||
|
||||
|
||||
char subkeyname[MAXREGPATHLEN+1];
|
||||
REGENUM state = 0;
|
||||
subkeyname[0] = '\0';
|
||||
@ -885,7 +991,7 @@ NS_IMETHODIMP nsRegistry::RemoveSubtree( nsRegistryKey baseKey, const char *path
|
||||
REGENUM_NORMAL) == REGERR_OK)
|
||||
{
|
||||
#ifdef DEBUG_dp
|
||||
printf("...recursing into %s\n", subkeyname);
|
||||
printf("...recursing into %s\n", subkeyname);
|
||||
#endif /* DEBUG_dp */
|
||||
// Even though this is not a "Raw" API the subkeys may still, in fact,
|
||||
// *be* raw. Since we're recursively deleting this will work either way.
|
||||
@ -899,15 +1005,15 @@ NS_IMETHODIMP nsRegistry::RemoveSubtree( nsRegistryKey baseKey, const char *path
|
||||
if (err == REGERR_OK)
|
||||
{
|
||||
#ifdef DEBUG_dp
|
||||
printf("...deleting %s\n", path);
|
||||
printf("...deleting %s\n", path);
|
||||
#endif /* DEBUG_dp */
|
||||
PR_Lock(mregLock);
|
||||
err = NR_RegDeleteKey(mReg, baseKey, (char *)path);
|
||||
PR_Unlock(mregLock);
|
||||
}
|
||||
|
||||
// Convert result.
|
||||
rv = regerr2nsresult( err );
|
||||
// Convert result.
|
||||
rv = regerr2nsresult( err );
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -919,8 +1025,8 @@ NS_IMETHODIMP nsRegistry::RemoveSubtreeRaw( nsRegistryKey baseKey, const char *k
|
||||
nsresult rv = NS_OK;
|
||||
REGERR err = REGERR_OK;
|
||||
|
||||
// libreg doesn't delete keys if there are subkeys under the key
|
||||
// Hence we have to recurse through to delete the subtree
|
||||
// libreg doesn't delete keys if there are subkeys under the key
|
||||
// Hence we have to recurse through to delete the subtree
|
||||
|
||||
RKEY key;
|
||||
char subkeyname[MAXREGPATHLEN+1];
|
||||
@ -931,18 +1037,18 @@ NS_IMETHODIMP nsRegistry::RemoveSubtreeRaw( nsRegistryKey baseKey, const char *k
|
||||
err = NR_RegGetKeyRaw(mReg, baseKey, (char *)keyname, &key);
|
||||
PR_Unlock(mregLock);
|
||||
if (err != REGERR_OK)
|
||||
{
|
||||
rv = regerr2nsresult( err );
|
||||
{
|
||||
rv = regerr2nsresult( err );
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
// Now recurse through and delete all keys under hierarchy
|
||||
|
||||
|
||||
subkeyname[0] = '\0';
|
||||
while (NR_RegEnumSubkeys(mReg, key, &state, subkeyname, n, REGENUM_NORMAL) == REGERR_OK)
|
||||
{
|
||||
#ifdef DEBUG_dp
|
||||
printf("...recursing into %s\n", subkeyname);
|
||||
printf("...recursing into %s\n", subkeyname);
|
||||
#endif /* DEBUG_dp */
|
||||
err = RemoveSubtreeRaw(key, subkeyname);
|
||||
if (err != REGERR_OK) break;
|
||||
@ -952,15 +1058,15 @@ NS_IMETHODIMP nsRegistry::RemoveSubtreeRaw( nsRegistryKey baseKey, const char *k
|
||||
if (err == REGERR_OK)
|
||||
{
|
||||
#ifdef DEBUG_dp
|
||||
printf("...deleting %s\n", keyname);
|
||||
printf("...deleting %s\n", keyname);
|
||||
#endif /* DEBUG_dp */
|
||||
PR_Lock(mregLock);
|
||||
err = NR_RegDeleteKeyRaw(mReg, baseKey, (char *)keyname);
|
||||
PR_Unlock(mregLock);
|
||||
}
|
||||
|
||||
// Convert result.
|
||||
rv = regerr2nsresult( err );
|
||||
// Convert result.
|
||||
rv = regerr2nsresult( err );
|
||||
return rv;
|
||||
}
|
||||
/*-------------------------- nsRegistry::GetSubtree ----------------------------
|
||||
@ -1196,6 +1302,157 @@ NS_IMETHODIMP nsRegistry::Pack() {
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*----------------------------- nsRegistry::EscapeKey -------------------------------
|
||||
| Escape a binary key so that the registry works OK, since it expects UTF8
|
||||
| with no slashes or control characters. This is probably better than raw.
|
||||
| If no escaping is required, then the method is successful and a null is
|
||||
| returned, indicating that the caller should use the original string.
|
||||
------------------------------------------------------------------------------*/
|
||||
static const char sEscapeKeyHex[] = "0123456789abcdef0123456789ABCDEF";
|
||||
NS_IMETHODIMP nsRegistry::EscapeKey(PRUint8* key, PRUint32 termination, PRUint32* length, PRUint8** escaped)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
char* value = (char*)key;
|
||||
char* b = value;
|
||||
char* e = b + *length;
|
||||
int escapees = 0;
|
||||
while (b < e) // Count characters outside legal range or slash
|
||||
{
|
||||
int c = *b++;
|
||||
if (c <= ' '
|
||||
|| c > '~'
|
||||
|| c == '/'
|
||||
|| c == '%')
|
||||
{
|
||||
escapees++;
|
||||
}
|
||||
}
|
||||
if (escapees == 0) // If no escapees, then no results
|
||||
{
|
||||
*length = 0;
|
||||
*escaped = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
// New length includes two extra chars for escapees.
|
||||
*length += escapees * 2;
|
||||
*escaped = (PRUint8*)nsAllocator::Alloc(*length + termination);
|
||||
if (*escaped == nsnull)
|
||||
{
|
||||
*length = 0;
|
||||
*escaped = nsnull;
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
char* n = (char*)*escaped;
|
||||
b = value;
|
||||
while (escapees && b < e)
|
||||
{
|
||||
char c = *b++;
|
||||
if (c < ' '
|
||||
|| c > '~'
|
||||
|| c == '/'
|
||||
|| c == '%')
|
||||
{
|
||||
*(n++) = '%';
|
||||
*(n++) = sEscapeKeyHex[ 0xF & (c >> 4) ];
|
||||
*(n++) = sEscapeKeyHex[ 0xF & c ];
|
||||
escapees--;
|
||||
}
|
||||
else
|
||||
{
|
||||
*(n++) = c;
|
||||
}
|
||||
}
|
||||
e += termination;
|
||||
if (b < e)
|
||||
{
|
||||
strncpy(n, b, e - b);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*----------------------------- nsRegistry::UnescapeKey -------------------------------
|
||||
| Unscape a binary key so that the registry works OK, since it expects UTF8
|
||||
| with no slashes or control characters. This is probably better than raw.
|
||||
| If no escaping is required, then the method is successful and a null is
|
||||
| returned, indicating that the caller should use the original string.
|
||||
------------------------------------------------------------------------------*/
|
||||
NS_IMETHODIMP nsRegistry::UnescapeKey(PRUint8* escaped, PRUint32 termination, PRUint32* length, PRUint8** key)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
char* value = (char*)escaped;
|
||||
char* b = value;
|
||||
char* e = b + *length;
|
||||
int escapees = 0;
|
||||
while (b < e) // Count characters outside legal range or slash
|
||||
{
|
||||
if (*b++ == '%')
|
||||
{
|
||||
escapees++;
|
||||
}
|
||||
}
|
||||
if (escapees == 0) // If no escapees, then no results
|
||||
{
|
||||
*length = 0;
|
||||
*key = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
// New length includes two extra chars for escapees.
|
||||
*length -= escapees * 2;
|
||||
*key = (PRUint8*)nsAllocator::Alloc(*length + termination);
|
||||
if (*key == nsnull)
|
||||
{
|
||||
*length = 0;
|
||||
*key = nsnull;
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
char* n = (char*)*key;
|
||||
b = value;
|
||||
while (escapees && b < e)
|
||||
{
|
||||
char c = *(b++);
|
||||
if (c == '%')
|
||||
{
|
||||
if (e - b >= 2)
|
||||
{
|
||||
char* c1 = strchr(sEscapeKeyHex, *(b++));
|
||||
char* c2 = strchr(sEscapeKeyHex, *(b++));
|
||||
if (c1 != nsnull
|
||||
&& c2 != nsnull)
|
||||
{
|
||||
*(n++) = ((c2 - sEscapeKeyHex) & 0xF)
|
||||
| (((c1 - sEscapeKeyHex) & 0xF) << 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
escapees = -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
escapees = -1;
|
||||
}
|
||||
escapees--;
|
||||
}
|
||||
else
|
||||
{
|
||||
*(n++) = c;
|
||||
}
|
||||
}
|
||||
if (escapees < 0)
|
||||
{
|
||||
nsAllocator::Free(*key);
|
||||
*length = 0;
|
||||
*key = nsnull;
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
e += termination;
|
||||
if (b < e)
|
||||
{
|
||||
strncpy(n, b, e - b);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*-------------- nsRegSubtreeEnumerator::nsRegSubtreeEnumerator ----------------
|
||||
| The ctor simply stashes all the information that will be needed to enumerate |
|
||||
| the subkeys. |
|
||||
@ -1437,7 +1694,7 @@ NS_IMETHODIMP nsRegistryNode::GetNameUTF8( char **result ) {
|
||||
}
|
||||
|
||||
/*-------------------------- nsRegistryNode::GetKey ----------------------------
|
||||
| Get the subkey corresponding to this node |
|
||||
| Get the subkey corresponding to this node |
|
||||
| using NR_RegEnumSubkeys. |
|
||||
------------------------------------------------------------------------------*/
|
||||
NS_IMETHODIMP nsRegistryNode::GetKey( nsRegistryKey *r_key ) {
|
||||
|
@ -260,24 +260,29 @@ void nsHashtable::Reset(nsHashtableEnumFunc destroyFunc, void* closure)
|
||||
|
||||
nsStringKey::nsStringKey(const char* str)
|
||||
{
|
||||
MOZ_COUNT_CTOR(nsStringKey);
|
||||
mStr.AssignWithConversion(str);
|
||||
}
|
||||
|
||||
nsStringKey::nsStringKey(const PRUnichar* str)
|
||||
{
|
||||
MOZ_COUNT_CTOR(nsStringKey);
|
||||
mStr.Assign(str);
|
||||
}
|
||||
|
||||
nsStringKey::nsStringKey(const nsString& str) {
|
||||
MOZ_COUNT_CTOR(nsStringKey);
|
||||
mStr.Assign(str);
|
||||
}
|
||||
|
||||
nsStringKey::nsStringKey(const nsCString& str) {
|
||||
MOZ_COUNT_CTOR(nsStringKey);
|
||||
mStr.AssignWithConversion(str);
|
||||
}
|
||||
|
||||
nsStringKey::~nsStringKey(void)
|
||||
{
|
||||
MOZ_COUNT_DTOR(nsStringKey);
|
||||
}
|
||||
|
||||
PRUint32 nsStringKey::HashValue(void) const
|
||||
|
Loading…
Reference in New Issue
Block a user