/*! \brief Initializes the roster. Currently only adds the registrar to the roster. The application must already be running, more precisly Run() must have been called. \return - \c B_OK: Everything went fine. - an error code */ status_t TRoster::Init() { // check lock initialization if (fLock.Sem() < 0) return fLock.Sem(); // create the info RosterAppInfo* info = new(nothrow) RosterAppInfo; if (info == NULL) return B_NO_MEMORY; // get the app's ref entry_ref ref; status_t error = get_app_ref(&ref); // init and add the info if (error == B_OK) { info->Init(be_app->Thread(), be_app->Team(), BMessenger::Private(be_app_messenger).Port(), B_EXCLUSIVE_LAUNCH | B_BACKGROUND_APP, &ref, B_REGISTRAR_SIGNATURE); info->state = APP_STATE_REGISTERED; info->registration_time = system_time(); error = AddApp(info); } if (error == B_OK) _LoadRosterSettings(); // cleanup on error if (error != B_OK) delete info; return error; }
/*! \brief Handles an AddApplication() request. \param request The request message */ void TRoster::HandleAddApplication(BMessage* request) { FUNCTION_START(); BAutolock _(fLock); status_t error = B_OK; // get the parameters const char* signature; entry_ref ref; uint32 flags; team_id team; thread_id thread; port_id port; bool fullReg; if (request->FindString("signature", &signature) != B_OK) signature = NULL; if (request->FindRef("ref", &ref) != B_OK) SET_ERROR(error, B_BAD_VALUE); if (request->FindInt32("flags", (int32*)&flags) != B_OK) flags = B_REG_DEFAULT_APP_FLAGS; if (request->FindInt32("team", &team) != B_OK) team = -1; if (request->FindInt32("thread", &thread) != B_OK) thread = -1; if (request->FindInt32("port", &port) != B_OK) port = -1; if (request->FindBool("full_registration", &fullReg) != B_OK) fullReg = false; PRINT("team: %" B_PRId32 ", signature: %s\n", team, signature); PRINT("full registration: %d\n", fullReg); if (fShuttingDown) error = B_SHUTTING_DOWN; // check the parameters team_id otherTeam = -1; uint32 token = 0; uint32 launchFlags = flags & B_LAUNCH_MASK; BEntry entry(&ref); if (!entry.Exists()) SET_ERROR(error, B_ENTRY_NOT_FOUND); if (error == B_OK) _ValidateRunning(ref, signature); // entry_ref if (error == B_OK) { PRINT("flags: %" B_PRIx32 "\n", flags); PRINT("ref: %" B_PRId32 ", %" B_PRId64 ", %s\n", ref.device, ref.directory, ref.name); // check single/exclusive launchers RosterAppInfo* info = NULL; if ((launchFlags == B_SINGLE_LAUNCH || launchFlags == B_EXCLUSIVE_LAUNCH) && ((info = fRegisteredApps.InfoFor(&ref)) != NULL || (info = fEarlyPreRegisteredApps.InfoFor(&ref)) != NULL)) { SET_ERROR(error, B_ALREADY_RUNNING); otherTeam = info->team; token = info->token; } } // signature if (error == B_OK && signature) { // check exclusive launchers RosterAppInfo* info = NULL; if (launchFlags == B_EXCLUSIVE_LAUNCH && (((info = fRegisteredApps.InfoFor(signature))) || ((info = fEarlyPreRegisteredApps.InfoFor(signature))))) { SET_ERROR(error, B_ALREADY_RUNNING); otherTeam = info->team; token = info->token; } } // If no team ID is given, full registration isn't possible. if (error == B_OK) { if (team < 0) { if (fullReg) SET_ERROR(error, B_BAD_VALUE); } else if (fRegisteredApps.InfoFor(team)) SET_ERROR(error, B_REG_ALREADY_REGISTERED); } // Add the application info. if (error == B_OK) { // alloc and init the info RosterAppInfo* info = new(nothrow) RosterAppInfo; if (info) { info->Init(thread, team, port, flags, &ref, signature); if (fullReg) info->state = APP_STATE_REGISTERED; else info->state = APP_STATE_PRE_REGISTERED; info->registration_time = system_time(); // add it to the right list bool addingSuccess = false; if (team >= 0) { PRINT("added ref: %" B_PRId32 ", %" B_PRId64 ", %s\n", info->ref.device, info->ref.directory, info->ref.name); addingSuccess = (AddApp(info) == B_OK); if (addingSuccess && fullReg) _AppAdded(info); } else { token = info->token = _NextToken(); addingSuccess = fEarlyPreRegisteredApps.AddInfo(info); PRINT("added to early pre-regs, token: %" B_PRIu32 "\n", token); } if (!addingSuccess) SET_ERROR(error, B_NO_MEMORY); } else SET_ERROR(error, B_NO_MEMORY); // delete the info on failure if (error != B_OK && info) delete info; } // reply to the request if (error == B_OK) { // add to recent apps if successful if (signature && signature[0] != '\0') fRecentApps.Add(signature, flags); else fRecentApps.Add(&ref, flags); BMessage reply(B_REG_SUCCESS); // The token is valid only when no team ID has been supplied. if (team < 0) reply.AddInt32("token", (int32)token); request->SendReply(&reply); } else { BMessage reply(B_REG_ERROR); reply.AddInt32("error", error); if (otherTeam >= 0) reply.AddInt32("other_team", otherTeam); if (token > 0) reply.AddInt32("token", (int32)token); request->SendReply(&reply); } FUNCTION_END(); }