15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/installer/util/lzma_util.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 71320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern "C" { 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/lzma_sdk/7z.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/lzma_sdk/7zAlloc.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/lzma_sdk/7zCrc.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/lzma_sdk/7zFile.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SRes LzmaReadFile(HANDLE file, void *data, size_t *size) { 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (*size == 0) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SZ_OK; 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t processedSize = 0; 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DWORD maxSize = *size; 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do { 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DWORD processedLoc = 0; 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BOOL res = ReadFile(file, data, maxSize, &processedLoc, NULL); 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data = (void *)((unsigned char *) data + processedLoc); 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) maxSize -= processedLoc; 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) processedSize += processedLoc; 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (processedLoc == 0) { 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (res) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SZ_ERROR_READ; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } while (maxSize > 0); 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *size = processedSize; 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SZ_OK; 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SRes SzFileSeekImp(void *object, Int64 *pos, ESzSeek origin) { 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CFileInStream *s = (CFileInStream *) object; 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LARGE_INTEGER value; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value.LowPart = (DWORD) *pos; 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value.HighPart = (LONG) ((UInt64) *pos >> 32); 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DWORD moveMethod; 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (origin) { 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SZ_SEEK_SET: 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) moveMethod = FILE_BEGIN; 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SZ_SEEK_CUR: 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) moveMethod = FILE_CURRENT; 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SZ_SEEK_END: 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) moveMethod = FILE_END; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SZ_ERROR_PARAM; 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value.LowPart = SetFilePointer(s->file.handle, value.LowPart, &value.HighPart, 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) moveMethod); 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *pos = ((Int64)value.HighPart << 32) | value.LowPart; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ((value.LowPart == 0xFFFFFFFF) && (GetLastError() != NO_ERROR)) ? 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SZ_ERROR_FAIL : SZ_OK; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SRes SzFileReadImp(void *object, void *buffer, size_t *size) { 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CFileInStream *s = (CFileInStream *) object; 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return LzmaReadFile(s->file.handle, buffer, size); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int32 LzmaUtil::UnPackArchive(const std::wstring& archive, 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::wstring& output_dir, 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::wstring* output_file) { 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << "Opening archive " << archive; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LzmaUtil lzma_util; 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DWORD ret; 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((ret = lzma_util.OpenArchive(archive)) != NO_ERROR) { 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Unable to open install archive: " << archive 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << ", error: " << ret; 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << "Uncompressing archive to path " << output_dir; 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((ret = lzma_util.UnPack(output_dir, output_file)) != NO_ERROR) { 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Unable to uncompress archive: " << archive 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << ", error: " << ret; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lzma_util.CloseArchive(); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ret; 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LzmaUtil::LzmaUtil() : archive_handle_(NULL) {} 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LzmaUtil::~LzmaUtil() { 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloseArchive(); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DWORD LzmaUtil::OpenArchive(const std::wstring& archivePath) { 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make sure file is not already open. 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloseArchive(); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DWORD ret = NO_ERROR; 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) archive_handle_ = CreateFile(archivePath.c_str(), GENERIC_READ, 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (archive_handle_ == INVALID_HANDLE_VALUE) { 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) archive_handle_ = NULL; // The rest of the code only checks for NULL. 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = GetLastError(); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ret; 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DWORD LzmaUtil::UnPack(const std::wstring& location) { 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return UnPack(location, NULL); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DWORD LzmaUtil::UnPack(const std::wstring& location, 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::wstring* output_file) { 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!archive_handle_) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ERROR_INVALID_HANDLE; 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CFileInStream archiveStream; 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CLookToRead lookStream; 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CSzArEx db; 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ISzAlloc allocImp; 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ISzAlloc allocTempImp; 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DWORD ret = NO_ERROR; 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) archiveStream.file.handle = archive_handle_; 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) archiveStream.s.Read = SzFileReadImp; 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) archiveStream.s.Seek = SzFileSeekImp; 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LookToRead_CreateVTable(&lookStream, false); 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookStream.realStream = &archiveStream.s; 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) allocImp.Alloc = SzAlloc; 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) allocImp.Free = SzFree; 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) allocTempImp.Alloc = SzAllocTemp; 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) allocTempImp.Free = SzFreeTemp; 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CrcGenerateTable(); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SzArEx_Init(&db); 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((ret = SzArEx_Open(&db, &lookStream.s, 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &allocImp, &allocTempImp)) != SZ_OK) { 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << L"Error returned by SzArchiveOpen: " << ret; 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ERROR_INVALID_HANDLE; 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Byte *outBuffer = 0; // it must be 0 before first call for each new archive 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UInt32 blockIndex = 0xFFFFFFFF; // can have any value if outBuffer = 0 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t outBufferSize = 0; // can have any value if outBuffer = 0 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < db.db.NumFiles; i++) { 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DWORD written; 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t offset; 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t outSizeProcessed; 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CSzFileItem *f = db.db.Files + i; 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((ret = SzArEx_Extract(&db, &lookStream.s, i, &blockIndex, 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &outBuffer, &outBufferSize, &offset, &outSizeProcessed, 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &allocImp, &allocTempImp)) != SZ_OK) { 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << L"Error returned by SzExtract: " << ret; 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = ERROR_INVALID_HANDLE; 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t file_name_length = SzArEx_GetFileNameUtf16(&db, i, NULL); 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (file_name_length < 1) { 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << L"Couldn't get file name"; 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = ERROR_INVALID_HANDLE; 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<UInt16> file_name(file_name_length); 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SzArEx_GetFileNameUtf16(&db, i, &file_name[0]); 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |file_name| is NULL-terminated. 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath file_path = base::FilePath(location).Append( 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath::StringType(file_name.begin(), file_name.end() - 1)); 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (output_file) 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *output_file = file_path.value(); 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If archive entry is directory create it and move on to the next entry. 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (f->IsDir) { 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateDirectory(file_path); 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateDirectory(file_path.DirName()); 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HANDLE hFile; 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hFile = CreateFile(file_path.value().c_str(), GENERIC_WRITE, 0, NULL, 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (hFile == INVALID_HANDLE_VALUE) { 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = GetLastError(); 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << L"Error returned by CreateFile: " << ret; 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((!WriteFile(hFile, outBuffer + offset, (DWORD) outSizeProcessed, 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &written, NULL)) || 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (written != outSizeProcessed)) { 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = GetLastError(); 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloseHandle(hFile); 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << L"Error returned by WriteFile: " << ret; 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (f->MTimeDefined) { 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!SetFileTime(hFile, NULL, NULL, 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (const FILETIME *)&(f->MTime))) { 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = GetLastError(); 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloseHandle(hFile); 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << L"Error returned by SetFileTime: " << ret; 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!CloseHandle(hFile)) { 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = GetLastError(); 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << L"Error returned by CloseHandle: " << ret; 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } // for loop 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IAlloc_Free(&allocImp, outBuffer); 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SzArEx_Free(&db, &allocImp); 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ret; 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LzmaUtil::CloseArchive() { 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (archive_handle_) { 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloseHandle(archive_handle_); 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) archive_handle_ = NULL; 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool LzmaUtil::CreateDirectory(const base::FilePath& dir) { 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool ret = true; 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (directories_created_.find(dir.value()) == directories_created_.end()) { 245a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ret = base::CreateDirectory(dir); 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret) 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) directories_created_.insert(dir.value()); 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ret; 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 251