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