//////////////////////////////////////////////////////////////////////////////// // This source file is part of the ZipArchive library source distribution and // is Copyrighted 2000 - 2011 by Artpol Software - Tadeusz Dracz // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // For the licensing details refer to the License.txt file. // // Web Site: http://www.artpol-software.com //////////////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "ZipCompatibility.h" #include "ZipPlatform.h" #include "ZipException.h" #include "ZipAutoBuffer.h" #include "ZipFileHeader.h" #include "ZipArchive.h" // *********************** WINDOWS ************************** #ifndef _WIN32 #define FILE_ATTRIBUTE_READONLY 0x00000001 #define FILE_ATTRIBUTE_HIDDEN 0x00000002 #define FILE_ATTRIBUTE_SYSTEM 0x00000004 #define FILE_ATTRIBUTE_DIRECTORY 0x00000010 #define FILE_ATTRIBUTE_ARCHIVE 0x00000020 #endif // *********************** UINX ************************** #define USER_PERMISSIONS_MASK 0x01C0 #define EXTRACT_USER_PERMISSIONS(x) ((x & USER_PERMISSIONS_MASK) >> 6) #define CREATE_USER_PERMISSIONS(x) ((x & 0x0007) << 6) #define GROUP_PERMISSIONS_MASK 0x0038 #define EXTRACT_GROUP_PERMISSIONS(x) ((x & GROUP_PERMISSIONS_MASK) >> 3) #define CREATE_GROUP_PERMISSIONS(x) ((x & 0x0007) << 3) #define OTHER_PERMISSIONS_MASK 0x0007 #define EXTRACT_OTHER_PERMISSIONS(x) ((x & OTHER_PERMISSIONS_MASK)) #define CREATE_OTHER_PERMISSIONS(x) (x & 0x0007) #define UNIX_DIRECTORY_ATTRIBUTE 0x4000 #define UNIX_FILE_ATTRIBUTE 0x8000 #define UNIX_EXEC 1 #define UNIX_WRITE 2 #define UNIX_READ 4 using namespace ZipCompatibility; typedef DWORD(*conv_func)(DWORD , bool ); DWORD AttrDos(DWORD , bool ); DWORD AttrUnix(DWORD, bool); DWORD AttrMac(DWORD , bool ); conv_func conv_funcs[21] = {AttrDos, NULL, NULL, AttrUnix, NULL, NULL, AttrDos, AttrMac, NULL, NULL, NULL, AttrDos, NULL, NULL, NULL, AttrDos, NULL, NULL, NULL, NULL, AttrMac, }; DWORD ZipCompatibility::ConvertToSystem(DWORD uAttr, int iFromSystem, int iToSystem) { if (iToSystem != iFromSystem && iFromSystem < zcLast && iToSystem < zcLast) { conv_func p = conv_funcs[iFromSystem], q = conv_funcs[iToSystem]; if (p && q) uAttr = q( p(uAttr, true), false); else CZipException::Throw(CZipException::platfNotSupp); } return uAttr; } DWORD ZipCompatibility::GetAsInternalAttributes(DWORD uAttr, int iFromSystem) { if (iFromSystem < zcLast) { conv_func f = conv_funcs[iFromSystem]; if (!f) CZipException::Throw(CZipException::platfNotSupp); return f(uAttr, true); } return uAttr; } DWORD AttrDos(DWORD uAttr, bool ) { return uAttr; } DWORD AttrUnix(DWORD uAttr, bool bFrom) { DWORD uNewAttr = 0; if (bFrom) { bool isDir = (uAttr & UNIX_DIRECTORY_ATTRIBUTE) != 0; if (isDir) uNewAttr = attDir; DWORD uGroupAttr = EXTRACT_GROUP_PERMISSIONS(uAttr); DWORD uOtherAttr = EXTRACT_OTHER_PERMISSIONS(uAttr); uAttr = EXTRACT_USER_PERMISSIONS (uAttr); // we may set archive attribute if the file hasn't got the execute permissions // and is not a directory if (!isDir && !(uAttr & UNIX_EXEC)) uNewAttr |= attArch ; if (!(uAttr & UNIX_WRITE)) uNewAttr |= attROnly; if (!(uGroupAttr & UNIX_READ) && !(uOtherAttr & UNIX_READ)) uNewAttr |= attHidd; } else { uNewAttr = CREATE_USER_PERMISSIONS (UNIX_READ); // we cannot assume that if the file hasn't the archive attribute set // then it is executable and set execute permissions if (!(uAttr & attHidd)) uNewAttr |= (CREATE_OTHER_PERMISSIONS (UNIX_READ) | CREATE_GROUP_PERMISSIONS (UNIX_READ)); if (!(uAttr & attROnly)) uNewAttr |= (CREATE_GROUP_PERMISSIONS (UNIX_WRITE) | CREATE_USER_PERMISSIONS (UNIX_WRITE)); if (uAttr & attDir) { uNewAttr |= UNIX_DIRECTORY_ATTRIBUTE; uNewAttr |= (CREATE_OTHER_PERMISSIONS (UNIX_EXEC) | CREATE_GROUP_PERMISSIONS (UNIX_EXEC)) | CREATE_USER_PERMISSIONS (UNIX_EXEC); } else uNewAttr |= UNIX_FILE_ATTRIBUTE; } return uNewAttr; } DWORD AttrMac(DWORD uAttr, bool ) { return uAttr & (attDir | attROnly); } // ************************************************************************ ZIPINLINE bool ZipCompatibility::IsPlatformSupported(int iCode) { return iCode == zcDosFat || iCode == zcUnix || iCode == zcMacintosh || iCode == zcNtfs || iCode == zcOs2Hpfs || iCode == zcVfat || iCode == zcMacDarwin; } void ZipCompatibility::ConvertBufferToString(CZipString& szString, const CZipAutoBuffer& buffer, UINT uCodePage) { #ifdef _UNICODE ZipPlatform::MultiByteToWide(buffer, szString, uCodePage); #else // iLen does not include the NULL character int iLen; if (uCodePage == CP_OEMCP) { CZipAutoBuffer buf; buf = buffer; ZipPlatform::AnsiOem(buf, false); iLen = buf.GetSize(); memcpy(szString.GetBuffer(iLen), buf.GetBuffer(), iLen); } else { iLen = buffer.GetSize(); memcpy(szString.GetBuffer(iLen), buffer.GetBuffer(), iLen); } szString.ReleaseBuffer(iLen); #endif } void ZipCompatibility::ConvertStringToBuffer(LPCTSTR lpszString, CZipAutoBuffer& buffer, UINT uCodePage) { #ifdef _UNICODE ZipPlatform::WideToMultiByte(lpszString, buffer, uCodePage); #else int iLen = (int)strlen(lpszString); // iLen does not include the NULL character buffer.Allocate(iLen); memcpy(buffer, lpszString, (size_t)iLen); if (uCodePage == CP_OEMCP) ZipPlatform::AnsiOem(buffer, true); #endif } void ZipCompatibility::SlashBackslashChg(CZipString& szFileName, bool bReplaceSlash) { TCHAR t1 = _T('\\') /*backslash*/, t2 = _T('/'), c1, c2; if (bReplaceSlash) { c1 = t1; c2 = t2; } else { c1 = t2; c2 = t1; } szFileName.Replace(c2, c1); } void ZipCompatibility::NormalizePathSeparators(CZipString& szFileName) { int iPlatform = ZipPlatform::GetSystemID(); ZipCompatibility::SlashBackslashChg(szFileName, iPlatform == ZipCompatibility::zcDosFat || iPlatform == ZipCompatibility::zcNtfs); } UINT ZipCompatibility::GetDefaultNameCodePage(int iPlatform) { if (iPlatform == ZipCompatibility::zcDosFat || iPlatform == ZipCompatibility::zcNtfs) return CP_OEMCP; else if (iPlatform == ZipCompatibility::zcUnix || iPlatform == ZipCompatibility::zcMacintosh || iPlatform == zcMacDarwin) return CP_UTF8; else return CP_ACP; } UINT ZipCompatibility::GetDefaultNameCodePage() { return GetDefaultNameCodePage(ZipPlatform::GetSystemID()); } UINT ZipCompatibility::GetDefaultCommentCodePage(int iPlatform) { if (iPlatform == ZipCompatibility::zcUnix || iPlatform == ZipCompatibility::zcMacintosh || iPlatform == zcMacDarwin) return CP_UTF8; else return CP_ACP; } UINT ZipCompatibility::GetDefaultPasswordCodePage(int iPlatform) { if (iPlatform == ZipCompatibility::zcUnix || iPlatform == ZipCompatibility::zcMacintosh || iPlatform == zcMacDarwin) return CP_UTF8; else return CP_ACP; } UINT ZipCompatibility::GetDefaultCommentCodePage() { return GetDefaultCommentCodePage(ZipPlatform::GetSystemID()); }