status_t PathHandler::_RemoveDirectory(BEntry& entry, ino_t directoryNode) { node_ref nodeRef; status_t status = entry.GetNodeRef(&nodeRef); if (status != B_OK) return status; return _RemoveDirectory(nodeRef, directoryNode); }
void PathHandler::_EntryRemoved(BMessage* message) { node_ref nodeRef; uint64 directoryNode; if (message->FindInt32("device", &nodeRef.device) != B_OK || message->FindInt64("directory", (int64 *)&directoryNode) != B_OK || message->FindInt64("node", &nodeRef.node) != B_OK) return; bool contained; if (_HasDirectory(nodeRef, &contained)) { // the directory has been removed, so we remove it as well _RemoveDirectory(nodeRef, directoryNode); if (contained && !_WatchFilesOnly()) { message->AddBool("removed", true); _NotifyTarget(message, nodeRef); } } else if (_HasFile(nodeRef)) { message->AddBool("removed", true); _NotifyTarget(message, nodeRef); _RemoveFile(nodeRef); } }
//Implementation of DeviceCtrl routine. static DWORD FatDeviceCtrl(__COMMON_OBJECT* lpDrv,__COMMON_OBJECT* lpDev, __DRCB* lpDrcb) { __COMMON_OBJECT* pFindHandle = NULL; if((NULL == lpDev) || (NULL == lpDrcb)) //Invalid parameters. { goto __TERMINAL; } //Dispatch the request to appropriate routines according to control command. switch(lpDrcb->dwCtrlCommand) { case IOCONTROL_FS_CHECKPARTITION: return CheckPartition(lpDev,(__COMMON_OBJECT*)lpDrcb->lpInputBuffer) ? 1 : 0; case IOCONTROL_FS_FINDFIRSTFILE: pFindHandle = _fat32FindFirstFile((__COMMON_OBJECT*)lpDev, (CHAR*)lpDrcb->dwExtraParam1, (FS_FIND_DATA*)lpDrcb->dwExtraParam2); if(NULL == pFindHandle) //Can not start the iterate. { return 0; } lpDrcb->lpOutputBuffer = (LPVOID)pFindHandle; return 1; case IOCONTROL_FS_FINDNEXTFILE: return _FindNextFile((__COMMON_OBJECT*)lpDev, (__COMMON_OBJECT*)lpDrcb->lpInputBuffer, (FS_FIND_DATA*)lpDrcb->dwExtraParam2) ? 1 : 0; case IOCONTROL_FS_FINDCLOSE: _fat32FindClose((__COMMON_OBJECT*)lpDev, (__COMMON_OBJECT*)lpDrcb->lpInputBuffer); break; case IOCONTROL_FS_CREATEDIR: if(_CreateDirectory(lpDev, (LPSTR)lpDrcb->lpInputBuffer, 0)) { lpDrcb->dwStatus = DRCB_STATUS_SUCCESS; return 1; } else { lpDrcb->dwStatus = DRCB_STATUS_FAIL; return 0; } break; case IOCONTROL_FS_GETFILEATTR: lpDrcb->dwExtraParam2 = _fat32GetFileAttributes( lpDev, (LPCTSTR)lpDrcb->dwExtraParam1); lpDrcb->dwStatus = DRCB_STATUS_SUCCESS; return 1; break; case IOCONTROL_FS_DELETEFILE: if(_fat32DeleteFile(lpDev, (LPSTR)lpDrcb->lpInputBuffer)) { lpDrcb->dwStatus = DRCB_STATUS_SUCCESS; return 1; } else { lpDrcb->dwStatus = DRCB_STATUS_FAIL; return 0; } break; case IOCONTROL_FS_REMOVEDIR: if(_RemoveDirectory(lpDev, (LPSTR)lpDrcb->lpInputBuffer)) { lpDrcb->dwStatus = DRCB_STATUS_SUCCESS; return 1; } else { lpDrcb->dwStatus = DRCB_STATUS_FAIL; return 0; } break; case IOCONTROL_FS_SETENDFILE: { if(_SetEndOfFile(lpDev)) { lpDrcb->dwStatus = DRCB_STATUS_SUCCESS; return 1; } else { lpDrcb->dwStatus = DRCB_STATUS_FAIL; return 0; } } break; default: break; } __TERMINAL: return 0; }
void PathHandler::_EntryMoved(BMessage* message) { // has the entry been moved into a monitored directory or has // it been removed from one? const char* name; node_ref nodeRef; uint64 fromNode; uint64 node; if (message->FindInt32("device", &nodeRef.device) != B_OK || message->FindInt64("to directory", &nodeRef.node) != B_OK || message->FindInt64("from directory", (int64 *)&fromNode) != B_OK || message->FindInt64("node", (int64 *)&node) != B_OK || message->FindString("name", &name) != B_OK) return; BEntry entry; if (set_entry(nodeRef, name, entry) != B_OK) return; bool entryContained = _IsContained(entry); bool wasAdded = false; bool wasRemoved = false; bool notify = false; bool parentContained; if (_HasDirectory(nodeRef, &parentContained)) { // something has been added to our watched directories nodeRef.node = node; TRACE(" ADDED TO PARENT (%d), has entry %d/%d, entry %d %d\n", parentContained, _HasDirectory(nodeRef), _HasFile(nodeRef), entryContained, _CloserToPath(entry)); if (entry.IsDirectory()) { if (!_HasDirectory(nodeRef) && (entryContained || _CloserToPath(entry))) { // there is a new directory to watch for us if (entryContained || (parentContained && !_WatchRecursively())) { _AddDirectory(entry, true); // NOTE: entry is toast now! } else if (_GetClosest(fPath.Path(), false, nodeRef) == B_OK) { // the new directory might put us even // closer to the path we are after _AddDirectory(nodeRef, true); } wasAdded = true; notify = entryContained; } if (_WatchFilesOnly()) notify = false; } else if (!_HasFile(nodeRef) && entryContained) { // file has been added wasAdded = true; notify = true; _AddFile(entry); } } else { // and entry has been removed from our directories wasRemoved = true; nodeRef.node = node; if (entry.IsDirectory()) { if (_HasDirectory(nodeRef, ¬ify)) _RemoveDirectory(entry, fromNode); if (_WatchFilesOnly()) notify = false; } else { _RemoveFile(entry); notify = true; } } if (notify) { if (wasAdded) message->AddBool("added", true); if (wasRemoved) message->AddBool("removed", true); _NotifyTarget(message, nodeRef); } }
void FontManager::MessageReceived(BMessage* message) { switch (message->what) { case B_NODE_MONITOR: { // TODO: support removing fonts! int32 opcode; if (message->FindInt32("opcode", &opcode) != B_OK) return; switch (opcode) { case B_ENTRY_CREATED: { const char* name; node_ref nodeRef; if (message->FindInt32("device", &nodeRef.device) != B_OK || message->FindInt64("directory", &nodeRef.node) != B_OK || message->FindString("name", &name) != B_OK) break; // TODO: make this better (possible under Haiku) snooze(100000); // let the font be written completely before trying to open it BEntry entry; if (set_entry(nodeRef, name, entry) != B_OK) break; if (entry.IsDirectory()) { // a new directory to watch for us _AddPath(entry); } else { // a new font font_directory* directory = _FindDirectory(nodeRef); if (directory == NULL) { // unknown directory? how come? break; } _AddFont(*directory, entry); } break; } case B_ENTRY_MOVED: { // has the entry been moved into a monitored directory or has // it been removed from one? const char* name; node_ref nodeRef; uint64 fromNode; uint64 node; if (message->FindInt32("device", &nodeRef.device) != B_OK || message->FindInt64("to directory", &nodeRef.node) != B_OK || message->FindInt64("from directory", (int64 *)&fromNode) != B_OK || message->FindInt64("node", (int64 *)&node) != B_OK || message->FindString("name", &name) != B_OK) break; font_directory* directory = _FindDirectory(nodeRef); BEntry entry; if (set_entry(nodeRef, name, entry) != B_OK) break; if (directory != NULL) { // something has been added to our watched font directories // test, if the source directory is one of ours as well nodeRef.node = fromNode; font_directory* fromDirectory = _FindDirectory(nodeRef); if (entry.IsDirectory()) { if (fromDirectory == NULL) { // there is a new directory to watch for us _AddPath(entry); FTRACE("new directory moved in"); } else { // A directory from our watched directories has // been renamed or moved within the watched // directories - we only need to update the // path names of the styles in that directory nodeRef.node = node; directory = _FindDirectory(nodeRef); if (directory != NULL) { for (int32 i = 0; i < directory->styles.CountItems(); i++) { FontStyle* style = directory->styles.ItemAt(i); style->UpdatePath(directory->directory); } } FTRACE("directory renamed"); } } else { if (fromDirectory != NULL) { // find style in source and move it to the target nodeRef.node = node; FontStyle* style = fromDirectory->FindStyle(nodeRef); if (style != NULL) { fromDirectory->styles.RemoveItem(style, false); directory->styles.AddItem(style); style->UpdatePath(directory->directory); } FTRACE(("font moved")); } else { FTRACE(("font added: %s\n", name)); _AddFont(*directory, entry); } } } else { // and entry has been removed from our font directories if (entry.IsDirectory()) { if (entry.GetNodeRef(&nodeRef) == B_OK && (directory = _FindDirectory(nodeRef)) != NULL) _RemoveDirectory(directory); } else { // remove font style from directory _RemoveStyle(nodeRef.device, fromNode, node); } } break; } case B_ENTRY_REMOVED: { node_ref nodeRef; uint64 directoryNode; if (message->FindInt32("device", &nodeRef.device) != B_OK || message->FindInt64("directory", (int64 *)&directoryNode) != B_OK || message->FindInt64("node", &nodeRef.node) != B_OK) break; font_directory* directory = _FindDirectory(nodeRef); if (directory != NULL) { // the directory has been removed, so we remove it as well _RemoveDirectory(directory); } else { // remove font style from directory _RemoveStyle(nodeRef.device, directoryNode, nodeRef.node); } break; } } break; } } }