internal void ApplyNotOnlyReadOperation(string subKeyName, KeySecurity samDesired, KeyImplOperation operation, Win32Api.RegWow64Options wowOptions = Win32Api.RegWow64Options.None) { if (!TryApplyOperation(KeyDisposition.DIFF_HIVE, subKeyName, samDesired, operation, wowOptions)) { throw new FileNotFoundException(); } }
internal void ApplyReadOperation(string subKeyName, KeySecurity samDesired, KeyImplOperation operation) { Debug.Assert(samDesired.IsOnlyForRead()); if (!samDesired.IsOnlyForRead()) { throw new AccessDeniedException(); } foreach (KeyDisposition disposition in HIVES_ORDER) { if (TryApplyOperation(disposition, subKeyName, samDesired, operation)) { return; } } throw new FileNotFoundException(); }
// returns false in case of FileNotFound error, otherwise throws exception internal bool TryApplyOperation(KeyDisposition disposition, string subKeyName, KeySecurity samDesired, KeyImplOperation operation, Win32Api.RegWow64Options wowOptions = Win32Api.RegWow64Options.None) { // None is passed from Get/Set/Enum operations which does not allow user to pass wow options // in such case we take it from the current identity if (wowOptions == Win32Api.RegWow64Options.None) { wowOptions = identity_.GetWow64Mode(); } KeyImplHolder subKey; if (!TryGetSubKey(disposition, subKeyName, samDesired, wowOptions, out subKey)) { return(false); } using (subKey) { // TODO: almost always the operation needs subKey name, at least for logging // so it is constructed second time there. // Better to pass it from here. try { if (!operation(subKey.GetKeyImpl())) { return(false); } } catch (FileNotFoundException) { // TODO: make all operations return false in case of FileNotFoundException // so that this catch can be removed. return(false); } } return(true); }
public void EnumValue( uint dwIndex, IntPtr lpValueName, /*ref UInt32*/ IntPtr lpcchValueName, IntPtr lpReserved, /*ref Win32Api.RegValueType*/ IntPtr lpType, IntPtr lpData, /*ref UInt32*/ IntPtr lpcbData) { // TODO: this function does not take into account the intersection // of value names between windows regisry key and offreg key, this is // to be done in the next version // It does not matter if the current key is open in windows registry or in offreg // we need to open and enumerate both them int cchValueName = 0; if (lpcchValueName != IntPtr.Zero) { cchValueName = Marshal.ReadInt32(lpcchValueName); } KeyImplOperation enumValue = keyImpl => TryAlterData(null, null, keyImpl, lpType, new Data(lpData, lpcbData, Data.CountIn.Bytes), (newpdwType, dst) => Win32Exception.CatchError( () => { // EnumValue takes buffer size WITH null character // but returns WITHOUT, so we need to reset input // param to allow multiple calls to the operation if (lpcchValueName != IntPtr.Zero) { Marshal.WriteInt32(lpcchValueName, cchValueName); } keyImpl.EnumValue(dwIndex, lpValueName, lpcchValueName, lpReserved, newpdwType, dst.Ptr, dst.PCount); })); foreach (KeyDisposition disposition in HIVES_REVERSE_ORDER) { bool indexHandled = false; TryApplyOperation(disposition, null, new KeySecurity(Win32Api.KeySecurity.KEY_QUERY_VALUE), keyImpl => { uint cValues = keyImpl.QueryInfo().ValuesNumber; if (dwIndex < cValues) { enumValue(keyImpl); indexHandled = true; } else { dwIndex -= cValues; } return(true); }); if (indexHandled) { return; } } throw Win32Exception.Create((int)Win32Api.Error.ERROR_NO_MORE_ITEMS); }