// BigFileToolDlg.cpp : implementation file // #include "stdafx.h" #include "BigFileTool.h" #include "BigFileToolDlg.h" #include #include #include #include #include #include "Scripts.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif #include #define C_szBigFileName "data.000" ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// long PTC_g_lCurrentRandom; //------------------------------------------------------------------------ // // Author Marc Trabucato // Date 26 mars 1999 // // Prototype PTC_fn_lGetCryptKey // Parameters _lValue : // Return Type DWORD // // Description Get the key used to crypt the file // //------------------------------------------------------------------------ DWORD PTC_fn_lGetCryptKey(DWORD _lValue) { DWORD lTmp; _lValue ^= 123459876; lTmp = _lValue / 127773; _lValue = 16807 * (_lValue - lTmp * 127773) - 2836 * lTmp; if (_lValue < 0) _lValue += 2147483647; return _lValue; } //------------------------------------------------------------------------ long PTC_fn_lGetRandom() { long lTmp; PTC_g_lCurrentRandom ^= 123459876; lTmp = PTC_g_lCurrentRandom / 127773; PTC_g_lCurrentRandom = 16807 * (PTC_g_lCurrentRandom - lTmp * 127773) - 2836 * lTmp; if (PTC_g_lCurrentRandom < 0) PTC_g_lCurrentRandom += 2147483647; return PTC_g_lCurrentRandom; } //------------------------------------------------------------------------ // // Author Marc Trabucato // Date 26 mars 1999 // // Prototype PTC_fn_lGetProtectionKey // Parameters _lValue : // Return Type DWORD // // Description Get the key added to the file // //------------------------------------------------------------------------ DWORD PTC_fn_lGetProtectionKey(DWORD _lValue) { DWORD lTmp; _lValue ^= 123459876; lTmp = _lValue / 44488; _lValue = 48271 * (_lValue - lTmp * 44488) - 3399 * lTmp; if (_lValue < 0) _lValue += 2147483647; return _lValue; } //------------------------------------------------------------------------ long PTC_fn_lGetRandomRange(long _lMin , long _lMax) { return (_lMin + (PTC_fn_lGetRandom() % (_lMax - _lMin))); } //------------------------------------------------------------------------ DWORD fn_dwAlignToSectorSize(DWORD dwSize, DWORD dwSectorSize) { return ((1 + (dwSize / dwSectorSize)) * dwSectorSize); } //------------------------------------------------------------------------ DWORD fn_dwGetTotalHeaderSize(DWORD dwFileNumber, DWORD dwOccur, DWORD dwSectorSize) { // Keys (4 DWORD) + MapNumber (DWORD) + OccurNumber (DOWRD) + Offset (DWORD) return fn_dwAlignToSectorSize(16 + 4 + 4 + (dwOccur* dwFileNumber) * 4 , dwSectorSize); } //------------------------------------------------------------------------ DWORD fn_dwGetHeaderSizeForAFile(DWORD dwOccur, DWORD dwSectorSize) { // Keys (4 DWORD) + Offset return fn_dwAlignToSectorSize(16 + dwOccur * 4 , dwSectorSize); } //------------------------------------------------------------------------ DWORD fn_dwGetHeaderSizeforAnOccur(DWORD dwFileNumber, DWORD dwSectorSize) { // Keys (4 DWORD) + Offset return fn_dwAlignToSectorSize(16 + dwFileNumber * 4 , dwSectorSize); } ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// // CAboutDlg dialog used for App About class CAboutDlg : public CDialog { public: CAboutDlg(); // Dialog Data //{{AFX_DATA(CAboutDlg) enum { IDD = IDD_ABOUTBOX }; //}}AFX_DATA // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CAboutDlg) protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL // Implementation protected: //{{AFX_MSG(CAboutDlg) //}}AFX_MSG DECLARE_MESSAGE_MAP() }; CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) { //{{AFX_DATA_INIT(CAboutDlg) //}}AFX_DATA_INIT } void CAboutDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CAboutDlg) //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) //{{AFX_MSG_MAP(CAboutDlg) // No message handlers //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CBigFileToolDlg dialog #define M_SPIN(nID) ((CSpinButtonCtrl*) GetDlgItem (nID)) #define M_EDIT(nID) ((CEdit*)GetDlgItem(nID)) #define M_LIST(nID) ((CListBox*)GetDlgItem(nID)) #define M_BT(nID) ((CButton*)GetDlgItem(nID)) CBigFileToolDlg::CBigFileToolDlg(CWnd* pParent /*=NULL*/) : CDialog(CBigFileToolDlg::IDD, pParent) { //{{AFX_DATA_INIT(CBigFileToolDlg) // NOTE: the ClassWizard will add member initialization here //}}AFX_DATA_INIT // Note that LoadIcon does not require a subsequent DestroyIcon in Win32 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); } void CBigFileToolDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CBigFileToolDlg) DDX_Control(pDX, IDC_PROGRESS, m_Ctrl_ProgressBar); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CBigFileToolDlg, CDialog) //{{AFX_MSG_MAP(CBigFileToolDlg) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_BN_CLICKED(IDC_BUTTON_BROWSE, OnButtonBrowse) ON_BN_CLICKED(IDC_BUTTON_RUN, OnButtonRun) ON_BN_CLICKED(IDC_BUTTON_BROWSESCRIPT, OnButtonBrowsescript) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CBigFileToolDlg message handlers BOOL CBigFileToolDlg::OnInitDialog() { CDialog::OnInitDialog(); // Add "About..." menu item to system menu. // IDM_ABOUTBOX must be in the system command range. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != NULL) { CString strAboutMenu; strAboutMenu.LoadString(IDS_ABOUTBOX); if (!strAboutMenu.IsEmpty()) { pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } } // Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon // Init Scripts fn_vInitScr(); // Init Controls M_SPIN(IDC_SPIN_SIZE) -> SetRange (1 , 500); M_LIST(IDC_LIST_WORK) -> ResetContent (); M_BT(IDC_CHECK_DELETEFILES) -> SetCheck (FALSE); if (AfxGetApp () -> m_lpCmdLine[0] == '\0') { ReadINIFile (); } else { InitWithCommandLine (); } if (m_bAutoRun) { PostMessage(WM_COMMAND , MAKEWPARAM(IDC_BUTTON_RUN,BN_CLICKED) , (LPARAM)GetDlgItem (IDC_BUTTON_RUN) -> m_hWnd); } return TRUE; // return TRUE unless you set the focus to a control } void CBigFileToolDlg::OnSysCommand(UINT nID, LPARAM lParam) { if ((nID & 0xFFF0) == IDM_ABOUTBOX) { CAboutDlg dlgAbout; dlgAbout.DoModal(); } else { CDialog::OnSysCommand(nID, lParam); } } // If you add a minimize button to your dialog, you will need the code below // to draw the icon. For MFC applications using the document/view model, // this is automatically done for you by the framework. void CBigFileToolDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // device context for painting SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0); // Center icon in client rectangle int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // Draw the icon dc.DrawIcon(x, y, m_hIcon); } else { CDialog::OnPaint(); } } // The system calls this to obtain the cursor to display while the user drags // the minimized window. HCURSOR CBigFileToolDlg::OnQueryDragIcon() { return (HCURSOR) m_hIcon; } /*======================================================================================= * Description BN_CLICKED message handles : button "Run" * * Creation date 23/03/99 * Author Marc Trabucato *=====================================================================================*/ void CBigFileToolDlg::OnButtonRun() { BOOL bResult; // Disables buttons GetDlgItem (IDC_BUTTON_RUN) -> EnableWindow (FALSE); GetDlgItem (IDOK) -> EnableWindow (FALSE); m_bGenerateInfoFiles = M_BT(IDC_CHECK_INFO) -> GetCheck (); // Save choices WriteINIFile (); // Run process bResult = Run(); // Restore buttons GetDlgItem (IDC_BUTTON_RUN) -> EnableWindow (TRUE); GetDlgItem (IDOK) -> EnableWindow (TRUE); if (m_bAutoRun) { if (bResult) OnOK (); else OnCancel(); } } /*======================================================================================= * Description BN_CLICKED message handles : button "Browse Script" * * Creation date 23/03/99 * Author Marc Trabucato *=====================================================================================*/ void CBigFileToolDlg::OnButtonBrowsescript() { OnBrowse (IDC_EDIT_SCRIPTDATAPATH); } /*======================================================================================= * Description BN_CLICKED message handles : button "Browse Binary" * * Creation date 23/03/99 * Author Marc Trabucato *=====================================================================================*/ void CBigFileToolDlg::OnButtonBrowse() { OnBrowse (IDC_EDIT_DATAPATH); } /*======================================================================================= * Description Open a Browse dialog and update nID control with result * * Creation date 23/03/99 * Author Marc Trabucato *=====================================================================================*/ void CBigFileToolDlg::OnBrowse(UINT nID) { BROWSEINFO bi; LPSTR lpBuffer = (LPSTR)malloc(_MAX_PATH); LPITEMIDLIST pidlBrowse; // PIDL selected by user // Fill in the BROWSEINFO structure. bi.hwndOwner = m_hWnd; bi.pidlRoot = NULL; bi.pszDisplayName = lpBuffer; bi.lpszTitle = "Choose a Path"; bi.ulFlags = 0; bi.lpfn = NULL; bi.lParam = 0; // Browse for a folder and return its PIDL. pidlBrowse = SHBrowseForFolder(&bi); if (pidlBrowse != NULL) { if (SHGetPathFromIDList(pidlBrowse, lpBuffer)) { M_EDIT(nID) -> SetWindowText(lpBuffer); } } // Clean up. free(lpBuffer); } /*======================================================================================= * Description BN_CLICKED message handles : button "Cancel" * * Creation date 23/03/99 * Author Marc Trabucato *=====================================================================================*/ void CBigFileToolDlg::OnCancel() { fn_vDesinitScr(); CDialog::OnCancel(); } /*======================================================================================= * Description BN_CLICKED message handles : button "OK" * * Creation date 23/03/99 * Author Marc Trabucato *=====================================================================================*/ void CBigFileToolDlg::OnOK() { fn_vDesinitScr(); CDialog::OnOK(); } #define M_Run_Assert(bTest,szTitle,szMessage) \ if(!(bTest)) \ { \ MessageBox (szMessage,szTitle,MB_OK + MB_ICONERROR); \ return FALSE; \ } /*======================================================================================= * Description Run process * * Creation date 23/03/99 * Author Marc Trabucato *=====================================================================================*/ BOOL CBigFileToolDlg::Run() { char szDataPath[MAX_PATH]; char szScriptDataPath[MAX_PATH]; CListOfFileInfo oFIList; tdstMixUpInfo *_a_MUITab; DWORD dwBigFileSize; char szText[128]; char szBigFileName[MAX_PATH]; CStringList oListOfMaps; tdstHeaderInfo *_a_HITab; tdstBigFileInfo stBFI; BOOL bResult; // Get script data path M_EDIT(IDC_EDIT_SCRIPTDATAPATH) -> GetWindowText (szScriptDataPath , MAX_PATH); if(szScriptDataPath[strlen (szScriptDataPath) - 1] != '\\') { strcat (szScriptDataPath , "\\"); } M_LIST(IDC_LIST_WORK) -> AddString ("Read Game.dsc"); M_LIST(IDC_LIST_WORK) -> AddString (""); // read Game.dsc to get list of maps bResult = fn_bReadGameDsc (szScriptDataPath , &oListOfMaps); M_Run_Assert(bResult,"ERROR","Can't find Game.dsc file"); sprintf (szText , "\t%d maps in Game.dsc" , oListOfMaps . GetCount ()); M_LIST(IDC_LIST_WORK) -> AddString (szText); // Message Pump PeekAndPump (); // Get Data Path M_EDIT(IDC_EDIT_DATAPATH) -> GetWindowText (szDataPath , MAX_PATH); if(szDataPath[strlen (szDataPath) - 1] != '\\') { strcat (szDataPath , "\\"); } strcat (szDataPath , "World\\Levels\\"); // Get BigfileSize; M_EDIT(IDC_EDIT_SIZE) -> GetWindowText (szText , 10); dwBigFileSize = 1024 * 1024 * atol (szText); // get list of rt* files and total size ReadListOfFiles (szDataPath , &oListOfMaps , &oFIList); // Message Pump PeekAndPump (); /* // mix up files bResult = MixUpFiles (dwBigFileSize , &oFIList , &_a_MUITab, &stBFI); // Message Pump PeekAndPump (); // create Big File strcpy (szBigFileName , szDataPath); strcat (szBigFileName , C_szBigFileName); HANDLE hFile = CreateFile (szBigFileName , GENERIC_WRITE , 0 , NULL , CREATE_ALWAYS , FILE_ATTRIBUTE_NORMAL , NULL); // Message Pump PeekAndPump (); // Write Header bResult = WriteHeader (hFile , &oFIList , _a_MUITab , &stBFI); // Write rt* Files bResult = WriteFiles (szDataPath , hFile , &oFIList , _a_MUITab , &stBFI); */ // mix up files bResult = MixUpFilesWithExplodedHeader(dwBigFileSize , &oFIList , &_a_MUITab, &stBFI , &_a_HITab); M_Run_Assert(bResult,"Error",m_csErrorMessage); // Message Pump PeekAndPump (); // create Big File strcpy (szBigFileName , szDataPath); strcat (szBigFileName , C_szBigFileName); HANDLE hFile = CreateFile (szBigFileName , GENERIC_WRITE , 0 , NULL , CREATE_ALWAYS , FILE_ATTRIBUTE_NORMAL , NULL); M_Run_Assert(hFile != INVALID_HANDLE_VALUE,"Error","Can't create data.000 file"); // Message Pump PeekAndPump (); // Write file bResult = WriteBigFileWithExplodedHeader(szDataPath , hFile, &oFIList, _a_MUITab, &stBFI , _a_HITab); M_Run_Assert(bResult,"Error",m_csErrorMessage); { CString csText; csText . Format ("\tSize of Big File : %ld" , GetFileSize (hFile , NULL)); M_LIST(IDC_LIST_WORK) -> AddString (csText); } // Close Big File CloseHandle (hFile); if (M_BT(IDC_CHECK_DELETEFILES) -> GetCheck ()) { DeleteFiles (szScriptDataPath , &oFIList); } if (M_BT(IDC_CHECK_STARTPRG) -> GetCheck ()) { UpdateStartPrg (); } // free while (oFIList . GetCount ()) free (oFIList . RemoveHead ()); free (_a_MUITab); M_LIST(IDC_LIST_WORK) -> AddString ("================================================="); M_LIST(IDC_LIST_WORK) -> AddString ("BigFile Generated"); M_LIST(IDC_LIST_WORK) -> AddString ("================================================="); return TRUE; } //------------------------------------------------------------------------ // // Author Marc Trabucato // Date 24 mars 1999 // // Prototype CBigFileToolDlg::PeekAndPump // Return Type void // // Description // //------------------------------------------------------------------------ void CBigFileToolDlg::PeekAndPump() { MSG msg; LONG lIdle = 0; while (::PeekMessage(&msg,NULL,0,0,PM_NOREMOVE)) { if (!AfxGetApp()->PumpMessage()) { ::PostQuitMessage(0); return; } } while(AfxGetApp()->OnIdle(lIdle++)); } /*======================================================================================= * Description Read default values on INI file * * Creation date 23/03/99 * Author Marc Trabucato *=====================================================================================*/ void CBigFileToolDlg::ReadINIFile() { CString csText; // Script Data Path csText = AfxGetApp () -> GetProfileString("Default" , "ScriptDataPath"); M_EDIT(IDC_EDIT_SCRIPTDATAPATH) -> SetWindowText (csText); // Binary Data Path csText = AfxGetApp () -> GetProfileString("Default" , "BinaryDataPath"); M_EDIT(IDC_EDIT_DATAPATH) -> SetWindowText (csText); // BigFile Size csText = AfxGetApp () -> GetProfileString("Default" , "BigFileSize"); M_EDIT(IDC_EDIT_SIZE) -> SetWindowText (csText); M_SPIN(IDC_SPIN_SIZE) -> SetPos (atol ((char*)(LPCTSTR)csText)); // Generate Info M_BT(IDC_CHECK_INFO) -> SetCheck (AfxGetApp () -> GetProfileInt("Default" , "GenerateInfo" , 0)); // Delete File M_BT(IDC_CHECK_DELETEFILES) -> SetCheck (AfxGetApp () -> GetProfileInt("Default" , "DeleteFiles" , 0)); // AutoRun m_bAutoRun = FALSE; // Update StartPrg.ini M_BT(IDC_CHECK_STARTPRG) -> SetCheck (AfxGetApp () -> GetProfileInt("Default" , "UpdateStartPrg" , 0)); } /*======================================================================================= * Description Save current values on INI file * * Creation date 23/03/99 * Author Marc Trabucato *=====================================================================================*/ void CBigFileToolDlg::WriteINIFile() { CString csText; // Script Data Path M_EDIT(IDC_EDIT_SCRIPTDATAPATH) -> GetWindowText (csText); AfxGetApp () -> WriteProfileString("Default" , "ScriptDataPath" , csText); // Binary Data Path M_EDIT(IDC_EDIT_DATAPATH) -> GetWindowText (csText); AfxGetApp () -> WriteProfileString("Default" , "BinaryDataPath" , csText); // BigFile Size M_EDIT(IDC_EDIT_SIZE) -> GetWindowText (csText); AfxGetApp () -> WriteProfileString("Default" , "BigFileSize" , csText); // Generate Info AfxGetApp () -> WriteProfileInt("Default" , "GenerateInfo" , M_BT(IDC_CHECK_INFO) -> GetCheck ()); // Delete File AfxGetApp () -> WriteProfileInt("Default" , "DeleteFiles" , M_BT(IDC_CHECK_DELETEFILES) -> GetCheck ()); // Update StartPrg.ini AfxGetApp () -> WriteProfileInt("Default" , "UpdateStartPrg" , M_BT(IDC_CHECK_STARTPRG) -> GetCheck ()); } //------------------------------------------------------------------------ // // Author Marc Trabucato // Date 23 mars 1999 // // Prototype CBigFileToolDlg::InitWithCommandLine // Return Type void // // Description // //------------------------------------------------------------------------ void CBigFileToolDlg::InitWithCommandLine() { LPSTR lpCommandLine = AfxGetApp () -> m_lpCmdLine; char szParam[MAX_PATH]; char *p_cScriptDataPath = strstr (lpCommandLine , "-scriptpath:"); char *p_cBinaryDataPath = strstr (lpCommandLine , "-binarypath:"); char *p_cBigFileSize = strstr (lpCommandLine , "-bigfilesize:"); char *p_cDeleteFile = strstr (lpCommandLine , "-deletefile"); char *p_cGenerateInfo = strstr (lpCommandLine , "-generateinfo"); char *p_cAutoRun = strstr (lpCommandLine , "-autorun"); char *p_cStartPrg = strstr (lpCommandLine , "-startprg"); // Script Data Path if (p_cScriptDataPath) { sscanf(p_cScriptDataPath + 12 , "%s" , szParam); M_EDIT(IDC_EDIT_SCRIPTDATAPATH) -> SetWindowText (szParam); } // Binary Data Path if (p_cBinaryDataPath) { sscanf(p_cBinaryDataPath + 12 , "%s" , szParam); M_EDIT(IDC_EDIT_DATAPATH) -> SetWindowText (szParam); } // Big File Size if (p_cBigFileSize) { sscanf(p_cBigFileSize + 13 , "%s" , szParam); M_EDIT(IDC_EDIT_SIZE) -> SetWindowText (szParam); M_SPIN(IDC_SPIN_SIZE) -> SetPos (atol (szParam)); } // Delete File M_BT(IDC_CHECK_DELETEFILES) -> SetCheck (p_cDeleteFile != NULL); // Generate Info M_BT(IDC_CHECK_INFO) -> SetCheck (p_cGenerateInfo != NULL); // AutoRun m_bAutoRun = (p_cAutoRun != NULL); // Update StartPrg.ini M_BT(IDC_CHECK_STARTPRG) -> SetCheck (p_cStartPrg != NULL); } /*------------------------------------------------------------------------ * * Author Marc Trabucato * Date 14 avr. 1999 * * Prototype CBigFileToolDlg::UpdateStartPrg * Return Type void * * Description * *------------------------------------------------------------------------*/ void CBigFileToolDlg::UpdateStartPrg() { char szScriptDataPath[MAX_PATH]; M_LIST(IDC_LIST_WORK) -> AddString (""); M_LIST(IDC_LIST_WORK) -> AddString ("Update StartPrg.ini"); M_LIST(IDC_LIST_WORK) -> AddString (""); // Get script data path M_EDIT(IDC_EDIT_SCRIPTDATAPATH) -> GetWindowText (szScriptDataPath , MAX_PATH); if(szScriptDataPath[strlen (szScriptDataPath) - 1] == '\\') { szScriptDataPath[strlen (szScriptDataPath) - 1] = 0; } // compute StartPrg.ini FileName char *p_cSeparator = strrchr (szScriptDataPath , '\\'); if (p_cSeparator) { p_cSeparator++; sprintf (p_cSeparator , "%s" , "StartPrg.ini"); // WritePrivateProfileString ("Start" , "UsesBigFile" , "Yes" , szScriptDataPath); } } //////////////////////////////////////////////////////////////////////////// //------------------------------------------------------------------------ // // Author Marc Trabucato // Date 22 mars 1999 // // Prototype CBigFileToolDlg::ReadListOfFiles // Parameters _p_oList : // Return Type void // // Description Read List of rt* files // //------------------------------------------------------------------------ void CBigFileToolDlg::ReadListOfFiles(char *_szDataPath , CStringList *_p_oMapList , CListOfFileInfo *_p_oList) { WIN32_FIND_DATA stWFDFile; HANDLE hFDFile; char szFileName[MAX_PATH]; DWORD dwMapNumber; CListBox *pLB = M_LIST(IDC_LIST_WORK); char szText[128]; pLB -> AddString (""); pLB -> AddString ("Search rt* files"); pLB -> AddString (""); m_Ctrl_ProgressBar . SetRange (0 , _p_oMapList -> GetCount ()); m_Ctrl_ProgressBar . SetPos (0); m_Ctrl_ProgressBar . SetStep (1); POSITION xPos = _p_oMapList -> GetHeadPosition (); while (xPos) { char *p_cMapName = (char*)(LPCTSTR) _p_oMapList -> GetNext (xPos); tdstFileInfo *p_stFI; // rtb file p_stFI = (tdstFileInfo*) malloc (sizeof tdstFileInfo); sprintf (szFileName , "%s%s\\%s.rtb" , _szDataPath , p_cMapName , p_cMapName); sprintf (p_stFI -> szFileName , "%s\\%s.rtb" , p_cMapName , p_cMapName); hFDFile = FindFirstFile (szFileName, &stWFDFile); p_stFI -> dwSize = (hFDFile != INVALID_HANDLE_VALUE ? stWFDFile . nFileSizeLow : 0); _p_oList -> AddTail (p_stFI); FindClose (hFDFile); // rtp file p_stFI = (tdstFileInfo*) malloc (sizeof tdstFileInfo); sprintf (szFileName , "%s%s\\%s.rtp" , _szDataPath , p_cMapName , p_cMapName); sprintf (p_stFI -> szFileName , "%s\\%s.rtp" , p_cMapName , p_cMapName); hFDFile = FindFirstFile (szFileName, &stWFDFile); p_stFI -> dwSize = (hFDFile != INVALID_HANDLE_VALUE ? stWFDFile . nFileSizeLow : 0); _p_oList -> AddTail (p_stFI); FindClose (hFDFile); // rts file p_stFI = (tdstFileInfo*) malloc (sizeof tdstFileInfo); sprintf (szFileName , "%s%s\\%s.rts" , _szDataPath , p_cMapName , p_cMapName); sprintf (p_stFI -> szFileName , "%s\\%s.rts" , p_cMapName , p_cMapName); hFDFile = FindFirstFile (szFileName, &stWFDFile); p_stFI -> dwSize = (hFDFile != INVALID_HANDLE_VALUE ? stWFDFile . nFileSizeLow : 0); _p_oList -> AddTail (p_stFI); FindClose (hFDFile); // rtt file p_stFI = (tdstFileInfo*) malloc (sizeof tdstFileInfo); sprintf (szFileName , "%s%s\\%s.rtt" , _szDataPath , p_cMapName , p_cMapName); sprintf (p_stFI -> szFileName , "%s\\%s.rtt" , p_cMapName , p_cMapName); hFDFile = FindFirstFile (szFileName, &stWFDFile); p_stFI -> dwSize = (hFDFile != INVALID_HANDLE_VALUE ? stWFDFile . nFileSizeLow : 0); _p_oList -> AddTail (p_stFI); FindClose (hFDFile); m_Ctrl_ProgressBar . StepIt (); } // dwMapNumber = 0; xPos = _p_oList -> GetHeadPosition (); while (xPos) { tdstFileInfo *p_stFI = _p_oList -> GetNext (xPos); p_stFI -> dwMapNumber = dwMapNumber++; } sprintf (szText , "\t%d rt? files" , _p_oList -> GetCount ()); pLB -> AddString (szText); } #define M_SECTOR_SIZE 2048 //------------------------------------------------------------------------ // // Author Marc Trabucato // Date 22 mars 1999 // // Prototype CBigFileToolDlg::MixUpFiles // Parameters _p_oFIList : // _p_oMUIList : // Return Type void // // Description // //------------------------------------------------------------------------ BOOL CBigFileToolDlg::MixUpFiles(DWORD _dwBigFileSize , CListOfFileInfo *_p_oFIList , tdstMixUpInfo **_a_MUITab, tdstBigFileInfo *p_stBFI) { DWORD dwArraySize; POSITION xPos; tdstMixUpInfo *p_stMUI; DWORD dwOffSet; DWORD dwMaxSize = 0; M_LIST(IDC_LIST_WORK) -> AddString (""); M_LIST(IDC_LIST_WORK) -> AddString ("Mix up files"); M_LIST(IDC_LIST_WORK) -> AddString (""); // compute total size M_LIST(IDC_LIST_WORK) -> AddString ("\tCompute total size"); p_stBFI -> dwTotalSize = 0; xPos = _p_oFIList -> GetHeadPosition (); while (xPos) { DWORD dwSize = _p_oFIList -> GetNext (xPos) -> dwSize; dwSize = fn_dwAlignToSectorSize(dwSize + 4, M_SECTOR_SIZE); // add protect-key to each file p_stBFI -> dwTotalSize += dwSize; } p_stBFI -> dwNbFile = _p_oFIList -> GetCount (); // compute number of occurrences M_LIST(IDC_LIST_WORK) -> AddString ("\tCompute number of occurrences"); p_stBFI -> dwNbOccur = 1 + (_dwBigFileSize / p_stBFI -> dwTotalSize); { CString csText; csText . Format ("\t%d occurrences of %d files" , p_stBFI -> dwNbOccur , p_stBFI -> dwNbFile); M_LIST(IDC_LIST_WORK) -> AddString (csText); } // LARGE_INTEGER PerformanceCount; QueryPerformanceCounter (&PerformanceCount); PTC_g_lCurrentRandom = PerformanceCount . LowPart; // Create Array dwArraySize = p_stBFI -> dwNbOccur * p_stBFI -> dwNbFile; *_a_MUITab = (tdstMixUpInfo*) malloc (dwArraySize * sizeof(tdstMixUpInfo)); // Fill Array p_stMUI = *_a_MUITab; p_stBFI -> dwMaxFileSize = 0; for (DWORD dwOccur = 0 ; dwOccur < p_stBFI -> dwNbOccur ; dwOccur++) { xPos = _p_oFIList -> GetHeadPosition (); while (xPos) { tdstFileInfo *p_stFI = _p_oFIList -> GetAt (xPos); p_stMUI -> xFileInfoPosition = xPos; p_stMUI -> dwOccur = dwOccur; p_stMUI -> dwOffSet = 0; p_stMUI -> dwMapNumber = p_stFI -> dwMapNumber; p_stMUI -> dwSize = fn_dwAlignToSectorSize(p_stFI -> dwSize + 4, M_SECTOR_SIZE); // add protect-key to each file p_stMUI -> p_cFileName = p_stFI -> szFileName; p_stBFI -> dwMaxFileSize = max (p_stBFI -> dwMaxFileSize, p_stMUI -> dwSize); _p_oFIList -> GetNext (xPos); p_stMUI++; } } // MixUp Array // M_LIST(IDC_LIST_WORK) -> AddString ("\tMix up files and Compute OffSets"); // Init Offset p_stBFI -> dwBigHeaderSize = fn_dwGetTotalHeaderSize(p_stBFI -> dwNbFile , p_stBFI -> dwNbOccur , M_SECTOR_SIZE); dwOffSet = p_stBFI -> dwBigHeaderSize; for (DWORD dwIndex = 0 ; dwIndex < dwArraySize-1 ; dwIndex++) { DWORD dwNewPosition = PTC_fn_lGetRandomRange (dwIndex+1 , dwArraySize); // swap tdstMixUpInfo stMUITmp; stMUITmp = (*_a_MUITab)[dwIndex]; (*_a_MUITab)[dwIndex] = (*_a_MUITab)[dwNewPosition]; (*_a_MUITab)[dwNewPosition] = stMUITmp; // compute OffSet (*_a_MUITab)[dwIndex] . dwOffSet = dwOffSet; // increase OffSet dwOffSet += (*_a_MUITab)[dwIndex] . dwSize; } // compute OffSet of last one (*_a_MUITab)[dwArraySize-1] . dwOffSet = dwOffSet; return TRUE; } //------------------------------------------------------------------------ //------------------------------------------------------------------------ //------------------------------------------------------------------------ //------------------------------------------------------------------------ //------------------------------------------------------------------------ BOOL CBigFileToolDlg::WriteHeader(HANDLE hFile, CListOfFileInfo *_p_oFIList, tdstMixUpInfo *_a_MUITab, tdstBigFileInfo *p_stBFI) { DWORD dwNumberOfMUI = p_stBFI -> dwNbOccur * p_stBFI -> dwNbFile; tdstMixUpInfo *p_stMUI = _a_MUITab; tdstMixUpInfo *p_stMUIEnd = _a_MUITab + dwNumberOfMUI; DWORD *a_OffSet; DWORD dwWritten; DWORD dwKeys[4]; DWORD dwCount; DWORD *p_dwHeader,*p_dwCurrentPos,*p_dwBeginOfCryptHeader,*p_dwEndHeader; M_LIST(IDC_LIST_WORK) -> AddString (""); M_LIST(IDC_LIST_WORK) -> AddString ("Write Header"); M_LIST(IDC_LIST_WORK) -> AddString (""); // Compute Header Size : Keys + MapNumber + OccurNumber + Offset p_dwCurrentPos = p_dwHeader = (DWORD*) malloc (p_stBFI -> dwBigHeaderSize); p_dwEndHeader = p_dwHeader + (p_stBFI -> dwBigHeaderSize>>2); m_Ctrl_ProgressBar . SetRange (0 , p_stBFI -> dwBigHeaderSize << 2); m_Ctrl_ProgressBar . SetPos (2); { CString csText; csText . Format ("\tSize of header : %d" , p_stBFI -> dwBigHeaderSize); M_LIST(IDC_LIST_WORK) -> AddString (csText); } // Compute and write keys dwCount = 0; M_LIST(IDC_LIST_WORK) -> AddString ("\tCompute keys"); for (int i=0 ; i<4 ; i++ ) { dwKeys[i] = PTC_fn_lGetRandom(); *p_dwCurrentPos++ = dwKeys[i]; m_Ctrl_ProgressBar . SetStep (1); dwCount++; } p_dwBeginOfCryptHeader = p_dwCurrentPos; // Write Number of map M_LIST(IDC_LIST_WORK) -> AddString ("\tWrite Number of files"); *p_dwCurrentPos++ = p_stBFI -> dwNbFile; m_Ctrl_ProgressBar . SetStep (1); dwCount++; // Write number of occur M_LIST(IDC_LIST_WORK) -> AddString ("\tWrite number of occur"); *p_dwCurrentPos++ = p_stBFI -> dwNbOccur; m_Ctrl_ProgressBar . SetStep (1); dwCount++; // Compute OffSet M_LIST(IDC_LIST_WORK) -> AddString ("\tCompute OffSet"); a_OffSet = p_dwCurrentPos; while (p_stMUI != p_stMUIEnd) { // DWORD dwIndex = p_stBFI -> dwNbOccur * p_stMUI -> dwMapNumber + p_stMUI -> dwOccur; a_OffSet [ dwIndex ] = p_stMUI -> dwOffSet ; // next p_stMUI++; m_Ctrl_ProgressBar . SetStep (1); } if (m_bGenerateInfoFiles) { char szText[255]; HANDLE hDebugFile = CreateFile ("BigFile.txt" , GENERIC_WRITE , 0 , NULL , CREATE_ALWAYS , FILE_ATTRIBUTE_NORMAL , NULL); DWORD dwMap , dwOcc, dwW; sprintf (szText , "Keys : 0x%08x - 0x%08x - 0x%08x - 0x%08x\x0D\x0A" , dwKeys[0] , dwKeys[1] , dwKeys[2] , dwKeys[3]); WriteFile (hDebugFile , szText , strlen(szText) , &dwW , NULL); for (dwOcc = 0 ; dwOcc < p_stBFI -> dwNbOccur ; dwOcc++) { sprintf (szText , "==============================================================================\x0D\x0A"); WriteFile (hDebugFile , szText , strlen(szText) , &dwW , NULL); for (dwMap = 0 ; dwMap < p_stBFI -> dwNbMap ; dwMap+=4) { DWORD dwIndex = p_stBFI -> dwNbOccur * dwMap + dwOcc; sprintf (szText , "Map : %02d : Occur %02d : 0x%08x - 0x%08x - 0x%08x - 0x%08x\x0D\x0A" , dwMap >> 2, dwOcc , a_OffSet [dwIndex] , a_OffSet [dwIndex + p_stBFI -> dwNbOccur] ,a_OffSet [dwIndex + p_stBFI -> dwNbOccur + p_stBFI -> dwNbOccur] ,a_OffSet [dwIndex + p_stBFI -> dwNbOccur + p_stBFI -> dwNbOccur + p_stBFI -> dwNbOccur]); WriteFile (hDebugFile , szText , strlen(szText) , &dwW , NULL); } } sprintf (szText , "==============================================================================\x0D\x0A"); WriteFile (hDebugFile , szText , strlen(szText) , &dwW , NULL); CloseHandle (hDebugFile); } p_dwCurrentPos = a_OffSet + (p_stBFI -> dwNbOccur * p_stBFI -> dwNbFile); dwCount += p_stBFI -> dwNbOccur * p_stBFI -> dwNbFile; // fill to align to Sector Size while (p_dwCurrentPos != p_dwEndHeader) { *p_dwCurrentPos++ = PTC_fn_lGetRandom(); m_Ctrl_ProgressBar . SetStep (1); dwCount++; } ASSERT(dwCount == (p_stBFI -> dwBigHeaderSize>>2)); // crypt file p_dwCurrentPos = p_dwBeginOfCryptHeader; while (p_dwCurrentPos != p_dwEndHeader) { *p_dwCurrentPos = (*p_dwCurrentPos ^ dwKeys[1]) + dwKeys[0]; *p_dwCurrentPos++; dwKeys[0] += dwKeys[2]; dwKeys[1] += dwKeys[3]; } // Write File WriteFile (hFile , p_dwHeader , p_stBFI -> dwBigHeaderSize , &dwWritten , NULL); free (p_dwHeader); return TRUE; } //------------------------------------------------------------------------ // // Author Marc Trabucato // Date 22 mars 1999 // // Prototype CBigFileToolDlg::WriteFiles // Parameters hFile : // _p_oFIList : // _p_oMUIList : // Return Type void // // Description Write all files to Big File // //------------------------------------------------------------------------ BOOL CBigFileToolDlg::WriteFiles(char *_szDataPath , HANDLE hFile, CListOfFileInfo *_p_oFIList, tdstMixUpInfo *_a_MUITab, tdstBigFileInfo *p_stBFI) { DWORD dwNumberOfMUI = p_stBFI -> dwNbOccur * p_stBFI -> dwNbFile; tdstMixUpInfo *p_stMUI = _a_MUITab; tdstMixUpInfo *p_stMUIEnd = _a_MUITab + dwNumberOfMUI; char szFileName[MAX_PATH]; char *p_cBeginFileName; DWORD dwRead , dwWritten; char szText[255]; HANDLE hDebugFile; DWORD dwW,dwCount; DWORD dwCurrentOffSet; unsigned char a_ucKeys[4]; unsigned char a_ucCode[4]; unsigned char a_ucProtection[4]; DWORD *p_dwKey = (DWORD*)a_ucKeys; DWORD *p_dwProtection = (DWORD*)a_ucProtection; M_LIST(IDC_LIST_WORK) -> AddString (""); M_LIST(IDC_LIST_WORK) -> AddString ("Write files"); M_LIST(IDC_LIST_WORK) -> AddString (""); m_Ctrl_ProgressBar . SetRange (0 , dwNumberOfMUI); m_Ctrl_ProgressBar . SetPos (0); m_Ctrl_ProgressBar . SetStep (1); strcpy (szFileName , _szDataPath); p_cBeginFileName = szFileName + strlen (_szDataPath); HGLOBAL hMem = GlobalAlloc (GHND , p_stBFI -> dwMaxFileSize + 4 + 4); char *p_Buffer = (char*) GlobalLock (hMem); char *p_Begin; if (m_bGenerateInfoFiles) { hDebugFile = CreateFile ("BigFile.log" , GENERIC_WRITE , 0 , NULL , CREATE_ALWAYS , FILE_ATTRIBUTE_NORMAL , NULL); dwCurrentOffSet = p_stBFI -> dwBigHeaderSize; dwCount = 0; } while (p_stMUI != p_stMUIEnd) { tdstFileInfo *p_stFI = _p_oFIList -> GetAt (p_stMUI -> xFileInfoPosition); // compute crypt int-key a_ucCode[0] = (unsigned char) (p_stMUI -> dwMapNumber >> 2); a_ucCode[1] = (unsigned char) (p_stMUI -> dwMapNumber % 4); a_ucCode[2] = (unsigned char) (p_stMUI -> dwOccur & 0x000000FF); a_ucCode[3] = ~a_ucCode[2]; // compute crypt key *p_dwKey = PTC_fn_lGetCryptKey (*(DWORD*)a_ucCode); // compute protection key *p_dwProtection = PTC_fn_lGetProtectionKey (*(DWORD*)a_ucCode); // fill Debug File if (m_bGenerateInfoFiles && hDebugFile != INVALID_HANDLE_VALUE) { sprintf (szText , "%03d - OffSet : 0x%08x - init-key : 0x%02x%02x%02x%02x => crypt-key : 0x%08x => protect-key : 0x%08x - Map : %s\x0D\x0A" , dwCount++ , dwCurrentOffSet , a_ucCode[0] , a_ucCode[1] , a_ucCode[2] , a_ucCode[3] , *p_dwKey , *p_dwProtection , p_cBeginFileName ); WriteFile (hDebugFile , szText , strlen(szText) , &dwW , NULL); } // copy Protect key to buffer memcpy (p_Buffer , p_dwProtection , 4); // open Source file strcpy (p_cBeginFileName , p_stFI -> szFileName); HANDLE hSourceFile = CreateFile ( szFileName, GENERIC_READ , 0 , NULL , OPEN_EXISTING , FILE_ATTRIBUTE_NORMAL , NULL); // Copy File // Read initial file ReadFile (hSourceFile , p_Buffer + 4 , p_stFI -> dwSize + 1 , &dwRead , NULL); CloseHandle (hSourceFile); dwRead += 4; // protect key size // crypt buffer unsigned char *p_ucBeginBuffer = (unsigned char*)p_Buffer; unsigned char *p_ucEndBuffer = (unsigned char*)p_Buffer + dwRead; while (p_ucBeginBuffer != p_ucEndBuffer) { *p_ucBeginBuffer = (*p_ucBeginBuffer ^ a_ucKeys[1]) + a_ucKeys[0]; a_ucKeys[0] += a_ucKeys[2]; a_ucKeys[1] += a_ucKeys[3]; p_ucBeginBuffer++; } p_Begin = p_Buffer + dwRead; // Fill to long alignment while (dwRead % 4) { *p_Begin = (unsigned char) PTC_fn_lGetRandomRange (0, 255); p_Begin++; dwRead++; } // Fill to align to sector size while (dwRead < p_stMUI -> dwSize) { DWORD dwRandom = PTC_fn_lGetRandom(); memcpy (p_Begin , &dwRandom , 4); p_Begin += 4; dwRead += 4; } // write buffer WriteFile(hFile , p_Buffer , p_stMUI -> dwSize , &dwWritten , NULL); if (m_bGenerateInfoFiles && hDebugFile != INVALID_HANDLE_VALUE) dwCurrentOffSet += dwWritten; m_Ctrl_ProgressBar . StepIt (); // next p_stMUI++; // Message Pump PeekAndPump (); } GlobalUnlock (hMem); GlobalFree (hMem); if (m_bGenerateInfoFiles && hDebugFile != INVALID_HANDLE_VALUE) CloseHandle (hDebugFile); m_Ctrl_ProgressBar . SetPos (0); return TRUE; } //------------------------------------------------------------------------ // // Author Marc Trabucato // Date 23 mars 1999 // // Prototype CBigFileToolDlg::DeleteFiles // Parameters _szDataPath : // _p_oList : // Return Type void // // Description // //------------------------------------------------------------------------ void CBigFileToolDlg::DeleteFiles(char *_szDataPath , CListOfFileInfo * _p_oList) { POSITION xPos; char szFileName[MAX_PATH]; char *p_cBeginFileName; M_LIST(IDC_LIST_WORK) -> AddString (""); M_LIST(IDC_LIST_WORK) -> AddString ("Delete files"); M_LIST(IDC_LIST_WORK) -> AddString (""); m_Ctrl_ProgressBar . SetRange (0 , _p_oList -> GetCount ()); m_Ctrl_ProgressBar . SetPos (0); m_Ctrl_ProgressBar . SetStep (1); strcpy (szFileName , _szDataPath); p_cBeginFileName = szFileName + strlen (_szDataPath); xPos = _p_oList -> GetHeadPosition (); while (xPos) { tdstFileInfo *p_stFI = _p_oList -> GetNext (xPos); strcpy (p_cBeginFileName , p_stFI -> szFileName); if (_access(szFileName , 00) == 0) { remove (szFileName); } m_Ctrl_ProgressBar . StepIt (); } } //------------------------------------------------------------------------ //------------------------------------------------------------------------ //------------------------------------------------------------------------ int fn_iCompareHeaderInfo(const void *elem1, const void *elem2 ) { tdstHeaderInfo *p_stHI1 = (tdstHeaderInfo*)elem1; tdstHeaderInfo *p_stHI2 = (tdstHeaderInfo*)elem2; if (p_stHI1 -> dwOffSet < p_stHI2 -> dwOffSet) return -1; else if (p_stHI1 -> dwOffSet == p_stHI2 -> dwOffSet) return 0; else return 1; } #define M_Arround(x) (floor(x * 1000000.0) / 1000000.0) //------------------------------------------------------------------------ //------------------------------------------------------------------------ BOOL CBigFileToolDlg::MixUpFilesWithExplodedHeader(DWORD _dwBigFileSize , CListOfFileInfo *_p_oFIList , tdstMixUpInfo **_a_MUITab, tdstBigFileInfo *p_stBFI, tdstHeaderInfo **_a_HITab) { DWORD dwArraySize , dwNextHeaderPos , dwHeaderNumber; POSITION xPos; tdstMixUpInfo *p_stMUI; DWORD dwOffSet; DWORD dwMaxSize = 0; DWORD dwCount = 0; CString csText; M_LIST(IDC_LIST_WORK) -> AddString (""); M_LIST(IDC_LIST_WORK) -> AddString ("Mix up files"); M_LIST(IDC_LIST_WORK) -> AddString (""); // compute total size M_LIST(IDC_LIST_WORK) -> AddString ("\tCompute total size of rt? files"); p_stBFI -> dwTotalSize = 0; xPos = _p_oFIList -> GetHeadPosition (); while (xPos) { DWORD dwSize = _p_oFIList -> GetNext (xPos) -> dwSize; dwSize = fn_dwAlignToSectorSize(dwSize + 4, M_SECTOR_SIZE); // add protect-key to each file p_stBFI -> dwTotalSize += dwSize; } p_stBFI -> dwNbFile = _p_oFIList -> GetCount (); p_stBFI -> dwNbMap = (p_stBFI -> dwNbFile >> 2); p_stBFI -> dwFirstHeaderSize = fn_dwAlignToSectorSize(16 + 4 + 4 + 4 + 4 + 4 + 4, M_SECTOR_SIZE); // First Header : Keys (4) + MapNumber (1) + OccurNumber (1) + HeaderStep (1) + FirstHeaderSize (1) + FileStep (1) + SectorSize (1) { csText . Format ("\t\tTotal Size : %d" , p_stBFI -> dwTotalSize); M_LIST(IDC_LIST_WORK) -> AddString (csText); } /* -------------------------------------------------------------------------------------------------------------- */ // compute number of occurrences M_LIST(IDC_LIST_WORK) -> AddString ("\tCompute number of occurrences"); p_stBFI -> dwNbOccur = 1 + (_dwBigFileSize / p_stBFI -> dwTotalSize); if (p_stBFI -> dwNbOccur > 30) p_stBFI -> dwNbOccur = 30; { csText . Format ("\t\t%d occurrences of %d files" , p_stBFI -> dwNbOccur , p_stBFI -> dwNbFile); M_LIST(IDC_LIST_WORK) -> AddString (csText); } // LARGE_INTEGER PerformanceCount; QueryPerformanceCounter (&PerformanceCount); PTC_g_lCurrentRandom = PerformanceCount . LowPart; /* -------------------------------------------------------------------------------------------------------------- */ // Create Array dwArraySize = p_stBFI -> dwNbOccur * p_stBFI -> dwNbFile; *_a_MUITab = (tdstMixUpInfo*) malloc (dwArraySize * sizeof(tdstMixUpInfo)); // Fill Array p_stMUI = *_a_MUITab; for (DWORD dwOccur = 0 ; dwOccur < p_stBFI -> dwNbOccur ; dwOccur++) { xPos = _p_oFIList -> GetHeadPosition (); while (xPos) { tdstFileInfo *p_stFI = _p_oFIList -> GetAt (xPos); p_stMUI -> xFileInfoPosition = xPos; p_stMUI -> dwOccur = dwOccur; p_stMUI -> dwOffSet = 0; p_stMUI -> dwMapNumber = p_stFI -> dwMapNumber; p_stMUI -> dwSize = fn_dwAlignToSectorSize(p_stFI -> dwSize + 4, M_SECTOR_SIZE); // add protect-key to each file p_stMUI -> p_cFileName = p_stFI -> szFileName; p_stBFI -> dwMaxFileSize = max (p_stBFI -> dwMaxFileSize, p_stMUI -> dwSize); _p_oFIList -> GetNext (xPos); p_stMUI++; } } /* -------------------------------------------------------------------------------------------------------------- */ p_stBFI -> dwHeaderSize = fn_dwGetHeaderSizeforAnOccur (p_stBFI -> dwNbOccur * 4, M_SECTOR_SIZE); p_stBFI -> dwTotalSector = (p_stBFI -> dwNbOccur * p_stBFI -> dwTotalSize) / M_SECTOR_SIZE; p_stBFI -> dwTotalSector = (p_stBFI -> dwNbOccur * p_stBFI -> dwTotalSize) / p_stBFI -> dwHeaderSize; p_stBFI -> dwHeaderStep = p_stBFI -> dwTotalSector / (p_stBFI -> dwNbOccur + 1); { CString csText; //csText . Format ("\tHeader Step : 0x%08x" , p_stBFI -> dwHeaderStep * M_SECTOR_SIZE); //M_LIST(IDC_LIST_WORK) -> AddString (csText); //csText . Format ("\tHeader Size : 0x%08x - %d" , p_stBFI -> dwHeaderSize , p_stBFI -> dwHeaderSize); //M_LIST(IDC_LIST_WORK) -> AddString (csText); csText . Format ("\tNb Total Sector : 0x%08x - %d" , p_stBFI -> dwTotalSector , p_stBFI -> dwTotalSector); M_LIST(IDC_LIST_WORK) -> AddString (csText); } /* -------------------------------------------------------------------------------------------------------------- */ M_LIST(IDC_LIST_WORK) -> AddString ("\tCompute Headers positions"); *_a_HITab = (tdstHeaderInfo*) malloc (p_stBFI -> dwNbOccur * sizeof(tdstHeaderInfo)); { DWORD dwN; double fN , fValue , fA , fB , fC, fInteger; //fA = M_Arround(log(2.0)); //fB = 1.0+fA; //fC = M_Arround(log(fB)); //fN = M_Arround(log(fabs(fA)+fabs(fB)+fabs(fC))); fA = 0.69314; fB = 1.69314; fC = 0.52658; fN = 1.06913; //csText . Format ("\tfA : %15.8f - fA : %15.8f - fC : %15.8f - f0 : %15.8f" , fA , fB , fC , fN); //M_LIST(IDC_LIST_WORK) -> AddString (csText); for (dwN = 0 ; dwN < p_stBFI -> dwNbOccur ; dwN++) { fValue = M_Arround(modf(fN , &fInteger)); //csText . Format ("\tOccur %03d : Value %15.8f - OffSet : 0x%08x" , dwN , fValue , M_SECTOR_SIZE * (DWORD)floor(fValue * p_stBFI -> dwTotalSector) ); //M_LIST(IDC_LIST_WORK) -> AddString (csText); (*_a_HITab) [dwN] . dwOccur = dwN; //(*_a_HITab) [dwN] . dwOffSet = M_SECTOR_SIZE * (DWORD)floor(fValue * p_stBFI -> dwTotalSector) + p_stBFI -> dwFirstHeaderSize; (*_a_HITab) [dwN] . dwOffSet = p_stBFI -> dwHeaderSize * (DWORD)floor(fValue * p_stBFI -> dwTotalSector) + p_stBFI -> dwFirstHeaderSize; fN = fN + fA * fabs(sin(fB * dwN * dwN)) + fC; //fN = M_Arround(fN); } qsort((*_a_HITab) , p_stBFI -> dwNbOccur , sizeof(tdstHeaderInfo) , fn_iCompareHeaderInfo); } /* { for (DWORD dwN = 0 ; dwN < *_p_dwTotalOccur ; dwN++) { CString csText; (*_a_HITab) [dwN] . dwOccur = dwN; (*_a_HITab) [dwN] . dwOffSet = (dwN+1) * *_p_dwHeaderStep * M_SECTOR_SIZE; } } */ M_LIST(IDC_LIST_WORK) -> AddString ("\t\tVerify Headers positions"); { for (DWORD dwN = 0 ; dwN < p_stBFI -> dwNbOccur - 1 ; dwN++) { //csText . Format ("\t%03d : Occur %03d - OffSet : 0x%08x" , dwN , (*_a_HITab) [dwN] . dwOccur , (*_a_HITab) [dwN] . dwOffSet ); //M_LIST(IDC_LIST_WORK) -> AddString (csText); if( (*_a_HITab) [dwN] . dwOffSet + p_stBFI -> dwHeaderSize >= (*_a_HITab) [dwN+1] . dwOffSet) { m_csErrorMessage = "Recovering Header"; return FALSE; } } } M_LIST(IDC_LIST_WORK) -> AddString ("\t\tHeaders positions Ok"); /* -------------------------------------------------------------------------------------------------------------- */ M_LIST(IDC_LIST_WORK) -> AddString ("\tMixUp Files and Headers"); dwOffSet = p_stBFI -> dwFirstHeaderSize; dwHeaderNumber = 0; dwNextHeaderPos = (*_a_HITab) [dwHeaderNumber] . dwOffSet; for (DWORD dwIndex = 0 ; dwIndex < dwArraySize-1 ; dwIndex++) { BOOL bContinue = TRUE; while (bContinue) { DWORD dwRandomPosition = PTC_fn_lGetRandomRange (dwIndex+1 , dwArraySize); DWORD dwNewPosition = dwRandomPosition; // swap tdstMixUpInfo stMUITmp; // enough place ??? while ((dwNewPosition < dwArraySize) && (dwOffSet + (*_a_MUITab)[dwNewPosition] . dwSize > dwNextHeaderPos)) { dwNewPosition++; } if(dwNewPosition == dwArraySize) { dwNewPosition = dwRandomPosition; while ((dwNewPosition > dwIndex) && (dwOffSet + (*_a_MUITab)[dwNewPosition] . dwSize > dwNextHeaderPos)) { dwNewPosition--; } } if (dwNewPosition != dwArraySize && dwNewPosition != dwIndex) { // found one stMUITmp = (*_a_MUITab)[dwIndex]; (*_a_MUITab)[dwIndex] = (*_a_MUITab)[dwNewPosition]; (*_a_MUITab)[dwNewPosition] = stMUITmp; // compute OffSet (*_a_MUITab)[dwIndex] . dwOffSet = dwOffSet; // // increase OffSet dwOffSet += (*_a_MUITab)[dwIndex] . dwSize; // bContinue = FALSE; } else { // up to next Header; dwOffSet = dwNextHeaderPos + p_stBFI -> dwHeaderSize; dwHeaderNumber++; if (dwHeaderNumber < p_stBFI -> dwNbOccur) { dwNextHeaderPos = (*_a_HITab) [dwHeaderNumber] . dwOffSet; } else { // no more header dwNextHeaderPos = 0xFFFFFFFF; } } } } // compute OffSet of last one (*_a_MUITab)[dwArraySize-1] . dwOffSet = dwOffSet; ///////////////////////////////// ///////////////////////////////// ///////////////////////////////// ///////////////////////////////// ///////////////////////////////// /* if (m_bGenerateInfoFiles) { HANDLE hDebugFile = CreateFile ("BigFile.map" , GENERIC_WRITE , 0 , NULL , CREATE_ALWAYS , FILE_ATTRIBUTE_NORMAL , NULL); DWORD dwW; p_stMUI = *_a_MUITab; tdstMixUpInfo *p_stMUIEnd = *_a_MUITab + dwArraySize; dwCount = 0; dwOffSet = p_stBFI -> dwFirstHeaderSize; dwHeaderNumber = 0; dwNextHeaderPos = (*_a_HITab) [dwHeaderNumber] . dwOffSet; while (p_stMUI != p_stMUIEnd) { csText . Format ("%03d - OffSet : 0x%08x - Size : 0x%08x - End : 0x%08x - %s\x0D\x0A" , dwCount , p_stMUI -> dwOffSet , p_stMUI -> dwSize , p_stMUI -> dwOffSet + p_stMUI -> dwSize , p_stMUI -> p_cFileName); WriteFile (hDebugFile , (char*)(LPCTSTR)csText , csText . GetLength () , &dwW , NULL); p_stMUI++; dwCount++; while (p_stMUI -> dwOffSet > dwNextHeaderPos) { csText . Format ("===== Gap : 0x%08x\x0D\x0A" , dwNextHeaderPos - ((p_stMUI-1) -> dwOffSet + (p_stMUI-1) -> dwSize)); WriteFile (hDebugFile , (char*)(LPCTSTR)csText , csText . GetLength () , &dwW , NULL); csText . Format ("\tOffSet : 0x%08x - Size : 0x%08x - End : 0x%08x - Header : %d\x0D\x0A" , (*_a_HITab) [dwHeaderNumber] . dwOffSet , p_stBFI -> dwHeaderSize , (*_a_HITab) [dwHeaderNumber] . dwOffSet + p_stBFI -> dwHeaderSize , (*_a_HITab) [dwHeaderNumber] .dwOccur); WriteFile (hDebugFile , (char*)(LPCTSTR)csText , csText . GetLength () , &dwW , NULL); dwHeaderNumber++; if (dwHeaderNumber < p_stBFI -> dwNbOccur) { dwNextHeaderPos = (*_a_HITab) [dwHeaderNumber] . dwOffSet; } else { // no more header dwNextHeaderPos = 0xFFFFFFFF; } } } CloseHandle (hDebugFile); } */ ///////////////////////////////// ///////////////////////////////// ///////////////////////////////// ///////////////////////////////// ///////////////////////////////// return TRUE; } //------------------------------------------------------------------------ //------------------------------------------------------------------------ BOOL CBigFileToolDlg::WriteBigFileWithExplodedHeader(char *_szDataPath , HANDLE hFile, CListOfFileInfo *_p_oFIList, tdstMixUpInfo *_a_MUITab, tdstBigFileInfo *p_stBFI, tdstHeaderInfo *_a_HITab) { DWORD dwNumberOfMUI = p_stBFI -> dwNbOccur * p_stBFI -> dwNbFile; tdstMixUpInfo *p_stMUI = _a_MUITab; tdstMixUpInfo *p_stMUIEnd = _a_MUITab + dwNumberOfMUI; char szFileName[MAX_PATH]; char *p_cBeginFileName; DWORD dwRead , dwWritten; char szText[255]; HANDLE hDebugFile; DWORD dwW,dwCount; DWORD dwOffSet; unsigned char a_ucKeys[4]; unsigned char a_ucCode[4]; unsigned char a_ucProtection[4]; DWORD *p_dwKey = (DWORD*)a_ucKeys; DWORD *p_dwProtection = (DWORD*)a_ucProtection; DWORD dwNextHeaderPos , dwHeaderNumber; M_LIST(IDC_LIST_WORK) -> AddString (""); M_LIST(IDC_LIST_WORK) -> AddString ("Write files"); M_LIST(IDC_LIST_WORK) -> AddString (""); m_Ctrl_ProgressBar . SetRange (0 , dwNumberOfMUI + p_stBFI -> dwNbOccur); m_Ctrl_ProgressBar . SetPos (0); m_Ctrl_ProgressBar . SetStep (1); strcpy (szFileName , _szDataPath); p_cBeginFileName = szFileName + strlen (_szDataPath); HGLOBAL hMem = GlobalAlloc (GHND , p_stBFI -> dwMaxFileSize + 4 + 4); char *p_Buffer = (char*) GlobalLock (hMem); char *p_Begin; //////////////////////////////////////////////// // compute all headers //////////////////////////////////////////////// DWORD *a_OffSet = (DWORD*) malloc (dwNumberOfMUI*4); DWORD *p_dwEndHeader = a_OffSet + (dwNumberOfMUI); while (p_stMUI != p_stMUIEnd) { // DWORD dwIndex = p_stBFI -> dwNbOccur * p_stMUI -> dwMapNumber + p_stMUI -> dwOccur; a_OffSet [ dwIndex ] = p_stMUI -> dwOffSet ; // next p_stMUI++; } if (m_bGenerateInfoFiles) { char szText[255]; HANDLE hDebugFile = CreateFile ("BigFile.txt" , GENERIC_WRITE , 0 , NULL , CREATE_ALWAYS , FILE_ATTRIBUTE_NORMAL , NULL); DWORD dwMap , dwOcc, dwW; for (dwOcc = 0 ; dwOcc < p_stBFI -> dwNbOccur ; dwOcc++) { sprintf (szText , "==============================================================================\x0D\x0A"); WriteFile (hDebugFile , szText , strlen(szText) , &dwW , NULL); for (dwMap = 0 ; dwMap < p_stBFI -> dwNbFile ; dwMap+=4) { DWORD dwIndex = p_stBFI -> dwNbOccur * dwMap + dwOcc; sprintf (szText , "Map : %02d : Occur %02d : 0x%08x - 0x%08x - 0x%08x - 0x%08x\x0D\x0A" , dwMap >> 2 , dwOcc , a_OffSet [dwIndex] , a_OffSet [dwIndex + p_stBFI -> dwNbOccur] ,a_OffSet [dwIndex + p_stBFI -> dwNbOccur + p_stBFI -> dwNbOccur] ,a_OffSet [dwIndex + p_stBFI -> dwNbOccur + p_stBFI -> dwNbOccur + p_stBFI -> dwNbOccur]); WriteFile (hDebugFile , szText , strlen(szText) , &dwW , NULL); } } sprintf (szText , "==============================================================================\x0D\x0A"); WriteFile (hDebugFile , szText , strlen(szText) , &dwW , NULL); CloseHandle (hDebugFile); } //////////////////////////////////////////////// // Write First Header : Keys (4) + MapNumber (1) + OccurNumber (1) + HeaderStep (1) + FirstHeaderSize (1) + File Step (1) + SectorSize (1) //////////////////////////////////////////////// if (m_bGenerateInfoFiles) { hDebugFile = CreateFile ("BigFile.log" , GENERIC_WRITE , 0 , NULL , CREATE_ALWAYS , FILE_ATTRIBUTE_NORMAL , NULL); dwOffSet = 0; dwCount = 0; } DWORD dwKeys[4]; DWORD *p_dwCurrentPos = (DWORD*)p_Buffer; dwOffSet = 0; // compute keys for (int i=0 ; i<4 ; i++ ) { dwKeys[i] = PTC_fn_lGetRandom(); *p_dwCurrentPos++ = dwKeys[i]; dwOffSet += 4; } // fill Debug File if (m_bGenerateInfoFiles && hDebugFile != INVALID_HANDLE_VALUE) { sprintf (szText , "First Header : Crypt-key : 0x%08x - 0x%08x - 0x%08x - 0x%08x\x0D\x0A" , dwKeys[0] , dwKeys[1] , dwKeys[2] , dwKeys[3]); WriteFile (hDebugFile , szText , strlen(szText) , &dwW , NULL); sprintf (szText , "MapNumber : %d : OccurNumber : %d : Header Step : 0x%08x\x0D\x0A" , p_stBFI -> dwNbFile , p_stBFI -> dwNbOccur , p_stBFI -> dwHeaderStep * M_SECTOR_SIZE); WriteFile (hDebugFile , szText , strlen(szText) , &dwW , NULL); sprintf (szText , "First Header Size : 0x%08x - File Step : 0x%08x - Header Size : 0x%08x - Sector Number : 0x%08x\x0D\x0A" , p_stBFI -> dwFirstHeaderSize , 0 , p_stBFI -> dwHeaderSize , p_stBFI -> dwTotalSector); WriteFile (hDebugFile , szText , strlen(szText) , &dwW , NULL); sprintf (szText , "==============================================================================\x0D\x0A"); WriteFile (hDebugFile , szText , strlen(szText) , &dwW , NULL); } // Add number of map *p_dwCurrentPos++ = (p_stBFI -> dwNbFile ^ dwKeys[1]) + dwKeys[0]; dwOffSet += 4; dwKeys[0] += dwKeys[2]; dwKeys[1] += dwKeys[3]; // Add number of Occur *p_dwCurrentPos++ = (p_stBFI -> dwNbOccur ^ dwKeys[1]) + dwKeys[0]; dwOffSet += 4; dwKeys[0] += dwKeys[2]; dwKeys[1] += dwKeys[3]; // Add Header Step *p_dwCurrentPos++ = ((p_stBFI -> dwHeaderStep * M_SECTOR_SIZE) ^ dwKeys[1]) + dwKeys[0]; dwOffSet += 4; dwKeys[0] += dwKeys[2]; dwKeys[1] += dwKeys[3]; // Add First Header Size *p_dwCurrentPos++ = (p_stBFI -> dwFirstHeaderSize ^ dwKeys[1]) + dwKeys[0]; dwOffSet += 4; dwKeys[0] += dwKeys[2]; dwKeys[1] += dwKeys[3]; // Add File Step *p_dwCurrentPos++ = (0 ^ dwKeys[1]) + dwKeys[0]; dwOffSet += 4; dwKeys[0] += dwKeys[2]; dwKeys[1] += dwKeys[3]; // Add Header size *p_dwCurrentPos++ = (p_stBFI -> dwHeaderSize ^ dwKeys[1]) + dwKeys[0]; dwOffSet += 4; dwKeys[0] += dwKeys[2]; dwKeys[1] += dwKeys[3]; // Add Sector Number *p_dwCurrentPos++ = (p_stBFI -> dwTotalSector ^ dwKeys[1]) + dwKeys[0]; dwOffSet += 4; dwKeys[0] += dwKeys[2]; dwKeys[1] += dwKeys[3]; // Fill to align to Sector Size while (dwOffSet < p_stBFI -> dwFirstHeaderSize) { *p_dwCurrentPos++ = PTC_fn_lGetRandom(); dwOffSet += 4; } WriteFile (hFile , p_Buffer , p_stBFI -> dwFirstHeaderSize , &dwOffSet , NULL); //////////////////////////////////////////////// // Write Files and Occur Header //////////////////////////////////////////////// dwHeaderNumber = 0; dwNextHeaderPos = _a_HITab [dwHeaderNumber] . dwOffSet; p_stMUI = _a_MUITab; while (p_stMUI != p_stMUIEnd) { tdstFileInfo *p_stFI = _p_oFIList -> GetAt (p_stMUI -> xFileInfoPosition); if(p_stMUI -> dwOffSet != dwOffSet) { m_csErrorMessage = p_stMUI -> dwOffSet < dwOffSet ? "Recovering blocs" : "Unwanted gap"; return FALSE; } // compute crypt int-key a_ucCode[0] = (unsigned char) (p_stMUI -> dwMapNumber >> 2); a_ucCode[1] = (unsigned char) (p_stMUI -> dwMapNumber % 4); a_ucCode[2] = (unsigned char) (p_stMUI -> dwOccur & 0x000000FF); a_ucCode[3] = ~a_ucCode[2]; // compute crypt key *p_dwKey = PTC_fn_lGetCryptKey (*(DWORD*)a_ucCode); // compute protection key *p_dwProtection = PTC_fn_lGetProtectionKey (*(DWORD*)a_ucCode); // copy Protect key to buffer memcpy (p_Buffer , p_dwProtection , 4); // open Source file strcpy (p_cBeginFileName , p_stFI -> szFileName); // fill Debug File if (m_bGenerateInfoFiles && hDebugFile != INVALID_HANDLE_VALUE) { sprintf (szText , "%03d - OffSet : 0x%08x - init-key : 0x%02x%02x%02x%02x => crypt-key : 0x%08x => protect-key : 0x%08x - Map : %s\x0D\x0A" , dwCount++ , dwOffSet , a_ucCode[0] , a_ucCode[1] , a_ucCode[2] , a_ucCode[3] , *p_dwKey , *p_dwProtection , p_cBeginFileName ); WriteFile (hDebugFile , szText , strlen(szText) , &dwW , NULL); } HANDLE hSourceFile = CreateFile ( szFileName, GENERIC_READ , 0 , NULL , OPEN_EXISTING , FILE_ATTRIBUTE_NORMAL , NULL); // Copy File // Read initial file ReadFile (hSourceFile , p_Buffer + 4 , p_stFI -> dwSize + 1 , &dwRead , NULL); CloseHandle (hSourceFile); dwRead += 4; // protect key size // crypt buffer unsigned char *p_ucBeginBuffer = (unsigned char*)p_Buffer; unsigned char *p_ucEndBuffer = (unsigned char*)p_Buffer + dwRead; while (p_ucBeginBuffer != p_ucEndBuffer) { *p_ucBeginBuffer = (*p_ucBeginBuffer ^ a_ucKeys[1]) + a_ucKeys[0]; a_ucKeys[0] += a_ucKeys[2]; a_ucKeys[1] += a_ucKeys[3]; p_ucBeginBuffer++; } p_Begin = p_Buffer + dwRead; // Fill to long alignment while (dwRead % 4) { *p_Begin = (unsigned char) PTC_fn_lGetRandomRange (0, 255); p_Begin++; dwRead++; } // Fill to align to sector size while (dwRead < p_stMUI -> dwSize) { DWORD dwRandom = PTC_fn_lGetRandom(); memcpy (p_Begin , &dwRandom , 4); p_Begin += 4; dwRead += 4; } // write buffer WriteFile(hFile , p_Buffer , p_stMUI -> dwSize , &dwWritten , NULL); m_Ctrl_ProgressBar . StepIt (); dwOffSet += p_stMUI -> dwSize; // next p_stMUI++; // Message Pump PeekAndPump (); while (p_stMUI -> dwOffSet > dwNextHeaderPos) { // fill to next Header Position DWORD dwSize = 0; while (dwOffSet < dwNextHeaderPos) { DWORD dwValue = PTC_fn_lGetRandom(); WriteFile (hFile , &dwValue , 4 , &dwWritten , NULL); dwOffSet += 4; dwSize += 4; } // write next Header DWORD dwKeys[4]; p_dwCurrentPos = (DWORD*)p_Buffer; // compute keys for (int i=0 ; i<4 ; i++ ) { dwKeys[i] = PTC_fn_lGetRandom(); *p_dwCurrentPos++ = dwKeys[i]; } // fill Debug File if (m_bGenerateInfoFiles && hDebugFile != INVALID_HANDLE_VALUE) { sprintf (szText , "==============================================================================\x0D\x0A"); WriteFile (hDebugFile , szText , strlen(szText) , &dwW , NULL); sprintf (szText , "OffSet : 0x%08x - Header %03d - crypt-key : 0x%08x - 0x%08x - 0x%08x - 0x%08x\x0D\x0A" , dwOffSet , _a_HITab [dwHeaderNumber] . dwOccur , dwKeys[0] , dwKeys[1] , dwKeys[2] , dwKeys[3]); WriteFile (hDebugFile , szText , strlen(szText) , &dwW , NULL); sprintf (szText , "==============================================================================\x0D\x0A"); WriteFile (hDebugFile , szText , strlen(szText) , &dwW , NULL); } // Write OffSet DWORD dwIndex = _a_HITab [dwHeaderNumber] . dwOccur; DWORD dwMyCount = 0; while (dwIndex < dwNumberOfMUI) { *p_dwCurrentPos++ = (a_OffSet [dwIndex] ^ dwKeys[1]) + dwKeys[0]; dwKeys[0] += dwKeys[2]; dwKeys[1] += dwKeys[3]; if (m_bGenerateInfoFiles && hDebugFile != INVALID_HANDLE_VALUE && !(dwMyCount % 4)) { sprintf (szText , "\t%03d - 0x%08x - 0x%08x - 0x%08x - 0x%08x\x0D\x0A" , dwMyCount / 4 , a_OffSet [dwIndex] , a_OffSet [dwIndex + p_stBFI -> dwNbOccur] , a_OffSet [dwIndex + p_stBFI -> dwNbOccur + p_stBFI -> dwNbOccur] , a_OffSet [dwIndex + p_stBFI -> dwNbOccur + p_stBFI -> dwNbOccur + p_stBFI -> dwNbOccur]); WriteFile (hDebugFile , szText , strlen(szText) , &dwW , NULL); } dwIndex += p_stBFI -> dwNbOccur; dwMyCount += 1; } if (m_bGenerateInfoFiles && hDebugFile != INVALID_HANDLE_VALUE) { sprintf (szText , "==============================================================================\x0D\x0A"); WriteFile (hDebugFile , szText , strlen(szText) , &dwW , NULL); } if (dwMyCount != p_stBFI -> dwNbFile) { m_csErrorMessage = "Bad Header Size"; return FALSE; } p_dwEndHeader = (DWORD*)(p_Buffer + p_stBFI -> dwHeaderSize); // align to Sector Size while (p_dwCurrentPos < p_dwEndHeader) { *p_dwCurrentPos++ = PTC_fn_lGetRandom(); } // write on file WriteFile (hFile , p_Buffer , p_stBFI -> dwHeaderSize , &dwWritten , NULL); m_Ctrl_ProgressBar . StepIt (); dwOffSet = dwNextHeaderPos + p_stBFI -> dwHeaderSize; // compute next Header pos dwHeaderNumber++; if (dwHeaderNumber < p_stBFI -> dwNbOccur) { dwNextHeaderPos = _a_HITab [dwHeaderNumber] . dwOffSet; } else { // no more header dwNextHeaderPos = 0xFFFFFFFF; } } } GlobalUnlock (hMem); GlobalFree (hMem); if (m_bGenerateInfoFiles && hDebugFile != INVALID_HANDLE_VALUE) CloseHandle (hDebugFile); m_Ctrl_ProgressBar . SetPos (0); free (a_OffSet); return TRUE; }