public bool TryGetValue( string lpValue, Win32Api.RegRestrictionFlags dwFlags, /*ref UInt32*/ IntPtr pdwType, IntPtr pvData, /*ref UInt32*/ IntPtr pcbData) { if (!DoUni2AnsiConversion) { return(Win32Exception.CheckIfFoundAndNoError((int)key_.TryGetValueUnmanaged(lpValue, pdwType, pvData, pcbData))); } Data dst = new Data(pvData, pcbData, 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 return(DataTransformer.TryAlterData(pdwType, dst, (newpdwType, newDst) => (int)key_.TryGetValueUnmanaged(lpValue, newpdwType, newDst.Ptr, newDst.PCount), (result, type) => result == Win32Api.Error.ERROR_SUCCESS && DataTransformer.IsStringType(type), (type, pSrcData, cbSrcData) => dst.FillWithString(new BytesString(pSrcData, cbSrcData), StringFormat.Ansi, Data.NullCharHandling.NotAddingIfNotPresent))); }
internal bool TryAlterData(KeyIdentity key, string valueName, IKeyImpl keyImpl, IntPtr pdwType, Data dst, DataTransformer.Operation operation) { // TODO: this is a specific check that // rewrite is done only for values in sandboxie reghive which is BASE_HIVE // and if values are copied, DIFF_HIVE is also supported // It should be put outside this generalized class if (keyImpl.GetDisposition() == KeyDisposition.WINDOWS_REG) { return(Win32Exception.CheckIfFoundAndNoError(operation(pdwType, dst))); } return(DataTransformer.TryAlterData(pdwType, dst, operation, (result, type) => { DebugLogger.WriteLine(@"AlterData {0} {1}\{2} ({3}) Result: {4}", keyImpl.GetDisposition(), key.ToString(), valueName, type, (int)result); return result == Win32Api.Error.ERROR_SUCCESS && DataTransformer.IsStringType(type); }, (type, pSrcData, cbSrcData) => DataTransformer.TransformStringValue( type, pSrcData, cbSrcData, dst, str => CallStrAlterers(key, valueName, str), HookBarrier.IsLastInjectedFuncAnsi ? StringFormat.Ansi : StringFormat.Unicode))); }
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; } } }