Пример #1
0
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;
}
Пример #2
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;
}
Пример #3
0
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;
}