checked in package manager

This commit is contained in:
Chris Danford
2002-01-28 21:24:17 +00:00
parent 294303e143
commit 5c8fc16b34
43 changed files with 7760 additions and 45 deletions
+28 -17
View File
@@ -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
+17 -20
View File
@@ -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;
}
+8 -8
View File
@@ -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_)
+8
View File
@@ -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"
+26
View File
@@ -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: &quot;zlib.h&quot; and &quot;zconf.h&quot; 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 &quot;ZipArchive.h&quot;):</p>
<h4>Method 1</h4>
<p>Add &quot;..\Zip\debug(release)\Zip.lib&quot; to <em>Project
Settings-&gt;Link-&gt;Input-&gt;Object/library modules</em> and add Zip
directory to the preprocessor searches (<em>Project Settings -&gt; C++ -&gt;
Preprocessor -&gt; 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
&quot;.zip&quot;. You should also label each disk with the appropriate label
starting from &quot;pkback# 001&quot;.</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&nbsp; 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>&nbsp;&nbsp;&nbsp; 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>
&nbsp;&nbsp;&nbsp; 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>
&nbsp;&nbsp; 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(&quot;Select directory to extract files&quot;);
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 &lt; 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-&gt;IsKindOf( RUNTIME_CLASS( CZipException )))
{
CZipException* p = (CZipException*) e;
//... and so on
}
else if (e-&gt;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-&gt;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>&quot;Project-&gt;Settings-&gt;
c/c++ -&gt;Code Generation-&gt;Use run-time library&quot; </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>&quot;Use run-time library&quot;</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 -&gt; Add To
Project -&gt; Files...)</em>
<li>go to the project setting dialog <em>(Project -&gt; Settings)</em>
<li>select debug configurations <em>(Setting For -&gt; 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>&quot;Exclude
file from build&quot;</em>
<li>select release configurations
<li>select <em>zlib_.lib</em> and exclude it from these builds</li>
</ul>
<p>&nbsp;</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.&nbsp;</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>&nbsp;</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_)
+279
View File
@@ -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

+26
View File
@@ -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

+66
View File
@@ -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
+120
View File
@@ -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;
}
+170
View File
@@ -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
+49
View File
@@ -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.
+209
View File
@@ -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
+210
View File
@@ -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();
}
+57
View File
@@ -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_)