19ecf9d1cSIngo Weinhold /* 289eb861aSAxel Dörfler * Copyright (c) 2001-2008, Haiku, Inc. 39ecf9d1cSIngo Weinhold * Distributed under the terms of the MIT License. 49ecf9d1cSIngo Weinhold * 59ecf9d1cSIngo Weinhold * Authors: 69ecf9d1cSIngo Weinhold * Erik Jaesler (erik@cgsoftware.com) 79ecf9d1cSIngo Weinhold */ 852a38012Sejakowatz 97bc5a06bSAxel Dörfler /*! BArchivable mix-in class defines the archiving protocol. 107bc5a06bSAxel Dörfler Also some global archiving functions. 117bc5a06bSAxel Dörfler */ 129ecf9d1cSIngo Weinhold 139ecf9d1cSIngo Weinhold 1452a38012Sejakowatz #include <ctype.h> 1552a38012Sejakowatz #include <errno.h> 1652a38012Sejakowatz #include <stdlib.h> 1752a38012Sejakowatz #include <stdio.h> 1852a38012Sejakowatz #include <string> 197bc5a06bSAxel Dörfler #include <syslog.h> 2052a38012Sejakowatz #include <typeinfo> 2152a38012Sejakowatz #include <vector> 2252a38012Sejakowatz 2352a38012Sejakowatz #include <AppFileInfo.h> 2452a38012Sejakowatz #include <Archivable.h> 2552a38012Sejakowatz #include <Entry.h> 2652a38012Sejakowatz #include <List.h> 2752a38012Sejakowatz #include <OS.h> 2852a38012Sejakowatz #include <Path.h> 2952a38012Sejakowatz #include <Roster.h> 3052a38012Sejakowatz #include <String.h> 3152a38012Sejakowatz 3252a38012Sejakowatz 3352a38012Sejakowatz using std::string; 3452a38012Sejakowatz using std::vector; 3552a38012Sejakowatz 3652a38012Sejakowatz const char* B_CLASS_FIELD = "class"; 3752a38012Sejakowatz const char* B_ADD_ON_FIELD = "add_on"; 3852a38012Sejakowatz const int32 FUNC_NAME_LEN = 1024; 3952a38012Sejakowatz 407bc5a06bSAxel Dörfler // TODO: consider moving these to a separate module, and making them more 417bc5a06bSAxel Dörfler // full-featured (e.g., taking NS::ClassName::Function(Param p) instead 427bc5a06bSAxel Dörfler // of just NS::ClassName) 4352a38012Sejakowatz 449ecf9d1cSIngo Weinhold 45*13bbfe42SAxel Dörfler static status_t 4689eb861aSAxel Dörfler demangle_class_name(const char* name, BString& out) 4752a38012Sejakowatz { 4852a38012Sejakowatz // TODO: add support for template classes 4952a38012Sejakowatz // _find__t12basic_string3ZcZt18string_char_traits1ZcZt24__default_alloc_template2b0i0PCccUlUl 5052a38012Sejakowatz 5152a38012Sejakowatz out = ""; 5252a38012Sejakowatz 53*13bbfe42SAxel Dörfler if (name[0] == 'Q') { 54*13bbfe42SAxel Dörfler // The name is in a namespace 55*13bbfe42SAxel Dörfler int namespaceCount = 0; 56*13bbfe42SAxel Dörfler name++; 57*13bbfe42SAxel Dörfler if (name[0] == '_') { 58*13bbfe42SAxel Dörfler // more than 10 namespaces deep 59*13bbfe42SAxel Dörfler if (!isdigit(*++name)) 60*13bbfe42SAxel Dörfler return B_BAD_VALUE; 6152a38012Sejakowatz 62*13bbfe42SAxel Dörfler namespaceCount = strtoul(name, (char**)&name, 10); 63*13bbfe42SAxel Dörfler if (name[0] != '_') 64*13bbfe42SAxel Dörfler return B_BAD_VALUE; 65*13bbfe42SAxel Dörfler } else 66*13bbfe42SAxel Dörfler namespaceCount = name[0] - '0'; 6752a38012Sejakowatz 68*13bbfe42SAxel Dörfler name++; 6952a38012Sejakowatz 70*13bbfe42SAxel Dörfler for (int i = 0; i < namespaceCount - 1; i++) { 71*13bbfe42SAxel Dörfler if (!isdigit(name[0])) 72*13bbfe42SAxel Dörfler return B_BAD_VALUE; 73*13bbfe42SAxel Dörfler 74*13bbfe42SAxel Dörfler int nameLength = strtoul(name, (char**)&name, 10); 75*13bbfe42SAxel Dörfler out.Append(name, nameLength); 7652a38012Sejakowatz out += "::"; 77*13bbfe42SAxel Dörfler name += nameLength; 7852a38012Sejakowatz } 7952a38012Sejakowatz } 8052a38012Sejakowatz 81*13bbfe42SAxel Dörfler int nameLength = strtoul(name, (char**)&name, 10); 82*13bbfe42SAxel Dörfler out.Append(name, nameLength); 83*13bbfe42SAxel Dörfler 84*13bbfe42SAxel Dörfler return B_OK; 8552a38012Sejakowatz } 869ecf9d1cSIngo Weinhold 879ecf9d1cSIngo Weinhold 8889eb861aSAxel Dörfler static void 8989eb861aSAxel Dörfler mangle_class_name(const char* name, BString& out) 9052a38012Sejakowatz { 9152a38012Sejakowatz // TODO: add support for template classes 9252a38012Sejakowatz // _find__t12basic_string3ZcZt18string_char_traits1ZcZt24__default_alloc_template2b0i0PCccUlUl 9352a38012Sejakowatz 9452a38012Sejakowatz // Chop this: 9552a38012Sejakowatz // testthree::testfour::Testthree::Testfour 9652a38012Sejakowatz // up into little bite-sized pieces 9752a38012Sejakowatz int count = 0; 9852a38012Sejakowatz string origName(name); 9952a38012Sejakowatz vector<string> spacenames; 10052a38012Sejakowatz 10152a38012Sejakowatz string::size_type pos = 0; 10252a38012Sejakowatz string::size_type oldpos = 0; 1039ecf9d1cSIngo Weinhold while (pos != string::npos) { 10452a38012Sejakowatz pos = origName.find_first_of("::", oldpos); 10552a38012Sejakowatz spacenames.push_back(string(origName, oldpos, pos - oldpos)); 10652a38012Sejakowatz pos = origName.find_first_not_of("::", pos); 10752a38012Sejakowatz oldpos = pos; 10852a38012Sejakowatz ++count; 10952a38012Sejakowatz } 11052a38012Sejakowatz 11152a38012Sejakowatz // Now mangle it into this: 11252a38012Sejakowatz // Q49testthree8testfour9Testthree8Testfour 11352a38012Sejakowatz out = ""; 1149ecf9d1cSIngo Weinhold if (count > 1) { 11552a38012Sejakowatz out += 'Q'; 11652a38012Sejakowatz if (count > 10) 11752a38012Sejakowatz out += '_'; 11852a38012Sejakowatz out << count; 11952a38012Sejakowatz if (count > 10) 12052a38012Sejakowatz out += '_'; 12152a38012Sejakowatz } 12252a38012Sejakowatz 1239ecf9d1cSIngo Weinhold for (unsigned int i = 0; i < spacenames.size(); ++i) { 12452a38012Sejakowatz out << (int)spacenames[i].length(); 12552a38012Sejakowatz out += spacenames[i].c_str(); 12652a38012Sejakowatz } 12752a38012Sejakowatz } 1289ecf9d1cSIngo Weinhold 1299ecf9d1cSIngo Weinhold 13089eb861aSAxel Dörfler static void 13189eb861aSAxel Dörfler build_function_name(const BString& className, BString& funcName) 13252a38012Sejakowatz { 13389eb861aSAxel Dörfler funcName = ""; 13452a38012Sejakowatz 13589eb861aSAxel Dörfler // This is what we're after: 13689eb861aSAxel Dörfler // Instantiate__Q28OpenBeOS11BArchivableP8BMessage 13789eb861aSAxel Dörfler mangle_class_name(className.String(), funcName); 13889eb861aSAxel Dörfler #if __GNUC__ >= 4 13989eb861aSAxel Dörfler funcName.Prepend("_ZN"); 14089eb861aSAxel Dörfler funcName.Append("11InstantiateE"); 14189eb861aSAxel Dörfler #else 14289eb861aSAxel Dörfler funcName.Prepend("Instantiate__"); 14352a38012Sejakowatz #endif 14489eb861aSAxel Dörfler funcName.Append("P8BMessage"); 14552a38012Sejakowatz } 14652a38012Sejakowatz 14789eb861aSAxel Dörfler 14889eb861aSAxel Dörfler static bool 14989eb861aSAxel Dörfler add_private_namespace(BString& name) 15089eb861aSAxel Dörfler { 15189eb861aSAxel Dörfler if (name.Compare("_", 1) != 0) 15289eb861aSAxel Dörfler return false; 15389eb861aSAxel Dörfler 15489eb861aSAxel Dörfler name.Prepend("BPrivate::"); 15589eb861aSAxel Dörfler return true; 15689eb861aSAxel Dörfler } 15789eb861aSAxel Dörfler 15889eb861aSAxel Dörfler 15989eb861aSAxel Dörfler static instantiation_func 16089eb861aSAxel Dörfler find_function_in_image(BString& funcName, image_id id, status_t& err) 16189eb861aSAxel Dörfler { 16289eb861aSAxel Dörfler instantiation_func instantiationFunc = NULL; 16389eb861aSAxel Dörfler err = get_image_symbol(id, funcName.String(), B_SYMBOL_TYPE_TEXT, 16489eb861aSAxel Dörfler (void**)&instantiationFunc); 16589eb861aSAxel Dörfler if (err != B_OK) 16689eb861aSAxel Dörfler return NULL; 16789eb861aSAxel Dörfler 16889eb861aSAxel Dörfler return instantiationFunc; 16989eb861aSAxel Dörfler } 17089eb861aSAxel Dörfler 17189eb861aSAxel Dörfler 17289eb861aSAxel Dörfler static status_t 17389eb861aSAxel Dörfler check_signature(const char* signature, image_info& info) 17489eb861aSAxel Dörfler { 17589eb861aSAxel Dörfler if (signature == NULL) { 17689eb861aSAxel Dörfler // If it wasn't specified, anything "matches" 17789eb861aSAxel Dörfler return B_OK; 17889eb861aSAxel Dörfler } 17989eb861aSAxel Dörfler 18089eb861aSAxel Dörfler // Get image signature 18189eb861aSAxel Dörfler BFile file(info.name, B_READ_ONLY); 18289eb861aSAxel Dörfler status_t err = file.InitCheck(); 18389eb861aSAxel Dörfler if (err != B_OK) 18489eb861aSAxel Dörfler return err; 18589eb861aSAxel Dörfler 18689eb861aSAxel Dörfler char imageSignature[B_MIME_TYPE_LENGTH]; 18789eb861aSAxel Dörfler BAppFileInfo appFileInfo(&file); 18889eb861aSAxel Dörfler err = appFileInfo.GetSignature(imageSignature); 18989eb861aSAxel Dörfler if (err != B_OK) { 19089eb861aSAxel Dörfler syslog(LOG_ERR, "instantiate_object - couldn't get mime sig for %s", 19189eb861aSAxel Dörfler info.name); 19289eb861aSAxel Dörfler return err; 19389eb861aSAxel Dörfler } 19489eb861aSAxel Dörfler 19589eb861aSAxel Dörfler if (strcmp(signature, imageSignature)) 19689eb861aSAxel Dörfler return B_MISMATCHED_VALUES; 19789eb861aSAxel Dörfler 19889eb861aSAxel Dörfler return B_OK; 19989eb861aSAxel Dörfler } 20089eb861aSAxel Dörfler 20189eb861aSAxel Dörfler 20289eb861aSAxel Dörfler // #pragma mark - 20389eb861aSAxel Dörfler 20489eb861aSAxel Dörfler 20589eb861aSAxel Dörfler BArchivable::BArchivable() 20689eb861aSAxel Dörfler { 20789eb861aSAxel Dörfler } 20889eb861aSAxel Dörfler 20989eb861aSAxel Dörfler 21089eb861aSAxel Dörfler BArchivable::BArchivable(BMessage* from) 21189eb861aSAxel Dörfler { 21289eb861aSAxel Dörfler } 21389eb861aSAxel Dörfler 21489eb861aSAxel Dörfler 21589eb861aSAxel Dörfler BArchivable::~BArchivable() 21689eb861aSAxel Dörfler { 21789eb861aSAxel Dörfler } 21889eb861aSAxel Dörfler 21989eb861aSAxel Dörfler 22089eb861aSAxel Dörfler status_t 22189eb861aSAxel Dörfler BArchivable::Archive(BMessage* into, bool deep) const 22289eb861aSAxel Dörfler { 22389eb861aSAxel Dörfler if (!into) { 22489eb861aSAxel Dörfler // TODO: logging/other error reporting? 22589eb861aSAxel Dörfler return B_BAD_VALUE; 22689eb861aSAxel Dörfler } 22789eb861aSAxel Dörfler 22889eb861aSAxel Dörfler BString name; 229*13bbfe42SAxel Dörfler status_t status = demangle_class_name(typeid(*this).name(), name); 230*13bbfe42SAxel Dörfler if (status != B_OK) 231*13bbfe42SAxel Dörfler return status; 23289eb861aSAxel Dörfler 23389eb861aSAxel Dörfler return into->AddString(B_CLASS_FIELD, name); 23489eb861aSAxel Dörfler } 23589eb861aSAxel Dörfler 23689eb861aSAxel Dörfler 23789eb861aSAxel Dörfler BArchivable* 23889eb861aSAxel Dörfler BArchivable::Instantiate(BMessage* from) 23989eb861aSAxel Dörfler { 24089eb861aSAxel Dörfler debugger("Can't create a plain BArchivable object"); 24189eb861aSAxel Dörfler return NULL; 24289eb861aSAxel Dörfler } 24389eb861aSAxel Dörfler 24489eb861aSAxel Dörfler 24589eb861aSAxel Dörfler status_t 24689eb861aSAxel Dörfler BArchivable::Perform(perform_code d, void* arg) 24789eb861aSAxel Dörfler { 24889eb861aSAxel Dörfler // TODO: Check against original 24989eb861aSAxel Dörfler return B_ERROR; 25089eb861aSAxel Dörfler } 25189eb861aSAxel Dörfler 25289eb861aSAxel Dörfler 25389eb861aSAxel Dörfler void BArchivable::_ReservedArchivable1() {} 25489eb861aSAxel Dörfler void BArchivable::_ReservedArchivable2() {} 25589eb861aSAxel Dörfler void BArchivable::_ReservedArchivable3() {} 25689eb861aSAxel Dörfler 25789eb861aSAxel Dörfler 25889eb861aSAxel Dörfler // #pragma mark - 25989eb861aSAxel Dörfler 26089eb861aSAxel Dörfler 26189eb861aSAxel Dörfler BArchivable* 26289eb861aSAxel Dörfler instantiate_object(BMessage* archive, image_id* _id) 26389eb861aSAxel Dörfler { 26489eb861aSAxel Dörfler status_t statusBuffer; 26589eb861aSAxel Dörfler status_t* status = &statusBuffer; 26689eb861aSAxel Dörfler if (_id != NULL) 26789eb861aSAxel Dörfler status = _id; 26889eb861aSAxel Dörfler 26989eb861aSAxel Dörfler // Check our params 27089eb861aSAxel Dörfler if (archive == NULL) { 27189eb861aSAxel Dörfler syslog(LOG_ERR, "instantiate_object failed: NULL BMessage argument"); 27289eb861aSAxel Dörfler *status = B_BAD_VALUE; 27389eb861aSAxel Dörfler return NULL; 27489eb861aSAxel Dörfler } 27589eb861aSAxel Dörfler 27689eb861aSAxel Dörfler // Get class name from archive 27789eb861aSAxel Dörfler const char* className = NULL; 27889eb861aSAxel Dörfler status_t err = archive->FindString(B_CLASS_FIELD, &className); 27989eb861aSAxel Dörfler if (err) { 28089eb861aSAxel Dörfler syslog(LOG_ERR, "instantiate_object failed: Failed to find an entry " 28189eb861aSAxel Dörfler "defining the class name (%s).", strerror(err)); 28289eb861aSAxel Dörfler *status = B_BAD_VALUE; 28389eb861aSAxel Dörfler return NULL; 28489eb861aSAxel Dörfler } 28589eb861aSAxel Dörfler 28689eb861aSAxel Dörfler // Get sig from archive 28789eb861aSAxel Dörfler const char* signature = NULL; 28889eb861aSAxel Dörfler bool hasSignature = archive->FindString(B_ADD_ON_FIELD, &signature) == B_OK; 28989eb861aSAxel Dörfler 29089eb861aSAxel Dörfler instantiation_func instantiationFunc = find_instantiation_func(className, 29189eb861aSAxel Dörfler signature); 29289eb861aSAxel Dörfler 29389eb861aSAxel Dörfler // if find_instantiation_func() can't locate Class::Instantiate() 29489eb861aSAxel Dörfler // and a signature was specified 29589eb861aSAxel Dörfler if (!instantiationFunc && hasSignature) { 29689eb861aSAxel Dörfler // use BRoster::FindApp() to locate an app or add-on with the symbol 29789eb861aSAxel Dörfler BRoster Roster; 29889eb861aSAxel Dörfler entry_ref ref; 29989eb861aSAxel Dörfler err = Roster.FindApp(signature, &ref); 30089eb861aSAxel Dörfler 30189eb861aSAxel Dörfler // if an entry_ref is obtained 30289eb861aSAxel Dörfler BEntry entry; 30389eb861aSAxel Dörfler if (err == B_OK) 30489eb861aSAxel Dörfler err = entry.SetTo(&ref); 30589eb861aSAxel Dörfler 30689eb861aSAxel Dörfler BPath path; 30789eb861aSAxel Dörfler if (err == B_OK) 30889eb861aSAxel Dörfler err = entry.GetPath(&path); 30989eb861aSAxel Dörfler 31089eb861aSAxel Dörfler if (err != B_OK) { 31189eb861aSAxel Dörfler syslog(LOG_ERR, "instantiate_object failed: Error finding app " 31289eb861aSAxel Dörfler "with signature \"%s\" (%s)", signature, strerror(err)); 31389eb861aSAxel Dörfler *status = err; 31489eb861aSAxel Dörfler return NULL; 31589eb861aSAxel Dörfler } 31689eb861aSAxel Dörfler 31789eb861aSAxel Dörfler // load the app/add-on 31889eb861aSAxel Dörfler image_id addOn = load_add_on(path.Path()); 31989eb861aSAxel Dörfler if (addOn < B_OK) { 32089eb861aSAxel Dörfler syslog(LOG_ERR, "instantiate_object failed: Could not load " 32189eb861aSAxel Dörfler "add-on %s: %s.", path.Path(), strerror(addOn)); 32289eb861aSAxel Dörfler *status = addOn; 32389eb861aSAxel Dörfler return NULL; 32489eb861aSAxel Dörfler } 32589eb861aSAxel Dörfler 32689eb861aSAxel Dörfler // Save the image_id 32789eb861aSAxel Dörfler if (_id != NULL) 32889eb861aSAxel Dörfler *_id = addOn; 32989eb861aSAxel Dörfler 33089eb861aSAxel Dörfler BString name = className; 33189eb861aSAxel Dörfler for (int32 pass = 0; pass < 2; pass++) { 33289eb861aSAxel Dörfler BString funcName; 33389eb861aSAxel Dörfler build_function_name(name, funcName); 33489eb861aSAxel Dörfler 33589eb861aSAxel Dörfler instantiationFunc = find_function_in_image(funcName, addOn, err); 33689eb861aSAxel Dörfler if (instantiationFunc != NULL) 33789eb861aSAxel Dörfler break; 33889eb861aSAxel Dörfler 33989eb861aSAxel Dörfler // Check if we have a private class, and add the BPrivate namespace 34089eb861aSAxel Dörfler // (for backwards compatibility) 34189eb861aSAxel Dörfler if (!add_private_namespace(name)) 34289eb861aSAxel Dörfler break; 34389eb861aSAxel Dörfler } 34489eb861aSAxel Dörfler 34589eb861aSAxel Dörfler if (instantiationFunc == NULL) { 34689eb861aSAxel Dörfler syslog(LOG_ERR, "instantiate_object failed: Failed to find exported " 34789eb861aSAxel Dörfler "Instantiate static function for class %s.", className); 34889eb861aSAxel Dörfler *status = B_NAME_NOT_FOUND; 34989eb861aSAxel Dörfler return NULL; 35089eb861aSAxel Dörfler } 35189eb861aSAxel Dörfler } else if (instantiationFunc == NULL) { 35289eb861aSAxel Dörfler syslog(LOG_ERR, "instantiate_object failed: No signature specified " 35389eb861aSAxel Dörfler "in archive, looking for class \"%s\".", className); 35489eb861aSAxel Dörfler *status = B_NAME_NOT_FOUND; 35589eb861aSAxel Dörfler return NULL; 35689eb861aSAxel Dörfler } 35789eb861aSAxel Dörfler 35889eb861aSAxel Dörfler // if Class::Instantiate(BMessage*) was found 35989eb861aSAxel Dörfler if (instantiationFunc != NULL) { 36089eb861aSAxel Dörfler // use to create and return an object instance 36189eb861aSAxel Dörfler return instantiationFunc(archive); 36289eb861aSAxel Dörfler } 36389eb861aSAxel Dörfler 36489eb861aSAxel Dörfler return NULL; 36589eb861aSAxel Dörfler } 36689eb861aSAxel Dörfler 36789eb861aSAxel Dörfler 36889eb861aSAxel Dörfler BArchivable* 36989eb861aSAxel Dörfler instantiate_object(BMessage* from) 37089eb861aSAxel Dörfler { 37189eb861aSAxel Dörfler return instantiate_object(from, NULL); 37252a38012Sejakowatz } 3739ecf9d1cSIngo Weinhold 3749ecf9d1cSIngo Weinhold 3759ecf9d1cSIngo Weinhold bool 37689eb861aSAxel Dörfler validate_instantiation(BMessage* from, const char* className) 37752a38012Sejakowatz { 37889eb861aSAxel Dörfler // Make sure our params are kosher -- original skimped here =P 37989eb861aSAxel Dörfler if (!from) { 38089eb861aSAxel Dörfler errno = B_BAD_VALUE; 38189eb861aSAxel Dörfler return false; 38289eb861aSAxel Dörfler } 38389eb861aSAxel Dörfler 384*13bbfe42SAxel Dörfler BString name = className; 385*13bbfe42SAxel Dörfler for (int32 pass = 0; pass < 2; pass++) { 386*13bbfe42SAxel Dörfler const char* archiveClassName; 387*13bbfe42SAxel Dörfler for (int32 index = 0; from->FindString(B_CLASS_FIELD, index, 388*13bbfe42SAxel Dörfler &archiveClassName) == B_OK; ++index) { 389*13bbfe42SAxel Dörfler if (name == archiveClassName) 39052a38012Sejakowatz return true; 39152a38012Sejakowatz } 39252a38012Sejakowatz 393*13bbfe42SAxel Dörfler if (!add_private_namespace(name)) 394*13bbfe42SAxel Dörfler break; 395*13bbfe42SAxel Dörfler } 396*13bbfe42SAxel Dörfler 39789eb861aSAxel Dörfler errno = B_MISMATCHED_VALUES; 39889eb861aSAxel Dörfler syslog(LOG_ERR, "validate_instantiation failed on class %s.", className); 39952a38012Sejakowatz 40052a38012Sejakowatz return false; 40152a38012Sejakowatz } 40252a38012Sejakowatz 40389eb861aSAxel Dörfler 40489eb861aSAxel Dörfler instantiation_func 40589eb861aSAxel Dörfler find_instantiation_func(const char* className, const char* signature) 40689eb861aSAxel Dörfler { 40789eb861aSAxel Dörfler if (className == NULL) { 40889eb861aSAxel Dörfler errno = B_BAD_VALUE; 40989eb861aSAxel Dörfler return NULL; 41052a38012Sejakowatz } 41152a38012Sejakowatz 41289eb861aSAxel Dörfler thread_info threadInfo; 41389eb861aSAxel Dörfler status_t err = get_thread_info(find_thread(NULL), &threadInfo); 41489eb861aSAxel Dörfler if (err != B_OK) { 41589eb861aSAxel Dörfler errno = err; 41689eb861aSAxel Dörfler return NULL; 41789eb861aSAxel Dörfler } 41889eb861aSAxel Dörfler 41989eb861aSAxel Dörfler instantiation_func instantiationFunc = NULL; 42089eb861aSAxel Dörfler image_info imageInfo; 42189eb861aSAxel Dörfler 42289eb861aSAxel Dörfler BString name = className; 42389eb861aSAxel Dörfler for (int32 pass = 0; pass < 2; pass++) { 42489eb861aSAxel Dörfler BString funcName; 42589eb861aSAxel Dörfler build_function_name(name, funcName); 42689eb861aSAxel Dörfler 42789eb861aSAxel Dörfler // for each image_id in team_id 42889eb861aSAxel Dörfler int32 cookie = 0; 42989eb861aSAxel Dörfler while (instantiationFunc == NULL 43089eb861aSAxel Dörfler && get_next_image_info(threadInfo.team, &cookie, &imageInfo) 43189eb861aSAxel Dörfler == B_OK) { 43289eb861aSAxel Dörfler instantiationFunc = find_function_in_image(funcName, imageInfo.id, 43389eb861aSAxel Dörfler err); 43489eb861aSAxel Dörfler } 43589eb861aSAxel Dörfler if (instantiationFunc != NULL) 43689eb861aSAxel Dörfler break; 43789eb861aSAxel Dörfler 43889eb861aSAxel Dörfler // Check if we have a private class, and add the BPrivate namespace 43989eb861aSAxel Dörfler // (for backwards compatibility) 44089eb861aSAxel Dörfler if (!add_private_namespace(name)) 44189eb861aSAxel Dörfler break; 44289eb861aSAxel Dörfler } 44389eb861aSAxel Dörfler 44489eb861aSAxel Dörfler if (instantiationFunc != NULL 44589eb861aSAxel Dörfler && check_signature(signature, imageInfo) != B_OK) 44689eb861aSAxel Dörfler return NULL; 44789eb861aSAxel Dörfler 44889eb861aSAxel Dörfler return instantiationFunc; 44989eb861aSAxel Dörfler } 45089eb861aSAxel Dörfler 45189eb861aSAxel Dörfler 45289eb861aSAxel Dörfler instantiation_func 45389eb861aSAxel Dörfler find_instantiation_func(const char* className) 45489eb861aSAxel Dörfler { 45589eb861aSAxel Dörfler return find_instantiation_func(className, NULL); 45689eb861aSAxel Dörfler } 45789eb861aSAxel Dörfler 45889eb861aSAxel Dörfler 45989eb861aSAxel Dörfler instantiation_func 46089eb861aSAxel Dörfler find_instantiation_func(BMessage* archive) 46189eb861aSAxel Dörfler { 46289eb861aSAxel Dörfler if (archive == NULL) { 46389eb861aSAxel Dörfler errno = B_BAD_VALUE; 46489eb861aSAxel Dörfler return NULL; 46589eb861aSAxel Dörfler } 46689eb861aSAxel Dörfler 46789eb861aSAxel Dörfler const char* name = NULL; 46889eb861aSAxel Dörfler const char* signature = NULL; 46989eb861aSAxel Dörfler if (archive->FindString(B_CLASS_FIELD, &name) != B_OK 47089eb861aSAxel Dörfler || archive->FindString(B_ADD_ON_FIELD, &signature)) { 47189eb861aSAxel Dörfler errno = B_BAD_VALUE; 47289eb861aSAxel Dörfler return NULL; 47389eb861aSAxel Dörfler } 47489eb861aSAxel Dörfler 47589eb861aSAxel Dörfler return find_instantiation_func(name, signature); 47652a38012Sejakowatz } 47752a38012Sejakowatz 478