pnacl_resources.cc revision 90dce4d38c5ff5333bea97d859d4e484e27edf0c
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 "native_client/src/trusted/plugin/pnacl_resources.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "native_client/src/include/portability_io.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "native_client/src/shared/platform/nacl_check.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "native_client/src/trusted/desc/nacl_desc_wrapper.h"
1090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "native_client/src/trusted/plugin/file_utils.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "native_client/src/trusted/plugin/manifest.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "native_client/src/trusted/plugin/plugin.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "native_client/src/trusted/plugin/pnacl_coordinator.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "native_client/src/trusted/plugin/utility.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/pp_errors.h"
1690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "third_party/jsoncpp/source/include/json/reader.h"
1790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "third_party/jsoncpp/source/include/json/value.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace plugin {
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)static const char kPnaclComponentScheme[] = "pnacl-component://";
2290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)const char PnaclUrls::kResourceInfoUrl[] = "pnacl.json";
2390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
2490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)const char PnaclResources::kDefaultLlcName[] = "llc.nexe";
2590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)const char PnaclResources::kDefaultLdName[] = "ld.nexe";
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)nacl::string PnaclUrls::GetBaseUrl() {
2890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return nacl::string(kPnaclComponentScheme);
2990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
3090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
3190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)nacl::string PnaclUrls::PrependPlatformPrefix(const nacl::string& url) {
3290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return nacl::string(GetSandboxISA()) + "/" + url;
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)// Determine if a URL is for a pnacl-component file, or if it is some other
36a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)// type of URL (e.g., http://, https://, chrome-extension://).
37a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)// The URL could be one of the other variants for shared libraries
38a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)// served from the web.
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PnaclUrls::IsPnaclComponent(const nacl::string& full_url) {
40a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  return full_url.find(kPnaclComponentScheme, 0) == 0;
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Convert a URL to a filename accepted by GetReadonlyPnaclFd.
44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Must be kept in sync with chrome/browser/nacl_host/nacl_file_host.
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)nacl::string PnaclUrls::PnaclComponentURLToFilename(
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const nacl::string& full_url) {
47a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // strip component scheme.
48a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  nacl::string r = full_url.substr(
49a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      nacl::string(kPnaclComponentScheme).length());
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Use white-listed-chars.
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t replace_pos;
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static const char* white_list = "abcdefghijklmnopqrstuvwxyz0123456789_";
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  replace_pos = r.find_first_not_of(white_list);
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  while(replace_pos != nacl::string::npos) {
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    r = r.replace(replace_pos, 1, "_");
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    replace_pos = r.find_first_not_of(white_list);
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return r;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//////////////////////////////////////////////////////////////////////
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PnaclResources::~PnaclResources() {
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (std::map<nacl::string, nacl::DescWrapper*>::iterator
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           i = resource_wrappers_.begin(), e = resource_wrappers_.end();
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       i != e;
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       ++i) {
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delete i->second;
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resource_wrappers_.clear();
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int32_t PnaclResources::GetPnaclFD(Plugin* plugin, const char* filename) {
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PP_FileHandle file_handle =
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      plugin->nacl_interface()->GetReadonlyPnaclFd(filename);
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (file_handle == PP_kInvalidFileHandle)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return -1;
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if NACL_WINDOWS
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //////// Now try the posix view.
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int32_t posix_desc = _open_osfhandle(reinterpret_cast<intptr_t>(file_handle),
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       _O_RDONLY | _O_BINARY);
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (posix_desc == -1) {
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PLUGIN_PRINTF((
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "PnaclResources::GetPnaclFD failed to convert HANDLE to posix\n"));
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Close the Windows HANDLE if it can't be converted.
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CloseHandle(file_handle);
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return posix_desc;
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return file_handle;
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)nacl::DescWrapper* PnaclResources::WrapperForUrl(const nacl::string& url) {
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(resource_wrappers_.find(url) != resource_wrappers_.end());
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return resource_wrappers_[url];
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void PnaclResources::ReadResourceInfo(
10390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const nacl::string& resource_info_url,
10490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const pp::CompletionCallback& resource_info_read_cb) {
10590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  PLUGIN_PRINTF(("PnaclResources::ReadResourceInfo\n"));
10690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
10790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  nacl::string full_url;
10890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  ErrorInfo error_info;
10990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (!manifest_->ResolveURL(resource_info_url, &full_url, &error_info)) {
11090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    ReadResourceInfoError(nacl::string("failed to resolve ") +
11190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                          resource_info_url + ": " +
11290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                          error_info.message() + ".");
11390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return;
11490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
11590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  PLUGIN_PRINTF(("Resolved resources info url: %s\n", full_url.c_str()));
11690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  nacl::string resource_info_filename =
11790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    PnaclUrls::PnaclComponentURLToFilename(full_url);
11890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
11990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  PLUGIN_PRINTF(("Pnacl-converted resources info url: %s\n",
12090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                 resource_info_filename.c_str()));
12190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
12290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  int32_t fd = GetPnaclFD(plugin_, resource_info_filename.c_str());
12390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (fd < 0) {
12490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    ReadResourceInfoError(
12590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        nacl::string("PnaclResources::ReadResourceInfo failed for: ") +
12690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        resource_info_filename);
12790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return;
12890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
12990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
13090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  nacl::string json_buffer;
13190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  file_utils::StatusCode status = file_utils::SlurpFile(fd, json_buffer);
13290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (status != file_utils::PLUGIN_FILE_SUCCESS) {
13390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    ReadResourceInfoError(
13490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        nacl::string("PnaclResources::ReadResourceInfo reading "
13590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                     "failed for: ") + resource_info_filename);
13690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return;
13790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
13890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
13990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Finally, we have the resource info JSON data in json_buffer.
14090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  PLUGIN_PRINTF(("Resource info JSON data:\n%s\n", json_buffer.c_str()));
14190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  nacl::string error_message;
14290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (!ParseResourceInfo(json_buffer, error_message)) {
14390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    ReadResourceInfoError(nacl::string("Parsing resource info failed: ") +
14490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                          error_message + "\n");
14590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return;
14690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
14790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
14890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Done. Queue the completion callback.
14990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  pp::Core* core = pp::Module::Get()->core();
15090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  core->CallOnMainThread(0, resource_info_read_cb, PP_OK);
15190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
15290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
15390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void PnaclResources::ReadResourceInfoError(const nacl::string& msg) {
15490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  coordinator_->ReportNonPpapiError(ERROR_PNACL_RESOURCE_FETCH, msg);
15590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
15690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
15790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)bool PnaclResources::ParseResourceInfo(const nacl::string& buf,
15890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                       nacl::string& errmsg) {
15990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Expect the JSON file to contain a top-level object (dictionary).
16090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  Json::Reader json_reader;
16190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  Json::Value json_data;
16290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (!json_reader.parse(buf, json_data)) {
16390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    errmsg = nacl::string("JSON parse error: ") +
16490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)             json_reader.getFormatedErrorMessages();
16590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return false;
16690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
16790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
16890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (!json_data.isObject()) {
16990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    errmsg = nacl::string("Malformed JSON dictionary");
17090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return false;
17190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
17290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
17390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (json_data.isMember("pnacl-llc-name")) {
17490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    Json::Value json_name = json_data["pnacl-llc-name"];
17590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if (json_name.isString()) {
17690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      llc_tool_name = json_name.asString();
17790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      PLUGIN_PRINTF(("Set llc_tool_name=%s\n", llc_tool_name.c_str()));
17890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    }
17990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
18090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
18190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (json_data.isMember("pnacl-ld-name")) {
18290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    Json::Value json_name = json_data["pnacl-ld-name"];
18390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if (json_name.isString()) {
18490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      ld_tool_name = json_name.asString();
18590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      PLUGIN_PRINTF(("Set ld_tool_name=%s\n", ld_tool_name.c_str()));
18690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    }
18790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
18890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
18990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return true;
19090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
19190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
19290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void PnaclResources::StartLoad(
19390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const pp::CompletionCallback& all_loaded_callback) {
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PLUGIN_PRINTF(("PnaclResources::StartLoad\n"));
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::vector<nacl::string> resource_urls;
19790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  resource_urls.push_back(GetLlcUrl());
19890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  resource_urls.push_back(GetLdUrl());
19990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
200a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  PLUGIN_PRINTF(("PnaclResources::StartLoad -- local install of PNaCl.\n"));
201a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // Do a blocking load of each of the resources.
202a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  int32_t result = PP_OK;
20390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  for (size_t i = 0; i < resource_urls.size(); ++i) {
20490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const nacl::string& url_with_platform_prefix =
20590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      PnaclUrls::PrependPlatformPrefix(resource_urls[i]);
206a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    nacl::string full_url;
207a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    ErrorInfo error_info;
20890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if (!manifest_->ResolveURL(url_with_platform_prefix, &full_url,
20990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                               &error_info)) {
210a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      coordinator_->ReportNonPpapiError(
211a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)          ERROR_PNACL_RESOURCE_FETCH,
212a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)          nacl::string("failed to resolve ") +
21390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          url_with_platform_prefix + ": " +
214a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)          error_info.message() + ".");
215a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      break;
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
217a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    nacl::string filename = PnaclUrls::PnaclComponentURLToFilename(full_url);
218a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
219a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    int32_t fd = PnaclResources::GetPnaclFD(plugin_, filename.c_str());
220a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    if (fd < 0) {
221a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      coordinator_->ReportNonPpapiError(
222a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)          ERROR_PNACL_RESOURCE_FETCH,
22390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          nacl::string("PnaclResources::StartLoad failed for: ") +
224a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)          filename + " (PNaCl not installed?  Check chrome://nacl)");
225a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      result = PP_ERROR_FILENOTFOUND;
226a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      break;
227a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    } else {
22890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      resource_wrappers_[resource_urls[i]] =
229a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)          plugin_->wrapper_factory()->MakeFileDesc(fd, O_RDONLY);
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
232a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // We're done!  Queue the callback.
233a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  pp::Core* core = pp::Module::Get()->core();
23490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  core->CallOnMainThread(0, all_loaded_callback, result);
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace plugin
238