├── DynamicPatchManager.h ├── DynamicPatchManager.m ├── Loader ├── JPLoader.h ├── JPLoader.m └── libs │ ├── RSAUtil.h │ ├── RSAUtil.m │ ├── ZipArchive.h │ ├── ZipArchive.m │ └── minizip │ ├── crypt.h │ ├── ioapi.c │ ├── ioapi.h │ ├── mztools.c │ ├── mztools.h │ ├── unzip.c │ ├── unzip.h │ ├── zip.c │ └── zip.h ├── NSData+Encryption.h ├── NSData+Encryption.m └── README.md /DynamicPatchManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // DynamicPatchManager.h 3 | // 4 | // 5 | // Created by KYao on 16/1/28. 6 | // Copyright © 2016年 XXXX. All rights reserved. 7 | // 8 | 9 | 10 | typedef void (^DynamicPatchReturnBlock)(NSError *error, NSDictionary *dynamicPatchConfiguration); 11 | 12 | typedef NS_ENUM(NSUInteger, DynamicPatchErrorCode) { 13 | 14 | DynamicPatch_ScriptCrash = 10000, 15 | DynamicPatch_ScriptNonExistent, 16 | DynamicPatch_ScriptVerifyError, 17 | DynamicPatch_ScriptRepeatRequest, 18 | }; 19 | 20 | 21 | @interface DynamicPatchManager : NSObject 22 | 23 | + (instancetype)sharedManager; 24 | 25 | /** 26 | * 返回当前脚本 27 | * 28 | * @return <#return value description#> 29 | */ 30 | - (NSString *)decryptPatchScript; 31 | 32 | 33 | /** 34 | * 执行本地MainBundle中的脚本 35 | * 36 | * @param name <#name description#> 37 | * @param type <#type description#> 38 | */ 39 | - (void)evaluateScriptInMainBundleForName:(NSString *)name type:(NSString *)type; 40 | 41 | 42 | /** 43 | * 执行已经请求的最新脚本,Block返回脚本信息 44 | * 45 | * @param completeBlock <#completeBlock description#> 46 | */ 47 | - (void)excutePatchScript:(DynamicPatchReturnBlock)completeBlock; 48 | 49 | 50 | /** 51 | * 请求最新脚本,Block返回脚本信息 52 | * 53 | * @param completeBlock <#completeBlock description#> 54 | */ 55 | - (void)requestPatchScriptWithCompleteBlock:(DynamicPatchReturnBlock)completeBlock; 56 | 57 | 58 | /** 59 | * 请求最新脚本并执行, Block返回脚本信息 (这个只是合并上面2个接口) 60 | * 61 | * @param completeBlock <#completeBlock description#> 62 | */ 63 | - (void)requestPatchScriptAndRunWithCompleteBlock:(DynamicPatchReturnBlock)completeBlock; 64 | 65 | 66 | 67 | @end 68 | -------------------------------------------------------------------------------- /DynamicPatchManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // DynamicPatchManager.m 3 | // 4 | // 5 | // Created by KYao on 16/1/28. 6 | // Copyright © 2016年 XXXX. All rights reserved. 7 | // 8 | 9 | #import "DynamicPatchManager.h" 10 | #import 11 | #import "NSData+Encryption.h" 12 | #import "JPLoader.h" 13 | 14 | static NSString *AES256Key = @"KDYNAMICPATCHxxxxx"; 15 | 16 | 17 | #define APP_DYNAMIC_PATCH_CLEANUP_KEY @"CleanupKey" 18 | #define APP_DYNAMIC_PATCH_CONFIGURATION_FILE_NAME @"ConfigurationFileName.dat" 19 | #define APP_DYNAMIC_PATCH_CURRENT_PATCH_MD5 @"MD5Code" 20 | #define APP_DYNAMIC_PATCH_CURRENT_VERSION @"Version" 21 | #define APP_DYNAMIC_PATCH_SCRIPT_DIRECTORY @"ScriptDirectory" 22 | 23 | 24 | #define DISPATCH_SEMAPHORE_WAIT(sema) dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); 25 | #define DISPATCH_SEMAPHORE_SIGNAL(sema) dispatch_semaphore_signal(sema); 26 | 27 | 28 | static NSMutableDictionary *dynamicPatchConfiguration = nil; 29 | static NSUncaughtExceptionHandler *originalExceptionHandler = NULL; 30 | static NSString *currentPatchScript = @""; 31 | 32 | @interface DynamicPatchManager () 33 | 34 | + (void)synchronizeConfiguration; 35 | 36 | @property (nonatomic,strong)dispatch_semaphore_t configurationSemaphore; 37 | 38 | @property (nonatomic,assign)NSTimeInterval requestPatchScriptTime; 39 | 40 | @property (nonatomic,copy) NSString *serverUrlString; 41 | @property (nonatomic,copy) NSString *pwd; 42 | 43 | @end 44 | 45 | static void hotFixExceptionHandler(NSException *exception) 46 | { 47 | [exception.callStackSymbols enumerateObjectsUsingBlock:^(NSString * _Nonnull lib, NSUInteger idx, BOOL * _Nonnull stop) { 48 | 49 | if ([lib rangeOfString:@"JPEngine"].length != 0) { 50 | 51 | [dynamicPatchConfiguration setObject:@"YES" forKey:APP_DYNAMIC_PATCH_CLEANUP_KEY]; 52 | [dynamicPatchConfiguration setObject:[currentPatchScript MD5String] forKey:APP_DYNAMIC_PATCH_CURRENT_PATCH_MD5]; 53 | [DynamicPatchManager synchronizeConfiguration]; 54 | 55 | *stop = YES; 56 | } 57 | 58 | }]; 59 | 60 | if (originalExceptionHandler) { 61 | originalExceptionHandler(exception); 62 | } 63 | } 64 | 65 | @implementation DynamicPatchManager 66 | 67 | + (void)load 68 | { 69 | } 70 | 71 | + (instancetype)sharedManager 72 | { 73 | //Singleton instance 74 | static DynamicPatchManager *dynamicPatchManager; 75 | static dispatch_once_t onceToken; 76 | dispatch_once(&onceToken, ^{ 77 | 78 | dynamicPatchManager = [[self alloc] init]; 79 | }); 80 | 81 | return dynamicPatchManager; 82 | } 83 | 84 | - (instancetype)init 85 | { 86 | if ((self = [super init])) { 87 | 88 | _configurationSemaphore = dispatch_semaphore_create(1); 89 | 90 | dynamicPatchConfiguration = [NSMutableDictionary dictionaryWithContentsOfFile:[[self class] dynamicPatchConfigurationPath]]; 91 | 92 | if (dynamicPatchConfiguration == nil) { 93 | dynamicPatchConfiguration = [NSMutableDictionary dictionary]; 94 | } 95 | 96 | originalExceptionHandler = NSGetUncaughtExceptionHandler(); 97 | NSSetUncaughtExceptionHandler(&hotFixExceptionHandler); 98 | 99 | } 100 | return self; 101 | } 102 | 103 | - (NSString *)decryptPatchScript 104 | { 105 | NSString *scriptDirectory = [[self class] fetchScriptDirectory]; 106 | NSString *scriptPath = [scriptDirectory stringByAppendingPathComponent:@"main.js"]; 107 | 108 | if ([[NSFileManager defaultManager] fileExistsAtPath:scriptPath]) { 109 | 110 | NSString *jsPatchScript = [self decryptPatchScriptWithPath:scriptPath]; 111 | if (jsPatchScript && ![[jsPatchScript MD5String] isEqualToString:[dynamicPatchConfiguration stringForKey:APP_DYNAMIC_PATCH_CURRENT_PATCH_MD5]]) { 112 | 113 | return jsPatchScript; 114 | } 115 | } 116 | 117 | return nil; 118 | } 119 | 120 | - (void)excutePatchScript:(DynamicPatchReturnBlock)completeBlock 121 | { 122 | //[self LogDynamicPatchConfiguration:dynamicPatchConfiguration]; 123 | void(^Block)(NSError *error) = ^(NSError *error) { 124 | 125 | if (completeBlock) { 126 | 127 | completeBlock(error, dynamicPatchConfiguration); 128 | } 129 | }; 130 | 131 | [self runPatchScriptWithConfiguration:dynamicPatchConfiguration completeBlock:Block]; 132 | } 133 | 134 | - (void)runPatchScriptWithConfiguration:(NSDictionary *)configuration completeBlock:(void(^)(NSError *error))completeBlock 135 | { 136 | NSError *error = nil; 137 | 138 | NSString *cleanUp = configuration[APP_DYNAMIC_PATCH_CLEANUP_KEY]; 139 | 140 | if ([cleanUp isEqualToString:@"YES"]) { 141 | 142 | error = [NSError errorWithDomain:@"" code:DynamicPatch_ScriptCrash userInfo:nil]; 143 | 144 | #ifdef DEBUG 145 | NSLog(@"Clean Up because of crash last time in js file."); 146 | #endif 147 | 148 | DISPATCH_SEMAPHORE_WAIT(_configurationSemaphore); 149 | [dynamicPatchConfiguration removeObjectForKey:APP_DYNAMIC_PATCH_CLEANUP_KEY]; 150 | [[self class] synchronizeConfiguration]; 151 | DISPATCH_SEMAPHORE_SIGNAL(_configurationSemaphore); 152 | 153 | 154 | } else { 155 | 156 | NSString *scriptDirectory = [[self class] fetchScriptDirectory]; 157 | NSString *scriptPath = [scriptDirectory stringByAppendingPathComponent:@"main.js"]; 158 | if ([[NSFileManager defaultManager] fileExistsAtPath:scriptPath]) { 159 | 160 | NSString *jsPatchScript = [self decryptPatchScriptWithPath:scriptPath]; 161 | if (jsPatchScript && [jsPatchScript isKindOfClass:[NSString class]] && ![[jsPatchScript MD5String] isEqualToString:[dynamicPatchConfiguration stringForKey:APP_DYNAMIC_PATCH_CURRENT_PATCH_MD5]]) { 162 | 163 | currentPatchScript = jsPatchScript; 164 | [self startEvaluateScript:jsPatchScript]; 165 | 166 | } else { 167 | 168 | error = [NSError errorWithDomain:@"" code:DynamicPatch_ScriptVerifyError userInfo:nil]; 169 | } 170 | 171 | } else { 172 | 173 | error = [NSError errorWithDomain:@"" code:DynamicPatch_ScriptNonExistent userInfo:nil]; 174 | } 175 | 176 | } 177 | 178 | if (completeBlock) completeBlock(error); 179 | 180 | 181 | } 182 | 183 | - (void)startEvaluateScript:(NSString *)jsPatchScript 184 | { 185 | dispatch_async(dispatch_get_main_queue(), ^ { 186 | 187 | [JPEngine startEngine]; 188 | [JPEngine addExtensions:@[@"JPLoaderInclude"]]; 189 | [JPEngine evaluateScript:jsPatchScript]; 190 | }); 191 | } 192 | 193 | -(void)evaluateScriptInMainBundleForName:(NSString *)name type:(NSString *)type 194 | { 195 | NSData *data = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:name ofType:type]]; 196 | if (data && [data length] > 0) { 197 | 198 | NSString *jsPatchScript = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 199 | if (jsPatchScript && [jsPatchScript isKindOfClass:[NSString class]] && [jsPatchScript length]) { 200 | 201 | currentPatchScript = jsPatchScript; 202 | [self startEvaluateScript:jsPatchScript]; 203 | 204 | } 205 | } 206 | 207 | } 208 | 209 | - (NSString *)decryptPatchScriptWithPath:(NSString *)path 210 | { 211 | NSData *data = [NSData dataWithContentsOfFile:path]; 212 | if (data) { 213 | 214 | NSData *decryptData = [data AES256ParmDecryptWithKey:AES256Key]; 215 | if (decryptData) { 216 | 217 | return [NSString stringWithCString:decryptData.bytes encoding:NSASCIIStringEncoding]; 218 | } 219 | } 220 | 221 | return nil; 222 | } 223 | 224 | - (void)requestPatchScriptAndRunWithCompleteBlock:(DynamicPatchReturnBlock)completeBlock 225 | { 226 | [self requestPatchScriptWithCompleteBlock:^(NSError *error, NSDictionary *dynamicPatchConfiguration) { 227 | 228 | if (!error) { 229 | 230 | [self excutePatchScript:^(NSError *error, NSDictionary *dynamicPatchConfiguration) { 231 | 232 | if (completeBlock) completeBlock(error, dynamicPatchConfiguration); 233 | 234 | }]; 235 | 236 | } else { 237 | 238 | if (completeBlock) completeBlock(error, dynamicPatchConfiguration); 239 | 240 | } 241 | }]; 242 | } 243 | 244 | - (void)requestPatchScriptWithCompleteBlock:(DynamicPatchReturnBlock)completeBlock 245 | { 246 | if ([[NSDate date] timeIntervalSince1970] - self.requestPatchScriptTime < 60 * 5) { 247 | 248 | if (completeBlock) { 249 | completeBlock([NSError errorWithDomain:@"" code:DynamicPatch_ScriptRepeatRequest userInfo:nil], dynamicPatchConfiguration); 250 | } 251 | return; 252 | } 253 | self.requestPatchScriptTime = [[NSDate date] timeIntervalSince1970]; 254 | 255 | NSInteger buildVersion = [CURRENT_APP_BUILDVERSION integerValue]; 256 | 257 | [self requestUpdateToVersion:buildVersion completeBlock:^(NSError *error) { 258 | 259 | if (!error) { 260 | 261 | DISPATCH_SEMAPHORE_WAIT(_configurationSemaphore); 262 | [dynamicPatchConfiguration setObject:@(buildVersion) forKey:APP_DYNAMIC_PATCH_CURRENT_VERSION]; 263 | [dynamicPatchConfiguration setObject:[[self class] fetchScriptDirectory] forKey:APP_DYNAMIC_PATCH_SCRIPT_DIRECTORY]; 264 | [[self class] synchronizeConfiguration]; 265 | DISPATCH_SEMAPHORE_SIGNAL(_configurationSemaphore); 266 | 267 | } 268 | if (completeBlock) completeBlock(error, dynamicPatchConfiguration); 269 | }]; 270 | 271 | } 272 | 273 | - (void)requestUpdateToVersion:(NSInteger)version completeBlock:(void(^)(NSError *error))completeBlock 274 | { 275 | [JPLoader updateToVersion:version callback:^(NSError *error) { 276 | 277 | if (completeBlock) { 278 | 279 | completeBlock(error); 280 | } 281 | 282 | }]; 283 | } 284 | 285 | + (void)synchronizeConfiguration 286 | { 287 | [dynamicPatchConfiguration writeToFile:[self dynamicPatchConfigurationPath] atomically:YES]; 288 | } 289 | 290 | + (NSString *)fetchScriptDirectory 291 | { 292 | NSString *appVersion = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"]; 293 | NSString *libraryDirectory = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) firstObject]; 294 | NSString *scriptDirectory = [libraryDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"JSPatch/%@/", appVersion]]; 295 | return scriptDirectory; 296 | } 297 | 298 | + (NSString *)dynamicPatchConfigurationPath 299 | { 300 | return [[self fetchScriptDirectory] stringByAppendingPathComponent:APP_DYNAMIC_PATCH_CONFIGURATION_FILE_NAME]; 301 | } 302 | 303 | @end 304 | -------------------------------------------------------------------------------- /Loader/JPLoader.h: -------------------------------------------------------------------------------- 1 | // 2 | // JSPatch.h 3 | // JSPatch 4 | // 5 | // Created by bang on 15/11/14. 6 | // Copyright (c) 2015 bang. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | const static NSString *rootUrl = @"http://7xr4jm.com1.z0.glb.clouddn.com"; 12 | 13 | static NSString *publicKey = @"-----BEGIN PUBLIC KEY-----\n \ 14 | MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDK3fvgvBuUtmnXaJBr4mxFByU3\n \ 15 | S5IQYKPMiRTPYpWDMjHRcyNRPQtVVSSjAL5iV7pO2SrX+IBrb15Sim/OaMecCJRU\n \ 16 | l8A5Q8VTuO/skzdRGqCg2GYi5rusuAZPQkGLk4y7miCKbG8nMW19C+5YeePmQ7e3\n \ 17 | QAmg8gpCtgN0jvwlBwIDAQAB\n \ 18 | -----END PUBLIC KEY-----"; 19 | 20 | typedef void (^JPUpdateCallback)(NSError *error); 21 | 22 | typedef enum { 23 | JPUpdateErrorUnzipFailed = -1001, 24 | JPUpdateErrorVerifyFailed = -1002, 25 | } JPUpdateError; 26 | 27 | @interface JPLoader : NSObject 28 | + (BOOL)run; 29 | + (void)updateToVersion:(NSInteger)version callback:(JPUpdateCallback)callback; 30 | + (void)runTestScriptInBundle; 31 | + (void)setLogger:(void(^)(NSString *log))logger; 32 | + (NSInteger)currentVersion; 33 | @end -------------------------------------------------------------------------------- /Loader/JPLoader.m: -------------------------------------------------------------------------------- 1 | // 2 | // JSPatch.m 3 | // JSPatch 4 | // 5 | // Created by bang on 15/11/14. 6 | // Copyright (c) 2015 bang. All rights reserved. 7 | // 8 | 9 | #import "JPLoader.h" 10 | #import "JPEngine.h" 11 | #import "ZipArchive.h" 12 | #import "RSAUtil.h" 13 | #import 14 | 15 | #define kJSPatchVersion(appVersion) [NSString stringWithFormat:@"JSPatchVersion_%@", appVersion] 16 | 17 | void (^JPLogger)(NSString *log); 18 | 19 | #pragma mark - Extension 20 | 21 | @interface JPLoaderInclude : JPExtension 22 | 23 | @end 24 | 25 | @implementation JPLoaderInclude 26 | 27 | + (void)main:(JSContext *)context 28 | { 29 | context[@"include"] = ^(NSString *filePath) { 30 | if (!filePath.length || [filePath rangeOfString:@".js"].location == NSNotFound) { 31 | return; 32 | } 33 | NSString *appVersion = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"]; 34 | NSString *libraryDirectory = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) firstObject]; 35 | NSString *scriptPath = [libraryDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"JSPatch/%@/%@", appVersion, filePath]]; 36 | if ([[NSFileManager defaultManager] fileExistsAtPath:scriptPath]) { 37 | [JPEngine startEngine]; 38 | [JPEngine evaluateScriptWithPath:scriptPath]; 39 | } 40 | }; 41 | } 42 | 43 | @end 44 | 45 | @interface JPLoaderTestInclude : JPExtension 46 | 47 | @end 48 | 49 | @implementation JPLoaderTestInclude 50 | 51 | + (void)main:(JSContext *)context 52 | { 53 | context[@"include"] = ^(NSString *filePath) { 54 | NSArray *component = [filePath componentsSeparatedByString:@"."]; 55 | if (component.count > 1) { 56 | NSString *testPath = [[NSBundle bundleForClass:[self class]] pathForResource:component[0] ofType:component[1]]; 57 | [JPEngine evaluateScriptWithPath:testPath]; 58 | } 59 | }; 60 | } 61 | 62 | @end 63 | 64 | #pragma mark - Loader 65 | 66 | @implementation JPLoader 67 | 68 | + (BOOL)run 69 | { 70 | if (JPLogger) JPLogger(@"JSPatch: runScript"); 71 | 72 | NSString *scriptDirectory = [self fetchScriptDirectory]; 73 | NSString *scriptPath = [scriptDirectory stringByAppendingPathComponent:@"main.js"]; 74 | 75 | if ([[NSFileManager defaultManager] fileExistsAtPath:scriptPath]) { 76 | [JPEngine startEngine]; 77 | [JPEngine addExtensions:@[@"JPLoaderInclude"]]; 78 | [JPEngine evaluateScriptWithPath:scriptPath]; 79 | if (JPLogger) JPLogger([NSString stringWithFormat:@"JSPatch: evaluated script %@", scriptPath]); 80 | return YES; 81 | } else { 82 | return NO; 83 | } 84 | } 85 | 86 | + (void)updateToVersion:(NSInteger)version callback:(JPUpdateCallback)callback 87 | { 88 | NSString *appVersion = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"]; 89 | 90 | if (JPLogger) JPLogger([NSString stringWithFormat:@"JSPatch: updateToVersion: %@", @(version)]); 91 | 92 | // create url request 93 | NSString *downloadKey = [NSString stringWithFormat:@"/%@_v%@.zip?v=%f", appVersion, @(version), [[NSDate date] timeIntervalSince1970]]; 94 | NSURL *downloadURL = [NSURL URLWithString:[rootUrl stringByAppendingString:downloadKey]]; 95 | NSURLRequest *request = [NSURLRequest requestWithURL:downloadURL cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:20.0]; 96 | 97 | if (JPLogger) JPLogger([NSString stringWithFormat:@"JSPatch: request file %@", downloadURL]); 98 | 99 | // create task 100 | NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { 101 | 102 | if (!error) { 103 | if (JPLogger) JPLogger([NSString stringWithFormat:@"JSPatch: request file success, data length:%@", @(data.length)]); 104 | 105 | // script directory 106 | NSString *scriptDirectory = [self fetchScriptDirectory]; 107 | 108 | // temporary files and directories 109 | NSString *downloadTmpPath = [NSString stringWithFormat:@"%@patch_%@_%@", NSTemporaryDirectory(), appVersion, @(version)]; 110 | NSString *unzipVerifyDirectory = [NSString stringWithFormat:@"%@patch_%@_%@_unzipTest/", NSTemporaryDirectory(), appVersion, @(version)]; 111 | NSString *unzipTmpDirectory = [NSString stringWithFormat:@"%@patch_%@_%@_unzip/", NSTemporaryDirectory(), appVersion, @(version)]; 112 | 113 | // save data 114 | [data writeToFile:downloadTmpPath atomically:YES]; 115 | 116 | // is the processing flow failed 117 | BOOL isFailed = NO; 118 | 119 | // 1. unzip encrypted md5 file and script file 120 | NSString *keyFilePath; 121 | NSString *scriptZipFilePath; 122 | ZipArchive *verifyZipArchive = [[ZipArchive alloc] init]; 123 | [verifyZipArchive UnzipOpenFile:downloadTmpPath]; 124 | BOOL verifyUnzipSucc = [verifyZipArchive UnzipFileTo:unzipVerifyDirectory overWrite:YES]; 125 | if (verifyUnzipSucc) { 126 | for (NSString *filePath in verifyZipArchive.unzippedFiles) { 127 | NSString *filename = [filePath lastPathComponent]; 128 | if ([filename isEqualToString:@"key"]) { 129 | // encrypted md5 file 130 | keyFilePath = filePath; 131 | } else if ([[filename pathExtension] isEqualToString:@"zip"]) { 132 | // script file 133 | scriptZipFilePath = filePath; 134 | } 135 | } 136 | } else { 137 | if (JPLogger) JPLogger(@"JSPatch: fail to unzip file"); 138 | isFailed = YES; 139 | 140 | if (callback) { 141 | callback([NSError errorWithDomain:@"org.jspatch" code:JPUpdateErrorUnzipFailed userInfo:nil]); 142 | } 143 | } 144 | 145 | // 2. decrypt and verify md5 file 146 | if (!isFailed) { 147 | NSData *md5Data = [RSAUtil decryptData:[NSData dataWithContentsOfFile:keyFilePath] publicKey:publicKey]; 148 | NSString *decryptMD5 = [[NSString alloc] initWithData:md5Data encoding:NSUTF8StringEncoding]; 149 | NSString *md5 = [self fileMD5:scriptZipFilePath]; 150 | if (![decryptMD5 isEqualToString:md5]) { 151 | if (JPLogger) JPLogger([NSString stringWithFormat:@"JSPatch: decompress error, md5 didn't match, decrypt:%@ md5:%@", decryptMD5, md5]); 152 | isFailed = YES; 153 | 154 | if (callback) { 155 | callback([NSError errorWithDomain:@"org.jspatch" code:JPUpdateErrorVerifyFailed userInfo:nil]); 156 | } 157 | } 158 | } 159 | 160 | // 3. unzip script file and save 161 | if (!isFailed) { 162 | ZipArchive *zipArchive = [[ZipArchive alloc] init]; 163 | [zipArchive UnzipOpenFile:scriptZipFilePath]; 164 | BOOL unzipSucc = [zipArchive UnzipFileTo:unzipTmpDirectory overWrite:YES]; 165 | if (unzipSucc) { 166 | for (NSString *filePath in zipArchive.unzippedFiles) { 167 | NSString *filename = [filePath lastPathComponent]; 168 | if ([[filename pathExtension] isEqualToString:@"js"]) { 169 | [[NSFileManager defaultManager] createDirectoryAtPath:scriptDirectory withIntermediateDirectories:YES attributes:nil error:nil]; 170 | NSString *newFilePath = [scriptDirectory stringByAppendingPathComponent:filename]; 171 | [[NSData dataWithContentsOfFile:filePath] writeToFile:newFilePath atomically:YES]; 172 | } 173 | } 174 | } 175 | else 176 | { 177 | if (JPLogger) JPLogger(@"JSPatch: fail to unzip script file"); 178 | isFailed = YES; 179 | 180 | if (callback) { 181 | callback([NSError errorWithDomain:@"org.jspatch" code:JPUpdateErrorUnzipFailed userInfo:nil]); 182 | } 183 | } 184 | } 185 | 186 | // success 187 | if (!isFailed) { 188 | if (JPLogger) JPLogger([NSString stringWithFormat:@"JSPatch: updateToVersion: %@ success", @(version)]); 189 | 190 | [[NSUserDefaults standardUserDefaults] setInteger:version forKey:kJSPatchVersion(appVersion)]; 191 | [[NSUserDefaults standardUserDefaults] synchronize]; 192 | 193 | if (callback) callback(nil); 194 | } 195 | 196 | // clear temporary files 197 | [[NSFileManager defaultManager] removeItemAtPath:downloadTmpPath error:nil]; 198 | [[NSFileManager defaultManager] removeItemAtPath:unzipVerifyDirectory error:nil]; 199 | [[NSFileManager defaultManager] removeItemAtPath:unzipTmpDirectory error:nil]; 200 | } else { 201 | if (JPLogger) JPLogger([NSString stringWithFormat:@"JSPatch: request error %@", error]); 202 | 203 | if (callback) callback(error); 204 | } 205 | }]; 206 | [task resume]; 207 | } 208 | 209 | + (void)runTestScriptInBundle 210 | { 211 | [JPEngine startEngine]; 212 | [JPEngine addExtensions:@[@"JPLoaderTestInclude"]]; 213 | 214 | NSString *path = [[NSBundle bundleForClass:[self class]] pathForResource:@"main" ofType:@"js"]; 215 | NSAssert(path, @"can't find main.js"); 216 | NSString *script = [[NSString alloc] initWithData:[[NSFileManager defaultManager] contentsAtPath:path] encoding:NSUTF8StringEncoding]; 217 | [JPEngine evaluateScript:script]; 218 | } 219 | 220 | + (void)setLogger:(void (^)(NSString *))logger { 221 | JPLogger = [logger copy]; 222 | } 223 | 224 | + (NSInteger)currentVersion 225 | { 226 | NSString *appVersion = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"]; 227 | return [[NSUserDefaults standardUserDefaults] integerForKey:kJSPatchVersion(appVersion)]; 228 | } 229 | 230 | + (NSString *)fetchScriptDirectory 231 | { 232 | NSString *appVersion = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"]; 233 | NSString *libraryDirectory = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) firstObject]; 234 | NSString *scriptDirectory = [libraryDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"JSPatch/%@/", appVersion]]; 235 | return scriptDirectory; 236 | } 237 | 238 | #pragma mark utils 239 | 240 | + (NSString *)fileMD5:(NSString *)filePath 241 | { 242 | NSFileHandle *handle = [NSFileHandle fileHandleForReadingAtPath:filePath]; 243 | if(!handle) 244 | { 245 | return nil; 246 | } 247 | 248 | CC_MD5_CTX md5; 249 | CC_MD5_Init(&md5); 250 | BOOL done = NO; 251 | while (!done) 252 | { 253 | NSData *fileData = [handle readDataOfLength:256]; 254 | CC_MD5_Update(&md5, [fileData bytes], (CC_LONG)[fileData length]); 255 | if([fileData length] == 0) 256 | done = YES; 257 | } 258 | 259 | unsigned char digest[CC_MD5_DIGEST_LENGTH]; 260 | CC_MD5_Final(digest, &md5); 261 | 262 | NSString *result = [NSString stringWithFormat:@"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", 263 | digest[0], digest[1], 264 | digest[2], digest[3], 265 | digest[4], digest[5], 266 | digest[6], digest[7], 267 | digest[8], digest[9], 268 | digest[10], digest[11], 269 | digest[12], digest[13], 270 | digest[14], digest[15]]; 271 | return result; 272 | } 273 | 274 | @end -------------------------------------------------------------------------------- /Loader/libs/RSAUtil.h: -------------------------------------------------------------------------------- 1 | /* 2 | @author: ideawu 3 | @link: https://github.com/ideawu/Objective-C-RSA 4 | */ 5 | 6 | #import 7 | 8 | @interface RSAUtil : NSObject 9 | 10 | // return base64 encoded string 11 | + (NSString *)encryptString:(NSString *)str publicKey:(NSString *)pubKey; 12 | // return raw data 13 | + (NSData *)encryptData:(NSData *)data publicKey:(NSString *)pubKey; 14 | 15 | // decrypt base64 encoded string, convert result to string(not base64 encoded) 16 | + (NSString *)decryptString:(NSString *)str publicKey:(NSString *)pubKey; 17 | + (NSData *)decryptData:(NSData *)data publicKey:(NSString *)pubKey; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /Loader/libs/RSAUtil.m: -------------------------------------------------------------------------------- 1 | /* 2 | @author: ideawu 3 | @link: https://github.com/ideawu/Objective-C-RSA 4 | */ 5 | 6 | #import "RSAUtil.h" 7 | #import 8 | 9 | @implementation RSAUtil 10 | 11 | 12 | static NSString *base64_encode_data(NSData *data){ 13 | data = [data base64EncodedDataWithOptions:0]; 14 | NSString *ret = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 15 | return ret; 16 | } 17 | 18 | static NSData *base64_decode(NSString *str){ 19 | NSData *data = [[NSData alloc] initWithBase64EncodedString:str options:NSDataBase64DecodingIgnoreUnknownCharacters]; 20 | return data; 21 | } 22 | 23 | + (NSData *)stripPublicKeyHeader:(NSData *)d_key{ 24 | // Skip ASN.1 public key header 25 | if (d_key == nil) return(nil); 26 | 27 | unsigned long len = [d_key length]; 28 | if (!len) return(nil); 29 | 30 | unsigned char *c_key = (unsigned char *)[d_key bytes]; 31 | unsigned int idx = 0; 32 | 33 | if (c_key[idx++] != 0x30) return(nil); 34 | 35 | if (c_key[idx] > 0x80) idx += c_key[idx] - 0x80 + 1; 36 | else idx++; 37 | 38 | // PKCS #1 rsaEncryption szOID_RSA_RSA 39 | static unsigned char seqiod[] = 40 | { 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 41 | 0x01, 0x05, 0x00 }; 42 | if (memcmp(&c_key[idx], seqiod, 15)) return(nil); 43 | 44 | idx += 15; 45 | 46 | if (c_key[idx++] != 0x03) return(nil); 47 | 48 | if (c_key[idx] > 0x80) idx += c_key[idx] - 0x80 + 1; 49 | else idx++; 50 | 51 | if (c_key[idx++] != '\0') return(nil); 52 | 53 | // Now make a new NSData from this buffer 54 | return([NSData dataWithBytes:&c_key[idx] length:len - idx]); 55 | } 56 | 57 | + (SecKeyRef)addPublicKey:(NSString *)key{ 58 | NSRange spos = [key rangeOfString:@"-----BEGIN PUBLIC KEY-----"]; 59 | NSRange epos = [key rangeOfString:@"-----END PUBLIC KEY-----"]; 60 | if(spos.location != NSNotFound && epos.location != NSNotFound){ 61 | NSUInteger s = spos.location + spos.length; 62 | NSUInteger e = epos.location; 63 | NSRange range = NSMakeRange(s, e-s); 64 | key = [key substringWithRange:range]; 65 | } 66 | key = [key stringByReplacingOccurrencesOfString:@"\r" withString:@""]; 67 | key = [key stringByReplacingOccurrencesOfString:@"\n" withString:@""]; 68 | key = [key stringByReplacingOccurrencesOfString:@"\t" withString:@""]; 69 | key = [key stringByReplacingOccurrencesOfString:@" " withString:@""]; 70 | 71 | // This will be base64 encoded, decode it. 72 | NSData *data = base64_decode(key); 73 | data = [RSAUtil stripPublicKeyHeader:data]; 74 | if(!data){ 75 | return nil; 76 | } 77 | 78 | NSString *tag = @"what_the_fuck_is_this"; 79 | NSData *d_tag = [NSData dataWithBytes:[tag UTF8String] length:[tag length]]; 80 | 81 | // Delete any old lingering key with the same tag 82 | NSMutableDictionary *publicKey = [[NSMutableDictionary alloc] init]; 83 | [publicKey setObject:(__bridge id) kSecClassKey forKey:(__bridge id)kSecClass]; 84 | [publicKey setObject:(__bridge id) kSecAttrKeyTypeRSA forKey:(__bridge id)kSecAttrKeyType]; 85 | [publicKey setObject:d_tag forKey:(__bridge id)kSecAttrApplicationTag]; 86 | SecItemDelete((__bridge CFDictionaryRef)publicKey); 87 | 88 | // Add persistent version of the key to system keychain 89 | [publicKey setObject:data forKey:(__bridge id)kSecValueData]; 90 | [publicKey setObject:(__bridge id) kSecAttrKeyClassPublic forKey:(__bridge id) 91 | kSecAttrKeyClass]; 92 | [publicKey setObject:[NSNumber numberWithBool:YES] forKey:(__bridge id) 93 | kSecReturnPersistentRef]; 94 | 95 | CFTypeRef persistKey = nil; 96 | OSStatus status = SecItemAdd((__bridge CFDictionaryRef)publicKey, &persistKey); 97 | if (persistKey != nil){ 98 | CFRelease(persistKey); 99 | } 100 | if ((status != noErr) && (status != errSecDuplicateItem)) { 101 | return nil; 102 | } 103 | 104 | [publicKey removeObjectForKey:(__bridge id)kSecValueData]; 105 | [publicKey removeObjectForKey:(__bridge id)kSecReturnPersistentRef]; 106 | [publicKey setObject:[NSNumber numberWithBool:YES] forKey:(__bridge id)kSecReturnRef]; 107 | [publicKey setObject:(__bridge id) kSecAttrKeyTypeRSA forKey:(__bridge id)kSecAttrKeyType]; 108 | 109 | // Now fetch the SecKeyRef version of the key 110 | SecKeyRef keyRef = nil; 111 | status = SecItemCopyMatching((__bridge CFDictionaryRef)publicKey, (CFTypeRef *)&keyRef); 112 | if(status != noErr){ 113 | return nil; 114 | } 115 | return keyRef; 116 | } 117 | 118 | + (NSString *)encryptString:(NSString *)str publicKey:(NSString *)pubKey{ 119 | NSData *data = [RSAUtil encryptData:[str dataUsingEncoding:NSUTF8StringEncoding] publicKey:pubKey]; 120 | NSString *ret = base64_encode_data(data); 121 | return ret; 122 | } 123 | 124 | + (NSData *)encryptData:(NSData *)data publicKey:(NSString *)pubKey{ 125 | if(!data || !pubKey){ 126 | return nil; 127 | } 128 | SecKeyRef keyRef = [RSAUtil addPublicKey:pubKey]; 129 | if(!keyRef){ 130 | return nil; 131 | } 132 | 133 | const uint8_t *srcbuf = (const uint8_t *)[data bytes]; 134 | size_t srclen = (size_t)data.length; 135 | 136 | size_t outlen = SecKeyGetBlockSize(keyRef) * sizeof(uint8_t); 137 | if(srclen > outlen - 11){ 138 | CFRelease(keyRef); 139 | return nil; 140 | } 141 | void *outbuf = malloc(outlen); 142 | 143 | OSStatus status = noErr; 144 | status = SecKeyEncrypt(keyRef, 145 | kSecPaddingPKCS1, 146 | srcbuf, 147 | srclen, 148 | outbuf, 149 | &outlen 150 | ); 151 | NSData *ret = nil; 152 | if (status != 0) { 153 | //NSLog(@"SecKeyEncrypt fail. Error Code: %ld", status); 154 | }else{ 155 | ret = [NSData dataWithBytes:outbuf length:outlen]; 156 | } 157 | free(outbuf); 158 | CFRelease(keyRef); 159 | return ret; 160 | } 161 | 162 | + (NSString *)decryptString:(NSString *)str publicKey:(NSString *)pubKey{ 163 | NSData *data = [[NSData alloc] initWithBase64EncodedString:str options:NSDataBase64DecodingIgnoreUnknownCharacters]; 164 | data = [RSAUtil decryptData:data publicKey:pubKey]; 165 | NSString *ret = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 166 | return ret; 167 | } 168 | 169 | + (NSData *)decryptData:(NSData *)data publicKey:(NSString *)pubKey{ 170 | if(!data || !pubKey){ 171 | return nil; 172 | } 173 | SecKeyRef keyRef = [RSAUtil addPublicKey:pubKey]; 174 | if(!keyRef){ 175 | return nil; 176 | } 177 | 178 | const uint8_t *srcbuf = (const uint8_t *)[data bytes]; 179 | size_t srclen = (size_t)data.length; 180 | 181 | size_t outlen = SecKeyGetBlockSize(keyRef) * sizeof(uint8_t); 182 | // if(srclen != outlen){ 183 | // //TODO currently we are able to decrypt only one block! 184 | // CFRelease(keyRef); 185 | // return nil; 186 | // } 187 | UInt8 *outbuf = malloc(outlen); 188 | 189 | //use kSecPaddingNone in decryption mode 190 | OSStatus status = noErr; 191 | status = SecKeyDecrypt(keyRef, 192 | kSecPaddingNone, 193 | srcbuf, 194 | srclen, 195 | outbuf, 196 | &outlen 197 | ); 198 | NSData *result = nil; 199 | if (status != 0) { 200 | //NSLog(@"SecKeyEncrypt fail. Error Code: %ld", status); 201 | }else{ 202 | //the actual decrypted data is in the middle, locate it! 203 | int idxFirstZero = -1; 204 | int idxNextZero = (int)outlen; 205 | for ( int i = 0; i < outlen; i++ ) { 206 | if ( outbuf[i] == 0 ) { 207 | if ( idxFirstZero < 0 ) { 208 | idxFirstZero = i; 209 | } else { 210 | idxNextZero = i; 211 | break; 212 | } 213 | } 214 | } 215 | 216 | result = [NSData dataWithBytes:&outbuf[idxFirstZero+1] length:idxNextZero-idxFirstZero-1]; 217 | } 218 | free(outbuf); 219 | CFRelease(keyRef); 220 | return result; 221 | } 222 | 223 | @end 224 | -------------------------------------------------------------------------------- /Loader/libs/ZipArchive.h: -------------------------------------------------------------------------------- 1 | /** 2 | // @header ZipArchive.h 3 | // 4 | // An objective C wrapper for minizip and libz for creating and exanding ZIP files. 5 | // 6 | // @author Created by aish on 08-9-11. 7 | // acsolu@gmail.com 8 | // @copyright Copyright 2008 Inc. All rights reserved. 9 | // 10 | */ 11 | 12 | #import 13 | 14 | 15 | /** 16 | a block that is called from UnzipFileTo:overwrite:withProgressBlock: where the percentage of 17 | files processed (as an integer from 0 to 100), the number of files processed so far and the 18 | total number of files in the archive is called after each file is processed. 19 | */ 20 | typedef void(^ZipArchiveProgressUpdateBlock)(int percentage, int filesProcessed, unsigned long numFiles); 21 | 22 | /** 23 | @protocol 24 | @discussion methods for a delegate to receive error notifications and control overwriting of files 25 | */ 26 | 27 | @protocol ZipArchiveDelegate 28 | @optional 29 | 30 | /** 31 | @brief Delegate method to be notified of errors 32 | 33 | ZipArchive calls this selector on the delegate when errors are encountered. 34 | 35 | @param msg a string describing the error. 36 | @result void 37 | */ 38 | 39 | -(void) ErrorMessage:(NSString*) msg; 40 | 41 | /** 42 | @brief Delegate method to determine if a file should be replaced 43 | 44 | When an zip file is being expanded and a file is about to be replaced, this selector 45 | is called on the delegate to notify that file is about to be replaced. The delegate method 46 | should return YES to overwrite the file, or NO to skip it. 47 | 48 | @param file - path to the file to be overwritten. 49 | @result a BOOL - YES to replace, NO to skip 50 | */ 51 | 52 | -(BOOL) OverWriteOperation:(NSString*) file; 53 | 54 | @end 55 | 56 | /** 57 | @class 58 | @brief An object that can create zip files and expand existing ones. 59 | This class provides methods to create a zip file (optionally with a password) and 60 | add files to that zip archive. 61 | 62 | It also provides methods to expand an existing archive file (optionally with a password), 63 | and extract the files. 64 | */ 65 | 66 | @interface ZipArchive : NSObject { 67 | @private 68 | void* _zipFile; 69 | void* _unzFile; 70 | 71 | unsigned long _numFiles; 72 | NSString* _password; 73 | __weak id _delegate; 74 | ZipArchiveProgressUpdateBlock _progressBlock; 75 | 76 | NSArray* _unzippedFiles; 77 | 78 | NSFileManager* _fileManager; 79 | NSStringEncoding _stringEncoding; 80 | } 81 | 82 | /** a delegate object conforming to ZipArchiveDelegate protocol */ 83 | @property (nonatomic, weak) id delegate; 84 | @property (nonatomic, readonly) unsigned long numFiles; 85 | @property (nonatomic, copy) ZipArchiveProgressUpdateBlock progressBlock; 86 | 87 | /** 88 | @brief String encoding to be used when interpreting file names in the zip file. 89 | */ 90 | @property (nonatomic, assign) NSStringEncoding stringEncoding; 91 | 92 | /** an array of files that were successfully expanded. Available after calling UnzipFileTo:overWrite: */ 93 | @property (nonatomic, readonly,strong) NSArray *unzippedFiles; 94 | 95 | -(id) initWithFileManager:(NSFileManager*) fileManager; 96 | 97 | -(BOOL) CreateZipFile2:(NSString*) zipFile; 98 | -(BOOL) CreateZipFile2:(NSString*) zipFile Password:(NSString*) password; 99 | -(BOOL) addFileToZip:(NSString*) file newname:(NSString*) newname; 100 | -(BOOL) CloseZipFile2; 101 | 102 | -(BOOL) UnzipOpenFile:(NSString*) zipFile; 103 | -(BOOL) UnzipOpenFile:(NSString*) zipFile Password:(NSString*) password; 104 | -(BOOL) UnzipFileTo:(NSString*) path overWrite:(BOOL) overwrite; 105 | -(BOOL) UnzipCloseFile; 106 | -(NSArray*) getZipFileContents; // list the contents of the zip archive. must be called after UnzipOpenFile 107 | 108 | @end 109 | -------------------------------------------------------------------------------- /Loader/libs/ZipArchive.m: -------------------------------------------------------------------------------- 1 | /** 2 | // ZipArchive.m 3 | // 4 | // 5 | // Created by aish on 08-9-11. 6 | // acsolu@gmail.com 7 | // Copyright 2008 Inc. All rights reserved. 8 | // 9 | */ 10 | 11 | #import "ZipArchive.h" 12 | #import "zlib.h" 13 | #import "zconf.h" 14 | #include "zip.h" 15 | #include "unzip.h" 16 | 17 | 18 | @interface NSFileManager(ZipArchive) 19 | - (NSDictionary *)_attributesOfItemAtPath:(NSString *)path followingSymLinks:(BOOL)followingSymLinks error:(NSError **)error; 20 | @end 21 | 22 | @interface ZipArchive () 23 | 24 | -(void) OutputErrorMessage:(NSString*) msg; 25 | -(BOOL) OverWrite:(NSString*) file; 26 | -(NSDate*) Date1980; 27 | 28 | @property (nonatomic,copy) NSString* password; 29 | @end 30 | 31 | 32 | 33 | @implementation ZipArchive 34 | @synthesize delegate = _delegate; 35 | @synthesize numFiles = _numFiles; 36 | @synthesize password = _password; 37 | @synthesize unzippedFiles = _unzippedFiles; 38 | @synthesize progressBlock = _progressBlock; 39 | @synthesize stringEncoding = _stringEncoding; 40 | 41 | -(id) init 42 | { 43 | return [self initWithFileManager:[NSFileManager defaultManager]]; 44 | } 45 | 46 | -(id) initWithFileManager:(NSFileManager*) fileManager 47 | { 48 | if( self=[super init] ) 49 | { 50 | _zipFile = NULL; 51 | _fileManager = fileManager; 52 | self.stringEncoding = NSUTF8StringEncoding; 53 | } 54 | return self; 55 | } 56 | 57 | -(void) dealloc 58 | { 59 | // close any open file operations 60 | [self CloseZipFile2]; 61 | [self UnzipCloseFile]; 62 | 63 | // release retained/copied properties. 64 | 65 | } 66 | 67 | /** 68 | * Create a new zip file at the specified path, ready for new files to be added. 69 | * 70 | * @param zipFile the path of the zip file to create 71 | * @returns BOOL YES on success 72 | */ 73 | 74 | -(BOOL) CreateZipFile2:(NSString*) zipFile 75 | { 76 | _zipFile = zipOpen( (const char*)[zipFile UTF8String], 0 ); 77 | if( !_zipFile ) 78 | return NO; 79 | return YES; 80 | } 81 | 82 | /** 83 | * Create a new zip file at the specified path, ready for new files to be added. 84 | * 85 | * @param zipFile the path of the zip file to create 86 | * @param password a password used to encrypt the zip file 87 | * @returns BOOL YES on success 88 | */ 89 | 90 | -(BOOL) CreateZipFile2:(NSString*) zipFile Password:(NSString*) password 91 | { 92 | self.password = password; 93 | return [self CreateZipFile2:zipFile]; 94 | } 95 | 96 | /** 97 | * add an existing file on disk to the zip archive, compressing it. 98 | * 99 | * @param file the path to the file to compress 100 | * @param newname the name of the file in the zip archive, ie: path relative to the zip archive root. 101 | * @returns BOOL YES on success 102 | */ 103 | 104 | -(BOOL) addFileToZip:(NSString*) file newname:(NSString*) newname; 105 | { 106 | if( !_zipFile ) 107 | return NO; 108 | // tm_zip filetime; 109 | 110 | zip_fileinfo zipInfo = {{0}}; 111 | 112 | NSDate* fileDate = nil; 113 | 114 | NSError* error = nil; 115 | NSDictionary* attr = [_fileManager _attributesOfItemAtPath:file followingSymLinks:YES error:&error]; 116 | if( attr ) 117 | fileDate = (NSDate*)[attr objectForKey:NSFileModificationDate]; 118 | 119 | if( fileDate == nil ) 120 | fileDate = [NSDate date]; 121 | 122 | 123 | NSCalendar *gregorianCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian]; 124 | NSDateComponents* components = [gregorianCalendar components:NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | 125 | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond fromDate:fileDate]; 126 | 127 | zipInfo.tmz_date.tm_sec = (uInt)components.second; 128 | zipInfo.tmz_date.tm_min = (uInt)components.minute; 129 | zipInfo.tmz_date.tm_hour = (uInt)components.hour; 130 | zipInfo.tmz_date.tm_mday = (uInt)components.day; 131 | zipInfo.tmz_date.tm_mon = (uInt)components.month; 132 | zipInfo.tmz_date.tm_year = (uInt)components.year; 133 | 134 | 135 | int ret ; 136 | NSData* data = nil; 137 | if( [_password length] == 0 ) 138 | { 139 | ret = zipOpenNewFileInZip( _zipFile, 140 | (const char*) [newname cStringUsingEncoding:self.stringEncoding], 141 | &zipInfo, 142 | NULL,0, 143 | NULL,0, 144 | NULL,//comment 145 | Z_DEFLATED, 146 | Z_DEFAULT_COMPRESSION ); 147 | } 148 | else 149 | { 150 | data = [ NSData dataWithContentsOfFile:file]; 151 | uLong crcValue = crc32( 0L,NULL, 0L ); 152 | crcValue = crc32( crcValue, (const Bytef*)[data bytes], (unsigned int)[data length] ); 153 | ret = zipOpenNewFileInZip3( _zipFile, 154 | (const char*) [newname cStringUsingEncoding:self.stringEncoding], 155 | &zipInfo, 156 | NULL,0, 157 | NULL,0, 158 | NULL,//comment 159 | Z_DEFLATED, 160 | Z_DEFAULT_COMPRESSION, 161 | 0, 162 | 15, 163 | 8, 164 | Z_DEFAULT_STRATEGY, 165 | [_password cStringUsingEncoding:NSASCIIStringEncoding], 166 | crcValue ); 167 | } 168 | if( ret!=Z_OK ) 169 | { 170 | return NO; 171 | } 172 | if( data==nil ) 173 | { 174 | data = [ NSData dataWithContentsOfFile:file]; 175 | } 176 | unsigned int dataLen = (unsigned int)[data length]; 177 | ret = zipWriteInFileInZip( _zipFile, (const void*)[data bytes], dataLen); 178 | if( ret!=Z_OK ) 179 | { 180 | return NO; 181 | } 182 | ret = zipCloseFileInZip( _zipFile ); 183 | if( ret!=Z_OK ) 184 | return NO; 185 | return YES; 186 | } 187 | 188 | /** 189 | * Close a zip file after creating and added files to it. 190 | * 191 | * @returns BOOL YES on success 192 | */ 193 | 194 | -(BOOL) CloseZipFile2 195 | { 196 | self.password = nil; 197 | if( _zipFile==NULL ) 198 | return NO; 199 | BOOL ret = zipClose( _zipFile,NULL )==Z_OK?YES:NO; 200 | _zipFile = NULL; 201 | return ret; 202 | } 203 | 204 | /** 205 | * open an existing zip file ready for expanding. 206 | * 207 | * @param zipFile the path to a zip file to be opened. 208 | * @returns BOOL YES on success 209 | */ 210 | 211 | -(BOOL) UnzipOpenFile:(NSString*) zipFile 212 | { 213 | // create an array to receive the list of unzipped files. 214 | _unzippedFiles = [[NSMutableArray alloc] initWithCapacity:1]; 215 | 216 | _unzFile = unzOpen( (const char*)[zipFile UTF8String] ); 217 | if( _unzFile ) 218 | { 219 | unz_global_info globalInfo = {0}; 220 | if( unzGetGlobalInfo(_unzFile, &globalInfo )==UNZ_OK ) 221 | { 222 | _numFiles = globalInfo.number_entry; 223 | NSLog(@"%lu entries in the zip file", globalInfo.number_entry); 224 | } 225 | } 226 | return _unzFile!=NULL; 227 | } 228 | 229 | /** 230 | * open an existing zip file with a password ready for expanding. 231 | * 232 | * @param zipFile the path to a zip file to be opened. 233 | * @param password the password to use decrpyting the file. 234 | * @returns BOOL YES on success 235 | */ 236 | 237 | -(BOOL) UnzipOpenFile:(NSString*) zipFile Password:(NSString*) password 238 | { 239 | self.password = password; 240 | return [self UnzipOpenFile:zipFile]; 241 | } 242 | 243 | /** 244 | * Expand all files in the zip archive into the specified directory. 245 | * 246 | * If a delegate has been set and responds to OverWriteOperation: it can 247 | * return YES to overwrite a file, or NO to skip that file. 248 | * 249 | * On completion, the property `unzippedFiles` will be an array populated 250 | * with the full paths of each file that was successfully expanded. 251 | * 252 | * @param path the directory where expanded files will be created 253 | * @param overwrite should existing files be overwritten 254 | * @returns BOOL YES on success 255 | */ 256 | 257 | -(BOOL) UnzipFileTo:(NSString*) path overWrite:(BOOL) overwrite 258 | { 259 | BOOL success = YES; 260 | int index = 0; 261 | int progress = -1; 262 | int ret = unzGoToFirstFile( _unzFile ); 263 | unsigned char buffer[4096] = {0}; 264 | if( ret!=UNZ_OK ) 265 | { 266 | [self OutputErrorMessage:@"Failed"]; 267 | } 268 | 269 | const char* password = [_password cStringUsingEncoding:NSASCIIStringEncoding]; 270 | 271 | do{ 272 | @autoreleasepool { 273 | if( [_password length]==0 ) 274 | ret = unzOpenCurrentFile( _unzFile ); 275 | else 276 | ret = unzOpenCurrentFilePassword( _unzFile, password ); 277 | if( ret!=UNZ_OK ) 278 | { 279 | [self OutputErrorMessage:@"Error occurs"]; 280 | success = NO; 281 | break; 282 | } 283 | // reading data and write to file 284 | int read ; 285 | unz_file_info fileInfo ={0}; 286 | ret = unzGetCurrentFileInfo(_unzFile, &fileInfo, NULL, 0, NULL, 0, NULL, 0); 287 | if( ret!=UNZ_OK ) 288 | { 289 | [self OutputErrorMessage:@"Error occurs while getting file info"]; 290 | success = NO; 291 | unzCloseCurrentFile( _unzFile ); 292 | break; 293 | } 294 | char* filename = (char*) malloc( fileInfo.size_filename +1 ); 295 | unzGetCurrentFileInfo(_unzFile, &fileInfo, filename, fileInfo.size_filename + 1, NULL, 0, NULL, 0); 296 | filename[fileInfo.size_filename] = '\0'; 297 | 298 | // check if it contains directory 299 | NSString * strPath = [NSString stringWithCString:filename encoding:self.stringEncoding]; 300 | BOOL isDirectory = NO; 301 | if( filename[fileInfo.size_filename-1]=='/' || filename[fileInfo.size_filename-1]=='\\') 302 | isDirectory = YES; 303 | free( filename ); 304 | if( [strPath rangeOfCharacterFromSet:[NSCharacterSet characterSetWithCharactersInString:@"/\\"]].location!=NSNotFound ) 305 | {// contains a path 306 | strPath = [strPath stringByReplacingOccurrencesOfString:@"\\" withString:@"/"]; 307 | } 308 | NSString* fullPath = [path stringByAppendingPathComponent:strPath]; 309 | 310 | if( isDirectory ) 311 | [_fileManager createDirectoryAtPath:fullPath withIntermediateDirectories:YES attributes:nil error:nil]; 312 | else 313 | [_fileManager createDirectoryAtPath:[fullPath stringByDeletingLastPathComponent] withIntermediateDirectories:YES attributes:nil error:nil]; 314 | 315 | FILE* fp = NULL; 316 | do 317 | { 318 | read = unzReadCurrentFile(_unzFile, buffer, 4096); 319 | if (read >= 0) 320 | { 321 | if (fp == NULL) { 322 | if( [_fileManager fileExistsAtPath:fullPath] && !isDirectory && !overwrite ) 323 | { 324 | if( ![self OverWrite:fullPath] ) 325 | { 326 | // don't process any more of the file, but continue 327 | break; 328 | } 329 | } 330 | if (!isDirectory) { 331 | fp = fopen( (const char*)[fullPath UTF8String], "wb"); 332 | if (fp == NULL) { 333 | [self OutputErrorMessage:@"Failed to open output file for writing"]; 334 | break; 335 | } 336 | } 337 | } 338 | fwrite(buffer, read, 1, fp ); 339 | } 340 | else // if (read < 0) 341 | { 342 | ret = read; // result will be an error code 343 | success = NO; 344 | [self OutputErrorMessage:@"Failed to read zip file"]; 345 | } 346 | } while (read > 0); 347 | 348 | if (fp) 349 | { 350 | fclose( fp ); 351 | 352 | // add the full path of this file to the output array 353 | [(NSMutableArray*)_unzippedFiles addObject:fullPath]; 354 | 355 | // set the orignal datetime property 356 | if( fileInfo.tmu_date.tm_year!=0 ) 357 | { 358 | NSDateComponents* components = [[NSDateComponents alloc] init]; 359 | components.second = fileInfo.tmu_date.tm_sec; 360 | components.minute = fileInfo.tmu_date.tm_min; 361 | components.hour = fileInfo.tmu_date.tm_hour; 362 | components.day = fileInfo.tmu_date.tm_mday; 363 | components.month = fileInfo.tmu_date.tm_mon; 364 | components.year = fileInfo.tmu_date.tm_year; 365 | 366 | NSCalendar *gregorianCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian]; 367 | NSDate* orgDate = [gregorianCalendar dateFromComponents:components]; 368 | 369 | NSDictionary* attr = [NSDictionary dictionaryWithObject:orgDate forKey:NSFileModificationDate]; //[_fileManager fileAttributesAtPath:fullPath traverseLink:YES]; 370 | if( attr ) 371 | { 372 | // [attr setValue:orgDate forKey:NSFileCreationDate]; 373 | if( ![_fileManager setAttributes:attr ofItemAtPath:fullPath error:nil] ) 374 | { 375 | // cann't set attributes 376 | NSLog(@"Failed to set attributes"); 377 | } 378 | 379 | } 380 | orgDate = nil; 381 | } 382 | 383 | } 384 | 385 | if (ret == UNZ_OK) { 386 | ret = unzCloseCurrentFile( _unzFile ); 387 | if (ret != UNZ_OK) { 388 | [self OutputErrorMessage:@"file was unzipped but failed crc check"]; 389 | success = NO; 390 | } 391 | } 392 | 393 | if (ret == UNZ_OK) { 394 | ret = unzGoToNextFile( _unzFile ); 395 | } 396 | 397 | if (_progressBlock && _numFiles) { 398 | index++; 399 | int p = index*100/_numFiles; 400 | progress = p; 401 | _progressBlock(progress, index, _numFiles); 402 | } 403 | } 404 | } while (ret==UNZ_OK && ret!=UNZ_END_OF_LIST_OF_FILE); 405 | return success; 406 | } 407 | 408 | /** 409 | * Close the zip file. 410 | * 411 | * @returns BOOL YES on success 412 | */ 413 | 414 | -(BOOL) UnzipCloseFile 415 | { 416 | self.password = nil; 417 | if( _unzFile ) { 418 | int err = unzClose( _unzFile ); 419 | _unzFile = nil; 420 | return err ==UNZ_OK; 421 | } 422 | return YES; 423 | } 424 | 425 | 426 | /** 427 | * Return a list of filenames that are in the zip archive. 428 | * No path information is available as this can be called before the zip is expanded. 429 | * 430 | * @returns NSArray list of filenames in the zip archive. 431 | */ 432 | 433 | -(NSArray*) getZipFileContents // list the contents of the zip archive. must be called after UnzipOpenFile 434 | { 435 | int ret = unzGoToFirstFile( _unzFile ); 436 | NSMutableArray * allFilenames = [NSMutableArray arrayWithCapacity:40]; 437 | 438 | if( ret!=UNZ_OK ) 439 | { 440 | [self OutputErrorMessage:@"Failed"]; 441 | } 442 | 443 | const char* password = [_password cStringUsingEncoding:NSASCIIStringEncoding]; 444 | 445 | do{ 446 | if( [_password length]==0 ) 447 | ret = unzOpenCurrentFile( _unzFile ); 448 | else 449 | ret = unzOpenCurrentFilePassword( _unzFile, password ); 450 | if( ret!=UNZ_OK ) 451 | { 452 | [self OutputErrorMessage:@"Error occured"]; 453 | break; 454 | } 455 | 456 | // reading data and write to file 457 | unz_file_info fileInfo ={0}; 458 | ret = unzGetCurrentFileInfo(_unzFile, &fileInfo, NULL, 0, NULL, 0, NULL, 0); 459 | if( ret!=UNZ_OK ) 460 | { 461 | [self OutputErrorMessage:@"Error occurs while getting file info"]; 462 | unzCloseCurrentFile( _unzFile ); 463 | break; 464 | } 465 | char* filename = (char*) malloc( fileInfo.size_filename +1 ); 466 | unzGetCurrentFileInfo(_unzFile, &fileInfo, filename, fileInfo.size_filename + 1, NULL, 0, NULL, 0); 467 | filename[fileInfo.size_filename] = '\0'; 468 | 469 | // check if it contains directory 470 | NSString * strPath = [NSString stringWithCString:filename encoding:NSASCIIStringEncoding]; 471 | free( filename ); 472 | if( [strPath rangeOfCharacterFromSet:[NSCharacterSet characterSetWithCharactersInString:@"/\\"]].location!=NSNotFound ) 473 | {// contains a path 474 | strPath = [strPath stringByReplacingOccurrencesOfString:@"\\" withString:@"/"]; 475 | } 476 | 477 | // Copy name to array 478 | [allFilenames addObject:strPath]; 479 | 480 | unzCloseCurrentFile( _unzFile ); 481 | ret = unzGoToNextFile( _unzFile ); 482 | } while( ret==UNZ_OK && UNZ_OK!=UNZ_END_OF_LIST_OF_FILE ); 483 | 484 | // return an immutable array. 485 | return [NSArray arrayWithArray:allFilenames]; 486 | } 487 | 488 | 489 | #pragma mark wrapper for delegate 490 | 491 | /** 492 | * send the ErrorMessage: to the delegate if it responds to it. 493 | */ 494 | -(void) OutputErrorMessage:(NSString*) msg 495 | { 496 | if( _delegate && [_delegate respondsToSelector:@selector(ErrorMessage:)] ) 497 | [_delegate ErrorMessage:msg]; 498 | } 499 | 500 | /** 501 | * send the OverWriteOperation: selector to the delegate if it responds to it, 502 | * returning the result, or YES by default. 503 | */ 504 | 505 | -(BOOL) OverWrite:(NSString*) file 506 | { 507 | if( _delegate && [_delegate respondsToSelector:@selector(OverWriteOperation:)] ) 508 | return [_delegate OverWriteOperation:file]; 509 | return YES; 510 | } 511 | 512 | #pragma mark get NSDate object for 1980-01-01 513 | -(NSDate*) Date1980 514 | { 515 | NSDateComponents *comps = [[NSDateComponents alloc] init]; 516 | [comps setDay:1]; 517 | [comps setMonth:1]; 518 | [comps setYear:1980]; 519 | NSCalendar *gregorian = [[NSCalendar alloc] 520 | initWithCalendarIdentifier:NSCalendarIdentifierGregorian]; 521 | NSDate *date = [gregorian dateFromComponents:comps]; 522 | 523 | return date; 524 | } 525 | 526 | 527 | @end 528 | 529 | 530 | @implementation NSFileManager(ZipArchive) 531 | 532 | - (NSDictionary *)_attributesOfItemAtPath:(NSString *)path followingSymLinks:(BOOL)followingSymLinks error:(NSError **)error 533 | { 534 | // call file manager default action, which is to not follow symlinks 535 | NSDictionary* results = [self attributesOfItemAtPath:path error:error]; 536 | if (followingSymLinks && results && (error ? *error == nil : YES)) { 537 | if ([[results fileType] isEqualToString:NSFileTypeSymbolicLink]) { 538 | // follow the symlink 539 | NSString* realPath = [self destinationOfSymbolicLinkAtPath:path error:error]; 540 | if (realPath && (error ? *error == nil : YES)) { 541 | return [self _attributesOfItemAtPath:realPath followingSymLinks:followingSymLinks error:error]; 542 | } else { 543 | // failure to resolve symlink should be an error returning nil and error will already be set. 544 | return nil; 545 | } 546 | } 547 | } 548 | return results; 549 | } 550 | 551 | @end 552 | 553 | -------------------------------------------------------------------------------- /Loader/libs/minizip/crypt.h: -------------------------------------------------------------------------------- 1 | /* crypt.h -- base code for crypt/uncrypt ZIPfile 2 | 3 | 4 | Version 1.01e, February 12th, 2005 5 | 6 | Copyright (C) 1998-2005 Gilles Vollant 7 | 8 | This code is a modified version of crypting code in Infozip distribution 9 | 10 | The encryption/decryption parts of this source code (as opposed to the 11 | non-echoing password parts) were originally written in Europe. The 12 | whole source package can be freely distributed, including from the USA. 13 | (Prior to January 2000, re-export from the US was a violation of US law.) 14 | 15 | This encryption code is a direct transcription of the algorithm from 16 | Roger Schlafly, described by Phil Katz in the file appnote.txt. This 17 | file (appnote.txt) is distributed with the PKZIP program (even in the 18 | version without encryption capabilities). 19 | 20 | If you don't need crypting in your application, just define symbols 21 | NOCRYPT and NOUNCRYPT. 22 | 23 | This code support the "Traditional PKWARE Encryption". 24 | 25 | The new AES encryption added on Zip format by Winzip (see the page 26 | http://www.winzip.com/aes_info.htm ) and PKWare PKZip 5.x Strong 27 | Encryption is not supported. 28 | */ 29 | 30 | #define CRC32(c, b) ((*(pcrc_32_tab+(((int)(c) ^ (b)) & 0xff))) ^ ((c) >> 8)) 31 | 32 | /*********************************************************************** 33 | * Return the next byte in the pseudo-random sequence 34 | */ 35 | static int decrypt_byte(unsigned long* pkeys, const unsigned long* pcrc_32_tab) 36 | { 37 | unsigned temp; /* POTENTIAL BUG: temp*(temp^1) may overflow in an 38 | * unpredictable manner on 16-bit systems; not a problem 39 | * with any known compiler so far, though */ 40 | 41 | temp = ((unsigned)(*(pkeys+2)) & 0xffff) | 2; 42 | return (int)(((temp * (temp ^ 1)) >> 8) & 0xff); 43 | } 44 | 45 | /*********************************************************************** 46 | * Update the encryption keys with the next byte of plain text 47 | */ 48 | static int update_keys(unsigned long* pkeys,const unsigned long* pcrc_32_tab,int c) 49 | { 50 | (*(pkeys+0)) = CRC32((*(pkeys+0)), c); 51 | (*(pkeys+1)) += (*(pkeys+0)) & 0xff; 52 | (*(pkeys+1)) = (*(pkeys+1)) * 134775813L + 1; 53 | { 54 | register int keyshift = (int)((*(pkeys+1)) >> 24); 55 | (*(pkeys+2)) = CRC32((*(pkeys+2)), keyshift); 56 | } 57 | return c; 58 | } 59 | 60 | 61 | /*********************************************************************** 62 | * Initialize the encryption keys and the random header according to 63 | * the given password. 64 | */ 65 | static void init_keys(const char* passwd,unsigned long* pkeys,const unsigned long* pcrc_32_tab) 66 | { 67 | *(pkeys+0) = 305419896L; 68 | *(pkeys+1) = 591751049L; 69 | *(pkeys+2) = 878082192L; 70 | while (*passwd != '\0') { 71 | update_keys(pkeys,pcrc_32_tab,(int)*passwd); 72 | passwd++; 73 | } 74 | } 75 | 76 | #define zdecode(pkeys,pcrc_32_tab,c) \ 77 | (update_keys(pkeys,pcrc_32_tab,c ^= decrypt_byte(pkeys,pcrc_32_tab))) 78 | 79 | #define zencode(pkeys,pcrc_32_tab,c,t) \ 80 | (t=decrypt_byte(pkeys,pcrc_32_tab), update_keys(pkeys,pcrc_32_tab,c), t^(c)) 81 | 82 | #ifdef INCLUDECRYPTINGCODE_IFCRYPTALLOWED 83 | 84 | #define RAND_HEAD_LEN 12 85 | /* "last resort" source for second part of crypt seed pattern */ 86 | # ifndef ZCR_SEED2 87 | # define ZCR_SEED2 3141592654UL /* use PI as default pattern */ 88 | # endif 89 | 90 | static int crypthead(const char* passwd, /* password string */ 91 | unsigned char* buf, /* where to write header */ 92 | int bufSize, 93 | unsigned long* pkeys, 94 | const unsigned long* pcrc_32_tab, 95 | unsigned long crcForCrypting) 96 | { 97 | int n; /* index in random header */ 98 | int t; /* temporary */ 99 | int c; /* random byte */ 100 | unsigned char header[RAND_HEAD_LEN-2]; /* random header */ 101 | static unsigned calls = 0; /* ensure different random header each time */ 102 | 103 | if (bufSize> 7) & 0xff; 118 | header[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, c, t); 119 | } 120 | /* Encrypt random header (last two bytes is high word of crc) */ 121 | init_keys(passwd, pkeys, pcrc_32_tab); 122 | for (n = 0; n < RAND_HEAD_LEN-2; n++) 123 | { 124 | buf[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, header[n], t); 125 | } 126 | buf[n++] = (unsigned char)zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 16) & 0xff, t); 127 | buf[n++] = (unsigned char)zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 24) & 0xff, t); 128 | return n; 129 | } 130 | 131 | #endif 132 | -------------------------------------------------------------------------------- /Loader/libs/minizip/ioapi.c: -------------------------------------------------------------------------------- 1 | /* ioapi.h -- IO base function header for compress/uncompress .zip 2 | part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) 3 | 4 | Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) 5 | 6 | Modifications for Zip64 support 7 | Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) 8 | 9 | For more info read MiniZip_info.txt 10 | 11 | */ 12 | 13 | #if (defined(_WIN32)) 14 | #define _CRT_SECURE_NO_WARNINGS 15 | #endif 16 | 17 | #include "ioapi.h" 18 | 19 | voidpf call_zopen64 (const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode) 20 | { 21 | if (pfilefunc->zfile_func64.zopen64_file != NULL) 22 | return (*(pfilefunc->zfile_func64.zopen64_file)) (pfilefunc->zfile_func64.opaque,filename,mode); 23 | else 24 | { 25 | return (*(pfilefunc->zopen32_file))(pfilefunc->zfile_func64.opaque,(const char*)filename,mode); 26 | } 27 | } 28 | 29 | long call_zseek64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin) 30 | { 31 | if (pfilefunc->zfile_func64.zseek64_file != NULL) 32 | return (*(pfilefunc->zfile_func64.zseek64_file)) (pfilefunc->zfile_func64.opaque,filestream,offset,origin); 33 | else 34 | { 35 | uLong offsetTruncated = (uLong)offset; 36 | if (offsetTruncated != offset) 37 | return -1; 38 | else 39 | return (*(pfilefunc->zseek32_file))(pfilefunc->zfile_func64.opaque,filestream,offsetTruncated,origin); 40 | } 41 | } 42 | 43 | ZPOS64_T call_ztell64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream) 44 | { 45 | if (pfilefunc->zfile_func64.zseek64_file != NULL) 46 | return (*(pfilefunc->zfile_func64.ztell64_file)) (pfilefunc->zfile_func64.opaque,filestream); 47 | else 48 | { 49 | uLong tell_uLong = (*(pfilefunc->ztell32_file))(pfilefunc->zfile_func64.opaque,filestream); 50 | if ((tell_uLong) == ((uLong)-1)) 51 | return (ZPOS64_T)-1; 52 | else 53 | return tell_uLong; 54 | } 55 | } 56 | 57 | void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32) 58 | { 59 | p_filefunc64_32->zfile_func64.zopen64_file = NULL; 60 | p_filefunc64_32->zopen32_file = p_filefunc32->zopen_file; 61 | p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file; 62 | p_filefunc64_32->zfile_func64.zread_file = p_filefunc32->zread_file; 63 | p_filefunc64_32->zfile_func64.zwrite_file = p_filefunc32->zwrite_file; 64 | p_filefunc64_32->zfile_func64.ztell64_file = NULL; 65 | p_filefunc64_32->zfile_func64.zseek64_file = NULL; 66 | p_filefunc64_32->zfile_func64.zclose_file = p_filefunc32->zclose_file; 67 | p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file; 68 | p_filefunc64_32->zfile_func64.opaque = p_filefunc32->opaque; 69 | p_filefunc64_32->zseek32_file = p_filefunc32->zseek_file; 70 | p_filefunc64_32->ztell32_file = p_filefunc32->ztell_file; 71 | } 72 | 73 | 74 | 75 | static voidpf ZCALLBACK fopen_file_func OF((voidpf opaque, const char* filename, int mode)); 76 | static uLong ZCALLBACK fread_file_func OF((voidpf opaque, voidpf stream, void* buf, uLong size)); 77 | static uLong ZCALLBACK fwrite_file_func OF((voidpf opaque, voidpf stream, const void* buf,uLong size)); 78 | static ZPOS64_T ZCALLBACK ftell64_file_func OF((voidpf opaque, voidpf stream)); 79 | static long ZCALLBACK fseek64_file_func OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin)); 80 | static int ZCALLBACK fclose_file_func OF((voidpf opaque, voidpf stream)); 81 | static int ZCALLBACK ferror_file_func OF((voidpf opaque, voidpf stream)); 82 | 83 | static voidpf ZCALLBACK fopen_file_func (voidpf opaque, const char* filename, int mode) 84 | { 85 | FILE* file = NULL; 86 | const char* mode_fopen = NULL; 87 | if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ) 88 | mode_fopen = "rb"; 89 | else 90 | if (mode & ZLIB_FILEFUNC_MODE_EXISTING) 91 | mode_fopen = "r+b"; 92 | else 93 | if (mode & ZLIB_FILEFUNC_MODE_CREATE) 94 | mode_fopen = "wb"; 95 | 96 | if ((filename!=NULL) && (mode_fopen != NULL)) 97 | file = fopen(filename, mode_fopen); 98 | return file; 99 | } 100 | 101 | static voidpf ZCALLBACK fopen64_file_func (voidpf opaque, const void* filename, int mode) 102 | { 103 | FILE* file = NULL; 104 | const char* mode_fopen = NULL; 105 | if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ) 106 | mode_fopen = "rb"; 107 | else 108 | if (mode & ZLIB_FILEFUNC_MODE_EXISTING) 109 | mode_fopen = "r+b"; 110 | else 111 | if (mode & ZLIB_FILEFUNC_MODE_CREATE) 112 | mode_fopen = "wb"; 113 | 114 | if ((filename!=NULL) && (mode_fopen != NULL)) 115 | file = fopen((const char*)filename, mode_fopen); 116 | return file; 117 | } 118 | 119 | 120 | static uLong ZCALLBACK fread_file_func (voidpf opaque, voidpf stream, void* buf, uLong size) 121 | { 122 | uLong ret; 123 | ret = (uLong)fread(buf, 1, (size_t)size, (FILE *)stream); 124 | return ret; 125 | } 126 | 127 | static uLong ZCALLBACK fwrite_file_func (voidpf opaque, voidpf stream, const void* buf, uLong size) 128 | { 129 | uLong ret; 130 | ret = (uLong)fwrite(buf, 1, (size_t)size, (FILE *)stream); 131 | return ret; 132 | } 133 | 134 | static long ZCALLBACK ftell_file_func (voidpf opaque, voidpf stream) 135 | { 136 | long ret; 137 | ret = ftell((FILE *)stream); 138 | return ret; 139 | } 140 | 141 | 142 | static ZPOS64_T ZCALLBACK ftell64_file_func (voidpf opaque, voidpf stream) 143 | { 144 | ZPOS64_T ret; 145 | ret = ftello((FILE *)stream); 146 | return ret; 147 | } 148 | 149 | static long ZCALLBACK fseek_file_func (voidpf opaque, voidpf stream, uLong offset, int origin) 150 | { 151 | int fseek_origin=0; 152 | long ret; 153 | switch (origin) 154 | { 155 | case ZLIB_FILEFUNC_SEEK_CUR : 156 | fseek_origin = SEEK_CUR; 157 | break; 158 | case ZLIB_FILEFUNC_SEEK_END : 159 | fseek_origin = SEEK_END; 160 | break; 161 | case ZLIB_FILEFUNC_SEEK_SET : 162 | fseek_origin = SEEK_SET; 163 | break; 164 | default: return -1; 165 | } 166 | ret = 0; 167 | if (fseek((FILE *)stream, offset, fseek_origin) != 0) 168 | ret = -1; 169 | return ret; 170 | } 171 | 172 | static long ZCALLBACK fseek64_file_func (voidpf opaque, voidpf stream, ZPOS64_T offset, int origin) 173 | { 174 | int fseek_origin=0; 175 | long ret; 176 | switch (origin) 177 | { 178 | case ZLIB_FILEFUNC_SEEK_CUR : 179 | fseek_origin = SEEK_CUR; 180 | break; 181 | case ZLIB_FILEFUNC_SEEK_END : 182 | fseek_origin = SEEK_END; 183 | break; 184 | case ZLIB_FILEFUNC_SEEK_SET : 185 | fseek_origin = SEEK_SET; 186 | break; 187 | default: return -1; 188 | } 189 | ret = 0; 190 | 191 | if(fseeko((FILE *)stream, offset, fseek_origin) != 0) 192 | ret = -1; 193 | 194 | return ret; 195 | } 196 | 197 | 198 | static int ZCALLBACK fclose_file_func (voidpf opaque, voidpf stream) 199 | { 200 | int ret; 201 | ret = fclose((FILE *)stream); 202 | return ret; 203 | } 204 | 205 | static int ZCALLBACK ferror_file_func (voidpf opaque, voidpf stream) 206 | { 207 | int ret; 208 | ret = ferror((FILE *)stream); 209 | return ret; 210 | } 211 | 212 | void fill_fopen_filefunc (pzlib_filefunc_def) 213 | zlib_filefunc_def* pzlib_filefunc_def; 214 | { 215 | pzlib_filefunc_def->zopen_file = fopen_file_func; 216 | pzlib_filefunc_def->zread_file = fread_file_func; 217 | pzlib_filefunc_def->zwrite_file = fwrite_file_func; 218 | pzlib_filefunc_def->ztell_file = ftell_file_func; 219 | pzlib_filefunc_def->zseek_file = fseek_file_func; 220 | pzlib_filefunc_def->zclose_file = fclose_file_func; 221 | pzlib_filefunc_def->zerror_file = ferror_file_func; 222 | pzlib_filefunc_def->opaque = NULL; 223 | } 224 | 225 | void fill_fopen64_filefunc (zlib_filefunc64_def* pzlib_filefunc_def) 226 | { 227 | pzlib_filefunc_def->zopen64_file = fopen64_file_func; 228 | pzlib_filefunc_def->zread_file = fread_file_func; 229 | pzlib_filefunc_def->zwrite_file = fwrite_file_func; 230 | pzlib_filefunc_def->ztell64_file = ftell64_file_func; 231 | pzlib_filefunc_def->zseek64_file = fseek64_file_func; 232 | pzlib_filefunc_def->zclose_file = fclose_file_func; 233 | pzlib_filefunc_def->zerror_file = ferror_file_func; 234 | pzlib_filefunc_def->opaque = NULL; 235 | } 236 | -------------------------------------------------------------------------------- /Loader/libs/minizip/ioapi.h: -------------------------------------------------------------------------------- 1 | /* ioapi.h -- IO base function header for compress/uncompress .zip 2 | part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) 3 | 4 | Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) 5 | 6 | Modifications for Zip64 support 7 | Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) 8 | 9 | For more info read MiniZip_info.txt 10 | 11 | Changes 12 | 13 | Oct-2009 - Defined ZPOS64_T to fpos_t on windows and u_int64_t on linux. (might need to find a better why for this) 14 | Oct-2009 - Change to fseeko64, ftello64 and fopen64 so large files would work on linux. 15 | More if/def section may be needed to support other platforms 16 | Oct-2009 - Defined fxxxx64 calls to normal fopen/ftell/fseek so they would compile on windows. 17 | (but you should use iowin32.c for windows instead) 18 | 19 | */ 20 | 21 | #ifndef _ZLIBIOAPI64_H 22 | #define _ZLIBIOAPI64_H 23 | 24 | #if (!defined(_WIN32)) && (!defined(WIN32)) 25 | 26 | // Linux needs this to support file operation on files larger then 4+GB 27 | // But might need better if/def to select just the platforms that needs them. 28 | 29 | #ifndef __USE_FILE_OFFSET64 30 | #define __USE_FILE_OFFSET64 31 | #endif 32 | #ifndef __USE_LARGEFILE64 33 | #define __USE_LARGEFILE64 34 | #endif 35 | #ifndef _LARGEFILE64_SOURCE 36 | #define _LARGEFILE64_SOURCE 37 | #endif 38 | #ifndef _FILE_OFFSET_BIT 39 | #define _FILE_OFFSET_BIT 64 40 | #endif 41 | #endif 42 | 43 | #include 44 | #include 45 | #include "zlib.h" 46 | 47 | #if defined(USE_FILE32API) 48 | #define fopen64 fopen 49 | #define ftello64 ftell 50 | #define fseeko64 fseek 51 | #else 52 | #ifdef _MSC_VER 53 | #define fopen64 fopen 54 | #if (_MSC_VER >= 1400) && (!(defined(NO_MSCVER_FILE64_FUNC))) 55 | #define ftello64 _ftelli64 56 | #define fseeko64 _fseeki64 57 | #else // old MSC 58 | #define ftello64 ftell 59 | #define fseeko64 fseek 60 | #endif 61 | #endif 62 | #endif 63 | 64 | /* 65 | #ifndef ZPOS64_T 66 | #ifdef _WIN32 67 | #define ZPOS64_T fpos_t 68 | #else 69 | #include 70 | #define ZPOS64_T uint64_t 71 | #endif 72 | #endif 73 | */ 74 | 75 | #ifdef HAVE_MINIZIP64_CONF_H 76 | #include "mz64conf.h" 77 | #endif 78 | 79 | /* a type choosen by DEFINE */ 80 | #ifdef HAVE_64BIT_INT_CUSTOM 81 | typedef 64BIT_INT_CUSTOM_TYPE ZPOS64_T; 82 | #else 83 | #ifdef HAS_STDINT_H 84 | #include "stdint.h" 85 | typedef uint64_t ZPOS64_T; 86 | #else 87 | 88 | 89 | #if defined(_MSC_VER) || defined(__BORLANDC__) 90 | typedef unsigned __int64 ZPOS64_T; 91 | #else 92 | typedef unsigned long long int ZPOS64_T; 93 | #endif 94 | #endif 95 | #endif 96 | 97 | 98 | 99 | #ifdef __cplusplus 100 | extern "C" { 101 | #endif 102 | 103 | 104 | #define ZLIB_FILEFUNC_SEEK_CUR (1) 105 | #define ZLIB_FILEFUNC_SEEK_END (2) 106 | #define ZLIB_FILEFUNC_SEEK_SET (0) 107 | 108 | #define ZLIB_FILEFUNC_MODE_READ (1) 109 | #define ZLIB_FILEFUNC_MODE_WRITE (2) 110 | #define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3) 111 | 112 | #define ZLIB_FILEFUNC_MODE_EXISTING (4) 113 | #define ZLIB_FILEFUNC_MODE_CREATE (8) 114 | 115 | 116 | #ifndef ZCALLBACK 117 | #if (defined(WIN32) || defined(_WIN32) || defined (WINDOWS) || defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK) 118 | #define ZCALLBACK CALLBACK 119 | #else 120 | #define ZCALLBACK 121 | #endif 122 | #endif 123 | 124 | 125 | 126 | 127 | typedef voidpf (ZCALLBACK *open_file_func) OF((voidpf opaque, const char* filename, int mode)); 128 | typedef uLong (ZCALLBACK *read_file_func) OF((voidpf opaque, voidpf stream, void* buf, uLong size)); 129 | typedef uLong (ZCALLBACK *write_file_func) OF((voidpf opaque, voidpf stream, const void* buf, uLong size)); 130 | typedef int (ZCALLBACK *close_file_func) OF((voidpf opaque, voidpf stream)); 131 | typedef int (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stream)); 132 | 133 | typedef long (ZCALLBACK *tell_file_func) OF((voidpf opaque, voidpf stream)); 134 | typedef long (ZCALLBACK *seek_file_func) OF((voidpf opaque, voidpf stream, uLong offset, int origin)); 135 | 136 | 137 | /* here is the "old" 32 bits structure structure */ 138 | typedef struct zlib_filefunc_def_s 139 | { 140 | open_file_func zopen_file; 141 | read_file_func zread_file; 142 | write_file_func zwrite_file; 143 | tell_file_func ztell_file; 144 | seek_file_func zseek_file; 145 | close_file_func zclose_file; 146 | testerror_file_func zerror_file; 147 | voidpf opaque; 148 | } zlib_filefunc_def; 149 | 150 | typedef ZPOS64_T (ZCALLBACK *tell64_file_func) OF((voidpf opaque, voidpf stream)); 151 | typedef long (ZCALLBACK *seek64_file_func) OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin)); 152 | typedef voidpf (ZCALLBACK *open64_file_func) OF((voidpf opaque, const void* filename, int mode)); 153 | 154 | typedef struct zlib_filefunc64_def_s 155 | { 156 | open64_file_func zopen64_file; 157 | read_file_func zread_file; 158 | write_file_func zwrite_file; 159 | tell64_file_func ztell64_file; 160 | seek64_file_func zseek64_file; 161 | close_file_func zclose_file; 162 | testerror_file_func zerror_file; 163 | voidpf opaque; 164 | } zlib_filefunc64_def; 165 | 166 | void fill_fopen64_filefunc OF((zlib_filefunc64_def* pzlib_filefunc_def)); 167 | void fill_fopen_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def)); 168 | 169 | /* now internal definition, only for zip.c and unzip.h */ 170 | typedef struct zlib_filefunc64_32_def_s 171 | { 172 | zlib_filefunc64_def zfile_func64; 173 | open_file_func zopen32_file; 174 | tell_file_func ztell32_file; 175 | seek_file_func zseek32_file; 176 | } zlib_filefunc64_32_def; 177 | 178 | 179 | #define ZREAD64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zread_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size)) 180 | #define ZWRITE64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zwrite_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size)) 181 | //#define ZTELL64(filefunc,filestream) ((*((filefunc).ztell64_file)) ((filefunc).opaque,filestream)) 182 | //#define ZSEEK64(filefunc,filestream,pos,mode) ((*((filefunc).zseek64_file)) ((filefunc).opaque,filestream,pos,mode)) 183 | #define ZCLOSE64(filefunc,filestream) ((*((filefunc).zfile_func64.zclose_file)) ((filefunc).zfile_func64.opaque,filestream)) 184 | #define ZERROR64(filefunc,filestream) ((*((filefunc).zfile_func64.zerror_file)) ((filefunc).zfile_func64.opaque,filestream)) 185 | 186 | voidpf call_zopen64 OF((const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode)); 187 | long call_zseek64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin)); 188 | ZPOS64_T call_ztell64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream)); 189 | 190 | void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32); 191 | 192 | #define ZOPEN64(filefunc,filename,mode) (call_zopen64((&(filefunc)),(filename),(mode))) 193 | #define ZTELL64(filefunc,filestream) (call_ztell64((&(filefunc)),(filestream))) 194 | #define ZSEEK64(filefunc,filestream,pos,mode) (call_zseek64((&(filefunc)),(filestream),(pos),(mode))) 195 | 196 | #ifdef __cplusplus 197 | } 198 | #endif 199 | 200 | #endif 201 | -------------------------------------------------------------------------------- /Loader/libs/minizip/mztools.c: -------------------------------------------------------------------------------- 1 | /* 2 | Additional tools for Minizip 3 | Code: Xavier Roche '2004 4 | License: Same as ZLIB (www.gzip.org) 5 | */ 6 | 7 | /* Code */ 8 | #include 9 | #include 10 | #include 11 | #include "zlib.h" 12 | #include "unzip.h" 13 | 14 | #define READ_8(adr) ((unsigned char)*(adr)) 15 | #define READ_16(adr) ( READ_8(adr) | (READ_8(adr+1) << 8) ) 16 | #define READ_32(adr) ( READ_16(adr) | (READ_16((adr)+2) << 16) ) 17 | 18 | #define WRITE_8(buff, n) do { \ 19 | *((unsigned char*)(buff)) = (unsigned char) ((n) & 0xff); \ 20 | } while(0) 21 | #define WRITE_16(buff, n) do { \ 22 | WRITE_8((unsigned char*)(buff), n); \ 23 | WRITE_8(((unsigned char*)(buff)) + 1, (n) >> 8); \ 24 | } while(0) 25 | #define WRITE_32(buff, n) do { \ 26 | WRITE_16((unsigned char*)(buff), (n) & 0xffff); \ 27 | WRITE_16((unsigned char*)(buff) + 2, (n) >> 16); \ 28 | } while(0) 29 | 30 | extern int ZEXPORT unzRepair(file, fileOut, fileOutTmp, nRecovered, bytesRecovered) 31 | const char* file; 32 | const char* fileOut; 33 | const char* fileOutTmp; 34 | uLong* nRecovered; 35 | uLong* bytesRecovered; 36 | { 37 | int err = Z_OK; 38 | FILE* fpZip = fopen(file, "rb"); 39 | FILE* fpOut = fopen(fileOut, "wb"); 40 | FILE* fpOutCD = fopen(fileOutTmp, "wb"); 41 | if (fpZip != NULL && fpOut != NULL) { 42 | int entries = 0; 43 | uLong totalBytes = 0; 44 | char header[30]; 45 | char filename[256]; 46 | char extra[1024]; 47 | int offset = 0; 48 | int offsetCD = 0; 49 | while ( fread(header, 1, 30, fpZip) == 30 ) { 50 | int currentOffset = offset; 51 | 52 | /* File entry */ 53 | if (READ_32(header) == 0x04034b50) { 54 | unsigned int version = READ_16(header + 4); 55 | unsigned int gpflag = READ_16(header + 6); 56 | unsigned int method = READ_16(header + 8); 57 | unsigned int filetime = READ_16(header + 10); 58 | unsigned int filedate = READ_16(header + 12); 59 | unsigned int crc = READ_32(header + 14); /* crc */ 60 | unsigned int cpsize = READ_32(header + 18); /* compressed size */ 61 | unsigned int uncpsize = READ_32(header + 22); /* uncompressed sz */ 62 | unsigned int fnsize = READ_16(header + 26); /* file name length */ 63 | unsigned int extsize = READ_16(header + 28); /* extra field length */ 64 | filename[0] = extra[0] = '\0'; 65 | 66 | /* Header */ 67 | if (fwrite(header, 1, 30, fpOut) == 30) { 68 | offset += 30; 69 | } else { 70 | err = Z_ERRNO; 71 | break; 72 | } 73 | 74 | /* Filename */ 75 | if (fnsize > 0) { 76 | if (fread(filename, 1, fnsize, fpZip) == fnsize) { 77 | if (fwrite(filename, 1, fnsize, fpOut) == fnsize) { 78 | offset += fnsize; 79 | } else { 80 | err = Z_ERRNO; 81 | break; 82 | } 83 | } else { 84 | err = Z_ERRNO; 85 | break; 86 | } 87 | } else { 88 | err = Z_STREAM_ERROR; 89 | break; 90 | } 91 | 92 | /* Extra field */ 93 | if (extsize > 0) { 94 | if (fread(extra, 1, extsize, fpZip) == extsize) { 95 | if (fwrite(extra, 1, extsize, fpOut) == extsize) { 96 | offset += extsize; 97 | } else { 98 | err = Z_ERRNO; 99 | break; 100 | } 101 | } else { 102 | err = Z_ERRNO; 103 | break; 104 | } 105 | } 106 | 107 | /* Data */ 108 | { 109 | int dataSize = cpsize; 110 | if (dataSize == 0) { 111 | dataSize = uncpsize; 112 | } 113 | if (dataSize > 0) { 114 | char* data = malloc(dataSize); 115 | if (data != NULL) { 116 | if ((int)fread(data, 1, dataSize, fpZip) == dataSize) { 117 | if ((int)fwrite(data, 1, dataSize, fpOut) == dataSize) { 118 | offset += dataSize; 119 | totalBytes += dataSize; 120 | } else { 121 | err = Z_ERRNO; 122 | } 123 | } else { 124 | err = Z_ERRNO; 125 | } 126 | free(data); 127 | if (err != Z_OK) { 128 | break; 129 | } 130 | } else { 131 | err = Z_MEM_ERROR; 132 | break; 133 | } 134 | } 135 | } 136 | 137 | /* Central directory entry */ 138 | { 139 | char header[46]; 140 | char* comment = ""; 141 | int comsize = (int) strlen(comment); 142 | WRITE_32(header, 0x02014b50); 143 | WRITE_16(header + 4, version); 144 | WRITE_16(header + 6, version); 145 | WRITE_16(header + 8, gpflag); 146 | WRITE_16(header + 10, method); 147 | WRITE_16(header + 12, filetime); 148 | WRITE_16(header + 14, filedate); 149 | WRITE_32(header + 16, crc); 150 | WRITE_32(header + 20, cpsize); 151 | WRITE_32(header + 24, uncpsize); 152 | WRITE_16(header + 28, fnsize); 153 | WRITE_16(header + 30, extsize); 154 | WRITE_16(header + 32, comsize); 155 | WRITE_16(header + 34, 0); /* disk # */ 156 | WRITE_16(header + 36, 0); /* int attrb */ 157 | WRITE_32(header + 38, 0); /* ext attrb */ 158 | WRITE_32(header + 42, currentOffset); 159 | /* Header */ 160 | if (fwrite(header, 1, 46, fpOutCD) == 46) { 161 | offsetCD += 46; 162 | 163 | /* Filename */ 164 | if (fnsize > 0) { 165 | if (fwrite(filename, 1, fnsize, fpOutCD) == fnsize) { 166 | offsetCD += fnsize; 167 | } else { 168 | err = Z_ERRNO; 169 | break; 170 | } 171 | } else { 172 | err = Z_STREAM_ERROR; 173 | break; 174 | } 175 | 176 | /* Extra field */ 177 | if (extsize > 0) { 178 | if (fwrite(extra, 1, extsize, fpOutCD) == extsize) { 179 | offsetCD += extsize; 180 | } else { 181 | err = Z_ERRNO; 182 | break; 183 | } 184 | } 185 | 186 | /* Comment field */ 187 | if (comsize > 0) { 188 | if ((int)fwrite(comment, 1, comsize, fpOutCD) == comsize) { 189 | offsetCD += comsize; 190 | } else { 191 | err = Z_ERRNO; 192 | break; 193 | } 194 | } 195 | 196 | 197 | } else { 198 | err = Z_ERRNO; 199 | break; 200 | } 201 | } 202 | 203 | /* Success */ 204 | entries++; 205 | 206 | } else { 207 | break; 208 | } 209 | } 210 | 211 | /* Final central directory */ 212 | { 213 | int entriesZip = entries; 214 | char header[22]; 215 | char* comment = ""; // "ZIP File recovered by zlib/minizip/mztools"; 216 | int comsize = (int) strlen(comment); 217 | if (entriesZip > 0xffff) { 218 | entriesZip = 0xffff; 219 | } 220 | WRITE_32(header, 0x06054b50); 221 | WRITE_16(header + 4, 0); /* disk # */ 222 | WRITE_16(header + 6, 0); /* disk # */ 223 | WRITE_16(header + 8, entriesZip); /* hack */ 224 | WRITE_16(header + 10, entriesZip); /* hack */ 225 | WRITE_32(header + 12, offsetCD); /* size of CD */ 226 | WRITE_32(header + 16, offset); /* offset to CD */ 227 | WRITE_16(header + 20, comsize); /* comment */ 228 | 229 | /* Header */ 230 | if (fwrite(header, 1, 22, fpOutCD) == 22) { 231 | 232 | /* Comment field */ 233 | if (comsize > 0) { 234 | if ((int)fwrite(comment, 1, comsize, fpOutCD) != comsize) { 235 | err = Z_ERRNO; 236 | } 237 | } 238 | 239 | } else { 240 | err = Z_ERRNO; 241 | } 242 | } 243 | 244 | /* Final merge (file + central directory) */ 245 | fclose(fpOutCD); 246 | if (err == Z_OK) { 247 | fpOutCD = fopen(fileOutTmp, "rb"); 248 | if (fpOutCD != NULL) { 249 | int nRead; 250 | char buffer[8192]; 251 | while ( (nRead = (int)fread(buffer, 1, sizeof(buffer), fpOutCD)) > 0) { 252 | if ((int)fwrite(buffer, 1, nRead, fpOut) != nRead) { 253 | err = Z_ERRNO; 254 | break; 255 | } 256 | } 257 | fclose(fpOutCD); 258 | } 259 | } 260 | 261 | /* Close */ 262 | fclose(fpZip); 263 | fclose(fpOut); 264 | 265 | /* Wipe temporary file */ 266 | (void)remove(fileOutTmp); 267 | 268 | /* Number of recovered entries */ 269 | if (err == Z_OK) { 270 | if (nRecovered != NULL) { 271 | *nRecovered = entries; 272 | } 273 | if (bytesRecovered != NULL) { 274 | *bytesRecovered = totalBytes; 275 | } 276 | } 277 | } else { 278 | err = Z_STREAM_ERROR; 279 | } 280 | return err; 281 | } 282 | -------------------------------------------------------------------------------- /Loader/libs/minizip/mztools.h: -------------------------------------------------------------------------------- 1 | /* 2 | Additional tools for Minizip 3 | Code: Xavier Roche '2004 4 | License: Same as ZLIB (www.gzip.org) 5 | */ 6 | 7 | #ifndef _zip_tools_H 8 | #define _zip_tools_H 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | #ifndef _ZLIB_H 15 | #include "zlib.h" 16 | #endif 17 | 18 | #include "unzip.h" 19 | 20 | /* Repair a ZIP file (missing central directory) 21 | file: file to recover 22 | fileOut: output file after recovery 23 | fileOutTmp: temporary file name used for recovery 24 | */ 25 | extern int ZEXPORT unzRepair(const char* file, 26 | const char* fileOut, 27 | const char* fileOutTmp, 28 | uLong* nRecovered, 29 | uLong* bytesRecovered); 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /Loader/libs/minizip/unzip.h: -------------------------------------------------------------------------------- 1 | /* unzip.h -- IO for uncompress .zip files using zlib 2 | Version 1.1, February 14h, 2010 3 | part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) 4 | 5 | Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) 6 | 7 | Modifications of Unzip for Zip64 8 | Copyright (C) 2007-2008 Even Rouault 9 | 10 | Modifications for Zip64 support on both zip and unzip 11 | Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) 12 | 13 | For more info read MiniZip_info.txt 14 | 15 | --------------------------------------------------------------------------------- 16 | 17 | Condition of use and distribution are the same than zlib : 18 | 19 | This software is provided 'as-is', without any express or implied 20 | warranty. In no event will the authors be held liable for any damages 21 | arising from the use of this software. 22 | 23 | Permission is granted to anyone to use this software for any purpose, 24 | including commercial applications, and to alter it and redistribute it 25 | freely, subject to the following restrictions: 26 | 27 | 1. The origin of this software must not be misrepresented; you must not 28 | claim that you wrote the original software. If you use this software 29 | in a product, an acknowledgment in the product documentation would be 30 | appreciated but is not required. 31 | 2. Altered source versions must be plainly marked as such, and must not be 32 | misrepresented as being the original software. 33 | 3. This notice may not be removed or altered from any source distribution. 34 | 35 | --------------------------------------------------------------------------------- 36 | 37 | Changes 38 | 39 | See header of unzip64.c 40 | 41 | */ 42 | 43 | #ifndef _unz64_H 44 | #define _unz64_H 45 | 46 | #ifdef __cplusplus 47 | extern "C" { 48 | #endif 49 | 50 | #ifndef _ZLIB_H 51 | #include "zlib.h" 52 | #endif 53 | 54 | #ifndef _ZLIBIOAPI_H 55 | #include "ioapi.h" 56 | #endif 57 | 58 | #ifdef HAVE_BZIP2 59 | #include "bzlib.h" 60 | #endif 61 | 62 | #define Z_BZIP2ED 12 63 | 64 | #if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP) 65 | /* like the STRICT of WIN32, we define a pointer that cannot be converted 66 | from (void*) without cast */ 67 | typedef struct TagunzFile__ { int unused; } unzFile__; 68 | typedef unzFile__ *unzFile; 69 | #else 70 | typedef voidp unzFile; 71 | #endif 72 | 73 | 74 | #define UNZ_OK (0) 75 | #define UNZ_END_OF_LIST_OF_FILE (-100) 76 | #define UNZ_ERRNO (Z_ERRNO) 77 | #define UNZ_EOF (0) 78 | #define UNZ_PARAMERROR (-102) 79 | #define UNZ_BADZIPFILE (-103) 80 | #define UNZ_INTERNALERROR (-104) 81 | #define UNZ_CRCERROR (-105) 82 | 83 | /* tm_unz contain date/time info */ 84 | typedef struct tm_unz_s 85 | { 86 | uInt tm_sec; /* seconds after the minute - [0,59] */ 87 | uInt tm_min; /* minutes after the hour - [0,59] */ 88 | uInt tm_hour; /* hours since midnight - [0,23] */ 89 | uInt tm_mday; /* day of the month - [1,31] */ 90 | uInt tm_mon; /* months since January - [0,11] */ 91 | uInt tm_year; /* years - [1980..2044] */ 92 | } tm_unz; 93 | 94 | /* unz_global_info structure contain global data about the ZIPfile 95 | These data comes from the end of central dir */ 96 | typedef struct unz_global_info64_s 97 | { 98 | ZPOS64_T number_entry; /* total number of entries in 99 | the central dir on this disk */ 100 | uLong size_comment; /* size of the global comment of the zipfile */ 101 | } unz_global_info64; 102 | 103 | typedef struct unz_global_info_s 104 | { 105 | uLong number_entry; /* total number of entries in 106 | the central dir on this disk */ 107 | uLong size_comment; /* size of the global comment of the zipfile */ 108 | } unz_global_info; 109 | 110 | /* unz_file_info contain information about a file in the zipfile */ 111 | typedef struct unz_file_info64_s 112 | { 113 | uLong version; /* version made by 2 bytes */ 114 | uLong version_needed; /* version needed to extract 2 bytes */ 115 | uLong flag; /* general purpose bit flag 2 bytes */ 116 | uLong compression_method; /* compression method 2 bytes */ 117 | uLong dosDate; /* last mod file date in Dos fmt 4 bytes */ 118 | uLong crc; /* crc-32 4 bytes */ 119 | ZPOS64_T compressed_size; /* compressed size 8 bytes */ 120 | ZPOS64_T uncompressed_size; /* uncompressed size 8 bytes */ 121 | uLong size_filename; /* filename length 2 bytes */ 122 | uLong size_file_extra; /* extra field length 2 bytes */ 123 | uLong size_file_comment; /* file comment length 2 bytes */ 124 | 125 | uLong disk_num_start; /* disk number start 2 bytes */ 126 | uLong internal_fa; /* internal file attributes 2 bytes */ 127 | uLong external_fa; /* external file attributes 4 bytes */ 128 | 129 | tm_unz tmu_date; 130 | } unz_file_info64; 131 | 132 | typedef struct unz_file_info_s 133 | { 134 | uLong version; /* version made by 2 bytes */ 135 | uLong version_needed; /* version needed to extract 2 bytes */ 136 | uLong flag; /* general purpose bit flag 2 bytes */ 137 | uLong compression_method; /* compression method 2 bytes */ 138 | uLong dosDate; /* last mod file date in Dos fmt 4 bytes */ 139 | uLong crc; /* crc-32 4 bytes */ 140 | uLong compressed_size; /* compressed size 4 bytes */ 141 | uLong uncompressed_size; /* uncompressed size 4 bytes */ 142 | uLong size_filename; /* filename length 2 bytes */ 143 | uLong size_file_extra; /* extra field length 2 bytes */ 144 | uLong size_file_comment; /* file comment length 2 bytes */ 145 | 146 | uLong disk_num_start; /* disk number start 2 bytes */ 147 | uLong internal_fa; /* internal file attributes 2 bytes */ 148 | uLong external_fa; /* external file attributes 4 bytes */ 149 | 150 | tm_unz tmu_date; 151 | } unz_file_info; 152 | 153 | extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1, 154 | const char* fileName2, 155 | int iCaseSensitivity)); 156 | /* 157 | Compare two filename (fileName1,fileName2). 158 | If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) 159 | If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi 160 | or strcasecmp) 161 | If iCaseSenisivity = 0, case sensitivity is defaut of your operating system 162 | (like 1 on Unix, 2 on Windows) 163 | */ 164 | 165 | 166 | extern unzFile ZEXPORT unzOpen OF((const char *path)); 167 | extern unzFile ZEXPORT unzOpen64 OF((const void *path)); 168 | /* 169 | Open a Zip file. path contain the full pathname (by example, 170 | on a Windows XP computer "c:\\zlib\\zlib113.zip" or on an Unix computer 171 | "zlib/zlib113.zip". 172 | If the zipfile cannot be opened (file don't exist or in not valid), the 173 | return value is NULL. 174 | Else, the return value is a unzFile Handle, usable with other function 175 | of this unzip package. 176 | the "64" function take a const void* pointer, because the path is just the 177 | value passed to the open64_file_func callback. 178 | Under Windows, if UNICODE is defined, using fill_fopen64_filefunc, the path 179 | is a pointer to a wide unicode string (LPCTSTR is LPCWSTR), so const char* 180 | does not describe the reality 181 | */ 182 | 183 | 184 | extern unzFile ZEXPORT unzOpen2 OF((const char *path, 185 | zlib_filefunc_def* pzlib_filefunc_def)); 186 | /* 187 | Open a Zip file, like unzOpen, but provide a set of file low level API 188 | for read/write the zip file (see ioapi.h) 189 | */ 190 | 191 | extern unzFile ZEXPORT unzOpen2_64 OF((const void *path, 192 | zlib_filefunc64_def* pzlib_filefunc_def)); 193 | /* 194 | Open a Zip file, like unz64Open, but provide a set of file low level API 195 | for read/write the zip file (see ioapi.h) 196 | */ 197 | 198 | extern int ZEXPORT unzClose OF((unzFile file)); 199 | /* 200 | Close a ZipFile opened with unzipOpen. 201 | If there is files inside the .Zip opened with unzOpenCurrentFile (see later), 202 | these files MUST be closed with unzipCloseCurrentFile before call unzipClose. 203 | return UNZ_OK if there is no problem. */ 204 | 205 | extern int ZEXPORT unzGetGlobalInfo OF((unzFile file, 206 | unz_global_info *pglobal_info)); 207 | 208 | extern int ZEXPORT unzGetGlobalInfo64 OF((unzFile file, 209 | unz_global_info64 *pglobal_info)); 210 | /* 211 | Write info about the ZipFile in the *pglobal_info structure. 212 | No preparation of the structure is needed 213 | return UNZ_OK if there is no problem. */ 214 | 215 | 216 | extern int ZEXPORT unzGetGlobalComment OF((unzFile file, 217 | char *szComment, 218 | uLong uSizeBuf)); 219 | /* 220 | Get the global comment string of the ZipFile, in the szComment buffer. 221 | uSizeBuf is the size of the szComment buffer. 222 | return the number of byte copied or an error code <0 223 | */ 224 | 225 | 226 | /***************************************************************************/ 227 | /* Unzip package allow you browse the directory of the zipfile */ 228 | 229 | extern int ZEXPORT unzGoToFirstFile OF((unzFile file)); 230 | /* 231 | Set the current file of the zipfile to the first file. 232 | return UNZ_OK if there is no problem 233 | */ 234 | 235 | extern int ZEXPORT unzGoToNextFile OF((unzFile file)); 236 | /* 237 | Set the current file of the zipfile to the next file. 238 | return UNZ_OK if there is no problem 239 | return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. 240 | */ 241 | 242 | extern int ZEXPORT unzLocateFile OF((unzFile file, 243 | const char *szFileName, 244 | int iCaseSensitivity)); 245 | /* 246 | Try locate the file szFileName in the zipfile. 247 | For the iCaseSensitivity signification, see unzStringFileNameCompare 248 | 249 | return value : 250 | UNZ_OK if the file is found. It becomes the current file. 251 | UNZ_END_OF_LIST_OF_FILE if the file is not found 252 | */ 253 | 254 | 255 | /* ****************************************** */ 256 | /* Ryan supplied functions */ 257 | /* unz_file_info contain information about a file in the zipfile */ 258 | typedef struct unz_file_pos_s 259 | { 260 | uLong pos_in_zip_directory; /* offset in zip file directory */ 261 | uLong num_of_file; /* # of file */ 262 | } unz_file_pos; 263 | 264 | extern int ZEXPORT unzGetFilePos( 265 | unzFile file, 266 | unz_file_pos* file_pos); 267 | 268 | extern int ZEXPORT unzGoToFilePos( 269 | unzFile file, 270 | unz_file_pos* file_pos); 271 | 272 | typedef struct unz64_file_pos_s 273 | { 274 | ZPOS64_T pos_in_zip_directory; /* offset in zip file directory */ 275 | ZPOS64_T num_of_file; /* # of file */ 276 | } unz64_file_pos; 277 | 278 | extern int ZEXPORT unzGetFilePos64( 279 | unzFile file, 280 | unz64_file_pos* file_pos); 281 | 282 | extern int ZEXPORT unzGoToFilePos64( 283 | unzFile file, 284 | const unz64_file_pos* file_pos); 285 | 286 | /* ****************************************** */ 287 | 288 | extern int ZEXPORT unzGetCurrentFileInfo64 OF((unzFile file, 289 | unz_file_info64 *pfile_info, 290 | char *szFileName, 291 | uLong fileNameBufferSize, 292 | void *extraField, 293 | uLong extraFieldBufferSize, 294 | char *szComment, 295 | uLong commentBufferSize)); 296 | 297 | extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file, 298 | unz_file_info *pfile_info, 299 | char *szFileName, 300 | uLong fileNameBufferSize, 301 | void *extraField, 302 | uLong extraFieldBufferSize, 303 | char *szComment, 304 | uLong commentBufferSize)); 305 | /* 306 | Get Info about the current file 307 | if pfile_info!=NULL, the *pfile_info structure will contain somes info about 308 | the current file 309 | if szFileName!=NULL, the filemane string will be copied in szFileName 310 | (fileNameBufferSize is the size of the buffer) 311 | if extraField!=NULL, the extra field information will be copied in extraField 312 | (extraFieldBufferSize is the size of the buffer). 313 | This is the Central-header version of the extra field 314 | if szComment!=NULL, the comment string of the file will be copied in szComment 315 | (commentBufferSize is the size of the buffer) 316 | */ 317 | 318 | 319 | /** Addition for GDAL : START */ 320 | 321 | extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64 OF((unzFile file)); 322 | 323 | /** Addition for GDAL : END */ 324 | 325 | 326 | /***************************************************************************/ 327 | /* for reading the content of the current zipfile, you can open it, read data 328 | from it, and close it (you can close it before reading all the file) 329 | */ 330 | 331 | extern int ZEXPORT unzOpenCurrentFile OF((unzFile file)); 332 | /* 333 | Open for reading data the current file in the zipfile. 334 | If there is no error, the return value is UNZ_OK. 335 | */ 336 | 337 | extern int ZEXPORT unzOpenCurrentFilePassword OF((unzFile file, 338 | const char* password)); 339 | /* 340 | Open for reading data the current file in the zipfile. 341 | password is a crypting password 342 | If there is no error, the return value is UNZ_OK. 343 | */ 344 | 345 | extern int ZEXPORT unzOpenCurrentFile2 OF((unzFile file, 346 | int* method, 347 | int* level, 348 | int raw)); 349 | /* 350 | Same than unzOpenCurrentFile, but open for read raw the file (not uncompress) 351 | if raw==1 352 | *method will receive method of compression, *level will receive level of 353 | compression 354 | note : you can set level parameter as NULL (if you did not want known level, 355 | but you CANNOT set method parameter as NULL 356 | */ 357 | 358 | extern int ZEXPORT unzOpenCurrentFile3 OF((unzFile file, 359 | int* method, 360 | int* level, 361 | int raw, 362 | const char* password)); 363 | /* 364 | Same than unzOpenCurrentFile, but open for read raw the file (not uncompress) 365 | if raw==1 366 | *method will receive method of compression, *level will receive level of 367 | compression 368 | note : you can set level parameter as NULL (if you did not want known level, 369 | but you CANNOT set method parameter as NULL 370 | */ 371 | 372 | 373 | extern int ZEXPORT unzCloseCurrentFile OF((unzFile file)); 374 | /* 375 | Close the file in zip opened with unzOpenCurrentFile 376 | Return UNZ_CRCERROR if all the file was read but the CRC is not good 377 | */ 378 | 379 | extern int ZEXPORT unzReadCurrentFile OF((unzFile file, 380 | voidp buf, 381 | unsigned len)); 382 | /* 383 | Read bytes from the current file (opened by unzOpenCurrentFile) 384 | buf contain buffer where data must be copied 385 | len the size of buf. 386 | 387 | return the number of byte copied if somes bytes are copied 388 | return 0 if the end of file was reached 389 | return <0 with error code if there is an error 390 | (UNZ_ERRNO for IO error, or zLib error for uncompress error) 391 | */ 392 | 393 | extern z_off_t ZEXPORT unztell OF((unzFile file)); 394 | 395 | extern ZPOS64_T ZEXPORT unztell64 OF((unzFile file)); 396 | /* 397 | Give the current position in uncompressed data 398 | */ 399 | 400 | extern int ZEXPORT unzeof OF((unzFile file)); 401 | /* 402 | return 1 if the end of file was reached, 0 elsewhere 403 | */ 404 | 405 | extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file, 406 | voidp buf, 407 | unsigned len)); 408 | /* 409 | Read extra field from the current file (opened by unzOpenCurrentFile) 410 | This is the local-header version of the extra field (sometimes, there is 411 | more info in the local-header version than in the central-header) 412 | 413 | if buf==NULL, it return the size of the local extra field 414 | 415 | if buf!=NULL, len is the size of the buffer, the extra header is copied in 416 | buf. 417 | the return value is the number of bytes copied in buf, or (if <0) 418 | the error code 419 | */ 420 | 421 | /***************************************************************************/ 422 | 423 | /* Get the current file offset */ 424 | extern ZPOS64_T ZEXPORT unzGetOffset64 (unzFile file); 425 | extern uLong ZEXPORT unzGetOffset (unzFile file); 426 | 427 | /* Set the current file offset */ 428 | extern int ZEXPORT unzSetOffset64 (unzFile file, ZPOS64_T pos); 429 | extern int ZEXPORT unzSetOffset (unzFile file, uLong pos); 430 | 431 | 432 | 433 | #ifdef __cplusplus 434 | } 435 | #endif 436 | 437 | #endif /* _unz64_H */ 438 | -------------------------------------------------------------------------------- /Loader/libs/minizip/zip.c: -------------------------------------------------------------------------------- 1 | /* zip.c -- IO on .zip files using zlib 2 | Version 1.1, February 14h, 2010 3 | part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) 4 | 5 | Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) 6 | 7 | Modifications for Zip64 support 8 | Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) 9 | 10 | For more info read MiniZip_info.txt 11 | 12 | Changes 13 | Oct-2009 - Mathias Svensson - Remove old C style function prototypes 14 | Oct-2009 - Mathias Svensson - Added Zip64 Support when creating new file archives 15 | Oct-2009 - Mathias Svensson - Did some code cleanup and refactoring to get better overview of some functions. 16 | Oct-2009 - Mathias Svensson - Added zipRemoveExtraInfoBlock to strip extra field data from its ZIP64 data 17 | It is used when recreting zip archive with RAW when deleting items from a zip. 18 | ZIP64 data is automaticly added to items that needs it, and existing ZIP64 data need to be removed. 19 | Oct-2009 - Mathias Svensson - Added support for BZIP2 as compression mode (bzip2 lib is required) 20 | Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer 21 | 22 | */ 23 | 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include "zlib.h" 30 | #include "zip.h" 31 | 32 | #ifdef STDC 33 | # include 34 | # include 35 | # include 36 | #endif 37 | #ifdef NO_ERRNO_H 38 | extern int errno; 39 | #else 40 | # include 41 | #endif 42 | 43 | 44 | #ifndef local 45 | # define local static 46 | #endif 47 | /* compile with -Dlocal if your debugger can't find static symbols */ 48 | 49 | #ifndef VERSIONMADEBY 50 | # define VERSIONMADEBY (0x0) /* platform depedent */ 51 | #endif 52 | 53 | #ifndef Z_BUFSIZE 54 | #define Z_BUFSIZE (64*1024) //(16384) 55 | #endif 56 | 57 | #ifndef Z_MAXFILENAMEINZIP 58 | #define Z_MAXFILENAMEINZIP (256) 59 | #endif 60 | 61 | #ifndef ALLOC 62 | # define ALLOC(size) (malloc(size)) 63 | #endif 64 | #ifndef TRYFREE 65 | # define TRYFREE(p) {if (p) free(p);} 66 | #endif 67 | 68 | /* 69 | #define SIZECENTRALDIRITEM (0x2e) 70 | #define SIZEZIPLOCALHEADER (0x1e) 71 | */ 72 | 73 | /* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */ 74 | 75 | 76 | // NOT sure that this work on ALL platform 77 | #define MAKEULONG64(a, b) ((ZPOS64_T)(((unsigned long)(a)) | ((ZPOS64_T)((unsigned long)(b))) << 32)) 78 | 79 | #ifndef SEEK_CUR 80 | #define SEEK_CUR 1 81 | #endif 82 | 83 | #ifndef SEEK_END 84 | #define SEEK_END 2 85 | #endif 86 | 87 | #ifndef SEEK_SET 88 | #define SEEK_SET 0 89 | #endif 90 | 91 | #ifndef DEF_MEM_LEVEL 92 | #if MAX_MEM_LEVEL >= 8 93 | # define DEF_MEM_LEVEL 8 94 | #else 95 | # define DEF_MEM_LEVEL MAX_MEM_LEVEL 96 | #endif 97 | #endif 98 | const char zip_copyright[] =" zip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll"; 99 | 100 | 101 | #define SIZEDATA_INDATABLOCK (4096-(4*4)) 102 | 103 | #define LOCALHEADERMAGIC (0x04034b50) 104 | #define CENTRALHEADERMAGIC (0x02014b50) 105 | #define ENDHEADERMAGIC (0x06054b50) 106 | #define ZIP64ENDHEADERMAGIC (0x6064b50) 107 | #define ZIP64ENDLOCHEADERMAGIC (0x7064b50) 108 | 109 | #define FLAG_LOCALHEADER_OFFSET (0x06) 110 | #define CRC_LOCALHEADER_OFFSET (0x0e) 111 | 112 | #define SIZECENTRALHEADER (0x2e) /* 46 */ 113 | 114 | typedef struct linkedlist_datablock_internal_s 115 | { 116 | struct linkedlist_datablock_internal_s* next_datablock; 117 | uLong avail_in_this_block; 118 | uLong filled_in_this_block; 119 | uLong unused; /* for future use and alignement */ 120 | unsigned char data[SIZEDATA_INDATABLOCK]; 121 | } linkedlist_datablock_internal; 122 | 123 | typedef struct linkedlist_data_s 124 | { 125 | linkedlist_datablock_internal* first_block; 126 | linkedlist_datablock_internal* last_block; 127 | } linkedlist_data; 128 | 129 | 130 | typedef struct 131 | { 132 | z_stream stream; /* zLib stream structure for inflate */ 133 | #ifdef HAVE_BZIP2 134 | bz_stream bstream; /* bzLib stream structure for bziped */ 135 | #endif 136 | 137 | int stream_initialised; /* 1 is stream is initialised */ 138 | uInt pos_in_buffered_data; /* last written byte in buffered_data */ 139 | 140 | ZPOS64_T pos_local_header; /* offset of the local header of the file 141 | currenty writing */ 142 | char* central_header; /* central header data for the current file */ 143 | uLong size_centralExtra; 144 | uLong size_centralheader; /* size of the central header for cur file */ 145 | uLong size_centralExtraFree; /* Extra bytes allocated to the centralheader but that are not used */ 146 | uLong flag; /* flag of the file currently writing */ 147 | 148 | int method; /* compression method of file currenty wr.*/ 149 | int raw; /* 1 for directly writing raw data */ 150 | Byte buffered_data[Z_BUFSIZE];/* buffer contain compressed data to be writ*/ 151 | uLong dosDate; 152 | uLong crc32; 153 | int encrypt; 154 | int zip64; /* Add ZIP64 extened information in the extra field */ 155 | ZPOS64_T pos_zip64extrainfo; 156 | ZPOS64_T totalCompressedData; 157 | ZPOS64_T totalUncompressedData; 158 | #ifndef NOCRYPT 159 | unsigned long keys[3]; /* keys defining the pseudo-random sequence */ 160 | const unsigned long* pcrc_32_tab; 161 | int crypt_header_size; 162 | #endif 163 | } curfile64_info; 164 | 165 | typedef struct 166 | { 167 | zlib_filefunc64_32_def z_filefunc; 168 | voidpf filestream; /* io structore of the zipfile */ 169 | linkedlist_data central_dir;/* datablock with central dir in construction*/ 170 | int in_opened_file_inzip; /* 1 if a file in the zip is currently writ.*/ 171 | curfile64_info ci; /* info on the file curretly writing */ 172 | 173 | ZPOS64_T begin_pos; /* position of the beginning of the zipfile */ 174 | ZPOS64_T add_position_when_writting_offset; 175 | ZPOS64_T number_entry; 176 | 177 | #ifndef NO_ADDFILEINEXISTINGZIP 178 | char *globalcomment; 179 | #endif 180 | 181 | } zip64_internal; 182 | 183 | 184 | #ifndef NOCRYPT 185 | #define INCLUDECRYPTINGCODE_IFCRYPTALLOWED 186 | #include "crypt.h" 187 | #endif 188 | 189 | local linkedlist_datablock_internal* allocate_new_datablock() 190 | { 191 | linkedlist_datablock_internal* ldi; 192 | ldi = (linkedlist_datablock_internal*) 193 | ALLOC(sizeof(linkedlist_datablock_internal)); 194 | if (ldi!=NULL) 195 | { 196 | ldi->next_datablock = NULL ; 197 | ldi->filled_in_this_block = 0 ; 198 | ldi->avail_in_this_block = SIZEDATA_INDATABLOCK ; 199 | } 200 | return ldi; 201 | } 202 | 203 | local void free_datablock(linkedlist_datablock_internal* ldi) 204 | { 205 | while (ldi!=NULL) 206 | { 207 | linkedlist_datablock_internal* ldinext = ldi->next_datablock; 208 | TRYFREE(ldi); 209 | ldi = ldinext; 210 | } 211 | } 212 | 213 | local void init_linkedlist(linkedlist_data* ll) 214 | { 215 | ll->first_block = ll->last_block = NULL; 216 | } 217 | 218 | local void free_linkedlist(linkedlist_data* ll) 219 | { 220 | free_datablock(ll->first_block); 221 | ll->first_block = ll->last_block = NULL; 222 | } 223 | 224 | 225 | local int add_data_in_datablock(linkedlist_data* ll, const void* buf, uLong len) 226 | { 227 | linkedlist_datablock_internal* ldi; 228 | const unsigned char* from_copy; 229 | 230 | if (ll==NULL) 231 | return ZIP_INTERNALERROR; 232 | 233 | if (ll->last_block == NULL) 234 | { 235 | ll->first_block = ll->last_block = allocate_new_datablock(); 236 | if (ll->first_block == NULL) 237 | return ZIP_INTERNALERROR; 238 | } 239 | 240 | ldi = ll->last_block; 241 | from_copy = (unsigned char*)buf; 242 | 243 | while (len>0) 244 | { 245 | uInt copy_this; 246 | uInt i; 247 | unsigned char* to_copy; 248 | 249 | if (ldi->avail_in_this_block==0) 250 | { 251 | ldi->next_datablock = allocate_new_datablock(); 252 | if (ldi->next_datablock == NULL) 253 | return ZIP_INTERNALERROR; 254 | ldi = ldi->next_datablock ; 255 | ll->last_block = ldi; 256 | } 257 | 258 | if (ldi->avail_in_this_block < len) 259 | copy_this = (uInt)ldi->avail_in_this_block; 260 | else 261 | copy_this = (uInt)len; 262 | 263 | to_copy = &(ldi->data[ldi->filled_in_this_block]); 264 | 265 | for (i=0;ifilled_in_this_block += copy_this; 269 | ldi->avail_in_this_block -= copy_this; 270 | from_copy += copy_this ; 271 | len -= copy_this; 272 | } 273 | return ZIP_OK; 274 | } 275 | 276 | 277 | 278 | /****************************************************************************/ 279 | 280 | #ifndef NO_ADDFILEINEXISTINGZIP 281 | /* =========================================================================== 282 | Inputs a long in LSB order to the given file 283 | nbByte == 1, 2 ,4 or 8 (byte, short or long, ZPOS64_T) 284 | */ 285 | 286 | local int zip64local_putValue OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte)); 287 | local int zip64local_putValue (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte) 288 | { 289 | unsigned char buf[8]; 290 | int n; 291 | for (n = 0; n < nbByte; n++) 292 | { 293 | buf[n] = (unsigned char)(x & 0xff); 294 | x >>= 8; 295 | } 296 | if (x != 0) 297 | { /* data overflow - hack for ZIP64 (X Roche) */ 298 | for (n = 0; n < nbByte; n++) 299 | { 300 | buf[n] = 0xff; 301 | } 302 | } 303 | 304 | if (ZWRITE64(*pzlib_filefunc_def,filestream,buf,nbByte)!=(uLong)nbByte) 305 | return ZIP_ERRNO; 306 | else 307 | return ZIP_OK; 308 | } 309 | 310 | local void zip64local_putValue_inmemory OF((void* dest, ZPOS64_T x, int nbByte)); 311 | local void zip64local_putValue_inmemory (void* dest, ZPOS64_T x, int nbByte) 312 | { 313 | unsigned char* buf=(unsigned char*)dest; 314 | int n; 315 | for (n = 0; n < nbByte; n++) { 316 | buf[n] = (unsigned char)(x & 0xff); 317 | x >>= 8; 318 | } 319 | 320 | if (x != 0) 321 | { /* data overflow - hack for ZIP64 */ 322 | for (n = 0; n < nbByte; n++) 323 | { 324 | buf[n] = 0xff; 325 | } 326 | } 327 | } 328 | 329 | /****************************************************************************/ 330 | 331 | 332 | local uLong zip64local_TmzDateToDosDate(const tm_zip* ptm) 333 | { 334 | uLong year = (uLong)ptm->tm_year; 335 | if (year>=1980) 336 | year-=1980; 337 | else if (year>=80) 338 | year-=80; 339 | return 340 | (uLong) (((ptm->tm_mday) + (32 * (ptm->tm_mon+1)) + (512 * year)) << 16) | 341 | ((ptm->tm_sec/2) + (32* ptm->tm_min) + (2048 * (uLong)ptm->tm_hour)); 342 | } 343 | 344 | 345 | /****************************************************************************/ 346 | 347 | local int zip64local_getByte OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi)); 348 | 349 | local int zip64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def,voidpf filestream,int* pi) 350 | { 351 | unsigned char c; 352 | int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1); 353 | if (err==1) 354 | { 355 | *pi = (int)c; 356 | return ZIP_OK; 357 | } 358 | else 359 | { 360 | if (ZERROR64(*pzlib_filefunc_def,filestream)) 361 | return ZIP_ERRNO; 362 | else 363 | return ZIP_EOF; 364 | } 365 | } 366 | 367 | 368 | /* =========================================================================== 369 | Reads a long in LSB order from the given gz_stream. Sets 370 | */ 371 | local int zip64local_getShort OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX)); 372 | 373 | local int zip64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX) 374 | { 375 | uLong x ; 376 | int i = 0; 377 | int err; 378 | 379 | err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); 380 | x = (uLong)i; 381 | 382 | if (err==ZIP_OK) 383 | err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); 384 | x += ((uLong)i)<<8; 385 | 386 | if (err==ZIP_OK) 387 | *pX = x; 388 | else 389 | *pX = 0; 390 | return err; 391 | } 392 | 393 | local int zip64local_getLong OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX)); 394 | 395 | local int zip64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX) 396 | { 397 | uLong x ; 398 | int i = 0; 399 | int err; 400 | 401 | err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); 402 | x = (uLong)i; 403 | 404 | if (err==ZIP_OK) 405 | err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); 406 | x += ((uLong)i)<<8; 407 | 408 | if (err==ZIP_OK) 409 | err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); 410 | x += ((uLong)i)<<16; 411 | 412 | if (err==ZIP_OK) 413 | err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); 414 | x += ((uLong)i)<<24; 415 | 416 | if (err==ZIP_OK) 417 | *pX = x; 418 | else 419 | *pX = 0; 420 | return err; 421 | } 422 | 423 | local int zip64local_getLong64 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX)); 424 | 425 | 426 | local int zip64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX) 427 | { 428 | ZPOS64_T x; 429 | int i = 0; 430 | int err; 431 | 432 | err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); 433 | x = (ZPOS64_T)i; 434 | 435 | if (err==ZIP_OK) 436 | err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); 437 | x += ((ZPOS64_T)i)<<8; 438 | 439 | if (err==ZIP_OK) 440 | err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); 441 | x += ((ZPOS64_T)i)<<16; 442 | 443 | if (err==ZIP_OK) 444 | err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); 445 | x += ((ZPOS64_T)i)<<24; 446 | 447 | if (err==ZIP_OK) 448 | err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); 449 | x += ((ZPOS64_T)i)<<32; 450 | 451 | if (err==ZIP_OK) 452 | err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); 453 | x += ((ZPOS64_T)i)<<40; 454 | 455 | if (err==ZIP_OK) 456 | err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); 457 | x += ((ZPOS64_T)i)<<48; 458 | 459 | if (err==ZIP_OK) 460 | err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); 461 | x += ((ZPOS64_T)i)<<56; 462 | 463 | if (err==ZIP_OK) 464 | *pX = x; 465 | else 466 | *pX = 0; 467 | 468 | return err; 469 | } 470 | 471 | #ifndef BUFREADCOMMENT 472 | #define BUFREADCOMMENT (0x400) 473 | #endif 474 | /* 475 | Locate the Central directory of a zipfile (at the end, just before 476 | the global comment) 477 | */ 478 | local ZPOS64_T zip64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)); 479 | 480 | local ZPOS64_T zip64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream) 481 | { 482 | unsigned char* buf; 483 | ZPOS64_T uSizeFile; 484 | ZPOS64_T uBackRead; 485 | ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ 486 | ZPOS64_T uPosFound=0; 487 | 488 | if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) 489 | return 0; 490 | 491 | 492 | uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); 493 | 494 | if (uMaxBack>uSizeFile) 495 | uMaxBack = uSizeFile; 496 | 497 | buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); 498 | if (buf==NULL) 499 | return 0; 500 | 501 | uBackRead = 4; 502 | while (uBackReaduMaxBack) 508 | uBackRead = uMaxBack; 509 | else 510 | uBackRead+=BUFREADCOMMENT; 511 | uReadPos = uSizeFile-uBackRead ; 512 | 513 | uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? 514 | (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos); 515 | if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) 516 | break; 517 | 518 | if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) 519 | break; 520 | 521 | for (i=(int)uReadSize-3; (i--)>0;) 522 | if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && 523 | ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06)) 524 | { 525 | uPosFound = uReadPos+i; 526 | break; 527 | } 528 | 529 | if (uPosFound!=0) 530 | break; 531 | } 532 | TRYFREE(buf); 533 | return uPosFound; 534 | } 535 | 536 | /* 537 | Locate the End of Zip64 Central directory locator and from there find the CD of a zipfile (at the end, just before 538 | the global comment) 539 | */ 540 | local ZPOS64_T zip64local_SearchCentralDir64 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)); 541 | 542 | local ZPOS64_T zip64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream) 543 | { 544 | unsigned char* buf; 545 | ZPOS64_T uSizeFile; 546 | ZPOS64_T uBackRead; 547 | ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ 548 | ZPOS64_T uPosFound=0; 549 | uLong uL; 550 | ZPOS64_T relativeOffset; 551 | 552 | if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) 553 | return 0; 554 | 555 | uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); 556 | 557 | if (uMaxBack>uSizeFile) 558 | uMaxBack = uSizeFile; 559 | 560 | buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); 561 | if (buf==NULL) 562 | return 0; 563 | 564 | uBackRead = 4; 565 | while (uBackReaduMaxBack) 571 | uBackRead = uMaxBack; 572 | else 573 | uBackRead+=BUFREADCOMMENT; 574 | uReadPos = uSizeFile-uBackRead ; 575 | 576 | uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? 577 | (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos); 578 | if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) 579 | break; 580 | 581 | if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) 582 | break; 583 | 584 | for (i=(int)uReadSize-3; (i--)>0;) 585 | { 586 | // Signature "0x07064b50" Zip64 end of central directory locater 587 | if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07)) 588 | { 589 | uPosFound = uReadPos+i; 590 | break; 591 | } 592 | } 593 | 594 | if (uPosFound!=0) 595 | break; 596 | } 597 | 598 | TRYFREE(buf); 599 | if (uPosFound == 0) 600 | return 0; 601 | 602 | /* Zip64 end of central directory locator */ 603 | if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0) 604 | return 0; 605 | 606 | /* the signature, already checked */ 607 | if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK) 608 | return 0; 609 | 610 | /* number of the disk with the start of the zip64 end of central directory */ 611 | if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK) 612 | return 0; 613 | if (uL != 0) 614 | return 0; 615 | 616 | /* relative offset of the zip64 end of central directory record */ 617 | if (zip64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=ZIP_OK) 618 | return 0; 619 | 620 | /* total number of disks */ 621 | if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK) 622 | return 0; 623 | if (uL != 1) 624 | return 0; 625 | 626 | /* Goto Zip64 end of central directory record */ 627 | if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0) 628 | return 0; 629 | 630 | /* the signature */ 631 | if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK) 632 | return 0; 633 | 634 | if (uL != 0x06064b50) // signature of 'Zip64 end of central directory' 635 | return 0; 636 | 637 | return relativeOffset; 638 | } 639 | 640 | int LoadCentralDirectoryRecord(zip64_internal* pziinit) 641 | { 642 | int err=ZIP_OK; 643 | ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ 644 | 645 | ZPOS64_T size_central_dir; /* size of the central directory */ 646 | ZPOS64_T offset_central_dir; /* offset of start of central directory */ 647 | ZPOS64_T central_pos; 648 | uLong uL; 649 | 650 | uLong number_disk; /* number of the current dist, used for 651 | spaning ZIP, unsupported, always 0*/ 652 | uLong number_disk_with_CD; /* number the the disk with central dir, used 653 | for spaning ZIP, unsupported, always 0*/ 654 | ZPOS64_T number_entry; 655 | ZPOS64_T number_entry_CD; /* total number of entries in 656 | the central dir 657 | (same than number_entry on nospan) */ 658 | uLong VersionMadeBy; 659 | uLong VersionNeeded; 660 | uLong size_comment; 661 | 662 | int hasZIP64Record = 0; 663 | 664 | // check first if we find a ZIP64 record 665 | central_pos = zip64local_SearchCentralDir64(&pziinit->z_filefunc,pziinit->filestream); 666 | if(central_pos > 0) 667 | { 668 | hasZIP64Record = 1; 669 | } 670 | else if(central_pos == 0) 671 | { 672 | central_pos = zip64local_SearchCentralDir(&pziinit->z_filefunc,pziinit->filestream); 673 | } 674 | 675 | /* disable to allow appending to empty ZIP archive 676 | if (central_pos==0) 677 | err=ZIP_ERRNO; 678 | */ 679 | 680 | if(hasZIP64Record) 681 | { 682 | ZPOS64_T sizeEndOfCentralDirectory; 683 | if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, central_pos, ZLIB_FILEFUNC_SEEK_SET) != 0) 684 | err=ZIP_ERRNO; 685 | 686 | /* the signature, already checked */ 687 | if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&uL)!=ZIP_OK) 688 | err=ZIP_ERRNO; 689 | 690 | /* size of zip64 end of central directory record */ 691 | if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &sizeEndOfCentralDirectory)!=ZIP_OK) 692 | err=ZIP_ERRNO; 693 | 694 | /* version made by */ 695 | if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &VersionMadeBy)!=ZIP_OK) 696 | err=ZIP_ERRNO; 697 | 698 | /* version needed to extract */ 699 | if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &VersionNeeded)!=ZIP_OK) 700 | err=ZIP_ERRNO; 701 | 702 | /* number of this disk */ 703 | if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&number_disk)!=ZIP_OK) 704 | err=ZIP_ERRNO; 705 | 706 | /* number of the disk with the start of the central directory */ 707 | if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&number_disk_with_CD)!=ZIP_OK) 708 | err=ZIP_ERRNO; 709 | 710 | /* total number of entries in the central directory on this disk */ 711 | if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &number_entry)!=ZIP_OK) 712 | err=ZIP_ERRNO; 713 | 714 | /* total number of entries in the central directory */ 715 | if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&number_entry_CD)!=ZIP_OK) 716 | err=ZIP_ERRNO; 717 | 718 | if ((number_entry_CD!=number_entry) || (number_disk_with_CD!=0) || (number_disk!=0)) 719 | err=ZIP_BADZIPFILE; 720 | 721 | /* size of the central directory */ 722 | if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&size_central_dir)!=ZIP_OK) 723 | err=ZIP_ERRNO; 724 | 725 | /* offset of start of central directory with respect to the 726 | starting disk number */ 727 | if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&offset_central_dir)!=ZIP_OK) 728 | err=ZIP_ERRNO; 729 | 730 | // TODO.. 731 | // read the comment from the standard central header. 732 | size_comment = 0; 733 | } 734 | else 735 | { 736 | // Read End of central Directory info 737 | if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) 738 | err=ZIP_ERRNO; 739 | 740 | /* the signature, already checked */ 741 | if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&uL)!=ZIP_OK) 742 | err=ZIP_ERRNO; 743 | 744 | /* number of this disk */ 745 | if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream,&number_disk)!=ZIP_OK) 746 | err=ZIP_ERRNO; 747 | 748 | /* number of the disk with the start of the central directory */ 749 | if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream,&number_disk_with_CD)!=ZIP_OK) 750 | err=ZIP_ERRNO; 751 | 752 | /* total number of entries in the central dir on this disk */ 753 | number_entry = 0; 754 | if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK) 755 | err=ZIP_ERRNO; 756 | else 757 | number_entry = uL; 758 | 759 | /* total number of entries in the central dir */ 760 | number_entry_CD = 0; 761 | if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK) 762 | err=ZIP_ERRNO; 763 | else 764 | number_entry_CD = uL; 765 | 766 | if ((number_entry_CD!=number_entry) || (number_disk_with_CD!=0) || (number_disk!=0)) 767 | err=ZIP_BADZIPFILE; 768 | 769 | /* size of the central directory */ 770 | size_central_dir = 0; 771 | if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK) 772 | err=ZIP_ERRNO; 773 | else 774 | size_central_dir = uL; 775 | 776 | /* offset of start of central directory with respect to the starting disk number */ 777 | offset_central_dir = 0; 778 | if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK) 779 | err=ZIP_ERRNO; 780 | else 781 | offset_central_dir = uL; 782 | 783 | 784 | /* zipfile global comment length */ 785 | if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &size_comment)!=ZIP_OK) 786 | err=ZIP_ERRNO; 787 | } 788 | 789 | if ((central_posz_filefunc, pziinit->filestream); 796 | return ZIP_ERRNO; 797 | } 798 | 799 | if (size_comment>0) 800 | { 801 | pziinit->globalcomment = (char*)ALLOC(size_comment+1); 802 | if (pziinit->globalcomment) 803 | { 804 | size_comment = ZREAD64(pziinit->z_filefunc, pziinit->filestream, pziinit->globalcomment,size_comment); 805 | pziinit->globalcomment[size_comment]=0; 806 | } 807 | } 808 | 809 | byte_before_the_zipfile = central_pos - (offset_central_dir+size_central_dir); 810 | pziinit->add_position_when_writting_offset = byte_before_the_zipfile; 811 | 812 | { 813 | ZPOS64_T size_central_dir_to_read = size_central_dir; 814 | size_t buf_size = SIZEDATA_INDATABLOCK; 815 | void* buf_read = (void*)ALLOC(buf_size); 816 | if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir + byte_before_the_zipfile, ZLIB_FILEFUNC_SEEK_SET) != 0) 817 | err=ZIP_ERRNO; 818 | 819 | while ((size_central_dir_to_read>0) && (err==ZIP_OK)) 820 | { 821 | ZPOS64_T read_this = SIZEDATA_INDATABLOCK; 822 | if (read_this > size_central_dir_to_read) 823 | read_this = size_central_dir_to_read; 824 | 825 | if (ZREAD64(pziinit->z_filefunc, pziinit->filestream,buf_read,(uLong)read_this) != read_this) 826 | err=ZIP_ERRNO; 827 | 828 | if (err==ZIP_OK) 829 | err = add_data_in_datablock(&pziinit->central_dir,buf_read, (uLong)read_this); 830 | 831 | size_central_dir_to_read-=read_this; 832 | } 833 | TRYFREE(buf_read); 834 | } 835 | pziinit->begin_pos = byte_before_the_zipfile; 836 | pziinit->number_entry = number_entry_CD; 837 | 838 | if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir+byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET) != 0) 839 | err=ZIP_ERRNO; 840 | 841 | return err; 842 | } 843 | 844 | 845 | #endif /* !NO_ADDFILEINEXISTINGZIP*/ 846 | 847 | 848 | /************************************************************/ 849 | extern zipFile ZEXPORT zipOpen3 (const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_32_def* pzlib_filefunc64_32_def) 850 | { 851 | zip64_internal ziinit; 852 | zip64_internal* zi; 853 | int err=ZIP_OK; 854 | 855 | ziinit.z_filefunc.zseek32_file = NULL; 856 | ziinit.z_filefunc.ztell32_file = NULL; 857 | if (pzlib_filefunc64_32_def==NULL) 858 | fill_fopen64_filefunc(&ziinit.z_filefunc.zfile_func64); 859 | else 860 | ziinit.z_filefunc = *pzlib_filefunc64_32_def; 861 | 862 | ziinit.filestream = ZOPEN64(ziinit.z_filefunc, 863 | pathname, 864 | (append == APPEND_STATUS_CREATE) ? 865 | (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE) : 866 | (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING)); 867 | 868 | if (ziinit.filestream == NULL) 869 | return NULL; 870 | 871 | if (append == APPEND_STATUS_CREATEAFTER) 872 | ZSEEK64(ziinit.z_filefunc,ziinit.filestream,0,SEEK_END); 873 | 874 | ziinit.begin_pos = ZTELL64(ziinit.z_filefunc,ziinit.filestream); 875 | ziinit.in_opened_file_inzip = 0; 876 | ziinit.ci.stream_initialised = 0; 877 | ziinit.number_entry = 0; 878 | ziinit.add_position_when_writting_offset = 0; 879 | init_linkedlist(&(ziinit.central_dir)); 880 | 881 | 882 | 883 | zi = (zip64_internal*)ALLOC(sizeof(zip64_internal)); 884 | if (zi==NULL) 885 | { 886 | ZCLOSE64(ziinit.z_filefunc,ziinit.filestream); 887 | return NULL; 888 | } 889 | 890 | /* now we add file in a zipfile */ 891 | # ifndef NO_ADDFILEINEXISTINGZIP 892 | ziinit.globalcomment = NULL; 893 | if (append == APPEND_STATUS_ADDINZIP) 894 | { 895 | // Read and Cache Central Directory Records 896 | err = LoadCentralDirectoryRecord(&ziinit); 897 | } 898 | 899 | if (globalcomment) 900 | { 901 | *globalcomment = ziinit.globalcomment; 902 | } 903 | # endif /* !NO_ADDFILEINEXISTINGZIP*/ 904 | 905 | if (err != ZIP_OK) 906 | { 907 | # ifndef NO_ADDFILEINEXISTINGZIP 908 | TRYFREE(ziinit.globalcomment); 909 | # endif /* !NO_ADDFILEINEXISTINGZIP*/ 910 | TRYFREE(zi); 911 | return NULL; 912 | } 913 | else 914 | { 915 | *zi = ziinit; 916 | return (zipFile)zi; 917 | } 918 | } 919 | 920 | extern zipFile ZEXPORT zipOpen2 (const char *pathname, int append, zipcharpc* globalcomment, zlib_filefunc_def* pzlib_filefunc32_def) 921 | { 922 | if (pzlib_filefunc32_def != NULL) 923 | { 924 | zlib_filefunc64_32_def zlib_filefunc64_32_def_fill; 925 | fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill,pzlib_filefunc32_def); 926 | return zipOpen3(pathname, append, globalcomment, &zlib_filefunc64_32_def_fill); 927 | } 928 | else 929 | return zipOpen3(pathname, append, globalcomment, NULL); 930 | } 931 | 932 | extern zipFile ZEXPORT zipOpen2_64 (const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_def* pzlib_filefunc_def) 933 | { 934 | if (pzlib_filefunc_def != NULL) 935 | { 936 | zlib_filefunc64_32_def zlib_filefunc64_32_def_fill; 937 | zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def; 938 | zlib_filefunc64_32_def_fill.ztell32_file = NULL; 939 | zlib_filefunc64_32_def_fill.zseek32_file = NULL; 940 | return zipOpen3(pathname, append, globalcomment, &zlib_filefunc64_32_def_fill); 941 | } 942 | else 943 | return zipOpen3(pathname, append, globalcomment, NULL); 944 | } 945 | 946 | 947 | 948 | extern zipFile ZEXPORT zipOpen (const char* pathname, int append) 949 | { 950 | return zipOpen3((const void*)pathname,append,NULL,NULL); 951 | } 952 | 953 | extern zipFile ZEXPORT zipOpen64 (const void* pathname, int append) 954 | { 955 | return zipOpen3(pathname,append,NULL,NULL); 956 | } 957 | 958 | int Write_LocalFileHeader(zip64_internal* zi, const char* filename, uInt size_extrafield_local, const void* extrafield_local) 959 | { 960 | /* write the local header */ 961 | int err; 962 | uInt size_filename = (uInt)strlen(filename); 963 | uInt size_extrafield = size_extrafield_local; 964 | 965 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)LOCALHEADERMAGIC, 4); 966 | 967 | if (err==ZIP_OK) 968 | { 969 | if(zi->ci.zip64) 970 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);/* version needed to extract */ 971 | else 972 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)20,2);/* version needed to extract */ 973 | } 974 | 975 | if (err==ZIP_OK) 976 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.flag,2); 977 | 978 | if (err==ZIP_OK) 979 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.method,2); 980 | 981 | if (err==ZIP_OK) 982 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.dosDate,4); 983 | 984 | // CRC / Compressed size / Uncompressed size will be filled in later and rewritten later 985 | if (err==ZIP_OK) 986 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* crc 32, unknown */ 987 | if (err==ZIP_OK) 988 | { 989 | if(zi->ci.zip64) 990 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xFFFFFFFF,4); /* compressed size, unknown */ 991 | else 992 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* compressed size, unknown */ 993 | } 994 | if (err==ZIP_OK) 995 | { 996 | if(zi->ci.zip64) 997 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xFFFFFFFF,4); /* uncompressed size, unknown */ 998 | else 999 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* uncompressed size, unknown */ 1000 | } 1001 | 1002 | if (err==ZIP_OK) 1003 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_filename,2); 1004 | 1005 | if(zi->ci.zip64) 1006 | { 1007 | size_extrafield += 20; 1008 | } 1009 | 1010 | if (err==ZIP_OK) 1011 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_extrafield,2); 1012 | 1013 | if ((err==ZIP_OK) && (size_filename > 0)) 1014 | { 1015 | if (ZWRITE64(zi->z_filefunc,zi->filestream,filename,size_filename)!=size_filename) 1016 | err = ZIP_ERRNO; 1017 | } 1018 | 1019 | if ((err==ZIP_OK) && (size_extrafield_local > 0)) 1020 | { 1021 | if (ZWRITE64(zi->z_filefunc, zi->filestream, extrafield_local, size_extrafield_local) != size_extrafield_local) 1022 | err = ZIP_ERRNO; 1023 | } 1024 | 1025 | 1026 | if ((err==ZIP_OK) && (zi->ci.zip64)) 1027 | { 1028 | // write the Zip64 extended info 1029 | short HeaderID = 1; 1030 | short DataSize = 16; 1031 | ZPOS64_T CompressedSize = 0; 1032 | ZPOS64_T UncompressedSize = 0; 1033 | 1034 | // Remember position of Zip64 extended info for the local file header. (needed when we update size after done with file) 1035 | zi->ci.pos_zip64extrainfo = ZTELL64(zi->z_filefunc,zi->filestream); 1036 | 1037 | err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)HeaderID,2); 1038 | err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)DataSize,2); 1039 | 1040 | err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)UncompressedSize,8); 1041 | err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)CompressedSize,8); 1042 | } 1043 | 1044 | return err; 1045 | } 1046 | 1047 | /* 1048 | NOTE. 1049 | When writing RAW the ZIP64 extended information in extrafield_local and extrafield_global needs to be stripped 1050 | before calling this function it can be done with zipRemoveExtraInfoBlock 1051 | 1052 | It is not done here because then we need to realloc a new buffer since parameters are 'const' and I want to minimize 1053 | unnecessary allocations. 1054 | */ 1055 | extern int ZEXPORT zipOpenNewFileInZip4_64 (zipFile file, const char* filename, const zip_fileinfo* zipfi, 1056 | const void* extrafield_local, uInt size_extrafield_local, 1057 | const void* extrafield_global, uInt size_extrafield_global, 1058 | const char* comment, int method, int level, int raw, 1059 | int windowBits,int memLevel, int strategy, 1060 | const char* password, uLong crcForCrypting, 1061 | uLong versionMadeBy, uLong flagBase, int zip64) 1062 | { 1063 | zip64_internal* zi; 1064 | uInt size_filename; 1065 | uInt size_comment; 1066 | uInt i; 1067 | int err = ZIP_OK; 1068 | 1069 | # ifdef NOCRYPT 1070 | if (password != NULL) 1071 | return ZIP_PARAMERROR; 1072 | # endif 1073 | 1074 | if (file == NULL) 1075 | return ZIP_PARAMERROR; 1076 | 1077 | #ifdef HAVE_BZIP2 1078 | if ((method!=0) && (method!=Z_DEFLATED) && (method!=Z_BZIP2ED)) 1079 | return ZIP_PARAMERROR; 1080 | #else 1081 | if ((method!=0) && (method!=Z_DEFLATED)) 1082 | return ZIP_PARAMERROR; 1083 | #endif 1084 | 1085 | zi = (zip64_internal*)file; 1086 | 1087 | if (zi->in_opened_file_inzip == 1) 1088 | { 1089 | err = zipCloseFileInZip (file); 1090 | if (err != ZIP_OK) 1091 | return err; 1092 | } 1093 | 1094 | if (filename==NULL) 1095 | filename="-"; 1096 | 1097 | if (comment==NULL) 1098 | size_comment = 0; 1099 | else 1100 | size_comment = (uInt)strlen(comment); 1101 | 1102 | size_filename = (uInt)strlen(filename); 1103 | 1104 | if (zipfi == NULL) 1105 | zi->ci.dosDate = 0; 1106 | else 1107 | { 1108 | if (zipfi->dosDate != 0) 1109 | zi->ci.dosDate = zipfi->dosDate; 1110 | else 1111 | zi->ci.dosDate = zip64local_TmzDateToDosDate(&zipfi->tmz_date); 1112 | } 1113 | 1114 | zi->ci.flag = flagBase; 1115 | if ((level==8) || (level==9)) 1116 | zi->ci.flag |= 2; 1117 | if (level==2) 1118 | zi->ci.flag |= 4; 1119 | if (level==1) 1120 | zi->ci.flag |= 6; 1121 | if (password != NULL) 1122 | zi->ci.flag |= 1; 1123 | 1124 | zi->ci.crc32 = 0; 1125 | zi->ci.method = method; 1126 | zi->ci.encrypt = 0; 1127 | zi->ci.stream_initialised = 0; 1128 | zi->ci.pos_in_buffered_data = 0; 1129 | zi->ci.raw = raw; 1130 | zi->ci.pos_local_header = ZTELL64(zi->z_filefunc,zi->filestream); 1131 | 1132 | zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename + size_extrafield_global + size_comment; 1133 | zi->ci.size_centralExtraFree = 32; // Extra space we have reserved in case we need to add ZIP64 extra info data 1134 | 1135 | zi->ci.central_header = (char*)ALLOC((uInt)zi->ci.size_centralheader + zi->ci.size_centralExtraFree); 1136 | 1137 | zi->ci.size_centralExtra = size_extrafield_global; 1138 | zip64local_putValue_inmemory(zi->ci.central_header,(uLong)CENTRALHEADERMAGIC,4); 1139 | /* version info */ 1140 | zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)versionMadeBy,2); 1141 | zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)20,2); 1142 | zip64local_putValue_inmemory(zi->ci.central_header+8,(uLong)zi->ci.flag,2); 1143 | zip64local_putValue_inmemory(zi->ci.central_header+10,(uLong)zi->ci.method,2); 1144 | zip64local_putValue_inmemory(zi->ci.central_header+12,(uLong)zi->ci.dosDate,4); 1145 | zip64local_putValue_inmemory(zi->ci.central_header+16,(uLong)0,4); /*crc*/ 1146 | zip64local_putValue_inmemory(zi->ci.central_header+20,(uLong)0,4); /*compr size*/ 1147 | zip64local_putValue_inmemory(zi->ci.central_header+24,(uLong)0,4); /*uncompr size*/ 1148 | zip64local_putValue_inmemory(zi->ci.central_header+28,(uLong)size_filename,2); 1149 | zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)size_extrafield_global,2); 1150 | zip64local_putValue_inmemory(zi->ci.central_header+32,(uLong)size_comment,2); 1151 | zip64local_putValue_inmemory(zi->ci.central_header+34,(uLong)0,2); /*disk nm start*/ 1152 | 1153 | if (zipfi==NULL) 1154 | zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)0,2); 1155 | else 1156 | zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)zipfi->internal_fa,2); 1157 | 1158 | if (zipfi==NULL) 1159 | zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)0,4); 1160 | else 1161 | zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)zipfi->external_fa,4); 1162 | 1163 | if(zi->ci.pos_local_header >= 0xffffffff) 1164 | zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)0xffffffff,4); 1165 | else 1166 | zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)zi->ci.pos_local_header - zi->add_position_when_writting_offset,4); 1167 | 1168 | for (i=0;ici.central_header+SIZECENTRALHEADER+i) = *(filename+i); 1170 | 1171 | for (i=0;ici.central_header+SIZECENTRALHEADER+size_filename+i) = 1173 | *(((const char*)extrafield_global)+i); 1174 | 1175 | for (i=0;ici.central_header+SIZECENTRALHEADER+size_filename+ 1177 | size_extrafield_global+i) = *(comment+i); 1178 | if (zi->ci.central_header == NULL) 1179 | return ZIP_INTERNALERROR; 1180 | 1181 | zi->ci.zip64 = zip64; 1182 | zi->ci.totalCompressedData = 0; 1183 | zi->ci.totalUncompressedData = 0; 1184 | zi->ci.pos_zip64extrainfo = 0; 1185 | 1186 | err = Write_LocalFileHeader(zi, filename, size_extrafield_local, extrafield_local); 1187 | 1188 | #ifdef HAVE_BZIP2 1189 | zi->ci.bstream.avail_in = (uInt)0; 1190 | zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE; 1191 | zi->ci.bstream.next_out = (char*)zi->ci.buffered_data; 1192 | zi->ci.bstream.total_in_hi32 = 0; 1193 | zi->ci.bstream.total_in_lo32 = 0; 1194 | zi->ci.bstream.total_out_hi32 = 0; 1195 | zi->ci.bstream.total_out_lo32 = 0; 1196 | #endif 1197 | 1198 | zi->ci.stream.avail_in = (uInt)0; 1199 | zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; 1200 | zi->ci.stream.next_out = zi->ci.buffered_data; 1201 | zi->ci.stream.total_in = 0; 1202 | zi->ci.stream.total_out = 0; 1203 | zi->ci.stream.data_type = Z_BINARY; 1204 | 1205 | #ifdef HAVE_BZIP2 1206 | if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED || zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw)) 1207 | #else 1208 | if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) 1209 | #endif 1210 | { 1211 | if(zi->ci.method == Z_DEFLATED) 1212 | { 1213 | zi->ci.stream.zalloc = (alloc_func)0; 1214 | zi->ci.stream.zfree = (free_func)0; 1215 | zi->ci.stream.opaque = (voidpf)0; 1216 | 1217 | if (windowBits>0) 1218 | windowBits = -windowBits; 1219 | 1220 | err = deflateInit2(&zi->ci.stream, level, Z_DEFLATED, windowBits, memLevel, strategy); 1221 | 1222 | if (err==Z_OK) 1223 | zi->ci.stream_initialised = Z_DEFLATED; 1224 | } 1225 | else if(zi->ci.method == Z_BZIP2ED) 1226 | { 1227 | #ifdef HAVE_BZIP2 1228 | // Init BZip stuff here 1229 | zi->ci.bstream.bzalloc = 0; 1230 | zi->ci.bstream.bzfree = 0; 1231 | zi->ci.bstream.opaque = (voidpf)0; 1232 | 1233 | err = BZ2_bzCompressInit(&zi->ci.bstream, level, 0,35); 1234 | if(err == BZ_OK) 1235 | zi->ci.stream_initialised = Z_BZIP2ED; 1236 | #endif 1237 | } 1238 | 1239 | } 1240 | 1241 | # ifndef NOCRYPT 1242 | zi->ci.crypt_header_size = 0; 1243 | if ((err==Z_OK) && (password != NULL)) 1244 | { 1245 | unsigned char bufHead[RAND_HEAD_LEN]; 1246 | unsigned int sizeHead; 1247 | zi->ci.encrypt = 1; 1248 | zi->ci.pcrc_32_tab = get_crc_table(); 1249 | /*init_keys(password,zi->ci.keys,zi->ci.pcrc_32_tab);*/ 1250 | 1251 | sizeHead=crypthead(password,bufHead,RAND_HEAD_LEN,zi->ci.keys,zi->ci.pcrc_32_tab,crcForCrypting); 1252 | zi->ci.crypt_header_size = sizeHead; 1253 | 1254 | if (ZWRITE64(zi->z_filefunc,zi->filestream,bufHead,sizeHead) != sizeHead) 1255 | err = ZIP_ERRNO; 1256 | } 1257 | # endif 1258 | 1259 | if (err==Z_OK) 1260 | zi->in_opened_file_inzip = 1; 1261 | return err; 1262 | } 1263 | 1264 | extern int ZEXPORT zipOpenNewFileInZip4 (zipFile file, const char* filename, const zip_fileinfo* zipfi, 1265 | const void* extrafield_local, uInt size_extrafield_local, 1266 | const void* extrafield_global, uInt size_extrafield_global, 1267 | const char* comment, int method, int level, int raw, 1268 | int windowBits,int memLevel, int strategy, 1269 | const char* password, uLong crcForCrypting, 1270 | uLong versionMadeBy, uLong flagBase) 1271 | { 1272 | return zipOpenNewFileInZip4_64 (file, filename, zipfi, 1273 | extrafield_local, size_extrafield_local, 1274 | extrafield_global, size_extrafield_global, 1275 | comment, method, level, raw, 1276 | windowBits, memLevel, strategy, 1277 | password, crcForCrypting, versionMadeBy, flagBase, 0); 1278 | } 1279 | 1280 | extern int ZEXPORT zipOpenNewFileInZip3 (zipFile file, const char* filename, const zip_fileinfo* zipfi, 1281 | const void* extrafield_local, uInt size_extrafield_local, 1282 | const void* extrafield_global, uInt size_extrafield_global, 1283 | const char* comment, int method, int level, int raw, 1284 | int windowBits,int memLevel, int strategy, 1285 | const char* password, uLong crcForCrypting) 1286 | { 1287 | return zipOpenNewFileInZip4_64 (file, filename, zipfi, 1288 | extrafield_local, size_extrafield_local, 1289 | extrafield_global, size_extrafield_global, 1290 | comment, method, level, raw, 1291 | windowBits, memLevel, strategy, 1292 | password, crcForCrypting, VERSIONMADEBY, 0, 0); 1293 | } 1294 | 1295 | extern int ZEXPORT zipOpenNewFileInZip3_64(zipFile file, const char* filename, const zip_fileinfo* zipfi, 1296 | const void* extrafield_local, uInt size_extrafield_local, 1297 | const void* extrafield_global, uInt size_extrafield_global, 1298 | const char* comment, int method, int level, int raw, 1299 | int windowBits,int memLevel, int strategy, 1300 | const char* password, uLong crcForCrypting, int zip64) 1301 | { 1302 | return zipOpenNewFileInZip4_64 (file, filename, zipfi, 1303 | extrafield_local, size_extrafield_local, 1304 | extrafield_global, size_extrafield_global, 1305 | comment, method, level, raw, 1306 | windowBits, memLevel, strategy, 1307 | password, crcForCrypting, VERSIONMADEBY, 0, zip64); 1308 | } 1309 | 1310 | extern int ZEXPORT zipOpenNewFileInZip2(zipFile file, const char* filename, const zip_fileinfo* zipfi, 1311 | const void* extrafield_local, uInt size_extrafield_local, 1312 | const void* extrafield_global, uInt size_extrafield_global, 1313 | const char* comment, int method, int level, int raw) 1314 | { 1315 | return zipOpenNewFileInZip4_64 (file, filename, zipfi, 1316 | extrafield_local, size_extrafield_local, 1317 | extrafield_global, size_extrafield_global, 1318 | comment, method, level, raw, 1319 | -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, 1320 | NULL, 0, VERSIONMADEBY, 0, 0); 1321 | } 1322 | 1323 | extern int ZEXPORT zipOpenNewFileInZip2_64(zipFile file, const char* filename, const zip_fileinfo* zipfi, 1324 | const void* extrafield_local, uInt size_extrafield_local, 1325 | const void* extrafield_global, uInt size_extrafield_global, 1326 | const char* comment, int method, int level, int raw, int zip64) 1327 | { 1328 | return zipOpenNewFileInZip4_64 (file, filename, zipfi, 1329 | extrafield_local, size_extrafield_local, 1330 | extrafield_global, size_extrafield_global, 1331 | comment, method, level, raw, 1332 | -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, 1333 | NULL, 0, VERSIONMADEBY, 0, zip64); 1334 | } 1335 | 1336 | extern int ZEXPORT zipOpenNewFileInZip64 (zipFile file, const char* filename, const zip_fileinfo* zipfi, 1337 | const void* extrafield_local, uInt size_extrafield_local, 1338 | const void*extrafield_global, uInt size_extrafield_global, 1339 | const char* comment, int method, int level, int zip64) 1340 | { 1341 | return zipOpenNewFileInZip4_64 (file, filename, zipfi, 1342 | extrafield_local, size_extrafield_local, 1343 | extrafield_global, size_extrafield_global, 1344 | comment, method, level, 0, 1345 | -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, 1346 | NULL, 0, VERSIONMADEBY, 0, zip64); 1347 | } 1348 | 1349 | extern int ZEXPORT zipOpenNewFileInZip (zipFile file, const char* filename, const zip_fileinfo* zipfi, 1350 | const void* extrafield_local, uInt size_extrafield_local, 1351 | const void*extrafield_global, uInt size_extrafield_global, 1352 | const char* comment, int method, int level) 1353 | { 1354 | return zipOpenNewFileInZip4_64 (file, filename, zipfi, 1355 | extrafield_local, size_extrafield_local, 1356 | extrafield_global, size_extrafield_global, 1357 | comment, method, level, 0, 1358 | -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, 1359 | NULL, 0, VERSIONMADEBY, 0, 0); 1360 | } 1361 | 1362 | local int zip64FlushWriteBuffer(zip64_internal* zi) 1363 | { 1364 | int err=ZIP_OK; 1365 | 1366 | if (zi->ci.encrypt != 0) 1367 | { 1368 | #ifndef NOCRYPT 1369 | uInt i; 1370 | int t; 1371 | for (i=0;ici.pos_in_buffered_data;i++) 1372 | zi->ci.buffered_data[i] = zencode(zi->ci.keys, zi->ci.pcrc_32_tab, zi->ci.buffered_data[i],t); 1373 | #endif 1374 | } 1375 | 1376 | if (ZWRITE64(zi->z_filefunc,zi->filestream,zi->ci.buffered_data,zi->ci.pos_in_buffered_data) != zi->ci.pos_in_buffered_data) 1377 | err = ZIP_ERRNO; 1378 | 1379 | zi->ci.totalCompressedData += zi->ci.pos_in_buffered_data; 1380 | 1381 | #ifdef HAVE_BZIP2 1382 | if(zi->ci.method == Z_BZIP2ED) 1383 | { 1384 | zi->ci.totalUncompressedData += zi->ci.bstream.total_in_lo32; 1385 | zi->ci.bstream.total_in_lo32 = 0; 1386 | zi->ci.bstream.total_in_hi32 = 0; 1387 | } 1388 | else 1389 | #endif 1390 | { 1391 | zi->ci.totalUncompressedData += zi->ci.stream.total_in; 1392 | zi->ci.stream.total_in = 0; 1393 | } 1394 | 1395 | 1396 | zi->ci.pos_in_buffered_data = 0; 1397 | 1398 | return err; 1399 | } 1400 | 1401 | extern int ZEXPORT zipWriteInFileInZip (zipFile file,const void* buf,unsigned int len) 1402 | { 1403 | zip64_internal* zi; 1404 | int err=ZIP_OK; 1405 | 1406 | if (file == NULL) 1407 | return ZIP_PARAMERROR; 1408 | zi = (zip64_internal*)file; 1409 | 1410 | if (zi->in_opened_file_inzip == 0) 1411 | return ZIP_PARAMERROR; 1412 | 1413 | zi->ci.crc32 = crc32(zi->ci.crc32,buf,(uInt)len); 1414 | 1415 | #ifdef HAVE_BZIP2 1416 | if(zi->ci.method == Z_BZIP2ED && (!zi->ci.raw)) 1417 | { 1418 | zi->ci.bstream.next_in = (void*)buf; 1419 | zi->ci.bstream.avail_in = len; 1420 | err = BZ_RUN_OK; 1421 | 1422 | while ((err==BZ_RUN_OK) && (zi->ci.bstream.avail_in>0)) 1423 | { 1424 | if (zi->ci.bstream.avail_out == 0) 1425 | { 1426 | if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) 1427 | err = ZIP_ERRNO; 1428 | zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE; 1429 | zi->ci.bstream.next_out = (char*)zi->ci.buffered_data; 1430 | } 1431 | 1432 | 1433 | if(err != BZ_RUN_OK) 1434 | break; 1435 | 1436 | if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw)) 1437 | { 1438 | uLong uTotalOutBefore_lo = zi->ci.bstream.total_out_lo32; 1439 | // uLong uTotalOutBefore_hi = zi->ci.bstream.total_out_hi32; 1440 | err=BZ2_bzCompress(&zi->ci.bstream, BZ_RUN); 1441 | 1442 | zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore_lo) ; 1443 | } 1444 | } 1445 | 1446 | if(err == BZ_RUN_OK) 1447 | err = ZIP_OK; 1448 | } 1449 | else 1450 | #endif 1451 | { 1452 | zi->ci.stream.next_in = (Bytef*)buf; 1453 | zi->ci.stream.avail_in = len; 1454 | 1455 | while ((err==ZIP_OK) && (zi->ci.stream.avail_in>0)) 1456 | { 1457 | if (zi->ci.stream.avail_out == 0) 1458 | { 1459 | if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) 1460 | err = ZIP_ERRNO; 1461 | zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; 1462 | zi->ci.stream.next_out = zi->ci.buffered_data; 1463 | } 1464 | 1465 | 1466 | if(err != ZIP_OK) 1467 | break; 1468 | 1469 | if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) 1470 | { 1471 | uLong uTotalOutBefore = zi->ci.stream.total_out; 1472 | err=deflate(&zi->ci.stream, Z_NO_FLUSH); 1473 | if(uTotalOutBefore > zi->ci.stream.total_out) 1474 | { 1475 | int bBreak = 0; 1476 | bBreak++; 1477 | } 1478 | 1479 | zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ; 1480 | } 1481 | else 1482 | { 1483 | uInt copy_this,i; 1484 | if (zi->ci.stream.avail_in < zi->ci.stream.avail_out) 1485 | copy_this = zi->ci.stream.avail_in; 1486 | else 1487 | copy_this = zi->ci.stream.avail_out; 1488 | 1489 | for (i = 0; i < copy_this; i++) 1490 | *(((char*)zi->ci.stream.next_out)+i) = 1491 | *(((const char*)zi->ci.stream.next_in)+i); 1492 | { 1493 | zi->ci.stream.avail_in -= copy_this; 1494 | zi->ci.stream.avail_out-= copy_this; 1495 | zi->ci.stream.next_in+= copy_this; 1496 | zi->ci.stream.next_out+= copy_this; 1497 | zi->ci.stream.total_in+= copy_this; 1498 | zi->ci.stream.total_out+= copy_this; 1499 | zi->ci.pos_in_buffered_data += copy_this; 1500 | } 1501 | } 1502 | }// while(...) 1503 | } 1504 | 1505 | return err; 1506 | } 1507 | 1508 | extern int ZEXPORT zipCloseFileInZipRaw (zipFile file, uLong uncompressed_size, uLong crc32) 1509 | { 1510 | return zipCloseFileInZipRaw64 (file, uncompressed_size, crc32); 1511 | } 1512 | 1513 | extern int ZEXPORT zipCloseFileInZipRaw64 (zipFile file, ZPOS64_T uncompressed_size, uLong crc32) 1514 | { 1515 | zip64_internal* zi; 1516 | ZPOS64_T compressed_size; 1517 | uLong invalidValue = 0xffffffff; 1518 | short datasize = 0; 1519 | int err=ZIP_OK; 1520 | 1521 | if (file == NULL) 1522 | return ZIP_PARAMERROR; 1523 | zi = (zip64_internal*)file; 1524 | 1525 | if (zi->in_opened_file_inzip == 0) 1526 | return ZIP_PARAMERROR; 1527 | zi->ci.stream.avail_in = 0; 1528 | 1529 | if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) 1530 | { 1531 | while (err==ZIP_OK) 1532 | { 1533 | uLong uTotalOutBefore; 1534 | if (zi->ci.stream.avail_out == 0) 1535 | { 1536 | if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) 1537 | err = ZIP_ERRNO; 1538 | zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; 1539 | zi->ci.stream.next_out = zi->ci.buffered_data; 1540 | } 1541 | uTotalOutBefore = zi->ci.stream.total_out; 1542 | err=deflate(&zi->ci.stream, Z_FINISH); 1543 | zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ; 1544 | } 1545 | } 1546 | else if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw)) 1547 | { 1548 | #ifdef HAVE_BZIP2 1549 | err = BZ_FINISH_OK; 1550 | while (err==BZ_FINISH_OK) 1551 | { 1552 | uLong uTotalOutBefore; 1553 | if (zi->ci.bstream.avail_out == 0) 1554 | { 1555 | if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) 1556 | err = ZIP_ERRNO; 1557 | zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE; 1558 | zi->ci.bstream.next_out = (char*)zi->ci.buffered_data; 1559 | } 1560 | uTotalOutBefore = zi->ci.bstream.total_out_lo32; 1561 | err=BZ2_bzCompress(&zi->ci.bstream, BZ_FINISH); 1562 | if(err == BZ_STREAM_END) 1563 | err = Z_STREAM_END; 1564 | 1565 | zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore); 1566 | } 1567 | 1568 | if(err == BZ_FINISH_OK) 1569 | err = ZIP_OK; 1570 | #endif 1571 | } 1572 | 1573 | if (err==Z_STREAM_END) 1574 | err=ZIP_OK; /* this is normal */ 1575 | 1576 | if ((zi->ci.pos_in_buffered_data>0) && (err==ZIP_OK)) 1577 | { 1578 | if (zip64FlushWriteBuffer(zi)==ZIP_ERRNO) 1579 | err = ZIP_ERRNO; 1580 | } 1581 | 1582 | if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) 1583 | { 1584 | int tmp_err = deflateEnd(&zi->ci.stream); 1585 | if (err == ZIP_OK) 1586 | err = tmp_err; 1587 | zi->ci.stream_initialised = 0; 1588 | } 1589 | #ifdef HAVE_BZIP2 1590 | else if((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw)) 1591 | { 1592 | int tmperr = BZ2_bzCompressEnd(&zi->ci.bstream); 1593 | if (err==ZIP_OK) 1594 | err = tmperr; 1595 | zi->ci.stream_initialised = 0; 1596 | } 1597 | #endif 1598 | 1599 | if (!zi->ci.raw) 1600 | { 1601 | crc32 = (uLong)zi->ci.crc32; 1602 | uncompressed_size = zi->ci.totalUncompressedData; 1603 | } 1604 | compressed_size = zi->ci.totalCompressedData; 1605 | 1606 | # ifndef NOCRYPT 1607 | compressed_size += zi->ci.crypt_header_size; 1608 | # endif 1609 | 1610 | // update Current Item crc and sizes, 1611 | if(compressed_size >= 0xffffffff || uncompressed_size >= 0xffffffff || zi->ci.pos_local_header >= 0xffffffff) 1612 | { 1613 | /*version Made by*/ 1614 | zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)45,2); 1615 | /*version needed*/ 1616 | zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)45,2); 1617 | 1618 | } 1619 | 1620 | zip64local_putValue_inmemory(zi->ci.central_header+16,crc32,4); /*crc*/ 1621 | 1622 | 1623 | if(compressed_size >= 0xffffffff) 1624 | zip64local_putValue_inmemory(zi->ci.central_header+20, invalidValue,4); /*compr size*/ 1625 | else 1626 | zip64local_putValue_inmemory(zi->ci.central_header+20, compressed_size,4); /*compr size*/ 1627 | 1628 | /// set internal file attributes field 1629 | if (zi->ci.stream.data_type == Z_ASCII) 1630 | zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)Z_ASCII,2); 1631 | 1632 | if(uncompressed_size >= 0xffffffff) 1633 | zip64local_putValue_inmemory(zi->ci.central_header+24, invalidValue,4); /*uncompr size*/ 1634 | else 1635 | zip64local_putValue_inmemory(zi->ci.central_header+24, uncompressed_size,4); /*uncompr size*/ 1636 | 1637 | // Add ZIP64 extra info field for uncompressed size 1638 | if(uncompressed_size >= 0xffffffff) 1639 | datasize += 8; 1640 | 1641 | // Add ZIP64 extra info field for compressed size 1642 | if(compressed_size >= 0xffffffff) 1643 | datasize += 8; 1644 | 1645 | // Add ZIP64 extra info field for relative offset to local file header of current file 1646 | if(zi->ci.pos_local_header >= 0xffffffff) 1647 | datasize += 8; 1648 | 1649 | if(datasize > 0) 1650 | { 1651 | char* p = NULL; 1652 | 1653 | if((uLong)(datasize + 4) > zi->ci.size_centralExtraFree) 1654 | { 1655 | // we can not write more data to the buffer that we have room for. 1656 | return ZIP_BADZIPFILE; 1657 | } 1658 | 1659 | p = zi->ci.central_header + zi->ci.size_centralheader; 1660 | 1661 | // Add Extra Information Header for 'ZIP64 information' 1662 | zip64local_putValue_inmemory(p, 0x0001, 2); // HeaderID 1663 | p += 2; 1664 | zip64local_putValue_inmemory(p, datasize, 2); // DataSize 1665 | p += 2; 1666 | 1667 | if(uncompressed_size >= 0xffffffff) 1668 | { 1669 | zip64local_putValue_inmemory(p, uncompressed_size, 8); 1670 | p += 8; 1671 | } 1672 | 1673 | if(compressed_size >= 0xffffffff) 1674 | { 1675 | zip64local_putValue_inmemory(p, compressed_size, 8); 1676 | p += 8; 1677 | } 1678 | 1679 | if(zi->ci.pos_local_header >= 0xffffffff) 1680 | { 1681 | zip64local_putValue_inmemory(p, zi->ci.pos_local_header, 8); 1682 | p += 8; 1683 | } 1684 | 1685 | // Update how much extra free space we got in the memory buffer 1686 | // and increase the centralheader size so the new ZIP64 fields are included 1687 | // ( 4 below is the size of HeaderID and DataSize field ) 1688 | zi->ci.size_centralExtraFree -= datasize + 4; 1689 | zi->ci.size_centralheader += datasize + 4; 1690 | 1691 | // Update the extra info size field 1692 | zi->ci.size_centralExtra += datasize + 4; 1693 | zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)zi->ci.size_centralExtra,2); 1694 | } 1695 | 1696 | if (err==ZIP_OK) 1697 | err = add_data_in_datablock(&zi->central_dir, zi->ci.central_header, (uLong)zi->ci.size_centralheader); 1698 | 1699 | free(zi->ci.central_header); 1700 | 1701 | if (err==ZIP_OK) 1702 | { 1703 | // Update the LocalFileHeader with the new values. 1704 | 1705 | ZPOS64_T cur_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream); 1706 | 1707 | if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_local_header + 14,ZLIB_FILEFUNC_SEEK_SET)!=0) 1708 | err = ZIP_ERRNO; 1709 | 1710 | if (err==ZIP_OK) 1711 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,crc32,4); /* crc 32, unknown */ 1712 | 1713 | if(uncompressed_size >= 0xffffffff) 1714 | { 1715 | if(zi->ci.pos_zip64extrainfo > 0) 1716 | { 1717 | // Update the size in the ZIP64 extended field. 1718 | if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_zip64extrainfo + 4,ZLIB_FILEFUNC_SEEK_SET)!=0) 1719 | err = ZIP_ERRNO; 1720 | 1721 | if (err==ZIP_OK) /* compressed size, unknown */ 1722 | err = zip64local_putValue(&zi->z_filefunc, zi->filestream, uncompressed_size, 8); 1723 | 1724 | if (err==ZIP_OK) /* uncompressed size, unknown */ 1725 | err = zip64local_putValue(&zi->z_filefunc, zi->filestream, compressed_size, 8); 1726 | } 1727 | } 1728 | else 1729 | { 1730 | if (err==ZIP_OK) /* compressed size, unknown */ 1731 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,compressed_size,4); 1732 | 1733 | if (err==ZIP_OK) /* uncompressed size, unknown */ 1734 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,4); 1735 | } 1736 | 1737 | if (ZSEEK64(zi->z_filefunc,zi->filestream, cur_pos_inzip,ZLIB_FILEFUNC_SEEK_SET)!=0) 1738 | err = ZIP_ERRNO; 1739 | } 1740 | 1741 | zi->number_entry ++; 1742 | zi->in_opened_file_inzip = 0; 1743 | 1744 | return err; 1745 | } 1746 | 1747 | extern int ZEXPORT zipCloseFileInZip (zipFile file) 1748 | { 1749 | return zipCloseFileInZipRaw (file,0,0); 1750 | } 1751 | 1752 | int Write_Zip64EndOfCentralDirectoryLocator(zip64_internal* zi, ZPOS64_T zip64eocd_pos_inzip) 1753 | { 1754 | int err = ZIP_OK; 1755 | ZPOS64_T pos = zip64eocd_pos_inzip - zi->add_position_when_writting_offset; 1756 | 1757 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDLOCHEADERMAGIC,4); 1758 | 1759 | /*num disks*/ 1760 | if (err==ZIP_OK) /* number of the disk with the start of the central directory */ 1761 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); 1762 | 1763 | /*relative offset*/ 1764 | if (err==ZIP_OK) /* Relative offset to the Zip64EndOfCentralDirectory */ 1765 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream, pos,8); 1766 | 1767 | /*total disks*/ /* Do not support spawning of disk so always say 1 here*/ 1768 | if (err==ZIP_OK) /* number of the disk with the start of the central directory */ 1769 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)1,4); 1770 | 1771 | return err; 1772 | } 1773 | 1774 | int Write_Zip64EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip) 1775 | { 1776 | int err = ZIP_OK; 1777 | 1778 | uLong Zip64DataSize = 44; 1779 | 1780 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDHEADERMAGIC,4); 1781 | 1782 | if (err==ZIP_OK) /* size of this 'zip64 end of central directory' */ 1783 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)Zip64DataSize,8); // why ZPOS64_T of this ? 1784 | 1785 | if (err==ZIP_OK) /* version made by */ 1786 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2); 1787 | 1788 | if (err==ZIP_OK) /* version needed */ 1789 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2); 1790 | 1791 | if (err==ZIP_OK) /* number of this disk */ 1792 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); 1793 | 1794 | if (err==ZIP_OK) /* number of the disk with the start of the central directory */ 1795 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); 1796 | 1797 | if (err==ZIP_OK) /* total number of entries in the central dir on this disk */ 1798 | err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8); 1799 | 1800 | if (err==ZIP_OK) /* total number of entries in the central dir */ 1801 | err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8); 1802 | 1803 | if (err==ZIP_OK) /* size of the central directory */ 1804 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)size_centraldir,8); 1805 | 1806 | if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */ 1807 | { 1808 | ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writting_offset; 1809 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (ZPOS64_T)pos,8); 1810 | } 1811 | return err; 1812 | } 1813 | int Write_EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip) 1814 | { 1815 | int err = ZIP_OK; 1816 | 1817 | /*signature*/ 1818 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ENDHEADERMAGIC,4); 1819 | 1820 | if (err==ZIP_OK) /* number of this disk */ 1821 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2); 1822 | 1823 | if (err==ZIP_OK) /* number of the disk with the start of the central directory */ 1824 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2); 1825 | 1826 | if (err==ZIP_OK) /* total number of entries in the central dir on this disk */ 1827 | { 1828 | { 1829 | if(zi->number_entry >= 0xFFFF) 1830 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); // use value in ZIP64 record 1831 | else 1832 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2); 1833 | } 1834 | } 1835 | 1836 | if (err==ZIP_OK) /* total number of entries in the central dir */ 1837 | { 1838 | if(zi->number_entry >= 0xFFFF) 1839 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); // use value in ZIP64 record 1840 | else 1841 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2); 1842 | } 1843 | 1844 | if (err==ZIP_OK) /* size of the central directory */ 1845 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_centraldir,4); 1846 | 1847 | if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */ 1848 | { 1849 | ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writting_offset; 1850 | if(pos >= 0xffffffff) 1851 | { 1852 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)0xffffffff,4); 1853 | } 1854 | else 1855 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)(centraldir_pos_inzip - zi->add_position_when_writting_offset),4); 1856 | } 1857 | 1858 | return err; 1859 | } 1860 | 1861 | int Write_GlobalComment(zip64_internal* zi, const char* global_comment) 1862 | { 1863 | int err = ZIP_OK; 1864 | uInt size_global_comment = 0; 1865 | 1866 | if(global_comment != NULL) 1867 | size_global_comment = (uInt)strlen(global_comment); 1868 | 1869 | err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_global_comment,2); 1870 | 1871 | if (err == ZIP_OK && size_global_comment > 0) 1872 | { 1873 | if (ZWRITE64(zi->z_filefunc,zi->filestream, global_comment, size_global_comment) != size_global_comment) 1874 | err = ZIP_ERRNO; 1875 | } 1876 | return err; 1877 | } 1878 | 1879 | extern int ZEXPORT zipClose (zipFile file, const char* global_comment) 1880 | { 1881 | zip64_internal* zi; 1882 | int err = 0; 1883 | uLong size_centraldir = 0; 1884 | ZPOS64_T centraldir_pos_inzip; 1885 | ZPOS64_T pos; 1886 | 1887 | if (file == NULL) 1888 | return ZIP_PARAMERROR; 1889 | 1890 | zi = (zip64_internal*)file; 1891 | 1892 | if (zi->in_opened_file_inzip == 1) 1893 | { 1894 | err = zipCloseFileInZip (file); 1895 | } 1896 | 1897 | #ifndef NO_ADDFILEINEXISTINGZIP 1898 | if (global_comment==NULL) 1899 | global_comment = zi->globalcomment; 1900 | #endif 1901 | 1902 | centraldir_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream); 1903 | 1904 | if (err==ZIP_OK) 1905 | { 1906 | linkedlist_datablock_internal* ldi = zi->central_dir.first_block; 1907 | while (ldi!=NULL) 1908 | { 1909 | if ((err==ZIP_OK) && (ldi->filled_in_this_block>0)) 1910 | { 1911 | if (ZWRITE64(zi->z_filefunc,zi->filestream, ldi->data, ldi->filled_in_this_block) != ldi->filled_in_this_block) 1912 | err = ZIP_ERRNO; 1913 | } 1914 | 1915 | size_centraldir += ldi->filled_in_this_block; 1916 | ldi = ldi->next_datablock; 1917 | } 1918 | } 1919 | free_linkedlist(&(zi->central_dir)); 1920 | 1921 | pos = centraldir_pos_inzip - zi->add_position_when_writting_offset; 1922 | if(pos >= 0xffffffff) 1923 | { 1924 | ZPOS64_T Zip64EOCDpos = ZTELL64(zi->z_filefunc,zi->filestream); 1925 | Write_Zip64EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip); 1926 | 1927 | Write_Zip64EndOfCentralDirectoryLocator(zi, Zip64EOCDpos); 1928 | } 1929 | 1930 | if (err==ZIP_OK) 1931 | err = Write_EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip); 1932 | 1933 | if(err == ZIP_OK) 1934 | err = Write_GlobalComment(zi, global_comment); 1935 | 1936 | if (ZCLOSE64(zi->z_filefunc,zi->filestream) != 0) 1937 | if (err == ZIP_OK) 1938 | err = ZIP_ERRNO; 1939 | 1940 | #ifndef NO_ADDFILEINEXISTINGZIP 1941 | TRYFREE(zi->globalcomment); 1942 | #endif 1943 | TRYFREE(zi); 1944 | 1945 | return err; 1946 | } 1947 | 1948 | extern int ZEXPORT zipRemoveExtraInfoBlock (char* pData, int* dataLen, short sHeader) 1949 | { 1950 | char* p = pData; 1951 | int size = 0; 1952 | char* pNewHeader; 1953 | char* pTmp; 1954 | short header; 1955 | short dataSize; 1956 | 1957 | int retVal = ZIP_OK; 1958 | 1959 | if(pData == NULL || *dataLen < 4) 1960 | return ZIP_PARAMERROR; 1961 | 1962 | pNewHeader = (char*)ALLOC(*dataLen); 1963 | pTmp = pNewHeader; 1964 | 1965 | while(p < (pData + *dataLen)) 1966 | { 1967 | header = *(short*)p; 1968 | dataSize = *(((short*)p)+1); 1969 | 1970 | if( header == sHeader ) // Header found. 1971 | { 1972 | p += dataSize + 4; // skip it. do not copy to temp buffer 1973 | } 1974 | else 1975 | { 1976 | // Extra Info block should not be removed, So copy it to the temp buffer. 1977 | memcpy(pTmp, p, dataSize + 4); 1978 | p += dataSize + 4; 1979 | size += dataSize + 4; 1980 | } 1981 | 1982 | } 1983 | 1984 | if(size < *dataLen) 1985 | { 1986 | // clean old extra info block. 1987 | memset(pData,0, *dataLen); 1988 | 1989 | // copy the new extra info block over the old 1990 | if(size > 0) 1991 | memcpy(pData, pNewHeader, size); 1992 | 1993 | // set the new extra info size 1994 | *dataLen = size; 1995 | 1996 | retVal = ZIP_OK; 1997 | } 1998 | else 1999 | retVal = ZIP_ERRNO; 2000 | 2001 | TRYFREE(pNewHeader); 2002 | 2003 | return retVal; 2004 | } 2005 | -------------------------------------------------------------------------------- /Loader/libs/minizip/zip.h: -------------------------------------------------------------------------------- 1 | /* zip.h -- IO on .zip files using zlib 2 | Version 1.1, February 14h, 2010 3 | part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) 4 | 5 | Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) 6 | 7 | Modifications for Zip64 support 8 | Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) 9 | 10 | For more info read MiniZip_info.txt 11 | 12 | --------------------------------------------------------------------------- 13 | 14 | Condition of use and distribution are the same than zlib : 15 | 16 | This software is provided 'as-is', without any express or implied 17 | warranty. In no event will the authors be held liable for any damages 18 | arising from the use of this software. 19 | 20 | Permission is granted to anyone to use this software for any purpose, 21 | including commercial applications, and to alter it and redistribute it 22 | freely, subject to the following restrictions: 23 | 24 | 1. The origin of this software must not be misrepresented; you must not 25 | claim that you wrote the original software. If you use this software 26 | in a product, an acknowledgment in the product documentation would be 27 | appreciated but is not required. 28 | 2. Altered source versions must be plainly marked as such, and must not be 29 | misrepresented as being the original software. 30 | 3. This notice may not be removed or altered from any source distribution. 31 | 32 | --------------------------------------------------------------------------- 33 | 34 | Changes 35 | 36 | See header of zip.h 37 | 38 | */ 39 | 40 | #ifndef _zip12_H 41 | #define _zip12_H 42 | 43 | #ifdef __cplusplus 44 | extern "C" { 45 | #endif 46 | 47 | //#define HAVE_BZIP2 48 | 49 | #ifndef _ZLIB_H 50 | #include "zlib.h" 51 | #endif 52 | 53 | #ifndef _ZLIBIOAPI_H 54 | #include "ioapi.h" 55 | #endif 56 | 57 | #ifdef HAVE_BZIP2 58 | #include "bzlib.h" 59 | #endif 60 | 61 | #define Z_BZIP2ED 12 62 | 63 | #if defined(STRICTZIP) || defined(STRICTZIPUNZIP) 64 | /* like the STRICT of WIN32, we define a pointer that cannot be converted 65 | from (void*) without cast */ 66 | typedef struct TagzipFile__ { int unused; } zipFile__; 67 | typedef zipFile__ *zipFile; 68 | #else 69 | typedef voidp zipFile; 70 | #endif 71 | 72 | #define ZIP_OK (0) 73 | #define ZIP_EOF (0) 74 | #define ZIP_ERRNO (Z_ERRNO) 75 | #define ZIP_PARAMERROR (-102) 76 | #define ZIP_BADZIPFILE (-103) 77 | #define ZIP_INTERNALERROR (-104) 78 | 79 | #ifndef DEF_MEM_LEVEL 80 | # if MAX_MEM_LEVEL >= 8 81 | # define DEF_MEM_LEVEL 8 82 | # else 83 | # define DEF_MEM_LEVEL MAX_MEM_LEVEL 84 | # endif 85 | #endif 86 | /* default memLevel */ 87 | 88 | /* tm_zip contain date/time info */ 89 | typedef struct tm_zip_s 90 | { 91 | uInt tm_sec; /* seconds after the minute - [0,59] */ 92 | uInt tm_min; /* minutes after the hour - [0,59] */ 93 | uInt tm_hour; /* hours since midnight - [0,23] */ 94 | uInt tm_mday; /* day of the month - [1,31] */ 95 | uInt tm_mon; /* months since January - [0,11] */ 96 | uInt tm_year; /* years - [1980..2044] */ 97 | } tm_zip; 98 | 99 | typedef struct 100 | { 101 | tm_zip tmz_date; /* date in understandable format */ 102 | uLong dosDate; /* if dos_date == 0, tmu_date is used */ 103 | /* uLong flag; */ /* general purpose bit flag 2 bytes */ 104 | 105 | uLong internal_fa; /* internal file attributes 2 bytes */ 106 | uLong external_fa; /* external file attributes 4 bytes */ 107 | } zip_fileinfo; 108 | 109 | typedef const char* zipcharpc; 110 | 111 | 112 | #define APPEND_STATUS_CREATE (0) 113 | #define APPEND_STATUS_CREATEAFTER (1) 114 | #define APPEND_STATUS_ADDINZIP (2) 115 | 116 | extern zipFile ZEXPORT zipOpen OF((const char *pathname, int append)); 117 | extern zipFile ZEXPORT zipOpen64 OF((const void *pathname, int append)); 118 | /* 119 | Create a zipfile. 120 | pathname contain on Windows XP a filename like "c:\\zlib\\zlib113.zip" or on 121 | an Unix computer "zlib/zlib113.zip". 122 | if the file pathname exist and append==APPEND_STATUS_CREATEAFTER, the zip 123 | will be created at the end of the file. 124 | (useful if the file contain a self extractor code) 125 | if the file pathname exist and append==APPEND_STATUS_ADDINZIP, we will 126 | add files in existing zip (be sure you don't add file that doesn't exist) 127 | If the zipfile cannot be opened, the return value is NULL. 128 | Else, the return value is a zipFile Handle, usable with other function 129 | of this zip package. 130 | */ 131 | 132 | /* Note : there is no delete function into a zipfile. 133 | If you want delete file into a zipfile, you must open a zipfile, and create another 134 | Of couse, you can use RAW reading and writing to copy the file you did not want delte 135 | */ 136 | 137 | extern zipFile ZEXPORT zipOpen2 OF((const char *pathname, 138 | int append, 139 | zipcharpc* globalcomment, 140 | zlib_filefunc_def* pzlib_filefunc_def)); 141 | 142 | extern zipFile ZEXPORT zipOpen2_64 OF((const void *pathname, 143 | int append, 144 | zipcharpc* globalcomment, 145 | zlib_filefunc64_def* pzlib_filefunc_def)); 146 | 147 | extern int ZEXPORT zipOpenNewFileInZip OF((zipFile file, 148 | const char* filename, 149 | const zip_fileinfo* zipfi, 150 | const void* extrafield_local, 151 | uInt size_extrafield_local, 152 | const void* extrafield_global, 153 | uInt size_extrafield_global, 154 | const char* comment, 155 | int method, 156 | int level)); 157 | 158 | extern int ZEXPORT zipOpenNewFileInZip64 OF((zipFile file, 159 | const char* filename, 160 | const zip_fileinfo* zipfi, 161 | const void* extrafield_local, 162 | uInt size_extrafield_local, 163 | const void* extrafield_global, 164 | uInt size_extrafield_global, 165 | const char* comment, 166 | int method, 167 | int level, 168 | int zip64)); 169 | 170 | /* 171 | Open a file in the ZIP for writing. 172 | filename : the filename in zip (if NULL, '-' without quote will be used 173 | *zipfi contain supplemental information 174 | if extrafield_local!=NULL and size_extrafield_local>0, extrafield_local 175 | contains the extrafield data the the local header 176 | if extrafield_global!=NULL and size_extrafield_global>0, extrafield_global 177 | contains the extrafield data the the local header 178 | if comment != NULL, comment contain the comment string 179 | method contain the compression method (0 for store, Z_DEFLATED for deflate) 180 | level contain the level of compression (can be Z_DEFAULT_COMPRESSION) 181 | zip64 is set to 1 if a zip64 extended information block should be added to the local file header. 182 | this MUST be '1' if the uncompressed size is >= 0xffffffff. 183 | 184 | */ 185 | 186 | 187 | extern int ZEXPORT zipOpenNewFileInZip2 OF((zipFile file, 188 | const char* filename, 189 | const zip_fileinfo* zipfi, 190 | const void* extrafield_local, 191 | uInt size_extrafield_local, 192 | const void* extrafield_global, 193 | uInt size_extrafield_global, 194 | const char* comment, 195 | int method, 196 | int level, 197 | int raw)); 198 | 199 | 200 | extern int ZEXPORT zipOpenNewFileInZip2_64 OF((zipFile file, 201 | const char* filename, 202 | const zip_fileinfo* zipfi, 203 | const void* extrafield_local, 204 | uInt size_extrafield_local, 205 | const void* extrafield_global, 206 | uInt size_extrafield_global, 207 | const char* comment, 208 | int method, 209 | int level, 210 | int raw, 211 | int zip64)); 212 | /* 213 | Same than zipOpenNewFileInZip, except if raw=1, we write raw file 214 | */ 215 | 216 | extern int ZEXPORT zipOpenNewFileInZip3 OF((zipFile file, 217 | const char* filename, 218 | const zip_fileinfo* zipfi, 219 | const void* extrafield_local, 220 | uInt size_extrafield_local, 221 | const void* extrafield_global, 222 | uInt size_extrafield_global, 223 | const char* comment, 224 | int method, 225 | int level, 226 | int raw, 227 | int windowBits, 228 | int memLevel, 229 | int strategy, 230 | const char* password, 231 | uLong crcForCrypting)); 232 | 233 | extern int ZEXPORT zipOpenNewFileInZip3_64 OF((zipFile file, 234 | const char* filename, 235 | const zip_fileinfo* zipfi, 236 | const void* extrafield_local, 237 | uInt size_extrafield_local, 238 | const void* extrafield_global, 239 | uInt size_extrafield_global, 240 | const char* comment, 241 | int method, 242 | int level, 243 | int raw, 244 | int windowBits, 245 | int memLevel, 246 | int strategy, 247 | const char* password, 248 | uLong crcForCrypting, 249 | int zip64 250 | )); 251 | 252 | /* 253 | Same than zipOpenNewFileInZip2, except 254 | windowBits,memLevel,,strategy : see parameter strategy in deflateInit2 255 | password : crypting password (NULL for no crypting) 256 | crcForCrypting : crc of file to compress (needed for crypting) 257 | */ 258 | 259 | extern int ZEXPORT zipOpenNewFileInZip4 OF((zipFile file, 260 | const char* filename, 261 | const zip_fileinfo* zipfi, 262 | const void* extrafield_local, 263 | uInt size_extrafield_local, 264 | const void* extrafield_global, 265 | uInt size_extrafield_global, 266 | const char* comment, 267 | int method, 268 | int level, 269 | int raw, 270 | int windowBits, 271 | int memLevel, 272 | int strategy, 273 | const char* password, 274 | uLong crcForCrypting, 275 | uLong versionMadeBy, 276 | uLong flagBase 277 | )); 278 | 279 | 280 | extern int ZEXPORT zipOpenNewFileInZip4_64 OF((zipFile file, 281 | const char* filename, 282 | const zip_fileinfo* zipfi, 283 | const void* extrafield_local, 284 | uInt size_extrafield_local, 285 | const void* extrafield_global, 286 | uInt size_extrafield_global, 287 | const char* comment, 288 | int method, 289 | int level, 290 | int raw, 291 | int windowBits, 292 | int memLevel, 293 | int strategy, 294 | const char* password, 295 | uLong crcForCrypting, 296 | uLong versionMadeBy, 297 | uLong flagBase, 298 | int zip64 299 | )); 300 | /* 301 | Same than zipOpenNewFileInZip4, except 302 | versionMadeBy : value for Version made by field 303 | flag : value for flag field (compression level info will be added) 304 | */ 305 | 306 | 307 | extern int ZEXPORT zipWriteInFileInZip OF((zipFile file, 308 | const void* buf, 309 | unsigned len)); 310 | /* 311 | Write data in the zipfile 312 | */ 313 | 314 | extern int ZEXPORT zipCloseFileInZip OF((zipFile file)); 315 | /* 316 | Close the current file in the zipfile 317 | */ 318 | 319 | extern int ZEXPORT zipCloseFileInZipRaw OF((zipFile file, 320 | uLong uncompressed_size, 321 | uLong crc32)); 322 | 323 | extern int ZEXPORT zipCloseFileInZipRaw64 OF((zipFile file, 324 | ZPOS64_T uncompressed_size, 325 | uLong crc32)); 326 | 327 | /* 328 | Close the current file in the zipfile, for file opened with 329 | parameter raw=1 in zipOpenNewFileInZip2 330 | uncompressed_size and crc32 are value for the uncompressed size 331 | */ 332 | 333 | extern int ZEXPORT zipClose OF((zipFile file, 334 | const char* global_comment)); 335 | /* 336 | Close the zipfile 337 | */ 338 | 339 | 340 | extern int ZEXPORT zipRemoveExtraInfoBlock OF((char* pData, int* dataLen, short sHeader)); 341 | /* 342 | zipRemoveExtraInfoBlock - Added by Mathias Svensson 343 | 344 | Remove extra information block from a extra information data for the local file header or central directory header 345 | 346 | It is needed to remove ZIP64 extra information blocks when before data is written if using RAW mode. 347 | 348 | 0x0001 is the signature header for the ZIP64 extra information blocks 349 | 350 | usage. 351 | Remove ZIP64 Extra information from a central director extra field data 352 | zipRemoveExtraInfoBlock(pCenDirExtraFieldData, &nCenDirExtraFieldDataLen, 0x0001); 353 | 354 | Remove ZIP64 Extra information from a Local File Header extra field data 355 | zipRemoveExtraInfoBlock(pLocalHeaderExtraFieldData, &nLocalHeaderExtraFieldDataLen, 0x0001); 356 | */ 357 | 358 | #ifdef __cplusplus 359 | } 360 | #endif 361 | 362 | #endif /* _zip64_H */ 363 | -------------------------------------------------------------------------------- /NSData+Encryption.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSData+Encryption.h 3 | // 4 | // 5 | // Copyright (c) 2015年 xxxxx. All rights reserved. 6 | //加密解密处理类 7 | 8 | #import 9 | 10 | @interface NSData (Encryption) 11 | - (NSData *)AES256ParmEncryptWithKey:(NSString *)key; 12 | - (NSData *)AES256ParmDecryptWithKey:(NSString *)key; 13 | 14 | - (NSData *)AES128ParmEncryptWithKey:(NSString *)key; 15 | - (NSData *)AES128ParmDecryptWithKey:(NSString *)key; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /NSData+Encryption.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSData+Encryption.m 3 | // 4 | // 5 | // Created by XXX on 15/1/8. 6 | // Copyright (c) 2015年 xxxxxx. All rights reserved. 7 | // 8 | 9 | #import "NSData+Encryption.h" 10 | #import 11 | @implementation NSData (Encryption) 12 | //加密 13 | - (NSData *)AES256ParmEncryptWithKey:(NSString *)key 14 | { 15 | char keyPtr[kCCKeySizeAES256+1]; 16 | bzero(keyPtr, sizeof(keyPtr)); 17 | [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding]; 18 | NSUInteger dataLength = [self length]; 19 | size_t bufferSize = dataLength + kCCBlockSizeAES128; 20 | void *buffer = malloc(bufferSize); 21 | size_t numBytesEncrypted = 0; 22 | CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128, 23 | kCCOptionPKCS7Padding | kCCOptionECBMode, 24 | keyPtr, kCCBlockSizeAES128, 25 | NULL, 26 | [self bytes], dataLength, 27 | buffer, bufferSize, 28 | &numBytesEncrypted); 29 | if (cryptStatus == kCCSuccess) { 30 | return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted]; 31 | } 32 | free(buffer); 33 | return nil; 34 | } 35 | 36 | - (NSData *)AES128ParmDecryptWithKey:(NSString *)key 37 | { 38 | char keyPtr[kCCKeySizeAES128 + 1]; 39 | bzero(keyPtr, sizeof(keyPtr)); 40 | [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding]; 41 | 42 | NSUInteger dataLength = [self length]; 43 | 44 | size_t bufferSize = dataLength + kCCBlockSizeAES128; 45 | void *buffer = malloc(bufferSize); 46 | 47 | size_t numBytesCrypted = 0; 48 | CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, 49 | kCCAlgorithmAES128, 50 | kCCOptionPKCS7Padding, 51 | keyPtr, 52 | kCCBlockSizeAES128, 53 | NULL, 54 | [self bytes], 55 | dataLength, 56 | buffer, 57 | bufferSize, 58 | &numBytesCrypted); 59 | if (cryptStatus == kCCSuccess) { 60 | return [NSData dataWithBytesNoCopy:buffer length:numBytesCrypted]; 61 | } 62 | free(buffer); 63 | return nil; 64 | } 65 | 66 | //解密 67 | - (NSData *)AES256ParmDecryptWithKey:(NSString *)key 68 | { 69 | char keyPtr[kCCKeySizeAES256+1]; 70 | bzero(keyPtr, sizeof(keyPtr)); 71 | [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding]; 72 | NSUInteger dataLength = [self length]; 73 | size_t bufferSize = dataLength + kCCBlockSizeAES128; 74 | void *buffer = malloc(bufferSize); 75 | size_t numBytesDecrypted = 0; 76 | CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128, 77 | kCCOptionPKCS7Padding | kCCOptionECBMode, 78 | keyPtr, kCCBlockSizeAES128, 79 | NULL, 80 | [self bytes], dataLength, 81 | buffer, bufferSize, 82 | &numBytesDecrypted); 83 | if (cryptStatus == kCCSuccess) { 84 | return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted]; 85 | } 86 | free(buffer); 87 | return nil; 88 | } 89 | 90 | - (NSData *)AES128ParmEncryptWithKey:(NSString *)key 91 | { 92 | char keyPtr[kCCKeySizeAES128+1]; 93 | memset(keyPtr, 0, sizeof(keyPtr)); 94 | [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding]; 95 | 96 | NSUInteger dataLength = [self length]; 97 | 98 | size_t bufferSize = dataLength + kCCBlockSizeAES128; 99 | void *buffer = malloc(bufferSize); 100 | size_t numBytesEncrypted = 0; 101 | CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, 102 | kCCAlgorithmAES128, 103 | kCCOptionPKCS7Padding, 104 | keyPtr, 105 | kCCBlockSizeAES128, 106 | NULL, 107 | [self bytes], 108 | dataLength, 109 | buffer, 110 | bufferSize, 111 | &numBytesEncrypted); 112 | if (cryptStatus == kCCSuccess) { 113 | return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted]; 114 | } 115 | free(buffer); 116 | return nil; 117 | } 118 | 119 | 120 | 121 | 122 | @end 123 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DynamicPatchManager 2 | 开源自己封装的JSPatch库,实现自动下载自动执行补丁等(包含执行脚本遇到crash情况处理) 3 | 4 | ##返回当前脚本 5 | - (NSString *)decryptPatchScript; 6 | 7 | ##执行本地MainBundle中的脚本 8 | - (void)evaluateScriptInMainBundleForName:(NSString *)name type:(NSString *)type; 9 | 10 | ##执行已经请求的最新脚本,Block返回脚本信息 11 | - (void)excutePatchScript:(DynamicPatchReturnBlock)completeBlock; 12 | 13 | ##请求最新脚本,Block返回脚本信息 14 | - (void)requestPatchScriptWithCompleteBlock:(DynamicPatchReturnBlock)completeBlock; 15 | 16 | 17 | --------------------------------------------------------------------------------