示例#1
0
/*!	\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;
}
示例#2
0
/*!	\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();
}