Index: /LICENSE
===================================================================
--- /LICENSE	(revision 4)
+++ /LICENSE	(revision 4)
@@ -0,0 +1,284 @@
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+                       59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+
+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
Index: /doc/winntreg.txt
===================================================================
--- /doc/winntreg.txt	(revision 4)
+++ /doc/winntreg.txt	(revision 4)
@@ -0,0 +1,268 @@
+The windows NT registry has 2 different blocks, where one can occur many
+times...
+
+the "regf"-Block
+================
+ 
+"regf" is obviosly the abbreviation for "Registry file". "regf" is the
+signature of the header-block which is always 4kb in size, although only
+the first 64 bytes seem to be used and a checksum is calculated over
+the first 0x200 bytes only!
+
+Offset            Size      Contents
+0x00000000      D-Word      ID: ASCII-"regf" = 0x66676572
+0x00000004      D-Word      ???? //see struct REGF
+0x00000008      D-Word      ???? Always the same value as at 0x00000004
+0x0000000C      Q-Word      last modify date in WinNT date-format
+0x00000014      D-Word      1
+0x00000018      D-Word      3
+0x0000001C      D-Word      0
+0x00000020      D-Word      1
+0x00000024      D-Word      Offset of 1st key record
+0x00000028      D-Word      Size of the data-blocks (Filesize-4kb)
+0x0000002C      D-Word      1
+0x000001FC      D-Word      Sum of all D-Words from 0x00000000 to
+0x000001FB  //XOR of all words. Nigel
+
+I have analyzed more registry files (from multiple machines running
+NT 4.0 german version) and could not find an explanation for the values
+marked with ???? the rest of the first 4kb page is not important...
+
+the "hbin"-Block
+================
+I dont know what "hbin" stands for, but this block is always a multiple
+of 4kb in size.
+
+Inside these hbin-blocks the different records are placed. The memory-
+management looks like a C-compiler heap management to me...
+
+hbin-Header
+===========
+Offset      Size      Contents
+0x0000      D-Word      ID: ASCII-"hbin" = 0x6E696268
+0x0004      D-Word      Offset from the 1st hbin-Block
+0x0008      D-Word      Offset to the next hbin-Block
+0x001C      D-Word      Block-size
+
+The values in 0x0008 and 0x001C should be the same, so I dont know
+if they are correct or swapped...
+
+From offset 0x0020 inside a hbin-block data is stored with the following
+format:
+
+Offset      Size      Contents
+0x0000      D-Word      Data-block size    //this size must be a
+multiple of 8. Nigel
+0x0004      ????      Data
+ 
+If the size field is negative (bit 31 set), the corresponding block
+is free and has a size of -blocksize!
+
+That does not seem to be true. All block lengths seem to be negative! 
+(Richard Sharpe) 
+
+The data is stored as one record per block. Block size is a multiple
+of 4 and the last block reaches the next hbin-block, leaving no room.
+
+(That also seems incorrect, in that the block size if a multiple of 8.
+That is, the block, including the 4 byte header, is always a multiple of
+8 bytes. Richard Sharpe.)
+
+Records in the hbin-blocks
+==========================
+
+nk-Record
+
+      The nk-record can be treated as a kombination of tree-record and
+      key-record of the win 95 registry.
+
+lf-Record
+
+      The lf-record is the counterpart to the RGKN-record (the
+      hash-function)
+
+vk-Record
+
+      The vk-record consists information to a single value.
+
+sk-Record
+
+      sk (? Security Key ?) is the ACL of the registry.
+
+Value-Lists
+
+      The value-lists contain information about which values are inside a
+      sub-key and dont have a header.
+
+Datas
+
+      The datas of the registry are (like the value-list) stored without a
+      header.
+
+All offset-values are relative to the first hbin-block and point to the
+block-size field of the record-entry. to get the file offset, you have to add
+the header size (4kb) and the size field (4 bytes)...
+
+the nk-Record
+=============
+Offset      Size      Contents
+0x0000      Word      ID: ASCII-"nk" = 0x6B6E
+0x0002      Word      for the root-key: 0x2C, otherwise 0x20  //key symbolic links 0x10. Nigel
+0x0004      Q-Word      write-date/time in windows nt notation
+0x0010      D-Word      Offset of Owner/Parent key
+0x0014      D-Word      number of sub-Keys
+0x001C      D-Word      Offset of the sub-key lf-Records
+0x0024      D-Word      number of values
+0x0028      D-Word      Offset of the Value-List
+0x002C      D-Word      Offset of the sk-Record
+
+0x0030      D-Word      Offset of the Class-Name //see NK structure for the use of these fields. Nigel
+0x0044      D-Word      Unused (data-trash)  //some kind of run time index. Does not appear to be important. Nigel
+0x0048      Word      name-length
+0x004A      Word      class-name length
+0x004C      ????      key-name
+
+the Value-List
+==============
+Offset      Size      Contents
+0x0000      D-Word      Offset 1st Value
+0x0004      D-Word      Offset 2nd Value
+0x????      D-Word      Offset nth Value
+
+To determine the number of values, you have to look at the owner-nk-record!
+
+Der vk-Record
+=============
+Offset      Size      Contents
+0x0000      Word      ID: ASCII-"vk" = 0x6B76
+0x0002      Word      name length
+0x0004      D-Word      length of the data   //if top bit is set when offset contains data. Nigel
+0x0008      D-Word      Offset of Data
+0x000C      D-Word      Type of value
+0x0010      Word      Flag
+0x0012      Word      Unused (data-trash)
+0x0014      ????      Name
+
+If bit 0 of the flag-word is set, a name is present, otherwise the value has no name (=default)
+
+If the data-size is lower 5, the data-offset value is used to store the data itself!
+
+The data-types
+==============
+Wert      Beteutung
+0x0001      RegSZ:             character string (in UNICODE!)
+0x0002      ExpandSZ:   string with "%var%" expanding (UNICODE!)
+0x0003      RegBin:           raw-binary value
+0x0004      RegDWord:   Dword
+0x0007      RegMultiSZ:      multiple strings, seperated with 0
+                  (UNICODE!)
+
+The "lf"-record
+===============
+Offset      Size      Contents
+0x0000      Word      ID: ASCII-"lf" = 0x666C
+0x0002      Word      number of keys
+0x0004      ????      Hash-Records
+
+Hash-Record
+===========
+Offset      Size      Contents
+0x0000      D-Word      Offset of corresponding "nk"-Record
+0x0004      D-Word      ASCII: the first 4 characters of the key-name, padded with 0-s. Case sensitiv!
+
+Keep in mind, that the value at 0x0004 is used for checking the data-consistency! If you change the 
+key-name you have to change the hash-value too!
+
+//These hashrecords must be sorted low to high within the lf record. Nigel.
+
+The "sk"-block
+==============
+(due to the complexity of the SAM-info, not clear jet)
+(This is just a self-relative security descriptor in the data. R Sharpe.) 
+
+
+Offset      Size      Contents
+0x0000      Word      ID: ASCII-"sk" = 0x6B73
+0x0002      Word      Unused
+0x0004      D-Word      Offset of previous "sk"-Record
+0x0008      D-Word      Offset of next "sk"-Record
+0x000C      D-Word      usage-counter
+0x0010      D-Word      Size of "sk"-record in bytes
+????                                             //standard self
+relative security desciptor. Nigel
+????  ????      Security and auditing settings...
+????
+
+The usage counter counts the number of references to this
+"sk"-record. You can use one "sk"-record for the entire registry!
+
+Windows nt date/time format
+===========================
+The time-format is a 64-bit integer which is incremented every
+0,0000001 seconds by 1 (I dont know how accurate it really is!)
+It starts with 0 at the 1st of january 1601 0:00! All values are
+stored in GMT time! The time-zone is important to get the real
+time!
+
+Common values for win95 and win-nt
+==================================
+Offset values marking an "end of list", are either 0 or -1 (0xFFFFFFFF).
+If a value has no name (length=0, flag(bit 0)=0), it is treated as the
+"Default" entry...
+If a value has no data (length=0), it is displayed as empty.
+
+simplyfied win-3.?? registry:
+=============================
+
++-----------+
+| next rec. |---+                      +----->+------------+
+| first sub |   |                      |      | Usage cnt. |
+| name      |   |  +-->+------------+  |      | length     |
+| value     |   |  |   | next rec.  |  |      | text       |------->+-------+
++-----------+   |  |   | name rec.  |--+      +------------+        | xxxxx |
+   +------------+  |   | value rec. |-------->+------------+        +-------+
+   v               |   +------------+         | Usage cnt. |
++-----------+      |                          | length     |
+| next rec. |      |                          | text       |------->+-------+
+| first sub |------+                          +------------+        | xxxxx |
+| name      |                                                       +-------+
+| value     |
++-----------+    
+
+Greatly simplyfied structure of the nt-registry:
+================================================
+   
++---------------------------------------------------------------+
+|                                                               |
+v                                                               |
++---------+     +---------->+-----------+  +----->+---------+   |
+| "nk"    |     |           | lf-rec.   |  |      | nk-rec. |   |
+| ID      |     |           | # of keys |  |      | parent  |---+
+| Date    |     |           | 1st key   |--+      | ....    |
+| parent  |     |           +-----------+         +---------+
+| suk-keys|-----+
+| values  |--------------------->+----------+
+| SK-rec. |---------------+      | 1. value |--> +----------+
+| class   |--+            |      +----------+    | vk-rec.  |
++---------+  |            |                      | ....     |
+             v            |                      | data     |--> +-------+
+      +------------+      |                      +----------+    | xxxxx |
+      | Class name |      |                                      +-------+
+      +------------+      |
+                          v
+          +---------+    +---------+
+   +----->| next sk |--->| Next sk |--+
+   |  +---| prev sk |<---| prev sk |  |
+   |  |   | ....    |    | ...     |  |
+   |  |   +---------+    +---------+  |
+   |  |                    ^          |
+   |  |                    |          |
+   |  +--------------------+          |
+   +----------------------------------+
+
+---------------------------------------------------------------------------
+
+Hope this helps....  (Although it was *fun* for me to uncover this things,
+                  it took me several sleepless nights ;)
+
+            B.D.
Index: /src/reglookup.c
===================================================================
--- /src/reglookup.c	(revision 3)
+++ /src/reglookup.c	(revision 4)
@@ -1,4 +1,6 @@
 /*
- * $Id: $
+ * $Id$
+ *
+ * A utility to edit a Windows NT/2K etc registry file.
  *
  * This code was taken from Richard Sharpe''s editreg utility, in the 
@@ -11,6 +13,5 @@
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * the Free Software Foundation; version 2 of the License.
  * 
  * This program is distributed in the hope that it will be useful,
@@ -25,288 +26,18 @@
  
 /*************************************************************************
-                                                    
- A utility to edit a Windows NT/2K etc registry file.
-                                     
- Many of the ideas in here come from other people and software. 
- I first looked in Wine in misc/registry.c and was also influenced by
- http://www.wednesday.demon.co.uk/dosreg.html
-
- Which seems to contain comments from someone else. I reproduce them here
- incase the site above disappears. It actually comes from 
- http://home.eunet.no/~pnordahl/ntpasswd/WinReg.txt. 
-
- The goal here is to read the registry into memory, manipulate it, and then
- write it out if it was changed by any actions of the user.
-
-The windows NT registry has 2 different blocks, where one can occur many
-times...
-
-the "regf"-Block
-================
+
+ A note from Richard Sharpe:
+  Many of the ideas in here come from other people and software. 
+  I first looked in Wine in misc/registry.c and was also influenced by
+  http://www.wednesday.demon.co.uk/dosreg.html
+
+  Which seems to contain comments from someone else. I reproduce them here
+  incase the site above disappears. It actually comes from 
+  http://home.eunet.no/~pnordahl/ntpasswd/WinReg.txt. 
  
-"regf" is obviosly the abbreviation for "Registry file". "regf" is the
-signature of the header-block which is always 4kb in size, although only
-the first 64 bytes seem to be used and a checksum is calculated over
-the first 0x200 bytes only!
-
-Offset            Size      Contents
-0x00000000      D-Word      ID: ASCII-"regf" = 0x66676572
-0x00000004      D-Word      ???? //see struct REGF
-0x00000008      D-Word      ???? Always the same value as at 0x00000004
-0x0000000C      Q-Word      last modify date in WinNT date-format
-0x00000014      D-Word      1
-0x00000018      D-Word      3
-0x0000001C      D-Word      0
-0x00000020      D-Word      1
-0x00000024      D-Word      Offset of 1st key record
-0x00000028      D-Word      Size of the data-blocks (Filesize-4kb)
-0x0000002C      D-Word      1
-0x000001FC      D-Word      Sum of all D-Words from 0x00000000 to
-0x000001FB  //XOR of all words. Nigel
-
-I have analyzed more registry files (from multiple machines running
-NT 4.0 german version) and could not find an explanation for the values
-marked with ???? the rest of the first 4kb page is not important...
-
-the "hbin"-Block
-================
-I dont know what "hbin" stands for, but this block is always a multiple
-of 4kb in size.
-
-Inside these hbin-blocks the different records are placed. The memory-
-management looks like a C-compiler heap management to me...
-
-hbin-Header
-===========
-Offset      Size      Contents
-0x0000      D-Word      ID: ASCII-"hbin" = 0x6E696268
-0x0004      D-Word      Offset from the 1st hbin-Block
-0x0008      D-Word      Offset to the next hbin-Block
-0x001C      D-Word      Block-size
-
-The values in 0x0008 and 0x001C should be the same, so I dont know
-if they are correct or swapped...
-
-From offset 0x0020 inside a hbin-block data is stored with the following
-format:
-
-Offset      Size      Contents
-0x0000      D-Word      Data-block size    //this size must be a
-multiple of 8. Nigel
-0x0004      ????      Data
- 
-If the size field is negative (bit 31 set), the corresponding block
-is free and has a size of -blocksize!
-
-That does not seem to be true. All block lengths seem to be negative! 
-(Richard Sharpe) 
-
-The data is stored as one record per block. Block size is a multiple
-of 4 and the last block reaches the next hbin-block, leaving no room.
-
-(That also seems incorrect, in that the block size if a multiple of 8.
-That is, the block, including the 4 byte header, is always a multiple of
-8 bytes. Richard Sharpe.)
-
-Records in the hbin-blocks
-==========================
-
-nk-Record
-
-      The nk-record can be treated as a kombination of tree-record and
-      key-record of the win 95 registry.
-
-lf-Record
-
-      The lf-record is the counterpart to the RGKN-record (the
-      hash-function)
-
-vk-Record
-
-      The vk-record consists information to a single value.
-
-sk-Record
-
-      sk (? Security Key ?) is the ACL of the registry.
-
-Value-Lists
-
-      The value-lists contain information about which values are inside a
-      sub-key and dont have a header.
-
-Datas
-
-      The datas of the registry are (like the value-list) stored without a
-      header.
-
-All offset-values are relative to the first hbin-block and point to the
-block-size field of the record-entry. to get the file offset, you have to add
-the header size (4kb) and the size field (4 bytes)...
-
-the nk-Record
-=============
-Offset      Size      Contents
-0x0000      Word      ID: ASCII-"nk" = 0x6B6E
-0x0002      Word      for the root-key: 0x2C, otherwise 0x20  //key symbolic links 0x10. Nigel
-0x0004      Q-Word      write-date/time in windows nt notation
-0x0010      D-Word      Offset of Owner/Parent key
-0x0014      D-Word      number of sub-Keys
-0x001C      D-Word      Offset of the sub-key lf-Records
-0x0024      D-Word      number of values
-0x0028      D-Word      Offset of the Value-List
-0x002C      D-Word      Offset of the sk-Record
-
-0x0030      D-Word      Offset of the Class-Name //see NK structure for the use of these fields. Nigel
-0x0044      D-Word      Unused (data-trash)  //some kind of run time index. Does not appear to be important. Nigel
-0x0048      Word      name-length
-0x004A      Word      class-name length
-0x004C      ????      key-name
-
-the Value-List
-==============
-Offset      Size      Contents
-0x0000      D-Word      Offset 1st Value
-0x0004      D-Word      Offset 2nd Value
-0x????      D-Word      Offset nth Value
-
-To determine the number of values, you have to look at the owner-nk-record!
-
-Der vk-Record
-=============
-Offset      Size      Contents
-0x0000      Word      ID: ASCII-"vk" = 0x6B76
-0x0002      Word      name length
-0x0004      D-Word      length of the data   //if top bit is set when offset contains data. Nigel
-0x0008      D-Word      Offset of Data
-0x000C      D-Word      Type of value
-0x0010      Word      Flag
-0x0012      Word      Unused (data-trash)
-0x0014      ????      Name
-
-If bit 0 of the flag-word is set, a name is present, otherwise the value has no name (=default)
-
-If the data-size is lower 5, the data-offset value is used to store the data itself!
-
-The data-types
-==============
-Wert      Beteutung
-0x0001      RegSZ:             character string (in UNICODE!)
-0x0002      ExpandSZ:   string with "%var%" expanding (UNICODE!)
-0x0003      RegBin:           raw-binary value
-0x0004      RegDWord:   Dword
-0x0007      RegMultiSZ:      multiple strings, seperated with 0
-                  (UNICODE!)
-
-The "lf"-record
-===============
-Offset      Size      Contents
-0x0000      Word      ID: ASCII-"lf" = 0x666C
-0x0002      Word      number of keys
-0x0004      ????      Hash-Records
-
-Hash-Record
-===========
-Offset      Size      Contents
-0x0000      D-Word      Offset of corresponding "nk"-Record
-0x0004      D-Word      ASCII: the first 4 characters of the key-name, padded with 0-s. Case sensitiv!
-
-Keep in mind, that the value at 0x0004 is used for checking the data-consistency! If you change the 
-key-name you have to change the hash-value too!
-
-//These hashrecords must be sorted low to high within the lf record. Nigel.
-
-The "sk"-block
-==============
-(due to the complexity of the SAM-info, not clear jet)
-(This is just a self-relative security descriptor in the data. R Sharpe.) 
-
-
-Offset      Size      Contents
-0x0000      Word      ID: ASCII-"sk" = 0x6B73
-0x0002      Word      Unused
-0x0004      D-Word      Offset of previous "sk"-Record
-0x0008      D-Word      Offset of next "sk"-Record
-0x000C      D-Word      usage-counter
-0x0010      D-Word      Size of "sk"-record in bytes
-????                                             //standard self
-relative security desciptor. Nigel
-????  ????      Security and auditing settings...
-????
-
-The usage counter counts the number of references to this
-"sk"-record. You can use one "sk"-record for the entire registry!
-
-Windows nt date/time format
-===========================
-The time-format is a 64-bit integer which is incremented every
-0,0000001 seconds by 1 (I dont know how accurate it really is!)
-It starts with 0 at the 1st of january 1601 0:00! All values are
-stored in GMT time! The time-zone is important to get the real
-time!
-
-Common values for win95 and win-nt
-==================================
-Offset values marking an "end of list", are either 0 or -1 (0xFFFFFFFF).
-If a value has no name (length=0, flag(bit 0)=0), it is treated as the
-"Default" entry...
-If a value has no data (length=0), it is displayed as empty.
-
-simplyfied win-3.?? registry:
-=============================
-
-+-----------+
-| next rec. |---+                      +----->+------------+
-| first sub |   |                      |      | Usage cnt. |
-| name      |   |  +-->+------------+  |      | length     |
-| value     |   |  |   | next rec.  |  |      | text       |------->+-------+
-+-----------+   |  |   | name rec.  |--+      +------------+        | xxxxx |
-   +------------+  |   | value rec. |-------->+------------+        +-------+
-   v               |   +------------+         | Usage cnt. |
-+-----------+      |                          | length     |
-| next rec. |      |                          | text       |------->+-------+
-| first sub |------+                          +------------+        | xxxxx |
-| name      |                                                       +-------+
-| value     |
-+-----------+    
-
-Greatly simplyfied structure of the nt-registry:
-================================================
-   
-+---------------------------------------------------------------+
-|                                                               |
-v                                                               |
-+---------+     +---------->+-----------+  +----->+---------+   |
-| "nk"    |     |           | lf-rec.   |  |      | nk-rec. |   |
-| ID      |     |           | # of keys |  |      | parent  |---+
-| Date    |     |           | 1st key   |--+      | ....    |
-| parent  |     |           +-----------+         +---------+
-| suk-keys|-----+
-| values  |--------------------->+----------+
-| SK-rec. |---------------+      | 1. value |--> +----------+
-| class   |--+            |      +----------+    | vk-rec.  |
-+---------+  |            |                      | ....     |
-             v            |                      | data     |--> +-------+
-      +------------+      |                      +----------+    | xxxxx |
-      | Class name |      |                                      +-------+
-      +------------+      |
-                          v
-          +---------+    +---------+
-   +----->| next sk |--->| Next sk |--+
-   |  +---| prev sk |<---| prev sk |  |
-   |  |   | ....    |    | ...     |  |
-   |  |   +---------+    +---------+  |
-   |  |                    ^          |
-   |  |                    |          |
-   |  +--------------------+          |
-   +----------------------------------+
-
----------------------------------------------------------------------------
-
-Hope this helps....  (Although it was *fun* for me to uncover this things,
-                  it took me several sleepless nights ;)
-
-            B.D.
-
-*************************************************************************/
+ NOTE: the comments he refers to have been moved to doc/winntreg.txt
+
+**************************************************************************/
+
 
 #include <stdio.h>
@@ -1154,6 +885,8 @@
   unsigned short num_nulls;
   unsigned char* ascii;
-  unsigned int ascii_max;
-  int str_rem;
+  unsigned char* cur_str;
+  unsigned int cur_str_len;
+  unsigned int ascii_max, cur_str_max;
+  unsigned int str_rem, cur_str_rem, alen;
 
   switch (type) 
@@ -1216,4 +949,6 @@
   case REG_TYPE_MULTISZ:
     ascii_max = sizeof(char)*len*4;
+    cur_str_max = sizeof(char)*len+1;
+    cur_str = malloc(cur_str_max);
     ascii = malloc(ascii_max+4);
     if(ascii == NULL)
@@ -1228,15 +963,41 @@
     num_nulls = 0;
     str_rem = ascii_max;
-    for(i=0; (i < len) && (num_nulls < 4) && str_rem > 0; i++)
+    cur_str_rem = cur_str_max;
+    cur_str_len = 0;
+
+    *asciip = '"';
+    asciip +=1;
+    
+    for(i=0; (i < len) && str_rem > 0; i++)
     {
-      asciip += snprintf((char*)asciip, str_rem, "%02x ", 
-			 *(unsigned char *)(datap+i));
-      str_rem -= 3;
-      if(*(datap+i) == 0)
+      *(cur_str+cur_str_len) = *(datap+i);
+      if(*(cur_str+cur_str_len) == 0)
 	num_nulls++;
       else
 	num_nulls = 0;
-    }
-    *asciip = '\0';
+      cur_str_len++;
+
+      if(num_nulls == 2)
+      {
+	uni_to_ascii(cur_str, asciip, str_rem, 0);
+	alen = strlen((char*)asciip);
+	asciip += alen;
+	str_rem -= alen;
+	if(*(datap+i+1) == 0 && *(datap+i+2) == 0)
+	  break;
+	else
+	{
+	  alen = snprintf((char*)asciip, str_rem, "%s", "\" \"");
+	  asciip += alen;
+	  str_rem -= alen;
+	  memset(cur_str, 0, cur_str_max);
+	  cur_str_len = 0;
+	  num_nulls = 0;
+	  /* To eliminate leading nulls in subsequent strings. */
+	  i++;
+	}
+      }
+    }
+    snprintf((char*)asciip, str_rem, "%s", "\"");
     return ascii;
     break;
@@ -2311,5 +2072,4 @@
   fprintf(stderr, "\n\t-v\t sets verbose mode");
   fprintf(stderr, "\n\t-f\t a simple prefix filter.");
-  fprintf(stderr, "\n\t-p\t prints the registry");
   fprintf(stderr, "\n\t-s\t prints security descriptors");
   fprintf(stderr, "\n");
@@ -2408,10 +2168,4 @@
   nt_key_iterator(regf, regf->root, 0, "", filter_prefix);
 
-  /* XXX: debugging; remove me. */
-  printf("%d,%d,%d\n", 
-	 str_is_prefix("foo", "foobar"),
-	 str_is_prefix("", "xyz"),
-	 str_is_prefix("foo", "foo"));
-
   return 0;
 }
