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 00000000000..9b7ab6bb44c Binary files /dev/null and b/mozilla/modules/plugin/tools/XPIPackager/ZipArchive.lib differ diff --git a/mozilla/modules/plugin/tools/XPIPackager/ZipArchiveDebug.lib b/mozilla/modules/plugin/tools/XPIPackager/ZipArchiveDebug.lib new file mode 100644 index 00000000000..9b5b783c727 Binary files /dev/null and b/mozilla/modules/plugin/tools/XPIPackager/ZipArchiveDebug.lib differ 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 00000000000..1f0f40d1da3 Binary files /dev/null and b/mozilla/modules/plugin/tools/XPIPackager/zlib.lib differ