コード例 #1
0
        public override Native.NtStatus NtCreateFileImpl(string filePath, out IntPtr handle, FileAccess access,
                                                         ref Native.OBJECT_ATTRIBUTES objectAttributes, ref Native.IO_STATUS_BLOCK ioStatus, ref long allocSize,
                                                         uint fileAttributes, FileShare share, uint createDisposition, uint createOptions, IntPtr eaBuffer, uint eaLength)
        {
            var result = mHooks.NtCreateFileHook.OriginalFunction(out handle, access, ref objectAttributes, ref ioStatus, ref allocSize,
                                                                  fileAttributes, share, createDisposition, createOptions, eaBuffer, eaLength);

            if (!mCpkByName.TryGetValue(filePath, out var cpk))
            {
                mCpkByName[filePath] = cpk = new VirtualCpk(mLogger);

                // Load file
                using (var fileStream = new FileStream(new SafeFileHandle(handle, true), FileAccess.Read, 1024 * 1024))
                    cpk.LoadFromFile(filePath, fileStream);

                // Reopen file to reset it
                result = mHooks.NtCreateFileHook.OriginalFunction(out handle, access, ref objectAttributes, ref ioStatus, ref allocSize,
                                                                  fileAttributes, share, createDisposition, createOptions, eaBuffer, eaLength);

                mLogger.Debug($"Registered {filePath}");

                // Redirect entries to a non-existent pac that will be handled by the DwPack redirector
                cpk.Redirect(mModDb);
            }

            mCpkByHandle[handle] = new VirtualCpkHandle()
            {
                Instance = cpk
            };
            mLogger.Debug($"Hnd {handle} {filePath} handle registered");
            CpkLoaded?.Invoke(this, cpk);
            return(result);
        }
コード例 #2
0
        public bool Redirect(ModDb modDb)
        {
            RedirectAttempted = true;

            foreach (var mod in modDb.Mods)
            {
                var pacRedirectFilePath = Path.Combine(mod.LoadDirectory, Pack.FileName, Native->Path);
                if (mod.Files.Contains(pacRedirectFilePath))
                {
                    // Replacement file stored in folder named after pac file
                    Redirect(pacRedirectFilePath);
                    mLogger.Info($"{Pack.FileName} {Native->Path} Redirected to {pacRedirectFilePath}");
                    return(true);
                }

                if (Pack.Cpk != null)
                {
                    var cpkRedirectFilePath = Path.Combine(mod.LoadDirectory, Pack.Cpk.FileName, Native->Path);
                    if (mod.Files.Contains(cpkRedirectFilePath))
                    {
                        // Replacement file stored in folder named after cpk file
                        Redirect(cpkRedirectFilePath);
                        mLogger.Info($"{Pack.FileName} {Native->Path} Redirected to {cpkRedirectFilePath}");
                        return(true);
                    }
                }

                mLogger.Debug($"No redirection for {Native->Path}.");
            }

            return(false);
        }
コード例 #3
0
        public override Native.NtStatus NtCreateFileImpl(string filePath, out IntPtr handle, FileAccess access,
                                                         ref Native.OBJECT_ATTRIBUTES objectAttributes, ref Native.IO_STATUS_BLOCK ioStatus, ref long allocSize,
                                                         uint fileAttributes, FileShare share, uint createDisposition, uint createOptions, IntPtr eaBuffer, uint eaLength)
        {
            var result = mHooks.NtCreateFileHook.OriginalFunction(out handle, access, ref objectAttributes, ref ioStatus, ref allocSize,
                                                                  fileAttributes, share, createDisposition, createOptions, eaBuffer, eaLength);

            if (!mPacksByName.TryGetValue(filePath, out var pack))
            {
                mPacksByName[filePath] = pack = new VirtualDwPack(mLogger);

                // Load file
                using (var fileStream = new FileStream(new SafeFileHandle(handle, true), FileAccess.Read, 1024 * 1024))
                    pack.LoadFromFile(filePath, fileStream);

                // Reopen file to reset it
                result = mHooks.NtCreateFileHook.OriginalFunction(out handle, access, ref objectAttributes, ref ioStatus, ref allocSize,
                                                                  fileAttributes, share, createDisposition, createOptions, eaBuffer, eaLength);

                mLogger.Debug($"Registered {filePath}");

                // Entries are redirected as needed to improve startup performance
            }

            mPacksByHandle[handle] = pack;
            mLogger.Debug($"Hnd {handle} {filePath} handle registered");
            return(result);
        }
コード例 #4
0
        private void Rebuild(int addedFiles)
        {
            // Write uncompressed CPK
            mLogger.Debug($"{FileName}: Rebuilding");

            var uncompressedSize = (int)(Native.Header->UncompressedSize + (addedFiles * CpkEntry.SIZE));

            using var tempBuf = MemoryPool <byte> .Shared.Rent(uncompressedSize);

            var tempBufSpan = tempBuf.Memory.Span.Slice(0, uncompressedSize);

            mWrapper.Write(tempBufSpan);

            // Compress it
            var comBuffer = (void *)Marshal.AllocHGlobal(uncompressedSize);
            var comSize   = CpkUtil.CompressCpk(tempBufSpan, new Span <byte>(comBuffer, uncompressedSize));

            // Replace old data
            Native.Dispose();
            Native = new CompressedCpkPtr(comBuffer);
        }
コード例 #5
0
        public bool TryRedirect(ModDb modDb)
        {
            RedirectAttempted = true;

            foreach (var mod in modDb.Mods)
            {
                var redirectedFilePath = Path.Combine(mod.LoadDirectory, Pack.FileName, Native->Path);
                if (mod.Files.Contains(redirectedFilePath))
                {
                    Redirect(redirectedFilePath);
                    mLogger.Info($"{Pack.FileName} {Native->Path} Redirected to {redirectedFilePath}");
                    return(true);
                }
                else
                {
                    mLogger.Debug($"No redirection for {Native->Path} because {redirectedFilePath} does not exist.");
                }
            }

            return(false);
        }
コード例 #6
0
        public override Native.NtStatus NtCreateFileImpl(string newFilePath, out IntPtr handle, FileAccess access, ref Native.OBJECT_ATTRIBUTES objectAttributes,
                                                         ref Native.IO_STATUS_BLOCK ioStatus, ref long allocSize, uint fileAttributes, FileShare share, uint createDisposition, uint createOptions, IntPtr eaBuffer, uint eaLength)
        {
            var result = mHooks.NtCreateFileHook.OriginalFunction(out handle, access, ref objectAttributes, ref ioStatus, ref allocSize, fileAttributes,
                                                                  share, createDisposition, createOptions, eaBuffer, eaLength);

            var              fileName   = Path.GetFileNameWithoutExtension(newFilePath);
            var              ext        = Path.GetExtension(newFilePath);
            var              isWaveBank = ext.Equals(".xwb", StringComparison.OrdinalIgnoreCase);
            VirtualWaveBank  waveBank   = null;
            VirtualSoundBank soundBank  = null;

            if (isWaveBank && !mWaveBankByName.TryGetValue(fileName, out waveBank))
            {
                // Try get sound bank for cue names
                mSoundBankByName.TryGetValue(fileName, out soundBank);

                // Wave bank
                mWaveBankByName[fileName] = waveBank = new VirtualWaveBank(mLogger);

                // Load wave bank
                using (var fileStream = new FileStream(new SafeFileHandle(handle, true), FileAccess.Read, 1024 * 1024))
                    waveBank.LoadFromFile(newFilePath, fileStream);

                // Reopen file to reset it
                result = mHooks.NtCreateFileHook.OriginalFunction(out handle, access, ref objectAttributes, ref ioStatus, ref allocSize, fileAttributes,
                                                                  share, createDisposition, createOptions, eaBuffer, eaLength);

                ProcessWaveBankEntries(newFilePath, soundBank, waveBank);
                mLogger.Debug($"{newFilePath} registered");
            }
            else if (!mSoundBankByName.TryGetValue(fileName, out soundBank))
            {
                // Sound bank
                mSoundBankByName[fileName] = soundBank = new VirtualSoundBank(mLogger);

                // Load wave bank
                using (var fileStream = new FileStream(new SafeFileHandle(handle, true), FileAccess.Read, 1024 * 1024))
                    soundBank.LoadFromFile(newFilePath, fileStream);

                // Reopen file to reset it
                result = mHooks.NtCreateFileHook.OriginalFunction(out handle, access, ref objectAttributes, ref ioStatus, ref allocSize, fileAttributes,
                                                                  share, createDisposition, createOptions, eaBuffer, eaLength);

                // Find associated wave bank
                if (!mWaveBankByName.TryGetValue(soundBank.Native.WaveBankNames[0].Name, out waveBank))
                {
                    mLogger.Error($"{newFilePath} Can't find wavebank!");
                }
                else
                {
                    ProcessWaveBankEntries(newFilePath, soundBank, waveBank);
                }
            }

            if (isWaveBank)
            {
                mWaveBankByHandle.Add(handle, waveBank);
                mLogger.Debug($"{waveBank.FileName} Hnd {handle} registered");
            }
            else
            {
                mSoundBankByHandle.Add(handle, soundBank);
            }


            return(result);
        }
コード例 #7
0
        public override Native.NtStatus NtCreateFileImpl(string filePath, out IntPtr handle, FileAccess access,
                                                         ref Native.OBJECT_ATTRIBUTES objectAttributes, ref Native.IO_STATUS_BLOCK ioStatus, ref long allocSize,
                                                         uint fileAttributes, FileShare share, uint createDisposition, uint createOptions, IntPtr eaBuffer, uint eaLength)
        {
            var result = mHooks.NtCreateFileHook.OriginalFunction(out handle, access, ref objectAttributes, ref ioStatus, ref allocSize,
                                                                  fileAttributes, share, createDisposition, createOptions, eaBuffer, eaLength);


            if (!mPacksByName.TryGetValue(filePath, out var pack))
            {
                mPacksByName[filePath] = pack = new VirtualDwPack(mLogger, filePath);

                var pacIndex = int.Parse(pack.FileName.Substring(pack.FileName.Length - 5, 5));
                var cpkName  = pack.FileName.Substring(0, pack.FileName.Length - 5);
                var cpk      = mLoadedCpks.Find(x => x.FileName.Contains(cpkName) && x.Entries.Any(y => y.PacIndex == pacIndex));
                pack.Cpk = cpk;

                if (result != NtStatus.ObjectNameNotFound)
                {
                    // Load file
                    using (var fileStream = new FileStream(new SafeFileHandle(handle, true), FileAccess.Read, 1024 * 1024))
                        pack.LoadFromFile(filePath, fileStream);

                    //pack.AddNewFiles( cpk );

                    // Reopen file to reset it
                    result = mHooks.NtCreateFileHook.OriginalFunction(out handle, access, ref objectAttributes, ref ioStatus, ref allocSize,
                                                                      fileAttributes, share, createDisposition, createOptions, eaBuffer, eaLength);
                }
                else
                {
                    pack.LoadFromCpk(pacIndex, cpk);
                    handle = GenerateHandle();
                    ioStatus.Information = (IntPtr)1;
                    ioStatus.Status      = 0;
                    result = NtStatus.Success;
                }

                mLogger.Debug($"Registered {filePath}");

                // Entries are redirected as needed to improve startup performance
            }
            else if (result == NtStatus.ObjectNameNotFound)
            {
                // Find handle from name
                if (!mHandleByPack.TryGetValue(pack, out handle))
                {
                    handle = GenerateHandle();
                }

                ioStatus.Information = (IntPtr)1;
                ioStatus.Status      = 0;
                result = NtStatus.Success;
            }

            mPacksByHandle[handle] = new VirtualDwPackHandle()
            {
                Instance = pack
            };
            mHandleByPack[pack] = handle;
            mLogger.Debug($"Hnd {handle} {filePath} handle registered");
            return(result);
        }