Rob Stow wrote:
Daniel Wang wrote:
http://lxr.mozilla.org/mozilla/source/profile/src/nsProfile.cpp ?
http://lxr.mozilla.org/mozilla/source/modules/libreg/xpcom/nsRegistry.cpp
?
Thanks, but I've already looked at those two files - and
many others - and neither gives the file structure of
registry.dat.
(see cvs:source/modules/libreg/src/reg.c nr_ReadDesc(), NR_RegGetKey )
( cvs:source/modules/libreg/src/reg.h line 113 )
file header
0 long magic // must equal MAGIC_NUMBER (0x76644441L) */
4 short ver_major
6 short ver_minor
8 long avail // next available offset
12 long root // root object
each data entry seems to have this basic structure
offset
0 long location // object's offset (for verification)
4 long name // name string
8 short namelen // length of name string (including terminator)
10 short type // node type (key, or entry style)
12 long left // next object at this level (0 if none)
16 long down // KEY: first subkey VALUE: 0
16 long valuebuf // KEY: 0 VALUE: length available
20 long value // KEY: first entry object VALUE: value string
24 long valuelen // KEY: 0 VALUE: length of value data
28 long parent // the node on the immediate level above
32 long size // size of desc on disk
?? name[namelen]
?? data[valuelen]
note:
long is 32 bit
short is 16 bit
if ( (type) & (0x0010) ) then
data is an "entry"
data at 16 offset is _valuebuf_
if !( (type) & (0x0010) ) then
data is a "key"
data at 16 offset is _down_
if ( type & (0x0080) ) then
data was "deleted"
type & (0x20) (ROOTKEY) then rootkey?
type & (0x21) (ROOTKEYVERSION) then rootkey version?
Registry.dat file structure:
File header (row data)
<magic> 0x76644441L
<ver_major> 1
<ver_minor> 2
<avail> 128 // next available offset (128 bytes reserved)
<root> 0 // root object
empty data (row data)
<location> 0
<name> nil?
<namelen> nil?
<type> (1) // REGTYPE_KEY
<left> 0
<value> 0
<valuelen> 0
<parent> 0
Then a list of data entry which has the same basic structure:
name value
-----------------------------
/ following defined in modules/libreg/src/reg.h
/ ?? // root key
Users ??
Common ??
Version Registry ??
Private Arenas ??
///
Profiles
Version 1.0
HavePregInfo // what's preg info?
/begin profile data (can be out of order, I think):
[nothing?] <profile name>
migrated yes
// The directory from which this profile
migratedFrom // was migrated from (if any)
// Added in mozilla1.0.1
NCProfileName
NCServiceDenial
NCEmailAddress
NCHavePregInfo
// added in mozilla1.0.1
CreationTime // Values are in milliseconds since
LastModTime // midnight Jan 1, 1970 GMT
directory C:\...\Profiles\...\xxxxxxx.slt
/end profile data
CurrentProfile [profile name]
/begin profile data (if more than one profile)
/end profile data
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
http://lxr.mozilla.org/mozilla/source/profile/src/nsProfileAccess.cpp#285
86 #define kRegistryProfileSubtreeString (NS_LITERAL_STRING("Profiles"))
87 #define kRegistryCurrentProfileString (NS_LITERAL_STRING("CurrentProfile"))
88 #define kRegistryNCServiceDenialString (NS_LITERAL_STRING("NCServiceDenial"))
89 #define kRegistryNCProfileNameString (NS_LITERAL_STRING("NCProfileName"))
90 #define kRegistryNCUserEmailString (NS_LITERAL_STRING("NCEmailAddress"))
91 #define kRegistryNCHavePREGInfoString (NS_LITERAL_STRING("NCHavePregInfo"))
92 #define kRegistryHavePREGInfoString (NS_LITERAL_STRING("HavePregInfo"))
93 #define kRegistryMigratedString (NS_LITERAL_STRING("migrated"))
94 #define kRegistryDirectoryString (NS_LITERAL_STRING("directory"))
95 #define kRegistryNeedMigrationString (NS_LITERAL_STRING("NeedMigration"))
96 #define kRegistryMozRegDataMovedString (NS_LITERAL_STRING("OldRegDataMoved"))
97 #define kRegistryCreationTimeString (NS_LITERAL_CSTRING("CreationTime"))
98 #define kRegistryLastModTimeString (NS_LITERAL_CSTRING("LastModTime"))
99 #define kRegistryMigratedFromString (NS_LITERAL_CSTRING("MigFromDir"))
100 #define kRegistryVersionString (NS_LITERAL_STRING("Version"))
101 #define kRegistryVersion_1_0 (NS_LITERAL_STRING("1.0"))
102 #define kRegistryCurrentVersion (NS_LITERAL_STRING("1.0"))>
277 // Enumerates through the registry for profile
278 // information. Reads in the data into the array
279 // of profile structs. After this, all the callers
280 // requesting profile info will get thier data from
281 // profiles array. All the udates will be done to this
282 // data structure to reflect the latest status.
283 // Data will be flushed at the end.
284 nsresult
285 nsProfileAccess::FillProfileInfo(nsIFile* regName)
286 {
287 nsresult rv = NS_OK;
288
289 nsCOMPtr<nsIRegistry> registry(do_CreateInstance(NS_REGISTRY_CONTRACTID, &rv));
nsIRegistry implemented in <cvs:source/modules/libreg/xpcom/nsRegistry.cpp>
290 if (NS_FAILED(rv)) return rv;
291 rv = registry->Open(regName);
292 if (NS_FAILED(rv)) return rv;
293
294 // Enumerate all subkeys (immediately) under the given node.
295 nsCOMPtr<nsIEnumerator> enumKeys;
296 nsRegistryKey profilesTreeKey;
typedef PRUint32 nsRegistryKey;
<cvs:source/xpcom/components/nsIRegistry.idl>
297
298 rv = registry->GetKey(nsIRegistry::Common,
299 kRegistryProfileSubtreeString.get(),
NS_LITERAL_STRING("Profiles").get(),
300 &profilesTreeKey);
for what registry->GetKey does, see below
301
302 if (NS_FAILED(rv))
: blah
310
311 // introducing these tmp variables as nsString variables cannot be passed to
312 // the resgitry methods
313 nsXPIDLString tmpCurrentProfile;
314 nsXPIDLString tmpVersion;
315 nsXPIDLString tmpPREGInfo;
316
317
318 // For the following variables, we do not check for the rv value
319 // but check for the variable instead, because it is valid to proceed
320 // without the variables having a value. That's why there are no returns
321 // for invalid rv values.
322
323 // Get the current profile
324 rv = registry->GetString(profilesTreeKey,
325 kRegistryCurrentProfileString.get(),
326 getter_Copies(tmpCurrentProfile));
327
328 if (tmpCurrentProfile)
329 {
330 // If current profile does not exist, mCurrentProfile will not be set
331 // This is not harmful, as GetCurrentProfile method needs to return this value
332 // And GetCurrentProfile returns:
333 // the current profile if set
334 // the first profile if profiles exist but no current profile is set
335 // an empty string if no profiles exist.
336
337 mCurrentProfile = NS_STATIC_CAST(const PRUnichar*, tmpCurrentProfile);
338 }
339
340 // Get the profile version
341 rv = registry->GetString(profilesTreeKey,
342 kRegistryVersionString.get(),
343 getter_Copies(tmpVersion));
344
345 // Get the preg info
346 rv = registry->GetString(profilesTreeKey,
347 kRegistryHavePREGInfoString.get(),
348 getter_Copies(tmpPREGInfo));
349
350 if (tmpPREGInfo == nsnull)
351 {
352 mHavePREGInfo = kRegistryNoString;
353 mProfileDataChanged = PR_TRUE;
354 }
355
356 rv = registry->EnumerateSubtrees( profilesTreeKey, getter_AddRefs(enumKeys));
357 if (NS_FAILED(rv)) return rv;
358
359 rv = enumKeys->First();
360 if (NS_FAILED(rv)) return rv;
361
362 PRBool currentProfileValid = mCurrentProfile.IsEmpty();
363
364 while (NS_OK != enumKeys->IsDone())
365 {
366 nsCOMPtr<nsISupports> base;
367
368 rv = enumKeys->CurrentItem( getter_AddRefs(base) );
369 if (NS_FAILED(rv)) return rv;
370
371 // Get specific interface.
372 nsCOMPtr <nsIRegistryNode> node;
373 nsIID nodeIID = NS_IREGISTRYNODE_IID;
374
375 rv = base->QueryInterface( nodeIID, getter_AddRefs(node));
376 if (NS_FAILED(rv)) return rv;
377
378 // Get node name.
379 nsXPIDLString profile;
380 nsXPIDLString isMigrated;
381 nsXPIDLString NCProfileName;
382 nsXPIDLString NCDeniedService;
383 nsXPIDLString NCEmailAddress;
384 nsXPIDLString NCHavePregInfo;
385
386 rv = node->GetName(getter_Copies(profile));
387 if (NS_FAILED(rv)) return rv;
388
389 nsRegistryKey profKey;
390 rv = node->GetKey(&profKey);
391 if (NS_FAILED(rv)) return rv;
392
393 rv = registry->GetString(profKey,
394 kRegistryMigratedString.get(),
395 getter_Copies(isMigrated));
396 if (NS_FAILED(rv)) return rv;
397 nsDependentString isMigratedString(isMigrated);
398
399 // Not checking the return values of these variables as they
400 // are for activation, they are optional and their values
401 // do not call for a return
402 registry->GetString(profKey,
403 kRegistryNCProfileNameString.get(),
404 getter_Copies(NCProfileName));
405
406 registry->GetString(profKey,
407 kRegistryNCServiceDenialString.get(),
408 getter_Copies(NCDeniedService));
409
410 registry->GetString(profKey,
411 kRegistryNCUserEmailString.get(),
412 getter_Copies(NCEmailAddress));
413
414 registry->GetString(profKey,
415 kRegistryNCHavePREGInfoString.get(),
416 getter_Copies(NCHavePregInfo));
417
418 // Make sure that mCurrentProfile is valid
419 if (!mCurrentProfile.IsEmpty() && mCurrentProfile.Equals(profile))
420 currentProfileValid = PR_TRUE;
421
422 ProfileStruct* profileItem = new ProfileStruct();
423 if (!profileItem)
424 return NS_ERROR_OUT_OF_MEMORY;
425
426 profileItem->updateProfileEntry = PR_TRUE;
427 profileItem->profileName = NS_STATIC_CAST(const PRUnichar*, profile);
428
429 PRInt64 tmpLongLong;
430 rv = registry->GetLongLong(profKey,
431 kRegistryCreationTimeString.get(),
432 &tmpLongLong);
433 if (NS_SUCCEEDED(rv))
434 profileItem->creationTime = tmpLongLong;
435
436 rv = registry->GetLongLong(profKey,
437 kRegistryLastModTimeString.get(),
438 &tmpLongLong);
439 if (NS_SUCCEEDED(rv))
440 profileItem->lastModTime = tmpLongLong;
441
442 rv = profileItem->InternalizeLocation(registry, profKey, PR_FALSE);
443 NS_ASSERTION(NS_SUCCEEDED(rv), "Internalizing profile location failed");
444 // Not checking the error since most won't have this info
445 profileItem->InternalizeMigratedFromLocation(registry, profKey);
446
447 profileItem->isMigrated = isMigratedString.Equals(kRegistryYesString);
448
449 if (NCProfileName)
450 profileItem->NCProfileName = NS_STATIC_CAST(const PRUnichar*, NCProfileName);
451
452 if (NCDeniedService)
453 profileItem->NCDeniedService = NS_STATIC_CAST(const PRUnichar*, NCDeniedService);
454
455 if (NCEmailAddress)
456 profileItem->NCEmailAddress = NS_STATIC_CAST(const PRUnichar*, NCEmailAddress);
457
458 if (NCHavePregInfo)
459 profileItem->NCHavePregInfo = NS_STATIC_CAST(const PRUnichar*, NCHavePregInfo);
460
461 profileItem->isImportType = PR_FALSE;
462 if (!mProfiles) {
463 mProfiles = new nsVoidArray();
464
465 if (!mProfiles) {
466 delete profileItem;
467 return NS_ERROR_OUT_OF_MEMORY;
468 }
469 }
470
471 mProfiles->AppendElement((void*)profileItem);
472
473 rv = enumKeys->Next();
474 if (NS_FAILED(rv)) return rv;
475 }
476
477 if (!currentProfileValid)
478 mCurrentProfile.SetLength(0);
479
480 return rv;
481 }
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
http://lxr.mozilla.org/mozilla/source/modules/libreg/xpcom/nsRegistry.cpp
641 /*--------------------------- nsRegistry::GetKey -------------------------------
642 | returns the nsRegistryKey associated with a given node in the registry |
643 ------------------------------------------------------------------------------*/
644 NS_IMETHODIMP nsRegistry::GetKey(nsRegistryKey baseKey, const PRUnichar *keyname, nsRegistryKey *_retval)
645 {
646 if ( !keyname || !_retval )
647 return NS_ERROR_NULL_POINTER;
648
649 return GetSubtree( baseKey, NS_ConvertUCS2toUTF8(keyname).get(), _retval );
650 }
1171 /*-------------------------- nsRegistry::GetSubtree ----------------------------
1172 | Returns a nsRegistryKey(RKEY) for a given key/path. The key is |
1173 | obtained using NR_RegGetKey. |
1174 ------------------------------------------------------------------------------*/
1175 NS_IMETHODIMP nsRegistry::GetSubtree( nsRegistryKey baseKey, const char *path, nsRegistryKey *result ) {
1176 nsresult rv = NS_OK;
1177 REGERR err = REGERR_OK;
1178 // Make sure we have a place for the result.
1179 if( result ) {
1180 // Get key.
1181 PR_Lock(mregLock);
1182 err = NR_RegGetKey( mReg,(RKEY)baseKey,(char*)path,(RKEY*)result );
NR_RegGetKey finds the data entry and gets the data structure (path == name)
1183 PR_Unlock(mregLock);
1184 // Convert result.
1185 rv = regerr2nsresult( err );
1186 } else {
1187 rv = NS_ERROR_NULL_POINTER;
1188 }
1189 return rv;
1190 }
1191