2015-12-18 Christian Franke
* 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
+#include
+#include
+
+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