예제 #1
0
        /**
         * Retrieves an array of strings containing all the value names.
         *
         * @return all value names.
         */
        public unsafe String[] GetValueNames()
        {
            CheckPermission(RegistryInternalCheck.CheckKeyReadPermission, null, false, RegistryKeyPermissionCheck.Default);
            EnsureNotDisposed();

            int values = InternalValueCount();

            String[] names = new String[values];

            if (values > 0)
            {
                char[] name = new char[MaxValueLength + 1];
                int    namelen;

                fixed(char *namePtr = &name[0])
                {
                    for (int i = 0; i < values; i++)
                    {
                        namelen = name.Length;

                        int ret = Win32Native.RegEnumValue(hkey,
                                                           i,
                                                           namePtr,
                                                           ref namelen,
                                                           IntPtr.Zero,
                                                           null,
                                                           null,
                                                           null);

                        if (ret != 0)
                        {
                            // ignore ERROR_MORE_DATA if we're querying HKEY_PERFORMANCE_DATA
                            if (!(IsPerfDataKey() && ret == Win32Native.ERROR_MORE_DATA))
                            {
                                Win32Error(ret, null);
                            }
                        }

                        names[i] = new String(namePtr);
                    }
                }
            }

            return(names);
        }
예제 #2
0
파일: RegistryKey.cs 프로젝트: relaxar/.net
        /// <summary>
        /// Retrieves an array of strings containing all the value names.
        /// </summary>
        public unsafe string[] GetValueNames()
        {
            EnsureNotDisposed();
            var names = new List <string>();

            // Names in the registry aren't usually very long, although they can go to as large
            // as 16383 characters (MaxValueLength).
            //
            // Every call to RegEnumValue will allocate another buffer to get the data from
            // NtEnumerateValueKey before copying it back out to our passed in buffer. This can
            // add up quickly- we'll try to keep the memory pressure low and grow the buffer
            // only if needed.

            char[] name = ArrayPool <char> .Shared.Rent(100);

            try
            {
                int result;
                int nameLength = name.Length;

                while ((result = Win32Native.RegEnumValue(
                            _hkey,
                            names.Count,
                            name,
                            ref nameLength,
                            IntPtr.Zero,
                            null,
                            null,
                            null)) != Interop.Errors.ERROR_NO_MORE_ITEMS)
                {
                    switch (result)
                    {
                    // The size is only ever reported back correctly in the case
                    // of ERROR_SUCCESS. It will almost always be changed, however.
                    case Interop.Errors.ERROR_SUCCESS:
                        names.Add(new string(name, 0, nameLength));
                        break;

                    case Interop.Errors.ERROR_MORE_DATA:
                        if (IsPerfDataKey())
                        {
                            // Enumerating the values for Perf keys always returns
                            // ERROR_MORE_DATA, but has a valid name. Buffer does need
                            // to be big enough however. 8 characters is the largest
                            // known name. The size isn't returned, but the string is
                            // null terminated.
                            fixed(char *c = &name[0])
                            {
                                names.Add(new string(c));
                            }
                        }
                        else
                        {
                            char[] oldName   = name;
                            int    oldLength = oldName.Length;
                            name = null;
                            ArrayPool <char> .Shared.Return(oldName);

                            name = ArrayPool <char> .Shared.Rent(checked (oldLength * 2));
                        }
                        break;

                    default:
                        // Throw the error
                        Win32Error(result, null);
                        break;
                    }

                    // Always set the name length back to the buffer size
                    nameLength = name.Length;
                }
            }
            finally
            {
                if (name != null)
                {
                    ArrayPool <char> .Shared.Return(name);
                }
            }

            return(names.ToArray());
        }