Documentation
¶
Overview ¶
Package regis3 provides a high-fidelity toolkit for parsing, manipulating, and exporting Windows Registry (.REG) files.
Unlike standard registry libraries that wrap the Windows Registry API (RegOpenKeyEx, etc.), go-regis3 treats .REG files as structured text documents. It uses a character-at-a-time state machine parser to build an in-memory tree representation (KeyEntry) that can be manipulated, compared (diff/merge), and exported back to .REG or WiX XML formats.
Core Features:
- Supports both REGEDIT4 (ANSI) and Windows Registry Editor 5.00 (UTF-16LE) formats.
- High-fidelity internal storage using UTF-16LE to preserve exact byte sequences.
- Case-insensitive but case-preserving key and value handling.
- Advanced features like variable substitution ($$VAR$$ syntax) and WiX XML generation.
- Robust error reporting with line/column numbers and context snippets.
The library is designed for cross-platform use, allowing registry files to be processed on non-Windows systems (e.g., for installer generation or snapshot analysis).
Index ¶
- Constants
- func EscapeString(input string) string
- func Is64BitOperatingSystem() bool
- func Is64BitProcess() bool
- func IsStringType(kind uint32) bool
- type ExportOptions
- type KeyEntry
- func (k *KeyEntry) AskToAddKey(addThis *KeyEntry) *KeyEntry
- func (k *KeyEntry) AskToAddValue(key *KeyEntry, val *ValueEntry)
- func (k *KeyEntry) AskToRemoveKey(removeThis *KeyEntry) *KeyEntry
- func (k *KeyEntry) AskToRemoveValue(key *KeyEntry, val *ValueEntry)
- func (k *KeyEntry) Clone(newParent *KeyEntry) *KeyEntry
- func (k *KeyEntry) DefaultValue() *ValueEntry
- func (k *KeyEntry) FindKey(path string) *KeyEntry
- func (k *KeyEntry) FindOrCreateKey(path string) *KeyEntry
- func (k *KeyEntry) FindOrCreateValue(name string) *ValueEntry
- func (k *KeyEntry) GetPath() string
- func (k *KeyEntry) Name() string
- func (k *KeyEntry) Parent() *KeyEntry
- func (k *KeyEntry) RemoveFlag() bool
- func (k *KeyEntry) SetParent(parent *KeyEntry)
- func (k *KeyEntry) SetRemoveFlag(flag bool)
- func (k *KeyEntry) SubKeys() map[string]*KeyEntry
- func (k *KeyEntry) Values() map[string]*ValueEntry
- type ParseError
- type ParseOptions
- type ParserContext
- func (p *ParserContext) BufferAppend(r rune)
- func (p *ParserContext) BufferAsString() string
- func (p *ParserContext) BufferClear()
- func (p *ParserContext) FormatError(err error) error
- func (p *ParserContext) LastState() ParserState
- func (p *ParserContext) ParseText(text string, initialState ParserState) error
- type ParserState
- type RegParser
- type RegWriter
- type ValueEntry
- func (v *ValueEntry) Data() []byte
- func (v *ValueEntry) GetDword(defaultValue uint32) uint32
- func (v *ValueEntry) GetMultiString() []string
- func (v *ValueEntry) GetQword(defaultValue uint64) uint64
- func (v *ValueEntry) GetString(defaultValue string) string
- func (v *ValueEntry) IsDefaultValue() bool
- func (v *ValueEntry) Kind() uint32
- func (v *ValueEntry) Name() string
- func (v *ValueEntry) RemoveFlag() bool
- func (v *ValueEntry) SetBinaryType(kind uint32, data []byte)
- func (v *ValueEntry) SetDword(val uint32)
- func (v *ValueEntry) SetEscapedDwordValue(variableRef string)
- func (v *ValueEntry) SetEscapedQwordValue(variableRef string)
- func (v *ValueEntry) SetExpandString(val string)
- func (v *ValueEntry) SetMultiString(stringsList []string)
- func (v *ValueEntry) SetNone()
- func (v *ValueEntry) SetQword(val uint64)
- func (v *ValueEntry) SetRemoveFlag(flag bool)
- func (v *ValueEntry) SetString(val string)
- type WixWriter
Constants ¶
const ( HeaderRegedit4 = "REGEDIT4" HeaderWindows5 = "Windows Registry Editor Version 5.00" )
const ( RegNone = 0 RegSz = 1 RegExpandSz = 2 RegBinary = 3 RegDword = 4 RegDwordLittleEndian = 4 RegDwordBigEndian = 5 RegLink = 6 RegMultiSz = 7 RegResourceList = 8 RegFullResourceDescriptor = 9 RegResourceRequirementsList = 10 RegQword = 11 RegQwordLittleEndian = 11 )
Registry Value Types These constants match the standard Windows API values found in winnt.h
const ( // RegTypeUnknown is a sentinel value indicating unknown/uninitialized registry value type. RegTypeUnknown = 0xFFFFFFFF // -1 // RegEscapedDword is a marker for escaped DWORD variables ($$VAR$$ syntax in .REG files). // The actual value is stored as a string to be expanded at write time. RegEscapedDword = 0xFFFFFFFE // -2 // RegEscapedQword is a marker for escaped QWORD variables ($$VAR$$ syntax in .REG files). RegEscapedQword = 0xFFFFFFFD // -3 )
pnq-specific Constants
Variables ¶
This section is empty.
Functions ¶
func EscapeString ¶
EscapeString escapes backslashes and double quotes for .REG files.
func Is64BitOperatingSystem ¶
func Is64BitOperatingSystem() bool
Is64BitOperatingSystem checks if the OS is 64-bit. On non-Windows platforms, we determine this based on the architecture.
func Is64BitProcess ¶
func Is64BitProcess() bool
Is64BitProcess checks if the current process is 64-bit.
func IsStringType ¶
IsStringType checks if a registry value type is a string type (REG_SZ or REG_EXPAND_SZ).
Types ¶
type ExportOptions ¶
type ExportOptions struct {
// NoEmptyKeys skips keys that have no values when exporting.
NoEmptyKeys bool
}
ExportOptions configures the behavior of the .REG file exporter.
type KeyEntry ¶
type KeyEntry struct {
// contains filtered or unexported fields
}
KeyEntry represents a registry key tree node. Keys and values are stored case-insensitively (lowercase keys).
func NewKeyEntry ¶
NewKeyEntry creates a new named key with a parent. Pass nil for parent to create a root key.
func Parse ¶
func Parse(content string, options *ParseOptions) (*KeyEntry, error)
Parse parses a .REG file content string. It automatically detects the header (REGEDIT4 or Windows Registry Editor Version 5.00). Pass nil for options to use defaults, or provide a ParseOptions struct.
func ParseFile ¶
func ParseFile(filename string, options *ParseOptions) (*KeyEntry, error)
ParseFile reads and parses a .REG file. It handles UTF-16LE to UTF-8 conversion if necessary. Pass nil for options to use defaults, or provide a ParseOptions struct.
func (*KeyEntry) AskToAddKey ¶
AskToAddKey creates or finds a key for adding content (for diff/merge operations).
The "Ask" naming reflects that you're not modifying the source key - you're "asking" this tree (typically a diff/merge result) to record that the given key should be added. The method copies the source key's structure into this tree.
This naming convention originates from the C# implementation and is preserved for API compatibility across the C#/C++/Go implementations.
func (*KeyEntry) AskToAddValue ¶
func (k *KeyEntry) AskToAddValue(key *KeyEntry, val *ValueEntry)
AskToAddValue adds a value to the key (for diff/merge operations).
The "Ask" naming reflects that you're not modifying the source - you're "asking" this tree to record that the given value should be added. See AskToAddKey for more details on the naming convention.
func (*KeyEntry) AskToRemoveKey ¶
AskToRemoveKey creates a key entry marked for removal (for diff/merge operations).
The "Ask" naming reflects that you're not modifying the source key - you're "asking" this tree (typically a diff/merge result) to record that the given key should be removed. See AskToAddKey for more details on the naming convention.
func (*KeyEntry) AskToRemoveValue ¶
func (k *KeyEntry) AskToRemoveValue(key *KeyEntry, val *ValueEntry)
AskToRemoveValue adds a value marked for removal (for diff/merge operations).
The "Ask" naming reflects that you're not modifying the source - you're "asking" this tree to record that the given value should be removed. See AskToAddKey for more details on the naming convention.
func (*KeyEntry) DefaultValue ¶
func (k *KeyEntry) DefaultValue() *ValueEntry
DefaultValue returns the default value (if any).
func (*KeyEntry) FindOrCreateKey ¶
FindOrCreateKey finds or creates a subkey by path. Handles "-PATH" syntax for remove flag.
func (*KeyEntry) FindOrCreateValue ¶
func (k *KeyEntry) FindOrCreateValue(name string) *ValueEntry
FindOrCreateValue finds or creates a named value. Empty string name creates/returns the default value.
func (*KeyEntry) RemoveFlag ¶
RemoveFlag checks if this key should be removed.
func (*KeyEntry) SetParent ¶
SetParent sets the parent key. This is useful when grafting a subtree onto another tree.
func (*KeyEntry) SetRemoveFlag ¶
SetRemoveFlag sets the remove flag.
func (*KeyEntry) SubKeys ¶
SubKeys returns the map of subkeys.
Note: This returns the actual internal map, not a copy. Callers can modify it directly. This matches the C# implementation (public readonly Dictionary) where the map contents are mutable. The C++ sibling returns const refs instead. This design allows external code (like registry importers) to populate the tree. Map keys are lowercase; use the KeyEntry.Name() method to get the original casing.
func (*KeyEntry) Values ¶
func (k *KeyEntry) Values() map[string]*ValueEntry
Values returns the map of values.
Note: This returns the actual internal map, not a copy. Callers can modify it directly. This matches the C# implementation (public readonly Dictionary) where the map contents are mutable. The C++ sibling returns const refs instead. This design allows external code (like registry importers) to populate the tree. Map keys are lowercase; use the ValueEntry.Name() method to get the original casing.
type ParseError ¶
type ParseError struct {
// Line number where the error occurred (1-based).
Line int
// Column number where the error occurred (1-based).
Column int
// Message describing what went wrong.
Message string
// Context shows the problematic line from the input.
Context string
// ContextPointer is a line with a ^ pointing to the error position.
ContextPointer string
}
ParseError represents an error that occurred during .REG file parsing. It includes location information (line, column) and context from the input.
func IsParseError ¶
func IsParseError(err error) *ParseError
IsParseError checks if an error is a ParseError and returns it. Returns nil if the error is not a ParseError.
func (*ParseError) Error ¶
func (e *ParseError) Error() string
Error implements the error interface.
func (*ParseError) Unwrap ¶
func (e *ParseError) Unwrap() error
Unwrap returns nil as ParseError doesn't wrap other errors.
type ParseOptions ¶
type ParseOptions struct {
// AllowHashtagComments allows # style line comments.
// Standard .REG files don't support comments; enable this for hand-edited files.
AllowHashtagComments bool
// AllowSemicolonComments allows ; style line comments.
// Standard .REG files don't support comments; enable this for hand-edited files.
AllowSemicolonComments bool
// IgnoreWhitespaces is more relaxed about whitespace in .REG files.
// Recommended for manually edited files that may have extra spaces.
IgnoreWhitespaces bool
// AllowVariableSubstitution allows variable names for non-string values.
// Enables syntax like: "value"=dword:$$VARIABLE$$
// Useful for installer templates where some values are filled in at install time.
AllowVariableSubstitution bool
// AnsiCodePage controls decoding for REGEDIT4 (ANSI) files when using ParseFile.
// If empty, the decoder falls back to raw bytes (best-effort UTF-8/ASCII behavior).
// Examples: "windows-1252", "windows-1250".
// This is intentionally lenient and may accept data that regedit itself would.
AnsiCodePage string
}
ParseOptions configures the behavior of the .REG file parser.
type ParserContext ¶
type ParserContext struct {
Line int
Column int
Index int
Buffer []rune
// contains filtered or unexported fields
}
ParserContext provides the base functionality for a state-machine parser. It mimics the C++ abstract_parser class.
func NewParserContext ¶
func NewParserContext() *ParserContext
NewParserContext creates a new ParserContext.
func (*ParserContext) BufferAppend ¶
func (p *ParserContext) BufferAppend(r rune)
BufferAppend appends a rune to the buffer.
func (*ParserContext) BufferAsString ¶
func (p *ParserContext) BufferAsString() string
BufferAsString returns the current buffer contents as a string.
func (*ParserContext) BufferClear ¶
func (p *ParserContext) BufferClear()
BufferClear clears the buffer.
func (*ParserContext) FormatError ¶
func (p *ParserContext) FormatError(err error) error
FormatError augments an error with context information (line, column, snippet). Returns a *ParseError with location and context details.
func (*ParserContext) LastState ¶
func (p *ParserContext) LastState() ParserState
LastState returns the parser's last known state function. This is used by concrete parsers to apply lenient EOF finalization.
func (*ParserContext) ParseText ¶
func (p *ParserContext) ParseText(text string, initialState ParserState) error
ParseText processes the input string starting with the given initial state.
type ParserState ¶
type ParserState func(r rune) (ParserState, error)
ParserState is a function representing a state in the state machine. It takes a rune and returns the next state, or an error.
type RegParser ¶
type RegParser struct {
*ParserContext
// contains filtered or unexported fields
}
RegParser parses Windows .REG files.
func NewRegParser ¶
func NewRegParser(expectedHeader string, options *ParseOptions) *RegParser
NewRegParser creates a new parser.
type RegWriter ¶
type RegWriter struct {
Header string
Options ExportOptions
// contains filtered or unexported fields
}
RegWriter handles exporting KeyEntry trees to .REG format.
func NewRegWriter ¶
func NewRegWriter(header string, options ExportOptions, useUtf16 bool) *RegWriter
NewRegWriter creates a new RegWriter. For Windows 5.00 format, use HeaderWindows5 and useUtf16=true. For REGEDIT4 format, use HeaderRegedit4 and useUtf16=false.
type ValueEntry ¶
type ValueEntry struct {
// contains filtered or unexported fields
}
ValueEntry represents a registry value with name, type, and data. Data is stored internally as UTF-16LE bytes (matching Windows registry format).
func NewValueEntry ¶
func NewValueEntry(name string) *ValueEntry
NewValueEntry creates a new ValueEntry.
func (*ValueEntry) GetDword ¶
func (v *ValueEntry) GetDword(defaultValue uint32) uint32
GetDword returns the value as DWORD.
func (*ValueEntry) GetMultiString ¶
func (v *ValueEntry) GetMultiString() []string
GetMultiString returns the value as a list of strings.
func (*ValueEntry) GetQword ¶
func (v *ValueEntry) GetQword(defaultValue uint64) uint64
GetQword returns the value as QWORD.
func (*ValueEntry) GetString ¶
func (v *ValueEntry) GetString(defaultValue string) string
GetString returns the value as string.
func (*ValueEntry) IsDefaultValue ¶
func (v *ValueEntry) IsDefaultValue() bool
IsDefaultValue checks if this is the default (unnamed) value for a key.
func (*ValueEntry) RemoveFlag ¶
func (v *ValueEntry) RemoveFlag() bool
RemoveFlag checks if this value should be removed.
func (*ValueEntry) SetBinaryType ¶
func (v *ValueEntry) SetBinaryType(kind uint32, data []byte)
SetBinaryType sets raw binary data with specified type.
func (*ValueEntry) SetDword ¶
func (v *ValueEntry) SetDword(val uint32)
SetDword sets the value as REG_DWORD.
func (*ValueEntry) SetEscapedDwordValue ¶
func (v *ValueEntry) SetEscapedDwordValue(variableRef string)
SetEscapedDwordValue sets escaped DWORD value (variable name stored as string).
func (*ValueEntry) SetEscapedQwordValue ¶
func (v *ValueEntry) SetEscapedQwordValue(variableRef string)
SetEscapedQwordValue sets escaped QWORD value (variable name stored as string).
func (*ValueEntry) SetExpandString ¶
func (v *ValueEntry) SetExpandString(val string)
SetExpandString sets the value as REG_EXPAND_SZ.
func (*ValueEntry) SetMultiString ¶
func (v *ValueEntry) SetMultiString(stringsList []string)
SetMultiString sets the value as REG_MULTI_SZ.
func (*ValueEntry) SetQword ¶
func (v *ValueEntry) SetQword(val uint64)
SetQword sets the value as REG_QWORD.
func (*ValueEntry) SetRemoveFlag ¶
func (v *ValueEntry) SetRemoveFlag(flag bool)
SetRemoveFlag sets the remove flag.
func (*ValueEntry) SetString ¶
func (v *ValueEntry) SetString(val string)
SetString sets the value as REG_SZ.
type WixWriter ¶
type WixWriter struct {
}
WixWriter handles exporting KeyEntry trees to WiX XML format.