15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2006-2009 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/mini_installer/pe_resource.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PEResource::PEResource(HRSRC resource, HMODULE module)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : resource_(resource), module_(module) {
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PEResource::PEResource(const wchar_t* name, const wchar_t* type, HMODULE module)
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : resource_(NULL), module_(module) {
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resource_ = ::FindResource(module, name, type);
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PEResource::IsValid() {
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return (NULL != resource_);
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)size_t PEResource::Size() {
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ::SizeofResource(module_, resource_);
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PEResource::WriteToDisk(const wchar_t* full_path) {
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Resource handles are not real HGLOBALs so do not attempt to close them.
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Windows frees them whenever there is memory pressure.
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HGLOBAL data_handle = ::LoadResource(module_, resource_);
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (NULL == data_handle) {
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void* data = ::LockResource(data_handle);
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (NULL == data) {
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t resource_size = Size();
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HANDLE out_file = ::CreateFile(full_path, GENERIC_WRITE, 0, NULL,
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (INVALID_HANDLE_VALUE == out_file) {
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DWORD written = 0;
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!::WriteFile(out_file, data, static_cast<DWORD>(resource_size),
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   &written, NULL)) {
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ::CloseHandle(out_file);
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ::CloseHandle(out_file) ? true : false;
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
49