2011-10-25 19 views
2

オフラインのNTUSER.DATファイルを読み込んで(そしてそれを変更しようとしていますが)、この作業ができません。 RegLoadKeyは8589934592を返すが、それは何を意味するのかわからない。これは失敗した行です:C#からレジストリハイブを読み込めません。

public class RegistryTest 
{ 
    [StructLayout(LayoutKind.Sequential)] 
    private struct LUID 
    { 
     public uint LowPart; 
     public int HighPart; 
    } 

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

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

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

    private const uint HKEY_USERS = 0x80000003; 
    private const string SE_RESTORE_NAME = "SeRestorePrivilege"; 
    private const string SE_BACKUP_NAME = "SeBackupPrivilege"; 

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

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

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

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

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

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

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

    private LUID _restoreLuid; 
    private LUID _backupLuid; 

    public RegistryTest() 
    { 
     if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, out _myToken)) 
      Console.WriteLine("OpenProcess Error"); 

     if (!LookupPrivilegeValue(null, SE_RESTORE_NAME, out _restoreLuid)) 
      Console.WriteLine("LookupPrivilegeValue Error"); 

     if (!LookupPrivilegeValue(null, SE_BACKUP_NAME, out _backupLuid)) 
      Console.WriteLine("LookupPrivilegeValue Error"); 

     _tokenPrivileges.Attr = SE_PRIVILEGE_ENABLED; 
     _tokenPrivileges.Luid = _restoreLuid; 
     _tokenPrivileges.Count = 1; 

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

     if (!AdjustTokenPrivileges(_myToken, false, ref _tokenPrivileges, 0, IntPtr.Zero, IntPtr.Zero)) 
      Console.WriteLine("AdjustTokenPrivileges Error: " + Marshal.GetLastWin32Error()); 

     if (!AdjustTokenPrivileges(_myToken, false, ref _tokenPrivileges2, 0, IntPtr.Zero, IntPtr.Zero)) 
      Console.WriteLine("AdjustTokenPrivileges Error: " + Marshal.GetLastWin32Error()); 

     // --> RegLoadKey fails with return value 8589934592 <-- 
     long retVal = RegLoadKey(HKEY_USERS, "123test", @"D:\temp\NTUSER.DAT"); 
     if (retVal != 0) 
      Console.WriteLine("RegLoadKey Error:" + retVal); 

     string test = Registry.GetValue(@"HKEY_LOCAL_MACHINE\123test\Environment", "TEMP", "") as string; 
     retVal = RegUnLoadKey(HKEY_USERS, "123test"); 
    } 
} 

は、私が何をしないのです。ここで

long retVal = RegLoadKey(HKEY_USERS, "123test", @"D:\temp\NTUSER.DAT"); 

は、完全なテストコードのですか?助けてください!!誰かがハイブを読み込んで値を変更するためのC#サンプルコードを作業していれば、さらに良いでしょう。

ありがとうございました。

+0

必ずお読みください:http://msdn.microsoft.com/en-us/library/windows/desktop/ms724889(v=vs.85).aspx –

答えて

8

8589934592は、32ビット以上の0x200000000です。

RegLoadKeyは32ビットのwin32 "long"値を返します。関数を64ビットのC#longを返すと宣言しました。 RegLoadKey宣言を修正してintを返すと、期待どおりの値0が得られます。

+0

私は、16進値に別の '0'が必要と思います –

+1

@エヴァンあなたは正しい、私は数えることはできません。テキストが更新されました。 – arx

+0

arx、それでした!ありがとうございました!!! – Lars

関連する問題