From 140e6c1cb487480fd32382cafa1603eb614f1dd2 Mon Sep 17 00:00:00 2001 From: Christophe Grenier Date: Mon, 14 Apr 2008 20:16:16 +0200 Subject: [PATCH] Use IOCTL_DISK_GET_LENGTH_INFO to get disk size under Windows, it works with Windows Dynamic Disk. --- src/hdaccess.c | 11 ++++++++--- src/win32.c | 37 ++++++++++++++++++++++++++++--------- 2 files changed, 36 insertions(+), 12 deletions(-) diff --git a/src/hdaccess.c b/src/hdaccess.c index 129501e7..9a1d2d34 100644 --- a/src/hdaccess.c +++ b/src/hdaccess.c @@ -877,7 +877,8 @@ static int scsi_query_product_info (const int hd_h, char **vendor, char **produc static void disk_get_model(const int hd_h, disk_t *dev, const int verbose) { #ifdef TARGET_LINUX - if(dev->model==NULL) + if(dev->model!=NULL) + return; { /* Use modern /sys interface for SCSI device */ char *vendor; @@ -894,7 +895,8 @@ static void disk_get_model(const int hd_h, disk_t *dev, const int verbose) } #endif #ifdef HDIO_GET_IDENTITY - if(dev->model==NULL) + if(dev->model!=NULL) + return; { struct hd_driveid hdi; if (ioctl (hd_h, HDIO_GET_IDENTITY, &hdi)==0) @@ -908,7 +910,8 @@ static void disk_get_model(const int hd_h, disk_t *dev, const int verbose) } #endif #if defined(TARGET_LINUX) && defined(SCSI_IOCTL_GET_IDLUN) && defined(SCSI_IOCTL_SEND_COMMAND) - if(dev->model==NULL) + if(dev->model!=NULL) + return; { /* Uses direct queries via the deprecated ioctl SCSI_IOCTL_SEND_COMMAND */ char *vendor=NULL; @@ -924,6 +927,8 @@ static void disk_get_model(const int hd_h, disk_t *dev, const int verbose) } #endif #if defined(__CYGWIN__) || defined(__MINGW32__) + if(dev->model!=NULL) + return; { HANDLE handle; #if defined(__CYGWIN__) diff --git a/src/win32.c b/src/win32.c index 2be36c98..0972f1b8 100644 --- a/src/win32.c +++ b/src/win32.c @@ -96,6 +96,20 @@ unsigned int disk_get_sector_size_win32(HANDLE handle, const char *device, const uint64_t disk_get_size_win32(HANDLE handle, const char *device, const int verbose) { uint64_t disk_size=0; + { + GET_LENGTH_INFORMATION buf; + DWORD i; + if (DeviceIoControl(handle, IOCTL_DISK_GET_LENGTH_INFO, NULL, 0, &buf, sizeof(buf), &i, NULL)) + { + disk_size=(uint64_t)buf.Length.QuadPart; + log_info("disk_get_size_win32 IOCTL_DISK_GET_LENGTH_INFO(%s)=%llu\n", + device, (long long unsigned)disk_size); + return disk_size; + } + } + disk_size=filewin32_getfilesize(handle, device); + if(disk_size!=0) + return disk_size; if(device[0]!='\0' && device[1]!='\0' && device[2]!='\0' && device[3]!='\0' && device[4]!='\0') { uint64_t i64FreeBytesToCaller, i64TotalBytes, i64FreeBytes; @@ -105,7 +119,8 @@ uint64_t disk_get_size_win32(HANDLE handle, const char *device, const int verbos (PULARGE_INTEGER)&i64FreeBytes)!=0) { if(verbose>1) - log_info("GetDiskFreeSpaceEx %s: ok\n", device); + log_info("disk_get_size_win32 GetDiskFreeSpaceEx %s: %llu\n", + device, (long long unsigned)i64TotalBytes); return i64TotalBytes; } } @@ -117,12 +132,10 @@ uint64_t disk_get_size_win32(HANDLE handle, const char *device, const int verbos { disk_size=(uint64_t)geometry_ex.DiskSize.QuadPart; if(verbose>1) - log_info("IOCTL_DISK_GET_DRIVE_GEOMETRY_EX %s: ok\n", device); + log_info("disk_get_size_win32 IOCTL_DISK_GET_DRIVE_GEOMETRY_EX %s: %llu\n", + device, (long long unsigned)disk_size); } } - if(disk_size!=0) - return disk_size; - disk_size=filewin32_getfilesize(handle, device); if(disk_size!=0) return disk_size; return filewin32_setfilepointer(handle, device); @@ -173,6 +186,7 @@ struct info_file_win32_struct static uint64_t filewin32_getfilesize(HANDLE handle, const char *device) { + uint64_t disk_size; DWORD lpFileSizeLow; DWORD lpFileSizeHigh; lpFileSizeLow=GetFileSize(handle,&lpFileSizeHigh); @@ -192,12 +206,15 @@ static uint64_t filewin32_getfilesize(HANDLE handle, const char *device) LocalFree(lpMsgBuf); return 0; } - log_verbose("filewin32_getfilesize(%s) ok\n",device); - return lpFileSizeLow+((uint64_t)lpFileSizeHigh>>32); + disk_size=lpFileSizeLow+((uint64_t)lpFileSizeHigh>>32); + log_verbose("filewin32_getfilesize(%s)=%llu\n", + device, (long long unsigned)disk_size ); + return disk_size; } static uint64_t filewin32_setfilepointer(HANDLE handle, const char *device) { + uint64_t disk_size; LARGE_INTEGER li; li.QuadPart = 0; li.LowPart = SetFilePointer(handle, li.LowPart, &li.HighPart, FILE_END); @@ -217,8 +234,10 @@ static uint64_t filewin32_setfilepointer(HANDLE handle, const char *device) LocalFree(lpMsgBuf); return 0; } - log_verbose("filewin32_setfilepointer(%s) ok\n",device); - return li.LowPart+((uint64_t)li.HighPart>>32); + disk_size=li.LowPart+((uint64_t)li.HighPart>>32); + log_verbose("filewin32_setfilepointer(%s)=%llu\n", + device, (long long unsigned)disk_size ); + return disk_size; } disk_t *file_test_availability_win32(const char *device, const int verbose, const arch_fnct_t *arch, int testdisk_mode)