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)) |
102 |
#include <time.h> /* ctime */ |
#include <time.h> /* ctime */ |
103 |
|
|
104 |
|
|
105 |
#if defined(SOLARIS) |
#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) |
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) |
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; |
|
BOOL delete_on_close; |
|
|
} |
|
|
g_fileinfo[MAX_OPEN_FILES]; |
|
145 |
|
|
146 |
|
|
147 |
time_t |
time_t |
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; |
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("open"); |
perror("open"); |
414 |
} |
} |
415 |
#endif |
#endif |
416 |
|
|
417 |
if (offset) |
lseek(handle, offset, SEEK_SET); |
418 |
lseek(handle, offset, SEEK_SET); |
|
419 |
n = read(handle, data, length); |
n = read(handle, data, length); |
420 |
|
|
421 |
if (n < 0) |
if (n < 0) |
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 |
|
|
555 |
struct stat filestat; |
struct stat filestat; |
556 |
time_t write_time, change_time, access_time, mod_time; |
time_t write_time, change_time, access_time, mod_time; |
557 |
struct utimbuf tvs; |
struct utimbuf tvs; |
558 |
|
struct STATFS_T stat_fs; |
559 |
|
|
560 |
pfinfo = &(g_fileinfo[handle]); |
pfinfo = &(g_fileinfo[handle]); |
561 |
|
|
638 |
|
|
639 |
if (fchmod(handle, mode)) |
if (fchmod(handle, mode)) |
640 |
return STATUS_ACCESS_DENIED; |
return STATUS_ACCESS_DENIED; |
641 |
|
|
642 |
break; |
break; |
643 |
|
|
644 |
case 10: /* FileRenameInformation */ |
case 10: /* FileRenameInformation */ |
692 |
in_uint8s(in, 28); /* unknown */ |
in_uint8s(in, 28); /* unknown */ |
693 |
in_uint32_le(in, length); /* file size */ |
in_uint32_le(in, length); /* file size */ |
694 |
|
|
695 |
printf("FileEndOfFileInformation length = %d\n", length); |
/* 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 |
unimpl("IRP Set File Information class: FileEndOfFileInformation\n"); |
//printf("FileEndOfFileInformation length = %d\n", length); |
701 |
|
// ???????????? |
702 |
|
//unimpl("IRP Set File Information class: FileEndOfFileInformation\n"); |
703 |
break; |
break; |
704 |
default: |
default: |
705 |
|
|
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) |
if (STATFS_FN(pfinfo->path, &stat_fs) != 0) |
790 |
{ |
{ |
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 */ |
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 */ |