RegSaveKey 获得的文件 用RegLoadKey加载,SE_BACKUP_NAME和 SE_RESTORE_NAME权限也已经加了。 
加载在HKEY_LOCAL_MACHINE下总是返回5 拒绝访问 
加载在HKEY_USERS下就能成功,可是是易失的,下次开机就没有了 各位帮帮我啊!   HANDLE htok = NULL; 
OpenProcessToken(GetCurrentProcess(), 
TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, 
&htok); 
        TOKEN_PRIVILEGES tp0; 
tp0.PrivilegeCount = 1; 
tp0.Privileges->Attributes = SE_PRIVILEGE_ENABLED; 
LUID luid0 ; 
LookupPrivilegeValue(0,SE_BACKUP_NAME,&luid0); 
tp0.Privileges->Luid = luid0; 
if(!AdjustTokenPrivileges( htok, FALSE, &tp0, sizeof(tp0), NULL,NULL)) 
printf("AdjustTokenPrivilegs tp0 error! %d\n",GetLastError()); 
        CloseHandle(htok);         HKEY hkey; 
        char* file = "C:\\backup.bak"; 
if(ret=RegOpenKeyEx(HKEY_LOCAL_MACHINE, KEYFSREG, 0, KEY_QUERY_VALUE, &hkey)) 
printf("打开不成功!%d\n",ret); 
        SECURITY_ATTRIBUTES sa; 
sa.nLength=sizeof(SECURITY_ATTRIBUTES); 
sa.lpSecurityDescriptor =NULL; 
sa.bInheritHandle =TRUE;         if(!(ret = RegSaveKey(hkey, file, &sa))) //听  HANDLE htok = NULL; 
OpenProcessToken(GetCurrentProcess(), 
TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, 
&htok); 
        TOKEN_PRIVILEGES tp0; 
tp0.PrivilegeCount = 1; 
tp0.Privileges->Attributes = SE_PRIVILEGE_ENABLED; 
LUID luid0 ; 
LookupPrivilegeValue(0,SE_BACKUP_NAME,&luid0); 
tp0.Privileges->Luid = luid0; 
if(!AdjustTokenPrivileges( htok, FALSE, &tp0, sizeof(tp0), NULL,NULL)) 
printf("AdjustTokenPrivilegs tp0 error! %d\n",GetLastError()); 
        CloseHandle(htok);         HKEY hkey; 
        char* file = "C:\\backup.bak"; 
if(ret=RegOpenKeyEx(HKEY_LOCAL_MACHINE, KEYFSREG, 0, KEY_QUERY_VALUE, &hkey)) 
printf("打开不成功!%d\n",ret); 
        SECURITY_ATTRIBUTES sa; 
sa.nLength=sizeof(SECURITY_ATTRIBUTES); 
sa.lpSecurityDescriptor =NULL; 
sa.bInheritHandle =TRUE;         if(!(ret = RegSaveKey(hkey, file, &sa))) //听biweilun 说可能是第三个参数的问题,之前是NULL。 
printf("保存成功!\n"); 
else 
printf("保存出错:%d\n",ret);            if(hkey) 
RegCloseKey(hkey); 

解决方案 »

  1.   

    下面是导入的 HANDLE htok = NULL; 
    OpenProcessToken(GetCurrentProcess(), 
    TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, 
    &htok); 
    TOKEN_PRIVILEGES tp0; 
    tp0.PrivilegeCount = 1; 
    tp0.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 
    LUID luid0 ; 
    LookupPrivilegeValue(0,SE_BACKUP_NAME,&luid0); 
    tp0.Privileges[0].Luid = luid0; if(!AdjustTokenPrivileges( htok, FALSE, &tp0, sizeof(tp0),0,0)) 
    printf("AdjustTokenPrivilegs tp0 error! %d\n",GetLastError()); 
    TOKEN_PRIVILEGES tp1; 
    tp1.PrivilegeCount = 1; 
    tp1.Privileges->Attributes = SE_PRIVILEGE_ENABLED; 
    LUID luid1 ; 
    LookupPrivilegeValue(0,SE_RESTORE_NAME,&luid1); 
    tp1.Privileges->Luid = luid1; 
    if(!AdjustTokenPrivileges( htok, FALSE, &tp1, sizeof(tp1), NULL,NULL)) 
    printf("AdjustTokenPrivilegs tp1 error! %d\n",GetLastError()); 
    CloseHandle(htok); 
    if(!(ret = RegLoadKey(HKEY_LOCAL_MACHINE, sFSReg , file))) 
    printf("导入成功!\n"); 
    else 
    printf("RegLoadKey error! %d\n", ret); 
      

  2.   

    现在是RegLoadKey 到HKEY_USERS下能行,但是是易失的,下次开机就没有了。
    我想加载到HKEY_LOCAL_MACHINE下总是返回5 拒绝访问 大家帮帮忙 昨天一天什么也没干啊 郁闷
      

  3.   

    你要对注册表进行什么操作?CRegKey (MSDN里封好的)不能满足你的需求啊
      

  4.   

    一、 创建键RegCreateKeyEx
      通过RegCreateKeyEx函数可以在注册表中创建键,如果需要创建的键已经存在了,则打开键。函数原型如下:
      LONG RegCreateKeyEx(
      HKEY hKey,
      LPCTSTR lpSubKey,
      DWORD Reserved,
      LPTSTR lpClass,
      DWORD dwOptions,
      REGSAM samDesired,
      LPSECURITY_ATTRIBUTESlpSecurityAttributes,
      PHKEY phkResult,
      LPDWORD lpdwDisposition
      );
      各参数及返回值的含义如下:
      •hKey为主键值,可以取下面的一些数值:
      HKEY_CLASSES_ROOT、HKEY_CURRENT_CONFIG
      HKEY_CURRENT_USER、HKEY_LOCAL_MACHINE
      HKEY_USER、HKEY_PERFORMANCE_DATA(WINNT操作系统)
      HKEY_DYN_DATA(WIN9X操作系统)
      •参数lpSubKey为一个指向以零结尾的字符串的指针,其中包含将要创建或打开的子键的名称。子键不可以用反斜线(\)开始。该参数可以为NULL。
      •Reserved保留,必须设置为0。
      •参数lpClass一个指向包含键类型的字符串。如果该键已经存在,则忽略该参数。
      •参数dwOptions为新创建的键设置一定的属性。可以取下面的一些数值:
      REG_OPTION_NON_VOLATILE 新创建的键为一个非短暂性的键(数据信息保存在文件中,当系统重新启动时,数据信息恢复)
      REG_OPTION_VOLATILE 新创建的键为一个短暂性的键(数据信息保存在内存中)。Windows95忽略该数值。
      REG_OPTION_BACKUP_RESTORE 仅在WINNT中支持,可以提供优先级支持。
      •参数samDesired用来设置对键访问的权限,可以取下面的一些数值:
      KEY_CREATE_LINK 准许生成符号键
      KEY_CREATE_SUB_KEY 准许生成子键
      KEY_ENUMERATE_SUB_KEYS 准许生成枚举子键
      KEY_EXECUTE 准许进行读操作
      KEY_NOTIFY 准许更换通告
      KEY_QUERY_VALUE 准许查询子键
      KEY_ALL_ACCESS 提供完全访问,是上面数值的组合
      KEY_READ 是下面数值的组合:
      KEY_QUERY_VALUE、KEY_ENUMERATE_SUB_KEYS、KEY_NOTIFY
      KEY_SET_VALUE 准许设置子键的数值
      KEY_WRITE 是下面数值的组合:
      KEY_SET_VALUE、KEY_CREATE_SUB_KEY
      •参数lpSecurityAttributes为一个指向SECURITY_ATTRIBUTES结构的指针,确定返回的句柄是否被子处理过程继承。如果该参数为NULL,则句柄不可以被继承。在WINNT中,该参数可以为新创建的键增加安全的描述。
      •参数phkResult为一个指向新创建或打开的键的句柄的指针。
      •参数lpdwDispition指明键是被创建还是被打开的,可以是下面的一些数值:
      REG_CREATE_NEW_KEY 键先前不存在,现在被创建。
      REG_OPENED_EXISTING_KEY 键先前已存在,现在被打开。
      •返回值 如果函数调用成功,则返回ERROR_SUCCESS。否则,返回值为文件WINERROR.h中定义的一个非零的错误代码,可以通过设置FORMAT_MESSAGE_FROM_SYSTEM标识调用FormatMessage函数来获取一个对错误的总体描述。
      二、 打开一个键RegOpenKeyEx
      RegOpenKeyEx函数可以打开一个指定的键,函数原型如下:
      LONG RegOpenKeyEx(
      HKEY hkey,
      LPCTSTR lpSubKey,
      DWORD ulOption,
      REGSAM samDesired,
      PHKEY phkResult
      );
      各参数及返回值的含义如下:
      •参数hKey的含义同RegCreateKeyEx函数中的hKey参数。
      •参数lpSubKey为一个指向以零结尾的字符串的指针,其中包含子键的名称,可以利用反斜线(\)分隔不同的子键名。如果字符串为空,则根据hKey参数创建一个新的句柄。在这种情况下,并不关闭先前打开的句柄。
      •ulOption保留,通常必须设置为0。
      •参数samDesired的含义同RegCreateKeyEx函数中的samDesired参数。
      •参数phkResult为一个指针,用来指向打开的键的句柄。可以通过RegCloseKey函数关闭这个句柄。
      •返回值同RegCreateKeyEx函数的返回值。
      三、 读取键RegQueryValueEx
      通过RegQueryValueEx函数可以从一个已经打开的键中读取数据,函数原型如下:
      LONG RegQueryValueEx(
      HKEY hKey,
      LPTSTR lpValueName,
      LPDWORD lpReserved,
      LPDWORD lpType,
      LPBYTE lpData,
      LPDWORD lpcbData
      );
      各个参数及返回值的含义如下:
      •参数hKey为当前的一个打开的键的句柄,具体数值同RegCreateKeyEx函数的hKey参数。
      •参数lpVauleName为一个指向非空的包含查询值的名称的字符串指针。
      •lpReserved保留,必须为NULL。
      •参数lpType为一个指向数据类型的指针,数据类型为下列类型之一:
      REG_BINARY 二进制数据
      REG_DWORD 32位整数
      REG_DWORD_LITTLE_ENDIAN little-endian格式的数据,例如0X12345678以(0X78 0X56 0X34 0X12)方式保存
      REG_DWORD_BIG_ENDIAN big-endian格式的数据,例如0X12345678以(0X12 0X34 0X56 0X78)方式保存
      REG_EXPAND_SZ 一个包含未扩展环境变量的字符串
      REG_LINK 一个Unicode类型的链接
      REG_MULIT_SZ 以两个零结尾的字符串
      REG_NONE 无类型数值
      REG_RESOURCE_LIST 设备驱动资源列表
      REG_SZ 一个以零结尾的字符串根据函数使用的字符集类型的不同而设置为Unicode或ANSI类型的字符串
      •参数lpData为一个指向保存返回值的变量的指针。如果不需要返回值,该参数可以为NULL。
      •参数lpcbData为一个指向保存返回值长度的变量的指针。其中长度以字节为单位。如果数据类型为REG_SZ、REG_MULTI_SZ或REG_EXPAND_SZ,那么长度也包括结尾的零字符,只有在参数lpData为NULL时,参数lpcbData才可以为NULL。
      •返回值同RegCreateKeyEx函数的返回值。
      四、 设置键值RegSetValueEx
      RegSetValueEx函数可以设置注册表中键的值,函数原型如下:
      LONG RegSetValueEx(
      HKEY hKey,
      LPCTSTR lpValueName,
      DWORD Reserved,
      DWORD dwType,
      CONST BYTE *lpData,
      DWORD cbData
      );
      各个参数及返回值的含义如下:
      •参数hKey的含义同RegCreateKeyEx函数中的hKey参数。
      •参数lpValueName为一个指向包含值名的字符串指针。
      •Reserved保留,通常必须设置为0。
      •参数dwType确定了设置的值的类型同RegQueryValueKeyEx的lyType参数。
      •参数lpData为一个指向包含数据的缓冲区的指针。
      •参数cbData以字节为单位,指定数据的长度。
      •返回值同RegCreateKeyEx函数的返回值。
      五、 删除键值RegDeketeKey
      函数RegDeketeKey删除一个键及所有的子键。函数原型如下:
      LONG RegDeleteKey(
      HKEY hKey,
      LPCTSTR lpSubKEY
      );
      各个参数及返回值的含义如下:
      •参数hKey的含义同RegCreateKeyEx函数中的hKey参数。
      •参数lpSubKey的含义同RegCreateKeyEx函数中的lpSubKey参数。
      六、 示例
      下面我们在Visual C++6.0或5.0环境中新建一基于对话框的工程。设置两个命令按钮,名为“查询用户信息”和“修改用户信息”,用来查询和修改注册表中的用户姓名和公司名称。需要说明的是,用户的信息位于系统注册表中\KEY-CURRENT-USER\Software\Micrsoft\MS Setup(ACME)\User Info\的位置,键值名DefName和DefCompany分别表示用户的姓名和用户公司的名称。
      1、 查询用户信息的代码
      HKEY hKey; //定义有关的hKey,在查询结束时要关闭。
      LPCTSTR path="Software\\Micrsoft\\MS Setup(ACME)\\User Info\\”;
      LONG return0=(::RegOpenKeyEx(HKEY_CURRENT_USER,path,0,KEY_READ,&hKey));
      if(return0!=ERROR_SUCCESS)
      {
      MessageBox("错误:无法打开有关的键!");
      Return;
      }
      LPBYTE username_Get=new BYTE[80];
      DWORD type_1=REG_SZ;
      DWORD cbData_1=80;
      LONG return1=::RegQueryValueEx(hKey,"Defname:,NULL,&type_1,
      username_Get,&cbData_1);
      if(return1!=ERROR_SUCCESS)
      {
      MessageBox("错误:无法查询有关注册表信息!");
      Return;
      }
      LPBYTE company_Get=new BYTE[80];
      DWORD type_2=REG_SZ;
      DWORD cbData_2=80;
      LONG return2=::RegQueryValueEx(hKey,"DefCompany",NULL,&type_2,
      company_Get,&cbData_2);
      if(return2!=ERROR_SUCCESS)
      {
      MessageBox("错误:无法查询有关注册表信息!");
      Return;
      }
      //将username_Get和company_Get转换为CString字符串,以便显示输出
      CString str_username=CString(username_Get);
      CString str_company=CString(company_Get);
      delete[] username_Get;
      delete[] company_Get;
      //程序结束前关闭已经打开的hKey
      ::RegCloseKey(hKey);
      ……
      字符串str_username和str_company表示查询的用户的姓名和公司的名称。
      2、修改用户信息的代码
      因用户输出的是CString类型的字符串,要先将其转换为LPBYTE类型,以便以后函数的调用。下面是转换函数:
      LPBYTE CString_To_LPBYTE(CString str)
      {
      LPBYTE lpb=new BYTE [str.GetLength( )+1];
      for(int i=0;i   lpb[str.GetLength( )]=0;
      return lpb;
      }
      以下是具体的修改注册表用户信息的代码:
      CString str_username,str_company;
      HKEY hKey;
      LPCTSTR path=“Software\\Micrsoft\\MS Setup(ACME)\\User Info\\”;
      LONG return0(::RegOpenKeyEx(HKEY_CURRENT_USER,path,0,KEY_WRITE,&hKey));
      if(return0!=ERROR_SUCCESS)
      {
      MessageBox(“错误:无法打开有关的键!”);
      return;
      }
      LPBYTE username_Set=Cstring_To_LPBYTE(str_username);
      DWORD type_1=REG_SZ;
      DWORD cbData_1=str_username.GetLength( )+1;
      LONG return1=::RegSetalueEx(hKey,"DefName",NULL,type_1,username_Set,cbData_1);
      if (return1!=ERROR_SUCCESS)
      {
      MessageBox(“错误:无法修改有关注册表信息!”);
      return;
      }
      LPBYTE company_Set=Cstring_To_LPBYTE(str_company);
      DWORD type_2=REG_SZ;
      DWORD cbData_2=str_COMPANY.GetLength( )+1;
      LONG return2=::RegSetalueEx(hKey,"DefCompany",NULL,type_2,company_Set,cbData_2);
      if (return2!=ERROR_SUCCESS)
      {
      MessageBox(“错误:无法修改有关注册表信息!”);
      return;
      }注:注册表的修改已经被封装了,见MSDN 2001 CRegKey类  
    this searched  by LS.longgun