Exemplo n.º 1
0
 private bool TryOpenOrCreateDiffKey(KeyIdentity existingBase, KeyIdentity identity,
                                     KeySecurity samDesired, out IKeyImpl openedImpl)
 {
     if (TryOpen(existingBase, KeyDisposition.DIFF_HIVE, identity, samDesired, out openedImpl))
     {
         return(true);
     }
     // If some modification operation is requested and offreg key
     // does not exist, but it is in one of readonly hives - creating it
     if (samDesired.IsOnlyForRead() ||
         !KeyExistsInROHives(identity))
     {
         return(false);
     }
     try
     {
         openedImpl = Create(identity,
                             null, (int)Win32Api.RegOption.REG_OPTION_NON_VOLATILE, IntPtr.Zero,
                             IntPtr.Zero);
         return(true);
     }
     catch (FileNotFoundException)
     {
         return(false);
     }
 }
Exemplo n.º 2
0
 private void OpenKey(KeyIdentity existingBase, KeyIdentity identity, KeySecurity samDesired,
                      out IntPtr phkResult)
 {
     phkResult = IntPtr.Zero;
     phkResult = keyStorage_.Add(
         factory_.OpenKeyPreliminarily(existingBase, identity, samDesired));
 }
Exemplo n.º 3
0
        // existingBase is passed for performance optimization
        // TODO: encapsulate existingBase in a class and extract methods
        // with it a first argument there
        private bool TryOpenImpl(KeyIdentity existingBase, KeyDisposition disposition,
                                 KeyIdentity identity, KeySecurity samDesired, out IKeyImpl openedImpl)
        {
            openedImpl = null;
            if (disposition != KeyDisposition.DIFF_HIVE)
            {
                if (diffHive_.IsMarkedAsDeleted(existingBase, identity))
                {
                    return(false);
                }
            }
            IKeyImplOpenFactory factory = null;

            switch (disposition)
            {
            case KeyDisposition.WINDOWS_REG:
                factory = windowsKeyFactory_;
                break;

            case KeyDisposition.BASE_HIVE:
                factory = baseHive_;
                break;

            case KeyDisposition.DIFF_HIVE:
                factory = diffHive_;
                break;
            }
            if (factory == null)
            {
                // In case if specified hive is not used (currently used
                // only for null baseHive_)
                return(false);
            }
            return(factory.TryOpen(identity, samDesired, out openedImpl));
        }
Exemplo n.º 4
0
 public static void ExtractWow64Options(Win32Api.KeySecurity value,
                                        out KeySecurity keySecurity, out Win32Api.RegWow64Options wow64Options)
 {
     wow64Options = (Win32Api.RegWow64Options)((int)value &
                                               (int)(Win32Api.RegWow64Options.KEY_WOW64_32KEY | Win32Api.RegWow64Options.KEY_WOW64_64KEY));
     keySecurity = new KeySecurity(value & (Win32Api.KeySecurity) ~wow64Options);
 }
Exemplo n.º 5
0
        public bool TryOpen(KeyIdentity identity, KeySecurity samDesired, out IKeyImpl openedImpl)
        {
            OffRegKey offregKey;
            bool      result = OffRegKey.TryOpen(this, hive_, identity, out offregKey);

            openedImpl = offregKey;
            return(result);
        }
Exemplo n.º 6
0
        public bool TryOpen(KeyIdentity identity, KeySecurity samDesired, out IKeyImpl openedImpl)
        {
            WindowsKey windowsKey;
            bool       result = WindowsKey.TryOpen(identity, samDesired, out windowsKey);

            openedImpl = windowsKey;
            return(result);
        }
Exemplo n.º 7
0
 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();
     }
 }
Exemplo n.º 8
0
 public bool IsSubSetOf(KeySecurity another)
 {
     // During refactoring in the next line
     // (value_ & ~another.value_) != 0 was replaced with (value_ & ~another.value_) == 0
     // this may be wrong (althoug looks like it was a bug and now it should be fixed)
     // so please keep an eye on this change
     return((value_ & ~another.value_) == 0 ||
            value_ == Win32Api.KeySecurity.MAXIMUM_ALLOWED ||
            another.value_ == Win32Api.KeySecurity.MAXIMUM_ALLOWED);
 }
Exemplo n.º 9
0
        internal IKeyImpl Open(KeyDisposition disposition, KeyIdentity identity,
                               KeySecurity samDesired)
        {
            IKeyImpl result;

            if (!TryOpen(null, disposition, identity, samDesired, out result))
            {
                throw new FileNotFoundException();
            }
            return(result);
        }
Exemplo n.º 10
0
 private static void CheckReadOnlyHivesAccess(KeyDisposition disposition,
                                              KeySecurity samDesired)
 {
     if (disposition != KeyDisposition.DIFF_HIVE)
     {
         Debug.Assert(samDesired.IsOnlyForRead());
         if (!samDesired.IsOnlyForRead())
         {
             throw new AccessDeniedException();
         }
     }
 }
Exemplo n.º 11
0
 // returns false if the key does not exist in the given disposition,
 // on other errors throws exception.
 private bool TryOpen(KeyIdentity existingBase, KeyDisposition disposition, KeyIdentity identity,
                      KeySecurity samDesired, out IKeyImpl openedImpl)
 {
     if (!TryOpenImpl(existingBase, disposition, identity, samDesired, out openedImpl))
     {
         return(false);
     }
     baseKeyManager_.BaseKeyCopied(identity.BaseKey);
     openedImpl = new KeyImplDecoratorHookingClose(openedImpl,
                                                   () => baseKeyManager_.BaseKeyClosed(identity.BaseKey));
     return(true);
 }
Exemplo n.º 12
0
        internal void OpenUserClassesRoot(
            IntPtr hToken,
            UInt32 dwOptions,
            KeySecurity samDesired,
            out IntPtr phkResult)
        {
            IntPtr baseKey;

            Win32Exception.CheckResult(
                Win32Api.RegOpenUserClassesRoot(hToken, dwOptions, samDesired.Value, out baseKey));
            OpenWindowsBaseKey(baseKey, samDesired, out phkResult);
        }
Exemplo n.º 13
0
        private bool TryOpenKey(KeyIdentity existingBase, KeyDisposition disposition,
                                KeyIdentity identity, KeySecurity samDesired, out VirtualKey key)
        {
            KeyImplHolder holder;

            key = null;
            if (!TryOpenHolder(existingBase, disposition, identity, samDesired, out holder))
            {
                return(false);
            }
            key = new VirtualKey(this, identity, holder.ReleaseKeyImpl(), alterer_);
            return(true);
        }
Exemplo n.º 14
0
        internal void OpenCurrentUser(
            KeySecurity samDesired,
            out IntPtr phkResult)
        {
            // CurrentUser identity depends on the user to which opening
            // thread is impersonated right now, so we need to do the syscall
            // exactly at the moment and then use the returned value
            IntPtr baseKey;

            Win32Exception.CheckResult(
                Win32Api.RegOpenCurrentUser(samDesired.Value, out baseKey));
            OpenWindowsBaseKey(baseKey, samDesired, out phkResult);
        }
Exemplo n.º 15
0
        internal void OpenKey(IntPtr hKey,
                              string lpSubKey,
                              int ulOptions,
                              Win32Api.KeySecurity samDesired,
                              out IntPtr phkResult)
        {
            // ulOptions are ignored as this is a reserved parameter
            phkResult = IntPtr.Zero;
            KeySecurity keySecurity;

            Win32Api.RegWow64Options wowOptions;
            KeySecurity.ExtractWow64Options(samDesired, out keySecurity, out wowOptions);
            KeyIdentity baseIdentity = GetKey(hKey).Identity;

            OpenKey(baseIdentity, new KeyIdentity(baseIdentity, wowOptions, lpSubKey),
                    keySecurity, out phkResult);
        }
Exemplo n.º 16
0
 private static bool CheckSystemKeyAccess(KeyDisposition disposition,
                                          KeyIdentity identity, KeySecurity samDesired)
 {
     // This way we redirect system registry locations into windows registry
     // and make it fail for write operations
     if (disposition != KeyDisposition.WINDOWS_REG &&
         identity.IsSystemKey())
     {
         if (samDesired.IsOnlyForRead())
         {
             // So that it retries to read from system registry
             return(false);
         }
         // So that user gets appropriate error code
         throw new AccessDeniedException();
     }
     return(true);
 }
Exemplo n.º 17
0
        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();
        }
Exemplo n.º 18
0
        // Returns keyImpl owned by cache, thus KeyHolder is not used
        public IKeyImpl TryGet(KeyIdentity identity, KeyDisposition disposition, KeySecurity samDesired)
        {
            lock (this)
            {
                CacheKey cacheKey = new CacheKey {
                    Identity = identity, Disposition = disposition
                };
                if (!cachedKeyImpls_.ContainsKey(cacheKey))
                {
                    return(null);
                }

                KeyImplHolder cached = cachedKeyImpls_[cacheKey];
                if (!samDesired.IsSubSetOf(cached.GetKeyImpl().GetAccessMode()))
                {
                    return(null);
                }

                return(cached.GetKeyImpl());
            }
        }
Exemplo n.º 19
0
        private bool TryGetSubKey(KeyDisposition disposition, string lpSubKey,
                                  KeySecurity samDesired, Win32Api.RegWow64Options wowOptions, out KeyImplHolder subKeyHolder)
        {
            KeyIdentity subKeyIdentity = new KeyIdentity(identity_, wowOptions, lpSubKey);
            IKeyImpl    keyImpl        = cachedKeyImpls_.TryGet(subKeyIdentity, disposition, samDesired);

            if (keyImpl != null)
            {
                subKeyHolder = new NotOwningKeyImplHolder(keyImpl);
                return(true);
            }
            KeyImplHolder newOne;

            if (!opener_.TryOpenHolder(identity_, disposition, subKeyIdentity, samDesired, out newOne))
            {
                subKeyHolder = null;
                return(false);
            }
            subKeyHolder = cachedKeyImpls_.Add(subKeyIdentity, disposition, newOne);
            return(true);
        }
Exemplo n.º 20
0
        internal void CreateKey(IntPtr hKey,
                                string lpSubKey,
                                int Reserved,
                                string lpClass,
                                Win32Api.RegOption dwOptions,
                                Win32Api.KeySecurity samDesired,
                                IntPtr lpSecurityAttributes,
                                out IntPtr phkResult,
                                IntPtr lpdwDisposition)
        {
            phkResult = IntPtr.Zero;
            // Reserved is ignored as this is a reserved parameter

            try
            {
                OpenKey(hKey, lpSubKey, 0, samDesired, out phkResult);
                if (lpdwDisposition != IntPtr.Zero)
                {
                    Marshal.WriteInt32(lpdwDisposition,
                                       (int)Win32Api.RegKeyDisposition.REG_OPENED_EXISTING_KEY);
                }
                return;
            }
            catch (FileNotFoundException) {}
            KeySecurity keySecurity;

            Win32Api.RegWow64Options wowOptions;
            KeySecurity.ExtractWow64Options(samDesired, out keySecurity, out wowOptions);
            VirtualKey key = factory_.CreateKey(
                new KeyIdentity(GetKey(hKey).Identity, wowOptions, lpSubKey), lpClass, dwOptions,
                lpSecurityAttributes);

            if (lpdwDisposition != IntPtr.Zero)
            {
                Marshal.WriteInt32(lpdwDisposition,
                                   (int)Win32Api.RegKeyDisposition.REG_CREATED_NEW_KEY);
            }
            phkResult = keyStorage_.Add(key);
        }
Exemplo n.º 21
0
        private void OpenWindowsBaseKey(IntPtr windowsBaseKey,
                                        KeySecurity samDesired, out IntPtr phkResult)
        {
            // There are two options:
            // 1. Opening for reading -> we create and return windows key, which is
            // closed by user call to RegCloseKey
            // 2. Opening for writing -> we call RegOpenCurrentUser so that
            // if a subkey is opened for reading, it is under the right branch
            // and we open OffReg key and return it.

            try
            {
                OpenKey(null, new KeyIdentity(windowsBaseKey), samDesired,
                        out phkResult);
            }
            catch (Exception)
            {
                // If something went wrong, we keep responsibility for closing the key
                Win32Api.RegCloseKey(windowsBaseKey);
                throw;
            }
        }
Exemplo n.º 22
0
        public static bool TryOpen(KeyIdentity identity, KeySecurity samDesired, out WindowsKey openedImpl)
        {
            if (identity.GetRegPath() == null)
            {
                // This works fine because baseKey is always one of the predefined
                // registry keys, so its handle does not need to be duplicated
                // or closed
                openedImpl = new WindowsKey(identity.BaseKey, samDesired);
                return(true);
            }
            IntPtr handle;
            int    result = Win32Api.RegOpenKeyEx(identity.BaseKey, identity.GetRegPath(), 0,
                                                  samDesired.Value | (Win32Api.KeySecurity)identity.GetWow64Mode(),
                                                  out handle);

            openedImpl = null;
            if (!Win32Exception.CheckIfFoundAndNoError(result))
            {
                return(false);
            }
            openedImpl = new WindowsKey(handle, samDesired);
            return(true);
        }
Exemplo n.º 23
0
        // 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);
        }
Exemplo n.º 24
0
/*
 *      public KeyImplHolder OpenHolder(KeyDisposition disposition,
 *          KeyIdentity identity, KeySecurity samDesired)
 *      {
 *          KeyImplHolder result;
 *          if (!TryOpenHolder(disposition, identity, samDesired, out result))
 *              throw new FileNotFoundException();
 *          return result;
 *      }
 */
        public bool TryOpenHolder(KeyIdentity existingBase, KeyDisposition disposition,
                                  KeyIdentity identity, KeySecurity samDesired, out KeyImplHolder openedHolder)
        {
            openedHolder = null;
            // ATTENTION: it is not clear if this function works fine if
            // lpSubKey == null is given for a predefined key, may be it will fail
            // trying to close the predefined key or something. Check later.

            // This way we redirect system registry locations into windows registry
            // and make it fail for write operations
            if (!CheckSystemKeyAccess(disposition, identity, samDesired))
            {
                return(false);
            }

            CheckReadOnlyHivesAccess(disposition, samDesired);

            IKeyImpl registryKey;

            if (disposition != KeyDisposition.DIFF_HIVE)
            {
                if (!TryOpen(existingBase, disposition, identity, samDesired, out registryKey))
                {
                    return(false);
                }
            }
            else
            {
                if (!TryOpenOrCreateDiffKey(existingBase, identity, samDesired, out registryKey))
                {
                    return(false);
                }
            }
            openedHolder = new KeyImplHolder(registryKey);
            return(true);
        }
Exemplo n.º 25
0
 private WindowsKey(IntPtr handle, KeySecurity samDesired)
 {
     handle_     = handle;
     accessMode_ = samDesired;
 }
Exemplo n.º 26
0
 // Opens virtual key not for regular operation, but just
 // when RegOpen*/RegCreate* is called, so access checking is not so strict
 // as for operation
 // TODO: don't check security access mode on open,
 // make just a reg function call check it
 internal VirtualKey OpenKeyPreliminarily(KeyIdentity existingBase, KeyIdentity identity, KeySecurity samDesired)
 {
     foreach (KeyDisposition disposition in VirtualKey.HIVES_ORDER)
     {
         try
         {
             VirtualKey key;
             if (TryOpenKey(existingBase, disposition, identity, samDesired, out key))
             {
                 return(key);
             }
             // Key not found
             if (!samDesired.IsOnlyForRead())
             {
                 // Key not present in reghive and write access requested
                 // we can't give it in hives other than DIFF_HIVE
                 throw new FileNotFoundException();
             }
         }
         catch (AccessDeniedException)
         {
             if (!identity.IsSystemKey() || disposition == KeyDisposition.WINDOWS_REG)
             {
                 // Access denied in reghive (may happen if key is system key)
                 // but if not a system key
                 throw;
             }
         }
         if (identity.IsSystemKey() && !samDesired.IsOnlyForRead())
         {
             // Relaxing access (some apps request write access and do not use it
             // we want to make them work
             samDesired.RelaxToReadAccess();
         }
     }
     throw new FileNotFoundException();
 }