int ntfs_dirclose_r (struct _reent *r, DIR_ITER *dirState) { ntfs_log_trace("dirState %p\n", dirState); ntfs_dir_state* dir = STATE(dirState); // Sanity check if (!dir || !dir->vd) { r->_errno = EBADF; return -1; } // Lock ntfsLock(dir->vd); // Close the directory ntfsCloseDir(dir); // Remove the directory from the double-linked FILO list of open directories dir->vd->openDirCount--; if (dir->nextOpenDir) dir->nextOpenDir->prevOpenDir = dir->prevOpenDir; if (dir->prevOpenDir) dir->prevOpenDir->nextOpenDir = dir->nextOpenDir; else dir->vd->firstOpenDir = dir->nextOpenDir; // Unlock ntfsUnlock(dir->vd); return 0; }
void ntfsDeinitVolume (ntfs_vd *vd) { // Sanity check if (!vd) { errno = ENODEV; return; } // Lock ntfsLock(vd); // Close any directories which are still open (lazy programmers!) ntfs_dir_state *nextDir = vd->firstOpenDir; while (nextDir) { ntfs_log_warning("Cleaning up orphaned directory @ %p\n", nextDir); ntfsCloseDir(nextDir); nextDir = nextDir->nextOpenDir; } // Close any files which are still open (lazy programmers!) ntfs_file_state *nextFile = vd->firstOpenFile; while (nextFile) { ntfs_log_warning("Cleaning up orphaned file @ %p\n", nextFile); ntfsCloseFile(nextFile); nextFile = nextFile->nextOpenFile; } // Reset open directory and file stats vd->openDirCount = 0; vd->openFileCount = 0; vd->firstOpenDir = NULL; vd->firstOpenFile = NULL; // Close the volumes current directory (if any) //if (vd->cwd_ni) { //ntfsCloseEntry(vd, vd->cwd_ni); //vd->cwd_ni = NULL; //} // Force the underlying device to sync ntfs_device_sync(vd->dev); // Unlock ntfsUnlock(vd); #ifndef LIBXENON // Deinitialise the volume lock LWP_MutexDestroy(vd->lock); #endif return; }
DIR_ITER *ntfs_diropen_r (struct _reent *r, DIR_ITER *dirState, const char *path) { ntfs_log_trace("dirState %p, path %s\n", dirState, path); ntfs_dir_state* dir = STATE(dirState); s64 position = 0; // Get the volume descriptor for this path dir->vd = ntfsGetVolume(path); if (!dir->vd) { r->_errno = ENODEV; return NULL; } // Lock ntfsLock(dir->vd); // Find the directory dir->ni = ntfsOpenEntry(dir->vd, path); if (!dir->ni) { ntfsUnlock(dir->vd); r->_errno = ENOENT; return NULL; } // Ensure that this directory is indeed a directory if (!(dir->ni->mrec->flags && MFT_RECORD_IS_DIRECTORY)) { ntfsCloseEntry(dir->vd, dir->ni); ntfsUnlock(dir->vd); r->_errno = ENOTDIR; return NULL; } // Read the directory dir->first = dir->current = NULL; if (ntfs_readdir(dir->ni, &position, dirState, (ntfs_filldir_t)ntfs_readdir_filler)) { ntfsCloseDir(dir); ntfsUnlock(dir->vd); r->_errno = errno; return NULL; } // Move to the first entry in the directory dir->current = dir->first; // Update directory times ntfsUpdateTimes(dir->vd, dir->ni, NTFS_UPDATE_ATIME); // Insert the directory into the double-linked FILO list of open directories if (dir->vd->firstOpenDir) { dir->nextOpenDir = dir->vd->firstOpenDir; dir->vd->firstOpenDir->prevOpenDir = dir; } else { dir->nextOpenDir = NULL; } dir->prevOpenDir = NULL; dir->vd->cwd_ni = dir->ni; dir->vd->firstOpenDir = dir; dir->vd->openDirCount++; // Unlock ntfsUnlock(dir->vd); return dirState; }