golang无法枚举注册表项

时间:2017-12-14 13:03:39

标签: windows go registry

我试图在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

1 个答案:

答案 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进行汇总,这就是答案。

相关问题