/[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 574 by stargo, Wed Jan 21 23:53:55 2004 UTC revision 807 by stargo, Thu Dec 23 20:43:47 2004 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_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_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  
   
 #ifdef SOLARIS  
 #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 82  Line 28 
28  #include <fnmatch.h>  #include <fnmatch.h>
29  #include <errno.h>              /* errno */  #include <errno.h>              /* errno */
30    
31  #if defined(SOLARIS)  #include <utime.h>
32    #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    /* TODO: let autoconf figure out everything below... */
41    #if (defined(sun) && (defined(__svr4__) || defined(__SVR4)))
42    #define SOLARIS
43    #endif
44    
45    #if (defined(SOLARIS) || defined (__hpux) || defined(__BEOS__))
46  #include <sys/statvfs.h>        /* solaris statvfs */  #include <sys/statvfs.h>        /* solaris statvfs */
47    /* TODO: Fix mntent-handling for solaris/hpux
48     * #include <sys/mntent.h> */
49    #undef HAVE_MNTENT_H
50    #define MNTENT_PATH "/etc/mnttab"
51  #define STATFS_FN(path, buf) (statvfs(path,buf))  #define STATFS_FN(path, buf) (statvfs(path,buf))
52  #define STATFS_T statvfs  #define STATFS_T statvfs
53  #define F_NAMELEN(buf) ((buf).f_namemax)  #define F_NAMELEN(buf) ((buf).f_namemax)
54    
55  #elif defined(__OpenBSD__)  #elif (defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__APPLE__))
56  #include <sys/param.h>  #include <sys/param.h>
57  #include <sys/mount.h>  #include <sys/mount.h>
58  #define STATFS_FN(path, buf) (statfs(path,buf))  #define STATFS_FN(path, buf) (statfs(path,buf))
59  #define STATFS_T statfs  #define STATFS_T statfs
60  #define F_NAMELEN(buf) (NAME_MAX)  #define F_NAMELEN(buf) (NAME_MAX)
61    
62    #elif (defined(__SGI_IRIX__))
63    #include <sys/types.h>
64    #include <sys/statvfs.h>
65    #define STATFS_FN(path, buf) (statvfs(path,buf))
66    #define STATFS_T statvfs
67    #define F_NAMELEN(buf) ((buf).f_namemax)
68    
69    #elif (defined(__alpha) && !defined(linux))
70    #include <sys/mount.h>                /* osf1 statfs */
71    #define STATFS_FN(path, buf) (statfs(path,buf,sizeof(buf)))
72    #define STATFS_T statfs
73    #define F_NAMELEN(buf) (255)
74    
75  #else  #else
76  #include <sys/vfs.h>            /* linux statfs */  #include <sys/vfs.h>            /* linux statfs */
77    #include <mntent.h>
78    #define HAVE_MNTENT_H
79    #define MNTENT_PATH "/etc/mtab"
80  #define STATFS_FN(path, buf) (statfs(path,buf))  #define STATFS_FN(path, buf) (statfs(path,buf))
81  #define STATFS_T statfs  #define STATFS_T statfs
82  #define F_NAMELEN(buf) ((buf).f_namelen)  #define F_NAMELEN(buf) ((buf).f_namelen)
# Line 106  Line 86 
86    
87  extern RDPDR_DEVICE g_rdpdr_device[];  extern RDPDR_DEVICE g_rdpdr_device[];
88    
89  struct fileinfo  FILEINFO g_fileinfo[MAX_OPEN_FILES];
90    BOOL g_notify_stamp = False;
91    
92    typedef struct
93  {  {
94          uint32 device_id, flags_and_attributes;          char name[256];
95          char path[256];          char label[256];
96          DIR *pdir;          unsigned long serial;
97          struct dirent *pdirent;          char type[256];
98          char pattern[64];  } FsInfoType;
99          BOOL delete_on_close;  
100    static NTSTATUS NotifyInfo(NTHANDLE handle, uint32 info_class, NOTIFY * p);
101    
102    static time_t
103    get_create_time(struct stat *st)
104    {
105            time_t ret, ret1;
106    
107            ret = MIN(st->st_ctime, st->st_mtime);
108            ret1 = MIN(ret, st->st_atime);
109    
110            if (ret1 != (time_t) 0)
111                    return ret1;
112    
113            return ret;
114  }  }
 g_fileinfo[MAX_OPEN_FILES];  
115    
116  /* Convert seconds since 1970 to a filetime */  /* Convert seconds since 1970 to a filetime */
117  void  static void
118  seconds_since_1970_to_filetime(time_t seconds, uint32 * high, uint32 * low)  seconds_since_1970_to_filetime(time_t seconds, uint32 * high, uint32 * low)
119  {  {
120          unsigned long long ticks;          unsigned long long ticks;
# Line 128  seconds_since_1970_to_filetime(time_t se Line 124  seconds_since_1970_to_filetime(time_t se
124          *high = (uint32) (ticks >> 32);          *high = (uint32) (ticks >> 32);
125  }  }
126    
127    /* Convert seconds since 1970 back to filetime */
128    static time_t
129    convert_1970_to_filetime(uint32 high, uint32 low)
130    {
131            unsigned long long ticks;
132            time_t val;
133    
134            ticks = low + (((unsigned long long) high) << 32);
135            ticks /= 10000000;
136            ticks -= 11644473600LL;
137    
138            val = (time_t) ticks;
139            return (val);
140    
141    }
142    
143    /* A wrapper for ftruncate which supports growing files, even if the
144       native ftruncate doesn't. This is needed on Linux FAT filesystems,
145       for example. */
146    static int
147    ftruncate_growable(int fd, off_t length)
148    {
149            int ret;
150            off_t pos;
151            static const char zero;
152    
153            /* Try the simple method first */
154            if ((ret = ftruncate(fd, length)) != -1)
155            {
156                    return ret;
157            }
158    
159            /*
160             * Some kind of error. Perhaps we were trying to grow. Retry
161             * in a safe way.
162             */
163    
164            /* Get current position */
165            if ((pos = lseek(fd, 0, SEEK_CUR)) == -1)
166            {
167                    perror("lseek");
168                    return -1;
169            }
170    
171            /* Seek to new size */
172            if (lseek(fd, length, SEEK_SET) == -1)
173            {
174                    perror("lseek");
175                    return -1;
176            }
177    
178            /* Write a zero */
179            if (write(fd, &zero, 1) == -1)
180            {
181                    perror("write");
182                    return -1;
183            }
184    
185            /* Truncate. This shouldn't fail. */
186            if (ftruncate(fd, length) == -1)
187            {
188                    perror("ftruncate");
189                    return -1;
190            }
191    
192            /* Restore position */
193            if (lseek(fd, pos, SEEK_SET) == -1)
194            {
195                    perror("lseek");
196                    return -1;
197            }
198    
199            return 0;
200    }
201    
202    /* Just like open(2), but if a open with O_EXCL fails, retry with
203       GUARDED semantics. This might be necessary because some filesystems
204       (such as NFS filesystems mounted from a unfsd server) doesn't
205       support O_EXCL. GUARDED semantics are subject to race conditions,
206       but we can live with that.
207    */
208    static int
209    open_weak_exclusive(const char *pathname, int flags, mode_t mode)
210    {
211            int ret;
212            struct stat statbuf;
213    
214            ret = open(pathname, flags, mode);
215            if (ret != -1 || !(flags & O_EXCL))
216            {
217                    /* Success, or not using O_EXCL */
218                    return ret;
219            }
220    
221            /* An error occured, and we are using O_EXCL. In case the FS
222               doesn't support O_EXCL, some kind of error will be
223               returned. Unfortunately, we don't know which one. Linux
224               2.6.8 seems to return 524, but I cannot find a documented
225               #define for this case. So, we'll return only on errors that
226               we know aren't related to O_EXCL. */
227            switch (errno)
228            {
229                    case EACCES:
230                    case EEXIST:
231                    case EINTR:
232                    case EISDIR:
233                    case ELOOP:
234                    case ENAMETOOLONG:
235                    case ENOENT:
236                    case ENOTDIR:
237                            return ret;
238            }
239    
240            /* Retry with GUARDED semantics */
241            if (stat(pathname, &statbuf) != -1)
242            {
243                    /* File exists */
244                    errno = EEXIST;
245                    return -1;
246            }
247            else
248            {
249                    return open(pathname, flags & ~O_EXCL, mode);
250            }
251    }
252    
253  /* Enumeration of devices from rdesktop.c        */  /* Enumeration of devices from rdesktop.c        */
254  /* returns numer of units found and initialized. */  /* returns numer of units found and initialized. */
255  /* optarg looks like ':h:=/mnt/floppy,b:=/mnt/usbdevice1' */  /* optarg looks like ':h=/mnt/floppy,b=/mnt/usbdevice1' */
256  /* when it arrives to this function.             */  /* when it arrives to this function.             */
257  int  int
258  disk_enum_devices(int *id, char *optarg)  disk_enum_devices(uint32 * id, char *optarg)
259  {  {
260          char *pos = optarg;          char *pos = optarg;
261          char *pos2;          char *pos2;
# Line 144  disk_enum_devices(int *id, char *optarg) Line 266  disk_enum_devices(int *id, char *optarg)
266          while ((pos = next_arg(optarg, ',')) && *id < RDPDR_MAX_DEVICES)          while ((pos = next_arg(optarg, ',')) && *id < RDPDR_MAX_DEVICES)
267          {          {
268                  pos2 = next_arg(optarg, '=');                  pos2 = next_arg(optarg, '=');
                 strcpy(g_rdpdr_device[*id].name, optarg);  
   
                 toupper_str(g_rdpdr_device[*id].name);  
269    
270                  /* add trailing colon to name. */                  strncpy(g_rdpdr_device[*id].name, optarg, sizeof(g_rdpdr_device[*id].name));
271                  strcat(g_rdpdr_device[*id].name, ":");                  if (strlen(optarg) > 8)
272                            fprintf(stderr, "share name %s truncated to %s\n", optarg,
273                                    g_rdpdr_device[*id].name);
274    
275                  g_rdpdr_device[*id].local_path = xmalloc(strlen(pos2) + 1);                  g_rdpdr_device[*id].local_path = xmalloc(strlen(pos2) + 1);
276                  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);  
277                  g_rdpdr_device[*id].device_type = DEVICE_TYPE_DISK;                  g_rdpdr_device[*id].device_type = DEVICE_TYPE_DISK;
278                  count++;                  count++;
279                  (*id)++;                  (*id)++;
# Line 163  disk_enum_devices(int *id, char *optarg) Line 283  disk_enum_devices(int *id, char *optarg)
283          return count;          return count;
284  }  }
285    
286  /* Opens of creates a file or directory */  /* Opens or creates a file or directory */
287  NTSTATUS  static NTSTATUS
288  disk_create(uint32 device_id, uint32 accessmask, uint32 sharemode, uint32 create_disposition,  disk_create(uint32 device_id, uint32 accessmask, uint32 sharemode, uint32 create_disposition,
289              uint32 flags_and_attributes, char *filename, HANDLE * phandle)              uint32 flags_and_attributes, char *filename, NTHANDLE * phandle)
290  {  {
291          HANDLE handle;          NTHANDLE handle;
292          DIR *dirp;          DIR *dirp;
293          int flags, mode;          int flags, mode;
294          char path[256];          char path[256];
295            struct stat filestat;
296    
297          handle = 0;          handle = 0;
298          dirp = NULL;          dirp = NULL;
299          flags = 0;          flags = 0;
300          mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;          mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
301    
302          if (filename[strlen(filename) - 1] == '/')          if (*filename && filename[strlen(filename) - 1] == '/')
303                  filename[strlen(filename) - 1] = 0;                  filename[strlen(filename) - 1] = 0;
304          sprintf(path, "%s%s", g_rdpdr_device[device_id].local_path, filename);          sprintf(path, "%s%s", g_rdpdr_device[device_id].local_path, filename);
         //printf("Open: %s\n", path);  
305    
306          switch (create_disposition)          switch (create_disposition)
307          {          {
# Line 216  disk_create(uint32 device_id, uint32 acc Line 336  disk_create(uint32 device_id, uint32 acc
336                          break;                          break;
337          }          }
338    
339            //printf("Open: \"%s\"  flags: %X, accessmask: %X sharemode: %X create disp: %X\n", path, flags_and_attributes, accessmask, sharemode, create_disposition);
340    
341            // Get information about file and set that flag ourselfs
342            if ((stat(path, &filestat) == 0) && (S_ISDIR(filestat.st_mode)))
343            {
344                    if (flags_and_attributes & FILE_NON_DIRECTORY_FILE)
345                            return STATUS_FILE_IS_A_DIRECTORY;
346                    else
347                            flags_and_attributes |= FILE_DIRECTORY_FILE;
348            }
349    
350          if (flags_and_attributes & FILE_DIRECTORY_FILE)          if (flags_and_attributes & FILE_DIRECTORY_FILE)
351          {          {
352                  if (flags & O_CREAT)                  if (flags & O_CREAT)
# Line 246  disk_create(uint32 device_id, uint32 acc Line 377  disk_create(uint32 device_id, uint32 acc
377          }          }
378          else          else
379          {          {
380    
381                  if (accessmask & GENERIC_ALL                  if (accessmask & GENERIC_ALL
382                      || (accessmask & GENERIC_READ && accessmask & GENERIC_WRITE))                      || (accessmask & GENERIC_READ && accessmask & GENERIC_WRITE))
383                  {                  {
# Line 260  disk_create(uint32 device_id, uint32 acc Line 392  disk_create(uint32 device_id, uint32 acc
392                          flags |= O_RDONLY;                          flags |= O_RDONLY;
393                  }                  }
394    
395                  handle = open(path, flags, mode);                  handle = open_weak_exclusive(path, flags, mode);
396                  if (handle == -1)                  if (handle == -1)
397                  {                  {
398                          switch (errno)                          switch (errno)
399                          {                          {
400                                    case EISDIR:
401    
402                                            return STATUS_FILE_IS_A_DIRECTORY;
403    
404                                  case EACCES:                                  case EACCES:
405    
406                                          return STATUS_ACCESS_DENIED;                                          return STATUS_ACCESS_DENIED;
# Line 272  disk_create(uint32 device_id, uint32 acc Line 408  disk_create(uint32 device_id, uint32 acc
408                                  case ENOENT:                                  case ENOENT:
409    
410                                          return STATUS_NO_SUCH_FILE;                                          return STATUS_NO_SUCH_FILE;
411                                    case EEXIST:
412    
413                                            return STATUS_OBJECT_NAME_COLLISION;
414                                  default:                                  default:
415    
416                                          perror("open");                                          perror("open");
417                                          return STATUS_NO_SUCH_FILE;                                          return STATUS_NO_SUCH_FILE;
418                          }                          }
419                  }                  }
420    
421                    /* all read and writes of files should be non blocking */
422                    if (fcntl(handle, F_SETFL, O_NONBLOCK) == -1)
423                            perror("fcntl");
424          }          }
425    
426          if (handle >= MAX_OPEN_FILES)          if (handle >= MAX_OPEN_FILES)
# Line 290  disk_create(uint32 device_id, uint32 acc Line 432  disk_create(uint32 device_id, uint32 acc
432    
433          if (dirp)          if (dirp)
434                  g_fileinfo[handle].pdir = dirp;                  g_fileinfo[handle].pdir = dirp;
435            else
436                    g_fileinfo[handle].pdir = NULL;
437    
438          g_fileinfo[handle].device_id = device_id;          g_fileinfo[handle].device_id = device_id;
439          g_fileinfo[handle].flags_and_attributes = flags_and_attributes;          g_fileinfo[handle].flags_and_attributes = flags_and_attributes;
440            g_fileinfo[handle].accessmask = accessmask;
441          strncpy(g_fileinfo[handle].path, path, 255);          strncpy(g_fileinfo[handle].path, path, 255);
442            g_fileinfo[handle].delete_on_close = False;
443            g_notify_stamp = True;
444    
445          *phandle = handle;          *phandle = handle;
446          return STATUS_SUCCESS;          return STATUS_SUCCESS;
447  }  }
448    
449  NTSTATUS  static NTSTATUS
450  disk_close(HANDLE handle)  disk_close(NTHANDLE handle)
451  {  {
452          struct fileinfo *pfinfo;          struct fileinfo *pfinfo;
453    
454          pfinfo = &(g_fileinfo[handle]);          pfinfo = &(g_fileinfo[handle]);
455    
456          if (pfinfo->flags_and_attributes & FILE_DIRECTORY_FILE)          g_notify_stamp = True;
457    
458            rdpdr_abort_io(handle, 0, STATUS_CANCELLED);
459    
460            if (pfinfo->pdir)
461          {          {
462                  closedir(pfinfo->pdir);                  if (closedir(pfinfo->pdir) < 0)
463                  //FIXME: Should check exit code                  {
464                            perror("closedir");
465                            return STATUS_INVALID_HANDLE;
466                    }
467    
468                    if (pfinfo->delete_on_close)
469                            if (rmdir(pfinfo->path) < 0)
470                            {
471                                    perror(pfinfo->path);
472                                    return STATUS_ACCESS_DENIED;
473                            }
474                    pfinfo->delete_on_close = False;
475          }          }
476          else          else
477          {          {
478                  close(handle);                  if (close(handle) < 0)
479                    {
480                            perror("close");
481                            return STATUS_INVALID_HANDLE;
482                    }
483                    if (pfinfo->delete_on_close)
484                            if (unlink(pfinfo->path) < 0)
485                            {
486                                    perror(pfinfo->path);
487                                    return STATUS_ACCESS_DENIED;
488                            }
489    
490                    pfinfo->delete_on_close = False;
491          }          }
492    
493          return STATUS_SUCCESS;          return STATUS_SUCCESS;
494  }  }
495    
496  NTSTATUS  static NTSTATUS
497  disk_read(HANDLE handle, uint8 * data, uint32 length, uint32 offset, uint32 * result)  disk_read(NTHANDLE handle, uint8 * data, uint32 length, uint32 offset, uint32 * result)
498  {  {
499          int n;          int n;
500    
501          if (offset)  #if 0
502                  lseek(handle, offset, SEEK_SET);          /* browsing dir ????        */
503            /* each request is 24 bytes */
504            if (g_fileinfo[handle].flags_and_attributes & FILE_DIRECTORY_FILE)
505            {
506                    *result = 0;
507                    return STATUS_SUCCESS;
508            }
509    #endif
510    
511            lseek(handle, offset, SEEK_SET);
512    
513          n = read(handle, data, length);          n = read(handle, data, length);
514    
515          if (n < 0)          if (n < 0)
516          {          {
                 perror("read");  
517                  *result = 0;                  *result = 0;
518                  return STATUS_INVALID_PARAMETER;                  switch (errno)
519                    {
520                            case EISDIR:
521                                    /* Implement 24 Byte directory read ??
522                                       with STATUS_NOT_IMPLEMENTED server doesn't read again */
523                                    /* return STATUS_FILE_IS_A_DIRECTORY; */
524                                    return STATUS_NOT_IMPLEMENTED;
525                            default:
526                                    perror("read");
527                                    return STATUS_INVALID_PARAMETER;
528                    }
529          }          }
530    
531          *result = n;          *result = n;
# Line 339  disk_read(HANDLE handle, uint8 * data, u Line 533  disk_read(HANDLE handle, uint8 * data, u
533          return STATUS_SUCCESS;          return STATUS_SUCCESS;
534  }  }
535    
536  NTSTATUS  static NTSTATUS
537  disk_write(HANDLE handle, uint8 * data, uint32 length, uint32 offset, uint32 * result)  disk_write(NTHANDLE handle, uint8 * data, uint32 length, uint32 offset, uint32 * result)
538  {  {
539          int n;          int n;
540    
541          if (offset)          lseek(handle, offset, SEEK_SET);
                 lseek(handle, offset, SEEK_SET);  
542    
543          n = write(handle, data, length);          n = write(handle, data, length);
544    
# Line 353  disk_write(HANDLE handle, uint8 * data, Line 546  disk_write(HANDLE handle, uint8 * data,
546          {          {
547                  perror("write");                  perror("write");
548                  *result = 0;                  *result = 0;
549                  return STATUS_ACCESS_DENIED;                  switch (errno)
550                    {
551                            case ENOSPC:
552                                    return STATUS_DISK_FULL;
553                            default:
554                                    return STATUS_ACCESS_DENIED;
555                    }
556          }          }
557    
558          *result = n;          *result = n;
# Line 362  disk_write(HANDLE handle, uint8 * data, Line 561  disk_write(HANDLE handle, uint8 * data,
561  }  }
562    
563  NTSTATUS  NTSTATUS
564  disk_query_information(HANDLE handle, uint32 info_class, STREAM out)  disk_query_information(NTHANDLE handle, uint32 info_class, STREAM out)
565  {  {
566          uint32 file_attributes, ft_high, ft_low;          uint32 file_attributes, ft_high, ft_low;
567          struct stat filestat;          struct stat filestat;
# Line 381  disk_query_information(HANDLE handle, ui Line 580  disk_query_information(HANDLE handle, ui
580          // Set file attributes          // Set file attributes
581          file_attributes = 0;          file_attributes = 0;
582          if (S_ISDIR(filestat.st_mode))          if (S_ISDIR(filestat.st_mode))
         {  
583                  file_attributes |= FILE_ATTRIBUTE_DIRECTORY;                  file_attributes |= FILE_ATTRIBUTE_DIRECTORY;
584          }  
585          filename = 1 + strrchr(path, '/');          filename = 1 + strrchr(path, '/');
586          if (filename && filename[0] == '.')          if (filename && filename[0] == '.')
         {  
587                  file_attributes |= FILE_ATTRIBUTE_HIDDEN;                  file_attributes |= FILE_ATTRIBUTE_HIDDEN;
588          }  
589            if (!file_attributes)
590                    file_attributes |= FILE_ATTRIBUTE_NORMAL;
591    
592            if (!(filestat.st_mode & S_IWUSR))
593                    file_attributes |= FILE_ATTRIBUTE_READONLY;
594    
595          // Return requested data          // Return requested data
596          switch (info_class)          switch (info_class)
597          {          {
598                  case 4: /* FileBasicInformation */                  case FileBasicInformation:
599                            seconds_since_1970_to_filetime(get_create_time(&filestat), &ft_high,
600                          out_uint8s(out, 8);     //create_time not available;                                                         &ft_low);
601                            out_uint32_le(out, ft_low);     //create_access_time
602                            out_uint32_le(out, ft_high);
603    
604                          seconds_since_1970_to_filetime(filestat.st_atime, &ft_high, &ft_low);                          seconds_since_1970_to_filetime(filestat.st_atime, &ft_high, &ft_low);
605                          out_uint32_le(out, ft_low);     //last_access_time                          out_uint32_le(out, ft_low);     //last_access_time
# Line 405  disk_query_information(HANDLE handle, ui Line 609  disk_query_information(HANDLE handle, ui
609                          out_uint32_le(out, ft_low);     //last_write_time                          out_uint32_le(out, ft_low);     //last_write_time
610                          out_uint32_le(out, ft_high);                          out_uint32_le(out, ft_high);
611    
612                          out_uint8s(out, 8);     //unknown zero                          seconds_since_1970_to_filetime(filestat.st_ctime, &ft_high, &ft_low);
613                            out_uint32_le(out, ft_low);     //last_change_time
614                            out_uint32_le(out, ft_high);
615    
616                          out_uint32_le(out, file_attributes);                          out_uint32_le(out, file_attributes);
617                          break;                          break;
618    
619                  case 5: /* FileStandardInformation */                  case FileStandardInformation:
620    
621                          out_uint32_le(out, filestat.st_size);   //Allocation size                          out_uint32_le(out, filestat.st_size);   //Allocation size
622                          out_uint32_le(out, 0);                          out_uint32_le(out, 0);
# Line 420  disk_query_information(HANDLE handle, ui Line 627  disk_query_information(HANDLE handle, ui
627                          out_uint8(out, S_ISDIR(filestat.st_mode) ? 1 : 0);      //Directory                          out_uint8(out, S_ISDIR(filestat.st_mode) ? 1 : 0);      //Directory
628                          break;                          break;
629    
630                  case 35:        /* FileObjectIdInformation */                  case FileObjectIdInformation:
631    
632                          out_uint32_le(out, file_attributes);    /* File Attributes */                          out_uint32_le(out, file_attributes);    /* File Attributes */
633                          out_uint32_le(out, 0);  /* Reparse Tag */                          out_uint32_le(out, 0);  /* Reparse Tag */
# Line 435  disk_query_information(HANDLE handle, ui Line 642  disk_query_information(HANDLE handle, ui
642  }  }
643    
644  NTSTATUS  NTSTATUS
645  disk_set_information(HANDLE handle, uint32 info_class, STREAM in, STREAM out)  disk_set_information(NTHANDLE handle, uint32 info_class, STREAM in, STREAM out)
646  {  {
647          uint32 device_id, length, file_attributes, ft_high, ft_low;          uint32 length, file_attributes, ft_high, ft_low, delete_on_close;
648          char newname[256], fullpath[256];          char newname[256], fullpath[256];
649          struct fileinfo *pfinfo;          struct fileinfo *pfinfo;
650            int mode;
651            struct stat filestat;
652            time_t write_time, change_time, access_time, mod_time;
653            struct utimbuf tvs;
654            struct STATFS_T stat_fs;
655    
656          pfinfo = &(g_fileinfo[handle]);          pfinfo = &(g_fileinfo[handle]);
657            g_notify_stamp = True;
658    
659          switch (info_class)          switch (info_class)
660          {          {
661                  case 4: /* FileBasicInformation */                  case FileBasicInformation:
662                            write_time = change_time = access_time = 0;
663    
664                            in_uint8s(in, 4);       /* Handle of root dir? */
665                            in_uint8s(in, 24);      /* unknown */
666    
667                            // CreationTime
668                            in_uint32_le(in, ft_low);
669                            in_uint32_le(in, ft_high);
670    
671                            // AccessTime
672                            in_uint32_le(in, ft_low);
673                            in_uint32_le(in, ft_high);
674                            if (ft_low || ft_high)
675                                    access_time = convert_1970_to_filetime(ft_high, ft_low);
676    
677                            // WriteTime
678                            in_uint32_le(in, ft_low);
679                            in_uint32_le(in, ft_high);
680                            if (ft_low || ft_high)
681                                    write_time = convert_1970_to_filetime(ft_high, ft_low);
682    
683                            // ChangeTime
684                            in_uint32_le(in, ft_low);
685                            in_uint32_le(in, ft_high);
686                            if (ft_low || ft_high)
687                                    change_time = convert_1970_to_filetime(ft_high, ft_low);
688    
689                            in_uint32_le(in, file_attributes);
690    
691                            if (fstat(handle, &filestat))
692                                    return STATUS_ACCESS_DENIED;
693    
694                            tvs.modtime = filestat.st_mtime;
695                            tvs.actime = filestat.st_atime;
696                            if (access_time)
697                                    tvs.actime = access_time;
698    
699    
700                            if (write_time || change_time)
701                                    mod_time = MIN(write_time, change_time);
702                            else
703                                    mod_time = write_time ? write_time : change_time;
704    
705                            if (mod_time)
706                                    tvs.modtime = mod_time;
707    
708    
709                            if (access_time || write_time || change_time)
710                            {
711    #if WITH_DEBUG_RDP5
712                                    printf("FileBasicInformation access       time %s",
713                                           ctime(&tvs.actime));
714                                    printf("FileBasicInformation modification time %s",
715                                           ctime(&tvs.modtime));
716    #endif
717                                    if (utime(pfinfo->path, &tvs) && errno != EPERM)
718                                            return STATUS_ACCESS_DENIED;
719                            }
720    
721                            if (!file_attributes)
722                                    break;  // not valid
723    
724                            mode = filestat.st_mode;
725    
726                            if (file_attributes & FILE_ATTRIBUTE_READONLY)
727                                    mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH);
728                            else
729                                    mode |= S_IWUSR;
730    
731                            mode &= 0777;
732    #if WITH_DEBUG_RDP5
733                            printf("FileBasicInformation set access mode 0%o", mode);
734    #endif
735    
736                            if (fchmod(handle, mode))
737                                    return STATUS_ACCESS_DENIED;
738    
                         // Probably safe to ignore  
739                          break;                          break;
740    
741                  case 10:        /* FileRenameInformation */                  case FileRenameInformation:
742    
743                          in_uint8s(in, 4);       /* Handle of root dir? */                          in_uint8s(in, 4);       /* Handle of root dir? */
744                          in_uint8s(in, 0x1a);    /* unknown */                          in_uint8s(in, 0x1a);    /* unknown */
# Line 476  disk_set_information(HANDLE handle, uint Line 764  disk_set_information(HANDLE handle, uint
764                          }                          }
765                          break;                          break;
766    
767                  case 13:        /* FileDispositionInformation */                  case FileDispositionInformation:
768                            /* As far as I understand it, the correct
769                               thing to do here is to *schedule* a delete,
770                               so it will be deleted when the file is
771                               closed. Subsequent
772                               FileDispositionInformation requests with
773                               DeleteFile set to FALSE should unschedule
774                               the delete. See
775                               http://www.osronline.com/article.cfm?article=245. */
776    
777                            in_uint32_le(in, delete_on_close);
778    
779                            if (delete_on_close ||
780                                (pfinfo->
781                                 accessmask & (FILE_DELETE_ON_CLOSE | FILE_COMPLETE_IF_OPLOCKED)))
782                            {
783                                    pfinfo->delete_on_close = True;
784                            }
785    
                         //unimpl("IRP Set File Information class: FileDispositionInformation\n");  
                         // in_uint32_le(in, delete_on_close);  
                         // disk_close(handle);  
                         unlink(pfinfo->path);  
786                          break;                          break;
787    
788                  case 19:        /* FileAllocationInformation */                  case FileAllocationInformation:
789                            /* Fall through to FileEndOfFileInformation,
790                          unimpl("IRP Set File Information class: FileAllocationInformation\n");                             which uses ftrunc. This is like Samba with
791                          break;                             "strict allocation = false", and means that
792                               we won't detect out-of-quota errors, for
793                               example. */
794    
795                    case FileEndOfFileInformation:
796                            in_uint8s(in, 28);      /* unknown */
797                            in_uint32_le(in, length);       /* file size */
798    
799                            /* prevents start of writing if not enough space left on device */
800                            if (STATFS_FN(g_rdpdr_device[pfinfo->device_id].local_path, &stat_fs) == 0)
801                                    if (stat_fs.f_bfree * stat_fs.f_bsize < length)
802                                            return STATUS_DISK_FULL;
803    
804                  case 20:        /* FileEndOfFileInformation */                          if (ftruncate_growable(handle, length) != 0)
805                            {
806                                    return STATUS_DISK_FULL;
807                            }
808    
                         unimpl("IRP Set File Information class: FileEndOfFileInformation\n");  
809                          break;                          break;
   
810                  default:                  default:
811    
812                          unimpl("IRP Set File Information class: 0x%x\n", info_class);                          unimpl("IRP Set File Information class: 0x%x\n", info_class);
# Line 503  disk_set_information(HANDLE handle, uint Line 816  disk_set_information(HANDLE handle, uint
816  }  }
817    
818  NTSTATUS  NTSTATUS
819  disk_query_volume_information(HANDLE handle, uint32 info_class, STREAM out)  disk_check_notify(NTHANDLE handle)
820    {
821            struct fileinfo *pfinfo;
822            NTSTATUS status = STATUS_PENDING;
823    
824            NOTIFY notify;
825    
826            pfinfo = &(g_fileinfo[handle]);
827            if (!pfinfo->pdir)
828                    return STATUS_INVALID_DEVICE_REQUEST;
829    
830    
831    
832            status = NotifyInfo(handle, pfinfo->info_class, &notify);
833    
834            if (status != STATUS_PENDING)
835                    return status;
836    
837            if (memcmp(&pfinfo->notify, &notify, sizeof(NOTIFY)))
838            {
839                    //printf("disk_check_notify found changed event\n");
840                    memcpy(&pfinfo->notify, &notify, sizeof(NOTIFY));
841                    status = STATUS_NOTIFY_ENUM_DIR;
842            }
843    
844            return status;
845    
846    
847    }
848    
849    NTSTATUS
850    disk_create_notify(NTHANDLE handle, uint32 info_class)
851    {
852    
853            struct fileinfo *pfinfo;
854            NTSTATUS ret = STATUS_PENDING;
855    
856            /* printf("start disk_create_notify info_class %X\n", info_class); */
857    
858            pfinfo = &(g_fileinfo[handle]);
859            pfinfo->info_class = info_class;
860    
861            ret = NotifyInfo(handle, info_class, &pfinfo->notify);
862    
863            if (info_class & 0x1000)
864            {                       /* ???? */
865                    if (ret == STATUS_PENDING)
866                            return STATUS_SUCCESS;
867            }
868    
869            /* printf("disk_create_notify: num_entries %d\n", pfinfo->notify.num_entries); */
870    
871    
872            return ret;
873    
874    }
875    
876    static NTSTATUS
877    NotifyInfo(NTHANDLE handle, uint32 info_class, NOTIFY * p)
878    {
879            struct fileinfo *pfinfo;
880            struct stat buf;
881            struct dirent *dp;
882            char *fullname;
883            DIR *dpr;
884    
885            pfinfo = &(g_fileinfo[handle]);
886            if (fstat(handle, &buf) < 0)
887            {
888                    perror("NotifyInfo");
889                    return STATUS_ACCESS_DENIED;
890            }
891            p->modify_time = buf.st_mtime;
892            p->status_time = buf.st_ctime;
893            p->num_entries = 0;
894            p->total_time = 0;
895    
896    
897            dpr = opendir(pfinfo->path);
898            if (!dpr)
899            {
900                    perror("NotifyInfo");
901                    return STATUS_ACCESS_DENIED;
902            }
903    
904    
905            while ((dp = readdir(dpr)))
906            {
907                    if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, ".."))
908                            continue;
909                    p->num_entries++;
910                    fullname = xmalloc(strlen(pfinfo->path) + strlen(dp->d_name) + 2);
911                    sprintf(fullname, "%s/%s", pfinfo->path, dp->d_name);
912    
913                    if (!stat(fullname, &buf))
914                    {
915                            p->total_time += (buf.st_mtime + buf.st_ctime);
916                    }
917    
918                    xfree(fullname);
919            }
920            closedir(dpr);
921    
922            return STATUS_PENDING;
923    }
924    
925    static FsInfoType *
926    FsVolumeInfo(char *fpath)
927    {
928    
929            FILE *fdfs;
930            static FsInfoType info;
931    #ifdef HAVE_MNTENT_H
932            struct mntent *e;
933    #endif
934    
935            /* initialize */
936            memset(&info, 0, sizeof(info));
937            strcpy(info.label, "RDESKTOP");
938            strcpy(info.type, "RDPFS");
939    
940    #ifdef HAVE_MNTENT_H
941            fdfs = setmntent(MNTENT_PATH, "r");
942            if (!fdfs)
943                    return &info;
944    
945            while ((e = getmntent(fdfs)))
946            {
947                    if (strncmp(fpath, e->mnt_dir, strlen(fpath)) == 0)
948                    {
949                            strcpy(info.type, e->mnt_type);
950                            strcpy(info.name, e->mnt_fsname);
951                            if (strstr(e->mnt_opts, "vfat") || strstr(e->mnt_opts, "iso9660"))
952                            {
953                                    int fd = open(e->mnt_fsname, O_RDONLY);
954                                    if (fd >= 0)
955                                    {
956                                            unsigned char buf[512];
957                                            memset(buf, 0, sizeof(buf));
958                                            if (strstr(e->mnt_opts, "vfat"))
959                                                     /*FAT*/
960                                            {
961                                                    strcpy(info.type, "vfat");
962                                                    read(fd, buf, sizeof(buf));
963                                                    info.serial =
964                                                            (buf[42] << 24) + (buf[41] << 16) +
965                                                            (buf[40] << 8) + buf[39];
966                                                    strncpy(info.label, buf + 43, 10);
967                                                    info.label[10] = '\0';
968                                            }
969                                            else if (lseek(fd, 32767, SEEK_SET) >= 0)       /* ISO9660 */
970                                            {
971                                                    read(fd, buf, sizeof(buf));
972                                                    strncpy(info.label, buf + 41, 32);
973                                                    info.label[32] = '\0';
974                                                    //info.Serial = (buf[128]<<24)+(buf[127]<<16)+(buf[126]<<8)+buf[125];
975                                            }
976                                            close(fd);
977                                    }
978                            }
979                    }
980            }
981            endmntent(fdfs);
982    #else
983            /* initialize */
984            memset(&info, 0, sizeof(info));
985            strcpy(info.label, "RDESKTOP");
986            strcpy(info.type, "RDPFS");
987    
988    #endif
989            return &info;
990    }
991    
992    
993    NTSTATUS
994    disk_query_volume_information(NTHANDLE handle, uint32 info_class, STREAM out)
995  {  {
         char *volume, *fs_type;  
996          struct STATFS_T stat_fs;          struct STATFS_T stat_fs;
997          struct fileinfo *pfinfo;          struct fileinfo *pfinfo;
998            FsInfoType *fsinfo;
999    
1000          pfinfo = &(g_fileinfo[handle]);          pfinfo = &(g_fileinfo[handle]);
         volume = "RDESKTOP";  
         fs_type = "RDPFS";  
1001    
1002          if (STATFS_FN(pfinfo->path, &stat_fs) != 0)     /* FIXME: statfs is not portable */          if (STATFS_FN(pfinfo->path, &stat_fs) != 0)
1003          {          {
1004                  perror("statfs");                  perror("statfs");
1005                  return STATUS_ACCESS_DENIED;                  return STATUS_ACCESS_DENIED;
1006          }          }
1007    
1008            fsinfo = FsVolumeInfo(pfinfo->path);
1009    
1010          switch (info_class)          switch (info_class)
1011          {          {
1012                  case 1: /* FileFsVolumeInformation */                  case FileFsVolumeInformation:
1013    
1014                          out_uint32_le(out, 0);  /* volume creation time low */                          out_uint32_le(out, 0);  /* volume creation time low */
1015                          out_uint32_le(out, 0);  /* volume creation time high */                          out_uint32_le(out, 0);  /* volume creation time high */
1016                          out_uint32_le(out, 0);  /* serial */                          out_uint32_le(out, fsinfo->serial);     /* serial */
1017                          out_uint32_le(out, 2 * strlen(volume)); /* length of string */  
1018                            out_uint32_le(out, 2 * strlen(fsinfo->label));  /* length of string */
1019    
1020                          out_uint8(out, 0);      /* support objects? */                          out_uint8(out, 0);      /* support objects? */
1021                          rdp_out_unistr(out, volume, 2 * strlen(volume) - 2);                          rdp_out_unistr(out, fsinfo->label, 2 * strlen(fsinfo->label) - 2);
1022                          break;                          break;
1023    
1024                  case 3: /* FileFsSizeInformation */                  case FileFsSizeInformation:
1025    
1026                          out_uint32_le(out, stat_fs.f_blocks);   /* Total allocation units low */                          out_uint32_le(out, stat_fs.f_blocks);   /* Total allocation units low */
1027                          out_uint32_le(out, 0);  /* Total allocation high units */                          out_uint32_le(out, 0);  /* Total allocation high units */
# Line 541  disk_query_volume_information(HANDLE han Line 1031  disk_query_volume_information(HANDLE han
1031                          out_uint32_le(out, 0x200);      /* Bytes per sector */                          out_uint32_le(out, 0x200);      /* Bytes per sector */
1032                          break;                          break;
1033    
1034                  case 5: /* FileFsAttributeInformation */                  case FileFsAttributeInformation:
1035    
1036                          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 */
1037                          out_uint32_le(out, F_NAMELEN(stat_fs)); /* max length of filename */                          out_uint32_le(out, F_NAMELEN(stat_fs)); /* max length of filename */
1038                          out_uint32_le(out, 2 * strlen(fs_type));        /* length of fs_type */  
1039                          rdp_out_unistr(out, fs_type, 2 * strlen(fs_type) - 2);                          out_uint32_le(out, 2 * strlen(fsinfo->type));   /* length of fs_type */
1040                            rdp_out_unistr(out, fsinfo->type, 2 * strlen(fsinfo->type) - 2);
1041                          break;                          break;
1042    
1043                  case 2: /* FileFsLabelInformation */                  case FileFsLabelInformation:
1044                  case 4: /* FileFsDeviceInformation */                  case FileFsDeviceInformation:
1045                  case 6: /* FileFsControlInformation */                  case FileFsControlInformation:
1046                  case 7: /* FileFsFullSizeInformation */                  case FileFsFullSizeInformation:
1047                  case 8: /* FileFsObjectIdInformation */                  case FileFsObjectIdInformation:
1048                  case 9: /* FileFsMaximumInformation */                  case FileFsMaximumInformation:
1049    
1050                  default:                  default:
1051    
1052                          unimpl("IRP Query Volume Information class: 0x%x\n", info_class);                          unimpl("IRP Query Volume Information class: 0x%x\n", info_class);
# Line 564  disk_query_volume_information(HANDLE han Line 1056  disk_query_volume_information(HANDLE han
1056  }  }
1057    
1058  NTSTATUS  NTSTATUS
1059  disk_query_directory(HANDLE handle, uint32 info_class, char *pattern, STREAM out)  disk_query_directory(NTHANDLE handle, uint32 info_class, char *pattern, STREAM out)
1060  {  {
1061          uint32 file_attributes, ft_low, ft_high;          uint32 file_attributes, ft_low, ft_high;
1062          char *dirname, fullpath[256];          char *dirname, fullpath[256];
# Line 580  disk_query_directory(HANDLE handle, uint Line 1072  disk_query_directory(HANDLE handle, uint
1072    
1073          switch (info_class)          switch (info_class)
1074          {          {
1075                  case 3: //FIXME: Why 3?                  case FileBothDirectoryInformation:
1076    
1077                          // If a search pattern is received, remember this pattern, and restart search                          // If a search pattern is received, remember this pattern, and restart search
1078                          if (pattern[0] != 0)                          if (pattern[0] != 0)
# Line 592  disk_query_directory(HANDLE handle, uint Line 1084  disk_query_directory(HANDLE handle, uint
1084                          // find next dirent matching pattern                          // find next dirent matching pattern
1085                          pdirent = readdir(pdir);                          pdirent = readdir(pdir);
1086                          while (pdirent && fnmatch(pfinfo->pattern, pdirent->d_name, 0) != 0)                          while (pdirent && fnmatch(pfinfo->pattern, pdirent->d_name, 0) != 0)
                         {  
1087                                  pdirent = readdir(pdir);                                  pdirent = readdir(pdir);
                         }  
1088    
1089                          if (pdirent == NULL)                          if (pdirent == NULL)
                         {  
1090                                  return STATUS_NO_MORE_FILES;                                  return STATUS_NO_MORE_FILES;
                         }  
1091    
1092                          // Get information for directory entry                          // Get information for directory entry
1093                          sprintf(fullpath, "%s/%s", dirname, pdirent->d_name);                          sprintf(fullpath, "%s/%s", dirname, pdirent->d_name);
1094                          /* JIF  
                            printf("Stat: %s\n", fullpath); */  
1095                          if (stat(fullpath, &fstat))                          if (stat(fullpath, &fstat))
1096                          {                          {
1097                                  perror("stat");                                  switch (errno)
1098                                  out_uint8(out, 0);                                  {
1099                                  return STATUS_ACCESS_DENIED;                                          case ENOENT:
1100                                            case ELOOP:
1101                                            case EACCES:
1102                                                    /* These are non-fatal errors. */
1103                                                    memset(&fstat, 0, sizeof(fstat));
1104                                                    break;
1105                                            default:
1106                                                    /* Fatal error. By returning STATUS_NO_SUCH_FILE,
1107                                                       the directory list operation will be aborted */
1108                                                    perror(fullpath);
1109                                                    out_uint8(out, 0);
1110                                                    return STATUS_NO_SUCH_FILE;
1111                                    }
1112                          }                          }
1113    
1114                          if (S_ISDIR(fstat.st_mode))                          if (S_ISDIR(fstat.st_mode))
1115                                  file_attributes |= FILE_ATTRIBUTE_DIRECTORY;                                  file_attributes |= FILE_ATTRIBUTE_DIRECTORY;
1116                          if (pdirent->d_name[0] == '.')                          if (pdirent->d_name[0] == '.')
1117                                  file_attributes |= FILE_ATTRIBUTE_HIDDEN;                                  file_attributes |= FILE_ATTRIBUTE_HIDDEN;
1118                            if (!file_attributes)
1119                                    file_attributes |= FILE_ATTRIBUTE_NORMAL;
1120                            if (!(fstat.st_mode & S_IWUSR))
1121                                    file_attributes |= FILE_ATTRIBUTE_READONLY;
1122    
1123                          // Return requested information                          // Return requested information
1124                          out_uint8s(out, 8);     //unknown zero                          out_uint8s(out, 8);     //unknown zero
1125                          out_uint8s(out, 8);     //create_time not available in posix;  
1126                            seconds_since_1970_to_filetime(get_create_time(&fstat), &ft_high, &ft_low);
1127                            out_uint32_le(out, ft_low);     // create time
1128                            out_uint32_le(out, ft_high);
1129    
1130                          seconds_since_1970_to_filetime(fstat.st_atime, &ft_high, &ft_low);                          seconds_since_1970_to_filetime(fstat.st_atime, &ft_high, &ft_low);
1131                          out_uint32_le(out, ft_low);     //last_access_time                          out_uint32_le(out, ft_low);     //last_access_time
# Line 629  disk_query_directory(HANDLE handle, uint Line 1135  disk_query_directory(HANDLE handle, uint
1135                          out_uint32_le(out, ft_low);     //last_write_time                          out_uint32_le(out, ft_low);     //last_write_time
1136                          out_uint32_le(out, ft_high);                          out_uint32_le(out, ft_high);
1137    
1138                          out_uint8s(out, 8);     //unknown zero                          seconds_since_1970_to_filetime(fstat.st_ctime, &ft_high, &ft_low);
1139                            out_uint32_le(out, ft_low);     //change_write_time
1140                            out_uint32_le(out, ft_high);
1141    
1142                          out_uint32_le(out, fstat.st_size);      //filesize low                          out_uint32_le(out, fstat.st_size);      //filesize low
1143                          out_uint32_le(out, 0);  //filesize high                          out_uint32_le(out, 0);  //filesize high
1144                          out_uint32_le(out, fstat.st_size);      //filesize low                          out_uint32_le(out, fstat.st_size);      //filesize low
# Line 643  disk_query_directory(HANDLE handle, uint Line 1152  disk_query_directory(HANDLE handle, uint
1152                          break;                          break;
1153    
1154                  default:                  default:
1155                            /* FIXME: Support FileDirectoryInformation,
1156                               FileFullDirectoryInformation, and
1157                               FileNamesInformation */
1158    
1159                          unimpl("IRP Query Directory sub: 0x%x\n", info_class);                          unimpl("IRP Query Directory sub: 0x%x\n", info_class);
1160                          return STATUS_INVALID_PARAMETER;                          return STATUS_INVALID_PARAMETER;
# Line 651  disk_query_directory(HANDLE handle, uint Line 1163  disk_query_directory(HANDLE handle, uint
1163          return STATUS_SUCCESS;          return STATUS_SUCCESS;
1164  }  }
1165    
1166    
1167    
1168    static NTSTATUS
1169    disk_device_control(NTHANDLE handle, uint32 request, STREAM in, STREAM out)
1170    {
1171            if (((request >> 16) != 20) || ((request >> 16) != 9))
1172                    return STATUS_INVALID_PARAMETER;
1173    
1174            /* extract operation */
1175            request >>= 2;
1176            request &= 0xfff;
1177    
1178            printf("DISK IOCTL %d\n", request);
1179    
1180            switch (request)
1181            {
1182                    case 25:        // ?
1183                    case 42:        // ?
1184                    default:
1185                            unimpl("DISK IOCTL %d\n", request);
1186                            return STATUS_INVALID_PARAMETER;
1187            }
1188    
1189            return STATUS_SUCCESS;
1190    }
1191    
1192  DEVICE_FNS disk_fns = {  DEVICE_FNS disk_fns = {
1193          disk_create,          disk_create,
1194          disk_close,          disk_close,
1195          disk_read,          disk_read,
1196          disk_write,          disk_write,
1197          NULL                    /* device_control */          disk_device_control     /* device_control */
1198  };  };

Legend:
Removed from v.574  
changed lines
  Added in v.807

  ViewVC Help
Powered by ViewVC 1.1.26