kernel32: Implement GetVolumeInformationByHandleW().

Signed-off-by: Zebediah Figura <zfigura@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Zebediah Figura 2020-04-08 16:06:07 -05:00 committed by Alexandre Julliard
parent 4b2f8c80fb
commit 928d1e6447
2 changed files with 119 additions and 14 deletions

View File

@ -60,6 +60,7 @@ static BOOL (WINAPI *pGetVolumePathNameA)(LPCSTR, LPSTR, DWORD);
static BOOL (WINAPI *pGetVolumePathNamesForVolumeNameA)(LPCSTR, LPSTR, DWORD, LPDWORD);
static BOOL (WINAPI *pGetVolumePathNamesForVolumeNameW)(LPCWSTR, LPWSTR, DWORD, LPDWORD);
static BOOL (WINAPI *pCreateSymbolicLinkA)(const char *, const char *, DWORD);
static BOOL (WINAPI *pGetVolumeInformationByHandleW)(HANDLE, WCHAR *, DWORD, DWORD *, DWORD *, DWORD *, WCHAR *, DWORD);
/* ############################### */
@ -1520,6 +1521,71 @@ static void test_mounted_folder(void)
ok(ret, "got error %u\n", GetLastError());
}
static void test_GetVolumeInformationByHandle(void)
{
char buffer[50] DECLSPEC_ALIGN(8);
FILE_FS_ATTRIBUTE_INFORMATION *attr_info = (void *)buffer;
FILE_FS_VOLUME_INFORMATION *volume_info = (void *)buffer;
DWORD serial, filename_len, flags;
WCHAR label[20], fsname[20];
IO_STATUS_BLOCK io;
HANDLE file;
NTSTATUS status;
BOOL ret;
if (!pGetVolumeInformationByHandleW)
{
win_skip("GetVolumeInformationByHandleW is not present.\n");
return;
}
file = CreateFileA( "C:/windows", 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL );
ok(file != INVALID_HANDLE_VALUE, "failed to open file, error %u\n", GetLastError());
SetLastError(0xdeadbeef);
ret = pGetVolumeInformationByHandleW( INVALID_HANDLE_VALUE, label, ARRAY_SIZE(label), &serial,
&filename_len, &flags, fsname, ARRAY_SIZE(fsname) );
ok(!ret, "expected failure\n");
ok(GetLastError() == ERROR_INVALID_HANDLE, "got error %u\n", GetLastError());
ret = pGetVolumeInformationByHandleW( file, NULL, 0, NULL, NULL, NULL, NULL, 0 );
ok(ret, "got error %u\n", GetLastError());
ret = pGetVolumeInformationByHandleW( file, label, ARRAY_SIZE(label), &serial,
&filename_len, &flags, fsname, ARRAY_SIZE(fsname) );
ok(ret, "got error %u\n", GetLastError());
memset(buffer, 0, sizeof(buffer));
status = NtQueryVolumeInformationFile( file, &io, buffer, sizeof(buffer), FileFsAttributeInformation );
ok(!status, "got status %#x\n", status);
ok(flags == attr_info->FileSystemAttributes, "expected flags %#x, got %#x\n",
attr_info->FileSystemAttributes, flags);
ok(filename_len == attr_info->MaximumComponentNameLength, "expected filename_len %u, got %u\n",
attr_info->MaximumComponentNameLength, filename_len);
ok(!wcscmp( fsname, attr_info->FileSystemName ), "expected fsname %s, got %s\n",
debugstr_w( attr_info->FileSystemName ), debugstr_w( fsname ));
ok(wcslen( fsname ) == attr_info->FileSystemNameLength / sizeof(WCHAR),
"expected fsname length %u, got %u\n", attr_info->FileSystemNameLength / sizeof(WCHAR), wcslen( fsname ));
SetLastError(0xdeadbeef);
ret = pGetVolumeInformationByHandleW( file, NULL, 0, NULL, &filename_len, &flags, fsname, 2 );
ok(!ret, "expected failure\n");
ok(GetLastError() == ERROR_BAD_LENGTH, "got error %u\n", GetLastError());
memset(buffer, 0, sizeof(buffer));
status = NtQueryVolumeInformationFile( file, &io, buffer, sizeof(buffer), FileFsVolumeInformation );
ok(!status, "got status %#x\n", status);
ok(serial == volume_info->VolumeSerialNumber, "expected serial %08x, got %08x\n",
volume_info->VolumeSerialNumber, serial);
ok(!wcscmp( label, volume_info->VolumeLabel ), "expected label %s, got %s\n",
debugstr_w( volume_info->VolumeLabel ), debugstr_w( label ));
ok(wcslen( label ) == volume_info->VolumeLabelLength / sizeof(WCHAR),
"expected label length %u, got %u\n", volume_info->VolumeLabelLength / sizeof(WCHAR), wcslen( label ));
CloseHandle( file );
}
START_TEST(volume)
{
hdll = GetModuleHandleA("kernel32.dll");
@ -1535,6 +1601,7 @@ START_TEST(volume)
pGetVolumePathNamesForVolumeNameA = (void *) GetProcAddress(hdll, "GetVolumePathNamesForVolumeNameA");
pGetVolumePathNamesForVolumeNameW = (void *) GetProcAddress(hdll, "GetVolumePathNamesForVolumeNameW");
pCreateSymbolicLinkA = (void *) GetProcAddress(hdll, "CreateSymbolicLinkA");
pGetVolumeInformationByHandleW = (void *) GetProcAddress(hdll, "GetVolumeInformationByHandleW");
test_query_dos_deviceA();
test_dos_devices();
@ -1553,4 +1620,5 @@ START_TEST(volume)
test_GetVolumePathNamesForVolumeNameW();
test_cdrom_ioctl();
test_mounted_folder();
test_GetVolumeInformationByHandle();
}

View File

@ -2117,21 +2117,58 @@ BOOL WINAPI SetVolumeMountPointW(LPCWSTR path, LPCWSTR volume)
/***********************************************************************
* GetVolumeInformationByHandleW (KERNEL32.@)
*/
BOOL WINAPI GetVolumeInformationByHandleW(HANDLE handle, WCHAR *volnamebuf, DWORD volnamesize, DWORD *volserial, DWORD *maxlength, DWORD *flags, WCHAR *fsnamebuf, DWORD fsnamesize)
BOOL WINAPI GetVolumeInformationByHandleW( HANDLE handle, WCHAR *label, DWORD label_len,
DWORD *serial, DWORD *filename_len, DWORD *flags,
WCHAR *fsname, DWORD fsname_len )
{
FIXME("%p %p %d %p %p %p %p %d\n", handle, volnamebuf, volnamesize, volserial, maxlength, flags, fsnamebuf, fsnamesize);
IO_STATUS_BLOCK io;
if(volnamebuf && volnamesize)
*volnamebuf = 0;
if(volserial)
*volserial = 0;
if(maxlength)
*maxlength = 0;
if(flags)
*flags = 0;
if(fsnamebuf && fsnamesize)
*fsnamebuf = 0;
TRACE( "%p\n", handle );
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
if (label || serial)
{
char buffer[sizeof(FILE_FS_VOLUME_INFORMATION) + MAX_PATH * sizeof(WCHAR)];
FILE_FS_VOLUME_INFORMATION *info = (FILE_FS_VOLUME_INFORMATION *)buffer;
if (!set_ntstatus( NtQueryVolumeInformationFile( handle, &io, info, sizeof(buffer),
FileFsVolumeInformation ) ))
return FALSE;
if (label)
{
if (label_len < info->VolumeLabelLength / sizeof(WCHAR) + 1)
{
SetLastError( ERROR_BAD_LENGTH );
return FALSE;
}
memcpy( label, info->VolumeLabel, info->VolumeLabelLength );
label[info->VolumeLabelLength / sizeof(WCHAR)] = 0;
}
if (serial) *serial = info->VolumeSerialNumber;
}
if (filename_len || flags || fsname)
{
char buffer[sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + MAX_PATH * sizeof(WCHAR)];
FILE_FS_ATTRIBUTE_INFORMATION *info = (FILE_FS_ATTRIBUTE_INFORMATION *)buffer;
if (!set_ntstatus( NtQueryVolumeInformationFile( handle, &io, info, sizeof(buffer),
FileFsAttributeInformation ) ))
return FALSE;
if (fsname)
{
if (fsname_len < info->FileSystemNameLength / sizeof(WCHAR) + 1)
{
SetLastError( ERROR_BAD_LENGTH );
return FALSE;
}
memcpy( fsname, info->FileSystemName, info->FileSystemNameLength );
fsname[info->FileSystemNameLength / sizeof(WCHAR)] = 0;
}
if (filename_len) *filename_len = info->MaximumComponentNameLength;
if (flags) *flags = info->FileSystemAttributes;
}
return TRUE;
}