Пример #1
0
        internal static void CopyValues(this VirtualRegistry virtualRegistry, VirtualKey sourceKey, KeyInfo sourceKeyInfo, VirtualKey destinationKey)
        {
            using (HGlobalPtr lpValueName = new HGlobalPtr((sourceKeyInfo.MaxValueNameLength + 1) * sizeof(char)),
                   lpcValueName = new HGlobalPtr(sizeof(int)),
                   lpReserved = new HGlobalPtr(IntPtr.Zero),
                   lpdwType = new HGlobalPtr(sizeof(int)),
                   lpvData = new HGlobalPtr(sourceKeyInfo.MaxValueLength),
                   lpcData = new HGlobalPtr(sizeof(int)))
            {
                for (uint i = 0; i < sourceKeyInfo.ValuesNumber; ++i)
                {
                    Marshal.WriteInt32(lpcValueName.Ptr, unchecked ((int)sourceKeyInfo.MaxValueNameLength) + 1);
                    Marshal.WriteInt32(lpcData.Ptr, unchecked ((int)sourceKeyInfo.MaxValueLength));
                    sourceKey.EnumValue(i, lpValueName.Ptr, lpcValueName.Ptr, lpReserved.Ptr, lpdwType.Ptr, lpvData.Ptr,
                                        lpcData.Ptr);

                    Win32Api.RegValueType valueType = (Win32Api.RegValueType)Marshal.ReadInt32(lpdwType.Ptr);

                    int currentValueLength     = Marshal.ReadInt32(lpcData.Ptr);
                    int currentValueNameLength = Marshal.ReadInt32(lpcValueName.Ptr);

                    string currentValueName = Marshal.PtrToStringUni(lpValueName.Ptr, currentValueNameLength);

                    destinationKey.SetValue(null, currentValueName, 0, valueType, lpvData.Ptr, currentValueLength);
                }
            }
        }
Пример #2
0
        // TODO: query info does not take data altering into account,
        // data may be replaced by some larger data and this may lead to
        // buffer overflow in client's code
        public void QueryInfo(
            /*out StringBuilder*/ IntPtr lpClass,
            /*ref */ IntPtr lpcClass,
            IntPtr lpReserved,
            /*out */ IntPtr lpcSubKeys,
            /*out */ IntPtr lpcbMaxSubKeyLen,
            /*out */ IntPtr lpcbMaxClassLen,
            /*out */ IntPtr lpcValues,
            /*out */ IntPtr lpcbMaxValueNameLen,
            /*out */ IntPtr lpcbMaxValueLen,
            /*out */ IntPtr lpcbSecurityDescriptor,
            IntPtr lpftLastWriteTime)
        {
            // TODO: this function does not take into accout the intersection
            // of subkey names between windows regisry key and offreg key, and
            // the same thing about value names, 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 both of them

            // if the class or security descriptor is defined for both of keys and are
            // different, then the values of windows registry keys just take priority.

            // TODO: during implementation of RegSetSecurity* probably the logic should be
            // changed to take security descriptor from OffReg key if it is there
            bool    callSucceeded = false;
            KeyInfo result        = new KeyInfo();

            foreach (KeyDisposition disposition in HIVES_REVERSE_ORDER)
            {
                KeyInfo current = new KeyInfo();
                if (!TryApplyOperation(disposition, null,
                                       new KeySecurity(Win32Api.KeySecurity.KEY_QUERY_VALUE),
                                       keyImpl =>
                {
                    current = keyImpl.QueryInfo();
                    return(true);
                }))
                {
                    continue;
                }

                // Taking class and security descriptor from higher level (windows registry)
                // if possible, this is subject to change as soon as Reg*Security functions
                // are implemented
                if (!callSucceeded)
                {
                    result.Class = current.Class;
                    result.SecurityDescriptorLength = current.SecurityDescriptorLength;
                }

                callSucceeded = true;

                result.SubKeysNumber  += current.SubKeysNumber;
                result.MaxSubKeyLength = Math.Max(result.MaxSubKeyLength,
                                                  current.MaxSubKeyLength);
                result.MaxClassLength = Math.Max(result.MaxClassLength,
                                                 current.MaxClassLength);
                result.ValuesNumber      += current.ValuesNumber;
                result.MaxValueNameLength = Math.Max(result.MaxValueNameLength,
                                                     current.MaxValueNameLength);
                result.MaxValueLength = Math.Max(result.MaxValueLength,
                                                 current.MaxValueLength);
                if (DateTime.FromFileTime(result.LastWriteTime.AsLong) <
                    DateTime.FromFileTime(current.LastWriteTime.AsLong))
                {
                    result.LastWriteTime = current.LastWriteTime;
                }
            }
            // At least one of windows or OffReg key exists (because it is open
            // and passed as hKey to this function), so at least one of calls did not return
            // FILE_NOT_FOUND, thus suppressing it here

            if (lpcSubKeys != IntPtr.Zero)
            {
                Marshal.WriteInt32(lpcSubKeys, unchecked ((int)result.SubKeysNumber));
            }
            if (lpcbMaxSubKeyLen != IntPtr.Zero)
            {
                Marshal.WriteInt32(lpcbMaxSubKeyLen, unchecked ((int)result.MaxSubKeyLength));
            }
            if (lpcbMaxClassLen != IntPtr.Zero)
            {
                Marshal.WriteInt32(lpcbMaxClassLen, unchecked ((int)result.MaxClassLength));
            }
            if (lpcValues != IntPtr.Zero)
            {
                Marshal.WriteInt32(lpcValues, unchecked ((int)result.ValuesNumber));
            }
            if (lpcbMaxValueNameLen != IntPtr.Zero)
            {
                Marshal.WriteInt32(lpcbMaxValueNameLen, unchecked ((int)result.MaxValueNameLength));
            }
            if (lpcbMaxValueLen != IntPtr.Zero)
            {
                Marshal.WriteInt32(lpcbMaxValueLen, unchecked ((int)result.MaxValueLength));
            }
            if (lpftLastWriteTime != IntPtr.Zero)
            {
                Marshal.StructureToPtr(result.LastWriteTime, lpftLastWriteTime, true);
            }
            Win32Exception.CheckResult(
                new Data(lpClass, lpcClass, Data.CountIn.Chars).FillWithString(
                    new ManagedString(result.Class),
                    HookBarrier.IsLastInjectedFuncAnsi ? StringFormat.Ansi : StringFormat.Unicode,
                    Data.NullCharHandling.NotCountingOnReturn));
        }
Пример #3
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;
 }