From 873dac92c4a8739a0dee0952b118d6c68cbfe082 Mon Sep 17 00:00:00 2001 From: "anthonyd%netscape.com" Date: Tue, 3 Dec 2002 21:52:45 +0000 Subject: [PATCH] *** 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. git-svn-id: svn://10.0.0.236/trunk@134725 18797224-902f-48f8-a5cc-f745e15eee43 --- .../tools/XPIPackager/FileChooserDlg.cpp | 154 ++ .../plugin/tools/XPIPackager/FileChooserDlg.h | 66 + .../tools/XPIPackager/MIMETypeChooseDlg.cpp | 86 + .../tools/XPIPackager/MIMETypeChooseDlg.h | 61 + .../plugin/tools/XPIPackager/StdAfx.cpp | 8 + .../modules/plugin/tools/XPIPackager/StdAfx.h | 26 + .../plugin/tools/XPIPackager/XPIPackager.cpp | 72 + .../plugin/tools/XPIPackager/XPIPackager.dsw | 29 + .../plugin/tools/XPIPackager/XPIPackager.h | 50 + .../plugin/tools/XPIPackager/XPIPackager.rc | 342 ++++ .../tools/XPIPackager/XPIPackagerDlg.cpp | 810 ++++++++++ .../plugin/tools/XPIPackager/XPIPackagerDlg.h | 95 ++ .../plugin/tools/XPIPackager/ZipArchive.cpp | 1381 +++++++++++++++++ .../plugin/tools/XPIPackager/ZipArchive.h | 698 +++++++++ .../plugin/tools/XPIPackager/ZipArchive.lib | Bin 0 -> 266574 bytes .../tools/XPIPackager/ZipArchiveDebug.lib | Bin 0 -> 506540 bytes .../tools/XPIPackager/ZipAutoBuffer.cpp | 104 ++ .../plugin/tools/XPIPackager/ZipAutoBuffer.h | 63 + .../plugin/tools/XPIPackager/ZipBigFile.cpp | 41 + .../plugin/tools/XPIPackager/ZipBigFile.h | 22 + .../tools/XPIPackager/ZipCentralDir.cpp | 677 ++++++++ .../plugin/tools/XPIPackager/ZipCentralDir.h | 156 ++ .../plugin/tools/XPIPackager/ZipException.cpp | 78 + .../plugin/tools/XPIPackager/ZipException.h | 71 + .../tools/XPIPackager/ZipFileHeader.cpp | 329 ++++ .../plugin/tools/XPIPackager/ZipFileHeader.h | 106 ++ .../tools/XPIPackager/ZipInternalInfo.cpp | 28 + .../tools/XPIPackager/ZipInternalInfo.h | 32 + .../plugin/tools/XPIPackager/ZipStorage.cpp | 428 +++++ .../plugin/tools/XPIPackager/ZipStorage.h | 134 ++ .../modules/plugin/tools/XPIPackager/body.js | 458 ++++++ .../plugin/tools/XPIPackager/filler.js | 23 + .../plugin/tools/XPIPackager/header.js | 22 + .../plugin/tools/XPIPackager/install.js | 505 ++++++ .../tools/XPIPackager/install_backup.js | 494 ++++++ .../plugin/tools/XPIPackager/resource.h | 51 + .../modules/plugin/tools/XPIPackager/zconf.h | 279 ++++ .../modules/plugin/tools/XPIPackager/zlib.h | 893 +++++++++++ .../modules/plugin/tools/XPIPackager/zlib.lib | Bin 0 -> 107376 bytes 39 files changed, 8872 insertions(+) create mode 100644 mozilla/modules/plugin/tools/XPIPackager/FileChooserDlg.cpp create mode 100644 mozilla/modules/plugin/tools/XPIPackager/FileChooserDlg.h create mode 100644 mozilla/modules/plugin/tools/XPIPackager/MIMETypeChooseDlg.cpp create mode 100644 mozilla/modules/plugin/tools/XPIPackager/MIMETypeChooseDlg.h create mode 100644 mozilla/modules/plugin/tools/XPIPackager/StdAfx.cpp create mode 100644 mozilla/modules/plugin/tools/XPIPackager/StdAfx.h create mode 100644 mozilla/modules/plugin/tools/XPIPackager/XPIPackager.cpp create mode 100644 mozilla/modules/plugin/tools/XPIPackager/XPIPackager.dsw create mode 100644 mozilla/modules/plugin/tools/XPIPackager/XPIPackager.h create mode 100644 mozilla/modules/plugin/tools/XPIPackager/XPIPackager.rc create mode 100644 mozilla/modules/plugin/tools/XPIPackager/XPIPackagerDlg.cpp create mode 100644 mozilla/modules/plugin/tools/XPIPackager/XPIPackagerDlg.h create mode 100644 mozilla/modules/plugin/tools/XPIPackager/ZipArchive.cpp create mode 100644 mozilla/modules/plugin/tools/XPIPackager/ZipArchive.h create mode 100644 mozilla/modules/plugin/tools/XPIPackager/ZipArchive.lib create mode 100644 mozilla/modules/plugin/tools/XPIPackager/ZipArchiveDebug.lib create mode 100644 mozilla/modules/plugin/tools/XPIPackager/ZipAutoBuffer.cpp create mode 100644 mozilla/modules/plugin/tools/XPIPackager/ZipAutoBuffer.h create mode 100644 mozilla/modules/plugin/tools/XPIPackager/ZipBigFile.cpp create mode 100644 mozilla/modules/plugin/tools/XPIPackager/ZipBigFile.h create mode 100644 mozilla/modules/plugin/tools/XPIPackager/ZipCentralDir.cpp create mode 100644 mozilla/modules/plugin/tools/XPIPackager/ZipCentralDir.h create mode 100644 mozilla/modules/plugin/tools/XPIPackager/ZipException.cpp create mode 100644 mozilla/modules/plugin/tools/XPIPackager/ZipException.h create mode 100644 mozilla/modules/plugin/tools/XPIPackager/ZipFileHeader.cpp create mode 100644 mozilla/modules/plugin/tools/XPIPackager/ZipFileHeader.h create mode 100644 mozilla/modules/plugin/tools/XPIPackager/ZipInternalInfo.cpp create mode 100644 mozilla/modules/plugin/tools/XPIPackager/ZipInternalInfo.h create mode 100644 mozilla/modules/plugin/tools/XPIPackager/ZipStorage.cpp create mode 100644 mozilla/modules/plugin/tools/XPIPackager/ZipStorage.h create mode 100644 mozilla/modules/plugin/tools/XPIPackager/body.js create mode 100644 mozilla/modules/plugin/tools/XPIPackager/filler.js create mode 100644 mozilla/modules/plugin/tools/XPIPackager/header.js create mode 100644 mozilla/modules/plugin/tools/XPIPackager/install.js create mode 100644 mozilla/modules/plugin/tools/XPIPackager/install_backup.js create mode 100644 mozilla/modules/plugin/tools/XPIPackager/resource.h create mode 100644 mozilla/modules/plugin/tools/XPIPackager/zconf.h create mode 100644 mozilla/modules/plugin/tools/XPIPackager/zlib.h create mode 100644 mozilla/modules/plugin/tools/XPIPackager/zlib.lib diff --git a/mozilla/modules/plugin/tools/XPIPackager/FileChooserDlg.cpp b/mozilla/modules/plugin/tools/XPIPackager/FileChooserDlg.cpp new file mode 100644 index 00000000000..9e990afd181 --- /dev/null +++ b/mozilla/modules/plugin/tools/XPIPackager/FileChooserDlg.cpp @@ -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(); +} diff --git a/mozilla/modules/plugin/tools/XPIPackager/FileChooserDlg.h b/mozilla/modules/plugin/tools/XPIPackager/FileChooserDlg.h new file mode 100644 index 00000000000..feca7cc00f1 --- /dev/null +++ b/mozilla/modules/plugin/tools/XPIPackager/FileChooserDlg.h @@ -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_) diff --git a/mozilla/modules/plugin/tools/XPIPackager/MIMETypeChooseDlg.cpp b/mozilla/modules/plugin/tools/XPIPackager/MIMETypeChooseDlg.cpp new file mode 100644 index 00000000000..b3ee4bca81d --- /dev/null +++ b/mozilla/modules/plugin/tools/XPIPackager/MIMETypeChooseDlg.cpp @@ -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(); +} diff --git a/mozilla/modules/plugin/tools/XPIPackager/MIMETypeChooseDlg.h b/mozilla/modules/plugin/tools/XPIPackager/MIMETypeChooseDlg.h new file mode 100644 index 00000000000..824afb523bf --- /dev/null +++ b/mozilla/modules/plugin/tools/XPIPackager/MIMETypeChooseDlg.h @@ -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_) diff --git a/mozilla/modules/plugin/tools/XPIPackager/StdAfx.cpp b/mozilla/modules/plugin/tools/XPIPackager/StdAfx.cpp new file mode 100644 index 00000000000..df18ed9597a --- /dev/null +++ b/mozilla/modules/plugin/tools/XPIPackager/StdAfx.cpp @@ -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" + + + diff --git a/mozilla/modules/plugin/tools/XPIPackager/StdAfx.h b/mozilla/modules/plugin/tools/XPIPackager/StdAfx.h new file mode 100644 index 00000000000..91d2a117fe5 --- /dev/null +++ b/mozilla/modules/plugin/tools/XPIPackager/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 // MFC core and standard components +#include // MFC extensions +#include // MFC support for Internet Explorer 4 Common Controls +#ifndef _AFX_NO_AFXCMN_SUPPORT +#include // 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_) diff --git a/mozilla/modules/plugin/tools/XPIPackager/XPIPackager.cpp b/mozilla/modules/plugin/tools/XPIPackager/XPIPackager.cpp new file mode 100644 index 00000000000..7380c8e5c80 --- /dev/null +++ b/mozilla/modules/plugin/tools/XPIPackager/XPIPackager.cpp @@ -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; +} diff --git a/mozilla/modules/plugin/tools/XPIPackager/XPIPackager.dsw b/mozilla/modules/plugin/tools/XPIPackager/XPIPackager.dsw new file mode 100644 index 00000000000..53ee8de4b14 --- /dev/null +++ b/mozilla/modules/plugin/tools/XPIPackager/XPIPackager.dsw @@ -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> +{{{ +}}} + +############################################################################### + diff --git a/mozilla/modules/plugin/tools/XPIPackager/XPIPackager.h b/mozilla/modules/plugin/tools/XPIPackager/XPIPackager.h new file mode 100644 index 00000000000..b1070ecbb4e --- /dev/null +++ b/mozilla/modules/plugin/tools/XPIPackager/XPIPackager.h @@ -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_) diff --git a/mozilla/modules/plugin/tools/XPIPackager/XPIPackager.rc b/mozilla/modules/plugin/tools/XPIPackager/XPIPackager.rc new file mode 100644 index 00000000000..b731bf53cb1 --- /dev/null +++ b/mozilla/modules/plugin/tools/XPIPackager/XPIPackager.rc @@ -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 + diff --git a/mozilla/modules/plugin/tools/XPIPackager/XPIPackagerDlg.cpp b/mozilla/modules/plugin/tools/XPIPackager/XPIPackagerDlg.cpp new file mode 100644 index 00000000000..132d8747de6 --- /dev/null +++ b/mozilla/modules/plugin/tools/XPIPackager/XPIPackagerDlg.cpp @@ -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; +} diff --git a/mozilla/modules/plugin/tools/XPIPackager/XPIPackagerDlg.h b/mozilla/modules/plugin/tools/XPIPackager/XPIPackagerDlg.h new file mode 100644 index 00000000000..efbee8119b7 --- /dev/null +++ b/mozilla/modules/plugin/tools/XPIPackager/XPIPackagerDlg.h @@ -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_) diff --git a/mozilla/modules/plugin/tools/XPIPackager/ZipArchive.cpp b/mozilla/modules/plugin/tools/XPIPackager/ZipArchive.cpp new file mode 100644 index 00000000000..ccff2a45456 --- /dev/null +++ b/mozilla/modules/plugin/tools/XPIPackager/ZipArchive.cpp @@ -0,0 +1,1381 @@ +// ZipArchive.cpp: implementation of the CZipArchive class. +// +//////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2000 Tadeusz Dracz. +// For conditions of distribution and use, see copyright notice in ZipArchive.h +//////////////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "ZipArchive.h" +#include +#include // for qsort + + +#ifndef DEF_MEM_LEVEL +#if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +#else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +#endif +#endif +#define ENCR_HEADER_LEN 12 +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// +TCHAR CZipArchive::m_gszCopyright[] = {_T("Zip archive creation and modification Copyright 2000 Tadeusz Dracz")}; +CZipArchive::CZipArchive() +{ + m_bDetectZlibMemoryLeaks = true; + m_centralDir.m_pStorage= &m_storage; + m_info.m_stream.zalloc = (alloc_func)myalloc; + m_info.m_stream.zfree = (free_func)myfree; + m_iFileOpened = nothing; +} + + +CZipArchive::~CZipArchive() +{ + // Close(); // cannot be here: if an exception is thrown strange things can happen + EmptyPtrList(); +} + +void CZipArchive::Open(LPCTSTR szPathName, int iMode, int iVolumeSize) +{ + if (!IsClosed()) + { + TRACE(_T("ZipArchive already opened.\n")); + return; + } + m_pszPassword.Release(); + m_iFileOpened = nothing; + m_storage.Open(szPathName, iMode, iVolumeSize); + m_centralDir.Init(); + if ((iMode == open) ||(iMode == openReadOnly)) + m_centralDir.Read(); +} + +void CZipArchive::Open(CMemFile& mf, int iMode) +{ + if (!IsClosed()) + { + TRACE(_T("ZipArchive already opened.\n")); + return; + } + if (iMode != open && iMode != openReadOnly && iMode != create) + { + TRACE(_T("Mode not supported.\n")); + return; + } + m_pszPassword.Release(); + m_iFileOpened = nothing; + m_storage.Open(mf, iMode); + m_centralDir.Init(); + if ((iMode == open) ||(iMode == openReadOnly)) + m_centralDir.Read(); +} + + +bool CZipArchive::IsClosed(bool bArchive) +{ + return bArchive ?(m_storage.GetCurrentDisk() == -1):(!m_storage.m_pFile || m_storage.m_pFile->m_hFile == CFile::hFileNull); +} + + +void CZipArchive::ThrowError(int err) +{ + AfxThrowZipException(err, IsClosed() ? _T("") : m_storage.m_pFile->GetFilePath()); +} + +bool CZipArchive::DeleteFile(WORD uIndex) +{ + if (m_storage.IsSpanMode()) + { + TRACE(_T("You cannot delete files from the disk spannig archive.\n")); + return false; + } + + if (m_iFileOpened) + { + TRACE(_T("You cannot delete files if there is a file opened.\n")); + return false; + } + + if (!m_centralDir.IsValidIndex(uIndex)) + return false; + + m_info.Init(); + m_centralDir.RemoveFromDisk(); + DeleteInternal(uIndex); + m_info.m_pBuffer.Release(); + return true; +} + +int CZipArchive::GetNoEntries() +{ + return m_centralDir.m_headers.GetSize(); +} + + +bool CZipArchive::GetFileInfo(CZipFileHeader & fhInfo, WORD uIndex) +{ + if (IsClosed()) + { + TRACE(_T("ZipArchive is closed.\n")); + return false; + } + + if (!m_centralDir.IsValidIndex(uIndex)) + return false; + + fhInfo = *(m_centralDir.m_headers[uIndex]); + m_centralDir.ConvertFileName(true, false, &fhInfo); + return true; +} + +int CZipArchive::FindFile(CString szFileName, bool bCaseSensitive) +{ + if (IsClosed()) + { + TRACE(_T("ZipArchive is closed.\n")); + return (int)-1; + } + // this is required for fast finding and is done only once + if (!m_centralDir.m_bConvertAfterOpen) + { + TRACE(_T("Converting all filenames.")); + m_centralDir.ConvertAll(); + } + if (!m_centralDir.m_bFindFastEnabled) + EnableFindFast(); + int iResult = m_centralDir.FindFileNameIndex(szFileName, bCaseSensitive); + return iResult == -1 ? -1 : m_centralDir.m_findarray[iResult].m_uIndex; +} + +bool CZipArchive::OpenFile(WORD uIndex) +{ + if (!m_centralDir.IsValidIndex(uIndex)) + return false; + + if (m_storage.IsSpanMode() == 1) + { + TRACE(_T("You cannot extract from the span in creation.\n")); + return false; + } + + + if (m_iFileOpened) + { + TRACE(_T("A file already opened.\n")); + return false; + } + + m_info.Init(); + m_centralDir.OpenFile(uIndex); + if (CurrentFile()->IsEncrypted()) + { + + if (m_pszPassword.GetSize() == 0) + { + TRACE(_T("Password not set for the encrypted file.\n")); + return false; + } + CryptInitKeys(); + if (!CryptCheck()) + ThrowError(ZIP_BADPASSWORD); // invalid password + + } + else if (m_pszPassword.GetSize() != 0) + { + TRACE(_T("Password set for a not encrypted file. Ignoring password.\n")); + } + + WORD uMethod = CurrentFile()->m_uMethod; + if ((uMethod != 0) &&(uMethod != Z_DEFLATED)) + ThrowError(ZIP_BADZIPFILE); + + if (uMethod == Z_DEFLATED) + { + m_info.m_stream.opaque = m_bDetectZlibMemoryLeaks ? &m_list : 0; + int err = inflateInit2(&m_info.m_stream, -MAX_WBITS); + // * windowBits is passed < 0 to tell that there is no zlib header. + // * Note that in this case inflate *requires* an extra "dummy" byte + // * after the compressed stream in order to complete decompression and + // * return Z_STREAM_END. + CheckForError(err); + } + m_info.m_uComprLeft = CurrentFile()->m_uComprSize; + if (CurrentFile()->IsEncrypted()) + m_info.m_uComprLeft -= ENCR_HEADER_LEN; + m_info.m_uUncomprLeft = CurrentFile()->m_uUncomprSize; + m_info.m_uCrc32 = 0; + m_info.m_stream.total_out = 0; + m_info.m_stream.avail_in = 0; + + m_iFileOpened = extract; + return true; +} + + +int CZipArchive::GetLocalExtraField(char *pBuf, int iSize) +{ + if (IsClosed()) + { + TRACE(_T("ZipArchive is closed.\n")); + return -1; + } + + if (m_iFileOpened != extract) + { + TRACE(_T("A file must be opened to get the local extra field.\n")); + return -1; + } + + int size = m_centralDir.m_pLocalExtraField.GetSize(); + if (!pBuf|| !size) + return size; + + if (iSize < size) + size = iSize; + + memcpy(pBuf, m_centralDir.m_pLocalExtraField, size); + return size; +} + +void* CZipArchive::myalloc(void* opaque, UINT items, UINT size) +{ + void* p = new char[size * items]; + if (opaque) + { + CPtrList* list = (CPtrList*) opaque; + list->AddTail(p); + } + return p; +} + +void CZipArchive::myfree(void* opaque, void* address) +{ + if (opaque) + { + CPtrList* list = (CPtrList*) opaque; + POSITION pos = list->Find(address); + if (pos) + list->RemoveAt(pos); + } + delete[] address; +} + +void CZipArchive::CheckForError(int iErr) +{ + if ((iErr == Z_OK) ||(iErr == Z_NEED_DICT)) + return; + + ThrowError(iErr); +} + +CZipFileHeader* CZipArchive::CurrentFile() +{ + ASSERT(m_centralDir.m_pOpenedFile); + return m_centralDir.m_pOpenedFile; +} + +DWORD CZipArchive::ReadFile(void *pBuf, DWORD iSize) +{ + if (m_iFileOpened != extract) + { + TRACE(_T("Current file must be opened.\n")); + return 0; + } + + if (!pBuf || !iSize) + return 0; + + m_info.m_stream.next_out = (Bytef*)pBuf; + m_info.m_stream.avail_out = iSize > m_info.m_uUncomprLeft + ? m_info.m_uUncomprLeft : iSize; + + + DWORD iRead = 0; + + // may happen when the file is 0 sized + bool bForce = m_info.m_stream.avail_out == 0 && m_info.m_uComprLeft > 0; + while (m_info.m_stream.avail_out > 0 || (bForce && m_info.m_uComprLeft > 0)) + { + if ((m_info.m_stream.avail_in == 0) && + (m_info.m_uComprLeft > 0)) + { + DWORD uToRead = m_info.m_pBuffer.GetSize(); + if (m_info.m_uComprLeft < uToRead) + uToRead = m_info.m_uComprLeft; + + if (uToRead == 0) + return 0; + + m_storage.Read(m_info.m_pBuffer, uToRead, false); + CryptDecodeBuffer(uToRead); + m_info.m_uComprLeft -= uToRead; + + m_info.m_stream.next_in = (unsigned char*)(char*)m_info.m_pBuffer; + m_info.m_stream.avail_in = uToRead; + } + + if (CurrentFile()->m_uMethod == 0) + { + DWORD uToCopy = m_info.m_stream.avail_out < m_info.m_stream.avail_in + ? m_info.m_stream.avail_out : m_info.m_stream.avail_in; + + memcpy(m_info.m_stream.next_out, m_info.m_stream.next_in, uToCopy); + + m_info.m_uCrc32 = crc32(m_info.m_uCrc32, m_info.m_stream.next_out, uToCopy); + + m_info.m_uUncomprLeft -= uToCopy; + m_info.m_stream.avail_in -= uToCopy; + m_info.m_stream.avail_out -= uToCopy; + m_info.m_stream.next_out += uToCopy; + m_info.m_stream.next_in += uToCopy; + m_info.m_stream.total_out += uToCopy; + iRead += uToCopy; + } + else + { + DWORD uTotal = m_info.m_stream.total_out; + Bytef* pOldBuf = m_info.m_stream.next_out; + int err = inflate(&m_info.m_stream, Z_SYNC_FLUSH); + DWORD uToCopy = m_info.m_stream.total_out - uTotal; + + m_info.m_uCrc32 = crc32(m_info.m_uCrc32, pOldBuf, uToCopy); + + m_info.m_uUncomprLeft -= uToCopy; + iRead += uToCopy; + + if (err == Z_STREAM_END) + return iRead; + + CheckForError(err); + } + } + + return iRead; +} + +void CZipArchive::Close(bool bAfterException) +{ + // if after an exception - the archive may be closed, but the file may be opened + if (IsClosed() && (!bAfterException || IsClosed(false))) + { + TRACE(_T("ZipArchive is already closed.\n")); + return; + } + + if (!bAfterException) + { + if (m_iFileOpened == extract) + CloseFile(NULL); + + if (m_iFileOpened == compress) + CloseNewFile(); + + // write central directory + m_centralDir.Write(); + } + else + { + m_info.m_pBuffer.Release(); + m_iFileOpened = nothing; + EmptyPtrList(); + } + + m_centralDir.Clear(); + m_storage.Close(bAfterException); +} + +void CZipArchive::SetSpanCallback(ZIPCALLBACKFUN pFunc, void* pData) +{ + m_storage.m_pZIPCALLBACKFUN = pFunc; + m_storage.m_pCallbackData = pData; +} + +void CZipArchive::SetAdvanced(int iWriteBuffer, int iExtractBuffer, int iSearchBuffer) +{ + if (!IsClosed()) + { + TRACE(_T("Set this options before opening the archive.\n")); + return; + } + + m_storage.m_iWriteBufferSize = iWriteBuffer < 1024 ? 1024 : iWriteBuffer; + m_centralDir.m_iBufferSize = iSearchBuffer < 1024 ? 1024 : iSearchBuffer; + m_info.m_iBufferSize = iExtractBuffer < 1024 ? 1024 : iExtractBuffer; +} + +int CZipArchive::CloseFile(CFile &file) +{ + CString temp = file.GetFilePath(); + file.Close(); + return CloseFile(temp); +} + +int CZipArchive::CloseFile(LPCTSTR lpszFilePath, bool bAfterException) +{ + if (m_iFileOpened != extract) + { + TRACE(_T("No opened file.\n")); + return false; + } + + int iRet = 1; + if (!bAfterException) + { + if (m_info.m_uUncomprLeft == 0) + { + if (m_info.m_uCrc32 != CurrentFile()->m_uCrc32) + ThrowError(ZIP_BADCRC); + } + else + iRet = -1; + + + if (CurrentFile()->m_uMethod == Z_DEFLATED) + inflateEnd(&m_info.m_stream); + + + if (lpszFilePath) + { + try + { + CFileStatus fs; + fs.m_ctime = fs.m_atime = CTime::GetCurrentTime(); + fs.m_attribute = 0; + fs.m_mtime = CurrentFile()->GetTime(); + CFile::SetStatus(lpszFilePath, fs); + if (SetFileAttributes(lpszFilePath, CurrentFile()->m_uExternalAttr) == 0) + iRet = -2; + } + catch (CException* e) + { + e->Delete(); + return false; + } + } + } + m_centralDir.CloseFile(); + m_iFileOpened = nothing; + m_info.m_pBuffer.Release(); + EmptyPtrList(); + return iRet; +} + +bool CZipArchive::OpenNewFile(CZipFileHeader & header, int iLevel, LPCTSTR lpszFilePath) +{ + if (IsClosed()) + { + TRACE(_T("ZipArchive is closed.\n")); + return false; + } + + if (m_iFileOpened) + { + TRACE(_T("A file already opened.\n")); + return false; + } + + if (m_storage.IsSpanMode() == -1) + { + TRACE(_T("You cannot add the files to the existing disk spannig archive.\n")); + return false; + } + + if (GetNoEntries() ==(WORD)USHRT_MAX) + { + TRACE(_T("Maximum file count inside archive reached.\n")); + return false; + } + + + if (lpszFilePath) + { + bool bRet = true; + CFileStatus fs; + if (!CFile::GetStatus(lpszFilePath, fs)) + bRet = false; + else + { + header.SetTime(fs.m_mtime); + header.m_uExternalAttr = ::GetFileAttributes(lpszFilePath); // mfc bug: m_attribute is 1-byte + if (header.m_uExternalAttr == -1) + bRet = false; + } + + if (!bRet) + // do not continue - if the file was a directory then not recognizing it will cause + // serious errors + return false; + } + + m_info.Init(); + m_centralDir.AddNewFile(header); + + CString szFileName = CurrentFile()->GetFileName(); + + if (szFileName.IsEmpty()) + { + szFileName.Format(_T("file%i"), GetNoEntries());; + CurrentFile()->SetFileName(szFileName); + } + // this ensures the conversion will take place anyway (must take because we are going + // to write the local header in a moment + m_centralDir.ConvertFileName(false, m_centralDir.m_bConvertAfterOpen); + + + bool bIsDirectory = IsDirectory(CurrentFile()->m_uExternalAttr); + bool bEncrypted = m_pszPassword.GetSize() != 0; +#ifdef _DEBUG + if (bIsDirectory && bEncrypted) + TRACE(_T("Warning! Encrypting a directory. Possible but pointless.\n\ + Clear the password before adding a directory.\n")); +#endif + + + if (!CurrentFile()->PrepareData(iLevel, m_storage.IsSpanMode() == 1, bEncrypted)) + ThrowError(ZIP_TOOLONGFILENAME); + + CurrentFile()->WriteLocal(m_storage); + // we have written the local header, but if we keep filenames not converted + // in memory , we have to restore the non-converted value + if (m_centralDir.m_bConvertAfterOpen) + CurrentFile()->SetFileName(szFileName); + if (bEncrypted) + { + CZipAutoBuffer buf(ENCR_HEADER_LEN); + // use pseudo-crc since we don't know it yet + CryptCryptHeader((long)header.m_uModTime << 16, buf); + m_storage.Write(buf, ENCR_HEADER_LEN, false); + } + + + m_info.m_uComprLeft = 0; + m_info.m_stream.avail_in = (uInt)0; + m_info.m_stream.avail_out = (uInt)m_info.m_pBuffer.GetSize(); + m_info.m_stream.next_out = (unsigned char*)(char*)m_info.m_pBuffer; + m_info.m_stream.total_in = 0; + m_info.m_stream.total_out = 0; + + if (bIsDirectory && (CurrentFile()->m_uMethod != 0)) + CurrentFile()->m_uMethod = 0; + + if (CurrentFile()->m_uMethod == Z_DEFLATED) + { + m_info.m_stream.opaque = m_bDetectZlibMemoryLeaks ? &m_list : 0; + + int err = deflateInit2(&m_info.m_stream, iLevel, + Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY); + + CheckForError(err); + } + m_iFileOpened = compress; + return true; +} + +CString CZipArchive::GetFilePath(LPCTSTR lpszFilePath) +{ + TCHAR szDir[_MAX_DIR]; + TCHAR szDrive[_MAX_DRIVE]; + _tsplitpath(lpszFilePath, szDrive, szDir, NULL, NULL); + return CString(szDrive) + CString(szDir); +} + +CString CZipArchive::GetFileExt(LPCTSTR lpszFilePath) +{ + TCHAR szExt[_MAX_EXT]; + _tsplitpath(lpszFilePath, NULL, NULL, NULL, szExt); + return CString(szExt); +} + +CString CZipArchive::GetFileTitle(LPCTSTR lpszFilePath) +{ + TCHAR szFname[_MAX_FNAME]; + _tsplitpath(lpszFilePath, NULL, NULL, szFname, NULL); + return CString(szFname); +} + +CString CZipArchive::GetFileDirAndName(LPCTSTR lpszFilePath) +{ + TCHAR szDir[_MAX_DIR]; + TCHAR szFname[_MAX_FNAME]; + TCHAR szExt[_MAX_EXT]; + _tsplitpath(lpszFilePath, NULL , szDir, szFname, szExt); + CString Dir = szDir; + Dir.TrimLeft(_T("\\")); + return Dir + szFname + szExt; +} + + +CString CZipArchive::GetFileName(LPCTSTR lpszFilePath) +{ + TCHAR szExt[_MAX_EXT]; + TCHAR szName[_MAX_FNAME]; + _tsplitpath(lpszFilePath, NULL, NULL, szName, szExt); + return CString(szName) + CString(szExt); +} + +bool CZipArchive::ForceDirectory(LPCTSTR lpDirectory) +{ + ASSERT(lpDirectory); + CString szDirectory = lpDirectory; + szDirectory.TrimRight(_T("\\")); + if ((GetFilePath(szDirectory) == szDirectory) || + (FileExists(szDirectory) == -1)) + return true; + if (!ForceDirectory(GetFilePath(szDirectory))) + return false; + if (!CreateDirectory(szDirectory, NULL)) + return false; + return true; +} + +int CZipArchive::FileExists(LPCTSTR lpszName) +{ + CFileFind fileFind; + if (!fileFind.FindFile(lpszName)) + { + if (DirectoryExists(lpszName)) // if root ex. "C:\" + return -1; + return 0; + } + fileFind.FindNextFile(); + return fileFind.IsDirectory() ? -1 : 1; +} + +bool CZipArchive::DirectoryExists(LPCTSTR lpszDir) +{ + TCHAR curPath[_MAX_PATH]; /* Get the current working directory: */ + if (!_tgetcwd(curPath, _MAX_PATH)) + return false; + if (_tchdir(lpszDir)) // retruns 0 if error + return false; + _tchdir(curPath); + return true; +} + +bool CZipArchive::IsFileDirectory(WORD uIndex) +{ + if (IsClosed()) + { + TRACE(_T("ZipArchive is closed.\n")); + return false; + } + + if (!m_centralDir.IsValidIndex(uIndex)) + return false; + + return IsDirectory(m_centralDir.m_headers[uIndex]->m_uExternalAttr); +} +bool CZipArchive::ExtractFile(WORD uIndex, + LPCTSTR lpszPath, + bool bFullPath, + LPCTSTR lpszNewName, + ZIPCALLBACKFUN pCallback, + void* pUserData, + DWORD nBufSize) +{ + if (!nBufSize && !lpszPath) + return false; + + CZipFileHeader header; + GetFileInfo(header, uIndex); // to ensure that slash and oem conversions take place + CString szFile = lpszPath, szFileName = lpszNewName ? lpszNewName : header.GetFileName(); + szFile.TrimRight(_T("\\")); + szFile += _T("\\") + (bFullPath ? GetFileDirAndName(szFileName) + : GetFileName(szFileName)); // just in case in the archive there are file names with drives + + if (IsFileDirectory(uIndex)) + { + ForceDirectory(szFile); + SetFileAttributes(szFile, header.m_uExternalAttr); + return true; + } + else + { + if (!OpenFile(uIndex)) + return false; + + ForceDirectory(GetFilePath(szFile)); + CFile f(szFile, CFile::modeWrite | CFile::modeCreate | CFile::shareDenyWrite); + DWORD iRead, iFileLength = pCallback ? header.GetSize() : 0, iSoFar = 0; + CZipAutoBuffer buf(nBufSize); + do + { + iRead = ReadFile(buf, buf.GetSize()); + if (iRead) + { + f.Write(buf, iRead); + iSoFar += iRead; + if (pCallback) + if (!pCallback(iFileLength, iSoFar, pUserData)) + break; + } + } + while (iRead == buf.GetSize()); + return CloseFile(f) == 1; + } +} + +void CZipArchive::SetExtraField(char *pBuf, WORD iSize) +{ + if (m_iFileOpened != compress) + { + TRACE(_T("A new file must be opened.\n")); + return; + } + if (!pBuf || !iSize) + return; + + CurrentFile()->m_pExtraField.Allocate(iSize); + memcpy(CurrentFile()->m_pExtraField, pBuf, iSize); +} + +bool CZipArchive::WriteNewFile(void *pBuf, DWORD iSize) +{ + if (m_iFileOpened != compress) + { + TRACE(_T("A new file must be opened.\n")); + return false; + } + + + m_info.m_stream.next_in = (unsigned char*)pBuf; + m_info.m_stream.avail_in = iSize; + CurrentFile()->m_uCrc32 = crc32(CurrentFile()->m_uCrc32, (unsigned char*)pBuf, iSize); + + + while (m_info.m_stream.avail_in > 0) + { + if (m_info.m_stream.avail_out == 0) + { + CryptEncodeBuffer(); + m_storage.Write(m_info.m_pBuffer, m_info.m_uComprLeft, false); + m_info.m_uComprLeft = 0; + m_info.m_stream.avail_out = m_info.m_pBuffer.GetSize(); + m_info.m_stream.next_out = (unsigned char*)(char*)m_info.m_pBuffer; + } + + if (CurrentFile()->m_uMethod == Z_DEFLATED) + { + DWORD uTotal = m_info.m_stream.total_out; + int err = deflate(&m_info.m_stream, Z_NO_FLUSH); + CheckForError(err); + m_info.m_uComprLeft += m_info.m_stream.total_out - uTotal; + } + else + { + DWORD uToCopy = (m_info.m_stream.avail_in < m_info.m_stream.avail_out) + ? m_info.m_stream.avail_in : m_info.m_stream.avail_out; + + memcpy(m_info.m_stream.next_out, m_info.m_stream.next_in, uToCopy); + + m_info.m_stream.avail_in -= uToCopy; + m_info.m_stream.avail_out -= uToCopy; + m_info.m_stream.next_in += uToCopy; + m_info.m_stream.next_out += uToCopy; + m_info.m_stream.total_in += uToCopy; + m_info.m_stream.total_out += uToCopy; + m_info.m_uComprLeft += uToCopy; + } + } + + return true; +} + +bool CZipArchive::CloseNewFile() +{ + if (m_iFileOpened != compress) + { + TRACE(_T("A new file must be opened.\n")); + return false; + } + + m_info.m_stream.avail_in = 0; + + int err = Z_OK; + if (CurrentFile()->m_uMethod == Z_DEFLATED) + while (err == Z_OK) + { + if (m_info.m_stream.avail_out == 0) + { + CryptEncodeBuffer(); + m_storage.Write(m_info.m_pBuffer, m_info.m_uComprLeft, false); + m_info.m_uComprLeft = 0; + m_info.m_stream.avail_out = m_info.m_pBuffer.GetSize(); + m_info.m_stream.next_out = (unsigned char*)(char*)m_info.m_pBuffer; + } + DWORD uTotal = m_info.m_stream.total_out; + err = deflate(&m_info.m_stream, Z_FINISH); + m_info.m_uComprLeft += m_info.m_stream.total_out - uTotal; + } + + if (err == Z_STREAM_END) + err = Z_OK; + CheckForError(err); + + if (m_info.m_uComprLeft > 0) + { + CryptEncodeBuffer(); + m_storage.Write(m_info.m_pBuffer, m_info.m_uComprLeft, false); + } + + if (CurrentFile()->m_uMethod == Z_DEFLATED) + { + err = deflateEnd(&m_info.m_stream); + CheckForError(err); + } + + + // it may be increased by the encrypted header size + CurrentFile()->m_uComprSize += m_info.m_stream.total_out; + CurrentFile()->m_uUncomprSize = m_info.m_stream.total_in; + + m_centralDir.CloseNewFile(); + m_iFileOpened = nothing; + m_info.m_pBuffer.Release(); + return true; +} + +void CZipArchive::DeleteFiles(CStringArray &aNames, bool bCaseSensitive) +{ + CWordArray indexes; + + for (WORD i = 0; i < GetNoEntries(); i++) + { + CZipFileHeader fh; + GetFileInfo(fh, i); + CString szFileName = fh.GetFileName(); + for (int j = 0; j < aNames.GetSize(); j++) + { + bool bEqual = (bCaseSensitive ? aNames[j].Collate(szFileName) + : aNames[j].CollateNoCase(szFileName)) == 0; + if (bEqual) + { + indexes.Add(i); + break; + } + } + } + + DeleteFiles(indexes); +} + + +void CZipArchive::DeleteFiles(CWordArray &aIndexes) +{ + if (IsClosed()) + { + TRACE(_T("ZipArchive is closed.\n")); + return; + } + + if (m_storage.IsSpanMode()) + { + TRACE(_T("You cannot delete files from the disk spannig archive.\n")); + return; + } + + if (m_iFileOpened) + { + TRACE(_T("You cannot delete files if there is a file opened.\n")); + return; + } + + // sorting the index table using qsort + int uSize = aIndexes.GetSize(); + if (!uSize) + return; + qsort((void*)&aIndexes[0], uSize, sizeof(WORD), CompareWords); + + m_centralDir.RemoveFromDisk(); + + m_info.Init(); + // remove in a reverse order + for (int i = uSize - 1; i >= 0; i--) + DeleteInternal(aIndexes[i]); + m_info.m_pBuffer.Release(); +} + +DWORD CZipArchive::RemovePackedFile(DWORD uStartOffset, DWORD uEndOffset) +{ + uStartOffset += m_centralDir.m_uBytesBeforeZip; + uEndOffset += m_centralDir.m_uBytesBeforeZip; + DWORD BytesToCopy = m_storage.m_pFile->GetLength() - uEndOffset; + DWORD uTotalToWrite = BytesToCopy; + + char* buf = (char*)m_info.m_pBuffer; + if (BytesToCopy > m_info.m_pBuffer.GetSize()) + BytesToCopy = m_info.m_pBuffer.GetSize(); + + + + DWORD TotalWritten = 0; + DWORD size_read; + + do + { + m_storage.m_pFile->Seek(uEndOffset + TotalWritten, CFile::begin); + size_read = m_storage.m_pFile->Read(buf, BytesToCopy); + if (size_read > 0) + { + m_storage.m_pFile->Seek(uStartOffset + TotalWritten, CFile::begin); + m_storage.m_pFile->Write(buf, size_read); + } + TotalWritten += size_read; + } + while (size_read == BytesToCopy); + if (uTotalToWrite != TotalWritten) + ThrowError(CZipException::generic); + DWORD uRemoved = (uEndOffset - uStartOffset); + m_storage.m_pFile->SetLength(m_storage.m_pFile->GetLength() - uRemoved); + return uRemoved; +} + + +void CZipArchive::DeleteInternal(WORD uIndex) +{ + CZipFileHeader* pfh = m_centralDir.m_headers[uIndex]; + DWORD uOtherOffsetChanged = 0; + + if (uIndex == GetNoEntries() - 1) // last entry or the only one entry + m_storage.m_pFile->SetLength(pfh->m_uOffset + m_centralDir.m_uBytesBeforeZip); + else + uOtherOffsetChanged = RemovePackedFile(pfh->m_uOffset, m_centralDir.m_headers[uIndex + 1]->m_uOffset); + + + m_centralDir.RemoveFile(uIndex); + + // teraz uaktualnij offsety w pozosta³ych pozycjach central dir + // (update offsets in file headers in the central dir) + if (uOtherOffsetChanged) + for (int i = uIndex; i < GetNoEntries(); i++) + m_centralDir.m_headers[i]->m_uOffset -= uOtherOffsetChanged; +} + +bool CZipArchive::IsDriveRemovable(LPCTSTR lpszFilePath) +{ + return GetDriveType(GetDrive(lpszFilePath)) == DRIVE_REMOVABLE; +} + +CString CZipArchive::GetDrive(LPCTSTR lpszFilePath) +{ + TCHAR szDrive[_MAX_DRIVE]; + _tsplitpath(lpszFilePath, szDrive, NULL, NULL, NULL); + return szDrive; +} + +bool CZipArchive::AddNewFile(LPCTSTR lpszFilePath, + int iLevel, + bool bFullPath, + ZIPCALLBACKFUN pCallback, + void* pUserData, + unsigned long nBufSize) +{ + if (!nBufSize) + return false; + + CZipFileHeader header; + header.SetFileName(bFullPath ? GetFileDirAndName(lpszFilePath) : GetFileName(lpszFilePath)); + if (header.GetFileNameSize() == 0) + return false; + if (!OpenNewFile(header, iLevel, lpszFilePath)) + return false; + + if (!IsDirectory(header.m_uExternalAttr)) + { + CFile f; + CFileException* e = new CFileException; + BOOL bRet = f.Open(lpszFilePath, CFile::modeRead | CFile::shareDenyWrite, e); + e->Delete(); + if (!bRet) + return false; + + DWORD iRead, iFileLength = pCallback ? f.GetLength() : 0, iSoFar = 0; + CZipAutoBuffer buf(nBufSize); + do + { + iRead = f.Read(buf, nBufSize); + if (iRead) + { + WriteNewFile(buf, iRead); + iSoFar += iRead; + if (pCallback) + if (!pCallback(iFileLength, iSoFar, pUserData)) + break; + } + } + while (iRead == buf.GetSize()); + } + CloseNewFile(); + return true; +} + +int CZipArchive::GetSpanMode() +{ + return m_storage.m_iSpanMode * m_storage.IsSpanMode(); +} + +CString CZipArchive::GetArchivePath() +{ + return m_storage.m_pFile->GetFilePath(); +} + +CString CZipArchive::GetGlobalComment() +{ + if (IsClosed()) + { + TRACE(_T("ZipArchive is closed.\n")); + return _T(""); + } + CString temp; + if (SingleToWide(m_centralDir.m_pszComment, temp) != -1) + return temp; + else + return _T(""); +} + +bool CZipArchive::SetGlobalComment(const CString &szComment) +{ + if (IsClosed()) + { + TRACE(_T("ZipArchive is closed.\n")); + return false; + } + if (m_storage.IsSpanMode() == -1) + { + TRACE(_T("You cannot modify the global comment of the existing disk spanning archive.\n")); + return false; + } + + WideToSingle(szComment, m_centralDir.m_pszComment); + m_centralDir.RemoveFromDisk(); + return true; +} + +bool CZipArchive::IsDirectory(DWORD uAttr) +{ + return (uAttr & FILE_ATTRIBUTE_DIRECTORY) != 0; +} + +int CZipArchive::GetCurrentDisk() +{ + return m_storage.GetCurrentDisk() + 1; +} + +bool CZipArchive::SetFileComment(WORD uIndex, CString szComment) +{ + if (IsClosed()) + { + TRACE(_T("ZipArchive is closed.\n")); + return false; + } + if (m_storage.IsSpanMode() == -1) + { + TRACE(_T("You cannot modify the file comment in the existing disk spanning archive.\n")); + return false; + } + + if (!m_centralDir.IsValidIndex(uIndex)) + return false; + m_centralDir.m_headers[uIndex]->SetComment(szComment); + m_centralDir.RemoveFromDisk(); + return true; +} + +int CZipArchive::CompareWords(const void *pArg1, const void *pArg2) +{ + WORD w1 = *(WORD*)pArg1; + WORD w2 = *(WORD*)pArg2; + return w1 == w2 ? 0 :(w1 < w2 ? - 1 : 1); +} + +void CZipArchive::CryptInitKeys() +{ + ASSERT(m_pszPassword.GetSize()); + m_keys[0] = 305419896L; + m_keys[1] = 591751049L; + m_keys[2] = 878082192L; + for (DWORD i = 0; i < m_pszPassword.GetSize(); i++) + CryptUpdateKeys(m_pszPassword[i]); +} + +void CZipArchive::CryptUpdateKeys(char c) +{ + + m_keys[0] = CryptCRC32(m_keys[0], c); + m_keys[1] += m_keys[0] & 0xff; + m_keys[1] = m_keys[1] * 134775813L + 1; + c = char(m_keys[1] >> 24); + m_keys[2] = CryptCRC32(m_keys[2], c); +} + +bool CZipArchive::CryptCheck() +{ + CZipAutoBuffer buf(ENCR_HEADER_LEN); + m_storage.Read(buf, ENCR_HEADER_LEN, false); + BYTE b = 0; + for (int i = 0; i < ENCR_HEADER_LEN; i++) + { + b = buf[i]; // only temporary + CryptDecode((char&)b); + } + // check the last byte + if (CurrentFile()->IsDataDescr()) // Data descriptor present + return BYTE(CurrentFile()->m_uModTime >> 8) == b; + else + return BYTE(CurrentFile()->m_uCrc32 >> 24) == b; +} + +char CZipArchive::CryptDecryptByte() +{ + int temp = (m_keys[2] & 0xffff) | 2; + return (char)(((temp * (temp ^ 1)) >> 8) & 0xff); +} + +void CZipArchive::CryptDecode(char &c) +{ + c ^= CryptDecryptByte(); + CryptUpdateKeys(c); +} + +bool CZipArchive::SetPassword(LPCTSTR lpszPassword) +{ + if (m_iFileOpened != nothing) + { + TRACE(_T("You cannot change the password when the file is opened\n")); + return false; // it's important not to change the password when the file inside archive is opened + } + if (IsClosed()) + { + TRACE(_T("Setting the password for a closed archive has no effect.\n")); + } + if (lpszPassword) + { + int iLen = WideToSingle(lpszPassword, m_pszPassword); + if (iLen == -1) + return false; + for (size_t i = 0; (int)i < iLen; i++) + if (m_pszPassword[i] > 127) + { + m_pszPassword.Release(); + TRACE(_T("The password contains forbidden characters. Password cleared.\n")); + return false; + } + } + else + m_pszPassword.Release(); + return true; +} + +DWORD CZipArchive::CryptCRC32(DWORD l, char c) +{ + const DWORD *CRC_TABLE = get_crc_table(); + return CRC_TABLE[(l ^ c) & 0xff] ^ (l >> 8); +} + +void CZipArchive::CryptCryptHeader(long iCrc, CZipAutoBuffer &buf) +{ + CryptInitKeys(); + srand(UINT(GetTickCount()*time(NULL))); + // genereate pseudo-random sequence + char c; + for (int i = 0; i < ENCR_HEADER_LEN - 2; i++) + { + int t1 = rand(); + c = (char)(t1 >> 6); + if (!c) + c = (char)t1; + CryptEncode(c); + buf[i] = c; + + } + c = (char)((iCrc >> 16) & 0xff); + CryptEncode(c); + buf[ENCR_HEADER_LEN - 2] = c; + c = (char)((iCrc >> 24) & 0xff); + CryptEncode(c); + buf[ENCR_HEADER_LEN - 1] = c; +} + +void CZipArchive::CryptEncode(char &c) +{ + char t = CryptDecryptByte(); + CryptUpdateKeys(c); + c ^= t; +} + +void CZipArchive::CryptEncodeBuffer() +{ + if (CurrentFile()->IsEncrypted()) + for (DWORD i = 0; i < m_info.m_uComprLeft; i++) + CryptEncode(m_info.m_pBuffer[i]); +} + +void CZipArchive::CloseFileAfterTestFailed() +{ + if (m_iFileOpened != extract) + { + TRACE(_T("No file opened.\n")); + return; + } + m_info.m_pBuffer.Release(); + m_centralDir.Clear(false); + m_iFileOpened = nothing; +} + +bool CZipArchive::TestFile(WORD uIndex, ZIPCALLBACKFUN pCallback, void* pUserData, DWORD uBufSize) +{ + if (!uBufSize) + return false; + CZipFileHeader* pHeader = m_centralDir.m_headers[uIndex]; + if (IsFileDirectory(uIndex)) + { + + // we do not test whether the password for the encrypted directory + // is correct, since it seems to be senseless (anyway password + // encrypted directories should be avoided - it adds 12 bytes) + DWORD iSize = pHeader->m_uComprSize; + if ((iSize != 0 || iSize != pHeader->m_uUncomprSize) + // different treating compressed directories + && !(pHeader->IsEncrypted() && iSize == 12 && !pHeader->m_uUncomprSize)) + ThrowError(CZipException::dirWithSize); + return true; + } + else + { + try + { + if (!OpenFile(uIndex)) + return false; + CZipAutoBuffer buf(uBufSize); + DWORD iRead, iSoFar = 0; + do + { + iRead = ReadFile(buf, buf.GetSize()); + iSoFar += iRead; + if (pCallback) + if (!pCallback(pHeader->m_uUncomprSize, iSoFar, pUserData)) + break; + } + while (iRead == buf.GetSize()); + CloseFile(); + } + catch(CException*) + { + CloseFileAfterTestFailed(); + throw; + } + } + return true; + +} + +int CZipArchive::WideToSingle(LPCTSTR lpWide, CZipAutoBuffer &szSingle) +{ + size_t wideLen = _tcslen(lpWide); + if (wideLen == 0) + { + szSingle.Release(); + return 0; + } + +#ifdef _UNICODE + // iLen does not include terminating character + int iLen = WideCharToMultiByte(CP_ACP,0, lpWide, wideLen, szSingle, + 0, NULL, NULL); + if (iLen > 0) + { + szSingle.Allocate(iLen, true); + iLen = WideCharToMultiByte(CP_ACP,0, lpWide , wideLen, szSingle, + iLen, NULL, NULL); + ASSERT(iLen != 0); + } + else // here it means error + { + szSingle.Release(); + iLen --; + } + return iLen; + +#else // if not UNICODE just copy + // iLen does not include the NULL character + szSingle.Allocate(wideLen); + memcpy(szSingle, lpWide, wideLen); + return wideLen; +#endif + +} + +int CZipArchive::SingleToWide(CZipAutoBuffer &szSingle, CString& szWide) +{ + int singleLen = szSingle.GetSize(); +#ifdef _UNICODE + // iLen doesn't include terminating character + int iLen = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szSingle, singleLen, NULL, 0); + if (iLen > 0) + { + iLen = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szSingle, singleLen, + szWide.GetBuffer(iLen) , iLen); + szWide.ReleaseBuffer(iLen); + ASSERT(iLen != 0); + } + else + { + szWide.Empty(); + iLen --; + } + return iLen; + +#else // if not UNICODE just copy + // iLen does not include the NULL character + memcpy(szWide.GetBuffer(singleLen), szSingle, singleLen); + szWide.ReleaseBuffer(singleLen); + return singleLen; +#endif +} + +const DWORD* CZipArchive::GetCRCTable() +{ + return get_crc_table(); +} + +void CZipArchive::CryptDecodeBuffer(DWORD uCount) +{ + if (CurrentFile()->IsEncrypted()) + for (DWORD i = 0; i < uCount; i++) + CryptDecode(m_info.m_pBuffer[i]); +} + +void CZipArchive::EmptyPtrList() +{ + if (m_list.GetCount()) + { + // if some memory hasn't been freed due to an error in zlib, so free it now + POSITION pos = m_list.GetHeadPosition(); + while (pos) + delete[] m_list.GetNext(pos); + } + +} + + + +void CZipArchive::EnableFindFast(bool bEnable) +{ + if (IsClosed()) + { + TRACE(_T("Set it after opening the archive")); + return; + } + + if (m_centralDir.m_bFindFastEnabled == bEnable) + return; + m_centralDir.m_bFindFastEnabled = bEnable; + if (bEnable) + m_centralDir.BuildFindFastArray(); + else + m_centralDir.m_findarray.RemoveAll(); +} diff --git a/mozilla/modules/plugin/tools/XPIPackager/ZipArchive.h b/mozilla/modules/plugin/tools/XPIPackager/ZipArchive.h new file mode 100644 index 00000000000..9f9eef92dea --- /dev/null +++ b/mozilla/modules/plugin/tools/XPIPackager/ZipArchive.h @@ -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_) diff --git a/mozilla/modules/plugin/tools/XPIPackager/ZipArchive.lib b/mozilla/modules/plugin/tools/XPIPackager/ZipArchive.lib new file mode 100644 index 0000000000000000000000000000000000000000..9b7ab6bb44ce9780327ee9ca138a72efcc11b855 GIT binary patch literal 266574 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 z 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 literal 0 HcmV?d00001 diff --git a/mozilla/modules/plugin/tools/XPIPackager/ZipArchiveDebug.lib b/mozilla/modules/plugin/tools/XPIPackager/ZipArchiveDebug.lib new file mode 100644 index 0000000000000000000000000000000000000000..9b5b783c727dc5e80d45ce96e1a5ca49e6ebad18 GIT binary patch literal 506540 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

<(!#5sd6|>!{ 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 literal 0 HcmV?d00001 diff --git a/mozilla/modules/plugin/tools/XPIPackager/ZipAutoBuffer.cpp b/mozilla/modules/plugin/tools/XPIPackager/ZipAutoBuffer.cpp new file mode 100644 index 00000000000..1197be39c19 --- /dev/null +++ b/mozilla/modules/plugin/tools/XPIPackager/ZipAutoBuffer.cpp @@ -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 + +// #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; +} \ No newline at end of file diff --git a/mozilla/modules/plugin/tools/XPIPackager/ZipAutoBuffer.h b/mozilla/modules/plugin/tools/XPIPackager/ZipAutoBuffer.h new file mode 100644 index 00000000000..404e6fb7658 --- /dev/null +++ b/mozilla/modules/plugin/tools/XPIPackager/ZipAutoBuffer.h @@ -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_) diff --git a/mozilla/modules/plugin/tools/XPIPackager/ZipBigFile.cpp b/mozilla/modules/plugin/tools/XPIPackager/ZipBigFile.cpp new file mode 100644 index 00000000000..1239e8e3551 --- /dev/null +++ b/mozilla/modules/plugin/tools/XPIPackager/ZipBigFile.cpp @@ -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; + +} diff --git a/mozilla/modules/plugin/tools/XPIPackager/ZipBigFile.h b/mozilla/modules/plugin/tools/XPIPackager/ZipBigFile.h new file mode 100644 index 00000000000..3790dd3c569 --- /dev/null +++ b/mozilla/modules/plugin/tools/XPIPackager/ZipBigFile.h @@ -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_) diff --git a/mozilla/modules/plugin/tools/XPIPackager/ZipCentralDir.cpp b/mozilla/modules/plugin/tools/XPIPackager/ZipCentralDir.cpp new file mode 100644 index 00000000000..012c21ab797 --- /dev/null +++ b/mozilla/modules/plugin/tools/XPIPackager/ZipCentralDir.cpp @@ -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; +} diff --git a/mozilla/modules/plugin/tools/XPIPackager/ZipCentralDir.h b/mozilla/modules/plugin/tools/XPIPackager/ZipCentralDir.h new file mode 100644 index 00000000000..25170ee5d09 --- /dev/null +++ b/mozilla/modules/plugin/tools/XPIPackager/ZipCentralDir.h @@ -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 +#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 m_headers; + CZipAutoBuffer m_pLocalExtraField; + void AddNewFile(CZipFileHeader & header); + void RemoveFromDisk(); + DWORD GetSize(bool bWhole = false); + CArray 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.
+ 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_) diff --git a/mozilla/modules/plugin/tools/XPIPackager/ZipException.cpp b/mozilla/modules/plugin/tools/XPIPackager/ZipException.cpp new file mode 100644 index 00000000000..e9e43fe6a65 --- /dev/null +++ b/mozilla/modules/plugin/tools/XPIPackager/ZipException.cpp @@ -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; + } + +} diff --git a/mozilla/modules/plugin/tools/XPIPackager/ZipException.h b/mozilla/modules/plugin/tools/XPIPackager/ZipException.h new file mode 100644 index 00000000000..93640ca0308 --- /dev/null +++ b/mozilla/modules/plugin/tools/XPIPackager/ZipException.h @@ -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_) diff --git a/mozilla/modules/plugin/tools/XPIPackager/ZipFileHeader.cpp b/mozilla/modules/plugin/tools/XPIPackager/ZipFileHeader.cpp new file mode 100644 index 00000000000..5487e02d440 --- /dev/null +++ b/mozilla/modules/plugin/tools/XPIPackager/ZipFileHeader.cpp @@ -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()); +} diff --git a/mozilla/modules/plugin/tools/XPIPackager/ZipFileHeader.h b/mozilla/modules/plugin/tools/XPIPackager/ZipFileHeader.h new file mode 100644 index 00000000000..b582345c383 --- /dev/null +++ b/mozilla/modules/plugin/tools/XPIPackager/ZipFileHeader.h @@ -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_) diff --git a/mozilla/modules/plugin/tools/XPIPackager/ZipInternalInfo.cpp b/mozilla/modules/plugin/tools/XPIPackager/ZipInternalInfo.cpp new file mode 100644 index 00000000000..653310dce05 --- /dev/null +++ b/mozilla/modules/plugin/tools/XPIPackager/ZipInternalInfo.cpp @@ -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); +} diff --git a/mozilla/modules/plugin/tools/XPIPackager/ZipInternalInfo.h b/mozilla/modules/plugin/tools/XPIPackager/ZipInternalInfo.h new file mode 100644 index 00000000000..86792fc989b --- /dev/null +++ b/mozilla/modules/plugin/tools/XPIPackager/ZipInternalInfo.h @@ -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_) diff --git a/mozilla/modules/plugin/tools/XPIPackager/ZipStorage.cpp b/mozilla/modules/plugin/tools/XPIPackager/ZipStorage.cpp new file mode 100644 index 00000000000..0a295d86123 --- /dev/null +++ b/mozilla/modules/plugin/tools/XPIPackager/ZipStorage.cpp @@ -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; +} diff --git a/mozilla/modules/plugin/tools/XPIPackager/ZipStorage.h b/mozilla/modules/plugin/tools/XPIPackager/ZipStorage.h new file mode 100644 index 00000000000..9d203ae32ef --- /dev/null +++ b/mozilla/modules/plugin/tools/XPIPackager/ZipStorage.h @@ -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_) diff --git a/mozilla/modules/plugin/tools/XPIPackager/body.js b/mozilla/modules/plugin/tools/XPIPackager/body.js new file mode 100644 index 00000000000..26cb4456ca6 --- /dev/null +++ b/mozilla/modules/plugin/tools/XPIPackager/body.js @@ -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 +# 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 +# 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 /* for off_t */ +# include /* 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 */ diff --git a/mozilla/modules/plugin/tools/XPIPackager/zlib.h b/mozilla/modules/plugin/tools/XPIPackager/zlib.h new file mode 100644 index 00000000000..49f56b43bc6 --- /dev/null +++ b/mozilla/modules/plugin/tools/XPIPackager/zlib.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 */ diff --git a/mozilla/modules/plugin/tools/XPIPackager/zlib.lib b/mozilla/modules/plugin/tools/XPIPackager/zlib.lib new file mode 100644 index 0000000000000000000000000000000000000000..1f0f40d1da3a59c89b6819e14d2e119075a30a0d GIT binary patch literal 107376 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�{fqBqJEd1;iV%?(Qw$*X~uJ#(dsT-CCU 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 literal 0 HcmV?d00001