/[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 596 by n-ki, Tue Feb 3 14:03:42 2004 UTC revision 627 by n-ki, Thu Mar 4 08:24:40 2004 UTC
# Line 24  Line 24 
24  #define FILE_ATTRIBUTE_DIRECTORY                0x00000010  #define FILE_ATTRIBUTE_DIRECTORY                0x00000010
25  #define FILE_ATTRIBUTE_ARCHIVE                  0x00000020  #define FILE_ATTRIBUTE_ARCHIVE                  0x00000020
26  #define FILE_ATTRIBUTE_DEVICE                   0x00000040  #define FILE_ATTRIBUTE_DEVICE                   0x00000040
27    #define FILE_ATTRIBUTE_UNKNOWNXXX0              0x00000060      /* ??? ACTION i.e. 0x860 == compress this file ? */
28  #define FILE_ATTRIBUTE_NORMAL                   0x00000080  #define FILE_ATTRIBUTE_NORMAL                   0x00000080
29  #define FILE_ATTRIBUTE_TEMPORARY                0x00000100  #define FILE_ATTRIBUTE_TEMPORARY                0x00000100
30  #define FILE_ATTRIBUTE_SPARSE_FILE              0x00000200  #define FILE_ATTRIBUTE_SPARSE_FILE              0x00000200
# Line 33  Line 34 
34  #define FILE_ATTRIBUTE_NOT_CONTENT_INDEXED      0x00002000  #define FILE_ATTRIBUTE_NOT_CONTENT_INDEXED      0x00002000
35  #define FILE_ATTRIBUTE_ENCRYPTED                0x00004000  #define FILE_ATTRIBUTE_ENCRYPTED                0x00004000
36    
37    #define FILE_FLAG_OPEN_NO_RECALL                0x00100000
38    #define FILE_FLAG_OPEN_REPARSE_POINT            0x00200000
39    #define FILE_FLAG_POSIX_SEMANTICS               0x01000000
40    #define FILE_FLAG_BACKUP_SEMANTICS              0x02000000      /* sometimes used to create a directory */
41    #define FILE_FLAG_DELETE_ON_CLOSE               0x04000000
42    #define FILE_FLAG_SEQUENTIAL_SCAN               0x08000000
43    #define FILE_FLAG_RANDOM_ACCESS                 0x10000000
44    #define FILE_FLAG_NO_BUFFERING                  0x20000000
45    #define FILE_FLAG_OVERLAPPED                    0x40000000
46    #define FILE_FLAG_WRITE_THROUGH                 0x80000000
47    
48    #define FILE_SHARE_READ                         0x01
49    #define FILE_SHARE_WRITE                        0x02
50    #define FILE_SHARE_DELETE                       0x04
51    
52  #define FILE_BASIC_INFORMATION                  0x04  #define FILE_BASIC_INFORMATION                  0x04
53  #define FILE_STANDARD_INFORMATION               0x05  #define FILE_STANDARD_INFORMATION               0x05
54    
# Line 68  Line 84 
84  #define SOLARIS  #define SOLARIS
85  #endif  #endif
86    
87  #ifdef SOLARIS  #if (defined(SOLARIS) || defined(__hpux))
88  #define DIRFD(a) ((a)->dd_fd)  #define DIRFD(a) ((a)->dd_fd)
89  #else  #else
90  #define DIRFD(a) (dirfd(a))  #define DIRFD(a) (dirfd(a))
# Line 82  Line 98 
98  #include <fnmatch.h>  #include <fnmatch.h>
99  #include <errno.h>              /* errno */  #include <errno.h>              /* errno */
100    
101  #if defined(SOLARIS)  #include <utime.h>
102    #include <time.h>               /* ctime */
103    
104    
105    #if (defined(SOLARIS) || defined (__hpux) || defined(__BEOS__))
106  #include <sys/statvfs.h>        /* solaris statvfs */  #include <sys/statvfs.h>        /* solaris statvfs */
107    #include <sys/mntent.h>
108    /* TODO: Fix mntent-handling for solaris */
109    #undef HAVE_MNTENT_H
110    #define MNTENT_PATH "/etc/mnttab"
111  #define STATFS_FN(path, buf) (statvfs(path,buf))  #define STATFS_FN(path, buf) (statvfs(path,buf))
112  #define STATFS_T statvfs  #define STATFS_T statvfs
113  #define F_NAMELEN(buf) ((buf).f_namemax)  #define F_NAMELEN(buf) ((buf).f_namemax)
# Line 97  Line 121 
121    
122  #else  #else
123  #include <sys/vfs.h>            /* linux statfs */  #include <sys/vfs.h>            /* linux statfs */
124    #include <mntent.h>
125    #define HAVE_MNTENT_H
126    #define MNTENT_PATH "/etc/mtab"
127  #define STATFS_FN(path, buf) (statfs(path,buf))  #define STATFS_FN(path, buf) (statfs(path,buf))
128  #define STATFS_T statfs  #define STATFS_T statfs
129  #define F_NAMELEN(buf) ((buf).f_namelen)  #define F_NAMELEN(buf) ((buf).f_namelen)
# Line 106  Line 133 
133    
134  extern RDPDR_DEVICE g_rdpdr_device[];  extern RDPDR_DEVICE g_rdpdr_device[];
135    
136  struct fileinfo  FILEINFO g_fileinfo[MAX_OPEN_FILES];
137    
138    typedef struct
139  {  {
140          uint32 device_id, flags_and_attributes;          char name[256];
141          char path[256];          char label[256];
142          DIR *pdir;          unsigned long serial;
143          struct dirent *pdirent;          char type[256];
144          char pattern[64];  } FsInfoType;
145          BOOL delete_on_close;  
146    
147    time_t
148    get_create_time(struct stat *st)
149    {
150            time_t ret, ret1;
151    
152            ret = MIN(st->st_ctime, st->st_mtime);
153            ret1 = MIN(ret, st->st_atime);
154    
155            if (ret1 != (time_t) 0)
156                    return ret1;
157    
158            return ret;
159  }  }
 g_fileinfo[MAX_OPEN_FILES];  
160    
161  /* Convert seconds since 1970 to a filetime */  /* Convert seconds since 1970 to a filetime */
162  void  void
# Line 128  seconds_since_1970_to_filetime(time_t se Line 169  seconds_since_1970_to_filetime(time_t se
169          *high = (uint32) (ticks >> 32);          *high = (uint32) (ticks >> 32);
170  }  }
171    
172    /* Convert seconds since 1970 back to filetime */
173    time_t
174    convert_1970_to_filetime(uint32 high, uint32 low)
175    {
176            unsigned long long ticks;
177            time_t val;
178    
179            ticks = low + (((unsigned long long) high) << 32);
180            ticks /= 10000000;
181            ticks -= 11644473600LL;
182    
183            val = (time_t) ticks;
184            return (val);
185    
186    }
187    
188    
189  /* Enumeration of devices from rdesktop.c        */  /* Enumeration of devices from rdesktop.c        */
190  /* returns numer of units found and initialized. */  /* returns numer of units found and initialized. */
191  /* optarg looks like ':h:=/mnt/floppy,b:=/mnt/usbdevice1' */  /* optarg looks like ':h=/mnt/floppy,b=/mnt/usbdevice1' */
192  /* when it arrives to this function.             */  /* when it arrives to this function.             */
193  int  int
194  disk_enum_devices(int *id, char *optarg)  disk_enum_devices(uint32 * id, char *optarg)
195  {  {
196          char *pos = optarg;          char *pos = optarg;
197          char *pos2;          char *pos2;
# Line 172  disk_create(uint32 device_id, uint32 acc Line 230  disk_create(uint32 device_id, uint32 acc
230          DIR *dirp;          DIR *dirp;
231          int flags, mode;          int flags, mode;
232          char path[256];          char path[256];
233            struct stat filestat;
234    
235          handle = 0;          handle = 0;
236          dirp = NULL;          dirp = NULL;
237          flags = 0;          flags = 0;
238          mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;          mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
239    
240    
241          if (filename[strlen(filename) - 1] == '/')          if (filename[strlen(filename) - 1] == '/')
242                  filename[strlen(filename) - 1] = 0;                  filename[strlen(filename) - 1] = 0;
243          sprintf(path, "%s%s", g_rdpdr_device[device_id].local_path, filename);          sprintf(path, "%s%s", g_rdpdr_device[device_id].local_path, filename);
# Line 215  disk_create(uint32 device_id, uint32 acc Line 275  disk_create(uint32 device_id, uint32 acc
275                          break;                          break;
276          }          }
277    
278          /* the sad part is that we can't trust this flag   */          //printf("Open: \"%s\"  flags: %u, accessmask: %u sharemode: %u create disp: %u\n", path, flags_and_attributes, accessmask, sharemode, create_disposition);
279          /* directories aren't always marked                */  
280          if (flags_and_attributes ^ FILE_DIRECTORY_FILE)          // Get information about file and set that flag ourselfs
281            if ((stat(path, &filestat) == 0) && (S_ISDIR(filestat.st_mode)))
282          {          {
283                  if (accessmask & GENERIC_ALL                  if (flags_and_attributes & FILE_NON_DIRECTORY_FILE)
284                      || (accessmask & GENERIC_READ && accessmask & GENERIC_WRITE))                          return STATUS_FILE_IS_A_DIRECTORY;
                 {  
                         flags |= O_RDWR;  
                 }  
                 else if ((accessmask & GENERIC_WRITE) && !(accessmask & GENERIC_READ))  
                 {  
                         flags |= O_WRONLY;  
                 }  
285                  else                  else
286                            flags_and_attributes |= FILE_DIRECTORY_FILE;
287            }
288    
289            if (flags_and_attributes & FILE_DIRECTORY_FILE)
290            {
291                    if (flags & O_CREAT)
292                  {                  {
293                          flags |= O_RDONLY;                          mkdir(path, mode);
294                  }                  }
295    
296                  handle = open(path, flags, mode);                  dirp = opendir(path);
297                  if (handle == -1)                  if (!dirp)
298                  {                  {
299                          switch (errno)                          switch (errno)
300                          {                          {
# Line 248  disk_create(uint32 device_id, uint32 acc Line 308  disk_create(uint32 device_id, uint32 acc
308    
309                                  default:                                  default:
310    
311                                          perror("open");                                          perror("opendir");
312                                          return STATUS_NO_SUCH_FILE;                                          return STATUS_NO_SUCH_FILE;
313                          }                          }
314                  }                  }
315                    handle = DIRFD(dirp);
                 /* all read and writes of files should be non blocking */  
                 if (fcntl(handle, F_SETFL, O_NONBLOCK) == -1)  
                         perror("fcntl");  
316          }          }
317            else
         /* since we can't trust the FILE_DIRECTORY_FILE flag */  
         /* we need to double check that the file isn't a dir */  
         if (handle != 0)  
318          {          {
                 /* Must check if this file isn't actually a directory */  
                 struct stat filestat;  
319    
320                  // Get information about file and set that flag ourselfs                  if (accessmask & GENERIC_ALL
321                  if ((fstat(handle, &filestat) == 0) && (S_ISDIR(filestat.st_mode)))                      || (accessmask & GENERIC_READ && accessmask & GENERIC_WRITE))
322                  {                  {
323                          flags_and_attributes |= FILE_DIRECTORY_FILE;                          flags |= O_RDWR;
                         close(handle);  
                         handle = 0;  
324                  }                  }
325          }                  else if ((accessmask & GENERIC_WRITE) && !(accessmask & GENERIC_READ))
   
   
         if (flags_and_attributes & FILE_DIRECTORY_FILE)  
         {  
                 if (flags & O_CREAT)  
326                  {                  {
327                          mkdir(path, mode);                          flags |= O_WRONLY;
328                    }
329                    else
330                    {
331                            flags |= O_RDONLY;
332                  }                  }
333    
334                  dirp = opendir(path);                  handle = open(path, flags, mode);
335                  if (!dirp)                  if (handle == -1)
336                  {                  {
337                          switch (errno)                          switch (errno)
338                          {                          {
339                                    case EISDIR:
340    
341                                            return STATUS_FILE_IS_A_DIRECTORY;
342    
343                                  case EACCES:                                  case EACCES:
344    
345                                          return STATUS_ACCESS_DENIED;                                          return STATUS_ACCESS_DENIED;
# Line 294  disk_create(uint32 device_id, uint32 acc Line 347  disk_create(uint32 device_id, uint32 acc
347                                  case ENOENT:                                  case ENOENT:
348    
349                                          return STATUS_NO_SUCH_FILE;                                          return STATUS_NO_SUCH_FILE;
350                                    case EEXIST:
351    
352                                            return STATUS_OBJECT_NAME_COLLISION;
353                                  default:                                  default:
354    
355                                          perror("opendir");                                          perror("open");
356                                          return STATUS_NO_SUCH_FILE;                                          return STATUS_NO_SUCH_FILE;
357                          }                          }
358                  }                  }
359                  handle = DIRFD(dirp);  
360                    /* all read and writes of files should be non blocking */
361                    if (fcntl(handle, F_SETFL, O_NONBLOCK) == -1)
362                            perror("fcntl");
363          }          }
364    
365          if (handle >= MAX_OPEN_FILES)          if (handle >= MAX_OPEN_FILES)
# Line 315  disk_create(uint32 device_id, uint32 acc Line 373  disk_create(uint32 device_id, uint32 acc
373                  g_fileinfo[handle].pdir = dirp;                  g_fileinfo[handle].pdir = dirp;
374          g_fileinfo[handle].device_id = device_id;          g_fileinfo[handle].device_id = device_id;
375          g_fileinfo[handle].flags_and_attributes = flags_and_attributes;          g_fileinfo[handle].flags_and_attributes = flags_and_attributes;
 //      printf("create: attrib: %u handle %u\n", g_fileinfo[handle].flags_and_attributes, handle );  
376          strncpy(g_fileinfo[handle].path, path, 255);          strncpy(g_fileinfo[handle].path, path, 255);
377    
378          *phandle = handle;          *phandle = handle;
# Line 347  disk_read(HANDLE handle, uint8 * data, u Line 404  disk_read(HANDLE handle, uint8 * data, u
404  {  {
405          int n;          int n;
406    
407    #if 0
408          /* browsing dir ????        */          /* browsing dir ????        */
409          /* each request is 24 bytes */          /* each request is 24 bytes */
410          if (g_fileinfo[handle].flags_and_attributes & FILE_DIRECTORY_FILE)          if (g_fileinfo[handle].flags_and_attributes & FILE_DIRECTORY_FILE)
# Line 354  disk_read(HANDLE handle, uint8 * data, u Line 412  disk_read(HANDLE handle, uint8 * data, u
412                  *result = 0;                  *result = 0;
413                  return STATUS_SUCCESS;                  return STATUS_SUCCESS;
414          }          }
415    #endif
416    
417            lseek(handle, offset, SEEK_SET);
418    
         if (offset)  
                 lseek(handle, offset, SEEK_SET);  
419          n = read(handle, data, length);          n = read(handle, data, length);
420    
421          if (n < 0)          if (n < 0)
422          {          {
                 perror("read");  
423                  *result = 0;                  *result = 0;
424                  return STATUS_INVALID_PARAMETER;                  switch (errno)
425                    {
426                            case EISDIR:
427                                    return STATUS_FILE_IS_A_DIRECTORY;
428                            default:
429                                    perror("read");
430                                    return STATUS_INVALID_PARAMETER;
431                    }
432          }          }
433    
434          *result = n;          *result = n;
# Line 376  disk_write(HANDLE handle, uint8 * data, Line 441  disk_write(HANDLE handle, uint8 * data,
441  {  {
442          int n;          int n;
443    
444          if (offset)          lseek(handle, offset, SEEK_SET);
                 lseek(handle, offset, SEEK_SET);  
445    
446          n = write(handle, data, length);          n = write(handle, data, length);
447    
# Line 385  disk_write(HANDLE handle, uint8 * data, Line 449  disk_write(HANDLE handle, uint8 * data,
449          {          {
450                  perror("write");                  perror("write");
451                  *result = 0;                  *result = 0;
452                  return STATUS_ACCESS_DENIED;                  switch (errno)
453                    {
454                            case ENOSPC:
455                                    return STATUS_DISK_FULL;
456                            default:
457                                    return STATUS_ACCESS_DENIED;
458                    }
459          }          }
460    
461          *result = n;          *result = n;
# Line 413  disk_query_information(HANDLE handle, ui Line 483  disk_query_information(HANDLE handle, ui
483          // Set file attributes          // Set file attributes
484          file_attributes = 0;          file_attributes = 0;
485          if (S_ISDIR(filestat.st_mode))          if (S_ISDIR(filestat.st_mode))
         {  
486                  file_attributes |= FILE_ATTRIBUTE_DIRECTORY;                  file_attributes |= FILE_ATTRIBUTE_DIRECTORY;
487          }  
488          filename = 1 + strrchr(path, '/');          filename = 1 + strrchr(path, '/');
489          if (filename && filename[0] == '.')          if (filename && filename[0] == '.')
         {  
490                  file_attributes |= FILE_ATTRIBUTE_HIDDEN;                  file_attributes |= FILE_ATTRIBUTE_HIDDEN;
491          }  
492            if (!file_attributes)
493                    file_attributes |= FILE_ATTRIBUTE_NORMAL;
494    
495            if (!(filestat.st_mode & S_IWUSR))
496                    file_attributes |= FILE_ATTRIBUTE_READONLY;
497    
498          // Return requested data          // Return requested data
499          switch (info_class)          switch (info_class)
500          {          {
501                  case 4: /* FileBasicInformation */                  case 4: /* FileBasicInformation */
502                            seconds_since_1970_to_filetime(get_create_time(&filestat), &ft_high,
503                          out_uint8s(out, 8);     //create_time not available;                                                         &ft_low);
504                            out_uint32_le(out, ft_low);     //create_access_time
505                            out_uint32_le(out, ft_high);
506    
507                          seconds_since_1970_to_filetime(filestat.st_atime, &ft_high, &ft_low);                          seconds_since_1970_to_filetime(filestat.st_atime, &ft_high, &ft_low);
508                          out_uint32_le(out, ft_low);     //last_access_time                          out_uint32_le(out, ft_low);     //last_access_time
# Line 437  disk_query_information(HANDLE handle, ui Line 512  disk_query_information(HANDLE handle, ui
512                          out_uint32_le(out, ft_low);     //last_write_time                          out_uint32_le(out, ft_low);     //last_write_time
513                          out_uint32_le(out, ft_high);                          out_uint32_le(out, ft_high);
514    
515                          out_uint8s(out, 8);     //unknown zero                          seconds_since_1970_to_filetime(filestat.st_ctime, &ft_high, &ft_low);
516                            out_uint32_le(out, ft_low);     //last_change_time
517                            out_uint32_le(out, ft_high);
518    
519                          out_uint32_le(out, file_attributes);                          out_uint32_le(out, file_attributes);
520                          break;                          break;
521    
# Line 473  disk_set_information(HANDLE handle, uint Line 551  disk_set_information(HANDLE handle, uint
551          char newname[256], fullpath[256];          char newname[256], fullpath[256];
552          struct fileinfo *pfinfo;          struct fileinfo *pfinfo;
553    
554            int mode;
555            struct stat filestat;
556            time_t write_time, change_time, access_time, mod_time;
557            struct utimbuf tvs;
558            struct STATFS_T stat_fs;
559    
560          pfinfo = &(g_fileinfo[handle]);          pfinfo = &(g_fileinfo[handle]);
561    
562          switch (info_class)          switch (info_class)
563          {          {
564                  case 4: /* FileBasicInformation */                  case 4: /* FileBasicInformation */
565                            write_time = change_time = access_time = 0;
566    
567                            in_uint8s(in, 4);       /* Handle of root dir? */
568                            in_uint8s(in, 24);      /* unknown */
569    
570                            // CreationTime
571                            in_uint32_le(in, ft_low);
572                            in_uint32_le(in, ft_high);
573    
574                            // AccessTime
575                            in_uint32_le(in, ft_low);
576                            in_uint32_le(in, ft_high);
577                            if (ft_low || ft_high)
578                                    access_time = convert_1970_to_filetime(ft_high, ft_low);
579    
580                            // WriteTime
581                            in_uint32_le(in, ft_low);
582                            in_uint32_le(in, ft_high);
583                            if (ft_low || ft_high)
584                                    write_time = convert_1970_to_filetime(ft_high, ft_low);
585    
586                            // ChangeTime
587                            in_uint32_le(in, ft_low);
588                            in_uint32_le(in, ft_high);
589                            if (ft_low || ft_high)
590                                    change_time = convert_1970_to_filetime(ft_high, ft_low);
591    
592                            in_uint32_le(in, file_attributes);
593    
594                            if (fstat(handle, &filestat))
595                                    return STATUS_ACCESS_DENIED;
596    
597                            tvs.modtime = filestat.st_mtime;
598                            tvs.actime = filestat.st_atime;
599                            if (access_time)
600                                    tvs.actime = access_time;
601    
602    
603                            if (write_time || change_time)
604                                    mod_time = MIN(write_time, change_time);
605                            else
606                                    mod_time = write_time ? write_time : change_time;
607    
608                            if (mod_time)
609                                    tvs.modtime = mod_time;
610    
611    
612                            if (access_time || write_time || change_time)
613                            {
614    #if WITH_DEBUG_RDP5
615                                    printf("FileBasicInformation access       time %s",
616                                           ctime(&tvs.actime));
617                                    printf("FileBasicInformation modification time %s",
618                                           ctime(&tvs.modtime));
619    #endif
620                                    if (utime(pfinfo->path, &tvs))
621                                            return STATUS_ACCESS_DENIED;
622                            }
623    
624                            if (!file_attributes)
625                                    break;  // not valid
626    
627                            mode = filestat.st_mode;
628    
629                            if (file_attributes & FILE_ATTRIBUTE_READONLY)
630                                    mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH);
631                            else
632                                    mode |= S_IWUSR;
633    
634                            mode &= 0777;
635    #if WITH_DEBUG_RDP5
636                            printf("FileBasicInformation set access mode 0%o", mode);
637    #endif
638    
639                            if (fchmod(handle, mode))
640                                    return STATUS_ACCESS_DENIED;
641    
                         // Probably safe to ignore  
642                          break;                          break;
643    
644                  case 10:        /* FileRenameInformation */                  case 10:        /* FileRenameInformation */
# Line 511  disk_set_information(HANDLE handle, uint Line 670  disk_set_information(HANDLE handle, uint
670                  case 13:        /* FileDispositionInformation */                  case 13:        /* FileDispositionInformation */
671    
672                          //unimpl("IRP Set File Information class: FileDispositionInformation\n");                          //unimpl("IRP Set File Information class: FileDispositionInformation\n");
673                          // in_uint32_le(in, delete_on_close);  
674                            //in_uint32_le(in, delete_on_close);
675                          // disk_close(handle);                          // disk_close(handle);
676                          unlink(pfinfo->path);                          if ((pfinfo->flags_and_attributes & FILE_DIRECTORY_FILE))       // remove a directory
677                            {
678                                    if (rmdir(pfinfo->path) < 0)
679                                            return STATUS_ACCESS_DENIED;
680                            }
681                            else if (unlink(pfinfo->path) < 0)      // unlink a file
682                                    return STATUS_ACCESS_DENIED;
683    
684                          break;                          break;
685    
686                  case 19:        /* FileAllocationInformation */                  case 19:        /* FileAllocationInformation */
# Line 522  disk_set_information(HANDLE handle, uint Line 689  disk_set_information(HANDLE handle, uint
689                          break;                          break;
690    
691                  case 20:        /* FileEndOfFileInformation */                  case 20:        /* FileEndOfFileInformation */
692                            in_uint8s(in, 28);      /* unknown */
693                            in_uint32_le(in, length);       /* file size */
694    
695                          unimpl("IRP Set File Information class: FileEndOfFileInformation\n");                          /* prevents start of writing if not enough space left on device */
696                            if (STATFS_FN(g_rdpdr_device[pfinfo->device_id].local_path, &stat_fs) == 0)
697                                    if (stat_fs.f_bsize * stat_fs.f_bfree < length)
698                                            return STATUS_DISK_FULL;
699    
700                            //printf("FileEndOfFileInformation length = %d\n", length);
701                            // ????????????
702                            //unimpl("IRP Set File Information class: FileEndOfFileInformation\n");
703                          break;                          break;
   
704                  default:                  default:
705    
706                          unimpl("IRP Set File Information class: 0x%x\n", info_class);                          unimpl("IRP Set File Information class: 0x%x\n", info_class);
# Line 534  disk_set_information(HANDLE handle, uint Line 709  disk_set_information(HANDLE handle, uint
709          return STATUS_SUCCESS;          return STATUS_SUCCESS;
710  }  }
711    
712    FsInfoType *
713    FsVolumeInfo(char *fpath)
714    {
715    
716    #ifdef HAVE_MNTENT_H
717            FILE *fdfs;
718            struct mntent *e;
719            static FsInfoType info;
720    
721            /* initialize */
722            memset(&info, 0, sizeof(info));
723            strcpy(info.label, "RDESKTOP");
724            strcpy(info.type, "RDPFS");
725    
726            fdfs = setmntent(MNTENT_PATH, "r");
727            if (!fdfs)
728                    return &info;
729    
730            while ((e = getmntent(fdfs)))
731            {
732                    if (strncmp(fpath, e->mnt_dir, strlen(fpath)) == 0)
733                    {
734                            strcpy(info.type, e->mnt_type);
735                            strcpy(info.name, e->mnt_fsname);
736                            if (strstr(e->mnt_opts, "vfat") || strstr(e->mnt_opts, "iso9660"))
737                            {
738                                    int fd = open(e->mnt_fsname, O_RDONLY);
739                                    if (fd >= 0)
740                                    {
741                                            unsigned char buf[512];
742                                            memset(buf, 0, sizeof(buf));
743                                            if (strstr(e->mnt_opts, "vfat"))
744                                                     /*FAT*/
745                                            {
746                                                    strcpy(info.type, "vfat");
747                                                    read(fd, buf, sizeof(buf));
748                                                    info.serial =
749                                                            (buf[42] << 24) + (buf[41] << 16) +
750                                                            (buf[40] << 8) + buf[39];
751                                                    strncpy(info.label, buf + 43, 10);
752                                                    info.label[10] = '\0';
753                                            }
754                                            else if (lseek(fd, 32767, SEEK_SET) >= 0)       /* ISO9660 */
755                                            {
756                                                    read(fd, buf, sizeof(buf));
757                                                    strncpy(info.label, buf + 41, 32);
758                                                    info.label[32] = '\0';
759                                                    //info.Serial = (buf[128]<<24)+(buf[127]<<16)+(buf[126]<<8)+buf[125];
760                                            }
761                                            close(fd);
762                                    }
763                            }
764                    }
765            }
766            endmntent(fdfs);
767    #else
768            static FsInfoType info;
769    
770            /* initialize */
771            memset(&info, 0, sizeof(info));
772            strcpy(info.label, "RDESKTOP");
773            strcpy(info.type, "RDPFS");
774    
775    #endif
776            return &info;
777    }
778    
779    
780  NTSTATUS  NTSTATUS
781  disk_query_volume_information(HANDLE handle, uint32 info_class, STREAM out)  disk_query_volume_information(HANDLE handle, uint32 info_class, STREAM out)
782  {  {
         char *volume, *fs_type;  
783          struct STATFS_T stat_fs;          struct STATFS_T stat_fs;
784          struct fileinfo *pfinfo;          struct fileinfo *pfinfo;
785            FsInfoType *fsinfo;
786    
787          pfinfo = &(g_fileinfo[handle]);          pfinfo = &(g_fileinfo[handle]);
         volume = "RDESKTOP";  
         fs_type = "RDPFS";  
788    
789          if (STATFS_FN(pfinfo->path, &stat_fs) != 0)     /* FIXME: statfs is not portable */          if (STATFS_FN(pfinfo->path, &stat_fs) != 0)
790          {          {
791                  perror("statfs");                  perror("statfs");
792                  return STATUS_ACCESS_DENIED;                  return STATUS_ACCESS_DENIED;
793          }          }
794    
795            fsinfo = FsVolumeInfo(pfinfo->path);
796    
797          switch (info_class)          switch (info_class)
798          {          {
799                  case 1: /* FileFsVolumeInformation */                  case 1: /* FileFsVolumeInformation */
800    
801                          out_uint32_le(out, 0);  /* volume creation time low */                          out_uint32_le(out, 0);  /* volume creation time low */
802                          out_uint32_le(out, 0);  /* volume creation time high */                          out_uint32_le(out, 0);  /* volume creation time high */
803                          out_uint32_le(out, 0);  /* serial */                          out_uint32_le(out, fsinfo->serial);     /* serial */
804                          out_uint32_le(out, 2 * strlen(volume)); /* length of string */  
805                            out_uint32_le(out, 2 * strlen(fsinfo->label));  /* length of string */
806    
807                          out_uint8(out, 0);      /* support objects? */                          out_uint8(out, 0);      /* support objects? */
808                          rdp_out_unistr(out, volume, 2 * strlen(volume) - 2);                          rdp_out_unistr(out, fsinfo->label, 2 * strlen(fsinfo->label) - 2);
809                          break;                          break;
810    
811                  case 3: /* FileFsSizeInformation */                  case 3: /* FileFsSizeInformation */
# Line 577  disk_query_volume_information(HANDLE han Line 822  disk_query_volume_information(HANDLE han
822    
823                          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 */
824                          out_uint32_le(out, F_NAMELEN(stat_fs)); /* max length of filename */                          out_uint32_le(out, F_NAMELEN(stat_fs)); /* max length of filename */
825                          out_uint32_le(out, 2 * strlen(fs_type));        /* length of fs_type */  
826                          rdp_out_unistr(out, fs_type, 2 * strlen(fs_type) - 2);                          out_uint32_le(out, 2 * strlen(fsinfo->type));   /* length of fs_type */
827                            rdp_out_unistr(out, fsinfo->type, 2 * strlen(fsinfo->type) - 2);
828                          break;                          break;
829    
830                  case 2: /* FileFsLabelInformation */                  case 2: /* FileFsLabelInformation */
# Line 624  disk_query_directory(HANDLE handle, uint Line 870  disk_query_directory(HANDLE handle, uint
870                          // find next dirent matching pattern                          // find next dirent matching pattern
871                          pdirent = readdir(pdir);                          pdirent = readdir(pdir);
872                          while (pdirent && fnmatch(pfinfo->pattern, pdirent->d_name, 0) != 0)                          while (pdirent && fnmatch(pfinfo->pattern, pdirent->d_name, 0) != 0)
                         {  
873                                  pdirent = readdir(pdir);                                  pdirent = readdir(pdir);
                         }  
874    
875                          if (pdirent == NULL)                          if (pdirent == NULL)
                         {  
876                                  return STATUS_NO_MORE_FILES;                                  return STATUS_NO_MORE_FILES;
                         }  
877    
878                          // Get information for directory entry                          // Get information for directory entry
879                          sprintf(fullpath, "%s/%s", dirname, pdirent->d_name);                          sprintf(fullpath, "%s/%s", dirname, pdirent->d_name);
880    
881                          /* JIF                          /* JIF
882                             printf("Stat: %s\n", fullpath); */                             printf("Stat: %s\n", fullpath); */
883                          if (stat(fullpath, &fstat))                          if (stat(fullpath, &fstat))
# Line 648  disk_query_directory(HANDLE handle, uint Line 891  disk_query_directory(HANDLE handle, uint
891                                  file_attributes |= FILE_ATTRIBUTE_DIRECTORY;                                  file_attributes |= FILE_ATTRIBUTE_DIRECTORY;
892                          if (pdirent->d_name[0] == '.')                          if (pdirent->d_name[0] == '.')
893                                  file_attributes |= FILE_ATTRIBUTE_HIDDEN;                                  file_attributes |= FILE_ATTRIBUTE_HIDDEN;
894                            if (!file_attributes)
895                                    file_attributes |= FILE_ATTRIBUTE_NORMAL;
896                            if (!(fstat.st_mode & S_IWUSR))
897                                    file_attributes |= FILE_ATTRIBUTE_READONLY;
898    
899                          // Return requested information                          // Return requested information
900                          out_uint8s(out, 8);     //unknown zero                          out_uint8s(out, 8);     //unknown zero
901                          out_uint8s(out, 8);     //create_time not available in posix;  
902                            seconds_since_1970_to_filetime(get_create_time(&fstat), &ft_high, &ft_low);
903                            out_uint32_le(out, ft_low);     // create time
904                            out_uint32_le(out, ft_high);
905    
906                          seconds_since_1970_to_filetime(fstat.st_atime, &ft_high, &ft_low);                          seconds_since_1970_to_filetime(fstat.st_atime, &ft_high, &ft_low);
907                          out_uint32_le(out, ft_low);     //last_access_time                          out_uint32_le(out, ft_low);     //last_access_time
# Line 661  disk_query_directory(HANDLE handle, uint Line 911  disk_query_directory(HANDLE handle, uint
911                          out_uint32_le(out, ft_low);     //last_write_time                          out_uint32_le(out, ft_low);     //last_write_time
912                          out_uint32_le(out, ft_high);                          out_uint32_le(out, ft_high);
913    
914                          out_uint8s(out, 8);     //unknown zero                          seconds_since_1970_to_filetime(fstat.st_ctime, &ft_high, &ft_low);
915                            out_uint32_le(out, ft_low);     //change_write_time
916                            out_uint32_le(out, ft_high);
917    
918                          out_uint32_le(out, fstat.st_size);      //filesize low                          out_uint32_le(out, fstat.st_size);      //filesize low
919                          out_uint32_le(out, 0);  //filesize high                          out_uint32_le(out, 0);  //filesize high
920                          out_uint32_le(out, fstat.st_size);      //filesize low                          out_uint32_le(out, fstat.st_size);      //filesize low
# Line 683  disk_query_directory(HANDLE handle, uint Line 936  disk_query_directory(HANDLE handle, uint
936          return STATUS_SUCCESS;          return STATUS_SUCCESS;
937  }  }
938    
939    
940    
941    static NTSTATUS
942    disk_device_control(HANDLE handle, uint32 request, STREAM in, STREAM out)
943    {
944            uint32 result;
945    
946            if (((request >> 16) != 20) || ((request >> 16) != 9))
947                    return STATUS_INVALID_PARAMETER;
948    
949            /* extract operation */
950            request >>= 2;
951            request &= 0xfff;
952    
953            printf("DISK IOCTL %d\n", request);
954    
955            switch (request)
956            {
957                    case 25:        // ?
958                    case 42:        // ?
959                    default:
960                            unimpl("DISK IOCTL %d\n", request);
961                            return STATUS_INVALID_PARAMETER;
962            }
963    
964            return STATUS_SUCCESS;
965    }
966    
967  DEVICE_FNS disk_fns = {  DEVICE_FNS disk_fns = {
968          disk_create,          disk_create,
969          disk_close,          disk_close,
970          disk_read,          disk_read,
971          disk_write,          disk_write,
972          NULL                    /* device_control */          disk_device_control     /* device_control */
973  };  };

Legend:
Removed from v.596  
changed lines
  Added in v.627

  ViewVC Help
Powered by ViewVC 1.1.26