зеркало из https://github.com/mozilla/gecko-dev.git
*** NOT PART OF THE BUILD PROCESS
bug # 163739 - XPI Packager adding the xpi packager to the mozilla tree. this is a windows only app used to build the xpi packager for building self installing xpi files.
This commit is contained in:
Родитель
d1f6284b02
Коммит
5416ac65f4
|
@ -0,0 +1,154 @@
|
|||
// FileChooserDlg.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "XPIPackager.h"
|
||||
#include "FileChooserDlg.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CFileChooserDlg dialog
|
||||
|
||||
|
||||
CFileChooserDlg::CFileChooserDlg(int a_FileType, CString& a_PLID, CString& a_FileName, const CString& a_Domain_Name,
|
||||
const CString& a_Product_Name, const CString& a_Version,
|
||||
CWnd* pParent /*=NULL*/)
|
||||
: CDialog(CFileChooserDlg::IDD, pParent)
|
||||
{
|
||||
//{{AFX_DATA_INIT(CFileChooserDlg)
|
||||
m_PLID_Value = _T("");
|
||||
m_FileName_Value = _T("");
|
||||
//}}AFX_DATA_INIT
|
||||
|
||||
// set members
|
||||
m_PLID = a_PLID;
|
||||
m_FileName = a_FileName;
|
||||
m_Domain_Name = a_Domain_Name;
|
||||
m_Product_Name = a_Product_Name;
|
||||
m_Version = a_Version;
|
||||
|
||||
m_FileType = a_FileType;
|
||||
}
|
||||
|
||||
|
||||
void CFileChooserDlg::DoDataExchange(CDataExchange* pDX)
|
||||
{
|
||||
CDialog::DoDataExchange(pDX);
|
||||
//{{AFX_DATA_MAP(CFileChooserDlg)
|
||||
DDX_Text(pDX, IDC_PLID, m_PLID_Value);
|
||||
DDX_Text(pDX, IDC_FILENAME, m_FileName_Value);
|
||||
//}}AFX_DATA_MAP
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(CFileChooserDlg, CDialog)
|
||||
//{{AFX_MSG_MAP(CFileChooserDlg)
|
||||
ON_BN_CLICKED(IDC_PLID_HELP, OnPLIDHelp)
|
||||
ON_BN_CLICKED(IDC_FILENAME_BROWSE, OnFilenameBrowse)
|
||||
ON_BN_CLICKED(IDC_AUTO_PLID, OnAutoPLID)
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CFileChooserDlg message handlers
|
||||
|
||||
void CFileChooserDlg::OnPLIDHelp()
|
||||
{
|
||||
// TODO: Add your control notification handler code here
|
||||
CString tempString = "http://www.mozilla.org/projects/plugins/plugin-identifier.html";
|
||||
ShellExecute(NULL,"open",tempString,"","",SW_SHOWDEFAULT);
|
||||
}
|
||||
|
||||
|
||||
static char BASED_CODE szFilter[] = "DLL Files (*.dll)|*.dll|Executeable Files (*.exe)|*.exe|XPT Files (*.xpt)|*.xpt|";
|
||||
static char BASED_CODE szFilter2[] = "XPT Files (*.xpt)|*.xpt|DLL Files (*.dll)|*.dll|Executeable Files (*.exe)|*.exe|";
|
||||
|
||||
void CFileChooserDlg::OnFilenameBrowse()
|
||||
{
|
||||
// TODO: Add your control notification handler code here
|
||||
// TODO: Add your control notification handler code here
|
||||
UpdateData(true);
|
||||
CString temp;
|
||||
if(m_FileType == CXPIPackagerApp::XPT_TYPE)
|
||||
temp = szFilter2;
|
||||
else
|
||||
temp = szFilter;
|
||||
|
||||
CFileDialog dlg(true, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, temp);
|
||||
|
||||
if(IDOK == dlg.DoModal())
|
||||
{
|
||||
CFile t_File;
|
||||
CString t_PluginFileName = dlg.GetPathName();
|
||||
if(t_File.Open(t_PluginFileName, CFile::modeRead))
|
||||
{
|
||||
CFileStatus t_FileStatus;
|
||||
if(t_File.GetStatus(t_FileStatus))
|
||||
{
|
||||
m_FileName_Value = t_PluginFileName;
|
||||
m_FileName = t_PluginFileName;// set the member
|
||||
t_File.Close();
|
||||
}
|
||||
}
|
||||
UpdateData(false);
|
||||
}
|
||||
}
|
||||
|
||||
void CFileChooserDlg::OnAutoPLID()
|
||||
{
|
||||
// TODO: Add your control notification handler code here
|
||||
UpdateData(true);
|
||||
CString temp;
|
||||
temp = "@";
|
||||
temp += m_Domain_Name;
|
||||
temp += "/";
|
||||
temp += m_Product_Name;
|
||||
temp += ",version=";
|
||||
temp += m_Version;
|
||||
|
||||
m_PLID_Value = temp;
|
||||
m_PLID = temp;// set the member
|
||||
|
||||
UpdateData(false);
|
||||
}
|
||||
|
||||
BOOL CFileChooserDlg::OnInitDialog()
|
||||
{
|
||||
CDialog::OnInitDialog();
|
||||
|
||||
// TODO: Add extra initialization here
|
||||
UpdateData(true);
|
||||
|
||||
m_PLID_Value = m_PLID;
|
||||
m_FileName_Value = m_FileName;
|
||||
|
||||
UpdateData(false);
|
||||
|
||||
return TRUE; // return TRUE unless you set the focus to a control
|
||||
// EXCEPTION: OCX Property Pages should return FALSE
|
||||
}
|
||||
|
||||
void CFileChooserDlg::OnOK()
|
||||
{
|
||||
// TODO: Add extra validation here
|
||||
UpdateData(true);
|
||||
m_PLID = m_PLID_Value;
|
||||
m_FileName = m_FileName_Value;
|
||||
|
||||
CFile t_File;
|
||||
if(! t_File.Open(m_FileName, CFile::modeRead))
|
||||
{
|
||||
CString tMessage = m_FileName;
|
||||
tMessage += " is not a valid File or File Name";
|
||||
MessageBox(tMessage, "Not a valid File!", MB_OK + MB_ICONEXCLAMATION);
|
||||
return;
|
||||
}
|
||||
t_File.Close();
|
||||
|
||||
CDialog::OnOK();
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
#if !defined(AFX_FILECHOOSERDLG_H__4F41CBA6_155C_4CC5_8E5E_7BA0A2F36C93__INCLUDED_)
|
||||
#define AFX_FILECHOOSERDLG_H__4F41CBA6_155C_4CC5_8E5E_7BA0A2F36C93__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
// FileChooserDlg.h : header file
|
||||
//
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CFileChooserDlg dialog
|
||||
|
||||
class CFileChooserDlg : public CDialog
|
||||
{
|
||||
// Construction
|
||||
public:
|
||||
CFileChooserDlg(int a_FileType, CString& a_PLID, CString& a_FileName, const CString& m_Domain_Name,
|
||||
const CString& m_Product_Name, const CString& a_Version,
|
||||
CWnd* pParent = NULL); // standard constructor
|
||||
|
||||
// Dialog Data
|
||||
//{{AFX_DATA(CFileChooserDlg)
|
||||
enum { IDD = IDD_FILE_CHOOSER };
|
||||
CString m_PLID_Value;
|
||||
CString m_FileName_Value;
|
||||
//}}AFX_DATA
|
||||
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(CFileChooserDlg)
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(CFileChooserDlg)
|
||||
afx_msg void OnPLIDHelp();
|
||||
afx_msg void OnFilenameBrowse();
|
||||
afx_msg void OnAutoPLID();
|
||||
virtual BOOL OnInitDialog();
|
||||
virtual void OnOK();
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
|
||||
private:
|
||||
CString m_PLID;
|
||||
CString m_FileName;
|
||||
CString m_Domain_Name;
|
||||
CString m_Product_Name;
|
||||
CString m_Version;
|
||||
|
||||
int m_FileType;
|
||||
|
||||
public:
|
||||
CString GetFileName(){return m_FileName;}
|
||||
CString GetPLIDForFileName(){return m_PLID;}
|
||||
};
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_FILECHOOSERDLG_H__4F41CBA6_155C_4CC5_8E5E_7BA0A2F36C93__INCLUDED_)
|
|
@ -0,0 +1,86 @@
|
|||
// MIMETypeChooseDlg.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "XPIPackager.h"
|
||||
#include "MIMETypeChooseDlg.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CMIMETypeChooseDlg dialog
|
||||
|
||||
|
||||
CMIMETypeChooseDlg::CMIMETypeChooseDlg(CString& a_MIMEType, CString& a_Suffix, CString& a_SuffixDescription, CString& a_Plugin,
|
||||
CStringArray* a_Array, CWnd* pParent /*=NULL*/)
|
||||
: CDialog(CMIMETypeChooseDlg::IDD, pParent)
|
||||
{
|
||||
//{{AFX_DATA_INIT(CMIMETypeChooseDlg)
|
||||
m_MIMEType_Value = _T("");
|
||||
m_Suffix_Value = _T("");
|
||||
m_Suffix_Description_Value = _T("");
|
||||
//}}AFX_DATA_INIT
|
||||
// set members
|
||||
m_PluginList = a_Array;
|
||||
m_MIMEType_Value = a_MIMEType;
|
||||
m_Suffix_Value = a_Suffix;
|
||||
m_Suffix_Description_Value = a_SuffixDescription;
|
||||
m_Plugin = a_Plugin;
|
||||
}
|
||||
|
||||
|
||||
void CMIMETypeChooseDlg::DoDataExchange(CDataExchange* pDX)
|
||||
{
|
||||
CDialog::DoDataExchange(pDX);
|
||||
//{{AFX_DATA_MAP(CMIMETypeChooseDlg)
|
||||
DDX_Control(pDX, IDC_PLUGIN_LIST, m_Plugin_List_Control);
|
||||
DDX_Text(pDX, IDC_MIMETYPE, m_MIMEType_Value);
|
||||
DDX_Text(pDX, IDC_SUFFIX, m_Suffix_Value);
|
||||
DDX_Text(pDX, IDC_SUFFIX_DESCRIPTION, m_Suffix_Description_Value);
|
||||
//}}AFX_DATA_MAP
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(CMIMETypeChooseDlg, CDialog)
|
||||
//{{AFX_MSG_MAP(CMIMETypeChooseDlg)
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CMIMETypeChooseDlg message handlers
|
||||
|
||||
BOOL CMIMETypeChooseDlg::OnInitDialog()
|
||||
{
|
||||
CDialog::OnInitDialog();
|
||||
|
||||
// TODO: Add extra initialization here
|
||||
CString temp;
|
||||
for(int i = 0; i < m_PluginList->GetSize(); i++)
|
||||
{
|
||||
temp = m_PluginList->ElementAt(i);
|
||||
m_Plugin_List_Control.AddString(temp);
|
||||
}
|
||||
m_Plugin_List_Control.SelectString(-1, m_Plugin);
|
||||
UpdateData(false);
|
||||
return TRUE; // return TRUE unless you set the focus to a control
|
||||
// EXCEPTION: OCX Property Pages should return FALSE
|
||||
}
|
||||
|
||||
void CMIMETypeChooseDlg::OnOK()
|
||||
{
|
||||
// TODO: Add extra validation here
|
||||
UpdateData(true);
|
||||
if(m_Plugin_List_Control.GetCurSel() == LB_ERR )
|
||||
{
|
||||
CString tMessage = "You must select a Plugin File from the List in order to add a MIME Type.";
|
||||
MessageBox(tMessage, "Must Choose A Plugin File!", MB_OK + MB_ICONEXCLAMATION);
|
||||
return;
|
||||
}
|
||||
m_Plugin_List_Control.GetText(m_Plugin_List_Control.GetCurSel(), m_Plugin);
|
||||
|
||||
CDialog::OnOK();
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
#if !defined(AFX_MIMETYPECHOOSEDLG_H__DD9847ED_1BC0_42AA_BC61_FA4F65DEDB8E__INCLUDED_)
|
||||
#define AFX_MIMETYPECHOOSEDLG_H__DD9847ED_1BC0_42AA_BC61_FA4F65DEDB8E__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
// MIMETypeChooseDlg.h : header file
|
||||
//
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CMIMETypeChooseDlg dialog
|
||||
|
||||
class CMIMETypeChooseDlg : public CDialog
|
||||
{
|
||||
// Construction
|
||||
public:
|
||||
CMIMETypeChooseDlg(CString& a_MIMEType, CString& a_Suffix, CString& a_SuffixDescription, CString& a_Plugin,
|
||||
CStringArray* a_Array, CWnd* pParent = NULL); // standard constructor
|
||||
|
||||
// Dialog Data
|
||||
//{{AFX_DATA(CMIMETypeChooseDlg)
|
||||
enum { IDD = IDD_MIMETYPE_CHOOSER };
|
||||
CListBox m_Plugin_List_Control;
|
||||
CString m_MIMEType_Value;
|
||||
CString m_Suffix_Value;
|
||||
CString m_Suffix_Description_Value;
|
||||
//}}AFX_DATA
|
||||
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(CMIMETypeChooseDlg)
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(CMIMETypeChooseDlg)
|
||||
virtual BOOL OnInitDialog();
|
||||
virtual void OnOK();
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
|
||||
private:
|
||||
CStringArray* m_PluginList;
|
||||
CString m_Plugin;
|
||||
|
||||
public:
|
||||
CString GetMIMEType(){return m_MIMEType_Value;}
|
||||
CString GetSuffix(){return m_Suffix_Value;}
|
||||
CString GetSuffixDescription(){return m_Suffix_Description_Value;}
|
||||
CString GetPlugin(){return m_Plugin;}
|
||||
};
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_MIMETYPECHOOSEDLG_H__DD9847ED_1BC0_42AA_BC61_FA4F65DEDB8E__INCLUDED_)
|
|
@ -0,0 +1,8 @@
|
|||
// stdafx.cpp : source file that includes just the standard includes
|
||||
// XPIPackager.pch will be the pre-compiled header
|
||||
// stdafx.obj will contain the pre-compiled type information
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
// stdafx.h : include file for standard system include files,
|
||||
// or project specific include files that are used frequently, but
|
||||
// are changed infrequently
|
||||
//
|
||||
|
||||
#if !defined(AFX_STDAFX_H__ACD5C3D0_F53A_4DB7_843A_6D032C6088D6__INCLUDED_)
|
||||
#define AFX_STDAFX_H__ACD5C3D0_F53A_4DB7_843A_6D032C6088D6__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__ACD5C3D0_F53A_4DB7_843A_6D032C6088D6__INCLUDED_)
|
|
@ -0,0 +1,72 @@
|
|||
// XPIPackager.cpp : Defines the class behaviors for the application.
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "XPIPackager.h"
|
||||
#include "XPIPackagerDlg.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CXPIPackagerApp
|
||||
|
||||
BEGIN_MESSAGE_MAP(CXPIPackagerApp, CWinApp)
|
||||
//{{AFX_MSG_MAP(CXPIPackagerApp)
|
||||
// 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()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CXPIPackagerApp construction
|
||||
|
||||
CXPIPackagerApp::CXPIPackagerApp()
|
||||
{
|
||||
// TODO: add construction code here,
|
||||
// Place all significant initialization in InitInstance
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// The one and only CXPIPackagerApp object
|
||||
|
||||
CXPIPackagerApp theApp;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CXPIPackagerApp initialization
|
||||
|
||||
BOOL CXPIPackagerApp::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
|
||||
|
||||
CXPIPackagerDlg dlg;
|
||||
m_pMainWnd = &dlg;
|
||||
int nResponse = dlg.DoModal();
|
||||
if (nResponse == IDOK)
|
||||
{
|
||||
// TODO: Place code here to handle when the dialog is
|
||||
// dismissed with OK
|
||||
}
|
||||
else if (nResponse == IDCANCEL)
|
||||
{
|
||||
// TODO: Place code here to handle when the dialog is
|
||||
// dismissed with Cancel
|
||||
}
|
||||
|
||||
// Since the dialog has been closed, return FALSE so that we exit the
|
||||
// application, rather than start the application's message pump.
|
||||
return FALSE;
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
Microsoft Developer Studio Workspace File, Format Version 6.00
|
||||
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "XPIPackager"=.\XPIPackager.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Global:
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<3>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
// XPIPackager.h : main header file for the XPIPACKAGER application
|
||||
//
|
||||
|
||||
#if !defined(AFX_XPIPACKAGER_H__B014FADE_A3A9_4663_8F39_F03905B8EDCA__INCLUDED_)
|
||||
#define AFX_XPIPACKAGER_H__B014FADE_A3A9_4663_8F39_F03905B8EDCA__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
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CXPIPackagerApp:
|
||||
// See XPIPackager.cpp for the implementation of this class
|
||||
//
|
||||
|
||||
class CXPIPackagerApp : public CWinApp
|
||||
{
|
||||
public:
|
||||
enum FILETYPE{DLL_TYPE = 0, XPT_TYPE, NUM_TYPES};
|
||||
CXPIPackagerApp();
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(CXPIPackagerApp)
|
||||
public:
|
||||
virtual BOOL InitInstance();
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
|
||||
//{{AFX_MSG(CXPIPackagerApp)
|
||||
// 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_XPIPACKAGER_H__B014FADE_A3A9_4663_8F39_F03905B8EDCA__INCLUDED_)
|
|
@ -0,0 +1,342 @@
|
|||
//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
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Dialog
|
||||
//
|
||||
|
||||
IDD_ABOUTBOX DIALOG DISCARDABLE 0, 0, 235, 55
|
||||
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "About XPIPackager"
|
||||
FONT 8, "MS Sans Serif"
|
||||
BEGIN
|
||||
ICON IDR_MAINFRAME,IDC_STATIC,11,17,20,20
|
||||
LTEXT "XPIPackager Version 1.1",IDC_STATIC,40,10,119,8,
|
||||
SS_NOPREFIX
|
||||
LTEXT "Copyright (C) 2002",IDC_STATIC,40,25,119,8
|
||||
DEFPUSHBUTTON "OK",IDOK,178,7,50,14,WS_GROUP
|
||||
END
|
||||
|
||||
IDD_XPIPACKAGER_DIALOG DIALOGEX 0, 0, 461, 313
|
||||
STYLE DS_MODALFRAME | WS_MINIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION |
|
||||
WS_SYSMENU
|
||||
EXSTYLE WS_EX_APPWINDOW
|
||||
CAPTION "XPI Installer Packager"
|
||||
FONT 8, "MS Sans Serif"
|
||||
BEGIN
|
||||
LTEXT "XPI Archive Name - REQUIRED \n(ie. MyPluginInstall.xpi)",
|
||||
IDC_STATIC,7,7,120,16
|
||||
EDITTEXT IDC_ARCHIVE_NAME,7,23,119,14,ES_AUTOHSCROLL
|
||||
LTEXT "Company Name",IDC_STATIC,131,14,132,8
|
||||
EDITTEXT IDC_COMPANY_NAME,131,23,132,14,ES_AUTOHSCROLL
|
||||
LTEXT "PLUGIN Description",IDC_STATIC,266,15,182,8
|
||||
EDITTEXT IDC_PLUGIN_DESCRIPTION,266,23,188,14,ES_AUTOHSCROLL
|
||||
GROUPBOX "Mandatory PLID Information",IDC_STATIC,7,43,364,64
|
||||
LTEXT "@Domain (ie. MyDomain.com)",IDC_STATIC,9,53,117,8
|
||||
EDITTEXT IDC_DOMAIN_NAME,9,62,117,14,ES_AUTOHSCROLL
|
||||
LTEXT "Product Name",IDC_STATIC,131,53,117,8
|
||||
EDITTEXT IDC_PRODUCT_NAME,131,62,117,14,ES_AUTOHSCROLL
|
||||
LTEXT "Plugin Version",IDC_STATIC,251,53,117,8
|
||||
EDITTEXT IDC_PLUGIN_VERSION,251,62,117,14,ES_AUTOHSCROLL
|
||||
LTEXT "PLID - Plugin Identifier",IDC_STATIC,11,80,226,8
|
||||
EDITTEXT IDC_PLID,9,88,227,14,ES_AUTOHSCROLL
|
||||
PUSHBUTTON "&Auto Generate PLID",IDC_AUTO_PLID,241,88,72,14
|
||||
PUSHBUTTON "&PLID Help",IDC_PLID_HELP,317,88,50,14
|
||||
LTEXT "PLUGIN FILES - REQUIRED (ie. MyPlugin.dll)",IDC_STATIC,
|
||||
7,124,219,8
|
||||
CONTROL "List1",IDC_PLUGIN_LIST,"SysListView32",LVS_REPORT |
|
||||
LVS_SINGLESEL | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,7,
|
||||
133,219,50
|
||||
PUSHBUTTON "&Add File",IDC_PLUGIN_BROWSE,7,185,50,14
|
||||
PUSHBUTTON "&Remove File",IDC_PLUGIN_REMOVE,59,185,50,14
|
||||
LTEXT "PLUGIN Size:",IDC_STATIC,139,188,45,8
|
||||
EDITTEXT IDC_PLUGIN_SIZE,186,185,40,14,ES_RIGHT | ES_AUTOHSCROLL |
|
||||
ES_NUMBER
|
||||
LTEXT "COMPONENT FILES (ie. MyScriptable.xpt)",IDC_STATIC,233,
|
||||
124,215,8
|
||||
CONTROL "List2",IDC_COMPONENT_LIST,"SysListView32",LVS_REPORT |
|
||||
LVS_SINGLESEL | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,
|
||||
233,133,219,50
|
||||
PUSHBUTTON "&Add File",IDC_COMPONENT_BROWSE,232,185,50,14
|
||||
PUSHBUTTON "&Remove File",IDC_COMPONENT_REMOVE,284,185,50,14
|
||||
LTEXT "COMPONENT Size:",IDC_STATIC,347,188,64,8
|
||||
EDITTEXT IDC_COMPONENT_SIZE,412,185,40,14,ES_RIGHT |
|
||||
ES_AUTOHSCROLL | ES_NUMBER
|
||||
LTEXT "MIME Type List:",IDC_STATIC,7,208,52,8
|
||||
CONTROL "List3",IDC_MIME_LIST,"SysListView32",LVS_REPORT |
|
||||
LVS_SINGLESEL | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,7,
|
||||
219,445,64
|
||||
PUSHBUTTON "&Add MIME Type",IDC_MIMETYPE_ADD,7,285,71,14
|
||||
PUSHBUTTON "&Remove MIME Type",IDC_MIMETYPE_REMOVE,81,285,71,14
|
||||
GROUPBOX "Archive Controls",IDC_STATIC,373,43,81,64
|
||||
DEFPUSHBUTTON "Create Archive",IDOK,386,54,53,14
|
||||
PUSHBUTTON "Close",IDCANCEL,386,70,53,14
|
||||
PUSHBUTTON "&Help",IDC_BIG_HELP,386,86,53,14
|
||||
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", "XPIPackager MFC Application\0"
|
||||
VALUE "FileVersion", "1, 0, 0, 1\0"
|
||||
VALUE "InternalName", "XPIPackager\0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2002\0"
|
||||
VALUE "LegalTrademarks", "\0"
|
||||
VALUE "OriginalFilename", "XPIPackager.EXE\0"
|
||||
VALUE "ProductName", "XPIPackager 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_ABOUTBOX, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 228
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 48
|
||||
END
|
||||
|
||||
IDD_XPIPACKAGER_DIALOG, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 454
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 306
|
||||
END
|
||||
END
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// String Table
|
||||
//
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
BEGIN
|
||||
IDS_ABOUTBOX "&About XPIPackager..."
|
||||
END
|
||||
|
||||
#endif // English (U.S.) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// English (U.S.) (unknown sub-lang: 0xC) resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENW)
|
||||
#ifdef _WIN32
|
||||
LANGUAGE LANG_ENGLISH, 0xC
|
||||
#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\\XPIPackager.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 "res\\XPIPackager.ico"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Dialog
|
||||
//
|
||||
|
||||
IDD_FILE_CHOOSER DIALOG DISCARDABLE 0, 0, 159, 126
|
||||
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "File Chooser"
|
||||
FONT 8, "MS Sans Serif"
|
||||
BEGIN
|
||||
LTEXT "Please input the filename to add:",IDC_STATIC,7,7,104,8
|
||||
EDITTEXT IDC_FILENAME,7,16,142,14,ES_AUTOHSCROLL
|
||||
PUSHBUTTON "&Browse",IDC_FILENAME_BROWSE,7,32,50,14
|
||||
LTEXT "Please input the PLID for this file:",IDC_STATIC,7,52,
|
||||
105,8
|
||||
EDITTEXT IDC_PLID,7,61,142,14,ES_AUTOHSCROLL
|
||||
PUSHBUTTON "&Auto Generate PLID",IDC_AUTO_PLID,7,77,70,14
|
||||
PUSHBUTTON "&PLID Help",IDC_PLID_HELP,99,77,50,14
|
||||
DEFPUSHBUTTON "OK",IDOK,48,105,50,14
|
||||
PUSHBUTTON "Cancel",IDCANCEL,102,105,50,14
|
||||
END
|
||||
|
||||
IDD_MIMETYPE_CHOOSER DIALOG DISCARDABLE 0, 0, 175, 150
|
||||
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "MIME Type Chooser"
|
||||
FONT 8, "MS Sans Serif"
|
||||
BEGIN
|
||||
LTEXT "MIME Type",IDC_STATIC,7,14,114,8
|
||||
EDITTEXT IDC_MIMETYPE,7,22,161,14,ES_AUTOHSCROLL
|
||||
LTEXT "Suffix",IDC_STATIC,7,41,18,8
|
||||
EDITTEXT IDC_SUFFIX,7,49,40,14,ES_AUTOHSCROLL
|
||||
LTEXT "Suffix Description",IDC_STATIC,52,41,99,8
|
||||
EDITTEXT IDC_SUFFIX_DESCRIPTION,51,49,117,14,ES_AUTOHSCROLL
|
||||
LTEXT "Plugin File (Choose a Plugin for this MIME Type)",
|
||||
IDC_STATIC,7,74,161,8
|
||||
LISTBOX IDC_PLUGIN_LIST,7,83,161,41,LBS_NOINTEGRALHEIGHT |
|
||||
WS_VSCROLL | WS_TABSTOP
|
||||
DEFPUSHBUTTON "OK",IDOK,64,129,50,14
|
||||
PUSHBUTTON "Cancel",IDCANCEL,118,129,50,14
|
||||
END
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DESIGNINFO
|
||||
//
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
GUIDELINES DESIGNINFO DISCARDABLE
|
||||
BEGIN
|
||||
IDD_FILE_CHOOSER, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 152
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 119
|
||||
END
|
||||
|
||||
IDD_MIMETYPE_CHOOSER, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 168
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 143
|
||||
END
|
||||
END
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// JSCRIPT
|
||||
//
|
||||
|
||||
IDR_HEADER JSCRIPT DISCARDABLE "res\\header.js"
|
||||
IDR_BODY JSCRIPT DISCARDABLE "res\\body.js"
|
||||
IDR_FILLER JSCRIPT DISCARDABLE "res\\filler.js"
|
||||
#endif // English (U.S.) (unknown sub-lang: 0xC) 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\XPIPackager.rc2" // non-Microsoft Visual C++ edited resources
|
||||
#include "afxres.rc" // Standard components
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
|
|
@ -0,0 +1,810 @@
|
|||
// XPIPackagerDlg.cpp : implementation file
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "XPIPackager.h"
|
||||
#include "XPIPackagerDlg.h"
|
||||
#include "FileChooserDlg.h"
|
||||
#include "MIMETypeChooseDlg.h"
|
||||
#include "ZipArchive.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
#define COMPANY_DEFAULT_VALUE "My Plugin Company"
|
||||
#define PLUGIN_DESC_DEFAULT_VALUE "My Exemplary Plugin Mine All Mine"
|
||||
#define DOMAIN_DEFAULT_VALUE "www.MyPluginCompany.com"
|
||||
|
||||
#define ZIP_COMMAND "Y:\\workspace\\XPIinstaller\\Debug\\zip.exe -q "
|
||||
#define QUOTE "\""
|
||||
#define SPACE " "
|
||||
#define INSTALL_JS_FILE "install.js"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CAboutDlg dialog used for App About
|
||||
|
||||
class CAboutDlg : public CDialog
|
||||
{
|
||||
public:
|
||||
CAboutDlg();
|
||||
|
||||
// Dialog Data
|
||||
//{{AFX_DATA(CAboutDlg)
|
||||
enum { IDD = IDD_ABOUTBOX };
|
||||
//}}AFX_DATA
|
||||
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(CAboutDlg)
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
//{{AFX_MSG(CAboutDlg)
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
};
|
||||
|
||||
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
|
||||
{
|
||||
//{{AFX_DATA_INIT(CAboutDlg)
|
||||
//}}AFX_DATA_INIT
|
||||
}
|
||||
|
||||
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
|
||||
{
|
||||
CDialog::DoDataExchange(pDX);
|
||||
//{{AFX_DATA_MAP(CAboutDlg)
|
||||
//}}AFX_DATA_MAP
|
||||
}
|
||||
|
||||
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
|
||||
//{{AFX_MSG_MAP(CAboutDlg)
|
||||
// No message handlers
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CXPIPackagerDlg dialog
|
||||
|
||||
CXPIPackagerDlg::CXPIPackagerDlg(CWnd* pParent /*=NULL*/)
|
||||
: CDialog(CXPIPackagerDlg::IDD, pParent)
|
||||
{
|
||||
//{{AFX_DATA_INIT(CXPIPackagerDlg)
|
||||
m_Domain_Name_Value = _T("");
|
||||
m_PLID_Value = _T("");
|
||||
m_Plugin_Version_Value = _T("");
|
||||
m_Product_Name_Value = _T("");
|
||||
m_Archive_Name_Value = _T("");
|
||||
m_Component_Size_Value = 0;
|
||||
m_Company_Name_Value = _T("");
|
||||
m_Plugin_Size_Value = 0;
|
||||
m_Plugin_Description_Value = _T("");
|
||||
//}}AFX_DATA_INIT
|
||||
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
|
||||
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
|
||||
}
|
||||
|
||||
void CXPIPackagerDlg::DoDataExchange(CDataExchange* pDX)
|
||||
{
|
||||
CDialog::DoDataExchange(pDX);
|
||||
//{{AFX_DATA_MAP(CXPIPackagerDlg)
|
||||
DDX_Control(pDX, IDC_MIME_LIST, m_MIME_List_Control);
|
||||
DDX_Control(pDX, IDC_COMPONENT_LIST, m_Component_List_Control);
|
||||
DDX_Control(pDX, IDC_PLUGIN_LIST, m_Plugin_List_Control);
|
||||
DDX_Text(pDX, IDC_DOMAIN_NAME, m_Domain_Name_Value);
|
||||
DDX_Text(pDX, IDC_PLID, m_PLID_Value);
|
||||
DDX_Text(pDX, IDC_PLUGIN_VERSION, m_Plugin_Version_Value);
|
||||
DDX_Text(pDX, IDC_PRODUCT_NAME, m_Product_Name_Value);
|
||||
DDX_Text(pDX, IDC_ARCHIVE_NAME, m_Archive_Name_Value);
|
||||
DDX_Text(pDX, IDC_COMPONENT_SIZE, m_Component_Size_Value);
|
||||
DDX_Text(pDX, IDC_COMPANY_NAME, m_Company_Name_Value);
|
||||
DDX_Text(pDX, IDC_PLUGIN_SIZE, m_Plugin_Size_Value);
|
||||
DDX_Text(pDX, IDC_PLUGIN_DESCRIPTION, m_Plugin_Description_Value);
|
||||
//}}AFX_DATA_MAP
|
||||
}
|
||||
|
||||
BEGIN_MESSAGE_MAP(CXPIPackagerDlg, CDialog)
|
||||
//{{AFX_MSG_MAP(CXPIPackagerDlg)
|
||||
ON_WM_SYSCOMMAND()
|
||||
ON_WM_PAINT()
|
||||
ON_WM_QUERYDRAGICON()
|
||||
ON_BN_CLICKED(IDOK, OnCreate)
|
||||
ON_BN_CLICKED(IDC_AUTO_PLID, OnAutoPLID)
|
||||
ON_BN_CLICKED(IDC_BIG_HELP, OnBigHelp)
|
||||
ON_BN_CLICKED(IDC_PLID_HELP, OnPLIDHelp)
|
||||
ON_BN_CLICKED(IDC_COMPONENT_BROWSE, OnComponentBrowse)
|
||||
ON_BN_CLICKED(IDC_COMPONENT_REMOVE, OnComponentRemove)
|
||||
ON_BN_CLICKED(IDC_PLUGIN_BROWSE, OnPluginBrowse)
|
||||
ON_BN_CLICKED(IDC_PLUGIN_REMOVE, OnPluginRemove)
|
||||
ON_BN_CLICKED(IDC_MIMETYPE_ADD, OnMIMETypeAdd)
|
||||
ON_BN_CLICKED(IDC_MIMETYPE_REMOVE, OnMIMETypeRemove)
|
||||
ON_NOTIFY(NM_DBLCLK, IDC_PLUGIN_LIST, OnDblclkPluginList)
|
||||
ON_NOTIFY(NM_DBLCLK, IDC_COMPONENT_LIST, OnDblclkComponentList)
|
||||
ON_NOTIFY(NM_DBLCLK, IDC_MIME_LIST, OnDblclkMimeList)
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CXPIPackagerDlg message handlers
|
||||
|
||||
BOOL CXPIPackagerDlg::OnInitDialog()
|
||||
{
|
||||
CDialog::OnInitDialog();
|
||||
|
||||
// Add "About..." menu item to system menu.
|
||||
|
||||
// IDM_ABOUTBOX must be in the system command range.
|
||||
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
|
||||
ASSERT(IDM_ABOUTBOX < 0xF000);
|
||||
|
||||
CMenu* pSysMenu = GetSystemMenu(FALSE);
|
||||
if (pSysMenu != NULL)
|
||||
{
|
||||
CString strAboutMenu;
|
||||
strAboutMenu.LoadString(IDS_ABOUTBOX);
|
||||
if (!strAboutMenu.IsEmpty())
|
||||
{
|
||||
pSysMenu->AppendMenu(MF_SEPARATOR);
|
||||
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
|
||||
}
|
||||
}
|
||||
|
||||
// Set the icon for this dialog. The framework does this automatically
|
||||
// when the application's main window is not a dialog
|
||||
SetIcon(m_hIcon, TRUE); // Set big icon
|
||||
SetIcon(m_hIcon, FALSE); // Set small icon
|
||||
|
||||
// TODO: Add extra initialization here
|
||||
// Initialize the CListControl Columns
|
||||
m_Plugin_List_Control.InsertColumn( 0, "Plugin File", LVCFMT_LEFT, 200, -1 );
|
||||
m_Plugin_List_Control.InsertColumn( 1, "PLID", LVCFMT_LEFT, 125, -1 );
|
||||
|
||||
m_Component_List_Control.InsertColumn( 0, "Component File", LVCFMT_LEFT, 200, -1 );
|
||||
m_Component_List_Control.InsertColumn( 1, "PLID", LVCFMT_LEFT, 125, -1 );
|
||||
|
||||
m_MIME_List_Control.InsertColumn( 0, "Mime Type", LVCFMT_LEFT, 150, -1 );
|
||||
m_MIME_List_Control.InsertColumn( 1, "Suffix", LVCFMT_LEFT, 100, -1 );
|
||||
m_MIME_List_Control.InsertColumn( 2, "Suffix Description", LVCFMT_LEFT, 150, -1 );
|
||||
m_MIME_List_Control.InsertColumn( 3, "Plugin File", LVCFMT_LEFT, 250, -1 );
|
||||
|
||||
// fill with starter information
|
||||
m_Company_Name_Value = COMPANY_DEFAULT_VALUE;
|
||||
m_Plugin_Description_Value = PLUGIN_DESC_DEFAULT_VALUE;
|
||||
m_Domain_Name_Value = DOMAIN_DEFAULT_VALUE;
|
||||
|
||||
UpdateData(false);
|
||||
|
||||
return TRUE; // return TRUE unless you set the focus to a control
|
||||
}
|
||||
|
||||
void CXPIPackagerDlg::OnSysCommand(UINT nID, LPARAM lParam)
|
||||
{
|
||||
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
|
||||
{
|
||||
CAboutDlg dlgAbout;
|
||||
dlgAbout.DoModal();
|
||||
}
|
||||
else
|
||||
{
|
||||
CDialog::OnSysCommand(nID, lParam);
|
||||
}
|
||||
}
|
||||
|
||||
// If you add a minimize button to your dialog, you will need the code below
|
||||
// to draw the icon. For MFC applications using the document/view model,
|
||||
// this is automatically done for you by the framework.
|
||||
|
||||
void CXPIPackagerDlg::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 CXPIPackagerDlg::OnQueryDragIcon()
|
||||
{
|
||||
return (HCURSOR) m_hIcon;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CXPIPackagerDlg::OnCreate()
|
||||
{
|
||||
// TODO: Add your control notification handler code here
|
||||
UpdateData(true);
|
||||
|
||||
if(!m_Archive_Name_Value.GetLength())
|
||||
{
|
||||
MessageBox("Need a valid name for the final XPI Installer file.", "Invalid File", MB_OK + MB_ICONEXCLAMATION);
|
||||
return;
|
||||
}
|
||||
|
||||
if(!m_PluginFileList.GetSize())
|
||||
{
|
||||
MessageBox("You must have at least one PLUGIN file in a XPI Archive.", "Plugin File Missing", MB_OK + MB_ICONEXCLAMATION);
|
||||
return;
|
||||
}
|
||||
|
||||
CString tempFileName = m_PluginFileList.ElementAt(0);
|
||||
CString tempArchiveName = m_Archive_Name_Value.Left(tempFileName.ReverseFind('.') + 1);
|
||||
|
||||
CString temp = tempFileName.Left(tempFileName.ReverseFind('\\') + 1);
|
||||
temp += m_Archive_Name_Value;
|
||||
|
||||
m_Archive_Name_Value = temp;
|
||||
|
||||
//create new archive *.xpi
|
||||
CZipArchive archive;
|
||||
archive.Open(m_Archive_Name_Value, CZipArchive::create);
|
||||
|
||||
//add plugin dlls
|
||||
int FileCount = m_PluginFileList.GetSize();
|
||||
for(int i = 0; i < FileCount; i++)
|
||||
{
|
||||
tempFileName = m_PluginFileList.GetAt(i);
|
||||
archive.AddNewFile(tempFileName, -1, false);
|
||||
}
|
||||
|
||||
//add components
|
||||
FileCount = m_ComponentFileList.GetSize();
|
||||
if( FileCount != 0 )
|
||||
{
|
||||
for( i = 0; i < FileCount; i++)
|
||||
{
|
||||
tempFileName = m_ComponentFileList.GetAt(i);
|
||||
archive.AddNewFile(tempFileName, -1, false);
|
||||
}
|
||||
}
|
||||
|
||||
//add install .js
|
||||
HRSRC info = ::FindResource(NULL,MAKEINTRESOURCE(IDR_HEADER), "JSCRIPT");
|
||||
HGLOBAL resource = ::LoadResource(NULL, info);
|
||||
DWORD fileSize = SizeofResource(NULL, info);
|
||||
BYTE *mempointer = (BYTE *) GlobalLock(resource);
|
||||
CString header;
|
||||
memcpy(header.GetBuffer(fileSize), mempointer, fileSize);
|
||||
header.ReleaseBuffer();
|
||||
int foo = header.GetLength();
|
||||
|
||||
info = ::FindResource(NULL,MAKEINTRESOURCE(IDR_BODY), "JSCRIPT");
|
||||
resource = ::LoadResource(NULL, info);
|
||||
fileSize = SizeofResource(NULL, info);
|
||||
mempointer = (BYTE *) GlobalLock(resource);
|
||||
CString body;
|
||||
memcpy(body.GetBuffer(fileSize), mempointer, fileSize);
|
||||
body.ReleaseBuffer();
|
||||
int foo2 = body.GetLength();
|
||||
|
||||
CString finalFile;
|
||||
GetGuts(header, body, finalFile);
|
||||
|
||||
if (finalFile.GetLength())
|
||||
{
|
||||
CZipFileHeader header;
|
||||
header.m_uMethod = Z_DEFLATED;
|
||||
header.SetFileName("install.js");
|
||||
header.SetComment("install.js: install script");
|
||||
archive.OpenNewFile(header, Z_DEFAULT_COMPRESSION, m_Archive_Name_Value);
|
||||
archive.WriteNewFile(finalFile.GetBuffer(0), finalFile.GetLength());
|
||||
archive.CloseNewFile();
|
||||
}
|
||||
//close archive
|
||||
archive.Close();
|
||||
GlobalUnlock(resource);
|
||||
|
||||
CString tMessage = "The following XPI Archive:\n\n";
|
||||
tMessage += m_Archive_Name_Value;
|
||||
tMessage += "\n\nwas created successfully!";
|
||||
MessageBox(tMessage, "XPI Archive Created!", MB_OK + MB_ICONEXCLAMATION);
|
||||
return;
|
||||
}
|
||||
|
||||
/* --- FILLER.JS ---
|
||||
var PLUGIN_FILE = [%s];
|
||||
var PLUGIN_FILE_PLID = [%s];
|
||||
var COMPONENT_FILE = [%s];
|
||||
var COMPONENT_FILE_PLID = [%s];
|
||||
// (DLL files)
|
||||
var PLUGIN_SIZE = %d;
|
||||
// (XPI files)
|
||||
var COMPONENT_SIZE = %d;
|
||||
var SOFTWARE_NAME = "%s";
|
||||
var PLID = "%s";
|
||||
var VERSION = "%s";
|
||||
var MIMETYPE = [%s];
|
||||
var SUFFIX = [%s];
|
||||
var SUFFIX_DESCRIPTION = [%s];
|
||||
var COMPANY_NAME = "%s";
|
||||
var PLUGIN_DESCRIPTION = "%s";
|
||||
*/
|
||||
|
||||
#define BUFFER_SIZE 5000
|
||||
|
||||
void
|
||||
CXPIPackagerDlg::GetGuts(const CString &header, const CString &body, CString &result)
|
||||
{
|
||||
CString filler;
|
||||
|
||||
HRSRC info = ::FindResource(NULL,MAKEINTRESOURCE(IDR_FILLER), "JSCRIPT");
|
||||
HGLOBAL resource = ::LoadResource(NULL, info);
|
||||
DWORD fileSize = SizeofResource(NULL, info);
|
||||
BYTE *mempointer = (BYTE *) GlobalLock(resource);
|
||||
memcpy(filler.GetBuffer(fileSize), mempointer, fileSize);
|
||||
filler.ReleaseBuffer();
|
||||
|
||||
|
||||
CFile t_File;
|
||||
CString t_FileName;
|
||||
CString t_FullFileName;
|
||||
|
||||
// build the plugin parameter
|
||||
CString t_PluginParameter;
|
||||
CString t_PluginPLIDParameter;
|
||||
int FileCount = m_PluginFileList.GetSize();
|
||||
for(int i = 0; i < FileCount; i++)
|
||||
{
|
||||
t_FullFileName = m_PluginFileList.GetAt(i);
|
||||
if(t_File.Open(t_FullFileName, CFile::modeRead))
|
||||
{
|
||||
t_FileName = t_File.GetFileName();
|
||||
}
|
||||
t_File.Close();
|
||||
t_PluginParameter += "\"" + t_FileName + "\"";
|
||||
t_PluginPLIDParameter += "\"" + m_PluginPLIDList.ElementAt(i) + "\"";
|
||||
if(i != (FileCount - 1))
|
||||
{
|
||||
t_PluginParameter += ", ";
|
||||
t_PluginPLIDParameter += ", ";
|
||||
}
|
||||
}
|
||||
|
||||
// build the component parameter
|
||||
CString t_ComponentParameter;
|
||||
CString t_ComponentPLIDParameter;
|
||||
FileCount = m_ComponentFileList.GetSize();
|
||||
for( i = 0; i < FileCount; i++)
|
||||
{
|
||||
t_FullFileName = m_ComponentFileList.GetAt(i);
|
||||
if(t_File.Open(t_FullFileName, CFile::modeRead))
|
||||
{
|
||||
t_FileName = t_File.GetFileName();
|
||||
}
|
||||
t_File.Close();
|
||||
t_ComponentParameter += "\"" + t_FileName + "\"";
|
||||
t_ComponentPLIDParameter += "\"" + m_ComponentPLIDList.ElementAt(i) + "\"";
|
||||
if(i != (FileCount - 1))
|
||||
{
|
||||
t_ComponentParameter += ", ";
|
||||
t_ComponentPLIDParameter += ", ";
|
||||
}
|
||||
}
|
||||
if(!t_ComponentParameter.GetLength())
|
||||
t_ComponentParameter = "\"\"";
|
||||
if(!t_ComponentPLIDParameter.GetLength())
|
||||
t_ComponentPLIDParameter = "\"\"";
|
||||
|
||||
// build the MIME parameters
|
||||
CString t_MIMETypeParameter;
|
||||
CString t_SuffixParameter;
|
||||
CString t_SuffixDescriptionParameter;
|
||||
FileCount = m_MIMETypeList.GetSize();
|
||||
for( i = 0; i < FileCount; i++)
|
||||
{
|
||||
t_MIMETypeParameter += "\"" + m_MIMETypeList.ElementAt(i) + "\"";
|
||||
t_SuffixParameter += "\"" + m_SuffixList.ElementAt(i) + "\"";
|
||||
t_SuffixDescriptionParameter += "\"" + m_SuffixDescriptionList.ElementAt(i) + "\"";
|
||||
if(i != (FileCount - 1))
|
||||
{
|
||||
t_MIMETypeParameter += ", ";;
|
||||
t_SuffixParameter += ", ";;
|
||||
t_SuffixDescriptionParameter += ", ";;
|
||||
}
|
||||
}
|
||||
if(!t_MIMETypeParameter.GetLength())
|
||||
t_MIMETypeParameter = "\"\"";
|
||||
if(!t_SuffixParameter.GetLength())
|
||||
t_SuffixParameter = "\"\"";
|
||||
if(!t_SuffixDescriptionParameter.GetLength())
|
||||
t_SuffixDescriptionParameter = "\"\"";
|
||||
|
||||
CString buffer;
|
||||
|
||||
sprintf(buffer.GetBuffer(filler.GetLength() + BUFFER_SIZE), filler, t_PluginParameter, t_PluginPLIDParameter,
|
||||
t_ComponentParameter, t_ComponentPLIDParameter, m_Plugin_Size_Value, m_Component_Size_Value,
|
||||
m_Product_Name_Value, m_PLID_Value, m_Plugin_Version_Value, t_MIMETypeParameter, t_SuffixParameter,
|
||||
t_SuffixDescriptionParameter, m_Company_Name_Value, m_Plugin_Description_Value);
|
||||
|
||||
buffer.ReleaseBuffer();
|
||||
result += header;
|
||||
result += buffer;
|
||||
result += body;
|
||||
}
|
||||
|
||||
void CXPIPackagerDlg::OnAutoPLID()
|
||||
{
|
||||
// TODO: Add your control notification handler code here
|
||||
UpdateData(true);
|
||||
CString temp;
|
||||
temp = "@";
|
||||
temp += m_Domain_Name_Value;
|
||||
temp += "/";
|
||||
temp += m_Product_Name_Value;
|
||||
temp += ",version=";
|
||||
temp += m_Plugin_Version_Value;
|
||||
|
||||
m_PLID_Value = temp;
|
||||
|
||||
UpdateData(false);
|
||||
}
|
||||
|
||||
void CXPIPackagerDlg::OnBigHelp()
|
||||
{
|
||||
// TODO: Add your control notification handler code here
|
||||
CString tempString = "http://devedge.netscape.com/viewsource/2002/xpinstall-guidelines/";
|
||||
ShellExecute(NULL,"open",tempString,"","",SW_SHOWDEFAULT);
|
||||
}
|
||||
|
||||
void CXPIPackagerDlg::OnPLIDHelp()
|
||||
{
|
||||
// TODO: Add your control notification handler code here
|
||||
CString tempString = "http://www.mozilla.org/projects/plugins/plugin-identifier.html";
|
||||
ShellExecute(NULL,"open",tempString,"","",SW_SHOWDEFAULT);
|
||||
}
|
||||
|
||||
|
||||
long CXPIPackagerDlg::CalculateTotalFileSize(const CStringArray* t_Array)
|
||||
{
|
||||
// TODO: Add your control notification handler code here
|
||||
CFile t_File;
|
||||
CString t_FileName;
|
||||
int t_NumFiles = t_Array->GetSize();
|
||||
|
||||
long t_Size = 0;
|
||||
|
||||
for(int i = 0; i < t_NumFiles; i++)
|
||||
{
|
||||
t_FileName = t_Array->GetAt(i);
|
||||
if(t_File.Open(t_FileName, CFile::modeRead))
|
||||
{
|
||||
CFileStatus t_FileStatus;
|
||||
if(t_File.GetStatus(t_FileStatus))
|
||||
t_Size += t_FileStatus.m_size;
|
||||
}
|
||||
t_File.Close();
|
||||
}
|
||||
return t_Size;
|
||||
}
|
||||
|
||||
void CXPIPackagerDlg::OnComponentBrowse()
|
||||
{
|
||||
// TODO: Add your control notification handler code here
|
||||
UpdateData(true);
|
||||
CString t_PLID;
|
||||
CString t_ComponentName;
|
||||
CString t_ComponentFileName;
|
||||
CFileChooserDlg dlg(CXPIPackagerApp::XPT_TYPE, m_PLID_Value, t_ComponentFileName, m_Domain_Name_Value, m_Product_Name_Value, m_Plugin_Version_Value, NULL);
|
||||
|
||||
if(IDOK == dlg.DoModal())
|
||||
{
|
||||
t_ComponentFileName = dlg.GetFileName();
|
||||
t_PLID = dlg.GetPLIDForFileName();
|
||||
|
||||
CFile t_File;
|
||||
if(t_File.Open(t_ComponentFileName, CFile::modeRead))
|
||||
{
|
||||
CFileStatus t_FileStatus;
|
||||
if(t_File.GetStatus(t_FileStatus))
|
||||
{
|
||||
t_ComponentName = t_File.GetFileName();
|
||||
|
||||
m_ComponentList.InsertAt(0, t_ComponentName);
|
||||
m_ComponentFileList.InsertAt(0, t_ComponentFileName);
|
||||
m_ComponentPLIDList.InsertAt(0, t_PLID);
|
||||
|
||||
m_Component_List_Control.InsertItem( 0, "", -1);
|
||||
m_Component_List_Control.SetItemText( 0, 0, t_ComponentFileName);
|
||||
m_Component_List_Control.SetItemText( 0, 1, t_PLID);
|
||||
|
||||
// re-adjust plugin total size
|
||||
t_File.Close();
|
||||
m_ComponentTotalSize = CalculateTotalFileSize(&m_ComponentFileList);
|
||||
m_Component_Size_Value = m_ComponentTotalSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
UpdateData(false);
|
||||
}
|
||||
|
||||
void CXPIPackagerDlg::OnComponentRemove()
|
||||
{
|
||||
// TODO: Add your control notification handler code here
|
||||
UpdateData(true);
|
||||
int t_CurrentSelection = m_Component_List_Control.GetSelectionMark( );
|
||||
if(t_CurrentSelection == -1)
|
||||
return;
|
||||
|
||||
m_Component_List_Control.DeleteItem(t_CurrentSelection);
|
||||
m_ComponentList.RemoveAt(t_CurrentSelection);
|
||||
m_ComponentFileList.RemoveAt(t_CurrentSelection);
|
||||
m_ComponentPLIDList.RemoveAt(t_CurrentSelection);
|
||||
// re-adjust size
|
||||
m_Component_Size_Value = CalculateTotalFileSize(&m_ComponentFileList);
|
||||
UpdateData(false);
|
||||
}
|
||||
|
||||
void CXPIPackagerDlg::OnPluginBrowse()
|
||||
{
|
||||
// TODO: Add your control notification handler code here
|
||||
UpdateData(true);
|
||||
|
||||
CString t_PLID;
|
||||
CString t_PluginName;
|
||||
CString t_PluginFileName;
|
||||
|
||||
CFileChooserDlg dlg(CXPIPackagerApp::DLL_TYPE, m_PLID_Value, t_PluginFileName, m_Domain_Name_Value, m_Product_Name_Value, m_Plugin_Version_Value, NULL);
|
||||
|
||||
if(IDOK == dlg.DoModal())
|
||||
{
|
||||
t_PluginFileName = dlg.GetFileName();
|
||||
t_PLID = dlg.GetPLIDForFileName();
|
||||
|
||||
CFile t_File;
|
||||
if(t_File.Open(t_PluginFileName, CFile::modeRead))
|
||||
{
|
||||
CFileStatus t_FileStatus;
|
||||
if(t_File.GetStatus(t_FileStatus))
|
||||
{
|
||||
t_PluginName = t_File.GetFileName();
|
||||
|
||||
m_PluginList.InsertAt(0, t_PluginName);
|
||||
m_PluginFileList.InsertAt(0, t_PluginFileName);
|
||||
m_PluginPLIDList.InsertAt(0, t_PLID);
|
||||
|
||||
m_Plugin_List_Control.InsertItem( 0, "", -1);
|
||||
m_Plugin_List_Control.SetItemText( 0, 0, t_PluginFileName);
|
||||
m_Plugin_List_Control.SetItemText( 0, 1, t_PLID);
|
||||
|
||||
// re-adjust plugin total size
|
||||
t_File.Close();
|
||||
m_PluginTotalSize = CalculateTotalFileSize(&m_PluginFileList);
|
||||
m_Plugin_Size_Value = m_PluginTotalSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
UpdateData(false);
|
||||
}
|
||||
|
||||
void CXPIPackagerDlg::OnPluginRemove()
|
||||
{
|
||||
// TODO: Add your control notification handler code here
|
||||
UpdateData(true);
|
||||
int t_CurrentSelection = m_Plugin_List_Control.GetSelectionMark( );
|
||||
if(t_CurrentSelection == -1)
|
||||
return;
|
||||
|
||||
m_Plugin_List_Control.DeleteItem(t_CurrentSelection);
|
||||
m_PluginList.RemoveAt(t_CurrentSelection);
|
||||
m_PluginFileList.RemoveAt(t_CurrentSelection);
|
||||
m_PluginPLIDList.RemoveAt(t_CurrentSelection);
|
||||
// re-adjust size
|
||||
m_Plugin_Size_Value = CalculateTotalFileSize(&m_PluginFileList);
|
||||
UpdateData(false);
|
||||
}
|
||||
|
||||
|
||||
void CXPIPackagerDlg::OnMIMETypeAdd()
|
||||
{
|
||||
// TODO: Add your control notification handler code here
|
||||
UpdateData(true);
|
||||
if(!m_PluginList.GetSize())
|
||||
{
|
||||
CString tMessage = "No Plugin File is present in the archive yet. A Plugin File is required to a MIME Type for the Plugin.";
|
||||
MessageBox(tMessage, "Error: No Plugin File!", MB_OK + MB_ICONEXCLAMATION);
|
||||
return;
|
||||
}
|
||||
CString temp;
|
||||
CMIMETypeChooseDlg dlg(temp, temp, temp, temp, &m_PluginList, NULL);
|
||||
|
||||
if(IDOK == dlg.DoModal())
|
||||
{
|
||||
m_MIMETypeList.InsertAt(0, dlg.GetMIMEType());
|
||||
m_SuffixList.InsertAt(0, dlg.GetSuffix());
|
||||
m_SuffixDescriptionList.InsertAt(0, dlg.GetSuffixDescription());
|
||||
m_MIMEPluginList.InsertAt(0, dlg.GetPlugin());
|
||||
|
||||
m_MIME_List_Control.InsertItem( 0, "", -1);
|
||||
m_MIME_List_Control.SetItemText( 0, 0, dlg.GetMIMEType());
|
||||
m_MIME_List_Control.SetItemText( 0, 1, dlg.GetSuffix());
|
||||
m_MIME_List_Control.SetItemText( 0, 2, dlg.GetSuffixDescription());
|
||||
m_MIME_List_Control.SetItemText( 0, 3, dlg.GetPlugin());
|
||||
}
|
||||
UpdateData(false);
|
||||
}
|
||||
|
||||
void CXPIPackagerDlg::OnMIMETypeRemove()
|
||||
{
|
||||
// TODO: Add your control notification handler code here
|
||||
UpdateData(true);
|
||||
int t_CurrentSelection = m_MIME_List_Control.GetSelectionMark( );
|
||||
if(t_CurrentSelection == -1)
|
||||
return;
|
||||
|
||||
m_MIME_List_Control.DeleteItem(t_CurrentSelection);
|
||||
|
||||
m_MIMETypeList.RemoveAt(t_CurrentSelection);
|
||||
m_SuffixList.RemoveAt(t_CurrentSelection);
|
||||
m_SuffixDescriptionList.RemoveAt(t_CurrentSelection);
|
||||
m_MIMEPluginList.RemoveAt(t_CurrentSelection);
|
||||
|
||||
UpdateData(false);
|
||||
}
|
||||
|
||||
void CXPIPackagerDlg::OnDblclkPluginList(NMHDR* pNMHDR, LRESULT* pResult)
|
||||
{
|
||||
// TODO: Add your control notification handler code here
|
||||
UpdateData(true);
|
||||
int t_CurrentSelection = m_Plugin_List_Control.GetSelectionMark( );
|
||||
if(t_CurrentSelection == -1)
|
||||
return;
|
||||
|
||||
CString t_PLID = m_PluginPLIDList.ElementAt(t_CurrentSelection);
|
||||
CString t_PluginName;
|
||||
CString t_PluginFileName = m_PluginFileList.ElementAt(t_CurrentSelection);
|
||||
|
||||
CFileChooserDlg dlg(CXPIPackagerApp::DLL_TYPE, t_PLID, t_PluginFileName, m_Domain_Name_Value, m_Product_Name_Value, m_Plugin_Version_Value, NULL);
|
||||
|
||||
if(IDOK == dlg.DoModal())
|
||||
{
|
||||
t_PluginFileName = dlg.GetFileName();
|
||||
t_PLID = dlg.GetPLIDForFileName();
|
||||
|
||||
CFile t_File;
|
||||
if(t_File.Open(t_PluginFileName, CFile::modeRead))
|
||||
{
|
||||
CFileStatus t_FileStatus;
|
||||
if(t_File.GetStatus(t_FileStatus))
|
||||
{
|
||||
t_PluginName = t_File.GetFileName();
|
||||
|
||||
m_PluginList.RemoveAt(t_CurrentSelection);
|
||||
m_PluginList.InsertAt(t_CurrentSelection, t_PluginName);
|
||||
m_PluginFileList.RemoveAt(t_CurrentSelection);
|
||||
m_PluginFileList.InsertAt(t_CurrentSelection, t_PluginFileName);
|
||||
m_PluginPLIDList.RemoveAt(t_CurrentSelection);
|
||||
m_PluginPLIDList.InsertAt(t_CurrentSelection, t_PLID);
|
||||
|
||||
//m_Plugin_List_Control.InsertItem( 0, "", -1);
|
||||
m_Plugin_List_Control.SetItemText( t_CurrentSelection, 0, t_PluginFileName);
|
||||
m_Plugin_List_Control.SetItemText( t_CurrentSelection, 1, t_PLID);
|
||||
|
||||
// re-adjust plugin total size
|
||||
t_File.Close();
|
||||
m_PluginTotalSize = CalculateTotalFileSize(&m_PluginFileList);
|
||||
m_Plugin_Size_Value = m_PluginTotalSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
UpdateData(false);
|
||||
|
||||
*pResult = 0;
|
||||
}
|
||||
|
||||
void CXPIPackagerDlg::OnDblclkComponentList(NMHDR* pNMHDR, LRESULT* pResult)
|
||||
{
|
||||
// TODO: Add your control notification handler code here
|
||||
UpdateData(true);
|
||||
int t_CurrentSelection = m_Component_List_Control.GetSelectionMark( );
|
||||
if(t_CurrentSelection == -1)
|
||||
return;
|
||||
|
||||
CString t_PLID = m_ComponentPLIDList.ElementAt(t_CurrentSelection);
|
||||
CString t_ComponentName;
|
||||
CString t_ComponentFileName = m_ComponentFileList.ElementAt(t_CurrentSelection);
|
||||
|
||||
CFileChooserDlg dlg(CXPIPackagerApp::XPT_TYPE, t_PLID, t_ComponentFileName, m_Domain_Name_Value, m_Product_Name_Value, m_Plugin_Version_Value, NULL);
|
||||
|
||||
if(IDOK == dlg.DoModal())
|
||||
{
|
||||
t_ComponentFileName = dlg.GetFileName();
|
||||
t_PLID = dlg.GetPLIDForFileName();
|
||||
|
||||
CFile t_File;
|
||||
if(t_File.Open(t_ComponentFileName, CFile::modeRead))
|
||||
{
|
||||
CFileStatus t_FileStatus;
|
||||
if(t_File.GetStatus(t_FileStatus))
|
||||
{
|
||||
t_ComponentName = t_File.GetFileName();
|
||||
|
||||
m_ComponentList.RemoveAt(t_CurrentSelection);
|
||||
m_ComponentList.InsertAt(t_CurrentSelection, t_ComponentName);
|
||||
m_ComponentFileList.RemoveAt(t_CurrentSelection);
|
||||
m_ComponentFileList.InsertAt(t_CurrentSelection, t_ComponentFileName);
|
||||
m_ComponentPLIDList.RemoveAt(t_CurrentSelection);
|
||||
m_ComponentPLIDList.InsertAt(t_CurrentSelection, t_PLID);
|
||||
|
||||
//m_Plugin_List_Control.InsertItem( 0, "", -1);
|
||||
m_Component_List_Control.SetItemText( t_CurrentSelection, 0, t_ComponentFileName);
|
||||
m_Component_List_Control.SetItemText( t_CurrentSelection, 1, t_PLID);
|
||||
|
||||
// re-adjust plugin total size
|
||||
t_File.Close();
|
||||
m_ComponentTotalSize = CalculateTotalFileSize(&m_ComponentFileList);
|
||||
m_Component_Size_Value = m_ComponentTotalSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
UpdateData(false);
|
||||
|
||||
*pResult = 0;
|
||||
}
|
||||
|
||||
void CXPIPackagerDlg::OnDblclkMimeList(NMHDR* pNMHDR, LRESULT* pResult)
|
||||
{
|
||||
// TODO: Add your control notification handler code here
|
||||
UpdateData(true);
|
||||
int t_CurrentSelection = m_MIME_List_Control.GetSelectionMark( );
|
||||
if(t_CurrentSelection == -1)
|
||||
return;
|
||||
|
||||
if(!m_PluginList.GetSize())
|
||||
{
|
||||
CString tMessage = "No Plugin File is present in the archive yet. A Plugin File is required to a MIME Type for the Plugin.";
|
||||
MessageBox(tMessage, "Error: No Plugin File!", MB_OK + MB_ICONEXCLAMATION);
|
||||
return;
|
||||
}
|
||||
|
||||
CString t_MIMEType = m_MIMETypeList.ElementAt(t_CurrentSelection);
|
||||
CString t_Suffix = m_SuffixList.ElementAt(t_CurrentSelection);
|
||||
CString t_SuffixDescription = m_SuffixDescriptionList.ElementAt(t_CurrentSelection);
|
||||
CString t_Plugin = m_MIMEPluginList.ElementAt(t_CurrentSelection);
|
||||
|
||||
CMIMETypeChooseDlg dlg(t_MIMEType, t_Suffix, t_SuffixDescription, t_Plugin, &m_PluginList, NULL);
|
||||
|
||||
if(IDOK == dlg.DoModal())
|
||||
{
|
||||
m_MIMETypeList.RemoveAt(t_CurrentSelection);
|
||||
m_SuffixList.RemoveAt(t_CurrentSelection);
|
||||
m_SuffixDescriptionList.RemoveAt(t_CurrentSelection);
|
||||
m_MIMEPluginList.RemoveAt(t_CurrentSelection);
|
||||
|
||||
m_MIMETypeList.InsertAt(t_CurrentSelection, dlg.GetMIMEType());
|
||||
m_SuffixList.InsertAt(t_CurrentSelection, dlg.GetSuffix());
|
||||
m_SuffixDescriptionList.InsertAt(t_CurrentSelection, dlg.GetSuffixDescription());
|
||||
m_MIMEPluginList.InsertAt(t_CurrentSelection, dlg.GetPlugin());
|
||||
|
||||
//m_MIME_List_Control.InsertItem( t_CurrentSelection, "", -1);
|
||||
m_MIME_List_Control.SetItemText( t_CurrentSelection, 0, dlg.GetMIMEType());
|
||||
m_MIME_List_Control.SetItemText( t_CurrentSelection, 1, dlg.GetSuffix());
|
||||
m_MIME_List_Control.SetItemText( t_CurrentSelection, 2, dlg.GetSuffixDescription());
|
||||
m_MIME_List_Control.SetItemText( t_CurrentSelection, 3, dlg.GetPlugin());
|
||||
}
|
||||
UpdateData(false);
|
||||
|
||||
*pResult = 0;
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
// XPIPackagerDlg.h : header file
|
||||
//
|
||||
|
||||
#if !defined(AFX_XPIPACKAGERDLG_H__E235AD70_02F3_47CB_85DD_2F9F9E023FCE__INCLUDED_)
|
||||
#define AFX_XPIPACKAGERDLG_H__E235AD70_02F3_47CB_85DD_2F9F9E023FCE__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CXPIPackagerDlg dialog
|
||||
|
||||
class CXPIPackagerDlg : public CDialog
|
||||
{
|
||||
// Construction
|
||||
public:
|
||||
CXPIPackagerDlg(CWnd* pParent = NULL); // standard constructor
|
||||
|
||||
// Dialog Data
|
||||
//{{AFX_DATA(CXPIPackagerDlg)
|
||||
enum { IDD = IDD_XPIPACKAGER_DIALOG };
|
||||
CListCtrl m_MIME_List_Control;
|
||||
CListCtrl m_Component_List_Control;
|
||||
CListCtrl m_Plugin_List_Control;
|
||||
CString m_Domain_Name_Value;
|
||||
CString m_PLID_Value;
|
||||
CString m_Plugin_Version_Value;
|
||||
CString m_Product_Name_Value;
|
||||
CString m_Archive_Name_Value;
|
||||
long m_Component_Size_Value;
|
||||
CString m_Company_Name_Value;
|
||||
long m_Plugin_Size_Value;
|
||||
CString m_Plugin_Description_Value;
|
||||
//}}AFX_DATA
|
||||
|
||||
// ClassWizard generated virtual function overrides
|
||||
//{{AFX_VIRTUAL(CXPIPackagerDlg)
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||
//}}AFX_VIRTUAL
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
HICON m_hIcon;
|
||||
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(CXPIPackagerDlg)
|
||||
virtual BOOL OnInitDialog();
|
||||
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
|
||||
afx_msg void OnPaint();
|
||||
afx_msg HCURSOR OnQueryDragIcon();
|
||||
afx_msg void OnCreate();
|
||||
afx_msg void OnAutoPLID();
|
||||
afx_msg void OnBigHelp();
|
||||
afx_msg void OnPLIDHelp();
|
||||
afx_msg void OnComponentBrowse();
|
||||
afx_msg void OnComponentRemove();
|
||||
afx_msg void OnPluginBrowse();
|
||||
afx_msg void OnPluginRemove();
|
||||
afx_msg void OnMIMETypeAdd();
|
||||
afx_msg void OnMIMETypeRemove();
|
||||
afx_msg void OnDblclkPluginList(NMHDR* pNMHDR, LRESULT* pResult);
|
||||
afx_msg void OnDblclkComponentList(NMHDR* pNMHDR, LRESULT* pResult);
|
||||
afx_msg void OnDblclkMimeList(NMHDR* pNMHDR, LRESULT* pResult);
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
|
||||
private:
|
||||
void GetGuts(const CString &header, const CString &body, CString &result);
|
||||
long CalculateTotalFileSize(const CStringArray* t_Array);
|
||||
|
||||
CStringArray m_PluginList;
|
||||
CStringArray m_PluginFileList;
|
||||
CStringArray m_PluginPLIDList;
|
||||
|
||||
CStringArray m_ComponentList;
|
||||
CStringArray m_ComponentFileList;
|
||||
CStringArray m_ComponentPLIDList;
|
||||
|
||||
CStringArray m_MIMETypeList;
|
||||
CStringArray m_SuffixList;
|
||||
CStringArray m_SuffixDescriptionList;
|
||||
CStringArray m_MIMEPluginList;
|
||||
|
||||
long m_PluginTotalSize;
|
||||
long m_ComponentTotalSize;
|
||||
|
||||
CString m_Archive_Name;
|
||||
};
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_XPIPACKAGERDLG_H__E235AD70_02F3_47CB_85DD_2F9F9E023FCE__INCLUDED_)
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -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:
|
||||
// tdracz@artpol.com.pl
|
||||
//
|
||||
// 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_)
|
Двоичный файл не отображается.
Двоичный файл не отображается.
|
@ -0,0 +1,104 @@
|
|||
// ZipAutoBuffer.cpp: implementation of the CZipAutoBuffer class.
|
||||
// Part of the ZipArchive library
|
||||
//
|
||||
// Copyright (C) 2000 - 2001 Tadeusz Dracz.
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// For the licensing details see the file License.txt
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "ZipAutoBuffer.h"
|
||||
#include <memory.h>
|
||||
|
||||
// #ifdef _DEBUG
|
||||
// #undef THIS_FILE
|
||||
// static char THIS_FILE[]=__FILE__;
|
||||
// #define new DEBUG_NEW
|
||||
// #endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Construction/Destruction
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
CZipAutoBuffer::CZipAutoBuffer()
|
||||
{
|
||||
m_iSize = 0;
|
||||
m_pBuffer = NULL;
|
||||
}
|
||||
|
||||
CZipAutoBuffer::CZipAutoBuffer(DWORD iSize, bool bZeroMemory)
|
||||
{
|
||||
m_iSize = 0;
|
||||
m_pBuffer = NULL;
|
||||
Allocate(iSize, bZeroMemory);
|
||||
}
|
||||
|
||||
CZipAutoBuffer::~CZipAutoBuffer()
|
||||
{
|
||||
Release();
|
||||
}
|
||||
|
||||
|
||||
void CZipAutoBuffer::Release()
|
||||
{
|
||||
if (m_pBuffer)
|
||||
{
|
||||
delete [] m_pBuffer;
|
||||
m_iSize = 0;
|
||||
m_pBuffer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
char* CZipAutoBuffer::Allocate(DWORD iSize, bool bZeroMemory)
|
||||
{
|
||||
if (iSize != m_iSize)
|
||||
Release();
|
||||
else
|
||||
{
|
||||
if (bZeroMemory)
|
||||
memset(m_pBuffer, 0, iSize); // zerowanie bufora
|
||||
return m_pBuffer;
|
||||
}
|
||||
|
||||
if (iSize > 0)
|
||||
{
|
||||
m_pBuffer = new char [iSize];
|
||||
if (bZeroMemory)
|
||||
memset(m_pBuffer, 0, iSize); // zerowanie bufora
|
||||
m_iSize = iSize;
|
||||
}
|
||||
else
|
||||
m_pBuffer = NULL;
|
||||
|
||||
return m_pBuffer;
|
||||
}
|
||||
|
||||
|
||||
CZipAutoBuffer::CZipAutoBuffer(const CZipAutoBuffer& buffer)
|
||||
{
|
||||
m_pBuffer = NULL;
|
||||
m_iSize = 0;
|
||||
|
||||
if (buffer.m_pBuffer)
|
||||
{
|
||||
Allocate(buffer.m_iSize);
|
||||
memcpy(m_pBuffer, buffer.m_pBuffer, buffer.m_iSize);
|
||||
}
|
||||
}
|
||||
CZipAutoBuffer& CZipAutoBuffer::operator=(const CZipAutoBuffer& buffer)
|
||||
{
|
||||
if (this == &buffer)
|
||||
return *this;
|
||||
Release();
|
||||
if (buffer.m_pBuffer)
|
||||
{
|
||||
Allocate(buffer.m_iSize);
|
||||
memcpy(m_pBuffer, buffer.m_pBuffer, buffer.m_iSize);
|
||||
}
|
||||
return *this;
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
/**
|
||||
* \file ZipAutoBuffer.h
|
||||
* Interface for the CZipAutoBuffer class.
|
||||
*
|
||||
* \author Tadeusz Dracz
|
||||
*/
|
||||
// Part of the ZipArchive library
|
||||
//
|
||||
// Copyright (C) 2000 - 2001 Tadeusz Dracz.
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// For the licensing details see the file License.txt
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#if !defined(AFX_ZIPAUTOBUFFER_H__DEC28C20_83FE_11D3_B7C3_EDEC47A8A86C__INCLUDED_)
|
||||
#define AFX_ZIPAUTOBUFFER_H__DEC28C20_83FE_11D3_B7C3_EDEC47A8A86C__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
|
||||
/**
|
||||
A smart buffer freeing its contents on destruction.
|
||||
*/
|
||||
class CZipAutoBuffer
|
||||
{
|
||||
public:
|
||||
operator char*()
|
||||
{
|
||||
return m_pBuffer;
|
||||
}
|
||||
|
||||
// may produce ambiguity on some compilers
|
||||
// operator const char*() const
|
||||
// {
|
||||
// return m_pBuffer;
|
||||
// }
|
||||
const char* GetBuffer() const {return m_pBuffer;}
|
||||
char* Allocate(DWORD iSize, bool bZeroMemory = false);
|
||||
void Release();
|
||||
DWORD GetSize() const
|
||||
{
|
||||
return m_iSize;
|
||||
}
|
||||
bool IsAllocated() const
|
||||
{
|
||||
return (m_pBuffer != NULL);
|
||||
}
|
||||
CZipAutoBuffer(DWORD iSize, bool bZeroMemory = false);
|
||||
CZipAutoBuffer();
|
||||
CZipAutoBuffer(const CZipAutoBuffer& buffer);
|
||||
virtual ~CZipAutoBuffer();
|
||||
CZipAutoBuffer& operator=(const CZipAutoBuffer& buffer);
|
||||
protected:
|
||||
char* m_pBuffer;
|
||||
DWORD m_iSize;
|
||||
};
|
||||
|
||||
#endif // !defined(AFX_ZIPAUTOBUFFER_H__DEC28C20_83FE_11D3_B7C3_EDEC47A8A86C__INCLUDED_)
|
|
@ -0,0 +1,41 @@
|
|||
// ZipBigFile.cpp: implementation of the CZipBigFile class.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "ZipBigFile.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Construction/Destruction
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
IMPLEMENT_DYNAMIC(CZipBigFile, CFile)
|
||||
|
||||
CZipBigFile::CZipBigFile()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CZipBigFile::~CZipBigFile()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
_int64 CZipBigFile::Seek(_int64 dOff, UINT nFrom)
|
||||
{
|
||||
ASSERT_VALID(this);
|
||||
ASSERT(m_hFile != (UINT)hFileNull);
|
||||
ASSERT(nFrom == begin || nFrom == end || nFrom == current);
|
||||
ASSERT(begin == FILE_BEGIN && end == FILE_END && current == FILE_CURRENT);
|
||||
LARGE_INTEGER li;
|
||||
li.QuadPart = dOff;
|
||||
|
||||
li.LowPart = ::SetFilePointer((HANDLE)m_hFile, li.LowPart, &li.HighPart, (DWORD)nFrom);
|
||||
DWORD dw = GetLastError();
|
||||
if ((li.LowPart == (DWORD)-1) && (dw != NO_ERROR))
|
||||
{
|
||||
CFileException::ThrowOsError((LONG)dw);
|
||||
}
|
||||
|
||||
return li.QuadPart;
|
||||
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
// ZipBigFile.h: interface for the CZipBigFile class.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if !defined(AFX_ZipBigFile_H__79E0E6BD_25D6_4B82_85C5_AB397D9EC368__INCLUDED_)
|
||||
#define AFX_ZipBigFile_H__79E0E6BD_25D6_4B82_85C5_AB397D9EC368__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
|
||||
class CZipBigFile : public CFile
|
||||
{
|
||||
DECLARE_DYNAMIC(CZipBigFile)
|
||||
public:
|
||||
_int64 Seek(_int64 dOff, UINT nFrom);
|
||||
CZipBigFile();
|
||||
virtual ~CZipBigFile();
|
||||
|
||||
};
|
||||
|
||||
#endif // !defined(AFX_ZipBigFile_H__79E0E6BD_25D6_4B82_85C5_AB397D9EC368__INCLUDED_)
|
|
@ -0,0 +1,677 @@
|
|||
// ZipCentralDir.cpp: implementation of the CZipCentralDir class.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2000 Tadeusz Dracz.
|
||||
// For conditions of distribution and use, see copyright notice in ZipArchive.h
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "ZipCentralDir.h"
|
||||
#include "ZipArchive.h"
|
||||
|
||||
struct CZipAutoHandle
|
||||
{
|
||||
HANDLE m_hFileMap;
|
||||
LPVOID m_pFileMap;
|
||||
CZipAutoHandle()
|
||||
{
|
||||
m_hFileMap = NULL;
|
||||
m_pFileMap = NULL;
|
||||
}
|
||||
bool CreateMapping(HANDLE hFile)
|
||||
{
|
||||
m_hFileMap = CreateFileMapping(hFile, NULL, PAGE_READWRITE,
|
||||
0, 0, _T("ZipArchive Mapping File"));
|
||||
if (!m_hFileMap)
|
||||
return false;
|
||||
// Get pointer to memory representing file
|
||||
m_pFileMap = MapViewOfFile(m_hFileMap, FILE_MAP_WRITE, 0, 0, 0);
|
||||
return (m_pFileMap != NULL);
|
||||
}
|
||||
void RemoveMapping()
|
||||
{
|
||||
if (m_pFileMap)
|
||||
{
|
||||
UnmapViewOfFile(m_pFileMap);
|
||||
m_pFileMap = NULL;
|
||||
}
|
||||
if (m_hFileMap)
|
||||
{
|
||||
CloseHandle(m_hFileMap);
|
||||
m_hFileMap = NULL;
|
||||
}
|
||||
|
||||
}
|
||||
~CZipAutoHandle()
|
||||
{
|
||||
RemoveMapping();
|
||||
}
|
||||
};
|
||||
|
||||
#define ZIPCENTRALDIRSIZE 22
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Construction/Destruction
|
||||
char CZipCentralDir::m_gszSignature[] = {0x50, 0x4b, 0x05, 0x06};
|
||||
CZipCentralDir::CZipCentralDir()
|
||||
{
|
||||
m_bConvertAfterOpen = true;
|
||||
m_bFindFastEnabled = false;
|
||||
m_pStorage = NULL;
|
||||
m_pOpenedFile = NULL;
|
||||
m_iBufferSize = 32768;
|
||||
|
||||
}
|
||||
|
||||
void CZipCentralDir::Init()
|
||||
{
|
||||
m_bOnDisk = false;
|
||||
m_uBytesBeforeZip = m_uCentrDirPos = 0;
|
||||
m_pOpenedFile = NULL;
|
||||
m_pszComment.Release();
|
||||
}
|
||||
|
||||
CZipCentralDir::~CZipCentralDir()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
void CZipCentralDir::Read()
|
||||
{
|
||||
ASSERT(m_pStorage);
|
||||
WORD uCommentSize;
|
||||
m_uCentrDirPos = Locate();
|
||||
m_pStorage->m_pFile->Seek(m_uCentrDirPos, CFile::begin);
|
||||
CZipAutoBuffer buf(ZIPCENTRALDIRSIZE);
|
||||
DWORD uRead = m_pStorage->m_pFile->Read(buf, ZIPCENTRALDIRSIZE );
|
||||
if (uRead != ZIPCENTRALDIRSIZE)
|
||||
ThrowError(ZIP_BADZIPFILE);
|
||||
memcpy(&m_szSignature, buf, 4);
|
||||
memcpy(&m_uThisDisk, buf + 4, 2);
|
||||
memcpy(&m_uDiskWithCD, buf + 6, 2);
|
||||
memcpy(&m_uDiskEntriesNo, buf + 8, 2);
|
||||
memcpy(&m_uEntriesNumber, buf + 10, 2);
|
||||
memcpy(&m_uSize, buf + 12, 4);
|
||||
memcpy(&m_uOffset, buf + 16, 4);
|
||||
memcpy(&uCommentSize, buf + 20, 2);
|
||||
buf.Release();
|
||||
|
||||
|
||||
m_pStorage->UpdateSpanMode(m_uThisDisk);
|
||||
// if m_uThisDisk is not zero, it is enough to say that it is multi archive
|
||||
ASSERT((!m_uThisDisk && (m_uEntriesNumber == m_uDiskEntriesNo) && !m_uDiskWithCD) || m_uThisDisk);
|
||||
|
||||
|
||||
|
||||
if (!m_pStorage->IsSpanMode() && ((DWORD)m_uCentrDirPos < m_uOffset + m_uSize))
|
||||
ThrowError(ZIP_BADZIPFILE);
|
||||
|
||||
if (uCommentSize)
|
||||
{
|
||||
m_pszComment.Allocate(uCommentSize);
|
||||
uRead = m_pStorage->m_pFile->Read(m_pszComment, uCommentSize);
|
||||
if (uRead != uCommentSize)
|
||||
ThrowError(ZIP_BADZIPFILE);
|
||||
}
|
||||
|
||||
m_uBytesBeforeZip = m_pStorage->IsSpanMode() ? 0 : m_uCentrDirPos - m_uSize - m_uOffset;
|
||||
|
||||
if ((!m_uSize && m_uEntriesNumber) || (!m_uEntriesNumber && m_uSize))
|
||||
ThrowError(ZIP_BADZIPFILE);
|
||||
|
||||
m_bOnDisk = true;
|
||||
m_pStorage->ChangeDisk(m_uDiskWithCD);
|
||||
|
||||
if (!m_uSize)
|
||||
return;
|
||||
|
||||
ReadHeaders();
|
||||
}
|
||||
|
||||
// return the location of the beginning of the "end" record in the file
|
||||
DWORD CZipCentralDir::Locate()
|
||||
{
|
||||
|
||||
// maximum size of end of central dir record
|
||||
long uMaxRecordSize = 0xffff + ZIPCENTRALDIRSIZE;
|
||||
DWORD uFileSize = m_pStorage->m_pFile->GetLength();
|
||||
|
||||
if ((DWORD)uMaxRecordSize > uFileSize)
|
||||
uMaxRecordSize = uFileSize;
|
||||
|
||||
CZipAutoBuffer buf(m_iBufferSize);
|
||||
|
||||
long uPosInFile = 0;
|
||||
int uRead = 0;
|
||||
// backward reading
|
||||
while (uPosInFile < uMaxRecordSize)
|
||||
{
|
||||
uPosInFile = uRead + m_iBufferSize;
|
||||
if (uPosInFile > uMaxRecordSize)
|
||||
uPosInFile = uMaxRecordSize;
|
||||
|
||||
int iToRead = uPosInFile - uRead;
|
||||
|
||||
m_pStorage->m_pFile->Seek(-uPosInFile, CFile::end);
|
||||
int iActuallyRead = m_pStorage->m_pFile->Read(buf, iToRead);
|
||||
if (iActuallyRead != iToRead)
|
||||
ThrowError(ZIP_BADZIPFILE);
|
||||
// search from the very last bytes to prevent an error if inside archive
|
||||
// there are packed other arhives
|
||||
for (int i = iToRead - 4; i >=0 ; i--)
|
||||
if (!memcmp((char*)buf + i, m_gszSignature, 4))
|
||||
return uFileSize - (uPosInFile - i);
|
||||
|
||||
uRead += iToRead - 3;
|
||||
|
||||
}
|
||||
|
||||
ThrowError(ZIP_CDIR_NOTFOUND);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CZipCentralDir::ThrowError(int err)
|
||||
{
|
||||
AfxThrowZipException(err, m_pStorage->m_pFile->GetFilePath());
|
||||
}
|
||||
|
||||
|
||||
void CZipCentralDir::ReadHeaders()
|
||||
{
|
||||
m_pStorage->m_pFile->Seek(m_uOffset + m_uBytesBeforeZip, CFile::begin);
|
||||
RemoveHeaders();
|
||||
for (int i = 0; i < m_uEntriesNumber; i++)
|
||||
{
|
||||
CZipFileHeader* pHeader = new CZipFileHeader;
|
||||
m_headers.Add(pHeader); // bezpoœrednio nastêpuje w razie wyj¹tku
|
||||
|
||||
if (!pHeader->Read(m_pStorage))
|
||||
ThrowError(ZIP_BADZIPFILE);
|
||||
ConvertFileName(true, true, pHeader);
|
||||
}
|
||||
if (m_bFindFastEnabled)
|
||||
BuildFindFastArray();
|
||||
|
||||
}
|
||||
|
||||
// remove all headers from the central dir
|
||||
void CZipCentralDir::Clear(bool bEverything)
|
||||
{
|
||||
m_pOpenedFile = NULL;
|
||||
m_pLocalExtraField.Release();
|
||||
|
||||
if (bEverything)
|
||||
{
|
||||
RemoveHeaders();
|
||||
m_findarray.RemoveAll();
|
||||
m_pszComment.Release();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool CZipCentralDir::IsValidIndex(WORD uIndex)
|
||||
{
|
||||
|
||||
bool ret = uIndex < m_headers.GetSize();
|
||||
#ifdef _DEBUG
|
||||
if (!ret)
|
||||
TRACE(_T("Not a valid index.\n"));
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
// open the file for extracting
|
||||
void CZipCentralDir::OpenFile(WORD uIndex)
|
||||
{
|
||||
WORD uLocalExtraFieldSize;
|
||||
m_pOpenedFile = m_headers[uIndex];
|
||||
m_pStorage->ChangeDisk(m_pOpenedFile->m_uDiskStart);
|
||||
m_pStorage->m_pFile->Seek(m_pOpenedFile->m_uOffset + m_uBytesBeforeZip, CFile::begin);
|
||||
if (!m_pOpenedFile->ReadLocal(m_pStorage, uLocalExtraFieldSize))
|
||||
ThrowError(ZIP_BADZIPFILE);
|
||||
|
||||
|
||||
m_pLocalExtraField.Release(); // just in case
|
||||
if (uLocalExtraFieldSize)
|
||||
{
|
||||
int iCurrDsk = m_pStorage->GetCurrentDisk();
|
||||
m_pLocalExtraField.Allocate(uLocalExtraFieldSize);
|
||||
m_pStorage->Read(m_pLocalExtraField, uLocalExtraFieldSize, true);
|
||||
if (m_pStorage->GetCurrentDisk() != iCurrDsk)
|
||||
ThrowError(ZIP_BADZIPFILE);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void CZipCentralDir::CloseFile()
|
||||
{
|
||||
if (!m_pOpenedFile)
|
||||
return;
|
||||
m_pLocalExtraField.Release();
|
||||
if (m_pOpenedFile->IsDataDescr())
|
||||
{
|
||||
CZipAutoBuffer buf(12);
|
||||
m_pStorage->Read(buf, 4, false);
|
||||
// in span mode, files that are divided between disks have bit 3 of flag set
|
||||
// which tell about the presence of the data descriptor after the compressed data
|
||||
// This signature may be in the disk spanning archive that is one volume only
|
||||
// (it is detected as a non disk spanning archive)
|
||||
if (memcmp(buf, CZipStorage::m_gszExtHeaderSignat, 4) != 0) // there is no signature
|
||||
m_pStorage->m_pFile->Seek(-4, CFile::current);
|
||||
|
||||
|
||||
m_pStorage->Read(buf, 12, false);
|
||||
if (!m_pOpenedFile->CheckCrcAndSizes(buf))
|
||||
ThrowError(ZIP_BADZIPFILE);
|
||||
}
|
||||
m_pOpenedFile = NULL;
|
||||
}
|
||||
|
||||
// add new header using the argument as a template
|
||||
void CZipCentralDir::AddNewFile(CZipFileHeader & header)
|
||||
{
|
||||
CZipFileHeader* pHeader = new CZipFileHeader(header);
|
||||
m_pOpenedFile = pHeader;
|
||||
m_headers.Add(pHeader);
|
||||
if (m_bFindFastEnabled)
|
||||
InsertFindFastElement(pHeader, WORD(m_headers.GetSize() - 1)); // GetSize IS > 0, 'cos we've just added a header
|
||||
RemoveFromDisk();
|
||||
m_pStorage->m_pFile->SeekToEnd();
|
||||
}
|
||||
|
||||
// called during adding or deleting files; remove the central dir from the disk
|
||||
void CZipCentralDir::RemoveFromDisk()
|
||||
{
|
||||
if (m_bOnDisk)
|
||||
{
|
||||
ASSERT(!m_pStorage->IsSpanMode()); // you can't add files to the existing disk span archive or to delete them from it
|
||||
m_pStorage->m_pFile->SetLength(m_uBytesBeforeZip + m_uOffset);
|
||||
m_bOnDisk = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CZipCentralDir::CloseNewFile()
|
||||
{
|
||||
CZipAutoBuffer buf(12 + 4);
|
||||
short iToWrite = 0;
|
||||
bool bIsSpan = m_pStorage->IsSpanMode() != 0;
|
||||
bool bEncrypted = m_pOpenedFile->IsEncrypted();
|
||||
if (m_pOpenedFile->IsDataDescr())
|
||||
{
|
||||
if (bIsSpan || bEncrypted)
|
||||
{
|
||||
memcpy(buf, m_pStorage->m_gszExtHeaderSignat, 4);
|
||||
iToWrite += 4;
|
||||
}
|
||||
}
|
||||
else /*if (!IsSpan)*/
|
||||
{
|
||||
ASSERT(!bIsSpan && !bEncrypted);
|
||||
m_pStorage->Flush();
|
||||
m_pStorage->m_pFile->Seek(m_pOpenedFile->m_uOffset + 14, CFile::begin);
|
||||
// we don't have to restore the pointer, because before adding a new file,
|
||||
// the pointer is moved to the end
|
||||
}
|
||||
|
||||
m_pOpenedFile->GetCrcAndSizes(buf + iToWrite);
|
||||
iToWrite += 12;
|
||||
|
||||
// offset set during writting the local header
|
||||
m_pOpenedFile->m_uOffset -= m_uBytesBeforeZip;
|
||||
|
||||
// write the data descriptor and a disk spanning signature at once
|
||||
m_pStorage->Write(buf, iToWrite, true);
|
||||
if (!bIsSpan && bEncrypted)
|
||||
{
|
||||
// write the information to the local header too
|
||||
m_pStorage->Flush();
|
||||
m_pStorage->m_pFile->Seek(m_pOpenedFile->m_uOffset + 14, CFile::begin);
|
||||
m_pStorage->Write(buf + 4, 12, true);
|
||||
}
|
||||
|
||||
if (!bIsSpan)
|
||||
m_pStorage->Flush();
|
||||
|
||||
m_pOpenedFile = NULL;
|
||||
|
||||
}
|
||||
|
||||
void CZipCentralDir::Write()
|
||||
{
|
||||
if (m_bOnDisk)
|
||||
return;
|
||||
if (!m_pStorage->IsSpanMode())
|
||||
{
|
||||
m_pStorage->Flush();
|
||||
m_pStorage->m_pFile->SeekToEnd();
|
||||
}
|
||||
m_uEntriesNumber = (WORD)m_headers.GetSize();
|
||||
m_uSize = 0;
|
||||
bool bDontAllowDiskChange = false;
|
||||
// if there is a disk spanning archive in creation and it is only one-volume,
|
||||
// (current disk is 0 so far, no bytes has been written so we know they are
|
||||
// all in the buffer) make sure that it will be after writting central dir
|
||||
// and make it a non disk spanning archive
|
||||
if (m_pStorage->IsSpanMode() && m_pStorage->GetCurrentDisk() == 0)
|
||||
{
|
||||
DWORD uVolumeFree = m_pStorage->VolumeLeft();
|
||||
// calculate the size of data descriptors already in the buffer or on the disk
|
||||
// (they will be removed in the non disk spanning archive):
|
||||
// multi span signature at the beginnig (4 bytes) + the size of the data
|
||||
// descr. for each file (multi span signature + 12 bytes data)
|
||||
// the count of bytes to add: central dir size - total to remove;
|
||||
DWORD uToGrow = GetSize(true) - (4 + m_uEntriesNumber * (4 + 12));
|
||||
if (uVolumeFree >= uToGrow)
|
||||
// lets make sure it will be one-disk archive
|
||||
{
|
||||
// can the operation be done only in the buffer?
|
||||
if (!m_pStorage->m_iBytesWritten && // no bytes on the disk yet
|
||||
(m_pStorage->GetFreeInBuffer() >= uToGrow)) // is the buffer big enough?
|
||||
{
|
||||
RemoveDataDescr(true);
|
||||
bDontAllowDiskChange = true; // if the disk change occurs somehow, we'll throw an error later
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pStorage->Flush();
|
||||
m_pStorage->m_pFile->Flush();
|
||||
if (RemoveDataDescr(false))
|
||||
bDontAllowDiskChange = true; // if the disk change occurs somehow, we'll throw an error later
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
WriteHeaders();
|
||||
m_uThisDisk = (WORD)m_pStorage->GetCurrentDisk();
|
||||
DWORD uSize = WriteCentralEnd();
|
||||
if (bDontAllowDiskChange && (m_pStorage->GetCurrentDisk() != 0))
|
||||
ThrowError(ZIP_BADZIPFILE);
|
||||
// if after adding a central directory there is a disk change,
|
||||
// update the information and write it again
|
||||
if (m_uThisDisk != m_pStorage->GetCurrentDisk())
|
||||
{
|
||||
m_uThisDisk = (WORD)m_pStorage->GetCurrentDisk();
|
||||
if (m_uEntriesNumber)
|
||||
{
|
||||
m_uDiskEntriesNo = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_uDiskWithCD = m_uThisDisk;
|
||||
m_uOffset = 0;
|
||||
}
|
||||
|
||||
if (m_pStorage->m_uBytesInWriteBuffer >= uSize)
|
||||
// if the data is still in the buffer, simply remove it
|
||||
m_pStorage->m_uBytesInWriteBuffer -= uSize;
|
||||
else
|
||||
{
|
||||
m_pStorage->Flush();
|
||||
m_pStorage->m_iBytesWritten -= uSize;
|
||||
m_pStorage->m_pFile->SeekToBegin();
|
||||
}
|
||||
|
||||
WriteCentralEnd();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void CZipCentralDir::WriteHeaders()
|
||||
{
|
||||
m_uDiskEntriesNo = 0;
|
||||
m_uDiskWithCD = (WORD)m_pStorage->GetCurrentDisk();
|
||||
m_uOffset = m_pStorage->GetPosition() - m_uBytesBeforeZip;
|
||||
if (!m_uEntriesNumber)
|
||||
return;
|
||||
|
||||
WORD iDisk = m_uDiskWithCD;
|
||||
for (int i = 0; i < m_uEntriesNumber; i++)
|
||||
{
|
||||
CZipFileHeader* pHeader = m_headers[i];
|
||||
ConvertFileName(false, true, pHeader);
|
||||
m_uSize += pHeader->Write(m_pStorage);
|
||||
if (m_pStorage->GetCurrentDisk() != iDisk)
|
||||
{
|
||||
m_uDiskEntriesNo = 1;
|
||||
iDisk = (WORD)m_pStorage->GetCurrentDisk();
|
||||
// update the information about the offset and starting disk if the
|
||||
// first header was written on the new disk
|
||||
if (i == 0)
|
||||
{
|
||||
m_uOffset = 0;
|
||||
m_uDiskWithCD = iDisk;
|
||||
}
|
||||
}
|
||||
else
|
||||
m_uDiskEntriesNo++;
|
||||
}
|
||||
}
|
||||
|
||||
DWORD CZipCentralDir::WriteCentralEnd()
|
||||
{
|
||||
DWORD uSize = GetSize();
|
||||
CZipAutoBuffer buf(uSize);
|
||||
WORD uCommentSize = (WORD)m_pszComment.GetSize();
|
||||
memcpy(buf, m_gszSignature, 4);
|
||||
memcpy(buf + 4, &m_uThisDisk, 2);
|
||||
memcpy(buf + 6, &m_uDiskWithCD, 2);
|
||||
memcpy(buf + 8, &m_uDiskEntriesNo, 2);
|
||||
memcpy(buf + 10, &m_uEntriesNumber, 2);
|
||||
memcpy(buf + 12, &m_uSize, 4);
|
||||
memcpy(buf + 16, &m_uOffset, 4);
|
||||
memcpy(buf + 20, &uCommentSize, 2);
|
||||
memcpy(buf + 22, m_pszComment, uCommentSize);
|
||||
m_pStorage->Write(buf, uSize, true);
|
||||
return uSize;
|
||||
}
|
||||
|
||||
|
||||
void CZipCentralDir::RemoveFile(WORD uIndex)
|
||||
{
|
||||
CZipFileHeader* pHeader = m_headers[uIndex];
|
||||
if (m_bFindFastEnabled)
|
||||
{
|
||||
int i = FindFileNameIndex(pHeader->GetFileName(), true);
|
||||
ASSERT(i != -1);
|
||||
int uIndex = m_findarray[i].m_uIndex;
|
||||
m_findarray.RemoveAt(i);
|
||||
// shift down the indexes
|
||||
for (int j = 0; j < m_findarray.GetSize(); j++)
|
||||
{
|
||||
if (m_findarray[j].m_uIndex > uIndex)
|
||||
m_findarray[j].m_uIndex--;
|
||||
}
|
||||
}
|
||||
delete pHeader;
|
||||
m_headers.RemoveAt(uIndex);
|
||||
}
|
||||
|
||||
|
||||
DWORD CZipCentralDir::GetSize(bool bWhole)
|
||||
{
|
||||
DWORD uHeaders = 0;
|
||||
if (bWhole)
|
||||
{
|
||||
for (int i = 0; i < m_headers.GetSize(); i++)
|
||||
uHeaders += m_headers[i]->GetSize();
|
||||
}
|
||||
return ZIPCENTRALDIRSIZE + m_pszComment.GetSize() + uHeaders;
|
||||
}
|
||||
|
||||
// remove data descriptors from the write buffer in the disk spanning volume
|
||||
// that is one-disk only (do not remove from password encrypted files)
|
||||
bool CZipCentralDir::RemoveDataDescr(bool bFromBuffer)
|
||||
{
|
||||
CZipAutoHandle ah;
|
||||
char* pFile = NULL;
|
||||
DWORD uSize;
|
||||
if (bFromBuffer)
|
||||
{
|
||||
uSize = m_pStorage->m_uBytesInWriteBuffer;
|
||||
pFile = m_pStorage->m_pWriteBuffer;
|
||||
}
|
||||
else
|
||||
{
|
||||
uSize = m_pStorage->m_pFile->GetLength();
|
||||
if (!ah.CreateMapping((HANDLE)m_pStorage->m_pFile->m_hFile))
|
||||
return false;
|
||||
pFile = (char*)ah.m_pFileMap;
|
||||
}
|
||||
|
||||
DWORD uOffsetToChange = 4;
|
||||
DWORD uToCopy = 0;
|
||||
DWORD uPosInBuffer = 0;
|
||||
DWORD uExtraHeaderLen;
|
||||
// this will work providing the order in the m_headers is the same as
|
||||
// in the archive
|
||||
for (int i = 0; i < m_headers.GetSize(); i++)
|
||||
{
|
||||
// update the flag value in the local and central header
|
||||
// int uDataDescr = (m_headers[i]->m_uFlag & 8) ? (4 + 12) : 0;
|
||||
|
||||
CZipFileHeader* pHeader = m_headers[i];
|
||||
|
||||
|
||||
char* pSour = pFile + pHeader->m_uOffset;
|
||||
|
||||
if (!pHeader->IsEncrypted())
|
||||
{
|
||||
// removing data descriptor
|
||||
pHeader->m_uFlag &= ~8;
|
||||
// update local header:
|
||||
// write modified flag in the local header
|
||||
memcpy(pSour + 6, &pHeader->m_uFlag, 2);
|
||||
uExtraHeaderLen = 4/*ext. header signature*/ + 12/*data descriptor*/;
|
||||
}
|
||||
else
|
||||
// do not remove data descriptors from encrypted files
|
||||
uExtraHeaderLen = 0;
|
||||
|
||||
// update crc32 and sizes' values
|
||||
pHeader->GetCrcAndSizes(pSour+ 14);
|
||||
|
||||
uToCopy = (i == (m_headers.GetSize() - 1) ? uSize : m_headers[i + 1]->m_uOffset)
|
||||
- pHeader->m_uOffset - uExtraHeaderLen;
|
||||
|
||||
memmove(pFile + uPosInBuffer, pSour, uToCopy);
|
||||
|
||||
uPosInBuffer += uToCopy;
|
||||
pHeader->m_uOffset -= uOffsetToChange;
|
||||
uOffsetToChange += uExtraHeaderLen;
|
||||
}
|
||||
|
||||
if (bFromBuffer)
|
||||
m_pStorage->m_uBytesInWriteBuffer = uPosInBuffer;
|
||||
else
|
||||
{
|
||||
m_pStorage->m_iBytesWritten = uPosInBuffer;
|
||||
ah.RemoveMapping();
|
||||
m_pStorage->m_pFile->SetLength(uPosInBuffer);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void CZipCentralDir::RemoveHeaders()
|
||||
{
|
||||
for (int i = 0; i < m_headers.GetSize(); i++)
|
||||
delete m_headers[i];
|
||||
m_headers.RemoveAll();
|
||||
}
|
||||
|
||||
void CZipCentralDir::ConvertAll()
|
||||
{
|
||||
ASSERT(!m_bConvertAfterOpen);
|
||||
for (int i = 0; i < m_headers.GetSize(); i++)
|
||||
ConvertFileName(true, false, m_headers[i]);
|
||||
m_bConvertAfterOpen = true;
|
||||
}
|
||||
|
||||
|
||||
void CZipCentralDir::BuildFindFastArray()
|
||||
{
|
||||
m_findarray.RemoveAll();// just in case
|
||||
for (int i = 0; i < m_headers.GetSize(); i++)
|
||||
InsertFindFastElement(m_headers[i], (WORD)i);
|
||||
}
|
||||
|
||||
void CZipCentralDir::InsertFindFastElement(CZipFileHeader* pHeader, WORD uIndex)
|
||||
{
|
||||
CString fileName = pHeader->GetFileName();
|
||||
|
||||
|
||||
int iSize = m_findarray.GetSize();
|
||||
|
||||
// Our initial binary search range encompasses the entire array of filenames:
|
||||
int start = 0;
|
||||
int end = iSize;
|
||||
|
||||
// Keep halving our search range until we find the right place
|
||||
// to insert the new element:
|
||||
while ( start < end )
|
||||
{
|
||||
// Find the midpoint of the search range:
|
||||
int midpoint = ( start + end ) / 2;
|
||||
|
||||
// Compare the filename with the filename at the midpoint of the current search range:
|
||||
int result = CompareElement(fileName, (WORD)midpoint, true);
|
||||
|
||||
// If our filename is larger, it must fall in the first half of the search range:
|
||||
if ( result > 0 )
|
||||
{
|
||||
end = midpoint;
|
||||
}
|
||||
|
||||
// If it's smaller, it must fall in the last half:
|
||||
else if ( result < 0 )
|
||||
{
|
||||
start = midpoint + 1;
|
||||
}
|
||||
|
||||
// If they're equal, we can go ahead and insert here:
|
||||
else
|
||||
{
|
||||
start = midpoint; break;
|
||||
}
|
||||
}
|
||||
m_findarray.InsertAt(start, CZipFindFast(pHeader, WORD(uIndex == -1 ? iSize : uIndex /* just in case */)));
|
||||
}
|
||||
|
||||
int CZipCentralDir::FindFileNameIndex(LPCTSTR lpszFileName, bool bCaseSensitive)
|
||||
{
|
||||
int start = 0;
|
||||
int end = m_findarray.GetUpperBound();
|
||||
|
||||
// Keep halving our search range until we find the given element:
|
||||
while ( start <= end )
|
||||
{
|
||||
// Find the midpoint of the search range:
|
||||
int midpoint = ( start + end ) / 2;
|
||||
|
||||
// Compare the given filename with the filename at the midpoint of the search range:
|
||||
int result = CompareElement(lpszFileName, (WORD)midpoint, bCaseSensitive);
|
||||
|
||||
// If our filename is smaller, it must fall in the first half of the search range:
|
||||
if ( result > 0 )
|
||||
{
|
||||
end = midpoint - 1;
|
||||
}
|
||||
|
||||
// If it's larger, it must fall in the last half:
|
||||
else if ( result < 0 )
|
||||
{
|
||||
start = midpoint + 1;
|
||||
}
|
||||
|
||||
// If they're equal, return the result:
|
||||
else
|
||||
{
|
||||
return midpoint;
|
||||
}
|
||||
}
|
||||
|
||||
// Signal failure:
|
||||
return -1;
|
||||
}
|
|
@ -0,0 +1,156 @@
|
|||
// ZipCentralDir.h: interface for the CZipCentralDir class.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2000 Tadeusz Dracz.
|
||||
// For conditions of distribution and use, see copyright notice in ZipArchive.h
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if !defined(AFX_ZipCentralDir_H__859029E8_8927_4717_9D4B_E26E5DA12BAE__INCLUDED_)
|
||||
#define AFX_ZipCentralDir_H__859029E8_8927_4717_9D4B_E26E5DA12BAE__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
#include "ZipException.h"
|
||||
#include <afxtempl.h>
|
||||
#include "ZipFileHeader.h"
|
||||
#include "ZipAutoBuffer.h"
|
||||
|
||||
/**
|
||||
Used in fast finding files by the filename.
|
||||
\see CZipCentralDir::m_findarray
|
||||
\see CZipArchive::FindFile
|
||||
*/
|
||||
struct CZipFindFast
|
||||
{
|
||||
CZipFindFast()
|
||||
{
|
||||
m_uIndex = 0;
|
||||
m_pHeader= NULL;
|
||||
}
|
||||
CZipFindFast(CZipFileHeader* pHeader, WORD uIndex):m_pHeader(pHeader), m_uIndex(uIndex){}
|
||||
/**
|
||||
We extract a name from it.
|
||||
*/
|
||||
CZipFileHeader* m_pHeader;
|
||||
|
||||
/**
|
||||
The index in the central directory of the \e m_pHeader.
|
||||
*/
|
||||
WORD m_uIndex;
|
||||
};
|
||||
|
||||
|
||||
class CZipCentralDir
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
// end of central dir signature 4 bytes (0x06054b50)
|
||||
char m_szSignature[4];
|
||||
// number of this disk 2 bytes
|
||||
WORD m_uThisDisk;
|
||||
// number of the disk with the
|
||||
// start of the central directory 2 bytes
|
||||
WORD m_uDiskWithCD;
|
||||
// total number of entries in
|
||||
// the central dir on this disk 2 bytes
|
||||
WORD m_uDiskEntriesNo;
|
||||
// total number of entries in
|
||||
// the central dir 2 bytes
|
||||
WORD m_uEntriesNumber;
|
||||
// size of the central directory 4 bytes
|
||||
DWORD m_uSize;
|
||||
// offset of start of central
|
||||
// directory with respect to
|
||||
// the starting disk number 4 bytes
|
||||
DWORD m_uOffset;
|
||||
// zipfile comment length 2 bytes
|
||||
// WORD m_uCommentSize;
|
||||
// zipfile comment (variable size)
|
||||
CZipAutoBuffer m_pszComment;
|
||||
bool m_bFindFastEnabled;
|
||||
CZipFileHeader* m_pOpenedFile;
|
||||
void RemoveFile(WORD uIndex);
|
||||
void Clear(bool bEverything = true);
|
||||
CZipStorage* m_pStorage;
|
||||
DWORD m_uCentrDirPos;
|
||||
DWORD m_uBytesBeforeZip;
|
||||
CZipCentralDir();
|
||||
virtual ~CZipCentralDir();
|
||||
void CloseFile();
|
||||
void OpenFile(WORD uIndex);
|
||||
bool IsValidIndex(WORD uIndex);
|
||||
void Read();
|
||||
void Init();
|
||||
void CloseNewFile();
|
||||
void Write();
|
||||
int m_iBufferSize;
|
||||
bool m_bOnDisk;
|
||||
static char m_gszSignature[];
|
||||
CTypedPtrArray<CPtrArray, CZipFileHeader*> m_headers;
|
||||
CZipAutoBuffer m_pLocalExtraField;
|
||||
void AddNewFile(CZipFileHeader & header);
|
||||
void RemoveFromDisk();
|
||||
DWORD GetSize(bool bWhole = false);
|
||||
CArray<CZipFindFast, CZipFindFast> m_findarray;
|
||||
int FindFileNameIndex(LPCTSTR lpszFileName, bool bCaseSensitive);
|
||||
void BuildFindFastArray();
|
||||
/**
|
||||
- If \c true, the conversion of the filenames takes
|
||||
place after opening the archive (after reading the central directory
|
||||
from the file), and before writing the central directory back to
|
||||
the archive.
|
||||
- If \c false, the conversion takes place on each call to CZipArchive::GetFileInfo
|
||||
|
||||
Set it to \c true when you plan to use CZipArchive::FindFile or get the stored files information. <BR>
|
||||
Set it to \c false when you plan mostly to only modify the archive.
|
||||
|
||||
\b Default: \c true
|
||||
\note Set it before opening the archive.
|
||||
\see ConvertFileName
|
||||
*/
|
||||
bool m_bConvertAfterOpen;
|
||||
|
||||
/**
|
||||
Convert the filename of the CZipFileHeader.
|
||||
\param bFromZip
|
||||
if \c true, convert from archive format
|
||||
\param bAfterOpen
|
||||
if \c true, called after opening the archive or before closing
|
||||
\param pHeader
|
||||
the header to have filename converted; if \c NULL convert the currently
|
||||
opened file
|
||||
\see m_bConvertAfterOpen
|
||||
*/
|
||||
void ConvertFileName(bool bFromZip, bool bAfterOpen, CZipFileHeader* pHeader = NULL)
|
||||
{
|
||||
if (bAfterOpen != m_bConvertAfterOpen)
|
||||
return;
|
||||
if (!pHeader)
|
||||
{
|
||||
pHeader = m_pOpenedFile;
|
||||
ASSERT(pHeader);
|
||||
}
|
||||
pHeader->AnsiOem(!bFromZip);
|
||||
pHeader->SlashChange(bFromZip);
|
||||
}
|
||||
void ConvertAll();
|
||||
protected:
|
||||
void InsertFindFastElement(CZipFileHeader* pHeader, WORD uIndex);
|
||||
void RemoveHeaders();
|
||||
bool RemoveDataDescr(bool bFromBuffer);
|
||||
DWORD WriteCentralEnd();
|
||||
void WriteHeaders();
|
||||
void ReadHeaders();
|
||||
void ThrowError(int err);
|
||||
DWORD Locate();
|
||||
int CompareElement(LPCTSTR lpszFileName, WORD uIndex, bool bCaseSensitive)
|
||||
{
|
||||
return bCaseSensitive ? m_findarray[uIndex].m_pHeader->GetFileName().Collate(lpszFileName)
|
||||
: m_findarray[uIndex].m_pHeader->GetFileName().CollateNoCase(lpszFileName);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif // !defined(AFX_ZipCentralDir_H__859029E8_8927_4717_9D4B_E26E5DA12BAE__INCLUDED_)
|
|
@ -0,0 +1,78 @@
|
|||
// ZipException.cpp: implementation of the CZipException class.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2000 Tadeusz Dracz.
|
||||
// For conditions of distribution and use, see copyright notice in ZipArchive.h
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "ZipException.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Construction/Destruction
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
IMPLEMENT_DYNAMIC( CZipException, CException)
|
||||
|
||||
CZipException::CZipException(int iCause, LPCTSTR lpszZipName):CException(TRUE)
|
||||
{
|
||||
m_iCause = iCause;
|
||||
|
||||
if (lpszZipName)
|
||||
m_szFileName = lpszZipName;
|
||||
}
|
||||
|
||||
CZipException::~CZipException()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void AfxThrowZipException(int iZipError, LPCTSTR lpszZipName)
|
||||
{
|
||||
throw new CZipException(CZipException::ZipErrToCause(iZipError), lpszZipName);
|
||||
}
|
||||
|
||||
int CZipException::ZipErrToCause(int iZipError)
|
||||
{
|
||||
switch (iZipError)
|
||||
{
|
||||
case 2://Z_NEED_DICT:
|
||||
return CZipException::needDict;
|
||||
case 1://Z_STREAM_END:
|
||||
return CZipException::streamEnd;
|
||||
case -1://Z_ERRNO:
|
||||
return CZipException::errNo;
|
||||
case -2://Z_STREAM_ERROR:
|
||||
return CZipException::streamError;
|
||||
case -3://Z_DATA_ERROR:
|
||||
return CZipException::dataError;
|
||||
case -4://Z_MEM_ERROR:
|
||||
return CZipException::memError;
|
||||
case -5://Z_BUF_ERROR:
|
||||
return CZipException::bufError;
|
||||
case -6://Z_VERSION_ERROR:
|
||||
return CZipException::versionError;
|
||||
case ZIP_BADZIPFILE:
|
||||
return CZipException::badZipFile;
|
||||
case ZIP_BADCRC:
|
||||
return CZipException::badCrc;
|
||||
case ZIP_ABORTED:
|
||||
return CZipException::aborted;
|
||||
case ZIP_NOCALLBACK:
|
||||
return CZipException::noCallback;
|
||||
case ZIP_NONREMOVABLE:
|
||||
return CZipException::nonRemovable;
|
||||
case ZIP_TOOMANYVOLUMES:
|
||||
return CZipException::tooManyVolumes;
|
||||
case ZIP_TOOLONGFILENAME:
|
||||
return CZipException::tooLongFileName;
|
||||
case ZIP_BADPASSWORD:
|
||||
return CZipException::badPassword;
|
||||
case ZIP_CDIR_NOTFOUND:
|
||||
return CZipException::cdirNotFound;
|
||||
|
||||
|
||||
default:
|
||||
return CZipException::generic;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
// ZipException.h: interface for the CZipException class.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2000 Tadeusz Dracz.
|
||||
// For conditions of distribution and use, see copyright notice in ZipArchive.h
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if !defined(AFX_ZIPEXCEPTION_H__E3546921_D728_11D3_B7C7_E77339672847__INCLUDED_)
|
||||
#define AFX_ZIPEXCEPTION_H__E3546921_D728_11D3_B7C7_E77339672847__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
typedef unsigned short uShort;
|
||||
// errors number definitions
|
||||
#define ZIP_BADZIPFILE (-101)
|
||||
#define ZIP_BADCRC (-102)
|
||||
#define ZIP_NOCALLBACK (-103)
|
||||
#define ZIP_ABORTED (-104)
|
||||
#define ZIP_NONREMOVABLE (-105)
|
||||
#define ZIP_TOOMANYVOLUMES (-106)
|
||||
#define ZIP_TOOLONGFILENAME (-107)
|
||||
#define ZIP_BADPASSWORD (-108)
|
||||
#define ZIP_CDIR_NOTFOUND (-109)
|
||||
|
||||
class CZipException : public CException
|
||||
{
|
||||
public:
|
||||
DECLARE_DYNAMIC(CZipException)
|
||||
// convert zlib library and internal error code to a ZipException code
|
||||
static int ZipErrToCause(int iZipError);
|
||||
// name of the zip file where the error occured
|
||||
CString m_szFileName;
|
||||
|
||||
enum
|
||||
{
|
||||
noError, // no error
|
||||
generic, // unknown error
|
||||
streamEnd, // zlib library errors
|
||||
needDict, //
|
||||
errNo, //
|
||||
streamError, //
|
||||
dataError, //
|
||||
memError, //
|
||||
bufError, //
|
||||
versionError, //
|
||||
badZipFile, // damaged or not a zip file
|
||||
badCrc, // crc mismatched
|
||||
noCallback, // no callback function set
|
||||
aborted, // disk change callback function returned false
|
||||
nonRemovable, // the disk selected for pkSpan archive is non removable
|
||||
tooManyVolumes, // limit of the maximum volumes reached (999)
|
||||
tooLongFileName, // the file name of the file added to the archive is too long
|
||||
badPassword, // incorrect password set for the file being decrypted
|
||||
cdirNotFound, ///< the central directory was not found in the archive
|
||||
dirWithSize // during testing: found the directory with the size greater than 0
|
||||
};
|
||||
// cause - takes one of the codes above
|
||||
int m_iCause;
|
||||
CZipException(int iCause = generic, LPCTSTR lpszZipName = NULL);
|
||||
virtual ~CZipException();
|
||||
|
||||
};
|
||||
|
||||
// throw zip exception
|
||||
// Parameters:
|
||||
// iZipError - zlib or internal error code
|
||||
// lpszZipName - name of the file where the error occured
|
||||
void AfxThrowZipException(int iZipError = 1000, LPCTSTR lpszZipName = NULL);
|
||||
|
||||
#endif // !defined(AFX_ZIPEXCEPTION_H__E3546921_D728_11D3_B7C7_E77339672847__INCLUDED_)
|
|
@ -0,0 +1,329 @@
|
|||
// ZipFileHeader.cpp: implementation of the CZipFileHeader class.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2000 Tadeusz Dracz.
|
||||
// For conditions of distribution and use, see copyright notice in ZipArchive.h
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "ZipFileHeader.h"
|
||||
#include "zlib.h"
|
||||
#include "ZipAutoBuffer.h"
|
||||
#include "ZipArchive.h"
|
||||
|
||||
#define ZipFileHeaderSIZE 46
|
||||
#define LOCALZipFileHeaderSIZE 30
|
||||
#define VERSIONMADEBY 20
|
||||
#define ENCR_HEADER_LEN 12
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Construction/Destruction
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
char CZipFileHeader::m_gszSignature[] = {0x50, 0x4b, 0x01, 0x02};
|
||||
char CZipFileHeader::m_gszLocalSignature[] = {0x50, 0x4b, 0x03, 0x04};
|
||||
CZipFileHeader::CZipFileHeader()
|
||||
{
|
||||
m_uExternalAttr = FILE_ATTRIBUTE_ARCHIVE;
|
||||
m_uModDate = m_uModTime = m_uInternalAttr = 0;
|
||||
m_uMethod = Z_DEFLATED;
|
||||
}
|
||||
|
||||
CZipFileHeader::~CZipFileHeader()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// read the header from the central dir
|
||||
bool CZipFileHeader::Read(CZipStorage *pStorage)
|
||||
{
|
||||
// // just in case
|
||||
// m_pszComment.Release();
|
||||
// m_pszFileName.Release();
|
||||
WORD uFileNameSize, uCommentSize, uExtraFieldSize;
|
||||
CZipAutoBuffer buf(ZipFileHeaderSIZE);
|
||||
pStorage->Read(buf, ZipFileHeaderSIZE, true);
|
||||
memcpy(&m_szSignature, buf, 4);
|
||||
memcpy(&m_uVersionMadeBy, buf + 4, 2);
|
||||
memcpy(&m_uVersionNeeded, buf + 6, 2);
|
||||
memcpy(&m_uFlag, buf + 8, 2);
|
||||
memcpy(&m_uMethod, buf + 10, 2);
|
||||
memcpy(&m_uModTime, buf + 12, 2);
|
||||
memcpy(&m_uModDate, buf + 14, 2);
|
||||
memcpy(&m_uCrc32, buf + 16, 4);
|
||||
memcpy(&m_uComprSize, buf + 20, 4);
|
||||
memcpy(&m_uUncomprSize, buf + 24, 4);
|
||||
memcpy(&uFileNameSize, buf + 28, 2);
|
||||
memcpy(&uExtraFieldSize, buf + 30, 2);
|
||||
memcpy(&uCommentSize, buf + 32, 2);
|
||||
memcpy(&m_uDiskStart, buf + 34, 2);
|
||||
memcpy(&m_uInternalAttr, buf + 36, 2);
|
||||
memcpy(&m_uExternalAttr, buf + 38, 4);
|
||||
memcpy(&m_uOffset, buf + 42, 4);
|
||||
buf.Release();
|
||||
|
||||
if (memcmp(m_szSignature, m_gszSignature, 4) != 0)
|
||||
return false;
|
||||
|
||||
int iCurDsk = pStorage->GetCurrentDisk();
|
||||
m_pszFileName.Allocate(uFileNameSize); // don't add NULL at the end
|
||||
pStorage->m_pFile->Read(m_pszFileName, uFileNameSize);
|
||||
if (uExtraFieldSize)
|
||||
{
|
||||
ASSERT(!m_pExtraField.IsAllocated());
|
||||
m_pExtraField.Allocate(uExtraFieldSize);
|
||||
pStorage->m_pFile->Read(m_pExtraField, uExtraFieldSize);
|
||||
}
|
||||
if (uCommentSize)
|
||||
{
|
||||
m_pszComment.Allocate(uCommentSize);
|
||||
pStorage->m_pFile->Read(m_pszComment, uCommentSize);
|
||||
}
|
||||
|
||||
return pStorage->GetCurrentDisk() == iCurDsk; // check that the while header is on the one disk
|
||||
}
|
||||
|
||||
// return CTime representation of m_uModDate, m_uModTime
|
||||
CTime CZipFileHeader::GetTime()
|
||||
{
|
||||
return CTime(m_uModDate, m_uModTime);
|
||||
}
|
||||
|
||||
// write the header to the central dir
|
||||
DWORD CZipFileHeader::Write(CZipStorage *pStorage)
|
||||
{
|
||||
WORD uFileNameSize = GetFileNameSize(), uCommentSize = GetCommentSize(),
|
||||
uExtraFieldSize = GetExtraFieldSize();
|
||||
DWORD iSize = GetSize();
|
||||
CZipAutoBuffer buf(iSize);
|
||||
memcpy(buf, &m_szSignature, 4);
|
||||
memcpy(buf + 4, &m_uVersionMadeBy, 2);
|
||||
memcpy(buf + 6, &m_uVersionNeeded, 2);
|
||||
memcpy(buf + 8, &m_uFlag, 2);
|
||||
memcpy(buf + 10, &m_uMethod, 2);
|
||||
memcpy(buf + 12, &m_uModTime, 2);
|
||||
memcpy(buf + 14, &m_uModDate, 2);
|
||||
memcpy(buf + 16, &m_uCrc32, 4);
|
||||
memcpy(buf + 20, &m_uComprSize, 4);
|
||||
memcpy(buf + 24, &m_uUncomprSize, 4);
|
||||
memcpy(buf + 28, &uFileNameSize, 2);
|
||||
memcpy(buf + 30, &uExtraFieldSize, 2);
|
||||
memcpy(buf + 32, &uCommentSize, 2);
|
||||
memcpy(buf + 34, &m_uDiskStart, 2);
|
||||
memcpy(buf + 36, &m_uInternalAttr, 2);
|
||||
memcpy(buf + 38, &m_uExternalAttr, 4);
|
||||
memcpy(buf + 42, &m_uOffset, 4);
|
||||
|
||||
memcpy(buf + 46, m_pszFileName, uFileNameSize);
|
||||
|
||||
if (uExtraFieldSize)
|
||||
memcpy(buf + 46 + uFileNameSize, m_pExtraField, uExtraFieldSize);
|
||||
|
||||
if (uCommentSize)
|
||||
memcpy(buf + 46 + uFileNameSize + uExtraFieldSize, m_pszComment, uCommentSize);
|
||||
|
||||
pStorage->Write(buf, iSize, true);
|
||||
return iSize;
|
||||
}
|
||||
|
||||
// read local header
|
||||
bool CZipFileHeader::ReadLocal(CZipStorage *pStorage, WORD& iLocExtrFieldSize)
|
||||
{
|
||||
char buf[LOCALZipFileHeaderSIZE];
|
||||
pStorage->Read(buf, LOCALZipFileHeaderSIZE, true);
|
||||
if (memcmp(buf, m_gszLocalSignature, 4) != 0)
|
||||
return false;
|
||||
|
||||
bool bIsDataDescr = (((WORD)*(buf + 6)) & 8) != 0;
|
||||
|
||||
WORD uFileNameSize = GetFileNameSize();
|
||||
if ((memcmp(buf + 6, &m_uFlag, 2) != 0)
|
||||
||(memcmp(buf + 8, &m_uMethod, 2) != 0)
|
||||
|| (m_uMethod && (m_uMethod != Z_DEFLATED))
|
||||
|| (memcmp(buf + 26, &uFileNameSize, 2) != 0))
|
||||
return false;
|
||||
|
||||
// jeszcze mo¿naby porównaæ nazwy plików
|
||||
|
||||
if (!bIsDataDescr/* || !pStorage->IsSpanMode()*/)
|
||||
if (!CheckCrcAndSizes(buf + 14))
|
||||
return false;
|
||||
|
||||
memcpy(&iLocExtrFieldSize, buf + 28, 2);
|
||||
pStorage->m_pFile->Seek(uFileNameSize, CFile::current);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// set the m_uModDate, m_uModTime values using CTime object
|
||||
void CZipFileHeader::SetTime(const CTime &time)
|
||||
{
|
||||
WORD year = (WORD)time.GetYear();
|
||||
if (year <= 1980)
|
||||
year = 0;
|
||||
else
|
||||
year -= 1980;
|
||||
m_uModDate = (WORD) (time.GetDay() + (time.GetMonth() << 5) + (year << 9));
|
||||
m_uModTime = (WORD) ((time.GetSecond() >> 1) + (time.GetMinute() << 5) +
|
||||
(time.GetHour() << 11));
|
||||
}
|
||||
// the buffer contains crc32, compressed and uncompressed sizes to be compared
|
||||
// with the actual values
|
||||
bool CZipFileHeader::CheckCrcAndSizes(char *pBuf)
|
||||
{
|
||||
return (memcmp(pBuf, &m_uCrc32, 4) == 0) && (memcmp(pBuf + 4, &m_uComprSize, 4) == 0)
|
||||
&& (memcmp(pBuf + 8, &m_uUncomprSize, 4) == 0);
|
||||
}
|
||||
|
||||
// write the local header
|
||||
void CZipFileHeader::WriteLocal(CZipStorage& storage)
|
||||
{
|
||||
// extra field is local by now
|
||||
WORD uFileNameSize = GetFileNameSize(), uExtraFieldSize = GetExtraFieldSize();
|
||||
DWORD iLocalSize = LOCALZipFileHeaderSIZE + uExtraFieldSize + uFileNameSize;
|
||||
CZipAutoBuffer buf(iLocalSize);
|
||||
memcpy(buf, m_gszLocalSignature, 4);
|
||||
memcpy(buf + 4, &m_uVersionNeeded, 2);
|
||||
memcpy(buf + 6, &m_uFlag, 2);
|
||||
memcpy(buf + 8, &m_uMethod, 2);
|
||||
memcpy(buf + 10, &m_uModTime, 2);
|
||||
memcpy(buf + 12, &m_uModDate, 2);
|
||||
memcpy(buf + 14, &m_uCrc32, 4);
|
||||
memcpy(buf + 18, &m_uComprSize, 4);
|
||||
memcpy(buf + 22, &m_uUncomprSize, 4);
|
||||
memcpy(buf + 26, &uFileNameSize, 2);
|
||||
memcpy(buf + 28, &uExtraFieldSize, 2);
|
||||
memcpy(buf + 30, m_pszFileName, uFileNameSize);
|
||||
memcpy(buf + 30 + uFileNameSize, m_pExtraField, uExtraFieldSize);
|
||||
|
||||
// possible disk change before writting to the file in the disk spanning mode
|
||||
// so write the local header first
|
||||
storage.Write(buf, iLocalSize, true);
|
||||
// it was only local information, use CZipArchive::SetExtraField to set the file extra field in the central directory
|
||||
m_pExtraField.Release();
|
||||
|
||||
m_uDiskStart = (WORD)storage.GetCurrentDisk();
|
||||
m_uOffset = storage.GetPosition() - iLocalSize;
|
||||
}
|
||||
|
||||
// prepare the data before adding a new file
|
||||
bool CZipFileHeader::PrepareData(int iLevel, bool bExtraHeader, bool bEncrypted)
|
||||
{
|
||||
memcpy(m_szSignature, m_gszSignature, 4);
|
||||
m_uInternalAttr = 0;
|
||||
m_uVersionMadeBy = VERSIONMADEBY;
|
||||
m_uVersionNeeded = 20;
|
||||
|
||||
m_uCrc32 = 0;
|
||||
m_uComprSize = 0;
|
||||
m_uUncomprSize = 0;
|
||||
if (iLevel == 0)
|
||||
m_uMethod = 0;
|
||||
|
||||
if ((m_uMethod != Z_DEFLATED) && (m_uMethod != 0))
|
||||
m_uMethod = Z_DEFLATED;
|
||||
|
||||
m_uFlag = 0;
|
||||
if (m_uMethod == Z_DEFLATED)
|
||||
switch (iLevel)
|
||||
{
|
||||
case 1:
|
||||
m_uFlag |= 6;
|
||||
break;
|
||||
case 2:
|
||||
m_uFlag |= 4;
|
||||
break;
|
||||
case 8:
|
||||
case 9:
|
||||
m_uFlag |= 2;
|
||||
break;
|
||||
}
|
||||
|
||||
if (bExtraHeader)
|
||||
m_uFlag |= 8; // data descriptor present
|
||||
|
||||
if (bEncrypted)
|
||||
{
|
||||
m_uComprSize = ENCR_HEADER_LEN; // encrypted header
|
||||
m_uFlag |= 9; // encrypted file
|
||||
}
|
||||
|
||||
return !(m_pszComment.GetSize() > USHRT_MAX || m_pszFileName.GetSize() > USHRT_MAX
|
||||
|| m_pExtraField.GetSize() > USHRT_MAX);
|
||||
}
|
||||
|
||||
// fill the buffer with the current values
|
||||
void CZipFileHeader::GetCrcAndSizes(char * pBuffer)
|
||||
{
|
||||
memcpy(pBuffer, &m_uCrc32, 4);
|
||||
memcpy(pBuffer + 4, &m_uComprSize, 4);
|
||||
memcpy(pBuffer + 8, &m_uUncomprSize, 4);
|
||||
}
|
||||
|
||||
DWORD CZipFileHeader::GetSize()
|
||||
{
|
||||
return ZipFileHeaderSIZE + GetExtraFieldSize() + GetFileNameSize() + GetCommentSize();
|
||||
}
|
||||
|
||||
|
||||
bool CZipFileHeader::IsEncrypted()
|
||||
{
|
||||
return (m_uFlag & (WORD) 1) != 0;
|
||||
}
|
||||
|
||||
bool CZipFileHeader::IsDataDescr()
|
||||
{
|
||||
return (m_uFlag & (WORD) 8) != 0;
|
||||
}
|
||||
|
||||
bool CZipFileHeader::SetComment(LPCTSTR lpszComment)
|
||||
{
|
||||
return CZipArchive::WideToSingle(lpszComment, m_pszComment) != -1;
|
||||
}
|
||||
|
||||
CString CZipFileHeader::GetComment()
|
||||
{
|
||||
CString temp;
|
||||
CZipArchive::SingleToWide(m_pszComment, temp);
|
||||
return temp;
|
||||
|
||||
}
|
||||
|
||||
bool CZipFileHeader::SetFileName(LPCTSTR lpszFileName)
|
||||
{
|
||||
return CZipArchive::WideToSingle(lpszFileName, m_pszFileName) != -1;
|
||||
}
|
||||
|
||||
CString CZipFileHeader::GetFileName()
|
||||
{
|
||||
CString temp;
|
||||
CZipArchive::SingleToWide(m_pszFileName, temp);
|
||||
return temp;
|
||||
}
|
||||
|
||||
|
||||
void CZipFileHeader::SlashChange(bool bWindowsStyle)
|
||||
{
|
||||
char t1 = '\\', t2 = '/', c1, c2;
|
||||
if (bWindowsStyle)
|
||||
{
|
||||
c1 = t1;
|
||||
c2 = t2;
|
||||
}
|
||||
else
|
||||
{
|
||||
c1 = t2;
|
||||
c2 = t1;
|
||||
}
|
||||
for (DWORD i = 0; i < m_pszFileName.GetSize(); i++)
|
||||
{
|
||||
if (m_pszFileName[i] == c2)
|
||||
m_pszFileName[i] = c1;
|
||||
}
|
||||
}
|
||||
|
||||
void CZipFileHeader::AnsiOem(bool bAnsiToOem)
|
||||
{
|
||||
if (bAnsiToOem)
|
||||
CharToOemBuffA(m_pszFileName, m_pszFileName, m_pszFileName.GetSize());
|
||||
else
|
||||
OemToCharBuffA(m_pszFileName, m_pszFileName, m_pszFileName.GetSize());
|
||||
}
|
|
@ -0,0 +1,106 @@
|
|||
// ZipFileHeader.h: interface for the CZipFileHeader class.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2000 Tadeusz Dracz.
|
||||
// For conditions of distribution and use, see copyright notice in ZipArchive.h
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if !defined(AFX_ZipFileHeader_H__0081FC65_C9C9_4D48_AF72_DBF37DF5E0CF__INCLUDED_)
|
||||
#define AFX_ZipFileHeader_H__0081FC65_C9C9_4D48_AF72_DBF37DF5E0CF__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
|
||||
#include "ZipException.h"
|
||||
#include "ZipStorage.h"
|
||||
#include "ZipAutoBuffer.h"
|
||||
|
||||
class CZipFileHeader
|
||||
{
|
||||
public:
|
||||
// convert characters in the filename from oem to ansi or vice-versa
|
||||
void AnsiOem(bool bAnsiToOem);
|
||||
// change slash to backslash or vice-versa
|
||||
void SlashChange(bool bWindowsStyle);
|
||||
// return the filename size in characters (without NULL);
|
||||
WORD GetFileNameSize(){return (WORD)m_pszFileName.GetSize();}
|
||||
// return the comment size in characters (without NULL);
|
||||
WORD GetCommentSize(){return (WORD)m_pszComment.GetSize();}
|
||||
// return the extra field size in characters (without NULL);
|
||||
WORD GetExtraFieldSize(){return (WORD)m_pExtraField.GetSize();}
|
||||
|
||||
CString GetFileName();
|
||||
// return true if confersion from unicode to single byte was successful
|
||||
bool SetFileName(LPCTSTR lpszFileName);
|
||||
CString GetComment();
|
||||
// return true if confersion from unicode to single byte was successful
|
||||
bool SetComment(LPCTSTR lpszComment);
|
||||
// return true if the data descriptor is present
|
||||
bool IsDataDescr();
|
||||
// return true if the file is encrypted
|
||||
bool IsEncrypted();
|
||||
// central file header signature 4 bytes (0x02014b50)
|
||||
char m_szSignature[4];
|
||||
// version made by 2 bytes
|
||||
WORD m_uVersionMadeBy;
|
||||
// version needed to extract 2 bytes
|
||||
WORD m_uVersionNeeded;
|
||||
// general purpose bit flag 2 bytes
|
||||
WORD m_uFlag;
|
||||
// compression method 2 bytes
|
||||
WORD m_uMethod;
|
||||
// last mod file time 2 bytes
|
||||
WORD m_uModTime;
|
||||
// last mod file date 2 bytes
|
||||
WORD m_uModDate;
|
||||
// crc-32 4 bytes
|
||||
DWORD m_uCrc32;
|
||||
// compressed size 4 bytes
|
||||
DWORD m_uComprSize;
|
||||
// uncompressed size 4 bytes
|
||||
DWORD m_uUncomprSize;
|
||||
// filename length 2 bytes
|
||||
// WORD m_uFileNameSize;
|
||||
// extra field length 2 bytes
|
||||
// WORD m_uExtraFieldSize;
|
||||
// file comment length 2 bytes
|
||||
// WORD m_uCommentSize;
|
||||
// disk number start 2 bytes
|
||||
WORD m_uDiskStart;
|
||||
// internal file attributes 2 bytes
|
||||
WORD m_uInternalAttr;
|
||||
// external file attributes 4 bytes
|
||||
DWORD m_uExternalAttr;
|
||||
// relative offset of local header 4 bytes
|
||||
DWORD m_uOffset;
|
||||
// extra field (variable size)
|
||||
CZipAutoBuffer m_pExtraField;
|
||||
|
||||
CZipFileHeader();
|
||||
virtual ~CZipFileHeader();
|
||||
CTime GetTime();
|
||||
void SetTime(const CTime& time);
|
||||
static char m_gszSignature[];
|
||||
static char m_gszLocalSignature[];
|
||||
// return the total size of the structure as stored in the central directory
|
||||
DWORD GetSize();
|
||||
protected:
|
||||
// filename (variable size)
|
||||
CZipAutoBuffer m_pszFileName;
|
||||
// file comment (variable size)
|
||||
CZipAutoBuffer m_pszComment;
|
||||
|
||||
void GetCrcAndSizes(char * pBuffer);
|
||||
bool PrepareData(int iLevel, bool bExtraHeader, bool bEncrypted);
|
||||
void WriteLocal(CZipStorage& storage);
|
||||
bool CheckCrcAndSizes(char* pBuf);
|
||||
friend class CZipCentralDir;
|
||||
friend class CZipArchive;
|
||||
bool Read(CZipStorage *pStorage);
|
||||
bool ReadLocal(CZipStorage *pStorage, WORD& iLocExtrFieldSize);
|
||||
DWORD Write(CZipStorage *pStorage);
|
||||
|
||||
};
|
||||
|
||||
#endif // !defined(AFX_ZipFileHeader_H__0081FC65_C9C9_4D48_AF72_DBF37DF5E0CF__INCLUDED_)
|
|
@ -0,0 +1,28 @@
|
|||
// ZipInternalInfo.cpp: implementation of the CZipInternalInfo class.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2000 Tadeusz Dracz.
|
||||
// For conditions of distribution and use, see copyright notice in ZipArchive.h
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "ZipInternalInfo.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Construction/Destruction
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
CZipInternalInfo::CZipInternalInfo()
|
||||
{
|
||||
m_iBufferSize = 16384;
|
||||
}
|
||||
|
||||
CZipInternalInfo::~CZipInternalInfo()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CZipInternalInfo::Init()
|
||||
{
|
||||
m_pBuffer.Allocate(m_iBufferSize);
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
// ZipInternalInfo.h: interface for the CZipInternalInfo class.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2000 Tadeusz Dracz.
|
||||
// For conditions of distribution and use, see copyright notice in ZipArchive.h
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if !defined(AFX_ZIPINTERNALINFO_H__C6749101_590C_4F74_8121_B82E3BE9FA44__INCLUDED_)
|
||||
#define AFX_ZIPINTERNALINFO_H__C6749101_590C_4F74_8121_B82E3BE9FA44__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
#include "ZipAutoBuffer.h"
|
||||
#include "zlib.h"
|
||||
|
||||
class CZipInternalInfo
|
||||
{
|
||||
public:
|
||||
DWORD m_iBufferSize;
|
||||
z_stream m_stream;
|
||||
DWORD m_uUncomprLeft;
|
||||
DWORD m_uComprLeft;
|
||||
DWORD m_uCrc32;
|
||||
void Init();
|
||||
CZipAutoBuffer m_pBuffer;
|
||||
CZipInternalInfo();
|
||||
virtual ~CZipInternalInfo();
|
||||
|
||||
};
|
||||
|
||||
#endif // !defined(AFX_ZIPINTERNALINFO_H__C6749101_590C_4F74_8121_B82E3BE9FA44__INCLUDED_)
|
|
@ -0,0 +1,428 @@
|
|||
// ZipStorage.cpp: implementation of the CZipStorage class.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2000 Tadeusz Dracz.
|
||||
// For conditions of distribution and use, see copyright notice in ZipArchive.h
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "ZipStorage.h"
|
||||
#include "ZipArchive.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// disk spanning objectives:
|
||||
// - sinature at the first disk at the beginning
|
||||
// - headers and central dir records not divided between disks
|
||||
// - each file has a data descriptor preceded by the signature
|
||||
// (bit 3 set in flag);
|
||||
|
||||
|
||||
char CZipStorage::m_gszExtHeaderSignat[] = {0x50, 0x4b, 0x07, 0x08};
|
||||
CZipStorage::CZipStorage()
|
||||
{
|
||||
m_pCallbackData = m_pZIPCALLBACKFUN = NULL;
|
||||
m_iWriteBufferSize = 65535;
|
||||
m_iCurrentDisk = -1;
|
||||
m_pFile = NULL;
|
||||
}
|
||||
|
||||
CZipStorage::~CZipStorage()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
DWORD CZipStorage::Read(void *pBuf, DWORD iSize, bool bAtOnce)
|
||||
{
|
||||
if (iSize == 0)
|
||||
return 0;
|
||||
DWORD iRead = 0;
|
||||
while (!iRead)
|
||||
{
|
||||
iRead = m_pFile->Read(pBuf, iSize);
|
||||
if (!iRead)
|
||||
if (IsSpanMode())
|
||||
ChangeDisk(m_iCurrentDisk + 1);
|
||||
else
|
||||
ThrowError(ZIP_BADZIPFILE);
|
||||
}
|
||||
|
||||
if (iRead == iSize)
|
||||
return iRead;
|
||||
else if (bAtOnce || !IsSpanMode())
|
||||
ThrowError(ZIP_BADZIPFILE);
|
||||
|
||||
while (iRead < iSize)
|
||||
{
|
||||
ChangeDisk(m_iCurrentDisk + 1);
|
||||
UINT iNewRead = m_pFile->Read((char*)pBuf + iRead, iSize - iRead);
|
||||
if (!iNewRead && iRead < iSize)
|
||||
ThrowError(ZIP_BADZIPFILE);
|
||||
iRead += iNewRead;
|
||||
}
|
||||
|
||||
return iRead;
|
||||
}
|
||||
|
||||
void CZipStorage::Open(LPCTSTR szPathName, int iMode, int iVolumeSize)
|
||||
{
|
||||
m_pWriteBuffer.Allocate(m_iWriteBufferSize);
|
||||
m_uBytesInWriteBuffer = 0;
|
||||
m_bNewSpan = false;
|
||||
m_pFile = &m_internalfile;
|
||||
|
||||
if ((iMode == CZipArchive::create) ||(iMode == CZipArchive::createSpan)) // create new archive
|
||||
{
|
||||
m_iCurrentDisk = 0;
|
||||
if (iMode == CZipArchive::create)
|
||||
{
|
||||
m_iSpanMode = noSpan;
|
||||
OpenFile(szPathName, CFile::modeCreate | CFile::modeReadWrite);
|
||||
}
|
||||
else // create disk spanning archive
|
||||
{
|
||||
m_bNewSpan = true;
|
||||
m_iBytesWritten = 0;
|
||||
if (iVolumeSize <= 0) // pkzip span
|
||||
{
|
||||
if (!m_pZIPCALLBACKFUN)
|
||||
ThrowError(ZIP_NOCALLBACK);
|
||||
if (!CZipArchive::IsDriveRemovable(szPathName))
|
||||
ThrowError(ZIP_NONREMOVABLE);
|
||||
m_iSpanMode = pkzipSpan;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_iTdSpanData = iVolumeSize;
|
||||
m_iSpanMode = tdSpan;
|
||||
}
|
||||
|
||||
NextDisk(4, szPathName);
|
||||
Write(m_gszExtHeaderSignat, 4, true);
|
||||
}
|
||||
}
|
||||
else // open existing
|
||||
{
|
||||
OpenFile(szPathName, CFile::modeNoTruncate | ((iMode == CZipArchive::openReadOnly) ? CFile::modeRead : CFile::modeReadWrite));
|
||||
// m_uData, m_bAllowModif i m_iSpanMode ustalane automatycznie podczas odczytu central dir
|
||||
m_iSpanMode = iVolumeSize == 0 ? suggestedAuto : suggestedTd;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void CZipStorage::Open(CMemFile& mf, int iMode)
|
||||
{
|
||||
m_pWriteBuffer.Allocate(m_iWriteBufferSize);
|
||||
m_uBytesInWriteBuffer = 0;
|
||||
m_bNewSpan = false;
|
||||
m_pFile = &mf;
|
||||
|
||||
if (iMode == CZipArchive::create)
|
||||
{
|
||||
m_iCurrentDisk = 0;
|
||||
m_iSpanMode = noSpan;
|
||||
mf.SetLength(0);
|
||||
}
|
||||
else // open existing
|
||||
{
|
||||
mf.SeekToBegin();
|
||||
m_iSpanMode = suggestedAuto;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int CZipStorage::IsSpanMode()
|
||||
{
|
||||
return m_iSpanMode == noSpan ? 0 : (m_bNewSpan ? 1 : -1);
|
||||
}
|
||||
|
||||
void CZipStorage::ChangeDisk(int iNumber)
|
||||
{
|
||||
if (iNumber == m_iCurrentDisk)
|
||||
return;
|
||||
|
||||
ASSERT(m_iSpanMode != noSpan);
|
||||
m_iCurrentDisk = iNumber;
|
||||
OpenFile(m_iSpanMode == pkzipSpan ? ChangePkzipRead() : ChangeTdRead(),
|
||||
CFile::modeNoTruncate | CFile::modeRead);
|
||||
}
|
||||
|
||||
void CZipStorage::ThrowError(int err)
|
||||
{
|
||||
AfxThrowZipException(err, m_pFile->GetFilePath());
|
||||
}
|
||||
|
||||
bool CZipStorage::OpenFile(LPCTSTR lpszName, UINT uFlags, bool bThrow)
|
||||
{
|
||||
CFileException* e = new CFileException;
|
||||
BOOL bRet = m_pFile->Open(lpszName, uFlags | CFile::shareDenyWrite, e);
|
||||
if (!bRet && bThrow)
|
||||
throw e;
|
||||
e->Delete();
|
||||
return bRet != 0;
|
||||
}
|
||||
|
||||
// zapobiega konstrukcji ChangeDisk(++m_iCurrentDisk)
|
||||
void CZipStorage::SetCurrentDisk(int iNumber)
|
||||
{
|
||||
m_iCurrentDisk = iNumber;
|
||||
}
|
||||
|
||||
int CZipStorage::GetCurrentDisk()
|
||||
{
|
||||
return m_iCurrentDisk;
|
||||
}
|
||||
|
||||
CString CZipStorage::ChangePkzipRead()
|
||||
{
|
||||
CString szTemp = m_pFile->GetFilePath();
|
||||
m_pFile->Close();
|
||||
CallCallback(-1 , szTemp);
|
||||
return szTemp;
|
||||
}
|
||||
|
||||
CString CZipStorage::ChangeTdRead()
|
||||
{
|
||||
CString szTemp = GetTdVolumeName(m_iCurrentDisk == m_iTdSpanData);
|
||||
m_pFile->Close();
|
||||
return szTemp;
|
||||
}
|
||||
|
||||
void CZipStorage::Close(bool bAfterException)
|
||||
{
|
||||
if (!bAfterException)
|
||||
{
|
||||
Flush();
|
||||
if ((m_iSpanMode == tdSpan) && (m_bNewSpan))
|
||||
{
|
||||
// give to the last volume the zip extension
|
||||
CString szFileName = m_pFile->GetFilePath();
|
||||
CString szNewFileName = GetTdVolumeName(true);
|
||||
m_pFile->Close();
|
||||
if (CZipArchive::FileExists(szNewFileName))
|
||||
CFile::Remove(szNewFileName);
|
||||
CFile::Rename(szFileName, szNewFileName);
|
||||
}
|
||||
else
|
||||
#ifdef _DEBUG // to prevent assertion if the file is already closed
|
||||
if (m_pFile->m_hFile != (UINT)CFile::hFileNull)
|
||||
#endif
|
||||
m_pFile->Close();
|
||||
}
|
||||
else
|
||||
#ifdef _DEBUG // to prevent assertion if the file is already closed
|
||||
if (m_pFile->m_hFile != (UINT)CFile::hFileNull)
|
||||
#endif
|
||||
m_pFile->Close();
|
||||
|
||||
|
||||
m_pWriteBuffer.Release();
|
||||
m_iCurrentDisk = -1;
|
||||
m_iSpanMode = noSpan;
|
||||
m_pFile = NULL;
|
||||
}
|
||||
|
||||
CString CZipStorage::GetTdVolumeName(bool bLast, LPCTSTR lpszZipName)
|
||||
{
|
||||
CString szFilePath = lpszZipName ? lpszZipName : m_pFile->GetFilePath();
|
||||
CString szPath = CZipArchive::GetFilePath(szFilePath);
|
||||
CString szName = CZipArchive::GetFileTitle(szFilePath);
|
||||
CString szExt;
|
||||
if (bLast)
|
||||
szExt = _T("zip");
|
||||
else
|
||||
szExt.Format(_T("%.3d"), m_iCurrentDisk);
|
||||
return szPath + szName + _T(".") + szExt;
|
||||
}
|
||||
|
||||
void CZipStorage::NextDisk(int iNeeded, LPCTSTR lpszFileName)
|
||||
{
|
||||
Flush();
|
||||
ASSERT(m_iSpanMode != noSpan);
|
||||
if (m_iBytesWritten)
|
||||
{
|
||||
m_iBytesWritten = 0;
|
||||
m_iCurrentDisk++;
|
||||
if (m_iCurrentDisk >= 999)
|
||||
ThrowError(ZIP_TOOMANYVOLUMES);
|
||||
}
|
||||
CString szFileName;
|
||||
bool bPkSpan = (m_iSpanMode == pkzipSpan);
|
||||
if (bPkSpan)
|
||||
szFileName = lpszFileName ? lpszFileName : m_pFile->GetFilePath();
|
||||
else
|
||||
szFileName = GetTdVolumeName(false, lpszFileName);
|
||||
|
||||
#ifdef _DEBUG // to prevent assertion if the file is already closed
|
||||
if (m_pFile->m_hFile != (UINT)CFile::hFileNull)
|
||||
#endif
|
||||
m_pFile->Close(); // if it is closed, so it will not close
|
||||
|
||||
if (bPkSpan)
|
||||
{
|
||||
int iCode = iNeeded;
|
||||
while (true)
|
||||
{
|
||||
CallCallback(iCode, szFileName);
|
||||
if (CZipArchive::FileExists(szFileName))
|
||||
iCode = -2;
|
||||
else
|
||||
{
|
||||
CString label;
|
||||
label.Format(_T("pkback# %.3d"), m_iCurrentDisk + 1);
|
||||
if (!SetVolumeLabel(CZipArchive::GetDrive(szFileName), label)) /*not write label*/
|
||||
iCode = -3;
|
||||
else if (!OpenFile(szFileName, CFile::modeCreate | CFile::modeReadWrite, false))
|
||||
iCode = -4;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
m_uCurrentVolSize = GetFreeVolumeSpace();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_uCurrentVolSize = m_iTdSpanData;
|
||||
OpenFile(szFileName, CFile::modeCreate | CFile::modeReadWrite);
|
||||
}
|
||||
}
|
||||
|
||||
void CZipStorage::CallCallback(int iCode, CString szTemp)
|
||||
{
|
||||
ASSERT(m_pZIPCALLBACKFUN);
|
||||
if (!(*m_pZIPCALLBACKFUN)(m_iCurrentDisk + 1, iCode, m_pCallbackData))
|
||||
throw new CZipException(CZipException::aborted, szTemp);
|
||||
}
|
||||
|
||||
DWORD CZipStorage::GetFreeVolumeSpace()
|
||||
{
|
||||
ASSERT (m_iSpanMode == pkzipSpan);
|
||||
DWORD SectorsPerCluster, BytesPerSector, NumberOfFreeClusters, TotalNumberOfClusters;
|
||||
if (!GetDiskFreeSpace(
|
||||
CZipArchive::GetDrive(m_pFile->GetFilePath()),
|
||||
&SectorsPerCluster,
|
||||
&BytesPerSector,
|
||||
&NumberOfFreeClusters,
|
||||
&TotalNumberOfClusters))
|
||||
return 0;
|
||||
_int64 total = SectorsPerCluster * BytesPerSector * NumberOfFreeClusters;
|
||||
return (DWORD)total;
|
||||
}
|
||||
|
||||
|
||||
void CZipStorage::UpdateSpanMode(WORD uLastDisk)
|
||||
{
|
||||
m_iCurrentDisk = uLastDisk;
|
||||
if (uLastDisk)
|
||||
{
|
||||
// disk spanning detected
|
||||
|
||||
if (m_iSpanMode == suggestedAuto)
|
||||
m_iSpanMode = CZipArchive::IsDriveRemovable(m_pFile->GetFilePath()) ?
|
||||
pkzipSpan : tdSpan;
|
||||
else
|
||||
m_iSpanMode = tdSpan;
|
||||
|
||||
if (m_iSpanMode == pkzipSpan)
|
||||
{
|
||||
if (!m_pZIPCALLBACKFUN)
|
||||
ThrowError(ZIP_NOCALLBACK);
|
||||
}
|
||||
else /*if (m_iSpanMode == tdSpan)*/
|
||||
m_iTdSpanData = uLastDisk; // disk with .zip extension ( the last one)
|
||||
|
||||
m_pWriteBuffer.Release(); // no need for this in this case
|
||||
}
|
||||
else
|
||||
m_iSpanMode = noSpan;
|
||||
|
||||
}
|
||||
|
||||
void CZipStorage::Write(void *pBuf, DWORD iSize, bool bAtOnce)
|
||||
{
|
||||
if (!IsSpanMode())
|
||||
WriteInternalBuffer((char*)pBuf, iSize);
|
||||
else
|
||||
{
|
||||
// if not at once, one byte is enough free space
|
||||
DWORD iNeeded = bAtOnce ? iSize : 1;
|
||||
DWORD uTotal = 0;
|
||||
|
||||
while (uTotal < iSize)
|
||||
{
|
||||
DWORD uFree;
|
||||
while ((uFree = VolumeLeft()) < iNeeded)
|
||||
{
|
||||
if ((m_iSpanMode == tdSpan) && !m_iBytesWritten && !m_uBytesInWriteBuffer)
|
||||
// in the tdSpan mode, if the size of the archive is less
|
||||
// than the size of the packet to be written at once,
|
||||
// increase once the size of the volume
|
||||
m_uCurrentVolSize = iNeeded;
|
||||
else
|
||||
NextDisk(iNeeded);
|
||||
}
|
||||
|
||||
DWORD uLeftToWrite = iSize - uTotal;
|
||||
DWORD uToWrite = uFree < uLeftToWrite ? uFree : uLeftToWrite;
|
||||
WriteInternalBuffer((char*)pBuf + uTotal, uToWrite);
|
||||
if (bAtOnce)
|
||||
return;
|
||||
else
|
||||
uTotal += uToWrite;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CZipStorage::WriteInternalBuffer(char *pBuf, DWORD uSize)
|
||||
{
|
||||
DWORD uWritten = 0;
|
||||
while (uWritten < uSize)
|
||||
{
|
||||
DWORD uFreeInBuffer = GetFreeInBuffer();
|
||||
if (uFreeInBuffer == 0)
|
||||
{
|
||||
Flush();
|
||||
uFreeInBuffer = m_pWriteBuffer.GetSize();
|
||||
}
|
||||
DWORD uLeftToWrite = uSize - uWritten;
|
||||
DWORD uToCopy = uLeftToWrite < uFreeInBuffer ? uLeftToWrite : uFreeInBuffer;
|
||||
memcpy(m_pWriteBuffer + m_uBytesInWriteBuffer, pBuf + uWritten, uToCopy);
|
||||
uWritten += uToCopy;
|
||||
m_uBytesInWriteBuffer += uToCopy;
|
||||
}
|
||||
}
|
||||
|
||||
DWORD CZipStorage::VolumeLeft()
|
||||
{
|
||||
// for pkzip span m_uCurrentVolSize is updated after each flush()
|
||||
return m_uCurrentVolSize - m_uBytesInWriteBuffer - ((m_iSpanMode == pkzipSpan) ? 0 : m_iBytesWritten);
|
||||
}
|
||||
|
||||
void CZipStorage::Flush()
|
||||
{
|
||||
m_iBytesWritten += m_uBytesInWriteBuffer;
|
||||
if (m_uBytesInWriteBuffer)
|
||||
{
|
||||
m_pFile->Write(m_pWriteBuffer, m_uBytesInWriteBuffer);
|
||||
m_uBytesInWriteBuffer = 0;
|
||||
}
|
||||
if (m_iSpanMode == pkzipSpan)
|
||||
// after writting it is difficult to predict the free space due to
|
||||
// not completly written clusters, write operation may start from
|
||||
// the new cluster
|
||||
m_uCurrentVolSize = GetFreeVolumeSpace();
|
||||
}
|
||||
|
||||
DWORD CZipStorage::GetPosition()
|
||||
{
|
||||
return m_pFile->GetPosition() + m_uBytesInWriteBuffer;
|
||||
}
|
||||
|
||||
|
||||
DWORD CZipStorage::GetFreeInBuffer()
|
||||
{
|
||||
return m_pWriteBuffer.GetSize() - m_uBytesInWriteBuffer;
|
||||
}
|
|
@ -0,0 +1,134 @@
|
|||
// ZipStorage.h: interface for the CZipStorage class.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2000 Tadeusz Dracz.
|
||||
// For conditions of distribution and use, see copyright notice in ZipArchive.h
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if !defined(AFX_ZIPSTORAGE_H__941824FE_3320_4794_BDE3_BE334ED8984B__INCLUDED_)
|
||||
#define AFX_ZIPSTORAGE_H__941824FE_3320_4794_BDE3_BE334ED8984B__INCLUDED_
|
||||
|
||||
#include "ZipBigFile.h" // Added by ClassView
|
||||
#include "ZipAutoBuffer.h" // Added by ClassView
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
|
||||
// callback function called when there is a need for a disk change
|
||||
// calling CZipArchive functions, apart from the static ones, may have unexpected results
|
||||
// iNumber - disk number needed
|
||||
// iCode :
|
||||
// -1 - disk needed for reading
|
||||
// other codes occurs during writting
|
||||
// >=0 : number of bytes needed
|
||||
// -2 - the file with the archive name already exists on the disk
|
||||
// -3 - the disk is probably write - protected
|
||||
// -4 - couldn't create a file
|
||||
// pData - user defined data
|
||||
// return false to abort operation: the proper exception will be thrown
|
||||
typedef bool (*ZIPCALLBACKFUN )(int iNumber, int iCode, void* pData);
|
||||
|
||||
class CZipStorage
|
||||
{
|
||||
public:
|
||||
void Open(CMemFile& mf, int iMode);
|
||||
// return the position in the file, taking into account the bytes in the write buffer
|
||||
DWORD GetPosition();
|
||||
|
||||
// flush the data from the read buffer to the disk
|
||||
void Flush();
|
||||
|
||||
// only called by CZipCentralDir when opening an existing archive
|
||||
void UpdateSpanMode(WORD uLastDisk);
|
||||
// the preset size of the write buffer
|
||||
int m_iWriteBufferSize;
|
||||
|
||||
// user data to be passed to the callback function
|
||||
void* m_pCallbackData;
|
||||
|
||||
// function used to change disks during writing to the disk spanning archive
|
||||
void NextDisk(int iNeeded, LPCTSTR lpszFileName = NULL);
|
||||
|
||||
void Close(bool bAfterException);
|
||||
|
||||
// return the numer of the current disk
|
||||
int GetCurrentDisk();
|
||||
|
||||
void SetCurrentDisk(int iNumber);
|
||||
|
||||
// change the disk during extract operations
|
||||
void ChangeDisk(int iNumber);
|
||||
|
||||
// Function name : IsSpanMode
|
||||
// Description : detect span mode
|
||||
// Return type : int
|
||||
// -1 - existing span opened
|
||||
// 0 - no span
|
||||
// 1 - new span
|
||||
int IsSpanMode();
|
||||
|
||||
void Open(LPCTSTR szPathName, int iMode, int iVolumeSize);
|
||||
void Write(void *pBuf, DWORD iSize, bool bAtOnce);
|
||||
DWORD Read(void* pBuf, DWORD iSize, bool bAtOnce);
|
||||
CZipBigFile m_internalfile;
|
||||
CFile* m_pFile;
|
||||
CZipStorage();
|
||||
virtual ~CZipStorage();
|
||||
enum {noSpan, pkzipSpan, tdSpan, suggestedAuto, suggestedTd};
|
||||
int m_iSpanMode;
|
||||
ZIPCALLBACKFUN m_pZIPCALLBACKFUN;
|
||||
static char m_gszExtHeaderSignat[];
|
||||
|
||||
// open tdspan: last disk number, create tdspan: volume size
|
||||
// create pkspan: not used
|
||||
int m_iTdSpanData;
|
||||
|
||||
protected:
|
||||
// how many bytes left free in the write buffer
|
||||
DWORD GetFreeInBuffer();
|
||||
friend class CZipCentralDir;
|
||||
// numer of bytes available in the write buffer
|
||||
DWORD m_uBytesInWriteBuffer;
|
||||
|
||||
// tdSpan : the total size of the current volume, pkSpan : free space on the current volume
|
||||
DWORD m_uCurrentVolSize;
|
||||
|
||||
// return the number of bytes left on the current volume
|
||||
DWORD VolumeLeft();
|
||||
|
||||
// write data to the internal buffer
|
||||
void WriteInternalBuffer(char *pBuf, DWORD uSize);
|
||||
|
||||
// number of bytes left free in the write buffer
|
||||
DWORD m_uVolumeFreeInBuffer;
|
||||
|
||||
CZipAutoBuffer m_pWriteBuffer;
|
||||
|
||||
// return the number of free bytes on the current removable disk
|
||||
DWORD GetFreeVolumeSpace();
|
||||
|
||||
void CallCallback(int iCode, CString szTemp);
|
||||
|
||||
// only disk spanning creation: tells how many bytes have been written physically to the current volume
|
||||
DWORD m_iBytesWritten;
|
||||
|
||||
// construct the name of the volume in tdSpan mode
|
||||
CString GetTdVolumeName(bool bLast, LPCTSTR lpszZipName = NULL);
|
||||
|
||||
// change the disk in tdSpan mode
|
||||
CString ChangeTdRead();
|
||||
|
||||
// change the disk in pkSpan mode
|
||||
CString ChangePkzipRead();
|
||||
|
||||
// you can only add a new files to the new disk spanning archive and only extract
|
||||
// them from the existing one
|
||||
bool m_bNewSpan;
|
||||
|
||||
int m_iCurrentDisk;
|
||||
bool OpenFile(LPCTSTR lpszName, UINT uFlags, bool bThrow = true);
|
||||
void ThrowError(int err);
|
||||
|
||||
};
|
||||
|
||||
#endif // !defined(AFX_ZIPSTORAGE_H__941824FE_3320_4794_BDE3_BE334ED8984B__INCLUDED_)
|
|
@ -0,0 +1,458 @@
|
|||
|
||||
|
||||
// Registry constant paths
|
||||
// These will be used when the Win32 Registry Keys are written
|
||||
|
||||
var HKEY_LOCAL_MACHINE = "HKEY_LOCAL_MACHINE";
|
||||
var HKEY_CURRENT_USER = "HKEY_CURRENT_USER";
|
||||
var REG_MOZ_PATH = "SOFTWARE\\MozillaPlugins";
|
||||
|
||||
|
||||
// My Own Error Code in case secondary installation fails
|
||||
var noSecondaryInstall = 1;
|
||||
|
||||
|
||||
// error return codes need some memory
|
||||
var err;
|
||||
|
||||
// error return codes when we try and install to the current browser
|
||||
|
||||
var errBlock1;
|
||||
|
||||
// error return codes when we try and do a secondary installation
|
||||
|
||||
var errBlock2 = 0;
|
||||
|
||||
// global variable containing our secondary install location
|
||||
|
||||
var secondaryFolder;
|
||||
|
||||
//Special error values used by the Cycore developers (www.cycore.com) who helped make this install script
|
||||
|
||||
var exceptionOccuredError = -4711;
|
||||
var winRegIsNullError = -4712;
|
||||
var invalidRootkeyError = -4713;
|
||||
var registrykeyNotWritableError = -4714;
|
||||
|
||||
|
||||
//initInstall block
|
||||
//the installation is initialized here -- if we fail here, cancel the installation
|
||||
|
||||
// initInstall is quite an overloaded method, but I have invoked it here with three strings
|
||||
// which are globally defined
|
||||
|
||||
err = initInstall(SOFTWARE_NAME, PLID, VERSION);
|
||||
|
||||
if (err != 0)
|
||||
{
|
||||
logComment("Install failed at initInstall level with " + err);
|
||||
cancelInstall(err);
|
||||
}
|
||||
|
||||
//addFiles to current browser block
|
||||
|
||||
var pluginsFolder = getFolder("Plugins");
|
||||
|
||||
//Verify Disk Space
|
||||
|
||||
if(verifyDiskSpace(pluginsFolder, PLUGIN_SIZE+COMPONENT_SIZE))
|
||||
{
|
||||
// start installing plugin shared library
|
||||
resetError();
|
||||
|
||||
// install the plugin shared library to the current browser's Plugin directory
|
||||
|
||||
errBlock1 = addFile (PLID, VERSION, PLUGIN_FILE, pluginsFolder, null);
|
||||
if (errBlock1!=0)
|
||||
{
|
||||
logComment("Could NOT add " + PLUGIN_FILE + " to " + pluginsFolder + ":" + errBlock1);
|
||||
cancelInstall(errBlock1);
|
||||
}
|
||||
|
||||
// start installing xpt file if this is a scriptable plugin
|
||||
// install to the plugins directory -- this works well in Mozilla 1.0 clients
|
||||
// in Mozilla 1.0 clients, the Components directory can be avoided for XPT files
|
||||
|
||||
errBlock1 = addFile (PLID, VERSION, COMPONENT_FILE, pluginsFolder, null);
|
||||
if (errBlock1!=0)
|
||||
{
|
||||
logComment("Could NOT add " + COMPONENT_FILE + " to " + pluginsFolder + ":" + errBlock1);
|
||||
cancelInstall(errBlock1);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
logComment("Cancelling current browser install due to lack of space...");
|
||||
cancellInstall();
|
||||
}
|
||||
|
||||
|
||||
// Secondary install block, which sets up plugins and xpt in another location in addition to the current browser
|
||||
|
||||
errBlock2 = createSecondaryInstall();
|
||||
|
||||
|
||||
// performInstall block, in which error conditions from previous blocks are checked.
|
||||
// This block also invokes a function to write registry keys (PLID) and checks return from key writing
|
||||
// This block invokes refreshPlugins() to ensure that plugin and xpt are available for use immediately
|
||||
|
||||
if (errBlock1 == SUCCESS)
|
||||
{
|
||||
|
||||
// installation to the current browser was a success - this is the most important job of this script!
|
||||
|
||||
if(errBlock2 == SUCCESS)
|
||||
{
|
||||
// Now take care of writing PLIDs to the Win32 Registry
|
||||
|
||||
err = writePLIDSolution();
|
||||
if(err!=SUCCESS)
|
||||
{
|
||||
logComment("Could NOT write Win32 Keys as specified: " + err);
|
||||
}
|
||||
else
|
||||
{
|
||||
logComment("PLID entries are present in the Win32 Registry");
|
||||
}
|
||||
}
|
||||
|
||||
resetError();
|
||||
err = performInstall();
|
||||
if (err == SUCCESS)
|
||||
refreshPlugins(true);
|
||||
|
||||
// call refreshPlugins(true) if you'd like the web page which invoked the plugin to
|
||||
// reload. You can also simply call refreshPlugins()
|
||||
}
|
||||
|
||||
else
|
||||
cancelInstall(errBlock1);
|
||||
|
||||
// PLID solution -- write keys to the registry
|
||||
|
||||
/**
|
||||
* Function for secondary installation of plugin (FirstInstall).
|
||||
* You should not stop the install process because the function failed,
|
||||
* you still have a chance to install the plugin for the already
|
||||
* installed gecko browsers.
|
||||
*
|
||||
* @param empty param list
|
||||
**/
|
||||
|
||||
function createSecondaryInstall()
|
||||
{
|
||||
// Use getFolder in such a way that it creates C:\WINNT\System32\MyPlugin
|
||||
|
||||
secondaryFolder = getFolder("Win System", COMPANY_NAME);
|
||||
|
||||
// if secondaryFolder is NULL, then there has been an error
|
||||
|
||||
if(!secondaryFolder)
|
||||
return noSecondaryInstall;
|
||||
else
|
||||
{
|
||||
// we have admin privileges to write to the Win System directory
|
||||
// so we will set up DLL and XPT in their new home
|
||||
errBlock2 = addFile (PLID, VERSION, PLUGIN_FILE, secondaryFolder, null);
|
||||
|
||||
// Something went wrong if errBlock2 is NOT 0
|
||||
|
||||
if (errBlock2!=0)
|
||||
{
|
||||
logComment("Could NOT add " + PLUGIN_FILE + " to " + secondaryFolder + ":" + errBlock2);
|
||||
return errBlock2;
|
||||
}
|
||||
|
||||
// start installing xpt file if this is a scriptable plugin
|
||||
errBlock2 = addFile (PLID, VERSION, COMPONENT_FILE, secondaryFolder, null);
|
||||
if (errBlock2!=0)
|
||||
{
|
||||
logComment("Could NOT add " + COMPONENT_FILE + " to " + secondaryFolder + ":" + errBlock2);
|
||||
return errBlock2;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
return 0; // 0 means everything went well with the secondary install
|
||||
}
|
||||
|
||||
function writePLIDSolution()
|
||||
{
|
||||
|
||||
//Concatenate the secondary install path with the filename to make a fully qualified pathname
|
||||
|
||||
var qualifiedSecondaryFolderDLL = secondaryFolder + PLUGIN_FILE;
|
||||
var qualifiedSecondaryFolderXPT = secondaryFolder + COMPONENT_FILE;
|
||||
|
||||
// write PLID keys (mozilla.org/projects/plugins/first-install-problem.html)
|
||||
// write PLID keys to HKLM
|
||||
|
||||
var HKLM_status = registerPLID(HKEY_LOCAL_MACHINE, REG_MOZ_PATH,
|
||||
PLID,
|
||||
qualifiedSecondaryFolderDLL, qualifiedSecondaryFolderXPT,
|
||||
PLUGIN_DESCRIPTION, COMPANY_NAME, SOFTWARE_NAME, VERSION,
|
||||
MIMETYPE, SUFFIX, SUFFIX_DESCRIPTION);
|
||||
|
||||
logComment("Moz First Install Installation: registerPLID("+HKEY_LOCAL_MACHINE+") returned, status "+HKLM_status);
|
||||
|
||||
if (HKLM_status == false)
|
||||
{
|
||||
// write PLID keys (mozilla.org/projects/plugins/first-install-problem.html)
|
||||
// write PLID keys to HKCU
|
||||
|
||||
var HKCU_status = registerPLID(HKEY_CURRENT_USER, REG_MOZ_PATH,
|
||||
PLID,
|
||||
qualifiedSecondaryFolderDLL, qualifiedSecondaryFolderXPT,
|
||||
PLUGIN_DESCRIPTION, COMPANY_NAME, SOFTWARE_NAME, VERSION,
|
||||
MIMETYPE, SUFFIX, SUFFIX_DESCRIPTION);
|
||||
|
||||
|
||||
logComment("First Install Installation: registerPLID("+HKEY_CURRENT_USER+") returned, status "+HKLM_status);
|
||||
|
||||
if (HKCU_status != 0)
|
||||
{
|
||||
logComment("Could not write to the registry. Errorcode="+HKCU_status);
|
||||
|
||||
return HKCU_status;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
|
||||
}
|
||||
/**
|
||||
* Function for preinstallation of plugin (FirstInstall).
|
||||
* You should not stop the install process because the function failed,
|
||||
* you still have a chance to install the plugin for the already
|
||||
* installed gecko browsers.
|
||||
*
|
||||
* @param dirPath directory path from getFolder
|
||||
* @param spaceRequired required space in kilobytes
|
||||
*
|
||||
**/
|
||||
|
||||
function verifyDiskSpace(dirPath, spaceRequired)
|
||||
{
|
||||
var spaceAvailable;
|
||||
|
||||
// Get the available disk space on the given path
|
||||
spaceAvailable = fileGetDiskSpaceAvailable(dirPath);
|
||||
|
||||
// Convert the available disk space into kilobytes
|
||||
spaceAvailable = parseInt(spaceAvailable / 1024);
|
||||
|
||||
// do the verification
|
||||
if(spaceAvailable < spaceRequired)
|
||||
{
|
||||
logComment("Insufficient disk space: " + dirPath);
|
||||
logComment(" required : " + spaceRequired + " K");
|
||||
logComment(" available: " + spaceAvailable + " K");
|
||||
return(false);
|
||||
}
|
||||
|
||||
return(true);
|
||||
}
|
||||
/**
|
||||
* Function for writing keys to the Win32 System Registry.
|
||||
* You should not stop the install process because the function failed.
|
||||
* You still have a chance to install the plugin for the
|
||||
* current Gecko browser.
|
||||
*
|
||||
* @param rootKey must be one of these two string values HKEY_LOCAL_MACHINE or HKEY_CURRENT_USER
|
||||
* @param plidID PLID for Plugins
|
||||
* @param dllAbsolutePath the fully qualified path to the DLL
|
||||
* @param xptAbsolutePath the fully qualified path to the XPT
|
||||
* @param pluginDescription a String describing the plugin
|
||||
* @param vendor a String describing the vendor
|
||||
* @param productName the name of this software
|
||||
* @param pluginVersion version string of the plugin
|
||||
* @param mimeType[] MIME type handled by the plugin
|
||||
Plugins with more than one MIME type
|
||||
might use an array
|
||||
* @param suffix[] Suffix handled by plugin (e.g. .my files)
|
||||
* @param suffixDescription[] String describing suffix -- each description matches the corresponding suffix
|
||||
**/
|
||||
function registerPLID(rootKey, plidPath,
|
||||
plidID,
|
||||
dllAbsolutePath, xptAbsolutePath,
|
||||
pluginDescription, vendor, productName, pluginVersion,
|
||||
mimeType, suffix, suffixDescription)
|
||||
{
|
||||
var myRegStatus = 0;
|
||||
var coMimetypePath;
|
||||
|
||||
winreg = getWinRegistry();
|
||||
|
||||
if (winreg == null)
|
||||
{
|
||||
logComment("Moz registerPLID: winreg == null");
|
||||
return winregIsNullError;
|
||||
}
|
||||
|
||||
// Which root to start from HKLM, HKCU
|
||||
if (rootKey == HKEY_LOCAL_MACHINE)
|
||||
{
|
||||
logComment("Moz registerPLID: rootKey=="+HKEY_LOCAL_MACHINE);
|
||||
winreg.setRootKey(winreg.HKEY_LOCAL_MACHINE);
|
||||
}
|
||||
else if (rootKey == HKEY_CURRENT_USER)
|
||||
{
|
||||
logComment("Moz registerPLID: rootKey=="+HKEY_CURRENT_USER);
|
||||
winreg.setRootKey(winreg.HKEY_CURRENT_USER);
|
||||
}
|
||||
else
|
||||
{
|
||||
logComment("Moz registerPlid: invalid rootkey, "+rootKey);
|
||||
return invalidRootkeyError;
|
||||
}
|
||||
|
||||
if (!winreg.isKeyWritable(plidPath))
|
||||
{
|
||||
logComment("Moz registerPLID: registry key not writable");
|
||||
return registryKeyNotWritableError;
|
||||
}
|
||||
|
||||
// If we can't find the plidPath create the key
|
||||
if (!winreg.keyExists(plidPath))
|
||||
{
|
||||
logComment("Moz registerPLID: creating missing key "+plidPath+".");
|
||||
myRegStatus = winreg.createKey(plidPath, "");
|
||||
if (myRegStatus != 0)
|
||||
{
|
||||
logComment("Moz registerPLID: Could not create the key, "+plidPath+"as expected. Errorcode="+myRegStatus);
|
||||
return myRegStatus;
|
||||
}
|
||||
}
|
||||
|
||||
// OK were done, let's write info about our plugin, path, productname, etc
|
||||
|
||||
|
||||
|
||||
myMozillaPluginPath = plidPath+"\\"+plidID; // For instance. SOFTWARE\MozillaPlugins\@Cycore.com/Cult3DViewer
|
||||
myRegStatus = winreg.createKey(plidPath+"\\"+plidID, "");
|
||||
if (myRegStatus != 0)
|
||||
{
|
||||
logComment("Moz registerPLID: could not create the subkey "+plidID+" to "+plidPath+". Errorcode="+myRegStatus);
|
||||
return myRegStatus;
|
||||
}
|
||||
|
||||
|
||||
// Write path to DLL
|
||||
myRegStatus = winreg.setValueString(myMozillaPluginPath, "Path", dllAbsolutePath);
|
||||
if (myRegStatus != 0)
|
||||
{
|
||||
logComment("Moz registerPLID: Could not write the DLL path value. RegPath="+myMozillaPluginPath+", DLLPath="+dllAbsolutePath+". ErrorCode="+myRegStatus);
|
||||
return myRegStatus;
|
||||
}
|
||||
|
||||
// Write XPTPath
|
||||
myRegStatus = winreg.setValueString(myMozillaPluginPath, "XPTPath", xptAbsolutePath);
|
||||
if (myRegStatus != 0)
|
||||
{
|
||||
logComment("Moz registerPLID: Could not write the XPT path value. RegPath="+myMozillaPluginPath+"XPTPath="+xptAbsolutePath+", as expected. Errorcode="+myRegStatus);
|
||||
return myRegStatus;
|
||||
}
|
||||
|
||||
// Write the productName
|
||||
myRegStatus = winreg.setValueString(myMozillaPluginPath, "ProductName", productName);
|
||||
if (myRegStatus != 0)
|
||||
{
|
||||
logComment("Moz registerPLID: Could not write productName. RegPath="+myMozillaPluginPath+", productName="+productName+", as expected. Errorcode="+myRegStatus);
|
||||
return myRegStatus;
|
||||
}
|
||||
|
||||
// Write the vendor
|
||||
myRegStatus = winreg.setValueString(myMozillaPluginPath, "Vendor", vendor);
|
||||
if (myRegStatus != 0)
|
||||
{
|
||||
logComment("Moz registerPLID: Could not write vendorName. RegPath="+myMozillaPluginPath+", vendorName="+vendor+", as expected. Errorcode="+myRegStatus);
|
||||
return myRegStatus;
|
||||
}
|
||||
|
||||
// Write the plugin description
|
||||
myRegStatus = winreg.setValueString(myMozillaPluginPath, "Description", pluginDescription);
|
||||
if (myRegStatus != 0)
|
||||
{
|
||||
logComment("Moz registerPLID: Could not write plugin description. RegPath="+myMozillaPluginPath+", description="+pluginDescription+", as expected. Errorcode="+myRegStatus);
|
||||
return myRegStatus;
|
||||
}
|
||||
|
||||
// Write the version number of the plug-in
|
||||
myRegStatus = winreg.setValueString(myMozillaPluginPath, "Version", pluginVersion);
|
||||
if (myRegStatus != 0)
|
||||
{
|
||||
logComment("Moz registerPLID: Could not write plugin version. RegPath="+myMozillaPluginPath+", pluginVersion="+pluginVersion+", as expected. Errorcode="+myRegStatus);
|
||||
return myRegStatus;
|
||||
}
|
||||
|
||||
/////////////////////////////////
|
||||
// Write the subkey MimeTypes //
|
||||
///////////////////////////////
|
||||
var myMimetypePath = myMozillaPluginPath+"\\MimeTypes";
|
||||
myRegStatus = winreg.createKey(myMimetypePath, "");
|
||||
if (myRegStatus != 0)
|
||||
{
|
||||
logComment("Moz registerPLID: Could not create the subkey MimeTypes, "+myMimetypePath+" as expected. Errorcode="+myRegStatus);
|
||||
return myRegStatus;
|
||||
}
|
||||
|
||||
//Write as many MIME types under the mimetypes key as you have...
|
||||
|
||||
for(i=0; i<mimeType.length; i++)
|
||||
{
|
||||
coMimetypePath = myMimetypePath+"\\"+mimeType[i];
|
||||
myRegStatus = winreg.createKey(coMimetypePath, "");
|
||||
if (myRegStatus != 0)
|
||||
{
|
||||
logComment("Moz registerPLID: Could not create the subkey "+coMimetypePath+", as expected. Errorcode="+myRegStatus);
|
||||
return myRegStatus;
|
||||
}
|
||||
|
||||
// Write the description of the co mimetype
|
||||
myRegStatus = winreg.setValueString(coMimetypePath, "Description", suffixDescription[i]);
|
||||
if (myRegStatus != 0)
|
||||
{
|
||||
logComment("Moz registerPLID: Could not create the suffix description value, "+suffixDescription[i]+", as expected. Errorcode="+myRegStatus);
|
||||
return myRegStatus;
|
||||
}
|
||||
|
||||
|
||||
myRegStatus = winreg.setValueString(coMimetypePath, "Suffixes", suffix[i])
|
||||
if (myRegStatus != 0)
|
||||
{
|
||||
logComment("Moz registerPLID: Could not create the suffixes value, "+suffix[i]+", as expected. Errorcode="+myRegStatus);
|
||||
return myRegStatus;
|
||||
}
|
||||
}
|
||||
/////////////////////////////////
|
||||
// Write the subkey Suffixes //
|
||||
///////////////////////////////
|
||||
|
||||
var suffixPath = myMozillaPluginPath+"\\Suffixes";
|
||||
|
||||
// Write the suffix of the mimetype
|
||||
myRegStatus = winreg.createKey(suffixPath, "");
|
||||
if (myRegStatus != 0)
|
||||
{
|
||||
logComment("Moz registerPLID: Could not create the suffix key, "+suffixPath+", as expected. ErrorCode="+myRegStatus);
|
||||
return myRegStatus;
|
||||
}
|
||||
|
||||
for(i=0; i<suffix.length; i++)
|
||||
{
|
||||
// Write the suffix (extension), (one value-key with no value)
|
||||
myRegStatus = winreg.setValueString(suffixPath, suffix[i], "\0");
|
||||
if (myRegStatus != 0)
|
||||
{
|
||||
logComment("Moz registerPLID: Could not create the suffix value. RegPath="+suffixPath+", value="+suffix+", as expected. Errorcode="+myRegStatus);
|
||||
return myRegStatus;
|
||||
}
|
||||
}
|
||||
|
||||
logComment("Moz registerPLID: Registry keys seems to be written successfully");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
var PLUGIN_FILE = [%s];
|
||||
var PLUGIN_FILE_PLID = [%s];
|
||||
|
||||
var COMPONENT_FILE = [%s];
|
||||
var COMPONENT_FILE_PLID = [%s];
|
||||
|
||||
// (DLL files)
|
||||
var PLUGIN_SIZE = %d;
|
||||
|
||||
// (XPI files)
|
||||
var COMPONENT_SIZE = %d;
|
||||
|
||||
var SOFTWARE_NAME = "%s";
|
||||
|
||||
var PLID = "%s";
|
||||
|
||||
var VERSION = "%s";
|
||||
|
||||
var MIMETYPE = [%s];
|
||||
var SUFFIX = [%s];
|
||||
var SUFFIX_DESCRIPTION = [%s];
|
||||
var COMPANY_NAME = "%s";
|
||||
var PLUGIN_DESCRIPTION = "%s";
|
|
@ -0,0 +1,22 @@
|
|||
/**
|
||||
|
||||
Doron Rosenberg -- doronAtNoSpamAllowedHerenetscape.com
|
||||
Arun K. Ranganathan -- arunerAtNoSpamAllowedHerenetscape.com
|
||||
Petter Ericson -- petterAtNoSpamAllowedHerecycore.com
|
||||
Anthony Davis -- anthonydAtNoSpamAllowedHerenetscape.com
|
||||
|
||||
This is an install.js file that does the following --
|
||||
|
||||
1. Installs to the current browser that is invoking the installation
|
||||
2. Additionally installs to a secondary location on the Windows desktop,
|
||||
in this case C:\WINNT\System32\MyPlugin\
|
||||
3. Writes registry keys exposing the above secondary install location for
|
||||
other browsers to find. The keys are written according to the specification:
|
||||
http://mozilla.org/projects/plugins/first-install-problem.html and follows the
|
||||
PLID specification: http://mozilla.org/projects/plugins/plugin-identifier.html
|
||||
|
||||
**/
|
||||
|
||||
// Define some global variables
|
||||
|
||||
|
|
@ -0,0 +1,505 @@
|
|||
/**
|
||||
|
||||
Doron Rosenberg -- doronAtNoSpamAllowedHerenetscape.com
|
||||
Arun K. Ranganathan -- arunerAtNoSpamAllowedHerenetscape.com
|
||||
Petter Ericson -- petterAtNoSpamAllowedHerecycore.com
|
||||
Anthony Davis -- anthonydAtNoSpamAllowedHerenetscape.com
|
||||
|
||||
This is an install.js file that does the following --
|
||||
|
||||
1. Installs to the current browser that is invoking the installation
|
||||
2. Additionally installs to a secondary location on the Windows desktop,
|
||||
in this case C:\WINNT\System32\MyPlugin\
|
||||
3. Writes registry keys exposing the above secondary install location for
|
||||
other browsers to find. The keys are written according to the specification:
|
||||
http://mozilla.org/projects/plugins/first-install-problem.html and follows the
|
||||
PLID specification: http://mozilla.org/projects/plugins/plugin-identifier.html
|
||||
|
||||
**/
|
||||
|
||||
// Define some global variables
|
||||
|
||||
|
||||
var PLUGIN_FILE = "NPSWF32.dll";
|
||||
|
||||
// This plugin consists of an XPT file because it is scriptable
|
||||
// http://mozilla.org/projects/plugins/scripting-plugins.html
|
||||
var COMPONENT_FILE = "flashplayer.xpt";
|
||||
|
||||
// (DLL file) Reserve a little extra so it is not required to update too often
|
||||
var PLUGIN_SIZE = 704512;
|
||||
|
||||
// (XPI file) Reserve a little extra so it is not required to update too often
|
||||
var COMPONENT_SIZE = 856;
|
||||
|
||||
var SOFTWARE_NAME="Flash Player";
|
||||
|
||||
|
||||
// PLIDs (http://mozilla.org/projects/plugins/plugin-identifier.html) are coined by vendors.
|
||||
var PLID = "@macromedia.com/Flash Player,version=6r47";
|
||||
|
||||
var VERSION = "6r47";
|
||||
|
||||
var MIMETYPE = ["application/x-shockwave-flash", "application/futuresplash"];
|
||||
var SUFFIX = ["swf", "spl"];
|
||||
var SUFFIX_DESCRIPTION = ["Macromedia Flash Movie", "FutureSplash Movie"];
|
||||
var COMPANY_NAME = "Macromedia";
|
||||
var PLUGIN_DESCRIPTION = "Shockwave Flash 6.0 r47";
|
||||
|
||||
|
||||
// Registry constant paths
|
||||
// These will be used when the Win32 Registry Keys are written
|
||||
|
||||
var HKEY_LOCAL_MACHINE = "HKEY_LOCAL_MACHINE";
|
||||
var HKEY_CURRENT_USER = "HKEY_CURRENT_USER";
|
||||
var REG_MOZ_PATH = "SOFTWARE\\MozillaPlugins";
|
||||
|
||||
|
||||
// My Own Error Code in case secondary installation fails
|
||||
var noSecondaryInstall = 1;
|
||||
|
||||
|
||||
// error return codes need some memory
|
||||
var err;
|
||||
|
||||
// error return codes when we try and install to the current browser
|
||||
|
||||
var errBlock1;
|
||||
|
||||
// error return codes when we try and do a secondary installation
|
||||
|
||||
var errBlock2 = 0;
|
||||
|
||||
// global variable containing our secondary install location
|
||||
|
||||
var secondaryFolder;
|
||||
|
||||
//Special error values used by the Cycore developers (www.cycore.com) who helped make this install script
|
||||
|
||||
var exceptionOccuredError = -4711;
|
||||
var winRegIsNullError = -4712;
|
||||
var invalidRootkeyError = -4713;
|
||||
var registrykeyNotWritableError = -4714;
|
||||
|
||||
|
||||
//initInstall block
|
||||
//the installation is initialized here -- if we fail here, cancel the installation
|
||||
|
||||
// initInstall is quite an overloaded method, but I have invoked it here with three strings
|
||||
// which are globally defined
|
||||
|
||||
err = initInstall(SOFTWARE_NAME, PLID, VERSION);
|
||||
|
||||
if (err != 0)
|
||||
{
|
||||
logComment("Install failed at initInstall level with " + err);
|
||||
cancelInstall(err);
|
||||
}
|
||||
|
||||
//addFiles to current browser block
|
||||
|
||||
var pluginsFolder = getFolder("Plugins");
|
||||
|
||||
//Verify Disk Space
|
||||
|
||||
if(verifyDiskSpace(pluginsFolder, PLUGIN_SIZE+COMPONENT_SIZE))
|
||||
{
|
||||
// start installing plugin shared library
|
||||
resetError();
|
||||
|
||||
// install the plugin shared library to the current browser's Plugin directory
|
||||
|
||||
errBlock1 = addFile (PLID, VERSION, PLUGIN_FILE, pluginsFolder, null);
|
||||
if (errBlock1!=0)
|
||||
{
|
||||
logComment("Could NOT add " + PLUGIN_FILE + " to " + pluginsFolder + ":" + errBlock1);
|
||||
cancelInstall(errBlock1);
|
||||
}
|
||||
|
||||
// start installing xpt file if this is a scriptable plugin
|
||||
// install to the plugins directory -- this works well in Mozilla 1.0 clients
|
||||
// in Mozilla 1.0 clients, the Components directory can be avoided for XPT files
|
||||
|
||||
errBlock1 = addFile (PLID, VERSION, COMPONENT_FILE, pluginsFolder, null);
|
||||
if (errBlock1!=0)
|
||||
{
|
||||
logComment("Could NOT add " + COMPONENT_FILE + " to " + pluginsFolder + ":" + errBlock1);
|
||||
cancelInstall(errBlock1);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
logComment("Cancelling current browser install due to lack of space...");
|
||||
cancellInstall();
|
||||
}
|
||||
|
||||
|
||||
// Secondary install block, which sets up plugins and xpt in another location in addition to the current browser
|
||||
|
||||
errBlock2 = createSecondaryInstall();
|
||||
|
||||
|
||||
// performInstall block, in which error conditions from previous blocks are checked.
|
||||
// This block also invokes a function to write registry keys (PLID) and checks return from key writing
|
||||
// This block invokes refreshPlugins() to ensure that plugin and xpt are available for use immediately
|
||||
|
||||
if (errBlock1 == SUCCESS)
|
||||
{
|
||||
|
||||
// installation to the current browser was a success - this is the most important job of this script!
|
||||
|
||||
if(errBlock2 == SUCCESS)
|
||||
{
|
||||
// Now take care of writing PLIDs to the Win32 Registry
|
||||
|
||||
err = writePLIDSolution();
|
||||
if(err!=SUCCESS)
|
||||
{
|
||||
logComment("Could NOT write Win32 Keys as specified: " + err);
|
||||
}
|
||||
else
|
||||
{
|
||||
logComment("PLID entries are present in the Win32 Registry");
|
||||
}
|
||||
}
|
||||
|
||||
resetError();
|
||||
err = performInstall();
|
||||
if (err == SUCCESS)
|
||||
refreshPlugins(true);
|
||||
|
||||
// call refreshPlugins(true) if you'd like the web page which invoked the plugin to
|
||||
// reload. You can also simply call refreshPlugins()
|
||||
}
|
||||
|
||||
else
|
||||
cancelInstall(errBlock1);
|
||||
|
||||
// PLID solution -- write keys to the registry
|
||||
|
||||
/**
|
||||
* Function for secondary installation of plugin (FirstInstall).
|
||||
* You should not stop the install process because the function failed,
|
||||
* you still have a chance to install the plugin for the already
|
||||
* installed gecko browsers.
|
||||
*
|
||||
* @param empty param list
|
||||
**/
|
||||
|
||||
function createSecondaryInstall()
|
||||
{
|
||||
// Use getFolder in such a way that it creates C:\WINNT\System32\MyPlugin
|
||||
|
||||
secondaryFolder = getFolder("Win System", COMPANY_NAME);
|
||||
|
||||
// if secondaryFolder is NULL, then there has been an error
|
||||
|
||||
if(!secondaryFolder)
|
||||
return noSecondaryInstall;
|
||||
else
|
||||
{
|
||||
// we have admin privileges to write to the Win System directory
|
||||
// so we will set up DLL and XPT in their new home
|
||||
errBlock2 = addFile (PLID, VERSION, PLUGIN_FILE, secondaryFolder, null);
|
||||
|
||||
// Something went wrong if errBlock2 is NOT 0
|
||||
|
||||
if (errBlock2!=0)
|
||||
{
|
||||
logComment("Could NOT add " + PLUGIN_FILE + " to " + secondaryFolder + ":" + errBlock2);
|
||||
return errBlock2;
|
||||
}
|
||||
|
||||
// start installing xpt file if this is a scriptable plugin
|
||||
errBlock2 = addFile (PLID, VERSION, COMPONENT_FILE, secondaryFolder, null);
|
||||
if (errBlock2!=0)
|
||||
{
|
||||
logComment("Could NOT add " + COMPONENT_FILE + " to " + secondaryFolder + ":" + errBlock2);
|
||||
return errBlock2;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
return 0; // 0 means everything went well with the secondary install
|
||||
}
|
||||
|
||||
function writePLIDSolution()
|
||||
{
|
||||
|
||||
//Concatenate the secondary install path with the filename to make a fully qualified pathname
|
||||
|
||||
var qualifiedSecondaryFolderDLL = secondaryFolder + PLUGIN_FILE;
|
||||
var qualifiedSecondaryFolderXPT = secondaryFolder + COMPONENT_FILE;
|
||||
|
||||
// write PLID keys (mozilla.org/projects/plugins/first-install-problem.html)
|
||||
// write PLID keys to HKLM
|
||||
|
||||
var HKLM_status = registerPLID(HKEY_LOCAL_MACHINE, REG_MOZ_PATH,
|
||||
PLID,
|
||||
qualifiedSecondaryFolderDLL, qualifiedSecondaryFolderXPT,
|
||||
PLUGIN_DESCRIPTION, COMPANY_NAME, SOFTWARE_NAME, VERSION,
|
||||
MIMETYPE, SUFFIX, SUFFIX_DESCRIPTION);
|
||||
|
||||
logComment("Moz First Install Installation: registerPLID("+HKEY_LOCAL_MACHINE+") returned, status "+HKLM_status);
|
||||
|
||||
if (HKLM_status == false)
|
||||
{
|
||||
// write PLID keys (mozilla.org/projects/plugins/first-install-problem.html)
|
||||
// write PLID keys to HKCU
|
||||
|
||||
var HKCU_status = registerPLID(HKEY_CURRENT_USER, REG_MOZ_PATH,
|
||||
PLID,
|
||||
qualifiedSecondaryFolderDLL, qualifiedSecondaryFolderXPT,
|
||||
PLUGIN_DESCRIPTION, COMPANY_NAME, SOFTWARE_NAME, VERSION,
|
||||
MIMETYPE, SUFFIX, SUFFIX_DESCRIPTION);
|
||||
|
||||
|
||||
logComment("First Install Installation: registerPLID("+HKEY_CURRENT_USER+") returned, status "+HKLM_status);
|
||||
|
||||
if (HKCU_status != 0)
|
||||
{
|
||||
logComment("Could not write to the registry. Errorcode="+HKCU_status);
|
||||
|
||||
return HKCU_status;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
|
||||
}
|
||||
/**
|
||||
* Function for preinstallation of plugin (FirstInstall).
|
||||
* You should not stop the install process because the function failed,
|
||||
* you still have a chance to install the plugin for the already
|
||||
* installed gecko browsers.
|
||||
*
|
||||
* @param dirPath directory path from getFolder
|
||||
* @param spaceRequired required space in kilobytes
|
||||
*
|
||||
**/
|
||||
|
||||
function verifyDiskSpace(dirPath, spaceRequired)
|
||||
{
|
||||
var spaceAvailable;
|
||||
|
||||
// Get the available disk space on the given path
|
||||
spaceAvailable = fileGetDiskSpaceAvailable(dirPath);
|
||||
|
||||
// Convert the available disk space into kilobytes
|
||||
spaceAvailable = parseInt(spaceAvailable / 1024);
|
||||
|
||||
// do the verification
|
||||
if(spaceAvailable < spaceRequired)
|
||||
{
|
||||
logComment("Insufficient disk space: " + dirPath);
|
||||
logComment(" required : " + spaceRequired + " K");
|
||||
logComment(" available: " + spaceAvailable + " K");
|
||||
return(false);
|
||||
}
|
||||
|
||||
return(true);
|
||||
}
|
||||
/**
|
||||
* Function for writing keys to the Win32 System Registry.
|
||||
* You should not stop the install process because the function failed.
|
||||
* You still have a chance to install the plugin for the
|
||||
* current Gecko browser.
|
||||
*
|
||||
* @param rootKey must be one of these two string values HKEY_LOCAL_MACHINE or HKEY_CURRENT_USER
|
||||
* @param plidID PLID for Plugins
|
||||
* @param dllAbsolutePath the fully qualified path to the DLL
|
||||
* @param xptAbsolutePath the fully qualified path to the XPT
|
||||
* @param pluginDescription a String describing the plugin
|
||||
* @param vendor a String describing the vendor
|
||||
* @param productName the name of this software
|
||||
* @param pluginVersion version string of the plugin
|
||||
* @param mimeType[] MIME type handled by the plugin
|
||||
Plugins with more than one MIME type
|
||||
might use an array
|
||||
* @param suffix[] Suffix handled by plugin (e.g. .my files)
|
||||
* @param suffixDescription[] String describing suffix -- each description matches the corresponding suffix
|
||||
**/
|
||||
function registerPLID(rootKey, plidPath,
|
||||
plidID,
|
||||
dllAbsolutePath, xptAbsolutePath,
|
||||
pluginDescription, vendor, productName, pluginVersion,
|
||||
mimeType, suffix, suffixDescription)
|
||||
{
|
||||
var myRegStatus = 0;
|
||||
var coMimetypePath;
|
||||
|
||||
winreg = getWinRegistry();
|
||||
|
||||
if (winreg == null)
|
||||
{
|
||||
logComment("Moz registerPLID: winreg == null");
|
||||
return winregIsNullError;
|
||||
}
|
||||
|
||||
// Which root to start from HKLM, HKCU
|
||||
if (rootKey == HKEY_LOCAL_MACHINE)
|
||||
{
|
||||
logComment("Moz registerPLID: rootKey=="+HKEY_LOCAL_MACHINE);
|
||||
winreg.setRootKey(winreg.HKEY_LOCAL_MACHINE);
|
||||
}
|
||||
else if (rootKey == HKEY_CURRENT_USER)
|
||||
{
|
||||
logComment("Moz registerPLID: rootKey=="+HKEY_CURRENT_USER);
|
||||
winreg.setRootKey(winreg.HKEY_CURRENT_USER);
|
||||
}
|
||||
else
|
||||
{
|
||||
logComment("Moz registerPlid: invalid rootkey, "+rootKey);
|
||||
return invalidRootkeyError;
|
||||
}
|
||||
|
||||
if (!winreg.isKeyWritable(plidPath))
|
||||
{
|
||||
logComment("Moz registerPLID: registry key not writable");
|
||||
return registryKeyNotWritableError;
|
||||
}
|
||||
|
||||
// If we can't find the plidPath create the key
|
||||
if (!winreg.keyExists(plidPath))
|
||||
{
|
||||
logComment("Moz registerPLID: creating missing key "+plidPath+".");
|
||||
myRegStatus = winreg.createKey(plidPath, "");
|
||||
if (myRegStatus != 0)
|
||||
{
|
||||
logComment("Moz registerPLID: Could not create the key, "+plidPath+"as expected. Errorcode="+myRegStatus);
|
||||
return myRegStatus;
|
||||
}
|
||||
}
|
||||
|
||||
// OK were done, let's write info about our plugin, path, productname, etc
|
||||
|
||||
|
||||
|
||||
myMozillaPluginPath = plidPath+"\\"+plidID; // For instance. SOFTWARE\MozillaPlugins\@Cycore.com/Cult3DViewer
|
||||
myRegStatus = winreg.createKey(plidPath+"\\"+plidID, "");
|
||||
if (myRegStatus != 0)
|
||||
{
|
||||
logComment("Moz registerPLID: could not create the subkey "+plidID+" to "+plidPath+". Errorcode="+myRegStatus);
|
||||
return myRegStatus;
|
||||
}
|
||||
|
||||
|
||||
// Write path to DLL
|
||||
myRegStatus = winreg.setValueString(myMozillaPluginPath, "Path", dllAbsolutePath);
|
||||
if (myRegStatus != 0)
|
||||
{
|
||||
logComment("Moz registerPLID: Could not write the DLL path value. RegPath="+myMozillaPluginPath+", DLLPath="+dllAbsolutePath+". ErrorCode="+myRegStatus);
|
||||
return myRegStatus;
|
||||
}
|
||||
|
||||
// Write XPTPath
|
||||
myRegStatus = winreg.setValueString(myMozillaPluginPath, "XPTPath", xptAbsolutePath);
|
||||
if (myRegStatus != 0)
|
||||
{
|
||||
logComment("Moz registerPLID: Could not write the XPT path value. RegPath="+myMozillaPluginPath+"XPTPath="+xptAbsolutePath+", as expected. Errorcode="+myRegStatus);
|
||||
return myRegStatus;
|
||||
}
|
||||
|
||||
// Write the productName
|
||||
myRegStatus = winreg.setValueString(myMozillaPluginPath, "ProductName", productName);
|
||||
if (myRegStatus != 0)
|
||||
{
|
||||
logComment("Moz registerPLID: Could not write productName. RegPath="+myMozillaPluginPath+", productName="+productName+", as expected. Errorcode="+myRegStatus);
|
||||
return myRegStatus;
|
||||
}
|
||||
|
||||
// Write the vendor
|
||||
myRegStatus = winreg.setValueString(myMozillaPluginPath, "Vendor", vendor);
|
||||
if (myRegStatus != 0)
|
||||
{
|
||||
logComment("Moz registerPLID: Could not write vendorName. RegPath="+myMozillaPluginPath+", vendorName="+vendor+", as expected. Errorcode="+myRegStatus);
|
||||
return myRegStatus;
|
||||
}
|
||||
|
||||
// Write the plugin description
|
||||
myRegStatus = winreg.setValueString(myMozillaPluginPath, "Description", pluginDescription);
|
||||
if (myRegStatus != 0)
|
||||
{
|
||||
logComment("Moz registerPLID: Could not write plugin description. RegPath="+myMozillaPluginPath+", description="+pluginDescription+", as expected. Errorcode="+myRegStatus);
|
||||
return myRegStatus;
|
||||
}
|
||||
|
||||
// Write the version number of the plug-in
|
||||
myRegStatus = winreg.setValueString(myMozillaPluginPath, "Version", pluginVersion);
|
||||
if (myRegStatus != 0)
|
||||
{
|
||||
logComment("Moz registerPLID: Could not write plugin version. RegPath="+myMozillaPluginPath+", pluginVersion="+pluginVersion+", as expected. Errorcode="+myRegStatus);
|
||||
return myRegStatus;
|
||||
}
|
||||
|
||||
/////////////////////////////////
|
||||
// Write the subkey MimeTypes //
|
||||
///////////////////////////////
|
||||
var myMimetypePath = myMozillaPluginPath+"\\MimeTypes";
|
||||
myRegStatus = winreg.createKey(myMimetypePath, "");
|
||||
if (myRegStatus != 0)
|
||||
{
|
||||
logComment("Moz registerPLID: Could not create the subkey MimeTypes, "+myMimetypePath+" as expected. Errorcode="+myRegStatus);
|
||||
return myRegStatus;
|
||||
}
|
||||
|
||||
//Write as many MIME types under the mimetypes key as you have...
|
||||
|
||||
for(i=0; i<mimeType.length; i++)
|
||||
{
|
||||
coMimetypePath = myMimetypePath+"\\"+mimeType[i];
|
||||
myRegStatus = winreg.createKey(coMimetypePath, "");
|
||||
if (myRegStatus != 0)
|
||||
{
|
||||
logComment("Moz registerPLID: Could not create the subkey "+coMimetypePath+", as expected. Errorcode="+myRegStatus);
|
||||
return myRegStatus;
|
||||
}
|
||||
|
||||
// Write the description of the co mimetype
|
||||
myRegStatus = winreg.setValueString(coMimetypePath, "Description", suffixDescription[i]);
|
||||
if (myRegStatus != 0)
|
||||
{
|
||||
logComment("Moz registerPLID: Could not create the suffix description value, "+suffixDescription[i]+", as expected. Errorcode="+myRegStatus);
|
||||
return myRegStatus;
|
||||
}
|
||||
|
||||
|
||||
myRegStatus = winreg.setValueString(coMimetypePath, "Suffixes", suffix[i])
|
||||
if (myRegStatus != 0)
|
||||
{
|
||||
logComment("Moz registerPLID: Could not create the suffixes value, "+suffix[i]+", as expected. Errorcode="+myRegStatus);
|
||||
return myRegStatus;
|
||||
}
|
||||
}
|
||||
/////////////////////////////////
|
||||
// Write the subkey Suffixes //
|
||||
///////////////////////////////
|
||||
|
||||
var suffixPath = myMozillaPluginPath+"\\Suffixes";
|
||||
|
||||
// Write the suffix of the mimetype
|
||||
myRegStatus = winreg.createKey(suffixPath, "");
|
||||
if (myRegStatus != 0)
|
||||
{
|
||||
logComment("Moz registerPLID: Could not create the suffix key, "+suffixPath+", as expected. ErrorCode="+myRegStatus);
|
||||
return myRegStatus;
|
||||
}
|
||||
|
||||
for(i=0; i<suffix.length; i++)
|
||||
{
|
||||
// Write the suffix (extension), (one value-key with no value)
|
||||
myRegStatus = winreg.setValueString(suffixPath, suffix[i], "\0");
|
||||
if (myRegStatus != 0)
|
||||
{
|
||||
logComment("Moz registerPLID: Could not create the suffix value. RegPath="+suffixPath+", value="+suffix+", as expected. Errorcode="+myRegStatus);
|
||||
return myRegStatus;
|
||||
}
|
||||
}
|
||||
|
||||
logComment("Moz registerPLID: Registry keys seems to be written successfully");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,494 @@
|
|||
/**
|
||||
|
||||
Doron Rosenberg -- doronAtNoSpamAllowedHerenetscape.com
|
||||
Arun K. Ranganathan -- arunerAtNoSpamAllowedHerenetscape.com
|
||||
Petter Ericson -- petterAtNoSpamAllowedHerecycore.com
|
||||
|
||||
This is an install.js file that does the following --
|
||||
|
||||
1. Installs to the current browser that is invoking the installation
|
||||
2. Additionally installs to a secondary location on the Windows desktop,
|
||||
in this case C:\WINNT\System32\MyPlugin\
|
||||
3. Writes registry keys exposing the above secondary install location for
|
||||
other browsers to find. The keys are written according to the specification:
|
||||
http://mozilla.org/projects/plugins/first-install-problem.html and follows the
|
||||
PLID specification: http://mozilla.org/projects/plugins/plugin-identifier.html
|
||||
|
||||
**/
|
||||
|
||||
// Define some global variables
|
||||
|
||||
var PLUGIN_FILE = "NPMyPlugin.dll";
|
||||
|
||||
// This plugin consists of an XPT file because it is scriptable
|
||||
// http://mozilla.org/projects/plugins/scripting-plugins.html
|
||||
|
||||
var COMPONENT_FILE = "NPMyPluginScriptable.xpt";
|
||||
|
||||
var PLUGIN_SIZE = 2000; // (DLL file) Reserve a little extra so it is not required to update too often
|
||||
var COMPONENT_SIZE = 10; // (XPI file) Reserve a little extra so it is not required to update too often
|
||||
|
||||
var SOFTWARE_NAME="Cult3D Mozilla Viewer";
|
||||
|
||||
// PLIDs (http://mozilla.org/projects/plugins/plugin-identifier.html) are coined by vendors.
|
||||
|
||||
var PLID = "@myplugin.com/myplugin,version=5.3";
|
||||
|
||||
var VERSION = "5.3.0.0";
|
||||
|
||||
var MIMETYPE = "application/x-my-plugin";
|
||||
var SUFFIX = "my";
|
||||
var SUFFIX_DESCRIPTION = "My Plugin Files";
|
||||
var COMPANY_NAME = "MyPluginCo";
|
||||
var PLUGIN_DESCRIPTION = "My Exemplary Plugin Mine All Mine";
|
||||
|
||||
// Registry constant paths
|
||||
// These will be used when the Win32 Registry Keys are written
|
||||
|
||||
var HKEY_LOCAL_MACHINE = "HKEY_LOCAL_MACHINE";
|
||||
var HKEY_CURRENT_USER = "HKEY_CURRENT_USER";
|
||||
var REG_MOZ_PATH = "SOFTWARE\\MozillaPlugins";
|
||||
|
||||
|
||||
|
||||
// My Own Error Code in case secondary installation fails
|
||||
var noSecondaryInstall = 1;
|
||||
|
||||
|
||||
// error return codes need some memory
|
||||
var err;
|
||||
|
||||
// error return codes when we try and install to the current browser
|
||||
|
||||
var errBlock1;
|
||||
|
||||
// error return codes when we try and do a secondary installation
|
||||
|
||||
var errBlock2 = 0;
|
||||
|
||||
// global variable containing our secondary install location
|
||||
|
||||
var secondaryFolder;
|
||||
|
||||
//Special error values used by the Cycore developers (www.cycore.com) who helped make this install script
|
||||
|
||||
var exceptionOccuredError = -4711;
|
||||
var winRegIsNullError = -4712;
|
||||
var invalidRootkeyError = -4713;
|
||||
var registrykeyNotWritableError = -4714;
|
||||
|
||||
|
||||
//initInstall block
|
||||
//the installation is initialized here -- if we fail here, cancel the installation
|
||||
|
||||
// initInstall is quite an overloaded method, but I have invoked it here with three strings
|
||||
// which are globally defined
|
||||
|
||||
err = initInstall(SOFTWARE_NAME, PLID, VERSION);
|
||||
|
||||
if (err != 0)
|
||||
{
|
||||
logComment("Install failed at initInstall level with " + err);
|
||||
cancelInstall(err);
|
||||
}
|
||||
|
||||
//addFiles to current browser block
|
||||
|
||||
var pluginsFolder = getFolder("Plugins");
|
||||
|
||||
//Verify Disk Space
|
||||
|
||||
if(verifyDiskSpace(pluginsFolder, PLUGIN_SIZE+COMPONENT_SIZE))
|
||||
{
|
||||
// start installing plugin shared library
|
||||
resetError();
|
||||
|
||||
// install the plugin shared library to the current browser's Plugin directory
|
||||
|
||||
errBlock1 = addFile (PLID, VERSION, PLUGIN_FILE, pluginsFolder, null);
|
||||
if (errBlock1!=0)
|
||||
{
|
||||
logComment("Could NOT add " + PLUGIN_FILE + " to " + pluginsFolder + ":" + errBlock1);
|
||||
cancelInstall(errBlock1);
|
||||
}
|
||||
|
||||
// start installing xpt file if this is a scriptable plugin
|
||||
// install to the plugins directory -- this works well in Mozilla 1.0 clients
|
||||
// in Mozilla 1.0 clients, the Components directory can be avoided for XPT files
|
||||
|
||||
errBlock1 = addFile (PLID, VERSION, COMPONENT_FILE, pluginsFolder, null);
|
||||
if (errBlock1!=0)
|
||||
{
|
||||
logComment("Could NOT add " + COMPONENT_FILE + " to " + pluginsFolder + ":" + errBlock1);
|
||||
cancelInstall(errBlock1);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
logComment("Cancelling current browser install due to lack of space...");
|
||||
cancellInstall();
|
||||
}
|
||||
|
||||
|
||||
// Secondary install block, which sets up plugins and xpt in another location in addition to the current browser
|
||||
|
||||
errBlock2 = createSecondaryInstall();
|
||||
|
||||
|
||||
// performInstall block, in which error conditions from previous blocks are checked.
|
||||
// This block also invokes a function to write registry keys (PLID) and checks return from key writing
|
||||
// This block invokes refreshPlugins() to ensure that plugin and xpt are available for use immediately
|
||||
|
||||
if (errBlock1 == SUCCESS)
|
||||
{
|
||||
|
||||
// installation to the current browser was a success - this is the most important job of this script!
|
||||
|
||||
if(errBlock2 == SUCCESS)
|
||||
{
|
||||
// Now take care of writing PLIDs to the Win32 Registry
|
||||
|
||||
err = writePLIDSolution();
|
||||
if(err!=SUCCESS)
|
||||
{
|
||||
logComment("Could NOT write Win32 Keys as specified: " + err);
|
||||
}
|
||||
else
|
||||
{
|
||||
logComment("PLID entries are present in the Win32 Registry");
|
||||
}
|
||||
}
|
||||
|
||||
resetError();
|
||||
err = performInstall();
|
||||
if (err == SUCCESS)
|
||||
refreshPlugins(true);
|
||||
|
||||
// call refreshPlugins(true) if you'd like the web page which invoked the plugin to
|
||||
// reload. You can also simply call refreshPlugins()
|
||||
}
|
||||
|
||||
else
|
||||
cancelInstall(errBlock1);
|
||||
|
||||
// PLID solution -- write keys to the registry
|
||||
|
||||
/**
|
||||
* Function for secondary installation of plugin (FirstInstall).
|
||||
* You should not stop the install process because the function failed,
|
||||
* you still have a chance to install the plugin for the already
|
||||
* installed gecko browsers.
|
||||
*
|
||||
* @param empty param list
|
||||
**/
|
||||
|
||||
function createSecondaryInstall()
|
||||
{
|
||||
// Use getFolder in such a way that it creates C:\WINNT\System32\MyPlugin
|
||||
|
||||
secondaryFolder = getFolder("Win System", COMPANY_NAME);
|
||||
|
||||
// if secondaryFolder is NULL, then there has been an error
|
||||
|
||||
if(!secondaryFolder)
|
||||
return noSecondaryInstall;
|
||||
else
|
||||
{
|
||||
// we have admin privileges to write to the Win System directory
|
||||
// so we will set up DLL and XPT in their new home
|
||||
errBlock2 = addFile (PLID, VERSION, PLUGIN_FILE, secondaryFolder, null);
|
||||
|
||||
// Something went wrong if errBlock2 is NOT 0
|
||||
|
||||
if (errBlock2!=0)
|
||||
{
|
||||
logComment("Could NOT add " + PLUGIN_FILE + " to " + secondaryFolder + ":" + errBlock2);
|
||||
return errBlock2;
|
||||
}
|
||||
|
||||
// start installing xpt file if this is a scriptable plugin
|
||||
errBlock2 = addFile (PLID, VERSION, COMPONENT_FILE, secondaryFolder, null);
|
||||
if (errBlock2!=0)
|
||||
{
|
||||
logComment("Could NOT add " + COMPONENT_FILE + " to " + secondaryFolder + ":" + errBlock2);
|
||||
return errBlock2;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
return 0; // 0 means everything went well with the secondary install
|
||||
}
|
||||
|
||||
function writePLIDSolution()
|
||||
{
|
||||
|
||||
//Concatenate the secondary install path with the filename to make a fully qualified pathname
|
||||
|
||||
var qualifiedSecondaryFolderDLL = secondaryFolder + PLUGIN_FILE;
|
||||
var qualifiedSecondaryFolderXPT = secondaryFolder + COMPONENT_FILE;
|
||||
|
||||
// write PLID keys (mozilla.org/projects/plugins/first-install-problem.html)
|
||||
// write PLID keys to HKLM
|
||||
|
||||
var HKLM_status = registerPLID(HKEY_LOCAL_MACHINE, REG_MOZ_PATH,
|
||||
PLID,
|
||||
qualifiedSecondaryFolderDLL, qualifiedSecondaryFolderXPT,
|
||||
PLUGIN_DESCRIPTION, COMPANY_NAME, SOFTWARE_NAME, VERSION,
|
||||
MIMETYPE, SUFFIX, SUFFIX_DESCRIPTION);
|
||||
|
||||
logComment("Moz First Install Installation: registerPLID("+HKEY_LOCAL_MACHINE+") returned, status "+HKLM_status);
|
||||
|
||||
if (HKLM_status == false)
|
||||
{
|
||||
// write PLID keys (mozilla.org/projects/plugins/first-install-problem.html)
|
||||
// write PLID keys to HKCU
|
||||
|
||||
var HKCU_status = registerPLID(HKEY_CURRENT_USER, REG_MOZ_PATH,
|
||||
PLID,
|
||||
qualifiedSecondaryFolderDLL, qualifiedSecondaryFolderXPT,
|
||||
PLUGIN_DESCRIPTION, COMPANY_NAME, SOFTWARE_NAME, VERSION,
|
||||
MIMETYPE, SUFFIX, SUFFIX_DESCRIPTION);
|
||||
|
||||
|
||||
logComment("First Install Installation: registerPLID("+HKEY_CURRENT_USER+") returned, status "+HKLM_status);
|
||||
|
||||
if (HKCU_status != 0)
|
||||
{
|
||||
logComment("Could not write to the registry. Errorcode="+HKCU_status);
|
||||
|
||||
return HKCU_status;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
|
||||
}
|
||||
/**
|
||||
* Function for preinstallation of plugin (FirstInstall).
|
||||
* You should not stop the install process because the function failed,
|
||||
* you still have a chance to install the plugin for the already
|
||||
* installed gecko browsers.
|
||||
*
|
||||
* @param dirPath directory path from getFolder
|
||||
* @param spaceRequired required space in kilobytes
|
||||
*
|
||||
**/
|
||||
|
||||
function verifyDiskSpace(dirPath, spaceRequired)
|
||||
{
|
||||
var spaceAvailable;
|
||||
|
||||
// Get the available disk space on the given path
|
||||
spaceAvailable = fileGetDiskSpaceAvailable(dirPath);
|
||||
|
||||
// Convert the available disk space into kilobytes
|
||||
spaceAvailable = parseInt(spaceAvailable / 1024);
|
||||
|
||||
// do the verification
|
||||
if(spaceAvailable < spaceRequired)
|
||||
{
|
||||
logComment("Insufficient disk space: " + dirPath);
|
||||
logComment(" required : " + spaceRequired + " K");
|
||||
logComment(" available: " + spaceAvailable + " K");
|
||||
return(false);
|
||||
}
|
||||
|
||||
return(true);
|
||||
}
|
||||
/**
|
||||
* Function for writing keys to the Win32 System Registry.
|
||||
* You should not stop the install process because the function failed.
|
||||
* You still have a chance to install the plugin for the
|
||||
* current Gecko browser.
|
||||
*
|
||||
* @param rootKey must be one of these two string values HKEY_LOCAL_MACHINE or HKEY_CURRENT_USER
|
||||
* @param plidID PLID for Plugins
|
||||
* @param dllAbsolutePath the fully qualified path to the DLL
|
||||
* @param xptAbsolutePath the fully qualified path to the XPT
|
||||
* @param pluginDescription a String describing the plugin
|
||||
* @param vendor a String describing the vendor
|
||||
* @param productName the name of this software
|
||||
* @param pluginVersion version string of the plugin
|
||||
* @param mimeType MIME type handled by the plugin
|
||||
Plugins with more than one MIME type
|
||||
might use an array
|
||||
* @param suffix Suffix handled by plugin (e.g. .my files)
|
||||
* @param suffixDescription String describing suffix
|
||||
**/
|
||||
function registerPLID(rootKey, plidPath,
|
||||
plidID,
|
||||
dllAbsolutePath, xptAbsolutePath,
|
||||
pluginDescription, vendor, productName, pluginVersion,
|
||||
mimeType, suffix, suffixDescription)
|
||||
{
|
||||
var myRegStatus = 0;
|
||||
|
||||
winreg = getWinRegistry();
|
||||
|
||||
if (winreg == null)
|
||||
{
|
||||
logComment("Moz registerPLID: winreg == null");
|
||||
return winregIsNullError;
|
||||
}
|
||||
|
||||
// Which root to start from HKLM, HKCU
|
||||
if (rootKey == HKEY_LOCAL_MACHINE)
|
||||
{
|
||||
logComment("Moz registerPLID: rootKey=="+HKEY_LOCAL_MACHINE);
|
||||
winreg.setRootKey(winreg.HKEY_LOCAL_MACHINE);
|
||||
}
|
||||
else if (rootKey == HKEY_CURRENT_USER)
|
||||
{
|
||||
logComment("Moz registerPLID: rootKey=="+HKEY_CURRENT_USER);
|
||||
winreg.setRootKey(winreg.HKEY_CURRENT_USER);
|
||||
}
|
||||
else
|
||||
{
|
||||
logComment("Moz registerPlid: invalid rootkey, "+rootKey);
|
||||
return invalidRootkeyError;
|
||||
}
|
||||
|
||||
if (!winreg.isKeyWritable(plidPath))
|
||||
{
|
||||
logComment("Moz registerPLID: registry key not writable");
|
||||
return registryKeyNotWritableError;
|
||||
}
|
||||
|
||||
// If we can't find the plidPath create the key
|
||||
if (!winreg.keyExists(plidPath))
|
||||
{
|
||||
logComment("Moz registerPLID: creating missing key "+plidPath+".");
|
||||
myRegStatus = winreg.createKey(plidPath, "");
|
||||
if (myRegStatus != 0)
|
||||
{
|
||||
logComment("Moz registerPLID: Could not create the key, "+plidPath+"as expected. Errorcode="+myRegStatus);
|
||||
return myRegStatus;
|
||||
}
|
||||
}
|
||||
|
||||
// OK were done, let's write info about our plugin, path, productname, etc
|
||||
|
||||
|
||||
// Write a subkey to MozillaPlugins with our PLID
|
||||
//var mySetStrRC = winreg.setValueString(plidPath, plidID, dllAbsolutePath);
|
||||
|
||||
myMozillaPluginPath = plidPath+"\\"+plidID; // For instance. SOFTWARE\MozillaPlugins\@Cycore.com/Cult3DViewer
|
||||
myRegStatus = winreg.createKey(plidPath+"\\"+plidID, "");
|
||||
if (myRegStatus != 0)
|
||||
{
|
||||
logComment("Moz registerPLID: could not create the subkey "+plidID+" to "+plidPath+". Errorcode="+myRegStatus);
|
||||
return myRegStatus;
|
||||
}
|
||||
|
||||
|
||||
// Write path to DLL
|
||||
myRegStatus = winreg.setValueString(myMozillaPluginPath, "Path", dllAbsolutePath);
|
||||
if (myRegStatus != 0)
|
||||
{
|
||||
logComment("Moz registerPLID: Could not write the DLL path value. RegPath="+myMozillaPluginPath+", DLLPath="+dllAbsolutePath+". ErrorCode="+myRegStatus);
|
||||
return myRegStatus;
|
||||
}
|
||||
|
||||
// Write XPTPath
|
||||
myRegStatus = winreg.setValueString(myMozillaPluginPath, "XPTPath", xptAbsolutePath);
|
||||
if (myRegStatus != 0)
|
||||
{
|
||||
logComment("Moz registerPLID: Could not write the XPT path value. RegPath="+myMozillaPluginPath+"XPTPath="+xptAbsolutePath+", as expected. Errorcode="+myRegStatus);
|
||||
return myRegStatus;
|
||||
}
|
||||
|
||||
// Write the productName
|
||||
myRegStatus = winreg.setValueString(myMozillaPluginPath, "ProductName", productName);
|
||||
if (myRegStatus != 0)
|
||||
{
|
||||
logComment("Moz registerPLID: Could not write productName. RegPath="+myMozillaPluginPath+", productName="+productName+", as expected. Errorcode="+myRegStatus);
|
||||
return myRegStatus;
|
||||
}
|
||||
|
||||
// Write the vendor
|
||||
myRegStatus = winreg.setValueString(myMozillaPluginPath, "Vendor", vendor);
|
||||
if (myRegStatus != 0)
|
||||
{
|
||||
logComment("Moz registerPLID: Could not write vendorName. RegPath="+myMozillaPluginPath+", vendorName="+vendor+", as expected. Errorcode="+myRegStatus);
|
||||
return myRegStatus;
|
||||
}
|
||||
|
||||
// Write the plugin description
|
||||
myRegStatus = winreg.setValueString(myMozillaPluginPath, "Description", pluginDescription);
|
||||
if (myRegStatus != 0)
|
||||
{
|
||||
logComment("Moz registerPLID: Could not write plugin description. RegPath="+myMozillaPluginPath+", description="+pluginDescription+", as expected. Errorcode="+myRegStatus);
|
||||
return myRegStatus;
|
||||
}
|
||||
|
||||
// Write the version number of the plug-in
|
||||
myRegStatus = winreg.setValueString(myMozillaPluginPath, "Version", pluginVersion);
|
||||
if (myRegStatus != 0)
|
||||
{
|
||||
logComment("Moz registerPLID: Could not write plugin version. RegPath="+myMozillaPluginPath+", pluginVersion="+pluginVersion+", as expected. Errorcode="+myRegStatus);
|
||||
return myRegStatus;
|
||||
}
|
||||
|
||||
/////////////////////////////////
|
||||
// Write the subkey MimeTypes //
|
||||
///////////////////////////////
|
||||
var myMimetypePath = myMozillaPluginPath+"\\MimeTypes";
|
||||
myRegStatus = winreg.createKey(myMimetypePath, "");
|
||||
if (myRegStatus != 0)
|
||||
{
|
||||
logComment("Moz registerPLID: Could not create the subkey MimeTypes, "+myMimetypePath+" as expected. Errorcode="+myRegStatus);
|
||||
return myRegStatus;
|
||||
}
|
||||
|
||||
var coMimetypePath = myMimetypePath+"\\"+mimeType;
|
||||
myRegStatus = winreg.createKey(coMimetypePath, "");
|
||||
if (myRegStatus != 0)
|
||||
{
|
||||
logComment("Moz registerPLID: Could not create the subkey "+coMimetypePath+", as expected. Errorcode="+myRegStatus);
|
||||
return myRegStatus;
|
||||
}
|
||||
|
||||
// Write the description of the co mimetype
|
||||
myRegStatus = winreg.setValueString(coMimetypePath, "Description", suffixDescription);
|
||||
if (myRegStatus != 0)
|
||||
{
|
||||
logComment("Moz registerPLID: Could not create the suffix description value, "+suffixDescription+", as expected. Errorcode="+myRegStatus);
|
||||
return myRegStatus;
|
||||
}
|
||||
|
||||
myRegStatus = winreg.setValueString(coMimetypePath, "Suffixes", suffix)
|
||||
if (myRegStatus != 0)
|
||||
{
|
||||
logComment("Moz registerPLID: Could not create the suffixes value, "+suffix+", as expected. Errorcode="+myRegStatus);
|
||||
return myRegStatus;
|
||||
}
|
||||
|
||||
/////////////////////////////////
|
||||
// Write the subkey Suffixes //
|
||||
///////////////////////////////
|
||||
|
||||
var suffixPath = myMozillaPluginPath+"\\Suffixes";
|
||||
|
||||
// Write the suffix of the mimetype
|
||||
myRegStatus = winreg.createKey(suffixPath, "");
|
||||
if (myRegStatus != 0)
|
||||
{
|
||||
logComment("Moz registerPLID: Could not create the suffix key, "+suffixPath+", as expected. ErrorCode="+myRegStatus);
|
||||
return myRegStatus;
|
||||
}
|
||||
|
||||
// Write the suffix (extension), (one value-key with no value)
|
||||
myRegStatus = winreg.setValueString(suffixPath, suffix, "\0");
|
||||
if (myRegStatus != 0)
|
||||
{
|
||||
logComment("Moz registerPLID: Could not create the suffix value. RegPath="+suffixPath+", value="+suffix+", as expected. Errorcode="+myRegStatus);
|
||||
return myRegStatus;
|
||||
}
|
||||
|
||||
logComment("Moz registerPLID: Registry keys seems to be written successfully");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Developer Studio generated include file.
|
||||
// Used by XPIPackager.rc
|
||||
//
|
||||
#define IDM_ABOUTBOX 0x0010
|
||||
#define IDD_ABOUTBOX 100
|
||||
#define IDS_ABOUTBOX 101
|
||||
#define IDD_XPIPACKAGER_DIALOG 102
|
||||
#define IDR_MAINFRAME 128
|
||||
#define IDD_FILE_CHOOSER 129
|
||||
#define IDR_HEADER 132
|
||||
#define IDR_BODY 134
|
||||
#define IDR_FILLER 135
|
||||
#define IDD_MIMETYPE_CHOOSER 136
|
||||
#define IDC_AUTO_PLID 1001
|
||||
#define IDC_DOMAIN_NAME 1002
|
||||
#define IDC_PRODUCT_NAME 1003
|
||||
#define IDC_PLUGIN_VERSION 1004
|
||||
#define IDC_PLID_HELP 1005
|
||||
#define IDC_PLID 1006
|
||||
#define IDC_ARCHIVE_NAME 1007
|
||||
#define IDC_PLUGIN_LIST 1008
|
||||
#define IDC_PLUGIN_BROWSE 1009
|
||||
#define IDC_PLUGIN_REMOVE 1010
|
||||
#define IDC_PLUGIN_SIZE 1011
|
||||
#define IDC_COMPONENT_LIST 1012
|
||||
#define IDC_COMPONENT_BROWSE 1013
|
||||
#define IDC_COMPONENT_REMOVE 1014
|
||||
#define IDC_COMPONENT_SIZE 1015
|
||||
#define IDC_MIME_LIST 1016
|
||||
#define IDC_COMPANY_NAME 1017
|
||||
#define IDC_BIG_HELP 1018
|
||||
#define IDC_FILENAME_BROWSE 1019
|
||||
#define IDC_FILENAME 1020
|
||||
#define IDC_PLUGIN_DESCRIPTION 1024
|
||||
#define IDC_MIMETYPE_ADD 1025
|
||||
#define IDC_MIMETYPE_REMOVE 1026
|
||||
#define IDC_MIMETYPE 1027
|
||||
#define IDC_SUFFIX 1028
|
||||
#define IDC_SUFFIX_DESCRIPTION 1029
|
||||
|
||||
// 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 1031
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
|
@ -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: zconf.h,v 1.1 2002/12/03 21:52:44 anthonyd%netscape.com Exp $ */
|
||||
|
||||
#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 */
|
|
@ -0,0 +1,893 @@
|
|||
/* zlib.h -- interface of the 'zlib' general purpose compression library
|
||||
version 1.1.3, July 9th, 1998
|
||||
|
||||
Copyright (C) 1995-1998 Jean-loup Gailly and Mark Adler
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. 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.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
Jean-loup Gailly Mark Adler
|
||||
jloup@gzip.org madler@alumni.caltech.edu
|
||||
|
||||
|
||||
The data format used by the zlib library is described by RFCs (Request for
|
||||
Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt
|
||||
(zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
|
||||
*/
|
||||
|
||||
#ifndef _ZLIB_H
|
||||
#define _ZLIB_H
|
||||
|
||||
#include "zconf.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define ZLIB_VERSION "1.1.3"
|
||||
|
||||
/*
|
||||
The 'zlib' compression library provides in-memory compression and
|
||||
decompression functions, including integrity checks of the uncompressed
|
||||
data. This version of the library supports only one compression method
|
||||
(deflation) but other algorithms will be added later and will have the same
|
||||
stream interface.
|
||||
|
||||
Compression can be done in a single step if the buffers are large
|
||||
enough (for example if an input file is mmap'ed), or can be done by
|
||||
repeated calls of the compression function. In the latter case, the
|
||||
application must provide more input and/or consume the output
|
||||
(providing more output space) before each call.
|
||||
|
||||
The library also supports reading and writing files in gzip (.gz) format
|
||||
with an interface similar to that of stdio.
|
||||
|
||||
The library does not install any signal handler. The decoder checks
|
||||
the consistency of the compressed data, so the library should never
|
||||
crash even in case of corrupted input.
|
||||
*/
|
||||
|
||||
typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
|
||||
typedef void (*free_func) OF((voidpf opaque, voidpf address));
|
||||
|
||||
struct internal_state;
|
||||
|
||||
typedef struct z_stream_s {
|
||||
Bytef *next_in; /* next input byte */
|
||||
uInt avail_in; /* number of bytes available at next_in */
|
||||
uLong total_in; /* total nb of input bytes read so far */
|
||||
|
||||
Bytef *next_out; /* next output byte should be put there */
|
||||
uInt avail_out; /* remaining free space at next_out */
|
||||
uLong total_out; /* total nb of bytes output so far */
|
||||
|
||||
char *msg; /* last error message, NULL if no error */
|
||||
struct internal_state FAR *state; /* not visible by applications */
|
||||
|
||||
alloc_func zalloc; /* used to allocate the internal state */
|
||||
free_func zfree; /* used to free the internal state */
|
||||
voidpf opaque; /* private data object passed to zalloc and zfree */
|
||||
|
||||
int data_type; /* best guess about the data type: ascii or binary */
|
||||
uLong adler; /* adler32 value of the uncompressed data */
|
||||
uLong reserved; /* reserved for future use */
|
||||
} z_stream;
|
||||
|
||||
typedef z_stream FAR *z_streamp;
|
||||
|
||||
/*
|
||||
The application must update next_in and avail_in when avail_in has
|
||||
dropped to zero. It must update next_out and avail_out when avail_out
|
||||
has dropped to zero. The application must initialize zalloc, zfree and
|
||||
opaque before calling the init function. All other fields are set by the
|
||||
compression library and must not be updated by the application.
|
||||
|
||||
The opaque value provided by the application will be passed as the first
|
||||
parameter for calls of zalloc and zfree. This can be useful for custom
|
||||
memory management. The compression library attaches no meaning to the
|
||||
opaque value.
|
||||
|
||||
zalloc must return Z_NULL if there is not enough memory for the object.
|
||||
If zlib is used in a multi-threaded application, zalloc and zfree must be
|
||||
thread safe.
|
||||
|
||||
On 16-bit systems, the functions zalloc and zfree must be able to allocate
|
||||
exactly 65536 bytes, but will not be required to allocate more than this
|
||||
if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS,
|
||||
pointers returned by zalloc for objects of exactly 65536 bytes *must*
|
||||
have their offset normalized to zero. The default allocation function
|
||||
provided by this library ensures this (see zutil.c). To reduce memory
|
||||
requirements and avoid any allocation of 64K objects, at the expense of
|
||||
compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h).
|
||||
|
||||
The fields total_in and total_out can be used for statistics or
|
||||
progress reports. After compression, total_in holds the total size of
|
||||
the uncompressed data and may be saved for use in the decompressor
|
||||
(particularly if the decompressor wants to decompress everything in
|
||||
a single step).
|
||||
*/
|
||||
|
||||
/* constants */
|
||||
|
||||
#define Z_NO_FLUSH 0
|
||||
#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */
|
||||
#define Z_SYNC_FLUSH 2
|
||||
#define Z_FULL_FLUSH 3
|
||||
#define Z_FINISH 4
|
||||
/* Allowed flush values; see deflate() below for details */
|
||||
|
||||
#define Z_OK 0
|
||||
#define Z_STREAM_END 1
|
||||
#define Z_NEED_DICT 2
|
||||
#define Z_ERRNO (-1)
|
||||
#define Z_STREAM_ERROR (-2)
|
||||
#define Z_DATA_ERROR (-3)
|
||||
#define Z_MEM_ERROR (-4)
|
||||
#define Z_BUF_ERROR (-5)
|
||||
#define Z_VERSION_ERROR (-6)
|
||||
/* Return codes for the compression/decompression functions. Negative
|
||||
* values are errors, positive values are used for special but normal events.
|
||||
*/
|
||||
|
||||
#define Z_NO_COMPRESSION 0
|
||||
#define Z_BEST_SPEED 1
|
||||
#define Z_BEST_COMPRESSION 9
|
||||
#define Z_DEFAULT_COMPRESSION (-1)
|
||||
/* compression levels */
|
||||
|
||||
#define Z_FILTERED 1
|
||||
#define Z_HUFFMAN_ONLY 2
|
||||
#define Z_DEFAULT_STRATEGY 0
|
||||
/* compression strategy; see deflateInit2() below for details */
|
||||
|
||||
#define Z_BINARY 0
|
||||
#define Z_ASCII 1
|
||||
#define Z_UNKNOWN 2
|
||||
/* Possible values of the data_type field */
|
||||
|
||||
#define Z_DEFLATED 8
|
||||
/* The deflate compression method (the only one supported in this version) */
|
||||
|
||||
#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */
|
||||
|
||||
#define zlib_version zlibVersion()
|
||||
/* for compatibility with versions < 1.0.2 */
|
||||
|
||||
/* basic functions */
|
||||
|
||||
ZEXTERN const char * ZEXPORT zlibVersion OF((void));
|
||||
/* The application can compare zlibVersion and ZLIB_VERSION for consistency.
|
||||
If the first character differs, the library code actually used is
|
||||
not compatible with the zlib.h header file used by the application.
|
||||
This check is automatically made by deflateInit and inflateInit.
|
||||
*/
|
||||
|
||||
/*
|
||||
ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
|
||||
|
||||
Initializes the internal stream state for compression. The fields
|
||||
zalloc, zfree and opaque must be initialized before by the caller.
|
||||
If zalloc and zfree are set to Z_NULL, deflateInit updates them to
|
||||
use default allocation functions.
|
||||
|
||||
The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
|
||||
1 gives best speed, 9 gives best compression, 0 gives no compression at
|
||||
all (the input data is simply copied a block at a time).
|
||||
Z_DEFAULT_COMPRESSION requests a default compromise between speed and
|
||||
compression (currently equivalent to level 6).
|
||||
|
||||
deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
|
||||
enough memory, Z_STREAM_ERROR if level is not a valid compression level,
|
||||
Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible
|
||||
with the version assumed by the caller (ZLIB_VERSION).
|
||||
msg is set to null if there is no error message. deflateInit does not
|
||||
perform any compression: this will be done by deflate().
|
||||
*/
|
||||
|
||||
|
||||
ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
|
||||
/*
|
||||
deflate compresses as much data as possible, and stops when the input
|
||||
buffer becomes empty or the output buffer becomes full. It may introduce some
|
||||
output latency (reading input without producing any output) except when
|
||||
forced to flush.
|
||||
|
||||
The detailed semantics are as follows. deflate performs one or both of the
|
||||
following actions:
|
||||
|
||||
- Compress more input starting at next_in and update next_in and avail_in
|
||||
accordingly. If not all input can be processed (because there is not
|
||||
enough room in the output buffer), next_in and avail_in are updated and
|
||||
processing will resume at this point for the next call of deflate().
|
||||
|
||||
- Provide more output starting at next_out and update next_out and avail_out
|
||||
accordingly. This action is forced if the parameter flush is non zero.
|
||||
Forcing flush frequently degrades the compression ratio, so this parameter
|
||||
should be set only when necessary (in interactive applications).
|
||||
Some output may be provided even if flush is not set.
|
||||
|
||||
Before the call of deflate(), the application should ensure that at least
|
||||
one of the actions is possible, by providing more input and/or consuming
|
||||
more output, and updating avail_in or avail_out accordingly; avail_out
|
||||
should never be zero before the call. The application can consume the
|
||||
compressed output when it wants, for example when the output buffer is full
|
||||
(avail_out == 0), or after each call of deflate(). If deflate returns Z_OK
|
||||
and with zero avail_out, it must be called again after making room in the
|
||||
output buffer because there might be more output pending.
|
||||
|
||||
If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
|
||||
flushed to the output buffer and the output is aligned on a byte boundary, so
|
||||
that the decompressor can get all input data available so far. (In particular
|
||||
avail_in is zero after the call if enough output space has been provided
|
||||
before the call.) Flushing may degrade compression for some compression
|
||||
algorithms and so it should be used only when necessary.
|
||||
|
||||
If flush is set to Z_FULL_FLUSH, all output is flushed as with
|
||||
Z_SYNC_FLUSH, and the compression state is reset so that decompression can
|
||||
restart from this point if previous compressed data has been damaged or if
|
||||
random access is desired. Using Z_FULL_FLUSH too often can seriously degrade
|
||||
the compression.
|
||||
|
||||
If deflate returns with avail_out == 0, this function must be called again
|
||||
with the same value of the flush parameter and more output space (updated
|
||||
avail_out), until the flush is complete (deflate returns with non-zero
|
||||
avail_out).
|
||||
|
||||
If the parameter flush is set to Z_FINISH, pending input is processed,
|
||||
pending output is flushed and deflate returns with Z_STREAM_END if there
|
||||
was enough output space; if deflate returns with Z_OK, this function must be
|
||||
called again with Z_FINISH and more output space (updated avail_out) but no
|
||||
more input data, until it returns with Z_STREAM_END or an error. After
|
||||
deflate has returned Z_STREAM_END, the only possible operations on the
|
||||
stream are deflateReset or deflateEnd.
|
||||
|
||||
Z_FINISH can be used immediately after deflateInit if all the compression
|
||||
is to be done in a single step. In this case, avail_out must be at least
|
||||
0.1% larger than avail_in plus 12 bytes. If deflate does not return
|
||||
Z_STREAM_END, then it must be called again as described above.
|
||||
|
||||
deflate() sets strm->adler to the adler32 checksum of all input read
|
||||
so far (that is, total_in bytes).
|
||||
|
||||
deflate() may update data_type if it can make a good guess about
|
||||
the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered
|
||||
binary. This field is only for information purposes and does not affect
|
||||
the compression algorithm in any manner.
|
||||
|
||||
deflate() returns Z_OK if some progress has been made (more input
|
||||
processed or more output produced), Z_STREAM_END if all input has been
|
||||
consumed and all output has been produced (only when flush is set to
|
||||
Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
|
||||
if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible
|
||||
(for example avail_in or avail_out was zero).
|
||||
*/
|
||||
|
||||
|
||||
ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));
|
||||
/*
|
||||
All dynamically allocated data structures for this stream are freed.
|
||||
This function discards any unprocessed input and does not flush any
|
||||
pending output.
|
||||
|
||||
deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
|
||||
stream state was inconsistent, Z_DATA_ERROR if the stream was freed
|
||||
prematurely (some input or output was discarded). In the error case,
|
||||
msg may be set but then points to a static string (which must not be
|
||||
deallocated).
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
|
||||
|
||||
Initializes the internal stream state for decompression. The fields
|
||||
next_in, avail_in, zalloc, zfree and opaque must be initialized before by
|
||||
the caller. If next_in is not Z_NULL and avail_in is large enough (the exact
|
||||
value depends on the compression method), inflateInit determines the
|
||||
compression method from the zlib header and allocates all data structures
|
||||
accordingly; otherwise the allocation will be deferred to the first call of
|
||||
inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to
|
||||
use default allocation functions.
|
||||
|
||||
inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
|
||||
memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
|
||||
version assumed by the caller. msg is set to null if there is no error
|
||||
message. inflateInit does not perform any decompression apart from reading
|
||||
the zlib header if present: this will be done by inflate(). (So next_in and
|
||||
avail_in may be modified, but next_out and avail_out are unchanged.)
|
||||
*/
|
||||
|
||||
|
||||
ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
|
||||
/*
|
||||
inflate decompresses as much data as possible, and stops when the input
|
||||
buffer becomes empty or the output buffer becomes full. It may some
|
||||
introduce some output latency (reading input without producing any output)
|
||||
except when forced to flush.
|
||||
|
||||
The detailed semantics are as follows. inflate performs one or both of the
|
||||
following actions:
|
||||
|
||||
- Decompress more input starting at next_in and update next_in and avail_in
|
||||
accordingly. If not all input can be processed (because there is not
|
||||
enough room in the output buffer), next_in is updated and processing
|
||||
will resume at this point for the next call of inflate().
|
||||
|
||||
- Provide more output starting at next_out and update next_out and avail_out
|
||||
accordingly. inflate() provides as much output as possible, until there
|
||||
is no more input data or no more space in the output buffer (see below
|
||||
about the flush parameter).
|
||||
|
||||
Before the call of inflate(), the application should ensure that at least
|
||||
one of the actions is possible, by providing more input and/or consuming
|
||||
more output, and updating the next_* and avail_* values accordingly.
|
||||
The application can consume the uncompressed output when it wants, for
|
||||
example when the output buffer is full (avail_out == 0), or after each
|
||||
call of inflate(). If inflate returns Z_OK and with zero avail_out, it
|
||||
must be called again after making room in the output buffer because there
|
||||
might be more output pending.
|
||||
|
||||
If the parameter flush is set to Z_SYNC_FLUSH, inflate flushes as much
|
||||
output as possible to the output buffer. The flushing behavior of inflate is
|
||||
not specified for values of the flush parameter other than Z_SYNC_FLUSH
|
||||
and Z_FINISH, but the current implementation actually flushes as much output
|
||||
as possible anyway.
|
||||
|
||||
inflate() should normally be called until it returns Z_STREAM_END or an
|
||||
error. However if all decompression is to be performed in a single step
|
||||
(a single call of inflate), the parameter flush should be set to
|
||||
Z_FINISH. In this case all pending input is processed and all pending
|
||||
output is flushed; avail_out must be large enough to hold all the
|
||||
uncompressed data. (The size of the uncompressed data may have been saved
|
||||
by the compressor for this purpose.) The next operation on this stream must
|
||||
be inflateEnd to deallocate the decompression state. The use of Z_FINISH
|
||||
is never required, but can be used to inform inflate that a faster routine
|
||||
may be used for the single inflate() call.
|
||||
|
||||
If a preset dictionary is needed at this point (see inflateSetDictionary
|
||||
below), inflate sets strm-adler to the adler32 checksum of the
|
||||
dictionary chosen by the compressor and returns Z_NEED_DICT; otherwise
|
||||
it sets strm->adler to the adler32 checksum of all output produced
|
||||
so far (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or
|
||||
an error code as described below. At the end of the stream, inflate()
|
||||
checks that its computed adler32 checksum is equal to that saved by the
|
||||
compressor and returns Z_STREAM_END only if the checksum is correct.
|
||||
|
||||
inflate() returns Z_OK if some progress has been made (more input processed
|
||||
or more output produced), Z_STREAM_END if the end of the compressed data has
|
||||
been reached and all uncompressed output has been produced, Z_NEED_DICT if a
|
||||
preset dictionary is needed at this point, Z_DATA_ERROR if the input data was
|
||||
corrupted (input stream not conforming to the zlib format or incorrect
|
||||
adler32 checksum), Z_STREAM_ERROR if the stream structure was inconsistent
|
||||
(for example if next_in or next_out was NULL), Z_MEM_ERROR if there was not
|
||||
enough memory, Z_BUF_ERROR if no progress is possible or if there was not
|
||||
enough room in the output buffer when Z_FINISH is used. In the Z_DATA_ERROR
|
||||
case, the application may then call inflateSync to look for a good
|
||||
compression block.
|
||||
*/
|
||||
|
||||
|
||||
ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm));
|
||||
/*
|
||||
All dynamically allocated data structures for this stream are freed.
|
||||
This function discards any unprocessed input and does not flush any
|
||||
pending output.
|
||||
|
||||
inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
|
||||
was inconsistent. In the error case, msg may be set but then points to a
|
||||
static string (which must not be deallocated).
|
||||
*/
|
||||
|
||||
/* Advanced functions */
|
||||
|
||||
/*
|
||||
The following functions are needed only in some special applications.
|
||||
*/
|
||||
|
||||
/*
|
||||
ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
|
||||
int level,
|
||||
int method,
|
||||
int windowBits,
|
||||
int memLevel,
|
||||
int strategy));
|
||||
|
||||
This is another version of deflateInit with more compression options. The
|
||||
fields next_in, zalloc, zfree and opaque must be initialized before by
|
||||
the caller.
|
||||
|
||||
The method parameter is the compression method. It must be Z_DEFLATED in
|
||||
this version of the library.
|
||||
|
||||
The windowBits parameter is the base two logarithm of the window size
|
||||
(the size of the history buffer). It should be in the range 8..15 for this
|
||||
version of the library. Larger values of this parameter result in better
|
||||
compression at the expense of memory usage. The default value is 15 if
|
||||
deflateInit is used instead.
|
||||
|
||||
The memLevel parameter specifies how much memory should be allocated
|
||||
for the internal compression state. memLevel=1 uses minimum memory but
|
||||
is slow and reduces compression ratio; memLevel=9 uses maximum memory
|
||||
for optimal speed. The default value is 8. See zconf.h for total memory
|
||||
usage as a function of windowBits and memLevel.
|
||||
|
||||
The strategy parameter is used to tune the compression algorithm. Use the
|
||||
value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
|
||||
filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman encoding only (no
|
||||
string match). Filtered data consists mostly of small values with a
|
||||
somewhat random distribution. In this case, the compression algorithm is
|
||||
tuned to compress them better. The effect of Z_FILTERED is to force more
|
||||
Huffman coding and less string matching; it is somewhat intermediate
|
||||
between Z_DEFAULT and Z_HUFFMAN_ONLY. The strategy parameter only affects
|
||||
the compression ratio but not the correctness of the compressed output even
|
||||
if it is not set appropriately.
|
||||
|
||||
deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
|
||||
memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid
|
||||
method). msg is set to null if there is no error message. deflateInit2 does
|
||||
not perform any compression: this will be done by deflate().
|
||||
*/
|
||||
|
||||
ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
|
||||
const Bytef *dictionary,
|
||||
uInt dictLength));
|
||||
/*
|
||||
Initializes the compression dictionary from the given byte sequence
|
||||
without producing any compressed output. This function must be called
|
||||
immediately after deflateInit, deflateInit2 or deflateReset, before any
|
||||
call of deflate. The compressor and decompressor must use exactly the same
|
||||
dictionary (see inflateSetDictionary).
|
||||
|
||||
The dictionary should consist of strings (byte sequences) that are likely
|
||||
to be encountered later in the data to be compressed, with the most commonly
|
||||
used strings preferably put towards the end of the dictionary. Using a
|
||||
dictionary is most useful when the data to be compressed is short and can be
|
||||
predicted with good accuracy; the data can then be compressed better than
|
||||
with the default empty dictionary.
|
||||
|
||||
Depending on the size of the compression data structures selected by
|
||||
deflateInit or deflateInit2, a part of the dictionary may in effect be
|
||||
discarded, for example if the dictionary is larger than the window size in
|
||||
deflate or deflate2. Thus the strings most likely to be useful should be
|
||||
put at the end of the dictionary, not at the front.
|
||||
|
||||
Upon return of this function, strm->adler is set to the Adler32 value
|
||||
of the dictionary; the decompressor may later use this value to determine
|
||||
which dictionary has been used by the compressor. (The Adler32 value
|
||||
applies to the whole dictionary even if only a subset of the dictionary is
|
||||
actually used by the compressor.)
|
||||
|
||||
deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
|
||||
parameter is invalid (such as NULL dictionary) or the stream state is
|
||||
inconsistent (for example if deflate has already been called for this stream
|
||||
or if the compression method is bsort). deflateSetDictionary does not
|
||||
perform any compression: this will be done by deflate().
|
||||
*/
|
||||
|
||||
ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
|
||||
z_streamp source));
|
||||
/*
|
||||
Sets the destination stream as a complete copy of the source stream.
|
||||
|
||||
This function can be useful when several compression strategies will be
|
||||
tried, for example when there are several ways of pre-processing the input
|
||||
data with a filter. The streams that will be discarded should then be freed
|
||||
by calling deflateEnd. Note that deflateCopy duplicates the internal
|
||||
compression state which can be quite large, so this strategy is slow and
|
||||
can consume lots of memory.
|
||||
|
||||
deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
|
||||
enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
|
||||
(such as zalloc being NULL). msg is left unchanged in both source and
|
||||
destination.
|
||||
*/
|
||||
|
||||
ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm));
|
||||
/*
|
||||
This function is equivalent to deflateEnd followed by deflateInit,
|
||||
but does not free and reallocate all the internal compression state.
|
||||
The stream will keep the same compression level and any other attributes
|
||||
that may have been set by deflateInit2.
|
||||
|
||||
deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
|
||||
stream state was inconsistent (such as zalloc or state being NULL).
|
||||
*/
|
||||
|
||||
ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
|
||||
int level,
|
||||
int strategy));
|
||||
/*
|
||||
Dynamically update the compression level and compression strategy. The
|
||||
interpretation of level and strategy is as in deflateInit2. This can be
|
||||
used to switch between compression and straight copy of the input data, or
|
||||
to switch to a different kind of input data requiring a different
|
||||
strategy. If the compression level is changed, the input available so far
|
||||
is compressed with the old level (and may be flushed); the new level will
|
||||
take effect only at the next call of deflate().
|
||||
|
||||
Before the call of deflateParams, the stream state must be set as for
|
||||
a call of deflate(), since the currently available input may have to
|
||||
be compressed and flushed. In particular, strm->avail_out must be non-zero.
|
||||
|
||||
deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source
|
||||
stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR
|
||||
if strm->avail_out was zero.
|
||||
*/
|
||||
|
||||
/*
|
||||
ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
|
||||
int windowBits));
|
||||
|
||||
This is another version of inflateInit with an extra parameter. The
|
||||
fields next_in, avail_in, zalloc, zfree and opaque must be initialized
|
||||
before by the caller.
|
||||
|
||||
The windowBits parameter is the base two logarithm of the maximum window
|
||||
size (the size of the history buffer). It should be in the range 8..15 for
|
||||
this version of the library. The default value is 15 if inflateInit is used
|
||||
instead. If a compressed stream with a larger window size is given as
|
||||
input, inflate() will return with the error code Z_DATA_ERROR instead of
|
||||
trying to allocate a larger window.
|
||||
|
||||
inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
|
||||
memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative
|
||||
memLevel). msg is set to null if there is no error message. inflateInit2
|
||||
does not perform any decompression apart from reading the zlib header if
|
||||
present: this will be done by inflate(). (So next_in and avail_in may be
|
||||
modified, but next_out and avail_out are unchanged.)
|
||||
*/
|
||||
|
||||
ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
|
||||
const Bytef *dictionary,
|
||||
uInt dictLength));
|
||||
/*
|
||||
Initializes the decompression dictionary from the given uncompressed byte
|
||||
sequence. This function must be called immediately after a call of inflate
|
||||
if this call returned Z_NEED_DICT. The dictionary chosen by the compressor
|
||||
can be determined from the Adler32 value returned by this call of
|
||||
inflate. The compressor and decompressor must use exactly the same
|
||||
dictionary (see deflateSetDictionary).
|
||||
|
||||
inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
|
||||
parameter is invalid (such as NULL dictionary) or the stream state is
|
||||
inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
|
||||
expected one (incorrect Adler32 value). inflateSetDictionary does not
|
||||
perform any decompression: this will be done by subsequent calls of
|
||||
inflate().
|
||||
*/
|
||||
|
||||
ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
|
||||
/*
|
||||
Skips invalid compressed data until a full flush point (see above the
|
||||
description of deflate with Z_FULL_FLUSH) can be found, or until all
|
||||
available input is skipped. No output is provided.
|
||||
|
||||
inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR
|
||||
if no more input was provided, Z_DATA_ERROR if no flush point has been found,
|
||||
or Z_STREAM_ERROR if the stream structure was inconsistent. In the success
|
||||
case, the application may save the current current value of total_in which
|
||||
indicates where valid compressed data was found. In the error case, the
|
||||
application may repeatedly call inflateSync, providing more input each time,
|
||||
until success or end of the input data.
|
||||
*/
|
||||
|
||||
ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));
|
||||
/*
|
||||
This function is equivalent to inflateEnd followed by inflateInit,
|
||||
but does not free and reallocate all the internal decompression state.
|
||||
The stream will keep attributes that may have been set by inflateInit2.
|
||||
|
||||
inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
|
||||
stream state was inconsistent (such as zalloc or state being NULL).
|
||||
*/
|
||||
|
||||
|
||||
/* utility functions */
|
||||
|
||||
/*
|
||||
The following utility functions are implemented on top of the
|
||||
basic stream-oriented functions. To simplify the interface, some
|
||||
default options are assumed (compression level and memory usage,
|
||||
standard memory allocation functions). The source code of these
|
||||
utility functions can easily be modified if you need special options.
|
||||
*/
|
||||
|
||||
ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen,
|
||||
const Bytef *source, uLong sourceLen));
|
||||
/*
|
||||
Compresses the source buffer into the destination buffer. sourceLen is
|
||||
the byte length of the source buffer. Upon entry, destLen is the total
|
||||
size of the destination buffer, which must be at least 0.1% larger than
|
||||
sourceLen plus 12 bytes. Upon exit, destLen is the actual size of the
|
||||
compressed buffer.
|
||||
This function can be used to compress a whole file at once if the
|
||||
input file is mmap'ed.
|
||||
compress returns Z_OK if success, Z_MEM_ERROR if there was not
|
||||
enough memory, Z_BUF_ERROR if there was not enough room in the output
|
||||
buffer.
|
||||
*/
|
||||
|
||||
ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen,
|
||||
const Bytef *source, uLong sourceLen,
|
||||
int level));
|
||||
/*
|
||||
Compresses the source buffer into the destination buffer. The level
|
||||
parameter has the same meaning as in deflateInit. sourceLen is the byte
|
||||
length of the source buffer. Upon entry, destLen is the total size of the
|
||||
destination buffer, which must be at least 0.1% larger than sourceLen plus
|
||||
12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
|
||||
|
||||
compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
|
||||
memory, Z_BUF_ERROR if there was not enough room in the output buffer,
|
||||
Z_STREAM_ERROR if the level parameter is invalid.
|
||||
*/
|
||||
|
||||
ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen,
|
||||
const Bytef *source, uLong sourceLen));
|
||||
/*
|
||||
Decompresses the source buffer into the destination buffer. sourceLen is
|
||||
the byte length of the source buffer. Upon entry, destLen is the total
|
||||
size of the destination buffer, which must be large enough to hold the
|
||||
entire uncompressed data. (The size of the uncompressed data must have
|
||||
been saved previously by the compressor and transmitted to the decompressor
|
||||
by some mechanism outside the scope of this compression library.)
|
||||
Upon exit, destLen is the actual size of the compressed buffer.
|
||||
This function can be used to decompress a whole file at once if the
|
||||
input file is mmap'ed.
|
||||
|
||||
uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
|
||||
enough memory, Z_BUF_ERROR if there was not enough room in the output
|
||||
buffer, or Z_DATA_ERROR if the input data was corrupted.
|
||||
*/
|
||||
|
||||
|
||||
typedef voidp gzFile;
|
||||
|
||||
ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
|
||||
/*
|
||||
Opens a gzip (.gz) file for reading or writing. The mode parameter
|
||||
is as in fopen ("rb" or "wb") but can also include a compression level
|
||||
("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for
|
||||
Huffman only compression as in "wb1h". (See the description
|
||||
of deflateInit2 for more information about the strategy parameter.)
|
||||
|
||||
gzopen can be used to read a file which is not in gzip format; in this
|
||||
case gzread will directly read from the file without decompression.
|
||||
|
||||
gzopen returns NULL if the file could not be opened or if there was
|
||||
insufficient memory to allocate the (de)compression state; errno
|
||||
can be checked to distinguish the two cases (if errno is zero, the
|
||||
zlib error is Z_MEM_ERROR). */
|
||||
|
||||
ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode));
|
||||
/*
|
||||
gzdopen() associates a gzFile with the file descriptor fd. File
|
||||
descriptors are obtained from calls like open, dup, creat, pipe or
|
||||
fileno (in the file has been previously opened with fopen).
|
||||
The mode parameter is as in gzopen.
|
||||
The next call of gzclose on the returned gzFile will also close the
|
||||
file descriptor fd, just like fclose(fdopen(fd), mode) closes the file
|
||||
descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode).
|
||||
gzdopen returns NULL if there was insufficient memory to allocate
|
||||
the (de)compression state.
|
||||
*/
|
||||
|
||||
ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
|
||||
/*
|
||||
Dynamically update the compression level or strategy. See the description
|
||||
of deflateInit2 for the meaning of these parameters.
|
||||
gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not
|
||||
opened for writing.
|
||||
*/
|
||||
|
||||
ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
|
||||
/*
|
||||
Reads the given number of uncompressed bytes from the compressed file.
|
||||
If the input file was not in gzip format, gzread copies the given number
|
||||
of bytes into the buffer.
|
||||
gzread returns the number of uncompressed bytes actually read (0 for
|
||||
end of file, -1 for error). */
|
||||
|
||||
ZEXTERN int ZEXPORT gzwrite OF((gzFile file,
|
||||
const voidp buf, unsigned len));
|
||||
/*
|
||||
Writes the given number of uncompressed bytes into the compressed file.
|
||||
gzwrite returns the number of uncompressed bytes actually written
|
||||
(0 in case of error).
|
||||
*/
|
||||
|
||||
ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...));
|
||||
/*
|
||||
Converts, formats, and writes the args to the compressed file under
|
||||
control of the format string, as in fprintf. gzprintf returns the number of
|
||||
uncompressed bytes actually written (0 in case of error).
|
||||
*/
|
||||
|
||||
ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s));
|
||||
/*
|
||||
Writes the given null-terminated string to the compressed file, excluding
|
||||
the terminating null character.
|
||||
gzputs returns the number of characters written, or -1 in case of error.
|
||||
*/
|
||||
|
||||
ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len));
|
||||
/*
|
||||
Reads bytes from the compressed file until len-1 characters are read, or
|
||||
a newline character is read and transferred to buf, or an end-of-file
|
||||
condition is encountered. The string is then terminated with a null
|
||||
character.
|
||||
gzgets returns buf, or Z_NULL in case of error.
|
||||
*/
|
||||
|
||||
ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c));
|
||||
/*
|
||||
Writes c, converted to an unsigned char, into the compressed file.
|
||||
gzputc returns the value that was written, or -1 in case of error.
|
||||
*/
|
||||
|
||||
ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
|
||||
/*
|
||||
Reads one byte from the compressed file. gzgetc returns this byte
|
||||
or -1 in case of end of file or error.
|
||||
*/
|
||||
|
||||
ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush));
|
||||
/*
|
||||
Flushes all pending output into the compressed file. The parameter
|
||||
flush is as in the deflate() function. The return value is the zlib
|
||||
error number (see function gzerror below). gzflush returns Z_OK if
|
||||
the flush parameter is Z_FINISH and all output could be flushed.
|
||||
gzflush should be called only when strictly necessary because it can
|
||||
degrade compression.
|
||||
*/
|
||||
|
||||
ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file,
|
||||
z_off_t offset, int whence));
|
||||
/*
|
||||
Sets the starting position for the next gzread or gzwrite on the
|
||||
given compressed file. The offset represents a number of bytes in the
|
||||
uncompressed data stream. The whence parameter is defined as in lseek(2);
|
||||
the value SEEK_END is not supported.
|
||||
If the file is opened for reading, this function is emulated but can be
|
||||
extremely slow. If the file is opened for writing, only forward seeks are
|
||||
supported; gzseek then compresses a sequence of zeroes up to the new
|
||||
starting position.
|
||||
|
||||
gzseek returns the resulting offset location as measured in bytes from
|
||||
the beginning of the uncompressed stream, or -1 in case of error, in
|
||||
particular if the file is opened for writing and the new starting position
|
||||
would be before the current position.
|
||||
*/
|
||||
|
||||
ZEXTERN int ZEXPORT gzrewind OF((gzFile file));
|
||||
/*
|
||||
Rewinds the given file. This function is supported only for reading.
|
||||
|
||||
gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET)
|
||||
*/
|
||||
|
||||
ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file));
|
||||
/*
|
||||
Returns the starting position for the next gzread or gzwrite on the
|
||||
given compressed file. This position represents a number of bytes in the
|
||||
uncompressed data stream.
|
||||
|
||||
gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR)
|
||||
*/
|
||||
|
||||
ZEXTERN int ZEXPORT gzeof OF((gzFile file));
|
||||
/*
|
||||
Returns 1 when EOF has previously been detected reading the given
|
||||
input stream, otherwise zero.
|
||||
*/
|
||||
|
||||
ZEXTERN int ZEXPORT gzclose OF((gzFile file));
|
||||
/*
|
||||
Flushes all pending output if necessary, closes the compressed file
|
||||
and deallocates all the (de)compression state. The return value is the zlib
|
||||
error number (see function gzerror below).
|
||||
*/
|
||||
|
||||
ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum));
|
||||
/*
|
||||
Returns the error message for the last error which occurred on the
|
||||
given compressed file. errnum is set to zlib error number. If an
|
||||
error occurred in the file system and not in the compression library,
|
||||
errnum is set to Z_ERRNO and the application may consult errno
|
||||
to get the exact error code.
|
||||
*/
|
||||
|
||||
/* checksum functions */
|
||||
|
||||
/*
|
||||
These functions are not related to compression but are exported
|
||||
anyway because they might be useful in applications using the
|
||||
compression library.
|
||||
*/
|
||||
|
||||
ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
|
||||
|
||||
/*
|
||||
Update a running Adler-32 checksum with the bytes buf[0..len-1] and
|
||||
return the updated checksum. If buf is NULL, this function returns
|
||||
the required initial value for the checksum.
|
||||
An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
|
||||
much faster. Usage example:
|
||||
|
||||
uLong adler = adler32(0L, Z_NULL, 0);
|
||||
|
||||
while (read_buffer(buffer, length) != EOF) {
|
||||
adler = adler32(adler, buffer, length);
|
||||
}
|
||||
if (adler != original_adler) error();
|
||||
*/
|
||||
|
||||
ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
|
||||
/*
|
||||
Update a running crc with the bytes buf[0..len-1] and return the updated
|
||||
crc. If buf is NULL, this function returns the required initial value
|
||||
for the crc. Pre- and post-conditioning (one's complement) is performed
|
||||
within this function so it shouldn't be done by the application.
|
||||
Usage example:
|
||||
|
||||
uLong crc = crc32(0L, Z_NULL, 0);
|
||||
|
||||
while (read_buffer(buffer, length) != EOF) {
|
||||
crc = crc32(crc, buffer, length);
|
||||
}
|
||||
if (crc != original_crc) error();
|
||||
*/
|
||||
|
||||
|
||||
/* various hacks, don't look :) */
|
||||
|
||||
/* deflateInit and inflateInit are macros to allow checking the zlib version
|
||||
* and the compiler's view of z_stream:
|
||||
*/
|
||||
ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level,
|
||||
const char *version, int stream_size));
|
||||
ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm,
|
||||
const char *version, int stream_size));
|
||||
ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method,
|
||||
int windowBits, int memLevel,
|
||||
int strategy, const char *version,
|
||||
int stream_size));
|
||||
ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits,
|
||||
const char *version, int stream_size));
|
||||
#define deflateInit(strm, level) \
|
||||
deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream))
|
||||
#define inflateInit(strm) \
|
||||
inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream))
|
||||
#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
|
||||
deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
|
||||
(strategy), ZLIB_VERSION, sizeof(z_stream))
|
||||
#define inflateInit2(strm, windowBits) \
|
||||
inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
|
||||
|
||||
|
||||
#if !defined(_Z_UTIL_H) && !defined(NO_DUMMY_DECL)
|
||||
struct internal_state {int dummy;}; /* hack for buggy compilers */
|
||||
#endif
|
||||
|
||||
ZEXTERN const char * ZEXPORT zError OF((int err));
|
||||
ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z));
|
||||
ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void));
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _ZLIB_H */
|
Двоичный файл не отображается.
Загрузка…
Ссылка в новой задаче