Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

RFE: Documentation !

49 views
Skip to first unread message

Rob Stow

unread,
Dec 1, 2002, 11:38:46 AM12/1/02
to
I just spent two hours trying to find something that gives
the file structure of registry.dat. This is not the first
time I have wasted hours trying to find something in the
Mozilla source code because the documentation is virtally
non-existent.

--
rob.stow is my name
sk.sympatico.ca provides me with this e-mail account
If you can't figure it out from there ask Mommy for help.
-------------------------------------------------------------
Mail from the the following spam hosts are deleted by my filters:
hotmail.com, ziplip.com, excite.com, bellsouth.net, yahoo.com,
earthlink.com

Daniel Wang

unread,
Dec 2, 2002, 1:27:01 AM12/2/02
to
Rob Stow wrote:
> I just spent two hours trying to find something that gives
> the file structure of registry.dat. This is not the first
> time I have wasted hours trying to find something in the
> Mozilla source code because the documentation is virtally
> non-existent.

Time to get n.p.m.documenation rolling?

mozilla.org is currently in need of contributors to help maintain its
documentation and to write new ones. You do not have to be a software
engineer to write documentation. You could write on anything you deem
relevent to mozilla.org nd Mozilla; your topic could be Mozilla
evangelism, browser troubleshooting (bank issues, anyone?), end user
manual, the Mozilla developement, history, processes, audience, goals,
etc., Internet privacy, security, and legal issues, Web authoring for
Mozilla, FAQs, quality, etc. etc.

What else you can do:
* help translating existing documents
* dubug documents (find grammar/spelling errors, correct invalid links,
correct factual errors, remove outdated information, add new ones,
etc.)
* help coordinate documentation project (there's currently none and we
desparately need some commitment in that area)
* suggest topics that need to be covered

btw, anyone want to take over the wishlist FAQ? I'd like to spend my
time doing QA and other documentation instead.

Rob Stow

unread,
Dec 2, 2002, 2:28:10 AM12/2/02
to
Daniel Wang wrote:
> Rob Stow wrote:
>
>> I just spent two hours trying to find something that gives
>> the file structure of registry.dat. This is not the first
>> time I have wasted hours trying to find something in the
>> Mozilla source code because the documentation is virtally
>> non-existent.
>
> btw, anyone want to take over the wishlist FAQ? I'd like to spend my
> time doing QA and other documentation instead.
>

Ask me in 6 weeks or two months. Before I do that I want
make a half decent profile manager - hence my need for the
registry.dat file structure.

Assuming that I can figure out the file structure for
registry.dat, 6 to 8 weeks is about how long I think it
would take me to do this in my spare time. Actually,
with the lost time over the holiday season you'd better
make that 8 to 10 weeks.

Mike

unread,
Dec 2, 2002, 3:01:11 AM12/2/02
to
I could be intrested in a few of these areas you mentioned, can you give
more info on time lines ect. if you wish email me directly ok. and i
will also tell you about the areas of interest..

Garth Wallace

unread,
Dec 2, 2002, 3:17:06 AM12/2/02
to
Rob Stow wrote:
> Daniel Wang wrote:
>
>> Rob Stow wrote:
>>
>>> I just spent two hours trying to find something that gives
>>> the file structure of registry.dat. This is not the first
>>> time I have wasted hours trying to find something in the
>>> Mozilla source code because the documentation is virtally
>>> non-existent.
>>
>>
>> btw, anyone want to take over the wishlist FAQ? I'd like to spend my
>> time doing QA and other documentation instead.
>>
>
> Ask me in 6 weeks or two months. Before I do that I want
> make a half decent profile manager - hence my need for the
> registry.dat file structure.
>
> Assuming that I can figure out the file structure for
> registry.dat, 6 to 8 weeks is about how long I think it
> would take me to do this in my spare time. Actually,
> with the lost time over the holiday season you'd better
> make that 8 to 10 weeks.

And here we see exactly *why* the documentation is in such an incomplete
state.

--
Mozilla 1.0 Guide: http://www.mozilla.org/start/1.0/guide/
Mozilla 1.0 FAQ: http://www.mozilla.org/start/1.0/faq/

End-user discussion and peer support:
snews://secnews.netscape.com:563/netscape.mozilla.user.general
snews://secnews.netscape.com:563/netscape.mozilla.user.win32
snews://secnews.netscape.com:563/netscape.mozilla.user.mac
snews://secnews.netscape.com:563/netscape.mozilla.user.unix

Daniel Wang

unread,
Dec 2, 2002, 11:27:53 AM12/2/02
to
Rob Stow wrote:
> Daniel Wang wrote:
>
> Ask me in 6 weeks or two months. Before I do that I want
> make a half decent profile manager - hence my need for the
> registry.dat file structure.
>
> Assuming that I can figure out the file structure for
> registry.dat, 6 to 8 weeks is about how long I think it
> would take me to do this in my spare time. Actually,
> with the lost time over the holiday season you'd better
> make that 8 to 10 weeks.
>

http://lxr.mozilla.org/mozilla/source/profile/src/nsProfile.cpp ?
http://lxr.mozilla.org/mozilla/source/modules/libreg/xpcom/nsRegistry.cpp ?

Rob Stow

unread,
Dec 2, 2002, 1:02:40 PM12/2/02
to

Thanks, but I've already looked at those two files - and
many others - and neither gives the file structure of
registry.dat.


Daniel Wang

unread,
Dec 3, 2002, 12:26:58 AM12/3/02
to
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

Rob Stow

unread,
Dec 3, 2002, 1:34:09 AM12/3/02
to

These files have links to the files you cited below
in your next post. However, when I clicked on the
links I got "File does not exist" types of errors.

However, it looks like you've provided the details I
need. Thanks a million.


And in case anyone else cares, some of the reasons I want
to make my own profile manager ...
1.) You can't use Mozilla's profile manager while Moz is running.
Why should a sys admin have to interrupt his Mozilla session just
to create a profile for a new user ?
2.) You can't use Mozilla's profile manager to make profiles
without "salting" - which is a pain in the ass when you
trying to support Mozilla on a LAN.
3.) Backup tools are needed - any novice user should be able to
easily backup his mail or his entire profile.

Bugs have been filed on those and many other shortcomings of
Mozilla's profile manager. However, progress is non-existant
and I need something I can use *now*. That is probably the
only reason anything ever gets done with Mozilla: nothing
ever happens until someone finally decides they are sick of
waiting for those blasted Bugzilla "committees" to *do*
something instead of just arguing about it forever.

Daniel Wang

unread,
Dec 3, 2002, 3:10:27 AM12/3/02
to
Mike wrote:
> I could be intrested in a few of these areas you mentioned, can you give
> more info on time lines ect. if you wish email me directly ok. and i
> will also tell you about the areas of interest..
>

Currently there is no agenda or priority list for what should be done
and when. You are basically free to do whatever you want.

You can review the open documentation bugs to pick what you want to do:
http://bugzilla.mozilla.org/buglist.cgi?component=Miscellaneous&component=Mozilla+Developer&component=User&component=Web+Developer&component=webmaster%40mozilla.org&resolution=---
or just start a new one on your own. Be reminded that none of the
documentation contributors and mozilla.org staff has any idea about who
is doing what, so to avoid duplicate effort (which happens) you should
announce first what you are going to do.

mozilla.org is not as "open" as you might think, so getting things done
might be tricky. If you want to avoid the hassle of cvs, getting
attention from mozilla.org to your work, and the mozilla.org review
process, you could try Zope <http://moz.zope.org> which is easier to use
and much more open.

try the n.p.m.documentation for help on getting involved.

Christian Biesinger

unread,
Dec 3, 2002, 5:38:04 PM12/3/02
to
Rob Stow wrote:
> 1.) You can't use Mozilla's profile manager while Moz is running.

Well that is wrong.
On windows, you need to set the environment variable MOZ_NO_REMOTE to 1
and you can use profile manager.

On Unix/Linux, it works "out of the box".

No idea about Mac.

--
Fiat iustitia, pereat mundus.

Neil

unread,
Feb 6, 2003, 11:33:44 AM2/6/03
to
Daniel Wang wrote:

> What else you can do:
> * help translating existing documents
> * dubug documents (find grammar/spelling errors,

^^^^^
How is it that any post containing the word "spelling" has a spelling error?

--
Warning: May contain traces of nuts.

Neil

unread,
Feb 6, 2003, 11:31:30 AM2/6/03
to
Rob Stow wrote:

> And in case anyone else cares, some of the reasons I want
> to make my own profile manager ...
> 1.) You can't use Mozilla's profile manager while Moz is running.
> Why should a sys admin have to interrupt his Mozilla session just
> to create a profile for a new user ?

This is possible in recent nightlies - Tools -> Switch Profile -> Manage
Profiles

> 2.) You can't use Mozilla's profile manager to make profiles
> without "salting" - which is a pain in the ass when you
> trying to support Mozilla on a LAN.

Just create an empty prefs.js in for folder first. VoilĂ !

> 3.) Backup tools are needed - any novice user should be able to
> easily backup his mail or his entire profile.

Perhaps you could add this in to the existing profile manager?

0 new messages