Module: wine Branch: master Commit: 928d1e64475f8936967943675754a0cacda48b3a URL: https://source.winehq.org/git/wine.git/?a=commit;h=928d1e64475f8936967943675...
Author: Zebediah Figura z.figura12@gmail.com Date: Wed Apr 8 16:06:07 2020 -0500
kernel32: Implement GetVolumeInformationByHandleW().
Signed-off-by: Zebediah Figura zfigura@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/kernel32/tests/volume.c | 68 ++++++++++++++++++++++++++++++++++++++++++++ dlls/kernel32/volume.c | 67 +++++++++++++++++++++++++++++++++---------- 2 files changed, 120 insertions(+), 15 deletions(-)
diff --git a/dlls/kernel32/tests/volume.c b/dlls/kernel32/tests/volume.c index 37d15fd3f8..126df5b8a0 100644 --- a/dlls/kernel32/tests/volume.c +++ b/dlls/kernel32/tests/volume.c @@ -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(); } diff --git a/dlls/kernel32/volume.c b/dlls/kernel32/volume.c index 4f0f4a0a0f..7555dd9e95 100644 --- a/dlls/kernel32/volume.c +++ b/dlls/kernel32/volume.c @@ -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); - - if(volnamebuf && volnamesize) - *volnamebuf = 0; - if(volserial) - *volserial = 0; - if(maxlength) - *maxlength = 0; - if(flags) - *flags = 0; - if(fsnamebuf && fsnamesize) - *fsnamebuf = 0; + IO_STATUS_BLOCK io;
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + TRACE( "%p\n", handle ); + + 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; }