checked in package manager
This commit is contained in:
@@ -62,38 +62,49 @@ void RageBitmapTexture::Create()
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
///////////////////////
|
||||
// Figure out which texture format to use
|
||||
///////////////////////
|
||||
D3DFORMAT fmtTexture;
|
||||
if( !GAMEINFO )
|
||||
|
||||
// look in the file name for a hint
|
||||
m_sFilePath.MakeLower();
|
||||
if( -1 != m_sFilePath.Find("(no alpha)") )
|
||||
{
|
||||
fmtTexture = D3DFMT_R5G6B5;
|
||||
}
|
||||
else if( -1 != m_sFilePath.Find("(1 alpha)") )
|
||||
{
|
||||
fmtTexture = D3DFMT_A1R5G5B5;
|
||||
}
|
||||
else // no hint, assume full alpha
|
||||
{
|
||||
fmtTexture = D3DFMT_A4R4G4B4;
|
||||
}
|
||||
else if( GAMEINFO->m_GameOptions.m_iDisplayColor == 16 )
|
||||
|
||||
// if the user has requested high color textures, use the higher color
|
||||
if( GAMEINFO != NULL
|
||||
&& GAMEINFO->m_GameOptions.m_iDisplayColor == 32
|
||||
&& GAMEINFO->m_GameOptions.m_iTextureColor == 32 )
|
||||
{
|
||||
fmtTexture = D3DFMT_A4R4G4B4;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch( GAMEINFO->m_GameOptions.m_iTextureColor )
|
||||
{
|
||||
case 16: fmtTexture = D3DFMT_A4R4G4B4; break;
|
||||
case 32: fmtTexture = D3DFMT_A8R8G8B8; break;
|
||||
default: ASSERT( true ); // invalid iTextureColor value
|
||||
}
|
||||
fmtTexture = D3DFMT_A8R8G8B8;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// load texture and get image info
|
||||
D3DXIMAGE_INFO ddii;
|
||||
|
||||
// load texture
|
||||
if( FAILED( hr = D3DXCreateTextureFromFileEx(
|
||||
m_pd3dDevice, // device
|
||||
m_sFilePath, // soure file
|
||||
D3DX_DEFAULT, D3DX_DEFAULT, // width, height
|
||||
3, // mip map levels
|
||||
4, // mip map levels
|
||||
0, // usage (is a render target?)
|
||||
fmtTexture, // our preferred texture format
|
||||
fmtTexture, // our preferred texture format
|
||||
D3DPOOL_MANAGED, // which memory pool
|
||||
D3DX_FILTER_BOX | D3DX_FILTER_DITHER, // filter
|
||||
D3DX_FILTER_BOX | D3DX_FILTER_DITHER, // mip filter
|
||||
D3DX_FILTER_BOX, // filter
|
||||
D3DX_FILTER_BOX, // mip filter
|
||||
0, // no color key
|
||||
&ddii, // struct to fill with source image info
|
||||
NULL, // no palette
|
||||
|
||||
@@ -75,35 +75,32 @@ void RageTexture::CreateFrameRects()
|
||||
#include "string.h"
|
||||
void RageTexture::GetFrameDimensionsFromFileName( CString sPath, UINT* puFramesWide, UINT* puFramesHigh ) const
|
||||
{
|
||||
*puFramesWide = *puFramesHigh = 1; // initialize in case we don't find dimensions in the file name
|
||||
*puFramesWide = *puFramesHigh = 1; // set default values in case we don't find the dimension in the file name
|
||||
|
||||
sPath.MakeLower();
|
||||
|
||||
CString sDir, sFName, sExt;
|
||||
splitrelpath( sPath, sDir, sFName, sExt);
|
||||
|
||||
CStringArray sFileNameBits;
|
||||
split( sFName, " ", sFileNameBits, false );
|
||||
CStringArray arrayBits;
|
||||
split( sFName, " ", arrayBits, false );
|
||||
|
||||
if( sFileNameBits.GetSize() < 2 )
|
||||
return; // there can't be dimensions in the file name if there's no space
|
||||
|
||||
CString sDimensionsPart = sFileNameBits[ sFileNameBits.GetSize()-1 ]; // looks like "10x5"
|
||||
|
||||
CStringArray sDimensionsBits;
|
||||
split( sDimensionsPart, "x", sDimensionsBits, false );
|
||||
|
||||
if( sDimensionsBits.GetSize() != 2 )
|
||||
for( int i=0; i<arrayBits.GetSize(); i++ )
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( !IsAnInt(sDimensionsBits[0]) || !IsAnInt(sDimensionsBits[1]) )
|
||||
return;
|
||||
CString &sBit = arrayBits[ i ];
|
||||
|
||||
// Test to see if it looks like "%ux%u" (e.g. 16x8)
|
||||
|
||||
*puFramesWide = atoi(sDimensionsBits[0]);
|
||||
*puFramesHigh = atoi(sDimensionsBits[1]);
|
||||
CStringArray arrayDimensionsBits;
|
||||
split( sBit, "x", arrayDimensionsBits, false );
|
||||
|
||||
if( arrayDimensionsBits.GetSize() != 2 )
|
||||
continue;
|
||||
else if( !IsAnInt(arrayDimensionsBits[0]) || !IsAnInt(arrayDimensionsBits[1]) )
|
||||
continue;
|
||||
|
||||
*puFramesWide = atoi(arrayDimensionsBits[0]);
|
||||
*puFramesHigh = atoi(arrayDimensionsBits[1]);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -133,10 +133,10 @@ CString ThemeManager::GetPathTo( ThemeElement te, CString sThemeName )
|
||||
///////////////////////////////////////
|
||||
if( sAssetDir == "Graphics\\" )
|
||||
{
|
||||
GetDirListing( sThemeDir + sAssetDir + sAssetFileName + ".sprite", arrayPossibleElementFileNames );
|
||||
GetDirListing( sThemeDir + sAssetDir + sAssetFileName + ".png", arrayPossibleElementFileNames );
|
||||
GetDirListing( sThemeDir + sAssetDir + sAssetFileName + ".jpg", arrayPossibleElementFileNames );
|
||||
GetDirListing( sThemeDir + sAssetDir + sAssetFileName + ".bmp", arrayPossibleElementFileNames );
|
||||
GetDirListing( sThemeDir + sAssetDir + sAssetFileName + "*.sprite", arrayPossibleElementFileNames );
|
||||
GetDirListing( sThemeDir + sAssetDir + sAssetFileName + "*.png", arrayPossibleElementFileNames );
|
||||
GetDirListing( sThemeDir + sAssetDir + sAssetFileName + "*.jpg", arrayPossibleElementFileNames );
|
||||
GetDirListing( sThemeDir + sAssetDir + sAssetFileName + "*.bmp", arrayPossibleElementFileNames );
|
||||
}
|
||||
else if( sAssetDir == "Sounds\\" )
|
||||
{
|
||||
@@ -168,10 +168,10 @@ CString ThemeManager::GetPathTo( ThemeElement te, CString sThemeName )
|
||||
///////////////////////////////////////
|
||||
if( sAssetDir == "Graphics\\" )
|
||||
{
|
||||
GetDirListing( DEFAULT_THEME_DIR + sAssetDir + sAssetFileName + ".sprite", arrayPossibleElementFileNames );
|
||||
GetDirListing( DEFAULT_THEME_DIR + sAssetDir + sAssetFileName + ".png", arrayPossibleElementFileNames );
|
||||
GetDirListing( DEFAULT_THEME_DIR + sAssetDir + sAssetFileName + ".jpg", arrayPossibleElementFileNames );
|
||||
GetDirListing( DEFAULT_THEME_DIR + sAssetDir + sAssetFileName + ".bmp", arrayPossibleElementFileNames );
|
||||
GetDirListing( DEFAULT_THEME_DIR + sAssetDir + sAssetFileName + "*.sprite", arrayPossibleElementFileNames );
|
||||
GetDirListing( DEFAULT_THEME_DIR + sAssetDir + sAssetFileName + "*.png", arrayPossibleElementFileNames );
|
||||
GetDirListing( DEFAULT_THEME_DIR + sAssetDir + sAssetFileName + "*.jpg", arrayPossibleElementFileNames );
|
||||
GetDirListing( DEFAULT_THEME_DIR + sAssetDir + sAssetFileName + "*.bmp", arrayPossibleElementFileNames );
|
||||
}
|
||||
else if( sAssetDir == "Sounds\\" )
|
||||
{
|
||||
|
||||
@@ -0,0 +1,172 @@
|
||||
// SMPackageInstallDlg.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "smpackage.h"
|
||||
#include "SMPackageInstallDlg.h"
|
||||
#include "../RageUtil.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CSMPackageInstallDlg dialog
|
||||
|
||||
|
||||
CSMPackageInstallDlg::CSMPackageInstallDlg(CString sPackagePath, CWnd* pParent /*=NULL*/)
|
||||
: CDialog(CSMPackageInstallDlg::IDD, pParent)
|
||||
{
|
||||
//{{AFX_DATA_INIT(CSMPackageInstallDlg)
|
||||
// NOTE: the ClassWizard will add member initialization here
|
||||
//}}AFX_DATA_INIT
|
||||
|
||||
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
|
||||
|
||||
m_sPackagePath = sPackagePath;
|
||||
}
|
||||
|
||||
|
||||
void CSMPackageInstallDlg::DoDataExchange(CDataExchange* pDX)
|
||||
{
|
||||
CDialog::DoDataExchange(pDX);
|
||||
//{{AFX_DATA_MAP(CSMPackageInstallDlg)
|
||||
// NOTE: the ClassWizard will add DDX and DDV calls here
|
||||
//}}AFX_DATA_MAP
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(CSMPackageInstallDlg, CDialog)
|
||||
//{{AFX_MSG_MAP(CSMPackageInstallDlg)
|
||||
ON_WM_PAINT()
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CSMPackageInstallDlg message handlers
|
||||
|
||||
BOOL CSMPackageInstallDlg::OnInitDialog()
|
||||
{
|
||||
CDialog::OnInitDialog();
|
||||
|
||||
// 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
|
||||
|
||||
// TODO: Add extra initialization here
|
||||
|
||||
CString sMessage;
|
||||
sMessage += ssprintf(
|
||||
"You have chosen to install the Stepmania package:\r\n"
|
||||
"\t%s\r\n"
|
||||
"\r\n"
|
||||
"This package contains the following files:\r\n",
|
||||
m_sPackagePath
|
||||
);
|
||||
|
||||
// add all the files in the zip to the message
|
||||
try
|
||||
{
|
||||
m_zip.Open( m_sPackagePath );
|
||||
}
|
||||
catch (CException* e)
|
||||
{
|
||||
AfxMessageBox( ssprintf("'%s' is not a valid zip archive.", m_sPackagePath), MB_ICONSTOP );
|
||||
e->Delete();
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
for( int i=0; i<m_zip.GetNoEntries(); i++ )
|
||||
{
|
||||
if( m_zip.IsFileDirectory((WORD)i) )
|
||||
continue;
|
||||
|
||||
CZipFileHeader fh;
|
||||
m_zip.GetFileInfo(fh, (WORD)i);
|
||||
sMessage += ssprintf( "\to %s\r\n", fh.GetFileName() );
|
||||
}
|
||||
|
||||
TCHAR szCurrentDirectory[MAX_PATH];
|
||||
GetCurrentDirectory( MAX_PATH, szCurrentDirectory );
|
||||
sMessage += ssprintf(
|
||||
"\r\n"
|
||||
"The package will be installed in the Stepmania program folder:\r\n"
|
||||
"\t%s",
|
||||
szCurrentDirectory
|
||||
);
|
||||
|
||||
// Set the message
|
||||
CEdit* pEdit = (CEdit*)GetDlgItem(IDC_EDIT_MESSAGE);
|
||||
pEdit->SetWindowText( sMessage );
|
||||
|
||||
|
||||
|
||||
return TRUE; // return TRUE unless you set the focus to a control
|
||||
// EXCEPTION: OCX Property Pages should return FALSE
|
||||
}
|
||||
|
||||
|
||||
void CSMPackageInstallDlg::OnPaint()
|
||||
{
|
||||
CPaintDC dc(this); // device context for painting
|
||||
|
||||
// TODO: Add your message handler code here
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CSMPackageInstallDlg::OnOK()
|
||||
{
|
||||
// TODO: Add extra validation here
|
||||
|
||||
TCHAR szCurrentDirectory[MAX_PATH];
|
||||
GetCurrentDirectory( MAX_PATH, szCurrentDirectory );
|
||||
|
||||
// Unzip the SMzip package into the Stepmania installation folder
|
||||
for( int i=0; i<m_zip.GetNoEntries(); i++ )
|
||||
{
|
||||
CZipFileHeader fh;
|
||||
m_zip.GetFileInfo(fh, (WORD)i);
|
||||
//AfxMessageBox( ssprintf( "Trying to extract '%s'", fh.GetFileName()) );
|
||||
|
||||
try
|
||||
{
|
||||
m_zip.ExtractFile( (WORD)i, szCurrentDirectory, true ); // extract file to current directory
|
||||
}
|
||||
catch (CException* e)
|
||||
{
|
||||
AfxMessageBox( "Error extracting files", MB_ICONSTOP );
|
||||
e->Delete();
|
||||
exit( 1 );
|
||||
}
|
||||
}
|
||||
|
||||
AfxMessageBox( "Package installed successfully!" );
|
||||
|
||||
// close the dialog
|
||||
CDialog::OnOK();
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
#if !defined(AFX_SMPACKAGEINSTALLDLG_H__5E362C4C_CA11_4071_A8AB_A0231E985DAF__INCLUDED_)
|
||||
#define AFX_SMPACKAGEINSTALLDLG_H__5E362C4C_CA11_4071_A8AB_A0231E985DAF__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
// SMPackageInstallDlg.h : header file
|
||||
//
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CSMPackageInstallDlg dialog
|
||||
|
||||
#include "ZipArchive\ZipArchive.h"
|
||||
|
||||
|
||||
class CSMPackageInstallDlg : public CDialog
|
||||
{
|
||||
// Construction
|
||||
public:
|
||||
CSMPackageInstallDlg(CString sPackagePath, CWnd* pParent = NULL); // standard constructor
|
||||
|
||||
// Dialog Data
|
||||
//{{AFX_DATA(CSMPackageInstallDlg)
|
||||
enum { IDD = IDD_INSTALL };
|
||||
// NOTE: the ClassWizard will add data members here
|
||||
//}}AFX_DATA
|
||||
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(CSMPackageInstallDlg)
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
HICON m_hIcon;
|
||||
CString m_sPackagePath;
|
||||
CZipArchive m_zip;
|
||||
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(CSMPackageInstallDlg)
|
||||
virtual BOOL OnInitDialog();
|
||||
virtual void OnOK();
|
||||
afx_msg void OnPaint();
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
};
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_SMPACKAGEINSTALLDLG_H__5E362C4C_CA11_4071_A8AB_A0231E985DAF__INCLUDED_)
|
||||
@@ -0,0 +1,8 @@
|
||||
// stdafx.cpp : source file that includes just the standard includes
|
||||
// smpackage.pch will be the pre-compiled header
|
||||
// stdafx.obj will contain the pre-compiled type information
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
// stdafx.h : include file for standard system include files,
|
||||
// or project specific include files that are used frequently, but
|
||||
// are changed infrequently
|
||||
//
|
||||
|
||||
#if !defined(AFX_STDAFX_H__D450D5ED_5C49_4A8B_B887_076F62424F1F__INCLUDED_)
|
||||
#define AFX_STDAFX_H__D450D5ED_5C49_4A8B_B887_076F62424F1F__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
|
||||
#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers
|
||||
|
||||
#include <afxwin.h> // MFC core and standard components
|
||||
#include <afxext.h> // MFC extensions
|
||||
#include <afxdtctl.h> // MFC support for Internet Explorer 4 Common Controls
|
||||
#ifndef _AFX_NO_AFXCMN_SUPPORT
|
||||
#include <afxcmn.h> // MFC support for Windows Common Controls
|
||||
#endif // _AFX_NO_AFXCMN_SUPPORT
|
||||
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_STDAFX_H__D450D5ED_5C49_4A8B_B887_076F62424F1F__INCLUDED_)
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,380 @@
|
||||
<!-- The Code Project article submission template (HTML version)
|
||||
|
||||
Using this template will help us post your article sooner. We are using MS
|
||||
IIS and ASP pages on the server, allowing us to simplify the templates used
|
||||
to create the articles.
|
||||
|
||||
To fill in this template, just follow the 3 easy steps below:
|
||||
|
||||
1. Fill in the article description details
|
||||
2. Add links to your images and downloads
|
||||
3. Include the main article text
|
||||
|
||||
That's all there is to it! All formatting will be done by the ASP script
|
||||
engine.
|
||||
-->
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>The Code Project</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<style>
|
||||
BODY { FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif; FONT-SIZE: 10pt }
|
||||
H2 { COLOR: #0066ff; FONT-SIZE: 13pt; FONT-WEIGHT: bold; }
|
||||
H3 { COLOR: #0066ff; FONT-SIZE: 12pt; FONT-WEIGHT: bold; font-style: italic; }
|
||||
H3 { COLOR: #0066ff; FONT-SIZE: 11pt; FONT-WEIGHT: bold; }
|
||||
PRE { BACKGROUND-COLOR: #FBEDBB; FONT-FAMILY: "Courier New", Courier, mono; WHITE-SPACE: pre; }
|
||||
CODE { COLOR: #990000; FONT-FAMILY: "Courier New", Courier, mono; }
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body bgcolor="#FFFFFF" color="#000000">
|
||||
<!-- STEP 1. Fill in the details (CodeProject will reformat this section for you) -->
|
||||
|
||||
<pre>
|
||||
Title: Zip and Unzip in the MFC way
|
||||
Author: Tadeusz Dracz
|
||||
Email: [email protected]
|
||||
Environment: VC++ 6.0, MFC, Windows 95/98/NT/2000/Me
|
||||
Keywords: Zip, Unzip, MFC
|
||||
Level: Intermediate
|
||||
Description: The library to create, modify and extract zip archives
|
||||
Section Miscellaneous
|
||||
SubSection General
|
||||
</pre>
|
||||
|
||||
<hr width="100%" noshade>
|
||||
<!-- STEP 2. Include download and sample image information -->
|
||||
|
||||
<ul>
|
||||
<li class="download"><a href="zip_src.zip">Download source - 110 Kb</a></li>
|
||||
<li class="download"><a href="zip_demo.zip">Download demo project - 40 Kb</a></li>
|
||||
<h2>Overview</h2>
|
||||
<p>This library allows creating, modifying and extracting zip archives in the
|
||||
compatible way with PKZIP (2.5 and higher) and WinZip. Supported are all
|
||||
possible operations on the zip archive: creating, extracting, adding, deleting
|
||||
files from the archive, modifications of the existing archive. There is also the
|
||||
support for creating and extracting multiple disk archives (on non-removable
|
||||
devices as well) and for password encryption and decryption. This module uses
|
||||
compression and decompression functions from zlib library by Jean-loup Gailly
|
||||
and Mark Adler.</p>
|
||||
<h2>How to integrate with the project</h2>
|
||||
<p>Zip is a static library and statically links to compiled zlib.lib (version
|
||||
1.13 nowadays). The zlib library can be replaced with a newer version providing
|
||||
you also replace the files: "zlib.h" and "zconf.h" in the
|
||||
Zip project. The Zip library uses MFC in a shared library as a Release and Debug
|
||||
Configuration. Your project must use MFC in the same way in the appropriate
|
||||
project configuration. You may need to adapt this to your needs. To add Zip
|
||||
library functionality to your project you need to link the library to the
|
||||
project. You can do this in at least two ways (in both cases you need to include
|
||||
ZipArchive.h header in your sources like this: #include "ZipArchive.h"):</p>
|
||||
<h4>Method 1</h4>
|
||||
<p>Add "..\Zip\debug(release)\Zip.lib" to <em>Project
|
||||
Settings->Link->Input->Object/library modules</em> and add Zip
|
||||
directory to the preprocessor searches (<em>Project Settings -> C++ ->
|
||||
Preprocessor -> Additional include directories</em>).</p>
|
||||
<h4>Method 2 (simpler)</h4>
|
||||
<p>Insert Zip project into workspace and set project dependencies (your project
|
||||
dependent on Zip project).</p>
|
||||
<h2>How to use</h2>
|
||||
<p>The details about using this library are in the sources. The example
|
||||
available for download at the bottom of the page is an almost complete
|
||||
compression\decompression program. There are only main issues mentioned below
|
||||
about using this library. If you have a question about using the library and you
|
||||
can't find the answer here, don't hesitate to ask.</p>
|
||||
<h3>Compression and decompression</h3>
|
||||
<p>There are some functions defined for fast operations on archive; among
|
||||
others: AddNewFile(), ExtractFile(), DeleteFile(). You only need to call
|
||||
functions Open() - before and Close() - after using them.<br>
|
||||
Remember to call Close() function when you finish working with CZipArchive
|
||||
class.</p>
|
||||
<h3>Multi-disk archives</h3>
|
||||
<p>This library supports two kinds of multi-disk archives:<br>
|
||||
1. Disk spanning performed in the compatible way with all other main zip
|
||||
programs. It means that the archive can only be created on a removable device,
|
||||
the size of the volume is auto-detected and the label is written to the disk. To
|
||||
use this kind of disk spanning you need to define a static callback function for
|
||||
changing disks and set it with SetSpanCallback() function.<br>
|
||||
2. Disk spanning performed in the internal mode, called in the sources TD span
|
||||
mode. This allows creating multi disk archives also on non-removable devices and
|
||||
with user-defined volume size. There is no need to set callback function in this
|
||||
mode.</p>
|
||||
<p>This two disk spanning modes create volumes with compatible internal
|
||||
structure. It means that you can easily convert the volumes created in one mode
|
||||
to the other one by renaming the files (in TD mode each volume but last has a
|
||||
number as an extension). To convert the archive from TD to PKZIP compatible
|
||||
archive, copy each file to the removable media, giving them the extension
|
||||
".zip". You should also label each disk with the appropriate label
|
||||
starting from "pkback# 001".</p>
|
||||
<p>There is a limited functions set available during work with multi-disk
|
||||
archives. Only adding is allowed when creating an archive and only extracting
|
||||
and testing when opening an existing one. Deleting files from these archives
|
||||
isn't allowed in any of these cases.</p>
|
||||
<p>Class CZipArchive uses write buffer to make write operations extremely fast.
|
||||
You can change its size with SetAdvanced() function. While creating a multi-disk
|
||||
archive, set the size of the buffer to the maximum size of the volume for
|
||||
the best performance.</p>
|
||||
<p>The popular archivers such as PKZIP and WinZip cannot operate on archive in
|
||||
TD span mode. You need to convert them to PKZIP span mode (have a look above).
|
||||
Remember about copying the files to the removable media (it does not comply with
|
||||
Winzip, which can extract a multi-disk archive from any media but only from the
|
||||
fixed location on the drive).</p>
|
||||
<h3>Password encryption and decryption</h3>
|
||||
<p> This library supports creating and extracting of the
|
||||
password protected archives. There are several issues you should be aware of
|
||||
when using this feature. To set the password for the file to be added or
|
||||
extracted call the function SetPassword() with the password as the argument. To
|
||||
clear the password call this function without arguments or with an empty string
|
||||
argument. The function has no effect on a closed archive and on the currently
|
||||
opened file (whether new or existing) inside archive. During opening an archive
|
||||
the password is cleared and it is not changed if the file inside archive is
|
||||
opened. You can set different passwords for different files inside the same
|
||||
archive, but remember to set it BEFORE opening the file. You cannot use ASCII
|
||||
characters with codes above 127 in a password, if you do so, the function
|
||||
SetPassword() returns false and the password is cleared. If the password is
|
||||
cleared, no encryption or decryption take place.<br>
|
||||
You can find out what files are password encrypted by calling
|
||||
CZipArchive::GetFileInfo() which fills the structrure CZipFileHeader with data,
|
||||
and then the method IsEncrypted() of this structure. If it returns true, the
|
||||
file needs a password to extract.<br>
|
||||
The successful extraction of the encrypted file doesn't always mean
|
||||
that the password is correct. CZipArchive doesn't check for a crc if
|
||||
m_info.m_uUncomprLeft is not zero in the function CZipArchive::CloseFile(). In
|
||||
some cases bad password causes that this value is not zero, so you have to check
|
||||
also for the return value of this function (it returns -1 in this case). You can
|
||||
also check the size of the extracted file since it is smaller than it should be.</p>
|
||||
<h3>Self extract support</h3>
|
||||
<p>The library automatically detects self-extracting archives. This is the
|
||||
simplest self-extract code :</p>
|
||||
<!-- start a block of source code -->
|
||||
<pre>
|
||||
int APIENTRY WinMain(HINSTANCE hInstance,
|
||||
HINSTANCE hPrevInstance,
|
||||
LPSTR lpCmdLine,
|
||||
int nCmdShow)
|
||||
{
|
||||
CZipArchive zip;
|
||||
|
||||
// get path of executable
|
||||
TCHAR szBuff[_MAX_PATH];
|
||||
if (!::GetModuleFileName(hInstance, szBuff, _MAX_PATH))
|
||||
return -1;
|
||||
|
||||
CString szDest;
|
||||
// ...
|
||||
// add the code here to get the destination directory from the user
|
||||
// for example:
|
||||
/* CBrowseForFolder bf;
|
||||
bf.strTitle = _T("Select directory to extract files");
|
||||
if (!bf.GetFolder(szDest))
|
||||
return -1;
|
||||
*/
|
||||
// class CBrowseForFolder is included in the example project
|
||||
// remember about including the header!
|
||||
|
||||
zip.Open(szBuff, CZipArchive::openReadOnly);
|
||||
// openReadOnly mode is necessary for self extract archives
|
||||
for (WORD i = 0; i < zip.GetNoEntries(); i++)
|
||||
zip.ExtractFile(i, szDest);
|
||||
|
||||
zip.Close();
|
||||
return 0;
|
||||
// this code will not work for the encrypted archives since it is needed
|
||||
// to get the password from the user ( a small addition to the
|
||||
// existing code I suppose )
|
||||
}
|
||||
<!-- end the block of source code -->
|
||||
|
||||
</pre>
|
||||
<p>After compiling it and appending a zip archive to it (e.g. with the DOS
|
||||
command: <em>copy /b SelfExtract.exe + ZipFile.zip FinalFile.exe</em>) we have a
|
||||
self extracting archive.</p>
|
||||
<h3>Testing the integrity of the archive</h3>
|
||||
<p>The new functions has been provided to allow the testing of the integrity of
|
||||
the archive. The first one is <em>CZipArchive::TestFile </em>which is a
|
||||
comprehensive testing function, but if you need a different functionality, you
|
||||
can make your own by taking advantage of the second function provided: <em>CZipArchive::CloseFileAfterTestFailed.
|
||||
</em>The detailed description and the example of use are provided in the sources
|
||||
and in the example project.</p>
|
||||
<h3>Exceptions</h3>
|
||||
<p>The library throws the following exceptions: CMemoryException, CFileExeption
|
||||
and CZipException. The first two don't need an explanation. The last is thrown
|
||||
when some internal error occurs. Handling them may be done in the following way:</p>
|
||||
<pre>
|
||||
try
|
||||
{
|
||||
// ...
|
||||
// some operations on Zip library
|
||||
}
|
||||
catch (CException* e)
|
||||
{
|
||||
if (e->IsKindOf( RUNTIME_CLASS( CZipException )))
|
||||
{
|
||||
CZipException* p = (CZipException*) e;
|
||||
//... and so on
|
||||
}
|
||||
else if (e->IsKindOf( RUNTIME_CLASS( CFileException )))
|
||||
{
|
||||
CFileException* p = (CFileException*) e;
|
||||
//... and so on
|
||||
}
|
||||
else
|
||||
{
|
||||
// the only possibility is a memory exception I suppose
|
||||
//... and so on
|
||||
}
|
||||
e->Delete();
|
||||
}
|
||||
</pre>
|
||||
<h3>Handling the extra field</h3>
|
||||
<p>The extra field of the file can be different in the local and central
|
||||
headers. To set the extra filed in the local header set it in <em>header</em>
|
||||
parameter of <font size="3"><em>CZipArchive::OpenNewFile </em>function<em>. </em>After
|
||||
that the extra field is written to the local header and cleared. You should call
|
||||
<em>CZipArchive::SetExtraField </em>function anytime after opening the new file
|
||||
(but before closing it) to set the file extra field in the central directory.</font></p>
|
||||
<h3>Sample application</h3>
|
||||
<p>To run the example, integrate first Zip library into it (Zip library is not
|
||||
included in the example, you must download it separately); you should be asked
|
||||
at the beginning about the location of the Zip project, if not, use one of the
|
||||
integration methods described above. If you don't put Zip library project at the
|
||||
same directory level what the sample application is, you also have to change the path pointing
|
||||
to ZipArchive.h in the file testzipdlgdlg.h.</p>
|
||||
<h3>Linking errors</h3>
|
||||
<p>When you experience linking errors (mostly <em>LNK2005)</em> you need to
|
||||
make sure that the library and your program are both using
|
||||
single-threaded or both multithreaded library. The option <em>"Project->Settings->
|
||||
c/c++ ->Code Generation->Use run-time library" </em>should be set
|
||||
to the same value in the ZipArchive library and the program project options.
|
||||
<p>If it doesn't help, try recompiling the zlib library ( <em>zlib.lib</em>
|
||||
provided with the project is compiled from a release configuration and using <font SIZE="2">Multithreaded</font>
|
||||
DLL run-time library ). You can download the zlib library
|
||||
sources from <a href="http://software.artpol.com.pl/d_zip.html.">http://software.artpol.com.pl/d_zip.html.</a>
|
||||
Use <em>zlibstat</em> project. Set <em>"Use run-time library"</em>
|
||||
option to the same value as you set it in ZipArchve library and your program
|
||||
configurations. Compile the Release configuration of the zlib library and
|
||||
replace with it the file <em>zlib.lib</em> in the ZipArchive folder. You may
|
||||
however experience linking warnings or errors while compiling the Debug
|
||||
configuration. To eliminate them do as follows:
|
||||
<ul>
|
||||
<li>compile Debug and Release configuraions of the zlib library
|
||||
<li>copy <em>zlib_d.lib</em> from Debug and <em>zlib.lib</em> from Release
|
||||
directories to the ZipArchive directory
|
||||
<li>add these files to the ZipArchive project <em>(Project -> Add To
|
||||
Project -> Files...)</em>
|
||||
<li>go to the project setting dialog <em>(Project -> Settings)</em>
|
||||
<li>select debug configurations <em>(Setting For -> Multiple
|
||||
Configurations)</em> such as Debug and Unicode Debug
|
||||
<li>select <em>zlib.lib</em> file, then the General tab, and check the box <em>"Exclude
|
||||
file from build"</em>
|
||||
<li>select release configurations
|
||||
<li>select <em>zlib_.lib</em> and exclude it from these builds</li>
|
||||
</ul>
|
||||
<p> </p>
|
||||
<h2>To Do and updates</h2>
|
||||
<p>I currently work on the non-MFC version of the library and a multi-platform
|
||||
support. Make sure to check out the site <a href="http://software.artpol.com.pl">http://software.artpol.com.pl</a>
|
||||
which is more likely to have an updated version. </p>
|
||||
<h2>Downloads</h2>
|
||||
<!-- demo and source files -->
|
||||
<a HREF="file:///E:/b/ZipArchive/zip_src.zip">
|
||||
<p>Download source - 110 KB</a><br>
|
||||
<a href="file:///E:/b/ZipArchive/zip_demo.zip">Download example - 40 KB</a></p>
|
||||
<h2>History</h2>
|
||||
<p><b>03.2001</b></p>
|
||||
<ul>
|
||||
<li>when the central directory was not located, the library throws
|
||||
CZipException::cdirNotFound,<br>
|
||||
which allows distinguish from other exceptions (useful when we want to keep
|
||||
prompting<br>
|
||||
the user to insert the last disk in a multi-disk spanning archive).</li>
|
||||
</ul>
|
||||
</ul>
|
||||
<p> </p>
|
||||
|
||||
<ul>
|
||||
<b>02.2001</b>
|
||||
<dl compact>
|
||||
<dt><b>Features added:</b>
|
||||
<dd>
|
||||
<ul>
|
||||
<li>ability to reuse the archive after an exception thrown during
|
||||
extraction
|
||||
<li>added progress control possibilities to CZipArchive::AddNewFile,
|
||||
CZipArchive::ExtractFile, CZipArchive::TestFile</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl compact>
|
||||
<dt><b>Changes:</b>
|
||||
<dd>
|
||||
<ul>
|
||||
<li>CZipArchive::FindFile operation boosted ( thanks to Darin Warling for
|
||||
the idea)
|
||||
<li>library name changed to ZipArchive</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl compact>
|
||||
<dt><b>Bugs fixed:</b>
|
||||
<dd>
|
||||
<ul>
|
||||
<li>removed bug during extracting an encrypted file with 0 size
|
||||
<li>fixed bug when extracting a file with an extra field in a local file
|
||||
header (CZipFileHeader::ReadLocal)</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
<b>01.2001</b>
|
||||
<ul>
|
||||
<li>Disk numbering in a disk spanning archive begins now from PKBACK# 001 not
|
||||
PKBACK# 000
|
||||
<li>Adding and extracting without a full path possible in
|
||||
CZipArchive::AddNewFile and CZipArchive::ExtractFile.
|
||||
<li>Several minor changes and enhancements
|
||||
<li>Changed names for several classes.</li>
|
||||
</ul>
|
||||
<b>11.2000</b>
|
||||
<ul>
|
||||
<li>Added support for password encryption and decryption. The encryption used
|
||||
in PKZIP was generously supplied by Roger Schlafly.
|
||||
<li>Testing the archive made easier
|
||||
<li>Unicode support added</li>
|
||||
</ul>
|
||||
<b>08.2000</b>
|
||||
<ul>
|
||||
<li>Bugs fixed</li>
|
||||
</ul>
|
||||
<b>06.2000</b>
|
||||
<p>the code has been completely rewritten since the very beginning; the main
|
||||
improvements are:
|
||||
<ul>
|
||||
<li>multi-disk archive support
|
||||
<li>creation of the disk spanning archives with the user-defined volume size
|
||||
<li>ability to modify existing archives (add, delete files)
|
||||
<li>modification self-extracting archives
|
||||
<li>write buffer used for faster disk write operations
|
||||
<li>one class for zip and unzip functions
|
||||
<li>fast adding, deleting and extracting files with a single function call</li>
|
||||
</ul>
|
||||
<b>03.2000</b>
|
||||
<ul>
|
||||
<li>international characters in filenames inside archive are now converted in
|
||||
a compatible way with other archiving programs (they are stored converted to
|
||||
OEM inside archive).</li>
|
||||
</ul>
|
||||
<b>01.2000</b>
|
||||
<p>first version; it is just modified code from zip.c and unzip.c files written
|
||||
by Gilles Vollant and distributed with zlib library; the modifications are as
|
||||
follows:
|
||||
<ul>
|
||||
<li>added class' wrappers
|
||||
<li>several bugs fixed
|
||||
<li>several enhancements added
|
||||
<li>MFC support added
|
||||
<li>memory leaks eliminated when write error occurred
|
||||
<li>automatically free used memory on destruction or exception
|
||||
<li>modern error notification using exceptions</li>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,6 @@
|
||||
// stdafx.cpp : source file that includes just the standard includes
|
||||
// Zip.pch will be the pre-compiled header
|
||||
// stdafx.obj will contain the pre-compiled type information
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
// stdafx.h : include file for standard system include files,
|
||||
// or project specific include files that are used frequently, but
|
||||
// are changed infrequently
|
||||
//
|
||||
|
||||
#if !defined(AFX_STDAFX_H__926F70F4_1B34_49AA_9532_498E8D2F3495__INCLUDED_)
|
||||
#define AFX_STDAFX_H__926F70F4_1B34_49AA_9532_498E8D2F3495__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
|
||||
#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers
|
||||
|
||||
#include <afx.h>
|
||||
#include <afxwin.h>
|
||||
|
||||
// TODO: reference additional headers your program requires here
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_STDAFX_H__926F70F4_1B34_49AA_9532_498E8D2F3495__INCLUDED_)
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,283 @@
|
||||
# Microsoft Developer Studio Project File - Name="ZipArchive" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Static Library" 0x0104
|
||||
|
||||
CFG=ZipArchive - Win32 Unicode Debug
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "ZipArchive.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "ZipArchive.mak" CFG="ZipArchive - Win32 Unicode Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "ZipArchive - Win32 Release" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE "ZipArchive - Win32 Debug" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE "ZipArchive - Win32 Static Release" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE "ZipArchive - Win32 Unicode Debug" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE "ZipArchive - Win32 Unicode Release" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE "ZipArchive - Win32 Unicode Static Release" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "ZipArchive - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 2
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 2
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_AFXDLL" /Yu"stdafx.h" /FD /c
|
||||
# ADD CPP /nologo /MD /W4 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "ZLIB_DLL" /D "_AFXDLL" /Yu"stdafx.h" /FD /c
|
||||
# ADD BASE RSC /l 0x415 /d "NDEBUG" /d "_AFXDLL"
|
||||
# ADD RSC /l 0x415 /d "NDEBUG" /d "_AFXDLL"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LIB32=link.exe -lib
|
||||
# ADD BASE LIB32 /nologo
|
||||
# ADD LIB32 /nologo
|
||||
|
||||
!ELSEIF "$(CFG)" == "ZipArchive - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 2
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 2
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /Yu"stdafx.h" /FD /GZ /c
|
||||
# ADD CPP /nologo /MDd /W4 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "ZLIB_DLL" /D "_AFXDLL" /Fr /Yu"stdafx.h" /FD /GZ /c
|
||||
# ADD BASE RSC /l 0x415 /d "_DEBUG" /d "_AFXDLL"
|
||||
# ADD RSC /l 0x415 /d "_DEBUG" /d "_AFXDLL"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LIB32=link.exe -lib
|
||||
# ADD BASE LIB32 /nologo
|
||||
# ADD LIB32 /nologo
|
||||
|
||||
!ELSEIF "$(CFG)" == "ZipArchive - Win32 Static Release"
|
||||
|
||||
# PROP BASE Use_MFC 2
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Zip___Win32_Static_Release"
|
||||
# PROP BASE Intermediate_Dir "Zip___Win32_Static_Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 1
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Static_Release"
|
||||
# PROP Intermediate_Dir "Static_Release"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "ZLIB_DLL" /D "_AFXDLL" /Yu"stdafx.h" /FD /c
|
||||
# ADD CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "ZLIB_DLL" /Yu"stdafx.h" /FD /c
|
||||
# ADD BASE RSC /l 0x415 /d "NDEBUG" /d "_AFXDLL"
|
||||
# ADD RSC /l 0x415 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LIB32=link.exe -lib
|
||||
# ADD BASE LIB32 /nologo
|
||||
# ADD LIB32 /nologo
|
||||
|
||||
!ELSEIF "$(CFG)" == "ZipArchive - Win32 Unicode Debug"
|
||||
|
||||
# PROP BASE Use_MFC 2
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Zip___Win32_Unicode_Debug"
|
||||
# PROP BASE Intermediate_Dir "Zip___Win32_Unicode_Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 2
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Unicode_Debug"
|
||||
# PROP Intermediate_Dir "Unicode_Debug"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MDd /W4 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /D "ZLIB_DLL" /Fr /Yu"stdafx.h" /FD /GZ /c
|
||||
# ADD CPP /nologo /MDd /W4 /Gm /GX /ZI /Od /D "ZLIB_DLL" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /D "_UNICODE" /Fr /Yu"stdafx.h" /FD /GZ /c
|
||||
# ADD BASE RSC /l 0x415 /d "_DEBUG" /d "_AFXDLL"
|
||||
# ADD RSC /l 0x415 /d "_DEBUG" /d "_AFXDLL"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LIB32=link.exe -lib
|
||||
# ADD BASE LIB32 /nologo
|
||||
# ADD LIB32 /nologo
|
||||
|
||||
!ELSEIF "$(CFG)" == "ZipArchive - Win32 Unicode Release"
|
||||
|
||||
# PROP BASE Use_MFC 2
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Zip___Win32_Unicode_Release"
|
||||
# PROP BASE Intermediate_Dir "Zip___Win32_Unicode_Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 2
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Unicode_Release"
|
||||
# PROP Intermediate_Dir "Unicode_Release"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MD /W4 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "ZLIB_DLL" /D "_AFXDLL" /Yu"stdafx.h" /FD /c
|
||||
# ADD CPP /nologo /MD /W4 /GX /O2 /D "ZLIB_DLL" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_AFXDLL" /D "_UNICODE" /Yu"stdafx.h" /FD /c
|
||||
# ADD BASE RSC /l 0x415 /d "NDEBUG" /d "_AFXDLL"
|
||||
# ADD RSC /l 0x415 /d "NDEBUG" /d "_AFXDLL"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LIB32=link.exe -lib
|
||||
# ADD BASE LIB32 /nologo
|
||||
# ADD LIB32 /nologo
|
||||
|
||||
!ELSEIF "$(CFG)" == "ZipArchive - Win32 Unicode Static Release"
|
||||
|
||||
# PROP BASE Use_MFC 1
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Zip___Win32_Unicode_Static_Release"
|
||||
# PROP BASE Intermediate_Dir "Zip___Win32_Unicode_Static_Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 1
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Unicode_Static_Release"
|
||||
# PROP Intermediate_Dir "Unicode_Static_Release"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "ZLIB_DLL" /Yu"stdafx.h" /FD /c
|
||||
# ADD CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "ZLIB_DLL" /D "_UNICODE" /Yu"stdafx.h" /FD /c
|
||||
# ADD BASE RSC /l 0x415 /d "NDEBUG"
|
||||
# ADD RSC /l 0x415 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LIB32=link.exe -lib
|
||||
# ADD BASE LIB32 /nologo
|
||||
# ADD LIB32 /nologo
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "ZipArchive - Win32 Release"
|
||||
# Name "ZipArchive - Win32 Debug"
|
||||
# Name "ZipArchive - Win32 Static Release"
|
||||
# Name "ZipArchive - Win32 Unicode Debug"
|
||||
# Name "ZipArchive - Win32 Unicode Release"
|
||||
# Name "ZipArchive - Win32 Unicode Static Release"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\StdAfx.cpp
|
||||
# ADD CPP /Yc"stdafx.h"
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ZipArchive.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ZipAutoBuffer.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ZipBigFile.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ZipCentralDir.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ZipException.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ZipFileHeader.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ZipInternalInfo.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ZipStorage.cpp
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\StdAfx.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zconf.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ZipArchive.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ZipAutoBuffer.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ZipBigFile.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ZipCentralDir.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ZipException.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ZipFileHeader.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ZipInternalInfo.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ZipStorage.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Appnote.txt
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zlib.lib
|
||||
# End Source File
|
||||
# End Target
|
||||
# End Project
|
||||
# Section ZipArchive : {427B9281-D5E8-11D3-B7C7-E75054E13747}
|
||||
# 2:12:AutoBuffer.h:AutoBuffer.h
|
||||
# 2:18:CLASS: CAutoBuffer:CAutoBuffer
|
||||
# 2:19:Application Include:Zip.h
|
||||
# 2:14:AutoBuffer.cpp:AutoBuffer.cpp
|
||||
# End Section
|
||||
@@ -0,0 +1,29 @@
|
||||
Microsoft Developer Studio Workspace File, Format Version 6.00
|
||||
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "ZipArchive"=.\ZipArchive.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Global:
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<3>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
@@ -0,0 +1,698 @@
|
||||
// ZipArchive.h: interface for the CZipArchive class.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// ZipArchive 1.5.1, March 2001
|
||||
//
|
||||
//
|
||||
// This library allows to crate ZIP files in the compatible way with
|
||||
// PKZIP version 2.6. Some important issues:
|
||||
// - multiple disk spanning is supported
|
||||
// - encyption is not supported
|
||||
// - allows to create disk spanning archive also on non removable devices
|
||||
// and with user-defined volume size
|
||||
// - this library uses the zlib library by Jean-loup Gailly and Mark Adler
|
||||
// to perform inflate, deflate operations
|
||||
//
|
||||
//
|
||||
//
|
||||
// Copyright (C) 2000 - 2001 Tadeusz Dracz
|
||||
//
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose
|
||||
// and to alter it and redistribute it freely, subject to the
|
||||
// following restrictions:
|
||||
//
|
||||
// 1. Using this software in commercial applications requires an author permission.
|
||||
// The permission will be granted to everyone excluding the cases when
|
||||
// someone simply tries to resell the code.
|
||||
//
|
||||
// 2. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would be
|
||||
// appreciated but is not required.
|
||||
//
|
||||
// 3. Altered source versions must be plainly marked as such, and must not be
|
||||
// misrepresented as being the original software.
|
||||
//
|
||||
// 4. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
//
|
||||
// You can contact me at:
|
||||
// [email protected]
|
||||
//
|
||||
// For new versions check the site:
|
||||
// http://software.artpol.com.pl
|
||||
//
|
||||
// History:
|
||||
// 03.2001
|
||||
//
|
||||
// - when the central directory was not located, the library throws CZipException::cdirNotFound,
|
||||
// which allows distinguish from other exceptions (useful when we want to keep prompting
|
||||
// the user to insert the last disk in a multi-disk spanning archive).
|
||||
//
|
||||
//
|
||||
// 02.2001
|
||||
// Features added:
|
||||
// - ability to reuse the archive after an exception thrown during extraction
|
||||
// - added progress control possibilities to CZipArchive::AddNewFile, CZipArchive::ExtractFile, CZipArchive::TestFile
|
||||
// Changes:
|
||||
// - CZipArchive::FindFile operation boosted ( thanks to Darin Warling for the idea)
|
||||
// - library name changed to ZipArchive
|
||||
// Bugs fixed:
|
||||
// - removed bug during extracting an encrypted file with 0 size
|
||||
// - fixed bug when extracting a file with an extra field in a local file header (CZipFileHeader::ReadLocal)
|
||||
//
|
||||
// 01.2001
|
||||
// - Disk numbering in a disk spanning archive begins now from PKBACK# 001 not PKBACK# 000
|
||||
// - Adding and extracting without a full path possible in CZipArchive::AddNewFile and CZipArchive::ExtractFile.
|
||||
// - Several minor changes and enhancements
|
||||
// - Changed names for several classes.
|
||||
//
|
||||
// 11.2000
|
||||
// - Added support for password encryption and decryption.
|
||||
// The encryption used in PKZIP was generously supplied by Roger
|
||||
// Schlafly.
|
||||
// - Testing the archive made easier
|
||||
// - Unicode support added
|
||||
//
|
||||
// 08.2000
|
||||
// - Bugs fixed
|
||||
//
|
||||
// 06.2000
|
||||
//
|
||||
// the code has been completely rewritten since the very beginning;
|
||||
// the main improvements are:
|
||||
// - multi-disk archive support
|
||||
// - creation of the disk spanning archives with the user-defined volume size
|
||||
// - ability to modify existing archives (add, delete files)
|
||||
// - modification self-extracting archives
|
||||
// - write buffer used for faster disk write operations
|
||||
// - one class for zip and unzip functions
|
||||
// - fast adding, deleting and extracting files with a single function call
|
||||
//
|
||||
// 03.2000
|
||||
// - international characters in filenames inside archive are now
|
||||
// converted in a compatible way with other archiving programs (they are stored
|
||||
// converted to OEM inside archive).
|
||||
//
|
||||
// 01.2000
|
||||
//
|
||||
// first version; it is just modified code from zip.c and unzip.c files
|
||||
// written by Gilles Vollant and distributed with zlib library;
|
||||
// the modifications are as follows:
|
||||
// - added class' wrappers
|
||||
// - several bugs fixed
|
||||
// - several enhancements added
|
||||
// - MFC support added
|
||||
// - memory leaks eliminated when write error occurred
|
||||
// - automatically free used memory on destruction or exception
|
||||
// - modern error notification using exceptions
|
||||
//
|
||||
// for more info about .ZIP format, see
|
||||
// ftp://ftp.pkware.com/appnote.zip
|
||||
// the unpacked file (appnote.txt) from this archive is a part of this project
|
||||
//
|
||||
//
|
||||
// Note:
|
||||
// if a file added to the archive is bigger after compressing
|
||||
// (e.g. it is an other archive) it should be delted from the archive and
|
||||
// added once again with store method (it may be done only on the files
|
||||
// not divided between volumes)
|
||||
|
||||
#if !defined(AFX_ZIPARCHIVE_H__A7F528A6_1872_4071_BE66_D56CC2DDE0E6__INCLUDED_)
|
||||
#define AFX_ZIPARCHIVE_H__A7F528A6_1872_4071_BE66_D56CC2DDE0E6__INCLUDED_
|
||||
|
||||
#include "ZipStorage.h" // Added by ClassView
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
|
||||
#include "ZipException.h"
|
||||
#include "ZipCentralDir.h" // Added by ClassView
|
||||
#include "ZipInternalInfo.h" // Added by ClassView
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
///////////////////// CZipArchive /////////////////////////////////////
|
||||
|
||||
class CZipArchive
|
||||
{
|
||||
public:
|
||||
static int SingleToWide(CZipAutoBuffer &szSingle, CString& szWide);
|
||||
static int WideToSingle(LPCTSTR lpWide, CZipAutoBuffer &szSingle);
|
||||
|
||||
// Function name : TestFile
|
||||
// Description : Test the file with the given index
|
||||
// the function throws CException*, but performs all the necessary cleanup
|
||||
// before, so that the next file can be tested after catchig the exception
|
||||
// and examining it for the reason of error.
|
||||
// Return type : bool
|
||||
// return false if the incorrect action has been taken by
|
||||
// the user or the programmer (it is when OpenFile(WORD nIndex) or
|
||||
// GetFileInfo(CZipFileHeader & fhInfo, WORD uIndex) return false or uBufSize
|
||||
// is 0
|
||||
// Argument : WORD uIndex
|
||||
// index of the file to test
|
||||
// Argument : ZIPCALLBACKFUN pCallback = NULL
|
||||
// See the description at AddNewFile
|
||||
// Argument : void* pUserData = NULL
|
||||
// Argument : DWORD uBufSize = 65535
|
||||
// the size of the buffer used during extraction
|
||||
bool TestFile(WORD uIndex, ZIPCALLBACKFUN pCallback = NULL, void* pUserData = NULL, DWORD uBufSize = 65535);
|
||||
|
||||
// Function name : CloseFileAfterTestFailed
|
||||
// Description : Perform the necessary cleanup after the exception
|
||||
// while testing the archive so that next files in the archive can be tested
|
||||
// Return type : void
|
||||
void CloseFileAfterTestFailed();
|
||||
|
||||
|
||||
// Function name : SetPassword
|
||||
// Description : set the password for the file that is going to be opened or created
|
||||
// use this function BEFORE opening or adding a file
|
||||
// Return type : bool
|
||||
// return false if the password contains ASCII characters
|
||||
// with values 128 or higher or the file inside archive is
|
||||
// opened
|
||||
// Argument : LPCTSTR lpszPassword = NULL
|
||||
// set it to NULL to clear password
|
||||
bool SetPassword(LPCTSTR lpszPassword = NULL);
|
||||
|
||||
// Function name : SetAdvanced
|
||||
// Description : set advanced options
|
||||
// Return type : void
|
||||
// Argument : int iWriteBuffer = 65535
|
||||
// buffer used during write operation to the disk, the bigger, the better;
|
||||
// it is pointless, however, to set it bigger than the size of the volume;
|
||||
// the optimal size is the size of the volume
|
||||
// Argument : int iExtractBuffer = 16384
|
||||
// set the size of the buffer used in extracting and compressing files
|
||||
// default 16384, must not be < 1024
|
||||
// set it before opening the archive
|
||||
// Argument : int iSearchBuffer = 32768
|
||||
// set the size of the buffer used in searching for the central dir
|
||||
// useful with big archives, default 32768, must not be < 1024
|
||||
void SetAdvanced(int iWriteBuffer = 65535, int iExtractBuffer = 16384, int iSearchBuffer = 32768);
|
||||
|
||||
// Function name : SetSpanCallback
|
||||
// Description : set callback function used during operations on a
|
||||
// pkzip compatible disk spanning archive to change disks;
|
||||
// set it usualy before opening the archive for reading
|
||||
// Return type : void
|
||||
// Argument : ZIPCALLBACKFUN pFunc
|
||||
// for the description of callback function see CZipStorage.h
|
||||
// Argument : void* pData
|
||||
// user data to be passed to the callback function as the last parameter
|
||||
void SetSpanCallback(ZIPCALLBACKFUN pFunc, void* pData = NULL);
|
||||
|
||||
// archive open modes
|
||||
enum {open, openReadOnly, create, createSpan};
|
||||
|
||||
// Disk spanning archive modes:
|
||||
// pkzip compatible mode (pkSpan):
|
||||
// - only on removeble devices
|
||||
// - autodetect the size of the volume
|
||||
// - write a label to the disk
|
||||
// - there is a need to set the span callback function
|
||||
// TD mode (tdSpan):
|
||||
// - may be created on non removable devices
|
||||
// - uses user-defined volume size
|
||||
// - no need to set the span callback function
|
||||
|
||||
// Function name : Open
|
||||
// Description : Open a zip archive
|
||||
// Return type : void
|
||||
// Argument : LPCTSTR szPathName
|
||||
// Path to the archive
|
||||
// Argument : int iMode= CZipArchive::open;
|
||||
// open mode flags:
|
||||
// open open an existing archive
|
||||
// openReadOnly open an existing archive as read only file
|
||||
// (this mode is intended to use in self extract code)
|
||||
// if you try to add or delete a file in this mode, an exception will be thrown
|
||||
// create create a new archive
|
||||
// createSpan create a disk spanning archive
|
||||
// Argument : int iVolumeSize = 0
|
||||
// if iMode == createSpan and iVolumeSize <= 0 then create disk spanning
|
||||
// archive in pkzip mode
|
||||
// if iMode == createSpan and iVolumeSize > 0 then create disk spanning
|
||||
// archive in TD mode
|
||||
// if iMode == open and the exisitng archive is a spanned archive
|
||||
// the pkSpan mode is assumed if the archive is on a removable device
|
||||
// or tdSpan otherwise;
|
||||
// if you want to open tdSpan archive on a removable device, set iVolumeSize
|
||||
// to a value different from 0
|
||||
// if iMode == create this argument doesn't matter
|
||||
void Open(LPCTSTR szPathName, int iMode = open, int iVolumeSize = 0);
|
||||
|
||||
// Function name : Open
|
||||
// Description : Open or create an archive in CMemFile
|
||||
// Return type : void
|
||||
// Argument : CMemFile& mf
|
||||
// Argument : int iMode = open
|
||||
// the following modes are valid: open, openReadOnly, create
|
||||
void Open(CMemFile& mf, int iMode = open);
|
||||
|
||||
|
||||
// Function name : AddNewFile
|
||||
// Description : add quickly a new file to the archive
|
||||
// Return type : bool
|
||||
// Argument : LPCTSTR lpszFilePath
|
||||
// file to be added
|
||||
// Argument : int iLevel = Z_DEFAULT_COMPRESSION
|
||||
// the compression level (see OpenNewFile() for detailed desciption)
|
||||
// Argument : bool bFullPath
|
||||
// if true, include full path of the file inside the archive
|
||||
// Argument : ZIPCALLBACKFUN pCallback = NULL
|
||||
// callback function (may be NULL)
|
||||
// To set the callback function for this operation pass its pointer as the
|
||||
// argument (do not use SetSpanCallback for it - its for different purposes).
|
||||
// The callback function, if set, is called after reading and writing one portion of data.
|
||||
// - the first argument (DWORD):
|
||||
// total number of bytes to read (the size of the file)
|
||||
// - the second one (int) :
|
||||
// total number bytes already read
|
||||
// - the third argument (void*):
|
||||
// pUserData argument passed to #AddNewFile
|
||||
// Argument : void* pUserData = NULL
|
||||
// user - defined data passed on to the callback function
|
||||
// (doesn't matter if there is no callback function defined)
|
||||
// Argument : DWORD nBufSize = 65535
|
||||
// the size of the buffer used during compression
|
||||
|
||||
/*
|
||||
*/
|
||||
bool AddNewFile(LPCTSTR lpszFilePath, int iLevel = -1, bool bFullPath = true, ZIPCALLBACKFUN pCallback = NULL, void* pUserData = NULL, unsigned long nBufSize = 65535);
|
||||
|
||||
// Function name : OpenNewFile
|
||||
// Description : add a new file to the zip archive
|
||||
// Return type : bool
|
||||
// return false in the following cases:
|
||||
// - the lpszFilePath is not NULL and the file attributes and data was not correctly retreived
|
||||
// - a file is already opened for extraction or compression
|
||||
// - archive is an existing disk span archive
|
||||
// - maximum file count inside archive reached (65535)
|
||||
// Argument : CZipFileHeader & header
|
||||
// structure that have addtional information; the following fields are valid:
|
||||
// - m_uMethod - file compression method; can be 0 (storing) or Z_DEFLATE (deflating)
|
||||
// otherwise Z_DEFLATE is assumed
|
||||
// - m_uModDate, m_uModTime - use SetTime method of CFileHeadeer to set them
|
||||
// if lpszFilePath is not NULL this fields are updated automaticaly
|
||||
// - m_uExternalAttr - attributes of the file
|
||||
// if lpszFilePath is not NULL this field is updated automaticaly
|
||||
// - m_szFileName - file name (may be with path) to be stored inside archive
|
||||
// to represent this file
|
||||
// - m_szComment - file comment
|
||||
// - m_pExtraField - LOCAL extra field, use SetExtraField() after opening
|
||||
// a new file, but before closing it to set the extra field
|
||||
// in the header in the central directory
|
||||
// other fields are ignored - they are updated automaticaly
|
||||
// Argument : int iLevel = Z_DEFAULT_COMPRESSION
|
||||
// the level of compression (-1, 0 - 9); named values:
|
||||
// Z_DEFAULT_COMPRESSION : -1
|
||||
// Z_NO_COMPRESSION : 0
|
||||
// Z_BEST_SPEED : 1
|
||||
// Z_BEST_COMPRESSION : 9
|
||||
// Argument : LPCTSTR lpszFilePath = NULL
|
||||
// the path to the file to retreive date and attributes from
|
||||
bool OpenNewFile(CZipFileHeader & header, int iLevel = Z_DEFAULT_COMPRESSION, LPCTSTR lpszFilePath = NULL);
|
||||
|
||||
// Function name : WriteNewFile
|
||||
// Description : compress the contents of the buffer and write it to a new file
|
||||
// Return type : bool
|
||||
// return false if the new file hasn't been opened
|
||||
// Argument : void *pBuf
|
||||
// buffer containing the data to be compressed and written
|
||||
// Argument : DWORD iSize
|
||||
// the size of the buffer
|
||||
bool WriteNewFile(void *pBuf, DWORD iSize);
|
||||
|
||||
// Function name : SetExtraField
|
||||
// Description : set the extra field in the file header in the central directory
|
||||
// must be used after opening a new file in the archive, but before closing it
|
||||
// Return type : void
|
||||
// Argument : char *pBuf
|
||||
// bufer with the data to be copied
|
||||
// Argument : DWORD iSize
|
||||
// size of the buffer
|
||||
void SetExtraField(char *pBuf, WORD iSize);
|
||||
|
||||
// Function name : CloseNewFile
|
||||
// Description : close the new file in the archive
|
||||
// Return type : bool
|
||||
// return false if no new file is opened
|
||||
// Argument : bool bAfterException = false
|
||||
// set it to true if you want to reuse CZipArchive after is has thrown an exception
|
||||
bool CloseNewFile();
|
||||
|
||||
// Function name : ExtractFile
|
||||
// Description : fast extracting
|
||||
// Return type : bool
|
||||
// Argument : WORD uIndex
|
||||
// the index of the file
|
||||
// Argument : LPCTSTR lpszPath
|
||||
// PATH only to extract the file to
|
||||
// Argument : bool bFullPath = true
|
||||
// extract the file with full path (if there is a path stored with the filename)
|
||||
// or just with the filename alone
|
||||
// (it means that the resulting file path is lpszPath + one of the above)
|
||||
// Argument : LPCTSTR lpszNewName = NULL
|
||||
// if NULL the default file name is taken (from the archive)
|
||||
// Argument : ZIPCALLBACKFUN pCallback = NULL
|
||||
// See the description at AddNewFile
|
||||
// Argument : void* pUserData = NULL
|
||||
// Argument : DWORD nBufSize = 65535
|
||||
// the size of the buffer used during extraction
|
||||
bool ExtractFile(WORD uIndex, LPCTSTR lpszPath, bool bFullPath = true, LPCTSTR lpszNewName = NULL, ZIPCALLBACKFUN pCallback = NULL, void* pUserData = NULL, DWORD nBufSize = 65535);
|
||||
|
||||
// Function name : OpenFile
|
||||
// Description : open the file with the given index in the archive for extracting
|
||||
// Argument : WORD uIndex
|
||||
// Return type : bool
|
||||
bool OpenFile(WORD uIndex);
|
||||
|
||||
// Function name : ReadFile
|
||||
// Description : decompress currently opened file to the bufor
|
||||
// Return type : DWORD
|
||||
// number of bytes read
|
||||
// Argument : void *pBuf
|
||||
// buffer to receive data
|
||||
// Argument : DWORD iSize
|
||||
// the size of the buffer
|
||||
DWORD ReadFile(void *pBuf, DWORD iSize);
|
||||
|
||||
// Function name : GetLocalExtraField
|
||||
// Description : get the local extra filed of the currently opened
|
||||
// for extraction file in the archive
|
||||
// Return type : int
|
||||
// if pBuf == NULL return the size of the local extra field
|
||||
// Argument : char* pBuf
|
||||
// the buffer to receive the data
|
||||
// Argument : int iSize
|
||||
// the size of the buffer
|
||||
int GetLocalExtraField(char* pBuf, int iSize);
|
||||
|
||||
// Function name : CloseFile
|
||||
// Description : close current file and update
|
||||
// date and attribute information of CFile, closes CFile
|
||||
// Return type : int
|
||||
// see below
|
||||
// Argument : CFile & file
|
||||
// OPENED CFile structure of the extracted file
|
||||
int CloseFile(CFile &file);
|
||||
|
||||
|
||||
/**
|
||||
Close the file opened for extraction in the archive and copy its date and
|
||||
attributes to the file pointed by \e lpszFilePath
|
||||
\param lpszFilePath
|
||||
Points to the path of the file to have the date and attributes information updated.
|
||||
\param bAfterException
|
||||
Set to \c true to close the file inside archive after an exception has been
|
||||
thrown, to allow futher operations on the archive.
|
||||
\warning Close the file pointed by \e lpszFilePath before using this method,
|
||||
because the system may not be able to retrieve information from it.
|
||||
\return
|
||||
- "1" = ok
|
||||
- "-1" = some bytes left to uncompress - probably due to a bad password
|
||||
- "-2" = setting extracted file date and attributes was not successful
|
||||
\note Throws exceptions.
|
||||
*/
|
||||
int CloseFile(LPCTSTR lpszFilePath = NULL, bool bAfterException = false);
|
||||
|
||||
// Function name : DeleteFile
|
||||
// Description : delete the file with the given index
|
||||
// Return type : bool
|
||||
// Argument : WORD uIndex
|
||||
// index of the file to be deleted
|
||||
bool DeleteFile(WORD uIndex);
|
||||
|
||||
/* delete files from the archive opened in the Delete mode specified by aIndexes
|
||||
or aNames
|
||||
|
||||
aIndexes is a array of indexes of the files inside the archive;
|
||||
the index no. 0 is the first file in the archive
|
||||
|
||||
aNames is a array of file names inside the archive; they must be the
|
||||
same as they apppear in the archive (the name and the path (if persists)
|
||||
is required, lower and upper case are not distinguished)
|
||||
|
||||
*/
|
||||
void DeleteFiles(CWordArray &aIndexes);
|
||||
void DeleteFiles(CStringArray &aNames, bool bCaseSensitive = false);
|
||||
|
||||
|
||||
// Function name : SetGlobalComment
|
||||
// Description : set the global comment in the archive
|
||||
// Return type : bool
|
||||
// return false if the archive is closed or if it is an existing disk spanning archive
|
||||
// Argument : const CString& szComment
|
||||
bool SetGlobalComment(const CString& szComment);
|
||||
|
||||
// Function name : GetGlobalComment
|
||||
// Description : get the global commment
|
||||
// Return type : CString
|
||||
// return an empty string if the archive is closed
|
||||
CString GetGlobalComment();
|
||||
|
||||
|
||||
// Function name : SetFileComment
|
||||
// Description : set the comment of the file with the given index
|
||||
// Return type : bool
|
||||
// return false if the comment change is imposible
|
||||
// Argument : WORD uIndex
|
||||
// index of the file
|
||||
// Argument : CString szComment
|
||||
// comment to add
|
||||
bool SetFileComment(WORD uIndex, CString szComment);
|
||||
|
||||
// Function name : GetArchivePath
|
||||
// Description : return the path of the currently opended archive volume
|
||||
// Return type : CString
|
||||
CString GetArchivePath();
|
||||
|
||||
// Function name : GetCurrentDisk
|
||||
// Description : return the zero-base number of the current disk
|
||||
// Return type : int
|
||||
// return -1 if there is no current disk (archive is closed)
|
||||
int GetCurrentDisk();
|
||||
|
||||
// Function name : GetSpanMode
|
||||
// Description : return the disk spanning mode of the cuurrent archive
|
||||
// Return type : int
|
||||
// CZipStorage::tdSpan == - 2 - exisitng TD compatible disk spanning
|
||||
// CZipStorage::pkzipSpan == - 1 - exisitng pkzip compatible disk spanning
|
||||
// CZipStorage::noSpan == 0 - no disk spanning
|
||||
// CZipStorage::pkzipSpan == 1 - pkzip compatible disk spanning in creation
|
||||
// CZipStorage::tdSpan == 2 - TD compatible disk spanning in creation
|
||||
int GetSpanMode();
|
||||
|
||||
// Function name : IsFileDirectory
|
||||
// Description : check if the file with the given index is a directory
|
||||
// Argument : WORD uIndex
|
||||
// index of the file
|
||||
// Return type : bool
|
||||
// return true if the file is a directory
|
||||
// return false if the file is not a directory or if there is no file
|
||||
// with the given index
|
||||
bool IsFileDirectory(WORD uIndex);
|
||||
|
||||
// Function name : FindFile
|
||||
// Description : find the file in the archive
|
||||
// This function requires CZipCentralDir::m_bFindFastEnabled set to true
|
||||
// Use EnableFindFast()
|
||||
// Return type : int
|
||||
// the index of the file found or -1 if no file was found
|
||||
// Argument : CString szFileName
|
||||
// the name of the file to be found
|
||||
// Argument : bool bCaseSensitive = false
|
||||
// if true - perform case sensitive search
|
||||
int FindFile(CString szFileName, bool bCaseSensitive = false);
|
||||
|
||||
|
||||
/*
|
||||
Function name : EnableFindFast
|
||||
Description :
|
||||
Enable fast finding by the file name of the files inside the archive.
|
||||
Set CZipCentralDir::m_bFindFastEnabled to true, which is required by FindFile.
|
||||
Do not enable it, if you don't plan to use FindFile function
|
||||
|
||||
Return type : void
|
||||
Argument : bool bEnable = true
|
||||
*/
|
||||
void EnableFindFast(bool bEnable = true);
|
||||
|
||||
|
||||
/*
|
||||
Function name : SetConvertAfterOpen
|
||||
Description : Set CZipCentralDir::m_bConvertAfterOpen value. Use before opening the archive
|
||||
see CZipCentralDir::m_bConvertAfterOpen
|
||||
Return type : void
|
||||
Argument : bool bConvertAfterOpen
|
||||
*/
|
||||
void SetConvertAfterOpen (bool bConvertAfterOpen)
|
||||
{
|
||||
if (!IsClosed())
|
||||
{
|
||||
TRACE(_T("Set it before opening the archive"));
|
||||
return;
|
||||
}
|
||||
m_centralDir.m_bConvertAfterOpen = bConvertAfterOpen;
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Function name : GetFileInfo
|
||||
// Description : get the info of the file with the given index
|
||||
// Return type : bool
|
||||
// true if successful
|
||||
// Argument : CZipFileHeader & fhInfo
|
||||
// structure to receive info
|
||||
// Argument : WORD uIndex
|
||||
// zero-based index of the file
|
||||
bool GetFileInfo(CZipFileHeader & fhInfo, WORD uIndex);
|
||||
|
||||
|
||||
// Function name : GetNoEntries
|
||||
// Description : get number of files in the archive
|
||||
// Return type : int
|
||||
int GetNoEntries();
|
||||
|
||||
// Function name : Close
|
||||
// Description : close archive
|
||||
// Return type : void
|
||||
// Argument : bool bAfterException = false
|
||||
// set it to true if you want to close and reuse CZipArchive after is has thrown an exception
|
||||
// ( it doesn't write any data to the file but only makes some cleaning then)
|
||||
void Close(bool bAfterException = false);
|
||||
|
||||
|
||||
|
||||
// Function name : IsClosed
|
||||
// Description : test if the archive or the current volume file is closed
|
||||
// Return type : bool
|
||||
// Argument : bool bArchive = true
|
||||
// if true test for the whole archive, if false - for the volume file only
|
||||
bool IsClosed(bool bArchive = true);
|
||||
|
||||
// specify whether to control memory allocation and freeing by zlib library
|
||||
// strongly suggested to set it to true (default)
|
||||
// set it before opening a file (new or current) in the archive
|
||||
bool m_bDetectZlibMemoryLeaks;
|
||||
|
||||
|
||||
CZipArchive();
|
||||
virtual ~CZipArchive();
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
////////////////////// static helper functions ///////////////////////
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Function name : GetFileTitle
|
||||
// Description : get the title of the file
|
||||
// Return type : CString
|
||||
// Argument : LPCTSTR lpszFilePath
|
||||
static CString GetFileTitle(LPCTSTR lpszFilePath);
|
||||
|
||||
// Function name : GetFileDirAndName
|
||||
// Description : get the directory and the file name from the file path
|
||||
// Return type : static CString
|
||||
// Argument : LPCTSTR lpszFilePath
|
||||
static CString GetFileDirAndName(LPCTSTR lpszFilePath);
|
||||
|
||||
// Function name : GetDrive
|
||||
// Description : return the (drive:) part from the path
|
||||
// Return type : static CString
|
||||
// Argument : LPCTSTR lpszFilePath
|
||||
static CString GetDrive(LPCTSTR lpszFilePath);
|
||||
|
||||
// Function name : IsDriveRemovable
|
||||
// Description : return true if the file, path or (disk:) specified by the
|
||||
// argument is (on) a removable drive
|
||||
// Return type : static bool
|
||||
// Argument : LPCTSTR lpszFilePath
|
||||
static bool IsDriveRemovable(LPCTSTR lpszFilePath);
|
||||
|
||||
// Function name : DirectoryExists
|
||||
// Description : check if the given directory exists
|
||||
// Return type : static bool
|
||||
// Argument : LPCTSTR lpszDir
|
||||
static bool DirectoryExists(LPCTSTR lpszDir);
|
||||
|
||||
|
||||
// Function name : FileExists
|
||||
// Description : check if the given file or directory exists
|
||||
// Return type : static int
|
||||
// return -1 if the given file is a directory, 1 if is a file
|
||||
// or 0 if there is no such a file
|
||||
// Argument : LPCTSTR lpszName
|
||||
static int FileExists(LPCTSTR lpszName);
|
||||
|
||||
// Function name : ForceDirectory
|
||||
// Description : create nested directories with a single command
|
||||
// Return type : static bool
|
||||
// Argument : LPCTSTR lpDirectory
|
||||
static bool ForceDirectory(LPCTSTR lpDirectory);
|
||||
|
||||
// Function name : GetFilePath
|
||||
// Description : get the path of the given file
|
||||
// Return type : static CString
|
||||
// Argument : LPCTSTR strFilePath
|
||||
static CString GetFilePath(LPCTSTR lpszFilePath);
|
||||
|
||||
|
||||
// Function name : GetFileExt
|
||||
// Description : return the file extension
|
||||
// Return type : static CString
|
||||
// Argument : LPCTSTR lpszFilePath
|
||||
static CString GetFileExt(LPCTSTR lpszFilePath);
|
||||
|
||||
|
||||
// Function name : GetFileName
|
||||
// Description : return the name of the file (title + extension)
|
||||
// Return type : static CString
|
||||
// Argument : LPCTSTR lpszFilePath
|
||||
static CString GetFileName(LPCTSTR lpszFilePath);
|
||||
|
||||
// just a helper for a various purposes
|
||||
static const DWORD* GetCRCTable();
|
||||
// function for a VERY advanced use - you normally never need that
|
||||
CZipStorage* GetStorage(){return &m_storage;}
|
||||
|
||||
protected:
|
||||
void EmptyPtrList();
|
||||
void CryptDecodeBuffer(DWORD uCount);
|
||||
void CryptEncodeBuffer();
|
||||
void CryptEncode(char &c);
|
||||
void CryptCryptHeader(long iCrc, CZipAutoBuffer& buf);
|
||||
DWORD CryptCRC32(DWORD l, char c);
|
||||
void CryptDecode(char &c);
|
||||
char CryptDecryptByte();
|
||||
bool CryptCheck();
|
||||
void CryptUpdateKeys(char c);
|
||||
void CryptInitKeys();
|
||||
CZipAutoBuffer m_pszPassword;
|
||||
DWORD m_keys[3];
|
||||
|
||||
static int CompareWords(const void *pArg1, const void *pArg2);
|
||||
bool IsDirectory(DWORD uAttr);
|
||||
void DeleteInternal(WORD uIndex);
|
||||
DWORD RemovePackedFile(DWORD uStartOffset, DWORD uEndOffset);
|
||||
CZipFileHeader* CurrentFile();
|
||||
void CheckForError(int iErr);
|
||||
CZipInternalInfo m_info;
|
||||
CZipStorage m_storage;
|
||||
CPtrList m_list;
|
||||
static void* myalloc(void* opaque, UINT items, UINT size);
|
||||
static void myfree(void* opaque, void* address);
|
||||
enum {extract = -1, nothing, compress};
|
||||
// 0 - no file inside archive opened
|
||||
// -1 - current opened for extract
|
||||
// 1 - new opened for compression
|
||||
char m_iFileOpened;
|
||||
void ThrowError(int err);
|
||||
CZipCentralDir m_centralDir;
|
||||
static TCHAR m_gszCopyright[];
|
||||
};
|
||||
|
||||
#endif // !defined(AFX_ZIPARCHIVE_H__A7F528A6_1872_4071_BE66_D56CC2DDE0E6__INCLUDED_)
|
||||
Binary file not shown.
@@ -0,0 +1,104 @@
|
||||
// ZipAutoBuffer.cpp: implementation of the CZipAutoBuffer class.
|
||||
// Part of the ZipArchive library
|
||||
//
|
||||
// Copyright (C) 2000 - 2001 Tadeusz Dracz.
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// For the licensing details see the file License.txt
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "ZipAutoBuffer.h"
|
||||
#include <memory.h>
|
||||
|
||||
// #ifdef _DEBUG
|
||||
// #undef THIS_FILE
|
||||
// static char THIS_FILE[]=__FILE__;
|
||||
// #define new DEBUG_NEW
|
||||
// #endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Construction/Destruction
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
CZipAutoBuffer::CZipAutoBuffer()
|
||||
{
|
||||
m_iSize = 0;
|
||||
m_pBuffer = NULL;
|
||||
}
|
||||
|
||||
CZipAutoBuffer::CZipAutoBuffer(DWORD iSize, bool bZeroMemory)
|
||||
{
|
||||
m_iSize = 0;
|
||||
m_pBuffer = NULL;
|
||||
Allocate(iSize, bZeroMemory);
|
||||
}
|
||||
|
||||
CZipAutoBuffer::~CZipAutoBuffer()
|
||||
{
|
||||
Release();
|
||||
}
|
||||
|
||||
|
||||
void CZipAutoBuffer::Release()
|
||||
{
|
||||
if (m_pBuffer)
|
||||
{
|
||||
delete [] m_pBuffer;
|
||||
m_iSize = 0;
|
||||
m_pBuffer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
char* CZipAutoBuffer::Allocate(DWORD iSize, bool bZeroMemory)
|
||||
{
|
||||
if (iSize != m_iSize)
|
||||
Release();
|
||||
else
|
||||
{
|
||||
if (bZeroMemory)
|
||||
memset(m_pBuffer, 0, iSize); // zerowanie bufora
|
||||
return m_pBuffer;
|
||||
}
|
||||
|
||||
if (iSize > 0)
|
||||
{
|
||||
m_pBuffer = new char [iSize];
|
||||
if (bZeroMemory)
|
||||
memset(m_pBuffer, 0, iSize); // zerowanie bufora
|
||||
m_iSize = iSize;
|
||||
}
|
||||
else
|
||||
m_pBuffer = NULL;
|
||||
|
||||
return m_pBuffer;
|
||||
}
|
||||
|
||||
|
||||
CZipAutoBuffer::CZipAutoBuffer(const CZipAutoBuffer& buffer)
|
||||
{
|
||||
m_pBuffer = NULL;
|
||||
m_iSize = 0;
|
||||
|
||||
if (buffer.m_pBuffer)
|
||||
{
|
||||
Allocate(buffer.m_iSize);
|
||||
memcpy(m_pBuffer, buffer.m_pBuffer, buffer.m_iSize);
|
||||
}
|
||||
}
|
||||
CZipAutoBuffer& CZipAutoBuffer::operator=(const CZipAutoBuffer& buffer)
|
||||
{
|
||||
if (this == &buffer)
|
||||
return *this;
|
||||
Release();
|
||||
if (buffer.m_pBuffer)
|
||||
{
|
||||
Allocate(buffer.m_iSize);
|
||||
memcpy(m_pBuffer, buffer.m_pBuffer, buffer.m_iSize);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/**
|
||||
* \file ZipAutoBuffer.h
|
||||
* Interface for the CZipAutoBuffer class.
|
||||
*
|
||||
* \author Tadeusz Dracz
|
||||
*/
|
||||
// Part of the ZipArchive library
|
||||
//
|
||||
// Copyright (C) 2000 - 2001 Tadeusz Dracz.
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// For the licensing details see the file License.txt
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#if !defined(AFX_ZIPAUTOBUFFER_H__DEC28C20_83FE_11D3_B7C3_EDEC47A8A86C__INCLUDED_)
|
||||
#define AFX_ZIPAUTOBUFFER_H__DEC28C20_83FE_11D3_B7C3_EDEC47A8A86C__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
|
||||
/**
|
||||
A smart buffer freeing its contents on destruction.
|
||||
*/
|
||||
class CZipAutoBuffer
|
||||
{
|
||||
public:
|
||||
operator char*()
|
||||
{
|
||||
return m_pBuffer;
|
||||
}
|
||||
|
||||
// may produce ambiguity on some compilers
|
||||
// operator const char*() const
|
||||
// {
|
||||
// return m_pBuffer;
|
||||
// }
|
||||
const char* GetBuffer() const {return m_pBuffer;}
|
||||
char* Allocate(DWORD iSize, bool bZeroMemory = false);
|
||||
void Release();
|
||||
DWORD GetSize() const
|
||||
{
|
||||
return m_iSize;
|
||||
}
|
||||
bool IsAllocated() const
|
||||
{
|
||||
return (m_pBuffer != NULL);
|
||||
}
|
||||
CZipAutoBuffer(DWORD iSize, bool bZeroMemory = false);
|
||||
CZipAutoBuffer();
|
||||
CZipAutoBuffer(const CZipAutoBuffer& buffer);
|
||||
virtual ~CZipAutoBuffer();
|
||||
CZipAutoBuffer& operator=(const CZipAutoBuffer& buffer);
|
||||
protected:
|
||||
char* m_pBuffer;
|
||||
DWORD m_iSize;
|
||||
};
|
||||
|
||||
#endif // !defined(AFX_ZIPAUTOBUFFER_H__DEC28C20_83FE_11D3_B7C3_EDEC47A8A86C__INCLUDED_)
|
||||
@@ -0,0 +1,41 @@
|
||||
// ZipBigFile.cpp: implementation of the CZipBigFile class.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "ZipBigFile.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Construction/Destruction
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
IMPLEMENT_DYNAMIC(CZipBigFile, CFile)
|
||||
|
||||
CZipBigFile::CZipBigFile()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CZipBigFile::~CZipBigFile()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
_int64 CZipBigFile::Seek(_int64 dOff, UINT nFrom)
|
||||
{
|
||||
ASSERT_VALID(this);
|
||||
ASSERT(m_hFile != (UINT)hFileNull);
|
||||
ASSERT(nFrom == begin || nFrom == end || nFrom == current);
|
||||
ASSERT(begin == FILE_BEGIN && end == FILE_END && current == FILE_CURRENT);
|
||||
LARGE_INTEGER li;
|
||||
li.QuadPart = dOff;
|
||||
|
||||
li.LowPart = ::SetFilePointer((HANDLE)m_hFile, li.LowPart, &li.HighPart, (DWORD)nFrom);
|
||||
DWORD dw = GetLastError();
|
||||
if ((li.LowPart == (DWORD)-1) && (dw != NO_ERROR))
|
||||
{
|
||||
CFileException::ThrowOsError((LONG)dw);
|
||||
}
|
||||
|
||||
return li.QuadPart;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
// ZipBigFile.h: interface for the CZipBigFile class.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if !defined(AFX_ZipBigFile_H__79E0E6BD_25D6_4B82_85C5_AB397D9EC368__INCLUDED_)
|
||||
#define AFX_ZipBigFile_H__79E0E6BD_25D6_4B82_85C5_AB397D9EC368__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
|
||||
class CZipBigFile : public CFile
|
||||
{
|
||||
DECLARE_DYNAMIC(CZipBigFile)
|
||||
public:
|
||||
_int64 Seek(_int64 dOff, UINT nFrom);
|
||||
CZipBigFile();
|
||||
virtual ~CZipBigFile();
|
||||
|
||||
};
|
||||
|
||||
#endif // !defined(AFX_ZipBigFile_H__79E0E6BD_25D6_4B82_85C5_AB397D9EC368__INCLUDED_)
|
||||
@@ -0,0 +1,677 @@
|
||||
// ZipCentralDir.cpp: implementation of the CZipCentralDir class.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2000 Tadeusz Dracz.
|
||||
// For conditions of distribution and use, see copyright notice in ZipArchive.h
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "ZipCentralDir.h"
|
||||
#include "ZipArchive.h"
|
||||
|
||||
struct CZipAutoHandle
|
||||
{
|
||||
HANDLE m_hFileMap;
|
||||
LPVOID m_pFileMap;
|
||||
CZipAutoHandle()
|
||||
{
|
||||
m_hFileMap = NULL;
|
||||
m_pFileMap = NULL;
|
||||
}
|
||||
bool CreateMapping(HANDLE hFile)
|
||||
{
|
||||
m_hFileMap = CreateFileMapping(hFile, NULL, PAGE_READWRITE,
|
||||
0, 0, _T("ZipArchive Mapping File"));
|
||||
if (!m_hFileMap)
|
||||
return false;
|
||||
// Get pointer to memory representing file
|
||||
m_pFileMap = MapViewOfFile(m_hFileMap, FILE_MAP_WRITE, 0, 0, 0);
|
||||
return (m_pFileMap != NULL);
|
||||
}
|
||||
void RemoveMapping()
|
||||
{
|
||||
if (m_pFileMap)
|
||||
{
|
||||
UnmapViewOfFile(m_pFileMap);
|
||||
m_pFileMap = NULL;
|
||||
}
|
||||
if (m_hFileMap)
|
||||
{
|
||||
CloseHandle(m_hFileMap);
|
||||
m_hFileMap = NULL;
|
||||
}
|
||||
|
||||
}
|
||||
~CZipAutoHandle()
|
||||
{
|
||||
RemoveMapping();
|
||||
}
|
||||
};
|
||||
|
||||
#define ZIPCENTRALDIRSIZE 22
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Construction/Destruction
|
||||
char CZipCentralDir::m_gszSignature[] = {0x50, 0x4b, 0x05, 0x06};
|
||||
CZipCentralDir::CZipCentralDir()
|
||||
{
|
||||
m_bConvertAfterOpen = true;
|
||||
m_bFindFastEnabled = false;
|
||||
m_pStorage = NULL;
|
||||
m_pOpenedFile = NULL;
|
||||
m_iBufferSize = 32768;
|
||||
|
||||
}
|
||||
|
||||
void CZipCentralDir::Init()
|
||||
{
|
||||
m_bOnDisk = false;
|
||||
m_uBytesBeforeZip = m_uCentrDirPos = 0;
|
||||
m_pOpenedFile = NULL;
|
||||
m_pszComment.Release();
|
||||
}
|
||||
|
||||
CZipCentralDir::~CZipCentralDir()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
void CZipCentralDir::Read()
|
||||
{
|
||||
ASSERT(m_pStorage);
|
||||
WORD uCommentSize;
|
||||
m_uCentrDirPos = Locate();
|
||||
m_pStorage->m_pFile->Seek(m_uCentrDirPos, CFile::begin);
|
||||
CZipAutoBuffer buf(ZIPCENTRALDIRSIZE);
|
||||
DWORD uRead = m_pStorage->m_pFile->Read(buf, ZIPCENTRALDIRSIZE );
|
||||
if (uRead != ZIPCENTRALDIRSIZE)
|
||||
ThrowError(ZIP_BADZIPFILE);
|
||||
memcpy(&m_szSignature, buf, 4);
|
||||
memcpy(&m_uThisDisk, buf + 4, 2);
|
||||
memcpy(&m_uDiskWithCD, buf + 6, 2);
|
||||
memcpy(&m_uDiskEntriesNo, buf + 8, 2);
|
||||
memcpy(&m_uEntriesNumber, buf + 10, 2);
|
||||
memcpy(&m_uSize, buf + 12, 4);
|
||||
memcpy(&m_uOffset, buf + 16, 4);
|
||||
memcpy(&uCommentSize, buf + 20, 2);
|
||||
buf.Release();
|
||||
|
||||
|
||||
m_pStorage->UpdateSpanMode(m_uThisDisk);
|
||||
// if m_uThisDisk is not zero, it is enough to say that it is multi archive
|
||||
ASSERT((!m_uThisDisk && (m_uEntriesNumber == m_uDiskEntriesNo) && !m_uDiskWithCD) || m_uThisDisk);
|
||||
|
||||
|
||||
|
||||
if (!m_pStorage->IsSpanMode() && ((DWORD)m_uCentrDirPos < m_uOffset + m_uSize))
|
||||
ThrowError(ZIP_BADZIPFILE);
|
||||
|
||||
if (uCommentSize)
|
||||
{
|
||||
m_pszComment.Allocate(uCommentSize);
|
||||
uRead = m_pStorage->m_pFile->Read(m_pszComment, uCommentSize);
|
||||
if (uRead != uCommentSize)
|
||||
ThrowError(ZIP_BADZIPFILE);
|
||||
}
|
||||
|
||||
m_uBytesBeforeZip = m_pStorage->IsSpanMode() ? 0 : m_uCentrDirPos - m_uSize - m_uOffset;
|
||||
|
||||
if ((!m_uSize && m_uEntriesNumber) || (!m_uEntriesNumber && m_uSize))
|
||||
ThrowError(ZIP_BADZIPFILE);
|
||||
|
||||
m_bOnDisk = true;
|
||||
m_pStorage->ChangeDisk(m_uDiskWithCD);
|
||||
|
||||
if (!m_uSize)
|
||||
return;
|
||||
|
||||
ReadHeaders();
|
||||
}
|
||||
|
||||
// return the location of the beginning of the "end" record in the file
|
||||
DWORD CZipCentralDir::Locate()
|
||||
{
|
||||
|
||||
// maximum size of end of central dir record
|
||||
long uMaxRecordSize = 0xffff + ZIPCENTRALDIRSIZE;
|
||||
DWORD uFileSize = m_pStorage->m_pFile->GetLength();
|
||||
|
||||
if ((DWORD)uMaxRecordSize > uFileSize)
|
||||
uMaxRecordSize = uFileSize;
|
||||
|
||||
CZipAutoBuffer buf(m_iBufferSize);
|
||||
|
||||
long uPosInFile = 0;
|
||||
int uRead = 0;
|
||||
// backward reading
|
||||
while (uPosInFile < uMaxRecordSize)
|
||||
{
|
||||
uPosInFile = uRead + m_iBufferSize;
|
||||
if (uPosInFile > uMaxRecordSize)
|
||||
uPosInFile = uMaxRecordSize;
|
||||
|
||||
int iToRead = uPosInFile - uRead;
|
||||
|
||||
m_pStorage->m_pFile->Seek(-uPosInFile, CFile::end);
|
||||
int iActuallyRead = m_pStorage->m_pFile->Read(buf, iToRead);
|
||||
if (iActuallyRead != iToRead)
|
||||
ThrowError(ZIP_BADZIPFILE);
|
||||
// search from the very last bytes to prevent an error if inside archive
|
||||
// there are packed other arhives
|
||||
for (int i = iToRead - 4; i >=0 ; i--)
|
||||
if (!memcmp((char*)buf + i, m_gszSignature, 4))
|
||||
return uFileSize - (uPosInFile - i);
|
||||
|
||||
uRead += iToRead - 3;
|
||||
|
||||
}
|
||||
|
||||
ThrowError(ZIP_CDIR_NOTFOUND);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CZipCentralDir::ThrowError(int err)
|
||||
{
|
||||
AfxThrowZipException(err, m_pStorage->m_pFile->GetFilePath());
|
||||
}
|
||||
|
||||
|
||||
void CZipCentralDir::ReadHeaders()
|
||||
{
|
||||
m_pStorage->m_pFile->Seek(m_uOffset + m_uBytesBeforeZip, CFile::begin);
|
||||
RemoveHeaders();
|
||||
for (int i = 0; i < m_uEntriesNumber; i++)
|
||||
{
|
||||
CZipFileHeader* pHeader = new CZipFileHeader;
|
||||
m_headers.Add(pHeader); // bezpoœrednio nastêpuje w razie wyj¹tku
|
||||
|
||||
if (!pHeader->Read(m_pStorage))
|
||||
ThrowError(ZIP_BADZIPFILE);
|
||||
ConvertFileName(true, true, pHeader);
|
||||
}
|
||||
if (m_bFindFastEnabled)
|
||||
BuildFindFastArray();
|
||||
|
||||
}
|
||||
|
||||
// remove all headers from the central dir
|
||||
void CZipCentralDir::Clear(bool bEverything)
|
||||
{
|
||||
m_pOpenedFile = NULL;
|
||||
m_pLocalExtraField.Release();
|
||||
|
||||
if (bEverything)
|
||||
{
|
||||
RemoveHeaders();
|
||||
m_findarray.RemoveAll();
|
||||
m_pszComment.Release();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool CZipCentralDir::IsValidIndex(WORD uIndex)
|
||||
{
|
||||
|
||||
bool ret = uIndex < m_headers.GetSize();
|
||||
#ifdef _DEBUG
|
||||
if (!ret)
|
||||
TRACE(_T("Not a valid index.\n"));
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
// open the file for extracting
|
||||
void CZipCentralDir::OpenFile(WORD uIndex)
|
||||
{
|
||||
WORD uLocalExtraFieldSize;
|
||||
m_pOpenedFile = m_headers[uIndex];
|
||||
m_pStorage->ChangeDisk(m_pOpenedFile->m_uDiskStart);
|
||||
m_pStorage->m_pFile->Seek(m_pOpenedFile->m_uOffset + m_uBytesBeforeZip, CFile::begin);
|
||||
if (!m_pOpenedFile->ReadLocal(m_pStorage, uLocalExtraFieldSize))
|
||||
ThrowError(ZIP_BADZIPFILE);
|
||||
|
||||
|
||||
m_pLocalExtraField.Release(); // just in case
|
||||
if (uLocalExtraFieldSize)
|
||||
{
|
||||
int iCurrDsk = m_pStorage->GetCurrentDisk();
|
||||
m_pLocalExtraField.Allocate(uLocalExtraFieldSize);
|
||||
m_pStorage->Read(m_pLocalExtraField, uLocalExtraFieldSize, true);
|
||||
if (m_pStorage->GetCurrentDisk() != iCurrDsk)
|
||||
ThrowError(ZIP_BADZIPFILE);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void CZipCentralDir::CloseFile()
|
||||
{
|
||||
if (!m_pOpenedFile)
|
||||
return;
|
||||
m_pLocalExtraField.Release();
|
||||
if (m_pOpenedFile->IsDataDescr())
|
||||
{
|
||||
CZipAutoBuffer buf(12);
|
||||
m_pStorage->Read(buf, 4, false);
|
||||
// in span mode, files that are divided between disks have bit 3 of flag set
|
||||
// which tell about the presence of the data descriptor after the compressed data
|
||||
// This signature may be in the disk spanning archive that is one volume only
|
||||
// (it is detected as a non disk spanning archive)
|
||||
if (memcmp(buf, CZipStorage::m_gszExtHeaderSignat, 4) != 0) // there is no signature
|
||||
m_pStorage->m_pFile->Seek(-4, CFile::current);
|
||||
|
||||
|
||||
m_pStorage->Read(buf, 12, false);
|
||||
if (!m_pOpenedFile->CheckCrcAndSizes(buf))
|
||||
ThrowError(ZIP_BADZIPFILE);
|
||||
}
|
||||
m_pOpenedFile = NULL;
|
||||
}
|
||||
|
||||
// add new header using the argument as a template
|
||||
void CZipCentralDir::AddNewFile(CZipFileHeader & header)
|
||||
{
|
||||
CZipFileHeader* pHeader = new CZipFileHeader(header);
|
||||
m_pOpenedFile = pHeader;
|
||||
m_headers.Add(pHeader);
|
||||
if (m_bFindFastEnabled)
|
||||
InsertFindFastElement(pHeader, WORD(m_headers.GetSize() - 1)); // GetSize IS > 0, 'cos we've just added a header
|
||||
RemoveFromDisk();
|
||||
m_pStorage->m_pFile->SeekToEnd();
|
||||
}
|
||||
|
||||
// called during adding or deleting files; remove the central dir from the disk
|
||||
void CZipCentralDir::RemoveFromDisk()
|
||||
{
|
||||
if (m_bOnDisk)
|
||||
{
|
||||
ASSERT(!m_pStorage->IsSpanMode()); // you can't add files to the existing disk span archive or to delete them from it
|
||||
m_pStorage->m_pFile->SetLength(m_uBytesBeforeZip + m_uOffset);
|
||||
m_bOnDisk = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CZipCentralDir::CloseNewFile()
|
||||
{
|
||||
CZipAutoBuffer buf(12 + 4);
|
||||
short iToWrite = 0;
|
||||
bool bIsSpan = m_pStorage->IsSpanMode() != 0;
|
||||
bool bEncrypted = m_pOpenedFile->IsEncrypted();
|
||||
if (m_pOpenedFile->IsDataDescr())
|
||||
{
|
||||
if (bIsSpan || bEncrypted)
|
||||
{
|
||||
memcpy(buf, m_pStorage->m_gszExtHeaderSignat, 4);
|
||||
iToWrite += 4;
|
||||
}
|
||||
}
|
||||
else /*if (!IsSpan)*/
|
||||
{
|
||||
ASSERT(!bIsSpan && !bEncrypted);
|
||||
m_pStorage->Flush();
|
||||
m_pStorage->m_pFile->Seek(m_pOpenedFile->m_uOffset + 14, CFile::begin);
|
||||
// we don't have to restore the pointer, because before adding a new file,
|
||||
// the pointer is moved to the end
|
||||
}
|
||||
|
||||
m_pOpenedFile->GetCrcAndSizes(buf + iToWrite);
|
||||
iToWrite += 12;
|
||||
|
||||
// offset set during writting the local header
|
||||
m_pOpenedFile->m_uOffset -= m_uBytesBeforeZip;
|
||||
|
||||
// write the data descriptor and a disk spanning signature at once
|
||||
m_pStorage->Write(buf, iToWrite, true);
|
||||
if (!bIsSpan && bEncrypted)
|
||||
{
|
||||
// write the information to the local header too
|
||||
m_pStorage->Flush();
|
||||
m_pStorage->m_pFile->Seek(m_pOpenedFile->m_uOffset + 14, CFile::begin);
|
||||
m_pStorage->Write(buf + 4, 12, true);
|
||||
}
|
||||
|
||||
if (!bIsSpan)
|
||||
m_pStorage->Flush();
|
||||
|
||||
m_pOpenedFile = NULL;
|
||||
|
||||
}
|
||||
|
||||
void CZipCentralDir::Write()
|
||||
{
|
||||
if (m_bOnDisk)
|
||||
return;
|
||||
if (!m_pStorage->IsSpanMode())
|
||||
{
|
||||
m_pStorage->Flush();
|
||||
m_pStorage->m_pFile->SeekToEnd();
|
||||
}
|
||||
m_uEntriesNumber = (WORD)m_headers.GetSize();
|
||||
m_uSize = 0;
|
||||
bool bDontAllowDiskChange = false;
|
||||
// if there is a disk spanning archive in creation and it is only one-volume,
|
||||
// (current disk is 0 so far, no bytes has been written so we know they are
|
||||
// all in the buffer) make sure that it will be after writting central dir
|
||||
// and make it a non disk spanning archive
|
||||
if (m_pStorage->IsSpanMode() && m_pStorage->GetCurrentDisk() == 0)
|
||||
{
|
||||
DWORD uVolumeFree = m_pStorage->VolumeLeft();
|
||||
// calculate the size of data descriptors already in the buffer or on the disk
|
||||
// (they will be removed in the non disk spanning archive):
|
||||
// multi span signature at the beginnig (4 bytes) + the size of the data
|
||||
// descr. for each file (multi span signature + 12 bytes data)
|
||||
// the count of bytes to add: central dir size - total to remove;
|
||||
DWORD uToGrow = GetSize(true) - (4 + m_uEntriesNumber * (4 + 12));
|
||||
if (uVolumeFree >= uToGrow)
|
||||
// lets make sure it will be one-disk archive
|
||||
{
|
||||
// can the operation be done only in the buffer?
|
||||
if (!m_pStorage->m_iBytesWritten && // no bytes on the disk yet
|
||||
(m_pStorage->GetFreeInBuffer() >= uToGrow)) // is the buffer big enough?
|
||||
{
|
||||
RemoveDataDescr(true);
|
||||
bDontAllowDiskChange = true; // if the disk change occurs somehow, we'll throw an error later
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pStorage->Flush();
|
||||
m_pStorage->m_pFile->Flush();
|
||||
if (RemoveDataDescr(false))
|
||||
bDontAllowDiskChange = true; // if the disk change occurs somehow, we'll throw an error later
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
WriteHeaders();
|
||||
m_uThisDisk = (WORD)m_pStorage->GetCurrentDisk();
|
||||
DWORD uSize = WriteCentralEnd();
|
||||
if (bDontAllowDiskChange && (m_pStorage->GetCurrentDisk() != 0))
|
||||
ThrowError(ZIP_BADZIPFILE);
|
||||
// if after adding a central directory there is a disk change,
|
||||
// update the information and write it again
|
||||
if (m_uThisDisk != m_pStorage->GetCurrentDisk())
|
||||
{
|
||||
m_uThisDisk = (WORD)m_pStorage->GetCurrentDisk();
|
||||
if (m_uEntriesNumber)
|
||||
{
|
||||
m_uDiskEntriesNo = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_uDiskWithCD = m_uThisDisk;
|
||||
m_uOffset = 0;
|
||||
}
|
||||
|
||||
if (m_pStorage->m_uBytesInWriteBuffer >= uSize)
|
||||
// if the data is still in the buffer, simply remove it
|
||||
m_pStorage->m_uBytesInWriteBuffer -= uSize;
|
||||
else
|
||||
{
|
||||
m_pStorage->Flush();
|
||||
m_pStorage->m_iBytesWritten -= uSize;
|
||||
m_pStorage->m_pFile->SeekToBegin();
|
||||
}
|
||||
|
||||
WriteCentralEnd();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void CZipCentralDir::WriteHeaders()
|
||||
{
|
||||
m_uDiskEntriesNo = 0;
|
||||
m_uDiskWithCD = (WORD)m_pStorage->GetCurrentDisk();
|
||||
m_uOffset = m_pStorage->GetPosition() - m_uBytesBeforeZip;
|
||||
if (!m_uEntriesNumber)
|
||||
return;
|
||||
|
||||
WORD iDisk = m_uDiskWithCD;
|
||||
for (int i = 0; i < m_uEntriesNumber; i++)
|
||||
{
|
||||
CZipFileHeader* pHeader = m_headers[i];
|
||||
ConvertFileName(false, true, pHeader);
|
||||
m_uSize += pHeader->Write(m_pStorage);
|
||||
if (m_pStorage->GetCurrentDisk() != iDisk)
|
||||
{
|
||||
m_uDiskEntriesNo = 1;
|
||||
iDisk = (WORD)m_pStorage->GetCurrentDisk();
|
||||
// update the information about the offset and starting disk if the
|
||||
// first header was written on the new disk
|
||||
if (i == 0)
|
||||
{
|
||||
m_uOffset = 0;
|
||||
m_uDiskWithCD = iDisk;
|
||||
}
|
||||
}
|
||||
else
|
||||
m_uDiskEntriesNo++;
|
||||
}
|
||||
}
|
||||
|
||||
DWORD CZipCentralDir::WriteCentralEnd()
|
||||
{
|
||||
DWORD uSize = GetSize();
|
||||
CZipAutoBuffer buf(uSize);
|
||||
WORD uCommentSize = (WORD)m_pszComment.GetSize();
|
||||
memcpy(buf, m_gszSignature, 4);
|
||||
memcpy(buf + 4, &m_uThisDisk, 2);
|
||||
memcpy(buf + 6, &m_uDiskWithCD, 2);
|
||||
memcpy(buf + 8, &m_uDiskEntriesNo, 2);
|
||||
memcpy(buf + 10, &m_uEntriesNumber, 2);
|
||||
memcpy(buf + 12, &m_uSize, 4);
|
||||
memcpy(buf + 16, &m_uOffset, 4);
|
||||
memcpy(buf + 20, &uCommentSize, 2);
|
||||
memcpy(buf + 22, m_pszComment, uCommentSize);
|
||||
m_pStorage->Write(buf, uSize, true);
|
||||
return uSize;
|
||||
}
|
||||
|
||||
|
||||
void CZipCentralDir::RemoveFile(WORD uIndex)
|
||||
{
|
||||
CZipFileHeader* pHeader = m_headers[uIndex];
|
||||
if (m_bFindFastEnabled)
|
||||
{
|
||||
int i = FindFileNameIndex(pHeader->GetFileName(), true);
|
||||
ASSERT(i != -1);
|
||||
int uIndex = m_findarray[i].m_uIndex;
|
||||
m_findarray.RemoveAt(i);
|
||||
// shift down the indexes
|
||||
for (int j = 0; j < m_findarray.GetSize(); j++)
|
||||
{
|
||||
if (m_findarray[j].m_uIndex > uIndex)
|
||||
m_findarray[j].m_uIndex--;
|
||||
}
|
||||
}
|
||||
delete pHeader;
|
||||
m_headers.RemoveAt(uIndex);
|
||||
}
|
||||
|
||||
|
||||
DWORD CZipCentralDir::GetSize(bool bWhole)
|
||||
{
|
||||
DWORD uHeaders = 0;
|
||||
if (bWhole)
|
||||
{
|
||||
for (int i = 0; i < m_headers.GetSize(); i++)
|
||||
uHeaders += m_headers[i]->GetSize();
|
||||
}
|
||||
return ZIPCENTRALDIRSIZE + m_pszComment.GetSize() + uHeaders;
|
||||
}
|
||||
|
||||
// remove data descriptors from the write buffer in the disk spanning volume
|
||||
// that is one-disk only (do not remove from password encrypted files)
|
||||
bool CZipCentralDir::RemoveDataDescr(bool bFromBuffer)
|
||||
{
|
||||
CZipAutoHandle ah;
|
||||
char* pFile = NULL;
|
||||
DWORD uSize;
|
||||
if (bFromBuffer)
|
||||
{
|
||||
uSize = m_pStorage->m_uBytesInWriteBuffer;
|
||||
pFile = m_pStorage->m_pWriteBuffer;
|
||||
}
|
||||
else
|
||||
{
|
||||
uSize = m_pStorage->m_pFile->GetLength();
|
||||
if (!ah.CreateMapping((HANDLE)m_pStorage->m_pFile->m_hFile))
|
||||
return false;
|
||||
pFile = (char*)ah.m_pFileMap;
|
||||
}
|
||||
|
||||
DWORD uOffsetToChange = 4;
|
||||
DWORD uToCopy = 0;
|
||||
DWORD uPosInBuffer = 0;
|
||||
DWORD uExtraHeaderLen;
|
||||
// this will work providing the order in the m_headers is the same as
|
||||
// in the archive
|
||||
for (int i = 0; i < m_headers.GetSize(); i++)
|
||||
{
|
||||
// update the flag value in the local and central header
|
||||
// int uDataDescr = (m_headers[i]->m_uFlag & 8) ? (4 + 12) : 0;
|
||||
|
||||
CZipFileHeader* pHeader = m_headers[i];
|
||||
|
||||
|
||||
char* pSour = pFile + pHeader->m_uOffset;
|
||||
|
||||
if (!pHeader->IsEncrypted())
|
||||
{
|
||||
// removing data descriptor
|
||||
pHeader->m_uFlag &= ~8;
|
||||
// update local header:
|
||||
// write modified flag in the local header
|
||||
memcpy(pSour + 6, &pHeader->m_uFlag, 2);
|
||||
uExtraHeaderLen = 4/*ext. header signature*/ + 12/*data descriptor*/;
|
||||
}
|
||||
else
|
||||
// do not remove data descriptors from encrypted files
|
||||
uExtraHeaderLen = 0;
|
||||
|
||||
// update crc32 and sizes' values
|
||||
pHeader->GetCrcAndSizes(pSour+ 14);
|
||||
|
||||
uToCopy = (i == (m_headers.GetSize() - 1) ? uSize : m_headers[i + 1]->m_uOffset)
|
||||
- pHeader->m_uOffset - uExtraHeaderLen;
|
||||
|
||||
memmove(pFile + uPosInBuffer, pSour, uToCopy);
|
||||
|
||||
uPosInBuffer += uToCopy;
|
||||
pHeader->m_uOffset -= uOffsetToChange;
|
||||
uOffsetToChange += uExtraHeaderLen;
|
||||
}
|
||||
|
||||
if (bFromBuffer)
|
||||
m_pStorage->m_uBytesInWriteBuffer = uPosInBuffer;
|
||||
else
|
||||
{
|
||||
m_pStorage->m_iBytesWritten = uPosInBuffer;
|
||||
ah.RemoveMapping();
|
||||
m_pStorage->m_pFile->SetLength(uPosInBuffer);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void CZipCentralDir::RemoveHeaders()
|
||||
{
|
||||
for (int i = 0; i < m_headers.GetSize(); i++)
|
||||
delete m_headers[i];
|
||||
m_headers.RemoveAll();
|
||||
}
|
||||
|
||||
void CZipCentralDir::ConvertAll()
|
||||
{
|
||||
ASSERT(!m_bConvertAfterOpen);
|
||||
for (int i = 0; i < m_headers.GetSize(); i++)
|
||||
ConvertFileName(true, false, m_headers[i]);
|
||||
m_bConvertAfterOpen = true;
|
||||
}
|
||||
|
||||
|
||||
void CZipCentralDir::BuildFindFastArray()
|
||||
{
|
||||
m_findarray.RemoveAll();// just in case
|
||||
for (int i = 0; i < m_headers.GetSize(); i++)
|
||||
InsertFindFastElement(m_headers[i], (WORD)i);
|
||||
}
|
||||
|
||||
void CZipCentralDir::InsertFindFastElement(CZipFileHeader* pHeader, WORD uIndex)
|
||||
{
|
||||
CString fileName = pHeader->GetFileName();
|
||||
|
||||
|
||||
int iSize = m_findarray.GetSize();
|
||||
|
||||
// Our initial binary search range encompasses the entire array of filenames:
|
||||
int start = 0;
|
||||
int end = iSize;
|
||||
|
||||
// Keep halving our search range until we find the right place
|
||||
// to insert the new element:
|
||||
while ( start < end )
|
||||
{
|
||||
// Find the midpoint of the search range:
|
||||
int midpoint = ( start + end ) / 2;
|
||||
|
||||
// Compare the filename with the filename at the midpoint of the current search range:
|
||||
int result = CompareElement(fileName, (WORD)midpoint, true);
|
||||
|
||||
// If our filename is larger, it must fall in the first half of the search range:
|
||||
if ( result > 0 )
|
||||
{
|
||||
end = midpoint;
|
||||
}
|
||||
|
||||
// If it's smaller, it must fall in the last half:
|
||||
else if ( result < 0 )
|
||||
{
|
||||
start = midpoint + 1;
|
||||
}
|
||||
|
||||
// If they're equal, we can go ahead and insert here:
|
||||
else
|
||||
{
|
||||
start = midpoint; break;
|
||||
}
|
||||
}
|
||||
m_findarray.InsertAt(start, CZipFindFast(pHeader, WORD(uIndex == -1 ? iSize : uIndex /* just in case */)));
|
||||
}
|
||||
|
||||
int CZipCentralDir::FindFileNameIndex(LPCTSTR lpszFileName, bool bCaseSensitive)
|
||||
{
|
||||
int start = 0;
|
||||
int end = m_findarray.GetUpperBound();
|
||||
|
||||
// Keep halving our search range until we find the given element:
|
||||
while ( start <= end )
|
||||
{
|
||||
// Find the midpoint of the search range:
|
||||
int midpoint = ( start + end ) / 2;
|
||||
|
||||
// Compare the given filename with the filename at the midpoint of the search range:
|
||||
int result = CompareElement(lpszFileName, (WORD)midpoint, bCaseSensitive);
|
||||
|
||||
// If our filename is smaller, it must fall in the first half of the search range:
|
||||
if ( result > 0 )
|
||||
{
|
||||
end = midpoint - 1;
|
||||
}
|
||||
|
||||
// If it's larger, it must fall in the last half:
|
||||
else if ( result < 0 )
|
||||
{
|
||||
start = midpoint + 1;
|
||||
}
|
||||
|
||||
// If they're equal, return the result:
|
||||
else
|
||||
{
|
||||
return midpoint;
|
||||
}
|
||||
}
|
||||
|
||||
// Signal failure:
|
||||
return -1;
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
// ZipCentralDir.h: interface for the CZipCentralDir class.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2000 Tadeusz Dracz.
|
||||
// For conditions of distribution and use, see copyright notice in ZipArchive.h
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if !defined(AFX_ZipCentralDir_H__859029E8_8927_4717_9D4B_E26E5DA12BAE__INCLUDED_)
|
||||
#define AFX_ZipCentralDir_H__859029E8_8927_4717_9D4B_E26E5DA12BAE__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
#include "ZipException.h"
|
||||
#include <afxtempl.h>
|
||||
#include "ZipFileHeader.h"
|
||||
#include "ZipAutoBuffer.h"
|
||||
|
||||
/**
|
||||
Used in fast finding files by the filename.
|
||||
\see CZipCentralDir::m_findarray
|
||||
\see CZipArchive::FindFile
|
||||
*/
|
||||
struct CZipFindFast
|
||||
{
|
||||
CZipFindFast()
|
||||
{
|
||||
m_uIndex = 0;
|
||||
m_pHeader= NULL;
|
||||
}
|
||||
CZipFindFast(CZipFileHeader* pHeader, WORD uIndex):m_pHeader(pHeader), m_uIndex(uIndex){}
|
||||
/**
|
||||
We extract a name from it.
|
||||
*/
|
||||
CZipFileHeader* m_pHeader;
|
||||
|
||||
/**
|
||||
The index in the central directory of the \e m_pHeader.
|
||||
*/
|
||||
WORD m_uIndex;
|
||||
};
|
||||
|
||||
|
||||
class CZipCentralDir
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
// end of central dir signature 4 bytes (0x06054b50)
|
||||
char m_szSignature[4];
|
||||
// number of this disk 2 bytes
|
||||
WORD m_uThisDisk;
|
||||
// number of the disk with the
|
||||
// start of the central directory 2 bytes
|
||||
WORD m_uDiskWithCD;
|
||||
// total number of entries in
|
||||
// the central dir on this disk 2 bytes
|
||||
WORD m_uDiskEntriesNo;
|
||||
// total number of entries in
|
||||
// the central dir 2 bytes
|
||||
WORD m_uEntriesNumber;
|
||||
// size of the central directory 4 bytes
|
||||
DWORD m_uSize;
|
||||
// offset of start of central
|
||||
// directory with respect to
|
||||
// the starting disk number 4 bytes
|
||||
DWORD m_uOffset;
|
||||
// zipfile comment length 2 bytes
|
||||
// WORD m_uCommentSize;
|
||||
// zipfile comment (variable size)
|
||||
CZipAutoBuffer m_pszComment;
|
||||
bool m_bFindFastEnabled;
|
||||
CZipFileHeader* m_pOpenedFile;
|
||||
void RemoveFile(WORD uIndex);
|
||||
void Clear(bool bEverything = true);
|
||||
CZipStorage* m_pStorage;
|
||||
DWORD m_uCentrDirPos;
|
||||
DWORD m_uBytesBeforeZip;
|
||||
CZipCentralDir();
|
||||
virtual ~CZipCentralDir();
|
||||
void CloseFile();
|
||||
void OpenFile(WORD uIndex);
|
||||
bool IsValidIndex(WORD uIndex);
|
||||
void Read();
|
||||
void Init();
|
||||
void CloseNewFile();
|
||||
void Write();
|
||||
int m_iBufferSize;
|
||||
bool m_bOnDisk;
|
||||
static char m_gszSignature[];
|
||||
CTypedPtrArray<CPtrArray, CZipFileHeader*> m_headers;
|
||||
CZipAutoBuffer m_pLocalExtraField;
|
||||
void AddNewFile(CZipFileHeader & header);
|
||||
void RemoveFromDisk();
|
||||
DWORD GetSize(bool bWhole = false);
|
||||
CArray<CZipFindFast, CZipFindFast> m_findarray;
|
||||
int FindFileNameIndex(LPCTSTR lpszFileName, bool bCaseSensitive);
|
||||
void BuildFindFastArray();
|
||||
/**
|
||||
- If \c true, the conversion of the filenames takes
|
||||
place after opening the archive (after reading the central directory
|
||||
from the file), and before writing the central directory back to
|
||||
the archive.
|
||||
- If \c false, the conversion takes place on each call to CZipArchive::GetFileInfo
|
||||
|
||||
Set it to \c true when you plan to use CZipArchive::FindFile or get the stored files information. <BR>
|
||||
Set it to \c false when you plan mostly to only modify the archive.
|
||||
|
||||
\b Default: \c true
|
||||
\note Set it before opening the archive.
|
||||
\see ConvertFileName
|
||||
*/
|
||||
bool m_bConvertAfterOpen;
|
||||
|
||||
/**
|
||||
Convert the filename of the CZipFileHeader.
|
||||
\param bFromZip
|
||||
if \c true, convert from archive format
|
||||
\param bAfterOpen
|
||||
if \c true, called after opening the archive or before closing
|
||||
\param pHeader
|
||||
the header to have filename converted; if \c NULL convert the currently
|
||||
opened file
|
||||
\see m_bConvertAfterOpen
|
||||
*/
|
||||
void ConvertFileName(bool bFromZip, bool bAfterOpen, CZipFileHeader* pHeader = NULL)
|
||||
{
|
||||
if (bAfterOpen != m_bConvertAfterOpen)
|
||||
return;
|
||||
if (!pHeader)
|
||||
{
|
||||
pHeader = m_pOpenedFile;
|
||||
ASSERT(pHeader);
|
||||
}
|
||||
pHeader->AnsiOem(!bFromZip);
|
||||
pHeader->SlashChange(bFromZip);
|
||||
}
|
||||
void ConvertAll();
|
||||
protected:
|
||||
void InsertFindFastElement(CZipFileHeader* pHeader, WORD uIndex);
|
||||
void RemoveHeaders();
|
||||
bool RemoveDataDescr(bool bFromBuffer);
|
||||
DWORD WriteCentralEnd();
|
||||
void WriteHeaders();
|
||||
void ReadHeaders();
|
||||
void ThrowError(int err);
|
||||
DWORD Locate();
|
||||
int CompareElement(LPCTSTR lpszFileName, WORD uIndex, bool bCaseSensitive)
|
||||
{
|
||||
return bCaseSensitive ? m_findarray[uIndex].m_pHeader->GetFileName().Collate(lpszFileName)
|
||||
: m_findarray[uIndex].m_pHeader->GetFileName().CollateNoCase(lpszFileName);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif // !defined(AFX_ZipCentralDir_H__859029E8_8927_4717_9D4B_E26E5DA12BAE__INCLUDED_)
|
||||
@@ -0,0 +1,78 @@
|
||||
// ZipException.cpp: implementation of the CZipException class.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2000 Tadeusz Dracz.
|
||||
// For conditions of distribution and use, see copyright notice in ZipArchive.h
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "ZipException.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Construction/Destruction
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
IMPLEMENT_DYNAMIC( CZipException, CException)
|
||||
|
||||
CZipException::CZipException(int iCause, LPCTSTR lpszZipName):CException(TRUE)
|
||||
{
|
||||
m_iCause = iCause;
|
||||
|
||||
if (lpszZipName)
|
||||
m_szFileName = lpszZipName;
|
||||
}
|
||||
|
||||
CZipException::~CZipException()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void AfxThrowZipException(int iZipError, LPCTSTR lpszZipName)
|
||||
{
|
||||
throw new CZipException(CZipException::ZipErrToCause(iZipError), lpszZipName);
|
||||
}
|
||||
|
||||
int CZipException::ZipErrToCause(int iZipError)
|
||||
{
|
||||
switch (iZipError)
|
||||
{
|
||||
case 2://Z_NEED_DICT:
|
||||
return CZipException::needDict;
|
||||
case 1://Z_STREAM_END:
|
||||
return CZipException::streamEnd;
|
||||
case -1://Z_ERRNO:
|
||||
return CZipException::errNo;
|
||||
case -2://Z_STREAM_ERROR:
|
||||
return CZipException::streamError;
|
||||
case -3://Z_DATA_ERROR:
|
||||
return CZipException::dataError;
|
||||
case -4://Z_MEM_ERROR:
|
||||
return CZipException::memError;
|
||||
case -5://Z_BUF_ERROR:
|
||||
return CZipException::bufError;
|
||||
case -6://Z_VERSION_ERROR:
|
||||
return CZipException::versionError;
|
||||
case ZIP_BADZIPFILE:
|
||||
return CZipException::badZipFile;
|
||||
case ZIP_BADCRC:
|
||||
return CZipException::badCrc;
|
||||
case ZIP_ABORTED:
|
||||
return CZipException::aborted;
|
||||
case ZIP_NOCALLBACK:
|
||||
return CZipException::noCallback;
|
||||
case ZIP_NONREMOVABLE:
|
||||
return CZipException::nonRemovable;
|
||||
case ZIP_TOOMANYVOLUMES:
|
||||
return CZipException::tooManyVolumes;
|
||||
case ZIP_TOOLONGFILENAME:
|
||||
return CZipException::tooLongFileName;
|
||||
case ZIP_BADPASSWORD:
|
||||
return CZipException::badPassword;
|
||||
case ZIP_CDIR_NOTFOUND:
|
||||
return CZipException::cdirNotFound;
|
||||
|
||||
|
||||
default:
|
||||
return CZipException::generic;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
// ZipException.h: interface for the CZipException class.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2000 Tadeusz Dracz.
|
||||
// For conditions of distribution and use, see copyright notice in ZipArchive.h
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if !defined(AFX_ZIPEXCEPTION_H__E3546921_D728_11D3_B7C7_E77339672847__INCLUDED_)
|
||||
#define AFX_ZIPEXCEPTION_H__E3546921_D728_11D3_B7C7_E77339672847__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
typedef unsigned short uShort;
|
||||
// errors number definitions
|
||||
#define ZIP_BADZIPFILE (-101)
|
||||
#define ZIP_BADCRC (-102)
|
||||
#define ZIP_NOCALLBACK (-103)
|
||||
#define ZIP_ABORTED (-104)
|
||||
#define ZIP_NONREMOVABLE (-105)
|
||||
#define ZIP_TOOMANYVOLUMES (-106)
|
||||
#define ZIP_TOOLONGFILENAME (-107)
|
||||
#define ZIP_BADPASSWORD (-108)
|
||||
#define ZIP_CDIR_NOTFOUND (-109)
|
||||
|
||||
class CZipException : public CException
|
||||
{
|
||||
public:
|
||||
DECLARE_DYNAMIC(CZipException)
|
||||
// convert zlib library and internal error code to a ZipException code
|
||||
static int ZipErrToCause(int iZipError);
|
||||
// name of the zip file where the error occured
|
||||
CString m_szFileName;
|
||||
|
||||
enum
|
||||
{
|
||||
noError, // no error
|
||||
generic, // unknown error
|
||||
streamEnd, // zlib library errors
|
||||
needDict, //
|
||||
errNo, //
|
||||
streamError, //
|
||||
dataError, //
|
||||
memError, //
|
||||
bufError, //
|
||||
versionError, //
|
||||
badZipFile, // damaged or not a zip file
|
||||
badCrc, // crc mismatched
|
||||
noCallback, // no callback function set
|
||||
aborted, // disk change callback function returned false
|
||||
nonRemovable, // the disk selected for pkSpan archive is non removable
|
||||
tooManyVolumes, // limit of the maximum volumes reached (999)
|
||||
tooLongFileName, // the file name of the file added to the archive is too long
|
||||
badPassword, // incorrect password set for the file being decrypted
|
||||
cdirNotFound, ///< the central directory was not found in the archive
|
||||
dirWithSize // during testing: found the directory with the size greater than 0
|
||||
};
|
||||
// cause - takes one of the codes above
|
||||
int m_iCause;
|
||||
CZipException(int iCause = generic, LPCTSTR lpszZipName = NULL);
|
||||
virtual ~CZipException();
|
||||
|
||||
};
|
||||
|
||||
// throw zip exception
|
||||
// Parameters:
|
||||
// iZipError - zlib or internal error code
|
||||
// lpszZipName - name of the file where the error occured
|
||||
void AfxThrowZipException(int iZipError = 1000, LPCTSTR lpszZipName = NULL);
|
||||
|
||||
#endif // !defined(AFX_ZIPEXCEPTION_H__E3546921_D728_11D3_B7C7_E77339672847__INCLUDED_)
|
||||
@@ -0,0 +1,329 @@
|
||||
// ZipFileHeader.cpp: implementation of the CZipFileHeader class.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2000 Tadeusz Dracz.
|
||||
// For conditions of distribution and use, see copyright notice in ZipArchive.h
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "ZipFileHeader.h"
|
||||
#include "zlib.h"
|
||||
#include "ZipAutoBuffer.h"
|
||||
#include "ZipArchive.h"
|
||||
|
||||
#define ZipFileHeaderSIZE 46
|
||||
#define LOCALZipFileHeaderSIZE 30
|
||||
#define VERSIONMADEBY 20
|
||||
#define ENCR_HEADER_LEN 12
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Construction/Destruction
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
char CZipFileHeader::m_gszSignature[] = {0x50, 0x4b, 0x01, 0x02};
|
||||
char CZipFileHeader::m_gszLocalSignature[] = {0x50, 0x4b, 0x03, 0x04};
|
||||
CZipFileHeader::CZipFileHeader()
|
||||
{
|
||||
m_uExternalAttr = FILE_ATTRIBUTE_ARCHIVE;
|
||||
m_uModDate = m_uModTime = m_uInternalAttr = 0;
|
||||
m_uMethod = Z_DEFLATED;
|
||||
}
|
||||
|
||||
CZipFileHeader::~CZipFileHeader()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// read the header from the central dir
|
||||
bool CZipFileHeader::Read(CZipStorage *pStorage)
|
||||
{
|
||||
// // just in case
|
||||
// m_pszComment.Release();
|
||||
// m_pszFileName.Release();
|
||||
WORD uFileNameSize, uCommentSize, uExtraFieldSize;
|
||||
CZipAutoBuffer buf(ZipFileHeaderSIZE);
|
||||
pStorage->Read(buf, ZipFileHeaderSIZE, true);
|
||||
memcpy(&m_szSignature, buf, 4);
|
||||
memcpy(&m_uVersionMadeBy, buf + 4, 2);
|
||||
memcpy(&m_uVersionNeeded, buf + 6, 2);
|
||||
memcpy(&m_uFlag, buf + 8, 2);
|
||||
memcpy(&m_uMethod, buf + 10, 2);
|
||||
memcpy(&m_uModTime, buf + 12, 2);
|
||||
memcpy(&m_uModDate, buf + 14, 2);
|
||||
memcpy(&m_uCrc32, buf + 16, 4);
|
||||
memcpy(&m_uComprSize, buf + 20, 4);
|
||||
memcpy(&m_uUncomprSize, buf + 24, 4);
|
||||
memcpy(&uFileNameSize, buf + 28, 2);
|
||||
memcpy(&uExtraFieldSize, buf + 30, 2);
|
||||
memcpy(&uCommentSize, buf + 32, 2);
|
||||
memcpy(&m_uDiskStart, buf + 34, 2);
|
||||
memcpy(&m_uInternalAttr, buf + 36, 2);
|
||||
memcpy(&m_uExternalAttr, buf + 38, 4);
|
||||
memcpy(&m_uOffset, buf + 42, 4);
|
||||
buf.Release();
|
||||
|
||||
if (memcmp(m_szSignature, m_gszSignature, 4) != 0)
|
||||
return false;
|
||||
|
||||
int iCurDsk = pStorage->GetCurrentDisk();
|
||||
m_pszFileName.Allocate(uFileNameSize); // don't add NULL at the end
|
||||
pStorage->m_pFile->Read(m_pszFileName, uFileNameSize);
|
||||
if (uExtraFieldSize)
|
||||
{
|
||||
ASSERT(!m_pExtraField.IsAllocated());
|
||||
m_pExtraField.Allocate(uExtraFieldSize);
|
||||
pStorage->m_pFile->Read(m_pExtraField, uExtraFieldSize);
|
||||
}
|
||||
if (uCommentSize)
|
||||
{
|
||||
m_pszComment.Allocate(uCommentSize);
|
||||
pStorage->m_pFile->Read(m_pszComment, uCommentSize);
|
||||
}
|
||||
|
||||
return pStorage->GetCurrentDisk() == iCurDsk; // check that the while header is on the one disk
|
||||
}
|
||||
|
||||
// return CTime representation of m_uModDate, m_uModTime
|
||||
CTime CZipFileHeader::GetTime()
|
||||
{
|
||||
return CTime(m_uModDate, m_uModTime);
|
||||
}
|
||||
|
||||
// write the header to the central dir
|
||||
DWORD CZipFileHeader::Write(CZipStorage *pStorage)
|
||||
{
|
||||
WORD uFileNameSize = GetFileNameSize(), uCommentSize = GetCommentSize(),
|
||||
uExtraFieldSize = GetExtraFieldSize();
|
||||
DWORD iSize = GetSize();
|
||||
CZipAutoBuffer buf(iSize);
|
||||
memcpy(buf, &m_szSignature, 4);
|
||||
memcpy(buf + 4, &m_uVersionMadeBy, 2);
|
||||
memcpy(buf + 6, &m_uVersionNeeded, 2);
|
||||
memcpy(buf + 8, &m_uFlag, 2);
|
||||
memcpy(buf + 10, &m_uMethod, 2);
|
||||
memcpy(buf + 12, &m_uModTime, 2);
|
||||
memcpy(buf + 14, &m_uModDate, 2);
|
||||
memcpy(buf + 16, &m_uCrc32, 4);
|
||||
memcpy(buf + 20, &m_uComprSize, 4);
|
||||
memcpy(buf + 24, &m_uUncomprSize, 4);
|
||||
memcpy(buf + 28, &uFileNameSize, 2);
|
||||
memcpy(buf + 30, &uExtraFieldSize, 2);
|
||||
memcpy(buf + 32, &uCommentSize, 2);
|
||||
memcpy(buf + 34, &m_uDiskStart, 2);
|
||||
memcpy(buf + 36, &m_uInternalAttr, 2);
|
||||
memcpy(buf + 38, &m_uExternalAttr, 4);
|
||||
memcpy(buf + 42, &m_uOffset, 4);
|
||||
|
||||
memcpy(buf + 46, m_pszFileName, uFileNameSize);
|
||||
|
||||
if (uExtraFieldSize)
|
||||
memcpy(buf + 46 + uFileNameSize, m_pExtraField, uExtraFieldSize);
|
||||
|
||||
if (uCommentSize)
|
||||
memcpy(buf + 46 + uFileNameSize + uExtraFieldSize, m_pszComment, uCommentSize);
|
||||
|
||||
pStorage->Write(buf, iSize, true);
|
||||
return iSize;
|
||||
}
|
||||
|
||||
// read local header
|
||||
bool CZipFileHeader::ReadLocal(CZipStorage *pStorage, WORD& iLocExtrFieldSize)
|
||||
{
|
||||
char buf[LOCALZipFileHeaderSIZE];
|
||||
pStorage->Read(buf, LOCALZipFileHeaderSIZE, true);
|
||||
if (memcmp(buf, m_gszLocalSignature, 4) != 0)
|
||||
return false;
|
||||
|
||||
bool bIsDataDescr = (((WORD)*(buf + 6)) & 8) != 0;
|
||||
|
||||
WORD uFileNameSize = GetFileNameSize();
|
||||
if ((memcmp(buf + 6, &m_uFlag, 2) != 0)
|
||||
||(memcmp(buf + 8, &m_uMethod, 2) != 0)
|
||||
|| (m_uMethod && (m_uMethod != Z_DEFLATED))
|
||||
|| (memcmp(buf + 26, &uFileNameSize, 2) != 0))
|
||||
return false;
|
||||
|
||||
// jeszcze mo¿naby porównaæ nazwy plików
|
||||
|
||||
if (!bIsDataDescr/* || !pStorage->IsSpanMode()*/)
|
||||
if (!CheckCrcAndSizes(buf + 14))
|
||||
return false;
|
||||
|
||||
memcpy(&iLocExtrFieldSize, buf + 28, 2);
|
||||
pStorage->m_pFile->Seek(uFileNameSize, CFile::current);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// set the m_uModDate, m_uModTime values using CTime object
|
||||
void CZipFileHeader::SetTime(const CTime &time)
|
||||
{
|
||||
WORD year = (WORD)time.GetYear();
|
||||
if (year <= 1980)
|
||||
year = 0;
|
||||
else
|
||||
year -= 1980;
|
||||
m_uModDate = (WORD) (time.GetDay() + (time.GetMonth() << 5) + (year << 9));
|
||||
m_uModTime = (WORD) ((time.GetSecond() >> 1) + (time.GetMinute() << 5) +
|
||||
(time.GetHour() << 11));
|
||||
}
|
||||
// the buffer contains crc32, compressed and uncompressed sizes to be compared
|
||||
// with the actual values
|
||||
bool CZipFileHeader::CheckCrcAndSizes(char *pBuf)
|
||||
{
|
||||
return (memcmp(pBuf, &m_uCrc32, 4) == 0) && (memcmp(pBuf + 4, &m_uComprSize, 4) == 0)
|
||||
&& (memcmp(pBuf + 8, &m_uUncomprSize, 4) == 0);
|
||||
}
|
||||
|
||||
// write the local header
|
||||
void CZipFileHeader::WriteLocal(CZipStorage& storage)
|
||||
{
|
||||
// extra field is local by now
|
||||
WORD uFileNameSize = GetFileNameSize(), uExtraFieldSize = GetExtraFieldSize();
|
||||
DWORD iLocalSize = LOCALZipFileHeaderSIZE + uExtraFieldSize + uFileNameSize;
|
||||
CZipAutoBuffer buf(iLocalSize);
|
||||
memcpy(buf, m_gszLocalSignature, 4);
|
||||
memcpy(buf + 4, &m_uVersionNeeded, 2);
|
||||
memcpy(buf + 6, &m_uFlag, 2);
|
||||
memcpy(buf + 8, &m_uMethod, 2);
|
||||
memcpy(buf + 10, &m_uModTime, 2);
|
||||
memcpy(buf + 12, &m_uModDate, 2);
|
||||
memcpy(buf + 14, &m_uCrc32, 4);
|
||||
memcpy(buf + 18, &m_uComprSize, 4);
|
||||
memcpy(buf + 22, &m_uUncomprSize, 4);
|
||||
memcpy(buf + 26, &uFileNameSize, 2);
|
||||
memcpy(buf + 28, &uExtraFieldSize, 2);
|
||||
memcpy(buf + 30, m_pszFileName, uFileNameSize);
|
||||
memcpy(buf + 30 + uFileNameSize, m_pExtraField, uExtraFieldSize);
|
||||
|
||||
// possible disk change before writting to the file in the disk spanning mode
|
||||
// so write the local header first
|
||||
storage.Write(buf, iLocalSize, true);
|
||||
// it was only local information, use CZipArchive::SetExtraField to set the file extra field in the central directory
|
||||
m_pExtraField.Release();
|
||||
|
||||
m_uDiskStart = (WORD)storage.GetCurrentDisk();
|
||||
m_uOffset = storage.GetPosition() - iLocalSize;
|
||||
}
|
||||
|
||||
// prepare the data before adding a new file
|
||||
bool CZipFileHeader::PrepareData(int iLevel, bool bExtraHeader, bool bEncrypted)
|
||||
{
|
||||
memcpy(m_szSignature, m_gszSignature, 4);
|
||||
m_uInternalAttr = 0;
|
||||
m_uVersionMadeBy = VERSIONMADEBY;
|
||||
m_uVersionNeeded = 20;
|
||||
|
||||
m_uCrc32 = 0;
|
||||
m_uComprSize = 0;
|
||||
m_uUncomprSize = 0;
|
||||
if (iLevel == 0)
|
||||
m_uMethod = 0;
|
||||
|
||||
if ((m_uMethod != Z_DEFLATED) && (m_uMethod != 0))
|
||||
m_uMethod = Z_DEFLATED;
|
||||
|
||||
m_uFlag = 0;
|
||||
if (m_uMethod == Z_DEFLATED)
|
||||
switch (iLevel)
|
||||
{
|
||||
case 1:
|
||||
m_uFlag |= 6;
|
||||
break;
|
||||
case 2:
|
||||
m_uFlag |= 4;
|
||||
break;
|
||||
case 8:
|
||||
case 9:
|
||||
m_uFlag |= 2;
|
||||
break;
|
||||
}
|
||||
|
||||
if (bExtraHeader)
|
||||
m_uFlag |= 8; // data descriptor present
|
||||
|
||||
if (bEncrypted)
|
||||
{
|
||||
m_uComprSize = ENCR_HEADER_LEN; // encrypted header
|
||||
m_uFlag |= 9; // encrypted file
|
||||
}
|
||||
|
||||
return !(m_pszComment.GetSize() > USHRT_MAX || m_pszFileName.GetSize() > USHRT_MAX
|
||||
|| m_pExtraField.GetSize() > USHRT_MAX);
|
||||
}
|
||||
|
||||
// fill the buffer with the current values
|
||||
void CZipFileHeader::GetCrcAndSizes(char * pBuffer)
|
||||
{
|
||||
memcpy(pBuffer, &m_uCrc32, 4);
|
||||
memcpy(pBuffer + 4, &m_uComprSize, 4);
|
||||
memcpy(pBuffer + 8, &m_uUncomprSize, 4);
|
||||
}
|
||||
|
||||
DWORD CZipFileHeader::GetSize()
|
||||
{
|
||||
return ZipFileHeaderSIZE + GetExtraFieldSize() + GetFileNameSize() + GetCommentSize();
|
||||
}
|
||||
|
||||
|
||||
bool CZipFileHeader::IsEncrypted()
|
||||
{
|
||||
return (m_uFlag & (WORD) 1) != 0;
|
||||
}
|
||||
|
||||
bool CZipFileHeader::IsDataDescr()
|
||||
{
|
||||
return (m_uFlag & (WORD) 8) != 0;
|
||||
}
|
||||
|
||||
bool CZipFileHeader::SetComment(LPCTSTR lpszComment)
|
||||
{
|
||||
return CZipArchive::WideToSingle(lpszComment, m_pszComment) != -1;
|
||||
}
|
||||
|
||||
CString CZipFileHeader::GetComment()
|
||||
{
|
||||
CString temp;
|
||||
CZipArchive::SingleToWide(m_pszComment, temp);
|
||||
return temp;
|
||||
|
||||
}
|
||||
|
||||
bool CZipFileHeader::SetFileName(LPCTSTR lpszFileName)
|
||||
{
|
||||
return CZipArchive::WideToSingle(lpszFileName, m_pszFileName) != -1;
|
||||
}
|
||||
|
||||
CString CZipFileHeader::GetFileName()
|
||||
{
|
||||
CString temp;
|
||||
CZipArchive::SingleToWide(m_pszFileName, temp);
|
||||
return temp;
|
||||
}
|
||||
|
||||
|
||||
void CZipFileHeader::SlashChange(bool bWindowsStyle)
|
||||
{
|
||||
char t1 = '\\', t2 = '/', c1, c2;
|
||||
if (bWindowsStyle)
|
||||
{
|
||||
c1 = t1;
|
||||
c2 = t2;
|
||||
}
|
||||
else
|
||||
{
|
||||
c1 = t2;
|
||||
c2 = t1;
|
||||
}
|
||||
for (DWORD i = 0; i < m_pszFileName.GetSize(); i++)
|
||||
{
|
||||
if (m_pszFileName[i] == c2)
|
||||
m_pszFileName[i] = c1;
|
||||
}
|
||||
}
|
||||
|
||||
void CZipFileHeader::AnsiOem(bool bAnsiToOem)
|
||||
{
|
||||
if (bAnsiToOem)
|
||||
CharToOemBuffA(m_pszFileName, m_pszFileName, m_pszFileName.GetSize());
|
||||
else
|
||||
OemToCharBuffA(m_pszFileName, m_pszFileName, m_pszFileName.GetSize());
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
// ZipFileHeader.h: interface for the CZipFileHeader class.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2000 Tadeusz Dracz.
|
||||
// For conditions of distribution and use, see copyright notice in ZipArchive.h
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if !defined(AFX_ZipFileHeader_H__0081FC65_C9C9_4D48_AF72_DBF37DF5E0CF__INCLUDED_)
|
||||
#define AFX_ZipFileHeader_H__0081FC65_C9C9_4D48_AF72_DBF37DF5E0CF__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
|
||||
#include "ZipException.h"
|
||||
#include "ZipStorage.h"
|
||||
#include "ZipAutoBuffer.h"
|
||||
|
||||
class CZipFileHeader
|
||||
{
|
||||
public:
|
||||
// convert characters in the filename from oem to ansi or vice-versa
|
||||
void AnsiOem(bool bAnsiToOem);
|
||||
// change slash to backslash or vice-versa
|
||||
void SlashChange(bool bWindowsStyle);
|
||||
// return the filename size in characters (without NULL);
|
||||
WORD GetFileNameSize(){return (WORD)m_pszFileName.GetSize();}
|
||||
// return the comment size in characters (without NULL);
|
||||
WORD GetCommentSize(){return (WORD)m_pszComment.GetSize();}
|
||||
// return the extra field size in characters (without NULL);
|
||||
WORD GetExtraFieldSize(){return (WORD)m_pExtraField.GetSize();}
|
||||
|
||||
CString GetFileName();
|
||||
// return true if confersion from unicode to single byte was successful
|
||||
bool SetFileName(LPCTSTR lpszFileName);
|
||||
CString GetComment();
|
||||
// return true if confersion from unicode to single byte was successful
|
||||
bool SetComment(LPCTSTR lpszComment);
|
||||
// return true if the data descriptor is present
|
||||
bool IsDataDescr();
|
||||
// return true if the file is encrypted
|
||||
bool IsEncrypted();
|
||||
// central file header signature 4 bytes (0x02014b50)
|
||||
char m_szSignature[4];
|
||||
// version made by 2 bytes
|
||||
WORD m_uVersionMadeBy;
|
||||
// version needed to extract 2 bytes
|
||||
WORD m_uVersionNeeded;
|
||||
// general purpose bit flag 2 bytes
|
||||
WORD m_uFlag;
|
||||
// compression method 2 bytes
|
||||
WORD m_uMethod;
|
||||
// last mod file time 2 bytes
|
||||
WORD m_uModTime;
|
||||
// last mod file date 2 bytes
|
||||
WORD m_uModDate;
|
||||
// crc-32 4 bytes
|
||||
DWORD m_uCrc32;
|
||||
// compressed size 4 bytes
|
||||
DWORD m_uComprSize;
|
||||
// uncompressed size 4 bytes
|
||||
DWORD m_uUncomprSize;
|
||||
// filename length 2 bytes
|
||||
// WORD m_uFileNameSize;
|
||||
// extra field length 2 bytes
|
||||
// WORD m_uExtraFieldSize;
|
||||
// file comment length 2 bytes
|
||||
// WORD m_uCommentSize;
|
||||
// disk number start 2 bytes
|
||||
WORD m_uDiskStart;
|
||||
// internal file attributes 2 bytes
|
||||
WORD m_uInternalAttr;
|
||||
// external file attributes 4 bytes
|
||||
DWORD m_uExternalAttr;
|
||||
// relative offset of local header 4 bytes
|
||||
DWORD m_uOffset;
|
||||
// extra field (variable size)
|
||||
CZipAutoBuffer m_pExtraField;
|
||||
|
||||
CZipFileHeader();
|
||||
virtual ~CZipFileHeader();
|
||||
CTime GetTime();
|
||||
void SetTime(const CTime& time);
|
||||
static char m_gszSignature[];
|
||||
static char m_gszLocalSignature[];
|
||||
// return the total size of the structure as stored in the central directory
|
||||
DWORD GetSize();
|
||||
protected:
|
||||
// filename (variable size)
|
||||
CZipAutoBuffer m_pszFileName;
|
||||
// file comment (variable size)
|
||||
CZipAutoBuffer m_pszComment;
|
||||
|
||||
void GetCrcAndSizes(char * pBuffer);
|
||||
bool PrepareData(int iLevel, bool bExtraHeader, bool bEncrypted);
|
||||
void WriteLocal(CZipStorage& storage);
|
||||
bool CheckCrcAndSizes(char* pBuf);
|
||||
friend class CZipCentralDir;
|
||||
friend class CZipArchive;
|
||||
bool Read(CZipStorage *pStorage);
|
||||
bool ReadLocal(CZipStorage *pStorage, WORD& iLocExtrFieldSize);
|
||||
DWORD Write(CZipStorage *pStorage);
|
||||
|
||||
};
|
||||
|
||||
#endif // !defined(AFX_ZipFileHeader_H__0081FC65_C9C9_4D48_AF72_DBF37DF5E0CF__INCLUDED_)
|
||||
@@ -0,0 +1,28 @@
|
||||
// ZipInternalInfo.cpp: implementation of the CZipInternalInfo class.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2000 Tadeusz Dracz.
|
||||
// For conditions of distribution and use, see copyright notice in ZipArchive.h
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "ZipInternalInfo.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Construction/Destruction
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
CZipInternalInfo::CZipInternalInfo()
|
||||
{
|
||||
m_iBufferSize = 16384;
|
||||
}
|
||||
|
||||
CZipInternalInfo::~CZipInternalInfo()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CZipInternalInfo::Init()
|
||||
{
|
||||
m_pBuffer.Allocate(m_iBufferSize);
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
// ZipInternalInfo.h: interface for the CZipInternalInfo class.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2000 Tadeusz Dracz.
|
||||
// For conditions of distribution and use, see copyright notice in ZipArchive.h
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if !defined(AFX_ZIPINTERNALINFO_H__C6749101_590C_4F74_8121_B82E3BE9FA44__INCLUDED_)
|
||||
#define AFX_ZIPINTERNALINFO_H__C6749101_590C_4F74_8121_B82E3BE9FA44__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
#include "ZipAutoBuffer.h"
|
||||
#include "zlib.h"
|
||||
|
||||
class CZipInternalInfo
|
||||
{
|
||||
public:
|
||||
DWORD m_iBufferSize;
|
||||
z_stream m_stream;
|
||||
DWORD m_uUncomprLeft;
|
||||
DWORD m_uComprLeft;
|
||||
DWORD m_uCrc32;
|
||||
void Init();
|
||||
CZipAutoBuffer m_pBuffer;
|
||||
CZipInternalInfo();
|
||||
virtual ~CZipInternalInfo();
|
||||
|
||||
};
|
||||
|
||||
#endif // !defined(AFX_ZIPINTERNALINFO_H__C6749101_590C_4F74_8121_B82E3BE9FA44__INCLUDED_)
|
||||
@@ -0,0 +1,428 @@
|
||||
// ZipStorage.cpp: implementation of the CZipStorage class.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2000 Tadeusz Dracz.
|
||||
// For conditions of distribution and use, see copyright notice in ZipArchive.h
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "ZipStorage.h"
|
||||
#include "ZipArchive.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// disk spanning objectives:
|
||||
// - sinature at the first disk at the beginning
|
||||
// - headers and central dir records not divided between disks
|
||||
// - each file has a data descriptor preceded by the signature
|
||||
// (bit 3 set in flag);
|
||||
|
||||
|
||||
char CZipStorage::m_gszExtHeaderSignat[] = {0x50, 0x4b, 0x07, 0x08};
|
||||
CZipStorage::CZipStorage()
|
||||
{
|
||||
m_pCallbackData = m_pZIPCALLBACKFUN = NULL;
|
||||
m_iWriteBufferSize = 65535;
|
||||
m_iCurrentDisk = -1;
|
||||
m_pFile = NULL;
|
||||
}
|
||||
|
||||
CZipStorage::~CZipStorage()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
DWORD CZipStorage::Read(void *pBuf, DWORD iSize, bool bAtOnce)
|
||||
{
|
||||
if (iSize == 0)
|
||||
return 0;
|
||||
DWORD iRead = 0;
|
||||
while (!iRead)
|
||||
{
|
||||
iRead = m_pFile->Read(pBuf, iSize);
|
||||
if (!iRead)
|
||||
if (IsSpanMode())
|
||||
ChangeDisk(m_iCurrentDisk + 1);
|
||||
else
|
||||
ThrowError(ZIP_BADZIPFILE);
|
||||
}
|
||||
|
||||
if (iRead == iSize)
|
||||
return iRead;
|
||||
else if (bAtOnce || !IsSpanMode())
|
||||
ThrowError(ZIP_BADZIPFILE);
|
||||
|
||||
while (iRead < iSize)
|
||||
{
|
||||
ChangeDisk(m_iCurrentDisk + 1);
|
||||
UINT iNewRead = m_pFile->Read((char*)pBuf + iRead, iSize - iRead);
|
||||
if (!iNewRead && iRead < iSize)
|
||||
ThrowError(ZIP_BADZIPFILE);
|
||||
iRead += iNewRead;
|
||||
}
|
||||
|
||||
return iRead;
|
||||
}
|
||||
|
||||
void CZipStorage::Open(LPCTSTR szPathName, int iMode, int iVolumeSize)
|
||||
{
|
||||
m_pWriteBuffer.Allocate(m_iWriteBufferSize);
|
||||
m_uBytesInWriteBuffer = 0;
|
||||
m_bNewSpan = false;
|
||||
m_pFile = &m_internalfile;
|
||||
|
||||
if ((iMode == CZipArchive::create) ||(iMode == CZipArchive::createSpan)) // create new archive
|
||||
{
|
||||
m_iCurrentDisk = 0;
|
||||
if (iMode == CZipArchive::create)
|
||||
{
|
||||
m_iSpanMode = noSpan;
|
||||
OpenFile(szPathName, CFile::modeCreate | CFile::modeReadWrite);
|
||||
}
|
||||
else // create disk spanning archive
|
||||
{
|
||||
m_bNewSpan = true;
|
||||
m_iBytesWritten = 0;
|
||||
if (iVolumeSize <= 0) // pkzip span
|
||||
{
|
||||
if (!m_pZIPCALLBACKFUN)
|
||||
ThrowError(ZIP_NOCALLBACK);
|
||||
if (!CZipArchive::IsDriveRemovable(szPathName))
|
||||
ThrowError(ZIP_NONREMOVABLE);
|
||||
m_iSpanMode = pkzipSpan;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_iTdSpanData = iVolumeSize;
|
||||
m_iSpanMode = tdSpan;
|
||||
}
|
||||
|
||||
NextDisk(4, szPathName);
|
||||
Write(m_gszExtHeaderSignat, 4, true);
|
||||
}
|
||||
}
|
||||
else // open existing
|
||||
{
|
||||
OpenFile(szPathName, CFile::modeNoTruncate | ((iMode == CZipArchive::openReadOnly) ? CFile::modeRead : CFile::modeReadWrite));
|
||||
// m_uData, m_bAllowModif i m_iSpanMode ustalane automatycznie podczas odczytu central dir
|
||||
m_iSpanMode = iVolumeSize == 0 ? suggestedAuto : suggestedTd;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void CZipStorage::Open(CMemFile& mf, int iMode)
|
||||
{
|
||||
m_pWriteBuffer.Allocate(m_iWriteBufferSize);
|
||||
m_uBytesInWriteBuffer = 0;
|
||||
m_bNewSpan = false;
|
||||
m_pFile = &mf;
|
||||
|
||||
if (iMode == CZipArchive::create)
|
||||
{
|
||||
m_iCurrentDisk = 0;
|
||||
m_iSpanMode = noSpan;
|
||||
mf.SetLength(0);
|
||||
}
|
||||
else // open existing
|
||||
{
|
||||
mf.SeekToBegin();
|
||||
m_iSpanMode = suggestedAuto;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int CZipStorage::IsSpanMode()
|
||||
{
|
||||
return m_iSpanMode == noSpan ? 0 : (m_bNewSpan ? 1 : -1);
|
||||
}
|
||||
|
||||
void CZipStorage::ChangeDisk(int iNumber)
|
||||
{
|
||||
if (iNumber == m_iCurrentDisk)
|
||||
return;
|
||||
|
||||
ASSERT(m_iSpanMode != noSpan);
|
||||
m_iCurrentDisk = iNumber;
|
||||
OpenFile(m_iSpanMode == pkzipSpan ? ChangePkzipRead() : ChangeTdRead(),
|
||||
CFile::modeNoTruncate | CFile::modeRead);
|
||||
}
|
||||
|
||||
void CZipStorage::ThrowError(int err)
|
||||
{
|
||||
AfxThrowZipException(err, m_pFile->GetFilePath());
|
||||
}
|
||||
|
||||
bool CZipStorage::OpenFile(LPCTSTR lpszName, UINT uFlags, bool bThrow)
|
||||
{
|
||||
CFileException* e = new CFileException;
|
||||
BOOL bRet = m_pFile->Open(lpszName, uFlags | CFile::shareDenyWrite, e);
|
||||
if (!bRet && bThrow)
|
||||
throw e;
|
||||
e->Delete();
|
||||
return bRet != 0;
|
||||
}
|
||||
|
||||
// zapobiega konstrukcji ChangeDisk(++m_iCurrentDisk)
|
||||
void CZipStorage::SetCurrentDisk(int iNumber)
|
||||
{
|
||||
m_iCurrentDisk = iNumber;
|
||||
}
|
||||
|
||||
int CZipStorage::GetCurrentDisk()
|
||||
{
|
||||
return m_iCurrentDisk;
|
||||
}
|
||||
|
||||
CString CZipStorage::ChangePkzipRead()
|
||||
{
|
||||
CString szTemp = m_pFile->GetFilePath();
|
||||
m_pFile->Close();
|
||||
CallCallback(-1 , szTemp);
|
||||
return szTemp;
|
||||
}
|
||||
|
||||
CString CZipStorage::ChangeTdRead()
|
||||
{
|
||||
CString szTemp = GetTdVolumeName(m_iCurrentDisk == m_iTdSpanData);
|
||||
m_pFile->Close();
|
||||
return szTemp;
|
||||
}
|
||||
|
||||
void CZipStorage::Close(bool bAfterException)
|
||||
{
|
||||
if (!bAfterException)
|
||||
{
|
||||
Flush();
|
||||
if ((m_iSpanMode == tdSpan) && (m_bNewSpan))
|
||||
{
|
||||
// give to the last volume the zip extension
|
||||
CString szFileName = m_pFile->GetFilePath();
|
||||
CString szNewFileName = GetTdVolumeName(true);
|
||||
m_pFile->Close();
|
||||
if (CZipArchive::FileExists(szNewFileName))
|
||||
CFile::Remove(szNewFileName);
|
||||
CFile::Rename(szFileName, szNewFileName);
|
||||
}
|
||||
else
|
||||
#ifdef _DEBUG // to prevent assertion if the file is already closed
|
||||
if (m_pFile->m_hFile != (UINT)CFile::hFileNull)
|
||||
#endif
|
||||
m_pFile->Close();
|
||||
}
|
||||
else
|
||||
#ifdef _DEBUG // to prevent assertion if the file is already closed
|
||||
if (m_pFile->m_hFile != (UINT)CFile::hFileNull)
|
||||
#endif
|
||||
m_pFile->Close();
|
||||
|
||||
|
||||
m_pWriteBuffer.Release();
|
||||
m_iCurrentDisk = -1;
|
||||
m_iSpanMode = noSpan;
|
||||
m_pFile = NULL;
|
||||
}
|
||||
|
||||
CString CZipStorage::GetTdVolumeName(bool bLast, LPCTSTR lpszZipName)
|
||||
{
|
||||
CString szFilePath = lpszZipName ? lpszZipName : m_pFile->GetFilePath();
|
||||
CString szPath = CZipArchive::GetFilePath(szFilePath);
|
||||
CString szName = CZipArchive::GetFileTitle(szFilePath);
|
||||
CString szExt;
|
||||
if (bLast)
|
||||
szExt = _T("zip");
|
||||
else
|
||||
szExt.Format(_T("%.3d"), m_iCurrentDisk);
|
||||
return szPath + szName + _T(".") + szExt;
|
||||
}
|
||||
|
||||
void CZipStorage::NextDisk(int iNeeded, LPCTSTR lpszFileName)
|
||||
{
|
||||
Flush();
|
||||
ASSERT(m_iSpanMode != noSpan);
|
||||
if (m_iBytesWritten)
|
||||
{
|
||||
m_iBytesWritten = 0;
|
||||
m_iCurrentDisk++;
|
||||
if (m_iCurrentDisk >= 999)
|
||||
ThrowError(ZIP_TOOMANYVOLUMES);
|
||||
}
|
||||
CString szFileName;
|
||||
bool bPkSpan = (m_iSpanMode == pkzipSpan);
|
||||
if (bPkSpan)
|
||||
szFileName = lpszFileName ? lpszFileName : m_pFile->GetFilePath();
|
||||
else
|
||||
szFileName = GetTdVolumeName(false, lpszFileName);
|
||||
|
||||
#ifdef _DEBUG // to prevent assertion if the file is already closed
|
||||
if (m_pFile->m_hFile != (UINT)CFile::hFileNull)
|
||||
#endif
|
||||
m_pFile->Close(); // if it is closed, so it will not close
|
||||
|
||||
if (bPkSpan)
|
||||
{
|
||||
int iCode = iNeeded;
|
||||
while (true)
|
||||
{
|
||||
CallCallback(iCode, szFileName);
|
||||
if (CZipArchive::FileExists(szFileName))
|
||||
iCode = -2;
|
||||
else
|
||||
{
|
||||
CString label;
|
||||
label.Format(_T("pkback# %.3d"), m_iCurrentDisk + 1);
|
||||
if (!SetVolumeLabel(CZipArchive::GetDrive(szFileName), label)) /*not write label*/
|
||||
iCode = -3;
|
||||
else if (!OpenFile(szFileName, CFile::modeCreate | CFile::modeReadWrite, false))
|
||||
iCode = -4;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
m_uCurrentVolSize = GetFreeVolumeSpace();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_uCurrentVolSize = m_iTdSpanData;
|
||||
OpenFile(szFileName, CFile::modeCreate | CFile::modeReadWrite);
|
||||
}
|
||||
}
|
||||
|
||||
void CZipStorage::CallCallback(int iCode, CString szTemp)
|
||||
{
|
||||
ASSERT(m_pZIPCALLBACKFUN);
|
||||
if (!(*m_pZIPCALLBACKFUN)(m_iCurrentDisk + 1, iCode, m_pCallbackData))
|
||||
throw new CZipException(CZipException::aborted, szTemp);
|
||||
}
|
||||
|
||||
DWORD CZipStorage::GetFreeVolumeSpace()
|
||||
{
|
||||
ASSERT (m_iSpanMode == pkzipSpan);
|
||||
DWORD SectorsPerCluster, BytesPerSector, NumberOfFreeClusters, TotalNumberOfClusters;
|
||||
if (!GetDiskFreeSpace(
|
||||
CZipArchive::GetDrive(m_pFile->GetFilePath()),
|
||||
&SectorsPerCluster,
|
||||
&BytesPerSector,
|
||||
&NumberOfFreeClusters,
|
||||
&TotalNumberOfClusters))
|
||||
return 0;
|
||||
_int64 total = SectorsPerCluster * BytesPerSector * NumberOfFreeClusters;
|
||||
return (DWORD)total;
|
||||
}
|
||||
|
||||
|
||||
void CZipStorage::UpdateSpanMode(WORD uLastDisk)
|
||||
{
|
||||
m_iCurrentDisk = uLastDisk;
|
||||
if (uLastDisk)
|
||||
{
|
||||
// disk spanning detected
|
||||
|
||||
if (m_iSpanMode == suggestedAuto)
|
||||
m_iSpanMode = CZipArchive::IsDriveRemovable(m_pFile->GetFilePath()) ?
|
||||
pkzipSpan : tdSpan;
|
||||
else
|
||||
m_iSpanMode = tdSpan;
|
||||
|
||||
if (m_iSpanMode == pkzipSpan)
|
||||
{
|
||||
if (!m_pZIPCALLBACKFUN)
|
||||
ThrowError(ZIP_NOCALLBACK);
|
||||
}
|
||||
else /*if (m_iSpanMode == tdSpan)*/
|
||||
m_iTdSpanData = uLastDisk; // disk with .zip extension ( the last one)
|
||||
|
||||
m_pWriteBuffer.Release(); // no need for this in this case
|
||||
}
|
||||
else
|
||||
m_iSpanMode = noSpan;
|
||||
|
||||
}
|
||||
|
||||
void CZipStorage::Write(void *pBuf, DWORD iSize, bool bAtOnce)
|
||||
{
|
||||
if (!IsSpanMode())
|
||||
WriteInternalBuffer((char*)pBuf, iSize);
|
||||
else
|
||||
{
|
||||
// if not at once, one byte is enough free space
|
||||
DWORD iNeeded = bAtOnce ? iSize : 1;
|
||||
DWORD uTotal = 0;
|
||||
|
||||
while (uTotal < iSize)
|
||||
{
|
||||
DWORD uFree;
|
||||
while ((uFree = VolumeLeft()) < iNeeded)
|
||||
{
|
||||
if ((m_iSpanMode == tdSpan) && !m_iBytesWritten && !m_uBytesInWriteBuffer)
|
||||
// in the tdSpan mode, if the size of the archive is less
|
||||
// than the size of the packet to be written at once,
|
||||
// increase once the size of the volume
|
||||
m_uCurrentVolSize = iNeeded;
|
||||
else
|
||||
NextDisk(iNeeded);
|
||||
}
|
||||
|
||||
DWORD uLeftToWrite = iSize - uTotal;
|
||||
DWORD uToWrite = uFree < uLeftToWrite ? uFree : uLeftToWrite;
|
||||
WriteInternalBuffer((char*)pBuf + uTotal, uToWrite);
|
||||
if (bAtOnce)
|
||||
return;
|
||||
else
|
||||
uTotal += uToWrite;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CZipStorage::WriteInternalBuffer(char *pBuf, DWORD uSize)
|
||||
{
|
||||
DWORD uWritten = 0;
|
||||
while (uWritten < uSize)
|
||||
{
|
||||
DWORD uFreeInBuffer = GetFreeInBuffer();
|
||||
if (uFreeInBuffer == 0)
|
||||
{
|
||||
Flush();
|
||||
uFreeInBuffer = m_pWriteBuffer.GetSize();
|
||||
}
|
||||
DWORD uLeftToWrite = uSize - uWritten;
|
||||
DWORD uToCopy = uLeftToWrite < uFreeInBuffer ? uLeftToWrite : uFreeInBuffer;
|
||||
memcpy(m_pWriteBuffer + m_uBytesInWriteBuffer, pBuf + uWritten, uToCopy);
|
||||
uWritten += uToCopy;
|
||||
m_uBytesInWriteBuffer += uToCopy;
|
||||
}
|
||||
}
|
||||
|
||||
DWORD CZipStorage::VolumeLeft()
|
||||
{
|
||||
// for pkzip span m_uCurrentVolSize is updated after each flush()
|
||||
return m_uCurrentVolSize - m_uBytesInWriteBuffer - ((m_iSpanMode == pkzipSpan) ? 0 : m_iBytesWritten);
|
||||
}
|
||||
|
||||
void CZipStorage::Flush()
|
||||
{
|
||||
m_iBytesWritten += m_uBytesInWriteBuffer;
|
||||
if (m_uBytesInWriteBuffer)
|
||||
{
|
||||
m_pFile->Write(m_pWriteBuffer, m_uBytesInWriteBuffer);
|
||||
m_uBytesInWriteBuffer = 0;
|
||||
}
|
||||
if (m_iSpanMode == pkzipSpan)
|
||||
// after writting it is difficult to predict the free space due to
|
||||
// not completly written clusters, write operation may start from
|
||||
// the new cluster
|
||||
m_uCurrentVolSize = GetFreeVolumeSpace();
|
||||
}
|
||||
|
||||
DWORD CZipStorage::GetPosition()
|
||||
{
|
||||
return m_pFile->GetPosition() + m_uBytesInWriteBuffer;
|
||||
}
|
||||
|
||||
|
||||
DWORD CZipStorage::GetFreeInBuffer()
|
||||
{
|
||||
return m_pWriteBuffer.GetSize() - m_uBytesInWriteBuffer;
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
// ZipStorage.h: interface for the CZipStorage class.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2000 Tadeusz Dracz.
|
||||
// For conditions of distribution and use, see copyright notice in ZipArchive.h
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if !defined(AFX_ZIPSTORAGE_H__941824FE_3320_4794_BDE3_BE334ED8984B__INCLUDED_)
|
||||
#define AFX_ZIPSTORAGE_H__941824FE_3320_4794_BDE3_BE334ED8984B__INCLUDED_
|
||||
|
||||
#include "ZipBigFile.h" // Added by ClassView
|
||||
#include "ZipAutoBuffer.h" // Added by ClassView
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
|
||||
// callback function called when there is a need for a disk change
|
||||
// calling CZipArchive functions, apart from the static ones, may have unexpected results
|
||||
// iNumber - disk number needed
|
||||
// iCode :
|
||||
// -1 - disk needed for reading
|
||||
// other codes occurs during writting
|
||||
// >=0 : number of bytes needed
|
||||
// -2 - the file with the archive name already exists on the disk
|
||||
// -3 - the disk is probably write - protected
|
||||
// -4 - couldn't create a file
|
||||
// pData - user defined data
|
||||
// return false to abort operation: the proper exception will be thrown
|
||||
typedef bool (*ZIPCALLBACKFUN )(int iNumber, int iCode, void* pData);
|
||||
|
||||
class CZipStorage
|
||||
{
|
||||
public:
|
||||
void Open(CMemFile& mf, int iMode);
|
||||
// return the position in the file, taking into account the bytes in the write buffer
|
||||
DWORD GetPosition();
|
||||
|
||||
// flush the data from the read buffer to the disk
|
||||
void Flush();
|
||||
|
||||
// only called by CZipCentralDir when opening an existing archive
|
||||
void UpdateSpanMode(WORD uLastDisk);
|
||||
// the preset size of the write buffer
|
||||
int m_iWriteBufferSize;
|
||||
|
||||
// user data to be passed to the callback function
|
||||
void* m_pCallbackData;
|
||||
|
||||
// function used to change disks during writing to the disk spanning archive
|
||||
void NextDisk(int iNeeded, LPCTSTR lpszFileName = NULL);
|
||||
|
||||
void Close(bool bAfterException);
|
||||
|
||||
// return the numer of the current disk
|
||||
int GetCurrentDisk();
|
||||
|
||||
void SetCurrentDisk(int iNumber);
|
||||
|
||||
// change the disk during extract operations
|
||||
void ChangeDisk(int iNumber);
|
||||
|
||||
// Function name : IsSpanMode
|
||||
// Description : detect span mode
|
||||
// Return type : int
|
||||
// -1 - existing span opened
|
||||
// 0 - no span
|
||||
// 1 - new span
|
||||
int IsSpanMode();
|
||||
|
||||
void Open(LPCTSTR szPathName, int iMode, int iVolumeSize);
|
||||
void Write(void *pBuf, DWORD iSize, bool bAtOnce);
|
||||
DWORD Read(void* pBuf, DWORD iSize, bool bAtOnce);
|
||||
CZipBigFile m_internalfile;
|
||||
CFile* m_pFile;
|
||||
CZipStorage();
|
||||
virtual ~CZipStorage();
|
||||
enum {noSpan, pkzipSpan, tdSpan, suggestedAuto, suggestedTd};
|
||||
int m_iSpanMode;
|
||||
ZIPCALLBACKFUN m_pZIPCALLBACKFUN;
|
||||
static char m_gszExtHeaderSignat[];
|
||||
|
||||
// open tdspan: last disk number, create tdspan: volume size
|
||||
// create pkspan: not used
|
||||
int m_iTdSpanData;
|
||||
|
||||
protected:
|
||||
// how many bytes left free in the write buffer
|
||||
DWORD GetFreeInBuffer();
|
||||
friend class CZipCentralDir;
|
||||
// numer of bytes available in the write buffer
|
||||
DWORD m_uBytesInWriteBuffer;
|
||||
|
||||
// tdSpan : the total size of the current volume, pkSpan : free space on the current volume
|
||||
DWORD m_uCurrentVolSize;
|
||||
|
||||
// return the number of bytes left on the current volume
|
||||
DWORD VolumeLeft();
|
||||
|
||||
// write data to the internal buffer
|
||||
void WriteInternalBuffer(char *pBuf, DWORD uSize);
|
||||
|
||||
// number of bytes left free in the write buffer
|
||||
DWORD m_uVolumeFreeInBuffer;
|
||||
|
||||
CZipAutoBuffer m_pWriteBuffer;
|
||||
|
||||
// return the number of free bytes on the current removable disk
|
||||
DWORD GetFreeVolumeSpace();
|
||||
|
||||
void CallCallback(int iCode, CString szTemp);
|
||||
|
||||
// only disk spanning creation: tells how many bytes have been written physically to the current volume
|
||||
DWORD m_iBytesWritten;
|
||||
|
||||
// construct the name of the volume in tdSpan mode
|
||||
CString GetTdVolumeName(bool bLast, LPCTSTR lpszZipName = NULL);
|
||||
|
||||
// change the disk in tdSpan mode
|
||||
CString ChangeTdRead();
|
||||
|
||||
// change the disk in pkSpan mode
|
||||
CString ChangePkzipRead();
|
||||
|
||||
// you can only add a new files to the new disk spanning archive and only extract
|
||||
// them from the existing one
|
||||
bool m_bNewSpan;
|
||||
|
||||
int m_iCurrentDisk;
|
||||
bool OpenFile(LPCTSTR lpszName, UINT uFlags, bool bThrow = true);
|
||||
void ThrowError(int err);
|
||||
|
||||
};
|
||||
|
||||
#endif // !defined(AFX_ZIPSTORAGE_H__941824FE_3320_4794_BDE3_BE334ED8984B__INCLUDED_)
|
||||
@@ -0,0 +1,279 @@
|
||||
/* zconf.h -- configuration of the zlib compression library
|
||||
* Copyright (C) 1995-1998 Jean-loup Gailly.
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
/* @(#) $Id$ */
|
||||
|
||||
#ifndef _ZCONF_H
|
||||
#define _ZCONF_H
|
||||
|
||||
/*
|
||||
* If you *really* need a unique prefix for all types and library functions,
|
||||
* compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
|
||||
*/
|
||||
#ifdef Z_PREFIX
|
||||
# define deflateInit_ z_deflateInit_
|
||||
# define deflate z_deflate
|
||||
# define deflateEnd z_deflateEnd
|
||||
# define inflateInit_ z_inflateInit_
|
||||
# define inflate z_inflate
|
||||
# define inflateEnd z_inflateEnd
|
||||
# define deflateInit2_ z_deflateInit2_
|
||||
# define deflateSetDictionary z_deflateSetDictionary
|
||||
# define deflateCopy z_deflateCopy
|
||||
# define deflateReset z_deflateReset
|
||||
# define deflateParams z_deflateParams
|
||||
# define inflateInit2_ z_inflateInit2_
|
||||
# define inflateSetDictionary z_inflateSetDictionary
|
||||
# define inflateSync z_inflateSync
|
||||
# define inflateSyncPoint z_inflateSyncPoint
|
||||
# define inflateReset z_inflateReset
|
||||
# define compress z_compress
|
||||
# define compress2 z_compress2
|
||||
# define uncompress z_uncompress
|
||||
# define adler32 z_adler32
|
||||
# define crc32 z_crc32
|
||||
# define get_crc_table z_get_crc_table
|
||||
|
||||
# define Byte z_Byte
|
||||
# define uInt z_uInt
|
||||
# define uLong z_uLong
|
||||
# define Bytef z_Bytef
|
||||
# define charf z_charf
|
||||
# define intf z_intf
|
||||
# define uIntf z_uIntf
|
||||
# define uLongf z_uLongf
|
||||
# define voidpf z_voidpf
|
||||
# define voidp z_voidp
|
||||
#endif
|
||||
|
||||
#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
|
||||
# define WIN32
|
||||
#endif
|
||||
#if defined(__GNUC__) || defined(WIN32) || defined(__386__) || defined(i386)
|
||||
# ifndef __32BIT__
|
||||
# define __32BIT__
|
||||
# endif
|
||||
#endif
|
||||
#if defined(__MSDOS__) && !defined(MSDOS)
|
||||
# define MSDOS
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Compile with -DMAXSEG_64K if the alloc function cannot allocate more
|
||||
* than 64k bytes at a time (needed on systems with 16-bit int).
|
||||
*/
|
||||
#if defined(MSDOS) && !defined(__32BIT__)
|
||||
# define MAXSEG_64K
|
||||
#endif
|
||||
#ifdef MSDOS
|
||||
# define UNALIGNED_OK
|
||||
#endif
|
||||
|
||||
#if (defined(MSDOS) || defined(_WINDOWS) || defined(WIN32)) && !defined(STDC)
|
||||
# define STDC
|
||||
#endif
|
||||
#if defined(__STDC__) || defined(__cplusplus) || defined(__OS2__)
|
||||
# ifndef STDC
|
||||
# define STDC
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef STDC
|
||||
# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
|
||||
# define const
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Some Mac compilers merge all .h files incorrectly: */
|
||||
#if defined(__MWERKS__) || defined(applec) ||defined(THINK_C) ||defined(__SC__)
|
||||
# define NO_DUMMY_DECL
|
||||
#endif
|
||||
|
||||
/* Old Borland C incorrectly complains about missing returns: */
|
||||
#if defined(__BORLANDC__) && (__BORLANDC__ < 0x500)
|
||||
# define NEED_DUMMY_RETURN
|
||||
#endif
|
||||
|
||||
|
||||
/* Maximum value for memLevel in deflateInit2 */
|
||||
#ifndef MAX_MEM_LEVEL
|
||||
# ifdef MAXSEG_64K
|
||||
# define MAX_MEM_LEVEL 8
|
||||
# else
|
||||
# define MAX_MEM_LEVEL 9
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Maximum value for windowBits in deflateInit2 and inflateInit2.
|
||||
* WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
|
||||
* created by gzip. (Files created by minigzip can still be extracted by
|
||||
* gzip.)
|
||||
*/
|
||||
#ifndef MAX_WBITS
|
||||
# define MAX_WBITS 15 /* 32K LZ77 window */
|
||||
#endif
|
||||
|
||||
/* The memory requirements for deflate are (in bytes):
|
||||
(1 << (windowBits+2)) + (1 << (memLevel+9))
|
||||
that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
|
||||
plus a few kilobytes for small objects. For example, if you want to reduce
|
||||
the default memory requirements from 256K to 128K, compile with
|
||||
make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
|
||||
Of course this will generally degrade compression (there's no free lunch).
|
||||
|
||||
The memory requirements for inflate are (in bytes) 1 << windowBits
|
||||
that is, 32K for windowBits=15 (default value) plus a few kilobytes
|
||||
for small objects.
|
||||
*/
|
||||
|
||||
/* Type declarations */
|
||||
|
||||
#ifndef OF /* function prototypes */
|
||||
# ifdef STDC
|
||||
# define OF(args) args
|
||||
# else
|
||||
# define OF(args) ()
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* The following definitions for FAR are needed only for MSDOS mixed
|
||||
* model programming (small or medium model with some far allocations).
|
||||
* This was tested only with MSC; for other MSDOS compilers you may have
|
||||
* to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
|
||||
* just define FAR to be empty.
|
||||
*/
|
||||
#if (defined(M_I86SM) || defined(M_I86MM)) && !defined(__32BIT__)
|
||||
/* MSC small or medium model */
|
||||
# define SMALL_MEDIUM
|
||||
# ifdef _MSC_VER
|
||||
# define FAR _far
|
||||
# else
|
||||
# define FAR far
|
||||
# endif
|
||||
#endif
|
||||
#if defined(__BORLANDC__) && (defined(__SMALL__) || defined(__MEDIUM__))
|
||||
# ifndef __32BIT__
|
||||
# define SMALL_MEDIUM
|
||||
# define FAR _far
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Compile with -DZLIB_DLL for Windows DLL support */
|
||||
#if defined(ZLIB_DLL)
|
||||
# if defined(_WINDOWS) || defined(WINDOWS)
|
||||
# ifdef FAR
|
||||
# undef FAR
|
||||
# endif
|
||||
# include <windows.h>
|
||||
# define ZEXPORT WINAPI
|
||||
# ifdef WIN32
|
||||
# define ZEXPORTVA WINAPIV
|
||||
# else
|
||||
# define ZEXPORTVA FAR _cdecl _export
|
||||
# endif
|
||||
# endif
|
||||
# if defined (__BORLANDC__)
|
||||
# if (__BORLANDC__ >= 0x0500) && defined (WIN32)
|
||||
# include <windows.h>
|
||||
# define ZEXPORT __declspec(dllexport) WINAPI
|
||||
# define ZEXPORTRVA __declspec(dllexport) WINAPIV
|
||||
# else
|
||||
# if defined (_Windows) && defined (__DLL__)
|
||||
# define ZEXPORT _export
|
||||
# define ZEXPORTVA _export
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined (__BEOS__)
|
||||
# if defined (ZLIB_DLL)
|
||||
# define ZEXTERN extern __declspec(dllexport)
|
||||
# else
|
||||
# define ZEXTERN extern __declspec(dllimport)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef ZEXPORT
|
||||
# define ZEXPORT
|
||||
#endif
|
||||
#ifndef ZEXPORTVA
|
||||
# define ZEXPORTVA
|
||||
#endif
|
||||
#ifndef ZEXTERN
|
||||
# define ZEXTERN extern
|
||||
#endif
|
||||
|
||||
#ifndef FAR
|
||||
# define FAR
|
||||
#endif
|
||||
|
||||
#if !defined(MACOS) && !defined(TARGET_OS_MAC)
|
||||
typedef unsigned char Byte; /* 8 bits */
|
||||
#endif
|
||||
typedef unsigned int uInt; /* 16 bits or more */
|
||||
typedef unsigned long uLong; /* 32 bits or more */
|
||||
|
||||
#ifdef SMALL_MEDIUM
|
||||
/* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
|
||||
# define Bytef Byte FAR
|
||||
#else
|
||||
typedef Byte FAR Bytef;
|
||||
#endif
|
||||
typedef char FAR charf;
|
||||
typedef int FAR intf;
|
||||
typedef uInt FAR uIntf;
|
||||
typedef uLong FAR uLongf;
|
||||
|
||||
#ifdef STDC
|
||||
typedef void FAR *voidpf;
|
||||
typedef void *voidp;
|
||||
#else
|
||||
typedef Byte FAR *voidpf;
|
||||
typedef Byte *voidp;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
# include <sys/types.h> /* for off_t */
|
||||
# include <unistd.h> /* for SEEK_* and off_t */
|
||||
# define z_off_t off_t
|
||||
#endif
|
||||
#ifndef SEEK_SET
|
||||
# define SEEK_SET 0 /* Seek from beginning of file. */
|
||||
# define SEEK_CUR 1 /* Seek from current position. */
|
||||
# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
|
||||
#endif
|
||||
#ifndef z_off_t
|
||||
# define z_off_t long
|
||||
#endif
|
||||
|
||||
/* MVS linker does not support external names larger than 8 bytes */
|
||||
#if defined(__MVS__)
|
||||
# pragma map(deflateInit_,"DEIN")
|
||||
# pragma map(deflateInit2_,"DEIN2")
|
||||
# pragma map(deflateEnd,"DEEND")
|
||||
# pragma map(inflateInit_,"ININ")
|
||||
# pragma map(inflateInit2_,"ININ2")
|
||||
# pragma map(inflateEnd,"INEND")
|
||||
# pragma map(inflateSync,"INSY")
|
||||
# pragma map(inflateSetDictionary,"INSEDI")
|
||||
# pragma map(inflate_blocks,"INBL")
|
||||
# pragma map(inflate_blocks_new,"INBLNE")
|
||||
# pragma map(inflate_blocks_free,"INBLFR")
|
||||
# pragma map(inflate_blocks_reset,"INBLRE")
|
||||
# pragma map(inflate_codes_free,"INCOFR")
|
||||
# pragma map(inflate_codes,"INCO")
|
||||
# pragma map(inflate_fast,"INFA")
|
||||
# pragma map(inflate_flush,"INFLU")
|
||||
# pragma map(inflate_mask,"INMA")
|
||||
# pragma map(inflate_set_dictionary,"INSEDI2")
|
||||
# pragma map(inflate_copyright,"INCOPY")
|
||||
# pragma map(inflate_trees_bits,"INTRBI")
|
||||
# pragma map(inflate_trees_dynamic,"INTRDY")
|
||||
# pragma map(inflate_trees_fixed,"INTRFI")
|
||||
# pragma map(inflate_trees_free,"INTRFR")
|
||||
#endif
|
||||
|
||||
#endif /* _ZCONF_H */
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 31 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 31 KiB |
@@ -0,0 +1,26 @@
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Developer Studio generated include file.
|
||||
// Used by smpackage.rc
|
||||
//
|
||||
#define IDD_SMPACKAGE_DIALOG 102
|
||||
#define IDD_MANAGER 102
|
||||
#define IDR_MAINFRAME 128
|
||||
#define IDD_INSTALL 129
|
||||
#define INSTALL 133
|
||||
#define MANAGE 135
|
||||
#define IDC_LIST_SONGS 1000
|
||||
#define IDC_BUTTON_PLAY 1001
|
||||
#define IDC_BUTTON_EXPORT 1002
|
||||
#define IDC_BUTTON_BACK 1003
|
||||
#define IDC_EDIT_MESSAGE 1005
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 137
|
||||
#define _APS_NEXT_COMMAND_VALUE 32771
|
||||
#define _APS_NEXT_CONTROL_VALUE 1007
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 5.9 KiB |
@@ -0,0 +1,66 @@
|
||||
; CLW file contains information for the MFC ClassWizard
|
||||
|
||||
[General Info]
|
||||
Version=1
|
||||
LastClass=CSMPackageInstallDlg
|
||||
LastTemplate=CDialog
|
||||
NewFileInclude1=#include "stdafx.h"
|
||||
NewFileInclude2=#include "smpackage.h"
|
||||
|
||||
ClassCount=3
|
||||
Class1=CSmpackageApp
|
||||
Class2=CSmpackageDlg
|
||||
|
||||
ResourceCount=3
|
||||
Resource1=IDR_MAINFRAME
|
||||
Resource2=IDD_MANAGER
|
||||
Class3=CSMPackageInstallDlg
|
||||
Resource3=IDD_INSTALL
|
||||
|
||||
[CLS:CSmpackageApp]
|
||||
Type=0
|
||||
HeaderFile=smpackage.h
|
||||
ImplementationFile=smpackage.cpp
|
||||
Filter=N
|
||||
LastObject=CSmpackageApp
|
||||
|
||||
[CLS:CSmpackageDlg]
|
||||
Type=0
|
||||
HeaderFile=smpackageDlg.h
|
||||
ImplementationFile=smpackageDlg.cpp
|
||||
Filter=D
|
||||
LastObject=CSmpackageDlg
|
||||
BaseClass=CDialog
|
||||
VirtualFilter=dWC
|
||||
|
||||
|
||||
|
||||
[DLG:IDD_MANAGER]
|
||||
Type=1
|
||||
Class=CSmpackageDlg
|
||||
ControlCount=5
|
||||
Control1=IDOK,button,1342242817
|
||||
Control2=IDC_LIST_SONGS,listbox,1352728835
|
||||
Control3=IDC_BUTTON_PLAY,button,1342242816
|
||||
Control4=IDC_BUTTON_EXPORT,button,1476460544
|
||||
Control5=IDC_STATIC,static,1342177294
|
||||
|
||||
[DLG:IDD_INSTALL]
|
||||
Type=1
|
||||
Class=CSMPackageInstallDlg
|
||||
ControlCount=5
|
||||
Control1=IDC_EDIT_MESSAGE,edit,1342179460
|
||||
Control2=IDOK,button,1342242817
|
||||
Control3=IDCANCEL,button,1342242816
|
||||
Control4=IDC_BUTTON_BACK,button,1476460544
|
||||
Control5=IDC_STATIC,static,1342177294
|
||||
|
||||
[CLS:CSMPackageInstallDlg]
|
||||
Type=0
|
||||
HeaderFile=SMPackageInstallDlg.h
|
||||
ImplementationFile=SMPackageInstallDlg.cpp
|
||||
BaseClass=CDialog
|
||||
Filter=D
|
||||
LastObject=CSMPackageInstallDlg
|
||||
VirtualFilter=dWC
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
// smpackage.cpp : Defines the class behaviors for the application.
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "smpackage.h"
|
||||
#include "smpackageDlg.h"
|
||||
#include "smpackageInstallDlg.h"
|
||||
#include "../RageUtil.h"
|
||||
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CSmpackageApp
|
||||
|
||||
BEGIN_MESSAGE_MAP(CSmpackageApp, CWinApp)
|
||||
//{{AFX_MSG_MAP(CSmpackageApp)
|
||||
// NOTE - the ClassWizard will add and remove mapping macros here.
|
||||
// DO NOT EDIT what you see in these blocks of generated code!
|
||||
//}}AFX_MSG
|
||||
ON_COMMAND(ID_HELP, CWinApp::OnHelp)
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CSmpackageApp construction
|
||||
|
||||
CSmpackageApp::CSmpackageApp()
|
||||
{
|
||||
// TODO: add construction code here,
|
||||
// Place all significant initialization in InitInstance
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// The one and only CSmpackageApp object
|
||||
|
||||
CSmpackageApp theApp;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CSmpackageApp initialization
|
||||
|
||||
BOOL CSmpackageApp::InitInstance()
|
||||
{
|
||||
// Standard initialization
|
||||
// If you are not using these features and wish to reduce the size
|
||||
// of your final executable, you should remove from the following
|
||||
// the specific initialization routines you do not need.
|
||||
|
||||
#ifdef _AFXDLL
|
||||
Enable3dControls(); // Call this when using MFC in a shared DLL
|
||||
#else
|
||||
Enable3dControlsStatic(); // Call this when linking to MFC statically
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
// Make sure the current directory is the root program directory
|
||||
if( !DoesFileExist("Songs") )
|
||||
{
|
||||
// change dir to path of the execuctable
|
||||
TCHAR szFullAppPath[MAX_PATH];
|
||||
GetModuleFileName(NULL, szFullAppPath, MAX_PATH);
|
||||
|
||||
// strip off executable name
|
||||
LPSTR pLastBackslash = strrchr(szFullAppPath, '\\');
|
||||
*pLastBackslash = '\0'; // terminate the string
|
||||
|
||||
SetCurrentDirectory(szFullAppPath);
|
||||
|
||||
if( !DoesFileExist("Songs") )
|
||||
{
|
||||
AfxMessageBox( "Your Songs folder could not be located. Be sure 'smpackage.exe' is in your Stepmania installation folder.", MB_ICONSTOP );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// check if there's a .smzip command line argument
|
||||
CStringArray arrayCommandLineBits;
|
||||
split( ::GetCommandLine(), "\"", arrayCommandLineBits );
|
||||
for( int i=0; i<arrayCommandLineBits.GetSize(); i++ )
|
||||
{
|
||||
CString sPath = arrayCommandLineBits[i];
|
||||
sPath.TrimLeft();
|
||||
sPath.TrimRight();
|
||||
CString sPathLower = sPath;
|
||||
sPathLower.MakeLower();
|
||||
|
||||
// test to see if this is a smzip file
|
||||
if( sPathLower.Right(3) == "zip" )
|
||||
{
|
||||
// We found a zip package. Prompt the user to install it!
|
||||
CSMPackageInstallDlg dlg( sPath );
|
||||
int nResponse = dlg.DoModal();
|
||||
if( nResponse == IDOK )
|
||||
{
|
||||
; // do nothing and fall through to below
|
||||
}
|
||||
else if (nResponse == IDCANCEL)
|
||||
{
|
||||
// the user cancelled. Don't fall through and display the Manager.
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Show the Manager Dialog
|
||||
CSmpackageDlg dlg;
|
||||
int nResponse = dlg.DoModal();
|
||||
// if (nResponse == IDOK)
|
||||
|
||||
|
||||
// Since the dialog has been closed, return FALSE so that we exit the
|
||||
// application, rather than start the application's message pump.
|
||||
return FALSE;
|
||||
}
|
||||
@@ -0,0 +1,170 @@
|
||||
# Microsoft Developer Studio Project File - Name="smpackage" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Application" 0x0101
|
||||
|
||||
CFG=smpackage - Win32 Debug
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "smpackage.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "smpackage.mak" CFG="smpackage - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "smpackage - Win32 Release" (based on "Win32 (x86) Application")
|
||||
!MESSAGE "smpackage - Win32 Debug" (based on "Win32 (x86) Application")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
MTL=midl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "smpackage - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 5
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 6
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /Yu"stdafx.h" /FD /c
|
||||
# ADD CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_AFXDLL" /FR /Yu"stdafx.h" /FD /c
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG" /d "_AFXDLL"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 /nologo /subsystem:windows /machine:I386
|
||||
# ADD LINK32 /nologo /subsystem:windows /machine:I386
|
||||
|
||||
!ELSEIF "$(CFG)" == "smpackage - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 5
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 6
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /Yu"stdafx.h" /FD /GZ /c
|
||||
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_AFXDLL" /Yu"stdafx.h" /FD /GZ /c
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG" /d "_AFXDLL"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "smpackage - Win32 Release"
|
||||
# Name "smpackage - Win32 Debug"
|
||||
# Begin Group "Stepmania Package files"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\RageUtil.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\RageUtil.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Resource.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\smpackage.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\smpackage.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\res\smpackage.ico
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\smpackage.rc
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\res\smpackage.rc2
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\smpackageDlg.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\smpackageDlg.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\SMPackageInstallDlg.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\SMPackageInstallDlg.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\StdAfx.cpp
|
||||
# ADD CPP /Yc"stdafx.h"
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\StdAfx.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\install.bmp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\manage.bmp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ReadMe.txt
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\smpackage.ICO
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\res\StepMania.ICO
|
||||
# End Source File
|
||||
# End Target
|
||||
# End Project
|
||||
@@ -0,0 +1,49 @@
|
||||
// smpackage.h : main header file for the SMPACKAGE application
|
||||
//
|
||||
|
||||
#if !defined(AFX_SMPACKAGE_H__FBCA9E6C_86A9_4271_8304_83CC34A31687__INCLUDED_)
|
||||
#define AFX_SMPACKAGE_H__FBCA9E6C_86A9_4271_8304_83CC34A31687__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
|
||||
#ifndef __AFXWIN_H__
|
||||
#error include 'stdafx.h' before including this file for PCH
|
||||
#endif
|
||||
|
||||
#include "resource.h" // main symbols
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CSmpackageApp:
|
||||
// See smpackage.cpp for the implementation of this class
|
||||
//
|
||||
|
||||
class CSmpackageApp : public CWinApp
|
||||
{
|
||||
public:
|
||||
CSmpackageApp();
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(CSmpackageApp)
|
||||
public:
|
||||
virtual BOOL InitInstance();
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
|
||||
//{{AFX_MSG(CSmpackageApp)
|
||||
// NOTE - the ClassWizard will add and remove member functions here.
|
||||
// DO NOT EDIT what you see in these blocks of generated code !
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
};
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_SMPACKAGE_H__FBCA9E6C_86A9_4271_8304_83CC34A31687__INCLUDED_)
|
||||
Binary file not shown.
@@ -0,0 +1,209 @@
|
||||
//Microsoft Developer Studio generated resource script.
|
||||
//
|
||||
#include "resource.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#include "afxres.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// English (U.S.) resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
||||
#ifdef _WIN32
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
#pragma code_page(1252)
|
||||
#endif //_WIN32
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
1 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"resource.h\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"#include ""afxres.h""\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"#define _AFX_NO_SPLITTER_RESOURCES\r\n"
|
||||
"#define _AFX_NO_OLE_RESOURCES\r\n"
|
||||
"#define _AFX_NO_TRACKER_RESOURCES\r\n"
|
||||
"#define _AFX_NO_PROPERTY_RESOURCES\r\n"
|
||||
"\r\n"
|
||||
"#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r\n"
|
||||
"#ifdef _WIN32\r\n"
|
||||
"LANGUAGE 9, 1\r\n"
|
||||
"#pragma code_page(1252)\r\n"
|
||||
"#endif //_WIN32\r\n"
|
||||
"#include ""res\\smpackage.rc2"" // non-Microsoft Visual C++ edited resources\r\n"
|
||||
"#include ""afxres.rc"" // Standard components\r\n"
|
||||
"#endif\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Icon
|
||||
//
|
||||
|
||||
// Icon with lowest ID value placed first to ensure application icon
|
||||
// remains consistent on all systems.
|
||||
IDR_MAINFRAME ICON DISCARDABLE "smpackage.ICO"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Dialog
|
||||
//
|
||||
|
||||
IDD_MANAGER DIALOGEX 0, 0, 332, 234
|
||||
STYLE DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_VISIBLE |
|
||||
WS_CAPTION | WS_SYSMENU
|
||||
EXSTYLE WS_EX_APPWINDOW
|
||||
CAPTION "Stepmania Package Manager"
|
||||
FONT 8, "MS Sans Serif"
|
||||
BEGIN
|
||||
DEFPUSHBUTTON "Close",IDOK,260,215,65,14
|
||||
LISTBOX IDC_LIST_SONGS,5,45,260,160,LBS_SORT |
|
||||
LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
|
||||
PUSHBUTTON "Play Stepmania",IDC_BUTTON_PLAY,5,215,70,15
|
||||
PUSHBUTTON "Export",IDC_BUTTON_EXPORT,275,75,50,15,WS_DISABLED
|
||||
CONTROL 135,IDC_STATIC,"Static",SS_BITMAP,0,0,295,30
|
||||
END
|
||||
|
||||
IDD_INSTALL DIALOG DISCARDABLE 0, 0, 332, 234
|
||||
STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION
|
||||
CAPTION "Stepmania Package Manager"
|
||||
FONT 8, "MS Sans Serif"
|
||||
BEGIN
|
||||
EDITTEXT IDC_EDIT_MESSAGE,5,45,320,160,ES_MULTILINE |
|
||||
ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER | NOT
|
||||
WS_TABSTOP
|
||||
DEFPUSHBUTTON "Finish >",IDOK,200,215,55,15
|
||||
PUSHBUTTON "Cancel",IDCANCEL,275,215,50,15
|
||||
PUSHBUTTON "< Back",IDC_BUTTON_BACK,145,215,55,15,WS_DISABLED
|
||||
CONTROL 133,IDC_STATIC,"Static",SS_BITMAP,0,0,258,37
|
||||
END
|
||||
|
||||
|
||||
#ifndef _MAC
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Version
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 1,0,0,1
|
||||
PRODUCTVERSION 1,0,0,1
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS 0x4L
|
||||
FILETYPE 0x1L
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904B0"
|
||||
BEGIN
|
||||
VALUE "CompanyName", "\0"
|
||||
VALUE "FileDescription", "smpackage MFC Application\0"
|
||||
VALUE "FileVersion", "1, 0, 0, 1\0"
|
||||
VALUE "InternalName", "smpackage\0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2002\0"
|
||||
VALUE "LegalTrademarks", "\0"
|
||||
VALUE "OriginalFilename", "smpackage.EXE\0"
|
||||
VALUE "ProductName", "smpackage Application\0"
|
||||
VALUE "ProductVersion", "1, 0, 0, 1\0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1200
|
||||
END
|
||||
END
|
||||
|
||||
#endif // !_MAC
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DESIGNINFO
|
||||
//
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
GUIDELINES DESIGNINFO DISCARDABLE
|
||||
BEGIN
|
||||
IDD_MANAGER, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 325
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 227
|
||||
END
|
||||
|
||||
IDD_INSTALL, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 325
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 227
|
||||
END
|
||||
END
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Bitmap
|
||||
//
|
||||
|
||||
INSTALL BITMAP DISCARDABLE "install.bmp"
|
||||
MANAGE BITMAP DISCARDABLE "manage.bmp"
|
||||
#endif // English (U.S.) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 3 resource.
|
||||
//
|
||||
#define _AFX_NO_SPLITTER_RESOURCES
|
||||
#define _AFX_NO_OLE_RESOURCES
|
||||
#define _AFX_NO_TRACKER_RESOURCES
|
||||
#define _AFX_NO_PROPERTY_RESOURCES
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
||||
#ifdef _WIN32
|
||||
LANGUAGE 9, 1
|
||||
#pragma code_page(1252)
|
||||
#endif //_WIN32
|
||||
#include "res\smpackage.rc2" // non-Microsoft Visual C++ edited resources
|
||||
#include "afxres.rc" // Standard components
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
|
||||
@@ -0,0 +1,210 @@
|
||||
// smpackageDlg.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "smpackage.h"
|
||||
#include "smpackageDlg.h"
|
||||
#include "../RageUtil.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CSmpackageDlg dialog
|
||||
|
||||
CSmpackageDlg::CSmpackageDlg(CWnd* pParent /*=NULL*/)
|
||||
: CDialog(CSmpackageDlg::IDD, pParent)
|
||||
{
|
||||
//{{AFX_DATA_INIT(CSmpackageDlg)
|
||||
// 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 CSmpackageDlg::DoDataExchange(CDataExchange* pDX)
|
||||
{
|
||||
CDialog::DoDataExchange(pDX);
|
||||
//{{AFX_DATA_MAP(CSmpackageDlg)
|
||||
DDX_Control(pDX, IDC_BUTTON_EXPORT, m_buttonExport);
|
||||
DDX_Control(pDX, IDC_LIST_SONGS, m_listBoxSongs);
|
||||
//}}AFX_DATA_MAP
|
||||
}
|
||||
|
||||
BEGIN_MESSAGE_MAP(CSmpackageDlg, CDialog)
|
||||
//{{AFX_MSG_MAP(CSmpackageDlg)
|
||||
ON_WM_PAINT()
|
||||
ON_WM_QUERYDRAGICON()
|
||||
ON_LBN_SELCHANGE(IDC_LIST_SONGS, OnSelchangeListSongs)
|
||||
ON_BN_CLICKED(IDC_BUTTON_EXPORT, OnButtonExport)
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CSmpackageDlg message handlers
|
||||
|
||||
BOOL CSmpackageDlg::OnInitDialog()
|
||||
{
|
||||
CDialog::OnInitDialog();
|
||||
|
||||
// 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
|
||||
|
||||
//
|
||||
// TODO: Add extra initialization here
|
||||
//
|
||||
|
||||
// Find all song directories
|
||||
CStringArray arrayGroupDirs;
|
||||
GetDirListing( "Songs\\*.*", arrayGroupDirs, true );
|
||||
|
||||
for( int i=0; i<arrayGroupDirs.GetSize(); i++ )
|
||||
{
|
||||
CString sGroupName = arrayGroupDirs[i];
|
||||
|
||||
CStringArray arraySongDirs;
|
||||
GetDirListing( "Songs\\" + sGroupName + "\\*.*", arraySongDirs, true );
|
||||
|
||||
for( int j=0; j<arraySongDirs.GetSize(); j++ )
|
||||
{
|
||||
CString sSongName = arraySongDirs[j];
|
||||
|
||||
m_listBoxSongs.AddString( sGroupName + "\\" + sSongName );
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE; // return TRUE unless you set the focus to a control
|
||||
}
|
||||
|
||||
// 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 CSmpackageDlg::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 CSmpackageDlg::OnQueryDragIcon()
|
||||
{
|
||||
return (HCURSOR) m_hIcon;
|
||||
}
|
||||
|
||||
void CSmpackageDlg::OnSelchangeListSongs()
|
||||
{
|
||||
// TODO: Add your control notification handler code here
|
||||
int iCurSel = m_listBoxSongs.GetCurSel();
|
||||
if( iCurSel == LB_ERR ) // no song is selected
|
||||
{
|
||||
m_buttonExport.EnableWindow( false );
|
||||
return;
|
||||
}
|
||||
|
||||
m_buttonExport.EnableWindow( true );
|
||||
|
||||
}
|
||||
|
||||
void CSmpackageDlg::OnButtonExport()
|
||||
{
|
||||
// TODO: Add your control notification handler code here
|
||||
|
||||
// Get the path to the selected song folder
|
||||
int iCurSel = m_listBoxSongs.GetCurSel();
|
||||
CString sSongDir;
|
||||
m_listBoxSongs.GetText( iCurSel, sSongDir );
|
||||
sSongDir = "Songs\\" + sSongDir;
|
||||
//MessageBox( ssprintf("sSongDir is '%s'", sSongDir), "", MB_OK );
|
||||
|
||||
|
||||
// Extract the group name and song name
|
||||
CStringArray arrayPathBits;
|
||||
split( sSongDir, "\\", arrayPathBits );
|
||||
CString sGroupName = arrayPathBits[1];
|
||||
CString sSongName = arrayPathBits[2];
|
||||
CString sGroupDir = "Songs\\" + sGroupName;
|
||||
|
||||
|
||||
// Get path to desktop
|
||||
CString sDesktopPath = getenv("USERPROFILE");
|
||||
sDesktopPath += "\\Desktop\\";
|
||||
//MessageBox( ssprintf("Desktop path is '%s'", sDesktopPath), "", MB_OK );
|
||||
|
||||
|
||||
// Create a new zip file on the desktop
|
||||
CString sZipFileName = sSongName + ".smzip";
|
||||
CString sZipFilePath = sDesktopPath + sZipFileName;
|
||||
//MessageBox( ssprintf("sZipFilePath is '%s'", sZipFilePath), "", MB_OK );
|
||||
try
|
||||
{
|
||||
m_zip.Open( sZipFilePath, CZipArchive::create );
|
||||
}
|
||||
catch( CException* e )
|
||||
{
|
||||
MessageBox( ssprintf("Error creating zip file '%s'", sDesktopPath), "", MB_OK );
|
||||
m_zip.Close();
|
||||
e->Delete();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
CStringArray arrayFiles;
|
||||
GetDirListing( sSongDir + "\\*.*", arrayFiles );
|
||||
//m_zip.AddNewFile( sRelPathToSelectedSong, 0, true ); // add the directory
|
||||
|
||||
m_zip.AddNewFile( "Songs", 0, true );
|
||||
m_zip.AddNewFile( sGroupDir, 0, true );
|
||||
m_zip.AddNewFile( sSongDir, 0, true );
|
||||
|
||||
for( int i=0; i<arrayFiles.GetSize(); i++ )
|
||||
{
|
||||
CString sFileName = arrayFiles[i];
|
||||
CString sFilePath = sSongDir + "\\" + sFileName;
|
||||
try
|
||||
{
|
||||
m_zip.AddNewFile( sFilePath, 9, true );
|
||||
}
|
||||
catch (CException* e)
|
||||
{
|
||||
MessageBox( ssprintf("Error adding file '%s'.", sFilePath), "", MB_OK );
|
||||
m_zip.Close();
|
||||
e->Delete();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
AfxMessageBox( ssprintf("Successfully exported '%s' to '%s' on your Desktop.", sSongDir, sZipFileName) );
|
||||
|
||||
|
||||
m_zip.Close();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
// smpackageDlg.h : header file
|
||||
//
|
||||
|
||||
#if !defined(AFX_SMPACKAGEDLG_H__E60DA2DD_D8D6_42BC_9049_631EAFBAA1F6__INCLUDED_)
|
||||
#define AFX_SMPACKAGEDLG_H__E60DA2DD_D8D6_42BC_9049_631EAFBAA1F6__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CSmpackageDlg dialog
|
||||
|
||||
|
||||
#include "ZipArchive\ZipArchive.h"
|
||||
|
||||
|
||||
class CSmpackageDlg : public CDialog
|
||||
{
|
||||
// Construction
|
||||
public:
|
||||
CSmpackageDlg(CWnd* pParent = NULL); // standard constructor
|
||||
|
||||
// Dialog Data
|
||||
//{{AFX_DATA(CSmpackageDlg)
|
||||
enum { IDD = IDD_SMPACKAGE_DIALOG };
|
||||
CButton m_buttonExport;
|
||||
CListBox m_listBoxSongs;
|
||||
//}}AFX_DATA
|
||||
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(CSmpackageDlg)
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
HICON m_hIcon;
|
||||
CZipArchive m_zip;
|
||||
|
||||
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(CSmpackageDlg)
|
||||
virtual BOOL OnInitDialog();
|
||||
afx_msg void OnPaint();
|
||||
afx_msg HCURSOR OnQueryDragIcon();
|
||||
afx_msg void OnSelchangeListSongs();
|
||||
afx_msg void OnButtonExport();
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
};
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_SMPACKAGEDLG_H__E60DA2DD_D8D6_42BC_9049_631EAFBAA1F6__INCLUDED_)
|
||||
Reference in New Issue
Block a user