diff options
Diffstat (limited to 'src/libs/7zip/unix/CPP/Windows')
53 files changed, 7281 insertions, 0 deletions
diff --git a/src/libs/7zip/unix/CPP/Windows/COM.cpp b/src/libs/7zip/unix/CPP/Windows/COM.cpp new file mode 100644 index 000000000..a746de12b --- /dev/null +++ b/src/libs/7zip/unix/CPP/Windows/COM.cpp @@ -0,0 +1,37 @@ +// Windows/COM.cpp + +#include "StdAfx.h" + +#include "Windows/COM.h" +#include "Common/StringConvert.h" + +namespace NWindows { +namespace NCOM { + +// CoInitialize (NULL); must be called! + +UString GUIDToStringW(REFGUID guid) +{ + UString string; + const int kStringSize = 48; + StringFromGUID2(guid, string.GetBuffer(kStringSize), kStringSize); + string.ReleaseBuffer(); + return string; +} + +AString GUIDToStringA(REFGUID guid) +{ + return UnicodeStringToMultiByte(GUIDToStringW(guid)); +} + +HRESULT StringToGUIDW(const wchar_t *string, GUID &classID) +{ + return CLSIDFromString((wchar_t *)string, &classID); +} + +HRESULT StringToGUIDA(const char *string, GUID &classID) +{ + return StringToGUIDW(MultiByteToUnicodeString(string), classID); +} + +}} diff --git a/src/libs/7zip/unix/CPP/Windows/COM.h b/src/libs/7zip/unix/CPP/Windows/COM.h new file mode 100644 index 000000000..506bbbc64 --- /dev/null +++ b/src/libs/7zip/unix/CPP/Windows/COM.h @@ -0,0 +1,69 @@ +// Windows/COM.h + +#ifndef __WINDOWS_COM_H +#define __WINDOWS_COM_H + +#include "Common/MyString.h" + +namespace NWindows { +namespace NCOM { + +#ifdef _WIN32 + +class CComInitializer +{ +public: + CComInitializer() + { + #ifdef UNDER_CE + CoInitializeEx(NULL, COINIT_MULTITHREADED); + #else + // it's single thread. Do we need multithread? + CoInitialize(NULL); + #endif + }; + ~CComInitializer() { CoUninitialize(); }; +}; + +class CStgMedium +{ + STGMEDIUM _object; +public: + bool _mustBeReleased; + CStgMedium(): _mustBeReleased(false) {} + ~CStgMedium() { Free(); } + void Free() + { + if (_mustBeReleased) + ReleaseStgMedium(&_object); + _mustBeReleased = false; + } + const STGMEDIUM* operator->() const { return &_object;} + STGMEDIUM* operator->() { return &_object;} + STGMEDIUM* operator&() { return &_object; } +}; + +#endif + +////////////////////////////////// +// GUID <--> String Conversions +UString GUIDToStringW(REFGUID guid); +AString GUIDToStringA(REFGUID guid); +#ifdef UNICODE + #define GUIDToString GUIDToStringW +#else + #define GUIDToString GUIDToStringA +#endif + +HRESULT StringToGUIDW(const wchar_t *string, GUID &classID); +HRESULT StringToGUIDA(const char *string, GUID &classID); +#ifdef UNICODE + #define StringToGUID StringToGUIDW +#else + #define StringToGUID StringToGUIDA +#endif + + +}} + +#endif diff --git a/src/libs/7zip/unix/CPP/Windows/Clipboard.cpp b/src/libs/7zip/unix/CPP/Windows/Clipboard.cpp new file mode 100644 index 000000000..bb081e153 --- /dev/null +++ b/src/libs/7zip/unix/CPP/Windows/Clipboard.cpp @@ -0,0 +1,160 @@ +// Windows/Clipboard.cpp + +#include "StdAfx.h" + + +#include "Windows/Clipboard.h" +#include "Windows/Defs.h" +#ifdef _WIN32 +#include "Windows/Memory.h" +#include "Windows/Shell.h" +#include "Windows/Memory.h" +#else +#include <wx/clipbrd.h> +#include <wx/dataobj.h> +#undef _WIN32 +#endif + +#include "Common/StringConvert.h" + +namespace NWindows { + +bool CClipboard::Open(HWND wndNewOwner) +{ +#ifdef _WIN32 + m_Open = BOOLToBool(::OpenClipboard(wndNewOwner)); +#else + m_Open = wxTheClipboard->Open(); +#endif + return m_Open; +} + +CClipboard::~CClipboard() +{ + Close(); +} + +bool CClipboard::Close() +{ + if (!m_Open) + return true; +#ifdef _WIN32 + m_Open = !BOOLToBool(CloseClipboard()); +#else + wxTheClipboard->Close(); + m_Open = false; +#endif + return !m_Open; +} + +#ifdef _WIN32 +bool ClipboardIsFormatAvailableHDROP() +{ + return BOOLToBool(IsClipboardFormatAvailable(CF_HDROP)); +} +#endif + +/* +bool ClipboardGetTextString(AString &s) +{ + s.Empty(); + if (!IsClipboardFormatAvailable(CF_TEXT)) + return false; + CClipboard clipboard; + + if (!clipboard.Open(NULL)) + return false; + + HGLOBAL h = ::GetClipboardData(CF_TEXT); + if (h != NULL) + { + NMemory::CGlobalLock globalLock(h); + const char *p = (const char *)globalLock.GetPointer(); + if (p != NULL) + { + s = p; + return true; + } + } + return false; +} +*/ + +/* +bool ClipboardGetFileNames(UStringVector &names) +{ + names.Clear(); + if (!IsClipboardFormatAvailable(CF_HDROP)) + return false; + CClipboard clipboard; + + if (!clipboard.Open(NULL)) + return false; + + HGLOBAL h = ::GetClipboardData(CF_HDROP); + if (h != NULL) + { + NMemory::CGlobalLock globalLock(h); + void *p = (void *)globalLock.GetPointer(); + if (p != NULL) + { + NShell::CDrop drop(false); + drop.Attach((HDROP)p); + drop.QueryFileNames(names); + return true; + } + } + return false; +} +*/ + +#ifdef _WIN32 +static bool ClipboardSetData(UINT uFormat, const void *data, size_t size) +{ + NMemory::CGlobal global; + if (!global.Alloc(GMEM_DDESHARE | GMEM_MOVEABLE, size)) + return false; + { + NMemory::CGlobalLock globalLock(global); + LPVOID p = globalLock.GetPointer(); + if (p == NULL) + return false; + memcpy(p, data, size); + } + if (::SetClipboardData(uFormat, global) == NULL) + return false; + global.Detach(); + return true; +} +#endif + +bool ClipboardSetText(HWND owner, const UString &s) +{ + CClipboard clipboard; + if (!clipboard.Open(owner)) + return false; +#ifdef _WIN32 + if (!::EmptyClipboard()) + return false; + + bool res; + res = ClipboardSetData(CF_UNICODETEXT, (const wchar_t *)s, (s.Length() + 1) * sizeof(wchar_t)); + #ifndef _UNICODE + AString a; + a = UnicodeStringToMultiByte(s, CP_ACP); + res |= ClipboardSetData(CF_TEXT, (const char *)a, (a.Length() + 1) * sizeof(char)); + a = UnicodeStringToMultiByte(s, CP_OEMCP); + res |= ClipboardSetData(CF_OEMTEXT, (const char *)a, (a.Length() + 1) * sizeof(char)); + #endif + return res; +#else + wxTheClipboard->Clear(); + // This data objects are held by the clipboard, + // so do not delete them in the app. + wxString ws(s); + wxTheClipboard->SetData( new wxTextDataObject(ws) ); + return true; +#endif +} + +} diff --git a/src/libs/7zip/unix/CPP/Windows/Clipboard.h b/src/libs/7zip/unix/CPP/Windows/Clipboard.h new file mode 100644 index 000000000..c80ba5ea7 --- /dev/null +++ b/src/libs/7zip/unix/CPP/Windows/Clipboard.h @@ -0,0 +1,28 @@ +// Windows/Clipboard.h + +#ifndef __CLIPBOARD_H +#define __CLIPBOARD_H + +#include "Common/MyString.h" + +namespace NWindows { + +class CClipboard +{ + bool m_Open; +public: + CClipboard(): m_Open(false) {}; + ~CClipboard(); + bool Open(HWND wndNewOwner); + bool Close(); +}; + +bool ClipboardIsFormatAvailableHDROP(); + +// bool ClipboardGetFileNames(UStringVector &names); +// bool ClipboardGetTextString(AString &s); +bool ClipboardSetText(HWND owner, const UString &s); + +} + +#endif diff --git a/src/libs/7zip/unix/CPP/Windows/CommonDialog.h b/src/libs/7zip/unix/CPP/Windows/CommonDialog.h new file mode 100644 index 000000000..f24bb5b24 --- /dev/null +++ b/src/libs/7zip/unix/CPP/Windows/CommonDialog.h @@ -0,0 +1,19 @@ +// Windows/CommonDialog.h + +#ifndef __WINDOWS_COMMON_DIALOG_H +#define __WINDOWS_COMMON_DIALOG_H + +#include "Common/MyString.h" + +namespace NWindows{ + +bool MyGetOpenFileName(HWND hwnd, LPCWSTR title, LPCWSTR fullFileName, + LPCWSTR s, UString &resPath + #ifdef UNDER_CE + , bool openFolder = false + #endif +); + +} + +#endif diff --git a/src/libs/7zip/unix/CPP/Windows/Control/ComboBox.h b/src/libs/7zip/unix/CPP/Windows/Control/ComboBox.h new file mode 100644 index 000000000..8717b4867 --- /dev/null +++ b/src/libs/7zip/unix/CPP/Windows/Control/ComboBox.h @@ -0,0 +1,82 @@ +// Windows/Control/ComboBox.h + +#ifndef __WINDOWS_WX_CONTROL_COMBOBOX_H +#define __WINDOWS_WX_CONTROL_COMBOBOX_H + +#include "Windows/Window.h" +#include "Windows/Defs.h" + + +#include "Windows/Control/Window2.h" // NMHDR + +#ifndef _WIN32 +#define CB_ERR (-1) // wxNOT_FOUND +#endif + +typedef struct +{ + NMHDR hdr; +#define CBENF_ESCAPE 1 +#define CBENF_RETURN 2 + int iWhy; +} NMCBEENDEDITW; + +typedef NMCBEENDEDITW * PNMCBEENDEDITW; + + +class wxComboBox; + +namespace NWindows { + namespace NControl { + + class CComboBox // : public CWindow + { + wxComboBox* _choice; + public: + CComboBox() : _choice(0) {} + + void Attach(wxWindow * newWindow); + wxWindow * Detach(); + operator HWND() const; + + int AddString(const TCHAR * txt); + + void SetText(LPCTSTR s); + + void GetText(CSysString &s); + + int GetCount() const ; + void GetLBText(int index, CSysString &s); + + void SetCurSel(int index); + int GetCurSel(); + + void SetItemData(int index, int val); + + int GetItemData(int index); + + void Enable(bool state); + + void ResetContent(); + }; + + class CComboBoxEx : public CComboBox // : public CWindow + { + public: + /* FIXME + LRESULT DeleteItem(int index) + { return SendMessage(CBEM_DELETEITEM, index, 0); } + LRESULT InsertItem(COMBOBOXEXITEM *item) + { return SendMessage(CBEM_INSERTITEM, 0, (LPARAM)item); } + DWORD SetExtendedStyle(DWORD exMask, DWORD exStyle) + { return (DWORD)SendMessage(CBEM_SETEXTENDEDSTYLE, exMask, exStyle); } + HWND GetEditControl() + { return (HWND)SendMessage(CBEM_GETEDITCONTROL, 0, 0); } + */ + }; + + + } +} + +#endif // __WINDOWS_WX_CONTROL_COMBOBOX_H diff --git a/src/libs/7zip/unix/CPP/Windows/Control/Controls.cpp b/src/libs/7zip/unix/CPP/Windows/Control/Controls.cpp new file mode 100644 index 000000000..2191d8009 --- /dev/null +++ b/src/libs/7zip/unix/CPP/Windows/Control/Controls.cpp @@ -0,0 +1,515 @@ +// Dialog.cpp + +#include "StdAfx.h" + +// For compilers that support precompilation, includes "wx/wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ + #pragma hdrstop +#endif + +// for all others, include the necessary headers (this file is usually all you +// need because it includes almost all "standard" wxWidgets headers) +#ifndef WX_PRECOMP + #include "wx/wx.h" + #include "wx/imaglist.h" + #include "wx/listctrl.h" +#endif + +#undef _WIN32 + +#include "Windows/Control/Dialog.h" + +void verify_main_thread(void); + +class LockGUI +{ + bool _IsMain; + public: + LockGUI() { + verify_main_thread(); + _IsMain = wxThread::IsMain(); + if (!_IsMain) { + // DEBUG + printf("GuiEnter-Controls(0x%lx)\n",wxThread::GetCurrentId()); + abort(); // FIXME wxMutexGuiEnter(); + } + } + ~LockGUI() { + if (!_IsMain) { + wxMutexGuiLeave(); + // DEBUG printf("GuiLeave(0x%lx)\n",wxThread::GetCurrentId()); + } + } +}; +///////////////////////// + +static const wxString CLASS_NAME_wxStaticText = wxT("wxStaticText"); +static const wxString CLASS_NAME_wxTextCtrl = wxT("wxTextCtrl"); + +namespace NWindows { + namespace NControl { + + void CDialogChildControl::SetText(LPCWSTR s) + { + LockGUI lock; + const wxChar * class_name = _window->GetClassInfo()->GetClassName (); + + if ( CLASS_NAME_wxStaticText == class_name) { + ((wxStaticText *)_window)->SetLabel(s); + } else if ( CLASS_NAME_wxTextCtrl == class_name) { + ((wxTextCtrl *)_window)->SetLabel(s); + } else { + // ((wxControl *)_window)->SetValue(s); // FIXME + printf("INTERNAL ERROR - CDialogChildControl::SetText(class=%ls) not implemented\n",class_name); + exit(-1); + } + } + + bool CDialogChildControl::GetText(CSysString &s) + { + wxString str; + { + LockGUI lock; + const wxChar * class_name = _window->GetClassInfo()->GetClassName (); + if ( CLASS_NAME_wxStaticText == class_name) { + str = ((wxStaticText *)_window)->GetLabel(); + } else if ( CLASS_NAME_wxTextCtrl == class_name) { + str = ((wxTextCtrl *)_window)->GetLabel(); + } else { + // FIXME str = ((wxTextCtrl *)_window)->GetValue(); + printf("INTERNAL ERROR - CDialogChildControl::GetText(class=%ls) not implemented\n",class_name); + exit(-1); + } + } + s = str; + return true; + } + } +} + +///////////////////////// Windows/Control/ComboBox.cpp +#include "Windows/Control/ComboBox.h" + +namespace NWindows { + namespace NControl { + + void CComboBox::Attach(wxWindow * newWindow) { _choice = (wxComboBox*)newWindow; } + + wxWindow * CComboBox::Detach() + { + wxWindow * window = _choice; + _choice = NULL; + return window; + } + + CComboBox::operator HWND() const { return (HWND)_choice; } + + + int CComboBox::AddString(const TCHAR * txt) { + LockGUI lock; + wxString item(txt); + return _choice->Append(item); + } + + void CComboBox::SetText(LPCTSTR s) { + LockGUI lock; + wxString str(s); + _choice->SetValue(str); + } + + void CComboBox::GetText(CSysString &s) { + LockGUI lock; + wxString str = _choice->GetValue(); + s = str; + } + + int CComboBox::GetCount() const { + LockGUI lock; + return _choice->GetCount(); + } + + void CComboBox::GetLBText(int index, CSysString &s) { + LockGUI lock; + wxString str = _choice->GetString(index); + s = str; + } + + void CComboBox::SetCurSel(int index) { + LockGUI lock; + _choice->SetSelection(index); + } + + int CComboBox::GetCurSel() { + LockGUI lock; + return _choice->GetSelection(); + } + + void CComboBox::SetItemData(int index, int val) { + LockGUI lock; + _choice->SetClientData( index, (void *)(((char *)0) + val)); + } + + int CComboBox::GetItemData(int index) + { + LockGUI lock; + void * data = _choice->GetClientData(index); + int ret = (int)(((char *)data) - ((char *)0)); + return ret; + } + + void CComboBox::Enable(bool state) { + LockGUI lock; + _choice->Enable(state); + } + + void CComboBox::ResetContent() { + LockGUI lock; + _choice->Clear(); + } + } +} + +///////////////////////// Windows/Control/Edit.cpp +#include "Windows/Control/Edit.h" + +namespace NWindows { + namespace NControl { + + void CEdit::SetPasswordChar(WPARAM c) // Warning : does not work for wxMSW + { + LockGUI lock; + long style = _window->GetWindowStyle(); + if ( c == 0 ) style &= ~(wxTE_PASSWORD); + else style |= wxTE_PASSWORD; + _window->SetWindowStyle(style); + _window->Refresh(); + } + + + void CEdit::Show(int cmdShow) + { + LockGUI lock; + // FIXME _window->Show(cmdShow != SW_HIDE); + _window->Enable(cmdShow != SW_HIDE); + } + + void CEdit::SetText(LPCWSTR s) + { + LockGUI lock; + ((wxTextCtrl *)_window)->SetValue(s); + } + + bool CEdit::GetText(CSysString &s) + { + wxString str; + { + LockGUI lock; + str = ((wxTextCtrl *)_window)->GetValue(); + } + s = str; + return true; + } + + } +} + +///////////////////////// Windows/Control/ProgressBar.cpp +#include "Windows/Control/ProgressBar.h" + +namespace NWindows { + namespace NControl { + + CProgressBar::CProgressBar(wxWindow* newWindow): + _window((wxGauge *)newWindow) , _minValue(0), _range(0) { } + + void CProgressBar::Attach(wxWindow* newWindow) { + _window = (wxGauge *)newWindow; + _minValue = 0; + _range = 0; + } + + void CProgressBar::SetRange32(int minValue, int maxValue) { + int range = maxValue - minValue; + if (range >= 1) + { + LockGUI lock; + _minValue = minValue; + _range = range; + _window->SetRange(_range); + } + } + + void CProgressBar::SetPos(int pos) { + if (_range >= 1) + { + LockGUI lock; + int value = pos - _minValue; + if ((value >= 0) && (value <= _range)) _window->SetValue(value); + } + } + + } +} + +///////////////////////// Windows/Control/StatusBar.cpp +#include "Windows/Control/StatusBar.h" + +namespace NWindows { + namespace NControl { + + void CStatusBar::Attach(wxWindow * newWindow) { _statusBar = (wxStatusBar*)newWindow; } + + wxWindow * CStatusBar::Detach() + { + wxWindow * window = _statusBar; + _statusBar = NULL; + return window; + } + + void CStatusBar::SetText(int index, LPCTSTR text) + { + _statusBar->SetStatusText(text,index); + } + + } + +} + +///////////////////////// Windows/Control/ListView.cpp +#include "Windows/Control/ListView.h" + +namespace NWindows { +namespace NControl { + + void CListView::Attach(wxWindow * newWindow) { + _list = (wxListCtrl *)newWindow; + } + + CListView::operator HWND() const { return (HWND)_list; } + + int CListView::GetItemCount() const {return _list->GetItemCount(); } + + int CListView::InsertItem(int index, LPCTSTR text) { + return _list->InsertItem(index, text); + } + int CListView::InsertItem(const LVITEM* item) { + /* + int col = item->iSubItem; + wxString text; + if (item->mask & LVIF_TEXT) text = item->pszText; + + // printf("%p->InsertItem(id=%d,%ls)\n",_list,item->iItem, (const wchar_t *)text); + return _list->InsertItem(item->iItem, text); + */ + wxListItem info; + long mask = 0; + info.SetId(item->iItem); + if (item->mask & LVIF_TEXT) + { + info.SetText(item->pszText); + mask |= wxLIST_MASK_TEXT; + } + if (item->mask & LVIF_PARAM) + { + info.SetData(item->lParam); + mask |= wxLIST_MASK_DATA; + } + if (item->mask & LVIF_STATE) + { + info.SetState(item->state); + mask |= wxLIST_MASK_STATE; + } + // FIXME if (item->mask & LVIF_IMAGE) + + info.SetMask(mask); + + return _list->InsertItem(info); + } + + void CListView::SetItem(const LVITEM* item) { + int col = item->iSubItem; + wxString text; + if (item->mask & LVIF_TEXT) text = item->pszText; + // printf("%p->SetItem(id=%d,col=%d,%ls)\n",_list,item->iItem, col,(const wchar_t *)text); + _list->SetItem(item->iItem, col, text); + } + + int CListView::SetSubItem(int index, int subIndex, LPCTSTR text) + { + return _list->SetItem(index, subIndex, text); + } + + void SetUnicodeFormat(bool fUnicode) { return ; } + + void CListView::InsertColumn(int columnIndex, LPCTSTR text, int width) + { + _list->InsertColumn(columnIndex, text, wxLIST_FORMAT_LEFT, width); + } + + void CListView::InsertColumn(int columnIndex, const LVCOLUMNW *columnInfo) + { + wxString text; + int format = wxLIST_FORMAT_LEFT; + int width = -1; + if (columnInfo->mask & LVCF_FMT) + { + if (columnInfo->fmt == LVCFMT_LEFT) format = wxLIST_FORMAT_LEFT; + if (columnInfo->fmt == LVCFMT_RIGHT) format = wxLIST_FORMAT_RIGHT; + } + if (columnInfo->mask & LVCF_TEXT) text = columnInfo->pszText; + if (columnInfo->mask & LVCF_WIDTH) width = columnInfo->cx; + // FIXME LVCF_SUBITEM + // printf("%p->InsertColumn(%d,%ls)\n",_list,columnIndex,(const wchar_t *)heading); + _list->InsertColumn(columnIndex, text, format, width); + } + + void CListView::DeleteAllItems() { + _list->DeleteAllItems(); + printf("%p->DeleteAllItems()\n",_list); + } + + void CListView::SetRedraw(bool b) { + if (b) _list->Thaw(); + else _list->Freeze(); + printf(" %p->SetRedraw()\n",_list); + } + + void CListView::SetItemCount(int count) { + // ONLY IF VIRTUAL REPORT -- _list->SetItemCount(count); + printf(" %p->SetItemCount(%d)\n",_list,count); + } + + void CListView::InvalidateRect(void *, bool) { + printf("FIXME %p->InvalidateRect()\n",_list);/* FIXME */ + } + + int CListView::GetSelectedCount() const { + int nb = _list->GetSelectedItemCount(); + printf(" %p->GetSelectedCount()=>%d\n",_list,nb); + return nb; + } + + void /* bool */ CListView::EnsureVisible(int index, bool partialOK) { + + printf(" %p->EnsureVisible(%d)\n",_list,index); + + if (index == -1) index = 0; + _list->EnsureVisible(index); + + // return true; + } + + void CListView::SetItemState(int index, UINT state, UINT mask) { + // don't work _list->SetItemState(index, state, mask); !? + // try SetItem ... + /* + wxListItem info; + + info.m_mask = wxLIST_MASK_STATE; + info.m_itemId = index; + info.m_col = 0; + info.m_state = state; + info.m_mask = mask; + + _list->SetItem(info); + */ + + printf(" %p->EnsureVisible(%d)\n",_list,index); + + if (index == -1) return; + + if (mask & LVIS_FOCUSED) { + _list->SetItemState(index, state & LVIS_FOCUSED, mask & LVIS_FOCUSED); + } + + if (mask & LVIS_SELECTED) { + _list->SetItemState(index, state & LVIS_SELECTED, mask & LVIS_SELECTED); + } + + } + + UINT CListView::GetItemState(int index, UINT mask) const + { + UINT state = _list->GetItemState(index, mask); + printf("FIXME %p->GetItemState(index=%d,mask=0x%x)=0x%x\n",_list,index,(unsigned)mask,(unsigned)state); /* FIXME */ + + return state; + } + + void /* bool */ CListView::Update() { + printf("FIXME %p->Update()\n",_list); /* FIXME */ + } + + bool CListView::DeleteColumn(int columnIndex) { + // printf("%p->DeleteColumn()\n",_list); + if (_list->GetColumnCount() < 1) return false; + return _list->DeleteColumn(columnIndex); // always return true !? + } + + bool CListView::GetItemParam(int itemIndex, LPARAM ¶m) const + { + param = _list->GetItemData(itemIndex); + + // printf(" %p->GetItemParam(%d) => %ld\n",_list,itemIndex,(long)param); + + return true; + } + + int CListView::GetNextItem(int startIndex, UINT flags) const + { + int item = _list->GetNextItem(startIndex, wxLIST_NEXT_ALL, flags); + printf(" %p->GetNextItem(%d) => %d\n",_list,startIndex,item); + return item; + + } + + int CListView::GetFocusedItem() const + { + int item = _list->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_FOCUSED); + printf(" %p->GetFocusedItem() => %d\n",_list,item); + return item; + } + + void CListView::RedrawAllItems() + { + printf("FIXME %p->RedrawAllItems()\n",_list); + } + + // FIXME added + int CListView::GetColumnCount() + { + return _list->GetColumnCount(); + } + + void CListView::SetFocus() { /* FIXME */ } + + void CListView::RedrawItem(int item) { /* FIXME */ } + + bool CListView::SortItems(PFNLVCOMPARE compareFunction, LPARAM dataParam) { + printf(" %p->SortItems()\n",_list); + return _list->SortItems(compareFunction, dataParam); + } + + bool CListView::GetColumn(int columnIndex, LVCOLUMN* columnInfo) + { + columnInfo->cx = _list->GetColumnWidth(columnIndex);// FIXME + + bool ret = false; + + if (columnInfo->cx >= 1) ret = true; + + // printf("CListView::GetColumn(%d) cx=%d\n",columnIndex,(int)columnInfo->cx); + + return ret; + } + + // HWND EditLabel(int itemIndex) + void CListView::EditLabel(int itemIndex) + { + /* FIXME */ + } + +}} + diff --git a/src/libs/7zip/unix/CPP/Windows/Control/Dialog.cpp b/src/libs/7zip/unix/CPP/Windows/Control/Dialog.cpp new file mode 100644 index 000000000..464ae302c --- /dev/null +++ b/src/libs/7zip/unix/CPP/Windows/Control/Dialog.cpp @@ -0,0 +1,560 @@ +// Dialog.cpp + +#include "StdAfx.h" + +// For compilers that support precompilation, includes "wx/wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ + #pragma hdrstop +#endif + +// for all others, include the necessary headers (this file is usually all you +// need because it includes almost all "standard" wxWidgets headers) +#ifndef WX_PRECOMP + #include "wx/wx.h" +#endif + +#include <wx/filename.h> + + +#undef _WIN32 + +#include "Windows/Control/DialogImpl.h" +#include "Windows/Synchronization.h" + + +// FIXME +class MyApp : public wxApp +{ +public: + virtual bool OnInit(); +}; + +DECLARE_APP(MyApp) + +// #include "../GUI/p7zip_32.xpm" +extern const char * p7zip_32_xpm[]; + +const TCHAR * nameWindowToUnix(const TCHAR * lpFileName) { + if ((lpFileName[0] == wxT('c')) && (lpFileName[1] == wxT(':'))) return lpFileName+2; + return lpFileName; +} + + +extern time_t g_T0; // FIXME + +#define DIALOG_ID_MESSAGEBOX 8100 +#define DIALOG_ID_DIR_DIALOG 8101 +#define DIALOG_ID_FILE_DIALOG 8102 +#define DIALOG_ID_POST_DIALOG 8190 +#define DIALOG_ID_END_DIALOG 8199 + +static struct +{ + bool busy; + + int id; + wxWindow *parentWindow; + + // CreateDialog + NWindows::NControl::CModalDialog * dialog; + + // EndModal + int value; + NWindows::NControl::CModalDialogImpl * window; + + // MessageBox + const TCHAR * msg; + const TCHAR * title; + int flag; + + // + LPCWSTR initialFolderOrFile; + + wxSemaphore * sem; + int ret; + + UString resultPath; + +#define MAX_CREATE 16 +} g_tabCreate[MAX_CREATE]; + +static int myCreateHandle2(int n); + +static int findFreeInd() +{ +static NWindows::NSynchronization::CCriticalSection g_CriticalSection; + + g_CriticalSection.Enter(); + int ind = 0; + while (ind < MAX_CREATE) + { + if (g_tabCreate[ind].busy == false) + { + g_tabCreate[ind].busy = true; + break; + } + ind++; + } + g_CriticalSection.Leave(); + + return ind; +} + +static int WaitInd(wxWindow * destWindow, int ind,int id,wxWindow * parent,UString &resultPath) +{ + int ret = 0; + + g_tabCreate[ind].id = id; + g_tabCreate[ind].parentWindow = parent; + g_tabCreate[ind].ret = 0; + g_tabCreate[ind].resultPath = wxEmptyString; + + if (wxThread::IsMain()) + { + ret = myCreateHandle2(ind); + resultPath = g_tabCreate[ind].resultPath; + } + else + { + if (destWindow == 0) { + extern wxWindow * g_window; + if (g_window == 0) + { + printf("INTERNAL ERROR : g_window and destWindow == NULL\n"); abort(); + } + destWindow = g_window; + } + g_tabCreate[ind].sem = new wxSemaphore(0); + + // create any type of command event here + wxCommandEvent event( wxEVT_COMMAND_MENU_SELECTED, WORKER_EVENT ); + event.SetInt( ind ); + + // send in a thread-safe way + // DEBUG printf("T=0x%lx - %d : WaitInd(%d,%p): BEGIN\n", wxThread::GetCurrentId(),time(0)-g_T0,g_tabCreate[ind].id,g_tabCreate[ind].parentWindow); + wxPostEvent( destWindow, event ); + + g_tabCreate[ind].sem->Wait(); + + ret = g_tabCreate[ind].ret; + resultPath = g_tabCreate[ind].resultPath; + // DEBUG printf("T=0x%lx - %d : WaitInd(%d,%p): ret=%d\n", wxThread::GetCurrentId(),time(0)-g_T0,g_tabCreate[ind].id,g_tabCreate[ind].parentWindow,ret); + delete g_tabCreate[ind].sem; + g_tabCreate[ind].sem = 0; + } + + g_tabCreate[ind].busy = false; + + return ret; +} + +static int WaitInd(wxWindow * destWindow,int ind,int id,wxWindow * parent) +{ + UString resultPath; + return WaitInd(destWindow,ind,id,parent,resultPath); +} + +void verify_main_thread(void); + +class LockGUI +{ + bool _IsMain; + public: + LockGUI() { + + verify_main_thread(); + + _IsMain = wxThread::IsMain(); + if (!_IsMain) { + // DEBUG + printf("GuiEnter-Dialog(0x%lx)\n",wxThread::GetCurrentId()); + abort(); // FIXME wxMutexGuiEnter(); + } + } + ~LockGUI() { + if (!_IsMain) { + wxMutexGuiLeave(); + // DEBUG printf("GuiLeave(0x%lx)\n",wxThread::GetCurrentId()); + } + } +}; + +static const unsigned int kNumDialogsMax = 32; +static unsigned int g_NumDialogs = 0; +static const CDialogInfo *g_Dialogs[kNumDialogsMax]; + +void RegisterDialog(const CDialogInfo *dialogInfo) +{ + // DEBUG printf("RegisterDialog : %d\n",dialogInfo->id); + if (g_NumDialogs < kNumDialogsMax) + g_Dialogs[g_NumDialogs++] = dialogInfo; +} + +namespace NWindows { + + CSysString MyLoadString(unsigned int resourceID) + { + for(unsigned i=0; i < g_NumDialogs; i++) { + if (g_Dialogs[i]->stringTable) { + int j = 0; + while(g_Dialogs[i]->stringTable[j].str) { + if (resourceID == g_Dialogs[i]->stringTable[j].id) { + return g_Dialogs[i]->stringTable[j].str; + } + + j++; + } + } + } + return L"FIXME-MyLoadStringW-"; + } + + namespace NControl { + +/////////////////////////////////////////// CModalDialog ////////////////////////////////// + + bool CModalDialog::CheckButton(int buttonID, UINT checkState) + { + LockGUI lock; + wxCheckBox* w = (wxCheckBox*)_window->FindWindow(buttonID); + if (w) + { + w->SetValue(checkState == BST_CHECKED); + return true; + } + return false; + } + + UINT CModalDialog::IsButtonChecked(int buttonID) const + { + LockGUI lock; + wxCheckBox* w = (wxCheckBox*)_window->FindWindow(buttonID); + if (w) + { + bool bret = w->GetValue(); + if (bret) return BST_CHECKED; + } + return BST_UNCHECKED; + } + + void CModalDialog::EnableItem(int id, bool state) + { + LockGUI lock; + wxWindow* w = _window->FindWindow(id); + if (w) w->Enable(state); + } + + void CModalDialog::SetItemText(int id, const TCHAR *txt) + { + LockGUI lock; + wxWindow* w = _window->FindWindow(id); + if (w) + { + wxString label(txt); + w->SetLabel(label); + } + } + + wxWindow * CModalDialog::GetItem(long id) const + { + LockGUI lock; + return _window->FindWindow(id); + } + + void CModalDialog::ShowItem(int itemID, int cmdShow) const + { + LockGUI lock; + // cmdShow = SW_HIDE or SW_SHOW (sometimes false or true !) + wxWindow* w = _window->FindWindow(itemID); + if (w) + { +// FIXME w->Show(cmdShow != SW_HIDE); + w->Enable(cmdShow != SW_HIDE); + } + } + + UINT_PTR CModalDialog::SetTimer(UINT_PTR idEvent , unsigned milliseconds) + { + LockGUI lock; + return _window->SetTimer(idEvent , milliseconds); + } + + void CModalDialog::KillTimer(UINT_PTR idEvent) + { + LockGUI lock; + _window->KillTimer(idEvent); + } + + void CModalDialog::SetText(const TCHAR *_title) { + LockGUI lock; + _window->SetTitle(_title); + } + + + bool CModalDialog::GetText(CSysString &s) { + wxString str; + { + LockGUI lock; + str = _window->GetTitle(); + } + s = str; + return true; + } + + INT_PTR CModalDialog::Create(int id , HWND parentWindow) + { + int ind = findFreeInd(); + + g_tabCreate[ind].dialog = this; + + return WaitInd(0, ind,id,parentWindow); + } + + void CModalDialog::End(int result) + { + int ind = findFreeInd(); + + g_tabCreate[ind].window = _window; + g_tabCreate[ind].value = result; + + WaitInd(this->_window,ind,DIALOG_ID_END_DIALOG,0); + } + + void CModalDialog::PostMessage(UINT message) + { + int ind = findFreeInd(); + + g_tabCreate[ind].dialog = this; + g_tabCreate[ind].value = message; + + WaitInd(this->_window,ind,DIALOG_ID_POST_DIALOG,0); + } + +/////////////////////////////////////////// CModalDialogImpl /////////////////////////////////////// + + CModalDialogImpl::CModalDialogImpl(CDialog *dialog, wxWindow* parent, wxWindowID id, + const wxString& title, const wxPoint& pos, + const wxSize& size, long style) : + wxDialog(parent, id, title , pos , size, style /* | wxDIALOG_NO_PARENT */ ) , + _timer(this, TIMER_ID_IMPL), _dialog(dialog) + { + // set the frame icon + this->SetIcon(wxICON(p7zip_32)); + } + + void CModalDialogImpl::OnAnyButton(wxCommandEvent& event) + { + int id = event.GetId(); + if (id == wxID_OK) + { + if (_dialog) _dialog->OnOK(); + // event.Skip(true); + } + else if (id == wxID_CANCEL) + { + if (_dialog) _dialog->OnCancel(); + // event.Skip(true); + } + else if (id == wxID_HELP) + { + if (_dialog) _dialog->OnHelp(); + } + else + { + if (_dialog) + { + /* bool bret = */ _dialog->OnButtonClicked(id, FindWindow(id) ); + } + } + } + + void CModalDialogImpl::OnAnyChoice(wxCommandEvent &event) + { + int itemID = event.GetId(); + if (_dialog) _dialog->OnCommand(CBN_SELCHANGE, itemID, 0); + } + + void CModalDialogImpl::OnAnyTimer(wxTimerEvent &event) + { + int timerID = event.GetId(); + if (_dialog) _dialog->OnTimer(timerID , 0); + } + } +} + +///////////////////////// myCreateHandle + + +static int myCreateHandle2(int n) +{ + unsigned int id = g_tabCreate[n].id; + wxWindow * parentWindow = g_tabCreate[n].parentWindow; + NWindows::NControl::CModalDialogImpl * window = 0; + + // DEBUG printf("T=0x%lx - %d : myCreateHandle(%d): BEGIN\n", wxThread::GetCurrentId(),time(0)-g_T0,n); + + if (id == DIALOG_ID_END_DIALOG) + { + /* FIXME : the dialog must be shown before ending it ? + while (!g_tabCreate[n].window->IsShownOnScreen()) Sleep(200); + Sleep(200); + */ + g_tabCreate[n].window->EndModal(g_tabCreate[n].value); + return 0; + } + + if (id == DIALOG_ID_POST_DIALOG) + { + g_tabCreate[n].dialog->OnMessage(g_tabCreate[n].value, 0, 0); + return 0; + } + + if (id == DIALOG_ID_MESSAGEBOX) + { + long style = g_tabCreate[n].flag; + long decorated_style = style; + if ( ( style & ( wxICON_EXCLAMATION | wxICON_HAND | wxICON_INFORMATION | + wxICON_QUESTION ) ) == 0 ) + { + decorated_style |= ( style & wxYES ) ? wxICON_QUESTION : wxICON_INFORMATION ; + } + wxMessageDialog dialog(parentWindow, g_tabCreate[n].msg, g_tabCreate[n].title, decorated_style); + dialog.SetIcon(wxICON(p7zip_32)); + int ret = dialog.ShowModal(); + + return ret; + } + + if (id == DIALOG_ID_DIR_DIALOG) + { + wxString defaultDir = g_tabCreate[n].initialFolderOrFile; + wxDirDialog dirDialog(g_tabCreate[n].parentWindow, + g_tabCreate[n].title, defaultDir); + dirDialog.SetIcon(wxICON(p7zip_32)); + int ret = dirDialog.ShowModal(); + if (ret == wxID_OK) g_tabCreate[n].resultPath = dirDialog.GetPath(); + return ret; + } + + if (id == DIALOG_ID_FILE_DIALOG) + { + wxString defaultFilename = g_tabCreate[n].initialFolderOrFile; + + wxFileName filename(defaultFilename); + + wxString dir = filename.GetPath(); + wxString name = filename.GetFullName(); + + + // printf("DIALOG_ID_FILE_DIALOG = '%ls' => '%ls' '%ls'\n",&defaultFilename[0],&dir[0],&name[0]); + + + wxFileDialog fileDialog(g_tabCreate[n].parentWindow, g_tabCreate[n].title, + dir, name, wxT("All Files (*.*)|*.*"), wxFD_SAVE|wxFD_OVERWRITE_PROMPT); + fileDialog.SetIcon(wxICON(p7zip_32)); + int ret = fileDialog.ShowModal(); + if (ret == wxID_OK) g_tabCreate[n].resultPath = fileDialog.GetPath(); + return ret; + } + + for(unsigned i=0; i < g_NumDialogs; i++) { + if (id == g_Dialogs[i]->id) { + // DEBUG printf("%d : Create(%d,%p): CreateDialog-1\n",time(0)-g_T0,id,parentWindow); + window = (g_Dialogs[i]->createDialog)(g_tabCreate[n].dialog,g_tabCreate[n].parentWindow); + // DEBUG printf("%d : Create(%d,%p): CreateDialog-2\n",time(0)-g_T0,id,parentWindow); + break; + } + } + + if (window) { + + // DEBUG printf("%d : Create(%d,%p): %p->ShowModal()\n",time(0)-g_T0,id,parentWindow,window); + + // window->Show(true); + // wxGetApp().ProcessPendingEvents(); + + INT_PTR ret = window->ShowModal(); + + // DEBUG printf("%d : Create(%d,%p): %p->ShowModal() - ret=%d\n",time(0)-g_T0,id,parentWindow,window,ret); + window->Detach(); + window->Destroy(); + + // DEBUG printf("%d : Create(%d,%p): END\n",time(0)-g_T0,id,parentWindow,window); + + return ret; + } + + // FIXME + printf("INTERNAL ERROR : cannot find dialog %d\n",id); + + return 0; +} + +void myCreateHandle(int n) +{ + int ret = myCreateHandle2(n); + g_tabCreate[n].ret = ret; + g_tabCreate[n].sem->Post(); +} + +int MessageBoxW(wxWindow * parent, const TCHAR * msg, const TCHAR * title,int flag) +{ + int ind = findFreeInd(); + + g_tabCreate[ind].msg = msg; + g_tabCreate[ind].title = title; + g_tabCreate[ind].flag = flag; + + return WaitInd(parent,ind,DIALOG_ID_MESSAGEBOX,parent); // FIXME +} + + + +// FIXME : should be in Windows/Shell.cpp + +namespace NWindows{ +namespace NShell{ + +bool BrowseForFolder(HWND owner, LPCWSTR title, LPCWSTR initialFolder, UString &resultPath) +{ + int ind = findFreeInd(); + + g_tabCreate[ind].title = title; + g_tabCreate[ind].initialFolderOrFile = nameWindowToUnix(initialFolder); + + UString resTmp; + int ret = WaitInd(0,ind,DIALOG_ID_DIR_DIALOG,owner,resTmp); // FIXME + if(ret == wxID_OK) + { + resultPath = resTmp; + return true; + } + return false; +} + +}} + +/////////////////////////// CPP/Windows/CommonDialog.cpp +namespace NWindows +{ + + bool MyGetOpenFileName(HWND hwnd, LPCWSTR title, LPCWSTR fullFileName, LPCWSTR s, UString &resPath) + { + int ind = findFreeInd(); + + g_tabCreate[ind].title = title; + g_tabCreate[ind].initialFolderOrFile = nameWindowToUnix(fullFileName); + + UString resTmp; + int ret = WaitInd(0,ind,DIALOG_ID_FILE_DIALOG,hwnd,resTmp); // FIXME + if(ret == wxID_OK) + { + resPath = resTmp; + return true; + } + return false; + } +} + diff --git a/src/libs/7zip/unix/CPP/Windows/Control/Dialog.h b/src/libs/7zip/unix/CPP/Windows/Control/Dialog.h new file mode 100644 index 000000000..54899a104 --- /dev/null +++ b/src/libs/7zip/unix/CPP/Windows/Control/Dialog.h @@ -0,0 +1,179 @@ +// Windows/Control/Dialog.h + +#ifndef __WINDOWS_CONTROL_DIALOG_H +#define __WINDOWS_CONTROL_DIALOG_H + +#include "Windows/Window.h" + +#ifndef _WIN32 +#define SW_HIDE 0 +#define SW_SHOW 5 + +#define WM_SETTEXT (6000) // wxID_HIGHEST + 1 +#define WM_USER (6999) // wxID_HIGHEST + 1000 + +#endif + +#ifndef _WIN32 +#define CBN_SELCHANGE 1 +#endif + +// FIXME +#define IDCLOSE (5001) // wxID_CLOSE +#define IDEXIT (5006) // wxID_EXIT +#define IDOK (5100) // wxID_OK +#define IDCANCEL (5101) // wxID_CANCEL +#define IDABORT (5115) // wxID_ABORT +#define IDYES (5103) // wxID_YES +#define IDNO (5104) // wxID_NO +#define IDHELP (5009) // wxID_HELP + +#define BST_CHECKED 1 +#define BST_UNCHECKED 0 +// #define BST_INDETERMINATE 0x0002 + +#define wsprintf(a,b,c,d,e) swprintf(a,9999,b,c,d,e) // FIXME + +namespace NWindows { + namespace NControl { + + class CModalDialogImpl; + + class CDialog + { + protected: + CModalDialogImpl * _window; + public: + operator HWND() const { return HWND(_window); } + + bool OnInit(CModalDialogImpl * window) { + _window = window; + return OnInit(); + } + virtual bool OnInit() { return false; } + virtual void OnOK() {} + virtual void OnCancel() {} + virtual void OnHelp() {} + virtual bool OnButtonClicked(int buttonID, wxWindow * buttonHWND) { return false; } + virtual bool OnMessage(UINT message, WPARAM wParam, LPARAM lParam) { return false; } + virtual bool OnCommand(int code, int itemID, LPARAM lParam) { return false; } + virtual bool OnTimer(WPARAM /* timerID */, LPARAM /* callback */) { return false; } + + void NormalizeSize(bool fullNormalize = false) { /* FIXME */ } + void NormalizePosition() { /* FIXME */ } + }; + + class CModalDialog : public CDialog + { + public: + + + ////////////////// COMPATIBILITY + + bool CheckRadioButton(int firstButtonID, int lastButtonID, int checkButtonID) + { +/* + for(int id = firstButtonID; id <= lastButtonID; id++) + { + CheckButton(id,id == checkButtonID); + } +*/ + this->CheckButton(checkButtonID,true); + + return true; + } + + + bool CheckButton(int buttonID, UINT checkState); + bool CheckButton(int buttonID, bool checkState) + { + return CheckButton(buttonID, UINT(checkState ? BST_CHECKED : BST_UNCHECKED)); + } + + + UINT IsButtonChecked(int buttonID) const; + + bool IsButtonCheckedBool(long buttonID) const + { return (IsButtonChecked(buttonID) == BST_CHECKED); } + + void EnableItem(int id, bool state); + + void SetItemText(int id, const TCHAR *txt); + + wxWindow * GetItem(long id) const ; + + void ShowItem(int itemID, int cmdShow) const; + + void HideItem(int itemID) const { ShowItem(itemID, SW_HIDE); } + + void End(int result); + + void SetText(const TCHAR *_title); // { _dialog->SetTitle(_title); } + + bool GetText(CSysString &s); + + INT_PTR Create(int id , HWND parentWindow); + + void PostMessage(UINT message); + + virtual void OnHelp() {} + + UINT_PTR SetTimer(UINT_PTR idEvent , unsigned milliseconds); + + void KillTimer(UINT_PTR idEvent); + + virtual void OnOK() { End(IDOK); } + virtual void OnCancel() { End(IDCANCEL); } + }; + +class CDialogChildControl : public NWindows::CWindow +{ +public: + CDialogChildControl() {} + + int m_ID; + void Init(const NWindows::NControl::CModalDialog &parentDialog, int id) + { + m_ID = id; + this->Attach(parentDialog.GetItem(id)); + } + virtual void SetText(LPCWSTR s); + virtual bool GetText(CSysString &s); +}; + +} +} + +struct CStringTable +{ + unsigned int id; + const wchar_t *str; +}; + +struct CDialogInfo +{ + unsigned int id; + NWindows::NControl::CModalDialogImpl * (*createDialog)(NWindows::NControl::CModalDialog * dialog, HWND parentWindow); + CStringTable * stringTable; +}; + +void RegisterDialog(const CDialogInfo *dialogInfo); + +#define REGISTER_DIALOG_NAME(x) CRegister ## x + +#define REGISTER_DIALOG(id,x,stringTable) \ + static NWindows::NControl::CModalDialogImpl * myCreate##x(NWindows::NControl::CModalDialog * dialog,HWND parentWindow) \ + { return new x##Impl(dialog,parentWindow,id); } \ + static struct CDialogInfo g_DialogInfo = { id , myCreate##x, stringTable }; \ + struct REGISTER_DIALOG_NAME(x) { \ + REGISTER_DIALOG_NAME(x)() { RegisterDialog(&g_DialogInfo); }}; \ + static REGISTER_DIALOG_NAME(x) g_RegisterDialog; + +#define REGISTER_STRINGTABLE(stringTable) \ + static struct CDialogInfo g_DialogInfo = { -1 , 0 , stringTable }; \ + struct REGISTER_DIALOG_NAME(x) { \ + REGISTER_DIALOG_NAME(x)() { RegisterDialog(&g_DialogInfo); }}; \ + static REGISTER_DIALOG_NAME(x) g_RegisterDialog; + +#endif + diff --git a/src/libs/7zip/unix/CPP/Windows/Control/DialogImpl.h b/src/libs/7zip/unix/CPP/Windows/Control/DialogImpl.h new file mode 100644 index 000000000..a9720b778 --- /dev/null +++ b/src/libs/7zip/unix/CPP/Windows/Control/DialogImpl.h @@ -0,0 +1,73 @@ +// Windows/Control/DialogImpl.h + +#ifndef __WINDOWS_CONTROL_DIALOGIMPL_H +#define __WINDOWS_CONTROL_DIALOGIMPL_H + +#include "Windows/Window.h" +#include "Windows/Control/Dialog.h" + +void myCreateHandle(int n); // FIXME - duplicate + +enum { + WORKER_EVENT=100 // this one gets sent from the worker thread +}; + +namespace NWindows { + namespace NControl { + +#define TIMER_ID_IMPL (1234) + + class CModalDialogImpl : public wxDialog + { + wxTimer _timer; + + CDialog *_dialog; + public: + CModalDialogImpl(CDialog *dialog, wxWindow* parent, wxWindowID id, const wxString& title, + const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, + long style = wxDEFAULT_DIALOG_STYLE ); + + CDialog * Detach() + { + CDialog * oldDialog = _dialog; + _dialog = NULL; + return oldDialog; + } + + void OnInit() + { + if (_dialog) _dialog->OnInit(this); + } + + void OnAnyButton(wxCommandEvent& event); + void OnAnyChoice(wxCommandEvent &event); + void OnAnyTimer(wxTimerEvent &event); + +/* FIXME virtual void SetLabel(const wxString &title) + { + // Why we must do this "alias" ? + this->SetTitle(title); + } +*/ + ////////////////// + UINT_PTR SetTimer(UINT_PTR /* FIXME idEvent */, unsigned milliseconds) + { + _timer.Start(milliseconds); + return TIMER_ID_IMPL; + } + void KillTimer(UINT_PTR idEvent) + { + if (idEvent == TIMER_ID_IMPL) _timer.Stop(); + } + void OnWorkerEvent(wxCommandEvent& event) + { + int n = event.GetInt(); + // printf("CModalDialogImpl::OnWorkerEvent(n=%d)\n",n); + myCreateHandle(n); + } + }; +} +} + +#endif + diff --git a/src/libs/7zip/unix/CPP/Windows/Control/Edit.h b/src/libs/7zip/unix/CPP/Windows/Control/Edit.h new file mode 100644 index 000000000..e6930e5d4 --- /dev/null +++ b/src/libs/7zip/unix/CPP/Windows/Control/Edit.h @@ -0,0 +1,24 @@ +// Windows/Control/Edit.h + +#ifndef __WINDOWS_CONTROL_EDIT_H +#define __WINDOWS_CONTROL_EDIT_H + +#include "Windows/Window.h" +#include "Windows/Defs.h" + +namespace NWindows { +namespace NControl { + +class CEdit: public CWindow +{ +public: + void SetPasswordChar(WPARAM c); + void Show(int cmdShow); + virtual void SetText(LPCWSTR s); + virtual bool GetText(CSysString &s); +}; + +}} + +#endif + diff --git a/src/libs/7zip/unix/CPP/Windows/Control/ListView.h b/src/libs/7zip/unix/CPP/Windows/Control/ListView.h new file mode 100644 index 000000000..149f4a450 --- /dev/null +++ b/src/libs/7zip/unix/CPP/Windows/Control/ListView.h @@ -0,0 +1,164 @@ +// Windows/Control/ListView.h + +#ifndef __WINDOWS_CONTROL_LISTVIEW_H +#define __WINDOWS_CONTROL_LISTVIEW_H + +#include "Windows/Window.h" +#include "Windows/Defs.h" + +/* +#include <commctrl.h> +*/ + +#ifndef _WIN32 + +#define LVCF_FMT 0x0001 +#define LVCF_WIDTH 0x0002 +#define LVCF_TEXT 0x0004 +#define LVCF_SUBITEM 0x0008 +#define LVCF_IMAGE 0x0010 +#define LVCF_ORDER 0x0020 + +#define LVCFMT_LEFT 0x0000 +#define LVCFMT_RIGHT 0x0001 +#define LVCFMT_CENTER 0x0002 +#define LVCFMT_JUSTIFYMASK 0x0003 + + +// state +#define LVIS_FOCUSED 0x0002 /* wxLIST_STATE_FOCUSED */ +#define LVIS_SELECTED 0x0004 /* wxLIST_STATE_SELECTED */ + +#define LVNI_SELECTED 0x0004 /* wxLIST_STATE_SELECTED */ + +typedef INT (CALLBACK *PFNLVCOMPARE)(LPARAM, LPARAM, LPARAM); + +typedef struct tagLVCOLUMNW +{ + UINT mask; + int fmt; + int cx; + LPWSTR pszText; + int cchTextMax; + int iSubItem; + int iOrder; // FIXME +} LVCOLUMNW; + +#define LVCOLUMN LVCOLUMNW +#define LV_COLUMNW LVCOLUMNW /* FIXME */ + + + +typedef struct tagLVITEMW +{ + UINT mask; + int iItem; + int iSubItem; + UINT state; + UINT stateMask; + LPWSTR pszText; + int cchTextMax; + int iImage; + LPARAM lParam; +#if (_WIN32_IE >= 0x0300) + int iIndent; +#endif +#if (_WIN32_WINNT >= 0x501) + int iGroupId; + UINT cColumns; // tile view columns + PUINT puColumns; +#endif +} LVITEMW; + +#define LVITEM LVITEMW + +#define LVIF_TEXT 0x0001 +// FIXME - mask +#define LVIF_PARAM 2 +#define LVIF_IMAGE 4 +#define LVIF_STATE 8 + +#endif + +class wxListCtrl; + +namespace NWindows { +namespace NControl { + +class CListView // : public NWindows::CWindow +{ + wxListCtrl *_list; +public: + CListView() : _list(0) {} + void Attach(wxWindow * newWindow); + + operator HWND() const; + + int GetItemCount() const; + + int InsertItem(int index, LPCTSTR text); + int InsertItem(const LVITEM* item); + + void SetItem(const LVITEM* item); + + int SetSubItem(int index, int subIndex, LPCTSTR text); + + void SetUnicodeFormat(bool fUnicode) { return ; } + + void InsertColumn(int columnIndex, LPCTSTR text, int width); + + void InsertColumn(int columnIndex, const LVCOLUMNW *columnInfo); + + void DeleteAllItems(); + + void SetRedraw(bool); + + void SetItemCount(int ); + + void InvalidateRect(void *, bool); + + int GetSelectedCount() const; + + void /* bool */ EnsureVisible(int index, bool partialOK); + + void SetItemState(int index, UINT state, UINT mask); + + void SetItemState_FocusedSelected(int index) { SetItemState(index, LVIS_FOCUSED | LVIS_SELECTED, LVIS_FOCUSED | LVIS_SELECTED); } + + UINT GetItemState(int index, UINT mask) const; + + void /* bool */ Update(); + + bool DeleteColumn(int columnIndex); + + bool GetItemParam(int itemIndex, LPARAM ¶m) const; + + int GetNextItem(int startIndex, UINT flags) const; + + int GetFocusedItem() const; + + void RedrawAllItems(); + // FIXME added + int GetColumnCount(); + + void SetFocus(); + + void RedrawItem(int item); + + bool SortItems(PFNLVCOMPARE compareFunction, LPARAM dataParam); + + bool GetColumn(int columnIndex, LVCOLUMN* columnInfo); + + // HWND EditLabel(int itemIndex) + void EditLabel(int itemIndex); + + bool SetColumnWidthAuto(int iCol) { + return true; // FIXME SetColumnWidth(iCol, LVSCW_AUTOSIZE); + } + + +}; + +}} +#endif + diff --git a/src/libs/7zip/unix/CPP/Windows/Control/ProgressBar.h b/src/libs/7zip/unix/CPP/Windows/Control/ProgressBar.h new file mode 100644 index 000000000..c7bfa8e8d --- /dev/null +++ b/src/libs/7zip/unix/CPP/Windows/Control/ProgressBar.h @@ -0,0 +1,34 @@ +// Windows/Control/ProgressBar.h + +#ifndef __WINDOWS_CONTROL_PROGRESSBAR_H +#define __WINDOWS_CONTROL_PROGRESSBAR_H + +#include "Windows/Window.h" +#include "Windows/Defs.h" + +class wxGauge; + +namespace NWindows { +namespace NControl { + + +class CProgressBar : public CWindow +{ +protected: + wxGauge* _window; + int _minValue; + int _range; +public: + CProgressBar(wxWindow* newWindow = NULL); + + void Attach(wxWindow* newWindow); + + void SetRange32(int minValue, int maxValue); + + void SetPos(int pos); +}; + +}} + +#endif + diff --git a/src/libs/7zip/unix/CPP/Windows/Control/Static.h b/src/libs/7zip/unix/CPP/Windows/Control/Static.h new file mode 100644 index 000000000..36469c18f --- /dev/null +++ b/src/libs/7zip/unix/CPP/Windows/Control/Static.h @@ -0,0 +1,23 @@ +// Windows/Control/Static.h + +#ifndef __WINDOWS_CONTROL_STATIC_H +#define __WINDOWS_CONTROL_STATIC_H + +#include "Windows/Window.h" +#include "Windows/Defs.h" + +typedef void * HICON; + +namespace NWindows { +namespace NControl { + +class CStatic : public CWindow +{ +public: + + HICON SetIcon(HICON icon) { return 0; } // FIXME +}; + +}} + +#endif diff --git a/src/libs/7zip/unix/CPP/Windows/Control/StatusBar.h b/src/libs/7zip/unix/CPP/Windows/Control/StatusBar.h new file mode 100644 index 000000000..6b4417d10 --- /dev/null +++ b/src/libs/7zip/unix/CPP/Windows/Control/StatusBar.h @@ -0,0 +1,56 @@ +// Windows/Control/StatusBar.h + +#ifndef __WINDOWS_CONTROL_STATUSBAR_H +#define __WINDOWS_CONTROL_STATUSBAR_H + +#include "Windows/Window.h" +#include "Windows/Defs.h" + +class wxStatusBar; + +namespace NWindows { +namespace NControl { + +class CStatusBar // : public NWindows::CWindow +{ + wxStatusBar * _statusBar; +public: + CStatusBar() : _statusBar(0) {} + + void Attach(wxWindow * newWindow); + wxWindow * Detach(); + + void SetText(int index, LPCTSTR text); + +/* FIXME + bool Create(LONG style, LPCTSTR text, HWND hwndParent, UINT id) + { return (_window = ::CreateStatusWindow(style, text, hwndParent, id)) != 0; } + bool SetParts(int numParts, const int *edgePostions) + { return LRESULTToBool(SendMessage(SB_SETPARTS, numParts, (LPARAM)edgePostions)); } + bool SetText(LPCTSTR text) + { return CWindow::SetText(text); } + + bool SetText(int index, LPCTSTR text, UINT type) + { return LRESULTToBool(SendMessage(SB_SETTEXT, index | type, (LPARAM)text)); } + bool SetText(int index, LPCTSTR text) + { return SetText(index, text, 0); } + void Simple(bool simple) + { SendMessage(SB_SIMPLE, BoolToBOOL(simple), 0); } + + #ifndef _UNICODE + bool Create(LONG style, LPCWSTR text, HWND hwndParent, UINT id) + { return (_window = ::CreateStatusWindowW(style, text, hwndParent, id)) != 0; } + bool SetText(LPCWSTR text) + { return CWindow::SetText(text); } + bool SetText(int index, LPCWSTR text, UINT type) + { return LRESULTToBool(SendMessage(SB_SETTEXTW, index | type, (LPARAM)text)); } + bool SetText(int index, LPCWSTR text) + { return SetText(index, text, 0); } + #endif +*/ +}; + +}} + +#endif + diff --git a/src/libs/7zip/unix/CPP/Windows/Control/Window2.cpp b/src/libs/7zip/unix/CPP/Windows/Control/Window2.cpp new file mode 100644 index 000000000..dda1da090 --- /dev/null +++ b/src/libs/7zip/unix/CPP/Windows/Control/Window2.cpp @@ -0,0 +1,211 @@ +// Windows/Control/Window2.cpp + +#include "StdAfx.h" + +#ifndef _UNICODE +#include "Common/StringConvert.h" +#endif +#include "Windows/Control/Window2.h" + +// extern HINSTANCE g_hInstance; +#ifndef _UNICODE +extern bool g_IsNT; +#endif + +namespace NWindows { + +#ifndef _UNICODE +ATOM MyRegisterClass(CONST WNDCLASSW *wndClass); +#endif + +namespace NControl { + +#ifdef _WIN32 +static LRESULT CALLBACK WindowProcedure(HWND aHWND, UINT message, + WPARAM wParam, LPARAM lParam) +{ + CWindow tempWindow(aHWND); + if (message == WM_NCCREATE) + tempWindow.SetUserDataLongPtr( + LONG_PTR(((LPCREATESTRUCT)lParam)->lpCreateParams)); + CWindow2 *window = (CWindow2*)(tempWindow.GetUserDataLongPtr()); + if (window != NULL && message == WM_NCCREATE) + window->Attach(aHWND); + if (window == 0) + { + #ifndef _UNICODE + if (g_IsNT) + return DefWindowProcW(aHWND, message, wParam, lParam); + else + #endif + return DefWindowProc(aHWND, message, wParam, lParam); + } + return window->OnMessage(message, wParam, lParam); +} + +bool CWindow2::CreateEx(DWORD exStyle, LPCTSTR className, + LPCTSTR windowName, DWORD style, + int x, int y, int width, int height, + HWND parentWindow, HMENU idOrHMenu, + HINSTANCE instance) +{ + WNDCLASS windowClass; + if(!::GetClassInfo(instance, className, &windowClass)) + { + // windowClass.style = CS_HREDRAW | CS_VREDRAW; + windowClass.style = 0; + + windowClass.lpfnWndProc = WindowProcedure; + windowClass.cbClsExtra = NULL; + windowClass.cbWndExtra = NULL; + windowClass.hInstance = instance; + windowClass.hIcon = NULL; + windowClass.hCursor = LoadCursor(NULL, IDC_ARROW); + windowClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); + windowClass.lpszMenuName = NULL; + windowClass.lpszClassName = className; + if (::RegisterClass(&windowClass) == 0) + return false; + } + return CWindow::CreateEx(exStyle, className, windowName, + style, x, y, width, height, parentWindow, + idOrHMenu, instance, this); +} + +#ifndef _UNICODE + +bool CWindow2::CreateEx(DWORD exStyle, LPCWSTR className, + LPCWSTR windowName, DWORD style, + int x, int y, int width, int height, + HWND parentWindow, HMENU idOrHMenu, + HINSTANCE instance) +{ + bool needRegister; + if(g_IsNT) + { + WNDCLASSW windowClass; + needRegister = ::GetClassInfoW(instance, className, &windowClass) == 0; + } + else + { + WNDCLASSA windowClassA; + AString classNameA; + LPCSTR classNameP; + if (IS_INTRESOURCE(className)) + classNameP = (LPCSTR)className; + else + { + classNameA = GetSystemString(className); + classNameP = classNameA; + } + needRegister = ::GetClassInfoA(instance, classNameP, &windowClassA) == 0; + } + if (needRegister) + { + WNDCLASSW windowClass; + // windowClass.style = CS_HREDRAW | CS_VREDRAW; + windowClass.style = 0; + windowClass.lpfnWndProc = WindowProcedure; + windowClass.cbClsExtra = NULL; + windowClass.cbWndExtra = NULL; + windowClass.hInstance = instance; + windowClass.hIcon = NULL; + windowClass.hCursor = LoadCursor(NULL, IDC_ARROW); + windowClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); + windowClass.lpszMenuName = NULL; + windowClass.lpszClassName = className; + if (MyRegisterClass(&windowClass) == 0) + return false; + } + return CWindow::CreateEx(exStyle, className, windowName, + style, x, y, width, height, parentWindow, + idOrHMenu, instance, this); + +} +#endif + +LRESULT CWindow2::DefProc(UINT message, WPARAM wParam, LPARAM lParam) +{ + #ifndef _UNICODE + if (g_IsNT) + return DefWindowProcW(_window, message, wParam, lParam); + else + #endif + return DefWindowProc(_window, message, wParam, lParam); +} +#endif + +LRESULT CWindow2::OnMessage(UINT message, WPARAM wParam, LPARAM lParam) +{ + LRESULT result; + switch (message) + { + case WM_CREATE: + if (!OnCreate((CREATESTRUCT *)lParam)) + return -1; + break; + case WM_COMMAND: + if (OnCommand(wParam, lParam, result)) + return result; + break; + case WM_NOTIFY: + if (OnNotify((UINT)wParam, (LPNMHDR) lParam, result)) + return result; + break; + case WM_DESTROY: + OnDestroy(); + break; + case WM_CLOSE: + OnClose(); + return 0; +#ifdef _WIN32 + case WM_SIZE: + if (OnSize(wParam, LOWORD(lParam), HIWORD(lParam))) + return 0; +#endif + } +#ifdef _WIN32 + return DefProc(message, wParam, lParam); +#else + return 0; +#endif +} + +bool CWindow2::OnCommand(WPARAM wParam, LPARAM lParam, LRESULT &result) +{ + return OnCommand(HIWORD(wParam), LOWORD(wParam), lParam, result); +} + +bool CWindow2::OnCommand(int /* code */, int /* itemID */, LPARAM /* lParam */, LRESULT & /* result */) +{ + return false; + // return DefProc(message, wParam, lParam); + /* + if (code == BN_CLICKED) + return OnButtonClicked(itemID, (HWND)lParam); + */ +} + +/* +bool CDialog::OnButtonClicked(int buttonID, HWND buttonHWND) +{ + switch(aButtonID) + { + case IDOK: + OnOK(); + break; + case IDCANCEL: + OnCancel(); + break; + case IDHELP: + OnHelp(); + break; + default: + return false; + } + return true; +} + +*/ + +}} diff --git a/src/libs/7zip/unix/CPP/Windows/Control/Window2.h b/src/libs/7zip/unix/CPP/Windows/Control/Window2.h new file mode 100644 index 000000000..48c890640 --- /dev/null +++ b/src/libs/7zip/unix/CPP/Windows/Control/Window2.h @@ -0,0 +1,111 @@ +// Windows/Control/Window2.h + +#ifndef __WINDOWS_CONTROL_WINDOW2_H +#define __WINDOWS_CONTROL_WINDOW2_H + +#include "Windows/Window.h" +#include "Windows/Defs.h" + +#ifndef _WIN32 +typedef void * WNDPROC; +typedef void * CREATESTRUCT; +typedef struct +{ + HWND hwndFrom; + + UINT code; +#define NM_DBLCLK 1 +#define LVN_ITEMCHANGED 2 +#define LVN_COLUMNCLICK 3 +#define CBEN_BEGINEDIT 10 +#define CBEN_ENDEDITW 11 + + +} NMHDR; +typedef NMHDR * LPNMHDR; + +typedef struct tagNMLISTVIEW +{ + NMHDR hdr; + INT iItem; + INT iSubItem; + UINT uNewState; + UINT uOldState; + // UINT uChanged; + // POINT ptAction; + LPARAM lParam; +} NMLISTVIEW, *LPNMLISTVIEW; + +typedef void * LPNMITEMACTIVATE; + +#define NM_RCLICK 1234 /* FIXME */ + +// FIXME +#define WM_CREATE 1 +#define WM_COMMAND 2 +#define WM_NOTIFY 3 +#define WM_DESTROY 4 +#define WM_CLOSE 5 + +#define HIWORD(l) ((WORD)((DWORD_PTR)(l) >> 16)) +#define LOWORD(l) ((WORD)((DWORD_PTR)(l) & 0xFFFF)) + + +#endif + +namespace NWindows { +namespace NControl { + +class CWindow2 // : public CWindow +{ + // LRESULT DefProc(UINT message, WPARAM wParam, LPARAM lParam); +public: + // CWindow2(HWND newWindow = NULL): CWindow(newWindow){}; + CWindow2() {} + virtual ~CWindow2() {} + +#ifdef _WIN32 + bool CreateEx(DWORD exStyle, LPCTSTR className, + LPCTSTR windowName, DWORD style, + int x, int y, int width, int height, + HWND parentWindow, HMENU idOrHMenu, + HINSTANCE instance); + + #ifndef _UNICODE + bool CreateEx(DWORD exStyle, LPCWSTR className, + LPCWSTR windowName, DWORD style, + int x, int y, int width, int height, + HWND parentWindow, HMENU idOrHMenu, + HINSTANCE instance); + #endif +#endif + + virtual LRESULT OnMessage(UINT message, WPARAM wParam, LPARAM lParam); + virtual bool OnCreate(CREATESTRUCT * /* createStruct */) { return true; } + // virtual LRESULT OnCommand(WPARAM wParam, LPARAM lParam); + virtual bool OnCommand(WPARAM wParam, LPARAM lParam, LRESULT &result); + virtual bool OnCommand(int code, int itemID, LPARAM lParam, LRESULT &result); + virtual bool OnSize(WPARAM /* wParam */, int /* xSize */, int /* ySize */) { return false; } + virtual bool OnNotify(UINT /* controlID */, LPNMHDR /* lParam */, LRESULT & /* result */) { return false; } + virtual void OnDestroy() { /* FIXME PostQuitMessage(0); */ } + virtual void OnClose() { /* FIXME Destroy(); */ } + /* + virtual LRESULT OnHelp(LPHELPINFO helpInfo) { OnHelp(); }; + virtual LRESULT OnHelp() {}; + virtual bool OnButtonClicked(int buttonID, HWND buttonHWND); + virtual void OnOK() {}; + virtual void OnCancel() {}; + */ + +#ifdef _WIN32 + LONG_PTR SetMsgResult(LONG_PTR newLongPtr ) + { return SetLongPtr(DWLP_MSGRESULT, newLongPtr); } + LONG_PTR GetMsgResult() const + { return GetLongPtr(DWLP_MSGRESULT); } +#endif +}; + +}} + +#endif + diff --git a/src/libs/7zip/unix/CPP/Windows/DLL.cpp b/src/libs/7zip/unix/CPP/Windows/DLL.cpp new file mode 100644 index 000000000..5f76cc5e2 --- /dev/null +++ b/src/libs/7zip/unix/CPP/Windows/DLL.cpp @@ -0,0 +1,193 @@ +// Windows/DLL.cpp + +#include "StdAfx.h" + +#ifdef __APPLE_CC__ +#include <mach-o/dyld.h> +#elif ENV_BEOS +#include <kernel/image.h> +#include <Path.h> +#else +#define UINT64 DLL_UINT64 // HP-UX , dlfcn.h defines UINT64 but p7zip also defines UINT64 +#include <dlfcn.h> // dlopen ... +#undef UINT64 +#endif + +#include "DLL.h" +#include "Defs.h" +#ifdef _UNICODE +#include "../Common/StringConvert.h" +#endif + +#define NEED_NAME_WINDOWS_TO_UNIX +#include "myPrivate.h" + +// #define TRACEN(u) u; +#define TRACEN(u) /* */ + +namespace NWindows { +namespace NDLL { + +CLibrary::~CLibrary() +{ + Free(); +} + +bool CLibrary::Free() +{ +TRACEN((printf("CLibrary::Free(%p)\n",(void *)_module))) + if (_module == 0) + return true; + +#ifdef __APPLE_CC__ + int ret = NSUnLinkModule ((NSModule)_module, 0); +#elif ENV_BEOS + int ret = unload_add_on((image_id)_module); +#else + int ret = dlclose(_module); +#endif +TRACEN((printf("CLibrary::Free dlclose(%p)=%d\n",(void *)_module,ret))) + if (ret != 0) return false; + _module = 0; + return true; +} + +static FARPROC local_GetProcAddress(HMODULE module,LPCSTR lpProcName) +{ + void *ptr = 0; + TRACEN((printf("local_GetProcAddress(%p,%s)\n",(void *)module,lpProcName))) + if (module) { +#ifdef __APPLE_CC__ + char name[MAX_PATHNAME_LEN]; + snprintf(name,sizeof(name),"_%s",lpProcName); + name[sizeof(name)-1] = 0; + TRACEN((printf("NSLookupSymbolInModule(%p,%s)\n",(void *)module,name))) + NSSymbol sym; + sym = NSLookupSymbolInModule((NSModule)module, name); + if (sym) { + ptr = NSAddressOfSymbol(sym); + } else { + ptr = 0; + } +#elif ENV_BEOS + if (get_image_symbol((image_id)module, lpProcName, B_SYMBOL_TYPE_TEXT, &ptr) != B_OK) + ptr = 0; +#else + ptr = dlsym (module, lpProcName); +#endif + TRACEN((printf("CLibrary::GetProc : dlsym(%p,%s)=%p\n",(void *)module,lpProcName,ptr))) + } + return (FARPROC)ptr; +} + +FARPROC CLibrary::GetProc(LPCSTR lpProcName) const +{ + TRACEN((printf("CLibrary::GetProc(%p,%s)\n",(void *)_module,lpProcName))) + return local_GetProcAddress(_module,lpProcName); +} + +bool CLibrary::LoadOperations(HMODULE newModule) +{ + if (newModule == NULL) + return false; + if(!Free()) + return false; + _module = newModule; + return true; +} + +bool CLibrary::Load(LPCTSTR lpLibFileName) +{ + void *handler = 0; + char name[MAX_PATHNAME_LEN+1]; +#ifdef _UNICODE + AString name2 = UnicodeStringToMultiByte(lpLibFileName); + strcpy(name,nameWindowToUnix((const char *)name2)); +#else + strcpy(name,nameWindowToUnix(lpLibFileName)); +#endif + + // replace ".dll" with ".so" + size_t len = strlen(name); + if ((len >=4) && (strcmp(name+len-4,".dll") == 0)) { + strcpy(name+len-4,".so"); + } + + TRACEN((printf("CLibrary::Load(%ls) => %s\n",lpLibFileName,name))) + +#ifdef __APPLE_CC__ + NSObjectFileImage image; + NSObjectFileImageReturnCode nsret; + + nsret = NSCreateObjectFileImageFromFile (name, &image); + if (nsret == NSObjectFileImageSuccess) { + TRACEN((printf("NSCreateObjectFileImageFromFile(%s) : OK\n",name))) + handler = (HMODULE)NSLinkModule(image,name,NSLINKMODULE_OPTION_RETURN_ON_ERROR + | NSLINKMODULE_OPTION_PRIVATE | NSLINKMODULE_OPTION_BINDNOW); + } else { + TRACEN((printf("NSCreateObjectFileImageFromFile(%s) : ERROR\n",name))) + } +#elif ENV_BEOS + // normalize path (remove things like "./", "..", etc..), otherwise it won't work + BPath p(name, NULL, true); + status_t err = B_OK; + image_id image = load_add_on(p.Path()); +TRACEN((printf("load_add_on(%s)=%d\n",p.Path(),(int)image))) + if (image < 0) { + err = (image_id)handler; + handler = 0; + } else { + err = 0; + handler = (HMODULE)image; + } +#else + int options_dlopen = 0; +#ifdef RTLD_LOCAL + options_dlopen |= RTLD_LOCAL; +#endif +#ifdef RTLD_NOW + options_dlopen |= RTLD_NOW; +#endif +#ifdef RTLD_GROUP + #if ! (defined(hpux) || defined(__hpux)) + options_dlopen |= RTLD_GROUP; // mainly for solaris but not for HPUX + #endif +#endif + TRACEN((printf("CLibrary::Load - dlopen(%s,0x%d)\n",name,options_dlopen))) + handler = dlopen(name,options_dlopen); +#endif // __APPLE_CC__ + TRACEN((printf("CLibrary::Load(%s) => %p\n",name,handler))) + if (handler) { + + // Call DllMain() like in Windows : useless now + + // Propagate the value of global_use_utf16_conversion into the plugins + int *tmp = (int *)local_GetProcAddress(handler,"global_use_utf16_conversion"); + if (tmp) *tmp = global_use_utf16_conversion; + + tmp = (int *)local_GetProcAddress(handler,"global_use_lstat"); + if (tmp) *tmp = global_use_lstat; + + // test construtors calls + void (*fctTest)(void) = (void (*)(void))local_GetProcAddress(handler,"sync_TestConstructor"); + if (fctTest) fctTest(); + + } else { +#ifdef __APPLE_CC__ + NSLinkEditErrors c; + int num_err; + const char *file,*err; + NSLinkEditError(&c,&num_err,&file,&err); + printf("Can't load '%ls' (%s)\n", lpLibFileName,err); +#elif ENV_BEOS + printf("Can't load '%ls' (%s)\n", lpLibFileName,strerror(err)); +#else + printf("Can't load '%ls' (%s)\n", lpLibFileName,dlerror()); +#endif + } + + return LoadOperations(handler); +} + +}} + diff --git a/src/libs/7zip/unix/CPP/Windows/DLL.h b/src/libs/7zip/unix/CPP/Windows/DLL.h new file mode 100644 index 000000000..9b57bec8a --- /dev/null +++ b/src/libs/7zip/unix/CPP/Windows/DLL.h @@ -0,0 +1,48 @@ +// Windows/DLL.h + +#ifndef __WINDOWS_DLL_H +#define __WINDOWS_DLL_H + +#include "../Common/MyString.h" + +typedef void * HMODULE; + +typedef int (*FARPROC)(); + +namespace NWindows { +namespace NDLL { + +class CLibrary +{ + bool LoadOperations(HMODULE newModule); + HMODULE _module; +public: + operator HMODULE() const { return _module; } + HMODULE* operator&() { return &_module; } + + + CLibrary():_module(NULL) {}; + ~CLibrary(); + + bool Free(); + + void Attach(HMODULE m) + { + Free(); + _module = m; + } + HMODULE Detach() + { + HMODULE m = _module; + _module = NULL; + return m; + } + + + bool Load(LPCTSTR fileName); + FARPROC GetProc(LPCSTR procName) const; +}; + +}} + +#endif diff --git a/src/libs/7zip/unix/CPP/Windows/Defs.h b/src/libs/7zip/unix/CPP/Windows/Defs.h new file mode 100644 index 000000000..bad4e3552 --- /dev/null +++ b/src/libs/7zip/unix/CPP/Windows/Defs.h @@ -0,0 +1,17 @@ +// Windows/Defs.h + +#ifndef __WINDOWS_DEFS_H +#define __WINDOWS_DEFS_H + +#include "../Common/MyWindows.h" + +// #ifdef _WIN32 +inline bool LRESULTToBool(LRESULT v) { return (v != FALSE); } +inline bool BOOLToBool(BOOL v) { return (v != FALSE); } +inline BOOL BoolToBOOL(bool v) { return (v ? TRUE: FALSE); } +// #endif + +inline VARIANT_BOOL BoolToVARIANT_BOOL(bool v) { return (v ? VARIANT_TRUE: VARIANT_FALSE); } +inline bool VARIANT_BOOLToBool(VARIANT_BOOL v) { return (v != VARIANT_FALSE); } + +#endif diff --git a/src/libs/7zip/unix/CPP/Windows/Error.cpp b/src/libs/7zip/unix/CPP/Windows/Error.cpp new file mode 100644 index 000000000..88008d711 --- /dev/null +++ b/src/libs/7zip/unix/CPP/Windows/Error.cpp @@ -0,0 +1,58 @@ +// Windows/Error.h + +#include "StdAfx.h" + +#include "Windows/Error.h" +#include "Common/StringConvert.h" + +namespace NWindows { +namespace NError { + +bool MyFormatMessage(DWORD messageID, CSysString &message) +{ + const char * txt = 0; + AString msg; + + switch(messageID) { + case ERROR_NO_MORE_FILES : txt = "No more files"; break ; + case E_NOTIMPL : txt = "E_NOTIMPL"; break ; + case E_NOINTERFACE : txt = "E_NOINTERFACE"; break ; + case E_ABORT : txt = "E_ABORT"; break ; + case E_FAIL : txt = "E_FAIL"; break ; + case STG_E_INVALIDFUNCTION : txt = "STG_E_INVALIDFUNCTION"; break ; + case E_OUTOFMEMORY : txt = "E_OUTOFMEMORY"; break ; + case E_INVALIDARG : txt = "E_INVALIDARG"; break ; + default: + txt = strerror(messageID); + } + if (txt) { + msg = txt; + } else { + char msgBuf[256]; + snprintf(msgBuf,sizeof(msgBuf),"error #%x",(unsigned)messageID); + msgBuf[sizeof(msgBuf)-1] = 0; + msg = msgBuf; + } + + msg += " "; + +#ifdef _UNICODE + message = MultiByteToUnicodeString(msg); +#else + message = msg; +#endif + return true; +} + +#ifndef _UNICODE +bool MyFormatMessage(DWORD messageID, UString &message) +{ + CSysString messageSys; + bool result = MyFormatMessage(messageID, messageSys); + message = GetUnicodeString(messageSys); + return result; +} +#endif + +}} + diff --git a/src/libs/7zip/unix/CPP/Windows/Error.h b/src/libs/7zip/unix/CPP/Windows/Error.h new file mode 100644 index 000000000..05b5cd0ea --- /dev/null +++ b/src/libs/7zip/unix/CPP/Windows/Error.h @@ -0,0 +1,33 @@ +// Windows/Error.h + +#ifndef __WINDOWS_ERROR_H +#define __WINDOWS_ERROR_H + +#include "Common/MyString.h" + +namespace NWindows { +namespace NError { + +bool MyFormatMessage(DWORD messageID, CSysString &message); +inline CSysString MyFormatMessage(DWORD messageID) +{ + CSysString message; + MyFormatMessage(messageID, message); + return message; +} +#ifdef _UNICODE +inline UString MyFormatMessageW(DWORD messageID) + { return MyFormatMessage(messageID); } +#else +bool MyFormatMessage(DWORD messageID, UString &message); +inline UString MyFormatMessageW(DWORD messageID) +{ + UString message; + MyFormatMessage(messageID, message); + return message; +} +#endif + +}} + +#endif diff --git a/src/libs/7zip/unix/CPP/Windows/FileDir.cpp b/src/libs/7zip/unix/CPP/Windows/FileDir.cpp new file mode 100644 index 000000000..838f92d5b --- /dev/null +++ b/src/libs/7zip/unix/CPP/Windows/FileDir.cpp @@ -0,0 +1,927 @@ +// Windows/FileDir.cpp + +#include "StdAfx.h" + +#include "FileDir.h" +#include "FileName.h" +#include "FileFind.h" +#include "Defs.h" +#include "../Common/StringConvert.h" +#include "../Common/IntToString.h" + +#define NEED_NAME_WINDOWS_TO_UNIX +#include "myPrivate.h" +#include "Windows/Synchronization.h" + +#include <unistd.h> // rmdir +#include <errno.h> + +#include <sys/stat.h> // mkdir +#include <sys/types.h> +#include <fcntl.h> + +#include <utime.h> + +// #define TRACEN(u) u; +#define TRACEN(u) /* */ + +class Umask +{ + public: + mode_t current_umask; + mode_t mask; + Umask() { + current_umask = umask (0); /* get and set the umask */ + umask(current_umask); /* restore the umask */ + mask = 0777 & (~current_umask); + } +}; + +static Umask gbl_umask; + +#ifdef _UNICODE +AString nameWindowToUnix2(LPCWSTR name) // FIXME : optimization ? +{ + AString astr = UnicodeStringToMultiByte(name); + return AString(nameWindowToUnix((const char *)astr)); +} +#endif + +extern BOOLEAN WINAPI RtlTimeToSecondsSince1970( const LARGE_INTEGER *Time, DWORD *Seconds ); + +#ifdef _UNICODE +DWORD WINAPI GetFullPathName( LPCTSTR name, DWORD len, LPTSTR buffer, LPTSTR *lastpart ) { // FIXME + if (name == 0) return 0; + + DWORD name_len = lstrlen(name); + + if (name[0] == '/') { + DWORD ret = name_len+2; + if (ret >= len) { + TRACEN((printf("GetFullPathNameA(%ls,%d,)=0000 (case 0)\n",name, (int)len))) + return 0; + } + lstrcpy(buffer,L"c:"); + lstrcat(buffer,name); + + *lastpart=buffer; + TCHAR *ptr=buffer; + while (*ptr) { + if (*ptr == '/') + *lastpart=ptr+1; + ptr++; + } + TRACEN((printf("GetFullPathNameA(%s,%d,%ls,%ls)=%d\n",name, (int)len,buffer, *lastpart,(int)ret))) + return ret; + } + if (isascii(name[0]) && (name[1] == ':')) { // FIXME isascii + DWORD ret = name_len; + if (ret >= len) { + TRACEN((printf("GetFullPathNameA(%ls,%d,)=0000 (case 1)\n",name, (int)len))) + return 0; + } + lstrcpy(buffer,name); + + *lastpart=buffer; + TCHAR *ptr=buffer; + while (*ptr) { + if (*ptr == '/') + *lastpart=ptr+1; + ptr++; + } + TRACEN((printf("GetFullPathNameA(%sl,%d,%ls,%ls)=%d\n",name, (int)len,buffer, *lastpart,(int)ret))) + return ret; + } + + // name is a relative pathname. + // + if (len < 2) { + TRACEN((printf("GetFullPathNameA(%s,%d,)=0000 (case 2)\n",name, (int)len))) + return 0; + } + + DWORD ret = 0; + char begin[MAX_PATHNAME_LEN]; + /* DWORD begin_len = GetCurrentDirectoryA(MAX_PATHNAME_LEN,begin); */ + DWORD begin_len = 0; + begin[0]='c'; + begin[1]=':'; + char * cret = getcwd(begin+2, MAX_PATHNAME_LEN - 3); + if (cret) { + begin_len = strlen(begin); + } + + if (begin_len >= 1) { + // strlen(begin) + strlen("/") + strlen(name) + ret = begin_len + 1 + name_len; + + if (ret >= len) { + TRACEN((printf("GetFullPathNameA(%s,%d,)=0000 (case 4)\n",name, (int)len))) + return 0; + } + UString wbegin = GetUnicodeString(begin); + lstrcpy(buffer,wbegin); + lstrcat(buffer,L"/"); + lstrcat(buffer,name); + + *lastpart=buffer + begin_len + 1; + TCHAR *ptr=buffer; + while (*ptr) { + if (*ptr == '/') + *lastpart=ptr+1; + ptr++; + } + TRACEN((printf("GetFullPathNameA(%s,%d,%s,%s)=%d\n",name, (int)len,buffer, *lastpart,(int)ret))) + } else { + ret = 0; + TRACEN((printf("GetFullPathNameA(%s,%d,)=0000 (case 5)\n",name, (int)len))) + } + return ret; +} + +#endif + +#if 0 +DWORD WINAPI GetFullPathName( LPCSTR name, DWORD len, LPSTR buffer, LPSTR *lastpart ) { + if (name == 0) return 0; + + DWORD name_len = strlen(name); + + if (name[0] == '/') { + DWORD ret = name_len+2; + if (ret >= len) { + TRACEN((printf("GetFullPathNameA(%s,%d,)=0000 (case 0)\n",name, (int)len))) + return 0; + } + strcpy(buffer,"c:"); + strcat(buffer,name); + + *lastpart=buffer; + char *ptr=buffer; + while (*ptr) { + if (*ptr == '/') + *lastpart=ptr+1; + ptr++; + } + TRACEN((printf("GetFullPathNameA(%s,%d,%s,%s)=%d\n",name, (int)len,buffer, *lastpart,(int)ret))) + return ret; + } + if (isascii(name[0]) && (name[1] == ':')) { + DWORD ret = name_len; + if (ret >= len) { + TRACEN((printf("GetFullPathNameA(%s,%d,)=0000 (case 1)\n",name, (int)len))) + return 0; + } + strcpy(buffer,name); + + *lastpart=buffer; + char *ptr=buffer; + while (*ptr) { + if (*ptr == '/') + *lastpart=ptr+1; + ptr++; + } + TRACEN((printf("GetFullPathNameA(%s,%d,%s,%s)=%d\n",name, (int)len,buffer, *lastpart,(int)ret))) + return ret; + } + + // name is a relative pathname. + // + if (len < 2) { + TRACEN((printf("GetFullPathNameA(%s,%d,)=0000 (case 2)\n",name, (int)len))) + return 0; + } + + DWORD ret = 0; + char begin[MAX_PATHNAME_LEN]; + /* DWORD begin_len = GetCurrentDirectoryA(MAX_PATHNAME_LEN,begin); */ + DWORD begin_len = 0; + begin[0]='c'; + begin[1]=':'; + char * cret = getcwd(begin+2, MAX_PATHNAME_LEN - 3); + if (cret) { + begin_len = strlen(begin); + } + + if (begin_len >= 1) { + // strlen(begin) + strlen("/") + strlen(name) + ret = begin_len + 1 + name_len; + + if (ret >= len) { + TRACEN((printf("GetFullPathNameA(%s,%d,)=0000 (case 4)\n",name, (int)len))) + return 0; + } + strcpy(buffer,begin); + strcat(buffer,"/"); + strcat(buffer,name); + + *lastpart=buffer + begin_len + 1; + char *ptr=buffer; + while (*ptr) { + if (*ptr == '/') + *lastpart=ptr+1; + ptr++; + } + TRACEN((printf("GetFullPathNameA(%s,%d,%s,%s)=%d\n",name, (int)len,buffer, *lastpart,(int)ret))) + } else { + ret = 0; + TRACEN((printf("GetFullPathNameA(%s,%d,)=0000 (case 5)\n",name, (int)len))) + } + return ret; +} + +static BOOL WINAPI RemoveDirectory(LPCSTR path) { + if (!path || !*path) { + SetLastError(ERROR_PATH_NOT_FOUND); + return FALSE; + } + const char * name = nameWindowToUnix(path); + TRACEN((printf("RemoveDirectoryA(%s)\n",name))) + + if (rmdir( name ) != 0) { + return FALSE; + } + return TRUE; +} +#endif + +#ifdef _UNICODE +static BOOL WINAPI RemoveDirectory(LPCWSTR path) { + if (!path || !*path) { + SetLastError(ERROR_PATH_NOT_FOUND); + return FALSE; + } + AString name = nameWindowToUnix2(path); + TRACEN((printf("RemoveDirectoryA(%s)\n",(const char *)name))) + + if (rmdir( (const char *)name ) != 0) { + return FALSE; + } + return TRUE; +} +#endif + +static int copy_fd(int fin,int fout) +{ + char buffer[16384]; + ssize_t ret_in; + ssize_t ret_out; + + do { + ret_out = -1; + do { + ret_in = read(fin, buffer,sizeof(buffer)); + } while (ret_in < 0 && (errno == EINTR)); + if (ret_in >= 1) { + do { + ret_out = write (fout, buffer, ret_in); + } while (ret_out < 0 && (errno == EINTR)); + } else if (ret_in == 0) { + ret_out = 0; + } + } while (ret_out >= 1); + return ret_out; +} + +static BOOL CopyFile(const char *src,const char *dst) +{ + int ret = -1; + +#ifdef O_BINARY + int flags = O_BINARY; +#else + int flags = 0; +#endif + +#ifdef O_LARGEFILE + flags |= O_LARGEFILE; +#endif + + int fout = open(dst,O_CREAT | O_WRONLY | O_EXCL | flags, 0600); + if (fout != -1) + { + int fin = open(src,O_RDONLY | flags , 0600); + if (fin != -1) + { + ret = copy_fd(fin,fout); + if (ret == 0) ret = close(fin); + else close(fin); + } + if (ret == 0) ret = close(fout); + else close(fout); + } + if (ret == 0) return TRUE; + return FALSE; +} + +/*****************************************************************************************/ + + +namespace NWindows { +namespace NFile { +namespace NDirectory { + + +bool MySetCurrentDirectory(LPCWSTR wpath) +{ + AString path = UnicodeStringToMultiByte(wpath); + + return chdir((const char*)path) == 0; +} + +#ifdef _UNICODE +bool GetOnlyName(LPCTSTR fileName, CSysString &resultName) +{ + int index; + if (!MyGetFullPathName(fileName, resultName, index)) + return false; + resultName = resultName.Mid(index); + return true; +} + +bool GetOnlyDirPrefix(LPCTSTR fileName, CSysString &resultName) +{ + int index; + if (!MyGetFullPathName(fileName, resultName, index)) + return false; + resultName = resultName.Left(index); + return true; +} +#endif + + +bool MyGetCurrentDirectory(CSysString &resultPath) +{ + char begin[MAX_PATHNAME_LEN]; + begin[0]='c'; + begin[1]=':'; + char * cret = getcwd(begin+2, MAX_PATHNAME_LEN - 3); + if (cret) + { +#ifdef _UNICODE + resultPath = GetUnicodeString(begin); +#else + resultPath = begin; +#endif + return true; + } + return false; +} + +bool MyMoveFile( LPCTSTR fn1, LPCTSTR fn2 ) { +#ifdef _UNICODE + AString src = nameWindowToUnix2(fn1); + AString dst = nameWindowToUnix2(fn2); +#else + const char * src = nameWindowToUnix(fn1); + const char * dst = nameWindowToUnix(fn2); +#endif + + TRACEN((printf("MoveFileW(%s,%s)\n",src,dst))) + + int ret = rename(src,dst); + if (ret != 0) + { + if (errno == EXDEV) // FIXED : bug #1112167 (Temporary directory must be on same partition as target) + { + BOOL bret = CopyFile(src,dst); + if (bret == FALSE) return false; + + struct stat info_file; + ret = stat(src,&info_file); + if (ret == 0) { + TRACEN((printf("##DBG chmod-1(%s,%o)\n",dst,(unsigned)info_file.st_mode & gbl_umask.mask))) + ret = chmod(dst,info_file.st_mode & gbl_umask.mask); + } + if (ret == 0) { + ret = unlink(src); + } + if (ret == 0) return true; + } + return false; + } + return true; +} + +bool MyRemoveDirectory(LPCTSTR pathName) +{ + return BOOLToBool(::RemoveDirectory(pathName)); +} + +bool SetDirTime(LPCWSTR fileName, const FILETIME * /* creationTime */ , + const FILETIME *lpLastAccessTime, const FILETIME *lpLastWriteTime) +{ + AString cfilename = UnicodeStringToMultiByte(fileName); + const char * unix_filename = nameWindowToUnix((const char *)cfilename); + + struct utimbuf buf; + + struct stat oldbuf; + int ret = stat(unix_filename,&oldbuf); + if (ret == 0) { + buf.actime = oldbuf.st_atime; + buf.modtime = oldbuf.st_mtime; + } else { + time_t current_time = time(0); + buf.actime = current_time; + buf.modtime = current_time; + } + + if (lpLastAccessTime) + { + LARGE_INTEGER ltime; + DWORD dw; + ltime.QuadPart = lpLastAccessTime->dwHighDateTime; + ltime.QuadPart = (ltime.QuadPart << 32) | lpLastAccessTime->dwLowDateTime; + RtlTimeToSecondsSince1970( <ime, &dw ); + buf.actime = dw; + } + + if (lpLastWriteTime) + { + LARGE_INTEGER ltime; + DWORD dw; + ltime.QuadPart = lpLastWriteTime->dwHighDateTime; + ltime.QuadPart = (ltime.QuadPart << 32) | lpLastWriteTime->dwLowDateTime; + RtlTimeToSecondsSince1970( <ime, &dw ); + buf.modtime = dw; + } + + /* ret = */ utime(unix_filename, &buf); + + return true; +} + +#ifndef _UNICODE +bool MySetFileAttributes(LPCWSTR fileName, DWORD fileAttributes) +{ + return MySetFileAttributes(UnicodeStringToMultiByte(fileName, CP_ACP), fileAttributes); +} + +bool MyRemoveDirectory(LPCWSTR pathName) +{ + return MyRemoveDirectory(UnicodeStringToMultiByte(pathName, CP_ACP)); +} + +bool MyMoveFile(LPCWSTR existFileName, LPCWSTR newFileName) +{ + UINT codePage = CP_ACP; + return MyMoveFile(UnicodeStringToMultiByte(existFileName, codePage), UnicodeStringToMultiByte(newFileName, codePage)); +} +#endif + + +static int convert_to_symlink(const char * name) { + FILE *file = fopen(name,"rb"); + if (file) { + char buf[MAX_PATHNAME_LEN+1]; + char * ret = fgets(buf,sizeof(buf)-1,file); + fclose(file); + if (ret) { + int ir = unlink(name); + if (ir == 0) { + ir = symlink(buf,name); + } + return ir; + } + } + return -1; +} + +bool MySetFileAttributes(LPCTSTR fileName, DWORD fileAttributes) +{ + if (!fileName) { + SetLastError(ERROR_PATH_NOT_FOUND); + TRACEN((printf("MySetFileAttributes(NULL,%d) : false-1\n",fileAttributes))) + return false; + } +#ifdef _UNICODE + AString name = nameWindowToUnix2(fileName); +#else + const char * name = nameWindowToUnix(fileName); +#endif + struct stat stat_info; +#ifdef ENV_HAVE_LSTAT + if (global_use_lstat) { + if(lstat(name,&stat_info)!=0) { + TRACEN((printf("MySetFileAttributes(%s,%d) : false-2-1\n",name,fileAttributes))) + return false; + } + } else +#endif + { + if(stat(name,&stat_info)!=0) { + TRACEN((printf("MySetFileAttributes(%s,%d) : false-2-2\n",name,fileAttributes))) + return false; + } + } + + if (fileAttributes & FILE_ATTRIBUTE_UNIX_EXTENSION) { + stat_info.st_mode = fileAttributes >> 16; +#ifdef ENV_HAVE_LSTAT + if (S_ISLNK(stat_info.st_mode)) { + if ( convert_to_symlink(name) != 0) { + TRACEN((printf("MySetFileAttributes(%s,%d) : false-3\n",name,fileAttributes))) + return false; + } + } else +#endif + if (S_ISREG(stat_info.st_mode)) { + TRACEN((printf("##DBG chmod-2(%s,%o)\n",name,(unsigned)stat_info.st_mode & gbl_umask.mask))) + chmod(name,stat_info.st_mode & gbl_umask.mask); + } else if (S_ISDIR(stat_info.st_mode)) { + // user/7za must be able to create files in this directory + stat_info.st_mode |= (S_IRUSR | S_IWUSR | S_IXUSR); + TRACEN((printf("##DBG chmod-3(%s,%o)\n",name,(unsigned)stat_info.st_mode & gbl_umask.mask))) + chmod(name,stat_info.st_mode & gbl_umask.mask); + } +#ifdef ENV_HAVE_LSTAT + } else if (!S_ISLNK(stat_info.st_mode)) { + // do not use chmod on a link +#else + } else { +#endif + + /* Only Windows Attributes */ + if( S_ISDIR(stat_info.st_mode)) { + /* Remark : FILE_ATTRIBUTE_READONLY ignored for directory. */ + TRACEN((printf("##DBG chmod-4(%s,%o)\n",name,(unsigned)stat_info.st_mode & gbl_umask.mask))) + chmod(name,stat_info.st_mode & gbl_umask.mask); + } else { + if (fileAttributes & FILE_ATTRIBUTE_READONLY) stat_info.st_mode &= ~0222; /* octal!, clear write permission bits */ + TRACEN((printf("##DBG chmod-5(%s,%o)\n",name,(unsigned)stat_info.st_mode & gbl_umask.mask))) + chmod(name,stat_info.st_mode & gbl_umask.mask); + } + } + TRACEN((printf("MySetFileAttributes(%s,%d) : true\n",name,fileAttributes))) + + return true; +} + +bool MyCreateDirectory(LPCTSTR pathName) +{ + if (!pathName || !*pathName) { + SetLastError(ERROR_PATH_NOT_FOUND); + return false; + } + +#ifdef _UNICODE + AString name = nameWindowToUnix2(pathName); +#else + const char * name = nameWindowToUnix(pathName); +#endif + bool bret = false; + if (mkdir( name, 0700 ) == 0) bret = true; + + TRACEN((printf("MyCreateDirectory(%s)=%d\n",name,(int)bret))) + return bret; +} + +#ifndef _UNICODE +bool MyCreateDirectory(LPCWSTR pathName) +{ + return MyCreateDirectory(UnicodeStringToMultiByte(pathName, CP_ACP)); +} +#endif + +bool CreateComplexDirectory(LPCTSTR _aPathName) +{ + CSysString pathName = _aPathName; + int pos = pathName.ReverseFind(TEXT(CHAR_PATH_SEPARATOR)); + if (pos > 0 && pos == pathName.Length() - 1) + { + if (pathName.Length() == 3 && pathName[1] == ':') + return true; // Disk folder; + pathName.Delete(pos); + } + CSysString pathName2 = pathName; + pos = pathName.Length(); + while(true) + { + if(MyCreateDirectory(pathName)) + break; + if(::GetLastError() == ERROR_ALREADY_EXISTS) + { +#ifdef _WIN32 // FIXED for supporting symbolic link instead of a directory + NFind::CFileInfo fileInfo; + if (!NFind::FindFile(pathName, fileInfo)) // For network folders + return true; + if (!fileInfo.IsDir()) + return false; +#endif + break; + } + pos = pathName.ReverseFind(TEXT(CHAR_PATH_SEPARATOR)); + if (pos < 0 || pos == 0) + return false; + if (pathName[pos - 1] == ':') + return false; + pathName = pathName.Left(pos); + } + pathName = pathName2; + while(pos < pathName.Length()) + { + pos = pathName.Find(TEXT(CHAR_PATH_SEPARATOR), pos + 1); + if (pos < 0) + pos = pathName.Length(); + if(!MyCreateDirectory(pathName.Left(pos))) + return false; + } + return true; +} + +#ifndef _UNICODE + +bool CreateComplexDirectory(LPCWSTR _aPathName) +{ + UString pathName = _aPathName; + int pos = pathName.ReverseFind(WCHAR_PATH_SEPARATOR); + if (pos > 0 && pos == pathName.Length() - 1) + { + if (pathName.Length() == 3 && pathName[1] == L':') + return true; // Disk folder; + pathName.Delete(pos); + } + UString pathName2 = pathName; + pos = pathName.Length(); + while(true) + { + if(MyCreateDirectory(pathName)) + break; + if(::GetLastError() == ERROR_ALREADY_EXISTS) + { +#ifdef _WIN32 // FIXED for supporting symbolic link instead of a directory + NFind::CFileInfoW fileInfo; + if (!NFind::FindFile(pathName, fileInfo)) // For network folders + return true; + if (!fileInfo.IsDir()) + return false; +#endif + break; + } + pos = pathName.ReverseFind(WCHAR_PATH_SEPARATOR); + if (pos < 0 || pos == 0) + return false; + if (pathName[pos - 1] == L':') + return false; + pathName = pathName.Left(pos); + } + pathName = pathName2; + while(pos < pathName.Length()) + { + pos = pathName.Find(WCHAR_PATH_SEPARATOR, pos + 1); + if (pos < 0) + pos = pathName.Length(); + if(!MyCreateDirectory(pathName.Left(pos))) + return false; + } + return true; +} + +#endif + +bool DeleteFileAlways(LPCTSTR name) +{ + if (!name || !*name) { + SetLastError(ERROR_PATH_NOT_FOUND); + return false; + } +#ifdef _UNICODE + AString unixname = nameWindowToUnix2(name); +#else + const char * unixname = nameWindowToUnix(name); +#endif + bool bret = false; + if (remove(unixname) == 0) bret = true; + TRACEN((printf("DeleteFileAlways(%s)=%d\n",unixname,(int)bret))) + return bret; +} + +#ifndef _UNICODE +bool DeleteFileAlways(LPCWSTR name) +{ + return DeleteFileAlways(UnicodeStringToMultiByte(name, CP_ACP)); +} +#endif + + +static bool RemoveDirectorySubItems2(const UString &pathPrefix, const NFind::CFileInfoW &fileInfo) +{ + if (fileInfo.IsDir()) + return RemoveDirectoryWithSubItems(pathPrefix + fileInfo.Name); + return DeleteFileAlways(pathPrefix + fileInfo.Name); +} + +bool RemoveDirectoryWithSubItems(const UString &path) +{ + NFind::CFileInfoW fileInfo; + UString pathPrefix = path + NName::kDirDelimiter; + { + NFind::CEnumeratorW enumerator(pathPrefix + TCHAR(NName::kAnyStringWildcard)); + while (enumerator.Next(fileInfo)) + if (!RemoveDirectorySubItems2(pathPrefix, fileInfo)) + return false; + } + if (!MySetFileAttributes(path, 0)) + return false; + return MyRemoveDirectory(path); +} + +#ifndef _WIN32_WCE + +bool MyGetFullPathName(LPCTSTR fileName, CSysString &resultPath, + int &fileNamePartStartIndex) +{ + LPTSTR fileNamePointer = 0; + LPTSTR buffer = resultPath.GetBuffer(MAX_PATH); + DWORD needLength = ::GetFullPathName(fileName, MAX_PATH + 1, + buffer, &fileNamePointer); + resultPath.ReleaseBuffer(); + if (needLength == 0 || needLength >= MAX_PATH) + return false; + if (fileNamePointer == 0) + fileNamePartStartIndex = lstrlen(fileName); + else + fileNamePartStartIndex = fileNamePointer - buffer; + return true; +} + +#ifndef _UNICODE +bool MyGetFullPathName(LPCWSTR fileName, UString &resultPath, + int &fileNamePartStartIndex) +{ + const UINT currentPage = CP_ACP; + CSysString sysPath; + if (!MyGetFullPathName(UnicodeStringToMultiByte(fileName, + currentPage), sysPath, fileNamePartStartIndex)) + return false; + UString resultPath1 = MultiByteToUnicodeString( + sysPath.Left(fileNamePartStartIndex), currentPage); + UString resultPath2 = MultiByteToUnicodeString( + sysPath.Mid(fileNamePartStartIndex), currentPage); + fileNamePartStartIndex = resultPath1.Length(); + resultPath = resultPath1 + resultPath2; + return true; +} +#endif + + +bool MyGetFullPathName(LPCTSTR fileName, CSysString &path) +{ + int index; + return MyGetFullPathName(fileName, path, index); +} + +#ifndef _UNICODE +bool MyGetFullPathName(LPCWSTR fileName, UString &path) +{ + int index; + return MyGetFullPathName(fileName, path, index); +} +#endif + +#endif + +/* needed to find .DLL/.so and SFX */ +bool MySearchPath(LPCWSTR path, LPCWSTR fileName, LPCWSTR extension, UString &resultPath) +{ + if (path != 0) { + printf("NOT EXPECTED : MySearchPath : path != NULL\n"); + exit(EXIT_FAILURE); + } + + if (extension != 0) { + printf("NOT EXPECTED : MySearchPath : extension != NULL\n"); + exit(EXIT_FAILURE); + } + + if (fileName == 0) { + printf("NOT EXPECTED : MySearchPath : fileName == NULL\n"); + exit(EXIT_FAILURE); + } + + const char *p7zip_home_dir = getenv("P7ZIP_HOME_DIR"); + if (p7zip_home_dir) { + AString file_path = p7zip_home_dir; + file_path += UnicodeStringToMultiByte(fileName, CP_ACP); + + TRACEN((printf("MySearchPath() fopen(%s)\n",(const char *)file_path))) + FILE *file = fopen((const char *)file_path,"r"); + if (file) { + // file is found + fclose(file); + resultPath = MultiByteToUnicodeString(file_path, CP_ACP); + return true; + } + } + return false; +} + +#ifndef _UNICODE +bool MyGetTempPath(CSysString &path) +{ + path = "c:/tmp/"; // final '/' is needed + return true; +} +#endif + +bool MyGetTempPath(UString &path) +{ + path = L"c:/tmp/"; // final '/' is needed + return true; +} + +static NSynchronization::CCriticalSection g_CountCriticalSection; + +static CSysString CSysConvertUInt32ToString(UInt32 value) +{ + TCHAR buffer[32]; + ConvertUInt32ToString(value, buffer); + return buffer; +} + +UINT CTempFile::Create(LPCTSTR dirPath, LPCTSTR prefix, CSysString &resultPath) +{ + static UInt32 memo_count = 0; + UInt32 count; + + g_CountCriticalSection.Enter(); + count = memo_count++; + g_CountCriticalSection.Leave(); + + Remove(); +/* UINT number = ::GetTempFileName(dirPath, prefix, 0, path.GetBuffer(MAX_PATH)); */ + UINT number = (UINT)getpid(); + + resultPath = dirPath; + resultPath += prefix; + resultPath += TEXT('#'); + resultPath += CSysConvertUInt32ToString(number); + resultPath += TEXT('@'); + resultPath += CSysConvertUInt32ToString(count); + resultPath += TEXT(".tmp"); + + _fileName = resultPath; + _mustBeDeleted = true; + + return number; +} + +bool CTempFile::Create(LPCTSTR prefix, CSysString &resultPath) +{ + CSysString tempPath; + if (!MyGetTempPath(tempPath)) + return false; + if (Create(tempPath, prefix, resultPath) != 0) + return true; + return false; +} + + +bool CTempFile::Remove() +{ + if (!_mustBeDeleted) + return true; + _mustBeDeleted = !DeleteFileAlways(_fileName); + return !_mustBeDeleted; +} + +bool CreateTempDirectory(LPCWSTR prefix, UString &dirName) +{ + /* + CSysString prefix = tempPath + prefixChars; + CRandom random; + random.Init(); + */ + for (;;) + { + { + CTempFileW tempFile; + if (!tempFile.Create(prefix, dirName)) + return false; + if (!tempFile.Remove()) + return false; + } + /* + UINT32 randomNumber = random.Generate(); + TCHAR randomNumberString[32]; + _stprintf(randomNumberString, _T("%04X"), randomNumber); + dirName = prefix + randomNumberString; + */ + if (NFind::DoesFileOrDirExist(dirName)) + continue; + if (MyCreateDirectory(dirName)) + return true; + if (::GetLastError() != ERROR_ALREADY_EXISTS) + return false; + } +} + +bool CTempDirectory::Create(LPCTSTR prefix) +{ + Remove(); + return (_mustBeDeleted = CreateTempDirectory(prefix, _tempDir)); +} + + +}}} diff --git a/src/libs/7zip/unix/CPP/Windows/FileDir.h b/src/libs/7zip/unix/CPP/Windows/FileDir.h new file mode 100644 index 000000000..a7cfbaf8d --- /dev/null +++ b/src/libs/7zip/unix/CPP/Windows/FileDir.h @@ -0,0 +1,115 @@ +// Windows/FileDir.h + +#ifndef __WINDOWS_FILEDIR_H +#define __WINDOWS_FILEDIR_H + +#include "../Common/MyString.h" +#include "Defs.h" + +/* GetFullPathName for 7zAES.cpp */ +DWORD WINAPI GetFullPathName( LPCSTR name, DWORD len, LPSTR buffer, LPSTR *lastpart ); + +namespace NWindows { +namespace NFile { +namespace NDirectory { + +bool SetDirTime(LPCWSTR fileName, const FILETIME *creationTime, const FILETIME *lastAccessTime, const FILETIME *lastWriteTime); + +bool MySetFileAttributes(LPCTSTR fileName, DWORD fileAttributes); +#ifndef _UNICODE +bool MySetFileAttributes(LPCWSTR fileName, DWORD fileAttributes); +#endif + +bool MyMoveFile(LPCTSTR existFileName, LPCTSTR newFileName); +#ifndef _UNICODE +bool MyMoveFile(LPCWSTR existFileName, LPCWSTR newFileName); +#endif + +bool MyRemoveDirectory(LPCTSTR pathName); +#ifndef _UNICODE +bool MyRemoveDirectory(LPCWSTR pathName); +#endif + +bool MyCreateDirectory(LPCTSTR pathName); +bool CreateComplexDirectory(LPCTSTR pathName); +#ifndef _UNICODE +bool MyCreateDirectory(LPCWSTR pathName); +bool CreateComplexDirectory(LPCWSTR pathName); +#endif + +bool DeleteFileAlways(LPCTSTR name); +#ifndef _UNICODE +bool DeleteFileAlways(LPCWSTR name); +#endif +bool RemoveDirectoryWithSubItems(const UString &path); + +#ifndef _WIN32_WCE +bool MyGetFullPathName(LPCTSTR fileName, CSysString &resultPath, + int &fileNamePartStartIndex); +bool MyGetFullPathName(LPCTSTR fileName, CSysString &resultPath); +bool GetOnlyName(LPCTSTR fileName, CSysString &resultName); +bool GetOnlyDirPrefix(LPCTSTR fileName, CSysString &resultName); +#ifndef _UNICODE +bool MyGetFullPathName(LPCWSTR fileName, UString &resultPath, + int &fileNamePartStartIndex); +bool MyGetFullPathName(LPCWSTR fileName, UString &resultPath); +#endif + +#endif + +bool MySetCurrentDirectory(LPCWSTR path); +bool MyGetCurrentDirectory(CSysString &resultPath); + +bool MySearchPath(LPCWSTR path, LPCWSTR fileName, LPCWSTR extension, UString &resultPath); + +bool MyGetTempPath(CSysString &resultPath); +#ifndef _UNICODE +bool MyGetTempPath(UString &resultPath); +#endif + +class CTempFile +{ + bool _mustBeDeleted; + CSysString _fileName; +public: + CTempFile(): _mustBeDeleted(false) {} + ~CTempFile() { Remove(); } + void DisableDeleting() { _mustBeDeleted = false; } + UINT Create(LPCTSTR dirPath, LPCTSTR prefix, CSysString &resultPath); + bool Create(LPCTSTR prefix, CSysString &resultPath); + bool Remove(); +}; + +#ifdef _UNICODE +typedef CTempFile CTempFileW; +#endif + +bool CreateTempDirectory(LPCWSTR prefixChars, UString &dirName); + +class CTempDirectory +{ + bool _mustBeDeleted; + CSysString _tempDir; +public: + const CSysString &GetPath() const { return _tempDir; } + CTempDirectory(): _mustBeDeleted(false) {} + ~CTempDirectory() { Remove(); } + bool Create(LPCTSTR prefix) ; + bool Remove() + { + if (!_mustBeDeleted) + return true; + _mustBeDeleted = !RemoveDirectoryWithSubItems(_tempDir); + return (!_mustBeDeleted); + } + void DisableDeleting() { _mustBeDeleted = false; } +}; + +#ifdef _UNICODE +typedef CTempDirectory CTempDirectoryW; +#endif + + +}}} + +#endif diff --git a/src/libs/7zip/unix/CPP/Windows/FileFind.cpp b/src/libs/7zip/unix/CPP/Windows/FileFind.cpp new file mode 100644 index 000000000..9e526a233 --- /dev/null +++ b/src/libs/7zip/unix/CPP/Windows/FileFind.cpp @@ -0,0 +1,604 @@ +// Windows/FileFind.cpp + +#include "StdAfx.h" + +#include "FileFind.h" +#include "../Common/StringConvert.h" + +#include <sys/stat.h> +#include <unistd.h> +#include <errno.h> + +#ifdef ENV_HAVE_LSTAT +extern "C" +{ + +int global_use_lstat=1; // default behaviour : p7zip stores symlinks instead of dumping the files they point to +} +#endif + +#define NEED_NAME_WINDOWS_TO_UNIX +#include "myPrivate.h" + +// #define TRACEN(u) u; +#define TRACEN(u) /* */ + +void my_windows_split_path(const AString &p_path, AString &dir , AString &base) { + int pos = p_path.ReverseFind('/'); + if (pos == -1) { + // no separator + dir = "."; + if (p_path.IsEmpty()) + base = "."; + else + base = p_path; + } else if ((pos+1) < p_path.Length()) { + // true separator + base = p_path.Mid(pos+1); + while ((pos >= 1) && (p_path[pos-1] == '/')) + pos--; + if (pos == 0) + dir = "/"; + else + dir = p_path.Left(pos); + } else { + // separator at the end of the path + // pos = p_path.find_last_not_of("/"); + pos = -1; + int ind = 0; + while (p_path[ind]) { + if (p_path[ind] != '/') + pos = ind; + ind++; + } + if (pos == -1) { + base = "/"; + dir = "/"; + } else { + my_windows_split_path(p_path.Left(pos+1),dir,base); + } + } +} + +static void my_windows_split_path(const UString &p_path, UString &dir , UString &base) { + int pos = p_path.ReverseFind(L'/'); + if (pos == -1) { + // no separator + dir = L"."; + if (p_path.IsEmpty()) + base = L"."; + else + base = p_path; + } else if ((pos+1) < p_path.Length()) { + // true separator + base = p_path.Mid(pos+1); + while ((pos >= 1) && (p_path[pos-1] == L'/')) + pos--; + if (pos == 0) + dir = L"/"; + else + dir = p_path.Left(pos); + } else { + // separator at the end of the path + // pos = p_path.find_last_not_of("/"); + pos = -1; + int ind = 0; + while (p_path[ind]) { + if (p_path[ind] != L'/') + pos = ind; + ind++; + } + if (pos == -1) { + base = L"/"; + dir = L"/"; + } else { + my_windows_split_path(p_path.Left(pos+1),dir,base); + } + } +} + +static int filter_pattern(const char *string , const char *pattern , int flags_nocase) { + if ((string == 0) || (*string==0)) { + if (pattern == 0) + return 1; + while (*pattern=='*') + ++pattern; + return (!*pattern); + } + + switch (*pattern) { + case '*': + if (!filter_pattern(string+1,pattern,flags_nocase)) + return filter_pattern(string,pattern+1,flags_nocase); + return 1; + case 0: + if (*string==0) + return 1; + break; + case '?': + return filter_pattern(string+1,pattern+1,flags_nocase); + default: + if ( ((flags_nocase) && (tolower(*pattern)==tolower(*string))) + || (*pattern == *string) + ) { + return filter_pattern(string+1,pattern+1,flags_nocase); + } + break; + } + return 0; +} + + +namespace NWindows { +namespace NFile { +namespace NFind { + +static const TCHAR kDot = TEXT('.'); + +bool CFileInfo::IsDots() const +{ + if (!IsDir() || Name.IsEmpty()) + return false; + if (Name[0] != kDot) + return false; + return Name.Length() == 1 || (Name[1] == kDot && Name.Length() == 2); +} + +bool CFileInfoW::IsDots() const +{ + if (!IsDir() || Name.IsEmpty()) + return false; + if (Name[0] != kDot) + return false; + return Name.Length() == 1 || (Name[1] == kDot && Name.Length() == 2); +} + +static bool originalFilename(const UString & src, AString & res) +{ + // Try to recover the original filename + res = ""; + int i=0; + while (src[i]) + { + if (src[i] >= 256) { + return false; + } else { + res += char(src[i]); + } + i++; + } + return true; +} + + + +// Warning this function cannot update "fileInfo.Name" +static int fillin_CFileInfo(CFileInfo &fileInfo,const char *filename) { + struct stat stat_info; + + int ret; +#ifdef ENV_HAVE_LSTAT + if (global_use_lstat) { + ret = lstat(filename,&stat_info); + } else +#endif + { + ret = stat(filename,&stat_info); + } + + if (ret != 0) return ret; + + /* FIXME : FILE_ATTRIBUTE_HIDDEN ? */ + if (S_ISDIR(stat_info.st_mode)) { + fileInfo.Attrib = FILE_ATTRIBUTE_DIRECTORY; + } else { + fileInfo.Attrib = FILE_ATTRIBUTE_ARCHIVE; + } + + if (!(stat_info.st_mode & S_IWUSR)) + fileInfo.Attrib |= FILE_ATTRIBUTE_READONLY; + + fileInfo.Attrib |= FILE_ATTRIBUTE_UNIX_EXTENSION + ((stat_info.st_mode & 0xFFFF) << 16); + + RtlSecondsSince1970ToFileTime( stat_info.st_ctime, &fileInfo.CTime ); + RtlSecondsSince1970ToFileTime( stat_info.st_mtime, &fileInfo.MTime ); + RtlSecondsSince1970ToFileTime( stat_info.st_atime, &fileInfo.ATime ); + + fileInfo.IsDevice = false; + + if (S_ISDIR(stat_info.st_mode)) { + fileInfo.Size = 0; + } else { // file or symbolic link + fileInfo.Size = stat_info.st_size; // for a symbolic link, size = size of filename + } + return 0; +} + +static int fillin_CFileInfo(CFileInfo &fileInfo,const char *dir,const char *name) { + char filename[MAX_PATHNAME_LEN]; + size_t dir_len = strlen(dir); + size_t name_len = strlen(name); + size_t total = dir_len + 1 + name_len + 1; // 1 = strlen("/"); + le zero character + if (total >= MAX_PATHNAME_LEN) throw "fillin_CFileInfo - internal error - MAX_PATHNAME_LEN"; + memcpy(filename,dir,dir_len); + if (dir_len >= 1) + { + if (filename[dir_len-1] == CHAR_PATH_SEPARATOR) + { // delete the '/' + dir_len--; + } + } + filename[dir_len] = CHAR_PATH_SEPARATOR; + memcpy(filename+(dir_len+1),name,name_len+1); // copy also final '\0' + + fileInfo.Name = name; + + int ret = fillin_CFileInfo(fileInfo,filename); + if (ret != 0) { + AString err_msg = "stat error for "; + err_msg += filename; + err_msg += " ("; + err_msg += strerror(errno); + err_msg += ")"; + throw err_msg; + } + return ret; +} + +//////////////////////////////// +// CFindFile + +bool CFindFile::Close() +{ + + if(_dirp == 0) + return true; + int ret = closedir(_dirp); + if (ret == 0) + { + _dirp = 0; + return true; + } + return false; +} + +// bool CFindFile::FindFirst(LPCTSTR wildcard, CFileInfo &fileInfo) +bool CFindFile::FindFirst(LPCSTR wildcard, CFileInfo &fileInfo) +{ + if (!Close()) + return false; + + if ((!wildcard) || (wildcard[0]==0)) { + SetLastError(ERROR_PATH_NOT_FOUND); + return false; + } + + my_windows_split_path(nameWindowToUnix(wildcard),_directory,_pattern); + + TRACEN((printf("CFindFile::FindFirst : %s (dirname=%s,pattern=%s)\n",wildcard,(const char *)_directory,(const char *)_pattern))) + + _dirp = ::opendir((const char *)_directory); + TRACEN((printf("CFindFile::FindFirst : opendir=%p\n",_dirp))) + + if ((_dirp == 0) && (global_use_utf16_conversion)) { + // Try to recover the original filename + UString ustr = MultiByteToUnicodeString(_directory, 0); + AString resultString; + bool is_good = originalFilename(ustr, resultString); + if (is_good) { + _dirp = ::opendir((const char *)resultString); + _directory = resultString; + } + } + + if (_dirp == 0) return false; + + struct dirent *dp; + while ((dp = readdir(_dirp)) != NULL) { + if (filter_pattern(dp->d_name,(const char *)_pattern,0) == 1) { + int retf = fillin_CFileInfo(fileInfo,(const char *)_directory,dp->d_name); + if (retf) + { + TRACEN((printf("CFindFile::FindFirst : closedir-1(dirp=%p)\n",_dirp))) + closedir(_dirp); + _dirp = 0; + SetLastError( ERROR_NO_MORE_FILES ); + return false; + } + TRACEN((printf("CFindFile::FindFirst -%s- true\n",dp->d_name))) + return true; + } + } + + TRACEN((printf("CFindFile::FindFirst : closedir-2(dirp=%p)\n",_dirp))) + closedir(_dirp); + _dirp = 0; + SetLastError( ERROR_NO_MORE_FILES ); + return false; +} + +bool CFindFile::FindFirst(LPCWSTR wildcard, CFileInfoW &fileInfo) +{ + if (!Close()) + return false; + CFileInfo fileInfo0; + AString Awildcard = UnicodeStringToMultiByte(wildcard, CP_ACP); + bool bret = FindFirst((LPCSTR)Awildcard, fileInfo0); + if (bret) + { + fileInfo.Attrib = fileInfo0.Attrib; + fileInfo.CTime = fileInfo0.CTime; + fileInfo.ATime = fileInfo0.ATime; + fileInfo.MTime = fileInfo0.MTime; + fileInfo.Size = fileInfo0.Size; + fileInfo.IsDevice = fileInfo0.IsDevice; + fileInfo.Name = GetUnicodeString(fileInfo0.Name, CP_ACP); + } + return bret; +} + +bool CFindFile::FindNext(CFileInfo &fileInfo) +{ + if (_dirp == 0) + { + SetLastError( ERROR_INVALID_HANDLE ); + return false; + } + + struct dirent *dp; + while ((dp = readdir(_dirp)) != NULL) { + if (filter_pattern(dp->d_name,(const char *)_pattern,0) == 1) { + int retf = fillin_CFileInfo(fileInfo,(const char *)_directory,dp->d_name); + if (retf) + { + TRACEN((printf("FindNextFileA -%s- ret_handle=FALSE (errno=%d)\n",dp->d_name,errno))) + return false; + + } + TRACEN((printf("FindNextFileA -%s- true\n",dp->d_name))) + return true; + } + } + TRACEN((printf("FindNextFileA ret_handle=FALSE (ERROR_NO_MORE_FILES)\n"))) + SetLastError( ERROR_NO_MORE_FILES ); + return false; +} + +bool CFindFile::FindNext(CFileInfoW &fileInfo) +{ + CFileInfo fileInfo0; + bool bret = FindNext(fileInfo0); + if (bret) + { + fileInfo.Attrib = fileInfo0.Attrib; + fileInfo.CTime = fileInfo0.CTime; + fileInfo.ATime = fileInfo0.ATime; + fileInfo.MTime = fileInfo0.MTime; + fileInfo.Size = fileInfo0.Size; + fileInfo.IsDevice = fileInfo0.IsDevice; + fileInfo.Name = GetUnicodeString(fileInfo0.Name, CP_ACP); + } + return bret; +} + +bool CFileInfo::Find(LPCSTR wildcard) +{ + #ifdef SUPPORT_DEVICE_FILE + if (IsDeviceName(wildcard)) + { + Clear(); + IsDevice = true; + NIO::CInFile inFile; + if (!inFile.Open(wildcard)) + return false; + Name = wildcard + 4; + if (inFile.LengthDefined) + Size = inFile.Length; + return true; + } + #endif + CFindFile finder; + return finder.FindFirst(wildcard, *this); +} + + +// #ifndef _UNICODE +bool CFileInfoW::Find(LPCWSTR wildcard) +{ + #ifdef SUPPORT_DEVICE_FILE + if (IsDeviceName(wildcard)) + { + Clear(); + IsDevice = true; + NIO::CInFile inFile; + if (!inFile.Open(wildcard)) + return false; + Name = wildcard + 4; + if (inFile.LengthDefined) + Size = inFile.Length; + return true; + } + #endif + CFindFile finder; + return finder.FindFirst(wildcard, *this); +} +// #endif + +bool FindFile(LPCSTR wildcard, CFileInfo &fileInfo) +{ + // CFindFile finder; + // return finder.FindFirst(wildcard, fileInfo); + AString dir,base; + my_windows_split_path(wildcard, dir , base); + int ret = fillin_CFileInfo(fileInfo,nameWindowToUnix(wildcard)); + fileInfo.Name = base; + TRACEN((printf("FindFile(%s,CFileInfo) ret=%d\n",wildcard,ret))) + return (ret == 0); +} + +bool FindFile(LPCWSTR wildcard, CFileInfoW &fileInfo) +{ + // CFindFile finder; + // return finder.FindFirst(wildcard, fileInfo); + AString name = UnicodeStringToMultiByte(wildcard, CP_ACP); + CFileInfo fileInfo0; + int ret = fillin_CFileInfo(fileInfo0,nameWindowToUnix((const char *)name)); + TRACEN((printf("FindFile-1(%s,CFileInfo) ret=%d\n",(const char *)name,ret))) + if (ret != 0) + { + // Try to recover the original filename + AString resultString; + bool is_good = originalFilename(wildcard, resultString); + if (is_good) { + ret = fillin_CFileInfo(fileInfo0,nameWindowToUnix((const char *)resultString)); + TRACEN((printf("FindFile-2(%s,CFileInfo) ret=%d\n",(const char *)resultString,ret))) + } + } + if (ret == 0) + { + UString dir,base; + my_windows_split_path(wildcard, dir , base); + fileInfo.Attrib = fileInfo0.Attrib; + fileInfo.CTime = fileInfo0.CTime; + fileInfo.ATime = fileInfo0.ATime; + fileInfo.MTime = fileInfo0.MTime; + fileInfo.Size = fileInfo0.Size; + fileInfo.Name = base; + } + return (ret == 0); +} + +bool DoesFileExist(LPCSTR name) // FIXME +{ + CFileInfo fi; + int ret = fillin_CFileInfo(fi,nameWindowToUnix(name)); + TRACEN((printf("DoesFileExist(%s) ret=%d\n",name,ret))) + return (ret == 0) && !fi.IsDir();; +} + +bool DoesDirExist(LPCSTR name) // FIXME +{ + CFileInfo fi; + int ret = fillin_CFileInfo(fi,nameWindowToUnix(name)); + TRACEN((printf("DoesDirExist(%s) ret=%d\n",name,ret))) + return (ret == 0) && fi.IsDir();; +} + +bool DoesFileOrDirExist(LPCSTR name) +{ + CFileInfo fileInfo; + int ret = fillin_CFileInfo(fileInfo,nameWindowToUnix(name)); + TRACEN((printf("DoesFileOrDirExist(%s) ret=%d\n",name,ret))) + return (ret == 0); +} + +bool DoesFileExist(LPCWSTR name) +{ + AString Aname = UnicodeStringToMultiByte(name, CP_ACP); + bool bret = DoesFileExist((LPCSTR)Aname); + if (bret) return bret; + + // Try to recover the original filename + AString resultString; + bool is_good = originalFilename(name, resultString); + if (is_good) { + bret = DoesFileExist((const char *)resultString); + } + return bret; +} + +bool DoesDirExist(LPCWSTR name) +{ + AString Aname = UnicodeStringToMultiByte(name, CP_ACP); + bool bret = DoesDirExist((LPCSTR)Aname); + if (bret) return bret; + + // Try to recover the original filename + AString resultString; + bool is_good = originalFilename(name, resultString); + if (is_good) { + bret = DoesDirExist((const char *)resultString); + } + return bret; +} + +bool DoesFileOrDirExist(LPCWSTR name) +{ + AString Aname = UnicodeStringToMultiByte(name, CP_ACP); + bool bret = DoesFileOrDirExist((LPCSTR)Aname); + if (bret) return bret; + + // Try to recover the original filename + AString resultString; + bool is_good = originalFilename(name, resultString); + if (is_good) { + bret = DoesFileOrDirExist((const char *)resultString); + } + return bret; +} + +///////////////////////////////////// +// CEnumerator + +bool CEnumerator::NextAny(CFileInfo &fileInfo) +{ + if(_findFile.IsHandleAllocated()) + return _findFile.FindNext(fileInfo); + else + return _findFile.FindFirst(_wildcard, fileInfo); +} + +bool CEnumerator::Next(CFileInfo &fileInfo) +{ + while(true) + { + if(!NextAny(fileInfo)) + return false; + if(!fileInfo.IsDots()) + return true; + } +} + +bool CEnumerator::Next(CFileInfo &fileInfo, bool &found) +{ + if (Next(fileInfo)) + { + found = true; + return true; + } + found = false; + return (::GetLastError() == ERROR_NO_MORE_FILES); +} + +bool CEnumeratorW::NextAny(CFileInfoW &fileInfo) +{ + if(_findFile.IsHandleAllocated()) + return _findFile.FindNext(fileInfo); + else + return _findFile.FindFirst(_wildcard, fileInfo); +} + +bool CEnumeratorW::Next(CFileInfoW &fileInfo) +{ + while(true) + { + if(!NextAny(fileInfo)) + return false; + if(!fileInfo.IsDots()) + return true; + } +} + +bool CEnumeratorW::Next(CFileInfoW &fileInfo, bool &found) +{ + if (Next(fileInfo)) + { + found = true; + return true; + } + found = false; + return (::GetLastError() == ERROR_NO_MORE_FILES); +} + + +}}} diff --git a/src/libs/7zip/unix/CPP/Windows/FileFind.h b/src/libs/7zip/unix/CPP/Windows/FileFind.h new file mode 100644 index 000000000..a1fd0f072 --- /dev/null +++ b/src/libs/7zip/unix/CPP/Windows/FileFind.h @@ -0,0 +1,126 @@ +// Windows/FileFind.h + +#ifndef __WINDOWS_FILEFIND_H +#define __WINDOWS_FILEFIND_H + +#include "../Common/MyString.h" +#include "FileName.h" +#include "Defs.h" + +#include <sys/types.h> /* for DIR */ +#include <dirent.h> + +namespace NWindows { +namespace NFile { +namespace NFind { + +namespace NAttributes +{ + inline bool IsReadOnly(DWORD attrib) { return (attrib & FILE_ATTRIBUTE_READONLY) != 0; } + inline bool IsHidden(DWORD attrib) { return (attrib & FILE_ATTRIBUTE_HIDDEN) != 0; } + inline bool IsSystem(DWORD attrib) { return (attrib & FILE_ATTRIBUTE_SYSTEM) != 0; } + inline bool IsDir(DWORD attrib) { return (attrib & FILE_ATTRIBUTE_DIRECTORY) != 0; } + inline bool IsArchived(DWORD attrib) { return (attrib & FILE_ATTRIBUTE_ARCHIVE) != 0; } + inline bool IsCompressed(DWORD attrib) { return (attrib & FILE_ATTRIBUTE_COMPRESSED) != 0; } + inline bool IsEncrypted(DWORD attrib) { return (attrib & FILE_ATTRIBUTE_ENCRYPTED) != 0; } +} + +class CFileInfoBase +{ + bool MatchesMask(UINT32 mask) const { return ((Attrib & mask) != 0); } +public: + UInt64 Size; + FILETIME CTime; + FILETIME ATime; + FILETIME MTime; + DWORD Attrib; + bool IsDevice; + + bool IsDir() const { return MatchesMask(FILE_ATTRIBUTE_DIRECTORY); } +}; + +class CFileInfo: public CFileInfoBase +{ +public: + AString Name; // FIXME CSysString Name; + bool IsDots() const; + bool Find(LPCSTR wildcard); +}; + +// FIXME #ifdef _UNICODE +// typedef CFileInfo CFileInfoW; +// #else +class CFileInfoW: public CFileInfoBase +{ +public: + UString Name; + bool IsDots() const; + bool Find(LPCWSTR wildcard); +}; +// #endif + +class CFindFile +{ + friend class CEnumerator; + DIR *_dirp; + AString _pattern; + AString _directory; +public: + bool IsHandleAllocated() const { return (_dirp != 0); } + CFindFile(): _dirp(0) {} + ~CFindFile() { Close(); } + // bool FindFirst(LPCTSTR wildcard, CFileInfo &fileInfo); + bool FindFirst(LPCSTR wildcard, CFileInfo &fileInfo); + bool FindNext(CFileInfo &fileInfo); + // FIXME #ifndef _UNICODE + bool FindFirst(LPCWSTR wildcard, CFileInfoW &fileInfo); + bool FindNext(CFileInfoW &fileInfo); + // FIXME #endif + bool Close(); +}; + +bool FindFile(LPCSTR wildcard, CFileInfo &fileInfo); + +bool DoesFileExist(LPCSTR name); +bool DoesDirExist(LPCTSTR name); +bool DoesFileOrDirExist(LPCSTR name); +// #ifndef _UNICODE +bool FindFile(LPCWSTR wildcard, CFileInfoW &fileInfo); +bool DoesFileExist(LPCWSTR name); +bool DoesDirExist(LPCWSTR name); +bool DoesFileOrDirExist(LPCWSTR name); +// #endif + +class CEnumerator +{ + CFindFile _findFile; + AString _wildcard; // FIXME CSysString _wildcard; + bool NextAny(CFileInfo &fileInfo); +public: + CEnumerator(): _wildcard(NName::kAnyStringWildcard) {} + // FIXME CEnumerator(const CSysString &wildcard): _wildcard(wildcard) {} + CEnumerator(const AString &wildcard): _wildcard(wildcard) {} + bool Next(CFileInfo &fileInfo); + bool Next(CFileInfo &fileInfo, bool &found); +}; + +// FIXME #ifdef _UNICODE +// typedef CEnumerator CEnumeratorW; +// #else +class CEnumeratorW +{ + CFindFile _findFile; + UString _wildcard; + bool NextAny(CFileInfoW &fileInfo); +public: + CEnumeratorW(): _wildcard(NName::kAnyStringWildcard) {} + CEnumeratorW(const UString &wildcard): _wildcard(wildcard) {} + bool Next(CFileInfoW &fileInfo); + bool Next(CFileInfoW &fileInfo, bool &found); +}; +// FIXME #endif + +}}} + +#endif + diff --git a/src/libs/7zip/unix/CPP/Windows/FileIO.cpp b/src/libs/7zip/unix/CPP/Windows/FileIO.cpp new file mode 100644 index 000000000..a731813f3 --- /dev/null +++ b/src/libs/7zip/unix/CPP/Windows/FileIO.cpp @@ -0,0 +1,475 @@ +// Windows/FileIO.cpp + +#include "StdAfx.h" + +#include "FileIO.h" +#include "Defs.h" +#include "../Common/StringConvert.h" + +#include <time.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <fcntl.h> + +#define NEED_NAME_WINDOWS_TO_UNIX +#include "myPrivate.h" + +#include <sys/types.h> +#include <utime.h> + +#ifdef ENV_HAVE_LSTAT +#define FD_LINK (-2) +#endif + +#define GENERIC_READ 0x80000000 +#define GENERIC_WRITE 0x40000000 + +extern BOOLEAN WINAPI RtlTimeToSecondsSince1970( const LARGE_INTEGER *Time, DWORD *Seconds ); + +namespace NWindows { +namespace NFile { +namespace NIO { + +CFileBase::~CFileBase() +{ + Close(); +} + +bool CFileBase::Create(LPCSTR filename, DWORD dwDesiredAccess, + DWORD dwShareMode, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes,bool ignoreSymbolicLink) +{ + Close(); + + int flags = 0; + const char * name = nameWindowToUnix(filename); + +#ifdef O_BINARY + flags |= O_BINARY; +#endif + +#ifdef O_LARGEFILE + flags |= O_LARGEFILE; +#endif + + /* now use the umask value */ + int mask = umask(0); + (void)umask(mask); + int mode = 0666 & ~(mask & 066); /* keep the R/W for the user */ + + if (dwDesiredAccess & GENERIC_WRITE) flags |= O_WRONLY; + if (dwDesiredAccess & GENERIC_READ) flags |= O_RDONLY; + + + switch (dwCreationDisposition) + { + case CREATE_NEW : flags |= O_CREAT | O_EXCL; break; + case CREATE_ALWAYS : flags |= O_CREAT; break; + case OPEN_EXISTING : break; + case OPEN_ALWAYS : flags |= O_CREAT; break; + // case TRUNCATE_EXISTING : flags |= O_TRUNC; break; + } + // printf("##DBG open(%s,0x%x,%o)##\n",name,flags,(unsigned)mode); + + _fd = -1; +#ifdef ENV_HAVE_LSTAT + if ((global_use_lstat) && (ignoreSymbolicLink == false)) + { + _size = readlink(name, _buffer, sizeof(_buffer)-1); + if (_size > 0) { + if (dwDesiredAccess & GENERIC_READ) { + _fd = FD_LINK; + _offset = 0; + _buffer[_size]=0; + } else if (dwDesiredAccess & GENERIC_WRITE) { + // does not overwrite the file pointed by symbolic link + if (!unlink(name)) return false; + } + } + } +#endif + + if (_fd == -1) { + _fd = open(name,flags, mode); + } + + if ((_fd == -1) && (global_use_utf16_conversion)) { + // bug #1204993 - Try to recover the original filename + UString ustr = MultiByteToUnicodeString(AString(name), 0); + AString resultString; + int is_good = 1; + for (int i = 0; i < ustr.Length(); i++) + { + if (ustr[i] >= 256) { + is_good = 0; + break; + } else { + resultString += char(ustr[i]); + } + } + if (is_good) { + _fd = open((const char *)resultString,flags, mode); + } + } + + if (_fd == -1) { + /* !ENV_HAVE_LSTAT : an invalid symbolic link => errno == ENOENT */ + return false; + } else { + _unix_filename = name; + } + + return true; +} + +bool CFileBase::Create(LPCWSTR fileName, DWORD desiredAccess, + DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes,bool ignoreSymbolicLink) +{ + Close(); + return Create(UnicodeStringToMultiByte(fileName, CP_ACP), + desiredAccess, shareMode, creationDisposition, flagsAndAttributes,ignoreSymbolicLink); +} + +bool CFileBase::Close() +{ + struct utimbuf buf; + + buf.actime = _lastAccessTime; + buf.modtime = _lastWriteTime; + + _lastAccessTime = _lastWriteTime = (time_t)-1; + + if(_fd == -1) + return true; + +#ifdef ENV_HAVE_LSTAT + if(_fd == FD_LINK) { + _fd = -1; + return true; + } +#endif + + int ret = ::close(_fd); + if (ret == 0) { + _fd = -1; + + /* On some OS (mingwin, MacOSX ...), you must close the file before updating times */ + if ((buf.actime != (time_t)-1) || (buf.modtime != (time_t)-1)) { + struct stat oldbuf; + int ret = stat((const char*)(_unix_filename),&oldbuf); + if (ret == 0) { + if (buf.actime == (time_t)-1) buf.actime = oldbuf.st_atime; + if (buf.modtime == (time_t)-1) buf.modtime = oldbuf.st_mtime; + } else { + time_t current_time = time(0); + if (buf.actime == (time_t)-1) buf.actime = current_time; + if (buf.modtime == (time_t)-1) buf.modtime = current_time; + } + /* ret = */ utime((const char *)(_unix_filename), &buf); + } + return true; + } + return false; +} + +bool CFileBase::GetLength(UINT64 &length) const +{ + if (_fd == -1) + { + SetLastError( ERROR_INVALID_HANDLE ); + return false; + } + +#ifdef ENV_HAVE_LSTAT + if (_fd == FD_LINK) { + length = _size; + return true; + } +#endif + + off_t pos_cur = ::lseek(_fd, 0, SEEK_CUR); + if (pos_cur == (off_t)-1) + return false; + + off_t pos_end = ::lseek(_fd, 0, SEEK_END); + if (pos_end == (off_t)-1) + return false; + + off_t pos_cur2 = ::lseek(_fd, pos_cur, SEEK_SET); + if (pos_cur2 == (off_t)-1) + return false; + + length = (UINT64)pos_end; + + return true; +} + +bool CFileBase::Seek(INT64 distanceToMove, DWORD moveMethod, UINT64 &newPosition) +{ + if (_fd == -1) + { + SetLastError( ERROR_INVALID_HANDLE ); + return false; + } + +#ifdef ENV_HAVE_LSTAT + if (_fd == FD_LINK) { + INT64 offset; + switch (moveMethod) { + case STREAM_SEEK_SET : offset = distanceToMove; break; + case STREAM_SEEK_CUR : offset = _offset + distanceToMove; break; + case STREAM_SEEK_END : offset = _size + distanceToMove; break; + default : offset = -1; + } + if (offset < 0) { + SetLastError( EINVAL ); + return false; + } + if (offset > _size) offset = _size; + newPosition = _offset = offset; + return true; + } +#endif + + bool ret = true; + + off_t pos = (off_t)distanceToMove; + + off_t newpos = ::lseek(_fd,pos,moveMethod); + + if (newpos == ((off_t)-1)) { + ret = false; + } else { + newPosition = (UINT64)newpos; + } + + return ret; +} + +bool CFileBase::Seek(UINT64 position, UINT64 &newPosition) +{ + return Seek(position, FILE_BEGIN, newPosition); +} + +///////////////////////// +// CInFile + +bool CInFile::Open(LPCTSTR fileName, DWORD shareMode, + DWORD creationDisposition, DWORD flagsAndAttributes) +{ + return Create(fileName, GENERIC_READ, shareMode, + creationDisposition, flagsAndAttributes); +} + +bool CInFile::Open(LPCTSTR fileName,bool ignoreSymbolicLink) +{ + return Create(fileName, GENERIC_READ , FILE_SHARE_READ, OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL,ignoreSymbolicLink); +} + +#ifndef _UNICODE +bool CInFile::Open(LPCWSTR fileName, DWORD shareMode, + DWORD creationDisposition, DWORD flagsAndAttributes) +{ + return Create(fileName, GENERIC_READ, shareMode, + creationDisposition, flagsAndAttributes); +} + +bool CInFile::Open(LPCWSTR fileName,bool ignoreSymbolicLink) +{ + return Create(fileName, GENERIC_READ , FILE_SHARE_READ, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,ignoreSymbolicLink); +} +#endif + +// ReadFile and WriteFile functions in Windows have BUG: +// If you Read or Write 64MB or more (probably min_failure_size = 64MB - 32KB + 1) +// from/to Network file, it returns ERROR_NO_SYSTEM_RESOURCES +// (Insufficient system resources exist to complete the requested service). + +// static UINT32 kChunkSizeMax = (1 << 24); + +bool CInFile::ReadPart(void *data, UINT32 size, UINT32 &processedSize) +{ + // if (size > kChunkSizeMax) + // size = kChunkSizeMax; + return Read(data,size,processedSize); +} + +bool CInFile::Read(void *buffer, UINT32 bytesToRead, UINT32 &bytesRead) +{ + if (_fd == -1) + { + SetLastError( ERROR_INVALID_HANDLE ); + return false; + } + + if (bytesToRead == 0) { + bytesRead =0; + return TRUE; + } + +#ifdef ENV_HAVE_LSTAT + if (_fd == FD_LINK) { + if (_offset >= _size) { + bytesRead = 0; + return TRUE; + } + int len = (_size - _offset); + if (len > bytesToRead) len = bytesToRead; + memcpy(buffer,_buffer+_offset,len); + bytesRead = len; + _offset += len; + return TRUE; + } +#endif + + ssize_t ret; + do { + ret = read(_fd,buffer,bytesToRead); + } while (ret < 0 && (errno == EINTR)); + + if (ret != -1) { + bytesRead = ret; + return TRUE; + } + bytesRead =0; + return FALSE; +} + +///////////////////////// +// COutFile + +bool COutFile::Open(LPCTSTR fileName, DWORD shareMode, + DWORD creationDisposition, DWORD flagsAndAttributes) +{ + return CFileBase::Create(fileName, GENERIC_WRITE, shareMode, + creationDisposition, flagsAndAttributes); +} + +static inline DWORD GetCreationDisposition(bool createAlways) + { return createAlways? CREATE_ALWAYS: CREATE_NEW; } + +bool COutFile::Open(LPCTSTR fileName, DWORD creationDisposition) +{ + return Open(fileName, FILE_SHARE_READ, + creationDisposition, FILE_ATTRIBUTE_NORMAL); +} + +bool COutFile::Create(LPCTSTR fileName, bool createAlways) +{ + return Open(fileName, GetCreationDisposition(createAlways)); +} + +#ifndef _UNICODE + +bool COutFile::Open(LPCWSTR fileName, DWORD shareMode, + DWORD creationDisposition, DWORD flagsAndAttributes) +{ + return CFileBase::Create(fileName, GENERIC_WRITE, shareMode, + creationDisposition, flagsAndAttributes); +} + +bool COutFile::Open(LPCWSTR fileName, DWORD creationDisposition) +{ + return Open(fileName, FILE_SHARE_READ, + creationDisposition, FILE_ATTRIBUTE_NORMAL); +} + +bool COutFile::Create(LPCWSTR fileName, bool createAlways) +{ + return Open(fileName, GetCreationDisposition(createAlways)); +} + +#endif + +bool COutFile::SetTime(const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime) +{ + LARGE_INTEGER ltime; + DWORD dw; + + if (_fd == -1) { + SetLastError( ERROR_INVALID_HANDLE ); + return false; + } + + /* On some OS (cygwin, MacOSX ...), you must close the file before updating times */ + if (aTime) { + ltime.QuadPart = aTime->dwHighDateTime; + ltime.QuadPart = (ltime.QuadPart << 32) | aTime->dwLowDateTime; + RtlTimeToSecondsSince1970( <ime, &dw ); + _lastAccessTime = dw; + } + if (mTime) { + ltime.QuadPart = mTime->dwHighDateTime; + ltime.QuadPart = (ltime.QuadPart << 32) | mTime->dwLowDateTime; + RtlTimeToSecondsSince1970( <ime, &dw ); + _lastWriteTime = dw; + } + + return true; +} + +bool COutFile::SetMTime(const FILETIME *mTime) +{ + return SetTime(NULL, NULL, mTime); +} + +bool COutFile::WritePart(const void *data, UINT32 size, UINT32 &processedSize) +{ +// if (size > kChunkSizeMax) +// size = kChunkSizeMax; + + return Write(data,size,processedSize); +} + +bool COutFile::Write(const void *buffer, UINT32 bytesToWrite, UINT32 &bytesWritten) +{ + if (_fd == -1) + { + SetLastError( ERROR_INVALID_HANDLE ); + return false; + } + + ssize_t ret; + do { + ret = write(_fd,buffer, bytesToWrite); + } while (ret < 0 && (errno == EINTR)); + + if (ret != -1) { + bytesWritten = ret; + return TRUE; + } + bytesWritten =0; + return FALSE; +} + +bool COutFile::SetEndOfFile() +{ + if (_fd == -1) + { + SetLastError( ERROR_INVALID_HANDLE ); + return false; + } + + bool bret = false; + + off_t pos_cur = lseek(_fd, 0, SEEK_CUR); + if (pos_cur != (off_t)-1) { + int iret = ftruncate(_fd, pos_cur); + if (iret == 0) bret = true; + } + + return bret; +} + +bool COutFile::SetLength(UINT64 length) +{ + UINT64 newPosition; + if(!Seek(length, newPosition)) + return false; + if(newPosition != length) + return false; + return SetEndOfFile(); +} + +}}} diff --git a/src/libs/7zip/unix/CPP/Windows/FileIO.h b/src/libs/7zip/unix/CPP/Windows/FileIO.h new file mode 100644 index 000000000..4aa84c053 --- /dev/null +++ b/src/libs/7zip/unix/CPP/Windows/FileIO.h @@ -0,0 +1,110 @@ +// Windows/FileIO.h + +#ifndef __WINDOWS_FILEIO_H +#define __WINDOWS_FILEIO_H + +#include <Common/MyString.h> + +#ifndef _WIN32 + +#define FILE_SHARE_READ 1 +#define FILE_SHARE_WRITE 2 + +#define FILE_BEGIN SEEK_SET +#define FILE_CURRENT SEEK_CUR +#define FILE_END SEEK_END +#define INVALID_SET_FILE_POINTER ((DWORD)-1) + +#define CREATE_NEW 1 +#define CREATE_ALWAYS 2 +#define OPEN_EXISTING 3 +#define OPEN_ALWAYS 4 +/* #define TRUNCATE_EXISTING 5 */ + +#endif + +namespace NWindows { +namespace NFile { +namespace NIO { + + +class CFileBase +{ +protected: + int _fd; + AString _unix_filename; + time_t _lastAccessTime; + time_t _lastWriteTime; +#ifdef ENV_HAVE_LSTAT + int _size; + char _buffer[MAX_PATHNAME_LEN+1]; + int _offset; +#endif + + bool Create(LPCSTR fileName, DWORD desiredAccess, + DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes,bool ignoreSymbolicLink=false); + bool Create(LPCWSTR fileName, DWORD desiredAccess, + DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes,bool ignoreSymbolicLink=false); + +public: + CFileBase(): _fd(-1) {}; + virtual ~CFileBase(); + + virtual bool Close(); + + bool GetLength(UINT64 &length) const; + + bool Seek(INT64 distanceToMove, DWORD moveMethod, UINT64 &newPosition); + bool Seek(UINT64 position, UINT64 &newPosition); +}; + +class CInFile: public CFileBase +{ +public: + bool Open(LPCTSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes); + bool OpenShared(LPCTSTR fileName, bool /* shareForWrite */ ,bool ignoreSymbolicLink=false) { + return Open(fileName,ignoreSymbolicLink); + } + bool Open(LPCTSTR fileName,bool ignoreSymbolicLink=false); + #ifndef _UNICODE + bool Open(LPCWSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes); + bool OpenShared(LPCWSTR fileName, bool /* shareForWrite */ ,bool ignoreSymbolicLink=false) { + return Open(fileName,ignoreSymbolicLink); + } + bool Open(LPCWSTR fileName,bool ignoreSymbolicLink=false); + #endif + bool ReadPart(void *data, UINT32 size, UINT32 &processedSize); + bool Read(void *data, UINT32 size, UINT32 &processedSize); +}; + +class COutFile: public CFileBase +{ +public: + bool Open(LPCTSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes); + bool Open(LPCTSTR fileName, DWORD creationDisposition); + bool Create(LPCTSTR fileName, bool createAlways); + + #ifndef _UNICODE + bool Open(LPCWSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes); + bool Open(LPCWSTR fileName, DWORD creationDisposition); + bool Create(LPCWSTR fileName, bool createAlways); + #endif + + /* + void SetOpenCreationDisposition(DWORD creationDisposition) + { m_CreationDisposition = creationDisposition; } + void SetOpenCreationDispositionCreateAlways() + { m_CreationDisposition = CREATE_ALWAYS; } + */ + + bool SetTime(const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime); + bool SetMTime(const FILETIME *mTime); + bool WritePart(const void *data, UINT32 size, UINT32 &processedSize); + bool Write(const void *data, UINT32 size, UINT32 &processedSize); + bool SetEndOfFile(); + bool SetLength(UINT64 length); +}; + +}}} + +#endif diff --git a/src/libs/7zip/unix/CPP/Windows/FileName.cpp b/src/libs/7zip/unix/CPP/Windows/FileName.cpp new file mode 100644 index 000000000..8443a4af9 --- /dev/null +++ b/src/libs/7zip/unix/CPP/Windows/FileName.cpp @@ -0,0 +1,50 @@ +// Windows/FileName.cpp + +#include "StdAfx.h" + +#include "Windows/FileName.h" +#include "Common/Wildcard.h" + +namespace NWindows { +namespace NFile { +namespace NName { + +void NormalizeDirPathPrefix(CSysString &dirPath) +{ + if (dirPath.IsEmpty()) + return; + if (dirPath.ReverseFind(kDirDelimiter) != dirPath.Length() - 1) + dirPath += kDirDelimiter; +} + +#ifndef _UNICODE +void NormalizeDirPathPrefix(UString &dirPath) +{ + if (dirPath.IsEmpty()) + return; + if (dirPath.ReverseFind(wchar_t(kDirDelimiter)) != dirPath.Length() - 1) + dirPath += wchar_t(kDirDelimiter); +} +#endif + +const wchar_t kExtensionDelimiter = L'.'; + +void SplitNameToPureNameAndExtension(const UString &fullName, + UString &pureName, UString &extensionDelimiter, UString &extension) +{ + int index = fullName.ReverseFind(kExtensionDelimiter); + if (index < 0) + { + pureName = fullName; + extensionDelimiter.Empty(); + extension.Empty(); + } + else + { + pureName = fullName.Left(index); + extensionDelimiter = kExtensionDelimiter; + extension = fullName.Mid(index + 1); + } +} + +}}} diff --git a/src/libs/7zip/unix/CPP/Windows/FileName.h b/src/libs/7zip/unix/CPP/Windows/FileName.h new file mode 100644 index 000000000..d98079026 --- /dev/null +++ b/src/libs/7zip/unix/CPP/Windows/FileName.h @@ -0,0 +1,27 @@ +// Windows/FileName.h + +#ifndef __WINDOWS_FILENAME_H +#define __WINDOWS_FILENAME_H + +#include "../../C/Types.h" + +#include "../Common/MyString.h" + +namespace NWindows { +namespace NFile { +namespace NName { + +const TCHAR kDirDelimiter = CHAR_PATH_SEPARATOR; +const TCHAR kAnyStringWildcard = '*'; + +void NormalizeDirPathPrefix(CSysString &dirPath); // ensures that it ended with '\\' +#ifndef _UNICODE +void NormalizeDirPathPrefix(UString &dirPath); // ensures that it ended with '\\' +#endif + +void SplitNameToPureNameAndExtension(const UString &fullName, + UString &pureName, UString &extensionDelimiter, UString &extension); + +}}} + +#endif diff --git a/src/libs/7zip/unix/CPP/Windows/Handle.h b/src/libs/7zip/unix/CPP/Windows/Handle.h new file mode 100644 index 000000000..0791b4acd --- /dev/null +++ b/src/libs/7zip/unix/CPP/Windows/Handle.h @@ -0,0 +1,37 @@ +// Windows/Handle.h + +#ifndef __WINDOWS_HANDLE_H +#define __WINDOWS_HANDLE_H + +namespace NWindows { + +class CHandle +{ +protected: + HANDLE _handle; +public: + operator HANDLE() { return _handle; } + CHandle(): _handle(NULL) {} + ~CHandle() { Close(); } + bool Close() + { + if (_handle == NULL) + return true; + if (!::CloseHandle(_handle)) + return false; + _handle = NULL; + return true; + } + void Attach(HANDLE handle) + { _handle = handle; } + HANDLE Detach() + { + HANDLE handle = _handle; + _handle = NULL; + return handle; + } +}; + +} + +#endif diff --git a/src/libs/7zip/unix/CPP/Windows/Menu.h b/src/libs/7zip/unix/CPP/Windows/Menu.h new file mode 100644 index 000000000..2f753c237 --- /dev/null +++ b/src/libs/7zip/unix/CPP/Windows/Menu.h @@ -0,0 +1,4 @@ + +/* TODO */ + + diff --git a/src/libs/7zip/unix/CPP/Windows/NtCheck.h b/src/libs/7zip/unix/CPP/Windows/NtCheck.h new file mode 100644 index 000000000..e56318f00 --- /dev/null +++ b/src/libs/7zip/unix/CPP/Windows/NtCheck.h @@ -0,0 +1,44 @@ +// Windows/NtCheck.h + +#ifndef __WINDOWS_NT_CHECK_H +#define __WINDOWS_NT_CHECK_H + +#ifdef _WIN32 + +#if !defined(_WIN64) && !defined(UNDER_CE) +static inline bool IsItWindowsNT() +{ + OSVERSIONINFO vi; + vi.dwOSVersionInfoSize = sizeof(vi); + return (::GetVersionEx(&vi) && vi.dwPlatformId == VER_PLATFORM_WIN32_NT); +} +#endif + +#ifndef _UNICODE + #if defined(_WIN64) || defined(UNDER_CE) + bool g_IsNT = true; + #define SET_IS_NT + #else + bool g_IsNT = false; + #define SET_IS_NT g_IsNT = IsItWindowsNT(); + #endif + #define NT_CHECK_ACTION + // #define NT_CHECK_ACTION { NT_CHECK_FAIL_ACTION } +#else + #if !defined(_WIN64) && !defined(UNDER_CE) + #define NT_CHECK_ACTION if (!IsItWindowsNT()) { NT_CHECK_FAIL_ACTION } + #else + #define NT_CHECK_ACTION + #endif + #define SET_IS_NT +#endif + +#define NT_CHECK NT_CHECK_ACTION SET_IS_NT + +#else + +#define NT_CHECK + +#endif + +#endif diff --git a/src/libs/7zip/unix/CPP/Windows/PropVariant.cpp b/src/libs/7zip/unix/CPP/Windows/PropVariant.cpp new file mode 100644 index 000000000..90212e08f --- /dev/null +++ b/src/libs/7zip/unix/CPP/Windows/PropVariant.cpp @@ -0,0 +1,243 @@ +// Windows/PropVariant.cpp + +#include "StdAfx.h" + +#include "PropVariant.h" + +#include "../Common/Defs.h" + +namespace NWindows { +namespace NCOM { + +CPropVariant::CPropVariant(const PROPVARIANT &varSrc) +{ + vt = VT_EMPTY; + InternalCopy(&varSrc); +} + +CPropVariant::CPropVariant(const CPropVariant &varSrc) +{ + vt = VT_EMPTY; + InternalCopy(&varSrc); +} + +CPropVariant::CPropVariant(BSTR bstrSrc) +{ + vt = VT_EMPTY; + *this = bstrSrc; +} + +CPropVariant::CPropVariant(LPCOLESTR lpszSrc) +{ + vt = VT_EMPTY; + *this = lpszSrc; +} + +CPropVariant& CPropVariant::operator=(const CPropVariant &varSrc) +{ + InternalCopy(&varSrc); + return *this; +} +CPropVariant& CPropVariant::operator=(const PROPVARIANT &varSrc) +{ + InternalCopy(&varSrc); + return *this; +} + +CPropVariant& CPropVariant::operator=(BSTR bstrSrc) +{ + *this = (LPCOLESTR)bstrSrc; + return *this; +} + +static const char *kMemException = "out of memory"; + +CPropVariant& CPropVariant::operator=(LPCOLESTR lpszSrc) +{ + InternalClear(); + vt = VT_BSTR; + wReserved1 = 0; + bstrVal = ::SysAllocString(lpszSrc); + if (bstrVal == NULL && lpszSrc != NULL) + { + throw kMemException; + // vt = VT_ERROR; + // scode = E_OUTOFMEMORY; + } + return *this; +} + + +CPropVariant& CPropVariant::operator=(const char *s) +{ + InternalClear(); + vt = VT_BSTR; + wReserved1 = 0; + UINT len = (UINT)strlen(s); + bstrVal = ::SysAllocStringByteLen(0, (UINT)len * sizeof(OLECHAR)); + if (bstrVal == NULL) + { + throw kMemException; + // vt = VT_ERROR; + // scode = E_OUTOFMEMORY; + } + else + { + for (UINT i = 0; i <= len; i++) + bstrVal[i] = s[i]; + } + return *this; +} + +CPropVariant& CPropVariant::operator=(bool bSrc) +{ + if (vt != VT_BOOL) + { + InternalClear(); + vt = VT_BOOL; + } + boolVal = bSrc ? VARIANT_TRUE : VARIANT_FALSE; + return *this; +} + +#define SET_PROP_FUNC(type, id, dest) \ + CPropVariant& CPropVariant::operator=(type value) \ + { if (vt != id) { InternalClear(); vt = id; } \ + dest = value; return *this; } + +SET_PROP_FUNC(Byte, VT_UI1, bVal) +SET_PROP_FUNC(Int16, VT_I2, iVal) +SET_PROP_FUNC(Int32, VT_I4, lVal) +SET_PROP_FUNC(UInt32, VT_UI4, ulVal) +SET_PROP_FUNC(UInt64, VT_UI8, uhVal.QuadPart) +SET_PROP_FUNC(const FILETIME &, VT_FILETIME, filetime) + +static HRESULT MyPropVariantClear(PROPVARIANT *prop) +{ + switch(prop->vt) + { + case VT_UI1: + case VT_I1: + case VT_I2: + case VT_UI2: + case VT_BOOL: + case VT_I4: + case VT_UI4: + case VT_R4: + case VT_INT: + case VT_UINT: + case VT_ERROR: + case VT_FILETIME: + case VT_UI8: + case VT_R8: + case VT_CY: + case VT_DATE: + prop->vt = VT_EMPTY; + prop->wReserved1 = 0; + return S_OK; + } + return ::VariantClear((VARIANTARG *)prop); +} + +HRESULT CPropVariant::Clear() +{ + return MyPropVariantClear(this); +} + +HRESULT CPropVariant::Copy(const PROPVARIANT* pSrc) +{ + ::VariantClear((tagVARIANT *)this); + switch(pSrc->vt) + { + case VT_UI1: + case VT_I1: + case VT_I2: + case VT_UI2: + case VT_BOOL: + case VT_I4: + case VT_UI4: + case VT_R4: + case VT_INT: + case VT_UINT: + case VT_ERROR: + case VT_FILETIME: + case VT_UI8: + case VT_R8: + case VT_CY: + case VT_DATE: + memmove((PROPVARIANT*)this, pSrc, sizeof(PROPVARIANT)); + return S_OK; + } + return ::VariantCopy((tagVARIANT *)this, (tagVARIANT *)const_cast<PROPVARIANT *>(pSrc)); +} + + +HRESULT CPropVariant::Attach(PROPVARIANT *pSrc) +{ + HRESULT hr = Clear(); + if (FAILED(hr)) + return hr; + memcpy(this, pSrc, sizeof(PROPVARIANT)); + pSrc->vt = VT_EMPTY; + return S_OK; +} + +HRESULT CPropVariant::Detach(PROPVARIANT *pDest) +{ + HRESULT hr = MyPropVariantClear(pDest); + if (FAILED(hr)) + return hr; + memcpy(pDest, this, sizeof(PROPVARIANT)); + vt = VT_EMPTY; + return S_OK; +} + +HRESULT CPropVariant::InternalClear() +{ + HRESULT hr = Clear(); + if (FAILED(hr)) + { + vt = VT_ERROR; + scode = hr; + } + return hr; +} + +void CPropVariant::InternalCopy(const PROPVARIANT *pSrc) +{ + HRESULT hr = Copy(pSrc); + if (FAILED(hr)) + { + if (hr == E_OUTOFMEMORY) + throw kMemException; + vt = VT_ERROR; + scode = hr; + } +} + +int CPropVariant::Compare(const CPropVariant &a) +{ + if (vt != a.vt) + return MyCompare(vt, a.vt); + switch (vt) + { + case VT_EMPTY: return 0; + // case VT_I1: return MyCompare(cVal, a.cVal); + case VT_UI1: return MyCompare(bVal, a.bVal); + case VT_I2: return MyCompare(iVal, a.iVal); + case VT_UI2: return MyCompare(uiVal, a.uiVal); + case VT_I4: return MyCompare(lVal, a.lVal); + case VT_UI4: return MyCompare(ulVal, a.ulVal); + // case VT_UINT: return MyCompare(uintVal, a.uintVal); + case VT_I8: return MyCompare(hVal.QuadPart, a.hVal.QuadPart); + case VT_UI8: return MyCompare(uhVal.QuadPart, a.uhVal.QuadPart); + case VT_BOOL: return -MyCompare(boolVal, a.boolVal); + case VT_FILETIME: return ::CompareFileTime(&filetime, &a.filetime); + case VT_BSTR: + return 0; // Not implemented + // return MyCompare(aPropVarint.cVal); + default: return 0; + } +} + +}} diff --git a/src/libs/7zip/unix/CPP/Windows/PropVariant.h b/src/libs/7zip/unix/CPP/Windows/PropVariant.h new file mode 100644 index 000000000..d018034eb --- /dev/null +++ b/src/libs/7zip/unix/CPP/Windows/PropVariant.h @@ -0,0 +1,56 @@ +// Windows/PropVariant.h + +#ifndef __WINDOWS_PROPVARIANT_H +#define __WINDOWS_PROPVARIANT_H + +#include "../Common/MyWindows.h" +#include "../Common/Types.h" + +namespace NWindows { +namespace NCOM { + +class CPropVariant : public tagPROPVARIANT +{ +public: + CPropVariant() { vt = VT_EMPTY; wReserved1 = 0; } + ~CPropVariant() { Clear(); } + CPropVariant(const PROPVARIANT &varSrc); + CPropVariant(const CPropVariant &varSrc); + CPropVariant(BSTR bstrSrc); + CPropVariant(LPCOLESTR lpszSrc); + CPropVariant(bool bSrc) { vt = VT_BOOL; wReserved1 = 0; boolVal = (bSrc ? VARIANT_TRUE : VARIANT_FALSE); }; + CPropVariant(Byte value) { vt = VT_UI1; wReserved1 = 0; bVal = value; } + CPropVariant(Int16 value) { vt = VT_I2; wReserved1 = 0; iVal = value; } + CPropVariant(Int32 value) { vt = VT_I4; wReserved1 = 0; lVal = value; } + CPropVariant(UInt32 value) { vt = VT_UI4; wReserved1 = 0; ulVal = value; } + CPropVariant(UInt64 value) { vt = VT_UI8; wReserved1 = 0; uhVal.QuadPart = value; } + CPropVariant(const FILETIME &value) { vt = VT_FILETIME; wReserved1 = 0; filetime = value; } + + CPropVariant& operator=(const CPropVariant &varSrc); + CPropVariant& operator=(const PROPVARIANT &varSrc); + CPropVariant& operator=(BSTR bstrSrc); + CPropVariant& operator=(LPCOLESTR lpszSrc); + CPropVariant& operator=(const char *s); + CPropVariant& operator=(bool bSrc); + CPropVariant& operator=(Byte value); + CPropVariant& operator=(Int16 value); + CPropVariant& operator=(Int32 value); + CPropVariant& operator=(UInt32 value); + CPropVariant& operator=(Int64 value); + CPropVariant& operator=(UInt64 value); + CPropVariant& operator=(const FILETIME &value); + + HRESULT Clear(); + HRESULT Copy(const PROPVARIANT *pSrc); + HRESULT Attach(PROPVARIANT *pSrc); + HRESULT Detach(PROPVARIANT *pDest); + + HRESULT InternalClear(); + void InternalCopy(const PROPVARIANT *pSrc); + + int Compare(const CPropVariant &a1); +}; + +}} + +#endif diff --git a/src/libs/7zip/unix/CPP/Windows/PropVariantConversions.cpp b/src/libs/7zip/unix/CPP/Windows/PropVariantConversions.cpp new file mode 100644 index 000000000..61d524d07 --- /dev/null +++ b/src/libs/7zip/unix/CPP/Windows/PropVariantConversions.cpp @@ -0,0 +1,142 @@ +// PropVariantConversions.cpp + +#include "StdAfx.h" + +#include "Common/IntToString.h" +#include "Common/StringConvert.h" + +#include "Windows/Defs.h" + +#include "PropVariantConversions.h" + +static UString ConvertUInt64ToString(UInt64 value) +{ + wchar_t buffer[32]; + ConvertUInt64ToString(value, buffer); + return buffer; +} + +static UString ConvertInt64ToString(Int64 value) +{ + wchar_t buffer[32]; + ConvertInt64ToString(value, buffer); + return buffer; +} + +#ifdef _WIN32 +static char *UIntToStringSpec(char c, UInt32 value, char *s, int numPos) +{ + if (c != 0) + *s++ = c; + char temp[16]; + int pos = 0; + do + { + temp[pos++] = (char)('0' + value % 10); + value /= 10; + } + while (value != 0); + int i; + for (i = 0; i < numPos - pos; i++) + *s++ = '0'; + do + *s++ = temp[--pos]; + while (pos > 0); + *s = '\0'; + return s; +} +#endif + +bool ConvertFileTimeToString(const FILETIME &ft, char *s, bool includeTime, bool includeSeconds) +{ +#ifdef _WIN32 + s[0] = '\0'; + SYSTEMTIME st; + if (!BOOLToBool(FileTimeToSystemTime(&ft, &st))) + return false; + s = UIntToStringSpec(0, st.wYear, s, 4); + s = UIntToStringSpec('-', st.wMonth, s, 2); + s = UIntToStringSpec('-', st.wDay, s, 2); + if (includeTime) + { + s = UIntToStringSpec(' ', st.wHour, s, 2); + s = UIntToStringSpec(':', st.wMinute, s, 2); + if (includeSeconds) + UIntToStringSpec(':', st.wSecond, s, 2); + } + /* + sprintf(s, "%04d-%02d-%02d", st.wYear, st.wMonth, st.wDay); + if (includeTime) + { + sprintf(s + strlen(s), " %02d:%02d", st.wHour, st.wMinute); + if (includeSeconds) + sprintf(s + strlen(s), ":%02d", st.wSecond); + } + */ +#else + BOOLEAN WINAPI RtlTimeToSecondsSince1970( const LARGE_INTEGER *Time, DWORD *Seconds ); + + FILETIME filetime; + LocalFileTimeToFileTime(&ft, &filetime); + + LARGE_INTEGER ltime; + + ltime.QuadPart = filetime.dwHighDateTime; + ltime.QuadPart = (ltime.QuadPart << 32) | filetime.dwLowDateTime; + + DWORD dw; + RtlTimeToSecondsSince1970(<ime, &dw ); + time_t timep = (time_t)dw; + + struct tm * date = localtime(&timep); + + sprintf(s, "%04d-%02d-%02d", date->tm_year+1900, date->tm_mon+1,date->tm_mday); + if (includeTime) + { + sprintf(s + strlen(s), " %02d:%02d", date->tm_hour,date->tm_min); + if (includeSeconds) + sprintf(s + strlen(s), ":%02d", date->tm_sec); + } +#endif + return true; +} + +UString ConvertFileTimeToString(const FILETIME &ft, bool includeTime, bool includeSeconds) +{ + char s[32]; + ConvertFileTimeToString(ft, s, includeTime, includeSeconds); + return GetUnicodeString(s); +} + + +UString ConvertPropVariantToString(const PROPVARIANT &prop) +{ + switch (prop.vt) + { + case VT_EMPTY: return UString(); + case VT_BSTR: return prop.bstrVal; + case VT_UI1: return ConvertUInt64ToString(prop.bVal); + case VT_UI2: return ConvertUInt64ToString(prop.uiVal); + case VT_UI4: return ConvertUInt64ToString(prop.ulVal); + case VT_UI8: return ConvertUInt64ToString(prop.uhVal.QuadPart); + case VT_FILETIME: return ConvertFileTimeToString(prop.filetime, true, true); + // case VT_I1: return ConvertInt64ToString(prop.cVal); + case VT_I2: return ConvertInt64ToString(prop.iVal); + case VT_I4: return ConvertInt64ToString(prop.lVal); + case VT_I8: return ConvertInt64ToString(prop.hVal.QuadPart); + case VT_BOOL: return VARIANT_BOOLToBool(prop.boolVal) ? L"+" : L"-"; + default: throw 150245; + } +} + +UInt64 ConvertPropVariantToUInt64(const PROPVARIANT &prop) +{ + switch (prop.vt) + { + case VT_UI1: return prop.bVal; + case VT_UI2: return prop.uiVal; + case VT_UI4: return prop.ulVal; + case VT_UI8: return (UInt64)prop.uhVal.QuadPart; + default: throw 151199; + } +} diff --git a/src/libs/7zip/unix/CPP/Windows/PropVariantConversions.h b/src/libs/7zip/unix/CPP/Windows/PropVariantConversions.h new file mode 100644 index 000000000..3de4dedb3 --- /dev/null +++ b/src/libs/7zip/unix/CPP/Windows/PropVariantConversions.h @@ -0,0 +1,14 @@ +// Windows/PropVariantConversions.h + +#ifndef __PROP_VARIANT_CONVERSIONS_H +#define __PROP_VARIANT_CONVERSIONS_H + +#include "Common/MyString.h" +#include "Common/Types.h" + +bool ConvertFileTimeToString(const FILETIME &ft, char *s, bool includeTime = true, bool includeSeconds = true); +UString ConvertFileTimeToString(const FILETIME &ft, bool includeTime = true, bool includeSeconds = true); +UString ConvertPropVariantToString(const PROPVARIANT &prop); +UInt64 ConvertPropVariantToUInt64(const PROPVARIANT &prop); + +#endif diff --git a/src/libs/7zip/unix/CPP/Windows/PropVariantUtils.cpp b/src/libs/7zip/unix/CPP/Windows/PropVariantUtils.cpp new file mode 100644 index 000000000..0a9cfab7f --- /dev/null +++ b/src/libs/7zip/unix/CPP/Windows/PropVariantUtils.cpp @@ -0,0 +1,78 @@ +// PropVariantUtils.cpp + +#include "StdAfx.h" + +#include "PropVariantUtils.h" +#include "Common/StringConvert.h" +#include "Common/IntToString.h" + +using namespace NWindows; + +static AString GetHex(UInt32 v) +{ + char sz[32] = { '0', 'x' }; + ConvertUInt64ToString(v, sz + 2, 16); + return sz; +} + +void StringToProp(const AString &s, NCOM::CPropVariant &prop) +{ + prop = MultiByteToUnicodeString(s); +} + +void PairToProp(const CUInt32PCharPair *pairs, unsigned num, UInt32 value, NCOM::CPropVariant &prop) +{ + AString s; + for (unsigned i = 0; i < num; i++) + { + const CUInt32PCharPair &p = pairs[i]; + if (p.Value == value) + s = p.Name; + } + if (s.IsEmpty()) + s = GetHex(value); + StringToProp(s, prop); +} + +AString TypeToString(const char *table[], unsigned num, UInt32 value) +{ + if (value < num) + return table[value]; + return GetHex(value); +} + +void TypeToProp(const char *table[], unsigned num, UInt32 value, NCOM::CPropVariant &prop) +{ + StringToProp(TypeToString(table, num, value), prop); +} + + +AString FlagsToString(const CUInt32PCharPair *pairs, unsigned num, UInt32 flags) +{ + AString s; + for (unsigned i = 0; i < num; i++) + { + const CUInt32PCharPair &p = pairs[i]; + UInt32 flag = (UInt32)1 << (unsigned)p.Value; + if ((flags & flag) != 0) + { + if (!s.IsEmpty()) + s += ' '; + s += p.Name; + } + flags &= ~flag; + } + if (flags != 0) + { + if (!s.IsEmpty()) + s += ' '; + s += GetHex(flags); + } + return s; +} + +void FlagsToProp(const CUInt32PCharPair *pairs, unsigned num, UInt32 flags, NCOM::CPropVariant &prop) +{ + StringToProp(FlagsToString(pairs, num, flags), prop); +} + diff --git a/src/libs/7zip/unix/CPP/Windows/PropVariantUtils.h b/src/libs/7zip/unix/CPP/Windows/PropVariantUtils.h new file mode 100644 index 000000000..5aaf65cb9 --- /dev/null +++ b/src/libs/7zip/unix/CPP/Windows/PropVariantUtils.h @@ -0,0 +1,28 @@ +// Windows/PropVariantUtils.h + +#ifndef __PROP_VARIANT_UTILS_H +#define __PROP_VARIANT_UTILS_H + +#include "Common/MyString.h" +#include "PropVariant.h" + +struct CUInt32PCharPair +{ + UInt32 Value; + const char *Name; +}; + +void StringToProp(const AString &s, NWindows::NCOM::CPropVariant &prop); +void PairToProp(const CUInt32PCharPair *pairs, unsigned num, UInt32 value, NWindows::NCOM::CPropVariant &prop); + +AString FlagsToString(const CUInt32PCharPair *pairs, unsigned num, UInt32 flags); +void FlagsToProp(const CUInt32PCharPair *pairs, unsigned num, UInt32 flags, NWindows::NCOM::CPropVariant &prop); + +AString TypeToString(const char *table[], unsigned num, UInt32 value); +void TypeToProp(const char *table[], unsigned num, UInt32 value, NWindows::NCOM::CPropVariant &prop); + +#define PAIR_TO_PROP(pairs, value, prop) PairToProp(pairs, sizeof(pairs) / sizeof(pairs[0]), value, prop) +#define FLAGS_TO_PROP(pairs, value, prop) FlagsToProp(pairs, sizeof(pairs) / sizeof(pairs[0]), value, prop) +#define TYPE_TO_PROP(table, value, prop) TypeToProp(table, sizeof(table) / sizeof(table[0]), value, prop) + +#endif diff --git a/src/libs/7zip/unix/CPP/Windows/Registry.cpp b/src/libs/7zip/unix/CPP/Windows/Registry.cpp new file mode 100644 index 000000000..74e255df4 --- /dev/null +++ b/src/libs/7zip/unix/CPP/Windows/Registry.cpp @@ -0,0 +1,313 @@ +// Windows/Registry.cpp + +#include "StdAfx.h" + +#ifndef _UNICODE +#include "Common/StringConvert.h" +#endif +#include "Windows/Registry.h" + +#include <wx/config.h> + +class HKEY_Impl +{ + public: + wxString path; + HKEY_Impl(wxString a) : path(a) {} +}; + +namespace NWindows { +namespace NRegistry { + +#define ERROR_SET_VALUE (E_INVALIDARG) // FIXME +#define ERROR_GET_VALUE (E_INVALIDARG) // FIXME +#define PROGRAM_NAME L"p7zip" + +static wxConfig * g_config = 0; +static int g_config_ref = 0; + +static void configAddRef() { + if (g_config == 0) { + g_config = new wxConfig(PROGRAM_NAME); + g_config->Flush(true); + wxConfigBase::Set(g_config); + } + g_config_ref++; +} + +static void configSubRef() { + if (g_config_ref >= 1) + { + g_config_ref--; + if (g_config_ref == 0) { + delete g_config; + g_config = 0; + wxConfigBase::Set(NULL); + } else { + g_config->Flush(true); + } + } +} + + LONG CKey::Close() + { + if (_object) + { + configSubRef(); + delete _object; + } + _object = 0; + return ERROR_SUCCESS; + } + + LONG CKey::Create(HKEY parentKey, LPCTSTR keyName) + { + Close(); + + configAddRef(); + + wxString path; + + if (parentKey == HKEY_CURRENT_USER) { + path=L"/" + wxString(keyName); + } else { + path = parentKey->path + L"/" + wxString(keyName); + } + _object = new HKEY_Impl(path); + return ERROR_SUCCESS; + } + LONG CKey::Open(HKEY parentKey, LPCTSTR keyName, REGSAM accessMask) + { + Close(); + + configAddRef(); + + wxString path; + + if (parentKey == HKEY_CURRENT_USER) { + path=L"/" + wxString(keyName); + } else { + path = parentKey->path + L"/" + wxString(keyName); + } + _object = new HKEY_Impl(path); + return ERROR_SUCCESS; + } + + LONG CKey::RecurseDeleteKey(LPCTSTR subKeyName) + { + g_config->SetPath(_object->path); + bool ret = g_config->DeleteGroup(subKeyName); + if (ret) return ERROR_SUCCESS; + return ERROR_GET_VALUE; + } + + LONG CKey::DeleteValue(LPCTSTR name) + { + g_config->SetPath(_object->path); + bool ret = g_config->DeleteEntry(name); + if (ret) return ERROR_SUCCESS; + return ERROR_GET_VALUE; + } + + LONG CKey::QueryValue(LPCTSTR name, UInt32 &value) + { + g_config->SetPath(_object->path); + long val; + bool ret = g_config->Read(name,&val); + if (ret) { + value = (UInt32)val; + return ERROR_SUCCESS; + } + return ERROR_GET_VALUE; + } + + LONG CKey::QueryValue(LPCTSTR name, bool &value) + { + g_config->SetPath(_object->path); + bool ret = g_config->Read(name,&value); + if (ret) return ERROR_SUCCESS; + return ERROR_GET_VALUE; + } + + LONG CKey::QueryValue(LPCTSTR name, CSysString &value) + { + g_config->SetPath(_object->path); + wxString val; + bool ret = g_config->Read(name,&val); + if (ret) { + value = val; + return ERROR_SUCCESS; + } + return ERROR_GET_VALUE; + } + +LONG CKey::GetValue_IfOk(LPCTSTR name, UInt32 &value) +{ + UInt32 newVal; + LONG res = QueryValue(name, newVal); + if (res == ERROR_SUCCESS) + value = newVal; + return res; +} + +LONG CKey::GetValue_IfOk(LPCTSTR name, bool &value) +{ + bool newVal; + LONG res = QueryValue(name, newVal); + if (res == ERROR_SUCCESS) + value = newVal; + return res; +} + + + LONG CKey::SetValue(LPCTSTR valueName, UInt32 value) + { + g_config->SetPath(_object->path); + bool ret = g_config->Write(valueName,(long)value); + if (ret == true) return ERROR_SUCCESS; + return ERROR_SET_VALUE; + } + LONG CKey::SetValue(LPCTSTR valueName, bool value) + { + g_config->SetPath(_object->path); + bool ret = g_config->Write(valueName,value); + if (ret == true) return ERROR_SUCCESS; + return ERROR_SET_VALUE; + } + LONG CKey::SetValue(LPCTSTR valueName, LPCTSTR value) + { + g_config->SetPath(_object->path); + bool ret = g_config->Write(valueName,value); + if (ret == true) return ERROR_SUCCESS; + return ERROR_SET_VALUE; + } + + LONG CKey::SetValue(LPCTSTR name, const void *value, UInt32 size) + { + static char hexa[] = "0123456789ABCDEF"; + /* FIXME + MYASSERT(value != NULL); + MYASSERT(_object != NULL); + return RegSetValueEx(_object, name, NULL, REG_BINARY, (const BYTE *)value, size); + */ + BYTE *buf = (BYTE *)value; + wxString str; + for(UInt32 i=0;i<size;i++) + { + str += hexa[ (buf[i]>>4) & 0x0f]; + str += hexa[ buf[i] & 0x0f]; + } + return SetValue(name,(LPCTSTR)str); + } + + LONG CKey::EnumKeys(CSysStringVector &keyNames) + { + g_config->SetPath(_object->path); + keyNames.Clear(); + // enumeration variables + wxString str; + long dummy; + bool bCont = g_config->GetFirstEntry(str, dummy); + while ( bCont ) { + keyNames.Add((const TCHAR *)str); + bCont = g_config->GetNextEntry(str, dummy); + } + + // now all groups... + bCont = g_config->GetFirstGroup(str, dummy); + while ( bCont ) { + keyNames.Add((const TCHAR *)str); + bCont = g_config->GetNextGroup(str, dummy); + } + return ERROR_SUCCESS; + } + + LONG CKey::QueryValue(LPCTSTR name, void *value, UInt32 &dataSize) + { + g_config->SetPath(_object->path); + wxString str; + bool ret = g_config->Read(name,&str); + if (ret == false) return ERROR_GET_VALUE; + + size_t l = str.Len() / 2; + if (l > dataSize) l = dataSize; + else dataSize=l; + + BYTE *buf = (BYTE *)value; + for(UInt32 i=0;i<dataSize;i++) + { + char cval[3]; + cval[0] = (char)str[2*i]; + cval[1] = (char)str[2*i+1]; + cval[2] = 0; + unsigned uval = 0; + sscanf(cval,"%x",&uval); + buf[i]=(BYTE)uval; + } + + return ERROR_SUCCESS; + } + + + LONG CKey::QueryValue(LPCTSTR name, CByteBuffer &value, UInt32 &dataSize) + { + g_config->SetPath(_object->path); + wxString str; + bool ret = g_config->Read(name,&str); + if (ret == false) return ERROR_GET_VALUE; + + dataSize = str.Len() / 2; + value.SetCapacity(dataSize); + return QueryValue(name, (BYTE *)value, dataSize); + } + + +LONG CKey::SetValue_Strings(LPCTSTR valueName, const UStringVector &strings) +{ + UInt32 numChars = 0; + int i; + for (i = 0; i < strings.Size(); i++) + numChars += strings[i].Length() + 1; + CBuffer<wchar_t> buffer; + buffer.SetCapacity(numChars); + int pos = 0; + for (i = 0; i < strings.Size(); i++) + { + const UString &s = strings[i]; + MyStringCopy((wchar_t *)buffer + pos, (const wchar_t *)s); + pos += s.Length() + 1; + } + return SetValue(valueName, buffer, numChars * sizeof(wchar_t)); +} + +LONG CKey::GetValue_Strings(LPCTSTR valueName, UStringVector &strings) +{ + strings.Clear(); + CByteBuffer buffer; + UInt32 dataSize; + LONG res = QueryValue(valueName, buffer, dataSize); + if (res != ERROR_SUCCESS) + return res; + if (dataSize % sizeof(wchar_t) != 0) + return E_FAIL; + const wchar_t *data = (const wchar_t *)(const Byte *)buffer; + int numChars = dataSize / sizeof(wchar_t); + UString s; + for (int i = 0; i < numChars; i++) + { + wchar_t c = data[i]; + if (c == 0) + { + strings.Add(s); + s.Empty(); + } + else + s += c; + } + return res; +} + + +} +} + diff --git a/src/libs/7zip/unix/CPP/Windows/Registry.h b/src/libs/7zip/unix/CPP/Windows/Registry.h new file mode 100644 index 000000000..a9078751f --- /dev/null +++ b/src/libs/7zip/unix/CPP/Windows/Registry.h @@ -0,0 +1,113 @@ +// Windows/Registry.h + +#ifndef __WINDOWS_REGISTRY_H +#define __WINDOWS_REGISTRY_H + +#include "Common/Buffer.h" +#include "Common/MyString.h" +#include "Common/Types.h" + +#ifndef _WIN32 +class HKEY_Impl; + +typedef HKEY_Impl * HKEY; + +/* +#define HKEY_CLASSES_ROOT ((HKEY) 0x80000000) +#define HKEY_LOCAL_MACHINE ((HKEY) 0x80000002) +#define HKEY_USERS ((HKEY) 0x80000003) +#define HKEY_PERFORMANCE_DATA ((HKEY) 0x80000004) +#define HKEY_CURRENT_CONFIG ((HKEY) 0x80000005) +#define HKEY_DYN_DATA ((HKEY) 0x80000006) +*/ +#define HKEY_CURRENT_USER ((HKEY) 0x80000001) + + +typedef DWORD REGSAM; +#define ERROR_SUCCESS (0) +#define KEY_READ (0x1234) // FIXME +#define KEY_ALL_ACCESS (~0) // FIXME + +/* ------------------------------ end registry ------------------------------ */ + +#endif + +namespace NWindows { +namespace NRegistry { + +const TCHAR kKeyNameDelimiter = TEXT(CHAR_PATH_SEPARATOR); + +// LONG SetValue(HKEY parentKey, LPCTSTR keyName, LPCTSTR valueName, LPCTSTR value); + +class CKey +{ + HKEY _object; +public: + CKey(): _object(NULL) {} + ~CKey() { Close(); } + + operator HKEY() const { return _object; } + + #if 0 + HKEY Detach(); + void Attach(HKEY key); + LONG Create(HKEY parentKey, LPCTSTR keyName, + LPTSTR keyClass = REG_NONE, DWORD options = REG_OPTION_NON_VOLATILE, + REGSAM accessMask = KEY_ALL_ACCESS, + LPSECURITY_ATTRIBUTES securityAttributes = NULL, + LPDWORD disposition = NULL); + LONG Open(HKEY parentKey, LPCTSTR keyName, + REGSAM accessMask = KEY_ALL_ACCESS); +#endif // #if 0 + LONG Create(HKEY parentKey, LPCTSTR keyName); + LONG Open(HKEY parentKey, LPCTSTR keyName, + REGSAM accessMask = KEY_ALL_ACCESS); + + LONG Close(); + + LONG DeleteSubKey(LPCTSTR subKeyName); + LONG RecurseDeleteKey(LPCTSTR subKeyName); + + LONG DeleteValue(LPCTSTR name); + #ifndef _UNICODE + LONG DeleteValue(LPCWSTR name); + #endif + + LONG SetValue(LPCTSTR valueName, UInt32 value); + LONG SetValue(LPCTSTR valueName, bool value); + LONG SetValue(LPCTSTR valueName, LPCTSTR value); + // LONG SetValue(LPCTSTR valueName, const CSysString &value); + #ifndef _UNICODE + LONG SetValue(LPCWSTR name, LPCWSTR value); + // LONG SetValue(LPCWSTR name, const UString &value); + #endif + + LONG SetValue(LPCTSTR name, const void *value, UInt32 size); + + LONG SetValue_Strings(LPCTSTR valueName, const UStringVector &strings); + LONG GetValue_Strings(LPCTSTR valueName, UStringVector &strings); + + LONG SetKeyValue(LPCTSTR keyName, LPCTSTR valueName, LPCTSTR value); + + LONG QueryValue(LPCTSTR name, UInt32 &value); + LONG QueryValue(LPCTSTR name, bool &value); + LONG QueryValue(LPCTSTR name, LPTSTR value, UInt32 &dataSize); + LONG QueryValue(LPCTSTR name, CSysString &value); + + LONG GetValue_IfOk(LPCTSTR name, UInt32 &value); + LONG GetValue_IfOk(LPCTSTR name, bool &value); + + #ifndef _UNICODE + LONG QueryValue(LPCWSTR name, LPWSTR value, UInt32 &dataSize); + LONG QueryValue(LPCWSTR name, UString &value); + #endif + + LONG QueryValue(LPCTSTR name, void *value, UInt32 &dataSize); + LONG QueryValue(LPCTSTR name, CByteBuffer &value, UInt32 &dataSize); + + LONG EnumKeys(CSysStringVector &keyNames); +}; + +}} + +#endif diff --git a/src/libs/7zip/unix/CPP/Windows/ResourceString.h b/src/libs/7zip/unix/CPP/Windows/ResourceString.h new file mode 100644 index 000000000..ac9c5cd5d --- /dev/null +++ b/src/libs/7zip/unix/CPP/Windows/ResourceString.h @@ -0,0 +1,22 @@ +// Windows/ResourceString.h + +#ifndef __WINDOWS_RESOURCESTRING_H +#define __WINDOWS_RESOURCESTRING_H + +#include "Common/MyString.h" + +namespace NWindows { + +CSysString MyLoadString(HINSTANCE hInstance, UINT resourceID); +CSysString MyLoadString(UINT resourceID); +#ifdef _UNICODE +inline UString MyLoadStringW(HINSTANCE hInstance, UINT resourceID) { return MyLoadString(hInstance, resourceID); } +inline UString MyLoadStringW(UINT resourceID) { return MyLoadString(resourceID); } +#else +UString MyLoadStringW(HINSTANCE hInstance, UINT resourceID); +UString MyLoadStringW(UINT resourceID); +#endif + +} + +#endif diff --git a/src/libs/7zip/unix/CPP/Windows/Shell.h b/src/libs/7zip/unix/CPP/Windows/Shell.h new file mode 100644 index 000000000..f116b772b --- /dev/null +++ b/src/libs/7zip/unix/CPP/Windows/Shell.h @@ -0,0 +1,21 @@ +// Windows/Shell.h + +#ifndef __WINDOWS_SHELL_H +#define __WINDOWS_SHELL_H + +#include <windows.h> +// #include <shlobj.h> + +#include "Common/MyString.h" +#include "Windows/Defs.h" + + +namespace NWindows{ +namespace NShell{ + +bool BrowseForFolder(HWND owner, LPCWSTR title, LPCWSTR initialFolder, UString &resultPath); + +}} + + +#endif diff --git a/src/libs/7zip/unix/CPP/Windows/Synchronization.cpp b/src/libs/7zip/unix/CPP/Windows/Synchronization.cpp new file mode 100644 index 000000000..8130f9ac3 --- /dev/null +++ b/src/libs/7zip/unix/CPP/Windows/Synchronization.cpp @@ -0,0 +1,157 @@ +// Windows/Synchronization.cpp + +#include "StdAfx.h" + +#include "Synchronization.h" + +// #define TRACEN(u) u; +#define TRACEN(u) /* */ + +#define MAGIC 0x1234CAFE +class CSynchroTest +{ + int _magic; + public: + CSynchroTest() { + _magic = MAGIC; + } + void testConstructor() { + if (_magic != MAGIC) { + printf("ERROR : no constructors called during loading of plugins (please look at LINK_SHARED in makefile.machine)\n"); + exit(EXIT_FAILURE); + } + } +}; + +static CSynchroTest gbl_synchroTest; + +extern "C" void sync_TestConstructor(void) { + gbl_synchroTest.testConstructor(); +} + + +namespace NWindows { +namespace NSynchronization { + + +#ifndef ENV_BEOS +#ifdef DEBUG_SYNCHRO + void CSynchro::dump_error(int ligne,int ret,const char *text,void *param) + { + printf("\n##T%d#ERROR2 (l=%d) %s : param=%p ret = %d (%s)##\n",(int)pthread_self(),ligne,text,param,ret,strerror(ret)); + // abort(); + } + CSynchro::CSynchro() { + TRACEN((printf("\nT%d : E1-CSynchro(this=%p,m=%p,cond=%p)\n",(int)pthread_self(),(void *)this,(void *)&_object,(void *)&_cond))) + _isValid = false; + } + + void CSynchro::Create() { + TRACEN((printf("\nT%d : E1-CSynchro::Create(this=%p,m=%p,cond=%p)\n",(int)pthread_self(),(void *)this,(void *)&_object,(void *)&_cond))) + pthread_mutexattr_t mutexattr; + memset(&mutexattr,0,sizeof(mutexattr)); + int ret = pthread_mutexattr_init(&mutexattr); + if (ret != 0) { + dump_error(__LINE__,ret,"pthread_mutexattr_init",&mutexattr); + } + ret = pthread_mutexattr_settype(&mutexattr,PTHREAD_MUTEX_ERRORCHECK); + if (ret != 0) dump_error(__LINE__,ret,"pthread_mutexattr_settype",&mutexattr); + ret = ::pthread_mutex_init(&_object,&mutexattr); + if (ret != 0) dump_error(__LINE__,ret,"pthread_mutex_init",&_object); + ret = ::pthread_cond_init(&_cond,0); + if (ret != 0) dump_error(__LINE__,ret,"pthread_cond_init",&_cond); + TRACEN((printf("\nT%d : E2-CSynchro::Create(m=%p,cond=%p)\n",(int)pthread_self(),(void *)&_object,(void *)&_cond))) + } + CSynchro::~CSynchro() { + TRACEN((printf("\nT%d : E1-~CSynchro(this=%p,m=%p,cond=%p)\n",(int)pthread_self(),(void *)this,(void *)&_object,(void *)&_cond))) + if (_isValid) { + int ret = ::pthread_mutex_destroy(&_object); + if (ret != 0) dump_error(__LINE__,ret,"pthread_mutex_destroy",&_object); + ret = ::pthread_cond_destroy(&_cond); + if (ret != 0) dump_error(__LINE__,ret,"pthread_cond_destroy",&_cond); + TRACEN((printf("\nT%d : E2-~CSynchro(m=%p,cond=%p)\n",(int)pthread_self(),(void *)&_object,(void *)&_cond))) + } + _isValid = false; + } + void CSynchro::Enter() { + TRACEN((printf("\nT%d : E1-CSynchro::Enter(%p)\n",(int)pthread_self(),(void *)&_object))) + int ret = ::pthread_mutex_lock(&_object); + if (ret != 0) { + dump_error(__LINE__,ret,"CSynchro::Enter-pthread_mutex_lock",&_object); + } + TRACEN((printf("\nT%d : E2-CSynchro::Enter(%p)\n",(int)pthread_self(),(void *)&_object))) + } + void CSynchro::Leave() { + TRACEN((printf("\nT%d : E1-CSynchro::Leave(%p)\n",(int)pthread_self(),(void *)&_object))) + int ret = ::pthread_mutex_unlock(&_object); + if (ret != 0) dump_error(__LINE__,ret,"Leave::pthread_mutex_unlock",&_object); + TRACEN((printf("\nT%d : E2-CSynchro::Leave(%p)\n",(int)pthread_self(),(void *)&_object))) + } + void CSynchro::WaitCond() { + TRACEN((printf("\nT%d : E1-CSynchro::WaitCond(%p,%p)\n",(int)pthread_self(),(void *)&_cond,(void *)&_object))) + int ret = ::pthread_cond_wait(&_cond, &_object); + if (ret != 0) dump_error(__LINE__,ret,"pthread_cond_wait",&_cond); + TRACEN((printf("\nT%d : E2-CSynchro::WaitCond(%p,%p)\n",(int)pthread_self(),(void *)&_cond,(void *)&_object))) + } + void CSynchro::LeaveAndSignal() { + TRACEN((printf("\nT%d : E1-CSynchro::LeaveAndSignal(%p)\n",(int)pthread_self(),(void *)&_cond))) + int ret = ::pthread_cond_broadcast(&_cond); + if (ret != 0) dump_error(__LINE__,ret,"pthread_cond_broadcast",&_cond); + TRACEN((printf("\nT%d : E2-CSynchro::LeaveAndSignal(%p)\n",(int)pthread_self(),(void *)&_object))) + ret = ::pthread_mutex_unlock(&_object); + if (ret != 0) dump_error(__LINE__,ret,"LeaveAndSignal::pthread_mutex_unlock",&_object); + TRACEN((printf("\nT%d : E3-CSynchro::LeaveAndSignal(%p)\n",(int)pthread_self(),(void *)&_cond))) + } +#endif +#endif + +}} + +DWORD WINAPI WaitForMultipleObjects( DWORD count, const HANDLE *handles, BOOL wait_all, DWORD timeout ) +{ + TRACEN((printf("\nT%d : E1-WaitForMultipleObjects(%d)\n",(int)pthread_self(),(int)count))) + if (wait_all != FALSE) { + printf("\n\n INTERNAL ERROR - WaitForMultipleObjects(...) wait_all(%d) != FALSE\n\n",(unsigned)wait_all); + abort(); + } + + if (timeout != INFINITE) { + printf("\n\n INTERNAL ERROR - WaitForMultipleObjects(...) timeout(%u) != INFINITE\n\n",(unsigned)timeout); + abort(); + } + + if (count < 1) { + printf("\n\n INTERNAL ERROR - WaitForMultipleObjects(...) count(%u) < 1\n\n",(unsigned)count); + abort(); + } + + NWindows::NSynchronization::CSynchro *synchro = handles[0]->_sync; + + TRACEN((printf("\nT%d : E2-WaitForMultipleObjects(%d)\n",(int)pthread_self(),(int)count))) + synchro->Enter(); + TRACEN((printf("\nT%d : E3-WaitForMultipleObjects(%d)\n",(int)pthread_self(),(int)count))) + +#ifdef DEBUG_SYNCHRO + for(DWORD i=1;i<count;i++) { + if (synchro != handles[i]->_sync) { + printf("\n\n INTERNAL ERROR - WaitForMultipleObjects(...) synchro(%p) != handles[%d]->_sync(%p)\n\n", + synchro,(unsigned)i,handles[i]->_sync); + abort(); + } + } +#endif + + while(1) { + for(DWORD i=0;i<count;i++) { + if (handles[i]->IsSignaledAndUpdate()) { + synchro->Leave(); + TRACEN((printf("\nT%d : E4-WaitForMultipleObjects(%d)\n",(int)pthread_self(),(int)count))) + return WAIT_OBJECT_0+i; + } + } + synchro->WaitCond(); + } + synchro->Leave(); + return ETIMEDOUT; // WAIT_TIMEOUT; +} + diff --git a/src/libs/7zip/unix/CPP/Windows/Synchronization.h b/src/libs/7zip/unix/CPP/Windows/Synchronization.h new file mode 100644 index 000000000..df3c693a7 --- /dev/null +++ b/src/libs/7zip/unix/CPP/Windows/Synchronization.h @@ -0,0 +1,187 @@ +// Windows/Synchronization.h + +#ifndef __WINDOWS_SYNCHRONIZATION_H +#define __WINDOWS_SYNCHRONIZATION_H + +#include "Defs.h" + +extern "C" +{ +#include "../../C/Threads.h" +} + +#ifdef _WIN32 +#include "Handle.h" +#endif + +namespace NWindows { +namespace NSynchronization { + +class Uncopyable { +protected: + Uncopyable() {} // allow construction + ~Uncopyable() {} // and destruction of derived objects... +private: + Uncopyable(const Uncopyable&); // ...but prevent copying + Uncopyable& operator=(const Uncopyable&); +}; + + +class CBaseEvent // FIXME : private Uncopyable +{ +protected: + ::CEvent _object; +public: + bool IsCreated() { return Event_IsCreated(&_object) != 0; } +#ifdef _WIN32 + operator HANDLE() { return _object.handle; } +#endif + CBaseEvent() { Event_Construct(&_object); } + ~CBaseEvent() { Close(); } + WRes Close() { return Event_Close(&_object); } + #ifdef _WIN32 + WRes Create(bool manualReset, bool initiallyOwn, LPCTSTR name = NULL, + LPSECURITY_ATTRIBUTES securityAttributes = NULL) + { + _object.handle = ::CreateEvent(securityAttributes, BoolToBOOL(manualReset), + BoolToBOOL(initiallyOwn), name); + if (_object.handle != 0) + return 0; + return ::GetLastError(); + } + WRes Open(DWORD desiredAccess, bool inheritHandle, LPCTSTR name) + { + _object.handle = ::OpenEvent(desiredAccess, BoolToBOOL(inheritHandle), name); + if (_object.handle != 0) + return 0; + return ::GetLastError(); + } + #endif + + WRes Set() { return Event_Set(&_object); } + // bool Pulse() { return BOOLToBool(::PulseEvent(_handle)); } + WRes Reset() { return Event_Reset(&_object); } + WRes Lock() { return Event_Wait(&_object); } +}; + +class CManualResetEvent: public CBaseEvent +{ +public: + WRes Create(bool initiallyOwn = false) + { + return ManualResetEvent_Create(&_object, initiallyOwn ? 1: 0); + } + WRes CreateIfNotCreated() + { + if (IsCreated()) + return 0; + return ManualResetEvent_CreateNotSignaled(&_object); + } + #ifdef _WIN32 + WRes CreateWithName(bool initiallyOwn, LPCTSTR name) + { + return CBaseEvent::Create(true, initiallyOwn, name); + } + #endif +}; + +class CAutoResetEvent: public CBaseEvent +{ +public: + WRes Create() + { + return AutoResetEvent_CreateNotSignaled(&_object); + } + WRes CreateIfNotCreated() + { + if (IsCreated()) + return 0; + return AutoResetEvent_CreateNotSignaled(&_object); + } +}; + +#ifdef _WIN32 +class CObject: public CHandle +{ +public: + WRes Lock(DWORD timeoutInterval = INFINITE) + { return (::WaitForSingleObject(_handle, timeoutInterval) == WAIT_OBJECT_0 ? 0 : ::GetLastError()); } +}; +class CMutex: public CObject +{ +public: + WRes Create(bool initiallyOwn, LPCTSTR name = NULL, + LPSECURITY_ATTRIBUTES securityAttributes = NULL) + { + _handle = ::CreateMutex(securityAttributes, BoolToBOOL(initiallyOwn), name); + if (_handle != 0) + return 0; + return ::GetLastError(); + } + WRes Open(DWORD desiredAccess, bool inheritHandle, LPCTSTR name) + { + _handle = ::OpenMutex(desiredAccess, BoolToBOOL(inheritHandle), name); + if (_handle != 0) + return 0; + return ::GetLastError(); + } + WRes Release() + { + return ::ReleaseMutex(_handle) ? 0 : ::GetLastError(); + } +}; +class CMutexLock +{ + CMutex *_object; +public: + CMutexLock(CMutex &object): _object(&object) { _object->Lock(); } + ~CMutexLock() { _object->Release(); } +}; +#endif + +class CSemaphore : private Uncopyable +{ + ::CSemaphore _object; +public: + CSemaphore() { Semaphore_Construct(&_object); } + ~CSemaphore() { Close(); } + WRes Close() { return Semaphore_Close(&_object); } +#ifdef _WIN32 + operator HANDLE() { return _object.handle; } +#endif + WRes Create(UInt32 initiallyCount, UInt32 maxCount) + { + return Semaphore_Create(&_object, initiallyCount, maxCount); + } + WRes Release() { return Semaphore_Release1(&_object); } + WRes Release(UInt32 releaseCount) { return Semaphore_ReleaseN(&_object, releaseCount); } + WRes Lock() { return Semaphore_Wait(&_object); } +}; + +class CCriticalSection : private Uncopyable +{ + ::CCriticalSection _object; +public: + CCriticalSection() { CriticalSection_Init(&_object); } + ~CCriticalSection() { CriticalSection_Delete(&_object); } + void Enter() { CriticalSection_Enter(&_object); } + void Leave() { CriticalSection_Leave(&_object); } +}; + +class CCriticalSectionLock : private Uncopyable +{ + CCriticalSection *_object; + void Unlock() { _object->Leave(); } +public: + CCriticalSectionLock(CCriticalSection &object): _object(&object) {_object->Enter(); } + ~CCriticalSectionLock() { Unlock(); } +}; + +}} + +#ifndef _WIN32 +#include "Synchronization2.h" +#endif + +#endif + diff --git a/src/libs/7zip/unix/CPP/Windows/Synchronization2.h b/src/libs/7zip/unix/CPP/Windows/Synchronization2.h new file mode 100644 index 000000000..d86b49dee --- /dev/null +++ b/src/libs/7zip/unix/CPP/Windows/Synchronization2.h @@ -0,0 +1,218 @@ +// Windows/Synchronization.h + +#ifdef ENV_BEOS +#include <Locker.h> +#include <kernel/OS.h> +#include <list> +#endif + +/* Remark : WFMO = WaitForMultipleObjects */ + +namespace NWindows { namespace NSynchronization { struct CBaseHandleWFMO; } } + +typedef NWindows::NSynchronization::CBaseHandleWFMO *HANDLE; + +DWORD WINAPI WaitForMultipleObjects( DWORD count, const HANDLE *handles, BOOL wait_all, DWORD timeout ); + +namespace NWindows { +namespace NSynchronization { + +#ifdef ENV_BEOS +class CSynchro : BLocker, private Uncopyable +{ +#define MAX_THREAD 256 + thread_id _waiting[MAX_THREAD]; // std::list<thread_id> _waiting; + int index_waiting; +public: + CSynchro() { index_waiting = 0; } + void Create() { index_waiting = 0; } + ~CSynchro() {} + void Enter() { Lock(); } + void Leave() { Unlock(); } + void WaitCond() { + _waiting[index_waiting++] = find_thread(NULL); // _waiting.push_back(find_thread(NULL)); + thread_id sender; + Unlock(); + int msg = receive_data(&sender, NULL, 0); + Lock(); + } + void LeaveAndSignal() { + // Unlock(); + // Lock(); + // for (std::list<thread_id>::iterator index = _waiting.begin(); index != _waiting.end(); index++) + for(int index = 0 ; index < index_waiting ; index++) + { + send_data(_waiting[index], '7zCN', NULL, 0); + } + index_waiting = 0; // _waiting.clear(); + Unlock(); + } +}; +#else // #ifdef ENV_BEOS +#ifdef DEBUG_SYNCHRO +class CSynchro: private Uncopyable +{ + pthread_mutex_t _object; + pthread_cond_t _cond; + bool _isValid; + void dump_error(int ligne,int ret,const char *text,void *param); +public: + CSynchro(); + ~CSynchro(); + void Create(); + void Enter(); + void Leave(); + void WaitCond(); + void LeaveAndSignal(); +}; +#else // #ifdef DEBUG_SYNCHRO +class CSynchro : private Uncopyable +{ + pthread_mutex_t _object; + pthread_cond_t _cond; + bool _isValid; +public: + CSynchro() { _isValid = false; } + ~CSynchro() { + if (_isValid) { + ::pthread_mutex_destroy(&_object); + ::pthread_cond_destroy(&_cond); + } + _isValid = false; + } + void Create() { + ::pthread_mutex_init(&_object,0); + ::pthread_cond_init(&_cond,0); + } + void Enter() { + ::pthread_mutex_lock(&_object); + } + void Leave() { + ::pthread_mutex_unlock(&_object); + } + void WaitCond() { + ::pthread_cond_wait(&_cond, &_object); + } + void LeaveAndSignal() { + ::pthread_cond_broadcast(&_cond); + ::pthread_mutex_unlock(&_object); + } +}; +#endif // #ifdef DEBUG_SYNCHRO +#endif // #ifdef ENV_BEOS + +struct CBaseHandleWFMO // FIXME : private Uncopyable +{ + CSynchro *_sync; + + CBaseHandleWFMO() { } + + operator HANDLE() { return this; } + virtual bool IsSignaledAndUpdate() = 0; +}; + +class CBaseEventWFMO : public CBaseHandleWFMO +{ + bool _manual_reset; + bool _state; + +public: + + bool IsCreated() { return (this->_sync != 0); } + CBaseEventWFMO() { this->_sync = 0; } + ~CBaseEventWFMO() { Close(); } + + WRes Close() { this->_sync = 0; return S_OK; } + + WRes Create(CSynchro *sync,bool manualReset, bool initiallyOwn) + { + this->_sync = sync; + this->_manual_reset = manualReset; + this->_state = initiallyOwn; + return S_OK; + } + + WRes Set() { + this->_sync->Enter(); + this->_state = true; + this->_sync->LeaveAndSignal(); + return S_OK; + } + + WRes Reset() { + this->_sync->Enter(); + this->_state = false; + this->_sync->Leave(); + return S_OK; + } + virtual bool IsSignaledAndUpdate() { + if (this->_state == true) { + if (this->_manual_reset == false) this->_state = false; + return true; + } + return false; + } +}; + +class CManualResetEventWFMO: public CBaseEventWFMO +{ +public: + WRes Create(CSynchro *sync,bool initiallyOwn = false) { return CBaseEventWFMO::Create(sync,true, initiallyOwn); } +}; + +class CAutoResetEventWFMO: public CBaseEventWFMO +{ +public: + WRes Create(CSynchro *sync) { return CBaseEventWFMO::Create(sync,false, false); } + WRes CreateIfNotCreated(CSynchro *sync) + { + if (IsCreated()) + return 0; + return CBaseEventWFMO::Create(sync,false, false); + } +}; + +class CSemaphoreWFMO : public CBaseHandleWFMO +{ + LONG _count; + LONG _maxCount; + +public: + CSemaphoreWFMO() : _count(0), _maxCount(0) { this->_sync=0;} + WRes Create(CSynchro *sync,LONG initiallyCount, LONG maxCount) + { + if ((initiallyCount < 0) || (initiallyCount > maxCount) || (maxCount < 1)) return S_FALSE; + this->_sync = sync; + this->_count = initiallyCount; + this->_maxCount = maxCount; + return S_OK; + } + WRes Release(LONG releaseCount = 1) { + if (releaseCount < 1) return S_FALSE; + + this->_sync->Enter(); + LONG newCount = this->_count + releaseCount; + if (newCount > this->_maxCount) + { + this->_sync->Leave(); + return S_FALSE; + } + this->_count = newCount; + + this->_sync->LeaveAndSignal(); + + return S_OK; + } + WRes Close() { this->_sync=0; return S_OK; } + + virtual bool IsSignaledAndUpdate() { + if (this->_count > 0) { + this->_count--; + return true; + } + return false; + } +}; + +}} + diff --git a/src/libs/7zip/unix/CPP/Windows/System.cpp b/src/libs/7zip/unix/CPP/Windows/System.cpp new file mode 100644 index 000000000..b63ebec79 --- /dev/null +++ b/src/libs/7zip/unix/CPP/Windows/System.cpp @@ -0,0 +1,166 @@ +#include <stdio.h> +#include <stdlib.h> + +#if defined (__NetBSD__) || defined(__OpenBSD__) || defined (__FreeBSD__) || defined (__FreeBSD_kernel__) || defined (__APPLE__) +#include <sys/param.h> +#include <sys/sysctl.h> +#elif defined(__linux__) || defined(__CYGWIN__) || defined(sun) || defined(__NETWARE__) +#include <unistd.h> +#elif defined(hpux) || defined(__hpux) +#include <sys/param.h> +#include <sys/pstat.h> +#endif + +#if defined(__NETWARE__) +#include <sys/sysinfo.h> +#endif + +#if defined(ENV_BEOS) +#include <be/kernel/OS.h> +#endif + + +#include "Common/Types.h" + +namespace NWindows +{ + namespace NSystem + { + /************************ GetNumberOfProcessors ************************/ + + #if defined (__NetBSD__) || defined(__OpenBSD__) + UInt32 GetNumberOfProcessors() { + int mib[2], value; + int nbcpu = 1; + + mib[0] = CTL_HW; + mib[1] = HW_NCPU; + size_t len = sizeof(size_t); + if (sysctl(mib, 2, &value, &len, NULL, 0) >= 0) + if (value > nbcpu) + nbcpu = value; + return nbcpu; + } + #elif defined (__FreeBSD__) || defined (__FreeBSD_kernel__) + UInt32 GetNumberOfProcessors() { + int nbcpu = 1; + size_t value; + size_t len = sizeof(value); + if (sysctlbyname("hw.ncpu", &value, &len, NULL, 0) == 0) + nbcpu = value; + return nbcpu; + } + #elif defined (__APPLE__) + UInt32 GetNumberOfProcessors() { + int nbcpu = 1,value; + size_t valSize = sizeof(value); + if (sysctlbyname ("hw.ncpu", &value, &valSize, NULL, 0) == 0) + nbcpu = value; + return nbcpu; + } + + #elif defined(__linux__) || defined(__CYGWIN__) || defined(sun) + UInt32 GetNumberOfProcessors() { + int nbcpu = sysconf (_SC_NPROCESSORS_CONF); + if (nbcpu < 1) nbcpu = 1; + return nbcpu; + } + #elif defined(hpux) || defined(__hpux) + UInt32 GetNumberOfProcessors() { + struct pst_dynamic psd; + if (pstat_getdynamic(&psd, sizeof(psd), (size_t)1, 0) != -1) + return (UInt32)psd.psd_proc_cnt; + return 1; + } + #elif defined(__NETWARE__) + UInt32 GetNumberOfProcessors() { + // int nbcpu = get_nprocs_conf(); + int nbcpu = get_nprocs(); + if (nbcpu < 1) nbcpu = 1; + return nbcpu; + } + #elif defined(ENV_BEOS) + UInt32 GetNumberOfProcessors() { + system_info info; + get_system_info(&info); + int nbcpu = info.cpu_count; + if (nbcpu < 1) nbcpu = 1; + return nbcpu; + } + #else + #warning Generic GetNumberOfProcessors + UInt32 GetNumberOfProcessors() { + return 1; + } + #endif + + /************************ GetRamSize ************************/ + UInt64 GetRamSize() { + UInt64 ullTotalPhys = 128 * 1024 * 1024; // default : 128MB + +#ifdef linux + FILE * f = fopen( "/proc/meminfo", "r" ); + if (f) + { + char buffer[256]; + unsigned long total; + + ullTotalPhys = 0; + + while (fgets( buffer, sizeof(buffer), f )) + { + /* old style /proc/meminfo ... */ + if (sscanf( buffer, "Mem: %lu", &total)) + { + ullTotalPhys += total; + } + + /* new style /proc/meminfo ... */ + if (sscanf(buffer, "MemTotal: %lu", &total)) + ullTotalPhys = ((UInt64)total)*1024; + } + fclose( f ); + } +#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__APPLE__) +#ifdef HW_MEMSIZE + uint64_t val = 0; // support 2Gb+ RAM + int mib[2] = { CTL_HW, HW_MEMSIZE }; +#else // HW_MEMSIZE + unsigned int val = 0; // For old system + int mib[2] = { CTL_HW, HW_PHYSMEM }; +#endif // HW_MEMSIZE + size_t size_sys = sizeof(val); + + sysctl(mib, 2, &val, &size_sys, NULL, 0); + if (val) ullTotalPhys = val; +#elif defined(__CYGWIN__) + unsigned long pagesize=4096; // FIXME - sysconf(_SC_PAGESIZE) returns 65536 !? + // see http://readlist.com/lists/cygwin.com/cygwin/0/3313.html + unsigned long maxpages=sysconf(_SC_PHYS_PAGES); + ullTotalPhys = ((UInt64)pagesize)*maxpages; +#elif defined ( sun ) || defined(__NETWARE__) + unsigned long pagesize=sysconf(_SC_PAGESIZE); + unsigned long maxpages=sysconf(_SC_PHYS_PAGES); + ullTotalPhys = ((UInt64)pagesize)*maxpages; +#elif defined(hpux) || defined(__hpux) + struct pst_static pst; + union pstun pu; + + pu.pst_static = &pst; + if ( pstat( PSTAT_STATIC, pu, (size_t)sizeof(pst), (size_t)0, 0 ) != -1 ) { + ullTotalPhys = ((UInt64)pst.physical_memory)*pst.page_size; + } +#elif defined(ENV_BEOS) + system_info info; + get_system_info(&info); + ullTotalPhys = info.max_pages; + ullTotalPhys *= 4096; +#else +#warning Generic GetRamSize +#endif + return ullTotalPhys; + } + + } +} + diff --git a/src/libs/7zip/unix/CPP/Windows/System.h b/src/libs/7zip/unix/CPP/Windows/System.h new file mode 100644 index 000000000..e0067158f --- /dev/null +++ b/src/libs/7zip/unix/CPP/Windows/System.h @@ -0,0 +1,16 @@ +// Windows/System.h + +#ifndef __WINDOWS_SYSTEM_H +#define __WINDOWS_SYSTEM_H + +#include "../Common/Types.h" + +namespace NWindows { +namespace NSystem { + +UInt32 GetNumberOfProcessors(); +UInt64 GetRamSize(); + +}} + +#endif diff --git a/src/libs/7zip/unix/CPP/Windows/Thread.h b/src/libs/7zip/unix/CPP/Windows/Thread.h new file mode 100644 index 000000000..ed72507f4 --- /dev/null +++ b/src/libs/7zip/unix/CPP/Windows/Thread.h @@ -0,0 +1,41 @@ +// Windows/Thread.h + +#ifndef __WINDOWS_THREAD_H +#define __WINDOWS_THREAD_H + +#include "Defs.h" + +extern "C" +{ +#include "../../C/Threads.h" +} + +namespace NWindows { + +class CThread +{ + ::CThread thread; +public: + CThread() { Thread_Construct(&thread); } + ~CThread() { Close(); } + bool IsCreated() { return Thread_WasCreated(&thread) != 0; } + WRes Close() { return Thread_Close(&thread); } + WRes Create(THREAD_FUNC_RET_TYPE (THREAD_FUNC_CALL_TYPE *startAddress)(void *), LPVOID parameter) + { return Thread_Create(&thread, startAddress, parameter); } + WRes Wait() { return Thread_Wait(&thread); } + + #ifdef _WIN32 + operator HANDLE() { return thread; } + void Attach(HANDLE handle) { thread = handle; } + HANDLE Detach() { HANDLE h = thread; thread = NULL; return h; } + DWORD Resume() { return ::ResumeThread(thread); } + DWORD Suspend() { return ::SuspendThread(thread); } + bool Terminate(DWORD exitCode) { return BOOLToBool(::TerminateThread(thread, exitCode)); } + int GetPriority() { return ::GetThreadPriority(thread); } + bool SetPriority(int priority) { return BOOLToBool(::SetThreadPriority(thread, priority)); } + #endif +}; + +} + +#endif diff --git a/src/libs/7zip/unix/CPP/Windows/Time.cpp b/src/libs/7zip/unix/CPP/Windows/Time.cpp new file mode 100644 index 000000000..dfa0938b5 --- /dev/null +++ b/src/libs/7zip/unix/CPP/Windows/Time.cpp @@ -0,0 +1,88 @@ +// Windows/Time.cpp + +#include "StdAfx.h" + +#include "Time.h" +#include "Windows/Defs.h" + +namespace NWindows { +namespace NTime { + +static const UInt32 kFileTimeStartYear = 1601; + +bool DosTimeToFileTime(UInt32 dosTime, FILETIME &fileTime) +{ + return BOOLToBool(::DosDateTimeToFileTime((UInt16)(dosTime >> 16), (UInt16)(dosTime & 0xFFFF), &fileTime)); +} + +static const UInt32 kHighDosTime = 0xFF9FBF7D; +static const UInt32 kLowDosTime = 0x210000; + +bool FileTimeToDosTime(const FILETIME &fileTime, UInt32 &dosTime) +{ + WORD datePart, timePart; + if (!::FileTimeToDosDateTime(&fileTime, &datePart, &timePart)) + { + dosTime = (fileTime.dwHighDateTime >= 0x01C00000) ? kHighDosTime : kLowDosTime; + return false; + } + dosTime = (((UInt32)datePart) << 16) + timePart; + return true; +} + +static const UInt32 kNumTimeQuantumsInSecond = 10000000; +static const UInt64 kUnixTimeStartValue = ((UInt64)kNumTimeQuantumsInSecond) * 60 * 60 * 24 * 134774; + +void UnixTimeToFileTime(UInt32 unixTime, FILETIME &fileTime) +{ + UInt64 v = kUnixTimeStartValue + ((UInt64)unixTime) * kNumTimeQuantumsInSecond; + fileTime.dwLowDateTime = (DWORD)v; + fileTime.dwHighDateTime = (DWORD)(v >> 32); +} + +bool FileTimeToUnixTime(const FILETIME &fileTime, UInt32 &unixTime) +{ + UInt64 winTime = (((UInt64)fileTime.dwHighDateTime) << 32) + fileTime.dwLowDateTime; + if (winTime < kUnixTimeStartValue) + { + unixTime = 0; + return false; + } + winTime = (winTime - kUnixTimeStartValue) / kNumTimeQuantumsInSecond; + if (winTime > 0xFFFFFFFF) + { + unixTime = 0xFFFFFFFF; + return false; + } + unixTime = (UInt32)winTime; + return true; +} + +bool GetSecondsSince1601(unsigned year, unsigned month, unsigned day, + unsigned hour, unsigned min, unsigned sec, UInt64 &resSeconds) +{ + resSeconds = 0; + if (year < kFileTimeStartYear || year >= 10000 || month < 1 || month > 12 || + day < 1 || day > 31 || hour > 23 || min > 59 || sec > 59) + return false; + UInt32 numYears = year - kFileTimeStartYear; + UInt32 numDays = numYears * 365 + numYears / 4 - numYears / 100 + numYears / 400; + Byte ms[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; + if (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)) + ms[1] = 29; + month--; + for (unsigned i = 0; i < month; i++) + numDays += ms[i]; + numDays += day - 1; + resSeconds = ((UInt64)(numDays * 24 + hour) * 60 + min) * 60 + sec; + return true; +} + +void GetCurUtcFileTime(FILETIME &ft) +{ + SYSTEMTIME st; + GetSystemTime(&st); + SystemTimeToFileTime(&st, &ft); +} + +}} diff --git a/src/libs/7zip/unix/CPP/Windows/Time.h b/src/libs/7zip/unix/CPP/Windows/Time.h new file mode 100644 index 000000000..6f510b22b --- /dev/null +++ b/src/libs/7zip/unix/CPP/Windows/Time.h @@ -0,0 +1,21 @@ +// Windows/Time.h + +#ifndef __WINDOWS_TIME_H +#define __WINDOWS_TIME_H + +#include "Common/Types.h" + +namespace NWindows { +namespace NTime { + +bool DosTimeToFileTime(UInt32 dosTime, FILETIME &fileTime); +bool FileTimeToDosTime(const FILETIME &fileTime, UInt32 &dosTime); +void UnixTimeToFileTime(UInt32 unixTime, FILETIME &fileTime); +bool FileTimeToUnixTime(const FILETIME &fileTime, UInt32 &unixTime); +bool GetSecondsSince1601(unsigned year, unsigned month, unsigned day, + unsigned hour, unsigned min, unsigned sec, UInt64 &resSeconds); +void GetCurUtcFileTime(FILETIME &ft); + +}} + +#endif diff --git a/src/libs/7zip/unix/CPP/Windows/Window.cpp b/src/libs/7zip/unix/CPP/Windows/Window.cpp new file mode 100644 index 000000000..e92228c70 --- /dev/null +++ b/src/libs/7zip/unix/CPP/Windows/Window.cpp @@ -0,0 +1,101 @@ +// Windows/Window.cpp + +#include "StdAfx.h" + +// For compilers that support precompilation, includes "wx/wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ + #pragma hdrstop +#endif + +// for all others, include the necessary headers (this file is usually all you +// need because it includes almost all "standard" wxWidgets headers) +#ifndef WX_PRECOMP + #include "wx/wx.h" +#endif + +#undef _WIN32 + +#ifndef _UNICODE +#include "Common/StringConvert.h" +#endif +#include "Windows/Window.h" + +void verify_main_thread(void); + +class LockGUI +{ + bool _IsMain; + public: + LockGUI() { + verify_main_thread(); + + _IsMain = wxThread::IsMain(); + if (!_IsMain) { + printf("LockGUI-Windows\n"); + abort(); // FIXME wxMutexGuiEnter(); + } + } + ~LockGUI() { if (!_IsMain) wxMutexGuiLeave(); } +}; + +namespace NWindows { + +HWND GetDlgItem(HWND dialogWindow, int ControlID) +{ + LockGUI lock; + if (dialogWindow) return dialogWindow->FindWindow(ControlID); + return 0; +} + +void MySetWindowText(HWND wnd, LPCWSTR s) +{ + if (wnd == 0) return; + + LockGUI lock; + + wxString str = s; + /* + int id = wnd->GetId(); + if ( (id != wxID_OK) && (id != wxID_CANCEL) && (id != wxID_HELP) && (id != wxID_YES) && (id != wxID_NO)) + */ + { + wnd->SetLabel(str); + } +} + + bool CWindow::GetText(CSysString &s) + { + wxString str; + { + LockGUI lock; + str = _window->GetLabel(); + } + s = str; + return true; + } + + bool CWindow::IsEnabled() + { + LockGUI lock; + return _window->IsEnabled(); + } +} + +////////////////////////////////// Windows Compatibility +#include <sys/resource.h> + +void Sleep(unsigned millisec) +{ + wxMilliSleep(millisec); +} + +t_processID GetCurrentProcess(void) { + return getpid(); +} + +void SetPriorityClass(t_processID pid , int priority) { + setpriority(PRIO_PROCESS,pid,priority); +} + diff --git a/src/libs/7zip/unix/CPP/Windows/Window.h b/src/libs/7zip/unix/CPP/Windows/Window.h new file mode 100644 index 000000000..1970fe62d --- /dev/null +++ b/src/libs/7zip/unix/CPP/Windows/Window.h @@ -0,0 +1,43 @@ +// Windows/Window.h + +#ifndef __WINDOWS_WINDOW_H +#define __WINDOWS_WINDOW_H + +#include "Windows/Defs.h" +#include "Common/MyString.h" + +namespace NWindows { + +HWND GetDlgItem(HWND dialogWindow, int ControlID); +void MySetWindowText(HWND wnd, LPCWSTR s); + +class CWindow +{ +private: + // bool ModifyStyleBase(int styleOffset, DWORD remove, DWORD add, UINT flags); +protected: + HWND _window; +public: + CWindow(HWND newWindow = NULL): _window(newWindow){}; + CWindow& operator=(HWND newWindow) + { + _window = newWindow; + return *this; + } + operator HWND() const { return _window; } + void Attach(HWND newWindow) { _window = newWindow; } + HWND Detach() + { + HWND window = _window; + _window = NULL; + return window; + } + virtual void SetText(LPCWSTR s) { MySetWindowText(_window, s); } + virtual bool GetText(CSysString &s); + bool IsEnabled(); +}; + +} + +#endif + |