ReactOS 0.4.15-dev-8092-ge0ba2f3
readdir.c File Reference
#include <windows.h>
#include <strsafe.h>
#include <stdlib.h>
#include "from_kernel.h"
#include "nfs41_ops.h"
#include "daemon_debug.h"
#include "upcall.h"
#include "util.h"
Include dependency graph for readdir.c:

Go to the source code of this file.

Classes

union  _FILE_DIR_INFO_UNION
 

Macros

#define FILTER_STAR   '*'
 
#define FILTER_QM   '>'
 
#define COOKIE_DOT   ((uint64_t)-2)
 
#define COOKIE_DOTDOT   ((uint64_t)-1)
 

Typedefs

typedef union _FILE_DIR_INFO_UNION FILE_DIR_INFO_UNION
 
typedef union _FILE_DIR_INFO_UNIONPFILE_DIR_INFO_UNION
 

Functions

static int parse_readdir (unsigned char *buffer, uint32_t length, nfs41_upcall *upcall)
 
static __inline const charskip_stars (const char *filter)
 
static int readdir_filter (const char *filter, const char *name)
 
static uint32_t readdir_size_for_entry (IN int query_class, IN uint32_t wname_size)
 
static void readdir_copy_dir_info (IN nfs41_readdir_entry *entry, IN PFILE_DIR_INFO_UNION info)
 
static void readdir_copy_shortname (IN LPCWSTR name, OUT LPWSTR name_out, OUT CCHAR *name_size_out)
 
static void readdir_copy_full_dir_info (IN nfs41_readdir_entry *entry, IN PFILE_DIR_INFO_UNION info)
 
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_filename (IN LPCWSTR name, IN uint32_t name_size, OUT LPWSTR name_out, OUT ULONG *name_size_out)
 
static int format_abs_path (IN const nfs41_abs_path *path, IN const nfs41_component *name, OUT nfs41_abs_path *path_out)
 
static int lookup_entry (IN nfs41_root *root, IN nfs41_session *session, IN nfs41_path_fh *parent, OUT nfs41_readdir_entry *entry)
 
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 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 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 handle_readdir (nfs41_upcall *upcall)
 
static int marshall_readdir (unsigned char *buffer, uint32_t *length, nfs41_upcall *upcall)
 

Variables

const nfs41_upcall_op nfs41_op_readdir
 

Macro Definition Documentation

◆ COOKIE_DOT

#define COOKIE_DOT   ((uint64_t)-2)

Definition at line 367 of file readdir.c.

◆ COOKIE_DOTDOT

#define COOKIE_DOTDOT   ((uint64_t)-1)

Definition at line 368 of file readdir.c.

◆ FILTER_QM

#define FILTER_QM   '>'

Definition at line 75 of file readdir.c.

◆ FILTER_STAR

#define FILTER_STAR   '*'

Definition at line 74 of file readdir.c.

Typedef Documentation

◆ FILE_DIR_INFO_UNION

◆ PFILE_DIR_INFO_UNION

Function Documentation

◆ format_abs_path()

static int format_abs_path ( IN const nfs41_abs_path path,
IN const nfs41_component name,
OUT nfs41_abs_path path_out 
)
static

Definition at line 211 of file readdir.c.

215{
216 /* format an absolute path 'parent\name' */
217 int status = NO_ERROR;
218
219 InitializeSRWLock(&path_out->lock);
220 abs_path_copy(path_out, path);
221 if (FAILED(StringCchPrintfA(path_out->path + path_out->len,
222 NFS41_MAX_PATH_LEN - path_out->len, "\\%s", name->name))) {
224 goto out;
225 }
226 path_out->len += name->len + 1;
227out:
228 return status;
229}
void abs_path_copy(OUT nfs41_abs_path *dst, IN const nfs41_abs_path *src)
Definition: util.c:338
#define NO_ERROR
Definition: dderror.h:5
VOID WINAPI InitializeSRWLock(PSRWLOCK Lock)
Definition: sync.c:75
#define FAILED(hr)
Definition: intsafe.h:51
#define NFS41_MAX_PATH_LEN
Definition: nfs41_const.h:46
static FILE * out
Definition: regtests2xml.c:44
STRSAFEAPI StringCchPrintfA(STRSAFE_LPSTR pszDest, size_t cchDest, STRSAFE_LPCSTR pszFormat,...)
Definition: strsafe.h:520
Definition: name.c:39
WCHAR * name
Definition: name.c:42
Definition: ps.c:97
#define ERROR_FILENAME_EXCED_RANGE
Definition: winerror.h:263

Referenced by lookup_entry(), and lookup_symlink().

◆ handle_readdir()

static int handle_readdir ( nfs41_upcall upcall)
static

Definition at line 455 of file readdir.c.

456{
457 int status;
458 readdir_upcall_args *args = &upcall->args.readdir;
459 nfs41_open_state *state = upcall->state_ref;
460 unsigned char *entry_buf = NULL;
461 uint32_t entry_buf_len;
462 bitmap4 attr_request;
463 bool_t eof;
464 /* make sure we allocate enough space for one nfs41_readdir_entry */
465 const uint32_t max_buf_len = max(args->buf_len,
467
468 dprintf(1, "-> handle_nfs41_dirquery(%s,%d,%d,%d)\n",
469 args->filter, args->initial, args->restart, args->single);
470
471 args->query_reply_len = 0;
472
473 if (args->initial || args->restart) {
474 ZeroMemory(&state->cookie, sizeof(nfs41_readdir_cookie));
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");
486 goto out;
487 }
488
489 entry_buf = calloc(max_buf_len, sizeof(unsigned char));
490 if (entry_buf == NULL) {
492 goto out_free_cookie;
493 }
494fetch_entries:
495 entry_buf_len = max_buf_len;
496
497 nfs41_superblock_getattr_mask(state->file.fh.superblock, &attr_request);
498 attr_request.arr[0] |= FATTR4_WORD0_RDATTR_ERROR;
499
500 if (strchr(args->filter, FILTER_STAR) || strchr(args->filter, FILTER_QM)) {
501 /* use READDIR for wildcards */
502
503 uint32_t dots_len = 0;
504 uint32_t *dots_next_offset = NULL;
505
506 if (args->filter[0] == '*' && args->filter[1] == '\0') {
507 status = readdir_add_dots(args, entry_buf,
508 entry_buf_len, &dots_len, &dots_next_offset);
509 if (status)
510 goto out_free_cookie;
511 entry_buf_len -= dots_len;
512 }
513
514 if (dots_len && args->single) {
515 dprintf(2, "skipping nfs41_readdir because the single query "
516 "will use . or ..\n");
517 entry_buf_len = 0;
518 eof = 0;
519 } else {
520 dprintf(2, "calling nfs41_readdir with cookie %llu\n",
521 state->cookie.cookie);
522 status = nfs41_readdir(state->session, &state->file,
523 &attr_request, &state->cookie, entry_buf + dots_len,
524 &entry_buf_len, &eof);
525 if (status) {
526 dprintf(1, "nfs41_readdir failed with %s\n",
529 goto out_free_cookie;
530 }
531 }
532
533 if (!entry_buf_len && dots_next_offset)
534 *dots_next_offset = 0;
535 entry_buf_len += dots_len;
536 } else {
537 /* use LOOKUP for single files */
539 entry->cookie = 0;
540 entry->name_len = (uint32_t)strlen(args->filter) + 1;
541 StringCbCopyA(entry->name, entry->name_len, args->filter);
542 entry->next_entry_offset = 0;
543
544 status = lookup_entry(upcall->root_ref,
545 state->session, &state->file, entry);
546 if (status) {
547 dprintf(1, "single_lookup failed with %d\n", status);
548 goto out_free_cookie;
549 }
550 entry_buf_len = entry->name_len +
552
553 eof = 1;
554 }
555
557
558 if (entry_buf_len) {
559 unsigned char *entry_pos = entry_buf;
560 unsigned char *dst_pos = args->kbuf;
561 uint32_t dst_len = args->buf_len;
563 PULONG offset, last_offset = NULL;
564
565 for (;;) {
566 entry = (nfs41_readdir_entry*)entry_pos;
567 offset = (PULONG)dst_pos; /* ULONG NextEntryOffset */
568
569 dprintf(2, "filter %s looking at %s with cookie %d\n",
570 args->filter, entry->name, entry->cookie);
571 if (readdir_filter((const char*)args->filter, entry->name)) {
572 if (readdir_copy_entry(args, entry, &dst_pos, &dst_len)) {
573 eof = 0;
574 dprintf(2, "not enough space to copy entry %s (cookie %d)\n",
575 entry->name, entry->cookie);
576 break;
577 }
578 last_offset = offset;
580 }
581 state->cookie.cookie = entry->cookie;
582
583 /* last entry we got from the server */
584 if (!entry->next_entry_offset)
585 break;
586
587 /* we found our single entry, but the server has more */
588 if (args->single && last_offset) {
589 eof = 0;
590 break;
591 }
592 entry_pos += entry->next_entry_offset;
593 }
594 args->query_reply_len = args->buf_len - dst_len;
595 if (last_offset) {
596 *last_offset = 0;
597 } else if (!eof) {
598 dprintf(1, "no entries matched; fetch more\n");
599 goto fetch_entries;
600 }
601 }
602
603 if (eof) {
604 dprintf(1, "we don't need to save a cookie\n");
605 goto out_free_cookie;
606 } else
607 dprintf(1, "saving cookie %llu\n", state->cookie.cookie);
608
609out_free_entry:
610 free(entry_buf);
611out:
612 dprintf(1, "<- handle_nfs41_dirquery(%s,%d,%d,%d) returning ",
613 args->filter, args->initial, args->restart, args->single);
614 if (status) {
615 switch (status) {
617 dprintf(1, "ERROR_FILE_NOT_FOUND.\n");
618 break;
620 dprintf(1, "ERROR_NO_MORE_FILES.\n");
621 break;
623 upcall->last_error = status;
625 break;
626 default:
627 dprintf(1, "error code %d.\n", status);
628 break;
629 }
630 } else {
631 dprintf(1, "success!\n");
632 }
633 return status;
634out_free_cookie:
635 state->cookie.cookie = 0;
636 goto out_free_entry;
637}
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
char * strchr(const char *String, int ch)
Definition: utclib.c:501
static int state
Definition: maze.c:121
int nfs_to_windows_error(int status, int default_error)
Definition: util.c:235
const char * nfs_error_string(int status)
Definition: daemon_debug.c:370
#define free
Definition: debug_ros.c:5
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
int32_t bool_t
Definition: types.h:101
UINT32 uint32_t
Definition: types.h:75
GLintptr offset
Definition: glext.h:5920
uint32_t entry
Definition: isohybrid.c:63
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
static __inline void nfs41_superblock_getattr_mask(IN const nfs41_superblock *superblock, OUT bitmap4 *attrs)
Definition: nfs41.h:448
#define NFS41_MAX_COMPONENT_LEN
Definition: nfs41_const.h:45
@ FATTR4_WORD0_RDATTR_ERROR
Definition: nfs41_const.h:218
nfs41_updowncall_list upcall
Definition: nfs41_driver.c:273
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)
Definition: nfs41_ops.c:1010
#define uint32_t
Definition: nsiface.idl:61
static int readdir_filter(const char *filter, const char *name)
Definition: readdir.c:85
#define FILTER_QM
Definition: readdir.c:75
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)
Definition: readdir.c:370
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)
Definition: readdir.c:283
static int lookup_entry(IN nfs41_root *root, IN nfs41_session *session, IN nfs41_path_fh *parent, OUT nfs41_readdir_entry *entry)
Definition: readdir.c:231
#define FILTER_STAR
Definition: readdir.c:74
#define dprintf
Definition: regdump.c:33
#define calloc
Definition: rosglue.h:14
_Check_return_ _CRTIMP int __cdecl __cdecl eof(_In_ int _FileHandle)
STRSAFEAPI StringCbCopyA(STRSAFE_LPSTR pszDest, size_t cbDest, STRSAFE_LPCSTR pszSrc)
Definition: strsafe.h:161
uint32_t arr[3]
Definition: nfs41_types.h:97
Definition: nfs41_ops.h:710
Definition: match.c:390
#define max(a, b)
Definition: svc.c:63
uint32_t * PULONG
Definition: typedefs.h:59
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define ZeroMemory
Definition: winbase.h:1712
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define ERROR_BUFFER_OVERFLOW
Definition: winerror.h:185
#define ERROR_BAD_NET_RESP
Definition: winerror.h:150
#define ERROR_NO_MORE_FILES
Definition: winerror.h:121

◆ lookup_entry()

static int lookup_entry ( IN nfs41_root root,
IN nfs41_session session,
IN nfs41_path_fh parent,
OUT nfs41_readdir_entry entry 
)
static

Definition at line 231 of file readdir.c.

236{
239 int status;
240
241 name.name = entry->name;
242 name.len = (unsigned short)entry->name_len - 1;
243
245 if (status) goto out;
246
248 NULL, NULL, &entry->attr_info, NULL);
249 if (status) goto out;
250out:
251 return status;
252}
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)
Definition: lookup.c:424
unsigned short(__cdecl typeof(TIFFCurrentDirectory))(struct tiff *)
Definition: typeof.h:94
r parent
Definition: btrfs.c:3010
static int format_abs_path(IN const nfs41_abs_path *path, IN const nfs41_component *name, OUT nfs41_abs_path *path_out)
Definition: readdir.c:211

Referenced by handle_readdir(), and readdir_copy_entry().

◆ lookup_symlink()

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

Definition at line 254 of file readdir.c.

260{
264 int status;
265
267 if (status) goto out;
268
269 file.path = &path;
271 if (status) goto out;
272
273 last_component(path.path, path.path + path.len, &file.name);
274
276 if (status) goto out;
277
278 info_out->symlink_dir = info.type == NF4DIR;
279out:
280 return status;
281}
bool_t last_component(IN const char *path, IN const char *path_end, OUT nfs41_component *component)
Definition: util.c:317
@ NF4DIR
Definition: nfs41_const.h:295
int nfs41_symlink_follow(IN nfs41_root *root, IN nfs41_session *session, IN nfs41_path_fh *symlink, OUT nfs41_file_info *info)
Definition: symlink.c:146
Definition: fci.c:127
WCHAR * path
Definition: filesystem.c:122
char name[1]
Definition: fci.c:135

Referenced by readdir_copy_entry().

◆ marshall_readdir()

static int marshall_readdir ( unsigned char buffer,
uint32_t length,
nfs41_upcall upcall 
)
static

Definition at line 639 of file readdir.c.

640{
641 int status;
642 readdir_upcall_args *args = &upcall->args.readdir;
643
644 status = safe_write(&buffer, length, &args->query_reply_len, sizeof(args->query_reply_len));
645 return status;
646}
int safe_write(unsigned char **pos, uint32_t *remaining, void *src, uint32_t src_len)
Definition: util.c:44
GLuint buffer
Definition: glext.h:5915
GLuint GLsizei GLsizei * length
Definition: glext.h:6040

◆ parse_readdir()

static int parse_readdir ( unsigned char buffer,
uint32_t  length,
nfs41_upcall upcall 
)
static

Definition at line 44 of file readdir.c.

45{
46 int status;
47 readdir_upcall_args *args = &upcall->args.readdir;
48
49 status = safe_read(&buffer, &length, &args->query_class, sizeof(args->query_class));
50 if (status) goto out;
51 status = safe_read(&buffer, &length, &args->buf_len, sizeof(args->buf_len));
52 if (status) goto out;
53 status = get_name(&buffer, &length, &args->filter);
54 if (status) goto out;
55 status = safe_read(&buffer, &length, &args->initial, sizeof(args->initial));
56 if (status) goto out;
57 status = safe_read(&buffer, &length, &args->restart, sizeof(args->restart));
58 if (status) goto out;
59 status = safe_read(&buffer, &length, &args->single, sizeof(args->single));
60 if (status) goto out;
61 status = safe_read(&buffer, &length, &args->kbuf, sizeof(args->kbuf));
62 if (status) goto out;
63 args->root = upcall->root_ref;
64 args->state = upcall->state_ref;
65
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",
68 args->query_class, args->buf_len, args->filter,
69 args->initial, args->restart, args->single, args->kbuf);
70out:
71 return status;
72}
int safe_read(unsigned char **pos, uint32_t *remaining, void *dest, uint32_t dest_len)
Definition: util.c:33
int get_name(unsigned char **pos, uint32_t *remaining, const char **out_name)
Definition: util.c:55

◆ readdir_add_dots()

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

Definition at line 370 of file readdir.c.

376{
377 int status = 0;
380 nfs41_open_state *state = args->state;
381
382 *len_out = 0;
383 *last_offset = NULL;
384 switch (state->cookie.cookie) {
385 case 0:
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;
391 goto out;
392 }
393
394 entry = (nfs41_readdir_entry*)entry_buf;
395 ZeroMemory(&entry->attr_info, sizeof(nfs41_file_info));
396
398 &state->file, &entry->attr_info);
399 if (status) {
400 dprintf(1, "failed to add '.' entry.\n");
401 goto out;
402 }
403 entry->cookie = COOKIE_DOT;
404 entry->name_len = 2;
405 StringCbCopyA(entry->name, entry->name_len, ".");
406 entry->next_entry_offset = entry_len + entry->name_len;
407
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;
412 if (args->single)
413 break;
414 /* else no break! */
415 case COOKIE_DOT:
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;
421 goto out;
422 }
423 /* XXX: this skips '..' when listing root fh */
424 if (state->file.name.len == 0)
425 break;
426
427 entry = (nfs41_readdir_entry*)entry_buf;
428 ZeroMemory(&entry->attr_info, sizeof(nfs41_file_info));
429
431 &state->parent, &entry->attr_info);
432 if (status) {
434 dprintf(1, "failed to add '..' entry.\n");
435 goto out;
436 }
437 entry->cookie = COOKIE_DOTDOT;
438 entry->name_len = 3;
439 StringCbCopyA(entry->name, entry->name_len, "..");
440 entry->next_entry_offset = entry_len + entry->name_len;
441
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;
446 break;
447 }
448 if (state->cookie.cookie == COOKIE_DOTDOT ||
449 state->cookie.cookie == COOKIE_DOT)
450 ZeroMemory(&state->cookie, sizeof(nfs41_readdir_cookie));
451out:
452 return status;
453}
int nfs41_cached_getattr(IN nfs41_session *session, IN nfs41_path_fh *file, OUT nfs41_file_info *info)
Definition: getattr.c:32
#define COOKIE_DOTDOT
Definition: readdir.c:368
#define COOKIE_DOT
Definition: readdir.c:367

Referenced by handle_readdir().

◆ readdir_copy_both_dir_info()

static void readdir_copy_both_dir_info ( IN nfs41_readdir_entry entry,
IN LPWSTR  wname,
IN PFILE_DIR_INFO_UNION  info 
)
static

Definition at line 191 of file readdir.c.

195{
197 readdir_copy_shortname(wname, info->fbdi.ShortName,
198 &info->fbdi.ShortNameLength);
199}
static void readdir_copy_full_dir_info(IN nfs41_readdir_entry *entry, IN PFILE_DIR_INFO_UNION info)
Definition: readdir.c:177
static void readdir_copy_shortname(IN LPCWSTR name, OUT LPWSTR name_out, OUT CCHAR *name_size_out)
Definition: readdir.c:160

Referenced by readdir_copy_entry().

◆ readdir_copy_dir_info()

static void readdir_copy_dir_info ( IN nfs41_readdir_entry entry,
IN PFILE_DIR_INFO_UNION  info 
)
static

Definition at line 139 of file readdir.c.

142{
143 info->fdi.FileIndex = (ULONG)entry->attr_info.fileid;
144 nfs_time_to_file_time(&entry->attr_info.time_create,
145 &info->fdi.CreationTime);
146 nfs_time_to_file_time(&entry->attr_info.time_access,
147 &info->fdi.LastAccessTime);
148 nfs_time_to_file_time(&entry->attr_info.time_modify,
149 &info->fdi.LastWriteTime);
150 /* XXX: was using 'change' attr, but that wasn't giving a time */
151 nfs_time_to_file_time(&entry->attr_info.time_modify,
152 &info->fdi.ChangeTime);
153 info->fdi.EndOfFile.QuadPart =
154 info->fdi.AllocationSize.QuadPart =
155 entry->attr_info.size;
156 info->fdi.FileAttributes = nfs_file_info_to_attributes(
157 &entry->attr_info);
158}
ULONG nfs_file_info_to_attributes(IN const nfs41_file_info *info)
Definition: util.c:137
static __inline void nfs_time_to_file_time(IN const nfstime4 *nfs_time, OUT PLARGE_INTEGER file_time)
Definition: util.h:125
uint32_t ULONG
Definition: typedefs.h:59

Referenced by readdir_copy_entry(), and readdir_copy_full_dir_info().

◆ readdir_copy_entry()

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

Definition at line 283 of file readdir.c.

288{
289 int status = 0;
291 uint32_t wname_len, wname_size, needed;
293
294 wname_len = MultiByteToWideChar(CP_UTF8, 0,
295 entry->name, entry->name_len, wname, NFS4_OPAQUE_LIMIT);
296 wname_size = (wname_len - 1) * sizeof(WCHAR);
297
298 needed = readdir_size_for_entry(args->query_class, wname_size);
299 if (!needed || needed > *dst_len) {
300 status = -1;
301 goto out;
302 }
303
304 info = (PFILE_DIR_INFO_UNION)*dst_pos;
305 info->NextEntryOffset = align8(needed);
306 *dst_pos += info->NextEntryOffset;
307 *dst_len -= info->NextEntryOffset;
308
309 if (entry->attr_info.rdattr_error == NFS4ERR_MOVED) {
310 entry->attr_info.type = NF4DIR; /* default to dir */
311 /* look up attributes for referral entries, but ignore return value;
312 * it's okay if lookup fails, we'll just write garbage attributes */
313 lookup_entry(args->root, args->state->session,
314 &args->state->file, entry);
315 } else if (entry->attr_info.type == NF4LNK) {
317 name.name = entry->name;
318 name.len = (unsigned short)entry->name_len - 1;
319 /* look up the symlink target to see whether it's a directory */
320 lookup_symlink(args->root, args->state->session,
321 &args->state->file, &name, &entry->attr_info);
322 }
323
324 switch (args->query_class)
325 {
327 info->fni.FileIndex = 0;
328 readdir_copy_filename(wname, wname_size,
329 info->fni.FileName, &info->fni.FileNameLength);
330 break;
333 readdir_copy_filename(wname, wname_size,
334 info->fdi.FileName, &info->fdi.FileNameLength);
335 break;
338 readdir_copy_filename(wname, wname_size,
339 info->ffdi.FileName, &info->ffdi.FileNameLength);
340 break;
343 info->fibdi.FileId.QuadPart = (LONGLONG)entry->attr_info.fileid;
344 readdir_copy_filename(wname, wname_size,
345 info->fifdi.FileName, &info->fifdi.FileNameLength);
346 break;
349 readdir_copy_filename(wname, wname_size,
350 info->fbdi.FileName, &info->fbdi.FileNameLength);
351 break;
354 info->fibdi.FileId.QuadPart = (LONGLONG)entry->attr_info.fileid;
355 readdir_copy_filename(wname, wname_size,
356 info->fibdi.FileName, &info->fibdi.FileNameLength);
357 break;
358 default:
359 eprintf("unhandled dir query class %d\n", args->query_class);
360 status = -1;
361 break;
362 }
363out:
364 return status;
365}
__inline uint32_t align8(uint32_t offset)
Definition: util.h:191
void eprintf(LPCSTR format,...)
Definition: daemon_debug.c:86
#define MultiByteToWideChar
Definition: compat.h:110
@ FileDirectoryInformation
Definition: from_kernel.h:62
@ FileIdBothDirectoryInformation
Definition: from_kernel.h:98
@ FileNamesInformation
Definition: from_kernel.h:73
@ FileFullDirectoryInformation
Definition: from_kernel.h:63
@ FileBothDirectoryInformation
Definition: from_kernel.h:64
@ FileIdFullDirectoryInformation
Definition: from_kernel.h:99
@ NF4LNK
Definition: nfs41_const.h:298
@ NFS4ERR_MOVED
Definition: nfs41_const.h:126
#define NFS4_OPAQUE_LIMIT
Definition: nfs41_const.h:31
union _FILE_DIR_INFO_UNION * PFILE_DIR_INFO_UNION
static void readdir_copy_filename(IN LPCWSTR name, IN uint32_t name_size, OUT LPWSTR name_out, OUT ULONG *name_size_out)
Definition: readdir.c:201
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)
Definition: readdir.c:254
static void readdir_copy_dir_info(IN nfs41_readdir_entry *entry, IN PFILE_DIR_INFO_UNION info)
Definition: readdir.c:139
static uint32_t readdir_size_for_entry(IN int query_class, IN uint32_t wname_size)
Definition: readdir.c:107
static void readdir_copy_both_dir_info(IN nfs41_readdir_entry *entry, IN LPWSTR wname, IN PFILE_DIR_INFO_UNION info)
Definition: readdir.c:191
#define CP_UTF8
Definition: nls.h:20
int64_t LONGLONG
Definition: typedefs.h:68
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by handle_readdir().

◆ readdir_copy_filename()

static void readdir_copy_filename ( IN LPCWSTR  name,
IN uint32_t  name_size,
OUT LPWSTR  name_out,
OUT ULONG name_size_out 
)
static

Definition at line 201 of file readdir.c.

206{
207 *name_size_out = name_size;
208 memcpy(name_out, name, name_size);
209}
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878

Referenced by readdir_copy_entry().

◆ readdir_copy_full_dir_info()

static void readdir_copy_full_dir_info ( IN nfs41_readdir_entry entry,
IN PFILE_DIR_INFO_UNION  info 
)
static

Definition at line 177 of file readdir.c.

180{
182 /* for files with the FILE_ATTRIBUTE_REPARSE_POINT attribute,
183 * EaSize is used instead to specify its reparse tag. this makes
184 * the 'dir' command to show files as <SYMLINK>, and triggers a
185 * FSCTL_GET_REPARSE_POINT to query the symlink target
186 */
187 info->fifdi.EaSize = entry->attr_info.type == NF4LNK ?
189}
#define IO_REPARSE_TAG_SYMLINK
Definition: iotypes.h:7240

Referenced by readdir_copy_both_dir_info(), and readdir_copy_entry().

◆ readdir_copy_shortname()

static void readdir_copy_shortname ( IN LPCWSTR  name,
OUT LPWSTR  name_out,
OUT CCHAR name_size_out 
)
static

Definition at line 160 of file readdir.c.

164{
165 /* GetShortPathName returns number of characters, not including \0 */
166 *name_size_out = (CCHAR)GetShortPathNameW(name, name_out, 12);
167 if (*name_size_out) {
168#ifndef __REACTOS__
169 *name_size_out++;
170#else
171 (*name_size_out)++;
172#endif
173 *name_size_out *= sizeof(WCHAR);
174 }
175}
DWORD WINAPI GetShortPathNameW(IN LPCWSTR lpszLongPath, OUT LPWSTR lpszShortPath, IN DWORD cchBuffer)
Definition: path.c:1833
char CCHAR
Definition: typedefs.h:51

Referenced by readdir_copy_both_dir_info().

◆ readdir_filter()

static int readdir_filter ( const char filter,
const char name 
)
static

Definition at line 85 of file readdir.c.

88{
89 const char *f = filter, *n = name;
90
91 while (*f && *n) {
92 if (*f == FILTER_STAR) {
93 f = skip_stars(f);
94 if (*f == '\0')
95 return 1;
96 while (*n && !readdir_filter(f, n))
97 n++;
98 } else if (*f == FILTER_QM || *f == *n) {
99 f++;
100 n++;
101 } else
102 return 0;
103 }
104 return *f == *n || *skip_stars(f) == '\0';
105}
GLdouble n
Definition: glext.h:7729
GLfloat f
Definition: glext.h:7540
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition: glext.h:7005
static __inline const char * skip_stars(const char *filter)
Definition: readdir.c:77

Referenced by handle_readdir(), and readdir_filter().

◆ readdir_size_for_entry()

static uint32_t readdir_size_for_entry ( IN int  query_class,
IN uint32_t  wname_size 
)
static

Definition at line 107 of file readdir.c.

110{
111 uint32_t needed = wname_size;
112 switch (query_class)
113 {
116 break;
119 break;
122 break;
124 needed += FIELD_OFFSET(FILE_ID_BOTH_DIR_INFO, FileName);
125 break;
128 break;
131 break;
132 default:
133 eprintf("unhandled dir query class %d\n", query_class);
134 return 0;
135 }
136 return needed;
137}

Referenced by readdir_copy_entry().

◆ skip_stars()

static __inline const char * skip_stars ( const char filter)
static

Definition at line 77 of file readdir.c.

79{
80 while (*filter == FILTER_STAR)
81 filter++;
82 return filter;
83}

Referenced by readdir_filter().

Variable Documentation

◆ nfs41_op_readdir

const nfs41_upcall_op nfs41_op_readdir
Initial value:
= {
}
static int parse_readdir(unsigned char *buffer, uint32_t length, nfs41_upcall *upcall)
Definition: readdir.c:44
static int marshall_readdir(unsigned char *buffer, uint32_t *length, nfs41_upcall *upcall)
Definition: readdir.c:639
static int handle_readdir(nfs41_upcall *upcall)
Definition: readdir.c:455

Definition at line 649 of file readdir.c.