Zebediah Figura : kernel32: Implement GetVolumeInformationByHandleW().
Alexandre Julliard
julliard at winehq.org
Thu Apr 9 16:04:45 CDT 2020
Module: wine
Branch: master
Commit: 928d1e64475f8936967943675754a0cacda48b3a
URL: https://source.winehq.org/git/wine.git/?a=commit;h=928d1e64475f8936967943675754a0cacda48b3a
Author: Zebediah Figura <z.figura12 at gmail.com>
Date: Wed Apr 8 16:06:07 2020 -0500
kernel32: Implement GetVolumeInformationByHandleW().
Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at 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;
}
More information about the wine-cvs
mailing list