/[rdesktop]/sourceforge.net/trunk/rdesktop/disk.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /sourceforge.net/trunk/rdesktop/disk.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 616 by n-ki, Tue Feb 24 15:24:38 2004 UTC revision 879 by astrand, Sun Apr 3 18:08:05 2005 UTC
# Line 18  Line 18 
18     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  */  */
20    
21  #define FILE_ATTRIBUTE_READONLY                 0x00000001  #include "disk.h"
 #define FILE_ATTRIBUTE_HIDDEN                   0x00000002  
 #define FILE_ATTRIBUTE_SYSTEM                   0x00000004  
 #define FILE_ATTRIBUTE_DIRECTORY                0x00000010  
 #define FILE_ATTRIBUTE_ARCHIVE                  0x00000020  
 #define FILE_ATTRIBUTE_DEVICE                   0x00000040  
 #define FILE_ATTRIBUTE_UNKNOWNXXX0              0x00000060      /* ??? ACTION i.e. 0x860 == compress this file ? */  
 #define FILE_ATTRIBUTE_NORMAL                   0x00000080  
 #define FILE_ATTRIBUTE_TEMPORARY                0x00000100  
 #define FILE_ATTRIBUTE_SPARSE_FILE              0x00000200  
 #define FILE_ATTRIBUTE_REPARSE_POINT            0x00000400  
 #define FILE_ATTRIBUTE_COMPRESSED               0x00000800  
 #define FILE_ATTRIBUTE_OFFLINE                  0x00001000  
 #define FILE_ATTRIBUTE_NOT_CONTENT_INDEXED      0x00002000  
 #define FILE_ATTRIBUTE_ENCRYPTED                0x00004000  
   
 #define FILE_FLAG_OPEN_NO_RECALL                0x00100000  
 #define FILE_FLAG_OPEN_REPARSE_POINT            0x00200000  
 #define FILE_FLAG_POSIX_SEMANTICS               0x01000000  
 #define FILE_FLAG_BACKUP_SEMANTICS              0x02000000      /* sometimes used to create a directory */  
 #define FILE_FLAG_DELETE_ON_CLOSE               0x04000000  
 #define FILE_FLAG_SEQUENTIAL_SCAN               0x08000000  
 #define FILE_FLAG_RANDOM_ACCESS                 0x10000000  
 #define FILE_FLAG_NO_BUFFERING                  0x20000000  
 #define FILE_FLAG_OVERLAPPED                    0x40000000  
 #define FILE_FLAG_WRITE_THROUGH                 0x80000000  
   
 #define FILE_SHARE_READ                         0x01  
 #define FILE_SHARE_WRITE                        0x02  
 #define FILE_SHARE_DELETE                       0x04  
   
 #define FILE_BASIC_INFORMATION                  0x04  
 #define FILE_STANDARD_INFORMATION               0x05  
   
 #define FS_CASE_SENSITIVE                       0x00000001  
 #define FS_CASE_IS_PRESERVED                    0x00000002  
 #define FS_UNICODE_STORED_ON_DISK               0x00000004  
 #define FS_PERSISTENT_ACLS                      0x00000008  
 #define FS_FILE_COMPRESSION                     0x00000010  
 #define FS_VOLUME_QUOTAS                        0x00000020  
 #define FS_SUPPORTS_SPARSE_FILES                0x00000040  
 #define FS_SUPPORTS_REPARSE_POINTS              0x00000080  
 #define FS_SUPPORTS_REMOTE_STORAGE              0X00000100  
 #define FS_VOL_IS_COMPRESSED                    0x00008000  
 #define FILE_READ_ONLY_VOLUME                   0x00080000  
   
 #define OPEN_EXISTING                           1  
 #define CREATE_NEW                              2  
 #define OPEN_ALWAYS                             3  
 #define TRUNCATE_EXISTING                       4  
 #define CREATE_ALWAYS                           5  
   
 #define GENERIC_READ                            0x80000000  
 #define GENERIC_WRITE                           0x40000000  
 #define GENERIC_EXECUTE                         0x20000000  
 #define GENERIC_ALL                             0x10000000  
   
 #define ERROR_FILE_NOT_FOUND                    2L  
 #define ERROR_ALREADY_EXISTS                    183L  
   
 #define MAX_OPEN_FILES  0x100  
   
 #if (defined(sun) && (defined(__svr4__) || defined(__SVR4)))  
 #define SOLARIS  
 #endif  
   
 #if (defined(SOLARIS) || defined(__hpux))  
 #define DIRFD(a) ((a)->dd_fd)  
 #else  
 #define DIRFD(a) (dirfd(a))  
 #endif  
22    
23  #include <sys/types.h>  #include <sys/types.h>
24  #include <sys/stat.h>  #include <sys/stat.h>
# Line 101  Line 31 
31  #include <utime.h>  #include <utime.h>
32  #include <time.h>               /* ctime */  #include <time.h>               /* ctime */
33    
34    #if (defined(HAVE_DIRFD) || (HAVE_DECL_DIRFD == 1))
35    #define DIRFD(a) (dirfd(a))
36    #else
37    #define DIRFD(a) ((a)->DIR_FD_MEMBER_NAME)
38    #endif
39    
40  #if (defined(SOLARIS) || defined (__hpux) || defined(__BEOS__))  /* TODO: Fix mntent-handling for solaris
41  #include <sys/statvfs.h>        /* solaris statvfs */   * #include <sys/mntent.h> */
42  #include <sys/mntent.h>  #if (defined(HAVE_MNTENT_H) && defined(HAVE_SETMNTENT))
43  #define HAVE_MNTENT_H  #include <mntent.h>
44  #define MNTENT_PATH "/etc/mnttab"  #define MNTENT_PATH "/etc/mtab"
45  #define STATFS_FN(path, buf) (statvfs(path,buf))  #define USE_SETMNTENT
46  #define STATFS_T statvfs  #endif
47  #define F_NAMELEN(buf) ((buf).f_namemax)  
48    #ifdef HAVE_SYS_VFS_H
49    #include <sys/vfs.h>
50    #endif
51    
52    #ifdef HAVE_SYS_STATVFS_H
53    #include <sys/statvfs.h>
54    #endif
55    
56  #elif (defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__))  #ifdef HAVE_SYS_STATFS_H
57    #include <sys/statfs.h>
58    #endif
59    
60    #ifdef HAVE_SYS_PARAM_H
61  #include <sys/param.h>  #include <sys/param.h>
62    #endif
63    
64    #ifdef HAVE_SYS_MOUNT_H
65  #include <sys/mount.h>  #include <sys/mount.h>
66  #define STATFS_FN(path, buf) (statfs(path,buf))  #endif
67    
68    #include "rdesktop.h"
69    
70    #ifdef STAT_STATFS3_OSF1
71    #define STATFS_FN(path, buf) (statfs(path,buf,sizeof(buf)))
72  #define STATFS_T statfs  #define STATFS_T statfs
73  #define F_NAMELEN(buf) (NAME_MAX)  #define USE_STATFS
74    #endif
75    
76  #else  #ifdef STAT_STATVFS
77  #include <sys/vfs.h>            /* linux statfs */  #define STATFS_FN(path, buf) (statvfs(path,buf))
78  #include <mntent.h>  #define STATFS_T statvfs
79  #define HAVE_MNTENT_H  #define USE_STATVFS
80  #define MNTENT_PATH "/etc/mtab"  #endif
81    
82    #ifdef STAT_STATVFS64
83    #define STATFS_FN(path, buf) (statvfs64(path,buf))
84    #define STATFS_T statvfs64
85    #define USE_STATVFS
86    #endif
87    
88    #if (defined(STAT_STATFS2_FS_DATA) || defined(STAT_STATFS2_BSIZE) || defined(STAT_STATFS2_FSIZE))
89  #define STATFS_FN(path, buf) (statfs(path,buf))  #define STATFS_FN(path, buf) (statfs(path,buf))
90  #define STATFS_T statfs  #define STATFS_T statfs
91    #define USE_STATFS
92    #endif
93    
94    #ifdef STAT_STATFS4
95    #define STATFS_FN(path, buf) (statfs(path,buf,sizeof(buf),0))
96    #define STATFS_T statfs
97    #define USE_STATFS
98    #endif
99    
100    #if ((defined(USE_STATFS) && defined(HAVE_STRUCT_STATFS_F_NAMEMAX)) || (defined(USE_STATVFS) && defined(HAVE_STRUCT_STATVFS_F_NAMEMAX)))
101    #define F_NAMELEN(buf) ((buf).f_namemax)
102    #endif
103    
104    #if ((defined(USE_STATFS) && defined(HAVE_STRUCT_STATFS_F_NAMELEN)) || (defined(USE_STATVFS) && defined(HAVE_STRUCT_STATVFS_F_NAMELEN)))
105  #define F_NAMELEN(buf) ((buf).f_namelen)  #define F_NAMELEN(buf) ((buf).f_namelen)
106  #endif  #endif
107    
108  #include "rdesktop.h"  #ifndef F_NAMELEN
109    #define F_NAMELEN(buf) (255)
110    #endif
111    
112  extern RDPDR_DEVICE g_rdpdr_device[];  /* Dummy statfs fallback */
113    #ifndef STATFS_T
114    struct dummy_statfs_t
115    {
116            long f_bfree;
117            long f_bsize;
118            long f_blocks;
119            int f_namelen;
120            int f_namemax;
121    };
122    
123  struct fileinfo  int
124    dummy_statfs(struct dummy_statfs_t *buf)
125  {  {
126          uint32 device_id, flags_and_attributes;          buf->f_blocks = 262144;
127          char path[256];          buf->f_bfree = 131072;
128          DIR *pdir;          buf->f_bsize = 512;
129          struct dirent *pdirent;          buf->f_namelen = 255;
130          char pattern[64];          buf->f_namemax = 255;
131          BOOL delete_on_close;  
132            return 0;
133  }  }
134  g_fileinfo[MAX_OPEN_FILES];  
135    #define STATFS_T dummy_statfs_t
136    #define STATFS_FN(path,buf) (dummy_statfs(buf))
137    #endif
138    
139    extern RDPDR_DEVICE g_rdpdr_device[];
140    
141    FILEINFO g_fileinfo[MAX_OPEN_FILES];
142    BOOL g_notify_stamp = False;
143    
144  typedef struct  typedef struct
145  {  {
# Line 151  typedef struct Line 149  typedef struct
149          char type[256];          char type[256];
150  } FsInfoType;  } FsInfoType;
151    
152    static NTSTATUS NotifyInfo(NTHANDLE handle, uint32 info_class, NOTIFY * p);
153    
154  time_t  static time_t
155  get_create_time(struct stat *st)  get_create_time(struct stat *st)
156  {  {
157          time_t ret, ret1;          time_t ret, ret1;
# Line 167  get_create_time(struct stat *st) Line 166  get_create_time(struct stat *st)
166  }  }
167    
168  /* Convert seconds since 1970 to a filetime */  /* Convert seconds since 1970 to a filetime */
169  void  static void
170  seconds_since_1970_to_filetime(time_t seconds, uint32 * high, uint32 * low)  seconds_since_1970_to_filetime(time_t seconds, uint32 * high, uint32 * low)
171  {  {
172          unsigned long long ticks;          unsigned long long ticks;
# Line 178  seconds_since_1970_to_filetime(time_t se Line 177  seconds_since_1970_to_filetime(time_t se
177  }  }
178    
179  /* Convert seconds since 1970 back to filetime */  /* Convert seconds since 1970 back to filetime */
180  time_t  static time_t
181  convert_1970_to_filetime(uint32 high, uint32 low)  convert_1970_to_filetime(uint32 high, uint32 low)
182  {  {
183          unsigned long long ticks;          unsigned long long ticks;
# Line 193  convert_1970_to_filetime(uint32 high, ui Line 192  convert_1970_to_filetime(uint32 high, ui
192    
193  }  }
194    
195    /* A wrapper for ftruncate which supports growing files, even if the
196       native ftruncate doesn't. This is needed on Linux FAT filesystems,
197       for example. */
198    static int
199    ftruncate_growable(int fd, off_t length)
200    {
201            int ret;
202            off_t pos;
203            static const char zero;
204    
205            /* Try the simple method first */
206            if ((ret = ftruncate(fd, length)) != -1)
207            {
208                    return ret;
209            }
210    
211            /*
212             * Some kind of error. Perhaps we were trying to grow. Retry
213             * in a safe way.
214             */
215    
216            /* Get current position */
217            if ((pos = lseek(fd, 0, SEEK_CUR)) == -1)
218            {
219                    perror("lseek");
220                    return -1;
221            }
222    
223            /* Seek to new size */
224            if (lseek(fd, length, SEEK_SET) == -1)
225            {
226                    perror("lseek");
227                    return -1;
228            }
229    
230            /* Write a zero */
231            if (write(fd, &zero, 1) == -1)
232            {
233                    perror("write");
234                    return -1;
235            }
236    
237            /* Truncate. This shouldn't fail. */
238            if (ftruncate(fd, length) == -1)
239            {
240                    perror("ftruncate");
241                    return -1;
242            }
243    
244            /* Restore position */
245            if (lseek(fd, pos, SEEK_SET) == -1)
246            {
247                    perror("lseek");
248                    return -1;
249            }
250    
251            return 0;
252    }
253    
254    /* Just like open(2), but if a open with O_EXCL fails, retry with
255       GUARDED semantics. This might be necessary because some filesystems
256       (such as NFS filesystems mounted from a unfsd server) doesn't
257       support O_EXCL. GUARDED semantics are subject to race conditions,
258       but we can live with that.
259    */
260    static int
261    open_weak_exclusive(const char *pathname, int flags, mode_t mode)
262    {
263            int ret;
264            struct stat statbuf;
265    
266            ret = open(pathname, flags, mode);
267            if (ret != -1 || !(flags & O_EXCL))
268            {
269                    /* Success, or not using O_EXCL */
270                    return ret;
271            }
272    
273            /* An error occured, and we are using O_EXCL. In case the FS
274               doesn't support O_EXCL, some kind of error will be
275               returned. Unfortunately, we don't know which one. Linux
276               2.6.8 seems to return 524, but I cannot find a documented
277               #define for this case. So, we'll return only on errors that
278               we know aren't related to O_EXCL. */
279            switch (errno)
280            {
281                    case EACCES:
282                    case EEXIST:
283                    case EINTR:
284                    case EISDIR:
285                    case ELOOP:
286                    case ENAMETOOLONG:
287                    case ENOENT:
288                    case ENOTDIR:
289                            return ret;
290            }
291    
292            /* Retry with GUARDED semantics */
293            if (stat(pathname, &statbuf) != -1)
294            {
295                    /* File exists */
296                    errno = EEXIST;
297                    return -1;
298            }
299            else
300            {
301                    return open(pathname, flags & ~O_EXCL, mode);
302            }
303    }
304    
305  /* Enumeration of devices from rdesktop.c        */  /* Enumeration of devices from rdesktop.c        */
306  /* returns numer of units found and initialized. */  /* returns numer of units found and initialized. */
# Line 205  disk_enum_devices(uint32 * id, char *opt Line 313  disk_enum_devices(uint32 * id, char *opt
313          char *pos2;          char *pos2;
314          int count = 0;          int count = 0;
315    
316          // skip the first colon          /* skip the first colon */
317          optarg++;          optarg++;
318          while ((pos = next_arg(optarg, ',')) && *id < RDPDR_MAX_DEVICES)          while ((pos = next_arg(optarg, ',')) && *id < RDPDR_MAX_DEVICES)
319          {          {
320                  pos2 = next_arg(optarg, '=');                  pos2 = next_arg(optarg, '=');
                 strcpy(g_rdpdr_device[*id].name, optarg);  
321    
322                  toupper_str(g_rdpdr_device[*id].name);                  strncpy(g_rdpdr_device[*id].name, optarg, sizeof(g_rdpdr_device[*id].name) - 1);
323                    if (strlen(optarg) > (sizeof(g_rdpdr_device[*id].name) - 1))
324                  /* add trailing colon to name. */                          fprintf(stderr, "share name %s truncated to %s\n", optarg,
325                  strcat(g_rdpdr_device[*id].name, ":");                                  g_rdpdr_device[*id].name);
326    
327                  g_rdpdr_device[*id].local_path = xmalloc(strlen(pos2) + 1);                  g_rdpdr_device[*id].local_path = xmalloc(strlen(pos2) + 1);
328                  strcpy(g_rdpdr_device[*id].local_path, pos2);                  strcpy(g_rdpdr_device[*id].local_path, pos2);
                 printf("DISK %s to %s\n", g_rdpdr_device[*id].name, g_rdpdr_device[*id].local_path);  
329                  g_rdpdr_device[*id].device_type = DEVICE_TYPE_DISK;                  g_rdpdr_device[*id].device_type = DEVICE_TYPE_DISK;
330                  count++;                  count++;
331                  (*id)++;                  (*id)++;
# Line 230  disk_enum_devices(uint32 * id, char *opt Line 336  disk_enum_devices(uint32 * id, char *opt
336  }  }
337    
338  /* Opens or creates a file or directory */  /* Opens or creates a file or directory */
339  NTSTATUS  static NTSTATUS
340  disk_create(uint32 device_id, uint32 accessmask, uint32 sharemode, uint32 create_disposition,  disk_create(uint32 device_id, uint32 accessmask, uint32 sharemode, uint32 create_disposition,
341              uint32 flags_and_attributes, char *filename, HANDLE * phandle)              uint32 flags_and_attributes, char *filename, NTHANDLE * phandle)
342  {  {
343          HANDLE handle;          NTHANDLE handle;
344          DIR *dirp;          DIR *dirp;
345          int flags, mode;          int flags, mode;
346          char path[256];          char path[256];
# Line 245  disk_create(uint32 device_id, uint32 acc Line 351  disk_create(uint32 device_id, uint32 acc
351          flags = 0;          flags = 0;
352          mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;          mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
353    
354            if (*filename && filename[strlen(filename) - 1] == '/')
         if (filename[strlen(filename) - 1] == '/')  
355                  filename[strlen(filename) - 1] = 0;                  filename[strlen(filename) - 1] = 0;
356          sprintf(path, "%s%s", g_rdpdr_device[device_id].local_path, filename);          sprintf(path, "%s%s", g_rdpdr_device[device_id].local_path, filename);
357    
# Line 254  disk_create(uint32 device_id, uint32 acc Line 359  disk_create(uint32 device_id, uint32 acc
359          {          {
360                  case CREATE_ALWAYS:                  case CREATE_ALWAYS:
361    
362                          // Delete existing file/link.                          /* Delete existing file/link. */
363                          unlink(path);                          unlink(path);
364                          flags |= O_CREAT;                          flags |= O_CREAT;
365                          break;                          break;
366    
367                  case CREATE_NEW:                  case CREATE_NEW:
368    
369                          // If the file already exists, then fail.                          /* If the file already exists, then fail. */
370                          flags |= O_CREAT | O_EXCL;                          flags |= O_CREAT | O_EXCL;
371                          break;                          break;
372    
373                  case OPEN_ALWAYS:                  case OPEN_ALWAYS:
374    
375                          // Create if not already exists.                          /* Create if not already exists. */
376                          flags |= O_CREAT;                          flags |= O_CREAT;
377                          break;                          break;
378    
379                  case OPEN_EXISTING:                  case OPEN_EXISTING:
380    
381                          // Default behaviour                          /* Default behaviour */
382                          break;                          break;
383    
384                  case TRUNCATE_EXISTING:                  case TRUNCATE_EXISTING:
385    
386                          // If the file does not exist, then fail.                          /* If the file does not exist, then fail. */
387                          flags |= O_TRUNC;                          flags |= O_TRUNC;
388                          break;                          break;
389          }          }
390    
391          //printf("Open: \"%s\"  flags: %u, accessmask: %u sharemode: %u create disp: %u\n", path, flags_and_attributes, accessmask, sharemode, create_disposition);          /*printf("Open: \"%s\"  flags: %X, accessmask: %X sharemode: %X create disp: %X\n", path, flags_and_attributes, accessmask, sharemode, create_disposition); */
392    
393          // Get information about file and set that flag ourselfs          /* Get information about file and set that flag ourselfs */
394          if ((stat(path, &filestat) == 0) && (S_ISDIR(filestat.st_mode)))          if ((stat(path, &filestat) == 0) && (S_ISDIR(filestat.st_mode)))
395          {          {
396                  if (flags_and_attributes & FILE_NON_DIRECTORY_FILE)                  if (flags_and_attributes & FILE_NON_DIRECTORY_FILE)
# Line 339  disk_create(uint32 device_id, uint32 acc Line 444  disk_create(uint32 device_id, uint32 acc
444                          flags |= O_RDONLY;                          flags |= O_RDONLY;
445                  }                  }
446    
447                  handle = open(path, flags, mode);                  handle = open_weak_exclusive(path, flags, mode);
448                  if (handle == -1)                  if (handle == -1)
449                  {                  {
450                          switch (errno)                          switch (errno)
# Line 379  disk_create(uint32 device_id, uint32 acc Line 484  disk_create(uint32 device_id, uint32 acc
484    
485          if (dirp)          if (dirp)
486                  g_fileinfo[handle].pdir = dirp;                  g_fileinfo[handle].pdir = dirp;
487            else
488                    g_fileinfo[handle].pdir = NULL;
489    
490          g_fileinfo[handle].device_id = device_id;          g_fileinfo[handle].device_id = device_id;
491          g_fileinfo[handle].flags_and_attributes = flags_and_attributes;          g_fileinfo[handle].flags_and_attributes = flags_and_attributes;
492            g_fileinfo[handle].accessmask = accessmask;
493          strncpy(g_fileinfo[handle].path, path, 255);          strncpy(g_fileinfo[handle].path, path, 255);
494            g_fileinfo[handle].delete_on_close = False;
495            g_notify_stamp = True;
496    
497          *phandle = handle;          *phandle = handle;
498          return STATUS_SUCCESS;          return STATUS_SUCCESS;
499  }  }
500    
501  NTSTATUS  static NTSTATUS
502  disk_close(HANDLE handle)  disk_close(NTHANDLE handle)
503  {  {
504          struct fileinfo *pfinfo;          struct fileinfo *pfinfo;
505    
506          pfinfo = &(g_fileinfo[handle]);          pfinfo = &(g_fileinfo[handle]);
507    
508          if (pfinfo->flags_and_attributes & FILE_DIRECTORY_FILE)          g_notify_stamp = True;
509    
510            rdpdr_abort_io(handle, 0, STATUS_CANCELLED);
511    
512            if (pfinfo->pdir)
513          {          {
514                  closedir(pfinfo->pdir);                  if (closedir(pfinfo->pdir) < 0)
515                  //FIXME: Should check exit code                  {
516                            perror("closedir");
517                            return STATUS_INVALID_HANDLE;
518                    }
519    
520                    if (pfinfo->delete_on_close)
521                            if (rmdir(pfinfo->path) < 0)
522                            {
523                                    perror(pfinfo->path);
524                                    return STATUS_ACCESS_DENIED;
525                            }
526                    pfinfo->delete_on_close = False;
527          }          }
528          else          else
529          {          {
530                  close(handle);                  if (close(handle) < 0)
531                    {
532                            perror("close");
533                            return STATUS_INVALID_HANDLE;
534                    }
535                    if (pfinfo->delete_on_close)
536                            if (unlink(pfinfo->path) < 0)
537                            {
538                                    perror(pfinfo->path);
539                                    return STATUS_ACCESS_DENIED;
540                            }
541    
542                    pfinfo->delete_on_close = False;
543          }          }
544    
545          return STATUS_SUCCESS;          return STATUS_SUCCESS;
546  }  }
547    
548  NTSTATUS  static NTSTATUS
549  disk_read(HANDLE handle, uint8 * data, uint32 length, uint32 offset, uint32 * result)  disk_read(NTHANDLE handle, uint8 * data, uint32 length, uint32 offset, uint32 * result)
550  {  {
551          int n;          int n;
552    
# Line 432  disk_read(HANDLE handle, uint8 * data, u Line 570  disk_read(HANDLE handle, uint8 * data, u
570                  switch (errno)                  switch (errno)
571                  {                  {
572                          case EISDIR:                          case EISDIR:
573                                  return STATUS_FILE_IS_A_DIRECTORY;                                  /* Implement 24 Byte directory read ??
574                                       with STATUS_NOT_IMPLEMENTED server doesn't read again */
575                                    /* return STATUS_FILE_IS_A_DIRECTORY; */
576                                    return STATUS_NOT_IMPLEMENTED;
577                          default:                          default:
578                                  perror("read");                                  perror("read");
579                                  return STATUS_INVALID_PARAMETER;                                  return STATUS_INVALID_PARAMETER;
# Line 444  disk_read(HANDLE handle, uint8 * data, u Line 585  disk_read(HANDLE handle, uint8 * data, u
585          return STATUS_SUCCESS;          return STATUS_SUCCESS;
586  }  }
587    
588  NTSTATUS  static NTSTATUS
589  disk_write(HANDLE handle, uint8 * data, uint32 length, uint32 offset, uint32 * result)  disk_write(NTHANDLE handle, uint8 * data, uint32 length, uint32 offset, uint32 * result)
590  {  {
591          int n;          int n;
592    
# Line 472  disk_write(HANDLE handle, uint8 * data, Line 613  disk_write(HANDLE handle, uint8 * data,
613  }  }
614    
615  NTSTATUS  NTSTATUS
616  disk_query_information(HANDLE handle, uint32 info_class, STREAM out)  disk_query_information(NTHANDLE handle, uint32 info_class, STREAM out)
617  {  {
618          uint32 file_attributes, ft_high, ft_low;          uint32 file_attributes, ft_high, ft_low;
619          struct stat filestat;          struct stat filestat;
# Line 480  disk_query_information(HANDLE handle, ui Line 621  disk_query_information(HANDLE handle, ui
621    
622          path = g_fileinfo[handle].path;          path = g_fileinfo[handle].path;
623    
624          // Get information about file          /* Get information about file */
625          if (fstat(handle, &filestat) != 0)          if (fstat(handle, &filestat) != 0)
626          {          {
627                  perror("stat");                  perror("stat");
# Line 488  disk_query_information(HANDLE handle, ui Line 629  disk_query_information(HANDLE handle, ui
629                  return STATUS_ACCESS_DENIED;                  return STATUS_ACCESS_DENIED;
630          }          }
631    
632          // Set file attributes          /* Set file attributes */
633          file_attributes = 0;          file_attributes = 0;
634          if (S_ISDIR(filestat.st_mode))          if (S_ISDIR(filestat.st_mode))
635                  file_attributes |= FILE_ATTRIBUTE_DIRECTORY;                  file_attributes |= FILE_ATTRIBUTE_DIRECTORY;
# Line 503  disk_query_information(HANDLE handle, ui Line 644  disk_query_information(HANDLE handle, ui
644          if (!(filestat.st_mode & S_IWUSR))          if (!(filestat.st_mode & S_IWUSR))
645                  file_attributes |= FILE_ATTRIBUTE_READONLY;                  file_attributes |= FILE_ATTRIBUTE_READONLY;
646    
647          // Return requested data          /* Return requested data */
648          switch (info_class)          switch (info_class)
649          {          {
650                  case 4: /* FileBasicInformation */                  case FileBasicInformation:
651                          seconds_since_1970_to_filetime(get_create_time(&filestat), &ft_high,                          seconds_since_1970_to_filetime(get_create_time(&filestat), &ft_high,
652                                                         &ft_low);                                                         &ft_low);
653                          out_uint32_le(out, ft_low);     //create_access_time                          out_uint32_le(out, ft_low);     /* create_access_time */
654                          out_uint32_le(out, ft_high);                          out_uint32_le(out, ft_high);
655    
656                          seconds_since_1970_to_filetime(filestat.st_atime, &ft_high, &ft_low);                          seconds_since_1970_to_filetime(filestat.st_atime, &ft_high, &ft_low);
657                          out_uint32_le(out, ft_low);     //last_access_time                          out_uint32_le(out, ft_low);     /* last_access_time */
658                          out_uint32_le(out, ft_high);                          out_uint32_le(out, ft_high);
659    
660                          seconds_since_1970_to_filetime(filestat.st_mtime, &ft_high, &ft_low);                          seconds_since_1970_to_filetime(filestat.st_mtime, &ft_high, &ft_low);
661                          out_uint32_le(out, ft_low);     //last_write_time                          out_uint32_le(out, ft_low);     /* last_write_time */
662                          out_uint32_le(out, ft_high);                          out_uint32_le(out, ft_high);
663    
664                          seconds_since_1970_to_filetime(filestat.st_ctime, &ft_high, &ft_low);                          seconds_since_1970_to_filetime(filestat.st_ctime, &ft_high, &ft_low);
665                          out_uint32_le(out, ft_low);     //last_change_time                          out_uint32_le(out, ft_low);     /* last_change_time */
666                          out_uint32_le(out, ft_high);                          out_uint32_le(out, ft_high);
667    
668                          out_uint32_le(out, file_attributes);                          out_uint32_le(out, file_attributes);
669                          break;                          break;
670    
671                  case 5: /* FileStandardInformation */                  case FileStandardInformation:
672    
673                          out_uint32_le(out, filestat.st_size);   //Allocation size                          out_uint32_le(out, filestat.st_size);   /* Allocation size */
674                          out_uint32_le(out, 0);                          out_uint32_le(out, 0);
675                          out_uint32_le(out, filestat.st_size);   //End of file                          out_uint32_le(out, filestat.st_size);   /* End of file */
676                          out_uint32_le(out, 0);                          out_uint32_le(out, 0);
677                          out_uint32_le(out, filestat.st_nlink);  //Number of links                          out_uint32_le(out, filestat.st_nlink);  /* Number of links */
678                          out_uint8(out, 0);      //Delete pending                          out_uint8(out, 0);      /* Delete pending */
679                          out_uint8(out, S_ISDIR(filestat.st_mode) ? 1 : 0);      //Directory                          out_uint8(out, S_ISDIR(filestat.st_mode) ? 1 : 0);      /* Directory */
680                          break;                          break;
681    
682                  case 35:        /* FileObjectIdInformation */                  case FileObjectIdInformation:
683    
684                          out_uint32_le(out, file_attributes);    /* File Attributes */                          out_uint32_le(out, file_attributes);    /* File Attributes */
685                          out_uint32_le(out, 0);  /* Reparse Tag */                          out_uint32_le(out, 0);  /* Reparse Tag */
# Line 553  disk_query_information(HANDLE handle, ui Line 694  disk_query_information(HANDLE handle, ui
694  }  }
695    
696  NTSTATUS  NTSTATUS
697  disk_set_information(HANDLE handle, uint32 info_class, STREAM in, STREAM out)  disk_set_information(NTHANDLE handle, uint32 info_class, STREAM in, STREAM out)
698  {  {
699          uint32 device_id, length, file_attributes, ft_high, ft_low;          uint32 length, file_attributes, ft_high, ft_low, delete_on_close;
700          char newname[256], fullpath[256];          char newname[256], fullpath[256];
701          struct fileinfo *pfinfo;          struct fileinfo *pfinfo;
   
702          int mode;          int mode;
703          struct stat filestat;          struct stat filestat;
704          time_t write_time, change_time, access_time, mod_time;          time_t write_time, change_time, access_time, mod_time;
# Line 566  disk_set_information(HANDLE handle, uint Line 706  disk_set_information(HANDLE handle, uint
706          struct STATFS_T stat_fs;          struct STATFS_T stat_fs;
707    
708          pfinfo = &(g_fileinfo[handle]);          pfinfo = &(g_fileinfo[handle]);
709            g_notify_stamp = True;
710    
711          switch (info_class)          switch (info_class)
712          {          {
713                  case 4: /* FileBasicInformation */                  case FileBasicInformation:
714                          write_time = change_time = access_time = 0;                          write_time = change_time = access_time = 0;
715    
716                          in_uint8s(in, 4);       /* Handle of root dir? */                          in_uint8s(in, 4);       /* Handle of root dir? */
717                          in_uint8s(in, 24);      /* unknown */                          in_uint8s(in, 24);      /* unknown */
718    
719                          // CreationTime                          /* CreationTime */
720                          in_uint32_le(in, ft_low);                          in_uint32_le(in, ft_low);
721                          in_uint32_le(in, ft_high);                          in_uint32_le(in, ft_high);
722    
723                          // AccessTime                          /* AccessTime */
724                          in_uint32_le(in, ft_low);                          in_uint32_le(in, ft_low);
725                          in_uint32_le(in, ft_high);                          in_uint32_le(in, ft_high);
726                          if (ft_low || ft_high)                          if (ft_low || ft_high)
727                                  access_time = convert_1970_to_filetime(ft_high, ft_low);                                  access_time = convert_1970_to_filetime(ft_high, ft_low);
728    
729                          // WriteTime                          /* WriteTime */
730                          in_uint32_le(in, ft_low);                          in_uint32_le(in, ft_low);
731                          in_uint32_le(in, ft_high);                          in_uint32_le(in, ft_high);
732                          if (ft_low || ft_high)                          if (ft_low || ft_high)
733                                  write_time = convert_1970_to_filetime(ft_high, ft_low);                                  write_time = convert_1970_to_filetime(ft_high, ft_low);
734    
735                          // ChangeTime                          /* ChangeTime */
736                          in_uint32_le(in, ft_low);                          in_uint32_le(in, ft_low);
737                          in_uint32_le(in, ft_high);                          in_uint32_le(in, ft_high);
738                          if (ft_low || ft_high)                          if (ft_low || ft_high)
# Line 625  disk_set_information(HANDLE handle, uint Line 766  disk_set_information(HANDLE handle, uint
766                                  printf("FileBasicInformation modification time %s",                                  printf("FileBasicInformation modification time %s",
767                                         ctime(&tvs.modtime));                                         ctime(&tvs.modtime));
768  #endif  #endif
769                                  if (utime(pfinfo->path, &tvs))                                  if (utime(pfinfo->path, &tvs) && errno != EPERM)
770                                          return STATUS_ACCESS_DENIED;                                          return STATUS_ACCESS_DENIED;
771                          }                          }
772    
773                          if (!file_attributes)                          if (!file_attributes)
774                                  break;  // not valid                                  break;  /* not valid */
775    
776                          mode = filestat.st_mode;                          mode = filestat.st_mode;
777    
# Line 649  disk_set_information(HANDLE handle, uint Line 790  disk_set_information(HANDLE handle, uint
790    
791                          break;                          break;
792    
793                  case 10:        /* FileRenameInformation */                  case FileRenameInformation:
794    
795                          in_uint8s(in, 4);       /* Handle of root dir? */                          in_uint8s(in, 4);       /* Handle of root dir? */
796                          in_uint8s(in, 0x1a);    /* unknown */                          in_uint8s(in, 0x1a);    /* unknown */
# Line 675  disk_set_information(HANDLE handle, uint Line 816  disk_set_information(HANDLE handle, uint
816                          }                          }
817                          break;                          break;
818    
819                  case 13:        /* FileDispositionInformation */                  case FileDispositionInformation:
820                            /* As far as I understand it, the correct
821                          //unimpl("IRP Set File Information class: FileDispositionInformation\n");                             thing to do here is to *schedule* a delete,
822                               so it will be deleted when the file is
823                          //in_uint32_le(in, delete_on_close);                             closed. Subsequent
824                          // disk_close(handle);                             FileDispositionInformation requests with
825                          if ((pfinfo->flags_and_attributes & FILE_DIRECTORY_FILE))       // remove a directory                             DeleteFile set to FALSE should unschedule
826                               the delete. See
827                               http://www.osronline.com/article.cfm?article=245. */
828    
829                            in_uint32_le(in, delete_on_close);
830    
831                            if (delete_on_close ||
832                                (pfinfo->
833                                 accessmask & (FILE_DELETE_ON_CLOSE | FILE_COMPLETE_IF_OPLOCKED)))
834                          {                          {
835                                  if (rmdir(pfinfo->path) < 0)                                  pfinfo->delete_on_close = True;
                                         return STATUS_ACCESS_DENIED;  
836                          }                          }
                         else if (unlink(pfinfo->path) < 0)      // unlink a file  
                                 return STATUS_ACCESS_DENIED;  
837    
838                          break;                          break;
839    
840                  case 19:        /* FileAllocationInformation */                  case FileAllocationInformation:
841                            /* Fall through to FileEndOfFileInformation,
842                          unimpl("IRP Set File Information class: FileAllocationInformation\n");                             which uses ftrunc. This is like Samba with
843                          break;                             "strict allocation = false", and means that
844                               we won't detect out-of-quota errors, for
845                               example. */
846    
847                  case 20:        /* FileEndOfFileInformation */                  case FileEndOfFileInformation:
848                          in_uint8s(in, 28);      /* unknown */                          in_uint8s(in, 28);      /* unknown */
849                          in_uint32_le(in, length);       /* file size */                          in_uint32_le(in, length);       /* file size */
850    
851                          /* prevents start of writing if not enough space left on device */                          /* prevents start of writing if not enough space left on device */
852                          if (STATFS_FN(g_rdpdr_device[pfinfo->device_id].local_path, &stat_fs) == 0)                          if (STATFS_FN(g_rdpdr_device[pfinfo->device_id].local_path, &stat_fs) == 0)
853                                  if (stat_fs.f_bsize * stat_fs.f_bfree < length)                                  if (stat_fs.f_bfree * stat_fs.f_bsize < length)
854                                          return STATUS_DISK_FULL;                                          return STATUS_DISK_FULL;
855    
856                          //printf("FileEndOfFileInformation length = %d\n", length);                          if (ftruncate_growable(handle, length) != 0)
857                          // ????????????                          {
858                          //unimpl("IRP Set File Information class: FileEndOfFileInformation\n");                                  return STATUS_DISK_FULL;
859                            }
860    
861                          break;                          break;
862                  default:                  default:
863    
# Line 717  disk_set_information(HANDLE handle, uint Line 867  disk_set_information(HANDLE handle, uint
867          return STATUS_SUCCESS;          return STATUS_SUCCESS;
868  }  }
869    
870  FsInfoType *  NTSTATUS
871    disk_check_notify(NTHANDLE handle)
872    {
873            struct fileinfo *pfinfo;
874            NTSTATUS status = STATUS_PENDING;
875    
876            NOTIFY notify;
877    
878            pfinfo = &(g_fileinfo[handle]);
879            if (!pfinfo->pdir)
880                    return STATUS_INVALID_DEVICE_REQUEST;
881    
882    
883    
884            status = NotifyInfo(handle, pfinfo->info_class, &notify);
885    
886            if (status != STATUS_PENDING)
887                    return status;
888    
889            if (memcmp(&pfinfo->notify, &notify, sizeof(NOTIFY)))
890            {
891                    /*printf("disk_check_notify found changed event\n"); */
892                    memcpy(&pfinfo->notify, &notify, sizeof(NOTIFY));
893                    status = STATUS_NOTIFY_ENUM_DIR;
894            }
895    
896            return status;
897    
898    
899    }
900    
901    NTSTATUS
902    disk_create_notify(NTHANDLE handle, uint32 info_class)
903    {
904    
905            struct fileinfo *pfinfo;
906            NTSTATUS ret = STATUS_PENDING;
907    
908            /* printf("start disk_create_notify info_class %X\n", info_class); */
909    
910            pfinfo = &(g_fileinfo[handle]);
911            pfinfo->info_class = info_class;
912    
913            ret = NotifyInfo(handle, info_class, &pfinfo->notify);
914    
915            if (info_class & 0x1000)
916            {                       /* ???? */
917                    if (ret == STATUS_PENDING)
918                            return STATUS_SUCCESS;
919            }
920    
921            /* printf("disk_create_notify: num_entries %d\n", pfinfo->notify.num_entries); */
922    
923    
924            return ret;
925    
926    }
927    
928    static NTSTATUS
929    NotifyInfo(NTHANDLE handle, uint32 info_class, NOTIFY * p)
930    {
931            struct fileinfo *pfinfo;
932            struct stat buf;
933            struct dirent *dp;
934            char *fullname;
935            DIR *dpr;
936    
937            pfinfo = &(g_fileinfo[handle]);
938            if (fstat(handle, &buf) < 0)
939            {
940                    perror("NotifyInfo");
941                    return STATUS_ACCESS_DENIED;
942            }
943            p->modify_time = buf.st_mtime;
944            p->status_time = buf.st_ctime;
945            p->num_entries = 0;
946            p->total_time = 0;
947    
948    
949            dpr = opendir(pfinfo->path);
950            if (!dpr)
951            {
952                    perror("NotifyInfo");
953                    return STATUS_ACCESS_DENIED;
954            }
955    
956    
957            while ((dp = readdir(dpr)))
958            {
959                    if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, ".."))
960                            continue;
961                    p->num_entries++;
962                    fullname = xmalloc(strlen(pfinfo->path) + strlen(dp->d_name) + 2);
963                    sprintf(fullname, "%s/%s", pfinfo->path, dp->d_name);
964    
965                    if (!stat(fullname, &buf))
966                    {
967                            p->total_time += (buf.st_mtime + buf.st_ctime);
968                    }
969    
970                    xfree(fullname);
971            }
972            closedir(dpr);
973    
974            return STATUS_PENDING;
975    }
976    
977    static FsInfoType *
978  FsVolumeInfo(char *fpath)  FsVolumeInfo(char *fpath)
979  {  {
980    
981  #ifdef HAVE_MNTENT_H          static FsInfoType info;
982    #ifdef USE_SETMNTENT
983          FILE *fdfs;          FILE *fdfs;
984          struct mntent *e;          struct mntent *e;
985          static FsInfoType info;  #endif
986    
987          /* initialize */          /* initialize */
988          memset(&info, 0, sizeof(info));          memset(&info, 0, sizeof(info));
989          strcpy(info.label, "RDESKTOP");          strcpy(info.label, "RDESKTOP");
990          strcpy(info.type, "RDPFS");          strcpy(info.type, "RDPFS");
991    
992    #ifdef USE_SETMNTENT
993          fdfs = setmntent(MNTENT_PATH, "r");          fdfs = setmntent(MNTENT_PATH, "r");
994          if (!fdfs)          if (!fdfs)
995                  return &info;                  return &info;
# Line 764  FsVolumeInfo(char *fpath) Line 1023  FsVolumeInfo(char *fpath)
1023                                                  read(fd, buf, sizeof(buf));                                                  read(fd, buf, sizeof(buf));
1024                                                  strncpy(info.label, buf + 41, 32);                                                  strncpy(info.label, buf + 41, 32);
1025                                                  info.label[32] = '\0';                                                  info.label[32] = '\0';
1026                                                  //info.Serial = (buf[128]<<24)+(buf[127]<<16)+(buf[126]<<8)+buf[125];                                                  /* info.Serial = (buf[128]<<24)+(buf[127]<<16)+(buf[126]<<8)+buf[125]; */
1027                                          }                                          }
1028                                          close(fd);                                          close(fd);
1029                                  }                                  }
# Line 773  FsVolumeInfo(char *fpath) Line 1032  FsVolumeInfo(char *fpath)
1032          }          }
1033          endmntent(fdfs);          endmntent(fdfs);
1034  #else  #else
         static FsInfoType info;  
   
1035          /* initialize */          /* initialize */
1036          memset(&info, 0, sizeof(info));          memset(&info, 0, sizeof(info));
1037          strcpy(info.label, "RDESKTOP");          strcpy(info.label, "RDESKTOP");
# Line 786  FsVolumeInfo(char *fpath) Line 1043  FsVolumeInfo(char *fpath)
1043    
1044    
1045  NTSTATUS  NTSTATUS
1046  disk_query_volume_information(HANDLE handle, uint32 info_class, STREAM out)  disk_query_volume_information(NTHANDLE handle, uint32 info_class, STREAM out)
1047  {  {
1048          struct STATFS_T stat_fs;          struct STATFS_T stat_fs;
1049          struct fileinfo *pfinfo;          struct fileinfo *pfinfo;
# Line 804  disk_query_volume_information(HANDLE han Line 1061  disk_query_volume_information(HANDLE han
1061    
1062          switch (info_class)          switch (info_class)
1063          {          {
1064                  case 1: /* FileFsVolumeInformation */                  case FileFsVolumeInformation:
1065    
1066                          out_uint32_le(out, 0);  /* volume creation time low */                          out_uint32_le(out, 0);  /* volume creation time low */
1067                          out_uint32_le(out, 0);  /* volume creation time high */                          out_uint32_le(out, 0);  /* volume creation time high */
# Line 816  disk_query_volume_information(HANDLE han Line 1073  disk_query_volume_information(HANDLE han
1073                          rdp_out_unistr(out, fsinfo->label, 2 * strlen(fsinfo->label) - 2);                          rdp_out_unistr(out, fsinfo->label, 2 * strlen(fsinfo->label) - 2);
1074                          break;                          break;
1075    
1076                  case 3: /* FileFsSizeInformation */                  case FileFsSizeInformation:
1077    
1078                          out_uint32_le(out, stat_fs.f_blocks);   /* Total allocation units low */                          out_uint32_le(out, stat_fs.f_blocks);   /* Total allocation units low */
1079                          out_uint32_le(out, 0);  /* Total allocation high units */                          out_uint32_le(out, 0);  /* Total allocation high units */
# Line 826  disk_query_volume_information(HANDLE han Line 1083  disk_query_volume_information(HANDLE han
1083                          out_uint32_le(out, 0x200);      /* Bytes per sector */                          out_uint32_le(out, 0x200);      /* Bytes per sector */
1084                          break;                          break;
1085    
1086                  case 5: /* FileFsAttributeInformation */                  case FileFsAttributeInformation:
1087    
1088                          out_uint32_le(out, FS_CASE_SENSITIVE | FS_CASE_IS_PRESERVED);   /* fs attributes */                          out_uint32_le(out, FS_CASE_SENSITIVE | FS_CASE_IS_PRESERVED);   /* fs attributes */
1089                          out_uint32_le(out, F_NAMELEN(stat_fs)); /* max length of filename */                          out_uint32_le(out, F_NAMELEN(stat_fs)); /* max length of filename */
# Line 835  disk_query_volume_information(HANDLE han Line 1092  disk_query_volume_information(HANDLE han
1092                          rdp_out_unistr(out, fsinfo->type, 2 * strlen(fsinfo->type) - 2);                          rdp_out_unistr(out, fsinfo->type, 2 * strlen(fsinfo->type) - 2);
1093                          break;                          break;
1094    
1095                  case 2: /* FileFsLabelInformation */                  case FileFsLabelInformation:
1096                  case 4: /* FileFsDeviceInformation */                  case FileFsDeviceInformation:
1097                  case 6: /* FileFsControlInformation */                  case FileFsControlInformation:
1098                  case 7: /* FileFsFullSizeInformation */                  case FileFsFullSizeInformation:
1099                  case 8: /* FileFsObjectIdInformation */                  case FileFsObjectIdInformation:
1100                  case 9: /* FileFsMaximumInformation */                  case FileFsMaximumInformation:
1101    
1102                  default:                  default:
1103    
1104                          unimpl("IRP Query Volume Information class: 0x%x\n", info_class);                          unimpl("IRP Query Volume Information class: 0x%x\n", info_class);
# Line 850  disk_query_volume_information(HANDLE han Line 1108  disk_query_volume_information(HANDLE han
1108  }  }
1109    
1110  NTSTATUS  NTSTATUS
1111  disk_query_directory(HANDLE handle, uint32 info_class, char *pattern, STREAM out)  disk_query_directory(NTHANDLE handle, uint32 info_class, char *pattern, STREAM out)
1112  {  {
1113          uint32 file_attributes, ft_low, ft_high;          uint32 file_attributes, ft_low, ft_high;
1114          char *dirname, fullpath[256];          char *dirname, fullpath[256];
# Line 866  disk_query_directory(HANDLE handle, uint Line 1124  disk_query_directory(HANDLE handle, uint
1124    
1125          switch (info_class)          switch (info_class)
1126          {          {
1127                  case 3: //FIXME: Why 3?                  case FileBothDirectoryInformation:
1128    
1129                          // If a search pattern is received, remember this pattern, and restart search                          /* If a search pattern is received, remember this pattern, and restart search */
1130                          if (pattern[0] != 0)                          if (pattern[0] != 0)
1131                          {                          {
1132                                  strncpy(pfinfo->pattern, 1 + strrchr(pattern, '/'), 64);                                  strncpy(pfinfo->pattern, 1 + strrchr(pattern, '/'), 64);
1133                                  rewinddir(pdir);                                  rewinddir(pdir);
1134                          }                          }
1135    
1136                          // find next dirent matching pattern                          /* find next dirent matching pattern */
1137                          pdirent = readdir(pdir);                          pdirent = readdir(pdir);
1138                          while (pdirent && fnmatch(pfinfo->pattern, pdirent->d_name, 0) != 0)                          while (pdirent && fnmatch(pfinfo->pattern, pdirent->d_name, 0) != 0)
1139                                  pdirent = readdir(pdir);                                  pdirent = readdir(pdir);
# Line 883  disk_query_directory(HANDLE handle, uint Line 1141  disk_query_directory(HANDLE handle, uint
1141                          if (pdirent == NULL)                          if (pdirent == NULL)
1142                                  return STATUS_NO_MORE_FILES;                                  return STATUS_NO_MORE_FILES;
1143    
1144                          // Get information for directory entry                          /* Get information for directory entry */
1145                          sprintf(fullpath, "%s/%s", dirname, pdirent->d_name);                          sprintf(fullpath, "%s/%s", dirname, pdirent->d_name);
1146    
                         /* JIF  
                            printf("Stat: %s\n", fullpath); */  
1147                          if (stat(fullpath, &fstat))                          if (stat(fullpath, &fstat))
1148                          {                          {
1149                                  perror("stat");                                  switch (errno)
1150                                  out_uint8(out, 0);                                  {
1151                                  return STATUS_ACCESS_DENIED;                                          case ENOENT:
1152                                            case ELOOP:
1153                                            case EACCES:
1154                                                    /* These are non-fatal errors. */
1155                                                    memset(&fstat, 0, sizeof(fstat));
1156                                                    break;
1157                                            default:
1158                                                    /* Fatal error. By returning STATUS_NO_SUCH_FILE,
1159                                                       the directory list operation will be aborted */
1160                                                    perror(fullpath);
1161                                                    out_uint8(out, 0);
1162                                                    return STATUS_NO_SUCH_FILE;
1163                                    }
1164                          }                          }
1165    
1166                          if (S_ISDIR(fstat.st_mode))                          if (S_ISDIR(fstat.st_mode))
# Line 904  disk_query_directory(HANDLE handle, uint Line 1172  disk_query_directory(HANDLE handle, uint
1172                          if (!(fstat.st_mode & S_IWUSR))                          if (!(fstat.st_mode & S_IWUSR))
1173                                  file_attributes |= FILE_ATTRIBUTE_READONLY;                                  file_attributes |= FILE_ATTRIBUTE_READONLY;
1174    
1175                          // Return requested information                          /* Return requested information */
1176                          out_uint8s(out, 8);     //unknown zero                          out_uint8s(out, 8);     /* unknown zero */
1177    
1178                          seconds_since_1970_to_filetime(get_create_time(&fstat), &ft_high, &ft_low);                          seconds_since_1970_to_filetime(get_create_time(&fstat), &ft_high, &ft_low);
1179                          out_uint32_le(out, ft_low);     // create time                          out_uint32_le(out, ft_low);     /* create time */
1180                          out_uint32_le(out, ft_high);                          out_uint32_le(out, ft_high);
1181    
1182                          seconds_since_1970_to_filetime(fstat.st_atime, &ft_high, &ft_low);                          seconds_since_1970_to_filetime(fstat.st_atime, &ft_high, &ft_low);
1183                          out_uint32_le(out, ft_low);     //last_access_time                          out_uint32_le(out, ft_low);     /* last_access_time */
1184                          out_uint32_le(out, ft_high);                          out_uint32_le(out, ft_high);
1185    
1186                          seconds_since_1970_to_filetime(fstat.st_mtime, &ft_high, &ft_low);                          seconds_since_1970_to_filetime(fstat.st_mtime, &ft_high, &ft_low);
1187                          out_uint32_le(out, ft_low);     //last_write_time                          out_uint32_le(out, ft_low);     /* last_write_time */
1188                          out_uint32_le(out, ft_high);                          out_uint32_le(out, ft_high);
1189    
1190                          seconds_since_1970_to_filetime(fstat.st_ctime, &ft_high, &ft_low);                          seconds_since_1970_to_filetime(fstat.st_ctime, &ft_high, &ft_low);
1191                          out_uint32_le(out, ft_low);     //change_write_time                          out_uint32_le(out, ft_low);     /* change_write_time */
1192                          out_uint32_le(out, ft_high);                          out_uint32_le(out, ft_high);
1193    
1194                          out_uint32_le(out, fstat.st_size);      //filesize low                          out_uint32_le(out, fstat.st_size);      /* filesize low */
1195                          out_uint32_le(out, 0);  //filesize high                          out_uint32_le(out, 0);  /* filesize high */
1196                          out_uint32_le(out, fstat.st_size);      //filesize low                          out_uint32_le(out, fstat.st_size);      /* filesize low */
1197                          out_uint32_le(out, 0);  //filesize high                          out_uint32_le(out, 0);  /* filesize high */
1198                          out_uint32_le(out, file_attributes);                          out_uint32_le(out, file_attributes);
1199                          out_uint8(out, 2 * strlen(pdirent->d_name) + 2);        //unicode length                          out_uint8(out, 2 * strlen(pdirent->d_name) + 2);        /* unicode length */
1200                          out_uint8s(out, 7);     //pad?                          out_uint8s(out, 7);     /* pad? */
1201                          out_uint8(out, 0);      //8.3 file length                          out_uint8(out, 0);      /* 8.3 file length */
1202                          out_uint8s(out, 2 * 12);        //8.3 unicode length                          out_uint8s(out, 2 * 12);        /* 8.3 unicode length */
1203                          rdp_out_unistr(out, pdirent->d_name, 2 * strlen(pdirent->d_name));                          rdp_out_unistr(out, pdirent->d_name, 2 * strlen(pdirent->d_name));
1204                          break;                          break;
1205    
1206                  default:                  default:
1207                            /* FIXME: Support FileDirectoryInformation,
1208                               FileFullDirectoryInformation, and
1209                               FileNamesInformation */
1210    
1211                          unimpl("IRP Query Directory sub: 0x%x\n", info_class);                          unimpl("IRP Query Directory sub: 0x%x\n", info_class);
1212                          return STATUS_INVALID_PARAMETER;                          return STATUS_INVALID_PARAMETER;
# Line 947  disk_query_directory(HANDLE handle, uint Line 1218  disk_query_directory(HANDLE handle, uint
1218    
1219    
1220  static NTSTATUS  static NTSTATUS
1221  disk_device_control(HANDLE handle, uint32 request, STREAM in, STREAM out)  disk_device_control(NTHANDLE handle, uint32 request, STREAM in, STREAM out)
1222  {  {
         uint32 result;  
   
1223          if (((request >> 16) != 20) || ((request >> 16) != 9))          if (((request >> 16) != 20) || ((request >> 16) != 9))
1224                  return STATUS_INVALID_PARAMETER;                  return STATUS_INVALID_PARAMETER;
1225    
# Line 962  disk_device_control(HANDLE handle, uint3 Line 1231  disk_device_control(HANDLE handle, uint3
1231    
1232          switch (request)          switch (request)
1233          {          {
1234                  case 25:        // ?                  case 25:        /* ? */
1235                  case 42:        // ?                  case 42:        /* ? */
1236                  default:                  default:
1237                          unimpl("DISK IOCTL %d\n", request);                          unimpl("DISK IOCTL %d\n", request);
1238                          return STATUS_INVALID_PARAMETER;                          return STATUS_INVALID_PARAMETER;

Legend:
Removed from v.616  
changed lines
  Added in v.879

  ViewVC Help
Powered by ViewVC 1.1.26