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) 5ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "ppapi/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" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/pp_errors.h" 11ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "ppapi/native_client/src/trusted/plugin/file_utils.h" 12ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "ppapi/native_client/src/trusted/plugin/manifest.h" 13ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "ppapi/native_client/src/trusted/plugin/plugin.h" 14ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h" 15ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "ppapi/native_client/src/trusted/plugin/utility.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) 24a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)nacl::string PnaclUrls::GetBaseUrl() { 2590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return nacl::string(kPnaclComponentScheme); 2690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 2790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 2890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)nacl::string PnaclUrls::PrependPlatformPrefix(const nacl::string& url) { 2990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return nacl::string(GetSandboxISA()) + "/" + url; 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 32a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)// Determine if a URL is for a pnacl-component file, or if it is some other 33a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)// type of URL (e.g., http://, https://, chrome-extension://). 34a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)// The URL could be one of the other variants for shared libraries 35a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)// served from the web. 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PnaclUrls::IsPnaclComponent(const nacl::string& full_url) { 37a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) return full_url.find(kPnaclComponentScheme, 0) == 0; 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Convert a URL to a filename accepted by GetReadonlyPnaclFd. 41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Must be kept in sync with chrome/browser/nacl_host/nacl_file_host. 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)nacl::string PnaclUrls::PnaclComponentURLToFilename( 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const nacl::string& full_url) { 44a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) // strip component scheme. 45a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) nacl::string r = full_url.substr( 46a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) nacl::string(kPnaclComponentScheme).length()); 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Use white-listed-chars. 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t replace_pos; 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static const char* white_list = "abcdefghijklmnopqrstuvwxyz0123456789_"; 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) replace_pos = r.find_first_not_of(white_list); 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) while(replace_pos != nacl::string::npos) { 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) r = r.replace(replace_pos, 1, "_"); 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) replace_pos = r.find_first_not_of(white_list); 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return r; 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////// 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PnaclResources::~PnaclResources() { 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::map<nacl::string, nacl::DescWrapper*>::iterator 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i = resource_wrappers_.begin(), e = resource_wrappers_.end(); 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i != e; 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++i) { 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete i->second; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) resource_wrappers_.clear(); 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int32_t PnaclResources::GetPnaclFD(Plugin* plugin, const char* filename) { 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_FileHandle file_handle = 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) plugin->nacl_interface()->GetReadonlyPnaclFd(filename); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (file_handle == PP_kInvalidFileHandle) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return -1; 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if NACL_WINDOWS 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) //////// Now try the posix view. 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32_t posix_desc = _open_osfhandle(reinterpret_cast<intptr_t>(file_handle), 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) _O_RDONLY | _O_BINARY); 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (posix_desc == -1) { 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PLUGIN_PRINTF(( 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "PnaclResources::GetPnaclFD failed to convert HANDLE to posix\n")); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Close the Windows HANDLE if it can't be converted. 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloseHandle(file_handle); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return posix_desc; 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return file_handle; 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)nacl::DescWrapper* PnaclResources::WrapperForUrl(const nacl::string& url) { 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(resource_wrappers_.find(url) != resource_wrappers_.end()); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return resource_wrappers_[url]; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void PnaclResources::ReadResourceInfo( 10090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const nacl::string& resource_info_url, 10190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const pp::CompletionCallback& resource_info_read_cb) { 10290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) PLUGIN_PRINTF(("PnaclResources::ReadResourceInfo\n")); 10390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 10490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) nacl::string full_url; 10590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ErrorInfo error_info; 10690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!manifest_->ResolveURL(resource_info_url, &full_url, &error_info)) { 10790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ReadResourceInfoError(nacl::string("failed to resolve ") + 10890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) resource_info_url + ": " + 10990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) error_info.message() + "."); 11090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return; 11190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 11290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) PLUGIN_PRINTF(("Resolved resources info url: %s\n", full_url.c_str())); 11390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) nacl::string resource_info_filename = 11490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) PnaclUrls::PnaclComponentURLToFilename(full_url); 11590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 11690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) PLUGIN_PRINTF(("Pnacl-converted resources info url: %s\n", 11790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) resource_info_filename.c_str())); 11890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 11990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int32_t fd = GetPnaclFD(plugin_, resource_info_filename.c_str()); 12090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (fd < 0) { 1217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // File-open failed. Assume this means that the file is 1227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // not actually installed. 12390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ReadResourceInfoError( 124424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) nacl::string("The Portable Native Client (pnacl) component is not " 125424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) "installed. Please consult chrome://components for more " 126424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) "information.")); 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) { 2217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // File-open failed. Assume this means that the file is 2227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // not actually installed. This shouldn't actually occur since 2237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // ReadResourceInfo() should happen first, and error out. 224a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) coordinator_->ReportNonPpapiError( 225a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) ERROR_PNACL_RESOURCE_FETCH, 226424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) nacl::string("The Portable Native Client (pnacl) component is not " 227424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) "installed. Please consult chrome://components for more " 228424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) "information.")); 229a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) result = PP_ERROR_FILENOTFOUND; 230a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) break; 231a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) } else { 23290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) resource_wrappers_[resource_urls[i]] = 233a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) plugin_->wrapper_factory()->MakeFileDesc(fd, O_RDONLY); 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 236a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) // We're done! Queue the callback. 237a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) pp::Core* core = pp::Module::Get()->core(); 23890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) core->CallOnMainThread(0, all_loaded_callback, result); 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace plugin 242