Mods to fix issues #502 & #462
authorNigel Reeves <nigel.reeves@hp.com>
Wed, 18 Apr 2012 09:52:49 +0000 (10:52 +0100)
committerNigel Reeves <nigel.reeves@hp.com>
Wed, 18 Apr 2012 09:52:49 +0000 (10:52 +0100)
Additionally modify some disk information values to reflect true values rather than some hardcoded ones so that disk properties show correctly.

channels/rdpdr/disk/disk_file.c
channels/rdpdr/disk/disk_file.h
channels/rdpdr/disk/disk_main.c

index dda4a7a..cdc1fe9 100644 (file)
 #include "rdpdr_types.h"
 #include "disk_file.h"
 
-#define FILE_TIME_SYSTEM_TO_RDP(_t) \
-       (((uint64)(_t) + 11644473600LL) * 10000000LL)
-#define FILE_TIME_RDP_TO_SYSTEM(_t) \
-       (((_t) == 0LL || (_t) == (uint64)(-1LL)) ? 0 : (time_t)((_t) / 10000000LL - 11644473600LL))
-
-#define FILE_ATTR_SYSTEM_TO_RDP(_f, _st) ( \
-       (S_ISDIR(_st.st_mode) ? FILE_ATTRIBUTE_DIRECTORY : 0) | \
-       (_f->filename[0] == '.' ? FILE_ATTRIBUTE_HIDDEN : 0) | \
-       (_f->delete_pending ? FILE_ATTRIBUTE_TEMPORARY : 0) | \
-       (st.st_mode & S_IWUSR ? 0 : FILE_ATTRIBUTE_READONLY))
-
-
 static boolean disk_file_wildcard_match(const char* pattern, const char* filename)
 {
        const char *p = pattern, *f = filename;
@@ -194,7 +182,7 @@ static boolean disk_file_init(DISK_FILE* file, uint32 DesiredAccess, uint32 Crea
        boolean exists;
 #ifndef WIN32
        boolean largeFile = false;
-#endif 
+#endif
        int oflag = 0;
 
        if (STAT(file->fullpath, &st) == 0)
@@ -203,7 +191,7 @@ static boolean disk_file_init(DISK_FILE* file, uint32 DesiredAccess, uint32 Crea
 #ifndef WIN32
                if (st.st_size > (unsigned long)0x07fffffff)
                    largeFile = true;
-#endif         
+#endif
                exists = true;
        }
        else
@@ -582,9 +570,8 @@ boolean disk_file_query_directory(DISK_FILE* file, uint32 FsInformationClass, ui
                DEBUG_WARN("stat %s failed. errno = %d", ent_path, errno);
        }
 
-       xfree(ent_path);
-
        DEBUG_SVC("  pattern %s matched %s", file->pattern, ent_path);
+       xfree(ent_path);
 
        uniconv = freerdp_uniconv_new();
        ent_path = freerdp_uniconv_out(uniconv, ent->d_name, &len);
index c9b4be8..68252df 100644 (file)
@@ -22,6 +22,7 @@
 #define __DISK_FILE_H
 
 #include <sys/types.h>
+#include <sys/statvfs.h>
 #include <sys/stat.h>
 #include <dirent.h>
 
 #define OPEN open
 #define LSEEK lseek
 #define FSTAT fstat
+#define STATVFS statvfs
 #elif defined(__APPLE__) || defined(__FreeBSD__)
 #define STAT stat
 #define OPEN open
 #define LSEEK lseek
 #define FSTAT fstat
+#define STATVFS statvfs
 #define O_LARGEFILE 0
 #else
 #define STAT stat64
 #define OPEN open64
 #define LSEEK lseek64
 #define FSTAT fstat64
+#define STATVFS statvfs64
 #endif
 
+#define EPOCH_DIFF 11644473600LL
+
+#define FILE_TIME_SYSTEM_TO_RDP(_t) \
+       (((uint64)(_t) + EPOCH_DIFF) * 10000000LL)
+#define FILE_TIME_RDP_TO_SYSTEM(_t) \
+       (((_t) == 0LL || (_t) == (uint64)(-1LL)) ? 0 : (time_t)((_t) / 10000000LL - EPOCH_DIFF))
+
+#define FILE_ATTR_SYSTEM_TO_RDP(_f, _st) ( \
+       (S_ISDIR(_st.st_mode) ? FILE_ATTRIBUTE_DIRECTORY : 0) | \
+       (_f->filename[0] == '.' ? FILE_ATTRIBUTE_HIDDEN : 0) | \
+       (_f->delete_pending ? FILE_ATTRIBUTE_TEMPORARY : 0) | \
+       (st.st_mode & S_IWUSR ? 0 : FILE_ATTRIBUTE_READONLY))
+
+
+
+
+
 typedef struct _DISK_FILE DISK_FILE;
 struct _DISK_FILE
 {
index 8cca5d9..ad0b5a2 100644 (file)
  * limitations under the License.
  */
 
+#ifndef _WIN32
+#define __USE_LARGEFILE64
+#define _LARGEFILE_SOURCE
+#define _LARGEFILE64_SOURCE
+
+#include <sys/time.h>
+#endif
+
+
 #include "config.h"
 #include <errno.h>
 #include <stdio.h>
@@ -44,8 +53,10 @@ struct _DISK_DEVICE
 
        LIST* irp_list;
        freerdp_thread* thread;
-};
 
+       DEVMAN* devman;
+       pcRegisterDevice UnregisterDevice;
+};
 
 static uint32
 disk_map_posix_err(int fs_errno)
@@ -117,6 +128,7 @@ static void disk_process_irp_create(DISK_DEVICE* disk, IRP* irp)
        freerdp_uniconv_free(uniconv);
 
        FileId = irp->devman->id_sequence++;
+
        file = disk_file_new(disk->path, path, FileId,
                DesiredAccess, CreateDisposition, CreateOptions);
 
@@ -135,7 +147,6 @@ static void disk_process_irp_create(DISK_DEVICE* disk, IRP* irp)
 
                /* map errno to windows result*/
                irp->IoStatus = disk_map_posix_err(file->err);
-
                disk_file_free(file);
        }
        else
@@ -362,55 +373,74 @@ static void disk_process_irp_query_volume_information(DISK_DEVICE* disk, IRP* ir
 {
        uint32 FsInformationClass;
        STREAM* output = irp->output;
+       struct STATVFS svfst;
+       struct STAT st;
+       UNICONV* uniconv;
+       char *volumeLabel = {"FREERDP"};  /* TODO:: Add sub routine to correctly pick up Volume Label name for each O/S supported*/
+       char *diskType = {"FAT32"};
+       char* outStr;
+       size_t len;
 
        stream_read_uint32(irp->input, FsInformationClass);
 
+       STATVFS(disk->path, &svfst);
+       STAT(disk->path, &st);
+
        switch (FsInformationClass)
        {
                case FileFsVolumeInformation:
                        /* http://msdn.microsoft.com/en-us/library/cc232108.aspx */
-                       stream_write_uint32(output, 34); /* Length */
-                       stream_check_size(output, 34);
-                       stream_write_uint64(output, 0); /* VolumeCreationTime */
-                       stream_write_uint32(output, 0); /* VolumeSerialNumber */
-                       stream_write_uint32(output, 16); /* VolumeLabelLength */
+                       uniconv = freerdp_uniconv_new();
+                       outStr = freerdp_uniconv_out(uniconv, volumeLabel, &len);
+                       freerdp_uniconv_free(uniconv);
+                       stream_write_uint32(output, 17 + len); /* Length */
+                       stream_check_size(output, 17 + len);
+                       stream_write_uint64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_ctime)); /* VolumeCreationTime */
+                       stream_write_uint32(output, svfst.f_fsid); /* VolumeSerialNumber */
+                       stream_write_uint32(output, len); /* VolumeLabelLength */
                        stream_write_uint8(output, 0); /* SupportsObjects */
-                       stream_write_uint8(output, 0); /* Reserved */
-                       stream_write(output, "F\0R\0E\0E\0R\0D\0P\0\0\0", 16); /* VolumeLabel (Unicode) */
+                       /* Reserved(1), MUST NOT be added! */
+                       stream_write(output, outStr, len); /* VolumeLabel (Unicode) */
+                       xfree(outStr);
                        break;
 
                case FileFsSizeInformation:
                        /* http://msdn.microsoft.com/en-us/library/cc232107.aspx */
                        stream_write_uint32(output, 24); /* Length */
                        stream_check_size(output, 24);
-                       stream_write_uint64(output, 0x1000000); /* TotalAllocationUnits */
-                       stream_write_uint64(output, 0x800000); /* AvailableAllocationUnits */
+                       stream_write_uint64(output, svfst.f_blocks); /* TotalAllocationUnits */
+                       stream_write_uint64(output, svfst.f_bavail); /* AvailableAllocationUnits */
                        stream_write_uint32(output, 1); /* SectorsPerAllocationUnit */
-                       stream_write_uint32(output, 0x400); /* BytesPerSector */
+                       stream_write_uint32(output, svfst.f_bsize); /* BytesPerSector */
                        break;
 
                case FileFsAttributeInformation:
                        /* http://msdn.microsoft.com/en-us/library/cc232101.aspx */
-                       stream_write_uint32(output, 22); /* Length */
-                       stream_check_size(output, 22);
+                       uniconv = freerdp_uniconv_new();
+                       outStr = freerdp_uniconv_out(uniconv, diskType, &len);
+                       freerdp_uniconv_free(uniconv);
+
+                       stream_write_uint32(output, 12 + len); /* Length */
+                       stream_check_size(output, 12 + len);
                        stream_write_uint32(output,
-                               FILE_CASE_SENSITIVE_SEARCH | 
-                               FILE_CASE_PRESERVED_NAMES | 
+                               FILE_CASE_SENSITIVE_SEARCH |
+                               FILE_CASE_PRESERVED_NAMES |
                                FILE_UNICODE_ON_DISK); /* FileSystemAttributes */
-                       stream_write_uint32(output, 510); /* MaximumComponentNameLength */
-                       stream_write_uint32(output, 10); /* FileSystemNameLength */
-                       stream_write(output, "F\0A\0T\03\02\0", 10); /* FileSystemName */
+                       stream_write_uint32(output, svfst.f_namemax/*510*/); /* MaximumComponentNameLength */
+                       stream_write_uint32(output, len); /* FileSystemNameLength */
+                       stream_write(output, outStr, len); /* FileSystemName (Unicode) */
+                       xfree(outStr);
                        break;
 
                case FileFsFullSizeInformation:
                        /* http://msdn.microsoft.com/en-us/library/cc232104.aspx */
                        stream_write_uint32(output, 32); /* Length */
                        stream_check_size(output, 32);
-                       stream_write_uint64(output, 0x1000000); /* TotalAllocationUnits */
-                       stream_write_uint64(output, 0x800000); /* CallerAvailableAllocationUnits */
-                       stream_write_uint64(output, 0x800000); /* ActualAvailableAllocationUnits */
+                       stream_write_uint64(output, svfst.f_blocks); /* TotalAllocationUnits */
+                       stream_write_uint64(output, svfst.f_bavail); /* CallerAvailableAllocationUnits */
+                       stream_write_uint64(output, svfst.f_bfree); /* AvailableAllocationUnits */
                        stream_write_uint32(output, 1); /* SectorsPerAllocationUnit */
-                       stream_write_uint32(output, 0x400); /* BytesPerSector */
+                       stream_write_uint32(output, svfst.f_bsize); /* BytesPerSector */
                        break;
 
                case FileFsDeviceInformation:
@@ -601,7 +631,7 @@ static void disk_free(DEVICE* device)
 
        freerdp_thread_stop(disk->thread);
        freerdp_thread_free(disk->thread);
-       
+
        while ((irp = (IRP*)list_dequeue(disk->irp_list)) != NULL)
                irp->Discard(irp);
        list_free(disk->irp_list);