private void DeleteSubKeyTreeInternal(string subkey)
        {
            int errorCode = 0;
            SafeTransactionHandle transactionHandle = this.GetTransactionHandle();
            TransactedRegistryKey key = this.InternalOpenSubKey(subkey, true);

            if (key == null)
            {
                throw new ArgumentException(RegistryProviderStrings.Arg_RegSubKeyAbsent);
            }
            try
            {
                if (key.InternalSubKeyCount() > 0)
                {
                    string[] subKeyNames = key.InternalGetSubKeyNames();
                    for (int i = 0; i < subKeyNames.Length; i++)
                    {
                        key.DeleteSubKeyTreeInternal(subKeyNames[i]);
                    }
                }
            }
            finally
            {
                key.Close();
            }
            errorCode = Microsoft.PowerShell.Commands.Internal.Win32Native.RegDeleteKeyTransacted(this.hkey, subkey, 0, 0, transactionHandle, IntPtr.Zero);
            if (errorCode != 0)
            {
                this.Win32Error(errorCode, null);
            }
        }
        private unsafe TransactedRegistryKey CreateSubKeyInternal(string subkey, RegistryKeyPermissionCheck permissionCheck, object registrySecurityObj)
        {
            ValidateKeyName(subkey);
            if (string.Empty == subkey)
            {
                throw new ArgumentException(RegistryProviderStrings.Arg_RegKeyStrEmpty);
            }
            ValidateKeyMode(permissionCheck);
            this.EnsureWriteable();
            subkey = FixupName(subkey);
            TransactedRegistryKey key = this.InternalOpenSubKey(subkey, permissionCheck != RegistryKeyPermissionCheck.ReadSubTree);

            if (key != null)
            {
                this.CheckSubKeyWritePermission(subkey);
                this.CheckSubTreePermission(subkey, permissionCheck);
                key.checkMode = permissionCheck;
                return(key);
            }
            this.CheckSubKeyCreatePermission(subkey);
            Microsoft.PowerShell.Commands.Internal.Win32Native.SECURITY_ATTRIBUTES structure = null;
            TransactedRegistrySecurity security = registrySecurityObj as TransactedRegistrySecurity;

            if (security != null)
            {
                structure = new Microsoft.PowerShell.Commands.Internal.Win32Native.SECURITY_ATTRIBUTES {
                    nLength = Marshal.SizeOf(structure)
                };
                byte[] securityDescriptorBinaryForm = security.GetSecurityDescriptorBinaryForm();
                byte * pDest = stackalloc byte[securityDescriptorBinaryForm.Length];
                Microsoft.PowerShell.Commands.Internal.Buffer.memcpy(securityDescriptorBinaryForm, 0, pDest, 0, securityDescriptorBinaryForm.Length);
                structure.pSecurityDescriptor = pDest;
            }
            int lpdwDisposition         = 0;
            SafeRegistryHandle hkResult = null;
            int errorCode = 0;
            SafeTransactionHandle transactionHandle = this.GetTransactionHandle();

            errorCode = Microsoft.PowerShell.Commands.Internal.Win32Native.RegCreateKeyTransacted(this.hkey, subkey, 0, null, 0, GetRegistryKeyAccess(permissionCheck != RegistryKeyPermissionCheck.ReadSubTree), structure, out hkResult, out lpdwDisposition, transactionHandle, IntPtr.Zero);
            if ((errorCode == 0) && !hkResult.IsInvalid)
            {
                TransactedRegistryKey key2 = new TransactedRegistryKey(hkResult, permissionCheck != RegistryKeyPermissionCheck.ReadSubTree, false, Transaction.Current, transactionHandle);
                this.CheckSubTreePermission(subkey, permissionCheck);
                key2.checkMode = permissionCheck;
                if (subkey.Length == 0)
                {
                    key2.keyName = this.keyName;
                    return(key2);
                }
                key2.keyName = this.keyName + @"\" + subkey;
                return(key2);
            }
            if (errorCode != 0)
            {
                this.Win32Error(errorCode, this.keyName + @"\" + subkey);
            }
            return(null);
        }
        public void DeleteSubKey(string subkey, bool throwOnMissingSubKey)
        {
            ValidateKeyName(subkey);
            this.EnsureWriteable();
            subkey = FixupName(subkey);
            this.CheckSubKeyWritePermission(subkey);
            TransactedRegistryKey key = this.InternalOpenSubKey(subkey, false);

            if (key != null)
            {
                try
                {
                    if (key.InternalSubKeyCount() > 0)
                    {
                        throw new InvalidOperationException(RegistryProviderStrings.InvalidOperation_RegRemoveSubKey);
                    }
                }
                finally
                {
                    key.Close();
                }
                int errorCode = 0;
                SafeTransactionHandle transactionHandle = this.GetTransactionHandle();
                errorCode = Microsoft.PowerShell.Commands.Internal.Win32Native.RegDeleteKeyTransacted(this.hkey, subkey, 0, 0, transactionHandle, IntPtr.Zero);
                switch (errorCode)
                {
                case 0:
                    return;

                case 2:
                    if (throwOnMissingSubKey)
                    {
                        throw new ArgumentException(RegistryProviderStrings.ArgumentException_RegSubKeyAbsent);
                    }
                    return;
                }
                this.Win32Error(errorCode, null);
            }
            else if (throwOnMissingSubKey)
            {
                throw new ArgumentException(RegistryProviderStrings.ArgumentException_RegSubKeyAbsent);
            }
        }
        public void DeleteSubKeyTree(string subkey)
        {
            ValidateKeyName(subkey);
            if ((string.IsNullOrEmpty(subkey) || (subkey.Length == 0)) && this.IsSystemKey())
            {
                throw new ArgumentException(RegistryProviderStrings.ArgRegKeyDelHive);
            }
            this.EnsureWriteable();
            int errorCode = 0;
            SafeTransactionHandle transactionHandle = this.GetTransactionHandle();

            subkey = FixupName(subkey);
            this.CheckSubTreeWritePermission(subkey);
            TransactedRegistryKey key = this.InternalOpenSubKey(subkey, true);

            if (key == null)
            {
                throw new ArgumentException(RegistryProviderStrings.Arg_RegSubKeyAbsent);
            }
            try
            {
                if (key.InternalSubKeyCount() > 0)
                {
                    string[] subKeyNames = key.InternalGetSubKeyNames();
                    for (int i = 0; i < subKeyNames.Length; i++)
                    {
                        key.DeleteSubKeyTreeInternal(subKeyNames[i]);
                    }
                }
            }
            finally
            {
                key.Close();
            }
            errorCode = Microsoft.PowerShell.Commands.Internal.Win32Native.RegDeleteKeyTransacted(this.hkey, subkey, 0, 0, transactionHandle, IntPtr.Zero);
            if (errorCode != 0)
            {
                this.Win32Error(errorCode, null);
            }
        }
        internal TransactedRegistryKey InternalOpenSubKey(String name, bool writable)
        {
            ValidateKeyName(name);
            EnsureNotDisposed();

            int winAccess = GetRegistryKeyAccess(writable);
            SafeRegistryHandle result = null;
            int ret = 0;
            SafeTransactionHandle safeTransactionHandle = GetTransactionHandle();

            ret = RegOpenKeyTransactedWrapper(_hkey, name, 0, winAccess, out result, safeTransactionHandle, IntPtr.Zero);

            if (ret == 0 && !result.IsInvalid)
            {
                TransactedRegistryKey key = new TransactedRegistryKey(result, writable, false, Transaction.Current, safeTransactionHandle);
                key._keyName = _keyName + "\\" + name;
                return key;
            }
            return null;
        }
        private TransactedRegistryKey InternalOpenSubKey(String name, RegistryKeyPermissionCheck permissionCheck, int rights)
        {
            ValidateKeyName(name);
            ValidateKeyMode(permissionCheck);
            ValidateKeyRights(rights);
            EnsureNotDisposed();
            name = FixupName(name); // Fixup multiple slashes to a single slash

            CheckOpenSubKeyPermission(name, permissionCheck);
            SafeRegistryHandle result = null;
            int ret = 0;

            SafeTransactionHandle safeTransactionHandle = GetTransactionHandle();

            ret = RegOpenKeyTransactedWrapper(_hkey, name, 0, rights, out result, safeTransactionHandle, IntPtr.Zero);

            if (ret == 0 && !result.IsInvalid)
            {
                TransactedRegistryKey key = new TransactedRegistryKey(result, (permissionCheck == RegistryKeyPermissionCheck.ReadWriteSubTree), false,
                                                                      Transaction.Current, safeTransactionHandle);
                key._keyName = _keyName + "\\" + name;
                key._checkMode = permissionCheck;
                return key;
            }

            // Return null if we didn't find the key.
            if (ret == Win32Native.ERROR_ACCESS_DENIED || ret == Win32Native.ERROR_BAD_IMPERSONATION_LEVEL)
            {
                // We need to throw SecurityException here for compatibility reason,
                // although UnauthorizedAccessException will make more sense.
                throw new SecurityException(RegistryProviderStrings.Security_RegistryPermission);
            }

            return null;
        }
        /**
         * Retrieves a new TransactedRegistryKey that represents the requested key. Valid
         * values are:
         *
         * HKEY_CLASSES_ROOT,
         * HKEY_CURRENT_USER,
         * HKEY_LOCAL_MACHINE,
         * HKEY_USERS,
         * HKEY_PERFORMANCE_DATA,
         * HKEY_CURRENT_CONFIG,
         * HKEY_DYN_DATA.
         *
         * @param hKey HKEY_* to open.
         *
         * @return the TransactedRegistryKey requested.
         */
        internal static TransactedRegistryKey GetBaseKey(IntPtr hKey)
        {
            int index = ((int)hKey) & 0x0FFFFFFF;
            BCLDebug.Assert(index >= 0 && index < s_hkeyNames.Length, "index is out of range!");
            BCLDebug.Assert((((int)hKey) & 0xFFFFFFF0) == 0x80000000, "Invalid hkey value!");

            SafeRegistryHandle srh = new SafeRegistryHandle(hKey, false);

            // For Base keys, there is no transaction associated with the HKEY.
            TransactedRegistryKey key = new TransactedRegistryKey(srh, true, true, null, null);
            key._checkMode = RegistryKeyPermissionCheck.Default;
            key._keyName = s_hkeyNames[index];
            return key;
        }
        private unsafe TransactedRegistryKey CreateSubKeyInternal(String subkey, RegistryKeyPermissionCheck permissionCheck, object registrySecurityObj)
        {
            ValidateKeyName(subkey);
            // RegCreateKeyTransacted requires a non-empty key name, so let's deal with that here.
            if (string.Empty == subkey)
            {
                throw new ArgumentException(RegistryProviderStrings.Arg_RegKeyStrEmpty);
            }

            ValidateKeyMode(permissionCheck);
            EnsureWriteable();
            subkey = FixupName(subkey); // Fixup multiple slashes to a single slash

            // only keys opened under read mode is not writable
            TransactedRegistryKey existingKey = InternalOpenSubKey(subkey, (permissionCheck != RegistryKeyPermissionCheck.ReadSubTree));
            if (existingKey != null)
            { // Key already exits
                CheckSubKeyWritePermission(subkey);
                CheckSubTreePermission(subkey, permissionCheck);
                existingKey._checkMode = permissionCheck;
                return existingKey;
            }

            CheckSubKeyCreatePermission(subkey);

            Win32Native.SECURITY_ATTRIBUTES secAttrs = null;
            TransactedRegistrySecurity registrySecurity = registrySecurityObj as TransactedRegistrySecurity;
            // For ACL's, get the security descriptor from the RegistrySecurity.
            if (registrySecurity != null)
            {
                secAttrs = new Win32Native.SECURITY_ATTRIBUTES();
                secAttrs.nLength = (int)Marshal.SizeOf(secAttrs);

                byte[] sd = registrySecurity.GetSecurityDescriptorBinaryForm();
                // We allocate memory on the stack to improve the speed.
                // So this part of code can't be refactored into a method.
                byte* pSecDescriptor = stackalloc byte[sd.Length];
                Microsoft.PowerShell.Commands.Internal.Buffer.memcpy(sd, 0, pSecDescriptor, 0, sd.Length);
                secAttrs.pSecurityDescriptor = pSecDescriptor;
            }
            int disposition = 0;

            // By default, the new key will be writable.
            SafeRegistryHandle result = null;
            int ret = 0;
            SafeTransactionHandle safeTransactionHandle = GetTransactionHandle();

            ret = Win32Native.RegCreateKeyTransacted(_hkey,
                subkey,
                0,
                null,
                0,
                GetRegistryKeyAccess(permissionCheck != RegistryKeyPermissionCheck.ReadSubTree),
                secAttrs,
                out result,
                out disposition,
                safeTransactionHandle,
                IntPtr.Zero
                );

            if (ret == 0 && !result.IsInvalid)
            {
                TransactedRegistryKey key = new TransactedRegistryKey(result, (permissionCheck != RegistryKeyPermissionCheck.ReadSubTree), false,
                                                                      Transaction.Current, safeTransactionHandle);
                CheckSubTreePermission(subkey, permissionCheck);
                key._checkMode = permissionCheck;

                if (subkey.Length == 0)
                    key._keyName = _keyName;
                else
                    key._keyName = _keyName + "\\" + subkey;
                return key;
            }
            else if (ret != 0) // syscall failed, ret is an error code.
                Win32Error(ret, _keyName + "\\" + subkey);  // Access denied?

            BCLDebug.Assert(false, "Unexpected code path in RegistryKey::CreateSubKey");
            return null;
        }
Example #9
0
 internal TransactedRegistryWrapper(TransactedRegistryKey txRegKey, CmdletProvider provider)
 {
     _txRegKey = txRegKey;
     _provider = provider;
 }
Example #10
0
 private unsafe TransactedRegistryKey CreateSubKeyInternal(string subkey, RegistryKeyPermissionCheck permissionCheck, object registrySecurityObj)
 {
     ValidateKeyName(subkey);
     if (string.Empty == subkey)
     {
         throw new ArgumentException(RegistryProviderStrings.Arg_RegKeyStrEmpty);
     }
     ValidateKeyMode(permissionCheck);
     this.EnsureWriteable();
     subkey = FixupName(subkey);
     TransactedRegistryKey key = this.InternalOpenSubKey(subkey, permissionCheck != RegistryKeyPermissionCheck.ReadSubTree);
     if (key != null)
     {
         this.CheckSubKeyWritePermission(subkey);
         this.CheckSubTreePermission(subkey, permissionCheck);
         key.checkMode = permissionCheck;
         return key;
     }
     this.CheckSubKeyCreatePermission(subkey);
     Microsoft.PowerShell.Commands.Internal.Win32Native.SECURITY_ATTRIBUTES structure = null;
     TransactedRegistrySecurity security = registrySecurityObj as TransactedRegistrySecurity;
     if (security != null)
     {
         structure = new Microsoft.PowerShell.Commands.Internal.Win32Native.SECURITY_ATTRIBUTES {
             nLength = Marshal.SizeOf(structure)
         };
         byte[] securityDescriptorBinaryForm = security.GetSecurityDescriptorBinaryForm();
         byte* pDest = stackalloc byte[securityDescriptorBinaryForm.Length];
         Microsoft.PowerShell.Commands.Internal.Buffer.memcpy(securityDescriptorBinaryForm, 0, pDest, 0, securityDescriptorBinaryForm.Length);
         structure.pSecurityDescriptor = pDest;
     }
     int lpdwDisposition = 0;
     SafeRegistryHandle hkResult = null;
     int errorCode = 0;
     SafeTransactionHandle transactionHandle = this.GetTransactionHandle();
     errorCode = Microsoft.PowerShell.Commands.Internal.Win32Native.RegCreateKeyTransacted(this.hkey, subkey, 0, null, 0, GetRegistryKeyAccess(permissionCheck != RegistryKeyPermissionCheck.ReadSubTree), structure, out hkResult, out lpdwDisposition, transactionHandle, IntPtr.Zero);
     if ((errorCode == 0) && !hkResult.IsInvalid)
     {
         TransactedRegistryKey key2 = new TransactedRegistryKey(hkResult, permissionCheck != RegistryKeyPermissionCheck.ReadSubTree, false, Transaction.Current, transactionHandle);
         this.CheckSubTreePermission(subkey, permissionCheck);
         key2.checkMode = permissionCheck;
         if (subkey.Length == 0)
         {
             key2.keyName = this.keyName;
             return key2;
         }
         key2.keyName = this.keyName + @"\" + subkey;
         return key2;
     }
     if (errorCode != 0)
     {
         this.Win32Error(errorCode, this.keyName + @"\" + subkey);
     }
     return null;
 }