116c4d154dca43c662571129af31b27433b919a32Adam Lesinski/* 216c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Copyright (C) 2010 The Android Open Source Project 316c4d154dca43c662571129af31b27433b919a32Adam Lesinski * 416c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Licensed under the Apache License, Version 2.0 (the "License"); 516c4d154dca43c662571129af31b27433b919a32Adam Lesinski * you may not use this file except in compliance with the License. 616c4d154dca43c662571129af31b27433b919a32Adam Lesinski * You may obtain a copy of the License at 716c4d154dca43c662571129af31b27433b919a32Adam Lesinski * 816c4d154dca43c662571129af31b27433b919a32Adam Lesinski * http://www.apache.org/licenses/LICENSE-2.0 916c4d154dca43c662571129af31b27433b919a32Adam Lesinski * 1016c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Unless required by applicable law or agreed to in writing, software 1116c4d154dca43c662571129af31b27433b919a32Adam Lesinski * distributed under the License is distributed on an "AS IS" BASIS, 1216c4d154dca43c662571129af31b27433b919a32Adam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1316c4d154dca43c662571129af31b27433b919a32Adam Lesinski * See the License for the specific language governing permissions and 1416c4d154dca43c662571129af31b27433b919a32Adam Lesinski * limitations under the License. 1516c4d154dca43c662571129af31b27433b919a32Adam Lesinski */ 1616c4d154dca43c662571129af31b27433b919a32Adam Lesinski 1716c4d154dca43c662571129af31b27433b919a32Adam Lesinski#include <errno.h> 1816c4d154dca43c662571129af31b27433b919a32Adam Lesinski#include <fcntl.h> 1916c4d154dca43c662571129af31b27433b919a32Adam Lesinski#include <stdint.h> 2016c4d154dca43c662571129af31b27433b919a32Adam Lesinski#include <stdlib.h> 2116c4d154dca43c662571129af31b27433b919a32Adam Lesinski#include <string.h> 2216c4d154dca43c662571129af31b27433b919a32Adam Lesinski#include <unistd.h> 2316c4d154dca43c662571129af31b27433b919a32Adam Lesinski 2416c4d154dca43c662571129af31b27433b919a32Adam Lesinski#define LOG_TAG "ObbFile" 2516c4d154dca43c662571129af31b27433b919a32Adam Lesinski 2616c4d154dca43c662571129af31b27433b919a32Adam Lesinski#include <androidfw/ObbFile.h> 2716c4d154dca43c662571129af31b27433b919a32Adam Lesinski#include <utils/Compat.h> 2816c4d154dca43c662571129af31b27433b919a32Adam Lesinski#include <utils/Log.h> 2916c4d154dca43c662571129af31b27433b919a32Adam Lesinski 3016c4d154dca43c662571129af31b27433b919a32Adam Lesinski//#define DEBUG 1 3116c4d154dca43c662571129af31b27433b919a32Adam Lesinski 3216c4d154dca43c662571129af31b27433b919a32Adam Lesinski#define kFooterTagSize 8 /* last two 32-bit integers */ 3316c4d154dca43c662571129af31b27433b919a32Adam Lesinski 3416c4d154dca43c662571129af31b27433b919a32Adam Lesinski#define kFooterMinSize 33 /* 32-bit signature version (4 bytes) 3516c4d154dca43c662571129af31b27433b919a32Adam Lesinski * 32-bit package version (4 bytes) 3616c4d154dca43c662571129af31b27433b919a32Adam Lesinski * 32-bit flags (4 bytes) 3716c4d154dca43c662571129af31b27433b919a32Adam Lesinski * 64-bit salt (8 bytes) 3816c4d154dca43c662571129af31b27433b919a32Adam Lesinski * 32-bit package name size (4 bytes) 3916c4d154dca43c662571129af31b27433b919a32Adam Lesinski * >=1-character package name (1 byte) 4016c4d154dca43c662571129af31b27433b919a32Adam Lesinski * 32-bit footer size (4 bytes) 4116c4d154dca43c662571129af31b27433b919a32Adam Lesinski * 32-bit footer marker (4 bytes) 4216c4d154dca43c662571129af31b27433b919a32Adam Lesinski */ 4316c4d154dca43c662571129af31b27433b919a32Adam Lesinski 4416c4d154dca43c662571129af31b27433b919a32Adam Lesinski#define kMaxBufSize 32768 /* Maximum file read buffer */ 4516c4d154dca43c662571129af31b27433b919a32Adam Lesinski 4616c4d154dca43c662571129af31b27433b919a32Adam Lesinski#define kSignature 0x01059983U /* ObbFile signature */ 4716c4d154dca43c662571129af31b27433b919a32Adam Lesinski 4816c4d154dca43c662571129af31b27433b919a32Adam Lesinski#define kSigVersion 1 /* We only know about signature version 1 */ 4916c4d154dca43c662571129af31b27433b919a32Adam Lesinski 5016c4d154dca43c662571129af31b27433b919a32Adam Lesinski/* offsets in version 1 of the header */ 5116c4d154dca43c662571129af31b27433b919a32Adam Lesinski#define kPackageVersionOffset 4 5216c4d154dca43c662571129af31b27433b919a32Adam Lesinski#define kFlagsOffset 8 5316c4d154dca43c662571129af31b27433b919a32Adam Lesinski#define kSaltOffset 12 5416c4d154dca43c662571129af31b27433b919a32Adam Lesinski#define kPackageNameLenOffset 20 5516c4d154dca43c662571129af31b27433b919a32Adam Lesinski#define kPackageNameOffset 24 5616c4d154dca43c662571129af31b27433b919a32Adam Lesinski 5716c4d154dca43c662571129af31b27433b919a32Adam Lesinski/* 5816c4d154dca43c662571129af31b27433b919a32Adam Lesinski * TEMP_FAILURE_RETRY is defined by some, but not all, versions of 5916c4d154dca43c662571129af31b27433b919a32Adam Lesinski * <unistd.h>. (Alas, it is not as standard as we'd hoped!) So, if it's 6016c4d154dca43c662571129af31b27433b919a32Adam Lesinski * not already defined, then define it here. 6116c4d154dca43c662571129af31b27433b919a32Adam Lesinski */ 6216c4d154dca43c662571129af31b27433b919a32Adam Lesinski#ifndef TEMP_FAILURE_RETRY 6316c4d154dca43c662571129af31b27433b919a32Adam Lesinski/* Used to retry syscalls that can return EINTR. */ 6416c4d154dca43c662571129af31b27433b919a32Adam Lesinski#define TEMP_FAILURE_RETRY(exp) ({ \ 6516c4d154dca43c662571129af31b27433b919a32Adam Lesinski typeof (exp) _rc; \ 6616c4d154dca43c662571129af31b27433b919a32Adam Lesinski do { \ 6716c4d154dca43c662571129af31b27433b919a32Adam Lesinski _rc = (exp); \ 6816c4d154dca43c662571129af31b27433b919a32Adam Lesinski } while (_rc == -1 && errno == EINTR); \ 6916c4d154dca43c662571129af31b27433b919a32Adam Lesinski _rc; }) 7016c4d154dca43c662571129af31b27433b919a32Adam Lesinski#endif 7116c4d154dca43c662571129af31b27433b919a32Adam Lesinski 7216c4d154dca43c662571129af31b27433b919a32Adam Lesinski 7316c4d154dca43c662571129af31b27433b919a32Adam Lesinskinamespace android { 7416c4d154dca43c662571129af31b27433b919a32Adam Lesinski 7516c4d154dca43c662571129af31b27433b919a32Adam LesinskiObbFile::ObbFile() 7616c4d154dca43c662571129af31b27433b919a32Adam Lesinski : mPackageName("") 7716c4d154dca43c662571129af31b27433b919a32Adam Lesinski , mVersion(-1) 7816c4d154dca43c662571129af31b27433b919a32Adam Lesinski , mFlags(0) 7916c4d154dca43c662571129af31b27433b919a32Adam Lesinski{ 8016c4d154dca43c662571129af31b27433b919a32Adam Lesinski memset(mSalt, 0, sizeof(mSalt)); 8116c4d154dca43c662571129af31b27433b919a32Adam Lesinski} 8216c4d154dca43c662571129af31b27433b919a32Adam Lesinski 8316c4d154dca43c662571129af31b27433b919a32Adam LesinskiObbFile::~ObbFile() { 8416c4d154dca43c662571129af31b27433b919a32Adam Lesinski} 8516c4d154dca43c662571129af31b27433b919a32Adam Lesinski 8616c4d154dca43c662571129af31b27433b919a32Adam Lesinskibool ObbFile::readFrom(const char* filename) 8716c4d154dca43c662571129af31b27433b919a32Adam Lesinski{ 8816c4d154dca43c662571129af31b27433b919a32Adam Lesinski int fd; 8916c4d154dca43c662571129af31b27433b919a32Adam Lesinski bool success = false; 9016c4d154dca43c662571129af31b27433b919a32Adam Lesinski 9116c4d154dca43c662571129af31b27433b919a32Adam Lesinski fd = ::open(filename, O_RDONLY); 9216c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (fd < 0) { 9316c4d154dca43c662571129af31b27433b919a32Adam Lesinski ALOGW("couldn't open file %s: %s", filename, strerror(errno)); 9416c4d154dca43c662571129af31b27433b919a32Adam Lesinski goto out; 9516c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 9616c4d154dca43c662571129af31b27433b919a32Adam Lesinski success = readFrom(fd); 9716c4d154dca43c662571129af31b27433b919a32Adam Lesinski close(fd); 9816c4d154dca43c662571129af31b27433b919a32Adam Lesinski 9916c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (!success) { 10016c4d154dca43c662571129af31b27433b919a32Adam Lesinski ALOGW("failed to read from %s (fd=%d)\n", filename, fd); 10116c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 10216c4d154dca43c662571129af31b27433b919a32Adam Lesinski 10316c4d154dca43c662571129af31b27433b919a32Adam Lesinskiout: 10416c4d154dca43c662571129af31b27433b919a32Adam Lesinski return success; 10516c4d154dca43c662571129af31b27433b919a32Adam Lesinski} 10616c4d154dca43c662571129af31b27433b919a32Adam Lesinski 10716c4d154dca43c662571129af31b27433b919a32Adam Lesinskibool ObbFile::readFrom(int fd) 10816c4d154dca43c662571129af31b27433b919a32Adam Lesinski{ 10916c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (fd < 0) { 11016c4d154dca43c662571129af31b27433b919a32Adam Lesinski ALOGW("attempt to read from invalid fd\n"); 11116c4d154dca43c662571129af31b27433b919a32Adam Lesinski return false; 11216c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 11316c4d154dca43c662571129af31b27433b919a32Adam Lesinski 11416c4d154dca43c662571129af31b27433b919a32Adam Lesinski return parseObbFile(fd); 11516c4d154dca43c662571129af31b27433b919a32Adam Lesinski} 11616c4d154dca43c662571129af31b27433b919a32Adam Lesinski 11716c4d154dca43c662571129af31b27433b919a32Adam Lesinskibool ObbFile::parseObbFile(int fd) 11816c4d154dca43c662571129af31b27433b919a32Adam Lesinski{ 11916c4d154dca43c662571129af31b27433b919a32Adam Lesinski off64_t fileLength = lseek64(fd, 0, SEEK_END); 12016c4d154dca43c662571129af31b27433b919a32Adam Lesinski 12116c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (fileLength < kFooterMinSize) { 12216c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (fileLength < 0) { 12316c4d154dca43c662571129af31b27433b919a32Adam Lesinski ALOGW("error seeking in ObbFile: %s\n", strerror(errno)); 12416c4d154dca43c662571129af31b27433b919a32Adam Lesinski } else { 12516c4d154dca43c662571129af31b27433b919a32Adam Lesinski ALOGW("file is only %lld (less than %d minimum)\n", fileLength, kFooterMinSize); 12616c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 12716c4d154dca43c662571129af31b27433b919a32Adam Lesinski return false; 12816c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 12916c4d154dca43c662571129af31b27433b919a32Adam Lesinski 13016c4d154dca43c662571129af31b27433b919a32Adam Lesinski ssize_t actual; 13116c4d154dca43c662571129af31b27433b919a32Adam Lesinski size_t footerSize; 13216c4d154dca43c662571129af31b27433b919a32Adam Lesinski 13316c4d154dca43c662571129af31b27433b919a32Adam Lesinski { 13416c4d154dca43c662571129af31b27433b919a32Adam Lesinski lseek64(fd, fileLength - kFooterTagSize, SEEK_SET); 13516c4d154dca43c662571129af31b27433b919a32Adam Lesinski 136e1aa223657dd1def8609b377afa86a024bfd4e14Elliott Hughes char footer[kFooterTagSize]; 13716c4d154dca43c662571129af31b27433b919a32Adam Lesinski actual = TEMP_FAILURE_RETRY(read(fd, footer, kFooterTagSize)); 13816c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (actual != kFooterTagSize) { 13916c4d154dca43c662571129af31b27433b919a32Adam Lesinski ALOGW("couldn't read footer signature: %s\n", strerror(errno)); 14016c4d154dca43c662571129af31b27433b919a32Adam Lesinski return false; 14116c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 14216c4d154dca43c662571129af31b27433b919a32Adam Lesinski 14316c4d154dca43c662571129af31b27433b919a32Adam Lesinski unsigned int fileSig = get4LE((unsigned char*)footer + sizeof(int32_t)); 14416c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (fileSig != kSignature) { 14516c4d154dca43c662571129af31b27433b919a32Adam Lesinski ALOGW("footer didn't match magic string (expected 0x%08x; got 0x%08x)\n", 14616c4d154dca43c662571129af31b27433b919a32Adam Lesinski kSignature, fileSig); 14716c4d154dca43c662571129af31b27433b919a32Adam Lesinski return false; 14816c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 14916c4d154dca43c662571129af31b27433b919a32Adam Lesinski 15016c4d154dca43c662571129af31b27433b919a32Adam Lesinski footerSize = get4LE((unsigned char*)footer); 15116c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (footerSize > (size_t)fileLength - kFooterTagSize 15216c4d154dca43c662571129af31b27433b919a32Adam Lesinski || footerSize > kMaxBufSize) { 15316c4d154dca43c662571129af31b27433b919a32Adam Lesinski ALOGW("claimed footer size is too large (0x%08zx; file size is 0x%08llx)\n", 15416c4d154dca43c662571129af31b27433b919a32Adam Lesinski footerSize, fileLength); 15516c4d154dca43c662571129af31b27433b919a32Adam Lesinski return false; 15616c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 15716c4d154dca43c662571129af31b27433b919a32Adam Lesinski 15816c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (footerSize < (kFooterMinSize - kFooterTagSize)) { 15916c4d154dca43c662571129af31b27433b919a32Adam Lesinski ALOGW("claimed footer size is too small (0x%zx; minimum size is 0x%x)\n", 16016c4d154dca43c662571129af31b27433b919a32Adam Lesinski footerSize, kFooterMinSize - kFooterTagSize); 16116c4d154dca43c662571129af31b27433b919a32Adam Lesinski return false; 16216c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 16316c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 16416c4d154dca43c662571129af31b27433b919a32Adam Lesinski 16516c4d154dca43c662571129af31b27433b919a32Adam Lesinski off64_t fileOffset = fileLength - footerSize - kFooterTagSize; 16616c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (lseek64(fd, fileOffset, SEEK_SET) != fileOffset) { 16716c4d154dca43c662571129af31b27433b919a32Adam Lesinski ALOGW("seek %lld failed: %s\n", fileOffset, strerror(errno)); 16816c4d154dca43c662571129af31b27433b919a32Adam Lesinski return false; 16916c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 17016c4d154dca43c662571129af31b27433b919a32Adam Lesinski 17116c4d154dca43c662571129af31b27433b919a32Adam Lesinski mFooterStart = fileOffset; 17216c4d154dca43c662571129af31b27433b919a32Adam Lesinski 17316c4d154dca43c662571129af31b27433b919a32Adam Lesinski char* scanBuf = (char*)malloc(footerSize); 17416c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (scanBuf == NULL) { 17516c4d154dca43c662571129af31b27433b919a32Adam Lesinski ALOGW("couldn't allocate scanBuf: %s\n", strerror(errno)); 17616c4d154dca43c662571129af31b27433b919a32Adam Lesinski return false; 17716c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 17816c4d154dca43c662571129af31b27433b919a32Adam Lesinski 17916c4d154dca43c662571129af31b27433b919a32Adam Lesinski actual = TEMP_FAILURE_RETRY(read(fd, scanBuf, footerSize)); 18016c4d154dca43c662571129af31b27433b919a32Adam Lesinski // readAmount is guaranteed to be less than kMaxBufSize 18116c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (actual != (ssize_t)footerSize) { 18216c4d154dca43c662571129af31b27433b919a32Adam Lesinski ALOGI("couldn't read ObbFile footer: %s\n", strerror(errno)); 18316c4d154dca43c662571129af31b27433b919a32Adam Lesinski free(scanBuf); 18416c4d154dca43c662571129af31b27433b919a32Adam Lesinski return false; 18516c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 18616c4d154dca43c662571129af31b27433b919a32Adam Lesinski 18716c4d154dca43c662571129af31b27433b919a32Adam Lesinski#ifdef DEBUG 18816c4d154dca43c662571129af31b27433b919a32Adam Lesinski for (int i = 0; i < footerSize; ++i) { 18916c4d154dca43c662571129af31b27433b919a32Adam Lesinski ALOGI("char: 0x%02x\n", scanBuf[i]); 19016c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 19116c4d154dca43c662571129af31b27433b919a32Adam Lesinski#endif 19216c4d154dca43c662571129af31b27433b919a32Adam Lesinski 19316c4d154dca43c662571129af31b27433b919a32Adam Lesinski uint32_t sigVersion = get4LE((unsigned char*)scanBuf); 19416c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (sigVersion != kSigVersion) { 19516c4d154dca43c662571129af31b27433b919a32Adam Lesinski ALOGW("Unsupported ObbFile version %d\n", sigVersion); 19616c4d154dca43c662571129af31b27433b919a32Adam Lesinski free(scanBuf); 19716c4d154dca43c662571129af31b27433b919a32Adam Lesinski return false; 19816c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 19916c4d154dca43c662571129af31b27433b919a32Adam Lesinski 20016c4d154dca43c662571129af31b27433b919a32Adam Lesinski mVersion = (int32_t) get4LE((unsigned char*)scanBuf + kPackageVersionOffset); 20116c4d154dca43c662571129af31b27433b919a32Adam Lesinski mFlags = (int32_t) get4LE((unsigned char*)scanBuf + kFlagsOffset); 20216c4d154dca43c662571129af31b27433b919a32Adam Lesinski 20316c4d154dca43c662571129af31b27433b919a32Adam Lesinski memcpy(&mSalt, (unsigned char*)scanBuf + kSaltOffset, sizeof(mSalt)); 20416c4d154dca43c662571129af31b27433b919a32Adam Lesinski 20516c4d154dca43c662571129af31b27433b919a32Adam Lesinski size_t packageNameLen = get4LE((unsigned char*)scanBuf + kPackageNameLenOffset); 20616c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (packageNameLen == 0 20716c4d154dca43c662571129af31b27433b919a32Adam Lesinski || packageNameLen > (footerSize - kPackageNameOffset)) { 20816c4d154dca43c662571129af31b27433b919a32Adam Lesinski ALOGW("bad ObbFile package name length (0x%04zx; 0x%04zx possible)\n", 20916c4d154dca43c662571129af31b27433b919a32Adam Lesinski packageNameLen, footerSize - kPackageNameOffset); 21016c4d154dca43c662571129af31b27433b919a32Adam Lesinski free(scanBuf); 21116c4d154dca43c662571129af31b27433b919a32Adam Lesinski return false; 21216c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 21316c4d154dca43c662571129af31b27433b919a32Adam Lesinski 21416c4d154dca43c662571129af31b27433b919a32Adam Lesinski char* packageName = reinterpret_cast<char*>(scanBuf + kPackageNameOffset); 21516c4d154dca43c662571129af31b27433b919a32Adam Lesinski mPackageName = String8(const_cast<char*>(packageName), packageNameLen); 21616c4d154dca43c662571129af31b27433b919a32Adam Lesinski 21716c4d154dca43c662571129af31b27433b919a32Adam Lesinski free(scanBuf); 21816c4d154dca43c662571129af31b27433b919a32Adam Lesinski 21916c4d154dca43c662571129af31b27433b919a32Adam Lesinski#ifdef DEBUG 22016c4d154dca43c662571129af31b27433b919a32Adam Lesinski ALOGI("Obb scan succeeded: packageName=%s, version=%d\n", mPackageName.string(), mVersion); 22116c4d154dca43c662571129af31b27433b919a32Adam Lesinski#endif 22216c4d154dca43c662571129af31b27433b919a32Adam Lesinski 22316c4d154dca43c662571129af31b27433b919a32Adam Lesinski return true; 22416c4d154dca43c662571129af31b27433b919a32Adam Lesinski} 22516c4d154dca43c662571129af31b27433b919a32Adam Lesinski 22616c4d154dca43c662571129af31b27433b919a32Adam Lesinskibool ObbFile::writeTo(const char* filename) 22716c4d154dca43c662571129af31b27433b919a32Adam Lesinski{ 22816c4d154dca43c662571129af31b27433b919a32Adam Lesinski int fd; 22916c4d154dca43c662571129af31b27433b919a32Adam Lesinski bool success = false; 23016c4d154dca43c662571129af31b27433b919a32Adam Lesinski 23116c4d154dca43c662571129af31b27433b919a32Adam Lesinski fd = ::open(filename, O_WRONLY); 23216c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (fd < 0) { 23316c4d154dca43c662571129af31b27433b919a32Adam Lesinski goto out; 23416c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 23516c4d154dca43c662571129af31b27433b919a32Adam Lesinski success = writeTo(fd); 23616c4d154dca43c662571129af31b27433b919a32Adam Lesinski close(fd); 23716c4d154dca43c662571129af31b27433b919a32Adam Lesinski 23816c4d154dca43c662571129af31b27433b919a32Adam Lesinskiout: 23916c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (!success) { 24016c4d154dca43c662571129af31b27433b919a32Adam Lesinski ALOGW("failed to write to %s: %s\n", filename, strerror(errno)); 24116c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 24216c4d154dca43c662571129af31b27433b919a32Adam Lesinski return success; 24316c4d154dca43c662571129af31b27433b919a32Adam Lesinski} 24416c4d154dca43c662571129af31b27433b919a32Adam Lesinski 24516c4d154dca43c662571129af31b27433b919a32Adam Lesinskibool ObbFile::writeTo(int fd) 24616c4d154dca43c662571129af31b27433b919a32Adam Lesinski{ 24716c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (fd < 0) { 24816c4d154dca43c662571129af31b27433b919a32Adam Lesinski return false; 24916c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 25016c4d154dca43c662571129af31b27433b919a32Adam Lesinski 25116c4d154dca43c662571129af31b27433b919a32Adam Lesinski lseek64(fd, 0, SEEK_END); 25216c4d154dca43c662571129af31b27433b919a32Adam Lesinski 25316c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (mPackageName.size() == 0 || mVersion == -1) { 25416c4d154dca43c662571129af31b27433b919a32Adam Lesinski ALOGW("tried to write uninitialized ObbFile data\n"); 25516c4d154dca43c662571129af31b27433b919a32Adam Lesinski return false; 25616c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 25716c4d154dca43c662571129af31b27433b919a32Adam Lesinski 25816c4d154dca43c662571129af31b27433b919a32Adam Lesinski unsigned char intBuf[sizeof(uint32_t)+1]; 25916c4d154dca43c662571129af31b27433b919a32Adam Lesinski memset(&intBuf, 0, sizeof(intBuf)); 26016c4d154dca43c662571129af31b27433b919a32Adam Lesinski 26116c4d154dca43c662571129af31b27433b919a32Adam Lesinski put4LE(intBuf, kSigVersion); 26216c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) { 26316c4d154dca43c662571129af31b27433b919a32Adam Lesinski ALOGW("couldn't write signature version: %s\n", strerror(errno)); 26416c4d154dca43c662571129af31b27433b919a32Adam Lesinski return false; 26516c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 26616c4d154dca43c662571129af31b27433b919a32Adam Lesinski 26716c4d154dca43c662571129af31b27433b919a32Adam Lesinski put4LE(intBuf, mVersion); 26816c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) { 26916c4d154dca43c662571129af31b27433b919a32Adam Lesinski ALOGW("couldn't write package version\n"); 27016c4d154dca43c662571129af31b27433b919a32Adam Lesinski return false; 27116c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 27216c4d154dca43c662571129af31b27433b919a32Adam Lesinski 27316c4d154dca43c662571129af31b27433b919a32Adam Lesinski put4LE(intBuf, mFlags); 27416c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) { 27516c4d154dca43c662571129af31b27433b919a32Adam Lesinski ALOGW("couldn't write package version\n"); 27616c4d154dca43c662571129af31b27433b919a32Adam Lesinski return false; 27716c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 27816c4d154dca43c662571129af31b27433b919a32Adam Lesinski 27916c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (write(fd, mSalt, sizeof(mSalt)) != (ssize_t)sizeof(mSalt)) { 28016c4d154dca43c662571129af31b27433b919a32Adam Lesinski ALOGW("couldn't write salt: %s\n", strerror(errno)); 28116c4d154dca43c662571129af31b27433b919a32Adam Lesinski return false; 28216c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 28316c4d154dca43c662571129af31b27433b919a32Adam Lesinski 28416c4d154dca43c662571129af31b27433b919a32Adam Lesinski size_t packageNameLen = mPackageName.size(); 28516c4d154dca43c662571129af31b27433b919a32Adam Lesinski put4LE(intBuf, packageNameLen); 28616c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) { 28716c4d154dca43c662571129af31b27433b919a32Adam Lesinski ALOGW("couldn't write package name length: %s\n", strerror(errno)); 28816c4d154dca43c662571129af31b27433b919a32Adam Lesinski return false; 28916c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 29016c4d154dca43c662571129af31b27433b919a32Adam Lesinski 29116c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (write(fd, mPackageName.string(), packageNameLen) != (ssize_t)packageNameLen) { 29216c4d154dca43c662571129af31b27433b919a32Adam Lesinski ALOGW("couldn't write package name: %s\n", strerror(errno)); 29316c4d154dca43c662571129af31b27433b919a32Adam Lesinski return false; 29416c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 29516c4d154dca43c662571129af31b27433b919a32Adam Lesinski 29616c4d154dca43c662571129af31b27433b919a32Adam Lesinski put4LE(intBuf, kPackageNameOffset + packageNameLen); 29716c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) { 29816c4d154dca43c662571129af31b27433b919a32Adam Lesinski ALOGW("couldn't write footer size: %s\n", strerror(errno)); 29916c4d154dca43c662571129af31b27433b919a32Adam Lesinski return false; 30016c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 30116c4d154dca43c662571129af31b27433b919a32Adam Lesinski 30216c4d154dca43c662571129af31b27433b919a32Adam Lesinski put4LE(intBuf, kSignature); 30316c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) { 30416c4d154dca43c662571129af31b27433b919a32Adam Lesinski ALOGW("couldn't write footer magic signature: %s\n", strerror(errno)); 30516c4d154dca43c662571129af31b27433b919a32Adam Lesinski return false; 30616c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 30716c4d154dca43c662571129af31b27433b919a32Adam Lesinski 30816c4d154dca43c662571129af31b27433b919a32Adam Lesinski return true; 30916c4d154dca43c662571129af31b27433b919a32Adam Lesinski} 31016c4d154dca43c662571129af31b27433b919a32Adam Lesinski 31116c4d154dca43c662571129af31b27433b919a32Adam Lesinskibool ObbFile::removeFrom(const char* filename) 31216c4d154dca43c662571129af31b27433b919a32Adam Lesinski{ 31316c4d154dca43c662571129af31b27433b919a32Adam Lesinski int fd; 31416c4d154dca43c662571129af31b27433b919a32Adam Lesinski bool success = false; 31516c4d154dca43c662571129af31b27433b919a32Adam Lesinski 31616c4d154dca43c662571129af31b27433b919a32Adam Lesinski fd = ::open(filename, O_RDWR); 31716c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (fd < 0) { 31816c4d154dca43c662571129af31b27433b919a32Adam Lesinski goto out; 31916c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 32016c4d154dca43c662571129af31b27433b919a32Adam Lesinski success = removeFrom(fd); 32116c4d154dca43c662571129af31b27433b919a32Adam Lesinski close(fd); 32216c4d154dca43c662571129af31b27433b919a32Adam Lesinski 32316c4d154dca43c662571129af31b27433b919a32Adam Lesinskiout: 32416c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (!success) { 32516c4d154dca43c662571129af31b27433b919a32Adam Lesinski ALOGW("failed to remove signature from %s: %s\n", filename, strerror(errno)); 32616c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 32716c4d154dca43c662571129af31b27433b919a32Adam Lesinski return success; 32816c4d154dca43c662571129af31b27433b919a32Adam Lesinski} 32916c4d154dca43c662571129af31b27433b919a32Adam Lesinski 33016c4d154dca43c662571129af31b27433b919a32Adam Lesinskibool ObbFile::removeFrom(int fd) 33116c4d154dca43c662571129af31b27433b919a32Adam Lesinski{ 33216c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (fd < 0) { 33316c4d154dca43c662571129af31b27433b919a32Adam Lesinski return false; 33416c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 33516c4d154dca43c662571129af31b27433b919a32Adam Lesinski 33616c4d154dca43c662571129af31b27433b919a32Adam Lesinski if (!readFrom(fd)) { 33716c4d154dca43c662571129af31b27433b919a32Adam Lesinski return false; 33816c4d154dca43c662571129af31b27433b919a32Adam Lesinski } 33916c4d154dca43c662571129af31b27433b919a32Adam Lesinski 34016c4d154dca43c662571129af31b27433b919a32Adam Lesinski ftruncate(fd, mFooterStart); 34116c4d154dca43c662571129af31b27433b919a32Adam Lesinski 34216c4d154dca43c662571129af31b27433b919a32Adam Lesinski return true; 34316c4d154dca43c662571129af31b27433b919a32Adam Lesinski} 34416c4d154dca43c662571129af31b27433b919a32Adam Lesinski 34516c4d154dca43c662571129af31b27433b919a32Adam Lesinski} 346