[PATCH] kernel32: Add support for detecting volume information with libudev.
Zebediah Figura
z.figura12 at gmail.com
Sun Jul 23 23:26:45 CDT 2017
Using GetVolumeInformation may fail due to lack of permissions; e.g.
when the drive was mounted as root. This patch uses libudev, if it
is available, to retrieve the volume label, serial number, and type.
Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
---
dlls/kernel32/Makefile.in | 3 +-
dlls/kernel32/volume.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 90 insertions(+), 1 deletion(-)
diff --git a/dlls/kernel32/Makefile.in b/dlls/kernel32/Makefile.in
index 1399859..a265625 100644
--- a/dlls/kernel32/Makefile.in
+++ b/dlls/kernel32/Makefile.in
@@ -2,7 +2,8 @@ EXTRADEFS = -D_KERNEL32_ -D_NORMALIZE_
MODULE = kernel32.dll
IMPORTLIB = kernel32
IMPORTS = winecrt0 ntdll
-EXTRALIBS = $(COREFOUNDATION_LIBS) $(POLL_LIBS)
+EXTRALIBS = $(COREFOUNDATION_LIBS) $(POLL_LIBS) $(UDEV_LIBS)
+EXTRAINCL = $(UDEV_CFLAGS)
EXTRADLLFLAGS = -nodefaultlibs -Wb,-F,KERNEL32.dll -Wl,--image-base,0x7b400000
C_SRCS = \
diff --git a/dlls/kernel32/volume.c b/dlls/kernel32/volume.c
index b4163f0..23631fe 100644
--- a/dlls/kernel32/volume.c
+++ b/dlls/kernel32/volume.c
@@ -28,6 +28,9 @@
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
+#ifdef HAVE_UDEV
+#include <libudev.h>
+#endif
#include "ntstatus.h"
#define WIN32_NO_STATUS
@@ -679,6 +682,87 @@ static DWORD VOLUME_GetAudioCDSerial( const CDROM_TOC *toc )
return serial;
}
+#ifdef HAVE_UDEV
+static enum fs_type get_udev_information( LPCWSTR root, LPWSTR label, DWORD label_len,
+ DWORD *serial )
+{
+ WCHAR devname[] = {' ',':',':',0};
+ char *unix_path;
+ struct stat st;
+ struct udev *udev_context = NULL;
+ struct udev_device *udev_device = NULL;
+ const char *device_label, *device_serial, *device_type;
+ DWORD serial_low, serial_high;
+ enum fs_type type = FS_ERROR;
+
+ devname[0] = root[0];
+ unix_path = get_dos_device_path(devname);
+
+ if (stat(unix_path, &st) != 0)
+ {
+ WARN("couldn't stat %s\n", debugstr_a(unix_path));
+ goto end;
+ }
+
+ if (!S_ISBLK(st.st_mode))
+ goto end;
+
+ if (!(udev_context = udev_new()))
+ {
+ ERR("couldn't create udev context\n");
+ goto end;
+ }
+
+ if (!(udev_device = udev_device_new_from_devnum(udev_context, 'b', st.st_rdev)))
+ {
+ ERR("couldn't create udev device\n");
+ goto end;
+ }
+
+ device_label = udev_device_get_property_value(udev_device, "ID_FS_LABEL_ENC");
+ device_serial = udev_device_get_property_value(udev_device, "ID_FS_UUID_ENC");
+ device_type = udev_device_get_property_value(udev_device, "ID_FS_TYPE");
+
+ if (label)
+ {
+ if (device_label)
+ {
+ if (!MultiByteToWideChar(CP_UNIXCP, 0, device_label, -1, label, label_len))
+ label[label_len-1] = 0;
+ }
+ else
+ label[0] = 0;
+ }
+ if (serial)
+ {
+ if (device_serial && sscanf(device_serial, "%04x-%04x", &serial_high, &serial_low) == 2)
+ *serial = (serial_high << 16) | serial_low;
+ else
+ *serial = 0;
+ }
+ if (!device_type)
+ type = FS_UNKNOWN;
+ else if (!strcmp(device_type, "iso9660"))
+ type = FS_ISO9660;
+ else if (!strcmp(device_type, "vfat"))
+ {
+ const char *fat_version = udev_device_get_property_value(udev_device, "ID_FS_VERSION");
+ if (fat_version && (!strcmp(fat_version, "FAT12") || !strcmp(fat_version, "FAT16")))
+ type = FS_FAT1216;
+ else
+ type = FS_FAT32;
+ }
+ else if (!strcmp(device_type, "udf"))
+ type = FS_UDF;
+ else
+ type = FS_UNKNOWN;
+end:
+ if (udev_device) udev_device_unref(udev_device);
+ if (udev_context) udev_unref(udev_context);
+ HeapFree(GetProcessHeap(), 0, unix_path);
+ return type;
+}
+#endif /* HAVE_UDEV */
/***********************************************************************
* GetVolumeInformationW (KERNEL32.@)
@@ -777,6 +861,10 @@ BOOL WINAPI GetVolumeInformationW( LPCWSTR root, LPWSTR label, DWORD label_len,
CloseHandle( handle );
goto fill_fs_info;
}
+#ifdef HAVE_UDEV
+ else if ((type = get_udev_information(root, label, label_len, serial)) != FS_ERROR)
+ goto fill_fs_info;
+#endif
else TRACE( "cannot open device %s: %x\n", debugstr_w(nt_name.Buffer), status );
/* we couldn't open the device, fallback to default strategy */
--
2.7.4
More information about the wine-patches
mailing list