66 dprintf(1,
"parsing NFS41_DIR_QUERY: info_class=%d buf_len=%d "
67 "filter='%s'\n\tInitial\\Restart\\Single %d\\%d\\%d buf=%p\n",
74#define FILTER_STAR '*'
133 eprintf(
"unhandled dir query class %d\n", query_class);
145 &
info->fdi.CreationTime);
147 &
info->fdi.LastAccessTime);
149 &
info->fdi.LastWriteTime);
152 &
info->fdi.ChangeTime);
153 info->fdi.EndOfFile.QuadPart =
154 info->fdi.AllocationSize.QuadPart =
155 entry->attr_info.size;
167 if (*name_size_out) {
173 *name_size_out *=
sizeof(
WCHAR);
198 &
info->fbdi.ShortNameLength);
207 *name_size_out = name_size;
226 path_out->len +=
name->len + 1;
286 IN OUT unsigned char **dst_pos,
291 uint32_t wname_len, wname_size, needed;
296 wname_size = (wname_len - 1) *
sizeof(
WCHAR);
299 if (!needed || needed > *dst_len) {
306 *dst_pos +=
info->NextEntryOffset;
307 *dst_len -=
info->NextEntryOffset;
324 switch (
args->query_class)
327 info->fni.FileIndex = 0;
329 info->fni.FileName, &
info->fni.FileNameLength);
334 info->fdi.FileName, &
info->fdi.FileNameLength);
339 info->ffdi.FileName, &
info->ffdi.FileNameLength);
345 info->fifdi.FileName, &
info->fifdi.FileNameLength);
350 info->fbdi.FileName, &
info->fbdi.FileNameLength);
356 info->fibdi.FileName, &
info->fibdi.FileNameLength);
359 eprintf(
"unhandled dir query class %d\n",
args->query_class);
367#define COOKIE_DOT ((uint64_t)-2)
368#define COOKIE_DOTDOT ((uint64_t)-1)
372 IN OUT unsigned char *entry_buf,
384 switch (
state->cookie.cookie) {
386 if (entry_buf_len < entry_len + 2) {
388 dprintf(1,
"not enough room for '.' entry. received %d need %d\n",
389 entry_buf_len, entry_len + 2);
390 args->query_reply_len = entry_len + 2;
400 dprintf(1,
"failed to add '.' entry.\n");
406 entry->next_entry_offset = entry_len +
entry->name_len;
408 entry_buf +=
entry->next_entry_offset;
409 entry_buf_len -=
entry->next_entry_offset;
410 *len_out +=
entry->next_entry_offset;
411 *last_offset = &
entry->next_entry_offset;
416 if (entry_buf_len < entry_len + 3) {
418 dprintf(1,
"not enough room for '..' entry. received %d need %d\n",
419 entry_buf_len, entry_len);
420 args->query_reply_len = entry_len + 2;
424 if (
state->file.name.len == 0)
434 dprintf(1,
"failed to add '..' entry.\n");
440 entry->next_entry_offset = entry_len +
entry->name_len;
442 entry_buf +=
entry->next_entry_offset;
443 entry_buf_len -=
entry->next_entry_offset;
444 *len_out +=
entry->next_entry_offset;
445 *last_offset = &
entry->next_entry_offset;
460 unsigned char *entry_buf =
NULL;
468 dprintf(1,
"-> handle_nfs41_dirquery(%s,%d,%d,%d)\n",
471 args->query_reply_len = 0;
473 if (
args->initial ||
args->restart) {
475 if (!
state->cookie.cookie)
476 dprintf(1,
"initializing the 1st readdir cookie\n");
477 else if (
args->restart)
478 dprintf(1,
"restarting; clearing previous cookie %llu\n",
479 state->cookie.cookie);
480 else if (
args->initial)
481 dprintf(1,
"*** initial; clearing previous cookie %llu!\n",
482 state->cookie.cookie);
483 }
else if (!
state->cookie.cookie) {
484 dprintf(1,
"handle_nfs41_readdir: EOF\n");
489 entry_buf =
calloc(max_buf_len,
sizeof(
unsigned char));
490 if (entry_buf ==
NULL) {
492 goto out_free_cookie;
495 entry_buf_len = max_buf_len;
506 if (
args->filter[0] ==
'*' &&
args->filter[1] ==
'\0') {
508 entry_buf_len, &dots_len, &dots_next_offset);
510 goto out_free_cookie;
511 entry_buf_len -= dots_len;
514 if (dots_len &&
args->single) {
515 dprintf(2,
"skipping nfs41_readdir because the single query "
516 "will use . or ..\n");
520 dprintf(2,
"calling nfs41_readdir with cookie %llu\n",
521 state->cookie.cookie);
523 &attr_request, &
state->cookie, entry_buf + dots_len,
524 &entry_buf_len, &
eof);
526 dprintf(1,
"nfs41_readdir failed with %s\n",
529 goto out_free_cookie;
533 if (!entry_buf_len && dots_next_offset)
534 *dots_next_offset = 0;
535 entry_buf_len += dots_len;
542 entry->next_entry_offset = 0;
548 goto out_free_cookie;
550 entry_buf_len =
entry->name_len +
559 unsigned char *entry_pos = entry_buf;
560 unsigned char *dst_pos =
args->kbuf;
569 dprintf(2,
"filter %s looking at %s with cookie %d\n",
574 dprintf(2,
"not enough space to copy entry %s (cookie %d)\n",
584 if (!
entry->next_entry_offset)
588 if (
args->single && last_offset) {
592 entry_pos +=
entry->next_entry_offset;
594 args->query_reply_len =
args->buf_len - dst_len;
598 dprintf(1,
"no entries matched; fetch more\n");
604 dprintf(1,
"we don't need to save a cookie\n");
605 goto out_free_cookie;
607 dprintf(1,
"saving cookie %llu\n",
state->cookie.cookie);
612 dprintf(1,
"<- handle_nfs41_dirquery(%s,%d,%d,%d) returning ",
617 dprintf(1,
"ERROR_FILE_NOT_FOUND.\n");
620 dprintf(1,
"ERROR_NO_MORE_FILES.\n");
635 state->cookie.cookie = 0;
ACPI_SIZE strlen(const char *String)
char * strchr(const char *String, int ch)
int nfs41_lookup(IN nfs41_root *root, IN nfs41_session *session, IN OUT nfs41_abs_path *path_inout, OUT OPTIONAL nfs41_path_fh *parent_out, OUT OPTIONAL nfs41_path_fh *target_out, OUT OPTIONAL nfs41_file_info *info_out, OUT nfs41_session **session_out)
ULONG nfs_file_info_to_attributes(IN const nfs41_file_info *info)
bool_t last_component(IN const char *path, IN const char *path_end, OUT nfs41_component *component)
int safe_write(unsigned char **pos, uint32_t *remaining, void *src, uint32_t src_len)
void abs_path_copy(OUT nfs41_abs_path *dst, IN const nfs41_abs_path *src)
int safe_read(unsigned char **pos, uint32_t *remaining, void *dest, uint32_t dest_len)
int nfs_to_windows_error(int status, int default_error)
int get_name(unsigned char **pos, uint32_t *remaining, const char **out_name)
__inline uint32_t align8(uint32_t offset)
static __inline void nfs_time_to_file_time(IN const nfstime4 *nfs_time, OUT PLARGE_INTEGER file_time)
void eprintf(LPCSTR format,...)
const char * nfs_error_string(int status)
#define MultiByteToWideChar
DWORD WINAPI GetShortPathNameW(IN LPCWSTR lpszLongPath, OUT LPWSTR lpszShortPath, IN DWORD cchBuffer)
VOID WINAPI InitializeSRWLock(PSRWLOCK Lock)
unsigned short(__cdecl typeof(TIFFCurrentDirectory))(struct tiff *)
@ FileDirectoryInformation
@ FileIdBothDirectoryInformation
@ FileFullDirectoryInformation
@ FileBothDirectoryInformation
@ FileIdFullDirectoryInformation
int nfs41_cached_getattr(IN nfs41_session *session, IN nfs41_path_fh *file, OUT nfs41_file_info *info)
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
GLuint GLsizei GLsizei * length
#define memcpy(s1, s2, n)
#define ERROR_FILE_NOT_FOUND
static __inline void nfs41_superblock_getattr_mask(IN const nfs41_superblock *superblock, OUT bitmap4 *attrs)
#define NFS41_MAX_PATH_LEN
@ FATTR4_WORD0_RDATTR_ERROR
#define NFS41_MAX_COMPONENT_LEN
#define NFS4_OPAQUE_LIMIT
nfs41_updowncall_list upcall
int nfs41_readdir(IN nfs41_session *session, IN nfs41_path_fh *file, IN bitmap4 *attr_request, IN nfs41_readdir_cookie *cookie, OUT unsigned char *entries, IN OUT uint32_t *entries_len, OUT bool_t *eof_out)
int nfs41_symlink_follow(IN nfs41_root *root, IN nfs41_session *session, IN nfs41_path_fh *symlink, OUT nfs41_file_info *info)
const nfs41_upcall_op nfs41_op_readdir
union _FILE_DIR_INFO_UNION * PFILE_DIR_INFO_UNION
static int readdir_filter(const char *filter, const char *name)
static void readdir_copy_full_dir_info(IN nfs41_readdir_entry *entry, IN PFILE_DIR_INFO_UNION info)
static void readdir_copy_filename(IN LPCWSTR name, IN uint32_t name_size, OUT LPWSTR name_out, OUT ULONG *name_size_out)
static int readdir_add_dots(IN readdir_upcall_args *args, IN OUT unsigned char *entry_buf, IN uint32_t entry_buf_len, OUT uint32_t *len_out, OUT uint32_t **last_offset)
static int lookup_symlink(IN nfs41_root *root, IN nfs41_session *session, IN nfs41_path_fh *parent, IN const nfs41_component *name, OUT nfs41_file_info *info_out)
static void readdir_copy_dir_info(IN nfs41_readdir_entry *entry, IN PFILE_DIR_INFO_UNION info)
static __inline const char * skip_stars(const char *filter)
static int format_abs_path(IN const nfs41_abs_path *path, IN const nfs41_component *name, OUT nfs41_abs_path *path_out)
static int readdir_copy_entry(IN readdir_upcall_args *args, IN nfs41_readdir_entry *entry, IN OUT unsigned char **dst_pos, IN OUT uint32_t *dst_len)
static int lookup_entry(IN nfs41_root *root, IN nfs41_session *session, IN nfs41_path_fh *parent, OUT nfs41_readdir_entry *entry)
static uint32_t readdir_size_for_entry(IN int query_class, IN uint32_t wname_size)
union _FILE_DIR_INFO_UNION FILE_DIR_INFO_UNION
static int parse_readdir(unsigned char *buffer, uint32_t length, nfs41_upcall *upcall)
static int marshall_readdir(unsigned char *buffer, uint32_t *length, nfs41_upcall *upcall)
static void readdir_copy_both_dir_info(IN nfs41_readdir_entry *entry, IN LPWSTR wname, IN PFILE_DIR_INFO_UNION info)
static void readdir_copy_shortname(IN LPCWSTR name, OUT LPWSTR name_out, OUT CCHAR *name_size_out)
static int handle_readdir(nfs41_upcall *upcall)
_Check_return_ _CRTIMP int __cdecl __cdecl eof(_In_ int _FileHandle)
STRSAFEAPI StringCchPrintfA(STRSAFE_LPSTR pszDest, size_t cchDest, STRSAFE_LPCSTR pszFormat,...)
STRSAFEAPI StringCbCopyA(STRSAFE_LPSTR pszDest, size_t cbDest, STRSAFE_LPCSTR pszSrc)
#define FIELD_OFFSET(t, f)
FILE_ID_BOTH_DIR_INFO fibdi
FILE_ID_FULL_DIR_INFO fifdi
FILE_BOTH_DIR_INFORMATION fbdi
FILE_NAMES_INFORMATION fni
DWORD WINAPI GetLastError(void)
#define ERROR_BUFFER_OVERFLOW
#define ERROR_BAD_NET_RESP
#define ERROR_NO_MORE_FILES
#define ERROR_FILENAME_EXCED_RANGE
#define IO_REPARSE_TAG_SYMLINK