Пример #1
0
	bool MpkManip::cleanupFragment(const char* mpkFilename)
	{
		bool bOk = false;
		HANDLE hMpk = 0;
		char tempFilename[MAX_PATH];
		if(SFileCreateArchiveEx(mpkFilename,OPEN_EXISTING,8000,&hMpk))
		{
			uint nTotal = SFileGetFileInfo(hMpk,SFILE_INFO_NUM_FILES);
			uint nFiles = 0;
			char tempPath[MAX_PATH];
			getTempPath(MAX_PATH, tempPath);
			getTempFileName(tempPath,tempFilename);

			HANDLE hTargetMpk = 0;
			if(SFileCreateArchiveEx(tempFilename,CREATE_ALWAYS,8000,&hTargetMpk))
			{
				SFILE_FIND_DATA fileFindData;
				HANDLE hFind = SFileFindFirstFile(hMpk,"*",&fileFindData,0);
				if(hFind)
				{
					do
					{
						const char* pFilename = fileFindData.cFileName;
						char tempFilename[MAX_PATH];
						getTempFileName(tempPath,tempFilename);
						if(SFileExtractFile(hMpk,pFilename,tempFilename))
						{
							if(SFileAddFile(hTargetMpk,tempFilename,pFilename,MPK_FILE_REPLACEEXISTING | MPK_FILE_COMPRESS_PKWARE))
							{
								nFiles++;
							}
						}
					}
					while(SFileFindNextFile(hFind,&fileFindData));

					if(nTotal == nFiles)bOk = true;
				}
				SFileCloseArchive(hTargetMpk);
			}

			SFileCloseArchive(hMpk);
		}

		if(bOk && copyFile(tempFilename,mpkFilename,FALSE))
		{
			bOk = true;
		}

		return bOk;
	}
Пример #2
0
STDCALL void merc_inventory_mpq_unload(void)
{
	if (!merc_mpq)
		return;

	SFileCloseArchive(merc_mpq);
}
Пример #3
0
int getFileType(const char *szFileName)
{
  if ( !szFileName )
    return 0;

  int rVal = 0;
  HANDLE hMPQ;
  HANDLE hFile;
  // Open archive for map checking
  if ( SFileOpenArchive(szFileName, 0, 0, &hMPQ) && hMPQ )
  {
    // Open scenario.chk file
    if ( SFileOpenFileEx(hMPQ, "staredit\\scenario.chk", SFILE_FROM_MPQ, &hFile) && hFile )
    {
      rVal = 1;
      SFileCloseFile(hFile);
    }
    // Close archive
    SFileCloseArchive(hMPQ);
  }
  else if ( SFileOpenFileEx(NULL, szFileName, SFILE_FROM_ABSOLUTE, &hFile) && hFile )
  {
    DWORD dwRead = 0;
    char tbuff[16];
    DWORD dwSize = SFileGetFileSize(hFile, 0);
    // Read file data to check if it's a replay
    if ( dwSize > 16 && SFileReadFile(hFile, &tbuff, 16, &dwRead, 0) && dwRead == 16 && *(DWORD*)&tbuff[12] == 'SRer' )
      rVal = 2;
    // Close file
    SFileCloseFile(hFile);
  }
  return rVal;
}
Пример #4
0
 void quit()
 {
     if (NULL != diabdat)
     {
         SFileCloseArchive(diabdat);
     }
 }
Пример #5
0
	~stormlib_builder()
	{
		if (handle_)
		{
			SFileCloseArchive(handle_);
			handle_ = NULL;
		}
	}
Пример #6
0
BOOL WINAPI SFileCloseArchive_stub(MPQHANDLE hMPQ)
{
	LoadSFMpqDll();
	if (hSFMpq) {
		*(FARPROC *)&SFileCloseArchive = GetProcAddress(hSFMpq,"SFileCloseArchive");
		if (SFileCloseArchive) return SFileCloseArchive(hMPQ);
	}
	return FALSE;
}
Пример #7
0
static void MPQ_closeArchive(void *opaque)
{
    MPQHandle *handle = (MPQHandle*)opaque;

    if (!handle)
        return;

    SFileCloseArchive(handle->mpqHandle);
    handle->io->destroy(handle->io);
    allocator.Free(handle);
}
Пример #8
0
void MainWindow::closeMPQ()
{
    FAIO::quit();

    ui->listView->clear();

    if (mDiabdat)
    {
        SFileCloseArchive(mDiabdat);
        mDiabdat = NULL;
    }
}
Пример #9
0
	bool MpkManip::close()
	{
		if(!m_hMpk)return true;

		bool bOk = SFileCloseArchive(m_hMpk) != FALSE;
		if(bOk)
		{
			m_hMpk = 0;
		}

		return bOk;
	}
Пример #10
0
	uint MpkManip::getUseRate(const char* mpkFilename)
	{
		HANDLE hMpk = 0;
		uint nRate = 100;
		if(SFileCreateArchiveEx(mpkFilename,OPEN_EXISTING,8000,&hMpk))
		{
			DWORD dwTotal,dwFree;
			SFileGetBlockNum(hMpk,dwTotal,dwFree);
			if(dwTotal > 0)
				nRate = 100 * (dwTotal - dwFree) / dwTotal;
			SFileCloseArchive(hMpk);
		}

		return nRate;
	}
Пример #11
0
int SC2Map::readMap()
{
  HANDLE archive;

  string fullArchiveName( argPath );
  fullArchiveName.append( archiveWithExt );

  if( !SFileOpenArchive( fullArchiveName.data(), 0, 0, &archive ) )
  {
    printWarning( "Could not open map MPQ archive file %s\n", archiveWithExt.data() );
    return -1;
  }

  // the order of reading archive files is important--some
  // analysis data structures are depedenent on one another
  if( readGameStrings_txt( archive ) < 0 )
  {
    printWarning( "Could not find a locale to extract map name, using archive filename instead.\n" );
    mapName.assign( archiveName );
  }
  // however we got a name for the map, make a version
  // that is valid for use in filenames
  makeMapNameValidForFilenames();

  printMessage( "  map name found for preferred locale: [%s]\n", mapName.data() );
  printMessage( "  map name as part of filenames:       [%s]\n", mapNameInOutputFiles.data() );

  if( readMapInfo( archive ) < 0 )
  {
    printMessage( "  No MapInfo file.\n" );
    return -1;
  }

  if( debugMapInfo > 0 )
  {
    printMessage( "End debugging MapInfo\n" );
    exit( 0 );
  }

  if( readt3HeightMap( archive ) < 0 )
  {
    printMessage( "  No t3HeightMap file.\n" );
    return -1;
  }

  computePathingFromCliffChanges();

  if( readt3Terrain_xml( archive ) < 0 )
  {
    printMessage( "  No Terrain.xml file, continuing...\n" );
  }

  if( readPaintedPathingLayer( archive ) < 0 )
  {
    printMessage( "  No PaintedPathingLayer file, continuing...\n" );
  }

  if( readObjects( archive ) < 0 )
  {
    printMessage( "  No Objects file, (StartLocs, resources, etc.), continuing...\n" );
  } else {
    // only do this after all Objects are read
    applyFillsAndFootprints();

    if( startLocs.empty() )
    {
      printWarning( "No start locations have been placed, some outputs may have odd values.\n" );
    }
  }

  if( debugObjects > 0 )
  {
    printMessage( "End debugging Objects\n" );
    exit( 0 );
  }


  SFileCloseArchive( archive );
  return 0;
}
Пример #12
0
int main(int argc, char * arg[])
{
    printf("Map & DBC Extractor\n");
    printf("===================\n\n");

    HandleArgs(argc, arg);

    int FirstLocale = -1;
    uint32 build = 0;

    for (int i = 0; i < LOCALES_COUNT; ++i)
    {
        TCHAR tmp1[512];
        _stprintf(tmp1, _T("%s/Data/%s/locale-%s.MPQ"), input_path, Locales[i], Locales[i]);

        //Open MPQs
        if (!LoadLocaleMPQFile(i))
        {
            if (GetLastError() != ERROR_PATH_NOT_FOUND)
                printf("Unable to load %s locale archives!\n", Locales[i]);
            continue;
        }

        printf("Detected locale: %s\n", Locales[i]);
        if ((CONF_extract & EXTRACT_DBC) == 0)
        {
            FirstLocale = i;
            build = ReadBuild(i);
            if (build > CONF_TargetBuild)
            {
                printf("Base locale-%s.MPQ has build higher than target build (%u > %u), nothing extracted!\n", Locales[i], build, CONF_TargetBuild);
                return 0;
            }

            printf("Detected client build: %u\n", build);
            break;
        }

        //Extract DBC files
        uint32 tempBuild = ReadBuild(i);
        printf("Detected client build %u for locale %s\n", tempBuild, Locales[i]);
        if (tempBuild > CONF_TargetBuild)
        {
            printf("Base locale-%s.MPQ has build higher than target build (%u > %u), nothing extracted!\n", Locales[i], tempBuild, CONF_TargetBuild);
            continue;
        }

        ExtractDBCFiles(i, FirstLocale < 0);
        ExtractDB2Files(i, FirstLocale < 0);

        if (FirstLocale < 0)
        {
            FirstLocale = i;
            build = tempBuild;
        }

        //Close MPQs
        SFileCloseArchive(LocaleMpq);
    }

    if (FirstLocale < 0)
    {
        printf("No locales detected\n");
        return 0;
    }

    if (CONF_extract & EXTRACT_MAP)
    {
        printf("Using locale: %s\n", Locales[FirstLocale]);

        // Open MPQs
        LoadLocaleMPQFile(FirstLocale);
        LoadCommonMPQFiles(build);

        // Extract maps
        ExtractMapsFromMpq(build);

        // Close MPQs
        SFileCloseArchive(WorldMpq);
        SFileCloseArchive(LocaleMpq);
    }

    return 0;
}
Пример #13
0
bool WINAPI SFileCreateArchive2(const TCHAR * szMpqName, PSFILE_CREATE_MPQ pCreateInfo, HANDLE * phMpq)
{
    TFileStream * pStream = NULL;           // File stream
    TMPQArchive * ha = NULL;                // MPQ archive handle
    ULONGLONG MpqPos = 0;                   // Position of MPQ header in the file
    HANDLE hMpq = NULL;
    DWORD dwBlockTableSize = 0;             // Initial block table size
    DWORD dwHashTableSize = 0;
    DWORD dwMaxFileCount;
    int nError = ERROR_SUCCESS;

    // Check the parameters, if they are valid
    if(szMpqName == NULL || *szMpqName == 0 || pCreateInfo == NULL || phMpq == NULL)
    {
        SetLastError(ERROR_INVALID_PARAMETER);
        return false;
    }

    // Verify if all variables in SFILE_CREATE_MPQ are correct
    if((pCreateInfo->cbSize == 0 || pCreateInfo->cbSize > sizeof(SFILE_CREATE_MPQ)) ||
       (pCreateInfo->dwMpqVersion > MPQ_FORMAT_VERSION_4)                        ||
       (pCreateInfo->pvUserData != NULL || pCreateInfo->cbUserData != 0)            ||
       (pCreateInfo->dwAttrFlags & ~MPQ_ATTRIBUTE_ALL)                              ||
       (pCreateInfo->dwSectorSize & (pCreateInfo->dwSectorSize - 1))                ||
       (pCreateInfo->dwRawChunkSize & (pCreateInfo->dwRawChunkSize - 1))            ||
       (pCreateInfo->dwMaxFileCount < 4))
    {
        SetLastError(ERROR_INVALID_PARAMETER);
        return false;
    }

    // One time initialization of MPQ cryptography
    InitializeMpqCryptography();

    // We verify if the file already exists and if it's a MPQ archive.
    // If yes, we won't allow to overwrite it.
    if(SFileOpenArchive(szMpqName, 0, STREAM_PROVIDER_LINEAR | BASE_PROVIDER_FILE | MPQ_OPEN_NO_ATTRIBUTES | MPQ_OPEN_NO_LISTFILE, &hMpq))
    {
        SFileCloseArchive(hMpq);
        SetLastError(ERROR_ALREADY_EXISTS);
        return false;
    }

    //
    // At this point, we have to create the archive.
    // - If the file exists, convert it to MPQ archive.
    // - If the file doesn't exist, create new empty file
    //

    pStream = FileStream_OpenFile(szMpqName, pCreateInfo->dwStreamFlags);
    if(pStream == NULL)
    {
        pStream = FileStream_CreateFile(szMpqName, pCreateInfo->dwStreamFlags);
        if(pStream == NULL)
            return false;
    }

    // Increment the maximum amount of files to have space
    // for listfile and attributes file
    dwMaxFileCount = pCreateInfo->dwMaxFileCount;
    if(pCreateInfo->dwAttrFlags != 0)
        dwMaxFileCount++;
    dwMaxFileCount++;

    // If file count is not zero, initialize the hash table size
    dwHashTableSize = GetHashTableSizeForFileCount(dwMaxFileCount);

    // Retrieve the file size and round it up to 0x200 bytes
    FileStream_GetSize(pStream, MpqPos);
    MpqPos = (MpqPos + 0x1FF) & (ULONGLONG)0xFFFFFFFFFFFFFE00ULL;
    if(!FileStream_SetSize(pStream, MpqPos))
        nError = GetLastError();

#ifdef _DEBUG    
    // Debug code, used for testing StormLib
//  dwBlockTableSize = dwHashTableSize * 2;
#endif

    // Create the archive handle
    if(nError == ERROR_SUCCESS)
    {
        if((ha = STORM_ALLOC(TMPQArchive, 1)) == NULL)
            nError = ERROR_NOT_ENOUGH_MEMORY;
    }

    // Fill the MPQ archive handle structure
    if(nError == ERROR_SUCCESS)
    {
        memset(ha, 0, sizeof(TMPQArchive));
        ha->pStream         = pStream;
        ha->dwSectorSize    = pCreateInfo->dwSectorSize;
        ha->UserDataPos     = MpqPos;
        ha->MpqPos          = MpqPos;
        ha->pHeader         = (TMPQHeader *)ha->HeaderData;
        ha->dwMaxFileCount  = dwMaxFileCount;
        ha->dwFileTableSize = 0;
        ha->dwFileFlags1    = pCreateInfo->dwFileFlags1;
        ha->dwFileFlags2    = pCreateInfo->dwFileFlags2;
        ha->dwFlags         = 0;

        // Setup the attributes
        ha->dwAttrFlags     = pCreateInfo->dwAttrFlags;
        pStream = NULL;
    }

    // Fill the MPQ header
    if(nError == ERROR_SUCCESS)
    {
        TMPQHeader * pHeader = ha->pHeader;

        // Fill the MPQ header
        memset(pHeader, 0, sizeof(ha->HeaderData));
        pHeader->dwID             = ID_MPQ;
        pHeader->dwHeaderSize     = MpqHeaderSizes[pCreateInfo->dwMpqVersion];
        pHeader->dwArchiveSize    = pHeader->dwHeaderSize + dwHashTableSize * sizeof(TMPQHash);
        pHeader->wFormatVersion   = (USHORT)pCreateInfo->dwMpqVersion;
        pHeader->wSectorSize      = GetSectorSizeShift(ha->dwSectorSize);
        pHeader->dwHashTablePos   = pHeader->dwHeaderSize;
        pHeader->dwHashTableSize  = dwHashTableSize;
        pHeader->dwBlockTablePos  = pHeader->dwHashTablePos + dwHashTableSize * sizeof(TMPQHash);
        pHeader->dwBlockTableSize = dwBlockTableSize;

        // For MPQs version 4 and higher, we set the size of raw data block
        // for calculating MD5
        if(pCreateInfo->dwMpqVersion >= MPQ_FORMAT_VERSION_4)
            pHeader->dwRawChunkSize = pCreateInfo->dwRawChunkSize;

        // Write the naked MPQ header
        nError = WriteNakedMPQHeader(ha);

        // Remember that the (listfile) and (attributes) need to be saved
        ha->dwFlags |= MPQ_FLAG_CHANGED | MPQ_FLAG_INV_LISTFILE | MPQ_FLAG_INV_ATTRIBUTES;
    }

    // Create initial HET table, if the caller required an MPQ format 3.0 or newer
    if(nError == ERROR_SUCCESS && pCreateInfo->dwMpqVersion >= MPQ_FORMAT_VERSION_3)
    {
        ha->pHetTable = CreateHetTable(ha->dwMaxFileCount, 0x40, true);
        if(ha->pHetTable == NULL)
            nError = ERROR_NOT_ENOUGH_MEMORY;
    }

    // Create initial hash table
    if(nError == ERROR_SUCCESS)
    {
        nError = CreateHashTable(ha, dwHashTableSize);
    }

    // Create initial file table
    if(nError == ERROR_SUCCESS)
    {
        ha->pFileTable = STORM_ALLOC(TFileEntry, ha->dwMaxFileCount);
        if(ha->pFileTable != NULL)
            memset(ha->pFileTable, 0x00, sizeof(TFileEntry) * ha->dwMaxFileCount);
        else
            nError = ERROR_NOT_ENOUGH_MEMORY;
    }

    // Cleanup : If an error, delete all buffers and return
    if(nError != ERROR_SUCCESS)
    {
        FileStream_Close(pStream);
        FreeMPQArchive(ha);
        SetLastError(nError);
        ha = NULL;
    }
    
    // Return the values
    *phMpq = (HANDLE)ha;
    return (nError == ERROR_SUCCESS);
}
Пример #14
0
void CloseArchives()
{
    for(ArchiveSet::const_iterator i = gOpenArchives.begin(); i != gOpenArchives.end();++i)
        SFileCloseArchive(*i);
    gOpenArchives.clear();
}
Пример #15
0
bool CloseArchive(MPQHANDLE mpq)
{
    return SFileCloseArchive(mpq) == TRUE;
}
Пример #16
0
int main(int argc, char* argv[])
{
	HANDLE hMPQ=0,hMPQ2=0,hMPQ3=0;
	DWORD *dwPalette = (DWORD *)_alloca(1024);
	memset(dwPalette,0,1024);
	LoadStorm("SFMpq.dll");
	SetMpqDll("SFMpq.dll");
	if (SFileOpenArchive!=0) {
		char *buffer = (char *)_alloca(13);
		memcpy(buffer,"StarDat.mpq",12);
		if (SFileOpenArchive(buffer,1000,0,&hMPQ)==0) return 0;
		memcpy(buffer,"BrooDat.mpq",12);
		SFileOpenArchive(buffer,2000,0,&hMPQ2);
		memcpy(buffer,"Patch_rt.mpq",13);
		SFileOpenArchive(buffer,3000,0,&hMPQ3);
	}
	BufferInfo BI;
	LoadPalette("tileset\\Platform.wpe",dwPalette);
	HANDLE hGrp, hGrp2;
	if (argc>1)
		hGrp = LoadGrp(argv[1]);
	else
		hGrp = LoadGrp("unit\\zerg\\zergling.grp");
	HDC hDC = GetDC(0);
	GRPHEADER GrpInfo;
	if (GetGrpInfo(hGrp,&GrpInfo)==0) {GrpInfo.nFrames=0;GrpInfo.wMaxWidth=0;GrpInfo.wMaxHeight=0;}
	BI.nWidth = GrpInfo.wMaxWidth;
	BI.nHeight = GrpInfo.wMaxHeight;
	//BI.nWidth = 255;
	//BI.nHeight = 255;
	BI.pBuffer = (signed short *)malloc(GrpInfo.nFrames * BI.nWidth * BI.nHeight * sizeof(short));
	WORD i,x,y;
	DWORD j, nGrpSize;
	unsigned int u,v;
	memset(BI.pBuffer, 0xFF, GrpInfo.nFrames * BI.nWidth * BI.nHeight * sizeof(short));
	//for (DWORD j=0;j<16;j++){
	/*for (WORD i=0;i<GrpInfo.nFrames;i++) {
		DrawGrp(hGrp,hDC,0,0,i,dwPalette,ALPHA_BLEND,0x401020);
	}*/
	signed short clrPixel;
	RECT rect;
	/*for (i=0;i<GrpInfo.nFrames;i++) {
		for (j=0;j<16;j++)
		{
			rand_s(&u);
			rand_s(&v);
			u = u % 800;
			v = v % 600;
			DrawGrp(hGrp,hDC,u,v,i,dwPalette,ALPHA_BLEND,0x404040);
		}
	}*/
	SetFunctionGetPixel((GETPIXELPROC)ReadPixelFromBuffer);
	SetFunctionSetPixel((SETPIXELPROC)WritePixelToBuffer);
	for (i=0;i<GrpInfo.nFrames;i++) {
		BI.nFrame = i;
		u = (BI.nWidth - GrpInfo.wMaxWidth) / 2;
		v = (BI.nHeight - GrpInfo.wMaxHeight) / 2;
		for (y = 0; y < BI.nHeight; y++) {
			for (x = 0; x < BI.nWidth; x++) {
				WritePixelToBuffer(&BI, x, y, -1);
			}
		}
		DrawGrp(hGrp,(HDC)&BI,u,v,i,0,USE_INDEX,0);
	}
	hGrp2 = hGrp;
	hGrp = CreateGrp(BI.pBuffer, GrpInfo.nFrames, BI.nWidth, BI.nHeight, FALSE, &nGrpSize);
	/*HANDLE hFile;
	hFile = CreateFile("generated zergling.grp", GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0);
	if (hFile != INVALID_HANDLE_VALUE) {
		WriteFile(hFile, hGrp, nGrpSize, &j, 0);
		CloseHandle(hFile);
	}*/
	BI.nFrame = 0xFFFF;
	j=0;
	
	for (i=0;i<GrpInfo.nFrames;i+=1) {
		rect.left = rect.top = 0;
		rect.right = rect.left + BI.nWidth;
		rect.bottom = rect.top + BI.nHeight;
		for (x = 0; x < BI.nWidth * BI.nHeight; x++)
			BI.pBuffer[x] = -1;
		//for (j=0;j<(1 * 1);j++) {
//			DrawGrp(hGrp,(HDC)&BI,i,0,i % (17*8),dwPalette,ALPHA_BLEND,0x401020);
			//DrawGrp(hGrp2,(HDC)&BI,0,0,i,0,USE_INDEX,0x401020);
			//u = memcmp(BI.pBuffer, &BI.pBuffer[i * BI.nWidth * BI.nHeight], BI.nWidth * BI.nHeight * sizeof(short));
			DrawGrp(hGrp,(HDC)&BI,0,0,i,0,USE_INDEX,0x401020);
			u = memcmp(BI.pBuffer, &BI.pBuffer[i * BI.nWidth * BI.nHeight], BI.nWidth * BI.nHeight * sizeof(short));
			for (x = 0; x < BI.nWidth; x++)
				for (y = 0; y < BI.nHeight; y++) {
					clrPixel = BI.pBuffer[(y * BI.nWidth) + x];
					if (clrPixel != -1) SetPixelV(hDC, x, y, dwPalette[clrPixel]);
				}
		//}
		if (u) {
			printf("Output of re-encoded graphic for frame %d does not match original!  Total %d\n", i, ++j);
			//break;
		}
		FillRect(hDC, &rect, (HBRUSH) (COLOR_WINDOW+1));
	}
	for (i=4;i<400;i+=17) {
		rect.left = rect.top = 400-i;
		rect.right = rect.left + BI.nWidth;
		rect.bottom = rect.top + BI.nHeight;
		for (x = 0; x < BI.nWidth * BI.nHeight; x++)
			BI.pBuffer[x] = -1;
		for (j=0;j<32;j++) {
//			DrawGrp(hGrp,(HDC)&BI,400-i,0,i % (17*8),dwPalette,HORIZONTAL_FLIP|ALPHA_BLEND,0x401020);
			DrawGrp(hGrp,(HDC)&BI,0,0,i % (17*8),0,HORIZONTAL_FLIP|USE_INDEX,0x401020);
			for (x = 0; x < BI.nWidth; x++)
				for (y = 0; y < BI.nHeight; y++) {
					clrPixel = BI.pBuffer[(y * BI.nWidth) + x];
					if (clrPixel != -1) SetPixelV(hDC, 400-i + x, 400-i + y, dwPalette[clrPixel]);
				}
		}
		FillRect(hDC, &rect, (HBRUSH) (COLOR_WINDOW+1));
	}
	for (i = 0; i < BI.nWidth; i++)
		for (j = 0; j < BI.nHeight; j++) {
			clrPixel = BI.pBuffer[(j * BI.nWidth) + i];
			if (clrPixel != -1) SetPixelV(hDC, 400 + i, 300 + j, dwPalette[clrPixel]);
		}
	//}
	
	ReleaseDC(0,hDC);
	free(BI.pBuffer);
    DestroyGrp(hGrp);
    DestroyGrp(hGrp2);
	if (SFileCloseArchive!=0) {
		if (hMPQ3!=0) SFileCloseArchive(hMPQ3);
		if (hMPQ2!=0) SFileCloseArchive(hMPQ2);
		if (hMPQ!=0) SFileCloseArchive(hMPQ);
	}
	return 0;
}
Пример #17
0
	void CMpqArchive::UnLoad()
	{
		SFileCloseArchive(m_hMpq);
	}
Пример #18
0
bool WINAPI SFileCreateArchive(const char * szMpqName, DWORD dwFlags, DWORD dwMaxFileCount, HANDLE * phMpq)
{
    TFileStream * pStream = NULL;           // File stream
    TMPQArchive * ha = NULL;                // MPQ archive handle
    ULONGLONG MpqPos = 0;                   // Position of MPQ header in the file
    HANDLE hMpq = NULL;
    USHORT wFormatVersion = MPQ_FORMAT_VERSION_1;
    DWORD dwBlockTableSize = 0;             // Initial block table size
    DWORD dwHashTableSize = 0;
    int nError = ERROR_SUCCESS;

    // Check the parameters, if they are valid
    if(szMpqName == NULL || *szMpqName == 0 || phMpq == NULL)
    {
        SetLastError(ERROR_INVALID_PARAMETER);
        return false;
    }

    // One time initialization of MPQ cryptography
    InitializeMpqCryptography();

    // We verify if the file already exists and if it's a MPQ archive.
    // If yes, we won't allow to overwrite it.
    if(SFileOpenArchive(szMpqName, 0, dwFlags, &hMpq))
    {
        SFileCloseArchive(hMpq);
        SetLastError(ERROR_ALREADY_EXISTS);
        return false;
    }

    //
    // At this point, we have to create the archive.
    // - If the file exists, convert it to MPQ archive.
    // - If the file doesn't exist, create new empty file
    //

    pStream = FileStream_OpenFile(szMpqName, true);
    if(pStream == NULL)
    {
        pStream = FileStream_CreateFile(szMpqName);
        if(pStream == NULL)
            return false;
    }

    // Decide what format to use
    wFormatVersion = (USHORT)((dwFlags & MPQ_CREATE_ARCHIVE_VMASK) >> 16);
    if(wFormatVersion > MPQ_FORMAT_VERSION_4)
    {
        SetLastError(ERROR_INVALID_PARAMETER);
        return false;
    }

    // Increment the maximum amount of files to have space
    // for listfile and attributes file
    if(dwFlags & MPQ_CREATE_ATTRIBUTES)
        dwMaxFileCount++;
    dwMaxFileCount++;

    // If file count is not zero, initialize the hash table size
    dwHashTableSize = GetHashTableSizeForFileCount(dwMaxFileCount);

    // Retrieve the file size and round it up to 0x200 bytes
    FileStream_GetSize(pStream, MpqPos);
    MpqPos = (MpqPos + 0x1FF) & (ULONGLONG)0xFFFFFFFFFFFFFE00ULL;
    if(!FileStream_SetSize(pStream, MpqPos))
        nError = GetLastError();

#ifdef _DEBUG    
    // Debug code, used for testing StormLib
//  dwBlockTableSize = dwHashTableSize * 2;
#endif

    // Create the archive handle
    if(nError == ERROR_SUCCESS)
    {
        if((ha = ALLOCMEM(TMPQArchive, 1)) == NULL)
            nError = ERROR_NOT_ENOUGH_MEMORY;
    }

    // Fill the MPQ archive handle structure
    if(nError == ERROR_SUCCESS)
    {
        memset(ha, 0, sizeof(TMPQArchive));
        ha->pStream         = pStream;
        ha->dwSectorSize    = (wFormatVersion >= MPQ_FORMAT_VERSION_3) ? 0x4000 : 0x1000;
        ha->UserDataPos     = MpqPos;
        ha->MpqPos          = MpqPos;
        ha->pHeader         = (TMPQHeader *)ha->HeaderData;
        ha->dwMaxFileCount  = dwMaxFileCount;
        ha->dwFileTableSize = 0;
        ha->dwFileFlags1    = MPQ_FILE_ENCRYPTED | MPQ_FILE_COMPRESS |  MPQ_FILE_REPLACEEXISTING;
        ha->dwFileFlags2    = MPQ_FILE_ENCRYPTED | MPQ_FILE_COMPRESS |  MPQ_FILE_REPLACEEXISTING;
        ha->dwFlags         = 0;

        // Setup the attributes
        if(dwFlags & MPQ_CREATE_ATTRIBUTES)
            ha->dwAttrFlags = MPQ_ATTRIBUTE_CRC32 | MPQ_ATTRIBUTE_FILETIME | MPQ_ATTRIBUTE_MD5;
        pStream = NULL;
    }

    // Fill the MPQ header
    if(nError == ERROR_SUCCESS)
    {
        TMPQHeader * pHeader = ha->pHeader;

        // Fill the MPQ header
        memset(pHeader, 0, sizeof(ha->HeaderData));
        pHeader->dwID             = ID_MPQ;
        pHeader->dwHeaderSize     = MpqHeaderSizes[wFormatVersion];
        pHeader->dwArchiveSize    = pHeader->dwHeaderSize + dwHashTableSize * sizeof(TMPQHash);
        pHeader->wFormatVersion   = wFormatVersion;
        pHeader->wSectorSize      = GetSectorSizeShift(ha->dwSectorSize);
        pHeader->dwHashTablePos   = pHeader->dwHeaderSize;
        pHeader->dwHashTableSize  = dwHashTableSize;
        pHeader->dwBlockTablePos  = pHeader->dwHashTablePos + dwHashTableSize * sizeof(TMPQHash);
        pHeader->dwBlockTableSize = dwBlockTableSize;

        // For MPQs version 4 and higher, we set the size of raw data block
        // for calculating MD5
        if(wFormatVersion >= MPQ_FORMAT_VERSION_4)
            pHeader->dwRawChunkSize = 0x4000;

        // Write the naked MPQ header
        nError = WriteNakedMPQHeader(ha);

        //
        // Note: Don't recalculate position of MPQ tables at this point.
        // We merely set a flag that indicates that the MPQ tables
        // have been changed, and SaveMpqTables will do the work when closing the archive.
        //

        ha->dwFlags |= MPQ_FLAG_CHANGED;
    }

    // Create initial hash table
    if(nError == ERROR_SUCCESS)
    {
        nError = CreateHashTable(ha, dwHashTableSize);
    }

    // Create initial HET table, if the caller required an MPQ format 3.0 or newer
    if(nError == ERROR_SUCCESS && wFormatVersion >= MPQ_FORMAT_VERSION_3)
    {
        ha->pHetTable = CreateHetTable(ha->dwMaxFileCount, 0x40, true);
        if(ha->pHetTable == NULL)
            nError = ERROR_NOT_ENOUGH_MEMORY;
    }

    // Create initial file table
    if(nError == ERROR_SUCCESS)
    {
        ha->pFileTable = ALLOCMEM(TFileEntry, dwMaxFileCount);
        if(ha->pFileTable != NULL)
            memset(ha->pFileTable, 0x00, sizeof(TFileEntry) * dwMaxFileCount);
        else
            nError = ERROR_NOT_ENOUGH_MEMORY;
    }

    // Cleanup : If an error, delete all buffers and return
    if(nError != ERROR_SUCCESS)
    {
        FileStream_Close(pStream);
        FreeMPQArchive(ha);
        SetLastError(nError);
        ha = NULL;
    }
    
    // Return the values
    *phMpq = (HANDLE)ha;
    return (nError == ERROR_SUCCESS);
}
Пример #19
0
int main(int argc, char** argv)
try
{
    po::options_description desc("Required options");
    desc.add_options()
    ("help,h", "produce help message")
    ("force,f", "overwrite existing files")
    ("mpq", po::value<std::string>(), "the mpq to create")
    ("files", po::value<std::vector<std::string> >(), "input files");

    po::positional_options_description p;

    p.add("mpq", 1);
    p.add("files", -1);

    po::variables_map vm;
    po::store(po::command_line_parser(argc, argv).options(desc).positional(p).run(), vm);
    po::notify(vm);

    if (!vm.count("files") || !vm.count("mpq") || vm.count("help"))
    {
        std::cout << "usage: <mpq> [<files> ...]" << std::endl << std::endl
                  << desc << std::endl;
        return 1;
    }

    std::vector<std::string> files(vm["files"].as< std::vector<std::string> >());
    std::vector<FileEntry> toAdd;
    fs::path mpqPath(vm["mpq"].as<std::string>());

    if(fs::exists(mpqPath))
    {
        if(vm.count("force"))
            fs::remove(mpqPath);
        else
            throw std::runtime_error("mpq does already exist");
    }

    for(std::vector<std::string>::iterator path = files.begin(); path != files.end(); ++path)
    {
        if(fs::is_regular_file(*path))
            toAdd.push_back(FileEntry(*path, *path));

        if(!fs::is_directory(*path)) //no symlinks etc
            continue;

        for(fs::recursive_directory_iterator file(*path), end; file != end; ++file)
            if(fs::is_regular_file(file->path()))
                toAdd.push_back(FileEntry(file->path(), makeRelative(*path, file->path())));
    }

    for(std::vector<FileEntry>::iterator it = toAdd.begin(); it != toAdd.end(); ++it)
        std::cout << it->realPath << " >> " << it->mpqPath << std::endl;

    HANDLE mpq;
    if(!SFileCreateArchive(mpqPath.string().c_str(), MPQ_CREATE_ARCHIVE_V2, toAdd.size(), &mpq))
        throw std::runtime_error("couldn't create mpq");

    SFileSetLocale(0);

    size_t counter(0);
    for(std::vector<FileEntry>::iterator it = toAdd.begin(); it != toAdd.end(); ++it)
    {
        loadbar(++counter, toAdd.size());

        if(!SFileAddFileEx(mpq, it->realPath.string().c_str(), it->mpqPath.string().c_str(), MPQ_FILE_COMPRESS, MPQ_COMPRESSION_BZIP2, MPQ_COMPRESSION_BZIP2))
            std::cout << "couldn't add file " << it->realPath << std::endl;
    }

    std::cout << std::endl;
    SFileCompactArchive(mpq, NULL, false);

    SFileFlushArchive(mpq);
    SFileCloseArchive(mpq);

    return 0;
}
catch (const std::exception& e)
{
    std::cerr << "error: " << e.what() << "\n";
}
Пример #20
0
void PackageManager::createMpqPackage(const char* pathName, const char* pszMpqName)
{
#ifdef WIN32
	if (!pathName || pathName[0] == 0) {
		return;
	}

	PackageUtil::logMsg("createPackage begin");

	std::string realPath = PackageUtil::flattenPathName(pathName);
	s_rootDir = realPath;

	std::replace(s_rootDir.begin(), s_rootDir.end(), '\\', '/');
	std::transform(s_rootDir.begin(), s_rootDir.end(), s_rootDir.begin(), tolower);
	if (s_rootDir.back() != '/') {
		s_rootDir += '/';
	}

	std::string fileName;
	if (realPath.back() == '/') {
		int last = realPath.find_last_of('/', realPath.size() - 2);
		fileName = realPath.substr(last + 1, realPath.size() - last - 1 - 1);
	} else {
		int last = realPath.find_last_of('/');
		fileName = realPath.substr(last, realPath.size() - last);
	}

	std::string listFileName = WORK_PATH + fileName + ".txt";
	std::string mpqName = WORK_PATH;
	mpqName += fileName;
	mpqName += ".mpq";

	if (PackageUtil::fileExists(mpqName.c_str())) {
		remove(mpqName.c_str());
	}

#ifdef WIN32
	wchar_t szMpqName[256] = {0};
	MultiByteToWideChar (CP_ACP, 0, mpqName.c_str(), mpqName.size(), szMpqName, 255);

	if (!SFileCreateArchive(szMpqName, MPQ_CREATE_ARCHIVE_V4 | MPQ_CREATE_ATTRIBUTES, 4000, &s_currentMpqHandle)) {
		s_currentMpqHandle = NULL;
		return;
	}
#else
	if (!SFileCreateArchive(mpqName.c_str(), MPQ_CREATE_ARCHIVE_V4 | MPQ_CREATE_ATTRIBUTES, 4000, &s_currentMpqHandle)) {
		s_currentMpqHandle = NULL;
		return;
	}
#endif

	if (s_fpListFile) {
		fclose(s_fpListFile);
	}

	s_fpListFile = fopen(listFileName.c_str(), "w");
	archivePath(realPath.c_str());
	fclose(s_fpListFile);
	SFileCloseArchive(s_currentMpqHandle);

	PackageUtil::logMsg("createPackage over");

	// 测试文件是否正确
#ifdef WIN32
	if(SFileOpenArchive(szMpqName, 0, 0, &s_currentMpqHandle)) {
        SFileCloseArchive(s_currentMpqHandle);
		return;
	}
#else
	if(SFileOpenArchive(mpqName.c_str(), 0, 0, &s_currentMpqHandle)) {
		SFileCloseArchive(s_currentMpqHandle);
		return;
	}
#endif

	assert(false);
#endif
}
Пример #21
0
int main(int argc, char ** argv)
{
    bool success=true;
    const char *versionString = "V4.00 2012_02";

    // Use command line arguments, when some
    if (!processArgv(argc, argv, versionString))
        return 1;

    // some simple check if working dir is dirty
    else
    {
        std::string sdir = std::string(szWorkDirWmo) + "/dir";
        std::string sdir_bin = std::string(szWorkDirWmo) + "/dir_bin";
        struct stat status;
        if (!stat(sdir.c_str(), &status) || !stat(sdir_bin.c_str(), &status))
        {
            printf("Your output directory seems to be polluted, please use an empty directory!\n");
            printf("<press return to exit>");
            char garbage[2];
            return scanf("%c", garbage);
        }
    }

    printf("Extract %s. Beginning work ....\n\n",versionString);
    //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    // Create the working directory
    if (mkdir(szWorkDirWmo
#if defined(__linux__) || defined(__APPLE__)
                    , 0711
#endif
                    ))
            success = (errno == EEXIST);

    LoadCommonMPQFiles(CONF_TargetBuild);

    for (int i = 0; i < LOCALES_COUNT; ++i)
    {
        //Open MPQs
        if (!LoadLocaleMPQFile(i))
        {
            if (GetLastError() != ERROR_PATH_NOT_FOUND)
                printf("Unable to load %s locale archives!\n", Locales[i]);
            continue;
        }

        printf("Detected and using locale: %s\n", Locales[i]);
        break;
    }

    ReadLiquidTypeTableDBC();

    // extract data
    if (success)
        success = ExtractWmo();

    //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    //map.dbc
    if (success)
    {
        DBCFile * dbc = new DBCFile(LocaleMpq, "DBFilesClient\\Map.dbc");
        if (!dbc->open())
        {
            delete dbc;
            printf("FATAL ERROR: Map.dbc not found in data file.\n");
            return 1;
        }
        map_count=dbc->getRecordCount ();
        map_ids=new map_id[map_count];
        for (unsigned int x=0;x<map_count;++x)
        {
            map_ids[x].id=dbc->getRecord (x).getUInt(0);
            strcpy(map_ids[x].name,dbc->getRecord(x).getString(1));
            printf("Map - %s\n",map_ids[x].name);
        }


        delete dbc;
        ParsMapFiles();
        delete [] map_ids;
        //nError = ERROR_SUCCESS;
        // Extract models, listed in GameObjectDisplayInfo.dbc
        ExtractGameobjectModels();
    }

    SFileCloseArchive(LocaleMpq);
    SFileCloseArchive(WorldMpq);

    printf("\n");
    if (!success)
    {
        printf("ERROR: Extract %s. Work NOT complete.\n   Precise vector data=%d.\nPress any key.\n",versionString, preciseVectorData);
        getchar();
    }

    printf("Extract %s. Work complete. No errors.\n",versionString);
    delete [] LiqType;
    return 0;
}
Пример #22
0
void MPQArchive::close()
{
    SFileCloseArchive(hMPQ);
}