在C#中访问System32 \ config \ SYSTEM配置单元

时间:2017-02-27 16:08:24

标签: c# registry

我正在编写一个实用程序,以便在WinPE中启动时尝试检索设备的计算机名称,并且无法在C#中找到本机方式来读取脱机配置单元。我有以下代码来检索它,我得到一个ERROR_BADDB错误:

ERROR_BADDB 
1009 (0x3F1)
    The configuration registry database is corrupt.

OfflineReg类:

class OfflineReg {

    // import services
    // portions taken from https://www.experts-exchange.com/questions/27413505/Loading-modifying-value-in-registry-hive-from-NET-C.html
    // http://stackoverflow.com/questions/2917309/regloadappkey-working-fine-on-32-bit-os-failing-on-64-bit-os-even-if-both-proc
    [System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
    private struct LUID {
        public uint LowPart;
        public int HighPart;
    }

    [System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
    private struct LUID_AND_ATTRIBUTES {
        public LUID pLuid;
        public System.UInt32 Attributes;
    }

    [System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential, Pack = 1)]
    private struct TokPriv1Luid {
        public int Count;
        public LUID Luid;
        public System.UInt32 Attr;
    }

    private const System.Int32 ANYSIZE_ARRAY = 1;
    private const System.UInt32 SE_PRIVILEGE_ENABLED = 0x00000002;
    private const System.UInt32 TOKEN_ADJUST_PRIVILEGES = 0x0020;
    private const System.UInt32 TOKEN_QUERY = 0x0008;

    private const uint HKEY_LOCAL_MACHINE = 0x80000002;
    private const string SE_RESTORE_NAME = "SeRestorePrivilege";
    private const string SE_BACKUP_NAME = "SeBackupPrivilege";

    [System.Runtime.InteropServices.DllImport("kernel32.dll")]
    static extern System.IntPtr GetCurrentProcess();

    [System.Runtime.InteropServices.DllImport("advapi32.dll", SetLastError = true)]
    [return: System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.Bool)]
    static extern bool OpenProcessToken(System.IntPtr ProcessHandle, System.UInt32 DesiredAccess, out System.IntPtr TokenHandle);

    [System.Runtime.InteropServices.DllImport("advapi32.dll", SetLastError = true, CharSet = System.Runtime.InteropServices.CharSet.Auto)]
    [return: System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.Bool)]
    static extern bool LookupPrivilegeValue(string lpSystemName, string lpName, out LUID lpLuid);

    [System.Runtime.InteropServices.DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
    static extern bool AdjustTokenPrivileges(
        System.IntPtr htok,
        bool disableAllPrivileges,
        ref TokPriv1Luid newState,
        int len,
        System.IntPtr prev,
        System.IntPtr relen);

    [System.Runtime.InteropServices.DllImport("advapi32.dll", SetLastError = true)]
    static extern System.Int32 RegLoadKey(System.UInt32 hKey, System.String lpSubKey, System.String lpFile);

    [System.Runtime.InteropServices.DllImport("advapi32.dll", SetLastError = true)]
    static extern System.Int32 RegUnLoadKey(System.UInt32 hKey, string lpSubKey);

    private System.IntPtr _myToken;
    private TokPriv1Luid _tokenPrivileges = new TokPriv1Luid();
    private TokPriv1Luid _tokenPrivileges2 = new TokPriv1Luid();

    private LUID _restoreLuid;
    private LUID _backupLuid;

    /**
     * temp_key
     * Temporary key name to load in HKLM
     */
    private System.String temp_key = null;

    /*
     * OfflineReg
     * Initialize registry environment, capture privileges, load key into HKLM
     */
    public OfflineReg(System.String hivepath) {
        // get process token
        if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, out _myToken)) {
            int error = System.Runtime.InteropServices.Marshal.GetLastWin32Error();
            throw new OfflineRegException("There was a problem invoking OpenProcessToken; error code: " + error);
        }

        // get privilege value for SE_RESTORE_NAME
        if (!LookupPrivilegeValue(null, SE_RESTORE_NAME, out _restoreLuid)) {
            int error = System.Runtime.InteropServices.Marshal.GetLastWin32Error();
            throw new OfflineRegException("There was a problem invoking LookupPrivilegeValue; error code: " + error);
        }

        // get privilege value for SE_BACKUP_NAME
        if (!LookupPrivilegeValue(null, SE_BACKUP_NAME, out _backupLuid)) {
            int error = System.Runtime.InteropServices.Marshal.GetLastWin32Error();
            throw new OfflineRegException("There was a problem invoking LookupPrivilegeValue; error code: " + error);
        }

        // set privileges to allow registry editing
        _tokenPrivileges.Attr = SE_PRIVILEGE_ENABLED;
        _tokenPrivileges.Luid = _restoreLuid;
        _tokenPrivileges.Count = 1;

        _tokenPrivileges2.Attr = SE_PRIVILEGE_ENABLED;
        _tokenPrivileges2.Luid = _backupLuid;
        _tokenPrivileges2.Count = 1;

        // adjust privileges
        if (!AdjustTokenPrivileges(_myToken, false, ref _tokenPrivileges, 0, System.IntPtr.Zero, System.IntPtr.Zero)) {
            int error = System.Runtime.InteropServices.Marshal.GetLastWin32Error();
            throw new OfflineRegException("There was a problem invoking AdjustTokenPrivileges; error code: " + error);
        }

        if (!AdjustTokenPrivileges(_myToken, false, ref _tokenPrivileges2, 0, System.IntPtr.Zero, System.IntPtr.Zero)) {
            int error = System.Runtime.InteropServices.Marshal.GetLastWin32Error();
            throw new OfflineRegException("There was a problem invoking AdjustTokenPrivileges; error code: " + error);
        }

        // attempt to load key
        System.Random rand = new System.Random();
        this.temp_key = "OfflineRegTmp" + rand.Next(0, 9) + rand.Next(0, 9) + rand.Next(0, 9);
        int result = RegLoadKey(HKEY_LOCAL_MACHINE, this.temp_key, hivepath);
        if (result != 0) {
            throw new OfflineRegException("There was a problem invoking RegLoadKey; error code: " + result);
        }
    }

当我从我从测试机器复制的CONFIG文件的路径调用时,结果返回1009:

OfflineReg reg = new OfflineReg("path_to_my_vs_dir\CONFIG");

1 个答案:

答案 0 :(得分:0)

找到它 - 我需要在那个路径中访问\ Windows \ System32 \ config \ SYSTEM,而不是在任何地方复制文件。它必须依赖于该目录中的其他注册表配置单元。

以原始路径访问配置单元,您应该很好。