/[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 569 by n-ki, Wed Jan 21 14:40:40 2004 UTC revision 618 by stargo, Sat Feb 28 10:52:29 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 64  Line 80 
80    
81  #define MAX_OPEN_FILES  0x100  #define MAX_OPEN_FILES  0x100
82    
83    #if (defined(sun) && (defined(__svr4__) || defined(__SVR4)))
84    #define SOLARIS
85    #endif
86    
87    #if (defined(SOLARIS) || defined(__hpux))
88    #define DIRFD(a) ((a)->dd_fd)
89    #else
90    #define DIRFD(a) (dirfd(a))
91    #endif
92    
93  #include <sys/types.h>  #include <sys/types.h>
94  #include <sys/stat.h>  #include <sys/stat.h>
 #include <sys/vfs.h>            /* linux statfs */  
95  #include <unistd.h>  #include <unistd.h>
96  #include <fcntl.h>              /* open, close */  #include <fcntl.h>              /* open, close */
97  #include <dirent.h>             /* opendir, closedir, readdir */  #include <dirent.h>             /* opendir, closedir, readdir */
98  #include <fnmatch.h>  #include <fnmatch.h>
99  #include <errno.h>              /* errno */  #include <errno.h>              /* errno */
100    
101    #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 */
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))
112    #define STATFS_T statvfs
113    #define F_NAMELEN(buf) ((buf).f_namemax)
114    
115    #elif (defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__))
116    #include <sys/param.h>
117    #include <sys/mount.h>
118    #define STATFS_FN(path, buf) (statfs(path,buf))
119    #define STATFS_T statfs
120    #define F_NAMELEN(buf) (NAME_MAX)
121    
122    #else
123    #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))
128    #define STATFS_T statfs
129    #define F_NAMELEN(buf) ((buf).f_namelen)
130    #endif
131    
132  #include "rdesktop.h"  #include "rdesktop.h"
133    
134  extern RDPDR_DEVICE g_rdpdr_device[];  extern RDPDR_DEVICE g_rdpdr_device[];
# Line 87  struct fileinfo Line 144  struct fileinfo
144  }  }
145  g_fileinfo[MAX_OPEN_FILES];  g_fileinfo[MAX_OPEN_FILES];
146    
147    typedef struct
148    {
149            char name[256];
150            char label[256];
151            unsigned long serial;
152            char type[256];
153    } FsInfoType;
154    
155    
156    time_t
157    get_create_time(struct stat *st)
158    {
159            time_t ret, ret1;
160    
161            ret = MIN(st->st_ctime, st->st_mtime);
162            ret1 = MIN(ret, st->st_atime);
163    
164            if (ret1 != (time_t) 0)
165                    return ret1;
166    
167            return ret;
168    }
169    
170  /* Convert seconds since 1970 to a filetime */  /* Convert seconds since 1970 to a filetime */
171  void  void
172  seconds_since_1970_to_filetime(time_t seconds, uint32 * high, uint32 * low)  seconds_since_1970_to_filetime(time_t seconds, uint32 * high, uint32 * low)
# Line 98  seconds_since_1970_to_filetime(time_t se Line 178  seconds_since_1970_to_filetime(time_t se
178          *high = (uint32) (ticks >> 32);          *high = (uint32) (ticks >> 32);
179  }  }
180    
181    /* Convert seconds since 1970 back to filetime */
182    time_t
183    convert_1970_to_filetime(uint32 high, uint32 low)
184    {
185            unsigned long long ticks;
186            time_t val;
187    
188            ticks = low + (((unsigned long long) high) << 32);
189            ticks /= 10000000;
190            ticks -= 11644473600LL;
191    
192            val = (time_t) ticks;
193            return (val);
194    
195    }
196    
197    
198  /* Enumeration of devices from rdesktop.c        */  /* Enumeration of devices from rdesktop.c        */
199  /* returns numer of units found and initialized. */  /* returns numer of units found and initialized. */
200  /* optarg looks like ':h:=/mnt/floppy,b:=/mnt/usbdevice1' */  /* optarg looks like ':h=/mnt/floppy,b=/mnt/usbdevice1' */
201  /* when it arrives to this function.             */  /* when it arrives to this function.             */
202  int  int
203  disk_enum_devices(int *id, char *optarg)  disk_enum_devices(uint32 * id, char *optarg)
204  {  {
205          char *pos = optarg;          char *pos = optarg;
206          char *pos2;          char *pos2;
# Line 116  disk_enum_devices(int *id, char *optarg) Line 213  disk_enum_devices(int *id, char *optarg)
213                  pos2 = next_arg(optarg, '=');                  pos2 = next_arg(optarg, '=');
214                  strcpy(g_rdpdr_device[*id].name, optarg);                  strcpy(g_rdpdr_device[*id].name, optarg);
215    
216                  toupper(g_rdpdr_device[*id].name);                  toupper_str(g_rdpdr_device[*id].name);
217    
218                  /* add trailing colon to name. */                  /* add trailing colon to name. */
219                  strcat(g_rdpdr_device[*id].name, ":");                  strcat(g_rdpdr_device[*id].name, ":");
# Line 133  disk_enum_devices(int *id, char *optarg) Line 230  disk_enum_devices(int *id, char *optarg)
230          return count;          return count;
231  }  }
232    
233  /* Opens of creates a file or directory */  /* Opens or creates a file or directory */
234  NTSTATUS  NTSTATUS
235  disk_create(uint32 device_id, uint32 accessmask, uint32 sharemode, uint32 create_disposition,  disk_create(uint32 device_id, uint32 accessmask, uint32 sharemode, uint32 create_disposition,
236              uint32 flags_and_attributes, char *filename, HANDLE * phandle)              uint32 flags_and_attributes, char *filename, HANDLE * phandle)
# Line 142  disk_create(uint32 device_id, uint32 acc Line 239  disk_create(uint32 device_id, uint32 acc
239          DIR *dirp;          DIR *dirp;
240          int flags, mode;          int flags, mode;
241          char path[256];          char path[256];
242            struct stat filestat;
243    
244          handle = 0;          handle = 0;
245          dirp = NULL;          dirp = NULL;
246          flags = 0;          flags = 0;
247          mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;          mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
248    
249    
250          if (filename[strlen(filename) - 1] == '/')          if (filename[strlen(filename) - 1] == '/')
251                  filename[strlen(filename) - 1] = 0;                  filename[strlen(filename) - 1] = 0;
252          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);  
253    
254          switch (create_disposition)          switch (create_disposition)
255          {          {
# Line 186  disk_create(uint32 device_id, uint32 acc Line 284  disk_create(uint32 device_id, uint32 acc
284                          break;                          break;
285          }          }
286    
287            //printf("Open: \"%s\"  flags: %u, accessmask: %u sharemode: %u create disp: %u\n", path, flags_and_attributes, accessmask, sharemode, create_disposition);
288    
289            // Get information about file and set that flag ourselfs
290            if ((stat(path, &filestat) == 0) && (S_ISDIR(filestat.st_mode)))
291            {
292                    if (flags_and_attributes & FILE_NON_DIRECTORY_FILE)
293                            return STATUS_FILE_IS_A_DIRECTORY;
294                    else
295                            flags_and_attributes |= FILE_DIRECTORY_FILE;
296            }
297    
298          if (flags_and_attributes & FILE_DIRECTORY_FILE)          if (flags_and_attributes & FILE_DIRECTORY_FILE)
299          {          {
300                  if (flags & O_CREAT)                  if (flags & O_CREAT)
# Line 212  disk_create(uint32 device_id, uint32 acc Line 321  disk_create(uint32 device_id, uint32 acc
321                                          return STATUS_NO_SUCH_FILE;                                          return STATUS_NO_SUCH_FILE;
322                          }                          }
323                  }                  }
324                  handle = dirfd(dirp);                  handle = DIRFD(dirp);
325          }          }
326          else          else
327          {          {
328    
329                  if (accessmask & GENERIC_ALL                  if (accessmask & GENERIC_ALL
330                      || (accessmask & GENERIC_READ && accessmask & GENERIC_WRITE))                      || (accessmask & GENERIC_READ && accessmask & GENERIC_WRITE))
331                  {                  {
# Line 235  disk_create(uint32 device_id, uint32 acc Line 345  disk_create(uint32 device_id, uint32 acc
345                  {                  {
346                          switch (errno)                          switch (errno)
347                          {                          {
348                                    case EISDIR:
349    
350                                            return STATUS_FILE_IS_A_DIRECTORY;
351    
352                                  case EACCES:                                  case EACCES:
353    
354                                          return STATUS_ACCESS_DENIED;                                          return STATUS_ACCESS_DENIED;
# Line 242  disk_create(uint32 device_id, uint32 acc Line 356  disk_create(uint32 device_id, uint32 acc
356                                  case ENOENT:                                  case ENOENT:
357    
358                                          return STATUS_NO_SUCH_FILE;                                          return STATUS_NO_SUCH_FILE;
359                                    case EEXIST:
360    
361                                            return STATUS_OBJECT_NAME_COLLISION;
362                                  default:                                  default:
363    
364                                          perror("open");                                          perror("open");
365                                          return STATUS_NO_SUCH_FILE;                                          return STATUS_NO_SUCH_FILE;
366                          }                          }
367                  }                  }
368    
369                    /* all read and writes of files should be non blocking */
370                    if (fcntl(handle, F_SETFL, O_NONBLOCK) == -1)
371                            perror("fcntl");
372          }          }
373    
374          if (handle >= MAX_OPEN_FILES)          if (handle >= MAX_OPEN_FILES)
# Line 293  disk_read(HANDLE handle, uint8 * data, u Line 413  disk_read(HANDLE handle, uint8 * data, u
413  {  {
414          int n;          int n;
415    
416          if (offset)  #if 0
417                  lseek(handle, offset, SEEK_SET);          /* browsing dir ????        */
418            /* each request is 24 bytes */
419            if (g_fileinfo[handle].flags_and_attributes & FILE_DIRECTORY_FILE)
420            {
421                    *result = 0;
422                    return STATUS_SUCCESS;
423            }
424    #endif
425    
426            lseek(handle, offset, SEEK_SET);
427    
428          n = read(handle, data, length);          n = read(handle, data, length);
429    
430          if (n < 0)          if (n < 0)
431          {          {
                 perror("read");  
432                  *result = 0;                  *result = 0;
433                  return STATUS_INVALID_PARAMETER;                  switch (errno)
434                    {
435                            case EISDIR:
436                                    return STATUS_FILE_IS_A_DIRECTORY;
437                            default:
438                                    perror("read");
439                                    return STATUS_INVALID_PARAMETER;
440                    }
441          }          }
442    
443          *result = n;          *result = n;
# Line 314  disk_write(HANDLE handle, uint8 * data, Line 450  disk_write(HANDLE handle, uint8 * data,
450  {  {
451          int n;          int n;
452    
453          if (offset)          lseek(handle, offset, SEEK_SET);
                 lseek(handle, offset, SEEK_SET);  
454    
455          n = write(handle, data, length);          n = write(handle, data, length);
456    
# Line 323  disk_write(HANDLE handle, uint8 * data, Line 458  disk_write(HANDLE handle, uint8 * data,
458          {          {
459                  perror("write");                  perror("write");
460                  *result = 0;                  *result = 0;
461                  return STATUS_ACCESS_DENIED;                  switch (errno)
462                    {
463                            case ENOSPC:
464                                    return STATUS_DISK_FULL;
465                            default:
466                                    return STATUS_ACCESS_DENIED;
467                    }
468          }          }
469    
470          *result = n;          *result = n;
# Line 351  disk_query_information(HANDLE handle, ui Line 492  disk_query_information(HANDLE handle, ui
492          // Set file attributes          // Set file attributes
493          file_attributes = 0;          file_attributes = 0;
494          if (S_ISDIR(filestat.st_mode))          if (S_ISDIR(filestat.st_mode))
         {  
495                  file_attributes |= FILE_ATTRIBUTE_DIRECTORY;                  file_attributes |= FILE_ATTRIBUTE_DIRECTORY;
496          }  
497          filename = 1 + strrchr(path, '/');          filename = 1 + strrchr(path, '/');
498          if (filename && filename[0] == '.')          if (filename && filename[0] == '.')
         {  
499                  file_attributes |= FILE_ATTRIBUTE_HIDDEN;                  file_attributes |= FILE_ATTRIBUTE_HIDDEN;
500          }  
501            if (!file_attributes)
502                    file_attributes |= FILE_ATTRIBUTE_NORMAL;
503    
504            if (!(filestat.st_mode & S_IWUSR))
505                    file_attributes |= FILE_ATTRIBUTE_READONLY;
506    
507          // Return requested data          // Return requested data
508          switch (info_class)          switch (info_class)
509          {          {
510                  case 4: /* FileBasicInformation */                  case 4: /* FileBasicInformation */
511                            seconds_since_1970_to_filetime(get_create_time(&filestat), &ft_high,
512                          out_uint8s(out, 8);     //create_time not available;                                                         &ft_low);
513                            out_uint32_le(out, ft_low);     //create_access_time
514                            out_uint32_le(out, ft_high);
515    
516                          seconds_since_1970_to_filetime(filestat.st_atime, &ft_high, &ft_low);                          seconds_since_1970_to_filetime(filestat.st_atime, &ft_high, &ft_low);
517                          out_uint32_le(out, ft_low);     //last_access_time                          out_uint32_le(out, ft_low);     //last_access_time
# Line 375  disk_query_information(HANDLE handle, ui Line 521  disk_query_information(HANDLE handle, ui
521                          out_uint32_le(out, ft_low);     //last_write_time                          out_uint32_le(out, ft_low);     //last_write_time
522                          out_uint32_le(out, ft_high);                          out_uint32_le(out, ft_high);
523    
524                          out_uint8s(out, 8);     //unknown zero                          seconds_since_1970_to_filetime(filestat.st_ctime, &ft_high, &ft_low);
525                            out_uint32_le(out, ft_low);     //last_change_time
526                            out_uint32_le(out, ft_high);
527    
528                          out_uint32_le(out, file_attributes);                          out_uint32_le(out, file_attributes);
529                          break;                          break;
530    
# Line 411  disk_set_information(HANDLE handle, uint Line 560  disk_set_information(HANDLE handle, uint
560          char newname[256], fullpath[256];          char newname[256], fullpath[256];
561          struct fileinfo *pfinfo;          struct fileinfo *pfinfo;
562    
563            int mode;
564            struct stat filestat;
565            time_t write_time, change_time, access_time, mod_time;
566            struct utimbuf tvs;
567            struct STATFS_T stat_fs;
568    
569          pfinfo = &(g_fileinfo[handle]);          pfinfo = &(g_fileinfo[handle]);
570    
571          switch (info_class)          switch (info_class)
572          {          {
573                  case 4: /* FileBasicInformation */                  case 4: /* FileBasicInformation */
574                            write_time = change_time = access_time = 0;
575    
576                            in_uint8s(in, 4);       /* Handle of root dir? */
577                            in_uint8s(in, 24);      /* unknown */
578    
579                            // CreationTime
580                            in_uint32_le(in, ft_low);
581                            in_uint32_le(in, ft_high);
582    
583                            // AccessTime
584                            in_uint32_le(in, ft_low);
585                            in_uint32_le(in, ft_high);
586                            if (ft_low || ft_high)
587                                    access_time = convert_1970_to_filetime(ft_high, ft_low);
588    
589                            // WriteTime
590                            in_uint32_le(in, ft_low);
591                            in_uint32_le(in, ft_high);
592                            if (ft_low || ft_high)
593                                    write_time = convert_1970_to_filetime(ft_high, ft_low);
594    
595                            // ChangeTime
596                            in_uint32_le(in, ft_low);
597                            in_uint32_le(in, ft_high);
598                            if (ft_low || ft_high)
599                                    change_time = convert_1970_to_filetime(ft_high, ft_low);
600    
601                            in_uint32_le(in, file_attributes);
602    
603                            if (fstat(handle, &filestat))
604                                    return STATUS_ACCESS_DENIED;
605    
606                            tvs.modtime = filestat.st_mtime;
607                            tvs.actime = filestat.st_atime;
608                            if (access_time)
609                                    tvs.actime = access_time;
610    
611    
612                            if (write_time || change_time)
613                                    mod_time = MIN(write_time, change_time);
614                            else
615                                    mod_time = write_time ? write_time : change_time;
616    
617                            if (mod_time)
618                                    tvs.modtime = mod_time;
619    
620    
621                            if (access_time || write_time || change_time)
622                            {
623    #if WITH_DEBUG_RDP5
624                                    printf("FileBasicInformation access       time %s",
625                                           ctime(&tvs.actime));
626                                    printf("FileBasicInformation modification time %s",
627                                           ctime(&tvs.modtime));
628    #endif
629                                    if (utime(pfinfo->path, &tvs))
630                                            return STATUS_ACCESS_DENIED;
631                            }
632    
633                            if (!file_attributes)
634                                    break;  // not valid
635    
636                            mode = filestat.st_mode;
637    
638                            if (file_attributes & FILE_ATTRIBUTE_READONLY)
639                                    mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH);
640                            else
641                                    mode |= S_IWUSR;
642    
643                            mode &= 0777;
644    #if WITH_DEBUG_RDP5
645                            printf("FileBasicInformation set access mode 0%o", mode);
646    #endif
647    
648                            if (fchmod(handle, mode))
649                                    return STATUS_ACCESS_DENIED;
650    
                         // Probably safe to ignore  
651                          break;                          break;
652    
653                  case 10:        /* FileRenameInformation */                  case 10:        /* FileRenameInformation */
# Line 449  disk_set_information(HANDLE handle, uint Line 679  disk_set_information(HANDLE handle, uint
679                  case 13:        /* FileDispositionInformation */                  case 13:        /* FileDispositionInformation */
680    
681                          //unimpl("IRP Set File Information class: FileDispositionInformation\n");                          //unimpl("IRP Set File Information class: FileDispositionInformation\n");
682                          // in_uint32_le(in, delete_on_close);  
683                            //in_uint32_le(in, delete_on_close);
684                          // disk_close(handle);                          // disk_close(handle);
685                          unlink(pfinfo->path);                          if ((pfinfo->flags_and_attributes & FILE_DIRECTORY_FILE))       // remove a directory
686                            {
687                                    if (rmdir(pfinfo->path) < 0)
688                                            return STATUS_ACCESS_DENIED;
689                            }
690                            else if (unlink(pfinfo->path) < 0)      // unlink a file
691                                    return STATUS_ACCESS_DENIED;
692    
693                          break;                          break;
694    
695                  case 19:        /* FileAllocationInformation */                  case 19:        /* FileAllocationInformation */
# Line 460  disk_set_information(HANDLE handle, uint Line 698  disk_set_information(HANDLE handle, uint
698                          break;                          break;
699    
700                  case 20:        /* FileEndOfFileInformation */                  case 20:        /* FileEndOfFileInformation */
701                            in_uint8s(in, 28);      /* unknown */
702                            in_uint32_le(in, length);       /* file size */
703    
704                          unimpl("IRP Set File Information class: FileEndOfFileInformation\n");                          /* prevents start of writing if not enough space left on device */
705                            if (STATFS_FN(g_rdpdr_device[pfinfo->device_id].local_path, &stat_fs) == 0)
706                                    if (stat_fs.f_bsize * stat_fs.f_bfree < length)
707                                            return STATUS_DISK_FULL;
708    
709                            //printf("FileEndOfFileInformation length = %d\n", length);
710                            // ????????????
711                            //unimpl("IRP Set File Information class: FileEndOfFileInformation\n");
712                          break;                          break;
   
713                  default:                  default:
714    
715                          unimpl("IRP Set File Information class: 0x%x\n", info_class);                          unimpl("IRP Set File Information class: 0x%x\n", info_class);
# Line 472  disk_set_information(HANDLE handle, uint Line 718  disk_set_information(HANDLE handle, uint
718          return STATUS_SUCCESS;          return STATUS_SUCCESS;
719  }  }
720    
721    FsInfoType *
722    FsVolumeInfo(char *fpath)
723    {
724    
725    #ifdef HAVE_MNTENT_H
726            FILE *fdfs;
727            struct mntent *e;
728            static FsInfoType info;
729    
730            /* initialize */
731            memset(&info, 0, sizeof(info));
732            strcpy(info.label, "RDESKTOP");
733            strcpy(info.type, "RDPFS");
734    
735            fdfs = setmntent(MNTENT_PATH, "r");
736            if (!fdfs)
737                    return &info;
738    
739            while ((e = getmntent(fdfs)))
740            {
741                    if (strncmp(fpath, e->mnt_dir, strlen(fpath)) == 0)
742                    {
743                            strcpy(info.type, e->mnt_type);
744                            strcpy(info.name, e->mnt_fsname);
745                            if (strstr(e->mnt_opts, "vfat") || strstr(e->mnt_opts, "iso9660"))
746                            {
747                                    int fd = open(e->mnt_fsname, O_RDONLY);
748                                    if (fd >= 0)
749                                    {
750                                            unsigned char buf[512];
751                                            memset(buf, 0, sizeof(buf));
752                                            if (strstr(e->mnt_opts, "vfat"))
753                                                     /*FAT*/
754                                            {
755                                                    strcpy(info.type, "vfat");
756                                                    read(fd, buf, sizeof(buf));
757                                                    info.serial =
758                                                            (buf[42] << 24) + (buf[41] << 16) +
759                                                            (buf[40] << 8) + buf[39];
760                                                    strncpy(info.label, buf + 43, 10);
761                                                    info.label[10] = '\0';
762                                            }
763                                            else if (lseek(fd, 32767, SEEK_SET) >= 0)       /* ISO9660 */
764                                            {
765                                                    read(fd, buf, sizeof(buf));
766                                                    strncpy(info.label, buf + 41, 32);
767                                                    info.label[32] = '\0';
768                                                    //info.Serial = (buf[128]<<24)+(buf[127]<<16)+(buf[126]<<8)+buf[125];
769                                            }
770                                            close(fd);
771                                    }
772                            }
773                    }
774            }
775            endmntent(fdfs);
776    #else
777            static FsInfoType info;
778    
779            /* initialize */
780            memset(&info, 0, sizeof(info));
781            strcpy(info.label, "RDESKTOP");
782            strcpy(info.type, "RDPFS");
783    
784    #endif
785            return &info;
786    }
787    
788    
789  NTSTATUS  NTSTATUS
790  disk_query_volume_information(HANDLE handle, uint32 info_class, STREAM out)  disk_query_volume_information(HANDLE handle, uint32 info_class, STREAM out)
791  {  {
792          char *volume, *fs_type;          struct STATFS_T stat_fs;
         struct statfs stat_fs;  
793          struct fileinfo *pfinfo;          struct fileinfo *pfinfo;
794            FsInfoType *fsinfo;
795    
796          pfinfo = &(g_fileinfo[handle]);          pfinfo = &(g_fileinfo[handle]);
         volume = "RDESKTOP";  
         fs_type = "RDPFS";  
797    
798          if (statfs(pfinfo->path, &stat_fs) != 0)        /* FIXME: statfs is not portable */          if (STATFS_FN(pfinfo->path, &stat_fs) != 0)
799          {          {
800                  perror("statfs");                  perror("statfs");
801                  return STATUS_ACCESS_DENIED;                  return STATUS_ACCESS_DENIED;
802          }          }
803    
804            fsinfo = FsVolumeInfo(pfinfo->path);
805    
806          switch (info_class)          switch (info_class)
807          {          {
808                  case 1: /* FileFsVolumeInformation */                  case 1: /* FileFsVolumeInformation */
809    
810                          out_uint32_le(out, 0);  /* volume creation time low */                          out_uint32_le(out, 0);  /* volume creation time low */
811                          out_uint32_le(out, 0);  /* volume creation time high */                          out_uint32_le(out, 0);  /* volume creation time high */
812                          out_uint32_le(out, 0);  /* serial */                          out_uint32_le(out, fsinfo->serial);     /* serial */
813                          out_uint32_le(out, 2 * strlen(volume)); /* length of string */  
814                            out_uint32_le(out, 2 * strlen(fsinfo->label));  /* length of string */
815    
816                          out_uint8(out, 0);      /* support objects? */                          out_uint8(out, 0);      /* support objects? */
817                          rdp_out_unistr(out, volume, 2 * strlen(volume) - 2);                          rdp_out_unistr(out, fsinfo->label, 2 * strlen(fsinfo->label) - 2);
818                          break;                          break;
819    
820                  case 3: /* FileFsSizeInformation */                  case 3: /* FileFsSizeInformation */
# Line 514  disk_query_volume_information(HANDLE han Line 830  disk_query_volume_information(HANDLE han
830                  case 5: /* FileFsAttributeInformation */                  case 5: /* FileFsAttributeInformation */
831    
832                          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 */
833                          out_uint32_le(out, stat_fs.f_namelen);  /* max length of filename */                          out_uint32_le(out, F_NAMELEN(stat_fs)); /* max length of filename */
834                          out_uint32_le(out, 2 * strlen(fs_type));        /* length of fs_type */  
835                          rdp_out_unistr(out, fs_type, 2 * strlen(fs_type) - 2);                          out_uint32_le(out, 2 * strlen(fsinfo->type));   /* length of fs_type */
836                            rdp_out_unistr(out, fsinfo->type, 2 * strlen(fsinfo->type) - 2);
837                          break;                          break;
838    
839                  case 2: /* FileFsLabelInformation */                  case 2: /* FileFsLabelInformation */
# Line 562  disk_query_directory(HANDLE handle, uint Line 879  disk_query_directory(HANDLE handle, uint
879                          // find next dirent matching pattern                          // find next dirent matching pattern
880                          pdirent = readdir(pdir);                          pdirent = readdir(pdir);
881                          while (pdirent && fnmatch(pfinfo->pattern, pdirent->d_name, 0) != 0)                          while (pdirent && fnmatch(pfinfo->pattern, pdirent->d_name, 0) != 0)
                         {  
882                                  pdirent = readdir(pdir);                                  pdirent = readdir(pdir);
                         }  
883    
884                          if (pdirent == NULL)                          if (pdirent == NULL)
                         {  
885                                  return STATUS_NO_MORE_FILES;                                  return STATUS_NO_MORE_FILES;
                         }  
886    
887                          // Get information for directory entry                          // Get information for directory entry
888                          sprintf(fullpath, "%s/%s", dirname, pdirent->d_name);                          sprintf(fullpath, "%s/%s", dirname, pdirent->d_name);
889                          /* JIF  
890                            /* JIF
891                             printf("Stat: %s\n", fullpath); */                             printf("Stat: %s\n", fullpath); */
892                          if (stat(fullpath, &fstat))                          if (stat(fullpath, &fstat))
893                          {                          {
# Line 586  disk_query_directory(HANDLE handle, uint Line 900  disk_query_directory(HANDLE handle, uint
900                                  file_attributes |= FILE_ATTRIBUTE_DIRECTORY;                                  file_attributes |= FILE_ATTRIBUTE_DIRECTORY;
901                          if (pdirent->d_name[0] == '.')                          if (pdirent->d_name[0] == '.')
902                                  file_attributes |= FILE_ATTRIBUTE_HIDDEN;                                  file_attributes |= FILE_ATTRIBUTE_HIDDEN;
903                            if (!file_attributes)
904                                    file_attributes |= FILE_ATTRIBUTE_NORMAL;
905                            if (!(fstat.st_mode & S_IWUSR))
906                                    file_attributes |= FILE_ATTRIBUTE_READONLY;
907    
908                          // Return requested information                          // Return requested information
909                          out_uint8s(out, 8);     //unknown zero                          out_uint8s(out, 8);     //unknown zero
910                          out_uint8s(out, 8);     //create_time not available in posix;  
911                            seconds_since_1970_to_filetime(get_create_time(&fstat), &ft_high, &ft_low);
912                            out_uint32_le(out, ft_low);     // create time
913                            out_uint32_le(out, ft_high);
914    
915                          seconds_since_1970_to_filetime(fstat.st_atime, &ft_high, &ft_low);                          seconds_since_1970_to_filetime(fstat.st_atime, &ft_high, &ft_low);
916                          out_uint32_le(out, ft_low);     //last_access_time                          out_uint32_le(out, ft_low);     //last_access_time
# Line 599  disk_query_directory(HANDLE handle, uint Line 920  disk_query_directory(HANDLE handle, uint
920                          out_uint32_le(out, ft_low);     //last_write_time                          out_uint32_le(out, ft_low);     //last_write_time
921                          out_uint32_le(out, ft_high);                          out_uint32_le(out, ft_high);
922    
923                          out_uint8s(out, 8);     //unknown zero                          seconds_since_1970_to_filetime(fstat.st_ctime, &ft_high, &ft_low);
924                            out_uint32_le(out, ft_low);     //change_write_time
925                            out_uint32_le(out, ft_high);
926    
927                          out_uint32_le(out, fstat.st_size);      //filesize low                          out_uint32_le(out, fstat.st_size);      //filesize low
928                          out_uint32_le(out, 0);  //filesize high                          out_uint32_le(out, 0);  //filesize high
929                          out_uint32_le(out, fstat.st_size);      //filesize low                          out_uint32_le(out, fstat.st_size);      //filesize low
# Line 621  disk_query_directory(HANDLE handle, uint Line 945  disk_query_directory(HANDLE handle, uint
945          return STATUS_SUCCESS;          return STATUS_SUCCESS;
946  }  }
947    
948    
949    
950    static NTSTATUS
951    disk_device_control(HANDLE handle, uint32 request, STREAM in, STREAM out)
952    {
953            uint32 result;
954    
955            if (((request >> 16) != 20) || ((request >> 16) != 9))
956                    return STATUS_INVALID_PARAMETER;
957    
958            /* extract operation */
959            request >>= 2;
960            request &= 0xfff;
961    
962            printf("DISK IOCTL %d\n", request);
963    
964            switch (request)
965            {
966                    case 25:        // ?
967                    case 42:        // ?
968                    default:
969                            unimpl("DISK IOCTL %d\n", request);
970                            return STATUS_INVALID_PARAMETER;
971            }
972    
973            return STATUS_SUCCESS;
974    }
975    
976  DEVICE_FNS disk_fns = {  DEVICE_FNS disk_fns = {
977          disk_create,          disk_create,
978          disk_close,          disk_close,
979          disk_read,          disk_read,
980          disk_write,          disk_write,
981          NULL                    /* device_control */          disk_device_control     /* device_control */
982  };  };

Legend:
Removed from v.569  
changed lines
  Added in v.618

  ViewVC Help
Powered by ViewVC 1.1.26