Adding initial files which contains the unrar.3.9.6 sources and a patch for the Makefile

This commit is contained in:
Robert McGovern 2009-11-10 16:48:42 +01:00
commit 9929851140
135 changed files with 31441 additions and 0 deletions

View File

@ -0,0 +1,2 @@
/* Localized versions of Info.plist keys */

4119
English.lproj/MainMenu.xib Normal file

File diff suppressed because it is too large Load Diff

281
QuietUnrar-Info.plist Normal file
View File

@ -0,0 +1,281 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>rar</string>
<string>r00</string>
<string>r01</string>
<string>r02</string>
<string>r03</string>
<string>r04</string>
<string>r05</string>
<string>r06</string>
<string>r07</string>
<string>r08</string>
<string>r09</string>
<string>r10</string>
<string>r11</string>
<string>r12</string>
<string>r13</string>
<string>r14</string>
<string>r15</string>
<string>r16</string>
<string>r17</string>
<string>r18</string>
<string>r19</string>
<string>r20</string>
<string>r21</string>
<string>r22</string>
<string>r23</string>
<string>r24</string>
<string>r25</string>
<string>r26</string>
<string>r27</string>
<string>r28</string>
<string>r29</string>
<string>r30</string>
<string>r31</string>
<string>r32</string>
<string>r33</string>
<string>r34</string>
<string>r35</string>
<string>r36</string>
<string>r37</string>
<string>r38</string>
<string>r39</string>
<string>r40</string>
<string>r41</string>
<string>r42</string>
<string>r43</string>
<string>r44</string>
<string>r45</string>
<string>r46</string>
<string>r47</string>
<string>r48</string>
<string>r49</string>
<string>r50</string>
<string>r51</string>
<string>r52</string>
<string>r53</string>
<string>r54</string>
<string>r55</string>
<string>r56</string>
<string>r57</string>
<string>r58</string>
<string>r59</string>
<string>r60</string>
<string>r61</string>
<string>r62</string>
<string>r63</string>
<string>r64</string>
<string>r65</string>
<string>r66</string>
<string>r67</string>
<string>r68</string>
<string>r69</string>
<string>r70</string>
<string>r71</string>
<string>r72</string>
<string>r73</string>
<string>r74</string>
<string>r75</string>
<string>r76</string>
<string>r77</string>
<string>r78</string>
<string>r79</string>
<string>r80</string>
<string>r81</string>
<string>r82</string>
<string>r83</string>
<string>r84</string>
<string>r85</string>
<string>r86</string>
<string>r87</string>
<string>r88</string>
<string>r89</string>
<string>r90</string>
<string>r91</string>
<string>r92</string>
<string>r93</string>
<string>r94</string>
<string>r95</string>
<string>r96</string>
<string>r97</string>
<string>r98</string>
<string>r99</string>
</array>
<key>CFBundleTypeIconFile</key>
<string></string>
<key>CFBundleTypeName</key>
<string>RAR Archive</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
<key>LSItemContentTypes</key>
<array>
<string>com.rarlab.rar-archive</string>
</array>
<key>NSDocumentClass</key>
<string>ZipDocument</string>
</dict>
</array>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIconFile</key>
<string></string>
<key>CFBundleIdentifier</key>
<string>com.yourcompany.${PRODUCT_NAME:rfc1034identifier}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSMinimumSystemVersion</key>
<string>${MACOSX_DEPLOYMENT_TARGET}</string>
<key>NSMainNibFile</key>
<string>MainMenu</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
<key>UTImportedTypeDeclarations</key>
<array>
<dict>
<key>UTTypeConformsTo</key>
<array>
<string>public.data</string>
<string>public.archive</string>
</array>
<key>UTTypeDescription</key>
<string>RAR Archive</string>
<key>UTTypeIconFile</key>
<string>RAR</string>
<key>UTTypeIdentifier</key>
<string>com.rarlab.rar-archive</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>rar</string>
<string>r00</string>
<string>r01</string>
<string>r02</string>
<string>r03</string>
<string>r04</string>
<string>r05</string>
<string>r06</string>
<string>r07</string>
<string>r08</string>
<string>r09</string>
<string>r10</string>
<string>r11</string>
<string>r12</string>
<string>r13</string>
<string>r14</string>
<string>r15</string>
<string>r16</string>
<string>r17</string>
<string>r18</string>
<string>r19</string>
<string>r20</string>
<string>r21</string>
<string>r22</string>
<string>r23</string>
<string>r24</string>
<string>r25</string>
<string>r26</string>
<string>r27</string>
<string>r28</string>
<string>r29</string>
<string>r30</string>
<string>r31</string>
<string>r32</string>
<string>r33</string>
<string>r34</string>
<string>r35</string>
<string>r36</string>
<string>r37</string>
<string>r38</string>
<string>r39</string>
<string>r40</string>
<string>r41</string>
<string>r42</string>
<string>r43</string>
<string>r44</string>
<string>r45</string>
<string>r46</string>
<string>r47</string>
<string>r48</string>
<string>r49</string>
<string>r50</string>
<string>r51</string>
<string>r52</string>
<string>r53</string>
<string>r54</string>
<string>r55</string>
<string>r56</string>
<string>r57</string>
<string>r58</string>
<string>r59</string>
<string>r60</string>
<string>r61</string>
<string>r62</string>
<string>r63</string>
<string>r64</string>
<string>r65</string>
<string>r66</string>
<string>r67</string>
<string>r68</string>
<string>r69</string>
<string>r70</string>
<string>r71</string>
<string>r72</string>
<string>r73</string>
<string>r74</string>
<string>r75</string>
<string>r76</string>
<string>r77</string>
<string>r78</string>
<string>r79</string>
<string>r80</string>
<string>r81</string>
<string>r82</string>
<string>r83</string>
<string>r84</string>
<string>r85</string>
<string>r86</string>
<string>r87</string>
<string>r88</string>
<string>r89</string>
<string>r90</string>
<string>r91</string>
<string>r92</string>
<string>r93</string>
<string>r94</string>
<string>r95</string>
<string>r96</string>
<string>r97</string>
<string>r98</string>
<string>r99</string>
</array>
<key>public.mime-type</key>
<array>
<string>application/x-rar</string>
<string>application/x-rar-compressed</string>
</array>
</dict>
</dict>
</array>
</dict>
</plist>

View File

@ -0,0 +1,610 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
256AC3DA0F4B6AC300CF3369 /* QuietUnrarAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 256AC3D90F4B6AC300CF3369 /* QuietUnrarAppDelegate.m */; };
8D11072D0486CEB800E47090 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; settings = {ATTRIBUTES = (); }; };
8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; };
D4A49691105435BE00BE38AE /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */; };
D4A49692105435C100BE38AE /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1DDD58140DA1D0A300B32029 /* MainMenu.xib */; };
D4A96E2110545E9A0091ECB4 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D4A96E2010545E9A0091ECB4 /* Carbon.framework */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
D4A4964C10541CFF00BE38AE /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
proxyType = 1;
remoteGlobalIDString = D4A4962A105419AA00BE38AE;
remoteInfo = libunrar;
};
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
D4A4965210541D2600BE38AE /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 7;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
089C165DFE840E0CC02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; };
1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
13E42FB307B3F0F600E4EEF1 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = "<absolute>"; };
1DDD58150DA1D0A300B32029 /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = English.lproj/MainMenu.xib; sourceTree = "<group>"; };
256AC3D80F4B6AC300CF3369 /* QuietUnrarAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QuietUnrarAppDelegate.h; sourceTree = "<group>"; };
256AC3D90F4B6AC300CF3369 /* QuietUnrarAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QuietUnrarAppDelegate.m; sourceTree = "<group>"; };
256AC3F00F4B6AF500CF3369 /* QuietUnrar_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QuietUnrar_Prefix.pch; sourceTree = "<group>"; };
29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
29B97324FDCFA39411CA2CEA /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = "<absolute>"; };
29B97325FDCFA39411CA2CEA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = "<absolute>"; };
8D1107310486CEB800E47090 /* QuietUnrar-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "QuietUnrar-Info.plist"; sourceTree = "<group>"; };
8D1107320486CEB800E47090 /* QuietUnrar.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = QuietUnrar.app; sourceTree = BUILT_PRODUCTS_DIR; };
D4A495741054177300BE38AE /* arccmt.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = arccmt.cpp; path = libunrar/arccmt.cpp; sourceTree = "<group>"; };
D4A495751054177300BE38AE /* archive.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = archive.cpp; path = libunrar/archive.cpp; sourceTree = "<group>"; };
D4A495761054177300BE38AE /* archive.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = archive.hpp; path = libunrar/archive.hpp; sourceTree = "<group>"; };
D4A495771054177300BE38AE /* arcread.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = arcread.cpp; path = libunrar/arcread.cpp; sourceTree = "<group>"; };
D4A495781054177300BE38AE /* array.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = array.hpp; path = libunrar/array.hpp; sourceTree = "<group>"; };
D4A495791054177300BE38AE /* beosea.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = beosea.cpp; path = libunrar/beosea.cpp; sourceTree = "<group>"; };
D4A4957A1054177300BE38AE /* cmddata.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = cmddata.cpp; path = libunrar/cmddata.cpp; sourceTree = "<group>"; };
D4A4957B1054177300BE38AE /* cmddata.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = cmddata.hpp; path = libunrar/cmddata.hpp; sourceTree = "<group>"; };
D4A4957C1054177300BE38AE /* coder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = coder.cpp; path = libunrar/coder.cpp; sourceTree = "<group>"; };
D4A4957D1054177300BE38AE /* coder.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = coder.hpp; path = libunrar/coder.hpp; sourceTree = "<group>"; };
D4A4957E1054177300BE38AE /* compress.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = compress.hpp; path = libunrar/compress.hpp; sourceTree = "<group>"; };
D4A4957F1054177300BE38AE /* consio.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = consio.cpp; path = libunrar/consio.cpp; sourceTree = "<group>"; };
D4A495801054177300BE38AE /* consio.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = consio.hpp; path = libunrar/consio.hpp; sourceTree = "<group>"; };
D4A495811054177300BE38AE /* crc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = crc.cpp; path = libunrar/crc.cpp; sourceTree = "<group>"; };
D4A495821054177300BE38AE /* crc.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = crc.hpp; path = libunrar/crc.hpp; sourceTree = "<group>"; };
D4A495831054177300BE38AE /* crypt.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = crypt.cpp; path = libunrar/crypt.cpp; sourceTree = "<group>"; };
D4A495841054177300BE38AE /* crypt.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = crypt.hpp; path = libunrar/crypt.hpp; sourceTree = "<group>"; };
D4A495851054177300BE38AE /* dll.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = dll.cpp; path = libunrar/dll.cpp; sourceTree = "<group>"; };
D4A495861054177300BE38AE /* dll.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = dll.hpp; path = libunrar/dll.hpp; sourceTree = "<group>"; };
D4A495871054177300BE38AE /* encname.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = encname.cpp; path = libunrar/encname.cpp; sourceTree = "<group>"; };
D4A495881054177300BE38AE /* encname.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = encname.hpp; path = libunrar/encname.hpp; sourceTree = "<group>"; };
D4A495891054177300BE38AE /* errhnd.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = errhnd.cpp; path = libunrar/errhnd.cpp; sourceTree = "<group>"; };
D4A4958A1054177300BE38AE /* errhnd.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = errhnd.hpp; path = libunrar/errhnd.hpp; sourceTree = "<group>"; };
D4A4958B1054177300BE38AE /* extinfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = extinfo.cpp; path = libunrar/extinfo.cpp; sourceTree = "<group>"; };
D4A4958C1054177300BE38AE /* extinfo.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = extinfo.hpp; path = libunrar/extinfo.hpp; sourceTree = "<group>"; };
D4A4958D1054177300BE38AE /* extract.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = extract.cpp; path = libunrar/extract.cpp; sourceTree = "<group>"; };
D4A4958E1054177300BE38AE /* extract.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = extract.hpp; path = libunrar/extract.hpp; sourceTree = "<group>"; };
D4A4958F1054177300BE38AE /* filcreat.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = filcreat.cpp; path = libunrar/filcreat.cpp; sourceTree = "<group>"; };
D4A495901054177300BE38AE /* filcreat.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = filcreat.hpp; path = libunrar/filcreat.hpp; sourceTree = "<group>"; };
D4A495911054177300BE38AE /* file.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = file.cpp; path = libunrar/file.cpp; sourceTree = "<group>"; };
D4A495921054177300BE38AE /* file.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = file.hpp; path = libunrar/file.hpp; sourceTree = "<group>"; };
D4A495931054177300BE38AE /* filefn.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = filefn.cpp; path = libunrar/filefn.cpp; sourceTree = "<group>"; };
D4A495941054177300BE38AE /* filefn.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = filefn.hpp; path = libunrar/filefn.hpp; sourceTree = "<group>"; };
D4A495951054177300BE38AE /* filestr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = filestr.cpp; path = libunrar/filestr.cpp; sourceTree = "<group>"; };
D4A495961054177300BE38AE /* filestr.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = filestr.hpp; path = libunrar/filestr.hpp; sourceTree = "<group>"; };
D4A495971054177300BE38AE /* find.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = find.cpp; path = libunrar/find.cpp; sourceTree = "<group>"; };
D4A495981054177300BE38AE /* find.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = find.hpp; path = libunrar/find.hpp; sourceTree = "<group>"; };
D4A495991054177300BE38AE /* getbits.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = getbits.cpp; path = libunrar/getbits.cpp; sourceTree = "<group>"; };
D4A4959A1054177300BE38AE /* getbits.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = getbits.hpp; path = libunrar/getbits.hpp; sourceTree = "<group>"; };
D4A4959B1054177300BE38AE /* global.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = global.cpp; path = libunrar/global.cpp; sourceTree = "<group>"; };
D4A4959C1054177300BE38AE /* global.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = global.hpp; path = libunrar/global.hpp; sourceTree = "<group>"; };
D4A4959D1054177300BE38AE /* headers.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = headers.hpp; path = libunrar/headers.hpp; sourceTree = "<group>"; };
D4A4959E1054177300BE38AE /* isnt.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = isnt.cpp; path = libunrar/isnt.cpp; sourceTree = "<group>"; };
D4A4959F1054177300BE38AE /* isnt.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = isnt.hpp; path = libunrar/isnt.hpp; sourceTree = "<group>"; };
D4A495A01054177300BE38AE /* list.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = list.cpp; path = libunrar/list.cpp; sourceTree = "<group>"; };
D4A495A11054177300BE38AE /* list.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = list.hpp; path = libunrar/list.hpp; sourceTree = "<group>"; };
D4A495A21054177300BE38AE /* loclang.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = loclang.hpp; path = libunrar/loclang.hpp; sourceTree = "<group>"; };
D4A495A31054177300BE38AE /* log.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = log.cpp; path = libunrar/log.cpp; sourceTree = "<group>"; };
D4A495A41054177300BE38AE /* log.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = log.hpp; path = libunrar/log.hpp; sourceTree = "<group>"; };
D4A495A51054177300BE38AE /* makefile.unix */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = makefile.unix; path = libunrar/makefile.unix; sourceTree = "<group>"; };
D4A495A61054177300BE38AE /* match.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = match.cpp; path = libunrar/match.cpp; sourceTree = "<group>"; };
D4A495A71054177300BE38AE /* match.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = match.hpp; path = libunrar/match.hpp; sourceTree = "<group>"; };
D4A495A81054177300BE38AE /* model.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = model.cpp; path = libunrar/model.cpp; sourceTree = "<group>"; };
D4A495A91054177300BE38AE /* model.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = model.hpp; path = libunrar/model.hpp; sourceTree = "<group>"; };
D4A495AA1054177300BE38AE /* options.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = options.cpp; path = libunrar/options.cpp; sourceTree = "<group>"; };
D4A495AB1054177300BE38AE /* options.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = options.hpp; path = libunrar/options.hpp; sourceTree = "<group>"; };
D4A495AC1054177300BE38AE /* os.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = os.hpp; path = libunrar/os.hpp; sourceTree = "<group>"; };
D4A495AD1054177300BE38AE /* os2ea.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = os2ea.cpp; path = libunrar/os2ea.cpp; sourceTree = "<group>"; };
D4A495AE1054177300BE38AE /* pathfn.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = pathfn.cpp; path = libunrar/pathfn.cpp; sourceTree = "<group>"; };
D4A495AF1054177300BE38AE /* pathfn.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = pathfn.hpp; path = libunrar/pathfn.hpp; sourceTree = "<group>"; };
D4A495B01054177300BE38AE /* rar.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = rar.cpp; path = libunrar/rar.cpp; sourceTree = "<group>"; };
D4A495B11054177300BE38AE /* rar.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = rar.hpp; path = libunrar/rar.hpp; sourceTree = "<group>"; };
D4A495B21054177300BE38AE /* rardefs.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = rardefs.hpp; path = libunrar/rardefs.hpp; sourceTree = "<group>"; };
D4A495B31054177300BE38AE /* rarlang.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = rarlang.hpp; path = libunrar/rarlang.hpp; sourceTree = "<group>"; };
D4A495B41054177300BE38AE /* raros.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = raros.hpp; path = libunrar/raros.hpp; sourceTree = "<group>"; };
D4A495B51054177300BE38AE /* rartypes.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = rartypes.hpp; path = libunrar/rartypes.hpp; sourceTree = "<group>"; };
D4A495B61054177300BE38AE /* rarvm.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = rarvm.cpp; path = libunrar/rarvm.cpp; sourceTree = "<group>"; };
D4A495B71054177300BE38AE /* rarvm.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = rarvm.hpp; path = libunrar/rarvm.hpp; sourceTree = "<group>"; };
D4A495B81054177300BE38AE /* rarvmtbl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = rarvmtbl.cpp; path = libunrar/rarvmtbl.cpp; sourceTree = "<group>"; };
D4A495B91054177300BE38AE /* rawread.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = rawread.cpp; path = libunrar/rawread.cpp; sourceTree = "<group>"; };
D4A495BA1054177300BE38AE /* rawread.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = rawread.hpp; path = libunrar/rawread.hpp; sourceTree = "<group>"; };
D4A495BB1054177300BE38AE /* rdwrfn.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = rdwrfn.cpp; path = libunrar/rdwrfn.cpp; sourceTree = "<group>"; };
D4A495BC1054177300BE38AE /* rdwrfn.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = rdwrfn.hpp; path = libunrar/rdwrfn.hpp; sourceTree = "<group>"; };
D4A495BD1054177300BE38AE /* recvol.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = recvol.cpp; path = libunrar/recvol.cpp; sourceTree = "<group>"; };
D4A495BE1054177300BE38AE /* recvol.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = recvol.hpp; path = libunrar/recvol.hpp; sourceTree = "<group>"; };
D4A495BF1054177300BE38AE /* resource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = resource.cpp; path = libunrar/resource.cpp; sourceTree = "<group>"; };
D4A495C01054177300BE38AE /* resource.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = resource.hpp; path = libunrar/resource.hpp; sourceTree = "<group>"; };
D4A495C11054177300BE38AE /* rijndael.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = rijndael.cpp; path = libunrar/rijndael.cpp; sourceTree = "<group>"; };
D4A495C21054177300BE38AE /* rijndael.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = rijndael.hpp; path = libunrar/rijndael.hpp; sourceTree = "<group>"; };
D4A495C31054177300BE38AE /* rs.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = rs.cpp; path = libunrar/rs.cpp; sourceTree = "<group>"; };
D4A495C41054177300BE38AE /* rs.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = rs.hpp; path = libunrar/rs.hpp; sourceTree = "<group>"; };
D4A495C51054177300BE38AE /* savepos.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = savepos.cpp; path = libunrar/savepos.cpp; sourceTree = "<group>"; };
D4A495C61054177300BE38AE /* savepos.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = savepos.hpp; path = libunrar/savepos.hpp; sourceTree = "<group>"; };
D4A495C71054177300BE38AE /* scantree.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = scantree.cpp; path = libunrar/scantree.cpp; sourceTree = "<group>"; };
D4A495C81054177300BE38AE /* scantree.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = scantree.hpp; path = libunrar/scantree.hpp; sourceTree = "<group>"; };
D4A495C91054177300BE38AE /* sha1.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = sha1.cpp; path = libunrar/sha1.cpp; sourceTree = "<group>"; };
D4A495CA1054177300BE38AE /* sha1.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = sha1.hpp; path = libunrar/sha1.hpp; sourceTree = "<group>"; };
D4A495CB1054177300BE38AE /* smallfn.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = smallfn.cpp; path = libunrar/smallfn.cpp; sourceTree = "<group>"; };
D4A495CC1054177300BE38AE /* smallfn.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = smallfn.hpp; path = libunrar/smallfn.hpp; sourceTree = "<group>"; };
D4A495CD1054177300BE38AE /* strfn.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = strfn.cpp; path = libunrar/strfn.cpp; sourceTree = "<group>"; };
D4A495CE1054177300BE38AE /* strfn.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = strfn.hpp; path = libunrar/strfn.hpp; sourceTree = "<group>"; };
D4A495CF1054177300BE38AE /* strlist.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = strlist.cpp; path = libunrar/strlist.cpp; sourceTree = "<group>"; };
D4A495D01054177300BE38AE /* strlist.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = strlist.hpp; path = libunrar/strlist.hpp; sourceTree = "<group>"; };
D4A495D11054177300BE38AE /* suballoc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = suballoc.cpp; path = libunrar/suballoc.cpp; sourceTree = "<group>"; };
D4A495D21054177300BE38AE /* suballoc.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = suballoc.hpp; path = libunrar/suballoc.hpp; sourceTree = "<group>"; };
D4A495D31054177300BE38AE /* system.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = system.cpp; path = libunrar/system.cpp; sourceTree = "<group>"; };
D4A495D41054177300BE38AE /* system.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = system.hpp; path = libunrar/system.hpp; sourceTree = "<group>"; };
D4A495D51054177300BE38AE /* timefn.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = timefn.cpp; path = libunrar/timefn.cpp; sourceTree = "<group>"; };
D4A495D61054177300BE38AE /* timefn.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = timefn.hpp; path = libunrar/timefn.hpp; sourceTree = "<group>"; };
D4A495D71054177300BE38AE /* ulinks.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ulinks.cpp; path = libunrar/ulinks.cpp; sourceTree = "<group>"; };
D4A495D81054177300BE38AE /* ulinks.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = ulinks.hpp; path = libunrar/ulinks.hpp; sourceTree = "<group>"; };
D4A495D91054177300BE38AE /* unicode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = unicode.cpp; path = libunrar/unicode.cpp; sourceTree = "<group>"; };
D4A495DA1054177300BE38AE /* unicode.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = unicode.hpp; path = libunrar/unicode.hpp; sourceTree = "<group>"; };
D4A495DB1054177300BE38AE /* unios2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = unios2.cpp; path = libunrar/unios2.cpp; sourceTree = "<group>"; };
D4A495DC1054177300BE38AE /* unpack.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = unpack.cpp; path = libunrar/unpack.cpp; sourceTree = "<group>"; };
D4A495DD1054177300BE38AE /* unpack.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = unpack.hpp; path = libunrar/unpack.hpp; sourceTree = "<group>"; };
D4A495DE1054177300BE38AE /* unpack15.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = unpack15.cpp; path = libunrar/unpack15.cpp; sourceTree = "<group>"; };
D4A495DF1054177300BE38AE /* unpack20.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = unpack20.cpp; path = libunrar/unpack20.cpp; sourceTree = "<group>"; };
D4A495E01054177300BE38AE /* uowners.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = uowners.cpp; path = libunrar/uowners.cpp; sourceTree = "<group>"; };
D4A495E11054177300BE38AE /* version.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = version.hpp; path = libunrar/version.hpp; sourceTree = "<group>"; };
D4A495E21054177300BE38AE /* volume.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = volume.cpp; path = libunrar/volume.cpp; sourceTree = "<group>"; };
D4A495E31054177300BE38AE /* volume.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = volume.hpp; path = libunrar/volume.hpp; sourceTree = "<group>"; };
D4A495E41054177300BE38AE /* win32acl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = win32acl.cpp; path = libunrar/win32acl.cpp; sourceTree = "<group>"; };
D4A495E51054177300BE38AE /* win32stm.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = win32stm.cpp; path = libunrar/win32stm.cpp; sourceTree = "<group>"; };
D4A96E2010545E9A0091ECB4 /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = System/Library/Frameworks/Carbon.framework; sourceTree = SDKROOT; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
8D11072E0486CEB800E47090 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */,
D4A96E2110545E9A0091ECB4 /* Carbon.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
080E96DDFE201D6D7F000001 /* Classes */ = {
isa = PBXGroup;
children = (
256AC3D80F4B6AC300CF3369 /* QuietUnrarAppDelegate.h */,
256AC3D90F4B6AC300CF3369 /* QuietUnrarAppDelegate.m */,
);
name = Classes;
sourceTree = "<group>";
};
1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */ = {
isa = PBXGroup;
children = (
1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */,
);
name = "Linked Frameworks";
sourceTree = "<group>";
};
1058C7A2FEA54F0111CA2CBB /* Other Frameworks */ = {
isa = PBXGroup;
children = (
29B97324FDCFA39411CA2CEA /* AppKit.framework */,
13E42FB307B3F0F600E4EEF1 /* CoreData.framework */,
29B97325FDCFA39411CA2CEA /* Foundation.framework */,
);
name = "Other Frameworks";
sourceTree = "<group>";
};
19C28FACFE9D520D11CA2CBB /* Products */ = {
isa = PBXGroup;
children = (
8D1107320486CEB800E47090 /* QuietUnrar.app */,
);
name = Products;
sourceTree = "<group>";
};
29B97314FDCFA39411CA2CEA /* QuietUnrar */ = {
isa = PBXGroup;
children = (
080E96DDFE201D6D7F000001 /* Classes */,
29B97315FDCFA39411CA2CEA /* Other Sources */,
29B97317FDCFA39411CA2CEA /* Resources */,
29B97323FDCFA39411CA2CEA /* Frameworks */,
19C28FACFE9D520D11CA2CBB /* Products */,
D4A96E2010545E9A0091ECB4 /* Carbon.framework */,
);
name = QuietUnrar;
sourceTree = "<group>";
};
29B97315FDCFA39411CA2CEA /* Other Sources */ = {
isa = PBXGroup;
children = (
D4A494191054167B00BE38AE /* libunrar */,
256AC3F00F4B6AF500CF3369 /* QuietUnrar_Prefix.pch */,
29B97316FDCFA39411CA2CEA /* main.m */,
);
name = "Other Sources";
sourceTree = "<group>";
};
29B97317FDCFA39411CA2CEA /* Resources */ = {
isa = PBXGroup;
children = (
8D1107310486CEB800E47090 /* QuietUnrar-Info.plist */,
089C165CFE840E0CC02AAC07 /* InfoPlist.strings */,
1DDD58140DA1D0A300B32029 /* MainMenu.xib */,
);
name = Resources;
sourceTree = "<group>";
};
29B97323FDCFA39411CA2CEA /* Frameworks */ = {
isa = PBXGroup;
children = (
1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */,
1058C7A2FEA54F0111CA2CBB /* Other Frameworks */,
);
name = Frameworks;
sourceTree = "<group>";
};
D4A494191054167B00BE38AE /* libunrar */ = {
isa = PBXGroup;
children = (
D4A495741054177300BE38AE /* arccmt.cpp */,
D4A495751054177300BE38AE /* archive.cpp */,
D4A495761054177300BE38AE /* archive.hpp */,
D4A495771054177300BE38AE /* arcread.cpp */,
D4A495781054177300BE38AE /* array.hpp */,
D4A495791054177300BE38AE /* beosea.cpp */,
D4A4957A1054177300BE38AE /* cmddata.cpp */,
D4A4957B1054177300BE38AE /* cmddata.hpp */,
D4A4957C1054177300BE38AE /* coder.cpp */,
D4A4957D1054177300BE38AE /* coder.hpp */,
D4A4957E1054177300BE38AE /* compress.hpp */,
D4A4957F1054177300BE38AE /* consio.cpp */,
D4A495801054177300BE38AE /* consio.hpp */,
D4A495811054177300BE38AE /* crc.cpp */,
D4A495821054177300BE38AE /* crc.hpp */,
D4A495831054177300BE38AE /* crypt.cpp */,
D4A495841054177300BE38AE /* crypt.hpp */,
D4A495851054177300BE38AE /* dll.cpp */,
D4A495861054177300BE38AE /* dll.hpp */,
D4A495871054177300BE38AE /* encname.cpp */,
D4A495881054177300BE38AE /* encname.hpp */,
D4A495891054177300BE38AE /* errhnd.cpp */,
D4A4958A1054177300BE38AE /* errhnd.hpp */,
D4A4958B1054177300BE38AE /* extinfo.cpp */,
D4A4958C1054177300BE38AE /* extinfo.hpp */,
D4A4958D1054177300BE38AE /* extract.cpp */,
D4A4958E1054177300BE38AE /* extract.hpp */,
D4A4958F1054177300BE38AE /* filcreat.cpp */,
D4A495901054177300BE38AE /* filcreat.hpp */,
D4A495911054177300BE38AE /* file.cpp */,
D4A495921054177300BE38AE /* file.hpp */,
D4A495931054177300BE38AE /* filefn.cpp */,
D4A495941054177300BE38AE /* filefn.hpp */,
D4A495951054177300BE38AE /* filestr.cpp */,
D4A495961054177300BE38AE /* filestr.hpp */,
D4A495971054177300BE38AE /* find.cpp */,
D4A495981054177300BE38AE /* find.hpp */,
D4A495991054177300BE38AE /* getbits.cpp */,
D4A4959A1054177300BE38AE /* getbits.hpp */,
D4A4959B1054177300BE38AE /* global.cpp */,
D4A4959C1054177300BE38AE /* global.hpp */,
D4A4959D1054177300BE38AE /* headers.hpp */,
D4A4959E1054177300BE38AE /* isnt.cpp */,
D4A4959F1054177300BE38AE /* isnt.hpp */,
D4A495A01054177300BE38AE /* list.cpp */,
D4A495A11054177300BE38AE /* list.hpp */,
D4A495A21054177300BE38AE /* loclang.hpp */,
D4A495A31054177300BE38AE /* log.cpp */,
D4A495A41054177300BE38AE /* log.hpp */,
D4A495A51054177300BE38AE /* makefile.unix */,
D4A495A61054177300BE38AE /* match.cpp */,
D4A495A71054177300BE38AE /* match.hpp */,
D4A495A81054177300BE38AE /* model.cpp */,
D4A495A91054177300BE38AE /* model.hpp */,
D4A495AA1054177300BE38AE /* options.cpp */,
D4A495AB1054177300BE38AE /* options.hpp */,
D4A495AC1054177300BE38AE /* os.hpp */,
D4A495AD1054177300BE38AE /* os2ea.cpp */,
D4A495AE1054177300BE38AE /* pathfn.cpp */,
D4A495AF1054177300BE38AE /* pathfn.hpp */,
D4A495B01054177300BE38AE /* rar.cpp */,
D4A495B11054177300BE38AE /* rar.hpp */,
D4A495B21054177300BE38AE /* rardefs.hpp */,
D4A495B31054177300BE38AE /* rarlang.hpp */,
D4A495B41054177300BE38AE /* raros.hpp */,
D4A495B51054177300BE38AE /* rartypes.hpp */,
D4A495B61054177300BE38AE /* rarvm.cpp */,
D4A495B71054177300BE38AE /* rarvm.hpp */,
D4A495B81054177300BE38AE /* rarvmtbl.cpp */,
D4A495B91054177300BE38AE /* rawread.cpp */,
D4A495BA1054177300BE38AE /* rawread.hpp */,
D4A495BB1054177300BE38AE /* rdwrfn.cpp */,
D4A495BC1054177300BE38AE /* rdwrfn.hpp */,
D4A495BD1054177300BE38AE /* recvol.cpp */,
D4A495BE1054177300BE38AE /* recvol.hpp */,
D4A495BF1054177300BE38AE /* resource.cpp */,
D4A495C01054177300BE38AE /* resource.hpp */,
D4A495C11054177300BE38AE /* rijndael.cpp */,
D4A495C21054177300BE38AE /* rijndael.hpp */,
D4A495C31054177300BE38AE /* rs.cpp */,
D4A495C41054177300BE38AE /* rs.hpp */,
D4A495C51054177300BE38AE /* savepos.cpp */,
D4A495C61054177300BE38AE /* savepos.hpp */,
D4A495C71054177300BE38AE /* scantree.cpp */,
D4A495C81054177300BE38AE /* scantree.hpp */,
D4A495C91054177300BE38AE /* sha1.cpp */,
D4A495CA1054177300BE38AE /* sha1.hpp */,
D4A495CB1054177300BE38AE /* smallfn.cpp */,
D4A495CC1054177300BE38AE /* smallfn.hpp */,
D4A495CD1054177300BE38AE /* strfn.cpp */,
D4A495CE1054177300BE38AE /* strfn.hpp */,
D4A495CF1054177300BE38AE /* strlist.cpp */,
D4A495D01054177300BE38AE /* strlist.hpp */,
D4A495D11054177300BE38AE /* suballoc.cpp */,
D4A495D21054177300BE38AE /* suballoc.hpp */,
D4A495D31054177300BE38AE /* system.cpp */,
D4A495D41054177300BE38AE /* system.hpp */,
D4A495D51054177300BE38AE /* timefn.cpp */,
D4A495D61054177300BE38AE /* timefn.hpp */,
D4A495D71054177300BE38AE /* ulinks.cpp */,
D4A495D81054177300BE38AE /* ulinks.hpp */,
D4A495D91054177300BE38AE /* unicode.cpp */,
D4A495DA1054177300BE38AE /* unicode.hpp */,
D4A495DB1054177300BE38AE /* unios2.cpp */,
D4A495DC1054177300BE38AE /* unpack.cpp */,
D4A495DD1054177300BE38AE /* unpack.hpp */,
D4A495DE1054177300BE38AE /* unpack15.cpp */,
D4A495DF1054177300BE38AE /* unpack20.cpp */,
D4A495E01054177300BE38AE /* uowners.cpp */,
D4A495E11054177300BE38AE /* version.hpp */,
D4A495E21054177300BE38AE /* volume.cpp */,
D4A495E31054177300BE38AE /* volume.hpp */,
D4A495E41054177300BE38AE /* win32acl.cpp */,
D4A495E51054177300BE38AE /* win32stm.cpp */,
);
name = libunrar;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXLegacyTarget section */
D4A4962A105419AA00BE38AE /* libunrar */ = {
isa = PBXLegacyTarget;
buildArgumentsString = "-f makefile.unix lib $(ACTION)";
buildConfigurationList = D4A4962D105419C800BE38AE /* Build configuration list for PBXLegacyTarget "libunrar" */;
buildPhases = (
);
buildToolPath = /usr/bin/make;
buildWorkingDirectory = ./libunrar/;
dependencies = (
);
name = libunrar;
passBuildSettingsInEnvironment = 1;
productName = libunrar;
};
/* End PBXLegacyTarget section */
/* Begin PBXNativeTarget section */
8D1107260486CEB800E47090 /* QuietUnrar */ = {
isa = PBXNativeTarget;
buildConfigurationList = C01FCF4A08A954540054247B /* Build configuration list for PBXNativeTarget "QuietUnrar" */;
buildPhases = (
8D11072C0486CEB800E47090 /* Sources */,
8D11072E0486CEB800E47090 /* Frameworks */,
D4A4965210541D2600BE38AE /* CopyFiles */,
D4A49697105435C700BE38AE /* Resources */,
);
buildRules = (
);
dependencies = (
D4A4964D10541CFF00BE38AE /* PBXTargetDependency */,
);
name = QuietUnrar;
productInstallPath = "$(HOME)/Applications";
productName = QuietUnrar;
productReference = 8D1107320486CEB800E47090 /* QuietUnrar.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
29B97313FDCFA39411CA2CEA /* Project object */ = {
isa = PBXProject;
buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "QuietUnrar" */;
compatibilityVersion = "Xcode 3.2";
hasScannedForEncodings = 1;
mainGroup = 29B97314FDCFA39411CA2CEA /* QuietUnrar */;
projectDirPath = "";
projectRoot = "";
targets = (
8D1107260486CEB800E47090 /* QuietUnrar */,
D4A4962A105419AA00BE38AE /* libunrar */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
D4A49697105435C700BE38AE /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
D4A49692105435C100BE38AE /* MainMenu.xib in Resources */,
D4A49691105435BE00BE38AE /* InfoPlist.strings in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
8D11072C0486CEB800E47090 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
8D11072D0486CEB800E47090 /* main.m in Sources */,
256AC3DA0F4B6AC300CF3369 /* QuietUnrarAppDelegate.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
D4A4964D10541CFF00BE38AE /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = D4A4962A105419AA00BE38AE /* libunrar */;
targetProxy = D4A4964C10541CFF00BE38AE /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */
089C165CFE840E0CC02AAC07 /* InfoPlist.strings */ = {
isa = PBXVariantGroup;
children = (
089C165DFE840E0CC02AAC07 /* English */,
);
name = InfoPlist.strings;
sourceTree = "<group>";
};
1DDD58140DA1D0A300B32029 /* MainMenu.xib */ = {
isa = PBXVariantGroup;
children = (
1DDD58150DA1D0A300B32029 /* English */,
);
name = MainMenu.xib;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
C01FCF4B08A954540054247B /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
COPY_PHASE_STRIP = NO;
GCC_DYNAMIC_NO_PIC = NO;
GCC_ENABLE_FIX_AND_CONTINUE = YES;
GCC_MODEL_TUNING = G5;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = QuietUnrar_Prefix.pch;
GCC_PREPROCESSOR_DEFINITIONS = _UNIX;
INFOPLIST_FILE = "QuietUnrar-Info.plist";
INSTALL_PATH = "$(HOME)/Applications";
PRODUCT_NAME = QuietUnrar;
};
name = Debug;
};
C01FCF4C08A954540054247B /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
GCC_MODEL_TUNING = G5;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = QuietUnrar_Prefix.pch;
GCC_PREPROCESSOR_DEFINITIONS = _UNIX;
INFOPLIST_FILE = "QuietUnrar-Info.plist";
INSTALL_PATH = "$(HOME)/Applications";
PRODUCT_NAME = QuietUnrar;
};
name = Release;
};
C01FCF4F08A954540054247B /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_ENABLE_OBJC_GC = required;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
ONLY_ACTIVE_ARCH = YES;
PREBINDING = NO;
SDKROOT = macosx10.6;
VALID_ARCHS = "i386 x86_64";
};
name = Debug;
};
C01FCF5008A954540054247B /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_ENABLE_OBJC_GC = required;
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
PREBINDING = NO;
SDKROOT = macosx10.6;
VALID_ARCHS = "i386 x86_64";
};
name = Release;
};
D4A4962B105419AA00BE38AE /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
COPY_PHASE_STRIP = NO;
GCC_DYNAMIC_NO_PIC = NO;
GCC_OPTIMIZATION_LEVEL = 0;
PRODUCT_NAME = libunrar;
};
name = Debug;
};
D4A4962C105419AA00BE38AE /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
COPY_PHASE_STRIP = YES;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
GCC_ENABLE_FIX_AND_CONTINUE = NO;
PRODUCT_NAME = libunrar;
ZERO_LINK = NO;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
C01FCF4A08A954540054247B /* Build configuration list for PBXNativeTarget "QuietUnrar" */ = {
isa = XCConfigurationList;
buildConfigurations = (
C01FCF4B08A954540054247B /* Debug */,
C01FCF4C08A954540054247B /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
C01FCF4E08A954540054247B /* Build configuration list for PBXProject "QuietUnrar" */ = {
isa = XCConfigurationList;
buildConfigurations = (
C01FCF4F08A954540054247B /* Debug */,
C01FCF5008A954540054247B /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
D4A4962D105419C800BE38AE /* Build configuration list for PBXLegacyTarget "libunrar" */ = {
isa = XCConfigurationList;
buildConfigurations = (
D4A4962B105419AA00BE38AE /* Debug */,
D4A4962C105419AA00BE38AE /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 29B97313FDCFA39411CA2CEA /* Project object */;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,346 @@
// !$*UTF8*$!
{
089C165DFE840E0CC02AAC07 /* English */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {703, 404}}";
sepNavSelRange = "{0, 0}";
sepNavVisRange = "{0, 45}";
};
};
256AC3D80F4B6AC300CF3369 /* QuietUnrarAppDelegate.h */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {670, 403}}";
sepNavSelRange = "{469, 0}";
sepNavVisRange = "{180, 436}";
};
};
256AC3D90F4B6AC300CF3369 /* QuietUnrarAppDelegate.m */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {740, 572}}";
sepNavSelRange = "{720, 0}";
sepNavVisRange = "{295, 827}";
sepNavWindowFrame = "{{85, 21}, {877, 731}}";
};
};
29B97313FDCFA39411CA2CEA /* Project object */ = {
activeBuildConfigurationName = Debug;
activeExecutable = D4A4940C1054167200BE38AE /* QuietUnrar */;
activeTarget = 8D1107260486CEB800E47090 /* QuietUnrar */;
addToTargets = (
8D1107260486CEB800E47090 /* QuietUnrar */,
);
codeSenseManager = D4A4941B1054167B00BE38AE /* Code sense */;
executables = (
D4A4940C1054167200BE38AE /* QuietUnrar */,
);
perUserDictionary = {
PBXConfiguration.PBXFileTableDataSource3.PBXExecutablesDataSource = {
PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
PBXFileTableDataSourceColumnSortingKey = PBXExecutablesDataSource_NameID;
PBXFileTableDataSourceColumnWidthsKey = (
22,
300,
413,
);
PBXFileTableDataSourceColumnsKey = (
PBXExecutablesDataSource_ActiveFlagID,
PBXExecutablesDataSource_NameID,
PBXExecutablesDataSource_CommentsID,
);
};
PBXConfiguration.PBXFileTableDataSource3.PBXFileTableDataSource = {
PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID;
PBXFileTableDataSourceColumnWidthsKey = (
20,
525,
20,
48,
43,
43,
20,
);
PBXFileTableDataSourceColumnsKey = (
PBXFileDataSource_FiletypeID,
PBXFileDataSource_Filename_ColumnID,
PBXFileDataSource_Built_ColumnID,
PBXFileDataSource_ObjectSize_ColumnID,
PBXFileDataSource_Errors_ColumnID,
PBXFileDataSource_Warnings_ColumnID,
PBXFileDataSource_Target_ColumnID,
);
};
PBXConfiguration.PBXTargetDataSource.PBXTargetDataSource = {
PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID;
PBXFileTableDataSourceColumnWidthsKey = (
20,
485,
60,
20,
48,
43,
43,
);
PBXFileTableDataSourceColumnsKey = (
PBXFileDataSource_FiletypeID,
PBXFileDataSource_Filename_ColumnID,
PBXTargetDataSource_PrimaryAttribute,
PBXFileDataSource_Built_ColumnID,
PBXFileDataSource_ObjectSize_ColumnID,
PBXFileDataSource_Errors_ColumnID,
PBXFileDataSource_Warnings_ColumnID,
);
};
PBXPerProjectTemplateStateSaveDate = 279557910;
PBXWorkspaceStateSaveDate = 279557910;
};
perUserProjectItems = {
D40FFE1C105828A50070BCAF = D40FFE1C105828A50070BCAF /* PBXTextBookmark */;
D40FFE1F105828A50070BCAF = D40FFE1F105828A50070BCAF /* PBXTextBookmark */;
D40FFE21105828A50070BCAF = D40FFE21105828A50070BCAF /* PBXTextBookmark */;
D4A4963610541A1C00BE38AE = D4A4963610541A1C00BE38AE /* PBXTextBookmark */;
D4A4965D105433E000BE38AE = D4A4965D105433E000BE38AE /* PBXTargetBookmark */;
D4A496731054350F00BE38AE = D4A496731054350F00BE38AE /* PBXTextBookmark */;
D4A96E4C1054628D0091ECB4 = D4A96E4C1054628D0091ECB4 /* PBXTextBookmark */;
D4A96E4D1054628D0091ECB4 = D4A96E4D1054628D0091ECB4 /* PBXTextBookmark */;
D4A96E4E1054628D0091ECB4 = D4A96E4E1054628D0091ECB4 /* PBXTextBookmark */;
D4A96E4F1054628D0091ECB4 = D4A96E4F1054628D0091ECB4 /* PBXTextBookmark */;
D4A96E511054628D0091ECB4 = D4A96E511054628D0091ECB4 /* PBXTextBookmark */;
D4C9D7E810A9B7A20005973D /* PBXTextBookmark */ = D4C9D7E810A9B7A20005973D /* PBXTextBookmark */;
D4C9D7EB10A9B7A20005973D /* PBXTextBookmark */ = D4C9D7EB10A9B7A20005973D /* PBXTextBookmark */;
};
sourceControlManager = D4A4941A1054167B00BE38AE /* Source Control */;
userBuildSettings = {
};
};
29B97316FDCFA39411CA2CEA /* main.m */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {633, 195}}";
sepNavSelRange = "{191, 0}";
sepNavVisRange = "{29, 213}";
};
};
8D1107260486CEB800E47090 /* QuietUnrar */ = {
activeExec = 0;
executables = (
D4A4940C1054167200BE38AE /* QuietUnrar */,
);
};
8D1107310486CEB800E47090 /* QuietUnrar-Info.plist */ = {
uiCtxt = {
sepNavWindowFrame = "{{53, 47}, {877, 731}}";
};
};
D40FFE1C105828A50070BCAF /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = 256AC3D90F4B6AC300CF3369 /* QuietUnrarAppDelegate.m */;
name = "QuietUnrarAppDelegate.m: 29";
rLen = 0;
rLoc = 720;
rType = 0;
vrLen = 882;
vrLoc = 235;
};
D40FFE1F105828A50070BCAF /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = D40FFE20105828A50070BCAF /* NSApplication.h */;
rLen = 1;
rLoc = 85;
rType = 1;
};
D40FFE20105828A50070BCAF /* NSApplication.h */ = {
isa = PBXFileReference;
lastKnownFileType = sourcecode.c.h;
name = NSApplication.h;
path = /Developer/SDKs/MacOSX10.6.sdk/System/Library/Frameworks/AppKit.framework/Versions/C/Headers/NSApplication.h;
sourceTree = "<absolute>";
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {3652, 5811}}";
sepNavSelRange = "{3400, 68}";
sepNavVisRange = "{13091, 2293}";
};
};
D40FFE21105828A50070BCAF /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = D40FFE22105828A50070BCAF /* NSApplication.h */;
name = "NSApplication.h: 86";
rLen = 68;
rLoc = 3400;
rType = 0;
vrLen = 2333;
vrLoc = 13122;
};
D40FFE22105828A50070BCAF /* NSApplication.h */ = {
isa = PBXFileReference;
lastKnownFileType = sourcecode.c.h;
name = NSApplication.h;
path = /Developer/SDKs/MacOSX10.6.sdk/System/Library/Frameworks/AppKit.framework/Versions/C/Headers/NSApplication.h;
sourceTree = "<absolute>";
};
D4A4940C1054167200BE38AE /* QuietUnrar */ = {
isa = PBXExecutable;
activeArgIndices = (
);
argumentStrings = (
);
autoAttachOnCrash = 1;
breakpointsEnabled = 0;
configStateDict = {
};
customDataFormattersEnabled = 1;
dataTipCustomDataFormattersEnabled = 1;
dataTipShowTypeColumn = 1;
dataTipSortType = 0;
debuggerPlugin = GDBDebugging;
disassemblyDisplayState = 0;
dylibVariantSuffix = "";
enableDebugStr = 1;
environmentEntries = (
);
executableSystemSymbolLevel = 0;
executableUserSymbolLevel = 0;
libgmallocEnabled = 0;
name = QuietUnrar;
savedGlobals = {
};
showTypeColumn = 0;
sourceDirectories = (
);
startupPath = "<<ProjectDirectory>>";
variableFormatDictionary = {
};
};
D4A4941A1054167B00BE38AE /* Source Control */ = {
isa = PBXSourceControlManager;
fallbackIsa = XCSourceControlManager;
isSCMEnabled = 0;
scmConfiguration = {
repositoryNamesForRoots = {
"" = "";
};
};
};
D4A4941B1054167B00BE38AE /* Code sense */ = {
isa = PBXCodeSenseManager;
indexTemplatePath = "";
};
D4A495741054177300BE38AE /* arccmt.cpp */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {703, 2847}}";
sepNavSelRange = "{386, 0}";
sepNavVisRange = "{70, 690}";
};
};
D4A4957F1054177300BE38AE /* consio.cpp */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {703, 3718}}";
sepNavSelRange = "{3913, 14}";
sepNavVisRange = "{3683, 678}";
};
};
D4A495861054177300BE38AE /* dll.hpp */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {616, 1950}}";
sepNavSelRange = "{2499, 0}";
sepNavVisRange = "{2236, 490}";
};
};
D4A4962A105419AA00BE38AE /* libunrar */ = {
activeExec = 0;
};
D4A4963610541A1C00BE38AE /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = D4A495741054177300BE38AE /* arccmt.cpp */;
name = "arccmt.cpp: 20";
rLen = 0;
rLoc = 386;
rType = 0;
vrLen = 690;
vrLoc = 70;
};
D4A4965D105433E000BE38AE /* PBXTargetBookmark */ = {
isa = PBXTargetBookmark;
trg = D4A4962A105419AA00BE38AE /* libunrar */;
};
D4A496731054350F00BE38AE /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = D4A495861054177300BE38AE /* dll.hpp */;
name = "dll.hpp: 12";
rLen = 0;
rLoc = 337;
rType = 0;
vrLen = 828;
vrLoc = 0;
};
D4A96E4C1054628D0091ECB4 /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = 089C165DFE840E0CC02AAC07 /* English */;
name = "InfoPlist.strings: 1";
rLen = 0;
rLoc = 0;
rType = 0;
vrLen = 45;
vrLoc = 0;
};
D4A96E4D1054628D0091ECB4 /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = 29B97316FDCFA39411CA2CEA /* main.m */;
name = "main.m: 1";
rLen = 0;
rLoc = 0;
rType = 0;
vrLen = 252;
vrLoc = 0;
};
D4A96E4E1054628D0091ECB4 /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = D4A4957F1054177300BE38AE /* consio.cpp */;
name = "consio.cpp: 184";
rLen = 14;
rLoc = 3913;
rType = 0;
vrLen = 678;
vrLoc = 3683;
};
D4A96E4F1054628D0091ECB4 /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = 256AC3D80F4B6AC300CF3369 /* QuietUnrarAppDelegate.h */;
name = "QuietUnrarAppDelegate.h: 20";
rLen = 0;
rLoc = 371;
rType = 0;
vrLen = 616;
vrLoc = 0;
};
D4A96E511054628D0091ECB4 /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = 256AC3D90F4B6AC300CF3369 /* QuietUnrarAppDelegate.m */;
name = "QuietUnrarAppDelegate.m: 11";
rLen = 0;
rLoc = 230;
rType = 0;
vrLen = 863;
vrLoc = 0;
};
D4C9D7E810A9B7A20005973D /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = 256AC3D90F4B6AC300CF3369 /* QuietUnrarAppDelegate.m */;
name = "QuietUnrarAppDelegate.m: 29";
rLen = 0;
rLoc = 720;
rType = 0;
vrLen = 827;
vrLoc = 295;
};
D4C9D7EB10A9B7A20005973D /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = D40FFE20105828A50070BCAF /* NSApplication.h */;
name = "NSApplication.h: 86";
rLen = 68;
rLoc = 3400;
rType = 0;
vrLen = 2293;
vrLoc = 13091;
};
}

30
QuietUnrarAppDelegate.h Normal file
View File

@ -0,0 +1,30 @@
//
// QuietUnrarAppDelegate.h
// QuietUnrar
//
// Created by Robert McGovern on 2009/09/06.
// Copyright 2009 Tarasis. All rights reserved.
//
#import <Cocoa/Cocoa.h>
enum
{
kVKC_Shift = 56,
kVKC_Option = 58,
kVKC_Control = 59,
kVKC_rShift = 60, /* Right-hand modifiers; not implemented */
kVKC_rOption = 61,
kVKC_rControl = 62,
kVKC_Command = 55,
};
#define KEYMAP_GET(m, index) ((((uint8_t*)(m))[(index) >> 3] & (1L << ((index) & 7))) ? 1 : 0)
@interface QuietUnrarAppDelegate : NSObject <NSApplicationDelegate> {
NSWindow *window;
}
@property (assign) IBOutlet NSWindow *window;
@end

43
QuietUnrarAppDelegate.m Normal file
View File

@ -0,0 +1,43 @@
//
// QuietUnrarAppDelegate.m
// QuietUnrar
//
// Created by Robert McGovern on 2009/09/06.
// Copyright 2009 Tarasis. All rights reserved.
//
#import <Carbon/Carbon.h>
#import "QuietUnrarAppDelegate.h"
#import "libunrar/dll.hpp"
@implementation QuietUnrarAppDelegate
@synthesize window;
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
// Insert code here to initialize your application
KeyMap map;
GetKeys(map);
NSLog(@"Shift or Right Shift: %d", KEYMAP_GET(map, kVKC_Shift) || KEYMAP_GET(map, kVKC_rShift));
}
- (BOOL)application:(id)sender openFileWithoutUI:(NSString *)filename {
NSLog(@"openFileWithoutUI with file: %@", filename);
return YES;
}
- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename {
NSLog(@"openFile: %@", filename);
return YES;
}
//- (void)application:(NSApplication *)sender openFiles:(NSArray *)filenames {
// for (NSString * filename in filenames) {
// NSLog(@"openFiles: %@", filename);
// }
//
// // If we get passed files don't open the UI
// [sender replyToOpenOrPrint:NSApplicationDelegateReplySuccess];
//}
@end

7
QuietUnrar_Prefix.pch Normal file
View File

@ -0,0 +1,7 @@
//
// Prefix header for all source files of the 'QuietUnrar' target in the 'QuietUnrar' project
//
#ifdef __OBJC__
#import <Cocoa/Cocoa.h>
#endif

BIN
docs/unrardll.webarchive Normal file

Binary file not shown.

217
libunrar/arccmt.cpp Normal file
View File

@ -0,0 +1,217 @@
bool Archive::GetComment(Array<byte> *CmtData,Array<wchar> *CmtDataW)
{
if (!MainComment)
return(false);
SaveFilePos SavePos(*this);
#ifndef SFX_MODULE
ushort CmtLength;
if (OldFormat)
{
Seek(SFXSize+SIZEOF_OLDMHD,SEEK_SET);
CmtLength=GetByte();
CmtLength+=(GetByte()<<8);
}
else
#endif
{
if (NewMhd.Flags & MHD_COMMENT)
{
Seek(SFXSize+SIZEOF_MARKHEAD+SIZEOF_NEWMHD,SEEK_SET);
ReadHeader();
}
else
{
Seek(SFXSize+SIZEOF_MARKHEAD+NewMhd.HeadSize,SEEK_SET);
return(SearchSubBlock(SUBHEAD_TYPE_CMT)!=0 && ReadCommentData(CmtData,CmtDataW)!=0);
}
#ifndef SFX_MODULE
if (CommHead.HeadCRC!=HeaderCRC)
{
Log(FileName,St(MLogCommHead));
Alarm();
return(false);
}
CmtLength=CommHead.HeadSize-SIZEOF_COMMHEAD;
#endif
}
#ifndef SFX_MODULE
if (OldFormat && (OldMhd.Flags & MHD_PACK_COMMENT) || !OldFormat && CommHead.Method!=0x30)
{
if (!OldFormat && (CommHead.UnpVer < 15 || CommHead.UnpVer > UNP_VER || CommHead.Method > 0x35))
return(false);
ComprDataIO DataIO;
Unpack Unpack(&DataIO);
Unpack.Init();
DataIO.SetTestMode(true);
uint UnpCmtLength;
if (OldFormat)
{
#ifdef NOCRYPT
return(false);
#else
UnpCmtLength=GetByte();
UnpCmtLength+=(GetByte()<<8);
CmtLength-=2;
DataIO.SetCmt13Encryption();
#endif
}
else
UnpCmtLength=CommHead.UnpSize;
DataIO.SetFiles(this,NULL);
DataIO.EnableShowProgress(false);
DataIO.SetPackedSizeToRead(CmtLength);
Unpack.SetDestSize(UnpCmtLength);
Unpack.DoUnpack(CommHead.UnpVer,false);
if (!OldFormat && ((~DataIO.UnpFileCRC)&0xffff)!=CommHead.CommCRC)
{
Log(FileName,St(MLogCommBrk));
Alarm();
return(false);
}
else
{
byte *UnpData;
size_t UnpDataSize;
DataIO.GetUnpackedData(&UnpData,&UnpDataSize);
CmtData->Alloc(UnpDataSize);
memcpy(&((*CmtData)[0]),UnpData,UnpDataSize);
}
}
else
{
CmtData->Alloc(CmtLength);
Read(&((*CmtData)[0]),CmtLength);
if (!OldFormat && CommHead.CommCRC!=(~CRC(0xffffffff,&((*CmtData)[0]),CmtLength)&0xffff))
{
Log(FileName,St(MLogCommBrk));
Alarm();
CmtData->Reset();
return(false);
}
}
#endif
#if defined(_WIN_32) && !defined(_WIN_CE)
if (CmtData->Size()>0)
{
size_t CmtSize=CmtData->Size();
OemToCharBuff((char *)CmtData->Addr(),(char *)CmtData->Addr(),(DWORD)CmtSize);
if (CmtDataW!=NULL)
{
CmtDataW->Alloc(CmtSize+1);
CmtData->Push(0);
CharToWide((char *)CmtData->Addr(),CmtDataW->Addr(),CmtSize+1);
CmtData->Alloc(CmtSize);
CmtDataW->Alloc(strlenw(CmtDataW->Addr()));
}
}
#endif
return(CmtData->Size()>0);
}
size_t Archive::ReadCommentData(Array<byte> *CmtData,Array<wchar> *CmtDataW)
{
bool Unicode=SubHead.SubFlags & SUBHEAD_FLAGS_CMT_UNICODE;
if (!ReadSubData(CmtData,NULL))
return(0);
size_t CmtSize=CmtData->Size();
if (Unicode)
{
CmtSize/=2;
Array<wchar> DataW(CmtSize+1);
RawToWide(CmtData->Addr(),DataW.Addr(),CmtSize);
DataW[CmtSize]=0;
size_t DestSize=CmtSize*4;
CmtData->Alloc(DestSize+1);
WideToChar(DataW.Addr(),(char *)CmtData->Addr(),DestSize);
(*CmtData)[DestSize]=0;
CmtSize=strlen((char *)CmtData->Addr());
CmtData->Alloc(CmtSize);
if (CmtDataW!=NULL)
{
*CmtDataW=DataW;
CmtDataW->Alloc(CmtSize);
}
}
else
if (CmtDataW!=NULL)
{
CmtData->Push(0);
CmtDataW->Alloc(CmtSize+1);
CharToWide((char *)CmtData->Addr(),CmtDataW->Addr(),CmtSize+1);
CmtData->Alloc(CmtSize);
CmtDataW->Alloc(strlenw(CmtDataW->Addr()));
}
return(CmtSize);
}
void Archive::ViewComment()
{
#ifndef GUI
if (Cmd->DisableComment)
return;
Array<byte> CmtBuf;
if (GetComment(&CmtBuf,NULL))
{
size_t CmtSize=CmtBuf.Size();
char *ChPtr=(char *)memchr(&CmtBuf[0],0x1A,CmtSize);
if (ChPtr!=NULL)
CmtSize=ChPtr-(char *)&CmtBuf[0];
mprintf("\n");
OutComment((char *)&CmtBuf[0],CmtSize);
}
#endif
}
#ifndef SFX_MODULE
void Archive::ViewFileComment()
{
if (!(NewLhd.Flags & LHD_COMMENT) || Cmd->DisableComment || OldFormat)
return;
#ifndef GUI
mprintf(St(MFileComment));
#endif
const int MaxSize=0x8000;
Array<char> CmtBuf(MaxSize);
SaveFilePos SavePos(*this);
Seek(CurBlockPos+SIZEOF_NEWLHD+NewLhd.NameSize,SEEK_SET);
int64 SaveCurBlockPos=CurBlockPos;
int64 SaveNextBlockPos=NextBlockPos;
size_t Size=ReadHeader();
CurBlockPos=SaveCurBlockPos;
NextBlockPos=SaveNextBlockPos;
if (Size<7 || CommHead.HeadType!=COMM_HEAD)
return;
if (CommHead.HeadCRC!=HeaderCRC)
{
#ifndef GUI
Log(FileName,St(MLogCommHead));
#endif
return;
}
if (CommHead.UnpVer < 15 || CommHead.UnpVer > UNP_VER ||
CommHead.Method > 0x30 || CommHead.UnpSize > MaxSize)
return;
Read(&CmtBuf[0],CommHead.UnpSize);
if (CommHead.CommCRC!=((~CRC(0xffffffff,&CmtBuf[0],CommHead.UnpSize)&0xffff)))
{
Log(FileName,St(MLogBrokFCmt));
}
else
{
OutComment(&CmtBuf[0],CommHead.UnpSize);
#ifndef GUI
mprintf("\n");
#endif
}
}
#endif

267
libunrar/archive.cpp Normal file
View File

@ -0,0 +1,267 @@
#include "rar.hpp"
#ifndef SHELL_EXT
#include "arccmt.cpp"
#endif
Archive::Archive(RAROptions *InitCmd)
{
Cmd=InitCmd==NULL ? &DummyCmd:InitCmd;
OpenShared=Cmd->OpenShared;
OldFormat=false;
Solid=false;
Volume=false;
MainComment=false;
Locked=false;
Signed=false;
NotFirstVolume=false;
SFXSize=0;
LatestTime.Reset();
Protected=false;
Encrypted=false;
BrokenFileHeader=false;
LastReadBlock=0;
CurBlockPos=0;
NextBlockPos=0;
RecoveryPos=SIZEOF_MARKHEAD;
RecoverySectors=-1;
memset(&NewMhd,0,sizeof(NewMhd));
NewMhd.HeadType=MAIN_HEAD;
NewMhd.HeadSize=SIZEOF_NEWMHD;
HeaderCRC=0;
VolWrite=0;
AddingFilesSize=0;
AddingHeadersSize=0;
#if !defined(SHELL_EXT) && !defined(NOCRYPT)
*HeadersSalt=0;
*SubDataSalt=0;
#endif
*FirstVolumeName=0;
*FirstVolumeNameW=0;
Splitting=false;
NewArchive=false;
SilentOpen=false;
}
#ifndef SHELL_EXT
void Archive::CheckArc(bool EnableBroken)
{
if (!IsArchive(EnableBroken))
{
Log(FileName,St(MBadArc),FileName);
ErrHandler.Exit(FATAL_ERROR);
}
}
#endif
#if !defined(SHELL_EXT) && !defined(SFX_MODULE)
void Archive::CheckOpen(char *Name,wchar *NameW)
{
TOpen(Name,NameW);
CheckArc(false);
}
#endif
bool Archive::WCheckOpen(char *Name,wchar *NameW)
{
if (!WOpen(Name,NameW))
return(false);
if (!IsArchive(false))
{
#ifndef SHELL_EXT
Log(FileName,St(MNotRAR),FileName);
#endif
Close();
return(false);
}
return(true);
}
bool Archive::IsSignature(byte *D)
{
bool Valid=false;
if (D[0]==0x52)
#ifndef SFX_MODULE
if (D[1]==0x45 && D[2]==0x7e && D[3]==0x5e)
{
OldFormat=true;
Valid=true;
}
else
#endif
if (D[1]==0x61 && D[2]==0x72 && D[3]==0x21 && D[4]==0x1a && D[5]==0x07 && D[6]==0x00)
{
OldFormat=false;
Valid=true;
}
return(Valid);
}
bool Archive::IsArchive(bool EnableBroken)
{
Encrypted=false;
#ifndef SFX_MODULE
if (IsDevice())
{
#ifndef SHELL_EXT
Log(FileName,St(MInvalidName),FileName);
#endif
return(false);
}
#endif
if (Read(MarkHead.Mark,SIZEOF_MARKHEAD)!=SIZEOF_MARKHEAD)
return(false);
SFXSize=0;
if (IsSignature(MarkHead.Mark))
{
if (OldFormat)
Seek(0,SEEK_SET);
}
else
{
Array<char> Buffer(MAXSFXSIZE);
long CurPos=(long)Tell();
int ReadSize=Read(&Buffer[0],Buffer.Size()-16);
for (int I=0;I<ReadSize;I++)
if (Buffer[I]==0x52 && IsSignature((byte *)&Buffer[I]))
{
if (OldFormat && I>0 && CurPos<28 && ReadSize>31)
{
char *D=&Buffer[28-CurPos];
if (D[0]!=0x52 || D[1]!=0x53 || D[2]!=0x46 || D[3]!=0x58)
continue;
}
SFXSize=CurPos+I;
Seek(SFXSize,SEEK_SET);
if (!OldFormat)
Read(MarkHead.Mark,SIZEOF_MARKHEAD);
break;
}
if (SFXSize==0)
return(false);
}
ReadHeader();
SeekToNext();
#ifndef SFX_MODULE
if (OldFormat)
{
NewMhd.Flags=OldMhd.Flags & 0x3f;
NewMhd.HeadSize=OldMhd.HeadSize;
}
else
#endif
{
if (HeaderCRC!=NewMhd.HeadCRC)
{
#ifndef SHELL_EXT
Log(FileName,St(MLogMainHead));
#endif
Alarm();
if (!EnableBroken)
return(false);
}
}
Volume=(NewMhd.Flags & MHD_VOLUME);
Solid=(NewMhd.Flags & MHD_SOLID)!=0;
MainComment=(NewMhd.Flags & MHD_COMMENT)!=0;
Locked=(NewMhd.Flags & MHD_LOCK)!=0;
Signed=(NewMhd.PosAV!=0);
Protected=(NewMhd.Flags & MHD_PROTECT)!=0;
Encrypted=(NewMhd.Flags & MHD_PASSWORD)!=0;
if (NewMhd.EncryptVer>UNP_VER)
{
#ifdef RARDLL
Cmd->DllError=ERAR_UNKNOWN_FORMAT;
#else
ErrHandler.SetErrorCode(WARNING);
#if !defined(SILENT) && !defined(SFX_MODULE)
Log(FileName,St(MUnknownMeth),FileName);
Log(FileName,St(MVerRequired),NewMhd.EncryptVer/10,NewMhd.EncryptVer%10);
#endif
#endif
return(false);
}
#ifdef RARDLL
SilentOpen=true;
#endif
//if not encrypted, we'll check it below
NotFirstVolume=Encrypted && (NewMhd.Flags & MHD_FIRSTVOLUME)==0;
if (!SilentOpen || !Encrypted)
{
SaveFilePos SavePos(*this);
int64 SaveCurBlockPos=CurBlockPos,SaveNextBlockPos=NextBlockPos;
NotFirstVolume=false;
while (ReadHeader()!=0)
{
int HeaderType=GetHeaderType();
if (HeaderType==NEWSUB_HEAD)
{
if (SubHead.CmpName(SUBHEAD_TYPE_CMT))
MainComment=true;
if ((SubHead.Flags & LHD_SPLIT_BEFORE) ||
Volume && (NewMhd.Flags & MHD_FIRSTVOLUME)==0)
NotFirstVolume=true;
}
else
{
if (HeaderType==FILE_HEAD && ((NewLhd.Flags & LHD_SPLIT_BEFORE)!=0 ||
Volume && NewLhd.UnpVer>=29 && (NewMhd.Flags & MHD_FIRSTVOLUME)==0))
NotFirstVolume=true;
break;
}
SeekToNext();
}
CurBlockPos=SaveCurBlockPos;
NextBlockPos=SaveNextBlockPos;
}
if (!Volume || !NotFirstVolume)
{
strcpy(FirstVolumeName,FileName);
strcpyw(FirstVolumeNameW,FileNameW);
}
return(true);
}
void Archive::SeekToNext()
{
Seek(NextBlockPos,SEEK_SET);
}
#ifndef SFX_MODULE
int Archive::GetRecoverySize(bool Required)
{
if (!Protected)
return(0);
if (RecoverySectors!=-1 || !Required)
return(RecoverySectors);
SaveFilePos SavePos(*this);
Seek(SFXSize,SEEK_SET);
SearchSubBlock(SUBHEAD_TYPE_RR);
return(RecoverySectors);
}
#endif

126
libunrar/archive.hpp Normal file
View File

@ -0,0 +1,126 @@
#ifndef _RAR_ARCHIVE_
#define _RAR_ARCHIVE_
class Pack;
enum {EN_LOCK=1,EN_VOL=2,EN_FIRSTVOL=4};
class Archive:public File
{
private:
bool IsSignature(byte *D);
void UpdateLatestTime(FileHeader *CurBlock);
void ConvertNameCase(char *Name);
void ConvertNameCase(wchar *Name);
void ConvertUnknownHeader();
size_t ReadOldHeader();
void UnexpEndArcMsg();
#if !defined(SHELL_EXT) && !defined(NOCRYPT)
CryptData HeadersCrypt;
byte HeadersSalt[SALT_SIZE];
#endif
#ifndef SHELL_EXT
ComprDataIO SubDataIO;
byte SubDataSalt[SALT_SIZE];
#endif
RAROptions *Cmd,DummyCmd;
MarkHeader MarkHead;
OldMainHeader OldMhd;
int RecoverySectors;
int64 RecoveryPos;
RarTime LatestTime;
int LastReadBlock;
int CurHeaderType;
bool SilentOpen;
public:
Archive(RAROptions *InitCmd=NULL);
bool IsArchive(bool EnableBroken);
size_t SearchBlock(int BlockType);
size_t SearchSubBlock(const char *Type);
int ReadBlock(int BlockType);
void WriteBlock(int BlockType,BaseBlock *wb=NULL);
int PrepareNamesToWrite(char *Name,wchar *NameW,char *DestName,byte *DestNameW);
void SetLhdSize();
size_t ReadHeader();
void CheckArc(bool EnableBroken);
void CheckOpen(char *Name,wchar *NameW=NULL);
bool WCheckOpen(char *Name,wchar *NameW=NULL);
bool TestLock(int Mode);
void MakeTemp();
void CopyMainHeader(Archive &Src,bool CopySFX=true,char *NameToDisplay=NULL);
bool ProcessToFileHead(Archive &Src,bool LastBlockAdded,
Pack *Pack=NULL,const char *SkipName=NULL);
void TmpToArc(Archive &Src);
void CloseNew(int AdjustRecovery,bool CloseVolume);
void WriteEndBlock(bool CloseVolume);
void CopyFileRecord(Archive &Src);
void CopyArchiveData(Archive &Src);
bool GetComment(Array<byte> *CmtData,Array<wchar> *CmtDataW);
void ViewComment();
void ViewFileComment();
void SetLatestTime(RarTime *NewTime);
void SeekToNext();
bool CheckAccess();
bool IsArcDir();
bool IsArcLabel();
void ConvertAttributes();
int GetRecoverySize(bool Required);
void VolSubtractHeaderSize(size_t SubSize);
void AddSubData(byte *SrcData,size_t DataSize,File *SrcFile,const char *Name,bool AllowSplit);
bool ReadSubData(Array<byte> *UnpData,File *DestFile);
int GetHeaderType() {return(CurHeaderType);};
size_t ReadCommentData(Array<byte> *CmtData,Array<wchar> *CmtDataW);
void WriteCommentData(byte *Data,size_t DataSize,bool FileComment);
RAROptions* GetRAROptions() {return(Cmd);}
void SetSilentOpen(bool Mode) {SilentOpen=Mode;}
BaseBlock ShortBlock;
MainHeader NewMhd;
FileHeader NewLhd;
EndArcHeader EndArcHead;
SubBlockHeader SubBlockHead;
FileHeader SubHead;
CommentHeader CommHead;
ProtectHeader ProtectHead;
AVHeader AVHead;
SignHeader SignHead;
UnixOwnersHeader UOHead;
MacFInfoHeader MACHead;
EAHeader EAHead;
StreamHeader StreamHead;
int64 CurBlockPos;
int64 NextBlockPos;
bool OldFormat;
bool Solid;
bool Volume;
bool MainComment;
bool Locked;
bool Signed;
bool NotFirstVolume;
bool Protected;
bool Encrypted;
size_t SFXSize;
bool BrokenFileHeader;
bool Splitting;
ushort HeaderCRC;
int64 VolWrite;
int64 AddingFilesSize;
size_t AddingHeadersSize;
bool NewArchive;
char FirstVolumeName[NM];
wchar FirstVolumeNameW[NM];
};
#endif

712
libunrar/arcread.cpp Normal file
View File

@ -0,0 +1,712 @@
#include "rar.hpp"
size_t Archive::SearchBlock(int BlockType)
{
size_t Size,Count=0;
while ((Size=ReadHeader())!=0 &&
(BlockType==ENDARC_HEAD || GetHeaderType()!=ENDARC_HEAD))
{
if ((++Count & 127)==0)
Wait();
if (GetHeaderType()==BlockType)
return(Size);
SeekToNext();
}
return(0);
}
size_t Archive::SearchSubBlock(const char *Type)
{
size_t Size;
while ((Size=ReadHeader())!=0 && GetHeaderType()!=ENDARC_HEAD)
{
if (GetHeaderType()==NEWSUB_HEAD && SubHead.CmpName(Type))
return(Size);
SeekToNext();
}
return(0);
}
void Archive::UnexpEndArcMsg()
{
int64 ArcSize=FileLength();
if (CurBlockPos>ArcSize || NextBlockPos>ArcSize)
{
#ifndef SHELL_EXT
Log(FileName,St(MLogUnexpEOF));
#endif
ErrHandler.SetErrorCode(WARNING);
}
}
size_t Archive::ReadHeader()
{
CurBlockPos=Tell();
#ifndef SFX_MODULE
if (OldFormat)
return(ReadOldHeader());
#endif
RawRead Raw(this);
bool Decrypt=Encrypted && CurBlockPos>=(int64)SFXSize+SIZEOF_MARKHEAD+SIZEOF_NEWMHD;
if (Decrypt)
{
#if defined(SHELL_EXT) || defined(NOCRYPT)
return(0);
#else
if (Read(HeadersSalt,SALT_SIZE)!=SALT_SIZE)
{
UnexpEndArcMsg();
return(0);
}
if (*Cmd->Password==0)
#ifdef RARDLL
if (Cmd->Callback==NULL ||
Cmd->Callback(UCM_NEEDPASSWORD,Cmd->UserData,(LPARAM)Cmd->Password,sizeof(Cmd->Password))==-1)
{
Close();
ErrHandler.Exit(USER_BREAK);
}
#else
if (!GetPassword(PASSWORD_ARCHIVE,FileName,Cmd->Password,sizeof(Cmd->Password)))
{
Close();
ErrHandler.Exit(USER_BREAK);
}
#endif
HeadersCrypt.SetCryptKeys(Cmd->Password,HeadersSalt,false,false,NewMhd.EncryptVer>=36);
Raw.SetCrypt(&HeadersCrypt);
#endif
}
Raw.Read(SIZEOF_SHORTBLOCKHEAD);
if (Raw.Size()==0)
{
UnexpEndArcMsg();
return(0);
}
Raw.Get(ShortBlock.HeadCRC);
byte HeadType;
Raw.Get(HeadType);
ShortBlock.HeadType=(HEADER_TYPE)HeadType;
Raw.Get(ShortBlock.Flags);
Raw.Get(ShortBlock.HeadSize);
if (ShortBlock.HeadSize<SIZEOF_SHORTBLOCKHEAD)
{
#ifndef SHELL_EXT
Log(FileName,St(MLogFileHead),"???");
#endif
BrokenFileHeader=true;
ErrHandler.SetErrorCode(CRC_ERROR);
return(0);
}
if (ShortBlock.HeadType==COMM_HEAD)
Raw.Read(SIZEOF_COMMHEAD-SIZEOF_SHORTBLOCKHEAD);
else
if (ShortBlock.HeadType==MAIN_HEAD && (ShortBlock.Flags & MHD_COMMENT)!=0)
Raw.Read(SIZEOF_NEWMHD-SIZEOF_SHORTBLOCKHEAD);
else
Raw.Read(ShortBlock.HeadSize-SIZEOF_SHORTBLOCKHEAD);
NextBlockPos=CurBlockPos+ShortBlock.HeadSize;
switch(ShortBlock.HeadType)
{
case MAIN_HEAD:
*(BaseBlock *)&NewMhd=ShortBlock;
Raw.Get(NewMhd.HighPosAV);
Raw.Get(NewMhd.PosAV);
if (NewMhd.Flags & MHD_ENCRYPTVER)
Raw.Get(NewMhd.EncryptVer);
break;
case ENDARC_HEAD:
*(BaseBlock *)&EndArcHead=ShortBlock;
if (EndArcHead.Flags & EARC_DATACRC)
Raw.Get(EndArcHead.ArcDataCRC);
if (EndArcHead.Flags & EARC_VOLNUMBER)
Raw.Get(EndArcHead.VolNumber);
break;
case FILE_HEAD:
case NEWSUB_HEAD:
{
FileHeader *hd=ShortBlock.HeadType==FILE_HEAD ? &NewLhd:&SubHead;
*(BaseBlock *)hd=ShortBlock;
Raw.Get(hd->PackSize);
Raw.Get(hd->UnpSize);
Raw.Get(hd->HostOS);
Raw.Get(hd->FileCRC);
Raw.Get(hd->FileTime);
Raw.Get(hd->UnpVer);
Raw.Get(hd->Method);
Raw.Get(hd->NameSize);
Raw.Get(hd->FileAttr);
if (hd->Flags & LHD_LARGE)
{
Raw.Get(hd->HighPackSize);
Raw.Get(hd->HighUnpSize);
}
else
{
hd->HighPackSize=hd->HighUnpSize=0;
if (hd->UnpSize==0xffffffff)
{
// UnpSize equal to 0xffffffff without LHD_LARGE flag indicates
// that we do not know the unpacked file size and must unpack it
// until we find the end of file marker in compressed data.
hd->UnpSize=(uint)(INT64NDF);
hd->HighUnpSize=(uint)(INT64NDF>>32);
}
}
hd->FullPackSize=INT32TO64(hd->HighPackSize,hd->PackSize);
hd->FullUnpSize=INT32TO64(hd->HighUnpSize,hd->UnpSize);
char FileName[NM*4];
int NameSize=Min(hd->NameSize,sizeof(FileName)-1);
Raw.Get((byte *)FileName,NameSize);
FileName[NameSize]=0;
strncpyz(hd->FileName,FileName,ASIZE(hd->FileName));
if (hd->HeadType==NEWSUB_HEAD)
{
int DataSize=hd->HeadSize-hd->NameSize-SIZEOF_NEWLHD;
if (hd->Flags & LHD_SALT)
DataSize-=SALT_SIZE;
if (DataSize>0)
{
hd->SubData.Alloc(DataSize);
Raw.Get(&hd->SubData[0],DataSize);
if (hd->CmpName(SUBHEAD_TYPE_RR))
{
byte *D=&hd->SubData[8];
RecoverySectors=D[0]+((uint)D[1]<<8)+((uint)D[2]<<16)+((uint)D[3]<<24);
}
}
}
else
if (hd->HeadType==FILE_HEAD)
{
if (hd->Flags & LHD_UNICODE)
{
EncodeFileName NameCoder;
size_t Length=strlen(FileName);
if (Length==hd->NameSize)
{
UtfToWide(FileName,hd->FileNameW,sizeof(hd->FileNameW)/sizeof(hd->FileNameW[0])-1);
WideToChar(hd->FileNameW,hd->FileName,sizeof(hd->FileName)/sizeof(hd->FileName[0])-1);
ExtToInt(hd->FileName,hd->FileName);
}
else
{
Length++;
NameCoder.Decode(FileName,(byte *)FileName+Length,
hd->NameSize-Length,hd->FileNameW,
sizeof(hd->FileNameW)/sizeof(hd->FileNameW[0]));
}
if (*hd->FileNameW==0)
hd->Flags &= ~LHD_UNICODE;
}
else
*hd->FileNameW=0;
#ifndef SFX_MODULE
ConvertNameCase(hd->FileName);
ConvertNameCase(hd->FileNameW);
#endif
ConvertUnknownHeader();
}
if (hd->Flags & LHD_SALT)
Raw.Get(hd->Salt,SALT_SIZE);
hd->mtime.SetDos(hd->FileTime);
hd->ctime.Reset();
hd->atime.Reset();
hd->arctime.Reset();
if (hd->Flags & LHD_EXTTIME)
{
ushort Flags;
Raw.Get(Flags);
RarTime *tbl[4];
tbl[0]=&NewLhd.mtime;
tbl[1]=&NewLhd.ctime;
tbl[2]=&NewLhd.atime;
tbl[3]=&NewLhd.arctime;
for (int I=0;I<4;I++)
{
RarTime *CurTime=tbl[I];
uint rmode=Flags>>(3-I)*4;
if ((rmode & 8)==0)
continue;
if (I!=0)
{
uint DosTime;
Raw.Get(DosTime);
CurTime->SetDos(DosTime);
}
RarLocalTime rlt;
CurTime->GetLocal(&rlt);
if (rmode & 4)
rlt.Second++;
rlt.Reminder=0;
int count=rmode&3;
for (int J=0;J<count;J++)
{
byte CurByte;
Raw.Get(CurByte);
rlt.Reminder|=(((uint)CurByte)<<((J+3-count)*8));
}
CurTime->SetLocal(&rlt);
}
}
NextBlockPos+=hd->FullPackSize;
bool CRCProcessedOnly=(hd->Flags & LHD_COMMENT)!=0;
HeaderCRC=~Raw.GetCRC(CRCProcessedOnly)&0xffff;
if (hd->HeadCRC!=HeaderCRC)
{
if (hd->HeadType==NEWSUB_HEAD)
strcat(hd->FileName,"- ???");
BrokenFileHeader=true;
ErrHandler.SetErrorCode(WARNING);
#ifndef SHELL_EXT
Log(Archive::FileName,St(MLogFileHead),IntNameToExt(hd->FileName));
Alarm();
#endif
}
}
break;
#ifndef SFX_MODULE
case COMM_HEAD:
*(BaseBlock *)&CommHead=ShortBlock;
Raw.Get(CommHead.UnpSize);
Raw.Get(CommHead.UnpVer);
Raw.Get(CommHead.Method);
Raw.Get(CommHead.CommCRC);
break;
case SIGN_HEAD:
*(BaseBlock *)&SignHead=ShortBlock;
Raw.Get(SignHead.CreationTime);
Raw.Get(SignHead.ArcNameSize);
Raw.Get(SignHead.UserNameSize);
break;
case AV_HEAD:
*(BaseBlock *)&AVHead=ShortBlock;
Raw.Get(AVHead.UnpVer);
Raw.Get(AVHead.Method);
Raw.Get(AVHead.AVVer);
Raw.Get(AVHead.AVInfoCRC);
break;
case PROTECT_HEAD:
*(BaseBlock *)&ProtectHead=ShortBlock;
Raw.Get(ProtectHead.DataSize);
Raw.Get(ProtectHead.Version);
Raw.Get(ProtectHead.RecSectors);
Raw.Get(ProtectHead.TotalBlocks);
Raw.Get(ProtectHead.Mark,8);
NextBlockPos+=ProtectHead.DataSize;
RecoverySectors=ProtectHead.RecSectors;
break;
case SUB_HEAD:
*(BaseBlock *)&SubBlockHead=ShortBlock;
Raw.Get(SubBlockHead.DataSize);
NextBlockPos+=SubBlockHead.DataSize;
Raw.Get(SubBlockHead.SubType);
Raw.Get(SubBlockHead.Level);
switch(SubBlockHead.SubType)
{
case UO_HEAD:
*(SubBlockHeader *)&UOHead=SubBlockHead;
Raw.Get(UOHead.OwnerNameSize);
Raw.Get(UOHead.GroupNameSize);
if (UOHead.OwnerNameSize>NM-1)
UOHead.OwnerNameSize=NM-1;
if (UOHead.GroupNameSize>NM-1)
UOHead.GroupNameSize=NM-1;
Raw.Get((byte *)UOHead.OwnerName,UOHead.OwnerNameSize);
Raw.Get((byte *)UOHead.GroupName,UOHead.GroupNameSize);
UOHead.OwnerName[UOHead.OwnerNameSize]=0;
UOHead.GroupName[UOHead.GroupNameSize]=0;
break;
case MAC_HEAD:
*(SubBlockHeader *)&MACHead=SubBlockHead;
Raw.Get(MACHead.fileType);
Raw.Get(MACHead.fileCreator);
break;
case EA_HEAD:
case BEEA_HEAD:
case NTACL_HEAD:
*(SubBlockHeader *)&EAHead=SubBlockHead;
Raw.Get(EAHead.UnpSize);
Raw.Get(EAHead.UnpVer);
Raw.Get(EAHead.Method);
Raw.Get(EAHead.EACRC);
break;
case STREAM_HEAD:
*(SubBlockHeader *)&StreamHead=SubBlockHead;
Raw.Get(StreamHead.UnpSize);
Raw.Get(StreamHead.UnpVer);
Raw.Get(StreamHead.Method);
Raw.Get(StreamHead.StreamCRC);
Raw.Get(StreamHead.StreamNameSize);
if (StreamHead.StreamNameSize>NM-1)
StreamHead.StreamNameSize=NM-1;
Raw.Get((byte *)StreamHead.StreamName,StreamHead.StreamNameSize);
StreamHead.StreamName[StreamHead.StreamNameSize]=0;
break;
}
break;
#endif
default:
if (ShortBlock.Flags & LONG_BLOCK)
{
uint DataSize;
Raw.Get(DataSize);
NextBlockPos+=DataSize;
}
break;
}
HeaderCRC=~Raw.GetCRC(false)&0xffff;
CurHeaderType=ShortBlock.HeadType;
if (Decrypt)
{
NextBlockPos+=Raw.PaddedSize()+SALT_SIZE;
if (ShortBlock.HeadCRC!=HeaderCRC)
{
bool Recovered=false;
if (ShortBlock.HeadType==ENDARC_HEAD && (EndArcHead.Flags & EARC_REVSPACE)!=0)
{
// Last 7 bytes of recovered volume can contain zeroes, because
// REV files store its own information (volume number, etc.) here.
SaveFilePos SavePos(*this);
int64 Length=Tell();
Seek(Length-7,SEEK_SET);
Recovered=true;
for (int J=0;J<7;J++)
if (GetByte()!=0)
Recovered=false;
}
if (!Recovered)
{
#ifndef SILENT
Log(FileName,St(MEncrBadCRC),FileName);
#endif
Close();
BrokenFileHeader=true;
ErrHandler.SetErrorCode(CRC_ERROR);
return(0);
// ErrHandler.Exit(CRC_ERROR);
}
}
}
if (NextBlockPos<=CurBlockPos)
{
#ifndef SHELL_EXT
Log(FileName,St(MLogFileHead),"???");
#endif
BrokenFileHeader=true;
ErrHandler.SetErrorCode(CRC_ERROR);
return(0);
}
return(Raw.Size());
}
#ifndef SFX_MODULE
size_t Archive::ReadOldHeader()
{
RawRead Raw(this);
if (CurBlockPos<=(int64)SFXSize)
{
Raw.Read(SIZEOF_OLDMHD);
Raw.Get(OldMhd.Mark,4);
Raw.Get(OldMhd.HeadSize);
Raw.Get(OldMhd.Flags);
NextBlockPos=CurBlockPos+OldMhd.HeadSize;
CurHeaderType=MAIN_HEAD;
}
else
{
OldFileHeader OldLhd;
Raw.Read(SIZEOF_OLDLHD);
NewLhd.HeadType=FILE_HEAD;
Raw.Get(NewLhd.PackSize);
Raw.Get(NewLhd.UnpSize);
Raw.Get(OldLhd.FileCRC);
Raw.Get(NewLhd.HeadSize);
Raw.Get(NewLhd.FileTime);
Raw.Get(OldLhd.FileAttr);
Raw.Get(OldLhd.Flags);
Raw.Get(OldLhd.UnpVer);
Raw.Get(OldLhd.NameSize);
Raw.Get(OldLhd.Method);
NewLhd.Flags=OldLhd.Flags|LONG_BLOCK;
NewLhd.UnpVer=(OldLhd.UnpVer==2) ? 13 : 10;
NewLhd.Method=OldLhd.Method+0x30;
NewLhd.NameSize=OldLhd.NameSize;
NewLhd.FileAttr=OldLhd.FileAttr;
NewLhd.FileCRC=OldLhd.FileCRC;
NewLhd.FullPackSize=NewLhd.PackSize;
NewLhd.FullUnpSize=NewLhd.UnpSize;
NewLhd.mtime.SetDos(NewLhd.FileTime);
NewLhd.ctime.Reset();
NewLhd.atime.Reset();
NewLhd.arctime.Reset();
Raw.Read(OldLhd.NameSize);
Raw.Get((byte *)NewLhd.FileName,OldLhd.NameSize);
NewLhd.FileName[OldLhd.NameSize]=0;
ConvertNameCase(NewLhd.FileName);
*NewLhd.FileNameW=0;
if (Raw.Size()!=0)
NextBlockPos=CurBlockPos+NewLhd.HeadSize+NewLhd.PackSize;
CurHeaderType=FILE_HEAD;
}
return(NextBlockPos>CurBlockPos ? Raw.Size():0);
}
#endif
void Archive::ConvertNameCase(char *Name)
{
if (Cmd->ConvertNames==NAMES_UPPERCASE)
{
IntToExt(Name,Name);
strupper(Name);
ExtToInt(Name,Name);
}
if (Cmd->ConvertNames==NAMES_LOWERCASE)
{
IntToExt(Name,Name);
strlower(Name);
ExtToInt(Name,Name);
}
}
#ifndef SFX_MODULE
void Archive::ConvertNameCase(wchar *Name)
{
if (Cmd->ConvertNames==NAMES_UPPERCASE)
strupperw(Name);
if (Cmd->ConvertNames==NAMES_LOWERCASE)
strlowerw(Name);
}
#endif
bool Archive::IsArcDir()
{
return((NewLhd.Flags & LHD_WINDOWMASK)==LHD_DIRECTORY);
}
bool Archive::IsArcLabel()
{
return(NewLhd.HostOS<=HOST_WIN32 && (NewLhd.FileAttr & 8));
}
void Archive::ConvertAttributes()
{
#if defined(_WIN_32) || defined(_EMX)
switch(NewLhd.HostOS)
{
case HOST_MSDOS:
case HOST_OS2:
case HOST_WIN32:
break;
case HOST_UNIX:
case HOST_BEOS:
if ((NewLhd.Flags & LHD_WINDOWMASK)==LHD_DIRECTORY)
NewLhd.FileAttr=0x10;
else
NewLhd.FileAttr=0x20;
break;
default:
if ((NewLhd.Flags & LHD_WINDOWMASK)==LHD_DIRECTORY)
NewLhd.FileAttr=0x10;
else
NewLhd.FileAttr=0x20;
break;
}
#endif
#ifdef _UNIX
// umask defines which permission bits must not be set by default
// when creating a file or directory.
static mode_t mask = (mode_t) -1;
if (mask == (mode_t) -1)
{
// umask call returns the current umask value. Argument (022) is not
// important here.
mask = umask(022);
// Restore the original umask value, which was changed to 022 above.
umask(mask);
}
switch(NewLhd.HostOS)
{
case HOST_MSDOS:
case HOST_OS2:
case HOST_WIN32:
{
// Mapping MSDOS, OS/2 and Windows file attributes to Unix.
if (NewLhd.FileAttr & 0x10) // FILE_ATTRIBUTE_DIRECTORY
{
// For directories we use 0777 mask.
NewLhd.FileAttr=0777 & ~mask;
}
else
if (NewLhd.FileAttr & 1) // FILE_ATTRIBUTE_READONLY
{
// For read only files we use 0444 mask with 'w' bits turned off.
NewLhd.FileAttr=0444 & ~mask;
}
else
{
// umask does not set +x for regular files, so we use 0666
// instead of 0777 as for directories.
NewLhd.FileAttr=0666 & ~mask;
}
}
break;
case HOST_UNIX:
case HOST_BEOS:
break;
default:
if ((NewLhd.Flags & LHD_WINDOWMASK)==LHD_DIRECTORY)
NewLhd.FileAttr=0x41ff & ~mask;
else
NewLhd.FileAttr=0x81b6 & ~mask;
break;
}
#endif
}
void Archive::ConvertUnknownHeader()
{
if (NewLhd.UnpVer<20 && (NewLhd.FileAttr & 0x10))
NewLhd.Flags|=LHD_DIRECTORY;
if (NewLhd.HostOS>=HOST_MAX)
{
if ((NewLhd.Flags & LHD_WINDOWMASK)==LHD_DIRECTORY)
NewLhd.FileAttr=0x10;
else
NewLhd.FileAttr=0x20;
}
for (char *s=NewLhd.FileName;*s!=0;s=charnext(s))
{
if (*s=='/' || *s=='\\')
*s=CPATHDIVIDER;
#if defined(_APPLE) && !defined(UNICODE_SUPPORTED)
if ((byte)*s<32 || (byte)*s>127)
*s='_';
#endif
#if defined(_WIN_32) || defined(_EMX)
// ':' in file names is allowed in Unix, but not in Windows.
// Even worse, file data will be written to NTFS stream on NTFS,
// so automatic name correction on file create error in extraction
// routine does not work. In Windows and DOS versions we better
// replace ':' now.
if (*s==':')
*s='_';
#endif
}
for (wchar *s=NewLhd.FileNameW;*s!=0;s++)
{
if (*s=='/' || *s=='\\')
*s=CPATHDIVIDER;
#if defined(_WIN_32) || defined(_EMX)
// ':' in file names is allowed in Unix, but not in Windows.
// Even worse, file data will be written to NTFS stream on NTFS,
// so automatic name correction on file create error in extraction
// routine does not work. In Windows and DOS versions we better
// replace ':' now.
if (*s==':')
*s='_';
#endif
}
}
#ifndef SHELL_EXT
bool Archive::ReadSubData(Array<byte> *UnpData,File *DestFile)
{
if (HeaderCRC!=SubHead.HeadCRC)
{
#ifndef SHELL_EXT
Log(FileName,St(MSubHeadCorrupt));
#endif
ErrHandler.SetErrorCode(CRC_ERROR);
return(false);
}
if (SubHead.Method<0x30 || SubHead.Method>0x35 || SubHead.UnpVer>/*PACK_VER*/36)
{
#ifndef SHELL_EXT
Log(FileName,St(MSubHeadUnknown));
#endif
return(false);
}
if (SubHead.PackSize==0 && (SubHead.Flags & LHD_SPLIT_AFTER)==0)
return(true);
SubDataIO.Init();
Unpack Unpack(&SubDataIO);
Unpack.Init();
if (DestFile==NULL)
{
UnpData->Alloc(SubHead.UnpSize);
SubDataIO.SetUnpackToMemory(&(*UnpData)[0],SubHead.UnpSize);
}
if (SubHead.Flags & LHD_PASSWORD)
if (*Cmd->Password)
SubDataIO.SetEncryption(SubHead.UnpVer,Cmd->Password,
(SubHead.Flags & LHD_SALT) ? SubHead.Salt:NULL,false,
SubHead.UnpVer>=36);
else
return(false);
SubDataIO.SetPackedSizeToRead(SubHead.PackSize);
SubDataIO.EnableShowProgress(false);
SubDataIO.SetFiles(this,DestFile);
SubDataIO.UnpVolume=(SubHead.Flags & LHD_SPLIT_AFTER)!=0;
SubDataIO.SetSubHeader(&SubHead,NULL);
Unpack.SetDestSize(SubHead.UnpSize);
if (SubHead.Method==0x30)
CmdExtract::UnstoreFile(SubDataIO,SubHead.UnpSize);
else
Unpack.DoUnpack(SubHead.UnpVer,false);
if (SubHead.FileCRC!=~SubDataIO.UnpFileCRC)
{
#ifndef SHELL_EXT
Log(FileName,St(MSubHeadDataCRC),SubHead.FileName);
#endif
ErrHandler.SetErrorCode(CRC_ERROR);
if (UnpData!=NULL)
UnpData->Reset();
return(false);
}
return(true);
}
#endif

122
libunrar/array.hpp Normal file
View File

@ -0,0 +1,122 @@
#ifndef _RAR_ARRAY_
#define _RAR_ARRAY_
extern ErrorHandler ErrHandler;
template <class T> class Array
{
private:
T *Buffer;
size_t BufSize;
size_t AllocSize;
public:
Array();
Array(size_t Size);
~Array();
inline void CleanData();
inline T& operator [](size_t Item);
inline size_t Size();
void Add(size_t Items);
void Alloc(size_t Items);
void Reset();
void operator = (Array<T> &Src);
void Push(T Item);
T* Addr() {return(Buffer);}
};
template <class T> void Array<T>::CleanData()
{
Buffer=NULL;
BufSize=0;
AllocSize=0;
}
template <class T> Array<T>::Array()
{
CleanData();
}
template <class T> Array<T>::Array(size_t Size)
{
Buffer=(T *)rarmalloc(sizeof(T)*Size);
if (Buffer==NULL && Size!=0)
ErrHandler.MemoryError();
AllocSize=BufSize=Size;
}
template <class T> Array<T>::~Array()
{
if (Buffer!=NULL)
rarfree(Buffer);
}
template <class T> inline T& Array<T>::operator [](size_t Item)
{
return(Buffer[Item]);
}
template <class T> inline size_t Array<T>::Size()
{
return(BufSize);
}
template <class T> void Array<T>::Add(size_t Items)
{
BufSize+=Items;
if (BufSize>AllocSize)
{
size_t Suggested=AllocSize+AllocSize/4+32;
size_t NewSize=Max(BufSize,Suggested);
Buffer=(T *)rarrealloc(Buffer,NewSize*sizeof(T));
if (Buffer==NULL)
ErrHandler.MemoryError();
AllocSize=NewSize;
}
}
template <class T> void Array<T>::Alloc(size_t Items)
{
if (Items>AllocSize)
Add(Items-BufSize);
else
BufSize=Items;
}
template <class T> void Array<T>::Reset()
{
if (Buffer!=NULL)
{
rarfree(Buffer);
Buffer=NULL;
}
BufSize=0;
AllocSize=0;
}
template <class T> void Array<T>::operator =(Array<T> &Src)
{
Reset();
Alloc(Src.BufSize);
if (Src.BufSize!=0)
memcpy((void *)Buffer,(void *)Src.Buffer,Src.BufSize*sizeof(T));
}
template <class T> void Array<T>::Push(T Item)
{
Add(1);
(*this)[Size()-1]=Item;
}
#endif

113
libunrar/beosea.cpp Normal file
View File

@ -0,0 +1,113 @@
void ExtractBeEA(Archive &Arc,char *FileName)
{
if (Arc.HeaderCRC!=Arc.EAHead.HeadCRC)
{
Log(Arc.FileName,St(MEABroken),FileName);
ErrHandler.SetErrorCode(CRC_ERROR);
return;
}
if (Arc.EAHead.Method<0x31 || Arc.EAHead.Method>0x35 || Arc.EAHead.UnpVer>PACK_VER)
{
Log(Arc.FileName,St(MEAUnknHeader),FileName);
return;
}
ComprDataIO DataIO;
Unpack Unpack(&DataIO);
Unpack.Init();
Array<byte> UnpData(Arc.EAHead.UnpSize);
DataIO.SetUnpackToMemory(&UnpData[0],Arc.EAHead.UnpSize);
DataIO.SetPackedSizeToRead(Arc.EAHead.DataSize);
DataIO.EnableShowProgress(false);
DataIO.SetFiles(&Arc,NULL);
Unpack.SetDestSize(Arc.EAHead.UnpSize);
Unpack.DoUnpack(Arc.EAHead.UnpVer,false);
if (Arc.EAHead.EACRC!=~DataIO.UnpFileCRC)
{
Log(Arc.FileName,St(MEABroken),FileName);
ErrHandler.SetErrorCode(CRC_ERROR);
return;
}
int fd = open(FileName,O_WRONLY);
if (fd==-1)
{
Log(Arc.FileName,St(MCannotSetEA),FileName);
ErrHandler.SetErrorCode(WARNING);
return;
}
int AttrPos=0;
while (AttrPos<Arc.EAHead.UnpSize)
{
unsigned char *CurItem=&UnpData[AttrPos];
int NameSize=CurItem[0]+((int)CurItem[1]<<8);
int Type=CurItem[2]+((int)CurItem[3]<<8)+((int)CurItem[4]<<16)+((int)CurItem[5]<<24);
int Size=CurItem[6]+((int)CurItem[7]<<8)+((int)CurItem[8]<<16)+((int)CurItem[9]<<24);
char Name[1024];
if (NameSize>=sizeof(Name))
{
Log(Arc.FileName,St(MCannotSetEA),FileName);
ErrHandler.SetErrorCode(WARNING);
break;
}
memcpy(Name,CurItem+10,NameSize);
Name[NameSize]=0;
if (fs_write_attr(fd,Name,Type,0,CurItem+10+NameSize,Size)==-1)
{
Log(Arc.FileName,St(MCannotSetEA),FileName);
ErrHandler.SetErrorCode(WARNING);
break;
}
AttrPos+=10+NameSize+Size;
}
close(fd);
mprintf(St(MShowEA));
}
void ExtractBeEANew(Archive &Arc,char *FileName)
{
Array<byte> SubData;
if (!Arc.ReadSubData(&SubData,NULL))
return;
int fd = open(FileName,O_WRONLY);
if (fd==-1)
{
Log(Arc.FileName,St(MCannotSetEA),FileName);
ErrHandler.SetErrorCode(WARNING);
return;
}
int AttrPos=0;
while (AttrPos<Arc.EAHead.UnpSize)
{
unsigned char *CurItem=&SubData[AttrPos];
int NameSize=CurItem[0]+((int)CurItem[1]<<8);
int Type=CurItem[2]+((int)CurItem[3]<<8)+((int)CurItem[4]<<16)+((int)CurItem[5]<<24);
int Size=CurItem[6]+((int)CurItem[7]<<8)+((int)CurItem[8]<<16)+((int)CurItem[9]<<24);
char Name[1024];
if (NameSize>=sizeof(Name))
{
Log(Arc.FileName,St(MCannotSetEA),FileName);
ErrHandler.SetErrorCode(WARNING);
break;
}
memcpy(Name,CurItem+10,NameSize);
Name[NameSize]=0;
if (fs_write_attr(fd,Name,Type,0,CurItem+10+NameSize,Size)==-1)
{
Log(Arc.FileName,St(MCannotSetEA),FileName);
ErrHandler.SetErrorCode(WARNING);
break;
}
AttrPos+=10+NameSize+Size;
}
close(fd);
mprintf(St(MShowEA));
}

1298
libunrar/cmddata.cpp Normal file

File diff suppressed because it is too large Load Diff

57
libunrar/cmddata.hpp Normal file
View File

@ -0,0 +1,57 @@
#ifndef _RAR_CMDDATA_
#define _RAR_CMDDATA_
#define DefaultStoreList "7z;ace;arj;bz2;cab;gz;jpeg;jpg;lha;lzh;mp3;rar;taz;tgz;z;zip"
class CommandData:public RAROptions
{
private:
void ProcessSwitchesString(char *Str);
void ProcessSwitch(char *Switch,wchar *SwitchW=NULL);
void BadSwitch(char *Switch);
bool ExclCheckArgs(StringList *Args,char *CheckName,bool CheckFullPath,int MatchMode);
uint GetExclAttr(char *Str);
bool FileLists;
bool NoMoreSwitches;
bool BareOutput;
public:
CommandData();
~CommandData();
void Init();
void Close();
void ParseArg(char *Arg,wchar *ArgW);
void ParseDone();
void ParseEnvVar();
void ReadConfig(int argc,char *argv[]);
bool IsConfigEnabled(int argc,char *argv[]);
void OutTitle();
void OutHelp();
bool IsSwitch(int Ch);
bool ExclCheck(char *CheckName,bool CheckFullPath,bool CheckInclList);
bool StoreCheck(char *CheckName);
bool TimeCheck(RarTime &ft);
bool SizeCheck(int64 Size);
bool AnyFiltersActive();
int IsProcessFile(FileHeader &NewLhd,bool *ExactMatch=NULL,int MatchType=MATCH_WILDSUBPATH);
void ProcessCommand();
void AddArcName(char *Name,wchar *NameW);
bool GetArcName(char *Name,wchar *NameW,int MaxSize);
bool CheckWinSize();
int GetRecoverySize(char *Str,int DefSize);
char Command[NM+16];
wchar CommandW[NM+16];
char ArcName[NM];
wchar ArcNameW[NM];
StringList *FileArgs;
StringList *ExclArgs;
StringList *InclArgs;
StringList *ArcNames;
StringList *StoreArgs;
};
#endif

48
libunrar/coder.cpp Normal file
View File

@ -0,0 +1,48 @@
inline unsigned int RangeCoder::GetChar()
{
return(UnpackRead->GetChar());
}
void RangeCoder::InitDecoder(Unpack *UnpackRead)
{
RangeCoder::UnpackRead=UnpackRead;
low=code=0;
range=uint(-1);
for (int i=0;i < 4;i++)
code=(code << 8) | GetChar();
}
// (int) cast before "low" added only to suppress compiler warnings.
#define ARI_DEC_NORMALIZE(code,low,range,read) \
{ \
while ((low^(low+range))<TOP || range<BOT && ((range=-(int)low&(BOT-1)),1)) \
{ \
code=(code << 8) | read->GetChar(); \
range <<= 8; \
low <<= 8; \
} \
}
inline int RangeCoder::GetCurrentCount()
{
return (code-low)/(range /= SubRange.scale);
}
inline uint RangeCoder::GetCurrentShiftCount(uint SHIFT)
{
return (code-low)/(range >>= SHIFT);
}
inline void RangeCoder::Decode()
{
low += range*SubRange.LowCount;
range *= SubRange.HighCount-SubRange.LowCount;
}

24
libunrar/coder.hpp Normal file
View File

@ -0,0 +1,24 @@
/****************************************************************************
* Contents: 'Carryless rangecoder' by Dmitry Subbotin *
****************************************************************************/
const uint TOP=1 << 24, BOT=1 << 15;
class RangeCoder
{
public:
void InitDecoder(Unpack *UnpackRead);
inline int GetCurrentCount();
inline uint GetCurrentShiftCount(uint SHIFT);
inline void Decode();
inline void PutChar(unsigned int c);
inline unsigned int GetChar();
uint low, code, range;
struct SUBRANGE
{
uint LowCount, HighCount, scale;
} SubRange;
Unpack *UnpackRead;
};

36
libunrar/compress.hpp Normal file
View File

@ -0,0 +1,36 @@
#ifndef _RAR_COMPRESS_
#define _RAR_COMPRESS_
class ComprDataIO;
class PackingFileTable;
#define CODEBUFSIZE 0x4000
#define MAXWINSIZE 0x400000
#define MAXWINMASK (MAXWINSIZE-1)
#define LOW_DIST_REP_COUNT 16
#define NC 299 /* alphabet = {0, 1, 2, ..., NC - 1} */
#define DC 60
#define LDC 17
#define RC 28
#define HUFF_TABLE_SIZE (NC+DC+RC+LDC)
#define BC 20
#define NC20 298 /* alphabet = {0, 1, 2, ..., NC - 1} */
#define DC20 48
#define RC20 28
#define BC20 19
#define MC20 257
enum {CODE_HUFFMAN,CODE_LZ,CODE_LZ2,CODE_REPEATLZ,CODE_CACHELZ,
CODE_STARTFILE,CODE_ENDFILE,CODE_VM,CODE_VMDATA};
enum FilterType {
FILTER_NONE, FILTER_PPM /*dummy*/, FILTER_E8, FILTER_E8E9,
FILTER_UPCASETOLOW, FILTER_AUDIO, FILTER_RGB, FILTER_DELTA,
FILTER_ITANIUM, FILTER_E8E9V2
};
#endif

294
libunrar/consio.cpp Normal file
View File

@ -0,0 +1,294 @@
#include "rar.hpp"
#ifndef GUI
#include "log.cpp"
#endif
static int KbdAnsi(char *Addr,int Size);
#if !defined(GUI) && !defined(SILENT)
static void RawPrint(char *Msg,MESSAGE_TYPE MessageType);
static uint GetKey();
#endif
static MESSAGE_TYPE MsgStream=MSG_STDOUT;
static bool Sound=false;
const int MaxMsgSize=2*NM+2048;
void InitConsoleOptions(MESSAGE_TYPE MsgStream,bool Sound)
{
::MsgStream=MsgStream;
::Sound=Sound;
}
#if !defined(GUI) && !defined(SILENT)
void mprintf(const char *fmt,...)
{
if (MsgStream==MSG_NULL || MsgStream==MSG_ERRONLY)
return;
safebuf char Msg[MaxMsgSize];
va_list argptr;
va_start(argptr,fmt);
vsprintf(Msg,fmt,argptr);
RawPrint(Msg,MsgStream);
va_end(argptr);
}
#endif
#if !defined(GUI) && !defined(SILENT)
void eprintf(const char *fmt,...)
{
if (MsgStream==MSG_NULL)
return;
safebuf char Msg[MaxMsgSize];
va_list argptr;
va_start(argptr,fmt);
vsprintf(Msg,fmt,argptr);
RawPrint(Msg,MSG_STDERR);
va_end(argptr);
}
#endif
#if !defined(GUI) && !defined(SILENT)
void RawPrint(char *Msg,MESSAGE_TYPE MessageType)
{
File OutFile;
switch(MessageType)
{
case MSG_STDOUT:
OutFile.SetHandleType(FILE_HANDLESTD);
break;
case MSG_STDERR:
case MSG_ERRONLY:
OutFile.SetHandleType(FILE_HANDLEERR);
break;
default:
return;
}
#ifdef _WIN_32
CharToOem(Msg,Msg);
char OutMsg[MaxMsgSize],*OutPos=OutMsg;
for (int I=0;Msg[I]!=0;I++)
{
if (Msg[I]=='\n' && (I==0 || Msg[I-1]!='\r'))
*(OutPos++)='\r';
*(OutPos++)=Msg[I];
}
*OutPos=0;
strcpy(Msg,OutMsg);
#endif
#if defined(_UNIX) || defined(_EMX)
char OutMsg[MaxMsgSize],*OutPos=OutMsg;
for (int I=0;Msg[I]!=0;I++)
if (Msg[I]!='\r')
*(OutPos++)=Msg[I];
*OutPos=0;
strcpy(Msg,OutMsg);
#endif
OutFile.Write(Msg,strlen(Msg));
// OutFile.Flush();
}
#endif
#ifndef SILENT
void Alarm()
{
#ifndef SFX_MODULE
if (Sound)
putchar('\007');
#endif
}
#endif
#ifndef SILENT
#ifndef GUI
void GetPasswordText(char *Str,int MaxLength)
{
#ifdef _WIN_32
HANDLE hConIn=GetStdHandle(STD_INPUT_HANDLE);
HANDLE hConOut=GetStdHandle(STD_OUTPUT_HANDLE);
DWORD ConInMode,ConOutMode;
DWORD Read=0;
GetConsoleMode(hConIn,&ConInMode);
GetConsoleMode(hConOut,&ConOutMode);
SetConsoleMode(hConIn,ENABLE_LINE_INPUT);
SetConsoleMode(hConOut,ENABLE_PROCESSED_OUTPUT|ENABLE_WRAP_AT_EOL_OUTPUT);
ReadConsole(hConIn,Str,MaxLength-1,&Read,NULL);
Str[Read]=0;
OemToChar(Str,Str);
SetConsoleMode(hConIn,ConInMode);
SetConsoleMode(hConOut,ConOutMode);
#elif defined(_EMX) || defined(_BEOS) || defined(__sparc) || defined(sparc) || defined (__VMS)
fgets(Str,MaxLength-1,stdin);
#else
strncpyz(Str,getpass(""),MaxLength);
#endif
Str[MaxLength-1]=0;
RemoveLF(Str);
}
#endif
#endif
#ifndef SILENT
bool GetPassword(PASSWORD_TYPE Type,const char *FileName,char *Password,int MaxLength)
{
Alarm();
while (true)
{
char PromptStr[NM+256];
#if defined(_EMX) || defined(_BEOS)
strcpy(PromptStr,St(MAskPswEcho));
#else
strcpy(PromptStr,St(MAskPsw));
#endif
if (Type!=PASSWORD_GLOBAL)
{
strcat(PromptStr,St(MFor));
char *NameOnly=PointToName(FileName);
if (strlen(PromptStr)+strlen(NameOnly)<ASIZE(PromptStr))
strcat(PromptStr,NameOnly);
}
eprintf("\n%s: ",PromptStr);
GetPasswordText(Password,MaxLength);
if (*Password==0 && Type==PASSWORD_GLOBAL)
return(false);
if (Type==PASSWORD_GLOBAL)
{
eprintf(St(MReAskPsw));
char CmpStr[MAXPASSWORD];
GetPasswordText(CmpStr,ASIZE(CmpStr));
if (*CmpStr==0 || strcmp(Password,CmpStr)!=0)
{
eprintf(St(MNotMatchPsw));
memset(Password,0,MaxLength);
memset(CmpStr,0,sizeof(CmpStr));
continue;
}
memset(CmpStr,0,sizeof(CmpStr));
}
break;
}
return(true);
}
#endif
#if !defined(GUI) && !defined(SILENT)
uint GetKey()
{
char Str[80];
bool EndOfFile;
#if defined(__GNUC__) || defined(sun)
EndOfFile=(fgets(Str,sizeof(Str),stdin)==NULL);
#else
File SrcFile;
SrcFile.SetHandleType(FILE_HANDLESTD);
EndOfFile=(SrcFile.Read(Str,sizeof(Str))==0);
#endif
if (EndOfFile)
{
// Looks like stdin is a null device. We can enter to infinite loop
// calling Ask(), so let's better exit.
ErrHandler.Exit(USER_BREAK);
}
return(Str[0]);
}
#endif
#if !defined(GUI) && !defined(SILENT)
int Ask(const char *AskStr)
{
const int MaxItems=10;
char Item[MaxItems][40];
int ItemKeyPos[MaxItems],NumItems=0;
for (const char *NextItem=AskStr;NextItem!=NULL;NextItem=strchr(NextItem+1,'_'))
{
char *CurItem=Item[NumItems];
strncpyz(CurItem,NextItem+1,ASIZE(Item[0]));
char *EndItem=strchr(CurItem,'_');
if (EndItem!=NULL)
*EndItem=0;
int KeyPos=0,CurKey;
while ((CurKey=CurItem[KeyPos])!=0)
{
bool Found=false;
for (int I=0;I<NumItems && !Found;I++)
if (loctoupper(Item[I][ItemKeyPos[I]])==loctoupper(CurKey))
Found=true;
if (!Found && CurKey!=' ')
break;
KeyPos++;
}
ItemKeyPos[NumItems]=KeyPos;
NumItems++;
}
for (int I=0;I<NumItems;I++)
{
eprintf(I==0 ? (NumItems>4 ? "\n":" "):", ");
int KeyPos=ItemKeyPos[I];
for (int J=0;J<KeyPos;J++)
eprintf("%c",Item[I][J]);
eprintf("[%c]%s",Item[I][KeyPos],&Item[I][KeyPos+1]);
}
eprintf(" ");
int Ch=GetKey();
#if defined(_WIN_32)
OemToCharBuff((LPCSTR)&Ch,(LPTSTR)&Ch,1);
#endif
Ch=loctoupper(Ch);
for (int I=0;I<NumItems;I++)
if (Ch==Item[I][ItemKeyPos[I]])
return(I+1);
return(0);
}
#endif
int KbdAnsi(char *Addr,size_t Size)
{
int RetCode=0;
#ifndef GUI
for (size_t I=0;I<Size;I++)
if (Addr[I]==27 && Addr[I+1]=='[')
{
for (size_t J=I+2;J<Size;J++)
{
if (Addr[J]=='\"')
return(2);
if (!IsDigit(Addr[J]) && Addr[J]!=';')
break;
}
RetCode=1;
}
#endif
return(RetCode);
}
void OutComment(char *Comment,size_t Size)
{
#ifndef GUI
if (KbdAnsi(Comment,Size)==2)
return;
const size_t MaxOutSize=0x400;
for (size_t I=0;I<Size;I+=MaxOutSize)
{
char Msg[MaxOutSize+1];
size_t CopySize=Min(MaxOutSize,Size-I);
strncpy(Msg,Comment+I,CopySize);
Msg[CopySize]=0;
mprintf("%s",Msg);
}
mprintf("\n");
#endif
}

46
libunrar/consio.hpp Normal file
View File

@ -0,0 +1,46 @@
#ifndef _RAR_CONSIO_
#define _RAR_CONSIO_
#if !defined(SILENT) && !defined(SFX_MODULE)
enum {SOUND_OK,SOUND_ALARM,SOUND_ERROR,SOUND_QUESTION};
#endif
enum PASSWORD_TYPE {PASSWORD_GLOBAL,PASSWORD_FILE,PASSWORD_ARCHIVE};
void InitConsoleOptions(MESSAGE_TYPE MsgStream,bool Sound);
#ifndef SILENT
void mprintf(const char *fmt,...);
void eprintf(const char *fmt,...);
void Alarm();
void GetPasswordText(char *Str,int MaxLength);
bool GetPassword(PASSWORD_TYPE Type,const char *FileName,char *Password,int MaxLength);
int Ask(const char *AskStr);
#endif
void OutComment(char *Comment,size_t Size);
#ifdef SILENT
#ifdef __GNUC__
#define mprintf(args...)
#define eprintf(args...)
#else
#ifdef _MSC_VER
inline void mprintf(const char *fmt,...) {}
#else
inline void mprintf(const char *fmt,const char *a=NULL,const char *b=NULL) {}
#endif
inline void eprintf(const char *fmt,const char *a=NULL,const char *b=NULL) {}
inline void mprintf(const char *fmt,int b) {}
inline void eprintf(const char *fmt,int b) {}
inline void mprintf(const char *fmt,const char *a,int b) {}
inline void eprintf(const char *fmt,const char *a,int b) {}
#endif
inline void Alarm() {}
inline void GetPasswordText(char *Str,int MaxLength) {}
inline unsigned int GetKey() {return(0);}
inline bool GetPassword(PASSWORD_TYPE Type,const char *FileName,char *Password,int MaxLength) {return(false);}
inline int Ask(const char *AskStr) {return(0);}
#endif
#endif

63
libunrar/crc.cpp Normal file
View File

@ -0,0 +1,63 @@
#include "rar.hpp"
uint CRCTab[256];
void InitCRC()
{
for (int I=0;I<256;I++)
{
uint C=I;
for (int J=0;J<8;J++)
C=(C & 1) ? (C>>1)^0xEDB88320L : (C>>1);
CRCTab[I]=C;
}
}
uint CRC(uint StartCRC,const void *Addr,size_t Size)
{
if (CRCTab[1]==0)
InitCRC();
byte *Data=(byte *)Addr;
#if defined(LITTLE_ENDIAN) && defined(PRESENT_INT32) && defined(ALLOW_NOT_ALIGNED_INT)
while (Size>0 && ((long)Data & 7))
{
StartCRC=CRCTab[(byte)(StartCRC^Data[0])]^(StartCRC>>8);
Size--;
Data++;
}
while (Size>=8)
{
StartCRC^=*(uint32 *)Data;
StartCRC=CRCTab[(byte)StartCRC]^(StartCRC>>8);
StartCRC=CRCTab[(byte)StartCRC]^(StartCRC>>8);
StartCRC=CRCTab[(byte)StartCRC]^(StartCRC>>8);
StartCRC=CRCTab[(byte)StartCRC]^(StartCRC>>8);
StartCRC^=*(uint32 *)(Data+4);
StartCRC=CRCTab[(byte)StartCRC]^(StartCRC>>8);
StartCRC=CRCTab[(byte)StartCRC]^(StartCRC>>8);
StartCRC=CRCTab[(byte)StartCRC]^(StartCRC>>8);
StartCRC=CRCTab[(byte)StartCRC]^(StartCRC>>8);
Data+=8;
Size-=8;
}
#endif
for (size_t I=0;I<Size;I++)
StartCRC=CRCTab[(byte)(StartCRC^Data[I])]^(StartCRC>>8);
return(StartCRC);
}
#ifndef SFX_MODULE
ushort OldCRC(ushort StartCRC,const void *Addr,size_t Size)
{
byte *Data=(byte *)Addr;
for (size_t I=0;I<Size;I++)
{
StartCRC=(StartCRC+Data[I])&0xffff;
StartCRC=((StartCRC<<1)|(StartCRC>>15))&0xffff;
}
return(StartCRC);
}
#endif

10
libunrar/crc.hpp Normal file
View File

@ -0,0 +1,10 @@
#ifndef _RAR_CRC_
#define _RAR_CRC_
extern uint CRCTab[256];
void InitCRC();
uint CRC(uint StartCRC,const void *Addr,size_t Size);
ushort OldCRC(ushort StartCRC,const void *Addr,size_t Size);
#endif

381
libunrar/crypt.cpp Normal file
View File

@ -0,0 +1,381 @@
#include "rar.hpp"
#ifndef SFX_MODULE
extern uint CRCTab[256];
#endif
#define NROUNDS 32
#define rol(x,n,xsize) (((x)<<(n)) | ((x)>>(xsize-(n))))
#define ror(x,n,xsize) (((x)>>(n)) | ((x)<<(xsize-(n))))
#define substLong(t) ( (uint)SubstTable[(uint)t&255] | \
((uint)SubstTable[(int)(t>> 8)&255]<< 8) | \
((uint)SubstTable[(int)(t>>16)&255]<<16) | \
((uint)SubstTable[(int)(t>>24)&255]<<24) )
CryptKeyCacheItem CryptData::Cache[4];
int CryptData::CachePos=0;
#ifndef SFX_MODULE
static byte InitSubstTable[256]={
215, 19,149, 35, 73,197,192,205,249, 28, 16,119, 48,221, 2, 42,
232, 1,177,233, 14, 88,219, 25,223,195,244, 90, 87,239,153,137,
255,199,147, 70, 92, 66,246, 13,216, 40, 62, 29,217,230, 86, 6,
71, 24,171,196,101,113,218,123, 93, 91,163,178,202, 67, 44,235,
107,250, 75,234, 49,167,125,211, 83,114,157,144, 32,193,143, 36,
158,124,247,187, 89,214,141, 47,121,228, 61,130,213,194,174,251,
97,110, 54,229,115, 57,152, 94,105,243,212, 55,209,245, 63, 11,
164,200, 31,156, 81,176,227, 21, 76, 99,139,188,127, 17,248, 51,
207,120,189,210, 8,226, 41, 72,183,203,135,165,166, 60, 98, 7,
122, 38,155,170, 69,172,252,238, 39,134, 59,128,236, 27,240, 80,
131, 3, 85,206,145, 79,154,142,159,220,201,133, 74, 64, 20,129,
224,185,138,103,173,182, 43, 34,254, 82,198,151,231,180, 58, 10,
118, 26,102, 12, 50,132, 22,191,136,111,162,179, 45, 4,148,108,
161, 56, 78,126,242,222, 15,175,146, 23, 33,241,181,190, 77,225,
0, 46,169,186, 68, 95,237, 65, 53,208,253,168, 9, 18,100, 52,
116,184,160, 96,109, 37, 30,106,140,104,150, 5,204,117,112, 84
};
#endif
void CryptData::DecryptBlock(byte *Buf,size_t Size)
{
rin.blockDecrypt(Buf,Size,Buf);
}
#ifndef SFX_MODULE
void CryptData::EncryptBlock20(byte *Buf)
{
uint A,B,C,D,T,TA,TB;
#if defined(BIG_ENDIAN) || !defined(PRESENT_INT32) || !defined(ALLOW_NOT_ALIGNED_INT)
A=((uint)Buf[0]|((uint)Buf[1]<<8)|((uint)Buf[2]<<16)|((uint)Buf[3]<<24))^Key[0];
B=((uint)Buf[4]|((uint)Buf[5]<<8)|((uint)Buf[6]<<16)|((uint)Buf[7]<<24))^Key[1];
C=((uint)Buf[8]|((uint)Buf[9]<<8)|((uint)Buf[10]<<16)|((uint)Buf[11]<<24))^Key[2];
D=((uint)Buf[12]|((uint)Buf[13]<<8)|((uint)Buf[14]<<16)|((uint)Buf[15]<<24))^Key[3];
#else
uint32 *BufPtr=(uint32 *)Buf;
A=BufPtr[0]^Key[0];
B=BufPtr[1]^Key[1];
C=BufPtr[2]^Key[2];
D=BufPtr[3]^Key[3];
#endif
for(int I=0;I<NROUNDS;I++)
{
T=((C+rol(D,11,32))^Key[I&3]);
TA=A^substLong(T);
T=((D^rol(C,17,32))+Key[I&3]);
TB=B^substLong(T);
A=C;
B=D;
C=TA;
D=TB;
}
#if defined(BIG_ENDIAN) || !defined(PRESENT_INT32) || !defined(ALLOW_NOT_ALIGNED_INT)
C^=Key[0];
Buf[0]=(byte)C;
Buf[1]=(byte)(C>>8);
Buf[2]=(byte)(C>>16);
Buf[3]=(byte)(C>>24);
D^=Key[1];
Buf[4]=(byte)D;
Buf[5]=(byte)(D>>8);
Buf[6]=(byte)(D>>16);
Buf[7]=(byte)(D>>24);
A^=Key[2];
Buf[8]=(byte)A;
Buf[9]=(byte)(A>>8);
Buf[10]=(byte)(A>>16);
Buf[11]=(byte)(A>>24);
B^=Key[3];
Buf[12]=(byte)B;
Buf[13]=(byte)(B>>8);
Buf[14]=(byte)(B>>16);
Buf[15]=(byte)(B>>24);
#else
BufPtr[0]=C^Key[0];
BufPtr[1]=D^Key[1];
BufPtr[2]=A^Key[2];
BufPtr[3]=B^Key[3];
#endif
UpdKeys(Buf);
}
void CryptData::DecryptBlock20(byte *Buf)
{
byte InBuf[16];
uint A,B,C,D,T,TA,TB;
#if defined(BIG_ENDIAN) || !defined(PRESENT_INT32) || !defined(ALLOW_NOT_ALIGNED_INT)
A=((uint)Buf[0]|((uint)Buf[1]<<8)|((uint)Buf[2]<<16)|((uint)Buf[3]<<24))^Key[0];
B=((uint)Buf[4]|((uint)Buf[5]<<8)|((uint)Buf[6]<<16)|((uint)Buf[7]<<24))^Key[1];
C=((uint)Buf[8]|((uint)Buf[9]<<8)|((uint)Buf[10]<<16)|((uint)Buf[11]<<24))^Key[2];
D=((uint)Buf[12]|((uint)Buf[13]<<8)|((uint)Buf[14]<<16)|((uint)Buf[15]<<24))^Key[3];
#else
uint32 *BufPtr=(uint32 *)Buf;
A=BufPtr[0]^Key[0];
B=BufPtr[1]^Key[1];
C=BufPtr[2]^Key[2];
D=BufPtr[3]^Key[3];
#endif
memcpy(InBuf,Buf,sizeof(InBuf));
for(int I=NROUNDS-1;I>=0;I--)
{
T=((C+rol(D,11,32))^Key[I&3]);
TA=A^substLong(T);
T=((D^rol(C,17,32))+Key[I&3]);
TB=B^substLong(T);
A=C;
B=D;
C=TA;
D=TB;
}
#if defined(BIG_ENDIAN) || !defined(PRESENT_INT32) || !defined(ALLOW_NOT_ALIGNED_INT)
C^=Key[0];
Buf[0]=(byte)C;
Buf[1]=(byte)(C>>8);
Buf[2]=(byte)(C>>16);
Buf[3]=(byte)(C>>24);
D^=Key[1];
Buf[4]=(byte)D;
Buf[5]=(byte)(D>>8);
Buf[6]=(byte)(D>>16);
Buf[7]=(byte)(D>>24);
A^=Key[2];
Buf[8]=(byte)A;
Buf[9]=(byte)(A>>8);
Buf[10]=(byte)(A>>16);
Buf[11]=(byte)(A>>24);
B^=Key[3];
Buf[12]=(byte)B;
Buf[13]=(byte)(B>>8);
Buf[14]=(byte)(B>>16);
Buf[15]=(byte)(B>>24);
#else
BufPtr[0]=C^Key[0];
BufPtr[1]=D^Key[1];
BufPtr[2]=A^Key[2];
BufPtr[3]=B^Key[3];
#endif
UpdKeys(InBuf);
}
void CryptData::UpdKeys(byte *Buf)
{
for (int I=0;I<16;I+=4)
{
Key[0]^=CRCTab[Buf[I]];
Key[1]^=CRCTab[Buf[I+1]];
Key[2]^=CRCTab[Buf[I+2]];
Key[3]^=CRCTab[Buf[I+3]];
}
}
void CryptData::Swap(byte *Ch1,byte *Ch2)
{
byte Ch=*Ch1;
*Ch1=*Ch2;
*Ch2=Ch;
}
#endif
void CryptData::SetCryptKeys(const char *Password,const byte *Salt,bool Encrypt,bool OldOnly,bool HandsOffHash)
{
if (*Password==0)
return;
if (OldOnly)
{
#ifndef SFX_MODULE
if (CRCTab[1]==0)
InitCRC();
byte Psw[MAXPASSWORD];
SetOldKeys(Password);
Key[0]=0xD3A3B879L;
Key[1]=0x3F6D12F7L;
Key[2]=0x7515A235L;
Key[3]=0xA4E7F123L;
memset(Psw,0,sizeof(Psw));
#if defined(_WIN_32) && !defined(GUI)
CharToOemBuff(Password,(char*)Psw,(DWORD)strlen(Password));
#else
strncpyz((char *)Psw,Password,ASIZE(Psw));
#endif
size_t PswLength=strlen(Password);
memcpy(SubstTable,InitSubstTable,sizeof(SubstTable));
for (int J=0;J<256;J++)
for (size_t I=0;I<PswLength;I+=2)
{
uint N1=(byte)CRCTab[(Psw[I]-J)&0xff];
uint N2=(byte)CRCTab[(Psw[I+1]+J)&0xff];
for (int K=1;N1!=N2;N1=(N1+1)&0xff,K++)
Swap(&SubstTable[N1],&SubstTable[(N1+I+K)&0xff]);
}
for (size_t I=0;I<PswLength;I+=16)
EncryptBlock20(&Psw[I]);
#endif
return;
}
bool Cached=false;
for (int I=0;I<ASIZE(Cache);I++)
if (strcmp(Cache[I].Password,Password)==0 &&
(Salt==NULL && !Cache[I].SaltPresent || Salt!=NULL &&
Cache[I].SaltPresent && memcmp(Cache[I].Salt,Salt,SALT_SIZE)==0) &&
Cache[I].HandsOffHash==HandsOffHash)
{
memcpy(AESKey,Cache[I].AESKey,sizeof(AESKey));
memcpy(AESInit,Cache[I].AESInit,sizeof(AESInit));
Cached=true;
break;
}
if (!Cached)
{
wchar PswW[MAXPASSWORD];
CharToWide(Password,PswW,MAXPASSWORD-1);
PswW[MAXPASSWORD-1]=0;
byte RawPsw[2*MAXPASSWORD+SALT_SIZE];
WideToRaw(PswW,RawPsw);
size_t RawLength=2*strlenw(PswW);
if (Salt!=NULL)
{
memcpy(RawPsw+RawLength,Salt,SALT_SIZE);
RawLength+=SALT_SIZE;
}
hash_context c;
hash_initial(&c);
const int HashRounds=0x40000;
for (int I=0;I<HashRounds;I++)
{
hash_process( &c, RawPsw, RawLength, HandsOffHash);
byte PswNum[3];
PswNum[0]=(byte)I;
PswNum[1]=(byte)(I>>8);
PswNum[2]=(byte)(I>>16);
hash_process( &c, PswNum, 3, HandsOffHash);
if (I%(HashRounds/16)==0)
{
hash_context tempc=c;
uint32 digest[5];
hash_final( &tempc, digest, HandsOffHash);
AESInit[I/(HashRounds/16)]=(byte)digest[4];
}
}
uint32 digest[5];
hash_final( &c, digest, HandsOffHash);
for (int I=0;I<4;I++)
for (int J=0;J<4;J++)
AESKey[I*4+J]=(byte)(digest[I]>>(J*8));
strcpy(Cache[CachePos].Password,Password);
if ((Cache[CachePos].SaltPresent=(Salt!=NULL))==true)
memcpy(Cache[CachePos].Salt,Salt,SALT_SIZE);
Cache[CachePos].HandsOffHash=HandsOffHash;
memcpy(Cache[CachePos].AESKey,AESKey,sizeof(AESKey));
memcpy(Cache[CachePos].AESInit,AESInit,sizeof(AESInit));
CachePos=(CachePos+1)%(sizeof(Cache)/sizeof(Cache[0]));
}
rin.init(Encrypt ? Rijndael::Encrypt : Rijndael::Decrypt,AESKey,AESInit);
}
#ifndef SFX_MODULE
void CryptData::SetOldKeys(const char *Password)
{
uint PswCRC=CRC(0xffffffff,Password,strlen(Password));
OldKey[0]=PswCRC&0xffff;
OldKey[1]=(PswCRC>>16)&0xffff;
OldKey[2]=OldKey[3]=0;
PN1=PN2=PN3=0;
byte Ch;
while ((Ch=*Password)!=0)
{
PN1+=Ch;
PN2^=Ch;
PN3+=Ch;
PN3=(byte)rol(PN3,1,8);
OldKey[2]^=Ch^CRCTab[Ch];
OldKey[3]+=Ch+(CRCTab[Ch]>>16);
Password++;
}
}
void CryptData::SetAV15Encryption()
{
OldKey[0]=0x4765;
OldKey[1]=0x9021;
OldKey[2]=0x7382;
OldKey[3]=0x5215;
}
void CryptData::SetCmt13Encryption()
{
PN1=0;
PN2=7;
PN3=77;
}
void CryptData::Crypt(byte *Data,uint Count,int Method)
{
if (Method==OLD_DECODE)
Decode13(Data,Count);
else
if (Method==OLD_ENCODE)
Encode13(Data,Count);
else
Crypt15(Data,Count);
}
void CryptData::Encode13(byte *Data,uint Count)
{
while (Count--)
{
PN2+=PN3;
PN1+=PN2;
*Data+=PN1;
Data++;
}
}
void CryptData::Decode13(byte *Data,uint Count)
{
while (Count--)
{
PN2+=PN3;
PN1+=PN2;
*Data-=PN1;
Data++;
}
}
void CryptData::Crypt15(byte *Data,uint Count)
{
while (Count--)
{
OldKey[0]+=0x1234;
OldKey[1]^=CRCTab[(OldKey[0] & 0x1fe)>>1];
OldKey[2]-=CRCTab[(OldKey[0] & 0x1fe)>>1]>>16;
OldKey[0]^=OldKey[2];
OldKey[3]=ror(OldKey[3]&0xffff,1,16)^OldKey[1];
OldKey[3]=ror(OldKey[3]&0xffff,1,16);
OldKey[0]^=OldKey[3];
*Data^=(byte)(OldKey[0]>>8);
Data++;
}
}
#endif

62
libunrar/crypt.hpp Normal file
View File

@ -0,0 +1,62 @@
#ifndef _RAR_CRYPT_
#define _RAR_CRYPT_
enum { OLD_DECODE=0,OLD_ENCODE=1,NEW_CRYPT=2 };
struct CryptKeyCacheItem
{
#ifndef _SFX_RTL_
CryptKeyCacheItem()
{
*Password=0;
}
~CryptKeyCacheItem()
{
memset(AESKey,0,sizeof(AESKey));
memset(AESInit,0,sizeof(AESInit));
memset(Password,0,sizeof(Password));
}
#endif
byte AESKey[16],AESInit[16];
char Password[MAXPASSWORD];
bool SaltPresent;
byte Salt[SALT_SIZE];
bool HandsOffHash;
};
class CryptData
{
private:
void Encode13(byte *Data,uint Count);
void Decode13(byte *Data,uint Count);
void Crypt15(byte *Data,uint Count);
void UpdKeys(byte *Buf);
void Swap(byte *Ch1,byte *Ch2);
void SetOldKeys(const char *Password);
Rijndael rin;
byte SubstTable[256];
uint Key[4];
ushort OldKey[4];
byte PN1,PN2,PN3;
byte AESKey[16],AESInit[16];
static CryptKeyCacheItem Cache[4];
static int CachePos;
public:
void SetCryptKeys(const char *Password,const byte *Salt,bool Encrypt,bool OldOnly,bool HandsOffHash);
void SetAV15Encryption();
void SetCmt13Encryption();
void EncryptBlock20(byte *Buf);
void DecryptBlock20(byte *Buf);
void EncryptBlock(byte *Buf,size_t Size);
void DecryptBlock(byte *Buf,size_t Size);
void Crypt(byte *Data,uint Count,int Method);
static void SetSalt(byte *Salt,int SaltSize);
};
#endif

369
libunrar/dll.cpp Normal file
View File

@ -0,0 +1,369 @@
#include "rar.hpp"
#include "dll.hpp"
static int RarErrorToDll(int ErrCode);
struct DataSet
{
CommandData Cmd;
CmdExtract Extract;
Archive Arc;
int OpenMode;
int HeaderSize;
DataSet():Arc(&Cmd) {};
};
HANDLE PASCAL RAROpenArchive(struct RAROpenArchiveData *r)
{
RAROpenArchiveDataEx rx;
memset(&rx,0,sizeof(rx));
rx.ArcName=r->ArcName;
rx.OpenMode=r->OpenMode;
rx.CmtBuf=r->CmtBuf;
rx.CmtBufSize=r->CmtBufSize;
HANDLE hArc=RAROpenArchiveEx(&rx);
r->OpenResult=rx.OpenResult;
r->CmtSize=rx.CmtSize;
r->CmtState=rx.CmtState;
return(hArc);
}
HANDLE PASCAL RAROpenArchiveEx(struct RAROpenArchiveDataEx *r)
{
try
{
r->OpenResult=0;
DataSet *Data=new DataSet;
Data->Cmd.DllError=0;
Data->OpenMode=r->OpenMode;
Data->Cmd.FileArgs->AddString("*");
char an[NM];
if (r->ArcName==NULL && r->ArcNameW!=NULL)
{
WideToChar(r->ArcNameW,an,NM);
r->ArcName=an;
}
Data->Cmd.AddArcName(r->ArcName,r->ArcNameW);
Data->Cmd.Overwrite=OVERWRITE_ALL;
Data->Cmd.VersionControl=1;
if (!Data->Arc.Open(r->ArcName,r->ArcNameW))
{
r->OpenResult=ERAR_EOPEN;
delete Data;
return(NULL);
}
if (!Data->Arc.IsArchive(false))
{
r->OpenResult=Data->Cmd.DllError!=0 ? Data->Cmd.DllError:ERAR_BAD_ARCHIVE;
delete Data;
return(NULL);
}
r->Flags=Data->Arc.NewMhd.Flags;
Array<byte> CmtData;
if (r->CmtBufSize!=0 && Data->Arc.GetComment(&CmtData,NULL))
{
r->Flags|=2;
size_t Size=CmtData.Size()+1;
r->CmtState=Size>r->CmtBufSize ? ERAR_SMALL_BUF:1;
r->CmtSize=(uint)Min(Size,r->CmtBufSize);
memcpy(r->CmtBuf,&CmtData[0],r->CmtSize-1);
if (Size<=r->CmtBufSize)
r->CmtBuf[r->CmtSize-1]=0;
}
else
r->CmtState=r->CmtSize=0;
if (Data->Arc.Signed)
r->Flags|=0x20;
Data->Extract.ExtractArchiveInit(&Data->Cmd,Data->Arc);
return((HANDLE)Data);
}
catch (int ErrCode)
{
r->OpenResult=RarErrorToDll(ErrCode);
return(NULL);
}
}
int PASCAL RARCloseArchive(HANDLE hArcData)
{
DataSet *Data=(DataSet *)hArcData;
bool Success=Data==NULL ? false:Data->Arc.Close();
delete Data;
return(Success ? 0:ERAR_ECLOSE);
}
int PASCAL RARReadHeader(HANDLE hArcData,struct RARHeaderData *D)
{
DataSet *Data=(DataSet *)hArcData;
try
{
if ((Data->HeaderSize=(int)Data->Arc.SearchBlock(FILE_HEAD))<=0)
{
if (Data->Arc.Volume && Data->Arc.GetHeaderType()==ENDARC_HEAD &&
(Data->Arc.EndArcHead.Flags & EARC_NEXT_VOLUME))
if (MergeArchive(Data->Arc,NULL,false,'L'))
{
Data->Extract.SignatureFound=false;
Data->Arc.Seek(Data->Arc.CurBlockPos,SEEK_SET);
return(RARReadHeader(hArcData,D));
}
else
return(ERAR_EOPEN);
return(Data->Arc.BrokenFileHeader ? ERAR_BAD_DATA:ERAR_END_ARCHIVE);
}
if (Data->OpenMode==RAR_OM_LIST && (Data->Arc.NewLhd.Flags & LHD_SPLIT_BEFORE))
{
int Code=RARProcessFile(hArcData,RAR_SKIP,NULL,NULL);
if (Code==0)
return(RARReadHeader(hArcData,D));
else
return(Code);
}
strncpyz(D->ArcName,Data->Arc.FileName,ASIZE(D->ArcName));
strncpyz(D->FileName,Data->Arc.NewLhd.FileName,ASIZE(D->FileName));
D->Flags=Data->Arc.NewLhd.Flags;
D->PackSize=Data->Arc.NewLhd.PackSize;
D->UnpSize=Data->Arc.NewLhd.UnpSize;
D->HostOS=Data->Arc.NewLhd.HostOS;
D->FileCRC=Data->Arc.NewLhd.FileCRC;
D->FileTime=Data->Arc.NewLhd.FileTime;
D->UnpVer=Data->Arc.NewLhd.UnpVer;
D->Method=Data->Arc.NewLhd.Method;
D->FileAttr=Data->Arc.NewLhd.FileAttr;
D->CmtSize=0;
D->CmtState=0;
}
catch (int ErrCode)
{
return(RarErrorToDll(ErrCode));
}
return(0);
}
int PASCAL RARReadHeaderEx(HANDLE hArcData,struct RARHeaderDataEx *D)
{
DataSet *Data=(DataSet *)hArcData;
try
{
if ((Data->HeaderSize=(int)Data->Arc.SearchBlock(FILE_HEAD))<=0)
{
if (Data->Arc.Volume && Data->Arc.GetHeaderType()==ENDARC_HEAD &&
(Data->Arc.EndArcHead.Flags & EARC_NEXT_VOLUME))
if (MergeArchive(Data->Arc,NULL,false,'L'))
{
Data->Extract.SignatureFound=false;
Data->Arc.Seek(Data->Arc.CurBlockPos,SEEK_SET);
return(RARReadHeaderEx(hArcData,D));
}
else
return(ERAR_EOPEN);
return(Data->Arc.BrokenFileHeader ? ERAR_BAD_DATA:ERAR_END_ARCHIVE);
}
if (Data->OpenMode==RAR_OM_LIST && (Data->Arc.NewLhd.Flags & LHD_SPLIT_BEFORE))
{
int Code=RARProcessFile(hArcData,RAR_SKIP,NULL,NULL);
if (Code==0)
return(RARReadHeaderEx(hArcData,D));
else
return(Code);
}
strncpyz(D->ArcName,Data->Arc.FileName,ASIZE(D->ArcName));
if (*Data->Arc.FileNameW)
strncpyw(D->ArcNameW,Data->Arc.FileNameW,sizeof(D->ArcNameW));
else
CharToWide(Data->Arc.FileName,D->ArcNameW);
strncpyz(D->FileName,Data->Arc.NewLhd.FileName,ASIZE(D->FileName));
if (*Data->Arc.NewLhd.FileNameW)
strncpyw(D->FileNameW,Data->Arc.NewLhd.FileNameW,sizeof(D->FileNameW));
else
{
#ifdef _WIN_32
char AnsiName[NM];
OemToChar(Data->Arc.NewLhd.FileName,AnsiName);
CharToWide(AnsiName,D->FileNameW);
#else
CharToWide(Data->Arc.NewLhd.FileName,D->FileNameW);
#endif
}
D->Flags=Data->Arc.NewLhd.Flags;
D->PackSize=Data->Arc.NewLhd.PackSize;
D->PackSizeHigh=Data->Arc.NewLhd.HighPackSize;
D->UnpSize=Data->Arc.NewLhd.UnpSize;
D->UnpSizeHigh=Data->Arc.NewLhd.HighUnpSize;
D->HostOS=Data->Arc.NewLhd.HostOS;
D->FileCRC=Data->Arc.NewLhd.FileCRC;
D->FileTime=Data->Arc.NewLhd.FileTime;
D->UnpVer=Data->Arc.NewLhd.UnpVer;
D->Method=Data->Arc.NewLhd.Method;
D->FileAttr=Data->Arc.NewLhd.FileAttr;
D->CmtSize=0;
D->CmtState=0;
}
catch (int ErrCode)
{
return(RarErrorToDll(ErrCode));
}
return(0);
}
int PASCAL ProcessFile(HANDLE hArcData,int Operation,char *DestPath,char *DestName,wchar *DestPathW,wchar *DestNameW)
{
DataSet *Data=(DataSet *)hArcData;
try
{
Data->Cmd.DllError=0;
if (Data->OpenMode==RAR_OM_LIST || Data->OpenMode==RAR_OM_LIST_INCSPLIT ||
Operation==RAR_SKIP && !Data->Arc.Solid)
{
if (Data->Arc.Volume &&
Data->Arc.GetHeaderType()==FILE_HEAD &&
(Data->Arc.NewLhd.Flags & LHD_SPLIT_AFTER)!=0)
if (MergeArchive(Data->Arc,NULL,false,'L'))
{
Data->Extract.SignatureFound=false;
Data->Arc.Seek(Data->Arc.CurBlockPos,SEEK_SET);
return(0);
}
else
return(ERAR_EOPEN);
Data->Arc.SeekToNext();
}
else
{
Data->Cmd.DllOpMode=Operation;
if (DestPath!=NULL || DestName!=NULL)
{
#ifdef _WIN_32
OemToChar(NullToEmpty(DestPath),Data->Cmd.ExtrPath);
#else
strcpy(Data->Cmd.ExtrPath,NullToEmpty(DestPath));
#endif
AddEndSlash(Data->Cmd.ExtrPath);
#ifdef _WIN_32
OemToChar(NullToEmpty(DestName),Data->Cmd.DllDestName);
#else
strcpy(Data->Cmd.DllDestName,NullToEmpty(DestName));
#endif
}
else
{
*Data->Cmd.ExtrPath=0;
*Data->Cmd.DllDestName=0;
}
if (DestPathW!=NULL || DestNameW!=NULL)
{
strncpyw(Data->Cmd.ExtrPathW,NullToEmpty(DestPathW),NM-2);
AddEndSlash(Data->Cmd.ExtrPathW);
strncpyw(Data->Cmd.DllDestNameW,NullToEmpty(DestNameW),NM-1);
if (*Data->Cmd.DllDestNameW!=0 && *Data->Cmd.DllDestName==0)
WideToChar(Data->Cmd.DllDestNameW,Data->Cmd.DllDestName);
}
else
{
*Data->Cmd.ExtrPathW=0;
*Data->Cmd.DllDestNameW=0;
}
strcpy(Data->Cmd.Command,Operation==RAR_EXTRACT ? "X":"T");
Data->Cmd.Test=Operation!=RAR_EXTRACT;
bool Repeat=false;
Data->Extract.ExtractCurrentFile(&Data->Cmd,Data->Arc,Data->HeaderSize,Repeat);
while (Data->Arc.ReadHeader()!=0 && Data->Arc.GetHeaderType()==NEWSUB_HEAD)
{
Data->Extract.ExtractCurrentFile(&Data->Cmd,Data->Arc,Data->HeaderSize,Repeat);
Data->Arc.SeekToNext();
}
Data->Arc.Seek(Data->Arc.CurBlockPos,SEEK_SET);
}
}
catch (int ErrCode)
{
return(RarErrorToDll(ErrCode));
}
return(Data->Cmd.DllError);
}
int PASCAL RARProcessFile(HANDLE hArcData,int Operation,char *DestPath,char *DestName)
{
return(ProcessFile(hArcData,Operation,DestPath,DestName,NULL,NULL));
}
int PASCAL RARProcessFileW(HANDLE hArcData,int Operation,wchar *DestPath,wchar *DestName)
{
return(ProcessFile(hArcData,Operation,NULL,NULL,DestPath,DestName));
}
void PASCAL RARSetChangeVolProc(HANDLE hArcData,CHANGEVOLPROC ChangeVolProc)
{
DataSet *Data=(DataSet *)hArcData;
Data->Cmd.ChangeVolProc=ChangeVolProc;
}
void PASCAL RARSetCallback(HANDLE hArcData,UNRARCALLBACK Callback,LPARAM UserData)
{
DataSet *Data=(DataSet *)hArcData;
Data->Cmd.Callback=Callback;
Data->Cmd.UserData=UserData;
}
void PASCAL RARSetProcessDataProc(HANDLE hArcData,PROCESSDATAPROC ProcessDataProc)
{
DataSet *Data=(DataSet *)hArcData;
Data->Cmd.ProcessDataProc=ProcessDataProc;
}
#ifndef NOCRYPT
void PASCAL RARSetPassword(HANDLE hArcData,char *Password)
{
DataSet *Data=(DataSet *)hArcData;
strncpyz(Data->Cmd.Password,Password,ASIZE(Data->Cmd.Password));
}
#endif
int PASCAL RARGetDllVersion()
{
return(RAR_DLL_VERSION);
}
static int RarErrorToDll(int ErrCode)
{
switch(ErrCode)
{
case FATAL_ERROR:
return(ERAR_EREAD);
case CRC_ERROR:
return(ERAR_BAD_DATA);
case WRITE_ERROR:
return(ERAR_EWRITE);
case OPEN_ERROR:
return(ERAR_EOPEN);
case CREATE_ERROR:
return(ERAR_ECREATE);
case MEMORY_ERROR:
return(ERAR_NO_MEMORY);
case SUCCESS:
return(0);
default:
return(ERAR_UNKNOWN);
}
}

12
libunrar/dll.def Normal file
View File

@ -0,0 +1,12 @@
EXPORTS
RAROpenArchive
RAROpenArchiveEx
RARCloseArchive
RARReadHeader
RARReadHeaderEx
RARProcessFile
RARSetCallback
RARSetChangeVolProc
RARSetProcessDataProc
RARSetPassword
RARGetDllVersion

140
libunrar/dll.hpp Normal file
View File

@ -0,0 +1,140 @@
#ifndef _UNRAR_DLL_
#define _UNRAR_DLL_
#define ERAR_END_ARCHIVE 10
#define ERAR_NO_MEMORY 11
#define ERAR_BAD_DATA 12
#define ERAR_BAD_ARCHIVE 13
#define ERAR_UNKNOWN_FORMAT 14
#define ERAR_EOPEN 15
#define ERAR_ECREATE 16
#define ERAR_ECLOSE 17
#define ERAR_EREAD 18
#define ERAR_EWRITE 19
#define ERAR_SMALL_BUF 20
#define ERAR_UNKNOWN 21
#define ERAR_MISSING_PASSWORD 22
#define RAR_OM_LIST 0
#define RAR_OM_EXTRACT 1
#define RAR_OM_LIST_INCSPLIT 2
#define RAR_SKIP 0
#define RAR_TEST 1
#define RAR_EXTRACT 2
#define RAR_VOL_ASK 0
#define RAR_VOL_NOTIFY 1
#define RAR_DLL_VERSION 4
#ifdef _UNIX
#define CALLBACK
#define PASCAL
#define LONG long
#define HANDLE void *
#define LPARAM long
#define UINT unsigned int
#endif
struct RARHeaderData
{
char ArcName[260];
char FileName[260];
unsigned int Flags;
unsigned int PackSize;
unsigned int UnpSize;
unsigned int HostOS;
unsigned int FileCRC;
unsigned int FileTime;
unsigned int UnpVer;
unsigned int Method;
unsigned int FileAttr;
char *CmtBuf;
unsigned int CmtBufSize;
unsigned int CmtSize;
unsigned int CmtState;
};
struct RARHeaderDataEx
{
char ArcName[1024];
wchar_t ArcNameW[1024];
char FileName[1024];
wchar_t FileNameW[1024];
unsigned int Flags;
unsigned int PackSize;
unsigned int PackSizeHigh;
unsigned int UnpSize;
unsigned int UnpSizeHigh;
unsigned int HostOS;
unsigned int FileCRC;
unsigned int FileTime;
unsigned int UnpVer;
unsigned int Method;
unsigned int FileAttr;
char *CmtBuf;
unsigned int CmtBufSize;
unsigned int CmtSize;
unsigned int CmtState;
unsigned int Reserved[1024];
};
struct RAROpenArchiveData
{
char *ArcName;
unsigned int OpenMode;
unsigned int OpenResult;
char *CmtBuf;
unsigned int CmtBufSize;
unsigned int CmtSize;
unsigned int CmtState;
};
struct RAROpenArchiveDataEx
{
char *ArcName;
wchar_t *ArcNameW;
unsigned int OpenMode;
unsigned int OpenResult;
char *CmtBuf;
unsigned int CmtBufSize;
unsigned int CmtSize;
unsigned int CmtState;
unsigned int Flags;
unsigned int Reserved[32];
};
enum UNRARCALLBACK_MESSAGES {
UCM_CHANGEVOLUME,UCM_PROCESSDATA,UCM_NEEDPASSWORD
};
typedef int (CALLBACK *UNRARCALLBACK)(UINT msg,LPARAM UserData,LPARAM P1,LPARAM P2);
typedef int (PASCAL *CHANGEVOLPROC)(char *ArcName,int Mode);
typedef int (PASCAL *PROCESSDATAPROC)(unsigned char *Addr,int Size);
#ifdef __cplusplus
extern "C" {
#endif
HANDLE PASCAL RAROpenArchive(struct RAROpenArchiveData *ArchiveData);
HANDLE PASCAL RAROpenArchiveEx(struct RAROpenArchiveDataEx *ArchiveData);
int PASCAL RARCloseArchive(HANDLE hArcData);
int PASCAL RARReadHeader(HANDLE hArcData,struct RARHeaderData *HeaderData);
int PASCAL RARReadHeaderEx(HANDLE hArcData,struct RARHeaderDataEx *HeaderData);
int PASCAL RARProcessFile(HANDLE hArcData,int Operation,char *DestPath,char *DestName);
int PASCAL RARProcessFileW(HANDLE hArcData,int Operation,wchar_t *DestPath,wchar_t *DestName);
void PASCAL RARSetCallback(HANDLE hArcData,UNRARCALLBACK Callback,LPARAM UserData);
void PASCAL RARSetChangeVolProc(HANDLE hArcData,CHANGEVOLPROC ChangeVolProc);
void PASCAL RARSetProcessDataProc(HANDLE hArcData,PROCESSDATAPROC ProcessDataProc);
void PASCAL RARSetPassword(HANDLE hArcData,char *Password);
int PASCAL RARGetDllVersion();
#ifdef __cplusplus
}
#endif
#endif

57
libunrar/encname.cpp Normal file
View File

@ -0,0 +1,57 @@
#include "rar.hpp"
EncodeFileName::EncodeFileName()
{
Flags=0;
FlagBits=0;
FlagsPos=0;
DestSize=0;
}
void EncodeFileName::Decode(char *Name,byte *EncName,size_t EncSize,wchar *NameW,
size_t MaxDecSize)
{
size_t EncPos=0,DecPos=0;
byte HighByte=EncName[EncPos++];
while (EncPos<EncSize && DecPos<MaxDecSize)
{
if (FlagBits==0)
{
Flags=EncName[EncPos++];
FlagBits=8;
}
switch(Flags>>6)
{
case 0:
NameW[DecPos++]=EncName[EncPos++];
break;
case 1:
NameW[DecPos++]=EncName[EncPos++]+(HighByte<<8);
break;
case 2:
NameW[DecPos++]=EncName[EncPos]+(EncName[EncPos+1]<<8);
EncPos+=2;
break;
case 3:
{
int Length=EncName[EncPos++];
if (Length & 0x80)
{
byte Correction=EncName[EncPos++];
for (Length=(Length&0x7f)+2;Length>0 && DecPos<MaxDecSize;Length--,DecPos++)
NameW[DecPos]=((Name[DecPos]+Correction)&0xff)+(HighByte<<8);
}
else
for (Length+=2;Length>0 && DecPos<MaxDecSize;Length--,DecPos++)
NameW[DecPos]=Name[DecPos];
}
break;
}
Flags<<=2;
FlagBits-=2;
}
NameW[DecPos<MaxDecSize ? DecPos:MaxDecSize-1]=0;
}

20
libunrar/encname.hpp Normal file
View File

@ -0,0 +1,20 @@
#ifndef _RAR_ENCNAME_
#define _RAR_ENCNAME_
class EncodeFileName
{
private:
void AddFlags(int Value);
byte *EncName;
byte Flags;
uint FlagBits;
size_t FlagsPos;
size_t DestSize;
public:
EncodeFileName();
size_t Encode(char *Name,wchar *NameW,byte *EncName);
void Decode(char *Name,byte *EncName,size_t EncSize,wchar *NameW,size_t MaxDecSize);
};
#endif

377
libunrar/errhnd.cpp Normal file
View File

@ -0,0 +1,377 @@
#include "rar.hpp"
static bool UserBreak;
ErrorHandler::ErrorHandler()
{
Clean();
}
void ErrorHandler::Clean()
{
ExitCode=SUCCESS;
ErrCount=0;
EnableBreak=true;
Silent=false;
DoShutdown=false;
}
void ErrorHandler::MemoryError()
{
MemoryErrorMsg();
Throw(MEMORY_ERROR);
}
void ErrorHandler::OpenError(const char *FileName)
{
#ifndef SILENT
OpenErrorMsg(FileName);
Throw(OPEN_ERROR);
#endif
}
void ErrorHandler::CloseError(const char *FileName)
{
#ifndef SILENT
if (!UserBreak)
{
ErrMsg(NULL,St(MErrFClose),FileName);
SysErrMsg();
}
#endif
#if !defined(SILENT) || defined(RARDLL)
Throw(FATAL_ERROR);
#endif
}
void ErrorHandler::ReadError(const char *FileName)
{
#ifndef SILENT
ReadErrorMsg(NULL,FileName);
#endif
#if !defined(SILENT) || defined(RARDLL)
Throw(FATAL_ERROR);
#endif
}
bool ErrorHandler::AskRepeatRead(const char *FileName)
{
#if !defined(SILENT) && !defined(SFX_MODULE) && !defined(_WIN_CE)
if (!Silent)
{
SysErrMsg();
mprintf("\n");
Log(NULL,St(MErrRead),FileName);
return(Ask(St(MRetryAbort))==1);
}
#endif
return(false);
}
void ErrorHandler::WriteError(const char *ArcName,const char *FileName)
{
#ifndef SILENT
WriteErrorMsg(ArcName,FileName);
#endif
#if !defined(SILENT) || defined(RARDLL)
Throw(WRITE_ERROR);
#endif
}
#ifdef _WIN_32
void ErrorHandler::WriteErrorFAT(const char *FileName)
{
#if !defined(SILENT) && !defined(SFX_MODULE)
SysErrMsg();
ErrMsg(NULL,St(MNTFSRequired),FileName);
#endif
#if !defined(SILENT) && !defined(SFX_MODULE) || defined(RARDLL)
Throw(WRITE_ERROR);
#endif
}
#endif
bool ErrorHandler::AskRepeatWrite(const char *FileName,bool DiskFull)
{
#if !defined(SILENT) && !defined(_WIN_CE)
if (!Silent)
{
SysErrMsg();
mprintf("\n");
Log(NULL,St(DiskFull ? MNotEnoughDisk:MErrWrite),FileName);
return(Ask(St(MRetryAbort))==1);
}
#endif
return(false);
}
void ErrorHandler::SeekError(const char *FileName)
{
#ifndef SILENT
if (!UserBreak)
{
ErrMsg(NULL,St(MErrSeek),FileName);
SysErrMsg();
}
#endif
#if !defined(SILENT) || defined(RARDLL)
Throw(FATAL_ERROR);
#endif
}
void ErrorHandler::GeneralErrMsg(const char *Msg)
{
#ifndef SILENT
Log(NULL,"%s",Msg);
SysErrMsg();
#endif
}
void ErrorHandler::MemoryErrorMsg()
{
#ifndef SILENT
ErrMsg(NULL,St(MErrOutMem));
#endif
}
void ErrorHandler::OpenErrorMsg(const char *FileName)
{
OpenErrorMsg(NULL,FileName);
}
void ErrorHandler::OpenErrorMsg(const char *ArcName,const char *FileName)
{
#ifndef SILENT
Log(ArcName && *ArcName ? ArcName:NULL,St(MCannotOpen),FileName);
Alarm();
SysErrMsg();
#endif
}
void ErrorHandler::CreateErrorMsg(const char *FileName)
{
CreateErrorMsg(NULL,FileName);
}
void ErrorHandler::CreateErrorMsg(const char *ArcName,const char *FileName)
{
#ifndef SILENT
Log(ArcName && *ArcName ? ArcName:NULL,St(MCannotCreate),FileName);
Alarm();
#if defined(_WIN_32) && !defined(_WIN_CE) && !defined(SFX_MODULE) && defined(MAX_PATH)
if (GetLastError()==ERROR_PATH_NOT_FOUND)
{
size_t NameLength=strlen(FileName);
if (!IsFullPath(FileName))
{
char CurDir[NM];
GetCurrentDirectory(sizeof(CurDir),CurDir);
NameLength+=strlen(CurDir)+1;
}
if (NameLength>MAX_PATH)
{
Log(ArcName && *ArcName ? ArcName:NULL,St(MMaxPathLimit),MAX_PATH);
}
}
#endif
SysErrMsg();
#endif
}
void ErrorHandler::ReadErrorMsg(const char *ArcName,const char *FileName)
{
#ifndef SILENT
ErrMsg(ArcName,St(MErrRead),FileName);
SysErrMsg();
#endif
}
void ErrorHandler::WriteErrorMsg(const char *ArcName,const char *FileName)
{
#ifndef SILENT
ErrMsg(ArcName,St(MErrWrite),FileName);
SysErrMsg();
#endif
}
void ErrorHandler::Exit(int ExitCode)
{
#ifndef SFX_MODULE
Alarm();
#endif
Throw(ExitCode);
}
#ifndef GUI
void ErrorHandler::ErrMsg(const char *ArcName,const char *fmt,...)
{
safebuf char Msg[NM+1024];
va_list argptr;
va_start(argptr,fmt);
vsprintf(Msg,fmt,argptr);
va_end(argptr);
#ifdef _WIN_32
if (UserBreak)
Sleep(5000);
#endif
Alarm();
if (*Msg)
{
Log(ArcName,"\n%s",Msg);
mprintf("\n%s\n",St(MProgAborted));
}
}
#endif
void ErrorHandler::SetErrorCode(int Code)
{
switch(Code)
{
case WARNING:
case USER_BREAK:
if (ExitCode==SUCCESS)
ExitCode=Code;
break;
case FATAL_ERROR:
if (ExitCode==SUCCESS || ExitCode==WARNING)
ExitCode=FATAL_ERROR;
break;
default:
ExitCode=Code;
break;
}
ErrCount++;
}
#if !defined(GUI) && !defined(_SFX_RTL_)
#ifdef _WIN_32
BOOL __stdcall ProcessSignal(DWORD SigType)
#else
#if defined(__sun)
extern "C"
#endif
void _stdfunction ProcessSignal(int SigType)
#endif
{
#ifdef _WIN_32
if (SigType==CTRL_LOGOFF_EVENT)
return(TRUE);
#endif
UserBreak=true;
mprintf(St(MBreak));
for (int I=0;!File::RemoveCreated() && I<3;I++)
{
#ifdef _WIN_32
Sleep(100);
#endif
}
#if defined(USE_RC) && !defined(SFX_MODULE) && !defined(_WIN_CE)
ExtRes.UnloadDLL();
#endif
exit(USER_BREAK);
#if defined(_WIN_32) && !defined(_MSC_VER)
// never reached, just to avoid a compiler warning
return(TRUE);
#endif
}
#endif
void ErrorHandler::SetSignalHandlers(bool Enable)
{
EnableBreak=Enable;
#if !defined(GUI) && !defined(_SFX_RTL_)
#ifdef _WIN_32
SetConsoleCtrlHandler(Enable ? ProcessSignal:NULL,TRUE);
// signal(SIGBREAK,Enable ? ProcessSignal:SIG_IGN);
#else
signal(SIGINT,Enable ? ProcessSignal:SIG_IGN);
signal(SIGTERM,Enable ? ProcessSignal:SIG_IGN);
#endif
#endif
}
void ErrorHandler::Throw(int Code)
{
if (Code==USER_BREAK && !EnableBreak)
return;
ErrHandler.SetErrorCode(Code);
#ifdef ALLOW_EXCEPTIONS
throw Code;
#else
File::RemoveCreated();
exit(Code);
#endif
}
void ErrorHandler::SysErrMsg()
{
#if !defined(SFX_MODULE) && !defined(SILENT)
#ifdef _WIN_32
#define STRCHR strchr
#define ERRCHAR char
ERRCHAR *lpMsgBuf=NULL;
int ErrType=GetLastError();
if (ErrType!=0 && FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
NULL,ErrType,MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)&lpMsgBuf,0,NULL))
{
ERRCHAR *CurMsg=lpMsgBuf;
while (CurMsg!=NULL)
{
while (*CurMsg=='\r' || *CurMsg=='\n')
CurMsg++;
if (*CurMsg==0)
break;
ERRCHAR *EndMsg=STRCHR(CurMsg,'\r');
if (EndMsg==NULL)
EndMsg=STRCHR(CurMsg,'\n');
if (EndMsg!=NULL)
{
*EndMsg=0;
EndMsg++;
}
Log(NULL,"\n%s",CurMsg);
CurMsg=EndMsg;
}
}
LocalFree( lpMsgBuf );
#endif
#if defined(_UNIX) || defined(_EMX)
char *err=strerror(errno);
if (err!=NULL)
Log(NULL,"\n%s",err);
#endif
#endif
}

63
libunrar/errhnd.hpp Normal file
View File

@ -0,0 +1,63 @@
#ifndef _RAR_ERRHANDLER_
#define _RAR_ERRHANDLER_
#if (defined(GUI) || !defined(_WIN_32)) && !defined(SFX_MODULE) && !defined(_WIN_CE) || defined(RARDLL)
#define ALLOW_EXCEPTIONS
#endif
#define rarmalloc malloc
#define rarcalloc calloc
#define rarrealloc realloc
#define rarfree free
#define rarstrdup strdup
#define rarstrdupw strdupw
enum { SUCCESS,WARNING,FATAL_ERROR,CRC_ERROR,LOCK_ERROR,WRITE_ERROR,
OPEN_ERROR,USER_ERROR,MEMORY_ERROR,CREATE_ERROR,USER_BREAK=255};
class ErrorHandler
{
private:
void ErrMsg(const char *ArcName,const char *fmt,...);
int ExitCode;
int ErrCount;
bool EnableBreak;
bool Silent;
bool DoShutdown;
public:
ErrorHandler();
void Clean();
void MemoryError();
void OpenError(const char *FileName);
void CloseError(const char *FileName);
void ReadError(const char *FileName);
bool AskRepeatRead(const char *FileName);
void WriteError(const char *ArcName,const char *FileName);
void WriteErrorFAT(const char *FileName);
bool AskRepeatWrite(const char *FileName,bool DiskFull);
void SeekError(const char *FileName);
void GeneralErrMsg(const char *Msg);
void MemoryErrorMsg();
void OpenErrorMsg(const char *FileName);
void OpenErrorMsg(const char *ArcName,const char *FileName);
void CreateErrorMsg(const char *FileName);
void CreateErrorMsg(const char *ArcName,const char *FileName);
void ReadErrorMsg(const char *ArcName,const char *FileName);
void WriteErrorMsg(const char *ArcName,const char *FileName);
void Exit(int ExitCode);
void SetErrorCode(int Code);
int GetErrorCode() {return(ExitCode);}
int GetErrorCount() {return(ErrCount);}
void SetSignalHandlers(bool Enable);
void Throw(int Code);
void SetSilent(bool Mode) {Silent=Mode;};
void SetShutdown(bool Mode) {DoShutdown=Mode;};
void SysErrMsg();
};
#endif

76
libunrar/extinfo.cpp Normal file
View File

@ -0,0 +1,76 @@
#include "rar.hpp"
#ifdef _WIN_32
#include "win32acl.cpp"
#include "win32stm.cpp"
#endif
#ifdef _BEOS
#include "beosea.cpp"
#endif
#if defined(_EMX) && !defined(_DJGPP)
#include "os2ea.cpp"
#endif
#ifdef _UNIX
#include "uowners.cpp"
#endif
#ifndef SFX_MODULE
void SetExtraInfo(CommandData *Cmd,Archive &Arc,char *Name,wchar *NameW)
{
switch(Arc.SubBlockHead.SubType)
{
#if defined(_EMX) && !defined(_DJGPP)
case EA_HEAD:
if (Cmd->ProcessEA)
ExtractOS2EA(Arc,Name);
break;
#endif
#ifdef _UNIX
case UO_HEAD:
if (Cmd->ProcessOwners)
ExtractUnixOwner(Arc,Name);
break;
#endif
#ifdef _BEOS
case BEEA_HEAD:
if (Cmd->ProcessEA)
ExtractBeEA(Arc,Name);
break;
#endif
#ifdef _WIN_32
case NTACL_HEAD:
if (Cmd->ProcessOwners)
ExtractACL(Arc,Name,NameW);
break;
case STREAM_HEAD:
ExtractStreams(Arc,Name,NameW);
break;
#endif
}
}
#endif
void SetExtraInfoNew(CommandData *Cmd,Archive &Arc,char *Name,wchar *NameW)
{
#if defined(_EMX) && !defined(_DJGPP)
if (Cmd->ProcessEA && Arc.SubHead.CmpName(SUBHEAD_TYPE_OS2EA))
ExtractOS2EANew(Arc,Name);
#endif
#ifdef _UNIX
if (Cmd->ProcessOwners && Arc.SubHead.CmpName(SUBHEAD_TYPE_UOWNER))
ExtractUnixOwnerNew(Arc,Name);
#endif
#ifdef _BEOS
if (Cmd->ProcessEA && Arc.SubHead.CmpName(SUBHEAD_TYPE_UOWNER))
ExtractUnixOwnerNew(Arc,Name);
#endif
#ifdef _WIN_32
if (Cmd->ProcessOwners && Arc.SubHead.CmpName(SUBHEAD_TYPE_ACL))
ExtractACLNew(Arc,Name,NameW);
if (Arc.SubHead.CmpName(SUBHEAD_TYPE_STREAM))
ExtractStreamsNew(Arc,Name,NameW);
#endif
}

8
libunrar/extinfo.hpp Normal file
View File

@ -0,0 +1,8 @@
#ifndef _RAR_EXTINFO_
#define _RAR_EXTINFO_
void SetExtraInfo(CommandData *Cmd,Archive &Arc,char *Name,wchar *NameW);
void SetExtraInfoNew(CommandData *Cmd,Archive &Arc,char *Name,wchar *NameW);
#endif

928
libunrar/extract.cpp Normal file
View File

@ -0,0 +1,928 @@
#include "rar.hpp"
CmdExtract::CmdExtract()
{
TotalFileCount=0;
*Password=0;
Unp=new Unpack(&DataIO);
Unp->Init(NULL);
}
CmdExtract::~CmdExtract()
{
delete Unp;
memset(Password,0,sizeof(Password));
}
void CmdExtract::DoExtract(CommandData *Cmd)
{
PasswordCancelled=false;
DataIO.SetCurrentCommand(*Cmd->Command);
struct FindData FD;
while (Cmd->GetArcName(ArcName,ArcNameW,sizeof(ArcName)))
if (FindFile::FastFind(ArcName,ArcNameW,&FD))
DataIO.TotalArcSize+=FD.Size;
Cmd->ArcNames->Rewind();
while (Cmd->GetArcName(ArcName,ArcNameW,sizeof(ArcName)))
{
while (true)
{
char PrevCmdPassword[MAXPASSWORD];
strcpy(PrevCmdPassword,Cmd->Password);
EXTRACT_ARC_CODE Code=ExtractArchive(Cmd);
// Restore Cmd->Password, which could be changed in IsArchive() call
// for next header encrypted archive.
strcpy(Cmd->Password,PrevCmdPassword);
if (Code!=EXTRACT_ARC_REPEAT)
break;
}
if (FindFile::FastFind(ArcName,ArcNameW,&FD))
DataIO.ProcessedArcSize+=FD.Size;
}
if (TotalFileCount==0 && *Cmd->Command!='I')
{
if (!PasswordCancelled)
{
mprintf(St(MExtrNoFiles));
}
ErrHandler.SetErrorCode(WARNING);
}
#ifndef GUI
else
if (!Cmd->DisableDone)
if (*Cmd->Command=='I')
mprintf(St(MDone));
else
if (ErrHandler.GetErrorCount()==0)
mprintf(St(MExtrAllOk));
else
mprintf(St(MExtrTotalErr),ErrHandler.GetErrorCount());
#endif
}
void CmdExtract::ExtractArchiveInit(CommandData *Cmd,Archive &Arc)
{
DataIO.UnpArcSize=Arc.FileLength();
FileCount=0;
MatchedArgs=0;
#ifndef SFX_MODULE
FirstFile=true;
#endif
if (*Cmd->Password!=0)
strcpy(Password,Cmd->Password);
PasswordAll=(*Cmd->Password!=0);
DataIO.UnpVolume=false;
PrevExtracted=false;
SignatureFound=false;
AllMatchesExact=true;
ReconstructDone=false;
StartTime.SetCurrentTime();
}
EXTRACT_ARC_CODE CmdExtract::ExtractArchive(CommandData *Cmd)
{
Archive Arc(Cmd);
if (!Arc.WOpen(ArcName,ArcNameW))
{
ErrHandler.SetErrorCode(OPEN_ERROR);
return(EXTRACT_ARC_NEXT);
}
if (!Arc.IsArchive(true))
{
#ifndef GUI
mprintf(St(MNotRAR),ArcName);
#endif
if (CmpExt(ArcName,"rar"))
ErrHandler.SetErrorCode(WARNING);
return(EXTRACT_ARC_NEXT);
}
// archive with corrupt encrypted header can be closed in IsArchive() call
if (!Arc.IsOpened())
return(EXTRACT_ARC_NEXT);
#ifndef SFX_MODULE
if (Arc.Volume && Arc.NotFirstVolume)
{
char FirstVolName[NM];
VolNameToFirstName(ArcName,FirstVolName,(Arc.NewMhd.Flags & MHD_NEWNUMBERING)!=0);
// If several volume names from same volume set are specified
// and current volume is not first in set and first volume is present
// and specified too, let's skip the current volume.
if (stricomp(ArcName,FirstVolName)!=0 && FileExist(FirstVolName) &&
Cmd->ArcNames->Search(FirstVolName,NULL,false))
return(EXTRACT_ARC_NEXT);
}
#endif
int64 VolumeSetSize=0; // Total size of volumes after the current volume.
if (Arc.Volume)
{
// Calculate the total size of all accessible volumes.
// This size is necessary to display the correct total progress indicator.
char NextName[NM];
wchar NextNameW[NM];
strcpy(NextName,Arc.FileName);
strcpyw(NextNameW,Arc.FileNameW);
while (true)
{
// First volume is already added to DataIO.TotalArcSize
// in initial TotalArcSize calculation in DoExtract.
// So we skip it and start from second volume.
NextVolumeName(NextName,NextNameW,ASIZE(NextName),(Arc.NewMhd.Flags & MHD_NEWNUMBERING)==0 || Arc.OldFormat);
struct FindData FD;
if (FindFile::FastFind(NextName,NextNameW,&FD))
VolumeSetSize+=FD.Size;
else
break;
}
DataIO.TotalArcSize+=VolumeSetSize;
}
ExtractArchiveInit(Cmd,Arc);
if (*Cmd->Command=='T' || *Cmd->Command=='I')
Cmd->Test=true;
#ifndef GUI
if (*Cmd->Command=='I')
Cmd->DisablePercentage=true;
else
if (Cmd->Test)
mprintf(St(MExtrTest),ArcName);
else
mprintf(St(MExtracting),ArcName);
#endif
Arc.ViewComment();
// RAR can close a corrupt encrypted archive
if (!Arc.IsOpened())
return(EXTRACT_ARC_NEXT);
while (1)
{
size_t Size=Arc.ReadHeader();
bool Repeat=false;
if (!ExtractCurrentFile(Cmd,Arc,Size,Repeat))
if (Repeat)
{
// If we started extraction from not first volume and need to
// restart it from first, we must correct DataIO.TotalArcSize
// for correct total progress display. We subtract the size
// of current volume and all volumes after it and add the size
// of new (first) volume.
struct FindData OldArc,NewArc;
if (FindFile::FastFind(Arc.FileName,Arc.FileNameW,&OldArc) &&
FindFile::FastFind(ArcName,ArcNameW,&NewArc))
DataIO.TotalArcSize-=VolumeSetSize+OldArc.Size-NewArc.Size;
return(EXTRACT_ARC_REPEAT);
}
else
break;
}
return(EXTRACT_ARC_NEXT);
}
bool CmdExtract::ExtractCurrentFile(CommandData *Cmd,Archive &Arc,size_t HeaderSize,bool &Repeat)
{
char Command=*Cmd->Command;
if (HeaderSize==0)
if (DataIO.UnpVolume)
{
#ifdef NOVOLUME
return(false);
#else
if (!MergeArchive(Arc,&DataIO,false,Command))
{
ErrHandler.SetErrorCode(WARNING);
return(false);
}
SignatureFound=false;
#endif
}
else
return(false);
int HeadType=Arc.GetHeaderType();
if (HeadType!=FILE_HEAD)
{
if (HeadType==AV_HEAD || HeadType==SIGN_HEAD)
SignatureFound=true;
#if !defined(SFX_MODULE) && !defined(_WIN_CE)
if (HeadType==SUB_HEAD && PrevExtracted)
SetExtraInfo(Cmd,Arc,DestFileName,*DestFileNameW ? DestFileNameW:NULL);
#endif
if (HeadType==NEWSUB_HEAD)
{
if (Arc.SubHead.CmpName(SUBHEAD_TYPE_AV))
SignatureFound=true;
#if !defined(NOSUBBLOCKS) && !defined(_WIN_CE)
if (PrevExtracted)
SetExtraInfoNew(Cmd,Arc,DestFileName,*DestFileNameW ? DestFileNameW:NULL);
#endif
}
if (HeadType==ENDARC_HEAD)
if (Arc.EndArcHead.Flags & EARC_NEXT_VOLUME)
{
#ifndef NOVOLUME
if (!MergeArchive(Arc,&DataIO,false,Command))
{
ErrHandler.SetErrorCode(WARNING);
return(false);
}
SignatureFound=false;
#endif
Arc.Seek(Arc.CurBlockPos,SEEK_SET);
return(true);
}
else
return(false);
Arc.SeekToNext();
return(true);
}
PrevExtracted=false;
if (SignatureFound ||
!Cmd->Recurse && MatchedArgs>=Cmd->FileArgs->ItemsCount() &&
AllMatchesExact)
return(false);
char ArcFileName[NM];
IntToExt(Arc.NewLhd.FileName,Arc.NewLhd.FileName);
strcpy(ArcFileName,Arc.NewLhd.FileName);
wchar ArcFileNameW[NM];
*ArcFileNameW=0;
int MatchType=MATCH_WILDSUBPATH;
bool EqualNames=false;
int MatchNumber=Cmd->IsProcessFile(Arc.NewLhd,&EqualNames,MatchType);
bool ExactMatch=MatchNumber!=0;
#if !defined(SFX_MODULE) && !defined(_WIN_CE)
if (Cmd->ExclPath==EXCL_BASEPATH)
{
*Cmd->ArcPath=0;
if (ExactMatch)
{
Cmd->FileArgs->Rewind();
if (Cmd->FileArgs->GetString(Cmd->ArcPath,NULL,sizeof(Cmd->ArcPath),MatchNumber-1))
*PointToName(Cmd->ArcPath)=0;
}
}
#endif
if (ExactMatch && !EqualNames)
AllMatchesExact=false;
#ifdef UNICODE_SUPPORTED
bool WideName=(Arc.NewLhd.Flags & LHD_UNICODE) && UnicodeEnabled();
#else
bool WideName=false;
#endif
#ifdef _APPLE
if (WideName)
{
WideToUtf(Arc.NewLhd.FileNameW,ArcFileName,sizeof(ArcFileName));
WideName=false;
}
#endif
wchar *DestNameW=WideName ? DestFileNameW:NULL;
#ifdef UNICODE_SUPPORTED
if (WideName)
{
ConvertPath(Arc.NewLhd.FileNameW,ArcFileNameW);
char Name[NM];
if (WideToChar(ArcFileNameW,Name) && IsNameUsable(Name))
strcpy(ArcFileName,Name);
}
#endif
ConvertPath(ArcFileName,ArcFileName);
if (Arc.IsArcLabel())
return(true);
if (Arc.NewLhd.Flags & LHD_VERSION)
{
if (Cmd->VersionControl!=1 && !EqualNames)
{
if (Cmd->VersionControl==0)
ExactMatch=false;
int Version=ParseVersionFileName(ArcFileName,ArcFileNameW,false);
if (Cmd->VersionControl-1==Version)
ParseVersionFileName(ArcFileName,ArcFileNameW,true);
else
ExactMatch=false;
}
}
else
if (!Arc.IsArcDir() && Cmd->VersionControl>1)
ExactMatch=false;
Arc.ConvertAttributes();
#ifndef SFX_MODULE
if ((Arc.NewLhd.Flags & (LHD_SPLIT_BEFORE/*|LHD_SOLID*/)) && FirstFile)
{
char CurVolName[NM];
strcpy(CurVolName,ArcName);
VolNameToFirstName(ArcName,ArcName,(Arc.NewMhd.Flags & MHD_NEWNUMBERING)!=0);
if (stricomp(ArcName,CurVolName)!=0 && FileExist(ArcName))
{
*ArcNameW=0;
Repeat=true;
return(false);
}
#if !defined(RARDLL) && !defined(_WIN_CE)
if (!ReconstructDone)
{
ReconstructDone=true;
RecVolumes RecVol;
if (RecVol.Restore(Cmd,Arc.FileName,Arc.FileNameW,true))
{
Repeat=true;
return(false);
}
}
#endif
strcpy(ArcName,CurVolName);
}
#endif
DataIO.UnpVolume=(Arc.NewLhd.Flags & LHD_SPLIT_AFTER)!=0;
DataIO.NextVolumeMissing=false;
Arc.Seek(Arc.NextBlockPos-Arc.NewLhd.FullPackSize,SEEK_SET);
bool TestMode=false;
bool ExtrFile=false;
bool SkipSolid=false;
#ifndef SFX_MODULE
if (FirstFile && (ExactMatch || Arc.Solid) && (Arc.NewLhd.Flags & (LHD_SPLIT_BEFORE/*|LHD_SOLID*/))!=0)
{
if (ExactMatch)
{
Log(Arc.FileName,St(MUnpCannotMerge),ArcFileName);
#ifdef RARDLL
Cmd->DllError=ERAR_BAD_DATA;
#endif
ErrHandler.SetErrorCode(OPEN_ERROR);
}
ExactMatch=false;
}
FirstFile=false;
#endif
if (ExactMatch || (SkipSolid=Arc.Solid)!=0)
{
if ((Arc.NewLhd.Flags & LHD_PASSWORD)!=0)
#ifndef RARDLL
if (*Password==0)
#endif
{
#ifdef RARDLL
if (*Cmd->Password==0)
if (Cmd->Callback==NULL ||
Cmd->Callback(UCM_NEEDPASSWORD,Cmd->UserData,(LPARAM)Cmd->Password,sizeof(Cmd->Password))==-1)
return(false);
strcpy(Password,Cmd->Password);
#else
if (!GetPassword(PASSWORD_FILE,ArcFileName,Password,sizeof(Password)))
{
PasswordCancelled=true;
return(false);
}
#endif
}
#if !defined(GUI) && !defined(SILENT)
else
if (!PasswordAll && (!Arc.Solid || Arc.NewLhd.UnpVer>=20 && (Arc.NewLhd.Flags & LHD_SOLID)==0))
{
eprintf(St(MUseCurPsw),ArcFileName);
switch(Cmd->AllYes ? 1:Ask(St(MYesNoAll)))
{
case -1:
ErrHandler.Exit(USER_BREAK);
case 2:
if (!GetPassword(PASSWORD_FILE,ArcFileName,Password,sizeof(Password)))
{
return(false);
}
break;
case 3:
PasswordAll=true;
break;
}
}
#endif
#ifndef SFX_MODULE
if (*Cmd->ExtrPath==0 && *Cmd->ExtrPathW!=0)
WideToChar(Cmd->ExtrPathW,DestFileName);
else
#endif
strcpy(DestFileName,Cmd->ExtrPath);
#ifndef SFX_MODULE
if (Cmd->AppendArcNameToPath)
{
strcat(DestFileName,PointToName(Arc.FirstVolumeName));
SetExt(DestFileName,NULL);
AddEndSlash(DestFileName);
}
#endif
char *ExtrName=ArcFileName;
bool EmptyName=false;
#ifndef SFX_MODULE
size_t Length=strlen(Cmd->ArcPath);
if (Length>1 && IsPathDiv(Cmd->ArcPath[Length-1]) &&
strlen(ArcFileName)==Length-1)
Length--;
if (Length>0 && strnicomp(Cmd->ArcPath,ArcFileName,Length)==0)
{
ExtrName+=Length;
while (*ExtrName==CPATHDIVIDER)
ExtrName++;
if (*ExtrName==0)
EmptyName=true;
}
#endif
bool AbsPaths=Cmd->ExclPath==EXCL_ABSPATH && Command=='X' && IsDriveDiv(':');
if (AbsPaths)
*DestFileName=0;
if (Command=='E' || Cmd->ExclPath==EXCL_SKIPWHOLEPATH)
strcat(DestFileName,PointToName(ExtrName));
else
strcat(DestFileName,ExtrName);
char DiskLetter=etoupper(DestFileName[0]);
if (AbsPaths && DestFileName[1]=='_' && IsPathDiv(DestFileName[2]) &&
DiskLetter>='A' && DiskLetter<='Z')
DestFileName[1]=':';
#ifndef SFX_MODULE
if (!WideName && *Cmd->ExtrPathW!=0)
{
DestNameW=DestFileNameW;
WideName=true;
CharToWide(ArcFileName,ArcFileNameW);
}
#endif
if (WideName)
{
if (*Cmd->ExtrPathW!=0)
strcpyw(DestFileNameW,Cmd->ExtrPathW);
else
CharToWide(Cmd->ExtrPath,DestFileNameW);
#ifndef SFX_MODULE
if (Cmd->AppendArcNameToPath)
{
wchar FileNameW[NM];
if (*Arc.FirstVolumeNameW!=0)
strcpyw(FileNameW,Arc.FirstVolumeNameW);
else
CharToWide(Arc.FirstVolumeName,FileNameW);
strcatw(DestFileNameW,PointToName(FileNameW));
SetExt(DestFileNameW,NULL);
AddEndSlash(DestFileNameW);
}
#endif
wchar *ExtrNameW=ArcFileNameW;
#ifndef SFX_MODULE
if (Length>0)
{
wchar ArcPathW[NM];
GetWideName(Cmd->ArcPath,Cmd->ArcPathW,ArcPathW);
Length=strlenw(ArcPathW);
}
ExtrNameW+=Length;
while (*ExtrNameW==CPATHDIVIDER)
ExtrNameW++;
#endif
if (AbsPaths)
*DestFileNameW=0;
if (Command=='E' || Cmd->ExclPath==EXCL_SKIPWHOLEPATH)
strcatw(DestFileNameW,PointToName(ExtrNameW));
else
strcatw(DestFileNameW,ExtrNameW);
if (AbsPaths && DestFileNameW[1]=='_' && IsPathDiv(DestFileNameW[2]))
DestFileNameW[1]=':';
}
else
*DestFileNameW=0;
ExtrFile=!SkipSolid && !EmptyName && (Arc.NewLhd.Flags & LHD_SPLIT_BEFORE)==0;
if ((Cmd->FreshFiles || Cmd->UpdateFiles) && (Command=='E' || Command=='X'))
{
struct FindData FD;
if (FindFile::FastFind(DestFileName,DestNameW,&FD))
{
if (FD.mtime >= Arc.NewLhd.mtime)
{
// If directory already exists and its modification time is newer
// than start of extraction, it is likely it was created
// when creating a path to one of already extracted items.
// In such case we'll better update its time even if archived
// directory is older.
if (!FD.IsDir || FD.mtime<StartTime)
ExtrFile=false;
}
}
else
if (Cmd->FreshFiles)
ExtrFile=false;
}
// Skip encrypted file if no password is specified.
if ((Arc.NewLhd.Flags & LHD_PASSWORD)!=0 && *Password==0)
{
ErrHandler.SetErrorCode(WARNING);
#ifdef RARDLL
Cmd->DllError=ERAR_MISSING_PASSWORD;
#endif
ExtrFile=false;
}
#ifdef RARDLL
if (*Cmd->DllDestName)
{
strncpyz(DestFileName,Cmd->DllDestName,ASIZE(DestFileName));
*DestFileNameW=0;
if (Cmd->DllOpMode!=RAR_EXTRACT)
ExtrFile=false;
}
if (*Cmd->DllDestNameW)
{
strncpyzw(DestFileNameW,Cmd->DllDestNameW,ASIZE(DestFileNameW));
DestNameW=DestFileNameW;
if (Cmd->DllOpMode!=RAR_EXTRACT)
ExtrFile=false;
}
#endif
#ifdef SFX_MODULE
if ((Arc.NewLhd.UnpVer!=UNP_VER && Arc.NewLhd.UnpVer!=29) &&
Arc.NewLhd.Method!=0x30)
#else
if (Arc.NewLhd.UnpVer<13 || Arc.NewLhd.UnpVer>UNP_VER)
#endif
{
#ifndef SILENT
Log(Arc.FileName,St(MUnknownMeth),ArcFileName);
#ifndef SFX_MODULE
Log(Arc.FileName,St(MVerRequired),Arc.NewLhd.UnpVer/10,Arc.NewLhd.UnpVer%10);
#endif
#endif
ExtrFile=false;
ErrHandler.SetErrorCode(WARNING);
#ifdef RARDLL
Cmd->DllError=ERAR_UNKNOWN_FORMAT;
#endif
}
File CurFile;
if (!IsLink(Arc.NewLhd.FileAttr))
if (Arc.IsArcDir())
{
if (!ExtrFile || Command=='P' || Command=='E' || Cmd->ExclPath==EXCL_SKIPWHOLEPATH)
return(true);
if (SkipSolid)
{
#ifndef GUI
mprintf(St(MExtrSkipFile),ArcFileName);
#endif
return(true);
}
TotalFileCount++;
if (Cmd->Test)
{
#ifndef GUI
mprintf(St(MExtrTestFile),ArcFileName);
mprintf(" %s",St(MOk));
#endif
return(true);
}
MKDIR_CODE MDCode=MakeDir(DestFileName,DestNameW,!Cmd->IgnoreGeneralAttr,Arc.NewLhd.FileAttr);
bool DirExist=false;
if (MDCode!=MKDIR_SUCCESS)
{
DirExist=FileExist(DestFileName,DestNameW);
if (DirExist && !IsDir(GetFileAttr(DestFileName,DestNameW)))
{
bool UserReject;
FileCreate(Cmd,NULL,DestFileName,DestNameW,Cmd->Overwrite,&UserReject,Arc.NewLhd.FullUnpSize,Arc.NewLhd.FileTime);
DirExist=false;
}
CreatePath(DestFileName,DestNameW,true);
MDCode=MakeDir(DestFileName,DestNameW,!Cmd->IgnoreGeneralAttr,Arc.NewLhd.FileAttr);
}
if (MDCode==MKDIR_SUCCESS)
{
#ifndef GUI
mprintf(St(MCreatDir),DestFileName);
mprintf(" %s",St(MOk));
#endif
PrevExtracted=true;
}
else
if (DirExist)
{
if (!Cmd->IgnoreGeneralAttr)
SetFileAttr(DestFileName,DestNameW,Arc.NewLhd.FileAttr);
PrevExtracted=true;
}
else
{
Log(Arc.FileName,St(MExtrErrMkDir),DestFileName);
ErrHandler.SysErrMsg();
#ifdef RARDLL
Cmd->DllError=ERAR_ECREATE;
#endif
ErrHandler.SetErrorCode(CREATE_ERROR);
}
if (PrevExtracted)
{
#if defined(_WIN_32) && !defined(_WIN_CE) && !defined(SFX_MODULE)
if (Cmd->SetCompressedAttr &&
(Arc.NewLhd.FileAttr & FILE_ATTRIBUTE_COMPRESSED)!=0 && WinNT())
SetFileCompression(DestFileName,DestNameW,true);
#endif
SetDirTime(DestFileName,DestNameW,
Cmd->xmtime==EXTTIME_NONE ? NULL:&Arc.NewLhd.mtime,
Cmd->xctime==EXTTIME_NONE ? NULL:&Arc.NewLhd.ctime,
Cmd->xatime==EXTTIME_NONE ? NULL:&Arc.NewLhd.atime);
}
return(true);
}
else
{
if (Cmd->Test && ExtrFile)
TestMode=true;
#if !defined(GUI) && !defined(SFX_MODULE)
if (Command=='P' && ExtrFile)
CurFile.SetHandleType(FILE_HANDLESTD);
#endif
if ((Command=='E' || Command=='X') && ExtrFile && !Cmd->Test)
{
bool UserReject;
if (!FileCreate(Cmd,&CurFile,DestFileName,DestNameW,Cmd->Overwrite,&UserReject,Arc.NewLhd.FullUnpSize,Arc.NewLhd.FileTime))
{
ExtrFile=false;
if (!UserReject)
{
ErrHandler.CreateErrorMsg(Arc.FileName,DestFileName);
ErrHandler.SetErrorCode(CREATE_ERROR);
#ifdef RARDLL
Cmd->DllError=ERAR_ECREATE;
#endif
if (!IsNameUsable(DestFileName))
{
Log(Arc.FileName,St(MCorrectingName));
char OrigName[sizeof(DestFileName)];
strncpyz(OrigName,DestFileName,ASIZE(OrigName));
MakeNameUsable(DestFileName,true);
CreatePath(DestFileName,NULL,true);
if (FileCreate(Cmd,&CurFile,DestFileName,NULL,Cmd->Overwrite,&UserReject,Arc.NewLhd.FullUnpSize,Arc.NewLhd.FileTime))
{
#ifndef SFX_MODULE
Log(Arc.FileName,St(MRenaming),OrigName,DestFileName);
#endif
ExtrFile=true;
}
else
ErrHandler.CreateErrorMsg(Arc.FileName,DestFileName);
}
}
}
}
}
if (!ExtrFile && Arc.Solid)
{
SkipSolid=true;
TestMode=true;
ExtrFile=true;
}
if (ExtrFile)
{
if (!SkipSolid)
{
if (!TestMode && Command!='P' && CurFile.IsDevice())
{
Log(Arc.FileName,St(MInvalidName),DestFileName);
ErrHandler.WriteError(Arc.FileName,DestFileName);
}
TotalFileCount++;
}
FileCount++;
#ifndef GUI
if (Command!='I')
if (SkipSolid)
mprintf(St(MExtrSkipFile),ArcFileName);
else
switch(Cmd->Test ? 'T':Command)
{
case 'T':
mprintf(St(MExtrTestFile),ArcFileName);
break;
#ifndef SFX_MODULE
case 'P':
mprintf(St(MExtrPrinting),ArcFileName);
break;
#endif
case 'X':
case 'E':
mprintf(St(MExtrFile),DestFileName);
break;
}
if (!Cmd->DisablePercentage)
mprintf(" ");
#endif
DataIO.CurUnpRead=0;
DataIO.CurUnpWrite=0;
DataIO.UnpFileCRC=Arc.OldFormat ? 0 : 0xffffffff;
DataIO.PackedCRC=0xffffffff;
DataIO.SetEncryption(
(Arc.NewLhd.Flags & LHD_PASSWORD) ? Arc.NewLhd.UnpVer:0,Password,
(Arc.NewLhd.Flags & LHD_SALT) ? Arc.NewLhd.Salt:NULL,false,
Arc.NewLhd.UnpVer>=36);
DataIO.SetPackedSizeToRead(Arc.NewLhd.FullPackSize);
DataIO.SetFiles(&Arc,&CurFile);
DataIO.SetTestMode(TestMode);
DataIO.SetSkipUnpCRC(SkipSolid);
#ifndef _WIN_CE
if (!TestMode && !Arc.BrokenFileHeader &&
(Arc.NewLhd.FullPackSize<<11)>Arc.NewLhd.FullUnpSize &&
(Arc.NewLhd.FullUnpSize<100000000 || Arc.FileLength()>Arc.NewLhd.FullPackSize))
CurFile.Prealloc(Arc.NewLhd.FullUnpSize);
#endif
CurFile.SetAllowDelete(!Cmd->KeepBroken);
bool LinkCreateMode=!Cmd->Test && !SkipSolid;
if (ExtractLink(DataIO,Arc,DestFileName,DataIO.UnpFileCRC,LinkCreateMode))
PrevExtracted=LinkCreateMode;
else
if ((Arc.NewLhd.Flags & LHD_SPLIT_BEFORE)==0)
if (Arc.NewLhd.Method==0x30)
UnstoreFile(DataIO,Arc.NewLhd.FullUnpSize);
else
{
Unp->SetDestSize(Arc.NewLhd.FullUnpSize);
#ifndef SFX_MODULE
if (Arc.NewLhd.UnpVer<=15)
Unp->DoUnpack(15,FileCount>1 && Arc.Solid);
else
#endif
Unp->DoUnpack(Arc.NewLhd.UnpVer,(Arc.NewLhd.Flags & LHD_SOLID)!=0);
}
if (Arc.IsOpened())
Arc.SeekToNext();
bool BrokenFile=false;
if (!SkipSolid)
{
if (Arc.OldFormat && UINT32(DataIO.UnpFileCRC)==UINT32(Arc.NewLhd.FileCRC) ||
!Arc.OldFormat && UINT32(DataIO.UnpFileCRC)==UINT32(Arc.NewLhd.FileCRC^0xffffffff))
{
#ifndef GUI
if (Command!='P' && Command!='I')
mprintf("%s%s ",Cmd->DisablePercentage ? " ":"\b\b\b\b\b ",St(MOk));
#endif
}
else
{
char *BadArcName=/*(Arc.NewLhd.Flags & LHD_SPLIT_BEFORE) ? NULL:*/Arc.FileName;
if (Arc.NewLhd.Flags & LHD_PASSWORD)
{
Log(BadArcName,St(MEncrBadCRC),ArcFileName);
}
else
{
Log(BadArcName,St(MCRCFailed),ArcFileName);
}
BrokenFile=true;
ErrHandler.SetErrorCode(CRC_ERROR);
#ifdef RARDLL
Cmd->DllError=ERAR_BAD_DATA;
#endif
Alarm();
}
}
#ifndef GUI
else
mprintf("\b\b\b\b\b ");
#endif
if (!TestMode && (Command=='X' || Command=='E') &&
!IsLink(Arc.NewLhd.FileAttr))
{
#if defined(_WIN_32) || defined(_EMX)
if (Cmd->ClearArc)
Arc.NewLhd.FileAttr&=~FA_ARCH;
/*
else
Arc.NewLhd.FileAttr|=FA_ARCH; //set archive bit for unpacked files (file is not backed up)
*/
#endif
if (!BrokenFile || Cmd->KeepBroken)
{
if (BrokenFile)
CurFile.Truncate();
CurFile.SetOpenFileTime(
Cmd->xmtime==EXTTIME_NONE ? NULL:&Arc.NewLhd.mtime,
Cmd->xctime==EXTTIME_NONE ? NULL:&Arc.NewLhd.ctime,
Cmd->xatime==EXTTIME_NONE ? NULL:&Arc.NewLhd.atime);
CurFile.Close();
#if defined(_WIN_32) && !defined(_WIN_CE) && !defined(SFX_MODULE)
if (Cmd->SetCompressedAttr &&
(Arc.NewLhd.FileAttr & FILE_ATTRIBUTE_COMPRESSED)!=0 && WinNT())
SetFileCompression(CurFile.FileName,CurFile.FileNameW,true);
#endif
CurFile.SetCloseFileTime(
Cmd->xmtime==EXTTIME_NONE ? NULL:&Arc.NewLhd.mtime,
Cmd->xatime==EXTTIME_NONE ? NULL:&Arc.NewLhd.atime);
if (!Cmd->IgnoreGeneralAttr)
SetFileAttr(CurFile.FileName,CurFile.FileNameW,Arc.NewLhd.FileAttr);
PrevExtracted=true;
}
}
}
}
if (ExactMatch)
MatchedArgs++;
if (DataIO.NextVolumeMissing || !Arc.IsOpened())
return(false);
if (!ExtrFile)
if (!Arc.Solid)
Arc.SeekToNext();
else
if (!SkipSolid)
return(false);
return(true);
}
void CmdExtract::UnstoreFile(ComprDataIO &DataIO,int64 DestUnpSize)
{
Array<byte> Buffer(0x10000);
while (1)
{
uint Code=DataIO.UnpRead(&Buffer[0],Buffer.Size());
if (Code==0 || (int)Code==-1)
break;
Code=Code<DestUnpSize ? Code:(uint)DestUnpSize;
DataIO.UnpWrite(&Buffer[0],Code);
if (DestUnpSize>=0)
DestUnpSize-=Code;
}
}

43
libunrar/extract.hpp Normal file
View File

@ -0,0 +1,43 @@
#ifndef _RAR_EXTRACT_
#define _RAR_EXTRACT_
enum EXTRACT_ARC_CODE {EXTRACT_ARC_NEXT,EXTRACT_ARC_REPEAT};
class CmdExtract
{
private:
EXTRACT_ARC_CODE ExtractArchive(CommandData *Cmd);
RarTime StartTime; // time when extraction started
ComprDataIO DataIO;
Unpack *Unp;
unsigned long TotalFileCount;
unsigned long FileCount;
unsigned long MatchedArgs;
bool FirstFile;
bool AllMatchesExact;
bool ReconstructDone;
char ArcName[NM];
wchar ArcNameW[NM];
char Password[MAXPASSWORD];
bool PasswordAll;
bool PrevExtracted;
char DestFileName[NM];
wchar DestFileNameW[NM];
bool PasswordCancelled;
public:
CmdExtract();
~CmdExtract();
void DoExtract(CommandData *Cmd);
void ExtractArchiveInit(CommandData *Cmd,Archive &Arc);
bool ExtractCurrentFile(CommandData *Cmd,Archive &Arc,size_t HeaderSize,
bool &Repeat);
static void UnstoreFile(ComprDataIO &DataIO,int64 DestUnpSize);
bool SignatureFound;
};
#endif

245
libunrar/filcreat.cpp Normal file
View File

@ -0,0 +1,245 @@
#include "rar.hpp"
bool FileCreate(RAROptions *Cmd,File *NewFile,char *Name,wchar *NameW,
OVERWRITE_MODE Mode,bool *UserReject,int64 FileSize,
uint FileTime)
{
if (UserReject!=NULL)
*UserReject=false;
#if defined(_WIN_32) && !defined(_WIN_CE)
bool ShortNameChanged=false;
#endif
while (FileExist(Name,NameW))
{
#if defined(_WIN_32) && !defined(_WIN_CE)
if (!ShortNameChanged)
{
ShortNameChanged=true;
if (UpdateExistingShortName(Name,NameW))
continue;
}
#endif
if (Mode==OVERWRITE_NONE)
{
if (UserReject!=NULL)
*UserReject=true;
return(false);
}
#ifdef SILENT
Mode=OVERWRITE_ALL;
#endif
if (Cmd->AllYes || Mode==OVERWRITE_ALL)
break;
if (Mode==OVERWRITE_DEFAULT || Mode==OVERWRITE_FORCE_ASK)
{
eprintf(St(MFileExists),Name);
int Choice=Ask(St(MYesNoAllRenQ));
if (Choice==1)
break;
if (Choice==2)
{
if (UserReject!=NULL)
*UserReject=true;
return(false);
}
if (Choice==3)
{
Cmd->Overwrite=OVERWRITE_ALL;
break;
}
if (Choice==4)
{
if (UserReject!=NULL)
*UserReject=true;
Cmd->Overwrite=OVERWRITE_NONE;
return(false);
}
if (Choice==5)
{
mprintf(St(MAskNewName));
char NewName[NM];
#ifdef _WIN_32
File SrcFile;
SrcFile.SetHandleType(FILE_HANDLESTD);
int Size=SrcFile.Read(NewName,sizeof(NewName)-1);
NewName[Size]=0;
OemToChar(NewName,NewName);
#else
if (fgets(NewName,sizeof(NewName),stdin)==NULL)
{
// Process fgets failure as if user answered 'No'.
if (UserReject!=NULL)
*UserReject=true;
return(false);
}
#endif
RemoveLF(NewName);
if (PointToName(NewName)==NewName)
strcpy(PointToName(Name),NewName);
else
strcpy(Name,NewName);
if (NameW!=NULL)
*NameW=0;
continue;
}
if (Choice==6)
ErrHandler.Exit(USER_BREAK);
}
if (Mode==OVERWRITE_AUTORENAME)
{
if (GetAutoRenamedName(Name))
{
if (NameW!=NULL)
*NameW=0;
}
else
Mode=OVERWRITE_DEFAULT;
continue;
}
}
if (NewFile!=NULL && NewFile->Create(Name,NameW))
return(true);
PrepareToDelete(Name,NameW);
CreatePath(Name,NameW,true);
return(NewFile!=NULL ? NewFile->Create(Name,NameW):DelFile(Name,NameW));
}
bool GetAutoRenamedName(char *Name)
{
char NewName[NM];
if (strlen(Name)>sizeof(NewName)-10)
return(false);
char *Ext=GetExt(Name);
if (Ext==NULL)
Ext=Name+strlen(Name);
for (int FileVer=1;;FileVer++)
{
sprintf(NewName,"%.*s(%d)%s",int(Ext-Name),Name,FileVer,Ext);
if (!FileExist(NewName))
{
strcpy(Name,NewName);
break;
}
if (FileVer>=1000000)
return(false);
}
return(true);
}
#if defined(_WIN_32) && !defined(_WIN_CE)
bool UpdateExistingShortName(char *Name,wchar *NameW)
{
FindData fd;
if (!FindFile::FastFind(Name,NameW,&fd))
return(false);
if (*fd.Name==0 || *fd.ShortName==0)
return(false);
if (stricomp(PointToName(fd.Name),fd.ShortName)==0 ||
stricomp(PointToName(Name),fd.ShortName)!=0)
return(false);
char NewName[NM];
for (int I=0;I<10000;I+=123)
{
strncpyz(NewName,Name,ASIZE(NewName));
sprintf(PointToName(NewName),"rtmp%d",I);
if (!FileExist(NewName))
break;
}
if (FileExist(NewName))
return(false);
char FullName[NM];
strncpyz(FullName,Name,ASIZE(FullName));
strcpy(PointToName(FullName),PointToName(fd.Name));
if (!MoveFile(FullName,NewName))
return(false);
File KeepShortFile;
bool Created=false;
if (!FileExist(Name))
Created=KeepShortFile.Create(Name);
MoveFile(NewName,FullName);
if (Created)
{
KeepShortFile.Close();
KeepShortFile.Delete();
}
return(true);
}
/*
bool UpdateExistingShortName(char *Name,wchar *NameW)
{
if (WinNT()<5)
return(false);
FindData fd;
if (!FindFile::FastFind(Name,NameW,&fd))
return(false);
if (*fd.Name==0 || *fd.ShortName==0)
return(false);
if (stricomp(PointToName(fd.Name),fd.ShortName)==0 ||
stricomp(PointToName(Name),fd.ShortName)!=0)
return(false);
typedef BOOL (WINAPI *SETFILESHORTNAME)(HANDLE,LPCSTR);
static SETFILESHORTNAME pSetFileShortName=NULL;
if (pSetFileShortName==NULL)
{
HMODULE hKernel=GetModuleHandle("kernel32.dll");
if (hKernel!=NULL)
pSetFileShortName=(SETFILESHORTNAME)GetProcAddress(hKernel,"SetFileShortNameA");
if (pSetFileShortName==NULL)
return(false);
}
static bool RestoreEnabled=false;
if (!RestoreEnabled)
{
HANDLE hToken;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken))
return(false);
TOKEN_PRIVILEGES tp;
tp.PrivilegeCount = 1;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if (LookupPrivilegeValue(NULL,SE_RESTORE_NAME,&tp.Privileges[0].Luid))
AdjustTokenPrivileges(hToken, FALSE, &tp, 0, NULL, NULL);
CloseHandle(hToken);
RestoreEnabled=true;
}
wchar FileNameW[NM];
GetWideName(Name,NameW,FileNameW);
HANDLE hFile=CreateFileW(FileNameW,GENERIC_WRITE|DELETE,FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL,OPEN_EXISTING,FILE_FLAG_BACKUP_SEMANTICS,NULL);
if (hFile==INVALID_HANDLE_VALUE)
return(false);
bool RetCode=false;
char FullName[NM];
wchar FullNameW[NM];
strcpy(FullName,Name);
strcpyw(FullNameW,NullToEmpty(NameW));
for (int I=1;I<1000000;I++)
{
char NewName[NM];
sprintf(NewName,"NAME~%d.%d",I%1000,I/1000+1);
strcpy(PointToName(FullName),NewName);
if (*FullNameW)
CharToWide(NewName,PointToName(FullNameW));
if (!FileExist(FullName,FullNameW))
{
RetCode=pSetFileShortName(hFile,NewName);
break;
}
}
CloseHandle(hFile);
return(RetCode);
}
*/
#endif

13
libunrar/filcreat.hpp Normal file
View File

@ -0,0 +1,13 @@
#ifndef _RAR_FILECREATE_
#define _RAR_FILECREATE_
bool FileCreate(RAROptions *Cmd,File *NewFile,char *Name,wchar *NameW,
OVERWRITE_MODE Mode,bool *UserReject,int64 FileSize=INT64NDF,
uint FileTime=0);
bool GetAutoRenamedName(char *Name);
#if defined(_WIN_32) && !defined(_WIN_CE)
bool UpdateExistingShortName(char *Name,wchar *NameW);
#endif
#endif

678
libunrar/file.cpp Normal file
View File

@ -0,0 +1,678 @@
#include "rar.hpp"
static File *CreatedFiles[256];
static int RemoveCreatedActive=0;
File::File()
{
hFile=BAD_HANDLE;
*FileName=0;
*FileNameW=0;
NewFile=false;
LastWrite=false;
HandleType=FILE_HANDLENORMAL;
SkipClose=false;
IgnoreReadErrors=false;
ErrorType=FILE_SUCCESS;
OpenShared=false;
AllowDelete=true;
CloseCount=0;
AllowExceptions=true;
#ifdef _WIN_32
NoSequentialRead=false;
#endif
}
File::~File()
{
if (hFile!=BAD_HANDLE && !SkipClose)
if (NewFile)
Delete();
else
Close();
}
void File::operator = (File &SrcFile)
{
hFile=SrcFile.hFile;
strcpy(FileName,SrcFile.FileName);
NewFile=SrcFile.NewFile;
LastWrite=SrcFile.LastWrite;
HandleType=SrcFile.HandleType;
SrcFile.SkipClose=true;
}
bool File::Open(const char *Name,const wchar *NameW,bool OpenShared,bool Update)
{
ErrorType=FILE_SUCCESS;
FileHandle hNewFile;
if (File::OpenShared)
OpenShared=true;
#ifdef _WIN_32
uint Access=GENERIC_READ;
if (Update)
Access|=GENERIC_WRITE;
uint ShareMode=FILE_SHARE_READ;
if (OpenShared)
ShareMode|=FILE_SHARE_WRITE;
uint Flags=NoSequentialRead ? 0:FILE_FLAG_SEQUENTIAL_SCAN;
if (WinNT() && NameW!=NULL && *NameW!=0)
hNewFile=CreateFileW(NameW,Access,ShareMode,NULL,OPEN_EXISTING,Flags,NULL);
else
hNewFile=CreateFile(Name,Access,ShareMode,NULL,OPEN_EXISTING,Flags,NULL);
if (hNewFile==BAD_HANDLE && GetLastError()==ERROR_FILE_NOT_FOUND)
ErrorType=FILE_NOTFOUND;
#else
int flags=Update ? O_RDWR:O_RDONLY;
#ifdef O_BINARY
flags|=O_BINARY;
#if defined(_AIX) && defined(_LARGE_FILE_API)
flags|=O_LARGEFILE;
#endif
#endif
#if defined(_EMX) && !defined(_DJGPP)
int sflags=OpenShared ? SH_DENYNO:SH_DENYWR;
int handle=sopen(Name,flags,sflags);
#else
int handle=open(Name,flags);
#ifdef LOCK_EX
#ifdef _OSF_SOURCE
extern "C" int flock(int, int);
#endif
if (!OpenShared && Update && handle>=0 && flock(handle,LOCK_EX|LOCK_NB)==-1)
{
close(handle);
return(false);
}
#endif
#endif
hNewFile=handle==-1 ? BAD_HANDLE:fdopen(handle,Update ? UPDATEBINARY:READBINARY);
if (hNewFile==BAD_HANDLE && errno==ENOENT)
ErrorType=FILE_NOTFOUND;
#endif
NewFile=false;
HandleType=FILE_HANDLENORMAL;
SkipClose=false;
bool Success=hNewFile!=BAD_HANDLE;
if (Success)
{
hFile=hNewFile;
if (NameW!=NULL)
strcpyw(FileNameW,NameW);
else
*FileNameW=0;
if (Name!=NULL)
strcpy(FileName,Name);
else
WideToChar(NameW,FileName);
AddFileToList(hFile);
}
return(Success);
}
#if !defined(SHELL_EXT) && !defined(SFX_MODULE)
void File::TOpen(const char *Name,const wchar *NameW)
{
if (!WOpen(Name,NameW))
ErrHandler.Exit(OPEN_ERROR);
}
#endif
bool File::WOpen(const char *Name,const wchar *NameW)
{
if (Open(Name,NameW))
return(true);
ErrHandler.OpenErrorMsg(Name);
return(false);
}
bool File::Create(const char *Name,const wchar *NameW,bool ShareRead)
{
#ifdef _WIN_32
DWORD ShareMode=(ShareRead || File::OpenShared) ? FILE_SHARE_READ:0;
if (WinNT() && NameW!=NULL && *NameW!=0)
hFile=CreateFileW(NameW,GENERIC_READ|GENERIC_WRITE,ShareMode,NULL,
CREATE_ALWAYS,0,NULL);
else
hFile=CreateFile(Name,GENERIC_READ|GENERIC_WRITE,ShareMode,NULL,
CREATE_ALWAYS,0,NULL);
#else
hFile=fopen(Name,CREATEBINARY);
#endif
NewFile=true;
HandleType=FILE_HANDLENORMAL;
SkipClose=false;
if (NameW!=NULL)
strcpyw(FileNameW,NameW);
else
*FileNameW=0;
if (Name!=NULL)
strcpy(FileName,Name);
else
WideToChar(NameW,FileName);
AddFileToList(hFile);
return(hFile!=BAD_HANDLE);
}
void File::AddFileToList(FileHandle hFile)
{
if (hFile!=BAD_HANDLE)
for (int I=0;I<sizeof(CreatedFiles)/sizeof(CreatedFiles[0]);I++)
if (CreatedFiles[I]==NULL)
{
CreatedFiles[I]=this;
break;
}
}
#if !defined(SHELL_EXT) && !defined(SFX_MODULE)
void File::TCreate(const char *Name,const wchar *NameW,bool ShareRead)
{
if (!WCreate(Name,NameW,ShareRead))
ErrHandler.Exit(FATAL_ERROR);
}
#endif
bool File::WCreate(const char *Name,const wchar *NameW,bool ShareRead)
{
if (Create(Name,NameW,ShareRead))
return(true);
ErrHandler.SetErrorCode(CREATE_ERROR);
ErrHandler.CreateErrorMsg(Name);
return(false);
}
bool File::Close()
{
bool Success=true;
if (HandleType!=FILE_HANDLENORMAL)
HandleType=FILE_HANDLENORMAL;
else
if (hFile!=BAD_HANDLE)
{
if (!SkipClose)
{
#ifdef _WIN_32
Success=CloseHandle(hFile)==TRUE;
#else
Success=fclose(hFile)!=EOF;
#endif
if (Success || !RemoveCreatedActive)
for (int I=0;I<sizeof(CreatedFiles)/sizeof(CreatedFiles[0]);I++)
if (CreatedFiles[I]==this)
{
CreatedFiles[I]=NULL;
break;
}
}
hFile=BAD_HANDLE;
if (!Success && AllowExceptions)
ErrHandler.CloseError(FileName);
}
CloseCount++;
return(Success);
}
void File::Flush()
{
#ifdef _WIN_32
FlushFileBuffers(hFile);
#else
fflush(hFile);
#endif
}
bool File::Delete()
{
if (HandleType!=FILE_HANDLENORMAL)
return(false);
if (hFile!=BAD_HANDLE)
Close();
if (!AllowDelete)
return(false);
return(DelFile(FileName,FileNameW));
}
bool File::Rename(const char *NewName,const wchar *NewNameW)
{
// we do not need to rename if names are already same
bool Success=strcmp(FileName,NewName)==0;
if (Success && *FileNameW!=0 && *NullToEmpty(NewNameW)!=0)
Success=strcmpw(FileNameW,NewNameW)==0;
if (!Success)
Success=RenameFile(FileName,FileNameW,NewName,NewNameW);
if (Success)
{
// renamed successfully, storing the new name
strcpy(FileName,NewName);
strcpyw(FileNameW,NullToEmpty(NewNameW));
}
return(Success);
}
void File::Write(const void *Data,size_t Size)
{
if (Size==0)
return;
#ifndef _WIN_CE
if (HandleType!=FILE_HANDLENORMAL)
switch(HandleType)
{
case FILE_HANDLESTD:
#ifdef _WIN_32
hFile=GetStdHandle(STD_OUTPUT_HANDLE);
#else
hFile=stdout;
#endif
break;
case FILE_HANDLEERR:
#ifdef _WIN_32
hFile=GetStdHandle(STD_ERROR_HANDLE);
#else
hFile=stderr;
#endif
break;
}
#endif
while (1)
{
bool Success=false;
#ifdef _WIN_32
DWORD Written=0;
if (HandleType!=FILE_HANDLENORMAL)
{
// writing to stdout can fail in old Windows if data block is too large
const size_t MaxSize=0x4000;
for (size_t I=0;I<Size;I+=MaxSize)
{
Success=WriteFile(hFile,(byte *)Data+I,(DWORD)Min(Size-I,MaxSize),&Written,NULL)==TRUE;
if (!Success)
break;
}
}
else
Success=WriteFile(hFile,Data,(DWORD)Size,&Written,NULL)==TRUE;
#else
int Written=fwrite(Data,1,Size,hFile);
Success=Written==Size && !ferror(hFile);
#endif
if (!Success && AllowExceptions && HandleType==FILE_HANDLENORMAL)
{
#if defined(_WIN_32) && !defined(SFX_MODULE) && !defined(RARDLL)
int ErrCode=GetLastError();
int64 FilePos=Tell();
uint64 FreeSize=GetFreeDisk(FileName);
SetLastError(ErrCode);
if (FreeSize>Size && FilePos-Size<=0xffffffff && FilePos+Size>0xffffffff)
ErrHandler.WriteErrorFAT(FileName);
#endif
if (ErrHandler.AskRepeatWrite(FileName,false))
{
#ifndef _WIN_32
clearerr(hFile);
#endif
if (Written<Size && Written>0)
Seek(Tell()-Written,SEEK_SET);
continue;
}
ErrHandler.WriteError(NULL,FileName);
}
break;
}
LastWrite=true;
}
int File::Read(void *Data,size_t Size)
{
int64 FilePos=0; //initialized only to suppress some compilers warning
if (IgnoreReadErrors)
FilePos=Tell();
int ReadSize;
while (true)
{
ReadSize=DirectRead(Data,Size);
if (ReadSize==-1)
{
ErrorType=FILE_READERROR;
if (AllowExceptions)
if (IgnoreReadErrors)
{
ReadSize=0;
for (size_t I=0;I<Size;I+=512)
{
Seek(FilePos+I,SEEK_SET);
size_t SizeToRead=Min(Size-I,512);
int ReadCode=DirectRead(Data,SizeToRead);
ReadSize+=(ReadCode==-1) ? 512:ReadCode;
}
}
else
{
if (HandleType==FILE_HANDLENORMAL && ErrHandler.AskRepeatRead(FileName))
continue;
ErrHandler.ReadError(FileName);
}
}
break;
}
return(ReadSize);
}
// Returns -1 in case of error.
int File::DirectRead(void *Data,size_t Size)
{
#ifdef _WIN_32
const size_t MaxDeviceRead=20000;
#endif
#ifndef _WIN_CE
if (HandleType==FILE_HANDLESTD)
{
#ifdef _WIN_32
if (Size>MaxDeviceRead)
Size=MaxDeviceRead;
hFile=GetStdHandle(STD_INPUT_HANDLE);
#else
hFile=stdin;
#endif
}
#endif
#ifdef _WIN_32
DWORD Read;
if (!ReadFile(hFile,Data,(DWORD)Size,&Read,NULL))
{
if (IsDevice() && Size>MaxDeviceRead)
return(DirectRead(Data,MaxDeviceRead));
if (HandleType==FILE_HANDLESTD && GetLastError()==ERROR_BROKEN_PIPE)
return(0);
return(-1);
}
return(Read);
#else
if (LastWrite)
{
fflush(hFile);
LastWrite=false;
}
clearerr(hFile);
size_t ReadSize=fread(Data,1,Size,hFile);
if (ferror(hFile))
return(-1);
return((int)ReadSize);
#endif
}
void File::Seek(int64 Offset,int Method)
{
if (!RawSeek(Offset,Method) && AllowExceptions)
ErrHandler.SeekError(FileName);
}
bool File::RawSeek(int64 Offset,int Method)
{
if (hFile==BAD_HANDLE)
return(true);
if (Offset<0 && Method!=SEEK_SET)
{
Offset=(Method==SEEK_CUR ? Tell():FileLength())+Offset;
Method=SEEK_SET;
}
#ifdef _WIN_32
LONG HighDist=(LONG)(Offset>>32);
if (SetFilePointer(hFile,(LONG)Offset,&HighDist,Method)==0xffffffff &&
GetLastError()!=NO_ERROR)
return(false);
#else
LastWrite=false;
#if defined(_LARGEFILE_SOURCE) && !defined(_OSF_SOURCE) && !defined(__VMS)
if (fseeko(hFile,Offset,Method)!=0)
#else
if (fseek(hFile,(long)Offset,Method)!=0)
#endif
return(false);
#endif
return(true);
}
int64 File::Tell()
{
#ifdef _WIN_32
LONG HighDist=0;
uint LowDist=SetFilePointer(hFile,0,&HighDist,FILE_CURRENT);
if (LowDist==0xffffffff && GetLastError()!=NO_ERROR)
if (AllowExceptions)
ErrHandler.SeekError(FileName);
else
return(-1);
return(INT32TO64(HighDist,LowDist));
#else
#if defined(_LARGEFILE_SOURCE) && !defined(_OSF_SOURCE)
return(ftello(hFile));
#else
return(ftell(hFile));
#endif
#endif
}
void File::Prealloc(int64 Size)
{
#ifdef _WIN_32
if (RawSeek(Size,SEEK_SET))
{
Truncate();
Seek(0,SEEK_SET);
}
#endif
}
byte File::GetByte()
{
byte Byte=0;
Read(&Byte,1);
return(Byte);
}
void File::PutByte(byte Byte)
{
Write(&Byte,1);
}
bool File::Truncate()
{
#ifdef _WIN_32
return(SetEndOfFile(hFile)==TRUE);
#else
return(false);
#endif
}
void File::SetOpenFileTime(RarTime *ftm,RarTime *ftc,RarTime *fta)
{
#ifdef _WIN_32
bool sm=ftm!=NULL && ftm->IsSet();
bool sc=ftc!=NULL && ftc->IsSet();
bool sa=fta!=NULL && fta->IsSet();
FILETIME fm,fc,fa;
if (sm)
ftm->GetWin32(&fm);
if (sc)
ftc->GetWin32(&fc);
if (sa)
fta->GetWin32(&fa);
SetFileTime(hFile,sc ? &fc:NULL,sa ? &fa:NULL,sm ? &fm:NULL);
#endif
}
void File::SetCloseFileTime(RarTime *ftm,RarTime *fta)
{
#if defined(_UNIX) || defined(_EMX)
SetCloseFileTimeByName(FileName,ftm,fta);
#endif
}
void File::SetCloseFileTimeByName(const char *Name,RarTime *ftm,RarTime *fta)
{
#if defined(_UNIX) || defined(_EMX)
bool setm=ftm!=NULL && ftm->IsSet();
bool seta=fta!=NULL && fta->IsSet();
if (setm || seta)
{
struct utimbuf ut;
if (setm)
ut.modtime=ftm->GetUnix();
else
ut.modtime=fta->GetUnix();
if (seta)
ut.actime=fta->GetUnix();
else
ut.actime=ut.modtime;
utime(Name,&ut);
}
#endif
}
void File::GetOpenFileTime(RarTime *ft)
{
#ifdef _WIN_32
FILETIME FileTime;
GetFileTime(hFile,NULL,NULL,&FileTime);
*ft=FileTime;
#endif
#if defined(_UNIX) || defined(_EMX)
struct stat st;
fstat(fileno(hFile),&st);
*ft=st.st_mtime;
#endif
}
int64 File::FileLength()
{
SaveFilePos SavePos(*this);
Seek(0,SEEK_END);
return(Tell());
}
void File::SetHandleType(FILE_HANDLETYPE Type)
{
HandleType=Type;
}
bool File::IsDevice()
{
if (hFile==BAD_HANDLE)
return(false);
#ifdef _WIN_32
uint Type=GetFileType(hFile);
return(Type==FILE_TYPE_CHAR || Type==FILE_TYPE_PIPE);
#else
return(isatty(fileno(hFile)));
#endif
}
#ifndef SFX_MODULE
void File::fprintf(const char *fmt,...)
{
va_list argptr;
va_start(argptr,fmt);
safebuf char Msg[2*NM+1024],OutMsg[2*NM+1024];
vsprintf(Msg,fmt,argptr);
#ifdef _WIN_32
for (int Src=0,Dest=0;;Src++)
{
char CurChar=Msg[Src];
if (CurChar=='\n')
OutMsg[Dest++]='\r';
OutMsg[Dest++]=CurChar;
if (CurChar==0)
break;
}
#else
strcpy(OutMsg,Msg);
#endif
Write(OutMsg,strlen(OutMsg));
va_end(argptr);
}
#endif
bool File::RemoveCreated()
{
RemoveCreatedActive++;
bool RetCode=true;
for (int I=0;I<sizeof(CreatedFiles)/sizeof(CreatedFiles[0]);I++)
if (CreatedFiles[I]!=NULL)
{
CreatedFiles[I]->SetExceptions(false);
bool Success;
if (CreatedFiles[I]->NewFile)
Success=CreatedFiles[I]->Delete();
else
Success=CreatedFiles[I]->Close();
if (Success)
CreatedFiles[I]=NULL;
else
RetCode=false;
}
RemoveCreatedActive--;
return(RetCode);
}
#ifndef SFX_MODULE
int64 File::Copy(File &Dest,int64 Length)
{
Array<char> Buffer(0x10000);
int64 CopySize=0;
bool CopyAll=(Length==INT64NDF);
while (CopyAll || Length>0)
{
Wait();
size_t SizeToRead=(!CopyAll && Length<(int64)Buffer.Size()) ? (size_t)Length:Buffer.Size();
int ReadSize=Read(&Buffer[0],SizeToRead);
if (ReadSize==0)
break;
Dest.Write(&Buffer[0],ReadSize);
CopySize+=ReadSize;
if (!CopyAll)
Length-=ReadSize;
}
return(CopySize);
}
#endif

98
libunrar/file.hpp Normal file
View File

@ -0,0 +1,98 @@
#ifndef _RAR_FILE_
#define _RAR_FILE_
#ifdef _WIN_32
typedef HANDLE FileHandle;
#define BAD_HANDLE INVALID_HANDLE_VALUE
#else
typedef FILE* FileHandle;
#define BAD_HANDLE NULL
#endif
class RAROptions;
enum FILE_HANDLETYPE {FILE_HANDLENORMAL,FILE_HANDLESTD,FILE_HANDLEERR};
enum FILE_ERRORTYPE {FILE_SUCCESS,FILE_NOTFOUND,FILE_READERROR};
struct FileStat
{
uint FileAttr;
uint FileTime;
int64 FileSize;
bool IsDir;
};
class File
{
private:
void AddFileToList(FileHandle hFile);
FileHandle hFile;
bool LastWrite;
FILE_HANDLETYPE HandleType;
bool SkipClose;
bool IgnoreReadErrors;
bool NewFile;
bool AllowDelete;
bool AllowExceptions;
#ifdef _WIN_32
bool NoSequentialRead;
#endif
protected:
bool OpenShared;
public:
char FileName[NM];
wchar FileNameW[NM];
FILE_ERRORTYPE ErrorType;
uint CloseCount;
public:
File();
virtual ~File();
void operator = (File &SrcFile);
bool Open(const char *Name,const wchar *NameW=NULL,bool OpenShared=false,bool Update=false);
void TOpen(const char *Name,const wchar *NameW=NULL);
bool WOpen(const char *Name,const wchar *NameW=NULL);
bool Create(const char *Name,const wchar *NameW=NULL,bool ShareRead=true);
void TCreate(const char *Name,const wchar *NameW=NULL,bool ShareRead=true);
bool WCreate(const char *Name,const wchar *NameW=NULL,bool ShareRead=true);
bool Close();
void Flush();
bool Delete();
bool Rename(const char *NewName,const wchar *NewNameW=NULL);
void Write(const void *Data,size_t Size);
int Read(void *Data,size_t Size);
int DirectRead(void *Data,size_t Size);
void Seek(int64 Offset,int Method);
bool RawSeek(int64 Offset,int Method);
int64 Tell();
void Prealloc(int64 Size);
byte GetByte();
void PutByte(byte Byte);
bool Truncate();
void SetOpenFileTime(RarTime *ftm,RarTime *ftc=NULL,RarTime *fta=NULL);
void SetCloseFileTime(RarTime *ftm,RarTime *fta=NULL);
static void SetCloseFileTimeByName(const char *Name,RarTime *ftm,RarTime *fta);
void GetOpenFileTime(RarTime *ft);
bool IsOpened() {return(hFile!=BAD_HANDLE);};
int64 FileLength();
void SetHandleType(FILE_HANDLETYPE Type);
FILE_HANDLETYPE GetHandleType() {return(HandleType);};
bool IsDevice();
void fprintf(const char *fmt,...);
static bool RemoveCreated();
FileHandle GetHandle() {return(hFile);};
void SetIgnoreReadErrors(bool Mode) {IgnoreReadErrors=Mode;};
char *GetName() {return(FileName);}
int64 Copy(File &Dest,int64 Length=INT64NDF);
void SetAllowDelete(bool Allow) {AllowDelete=Allow;}
void SetExceptions(bool Allow) {AllowExceptions=Allow;}
#ifdef _WIN_32
void RemoveSequentialFlag() {NoSequentialRead=true;}
#endif
};
#endif

585
libunrar/filefn.cpp Normal file
View File

@ -0,0 +1,585 @@
#include "rar.hpp"
MKDIR_CODE MakeDir(const char *Name,const wchar *NameW,bool SetAttr,uint Attr)
{
#ifdef _WIN_32
int Success;
if (WinNT() && NameW!=NULL && *NameW!=0)
Success=CreateDirectoryW(NameW,NULL);
else
Success=CreateDirectory(Name,NULL);
if (Success)
{
if (SetAttr)
SetFileAttr(Name,NameW,Attr);
return(MKDIR_SUCCESS);
}
int ErrCode=GetLastError();
if (ErrCode==ERROR_FILE_NOT_FOUND || ErrCode==ERROR_PATH_NOT_FOUND)
return(MKDIR_BADPATH);
return(MKDIR_ERROR);
#endif
#ifdef _EMX
#ifdef _DJGPP
if (mkdir(Name,(Attr & FA_RDONLY) ? 0:S_IWUSR)==0)
#else
if (__mkdir(Name)==0)
#endif
{
if (SetAttr)
SetFileAttr(Name,NameW,Attr);
return(MKDIR_SUCCESS);
}
return(errno==ENOENT ? MKDIR_BADPATH:MKDIR_ERROR);
#endif
#ifdef _UNIX
mode_t uattr=SetAttr ? (mode_t)Attr:0777;
int ErrCode=Name==NULL ? -1:mkdir(Name,uattr);
if (ErrCode==-1)
return(errno==ENOENT ? MKDIR_BADPATH:MKDIR_ERROR);
return(MKDIR_SUCCESS);
#endif
}
bool CreatePath(const char *Path,const wchar *PathW,bool SkipLastName)
{
#if defined(_WIN_32) || defined(_EMX)
uint DirAttr=0;
#else
uint DirAttr=0777;
#endif
#ifdef UNICODE_SUPPORTED
bool Wide=PathW!=NULL && *PathW!=0 && UnicodeEnabled();
#else
bool Wide=false;
#endif
bool IgnoreAscii=false;
bool Success=true;
const char *s=Path;
for (int PosW=0;;PosW++)
{
if (s==NULL || s-Path>=NM || *s==0)
IgnoreAscii=true;
if (Wide && (PosW>=NM || PathW[PosW]==0) || !Wide && IgnoreAscii)
break;
if (Wide && PathW[PosW]==CPATHDIVIDER || !Wide && *s==CPATHDIVIDER)
{
wchar *DirPtrW=NULL,DirNameW[NM];
if (Wide)
{
strncpyw(DirNameW,PathW,PosW);
DirNameW[PosW]=0;
DirPtrW=DirNameW;
}
char DirName[NM];
if (IgnoreAscii)
WideToChar(DirPtrW,DirName);
else
{
#ifndef DBCS_SUPPORTED
if (*s!=CPATHDIVIDER)
for (const char *n=s;*n!=0 && n-Path<NM;n++)
if (*n==CPATHDIVIDER)
{
s=n;
break;
}
#endif
strncpy(DirName,Path,s-Path);
DirName[s-Path]=0;
}
if (MakeDir(DirName,DirPtrW,true,DirAttr)==MKDIR_SUCCESS)
{
#ifndef GUI
mprintf(St(MCreatDir),DirName);
mprintf(" %s",St(MOk));
#endif
}
else
Success=false;
}
if (!IgnoreAscii)
s=charnext(s);
}
if (!SkipLastName && !IsPathDiv(*PointToLastChar(Path)))
if (MakeDir(Path,PathW,true,DirAttr)!=MKDIR_SUCCESS)
Success=false;
return(Success);
}
void SetDirTime(const char *Name,const wchar *NameW,RarTime *ftm,RarTime *ftc,RarTime *fta)
{
#ifdef _WIN_32
if (!WinNT())
return;
bool sm=ftm!=NULL && ftm->IsSet();
bool sc=ftc!=NULL && ftc->IsSet();
bool sa=fta!=NULL && fta->IsSet();
unsigned int DirAttr=GetFileAttr(Name,NameW);
bool ResetAttr=(DirAttr!=0xffffffff && (DirAttr & FA_RDONLY)!=0);
if (ResetAttr)
SetFileAttr(Name,NameW,0);
wchar DirNameW[NM];
GetWideName(Name,NameW,DirNameW);
HANDLE hFile=CreateFileW(DirNameW,GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL,OPEN_EXISTING,FILE_FLAG_BACKUP_SEMANTICS,NULL);
if (hFile==INVALID_HANDLE_VALUE)
return;
FILETIME fm,fc,fa;
if (sm)
ftm->GetWin32(&fm);
if (sc)
ftc->GetWin32(&fc);
if (sa)
fta->GetWin32(&fa);
SetFileTime(hFile,sc ? &fc:NULL,sa ? &fa:NULL,sm ? &fm:NULL);
CloseHandle(hFile);
if (ResetAttr)
SetFileAttr(Name,NameW,DirAttr);
#endif
#if defined(_UNIX) || defined(_EMX)
File::SetCloseFileTimeByName(Name,ftm,fta);
#endif
}
bool IsRemovable(const char *Name)
{
#ifdef _WIN_32
char Root[NM];
GetPathRoot(Name,Root);
int Type=GetDriveType(*Root ? Root:NULL);
return(Type==DRIVE_REMOVABLE || Type==DRIVE_CDROM);
#elif defined(_EMX)
char Drive=etoupper(Name[0]);
return((Drive=='A' || Drive=='B') && Name[1]==':');
#else
return(false);
#endif
}
#ifndef SFX_MODULE
int64 GetFreeDisk(const char *Name)
{
#ifdef _WIN_32
char Root[NM];
GetPathRoot(Name,Root);
typedef BOOL (WINAPI *GETDISKFREESPACEEX)(
LPCTSTR,PULARGE_INTEGER,PULARGE_INTEGER,PULARGE_INTEGER
);
static GETDISKFREESPACEEX pGetDiskFreeSpaceEx=NULL;
if (pGetDiskFreeSpaceEx==NULL)
{
HMODULE hKernel=GetModuleHandle("kernel32.dll");
if (hKernel!=NULL)
pGetDiskFreeSpaceEx=(GETDISKFREESPACEEX)GetProcAddress(hKernel,"GetDiskFreeSpaceExA");
}
if (pGetDiskFreeSpaceEx!=NULL)
{
GetFilePath(Name,Root,ASIZE(Root));
ULARGE_INTEGER uiTotalSize,uiTotalFree,uiUserFree;
uiUserFree.u.LowPart=uiUserFree.u.HighPart=0;
if (pGetDiskFreeSpaceEx(*Root ? Root:NULL,&uiUserFree,&uiTotalSize,&uiTotalFree) &&
uiUserFree.u.HighPart<=uiTotalFree.u.HighPart)
return(INT32TO64(uiUserFree.u.HighPart,uiUserFree.u.LowPart));
}
// We are here if we failed to load GetDiskFreeSpaceExA.
DWORD SectorsPerCluster,BytesPerSector,FreeClusters,TotalClusters;
if (!GetDiskFreeSpace(*Root ? Root:NULL,&SectorsPerCluster,&BytesPerSector,&FreeClusters,&TotalClusters))
return(1457664);
int64 FreeSize=SectorsPerCluster*BytesPerSector;
FreeSize=FreeSize*FreeClusters;
return(FreeSize);
#elif defined(_BEOS)
char Root[NM];
GetFilePath(Name,Root,ASIZE(Root));
dev_t Dev=dev_for_path(*Root ? Root:".");
if (Dev<0)
return(1457664);
fs_info Info;
if (fs_stat_dev(Dev,&Info)!=0)
return(1457664);
int64 FreeSize=Info.block_size;
FreeSize=FreeSize*Info.free_blocks;
return(FreeSize);
#elif defined(_UNIX)
return(1457664);
#elif defined(_EMX)
int Drive=IsDiskLetter(Name) ? etoupper(Name[0])-'A'+1:0;
#ifndef _DJGPP
if (_osmode == OS2_MODE)
{
FSALLOCATE fsa;
if (DosQueryFSInfo(Drive,1,&fsa,sizeof(fsa))!=0)
return(1457664);
int64 FreeSize=fsa.cSectorUnit*fsa.cbSector;
FreeSize=FreeSize*fsa.cUnitAvail;
return(FreeSize);
}
else
#endif
{
union REGS regs,outregs;
memset(&regs,0,sizeof(regs));
regs.h.ah=0x36;
regs.h.dl=Drive;
#ifdef _DJGPP
int86 (0x21,&regs,&outregs);
#else
_int86 (0x21,&regs,&outregs);
#endif
if (outregs.x.ax==0xffff)
return(1457664);
int64 FreeSize=outregs.x.ax*outregs.x.cx;
FreeSize=FreeSize*outregs.x.bx;
return(FreeSize);
}
#else
#define DISABLEAUTODETECT
return(1457664);
#endif
}
#endif
bool FileExist(const char *Name,const wchar *NameW)
{
#ifdef _WIN_32
if (WinNT() && NameW!=NULL && *NameW!=0)
return(GetFileAttributesW(NameW)!=0xffffffff);
else
return(GetFileAttributes(Name)!=0xffffffff);
#elif defined(ENABLE_ACCESS)
return(access(Name,0)==0);
#else
struct FindData FD;
return(FindFile::FastFind(Name,NameW,&FD));
#endif
}
bool WildFileExist(const char *Name,const wchar *NameW)
{
if (IsWildcard(Name,NameW))
{
FindFile Find;
Find.SetMask(Name);
Find.SetMaskW(NameW);
struct FindData fd;
return(Find.Next(&fd));
}
return(FileExist(Name,NameW));
}
bool IsDir(uint Attr)
{
#if defined (_WIN_32) || defined(_EMX)
return(Attr!=0xffffffff && (Attr & 0x10)!=0);
#endif
#if defined(_UNIX)
return((Attr & 0xF000)==0x4000);
#endif
}
bool IsUnreadable(uint Attr)
{
#if defined(_UNIX) && defined(S_ISFIFO) && defined(S_ISSOCK) && defined(S_ISCHR)
return(S_ISFIFO(Attr) || S_ISSOCK(Attr) || S_ISCHR(Attr));
#endif
return(false);
}
bool IsLabel(uint Attr)
{
#if defined (_WIN_32) || defined(_EMX)
return((Attr & 8)!=0);
#else
return(false);
#endif
}
bool IsLink(uint Attr)
{
#ifdef _UNIX
return((Attr & 0xF000)==0xA000);
#else
return(false);
#endif
}
bool IsDeleteAllowed(uint FileAttr)
{
#if defined(_WIN_32) || defined(_EMX)
return((FileAttr & (FA_RDONLY|FA_SYSTEM|FA_HIDDEN))==0);
#else
return((FileAttr & (S_IRUSR|S_IWUSR))==(S_IRUSR|S_IWUSR));
#endif
}
void PrepareToDelete(const char *Name,const wchar *NameW)
{
#if defined(_WIN_32) || defined(_EMX)
SetFileAttr(Name,NameW,0);
#endif
#ifdef _UNIX
chmod(Name,S_IRUSR|S_IWUSR|S_IXUSR);
#endif
}
uint GetFileAttr(const char *Name,const wchar *NameW)
{
#ifdef _WIN_32
if (WinNT() && NameW!=NULL && *NameW!=0)
return(GetFileAttributesW(NameW));
else
return(GetFileAttributes(Name));
#elif defined(_DJGPP)
return(_chmod(Name,0));
#else
struct stat st;
if (stat(Name,&st)!=0)
return(0);
#ifdef _EMX
return(st.st_attr);
#else
return(st.st_mode);
#endif
#endif
}
bool SetFileAttr(const char *Name,const wchar *NameW,uint Attr)
{
bool Success;
#ifdef _WIN_32
if (WinNT() && NameW!=NULL && *NameW!=0)
Success=SetFileAttributesW(NameW,Attr)!=0;
else
Success=SetFileAttributes(Name,Attr)!=0;
#elif defined(_DJGPP)
Success=_chmod(Name,1,Attr)!=-1;
#elif defined(_EMX)
Success=__chmod(Name,1,Attr)!=-1;
#elif defined(_UNIX)
Success=chmod(Name,(mode_t)Attr)==0;
#else
Success=false;
#endif
return(Success);
}
void ConvertNameToFull(const char *Src,char *Dest)
{
#ifdef _WIN_32
#ifndef _WIN_CE
char FullName[NM],*NamePtr;
if (GetFullPathName(Src,sizeof(FullName),FullName,&NamePtr))
strcpy(Dest,FullName);
else
#endif
if (Src!=Dest)
strcpy(Dest,Src);
#else
char FullName[NM];
if (IsPathDiv(*Src) || IsDiskLetter(Src))
strcpy(FullName,Src);
else
{
if (getcwd(FullName,sizeof(FullName))==NULL)
*FullName=0;
else
AddEndSlash(FullName);
strcat(FullName,Src);
}
strcpy(Dest,FullName);
#endif
}
#ifndef SFX_MODULE
void ConvertNameToFull(const wchar *Src,wchar *Dest)
{
if (Src==NULL || *Src==0)
{
*Dest=0;
return;
}
#ifdef _WIN_32
#ifndef _WIN_CE
if (WinNT())
#endif
{
#ifndef _WIN_CE
wchar FullName[NM],*NamePtr;
if (GetFullPathNameW(Src,sizeof(FullName)/sizeof(FullName[0]),FullName,&NamePtr))
strcpyw(Dest,FullName);
else
#endif
if (Src!=Dest)
strcpyw(Dest,Src);
}
#ifndef _WIN_CE
else
{
char AnsiName[NM];
WideToChar(Src,AnsiName);
ConvertNameToFull(AnsiName,AnsiName);
CharToWide(AnsiName,Dest);
}
#endif
#else
char AnsiName[NM];
WideToChar(Src,AnsiName);
ConvertNameToFull(AnsiName,AnsiName);
CharToWide(AnsiName,Dest);
#endif
}
#endif
#ifndef SFX_MODULE
char *MkTemp(char *Name)
{
size_t Length=strlen(Name);
if (Length<=6)
return(NULL);
int Random=clock();
for (int Attempt=0;;Attempt++)
{
sprintf(Name+Length-6,"%06u",Random+Attempt);
Name[Length-4]='.';
if (!FileExist(Name))
break;
if (Attempt==1000)
return(NULL);
}
return(Name);
}
#endif
#ifndef SFX_MODULE
uint CalcFileCRC(File *SrcFile,int64 Size,CALCCRC_SHOWMODE ShowMode)
{
SaveFilePos SavePos(*SrcFile);
const size_t BufSize=0x10000;
Array<byte> Data(BufSize);
int64 BlockCount=0;
uint DataCRC=0xffffffff;
#if !defined(SILENT) && !defined(_WIN_CE)
int64 FileLength=SrcFile->FileLength();
if (ShowMode!=CALCCRC_SHOWNONE)
{
mprintf(St(MCalcCRC));
mprintf(" ");
}
#endif
SrcFile->Seek(0,SEEK_SET);
while (true)
{
size_t SizeToRead;
if (Size==INT64NDF) // If we process the entire file.
SizeToRead=BufSize; // Then always attempt to read the entire buffer.
else
SizeToRead=(size_t)Min((int64)BufSize,Size);
int ReadSize=SrcFile->Read(&Data[0],SizeToRead);
if (ReadSize==0)
break;
++BlockCount;
if ((BlockCount & 15)==0)
{
#if !defined(SILENT) && !defined(_WIN_CE)
if (ShowMode==CALCCRC_SHOWALL)
mprintf("\b\b\b\b%3d%%",ToPercent(BlockCount*int64(BufSize),FileLength));
#endif
Wait();
}
DataCRC=CRC(DataCRC,&Data[0],ReadSize);
if (Size!=INT64NDF)
Size-=ReadSize;
}
#if !defined(SILENT) && !defined(_WIN_CE)
if (ShowMode==CALCCRC_SHOWALL)
mprintf("\b\b\b\b ");
#endif
return(DataCRC^0xffffffff);
}
#endif
bool RenameFile(const char *SrcName,const wchar *SrcNameW,const char *DestName,const wchar *DestNameW)
{
return(rename(SrcName,DestName)==0);
}
bool DelFile(const char *Name)
{
return(DelFile(Name,NULL));
}
bool DelFile(const char *Name,const wchar *NameW)
{
return(remove(Name)==0);
}
#if defined(_WIN_32) && !defined(_WIN_CE) && !defined(SFX_MODULE)
bool SetFileCompression(char *Name,wchar *NameW,bool State)
{
wchar FileNameW[NM];
GetWideName(Name,NameW,FileNameW);
HANDLE hFile=CreateFileW(FileNameW,FILE_READ_DATA|FILE_WRITE_DATA,
FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS|FILE_FLAG_SEQUENTIAL_SCAN,NULL);
if (hFile==INVALID_HANDLE_VALUE)
return(false);
SHORT NewState=State ? COMPRESSION_FORMAT_DEFAULT:COMPRESSION_FORMAT_NONE;
DWORD Result;
int RetCode=DeviceIoControl(hFile,FSCTL_SET_COMPRESSION,&NewState,
sizeof(NewState),NULL,0,&Result,NULL);
CloseHandle(hFile);
return(RetCode!=0);
}
#endif

44
libunrar/filefn.hpp Normal file
View File

@ -0,0 +1,44 @@
#ifndef _RAR_FILEFN_
#define _RAR_FILEFN_
enum MKDIR_CODE {MKDIR_SUCCESS,MKDIR_ERROR,MKDIR_BADPATH};
MKDIR_CODE MakeDir(const char *Name,const wchar *NameW,bool SetAttr,uint Attr);
bool CreatePath(const char *Path,const wchar *PathW,bool SkipLastName);
void SetDirTime(const char *Name,const wchar *NameW,RarTime *ftm,RarTime *ftc,RarTime *fta);
bool IsRemovable(const char *Name);
int64 GetFreeDisk(const char *Name);
bool FileExist(const char *Name,const wchar *NameW=NULL);
bool WildFileExist(const char *Name,const wchar *NameW=NULL);
bool IsDir(uint Attr);
bool IsUnreadable(uint Attr);
bool IsLabel(uint Attr);
bool IsLink(uint Attr);
void SetSFXMode(const char *FileName);
void EraseDiskContents(const char *FileName);
bool IsDeleteAllowed(uint FileAttr);
void PrepareToDelete(const char *Name,const wchar *NameW=NULL);
uint GetFileAttr(const char *Name,const wchar *NameW=NULL);
bool SetFileAttr(const char *Name,const wchar *NameW,uint Attr);
void ConvertNameToFull(const char *Src,char *Dest);
void ConvertNameToFull(const wchar *Src,wchar *Dest);
char* MkTemp(char *Name);
enum CALCCRC_SHOWMODE {CALCCRC_SHOWNONE,CALCCRC_SHOWTEXT,CALCCRC_SHOWALL};
uint CalcFileCRC(File *SrcFile,int64 Size=INT64NDF,CALCCRC_SHOWMODE ShowMode=CALCCRC_SHOWNONE);
bool RenameFile(const char *SrcName,const wchar *SrcNameW,const char *DestName,const wchar *DestNameW);
bool DelFile(const char *Name);
bool DelFile(const char *Name,const wchar *NameW);
bool DelDir(const char *Name);
bool DelDir(const char *Name,const wchar *NameW);
#if defined(_WIN_32) && !defined(_WIN_CE)
bool SetFileCompression(char *Name,wchar *NameW,bool State);
#endif
#endif

189
libunrar/filestr.cpp Normal file
View File

@ -0,0 +1,189 @@
#include "rar.hpp"
static bool IsUnicode(byte *Data,int Size);
bool ReadTextFile(const char *Name,StringList *List,bool Config,
bool AbortOnError,RAR_CHARSET SrcCharset,bool Unquote,
bool SkipComments,bool ExpandEnvStr)
{
char FileName[NM];
if (Config)
GetConfigName(Name,FileName,true);
else
strcpy(FileName,Name);
File SrcFile;
if (*FileName)
{
bool OpenCode=AbortOnError ? SrcFile.WOpen(FileName):SrcFile.Open(FileName);
if (!OpenCode)
{
if (AbortOnError)
ErrHandler.Exit(OPEN_ERROR);
return(false);
}
}
else
SrcFile.SetHandleType(FILE_HANDLESTD);
unsigned int DataSize=0,ReadSize;
const int ReadBlock=1024;
Array<char> Data(ReadBlock+5);
while ((ReadSize=SrcFile.Read(&Data[DataSize],ReadBlock))!=0)
{
DataSize+=ReadSize;
Data.Add(ReadSize);
}
memset(&Data[DataSize],0,5);
if (SrcCharset==RCH_UNICODE ||
SrcCharset==RCH_DEFAULT && IsUnicode((byte *)&Data[0],DataSize))
{
// Unicode in native system format, can be more than 2 bytes per character.
Array<wchar> DataW(Data.Size()/2+1);
for (size_t I=2;I<Data.Size()-1;I+=2)
{
// Need to convert Data to (byte) first to prevent the sign extension
// to higher bytes.
DataW[(I-2)/2]=(wchar)((byte)Data[I])+(wchar)((byte)Data[I+1])*256;
}
wchar *CurStr=&DataW[0];
Array<char> AnsiName;
while (*CurStr!=0)
{
wchar *NextStr=CurStr,*CmtPtr=NULL;
while (*NextStr!='\r' && *NextStr!='\n' && *NextStr!=0)
{
if (SkipComments && NextStr[0]=='/' && NextStr[1]=='/')
{
*NextStr=0;
CmtPtr=NextStr;
}
NextStr++;
}
*NextStr=0;
for (wchar *SpacePtr=(CmtPtr ? CmtPtr:NextStr)-1;SpacePtr>=CurStr;SpacePtr--)
{
if (*SpacePtr!=' ' && *SpacePtr!='\t')
break;
*SpacePtr=0;
}
if (*CurStr)
{
// Length and AddSize must be defined as signed, because AddSize
// can be negative.
int Length=(int)strlenw(CurStr);
int AddSize=4*(Length-(int)AnsiName.Size()+1);
if (AddSize>0)
AnsiName.Add(AddSize);
if (Unquote && *CurStr=='\"' && CurStr[Length-1]=='\"')
{
CurStr[Length-1]=0;
CurStr++;
}
WideToChar(CurStr,&AnsiName[0],AnsiName.Size());
bool Expanded=false;
#if defined(_WIN_32) && !defined(_WIN_CE)
if (ExpandEnvStr && *CurStr=='%')
{
// expanding environment variables in Windows version
char ExpName[NM];
wchar ExpNameW[NM];
*ExpNameW=0;
int ret,retw=1;
ret=ExpandEnvironmentStrings(&AnsiName[0],ExpName,ASIZE(ExpName));
if (ret!=0 && WinNT())
retw=ExpandEnvironmentStringsW(CurStr,ExpNameW,ASIZE(ExpNameW));
Expanded=ret!=0 && ret<ASIZE(ExpName) &&
retw!=0 && retw<ASIZE(ExpNameW);
if (Expanded)
List->AddString(ExpName,ExpNameW);
}
#endif
if (!Expanded)
List->AddString(&AnsiName[0],CurStr);
}
CurStr=NextStr+1;
while (*CurStr=='\r' || *CurStr=='\n')
CurStr++;
}
}
else
{
char *CurStr=&Data[0];
while (*CurStr!=0)
{
char *NextStr=CurStr,*CmtPtr=NULL;
while (*NextStr!='\r' && *NextStr!='\n' && *NextStr!=0)
{
if (SkipComments && NextStr[0]=='/' && NextStr[1]=='/')
{
*NextStr=0;
CmtPtr=NextStr;
}
NextStr++;
}
*NextStr=0;
for (char *SpacePtr=(CmtPtr ? CmtPtr:NextStr)-1;SpacePtr>=CurStr;SpacePtr--)
{
if (*SpacePtr!=' ' && *SpacePtr!='\t')
break;
*SpacePtr=0;
}
if (*CurStr)
{
if (Unquote && *CurStr=='\"')
{
size_t Length=strlen(CurStr);
if (CurStr[Length-1]=='\"')
{
CurStr[Length-1]=0;
CurStr++;
}
}
#if defined(_WIN_32)
if (SrcCharset==RCH_OEM)
OemToChar(CurStr,CurStr);
#endif
bool Expanded=false;
#if defined(_WIN_32) && !defined(_WIN_CE)
if (ExpandEnvStr && *CurStr=='%')
{
// expanding environment variables in Windows version
char ExpName[NM];
int ret=ExpandEnvironmentStrings(CurStr,ExpName,ASIZE(ExpName));
Expanded=ret!=0 && ret<ASIZE(ExpName);
if (Expanded)
List->AddString(ExpName);
}
#endif
if (!Expanded)
List->AddString(CurStr);
}
CurStr=NextStr+1;
while (*CurStr=='\r' || *CurStr=='\n')
CurStr++;
}
}
return(true);
}
bool IsUnicode(byte *Data,int Size)
{
if (Size<4 || Data[0]!=0xff || Data[1]!=0xfe)
return(false);
for (int I=2;I<Size;I++)
if (Data[I]<32 && Data[I]!='\r' && Data[I]!='\n')
return(true);
return(false);
}

9
libunrar/filestr.hpp Normal file
View File

@ -0,0 +1,9 @@
#ifndef _RAR_FILESTR_
#define _RAR_FILESTR_
bool ReadTextFile(const char *Name,StringList *List,bool Config,
bool AbortOnError=false,RAR_CHARSET SrcCharset=RCH_DEFAULT,
bool Unquote=false,bool SkipComments=false,
bool ExpandEnvStr=false);
#endif

299
libunrar/find.cpp Normal file
View File

@ -0,0 +1,299 @@
#include "rar.hpp"
FindFile::FindFile()
{
*FindMask=0;
*FindMaskW=0;
FirstCall=true;
#ifdef _WIN_32
hFind=INVALID_HANDLE_VALUE;
#else
dirp=NULL;
#endif
}
FindFile::~FindFile()
{
#ifdef _WIN_32
if (hFind!=INVALID_HANDLE_VALUE)
FindClose(hFind);
#else
if (dirp!=NULL)
closedir(dirp);
#endif
}
void FindFile::SetMask(const char *FindMask)
{
strcpy(FindFile::FindMask,FindMask);
if (*FindMaskW==0)
CharToWide(FindMask,FindMaskW);
FirstCall=true;
}
void FindFile::SetMaskW(const wchar *FindMaskW)
{
if (FindMaskW==NULL)
return;
strcpyw(FindFile::FindMaskW,FindMaskW);
if (*FindMask==0)
WideToChar(FindMaskW,FindMask);
FirstCall=true;
}
bool FindFile::Next(struct FindData *fd,bool GetSymLink)
{
fd->Error=false;
if (*FindMask==0)
return(false);
#ifdef _WIN_32
if (FirstCall)
{
if ((hFind=Win32Find(INVALID_HANDLE_VALUE,FindMask,FindMaskW,fd))==INVALID_HANDLE_VALUE)
return(false);
}
else
if (Win32Find(hFind,FindMask,FindMaskW,fd)==INVALID_HANDLE_VALUE)
return(false);
#else
if (FirstCall)
{
char DirName[NM];
strcpy(DirName,FindMask);
RemoveNameFromPath(DirName);
if (*DirName==0)
strcpy(DirName,".");
/*
else
{
int Length=strlen(DirName);
if (Length>1 && DirName[Length-1]==CPATHDIVIDER && (Length!=3 || !IsDriveDiv(DirName[1])))
DirName[Length-1]=0;
}
*/
if ((dirp=opendir(DirName))==NULL)
{
fd->Error=(errno!=ENOENT);
return(false);
}
}
while (1)
{
struct dirent *ent=readdir(dirp);
if (ent==NULL)
return(false);
if (strcmp(ent->d_name,".")==0 || strcmp(ent->d_name,"..")==0)
continue;
if (CmpName(FindMask,ent->d_name,MATCH_NAMES))
{
char FullName[NM];
strcpy(FullName,FindMask);
*PointToName(FullName)=0;
if (strlen(FullName)+strlen(ent->d_name)>=ASIZE(FullName)-1)
{
#ifndef SILENT
Log(NULL,"\n%s%s",FullName,ent->d_name);
Log(NULL,St(MPathTooLong));
#endif
return(false);
}
strcat(FullName,ent->d_name);
if (!FastFind(FullName,NULL,fd,GetSymLink))
{
ErrHandler.OpenErrorMsg(FullName);
continue;
}
strcpy(fd->Name,FullName);
break;
}
}
*fd->NameW=0;
#ifdef _APPLE
if (!LowAscii(fd->Name))
UtfToWide(fd->Name,fd->NameW,sizeof(fd->NameW));
#elif defined(UNICODE_SUPPORTED)
if (!LowAscii(fd->Name) && UnicodeEnabled())
CharToWide(fd->Name,fd->NameW);
#endif
#endif
fd->Flags=0;
fd->IsDir=IsDir(fd->FileAttr);
FirstCall=false;
char *Name=PointToName(fd->Name);
if (strcmp(Name,".")==0 || strcmp(Name,"..")==0)
return(Next(fd));
return(true);
}
bool FindFile::FastFind(const char *FindMask,const wchar *FindMaskW,struct FindData *fd,bool GetSymLink)
{
fd->Error=false;
#ifndef _UNIX
if (IsWildcard(FindMask,FindMaskW))
return(false);
#endif
#ifdef _WIN_32
HANDLE hFind=Win32Find(INVALID_HANDLE_VALUE,FindMask,FindMaskW,fd);
if (hFind==INVALID_HANDLE_VALUE)
return(false);
FindClose(hFind);
#else
struct stat st;
if (GetSymLink)
{
#ifdef SAVE_LINKS
if (lstat(FindMask,&st)!=0)
#else
if (stat(FindMask,&st)!=0)
#endif
{
fd->Error=(errno!=ENOENT);
return(false);
}
}
else
if (stat(FindMask,&st)!=0)
{
fd->Error=(errno!=ENOENT);
return(false);
}
#ifdef _DJGPP
fd->FileAttr=_chmod(FindMask,0);
#elif defined(_EMX)
fd->FileAttr=st.st_attr;
#else
fd->FileAttr=st.st_mode;
#endif
fd->IsDir=IsDir(st.st_mode);
fd->Size=st.st_size;
fd->mtime=st.st_mtime;
fd->atime=st.st_atime;
fd->ctime=st.st_ctime;
fd->FileTime=fd->mtime.GetDos();
strcpy(fd->Name,FindMask);
*fd->NameW=0;
#ifdef _APPLE
if (!LowAscii(fd->Name))
UtfToWide(fd->Name,fd->NameW,sizeof(fd->NameW));
#elif defined(UNICODE_SUPPORTED)
if (!LowAscii(fd->Name) && UnicodeEnabled())
CharToWide(fd->Name,fd->NameW);
#endif
#endif
fd->Flags=0;
fd->IsDir=IsDir(fd->FileAttr);
return(true);
}
#ifdef _WIN_32
HANDLE FindFile::Win32Find(HANDLE hFind,const char *Mask,const wchar *MaskW,struct FindData *fd)
{
#ifndef _WIN_CE
if (WinNT())
#endif
{
wchar WideMask[NM];
if (MaskW!=NULL && *MaskW!=0)
strcpyw(WideMask,MaskW);
else
CharToWide(Mask,WideMask);
WIN32_FIND_DATAW FindData;
if (hFind==INVALID_HANDLE_VALUE)
{
hFind=FindFirstFileW(WideMask,&FindData);
if (hFind==INVALID_HANDLE_VALUE)
{
int SysErr=GetLastError();
fd->Error=(SysErr!=ERROR_FILE_NOT_FOUND &&
SysErr!=ERROR_PATH_NOT_FOUND &&
SysErr!=ERROR_NO_MORE_FILES);
}
}
else
if (!FindNextFileW(hFind,&FindData))
{
hFind=INVALID_HANDLE_VALUE;
fd->Error=GetLastError()!=ERROR_NO_MORE_FILES;
}
if (hFind!=INVALID_HANDLE_VALUE)
{
strcpyw(fd->NameW,WideMask);
strcpyw(PointToName(fd->NameW),FindData.cFileName);
WideToChar(fd->NameW,fd->Name);
fd->Size=INT32TO64(FindData.nFileSizeHigh,FindData.nFileSizeLow);
fd->FileAttr=FindData.dwFileAttributes;
WideToChar(FindData.cAlternateFileName,fd->ShortName);
fd->ftCreationTime=FindData.ftCreationTime;
fd->ftLastAccessTime=FindData.ftLastAccessTime;
fd->ftLastWriteTime=FindData.ftLastWriteTime;
fd->mtime=FindData.ftLastWriteTime;
fd->ctime=FindData.ftCreationTime;
fd->atime=FindData.ftLastAccessTime;
fd->FileTime=fd->mtime.GetDos();
#ifndef _WIN_CE
if (LowAscii(fd->NameW))
*fd->NameW=0;
#endif
}
}
#ifndef _WIN_CE
else
{
char CharMask[NM];
if (Mask!=NULL && *Mask!=0)
strcpy(CharMask,Mask);
else
WideToChar(MaskW,CharMask);
WIN32_FIND_DATA FindData;
if (hFind==INVALID_HANDLE_VALUE)
{
hFind=FindFirstFile(CharMask,&FindData);
if (hFind==INVALID_HANDLE_VALUE)
{
int SysErr=GetLastError();
fd->Error=SysErr!=ERROR_FILE_NOT_FOUND && SysErr!=ERROR_PATH_NOT_FOUND;
}
}
else
if (!FindNextFile(hFind,&FindData))
{
hFind=INVALID_HANDLE_VALUE;
fd->Error=GetLastError()!=ERROR_NO_MORE_FILES;
}
if (hFind!=INVALID_HANDLE_VALUE)
{
strcpy(fd->Name,CharMask);
strcpy(PointToName(fd->Name),FindData.cFileName);
CharToWide(fd->Name,fd->NameW);
fd->Size=INT32TO64(FindData.nFileSizeHigh,FindData.nFileSizeLow);
fd->FileAttr=FindData.dwFileAttributes;
strcpy(fd->ShortName,FindData.cAlternateFileName);
fd->ftCreationTime=FindData.ftCreationTime;
fd->ftLastAccessTime=FindData.ftLastAccessTime;
fd->ftLastWriteTime=FindData.ftLastWriteTime;
fd->mtime=FindData.ftLastWriteTime;
fd->ctime=FindData.ftCreationTime;
fd->atime=FindData.ftLastAccessTime;
fd->FileTime=fd->mtime.GetDos();
if (LowAscii(fd->Name))
*fd->NameW=0;
}
}
#endif
fd->Flags=0;
return(hFind);
}
#endif

53
libunrar/find.hpp Normal file
View File

@ -0,0 +1,53 @@
#ifndef _RAR_FINDDATA_
#define _RAR_FINDDATA_
enum FINDDATA_FLAGS {
FDDF_SECONDDIR=1 // Second encounter of same directory in SCAN_GETDIRSTWICE ScanTree mode
};
struct FindData
{
char Name[NM];
wchar NameW[NM];
int64 Size;
uint FileAttr;
uint FileTime;
bool IsDir;
RarTime mtime;
RarTime ctime;
RarTime atime;
#ifdef _WIN_32
char ShortName[NM];
FILETIME ftCreationTime;
FILETIME ftLastAccessTime;
FILETIME ftLastWriteTime;
#endif
uint Flags;
bool Error;
};
class FindFile
{
private:
#ifdef _WIN_32
static HANDLE Win32Find(HANDLE hFind,const char *Mask,const wchar *MaskW,struct FindData *fd);
#endif
char FindMask[NM];
wchar FindMaskW[NM];
bool FirstCall;
#ifdef _WIN_32
HANDLE hFind;
#else
DIR *dirp;
#endif
public:
FindFile();
~FindFile();
void SetMask(const char *FindMask);
void SetMaskW(const wchar *FindMaskW);
bool Next(struct FindData *fd,bool GetSymLink=false);
static bool FastFind(const char *FindMask,const wchar *FindMaskW,struct FindData *fd,bool GetSymLink=false);
};
#endif

30
libunrar/getbits.cpp Normal file
View File

@ -0,0 +1,30 @@
#include "rar.hpp"
BitInput::BitInput()
{
// getbits attempts to read data from InAddr, InAddr+1, InAddr+2 positions.
// So let's allocate two additional bytes for situation, when we need to
// read only 1 byte from the last position of buffer and avoid a crash
// from access to next 2 bytes, which contents we do not need.
InBuf=new byte[MAX_SIZE+2];
}
BitInput::~BitInput()
{
delete[] InBuf;
}
void BitInput::faddbits(uint Bits)
{
// Function wrapped version of inline addbits to save code size.
addbits(Bits);
}
uint BitInput::fgetbits()
{
// Function wrapped version of inline getbits to save code size.
return(getbits());
}

51
libunrar/getbits.hpp Normal file
View File

@ -0,0 +1,51 @@
#ifndef _RAR_GETBITS_
#define _RAR_GETBITS_
class BitInput
{
public:
enum BufferSize {MAX_SIZE=0x8000}; // Size of input buffer.
protected:
int InAddr; // Curent byte position in the buffer.
int InBit; // Current bit position in the current byte.
public:
BitInput();
~BitInput();
byte *InBuf; // Dynamically allocated input buffer.
void InitBitInput()
{
InAddr=InBit=0;
}
// Move forward by 'Bits' bits.
void addbits(uint Bits)
{
Bits+=InBit;
InAddr+=Bits>>3;
InBit=Bits&7;
}
// Return 16 bits from current position in the buffer.
// Bit at (InAddr,InBit) has the highest position in returning data.
uint getbits()
{
uint BitField=(uint)InBuf[InAddr] << 16;
BitField|=(uint)InBuf[InAddr+1] << 8;
BitField|=(uint)InBuf[InAddr+2];
BitField >>= (8-InBit);
return(BitField & 0xffff);
}
void faddbits(uint Bits);
uint fgetbits();
// Check if buffer has enough space for IncPtr bytes. Returns 'true'
// if buffer will be overflown.
bool Overflow(uint IncPtr)
{
return(InAddr+IncPtr>=MAX_SIZE);
}
};
#endif

4
libunrar/global.cpp Normal file
View File

@ -0,0 +1,4 @@
#define INCLUDEGLOBAL
#include "rar.hpp"

14
libunrar/global.hpp Normal file
View File

@ -0,0 +1,14 @@
#ifndef _RAR_GLOBAL_
#define _RAR_GLOBAL_
#ifdef INCLUDEGLOBAL
#define EXTVAR
#else
#define EXTVAR extern
#endif
EXTVAR ErrorHandler ErrHandler;
#endif

308
libunrar/headers.hpp Normal file
View File

@ -0,0 +1,308 @@
#ifndef _RAR_HEADERS_
#define _RAR_HEADERS_
#define SIZEOF_MARKHEAD 7
#define SIZEOF_OLDMHD 7
#define SIZEOF_NEWMHD 13
#define SIZEOF_OLDLHD 21
#define SIZEOF_NEWLHD 32
#define SIZEOF_SHORTBLOCKHEAD 7
#define SIZEOF_LONGBLOCKHEAD 11
#define SIZEOF_SUBBLOCKHEAD 14
#define SIZEOF_COMMHEAD 13
#define SIZEOF_PROTECTHEAD 26
#define SIZEOF_AVHEAD 14
#define SIZEOF_SIGNHEAD 15
#define SIZEOF_UOHEAD 18
#define SIZEOF_MACHEAD 22
#define SIZEOF_EAHEAD 24
#define SIZEOF_BEEAHEAD 24
#define SIZEOF_STREAMHEAD 26
#define PACK_VER 29
#define PACK_CRYPT_VER 29
#define UNP_VER 36
#define CRYPT_VER 29
#define AV_VER 20
#define PROTECT_VER 20
#define MHD_VOLUME 0x0001U
#define MHD_COMMENT 0x0002U
#define MHD_LOCK 0x0004U
#define MHD_SOLID 0x0008U
#define MHD_PACK_COMMENT 0x0010U
#define MHD_NEWNUMBERING 0x0010U
#define MHD_AV 0x0020U
#define MHD_PROTECT 0x0040U
#define MHD_PASSWORD 0x0080U
#define MHD_FIRSTVOLUME 0x0100U
#define MHD_ENCRYPTVER 0x0200U
#define LHD_SPLIT_BEFORE 0x0001U
#define LHD_SPLIT_AFTER 0x0002U
#define LHD_PASSWORD 0x0004U
#define LHD_COMMENT 0x0008U
#define LHD_SOLID 0x0010U
#define LHD_WINDOWMASK 0x00e0U
#define LHD_WINDOW64 0x0000U
#define LHD_WINDOW128 0x0020U
#define LHD_WINDOW256 0x0040U
#define LHD_WINDOW512 0x0060U
#define LHD_WINDOW1024 0x0080U
#define LHD_WINDOW2048 0x00a0U
#define LHD_WINDOW4096 0x00c0U
#define LHD_DIRECTORY 0x00e0U
#define LHD_LARGE 0x0100U
#define LHD_UNICODE 0x0200U
#define LHD_SALT 0x0400U
#define LHD_VERSION 0x0800U
#define LHD_EXTTIME 0x1000U
#define LHD_EXTFLAGS 0x2000U
#define SKIP_IF_UNKNOWN 0x4000U
#define LONG_BLOCK 0x8000U
#define EARC_NEXT_VOLUME 0x0001U // not last volume
#define EARC_DATACRC 0x0002U // store CRC32 of RAR archive (now used only in volumes)
#define EARC_REVSPACE 0x0004U // reserve space for end of REV file 7 byte record
#define EARC_VOLNUMBER 0x0008U // store a number of current volume
enum HEADER_TYPE {
MARK_HEAD=0x72,MAIN_HEAD=0x73,FILE_HEAD=0x74,COMM_HEAD=0x75,AV_HEAD=0x76,
SUB_HEAD=0x77,PROTECT_HEAD=0x78,SIGN_HEAD=0x79,NEWSUB_HEAD=0x7a,
ENDARC_HEAD=0x7b
};
enum { EA_HEAD=0x100,UO_HEAD=0x101,MAC_HEAD=0x102,BEEA_HEAD=0x103,
NTACL_HEAD=0x104,STREAM_HEAD=0x105 };
enum HOST_SYSTEM {
HOST_MSDOS=0,HOST_OS2=1,HOST_WIN32=2,HOST_UNIX=3,HOST_MACOS=4,
HOST_BEOS=5,HOST_MAX
};
#define SUBHEAD_TYPE_CMT "CMT"
#define SUBHEAD_TYPE_ACL "ACL"
#define SUBHEAD_TYPE_STREAM "STM"
#define SUBHEAD_TYPE_UOWNER "UOW"
#define SUBHEAD_TYPE_AV "AV"
#define SUBHEAD_TYPE_RR "RR"
#define SUBHEAD_TYPE_OS2EA "EA2"
#define SUBHEAD_TYPE_BEOSEA "EABE"
/* new file inherits a subblock when updating a host file */
#define SUBHEAD_FLAGS_INHERITED 0x80000000
#define SUBHEAD_FLAGS_CMT_UNICODE 0x00000001
struct OldMainHeader
{
byte Mark[4];
ushort HeadSize;
byte Flags;
};
struct OldFileHeader
{
uint PackSize;
uint UnpSize;
ushort FileCRC;
ushort HeadSize;
uint FileTime;
byte FileAttr;
byte Flags;
byte UnpVer;
byte NameSize;
byte Method;
};
struct MarkHeader
{
byte Mark[7];
};
struct BaseBlock
{
ushort HeadCRC;
HEADER_TYPE HeadType;//byte
ushort Flags;
ushort HeadSize;
bool IsSubBlock()
{
if (HeadType==SUB_HEAD)
return(true);
if (HeadType==NEWSUB_HEAD && (Flags & LHD_SOLID)!=0)
return(true);
return(false);
}
};
struct BlockHeader:BaseBlock
{
union {
uint DataSize;
uint PackSize;
};
};
struct MainHeader:BaseBlock
{
ushort HighPosAV;
uint PosAV;
byte EncryptVer;
};
#define SALT_SIZE 8
struct FileHeader:BlockHeader
{
uint UnpSize;
byte HostOS;
uint FileCRC;
uint FileTime;
byte UnpVer;
byte Method;
ushort NameSize;
union {
uint FileAttr;
uint SubFlags;
};
/* optional */
uint HighPackSize;
uint HighUnpSize;
/* names */
char FileName[NM];
wchar FileNameW[NM];
/* optional */
Array<byte> SubData;
byte Salt[SALT_SIZE];
RarTime mtime;
RarTime ctime;
RarTime atime;
RarTime arctime;
/* dummy */
int64 FullPackSize;
int64 FullUnpSize;
void Clear(size_t SubDataSize)
{
SubData.Alloc(SubDataSize);
Flags=LONG_BLOCK;
SubFlags=0;
}
bool CmpName(const char *Name)
{
return(strcmp(FileName,Name)==0);
}
FileHeader& operator = (FileHeader &hd)
{
SubData.Reset();
memcpy(this,&hd,sizeof(*this));
SubData.CleanData();
SubData=hd.SubData;
return(*this);
}
};
struct EndArcHeader:BaseBlock
{
uint ArcDataCRC; // optional archive CRC32
ushort VolNumber; // optional current volume number
};
// SubBlockHeader and its successors were used in RAR 2.x format.
// RAR 3.x uses FileHeader with NEWSUB_HEAD HeadType for subblocks.
struct SubBlockHeader:BlockHeader
{
ushort SubType;
byte Level;
};
struct CommentHeader:BaseBlock
{
ushort UnpSize;
byte UnpVer;
byte Method;
ushort CommCRC;
};
struct ProtectHeader:BlockHeader
{
byte Version;
ushort RecSectors;
uint TotalBlocks;
byte Mark[8];
};
struct AVHeader:BaseBlock
{
byte UnpVer;
byte Method;
byte AVVer;
uint AVInfoCRC;
};
struct SignHeader:BaseBlock
{
uint CreationTime;
ushort ArcNameSize;
ushort UserNameSize;
};
struct UnixOwnersHeader:SubBlockHeader
{
ushort OwnerNameSize;
ushort GroupNameSize;
/* dummy */
char OwnerName[NM];
char GroupName[NM];
};
struct EAHeader:SubBlockHeader
{
uint UnpSize;
byte UnpVer;
byte Method;
uint EACRC;
};
struct StreamHeader:SubBlockHeader
{
uint UnpSize;
byte UnpVer;
byte Method;
uint StreamCRC;
ushort StreamNameSize;
/* dummy */
byte StreamName[NM];
};
struct MacFInfoHeader:SubBlockHeader
{
uint fileType;
uint fileCreator;
};
#endif

17
libunrar/isnt.cpp Normal file
View File

@ -0,0 +1,17 @@
#include "rar.hpp"
#ifdef _WIN_32
int WinNT()
{
static int dwPlatformId=-1,dwMajorVersion;
if (dwPlatformId==-1)
{
OSVERSIONINFO WinVer;
WinVer.dwOSVersionInfoSize=sizeof(WinVer);
GetVersionEx(&WinVer);
dwPlatformId=WinVer.dwPlatformId;
dwMajorVersion=WinVer.dwMajorVersion;
}
return(dwPlatformId==VER_PLATFORM_WIN32_NT ? dwMajorVersion:0);
}
#endif

6
libunrar/isnt.hpp Normal file
View File

@ -0,0 +1,6 @@
#ifndef _RAR_ISNT_
#define _RAR_ISNT_
int WinNT();
#endif

40
libunrar/license.txt Normal file
View File

@ -0,0 +1,40 @@
****** ***** ****** UnRAR - free utility for RAR archives
** ** ** ** ** ** ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
****** ******* ****** License for use and distribution of
** ** ** ** ** ** ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
** ** ** ** ** ** FREE portable version
~~~~~~~~~~~~~~~~~~~~~
The source code of UnRAR utility is freeware. This means:
1. All copyrights to RAR and the utility UnRAR are exclusively
owned by the author - Alexander Roshal.
2. The UnRAR sources may be used in any software to handle RAR
archives without limitations free of charge, but cannot be used
to re-create the RAR compression algorithm, which is proprietary.
Distribution of modified UnRAR sources in separate form or as a
part of other software is permitted, provided that it is clearly
stated in the documentation and source comments that the code may
not be used to develop a RAR (WinRAR) compatible archiver.
3. The UnRAR utility may be freely distributed. It is allowed
to distribute UnRAR inside of other software packages.
4. THE RAR ARCHIVER AND THE UnRAR UTILITY ARE DISTRIBUTED "AS IS".
NO WARRANTY OF ANY KIND IS EXPRESSED OR IMPLIED. YOU USE AT
YOUR OWN RISK. THE AUTHOR WILL NOT BE LIABLE FOR DATA LOSS,
DAMAGES, LOSS OF PROFITS OR ANY OTHER KIND OF LOSS WHILE USING
OR MISUSING THIS SOFTWARE.
5. Installing and using the UnRAR utility signifies acceptance of
these terms and conditions of the license.
6. If you don't agree with terms of the license you must remove
UnRAR files from your storage devices and cease to use the
utility.
Thank you for your interest in RAR and UnRAR.
Alexander L. Roshal

396
libunrar/list.cpp Normal file
View File

@ -0,0 +1,396 @@
#include "rar.hpp"
static void ListFileHeader(FileHeader &hd,bool Verbose,bool Technical,bool &TitleShown,bool Bare);
static void ListSymLink(Archive &Arc);
static void ListFileAttr(uint A,int HostOS);
static void ListOldSubHeader(Archive &Arc);
static void ListNewSubHeader(CommandData *Cmd,Archive &Arc,bool Technical);
void ListArchive(CommandData *Cmd)
{
int64 SumPackSize=0,SumUnpSize=0;
uint ArcCount=0,SumFileCount=0;
bool Technical=(Cmd->Command[1]=='T');
bool Bare=(Cmd->Command[1]=='B');
bool Verbose=(*Cmd->Command=='V');
char ArcName[NM];
wchar ArcNameW[NM];
while (Cmd->GetArcName(ArcName,ArcNameW,sizeof(ArcName)))
{
Archive Arc(Cmd);
#ifdef _WIN_32
Arc.RemoveSequentialFlag();
#endif
if (!Arc.WOpen(ArcName,ArcNameW))
continue;
bool FileMatched=true;
while (1)
{
int64 TotalPackSize=0,TotalUnpSize=0;
uint FileCount=0;
if (Arc.IsArchive(true))
{
if (!Arc.IsOpened())
break;
bool TitleShown=false;
if (!Bare)
{
Arc.ViewComment();
// RAR can close a corrupt encrypted archive
if (!Arc.IsOpened())
break;
mprintf("\n");
if (Arc.Solid)
mprintf(St(MListSolid));
if (Arc.SFXSize>0)
mprintf(St(MListSFX));
if (Arc.Volume)
if (Arc.Solid)
mprintf(St(MListVol1));
else
mprintf(St(MListVol2));
else
if (Arc.Solid)
mprintf(St(MListArc1));
else
mprintf(St(MListArc2));
mprintf(" %s\n",Arc.FileName);
if (Technical)
{
if (Arc.Protected)
mprintf(St(MListRecRec));
if (Arc.Locked)
mprintf(St(MListLock));
}
}
while(Arc.ReadHeader()>0)
{
int HeaderType=Arc.GetHeaderType();
if (HeaderType==ENDARC_HEAD)
break;
switch(HeaderType)
{
case FILE_HEAD:
IntToExt(Arc.NewLhd.FileName,Arc.NewLhd.FileName);
FileMatched=Cmd->IsProcessFile(Arc.NewLhd)!=0;
if (FileMatched)
{
ListFileHeader(Arc.NewLhd,Verbose,Technical,TitleShown,Bare);
if (!(Arc.NewLhd.Flags & LHD_SPLIT_BEFORE))
{
TotalUnpSize+=Arc.NewLhd.FullUnpSize;
FileCount++;
}
TotalPackSize+=Arc.NewLhd.FullPackSize;
if (Technical)
ListSymLink(Arc);
#ifndef SFX_MODULE
if (Verbose)
Arc.ViewFileComment();
#endif
}
break;
#ifndef SFX_MODULE
case SUB_HEAD:
if (Technical && FileMatched && !Bare)
ListOldSubHeader(Arc);
break;
#endif
case NEWSUB_HEAD:
if (FileMatched && !Bare)
{
if (Technical)
ListFileHeader(Arc.SubHead,Verbose,true,TitleShown,false);
ListNewSubHeader(Cmd,Arc,Technical);
}
break;
}
Arc.SeekToNext();
}
if (!Bare)
if (TitleShown)
{
mprintf("\n");
for (int I=0;I<79;I++)
mprintf("-");
char UnpSizeText[20];
itoa(TotalUnpSize,UnpSizeText);
char PackSizeText[20];
itoa(TotalPackSize,PackSizeText);
mprintf("\n%5lu %16s %8s %3d%%",FileCount,UnpSizeText,
PackSizeText,ToPercentUnlim(TotalPackSize,TotalUnpSize));
SumFileCount+=FileCount;
SumUnpSize+=TotalUnpSize;
SumPackSize+=TotalPackSize;
#ifndef SFX_MODULE
if (Arc.EndArcHead.Flags & EARC_VOLNUMBER)
{
mprintf(" ");
mprintf(St(MVolumeNumber),Arc.EndArcHead.VolNumber+1);
}
#endif
mprintf("\n");
}
else
mprintf(St(MListNoFiles));
ArcCount++;
#ifndef NOVOLUME
if (Cmd->VolSize!=0 && ((Arc.NewLhd.Flags & LHD_SPLIT_AFTER) ||
Arc.GetHeaderType()==ENDARC_HEAD &&
(Arc.EndArcHead.Flags & EARC_NEXT_VOLUME)!=0) &&
MergeArchive(Arc,NULL,false,*Cmd->Command))
{
Arc.Seek(0,SEEK_SET);
}
else
#endif
break;
}
else
{
if (Cmd->ArcNames->ItemsCount()<2 && !Bare)
mprintf(St(MNotRAR),Arc.FileName);
break;
}
}
}
if (ArcCount>1 && !Bare)
{
char UnpSizeText[20],PackSizeText[20];
itoa(SumUnpSize,UnpSizeText);
itoa(SumPackSize,PackSizeText);
mprintf("\n%5lu %16s %8s %3d%%\n",SumFileCount,UnpSizeText,
PackSizeText,ToPercentUnlim(SumPackSize,SumUnpSize));
}
}
void ListFileHeader(FileHeader &hd,bool Verbose,bool Technical,bool &TitleShown,bool Bare)
{
if (!Bare)
{
if (!TitleShown)
{
if (Verbose)
mprintf(St(MListPathComm));
else
mprintf(St(MListName));
mprintf(St(MListTitle));
if (Technical)
mprintf(St(MListTechTitle));
for (int I=0;I<79;I++)
mprintf("-");
TitleShown=true;
}
if (hd.HeadType==NEWSUB_HEAD)
mprintf(St(MSubHeadType),hd.FileName);
mprintf("\n%c",(hd.Flags & LHD_PASSWORD) ? '*' : ' ');
}
char *Name=hd.FileName;
#ifdef UNICODE_SUPPORTED
char ConvertedName[NM];
if ((hd.Flags & LHD_UNICODE)!=0 && *hd.FileNameW!=0 && UnicodeEnabled())
{
if (WideToChar(hd.FileNameW,ConvertedName) && *ConvertedName!=0)
Name=ConvertedName;
}
#endif
if (Bare)
{
mprintf("%s\n",Verbose ? Name:PointToName(Name));
return;
}
if (Verbose)
mprintf("%s\n%12s ",Name,"");
else
mprintf("%-12s",PointToName(Name));
char UnpSizeText[20],PackSizeText[20];
if (hd.FullUnpSize==INT64NDF)
strcpy(UnpSizeText,"?");
else
itoa(hd.FullUnpSize,UnpSizeText);
itoa(hd.FullPackSize,PackSizeText);
mprintf(" %8s %8s ",UnpSizeText,PackSizeText);
if ((hd.Flags & LHD_SPLIT_BEFORE) && (hd.Flags & LHD_SPLIT_AFTER))
mprintf(" <->");
else
if (hd.Flags & LHD_SPLIT_BEFORE)
mprintf(" <--");
else
if (hd.Flags & LHD_SPLIT_AFTER)
mprintf(" -->");
else
mprintf("%3d%%",ToPercentUnlim(hd.FullPackSize,hd.FullUnpSize));
char DateStr[50];
hd.mtime.GetText(DateStr,false);
mprintf(" %s ",DateStr);
if (hd.HeadType==NEWSUB_HEAD)
mprintf(" %c....B ",(hd.SubFlags & SUBHEAD_FLAGS_INHERITED) ? 'I' : '.');
else
ListFileAttr(hd.FileAttr,hd.HostOS);
mprintf(" %8.8X",hd.FileCRC);
mprintf(" m%d",hd.Method-0x30);
if ((hd.Flags & LHD_WINDOWMASK)<=6*32)
mprintf("%c",((hd.Flags&LHD_WINDOWMASK)>>5)+'a');
else
mprintf(" ");
mprintf(" %d.%d",hd.UnpVer/10,hd.UnpVer%10);
static const char *RarOS[]={
"DOS","OS/2","Win95/NT","Unix","MacOS","BeOS","WinCE","","",""
};
if (Technical)
mprintf("\n%22s %8s %4s",
(hd.HostOS<sizeof(RarOS)/sizeof(RarOS[0]) ? RarOS[hd.HostOS]:""),
(hd.Flags & LHD_SOLID) ? St(MYes):St(MNo),
(hd.Flags & LHD_VERSION) ? St(MYes):St(MNo));
}
void ListSymLink(Archive &Arc)
{
if (Arc.NewLhd.HostOS==HOST_UNIX && (Arc.NewLhd.FileAttr & 0xF000)==0xA000)
if ((Arc.NewLhd.Flags & LHD_PASSWORD)==0)
{
char FileName[NM];
int DataSize=Min(Arc.NewLhd.PackSize,sizeof(FileName)-1);
Arc.Read(FileName,DataSize);
FileName[DataSize]=0;
mprintf("\n%22s %s","-->",FileName);
}
else
{
// Link data are encrypted. We would need to ask for password
// and initialize decryption routine to display the link target.
mprintf("\n%22s %s","-->","*<-?->");
}
}
void ListFileAttr(uint A,int HostOS)
{
switch(HostOS)
{
case HOST_MSDOS:
case HOST_OS2:
case HOST_WIN32:
case HOST_MACOS:
mprintf(" %c%c%c%c%c%c%c ",
(A & 0x08) ? 'V' : '.',
(A & 0x10) ? 'D' : '.',
(A & 0x01) ? 'R' : '.',
(A & 0x02) ? 'H' : '.',
(A & 0x04) ? 'S' : '.',
(A & 0x20) ? 'A' : '.',
(A & 0x800) ? 'C' : '.');
break;
case HOST_UNIX:
case HOST_BEOS:
switch (A & 0xF000)
{
case 0x4000:
mprintf("d");
break;
case 0xA000:
mprintf("l");
break;
default:
mprintf("-");
break;
}
mprintf("%c%c%c%c%c%c%c%c%c",
(A & 0x0100) ? 'r' : '-',
(A & 0x0080) ? 'w' : '-',
(A & 0x0040) ? ((A & 0x0800) ? 's':'x'):((A & 0x0800) ? 'S':'-'),
(A & 0x0020) ? 'r' : '-',
(A & 0x0010) ? 'w' : '-',
(A & 0x0008) ? ((A & 0x0400) ? 's':'x'):((A & 0x0400) ? 'S':'-'),
(A & 0x0004) ? 'r' : '-',
(A & 0x0002) ? 'w' : '-',
(A & 0x0001) ? 'x' : '-');
break;
}
}
#ifndef SFX_MODULE
void ListOldSubHeader(Archive &Arc)
{
switch(Arc.SubBlockHead.SubType)
{
case EA_HEAD:
mprintf(St(MListEAHead));
break;
case UO_HEAD:
mprintf(St(MListUOHead),Arc.UOHead.OwnerName,Arc.UOHead.GroupName);
break;
case MAC_HEAD:
mprintf(St(MListMACHead1),Arc.MACHead.fileType>>24,Arc.MACHead.fileType>>16,Arc.MACHead.fileType>>8,Arc.MACHead.fileType);
mprintf(St(MListMACHead2),Arc.MACHead.fileCreator>>24,Arc.MACHead.fileCreator>>16,Arc.MACHead.fileCreator>>8,Arc.MACHead.fileCreator);
break;
case BEEA_HEAD:
mprintf(St(MListBeEAHead));
break;
case NTACL_HEAD:
mprintf(St(MListNTACLHead));
break;
case STREAM_HEAD:
mprintf(St(MListStrmHead),Arc.StreamHead.StreamName);
break;
default:
mprintf(St(MListUnkHead),Arc.SubBlockHead.SubType);
break;
}
}
#endif
void ListNewSubHeader(CommandData *Cmd,Archive &Arc,bool Technical)
{
if (Arc.SubHead.CmpName(SUBHEAD_TYPE_CMT) &&
(Arc.SubHead.Flags & LHD_SPLIT_BEFORE)==0 && !Cmd->DisableComment)
{
Array<byte> CmtData;
size_t ReadSize=Arc.ReadCommentData(&CmtData,NULL);
if (ReadSize!=0)
{
mprintf(St(MFileComment));
OutComment((char *)&CmtData[0],ReadSize);
}
}
if (Arc.SubHead.CmpName(SUBHEAD_TYPE_STREAM) &&
(Arc.SubHead.Flags & LHD_SPLIT_BEFORE)==0)
{
size_t DestSize=Arc.SubHead.SubData.Size()/2;
wchar DestNameW[NM];
char DestName[NM];
if (DestSize<sizeof(DestName))
{
RawToWide(&Arc.SubHead.SubData[0],DestNameW,DestSize);
DestNameW[DestSize]=0;
WideToChar(DestNameW,DestName);
mprintf("\n %s",DestName);
}
}
}

6
libunrar/list.hpp Normal file
View File

@ -0,0 +1,6 @@
#ifndef _RAR_LIST_
#define _RAR_LIST_
void ListArchive(CommandData *Cmd);
#endif

354
libunrar/loclang.hpp Normal file
View File

@ -0,0 +1,354 @@
#define MYesNo "_Yes_No"
#define MYesNoAll "_Yes_No_All"
#define MYesNoAllQ "_Yes_No_All_nEver_Quit"
#define MYesNoAllRenQ "_Yes_No_All_nEver_Rename_Quit"
#define MContinueQuit "_Continue_Quit"
#define MRetryAbort "_Retry_Abort"
#define MCopyright "\nRAR %s Copyright (c) 1993-%d Alexander Roshal %d %s %d"
#define MRegTo "\nRegistered to %s\n"
#define MShare "\nShareware version Type RAR -? for help\n"
#define MUCopyright "\nUNRAR %s freeware Copyright (c) 1993-%d Alexander Roshal\n"
#define MBeta "beta"
#define MMonthJan "Jan"
#define MMonthFeb "Feb"
#define MMonthMar "Mar"
#define MMonthApr "Apr"
#define MMonthMay "May"
#define MMonthJun "Jun"
#define MMonthJul "Jul"
#define MMonthAug "Aug"
#define MMonthSep "Sep"
#define MMonthOct "Oct"
#define MMonthNov "Nov"
#define MMonthDec "Dec"
#define MRARTitle1 "\nUsage: rar <command> -<switch 1> -<switch N> <archive> <files...>"
#define MUNRARTitle1 "\nUsage: unrar <command> -<switch 1> -<switch N> <archive> <files...>"
#define MRARTitle2 "\n <@listfiles...> <path_to_extract\\>"
#define MCHelpCmd "\n\n<Commands>"
#define MCHelpCmdA "\n a Add files to archive"
#define MCHelpCmdC "\n c Add archive comment"
#define MCHelpCmdCF "\n cf Add files comment"
#define MCHelpCmdCH "\n ch Change archive parameters"
#define MCHelpCmdCW "\n cw Write archive comment to file"
#define MCHelpCmdD "\n d Delete files from archive"
#define MCHelpCmdE "\n e Extract files to current directory"
#define MCHelpCmdF "\n f Freshen files in archive"
#define MCHelpCmdI "\n i[par]=<str> Find string in archives"
#define MCHelpCmdK "\n k Lock archive"
#define MCHelpCmdL "\n l[t,b] List archive [technical, bare]"
#define MCHelpCmdM "\n m[f] Move to archive [files only]"
#define MCHelpCmdP "\n p Print file to stdout"
#define MCHelpCmdR "\n r Repair archive"
#define MCHelpCmdRC "\n rc Reconstruct missing volumes"
#define MCHelpCmdRN "\n rn Rename archived files"
#define MCHelpCmdRR "\n rr[N] Add data recovery record"
#define MCHelpCmdRV "\n rv[N] Create recovery volumes"
#define MCHelpCmdS "\n s[name|-] Convert archive to or from SFX"
#define MCHelpCmdT "\n t Test archive files"
#define MCHelpCmdU "\n u Update files in archive"
#define MCHelpCmdV "\n v[t,b] Verbosely list archive [technical,bare]"
#define MCHelpCmdX "\n x Extract files with full path"
#define MCHelpSw "\n\n<Switches>"
#define MCHelpSwm "\n - Stop switches scanning"
#define MCHelpSwAC "\n ac Clear Archive attribute after compression or extraction"
#define MCHelpSwAD "\n ad Append archive name to destination path"
#define MCHelpSwAG "\n ag[format] Generate archive name using the current date"
#define MCHelpSwAI "\n ai Ignore file attributes"
#define MCHelpSwAO "\n ao Add files with Archive attribute set"
#define MCHelpSwAP "\n ap<path> Set path inside archive"
#define MCHelpSwAS "\n as Synchronize archive contents"
#define MCHelpSwAV "\n av Put authenticity verification (registered versions only)"
#define MCHelpSwAVm "\n av- Disable authenticity verification check"
#define MCHelpSwCm "\n c- Disable comments show"
#define MCHelpSwCFGm "\n cfg- Disable read configuration"
#define MCHelpSwCL "\n cl Convert names to lower case"
#define MCHelpSwCU "\n cu Convert names to upper case"
#define MCHelpSwDF "\n df Delete files after archiving"
#define MCHelpSwDH "\n dh Open shared files"
#define MCHelpSwDR "\n dr Delete files to Recycle Bin"
#define MCHelpSwDS "\n ds Disable name sort for solid archive"
#define MCHelpSwDW "\n dw Wipe files after archiving"
#define MCHelpSwEa "\n e[+]<attr> Set file exclude and include attributes"
#define MCHelpSwED "\n ed Do not add empty directories"
#define MCHelpSwEE "\n ee Do not save and extract extended attributes"
#define MCHelpSwEN "\n en Do not put 'end of archive' block"
#define MCHelpSwEP "\n ep Exclude paths from names"
#define MCHelpSwEP1 "\n ep1 Exclude base directory from names"
#define MCHelpSwEP2 "\n ep2 Expand paths to full"
#define MCHelpSwEP3 "\n ep3 Expand paths to full including the drive letter"
#define MCHelpSwF "\n f Freshen files"
#define MCHelpSwHP "\n hp[password] Encrypt both file data and headers"
#define MCHelpSwIDP "\n id[c,d,p,q] Disable messages"
#define MCHelpSwIEML "\n ieml[addr] Send archive by email"
#define MCHelpSwIERR "\n ierr Send all messages to stderr"
#define MCHelpSwILOG "\n ilog[name] Log errors to file (registered versions only)"
#define MCHelpSwINUL "\n inul Disable all messages"
#define MCHelpSwIOFF "\n ioff Turn PC off after completing an operation"
#define MCHelpSwISND "\n isnd Enable sound"
#define MCHelpSwK "\n k Lock archive"
#define MCHelpSwKB "\n kb Keep broken extracted files"
#define MCHelpSwMn "\n m<0..5> Set compression level (0-store...3-default...5-maximal)"
#define MCHelpSwMC "\n mc<par> Set advanced compression parameters"
#define MCHelpSwMD "\n md<size> Dictionary size in KB (64,128,256,512,1024,2048,4096 or A-G)"
#define MCHelpSwMS "\n ms[ext;ext] Specify file types to store"
#define MCHelpSwMT "\n mt<threads> Set the number of threads"
#define MCHelpSwN "\n n<file> Include only specified file"
#define MCHelpSwNa "\n n@ Read file names to include from stdin"
#define MCHelpSwNal "\n n@<list> Include files listed in specified list file"
#define MCHelpSwO "\n o[+|-] Set the overwrite mode"
#define MCHelpSwOC "\n oc Set NTFS Compressed attribute"
#define MCHelpSwOL "\n ol Save symbolic links as the link instead of the file"
#define MCHelpSwOR "\n or Rename files automatically"
#define MCHelpSwOS "\n os Save NTFS streams"
#define MCHelpSwOW "\n ow Save or restore file owner and group"
#define MCHelpSwP "\n p[password] Set password"
#define MCHelpSwPm "\n p- Do not query password"
#define MCHelpSwR "\n r Recurse subdirectories"
#define MCHelpSwRm "\n r- Disable recursion"
#define MCHelpSwR0 "\n r0 Recurse subdirectories for wildcard names only"
#define MCHelpSwRI "\n ri<P>[:<S>] Set priority (0-default,1-min..15-max) and sleep time in ms"
#define MCHelpSwRR "\n rr[N] Add data recovery record"
#define MCHelpSwRV "\n rv[N] Create recovery volumes"
#define MCHelpSwS "\n s[<N>,v[-],e] Create solid archive"
#define MCHelpSwSm "\n s- Disable solid archiving"
#define MCHelpSwSC "\n sc<chr>[obj] Specify the character set"
#define MCHelpSwSFX "\n sfx[name] Create SFX archive"
#define MCHelpSwSI "\n si[name] Read data from standard input (stdin)"
#define MCHelpSwSL "\n sl<size> Process files with size less than specified"
#define MCHelpSwSM "\n sm<size> Process files with size more than specified"
#define MCHelpSwT "\n t Test files after archiving"
#define MCHelpSwTK "\n tk Keep original archive time"
#define MCHelpSwTL "\n tl Set archive time to latest file"
#define MCHelpSwTN "\n tn<time> Process files newer than <time>"
#define MCHelpSwTO "\n to<time> Process files older than <time>"
#define MCHelpSwTA "\n ta<date> Process files modified after <date> in YYYYMMDDHHMMSS format"
#define MCHelpSwTB "\n tb<date> Process files modified before <date> in YYYYMMDDHHMMSS format"
#define MCHelpSwTS "\n ts<m,c,a>[N] Save or restore file time (modification, creation, access)"
#define MCHelpSwU "\n u Update files"
#define MCHelpSwV "\n v Create volumes with size autodetection or list all volumes"
#define MCHelpSwVUnr "\n v List all volumes"
#define MCHelpSwVn "\n v<size>[k,b] Create volumes with size=<size>*1000 [*1024, *1]"
#define MCHelpSwVD "\n vd Erase disk contents before creating volume"
#define MCHelpSwVER "\n ver[n] File version control"
#define MCHelpSwVN "\n vn Use the old style volume naming scheme"
#define MCHelpSwVP "\n vp Pause before each volume"
#define MCHelpSwW "\n w<path> Assign work directory"
#define MCHelpSwX "\n x<file> Exclude specified file"
#define MCHelpSwXa "\n x@ Read file names to exclude from stdin"
#define MCHelpSwXal "\n x@<list> Exclude files listed in specified list file"
#define MCHelpSwY "\n y Assume Yes on all queries"
#define MCHelpSwZ "\n z[file] Read archive comment from file"
#define MBadArc "\nERROR: Bad archive %s\n"
#define MAskPsw "Enter password (will not be echoed)"
#define MAskPswEcho "Enter password"
#define MReAskPsw "\nReenter password: "
#define MFor " for "
#define MNotMatchPsw "\nERROR: Passwords do not match\n"
#define MErrWrite "Write error in the file %s"
#define MErrRead "Read error in the file %s"
#define MErrSeek "Seek error in the file %s"
#define MErrFClose "Cannot close the file %s"
#define MErrOutMem "Not enough memory"
#define MErrBrokenArc "Corrupt archive - use 'Repair' command"
#define MProgAborted "Program aborted"
#define MErrRename "\nCannot rename %s to %s"
#define MAbsNextVol "\nCannot find volume %s"
#define MBreak "\nUser break\n"
#define MAskCreatVol "\nCreate next volume ?"
#define MAskNextDisk "\nDisk full. Insert next"
#define MCreatVol "\n\nCreating %sarchive %s\n"
#define MAskNextVol "\nInsert disk with %s"
#define MTestVol "\n\nTesting archive %s\n"
#define MExtrVol "\n\nExtracting from %s\n"
#define MConverting "\nConverting %s"
#define MCvtToSFX "\nConvert archives to SFX"
#define MCvtFromSFX "\nRemoving SFX module"
#define MNotSFX "\n%s is not SFX archive"
#define MNotRAR "\n%s is not RAR archive"
#define MNotFirstVol "\n%s is not the first volume"
#define MCvtOldFormat "\n%s - cannot convert to SFX archive with old format"
#define MCannotCreate "\nCannot create %s"
#define MCannotOpen "\nCannot open %s"
#define MUnknownMeth "\nUnknown method in %s"
#define MVerRequired "\nYou need RAR %d.%d to unpack it"
#define MOk " OK"
#define MDone "\nDone"
#define MLockingArc "\nLocking archive"
#define MNotMdfOld "\n\nERROR: Cannot modify old format archive"
#define MNotMdfLock "\n\nERROR: Locked archive"
#define MNotMdfVol "\n\nERROR: Cannot modify volume"
#define MVerifyAV "\nVerifying authenticity information ... "
#define MFailedAV " Failed\n"
#define MStrAV1 "\n\nArchive %s"
#define MStrAV2 "\ncreated at %s"
#define MStrAV3 "\nby %s\n"
#define MLogFailedAV "Invalid authenticity information"
#define MAddingAV "\nAdding authenticity verification "
#define MAVOldStyle "\n\nOld style authenticity information"
#define MPackAskReg "\nEvaluation copy. Please register.\n"
#define MCreateArchive "\nCreating %sarchive %s\n"
#define MUpdateArchive "\nUpdating %sarchive %s\n"
#define MAddSolid "solid "
#define MAddFile "\nAdding %-58s "
#define MUpdFile "\nUpdating %-58s "
#define MAddPoints "\n... %-58s "
#define MCannotUpdPswSolid "\nERROR: Cannot update solid archives with password\n"
#define MMoveDelFiles "\n\nDeleting files %s..."
#define MMoveDelDirs "and directories"
#define MMoveDelFile "\nDeleting %-30s"
#define MMoveDeleted " deleted"
#define MMoveNotDeleted " NOT DELETED"
#define MClearAttrib "\n\nClearing attributes..."
#define MMoveDelDir "\nDeleting directory %-30s"
#define MWarErrFOpen "\nWARNING: Cannot open %d %s"
#define MErrOpenFiles "files"
#define MErrOpenFile "file"
#define MAddNoFiles "\nWARNING: No files"
#define MMdfEncrSol "\n%s: encrypted"
#define MCannotMdfEncrSol "\nCannot modify solid archive containing encrypted files"
#define MAddAnalyze "\nAnalyzing archived files: "
#define MRepacking "\nRepacking archived files: "
#define MCRCFailed "\n%-20s - CRC failed"
#define MExtrTest "\n\nTesting archive %s\n"
#define MExtracting "\n\nExtracting from %s\n"
#define MUseCurPsw "\n%s - use current password ?"
#define MCreatDir "\nCreating %-56s"
#define MExtrSkipFile "\nSkipping %-56s"
#define MExtrTestFile "\nTesting %-56s"
#define MExtrFile "\nExtracting %-56s"
#define MExtrPoints "\n... %-56s"
#define MExtrErrMkDir "\nCannot create directory %s"
#define MExtrPrinting "\n------ Printing %s\n\n"
#define MEncrBadCRC "\nEncrypted file: CRC failed in %s (password incorrect ?)"
#define MExtrNoFiles "\nNo files to extract"
#define MExtrAllOk "\nAll OK"
#define MExtrTotalErr "\nTotal errors: %ld"
#define MFileExists "\n\n%s already exists. Overwrite it ?"
#define MAskOverwrite "\nOverwrite %s ?"
#define MAskNewName "\nEnter new name: "
#define MLogMainHead "\nThe archive header is corrupt"
#define MLogFileHead "\n%s - the file header is corrupt"
#define MLogCommHead "\nThe comment header is corrupt\n"
#define MLogProtectHead "The data recovery header is corrupt"
#define MReadStdinCmt "\nReading comment from stdin\n"
#define MReadCommFrom "\nReading comment from %s"
#define MDelComment "\nDeleting comment from %s"
#define MAddComment "\nAdding comment to %s"
#define MFCommAdd "\nAdding file comments"
#define MAskFComm "\n\nReading comment for %s : %s from stdin\n"
#define MLogCommBrk "\nThe archive comment is corrupt"
#define MCommAskCont "\nPress 'Enter' to continue or 'Q' to quit:"
#define MLogBrokFCmt "\nThe file comment is corrupt"
#define MWriteCommTo "\nWrite comment to %s"
#define MCommNotPres "\nComment is not present"
#define MDelFrom "\nDeleting from %s"
#define MDeleting "\nDeleting %s"
#define MEraseArc "\nErasing empty archive %s"
#define MNoDelFiles "\nNo files to delete"
#define MLogTitle "\n\n-------- %2d %s %d, archive %s\n"
#define MPathTooLong "\nERROR: Path too long\n"
#define MListSolid "Solid "
#define MListSFX "SFX "
#define MListVol1 "volume"
#define MListVol2 "Volume"
#define MListArc1 "archive"
#define MListArc2 "Archive"
#define MListRecRec "\nRecovery record is present\n"
#define MListLock "\nLock is present\n"
#define MListPathComm "\nPathname/Comment\n "
#define MListName "\n Name "
#define MListTitle " Size Packed Ratio Date Time Attr CRC Meth Ver\n"
#define MListTechTitle " Host OS Solid Old\n"
#define MListEAHead "\n OS/2 extended attributes"
#define MListUOHead "\n Unix Owner/Group data: %-14s %-14s"
#define MListBeEAHead "\n BeOS extended attributes"
#define MListNTACLHead "\n NTFS security data"
#define MListStrmHead "\n NTFS stream: %s"
#define MListUnkHead "\n Unknown subheader type: 0x%04x"
#define MFileComment "\nComment: "
#define MYes "Yes"
#define MNo "No"
#define MListNoFiles " 0 files\n"
#define MRprReconstr "\nReconstructing %s"
#define MRprBuild "\nBuilding %s"
#define MRprOldFormat "\nCannot repair archive with old format"
#define MRprFind "\nFound %s"
#define MRprAskIsSol "\nThe archive header is corrupt. Mark archive as solid ?"
#define MRprNoFiles "\nNo files found"
#define MRprSuspEntry "\n\nSuspicious entry %s"
#define MRprDir "\nDirectory"
#define MRprSuspSize "\nSize %ld Packed %ld"
#define MRprSuspAdd "\nAdd it to archive ?"
#define MLogUnexpEOF "\nUnexpected end of archive"
#define MRepAskReconst "\nReconstruct archive structure ?"
#define MRecScanning "\nScanning..."
#define MRecRNotFound "\nData recovery record not found"
#define MRecRFound "\nData recovery record found"
#define MRecSecDamage "\nSector %ld (offsets %lX...%lX) damaged"
#define MRecCorrected " - data recovered"
#define MRecFailed " - cannot recover data"
#define MAddRecRec "\nAdding data recovery record"
#define MEraseForVolume "\n\nErasing contents of drive %c:\n"
#define MGetOwnersError "\nWARNING: Cannot get %s owner and group\n"
#define MErrGetOwnerID "\nWARNING: Cannot get owner %s ID\n"
#define MErrGetGroupID "\nWARNING: Cannot get group %s ID\n"
#define MOwnersBroken "\nERROR: %s group and owner data are corrupt\n"
#define MSetOwnersError "\nWARNING: Cannot set %s owner and group\n"
#define MErrLnkRead "\nWARNING: Cannot read symbolic link %s"
#define MErrCreateLnk "\nWARNING: Cannot create link %s"
#define MSymLinkExists "\nWARNING: Symbolic link %s already exists"
#define MAskRetryCreate "\nCannot create %s. Retry ?"
#define MListMACHead1 "\n MacOS file type: %c%c%c%c ; "
#define MListMACHead2 "file creator: %c%c%c%c\n"
#define MDataBadCRC "\n%-20s : packed data CRC failed in volume %s"
#define MFileRO "\n%s is read-only"
#define MACLGetError "\nWARNING: Cannot get %s security data\n"
#define MACLSetError "\nWARNING: Cannot set %s security data\n"
#define MACLBroken "\nERROR: %s security data are corrupt\n"
#define MACLUnknown "\nWARNING: Unknown format of %s security data\n"
#define MStreamBroken "\nERROR: %s stream data are corrupt\n"
#define MStreamUnknown "\nWARNING: Unknown format of %s stream data\n"
#define MInvalidName "\nERROR: Invalid file name %s"
#define MEABroken "\nERROR: %s extended attributes are corrupt\n"
#define MEAUnknHeader "\nWARNING: %s - unknown format of extended attributes\n"
#define MCannotSetEA "\nWARNING: cannot set extended attributes to %s\n"
#define MCannotGetEA "\nERROR: Cannot get extended attributes of %s\n"
#define MShowEA " (+EA)"
#define MSkipEA "\n...skipping extended attributes"
#define MProcessArc "\n\nProcessing archive %s"
#define MSyncScanError "\nFile search errors, cannot synchronize archive"
#define MCorrectingName "\nWARNING: Attempting to correct the invalid file name"
#define MUnpCannotMerge "\nWARNING: You need to start extraction from a previous volume to unpack %s"
#define MUnknownOption "\nERROR: Unknown option: %s"
#define MSubHeadCorrupt "\nERROR: Corrupt data header found, ignored"
#define MSubHeadUnknown "\nWARNING: Unknown data header format, ignored"
#define MSubHeadDataCRC "\nERROR: Corrupt %s data block"
#define MSubHeadType "\nData header type: %s"
#define MScanError "\nCannot read contents of %s"
#define MNotVolume "\n%s is not volume"
#define MRecVolDiffSets "\nERROR: %s and %s belong to different sets"
#define MRecVolMissing "\n%d volumes missing"
#define MRecVolFound "\n%d recovery volumes found"
#define MRecVolAllExist "\nNothing to reconstruct"
#define MRecVolCannotFix "\nReconstruction impossible"
#define MReconstructing "\nReconstructing..."
#define MCreating "\nCreating %s"
#define MRenaming "\nRenaming %s to %s"
#define MNTFSRequired "\nWrite error: only NTFS file system supports files larger than 4 GB"
#define MErrChangeAttr "\nWARNING: Cannot change attributes of %s"
#define MWrongSFXVer "\nERROR: default SFX module does not support RAR %d.%d archives"
#define MCannotEncName "\nCannot encrypt archive already contained encrypted files"
#define MCannotEmail "\nCannot email the file %s"
#define MCopyrightS "\nRAR SFX archive"
#define MSHelpCmd "\n\n<Commands>"
#define MSHelpCmdE "\n -x Extract from archive (default)"
#define MSHelpCmdT "\n -t Test archive files"
#define MSHelpCmdV "\n -v Verbosely list contents of archive"
#define MMaxPathLimit "\nTotal path and file name length must not exceed %d characters"
#define MRecVolLimit "\nTotal number of usual and recovery volumes must not exceed 255"
#define MVolumeNumber "volume %d"
#define MCannotDelete "\nCannot delete %s"
#define MCalcCRC "\nCalculating the control sum"
#define MTooLargeSFXArc "\nWARNING: Too large SFX archive. Windows cannot run the executable file exceeding 4 GB."
#define MCalcCRCAllVol "\nCalculating control sums of all volumes."
#define MNotEnoughDisk "\nERROR: Not enough disk space for %s."

24
libunrar/log.cpp Normal file
View File

@ -0,0 +1,24 @@
#include "rar.hpp"
static char LogName[NM];
void InitLogOptions(char *LogName)
{
strcpy(::LogName,LogName);
}
#ifndef SILENT
void Log(const char *ArcName,const char *Format,...)
{
safebuf char Msg[2*NM+1024];
va_list ArgPtr;
va_start(ArgPtr,Format);
vsprintf(Msg,Format,ArgPtr);
va_end(ArgPtr);
eprintf("%s",Msg);
}
#endif

18
libunrar/log.hpp Normal file
View File

@ -0,0 +1,18 @@
#ifndef _RAR_LOG_
#define _RAR_LOG_
void InitLogOptions(char *LogName);
#ifndef SILENT
void Log(const char *ArcName,const char *Format,...);
#endif
#ifdef SILENT
#ifdef __GNUC__
#define Log(args...)
#else
inline void Log(const char *a,const char *b,const char *c=NULL,const char *d=NULL) {}
#endif
#endif
#endif

501
libunrar/makefile.bcc Normal file
View File

@ -0,0 +1,501 @@
.AUTODEPEND
basepath = $(BASEPATHCC)
binpath = $(basepath)\bin
libpath = $(basepath)\lib
rarpath = .
incpath = $(basepath)\include;$(rarpath)
cc = $(binpath)\bcc32
link = $(binpath)\ilink32
objpath = .
guiopt = -WC -H=$(objpath)\rar.csm
!ifndef RARDLL
!ifndef GUI
guiopt=$(guiopt) -x-
!endif
!ifdef SFX_MODULE
guiopt=$(guiopt) -x-
!endif
!endif
!ifdef DEBUG
optdeb=-Od -k -vi- -DDEBUG
!else
# -O is not safe to use with -pr and int64 return values, so let's turn it off
optdeb=-O1 -O- -k-
#optdeb=-Ob -Oe -Og -Oi -Ol -Om -Op -OS -Ov -Z -Oc
!endif
optunrar=-DUNRAR
linkdest=unrar.exe
!ifdef SFX_MODULE
optunrar=-DUNRAR -DSFX_MODULE
linkdest=sfx.exe
!endif
linkopt = -L$(libpath) -ap -c -v -s -V4.0 -Gn
compopt = -P -c -I$(incpath) -R -v -vi -w-pch -w-par -K -f-\
-ff- -a4 -pr -RT- $(optdeb) $(guiopt) $(optunrar) -d -w-8072
!ifdef RARDLL
SILENT=true
linkdest=unrar.dll
linkopt=$(linkopt) -Tpd
compopt=$(compopt) -DRARDLL
!else
linkopt=$(linkopt) -Tpe -B:0x400000
!endif
!ifdef SILENT
compopt=$(compopt) -DSILENT
!endif
rar: $(linkdest)
Dep_SFX= \
$(objpath)\strlist.obj\
$(objpath)\strfn.obj\
$(objpath)\pathfn.obj\
$(objpath)\cmddata.obj\
$(objpath)\consio.obj\
$(objpath)\savepos.obj\
$(objpath)\smallfn.obj\
$(objpath)\file.obj\
$(objpath)\filefn.obj\
$(objpath)\filcreat.obj\
$(objpath)\sha1.obj\
$(objpath)\archive.obj\
$(objpath)\arcread.obj\
$(objpath)\unicode.obj\
$(objpath)\system.obj\
$(objpath)\isnt.obj\
$(objpath)\crc.obj\
$(objpath)\crypt.obj\
$(objpath)\rijndael.obj\
$(objpath)\rawread.obj\
$(objpath)\encname.obj\
$(objpath)\resource.obj\
$(objpath)\match.obj\
$(objpath)\find.obj\
$(objpath)\timefn.obj\
$(objpath)\getbits.obj\
$(objpath)\rarvm.obj\
$(objpath)\rdwrfn.obj\
$(objpath)\options.obj\
$(objpath)\ulinks.obj\
$(objpath)\errhnd.obj\
$(objpath)\volume.obj\
$(objpath)\rs.obj\
$(objpath)\recvol.obj\
$(objpath)\extinfo.obj\
$(objpath)\extract.obj\
$(objpath)\unpack.obj\
$(objpath)\rar.obj\
$(objpath)\global.obj
Dep_Unrar = \
$(objpath)\filestr.obj\
$(objpath)\scantree.obj
Dep_Dll = \
$(objpath)\dll.obj
#Dep_SFXOnly = $(objpath)\rtl.obj
!ifndef GUI
!ifndef SILENT
Dep_Console = \
$(objpath)\list.obj
!endif
!endif
!ifdef SFX_MODULE
Dep = $(Dep_SFX) $(Dep_SFXOnly)
!else
Dep = $(Dep_SFX) $(Dep_Unrar)
!endif
!ifndef GUI
Dep = $(Dep) $(Dep_Console)
!endif
!ifdef RARDLL
Dep = $(Dep) $(Dep_Dll)
!endif
!ifdef GUI
$(linkdest) : $(Dep)
echo Done
!else
$(linkdest) : $(Dep)
$(link) @&&|
$(linkopt) +
#!ifdef SFX_MODULE
#$(objpath)\dummy.obj+
#$(objpath)\ll.obj+
#$(objpath)\rtl.obj+
#!else
!ifdef RARDLL
$(libpath)\c0d32.obj+
!else
$(libpath)\c0x32.obj+
!endif
#!endif
$(objpath)\strlist.obj+
$(objpath)\strfn.obj+
$(objpath)\pathfn.obj+
$(objpath)\savepos.obj+
$(objpath)\smallfn.obj+
$(objpath)\global.obj+
$(objpath)\file.obj+
$(objpath)\filefn.obj+
$(objpath)\filcreat.obj+
$(objpath)\sha1.obj+
$(objpath)\archive.obj+
$(objpath)\arcread.obj+
$(objpath)\unicode.obj+
$(objpath)\system.obj+
$(objpath)\isnt.obj+
$(objpath)\crc.obj+
$(objpath)\crypt.obj+
$(objpath)\rijndael.obj+
$(objpath)\rawread.obj+
$(objpath)\encname.obj+
$(objpath)\resource.obj+
$(objpath)\match.obj+
$(objpath)\find.obj+
!ifndef SFX_MODULE
$(objpath)\filestr.obj+
$(objpath)\scantree.obj+
!endif
$(objpath)\timefn.obj+
$(objpath)\getbits.obj+
$(objpath)\rarvm.obj+
$(objpath)\rdwrfn.obj+
$(objpath)\consio.obj+
$(objpath)\cmddata.obj+
$(objpath)\options.obj+
$(objpath)\ulinks.obj+
$(objpath)\volume.obj+
$(objpath)\extinfo.obj+
$(objpath)\extract.obj+
$(objpath)\rs.obj+
$(objpath)\recvol.obj+
!ifndef SILENT
!ifndef GUI
$(objpath)\list.obj+
!endif
!endif
!ifdef RARDLL
$(objpath)\dll.obj+
!endif
$(objpath)\errhnd.obj+
$(objpath)\unpack.obj+
$(objpath)\rar.obj
$<,$*
$(libpath)\cw32.lib+
$(libpath)\import32.lib
!ifdef RARDLL
$(rarpath)\dll.def
!else
!endif
|
!endif
$(objpath)\rar.obj : $(rarpath)\rar.cpp
$(cc) -q @&&|
$(compopt) -o$@ $(rarpath)\rar.cpp
|
$(objpath)\strlist.obj : $(rarpath)\strlist.cpp
$(cc) -q @&&|
$(compopt) -o$@ $(rarpath)\strlist.cpp
|
$(objpath)\strfn.obj : $(rarpath)\strfn.cpp
$(cc) -q @&&|
$(compopt) -o$@ $(rarpath)\strfn.cpp
|
$(objpath)\pathfn.obj : $(rarpath)\pathfn.cpp
$(cc) -q @&&|
$(compopt) -o$@ $(rarpath)\pathfn.cpp
|
$(objpath)\savepos.obj : $(rarpath)\savepos.cpp
$(cc) -q @&&|
$(compopt) -o$@ $(rarpath)\savepos.cpp
|
$(objpath)\smallfn.obj : $(rarpath)\smallfn.cpp
$(cc) -q @&&|
$(compopt) -o$@ $(rarpath)\smallfn.cpp
|
$(objpath)\global.obj : $(rarpath)\global.cpp
$(cc) -q @&&|
$(compopt) -H- -o$@ $(rarpath)\global.cpp
|
$(objpath)\file.obj : $(rarpath)\file.cpp
$(cc) -q @&&|
$(compopt) -o$@ $(rarpath)\file.cpp
|
$(objpath)\filefn.obj : $(rarpath)\filefn.cpp
$(cc) -q @&&|
$(compopt) -o$@ $(rarpath)\filefn.cpp
|
$(objpath)\filestr.obj : $(rarpath)\filestr.cpp
$(cc) -q @&&|
$(compopt) -o$@ $(rarpath)\filestr.cpp
|
$(objpath)\filcreat.obj : $(rarpath)\filcreat.cpp
$(cc) -q @&&|
$(compopt) -o$@ $(rarpath)\filcreat.cpp
|
$(objpath)\sha1.obj : $(rarpath)\sha1.cpp
$(cc) -q @&&|
$(compopt) -o$@ $(rarpath)\sha1.cpp
|
$(objpath)\ec.obj : $(rarpath)\ec.cpp
$(cc) -q @&&|
$(compopt) -o$@ $(rarpath)\ec.cpp
|
$(objpath)\av.obj : $(rarpath)\av.cpp
$(cc) -q @&&|
$(compopt) -o$@ $(rarpath)\av.cpp
|
$(objpath)\archive.obj : $(rarpath)\archive.cpp
$(cc) -q @&&|
$(compopt) -o$@ $(rarpath)\archive.cpp
|
$(objpath)\arcread.obj : $(rarpath)\arcread.cpp
$(cc) -q @&&|
$(compopt) -o$@ $(rarpath)\arcread.cpp
|
$(objpath)\unicode.obj : $(rarpath)\unicode.cpp
$(cc) -q @&&|
$(compopt) -o$@ $(rarpath)\unicode.cpp
|
$(objpath)\system.obj : $(rarpath)\system.cpp
$(cc) -q @&&|
$(compopt) -o$@ $(rarpath)\system.cpp
|
$(objpath)\isnt.obj : $(rarpath)\isnt.cpp
$(cc) -q @&&|
$(compopt) -o$@ $(rarpath)\isnt.cpp
|
$(objpath)\crc.obj : $(rarpath)\crc.cpp
$(cc) -q @&&|
$(compopt) -o$@ $(rarpath)\crc.cpp
|
$(objpath)\crypt.obj : $(rarpath)\crypt.cpp
$(cc) -q @&&|
$(compopt) -o$@ $(rarpath)\crypt.cpp
|
$(objpath)\rijndael.obj : $(rarpath)\rijndael.cpp
$(cc) -q @&&|
$(compopt) -o$@ $(rarpath)\rijndael.cpp
|
$(objpath)\rawread.obj : $(rarpath)\rawread.cpp
$(cc) -q @&&|
$(compopt) -o$@ $(rarpath)\rawread.cpp
|
$(objpath)\rawwrite.obj : $(rarpath)\rawwrite.cpp
$(cc) -q @&&|
$(compopt) -o$@ $(rarpath)\rawwrite.cpp
|
$(objpath)\encname.obj : $(rarpath)\encname.cpp
$(cc) -q @&&|
$(compopt) -o$@ $(rarpath)\encname.cpp
|
$(objpath)\resource.obj : $(rarpath)\resource.cpp
$(cc) -q @&&|
$(compopt) -o$@ $(rarpath)\resource.cpp
|
$(objpath)\match.obj : $(rarpath)\match.cpp
$(cc) -q @&&|
$(compopt) -o$@ $(rarpath)\match.cpp
|
$(objpath)\find.obj : $(rarpath)\find.cpp
$(cc) -q @&&|
$(compopt) -o$@ $(rarpath)\find.cpp
|
$(objpath)\scantree.obj : $(rarpath)\scantree.cpp
$(cc) -q @&&|
$(compopt) -o$@ $(rarpath)\scantree.cpp
|
$(objpath)\timefn.obj : $(rarpath)\timefn.cpp
$(cc) -q @&&|
$(compopt) -o$@ $(rarpath)\timefn.cpp
|
$(objpath)\getbits.obj : $(rarpath)\getbits.cpp
$(cc) -q @&&|
$(compopt) -o$@ $(rarpath)\getbits.cpp
|
$(objpath)\rarvm.obj : $(rarpath)\rarvm.cpp
$(cc) -q @&&|
$(compopt) -o$@ $(rarpath)\rarvm.cpp
|
$(objpath)\putbits.obj : $(rarpath)\putbits.cpp
$(cc) -q @&&|
$(compopt) -o$@ $(rarpath)\putbits.cpp
|
$(objpath)\pack.obj : $(rarpath)\pack.cpp
$(cc) -q @&&|
$(compopt) -o$@ $(rarpath)\pack.cpp
|
$(objpath)\packbord.obj : $(rarpath)\packbord.cpp
$(cc) -q @&&|
$(compopt) -o$@ $(rarpath)\packbord.cpp
|
$(objpath)\packanlz.obj : $(rarpath)\packanlz.cpp
$(cc) -q @&&|
$(compopt) -o$@ $(rarpath)\packanlz.cpp
|
$(objpath)\cblock.obj : $(rarpath)\cblock.cpp
$(cc) -q @&&|
$(compopt) -o$@ $(rarpath)\cblock.cpp
|
$(objpath)\add.obj : $(rarpath)\add.cpp
$(cc) -q @&&|
$(compopt) -o$@ $(rarpath)\add.cpp
|
$(objpath)\addlist.obj : $(rarpath)\addlist.cpp
$(cc) -q @&&|
$(compopt) -o$@ $(rarpath)\addlist.cpp
|
$(objpath)\procarc.obj : $(rarpath)\procarc.cpp
$(cc) -q @&&|
$(compopt) -o$@ $(rarpath)\procarc.cpp
|
$(objpath)\sfx.obj : $(rarpath)\sfx.cpp
$(cc) -q @&&|
$(compopt) -o$@ $(rarpath)\sfx.cpp
|
$(objpath)\comment.obj : $(rarpath)\comment.cpp
$(cc) -q @&&|
$(compopt) -o$@ $(rarpath)\comment.cpp
|
$(objpath)\rs.obj : $(rarpath)\rs.cpp
$(cc) -q @&&|
$(compopt) -o$@ $(rarpath)\rs.cpp
|
$(objpath)\recvol.obj : $(rarpath)\recvol.cpp
$(cc) -q @&&|
$(compopt) -o$@ $(rarpath)\recvol.cpp
|
$(objpath)\repair.obj : $(rarpath)\repair.cpp
$(cc) -q @&&|
$(compopt) -o$@ $(rarpath)\repair.cpp
|
$(objpath)\rdwrfn.obj : $(rarpath)\rdwrfn.cpp
$(cc) -q @&&|
$(compopt) -o$@ $(rarpath)\rdwrfn.cpp
|
$(objpath)\consio.obj : $(rarpath)\consio.cpp
$(cc) -q @&&|
$(compopt) -o$@ $(rarpath)\consio.cpp
|
$(objpath)\cmddata.obj : $(rarpath)\cmddata.cpp
$(cc) -q @&&|
$(compopt) -o$@ $(rarpath)\cmddata.cpp
|
$(objpath)\options.obj : $(rarpath)\options.cpp
$(cc) -q @&&|
$(compopt) -o$@ $(rarpath)\options.cpp
|
$(objpath)\ulinks.obj : $(rarpath)\ulinks.cpp
$(cc) -q @&&|
$(compopt) -o$@ $(rarpath)\ulinks.cpp
|
$(objpath)\errhnd.obj : $(rarpath)\errhnd.cpp
$(cc) -q @&&|
$(compopt) -o$@ $(rarpath)\errhnd.cpp
|
$(objpath)\volume.obj : $(rarpath)\volume.cpp
$(cc) -q @&&|
$(compopt) -o$@ $(rarpath)\volume.cpp
|
$(objpath)\extinfo.obj : $(rarpath)\extinfo.cpp
$(cc) -q @&&|
$(compopt) -o$@ $(rarpath)\extinfo.cpp
|
$(objpath)\extract.obj : $(rarpath)\extract.cpp
$(cc) -q @&&|
$(compopt) -o$@ $(rarpath)\extract.cpp
|
$(objpath)\list.obj : $(rarpath)\list.cpp
$(cc) -q @&&|
$(compopt) -o$@ $(rarpath)\list.cpp
|
$(objpath)\rtl.obj : $(rarpath)\rtl.cpp
$(cc) -q @&&|
$(compopt) -o$@ $(rarpath)\rtl.cpp
|
$(objpath)\unpack.obj : $(rarpath)\unpack.cpp
$(cc) -q @&&|
$(compopt) -o$@ $(rarpath)\unpack.cpp
|
$(objpath)\dll.obj : $(rarpath)\dll.cpp
$(cc) -q @&&|
$(compopt) -o$@ $(rarpath)\dll.cpp
|

54
libunrar/makefile.cygmin Normal file
View File

@ -0,0 +1,54 @@
#
# Makefile for cygmin/mingw - unrar
#
# Note: you have to 'make clean' before you can build
# the sfx module
#
# POSIX using Cygmin GCC 3.3.1
#CXX = g++
#CXXFLAGS = -O2 -Wno-deprecated
#DEFINES = -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -DLITTLE_ENDIAN
# Win32 using Cygmin GCC 3.3.1
CXX = g++ -mno-cygwin
CXXFLAGS = -O2 -Wno-deprecated
DEFINES = -D_MSC_VER -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
# Win32 using Mingw32 GCC 3.3.2
#CXX = g++
#CXXFLAGS = -O2 -Wno-deprecated
#DEFINES = -D_MSC_VER -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
##########################
COMPILE=$(CXX) $(CXXFLAGS) $(DEFINES)
LINK=$(CXX)
UNRAR_OBJ=filestr.o recvol.o rs.o scantree.o
OBJECTS=rar.o strlist.o strfn.o pathfn.o savepos.o smallfn.o global.o \
file.o filefn.o filcreat.o archive.o arcread.o unicode.o \
system.o isnt.o crypt.o crc.o rawread.o encname.o \
resource.o match.o timefn.o rdwrfn.o consio.o options.o \
ulinks.o errhnd.o rarvm.o rijndael.o getbits.o sha1.o \
extinfo.o extract.o volume.o list.o find.o unpack.o cmddata.o
.cpp.o:
$(COMPILE) -D$(WHAT) -c $<
all: unrar
clean:
@rm -f *.o *.bak *~
unrar: WHAT=UNRAR
unrar: $(OBJECTS) $(UNRAR_OBJ)
@rm -f makeunrar
$(LINK) -Wl,-s -o unrar $(LDFLAGS) $(OBJECTS) $(UNRAR_OBJ) $(LIBS)
sfx: WHAT=SFX_MODULE
sfx: $(OBJECTS)
@rm -f default.sfx
$(LINK) -Wl,-s -o default.sfx $(LDFLAGS) $(OBJECTS) -DSFX_MODULE

50
libunrar/makefile.dj Normal file
View File

@ -0,0 +1,50 @@
#
# Makefile for DJGPP - unrar
#
# Note: you have to 'make clean' before you can build
# the sfx module
#
# DOS32 using DJGPP 2.03 Patchlevel 2 and GCC 2.95.3
CXX = gpp
CXXFLAGS = -O2 -Wno-deprecated
#DEFINES = -D_MSC_VER -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
##########################
.PHONY: all clean veryclean
COMPILE=$(CXX) $(CXXFLAGS) $(DEFINES)
LINK=$(CXX)
UNRAR_OBJ=filestr.o recvol.o rs.o scantree.o
OBJECTS=rar.o strlist.o strfn.o pathfn.o savepos.o smallfn.o global.o \
file.o filefn.o filcreat.o archive.o arcread.o unicode.o \
system.o isnt.o crypt.o crc.o rawread.o encname.o \
resource.o match.o timefn.o rdwrfn.o consio.o options.o \
ulinks.o errhnd.o rarvm.o rijndael.o getbits.o sha1.o \
extinfo.o extract.o volume.o list.o find.o unpack.o cmddata.o
.cpp.o:
$(COMPILE) -D$(WHAT) -c $<
all: unrar
unrar: WHAT=UNRAR
unrar: $(OBJECTS) $(UNRAR_OBJ)
$(LINK) -Wl,-s -o unrar.exe $(LDFLAGS) $(OBJECTS) $(UNRAR_OBJ) $(LIBS)
exe2coff unrar.exe
cp -u $(DJDIR)/bin/cwsdstub.exe .
copy /b cwsdstub.exe+unrar unrar.exe
-upx --ultra-brute unrar.exe
sfx: WHAT=SFX_MODULE
sfx: $(OBJECTS)
$(LINK) -Wl,-s -o default.sfx $(LDFLAGS) $(OBJECTS) -DSFX_MODULE
clean:
$(RM) $(OBJECTS) $(UNRAR_OBJ)
veryclean: clean
$(RM) unrar.exe default.sfx cwsdstub.exe unrar

54
libunrar/makefile.dmc Normal file
View File

@ -0,0 +1,54 @@
# Makefile for Digital Mars C++ Compiler
# http://www.rarlab.com
# http://www.digitalmars.com
#
# DEFINES: UNRAR RARDLL GUI SFX_MODULE SILENT
NAME = unrar
EXT = exe
CPP = dmc
LINK = link
# --------------
# Release Build
# --------------
DEFINES = -DNDEBUG -D_MSC_VER -DUNRAR
CPPFLAGS = -o+all -ff -Nc -g- -Ae
LNKFLAGS = /EXETYPE:NT /MACHINE:i386 /SUBSYSTEM:CONSOLE /NOLOGO /NODEBUG /NOCODEVIEW /PACKFUNCTIONS
# --------------
# Debug Build
# --------------
#DEFINES = -D_DEBUG -D_MSC_VER -DUNRAR
#CPPFLAGS = -o+none -Nc -S -gf -Ae
#LNKFLAGS = /EXETYPE:NT /MACHINE:i386 /SUBSYSTEM:CONSOLE /NOLOGO /DEBUG
OBJ = rar.obj strlist.obj strfn.obj pathfn.obj savepos.obj smallfn.o global.obj \
file.obj filefn.obj filcreat.obj archive.obj arcread.obj unicode.obj \
system.obj isnt.obj crypt.obj crc.obj rawread.obj encname.obj \
resource.obj match.obj timefn.obj rdwrfn.obj consio.obj options.obj \
ulinks.obj errhnd.obj rarvm.obj rijndael.obj getbits.obj sha1.obj \
extinfo.obj extract.obj volume.obj find.obj unpack.obj cmddata.obj \
filestr.obj recvol.obj rs.obj scantree.obj \
list.obj \
# dll.obj \
LIB = kernel32.lib+user32.lib+advapi32.lib
#DEF = dll.def
link: $(OBJ)
$(LINK) $(LNKFLAGS) $(OBJ), $(NAME).$(EXT), $(NAME).map, $(LIB), $(DEF)
.c.obj:
$(CPP) $(CPPFLAGS) $(DEFINES) -c $< -o $@
.cpp.obj:
$(CPP) $(CPPFLAGS) $(DEFINES) -c $< -o $@
clean:
del $(OBJ)
del $(NAME).$(EXT)
del $(NAME).map

564
libunrar/makefile.msc Normal file
View File

@ -0,0 +1,564 @@
# Microsoft Developer Studio Generated NMAKE File, Based on unrar.dsp
!IF "$(CFG)" == ""
CFG=unrar - Win32 Release
!MESSAGE No configuration specified. Defaulting to unrar - Win32 Release.
!ENDIF
!IF "$(CFG)" != "unrar - Win32 Release" && "$(CFG)" != "unrar - Win32 Debug"
!MESSAGE Invalid configuration "$(CFG)" specified.
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "unrar.mak" CFG="unrar - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "unrar - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "unrar - Win32 Debug" (based on "Win32 (x86) Console Application")
!MESSAGE
!ERROR An invalid configuration is specified.
!ENDIF
!IF "$(OS)" == "Windows_NT"
NULL=
!ELSE
NULL=nul
!ENDIF
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "unrar - Win32 Release"
OUTDIR=.\Release
INTDIR=.\Release
# Begin Custom Macros
OutDir=.\Release
# End Custom Macros
ALL : "$(OUTDIR)\unrar.exe"
CLEAN :
-@erase "$(INTDIR)\archive.obj"
-@erase "$(INTDIR)\arcread.obj"
-@erase "$(INTDIR)\cmddata.obj"
-@erase "$(INTDIR)\consio.obj"
-@erase "$(INTDIR)\crc.obj"
-@erase "$(INTDIR)\crypt.obj"
-@erase "$(INTDIR)\encname.obj"
-@erase "$(INTDIR)\errhnd.obj"
-@erase "$(INTDIR)\extinfo.obj"
-@erase "$(INTDIR)\extract.obj"
-@erase "$(INTDIR)\filcreat.obj"
-@erase "$(INTDIR)\file.obj"
-@erase "$(INTDIR)\filefn.obj"
-@erase "$(INTDIR)\filestr.obj"
-@erase "$(INTDIR)\find.obj"
-@erase "$(INTDIR)\getbits.obj"
-@erase "$(INTDIR)\global.obj"
-@erase "$(INTDIR)\isnt.obj"
-@erase "$(INTDIR)\list.obj"
-@erase "$(INTDIR)\match.obj"
-@erase "$(INTDIR)\options.obj"
-@erase "$(INTDIR)\pathfn.obj"
-@erase "$(INTDIR)\rar.obj"
-@erase "$(INTDIR)\rarvm.obj"
-@erase "$(INTDIR)\rawread.obj"
-@erase "$(INTDIR)\rdwrfn.obj"
-@erase "$(INTDIR)\recvol.obj"
-@erase "$(INTDIR)\resource.obj"
-@erase "$(INTDIR)\rijndael.obj"
-@erase "$(INTDIR)\rs.obj"
-@erase "$(INTDIR)\savepos.obj"
-@erase "$(INTDIR)\smallfn.obj"
-@erase "$(INTDIR)\scantree.obj"
-@erase "$(INTDIR)\sha1.obj"
-@erase "$(INTDIR)\strfn.obj"
-@erase "$(INTDIR)\strlist.obj"
-@erase "$(INTDIR)\system.obj"
-@erase "$(INTDIR)\timefn.obj"
-@erase "$(INTDIR)\ulinks.obj"
-@erase "$(INTDIR)\unicode.obj"
-@erase "$(INTDIR)\unpack.obj"
-@erase "$(INTDIR)\vc60.idb"
-@erase "$(INTDIR)\volume.obj"
-@erase "$(OUTDIR)\unrar.exe"
-@erase "$(OUTDIR)\unrar.map"
"$(OUTDIR)" :
if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
CPP_PROJ=/nologo /W3 /EHsc /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "UNRAR" /D _CRT_SECURE_NO_WARNINGS /Fp"$(INTDIR)\unrar.pch" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c
BSC32=bscmake.exe
BSC32_FLAGS=/nologo /o"$(OUTDIR)\unrar.bsc"
BSC32_SBRS= \
LINK32=link.exe
LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /incremental:no /pdb:"$(OUTDIR)\unrar.pdb" /map:"$(INTDIR)\unrar.map" /machine:I386 /out:"$(OUTDIR)\unrar.exe"
LINK32_OBJS= \
"$(INTDIR)\rar.obj" \
"$(INTDIR)\strlist.obj" \
"$(INTDIR)\strfn.obj" \
"$(INTDIR)\pathfn.obj" \
"$(INTDIR)\savepos.obj" \
"$(INTDIR)\smallfn.obj" \
"$(INTDIR)\global.obj" \
"$(INTDIR)\file.obj" \
"$(INTDIR)\filefn.obj" \
"$(INTDIR)\filcreat.obj" \
"$(INTDIR)\archive.obj" \
"$(INTDIR)\arcread.obj" \
"$(INTDIR)\unicode.obj" \
"$(INTDIR)\system.obj" \
"$(INTDIR)\isnt.obj" \
"$(INTDIR)\crypt.obj" \
"$(INTDIR)\crc.obj" \
"$(INTDIR)\rawread.obj" \
"$(INTDIR)\encname.obj" \
"$(INTDIR)\resource.obj" \
"$(INTDIR)\match.obj" \
"$(INTDIR)\timefn.obj" \
"$(INTDIR)\rdwrfn.obj" \
"$(INTDIR)\consio.obj" \
"$(INTDIR)\options.obj" \
"$(INTDIR)\ulinks.obj" \
"$(INTDIR)\errhnd.obj" \
"$(INTDIR)\rarvm.obj" \
"$(INTDIR)\rijndael.obj" \
"$(INTDIR)\getbits.obj" \
"$(INTDIR)\sha1.obj" \
"$(INTDIR)\extinfo.obj" \
"$(INTDIR)\extract.obj" \
"$(INTDIR)\volume.obj" \
"$(INTDIR)\list.obj" \
"$(INTDIR)\find.obj" \
"$(INTDIR)\unpack.obj" \
"$(INTDIR)\cmddata.obj" \
"$(INTDIR)\filestr.obj" \
"$(INTDIR)\recvol.obj" \
"$(INTDIR)\rs.obj" \
"$(INTDIR)\scantree.obj"
"$(OUTDIR)\unrar.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
$(LINK32) @<<
$(LINK32_FLAGS) $(LINK32_OBJS)
<<
!ELSEIF "$(CFG)" == "unrar - Win32 Debug"
OUTDIR=.\Debug
INTDIR=.\Debug
# Begin Custom Macros
OutDir=.\Debug
# End Custom Macros
ALL : "$(OUTDIR)\unrar.exe"
CLEAN :
-@erase "$(INTDIR)\archive.obj"
-@erase "$(INTDIR)\arcread.obj"
-@erase "$(INTDIR)\cmddata.obj"
-@erase "$(INTDIR)\consio.obj"
-@erase "$(INTDIR)\crc.obj"
-@erase "$(INTDIR)\crypt.obj"
-@erase "$(INTDIR)\encname.obj"
-@erase "$(INTDIR)\errhnd.obj"
-@erase "$(INTDIR)\extinfo.obj"
-@erase "$(INTDIR)\extract.obj"
-@erase "$(INTDIR)\filcreat.obj"
-@erase "$(INTDIR)\file.obj"
-@erase "$(INTDIR)\filefn.obj"
-@erase "$(INTDIR)\filestr.obj"
-@erase "$(INTDIR)\find.obj"
-@erase "$(INTDIR)\getbits.obj"
-@erase "$(INTDIR)\global.obj"
-@erase "$(INTDIR)\isnt.obj"
-@erase "$(INTDIR)\list.obj"
-@erase "$(INTDIR)\match.obj"
-@erase "$(INTDIR)\options.obj"
-@erase "$(INTDIR)\pathfn.obj"
-@erase "$(INTDIR)\rar.obj"
-@erase "$(INTDIR)\rarvm.obj"
-@erase "$(INTDIR)\rawread.obj"
-@erase "$(INTDIR)\rdwrfn.obj"
-@erase "$(INTDIR)\recvol.obj"
-@erase "$(INTDIR)\resource.obj"
-@erase "$(INTDIR)\rijndael.obj"
-@erase "$(INTDIR)\rs.obj"
-@erase "$(INTDIR)\savepos.obj"
-@erase "$(INTDIR)\smallfn.obj"
-@erase "$(INTDIR)\scantree.obj"
-@erase "$(INTDIR)\sha1.obj"
-@erase "$(INTDIR)\strfn.obj"
-@erase "$(INTDIR)\strlist.obj"
-@erase "$(INTDIR)\system.obj"
-@erase "$(INTDIR)\timefn.obj"
-@erase "$(INTDIR)\ulinks.obj"
-@erase "$(INTDIR)\unicode.obj"
-@erase "$(INTDIR)\unpack.obj"
-@erase "$(INTDIR)\vc60.idb"
-@erase "$(INTDIR)\vc60.pdb"
-@erase "$(INTDIR)\volume.obj"
-@erase "$(OUTDIR)\unrar.exe"
-@erase "$(OUTDIR)\unrar.ilk"
-@erase "$(OUTDIR)\unrar.pdb"
"$(OUTDIR)" :
if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
CPP_PROJ=/nologo /W3 /Gm /EHsc /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "UNRAR" /D _CRT_SECURE_NO_WARNINGS /Fp"$(INTDIR)\unrar.pch" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c
BSC32=bscmake.exe
BSC32_FLAGS=/nologo /o"$(OUTDIR)\unrar.bsc"
BSC32_SBRS= \
LINK32=link.exe
LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /incremental:yes /pdb:"$(OUTDIR)\unrar.pdb" /debug /machine:I386 /out:"$(OUTDIR)\unrar.exe" /pdbtype:sept
LINK32_OBJS= \
"$(INTDIR)\rar.obj" \
"$(INTDIR)\strlist.obj" \
"$(INTDIR)\strfn.obj" \
"$(INTDIR)\pathfn.obj" \
"$(INTDIR)\savepos.obj" \
"$(INTDIR)\smallfn.obj" \
"$(INTDIR)\global.obj" \
"$(INTDIR)\file.obj" \
"$(INTDIR)\filefn.obj" \
"$(INTDIR)\filcreat.obj" \
"$(INTDIR)\archive.obj" \
"$(INTDIR)\arcread.obj" \
"$(INTDIR)\unicode.obj" \
"$(INTDIR)\system.obj" \
"$(INTDIR)\isnt.obj" \
"$(INTDIR)\crypt.obj" \
"$(INTDIR)\crc.obj" \
"$(INTDIR)\rawread.obj" \
"$(INTDIR)\encname.obj" \
"$(INTDIR)\resource.obj" \
"$(INTDIR)\match.obj" \
"$(INTDIR)\timefn.obj" \
"$(INTDIR)\rdwrfn.obj" \
"$(INTDIR)\consio.obj" \
"$(INTDIR)\options.obj" \
"$(INTDIR)\ulinks.obj" \
"$(INTDIR)\errhnd.obj" \
"$(INTDIR)\rarvm.obj" \
"$(INTDIR)\rijndael.obj" \
"$(INTDIR)\getbits.obj" \
"$(INTDIR)\sha1.obj" \
"$(INTDIR)\extinfo.obj" \
"$(INTDIR)\extract.obj" \
"$(INTDIR)\volume.obj" \
"$(INTDIR)\list.obj" \
"$(INTDIR)\find.obj" \
"$(INTDIR)\unpack.obj" \
"$(INTDIR)\cmddata.obj" \
"$(INTDIR)\filestr.obj" \
"$(INTDIR)\recvol.obj" \
"$(INTDIR)\rs.obj" \
"$(INTDIR)\scantree.obj"
"$(OUTDIR)\unrar.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
$(LINK32) @<<
$(LINK32_FLAGS) $(LINK32_OBJS)
<<
!ENDIF
.c{$(INTDIR)}.obj::
$(CPP) @<<
$(CPP_PROJ) $<
<<
.cpp{$(INTDIR)}.obj::
$(CPP) @<<
$(CPP_PROJ) $<
<<
.cxx{$(INTDIR)}.obj::
$(CPP) @<<
$(CPP_PROJ) $<
<<
.c{$(INTDIR)}.sbr::
$(CPP) @<<
$(CPP_PROJ) $<
<<
.cpp{$(INTDIR)}.sbr::
$(CPP) @<<
$(CPP_PROJ) $<
<<
.cxx{$(INTDIR)}.sbr::
$(CPP) @<<
$(CPP_PROJ) $<
<<
!IF "$(NO_EXTERNAL_DEPS)" != "1"
!IF EXISTS("msc.dep")
!INCLUDE "msc.dep"
!ELSE
!MESSAGE Warning: cannot find "msc.dep"
!ENDIF
!ENDIF
!IF "$(CFG)" == "unrar - Win32 Release" || "$(CFG)" == "unrar - Win32 Debug"
SOURCE=.\archive.cpp
"$(INTDIR)\archive.obj" : $(SOURCE) "$(INTDIR)"
$(CPP) $(CPP_PROJ) $(SOURCE)
SOURCE=.\arcread.cpp
"$(INTDIR)\arcread.obj" : $(SOURCE) "$(INTDIR)"
$(CPP) $(CPP_PROJ) $(SOURCE)
SOURCE=.\cmddata.cpp
"$(INTDIR)\cmddata.obj" : $(SOURCE) "$(INTDIR)"
$(CPP) $(CPP_PROJ) $(SOURCE)
SOURCE=.\consio.cpp
"$(INTDIR)\consio.obj" : $(SOURCE) "$(INTDIR)"
$(CPP) $(CPP_PROJ) $(SOURCE)
SOURCE=.\crc.cpp
"$(INTDIR)\crc.obj" : $(SOURCE) "$(INTDIR)"
$(CPP) $(CPP_PROJ) $(SOURCE)
SOURCE=.\crypt.cpp
"$(INTDIR)\crypt.obj" : $(SOURCE) "$(INTDIR)"
$(CPP) $(CPP_PROJ) $(SOURCE)
SOURCE=.\encname.cpp
"$(INTDIR)\encname.obj" : $(SOURCE) "$(INTDIR)"
$(CPP) $(CPP_PROJ) $(SOURCE)
SOURCE=.\errhnd.cpp
"$(INTDIR)\errhnd.obj" : $(SOURCE) "$(INTDIR)"
$(CPP) $(CPP_PROJ) $(SOURCE)
SOURCE=.\extinfo.cpp
"$(INTDIR)\extinfo.obj" : $(SOURCE) "$(INTDIR)"
$(CPP) $(CPP_PROJ) $(SOURCE)
SOURCE=.\extract.cpp
"$(INTDIR)\extract.obj" : $(SOURCE) "$(INTDIR)"
$(CPP) $(CPP_PROJ) $(SOURCE)
SOURCE=.\filcreat.cpp
"$(INTDIR)\filcreat.obj" : $(SOURCE) "$(INTDIR)"
$(CPP) $(CPP_PROJ) $(SOURCE)
SOURCE=.\file.cpp
"$(INTDIR)\file.obj" : $(SOURCE) "$(INTDIR)"
$(CPP) $(CPP_PROJ) $(SOURCE)
SOURCE=.\filefn.cpp
"$(INTDIR)\filefn.obj" : $(SOURCE) "$(INTDIR)"
$(CPP) $(CPP_PROJ) $(SOURCE)
SOURCE=.\filestr.cpp
"$(INTDIR)\filestr.obj" : $(SOURCE) "$(INTDIR)"
$(CPP) $(CPP_PROJ) $(SOURCE)
SOURCE=.\find.cpp
"$(INTDIR)\find.obj" : $(SOURCE) "$(INTDIR)"
$(CPP) $(CPP_PROJ) $(SOURCE)
SOURCE=.\getbits.cpp
"$(INTDIR)\getbits.obj" : $(SOURCE) "$(INTDIR)"
$(CPP) $(CPP_PROJ) $(SOURCE)
SOURCE=.\global.cpp
"$(INTDIR)\global.obj" : $(SOURCE) "$(INTDIR)"
$(CPP) $(CPP_PROJ) $(SOURCE)
SOURCE=.\isnt.cpp
"$(INTDIR)\isnt.obj" : $(SOURCE) "$(INTDIR)"
$(CPP) $(CPP_PROJ) $(SOURCE)
SOURCE=.\list.cpp
"$(INTDIR)\list.obj" : $(SOURCE) "$(INTDIR)"
$(CPP) $(CPP_PROJ) $(SOURCE)
SOURCE=.\match.cpp
"$(INTDIR)\match.obj" : $(SOURCE) "$(INTDIR)"
$(CPP) $(CPP_PROJ) $(SOURCE)
SOURCE=.\options.cpp
"$(INTDIR)\options.obj" : $(SOURCE) "$(INTDIR)"
$(CPP) $(CPP_PROJ) $(SOURCE)
SOURCE=.\pathfn.cpp
"$(INTDIR)\pathfn.obj" : $(SOURCE) "$(INTDIR)"
$(CPP) $(CPP_PROJ) $(SOURCE)
SOURCE=.\rar.cpp
"$(INTDIR)\rar.obj" : $(SOURCE) "$(INTDIR)"
$(CPP) $(CPP_PROJ) $(SOURCE)
SOURCE=.\rarvm.cpp
"$(INTDIR)\rarvm.obj" : $(SOURCE) "$(INTDIR)"
$(CPP) $(CPP_PROJ) $(SOURCE)
SOURCE=.\rawread.cpp
"$(INTDIR)\rawread.obj" : $(SOURCE) "$(INTDIR)"
$(CPP) $(CPP_PROJ) $(SOURCE)
SOURCE=.\rdwrfn.cpp
"$(INTDIR)\rdwrfn.obj" : $(SOURCE) "$(INTDIR)"
$(CPP) $(CPP_PROJ) $(SOURCE)
SOURCE=.\recvol.cpp
"$(INTDIR)\recvol.obj" : $(SOURCE) "$(INTDIR)"
$(CPP) $(CPP_PROJ) $(SOURCE)
SOURCE=.\resource.cpp
"$(INTDIR)\resource.obj" : $(SOURCE) "$(INTDIR)"
$(CPP) $(CPP_PROJ) $(SOURCE)
SOURCE=.\rijndael.cpp
"$(INTDIR)\rijndael.obj" : $(SOURCE) "$(INTDIR)"
$(CPP) $(CPP_PROJ) $(SOURCE)
SOURCE=.\rs.cpp
"$(INTDIR)\rs.obj" : $(SOURCE) "$(INTDIR)"
$(CPP) $(CPP_PROJ) $(SOURCE)
SOURCE=.\savepos.cpp
"$(INTDIR)\savepos.obj" : $(SOURCE) "$(INTDIR)"
$(CPP) $(CPP_PROJ) $(SOURCE)
SOURCE=.\smallfn.cpp
"$(INTDIR)\smallfn.obj" : $(SOURCE) "$(INTDIR)"
$(CPP) $(CPP_PROJ) $(SOURCE)
SOURCE=.\scantree.cpp
"$(INTDIR)\scantree.obj" : $(SOURCE) "$(INTDIR)"
$(CPP) $(CPP_PROJ) $(SOURCE)
SOURCE=.\sha1.cpp
"$(INTDIR)\sha1.obj" : $(SOURCE) "$(INTDIR)"
$(CPP) $(CPP_PROJ) $(SOURCE)
SOURCE=.\strfn.cpp
"$(INTDIR)\strfn.obj" : $(SOURCE) "$(INTDIR)"
$(CPP) $(CPP_PROJ) $(SOURCE)
SOURCE=.\strlist.cpp
"$(INTDIR)\strlist.obj" : $(SOURCE) "$(INTDIR)"
$(CPP) $(CPP_PROJ) $(SOURCE)
SOURCE=.\system.cpp
"$(INTDIR)\system.obj" : $(SOURCE) "$(INTDIR)"
$(CPP) $(CPP_PROJ) $(SOURCE)
SOURCE=.\timefn.cpp
"$(INTDIR)\timefn.obj" : $(SOURCE) "$(INTDIR)"
$(CPP) $(CPP_PROJ) $(SOURCE)
SOURCE=.\ulinks.cpp
"$(INTDIR)\ulinks.obj" : $(SOURCE) "$(INTDIR)"
$(CPP) $(CPP_PROJ) $(SOURCE)
SOURCE=.\unicode.cpp
"$(INTDIR)\unicode.obj" : $(SOURCE) "$(INTDIR)"
$(CPP) $(CPP_PROJ) $(SOURCE)
SOURCE=.\unpack.cpp
"$(INTDIR)\unpack.obj" : $(SOURCE) "$(INTDIR)"
$(CPP) $(CPP_PROJ) $(SOURCE)
SOURCE=.\volume.cpp
"$(INTDIR)\volume.obj" : $(SOURCE) "$(INTDIR)"
$(CPP) $(CPP_PROJ) $(SOURCE)
!ENDIF

148
libunrar/makefile.unix Normal file
View File

@ -0,0 +1,148 @@
#
# Makefile for UNIX - unrar
#
# Note: you have to 'make clean' before you can build
# the sfx module
#
# Linux using GCC
#CXX=g++
#CXXFLAGS=-O2
DEFINES=-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -DGUI -DSILENT
STRIP=strip
DESTDIR=/usr
# Linux using LCC
#CXX=lcc
#CXXFLAGS=-O2
#DEFINES=-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
#STRIP=strip
#DESTDIR=/usr
# HP UX using aCC
#CXX=aCC
#CXXFLAGS=-AA +O2 +Onolimit
#DEFINES=-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
#STRIP=strip
#DESTDIR=/usr
# IRIX using GCC
#CXX=g++
#CXXFLAGS=-O2
#DEFINES=-DBIG_ENDIAN -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_BSD_COMPAT -D_XOPEN_SOURCE -D_XOPEN_SOURCE_EXTENDED=1
#STRIP=strip
#DESTDIR=/usr
# IRIX using MIPSPro (experimental)
#CXX=CC
#CXXFLAGS=-O2 -mips3 -woff 1234,1156,3284 -LANG:std
#DEFINES=-DBIG_ENDIAN -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_BSD_COMPAT -Dint64=int64_t
#STRIP=strip
#DESTDIR=/usr
# AIX using xlC (IBM VisualAge C++ 5.0)
#CXX=xlC
#CXXFLAGS=-O -qinline -qro -qroconst -qmaxmem=16384 -qcpluscmt
#DEFINES=-D_LARGE_FILES -D_LARGE_FILE_API
#LIBS=-lbsd
#STRIP=strip
#DESTDIR=/usr
# Solaris using CC
#CXX=CC
#CXXFLAGS=-fast -erroff=wvarhidemem
#DEFINES=-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
#STRIP=strip
#DESTDIR=/usr
# Solaris using GCC (optimized for UltraSPARC 1 CPU)
#CXX=g++
#CXXFLAGS=-O3 -mcpu=v9 -mtune=ultrasparc -m32
#DEFINES=-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
#STRIP=/usr/ccs/bin/strip
#DESTDIR=/usr
# Tru64 5.1B using GCC3
#CXX=g++
#CXXFLAGS=-O2 -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_XOPEN_SOURCE=500
#STRIP=strip
#LDFLAGS=-rpath /usr/local/gcc/lib
#DESTDIR=/usr
# Tru64 5.1B using DEC C++
#CXX=cxx
#CXXFLAGS=-O4 -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -Dint64=long
#STRIP=strip
#LDFLAGS=
#DESTDIR=/usr
# QNX 6.x using GCC
#CXX=g++
#CXXFLAGS=-O2 -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -fexceptions
#STRIP=strip
#LDFLAGS=-fexceptions
#DESTDIR=/usr
# Cross-compile
# Linux using arm-linux-g++
#CXX=arm-linux-g++
#CXXFLAGS=-O2
#DEFINES=-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
#STRIP=arm-linux-strip
#LDFLAGS=-static
#DESTDIR=/usr
##########################
COMPILE=$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(DEFINES)
LINK=$(CXX)
WHAT=UNRAR
UNRAR_OBJ=filestr.o recvol.o rs.o scantree.o
LIB_OBJ=filestr.o scantree.o dll.o
OBJECTS=rar.o strlist.o strfn.o pathfn.o savepos.o smallfn.o global.o file.o filefn.o filcreat.o \
archive.o arcread.o unicode.o system.o isnt.o crypt.o crc.o rawread.o encname.o \
resource.o match.o timefn.o rdwrfn.o consio.o options.o ulinks.o errhnd.o rarvm.o \
rijndael.o getbits.o sha1.o extinfo.o extract.o volume.o list.o find.o unpack.o cmddata.o
.cpp.o:
$(COMPILE) -D$(WHAT) -c $<
all: unrar
install: install-unrar
uninstall: uninstall-unrar
clean:
@rm -f *.o *.bak *~
unrar: $(OBJECTS) $(UNRAR_OBJ)
@rm -f unrar
$(LINK) -o unrar $(LDFLAGS) $(OBJECTS) $(UNRAR_OBJ) $(LIBS)
$(STRIP) unrar
sfx: WHAT=SFX_MODULE
sfx: $(OBJECTS)
@rm -f default.sfx
$(LINK) -o default.sfx $(LDFLAGS) $(OBJECTS)
$(STRIP) default.sfx
lib: WHAT=RARDLL
lib: $(OBJECTS) $(LIB_OBJ)
@rm -f libunrar.so
$(LINK) -shared -o libunrar.so $(LDFLAGS) $(OBJECTS) $(LIB_OBJ)
install-unrar:
install unrar $(DESTDIR)/bin
uninstall-unrar:
rm -f $(DESTDIR)/bin/unrar
install-lib:
install libunrar.so $(DESTDIR)/lib
uninstall-lib:
rm -f $(DESTDIR)/lib/libunrar.so

270
libunrar/match.cpp Normal file
View File

@ -0,0 +1,270 @@
#include "rar.hpp"
static bool match(char *pattern,char *string,bool ForceCase);
static bool match(wchar *pattern,wchar *string,bool ForceCase);
static int mstricompc(const char *Str1,const char *Str2,bool ForceCase);
static int mstricompcw(const wchar *Str1,const wchar *Str2,bool ForceCase);
static int mstrnicompc(const char *Str1,const char *Str2,size_t N,bool ForceCase);
static int mstrnicompcw(const wchar *Str1,const wchar *Str2,size_t N,bool ForceCase);
inline uint toupperc(byte ch,bool ForceCase)
{
if (ForceCase)
return(ch);
#ifdef _WIN_32
return((uint)(LPARAM)CharUpper((LPTSTR)(ch)));
#elif defined(_UNIX)
return(ch);
#else
return(toupper(ch));
#endif
}
inline uint touppercw(uint ch,bool ForceCase)
{
if (ForceCase)
return(ch);
#if defined(_UNIX)
return(ch);
#else
return(toupperw(ch));
#endif
}
bool CmpName(char *Wildcard,char *Name,int CmpPath)
{
bool ForceCase=(CmpPath&MATCH_FORCECASESENSITIVE)!=0;
CmpPath&=MATCH_MODEMASK;
if (CmpPath!=MATCH_NAMES)
{
size_t WildLength=strlen(Wildcard);
if (CmpPath!=MATCH_EXACTPATH && mstrnicompc(Wildcard,Name,WildLength,ForceCase)==0)
{
char NextCh=Name[WildLength];
if (NextCh=='\\' || NextCh=='/' || NextCh==0)
return(true);
}
char Path1[NM],Path2[NM];
GetFilePath(Wildcard,Path1,ASIZE(Path1));
GetFilePath(Name,Path2,ASIZE(Path1));
if (mstricompc(Wildcard,Path2,ForceCase)==0)
return(true);
if ((CmpPath==MATCH_PATH || CmpPath==MATCH_EXACTPATH) && mstricompc(Path1,Path2,ForceCase)!=0)
return(false);
if (CmpPath==MATCH_SUBPATH || CmpPath==MATCH_WILDSUBPATH)
if (IsWildcard(Path1))
return(match(Wildcard,Name,ForceCase));
else
if (CmpPath==MATCH_SUBPATH || IsWildcard(Wildcard))
{
if (*Path1 && mstrnicompc(Path1,Path2,strlen(Path1),ForceCase)!=0)
return(false);
}
else
if (mstricompc(Path1,Path2,ForceCase)!=0)
return(false);
}
char *Name1=PointToName(Wildcard);
char *Name2=PointToName(Name);
// always return false for RAR temporary files to exclude them
// from archiving operations
if (mstrnicompc("__rar_",Name2,6,false)==0)
return(false);
return(match(Name1,Name2,ForceCase));
}
#ifndef SFX_MODULE
bool CmpName(wchar *Wildcard,wchar *Name,int CmpPath)
{
bool ForceCase=(CmpPath&MATCH_FORCECASESENSITIVE)!=0;
CmpPath&=MATCH_MODEMASK;
if (CmpPath!=MATCH_NAMES)
{
size_t WildLength=strlenw(Wildcard);
if (CmpPath!=MATCH_EXACTPATH && mstrnicompcw(Wildcard,Name,WildLength,ForceCase)==0)
{
wchar NextCh=Name[WildLength];
if (NextCh==L'\\' || NextCh==L'/' || NextCh==0)
return(true);
}
wchar Path1[NM],Path2[NM];
GetFilePath(Wildcard,Path1,ASIZE(Path1));
GetFilePath(Name,Path2,ASIZE(Path2));
if ((CmpPath==MATCH_PATH || CmpPath==MATCH_EXACTPATH) && mstricompcw(Path1,Path2,ForceCase)!=0)
return(false);
if (CmpPath==MATCH_SUBPATH || CmpPath==MATCH_WILDSUBPATH)
if (IsWildcard(NULL,Path1))
return(match(Wildcard,Name,ForceCase));
else
if (CmpPath==MATCH_SUBPATH || IsWildcard(NULL,Wildcard))
{
if (*Path1 && mstrnicompcw(Path1,Path2,strlenw(Path1),ForceCase)!=0)
return(false);
}
else
if (mstricompcw(Path1,Path2,ForceCase)!=0)
return(false);
}
wchar *Name1=PointToName(Wildcard);
wchar *Name2=PointToName(Name);
// always return false for RAR temporary files to exclude them
// from archiving operations
if (mstrnicompcw(L"__rar_",Name2,6,false)==0)
return(false);
return(match(Name1,Name2,ForceCase));
}
#endif
bool match(char *pattern,char *string,bool ForceCase)
{
for (;; ++string)
{
char stringc=toupperc(*string,ForceCase);
char patternc=toupperc(*pattern++,ForceCase);
switch (patternc)
{
case 0:
return(stringc==0);
case '?':
if (stringc == 0)
return(false);
break;
case '*':
if (*pattern==0)
return(true);
if (*pattern=='.')
{
if (pattern[1]=='*' && pattern[2]==0)
return(true);
char *dot=strchr(string,'.');
if (pattern[1]==0)
return (dot==NULL || dot[1]==0);
if (dot!=NULL)
{
string=dot;
if (strpbrk(pattern,"*?")==NULL && strchr(string+1,'.')==NULL)
return(mstricompc(pattern+1,string+1,ForceCase)==0);
}
}
while (*string)
if (match(pattern,string++,ForceCase))
return(true);
return(false);
default:
if (patternc != stringc)
if (patternc=='.' && stringc==0)
return(match(pattern,string,ForceCase));
else
return(false);
break;
}
}
}
#ifndef SFX_MODULE
bool match(wchar *pattern,wchar *string,bool ForceCase)
{
for (;; ++string)
{
wchar stringc=touppercw(*string,ForceCase);
wchar patternc=touppercw(*pattern++,ForceCase);
switch (patternc)
{
case 0:
return(stringc==0);
case '?':
if (stringc == 0)
return(false);
break;
case '*':
if (*pattern==0)
return(true);
if (*pattern=='.')
{
if (pattern[1]=='*' && pattern[2]==0)
return(true);
wchar *dot=strchrw(string,'.');
if (pattern[1]==0)
return (dot==NULL || dot[1]==0);
if (dot!=NULL)
{
string=dot;
if (strpbrkw(pattern,L"*?")==NULL && strchrw(string+1,'.')==NULL)
return(mstricompcw(pattern+1,string+1,ForceCase)==0);
}
}
while (*string)
if (match(pattern,string++,ForceCase))
return(true);
return(false);
default:
if (patternc != stringc)
if (patternc=='.' && stringc==0)
return(match(pattern,string,ForceCase));
else
return(false);
break;
}
}
}
#endif
int mstricompc(const char *Str1,const char *Str2,bool ForceCase)
{
if (ForceCase)
return(strcmp(Str1,Str2));
return(stricompc(Str1,Str2));
}
#ifndef SFX_MODULE
int mstricompcw(const wchar *Str1,const wchar *Str2,bool ForceCase)
{
if (ForceCase)
return(strcmpw(Str1,Str2));
return(stricompcw(Str1,Str2));
}
#endif
int mstrnicompc(const char *Str1,const char *Str2,size_t N,bool ForceCase)
{
if (ForceCase)
return(strncmp(Str1,Str2,N));
#if defined(_UNIX)
return(strncmp(Str1,Str2,N));
#else
return(strnicomp(Str1,Str2,N));
#endif
}
#ifndef SFX_MODULE
int mstrnicompcw(const wchar *Str1,const wchar *Str2,size_t N,bool ForceCase)
{
if (ForceCase)
return(strncmpw(Str1,Str2,N));
#if defined(_UNIX)
return(strncmpw(Str1,Str2,N));
#else
return(strnicmpw(Str1,Str2,N));
#endif
}
#endif

27
libunrar/match.hpp Normal file
View File

@ -0,0 +1,27 @@
#ifndef _RAR_MATCH_
#define _RAR_MATCH_
enum {
MATCH_NAMES, // Compare names only.
MATCH_PATH, // Compares names and paths. Both must match exactly.
// Unlike MATCH_EXACTPATH, also matches names if
// mask contains path only and this path is a part
// of name path.
MATCH_EXACTPATH, // Compares names and paths. Both must match exactly.
MATCH_SUBPATH, // Names must be the same, but path in mask is allowed
// to be only a part of name path.
MATCH_WILDSUBPATH // Works as MATCH_SUBPATH if mask contains wildcards
// and as MATCH_PATH otherwise.
};
#define MATCH_MODEMASK 0x0000ffff
#define MATCH_FORCECASESENSITIVE 0x80000000
bool CmpName(char *Wildcard,char *Name,int CmpPath);
bool CmpName(wchar *Wildcard,wchar *Name,int CmpPath);
#endif

610
libunrar/model.cpp Normal file
View File

@ -0,0 +1,610 @@
/****************************************************************************
* This file is part of PPMd project *
* Written and distributed to public domain by Dmitry Shkarin 1997, *
* 1999-2000 *
* Contents: model description and encoding/decoding routines *
****************************************************************************/
inline PPM_CONTEXT* PPM_CONTEXT::createChild(ModelPPM *Model,STATE* pStats,
STATE& FirstState)
{
PPM_CONTEXT* pc = (PPM_CONTEXT*) Model->SubAlloc.AllocContext();
if ( pc )
{
pc->NumStats=1;
pc->OneState=FirstState;
pc->Suffix=this;
pStats->Successor=pc;
}
return pc;
}
ModelPPM::ModelPPM()
{
MinContext=NULL;
MaxContext=NULL;
MedContext=NULL;
}
void ModelPPM::RestartModelRare()
{
int i, k, m;
memset(CharMask,0,sizeof(CharMask));
SubAlloc.InitSubAllocator();
InitRL=-(MaxOrder < 12 ? MaxOrder:12)-1;
MinContext = MaxContext = (PPM_CONTEXT*) SubAlloc.AllocContext();
MinContext->Suffix=NULL;
OrderFall=MaxOrder;
MinContext->U.SummFreq=(MinContext->NumStats=256)+1;
FoundState=MinContext->U.Stats=(STATE*)SubAlloc.AllocUnits(256/2);
for (RunLength=InitRL, PrevSuccess=i=0;i < 256;i++)
{
MinContext->U.Stats[i].Symbol=i;
MinContext->U.Stats[i].Freq=1;
MinContext->U.Stats[i].Successor=NULL;
}
static const ushort InitBinEsc[]={
0x3CDD,0x1F3F,0x59BF,0x48F3,0x64A1,0x5ABC,0x6632,0x6051
};
for (i=0;i < 128;i++)
for (k=0;k < 8;k++)
for (m=0;m < 64;m += 8)
BinSumm[i][k+m]=BIN_SCALE-InitBinEsc[k]/(i+2);
for (i=0;i < 25;i++)
for (k=0;k < 16;k++)
SEE2Cont[i][k].init(5*i+10);
}
void ModelPPM::StartModelRare(int MaxOrder)
{
int i, k, m ,Step;
EscCount=1;
/*
if (MaxOrder < 2)
{
memset(CharMask,0,sizeof(CharMask));
OrderFall=ModelPPM::MaxOrder;
MinContext=MaxContext;
while (MinContext->Suffix != NULL)
{
MinContext=MinContext->Suffix;
OrderFall--;
}
FoundState=MinContext->U.Stats;
MinContext=MaxContext;
}
else
*/
{
ModelPPM::MaxOrder=MaxOrder;
RestartModelRare();
NS2BSIndx[0]=2*0;
NS2BSIndx[1]=2*1;
memset(NS2BSIndx+2,2*2,9);
memset(NS2BSIndx+11,2*3,256-11);
for (i=0;i < 3;i++)
NS2Indx[i]=i;
for (m=i, k=Step=1;i < 256;i++)
{
NS2Indx[i]=m;
if ( !--k )
{
k = ++Step;
m++;
}
}
memset(HB2Flag,0,0x40);
memset(HB2Flag+0x40,0x08,0x100-0x40);
DummySEE2Cont.Shift=PERIOD_BITS;
}
}
void PPM_CONTEXT::rescale(ModelPPM *Model)
{
int OldNS=NumStats, i=NumStats-1, Adder, EscFreq;
STATE* p1, * p;
for (p=Model->FoundState;p != U.Stats;p--)
_PPMD_SWAP(p[0],p[-1]);
U.Stats->Freq += 4;
U.SummFreq += 4;
EscFreq=U.SummFreq-p->Freq;
Adder=(Model->OrderFall != 0);
U.SummFreq = (p->Freq=(p->Freq+Adder) >> 1);
do
{
EscFreq -= (++p)->Freq;
U.SummFreq += (p->Freq=(p->Freq+Adder) >> 1);
if (p[0].Freq > p[-1].Freq)
{
STATE tmp=*(p1=p);
do
{
p1[0]=p1[-1];
} while (--p1 != U.Stats && tmp.Freq > p1[-1].Freq);
*p1=tmp;
}
} while ( --i );
if (p->Freq == 0)
{
do
{
i++;
} while ((--p)->Freq == 0);
EscFreq += i;
if ((NumStats -= i) == 1)
{
STATE tmp=*U.Stats;
do
{
tmp.Freq-=(tmp.Freq >> 1);
EscFreq>>=1;
} while (EscFreq > 1);
Model->SubAlloc.FreeUnits(U.Stats,(OldNS+1) >> 1);
*(Model->FoundState=&OneState)=tmp; return;
}
}
U.SummFreq += (EscFreq -= (EscFreq >> 1));
int n0=(OldNS+1) >> 1, n1=(NumStats+1) >> 1;
if (n0 != n1)
U.Stats = (STATE*) Model->SubAlloc.ShrinkUnits(U.Stats,n0,n1);
Model->FoundState=U.Stats;
}
inline PPM_CONTEXT* ModelPPM::CreateSuccessors(bool Skip,STATE* p1)
{
#ifdef __ICL
static
#endif
STATE UpState;
PPM_CONTEXT* pc=MinContext, * UpBranch=FoundState->Successor;
STATE * p, * ps[MAX_O], ** pps=ps;
if ( !Skip )
{
*pps++ = FoundState;
if ( !pc->Suffix )
goto NO_LOOP;
}
if ( p1 )
{
p=p1;
pc=pc->Suffix;
goto LOOP_ENTRY;
}
do
{
pc=pc->Suffix;
if (pc->NumStats != 1)
{
if ((p=pc->U.Stats)->Symbol != FoundState->Symbol)
do
{
p++;
} while (p->Symbol != FoundState->Symbol);
}
else
p=&(pc->OneState);
LOOP_ENTRY:
if (p->Successor != UpBranch)
{
pc=p->Successor;
break;
}
*pps++ = p;
} while ( pc->Suffix );
NO_LOOP:
if (pps == ps)
return pc;
UpState.Symbol=*(byte*) UpBranch;
UpState.Successor=(PPM_CONTEXT*) (((byte*) UpBranch)+1);
if (pc->NumStats != 1)
{
if ((byte*) pc <= SubAlloc.pText)
return(NULL);
if ((p=pc->U.Stats)->Symbol != UpState.Symbol)
do
{
p++;
} while (p->Symbol != UpState.Symbol);
uint cf=p->Freq-1;
uint s0=pc->U.SummFreq-pc->NumStats-cf;
UpState.Freq=1+((2*cf <= s0)?(5*cf > s0):((2*cf+3*s0-1)/(2*s0)));
}
else
UpState.Freq=pc->OneState.Freq;
do
{
pc = pc->createChild(this,*--pps,UpState);
if ( !pc )
return NULL;
} while (pps != ps);
return pc;
}
inline void ModelPPM::UpdateModel()
{
STATE fs = *FoundState, *p = NULL;
PPM_CONTEXT *pc, *Successor;
uint ns1, ns, cf, sf, s0;
if (fs.Freq < MAX_FREQ/4 && (pc=MinContext->Suffix) != NULL)
{
if (pc->NumStats != 1)
{
if ((p=pc->U.Stats)->Symbol != fs.Symbol)
{
do
{
p++;
} while (p->Symbol != fs.Symbol);
if (p[0].Freq >= p[-1].Freq)
{
_PPMD_SWAP(p[0],p[-1]);
p--;
}
}
if (p->Freq < MAX_FREQ-9)
{
p->Freq += 2;
pc->U.SummFreq += 2;
}
}
else
{
p=&(pc->OneState);
p->Freq += (p->Freq < 32);
}
}
if ( !OrderFall )
{
MinContext=MaxContext=FoundState->Successor=CreateSuccessors(TRUE,p);
if ( !MinContext )
goto RESTART_MODEL;
return;
}
*SubAlloc.pText++ = fs.Symbol;
Successor = (PPM_CONTEXT*) SubAlloc.pText;
if (SubAlloc.pText >= SubAlloc.FakeUnitsStart)
goto RESTART_MODEL;
if ( fs.Successor )
{
if ((byte*) fs.Successor <= SubAlloc.pText &&
(fs.Successor=CreateSuccessors(FALSE,p)) == NULL)
goto RESTART_MODEL;
if ( !--OrderFall )
{
Successor=fs.Successor;
SubAlloc.pText -= (MaxContext != MinContext);
}
}
else
{
FoundState->Successor=Successor;
fs.Successor=MinContext;
}
s0=MinContext->U.SummFreq-(ns=MinContext->NumStats)-(fs.Freq-1);
for (pc=MaxContext;pc != MinContext;pc=pc->Suffix)
{
if ((ns1=pc->NumStats) != 1)
{
if ((ns1 & 1) == 0)
{
pc->U.Stats=(STATE*) SubAlloc.ExpandUnits(pc->U.Stats,ns1 >> 1);
if ( !pc->U.Stats )
goto RESTART_MODEL;
}
pc->U.SummFreq += (2*ns1 < ns)+2*((4*ns1 <= ns) & (pc->U.SummFreq <= 8*ns1));
}
else
{
p=(STATE*) SubAlloc.AllocUnits(1);
if ( !p )
goto RESTART_MODEL;
*p=pc->OneState;
pc->U.Stats=p;
if (p->Freq < MAX_FREQ/4-1)
p->Freq += p->Freq;
else
p->Freq = MAX_FREQ-4;
pc->U.SummFreq=p->Freq+InitEsc+(ns > 3);
}
cf=2*fs.Freq*(pc->U.SummFreq+6);
sf=s0+pc->U.SummFreq;
if (cf < 6*sf)
{
cf=1+(cf > sf)+(cf >= 4*sf);
pc->U.SummFreq += 3;
}
else
{
cf=4+(cf >= 9*sf)+(cf >= 12*sf)+(cf >= 15*sf);
pc->U.SummFreq += cf;
}
p=pc->U.Stats+ns1;
p->Successor=Successor;
p->Symbol = fs.Symbol;
p->Freq = cf;
pc->NumStats=++ns1;
}
MaxContext=MinContext=fs.Successor;
return;
RESTART_MODEL:
RestartModelRare();
EscCount=0;
}
// Tabulated escapes for exponential symbol distribution
static const byte ExpEscape[16]={ 25,14, 9, 7, 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 2 };
#define GET_MEAN(SUMM,SHIFT,ROUND) ((SUMM+(1 << (SHIFT-ROUND))) >> (SHIFT))
inline void PPM_CONTEXT::decodeBinSymbol(ModelPPM *Model)
{
STATE& rs=OneState;
Model->HiBitsFlag=Model->HB2Flag[Model->FoundState->Symbol];
ushort& bs=Model->BinSumm[rs.Freq-1][Model->PrevSuccess+
Model->NS2BSIndx[Suffix->NumStats-1]+
Model->HiBitsFlag+2*Model->HB2Flag[rs.Symbol]+
((Model->RunLength >> 26) & 0x20)];
if (Model->Coder.GetCurrentShiftCount(TOT_BITS) < bs)
{
Model->FoundState=&rs;
rs.Freq += (rs.Freq < 128);
Model->Coder.SubRange.LowCount=0;
Model->Coder.SubRange.HighCount=bs;
bs = SHORT16(bs+INTERVAL-GET_MEAN(bs,PERIOD_BITS,2));
Model->PrevSuccess=1;
Model->RunLength++;
}
else
{
Model->Coder.SubRange.LowCount=bs;
bs = SHORT16(bs-GET_MEAN(bs,PERIOD_BITS,2));
Model->Coder.SubRange.HighCount=BIN_SCALE;
Model->InitEsc=ExpEscape[bs >> 10];
Model->NumMasked=1;
Model->CharMask[rs.Symbol]=Model->EscCount;
Model->PrevSuccess=0;
Model->FoundState=NULL;
}
}
inline void PPM_CONTEXT::update1(ModelPPM *Model,STATE* p)
{
(Model->FoundState=p)->Freq += 4;
U.SummFreq += 4;
if (p[0].Freq > p[-1].Freq)
{
_PPMD_SWAP(p[0],p[-1]);
Model->FoundState=--p;
if (p->Freq > MAX_FREQ)
rescale(Model);
}
}
inline bool PPM_CONTEXT::decodeSymbol1(ModelPPM *Model)
{
Model->Coder.SubRange.scale=U.SummFreq;
STATE* p=U.Stats;
int i, HiCnt;
int count=Model->Coder.GetCurrentCount();
if (count>=(int)Model->Coder.SubRange.scale)
return(false);
if (count < (HiCnt=p->Freq))
{
Model->PrevSuccess=(2*(Model->Coder.SubRange.HighCount=HiCnt) > Model->Coder.SubRange.scale);
Model->RunLength += Model->PrevSuccess;
(Model->FoundState=p)->Freq=(HiCnt += 4);
U.SummFreq += 4;
if (HiCnt > MAX_FREQ)
rescale(Model);
Model->Coder.SubRange.LowCount=0;
return(true);
}
else
if (Model->FoundState==NULL)
return(false);
Model->PrevSuccess=0;
i=NumStats-1;
while ((HiCnt += (++p)->Freq) <= count)
if (--i == 0)
{
Model->HiBitsFlag=Model->HB2Flag[Model->FoundState->Symbol];
Model->Coder.SubRange.LowCount=HiCnt;
Model->CharMask[p->Symbol]=Model->EscCount;
i=(Model->NumMasked=NumStats)-1;
Model->FoundState=NULL;
do
{
Model->CharMask[(--p)->Symbol]=Model->EscCount;
} while ( --i );
Model->Coder.SubRange.HighCount=Model->Coder.SubRange.scale;
return(true);
}
Model->Coder.SubRange.LowCount=(Model->Coder.SubRange.HighCount=HiCnt)-p->Freq;
update1(Model,p);
return(true);
}
inline void PPM_CONTEXT::update2(ModelPPM *Model,STATE* p)
{
(Model->FoundState=p)->Freq += 4;
U.SummFreq += 4;
if (p->Freq > MAX_FREQ)
rescale(Model);
Model->EscCount++;
Model->RunLength=Model->InitRL;
}
inline SEE2_CONTEXT* PPM_CONTEXT::makeEscFreq2(ModelPPM *Model,int Diff)
{
SEE2_CONTEXT* psee2c;
if (NumStats != 256)
{
psee2c=Model->SEE2Cont[Model->NS2Indx[Diff-1]]+
(Diff < Suffix->NumStats-NumStats)+
2*(U.SummFreq < 11*NumStats)+4*(Model->NumMasked > Diff)+
Model->HiBitsFlag;
Model->Coder.SubRange.scale=psee2c->getMean();
}
else
{
psee2c=&Model->DummySEE2Cont;
Model->Coder.SubRange.scale=1;
}
return psee2c;
}
inline bool PPM_CONTEXT::decodeSymbol2(ModelPPM *Model)
{
int count, HiCnt, i=NumStats-Model->NumMasked;
SEE2_CONTEXT* psee2c=makeEscFreq2(Model,i);
STATE* ps[256], ** pps=ps, * p=U.Stats-1;
HiCnt=0;
do
{
do
{
p++;
} while (Model->CharMask[p->Symbol] == Model->EscCount);
HiCnt += p->Freq;
*pps++ = p;
} while ( --i );
Model->Coder.SubRange.scale += HiCnt;
count=Model->Coder.GetCurrentCount();
if (count>=(int)Model->Coder.SubRange.scale)
return(false);
p=*(pps=ps);
if (count < HiCnt)
{
HiCnt=0;
while ((HiCnt += p->Freq) <= count)
p=*++pps;
Model->Coder.SubRange.LowCount = (Model->Coder.SubRange.HighCount=HiCnt)-p->Freq;
psee2c->update();
update2(Model,p);
}
else
{
Model->Coder.SubRange.LowCount=HiCnt;
Model->Coder.SubRange.HighCount=Model->Coder.SubRange.scale;
i=NumStats-Model->NumMasked;
pps--;
do
{
Model->CharMask[(*++pps)->Symbol]=Model->EscCount;
} while ( --i );
psee2c->Summ += Model->Coder.SubRange.scale;
Model->NumMasked = NumStats;
}
return(true);
}
inline void ModelPPM::ClearMask()
{
EscCount=1;
memset(CharMask,0,sizeof(CharMask));
}
// reset PPM variables after data error allowing safe resuming
// of further data processing
void ModelPPM::CleanUp()
{
SubAlloc.StopSubAllocator();
SubAlloc.StartSubAllocator(1);
StartModelRare(2);
}
bool ModelPPM::DecodeInit(Unpack *UnpackRead,int &EscChar)
{
int MaxOrder=UnpackRead->GetChar();
bool Reset=(MaxOrder & 0x20)!=0;
int MaxMB;
if (Reset)
MaxMB=UnpackRead->GetChar();
else
if (SubAlloc.GetAllocatedMemory()==0)
return(false);
if (MaxOrder & 0x40)
EscChar=UnpackRead->GetChar();
Coder.InitDecoder(UnpackRead);
if (Reset)
{
MaxOrder=(MaxOrder & 0x1f)+1;
if (MaxOrder>16)
MaxOrder=16+(MaxOrder-16)*3;
if (MaxOrder==1)
{
SubAlloc.StopSubAllocator();
return(false);
}
SubAlloc.StartSubAllocator(MaxMB+1);
StartModelRare(MaxOrder);
}
return(MinContext!=NULL);
}
int ModelPPM::DecodeChar()
{
if ((byte*)MinContext <= SubAlloc.pText || (byte*)MinContext>SubAlloc.HeapEnd)
return(-1);
if (MinContext->NumStats != 1)
{
if ((byte*)MinContext->U.Stats <= SubAlloc.pText || (byte*)MinContext->U.Stats>SubAlloc.HeapEnd)
return(-1);
if (!MinContext->decodeSymbol1(this))
return(-1);
}
else
MinContext->decodeBinSymbol(this);
Coder.Decode();
while ( !FoundState )
{
ARI_DEC_NORMALIZE(Coder.code,Coder.low,Coder.range,Coder.UnpackRead);
do
{
OrderFall++;
MinContext=MinContext->Suffix;
if ((byte*)MinContext <= SubAlloc.pText || (byte*)MinContext>SubAlloc.HeapEnd)
return(-1);
} while (MinContext->NumStats == NumMasked);
if (!MinContext->decodeSymbol2(this))
return(-1);
Coder.Decode();
}
int Symbol=FoundState->Symbol;
if (!OrderFall && (byte*) FoundState->Successor > SubAlloc.pText)
MinContext=MaxContext=FoundState->Successor;
else
{
UpdateModel();
if (EscCount == 0)
ClearMask();
}
ARI_DEC_NORMALIZE(Coder.code,Coder.low,Coder.range,Coder.UnpackRead);
return(Symbol);
}

132
libunrar/model.hpp Normal file
View File

@ -0,0 +1,132 @@
#ifndef _RAR_PPMMODEL_
#define _RAR_PPMMODEL_
#include "coder.hpp"
#include "suballoc.hpp"
const int MAX_O=64; /* maximum allowed model order */
const int INT_BITS=7, PERIOD_BITS=7, TOT_BITS=INT_BITS+PERIOD_BITS,
INTERVAL=1 << INT_BITS, BIN_SCALE=1 << TOT_BITS, MAX_FREQ=124;
#ifndef STRICT_ALIGNMENT_REQUIRED
#pragma pack(1)
#endif
struct SEE2_CONTEXT
{ // SEE-contexts for PPM-contexts with masked symbols
ushort Summ;
byte Shift, Count;
void init(int InitVal)
{
Summ=InitVal << (Shift=PERIOD_BITS-4);
Count=4;
}
uint getMean()
{
uint RetVal=SHORT16(Summ) >> Shift;
Summ -= RetVal;
return RetVal+(RetVal == 0);
}
void update()
{
if (Shift < PERIOD_BITS && --Count == 0)
{
Summ += Summ;
Count=3 << Shift++;
}
}
};
class ModelPPM;
struct PPM_CONTEXT;
struct STATE
{
byte Symbol;
byte Freq;
PPM_CONTEXT* Successor;
};
struct FreqData
{
ushort SummFreq;
STATE _PACK_ATTR * Stats;
};
struct PPM_CONTEXT
{
ushort NumStats;
union
{
FreqData U;
STATE OneState;
};
PPM_CONTEXT* Suffix;
inline void encodeBinSymbol(ModelPPM *Model,int symbol); // MaxOrder:
inline void encodeSymbol1(ModelPPM *Model,int symbol); // ABCD context
inline void encodeSymbol2(ModelPPM *Model,int symbol); // BCD suffix
inline void decodeBinSymbol(ModelPPM *Model); // BCDE successor
inline bool decodeSymbol1(ModelPPM *Model); // other orders:
inline bool decodeSymbol2(ModelPPM *Model); // BCD context
inline void update1(ModelPPM *Model,STATE* p); // CD suffix
inline void update2(ModelPPM *Model,STATE* p); // BCDE successor
void rescale(ModelPPM *Model);
inline PPM_CONTEXT* createChild(ModelPPM *Model,STATE* pStats,STATE& FirstState);
inline SEE2_CONTEXT* makeEscFreq2(ModelPPM *Model,int Diff);
};
#ifndef STRICT_ALIGNMENT_REQUIRED
#ifdef _AIX
#pragma pack(pop)
#else
#pragma pack()
#endif
#endif
const uint UNIT_SIZE=Max(sizeof(PPM_CONTEXT),sizeof(RAR_MEM_BLK));
const uint FIXED_UNIT_SIZE=12;
/*
inline PPM_CONTEXT::PPM_CONTEXT(STATE* pStats,PPM_CONTEXT* ShorterContext):
NumStats(1), Suffix(ShorterContext) { pStats->Successor=this; }
inline PPM_CONTEXT::PPM_CONTEXT(): NumStats(0) {}
*/
template <class T>
inline void _PPMD_SWAP(T& t1,T& t2) { T tmp=t1; t1=t2; t2=tmp; }
class ModelPPM
{
private:
friend struct PPM_CONTEXT;
SEE2_CONTEXT SEE2Cont[25][16], DummySEE2Cont;
struct PPM_CONTEXT *MinContext, *MedContext, *MaxContext;
STATE* FoundState; // found next state transition
int NumMasked, InitEsc, OrderFall, MaxOrder, RunLength, InitRL;
byte CharMask[256], NS2Indx[256], NS2BSIndx[256], HB2Flag[256];
byte EscCount, PrevSuccess, HiBitsFlag;
ushort BinSumm[128][64]; // binary SEE-contexts
RangeCoder Coder;
SubAllocator SubAlloc;
void RestartModelRare();
void StartModelRare(int MaxOrder);
inline PPM_CONTEXT* CreateSuccessors(bool Skip,STATE* p1);
inline void UpdateModel();
inline void ClearMask();
public:
ModelPPM();
void CleanUp(); // reset PPM variables after data error
bool DecodeInit(Unpack *UnpackRead,int &EscChar);
int DecodeChar();
};
#endif

2390
libunrar/msc.dep Normal file

File diff suppressed because it is too large Load Diff

28
libunrar/options.cpp Normal file
View File

@ -0,0 +1,28 @@
#include "rar.hpp"
RAROptions::RAROptions()
{
Init();
}
RAROptions::~RAROptions()
{
memset(this,0,sizeof(RAROptions));
}
void RAROptions::Init()
{
memset(this,0,sizeof(RAROptions));
WinSize=0x400000;
Overwrite=OVERWRITE_DEFAULT;
Method=3;
MsgStream=MSG_STDOUT;
ConvertNames=NAMES_ORIGINALCASE;
ProcessEA=true;
xmtime=EXTTIME_HIGH3;
CurVolNum=0;
FileSizeLess=INT64NDF;
FileSizeMore=INT64NDF;
}

160
libunrar/options.hpp Normal file
View File

@ -0,0 +1,160 @@
#ifndef _RAR_OPTIONS_
#define _RAR_OPTIONS_
#define DEFAULT_RECOVERY -1
#define DEFAULT_RECVOLUMES -10
enum PATH_EXCL_MODE {
EXCL_NONE,EXCL_BASEPATH,EXCL_SKIPWHOLEPATH,EXCL_SAVEFULLPATH,
EXCL_SKIPABSPATH,EXCL_ABSPATH
};
enum {SOLID_NONE=0,SOLID_NORMAL=1,SOLID_COUNT=2,SOLID_FILEEXT=4,
SOLID_VOLUME_DEPENDENT=8,SOLID_VOLUME_INDEPENDENT=16};
enum {ARCTIME_NONE,ARCTIME_KEEP,ARCTIME_LATEST};
enum EXTTIME_MODE {
EXTTIME_NONE,EXTTIME_1S,EXTTIME_HIGH1,EXTTIME_HIGH2,EXTTIME_HIGH3
};
enum {NAMES_ORIGINALCASE,NAMES_UPPERCASE,NAMES_LOWERCASE};
enum MESSAGE_TYPE {MSG_STDOUT,MSG_STDERR,MSG_ERRONLY,MSG_NULL};
enum RECURSE_MODE
{
RECURSE_NONE=0, // no recurse switches
RECURSE_DISABLE, // switch -r-
RECURSE_ALWAYS, // switch -r
RECURSE_WILDCARDS, // switch -r0
};
enum OVERWRITE_MODE
{
OVERWRITE_DEFAULT=0, // ask for extraction, silently overwrite for archiving
OVERWRITE_ALL,
OVERWRITE_NONE,
OVERWRITE_AUTORENAME,
OVERWRITE_FORCE_ASK
};
enum RAR_CHARSET { RCH_DEFAULT=0,RCH_ANSI,RCH_OEM,RCH_UNICODE };
#define MAX_FILTERS 16
enum FilterState {FILTER_DEFAULT=0,FILTER_AUTO,FILTER_FORCE,FILTER_DISABLE};
struct FilterMode
{
FilterState State;
int Param1;
int Param2;
};
class RAROptions
{
public:
RAROptions();
~RAROptions();
void Init();
uint ExclFileAttr;
uint InclFileAttr;
bool InclAttrSet;
uint WinSize;
char TempPath[NM];
char SFXModule[NM];
char ExtrPath[NM];
wchar ExtrPathW[NM];
char CommentFile[NM];
RAR_CHARSET CommentCharset;
RAR_CHARSET FilelistCharset;
char ArcPath[NM];
wchar ArcPathW[NM];
char Password[MAXPASSWORD];
bool EncryptHeaders;
char LogName[NM];
MESSAGE_TYPE MsgStream;
bool Sound;
OVERWRITE_MODE Overwrite;
int Method;
int Recovery;
int RecVolNumber;
bool DisablePercentage;
bool DisableCopyright;
bool DisableDone;
int Solid;
int SolidCount;
bool ClearArc;
bool AddArcOnly;
bool AV;
bool DisableComment;
bool FreshFiles;
bool UpdateFiles;
PATH_EXCL_MODE ExclPath;
RECURSE_MODE Recurse;
int64 VolSize;
Array<int64> NextVolSizes;
uint CurVolNum;
bool AllYes;
bool DisableViewAV;
bool DisableSortSolid;
int ArcTime;
int ConvertNames;
bool ProcessOwners;
bool SaveLinks;
int Priority;
int SleepTime;
bool KeepBroken;
bool EraseDisk;
bool OpenShared;
bool DeleteFiles;
bool SyncFiles;
bool GenerateArcName;
char GenerateMask[80];
bool ProcessEA;
bool SaveStreams;
bool SetCompressedAttr;
bool IgnoreGeneralAttr;
RarTime FileTimeBefore;
RarTime FileTimeAfter;
int64 FileSizeLess;
int64 FileSizeMore;
bool OldNumbering;
bool Lock;
bool Test;
bool VolumePause;
FilterMode FilterModes[MAX_FILTERS];
char EmailTo[NM];
uint VersionControl;
bool NoEndBlock;
bool AppendArcNameToPath;
bool Shutdown;
EXTTIME_MODE xmtime;
EXTTIME_MODE xctime;
EXTTIME_MODE xatime;
EXTTIME_MODE xarctime;
char CompressStdin[NM];
#ifdef PACK_SMP
uint Threads;
#endif
#ifdef RARDLL
char DllDestName[NM];
wchar DllDestNameW[NM];
int DllOpMode;
int DllError;
LPARAM UserData;
UNRARCALLBACK Callback;
CHANGEVOLPROC ChangeVolProc;
PROCESSDATAPROC ProcessDataProc;
#endif
};
#endif

259
libunrar/os.hpp Normal file
View File

@ -0,0 +1,259 @@
#ifndef _RAR_OS_
#define _RAR_OS_
#define FALSE 0
#define TRUE 1
#ifdef __EMX__
#define INCL_BASE
#endif
#if defined(_WIN_32) || defined(_EMX)
#define ENABLE_BAD_ALLOC
#endif
#if defined(_WIN_32) || defined(_EMX)
#define LITTLE_ENDIAN
#define NM 1024
#ifdef _WIN_32
#define STRICT
#undef WINVER
#undef _WIN32_WINNT
#define WINVER 0x0400
#define _WIN32_WINNT 0x0300
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <prsht.h>
#ifndef _WIN_CE
#include <shellapi.h>
#include <shlobj.h>
#include <winioctl.h>
#endif // _WIN_CE
#endif // _WIN_32
#ifndef _WIN_CE
#include <sys/types.h>
#include <sys/stat.h>
#include <dos.h>
#endif // _WIN_CE
#if !defined(_EMX) && !defined(_MSC_VER) && !defined(_WIN_CE)
#include <dir.h>
#endif
#ifdef _MSC_VER
#if _MSC_VER<1500
#define for if (0) ; else for
#endif
#ifndef _WIN_CE
#include <direct.h>
#endif
#else
#include <dirent.h>
#endif // _MSC_VER
#ifndef _WIN_CE
#include <share.h>
#endif // _WIN_CE
#if defined(ENABLE_BAD_ALLOC) && !defined(_WIN_CE)
#include <new.h>
#endif
#ifdef _EMX
#include <unistd.h>
#include <pwd.h>
#include <grp.h>
#include <errno.h>
#ifdef _DJGPP
#include <utime.h>
#else
#include <os2.h>
#include <sys/utime.h>
#include <emx/syscalls.h>
#endif
#else
#if defined(_MSC_VER) || defined(__MINGW32__)
#include <exception>
#else
#include <except.h>
#endif
#endif
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <ctype.h>
#ifndef _WIN_CE
#include <fcntl.h>
#include <dos.h>
#include <io.h>
#include <time.h>
#include <signal.h>
#endif
/*
#ifdef _WIN_32
#pragma hdrstop
#endif // _WIN_32
*/
#define ENABLE_ACCESS
#define DefConfigName "rar.ini"
#define DefLogName "rar.log"
#define PATHDIVIDER "\\"
#define PATHDIVIDERW L"\\"
#define CPATHDIVIDER '\\'
#define MASKALL "*"
#define MASKALLW L"*"
#define READBINARY "rb"
#define READTEXT "rt"
#define UPDATEBINARY "r+b"
#define CREATEBINARY "w+b"
#define APPENDTEXT "at"
#if defined(_WIN_32)
#ifdef _MSC_VER
#define _stdfunction __cdecl
#else
#define _stdfunction _USERENTRY
#endif
#else
#define _stdfunction
#endif
#endif
#ifdef _UNIX
#define NM 1024
#ifdef _BEOS
#include <be/kernel/fs_info.h>
#include <be/kernel/fs_attr.h>
#endif
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/file.h>
#if defined(__QNXNTO__)
#include <sys/param.h>
#endif
#if defined(__FreeBSD__) || defined (__NetBSD__) || defined (__OpenBSD__) || defined(__APPLE__)
#include <sys/param.h>
#include <sys/mount.h>
#else
#endif
#include <pwd.h>
#include <grp.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <ctype.h>
#include <fcntl.h>
#include <errno.h>
#include <dirent.h>
#include <time.h>
#include <signal.h>
#include <utime.h>
#include <locale.h>
#ifdef S_IFLNK
#define SAVE_LINKS
#endif
#define ENABLE_ACCESS
#define DefConfigName ".rarrc"
#define DefLogName ".rarlog"
#define PATHDIVIDER "/"
#define PATHDIVIDERW L"/"
#define CPATHDIVIDER '/'
#define MASKALL "*"
#define MASKALLW L"*"
#define READBINARY "r"
#define READTEXT "r"
#define UPDATEBINARY "r+"
#define CREATEBINARY "w+"
#define APPENDTEXT "a"
#define _stdfunction
#ifdef _APPLE
#if defined(__BIG_ENDIAN__) && !defined(BIG_ENDIAN)
#define BIG_ENDIAN
#undef LITTLE_ENDIAN
#endif
#if defined(__i386__) && !defined(LITTLE_ENDIAN)
#define LITTLE_ENDIAN
#undef BIG_ENDIAN
#endif
#endif
#if defined(__sparc) || defined(sparc) || defined(__hpux)
#ifndef BIG_ENDIAN
#define BIG_ENDIAN
#endif
#endif
#endif
typedef const char* MSGID;
#define safebuf static
#if !defined(LITTLE_ENDIAN) && !defined(BIG_ENDIAN)
#if defined(__i386) || defined(i386) || defined(__i386__)
#define LITTLE_ENDIAN
#elif defined(BYTE_ORDER) && BYTE_ORDER == LITTLE_ENDIAN
#define LITTLE_ENDIAN
#elif defined(BYTE_ORDER) && BYTE_ORDER == BIG_ENDIAN
#define BIG_ENDIAN
#else
#error "Neither LITTLE_ENDIAN nor BIG_ENDIAN are defined. Define one of them."
#endif
#endif
#if defined(LITTLE_ENDIAN) && defined(BIG_ENDIAN)
#if defined(BYTE_ORDER) && BYTE_ORDER == BIG_ENDIAN
#undef LITTLE_ENDIAN
#elif defined(BYTE_ORDER) && BYTE_ORDER == LITTLE_ENDIAN
#undef BIG_ENDIAN
#else
#error "Both LITTLE_ENDIAN and BIG_ENDIAN are defined. Undef one of them."
#endif
#endif
#if !defined(BIG_ENDIAN) && !defined(_WIN_CE) && defined(_WIN_32)
/* allow not aligned integer access, increases speed in some operations */
#define ALLOW_NOT_ALIGNED_INT
#endif
#if defined(__sparc) || defined(sparc) || defined(__sparcv9)
/* prohibit not aligned access to data structures in text comression
algorithm, increases memory requirements */
#define STRICT_ALIGNMENT_REQUIRED
#endif
#endif // _RAR_OS_

94
libunrar/os2ea.cpp Normal file
View File

@ -0,0 +1,94 @@
#include <os2.h>
void ExtractOS2EA(Archive &Arc,char *FileName)
{
if (_osmode != OS2_MODE)
{
mprintf(St(MSkipEA));
return;
}
if (Arc.HeaderCRC!=Arc.EAHead.HeadCRC)
{
Log(Arc.FileName,St(MEABroken),FileName);
ErrHandler.SetErrorCode(CRC_ERROR);
return;
}
if (Arc.EAHead.Method<0x31 || Arc.EAHead.Method>0x35 || Arc.EAHead.UnpVer>PACK_VER)
{
Log(Arc.FileName,St(MEAUnknHeader),FileName);
ErrHandler.SetErrorCode(WARNING);
return;
}
struct StructEAOP2
{
char *GEAPtr;
char *FEAPtr;
unsigned long Error;
} EAOP2;
ComprDataIO DataIO;
Unpack Unpack(&DataIO);
Unpack.Init();
Array<unsigned char> UnpData(Arc.EAHead.UnpSize);
DataIO.SetUnpackToMemory(&UnpData[0],Arc.EAHead.UnpSize);
DataIO.SetPackedSizeToRead(Arc.EAHead.DataSize);
DataIO.EnableShowProgress(false);
DataIO.SetFiles(&Arc,NULL);
Unpack.SetDestSize(Arc.EAHead.UnpSize);
Unpack.DoUnpack(Arc.EAHead.UnpVer,false);
if (Arc.EAHead.EACRC!=~DataIO.UnpFileCRC)
{
Log(Arc.FileName,St(MEABroken),FileName);
ErrHandler.SetErrorCode(CRC_ERROR);
return;
}
EAOP2.FEAPtr=(char *)&UnpData[0];
EAOP2.GEAPtr=NULL;
if (DosSetPathInfo((unsigned char *)FileName,2,&EAOP2,sizeof(EAOP2),0x10)!=0)
{
Log(Arc.FileName,St(MCannotSetEA),FileName);
ErrHandler.SetErrorCode(WARNING);
}
File::SetCloseFileTimeByName(FileName,&Arc.NewLhd.mtime,&Arc.NewLhd.atime);
mprintf(St(MShowEA));
}
void ExtractOS2EANew(Archive &Arc,char *FileName)
{
if (_osmode != OS2_MODE)
{
mprintf(St(MSkipEA));
return;
}
Array<byte> SubData;
if (!Arc.ReadSubData(&SubData,NULL))
return;
struct StructEAOP2
{
char *GEAPtr;
char *FEAPtr;
unsigned long Error;
} EAOP2;
EAOP2.FEAPtr=(char *)&SubData[0];
EAOP2.GEAPtr=NULL;
if (DosSetPathInfo((unsigned char *)FileName,2,&EAOP2,sizeof(EAOP2),0x10)!=0)
{
Log(Arc.FileName,St(MCannotSetEA),FileName);
ErrHandler.SetErrorCode(WARNING);
}
File::SetCloseFileTimeByName(FileName,&Arc.NewLhd.mtime,&Arc.NewLhd.atime);
mprintf(St(MShowEA));
}

View File

@ -0,0 +1,44 @@
--- makefile.unix.orig 2008-10-09 15:43:06.000000000 +0200
+++ makefile.unix 2008-11-06 01:43:52.000000000 +0100
@@ -7,10 +7,11 @@
# Linux using GCC
#CXX=g++
-#CXXFLAGS=-O2
-DEFINES=-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
+CXXFLAGS=$(CFLAGS) -fPIC -DPIC
+DEFINES=-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -DGUI -DSILENT
STRIP=strip
DESTDIR=/usr
+RANLIB=ranlib
# Linux using LCC
#CXX=lcc
@@ -100,7 +101,7 @@
WHAT=UNRAR
UNRAR_OBJ=filestr.o recvol.o rs.o scantree.o
-LIB_OBJ=filestr.o scantree.o dll.o
+LIB_OBJ=dll.o
OBJECTS=rar.o strlist.o strfn.o pathfn.o int64.o savepos.o global.o file.o filefn.o filcreat.o \
archive.o arcread.o unicode.o system.o isnt.o crypt.o crc.o rawread.o encname.o \
@@ -131,9 +132,15 @@
$(STRIP) default.sfx
lib: WHAT=RARDLL
-lib: $(OBJECTS) $(LIB_OBJ)
- @rm -f libunrar.so
- $(LINK) -shared -o libunrar.so $(LDFLAGS) $(OBJECTS) $(LIB_OBJ)
+lib: $(OBJECTS) $(LIB_OBJ) $(UNRAR_OBJ)
+ @rm -f libunrar.so.3
+ $(LINK) -shared -o libunrar.so.3 $(LDFLAGS) $(OBJECTS) $(LIB_OBJ) $(UNRAR_OBJ)
+
+liba: WHAT=RARDLL
+liba: $(OBJECTS) $(LIB_OBJ) $(UNRAR_OBJ)
+ @rm -f libunrar.a
+ $(AR) rc libunrar.a $(OBJECTS) $(LIB_OBJ) $(UNRAR_OBJ)
+ $(RANLIB) libunrar.a
install-unrar:
install unrar $(DESTDIR)/bin

792
libunrar/pathfn.cpp Normal file
View File

@ -0,0 +1,792 @@
#include "rar.hpp"
char* PointToName(const char *Path)
{
const char *Found=NULL;
for (const char *s=Path;*s!=0;s=charnext(s))
if (IsPathDiv(*s))
Found=(char*)(s+1);
if (Found!=NULL)
return((char*)Found);
return (char*)((*Path && IsDriveDiv(Path[1]) && charnext(Path)==Path+1) ? Path+2:Path);
}
wchar* PointToName(const wchar *Path)
{
for (int I=(int)strlenw(Path)-1;I>=0;I--)
if (IsPathDiv(Path[I]))
return (wchar*)&Path[I+1];
return (wchar*)((*Path && IsDriveDiv(Path[1])) ? Path+2:Path);
}
char* PointToLastChar(const char *Path)
{
for (const char *s=Path,*p=Path;;p=s,s=charnext(s))
if (*s==0)
return((char *)p);
}
char* ConvertPath(const char *SrcPath,char *DestPath)
{
const char *DestPtr=SrcPath;
// Prevent \..\ in any part of path string.
for (const char *s=DestPtr;*s!=0;s++)
if (IsPathDiv(s[0]) && s[1]=='.' && s[2]=='.' && IsPathDiv(s[3]))
DestPtr=s+4;
// Remove any sequence of . and \ in the beginning of path string.
while (*DestPtr)
{
const char *s=DestPtr;
if (s[0] && IsDriveDiv(s[1]))
s+=2;
else
if (s[0]=='\\' && s[1]=='\\')
{
const char *Slash=strchr(s+2,'\\');
if (Slash!=NULL && (Slash=strchr(Slash+1,'\\'))!=NULL)
s=Slash+1;
}
for (const char *t=s;*t!=0;t++)
if (IsPathDiv(*t))
s=t+1;
else
if (*t!='.')
break;
if (s==DestPtr)
break;
DestPtr=s;
}
// Code above does not remove last "..", doing here.
if (DestPtr[0]=='.' && DestPtr[1]=='.' && DestPtr[2]==0)
DestPtr+=2;
if (DestPath!=NULL)
{
// SrcPath and DestPath can point to same memory area,
// so we use the temporary buffer for copying.
char TmpStr[NM];
strncpyz(TmpStr,DestPtr,ASIZE(TmpStr));
strcpy(DestPath,TmpStr);
}
return((char *)DestPtr);
}
wchar* ConvertPath(const wchar *SrcPath,wchar *DestPath)
{
const wchar *DestPtr=SrcPath;
for (const wchar *s=DestPtr;*s!=0;s++)
if (IsPathDiv(s[0]) && s[1]=='.' && s[2]=='.' && IsPathDiv(s[3]))
DestPtr=s+4;
while (*DestPtr)
{
const wchar *s=DestPtr;
if (s[0] && IsDriveDiv(s[1]))
s+=2;
if (s[0]=='\\' && s[1]=='\\')
{
const wchar *Slash=strchrw(s+2,'\\');
if (Slash!=NULL && (Slash=strchrw(Slash+1,'\\'))!=NULL)
s=Slash+1;
}
for (const wchar *t=s;*t!=0;t++)
if (IsPathDiv(*t))
s=t+1;
else
if (*t!='.')
break;
if (s==DestPtr)
break;
DestPtr=s;
}
if (DestPath!=NULL)
{
wchar TmpStr[NM];
strncpyw(TmpStr,DestPtr,sizeof(TmpStr)/sizeof(TmpStr[0])-1);
strcpyw(DestPath,TmpStr);
}
return((wchar *)DestPtr);
}
void SetExt(char *Name,const char *NewExt)
{
char *Dot=GetExt(Name);
if (NewExt==NULL)
{
if (Dot!=NULL)
*Dot=0;
}
else
if (Dot==NULL)
{
strcat(Name,".");
strcat(Name,NewExt);
}
else
strcpy(Dot+1,NewExt);
}
#ifndef SFX_MODULE
void SetExt(wchar *Name,const wchar *NewExt)
{
if (Name==NULL || *Name==0)
return;
wchar *Dot=GetExt(Name);
if (NewExt==NULL)
{
if (Dot!=NULL)
*Dot=0;
}
else
if (Dot==NULL)
{
strcatw(Name,L".");
strcatw(Name,NewExt);
}
else
strcpyw(Dot+1,NewExt);
}
#endif
#ifndef SFX_MODULE
void SetSFXExt(char *SFXName)
{
#ifdef _UNIX
SetExt(SFXName,"sfx");
#endif
#if defined(_WIN_32) || defined(_EMX)
SetExt(SFXName,"exe");
#endif
}
#endif
#ifndef SFX_MODULE
void SetSFXExt(wchar *SFXName)
{
if (SFXName==NULL || *SFXName==0)
return;
#ifdef _UNIX
SetExt(SFXName,L"sfx");
#endif
#if defined(_WIN_32) || defined(_EMX)
SetExt(SFXName,L"exe");
#endif
}
#endif
char *GetExt(const char *Name)
{
return(strrchrd(PointToName(Name),'.'));
}
wchar *GetExt(const wchar *Name)
{
return(Name==NULL ? (wchar *)L"":strrchrw(PointToName(Name),'.'));
}
bool CmpExt(const char *Name,const char *Ext)
{
char *NameExt=GetExt(Name);
return(NameExt!=NULL && stricomp(NameExt+1,Ext)==0);
}
bool IsWildcard(const char *Str,const wchar *StrW)
{
if (StrW!=NULL && *StrW!=0)
return(strpbrkw(StrW,L"*?")!=NULL);
return(Str==NULL ? false:strpbrk(Str,"*?")!=NULL);
}
bool IsPathDiv(int Ch)
{
#if defined(_WIN_32) || defined(_EMX)
return(Ch=='\\' || Ch=='/');
#else
return(Ch==CPATHDIVIDER);
#endif
}
bool IsDriveDiv(int Ch)
{
#ifdef _UNIX
return(false);
#else
return(Ch==':');
#endif
}
int GetPathDisk(const char *Path)
{
if (IsDiskLetter(Path))
return(etoupper(*Path)-'A');
else
return(-1);
}
void AddEndSlash(char *Path)
{
char *LastChar=PointToLastChar(Path);
if (*LastChar!=0 && *LastChar!=CPATHDIVIDER)
strcat(LastChar,PATHDIVIDER);
}
void AddEndSlash(wchar *Path)
{
size_t Length=strlenw(Path);
if (Length>0 && Path[Length-1]!=CPATHDIVIDER)
strcatw(Path,PATHDIVIDERW);
}
// Returns file path including the trailing path separator symbol.
void GetFilePath(const char *FullName,char *Path,int MaxLength)
{
size_t PathLength=Min(MaxLength-1,PointToName(FullName)-FullName);
strncpy(Path,FullName,PathLength);
Path[PathLength]=0;
}
// Returns file path including the trailing path separator symbol.
void GetFilePath(const wchar *FullName,wchar *Path,int MaxLength)
{
size_t PathLength=Min(MaxLength-1,PointToName(FullName)-FullName);
strncpyw(Path,FullName,PathLength);
Path[PathLength]=0;
}
// Removes name and returns file path without the trailing
// path separator symbol.
void RemoveNameFromPath(char *Path)
{
char *Name=PointToName(Path);
if (Name>=Path+2 && (!IsDriveDiv(Path[1]) || Name>=Path+4))
Name--;
*Name=0;
}
#ifndef SFX_MODULE
// Removes name and returns file path without the trailing
// path separator symbol.
void RemoveNameFromPath(wchar *Path)
{
wchar *Name=PointToName(Path);
if (Name>=Path+2 && (!IsDriveDiv(Path[1]) || Name>=Path+4))
Name--;
*Name=0;
}
#endif
#if defined(_WIN_32) && !defined(_WIN_CE) && !defined(SFX_MODULE)
void GetAppDataPath(char *Path)
{
LPMALLOC g_pMalloc;
SHGetMalloc(&g_pMalloc);
LPITEMIDLIST ppidl;
*Path=0;
bool Success=false;
if (SHGetSpecialFolderLocation(NULL,CSIDL_APPDATA,&ppidl)==NOERROR &&
SHGetPathFromIDList(ppidl,Path) && *Path!=0)
{
AddEndSlash(Path);
strcat(Path,"WinRAR");
Success=FileExist(Path) || MakeDir(Path,NULL,false,0)==MKDIR_SUCCESS;
}
if (!Success)
{
GetModuleFileName(NULL,Path,NM);
RemoveNameFromPath(Path);
}
g_pMalloc->Free(ppidl);
}
#endif
#if defined(_WIN_32) && !defined(_WIN_CE) && !defined(SFX_MODULE)
void GetRarDataPath(char *Path)
{
*Path=0;
HKEY hKey;
if (RegOpenKeyEx(HKEY_CURRENT_USER,"Software\\WinRAR\\Paths",0,
KEY_QUERY_VALUE,&hKey)==ERROR_SUCCESS)
{
DWORD DataSize=NM,Type;
RegQueryValueEx(hKey,"AppData",0,&Type,(BYTE *)Path,&DataSize);
RegCloseKey(hKey);
}
if (*Path==0 || !FileExist(Path))
GetAppDataPath(Path);
}
#endif
#ifndef SFX_MODULE
bool EnumConfigPaths(char *Path,int Number)
{
#ifdef _EMX
static char RARFileName[NM];
if (Number==-1)
strcpy(RARFileName,Path);
if (Number!=0)
return(false);
#ifndef _DJGPP
if (_osmode==OS2_MODE)
{
PTIB ptib;
PPIB ppib;
DosGetInfoBlocks(&ptib, &ppib);
DosQueryModuleName(ppib->pib_hmte,NM,Path);
}
else
#endif
strcpy(Path,RARFileName);
RemoveNameFromPath(Path);
return(true);
#elif defined(_UNIX)
static const char *AltPath[]={
"/etc","/etc/rar","/usr/lib","/usr/local/lib","/usr/local/etc"
};
if (Number==0)
{
char *EnvStr=getenv("HOME");
strncpy(Path, (EnvStr==NULL) ? AltPath[0] : EnvStr, NM-1);
Path[NM-1]=0;
return(true);
}
Number--;
if (Number<0 || Number>=sizeof(AltPath)/sizeof(AltPath[0]))
return(false);
strcpy(Path,AltPath[Number]);
return(true);
#elif defined(_WIN_32)
if (Number<0 || Number>1)
return(false);
if (Number==0)
GetRarDataPath(Path);
else
{
GetModuleFileName(NULL,Path,NM);
RemoveNameFromPath(Path);
}
return(true);
#else
return(false);
#endif
}
#endif
#ifndef SFX_MODULE
void GetConfigName(const char *Name,char *FullName,bool CheckExist)
{
*FullName=0;
for (int I=0;EnumConfigPaths(FullName,I);I++)
{
AddEndSlash(FullName);
strcat(FullName,Name);
if (!CheckExist || WildFileExist(FullName))
break;
}
}
#endif
// Returns a pointer to rightmost digit of volume number.
char* GetVolNumPart(char *ArcName)
{
// Pointing to last name character.
char *ChPtr=ArcName+strlen(ArcName)-1;
// Skipping the archive extension.
while (!IsDigit(*ChPtr) && ChPtr>ArcName)
ChPtr--;
// Skipping the numeric part of name.
char *NumPtr=ChPtr;
while (IsDigit(*NumPtr) && NumPtr>ArcName)
NumPtr--;
// Searching for first numeric part in names like name.part##of##.rar.
// Stop search on the first dot.
while (NumPtr>ArcName && *NumPtr!='.')
{
if (IsDigit(*NumPtr))
{
// Validate the first numeric part only if it has a dot somwhere
// before it.
char *Dot=strchrd(PointToName(ArcName),'.');
if (Dot!=NULL && Dot<NumPtr)
ChPtr=NumPtr;
break;
}
NumPtr--;
}
return(ChPtr);
}
void NextVolumeName(char *ArcName,wchar *ArcNameW,uint MaxLength,bool OldNumbering)
{
char *ChPtr;
if ((ChPtr=GetExt(ArcName))==NULL)
{
strcat(ArcName,".rar");
ChPtr=GetExt(ArcName);
}
else
if (ChPtr[1]==0 || stricomp(ChPtr+1,"exe")==0 || stricomp(ChPtr+1,"sfx")==0)
strcpy(ChPtr+1,"rar");
if (!OldNumbering)
{
ChPtr=GetVolNumPart(ArcName);
while ((++(*ChPtr))=='9'+1)
{
*ChPtr='0';
ChPtr--;
if (ChPtr<ArcName || !IsDigit(*ChPtr))
{
for (char *EndPtr=ArcName+strlen(ArcName);EndPtr!=ChPtr;EndPtr--)
*(EndPtr+1)=*EndPtr;
*(ChPtr+1)='1';
break;
}
}
}
else
if (!IsDigit(*(ChPtr+2)) || !IsDigit(*(ChPtr+3)))
strcpy(ChPtr+2,"00");
else
{
ChPtr+=3;
while ((++(*ChPtr))=='9'+1)
if (*(ChPtr-1)=='.')
{
*ChPtr='A';
break;
}
else
{
*ChPtr='0';
ChPtr--;
}
}
if (ArcNameW!=NULL && *ArcNameW!=0)
{
// Copy incremented trailing low ASCII volume name part to Unicode name.
// It is simpler than implementing Unicode version of entire function.
char *NumPtr=GetVolNumPart(ArcName);
// moving to first digit in volume number
while (NumPtr>ArcName && IsDigit(*NumPtr) && IsDigit(*(NumPtr-1)))
NumPtr--;
// also copy the first character before volume number,
// because it can be changed when going from .r99 to .s00
if (NumPtr>ArcName)
NumPtr--;
int CharsToCopy=(int)(strlen(ArcName)-(NumPtr-ArcName));
int DestPos=(int)(strlenw(ArcNameW)-CharsToCopy);
if (DestPos>=0)
{
CharToWide(NumPtr,ArcNameW+DestPos,MaxLength-DestPos-1);
ArcNameW[MaxLength-1]=0;
}
}
}
bool IsNameUsable(const char *Name)
{
#ifndef _UNIX
if (Name[0] && Name[1] && strchr(Name+2,':')!=NULL)
return(false);
for (const char *s=Name;*s!=0;s=charnext(s))
{
if ((byte)*s<32)
return(false);
if (*s==' ' && IsPathDiv(s[1]))
return(false);
}
#endif
return(*Name!=0 && strpbrk(Name,"?*<>|\"")==NULL);
}
void MakeNameUsable(char *Name,bool Extended)
{
for (char *s=Name;*s!=0;s=charnext(s))
{
if (strchr(Extended ? "?*<>|\"":"?*",*s)!=NULL || Extended && (byte)*s<32)
*s='_';
#ifdef _EMX
if (*s=='=')
*s='_';
#endif
#ifndef _UNIX
if (s-Name>1 && *s==':')
*s='_';
if (*s==' ' && IsPathDiv(s[1]))
*s='_';
#endif
}
}
char* UnixSlashToDos(char *SrcName,char *DestName,uint MaxLength)
{
if (DestName!=NULL && DestName!=SrcName)
if (strlen(SrcName)>=MaxLength)
{
*DestName=0;
return(DestName);
}
else
strcpy(DestName,SrcName);
for (char *s=SrcName;*s!=0;s=charnext(s))
{
if (*s=='/')
if (DestName==NULL)
*s='\\';
else
DestName[s-SrcName]='\\';
}
return(DestName==NULL ? SrcName:DestName);
}
char* DosSlashToUnix(char *SrcName,char *DestName,uint MaxLength)
{
if (DestName!=NULL && DestName!=SrcName)
if (strlen(SrcName)>=MaxLength)
{
*DestName=0;
return(DestName);
}
else
strcpy(DestName,SrcName);
for (char *s=SrcName;*s!=0;s=charnext(s))
{
if (*s=='\\')
if (DestName==NULL)
*s='/';
else
DestName[s-SrcName]='/';
}
return(DestName==NULL ? SrcName:DestName);
}
wchar* UnixSlashToDos(wchar *SrcName,wchar *DestName,uint MaxLength)
{
if (DestName!=NULL && DestName!=SrcName)
if (strlenw(SrcName)>=MaxLength)
{
*DestName=0;
return(DestName);
}
else
strcpyw(DestName,SrcName);
for (wchar *s=SrcName;*s!=0;s++)
{
if (*s=='/')
if (DestName==NULL)
*s='\\';
else
DestName[s-SrcName]='\\';
}
return(DestName==NULL ? SrcName:DestName);
}
bool IsFullPath(const char *Path)
{
char PathOnly[NM];
GetFilePath(Path,PathOnly,ASIZE(PathOnly));
if (IsWildcard(PathOnly,NULL))
return(true);
#if defined(_WIN_32) || defined(_EMX)
return(Path[0]=='\\' && Path[1]=='\\' ||
IsDiskLetter(Path) && IsPathDiv(Path[2]));
#else
return(IsPathDiv(Path[0]));
#endif
}
bool IsFullPath(const wchar *Path)
{
wchar PathOnly[NM];
GetFilePath(Path,PathOnly,ASIZE(PathOnly));
if (IsWildcard(NULL,PathOnly))
return(true);
#if defined(_WIN_32) || defined(_EMX)
return(Path[0]=='\\' && Path[1]=='\\' ||
IsDiskLetter(Path) && IsPathDiv(Path[2]));
#else
return(IsPathDiv(Path[0]));
#endif
}
bool IsDiskLetter(const char *Path)
{
char Letter=etoupper(Path[0]);
return(Letter>='A' && Letter<='Z' && IsDriveDiv(Path[1]));
}
bool IsDiskLetter(const wchar *Path)
{
wchar Letter=etoupperw(Path[0]);
return(Letter>='A' && Letter<='Z' && IsDriveDiv(Path[1]));
}
void GetPathRoot(const char *Path,char *Root)
{
*Root=0;
if (IsDiskLetter(Path))
sprintf(Root,"%c:\\",*Path);
else
if (Path[0]=='\\' && Path[1]=='\\')
{
const char *Slash=strchr(Path+2,'\\');
if (Slash!=NULL)
{
size_t Length;
if ((Slash=strchr(Slash+1,'\\'))!=NULL)
Length=Slash-Path+1;
else
Length=strlen(Path);
strncpy(Root,Path,Length);
Root[Length]=0;
}
}
}
int ParseVersionFileName(char *Name,wchar *NameW,bool Truncate)
{
int Version=0;
char *VerText=strrchrd(Name,';');
if (VerText!=NULL)
{
Version=atoi(VerText+1);
if (Truncate)
*VerText=0;
}
if (NameW!=NULL)
{
wchar *VerTextW=strrchrw(NameW,';');
if (VerTextW!=NULL)
{
if (Version==0)
Version=atoiw(VerTextW+1);
if (Truncate)
*VerTextW=0;
}
}
return(Version);
}
#if !defined(SFX_MODULE) && !defined(SETUP)
char* VolNameToFirstName(const char *VolName,char *FirstName,bool NewNumbering)
{
if (FirstName!=VolName)
strcpy(FirstName,VolName);
char *VolNumStart=FirstName;
if (NewNumbering)
{
int N='1';
for (char *ChPtr=GetVolNumPart(FirstName);ChPtr>FirstName;ChPtr--)
if (IsDigit(*ChPtr))
{
*ChPtr=N;
N='0';
}
else
if (N=='0')
{
VolNumStart=ChPtr+1;
break;
}
}
else
{
SetExt(FirstName,"rar");
VolNumStart=GetExt(FirstName);
}
if (!FileExist(FirstName))
{
char Mask[NM];
strcpy(Mask,FirstName);
SetExt(Mask,"*");
FindFile Find;
Find.SetMask(Mask);
struct FindData FD;
while (Find.Next(&FD))
{
Archive Arc;
if (Arc.Open(FD.Name,FD.NameW) && Arc.IsArchive(true) && !Arc.NotFirstVolume)
{
strcpy(FirstName,FD.Name);
break;
}
}
}
return(VolNumStart);
}
#endif
wchar* GetWideName(const char *Name,const wchar *NameW,wchar *DestW)
{
if (NameW!=NULL && *NameW!=0)
{
if (DestW!=NameW)
strcpyw(DestW,NameW);
}
else
CharToWide(Name,DestW);
return(DestW);
}

49
libunrar/pathfn.hpp Normal file
View File

@ -0,0 +1,49 @@
#ifndef _RAR_PATHFN_
#define _RAR_PATHFN_
char* PointToName(const char *Path);
wchar* PointToName(const wchar *Path);
char* PointToLastChar(const char *Path);
char* ConvertPath(const char *SrcPath,char *DestPath);
wchar* ConvertPath(const wchar *SrcPath,wchar *DestPath);
void SetExt(char *Name,const char *NewExt);
void SetExt(wchar *Name,const wchar *NewExt);
void SetSFXExt(char *SFXName);
void SetSFXExt(wchar *SFXName);
char *GetExt(const char *Name);
wchar *GetExt(const wchar *Name);
bool CmpExt(const char *Name,const char *Ext);
bool IsWildcard(const char *Str,const wchar *StrW=NULL);
bool IsPathDiv(int Ch);
bool IsDriveDiv(int Ch);
int GetPathDisk(const char *Path);
void AddEndSlash(char *Path);
void AddEndSlash(wchar *Path);
void GetFilePath(const char *FullName,char *Path,int MaxLength);
void GetFilePath(const wchar *FullName,wchar *Path,int MaxLength);
void RemoveNameFromPath(char *Path);
void RemoveNameFromPath(wchar *Path);
void GetAppDataPath(char *Path);
void GetRarDataPath(char *Path);
bool EnumConfigPaths(char *Path,int Number);
void GetConfigName(const char *Name,char *FullName,bool CheckExist);
char* GetVolNumPart(char *ArcName);
void NextVolumeName(char *ArcName,wchar *ArcNameW,uint MaxLength,bool OldNumbering);
bool IsNameUsable(const char *Name);
void MakeNameUsable(char *Name,bool Extended);
char* UnixSlashToDos(char *SrcName,char *DestName=NULL,uint MaxLength=NM);
char* DosSlashToUnix(char *SrcName,char *DestName=NULL,uint MaxLength=NM);
wchar* UnixSlashToDos(wchar *SrcName,wchar *DestName=NULL,uint MaxLength=NM);
bool IsFullPath(const char *Path);
bool IsFullPath(const wchar *Path);
bool IsDiskLetter(const char *Path);
bool IsDiskLetter(const wchar *Path);
void GetPathRoot(const char *Path,char *Root);
int ParseVersionFileName(char *Name,wchar *NameW,bool Truncate);
char* VolNameToFirstName(const char *VolName,char *FirstName,bool NewNumbering);
wchar* GetWideName(const char *Name,const wchar *NameW,wchar *DestW);
inline char* GetOutputName(const char *Name) {return((char *)Name);};
#endif

136
libunrar/rar.cpp Normal file
View File

@ -0,0 +1,136 @@
#include "rar.hpp"
#if !defined(GUI) && !defined(RARDLL)
int main(int argc, char *argv[])
{
#ifdef _UNIX
setlocale(LC_ALL,"");
#endif
#if defined(_EMX) && !defined(_DJGPP)
uni_init(0);
#endif
#if !defined(_SFX_RTL_) && !defined(_WIN_32)
setbuf(stdout,NULL);
#endif
#if !defined(SFX_MODULE) && defined(_EMX)
EnumConfigPaths(argv[0],-1);
#endif
ErrHandler.SetSignalHandlers(true);
RARInitData();
#ifdef SFX_MODULE
char ModuleName[NM];
#ifdef _WIN_32
GetModuleFileName(NULL,ModuleName,sizeof(ModuleName));
#else
strcpy(ModuleName,argv[0]);
#endif
#endif
#ifdef _WIN_32
SetErrorMode(SEM_NOALIGNMENTFAULTEXCEPT|SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX);
#endif
#if defined(_WIN_32) && !defined(SFX_MODULE) && !defined(SHELL_EXT)
bool ShutdownOnClose;
#endif
#ifdef ALLOW_EXCEPTIONS
try
#endif
{
CommandData Cmd;
#ifdef SFX_MODULE
strcpy(Cmd.Command,"X");
char *Switch=NULL;
#ifdef _SFX_RTL_
char *CmdLine=GetCommandLine();
if (CmdLine!=NULL && *CmdLine=='\"')
CmdLine=strchr(CmdLine+1,'\"');
if (CmdLine!=NULL && (CmdLine=strpbrk(CmdLine," /"))!=NULL)
{
while (IsSpace(*CmdLine))
CmdLine++;
Switch=CmdLine;
}
#else
Switch=argc>1 ? argv[1]:NULL;
#endif
if (Switch!=NULL && Cmd.IsSwitch(Switch[0]))
{
int UpperCmd=etoupper(Switch[1]);
switch(UpperCmd)
{
case 'T':
case 'V':
Cmd.Command[0]=UpperCmd;
break;
case '?':
Cmd.OutHelp();
break;
}
}
Cmd.AddArcName(ModuleName,NULL);
#else
if (Cmd.IsConfigEnabled(argc,argv))
{
Cmd.ReadConfig(argc,argv);
Cmd.ParseEnvVar();
}
for (int I=1;I<argc;I++)
Cmd.ParseArg(argv[I],NULL);
#endif
Cmd.ParseDone();
#if defined(_WIN_32) && !defined(SFX_MODULE) && !defined(SHELL_EXT)
ShutdownOnClose=Cmd.Shutdown;
#endif
InitConsoleOptions(Cmd.MsgStream,Cmd.Sound);
InitLogOptions(Cmd.LogName);
ErrHandler.SetSilent(Cmd.AllYes || Cmd.MsgStream==MSG_NULL);
ErrHandler.SetShutdown(Cmd.Shutdown);
Cmd.OutTitle();
Cmd.ProcessCommand();
}
#ifdef ALLOW_EXCEPTIONS
catch (int ErrCode)
{
ErrHandler.SetErrorCode(ErrCode);
}
#ifdef ENABLE_BAD_ALLOC
catch (bad_alloc)
{
ErrHandler.SetErrorCode(MEMORY_ERROR);
}
#endif
catch (...)
{
ErrHandler.SetErrorCode(FATAL_ERROR);
}
#endif
File::RemoveCreated();
#if defined(SFX_MODULE) && defined(_DJGPP)
_chmod(ModuleName,1,0x20);
#endif
#if defined(_EMX) && !defined(_DJGPP)
uni_done();
#endif
#if defined(_WIN_32) && !defined(SFX_MODULE) && !defined(SHELL_EXT)
if (ShutdownOnClose)
Shutdown();
#endif
return(ErrHandler.GetErrorCode());
}
#endif

77
libunrar/rar.hpp Normal file
View File

@ -0,0 +1,77 @@
#ifndef _RAR_RARCOMMON_
#define _RAR_RARCOMMON_
#include "raros.hpp"
#include "os.hpp"
#ifdef RARDLL
#include "dll.hpp"
#endif
#ifndef _WIN_CE
#include "version.hpp"
#endif
#include "rartypes.hpp"
#include "rardefs.hpp"
#include "rarlang.hpp"
#include "unicode.hpp"
#include "errhnd.hpp"
#include "array.hpp"
#include "timefn.hpp"
#include "options.hpp"
#include "headers.hpp"
#include "pathfn.hpp"
#include "strfn.hpp"
#include "strlist.hpp"
#include "file.hpp"
#include "sha1.hpp"
#include "crc.hpp"
#include "rijndael.hpp"
#include "crypt.hpp"
#include "filefn.hpp"
#include "filestr.hpp"
#include "find.hpp"
#include "scantree.hpp"
#include "savepos.hpp"
#include "getbits.hpp"
#include "rdwrfn.hpp"
#include "archive.hpp"
#include "match.hpp"
#include "cmddata.hpp"
#include "filcreat.hpp"
#include "consio.hpp"
#include "system.hpp"
#include "isnt.hpp"
#include "log.hpp"
#include "rawread.hpp"
#include "encname.hpp"
#include "resource.hpp"
#include "compress.hpp"
#include "rarvm.hpp"
#include "model.hpp"
#include "unpack.hpp"
#include "extinfo.hpp"
#include "extract.hpp"
#include "list.hpp"
#include "rs.hpp"
#include "recvol.hpp"
#include "volume.hpp"
#include "smallfn.hpp"
#include "ulinks.hpp"
#include "global.hpp"
#endif

24
libunrar/rardefs.hpp Normal file
View File

@ -0,0 +1,24 @@
#ifndef _RAR_DEFS_
#define _RAR_DEFS_
#define Min(x,y) (((x)<(y)) ? (x):(y))
#define Max(x,y) (((x)>(y)) ? (x):(y))
#define ASIZE(x) (sizeof(x)/sizeof(x[0]))
#define MAXPASSWORD 128
#define MAXSFXSIZE 0x80000
#define DefSFXName "default.sfx"
#define DefSortListName "rarfiles.lst"
#ifndef FA_RDONLY
#define FA_RDONLY 0x01
#define FA_HIDDEN 0x02
#define FA_SYSTEM 0x04
#define FA_LABEL 0x08
#define FA_DIREC 0x10
#define FA_ARCH 0x20
#endif
#endif

10
libunrar/rarlang.hpp Normal file
View File

@ -0,0 +1,10 @@
#ifndef _RAR_LANG_
#define _RAR_LANG_
#ifdef USE_RC
#include "rarres.hpp"
#else
#include "loclang.hpp"
#endif
#endif

41
libunrar/raros.hpp Normal file
View File

@ -0,0 +1,41 @@
#ifndef _RAR_RAROS_
#define _RAR_RAROS_
#ifdef __EMX__
#define _EMX
#endif
#ifdef __DJGPP__
#define _DJGPP
#define _EMX
#endif
#if defined(__WIN32__) || defined(_WIN32)
#define _WIN_32
#endif
#ifdef _WIN32_WCE
#define _WIN_32
#define _WIN_CE
#ifdef WM_FILECHANGEINFO
#define PC2002
#else
#undef PC2002
#endif
#endif
#ifdef __BEOS__
#define _UNIX
#define _BEOS
#endif
#ifdef __APPLE__
#define _UNIX
#define _APPLE
#endif
#if !defined(_EMX) && !defined(_WIN_32) && !defined(_BEOS) && !defined(_APPLE)
#define _UNIX
#endif
#endif

47
libunrar/rartypes.hpp Normal file
View File

@ -0,0 +1,47 @@
#ifndef _RAR_TYPES_
#define _RAR_TYPES_
typedef unsigned char byte; // unsigned 8 bits
typedef unsigned short ushort; // preferably 16 bits, but can be more
typedef unsigned int uint; // 32 bits or more
#define PRESENT_INT32 // undefine if signed 32 bits is not available
typedef unsigned int uint32; // 32 bits exactly
typedef signed int int32; // signed 32 bits exactly
// If compiler does not support 64 bit variables, we can define
// uint64 and int64 as 32 bit, but it will limit the maximum processed
// file size to 2 GB.
#if defined(__BORLANDC__) || defined(_MSC_VER)
typedef unsigned __int64 uint64; // unsigned 64 bits
typedef signed __int64 int64; // signed 64 bits
#else
typedef unsigned long long uint64; // unsigned 64 bits
typedef signed long long int64; // signed 64 bits
#endif
#if defined(_WIN_32) || defined(__GNUC__) || defined(__sgi) || defined(_AIX) || defined(__sun) || defined(__hpux) || defined(_OSF_SOURCE)
typedef wchar_t wchar;
#else
typedef ushort wchar;
#endif
// Get lowest 16 bits.
#define SHORT16(x) (sizeof(ushort)==2 ? (ushort)(x):((x)&0xffff))
// Get lowest 32 bits.
#define UINT32(x) (sizeof(uint32)==4 ? (uint32)(x):((x)&0xffffffff))
// Make 64 bit integer from two 32 bit.
#define INT32TO64(high,low) ((((uint64)(high))<<32)+((uint64)low))
// Special int64 value, large enough to be never found in real life.
// We use it in situations, when we need to indicate that parameter
// is not defined and probably should be calculated inside of function.
// Lower part is intentionally 0x7fffffff, not 0xffffffff, to make it
// compatible with 32 bit int64.
#define INT64NDF INT32TO64(0x7fffffff,0x7fffffff)
#endif

1139
libunrar/rarvm.cpp Normal file

File diff suppressed because it is too large Load Diff

113
libunrar/rarvm.hpp Normal file
View File

@ -0,0 +1,113 @@
#ifndef _RAR_VM_
#define _RAR_VM_
#define VM_STANDARDFILTERS
#ifndef SFX_MODULE
#define VM_OPTIMIZE
#endif
#define VM_MEMSIZE 0x40000
#define VM_MEMMASK (VM_MEMSIZE-1)
#define VM_GLOBALMEMADDR 0x3C000
#define VM_GLOBALMEMSIZE 0x2000
#define VM_FIXEDGLOBALSIZE 64
enum VM_Commands
{
VM_MOV, VM_CMP, VM_ADD, VM_SUB, VM_JZ, VM_JNZ, VM_INC, VM_DEC,
VM_JMP, VM_XOR, VM_AND, VM_OR, VM_TEST, VM_JS, VM_JNS, VM_JB,
VM_JBE, VM_JA, VM_JAE, VM_PUSH, VM_POP, VM_CALL, VM_RET, VM_NOT,
VM_SHL, VM_SHR, VM_SAR, VM_NEG, VM_PUSHA,VM_POPA, VM_PUSHF,VM_POPF,
VM_MOVZX,VM_MOVSX,VM_XCHG, VM_MUL, VM_DIV, VM_ADC, VM_SBB, VM_PRINT,
#ifdef VM_OPTIMIZE
VM_MOVB, VM_MOVD, VM_CMPB, VM_CMPD,
VM_ADDB, VM_ADDD, VM_SUBB, VM_SUBD, VM_INCB, VM_INCD, VM_DECB, VM_DECD,
VM_NEGB, VM_NEGD,
#endif
VM_STANDARD
};
enum VM_StandardFilters {
VMSF_NONE, VMSF_E8, VMSF_E8E9, VMSF_ITANIUM, VMSF_RGB, VMSF_AUDIO,
VMSF_DELTA, VMSF_UPCASE
};
enum VM_Flags {VM_FC=1,VM_FZ=2,VM_FS=0x80000000};
enum VM_OpType {VM_OPREG,VM_OPINT,VM_OPREGMEM,VM_OPNONE};
struct VM_PreparedOperand
{
VM_OpType Type;
uint Data;
uint Base;
uint *Addr;
};
struct VM_PreparedCommand
{
VM_Commands OpCode;
bool ByteMode;
VM_PreparedOperand Op1,Op2;
};
struct VM_PreparedProgram
{
VM_PreparedProgram()
{
AltCmd=NULL;
FilteredDataSize=0;
CmdCount=0;
}
Array<VM_PreparedCommand> Cmd;
VM_PreparedCommand *AltCmd;
int CmdCount;
Array<byte> GlobalData;
Array<byte> StaticData; // static data contained in DB operators
uint InitR[7];
byte *FilteredData;
uint FilteredDataSize;
};
class RarVM:private BitInput
{
private:
inline uint GetValue(bool ByteMode,uint *Addr);
inline void SetValue(bool ByteMode,uint *Addr,uint Value);
inline uint* GetOperand(VM_PreparedOperand *CmdOp);
void DecodeArg(VM_PreparedOperand &Op,bool ByteMode);
#ifdef VM_OPTIMIZE
void Optimize(VM_PreparedProgram *Prg);
#endif
bool ExecuteCode(VM_PreparedCommand *PreparedCode,uint CodeSize);
#ifdef VM_STANDARDFILTERS
VM_StandardFilters IsStandardFilter(byte *Code,uint CodeSize);
void ExecuteStandardFilter(VM_StandardFilters FilterType);
uint FilterItanium_GetBits(byte *Data,int BitPos,int BitCount);
void FilterItanium_SetBits(byte *Data,uint BitField,int BitPos,int BitCount);
#endif
byte *Mem;
uint R[8];
uint Flags;
public:
RarVM();
~RarVM();
void Init();
void Prepare(byte *Code,uint CodeSize,VM_PreparedProgram *Prg);
void Execute(VM_PreparedProgram *Prg);
void SetLowEndianValue(uint *Addr,uint Value);
void SetMemory(uint Pos,byte *Data,uint DataSize);
static uint ReadData(BitInput &Inp);
};
#endif

53
libunrar/rarvmtbl.cpp Normal file
View File

@ -0,0 +1,53 @@
#define VMCF_OP0 0
#define VMCF_OP1 1
#define VMCF_OP2 2
#define VMCF_OPMASK 3
#define VMCF_BYTEMODE 4
#define VMCF_JUMP 8
#define VMCF_PROC 16
#define VMCF_USEFLAGS 32
#define VMCF_CHFLAGS 64
static byte VM_CmdFlags[]=
{
/* VM_MOV */ VMCF_OP2 | VMCF_BYTEMODE ,
/* VM_CMP */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS ,
/* VM_ADD */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS ,
/* VM_SUB */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS ,
/* VM_JZ */ VMCF_OP1 | VMCF_JUMP | VMCF_USEFLAGS ,
/* VM_JNZ */ VMCF_OP1 | VMCF_JUMP | VMCF_USEFLAGS ,
/* VM_INC */ VMCF_OP1 | VMCF_BYTEMODE | VMCF_CHFLAGS ,
/* VM_DEC */ VMCF_OP1 | VMCF_BYTEMODE | VMCF_CHFLAGS ,
/* VM_JMP */ VMCF_OP1 | VMCF_JUMP ,
/* VM_XOR */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS ,
/* VM_AND */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS ,
/* VM_OR */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS ,
/* VM_TEST */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS ,
/* VM_JS */ VMCF_OP1 | VMCF_JUMP | VMCF_USEFLAGS ,
/* VM_JNS */ VMCF_OP1 | VMCF_JUMP | VMCF_USEFLAGS ,
/* VM_JB */ VMCF_OP1 | VMCF_JUMP | VMCF_USEFLAGS ,
/* VM_JBE */ VMCF_OP1 | VMCF_JUMP | VMCF_USEFLAGS ,
/* VM_JA */ VMCF_OP1 | VMCF_JUMP | VMCF_USEFLAGS ,
/* VM_JAE */ VMCF_OP1 | VMCF_JUMP | VMCF_USEFLAGS ,
/* VM_PUSH */ VMCF_OP1 ,
/* VM_POP */ VMCF_OP1 ,
/* VM_CALL */ VMCF_OP1 | VMCF_PROC ,
/* VM_RET */ VMCF_OP0 | VMCF_PROC ,
/* VM_NOT */ VMCF_OP1 | VMCF_BYTEMODE ,
/* VM_SHL */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS ,
/* VM_SHR */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS ,
/* VM_SAR */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS ,
/* VM_NEG */ VMCF_OP1 | VMCF_BYTEMODE | VMCF_CHFLAGS ,
/* VM_PUSHA */ VMCF_OP0 ,
/* VM_POPA */ VMCF_OP0 ,
/* VM_PUSHF */ VMCF_OP0 | VMCF_USEFLAGS ,
/* VM_POPF */ VMCF_OP0 | VMCF_CHFLAGS ,
/* VM_MOVZX */ VMCF_OP2 ,
/* VM_MOVSX */ VMCF_OP2 ,
/* VM_XCHG */ VMCF_OP2 | VMCF_BYTEMODE ,
/* VM_MUL */ VMCF_OP2 | VMCF_BYTEMODE ,
/* VM_DIV */ VMCF_OP2 | VMCF_BYTEMODE ,
/* VM_ADC */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_USEFLAGS | VMCF_CHFLAGS ,
/* VM_SBB */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_USEFLAGS | VMCF_CHFLAGS ,
/* VM_PRINT */ VMCF_OP0
};

126
libunrar/rawread.cpp Normal file
View File

@ -0,0 +1,126 @@
#include "rar.hpp"
RawRead::RawRead(File *SrcFile)
{
RawRead::SrcFile=SrcFile;
ReadPos=0;
DataSize=0;
#ifndef SHELL_EXT
Crypt=NULL;
#endif
}
void RawRead::Read(size_t Size)
{
#if !defined(SHELL_EXT) && !defined(NOCRYPT)
if (Crypt!=NULL)
{
size_t CurSize=Data.Size();
size_t SizeToRead=Size-(CurSize-DataSize);
if (SizeToRead>0)
{
size_t AlignedReadSize=SizeToRead+((~SizeToRead+1)&0xf);
Data.Add(AlignedReadSize);
size_t ReadSize=SrcFile->Read(&Data[CurSize],AlignedReadSize);
Crypt->DecryptBlock(&Data[CurSize],AlignedReadSize);
DataSize+=ReadSize==0 ? 0:Size;
}
else
DataSize+=Size;
}
else
#endif
if (Size!=0)
{
Data.Add(Size);
DataSize+=SrcFile->Read(&Data[DataSize],Size);
}
}
void RawRead::Read(byte *SrcData,size_t Size)
{
if (Size!=0)
{
Data.Add(Size);
memcpy(&Data[DataSize],SrcData,Size);
DataSize+=Size;
}
}
void RawRead::Get(byte &Field)
{
if (ReadPos<DataSize)
{
Field=Data[ReadPos];
ReadPos++;
}
else
Field=0;
}
void RawRead::Get(ushort &Field)
{
if (ReadPos+1<DataSize)
{
Field=Data[ReadPos]+(Data[ReadPos+1]<<8);
ReadPos+=2;
}
else
Field=0;
}
void RawRead::Get(uint &Field)
{
if (ReadPos+3<DataSize)
{
Field=Data[ReadPos]+(Data[ReadPos+1]<<8)+(Data[ReadPos+2]<<16)+
(Data[ReadPos+3]<<24);
ReadPos+=4;
}
else
Field=0;
}
void RawRead::Get8(int64 &Field)
{
uint Low,High;
Get(Low);
Get(High);
Field=INT32TO64(High,Low);
}
void RawRead::Get(byte *Field,size_t Size)
{
if (ReadPos+Size-1<DataSize)
{
memcpy(Field,&Data[ReadPos],Size);
ReadPos+=Size;
}
else
memset(Field,0,Size);
}
void RawRead::Get(wchar *Field,size_t Size)
{
if (ReadPos+2*Size-1<DataSize)
{
RawToWide(&Data[ReadPos],Field,Size);
ReadPos+=2*Size;
}
else
memset(Field,0,2*Size);
}
uint RawRead::GetCRC(bool ProcessedOnly)
{
return(DataSize>2 ? CRC(0xffffffff,&Data[2],(ProcessedOnly ? ReadPos:DataSize)-2):0xffffffff);
}

32
libunrar/rawread.hpp Normal file
View File

@ -0,0 +1,32 @@
#ifndef _RAR_RAWREAD_
#define _RAR_RAWREAD_
class RawRead
{
private:
Array<byte> Data;
File *SrcFile;
size_t DataSize;
size_t ReadPos;
#ifndef SHELL_EXT
CryptData *Crypt;
#endif
public:
RawRead(File *SrcFile);
void Read(size_t Size);
void Read(byte *SrcData,size_t Size);
void Get(byte &Field);
void Get(ushort &Field);
void Get(uint &Field);
void Get8(int64 &Field);
void Get(byte *Field,size_t Size);
void Get(wchar *Field,size_t Size);
uint GetCRC(bool ProcessedOnly);
size_t Size() {return DataSize;}
size_t PaddedSize() {return Data.Size()-DataSize;}
#ifndef SHELL_EXT
void SetCrypt(CryptData *Crypt) {RawRead::Crypt=Crypt;}
#endif
};
#endif

295
libunrar/rdwrfn.cpp Normal file
View File

@ -0,0 +1,295 @@
#include "rar.hpp"
ComprDataIO::ComprDataIO()
{
Init();
}
void ComprDataIO::Init()
{
UnpackFromMemory=false;
UnpackToMemory=false;
UnpPackedSize=0;
ShowProgress=true;
TestMode=false;
SkipUnpCRC=false;
PackVolume=false;
UnpVolume=false;
NextVolumeMissing=false;
SrcFile=NULL;
DestFile=NULL;
UnpWrSize=0;
Command=NULL;
Encryption=0;
Decryption=0;
TotalPackRead=0;
CurPackRead=CurPackWrite=CurUnpRead=CurUnpWrite=0;
PackFileCRC=UnpFileCRC=PackedCRC=0xffffffff;
LastPercent=-1;
SubHead=NULL;
SubHeadPos=NULL;
CurrentCommand=0;
ProcessedArcSize=TotalArcSize=0;
}
int ComprDataIO::UnpRead(byte *Addr,size_t Count)
{
int RetCode=0,TotalRead=0;
byte *ReadAddr;
ReadAddr=Addr;
while (Count > 0)
{
Archive *SrcArc=(Archive *)SrcFile;
size_t ReadSize=((int64)Count>UnpPackedSize) ? (size_t)UnpPackedSize:Count;
if (UnpackFromMemory)
{
memcpy(Addr,UnpackFromMemoryAddr,UnpackFromMemorySize);
RetCode=(int)UnpackFromMemorySize;
UnpackFromMemorySize=0;
}
else
{
if (!SrcFile->IsOpened())
return(-1);
RetCode=SrcFile->Read(ReadAddr,ReadSize);
FileHeader *hd=SubHead!=NULL ? SubHead:&SrcArc->NewLhd;
if (hd->Flags & LHD_SPLIT_AFTER)
PackedCRC=CRC(PackedCRC,ReadAddr,RetCode);
}
CurUnpRead+=RetCode;
TotalRead+=RetCode;
#ifndef NOVOLUME
// These variable are not used in NOVOLUME mode, so it is better
// to exclude commands below to avoid compiler warnings.
ReadAddr+=RetCode;
Count-=RetCode;
#endif
UnpPackedSize-=RetCode;
if (UnpPackedSize == 0 && UnpVolume)
{
#ifndef NOVOLUME
if (!MergeArchive(*SrcArc,this,true,CurrentCommand))
#endif
{
NextVolumeMissing=true;
return(-1);
}
}
else
break;
}
Archive *SrcArc=(Archive *)SrcFile;
if (SrcArc!=NULL)
ShowUnpRead(SrcArc->CurBlockPos+CurUnpRead,UnpArcSize);
if (RetCode!=-1)
{
RetCode=TotalRead;
#ifndef NOCRYPT
if (Decryption)
#ifndef SFX_MODULE
if (Decryption<20)
Decrypt.Crypt(Addr,RetCode,(Decryption==15) ? NEW_CRYPT : OLD_DECODE);
else
if (Decryption==20)
for (int I=0;I<RetCode;I+=16)
Decrypt.DecryptBlock20(&Addr[I]);
else
#endif
{
int CryptSize=(RetCode & 0xf)==0 ? RetCode:((RetCode & ~0xf)+16);
Decrypt.DecryptBlock(Addr,CryptSize);
}
#endif
}
Wait();
return(RetCode);
}
#if defined(RARDLL) && defined(_MSC_VER) && !defined(_M_X64)
// Disable the run time stack check for unrar.dll, so we can manipulate
// with ProcessDataProc call type below. Run time check would intercept
// a wrong ESP before we restore it.
#pragma runtime_checks( "s", off )
#endif
void ComprDataIO::UnpWrite(byte *Addr,size_t Count)
{
#ifdef RARDLL
RAROptions *Cmd=((Archive *)SrcFile)->GetRAROptions();
if (Cmd->DllOpMode!=RAR_SKIP)
{
if (Cmd->Callback!=NULL &&
Cmd->Callback(UCM_PROCESSDATA,Cmd->UserData,(LPARAM)Addr,Count)==-1)
ErrHandler.Exit(USER_BREAK);
if (Cmd->ProcessDataProc!=NULL)
{
// Here we preserve ESP value. It is necessary for those developers,
// who still define ProcessDataProc callback as "C" type function,
// even though in year 2001 we announced in unrar.dll whatsnew.txt
// that it will be PASCAL type (for compatibility with Visual Basic).
#if defined(_MSC_VER)
#ifndef _M_X64
__asm mov ebx,esp
#endif
#elif defined(_WIN_32) && defined(__BORLANDC__)
_EBX=_ESP;
#endif
int RetCode=Cmd->ProcessDataProc(Addr,(int)Count);
// Restore ESP after ProcessDataProc with wrongly defined calling
// convention broken it.
#if defined(_MSC_VER)
#ifndef _M_X64
__asm mov esp,ebx
#endif
#elif defined(_WIN_32) && defined(__BORLANDC__)
_ESP=_EBX;
#endif
if (RetCode==0)
ErrHandler.Exit(USER_BREAK);
}
}
#endif // RARDLL
UnpWrAddr=Addr;
UnpWrSize=Count;
if (UnpackToMemory)
{
if (Count <= UnpackToMemorySize)
{
memcpy(UnpackToMemoryAddr,Addr,Count);
UnpackToMemoryAddr+=Count;
UnpackToMemorySize-=Count;
}
}
else
if (!TestMode)
DestFile->Write(Addr,Count);
CurUnpWrite+=Count;
if (!SkipUnpCRC)
#ifndef SFX_MODULE
if (((Archive *)SrcFile)->OldFormat)
UnpFileCRC=OldCRC((ushort)UnpFileCRC,Addr,Count);
else
#endif
UnpFileCRC=CRC(UnpFileCRC,Addr,Count);
ShowUnpWrite();
Wait();
}
#if defined(RARDLL) && defined(_MSC_VER) && !defined(_M_X64)
// Restore the run time stack check for unrar.dll.
#pragma runtime_checks( "s", restore )
#endif
void ComprDataIO::ShowUnpRead(int64 ArcPos,int64 ArcSize)
{
if (ShowProgress && SrcFile!=NULL)
{
if (TotalArcSize!=0)
{
// important when processing several archives or multivolume archive
ArcSize=TotalArcSize;
ArcPos+=ProcessedArcSize;
}
Archive *SrcArc=(Archive *)SrcFile;
RAROptions *Cmd=SrcArc->GetRAROptions();
int CurPercent=ToPercent(ArcPos,ArcSize);
if (!Cmd->DisablePercentage && CurPercent!=LastPercent)
{
mprintf("\b\b\b\b%3d%%",CurPercent);
LastPercent=CurPercent;
}
}
}
void ComprDataIO::ShowUnpWrite()
{
}
void ComprDataIO::SetFiles(File *SrcFile,File *DestFile)
{
if (SrcFile!=NULL)
ComprDataIO::SrcFile=SrcFile;
if (DestFile!=NULL)
ComprDataIO::DestFile=DestFile;
LastPercent=-1;
}
void ComprDataIO::GetUnpackedData(byte **Data,size_t *Size)
{
*Data=UnpWrAddr;
*Size=UnpWrSize;
}
void ComprDataIO::SetEncryption(int Method,const char *Password,const byte *Salt,bool Encrypt,bool HandsOffHash)
{
if (Encrypt)
{
Encryption=*Password ? Method:0;
#ifndef NOCRYPT
Crypt.SetCryptKeys(Password,Salt,Encrypt,false,HandsOffHash);
#endif
}
else
{
Decryption=*Password ? Method:0;
#ifndef NOCRYPT
Decrypt.SetCryptKeys(Password,Salt,Encrypt,Method<29,HandsOffHash);
#endif
}
}
#if !defined(SFX_MODULE) && !defined(NOCRYPT)
void ComprDataIO::SetAV15Encryption()
{
Decryption=15;
Decrypt.SetAV15Encryption();
}
#endif
#if !defined(SFX_MODULE) && !defined(NOCRYPT)
void ComprDataIO::SetCmt13Encryption()
{
Decryption=13;
Decrypt.SetCmt13Encryption();
}
#endif
void ComprDataIO::SetUnpackToMemory(byte *Addr,uint Size)
{
UnpackToMemory=true;
UnpackToMemoryAddr=Addr;
UnpackToMemorySize=Size;
}

88
libunrar/rdwrfn.hpp Normal file
View File

@ -0,0 +1,88 @@
#ifndef _RAR_DATAIO_
#define _RAR_DATAIO_
class CmdAdd;
class Unpack;
class ComprDataIO
{
private:
void ShowUnpRead(int64 ArcPos,int64 ArcSize);
void ShowUnpWrite();
bool UnpackFromMemory;
size_t UnpackFromMemorySize;
byte *UnpackFromMemoryAddr;
bool UnpackToMemory;
size_t UnpackToMemorySize;
byte *UnpackToMemoryAddr;
size_t UnpWrSize;
byte *UnpWrAddr;
int64 UnpPackedSize;
bool ShowProgress;
bool TestMode;
bool SkipUnpCRC;
File *SrcFile;
File *DestFile;
CmdAdd *Command;
FileHeader *SubHead;
int64 *SubHeadPos;
#ifndef NOCRYPT
CryptData Crypt;
CryptData Decrypt;
#endif
int LastPercent;
char CurrentCommand;
public:
ComprDataIO();
void Init();
int UnpRead(byte *Addr,size_t Count);
void UnpWrite(byte *Addr,size_t Count);
void EnableShowProgress(bool Show) {ShowProgress=Show;}
void GetUnpackedData(byte **Data,size_t *Size);
void SetPackedSizeToRead(int64 Size) {UnpPackedSize=Size;}
void SetTestMode(bool Mode) {TestMode=Mode;}
void SetSkipUnpCRC(bool Skip) {SkipUnpCRC=Skip;}
void SetFiles(File *SrcFile,File *DestFile);
void SetCommand(CmdAdd *Cmd) {Command=Cmd;}
void SetSubHeader(FileHeader *hd,int64 *Pos) {SubHead=hd;SubHeadPos=Pos;}
void SetEncryption(int Method,const char *Password,const byte *Salt,bool Encrypt,bool HandsOffHash);
void SetAV15Encryption();
void SetCmt13Encryption();
void SetUnpackToMemory(byte *Addr,uint Size);
void SetCurrentCommand(char Cmd) {CurrentCommand=Cmd;}
bool PackVolume;
bool UnpVolume;
bool NextVolumeMissing;
int64 TotalPackRead;
int64 UnpArcSize;
int64 CurPackRead,CurPackWrite,CurUnpRead,CurUnpWrite;
// Size of already processed archives.
// Used to calculate the total operation progress.
int64 ProcessedArcSize;
int64 TotalArcSize;
uint PackFileCRC,UnpFileCRC,PackedCRC;
int Encryption;
int Decryption;
};
#endif

63
libunrar/readme.txt Normal file
View File

@ -0,0 +1,63 @@
Portable UnRAR version
1. General
This package includes freeware Unrar C++ source and a few makefiles
(makefile.bcc, makefile.msc+msc.dep, makefile.unix). Unrar source
is subset of RAR and generated from RAR source automatically,
by a small program removing blocks like '#ifndef UNRAR ... #endif'.
Such method is not perfect and you may find some RAR related
stuff unnecessary in Unrar, especially in header files.
If you wish to port Unrar to a new platform, you may need to edit
'#define LITTLE_ENDIAN' in os.hpp and data type definitions
in rartypes.hpp.
if computer architecture does not allow not aligned data access,
you need to undefine ALLOW_NOT_ALIGNED_INT and define
STRICT_ALIGNMENT_REQUIRED in os.h. Note that it will increase memory
requirements.
If you use Borland C++ makefile (makefile.bcc), you need to define
BASEPATHCC environment (or makefile) variable containing
the path to Borland C++ installation.
Makefile.unix contains numerous compiler option sets.
GCC Linux is selected by default. If you need to compile Unrar
for other platforms, uncomment corresponding lines.
2. Unrar binaries
If you compiled Unrar for OS, which is not present in "Downloads"
and "RAR extras" on www.rarlab.com, we will appreciate if you send
us the compiled executable to place it to our site.
3. Acknowledgements
This source includes parts of code written by the following authors:
Dmitry Shkarin PPMII v.H text compression
Dmitry Subbotin Carryless rangecoder
Szymon Stefanek AES encryption
Brian Gladman AES encryption
Steve Reid SHA-1 hash function
Marcus Herbert makefile.unix file
Tomasz Klim fixes for libunrar.so
Robert Riebisch makefile.dj and patches for DJGPP
4. Legal stuff
Unrar source may be used in any software to handle RAR archives
without limitations free of charge, but cannot be used to re-create
the RAR compression algorithm, which is proprietary. Distribution
of modified Unrar source in separate form or as a part of other
software is permitted, provided that it is clearly stated in
the documentation and source comments that the code may not be used
to develop a RAR (WinRAR) compatible archiver.
More detailed license text is available in license.txt.

372
libunrar/recvol.cpp Normal file
View File

@ -0,0 +1,372 @@
#include "rar.hpp"
#define RECVOL_BUFSIZE 0x8000
RecVolumes::RecVolumes()
{
Buf.Alloc(RECVOL_BUFSIZE*256);
memset(SrcFile,0,sizeof(SrcFile));
}
RecVolumes::~RecVolumes()
{
for (int I=0;I<sizeof(SrcFile)/sizeof(SrcFile[0]);I++)
delete SrcFile[I];
}
bool RecVolumes::Restore(RAROptions *Cmd,const char *Name,
const wchar *NameW,bool Silent)
{
char ArcName[NM];
wchar ArcNameW[NM];
strcpy(ArcName,Name);
strcpyw(ArcNameW,NameW);
char *Ext=GetExt(ArcName);
bool NewStyle=false;
bool RevName=Ext!=NULL && stricomp(Ext,".rev")==0;
if (RevName)
{
for (int DigitGroup=0;Ext>ArcName && DigitGroup<3;Ext--)
if (!IsDigit(*Ext))
if (IsDigit(*(Ext-1)) && (*Ext=='_' || DigitGroup<2))
DigitGroup++;
else
if (DigitGroup<2)
{
NewStyle=true;
break;
}
while (IsDigit(*Ext) && Ext>ArcName+1)
Ext--;
strcpy(Ext,"*.*");
FindFile Find;
Find.SetMask(ArcName);
struct FindData FD;
while (Find.Next(&FD))
{
Archive Arc(Cmd);
if (Arc.WOpen(FD.Name,FD.NameW) && Arc.IsArchive(true))
{
strcpy(ArcName,FD.Name);
*ArcNameW=0;
break;
}
}
}
Archive Arc(Cmd);
if (!Arc.WCheckOpen(ArcName,ArcNameW))
return(false);
if (!Arc.Volume)
{
#ifndef SILENT
Log(ArcName,St(MNotVolume),ArcName);
#endif
return(false);
}
bool NewNumbering=(Arc.NewMhd.Flags & MHD_NEWNUMBERING)!=0;
Arc.Close();
char *VolNumStart=VolNameToFirstName(ArcName,ArcName,NewNumbering);
char RecVolMask[NM];
strcpy(RecVolMask,ArcName);
size_t BaseNamePartLength=VolNumStart-ArcName;
strcpy(RecVolMask+BaseNamePartLength,"*.rev");
#ifndef SILENT
int64 RecFileSize=0;
#endif
#ifndef SILENT
mprintf(St(MCalcCRCAllVol));
#endif
FindFile Find;
Find.SetMask(RecVolMask);
struct FindData RecData;
int FileNumber=0,RecVolNumber=0,FoundRecVolumes=0,MissingVolumes=0;
char PrevName[NM];
while (Find.Next(&RecData))
{
char *Name=RecData.Name;
int P[3];
if (!RevName && !NewStyle)
{
NewStyle=true;
char *Dot=GetExt(Name);
if (Dot!=NULL)
{
int LineCount=0;
Dot--;
while (Dot>Name && *Dot!='.')
{
if (*Dot=='_')
LineCount++;
Dot--;
}
if (LineCount==2)
NewStyle=false;
}
}
if (NewStyle)
{
File CurFile;
CurFile.TOpen(Name);
CurFile.Seek(0,SEEK_END);
int64 Length=CurFile.Tell();
CurFile.Seek(Length-7,SEEK_SET);
for (int I=0;I<3;I++)
P[2-I]=CurFile.GetByte()+1;
uint FileCRC=0;
for (int I=0;I<4;I++)
FileCRC|=CurFile.GetByte()<<(I*8);
if (FileCRC!=CalcFileCRC(&CurFile,Length-4))
{
#ifndef SILENT
mprintf(St(MCRCFailed),Name);
#endif
continue;
}
}
else
{
char *Dot=GetExt(Name);
if (Dot==NULL)
continue;
bool WrongParam=false;
for (int I=0;I<sizeof(P)/sizeof(P[0]);I++)
{
do
{
Dot--;
} while (IsDigit(*Dot) && Dot>=Name+BaseNamePartLength);
P[I]=atoi(Dot+1);
if (P[I]==0 || P[I]>255)
WrongParam=true;
}
if (WrongParam)
continue;
}
if (P[1]+P[2]>255)
continue;
if (RecVolNumber!=0 && RecVolNumber!=P[1] || FileNumber!=0 && FileNumber!=P[2])
{
#ifndef SILENT
Log(NULL,St(MRecVolDiffSets),Name,PrevName);
#endif
return(false);
}
RecVolNumber=P[1];
FileNumber=P[2];
strcpy(PrevName,Name);
File *NewFile=new File;
NewFile->TOpen(Name);
SrcFile[FileNumber+P[0]-1]=NewFile;
FoundRecVolumes++;
#ifndef SILENT
if (RecFileSize==0)
RecFileSize=NewFile->FileLength();
#endif
}
#ifndef SILENT
if (!Silent || FoundRecVolumes!=0)
{
mprintf(St(MRecVolFound),FoundRecVolumes);
}
#endif
if (FoundRecVolumes==0)
return(false);
bool WriteFlags[256];
memset(WriteFlags,0,sizeof(WriteFlags));
char LastVolName[NM];
*LastVolName=0;
for (int CurArcNum=0;CurArcNum<FileNumber;CurArcNum++)
{
Archive *NewFile=new Archive;
bool ValidVolume=FileExist(ArcName);
if (ValidVolume)
{
NewFile->TOpen(ArcName);
ValidVolume=NewFile->IsArchive(false);
if (ValidVolume)
{
while (NewFile->ReadHeader()!=0)
{
if (NewFile->GetHeaderType()==ENDARC_HEAD)
{
if ((NewFile->EndArcHead.Flags&EARC_DATACRC)!=0 &&
NewFile->EndArcHead.ArcDataCRC!=CalcFileCRC(NewFile,NewFile->CurBlockPos))
{
ValidVolume=false;
#ifndef SILENT
mprintf(St(MCRCFailed),ArcName);
#endif
}
break;
}
NewFile->SeekToNext();
}
}
if (!ValidVolume)
{
NewFile->Close();
char NewName[NM];
strcpy(NewName,ArcName);
strcat(NewName,".bad");
#ifndef SILENT
mprintf(St(MBadArc),ArcName);
mprintf(St(MRenaming),ArcName,NewName);
#endif
rename(ArcName,NewName);
}
NewFile->Seek(0,SEEK_SET);
}
if (!ValidVolume)
{
NewFile->TCreate(ArcName);
WriteFlags[CurArcNum]=true;
MissingVolumes++;
if (CurArcNum==FileNumber-1)
strcpy(LastVolName,ArcName);
#ifndef SILENT
mprintf(St(MAbsNextVol),ArcName);
#endif
}
SrcFile[CurArcNum]=(File*)NewFile;
NextVolumeName(ArcName,ArcNameW,ASIZE(ArcName),!NewNumbering);
}
#ifndef SILENT
mprintf(St(MRecVolMissing),MissingVolumes);
#endif
if (MissingVolumes==0)
{
#ifndef SILENT
mprintf(St(MRecVolAllExist));
#endif
return(false);
}
if (MissingVolumes>FoundRecVolumes)
{
#ifndef SILENT
mprintf(St(MRecVolCannotFix));
#endif
return(false);
}
#ifndef SILENT
mprintf(St(MReconstructing));
#endif
RSCoder RSC(RecVolNumber);
int TotalFiles=FileNumber+RecVolNumber;
int Erasures[256],EraSize=0;
for (int I=0;I<TotalFiles;I++)
if (WriteFlags[I] || SrcFile[I]==NULL)
Erasures[EraSize++]=I;
#ifndef SILENT
int64 ProcessedSize=0;
#ifndef GUI
int LastPercent=-1;
mprintf(" ");
#endif
#endif
int RecCount=0;
while (true)
{
if ((++RecCount & 15)==0)
Wait();
int MaxRead=0;
for (int I=0;I<TotalFiles;I++)
if (WriteFlags[I] || SrcFile[I]==NULL)
memset(&Buf[I*RECVOL_BUFSIZE],0,RECVOL_BUFSIZE);
else
{
int ReadSize=SrcFile[I]->Read(&Buf[I*RECVOL_BUFSIZE],RECVOL_BUFSIZE);
if (ReadSize!=RECVOL_BUFSIZE)
memset(&Buf[I*RECVOL_BUFSIZE+ReadSize],0,RECVOL_BUFSIZE-ReadSize);
if (ReadSize>MaxRead)
MaxRead=ReadSize;
}
if (MaxRead==0)
break;
#ifndef SILENT
int CurPercent=ToPercent(ProcessedSize,RecFileSize);
if (!Cmd->DisablePercentage && CurPercent!=LastPercent)
{
mprintf("\b\b\b\b%3d%%",CurPercent);
LastPercent=CurPercent;
}
ProcessedSize+=MaxRead;
#endif
for (int BufPos=0;BufPos<MaxRead;BufPos++)
{
byte Data[256];
for (int I=0;I<TotalFiles;I++)
Data[I]=Buf[I*RECVOL_BUFSIZE+BufPos];
RSC.Decode(Data,TotalFiles,Erasures,EraSize);
for (int I=0;I<EraSize;I++)
Buf[Erasures[I]*RECVOL_BUFSIZE+BufPos]=Data[Erasures[I]];
/*
for (int I=0;I<FileNumber;I++)
Buf[I*RECVOL_BUFSIZE+BufPos]=Data[I];
*/
}
for (int I=0;I<FileNumber;I++)
if (WriteFlags[I])
SrcFile[I]->Write(&Buf[I*RECVOL_BUFSIZE],MaxRead);
}
for (int I=0;I<RecVolNumber+FileNumber;I++)
if (SrcFile[I]!=NULL)
{
File *CurFile=SrcFile[I];
if (NewStyle && WriteFlags[I])
{
int64 Length=CurFile->Tell();
CurFile->Seek(Length-7,SEEK_SET);
for (int J=0;J<7;J++)
CurFile->PutByte(0);
}
CurFile->Close();
SrcFile[I]=NULL;
}
if (*LastVolName)
{
Archive Arc(Cmd);
if (Arc.Open(LastVolName,NULL,false,true) && Arc.IsArchive(true) &&
Arc.SearchBlock(ENDARC_HEAD))
{
Arc.Seek(Arc.NextBlockPos,SEEK_SET);
char Buf[8192];
int ReadSize=Arc.Read(Buf,sizeof(Buf));
int ZeroCount=0;
while (ZeroCount<ReadSize && Buf[ZeroCount]==0)
ZeroCount++;
if (ZeroCount==ReadSize)
{
Arc.Seek(Arc.NextBlockPos,SEEK_SET);
Arc.Truncate();
}
}
}
#if !defined(GUI) && !defined(SILENT)
if (!Cmd->DisablePercentage)
mprintf("\b\b\b\b100%%");
if (!Silent && !Cmd->DisableDone)
mprintf(St(MDone));
#endif
return(true);
}

16
libunrar/recvol.hpp Normal file
View File

@ -0,0 +1,16 @@
#ifndef _RAR_RECVOL_
#define _RAR_RECVOL_
class RecVolumes
{
private:
File *SrcFile[256];
Array<byte> Buf;
public:
RecVolumes();
~RecVolumes();
void Make(RAROptions *Cmd,char *ArcName,wchar *ArcNameW);
bool Restore(RAROptions *Cmd,const char *Name,const wchar *NameW,bool Silent);
};
#endif

12
libunrar/resource.cpp Normal file
View File

@ -0,0 +1,12 @@
#include "rar.hpp"
#if !defined(SILENT) || !defined(RARDLL)
const char *St(MSGID StringId)
{
return(StringId);
}
#endif

14
libunrar/resource.hpp Normal file
View File

@ -0,0 +1,14 @@
#ifndef _RAR_RESOURCE_
#define _RAR_RESOURCE_
#if defined(SILENT) && defined(RARDLL)
#define St(x) ("")
#else
const char *St(MSGID StringId);
#endif
inline const char *StT(MSGID StringId) {return(St(StringId));}
#endif

298
libunrar/rijndael.cpp Normal file
View File

@ -0,0 +1,298 @@
/**************************************************************************
* This code is based on Szymon Stefanek AES implementation: *
* http://www.esat.kuleuven.ac.be/~rijmen/rijndael/rijndael-cpplib.tar.gz *
* *
* Dynamic tables generation is based on the Brian Gladman work: *
* http://fp.gladman.plus.com/cryptography_technology/rijndael *
**************************************************************************/
#include "rar.hpp"
const int uKeyLenInBytes=16, m_uRounds=10;
static byte S[256],S5[256],rcon[30];
static byte T1[256][4],T2[256][4],T3[256][4],T4[256][4];
static byte T5[256][4],T6[256][4],T7[256][4],T8[256][4];
static byte U1[256][4],U2[256][4],U3[256][4],U4[256][4];
inline void Xor128(byte *dest,const byte *arg1,const byte *arg2)
{
#if defined(PRESENT_INT32) && defined(ALLOW_NOT_ALIGNED_INT)
((uint32*)dest)[0]=((uint32*)arg1)[0]^((uint32*)arg2)[0];
((uint32*)dest)[1]=((uint32*)arg1)[1]^((uint32*)arg2)[1];
((uint32*)dest)[2]=((uint32*)arg1)[2]^((uint32*)arg2)[2];
((uint32*)dest)[3]=((uint32*)arg1)[3]^((uint32*)arg2)[3];
#else
for (int I=0;I<16;I++)
dest[I]=arg1[I]^arg2[I];
#endif
}
inline void Xor128(byte *dest,const byte *arg1,const byte *arg2,
const byte *arg3,const byte *arg4)
{
#if defined(PRESENT_INT32) && defined(ALLOW_NOT_ALIGNED_INT)
(*(uint32*)dest)=(*(uint32*)arg1)^(*(uint32*)arg2)^(*(uint32*)arg3)^(*(uint32*)arg4);
#else
for (int I=0;I<4;I++)
dest[I]=arg1[I]^arg2[I]^arg3[I]^arg4[I];
#endif
}
inline void Copy128(byte *dest,const byte *src)
{
#if defined(PRESENT_INT32) && defined(ALLOW_NOT_ALIGNED_INT)
((uint32*)dest)[0]=((uint32*)src)[0];
((uint32*)dest)[1]=((uint32*)src)[1];
((uint32*)dest)[2]=((uint32*)src)[2];
((uint32*)dest)[3]=((uint32*)src)[3];
#else
for (int I=0;I<16;I++)
dest[I]=src[I];
#endif
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// API
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Rijndael::Rijndael()
{
if (S[0]==0)
GenerateTables();
}
void Rijndael::init(Direction dir,const byte * key,byte * initVector)
{
m_direction = dir;
byte keyMatrix[_MAX_KEY_COLUMNS][4];
for(uint i = 0;i < uKeyLenInBytes;i++)
keyMatrix[i >> 2][i & 3] = key[i];
for(int i = 0;i < MAX_IV_SIZE;i++)
m_initVector[i] = initVector[i];
keySched(keyMatrix);
if(m_direction == Decrypt)
keyEncToDec();
}
size_t Rijndael::blockDecrypt(const byte *input, size_t inputLen, byte *outBuffer)
{
if (input == 0 || inputLen <= 0)
return 0;
byte block[16], iv[4][4];
memcpy(iv,m_initVector,16);
size_t numBlocks=inputLen/16;
for (size_t i = numBlocks; i > 0; i--)
{
decrypt(input, block);
Xor128(block,block,(byte*)iv);
#if STRICT_ALIGN
memcpy(iv, input, 16);
memcpy(outBuf, block, 16);
#else
Copy128((byte*)iv,input);
Copy128(outBuffer,block);
#endif
input += 16;
outBuffer += 16;
}
memcpy(m_initVector,iv,16);
return 16*numBlocks;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// ALGORITHM
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void Rijndael::keySched(byte key[_MAX_KEY_COLUMNS][4])
{
int j,rconpointer = 0;
// Calculate the necessary round keys
// The number of calculations depends on keyBits and blockBits
int uKeyColumns = m_uRounds - 6;
byte tempKey[_MAX_KEY_COLUMNS][4];
// Copy the input key to the temporary key matrix
memcpy(tempKey,key,sizeof(tempKey));
int r = 0;
int t = 0;
// copy values into round key array
for(j = 0;(j < uKeyColumns) && (r <= m_uRounds); )
{
for(;(j < uKeyColumns) && (t < 4); j++, t++)
for (int k=0;k<4;k++)
m_expandedKey[r][t][k]=tempKey[j][k];
if(t == 4)
{
r++;
t = 0;
}
}
while(r <= m_uRounds)
{
tempKey[0][0] ^= S[tempKey[uKeyColumns-1][1]];
tempKey[0][1] ^= S[tempKey[uKeyColumns-1][2]];
tempKey[0][2] ^= S[tempKey[uKeyColumns-1][3]];
tempKey[0][3] ^= S[tempKey[uKeyColumns-1][0]];
tempKey[0][0] ^= rcon[rconpointer++];
if (uKeyColumns != 8)
for(j = 1; j < uKeyColumns; j++)
for (int k=0;k<4;k++)
tempKey[j][k] ^= tempKey[j-1][k];
else
{
for(j = 1; j < uKeyColumns/2; j++)
for (int k=0;k<4;k++)
tempKey[j][k] ^= tempKey[j-1][k];
tempKey[uKeyColumns/2][0] ^= S[tempKey[uKeyColumns/2 - 1][0]];
tempKey[uKeyColumns/2][1] ^= S[tempKey[uKeyColumns/2 - 1][1]];
tempKey[uKeyColumns/2][2] ^= S[tempKey[uKeyColumns/2 - 1][2]];
tempKey[uKeyColumns/2][3] ^= S[tempKey[uKeyColumns/2 - 1][3]];
for(j = uKeyColumns/2 + 1; j < uKeyColumns; j++)
for (int k=0;k<4;k++)
tempKey[j][k] ^= tempKey[j-1][k];
}
for(j = 0; (j < uKeyColumns) && (r <= m_uRounds); )
{
for(; (j < uKeyColumns) && (t < 4); j++, t++)
for (int k=0;k<4;k++)
m_expandedKey[r][t][k] = tempKey[j][k];
if(t == 4)
{
r++;
t = 0;
}
}
}
}
void Rijndael::keyEncToDec()
{
for(int r = 1; r < m_uRounds; r++)
{
byte n_expandedKey[4][4];
for (int i=0;i<4;i++)
for (int j=0;j<4;j++)
{
byte *w=m_expandedKey[r][j];
n_expandedKey[j][i]=U1[w[0]][i]^U2[w[1]][i]^U3[w[2]][i]^U4[w[3]][i];
}
memcpy(m_expandedKey[r],n_expandedKey,sizeof(m_expandedKey[0]));
}
}
void Rijndael::decrypt(const byte a[16], byte b[16])
{
int r;
byte temp[4][4];
Xor128((byte*)temp,(byte*)a,(byte*)m_expandedKey[m_uRounds]);
Xor128(b, T5[temp[0][0]],T6[temp[3][1]],T7[temp[2][2]],T8[temp[1][3]]);
Xor128(b+4, T5[temp[1][0]],T6[temp[0][1]],T7[temp[3][2]],T8[temp[2][3]]);
Xor128(b+8, T5[temp[2][0]],T6[temp[1][1]],T7[temp[0][2]],T8[temp[3][3]]);
Xor128(b+12,T5[temp[3][0]],T6[temp[2][1]],T7[temp[1][2]],T8[temp[0][3]]);
for(r = m_uRounds-1; r > 1; r--)
{
Xor128((byte*)temp,(byte*)b,(byte*)m_expandedKey[r]);
Xor128(b, T5[temp[0][0]],T6[temp[3][1]],T7[temp[2][2]],T8[temp[1][3]]);
Xor128(b+4, T5[temp[1][0]],T6[temp[0][1]],T7[temp[3][2]],T8[temp[2][3]]);
Xor128(b+8, T5[temp[2][0]],T6[temp[1][1]],T7[temp[0][2]],T8[temp[3][3]]);
Xor128(b+12,T5[temp[3][0]],T6[temp[2][1]],T7[temp[1][2]],T8[temp[0][3]]);
}
Xor128((byte*)temp,(byte*)b,(byte*)m_expandedKey[1]);
b[ 0] = S5[temp[0][0]];
b[ 1] = S5[temp[3][1]];
b[ 2] = S5[temp[2][2]];
b[ 3] = S5[temp[1][3]];
b[ 4] = S5[temp[1][0]];
b[ 5] = S5[temp[0][1]];
b[ 6] = S5[temp[3][2]];
b[ 7] = S5[temp[2][3]];
b[ 8] = S5[temp[2][0]];
b[ 9] = S5[temp[1][1]];
b[10] = S5[temp[0][2]];
b[11] = S5[temp[3][3]];
b[12] = S5[temp[3][0]];
b[13] = S5[temp[2][1]];
b[14] = S5[temp[1][2]];
b[15] = S5[temp[0][3]];
Xor128((byte*)b,(byte*)b,(byte*)m_expandedKey[0]);
}
#define ff_poly 0x011b
#define ff_hi 0x80
#define FFinv(x) ((x) ? pow[255 - log[x]]: 0)
#define FFmul02(x) (x ? pow[log[x] + 0x19] : 0)
#define FFmul03(x) (x ? pow[log[x] + 0x01] : 0)
#define FFmul09(x) (x ? pow[log[x] + 0xc7] : 0)
#define FFmul0b(x) (x ? pow[log[x] + 0x68] : 0)
#define FFmul0d(x) (x ? pow[log[x] + 0xee] : 0)
#define FFmul0e(x) (x ? pow[log[x] + 0xdf] : 0)
#define fwd_affine(x) \
(w = (uint)x, w ^= (w<<1)^(w<<2)^(w<<3)^(w<<4), (byte)(0x63^(w^(w>>8))))
#define inv_affine(x) \
(w = (uint)x, w = (w<<1)^(w<<3)^(w<<6), (byte)(0x05^(w^(w>>8))))
void Rijndael::GenerateTables()
{
unsigned char pow[512],log[256];
int i = 0, w = 1;
do
{
pow[i] = (byte)w;
pow[i + 255] = (byte)w;
log[w] = (byte)i++;
w ^= (w << 1) ^ (w & ff_hi ? ff_poly : 0);
} while (w != 1);
for (int i = 0,w = 1; i < sizeof(rcon)/sizeof(rcon[0]); i++)
{
rcon[i] = w;
w = (w << 1) ^ (w & ff_hi ? ff_poly : 0);
}
for(int i = 0; i < 256; ++i)
{
unsigned char b=S[i]=fwd_affine(FFinv((byte)i));
T1[i][1]=T1[i][2]=T2[i][2]=T2[i][3]=T3[i][0]=T3[i][3]=T4[i][0]=T4[i][1]=b;
T1[i][0]=T2[i][1]=T3[i][2]=T4[i][3]=FFmul02(b);
T1[i][3]=T2[i][0]=T3[i][1]=T4[i][2]=FFmul03(b);
S5[i] = b = FFinv(inv_affine((byte)i));
U1[b][3]=U2[b][0]=U3[b][1]=U4[b][2]=T5[i][3]=T6[i][0]=T7[i][1]=T8[i][2]=FFmul0b(b);
U1[b][1]=U2[b][2]=U3[b][3]=U4[b][0]=T5[i][1]=T6[i][2]=T7[i][3]=T8[i][0]=FFmul09(b);
U1[b][2]=U2[b][3]=U3[b][0]=U4[b][1]=T5[i][2]=T6[i][3]=T7[i][0]=T8[i][1]=FFmul0d(b);
U1[b][0]=U2[b][1]=U3[b][2]=U4[b][3]=T5[i][0]=T6[i][1]=T7[i][2]=T8[i][3]=FFmul0e(b);
}
}

37
libunrar/rijndael.hpp Normal file
View File

@ -0,0 +1,37 @@
#ifndef _RIJNDAEL_H_
#define _RIJNDAEL_H_
/**************************************************************************
* This code is based on Szymon Stefanek AES implementation: *
* http://www.esat.kuleuven.ac.be/~rijmen/rijndael/rijndael-cpplib.tar.gz *
* *
* Dynamic tables generation is based on the Brian Gladman's work: *
* http://fp.gladman.plus.com/cryptography_technology/rijndael *
**************************************************************************/
#define _MAX_KEY_COLUMNS (256/32)
#define _MAX_ROUNDS 14
#define MAX_IV_SIZE 16
class Rijndael
{
public:
enum Direction { Encrypt , Decrypt };
private:
void keySched(byte key[_MAX_KEY_COLUMNS][4]);
void keyEncToDec();
void encrypt(const byte a[16], byte b[16]);
void decrypt(const byte a[16], byte b[16]);
void GenerateTables();
Direction m_direction;
byte m_initVector[MAX_IV_SIZE];
byte m_expandedKey[_MAX_ROUNDS+1][4][4];
public:
Rijndael();
void init(Direction dir,const byte *key,byte *initVector);
size_t blockEncrypt(const byte *input, size_t inputLen, byte *outBuffer);
size_t blockDecrypt(const byte *input, size_t inputLen, byte *outBuffer);
};
#endif // _RIJNDAEL_H_

143
libunrar/rs.cpp Normal file
View File

@ -0,0 +1,143 @@
#include "rar.hpp"
#define Clean(D,S) {for (int I=0;I<(S);I++) (D)[I]=0;}
RSCoder::RSCoder(int ParSize)
{
RSCoder::ParSize=ParSize;
FirstBlockDone=false;
gfInit();
pnInit();
}
void RSCoder::gfInit()
{
for (int I=0,J=1;I<MAXPAR;I++)
{
gfLog[J]=I;
gfExp[I]=J;
if ((J<<=1)&256)
J^=285;
}
for (int I=MAXPAR;I<MAXPOL;I++)
gfExp[I]=gfExp[I-MAXPAR];
}
inline int RSCoder::gfMult(int a,int b)
{
return(a==0 || b == 0 ? 0:gfExp[gfLog[a]+gfLog[b]]);
}
void RSCoder::pnInit()
{
int p1[MAXPAR+1],p2[MAXPAR+1];
Clean(p2,ParSize);
p2[0]=1;
for (int I=1;I<=ParSize;I++)
{
Clean(p1,ParSize);
p1[0]=gfExp[I];
p1[1]=1;
pnMult(p1,p2,GXPol);
for (int J=0;J<ParSize;J++)
p2[J]=GXPol[J];
}
}
void RSCoder::pnMult(int *p1,int *p2,int *r)
{
Clean(r,ParSize);
for (int I=0;I<ParSize;I++)
if (p1[I]!=0)
for(int J=0;J<ParSize-I;J++)
r[I+J]^=gfMult(p1[I],p2[J]);
}
void RSCoder::Encode(byte *Data,int DataSize,byte *DestData)
{
int ShiftReg[MAXPAR+1];
Clean(ShiftReg,ParSize+1);
for (int I=0;I<DataSize;I++)
{
int D=Data[I]^ShiftReg[ParSize-1];
for (int J=ParSize-1;J>0;J--)
ShiftReg[J]=ShiftReg[J-1]^gfMult(GXPol[J],D);
ShiftReg[0]=gfMult(GXPol[0],D);
}
for (int I=0;I<ParSize;I++)
DestData[I]=ShiftReg[ParSize-I-1];
}
bool RSCoder::Decode(byte *Data,int DataSize,int *EraLoc,int EraSize)
{
int SynData[MAXPOL];
bool AllZeroes=true;
for (int I=0;I<ParSize;I++)
{
int Sum=Data[0],J=1,Exp=gfExp[I+1];
for (;J+8<=DataSize;J+=8)
{
Sum=Data[J]^gfMult(Exp,Sum);
Sum=Data[J+1]^gfMult(Exp,Sum);
Sum=Data[J+2]^gfMult(Exp,Sum);
Sum=Data[J+3]^gfMult(Exp,Sum);
Sum=Data[J+4]^gfMult(Exp,Sum);
Sum=Data[J+5]^gfMult(Exp,Sum);
Sum=Data[J+6]^gfMult(Exp,Sum);
Sum=Data[J+7]^gfMult(Exp,Sum);
}
for (;J<DataSize;J++)
Sum=Data[J]^gfMult(Exp,Sum);
if ((SynData[I]=Sum)!=0)
AllZeroes=false;
}
if (AllZeroes)
return(true);
if (!FirstBlockDone)
{
FirstBlockDone=true;
Clean(PolB,ParSize+1);
PolB[0]=1;
for (int EraPos=0;EraPos<EraSize;EraPos++)
for (int I=ParSize,M=gfExp[DataSize-EraLoc[EraPos]-1];I>0;I--)
PolB[I]^=gfMult(M,PolB[I-1]);
ErrCount=0;
for (int Root=MAXPAR-DataSize;Root<MAXPAR+1;Root++)
{
int Sum=0;
for (int B=0;B<ParSize+1;B++)
Sum^=gfMult(gfExp[(B*Root)%MAXPAR],PolB[B]);
if (Sum==0)
{
Dn[ErrCount]=0;
for (int I=1;I<ParSize+1;I+=2)
Dn[ErrCount]^= gfMult(PolB[I],gfExp[Root*(I-1)%MAXPAR]);
ErrorLocs[ErrCount++]=MAXPAR-Root;
}
}
}
int PolD[MAXPOL];
pnMult(PolB,SynData,PolD);
if ((ErrCount<=ParSize) && ErrCount>0)
for (int I=0;I<ErrCount;I++)
{
int Loc=ErrorLocs[I],DLoc=MAXPAR-Loc,N=0;
for (int J=0;J<ParSize;J++)
N^=gfMult(PolD[J],gfExp[DLoc*J%MAXPAR]);
int DataPos=DataSize-Loc-1;
if (DataPos>=0 && DataPos<DataSize)
Data[DataPos]^=gfMult(N,gfExp[MAXPAR-gfLog[Dn[I]]]);
}
return(ErrCount<=ParSize);
}

Some files were not shown because too many files have changed in this diff Show More