ObbFile.cpp revision 3b1abba6bbc895d63da3e82e9b158c01bd12eddd
17cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root/* 27cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root * Copyright (C) 2010 The Android Open Source Project 37cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root * 47cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root * Licensed under the Apache License, Version 2.0 (the "License"); 57cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root * you may not use this file except in compliance with the License. 67cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root * You may obtain a copy of the License at 77cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root * 87cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root * http://www.apache.org/licenses/LICENSE-2.0 97cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root * 107cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root * Unless required by applicable law or agreed to in writing, software 117cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root * distributed under the License is distributed on an "AS IS" BASIS, 127cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 137cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root * See the License for the specific language governing permissions and 147cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root * limitations under the License. 157cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root */ 167cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root 177cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root#include <errno.h> 187cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root#include <fcntl.h> 197cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root#include <stdint.h> 207cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root#include <stdlib.h> 217cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root#include <string.h> 227cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root#include <unistd.h> 237cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root 247cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root#define LOG_TAG "ObbFile" 257cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root#include <utils/Log.h> 267cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root#include <utils/ObbFile.h> 277cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root 287cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root//#define DEBUG 1 297cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root 307cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root#define kFooterTagSize 8 /* last two 32-bit integers */ 317cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root 323b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root#define kFooterMinSize 33 /* 32-bit signature version (4 bytes) 3302ca31fbae9f35dd30f79de6927fae11b549391aKenny Root * 32-bit package version (4 bytes) 3402ca31fbae9f35dd30f79de6927fae11b549391aKenny Root * 32-bit flags (4 bytes) 353b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root * 64-bit salt (8 bytes) 363b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root * 32-bit package name size (4 bytes) 3702ca31fbae9f35dd30f79de6927fae11b549391aKenny Root * >=1-character package name (1 byte) 3802ca31fbae9f35dd30f79de6927fae11b549391aKenny Root * 32-bit footer size (4 bytes) 3902ca31fbae9f35dd30f79de6927fae11b549391aKenny Root * 32-bit footer marker (4 bytes) 407cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root */ 417cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root 427cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root#define kMaxBufSize 32768 /* Maximum file read buffer */ 437cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root 447cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root#define kSignature 0x01059983U /* ObbFile signature */ 457cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root 467cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root#define kSigVersion 1 /* We only know about signature version 1 */ 477cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root 487cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root/* offsets in version 1 of the header */ 497cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root#define kPackageVersionOffset 4 5002ca31fbae9f35dd30f79de6927fae11b549391aKenny Root#define kFlagsOffset 8 513b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root#define kSaltOffset 12 523b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root#define kPackageNameLenOffset 20 533b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root#define kPackageNameOffset 24 547cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root 557cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root/* 567cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root * TEMP_FAILURE_RETRY is defined by some, but not all, versions of 577cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root * <unistd.h>. (Alas, it is not as standard as we'd hoped!) So, if it's 587cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root * not already defined, then define it here. 597cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root */ 607cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root#ifndef TEMP_FAILURE_RETRY 617cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root/* Used to retry syscalls that can return EINTR. */ 627cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root#define TEMP_FAILURE_RETRY(exp) ({ \ 637cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root typeof (exp) _rc; \ 647cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root do { \ 657cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root _rc = (exp); \ 667cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root } while (_rc == -1 && errno == EINTR); \ 677cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root _rc; }) 687cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root#endif 697cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root 707cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root/* 717cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root * Work around situations where off_t is 64-bit and use off64_t in 727cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root * situations where it's 32-bit. 737cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root */ 747cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root#ifdef OFF_T_IS_64_BIT 757cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root#define my_lseek64 lseek 767cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Roottypedef off_t my_off64_t; 777cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root#else 787cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root#define my_lseek64 lseek64 797cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Roottypedef off64_t my_off64_t; 807cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root#endif 817cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root 827cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Rootnamespace android { 837cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root 843b1abba6bbc895d63da3e82e9b158c01bd12edddKenny RootObbFile::ObbFile() 853b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root : mPackageName("") 863b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root , mVersion(-1) 873b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root , mFlags(0) 8802ca31fbae9f35dd30f79de6927fae11b549391aKenny Root{ 893b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root memset(mSalt, 0, sizeof(mSalt)); 907cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root} 917cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root 927cee34a051eb0087322c8b965e498f88b1aa52d3Kenny RootObbFile::~ObbFile() { 937cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root} 947cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root 957cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Rootbool ObbFile::readFrom(const char* filename) 967cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root{ 977cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root int fd; 987cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root bool success = false; 997cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root 1007cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root fd = ::open(filename, O_RDONLY); 1017cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root if (fd < 0) { 10287315aa1f0b64efcef416628215be89851cc4736Kenny Root LOGW("couldn't open file %s: %s", filename, strerror(errno)); 1037cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root goto out; 1047cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root } 1057cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root success = readFrom(fd); 1067cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root close(fd); 1077cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root 1087cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root if (!success) { 10987315aa1f0b64efcef416628215be89851cc4736Kenny Root LOGW("failed to read from %s (fd=%d)\n", filename, fd); 1107cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root } 11187315aa1f0b64efcef416628215be89851cc4736Kenny Root 11287315aa1f0b64efcef416628215be89851cc4736Kenny Rootout: 1137cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root return success; 1147cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root} 1157cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root 1167cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Rootbool ObbFile::readFrom(int fd) 1177cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root{ 1187cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root if (fd < 0) { 11987315aa1f0b64efcef416628215be89851cc4736Kenny Root LOGW("attempt to read from invalid fd\n"); 1207cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root return false; 1217cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root } 1227cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root 1237cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root return parseObbFile(fd); 1247cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root} 1257cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root 1267cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Rootbool ObbFile::parseObbFile(int fd) 1277cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root{ 1287cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root my_off64_t fileLength = my_lseek64(fd, 0, SEEK_END); 1297cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root 1307cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root if (fileLength < kFooterMinSize) { 1317cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root if (fileLength < 0) { 1327cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root LOGW("error seeking in ObbFile: %s\n", strerror(errno)); 1337cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root } else { 1347cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root LOGW("file is only %lld (less than %d minimum)\n", fileLength, kFooterMinSize); 1357cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root } 1367cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root return false; 1377cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root } 1387cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root 1397cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root ssize_t actual; 1407cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root size_t footerSize; 1417cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root 1427cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root { 1437cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root my_lseek64(fd, fileLength - kFooterTagSize, SEEK_SET); 1447cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root 1457cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root char *footer = new char[kFooterTagSize]; 1467cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root actual = TEMP_FAILURE_RETRY(read(fd, footer, kFooterTagSize)); 1477cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root if (actual != kFooterTagSize) { 1487cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root LOGW("couldn't read footer signature: %s\n", strerror(errno)); 1497cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root return false; 1507cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root } 1517cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root 1527cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root unsigned int fileSig = get4LE((unsigned char*)footer + sizeof(int32_t)); 1537cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root if (fileSig != kSignature) { 1547cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root LOGW("footer didn't match magic string (expected 0x%08x; got 0x%08x)\n", 1557cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root kSignature, fileSig); 1567cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root return false; 1577cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root } 1587cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root 1597cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root footerSize = get4LE((unsigned char*)footer); 1607cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root if (footerSize > (size_t)fileLength - kFooterTagSize 1617cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root || footerSize > kMaxBufSize) { 16287315aa1f0b64efcef416628215be89851cc4736Kenny Root LOGW("claimed footer size is too large (0x%08zx; file size is 0x%08llx)\n", 1637cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root footerSize, fileLength); 1647cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root return false; 1657cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root } 16687315aa1f0b64efcef416628215be89851cc4736Kenny Root 1676e7ac5f0bceddf51947fbf3b376e278df0735603Kenny Root if (footerSize < (kFooterMinSize - kFooterTagSize)) { 1686e7ac5f0bceddf51947fbf3b376e278df0735603Kenny Root LOGW("claimed footer size is too small (0x%zx; minimum size is 0x%x)\n", 1696e7ac5f0bceddf51947fbf3b376e278df0735603Kenny Root footerSize, kFooterMinSize - kFooterTagSize); 17087315aa1f0b64efcef416628215be89851cc4736Kenny Root return false; 17187315aa1f0b64efcef416628215be89851cc4736Kenny Root } 1727cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root } 1737cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root 1747cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root my_off64_t fileOffset = fileLength - footerSize - kFooterTagSize; 1757cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root if (my_lseek64(fd, fileOffset, SEEK_SET) != fileOffset) { 1767cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root LOGW("seek %lld failed: %s\n", fileOffset, strerror(errno)); 1777cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root return false; 1787cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root } 1797cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root 1806e7ac5f0bceddf51947fbf3b376e278df0735603Kenny Root mFooterStart = fileOffset; 1816e7ac5f0bceddf51947fbf3b376e278df0735603Kenny Root 18287315aa1f0b64efcef416628215be89851cc4736Kenny Root char* scanBuf = (char*)malloc(footerSize); 1837cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root if (scanBuf == NULL) { 1847cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root LOGW("couldn't allocate scanBuf: %s\n", strerror(errno)); 1857cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root return false; 1867cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root } 1877cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root 18887315aa1f0b64efcef416628215be89851cc4736Kenny Root actual = TEMP_FAILURE_RETRY(read(fd, scanBuf, footerSize)); 1897cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root // readAmount is guaranteed to be less than kMaxBufSize 19087315aa1f0b64efcef416628215be89851cc4736Kenny Root if (actual != (ssize_t)footerSize) { 1917cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root LOGI("couldn't read ObbFile footer: %s\n", strerror(errno)); 1927cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root free(scanBuf); 1937cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root return false; 1947cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root } 1957cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root 1967cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root#ifdef DEBUG 19787315aa1f0b64efcef416628215be89851cc4736Kenny Root for (int i = 0; i < footerSize; ++i) { 1983b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root LOGI("char: 0x%02x\n", scanBuf[i]); 1997cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root } 2007cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root#endif 2017cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root 2027cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root uint32_t sigVersion = get4LE((unsigned char*)scanBuf); 2037cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root if (sigVersion != kSigVersion) { 2047cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root LOGW("Unsupported ObbFile version %d\n", sigVersion); 2057cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root free(scanBuf); 2067cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root return false; 2077cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root } 2087cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root 2097cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root mVersion = (int32_t) get4LE((unsigned char*)scanBuf + kPackageVersionOffset); 21002ca31fbae9f35dd30f79de6927fae11b549391aKenny Root mFlags = (int32_t) get4LE((unsigned char*)scanBuf + kFlagsOffset); 2117cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root 2123b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root memcpy(&mSalt, (unsigned char*)scanBuf + kSaltOffset, sizeof(mSalt)); 2133b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root 2147cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root uint32_t packageNameLen = get4LE((unsigned char*)scanBuf + kPackageNameLenOffset); 2157cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root if (packageNameLen <= 0 2167cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root || packageNameLen > (footerSize - kPackageNameOffset)) { 21787315aa1f0b64efcef416628215be89851cc4736Kenny Root LOGW("bad ObbFile package name length (0x%04x; 0x%04x possible)\n", 21887315aa1f0b64efcef416628215be89851cc4736Kenny Root packageNameLen, footerSize - kPackageNameOffset); 2197cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root free(scanBuf); 2207cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root return false; 2217cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root } 2227cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root 2237cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root char* packageName = reinterpret_cast<char*>(scanBuf + kPackageNameOffset); 2247cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root mPackageName = String8(const_cast<char*>(packageName), packageNameLen); 2257cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root 2267cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root free(scanBuf); 22787315aa1f0b64efcef416628215be89851cc4736Kenny Root 22887315aa1f0b64efcef416628215be89851cc4736Kenny Root#ifdef DEBUG 22987315aa1f0b64efcef416628215be89851cc4736Kenny Root LOGI("Obb scan succeeded: packageName=%s, version=%d\n", mPackageName.string(), mVersion); 23087315aa1f0b64efcef416628215be89851cc4736Kenny Root#endif 23187315aa1f0b64efcef416628215be89851cc4736Kenny Root 2327cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root return true; 2337cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root} 2347cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root 2357cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Rootbool ObbFile::writeTo(const char* filename) 2367cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root{ 2377cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root int fd; 2387cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root bool success = false; 2397cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root 2407cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root fd = ::open(filename, O_WRONLY); 2417cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root if (fd < 0) { 2427cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root goto out; 2437cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root } 2447cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root success = writeTo(fd); 2457cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root close(fd); 2467cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root 2477cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Rootout: 2487cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root if (!success) { 2497cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root LOGW("failed to write to %s: %s\n", filename, strerror(errno)); 2507cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root } 2517cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root return success; 2527cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root} 2537cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root 2547cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Rootbool ObbFile::writeTo(int fd) 2557cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root{ 2567cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root if (fd < 0) { 2577cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root return false; 2587cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root } 2597cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root 26087315aa1f0b64efcef416628215be89851cc4736Kenny Root my_lseek64(fd, 0, SEEK_END); 26187315aa1f0b64efcef416628215be89851cc4736Kenny Root 2627cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root if (mPackageName.size() == 0 || mVersion == -1) { 2633b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root LOGW("tried to write uninitialized ObbFile data\n"); 2647cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root return false; 2657cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root } 2667cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root 2677cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root unsigned char intBuf[sizeof(uint32_t)+1]; 2687cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root memset(&intBuf, 0, sizeof(intBuf)); 2697cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root 2707cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root put4LE(intBuf, kSigVersion); 2717cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) { 2723b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root LOGW("couldn't write signature version: %s\n", strerror(errno)); 2737cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root return false; 2747cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root } 2757cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root 2767cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root put4LE(intBuf, mVersion); 2777cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) { 2783b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root LOGW("couldn't write package version\n"); 2797cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root return false; 2807cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root } 2817cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root 28202ca31fbae9f35dd30f79de6927fae11b549391aKenny Root put4LE(intBuf, mFlags); 28302ca31fbae9f35dd30f79de6927fae11b549391aKenny Root if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) { 2843b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root LOGW("couldn't write package version\n"); 2853b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root return false; 2863b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root } 2873b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root 2883b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root if (write(fd, mSalt, sizeof(mSalt)) != (ssize_t)sizeof(mSalt)) { 2893b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root LOGW("couldn't write salt: %s\n", strerror(errno)); 29002ca31fbae9f35dd30f79de6927fae11b549391aKenny Root return false; 29102ca31fbae9f35dd30f79de6927fae11b549391aKenny Root } 29202ca31fbae9f35dd30f79de6927fae11b549391aKenny Root 2937cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root size_t packageNameLen = mPackageName.size(); 2947cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root put4LE(intBuf, packageNameLen); 2957cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) { 2963b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root LOGW("couldn't write package name length: %s\n", strerror(errno)); 2977cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root return false; 2987cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root } 2997cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root 3007cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root if (write(fd, mPackageName.string(), packageNameLen) != (ssize_t)packageNameLen) { 3013b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root LOGW("couldn't write package name: %s\n", strerror(errno)); 3027cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root return false; 3037cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root } 3047cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root 30502ca31fbae9f35dd30f79de6927fae11b549391aKenny Root put4LE(intBuf, kPackageNameOffset + packageNameLen); 3067cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) { 3073b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root LOGW("couldn't write footer size: %s\n", strerror(errno)); 3087cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root return false; 3097cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root } 3107cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root 3117cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root put4LE(intBuf, kSignature); 3127cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) { 3133b1abba6bbc895d63da3e82e9b158c01bd12edddKenny Root LOGW("couldn't write footer magic signature: %s\n", strerror(errno)); 3147cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root return false; 3157cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root } 3167cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root 3177cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root return true; 3187cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root} 3197cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root 3206e7ac5f0bceddf51947fbf3b376e278df0735603Kenny Rootbool ObbFile::removeFrom(const char* filename) 3216e7ac5f0bceddf51947fbf3b376e278df0735603Kenny Root{ 3226e7ac5f0bceddf51947fbf3b376e278df0735603Kenny Root int fd; 3236e7ac5f0bceddf51947fbf3b376e278df0735603Kenny Root bool success = false; 3246e7ac5f0bceddf51947fbf3b376e278df0735603Kenny Root 3256e7ac5f0bceddf51947fbf3b376e278df0735603Kenny Root fd = ::open(filename, O_RDWR); 3266e7ac5f0bceddf51947fbf3b376e278df0735603Kenny Root if (fd < 0) { 3276e7ac5f0bceddf51947fbf3b376e278df0735603Kenny Root goto out; 3286e7ac5f0bceddf51947fbf3b376e278df0735603Kenny Root } 3296e7ac5f0bceddf51947fbf3b376e278df0735603Kenny Root success = removeFrom(fd); 3306e7ac5f0bceddf51947fbf3b376e278df0735603Kenny Root close(fd); 3316e7ac5f0bceddf51947fbf3b376e278df0735603Kenny Root 3326e7ac5f0bceddf51947fbf3b376e278df0735603Kenny Rootout: 3336e7ac5f0bceddf51947fbf3b376e278df0735603Kenny Root if (!success) { 3346e7ac5f0bceddf51947fbf3b376e278df0735603Kenny Root LOGW("failed to remove signature from %s: %s\n", filename, strerror(errno)); 3356e7ac5f0bceddf51947fbf3b376e278df0735603Kenny Root } 3366e7ac5f0bceddf51947fbf3b376e278df0735603Kenny Root return success; 3376e7ac5f0bceddf51947fbf3b376e278df0735603Kenny Root} 3386e7ac5f0bceddf51947fbf3b376e278df0735603Kenny Root 3396e7ac5f0bceddf51947fbf3b376e278df0735603Kenny Rootbool ObbFile::removeFrom(int fd) 3406e7ac5f0bceddf51947fbf3b376e278df0735603Kenny Root{ 3416e7ac5f0bceddf51947fbf3b376e278df0735603Kenny Root if (fd < 0) { 3426e7ac5f0bceddf51947fbf3b376e278df0735603Kenny Root return false; 3436e7ac5f0bceddf51947fbf3b376e278df0735603Kenny Root } 3446e7ac5f0bceddf51947fbf3b376e278df0735603Kenny Root 3456e7ac5f0bceddf51947fbf3b376e278df0735603Kenny Root if (!readFrom(fd)) { 3466e7ac5f0bceddf51947fbf3b376e278df0735603Kenny Root return false; 3476e7ac5f0bceddf51947fbf3b376e278df0735603Kenny Root } 3486e7ac5f0bceddf51947fbf3b376e278df0735603Kenny Root 3496e7ac5f0bceddf51947fbf3b376e278df0735603Kenny Root ftruncate(fd, mFooterStart); 3506e7ac5f0bceddf51947fbf3b376e278df0735603Kenny Root 3516e7ac5f0bceddf51947fbf3b376e278df0735603Kenny Root return true; 3526e7ac5f0bceddf51947fbf3b376e278df0735603Kenny Root} 3536e7ac5f0bceddf51947fbf3b376e278df0735603Kenny Root 3547cee34a051eb0087322c8b965e498f88b1aa52d3Kenny Root} 355