ReactOS  0.4.15-dev-506-ga3ec01c
readdir.c
Go to the documentation of this file.
1 /* NFSv4.1 client for Windows
2  * Copyright © 2012 The Regents of the University of Michigan
3  *
4  * Olga Kornievskaia <aglo@umich.edu>
5  * Casey Bodley <cbodley@umich.edu>
6  *
7  * This library is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU Lesser General Public License as published by
9  * the Free Software Foundation; either version 2.1 of the License, or (at
10  * your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful, but
13  * without any warranty; without even the implied warranty of merchantability
14  * or fitness for a particular purpose. See the GNU Lesser General Public
15  * License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public License
18  * along with this library; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20  */
21 
22 #include <windows.h>
23 #include <strsafe.h>
24 #include <stdlib.h>
25 #include "from_kernel.h"
26 #include "nfs41_ops.h"
27 #include "daemon_debug.h"
28 #include "upcall.h"
29 #include "util.h"
30 
31 
32 typedef union _FILE_DIR_INFO_UNION {
39  FILE_ID_BOTH_DIR_INFO fibdi;
41 
42 
43 /* NFS41_DIR_QUERY */
44 static int parse_readdir(unsigned char *buffer, uint32_t length, nfs41_upcall *upcall)
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);
70 out:
71  return status;
72 }
73 
74 #define FILTER_STAR '*'
75 #define FILTER_QM '>'
76 
77 static __inline const char* skip_stars(
78  const char *filter)
79 {
80  while (*filter == FILTER_STAR)
81  filter++;
82  return filter;
83 }
84 
85 static int readdir_filter(
86  const char *filter,
87  const char *name)
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 }
106 
108  IN int query_class,
109  IN uint32_t wname_size)
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 }
138 
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 }
159 
161  IN LPCWSTR name,
162  OUT LPWSTR name_out,
163  OUT CCHAR *name_size_out)
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 }
176 
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 }
190 
193  IN LPWSTR wname,
195 {
197  readdir_copy_shortname(wname, info->fbdi.ShortName,
198  &info->fbdi.ShortNameLength);
199 }
200 
202  IN LPCWSTR name,
203  IN uint32_t name_size,
204  OUT LPWSTR name_out,
205  OUT ULONG *name_size_out)
206 {
207  *name_size_out = name_size;
208  memcpy(name_out, name, name_size);
209 }
210 
211 static int format_abs_path(
212  IN const nfs41_abs_path *path,
213  IN const nfs41_component *name,
214  OUT nfs41_abs_path *path_out)
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;
227 out:
228  return status;
229 }
230 
231 static int lookup_entry(
232  IN nfs41_root *root,
236 {
239  int status;
240 
241  name.name = entry->name;
242  name.len = (unsigned short)entry->name_len - 1;
243 
244  status = format_abs_path(parent->path, &name, &path);
245  if (status) goto out;
246 
248  NULL, NULL, &entry->attr_info, NULL);
249  if (status) goto out;
250 out:
251  return status;
252 }
253 
254 static int lookup_symlink(
255  IN nfs41_root *root,
258  IN const nfs41_component *name,
259  OUT nfs41_file_info *info_out)
260 {
264  int status;
265 
266  status = format_abs_path(parent->path, name, &path);
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;
279 out:
280  return status;
281 }
282 
286  IN OUT unsigned char **dst_pos,
287  IN OUT uint32_t *dst_len)
288 {
289  int status = 0;
290  WCHAR wname[NFS4_OPAQUE_LIMIT];
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  }
363 out:
364  return status;
365 }
366 
367 #define COOKIE_DOT ((uint64_t)-2)
368 #define COOKIE_DOTDOT ((uint64_t)-1)
369 
370 static int readdir_add_dots(
372  IN OUT unsigned char *entry_buf,
373  IN uint32_t entry_buf_len,
374  OUT uint32_t *len_out,
375  OUT uint32_t **last_offset)
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 
397  status = nfs41_cached_getattr(state->session,
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 
430  status = nfs41_cached_getattr(state->session,
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));
451 out:
452  return status;
453 }
454 
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) {
491  status = GetLastError();
492  goto out_free_cookie;
493  }
494 fetch_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;
579  status = NO_ERROR;
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 
609 out_free_entry:
610  free(entry_buf);
611 out:
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;
619  case ERROR_NO_MORE_FILES:
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;
634 out_free_cookie:
635  state->cookie.cookie = 0;
636  goto out_free_entry;
637 }
638 
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 }
647 
648 
653 };
int nfs41_cached_getattr(IN nfs41_session *session, IN nfs41_path_fh *file, OUT nfs41_file_info *info)
Definition: getattr.c:32
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
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
#define IN
Definition: typedefs.h:39
int nfs_to_windows_error(int status, int default_error)
Definition: util.c:235
#define max(a, b)
Definition: svc.c:63
static uint32_t readdir_size_for_entry(IN int query_class, IN uint32_t wname_size)
Definition: readdir.c:107
#define ERROR_SUCCESS
Definition: deptool.c:10
Definition: nfs41_ops.h:710
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
#define NFS41_MAX_COMPONENT_LEN
Definition: nfs41_const.h:45
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
int32_t bool_t
Definition: types.h:101
#define ERROR_BUFFER_OVERFLOW
Definition: winerror.h:185
GLsizei const GLchar ** path
Definition: glext.h:7234
static int handle_readdir(nfs41_upcall *upcall)
Definition: readdir.c:455
#define free
Definition: debug_ros.c:5
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
GLintptr offset
Definition: glext.h:5920
GLdouble n
Definition: glext.h:7729
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
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
#define ZeroMemory
Definition: winbase.h:1648
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
void eprintf(LPCSTR format,...)
Definition: daemon_debug.c:86
GLuint buffer
Definition: glext.h:5915
union _FILE_DIR_INFO_UNION FILE_DIR_INFO_UNION
#define NO_ERROR
Definition: dderror.h:5
uint32_t arr[3]
Definition: nfs41_types.h:97
Definition: match.c:390
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
bool_t last_component(IN const char *path, IN const char *path_end, OUT nfs41_component *component)
Definition: util.c:317
struct _test_info info[]
Definition: SetCursorPos.c:19
static void readdir_copy_shortname(IN LPCWSTR name, OUT LPWSTR name_out, OUT CCHAR *name_size_out)
Definition: readdir.c:160
static __inline const char * skip_stars(const char *filter)
Definition: readdir.c:77
#define NFS41_MAX_PATH_LEN
Definition: nfs41_const.h:46
void abs_path_copy(OUT nfs41_abs_path *dst, IN const nfs41_abs_path *src)
Definition: util.c:338
#define ERROR_BAD_NET_RESP
Definition: winerror.h:150
unsigned short(__cdecl typeof(TIFFCurrentDirectory))(struct tiff *)
Definition: typeof.h:94
#define FILTER_QM
Definition: readdir.c:75
FILE_BOTH_DIR_INFORMATION fbdi
Definition: readdir.c:38
char name[1]
Definition: fci.c:135
FILE_DIRECTORY_INFO fdi
Definition: readdir.c:35
#define CP_UTF8
Definition: nls.h:20
#define dprintf
Definition: regdump.c:33
STRSAFEAPI StringCchPrintfA(STRSAFE_LPSTR pszDest, size_t cchDest, STRSAFE_LPCSTR pszFormat,...)
Definition: strsafe.h:520
int get_name(unsigned char **pos, uint32_t *remaining, const char **out_name)
Definition: util.c:55
#define NFS4_OPAQUE_LIMIT
Definition: nfs41_const.h:31
FILE_NAMES_INFORMATION fni
Definition: readdir.c:34
smooth NULL
Definition: ftsmooth.c:416
STRSAFEAPI StringCbCopyA(STRSAFE_LPSTR pszDest, size_t cbDest, STRSAFE_LPCSTR pszSrc)
Definition: strsafe.h:161
__inline uint32_t align8(uint32_t offset)
Definition: util.h:191
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
#define ERROR_NO_MORE_FILES
Definition: winerror.h:121
#define COOKIE_DOT
Definition: readdir.c:367
int64_t LONGLONG
Definition: typedefs.h:67
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
GLfloat f
Definition: glext.h:7540
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
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
r parent
Definition: btrfs.c:2944
__wchar_t WCHAR
Definition: xmlstorage.h:180
char CCHAR
Definition: typedefs.h:51
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
DWORD WINAPI GetShortPathNameW(IN LPCWSTR lpszLongPath, OUT LPWSTR lpszShortPath, IN DWORD cchBuffer)
Definition: path.c:1832
const char file[]
Definition: icontest.c:11
static FILE * out
Definition: regtests2xml.c:44
union _FILE_DIR_INFO_UNION * PFILE_DIR_INFO_UNION
int safe_write(unsigned char **pos, uint32_t *remaining, void *src, uint32_t src_len)
Definition: util.c:44
const char * nfs_error_string(int status)
Definition: daemon_debug.c:370
FILE_FULL_DIR_INFO ffdi
Definition: readdir.c:36
static int marshall_readdir(unsigned char *buffer, uint32_t *length, nfs41_upcall *upcall)
Definition: readdir.c:639
static int state
Definition: maze.c:121
uint32_t entry
Definition: isohybrid.c:63
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
static __inline void nfs_time_to_file_time(IN const nfstime4 *nfs_time, OUT PLARGE_INTEGER file_time)
Definition: util.h:125
static void readdir_copy_dir_info(IN nfs41_readdir_entry *entry, IN PFILE_DIR_INFO_UNION info)
Definition: readdir.c:139
VOID WINAPI InitializeSRWLock(PSRWLOCK Lock)
Definition: sync.c:75
ULONG nfs_file_info_to_attributes(IN const nfs41_file_info *info)
Definition: util.c:137
static int parse_readdir(unsigned char *buffer, uint32_t length, nfs41_upcall *upcall)
Definition: readdir.c:44
_Check_return_ _CRTIMP int __cdecl __cdecl eof(_In_ int _FileHandle)
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
ULONG NextEntryOffset
Definition: readdir.c:33
unsigned int * PULONG
Definition: retypes.h:1
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 __inline void nfs41_superblock_getattr_mask(IN const nfs41_superblock *superblock, OUT bitmap4 *attrs)
Definition: nfs41.h:448
UINT32 uint32_t
Definition: types.h:75
#define MultiByteToWideChar
Definition: compat.h:100
char * strchr(const char *String, int ch)
Definition: utclib.c:501
const nfs41_upcall_op nfs41_op_readdir
Definition: readdir.c:649
WCHAR * path
Definition: filesystem.c:122
static int readdir_filter(const char *filter, const char *name)
Definition: readdir.c:85
nfs41_updowncall_list upcall
Definition: nfs41_driver.c:273
Definition: name.c:38
#define calloc
Definition: rosglue.h:14
#define OUT
Definition: typedefs.h:40
static void readdir_copy_full_dir_info(IN nfs41_readdir_entry *entry, IN PFILE_DIR_INFO_UNION info)
Definition: readdir.c:177
#define COOKIE_DOTDOT
Definition: readdir.c:368
unsigned int ULONG
Definition: retypes.h:1
int safe_read(unsigned char **pos, uint32_t *remaining, void *dest, uint32_t dest_len)
Definition: util.c:33
FILE_ID_FULL_DIR_INFO fifdi
Definition: readdir.c:37
FILE_ID_BOTH_DIR_INFO fibdi
Definition: readdir.c:39
WCHAR * LPWSTR
Definition: xmlstorage.h:184
#define uint32_t
Definition: nsiface.idl:61
static SERVICE_STATUS status
Definition: service.c:31
#define IO_REPARSE_TAG_SYMLINK
Definition: iotypes.h:6886
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition: glext.h:7005
#define FILTER_STAR
Definition: readdir.c:74
WCHAR * name
Definition: name.c:42
#define ERROR_FILENAME_EXCED_RANGE
Definition: winerror.h:263
Definition: fci.c:126
Definition: ps.c:97
GLuint const GLchar * name
Definition: glext.h:6031