├── .circleci └── config.yml ├── .github ├── CONTRIBUTING.md ├── ISSUE_TEMPLATE.MD └── PULL_REQUEST_TEMPLATE.md ├── .gitignore ├── .travis.yml ├── CHANGELOG.md ├── Classes ├── Categories │ ├── NSString+UnrarKit.h │ └── NSString+UnrarKit.mm ├── URKArchive.h ├── URKArchive.mm ├── URKFileInfo.h ├── URKFileInfo.m ├── UnrarKit.h └── UnrarKitMacros.h ├── Example ├── .gitignore ├── Classes │ ├── UnrarExampleAppDelegate.h │ ├── UnrarExampleAppDelegate.m │ ├── UnrarExampleViewController.h │ └── UnrarExampleViewController.m ├── Default-568h@2x.png ├── MainWindow.xib ├── UnrarExample-Info.plist ├── UnrarExample.xcodeproj │ ├── .gitignore │ ├── project.pbxproj │ ├── project.xcworkspace │ │ └── contents.xcworkspacedata │ └── xcshareddata │ │ └── xcschemes │ │ └── UnrarExample.xcscheme ├── UnrarExampleViewController.xib ├── UnrarExample_Prefix.pch ├── main.m └── makeLargeArchive.sh ├── LICENSE ├── Libraries └── unrar │ ├── acknow.txt │ ├── arccmt.cpp │ ├── archive.cpp │ ├── archive.hpp │ ├── arcread.cpp │ ├── array.hpp │ ├── blake2s.cpp │ ├── blake2s.hpp │ ├── blake2s_sse.cpp │ ├── blake2sp.cpp │ ├── cmddata.cpp │ ├── cmddata.hpp │ ├── cmdfilter.cpp │ ├── cmdmix.cpp │ ├── coder.cpp │ ├── coder.hpp │ ├── compress.hpp │ ├── consio.cpp │ ├── consio.hpp │ ├── crc.cpp │ ├── crc.hpp │ ├── crypt.cpp │ ├── crypt.hpp │ ├── crypt1.cpp │ ├── crypt2.cpp │ ├── crypt3.cpp │ ├── crypt5.cpp │ ├── dll.cpp │ ├── dll.def │ ├── dll.hpp │ ├── dll.rc │ ├── dll_nocrypt.def │ ├── encname.cpp │ ├── encname.hpp │ ├── errhnd.cpp │ ├── errhnd.hpp │ ├── extinfo.cpp │ ├── extinfo.hpp │ ├── extract.cpp │ ├── extract.hpp │ ├── filcreat.cpp │ ├── filcreat.hpp │ ├── file.cpp │ ├── file.hpp │ ├── filefn.cpp │ ├── filefn.hpp │ ├── filestr.cpp │ ├── filestr.hpp │ ├── find.cpp │ ├── find.hpp │ ├── getbits.cpp │ ├── getbits.hpp │ ├── global.cpp │ ├── global.hpp │ ├── hardlinks.cpp │ ├── hash.cpp │ ├── hash.hpp │ ├── headers.cpp │ ├── headers.hpp │ ├── headers5.hpp │ ├── isnt.cpp │ ├── isnt.hpp │ ├── license.txt │ ├── list.cpp │ ├── list.hpp │ ├── loclang.hpp │ ├── log.cpp │ ├── log.hpp │ ├── makefile │ ├── match.cpp │ ├── match.hpp │ ├── model.cpp │ ├── model.hpp │ ├── options.cpp │ ├── options.hpp │ ├── os.hpp │ ├── pathfn.cpp │ ├── pathfn.hpp │ ├── qopen.cpp │ ├── qopen.hpp │ ├── rar.cpp │ ├── rar.hpp │ ├── rardefs.hpp │ ├── rarlang.hpp │ ├── raros.hpp │ ├── rarpch.cpp │ ├── rartypes.hpp │ ├── rarvm.cpp │ ├── rarvm.hpp │ ├── rawint.hpp │ ├── rawread.cpp │ ├── rawread.hpp │ ├── rdwrfn.cpp │ ├── rdwrfn.hpp │ ├── readme.txt │ ├── recvol.cpp │ ├── recvol.hpp │ ├── recvol3.cpp │ ├── recvol5.cpp │ ├── resource.cpp │ ├── resource.hpp │ ├── rijndael.cpp │ ├── rijndael.hpp │ ├── rs.cpp │ ├── rs.hpp │ ├── rs16.cpp │ ├── rs16.hpp │ ├── scantree.cpp │ ├── scantree.hpp │ ├── secpassword.cpp │ ├── secpassword.hpp │ ├── sha1.cpp │ ├── sha1.hpp │ ├── sha256.cpp │ ├── sha256.hpp │ ├── smallfn.cpp │ ├── smallfn.hpp │ ├── strfn.cpp │ ├── strfn.hpp │ ├── strlist.cpp │ ├── strlist.hpp │ ├── suballoc.cpp │ ├── suballoc.hpp │ ├── system.cpp │ ├── system.hpp │ ├── threadmisc.cpp │ ├── threadpool.cpp │ ├── threadpool.hpp │ ├── timefn.cpp │ ├── timefn.hpp │ ├── ui.cpp │ ├── ui.hpp │ ├── uicommon.cpp │ ├── uiconsole.cpp │ ├── uisilent.cpp │ ├── ulinks.cpp │ ├── unicode.cpp │ ├── unicode.hpp │ ├── unpack.cpp │ ├── unpack.hpp │ ├── unpack15.cpp │ ├── unpack20.cpp │ ├── unpack30.cpp │ ├── unpack50.cpp │ ├── unpack50frag.cpp │ ├── unpack50mt.cpp │ ├── unpackinline.cpp │ ├── uowners.cpp │ ├── version.hpp │ ├── volume.cpp │ ├── volume.hpp │ ├── win32acl.cpp │ ├── win32lnk.cpp │ └── win32stm.cpp ├── README.md ├── Resources ├── UnrarKit-Info.plist ├── UnrarKitResources-Info.plist └── en.lproj │ └── UnrarKit.strings ├── Scripts ├── add-github-release.py ├── archive-carthage.sh ├── carthage-validate.sh ├── cocoapod-validate.sh ├── get-release-notes.py ├── localize.sh ├── push-output.sh └── set-version.sh ├── Tests ├── CheckDataTests.m ├── ExtractBufferedDataTests.m ├── ExtractDataTests.m ├── ExtractFilesTests.m ├── FirstVolumeTests.m ├── HasMultipleVolumesTests.m ├── IsPasswordProtectedTests.m ├── IterateFileInfoTests.m ├── ListFileInfoTests.m ├── ListFilenamesTests.m ├── ListVolumesTests.m ├── PerformOnDataTests.m ├── PerformOnFilesTests.m ├── ProgressReportingTests.m ├── Test Data │ ├── Folder Archive.rar │ ├── Good CRC Archive.rar │ ├── Modified CRC Archive.rar │ ├── README.md │ ├── Test Archive (Header Password).rar │ ├── Test Archive (Password).rar │ ├── Test Archive (RAR5).rar │ ├── Test Archive (RAR5, Password).rar │ ├── Test Archive.rar │ ├── Test File A.txt │ ├── Test File B.jpg │ ├── Test File C.m4a │ ├── Test File Ⓐ.txt │ ├── Test File Ⓑ.jpg │ ├── Test File Ⓒ.m4a │ ├── bin │ │ ├── arm │ │ │ ├── license.txt │ │ │ └── rar │ │ └── x64 │ │ │ ├── license.txt │ │ │ └── rar │ └── Ⓣest Ⓐrchive.rar ├── URKArchiveTestCase.h ├── URKArchiveTestCase.m ├── URKArchiveTestCase.swift ├── URKArchiveTests.m ├── UnrarKit Tests-Bridging-Header.h ├── UnrarKit Tests-Info.plist ├── ValidatePasswordTests.m └── en.lproj │ └── InfoPlist.strings ├── UnrarKit.podspec ├── UnrarKit.xcodeproj ├── .gitignore ├── project.pbxproj ├── project.xcworkspace │ └── contents.xcworkspacedata └── xcshareddata │ └── xcschemes │ └── UnrarKit.xcscheme ├── UnrarKit.xcworkspace ├── contents.xcworkspacedata └── xcshareddata │ ├── IDEWorkspaceChecks.plist │ └── WorkspaceSettings.xcsettings └── beta-notes.md /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | version: 2.1 2 | 3 | executors: 4 | my-xcode: 5 | macos: 6 | xcode: 13.2.1 7 | 8 | workflows: 9 | version: 2 10 | test-validate-release: 11 | jobs: 12 | # Testing 13 | - test-Mac 14 | - test-iOS 15 | - test-ExampleApp 16 | 17 | # Validation 18 | - validate-CocoaPods: 19 | requires: 20 | - test-Mac 21 | - test-iOS 22 | - test-ExampleApp 23 | - validate-Carthage: 24 | requires: 25 | - test-Mac 26 | - test-iOS 27 | - test-ExampleApp 28 | 29 | # Release 30 | # - release: 31 | # # Only run for tags 32 | # filters: 33 | # branches: 34 | # ignore: /.*/ 35 | # tags: 36 | # only: /.*/ 37 | # requires: 38 | # - validate-CocoaPods 39 | # - validate-Carthage 40 | 41 | jobs: 42 | test-Mac: 43 | executor: my-xcode 44 | steps: 45 | - checkout 46 | # The CLANG arguments and find command fail the build on analyzer errors 47 | - run: xcodebuild -workspace UnrarKit.xcworkspace -scheme UnrarKit -sdk macosx -configuration Release -quiet analyze test CLANG_ANALYZER_OUTPUT=html CLANG_ANALYZER_OUTPUT_DIR=analyzer-output && [[ -z `find analyzer-output -name "*.html"` ]] 48 | 49 | test-iOS: 50 | executor: my-xcode 51 | steps: 52 | - checkout 53 | # The CLANG arguments and find command fail the build on analyzer errors 54 | - run: xcodebuild -workspace UnrarKit.xcworkspace -scheme UnrarKit -destination 'platform=iOS Simulator,name=iPhone 11,OS=latest' -configuration Release analyze test CLANG_ANALYZER_OUTPUT=html CLANG_ANALYZER_OUTPUT_DIR=analyzer-output && [[ -z `find analyzer-output -name "*.html"` ]] 55 | 56 | test-ExampleApp: 57 | executor: my-xcode 58 | steps: 59 | - checkout 60 | # The CLANG arguments and find command fail the build on analyzer errors 61 | - run: xcodebuild -workspace UnrarKit.xcworkspace -scheme UnrarExample -sdk iphonesimulator -configuration Release analyze CLANG_ANALYZER_OUTPUT=html CLANG_ANALYZER_OUTPUT_DIR=analyzer-output && [[ -z `find analyzer-output -name "*.html"` ]] 62 | 63 | validate-CocoaPods: 64 | executor: my-xcode 65 | steps: 66 | - checkout 67 | - run: ./Scripts/cocoapod-validate.sh 68 | 69 | validate-Carthage: 70 | executor: my-xcode 71 | steps: 72 | - checkout 73 | - run: ./Scripts/carthage-validate.sh 74 | 75 | # release: 76 | # executor: my-xcode 77 | # steps: 78 | # - checkout 79 | # - run: ./Scripts/push-output.sh 80 | -------------------------------------------------------------------------------- /.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to UnrarKit 2 | 3 | First of all, if you're reading this, thanks! I love getting feedback from other developers who use this library and welcome any and all feedback. Issues and Pull requests are welcome, with a few guidelines, laid out below. 4 | 5 | # Issues 6 | 7 | I need the following, at a minimum: 8 | 9 | 1. The steps to reproduce your issue, detailed enough for me to follow along and see what you're seeing (bonus points for giving me a sample archive that demonstrates the issue) 10 | 2. What you expect to happen 11 | 3. What actually happened 12 | 13 | If what you're reporting is a crash, a crash report is key (or a stack trace, if you don't have a full crash report). 14 | 15 | Beyond that, the **quickest way** to get me to address what you're asking for is to provide a unit test (or tests) to demonstrate what you'd like to see (they should probably fail). I have a pretty complete set of tests already in the library that you can use as an example if you'd like. 16 | 17 | # Pull Requests 18 | 19 | Pull Requests are always greatly appreciated. The general rule of thumb for how quickly something will make it into a future release is the inverse of how much work I'll need to do on it. Creating a PR instead of an issue report takes a huge burden off of me. If you do create a PR, I'll require these things before I merge it: 20 | 21 | 1. Style needs to mesh with the rest of the repo. I'd love to have some style enforcement checks at some point, but don't yet. Do your best according to what you see in the rest of the source and I'll point out anything you missed. No big deal 22 | 2. If you're fixing a bug, I need to see a unit test that reproduces the issue(s) by failing if I comment out your fix. I try to maintain code coverage that's as complete as possible, so more unit tests are always welcome 23 | 3. Don't touch the `Libraries/unrar` directory. This is the UnRAR source code, downloaded from [the RARLAB site](https://www.rarlab.com/rar_add.htm), and updated occasionally. You can usually look at the revision history of that folder to see what version it's currently on. This library does cause some compiler warnings, but I ignore them in Xcode and CocoaPods, relying on unit tests to tell me if anything is truly broken, since I don't maintain patches - I expect to be able to drop in newer versions as needed 24 | 4. Be patient with the process - I maintain a high attention to detail, and will take however much time is necessary to get the change to where I'd like it. If you'd rather have a more brief back-and-forth, I can always pull into a separate branch to make the changes myself before merging, but enjoy the interaction of collaborating on PRs whenever possible -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.MD: -------------------------------------------------------------------------------- 1 | Thanks for making a contribution to UnrarKit! I greatly value issue reports, which help make the library better, and more useful to more people. To help me address your issue, please follow the steps below. 2 | 3 | _Delete from this line up_ 4 | 5 | - [ ] Provide a brief, descriptive issue title 6 | - [ ] Fill out the template below 7 | - [ ] **Option A** is the easier, more traditional way of reporting a bug 8 | - [ ] **Option B** gets you bonus points (redeemable in the form of me looking at your issue more quickly). Create a failing unit test that would pass if the issue were resolved. When I go to fix your issue, it's one of the first things I would do anyway. There is a pretty complete set already there, so you can use those as a guide to creating new ones. 9 | 10 | ## Option A 11 | 12 | ### Steps to reproduce issue (Detailed enough for me to reproduce - attaching a sample archive can be very helpful): 13 | 14 | 15 | ### What you expect to happen: 16 | 17 | 18 | ### What actually happened: 19 | 20 | 21 | ### (_Optional_) A stack trace or crash report, if you have one: 22 | 23 | 24 | ## Option B 25 | 26 | ### Brief summary of issue: 27 | 28 | ### Link to your branch where you've created automated tests to demonstrate the issue (and the name of the unit test(s) you created): -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | Fixes # _Please mention here if this PR addresses an existing issue_ 2 | 3 | Summary: 4 | * List the high-level description of each change here, in order of significance 5 | 6 | Checklist: 7 | - [ ] Don't make changes to the repo that aren't necessary for the changes described above (e.g. style/formatting changes) 8 | - [ ] Make an update to [CHANGELOG.md](CHANGELOG.md) with a quick overview of your change under the version whose branch you're merging into. This should also include a reference to your username/profile and any issues you're addressing, with this PR # (_once submitted obviously, chicken/egg and all that_) 9 | - [ ] I use continuous integration with Circle and/or Travis CI, and any of those builds run must be passing. Ask for help if you need guidance figuring out why they're failing 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | .DS_Store 3 | 4 | CarthageValidation 5 | analyzer-output 6 | 7 | **/*.xccheckout 8 | **/xcuserdata/* 9 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: objective-c 2 | osx_image: xcode13.2 3 | 4 | branches: 5 | except: 6 | - circle-ci 7 | 8 | before_script: 9 | - pod --version 10 | # Make log level less verbose. Temporarily undo if more info is needed 11 | - sudo log config --mode "level:default" 12 | 13 | matrix: 14 | include: 15 | - stage: Test 16 | env: Name=Mac 17 | # The CLANG arguments and find command fail the build on analyzer errors 18 | script: xcodebuild -workspace UnrarKit.xcworkspace -scheme UnrarKit -sdk macosx -configuration Release -quiet analyze test CLANG_ANALYZER_OUTPUT=html CLANG_ANALYZER_OUTPUT_DIR=analyzer-output && [[ -z `find analyzer-output -name "*.html"` ]] 19 | 20 | - stage: Test 21 | env: Name=iOS 22 | # The CLANG arguments and find command fail the build on analyzer errors 23 | script: xcodebuild -workspace UnrarKit.xcworkspace -scheme UnrarKit -destination 'platform=iOS Simulator,name=iPhone 11,OS=latest' -configuration Release analyze test CLANG_ANALYZER_OUTPUT=html CLANG_ANALYZER_OUTPUT_DIR=analyzer-output && [[ -z `find analyzer-output -name "*.html"` ]] 24 | 25 | - stage: Test 26 | env: Name=ExampleAppBuild 27 | # The CLANG arguments and find command fail the build on analyzer errors 28 | script: xcodebuild -workspace UnrarKit.xcworkspace -scheme UnrarExample -sdk iphonesimulator -configuration Release analyze CLANG_ANALYZER_OUTPUT=html CLANG_ANALYZER_OUTPUT_DIR=analyzer-output && [[ -z `find analyzer-output -name "*.html"` ]] 29 | 30 | - stage: Validate 31 | env: Name=CocoaPods 32 | script: ./Scripts/cocoapod-validate.sh 33 | 34 | - stage: Validate 35 | env: Name=Carthage 36 | script: ./Scripts/carthage-validate.sh 37 | 38 | - stage: Release 39 | if: tag IS present 40 | script: ./Scripts/push-output.sh 41 | -------------------------------------------------------------------------------- /Classes/Categories/NSString+UnrarKit.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+UnrarKit.h 3 | // UnrarKit 4 | // 5 | // 6 | 7 | #import 8 | 9 | @interface NSString (UnrarKit) 10 | 11 | + (instancetype)stringWithUnichars:(wchar_t *)unichars; 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Classes/Categories/NSString+UnrarKit.mm: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+UnrarKit.m 3 | // UnrarKit 4 | // 5 | // 6 | 7 | #import "NSString+UnrarKit.h" 8 | #import "UnrarKitMacros.h" 9 | 10 | RarHppIgnore 11 | #import "rar.hpp" 12 | #pragma clang diagnostic pop 13 | 14 | @implementation NSString (UnrarKit) 15 | 16 | + (instancetype)stringWithUnichars:(wchar_t *)unichars { 17 | return [[NSString alloc] initWithBytes:unichars 18 | length:wcslen(unichars) * sizeof(*unichars) 19 | encoding:NSUTF32LittleEndianStringEncoding]; 20 | } 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /Classes/URKFileInfo.h: -------------------------------------------------------------------------------- 1 | // 2 | // URKFileInfo.h 3 | // UnrarKit 4 | // 5 | 6 | #import 7 | #import 8 | 9 | RarosHppIgnore 10 | #import 11 | #pragma clang diagnostic pop 12 | 13 | DllHppIgnore 14 | #import 15 | #pragma clang diagnostic pop 16 | 17 | /* See http://www.forensicswiki.org/wiki/RAR and 18 | http://www.rarlab.com/technote.htm#filehead for 19 | more information about the RAR File Header spec */ 20 | 21 | /** 22 | * Defines the packing methods that can be used on a file in an archive 23 | */ 24 | typedef NS_ENUM(NSUInteger, URKCompressionMethod) { 25 | 26 | /** 27 | * No compression is used 28 | */ 29 | URKCompressionMethodStorage = 0x30, 30 | 31 | /** 32 | * Fastest compression 33 | */ 34 | URKCompressionMethodFastest = 0x31, 35 | 36 | /** 37 | * Fast compression 38 | */ 39 | URKCompressionMethodFast = 0x32, 40 | 41 | /** 42 | * Normal compression 43 | */ 44 | URKCompressionMethodNormal = 0x33, 45 | 46 | /** 47 | * Good compression 48 | */ 49 | URKCompressionMethodGood = 0x34, 50 | 51 | /** 52 | * Best compression 53 | */ 54 | URKCompressionMethodBest = 0x35, 55 | }; 56 | 57 | /** 58 | * Defines the various operating systems that can be used when archiving 59 | */ 60 | typedef NS_ENUM(NSUInteger, URKHostOS) { 61 | 62 | /** 63 | * MS-DOS 64 | */ 65 | URKHostOSMSDOS = 0, 66 | 67 | /** 68 | * OS/2 69 | */ 70 | URKHostOSOS2 = 1, 71 | 72 | /** 73 | * Windows 74 | */ 75 | URKHostOSWindows = 2, 76 | 77 | /** 78 | * Unix 79 | */ 80 | URKHostOSUnix = 3, 81 | 82 | /** 83 | * Mac OS 84 | */ 85 | URKHostOSMacOS = 4, 86 | 87 | /** 88 | * BeOS 89 | */ 90 | URKHostOSBeOS = 5, 91 | }; 92 | 93 | /** 94 | * A wrapper around a RAR archive's file header, defining the various fields 95 | * it contains 96 | */ 97 | @interface URKFileInfo : NSObject 98 | 99 | /** 100 | * The name of the file's archive 101 | */ 102 | @property (readonly, strong) NSString *archiveName; 103 | 104 | /** 105 | * The name of the file 106 | */ 107 | @property (readonly, strong) NSString *filename; 108 | 109 | /** 110 | * The timestamp of the file 111 | */ 112 | @property (readonly, strong) NSDate *timestamp; 113 | 114 | /** 115 | * The CRC checksum of the file 116 | */ 117 | @property (readonly, assign) NSUInteger CRC; 118 | 119 | /** 120 | * Size of the uncompressed file 121 | */ 122 | @property (readonly, assign) long long uncompressedSize; 123 | 124 | /** 125 | * Size of the compressed file 126 | */ 127 | @property (readonly, assign) long long compressedSize; 128 | 129 | /** 130 | * YES if the file will be continued of the next volume 131 | */ 132 | @property (readonly) BOOL isEncryptedWithPassword; 133 | 134 | /** 135 | * YES if the file is a directory 136 | */ 137 | @property (readonly) BOOL isDirectory; 138 | 139 | /** 140 | * The type of compression 141 | */ 142 | @property (readonly, assign) URKCompressionMethod compressionMethod; 143 | 144 | /** 145 | * The OS of the file 146 | */ 147 | @property (readonly, assign) URKHostOS hostOS; 148 | 149 | /** 150 | * Returns a URKFileInfo instance for the given extended header data 151 | * 152 | * @param fileHeader The header data for a RAR file 153 | * 154 | * @return an instance of URKFileInfo 155 | */ 156 | + (instancetype) fileInfo:(struct RARHeaderDataEx *)fileHeader; 157 | 158 | @end 159 | -------------------------------------------------------------------------------- /Classes/URKFileInfo.m: -------------------------------------------------------------------------------- 1 | // 2 | // URKFileInfo.m 3 | // UnrarKit 4 | // 5 | 6 | #import "URKFileInfo.h" 7 | #import "UnrarKitMacros.h" 8 | 9 | #import "NSString+UnrarKit.h" 10 | 11 | @implementation URKFileInfo 12 | 13 | 14 | 15 | #pragma mark - Initialization 16 | 17 | 18 | + (instancetype) fileInfo:(struct RARHeaderDataEx *)fileHeader { 19 | return [[URKFileInfo alloc] initWithFileHeader:fileHeader]; 20 | } 21 | 22 | - (instancetype)initWithFileHeader:(struct RARHeaderDataEx *)fileHeader 23 | { 24 | URKCreateActivity("Init URKFileInfo"); 25 | 26 | if ((self = [super init])) { 27 | URKLogDebug("Setting file info fields"); 28 | 29 | _filename = [NSString stringWithUnichars:fileHeader->FileNameW]; 30 | _archiveName = [NSString stringWithUnichars:fileHeader->ArcNameW]; 31 | _uncompressedSize = (long long) fileHeader->UnpSizeHigh << 32 | fileHeader->UnpSize; 32 | _compressedSize = (long long) fileHeader->PackSizeHigh << 32 | fileHeader->PackSize; 33 | _compressionMethod = fileHeader->Method; 34 | _hostOS = fileHeader->HostOS; 35 | _timestamp = [self parseDOSDate:fileHeader->FileTime]; 36 | _CRC = fileHeader->FileCRC; 37 | 38 | //_fileContinuedFromPreviousVolume = fileHeader->Flags & (1 << 0) 39 | //_fileContinuedOnNextVolume = fileHeader->Flags & (1 << 1) 40 | _isEncryptedWithPassword = fileHeader->Flags & (1 << 2); 41 | //_fileHasComment = fileHeader->Flags & (1 << 3) 42 | 43 | _isDirectory = (fileHeader->Flags & RHDF_DIRECTORY) ? YES : NO; 44 | } 45 | 46 | return self; 47 | } 48 | 49 | 50 | 51 | #pragma mark - Private Methods 52 | 53 | 54 | - (NSDate *)parseDOSDate:(NSUInteger)dosTime 55 | { 56 | URKCreateActivity("-parseDOSDate:"); 57 | 58 | if (dosTime == 0) { 59 | URKLogDebug("DOS Time == 0"); 60 | return nil; 61 | } 62 | 63 | // MSDOS Date Format Parsing specified at this URL: 64 | // http://www.cocoanetics.com/2012/02/decompressing-files-into-memory/ 65 | 66 | int year = ((dosTime>>25) & 127) + 1980; // 7 bits 67 | int month = (dosTime>>21) & 15; // 4 bits 68 | int day = (dosTime>>16) & 31; // 5 bits 69 | int hour = (dosTime>>11) & 31; // 5 bits 70 | int minute = (dosTime>>5) & 63; // 6 bits 71 | int second = (dosTime & 31) * 2; // 5 bits 72 | 73 | NSDateComponents *components = [[NSDateComponents alloc] init]; 74 | components.year = year; 75 | components.month = month; 76 | components.day = day; 77 | components.hour = hour; 78 | components.minute = minute; 79 | components.second = second; 80 | 81 | return [[NSCalendar currentCalendar] dateFromComponents:components]; 82 | } 83 | 84 | @end 85 | -------------------------------------------------------------------------------- /Classes/UnrarKit.h: -------------------------------------------------------------------------------- 1 | // 2 | // UnrarKit.h 3 | // UnrarKit 4 | // 5 | // Created by Dov Frankel on 1/9/2015. 6 | // Copyright (c) 2015 Abbey Code. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for UnrarKit. 12 | FOUNDATION_EXPORT double UnrarKitVersionNumber; 13 | 14 | //! Project version string for UnrarKit. 15 | FOUNDATION_EXPORT const unsigned char UnrarKitVersionString[]; 16 | 17 | 18 | #import 19 | #import 20 | -------------------------------------------------------------------------------- /Example/.gitignore: -------------------------------------------------------------------------------- 1 | /*.DS_Store 2 | -------------------------------------------------------------------------------- /Example/Classes/UnrarExampleAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // UnrarExampleAppDelegate.h 3 | // UnrarExample 4 | // 5 | // 6 | 7 | #import 8 | 9 | @class UnrarExampleViewController; 10 | 11 | @interface UnrarExampleAppDelegate : NSObject 12 | 13 | @property (nonatomic, strong) IBOutlet UIWindow *window; 14 | @property (nonatomic, strong) IBOutlet UnrarExampleViewController *viewController; 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /Example/Classes/UnrarExampleAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // UnrarExampleAppDelegate.m 3 | // UnrarExample 4 | // 5 | // 6 | 7 | #import "UnrarExampleAppDelegate.h" 8 | #import "UnrarExampleViewController.h" 9 | 10 | @implementation UnrarExampleAppDelegate 11 | 12 | 13 | #pragma mark - Application lifecycle 14 | 15 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 16 | 17 | // Override point for customization after application launch. 18 | 19 | // Add the view controller's view to the window and display. 20 | [self.window addSubview:self.viewController.view]; 21 | [self.window makeKeyAndVisible]; 22 | 23 | return YES; 24 | } 25 | 26 | 27 | - (void)applicationWillResignActive:(UIApplication *)application { 28 | /* 29 | Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 30 | Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 31 | */ 32 | } 33 | 34 | 35 | - (void)applicationDidEnterBackground:(UIApplication *)application { 36 | /* 37 | Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 38 | If your application supports background execution, called instead of applicationWillTerminate: when the user quits. 39 | */ 40 | } 41 | 42 | 43 | - (void)applicationWillEnterForeground:(UIApplication *)application { 44 | /* 45 | Called as part of transition from the background to the inactive state: here you can undo many of the changes made on entering the background. 46 | */ 47 | } 48 | 49 | 50 | - (void)applicationDidBecomeActive:(UIApplication *)application { 51 | /* 52 | Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 53 | */ 54 | } 55 | 56 | 57 | - (void)applicationWillTerminate:(UIApplication *)application { 58 | /* 59 | Called when the application is about to terminate. 60 | See also applicationDidEnterBackground:. 61 | */ 62 | } 63 | 64 | 65 | #pragma mark - Memory management 66 | 67 | - (void)applicationDidReceiveMemoryWarning:(UIApplication *)application { 68 | /* 69 | Free up as much memory as possible by purging cached data objects that can be recreated (or reloaded from disk) later. 70 | */ 71 | } 72 | 73 | 74 | 75 | 76 | @end 77 | -------------------------------------------------------------------------------- /Example/Classes/UnrarExampleViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // UnrarExampleViewController.h 3 | // UnrarExample 4 | // 5 | // 6 | 7 | #import 8 | 9 | @interface UnrarExampleViewController : UIViewController 10 | 11 | 12 | @property (weak, nonatomic) IBOutlet UITextField *passwordField; 13 | @property (weak, nonatomic) IBOutlet UITextView *fileListTextView; 14 | 15 | @property (weak, nonatomic) IBOutlet UILabel *extractionStepLabel; 16 | @property (weak, nonatomic) IBOutlet UIProgressView *extractionProgressView; 17 | 18 | 19 | - (IBAction)listFiles:(id)sender; 20 | - (IBAction)extractLargeFile:(id)sender; 21 | - (IBAction)cancelExtraction:(id)sender; 22 | 23 | @end 24 | 25 | -------------------------------------------------------------------------------- /Example/Default-568h@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abbeycode/UnrarKit/7cd8c32bcfc1e1a7d16bc5b58cbd37a6eaf8b316/Example/Default-568h@2x.png -------------------------------------------------------------------------------- /Example/MainWindow.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /Example/UnrarExample-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIconFile 12 | 13 | CFBundleIdentifier 14 | $(PRODUCT_BUNDLE_IDENTIFIER) 15 | CFBundleInfoDictionaryVersion 16 | 6.0 17 | CFBundleName 18 | ${PRODUCT_NAME} 19 | CFBundlePackageType 20 | APPL 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1.0 25 | LSRequiresIPhoneOS 26 | 27 | NSMainNibFile 28 | MainWindow 29 | 30 | 31 | -------------------------------------------------------------------------------- /Example/UnrarExample.xcodeproj/.gitignore: -------------------------------------------------------------------------------- 1 | /rogerio.mode1v3 2 | /rogerio.pbxuser 3 | /*.mode1v3 4 | /*.pbxuser 5 | -------------------------------------------------------------------------------- /Example/UnrarExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Example/UnrarExample.xcodeproj/xcshareddata/xcschemes/UnrarExample.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 37 | 38 | 39 | 40 | 41 | 42 | 52 | 54 | 60 | 61 | 62 | 63 | 69 | 71 | 77 | 78 | 79 | 80 | 82 | 83 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /Example/UnrarExample_Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'UnrarExample' target in the 'UnrarExample' project 3 | // 4 | 5 | #ifdef __OBJC__ 6 | #import 7 | #import 8 | #endif 9 | -------------------------------------------------------------------------------- /Example/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // UnrarExample 4 | // 5 | // Created by Rogerio Pereira Araujo on 08/11/10. 6 | // Copyright 2010 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | int main(int argc, char *argv[]) { 12 | 13 | @autoreleasepool { 14 | int retVal = UIApplicationMain(argc, argv, nil, nil); 15 | return retVal; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Example/makeLargeArchive.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | 4 | UNCOMPRESSED_FILE="$1" 5 | ARCHIVE_NAME="`dirname $1`/large-archive.rar" 6 | 7 | ARCH="`uname -m`" 8 | 9 | if [[ $ARCH -eq "arm64" ]]; 10 | then 11 | RAR="Tests/Test Data/bin/arm/rar" 12 | else 13 | RAR="Tests/Test Data/bin/x64/rar" 14 | fi 15 | 16 | "$RAR" a -ep "${ARCHIVE_NAME}" "${UNCOMPRESSED_FILE}" -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | © Dov Frankel, All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 4 | 5 | Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /Libraries/unrar/acknow.txt: -------------------------------------------------------------------------------- 1 | ACKNOWLEDGMENTS 2 | 3 | * We used "Screaming Fast Galois Field Arithmetic Using Intel 4 | SIMD Instructions" paper by James S. Plank, Kevin M. Greenan 5 | and Ethan L. Miller to improve Reed-Solomon coding performance. 6 | Also we are grateful to Artem Drobanov and Bulat Ziganshin 7 | for samples and ideas allowed to make Reed-Solomon coding 8 | more efficient. 9 | 10 | * RAR4 text compression algorithm is based on Dmitry Shkarin PPMII 11 | and Dmitry Subbotin carryless rangecoder public domain source code. 12 | You can find it in ftp.elf.stuba.sk/pub/pc/pack. 13 | 14 | * RAR encryption includes parts of public domain code 15 | from Szymon Stefanek AES and Steve Reid SHA-1 implementations. 16 | 17 | * With exception of SFX modules, RAR uses CRC32 function based 18 | on Intel Slicing-by-8 algorithm. Original Intel Slicing-by-8 code 19 | is available here: 20 | 21 | https://sourceforge.net/projects/slicing-by-8/ 22 | 23 | Original Intel Slicing-by-8 code is licensed under BSD License 24 | available at http://www.opensource.org/licenses/bsd-license.html 25 | 26 | Copyright (c) 2004-2006 Intel Corporation. 27 | All Rights Reserved 28 | 29 | Redistribution and use in source and binary forms, with or without 30 | modification, are permitted provided that the following conditions 31 | are met: 32 | 33 | Redistributions of source code must retain the above copyright notice, 34 | this list of conditions and the following disclaimer. 35 | 36 | Redistributions in binary form must reproduce the above copyright 37 | notice, this list of conditions and the following disclaimer 38 | in the documentation and/or other materials provided with 39 | the distribution. 40 | 41 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 42 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 43 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 44 | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 45 | HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 46 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 47 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 48 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 49 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 50 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 51 | OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 52 | SUCH DAMAGE. 53 | 54 | * RAR archives may optionally include BLAKE2sp hash ( https://blake2.net ), 55 | designed by Jean-Philippe Aumasson, Samuel Neves, Zooko Wilcox-O'Hearn 56 | and Christian Winnerlein. 57 | 58 | * Useful hints provided by Alexander Khoroshev and Bulat Ziganshin allowed 59 | to significantly improve RAR compression and speed. 60 | -------------------------------------------------------------------------------- /Libraries/unrar/blake2s.hpp: -------------------------------------------------------------------------------- 1 | // Based on public domain code written in 2012 by Samuel Neves 2 | #ifndef _RAR_BLAKE2_ 3 | #define _RAR_BLAKE2_ 4 | 5 | #define BLAKE2_DIGEST_SIZE 32 6 | #define BLAKE2_THREADS_NUMBER 8 7 | 8 | enum blake2s_constant 9 | { 10 | BLAKE2S_BLOCKBYTES = 64, 11 | BLAKE2S_OUTBYTES = 32 12 | }; 13 | 14 | 15 | // Alignment to 64 improves performance of both SSE and non-SSE versions. 16 | // Alignment to n*16 is required for SSE version, so we selected 64. 17 | // We use the custom alignment scheme instead of __declspec(align(x)), 18 | // because it is less compiler dependent. Also the compiler directive 19 | // does not help if structure is a member of class allocated through 20 | // 'new' operator. 21 | struct blake2s_state 22 | { 23 | enum { BLAKE_ALIGNMENT = 64 }; 24 | 25 | // buffer and uint32 h[8], t[2], f[2]; 26 | enum { BLAKE_DATA_SIZE = 48 + 2 * BLAKE2S_BLOCKBYTES }; 27 | 28 | byte ubuf[BLAKE_DATA_SIZE + BLAKE_ALIGNMENT]; 29 | 30 | byte *buf; // byte buf[2 * BLAKE2S_BLOCKBYTES]. 31 | uint32 *h, *t, *f; // uint32 h[8], t[2], f[2]. 32 | 33 | size_t buflen; 34 | byte last_node; 35 | 36 | blake2s_state() 37 | { 38 | set_pointers(); 39 | } 40 | 41 | // Required when we declare and assign in the same command. 42 | blake2s_state(blake2s_state &st) 43 | { 44 | set_pointers(); 45 | *this=st; 46 | } 47 | 48 | void set_pointers() 49 | { 50 | // Set aligned pointers. Must be done in constructor, not in Init(), 51 | // so assignments like 'blake2sp_state res=blake2ctx' work correctly 52 | // even if blake2sp_init is not called for 'res'. 53 | buf = (byte *) ALIGN_VALUE(ubuf, BLAKE_ALIGNMENT); 54 | h = (uint32 *) (buf + 2 * BLAKE2S_BLOCKBYTES); 55 | t = h + 8; 56 | f = t + 2; 57 | } 58 | 59 | void init() 60 | { 61 | memset( ubuf, 0, sizeof( ubuf ) ); 62 | buflen = 0; 63 | last_node = 0; 64 | } 65 | 66 | // Since we use pointers, the default = would work incorrectly. 67 | blake2s_state& operator = (blake2s_state &st) 68 | { 69 | if (this != &st) 70 | { 71 | memcpy(buf, st.buf, BLAKE_DATA_SIZE); 72 | buflen = st.buflen; 73 | last_node = st.last_node; 74 | } 75 | return *this; 76 | } 77 | }; 78 | 79 | 80 | #ifdef RAR_SMP 81 | class ThreadPool; 82 | #endif 83 | 84 | struct blake2sp_state 85 | { 86 | blake2s_state S[8]; 87 | blake2s_state R; 88 | byte buf[8 * BLAKE2S_BLOCKBYTES]; 89 | size_t buflen; 90 | 91 | #ifdef RAR_SMP 92 | ThreadPool *ThPool; 93 | uint MaxThreads; 94 | #endif 95 | }; 96 | 97 | void blake2sp_init( blake2sp_state *S ); 98 | void blake2sp_update( blake2sp_state *S, const byte *in, size_t inlen ); 99 | void blake2sp_final( blake2sp_state *S, byte *digest ); 100 | 101 | #endif 102 | 103 | -------------------------------------------------------------------------------- /Libraries/unrar/cmddata.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _RAR_CMDDATA_ 2 | #define _RAR_CMDDATA_ 3 | 4 | 5 | #define DefaultStoreList L"7z;ace;arj;bz2;cab;gz;jpeg;jpg;lha;lz;lzh;mp3;rar;taz;tgz;xz;z;zip;zipx" 6 | 7 | enum RAR_CMD_LIST_MODE {RCLM_AUTO,RCLM_REJECT_LISTS,RCLM_ACCEPT_LISTS}; 8 | 9 | enum IS_PROCESS_FILE_FLAGS {IPFF_EXCLUDE_PARENT=1}; 10 | 11 | class CommandData:public RAROptions 12 | { 13 | private: 14 | void ProcessSwitch(const wchar *Switch); 15 | void BadSwitch(const wchar *Switch); 16 | uint GetExclAttr(const wchar *Str,bool &Dir); 17 | #if !defined(SFX_MODULE) 18 | void SetTimeFilters(const wchar *Mod,bool Before,bool Age); 19 | void SetStoreTimeMode(const wchar *S); 20 | #endif 21 | 22 | bool FileLists; 23 | bool NoMoreSwitches; 24 | RAR_CMD_LIST_MODE ListMode; 25 | bool BareOutput; 26 | public: 27 | CommandData(); 28 | void Init(); 29 | 30 | void ParseCommandLine(bool Preprocess,int argc, char *argv[]); 31 | void ParseArg(wchar *ArgW); 32 | void ParseDone(); 33 | void ParseEnvVar(); 34 | void ReadConfig(); 35 | void PreprocessArg(const wchar *Arg); 36 | void ProcessSwitchesString(const wchar *Str); 37 | void OutTitle(); 38 | void OutHelp(RAR_EXIT ExitCode); 39 | bool IsSwitch(int Ch); 40 | bool ExclCheck(const wchar *CheckName,bool Dir,bool CheckFullPath,bool CheckInclList); 41 | static bool CheckArgs(StringList *Args,bool Dir,const wchar *CheckName,bool CheckFullPath,int MatchMode); 42 | bool ExclDirByAttr(uint FileAttr); 43 | bool TimeCheck(RarTime &ftm,RarTime &ftc,RarTime &fta); 44 | bool SizeCheck(int64 Size); 45 | bool AnyFiltersActive(); 46 | int IsProcessFile(FileHeader &FileHead,bool *ExactMatch,int MatchType, 47 | bool Flags,wchar *MatchedArg,uint MatchedArgSize); 48 | void ProcessCommand(); 49 | void AddArcName(const wchar *Name); 50 | bool GetArcName(wchar *Name,int MaxSize); 51 | bool CheckWinSize(); 52 | 53 | int GetRecoverySize(const wchar *CmdStr,const wchar *Value,int DefSize); 54 | 55 | #ifndef SFX_MODULE 56 | void ReportWrongSwitches(RARFORMAT Format); 57 | #endif 58 | 59 | wchar Command[NM+16]; 60 | 61 | wchar ArcName[NM]; 62 | 63 | StringList FileArgs; 64 | StringList ExclArgs; 65 | StringList InclArgs; 66 | StringList ArcNames; 67 | StringList StoreArgs; 68 | }; 69 | 70 | #endif 71 | -------------------------------------------------------------------------------- /Libraries/unrar/cmdmix.cpp: -------------------------------------------------------------------------------- 1 | void CommandData::OutTitle() 2 | { 3 | if (BareOutput || DisableCopyright) 4 | return; 5 | #if defined(__GNUC__) && defined(SFX_MODULE) 6 | mprintf(St(MCopyrightS)); 7 | #else 8 | #ifndef SILENT 9 | static bool TitleShown=false; 10 | if (TitleShown) 11 | return; 12 | TitleShown=true; 13 | 14 | wchar Version[80]; 15 | if (RARVER_BETA!=0) 16 | swprintf(Version,ASIZE(Version),L"%d.%02d %ls %d",RARVER_MAJOR,RARVER_MINOR,St(MBeta),RARVER_BETA); 17 | else 18 | swprintf(Version,ASIZE(Version),L"%d.%02d",RARVER_MAJOR,RARVER_MINOR); 19 | #if defined(_WIN_32) || defined(_WIN_64) 20 | wcsncatz(Version,L" ",ASIZE(Version)); 21 | #endif 22 | #ifdef _WIN_32 23 | wcsncatz(Version,St(Mx86),ASIZE(Version)); 24 | #endif 25 | #ifdef _WIN_64 26 | wcsncatz(Version,St(Mx64),ASIZE(Version)); 27 | #endif 28 | if (PrintVersion) 29 | { 30 | mprintf(L"%s",Version); 31 | exit(0); 32 | } 33 | mprintf(St(MUCopyright),Version,RARVER_YEAR); 34 | #endif 35 | #endif 36 | } 37 | 38 | 39 | inline bool CmpMSGID(MSGID i1,MSGID i2) 40 | { 41 | #ifdef MSGID_INT 42 | return i1==i2; 43 | #else 44 | // If MSGID is const char*, we cannot compare pointers only. 45 | // Pointers to different instances of same string can differ, 46 | // so we need to compare complete strings. 47 | return wcscmp(i1,i2)==0; 48 | #endif 49 | } 50 | 51 | void CommandData::OutHelp(RAR_EXIT ExitCode) 52 | { 53 | #if !defined(SILENT) 54 | OutTitle(); 55 | static MSGID Help[]={ 56 | #ifdef SFX_MODULE 57 | // Console SFX switches definition. 58 | MCHelpCmd,MSHelpCmdE,MSHelpCmdT,MSHelpCmdV 59 | #else 60 | // UnRAR switches definition. 61 | MUNRARTitle1,MRARTitle2,MCHelpCmd,MCHelpCmdE,MCHelpCmdL, 62 | MCHelpCmdP,MCHelpCmdT,MCHelpCmdV,MCHelpCmdX,MCHelpSw,MCHelpSwm, 63 | MCHelpSwAT,MCHelpSwAC,MCHelpSwAD,MCHelpSwAG,MCHelpSwAI,MCHelpSwAP, 64 | MCHelpSwCm,MCHelpSwCFGm,MCHelpSwCL,MCHelpSwCU,MCHelpSwDH,MCHelpSwEP, 65 | MCHelpSwEP3,MCHelpSwEP4,MCHelpSwF,MCHelpSwIDP,MCHelpSwIERR, 66 | MCHelpSwINUL,MCHelpSwIOFF,MCHelpSwKB,MCHelpSwME,MCHelpSwN,MCHelpSwNa, 67 | MCHelpSwNal,MCHelpSwO,MCHelpSwOC,MCHelpSwOL,MCHelpSwOP,MCHelpSwOR, 68 | MCHelpSwOW,MCHelpSwP,MCHelpSwR,MCHelpSwRI,MCHelpSwSC,MCHelpSwSI, 69 | MCHelpSwSL,MCHelpSwSM,MCHelpSwTA,MCHelpSwTB,MCHelpSwTN,MCHelpSwTO, 70 | MCHelpSwTS,MCHelpSwU,MCHelpSwVUnr,MCHelpSwVER,MCHelpSwVP,MCHelpSwX, 71 | MCHelpSwXa,MCHelpSwXal,MCHelpSwY 72 | #endif 73 | }; 74 | 75 | for (uint I=0;IGetChar()); 6 | } 7 | 8 | 9 | void RangeCoder::InitDecoder(Unpack *UnpackRead) 10 | { 11 | RangeCoder::UnpackRead=UnpackRead; 12 | 13 | low=code=0; 14 | range=uint(-1); 15 | for (int i=0;i < 4;i++) 16 | code=(code << 8) | GetChar(); 17 | } 18 | 19 | 20 | // (int) cast before "low" added only to suppress compiler warnings. 21 | #define ARI_DEC_NORMALIZE(code,low,range,read) \ 22 | { \ 23 | while ((low^(low+range))GetChar(); \ 26 | range <<= 8; \ 27 | low <<= 8; \ 28 | } \ 29 | } 30 | 31 | 32 | inline int RangeCoder::GetCurrentCount() 33 | { 34 | return (code-low)/(range /= SubRange.scale); 35 | } 36 | 37 | 38 | inline uint RangeCoder::GetCurrentShiftCount(uint SHIFT) 39 | { 40 | return (code-low)/(range >>= SHIFT); 41 | } 42 | 43 | 44 | inline void RangeCoder::Decode() 45 | { 46 | low += range*SubRange.LowCount; 47 | range *= SubRange.HighCount-SubRange.LowCount; 48 | } 49 | -------------------------------------------------------------------------------- /Libraries/unrar/coder.hpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * Contents: 'Carryless rangecoder' by Dmitry Subbotin * 3 | ****************************************************************************/ 4 | 5 | 6 | class RangeCoder 7 | { 8 | public: 9 | void InitDecoder(Unpack *UnpackRead); 10 | inline int GetCurrentCount(); 11 | inline uint GetCurrentShiftCount(uint SHIFT); 12 | inline void Decode(); 13 | inline void PutChar(unsigned int c); 14 | inline unsigned int GetChar(); 15 | 16 | uint low, code, range; 17 | struct SUBRANGE 18 | { 19 | uint LowCount, HighCount, scale; 20 | } SubRange; 21 | 22 | Unpack *UnpackRead; 23 | }; 24 | -------------------------------------------------------------------------------- /Libraries/unrar/compress.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _RAR_COMPRESS_ 2 | #define _RAR_COMPRESS_ 3 | 4 | // Combine pack and unpack constants to class to avoid polluting global 5 | // namespace with numerous short names. 6 | class PackDef 7 | { 8 | public: 9 | // Maximum LZ match length we can encode even for short distances. 10 | static const uint MAX_LZ_MATCH = 0x1001; 11 | 12 | // We increment LZ match length for longer distances, because shortest 13 | // matches are not allowed for them. Maximum length increment is 3 14 | // for distances larger than 256KB (0x40000). Here we define the maximum 15 | // incremented LZ match. Normally packer does not use it, but we must be 16 | // ready to process it in corrupt archives. 17 | static const uint MAX_INC_LZ_MATCH = MAX_LZ_MATCH + 3; 18 | 19 | static const uint MAX3_LZ_MATCH = 0x101; // Maximum match length for RAR v3. 20 | static const uint LOW_DIST_REP_COUNT = 16; 21 | 22 | static const uint NC = 306; /* alphabet = {0, 1, 2, ..., NC - 1} */ 23 | static const uint DC = 64; 24 | static const uint LDC = 16; 25 | static const uint RC = 44; 26 | static const uint HUFF_TABLE_SIZE = NC + DC + RC + LDC; 27 | static const uint BC = 20; 28 | 29 | static const uint NC30 = 299; /* alphabet = {0, 1, 2, ..., NC - 1} */ 30 | static const uint DC30 = 60; 31 | static const uint LDC30 = 17; 32 | static const uint RC30 = 28; 33 | static const uint BC30 = 20; 34 | static const uint HUFF_TABLE_SIZE30 = NC30 + DC30 + RC30 + LDC30; 35 | 36 | static const uint NC20 = 298; /* alphabet = {0, 1, 2, ..., NC - 1} */ 37 | static const uint DC20 = 48; 38 | static const uint RC20 = 28; 39 | static const uint BC20 = 19; 40 | static const uint MC20 = 257; 41 | 42 | // Largest alphabet size among all values listed above. 43 | static const uint LARGEST_TABLE_SIZE = 306; 44 | 45 | enum { 46 | CODE_HUFFMAN, CODE_LZ, CODE_REPEATLZ, CODE_CACHELZ, CODE_STARTFILE, 47 | CODE_ENDFILE, CODE_FILTER, CODE_FILTERDATA 48 | }; 49 | }; 50 | 51 | 52 | enum FilterType { 53 | // These values must not be changed, because we use them directly 54 | // in RAR5 compression and decompression code. 55 | FILTER_DELTA=0, FILTER_E8, FILTER_E8E9, FILTER_ARM, 56 | FILTER_AUDIO, FILTER_RGB, FILTER_ITANIUM, FILTER_PPM, FILTER_NONE 57 | }; 58 | 59 | #endif 60 | -------------------------------------------------------------------------------- /Libraries/unrar/consio.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _RAR_CONSIO_ 2 | #define _RAR_CONSIO_ 3 | 4 | void InitConsole(); 5 | void SetConsoleMsgStream(MESSAGE_TYPE MsgStream); 6 | void SetConsoleRedirectCharset(RAR_CHARSET RedirectCharset); 7 | void ProhibitConsoleInput(); 8 | void OutComment(const wchar *Comment,size_t Size); 9 | 10 | #ifndef SILENT 11 | bool GetConsolePassword(UIPASSWORD_TYPE Type,const wchar *FileName,SecPassword *Password); 12 | #endif 13 | 14 | #ifdef SILENT 15 | inline void mprintf(const wchar *fmt,...) {} 16 | inline void eprintf(const wchar *fmt,...) {} 17 | inline void Alarm() {} 18 | inline int Ask(const wchar *AskStr) {return 0;} 19 | inline bool getwstr(wchar *str,size_t n) {return false;} 20 | #else 21 | void mprintf(const wchar *fmt,...); 22 | void eprintf(const wchar *fmt,...); 23 | void Alarm(); 24 | int Ask(const wchar *AskStr); 25 | bool getwstr(wchar *str,size_t n); 26 | #endif 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /Libraries/unrar/crc.cpp: -------------------------------------------------------------------------------- 1 | // This CRC function is based on Intel Slicing-by-8 algorithm. 2 | // 3 | // Original Intel Slicing-by-8 code is available here: 4 | // 5 | // http://sourceforge.net/projects/slicing-by-8/ 6 | // 7 | // Original Intel Slicing-by-8 code is licensed as: 8 | // 9 | // Copyright (c) 2004-2006 Intel Corporation - All Rights Reserved 10 | // 11 | // This software program is licensed subject to the BSD License, 12 | // available at http://www.opensource.org/licenses/bsd-license.html 13 | 14 | 15 | #include "rar.hpp" 16 | 17 | #ifndef SFX_MODULE 18 | // User suggested to avoid BSD license in SFX module, so they do not need 19 | // to include the license to SFX archive. 20 | #define USE_SLICING 21 | #endif 22 | 23 | static uint crc_tables[8][256]; // Tables for Slicing-by-8. 24 | 25 | 26 | // Build the classic CRC32 lookup table. 27 | // We also provide this function to legacy RAR and ZIP decryption code. 28 | void InitCRC32(uint *CRCTab) 29 | { 30 | if (CRCTab[1]!=0) 31 | return; 32 | for (uint I=0;I<256;I++) 33 | { 34 | uint C=I; 35 | for (uint J=0;J<8;J++) 36 | C=(C & 1) ? (C>>1)^0xEDB88320 : (C>>1); 37 | CRCTab[I]=C; 38 | } 39 | } 40 | 41 | 42 | static void InitTables() 43 | { 44 | InitCRC32(crc_tables[0]); 45 | 46 | #ifdef USE_SLICING 47 | for (uint I=0;I<256;I++) // Build additional lookup tables. 48 | { 49 | uint C=crc_tables[0][I]; 50 | for (uint J=1;J<8;J++) 51 | { 52 | C=crc_tables[0][(byte)C]^(C>>8); 53 | crc_tables[J][I]=C; 54 | } 55 | } 56 | #endif 57 | } 58 | 59 | 60 | struct CallInitCRC {CallInitCRC() {InitTables();}} static CallInit32; 61 | 62 | uint CRC32(uint StartCRC,const void *Addr,size_t Size) 63 | { 64 | byte *Data=(byte *)Addr; 65 | 66 | #ifdef USE_SLICING 67 | // Align Data to 8 for better performance. 68 | for (;Size>0 && ((size_t)Data & 7);Size--,Data++) 69 | StartCRC=crc_tables[0][(byte)(StartCRC^Data[0])]^(StartCRC>>8); 70 | 71 | for (;Size>=8;Size-=8,Data+=8) 72 | { 73 | #ifdef BIG_ENDIAN 74 | StartCRC ^= Data[0]|(Data[1] << 8)|(Data[2] << 16)|(Data[3] << 24); 75 | uint NextData = Data[4]|(Data[5] << 8)|(Data[6] << 16)|(Data[7] << 24); 76 | #else 77 | StartCRC ^= *(uint32 *) Data; 78 | uint NextData = *(uint32 *) (Data+4); 79 | #endif 80 | StartCRC = crc_tables[7][(byte) StartCRC ] ^ 81 | crc_tables[6][(byte)(StartCRC >> 8) ] ^ 82 | crc_tables[5][(byte)(StartCRC >> 16)] ^ 83 | crc_tables[4][(byte)(StartCRC >> 24)] ^ 84 | crc_tables[3][(byte) NextData ] ^ 85 | crc_tables[2][(byte)(NextData >> 8) ] ^ 86 | crc_tables[1][(byte)(NextData >> 16)] ^ 87 | crc_tables[0][(byte)(NextData >> 24)]; 88 | } 89 | #endif 90 | 91 | for (;Size>0;Size--,Data++) // Process left data. 92 | StartCRC=crc_tables[0][(byte)(StartCRC^Data[0])]^(StartCRC>>8); 93 | 94 | return StartCRC; 95 | } 96 | 97 | 98 | #ifndef SFX_MODULE 99 | // For RAR 1.4 archives in case somebody still has them. 100 | ushort Checksum14(ushort StartCRC,const void *Addr,size_t Size) 101 | { 102 | byte *Data=(byte *)Addr; 103 | for (size_t I=0;I>15))&0xffff; 107 | } 108 | return StartCRC; 109 | } 110 | #endif 111 | 112 | 113 | -------------------------------------------------------------------------------- /Libraries/unrar/crc.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _RAR_CRC_ 2 | #define _RAR_CRC_ 3 | 4 | // This function is only to intialize external CRC tables. We do not need to 5 | // call it before calculating CRC32. 6 | void InitCRC32(uint *CRCTab); 7 | 8 | uint CRC32(uint StartCRC,const void *Addr,size_t Size); 9 | 10 | #ifndef SFX_MODULE 11 | ushort Checksum14(ushort StartCRC,const void *Addr,size_t Size); 12 | #endif 13 | 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /Libraries/unrar/crypt.cpp: -------------------------------------------------------------------------------- 1 | #include "rar.hpp" 2 | 3 | #ifndef SFX_MODULE 4 | #include "crypt1.cpp" 5 | #include "crypt2.cpp" 6 | #endif 7 | #include "crypt3.cpp" 8 | #include "crypt5.cpp" 9 | 10 | 11 | CryptData::CryptData() 12 | { 13 | Method=CRYPT_NONE; 14 | memset(KDF3Cache,0,sizeof(KDF3Cache)); 15 | memset(KDF5Cache,0,sizeof(KDF5Cache)); 16 | KDF3CachePos=0; 17 | KDF5CachePos=0; 18 | memset(CRCTab,0,sizeof(CRCTab)); 19 | } 20 | 21 | 22 | CryptData::~CryptData() 23 | { 24 | cleandata(KDF3Cache,sizeof(KDF3Cache)); 25 | cleandata(KDF5Cache,sizeof(KDF5Cache)); 26 | } 27 | 28 | 29 | 30 | 31 | void CryptData::DecryptBlock(byte *Buf,size_t Size) 32 | { 33 | switch(Method) 34 | { 35 | #ifndef SFX_MODULE 36 | case CRYPT_RAR13: 37 | Decrypt13(Buf,Size); 38 | break; 39 | case CRYPT_RAR15: 40 | Crypt15(Buf,Size); 41 | break; 42 | case CRYPT_RAR20: 43 | for (size_t I=0;IIsSet() || Method==CRYPT_NONE) 60 | return false; 61 | 62 | CryptData::Method=Method; 63 | 64 | wchar PwdW[MAXPASSWORD]; 65 | Password->Get(PwdW,ASIZE(PwdW)); 66 | char PwdA[MAXPASSWORD]; 67 | WideToChar(PwdW,PwdA,ASIZE(PwdA)); 68 | 69 | switch(Method) 70 | { 71 | #ifndef SFX_MODULE 72 | case CRYPT_RAR13: 73 | SetKey13(PwdA); 74 | break; 75 | case CRYPT_RAR15: 76 | SetKey15(PwdA); 77 | break; 78 | case CRYPT_RAR20: 79 | SetKey20(PwdA); 80 | break; 81 | #endif 82 | case CRYPT_RAR30: 83 | SetKey30(Encrypt,Password,PwdW,Salt); 84 | break; 85 | case CRYPT_RAR50: 86 | SetKey50(Encrypt,Password,PwdW,Salt,InitV,Lg2Cnt,HashKey,PswCheck); 87 | break; 88 | } 89 | cleandata(PwdA,sizeof(PwdA)); 90 | cleandata(PwdW,sizeof(PwdW)); 91 | return true; 92 | } 93 | 94 | 95 | // Use the current system time to additionally randomize data. 96 | static void TimeRandomize(byte *RndBuf,size_t BufSize) 97 | { 98 | static uint Count=0; 99 | RarTime CurTime; 100 | CurTime.SetCurrentTime(); 101 | uint64 Random=CurTime.GetWin()+clock(); 102 | for (size_t I=0;I> ( (I & 7) * 8 )); 105 | RndBuf[I]=byte( (RndByte ^ I) + Count++); 106 | } 107 | } 108 | 109 | 110 | 111 | 112 | // Fill buffer with random data. 113 | void GetRnd(byte *RndBuf,size_t BufSize) 114 | { 115 | bool Success=false; 116 | #if defined(_WIN_ALL) 117 | HCRYPTPROV hProvider = 0; 118 | if (CryptAcquireContext(&hProvider, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) 119 | { 120 | Success=CryptGenRandom(hProvider, (DWORD)BufSize, RndBuf) == TRUE; 121 | CryptReleaseContext(hProvider, 0); 122 | } 123 | #elif defined(_UNIX) 124 | FILE *rndf = fopen("/dev/urandom", "r"); 125 | if (rndf!=NULL) 126 | { 127 | Success=fread(RndBuf, BufSize, 1, rndf) == BufSize; 128 | fclose(rndf); 129 | } 130 | #endif 131 | // We use this code only as the last resort if code above failed. 132 | if (!Success) 133 | TimeRandomize(RndBuf,BufSize); 134 | } 135 | -------------------------------------------------------------------------------- /Libraries/unrar/crypt.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _RAR_CRYPT_ 2 | #define _RAR_CRYPT_ 3 | 4 | 5 | enum CRYPT_METHOD { 6 | CRYPT_NONE,CRYPT_RAR13,CRYPT_RAR15,CRYPT_RAR20,CRYPT_RAR30,CRYPT_RAR50 7 | }; 8 | 9 | #define SIZE_SALT50 16 10 | #define SIZE_SALT30 8 11 | #define SIZE_INITV 16 12 | #define SIZE_PSWCHECK 8 13 | #define SIZE_PSWCHECK_CSUM 4 14 | 15 | #define CRYPT_BLOCK_SIZE 16 16 | #define CRYPT_BLOCK_MASK (CRYPT_BLOCK_SIZE-1) // 0xf 17 | 18 | #define CRYPT5_KDF_LG2_COUNT 15 // LOG2 of PDKDF2 iteration count. 19 | #define CRYPT5_KDF_LG2_COUNT_MAX 24 // LOG2 of maximum accepted iteration count. 20 | #define CRYPT_VERSION 0 // Supported encryption version. 21 | 22 | 23 | class CryptData 24 | { 25 | struct KDF5CacheItem 26 | { 27 | SecPassword Pwd; 28 | byte Salt[SIZE_SALT50]; 29 | byte Key[32]; 30 | uint Lg2Count; // Log2 of PBKDF2 repetition count. 31 | byte PswCheckValue[SHA256_DIGEST_SIZE]; 32 | byte HashKeyValue[SHA256_DIGEST_SIZE]; 33 | }; 34 | 35 | struct KDF3CacheItem 36 | { 37 | SecPassword Pwd; 38 | byte Salt[SIZE_SALT30]; 39 | byte Key[16]; 40 | byte Init[16]; 41 | bool SaltPresent; 42 | }; 43 | 44 | 45 | private: 46 | void SetKey13(const char *Password); 47 | void Decrypt13(byte *Data,size_t Count); 48 | 49 | void SetKey15(const char *Password); 50 | void Crypt15(byte *Data,size_t Count); 51 | 52 | void SetKey20(const char *Password); 53 | void Swap20(byte *Ch1,byte *Ch2); 54 | void UpdKeys20(byte *Buf); 55 | void EncryptBlock20(byte *Buf); 56 | void DecryptBlock20(byte *Buf); 57 | 58 | void SetKey30(bool Encrypt,SecPassword *Password,const wchar *PwdW,const byte *Salt); 59 | void SetKey50(bool Encrypt,SecPassword *Password,const wchar *PwdW,const byte *Salt,const byte *InitV,uint Lg2Cnt,byte *HashKey,byte *PswCheck); 60 | 61 | KDF3CacheItem KDF3Cache[4]; 62 | uint KDF3CachePos; 63 | 64 | KDF5CacheItem KDF5Cache[4]; 65 | uint KDF5CachePos; 66 | 67 | CRYPT_METHOD Method; 68 | 69 | Rijndael rin; 70 | 71 | uint CRCTab[256]; // For RAR 1.5 and RAR 2.0 encryption. 72 | 73 | byte SubstTable20[256]; 74 | uint Key20[4]; 75 | 76 | byte Key13[3]; 77 | ushort Key15[4]; 78 | public: 79 | CryptData(); 80 | ~CryptData(); 81 | bool SetCryptKeys(bool Encrypt,CRYPT_METHOD Method,SecPassword *Password, 82 | const byte *Salt,const byte *InitV,uint Lg2Cnt, 83 | byte *HashKey,byte *PswCheck); 84 | void SetAV15Encryption(); 85 | void SetCmt13Encryption(); 86 | void EncryptBlock(byte *Buf,size_t Size); 87 | void DecryptBlock(byte *Buf,size_t Size); 88 | static void SetSalt(byte *Salt,size_t SaltSize); 89 | }; 90 | 91 | void GetRnd(byte *RndBuf,size_t BufSize); 92 | 93 | void hmac_sha256(const byte *Key,size_t KeyLength,const byte *Data, 94 | size_t DataLength,byte *ResDigest); 95 | void pbkdf2(const byte *pass, size_t pass_len, const byte *salt, 96 | size_t salt_len,byte *key, byte *Value1, byte *Value2, 97 | uint rounds); 98 | 99 | void ConvertHashToMAC(HashValue *Value,byte *Key); 100 | 101 | #endif 102 | -------------------------------------------------------------------------------- /Libraries/unrar/crypt1.cpp: -------------------------------------------------------------------------------- 1 | extern uint CRCTab[256]; 2 | 3 | void CryptData::SetKey13(const char *Password) 4 | { 5 | Key13[0]=Key13[1]=Key13[2]=0; 6 | for (size_t I=0;Password[I]!=0;I++) 7 | { 8 | byte P=Password[I]; 9 | Key13[0]+=P; 10 | Key13[1]^=P; 11 | Key13[2]+=P; 12 | Key13[2]=(byte)rotls(Key13[2],1,8); 13 | } 14 | } 15 | 16 | 17 | void CryptData::SetKey15(const char *Password) 18 | { 19 | InitCRC32(CRCTab); 20 | uint PswCRC=CRC32(0xffffffff,Password,strlen(Password)); 21 | Key15[0]=PswCRC&0xffff; 22 | Key15[1]=(PswCRC>>16)&0xffff; 23 | Key15[2]=Key15[3]=0; 24 | for (size_t I=0;Password[I]!=0;I++) 25 | { 26 | byte P=Password[I]; 27 | Key15[2]^=P^CRCTab[P]; 28 | Key15[3]+=P+(CRCTab[P]>>16); 29 | } 30 | } 31 | 32 | 33 | void CryptData::SetAV15Encryption() 34 | { 35 | InitCRC32(CRCTab); 36 | Method=CRYPT_RAR15; 37 | Key15[0]=0x4765; 38 | Key15[1]=0x9021; 39 | Key15[2]=0x7382; 40 | Key15[3]=0x5215; 41 | } 42 | 43 | 44 | void CryptData::SetCmt13Encryption() 45 | { 46 | Method=CRYPT_RAR13; 47 | Key13[0]=0; 48 | Key13[1]=7; 49 | Key13[2]=77; 50 | } 51 | 52 | 53 | void CryptData::Decrypt13(byte *Data,size_t Count) 54 | { 55 | while (Count--) 56 | { 57 | Key13[1]+=Key13[2]; 58 | Key13[0]+=Key13[1]; 59 | *Data-=Key13[0]; 60 | Data++; 61 | } 62 | } 63 | 64 | 65 | void CryptData::Crypt15(byte *Data,size_t Count) 66 | { 67 | while (Count--) 68 | { 69 | Key15[0]+=0x1234; 70 | Key15[1]^=CRCTab[(Key15[0] & 0x1fe)>>1]; 71 | Key15[2]-=CRCTab[(Key15[0] & 0x1fe)>>1]>>16; 72 | Key15[0]^=Key15[2]; 73 | Key15[3]=rotrs(Key15[3]&0xffff,1,16)^Key15[1]; 74 | Key15[3]=rotrs(Key15[3]&0xffff,1,16); 75 | Key15[0]^=Key15[3]; 76 | *Data^=(byte)(Key15[0]>>8); 77 | Data++; 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /Libraries/unrar/crypt2.cpp: -------------------------------------------------------------------------------- 1 | #define NROUNDS 32 2 | 3 | #define substLong(t) ( (uint)SubstTable20[(uint)t&255] | \ 4 | ((uint)SubstTable20[(int)(t>> 8)&255]<< 8) | \ 5 | ((uint)SubstTable20[(int)(t>>16)&255]<<16) | \ 6 | ((uint)SubstTable20[(int)(t>>24)&255]<<24) ) 7 | 8 | 9 | static byte InitSubstTable20[256]={ 10 | 215, 19,149, 35, 73,197,192,205,249, 28, 16,119, 48,221, 2, 42, 11 | 232, 1,177,233, 14, 88,219, 25,223,195,244, 90, 87,239,153,137, 12 | 255,199,147, 70, 92, 66,246, 13,216, 40, 62, 29,217,230, 86, 6, 13 | 71, 24,171,196,101,113,218,123, 93, 91,163,178,202, 67, 44,235, 14 | 107,250, 75,234, 49,167,125,211, 83,114,157,144, 32,193,143, 36, 15 | 158,124,247,187, 89,214,141, 47,121,228, 61,130,213,194,174,251, 16 | 97,110, 54,229,115, 57,152, 94,105,243,212, 55,209,245, 63, 11, 17 | 164,200, 31,156, 81,176,227, 21, 76, 99,139,188,127, 17,248, 51, 18 | 207,120,189,210, 8,226, 41, 72,183,203,135,165,166, 60, 98, 7, 19 | 122, 38,155,170, 69,172,252,238, 39,134, 59,128,236, 27,240, 80, 20 | 131, 3, 85,206,145, 79,154,142,159,220,201,133, 74, 64, 20,129, 21 | 224,185,138,103,173,182, 43, 34,254, 82,198,151,231,180, 58, 10, 22 | 118, 26,102, 12, 50,132, 22,191,136,111,162,179, 45, 4,148,108, 23 | 161, 56, 78,126,242,222, 15,175,146, 23, 33,241,181,190, 77,225, 24 | 0, 46,169,186, 68, 95,237, 65, 53,208,253,168, 9, 18,100, 52, 25 | 116,184,160, 96,109, 37, 30,106,140,104,150, 5,204,117,112, 84 26 | }; 27 | 28 | 29 | void CryptData::SetKey20(const char *Password) 30 | { 31 | InitCRC32(CRCTab); 32 | 33 | char Psw[MAXPASSWORD]; 34 | strncpyz(Psw,Password,ASIZE(Psw)); // We'll need to modify it below. 35 | size_t PswLength=strlen(Psw); 36 | 37 | Key20[0]=0xD3A3B879L; 38 | Key20[1]=0x3F6D12F7L; 39 | Key20[2]=0x7515A235L; 40 | Key20[3]=0xA4E7F123L; 41 | 42 | memcpy(SubstTable20,InitSubstTable20,sizeof(SubstTable20)); 43 | for (uint J=0;J<256;J++) 44 | for (size_t I=0;I=0;I--) 98 | { 99 | T=((C+rotls(D,11,32))^Key20[I&3]); 100 | TA=A^substLong(T); 101 | T=((D^rotls(C,17,32))+Key20[I&3]); 102 | TB=B^substLong(T); 103 | A=C; 104 | B=D; 105 | C=TA; 106 | D=TB; 107 | } 108 | RawPut4(C^Key20[0],Buf+0); 109 | RawPut4(D^Key20[1],Buf+4); 110 | RawPut4(A^Key20[2],Buf+8); 111 | RawPut4(B^Key20[3],Buf+12); 112 | UpdKeys20(InBuf); 113 | } 114 | 115 | 116 | void CryptData::UpdKeys20(byte *Buf) 117 | { 118 | for (int I=0;I<16;I+=4) 119 | { 120 | Key20[0]^=CRCTab[Buf[I]]; 121 | Key20[1]^=CRCTab[Buf[I+1]]; 122 | Key20[2]^=CRCTab[Buf[I+2]]; 123 | Key20[3]^=CRCTab[Buf[I+3]]; 124 | } 125 | } 126 | 127 | 128 | void CryptData::Swap20(byte *Ch1,byte *Ch2) 129 | { 130 | byte Ch=*Ch1; 131 | *Ch1=*Ch2; 132 | *Ch2=Ch; 133 | } 134 | -------------------------------------------------------------------------------- /Libraries/unrar/crypt3.cpp: -------------------------------------------------------------------------------- 1 | void CryptData::SetKey30(bool Encrypt,SecPassword *Password,const wchar *PwdW,const byte *Salt) 2 | { 3 | byte AESKey[16],AESInit[16]; 4 | 5 | bool Cached=false; 6 | for (uint I=0;I>8); 38 | PswNum[2]=(byte)(I>>16); 39 | sha1_process(&c, PswNum, 3); 40 | if (I%(HashRounds/16)==0) 41 | { 42 | sha1_context tempc=c; 43 | uint32 digest[5]; 44 | sha1_done( &tempc, digest ); 45 | AESInit[I/(HashRounds/16)]=(byte)digest[4]; 46 | } 47 | } 48 | uint32 digest[5]; 49 | sha1_done( &c, digest ); 50 | for (uint I=0;I<4;I++) 51 | for (uint J=0;J<4;J++) 52 | AESKey[I*4+J]=(byte)(digest[I]>>(J*8)); 53 | 54 | KDF3Cache[KDF3CachePos].Pwd=*Password; 55 | if ((KDF3Cache[KDF3CachePos].SaltPresent=(Salt!=NULL))==true) 56 | memcpy(KDF3Cache[KDF3CachePos].Salt,Salt,SIZE_SALT30); 57 | memcpy(KDF3Cache[KDF3CachePos].Key,AESKey,sizeof(AESKey)); 58 | SecHideData(KDF3Cache[KDF3CachePos].Key,sizeof(KDF3Cache[KDF3CachePos].Key),true,false); 59 | memcpy(KDF3Cache[KDF3CachePos].Init,AESInit,sizeof(AESInit)); 60 | KDF3CachePos=(KDF3CachePos+1)%ASIZE(KDF3Cache); 61 | 62 | cleandata(RawPsw,sizeof(RawPsw)); 63 | } 64 | rin.Init(Encrypt, AESKey, 128, AESInit); 65 | cleandata(AESKey,sizeof(AESKey)); 66 | cleandata(AESInit,sizeof(AESInit)); 67 | } 68 | 69 | -------------------------------------------------------------------------------- /Libraries/unrar/dll.def: -------------------------------------------------------------------------------- 1 | EXPORTS 2 | RAROpenArchive 3 | RAROpenArchiveEx 4 | RARCloseArchive 5 | RARReadHeader 6 | RARReadHeaderEx 7 | RARProcessFile 8 | RARProcessFileW 9 | RARSetCallback 10 | RARSetChangeVolProc 11 | RARSetProcessDataProc 12 | RARSetPassword 13 | RARGetDllVersion 14 | -------------------------------------------------------------------------------- /Libraries/unrar/dll.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abbeycode/UnrarKit/7cd8c32bcfc1e1a7d16bc5b58cbd37a6eaf8b316/Libraries/unrar/dll.rc -------------------------------------------------------------------------------- /Libraries/unrar/dll_nocrypt.def: -------------------------------------------------------------------------------- 1 | EXPORTS 2 | RAROpenArchive 3 | RAROpenArchiveEx 4 | RARCloseArchive 5 | RARReadHeader 6 | RARReadHeaderEx 7 | RARProcessFile 8 | RARProcessFileW 9 | RARSetCallback 10 | RARSetChangeVolProc 11 | RARSetProcessDataProc 12 | ; RARSetPassword 13 | RARGetDllVersion 14 | -------------------------------------------------------------------------------- /Libraries/unrar/encname.cpp: -------------------------------------------------------------------------------- 1 | #include "rar.hpp" 2 | 3 | EncodeFileName::EncodeFileName() 4 | { 5 | Flags=0; 6 | FlagBits=0; 7 | FlagsPos=0; 8 | DestSize=0; 9 | } 10 | 11 | 12 | 13 | 14 | void EncodeFileName::Decode(char *Name,size_t NameSize,byte *EncName,size_t EncSize, 15 | wchar *NameW,size_t MaxDecSize) 16 | { 17 | size_t EncPos=0,DecPos=0; 18 | byte HighByte=EncPos>6) 27 | { 28 | case 0: 29 | if (EncPos>=EncSize) 30 | break; 31 | NameW[DecPos++]=EncName[EncPos++]; 32 | break; 33 | case 1: 34 | if (EncPos>=EncSize) 35 | break; 36 | NameW[DecPos++]=EncName[EncPos++]+(HighByte<<8); 37 | break; 38 | case 2: 39 | if (EncPos+1>=EncSize) 40 | break; 41 | NameW[DecPos++]=EncName[EncPos]+(EncName[EncPos+1]<<8); 42 | EncPos+=2; 43 | break; 44 | case 3: 45 | { 46 | if (EncPos>=EncSize) 47 | break; 48 | int Length=EncName[EncPos++]; 49 | if ((Length & 0x80)!=0) 50 | { 51 | if (EncPos>=EncSize) 52 | break; 53 | byte Correction=EncName[EncPos++]; 54 | for (Length=(Length&0x7f)+2;Length>0 && DecPos0 && DecPos>3; 29 | InBit=Bits&7; 30 | } 31 | 32 | // Return 16 bits from current position in the buffer. 33 | // Bit at (InAddr,InBit) has the highest position in returning data. 34 | uint getbits() 35 | { 36 | uint BitField=(uint)InBuf[InAddr] << 16; 37 | BitField|=(uint)InBuf[InAddr+1] << 8; 38 | BitField|=(uint)InBuf[InAddr+2]; 39 | BitField >>= (8-InBit); 40 | return BitField & 0xffff; 41 | } 42 | 43 | // Return 32 bits from current position in the buffer. 44 | // Bit at (InAddr,InBit) has the highest position in returning data. 45 | uint getbits32() 46 | { 47 | uint BitField=(uint)InBuf[InAddr] << 24; 48 | BitField|=(uint)InBuf[InAddr+1] << 16; 49 | BitField|=(uint)InBuf[InAddr+2] << 8; 50 | BitField|=(uint)InBuf[InAddr+3]; 51 | BitField <<= InBit; 52 | BitField|=(uint)InBuf[InAddr+4] >> (8-InBit); 53 | return BitField & 0xffffffff; 54 | } 55 | 56 | void faddbits(uint Bits); 57 | uint fgetbits(); 58 | 59 | // Check if buffer has enough space for IncPtr bytes. Returns 'true' 60 | // if buffer will be overflown. 61 | bool Overflow(uint IncPtr) 62 | { 63 | return InAddr+IncPtr>=MAX_SIZE; 64 | } 65 | 66 | void SetExternalBuffer(byte *Buf); 67 | }; 68 | #endif 69 | -------------------------------------------------------------------------------- /Libraries/unrar/global.cpp: -------------------------------------------------------------------------------- 1 | #define INCLUDEGLOBAL 2 | 3 | #ifdef _MSC_VER 4 | #pragma hdrstop 5 | #endif 6 | 7 | #include "rar.hpp" 8 | -------------------------------------------------------------------------------- /Libraries/unrar/global.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _RAR_GLOBAL_ 2 | #define _RAR_GLOBAL_ 3 | 4 | #ifdef INCLUDEGLOBAL 5 | #define EXTVAR 6 | #else 7 | #define EXTVAR extern 8 | #endif 9 | 10 | EXTVAR ErrorHandler ErrHandler; 11 | 12 | 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /Libraries/unrar/hardlinks.cpp: -------------------------------------------------------------------------------- 1 | bool ExtractHardlink(CommandData *Cmd,wchar *NameNew,wchar *NameExisting,size_t NameExistingSize) 2 | { 3 | SlashToNative(NameExisting,NameExisting,NameExistingSize); // Not needed for RAR 5.1+ archives. 4 | 5 | if (!FileExist(NameExisting)) 6 | { 7 | uiMsg(UIERROR_HLINKCREATE,NameNew); 8 | uiMsg(UIERROR_NOLINKTARGET); 9 | ErrHandler.SetErrorCode(RARX_CREATE); 10 | return false; 11 | } 12 | CreatePath(NameNew,true,Cmd->DisableNames); 13 | 14 | #ifdef _WIN_ALL 15 | bool Success=CreateHardLink(NameNew,NameExisting,NULL)!=0; 16 | if (!Success) 17 | { 18 | uiMsg(UIERROR_HLINKCREATE,NameNew); 19 | ErrHandler.SysErrMsg(); 20 | ErrHandler.SetErrorCode(RARX_CREATE); 21 | } 22 | return Success; 23 | #elif defined(_UNIX) 24 | char NameExistingA[NM],NameNewA[NM]; 25 | WideToChar(NameExisting,NameExistingA,ASIZE(NameExistingA)); 26 | WideToChar(NameNew,NameNewA,ASIZE(NameNewA)); 27 | bool Success=link(NameExistingA,NameNewA)==0; 28 | if (!Success) 29 | { 30 | uiMsg(UIERROR_HLINKCREATE,NameNew); 31 | ErrHandler.SysErrMsg(); 32 | ErrHandler.SetErrorCode(RARX_CREATE); 33 | } 34 | return Success; 35 | #else 36 | return false; 37 | #endif 38 | } 39 | 40 | -------------------------------------------------------------------------------- /Libraries/unrar/hash.cpp: -------------------------------------------------------------------------------- 1 | #include "rar.hpp" 2 | 3 | void HashValue::Init(HASH_TYPE Type) 4 | { 5 | HashValue::Type=Type; 6 | 7 | // Zero length data CRC32 is 0. It is important to set it when creating 8 | // headers with no following data like directories or symlinks. 9 | if (Type==HASH_RAR14 || Type==HASH_CRC32) 10 | CRC32=0; 11 | if (Type==HASH_BLAKE2) 12 | { 13 | // dd0e891776933f43c7d032b08a917e25741f8aa9a12c12e1cac8801500f2ca4f 14 | // is BLAKE2sp hash of empty data. We init the structure to this value, 15 | // so if we create a file or service header with no following data like 16 | // "file copy" or "symlink", we set the checksum to proper value avoiding 17 | // additional header type or size checks when extracting. 18 | static byte EmptyHash[32]={ 19 | 0xdd, 0x0e, 0x89, 0x17, 0x76, 0x93, 0x3f, 0x43, 20 | 0xc7, 0xd0, 0x32, 0xb0, 0x8a, 0x91, 0x7e, 0x25, 21 | 0x74, 0x1f, 0x8a, 0xa9, 0xa1, 0x2c, 0x12, 0xe1, 22 | 0xca, 0xc8, 0x80, 0x15, 0x00, 0xf2, 0xca, 0x4f 23 | }; 24 | memcpy(Digest,EmptyHash,sizeof(Digest)); 25 | } 26 | } 27 | 28 | 29 | bool HashValue::operator == (const HashValue &cmp) 30 | { 31 | if (Type==HASH_NONE || cmp.Type==HASH_NONE) 32 | return true; 33 | if (Type==HASH_RAR14 && cmp.Type==HASH_RAR14 || 34 | Type==HASH_CRC32 && cmp.Type==HASH_CRC32) 35 | return CRC32==cmp.CRC32; 36 | if (Type==HASH_BLAKE2 && cmp.Type==HASH_BLAKE2) 37 | return memcmp(Digest,cmp.Digest,sizeof(Digest))==0; 38 | return false; 39 | } 40 | 41 | 42 | DataHash::DataHash() 43 | { 44 | blake2ctx=NULL; 45 | HashType=HASH_NONE; 46 | #ifdef RAR_SMP 47 | ThPool=NULL; 48 | MaxThreads=0; 49 | #endif 50 | } 51 | 52 | 53 | DataHash::~DataHash() 54 | { 55 | #ifdef RAR_SMP 56 | delete ThPool; 57 | #endif 58 | cleandata(&CurCRC32, sizeof(CurCRC32)); 59 | if (blake2ctx!=NULL) 60 | { 61 | cleandata(blake2ctx, sizeof(blake2sp_state)); 62 | delete blake2ctx; 63 | } 64 | } 65 | 66 | 67 | void DataHash::Init(HASH_TYPE Type,uint MaxThreads) 68 | { 69 | if (blake2ctx==NULL) 70 | blake2ctx=new blake2sp_state; 71 | HashType=Type; 72 | if (Type==HASH_RAR14) 73 | CurCRC32=0; 74 | if (Type==HASH_CRC32) 75 | CurCRC32=0xffffffff; // Initial CRC32 value. 76 | if (Type==HASH_BLAKE2) 77 | blake2sp_init(blake2ctx); 78 | #ifdef RAR_SMP 79 | DataHash::MaxThreads=Min(MaxThreads,MaxHashThreads); 80 | #endif 81 | } 82 | 83 | 84 | void DataHash::Update(const void *Data,size_t DataSize) 85 | { 86 | #ifndef SFX_MODULE 87 | if (HashType==HASH_RAR14) 88 | CurCRC32=Checksum14((ushort)CurCRC32,Data,DataSize); 89 | #endif 90 | if (HashType==HASH_CRC32) 91 | CurCRC32=CRC32(CurCRC32,Data,DataSize); 92 | 93 | if (HashType==HASH_BLAKE2) 94 | { 95 | #ifdef RAR_SMP 96 | if (MaxThreads>1 && ThPool==NULL) 97 | ThPool=new ThreadPool(BLAKE2_THREADS_NUMBER); 98 | blake2ctx->ThPool=ThPool; 99 | blake2ctx->MaxThreads=MaxThreads; 100 | #endif 101 | blake2sp_update( blake2ctx, (byte *)Data, DataSize); 102 | } 103 | } 104 | 105 | 106 | void DataHash::Result(HashValue *Result) 107 | { 108 | Result->Type=HashType; 109 | if (HashType==HASH_RAR14) 110 | Result->CRC32=CurCRC32; 111 | if (HashType==HASH_CRC32) 112 | Result->CRC32=CurCRC32^0xffffffff; 113 | if (HashType==HASH_BLAKE2) 114 | { 115 | // Preserve the original context, so we can continue hashing if necessary. 116 | blake2sp_state res=*blake2ctx; 117 | blake2sp_final(&res,Result->Digest); 118 | } 119 | } 120 | 121 | 122 | uint DataHash::GetCRC32() 123 | { 124 | return HashType==HASH_CRC32 ? CurCRC32^0xffffffff : 0; 125 | } 126 | 127 | 128 | bool DataHash::Cmp(HashValue *CmpValue,byte *Key) 129 | { 130 | HashValue Final; 131 | Result(&Final); 132 | if (Key!=NULL) 133 | ConvertHashToMAC(&Final,Key); 134 | return Final==*CmpValue; 135 | } 136 | -------------------------------------------------------------------------------- /Libraries/unrar/hash.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _RAR_DATAHASH_ 2 | #define _RAR_DATAHASH_ 3 | 4 | enum HASH_TYPE {HASH_NONE,HASH_RAR14,HASH_CRC32,HASH_BLAKE2}; 5 | 6 | struct HashValue 7 | { 8 | void Init(HASH_TYPE Type); 9 | bool operator == (const HashValue &cmp); 10 | bool operator != (const HashValue &cmp) {return !(*this==cmp);} 11 | 12 | HASH_TYPE Type; 13 | union 14 | { 15 | uint CRC32; 16 | byte Digest[SHA256_DIGEST_SIZE]; 17 | }; 18 | }; 19 | 20 | 21 | #ifdef RAR_SMP 22 | class ThreadPool; 23 | class DataHash; 24 | #endif 25 | 26 | 27 | class DataHash 28 | { 29 | private: 30 | HASH_TYPE HashType; 31 | uint CurCRC32; 32 | blake2sp_state *blake2ctx; 33 | 34 | #ifdef RAR_SMP 35 | ThreadPool *ThPool; 36 | 37 | uint MaxThreads; 38 | // Upper limit for maximum threads to prevent wasting threads in pool. 39 | static const uint MaxHashThreads=8; 40 | #endif 41 | public: 42 | DataHash(); 43 | ~DataHash(); 44 | void Init(HASH_TYPE Type,uint MaxThreads); 45 | void Update(const void *Data,size_t DataSize); 46 | void Result(HashValue *Result); 47 | uint GetCRC32(); 48 | bool Cmp(HashValue *CmpValue,byte *Key); 49 | HASH_TYPE Type() {return HashType;} 50 | }; 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /Libraries/unrar/headers.cpp: -------------------------------------------------------------------------------- 1 | #include "rar.hpp" 2 | 3 | void FileHeader::Reset(size_t SubDataSize) 4 | { 5 | SubData.Alloc(SubDataSize); 6 | BaseBlock::Reset(); 7 | FileHash.Init(HASH_NONE); 8 | mtime.Reset(); 9 | atime.Reset(); 10 | ctime.Reset(); 11 | SplitBefore=false; 12 | SplitAfter=false; 13 | 14 | UnknownUnpSize=0; 15 | 16 | SubFlags=0; // Important for RAR 3.0 subhead. 17 | 18 | CryptMethod=CRYPT_NONE; 19 | Encrypted=false; 20 | SaltSet=false; 21 | UsePswCheck=false; 22 | UseHashKey=false; 23 | Lg2Count=0; 24 | 25 | Solid=false; 26 | Dir=false; 27 | WinSize=0; 28 | Inherited=false; 29 | SubBlock=false; 30 | CommentInHeader=false; 31 | Version=false; 32 | LargeFile=false; 33 | 34 | RedirType=FSREDIR_NONE; 35 | DirTarget=false; 36 | UnixOwnerSet=false; 37 | } 38 | 39 | 40 | FileHeader& FileHeader::operator = (FileHeader &hd) 41 | { 42 | SubData.Reset(); 43 | memcpy(this,&hd,sizeof(*this)); 44 | SubData.CleanData(); 45 | SubData=hd.SubData; 46 | return *this; 47 | } 48 | 49 | 50 | void MainHeader::Reset() 51 | { 52 | HighPosAV=0; 53 | PosAV=0; 54 | CommentInHeader=false; 55 | PackComment=false; 56 | Locator=false; 57 | QOpenOffset=0; 58 | QOpenMaxSize=0; 59 | RROffset=0; 60 | RRMaxSize=0; 61 | } 62 | -------------------------------------------------------------------------------- /Libraries/unrar/isnt.cpp: -------------------------------------------------------------------------------- 1 | #include "rar.hpp" 2 | 3 | DWORD WinNT() 4 | { 5 | static int dwPlatformId=-1; 6 | static DWORD dwMajorVersion,dwMinorVersion; 7 | if (dwPlatformId==-1) 8 | { 9 | OSVERSIONINFO WinVer; 10 | WinVer.dwOSVersionInfoSize=sizeof(WinVer); 11 | GetVersionEx(&WinVer); 12 | dwPlatformId=WinVer.dwPlatformId; 13 | dwMajorVersion=WinVer.dwMajorVersion; 14 | dwMinorVersion=WinVer.dwMinorVersion; 15 | 16 | } 17 | DWORD Result=0; 18 | if (dwPlatformId==VER_PLATFORM_WIN32_NT) 19 | Result=dwMajorVersion*0x100+dwMinorVersion; 20 | 21 | 22 | return Result; 23 | } 24 | 25 | 26 | // Replace it with documented Windows 11 check when available. 27 | #include 28 | #include 29 | #pragma comment(lib, "wbemuuid.lib") 30 | 31 | static bool WMI_IsWindows10() 32 | { 33 | IWbemLocator *pLoc = NULL; 34 | 35 | HRESULT hres = CoCreateInstance(CLSID_WbemLocator,0,CLSCTX_INPROC_SERVER, 36 | IID_IWbemLocator,(LPVOID *)&pLoc); 37 | 38 | if (FAILED(hres)) 39 | return false; 40 | 41 | IWbemServices *pSvc = NULL; 42 | 43 | hres = pLoc->ConnectServer(_bstr_t(L"ROOT\\CIMV2"),NULL,NULL,0,NULL,0,0,&pSvc); 44 | 45 | if (FAILED(hres)) 46 | { 47 | pLoc->Release(); 48 | return false; 49 | } 50 | 51 | hres = CoSetProxyBlanket(pSvc,RPC_C_AUTHN_WINNT,RPC_C_AUTHZ_NONE,NULL, 52 | RPC_C_AUTHN_LEVEL_CALL,RPC_C_IMP_LEVEL_IMPERSONATE,NULL,EOAC_NONE); 53 | 54 | if (FAILED(hres)) 55 | { 56 | pSvc->Release(); 57 | pLoc->Release(); 58 | return false; 59 | } 60 | 61 | IEnumWbemClassObject *pEnumerator = NULL; 62 | hres = pSvc->ExecQuery(bstr_t("WQL"), bstr_t("SELECT * FROM Win32_OperatingSystem"), 63 | WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumerator); 64 | 65 | if (FAILED(hres)) 66 | { 67 | pSvc->Release(); 68 | pLoc->Release(); 69 | return false; 70 | } 71 | 72 | IWbemClassObject *pclsObj = NULL; 73 | ULONG uReturn = 0; 74 | 75 | bool Win10=false; 76 | while (pEnumerator!=NULL) 77 | { 78 | HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn); 79 | 80 | if (uReturn==0) 81 | break; 82 | 83 | VARIANT vtProp; 84 | 85 | hr = pclsObj->Get(L"Name", 0, &vtProp, 0, 0); 86 | Win10|=wcsstr(vtProp.bstrVal,L"Windows 10")!=NULL; 87 | VariantClear(&vtProp); 88 | 89 | pclsObj->Release(); 90 | } 91 | 92 | pSvc->Release(); 93 | pLoc->Release(); 94 | pEnumerator->Release(); 95 | 96 | return Win10; 97 | } 98 | 99 | 100 | // Replace it with actual check when available. 101 | bool IsWindows11OrGreater() 102 | { 103 | static bool IsSet=false,IsWin11=false; 104 | if (!IsSet) 105 | { 106 | OSVERSIONINFO WinVer; 107 | WinVer.dwOSVersionInfoSize=sizeof(WinVer); 108 | GetVersionEx(&WinVer); 109 | IsWin11=WinVer.dwMajorVersion>10 || 110 | WinVer.dwMajorVersion==10 && WinVer.dwBuildNumber >= 22000 && !WMI_IsWindows10(); 111 | IsSet=true; 112 | } 113 | return IsWin11; 114 | } 115 | -------------------------------------------------------------------------------- /Libraries/unrar/isnt.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _RAR_ISNT_ 2 | #define _RAR_ISNT_ 3 | 4 | enum WINNT_VERSION { 5 | WNT_NONE=0,WNT_NT351=0x0333,WNT_NT4=0x0400,WNT_W2000=0x0500, 6 | WNT_WXP=0x0501,WNT_W2003=0x0502,WNT_VISTA=0x0600,WNT_W7=0x0601, 7 | WNT_W8=0x0602,WNT_W81=0x0603,WNT_W10=0x0a00 8 | }; 9 | 10 | DWORD WinNT(); 11 | 12 | 13 | // Replace it with actual check when available. 14 | bool IsWindows11OrGreater(); 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /Libraries/unrar/license.txt: -------------------------------------------------------------------------------- 1 | ****** ***** ****** UnRAR - free utility for RAR archives 2 | ** ** ** ** ** ** ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 3 | ****** ******* ****** License for use and distribution of 4 | ** ** ** ** ** ** ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 5 | ** ** ** ** ** ** FREE portable version 6 | ~~~~~~~~~~~~~~~~~~~~~ 7 | 8 | The source code of UnRAR utility is freeware. This means: 9 | 10 | 1. All copyrights to RAR and the utility UnRAR are exclusively 11 | owned by the author - Alexander Roshal. 12 | 13 | 2. UnRAR source code may be used in any software to handle 14 | RAR archives without limitations free of charge, but cannot be 15 | used to develop RAR (WinRAR) compatible archiver and to 16 | re-create RAR compression algorithm, which is proprietary. 17 | Distribution of modified UnRAR source code in separate form 18 | or as a part of other software is permitted, provided that 19 | full text of this paragraph, starting from "UnRAR source code" 20 | words, is included in license, or in documentation if license 21 | is not available, and in source code comments of resulting package. 22 | 23 | 3. The UnRAR utility may be freely distributed. It is allowed 24 | to distribute UnRAR inside of other software packages. 25 | 26 | 4. THE RAR ARCHIVER AND THE UnRAR UTILITY ARE DISTRIBUTED "AS IS". 27 | NO WARRANTY OF ANY KIND IS EXPRESSED OR IMPLIED. YOU USE AT 28 | YOUR OWN RISK. THE AUTHOR WILL NOT BE LIABLE FOR DATA LOSS, 29 | DAMAGES, LOSS OF PROFITS OR ANY OTHER KIND OF LOSS WHILE USING 30 | OR MISUSING THIS SOFTWARE. 31 | 32 | 5. Installing and using the UnRAR utility signifies acceptance of 33 | these terms and conditions of the license. 34 | 35 | 6. If you don't agree with terms of the license you must remove 36 | UnRAR files from your storage devices and cease to use the 37 | utility. 38 | 39 | Thank you for your interest in RAR and UnRAR. 40 | 41 | 42 | Alexander L. Roshal 43 | -------------------------------------------------------------------------------- /Libraries/unrar/list.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _RAR_LIST_ 2 | #define _RAR_LIST_ 3 | 4 | void ListArchive(CommandData *Cmd); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /Libraries/unrar/log.cpp: -------------------------------------------------------------------------------- 1 | #include "rar.hpp" 2 | 3 | 4 | static wchar LogName[NM]; 5 | static RAR_CHARSET LogCharset=RCH_DEFAULT; 6 | 7 | void InitLogOptions(const wchar *LogFileName,RAR_CHARSET CSet) 8 | { 9 | wcsncpyz(LogName,LogFileName,ASIZE(LogName)); 10 | LogCharset=CSet; 11 | } 12 | 13 | 14 | #ifndef SILENT 15 | void Log(const wchar *ArcName,const wchar *fmt,...) 16 | { 17 | // Preserve the error code for possible following system error message. 18 | int Code=ErrHandler.GetSystemErrorCode(); 19 | 20 | uiAlarm(UIALARM_ERROR); 21 | 22 | // This buffer is for format string only, not for entire output, 23 | // so it can be short enough. 24 | wchar fmtw[1024]; 25 | PrintfPrepareFmt(fmt,fmtw,ASIZE(fmtw)); 26 | 27 | safebuf wchar Msg[2*NM+1024]; 28 | va_list arglist; 29 | va_start(arglist,fmt); 30 | vswprintf(Msg,ASIZE(Msg),fmtw,arglist); 31 | va_end(arglist); 32 | eprintf(L"%ls",Msg); 33 | ErrHandler.SetSystemErrorCode(Code); 34 | } 35 | #endif 36 | 37 | 38 | -------------------------------------------------------------------------------- /Libraries/unrar/log.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _RAR_LOG_ 2 | #define _RAR_LOG_ 3 | 4 | void InitLogOptions(const wchar *LogFileName,RAR_CHARSET CSet); 5 | 6 | #ifdef SILENT 7 | inline void Log(const wchar *ArcName,const wchar *fmt,...) {} 8 | #else 9 | void Log(const wchar *ArcName,const wchar *fmt,...); 10 | #endif 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /Libraries/unrar/match.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _RAR_MATCH_ 2 | #define _RAR_MATCH_ 3 | 4 | enum { 5 | MATCH_NAMES, // Paths are ignored. 6 | // Compares names only using wildcards. 7 | 8 | MATCH_SUBPATHONLY, // Paths must match either exactly or path in wildcard 9 | // must be present in the beginning of file path. 10 | // For example, "c:\path1\*" or "c:\path1" will match 11 | // "c:\path1\path2\file". 12 | // Names are not compared. 13 | 14 | MATCH_EXACT, // Paths must match exactly. 15 | // Names must match exactly. 16 | 17 | MATCH_ALLWILD, // Paths and names are compared using wildcards. 18 | // Unlike MATCH_SUBPATH, paths do not match subdirs 19 | // unless a wildcard tells so. 20 | 21 | MATCH_EXACTPATH, // Paths must match exactly. 22 | // Names are compared using wildcards. 23 | 24 | MATCH_SUBPATH, // Names must be the same, but path in mask is allowed 25 | // to be only a part of name path. In other words, 26 | // we match all files matching the file mask 27 | // in current folder and subfolders. 28 | 29 | MATCH_WILDSUBPATH // Works as MATCH_SUBPATH if file mask contains 30 | // wildcards and as MATCH_EXACTPATH otherwise. 31 | }; 32 | 33 | #define MATCH_MODEMASK 0x0000ffff 34 | #define MATCH_FORCECASESENSITIVE 0x80000000 35 | 36 | bool CmpName(const wchar *Wildcard,const wchar *Name,int CmpMode); 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /Libraries/unrar/model.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _RAR_PPMMODEL_ 2 | #define _RAR_PPMMODEL_ 3 | 4 | #include "coder.hpp" 5 | #include "suballoc.hpp" 6 | 7 | #ifdef ALLOW_MISALIGNED 8 | #pragma pack(1) 9 | #endif 10 | 11 | struct RARPPM_DEF 12 | { 13 | static const int INT_BITS=7, PERIOD_BITS=7, TOT_BITS=INT_BITS+PERIOD_BITS, 14 | INTERVAL=1 << INT_BITS, BIN_SCALE=1 << TOT_BITS, MAX_FREQ=124; 15 | }; 16 | 17 | struct RARPPM_SEE2_CONTEXT : RARPPM_DEF 18 | { // SEE-contexts for PPM-contexts with masked symbols 19 | ushort Summ; 20 | byte Shift, Count; 21 | void init(int InitVal) 22 | { 23 | Summ=InitVal << (Shift=PERIOD_BITS-4); 24 | Count=4; 25 | } 26 | uint getMean() 27 | { 28 | uint RetVal=GET_SHORT16(Summ) >> Shift; 29 | Summ -= RetVal; 30 | return RetVal+(RetVal == 0); 31 | } 32 | void update() 33 | { 34 | if (Shift < PERIOD_BITS && --Count == 0) 35 | { 36 | Summ += Summ; 37 | Count=3 << Shift++; 38 | } 39 | } 40 | }; 41 | 42 | 43 | class ModelPPM; 44 | struct RARPPM_CONTEXT; 45 | 46 | struct RARPPM_STATE 47 | { 48 | byte Symbol; 49 | byte Freq; 50 | RARPPM_CONTEXT* Successor; 51 | }; 52 | 53 | 54 | struct RARPPM_CONTEXT : RARPPM_DEF 55 | { 56 | ushort NumStats; 57 | 58 | struct FreqData 59 | { 60 | ushort SummFreq; 61 | RARPPM_STATE RARPPM_PACK_ATTR * Stats; 62 | }; 63 | 64 | union 65 | { 66 | FreqData U; 67 | RARPPM_STATE OneState; 68 | }; 69 | 70 | RARPPM_CONTEXT* Suffix; 71 | inline void encodeBinSymbol(ModelPPM *Model,int symbol); // MaxOrder: 72 | inline void encodeSymbol1(ModelPPM *Model,int symbol); // ABCD context 73 | inline void encodeSymbol2(ModelPPM *Model,int symbol); // BCD suffix 74 | inline void decodeBinSymbol(ModelPPM *Model); // BCDE successor 75 | inline bool decodeSymbol1(ModelPPM *Model); // other orders: 76 | inline bool decodeSymbol2(ModelPPM *Model); // BCD context 77 | inline void update1(ModelPPM *Model,RARPPM_STATE* p); // CD suffix 78 | inline void update2(ModelPPM *Model,RARPPM_STATE* p); // BCDE successor 79 | void rescale(ModelPPM *Model); 80 | inline RARPPM_CONTEXT* createChild(ModelPPM *Model,RARPPM_STATE* pStats,RARPPM_STATE& FirstState); 81 | inline RARPPM_SEE2_CONTEXT* makeEscFreq2(ModelPPM *Model,int Diff); 82 | }; 83 | 84 | #ifdef ALLOW_MISALIGNED 85 | #ifdef _AIX 86 | #pragma pack(pop) 87 | #else 88 | #pragma pack() 89 | #endif 90 | #endif 91 | 92 | class ModelPPM : RARPPM_DEF 93 | { 94 | private: 95 | friend struct RARPPM_CONTEXT; 96 | 97 | RARPPM_SEE2_CONTEXT SEE2Cont[25][16], DummySEE2Cont; 98 | 99 | struct RARPPM_CONTEXT *MinContext, *MedContext, *MaxContext; 100 | RARPPM_STATE* FoundState; // found next state transition 101 | int NumMasked, InitEsc, OrderFall, MaxOrder, RunLength, InitRL; 102 | byte CharMask[256], NS2Indx[256], NS2BSIndx[256], HB2Flag[256]; 103 | byte EscCount, PrevSuccess, HiBitsFlag; 104 | ushort BinSumm[128][64]; // binary SEE-contexts 105 | 106 | RangeCoder Coder; 107 | SubAllocator SubAlloc; 108 | 109 | void RestartModelRare(); 110 | void StartModelRare(int MaxOrder); 111 | inline RARPPM_CONTEXT* CreateSuccessors(bool Skip,RARPPM_STATE* p1); 112 | 113 | inline void UpdateModel(); 114 | inline void ClearMask(); 115 | public: 116 | ModelPPM(); 117 | void CleanUp(); // reset PPM variables after data error 118 | bool DecodeInit(Unpack *UnpackRead,int &EscChar); 119 | int DecodeChar(); 120 | }; 121 | 122 | #endif 123 | -------------------------------------------------------------------------------- /Libraries/unrar/options.cpp: -------------------------------------------------------------------------------- 1 | #include "rar.hpp" 2 | 3 | RAROptions::RAROptions() 4 | { 5 | Init(); 6 | } 7 | 8 | 9 | RAROptions::~RAROptions() 10 | { 11 | // It is important for security reasons, so we do not have the unnecessary 12 | // password data left in memory. 13 | memset(this,0,sizeof(RAROptions)); 14 | } 15 | 16 | 17 | void RAROptions::Init() 18 | { 19 | memset(this,0,sizeof(RAROptions)); 20 | WinSize=0x2000000; 21 | Overwrite=OVERWRITE_DEFAULT; 22 | Method=3; 23 | MsgStream=MSG_STDOUT; 24 | ConvertNames=NAMES_ORIGINALCASE; 25 | xmtime=EXTTIME_MAX; 26 | FileSizeLess=INT64NDF; 27 | FileSizeMore=INT64NDF; 28 | HashType=HASH_CRC32; 29 | #ifdef RAR_SMP 30 | Threads=GetNumberOfThreads(); 31 | #endif 32 | #ifdef USE_QOPEN 33 | QOpenMode=QOPEN_AUTO; 34 | #endif 35 | } 36 | -------------------------------------------------------------------------------- /Libraries/unrar/pathfn.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _RAR_PATHFN_ 2 | #define _RAR_PATHFN_ 3 | 4 | wchar* PointToName(const wchar *Path); 5 | wchar* PointToLastChar(const wchar *Path); 6 | wchar* ConvertPath(const wchar *SrcPath,wchar *DestPath,size_t DestSize); 7 | void SetName(wchar *FullName,const wchar *Name,size_t MaxSize); 8 | void SetExt(wchar *Name,const wchar *NewExt,size_t MaxSize); 9 | void SetSFXExt(wchar *SFXName,size_t MaxSize); 10 | wchar *GetExt(const wchar *Name); 11 | bool CmpExt(const wchar *Name,const wchar *Ext); 12 | bool IsWildcard(const wchar *Str); 13 | bool IsPathDiv(int Ch); 14 | bool IsDriveDiv(int Ch); 15 | bool IsDriveLetter(const wchar *Path); 16 | int GetPathDisk(const wchar *Path); 17 | void AddEndSlash(wchar *Path,size_t MaxLength); 18 | void MakeName(const wchar *Path,const wchar *Name,wchar *Pathname,size_t MaxSize); 19 | void GetFilePath(const wchar *FullName,wchar *Path,size_t MaxLength); 20 | void RemoveNameFromPath(wchar *Path); 21 | #if defined(_WIN_ALL) && !defined(SFX_MODULE) 22 | bool GetAppDataPath(wchar *Path,size_t MaxSize,bool Create); 23 | void GetRarDataPath(wchar *Path,size_t MaxSize,bool Create); 24 | #endif 25 | #ifndef SFX_MODULE 26 | bool EnumConfigPaths(uint Number,wchar *Path,size_t MaxSize,bool Create); 27 | void GetConfigName(const wchar *Name,wchar *FullName,size_t MaxSize,bool CheckExist,bool Create); 28 | #endif 29 | wchar* GetVolNumPart(const wchar *ArcName); 30 | void NextVolumeName(wchar *ArcName,uint MaxLength,bool OldNumbering); 31 | bool IsNameUsable(const wchar *Name); 32 | void MakeNameUsable(char *Name,bool Extended); 33 | void MakeNameUsable(wchar *Name,bool Extended); 34 | 35 | void UnixSlashToDos(const char *SrcName,char *DestName,size_t MaxLength); 36 | void DosSlashToUnix(const char *SrcName,char *DestName,size_t MaxLength); 37 | void UnixSlashToDos(const wchar *SrcName,wchar *DestName,size_t MaxLength); 38 | void DosSlashToUnix(const wchar *SrcName,wchar *DestName,size_t MaxLength); 39 | 40 | inline void SlashToNative(const char *SrcName,char *DestName,size_t MaxLength) 41 | { 42 | #ifdef _WIN_ALL 43 | UnixSlashToDos(SrcName,DestName,MaxLength); 44 | #else 45 | DosSlashToUnix(SrcName,DestName,MaxLength); 46 | #endif 47 | } 48 | 49 | inline void SlashToNative(const wchar *SrcName,wchar *DestName,size_t MaxLength) 50 | { 51 | #ifdef _WIN_ALL 52 | UnixSlashToDos(SrcName,DestName,MaxLength); 53 | #else 54 | DosSlashToUnix(SrcName,DestName,MaxLength); 55 | #endif 56 | } 57 | 58 | void ConvertNameToFull(const wchar *Src,wchar *Dest,size_t MaxSize); 59 | bool IsFullPath(const wchar *Path); 60 | bool IsFullRootPath(const wchar *Path); 61 | void GetPathRoot(const wchar *Path,wchar *Root,size_t MaxSize); 62 | int ParseVersionFileName(wchar *Name,bool Truncate); 63 | wchar* VolNameToFirstName(const wchar *VolName,wchar *FirstName,size_t MaxSize,bool NewNumbering); 64 | wchar* GetWideName(const char *Name,const wchar *NameW,wchar *DestW,size_t DestSize); 65 | 66 | #ifndef SFX_MODULE 67 | void GenerateArchiveName(wchar *ArcName,size_t MaxSize,const wchar *GenerateMask,bool Archiving); 68 | #endif 69 | 70 | #ifdef _WIN_ALL 71 | bool GetWinLongPath(const wchar *Src,wchar *Dest,size_t MaxSize); 72 | void ConvertToPrecomposed(wchar *Name,size_t NameSize); 73 | void MakeNameCompatible(wchar *Name,size_t MaxSize); 74 | #endif 75 | 76 | 77 | #endif 78 | -------------------------------------------------------------------------------- /Libraries/unrar/qopen.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _RAR_QOPEN_ 2 | #define _RAR_QOPEN_ 3 | 4 | struct QuickOpenItem 5 | { 6 | byte *Header; 7 | size_t HeaderSize; 8 | uint64 ArcPos; 9 | QuickOpenItem *Next; 10 | }; 11 | 12 | 13 | class Archive; 14 | class RawRead; 15 | 16 | class QuickOpen 17 | { 18 | private: 19 | void Close(); 20 | 21 | 22 | uint ReadBuffer(); 23 | bool ReadRaw(RawRead &Raw); 24 | bool ReadNext(); 25 | 26 | Archive *Arc; 27 | bool WriteMode; 28 | 29 | QuickOpenItem *ListStart; 30 | QuickOpenItem *ListEnd; 31 | 32 | byte *Buf; // Read quick open data here. 33 | static const size_t MaxBufSize=0x10000; // Buf size, must be multiple of CRYPT_BLOCK_SIZE. 34 | size_t CurBufSize; // Current size of buffered data in write mode. 35 | #ifndef RAR_NOCRYPT // For shell extension. 36 | CryptData Crypt; 37 | #endif 38 | 39 | bool Loaded; 40 | uint64 QOHeaderPos; // Main QO header position. 41 | uint64 RawDataStart; // Start of QO data, just after the main header. 42 | uint64 RawDataSize; // Size of entire QO data. 43 | uint64 RawDataPos; // Current read position in QO data. 44 | size_t ReadBufSize; // Size of Buf data currently read from QO. 45 | size_t ReadBufPos; // Current read position in Buf data. 46 | Array LastReadHeader; 47 | uint64 LastReadHeaderPos; 48 | uint64 SeekPos; 49 | bool UnsyncSeekPos; // QOpen SeekPos does not match an actual file pointer. 50 | public: 51 | QuickOpen(); 52 | ~QuickOpen(); 53 | void Init(Archive *Arc,bool WriteMode); 54 | void Load(uint64 BlockPos); 55 | void Unload() { Loaded=false; } 56 | bool Read(void *Data,size_t Size,size_t &Result); 57 | bool Seek(int64 Offset,int Method); 58 | bool Tell(int64 *Pos); 59 | }; 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /Libraries/unrar/rar.cpp: -------------------------------------------------------------------------------- 1 | #include "rar.hpp" 2 | 3 | #if !defined(RARDLL) 4 | int main(int argc, char *argv[]) 5 | { 6 | 7 | #ifdef _UNIX 8 | setlocale(LC_ALL,""); 9 | #endif 10 | 11 | InitConsole(); 12 | ErrHandler.SetSignalHandlers(true); 13 | 14 | #ifdef SFX_MODULE 15 | wchar ModuleName[NM]; 16 | #ifdef _WIN_ALL 17 | GetModuleFileName(NULL,ModuleName,ASIZE(ModuleName)); 18 | #else 19 | CharToWide(argv[0],ModuleName,ASIZE(ModuleName)); 20 | #endif 21 | #endif 22 | 23 | #ifdef _WIN_ALL 24 | SetErrorMode(SEM_NOALIGNMENTFAULTEXCEPT|SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX); 25 | 26 | 27 | #endif 28 | 29 | #if defined(_WIN_ALL) && !defined(SFX_MODULE) 30 | // Must be initialized, normal initialization can be skipped in case of 31 | // exception. 32 | POWER_MODE ShutdownOnClose=POWERMODE_KEEP; 33 | #endif 34 | 35 | try 36 | { 37 | 38 | CommandData *Cmd=new CommandData; 39 | #ifdef SFX_MODULE 40 | wcsncpyz(Cmd->Command,L"X",ASIZE(Cmd->Command)); 41 | char *Switch=argc>1 ? argv[1]:NULL; 42 | if (Switch!=NULL && Cmd->IsSwitch(Switch[0])) 43 | { 44 | int UpperCmd=etoupper(Switch[1]); 45 | switch(UpperCmd) 46 | { 47 | case 'T': 48 | case 'V': 49 | Cmd->Command[0]=UpperCmd; 50 | break; 51 | case '?': 52 | Cmd->OutHelp(RARX_SUCCESS); 53 | break; 54 | } 55 | } 56 | Cmd->AddArcName(ModuleName); 57 | Cmd->ParseDone(); 58 | Cmd->AbsoluteLinks=true; // If users runs SFX, he trusts an archive source. 59 | #else // !SFX_MODULE 60 | Cmd->ParseCommandLine(true,argc,argv); 61 | if (!Cmd->ConfigDisabled) 62 | { 63 | Cmd->ReadConfig(); 64 | Cmd->ParseEnvVar(); 65 | } 66 | Cmd->ParseCommandLine(false,argc,argv); 67 | #endif 68 | 69 | #if defined(_WIN_ALL) && !defined(SFX_MODULE) 70 | ShutdownOnClose=Cmd->Shutdown; 71 | if (ShutdownOnClose) 72 | ShutdownCheckAnother(true); 73 | #endif 74 | 75 | uiInit(Cmd->Sound); 76 | InitLogOptions(Cmd->LogName,Cmd->ErrlogCharset); 77 | ErrHandler.SetSilent(Cmd->AllYes || Cmd->MsgStream==MSG_NULL); 78 | 79 | Cmd->OutTitle(); 80 | Cmd->ProcessCommand(); 81 | delete Cmd; 82 | } 83 | catch (RAR_EXIT ErrCode) 84 | { 85 | ErrHandler.SetErrorCode(ErrCode); 86 | } 87 | catch (std::bad_alloc&) 88 | { 89 | ErrHandler.MemoryErrorMsg(); 90 | ErrHandler.SetErrorCode(RARX_MEMORY); 91 | } 92 | catch (...) 93 | { 94 | ErrHandler.SetErrorCode(RARX_FATAL); 95 | } 96 | 97 | #if defined(_WIN_ALL) && !defined(SFX_MODULE) 98 | if (ShutdownOnClose!=POWERMODE_KEEP && ErrHandler.IsShutdownEnabled() && 99 | !ShutdownCheckAnother(false)) 100 | Shutdown(ShutdownOnClose); 101 | #endif 102 | ErrHandler.MainExit=true; 103 | return ErrHandler.GetErrorCode(); 104 | } 105 | #endif 106 | 107 | 108 | -------------------------------------------------------------------------------- /Libraries/unrar/rar.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _RAR_RARCOMMON_ 2 | #define _RAR_RARCOMMON_ 3 | 4 | #include "raros.hpp" 5 | #include "rartypes.hpp" 6 | #include "os.hpp" 7 | 8 | #ifdef RARDLL 9 | #include "dll.hpp" 10 | #endif 11 | 12 | #include "version.hpp" 13 | #include "rardefs.hpp" 14 | #include "rarlang.hpp" 15 | #include "unicode.hpp" 16 | #include "errhnd.hpp" 17 | #include "secpassword.hpp" 18 | #include "array.hpp" 19 | #include "strlist.hpp" 20 | #include "timefn.hpp" 21 | #include "sha1.hpp" 22 | #include "sha256.hpp" 23 | #include "blake2s.hpp" 24 | #include "hash.hpp" 25 | #include "options.hpp" 26 | #include "rijndael.hpp" 27 | #include "crypt.hpp" 28 | #include "headers5.hpp" 29 | #include "headers.hpp" 30 | #include "pathfn.hpp" 31 | #include "strfn.hpp" 32 | #ifdef _WIN_ALL 33 | #include "isnt.hpp" 34 | #endif 35 | #include "file.hpp" 36 | #include "crc.hpp" 37 | #include "ui.hpp" 38 | #include "filefn.hpp" 39 | #include "filestr.hpp" 40 | #include "find.hpp" 41 | #include "scantree.hpp" 42 | #include "getbits.hpp" 43 | #include "rdwrfn.hpp" 44 | #ifdef USE_QOPEN 45 | #include "qopen.hpp" 46 | #endif 47 | #include "archive.hpp" 48 | #include "match.hpp" 49 | #include "cmddata.hpp" 50 | #include "filcreat.hpp" 51 | #include "consio.hpp" 52 | #include "system.hpp" 53 | #include "log.hpp" 54 | #include "rawint.hpp" 55 | #include "rawread.hpp" 56 | #include "encname.hpp" 57 | #include "resource.hpp" 58 | #include "compress.hpp" 59 | 60 | #include "rarvm.hpp" 61 | #include "model.hpp" 62 | 63 | #include "threadpool.hpp" 64 | 65 | #include "unpack.hpp" 66 | 67 | 68 | 69 | #include "extinfo.hpp" 70 | #include "extract.hpp" 71 | 72 | 73 | 74 | #include "list.hpp" 75 | 76 | 77 | #include "rs.hpp" 78 | #include "rs16.hpp" 79 | 80 | 81 | 82 | #include "recvol.hpp" 83 | #include "volume.hpp" 84 | #include "smallfn.hpp" 85 | 86 | #include "global.hpp" 87 | 88 | #if 0 89 | #include "benchmark.hpp" 90 | #endif 91 | 92 | 93 | 94 | 95 | 96 | #endif 97 | -------------------------------------------------------------------------------- /Libraries/unrar/rardefs.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _RAR_DEFS_ 2 | #define _RAR_DEFS_ 3 | 4 | #define Min(x,y) (((x)<(y)) ? (x):(y)) 5 | #define Max(x,y) (((x)>(y)) ? (x):(y)) 6 | 7 | // Universal replacement of abs function. 8 | #define Abs(x) (((x)<0) ? -(x):(x)) 9 | 10 | #define ASIZE(x) (sizeof(x)/sizeof(x[0])) 11 | 12 | // MAXPASSWORD is expected to be multiple of CRYPTPROTECTMEMORY_BLOCK_SIZE (16) 13 | // for CryptProtectMemory in SecPassword. 14 | #define MAXPASSWORD 128 15 | 16 | #define MAXSFXSIZE 0x200000 17 | 18 | #define MAXCMTSIZE 0x40000 19 | 20 | #define DefSFXName L"default.sfx" 21 | #define DefSortListName L"rarfiles.lst" 22 | 23 | 24 | #ifndef SFX_MODULE 25 | #define USE_QOPEN 26 | #endif 27 | 28 | // Produce the value, which is equal or larger than 'v' and aligned to 'a'. 29 | #define ALIGN_VALUE(v,a) (size_t(v) + ( (~size_t(v) + 1) & (a - 1) ) ) 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /Libraries/unrar/rarlang.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _RAR_LANG_ 2 | #define _RAR_LANG_ 3 | 4 | #ifdef USE_RC 5 | #include "rarres.hpp" 6 | #else 7 | #include "loclang.hpp" 8 | #endif 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /Libraries/unrar/raros.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _RAR_RAROS_ 2 | #define _RAR_RAROS_ 3 | 4 | #ifdef __EMX__ 5 | #define _EMX 6 | #endif 7 | 8 | #ifdef __DJGPP__ 9 | #define _DJGPP 10 | #define _EMX 11 | #endif 12 | 13 | #if defined(__WIN32__) || defined(_WIN32) 14 | #define _WIN_ALL // Defined for all Windows platforms, 32 and 64 bit, mobile and desktop. 15 | #ifdef _M_X64 16 | #define _WIN_64 17 | #else 18 | #define _WIN_32 19 | #endif 20 | #endif 21 | 22 | #if defined(ANDROID) || defined(__ANDROID__) 23 | #define _UNIX 24 | #define _ANDROID 25 | #endif 26 | 27 | #ifdef __APPLE__ 28 | #define _UNIX 29 | #define _APPLE 30 | #endif 31 | 32 | #if !defined(_EMX) && !defined(_WIN_ALL) && !defined(_BEOS) && !defined(_APPLE) 33 | #define _UNIX 34 | #endif 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /Libraries/unrar/rarpch.cpp: -------------------------------------------------------------------------------- 1 | // We use rarpch.cpp to create precompiled headers for MS Visual C++. 2 | #include "rar.hpp" 3 | -------------------------------------------------------------------------------- /Libraries/unrar/rartypes.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _RAR_TYPES_ 2 | #define _RAR_TYPES_ 3 | 4 | #include 5 | 6 | typedef uint8_t byte; // Unsigned 8 bits. 7 | typedef uint16_t ushort; // Preferably 16 bits, but can be more. 8 | typedef unsigned int uint; // 32 bits or more. 9 | typedef uint32_t uint32; // 32 bits exactly. 10 | typedef int32_t int32; // Signed 32 bits exactly. 11 | typedef uint64_t uint64; // 64 bits exactly. 12 | typedef int64_t int64; // Signed 64 bits exactly. 13 | typedef wchar_t wchar; // Unicode character 14 | 15 | // Get lowest 16 bits. 16 | #define GET_SHORT16(x) (sizeof(ushort)==2 ? (ushort)(x):((x)&0xffff)) 17 | 18 | // Make 64 bit integer from two 32 bit. 19 | #define INT32TO64(high,low) ((((uint64)(high))<<32)+((uint64)low)) 20 | 21 | // Maximum int64 value. 22 | #define MAX_INT64 int64(INT32TO64(0x7fffffff,0xffffffff)) 23 | 24 | // Special int64 value, large enough to never be found in real life 25 | // and small enough to fit to both signed and unsigned 64-bit ints. 26 | // We use it in situations, when we need to indicate that parameter 27 | // is not defined and probably should be calculated inside of function. 28 | // Lower part is intentionally 0x7fffffff, not 0xffffffff, to make it 29 | // compatible with 32 bit int64 if 64 bit type is not supported. 30 | #define INT64NDF INT32TO64(0x7fffffff,0x7fffffff) 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /Libraries/unrar/rarvm.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _RAR_VM_ 2 | #define _RAR_VM_ 3 | 4 | #define VM_MEMSIZE 0x40000 5 | #define VM_MEMMASK (VM_MEMSIZE-1) 6 | 7 | enum VM_StandardFilters { 8 | VMSF_NONE, VMSF_E8, VMSF_E8E9, VMSF_ITANIUM, VMSF_RGB, VMSF_AUDIO, 9 | VMSF_DELTA 10 | }; 11 | 12 | struct VM_PreparedProgram 13 | { 14 | VM_PreparedProgram() 15 | { 16 | FilteredDataSize=0; 17 | Type=VMSF_NONE; 18 | } 19 | VM_StandardFilters Type; 20 | uint InitR[7]; 21 | byte *FilteredData; 22 | uint FilteredDataSize; 23 | }; 24 | 25 | class RarVM 26 | { 27 | private: 28 | bool ExecuteStandardFilter(VM_StandardFilters FilterType); 29 | uint FilterItanium_GetBits(byte *Data,uint BitPos,uint BitCount); 30 | void FilterItanium_SetBits(byte *Data,uint BitField,uint BitPos,uint BitCount); 31 | 32 | byte *Mem; 33 | uint R[8]; 34 | public: 35 | RarVM(); 36 | ~RarVM(); 37 | void Init(); 38 | void Prepare(byte *Code,uint CodeSize,VM_PreparedProgram *Prg); 39 | void Execute(VM_PreparedProgram *Prg); 40 | void SetMemory(size_t Pos,byte *Data,size_t DataSize); 41 | static uint ReadData(BitInput &Inp); 42 | }; 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /Libraries/unrar/rawint.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _RAR_RAWINT_ 2 | #define _RAR_RAWINT_ 3 | 4 | #define rotls(x,n,xsize) (((x)<<(n)) | ((x)>>(xsize-(n)))) 5 | #define rotrs(x,n,xsize) (((x)>>(n)) | ((x)<<(xsize-(n)))) 6 | #define rotl32(x,n) rotls(x,n,32) 7 | #define rotr32(x,n) rotrs(x,n,32) 8 | 9 | inline uint RawGet2(const void *Data) 10 | { 11 | byte *D=(byte *)Data; 12 | return D[0]+(D[1]<<8); 13 | } 14 | 15 | 16 | inline uint32 RawGet4(const void *Data) 17 | { 18 | #if defined(BIG_ENDIAN) || !defined(ALLOW_MISALIGNED) 19 | byte *D=(byte *)Data; 20 | return D[0]+(D[1]<<8)+(D[2]<<16)+(D[3]<<24); 21 | #else 22 | return *(uint32 *)Data; 23 | #endif 24 | } 25 | 26 | 27 | inline uint64 RawGet8(const void *Data) 28 | { 29 | #if defined(BIG_ENDIAN) || !defined(ALLOW_MISALIGNED) 30 | byte *D=(byte *)Data; 31 | return INT32TO64(RawGet4(D+4),RawGet4(D)); 32 | #else 33 | return *(uint64 *)Data; 34 | #endif 35 | } 36 | 37 | 38 | inline void RawPut2(uint Field,void *Data) 39 | { 40 | byte *D=(byte *)Data; 41 | D[0]=(byte)(Field); 42 | D[1]=(byte)(Field>>8); 43 | } 44 | 45 | 46 | inline void RawPut4(uint32 Field,void *Data) 47 | { 48 | #if defined(BIG_ENDIAN) || !defined(ALLOW_MISALIGNED) 49 | byte *D=(byte *)Data; 50 | D[0]=(byte)(Field); 51 | D[1]=(byte)(Field>>8); 52 | D[2]=(byte)(Field>>16); 53 | D[3]=(byte)(Field>>24); 54 | #else 55 | *(uint32 *)Data=Field; 56 | #endif 57 | } 58 | 59 | 60 | inline void RawPut8(uint64 Field,void *Data) 61 | { 62 | #if defined(BIG_ENDIAN) || !defined(ALLOW_MISALIGNED) 63 | byte *D=(byte *)Data; 64 | D[0]=(byte)(Field); 65 | D[1]=(byte)(Field>>8); 66 | D[2]=(byte)(Field>>16); 67 | D[3]=(byte)(Field>>24); 68 | D[4]=(byte)(Field>>32); 69 | D[5]=(byte)(Field>>40); 70 | D[6]=(byte)(Field>>48); 71 | D[7]=(byte)(Field>>56); 72 | #else 73 | *(uint64 *)Data=Field; 74 | #endif 75 | } 76 | 77 | 78 | #if defined(LITTLE_ENDIAN) && defined(ALLOW_MISALIGNED) 79 | #define USE_MEM_BYTESWAP 80 | #endif 81 | 82 | // Load 4 big endian bytes from memory and return uint32. 83 | inline uint32 RawGetBE4(const byte *m) 84 | { 85 | #if defined(USE_MEM_BYTESWAP) && defined(_MSC_VER) 86 | return _byteswap_ulong(*(uint32 *)m); 87 | #elif defined(USE_MEM_BYTESWAP) && (__GNUC__ > 3) && (__GNUC_MINOR__ > 2) 88 | return __builtin_bswap32(*(uint32 *)m); 89 | #else 90 | return uint32(m[0]<<24) | uint32(m[1]<<16) | uint32(m[2]<<8) | m[3]; 91 | #endif 92 | } 93 | 94 | 95 | // Save integer to memory as big endian. 96 | inline void RawPutBE4(uint32 i,byte *mem) 97 | { 98 | #if defined(USE_MEM_BYTESWAP) && defined(_MSC_VER) 99 | *(uint32*)mem = _byteswap_ulong(i); 100 | #elif defined(USE_MEM_BYTESWAP) && (__GNUC__ > 3) && (__GNUC_MINOR__ > 2) 101 | *(uint32*)mem = __builtin_bswap32(i); 102 | #else 103 | mem[0]=byte(i>>24); 104 | mem[1]=byte(i>>16); 105 | mem[2]=byte(i>>8); 106 | mem[3]=byte(i); 107 | #endif 108 | } 109 | 110 | 111 | inline uint32 ByteSwap32(uint32 i) 112 | { 113 | #ifdef _MSC_VER 114 | return _byteswap_ulong(i); 115 | #elif (__GNUC__ > 3) && (__GNUC_MINOR__ > 2) 116 | return __builtin_bswap32(i); 117 | #else 118 | return (rotl32(i,24)&0xFF00FF00)|(rotl32(i,8)&0x00FF00FF); 119 | #endif 120 | } 121 | 122 | #endif 123 | -------------------------------------------------------------------------------- /Libraries/unrar/rawread.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _RAR_RAWREAD_ 2 | #define _RAR_RAWREAD_ 3 | 4 | class RawRead 5 | { 6 | private: 7 | Array Data; 8 | File *SrcFile; 9 | size_t DataSize; 10 | size_t ReadPos; 11 | CryptData *Crypt; 12 | public: 13 | RawRead(); 14 | RawRead(File *SrcFile); 15 | void Reset(); 16 | size_t Read(size_t Size); 17 | void Read(byte *SrcData,size_t Size); 18 | byte Get1(); 19 | ushort Get2(); 20 | uint Get4(); 21 | uint64 Get8(); 22 | uint64 GetV(); 23 | uint GetVSize(size_t Pos); 24 | size_t GetB(void *Field,size_t Size); 25 | void GetW(wchar *Field,size_t Size); 26 | uint GetCRC15(bool ProcessedOnly); 27 | uint GetCRC50(); 28 | byte* GetDataPtr() {return &Data[0];} 29 | size_t Size() {return DataSize;} 30 | size_t PaddedSize() {return Data.Size()-DataSize;} 31 | size_t DataLeft() {return DataSize-ReadPos;} 32 | size_t GetPos() {return ReadPos;} 33 | void SetPos(size_t Pos) {ReadPos=Pos;} 34 | void Skip(size_t Size) {ReadPos+=Size;} 35 | void Rewind() {SetPos(0);} 36 | void SetCrypt(CryptData *Crypt) {RawRead::Crypt=Crypt;} 37 | }; 38 | 39 | uint64 RawGetV(const byte *Data,uint &ReadPos,uint DataSize,bool &Overflow); 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /Libraries/unrar/rdwrfn.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _RAR_DATAIO_ 2 | #define _RAR_DATAIO_ 3 | 4 | class Archive; 5 | class CmdAdd; 6 | class Unpack; 7 | class ArcFileSearch; 8 | 9 | #if 0 10 | // We use external i/o calls for Benchmark command. 11 | #define COMPRDATAIO_EXTIO 12 | #endif 13 | 14 | class ComprDataIO 15 | { 16 | private: 17 | void ShowUnpRead(int64 ArcPos,int64 ArcSize); 18 | void ShowUnpWrite(); 19 | 20 | 21 | bool UnpackFromMemory; 22 | size_t UnpackFromMemorySize; 23 | byte *UnpackFromMemoryAddr; 24 | 25 | bool UnpackToMemory; 26 | size_t UnpackToMemorySize; 27 | byte *UnpackToMemoryAddr; 28 | 29 | size_t UnpWrSize; 30 | byte *UnpWrAddr; 31 | 32 | int64 UnpPackedSize; 33 | int64 UnpPackedLeft; 34 | 35 | bool ShowProgress; 36 | bool TestMode; 37 | bool SkipUnpCRC; 38 | bool NoFileHeader; 39 | 40 | File *SrcFile; 41 | File *DestFile; 42 | 43 | CmdAdd *Command; 44 | 45 | FileHeader *SubHead; 46 | int64 *SubHeadPos; 47 | 48 | #ifndef RAR_NOCRYPT 49 | CryptData *Crypt; 50 | CryptData *Decrypt; 51 | #endif 52 | 53 | 54 | int LastPercent; 55 | 56 | wchar CurrentCommand; 57 | 58 | public: 59 | ComprDataIO(); 60 | ~ComprDataIO(); 61 | void Init(); 62 | int UnpRead(byte *Addr,size_t Count); 63 | void UnpWrite(byte *Addr,size_t Count); 64 | void EnableShowProgress(bool Show) {ShowProgress=Show;} 65 | void GetUnpackedData(byte **Data,size_t *Size); 66 | void SetPackedSizeToRead(int64 Size) {UnpPackedSize=UnpPackedLeft=Size;} 67 | void SetTestMode(bool Mode) {TestMode=Mode;} 68 | void SetSkipUnpCRC(bool Skip) {SkipUnpCRC=Skip;} 69 | void SetNoFileHeader(bool Mode) {NoFileHeader=Mode;} 70 | void SetFiles(File *SrcFile,File *DestFile); 71 | void SetCommand(CmdAdd *Cmd) {Command=Cmd;} 72 | void SetSubHeader(FileHeader *hd,int64 *Pos) {SubHead=hd;SubHeadPos=Pos;} 73 | void SetEncryption(bool Encrypt,CRYPT_METHOD Method,SecPassword *Password, 74 | const byte *Salt,const byte *InitV,uint Lg2Cnt,byte *HashKey,byte *PswCheck); 75 | void SetAV15Encryption(); 76 | void SetCmt13Encryption(); 77 | void SetUnpackToMemory(byte *Addr,uint Size); 78 | void SetCurrentCommand(wchar Cmd) {CurrentCommand=Cmd;} 79 | void AdjustTotalArcSize(Archive *Arc); 80 | 81 | 82 | bool PackVolume; 83 | bool UnpVolume; 84 | bool NextVolumeMissing; 85 | int64 CurPackRead,CurPackWrite,CurUnpRead,CurUnpWrite; 86 | 87 | 88 | // Size of already processed archives. 89 | // Used to calculate the total operation progress. 90 | int64 ProcessedArcSize; 91 | 92 | // Last extracted archive size up to QO or RR block. 93 | int64 LastArcSize; 94 | 95 | int64 TotalArcSize; 96 | 97 | DataHash PackedDataHash; // Packed write and unpack read hash. 98 | DataHash PackHash; // Pack read hash. 99 | DataHash UnpHash; // Unpack write hash. 100 | 101 | bool Encryption; 102 | bool Decryption; 103 | }; 104 | 105 | #endif 106 | -------------------------------------------------------------------------------- /Libraries/unrar/readme.txt: -------------------------------------------------------------------------------- 1 | 2 | Portable UnRAR version 3 | 4 | 5 | 1. General 6 | 7 | This package includes freeware Unrar C++ source and makefile for 8 | several Unix compilers. 9 | 10 | Unrar source is subset of RAR and generated from RAR source automatically, 11 | by a small program removing blocks like '#ifndef UNRAR ... #endif'. 12 | Such method is not perfect and you may find some RAR related stuff 13 | unnecessary in Unrar, especially in header files. 14 | 15 | If you wish to port Unrar to a new platform, you may need to edit 16 | '#define LITTLE_ENDIAN' in os.hpp and data type definitions 17 | in rartypes.hpp. 18 | 19 | if computer architecture does not allow not aligned data access, 20 | you need to undefine ALLOW_NOT_ALIGNED_INT and define 21 | STRICT_ALIGNMENT_REQUIRED in os.h. 22 | 23 | UnRAR.vcproj and UnRARDll.vcproj are projects for Microsoft Visual C++. 24 | UnRARDll.vcproj lets to build unrar.dll library. 25 | 26 | 27 | 2. Unrar binaries 28 | 29 | If you compiled Unrar for OS, which is not present in "Downloads" 30 | and "RAR extras" on www.rarlab.com, we will appreciate if you send 31 | us the compiled executable to place it to our site. 32 | 33 | 34 | 3. Acknowledgements 35 | 36 | This source includes parts of code written by other authors. 37 | Please see acknow.txt file for details. 38 | 39 | 40 | 4. Legal stuff 41 | 42 | Unrar source may be used in any software to handle RAR archives 43 | without limitations free of charge, but cannot be used to re-create 44 | the RAR compression algorithm, which is proprietary. Distribution 45 | of modified Unrar source in separate form or as a part of other 46 | software is permitted, provided that it is clearly stated in 47 | the documentation and source comments that the code may not be used 48 | to develop a RAR (WinRAR) compatible archiver. 49 | 50 | More detailed license text is available in license.txt. 51 | -------------------------------------------------------------------------------- /Libraries/unrar/recvol.cpp: -------------------------------------------------------------------------------- 1 | #include "rar.hpp" 2 | 3 | #include "recvol3.cpp" 4 | #include "recvol5.cpp" 5 | 6 | 7 | 8 | bool RecVolumesRestore(RAROptions *Cmd,const wchar *Name,bool Silent) 9 | { 10 | Archive Arc(Cmd); 11 | if (!Arc.Open(Name)) 12 | { 13 | if (!Silent) 14 | ErrHandler.OpenErrorMsg(Name); 15 | return false; 16 | } 17 | 18 | RARFORMAT Fmt=RARFMT15; 19 | if (Arc.IsArchive(true)) 20 | Fmt=Arc.Format; 21 | else 22 | { 23 | byte Sign[REV5_SIGN_SIZE]; 24 | Arc.Seek(0,SEEK_SET); 25 | if (Arc.Read(Sign,REV5_SIGN_SIZE)==REV5_SIGN_SIZE && memcmp(Sign,REV5_SIGN,REV5_SIGN_SIZE)==0) 26 | Fmt=RARFMT50; 27 | } 28 | Arc.Close(); 29 | 30 | // We define RecVol as local variable for proper stack unwinding when 31 | // handling exceptions. So it can close and delete files on Cancel. 32 | if (Fmt==RARFMT15) 33 | { 34 | RecVolumes3 RecVol(Cmd,false); 35 | return RecVol.Restore(Cmd,Name,Silent); 36 | } 37 | else 38 | { 39 | RecVolumes5 RecVol(Cmd,false); 40 | return RecVol.Restore(Cmd,Name,Silent); 41 | } 42 | } 43 | 44 | 45 | void RecVolumesTest(RAROptions *Cmd,Archive *Arc,const wchar *Name) 46 | { 47 | wchar RevName[NM]; 48 | *RevName=0; 49 | if (Arc!=NULL) 50 | { 51 | // We received .rar or .exe volume as a parameter, trying to find 52 | // the matching .rev file number 1. 53 | bool NewNumbering=Arc->NewNumbering; 54 | 55 | wchar ArcName[NM]; 56 | wcsncpyz(ArcName,Name,ASIZE(ArcName)); 57 | 58 | wchar *VolNumStart=VolNameToFirstName(ArcName,ArcName,ASIZE(ArcName),NewNumbering); 59 | wchar RecVolMask[NM]; 60 | wcsncpyz(RecVolMask,ArcName,ASIZE(RecVolMask)); 61 | size_t BaseNamePartLength=VolNumStart-ArcName; 62 | wcsncpyz(RecVolMask+BaseNamePartLength,L"*.rev",ASIZE(RecVolMask)-BaseNamePartLength); 63 | 64 | FindFile Find; 65 | Find.SetMask(RecVolMask); 66 | FindData RecData; 67 | 68 | while (Find.Next(&RecData)) 69 | { 70 | wchar *Num=GetVolNumPart(RecData.Name); 71 | if (*Num!='1') // Name must have "0...01" numeric part. 72 | continue; 73 | bool FirstVol=true; 74 | while (--Num>=RecData.Name && IsDigit(*Num)) 75 | if (*Num!='0') 76 | { 77 | FirstVol=false; 78 | break; 79 | } 80 | if (FirstVol) 81 | { 82 | wcsncpyz(RevName,RecData.Name,ASIZE(RevName)); 83 | Name=RevName; 84 | break; 85 | } 86 | } 87 | if (*RevName==0) // First .rev file not found. 88 | return; 89 | } 90 | 91 | File RevFile; 92 | if (!RevFile.Open(Name)) 93 | { 94 | ErrHandler.OpenErrorMsg(Name); // It also sets RARX_OPEN. 95 | return; 96 | } 97 | mprintf(L"\n"); 98 | byte Sign[REV5_SIGN_SIZE]; 99 | bool Rev5=RevFile.Read(Sign,REV5_SIGN_SIZE)==REV5_SIGN_SIZE && memcmp(Sign,REV5_SIGN,REV5_SIGN_SIZE)==0; 100 | RevFile.Close(); 101 | if (Rev5) 102 | { 103 | RecVolumes5 RecVol(Cmd,true); 104 | RecVol.Test(Cmd,Name); 105 | } 106 | else 107 | { 108 | RecVolumes3 RecVol(Cmd,true); 109 | RecVol.Test(Cmd,Name); 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /Libraries/unrar/recvol.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _RAR_RECVOL_ 2 | #define _RAR_RECVOL_ 3 | 4 | #define REV5_SIGN "Rar!\x1aRev" 5 | #define REV5_SIGN_SIZE 8 6 | 7 | class RecVolumes3 8 | { 9 | private: 10 | File *SrcFile[256]; 11 | Array Buf; 12 | 13 | #ifdef RAR_SMP 14 | ThreadPool *RSThreadPool; 15 | #endif 16 | public: 17 | RecVolumes3(RAROptions *Cmd,bool TestOnly); 18 | ~RecVolumes3(); 19 | void Make(RAROptions *Cmd,wchar *ArcName); 20 | bool Restore(RAROptions *Cmd,const wchar *Name,bool Silent); 21 | void Test(RAROptions *Cmd,const wchar *Name); 22 | }; 23 | 24 | 25 | struct RecVolItem 26 | { 27 | File *f; 28 | wchar Name[NM]; 29 | uint CRC; 30 | uint64 FileSize; 31 | bool New; // Newly created RAR volume. 32 | bool Valid; // If existing RAR volume is valid. 33 | }; 34 | 35 | 36 | class RecVolumes5; 37 | struct RecRSThreadData 38 | { 39 | RecVolumes5 *RecRSPtr; 40 | RSCoder16 *RS; 41 | bool Encode; 42 | uint DataNum; 43 | const byte *Data; 44 | size_t StartPos; 45 | size_t Size; 46 | }; 47 | 48 | class RecVolumes5 49 | { 50 | private: 51 | void ProcessRS(RAROptions *Cmd,uint DataNum,const byte *Data,uint MaxRead,bool Encode); 52 | void ProcessRS(RAROptions *Cmd,uint MaxRead,bool Encode); 53 | uint ReadHeader(File *RecFile,bool FirstRev); 54 | 55 | Array RecItems; 56 | 57 | byte *RealReadBuffer; // Real pointer returned by 'new'. 58 | byte *ReadBuffer; // Pointer aligned for SSE instructions. 59 | 60 | byte *RealBuf; // Real pointer returned by 'new'. 61 | byte *Buf; // Store ECC or recovered data here, aligned for SSE. 62 | size_t RecBufferSize; // Buffer area allocated for single volume. 63 | 64 | uint DataCount; // Number of archives. 65 | uint RecCount; // Number of recovery volumes. 66 | uint TotalCount; // Total number of archives and recovery volumes. 67 | 68 | bool *ValidFlags; // Volume validity flags for recovering. 69 | uint MissingVolumes; // Number of missing or bad RAR volumes. 70 | 71 | #ifdef RAR_SMP 72 | ThreadPool *RecThreadPool; 73 | #endif 74 | uint MaxUserThreads; // Maximum number of threads defined by user. 75 | RecRSThreadData *ThreadData; // Array to store thread parameters. 76 | public: // 'public' only because called from thread functions. 77 | void ProcessAreaRS(RecRSThreadData *td); 78 | public: 79 | RecVolumes5(RAROptions *Cmd,bool TestOnly); 80 | ~RecVolumes5(); 81 | bool Restore(RAROptions *Cmd,const wchar *Name,bool Silent); 82 | void Test(RAROptions *Cmd,const wchar *Name); 83 | }; 84 | 85 | bool RecVolumesRestore(RAROptions *Cmd,const wchar *Name,bool Silent); 86 | void RecVolumesTest(RAROptions *Cmd,Archive *Arc,const wchar *Name); 87 | 88 | #endif 89 | -------------------------------------------------------------------------------- /Libraries/unrar/resource.cpp: -------------------------------------------------------------------------------- 1 | #include "rar.hpp" 2 | 3 | 4 | 5 | 6 | 7 | #ifndef RARDLL 8 | const wchar* St(MSGID StringId) 9 | { 10 | return StringId; 11 | } 12 | 13 | 14 | // Needed for Unix swprintf to convert %s to %ls in legacy language resources. 15 | const wchar *StF(MSGID StringId) 16 | { 17 | static wchar FormattedStr[512]; 18 | PrintfPrepareFmt(St(StringId),FormattedStr,ASIZE(FormattedStr)); 19 | return FormattedStr; 20 | } 21 | #endif 22 | 23 | -------------------------------------------------------------------------------- /Libraries/unrar/resource.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _RAR_RESOURCE_ 2 | #define _RAR_RESOURCE_ 3 | 4 | #ifdef RARDLL 5 | #define St(x) (L"") 6 | #define StF(x) (L"") 7 | #else 8 | const wchar *St(MSGID StringId); 9 | const wchar *StF(MSGID StringId); 10 | #endif 11 | 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /Libraries/unrar/rijndael.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _RIJNDAEL_H_ 2 | #define _RIJNDAEL_H_ 3 | 4 | /************************************************************************** 5 | * This code is based on Szymon Stefanek public domain AES implementation * 6 | **************************************************************************/ 7 | 8 | #define _MAX_KEY_COLUMNS (256/32) 9 | #define _MAX_ROUNDS 14 10 | #define MAX_IV_SIZE 16 11 | 12 | class Rijndael 13 | { 14 | private: 15 | #ifdef USE_SSE 16 | void blockEncryptSSE(const byte *input,size_t numBlocks,byte *outBuffer); 17 | void blockDecryptSSE(const byte *input, size_t numBlocks, byte *outBuffer); 18 | 19 | bool AES_NI; 20 | #endif 21 | void keySched(byte key[_MAX_KEY_COLUMNS][4]); 22 | void keyEncToDec(); 23 | void GenerateTables(); 24 | 25 | // RAR always uses CBC, but we may need to turn it off when calling 26 | // this code from other archive formats with CTR and other modes. 27 | bool CBCMode; 28 | 29 | int m_uRounds; 30 | byte m_initVector[MAX_IV_SIZE]; 31 | byte m_expandedKey[_MAX_ROUNDS+1][4][4]; 32 | public: 33 | Rijndael(); 34 | void Init(bool Encrypt,const byte *key,uint keyLen,const byte *initVector); 35 | void blockEncrypt(const byte *input, size_t inputLen, byte *outBuffer); 36 | void blockDecrypt(const byte *input, size_t inputLen, byte *outBuffer); 37 | void SetCBCMode(bool Mode) {CBCMode=Mode;} 38 | }; 39 | 40 | #endif // _RIJNDAEL_H_ 41 | -------------------------------------------------------------------------------- /Libraries/unrar/rs.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _RAR_RS_ 2 | #define _RAR_RS_ 3 | 4 | #define MAXPAR 255 // Maximum parity data size. 5 | #define MAXPOL 512 // Maximum polynomial degree. 6 | 7 | class RSCoder 8 | { 9 | private: 10 | void gfInit(); 11 | int gfMult(int a,int b); 12 | void pnInit(); 13 | void pnMult(int *p1,int *p2,int *r); 14 | 15 | int gfExp[MAXPOL]; // Galois field exponents. 16 | int gfLog[MAXPAR+1]; // Galois field logarithms. 17 | 18 | int GXPol[MAXPOL*2]; // Generator polynomial g(x). 19 | 20 | int ErrorLocs[MAXPAR+1],ErrCount; 21 | int Dnm[MAXPAR+1]; 22 | 23 | int ParSize; // Parity bytes size and so the number of recovery volumes. 24 | int ELPol[MAXPOL]; // Error locator polynomial. 25 | bool FirstBlockDone; 26 | public: 27 | void Init(int ParSize); 28 | void Encode(byte *Data,int DataSize,byte *DestData); 29 | bool Decode(byte *Data,int DataSize,int *EraLoc,int EraSize); 30 | }; 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /Libraries/unrar/rs16.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abbeycode/UnrarKit/7cd8c32bcfc1e1a7d16bc5b58cbd37a6eaf8b316/Libraries/unrar/rs16.cpp -------------------------------------------------------------------------------- /Libraries/unrar/rs16.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _RAR_RS16_ 2 | #define _RAR_RS16_ 3 | 4 | class RSCoder16 5 | { 6 | private: 7 | static const uint gfSize=65535; // Galois field size. 8 | void gfInit(); // Galois field inititalization. 9 | inline uint gfAdd(uint a,uint b); // Addition in Galois field. 10 | inline uint gfMul(uint a,uint b); // Multiplication in Galois field. 11 | inline uint gfInv(uint a); // Inverse element in Galois field. 12 | uint *gfExp; // Galois field exponents. 13 | uint *gfLog; // Galois field logarithms. 14 | 15 | void MakeEncoderMatrix(); 16 | void MakeDecoderMatrix(); 17 | void InvertDecoderMatrix(); 18 | 19 | #ifdef USE_SSE 20 | bool SSE_UpdateECC(uint DataNum, uint ECCNum, const byte *Data, byte *ECC, size_t BlockSize); 21 | #endif 22 | 23 | bool Decoding; // If we are decoding or encoding data. 24 | uint ND; // Number of data units. 25 | uint NR; // Number of Reed-Solomon code units. 26 | uint NE; // Number of erasures. 27 | bool *ValidFlags; // Validity flags for data and ECC units. 28 | uint *MX; // Cauchy based coding or decoding matrix. 29 | 30 | uint *DataLog; // Buffer to store data logarithms for UpdateECC. 31 | size_t DataLogSize; 32 | 33 | public: 34 | RSCoder16(); 35 | ~RSCoder16(); 36 | 37 | bool Init(uint DataCount, uint RecCount, bool *ValidityFlags); 38 | #if 0 // We use only UpdateECC now. 39 | void Process(const uint *Data, uint *Out); 40 | #endif 41 | void UpdateECC(uint DataNum, uint ECCNum, const byte *Data, byte *ECC, size_t BlockSize); 42 | }; 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /Libraries/unrar/scantree.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _RAR_SCANTREE_ 2 | #define _RAR_SCANTREE_ 3 | 4 | enum SCAN_DIRS 5 | { 6 | SCAN_SKIPDIRS, // Skip directories, but recurse for files if recursion mode is enabled. 7 | SCAN_GETDIRS, // Get subdirectories in recurse mode. 8 | SCAN_GETDIRSTWICE, // Get the directory name both before and after the list of files it contains. 9 | SCAN_GETCURDIRS // Get subdirectories in current directory even in RECURSE_NONE mode. 10 | }; 11 | 12 | enum SCAN_CODE { SCAN_SUCCESS,SCAN_DONE,SCAN_ERROR,SCAN_NEXT }; 13 | 14 | #define MAXSCANDEPTH (NM/2) 15 | 16 | class CommandData; 17 | 18 | class ScanTree 19 | { 20 | private: 21 | bool ExpandFolderMask(); 22 | bool GetFilteredMask(); 23 | bool GetNextMask(); 24 | SCAN_CODE FindProc(FindData *FD); 25 | void ScanError(bool &Error); 26 | 27 | FindFile *FindStack[MAXSCANDEPTH]; 28 | int Depth; 29 | 30 | int SetAllMaskDepth; 31 | 32 | StringList *FileMasks; 33 | RECURSE_MODE Recurse; 34 | bool GetLinks; 35 | SCAN_DIRS GetDirs; 36 | int Errors; 37 | 38 | // Set when processing paths like c:\ (root directory without wildcards). 39 | bool ScanEntireDisk; 40 | 41 | wchar CurMask[NM]; 42 | wchar OrigCurMask[NM]; 43 | 44 | // Store all folder masks generated from folder wildcard mask in non-recursive mode. 45 | StringList ExpandedFolderList; 46 | 47 | // Store a filter string for folder wildcard in recursive mode. 48 | StringList FilterList; 49 | 50 | // Save the list of unreadable dirs here. 51 | StringList *ErrDirList; 52 | Array *ErrDirSpecPathLength; 53 | 54 | // Set if processing a folder wildcard mask. 55 | bool FolderWildcards; 56 | 57 | bool SearchAllInRoot; 58 | size_t SpecPathLength; 59 | 60 | wchar ErrArcName[NM]; 61 | 62 | CommandData *Cmd; 63 | public: 64 | ScanTree(StringList *FileMasks,RECURSE_MODE Recurse,bool GetLinks,SCAN_DIRS GetDirs); 65 | ~ScanTree(); 66 | SCAN_CODE GetNext(FindData *FindData); 67 | size_t GetSpecPathLength() {return SpecPathLength;} 68 | int GetErrors() {return Errors;}; 69 | void SetErrArcName(const wchar *Name) {wcsncpyz(ErrArcName,Name,ASIZE(ErrArcName));} 70 | void SetCommandData(CommandData *Cmd) {ScanTree::Cmd=Cmd;} 71 | void SetErrDirList(StringList *List,Array *Lengths) 72 | { 73 | ErrDirList=List; 74 | ErrDirSpecPathLength=Lengths; 75 | } 76 | }; 77 | 78 | #endif 79 | -------------------------------------------------------------------------------- /Libraries/unrar/secpassword.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _RAR_SECURE_PASSWORD_ 2 | #define _RAR_SECURE_PASSWORD_ 3 | 4 | // Store a password securely (if data encryption is provided by OS) 5 | // or obfuscated to make search for password in memory dump less trivial. 6 | class SecPassword 7 | { 8 | private: 9 | void Process(const wchar *Src,size_t SrcSize,wchar *Dst,size_t DstSize,bool Encode); 10 | 11 | wchar Password[MAXPASSWORD]; 12 | 13 | // It is important to have this 'bool' value, so if our object is cleaned 14 | // with memset as a part of larger structure, it is handled correctly. 15 | bool PasswordSet; 16 | public: 17 | SecPassword(); 18 | ~SecPassword(); 19 | void Clean(); 20 | void Get(wchar *Psw,size_t MaxSize); 21 | void Set(const wchar *Psw); 22 | bool IsSet() {return PasswordSet;} 23 | size_t Length(); 24 | bool operator == (SecPassword &psw); 25 | 26 | // Set to true if we need to pass a password to another process. 27 | // We use it when transferring parameters to UAC elevated WinRAR. 28 | bool CrossProcess; 29 | }; 30 | 31 | 32 | void cleandata(void *data,size_t size); 33 | void SecHideData(void *Data,size_t DataSize,bool Encode,bool CrossProcess); 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /Libraries/unrar/sha1.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _RAR_SHA1_ 2 | #define _RAR_SHA1_ 3 | 4 | typedef struct { 5 | uint32 state[5]; 6 | uint64 count; 7 | unsigned char buffer[64]; 8 | } sha1_context; 9 | 10 | void sha1_init( sha1_context * c ); 11 | void sha1_process(sha1_context * c, const byte *data, size_t len); 12 | void sha1_process_rar29(sha1_context *context, const unsigned char *data, size_t len); 13 | void sha1_done( sha1_context * c, uint32 digest[5] ); 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /Libraries/unrar/sha256.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _RAR_SHA256_ 2 | #define _RAR_SHA256_ 3 | 4 | #define SHA256_DIGEST_SIZE 32 5 | 6 | typedef struct 7 | { 8 | uint32 H[8]; 9 | uint64 Count; 10 | byte Buffer[64]; 11 | } sha256_context; 12 | 13 | void sha256_init(sha256_context *ctx); 14 | void sha256_process(sha256_context *ctx, const void *Data, size_t Size); 15 | void sha256_done(sha256_context *ctx, byte *Digest); 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /Libraries/unrar/smallfn.cpp: -------------------------------------------------------------------------------- 1 | #include "rar.hpp" 2 | 3 | int ToPercent(int64 N1,int64 N2) 4 | { 5 | if (N2 StrW(strlen(Str)); 21 | CharToWide(Str,&StrW[0],StrW.Size()); 22 | AddString(&StrW[0]); 23 | } 24 | 25 | 26 | void StringList::AddString(const wchar *Str) 27 | { 28 | if (Str==NULL) 29 | Str=L""; 30 | 31 | size_t PrevSize=StringData.Size(); 32 | StringData.Add(wcslen(Str)+1); 33 | wcscpy(&StringData[PrevSize],Str); 34 | 35 | StringsCount++; 36 | } 37 | 38 | 39 | bool StringList::GetStringA(char *Str,size_t MaxLength) 40 | { 41 | Array StrW(MaxLength); 42 | if (!GetString(&StrW[0],StrW.Size())) 43 | return false; 44 | WideToChar(&StrW[0],Str,MaxLength); 45 | return true; 46 | } 47 | 48 | 49 | bool StringList::GetString(wchar *Str,size_t MaxLength) 50 | { 51 | wchar *StrPtr; 52 | if (!GetString(&StrPtr)) 53 | return false; 54 | wcsncpyz(Str,StrPtr,MaxLength); 55 | return true; 56 | } 57 | 58 | 59 | #ifndef SFX_MODULE 60 | bool StringList::GetString(wchar *Str,size_t MaxLength,int StringNum) 61 | { 62 | SavePosition(); 63 | Rewind(); 64 | bool RetCode=true; 65 | while (StringNum-- >=0) 66 | if (!GetString(Str,MaxLength)) 67 | { 68 | RetCode=false; 69 | break; 70 | } 71 | RestorePosition(); 72 | return RetCode; 73 | } 74 | #endif 75 | 76 | 77 | wchar* StringList::GetString() 78 | { 79 | wchar *Str; 80 | GetString(&Str); 81 | return Str; 82 | } 83 | 84 | 85 | bool StringList::GetString(wchar **Str) 86 | { 87 | if (CurPos>=StringData.Size()) // No more strings left unprocessed. 88 | { 89 | if (Str!=NULL) 90 | *Str=NULL; 91 | return false; 92 | } 93 | 94 | wchar *CurStr=&StringData[CurPos]; 95 | CurPos+=wcslen(CurStr)+1; 96 | if (Str!=NULL) 97 | *Str=CurStr; 98 | 99 | return true; 100 | } 101 | 102 | 103 | void StringList::Rewind() 104 | { 105 | CurPos=0; 106 | } 107 | 108 | 109 | #ifndef SFX_MODULE 110 | bool StringList::Search(const wchar *Str,bool CaseSensitive) 111 | { 112 | SavePosition(); 113 | Rewind(); 114 | bool Found=false; 115 | wchar *CurStr; 116 | while (GetString(&CurStr)) 117 | { 118 | if (Str!=NULL && CurStr!=NULL) 119 | if ((CaseSensitive ? wcscmp(Str,CurStr):wcsicomp(Str,CurStr))!=0) 120 | continue; 121 | Found=true; 122 | break; 123 | } 124 | RestorePosition(); 125 | return Found; 126 | } 127 | #endif 128 | 129 | 130 | #ifndef SFX_MODULE 131 | void StringList::SavePosition() 132 | { 133 | if (SavePosNumber0) 146 | { 147 | SavePosNumber--; 148 | CurPos=SaveCurPos[SavePosNumber]; 149 | } 150 | } 151 | #endif 152 | -------------------------------------------------------------------------------- /Libraries/unrar/strlist.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _RAR_STRLIST_ 2 | #define _RAR_STRLIST_ 3 | 4 | class StringList 5 | { 6 | private: 7 | Array StringData; 8 | size_t CurPos; 9 | 10 | size_t StringsCount; 11 | 12 | size_t SaveCurPos[16],SavePosNumber; 13 | public: 14 | StringList(); 15 | void Reset(); 16 | void AddStringA(const char *Str); 17 | void AddString(const wchar *Str); 18 | bool GetStringA(char *Str,size_t MaxLength); 19 | bool GetString(wchar *Str,size_t MaxLength); 20 | bool GetString(wchar *Str,size_t MaxLength,int StringNum); 21 | wchar* GetString(); 22 | bool GetString(wchar **Str); 23 | void Rewind(); 24 | size_t ItemsCount() {return StringsCount;}; 25 | size_t GetCharCount() {return StringData.Size();} 26 | bool Search(const wchar *Str,bool CaseSensitive); 27 | void SavePosition(); 28 | void RestorePosition(); 29 | }; 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /Libraries/unrar/suballoc.hpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * This file is part of PPMd project * 3 | * Written and distributed to public domain by Dmitry Shkarin 1997, * 4 | * 1999-2000 * 5 | * Contents: interface to memory allocation routines * 6 | ****************************************************************************/ 7 | #if !defined(_SUBALLOC_H_) 8 | #define _SUBALLOC_H_ 9 | 10 | #if defined(__GNUC__) && defined(ALLOW_MISALIGNED) 11 | #define RARPPM_PACK_ATTR __attribute__ ((packed)) 12 | #else 13 | #define RARPPM_PACK_ATTR 14 | #endif /* defined(__GNUC__) */ 15 | 16 | #ifdef ALLOW_MISALIGNED 17 | #pragma pack(1) 18 | #endif 19 | 20 | struct RARPPM_MEM_BLK 21 | { 22 | ushort Stamp, NU; 23 | RARPPM_MEM_BLK* next, * prev; 24 | void insertAt(RARPPM_MEM_BLK* p) 25 | { 26 | next=(prev=p)->next; 27 | p->next=next->prev=this; 28 | } 29 | void remove() 30 | { 31 | prev->next=next; 32 | next->prev=prev; 33 | } 34 | } RARPPM_PACK_ATTR; 35 | 36 | #ifdef ALLOW_MISALIGNED 37 | #ifdef _AIX 38 | #pragma pack(pop) 39 | #else 40 | #pragma pack() 41 | #endif 42 | #endif 43 | 44 | 45 | class SubAllocator 46 | { 47 | private: 48 | static const int N1=4, N2=4, N3=4, N4=(128+3-1*N1-2*N2-3*N3)/4; 49 | static const int N_INDEXES=N1+N2+N3+N4; 50 | 51 | struct RAR_NODE 52 | { 53 | RAR_NODE* next; 54 | }; 55 | 56 | inline void InsertNode(void* p,int indx); 57 | inline void* RemoveNode(int indx); 58 | inline uint U2B(int NU); 59 | inline void SplitBlock(void* pv,int OldIndx,int NewIndx); 60 | inline void GlueFreeBlocks(); 61 | void* AllocUnitsRare(int indx); 62 | inline RARPPM_MEM_BLK* MBPtr(RARPPM_MEM_BLK *BasePtr,int Items); 63 | 64 | long SubAllocatorSize; 65 | byte Indx2Units[N_INDEXES], Units2Indx[128], GlueCount; 66 | byte *HeapStart,*LoUnit, *HiUnit; 67 | struct RAR_NODE FreeList[N_INDEXES]; 68 | public: 69 | SubAllocator(); 70 | ~SubAllocator() {StopSubAllocator();} 71 | void Clean(); 72 | bool StartSubAllocator(int SASize); 73 | void StopSubAllocator(); 74 | void InitSubAllocator(); 75 | inline void* AllocContext(); 76 | inline void* AllocUnits(int NU); 77 | inline void* ExpandUnits(void* ptr,int OldNU); 78 | inline void* ShrinkUnits(void* ptr,int OldNU,int NewNU); 79 | inline void FreeUnits(void* ptr,int OldNU); 80 | long GetAllocatedMemory() {return(SubAllocatorSize);} 81 | 82 | byte *pText, *UnitsStart,*HeapEnd,*FakeUnitsStart; 83 | }; 84 | 85 | 86 | #endif /* !defined(_SUBALLOC_H_) */ 87 | -------------------------------------------------------------------------------- /Libraries/unrar/system.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _RAR_SYSTEM_ 2 | #define _RAR_SYSTEM_ 3 | 4 | #ifdef _WIN_ALL 5 | #ifndef BELOW_NORMAL_PRIORITY_CLASS 6 | #define BELOW_NORMAL_PRIORITY_CLASS 0x00004000 7 | #define ABOVE_NORMAL_PRIORITY_CLASS 0x00008000 8 | #endif 9 | #ifndef PROCESS_MODE_BACKGROUND_BEGIN 10 | #define PROCESS_MODE_BACKGROUND_BEGIN 0x00100000 11 | #define PROCESS_MODE_BACKGROUND_END 0x00200000 12 | #endif 13 | #ifndef SHTDN_REASON_MAJOR_APPLICATION 14 | #define SHTDN_REASON_MAJOR_APPLICATION 0x00040000 15 | #define SHTDN_REASON_FLAG_PLANNED 0x80000000 16 | #define SHTDN_REASON_MINOR_MAINTENANCE 0x00000001 17 | #endif 18 | #endif 19 | 20 | void InitSystemOptions(int SleepTime); 21 | void SetPriority(int Priority); 22 | clock_t MonoClock(); 23 | void Wait(); 24 | bool EmailFile(const wchar *FileName,const wchar *MailToW); 25 | void Shutdown(POWER_MODE Mode); 26 | bool ShutdownCheckAnother(bool Open); 27 | 28 | #ifdef _WIN_ALL 29 | HMODULE WINAPI LoadSysLibrary(const wchar *Name); 30 | bool IsUserAdmin(); 31 | #endif 32 | 33 | 34 | #ifdef USE_SSE 35 | enum SSE_VERSION {SSE_NONE,SSE_SSE,SSE_SSE2,SSE_SSSE3,SSE_SSE41,SSE_AVX2}; 36 | SSE_VERSION GetSSEVersion(); 37 | extern SSE_VERSION _SSE_Version; 38 | #endif 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /Libraries/unrar/threadmisc.cpp: -------------------------------------------------------------------------------- 1 | static inline bool CriticalSectionCreate(CRITSECT_HANDLE *CritSection) 2 | { 3 | #ifdef _WIN_ALL 4 | InitializeCriticalSection(CritSection); 5 | return true; 6 | #elif defined(_UNIX) 7 | return pthread_mutex_init(CritSection,NULL)==0; 8 | #endif 9 | } 10 | 11 | 12 | static inline void CriticalSectionDelete(CRITSECT_HANDLE *CritSection) 13 | { 14 | #ifdef _WIN_ALL 15 | DeleteCriticalSection(CritSection); 16 | #elif defined(_UNIX) 17 | pthread_mutex_destroy(CritSection); 18 | #endif 19 | } 20 | 21 | 22 | static inline void CriticalSectionStart(CRITSECT_HANDLE *CritSection) 23 | { 24 | #ifdef _WIN_ALL 25 | EnterCriticalSection(CritSection); 26 | #elif defined(_UNIX) 27 | pthread_mutex_lock(CritSection); 28 | #endif 29 | } 30 | 31 | 32 | static inline void CriticalSectionEnd(CRITSECT_HANDLE *CritSection) 33 | { 34 | #ifdef _WIN_ALL 35 | LeaveCriticalSection(CritSection); 36 | #elif defined(_UNIX) 37 | pthread_mutex_unlock(CritSection); 38 | #endif 39 | } 40 | 41 | 42 | static THREAD_HANDLE ThreadCreate(NATIVE_THREAD_PTR Proc,void *Data) 43 | { 44 | #ifdef _UNIX 45 | /* 46 | pthread_attr_t attr; 47 | pthread_attr_init(&attr); 48 | pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); 49 | */ 50 | pthread_t pt; 51 | int Code=pthread_create(&pt,NULL/*&attr*/,Proc,Data); 52 | if (Code!=0) 53 | { 54 | wchar Msg[100]; 55 | swprintf(Msg,ASIZE(Msg),L"\npthread_create failed, code %d\n",Code); 56 | ErrHandler.GeneralErrMsg(Msg); 57 | ErrHandler.SysErrMsg(); 58 | ErrHandler.Exit(RARX_FATAL); 59 | } 60 | return pt; 61 | #else 62 | DWORD ThreadId; 63 | HANDLE hThread=CreateThread(NULL,0x10000,Proc,Data,0,&ThreadId); 64 | if (hThread==NULL) 65 | { 66 | ErrHandler.GeneralErrMsg(L"CreateThread failed"); 67 | ErrHandler.SysErrMsg(); 68 | ErrHandler.Exit(RARX_FATAL); 69 | } 70 | return hThread; 71 | #endif 72 | } 73 | 74 | 75 | static void ThreadClose(THREAD_HANDLE hThread) 76 | { 77 | #ifdef _UNIX 78 | pthread_join(hThread,NULL); 79 | #else 80 | CloseHandle(hThread); 81 | #endif 82 | } 83 | 84 | 85 | #ifdef _WIN_ALL 86 | static void CWaitForSingleObject(HANDLE hHandle) 87 | { 88 | DWORD rc=WaitForSingleObject(hHandle,INFINITE); 89 | if (rc==WAIT_FAILED) 90 | { 91 | ErrHandler.GeneralErrMsg(L"\nWaitForMultipleObjects error %d, GetLastError %d",rc,GetLastError()); 92 | ErrHandler.Exit(RARX_FATAL); 93 | } 94 | } 95 | #endif 96 | 97 | 98 | #ifdef _UNIX 99 | static void cpthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) 100 | { 101 | int rc=pthread_cond_wait(cond,mutex); 102 | if (rc!=0) 103 | { 104 | ErrHandler.GeneralErrMsg(L"\npthread_cond_wait error %d",rc); 105 | ErrHandler.Exit(RARX_FATAL); 106 | } 107 | } 108 | #endif 109 | 110 | 111 | uint GetNumberOfCPU() 112 | { 113 | #ifndef RAR_SMP 114 | return 1; 115 | #else 116 | #ifdef _UNIX 117 | #ifdef _SC_NPROCESSORS_ONLN 118 | uint Count=(uint)sysconf(_SC_NPROCESSORS_ONLN); 119 | return Count<1 ? 1:Count; 120 | #elif defined(_APPLE) 121 | uint Count; 122 | size_t Size=sizeof(Count); 123 | return sysctlbyname("hw.ncpu",&Count,&Size,NULL,0)==0 ? Count:1; 124 | #endif 125 | #else // !_UNIX 126 | DWORD_PTR ProcessMask; 127 | DWORD_PTR SystemMask; 128 | 129 | if (!GetProcessAffinityMask(GetCurrentProcess(),&ProcessMask,&SystemMask)) 130 | return 1; 131 | uint Count=0; 132 | for (DWORD_PTR Mask=1;Mask!=0;Mask<<=1) 133 | if ((ProcessMask & Mask)!=0) 134 | Count++; 135 | return Count<1 ? 1:Count; 136 | #endif 137 | 138 | #endif // RAR_SMP 139 | } 140 | 141 | 142 | uint GetNumberOfThreads() 143 | { 144 | uint NumCPU=GetNumberOfCPU(); 145 | if (NumCPU<1) 146 | return 1; 147 | if (NumCPU>MaxPoolThreads) 148 | return MaxPoolThreads; 149 | return NumCPU; 150 | } 151 | 152 | -------------------------------------------------------------------------------- /Libraries/unrar/threadpool.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _RAR_THREADPOOL_ 2 | #define _RAR_THREADPOOL_ 3 | 4 | #ifndef RAR_SMP 5 | const uint MaxPoolThreads=1; // For single threaded version. 6 | #else 7 | // We need to use the processor groups API to increase it beyond 64. 8 | // Also be sure to check and adjust if needed per thread and total block size 9 | // when compressing if going above 64. 10 | const uint MaxPoolThreads=64; 11 | 12 | 13 | #ifdef _UNIX 14 | #include 15 | #include 16 | #endif 17 | 18 | // Undefine for debugging. 19 | #define USE_THREADS 20 | 21 | #ifdef _UNIX 22 | #define NATIVE_THREAD_TYPE void* 23 | typedef void* (*NATIVE_THREAD_PTR)(void *Data); 24 | typedef pthread_t THREAD_HANDLE; 25 | typedef pthread_mutex_t CRITSECT_HANDLE; 26 | #else 27 | #define NATIVE_THREAD_TYPE DWORD WINAPI 28 | typedef DWORD (WINAPI *NATIVE_THREAD_PTR)(void *Data); 29 | typedef HANDLE THREAD_HANDLE; 30 | typedef CRITICAL_SECTION CRITSECT_HANDLE; 31 | #endif 32 | 33 | typedef void (*PTHREAD_PROC)(void *Data); 34 | #define THREAD_PROC(fn) void fn(void *Data) 35 | 36 | uint GetNumberOfCPU(); 37 | uint GetNumberOfThreads(); 38 | 39 | 40 | class ThreadPool 41 | { 42 | private: 43 | struct QueueEntry 44 | { 45 | PTHREAD_PROC Proc; 46 | void *Param; 47 | }; 48 | 49 | void CreateThreads(); 50 | static NATIVE_THREAD_TYPE PoolThread(void *Param); 51 | void PoolThreadLoop(); 52 | bool GetQueuedTask(QueueEntry *Task); 53 | 54 | // Number of threads in the pool. Must not exceed MaxPoolThreads. 55 | uint MaxAllowedThreads; 56 | THREAD_HANDLE ThreadHandles[MaxPoolThreads]; 57 | 58 | // Number of actually created threads. 59 | uint ThreadsCreatedCount; 60 | 61 | uint ActiveThreads; 62 | 63 | QueueEntry TaskQueue[MaxPoolThreads]; 64 | uint QueueTop; 65 | uint QueueBottom; 66 | 67 | bool Closing; // Set true to quit all threads. 68 | 69 | #ifdef _WIN_ALL 70 | // Semaphore counting number of tasks stored in queue. 71 | HANDLE QueuedTasksCnt; 72 | 73 | // Event signalling if no active tasks are performing now. 74 | HANDLE NoneActive; 75 | 76 | #elif defined(_UNIX) 77 | // Semaphores seem to be slower than conditional variables in pthreads, 78 | // so we use the conditional variable to count tasks stored in queue. 79 | uint QueuedTasksCnt; 80 | pthread_cond_t QueuedTasksCntCond; 81 | pthread_mutex_t QueuedTasksCntMutex; 82 | 83 | bool AnyActive; // Active tasks present flag. 84 | pthread_cond_t AnyActiveCond; 85 | pthread_mutex_t AnyActiveMutex; 86 | #endif 87 | 88 | // Pool critical section. We use the single section for all branches 89 | // to avoid deadlocks, when thread1 has section1 and wants section2 90 | // and thread2 has section2 and wants section1. 91 | CRITSECT_HANDLE CritSection; 92 | public: 93 | ThreadPool(uint MaxThreads); 94 | ~ThreadPool(); 95 | void AddTask(PTHREAD_PROC Proc,void *Data); 96 | void WaitDone(); 97 | 98 | #ifdef _WIN_ALL 99 | static int ThreadPriority; 100 | static void SetPriority(int Priority) {ThreadPriority=Priority;} 101 | #endif 102 | }; 103 | 104 | #endif // RAR_SMP 105 | 106 | #endif // _RAR_THREADPOOL_ 107 | 108 | -------------------------------------------------------------------------------- /Libraries/unrar/timefn.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _RAR_TIMEFN_ 2 | #define _RAR_TIMEFN_ 3 | 4 | struct RarLocalTime 5 | { 6 | uint Year; 7 | uint Month; 8 | uint Day; 9 | uint Hour; 10 | uint Minute; 11 | uint Second; 12 | uint Reminder; // Part of time smaller than 1 second, represented in 1/REMINDER_PRECISION intervals. 13 | uint wDay; 14 | uint yDay; 15 | }; 16 | 17 | 18 | class RarTime 19 | { 20 | private: 21 | static const uint TICKS_PER_SECOND = 1000000000; // Internal precision. 22 | 23 | // Internal time representation in 1/TICKS_PER_SECOND since 01.01.1601. 24 | // We use nanoseconds here to handle the high precision Unix time. 25 | uint64 itime; 26 | public: 27 | // RarLocalTime::Reminder precision. Must be equal to TICKS_PER_SECOND. 28 | // Unlike TICKS_PER_SECOND, it is a public field. 29 | static const uint REMINDER_PRECISION = TICKS_PER_SECOND; 30 | public: 31 | RarTime() {Reset();} 32 | bool operator == (RarTime &rt) {return itime==rt.itime;} 33 | bool operator != (RarTime &rt) {return itime!=rt.itime;} 34 | bool operator < (RarTime &rt) {return itime (RarTime &rt) {return itime>rt.itime;} 37 | bool operator >= (RarTime &rt) {return itime>rt.itime || itime==rt.itime;} 38 | 39 | void GetLocal(RarLocalTime *lt); 40 | void SetLocal(RarLocalTime *lt); 41 | #ifdef _WIN_ALL 42 | void GetWinFT(FILETIME *ft); 43 | void SetWinFT(FILETIME *ft); 44 | #endif 45 | uint64 GetWin(); 46 | void SetWin(uint64 WinTime); 47 | time_t GetUnix(); 48 | void SetUnix(time_t ut); 49 | uint64 GetUnixNS(); 50 | void SetUnixNS(uint64 ns); 51 | uint GetDos(); 52 | void SetDos(uint DosTime); 53 | void GetText(wchar *DateStr,size_t MaxSize,bool FullMS); 54 | void SetIsoText(const wchar *TimeText); 55 | void SetAgeText(const wchar *TimeText); 56 | void SetCurrentTime(); 57 | void Reset() {itime=0;} 58 | bool IsSet() {return itime!=0;} 59 | void Adjust(int64 ns); 60 | }; 61 | 62 | const wchar *GetMonthName(int Month); 63 | bool IsLeapYear(int Year); 64 | 65 | #endif 66 | -------------------------------------------------------------------------------- /Libraries/unrar/ui.cpp: -------------------------------------------------------------------------------- 1 | #include "rar.hpp" 2 | 3 | #include "uicommon.cpp" 4 | 5 | #ifdef SILENT 6 | #include "uisilent.cpp" 7 | #else 8 | 9 | 10 | 11 | 12 | #include "uiconsole.cpp" 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /Libraries/unrar/uicommon.cpp: -------------------------------------------------------------------------------- 1 | static SOUND_NOTIFY_MODE uiSoundNotify; 2 | 3 | void uiInit(SOUND_NOTIFY_MODE Sound) 4 | { 5 | uiSoundNotify = Sound; 6 | } 7 | 8 | 9 | // Additionally to handling user input, it analyzes and sets command options. 10 | // Returns only 'replace', 'skip' and 'cancel' codes. 11 | UIASKREP_RESULT uiAskReplaceEx(RAROptions *Cmd,wchar *Name,size_t MaxNameSize,int64 FileSize,RarTime *FileTime,uint Flags) 12 | { 13 | if (Cmd->Overwrite==OVERWRITE_NONE) 14 | return UIASKREP_R_SKIP; 15 | 16 | #if !defined(SFX_MODULE) && !defined(SILENT) 17 | // Must be before Cmd->AllYes check or -y switch would override -or. 18 | if (Cmd->Overwrite==OVERWRITE_AUTORENAME && GetAutoRenamedName(Name,MaxNameSize)) 19 | return UIASKREP_R_REPLACE; 20 | #endif 21 | 22 | // This check must be after OVERWRITE_AUTORENAME processing or -y switch 23 | // would override -or. 24 | if (Cmd->AllYes || Cmd->Overwrite==OVERWRITE_ALL) 25 | { 26 | PrepareToDelete(Name); 27 | return UIASKREP_R_REPLACE; 28 | } 29 | 30 | wchar NewName[NM]; 31 | wcsncpyz(NewName,Name,ASIZE(NewName)); 32 | UIASKREP_RESULT Choice=uiAskReplace(NewName,ASIZE(NewName),FileSize,FileTime,Flags); 33 | 34 | if (Choice==UIASKREP_R_REPLACE || Choice==UIASKREP_R_REPLACEALL) 35 | PrepareToDelete(Name); 36 | 37 | if (Choice==UIASKREP_R_REPLACEALL) 38 | { 39 | Cmd->Overwrite=OVERWRITE_ALL; 40 | return UIASKREP_R_REPLACE; 41 | } 42 | if (Choice==UIASKREP_R_SKIPALL) 43 | { 44 | Cmd->Overwrite=OVERWRITE_NONE; 45 | return UIASKREP_R_SKIP; 46 | } 47 | if (Choice==UIASKREP_R_RENAME) 48 | { 49 | if (PointToName(NewName)==NewName) 50 | SetName(Name,NewName,MaxNameSize); 51 | else 52 | wcsncpyz(Name,NewName,MaxNameSize); 53 | if (FileExist(Name)) 54 | return uiAskReplaceEx(Cmd,Name,MaxNameSize,FileSize,FileTime,Flags); 55 | return UIASKREP_R_REPLACE; 56 | } 57 | #if !defined(SFX_MODULE) && !defined(SILENT) 58 | if (Choice==UIASKREP_R_RENAMEAUTO && GetAutoRenamedName(Name,MaxNameSize)) 59 | { 60 | Cmd->Overwrite=OVERWRITE_AUTORENAME; 61 | return UIASKREP_R_REPLACE; 62 | } 63 | #endif 64 | return Choice; 65 | } 66 | -------------------------------------------------------------------------------- /Libraries/unrar/uisilent.cpp: -------------------------------------------------------------------------------- 1 | // Purely user interface function. Gets and returns user input. 2 | UIASKREP_RESULT uiAskReplace(wchar *Name,size_t MaxNameSize,int64 FileSize,RarTime *FileTime,uint Flags) 3 | { 4 | return UIASKREP_R_REPLACE; 5 | } 6 | 7 | 8 | 9 | 10 | void uiStartArchiveExtract(bool Extract,const wchar *ArcName) 11 | { 12 | } 13 | 14 | 15 | bool uiStartFileExtract(const wchar *FileName,bool Extract,bool Test,bool Skip) 16 | { 17 | return true; 18 | } 19 | 20 | 21 | void uiExtractProgress(int64 CurFileSize,int64 TotalFileSize,int64 CurSize,int64 TotalSize) 22 | { 23 | } 24 | 25 | 26 | void uiProcessProgress(const char *Command,int64 CurSize,int64 TotalSize) 27 | { 28 | } 29 | 30 | 31 | void uiMsgStore::Msg() 32 | { 33 | } 34 | 35 | 36 | bool uiGetPassword(UIPASSWORD_TYPE Type,const wchar *FileName,SecPassword *Password) 37 | { 38 | return false; 39 | } 40 | 41 | 42 | bool uiIsGlobalPasswordSet() 43 | { 44 | return false; 45 | } 46 | 47 | 48 | void uiAlarm(UIALARM_TYPE Type) 49 | { 50 | } 51 | 52 | 53 | bool uiIsAborted() 54 | { 55 | return false; 56 | } 57 | 58 | 59 | void uiGiveTick() 60 | { 61 | } 62 | 63 | 64 | #ifndef SFX_MODULE 65 | const wchar *uiGetMonthName(int Month) 66 | { 67 | return L""; 68 | } 69 | #endif 70 | 71 | 72 | void uiEolAfterMsg() 73 | { 74 | } 75 | -------------------------------------------------------------------------------- /Libraries/unrar/unicode.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _RAR_UNICODE_ 2 | #define _RAR_UNICODE_ 3 | 4 | #if defined( _WIN_ALL) 5 | #define DBCS_SUPPORTED 6 | #endif 7 | 8 | bool WideToChar(const wchar *Src,char *Dest,size_t DestSize); 9 | bool CharToWide(const char *Src,wchar *Dest,size_t DestSize); 10 | byte* WideToRaw(const wchar *Src,byte *Dest,size_t SrcSize); 11 | wchar* RawToWide(const byte *Src,wchar *Dest,size_t DestSize); 12 | void WideToUtf(const wchar *Src,char *Dest,size_t DestSize); 13 | size_t WideToUtfSize(const wchar *Src); 14 | bool UtfToWide(const char *Src,wchar *Dest,size_t DestSize); 15 | bool IsTextUtf8(const byte *Src); 16 | bool IsTextUtf8(const byte *Src,size_t SrcSize); 17 | 18 | int wcsicomp(const wchar *s1,const wchar *s2); 19 | int wcsnicomp(const wchar *s1,const wchar *s2,size_t n); 20 | const wchar_t* wcscasestr(const wchar_t *str, const wchar_t *search); 21 | #ifndef SFX_MODULE 22 | wchar* wcslower(wchar *s); 23 | wchar* wcsupper(wchar *s); 24 | #endif 25 | int toupperw(int ch); 26 | int tolowerw(int ch); 27 | int atoiw(const wchar *s); 28 | int64 atoilw(const wchar *s); 29 | 30 | #ifdef DBCS_SUPPORTED 31 | class SupportDBCS 32 | { 33 | public: 34 | SupportDBCS(); 35 | void Init(); 36 | char* charnext(const char *s); 37 | 38 | bool IsLeadByte[256]; 39 | bool DBCSMode; 40 | }; 41 | extern SupportDBCS gdbcs; 42 | 43 | inline char* charnext(const char *s) {return (char *)(gdbcs.DBCSMode ? gdbcs.charnext(s):s+1);} 44 | inline bool IsDBCSMode() {return gdbcs.DBCSMode;} 45 | 46 | #else 47 | #define charnext(s) ((s)+1) 48 | #define IsDBCSMode() (false) 49 | #endif 50 | 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /Libraries/unrar/unpack50frag.cpp: -------------------------------------------------------------------------------- 1 | FragmentedWindow::FragmentedWindow() 2 | { 3 | memset(Mem,0,sizeof(Mem)); 4 | memset(MemSize,0,sizeof(MemSize)); 5 | } 6 | 7 | 8 | FragmentedWindow::~FragmentedWindow() 9 | { 10 | Reset(); 11 | } 12 | 13 | 14 | void FragmentedWindow::Reset() 15 | { 16 | for (uint I=0;I=MinSize) 43 | { 44 | NewMem=(byte *)malloc(Size); 45 | if (NewMem!=NULL) 46 | break; 47 | Size-=Size/32; 48 | } 49 | if (NewMem==NULL) 50 | throw std::bad_alloc(); 51 | 52 | // Clean the window to generate the same output when unpacking corrupt 53 | // RAR files, which may access to unused areas of sliding dictionary. 54 | memset(NewMem,0,Size); 55 | 56 | Mem[BlockNum]=NewMem; 57 | TotalSize+=Size; 58 | MemSize[BlockNum]=TotalSize; 59 | BlockNum++; 60 | } 61 | if (TotalSize 0) 81 | { 82 | (*this)[UnpPtr]=(*this)[SrcPtr++ & MaxWinMask]; 83 | // We need to have masked UnpPtr after quit from loop, so it must not 84 | // be replaced with '(*this)[UnpPtr++ & MaxWinMask]' 85 | UnpPtr=(UnpPtr+1) & MaxWinMask; 86 | } 87 | } 88 | 89 | 90 | void FragmentedWindow::CopyData(byte *Dest,size_t WinPos,size_t Size) 91 | { 92 | for (size_t I=0;Ipw_uid; 25 | 26 | struct group *gr; 27 | errno=0; // Required by getgrnam specification if we need to check errno. 28 | if ((gr=getgrnam(Arc.UOHead.GroupName))==NULL) 29 | { 30 | uiMsg(UIERROR_UOWNERGETGROUPID,Arc.FileName,GetWide(Arc.UOHead.GroupName)); 31 | ErrHandler.SysErrMsg(); 32 | ErrHandler.SetErrorCode(RARX_CRC); 33 | return; 34 | } 35 | uint Attr=GetFileAttr(FileName); 36 | gid_t GroupID=gr->gr_gid; 37 | #if defined(SAVE_LINKS) && !defined(_APPLE) 38 | if (lchown(NameA,OwnerID,GroupID)!=0) 39 | #else 40 | if (chown(NameA,OwnerID,GroupID)!=0) 41 | #endif 42 | { 43 | uiMsg(UIERROR_UOWNERSET,Arc.FileName,FileName); 44 | ErrHandler.SetErrorCode(RARX_CREATE); 45 | } 46 | SetFileAttr(FileName,Attr); 47 | } 48 | 49 | 50 | void ExtractUnixOwner30(Archive &Arc,const wchar *FileName) 51 | { 52 | char NameA[NM]; 53 | WideToChar(FileName,NameA,ASIZE(NameA)); 54 | 55 | char *OwnerName=(char *)&Arc.SubHead.SubData[0]; 56 | int OwnerSize=strlen(OwnerName)+1; 57 | int GroupSize=Arc.SubHead.SubData.Size()-OwnerSize; 58 | char GroupName[NM]; 59 | strncpy(GroupName,(char *)&Arc.SubHead.SubData[OwnerSize],GroupSize); 60 | GroupName[GroupSize]=0; 61 | 62 | struct passwd *pw; 63 | if ((pw=getpwnam(OwnerName))==NULL) 64 | { 65 | uiMsg(UIERROR_UOWNERGETOWNERID,Arc.FileName,GetWide(OwnerName)); 66 | ErrHandler.SetErrorCode(RARX_WARNING); 67 | return; 68 | } 69 | uid_t OwnerID=pw->pw_uid; 70 | 71 | struct group *gr; 72 | if ((gr=getgrnam(GroupName))==NULL) 73 | { 74 | uiMsg(UIERROR_UOWNERGETGROUPID,Arc.FileName,GetWide(GroupName)); 75 | ErrHandler.SetErrorCode(RARX_WARNING); 76 | return; 77 | } 78 | uint Attr=GetFileAttr(FileName); 79 | gid_t GroupID=gr->gr_gid; 80 | #if defined(SAVE_LINKS) && !defined(_APPLE) 81 | if (lchown(NameA,OwnerID,GroupID)!=0) 82 | #else 83 | if (chown(NameA,OwnerID,GroupID)!=0) 84 | #endif 85 | { 86 | uiMsg(UIERROR_UOWNERSET,Arc.FileName,FileName); 87 | ErrHandler.SetErrorCode(RARX_CREATE); 88 | } 89 | SetFileAttr(FileName,Attr); 90 | } 91 | 92 | 93 | void SetUnixOwner(Archive &Arc,const wchar *FileName) 94 | { 95 | char NameA[NM]; 96 | WideToChar(FileName,NameA,ASIZE(NameA)); 97 | 98 | // First, we try to resolve symbolic names. If they are missing or cannot 99 | // be resolved, we try to use numeric values if any. If numeric values 100 | // are missing too, function fails. 101 | FileHeader &hd=Arc.FileHead; 102 | if (*hd.UnixOwnerName!=0) 103 | { 104 | struct passwd *pw; 105 | if ((pw=getpwnam(hd.UnixOwnerName))==NULL) 106 | { 107 | if (!hd.UnixOwnerNumeric) 108 | { 109 | uiMsg(UIERROR_UOWNERGETOWNERID,Arc.FileName,GetWide(hd.UnixOwnerName)); 110 | ErrHandler.SetErrorCode(RARX_WARNING); 111 | return; 112 | } 113 | } 114 | else 115 | hd.UnixOwnerID=pw->pw_uid; 116 | } 117 | if (*hd.UnixGroupName!=0) 118 | { 119 | struct group *gr; 120 | if ((gr=getgrnam(hd.UnixGroupName))==NULL) 121 | { 122 | if (!hd.UnixGroupNumeric) 123 | { 124 | uiMsg(UIERROR_UOWNERGETGROUPID,Arc.FileName,GetWide(hd.UnixGroupName)); 125 | ErrHandler.SetErrorCode(RARX_WARNING); 126 | return; 127 | } 128 | } 129 | else 130 | hd.UnixGroupID=gr->gr_gid; 131 | } 132 | #if defined(SAVE_LINKS) && !defined(_APPLE) 133 | if (lchown(NameA,hd.UnixOwnerID,hd.UnixGroupID)!=0) 134 | #else 135 | if (chown(NameA,hd.UnixOwnerID,hd.UnixGroupID)!=0) 136 | #endif 137 | { 138 | uiMsg(UIERROR_UOWNERSET,Arc.FileName,FileName); 139 | ErrHandler.SetErrorCode(RARX_CREATE); 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /Libraries/unrar/version.hpp: -------------------------------------------------------------------------------- 1 | #define RARVER_MAJOR 6 2 | #define RARVER_MINOR 12 3 | #define RARVER_BETA 0 4 | #define RARVER_DAY 4 5 | #define RARVER_MONTH 5 6 | #define RARVER_YEAR 2022 7 | -------------------------------------------------------------------------------- /Libraries/unrar/volume.hpp: -------------------------------------------------------------------------------- 1 | #ifndef _RAR_VOLUME_ 2 | #define _RAR_VOLUME_ 3 | 4 | void SplitArchive(Archive &Arc,FileHeader *fh,int64 *HeaderPos, 5 | ComprDataIO *DataIO); 6 | bool MergeArchive(Archive &Arc,ComprDataIO *DataIO,bool ShowFileName, 7 | wchar Command); 8 | void SetVolWrite(Archive &Dest,int64 VolSize); 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /Libraries/unrar/win32acl.cpp: -------------------------------------------------------------------------------- 1 | static void SetACLPrivileges(); 2 | 3 | static bool ReadSacl=false; 4 | 5 | 6 | 7 | #ifndef SFX_MODULE 8 | void ExtractACL20(Archive &Arc,const wchar *FileName) 9 | { 10 | SetACLPrivileges(); 11 | 12 | if (Arc.BrokenHeader) 13 | { 14 | uiMsg(UIERROR_ACLBROKEN,Arc.FileName,FileName); 15 | ErrHandler.SetErrorCode(RARX_CRC); 16 | return; 17 | } 18 | 19 | if (Arc.EAHead.Method<0x31 || Arc.EAHead.Method>0x35 || Arc.EAHead.UnpVer>VER_PACK) 20 | { 21 | uiMsg(UIERROR_ACLUNKNOWN,Arc.FileName,FileName); 22 | ErrHandler.SetErrorCode(RARX_WARNING); 23 | return; 24 | } 25 | 26 | ComprDataIO DataIO; 27 | Unpack Unpack(&DataIO); 28 | Unpack.Init(0x10000,false); 29 | 30 | Array UnpData(Arc.EAHead.UnpSize); 31 | DataIO.SetUnpackToMemory(&UnpData[0],Arc.EAHead.UnpSize); 32 | DataIO.SetPackedSizeToRead(Arc.EAHead.DataSize); 33 | DataIO.EnableShowProgress(false); 34 | DataIO.SetFiles(&Arc,NULL); 35 | DataIO.UnpHash.Init(HASH_CRC32,1); 36 | Unpack.SetDestSize(Arc.EAHead.UnpSize); 37 | Unpack.DoUnpack(Arc.EAHead.UnpVer,false); 38 | 39 | if (Arc.EAHead.EACRC!=DataIO.UnpHash.GetCRC32()) 40 | { 41 | uiMsg(UIERROR_ACLBROKEN,Arc.FileName,FileName); 42 | ErrHandler.SetErrorCode(RARX_CRC); 43 | return; 44 | } 45 | 46 | SECURITY_INFORMATION si=OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION| 47 | DACL_SECURITY_INFORMATION; 48 | if (ReadSacl) 49 | si|=SACL_SECURITY_INFORMATION; 50 | SECURITY_DESCRIPTOR *sd=(SECURITY_DESCRIPTOR *)&UnpData[0]; 51 | 52 | int SetCode=SetFileSecurity(FileName,si,sd); 53 | 54 | if (!SetCode) 55 | { 56 | uiMsg(UIERROR_ACLSET,Arc.FileName,FileName); 57 | DWORD LastError=GetLastError(); 58 | ErrHandler.SysErrMsg(); 59 | if (LastError==ERROR_ACCESS_DENIED && !IsUserAdmin()) 60 | uiMsg(UIERROR_NEEDADMIN); 61 | ErrHandler.SetErrorCode(RARX_WARNING); 62 | } 63 | } 64 | #endif 65 | 66 | 67 | void ExtractACL(Archive &Arc,const wchar *FileName) 68 | { 69 | Array SubData; 70 | if (!Arc.ReadSubData(&SubData,NULL,false)) 71 | return; 72 | 73 | SetACLPrivileges(); 74 | 75 | SECURITY_INFORMATION si=OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION| 76 | DACL_SECURITY_INFORMATION; 77 | if (ReadSacl) 78 | si|=SACL_SECURITY_INFORMATION; 79 | SECURITY_DESCRIPTOR *sd=(SECURITY_DESCRIPTOR *)&SubData[0]; 80 | 81 | int SetCode=SetFileSecurity(FileName,si,sd); 82 | if (!SetCode) 83 | { 84 | wchar LongName[NM]; 85 | if (GetWinLongPath(FileName,LongName,ASIZE(LongName))) 86 | SetCode=SetFileSecurity(LongName,si,sd); 87 | } 88 | 89 | if (!SetCode) 90 | { 91 | uiMsg(UIERROR_ACLSET,Arc.FileName,FileName); 92 | DWORD LastError=GetLastError(); 93 | ErrHandler.SysErrMsg(); 94 | if (LastError==ERROR_ACCESS_DENIED && !IsUserAdmin()) 95 | uiMsg(UIERROR_NEEDADMIN); 96 | ErrHandler.SetErrorCode(RARX_WARNING); 97 | } 98 | } 99 | 100 | 101 | void SetACLPrivileges() 102 | { 103 | static bool InitDone=false; 104 | if (InitDone) 105 | return; 106 | 107 | if (SetPrivilege(SE_SECURITY_NAME)) 108 | ReadSacl=true; 109 | SetPrivilege(SE_RESTORE_NAME); 110 | 111 | InitDone=true; 112 | } 113 | 114 | 115 | bool SetPrivilege(LPCTSTR PrivName) 116 | { 117 | bool Success=false; 118 | 119 | HANDLE hToken; 120 | if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)) 121 | { 122 | TOKEN_PRIVILEGES tp; 123 | tp.PrivilegeCount = 1; 124 | tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 125 | 126 | if (LookupPrivilegeValue(NULL,PrivName,&tp.Privileges[0].Luid) && 127 | AdjustTokenPrivileges(hToken, FALSE, &tp, 0, NULL, NULL) && 128 | GetLastError() == ERROR_SUCCESS) 129 | Success=true; 130 | 131 | CloseHandle(hToken); 132 | } 133 | 134 | return Success; 135 | } 136 | -------------------------------------------------------------------------------- /Resources/UnrarKit-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 2.10-beta8 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 2.10-beta8 23 | 24 | 25 | -------------------------------------------------------------------------------- /Resources/UnrarKitResources-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleIdentifier 8 | $(PRODUCT_BUNDLE_IDENTIFIER) 9 | CFBundleInfoDictionaryVersion 10 | 6.0 11 | CFBundleName 12 | $(PRODUCT_NAME) 13 | CFBundlePackageType 14 | BNDL 15 | CFBundleShortVersionString 16 | 2.10-beta8 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | 2.10-beta8 21 | NSHumanReadableCopyright 22 | Copyright © 2017 Abbey Code. All rights reserved. 23 | 24 | 25 | -------------------------------------------------------------------------------- /Resources/en.lproj/UnrarKit.strings: -------------------------------------------------------------------------------- 1 | /* Error detail string */ 2 | "An unknown error occurred" = "An unknown error occurred"; 3 | 4 | /* Error detail string */ 5 | "Archive has a corrupt header" = "Archive has a corrupt header"; 6 | 7 | /* Error detail string */ 8 | "Buffer too small to contain entire comments" = "Buffer too small to contain entire comments"; 9 | 10 | /* Error detail string */ 11 | "Error encountered while closing the archive" = "Error encountered while closing the archive"; 12 | 13 | /* Error detail string */ 14 | "Error encountered while reading the archive" = "Error encountered while reading the archive"; 15 | 16 | /* Error detail string */ 17 | "Error encountered while writing a file to disk" = "Error encountered while writing a file to disk"; 18 | 19 | /* Error detail string */ 20 | "Failed to create the target directory for extraction" = "Failed to create the target directory for extraction"; 21 | 22 | /* Error detail string */ 23 | "Failed to open a reference to the file" = "Failed to open a reference to the file"; 24 | 25 | /* Error detail string */ 26 | "File is not a valid RAR archive" = "File is not a valid RAR archive"; 27 | 28 | /* Error detail string */ 29 | "No password given to unlock a protected archive" = "No password given to unlock a protected archive"; 30 | 31 | /* Error detail string */ 32 | "Ran out of memory while reading archive" = "Ran out of memory while reading archive"; 33 | 34 | /* Error detail string */ 35 | "RAR headers encrypted in unknown format" = "RAR headers encrypted in unknown format"; 36 | 37 | /* Error detail string */ 38 | "Unable to find the archive" = "Unable to find the archive"; 39 | 40 | /* Error detail string */ 41 | "Unknown error encountered (code %ld)" = "Unknown error encountered (code %ld)"; 42 | 43 | /* Error detail string */ 44 | "User cancelled the operation in progress" = "User cancelled the operation in progress"; 45 | 46 | /* Error detail string */ 47 | "Provided password is incorrect" = "Provided password is incorrect"; 48 | 49 | -------------------------------------------------------------------------------- /Scripts/add-github-release.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: UTF-8 -*- 3 | 4 | # Usage: add-github-release.py 5 | # 6 | # Creates a release in GitHub for the given tag 7 | # 8 | 9 | import json 10 | import os 11 | import urllib2 12 | import sys 13 | 14 | def add_release(token, repo, tag, archive_path, notes): 15 | ''' 16 | Creates a release on GitHub for the given arguments 17 | ''' 18 | print('token: "{}", repo: "{}", tag: "{}", archive: "{}" notes: "{}"'.format('SECURE' if token else '', repo, tag, archive_path, notes)) 19 | 20 | assert token, 'No API token given' 21 | assert repo, 'No repo given' 22 | assert '/' in repo, "Repo doesn't look like a valid GitHub repo (e.g. abbeycode/UnrarKit)" 23 | assert tag, 'No tag given' 24 | assert archive_path, 'No archive path given' 25 | assert notes, 'No notes given' 26 | 27 | is_beta = tag_is_beta(tag) 28 | 29 | url = 'https://api.github.com/repos/{}/releases'.format(repo) 30 | header = { 31 | 'Authorization': 'token {}'.format(token) 32 | } 33 | values = { 34 | 'tag_name': tag, 35 | 'name': 'v{}'.format(tag), 36 | 'body': notes, 37 | 'prerelease': True if is_beta else False 38 | } 39 | 40 | data = json.dumps(values) 41 | request = urllib2.Request(url, data, header) 42 | response = urllib2.urlopen(request) 43 | the_page = response.read() 44 | 45 | response_dict = json.loads(the_page) 46 | upload_url = response_dict['upload_url'] 47 | release_url = response_dict['url'] 48 | 49 | upload_carthage_archive(token, upload_url, archive_path) 50 | 51 | print('Release added: {}'.format(release_url)) 52 | return True 53 | 54 | def tag_is_beta(tag): 55 | ''' 56 | Returns True if the tag contains a label indicating it's a beta build 57 | 58 | >>> tag_is_beta('1.2.3') 59 | False 60 | >>> tag_is_beta('1.2.3-beta') 61 | True 62 | >>> tag_is_beta('1.2.3-beta2') 63 | True 64 | >>> tag_is_beta('1.2.3-RC') 65 | True 66 | >>> tag_is_beta('1.2.3-RC1') 67 | True 68 | >>> tag_is_beta('1.2.3-prerelease') 69 | True 70 | >>> tag_is_beta('1.2.3-prerelease2') 71 | True 72 | >>> tag_is_beta('1.2.3-alpha') 73 | True 74 | >>> tag_is_beta('1.2.3-alpha2') 75 | True 76 | ''' 77 | 78 | return 'beta' in tag or 'RC' in tag or 'prerelease' in tag or 'alpha' in tag 79 | 80 | def upload_carthage_archive(token, upload_url, archive_path): 81 | ''' 82 | Uploads the archive at the given path to GitHub for the release specified 83 | ''' 84 | 85 | upload_url = upload_url.split('{')[0] 86 | url = '{}?name={}'.format(upload_url, archive_path) 87 | header = { 88 | 'Authorization': 'token {}'.format(token), 89 | 'Content-Type': 'application/zip' 90 | } 91 | 92 | with FileWithLen(archive_path, 'r') as f: 93 | request = urllib2.Request(url, f, header) 94 | response = urllib2.urlopen(request) 95 | 96 | page = response.read() 97 | response_dict = json.loads(page) 98 | return True 99 | 100 | class FileWithLen(file): 101 | def __init__(self, *args, **keyws): 102 | file.__init__(self, *args, **keyws) 103 | 104 | def __len__(self): 105 | return int(os.fstat(self.fileno())[6]) 106 | 107 | 108 | if __name__ == '__main__': 109 | # Allow script to be called with 'test' argument 110 | if len(sys.argv) == 2 and sys.argv[1].lower() == 'test': 111 | import doctest 112 | result = doctest.testmod() 113 | sys.exit(0 if result.failed == 0 else 1) 114 | 115 | expected_arg_count = 6 116 | 117 | if len(sys.argv) != expected_arg_count: 118 | print('\nadd-github-release given {} arguments ({}). Expecting {}\n'.format(len(sys.argv) - 1, sys.argv[1:], expected_arg_count - 1)) 119 | sys.exit(1) 120 | 121 | exit_code = 0 if add_release(*sys.argv[1:]) else 1 122 | sys.exit(exit_code) 123 | -------------------------------------------------------------------------------- /Scripts/archive-carthage.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ev 4 | 5 | # Archives the Carthage packages, and prints the name of the archive 6 | 7 | carthage build --use-xcframeworks --no-skip-current 8 | 9 | # This is currently broken, combined with the --use-xcframeworks option above, as of Carthage 0.38.0 on 2/17/2021 10 | carthage archive 11 | 12 | export ARCHIVE_PATH="UnrarKit.xcframework.zip" -------------------------------------------------------------------------------- /Scripts/carthage-validate.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | carthage --version 4 | 5 | REPO="github \"$TRAVIS_REPO_SLUG\"" 6 | COMMIT=$TRAVIS_COMMIT 7 | 8 | if [ -z ${TRAVIS+x} ]; then 9 | REPO="git \"`pwd`\"" 10 | COMMIT=`git log -1 --oneline | cut -f1 -d' '` 11 | echo "Not running in Travis. Setting REPO ($REPO) and COMMIT ($COMMIT)" 12 | fi 13 | 14 | if [ -n "$TRAVIS" ] && [ "$TRAVIS_PULL_REQUEST" != "false" ]; then 15 | REPO="github \"$TRAVIS_PULL_REQUEST_SLUG\"" 16 | COMMIT=$TRAVIS_PULL_REQUEST_SHA 17 | echo "Build is for a Pull Request. Overriding REPO ($REPO) and COMMIT ($COMMIT)" 18 | fi 19 | 20 | if [ ! -d "CarthageValidation" ]; then 21 | mkdir "CarthageValidation" 22 | fi 23 | 24 | echo "Validating commit '$COMMIT'" 25 | 26 | pushd CarthageValidation > /dev/null 27 | 28 | rm Cartfile 29 | rm Cartfile.resolved 30 | rm -rf Carthage 31 | 32 | echo "$REPO \"$COMMIT\"" > Cartfile 33 | 34 | 35 | carthage bootstrap --use-xcframeworks --configuration Debug --verbose 36 | EXIT_CODE=$? 37 | 38 | echo "Checking for build products..." 39 | 40 | if [ ! -d "Carthage/Build/UnrarKit.xcframework/macos-arm64_x86_64" ]; then 41 | echo "No Mac library built" 42 | EXIT_CODE=1 43 | fi 44 | 45 | if [ ! -d "Carthage/Build/UnrarKit.xcframework/ios-arm64" ]; then 46 | echo "No iOS library built" 47 | EXIT_CODE=1 48 | fi 49 | 50 | popd > /dev/null 51 | 52 | exit $EXIT_CODE -------------------------------------------------------------------------------- /Scripts/cocoapod-validate.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ev 4 | set -o pipefail 5 | 6 | git fetch --tags 7 | 8 | if [ -z "$TRAVIS_TAG" ]; then 9 | TRAVIS_TAG_SUBSTITUTED=1 10 | export TRAVIS_TAG="$(git tag -l | tail -1)" 11 | echo "Not a tagged build. Using last tag ($TRAVIS_TAG) for pod lib lint..." 12 | fi 13 | 14 | # For linting purposes, fix the error in dll.hpp 15 | sed -i .original 's/RARGetDllVersion();/RARGetDllVersion(void);/' Libraries/unrar/dll.hpp 16 | 17 | # Lint the podspec to check for errors. Don't call `pod spec lint`, because we want it to evaluate locally 18 | 19 | # Using sed to remove logging from output until CocoaPods issue #7577 is implemented and I can use the 20 | # OS_ACTIVITY_MODE = disable environment variable from the test spec scheme 21 | pod lib lint --verbose | sed -l '/xctest\[/d; /^$/d' 22 | 23 | # Put back the original dll.hpp 24 | mv Libraries/unrar/dll.hpp.original Libraries/unrar/dll.hpp 25 | 26 | if [ -n "$TRAVIS_TAG_SUBSTITUTED" ]; then 27 | echo "Unsetting TRAVIS_TAG..." 28 | unset TRAVIS_TAG 29 | fi 30 | -------------------------------------------------------------------------------- /Scripts/localize.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Generate Localizable.strings 4 | find -E . -iregex '.*\.(m|h|mm)$' \ 5 | -not -path "./Tests*" \ 6 | -print0 \ 7 | | xargs -0 genstrings -o Resources/en.lproj 8 | 9 | # Define file and temp file 10 | LOCALIZE=./Resources/en.lproj/UnrarKit.strings 11 | UTF8=./Resources/en.lproj/UnrarKitUTF8.txt 12 | 13 | # Convert file encoding from UTF-16 to UTF-8 14 | iconv -f UTF-16LE -t UTF-8 $LOCALIZE >$UTF8 15 | mv $UTF8 $LOCALIZE 16 | 17 | # Replace all \\n tokens in the file with a newline (used in comments) 18 | sed -i "" 's_\\\\n_\ 19 | _g' $LOCALIZE 20 | 21 | # Check for missing comments in the UTF8 file, showing the violating lines 22 | MISSING=$(grep -A 1 'engineer' $LOCALIZE | sed '/*\/$/ s_.*__') 23 | 24 | # If there were missing comments 25 | if [ -n "$MISSING" ]; then 26 | echo "Comments are missing for:" 27 | 28 | #Print output, putting line breaks back in and indenting each line 29 | echo $MISSING | sed 's:-- :\ 30 | :' | sed 's/^/& /g' 31 | 32 | # Return non-zero to signal an error 33 | exit 1 34 | fi -------------------------------------------------------------------------------- /Scripts/push-output.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ev 4 | 5 | # Only potentially push to CocoaPods when it's a tagged build 6 | if [ -z "$TRAVIS_TAG" ]; then 7 | echo -e "\nBuild is not tagged" 8 | exit 0 9 | fi 10 | 11 | # Make sure tag name looks like a version number 12 | if ! [[ $TRAVIS_TAG =~ ^[0-9\.]+(\-beta[0-9]*)?$ ]]; then 13 | echo -e "\nBranch build not a valid version number: $TRAVIS_TAG" 14 | exit 1 15 | else 16 | echo -e "\nTag looks like a version number: $TRAVIS_TAG" 17 | fi 18 | 19 | # Skip tests because they're assumed to have passed during the cocoapod-validate script or else 20 | # this script wouldn't run. Allow warnings, because prior validation doesn't, and it patches 21 | # around the one warning in the UnRAR library I can't silence 22 | echo -e "\nLinting podspec..." 23 | pod spec lint --fail-fast --skip-tests --allow-warnings 24 | 25 | if [ $? -ne 0 ]; then 26 | echo -e "\nPodspec failed lint. Run again with --verbose to troubleshoot" 27 | exit 1 28 | fi 29 | 30 | echo -e "\nExporting Carthage archive...\n" 31 | # Exports ARCHIVE_PATH, used below 32 | source ./Scripts/archive-carthage.sh 33 | 34 | # Skip tests and allow warnings for reasons stated above 35 | echo -e "\nPushing to CocoaPods...\n" 36 | pod trunk push --skip-tests --allow-warnings 37 | 38 | # If push is successful, add release to GitHub 39 | if [ $? -ne 0 ]; then 40 | echo -e "\nPush to CocoaPods failed" 41 | exit 1 42 | fi 43 | 44 | RELEASE_NOTES=$(./Scripts/get-release-notes.py "$TRAVIS_TAG") 45 | ./Scripts/add-github-release.py $GITHUB_RELEASE_API_TOKEN $TRAVIS_REPO_SLUG $TRAVIS_TAG "$ARCHIVE_PATH" "$RELEASE_NOTES" -------------------------------------------------------------------------------- /Scripts/set-version.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Usage: set-version.sh 4 | # 5 | # Updates the main plist file, then tags the build in Git, using the release notes from CHANGELOG.md 6 | 7 | # Colors 8 | COLOR_OFF='\033[0m' 9 | RED='\033[0;31m' 10 | GREEN='\033[0;32m' 11 | BOLD_YELLOW='\033[1;33m' 12 | 13 | # Did this script change since the last commit? 14 | THIS_FILE_REGEX='.*Scripts/set-version\.sh.*' 15 | THIS_FILE_CHANGED=$(git status --porcelain --untracked-files=no | grep $THIS_FILE_REGEX | wc -l) 16 | 17 | # Only continue if the repo has no changes (excluding this script) 18 | CHANGED_FILE_COUNT=$(git status --porcelain --untracked-files=no | grep -v $THIS_FILE_REGEX | wc -l) 19 | if [ $CHANGED_FILE_COUNT -gt 0 ]; then 20 | echo -e "${RED}Please commit or discard any changes before continuing$COLOR_OFF" 21 | exit 1 22 | fi 23 | 24 | # Require a single argument to be passed in 25 | if [ "$#" -ne 1 ]; then 26 | echo -e "${RED}Please pass the desired version number as an argument$COLOR_OFF" 27 | exit 1 28 | fi 29 | 30 | ./Scripts/get-release-notes.py $1 --beta-notes-check 31 | 32 | # Check whether beta notes have been updated. The check passes for first- or non-beta releases 33 | if [ ! $? -eq 0 ]; then 34 | exit 1 35 | fi 36 | 37 | RELEASE_NOTES=$(./Scripts/get-release-notes.py $1) 38 | if [ -z "$RELEASE_NOTES" ]; then 39 | echo -e "${RED}Please add release notes for v$1 into CHANGELOG.md$COLOR_OFF" 40 | exit 1 41 | fi 42 | 43 | # Require agvtool for updating the plist versions. Exit if not installed 44 | if ! [ -x "$(command -v agvtool)" ]; then 45 | echo -e "${RED}agvtool not found. Are you running on a Mac?$COLOR_OFF" 46 | exit 2 47 | fi 48 | 49 | echo -e "${GREEN}Updating version numbers in plist to '$1'..$COLOR_OFF" 50 | agvtool new-version -all "$1" # CFBundleVersion 51 | agvtool new-marketing-version "$1" # CFBundleShortVersionString 52 | 53 | if [ "$THIS_FILE_CHANGED" -gt 0 ]; then 54 | echo -e "${BOLD_YELLOW}Not committing to Git, as this script isn't final. Commit it to continue$COLOR_OFF" 55 | exit 2 56 | fi 57 | 58 | echo -e "${GREEN}Committing updated plist...$COLOR_OFF" 59 | git commit -m "Updated plist to v$1" Resources 60 | 61 | # Revert changes to other plist files 62 | git checkout . 63 | 64 | echo -e "${GREEN}Tagging build...$COLOR_OFF" 65 | git tag $1 -m "$RELEASE_NOTES" -------------------------------------------------------------------------------- /Tests/HasMultipleVolumesTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // HasMultipleVolumesTests.m 3 | // UnrarKit 4 | // 5 | // Created by Dov Frankel on 2/9/17. 6 | // 7 | // 8 | 9 | #import "URKArchiveTestCase.h" 10 | 11 | @interface HasMultipleVolumesTests : URKArchiveTestCase 12 | 13 | @end 14 | 15 | @implementation HasMultipleVolumesTests 16 | 17 | - (void)testSingleVolume { 18 | NSURL *testArchiveURL = self.testFileURLs[@"Test Archive.rar"]; 19 | URKArchive *archive = [[URKArchive alloc] initWithURL:testArchiveURL error:nil]; 20 | 21 | BOOL hasMultipleParts = archive.hasMultipleVolumes; 22 | 23 | XCTAssertFalse(hasMultipleParts, @"Single-volume archive reported to have multiple parts"); 24 | } 25 | 26 | #if !TARGET_OS_IPHONE 27 | - (void)testMultipleVolume_UseFirstVolume { 28 | NSArray *volumeURLs = [self multiPartArchiveWithName:@"HasMultipleVolumesTests-testMultipleVolume_UseFirstVolume.rar"]; 29 | URKArchive *archive = [[URKArchive alloc] initWithURL:volumeURLs.firstObject error:nil]; 30 | 31 | BOOL hasMultipleParts = archive.hasMultipleVolumes; 32 | XCTAssertTrue(hasMultipleParts, @"Multi-volume archive's first part not reported to have multiple volumes"); 33 | } 34 | #endif 35 | 36 | #if !TARGET_OS_IPHONE 37 | - (void)testMultipleVolume_UseMiddleVolume { 38 | NSArray *volumeURLs = [self multiPartArchiveWithName:@"HasMultipleVolumesTests-testMultipleVolume_UseMiddleVolume.rar"]; 39 | URKArchive *archive = [[URKArchive alloc] initWithURL:volumeURLs[2] error:nil]; 40 | 41 | BOOL hasMultipleParts = archive.hasMultipleVolumes; 42 | XCTAssertTrue(hasMultipleParts, @"Multi-volume archive's middle part not reported to have multiple volumes"); 43 | } 44 | #endif 45 | 46 | #if !TARGET_OS_IPHONE 47 | - (void)testMultipleVolume_UseFirstVolume_OldNamingScheme { 48 | NSArray *volumeURLs = [self multiPartArchiveOldSchemeWithName:@"HasMultipleVolumesTests-testMultipleVolume_UseFirstVolume_OldNamingScheme.rar"]; 49 | URKArchive *archive = [[URKArchive alloc] initWithURL:volumeURLs.firstObject error:nil]; 50 | 51 | BOOL hasMultipleParts = archive.hasMultipleVolumes; 52 | XCTAssertTrue(hasMultipleParts, @"Multi-volume archive's first part not reported to have multiple volumes"); 53 | } 54 | #endif 55 | 56 | #if !TARGET_OS_IPHONE 57 | - (void)testMultipleVolume_UseMiddleVolume_OldNamingScheme { 58 | NSArray *volumeURLs = [self multiPartArchiveOldSchemeWithName:@"HasMultipleVolumesTests-testMultipleVolume_UseMiddleVolume_OldNamingScheme.rar"]; 59 | URKArchive *archive = [[URKArchive alloc] initWithURL:volumeURLs[2] error:nil]; 60 | 61 | BOOL hasMultipleParts = archive.hasMultipleVolumes; 62 | XCTAssertTrue(hasMultipleParts, @"Multi-volume archive's middle part not reported to have multiple volumes"); 63 | } 64 | #endif 65 | 66 | - (void)testInvalidArchive { 67 | URKArchive *archive = [[URKArchive alloc] initWithURL:self.testFileURLs[@"Test File A.txt"] error:nil]; 68 | 69 | BOOL hasMultipleParts = archive.hasMultipleVolumes; 70 | XCTAssertFalse(hasMultipleParts, @"Invalid archive reported to have multiple volumes"); 71 | } 72 | 73 | @end 74 | -------------------------------------------------------------------------------- /Tests/IsPasswordProtectedTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // IsPasswordProtectedTests.m 3 | // UnrarKit 4 | // 5 | // Created by Dov Frankel on 6/22/15. 6 | // 7 | // 8 | 9 | #import "URKArchiveTestCase.h" 10 | 11 | @interface IsPasswordProtectedTests : URKArchiveTestCase 12 | 13 | @end 14 | 15 | @implementation IsPasswordProtectedTests 16 | 17 | - (void)testIsPasswordProtected_PasswordRequired 18 | { 19 | NSURL *archiveURL = self.testFileURLs[@"Test Archive (Password).rar"]; 20 | 21 | URKArchive *archive = [[URKArchive alloc] initWithURL:archiveURL error:nil]; 22 | 23 | XCTAssertTrue(archive.isPasswordProtected, @"isPasswordProtected = NO for password-protected archive"); 24 | } 25 | 26 | - (void)testIsPasswordProtected_PasswordRequired_RAR5 27 | { 28 | NSURL *archiveURL = self.testFileURLs[@"Test Archive (RAR5, Password).rar"]; 29 | 30 | URKArchive *archive = [[URKArchive alloc] initWithURL:archiveURL error:nil]; 31 | 32 | XCTAssertTrue(archive.isPasswordProtected, @"isPasswordProtected = NO for password-protected RAR5 archive"); 33 | } 34 | 35 | - (void)testIsPasswordProtected_HeaderPasswordRequired 36 | { 37 | NSURL *archiveURL = self.testFileURLs[@"Test Archive (Header Password).rar"]; 38 | 39 | URKArchive *archive = [[URKArchive alloc] initWithURL:archiveURL error:nil]; 40 | 41 | XCTAssertTrue(archive.isPasswordProtected, @"isPasswordProtected = NO for password-protected archive"); 42 | } 43 | 44 | - (void)testIsPasswordProtected_PasswordNotRequired 45 | { 46 | NSURL *archiveURL = self.testFileURLs[@"Test Archive.rar"]; 47 | 48 | URKArchive *archive = [[URKArchive alloc] initWithURL:archiveURL error:nil]; 49 | 50 | XCTAssertFalse(archive.isPasswordProtected, @"isPasswordProtected = YES for password-protected archive"); 51 | } 52 | 53 | @end 54 | -------------------------------------------------------------------------------- /Tests/Test Data/Folder Archive.rar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abbeycode/UnrarKit/7cd8c32bcfc1e1a7d16bc5b58cbd37a6eaf8b316/Tests/Test Data/Folder Archive.rar -------------------------------------------------------------------------------- /Tests/Test Data/Good CRC Archive.rar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abbeycode/UnrarKit/7cd8c32bcfc1e1a7d16bc5b58cbd37a6eaf8b316/Tests/Test Data/Good CRC Archive.rar -------------------------------------------------------------------------------- /Tests/Test Data/Modified CRC Archive.rar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abbeycode/UnrarKit/7cd8c32bcfc1e1a7d16bc5b58cbd37a6eaf8b316/Tests/Test Data/Modified CRC Archive.rar -------------------------------------------------------------------------------- /Tests/Test Data/Test Archive (Header Password).rar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abbeycode/UnrarKit/7cd8c32bcfc1e1a7d16bc5b58cbd37a6eaf8b316/Tests/Test Data/Test Archive (Header Password).rar -------------------------------------------------------------------------------- /Tests/Test Data/Test Archive (Password).rar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abbeycode/UnrarKit/7cd8c32bcfc1e1a7d16bc5b58cbd37a6eaf8b316/Tests/Test Data/Test Archive (Password).rar -------------------------------------------------------------------------------- /Tests/Test Data/Test Archive (RAR5).rar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abbeycode/UnrarKit/7cd8c32bcfc1e1a7d16bc5b58cbd37a6eaf8b316/Tests/Test Data/Test Archive (RAR5).rar -------------------------------------------------------------------------------- /Tests/Test Data/Test Archive (RAR5, Password).rar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abbeycode/UnrarKit/7cd8c32bcfc1e1a7d16bc5b58cbd37a6eaf8b316/Tests/Test Data/Test Archive (RAR5, Password).rar -------------------------------------------------------------------------------- /Tests/Test Data/Test Archive.rar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abbeycode/UnrarKit/7cd8c32bcfc1e1a7d16bc5b58cbd37a6eaf8b316/Tests/Test Data/Test Archive.rar -------------------------------------------------------------------------------- /Tests/Test Data/Test File A.txt: -------------------------------------------------------------------------------- 1 | Test File A (secret message here) -------------------------------------------------------------------------------- /Tests/Test Data/Test File B.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abbeycode/UnrarKit/7cd8c32bcfc1e1a7d16bc5b58cbd37a6eaf8b316/Tests/Test Data/Test File B.jpg -------------------------------------------------------------------------------- /Tests/Test Data/Test File C.m4a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abbeycode/UnrarKit/7cd8c32bcfc1e1a7d16bc5b58cbd37a6eaf8b316/Tests/Test Data/Test File C.m4a -------------------------------------------------------------------------------- /Tests/Test Data/Test File Ⓐ.txt: -------------------------------------------------------------------------------- 1 | Test File A (secret message here) -------------------------------------------------------------------------------- /Tests/Test Data/Test File Ⓑ.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abbeycode/UnrarKit/7cd8c32bcfc1e1a7d16bc5b58cbd37a6eaf8b316/Tests/Test Data/Test File Ⓑ.jpg -------------------------------------------------------------------------------- /Tests/Test Data/Test File Ⓒ.m4a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abbeycode/UnrarKit/7cd8c32bcfc1e1a7d16bc5b58cbd37a6eaf8b316/Tests/Test Data/Test File Ⓒ.m4a -------------------------------------------------------------------------------- /Tests/Test Data/bin/arm/rar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abbeycode/UnrarKit/7cd8c32bcfc1e1a7d16bc5b58cbd37a6eaf8b316/Tests/Test Data/bin/arm/rar -------------------------------------------------------------------------------- /Tests/Test Data/bin/x64/rar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abbeycode/UnrarKit/7cd8c32bcfc1e1a7d16bc5b58cbd37a6eaf8b316/Tests/Test Data/bin/x64/rar -------------------------------------------------------------------------------- /Tests/Test Data/Ⓣest Ⓐrchive.rar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abbeycode/UnrarKit/7cd8c32bcfc1e1a7d16bc5b58cbd37a6eaf8b316/Tests/Test Data/Ⓣest Ⓐrchive.rar -------------------------------------------------------------------------------- /Tests/URKArchiveTestCase.h: -------------------------------------------------------------------------------- 1 | // 2 | // URKArchiveTestCase.h 3 | // UnrarKit 4 | // 5 | // Created by Dov Frankel on 6/22/15. 6 | // 7 | // 8 | 9 | #import "TargetConditionals.h" 10 | 11 | #if TARGET_OS_IPHONE 12 | #import 13 | #else 14 | #import 15 | #endif 16 | 17 | @import XCTest; 18 | @import UnrarKit; 19 | 20 | 21 | @interface URKArchiveTestCase : XCTestCase 22 | 23 | @property BOOL testFailed; 24 | 25 | @property NSURL *tempDirectory; 26 | @property NSMutableDictionary *testFileURLs; 27 | @property NSMutableDictionary *unicodeFileURLs; 28 | @property NSURL *corruptArchive; 29 | 30 | 31 | - (NSURL *)urlOfTestFile:(NSString *)filename; 32 | - (NSString *)randomDirectoryName; 33 | - (NSString *)randomDirectoryWithPrefix:(NSString *)prefix; 34 | - (NSURL *)randomTextFileOfLength:(NSUInteger)numberOfCharacters; 35 | - (NSUInteger)crcOfTestFile:(NSString *)filename; 36 | 37 | // Mac Only 38 | 39 | #if !TARGET_OS_IPHONE 40 | - (NSURL *)largeArchiveURL; 41 | - (NSInteger)numberOfOpenFileHandles; 42 | - (NSURL *)archiveWithFiles:(NSArray *)fileURLs; 43 | 44 | - (NSURL *)archiveWithFiles:(NSArray *)fileURLs arguments:(NSArray *)customArgs; 45 | - (NSURL *)archiveWithFiles:(NSArray *)fileURLs arguments:(NSArray *)customArgs commandOutput:(NSString **)commandOutput; 46 | 47 | - (NSURL *)archiveWithFiles:(NSArray *)fileURLs name:(NSString *)archiveName; 48 | - (NSURL *)archiveWithFiles:(NSArray *)fileURLs name:(NSString *)archiveName arguments:(NSArray *)customArgs; 49 | - (NSURL *)archiveWithFiles:(NSArray *)fileURLs name:(NSString *)archiveName arguments:(NSArray *)customArgs commandOutput:(NSString **)commandOutput; 50 | 51 | - (NSArray *)multiPartArchiveWithName:(NSString *)baseName; 52 | - (NSArray *)multiPartArchiveWithName:(NSString *)baseName fileSize:(NSUInteger)fileSize; 53 | - (NSArray *)multiPartArchiveOldSchemeWithName:(NSString *)baseName; 54 | #endif 55 | 56 | @end 57 | 58 | @interface NSString (URKArchiveTestCaseExtensions) 59 | 60 | /** 61 | * Returns all of the regex matches in the given string 62 | * 63 | * @param expression The regex expression to match. Must contain exactly one capture group 64 | */ 65 | - (NSArray *)regexMatches:(NSString *)expression; 66 | 67 | @end 68 | -------------------------------------------------------------------------------- /Tests/URKArchiveTestCase.swift: -------------------------------------------------------------------------------- 1 | // 2 | // URKArchiveTestCase.swift 3 | // UnrarKit Tests 4 | // 5 | // Created by Dov Frankel on 8/1/22. 6 | // 7 | 8 | import Foundation 9 | 10 | @objc public extension URKArchiveTestCase { 11 | 12 | var machineHardwareName: String? { 13 | var sysinfo = utsname() 14 | guard uname(&sysinfo) == EXIT_SUCCESS else { return nil } 15 | 16 | let data = Data(bytes: &sysinfo.machine, count: Int(_SYS_NAMELEN)) 17 | guard let identifier = String(bytes: data, encoding: .ascii) else { return nil } 18 | return identifier.trimmingCharacters(in: .controlCharacters) 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /Tests/UnrarKit Tests-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | // 2 | // Use this file to import your target's public headers that you would like to expose to Swift. 3 | // 4 | 5 | #import "URKArchiveTestCase.h" 6 | -------------------------------------------------------------------------------- /Tests/UnrarKit Tests-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /Tests/ValidatePasswordTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // ValidatePasswordTests.m 3 | // UnrarKit 4 | // 5 | // Created by Dov Frankel on 6/22/15. 6 | // 7 | // 8 | 9 | #import "URKArchiveTestCase.h" 10 | 11 | @interface ValidatePasswordTests : URKArchiveTestCase @end 12 | 13 | @implementation ValidatePasswordTests 14 | 15 | - (void)testValidatePassword_PasswordRequired 16 | { 17 | NSURL *archiveURL = self.testFileURLs[@"Test Archive (Password).rar"]; 18 | 19 | URKArchive *archive = [[URKArchive alloc] initWithURL:archiveURL error:nil]; 20 | 21 | XCTAssertFalse(archive.validatePassword, @"validatePassword = YES when no password supplied"); 22 | 23 | archive.password = @"wrong"; 24 | XCTAssertFalse(archive.validatePassword, @"validatePassword = YES when wrong password supplied"); 25 | 26 | archive.password = @"password"; 27 | XCTAssertTrue(archive.validatePassword, @"validatePassword = NO when correct password supplied"); 28 | } 29 | 30 | - (void)testValidatePassword_HeaderPasswordRequired 31 | { 32 | NSURL *archiveURL = self.testFileURLs[@"Test Archive (Header Password).rar"]; 33 | 34 | URKArchive *archive = [[URKArchive alloc] initWithURL:archiveURL error:nil]; 35 | 36 | XCTAssertFalse(archive.validatePassword, @"validatePassword = YES when no password supplied"); 37 | 38 | archive.password = @"wrong"; 39 | XCTAssertFalse(archive.validatePassword, @"validatePassword = YES when wrong password supplied"); 40 | 41 | archive.password = @"password"; 42 | XCTAssertTrue(archive.validatePassword, @"validatePassword = NO when correct password supplied"); 43 | } 44 | 45 | - (void)testValidatePassword_PasswordNotRequired 46 | { 47 | NSURL *archiveURL = self.testFileURLs[@"Test Archive.rar"]; 48 | 49 | URKArchive *archive = [[URKArchive alloc] initWithURL:archiveURL error:nil]; 50 | 51 | XCTAssertTrue(archive.validatePassword, @"validatePassword = NO when no password supplied"); 52 | 53 | archive.password = @"password"; 54 | XCTAssertTrue(archive.validatePassword, @"validatePassword = NO when password supplied"); 55 | } 56 | 57 | - (void)testValidatePassword_RAR5 58 | { 59 | NSURL *archiveURL = self.testFileURLs[@"Test Archive (RAR5, Password).rar"]; 60 | 61 | URKArchive *archive = [[URKArchive alloc] initWithURL:archiveURL error:nil]; 62 | 63 | XCTAssertFalse(archive.validatePassword, @"validatePassword = YES when no password supplied"); 64 | 65 | archive.password = @"wrong"; 66 | XCTAssertFalse(archive.validatePassword, @"validatePassword = YES when wrong password supplied"); 67 | 68 | archive.password = @"123"; 69 | XCTAssertTrue(archive.validatePassword, @"validatePassword = NO when correct password supplied"); 70 | } 71 | 72 | 73 | @end 74 | -------------------------------------------------------------------------------- /Tests/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /UnrarKit.xcodeproj/.gitignore: -------------------------------------------------------------------------------- 1 | /rogerio.mode1v3 2 | /rogerio.pbxuser 3 | -------------------------------------------------------------------------------- /UnrarKit.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /UnrarKit.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /UnrarKit.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /UnrarKit.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEWorkspaceSharedSettings_AutocreateContextsIfNeeded 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /beta-notes.md: -------------------------------------------------------------------------------- 1 | Fixed crash in `-_unrarOpenFile:inMode:withPassword:error:` (PR #97) --------------------------------------------------------------------------------