Exemplo n.º 1
0
        internal static void QueryMultipleValues(
            this VirtualKey key,
            IntPtr val_list,
            UInt32 num_vals,
            IntPtr lpValueBuf,
            IntPtr ldwTotsize)
        {
            // TODO: although the reason RegQueryMultipleValues function exists
            // is to allow atomic reading of multiple values of a key,
            // the current implementation reads them non-atomically, so this is a
            // possible subject to change in the future
            int totalSize = 0;

            if (ldwTotsize != IntPtr.Zero)
            {
                totalSize = Marshal.ReadInt32(ldwTotsize);
            }
            int   usedSize = 0;
            Int64 PTR_SIZE = Marshal.SizeOf(typeof(IntPtr));

            for (uint i = 0; i < num_vals; ++i)
            {
                Int64 pVal = (Int64)val_list + 8 * i + 2 * PTR_SIZE * i;

                IntPtr lpValueName = Marshal.ReadIntPtr((IntPtr)pVal);
                string valueName   = DataTransformer.PtrToString(lpValueName);

                IntPtr pcbData = (IntPtr)(pVal + PTR_SIZE);
                Marshal.WriteInt32(pcbData, Math.Max(0, totalSize - usedSize));

                IntPtr lpData = (lpValueBuf == IntPtr.Zero || usedSize > totalSize) ?
                                IntPtr.Zero :
                                (IntPtr)((Int64)lpValueBuf + usedSize);
                Marshal.WriteIntPtr((IntPtr)(pVal + 4 + PTR_SIZE), lpData);

                IntPtr lpType = (IntPtr)(pVal + 4 + 2 * PTR_SIZE);
                try
                {
                    key.QueryValue(valueName, IntPtr.Zero, lpType, lpData, pcbData);
                }
                catch (Win32Exception ex)
                {
                    if (ex.ErrorCode != (int)Win32Api.Error.ERROR_MORE_DATA)
                    {
                        throw;
                    }
                }
                int valueSize = Marshal.ReadInt32(pcbData);
                usedSize += valueSize;
            }
            if (ldwTotsize != IntPtr.Zero)
            {
                Marshal.WriteInt32(ldwTotsize, usedSize);
            }
            if (usedSize > totalSize)
            {
                throw Win32Exception.Create((int)Win32Api.Error.ERROR_MORE_DATA);
            }
        }
Exemplo n.º 2
0
        public SystemHKeyFactory()
        {
            int result = Win32Api.RegOpenKeyEx((IntPtr)Win32Api.RegPredefinedKeys.HKEY_CURRENT_USER, "Software",
                                               0, Win32Api.KeySecurity.KEY_QUERY_VALUE, out seedHKey_);

            if ((Win32Result)result != Win32Result.ERROR_SUCCESS)
            {
                throw Win32Exception.Create(result);
            }
        }
Exemplo n.º 3
0
 internal static void ConvertException(Win32Exception.Operation operation)
 {
     try
     {
         operation();
     }
     catch (System.ComponentModel.Win32Exception e)
     {
         throw Win32Exception.Create(e.NativeErrorCode);
     }
 }
Exemplo n.º 4
0
 public int Read(IntPtr pData, int cbData)
 {
     using (HGlobalPtr pcbData = new HGlobalPtr(sizeof(int)))
     {
         if (!Win32Api.ReadFile(hFile_, pData, unchecked ((uint)cbData),
                                pcbData.Ptr, IntPtr.Zero))
         {
             throw Win32Exception.Create(unchecked ((int)Win32Api.GetLastError()));
         }
         return(Marshal.ReadInt32(pcbData.Ptr));
     }
 }
Exemplo n.º 5
0
        // TODO: generalize the order in which enumeration operations are performed
        // and create smth like ApplyEnumOperation
        public void EnumKey(
            uint dwIndex,
            IntPtr lpName,
            /*ref UInt32*/ IntPtr lpcchName,
            IntPtr lpReserved,
            IntPtr lpClass,
            /*ref UInt32*/ IntPtr lpcchClass,
            /*ref Win32Api.FILETIME*/ IntPtr lpftLastWriteTime)
        {
            // TODO: this function does not take into accout the intersection
            // of subkey names between windows regisry key and offreg key, this is
            // to be done in a next version

            // It does not matter in which hive the current key is
            // we need to open and enumerate them all
            foreach (KeyDisposition disposition in HIVES_REVERSE_ORDER)
            {
                bool indexHandled = false;
                // Requesting access rights for both RegEnumKey and RegQueryInfoKey operations
                TryApplyOperation(disposition, null,
                                  new KeySecurity(Win32Api.KeySecurity.KEY_ENUMERATE_SUB_KEYS |
                                                  Win32Api.KeySecurity.KEY_QUERY_VALUE), keyImpl =>
                {
                    try
                    {
                        keyImpl.EnumKey(dwIndex, lpName, lpcchName, lpReserved, lpClass,
                                        lpcchClass, lpftLastWriteTime);

                        indexHandled = true;
                    }
                    catch (Win32Exception e)
                    {
                        if (e.ErrorCode != (int)Win32Api.Error.ERROR_NO_MORE_ITEMS)
                        {
                            throw;
                        }
                        uint cSubKeys = keyImpl.QueryInfo().SubKeysNumber;
                        // Assumming here that dwIndex >= cSubKeys, but this might
                        // be false if key has been changed between calls to EnumKey and QueryInfo
                        dwIndex -= cSubKeys;
                    }
                    return(true);
                });
                if (indexHandled)
                {
                    return;
                }
            }
            throw Win32Exception.Create((int)Win32Api.Error.ERROR_NO_MORE_ITEMS);
        }
Exemplo n.º 6
0
 public void CopyTo(IntPtr dst, StringFormat dstFormat)
 {
     // For now only Uni->Ansi conversion is needed
     Debug.Assert(dstFormat == StringFormat.Ansi);
     if (dstFormat != StringFormat.Ansi)
     {
         throw Win32Exception.Create((int)Win32Api.Error.ERROR_INVALID_PARAMETER);
     }
     if (format_ == StringFormat.Unicode)
     {
         PInvokeHelper.StringUniToAnsi(pSrcData_, dst, Length);
     }
     else
     {
         Marshal.Copy(bytes_, 0, dst, bytes_.Length);
     }
 }
Exemplo n.º 7
0
        public static bool TryOpen(OffRegHive hive, OffregLib.OffregHive hiveImpl, KeyIdentity identity, out OffRegKey openedKey)
        {
            // TODO: possibly we need to simulate security restrictions in some way so that,
            // for instance, write operations from app w/o administrative permissions
            // to HKEY_LOCAL_MACHINE hive would fail
            List <string> paths = GetOffRegPaths(identity);

            foreach (string path in paths)
            {
                OffregLib.Win32Result result;
                OffregLib.OffregKey   key;
                if (hiveImpl.Root.TryOpenSubKey(path, out key, out result))
                {
                    openedKey = new OffRegKey(hive, key, identity);
                    return(true);
                }
                if ((int)result != (int)Win32Api.Error.ERROR_FILE_NOT_FOUND)
                {
                    throw Win32Exception.Create((int)result);
                }
            }
            openedKey = null;
            return(false);
        }
Exemplo n.º 8
0
        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);
        }
Exemplo n.º 9
0
 public bool Handle(OffRegKey key)
 {
     // TODO: exceptions thrown from this function should use STATUS_* error codes set
     // instead of ERROR_*
     string name = key.Identity.GetSystemPath();
     KeyInfo info = key.QueryInfo();
     // TODO: either test the following error-prone code with offsets thoroughly
     // or replace it with safer alternative code
     int offset = 0;
     switch (KeyInformationClass_)
     {
         case Win32Api.KeyInformationClass.KeyBasicInformation:
             ResultLength_ = unchecked((uint)(16 + sizeof(char) * name.Length));
             if (Length_ < ResultLength_)
             {
                 throw Win32Exception.Create((int)Win32Api.Status.STATUS_BUFFER_TOO_SMALL);
             }
             if (KeyInformation_ != IntPtr.Zero)
             {
                 Marshal.StructureToPtr(info.LastWriteTime, KeyInformation_, false); offset += 8;
                 Marshal.WriteInt32(KeyInformation_, offset, 0); offset += 4;
                 Marshal.WriteInt32(KeyInformation_, offset, sizeof(char) * name.Length); offset += 4;
                 PInvokeHelper.CopyStringUni(name,
                     (IntPtr)((Int64)KeyInformation_ + offset), name.Length);
             }
             return true;
         case Win32Api.KeyInformationClass.KeyNodeInformation:
             ResultLength_ = unchecked((uint)(24 + sizeof(char) * (name.Length + info.Class.Length)));
             if (Length_ < ResultLength_)
             {
                 throw Win32Exception.Create((int)Win32Api.Status.STATUS_BUFFER_TOO_SMALL);
             }
             if (KeyInformation_ != IntPtr.Zero)
             {
                 // TODO: fill the parts of structures w/o strings using
                 // C# structures (until now I don't know solution for strings, but
                 // at least all other fields will be set carefully)
                 // do this throughout the function
                 Marshal.StructureToPtr(info.LastWriteTime, KeyInformation_, false); offset += 8;
                 Marshal.WriteInt32(KeyInformation_, offset, 0); offset += 4;
                 Marshal.WriteInt32(KeyInformation_, offset,
                     24 + sizeof(char) * name.Length); offset += 4;
                 Marshal.WriteInt32(KeyInformation_, offset,
                     sizeof(char) * info.Class.Length); offset += 4;
                 Marshal.WriteInt32(KeyInformation_, offset,
                     sizeof(char) * name.Length); offset += 4;
                 PInvokeHelper.CopyStringUni(name,
                     (IntPtr)((Int64)KeyInformation_ + offset),
                     name.Length); offset += name.Length * sizeof(char);
                 PInvokeHelper.CopyStringUni(info.Class,
                     (IntPtr)((Int64)KeyInformation_ + offset),
                     info.Class.Length);
             }
             return true;
         case Win32Api.KeyInformationClass.KeyFullInformation:
             ResultLength_ = unchecked((uint)(44 + sizeof(char) * (info.Class.Length)));
             if (Length_ < ResultLength_)
             {
                 throw Win32Exception.Create((int)Win32Api.Status.STATUS_BUFFER_TOO_SMALL);
             }
             if (KeyInformation_ != IntPtr.Zero)
             {
                 Marshal.StructureToPtr(info.LastWriteTime, KeyInformation_, false); offset += 8;
                 Marshal.WriteInt32(KeyInformation_, offset, 0); offset += 4;
                 Marshal.WriteInt32(KeyInformation_, offset, 44); offset += 4;
                 Marshal.WriteInt32(KeyInformation_, offset,
                     sizeof(char) * info.Class.Length); offset += 4;
                 Marshal.WriteInt32(KeyInformation_, offset, unchecked((int)info.SubKeysNumber)); offset += 4;
                 Marshal.WriteInt32(KeyInformation_, offset, unchecked((int)info.MaxSubKeyLength)); offset += 4;
                 Marshal.WriteInt32(KeyInformation_, offset, unchecked((int)info.MaxClassLength)); offset += 4;
                 Marshal.WriteInt32(KeyInformation_, offset, unchecked((int)info.ValuesNumber)); offset += 4;
                 Marshal.WriteInt32(KeyInformation_, offset, unchecked((int)info.MaxValueNameLength)); offset += 4;
                 Marshal.WriteInt32(KeyInformation_, offset, unchecked((int)info.MaxValueLength)); offset += 4;
                 PInvokeHelper.CopyStringUni(info.Class,
                     (IntPtr)((Int64)KeyInformation_ + offset),
                     info.Class.Length);
             }
             return true;
         case Win32Api.KeyInformationClass.KeyNameInformation:
             ResultLength_ = unchecked((uint)(4 + sizeof(char) * name.Length));
             if (Length_ < ResultLength_)
             {
                 throw Win32Exception.Create((int)Win32Api.Status.STATUS_BUFFER_TOO_SMALL);
             }
             if (KeyInformation_ != IntPtr.Zero)
             {
                 Marshal.WriteInt32(KeyInformation_, sizeof(char) * name.Length); offset += 4;
                 PInvokeHelper.CopyStringUni(name,
                     (IntPtr)((Int64)KeyInformation_ + offset), name.Length);
             }
             return true;
         case Win32Api.KeyInformationClass.KeyCachedInformation:
             ResultLength_ = 36;
             if (Length_ < ResultLength_)
             {
                 throw Win32Exception.Create((int)Win32Api.Status.STATUS_BUFFER_TOO_SMALL);
             }
             if (KeyInformation_ != IntPtr.Zero)
             {
                 Marshal.StructureToPtr(info.LastWriteTime, KeyInformation_, false); offset += 8;
                 Marshal.WriteInt32(KeyInformation_, offset, 0); offset += 4;
                 Marshal.WriteInt32(KeyInformation_, offset, unchecked((int)info.SubKeysNumber)); offset += 4;
                 Marshal.WriteInt32(KeyInformation_, offset, unchecked((int)info.MaxSubKeyLength)); offset += 4;
                 Marshal.WriteInt32(KeyInformation_, offset, unchecked((int)info.ValuesNumber)); offset += 4;
                 Marshal.WriteInt32(KeyInformation_, offset, unchecked((int)info.MaxValueNameLength)); offset += 4;
                 Marshal.WriteInt32(KeyInformation_, offset, unchecked((int)info.MaxValueLength)); offset += 4;
                 Marshal.WriteInt32(KeyInformation_, offset, name.Length);
             }
             return true;
         case Win32Api.KeyInformationClass.KeyFlagsInformation:
             // Reserved
             break;
         case Win32Api.KeyInformationClass.KeyVirtualizationInformation:
             // Not implemented
             break;
         case Win32Api.KeyInformationClass.KeyHandleTagsInformation:
             // Reserved
             break;
     }
     return false;
 }