Ejemplo n.º 1
0
        private bool ContainsRegistryValue(string name)
        {
            int type     = 0;
            int datasize = 0;
            int retval   = Win32Native.RegQueryValueEx(hkey, name, null, ref type, (byte[])null, ref datasize);

            return(retval == 0);
        }
Ejemplo n.º 2
0
        internal object InternalGetValue(string name, object defaultValue, bool doNotExpand, bool checkSecurity)
        {
            if (checkSecurity)
            {
                // Name can be null!  It's the most common use of RegQueryValueEx
                EnsureNotDisposed();
            }

            object data     = defaultValue;
            int    type     = 0;
            int    datasize = 0;

            int ret = Win32Native.RegQueryValueEx(_hkey, name, null, ref type, (byte[])null, ref datasize);

            if (ret != 0)
            {
                if (IsPerfDataKey())
                {
                    int size      = 65000;
                    int sizeInput = size;

                    int    r;
                    byte[] blob = new byte[size];
                    while (Interop.Errors.ERROR_MORE_DATA == (r = Win32Native.RegQueryValueEx(_hkey, name, null, ref type, blob, ref sizeInput)))
                    {
                        if (size == int.MaxValue)
                        {
                            // ERROR_MORE_DATA was returned however we cannot increase the buffer size beyond int.MaxValue
                            Win32Error(r, name);
                        }
                        else if (size > (int.MaxValue / 2))
                        {
                            // at this point in the loop "size * 2" would cause an overflow
                            size = int.MaxValue;
                        }
                        else
                        {
                            size *= 2;
                        }
                        sizeInput = size;
                        blob      = new byte[size];
                    }
                    if (r != 0)
                    {
                        Win32Error(r, name);
                    }
                    return(blob);
                }
                else
                {
                    // For stuff like ERROR_FILE_NOT_FOUND, we want to return null (data).
                    // Some OS's returned ERROR_MORE_DATA even in success cases, so we
                    // want to continue on through the function.
                    if (ret != Interop.Errors.ERROR_MORE_DATA)
                    {
                        return(data);
                    }
                }
            }

            if (datasize < 0)
            {
                // unexpected code path
                Debug.Fail("[InternalGetValue] RegQueryValue returned ERROR_SUCCESS but gave a negative datasize");
                datasize = 0;
            }


            switch (type)
            {
            case Win32Native.REG_NONE:
            case Win32Native.REG_DWORD_BIG_ENDIAN:
            case Win32Native.REG_BINARY:
            {
                byte[] blob = new byte[datasize];
                ret  = Win32Native.RegQueryValueEx(_hkey, name, null, ref type, blob, ref datasize);
                data = blob;
            }
            break;

            case Win32Native.REG_QWORD:
            {            // also REG_QWORD_LITTLE_ENDIAN
                if (datasize > 8)
                {
                    // prevent an AV in the edge case that datasize is larger than sizeof(long)
                    goto case Win32Native.REG_BINARY;
                }
                long blob = 0;
                Debug.Assert(datasize == 8, "datasize==8");
                // Here, datasize must be 8 when calling this
                ret = Win32Native.RegQueryValueEx(_hkey, name, null, ref type, ref blob, ref datasize);

                data = blob;
            }
            break;

            case Win32Native.REG_DWORD:
            {            // also REG_DWORD_LITTLE_ENDIAN
                if (datasize > 4)
                {
                    // prevent an AV in the edge case that datasize is larger than sizeof(int)
                    goto case Win32Native.REG_QWORD;
                }
                int blob = 0;
                Debug.Assert(datasize == 4, "datasize==4");
                // Here, datasize must be four when calling this
                ret = Win32Native.RegQueryValueEx(_hkey, name, null, ref type, ref blob, ref datasize);

                data = blob;
            }
            break;

            case Win32Native.REG_SZ:
            {
                if (datasize % 2 == 1)
                {
                    // handle the case where the registry contains an odd-byte length (corrupt data?)
                    try
                    {
                        datasize = checked (datasize + 1);
                    }
                    catch (OverflowException e)
                    {
                        throw new IOException(SR.Arg_RegGetOverflowBug, e);
                    }
                }
                char[] blob = new char[datasize / 2];

                ret = Win32Native.RegQueryValueEx(_hkey, name, null, ref type, blob, ref datasize);
                if (blob.Length > 0 && blob[blob.Length - 1] == (char)0)
                {
                    data = new string(blob, 0, blob.Length - 1);
                }
                else
                {
                    // in the very unlikely case the data is missing null termination,
                    // pass in the whole char[] to prevent truncating a character
                    data = new string(blob);
                }
            }
            break;

            case Win32Native.REG_EXPAND_SZ:
            {
                if (datasize % 2 == 1)
                {
                    // handle the case where the registry contains an odd-byte length (corrupt data?)
                    try
                    {
                        datasize = checked (datasize + 1);
                    }
                    catch (OverflowException e)
                    {
                        throw new IOException(SR.Arg_RegGetOverflowBug, e);
                    }
                }
                char[] blob = new char[datasize / 2];

                ret = Win32Native.RegQueryValueEx(_hkey, name, null, ref type, blob, ref datasize);

                if (blob.Length > 0 && blob[blob.Length - 1] == (char)0)
                {
                    data = new string(blob, 0, blob.Length - 1);
                }
                else
                {
                    // in the very unlikely case the data is missing null termination,
                    // pass in the whole char[] to prevent truncating a character
                    data = new string(blob);
                }

                if (!doNotExpand)
                {
                    data = Environment.ExpandEnvironmentVariables((string)data);
                }
            }
            break;

            case Win32Native.REG_MULTI_SZ:
            {
                if (datasize % 2 == 1)
                {
                    // handle the case where the registry contains an odd-byte length (corrupt data?)
                    try
                    {
                        datasize = checked (datasize + 1);
                    }
                    catch (OverflowException e)
                    {
                        throw new IOException(SR.Arg_RegGetOverflowBug, e);
                    }
                }
                char[] blob = new char[datasize / 2];

                ret = Win32Native.RegQueryValueEx(_hkey, name, null, ref type, blob, ref datasize);

                // make sure the string is null terminated before processing the data
                if (blob.Length > 0 && blob[blob.Length - 1] != (char)0)
                {
                    try
                    {
                        char[] newBlob = new char[checked (blob.Length + 1)];
                        for (int i = 0; i < blob.Length; i++)
                        {
                            newBlob[i] = blob[i];
                        }
                        newBlob[newBlob.Length - 1] = (char)0;
                        blob = newBlob;
                    }
                    catch (OverflowException e)
                    {
                        throw new IOException(SR.Arg_RegGetOverflowBug, e);
                    }
                    blob[blob.Length - 1] = (char)0;
                }


                IList <string> strings = new List <string>();
                int            cur     = 0;
                int            len     = blob.Length;

                while (ret == 0 && cur < len)
                {
                    int nextNull = cur;
                    while (nextNull < len && blob[nextNull] != (char)0)
                    {
                        nextNull++;
                    }

                    if (nextNull < len)
                    {
                        Debug.Assert(blob[nextNull] == (char)0, "blob[nextNull] should be 0");
                        if (nextNull - cur > 0)
                        {
                            strings.Add(new string(blob, cur, nextNull - cur));
                        }
                        else
                        {
                            // we found an empty string.  But if we're at the end of the data,
                            // it's just the extra null terminator.
                            if (nextNull != len - 1)
                            {
                                strings.Add(string.Empty);
                            }
                        }
                    }
                    else
                    {
                        strings.Add(new string(blob, cur, len - cur));
                    }
                    cur = nextNull + 1;
                }

                data = new string[strings.Count];
                strings.CopyTo((string[])data, 0);
            }
            break;

            case Win32Native.REG_LINK:
            default:
                break;
            }

            return(data);
        }