kernel32: Use the NT name to retrieve label and serial in GetVolumeInformationW.
This commit is contained in:
parent
5820f40862
commit
357b50600b
|
@ -209,15 +209,31 @@ static DWORD get_mountmgr_drive_type( LPCWSTR root )
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get the label by reading it from a file at the root of the filesystem */
|
/* get the label by reading it from a file at the root of the filesystem */
|
||||||
static void get_filesystem_label( const WCHAR *device, WCHAR *label, DWORD len )
|
static void get_filesystem_label( const UNICODE_STRING *device, WCHAR *label, DWORD len )
|
||||||
{
|
{
|
||||||
|
static const WCHAR labelW[] = {'.','w','i','n','d','o','w','s','-','l','a','b','e','l',0};
|
||||||
HANDLE handle;
|
HANDLE handle;
|
||||||
WCHAR labelW[] = {'A',':','\\','.','w','i','n','d','o','w','s','-','l','a','b','e','l',0};
|
UNICODE_STRING name;
|
||||||
|
IO_STATUS_BLOCK io;
|
||||||
|
OBJECT_ATTRIBUTES attr;
|
||||||
|
|
||||||
labelW[0] = device[4];
|
label[0] = 0;
|
||||||
handle = CreateFileW( labelW, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
|
|
||||||
OPEN_EXISTING, 0, 0 );
|
attr.Length = sizeof(attr);
|
||||||
if (handle != INVALID_HANDLE_VALUE)
|
attr.RootDirectory = 0;
|
||||||
|
attr.Attributes = OBJ_CASE_INSENSITIVE;
|
||||||
|
attr.ObjectName = &name;
|
||||||
|
attr.SecurityDescriptor = NULL;
|
||||||
|
attr.SecurityQualityOfService = NULL;
|
||||||
|
|
||||||
|
name.MaximumLength = device->Length + sizeof(labelW);
|
||||||
|
name.Length = name.MaximumLength - sizeof(WCHAR);
|
||||||
|
if (!(name.Buffer = HeapAlloc( GetProcessHeap(), 0, name.MaximumLength ))) return;
|
||||||
|
|
||||||
|
memcpy( name.Buffer, device->Buffer, device->Length );
|
||||||
|
memcpy( name.Buffer + device->Length / sizeof(WCHAR), labelW, sizeof(labelW) );
|
||||||
|
if (!NtOpenFile( &handle, GENERIC_READ, &attr, &io, FILE_SHARE_READ|FILE_SHARE_WRITE,
|
||||||
|
FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT ))
|
||||||
{
|
{
|
||||||
char buffer[256], *p;
|
char buffer[256], *p;
|
||||||
DWORD size;
|
DWORD size;
|
||||||
|
@ -230,19 +246,34 @@ static void get_filesystem_label( const WCHAR *device, WCHAR *label, DWORD len )
|
||||||
if (!MultiByteToWideChar( CP_UNIXCP, 0, buffer, -1, label, len ))
|
if (!MultiByteToWideChar( CP_UNIXCP, 0, buffer, -1, label, len ))
|
||||||
label[len-1] = 0;
|
label[len-1] = 0;
|
||||||
}
|
}
|
||||||
else label[0] = 0;
|
RtlFreeUnicodeString( &name );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get the serial number by reading it from a file at the root of the filesystem */
|
/* get the serial number by reading it from a file at the root of the filesystem */
|
||||||
static DWORD get_filesystem_serial( const WCHAR *device )
|
static DWORD get_filesystem_serial( const UNICODE_STRING *device )
|
||||||
{
|
{
|
||||||
|
static const WCHAR serialW[] = {'.','w','i','n','d','o','w','s','-','s','e','r','i','a','l',0};
|
||||||
HANDLE handle;
|
HANDLE handle;
|
||||||
WCHAR serialW[] = {'A',':','\\','.','w','i','n','d','o','w','s','-','s','e','r','i','a','l',0};
|
UNICODE_STRING name;
|
||||||
|
IO_STATUS_BLOCK io;
|
||||||
|
OBJECT_ATTRIBUTES attr;
|
||||||
|
DWORD ret = 0;
|
||||||
|
|
||||||
serialW[0] = device[4];
|
attr.Length = sizeof(attr);
|
||||||
handle = CreateFileW( serialW, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
|
attr.RootDirectory = 0;
|
||||||
OPEN_EXISTING, 0, 0 );
|
attr.Attributes = OBJ_CASE_INSENSITIVE;
|
||||||
if (handle != INVALID_HANDLE_VALUE)
|
attr.ObjectName = &name;
|
||||||
|
attr.SecurityDescriptor = NULL;
|
||||||
|
attr.SecurityQualityOfService = NULL;
|
||||||
|
|
||||||
|
name.MaximumLength = device->Length + sizeof(serialW);
|
||||||
|
name.Length = name.MaximumLength - sizeof(WCHAR);
|
||||||
|
if (!(name.Buffer = HeapAlloc( GetProcessHeap(), 0, name.MaximumLength ))) return 0;
|
||||||
|
|
||||||
|
memcpy( name.Buffer, device->Buffer, device->Length );
|
||||||
|
memcpy( name.Buffer + device->Length / sizeof(WCHAR), serialW, sizeof(serialW) );
|
||||||
|
if (!NtOpenFile( &handle, GENERIC_READ, &attr, &io, FILE_SHARE_READ|FILE_SHARE_WRITE,
|
||||||
|
FILE_SYNCHRONOUS_IO_NONALERT ))
|
||||||
{
|
{
|
||||||
char buffer[32];
|
char buffer[32];
|
||||||
DWORD size;
|
DWORD size;
|
||||||
|
@ -250,9 +281,10 @@ static DWORD get_filesystem_serial( const WCHAR *device )
|
||||||
if (!ReadFile( handle, buffer, sizeof(buffer)-1, &size, NULL )) size = 0;
|
if (!ReadFile( handle, buffer, sizeof(buffer)-1, &size, NULL )) size = 0;
|
||||||
CloseHandle( handle );
|
CloseHandle( handle );
|
||||||
buffer[size] = 0;
|
buffer[size] = 0;
|
||||||
return strtoul( buffer, NULL, 16 );
|
ret = strtoul( buffer, NULL, 16 );
|
||||||
}
|
}
|
||||||
else return 0;
|
RtlFreeUnicodeString( &name );
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -377,8 +409,8 @@ static enum fs_type VOLUME_ReadCDSuperblock( HANDLE handle, BYTE *buff )
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
* VOLUME_GetSuperblockLabel
|
* VOLUME_GetSuperblockLabel
|
||||||
*/
|
*/
|
||||||
static void VOLUME_GetSuperblockLabel( const WCHAR *device, enum fs_type type, const BYTE *superblock,
|
static void VOLUME_GetSuperblockLabel( const UNICODE_STRING *device, enum fs_type type,
|
||||||
WCHAR *label, DWORD len )
|
const BYTE *superblock, WCHAR *label, DWORD len )
|
||||||
{
|
{
|
||||||
const BYTE *label_ptr = NULL;
|
const BYTE *label_ptr = NULL;
|
||||||
DWORD label_len;
|
DWORD label_len;
|
||||||
|
@ -431,7 +463,8 @@ static void VOLUME_GetSuperblockLabel( const WCHAR *device, enum fs_type type, c
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
* VOLUME_GetSuperblockSerial
|
* VOLUME_GetSuperblockSerial
|
||||||
*/
|
*/
|
||||||
static DWORD VOLUME_GetSuperblockSerial( const WCHAR *device, enum fs_type type, const BYTE *superblock )
|
static DWORD VOLUME_GetSuperblockSerial( const UNICODE_STRING *device, enum fs_type type,
|
||||||
|
const BYTE *superblock )
|
||||||
{
|
{
|
||||||
switch(type)
|
switch(type)
|
||||||
{
|
{
|
||||||
|
@ -515,7 +548,6 @@ BOOL WINAPI GetVolumeInformationW( LPCWSTR root, LPWSTR label, DWORD label_len,
|
||||||
static const WCHAR cdfsW[] = {'C','D','F','S',0};
|
static const WCHAR cdfsW[] = {'C','D','F','S',0};
|
||||||
static const WCHAR default_rootW[] = {'\\',0};
|
static const WCHAR default_rootW[] = {'\\',0};
|
||||||
|
|
||||||
WCHAR device[] = {'\\','\\','.','\\','A',':',0};
|
|
||||||
HANDLE handle;
|
HANDLE handle;
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
UNICODE_STRING nt_name;
|
UNICODE_STRING nt_name;
|
||||||
|
@ -539,7 +571,6 @@ BOOL WINAPI GetVolumeInformationW( LPCWSTR root, LPWSTR label, DWORD label_len,
|
||||||
SetLastError( ERROR_INVALID_NAME );
|
SetLastError( ERROR_INVALID_NAME );
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
device[4] = nt_name.Buffer[4];
|
|
||||||
|
|
||||||
/* try to open the device */
|
/* try to open the device */
|
||||||
|
|
||||||
|
@ -585,8 +616,8 @@ BOOL WINAPI GetVolumeInformationW( LPCWSTR root, LPWSTR label, DWORD label_len,
|
||||||
TRACE( "%s: found fs type %d\n", debugstr_w(nt_name.Buffer), type );
|
TRACE( "%s: found fs type %d\n", debugstr_w(nt_name.Buffer), type );
|
||||||
if (type == FS_ERROR) goto done;
|
if (type == FS_ERROR) goto done;
|
||||||
|
|
||||||
if (label && label_len) VOLUME_GetSuperblockLabel( device, type, superblock, label, label_len );
|
if (label && label_len) VOLUME_GetSuperblockLabel( &nt_name, type, superblock, label, label_len );
|
||||||
if (serial) *serial = VOLUME_GetSuperblockSerial( device, type, superblock );
|
if (serial) *serial = VOLUME_GetSuperblockSerial( &nt_name, type, superblock );
|
||||||
goto fill_fs_info;
|
goto fill_fs_info;
|
||||||
}
|
}
|
||||||
else TRACE( "cannot open device %s: err %d\n", debugstr_w(nt_name.Buffer), GetLastError() );
|
else TRACE( "cannot open device %s: err %d\n", debugstr_w(nt_name.Buffer), GetLastError() );
|
||||||
|
@ -608,8 +639,8 @@ BOOL WINAPI GetVolumeInformationW( LPCWSTR root, LPWSTR label, DWORD label_len,
|
||||||
}
|
}
|
||||||
if (info.DeviceType == FILE_DEVICE_CD_ROM_FILE_SYSTEM) type = FS_ISO9660;
|
if (info.DeviceType == FILE_DEVICE_CD_ROM_FILE_SYSTEM) type = FS_ISO9660;
|
||||||
|
|
||||||
if (label && label_len) get_filesystem_label( device, label, label_len );
|
if (label && label_len) get_filesystem_label( &nt_name, label, label_len );
|
||||||
if (serial) *serial = get_filesystem_serial( device );
|
if (serial) *serial = get_filesystem_serial( &nt_name );
|
||||||
|
|
||||||
fill_fs_info: /* now fill in the information that depends on the file system type */
|
fill_fs_info: /* now fill in the information that depends on the file system type */
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue