Hello Antonio,
Antonio Diaz Diaz wrote:
Christian Franke wrote:
the attached patch adds device_id() for Cygwin. Tested with 32- and
64-bit Cygwin.
Should be safe to include in 1.21 as no other platform is affected.
Thanks for the patch.
The patch is mostly ok but, isn't there a safer way of implementing
this for Cygwin? I don't like neither the use of an union nor the
unverified access to the 'raw' member in the union
('data.raw[data.desc.VendorIdOffset]', for example). Most probably
this will cause problems with '-fstrict-aliasing', or even an invalid
memory access.
New attached new patch avoids the union, does strict index checks and
ensures zero termination. It now also allows that an ATA IDENTIFY string
is only in VendorId or ProductId which occasionally happened with some
older drives.
Tested with g++ 4.9.3 and clang++ 3.5.2.
BTW: I guess both approaches (char buffer + cast to *struct, union of
buf + struct) are safe:
"A character type may alias any other type."
"Even with -fstrict-aliasing, type-punning is allowed, provided the
memory is accessed through the union type."
https://gcc.gnu.org/onlinedocs/gcc-4.9.3/gcc/Optimize-Options.html#index-fstrict-aliasing-926
Best regards,
Christian
2015-12-18 Christian Franke <[email protected]>
* non_posix.cc: Add device_id() for Cygwin.
diff --git a/non_posix.cc b/non_posix.cc
index 480c71d..7d7217f 100644
--- a/non_posix.cc
+++ b/non_posix.cc
@@ -56,6 +56,57 @@ const char * device_id( const int fd )
return id_str.c_str();
}
+#elif defined(__CYGWIN__)
+
+#include <cstddef>
+#include <io.h>
+#include <windows.h>
+
+const char * device_id( const int fd )
+ {
+ HANDLE h = (HANDLE) _get_osfhandle( fd );
+ if( h == INVALID_HANDLE_VALUE )
+ return 0;
+
+ STORAGE_PROPERTY_QUERY query =
+ { StorageDeviceProperty, PropertyStandardQuery, { 0 } };
+ char buf[256] = "";
+ DWORD size = 0;
+
+ if( !DeviceIoControl( h, IOCTL_STORAGE_QUERY_PROPERTY, &query, sizeof(query),
+ &buf, sizeof(buf)-1, &size, (LPOVERLAPPED)0 ) )
+ return 0;
+
+ const STORAGE_DEVICE_DESCRIPTOR * const pdesc =
+ reinterpret_cast< STORAGE_DEVICE_DESCRIPTOR * >( buf );
+ const unsigned first =
+ offsetof( STORAGE_DEVICE_DESCRIPTOR, RawDeviceProperties );
+
+ static std::string id_str;
+ if( first <= pdesc->VendorIdOffset && pdesc->VendorIdOffset < size )
+ id_str = &buf[pdesc->VendorIdOffset];
+ if( first <= pdesc->ProductIdOffset && pdesc->ProductIdOffset < size )
+ {
+ if( pdesc->BusType != BusTypeAta
+ && pdesc->BusType != 0x0b ) // BusTypeSata
+ id_str += ' ';
+ id_str += &buf[pdesc->ProductIdOffset];
+ }
+ sanitize_string( id_str );
+ if( id_str.empty() )
+ return 0;
+
+ if( first <= pdesc->SerialNumberOffset && pdesc->SerialNumberOffset < size )
+ {
+ std::string id_serial( &buf[pdesc->SerialNumberOffset] );
+ sanitize_string( id_serial );
+ if ( !id_serial.empty() )
+ { id_str += "::"; id_str += id_serial; }
+ }
+
+ return id_str.c_str();
+ }
+
#else // use linux by default
#include <linux/hdreg.h>
_______________________________________________
Bug-ddrescue mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/bug-ddrescue