public void DeleteValue(string lpValueName) { int result = OffRegHive.CatchException(() => key_.DeleteValue(lpValueName)); hive_.MarkAsModified(); Win32Exception.CheckResult(result); }
// Create key and if needed all parent keys private OffregLib.OffregKey CreateKeys(OffregLib.OffregHive hiveImpl, string path, string lpClass, Win32Api.RegOption dwOptions, IntPtr lpSecurityDescriptor, IntPtr lpdwDisposition) { OffregLib.OffregKey result = null; try { OffRegHive.ConvertException(() => result = hiveImpl.Root.OpenSubKey(path)); return(result); } catch (FileNotFoundException) { } // We either take the first subkey of the path, or the last string parentPath, subkey; if (KeyIdentity.PartitionPath(path, out parentPath, out subkey)) { OffregLib.OffregKey parentKey = CreateKeys(hiveImpl, parentPath, lpClass, dwOptions, lpSecurityDescriptor, lpdwDisposition); OffRegHive.ConvertException(() => parentKey.Close()); } // TODO: do something with lpClass, lpSecurityDescriptor, for now they are ignored OffRegHive.ConvertException(() => result = hiveImpl.Root.CreateSubKey( path, (OffregLib.RegOption)dwOptions)); if (lpdwDisposition != IntPtr.Zero) { Marshal.WriteInt32(lpdwDisposition, (int)Win32Api.RegKeyDisposition.REG_CREATED_NEW_KEY); } // TODO: if there is an existing key in windows registry, but we create one // in offreg hive, which disposition do we need to return? return(result); }
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: Actually a much more complex implementation of QeryInfoKeyA, // traversing through all values and handling strings in a special way // is required for exact MaxValueLen value calculation taking // into account unicode->ansi conversion. // For now we return a bigger value, still enough to allocate buffers // (length of unicode values is always larger than length of ansi ones). using (Uni2AnsiConverter classConverter = new Uni2AnsiConverter(new Data(lpClass, lpcClass, Data.CountIn.Chars), DoUni2AnsiConversion)) { OffRegHive.ConvertException(() => key_.QueryInfoUnmanaged( classConverter.UnicodeStr, lpcClass, lpcSubKeys, lpcbMaxSubKeyLen, lpcbMaxClassLen, lpcValues, lpcbMaxValueNameLen, lpcbMaxValueLen, lpcbSecurityDescriptor, lpftLastWriteTime)); classConverter.Convert(); } }
public void Delete() { int result = OffRegHive.CatchException(() => key_.Delete()); hive_.MarkAsModified(); Win32Exception.CheckResult(result); }
public void SetValue( string lpValueName, Win32Api.RegValueType dwType, IntPtr lpData, int cbData) { int result; if (!DoUni2AnsiConversion || !DataTransformer.IsStringType(dwType)) { result = OffRegHive.CatchException(() => key_.SetValueUnmanaged(lpValueName, (OffregLib.RegValueType)dwType, lpData, cbData)); hive_.MarkAsModified(); Win32Exception.CheckResult(result); return; } string str = Marshal.PtrToStringAnsi(lpData, cbData); using (HGlobalPtr pStr = new HGlobalPtr(Marshal.StringToHGlobalUni(str))) { result = OffRegHive.CatchException(() => key_.SetValueUnmanaged(lpValueName, (OffregLib.RegValueType)dwType, pStr.Ptr, cbData * sizeof(char))); hive_.MarkAsModified(); Win32Exception.CheckResult(result); } }
internal OffRegKey(OffRegHive hive, OffregLib.OffregHive hiveImpl, KeyIdentity identity, string lpClass, Win32Api.RegOption dwOptions, IntPtr lpSecurityDescriptor, IntPtr lpdwDisposition) { hive_ = hive; identity_ = identity; key_ = CreateKeys(hiveImpl, GetMainOffRegPath(identity), lpClass, dwOptions, lpSecurityDescriptor, lpdwDisposition); }
internal VirtualKeyFactory(string baseHivePath, string diffHivePath, DataAlterer alterer) { // It is allowed for tests that base hive is not used if (baseHivePath != null) { baseHive_ = new OffRegHive(KeyDisposition.BASE_HIVE, baseHivePath); } diffHive_ = new OffRegHive(KeyDisposition.DIFF_HIVE, diffHivePath, readOnly: false); alterer_ = alterer; }
protected override void DisposeManaged() { if (baseHive_ != null) { baseHive_.Dispose(); baseHive_ = null; } if (diffHive_ != null) { diffHive_.Dispose(); diffHive_ = null; } }
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 EnumKey( uint dwIndex, IntPtr lpName, /*ref UInt32*/ IntPtr lpcchName, IntPtr lpReserved, IntPtr lpClass, /*ref UInt32*/ IntPtr lpcchClass, /*ref Win32Api.FILETIME*/ IntPtr lpftLastWriteTime) { using (Uni2AnsiConverter nameConverter = new Uni2AnsiConverter(new Data(lpName, lpcchName, Data.CountIn.Chars), DoUni2AnsiConversion), classConverter = new Uni2AnsiConverter(new Data(lpClass, lpcchClass, Data.CountIn.Chars), DoUni2AnsiConversion)) { OffRegHive.ConvertException(() => key_.EnumKeyUnmanaged(dwIndex, nameConverter.UnicodeStr, lpcchName, classConverter.UnicodeStr, lpcchClass, lpftLastWriteTime)); nameConverter.Convert(); classConverter.Convert(); } }
internal OffRegKey(OffRegHive hive, OffregLib.OffregKey key, KeyIdentity identity) { hive_ = hive; key_ = key; identity_ = identity; }
public void EnumValue( uint dwIndex, IntPtr lpValueName, /*ref UInt32*/ IntPtr lpcchValueName, IntPtr lpReserved, /*ref Win32Api.RegValueType*/ IntPtr lpType, IntPtr lpData, /*ref UInt32*/ IntPtr lpcbData) { if (!DoUni2AnsiConversion) { OffRegHive.ConvertException(() => key_.EnumValueUnmanaged(dwIndex, lpValueName, lpcchValueName, lpType, lpData, lpcbData)); return; } int cchValueName = 0; if (lpcchValueName != IntPtr.Zero) { cchValueName = Marshal.ReadInt32(lpcchValueName); } using (Uni2AnsiConverter nameConverter = new Uni2AnsiConverter(new Data(lpValueName, lpcchValueName, Data.CountIn.Chars))) { try { Data dst = new Data(lpData, lpcbData, Data.CountIn.Bytes); // Sandboxie-generated reghives might contain REG_SZ values stored in ansi format // we need to detect them and avoid conversion for them if (!DataTransformer.TryAlterData(lpType, dst, (newpdwType, newDst) => { // 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); } return(OffRegHive.CatchException(() => key_.EnumValueUnmanaged( dwIndex, nameConverter.UnicodeStr, lpcchValueName, newpdwType, newDst.Ptr, newDst.PCount))); }, (result, type) => (result == Win32Api.Error.ERROR_SUCCESS || result == Win32Api.Error.ERROR_MORE_DATA) && DataTransformer.IsStringType(type), (type, pSrcData, cbSrcData) => dst.FillWithString(new BytesString(pSrcData, cbSrcData), StringFormat.Ansi, Data.NullCharHandling.NotAddingIfNotPresent))) { throw new FileNotFoundException(); } nameConverter.Convert(); } catch (Win32Exception ex) { if (ex.ErrorCode == (int)Win32Api.Error.ERROR_MORE_DATA) { // Assumming that in case of ERROR_MORE_DATA lpcchValueName is // filled with correct value nameConverter.Convert(); } throw; } } }
public void Close() { OffRegHive.ConvertException(() => key_.Close()); key_ = null; }