aboutsummaryrefslogtreecommitdiff
path: root/src/SFileExtractFile.cpp
blob: 64be8d37c4b33c1ba381ae9a553d33de7a1a3ef0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
/*****************************************************************************/
/* SFileExtractFile.cpp                   Copyright (c) Ladislav Zezula 2003 */
/*---------------------------------------------------------------------------*/
/* Simple extracting utility                                                 */
/*---------------------------------------------------------------------------*/
/*   Date    Ver   Who  Comment                                              */
/* --------  ----  ---  -------                                              */
/* 20.06.03  1.00  Lad  The first version of SFileExtractFile.cpp            */
/*****************************************************************************/

#define __STORMLIB_NO_AUTO_LINK__
#include <StormLib.h>
#include "StormCommon.h"

bool WINAPI SFileExtractFile(HANDLE hMpq, const char * szToExtract, const TCHAR * szExtracted, DWORD dwSearchScope)
{
    TFileStream * pLocalFile = NULL;
    HANDLE hMpqFile = NULL;
    int nError = ERROR_SUCCESS;

    // Open the MPQ file
    if(nError == ERROR_SUCCESS)
    {
        if(!SFileOpenFileEx(hMpq, szToExtract, dwSearchScope, &hMpqFile))
            nError = GetLastError();
    }

    // Create the local file
    if(nError == ERROR_SUCCESS)
    {
        pLocalFile = FileStream_CreateFile(szExtracted, 0);
        if(pLocalFile == NULL)
            nError = GetLastError();
    }

    // Copy the file's content
    while(nError == ERROR_SUCCESS)
    {
        char  szBuffer[0x1000];
        DWORD dwTransferred = 0;

        // dwTransferred is only set to nonzero if something has been read.
        // nError can be ERROR_SUCCESS or ERROR_HANDLE_EOF
        if(!SFileReadFile(hMpqFile, szBuffer, sizeof(szBuffer), &dwTransferred, NULL))
            nError = GetLastError();
        if(nError == ERROR_HANDLE_EOF)
            nError = ERROR_SUCCESS;
        if(dwTransferred == 0)
            break;

        // If something has been actually read, write it
        if(!FileStream_Write(pLocalFile, NULL, szBuffer, dwTransferred))
            nError = GetLastError();
    }

    // Close the files
    if(hMpqFile != NULL)
        SFileCloseFile(hMpqFile);
    if(pLocalFile != NULL)
        FileStream_Close(pLocalFile);
    if(nError != ERROR_SUCCESS)
        SetLastError(nError);
    return (nError == ERROR_SUCCESS);
}