struct vfs_node_p *vfs_open(char *path, char *flags) { mountpoint_t *mp = vfs_get_mountpoint(path); if(mp == NULL) return (struct vfs_node_p *) NULL; path += _strlen(mp->path); /* split the restant path, and get nodes */ char token[VFS_TOKEN_SIZE]; unsigned tok_len; struct vfs_node_p *tmp = mp->root; struct readdir_t rd; unsigned i; while(tmp != NULL) { /* get the token */ tok_len = 0; while((*path != '/') && (*path != 0)) { token[tok_len] = *path; path++; tok_len++; } token[tok_len] = 0; /* read the dir and find the correct token */ struct vfs_node_p *tmp2 = NULL; i = 0; while((tmp2 == NULL) && (tmp->readdir(tmp, &rd, i))) { if(_strcmp(tmp->name, token) == 0) { /* get the correct node */ tmp2 = tmp->get_node(tmp, i); if(tmp != mp->root) { mm_free(tmp); } tmp = tmp2; if(*(path-1) == 0) return tmp; } i++; } } return (struct vfs_node_p *) NULL; }
int vfs_unlink(const char *path, struct uio *uio) { int ret = 0; struct vfs_path *p = NULL; char **tokens = NULL; /* if path is NULL pointer, or path is empty string, return NULL */ if (!path || !*path) return -ENOENT; char *_path = NULL; if ((ret = vfs_parse_path(path, uio, &_path))) goto error; /* Canonicalize Path */ tokens = canonicalize_path(_path); /* Get mountpoint & path */ p = vfs_get_mountpoint(tokens); struct vnode cur, next; cur.super = p->mountpoint; cur.ino = p->mountpoint->ino; cur.mode = S_IFDIR; next.super = p->mountpoint; char *name = NULL; char **tok = p->tokens; while (tok) { char *token = *tok; if (!*(tok + 1)) { name = token; break; } if ((ret = vfs_vfind(&cur, token, &next))) goto error; memcpy(&cur, &next, sizeof(cur)); ++tok; } if ((ret = vfs_vunlink(&cur, name, uio))) goto error; free_tokens(tokens); kfree(p); kfree(_path); return 0; error: if (tokens) free_tokens(tokens); if (p) kfree(p); if (_path) kfree(_path); return ret; }
static int winfs_getpath(struct file *f, char *buf) { AcquireSRWLockShared(&f->rw_lock); struct winfs_file *winfile = (struct winfs_file *)f; char data[PATH_MAX + 128]; FILE_NAME_INFORMATION *info = (FILE_NAME_INFORMATION *)data; IO_STATUS_BLOCK status_block; NTSTATUS status; status = NtQueryInformationFile(winfile->handle, &status_block, info, sizeof(data), FileNameInformation); info->FileName[info->FileNameLength / 2] = 0; if (!NT_SUCCESS(status)) { log_error("NtQueryInformationFile(FileNameInformation) failed, status: %x", status); __debugbreak(); } struct mount_point mp; if (!vfs_get_mountpoint(winfile->mp_key, &mp)) vfs_get_root_mountpoint(&mp); int len = 0; WCHAR *relpath; /* Test if the file is in the mount point */ /* \??\C:\Windows, \Windows */ if (mp.win_path[4] == winfile->drive_letter && !wcsncmp(mp.win_path + 6, info->FileName, mp.win_path_len - 6)) { relpath = info->FileName + mp.win_path_len - 6; /* Copy mount point */ memcpy(buf, mp.mountpoint, mp.mountpoint_len); len = mp.mountpoint_len; buf += mp.mountpoint_len; /* Remove trailling slash */ if (buf[-1] == '/') { buf--; len--; } } else { /* Not inside the point, use dos drive mount points as the last resort */ relpath = info->FileName; buf[0] = '/'; buf[1] = winfile->drive_letter - 'A' + 'a'; buf += 2; len = 2; } int r = utf16_to_utf8_filename(relpath, wcslen(relpath), buf, PATH_MAX); /* TODO: length */ if (r < 0) { log_error("utf16_to_utf8_filename() failed."); __debugbreak(); } len += r; buf[r] = 0; ReleaseSRWLockShared(&f->rw_lock); if (len == 0) { buf[len++] = '/'; buf[len] = 0; } return len; }