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