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); } }
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); } }
internal static void ConvertException(Win32Exception.Operation operation) { try { operation(); } catch (System.ComponentModel.Win32Exception e) { throw Win32Exception.Create(e.NativeErrorCode); } }
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)); } }
// 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); }
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); } }
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); }
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); }
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; }