コード例 #1
0
ファイル: System.cpp プロジェクト: ArkaniaTrinityFix/Arkania
void ExtractDBCFiles(int l, bool basicLocale)
{
    printf("Extracting dbc files...\n");

    SFILE_FIND_DATA foundFile;
    memset(&foundFile, 0, sizeof(foundFile));
    HANDLE listFile = SFileFindFirstFile(LocaleMpq, "DBFilesClient\\*dbc", &foundFile, NULL);
    HANDLE dbcFile = NULL;
    uint32 count = 0;
    if (listFile)
    {
        std::string outputPath = output_path;
        outputPath += "/dbc/";

        CreateDir(outputPath);
        if (!basicLocale)
        {
            outputPath += Locales[l];
            outputPath += "/";
            CreateDir(outputPath);
        }

        std::string filename;

        do
        {
            if (!SFileOpenFileEx(LocaleMpq, foundFile.cFileName, SFILE_OPEN_PATCHED_FILE, &dbcFile))
            {
                printf("Unable to open file %s in the archive\n", foundFile.cFileName);
                continue;
            }

            filename = foundFile.cFileName;
            filename = outputPath + filename.substr(filename.rfind('\\'));

            if (FileExists(filename.c_str()))
                continue;

            if (ExtractFile(dbcFile, filename.c_str()))
                ++count;

            SFileCloseFile(dbcFile);
        } while (SFileFindNextFile(listFile, &foundFile));

        SFileFindClose(listFile);
    }

    printf("Extracted %u DBC files\n\n", count);
}
コード例 #2
0
ファイル: SFileVerify.cpp プロジェクト: BinaryMuse/StormLib
static bool QueryMpqSignatureInfo(
    TMPQArchive * ha,
    PMPQ_SIGNATURE_INFO pSI) {
    ULONGLONG ExtraBytes;
    TMPQFile * hf;
    HANDLE hFile;
    DWORD dwFileSize;

    // Calculate the range of the MPQ
    CalculateArchiveRange(ha, pSI);

    // If there is "(signature)" file in the MPQ, it has a weak signature
    if (SFileOpenFileEx((HANDLE)ha, SIGNATURE_NAME, SFILE_OPEN_FROM_MPQ, &hFile)) {
        // Get the content of the signature
        SFileReadFile(hFile, pSI->Signature, sizeof(pSI->Signature), &pSI->cbSignatureSize);

        // Verify the size of the signature
        hf = (TMPQFile *)hFile;

        // We have to exclude the signature file from the digest
        pSI->BeginExclude = ha->MpqPos + hf->pFileEntry->ByteOffset;
        pSI->EndExclude = pSI->BeginExclude + hf->pFileEntry->dwCmpSize;
        dwFileSize = hf->dwDataSize;

        // Close the file
        SFileCloseFile(hFile);
        pSI->nSignatureType = SIGNATURE_TYPE_WEAK;
        return (dwFileSize == (MPQ_WEAK_SIGNATURE_SIZE + 8)) ? true : false;
    }

    // If there is extra bytes beyond the end of the archive,
    // it's the strong signature
    ExtraBytes = pSI->EndOfFile - pSI->EndMpqData;
    if (ExtraBytes >= (MPQ_STRONG_SIGNATURE_SIZE + 4)) {
        // Read the strong signature
        if (!FileStream_Read(ha->pStream, &pSI->EndMpqData, pSI->Signature, (MPQ_STRONG_SIGNATURE_SIZE + 4)))
            return false;

        // Check the signature header "NGIS"
        if (pSI->Signature[0] != 'N' || pSI->Signature[1] != 'G' || pSI->Signature[2] != 'I' || pSI->Signature[3] != 'S')
            return false;

        pSI->nSignatureType = SIGNATURE_TYPE_STRONG;
        return true;
    }

    // Succeeded, but no known signature found
    return true;
}
コード例 #3
0
ファイル: read.cpp プロジェクト: RFDaemoniac/sc2-map-analyzer
int SC2Map::readArchiveFile( const HANDLE archive,
                             const char*  strFilename,
                             int*         bufferOutSize,
                             u8**         bufferOut )
{
  HANDLE hFile;

  if( !SFileOpenFileEx( archive, strFilename, 0, &hFile ) )
  {
    //printWarning( "Could not open %s for reading.\n", strFilename );
    return -1;
  }

  DWORD fileSizeBytes = SFileGetFileSize( hFile, NULL );
  if( fileSizeBytes == SFILE_INVALID_SIZE ||
      fileSizeBytes <= 0 )
  {
    printWarning( "%s is empty or invalid.\n", strFilename );
    return -1;
  }

  u8*   buffer = new u8[fileSizeBytes];
  DWORD numBytesRead;

  // initialize buffer to easily recognized values,
  // after a successful read all of them are overwritten
  memset( buffer, 'q', fileSizeBytes );

  if( !SFileReadFile( hFile, (void*)buffer, fileSizeBytes, &numBytesRead, NULL ) )
  {
    delete buffer;
    printWarning( "Could not read %s from archive.\n", strFilename );
    return -1;
  }

  if( numBytesRead != fileSizeBytes )
  {
    delete buffer;
    printWarning( "Could not read %s from archive. [NOT EXPECTING TO SEE THIS WARNING!]\n", strFilename );
    return -1;
  }

  *bufferOutSize = fileSizeBytes;
  *bufferOut     = buffer;

  SFileCloseFile( hFile );
  return 0;
}
コード例 #4
0
ファイル: MPQ.cpp プロジェクト: Sasho/SkyFireEMU_430
int ExtractFileToHardDrive(HANDLE &MPQ_handle, const char * szArchivedFile, const char * szFileName)
{
    HANDLE hFile  = NULL;          // Archived file handle
    TFileStream* handle = NULL;    // Disk file handle
    int    nError = ERROR_SUCCESS; // Result value
    
    if (nError == ERROR_SUCCESS)            
    {
        if (!SFileOpenFileEx(MPQ_handle, szArchivedFile, SFILE_OPEN_PATCHED_FILE, &hFile))
            nError = GetLastError();
    }
    
    // Create the target file
    if (nError == ERROR_SUCCESS)
    {
        handle = FileStream_CreateFile(szFileName);
        if (handle == NULL)
            nError = GetLastError();
    }
    
    // Read the file from the archive
    if (nError == ERROR_SUCCESS)
    {
        // Get the size of the full patched file
        DWORD dwFileSize = SFileGetFileSize(hFile, NULL);
        if (dwFileSize != 0)
        {
            // Allocate space for the full file
            BYTE * pbFullFile = new BYTE[dwFileSize];
            if (!SFileReadFile(hFile, pbFullFile, dwFileSize))
            {           
                nError = GetLastError();
                printf("Failed to read full patched file data \"%s\"\n", szFileName);
                assert(false);
            }
            FileStream_Write(handle, NULL, pbFullFile, dwFileSize);
            delete [] pbFullFile;
        }
    }
    
    // Cleanup and exit
    if (handle != NULL)
        FileStream_Close(handle);
    if (hFile != NULL)
        SFileCloseFile(hFile);
    
    return nError;
}
コード例 #5
0
ファイル: SFileListFile.cpp プロジェクト: DoGoodS/StormLib
static int SFileAddExternalListFile(
    TMPQArchive * ha,
    HANDLE hMpq,
    const char * szListFile)
{
    HANDLE hListFile;
    int nError = ERROR_SUCCESS;

    // Open the external list file
    if(SFileOpenFileEx(hMpq, szListFile, SFILE_OPEN_LOCAL_FILE, &hListFile))
    {
        // Add the data from the listfile to MPQ
        nError = SFileAddArbitraryListFile(ha, hListFile);
        SFileCloseFile(hListFile);
    }
    return nError;
}
コード例 #6
0
ファイル: System.cpp プロジェクト: FirstCore/PandaCore
uint32 ReadBuild(int locale)
{
    // include build info file also
    std::string filename  = std::string("component.wow-") + Locales[locale] + ".txt";
    //printf("Read %s file... ", filename.c_str());

    HANDLE dbcFile;
    if (!SFileOpenFileEx(LocaleMpq, filename.c_str(), SFILE_OPEN_PATCHED_FILE, &dbcFile))
    {
        printf("Fatal error: Not found %s file!\n", filename.c_str());
        exit(1);
    }

    char buff[512];
    DWORD readBytes = 0;
    SFileReadFile(dbcFile, buff, 512, &readBytes, NULL);
    if (!readBytes)
    {
        printf("Fatal error: Not found %s file!\n", filename.c_str());
        exit(1);
    }

    std::string text = buff;
    SFileCloseFile(dbcFile);

    size_t pos = text.find("version=\"");
    size_t pos1 = pos + strlen("version=\"");
    size_t pos2 = text.find("\"", pos1);
    if (pos == text.npos || pos2 == text.npos || pos1 >= pos2)
    {
        printf("Fatal error: Invalid  %s file format!\n", filename.c_str());
        exit(1);
    }

    std::string build_str = text.substr(pos1,pos2-pos1);

    int build = atoi(build_str.c_str());
    if (build <= 0)
    {
        printf("Fatal error: Invalid  %s file format!\n", filename.c_str());
        exit(1);
    }

    return build;
}
コード例 #7
0
static bool IsMatchingPatchFile(
    TMPQArchive * ha,
    const char * szFileName,
    LPBYTE pbBaseFileMd5)
{
    MPQ_PATCH_HEADER PatchHeader = {0};
    HANDLE hFile = NULL;
    DWORD dwTransferred = 0;
    DWORD dwFlags = 0;
    bool bResult = false;

    // Open the file and load the patch header
    if(SFileOpenFileEx((HANDLE)ha, szFileName, SFILE_OPEN_BASE_FILE, &hFile))
    {
        // Retrieve the flags. We need to know whether the file is a patch or not
        SFileGetFileInfo(hFile, SFileInfoFlags, &dwFlags, sizeof(DWORD), &dwTransferred);
        if(dwFlags & MPQ_FILE_PATCH_FILE)
        {
            // Load the patch header
            SFileReadFile(hFile, &PatchHeader, sizeof(MPQ_PATCH_HEADER), &dwTransferred, NULL);
            BSWAP_ARRAY32_UNSIGNED(pPatchHeader, sizeof(DWORD) * 6);

            // If the file contains an incremental patch,
            // compare the "MD5 before patching" with the base file MD5
            if(dwTransferred == sizeof(MPQ_PATCH_HEADER) && PatchHeader.dwSignature == PATCH_SIGNATURE_HEADER)
                bResult = (!memcmp(PatchHeader.md5_before_patch, pbBaseFileMd5, MD5_DIGEST_SIZE));
        }
        else
        {
            // TODO: How to match it if it's not an incremental patch?
            // Example: StarCraft II\Updates\enGB\s2-update-enGB-23258.MPQ:
            //          Mods\Core.SC2Mod\enGB.SC2Assets\StreamingBuckets.txt" 
            bResult = false;
        }

        // Close the file
        SFileCloseFile(hFile);
    }

    return bResult;
}
コード例 #8
0
ファイル: faio.cpp プロジェクト: Necrolis/freeablo
    int FAfclose(FAFile* stream)
    {
        int retval = 0;

        switch(stream->mode)
        {
            case FAFile::PlainFile:
                delete stream->data.plainFile.filename;
                return fclose(stream->data.plainFile.file);

            case FAFile::MPQFile:
                int res = SFileCloseFile(*((HANDLE*)stream->data.mpqFile));
                free(stream->data.mpqFile);

                if(res != 0)
                    retval = EOF;
        }

        delete stream;

        return retval;
    }
コード例 #9
0
ファイル: FileIO.cpp プロジェクト: jjf28/Chkdraft
bool FindFileInMpq(MPQHANDLE mpq, const char* fileName)
{
    if ( mpq == nullptr )
        CHKD_ERR("NULL MPQ file specified for opening %s", fileName);
    else
    {
        u32 bytesRead = 0;
        HANDLE openFile = NULL;
        if ( SFileGetFileInfo(mpq, SFILE_INFO_NUM_FILES) != 0xFFFFFFFF )
        {
            if ( SFileOpenFileEx(mpq, fileName, SFILE_SEARCH_CURRENT_ONLY, &openFile) == TRUE )
            {
                SFileCloseFile(openFile);
                return true;
            }
            else
                CHKD_ERR("Failed to get %s from MPQ file", fileName);
        }
        else
            CHKD_ERR("File is already open", fileName);
    }
    return false;
}
コード例 #10
0
ファイル: MPQ.cpp プロジェクト: Sasho/SkyFireEMU_430
char* ExtractFileToMemory(HANDLE &MPQ_handle, const char * szArchivedFile, int & size )
{
    HANDLE hFile  = NULL;          // Archived file handle
    int    nError = ERROR_SUCCESS; // Result value
    char * pbFullFile = NULL;
    
    if (nError == ERROR_SUCCESS)            
    {
        if (!SFileOpenFileEx(MPQ_handle, szArchivedFile, SFILE_OPEN_PATCHED_FILE, &hFile))
            nError = GetLastError();
    }
    
    // Read the file from the archive
    if (nError == ERROR_SUCCESS)
    {
        // Get the size of the full patched file
        size = SFileGetFileSize(hFile, NULL);
        if (size != 0)
        {
            // Allocate space for the full file
            pbFullFile = new char[size];
            if (!SFileReadFile(hFile, pbFullFile, size))
            {           
                nError = GetLastError();
                printf("Failed to read full patched file data \"%s\"\n", szArchivedFile);
                assert(false);
            }
        }
    }
    
    // Cleanup and exit
    if (nError == ERROR_SUCCESS && hFile != NULL)
        SFileCloseFile(hFile);
    
    return pbFullFile;
}
コード例 #11
0
ファイル: map.cpp プロジェクト: nyilmaz/px-guard
void CMap :: Load( CConfig *CFG, string nCFGFile )
{
	m_Valid = true;
	m_CFGFile = nCFGFile;

	// load the map data

	m_MapLocalPath = CFG->GetString( "map_localpath", string( ) );
	m_MapData.clear( );

	if( !m_MapLocalPath.empty( ) )
		m_MapData = UTIL_FileRead( m_GHost->m_MapPath + m_MapLocalPath );

	// load the map MPQ

	string MapMPQFileName = m_GHost->m_MapPath + m_MapLocalPath;
	HANDLE MapMPQ;
	bool MapMPQReady = false;

	if( SFileOpenArchive( MapMPQFileName.c_str( ), 0, MPQ_OPEN_FORCE_MPQ_V1, &MapMPQ ) )
	{
		CONSOLE_Print( "[MAP] loading MPQ file [" + MapMPQFileName + "]" );
		MapMPQReady = true;
	}
	else
		CONSOLE_Print( "[MAP] warning - unable to load MPQ file [" + MapMPQFileName + "]" );

	// try to calculate map_size, map_info, map_crc, map_sha1

	BYTEARRAY MapSize;
	BYTEARRAY MapInfo;
	BYTEARRAY MapCRC;
	BYTEARRAY MapSHA1;

	if( !m_MapData.empty( ) )
	{
		m_GHost->m_SHA->Reset( );

		// calculate map_size

		MapSize = UTIL_CreateByteArray( (uint32_t)m_MapData.size( ), false );
		CONSOLE_Print( "[MAP] calculated map_size = " + UTIL_ByteArrayToDecString( MapSize ) );

		// calculate map_info (this is actually the CRC)

		MapInfo = UTIL_CreateByteArray( (uint32_t)m_GHost->m_CRC->FullCRC( (unsigned char *)m_MapData.c_str( ), m_MapData.size( ) ), false );
		CONSOLE_Print( "[MAP] calculated map_info = " + UTIL_ByteArrayToDecString( MapInfo ) );

		// calculate map_crc (this is not the CRC) and map_sha1
		// a big thank you to Strilanc for figuring the map_crc algorithm out

		string CommonJ = UTIL_FileRead( m_GHost->m_MapCFGPath + "common.j" );

		if( CommonJ.empty( ) )
			CONSOLE_Print( "[MAP] unable to calculate map_crc/sha1 - unable to read file [" + m_GHost->m_MapCFGPath + "common.j]" );
		else
		{
			string BlizzardJ = UTIL_FileRead( m_GHost->m_MapCFGPath + "blizzard.j" );

			if( BlizzardJ.empty( ) )
				CONSOLE_Print( "[MAP] unable to calculate map_crc/sha1 - unable to read file [" + m_GHost->m_MapCFGPath + "blizzard.j]" );
			else
			{
				uint32_t Val = 0;

				// update: it's possible for maps to include their own copies of common.j and/or blizzard.j
				// this code now overrides the default copies if required

				bool OverrodeCommonJ = false;
				bool OverrodeBlizzardJ = false;

				if( MapMPQReady )
				{
					HANDLE SubFile;

					// override common.j

					if( SFileOpenFileEx( MapMPQ, "Scripts\\common.j", 0, &SubFile ) )
					{
						uint32_t FileLength = SFileGetFileSize( SubFile, NULL );

						if( FileLength > 0 && FileLength != 0xFFFFFFFF )
						{
							char *SubFileData = new char[FileLength];
							DWORD BytesRead = 0;

							if( SFileReadFile( SubFile, SubFileData, FileLength, &BytesRead ) )
							{
								CONSOLE_Print( "[MAP] overriding default common.j with map copy while calculating map_crc/sha1" );
								OverrodeCommonJ = true;
								Val = Val ^ XORRotateLeft( (unsigned char *)SubFileData, BytesRead );
								m_GHost->m_SHA->Update( (unsigned char *)SubFileData, BytesRead );
							}

							delete [] SubFileData;
						}

						SFileCloseFile( SubFile );
					}
				}

				if( !OverrodeCommonJ )
				{
					Val = Val ^ XORRotateLeft( (unsigned char *)CommonJ.c_str( ), CommonJ.size( ) );
					m_GHost->m_SHA->Update( (unsigned char *)CommonJ.c_str( ), CommonJ.size( ) );
				}

				if( MapMPQReady )
				{
					HANDLE SubFile;

					// override blizzard.j

					if( SFileOpenFileEx( MapMPQ, "Scripts\\blizzard.j", 0, &SubFile ) )
					{
						uint32_t FileLength = SFileGetFileSize( SubFile, NULL );

						if( FileLength > 0 && FileLength != 0xFFFFFFFF )
						{
							char *SubFileData = new char[FileLength];
							DWORD BytesRead = 0;

							if( SFileReadFile( SubFile, SubFileData, FileLength, &BytesRead ) )
							{
								CONSOLE_Print( "[MAP] overriding default blizzard.j with map copy while calculating map_crc/sha1" );
								OverrodeBlizzardJ = true;
								Val = Val ^ XORRotateLeft( (unsigned char *)SubFileData, BytesRead );
								m_GHost->m_SHA->Update( (unsigned char *)SubFileData, BytesRead );
							}

							delete [] SubFileData;
						}

						SFileCloseFile( SubFile );
					}
				}

				if( !OverrodeBlizzardJ )
				{
					Val = Val ^ XORRotateLeft( (unsigned char *)BlizzardJ.c_str( ), BlizzardJ.size( ) );
					m_GHost->m_SHA->Update( (unsigned char *)BlizzardJ.c_str( ), BlizzardJ.size( ) );
				}

				Val = ROTL( Val, 3 );
				Val = ROTL( Val ^ 0x03F1379E, 3 );
				m_GHost->m_SHA->Update( (unsigned char *)"\x9E\x37\xF1\x03", 4 );

				if( MapMPQReady )
				{
					vector<string> FileList;
					FileList.push_back( "war3map.j" );
					FileList.push_back( "scripts\\war3map.j" );
					FileList.push_back( "war3map.w3e" );
					FileList.push_back( "war3map.wpm" );
					FileList.push_back( "war3map.doo" );
					FileList.push_back( "war3map.w3u" );
					FileList.push_back( "war3map.w3b" );
					FileList.push_back( "war3map.w3d" );
					FileList.push_back( "war3map.w3a" );
					FileList.push_back( "war3map.w3q" );
					bool FoundScript = false;

					for( vector<string> :: iterator i = FileList.begin( ); i != FileList.end( ); i++ )
					{
						// don't use scripts\war3map.j if we've already used war3map.j (yes, some maps have both but only war3map.j is used)

						if( FoundScript && *i == "scripts\\war3map.j" )
							continue;

						HANDLE SubFile;

						if( SFileOpenFileEx( MapMPQ, (*i).c_str( ), 0, &SubFile ) )
						{
							uint32_t FileLength = SFileGetFileSize( SubFile, NULL );

							if( FileLength > 0 && FileLength != 0xFFFFFFFF )
							{
								char *SubFileData = new char[FileLength];
								DWORD BytesRead = 0;

								if( SFileReadFile( SubFile, SubFileData, FileLength, &BytesRead ) )
								{
									if( *i == "war3map.j" || *i == "scripts\\war3map.j" )
										FoundScript = true;

									Val = ROTL( Val ^ XORRotateLeft( (unsigned char *)SubFileData, BytesRead ), 3 );
									m_GHost->m_SHA->Update( (unsigned char *)SubFileData, BytesRead );
									// DEBUG_Print( "*** found: " + *i );
								}

								delete [] SubFileData;
							}

							SFileCloseFile( SubFile );
						}
						else
						{
							// DEBUG_Print( "*** not found: " + *i );
						}
					}

					if( !FoundScript )
						CONSOLE_Print( "[MAP] couldn't find war3map.j or scripts\\war3map.j in MPQ file, calculated map_crc/sha1 is probably wrong" );

					MapCRC = UTIL_CreateByteArray( Val, false );
					CONSOLE_Print( "[MAP] calculated map_crc = " + UTIL_ByteArrayToDecString( MapCRC ) );

					m_GHost->m_SHA->Final( );
					unsigned char SHA1[20];
					memset( SHA1, 0, sizeof( unsigned char ) * 20 );
					m_GHost->m_SHA->GetHash( SHA1 );
					MapSHA1 = UTIL_CreateByteArray( SHA1, 20 );
					CONSOLE_Print( "[MAP] calculated map_sha1 = " + UTIL_ByteArrayToDecString( MapSHA1 ) );
				}
				else
					CONSOLE_Print( "[MAP] unable to calculate map_crc/sha1 - map MPQ file not loaded" );
			}
		}
	}
	else
		CONSOLE_Print( "[MAP] no map data available, using config file for map_size, map_info, map_crc, map_sha1" );

	// try to calculate map_width, map_height, map_slot<x>, map_numplayers, map_numteams

	uint32_t MapOptions = 0;
	BYTEARRAY MapWidth;
	BYTEARRAY MapHeight;
	uint32_t MapNumPlayers = 0;
	uint32_t MapNumTeams = 0;
	vector<CGameSlot> Slots;

	if( !m_MapData.empty( ) )
	{
		if( MapMPQReady )
		{
			HANDLE SubFile;

			if( SFileOpenFileEx( MapMPQ, "war3map.w3i", 0, &SubFile ) )
			{
				uint32_t FileLength = SFileGetFileSize( SubFile, NULL );

				if( FileLength > 0 && FileLength != 0xFFFFFFFF )
				{
					char *SubFileData = new char[FileLength];
					DWORD BytesRead = 0;

					if( SFileReadFile( SubFile, SubFileData, FileLength, &BytesRead ) )
					{
						istringstream ISS( string( SubFileData, BytesRead ) );

						// war3map.w3i format found at http://www.wc3campaigns.net/tools/specs/index.html by Zepir/PitzerMike

						string GarbageString;
						uint32_t FileFormat;
						uint32_t RawMapWidth;
						uint32_t RawMapHeight;
						uint32_t RawMapFlags;
						uint32_t RawMapNumPlayers;
						uint32_t RawMapNumTeams;

						ISS.read( (char *)&FileFormat, 4 );				// file format (18 = ROC, 25 = TFT)

						if( FileFormat == 18 || FileFormat == 25 )
						{
							ISS.seekg( 4, ios :: cur );					// number of saves
							ISS.seekg( 4, ios :: cur );					// editor version
							getline( ISS, GarbageString, '\0' );		// map name
							getline( ISS, GarbageString, '\0' );		// map author
							getline( ISS, GarbageString, '\0' );		// map description
							getline( ISS, GarbageString, '\0' );		// players recommended
							ISS.seekg( 32, ios :: cur );				// camera bounds
							ISS.seekg( 16, ios :: cur );				// camera bounds complements
							ISS.read( (char *)&RawMapWidth, 4 );		// map width
							ISS.read( (char *)&RawMapHeight, 4 );		// map height
							ISS.read( (char *)&RawMapFlags, 4 );		// flags
							ISS.seekg( 1, ios :: cur );					// map main ground type

							if( FileFormat == 18 )
								ISS.seekg( 4, ios :: cur );				// campaign background number
							else if( FileFormat == 25 )
							{
								ISS.seekg( 4, ios :: cur );				// loading screen background number
								getline( ISS, GarbageString, '\0' );	// path of custom loading screen model
							}

							getline( ISS, GarbageString, '\0' );		// map loading screen text
							getline( ISS, GarbageString, '\0' );		// map loading screen title
							getline( ISS, GarbageString, '\0' );		// map loading screen subtitle

							if( FileFormat == 18 )
								ISS.seekg( 4, ios :: cur );				// map loading screen number
							else if( FileFormat == 25 )
							{
								ISS.seekg( 4, ios :: cur );				// used game data set
								getline( ISS, GarbageString, '\0' );	// prologue screen path
							}

							getline( ISS, GarbageString, '\0' );		// prologue screen text
							getline( ISS, GarbageString, '\0' );		// prologue screen title
							getline( ISS, GarbageString, '\0' );		// prologue screen subtitle

							if( FileFormat == 25 )
							{
								ISS.seekg( 4, ios :: cur );				// uses terrain fog
								ISS.seekg( 4, ios :: cur );				// fog start z height
								ISS.seekg( 4, ios :: cur );				// fog end z height
								ISS.seekg( 4, ios :: cur );				// fog density
								ISS.seekg( 1, ios :: cur );				// fog red value
								ISS.seekg( 1, ios :: cur );				// fog green value
								ISS.seekg( 1, ios :: cur );				// fog blue value
								ISS.seekg( 1, ios :: cur );				// fog alpha value
								ISS.seekg( 4, ios :: cur );				// global weather id
								getline( ISS, GarbageString, '\0' );	// custom sound environment
								ISS.seekg( 1, ios :: cur );				// tileset id of the used custom light environment
								ISS.seekg( 1, ios :: cur );				// custom water tinting red value
								ISS.seekg( 1, ios :: cur );				// custom water tinting green value
								ISS.seekg( 1, ios :: cur );				// custom water tinting blue value
								ISS.seekg( 1, ios :: cur );				// custom water tinting alpha value
							}

							ISS.read( (char *)&RawMapNumPlayers, 4 );	// number of players
							uint32_t ClosedSlots = 0;

							for( uint32_t i = 0; i < RawMapNumPlayers; i++ )
							{
								CGameSlot Slot( 0, 255, SLOTSTATUS_OPEN, 0, 0, 1, SLOTRACE_RANDOM );
								uint32_t Colour;
								uint32_t Status;
								uint32_t Race;

								ISS.read( (char *)&Colour, 4 );			// colour
								Slot.SetColour( Colour );
								ISS.read( (char *)&Status, 4 );			// status

								if( Status == 1 )
									Slot.SetSlotStatus( SLOTSTATUS_OPEN );
								else if( Status == 2 )
								{
									Slot.SetSlotStatus( SLOTSTATUS_OCCUPIED );
									Slot.SetComputer( 1 );
									Slot.SetComputerType( SLOTCOMP_NORMAL );
								}
								else
								{
									Slot.SetSlotStatus( SLOTSTATUS_CLOSED );
									ClosedSlots++;
								}

								ISS.read( (char *)&Race, 4 );			// race

								if( Race == 1 )
									Slot.SetRace( SLOTRACE_HUMAN );
								else if( Race == 2 )
									Slot.SetRace( SLOTRACE_ORC );
								else if( Race == 3 )
									Slot.SetRace( SLOTRACE_UNDEAD );
								else if( Race == 4 )
									Slot.SetRace( SLOTRACE_NIGHTELF );
								else
									Slot.SetRace( SLOTRACE_RANDOM );

								ISS.seekg( 4, ios :: cur );				// fixed start position
								getline( ISS, GarbageString, '\0' );	// player name
								ISS.seekg( 4, ios :: cur );				// start position x
								ISS.seekg( 4, ios :: cur );				// start position y
								ISS.seekg( 4, ios :: cur );				// ally low priorities
								ISS.seekg( 4, ios :: cur );				// ally high priorities

								if( Slot.GetSlotStatus( ) != SLOTSTATUS_CLOSED )
									Slots.push_back( Slot );
							}

							ISS.read( (char *)&RawMapNumTeams, 4 );		// number of teams

							for( uint32_t i = 0; i < RawMapNumTeams; i++ )
							{
								uint32_t Flags;
								uint32_t PlayerMask;

								ISS.read( (char *)&Flags, 4 );			// flags
								ISS.read( (char *)&PlayerMask, 4 );		// player mask

								for( unsigned char j = 0; j < 12; j++ )
								{
									if( PlayerMask & 1 )
									{
										for( vector<CGameSlot> :: iterator k = Slots.begin( ); k != Slots.end( ); k++ )
										{
											if( (*k).GetColour( ) == j )
												(*k).SetTeam( i );
										}
									}

									PlayerMask >>= 1;
								}

								getline( ISS, GarbageString, '\0' );	// team name
							}

							// the bot only cares about the following options: melee, fixed player settings, custom forces
							// let's not confuse the user by displaying erroneous map options so zero them out now

							MapOptions = RawMapFlags & ( MAPOPT_MELEE | MAPOPT_FIXEDPLAYERSETTINGS | MAPOPT_CUSTOMFORCES );
							CONSOLE_Print( "[MAP] calculated map_options = " + UTIL_ToString( MapOptions ) );
							MapWidth = UTIL_CreateByteArray( (uint16_t)RawMapWidth, false );
							CONSOLE_Print( "[MAP] calculated map_width = " + UTIL_ByteArrayToDecString( MapWidth ) );
							MapHeight = UTIL_CreateByteArray( (uint16_t)RawMapHeight, false );
							CONSOLE_Print( "[MAP] calculated map_height = " + UTIL_ByteArrayToDecString( MapHeight ) );
							MapNumPlayers = RawMapNumPlayers - ClosedSlots;
							CONSOLE_Print( "[MAP] calculated map_numplayers = " + UTIL_ToString( MapNumPlayers ) );
							MapNumTeams = RawMapNumTeams;
							CONSOLE_Print( "[MAP] calculated map_numteams = " + UTIL_ToString( MapNumTeams ) );

							uint32_t SlotNum = 1;

							for( vector<CGameSlot> :: iterator i = Slots.begin( ); i != Slots.end( ); i++ )
							{
								CONSOLE_Print( "[MAP] calculated map_slot" + UTIL_ToString( SlotNum ) + " = " + UTIL_ByteArrayToDecString( (*i).GetByteArray( ) ) );
								SlotNum++;
							}

							if( MapOptions & MAPOPT_MELEE )
							{
								CONSOLE_Print( "[MAP] found melee map, initializing slots" );

								// give each slot a different team and set the race to random

								unsigned char Team = 0;

								for( vector<CGameSlot> :: iterator i = Slots.begin( ); i != Slots.end( ); i++ )
								{
									(*i).SetTeam( Team++ );
									(*i).SetRace( SLOTRACE_RANDOM );
								}
							}

							if( !( MapOptions & MAPOPT_FIXEDPLAYERSETTINGS ) )
							{
								// make races selectable

								for( vector<CGameSlot> :: iterator i = Slots.begin( ); i != Slots.end( ); i++ )
									(*i).SetRace( (*i).GetRace( ) | SLOTRACE_SELECTABLE );
							}
						}
					}
					else
コード例 #12
0
ファイル: SFileVerify.cpp プロジェクト: Enturion/EnturionEMU
DWORD WINAPI SFileVerifyFile(HANDLE hMpq, const char * szFileName, DWORD dwFlags)
{
    hash_state md5_state;
    unsigned char md5[MD5_DIGEST_SIZE];
    TFileEntry * pFileEntry;
    TMPQFile * hf;
    BYTE Buffer[0x1000];
    HANDLE hFile = NULL;
    DWORD dwVerifyResult = 0;
    DWORD dwSearchScope = SFILE_OPEN_FROM_MPQ;
    DWORD dwTotalBytes = 0;
    DWORD dwBytesRead;
    DWORD dwCrc32;

    // Fix the open type for patched archives
    if (SFileIsPatchedArchive(hMpq))
        dwSearchScope = SFILE_OPEN_PATCHED_FILE;

    // Attempt to open the file
    if (SFileOpenFileEx(hMpq, szFileName, dwSearchScope, &hFile))
    {
        // Get the file size
        hf = (TMPQFile *)hFile;
        pFileEntry = hf->pFileEntry;
        dwTotalBytes = SFileGetFileSize(hFile, NULL);

        // Initialize the CRC32 and MD5 contexts
        md5_init(&md5_state);
        dwCrc32 = crc32(0, Z_NULL, 0);

        // Also turn on sector checksum verification
        hf->bCheckSectorCRCs = true;

        // Go through entire file and update both CRC32 and MD5
        for (;;)
        {
            // Read data from file
            SFileReadFile(hFile, Buffer, sizeof(Buffer), &dwBytesRead, NULL);
            if (dwBytesRead == 0)
            {
                if (GetLastError() == ERROR_CHECKSUM_ERROR)
                    dwVerifyResult |= VERIFY_SECTOR_CHECKSUM_ERROR;
                break;
            }

            // Update CRC32 value
            if (dwFlags & MPQ_ATTRIBUTE_CRC32)
                dwCrc32 = crc32(dwCrc32, Buffer, dwBytesRead);

            // Update MD5 value
            if (dwFlags & MPQ_ATTRIBUTE_MD5)
                md5_process(&md5_state, Buffer, dwBytesRead);

            // Decrement the total size
            dwTotalBytes -= dwBytesRead;
        }

        // If the file has sector checksums, indicate it in the flags
        if ((hf->pFileEntry->dwFlags & MPQ_FILE_SECTOR_CRC) && hf->SectorChksums != NULL && hf->SectorChksums[0] != 0)
            dwVerifyResult |= VERIFY_SECTORS_HAVE_CHECKSUM;

        // Check if the entire file has been read
        // No point in checking CRC32 and MD5 if not
        // Skip checksum checks if the file has patches
        if (dwTotalBytes == 0)
        {
            // Check CRC32 and MD5 only if there is no patches
            if (hf->hfPatchFile == NULL)
            {
                // Check if the CRC32 matches.
                if (dwFlags & MPQ_ATTRIBUTE_CRC32)
                {
                    // Some files may have their CRC zeroed
                    if (pFileEntry->dwCrc32 != 0)
                    {
                        dwVerifyResult |= VERIFY_FILE_HAS_CHECKSUM;
                        if (dwCrc32 != pFileEntry->dwCrc32)
                            dwVerifyResult |= VERIFY_FILE_CHECKSUM_ERROR;
                    }
                }

                // Check if MD5 matches
                if (dwFlags & MPQ_ATTRIBUTE_MD5)
                {
                    md5_done(&md5_state, md5);

                    // Some files have the MD5 zeroed. Don't check MD5 in that case
                    if (is_valid_md5(pFileEntry->md5))
                    {
                        dwVerifyResult |= VERIFY_FILE_HAS_MD5;
                        if (memcmp(md5, pFileEntry->md5, MD5_DIGEST_SIZE))
                            dwVerifyResult |= VERIFY_FILE_MD5_ERROR;
                    }
                }
            }
            else
            {
                // Patched files are MD5-checked automatically
                dwVerifyResult |= VERIFY_FILE_HAS_MD5;
            }
        }
        else
        {
            dwVerifyResult |= VERIFY_READ_ERROR;
        }

        SFileCloseFile(hFile);
    }
    else
    {
        // Remember that the file couldn't be open
        dwVerifyResult |= VERIFY_OPEN_ERROR;
    }

    return dwVerifyResult;
}
コード例 #13
0
ファイル: SAttrFile.cpp プロジェクト: Artyom91/OHBot
int SAttrFileLoad(TMPQArchive * ha)
{
    TMPQAttr * pAttr = NULL;
    HANDLE hFile = NULL;
    DWORD dwBytesRead;
    DWORD dwToRead;
    int nError = ERROR_SUCCESS;

    // Initially, set the attrobutes to NULL
    ha->pAttributes = NULL;

    // Attempt to open the "(attributes)" file.
    // If it's not there, we don't support attributes
    if(!SFileOpenFileEx((HANDLE)ha, ATTRIBUTES_NAME, 0, &hFile))
        nError = GetLastError();

    // Allocate space for the TMPQAttributes
    if(nError == ERROR_SUCCESS)
    {
        pAttr = ALLOCMEM(TMPQAttr, 1);
        if(pAttr == NULL)
            nError = ERROR_NOT_ENOUGH_MEMORY;
    }

    // Load the content of the attributes file
    if(nError == ERROR_SUCCESS)
    {
        memset(pAttr, 0, sizeof(TMPQAttr));
        
        dwToRead = sizeof(DWORD) + sizeof(DWORD);
        SFileReadFile(hFile, pAttr, dwToRead, &dwBytesRead, NULL);
        if(dwBytesRead != dwToRead)
            nError = ERROR_FILE_CORRUPT;
    }

    // Verify format of the attributes
    if(nError == ERROR_SUCCESS)
    {
        if(pAttr->dwVersion > MPQ_ATTRIBUTES_V1)
            nError = ERROR_BAD_FORMAT;
    }

    // Load the CRC32 (if any)
    if(nError == ERROR_SUCCESS && (pAttr->dwFlags & MPQ_ATTRIBUTE_CRC32))
    {
        pAttr->pCrc32 = ALLOCMEM(TMPQCRC32, ha->pHeader->dwHashTableSize);
        if(pAttr->pCrc32 != NULL)
        {
            memset(pAttr->pCrc32, 0, sizeof(TMPQCRC32) * ha->pHeader->dwHashTableSize);
            dwToRead = sizeof(TMPQCRC32) * ha->pHeader->dwBlockTableSize;
            SFileReadFile(hFile, pAttr->pCrc32, dwToRead, &dwBytesRead, NULL);
            if(dwBytesRead != dwToRead)
                nError = ERROR_FILE_CORRUPT;
        }
        else
        {
            nError = ERROR_NOT_ENOUGH_MEMORY;
        }
    }

    // Read the FILETIMEs (if any)
    if(nError == ERROR_SUCCESS && (pAttr->dwFlags & MPQ_ATTRIBUTE_FILETIME))
    {
        pAttr->pFileTime = ALLOCMEM(TMPQFileTime, ha->pHeader->dwHashTableSize);
        if(pAttr->pFileTime != NULL)
        {
            memset(pAttr->pFileTime, 0, sizeof(TMPQFileTime) * ha->pHeader->dwHashTableSize);
            dwToRead = sizeof(TMPQFileTime) * ha->pHeader->dwBlockTableSize;
            SFileReadFile(hFile, pAttr->pFileTime, dwToRead, &dwBytesRead, NULL);
            if(dwBytesRead != dwToRead)
                nError = ERROR_FILE_CORRUPT;
        }
        else
        {
            nError = ERROR_NOT_ENOUGH_MEMORY;
        }
    }

    // Read the MD5 (if any)
    if(nError == ERROR_SUCCESS && (pAttr->dwFlags & MPQ_ATTRIBUTE_MD5))
    {
        pAttr->pMd5 = ALLOCMEM(TMPQMD5, ha->pHeader->dwHashTableSize);
        if(pAttr->pMd5 != NULL)
        {
            memset(pAttr->pMd5, 0, sizeof(TMPQMD5) * ha->pHeader->dwHashTableSize);
            dwToRead = sizeof(TMPQMD5) * ha->pHeader->dwBlockTableSize;
            SFileReadFile(hFile, pAttr->pMd5, dwToRead, &dwBytesRead, NULL);
            if(dwBytesRead != dwToRead)
                nError = ERROR_FILE_CORRUPT;
        }
        else
        {
            nError = ERROR_NOT_ENOUGH_MEMORY;
        }
    }

    // Set the attributes into the MPQ archive
    if(nError == ERROR_SUCCESS)
    {
        ha->pAttributes = pAttr;
        pAttr = NULL;
    }

    // Cleanup & exit
    FreeMPQAttributes(pAttr);
    SFileCloseFile(hFile);
    return nError;
}
コード例 #14
0
ファイル: System.cpp プロジェクト: milleniumcore/CactusEMU
int ExtractLocaleFile(int MPQId, const char * szArchivedFile, const char * szFileName)
{
    HANDLE hFile  = NULL;          // Archived file handle
    TFileStream* handle = NULL;          // Disk file handle
    int    nError = ERROR_SUCCESS; // Result value
    
    // Open a file in the archive, e.g. "data\global\music\Act1\tristram.wav"
    if(nError == ERROR_SUCCESS)            
    {
        if(!SFileOpenFileEx(localeMPQ[MPQId], szArchivedFile, SFILE_OPEN_PATCHED_FILE, &hFile))
            nError = GetLastError();
    }
	
    // Create the target file
    if(nError == ERROR_SUCCESS)
    {
        //handle = CreateFile(szFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
		//if(handle == INVALID_HANDLE_VALUE)
        //    nError = GetLastError();
		handle = FileStream_CreateFile(szFileName);
        if(handle == NULL)
            nError = GetLastError();
    }
	
	/*
	 // Get the size of the full patched file
	 dwFileSize = SFileGetFileSize(hFile, NULL);
	 if(dwFileSize != 0)
	 {
	 // Allocate space for the full file
	 pbFullFile = new BYTE[dwFileSize];
	 if(pbFullFile != NULL)
	 {
	 if(!SFileReadFile(hFile, pbFullFile, dwFileSize))
	 {           
	 nError = GetLastError();
	 printf("Failed to read full patched file data \"%s\"\n", szFileName);
	 }
	 
	 if(nError == ERROR_SUCCESS)
	 {
	 strcpy(szLocFileName, MAKE_PATH("Work//"));
	 strcat(szLocFileName, GetPlainName(szFileName));
	 
	 pStream = FileStream_CreateFile(szLocFileName);
	 if(pStream != NULL)
	 {
	 FileStream_Write(pStream, NULL, pbFullFile, dwFileSize);
	 FileStream_Close(pStream);
	 }
	 }
	 
	 delete [] pbFullFile;
	 }
	 }
	 */
    // Read the file from the archive
    if(nError == ERROR_SUCCESS)
    {
        // Get the size of the full patched file
        DWORD dwFileSize = SFileGetFileSize(hFile, NULL);
        if(dwFileSize != 0)
        {
            // Allocate space for the full file
            BYTE * pbFullFile = new BYTE[dwFileSize];
            if(!SFileReadFile(hFile, pbFullFile, dwFileSize))
			{           
				nError = GetLastError();
				printf("Failed to read full patched file data \"%s\"\n", szFileName);
				assert(false);
			}
			FileStream_Write(handle, NULL, pbFullFile, dwFileSize);
			delete [] pbFullFile;
        }
    }        
	
    // Cleanup and exit
    if(handle != NULL)
        FileStream_Close(handle);
    if(hFile != NULL)
        SFileCloseFile(hFile);
	
    return nError;
}
コード例 #15
0
ファイル: SFileOpenFileEx.cpp プロジェクト: Hernrup/stormlib
bool OpenPatchedFile(HANDLE hMpq, const char * szFileName, DWORD dwReserved, HANDLE * phFile)
{
    TMPQArchive * ha = (TMPQArchive *)hMpq;
    TMPQFile * hfPatch;                     // Pointer to patch file
    TMPQFile * hfBase = NULL;               // Pointer to base open file
    TMPQFile * hfLast = NULL;               // The highest file in the chain that is not patch file
    TMPQFile * hf = NULL;
    HANDLE hPatchFile;
    char szPatchFileName[MAX_PATH];

    // Keep this flag here for future updates
    dwReserved = dwReserved;

    // First of all, try to open the original version of the file in any of the patch chain
    while(ha != NULL)
    {
        // Construct the name of the patch file
        strcpy(szPatchFileName, ha->szPatchPrefix);
        strcpy(&szPatchFileName[ha->cchPatchPrefix], szFileName);
        if(SFileOpenFileEx((HANDLE)ha, szPatchFileName, SFILE_OPEN_BASE_FILE, (HANDLE *)&hfBase))
        {
            // The file must be a base file, i.e. without MPQ_FILE_PATCH_FILE
            if((hfBase->pFileEntry->dwFlags & MPQ_FILE_PATCH_FILE) == 0)
            {
                hf = hfLast = hfBase;
                break;
            }

            SFileCloseFile((HANDLE)hfBase);
        }

        // Move to the next file in the patch chain
        ha = ha->haPatch;
    }

    // If we couldn't find the file in any of the patches, it doesn't exist
    if(hf == NULL)
    {
        SetLastError(ERROR_FILE_NOT_FOUND);
        return false;
    }

    // Now keep going in the patch chain and open every patch file that is there
    for(ha = ha->haPatch; ha != NULL; ha = ha->haPatch)
    {
        // Construct patch file name
        strcpy(szPatchFileName, ha->szPatchPrefix);
        strcpy(&szPatchFileName[ha->cchPatchPrefix], szFileName);
        if(SFileOpenFileEx((HANDLE)ha, szPatchFileName, SFILE_OPEN_BASE_FILE, &hPatchFile))
        {
            // Remember the new version
            hfPatch = (TMPQFile *)hPatchFile;

            // If we encountered a full replacement of the file, 
            // we have to remember the highest full file
            if((hfPatch->pFileEntry->dwFlags & MPQ_FILE_PATCH_FILE) == 0)
                hfLast = hfPatch;

            // Set current patch to base file and move on
            hf->hfPatchFile = hfPatch;
            hf = hfPatch;
        }
    }

    // Now we need to free all files that are below the highest unpatched version
    while(hfBase != hfLast)
    {
        TMPQFile * hfNext = hfBase->hfPatchFile;

        // Free the file below
        hfBase->hfPatchFile = NULL;
        FreeMPQFile(hfBase);

        // Move the base to the next file
        hfBase = hfNext;
    }

    // Give the updated base MPQ
    if(phFile != NULL)
        *phFile = (HANDLE)hfBase;
    return true;
}
コード例 #16
0
ファイル: dbcfile.cpp プロジェクト: Ayik0/DeathCore_5.4.8
DBCFile::~DBCFile()
{
    delete [] _data;
    if (_file != NULL)
        SFileCloseFile(_file);
}
コード例 #17
0
ファイル: SFileListFile.cpp プロジェクト: DoGoodS/StormLib
HANDLE WINAPI SListFileFindFirstFile(HANDLE hMpq, const char * szListFile, const char * szMask, SFILE_FIND_DATA * lpFindFileData)
{
    TListFileCache * pCache = NULL;
    HANDLE hListFile = NULL;
    size_t nLength = 0;
    DWORD dwSearchScope = SFILE_OPEN_LOCAL_FILE;
    int nError = ERROR_SUCCESS;

    // Initialize the structure with zeros
    memset(lpFindFileData, 0, sizeof(SFILE_FIND_DATA));

    // If the szListFile is NULL, it means we have to open internal listfile
    if(szListFile == NULL)
    {
        // Use SFILE_OPEN_ANY_LOCALE for listfile. This will allow us to load
        // the listfile even if there is only non-neutral version of the listfile in the MPQ
        dwSearchScope = SFILE_OPEN_ANY_LOCALE;
        szListFile = LISTFILE_NAME;
    }

    // Open the local/internal listfile
    if(!SFileOpenFileEx(hMpq, szListFile, dwSearchScope, &hListFile))
        nError = GetLastError();

    // Load the listfile to cache
    if(nError == ERROR_SUCCESS)
    {
        pCache = CreateListFileCache(hListFile, szMask);
        if(pCache == NULL)
            nError = ERROR_FILE_CORRUPT;
    }

    // Perform file search
    if(nError == ERROR_SUCCESS)
    {
        for(;;)
        {
            // Read the (next) line
            nLength = ReadListFileLine(pCache, lpFindFileData->cFileName, sizeof(lpFindFileData->cFileName));
            if(nLength == 0)
            {
                nError = ERROR_NO_MORE_FILES;
                break;
            }

            // If some mask entered, check it
            if(CheckWildCard(lpFindFileData->cFileName, pCache->szMask))
                break;                
        }
    }

    // Cleanup & exit
    if(nError != ERROR_SUCCESS)
    {
        memset(lpFindFileData, 0, sizeof(SFILE_FIND_DATA));
        SetLastError(nError);
    }

    if(pCache != NULL)
        FreeListFileCache(pCache);
    if(hListFile != NULL)
        SFileCloseFile(hListFile);
    return (HANDLE)pCache;
}
コード例 #18
0
static int CheckIfAllFilesKnown(TMPQArchive * ha, const char * szListFile, DWORD * pFileSeeds)
{
    TMPQHash * pHashTableCopy = NULL;   // Copy of the hash table
    TMPQHash * pHash;
    TMPQHash * pHashEnd = NULL;         // End of the hash table
    DWORD dwFileCount = 0;
    int nError = ERROR_SUCCESS;

    // First of all, create a copy of hash table
    if(nError == ERROR_SUCCESS)
    {
        if((pHashTableCopy = CopyHashTable(ha)) == NULL)
            nError = ERROR_NOT_ENOUGH_MEMORY;
        pHashEnd = pHashTableCopy + ha->pHeader->dwHashTableSize;

        // Notify the user
        if(CompactCB != NULL)
            CompactCB(lpUserData, CCB_CHECKING_FILES, 0, ha->pHeader->dwBlockTableSize);
    }

    // Now check all the files from the filelist
    if(nError == ERROR_SUCCESS)
    {
        SFILE_FIND_DATA wf;
        HANDLE hFind = SFileFindFirstFile((HANDLE)ha, "*", &wf, szListFile);
        BOOL bResult = TRUE;

        // Do while some files have been found
        while(hFind != NULL && bResult)
        {
            TMPQHash * pHash = GetHashEntry(ha, wf.cFileName);

            // If the hash table entry has been found, find it's position
            // in the hash table copy
            if(pHash != NULL)
            {
                pHash = pHashTableCopy + (pHash - ha->pHashTable);
                if(pHash->dwName1 != (DWORD)-1 && pHash->dwName2 != (DWORD)-1)
                {
                    TMPQBlock * pBlock = ha->pBlockTable + pHash->dwBlockIndex;
                    DWORD dwSeed = 0;

                    // Resolve the file seed. Use plain file name for it
                    if(pBlock->dwFlags & MPQ_FILE_ENCRYPTED)
                    {
                        char * szFileName = strrchr(wf.cFileName, '\\');

                        if(szFileName == NULL)
                            szFileName = wf.cFileName;
                        else
                            szFileName++;

                        dwSeed = DecryptFileSeed(szFileName);
                        if(pBlock->dwFlags & MPQ_FILE_FIXSEED)
                            dwSeed = (dwSeed + pBlock->dwFilePos) ^ pBlock->dwFSize;
                    }
                    pFileSeeds[pHash->dwBlockIndex] = dwSeed;

                    pHash->dwName1      = 0xFFFFFFFF;
                    pHash->dwName2      = 0xFFFFFFFF;
                    pHash->lcLocale     = 0xFFFF;
                    pHash->wPlatform    = 0xFFFF;
                    pHash->dwBlockIndex = 0xFFFFFFFF;
                }
            }
            // Notify the user
            if(CompactCB != NULL)
                CompactCB(lpUserData, CCB_CHECKING_FILES, ++dwFileCount, ha->pHeader->dwBlockTableSize);

            // Find the next file in the archive
            bResult = SFileFindNextFile(hFind, &wf);
        }

        if(hFind != NULL)
            SFileFindClose(hFind);
    }

    // When the filelist checking is complete, parse the hash table copy and find the
    if(nError == ERROR_SUCCESS)
    {
        // Notify the user about checking hash table
        dwFileCount = 0;
        if(CompactCB != NULL)
            CompactCB(lpUserData, CCB_CHECKING_HASH_TABLE, dwFileCount, ha->pHeader->dwBlockTableSize);

        for(pHash = pHashTableCopy; pHash < pHashEnd; pHash++)
        {
            // If there is an unresolved entry, try to detect its seed. If it fails,
            // we cannot complete the work
            if(pHash->dwName1 != (DWORD)-1 && pHash->dwName2 != (DWORD)-1)
            {
                HANDLE hFile  = NULL;
                DWORD dwFlags = 0;
                DWORD dwSeed  = 0;

                if(SFileOpenFileEx((HANDLE)ha, (char *)(DWORD_PTR)pHash->dwBlockIndex, SFILE_OPEN_BY_INDEX, &hFile))
                {
                    TMPQFile * hf = (TMPQFile *)hFile;
                    dwFlags = hf->pBlock->dwFlags;
                    dwSeed = hf->dwSeed1;
                    SFileCloseFile(hFile);
                }

                // If the file is encrypted, we have to check 
                // If we can apply the file decryption seed
                if(dwFlags & MPQ_FILE_ENCRYPTED && dwSeed == 0)
                {
                    nError = ERROR_CAN_NOT_COMPLETE;
                    break;
                }

                // Remember the seed
                pFileSeeds[pHash->dwBlockIndex] = dwSeed;

                // Notify the user
                if(CompactCB != NULL)
                    CompactCB(lpUserData, CCB_CHECKING_HASH_TABLE, ++dwFileCount, ha->pHeader->dwBlockTableSize);
            }
        }
    }

    // Delete the copy of hash table
    if(pHashTableCopy != NULL)
        FREEMEM(pHashTableCopy);
    return nError;
}
コード例 #19
0
// Performs one MPQ search
static int DoMPQSearch(TMPQSearch * hs, SFILE_FIND_DATA * lpFindFileData)
{
    TMPQArchive * ha = hs->ha;
    TFileEntry * pFileTableEnd;
    TFileEntry * pFileEntry;
    const char * szFileName;
    char szPseudoName[20];
    DWORD dwBlockIndex;
    size_t nPrefixLength;

    // Do that for all files in the patch chain
    while(ha != NULL)
    {
        // Now parse the file entry table in order to get all files.
        pFileTableEnd = ha->pFileTable + ha->dwFileTableSize;
        pFileEntry = ha->pFileTable + hs->dwNextIndex;

        // Get the start and end of the hash table
        nPrefixLength = strlen(ha->szPatchPrefix);

        // Parse the file table
        while(pFileEntry < pFileTableEnd)
        {
            // Increment the next index for subsequent search
            hs->dwNextIndex++;

            // Does the block exist ?
            if(pFileEntry->dwFlags & MPQ_FILE_EXISTS)
            {
                // Prepare the block index
                dwBlockIndex = (DWORD)(pFileEntry - ha->pFileTable);

                // Get the file name. If it's not known, we will create pseudo-name
                szFileName = pFileEntry->szFileName;
                if(szFileName == NULL)
                {
                    HANDLE hFile;

                    // Open the file by index in order to check if the file exists
                    if(SFileOpenFileEx((HANDLE)hs->ha, (char *)(DWORD_PTR)dwBlockIndex, SFILE_OPEN_BY_INDEX, &hFile))
                        SFileCloseFile(hFile);

                    // If the name was retrieved, use that one. Otherwise, just use generic pseudo-name
                    szFileName = pFileEntry->szFileName;
                    if(szFileName == NULL)
                    {
                        sprintf(szPseudoName, "File%08u.xxx", dwBlockIndex);
                        szFileName = szPseudoName;
                    }
                }

                // If we are already in the patch MPQ, we skip all files
                // that don't have the appropriate patch prefix and are patch files
                if(ha->haBase != NULL)
                {
                    // If the file has different patch prefix, don't report it
                    if(nPrefixLength != 0 && _strnicmp(szFileName, ha->szPatchPrefix, nPrefixLength))
                        goto __SkipThisFile;

                    //
                    // We need to properly handle the following case:
                    //
                    // 1) Base MPQ file doesn't contain the desired file
                    // 2) First patch MPQ contains the file with MPQ_FILE_PATCH_FILE
                    // 3) Second patch contains full version of the file (MPQ_FILE_PATCH_FILE is not set)
                    //

                    if(IsBaseFileMissing(ha, szFileName, szFileName + nPrefixLength, pFileEntry->lcLocale))
                        goto __SkipThisFile;
                }

                // Check the file name.
                if(CheckWildCard(szFileName, hs->szSearchMask))
                {
                    // Fill the found entry
                    lpFindFileData->dwHashIndex  = pFileEntry->dwHashIndex;
                    lpFindFileData->dwBlockIndex = dwBlockIndex;
                    lpFindFileData->dwFileSize   = pFileEntry->dwFileSize;
                    lpFindFileData->dwFileFlags  = pFileEntry->dwFlags;
                    lpFindFileData->dwCompSize   = pFileEntry->dwCmpSize;
                    lpFindFileData->lcLocale     = pFileEntry->lcLocale;

                    // Fill the filetime
                    lpFindFileData->dwFileTimeHi = (DWORD)(pFileEntry->FileTime >> 32);
                    lpFindFileData->dwFileTimeLo = (DWORD)(pFileEntry->FileTime);

                    // Fill the file name and plain file name
                    strcpy(lpFindFileData->cFileName, szFileName + nPrefixLength);
                    lpFindFileData->szPlainName = (char *)GetPlainFileName(lpFindFileData->cFileName);
                    return ERROR_SUCCESS;
                }
            }

            // Move to the next file entry
__SkipThisFile:

            pFileEntry++;
        }
コード例 #20
0
	void CMpqDataStream::Close()
	{
		SFileCloseFile(m_hFile);
	}
コード例 #21
0
ファイル: mpq.cpp プロジェクト: mityada/wowobjectviewer
QByteArray MPQ::readFile(const QString &fileName)
{
    static QHash<QString, QByteArray> files;

    static const QString mpqs[] = {
        "patch-2.MPQ",
        "patch.MPQ",
        "dbc.MPQ",
        "model.MPQ",
        "interface.MPQ",
        "texture.MPQ",
        ""
    };

    if (files.contains(fileName))
        return files[fileName];

    const QString *mpq = mpqs;

    HANDLE hMPQ = 0;

    while (!mpq->isEmpty()) {
        QString path = MPQ::gameDir() + "Data/" + *mpq;

        hMPQ = getHandle(path);

        if (hMPQ && SFileHasFile(hMPQ, fileName.toUtf8().constData()))
            break;
        else
            hMPQ = 0;

        mpq++;
    }

    if (!hMPQ) {
        qCritical("File '%s' not found", qPrintable(fileName));
        return files[fileName];
    }

    HANDLE hFile;

    if (!SFileOpenFileEx(hMPQ, fileName.toUtf8().constData(), SFILE_OPEN_FROM_MPQ, &hFile)) {
        qCritical("Cannot open file '%s' from archive", qPrintable(fileName));
        return files[fileName];
    }

    DWORD size = SFileGetFileSize(hFile, NULL);

    if (size == SFILE_INVALID_SIZE) {
        qCritical("Cannot read file '%s' from archive", qPrintable(fileName));
        return files[fileName];
    }

    char *data = new char[size];

    if (!SFileReadFile(hFile, data, size, NULL, NULL)) {
        qCritical("Cannot read file '%s' from archive", qPrintable(fileName));
        SFileCloseFile(hFile);
        delete[] data;
        return files[fileName];
    }

    SFileCloseFile(hFile);

    files[fileName] = QByteArray(data, size);

    delete[] data;

    return files[fileName];
}
コード例 #22
0
ファイル: SFileFindFile.cpp プロジェクト: DoGoodS/StormLib
// Performs one MPQ search
static int DoMPQSearch(TMPQSearch * hs, SFILE_FIND_DATA * lpFindFileData)
{
    TMPQArchive * ha = hs->ha;
    TFileEntry * pFileTableEnd;
    TFileEntry * pPatchEntry;
    TFileEntry * pFileEntry;
    const char * szFileName;
    HANDLE hFile;
    char szPseudoName[20];
    DWORD dwBlockIndex;
    size_t nPrefixLength;

    // Start searching with base MPQ
    while(ha != NULL)
    {
        // Now parse the file entry table in order to get all files.
        pFileTableEnd = ha->pFileTable + ha->dwFileTableSize;
        pFileEntry = ha->pFileTable + hs->dwNextIndex;

        // Get the length of the patch prefix (0 if none)
        nPrefixLength = strlen(ha->szPatchPrefix);

        // Parse the file table
        while(pFileEntry < pFileTableEnd)
        {
            // Increment the next index for subsequent search
            hs->dwNextIndex++;

            // Is it a file and not a patch file?
            if((pFileEntry->dwFlags & hs->dwFlagMask) == MPQ_FILE_EXISTS)
            {
                // Now we have to check if this file was not enumerated before
                if(!FileWasFoundBefore(ha, hs, pFileEntry))
                {
                    // Find a patch to this file
                    pPatchEntry = FindPatchEntry(ha, pFileEntry);
                    if(pPatchEntry == NULL)
                        pPatchEntry = pFileEntry;

                    // Prepare the block index
                    dwBlockIndex = (DWORD)(pFileEntry - ha->pFileTable);

                    // Get the file name. If it's not known, we will create pseudo-name
                    szFileName = pFileEntry->szFileName;
                    if(szFileName == NULL)
                    {
                        // Open the file by its pseudo-name.
                        // This also generates the file name with a proper extension
                        sprintf(szPseudoName, "File%08u.xxx", dwBlockIndex);
                        if(SFileOpenFileEx((HANDLE)hs->ha, szPseudoName, SFILE_OPEN_BASE_FILE, &hFile))
                        {
                            szFileName = (pFileEntry->szFileName != NULL) ? pFileEntry->szFileName : szPseudoName;
                            SFileCloseFile(hFile);
                        }
                    }

                    // Check the file name against the wildcard
                    if(CheckWildCard(szFileName + nPrefixLength, hs->szSearchMask))
                    {
                        // Fill the found entry
                        lpFindFileData->dwHashIndex  = pPatchEntry->dwHashIndex;
                        lpFindFileData->dwBlockIndex = dwBlockIndex;
                        lpFindFileData->dwFileSize   = pPatchEntry->dwFileSize;
                        lpFindFileData->dwFileFlags  = pPatchEntry->dwFlags;
                        lpFindFileData->dwCompSize   = pPatchEntry->dwCmpSize;
                        lpFindFileData->lcLocale     = pPatchEntry->lcLocale;

                        // Fill the filetime
                        lpFindFileData->dwFileTimeHi = (DWORD)(pPatchEntry->FileTime >> 32);
                        lpFindFileData->dwFileTimeLo = (DWORD)(pPatchEntry->FileTime);

                        // Fill the file name and plain file name
                        strcpy(lpFindFileData->cFileName, szFileName + nPrefixLength);
                        lpFindFileData->szPlainName = (char *)GetPlainFileNameA(lpFindFileData->cFileName);
                        return ERROR_SUCCESS;
                    }

                }
            }

            pFileEntry++;
        }
コード例 #23
0
static int CheckIfAllFilesKnown(TMPQArchive * ha, const char * szListFile, DWORD * pFileKeys)
{
    TMPQHash * pHashTableCopy = NULL;   // Copy of the hash table
    TMPQHash * pHash;
    TMPQHash * pHashEnd = NULL;         // End of the hash table
    DWORD dwFileCount = 0;
    int nError = ERROR_SUCCESS;

    // First of all, create a copy of hash table
    if(nError == ERROR_SUCCESS)
    {
        if((pHashTableCopy = CopyHashTable(ha)) == NULL)
            nError = ERROR_NOT_ENOUGH_MEMORY;
        pHashEnd = pHashTableCopy + ha->pHeader->dwHashTableSize;

        // Notify the user
        if(CompactCB != NULL)
            CompactCB(pvUserData, CCB_CHECKING_FILES, &CompactBytesProcessed, &CompactTotalBytes);
    }

    // Now check all the files from the listfile
    if(nError == ERROR_SUCCESS)
    {
        SFILE_FIND_DATA wf;
        HANDLE hFind = SFileFindFirstFile((HANDLE)ha, "*", &wf, szListFile);
        bool bResult = true;

        // Do while something has been found
        while(hFind != NULL && bResult)
        {
            TMPQHash * pHash = ha->pHashTable + wf.dwHashIndex;

            // Find the entry in the hash table copy
            pHash = pHashTableCopy + (pHash - ha->pHashTable);
            if(pHash->dwBlockIndex != HASH_ENTRY_FREE)
            {
                TMPQBlock * pBlock = ha->pBlockTable + pHash->dwBlockIndex;
                DWORD dwFileKey = 0;

                // Resolve the file key. Use plain file name for it
                if(pBlock->dwFlags & MPQ_FILE_ENCRYPTED)
                {
                    const char * szPlainName = GetPlainMpqFileName(wf.cFileName);

                    dwFileKey = DecryptFileKey(szPlainName);
                    if(pBlock->dwFlags & MPQ_FILE_FIX_KEY)
                        dwFileKey = (dwFileKey + pBlock->dwFilePos) ^ pBlock->dwFSize;
                }

                // Give the key to the caller
                pFileKeys[pHash->dwBlockIndex] = dwFileKey;

                pHash->dwName1      = 0xFFFFFFFF;
                pHash->dwName2      = 0xFFFFFFFF;
                pHash->lcLocale     = 0xFFFF;
                pHash->wPlatform    = 0xFFFF;
                pHash->dwBlockIndex = HASH_ENTRY_FREE;
            }

            // Find the next file in the archive
            bResult = SFileFindNextFile(hFind, &wf);
        }

        if(hFind != NULL)
            SFileFindClose(hFind);
    }

    // When the filelist checking is complete, parse the hash table copy and find the
    if(nError == ERROR_SUCCESS)
    {
        // Notify the user about checking hash table
        dwFileCount = 0;
        if(CompactCB != NULL)
            CompactCB(pvUserData, CCB_CHECKING_HASH_TABLE, &CompactBytesProcessed, &CompactTotalBytes);

        for(pHash = pHashTableCopy; pHash < pHashEnd; pHash++)
        {
            // If there is an unresolved entry, try to detect its key. If it fails,
            // we cannot complete the work
            if(pHash->dwBlockIndex < ha->pHeader->dwBlockTableSize)
            {
                HANDLE hFile  = NULL;
                DWORD dwFlags = 0;
                DWORD dwFileKey  = 0;

                if(SFileOpenFileEx((HANDLE)ha, (char *)(DWORD_PTR)pHash->dwBlockIndex, SFILE_OPEN_BY_INDEX, &hFile))
                {
                    TMPQFile * hf = (TMPQFile *)hFile;
                    dwFlags = hf->pBlock->dwFlags;
                    dwFileKey = hf->dwFileKey;
                    SFileCloseFile(hFile);
                }

                // If the file is encrypted, we have to check
                // If we can apply the file decryption key
                if((dwFlags & MPQ_FILE_ENCRYPTED) && dwFileKey == 0)
                {
                    nError = ERROR_CAN_NOT_COMPLETE;
                    break;
                }

                // Give the key to the caller
                pFileKeys[pHash->dwBlockIndex] = dwFileKey;
            }
        }
    }

    // Delete the copy of hash table
    if(pHashTableCopy != NULL)
        FREEMEM(pHashTableCopy);
    return nError;
}
コード例 #24
0
ファイル: SFileVerify.cpp プロジェクト: Zim4ikUKR/PseuWoW
static DWORD VerifyFile(
    HANDLE hMpq,
    const char * szFileName,
    LPDWORD pdwCrc32,
    char * pMD5,
    DWORD dwFlags)
{
    hash_state md5_state;
    unsigned char * pFileMd5;
    unsigned char md5[MD5_DIGEST_SIZE];
    TFileEntry * pFileEntry;
    TMPQFile * hf;
    BYTE Buffer[0x1000];
    HANDLE hFile = NULL;
    DWORD dwVerifyResult = 0;
    DWORD dwSearchScope = SFILE_OPEN_FROM_MPQ;
    DWORD dwTotalBytes = 0;
    DWORD dwBytesRead;
    DWORD dwCrc32 = 0;

    // Fix the open type for patched archives
    if(SFileIsPatchedArchive(hMpq))
        dwSearchScope = SFILE_OPEN_PATCHED_FILE;

    // Attempt to open the file
    if(SFileOpenFileEx(hMpq, szFileName, dwSearchScope, &hFile))
    {
        // Get the file size
        hf = (TMPQFile *)hFile;
        pFileEntry = hf->pFileEntry;
        dwTotalBytes = SFileGetFileSize(hFile, NULL);

        // Initialize the CRC32 and MD5 contexts
        md5_init(&md5_state);
        dwCrc32 = crc32(0, Z_NULL, 0);

        // If we have to verify raw data MD5, do it
        if(dwFlags & SFILE_VERIFY_RAW_MD5)
        {
            if(hf->ha->pHeader->dwRawChunkSize != 0)
            {
                // Note: we have to open the file from the MPQ where it was open from
                if(VerifyRawMpqData(hf->ha, pFileEntry->ByteOffset, pFileEntry->dwCmpSize) != ERROR_SUCCESS)
                    dwVerifyResult |= VERIFY_FILE_RAW_MD5_ERROR;
                dwVerifyResult |= VERIFY_FILE_HAS_RAW_MD5;
            }
        }

        // Also turn on sector checksum verification
        if(dwFlags & SFILE_VERIFY_SECTOR_CRC)
            hf->bCheckSectorCRCs = true;

        // Go through entire file and update both CRC32 and MD5
        for(;;)
        {
            // Read data from file
            SFileReadFile(hFile, Buffer, sizeof(Buffer), &dwBytesRead, NULL);
            if(dwBytesRead == 0)
            {
                if(GetLastError() == ERROR_CHECKSUM_ERROR)
                    dwVerifyResult |= VERIFY_FILE_SECTOR_CRC_ERROR;
                break;
            }

            // Update CRC32 value
            if(dwFlags & SFILE_VERIFY_FILE_CRC)
                dwCrc32 = crc32(dwCrc32, Buffer, dwBytesRead);
            
            // Update MD5 value
            if(dwFlags & SFILE_VERIFY_FILE_MD5)
                md5_process(&md5_state, Buffer, dwBytesRead);

            // Decrement the total size
            dwTotalBytes -= dwBytesRead;
        }

        // If the file has sector checksums, indicate it in the flags
        if(dwFlags & SFILE_VERIFY_SECTOR_CRC)
        {
            if((hf->pFileEntry->dwFlags & MPQ_FILE_SECTOR_CRC) && hf->SectorChksums != NULL && hf->SectorChksums[0] != 0)
                dwVerifyResult |= VERIFY_FILE_HAS_SECTOR_CRC;
        }

        // Check if the entire file has been read
        // No point in checking CRC32 and MD5 if not
        // Skip checksum checks if the file has patches
        if(dwTotalBytes == 0)
        {
            // Check CRC32 and MD5 only if there is no patches
            if(hf->hfPatchFile == NULL)
            {
                // Check if the CRC32 matches.
                if(dwFlags & SFILE_VERIFY_FILE_CRC)
                {
                    // Only check the CRC32 if it is valid
                    if(pFileEntry->dwCrc32 != 0)
                    {
                        dwVerifyResult |= VERIFY_FILE_HAS_CHECKSUM;
                        if(dwCrc32 != pFileEntry->dwCrc32)
                            dwVerifyResult |= VERIFY_FILE_CHECKSUM_ERROR;
                    }
                }

                // Check if MD5 matches
                if(dwFlags & SFILE_VERIFY_FILE_MD5)
                {
                    // Patch files have their MD5 saved in the patch info
                    pFileMd5 = (hf->pPatchInfo != NULL) ? hf->pPatchInfo->md5 : pFileEntry->md5;
                    md5_done(&md5_state, md5);

                    // Only check the MD5 if it is valid
                    if(is_valid_md5(pFileMd5))
                    {
                        dwVerifyResult |= VERIFY_FILE_HAS_MD5;
                        if(memcmp(md5, pFileMd5, MD5_DIGEST_SIZE))
                            dwVerifyResult |= VERIFY_FILE_MD5_ERROR;
                    }
                }
            }
            else
            {
                // Patched files are MD5-checked automatically
                dwVerifyResult |= VERIFY_FILE_HAS_MD5;
            }
        }
        else
        {
            dwVerifyResult |= VERIFY_READ_ERROR;
        }

        SFileCloseFile(hFile);
    }
    else
    {
        // Remember that the file couldn't be open
        dwVerifyResult |= VERIFY_OPEN_ERROR;
    }

    // If the caller required CRC32 and/or MD5, give it to him
    if(pdwCrc32 != NULL)
        *pdwCrc32 = dwCrc32;
    if(pMD5 != NULL)
        memcpy(pMD5, md5, MD5_DIGEST_SIZE); 

    return dwVerifyResult;
}
コード例 #25
0
ファイル: dbcfile.cpp プロジェクト: Chuck5ta/server-4
bool DBCFile::open()
{
    //if (!OpenNewestFile(filename.c_str(), &fileHandle))
    //    return false;

    char header[4];
    unsigned int na, nb, es, ss;

    if (!SFileReadFile(fileHandle, header, 4, NULL, NULL))              // Magic header
    {
        SFileCloseFile(fileHandle);
        return false;
    }

    if (header[0] != 'W' || header[1] != 'D' || header[2] != 'B' || header[3] != 'C')
    {
        SFileCloseFile(fileHandle);
        return false;
    }

    if (!SFileReadFile(fileHandle, &na, 4, NULL, NULL))                 // Number of records
    {
        SFileCloseFile(fileHandle);
        return false;
    }

    if (!SFileReadFile(fileHandle, &nb, 4, NULL, NULL))                 // Number of fields
    {
        SFileCloseFile(fileHandle);
        return false;
    }

    if (!SFileReadFile(fileHandle, &es, 4, NULL, NULL))                 // Size of a record
    {
        SFileCloseFile(fileHandle);
        return false;
    }

    if (!SFileReadFile(fileHandle, &ss, 4, NULL, NULL))                 // String size
    {
        SFileCloseFile(fileHandle);
        return false;
    }

    recordSize = es;
    recordCount = na;
    fieldCount = nb;
    stringSize = ss;
    if (fieldCount * 4 != recordSize)
    {
        SFileCloseFile(fileHandle);
        return false;
    }

    data = new unsigned char[recordSize * recordCount + stringSize];
    stringTable = data + recordSize * recordCount;

    size_t data_size = recordSize * recordCount + stringSize;

    if (!SFileReadFile(fileHandle, data, data_size, NULL, NULL))
    {
        SFileCloseFile(fileHandle);
        return false;
    }

    SFileCloseFile(fileHandle);
    return true;
}
コード例 #26
0
ファイル: SFileFindFile.cpp プロジェクト: 1143910315/StormLib
static bool DoMPQSearch_FileEntry(
    TMPQSearch * hs,
    SFILE_FIND_DATA * lpFindFileData,
    TMPQArchive * ha,
    TMPQHash * pHashEntry,
    TFileEntry * pFileEntry)
{
    TFileEntry * pPatchEntry;
    HANDLE hFile = NULL;
    const char * szFileName;
    size_t nPrefixLength = (ha->pPatchPrefix != NULL) ? ha->pPatchPrefix->nLength : 0;
    DWORD dwBlockIndex;
    char szNameBuff[MAX_PATH];

    // Is it a file but not a patch file?
    if((pFileEntry->dwFlags & hs->dwFlagMask) == MPQ_FILE_EXISTS)
    {
        // Now we have to check if this file was not enumerated before
        if(!FileWasFoundBefore(ha, hs, pFileEntry))
        {
//          if(pFileEntry != NULL && !_stricmp(pFileEntry->szFileName, "TriggerLibs\\NativeLib.galaxy"))
//              DebugBreak();

            // Find a patch to this file
            pPatchEntry = FindPatchEntry(ha, pFileEntry);
            if(pPatchEntry == NULL)
                pPatchEntry = pFileEntry;

            // Prepare the block index
            dwBlockIndex = (DWORD)(pFileEntry - ha->pFileTable);

            // Get the file name. If it's not known, we will create pseudo-name
            szFileName = pFileEntry->szFileName;
            if(szFileName == NULL)
            {
                // Open the file by its pseudo-name.
                sprintf(szNameBuff, "File%08u.xxx", (unsigned int)dwBlockIndex);
                if(SFileOpenFileEx((HANDLE)hs->ha, szNameBuff, SFILE_OPEN_BASE_FILE, &hFile))
                {
                    SFileGetFileName(hFile, szNameBuff);
                    szFileName = szNameBuff;
                    SFileCloseFile(hFile);
                }
            }

            // If the file name is still NULL, we cannot include the file to search results
            if(szFileName != NULL)
            {
                // Check the file name against the wildcard
                if(CheckWildCard(szFileName + nPrefixLength, hs->szSearchMask))
                {
                    // Fill the found entry. hash entry and block index are taken from the base MPQ
                    lpFindFileData->dwHashIndex  = HASH_ENTRY_FREE;
                    lpFindFileData->dwBlockIndex = dwBlockIndex;
                    lpFindFileData->dwFileSize   = pPatchEntry->dwFileSize;
                    lpFindFileData->dwFileFlags  = pPatchEntry->dwFlags;
                    lpFindFileData->dwCompSize   = pPatchEntry->dwCmpSize;
                    lpFindFileData->lcLocale     = 0;   // pPatchEntry->lcLocale;

                    // Fill the filetime
                    lpFindFileData->dwFileTimeHi = (DWORD)(pPatchEntry->FileTime >> 32);
                    lpFindFileData->dwFileTimeLo = (DWORD)(pPatchEntry->FileTime);

                    // Fill-in the entries from hash table entry, if given
                    if(pHashEntry != NULL)
                    {
                        lpFindFileData->dwHashIndex = (DWORD)(pHashEntry - ha->pHashTable);
                        lpFindFileData->lcLocale = pHashEntry->lcLocale;
                    }

                    // Fill the file name and plain file name
                    StringCopyA(lpFindFileData->cFileName, szFileName + nPrefixLength, MAX_PATH-1);
                    lpFindFileData->szPlainName = (char *)GetPlainFileName(lpFindFileData->cFileName);
                    return true;
                }
            }
        }
コード例 #27
0
ファイル: DLLMain.cpp プロジェクト: RadicalZephyr/bwapi
//------------------------------------------------- DLL MAIN -------------------------------------------------
BOOL APIENTRY DllMain(HMODULE, DWORD ul_reason_for_call, LPVOID)
{
  switch (ul_reason_for_call)
  {
    case DLL_PROCESS_ATTACH:
      {
#ifdef _DEBUG
        _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
#endif
        // Retrieve the initial configuration stuff if not already
        InitPrimaryConfig();

        // Get revision/build automatically
        char szDllPath[MAX_PATH];

        DWORD dwDesiredRevision = 0;
        std::string aicfg = LoadConfigString("ai", BUILD_DEBUG ? "ai_dbg" : "ai", "_NULL");
        strncpy(szDllPath, aicfg.c_str(), MAX_PATH);

        if ( aicfg == "_NULL" )
        {
            BWAPIError("Could not find %s under ai in \"%s\" for revision identification.", BUILD_DEBUG ? "ai_dbg" : "ai", szConfigPath);
        }
        else
        {
          DWORD dwDesiredBuild    = 0; // 0 = undefined, 1 = release, 2 = debug

          // Tokenize and retrieve correct path for the instance number
          char *pszDll = strtok(szDllPath, ",");
          for ( unsigned int i = 0; i < gdwProcNum-1; ++i )
          {
            char *pszNext = strtok(NULL, ",");
            if ( !pszNext )
              break;
            pszDll = pszNext;
          }
          // Retrieve revision info if it exists
          char *pszLoadRevCheck = strchr(pszDll, ':');
          if ( pszLoadRevCheck )
          {
            pszLoadRevCheck[0] = 0;
            ++pszLoadRevCheck;
            sscanf(pszLoadRevCheck, "%u", &dwDesiredRevision);
          }

          // Remove spaces
          while ( isspace(pszDll[0]) )
            ++pszDll;

          // Open File
          HANDLE hFile = NULL;
          if ( !SFileOpenFileEx(NULL, pszDll, SFILE_FROM_ABSOLUTE, &hFile) || !hFile)
          {
              BWAPIError("Could not load module \"%s\" for revision identification.", pszDll);
          }
          else
          {
            // Obtain file size
            DWORD dwFileSize = SFileGetFileSize(hFile, 0);

            // Allocate memory
            char *pbBuffer = (char*)SMAlloc(dwFileSize);
            if ( !pbBuffer )
            {
                BWAPIError("Unable to allocate enough memory for module \"%s\" for revision identification.", pszDll);
            }
            else
            {
              // Read file
              DWORD dwBytesRead = 0;
              SFileReadFile(hFile, pbBuffer, dwFileSize, &dwBytesRead, 0);
              for ( u32 i = 0; i < dwBytesRead && (dwDesiredRevision == 0 || dwDesiredBuild == 0); ++i )
              {
                if ( dwDesiredRevision == 0 && memcmp(&pbBuffer[i], "XBWAPIXREVISIONXSTAMPX", 22) == 0 )
                {
                  i += 22;
                  sscanf(&pbBuffer[i], "%u", &dwDesiredRevision);
                  i += 5;
                }  // if REVISION
                if ( memcmp(&pbBuffer[i], "XBWAPIXBUILDXSTAMPX", 19) == 0 )
                {
                  i += 19;
                  if ( strcmp(&pbBuffer[i], "DEBUG") == 0 )
                  {
                    dwDesiredBuild = 2;
                    i += 6;
                  }
                  else if ( strcmp(&pbBuffer[i], "RELEASE") == 0 )
                  {
                    dwDesiredBuild = 1;
                    i += 8;
                  }
                } // if BUILD
              } // for (iterate file)
              // Free memory and close file
              SMFree(pbBuffer);
              SFileCloseFile(hFile);
            } // buffer was allocated
          } // file was opened

          /* Do revision checking */
          if ( dwDesiredRevision > 0 && dwDesiredRevision != SVN_REV )
          {
            // revision that ai_dll_# for multiple instances was introduced
            if ( gdwProcNum && dwDesiredRevision < 2753 && showWarn )
            {
              char err[512];
              sprintf(err, "Revision %u is not compatible with multiple instances.\nExpecting revision 2753 (BWAPI Beta 3.1) or greater. If you proceed, the older revision of BWAPI will attempt to load its module from ai_dll instead of the multi-instance specification. Do you want to continue anyway?", dwDesiredRevision);
              BWAPIError("%s", err);
              if ( MessageBox(NULL, err, "Error", MB_YESNO | MB_ICONWARNING | MB_DEFBUTTON1 | MB_TASKMODAL) == IDNO )
                return TRUE;
            } // revision is old

            if ( dwDesiredBuild == 0 )
              dwDesiredBuild = BUILD_DEBUG + 1;
            char szRevModule[MAX_PATH];
            sprintf_s(szRevModule, MAX_PATH, "%sbwapi-data\\revisions\\%u%s.dll", szInstallPath, dwDesiredRevision, dwDesiredBuild == 2 ? "d" : "");
            HMODULE hLib = LoadLibrary(szRevModule);
            if ( hLib )
            {
              if ( showWarn )
              {
                char msg[MAX_PATH+32];
                char szLoadedName[MAX_PATH];
                GetModuleFileName(hLib, szLoadedName, MAX_PATH);
                sprintf_s(msg, MAX_PATH+32, "Loaded \"%s\" instead.", szLoadedName);
                MessageBox(NULL, msg, "Success", MB_OK | MB_ICONINFO);
              }
              return TRUE;
            }

            if ( showWarn )
            {
              char err[512];
              sprintf(err, "Couldn't find revision module \"%s\" of which the AI DLL was compiled for. Do you want to try using the current revision instead?", szRevModule);
              BWAPIError("%s", err);
              if ( MessageBox(NULL, err, "Error", MB_YESNO | MB_ICONWARNING | MB_DEFBUTTON1 | MB_TASKMODAL) == IDNO )
                return TRUE;
            }
          } // specified rev is not this one
          else if ( dwDesiredBuild && BUILD_DEBUG + 1 != dwDesiredBuild )
          {
            char envBuffer[MAX_PATH];
            if ( !GetEnvironmentVariable("ChaosDir", envBuffer, MAX_PATH) )
              if ( !GetCurrentDirectory(MAX_PATH, envBuffer) && showWarn )
                BWAPIError("Could not find ChaosDir or current directory for build identification.");

            SStrNCat(envBuffer, "\\BWAPI", MAX_PATH);
            if ( dwDesiredBuild == 2 )
              SStrNCat(envBuffer, "d", MAX_PATH);
            SStrNCat(envBuffer, ".dll", MAX_PATH);

            HMODULE hLib = LoadLibrary(envBuffer);
            if ( hLib )
            {
              if ( showWarn )
              {
                char msg[MAX_PATH+32];
                sprintf_s(msg, MAX_PATH+32, "Loaded \"%s\" instead.", envBuffer);
                MessageBox(NULL, msg, "Success", MB_OK | MB_ICONINFO);
              }
              return TRUE;
            }

            if ( showWarn )
            {
              char err[512];
              sprintf(err, "Couldn't find build module \"%s\" of which the AI DLL was compiled for. Do you want to try using the current build instead?", envBuffer);
              BWAPIError("%s", err);
              if ( MessageBox(NULL, err, "Error", MB_YESNO | MB_ICONWARNING | MB_DEFBUTTON1 | MB_TASKMODAL) == IDNO )
                return TRUE;
            }
            return TRUE;
          }
        } // module str was found

        // Do version checking
        CheckVersion();

        // Load the auto-menu config
        BWAPI::BroodwarImpl.loadAutoMenuData();

        // Apply all hacks and patches to the game
        ApplyCodePatches();

        // Initialize BWAPI
        BWAPI::BWAPI_init();

        // Create our thread that persistently applies hacks
        CreateThread(NULL, 0, &PersistentPatch, NULL, 0, NULL);

        return TRUE;
      }
  }
  return TRUE;
}