public override unsafe NtStatus NtSetInformationFileImpl(IntPtr hfile, out IO_STATUS_BLOCK ioStatusBlock, void *fileInformation, uint length, FileInformationClass fileInformationClass) { if (fileInformationClass == FileInformationClass.FilePositionInformation) { var pack = mPacksByHandle[hfile]; pack.FilePointer = *( long * )fileInformation; mLogger.Debug($"{pack.Instance.FileName} Hnd: {hfile} SetFilePointer -> 0x{pack.FilePointer:X8}"); } else { mLogger.Warning($"SetInformationFileImpl(hfile = {hfile}, out ioStatusBlock, fileInformation = *0x{( long )fileInformation:X8}, " + $"length = {length}, fileInformationClass = {fileInformationClass}"); } mHooks.NtSetInformationFileHook.OriginalFunction(hfile, out ioStatusBlock, fileInformation, length, fileInformationClass); // Spoof return value as we extend beyond the end of the file return(NtStatus.Success); }
private bool ParseTxth(string path) { using (var reader = new StreamReader(path)) { var txth = new ParsedTxth(); while (!reader.EndOfStream) { var line = reader.ReadLine(); var kvp = line.Split("=", StringSplitOptions.RemoveEmptyEntries); var key = kvp[0].Trim(); var value = kvp[1].Trim(); int temp = 0; switch (key) { case "num_samples": if (!int.TryParse(value, out temp)) { return(false); } txth.Duration = temp; break; case "codec": switch (value) { case "PCM16LE": txth.FormatTag = WaveBankMiniFormatTag.PCM; txth.BitDepth = WaveBankMiniFormatBitDepth._16; break; case "PCM8": txth.FormatTag = WaveBankMiniFormatTag.PCM; txth.BitDepth = WaveBankMiniFormatBitDepth._8; break; case "XMA2": txth.FormatTag = WaveBankMiniFormatTag.XMA; break; case "MSADPCM": txth.FormatTag = WaveBankMiniFormatTag.ADPCM; break; case "XWMA": txth.FormatTag = WaveBankMiniFormatTag.WMA; break; default: mLogger.Error($"Unsupported codec ({value})"); return(false); } break; case "channels": if (!int.TryParse(value, out temp)) { return(false); } txth.Channels = temp; break; case "sample_rate": if (!int.TryParse(value, out temp)) { return(false); } txth.SampleRate = temp; break; case "interleave": if (!int.TryParse(value, out temp)) { return(false); } txth.Interleave = temp; break; case "loop_start_sample": if (!int.TryParse(value, out temp)) { return(false); } txth.LoopStart = temp; break; case "loop_end_sample": if (!int.TryParse(value, out temp)) { return(false); } txth.LoopEnd = temp; break; default: mLogger.Error($"{path} Unrecognized TXTH command: {key} = {value}"); break; } } if (!txth.Duration.HasValue) { mLogger.Error($"{path} num_samples is not set!"); return(false); } if (!txth.FormatTag.HasValue) { mLogger.Error($"{path} codec is not set!"); return(false); } if (!txth.Channels.HasValue) { mLogger.Error($"{path} channels is not set!"); return(false); } if (!txth.SampleRate.HasValue) { mLogger.Error($"{path} sample_rate is not set!"); return(false); } if (!txth.Interleave.HasValue) { mLogger.Error($"{path} interleave is not set!"); return(false); } if (txth.LoopStart.HasValue && !txth.LoopEnd.HasValue) { // Set end loop sample to the duration if it is somehow missing txth.LoopEnd = txth.Duration; } // Set settings Native->Format.FormatTag.Set(txth.FormatTag.Value); Native->Format.BitsPerSample.Set(txth.BitDepth.GetValueOrDefault(0)); Native->Format.Channels.Set(txth.Channels.Value); Native->Format.SamplesPerSecond.Set(txth.SampleRate.Value); Native->Format.CalculatedBlockAlign = txth.Interleave.Value; var durationAligned = WaveBankFormatHelper.AlignSamples(Native->Format.FormatTag.Get(), txth.Duration.Value, Native->Format.CalculatedBlockAlign, Native->Format.Channels); if (txth.LoopStart.HasValue) { var startSampleAligned = WaveBankFormatHelper.AlignSamples(Native->Format.FormatTag.Get(), txth.LoopStart.Value, Native->Format.CalculatedBlockAlign, Native->Format.Channels); var startSampleAlignedDiff = startSampleAligned - txth.LoopStart.Value; var endSampleAligned = WaveBankFormatHelper.AlignSamples(Native->Format.FormatTag.Get(), txth.LoopEnd.Value + startSampleAlignedDiff, Native->Format.CalculatedBlockAlign, Native->Format.Channels); var endSampleAlignedOff = endSampleAligned - txth.LoopEnd.Value; if (startSampleAlignedDiff > 0) { mLogger.Warning($"{path} Loop start sample is not aligned properly, it may not loop correctly ingame!"); } if (endSampleAlignedOff > 0) { mLogger.Warning($"{path} Loop end sample is not aligned properly, it may not loop correctly ingame!"); } Native->LoopRegion.StartSample = startSampleAligned; Native->LoopRegion.TotalSamples = endSampleAligned - startSampleAligned; if (endSampleAligned > durationAligned) { durationAligned = endSampleAligned; } } else { Native->LoopRegion.StartSample = 0; Native->LoopRegion.TotalSamples = 0; } if (durationAligned > txth.Duration) { mLogger.Warning($"[{path} Duration is not aligned properly, it may not play correctly ingame!"); } Native->FlagsAndDuration.Duration.Set(( uint )durationAligned); } return(true); }