public DebugOutputRedirection(TempleLibrary library, Settings settings)
        {
            _active = settings.DebuggingOutput;

            _regOpenKeyExDelegate    = new RegOpenKeyExDelegate(RegOpenKeyExHook);
            _regQueryValueExDelegate = new RegQueryValueExDelegate(RegQueryValueExHook);
            _regCloseKeyDelegate     = new RegCloseKeyDelegate(RegCloseKeyHook);

            library.ImportAddressTable.ReplaceFunction("advapi32.dll", "RegOpenKeyExA", _regOpenKeyExDelegate);
            library.ImportAddressTable.ReplaceFunction("advapi32.dll", "RegQueryValueExA", _regQueryValueExDelegate);
            library.ImportAddressTable.ReplaceFunction("advapi32.dll", "RegCloseKey", _regCloseKeyDelegate);
        }
        /// <summary>
        /// Patches the loaded temple.dll library with the given settings.
        /// </summary>
        /// <param name="filename">Path to the temple.dll that should be used.</param>
        /// <param name="settings">The settings to use for starting the game.</param>
        /// <exception cref="Exception"></exception>
        public static void Start(string filename, Settings settings)
        {
            using (var library = new TempleLibrary(filename))
            {
                if (!library.Valid)
                {
                    throw new Exception(string.Format(
                                            "Unable to start the game. Cannot load the game library {0}: {1}", filename, library.Error));
                }

                // Test code that just overwrites the prototype of the first animal companion to 1000
                var animalCompanions = library.ReadStructure <AnimalCompanionList>(0x2EF14C);
                animalCompanions.Prototypes[0] = 1000;
                library.WriteStructure(0x2EF14C, animalCompanions);

                using (new DebugOutputRedirection(library, settings))
                {
                    using (new FilesystemRedirector(library, settings))
                    {
                        library.StartGame(settings);
                    }
                }
            }
        }
        public FilesystemRedirector(TempleLibrary library, Settings settings)
        {
            _settings = settings;

            LoadRedirections(settings);
            InitializeDelegates();

            var iat = library.ImportAddressTable;

            var tioHandle = Win32Api.GetModuleHandle("tio.dll");
            var tioIat    = new ImportAddressTable(tioHandle);

            var binkHandle = Win32Api.GetModuleHandle("binkw32.dll");
            var binkIat    = new ImportAddressTable(binkHandle);

            var msvcrHandle = Win32Api.GetModuleHandle("msvcr71.dll");
            var msvcrIat    = new ImportAddressTable(msvcrHandle);

            var pythonHandle = Win32Api.GetModuleHandle("pyToEE22.dll");
            var pythonIat    = new ImportAddressTable(pythonHandle);

            var pathAddImport = iat.GetImportedFunction("tio.dll", "tio_path_add");
            var tioPathAdd    = Win32Api.GetProcAddress(tioHandle, "tio_path_add");

            _originalTioPathAdd = (TioPathAdd)Marshal.GetDelegateForFunctionPointer(tioPathAdd,
                                                                                    typeof(TioPathAdd));
            pathAddImport.ReplaceFunction(_tioPathAdd);

            /*
             * iat.ReplaceFunction("kernel32.dll", "CreateFileA", _createFileDelegate);
             * tioIat.ReplaceFunction("kernel32.dll", "CreateFileA", _createFileDelegate);
             * binkIat.ReplaceFunction("kernel32.dll", "CreateFileA", _createFileDelegate);
             * msvcrIat.ReplaceFunction("kernel32.dll", "CreateFileA", _createFileDelegate);
             *
             * iat.ReplaceFunction("kernel32.dll", "CloseHandle", _closeHandleDelegate);
             * tioIat.ReplaceFunction("kernel32.dll", "CloseHandle", _closeHandleDelegate);
             * binkIat.ReplaceFunction("kernel32.dll", "CloseHandle", _closeHandleDelegate);
             * msvcrIat.ReplaceFunction("kernel32.dll", "CloseHandle", _closeHandleDelegate);
             *
             * tioIat.ReplaceFunction("kernel32.dll", "ReadFile", _readFileDelegate);
             * iat.ReplaceFunction("kernel32.dll", "ReadFile", _readFileDelegate);
             * binkIat.ReplaceFunction("kernel32.dll", "ReadFile", _readFileDelegate);
             * msvcrIat.ReplaceFunction("kernel32.dll", "ReadFile", _readFileDelegate);
             *
             * tioIat.ReplaceFunction("kernel32.dll", "GetFileType", _getFileTypeDelegate);
             * iat.ReplaceFunction("kernel32.dll", "GetFileType", _getFileTypeDelegate);
             * binkIat.ReplaceFunction("kernel32.dll", "GetFileType", _getFileTypeDelegate);
             * msvcrIat.ReplaceFunction("kernel32.dll", "GetFileType", _getFileTypeDelegate);
             *
             * tioIat.ReplaceFunction("kernel32.dll", "SetFilePointer", _setFilePointerDelegate);
             * iat.ReplaceFunction("kernel32.dll", "SetFilePointer", _setFilePointerDelegate);
             * binkIat.ReplaceFunction("kernel32.dll", "SetFilePointer", _setFilePointerDelegate);
             * msvcrIat.ReplaceFunction("kernel32.dll", "SetFilePointer", _setFilePointerDelegate);
             *
             * tioIat.ReplaceFunction("kernel32.dll", "SetEndOfFile", _setEndOfFileDelegate);
             * iat.ReplaceFunction("kernel32.dll", "SetEndOfFile", _setEndOfFileDelegate);
             * msvcrIat.ReplaceFunction("kernel32.dll", "SetEndOfFile", _setEndOfFileDelegate);
             *
             * tioIat.ReplaceFunction("kernel32.dll", "GetFileInformationByHandle", _getFileInformationByHandleDelegate);
             * msvcrIat.ReplaceFunction("kernel32.dll", "GetFileInformationByHandle", _getFileInformationByHandleDelegate);
             *
             * iat.ReplaceFunction("kernel32.dll", "FindFirstFileA", _findFirstFile);
             * tioIat.ReplaceFunction("kernel32.dll", "FindFirstFileA", _findFirstFile);
             * tioIat.ReplaceFunction("kernel32.dll", "FindNextFileA", _findNextFile);
             * tioIat.ReplaceFunction("kernel32.dll", "FindClose", _findClose);
             *
             * msvcrIat.ReplaceFunction("kernel32.dll", "FindFirstFileA", _findFirstFile);
             * msvcrIat.ReplaceFunction("kernel32.dll", "FindNextFileA", _findNextFile);
             * msvcrIat.ReplaceFunction("kernel32.dll", "FindClose", _findClose);
             *
             * pythonIat.ReplaceFunction("kernel32.dll", "FindFirstFileA", _findFirstFile);
             * pythonIat.ReplaceFunction("kernel32.dll", "FindNextFileA", _findNextFile);
             * pythonIat.ReplaceFunction("kernel32.dll", "FindClose", _findClose);
             *
             * tioIat.ReplaceFunction("kernel32.dll", "CreateDirectoryA", _createDirectoryDelegate);
             *
             * tioIat.ReplaceFunction("kernel32.dll", "DeleteFileA", _deleteFileDelegate);
             *
             * tioIat.ReplaceFunction("kernel32.dll", "RemoveDirectoryA", _removeDirectoryDelegate);
             *
             * tioIat.ReplaceFunction("kernel32.dll", "MoveFileA", _moveFileDelegate);
             *
             * tioIat.ReplaceFunction("kernel32.dll", "GetFileAttributesA", _getFileAttributesDelegate);
             * msvcrIat.ReplaceFunction("kernel32.dll", "GetFileAttributesA", _getFileAttributesDelegate);*/

            /*
             * var dllPath = Path.Combine(settings.InstallationDirectory, "7z.dll");
             * SevenZipBase.SetLibraryPath(dllPath);
             *
             * if (settings.MountedArchives.Count > 0)
             * {
             *  var archivePath = settings.MountedArchives[0];
             *  _extractor = new SevenZipExtractor(archivePath);
             *
             *  foreach (var entry in _extractor.ArchiveFileData)
             *  {
             *      var filename = NormalizeFileName(entry.FileName);
             *      _archiveFiles.Add(filename, entry.Index);
             *  }
             * }*/
        }