Exemple #1
0
    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);
    }
Exemple #2
0
    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);
    }
Exemple #3
0
    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);
    }
Exemple #4
0
    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);
    }
Exemple #5
0
    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);
        }
    }
Exemple #6
0
    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);
    }