我试图在Windows注册表中查看一些键和值。有一些键,不能用registry.READ权限打开,所以对我来说读取值和键,我必须使用registry.QUERY_VALUE和registry.ENUMERATE_SUB_KEYS权限; 但是,在使用具有此类权限的k.OpenKey()(例如HKEY_LOCAL_MACHINE \ SOFTWARE)成功打开密钥后,k.ReadSubKeyNames()函数在两种情况下都会出错:
ReadSubKeyNames:HKEY_LOCAL_MACHINE \ SOFTWARE访问被拒绝。
当然,为管理员启用了实际的注册表键权限QUERY_VALUE和ENUMERATE_SUB_KEYS(我使用管理员配置文件)
如何在不使用registry.READ权限的情况下获取子密钥名称,问题是什么?
代码示例:
var (
queryVal uint32 = registry.QUERY_VALUE
enumSubs uint32 = registry.ENUMERATE_SUB_KEYS
)
k, err = registry.OpenKey(globalK, p, queryVal)
if err != nil {
logErr(wrapErr(fmt.Sprintf("registry.OpenKey: %s", keyPath), err))
return
}
defer k.Close()
newKey := someLocalType{
}
keyStat, err := k.Stat()
if err != nil {
logWarn(fmt.Sprintf("Stat: %s %v", keyPath, err))
return
}
newKey.mod = keyStat.ModTime()
n, err := k.ReadValueNames(-1)
if err != nil {
logWarn(fmt.Sprintf("ReadValueNames: %s %v", keyPath, err))
return
}
for _, each := range n {
v, err := getKeyValue(k, each, keyStat.MaxValueLen)
if err != nil {
logWarn(fmt.Sprintf("getKeyValue: %s %v", keyPath, err))
continue
}
newKey.val = append(newKey.val, v)
}
var k1 registry.Key
if len(p) != 0 {
k1, err = registry.OpenKey(globalK, p, enumSubs)
if err != nil {
logErr(wrapErr(fmt.Sprintf("registry.OpenKey: %s", keyPath), err))
return
}
defer k1.Close()
} else {
k1 = globalK
}
subNames, err := k1.ReadSubKeyNames(-1)
if err != nil {
logWarn(fmt.Sprintf("ReadSubKeyNames: %s %v", keyPath, err))
return
}
for _, each := range subNames {
newPath := joinPath(p, each)
scanKey(globalK, newPath, c)
}
return
答案 0 :(得分:1)
答案是使用组合值:
combinedRights := registry.QUERY_VALUE | registry.ENUMERATE_SUB_KEYS
因为k.ReadSubKeyNames()在其中使用k.Stat(),并且k.Stat()需要registry.QUERY_VALUE权限才能成功返回,之后k.ReadSubKeyNames()使用syscall枚举子键并且有注册表使用.ENUMERATE_SUB_KEYS权限。 Windows注册表权限可以使用OR进行汇总,这就是答案。