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

Reply via email to