ReactOS  0.4.14-dev-52-g6116262
disk.c
Go to the documentation of this file.
1 /* -*- c-basic-offset: 8 -*-
2  rdesktop: A Remote Desktop Protocol client.
3  Disk Redirection
4  Copyright (C) Jeroen Meijer 2003
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License along
17  with this program; if not, write to the Free Software Foundation, Inc.,
18  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20 
21 #include "disk.h"
22 
23 #include <sys/types.h>
24 #include <sys/stat.h>
25 #include <unistd.h>
26 #include <fcntl.h> /* open, close */
27 #include <dirent.h> /* opendir, closedir, readdir */
28 #include <fnmatch.h>
29 #include <errno.h> /* errno */
30 #include <stdio.h>
31 
32 #include <utime.h>
33 #include <time.h> /* ctime */
34 
35 #if (defined(HAVE_DIRFD) || (HAVE_DECL_DIRFD == 1))
36 #define DIRFD(a) (dirfd(a))
37 #else
38 #define DIRFD(a) ((a)->DIR_FD_MEMBER_NAME)
39 #endif
40 
41 /* TODO: Fix mntent-handling for solaris
42  * #include <sys/mntent.h> */
43 #if (defined(HAVE_MNTENT_H) && defined(HAVE_SETMNTENT))
44 #include <mntent.h>
45 #define MNTENT_PATH "/etc/mtab"
46 #define USE_SETMNTENT
47 #endif
48 
49 #ifdef HAVE_SYS_VFS_H
50 #include <sys/vfs.h>
51 #endif
52 
53 #ifdef HAVE_SYS_STATVFS_H
54 #include <sys/statvfs.h>
55 #endif
56 
57 #ifdef HAVE_SYS_STATFS_H
58 #include <sys/statfs.h>
59 #endif
60 
61 #ifdef HAVE_SYS_PARAM_H
62 #include <sys/param.h>
63 #endif
64 
65 #ifdef HAVE_SYS_MOUNT_H
66 #include <sys/mount.h>
67 #endif
68 
69 #include "rdesktop.h"
70 
71 #ifdef STAT_STATFS3_OSF1
72 #define STATFS_FN(path, buf) (statfs(path,buf,sizeof(buf)))
73 #define STATFS_T statfs
74 #define USE_STATFS
75 #endif
76 
77 #ifdef STAT_STATVFS
78 #define STATFS_FN(path, buf) (statvfs(path,buf))
79 #define STATFS_T statvfs
80 #define USE_STATVFS
81 #endif
82 
83 #ifdef STAT_STATVFS64
84 #define STATFS_FN(path, buf) (statvfs64(path,buf))
85 #define STATFS_T statvfs64
86 #define USE_STATVFS
87 #endif
88 
89 #if (defined(STAT_STATFS2_FS_DATA) || defined(STAT_STATFS2_BSIZE) || defined(STAT_STATFS2_FSIZE))
90 #define STATFS_FN(path, buf) (statfs(path,buf))
91 #define STATFS_T statfs
92 #define USE_STATFS
93 #endif
94 
95 #ifdef STAT_STATFS4
96 #define STATFS_FN(path, buf) (statfs(path,buf,sizeof(buf),0))
97 #define STATFS_T statfs
98 #define USE_STATFS
99 #endif
100 
101 #if ((defined(USE_STATFS) && defined(HAVE_STRUCT_STATFS_F_NAMEMAX)) || (defined(USE_STATVFS) && defined(HAVE_STRUCT_STATVFS_F_NAMEMAX)))
102 #define F_NAMELEN(buf) ((buf).f_namemax)
103 #endif
104 
105 #if ((defined(USE_STATFS) && defined(HAVE_STRUCT_STATFS_F_NAMELEN)) || (defined(USE_STATVFS) && defined(HAVE_STRUCT_STATVFS_F_NAMELEN)))
106 #define F_NAMELEN(buf) ((buf).f_namelen)
107 #endif
108 
109 #ifndef F_NAMELEN
110 #define F_NAMELEN(buf) (255)
111 #endif
112 
113 /* Dummy statfs fallback */
114 #ifndef STATFS_T
116 {
117  long f_bfree;
118  long f_bsize;
119  long f_blocks;
122 };
123 
124 static int
126 {
127  buf->f_blocks = 262144;
128  buf->f_bfree = 131072;
129  buf->f_bsize = 512;
130  buf->f_namelen = 255;
131  buf->f_namemax = 255;
132 
133  return 0;
134 }
135 
136 #define STATFS_T dummy_statfs_t
137 #define STATFS_FN(path,buf) (dummy_statfs(buf))
138 #endif
139 
140 typedef struct
141 {
142  char name[PATH_MAX];
144  unsigned long serial;
145  char type[PATH_MAX];
146 } FsInfoType;
147 
149 
150 static time_t
152 {
153  time_t ret, ret1;
154 
155  ret = MIN(st->st_ctime, st->st_mtime);
156  ret1 = MIN(ret, st->st_atime);
157 
158  if (ret1 != (time_t) 0)
159  return ret1;
160 
161  return ret;
162 }
163 
164 /* Convert seconds since 1970 to a filetime */
165 static void
167 {
168  unsigned long long ticks;
169 
170  ticks = (seconds + 11644473600LL) * 10000000;
171  *low = (uint32) ticks;
172  *high = (uint32) (ticks >> 32);
173 }
174 
175 /* Convert seconds since 1970 back to filetime */
176 static time_t
178 {
179  unsigned long long ticks;
180  time_t val;
181 
182  ticks = low + (((unsigned long long) high) << 32);
183  ticks /= 10000000;
184  ticks -= 11644473600LL;
185 
186  val = (time_t) ticks;
187  return (val);
188 
189 }
190 
191 /* A wrapper for ftruncate which supports growing files, even if the
192  native ftruncate doesn't. This is needed on Linux FAT filesystems,
193  for example. */
194 static int
196 {
197  int ret;
198  off_t pos;
199  static const char zero = 0;
200 
201  /* Try the simple method first */
202  if ((ret = ftruncate(fd, length)) != -1)
203  {
204  return ret;
205  }
206 
207  /*
208  * Some kind of error. Perhaps we were trying to grow. Retry
209  * in a safe way.
210  */
211 
212  /* Get current position */
213  if ((pos = lseek(fd, 0, SEEK_CUR)) == -1)
214  {
215  perror("lseek");
216  return -1;
217  }
218 
219  /* Seek to new size */
220  if (lseek(fd, length, SEEK_SET) == -1)
221  {
222  perror("lseek");
223  return -1;
224  }
225 
226  /* Write a zero */
227  if (write(fd, &zero, 1) == -1)
228  {
229  perror("write");
230  return -1;
231  }
232 
233  /* Truncate. This shouldn't fail. */
234  if (ftruncate(fd, length) == -1)
235  {
236  perror("ftruncate");
237  return -1;
238  }
239 
240  /* Restore position */
241  if (lseek(fd, pos, SEEK_SET) == -1)
242  {
243  perror("lseek");
244  return -1;
245  }
246 
247  return 0;
248 }
249 
250 /* Just like open(2), but if a open with O_EXCL fails, retry with
251  GUARDED semantics. This might be necessary because some filesystems
252  (such as NFS filesystems mounted from a unfsd server) doesn't
253  support O_EXCL. GUARDED semantics are subject to race conditions,
254  but we can live with that.
255 */
256 static int
258 {
259  int ret;
260  struct stat statbuf;
261 
262  ret = open(pathname, flags, mode);
263  if (ret != -1 || !(flags & O_EXCL))
264  {
265  /* Success, or not using O_EXCL */
266  return ret;
267  }
268 
269  /* An error occured, and we are using O_EXCL. In case the FS
270  doesn't support O_EXCL, some kind of error will be
271  returned. Unfortunately, we don't know which one. Linux
272  2.6.8 seems to return 524, but I cannot find a documented
273  #define for this case. So, we'll return only on errors that
274  we know aren't related to O_EXCL. */
275  switch (errno)
276  {
277  case EACCES:
278  case EEXIST:
279  case EINTR:
280  case EISDIR:
281  case ELOOP:
282  case ENAMETOOLONG:
283  case ENOENT:
284  case ENOTDIR:
285  return ret;
286  }
287 
288  /* Retry with GUARDED semantics */
289  if (stat(pathname, &statbuf) != -1)
290  {
291  /* File exists */
292  errno = EEXIST;
293  return -1;
294  }
295  else
296  {
297  return open(pathname, flags & ~O_EXCL, mode);
298  }
299 }
300 
301 /* Enumeration of devices from rdesktop.c */
302 /* returns numer of units found and initialized. */
303 /* optarg looks like ':h=/mnt/floppy,b=/mnt/usbdevice1' */
304 /* when it arrives to this function. */
305 int
307 {
308  char *pos = optarg;
309  char *pos2;
310  int count = 0;
311 
312  /* skip the first colon */
313  optarg++;
314  while ((pos = next_arg(optarg, ',')) && *id < RDPDR_MAX_DEVICES)
315  {
316  pos2 = next_arg(optarg, '=');
317 
318  strncpy(This->rdpdr_device[*id].name, optarg, sizeof(This->rdpdr_device[*id].name) - 1);
319  if (strlen(optarg) > (sizeof(This->rdpdr_device[*id].name) - 1))
320  fprintf(stderr, "share name %s truncated to %s\n", optarg,
321  This->rdpdr_device[*id].name);
322 
323  This->rdpdr_device[*id].local_path = (char *) xmalloc(strlen(pos2) + 1);
324  strcpy(This->rdpdr_device[*id].local_path, pos2);
325  This->rdpdr_device[*id].device_type = DEVICE_TYPE_DISK;
326  count++;
327  (*id)++;
328 
329  optarg = pos;
330  }
331  return count;
332 }
333 
334 /* Opens or creates a file or directory */
335 static NTSTATUS
336 disk_create(RDPCLIENT * This, uint32 device_id, uint32 accessmask, uint32 sharemode, uint32 create_disposition,
337  uint32 flags_and_attributes, char *filename, NTHANDLE * phandle)
338 {
339  NTHANDLE handle;
340  DIR *dirp;
341  int flags, mode;
342  char path[PATH_MAX];
343  struct stat filestat;
344 
345  handle = 0;
346  dirp = NULL;
347  flags = 0;
349 
350  if (*filename && filename[strlen(filename) - 1] == '/')
351  filename[strlen(filename) - 1] = 0;
352  sprintf(path, "%s%s", This->rdpdr_device[device_id].local_path, filename);
353 
354  switch (create_disposition)
355  {
356  case CREATE_ALWAYS:
357 
358  /* Delete existing file/link. */
359  unlink(path);
360  flags |= O_CREAT;
361  break;
362 
363  case CREATE_NEW:
364 
365  /* If the file already exists, then fail. */
366  flags |= O_CREAT | O_EXCL;
367  break;
368 
369  case OPEN_ALWAYS:
370 
371  /* Create if not already exists. */
372  flags |= O_CREAT;
373  break;
374 
375  case OPEN_EXISTING:
376 
377  /* Default behaviour */
378  break;
379 
380  case TRUNCATE_EXISTING:
381 
382  /* If the file does not exist, then fail. */
383  flags |= O_TRUNC;
384  break;
385  }
386 
387  /*printf("Open: \"%s\" flags: %X, accessmask: %X sharemode: %X create disp: %X\n", path, flags_and_attributes, accessmask, sharemode, create_disposition); */
388 
389  /* Get information about file and set that flag ourselfs */
390  if ((stat(path, &filestat) == 0) && (S_ISDIR(filestat.st_mode)))
391  {
392  if (flags_and_attributes & FILE_NON_DIRECTORY_FILE)
394  else
395  flags_and_attributes |= FILE_DIRECTORY_FILE;
396  }
397 
398  if (flags_and_attributes & FILE_DIRECTORY_FILE)
399  {
400  if (flags & O_CREAT)
401  {
402  mkdir(path, mode);
403  }
404 
405  dirp = opendir(path);
406  if (!dirp)
407  {
408  switch (errno)
409  {
410  case EACCES:
411 
412  return STATUS_ACCESS_DENIED;
413 
414  case ENOENT:
415 
416  return STATUS_NO_SUCH_FILE;
417 
418  default:
419 
420  perror("opendir");
421  return STATUS_NO_SUCH_FILE;
422  }
423  }
424  handle = DIRFD(dirp);
425  }
426  else
427  {
428 
429  if (accessmask & GENERIC_ALL
430  || (accessmask & GENERIC_READ && accessmask & GENERIC_WRITE))
431  {
432  flags |= O_RDWR;
433  }
434  else if ((accessmask & GENERIC_WRITE) && !(accessmask & GENERIC_READ))
435  {
436  flags |= O_WRONLY;
437  }
438  else
439  {
440  flags |= O_RDONLY;
441  }
442 
444  if (handle == -1)
445  {
446  switch (errno)
447  {
448  case EISDIR:
449 
451 
452  case EACCES:
453 
454  return STATUS_ACCESS_DENIED;
455 
456  case ENOENT:
457 
458  return STATUS_NO_SUCH_FILE;
459  case EEXIST:
460 
462  default:
463 
464  perror("open");
465  return STATUS_NO_SUCH_FILE;
466  }
467  }
468 
469  /* all read and writes of files should be non blocking */
470  if (fcntl(handle, F_SETFL, O_NONBLOCK) == -1)
471  perror("fcntl");
472  }
473 
474  if (handle >= MAX_OPEN_FILES)
475  {
476  error("Maximum number of open files (%s) reached. Increase MAX_OPEN_FILES!\n",
477  handle);
478  exit(1);
479  }
480 
481  if (dirp)
482  This->fileinfo[handle].pdir = dirp;
483  else
484  This->fileinfo[handle].pdir = NULL;
485 
486  This->fileinfo[handle].device_id = device_id;
487  This->fileinfo[handle].flags_and_attributes = flags_and_attributes;
488  This->fileinfo[handle].accessmask = accessmask;
489  strncpy(This->fileinfo[handle].path, path, PATH_MAX - 1);
490  This->fileinfo[handle].delete_on_close = False;
491  This->notify_stamp = True;
492 
493  *phandle = handle;
494  return STATUS_SUCCESS;
495 }
496 
497 static NTSTATUS
499 {
500  struct fileinfo *pfinfo;
501 
502  pfinfo = &(This->fileinfo[handle]);
503 
504  This->notify_stamp = True;
505 
507 
508  if (pfinfo->pdir)
509  {
510  if (closedir(pfinfo->pdir) < 0)
511  {
512  perror("closedir");
513  return STATUS_INVALID_HANDLE;
514  }
515 
516  if (pfinfo->delete_on_close)
517  if (rmdir(pfinfo->path) < 0)
518  {
519  perror(pfinfo->path);
520  return STATUS_ACCESS_DENIED;
521  }
522  pfinfo->delete_on_close = False;
523  }
524  else
525  {
526  if (close(handle) < 0)
527  {
528  perror("close");
529  return STATUS_INVALID_HANDLE;
530  }
531  if (pfinfo->delete_on_close)
532  if (unlink(pfinfo->path) < 0)
533  {
534  perror(pfinfo->path);
535  return STATUS_ACCESS_DENIED;
536  }
537 
538  pfinfo->delete_on_close = False;
539  }
540 
541  return STATUS_SUCCESS;
542 }
543 
544 static NTSTATUS
546 {
547  int n;
548 
549 #if 0
550  /* browsing dir ???? */
551  /* each request is 24 bytes */
552  if (This->fileinfo[handle].flags_and_attributes & FILE_DIRECTORY_FILE)
553  {
554  *result = 0;
555  return STATUS_SUCCESS;
556  }
557 #endif
558 
560 
561  n = read(handle, data, length);
562 
563  if (n < 0)
564  {
565  *result = 0;
566  switch (errno)
567  {
568  case EISDIR:
569  /* Implement 24 Byte directory read ??
570  with STATUS_NOT_IMPLEMENTED server doesn't read again */
571  /* return STATUS_FILE_IS_A_DIRECTORY; */
572  return STATUS_NOT_IMPLEMENTED;
573  default:
574  perror("read");
576  }
577  }
578 
579  *result = n;
580 
581  return STATUS_SUCCESS;
582 }
583 
584 static NTSTATUS
586 {
587  int n;
588 
590 
591  n = write(handle, data, length);
592 
593  if (n < 0)
594  {
595  perror("write");
596  *result = 0;
597  switch (errno)
598  {
599  case ENOSPC:
600  return STATUS_DISK_FULL;
601  default:
602  return STATUS_ACCESS_DENIED;
603  }
604  }
605 
606  *result = n;
607 
608  return STATUS_SUCCESS;
609 }
610 
611 NTSTATUS
613 {
614  uint32 file_attributes, ft_high, ft_low;
615  struct stat filestat;
616  char *path, *filename;
617 
618  path = This->fileinfo[handle].path;
619 
620  /* Get information about file */
621  if (fstat(handle, &filestat) != 0)
622  {
623  perror("stat");
624  out_uint8(out, 0);
625  return STATUS_ACCESS_DENIED;
626  }
627 
628  /* Set file attributes */
629  file_attributes = 0;
630  if (S_ISDIR(filestat.st_mode))
631  file_attributes |= FILE_ATTRIBUTE_DIRECTORY;
632 
633  filename = 1 + strrchr(path, '/');
634  if (filename && filename[0] == '.')
635  file_attributes |= FILE_ATTRIBUTE_HIDDEN;
636 
637  if (!file_attributes)
638  file_attributes |= FILE_ATTRIBUTE_NORMAL;
639 
640  if (!(filestat.st_mode & S_IWUSR))
641  file_attributes |= FILE_ATTRIBUTE_READONLY;
642 
643  /* Return requested data */
644  switch (info_class)
645  {
647  seconds_since_1970_to_filetime(get_create_time(&filestat), &ft_high,
648  &ft_low);
649  out_uint32_le(out, ft_low); /* create_access_time */
650  out_uint32_le(out, ft_high);
651 
652  seconds_since_1970_to_filetime(filestat.st_atime, &ft_high, &ft_low);
653  out_uint32_le(out, ft_low); /* last_access_time */
654  out_uint32_le(out, ft_high);
655 
656  seconds_since_1970_to_filetime(filestat.st_mtime, &ft_high, &ft_low);
657  out_uint32_le(out, ft_low); /* last_write_time */
658  out_uint32_le(out, ft_high);
659 
660  seconds_since_1970_to_filetime(filestat.st_ctime, &ft_high, &ft_low);
661  out_uint32_le(out, ft_low); /* last_change_time */
662  out_uint32_le(out, ft_high);
663 
664  out_uint32_le(out, file_attributes);
665  break;
666 
668 
669  out_uint32_le(out, filestat.st_size); /* Allocation size */
670  out_uint32_le(out, 0);
671  out_uint32_le(out, filestat.st_size); /* End of file */
672  out_uint32_le(out, 0);
673  out_uint32_le(out, filestat.st_nlink); /* Number of links */
674  out_uint8(out, 0); /* Delete pending */
675  out_uint8(out, S_ISDIR(filestat.st_mode) ? 1 : 0); /* Directory */
676  break;
677 
679 
680  out_uint32_le(out, file_attributes); /* File Attributes */
681  out_uint32_le(out, 0); /* Reparse Tag */
682  break;
683 
684  default:
685 
686  unimpl("IRP Query (File) Information class: 0x%x\n", info_class);
688  }
689  return STATUS_SUCCESS;
690 }
691 
692 NTSTATUS
694 {
695  uint32 length, file_attributes, ft_high, ft_low, delete_on_close;
696  char newname[PATH_MAX], fullpath[PATH_MAX];
697  struct fileinfo *pfinfo;
698  int mode;
699  struct stat filestat;
700  time_t write_time, change_time, access_time, mod_time;
701  struct utimbuf tvs;
702  struct STATFS_T stat_fs;
703 
704  pfinfo = &(This->fileinfo[handle]);
705  This->notify_stamp = True;
706 
707  switch (info_class)
708  {
710  write_time = change_time = access_time = 0;
711 
712  in_uint8s(in, 4); /* Handle of root dir? */
713  in_uint8s(in, 24); /* unknown */
714 
715  /* CreationTime */
716  in_uint32_le(in, ft_low);
717  in_uint32_le(in, ft_high);
718 
719  /* AccessTime */
720  in_uint32_le(in, ft_low);
721  in_uint32_le(in, ft_high);
722  if (ft_low || ft_high)
723  access_time = convert_1970_to_filetime(ft_high, ft_low);
724 
725  /* WriteTime */
726  in_uint32_le(in, ft_low);
727  in_uint32_le(in, ft_high);
728  if (ft_low || ft_high)
729  write_time = convert_1970_to_filetime(ft_high, ft_low);
730 
731  /* ChangeTime */
732  in_uint32_le(in, ft_low);
733  in_uint32_le(in, ft_high);
734  if (ft_low || ft_high)
735  change_time = convert_1970_to_filetime(ft_high, ft_low);
736 
737  in_uint32_le(in, file_attributes);
738 
739  if (fstat(handle, &filestat))
740  return STATUS_ACCESS_DENIED;
741 
742  tvs.modtime = filestat.st_mtime;
743  tvs.actime = filestat.st_atime;
744  if (access_time)
745  tvs.actime = access_time;
746 
747 
748  if (write_time || change_time)
749  mod_time = MIN(write_time, change_time);
750  else
751  mod_time = write_time ? write_time : change_time;
752 
753  if (mod_time)
754  tvs.modtime = mod_time;
755 
756 
757  if (access_time || write_time || change_time)
758  {
759 #if WITH_DEBUG_RDP5
760  printf("FileBasicInformation access time %s",
761  ctime(&tvs.actime));
762  printf("FileBasicInformation modification time %s",
763  ctime(&tvs.modtime));
764 #endif
765  if (utime(pfinfo->path, &tvs) && errno != EPERM)
766  return STATUS_ACCESS_DENIED;
767  }
768 
769  if (!file_attributes)
770  break; /* not valid */
771 
772  mode = filestat.st_mode;
773 
774  if (file_attributes & FILE_ATTRIBUTE_READONLY)
775  mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH);
776  else
777  mode |= S_IWUSR;
778 
779  mode &= 0777;
780 #if WITH_DEBUG_RDP5
781  printf("FileBasicInformation set access mode 0%o", mode);
782 #endif
783 
784  if (fchmod(handle, mode))
785  return STATUS_ACCESS_DENIED;
786 
787  break;
788 
790 
791  in_uint8s(in, 4); /* Handle of root dir? */
792  in_uint8s(in, 0x1a); /* unknown */
794 
795  if (length && (length / 2) < 256)
796  {
797  rdp_in_unistr(This, in, newname, length);
798  convert_to_unix_filename(newname);
799  }
800  else
801  {
803  }
804 
805  sprintf(fullpath, "%s%s", This->rdpdr_device[pfinfo->device_id].local_path,
806  newname);
807 
808  if (rename(pfinfo->path, fullpath) != 0)
809  {
810  perror("rename");
811  return STATUS_ACCESS_DENIED;
812  }
813  break;
814 
816  /* As far as I understand it, the correct
817  thing to do here is to *schedule* a delete,
818  so it will be deleted when the file is
819  closed. Subsequent
820  FileDispositionInformation requests with
821  DeleteFile set to FALSE should unschedule
822  the delete. See
823  http://www.osronline.com/article.cfm?article=245. */
824 
825  in_uint32_le(in, delete_on_close);
826 
827  if (delete_on_close ||
828  (pfinfo->
830  {
831  pfinfo->delete_on_close = True;
832  }
833 
834  break;
835 
837  /* Fall through to FileEndOfFileInformation,
838  which uses ftrunc. This is like Samba with
839  "strict allocation = false", and means that
840  we won't detect out-of-quota errors, for
841  example. */
842 
844  in_uint8s(in, 28); /* unknown */
845  in_uint32_le(in, length); /* file size */
846 
847  /* prevents start of writing if not enough space left on device */
848  if (STATFS_FN(This->rdpdr_device[pfinfo->device_id].local_path, &stat_fs) == 0)
849  if (stat_fs.f_bfree * stat_fs.f_bsize < length)
850  return STATUS_DISK_FULL;
851 
852  if (ftruncate_growable(handle, length) != 0)
853  {
854  return STATUS_DISK_FULL;
855  }
856 
857  break;
858  default:
859 
860  unimpl("IRP Set File Information class: 0x%x\n", info_class);
862  }
863  return STATUS_SUCCESS;
864 }
865 
866 NTSTATUS
868 {
869  struct fileinfo *pfinfo;
871 
872  NOTIFY notify;
873 
874  pfinfo = &(This->fileinfo[handle]);
875  if (!pfinfo->pdir)
877 
878 
879 
880  status = NotifyInfo(This, handle, pfinfo->info_class, &notify);
881 
882  if (status != STATUS_PENDING)
883  return status;
884 
885  if (memcmp(&pfinfo->notify, &notify, sizeof(NOTIFY)))
886  {
887  /*printf("disk_check_notify found changed event\n"); */
888  memcpy(&pfinfo->notify, &notify, sizeof(NOTIFY));
890  }
891 
892  return status;
893 
894 
895 }
896 
897 NTSTATUS
899 {
900 
901  struct fileinfo *pfinfo;
903 
904  /* printf("start disk_create_notify info_class %X\n", info_class); */
905 
906  pfinfo = &(This->fileinfo[handle]);
907  pfinfo->info_class = info_class;
908 
909  ret = NotifyInfo(This, handle, info_class, &pfinfo->notify);
910 
911  if (info_class & 0x1000)
912  { /* ???? */
913  if (ret == STATUS_PENDING)
914  return STATUS_SUCCESS;
915  }
916 
917  /* printf("disk_create_notify: num_entries %d\n", pfinfo->notify.num_entries); */
918 
919 
920  return ret;
921 
922 }
923 
924 static NTSTATUS
926 {
927  struct fileinfo *pfinfo;
928  struct stat buf;
929  struct dirent *dp;
930  char *fullname;
931  DIR *dpr;
932 
933  pfinfo = &(This->fileinfo[handle]);
934  if (fstat(handle, &buf) < 0)
935  {
936  perror("NotifyInfo");
937  return STATUS_ACCESS_DENIED;
938  }
939  p->modify_time = buf.st_mtime;
940  p->status_time = buf.st_ctime;
941  p->num_entries = 0;
942  p->total_time = 0;
943 
944 
945  dpr = opendir(pfinfo->path);
946  if (!dpr)
947  {
948  perror("NotifyInfo");
949  return STATUS_ACCESS_DENIED;
950  }
951 
952 
953  while ((dp = readdir(dpr)))
954  {
955  if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, ".."))
956  continue;
957  p->num_entries++;
958  fullname = (char *) xmalloc(strlen(pfinfo->path) + strlen(dp->d_name) + 2);
959  sprintf(fullname, "%s/%s", pfinfo->path, dp->d_name);
960 
961  if (!stat(fullname, &buf))
962  {
963  p->total_time += (buf.st_mtime + buf.st_ctime);
964  }
965 
966  xfree(fullname);
967  }
968  closedir(dpr);
969 
970  return STATUS_PENDING;
971 }
972 
973 static FsInfoType *
974 FsVolumeInfo(char *fpath)
975 {
976 
977  static FsInfoType info;
978 #ifdef USE_SETMNTENT
979  FILE *fdfs;
980  struct mntent *e;
981 #endif
982 
983  /* initialize */
984  memset(&info, 0, sizeof(info));
985  strcpy(info.label, "RDESKTOP");
986  strcpy(info.type, "RDPFS");
987 
988 #ifdef USE_SETMNTENT
989  fdfs = setmntent(MNTENT_PATH, "r");
990  if (!fdfs)
991  return &info;
992 
993  while ((e = getmntent(fdfs)))
994  {
995  if (str_startswith(e->mnt_dir, fpath))
996  {
997  strcpy(info.type, e->mnt_type);
998  strcpy(info.name, e->mnt_fsname);
999  if (strstr(e->mnt_opts, "vfat") || strstr(e->mnt_opts, "iso9660"))
1000  {
1001  int fd = open(e->mnt_fsname, O_RDONLY);
1002  if (fd >= 0)
1003  {
1004  unsigned char buf[512];
1005  memset(buf, 0, sizeof(buf));
1006  if (strstr(e->mnt_opts, "vfat"))
1007  /*FAT*/
1008  {
1009  strcpy(info.type, "vfat");
1010  read(fd, buf, sizeof(buf));
1011  info.serial =
1012  (buf[42] << 24) + (buf[41] << 16) +
1013  (buf[40] << 8) + buf[39];
1014  strncpy(info.label, buf + 43, 10);
1015  info.label[10] = '\0';
1016  }
1017  else if (lseek(fd, 32767, SEEK_SET) >= 0) /* ISO9660 */
1018  {
1019  read(fd, buf, sizeof(buf));
1020  strncpy(info.label, buf + 41, 32);
1021  info.label[32] = '\0';
1022  /* info.Serial = (buf[128]<<24)+(buf[127]<<16)+(buf[126]<<8)+buf[125]; */
1023  }
1024  close(fd);
1025  }
1026  }
1027  }
1028  }
1029  endmntent(fdfs);
1030 #else
1031  /* initialize */
1032  memset(&info, 0, sizeof(info));
1033  strcpy(info.label, "RDESKTOP");
1034  strcpy(info.type, "RDPFS");
1035 
1036 #endif
1037  return &info;
1038 }
1039 
1040 
1041 NTSTATUS
1043 {
1044  struct STATFS_T stat_fs;
1045  struct fileinfo *pfinfo;
1046  FsInfoType *fsinfo;
1047 
1048  pfinfo = &(This->fileinfo[handle]);
1049 
1050  if (STATFS_FN(pfinfo->path, &stat_fs) != 0)
1051  {
1052  perror("statfs");
1053  return STATUS_ACCESS_DENIED;
1054  }
1055 
1056  fsinfo = FsVolumeInfo(pfinfo->path);
1057 
1058  switch (info_class)
1059  {
1061 
1062  out_uint32_le(out, 0); /* volume creation time low */
1063  out_uint32_le(out, 0); /* volume creation time high */
1064  out_uint32_le(out, fsinfo->serial); /* serial */
1065 
1066  out_uint32_le(out, 2 * strlen(fsinfo->label)); /* length of string */
1067 
1068  out_uint8(out, 0); /* support objects? */
1069  rdp_out_unistr(This, out, fsinfo->label, 2 * strlen(fsinfo->label) - 2);
1070  break;
1071 
1072  case FileFsSizeInformation:
1073 
1074  out_uint32_le(out, stat_fs.f_blocks); /* Total allocation units low */
1075  out_uint32_le(out, 0); /* Total allocation high units */
1076  out_uint32_le(out, stat_fs.f_bfree); /* Available allocation units */
1077  out_uint32_le(out, 0); /* Available allowcation units */
1078  out_uint32_le(out, stat_fs.f_bsize / 0x200); /* Sectors per allocation unit */
1079  out_uint32_le(out, 0x200); /* Bytes per sector */
1080  break;
1081 
1083 
1084  out_uint32_le(out, FS_CASE_SENSITIVE | FS_CASE_IS_PRESERVED); /* fs attributes */
1085  out_uint32_le(out, F_NAMELEN(stat_fs)); /* max length of filename */
1086 
1087  out_uint32_le(out, 2 * strlen(fsinfo->type)); /* length of fs_type */
1088  rdp_out_unistr(This, out, fsinfo->type, 2 * strlen(fsinfo->type) - 2);
1089  break;
1090 
1097 
1098  default:
1099 
1100  unimpl("IRP Query Volume Information class: 0x%x\n", info_class);
1101  return STATUS_INVALID_PARAMETER;
1102  }
1103  return STATUS_SUCCESS;
1104 }
1105 
1106 NTSTATUS
1108 {
1109  uint32 file_attributes, ft_low, ft_high;
1110  char *dirname, fullpath[PATH_MAX];
1111  DIR *pdir;
1112  struct dirent *pdirent;
1113  struct stat fstat;
1114  struct fileinfo *pfinfo;
1115 
1116  pfinfo = &(This->fileinfo[handle]);
1117  pdir = pfinfo->pdir;
1118  dirname = pfinfo->path;
1119  file_attributes = 0;
1120 
1121  switch (info_class)
1122  {
1124 
1125  /* If a search pattern is received, remember this pattern, and restart search */
1126  if (pattern[0] != 0)
1127  {
1128  strncpy(pfinfo->pattern, 1 + strrchr(pattern, '/'), PATH_MAX - 1);
1129  rewinddir(pdir);
1130  }
1131 
1132  /* find next dirent matching pattern */
1133  pdirent = readdir(pdir);
1134  while (pdirent && fnmatch(pfinfo->pattern, pdirent->d_name, 0) != 0)
1135  pdirent = readdir(pdir);
1136 
1137  if (pdirent == NULL)
1138  return STATUS_NO_MORE_FILES;
1139 
1140  /* Get information for directory entry */
1141  sprintf(fullpath, "%s/%s", dirname, pdirent->d_name);
1142 
1143  if (stat(fullpath, &fstat))
1144  {
1145  switch (errno)
1146  {
1147  case ENOENT:
1148  case ELOOP:
1149  case EACCES:
1150  /* These are non-fatal errors. */
1151  memset(&fstat, 0, sizeof(fstat));
1152  break;
1153  default:
1154  /* Fatal error. By returning STATUS_NO_SUCH_FILE,
1155  the directory list operation will be aborted */
1156  perror(fullpath);
1157  out_uint8(out, 0);
1158  return STATUS_NO_SUCH_FILE;
1159  }
1160  }
1161 
1162  if (S_ISDIR(fstat.st_mode))
1163  file_attributes |= FILE_ATTRIBUTE_DIRECTORY;
1164  if (pdirent->d_name[0] == '.')
1165  file_attributes |= FILE_ATTRIBUTE_HIDDEN;
1166  if (!file_attributes)
1167  file_attributes |= FILE_ATTRIBUTE_NORMAL;
1168  if (!(fstat.st_mode & S_IWUSR))
1169  file_attributes |= FILE_ATTRIBUTE_READONLY;
1170 
1171  /* Return requested information */
1172  out_uint8s(out, 8); /* unknown zero */
1173 
1175  out_uint32_le(out, ft_low); /* create time */
1176  out_uint32_le(out, ft_high);
1177 
1178  seconds_since_1970_to_filetime(fstat.st_atime, &ft_high, &ft_low);
1179  out_uint32_le(out, ft_low); /* last_access_time */
1180  out_uint32_le(out, ft_high);
1181 
1182  seconds_since_1970_to_filetime(fstat.st_mtime, &ft_high, &ft_low);
1183  out_uint32_le(out, ft_low); /* last_write_time */
1184  out_uint32_le(out, ft_high);
1185 
1186  seconds_since_1970_to_filetime(fstat.st_ctime, &ft_high, &ft_low);
1187  out_uint32_le(out, ft_low); /* change_write_time */
1188  out_uint32_le(out, ft_high);
1189 
1190  out_uint32_le(out, fstat.st_size); /* filesize low */
1191  out_uint32_le(out, 0); /* filesize high */
1192  out_uint32_le(out, fstat.st_size); /* filesize low */
1193  out_uint32_le(out, 0); /* filesize high */
1194  out_uint32_le(out, file_attributes);
1195  out_uint8(out, 2 * strlen(pdirent->d_name) + 2); /* unicode length */
1196  out_uint8s(out, 7); /* pad? */
1197  out_uint8(out, 0); /* 8.3 file length */
1198  out_uint8s(out, 2 * 12); /* 8.3 unicode length */
1199  rdp_out_unistr(This, out, pdirent->d_name, 2 * strlen(pdirent->d_name));
1200  break;
1201 
1202  default:
1203  /* FIXME: Support FileDirectoryInformation,
1204  FileFullDirectoryInformation, and
1205  FileNamesInformation */
1206 
1207  unimpl("IRP Query Directory sub: 0x%x\n", info_class);
1208  return STATUS_INVALID_PARAMETER;
1209  }
1210 
1211  return STATUS_SUCCESS;
1212 }
1213 
1214 
1215 
1216 static NTSTATUS
1218 {
1219  if (((request >> 16) != 20) || ((request >> 16) != 9))
1220  return STATUS_INVALID_PARAMETER;
1221 
1222  /* extract operation */
1223  request >>= 2;
1224  request &= 0xfff;
1225 
1226  printf("DISK IOCTL %d\n", request);
1227 
1228  switch (request)
1229  {
1230  case 25: /* ? */
1231  case 42: /* ? */
1232  default:
1233  unimpl("DISK IOCTL %d\n", request);
1234  return STATUS_INVALID_PARAMETER;
1235  }
1236 
1237  return STATUS_SUCCESS;
1238 }
1239 
1241  disk_create,
1242  disk_close,
1243  disk_read,
1244  disk_write,
1245  disk_device_control /* device_control */
1246 };
void rdp_in_unistr(STREAM s, int in_len, char **string, uint32 *str_size)
Definition: rdp.c:265
short st_nlink
Definition: stat.h:59
#define STATUS_OBJECT_NAME_COLLISION
Definition: udferr_usr.h:150
#define SEEK_CUR
Definition: util.h:63
static PIO_STATUS_BLOCK void ULONG FS_INFORMATION_CLASS info_class
Definition: pipe.c:76
#define GENERIC_ALL
Definition: nt_native.h:92
void __cdecl rewinddir(DIR *)
namespace GUID const ADDRINFOEXW ADDRINFOEXW struct timeval OVERLAPPED LPLOOKUPSERVICE_COMPLETION_ROUTINE HANDLE * handle
Definition: sock.c:82
RD_BOOL str_startswith(const char *s, const char *prefix)
Definition: rdesktop.c:1235
#define DEVICE_TYPE_DISK
Definition: constants.h:488
#define STATUS_FILE_IS_A_DIRECTORY
Definition: udferr_usr.h:164
#define LL
Definition: tui.h:85
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
RD_BOOL rdpdr_abort_io(uint32 fd, uint32 major, RD_NTSTATUS status)
#define error(str)
Definition: mkdosfs.c:1605
void convert_to_unix_filename(char *filename)
Definition: rdpdr.c:78
time_t st_ctime
Definition: stat.h:66
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
#define open
Definition: acwin.h:95
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
GLsizei const GLchar ** path
Definition: glext.h:7234
char * strstr(char *String1, char *String2)
Definition: utclib.c:653
#define FILE_DIRECTORY_FILE
Definition: constants.h:491
GLuint GLuint GLsizei count
Definition: gl.h:1545
unsigned int uint32
Definition: types.h:32
char * strncpy(char *DstString, const char *SrcString, ACPI_SIZE Count)
Definition: utclib.c:427
#define O_NONBLOCK
Definition: port.h:158
int f_namemax
Definition: disk.c:121
__kernel_off_t off_t
Definition: linux.h:201
#define EINTR
Definition: acclib.h:80
int notify
Definition: msacm.c:1353
char pathname[512]
Definition: util.h:13
#define FileFsFullSizeInformation
Definition: ntifs_ex.h:389
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS disk_query_directory(RDPCLIENT *This, NTHANDLE handle, uint32 info_class, char *pattern, STREAM out)
Definition: disk.c:1107
NTSTATUS disk_query_information(RDPCLIENT *This, NTHANDLE handle, uint32 info_class, STREAM out)
Definition: disk.c:612
GLintptr offset
Definition: glext.h:5920
#define out_uint32_le(s, v)
Definition: parse.h:59
GLdouble n
Definition: glext.h:7729
#define ELOOP
Definition: errno.h:41
__cdecl __MINGW_NOTHROW char * dirname(char *)
#define unlink
Definition: syshdrs.h:54
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
static int fd
Definition: io.c:51
static NTSTATUS disk_close(RDPCLIENT *This, NTHANDLE handle)
Definition: disk.c:498
_Check_return_opt_ _CRTIMP long __cdecl lseek(_In_ int _FileHandle, _In_ long _Offset, _In_ int _Origin)
static NTSTATUS disk_device_control(RDPCLIENT *This, NTHANDLE handle, uint32 request, STREAM in, STREAM out)
Definition: disk.c:1217
NTSTATUS disk_query_volume_information(RDPCLIENT *This, NTHANDLE handle, uint32 info_class, STREAM out)
Definition: disk.c:1042
int errno
_Check_return_ _CRTIMP _CONST_RETURN char *__cdecl strrchr(_In_z_ const char *_Str, _In_ int _Ch)
const char * filename
Definition: ioapi.h:135
#define F_NAMELEN(buf)
Definition: disk.c:110
long f_bsize
Definition: disk.c:118
#define STATUS_INVALID_HANDLE
Definition: ntstatus.h:231
#define EEXIST
Definition: acclib.h:88
Definition: fatfs.h:198
struct _test_info info[]
Definition: SetCursorPos.c:19
__CRT_INLINE int __cdecl utime(const char *_Filename, struct utimbuf *_Utimbuf)
Definition: utime.h:136
T MIN(T a, T b)
Definition: polytest.cpp:79
#define sprintf(buf, format,...)
Definition: sprintf.c:55
DIR *__cdecl opendir(const char *)
#define write
Definition: acwin.h:97
#define out_uint8(s, v)
Definition: parse.h:92
NOTIFY notify
Definition: types.h:291
static int open_weak_exclusive(const char *pathname, int flags, mode_t mode)
Definition: disk.c:257
NTSTATUS disk_create_notify(RDPCLIENT *This, NTHANDLE handle, uint32 info_class)
Definition: disk.c:898
_Check_return_ int __cdecl rename(_In_z_ const char *_OldFilename, _In_z_ const char *_NewFilename)
void * xmalloc(int size)
Definition: uimain.c:747
_CRTIMP void __cdecl perror(_In_opt_z_ const char *_ErrMsg)
#define RDPDR_MAX_DEVICES
Definition: constants.h:484
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
int ftruncate(int, off_t)
Definition: unistd.h:30
#define e
Definition: ke_i.h:82
#define S_IRGRP
Definition: propsheet.h:41
#define S_IXOTH
Definition: propsheet.h:61
static NTSTATUS disk_write(RDPCLIENT *This, NTHANDLE handle, uint8 *data, uint32 length, uint32 offset, uint32 *result)
Definition: disk.c:585
#define O_WRONLY
Definition: acwin.h:111
#define GENERIC_WRITE
Definition: nt_native.h:90
Definition: dirent.h:39
static time_t get_create_time(struct stat *st)
Definition: disk.c:151
Definition: arc.h:49
smooth NULL
Definition: ftsmooth.c:416
static FsInfoType * FsVolumeInfo(char *fpath)
Definition: disk.c:974
#define in_uint8s(s, n)
Definition: parse.h:91
char label[PATH_MAX]
Definition: disk.c:143
NTSTATUS disk_check_notify(RDPCLIENT *This, NTHANDLE handle)
Definition: disk.c:867
#define out_uint8s(s, n)
Definition: parse.h:95
RD_BOOL delete_on_close
Definition: types.h:290
#define FS_CASE_SENSITIVE
Definition: disk.h:56
time_t actime
Definition: syshdrs.h:132
#define O_EXCL
Definition: fcntl.h:40
#define STATUS_NOTIFY_ENUM_DIR
Definition: ntstatus.h:91
#define OPEN_EXISTING
Definition: compat.h:426
GLuint GLfloat * val
Definition: glext.h:7180
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
uint32 info_class
Definition: types.h:292
char * d_name
Definition: dirent.h:29
Definition: arc.h:50
#define True
Definition: types.h:24
#define SEEK_SET
Definition: jmemansi.c:26
#define FILE_DELETE_ON_CLOSE
Definition: constants.h:494
#define S_IWGRP
Definition: propsheet.h:45
__u16 ctime
Definition: mkdosfs.c:362
#define S_IXGRP
Definition: propsheet.h:49
#define False
Definition: types.h:25
static NTSTATUS disk_create(RDPCLIENT *This, uint32 device_id, uint32 accessmask, uint32 sharemode, uint32 create_disposition, uint32 flags_and_attributes, char *filename, NTHANDLE *phandle)
Definition: disk.c:336
#define S_IWUSR
Definition: propsheet.h:33
void xfree(void *mem)
Definition: uimain.c:758
#define FileFsObjectIdInformation
Definition: ntifs_ex.h:390
#define STATUS_PENDING
Definition: ntstatus.h:82
#define mkdir
Definition: acwin.h:101
#define STATUS_NO_MORE_FILES
Definition: udferr_usr.h:128
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
int disk_enum_devices(RDPCLIENT *This, uint32 *id, char *optarg)
Definition: disk.c:306
unsigned long serial
Definition: disk.c:144
#define S_ISDIR(mode)
Definition: various.h:18
#define STATUS_CANCELLED
Definition: udferr_usr.h:170
#define FILE_ATTRIBUTE_READONLY
Definition: nt_native.h:702
static FILE * out
Definition: regtests2xml.c:44
#define DIRFD(a)
Definition: disk.c:38
#define PATH_MAX
Definition: types.h:280
unsigned char uint8
Definition: types.h:28
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
char type[PATH_MAX]
Definition: disk.c:145
#define OPEN_ALWAYS
Definition: disk.h:70
NTSTATUS disk_set_information(RDPCLIENT *This, NTHANDLE handle, uint32 info_class, STREAM in, STREAM out)
Definition: disk.c:693
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLbitfield flags
Definition: glext.h:7161
char * next_arg(char *src, char needle)
Definition: rdesktop.c:1174
static double zero
Definition: j0_y0.c:96
int ret
Definition: arc.h:34
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:126
struct dirent * pdirent
Definition: types.h:288
Definition: parse.h:22
#define S_IROTH
Definition: propsheet.h:53
unsigned short st_mode
Definition: stat.h:58
int f_namelen
Definition: disk.c:120
Definition: stat.h:55
#define FILE_NON_DIRECTORY_FILE
Definition: constants.h:492
static NTSTATUS disk_read(RDPCLIENT *This, NTHANDLE handle, uint8 *data, uint32 length, uint32 offset, uint32 *result)
Definition: disk.c:545
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
time_t modtime
Definition: syshdrs.h:132
#define O_TRUNC
Definition: acwin.h:112
#define GENERIC_READ
Definition: compat.h:124
#define close
Definition: acwin.h:98
GLenum mode
Definition: glext.h:6217
int __cdecl closedir(DIR *)
uint8_t label[11]
Definition: fsck.fat.h:65
#define FS_CASE_IS_PRESERVED
Definition: disk.h:57
#define S_IWOTH
Definition: propsheet.h:57
struct dirent *__cdecl readdir(DIR *)
DIR * pdir
Definition: types.h:287
_CRTIMP int __cdecl stat(const char *_Filename, struct stat *_Stat)
Definition: stat.h:345
#define CREATE_ALWAYS
Definition: disk.h:72
GLuint in
Definition: glext.h:9616
__kernel_mode_t mode_t
Definition: linux.h:199
__kernel_time_t time_t
Definition: linux.h:252
time_t st_atime
Definition: stat.h:64
void rdp_out_unistr(STREAM s, char *string, int len)
Definition: rdp.c:188
#define O_RDWR
Definition: fcntl.h:36
const char * optarg
Definition: getopt.c:49
#define long
Definition: qsort.c:33
#define STATUS_NO_SUCH_FILE
Definition: udferr_usr.h:137
Definition: services.c:325
#define FILE_ATTRIBUTE_HIDDEN
Definition: nt_native.h:703
Definition: arc.h:46
char pattern[PATH_MAX]
Definition: types.h:289
#define STATFS_T
Definition: disk.c:136
static time_t convert_1970_to_filetime(uint32 high, uint32 low)
Definition: disk.c:177
static void seconds_since_1970_to_filetime(time_t seconds, uint32 *high, uint32 *low)
Definition: disk.c:166
Definition: arc.h:41
#define S_IRWXU
Definition: ext2fs.h:377
Definition: tftpd.h:85
#define FileStandardInformation
Definition: propsheet.cpp:61
static NTSTATUS NotifyInfo(RDPCLIENT *This, NTHANDLE handle, uint32 info_class, NOTIFY *p)
Definition: disk.c:925
Definition: name.c:36
DEVICE_FNS disk_fns
Definition: disk.c:1240
static int ftruncate_growable(int fd, off_t length)
Definition: disk.c:195
#define STATUS_DISK_FULL
Definition: udferr_usr.h:155
_CRTIMP int __cdecl fstat(int _Desc, struct stat *_Stat)
Definition: stat.h:341
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
static int dummy_statfs(struct dummy_statfs_t *buf)
Definition: disk.c:125
GLenum GLuint id
Definition: glext.h:5579
FILE * stderr
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
char path[PATH_MAX]
Definition: types.h:286
void unimpl(char *format,...)
Definition: uimain.c:801
#define CREATE_NEW
Definition: disk.h:69
#define TRUNCATE_EXISTING
Definition: disk.h:71
long f_bfree
Definition: disk.c:117
void exit(int exitcode)
Definition: _exit.c:33
GLfloat GLfloat p
Definition: glext.h:8902
#define in_uint32_le(s, v)
Definition: parse.h:56
time_t st_mtime
Definition: stat.h:65
return STATUS_SUCCESS
Definition: btrfs.c:2966
#define rmdir
Definition: syshdrs.h:70
GLuint64EXT * result
Definition: glext.h:11304
#define memset(x, y, z)
Definition: compat.h:39
static SERVICE_STATUS status
Definition: service.c:31
int fnmatch(char *pattern, const char *string, int flags) const
Definition: fnmatch.c:100
#define STATFS_FN(path, buf)
Definition: disk.c:137
#define O_CREAT
Definition: acwin.h:110
#define FILE_COMPLETE_IF_OPLOCKED
Definition: constants.h:493
#define EPERM
Definition: acclib.h:78
_CRTIMP int __cdecl read(_In_ int _FileHandle, _Out_writes_bytes_(_MaxCharCount) void *_DstBuf, _In_ unsigned int _MaxCharCount)
GLubyte * pattern
Definition: glext.h:7787
long f_blocks
Definition: disk.c:119
_off_t st_size
Definition: stat.h:63
#define printf
Definition: config.h:203
#define O_RDONLY
Definition: acwin.h:108
Definition: ps.c:97