static bool WriteImportFile(IntPtr hMpq, string impFile, List <ImportFile> fileList) { var data = GenImpFile(fileList); if (data == null) { return(StormLib.SFileRemoveFile(hMpq, impFile, 0u)); } var buffer = Marshal.AllocHGlobal(data.Length); Marshal.Copy(data, 0, buffer, data.Length); var result = true; IntPtr hFile; if (result &= StormLib.SFileCreateFile(hMpq, impFile, 0ul, (uint)data.Length, 0u, 0x80000200u, out hFile)) { result &= StormLib.SFileWriteFile(hFile, buffer, (uint)data.Length, 0x2u); } if (result &= (hFile != IntPtr.Zero)) { result &= StormLib.SFileFinishFile(hFile); } Marshal.FreeHGlobal(buffer); return(result); }
static List <ImportFile> ReadImportFile(IntPtr hMpq, string impFile) { List <ImportFile> result = null; IntPtr hFile; if (StormLib.SFileOpenFileEx(hMpq, impFile, 0u, out hFile)) { var fSize = StormLib.SFileGetFileSize(hFile, 0u); if (fSize < 0xFFFFFFFFu) { var buffer = Marshal.AllocHGlobal((int)fSize); if (StormLib.SFileReadFile(hFile, buffer, fSize, 0u, IntPtr.Zero)) { int offset = 0; var version = Marshal.ReadInt32(buffer, offset); if (version < 2) { offset += sizeof(int); var fileCount = Marshal.ReadInt32(buffer, offset); offset += sizeof(int); result = new List <ImportFile>(fileCount); for (int i = 0; i < fileCount; i++) { var bt = (version > 0) && ((Marshal.ReadByte(buffer, offset++) & 1) > 0); var strLen = SeekStrLen(buffer, offset, fSize); var data = new byte[strLen]; Marshal.Copy(buffer + offset, data, 0, data.Length); offset += strLen + 1; result.Add(new ImportFile(Encoding.UTF8.GetString(data), bt)); } } } Marshal.FreeHGlobal(buffer); } else { result = new List <ImportFile>(); } } if (hFile != IntPtr.Zero) { StormLib.SFileCloseFile(hFile); } return(result); }
static string DetectImpFile(IntPtr hMpq) { string impFile = null; for (int i = 0; (i < archTypes.Length) && (impFile == null); i++) { var archType = archTypes[i]; IntPtr hFile; if (StormLib.SFileOpenFileEx(hMpq, archType.DetectFile, 0u, out hFile) && (StormLib.SFileGetFileSize(hFile, 0u) < 0xFFFFFFFFu)) { impFile = archType.ImpFile; } if (hFile != IntPtr.Zero) { StormLib.SFileCloseFile(hFile); } } return(impFile); }
public static List <ImportFile> GetImportList(string mapPath) { List <ImportFile> result = null; IntPtr hMpq; if (StormLib.SFileOpenArchive(mapPath, 0u, 0u, out hMpq)) { var impFile = DetectImpFile(hMpq); if (impFile != null) { result = ReadImportFile(hMpq, impFile); } } if (hMpq != IntPtr.Zero) { StormLib.SFileCloseArchive(hMpq); } return(result); }
public static void Export(string mapPath, List <ImportFile> fileList, string destPath) { IntPtr hMpq; if (StormLib.SFileOpenArchive(mapPath, 0u, 0u, out hMpq)) { for (int i = 0; i < fileList.Count; i++) { var file = fileList[i]; if (!string.IsNullOrEmpty(file.OrigPath)) { var fp = Path.Combine(destPath, file.FilePath); Directory.CreateDirectory(Path.GetDirectoryName(fp)); StormLib.SFileExtractFile(hMpq, file.OrigPath, fp, 0u); } } } if (hMpq != IntPtr.Zero) { StormLib.SFileCloseArchive(hMpq); } }
public static SaveResult SaveImportList(string mapPath, List <ImportFile> fileList) { var result = new SaveResult(); var saved = true; IntPtr hMpq; if (saved &= StormLib.SFileOpenArchive(mapPath, 0u, 0u, out hMpq)) { var hashtableSize = 32u; var fileCount = (uint)fileList.Count + hashtableSize; while (hashtableSize < fileCount) { hashtableSize *= 2; } StormLib.SFileSetMaxFileCount(hMpq, hashtableSize); var failedFiles = new List <string>(); for (int i = 0; (i < fileList.Count) && saved; i++) { var file = fileList[i]; if (file.Deleted) { StormLib.SFileRemoveFile(hMpq, file.OrigPath, 0u); } else if (file.Changed) { if (string.IsNullOrEmpty(file.DiskPath)) { StormLib.SFileRenameFile(hMpq, file.OrigPath, file.FilePath); } else { StormLib.SFileRemoveFile(hMpq, file.OrigPath, 0u); if (!StormLib.SFileAddFileEx(hMpq, file.DiskPath, file.FilePath, 0x80000200u, 0x2u, 0x2u)) { failedFiles.Add(file.DiskPath); file.Deleted = true; } } } } result.FailedFiles = failedFiles; var impFile = DetectImpFile(hMpq); if (saved &= (impFile != null)) { saved &= WriteImportFile(hMpq, impFile, fileList); } StormLib.SFileCompactArchive(hMpq, null, false); } if (saved &= (hMpq != IntPtr.Zero)) { saved &= StormLib.SFileCloseArchive(hMpq); } result.Saved = saved; return(result); }