コード例 #1
0
ファイル: AddOnManager.cpp プロジェクト: AmirAbrams/haiku
bool
AddOnManager::_FindDecoder(const media_format& format, const BPath& path,
	entry_ref* _decoderRef)
{
	node_ref nref;
	BDirectory directory;
	if (directory.SetTo(path.Path()) != B_OK
		|| directory.GetNodeRef(&nref) != B_OK) {
		return false;
	}

	decoder_info* info;
	for (fDecoderList.Rewind(); fDecoderList.GetNext(&info);) {
		if (info->ref.directory != nref.node)
			continue;

		media_format* decoderFormat;
		for (info->formats.Rewind(); info->formats.GetNext(&decoderFormat);) {
			// check if the decoder matches the supplied format
			if (!decoderFormat->Matches(&format))
				continue;

			*_decoderRef = info->ref;
			return true;
		}
	}
	return false;
}
コード例 #2
0
ファイル: Tracker.cpp プロジェクト: Ithamar/cosmoe
void
TTracker::Pulse()
{
	if (!TrackerSettings().ShowVolumeSpaceBar())
		return;

	// update the volume icon's free space bars
	BVolumeRoster roster;

 	BVolume volume;
	while (roster.GetNextVolume(&volume) == B_NO_ERROR)
	{
		BDirectory dir;
		volume.GetRootDirectory(&dir);
		node_ref nodeRef;
		dir.GetNodeRef(&nodeRef);

		BMessage notificationMessage;
		notificationMessage.AddInt32("device", *(int32 *)&nodeRef.device);

		LockLooper();
		SendNotices(kUpdateVolumeSpaceBar, &notificationMessage);
		UnlockLooper();
	}
}
コード例 #3
0
ファイル: PathMonitor.cpp プロジェクト: mmanley/Antares
status_t
PathHandler::_GetClosest(const char* path, bool updatePath, node_ref& nodeRef)
{
	BPath first(path);
	BString missing;

	while (true) {
		// try to find the first part of the path that exists
		BDirectory directory;
		status_t status = directory.SetTo(first.Path());
		if (status == B_OK) {
			status = directory.GetNodeRef(&nodeRef);
			if (status == B_OK) {
				if (updatePath) {
					// normalize path
					status = fPath.SetTo(&directory, NULL, true);
					if (status == B_OK) {
						fPath.Append(missing.String());
						fPathLength = strlen(fPath.Path());
					}
				}
				return status;
			}
		}

		if (updatePath) {
			if (missing.Length() > 0)
				missing.Prepend("/");
			missing.Prepend(first.Leaf());
		}

		if (first.GetParent(&first) != B_OK)
			return B_ERROR;
	}
}
コード例 #4
0
ファイル: PrinterListView.cpp プロジェクト: AmirAbrams/haiku
void
PrinterListView::_AddPrinter(BDirectory& printer, bool calculateLayout)
{
	BString state;
	node_ref node;
		// If the entry is a directory
	if (printer.InitCheck() == B_OK
		&& printer.GetNodeRef(&node) == B_OK
		&& _FindItem(&node) == NULL
		&& printer.ReadAttrString(PSRV_PRINTER_ATTR_STATE, &state) == B_OK
		&& state == "free") {
			// Check it's Mime type for a spool director
		BNodeInfo info(&printer);
		char buffer[256];

		if (info.GetType(buffer) == B_OK
			&& strcmp(buffer, PSRV_PRINTER_FILETYPE) == 0) {
				// Yes, it is a printer definition node
			AddItem(new PrinterItem(static_cast<PrintersWindow*>(Window()),
				printer, fLayoutData));
			if (calculateLayout)
				_LayoutPrinterItems();
		}
	}
}
コード例 #5
0
ファイル: AddOnManager.cpp プロジェクト: AmirAbrams/haiku
bool
AddOnManager::_FindEncoder(const media_format& format, const BPath& path,
	entry_ref* _encoderRef)
{
	node_ref nref;
	BDirectory directory;
	if (directory.SetTo(path.Path()) != B_OK
		|| directory.GetNodeRef(&nref) != B_OK) {
		return false;
	}

	encoder_info* info;
	for (fEncoderList.Rewind(); fEncoderList.GetNext(&info);) {
		if (info->ref.directory != nref.node)
			continue;

		// check if the encoder matches the supplied format
		if (info->outputFormat.Matches(&format)) {
			*_encoderRef = info->ref;
			return true;
		}
		continue;
	}
	return false;
}
コード例 #6
0
void
BTrashWatcher::MessageReceived(BMessage* message)
{
	if (message->what != B_NODE_MONITOR) {
		_inherited::MessageReceived(message);
		return;
	}

	switch (message->FindInt32("opcode")) {
		case B_ENTRY_CREATED:
			if (!fTrashFull) {
				fTrashFull = true;
				UpdateTrashIcons();
			}
			break;

		case B_ENTRY_MOVED:
		{
			// allow code to fall through if move is from/to trash
			// but do nothing for moves in the same directory
			ino_t toDir;
			ino_t fromDir;
			message->FindInt64("from directory", &fromDir);
			message->FindInt64("to directory", &toDir);
			if (fromDir == toDir)
				break;
		} // fall thru
		case B_DEVICE_UNMOUNTED: // fall thru
		case B_ENTRY_REMOVED:
		{
			bool full = CheckTrashDirs();
			if (fTrashFull != full) {
				fTrashFull = full;
				UpdateTrashIcons();
			}
			break;
		}
		// We should handle DEVICE_UNMOUNTED here too to remove trash

		case B_DEVICE_MOUNTED:
		{
			dev_t device;
			BDirectory trashDir;
			if (message->FindInt32("new device", &device) == B_OK
				&& FSGetTrashDir(&trashDir, device) == B_OK) {
				node_ref trashNode;
				trashDir.GetNodeRef(&trashNode);
				TTracker::WatchNode(&trashNode, B_WATCH_DIRECTORY, this);
				fTrashNodeList.AddItem(new node_ref(trashNode));

				// Check if the new volume has anything trashed.
				if (CheckTrashDirs() && !fTrashFull) {
					fTrashFull = true;
					UpdateTrashIcons();
				}
			}
			break;
		}
	}
}
コード例 #7
0
ファイル: AddOnManager.cpp プロジェクト: naveedasmat/haiku
bool
AddOnManager::_FindDecoder(const media_format& format, const BPath& path,
	xfer_entry_ref* _decoderRef)
{
	node_ref nref;
	BDirectory directory;
	if (directory.SetTo(path.Path()) != B_OK
		|| directory.GetNodeRef(&nref) != B_OK) {
		return false;
	}

	decoder_info* info;
	for (fDecoderList.Rewind(); fDecoderList.GetNext(&info);) {
		if (info->ref.directory != nref.node)
			continue;

		media_format* decoderFormat;
		for (info->formats.Rewind(); info->formats.GetNext(&decoderFormat);) {
			// check if the decoder matches the supplied format
			if (!decoderFormat->Matches(&format))
				continue;

			printf("AddOnManager::GetDecoderForFormat: found decoder %s/%s "
				"for encoding %" B_PRIu32 "\n", path.Path(), info->ref.name,
				decoderFormat->Encoding());

			*_decoderRef = info->ref;
			return true;
		}
	}
	return false;
}
コード例 #8
0
ファイル: AddOnManager.cpp プロジェクト: mmanley/Antares
void
AddOnManager::_RegisterAddOns()
{
	CALLED();
	BAutolock locker(this);
	status_t err;

	fHandler = new MonitorHandler(this);
	fAddOnMonitor = new AddOnMonitor(fHandler);

	err = fAddOnMonitor->InitCheck();
	if (err != B_OK) {
		ERROR("AddOnManager::RegisterAddOns(): fAddOnMonitor->InitCheck() "
			"returned %s\n", strerror(err));
		return;
	}

	const directory_which directories[] = {
		B_USER_ADDONS_DIRECTORY,
		B_COMMON_ADDONS_DIRECTORY,
		B_BEOS_ADDONS_DIRECTORY
	};
	const char* subDirectories[] = {
		"input_server/devices",
		"input_server/filters",
		"input_server/methods"
	};
	int32 subDirectoryCount = sizeof(subDirectories) / sizeof(const char*);

	node_ref nref;
	BDirectory directory;
	BPath path;
	// when safemode, only B_BEOS_ADDONS_DIRECTORY is used
	for (uint32 i = fSafeMode ? 2 : 0;
			i < sizeof(directories) / sizeof(directory_which); i++) {
		for (int32 j = 0; j < subDirectoryCount; j++) {
			if (find_directory(directories[i], &path) == B_OK
				&& path.Append(subDirectories[j]) == B_OK
				&& directory.SetTo(path.Path()) == B_OK
				&& directory.GetNodeRef(&nref) == B_OK) {
				fHandler->AddDirectory(&nref);
			}
		}
	}
}
コード例 #9
0
void
BTrashWatcher::WatchTrashDirs()
{
	BVolumeRoster volRoster;
	volRoster.Rewind();
	BVolume	volume;
	while (volRoster.GetNextVolume(&volume) == B_OK) {
		if (volume.IsReadOnly() || !volume.IsPersistent())
			continue;

		BDirectory trashDir;
		if (FSGetTrashDir(&trashDir, volume.Device()) == B_OK) {
			node_ref trash_node;
			trashDir.GetNodeRef(&trash_node);
			watch_node(&trash_node, B_WATCH_DIRECTORY, this);
			fTrashNodeList.AddItem(new node_ref(trash_node));
		}
	}
}
コード例 #10
0
ファイル: AddOnManager.cpp プロジェクト: AmirAbrams/haiku
void
AddOnManager::_GetReaders(const BPath& path, entry_ref* outRefs,
	int32* outCount, int32 maxCount)
{
	node_ref nref;
	BDirectory directory;
	if (directory.SetTo(path.Path()) != B_OK
		|| directory.GetNodeRef(&nref) != B_OK) {
		return;
	}

	reader_info* info;
	for (fReaderList.Rewind(); fReaderList.GetNext(&info)
		&& *outCount < maxCount;) {
		if (info->ref.directory != nref.node)
			continue;

		outRefs[*outCount] = info->ref;
		(*outCount)++;
	}
}
コード例 #11
0
ファイル: Tracker.cpp プロジェクト: Ithamar/cosmoe
void
TTracker::ReadyToRun()
{
	gStatusWindow = new BStatusWindow();
	InitMimeTypes();
	InstallDefaultTemplates();
	InstallIndices();
	
	HideVarDir();

	fTrashWatcher = new BTrashWatcher();
	fTrashWatcher->Run();

	fClipboardRefsWatcher = new BClipboardRefsWatcher();
	fClipboardRefsWatcher->Run();
	
	fAutoMounter = new AutoMounter();
	fAutoMounter->Run();
	
	fTaskLoop = new StandAloneTaskLoop(true);

	bool openDisksWindow = false;

	// open desktop window 
	BContainerWindow *deskWindow = NULL;
	BVolume	bootVol;
	BVolumeRoster().GetBootVolume(&bootVol);
	BDirectory deskDir;
	if (FSGetDeskDir(&deskDir, bootVol.Device()) == B_OK) {
		// create desktop
		BEntry entry;
		deskDir.GetEntry(&entry);
		Model *model = new Model(&entry);
		if (model->InitCheck() == B_OK) {
			AutoLock<WindowList> lock(&fWindowList);
			deskWindow = new BDeskWindow(&fWindowList);
			AutoLock<BWindow> windowLock(deskWindow);
			deskWindow->CreatePoseView(model);
			deskWindow->Init();
		} else
			delete model;

		// open previously open windows
		attr_info attrInfo;
		if (!BootedInSafeMode()
			&& deskDir.GetAttrInfo(kAttrOpenWindows, &attrInfo) == B_OK) {
			char *buffer = (char *)malloc((size_t)attrInfo.size);
			BMessage message;
			if (deskDir.ReadAttr(kAttrOpenWindows, B_MESSAGE_TYPE, 0, buffer, (size_t)attrInfo.size)
				== attrInfo.size
				&& message.Unflatten(buffer) == B_OK) {

				node_ref nodeRef;
				deskDir.GetNodeRef(&nodeRef);
	
				int32 stateMessageCounter = 0;
				const char *path;
				for (int32 outer = 0;message.FindString("paths", outer, &path) == B_OK;outer++) {
					int8 flags = 0;
					for (int32 inner = 0;message.FindInt8(path, inner, &flags) == B_OK;inner++) {
						BEntry entry(path, true);
						if (entry.InitCheck() == B_OK) {
							Model *model = new Model(&entry);
							if (model->InitCheck() == B_OK && model->IsContainer()) {
								BMessage state;
								bool restoreStateFromMessage = false;
								if ((flags & kOpenWindowHasState) != 0
									&& message.FindMessage("window state", stateMessageCounter++, &state) == B_OK)
									restoreStateFromMessage = true;

								if (restoreStateFromMessage)
									OpenContainerWindow(model, 0, kOpen, 
										kRestoreWorkspace | (flags & kOpenWindowMinimized ? kIsHidden : 0U),
										false, &state);
								else
									OpenContainerWindow(model, 0, kOpen, 
										kRestoreWorkspace | (flags & kOpenWindowMinimized ? kIsHidden : 0U));
							} else
								delete model;
						}
					}
				}
	
				if (message.HasBool("open_disks_window"))
					openDisksWindow = true;
			}
			free(buffer);
		}
	}

	// create model for root of everything
	if (deskWindow) {
		BEntry entry("/");
		Model model(&entry);
		if (model.InitCheck() == B_OK) {

			if (TrackerSettings().ShowDisksIcon()) {
				// add the root icon to desktop window
				BMessage message;
				message.what = B_NODE_MONITOR;
				message.AddInt32("opcode", B_ENTRY_CREATED);
				message.AddInt32("device", model.NodeRef()->device);
				message.AddInt64("node", model.NodeRef()->node);
				message.AddInt64("directory", model.EntryRef()->directory);
				message.AddString("name", model.EntryRef()->name);
				deskWindow->PostMessage(&message, deskWindow->PoseView());
			}
			
			if (openDisksWindow)
				OpenContainerWindow(new Model(model), 0, kOpen, kRestoreWorkspace);
		}
	}

	// kick off building the mime type list for find panels, etc.
	fMimeTypeList = new MimeTypeList();

	if (!BootedInSafeMode())
		// kick of transient query killer
		DeleteTransientQueriesTask::StartUpTransientQueryCleaner();
}
コード例 #12
0
void
MediaAddonServer::ReadyToRun()
{
	if (!be_roster->IsRunning("application/x-vnd.Be.media-server")) {
		// the media server is not running, let's quit
		fprintf(stderr, "The media_server is not running!\n");
		Quit();
		return;
	}

	// the control thread is already running at this point,
	// so we can talk to the media server and also receive
	// commands for instantiation

	ASSERT(fStartup == true);

	// The very first thing to do is to create the system time source,
	// register it with the server, and make it the default SYSTEM_TIME_SOURCE
	BMediaNode *timeSource = new SystemTimeSource;
	status_t result = fMediaRoster->RegisterNode(timeSource);
	if (result != B_OK) {
		fprintf(stderr, "Can't register system time source : %s\n",
			strerror(result));
		debugger("Can't register system time source");
	}

	if (timeSource->ID() != NODE_SYSTEM_TIMESOURCE_ID)
		debugger("System time source got wrong node ID");
	media_node node = timeSource->Node();
	result = MediaRosterEx(fMediaRoster)->SetNode(SYSTEM_TIME_SOURCE, &node);
	if (result != B_OK)
		debugger("Can't setup system time source as default");

	// During startup, first all add-ons are loaded, then all
	// nodes (flavors) representing physical inputs and outputs
	// are instantiated. Next, all add-ons that need autostart
	// will be autostarted. Finally, add-ons that don't have
	// any active nodes (flavors) will be unloaded.

	char parameter[32];
	size_t parameterLength = sizeof(parameter);
	bool safeMode = false;
	if (_kern_get_safemode_option(B_SAFEMODE_SAFE_MODE, parameter,
			&parameterLength) == B_OK) {
		if (!strcasecmp(parameter, "enabled") || !strcasecmp(parameter, "on")
			|| !strcasecmp(parameter, "true") || !strcasecmp(parameter, "yes")
			|| !strcasecmp(parameter, "enable") || !strcmp(parameter, "1"))
			safeMode = true;
	}

	fMonitorHandler = new MonitorHandler(this);
	AddHandler(fMonitorHandler);

	BMessage pulse(B_PULSE);
	fPulseRunner = new BMessageRunner(fMonitorHandler, &pulse, 1000000LL);
		// the monitor handler needs a pulse to check if add-ons are ready

	// load dormant media nodes
	const directory_which directories[] = {
		B_USER_ADDONS_DIRECTORY,
		B_COMMON_ADDONS_DIRECTORY,
		B_SYSTEM_ADDONS_DIRECTORY
	};

	// when safemode, only B_SYSTEM_ADDONS_DIRECTORY is used
	for (uint32 i = safeMode ? 2 : 0;
			i < sizeof(directories) / sizeof(directory_which); i++) {
		BDirectory directory;
		node_ref nodeRef;
		BPath path;
		if (find_directory(directories[i], &path) == B_OK
			&& path.Append("media") == B_OK
			&& directory.SetTo(path.Path()) == B_OK
			&& directory.GetNodeRef(&nodeRef) == B_OK)
			fMonitorHandler->AddDirectory(&nodeRef);
	}

#ifdef USER_ADDON_PATH
	node_ref nodeRef;
	if (entry.SetTo(USER_ADDON_PATH) == B_OK
		&& entry.GetNodeRef(&nodeRef) == B_OK)
		fMonitorHandler->AddDirectory(&nodeRef);
#endif

	fStartup = false;

	InfoMap::iterator iterator = fInfoMap.begin();
	for (; iterator != fInfoMap.end(); iterator++)
		_InstantiatePhysicalInputsAndOutputs(iterator->second);

	for (iterator = fInfoMap.begin(); iterator != fInfoMap.end(); iterator++)
		_InstantiateAutostartFlavors(iterator->second);

	for (iterator = fInfoMap.begin(); iterator != fInfoMap.end(); iterator++)
		_PutAddonIfPossible(iterator->second);

	server_rescan_defaults_command cmd;
	SendToServer(SERVER_RESCAN_DEFAULTS, &cmd, sizeof(cmd));
}
コード例 #13
0
void
TTracker::_OpenPreviouslyOpenedWindows(const char* pathFilter)
{
	size_t filterLength = 0;
	if (pathFilter != NULL)
		filterLength = strlen(pathFilter);

	BDirectory deskDir;
	attr_info attrInfo;
	if (FSGetDeskDir(&deskDir) != B_OK
		|| deskDir.GetAttrInfo(kAttrOpenWindows, &attrInfo) != B_OK)
		return;

	char *buffer = (char *)malloc((size_t)attrInfo.size);
	BMessage message;
	if (deskDir.ReadAttr(kAttrOpenWindows, B_MESSAGE_TYPE, 0, buffer,
		(size_t)attrInfo.size) != attrInfo.size
		|| message.Unflatten(buffer) != B_OK) {
		free(buffer);
		return;
	}

	free(buffer);

	node_ref nodeRef;
	deskDir.GetNodeRef(&nodeRef);

	int32 stateMessageCounter = 0;
	const char *path;
	for (int32 i = 0; message.FindString("paths", i, &path) == B_OK; i++) {
		if (strncmp(path, pathFilter, filterLength))
			continue;

		BEntry entry(path, true);
		if (entry.InitCheck() != B_OK)
			continue;

		int8 flags = 0;
		for (int32 j = 0; message.FindInt8(path, j, &flags) == B_OK; j++) {
			Model *model = new Model(&entry);
			if (model->InitCheck() == B_OK && model->IsContainer()) {
				BMessage state;
				bool restoreStateFromMessage = false;
				if ((flags & kOpenWindowHasState) != 0
					&& message.FindMessage("window state", stateMessageCounter++,
							&state) == B_OK)
					restoreStateFromMessage = true;

				if (restoreStateFromMessage) {
					OpenContainerWindow(model, 0, kOpen, kRestoreWorkspace
						| (flags & kOpenWindowMinimized ? kIsHidden : 0U)
						| kRestoreDecor, false, &state);
				} else {
					OpenContainerWindow(model, 0, kOpen, kRestoreWorkspace
						| (flags & kOpenWindowMinimized ? kIsHidden : 0U)
						| kRestoreDecor);
				}
			} else
				delete model;
		}
	}

	// Open disks window if needed

	if (pathFilter == NULL && TrackerSettings().ShowDisksIcon()
		&& message.HasBool("open_disks_window")) {
		BEntry entry("/");
		Model* model = new Model(&entry);
		if (model->InitCheck() == B_OK)
			OpenContainerWindow(model, 0, kOpen, kRestoreWorkspace);
		else
			delete model;
	}
}
コード例 #14
0
ファイル: BeHappy.cpp プロジェクト: mmadia/behappy-svn_clone
void BeHappy::SearchAddOns()
{
	// on vide les listes
	{
		BPath *p;
		while ((p=(BPath*)addOnsPaths.RemoveItem((int32)0))!=NULL)
			delete p;
			
		BString *s;
		while ((s=(BString*)addOnsNames.RemoveItem((int32)0))!=NULL)
			delete s;
	}
		
	// d'abord on cherche le dossier
	app_info myInfo;
	be_app->GetAppInfo(&myInfo);
	BEntry appEntry(&(myInfo.ref));
	BDirectory addOnsDir;
	appEntry.GetParent(&addOnsDir);
	
	// parcours de tous les fichiers du dossier
	if (addOnsDir.SetTo(&addOnsDir,"Add-ons")==B_OK)
	{
		BEntry addOn;
		while (addOnsDir.GetNextEntry(&addOn,true) == B_OK)
		{
			BPath *addOnPath = new BPath;
			addOn.GetPath(addOnPath);
			// extraction du type MIME
			{
				BNode myNode(&addOn);
								
				BNodeInfo myNodeInfo(&myNode);
				char mimeType[256];
				myNodeInfo.GetType(mimeType);
				if (BString("application/x-vnd.Be-elfexecutable") != mimeType)
					continue;
			}
			
			// on est sûrs que c'est un Add-on
			BString *projName = new BString;
			if (CheckAddOn(addOnPath->Path(),true,projName))
			{
				addOnsPaths.AddItem(addOnPath);
				addOnsNames.AddItem(projName);
			}
			else
			{
				delete addOnPath;
				delete projName;
			}
			
			// si c'est la première fois que SearchAddOns est appelé, on doit activer le node monitor
			if (!addOnsSearched)
			{
				addOnsSearched = true;
				
				node_ref myRef;
				addOnsDir.GetNodeRef(&myRef);
				watch_node(&myRef,B_WATCH_DIRECTORY,be_app_messenger);
			}
		}
	}
	else
	{
		BAlert *myAlert = new BAlert("BeHappy",T("Can't find Add-ons folder"),
			"Quit",NULL,NULL,B_WIDTH_AS_USUAL,B_STOP_ALERT);
		
		myAlert->Go();
		PostMessage(B_QUIT_REQUESTED);
	}
}
コード例 #15
0
ファイル: AddOnManager.cpp プロジェクト: naveedasmat/haiku
void
AddOnManager::_RegisterAddOns()
{
	class CodecHandler : public AddOnMonitorHandler {
	private:
		AddOnManager* fManager;

	public:
		CodecHandler(AddOnManager* manager)
		{
			fManager = manager;
		}

		virtual void AddOnCreated(const add_on_entry_info* entryInfo)
		{
		}

		virtual void AddOnEnabled(const add_on_entry_info* entryInfo)
		{
			entry_ref ref;
			make_entry_ref(entryInfo->dir_nref.device,
				entryInfo->dir_nref.node, entryInfo->name, &ref);
			fManager->_RegisterAddOn(ref);
		}

		virtual void AddOnDisabled(const add_on_entry_info* entryInfo)
		{
			entry_ref ref;
			make_entry_ref(entryInfo->dir_nref.device,
				entryInfo->dir_nref.node, entryInfo->name, &ref);
			fManager->_UnregisterAddOn(ref);
		}

		virtual void AddOnRemoved(const add_on_entry_info* entryInfo)
		{
		}
	};

	fAddOnMonitorHandler = new CodecHandler(this);
	fAddOnMonitor = new AddOnMonitor(fAddOnMonitorHandler);

	// get safemode option for disabling user add-ons

	char buffer[16];
	size_t size = sizeof(buffer);

	bool disableUserAddOns = _kern_get_safemode_option(
			B_SAFEMODE_DISABLE_USER_ADD_ONS, buffer, &size) == B_OK
		&& (!strcasecmp(buffer, "true")
			|| !strcasecmp(buffer, "yes")
			|| !strcasecmp(buffer, "on")
			|| !strcasecmp(buffer, "enabled")
			|| !strcmp(buffer, "1"));

	node_ref nref;
	BDirectory directory;
	BPath path;
	for (uint i = 0; i < sizeof(sDirectories) / sizeof(directory_which); i++) {
		if (disableUserAddOns && i <= 1)
			continue;

		if (find_directory(sDirectories[i], &path) == B_OK
			&& path.Append("media/plugins") == B_OK
			&& directory.SetTo(path.Path()) == B_OK
			&& directory.GetNodeRef(&nref) == B_OK) {
			fAddOnMonitorHandler->AddDirectory(&nref);
				// NOTE: This may already start registering add-ons in the
				// AddOnMonitor looper thread after the call returns!
		}
	}
}