Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=49160 Signed-off-by: Hans Leidekker hans@codeweavers.com --- dlls/wbemprox/builtin.c | 40 +++++++++++++++++++++++++++++++++++-- dlls/wbemprox/tests/query.c | 26 ++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 2 deletions(-)
diff --git a/dlls/wbemprox/builtin.c b/dlls/wbemprox/builtin.c index ddd12d6ebcb..6a35737da59 100644 --- a/dlls/wbemprox/builtin.c +++ b/dlls/wbemprox/builtin.c @@ -44,6 +44,8 @@ #include "ntsecapi.h" #include "winspool.h" #include "setupapi.h" +#define WINE_MOUNTMGR_EXTENSIONS +#include <ddk/mountmgr.h>
#include "wine/asm.h" #include "wine/debug.h" @@ -140,7 +142,7 @@ static const struct column col_diskdrive[] = { L"MediaType", CIM_STRING }, { L"Model", CIM_STRING }, { L"PNPDeviceID", CIM_STRING }, - { L"SerialNumber", CIM_STRING }, + { L"SerialNumber", CIM_STRING|COL_FLAG_DYNAMIC }, { L"Size", CIM_UINT64 }, }; static const struct column col_diskdrivetodiskpartition[] = @@ -2081,6 +2083,40 @@ static UINT64 get_freespace( const WCHAR *dir, UINT64 *disksize ) } return free.QuadPart; } +static WCHAR *get_diskdrive_serialnumber( WCHAR drive_letter ) +{ + WCHAR *ret = NULL; + struct mountmgr_unix_drive input; + struct mountmgr_unix_drive *data; + HANDLE handle; + DWORD size = 256; + + memset( &input, 0, sizeof(input) ); + input.letter = drive_letter; + + if ((handle = CreateFileW( MOUNTMGR_DOS_DEVICE_NAME, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, + NULL, OPEN_EXISTING, 0, 0 )) == INVALID_HANDLE_VALUE) goto done; + for (;;) + { + if (!(data = heap_alloc( size ))) break; + + if (DeviceIoControl( handle, IOCTL_MOUNTMGR_QUERY_UNIX_DRIVE, &input, sizeof(input), data, size, NULL, NULL )) + { + if (data->disk_serial_offset) ret = heap_strdupAW( (const char *)data + data->disk_serial_offset ); + heap_free( data ); + break; + } + + heap_free( data ); + if (GetLastError() == ERROR_MORE_DATA) size = data->size; + else break; + } + CloseHandle( handle ); + +done: + if (!ret) return heap_strdupW( L"WINEHDISK" ); + return ret; +}
static enum fill_status fill_diskdrive( struct table *table, const struct expr *cond ) { @@ -2114,7 +2150,7 @@ static enum fill_status fill_diskdrive( struct table *table, const struct expr * rec->mediatype = (type == DRIVE_FIXED) ? L"Fixed hard disk" : L"Removable media"; rec->model = L"Wine Disk Drive"; rec->pnpdevice_id = L"IDE\Disk\VEN_WINE"; - rec->serialnumber = L"WINEHDISK"; + rec->serialnumber = get_diskdrive_serialnumber( root[0] ); get_freespace( root, &size ); rec->size = size; if (!match_row( table, row, cond, &status )) diff --git a/dlls/wbemprox/tests/query.c b/dlls/wbemprox/tests/query.c index a9b4910ebfa..578e9308df7 100644 --- a/dlls/wbemprox/tests/query.c +++ b/dlls/wbemprox/tests/query.c @@ -1456,6 +1456,31 @@ static void test_Win32_DesktopMonitor( IWbemServices *services ) SysFreeString( wql ); }
+static void test_Win32_DiskDrive( IWbemServices *services ) +{ + BSTR wql = SysAllocString( L"wql" ), query = SysAllocString( L"SELECT * FROM Win32_DiskDrive" ); + IEnumWbemClassObject *result; + IWbemClassObject *obj; + HRESULT hr; + DWORD count; + + hr = IWbemServices_ExecQuery( services, wql, query, 0, NULL, &result ); + ok( hr == S_OK, "got %08x\n", hr ); + + for (;;) + { + hr = IEnumWbemClassObject_Next( result, 10000, 1, &obj, &count ); + if (hr != S_OK) break; + + check_property( obj, L"DeviceID", VT_BSTR, CIM_STRING ); + IWbemClassObject_Release( obj ); + } + + IEnumWbemClassObject_Release( result ); + SysFreeString( query ); + SysFreeString( wql ); +} + static void test_Win32_DisplayControllerConfiguration( IWbemServices *services ) { BSTR wql = SysAllocString( L"wql" ); @@ -1561,6 +1586,7 @@ START_TEST(query) test_Win32_ComputerSystemProduct( services ); test_Win32_Bios( services ); test_Win32_DesktopMonitor( services ); + test_Win32_DiskDrive( services ); test_Win32_DisplayControllerConfiguration( services ); test_Win32_IP4RouteTable( services ); test_Win32_OperatingSystem( services );
Hans Leidekker hans@codeweavers.com writes:
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=49160 Signed-off-by: Hans Leidekker hans@codeweavers.com
dlls/wbemprox/builtin.c | 40 +++++++++++++++++++++++++++++++++++-- dlls/wbemprox/tests/query.c | 26 ++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 2 deletions(-)
diff --git a/dlls/wbemprox/builtin.c b/dlls/wbemprox/builtin.c index ddd12d6ebcb..6a35737da59 100644 --- a/dlls/wbemprox/builtin.c +++ b/dlls/wbemprox/builtin.c @@ -44,6 +44,8 @@ #include "ntsecapi.h" #include "winspool.h" #include "setupapi.h" +#define WINE_MOUNTMGR_EXTENSIONS +#include <ddk/mountmgr.h>
Couldn't this go through some Win32 APIs instead of directly accessing mountmgr?
On Thu, May 21, 2020 at 12:48 PM Alexandre Julliard julliard@winehq.org wrote:
... Couldn't this go through some Win32 APIs instead of directly accessing mountmgr?
GetVolumeInformationW
(I'm playing around in this area to try and rebase a patch)
Best, Erich
On 5/21/20 3:50 PM, Erich E. Hoover wrote:
On Thu, May 21, 2020 at 12:48 PM Alexandre Julliard julliard@winehq.org wrote:
... Couldn't this go through some Win32 APIs instead of directly accessing mountmgr?
GetVolumeInformationW
That retrieves the volume (aka filesystem) serial number, not the disk drive serial number. The latter is distinguished by being alphanumeric and more than 8 bytes long.
My guess is IOCTL_STORAGE_GET_MEDIA_SERIAL_NUMBER, but I haven't tried to verify this.
(I'm playing around in this area to try and rebase a patch)
Best, Erich
On Thu, May 21, 2020 at 2:59 PM Zebediah Figura zfigura@codeweavers.com wrote:
On 5/21/20 3:50 PM, Erich E. Hoover wrote:
On Thu, May 21, 2020 at 12:48 PM Alexandre Julliard julliard@winehq.org wrote:
... Couldn't this go through some Win32 APIs instead of directly accessing mountmgr?
GetVolumeInformationW
That retrieves the volume (aka filesystem) serial number, not the disk drive serial number. The latter is distinguished by being alphanumeric and more than 8 bytes long.
My guess is IOCTL_STORAGE_GET_MEDIA_SERIAL_NUMBER, but I haven't tried to verify this. ...
Sorry, was trying to be helpful and didn't pay close enough attention. If that ioctl is correct then probably the answer is that it needs to be implemented, as it doesn't look like we have support for it at the moment.
Best, Erich
On Thu, May 21, 2020 at 4:26 PM Erich E. Hoover erich.e.hoover@gmail.com wrote:
On Thu, May 21, 2020 at 2:59 PM Zebediah Figura zfigura@codeweavers.com wrote:
... My guess is IOCTL_STORAGE_GET_MEDIA_SERIAL_NUMBER, but I haven't tried to verify this. ...
Sorry, was trying to be helpful and didn't pay close enough attention. If that ioctl is correct then probably the answer is that it needs to be implemented, as it doesn't look like we have support for it at the moment.
I think the correct one for this is IOCTL_STORAGE_QUERY_PROPERTY with StorageDeviceProperty, which is only partially implemented right now.
Unfortunately for me, the thing I'm trying to do _is_ work with the volume information - which looks like it involves figuring out how to implement IRP_MJ_QUERY_VOLUME_INFORMATION.
Best, Erich
On 5/23/20 1:49 PM, Erich E. Hoover wrote:
On Thu, May 21, 2020 at 4:26 PM Erich E. Hoover erich.e.hoover@gmail.com wrote:
On Thu, May 21, 2020 at 2:59 PM Zebediah Figura zfigura@codeweavers.com wrote:
... My guess is IOCTL_STORAGE_GET_MEDIA_SERIAL_NUMBER, but I haven't tried to verify this. ...
Sorry, was trying to be helpful and didn't pay close enough attention. If that ioctl is correct then probably the answer is that it needs to be implemented, as it doesn't look like we have support for it at the moment.
I think the correct one for this is IOCTL_STORAGE_QUERY_PROPERTY with StorageDeviceProperty, which is only partially implemented right now.
Unfortunately for me, the thing I'm trying to do _is_ work with the volume information - which looks like it involves figuring out how to implement IRP_MJ_QUERY_VOLUME_INFORMATION.
Does this have to do with the problem mentioned in [1]?
Wiring up IRP_MJ_QUERY_VOLUME_INFORMATION in mountmgr is one possible approach, and maybe even the best one. I'm not really sure, though. (Of course, I'm also not Alexandre.)
It'd kind of be nice for volume information to be implemented in one place and not two, but this requires a lot of work (probably fully implementing opening files by device path) which isn't really justified by anything other than one failing test. Nevertheless, I have some ideas I've described in [2].
[1] https://www.winehq.org/pipermail/wine-devel/2020-April/164070.html
[2] https://bugs.winehq.org/show_bug.cgi?id=39569#c3
Best, Erich
On Sat, May 23, 2020 at 1:01 PM Zebediah Figura z.figura12@gmail.com wrote:
On 5/23/20 1:49 PM, Erich E. Hoover wrote:
... Unfortunately for me, the thing I'm trying to do _is_ work with the volume information - which looks like it involves figuring out how to implement IRP_MJ_QUERY_VOLUME_INFORMATION.
Does this have to do with the problem mentioned in [1]?
Yes, I'd like to fix some rebase issues with my junction point patches and that now involves GetVolumeInformation getting pushed down further. The right way to do this looks like implementing GetVolumeInformation on top of GetVolumeInformationByHandle. To not break ??\Volume{...}\ this looks like it means that NtQueryVolumeInformationFile needs to be able to issue IRP_MJ_QUERY_VOLUME_INFORMATION to the mountmgr.
Wiring up IRP_MJ_QUERY_VOLUME_INFORMATION in mountmgr is one possible approach, and maybe even the best one. I'm not really sure, though. (Of course, I'm also not Alexandre.)
Another possibility could be to have the mountmgr create a special set of symlinks for NT devices that can be easily figured out (like we do for DOS devices). I'm not sure how AJ would feel about that, but my gut feeling is that having the volume information in one place (like you mention below) would override the simplicity of creating an "ntdevices" concept similar to dosdevices.
It'd kind of be nice for volume information to be implemented in one place and not two, but this requires a lot of work (probably fully implementing opening files by device path) which isn't really justified by anything other than one failing test. Nevertheless, I have some ideas I've described in [2].
Are we terribly concerned about performance here? It doesn't seem like apps "should" be querying volume information in a performance-sensitive way, but "should" and "do" are often different.
[1] https://www.winehq.org/pipermail/wine-devel/2020-April/164070.html
Best, Erch
On 5/23/20 3:49 PM, Erich E. Hoover wrote:
On Sat, May 23, 2020 at 1:01 PM Zebediah Figura z.figura12@gmail.com wrote:
On 5/23/20 1:49 PM, Erich E. Hoover wrote:
... Unfortunately for me, the thing I'm trying to do _is_ work with the volume information - which looks like it involves figuring out how to implement IRP_MJ_QUERY_VOLUME_INFORMATION.
Does this have to do with the problem mentioned in [1]?
Yes, I'd like to fix some rebase issues with my junction point patches and that now involves GetVolumeInformation getting pushed down further. The right way to do this looks like implementing GetVolumeInformation on top of GetVolumeInformationByHandle. To not break ??\Volume{...}\ this looks like it means that NtQueryVolumeInformationFile needs to be able to issue IRP_MJ_QUERY_VOLUME_INFORMATION to the mountmgr.
Yep. Broadly, this should look like other IRPs. We already have a fd op for it, so it'd just need to get wired up through device_file_ops and ntoskrnl.
Wiring up IRP_MJ_QUERY_VOLUME_INFORMATION in mountmgr is one possible approach, and maybe even the best one. I'm not really sure, though. (Of course, I'm also not Alexandre.)
Another possibility could be to have the mountmgr create a special set of symlinks for NT devices that can be easily figured out (like we do for DOS devices). I'm not sure how AJ would feel about that, but my gut feeling is that having the volume information in one place (like you mention below) would override the simplicity of creating an "ntdevices" concept similar to dosdevices.
Maybe. The benefit of doing this becomes less, though, if all file resolution goes through the server, which I am inclined to think is what we want.
It'd kind of be nice for volume information to be implemented in one place and not two, but this requires a lot of work (probably fully implementing opening files by device path) which isn't really justified by anything other than one failing test. Nevertheless, I have some ideas I've described in [2].
Are we terribly concerned about performance here? It doesn't seem like apps "should" be querying volume information in a performance-sensitive way, but "should" and "do" are often different.
Not performance of NtQueryVolumeInformationFile(), no, but if there's an attempt to make all files openable through device paths, that can't all go through mountmgr.
[1] https://www.winehq.org/pipermail/wine-devel/2020-April/164070.html
Best, Erch
On Thu, 2020-05-21 at 20:48 +0200, Alexandre Julliard wrote:
Hans Leidekker hans@codeweavers.com writes:
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=49160 Signed-off-by: Hans Leidekker hans@codeweavers.com
dlls/wbemprox/builtin.c | 40 +++++++++++++++++++++++++++++++++++-- dlls/wbemprox/tests/query.c | 26 ++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 2 deletions(-)
diff --git a/dlls/wbemprox/builtin.c b/dlls/wbemprox/builtin.c index ddd12d6ebcb..6a35737da59 100644 --- a/dlls/wbemprox/builtin.c +++ b/dlls/wbemprox/builtin.c @@ -44,6 +44,8 @@ #include "ntsecapi.h" #include "winspool.h" #include "setupapi.h" +#define WINE_MOUNTMGR_EXTENSIONS +#include <ddk/mountmgr.h>
Couldn't this go through some Win32 APIs instead of directly accessing mountmgr?
I've submitted a different version that uses IOCTL_STORAGE_QUERY_PROPERTY. While this works for drives mapped to directories (c: -> ../drive_c) it fails for drives mapped to Unix mount points (z: -> /) because in the latter case we try to open the underlying Unix device, which usually returns a permission denied error.