我试图在整个Windows注册表中监视以查找一些键和值。 有些注册表项无法使用Registry.READ权限打开,因此对于我而言,要读取值和注册表项,我必须使用Registry.QUERY_VALUE和Registry.ENUMERATE_SUB_KEYS权限;
但是,成功使用具有此类许可权的k.OpenKey()(例如HKEY_LOCAL_MACHINE SOFTWARE)打开密钥后,在两种情况下,k.ReadSubKeyNames()函数都会出现错误:
ReadSubKeyNames: HKEY_LOCAL_MACHINE\SOFTWARE Access is denied.
当然,已为管理员启用了实际的注册表项权限QUERY_VALUE和ENUMERATE_SUB_KEYS(我正在使用管理员配置文件)
我应该如何在不使用Registry.READ权限的情况下获得子键名称,这是什么问题?
代码示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | 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 | combinedRights := registry.QUERY_VALUE | registry.ENUMERATE_SUB_KEYS |
因为k.ReadSubKeyNames()在其中使用k.Stat(),并且k.Stat()要求Registry.QUERY_VALUE权限才能成功返回,然后k.ReadSubKeyNames()使用syscall枚举子项,并且那里是Registry.ENUMERATE_SUB_KEYS 用来。 Windows注册表权限可以在其上使用OR进行汇总,因此就是答案。