104 |
|
|
105 |
#if (defined(SOLARIS) || defined (__hpux) || defined(__BEOS__)) |
#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 |
|
#define HAVE_MNTENT_H |
109 |
|
#define MNTENT_PATH "/etc/mnttab" |
110 |
#define STATFS_FN(path, buf) (statvfs(path,buf)) |
#define STATFS_FN(path, buf) (statvfs(path,buf)) |
111 |
#define STATFS_T statvfs |
#define STATFS_T statvfs |
112 |
#define F_NAMELEN(buf) ((buf).f_namemax) |
#define F_NAMELEN(buf) ((buf).f_namemax) |
120 |
|
|
121 |
#else |
#else |
122 |
#include <sys/vfs.h> /* linux statfs */ |
#include <sys/vfs.h> /* linux statfs */ |
123 |
|
#include <mntent.h> |
124 |
|
#define HAVE_MNTENT_H |
125 |
|
#define MNTENT_PATH "/etc/mtab" |
126 |
#define STATFS_FN(path, buf) (statfs(path,buf)) |
#define STATFS_FN(path, buf) (statfs(path,buf)) |
127 |
#define STATFS_T statfs |
#define STATFS_T statfs |
128 |
#define F_NAMELEN(buf) ((buf).f_namelen) |
#define F_NAMELEN(buf) ((buf).f_namelen) |
143 |
} |
} |
144 |
g_fileinfo[MAX_OPEN_FILES]; |
g_fileinfo[MAX_OPEN_FILES]; |
145 |
|
|
146 |
|
typedef struct |
147 |
|
{ |
148 |
|
char name[256]; |
149 |
|
char label[256]; |
150 |
|
unsigned long serial; |
151 |
|
char type[256]; |
152 |
|
} FsInfoType; |
153 |
|
|
154 |
|
|
155 |
time_t |
time_t |
156 |
get_create_time(struct stat *st) |
get_create_time(struct stat *st) |
196 |
|
|
197 |
/* Enumeration of devices from rdesktop.c */ |
/* Enumeration of devices from rdesktop.c */ |
198 |
/* returns numer of units found and initialized. */ |
/* returns numer of units found and initialized. */ |
199 |
/* optarg looks like ':h:=/mnt/floppy,b:=/mnt/usbdevice1' */ |
/* optarg looks like ':h=/mnt/floppy,b=/mnt/usbdevice1' */ |
200 |
/* when it arrives to this function. */ |
/* when it arrives to this function. */ |
201 |
int |
int |
202 |
disk_enum_devices(uint32 *id, char *optarg) |
disk_enum_devices(uint32 * id, char *optarg) |
203 |
{ |
{ |
204 |
char *pos = optarg; |
char *pos = optarg; |
205 |
char *pos2; |
char *pos2; |
355 |
case ENOENT: |
case ENOENT: |
356 |
|
|
357 |
return STATUS_NO_SUCH_FILE; |
return STATUS_NO_SUCH_FILE; |
358 |
|
case EEXIST: |
359 |
|
|
360 |
|
return STATUS_OBJECT_NAME_COLLISION; |
361 |
default: |
default: |
362 |
|
|
363 |
perror("open"); |
perror("open"); |
422 |
} |
} |
423 |
#endif |
#endif |
424 |
|
|
425 |
if (offset) |
lseek(handle, offset, SEEK_SET); |
426 |
lseek(handle, offset, SEEK_SET); |
|
427 |
n = read(handle, data, length); |
n = read(handle, data, length); |
428 |
|
|
429 |
if (n < 0) |
if (n < 0) |
449 |
{ |
{ |
450 |
int n; |
int n; |
451 |
|
|
452 |
if (offset) |
lseek(handle, offset, SEEK_SET); |
|
lseek(handle, offset, SEEK_SET); |
|
453 |
|
|
454 |
n = write(handle, data, length); |
n = write(handle, data, length); |
455 |
|
|
563 |
struct stat filestat; |
struct stat filestat; |
564 |
time_t write_time, change_time, access_time, mod_time; |
time_t write_time, change_time, access_time, mod_time; |
565 |
struct utimbuf tvs; |
struct utimbuf tvs; |
566 |
|
struct STATFS_T stat_fs; |
567 |
|
|
568 |
pfinfo = &(g_fileinfo[handle]); |
pfinfo = &(g_fileinfo[handle]); |
569 |
|
|
646 |
|
|
647 |
if (fchmod(handle, mode)) |
if (fchmod(handle, mode)) |
648 |
return STATUS_ACCESS_DENIED; |
return STATUS_ACCESS_DENIED; |
649 |
|
|
650 |
break; |
break; |
651 |
|
|
652 |
case 10: /* FileRenameInformation */ |
case 10: /* FileRenameInformation */ |
700 |
in_uint8s(in, 28); /* unknown */ |
in_uint8s(in, 28); /* unknown */ |
701 |
in_uint32_le(in, length); /* file size */ |
in_uint32_le(in, length); /* file size */ |
702 |
|
|
703 |
printf("FileEndOfFileInformation length = %d\n", length); |
/* prevents start of writing if not enough space left on device */ |
704 |
// ???????????? |
if (STATFS_FN(g_rdpdr_device[pfinfo->device_id].local_path, &stat_fs) == 0) |
705 |
|
if (stat_fs.f_bsize * stat_fs.f_bfree < length) |
706 |
|
return STATUS_DISK_FULL; |
707 |
|
|
708 |
unimpl("IRP Set File Information class: FileEndOfFileInformation\n"); |
//printf("FileEndOfFileInformation length = %d\n", length); |
709 |
|
// ???????????? |
710 |
|
//unimpl("IRP Set File Information class: FileEndOfFileInformation\n"); |
711 |
break; |
break; |
712 |
default: |
default: |
713 |
|
|
717 |
return STATUS_SUCCESS; |
return STATUS_SUCCESS; |
718 |
} |
} |
719 |
|
|
720 |
|
FsInfoType * |
721 |
|
FsVolumeInfo(char *fpath) |
722 |
|
{ |
723 |
|
|
724 |
|
#ifdef HAVE_MNTENT_H |
725 |
|
FILE *fdfs; |
726 |
|
struct mntent *e; |
727 |
|
static FsInfoType info; |
728 |
|
|
729 |
|
/* initialize */ |
730 |
|
memset(&info, 0, sizeof(info)); |
731 |
|
strcpy(info.label, "RDESKTOP"); |
732 |
|
strcpy(info.type, "RDPFS"); |
733 |
|
|
734 |
|
fdfs = setmntent(MNTENT_PATH, "r"); |
735 |
|
if (!fdfs) |
736 |
|
return &info; |
737 |
|
|
738 |
|
while ((e = getmntent(fdfs))) |
739 |
|
{ |
740 |
|
if (strncmp(fpath, e->mnt_dir, strlen(fpath)) == 0) |
741 |
|
{ |
742 |
|
strcpy(info.type, e->mnt_type); |
743 |
|
strcpy(info.name, e->mnt_fsname); |
744 |
|
if (strstr(e->mnt_opts, "vfat") || strstr(e->mnt_opts, "iso9660")) |
745 |
|
{ |
746 |
|
int fd = open(e->mnt_fsname, O_RDONLY); |
747 |
|
if (fd >= 0) |
748 |
|
{ |
749 |
|
unsigned char buf[512]; |
750 |
|
memset(buf, 0, sizeof(buf)); |
751 |
|
if (strstr(e->mnt_opts, "vfat")) |
752 |
|
/*FAT*/ |
753 |
|
{ |
754 |
|
strcpy(info.type, "vfat"); |
755 |
|
read(fd, buf, sizeof(buf)); |
756 |
|
info.serial = |
757 |
|
(buf[42] << 24) + (buf[41] << 16) + |
758 |
|
(buf[40] << 8) + buf[39]; |
759 |
|
strncpy(info.label, buf + 43, 10); |
760 |
|
info.label[10] = '\0'; |
761 |
|
} |
762 |
|
else if (lseek(fd, 32767, SEEK_SET) >= 0) /* ISO9660 */ |
763 |
|
{ |
764 |
|
read(fd, buf, sizeof(buf)); |
765 |
|
strncpy(info.label, buf + 41, 32); |
766 |
|
info.label[32] = '\0'; |
767 |
|
//info.Serial = (buf[128]<<24)+(buf[127]<<16)+(buf[126]<<8)+buf[125]; |
768 |
|
} |
769 |
|
close(fd); |
770 |
|
} |
771 |
|
} |
772 |
|
} |
773 |
|
} |
774 |
|
endmntent(fdfs); |
775 |
|
#else |
776 |
|
static FsInfoType info; |
777 |
|
|
778 |
|
/* initialize */ |
779 |
|
memset(&info, 0, sizeof(info)); |
780 |
|
strcpy(info.label, "RDESKTOP"); |
781 |
|
strcpy(info.type, "RDPFS"); |
782 |
|
|
783 |
|
#endif |
784 |
|
return &info; |
785 |
|
} |
786 |
|
|
787 |
|
|
788 |
NTSTATUS |
NTSTATUS |
789 |
disk_query_volume_information(HANDLE handle, uint32 info_class, STREAM out) |
disk_query_volume_information(HANDLE handle, uint32 info_class, STREAM out) |
790 |
{ |
{ |
|
char *volume, *fs_type; |
|
791 |
struct STATFS_T stat_fs; |
struct STATFS_T stat_fs; |
792 |
struct fileinfo *pfinfo; |
struct fileinfo *pfinfo; |
793 |
|
FsInfoType *fsinfo; |
794 |
|
|
795 |
pfinfo = &(g_fileinfo[handle]); |
pfinfo = &(g_fileinfo[handle]); |
|
volume = "RDESKTOP"; |
|
|
fs_type = "RDPFS"; |
|
796 |
|
|
797 |
if (STATFS_FN(pfinfo->path, &stat_fs) != 0) |
if (STATFS_FN(pfinfo->path, &stat_fs) != 0) |
798 |
{ |
{ |
800 |
return STATUS_ACCESS_DENIED; |
return STATUS_ACCESS_DENIED; |
801 |
} |
} |
802 |
|
|
803 |
|
fsinfo = FsVolumeInfo(pfinfo->path); |
804 |
|
|
805 |
switch (info_class) |
switch (info_class) |
806 |
{ |
{ |
807 |
case 1: /* FileFsVolumeInformation */ |
case 1: /* FileFsVolumeInformation */ |
808 |
|
|
809 |
out_uint32_le(out, 0); /* volume creation time low */ |
out_uint32_le(out, 0); /* volume creation time low */ |
810 |
out_uint32_le(out, 0); /* volume creation time high */ |
out_uint32_le(out, 0); /* volume creation time high */ |
811 |
out_uint32_le(out, 0); /* serial */ |
out_uint32_le(out, fsinfo->serial); /* serial */ |
812 |
out_uint32_le(out, 2 * strlen(volume)); /* length of string */ |
|
813 |
|
out_uint32_le(out, 2 * strlen(fsinfo->label)); /* length of string */ |
814 |
|
|
815 |
out_uint8(out, 0); /* support objects? */ |
out_uint8(out, 0); /* support objects? */ |
816 |
rdp_out_unistr(out, volume, 2 * strlen(volume) - 2); |
rdp_out_unistr(out, fsinfo->label, 2 * strlen(fsinfo->label) - 2); |
817 |
break; |
break; |
818 |
|
|
819 |
case 3: /* FileFsSizeInformation */ |
case 3: /* FileFsSizeInformation */ |
830 |
|
|
831 |
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 */ |
832 |
out_uint32_le(out, F_NAMELEN(stat_fs)); /* max length of filename */ |
out_uint32_le(out, F_NAMELEN(stat_fs)); /* max length of filename */ |
833 |
out_uint32_le(out, 2 * strlen(fs_type)); /* length of fs_type */ |
|
834 |
rdp_out_unistr(out, fs_type, 2 * strlen(fs_type) - 2); |
out_uint32_le(out, 2 * strlen(fsinfo->type)); /* length of fs_type */ |
835 |
|
rdp_out_unistr(out, fsinfo->type, 2 * strlen(fsinfo->type) - 2); |
836 |
break; |
break; |
837 |
|
|
838 |
case 2: /* FileFsLabelInformation */ |
case 2: /* FileFsLabelInformation */ |