# Copyright 2026 SigmaSRC, Inc. All Rights Reserved.

"""Gather Windows registry information."""

import os
import sys
import time
import winreg as _winreg

from sigma.util import config

def Gather(collector):
    if os.name != "nt":
        raise RuntimeError("Can only gather Windows process info on Windows")
    options = config.Options()
    if options.limit_gathers:
        roots = [
            ("HKEY_USERS", "HKU"),
            ]
    else:
        roots = [
            # Note: HKCR, HKCU and HKCC are symlinks
            ("HKEY_LOCAL_MACHINE", "HKLM"),
            ("HKEY_USERS", "HKU"),
            # Note: HKEY_PERFORMANCE_DATA is not interesting for us
            ]
    table = collector.table("winreg", "path name value type mtime".split())
    for keyname, shortcut in roots:
        walkroot(table, keyname, shortcut)

def walkroot(table, keyname, shortcut):
    counter = walkreg(table, getattr(_winreg, keyname), shortcut)
    ##print >>sys.stderr, keyname, counter

def walkreg(table, key, path):
    counter = 0
    nsubkeys, nvalues, mtime = _winreg.QueryInfoKey(key)
    if mtime:
        # mtime is expressed in 100s of nanoseconds since 1/1/1600, no kidding!
        mtime *= 100e-9 # convert to seconds
        mtime = mtime - 135140 * 24 * 3600 # convert to POSIX epoch (1/1/1970)
    for i in range(nvalues):
        nm, val, typ = _winreg.EnumValue(key, i)
        # No .encode() here: winreg returns str on Py3, and records.py
        # encodes to UTF-8 itself.  Pre-encoding produced bytes, which
        # str()'d into the literal text "b'SomeValue'" on the way out.
        table.add([path, nm, val, typ, mtime])
        counter += 1

    for i in range(nsubkeys):
        try:
            subkeyname = _winreg.EnumKey(key, i)
        except OSError as err:
            ##print >>sys.stderr, path, i, err
            continue # Probably "More data is available" ?!?!?!
        subkeypath = path + "\\" + subkeyname
        try:
            subkey = _winreg.OpenKey(key, subkeyname)
        except OSError as err:
            ##print >>sys.stderr, path, subkeyname, err
            pass # Probably access denied
        else:
            counter += walkreg(table, subkey, subkeypath)

    return counter

def _test():
    from sigma.gather import gathering
    gathering.test(Gather)

if __name__ == "__main__":
    _test()
