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); } }
internal static KeyInfo QueryInfo(this IKey key) { using (HGlobalPtr lpcClass = new HGlobalPtr(Marshal.SizeOf(typeof(int)))) { Marshal.WriteInt32(lpcClass.Ptr, 0); try { key.QueryInfo(IntPtr.Zero, lpcClass.Ptr, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero); } catch (Win32Exception ex) { if (ex.ErrorCode != (int)Win32Api.Error.ERROR_MORE_DATA) { throw; } } int cClass = Marshal.ReadInt32(lpcClass.Ptr) + 1; Marshal.WriteInt32(lpcClass.Ptr, cClass); using (HGlobalPtr lpClass = new HGlobalPtr(cClass * sizeof(char)), lpReserved = new HGlobalPtr(IntPtr.Zero), lpcSubKeys = new HGlobalPtr(sizeof(int)), lpcMaxSubKeyLen = new HGlobalPtr(sizeof(int)), lpcMaxClassLen = new HGlobalPtr(sizeof(int)), lpcValues = new HGlobalPtr(sizeof(int)), lpcMaxValueNameLen = new HGlobalPtr(sizeof(int)), lpcMaxValueLen = new HGlobalPtr(sizeof(int)), lpcSecurityDescriptor = new HGlobalPtr(sizeof(int)), lpftLastWriteTime = new HGlobalPtr(2 * sizeof(int))) { key.QueryInfo( lpClass.Ptr, lpcClass.Ptr, lpReserved.Ptr, lpcSubKeys.Ptr, lpcMaxSubKeyLen.Ptr, lpcMaxClassLen.Ptr, lpcValues.Ptr, lpcMaxValueNameLen.Ptr, lpcMaxValueLen.Ptr, lpcSecurityDescriptor.Ptr, lpftLastWriteTime.Ptr); int classLength = Marshal.ReadInt32(lpcClass.Ptr); Win32Api.FILETIME lastWriteTime = (Win32Api.FILETIME)Marshal.PtrToStructure(lpftLastWriteTime.Ptr, typeof(Win32Api.FILETIME)); KeyInfo info; info.Class = DataTransformer.PtrToString(lpClass.Ptr, classLength); info.SubKeysNumber = unchecked ((uint)Marshal.ReadInt32(lpcSubKeys.Ptr)); info.MaxSubKeyLength = unchecked ((uint)Marshal.ReadInt32(lpcMaxSubKeyLen.Ptr)); info.MaxClassLength = unchecked ((uint)Marshal.ReadInt32(lpcMaxClassLen.Ptr)); info.ValuesNumber = unchecked ((uint)Marshal.ReadInt32(lpcValues.Ptr)); info.MaxValueNameLength = unchecked ((uint)Marshal.ReadInt32(lpcMaxValueNameLen.Ptr)); info.MaxValueLength = unchecked ((uint)Marshal.ReadInt32(lpcMaxValueLen.Ptr)); info.SecurityDescriptorLength = unchecked ((uint)Marshal.ReadInt32(lpcSecurityDescriptor.Ptr)); info.LastWriteTime = lastWriteTime; return(info); } } }