Based on a patch by Louis Lenders.
Signed-off-by: Gijs Vermeulen gijsvrm@gmail.com --- include/Makefile.in | 1 + include/virtdisk.h | 202 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 203 insertions(+) create mode 100644 include/virtdisk.h
diff --git a/include/Makefile.in b/include/Makefile.in index ffecb98d9e..74dc293a29 100644 --- a/include/Makefile.in +++ b/include/Makefile.in @@ -637,6 +637,7 @@ SOURCES = \ verrsrc.h \ vfw.h \ vfwmsgs.h \ + virtdisk.h \ vmr9.idl \ vmrender.idl \ vss.idl \ diff --git a/include/virtdisk.h b/include/virtdisk.h new file mode 100644 index 0000000000..0927f609a8 --- /dev/null +++ b/include/virtdisk.h @@ -0,0 +1,202 @@ +/* + * Copyright 2017 Louis Lenders + * Copyright 2018 Gijs Vermeulen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef __WINE_VIRTDISK_DLL_H +#define __WINE_VIRTDISK_DLL_H + +#include <windows.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#define VIRTUAL_STORAGE_TYPE_DEVICE_UNKNOWN 0 +#define VIRTUAL_STORAGE_TYPE_DEVICE_ISO 1 +#define VIRTUAL_STORAGE_TYPE_DEVICE_VHD 2 + +typedef enum _ATTACH_VIRTUAL_DISK_FLAG { + ATTACH_VIRTUAL_DISK_FLAG_NONE = 0x00000000, + ATTACH_VIRTUAL_DISK_FLAG_READ_ONLY = 0x00000001, + ATTACH_VIRTUAL_DISK_FLAG_NO_DRIVE_LETTER = 0x00000002, + ATTACH_VIRTUAL_DISK_FLAG_PERMANENT_LIFETIME = 0x00000004, + ATTACH_VIRTUAL_DISK_FLAG_NO_LOCAL_HOST = 0x00000008 +} ATTACH_VIRTUAL_DISK_FLAG; + +typedef enum _ATTACH_VIRTUAL_DISK_VERSION { + ATTACH_VIRTUAL_DISK_VERSION_UNSPECIFIED = 0, + ATTACH_VIRTUAL_DISK_VERSION_1 = 1 +} ATTACH_VIRTUAL_DISK_VERSION; + +typedef enum _COMPACT_VIRTUAL_DISK_FLAG { + COMPACT_VIRTUAL_DISK_FLAG_NONE = 0x00000000 +} COMPACT_VIRTUAL_DISK_FLAG; + +typedef enum _COMPACT_VIRTUAL_DISK_VERSION { + COMPACT_VIRTUAL_DISK_VERSION_UNSPECIFIED = 0, + COMPACT_VIRTUAL_DISK_VERSION_1 = 1 +} COMPACT_VIRTUAL_DISK_VERSION; + +typedef enum _DEPENDENT_DISK_FLAG +{ + DEPENDENT_DISK_FLAG_NONE = 0x00000000, + DEPENDENT_DISK_FLAG_MULT_BACKING_FILES = 0x00000001, + DEPENDENT_DISK_FLAG_FULLY_ALLOCATED = 0x00000002, + DEPENDENT_DISK_FLAG_READ_ONLY = 0x00000004, + DEPENDENT_DISK_FLAG_REMOTE = 0x00000008, + DEPENDENT_DISK_FLAG_SYSTEM_VOLUME = 0x00000010, + DEPENDENT_DISK_FLAG_SYSTEM_VOLUME_PARENT = 0x00000020, + DEPENDENT_DISK_FLAG_REMOVABLE = 0x00000040, + DEPENDENT_DISK_FLAG_NO_DRIVE_LETTER = 0x00000080, + DEPENDENT_DISK_FLAG_PARENT = 0x00000100, + DEPENDENT_DISK_FLAG_NO_HOST_DISK = 0x00000200, + DEPENDENT_DISK_FLAG_PERMANENT_LIFETIME = 0x00000400 +} DEPENDENT_DISK_FLAG; + +typedef enum _EXPAND_VIRTUAL_DISK_VERSION { + EXPAND_VIRTUAL_DISK_VERSION_UNSPECIFIED = 0, + EXPAND_VIRTUAL_DISK_VERSION_1 = 1 +} EXPAND_VIRTUAL_DISK_VERSION; + +typedef enum _DETACH_VIRTUAL_DISK_FLAG { + DETACH_VIRTUAL_DISK_FLAG_NONE = 0x00000000 +} DETACH_VIRTUAL_DISK_FLAG; + +typedef enum _EXPAND_VIRTUAL_DISK_FLAG { + EXPAND_VIRTUAL_DISK_FLAG_NONE = 0x00000000 +} EXPAND_VIRTUAL_DISK_FLAG; + +typedef enum _GET_STORAGE_DEPENDENCY_FLAG +{ + GET_STORAGE_DEPENDENCY_FLAG_NONE = 0x00000000, + GET_STORAGE_DEPENDENCY_FLAG_HOST_VOLUMES = 0x00000001, + GET_STORAGE_DEPENDENCY_FLAG_DISK_HANDLE = 0x00000002 +} GET_STORAGE_DEPENDENCY_FLAG; + +typedef enum _MIRROR_VIRTUAL_DISK_FLAG { + MIRROR_VIRTUAL_DISK_FLAG_NONE = 0x00000000, + MIRROR_VIRTUAL_DISK_FLAG_EXISTING_FILE = 0x00000001 +} MIRROR_VIRTUAL_DISK_FLAG; + +typedef enum _MIRROR_VIRTUAL_DISK_VERSION { + MIRROR_VIRTUAL_DISK_VERSION_UNSPECIFIED = 0, + MIRROR_VIRTUAL_DISK_VERSION_1 = 1 +} MIRROR_VIRTUAL_DISK_VERSION; + +typedef enum _MERGE_VIRTUAL_DISK_FLAG { + MERGE_VIRTUAL_DISK_FLAG_NONE = 0x00000000 +} MERGE_VIRTUAL_DISK_FLAG; + +typedef enum _STORAGE_DEPENDENCY_INFO_VERSION +{ + STORAGE_DEPENDENCY_INFO_VERSION_UNSPECIFIED = 0x0, + STORAGE_DEPENDENCY_INFO_VERSION_1 = 0x1, + STORAGE_DEPENDENCY_INFO_VERSION_2 = 0x2 +} STORAGE_DEPENDENCY_INFO_VERSION; + +typedef enum _VIRTUAL_DISK_ACCESS_MASK { + VIRTUAL_DISK_ACCESS_NONE = 0x00000000, + VIRTUAL_DISK_ACCESS_ATTACH_RO = 0x00010000, + VIRTUAL_DISK_ACCESS_ATTACH_RW = 0x00020000, + VIRTUAL_DISK_ACCESS_DETACH = 0x00040000, + VIRTUAL_DISK_ACCESS_GET_INFO = 0x00080000, + VIRTUAL_DISK_ACCESS_CREATE = 0x00100000, + VIRTUAL_DISK_ACCESS_METAOPS = 0x00200000, + VIRTUAL_DISK_ACCESS_READ = 0x000d0000, + VIRTUAL_DISK_ACCESS_ALL = 0x003f0000, + VIRTUAL_DISK_ACCESS_WRITABLE = 0x00320000 +} VIRTUAL_DISK_ACCESS_MASK; + +typedef struct _VIRTUAL_STORAGE_TYPE +{ + ULONG DeviceId; + GUID VendorId; +} VIRTUAL_STORAGE_TYPE, *PVIRTUAL_STORAGE_TYPE; + +typedef struct _ATTACH_VIRTUAL_DISK_PARAMETERS { + ATTACH_VIRTUAL_DISK_VERSION Version; + __C89_NAMELESS union { + struct { + ULONG Reserved; + } Version1; + } DUMMYUNIONNAME; +} ATTACH_VIRTUAL_DISK_PARAMETERS, *PATTACH_VIRTUAL_DISK_PARAMETERS; + +typedef struct _COMPACT_VIRTUAL_DISK_PARAMETERS { + COMPACT_VIRTUAL_DISK_VERSION Version; + __C89_NAMELESS union { + struct { + ULONG Reserved; + } Version1; + } DUMMYUNIONNAME; +} COMPACT_VIRTUAL_DISK_PARAMETERS, *PCOMPACT_VIRTUAL_DISK_PARAMETERS; + +typedef struct _EXPAND_VIRTUAL_DISK_PARAMETERS { + EXPAND_VIRTUAL_DISK_VERSION Version; + __C89_NAMELESS union { + struct { + ULONGLONG NewSize; + } Version1; + } DUMMYUNIONNAME; +} EXPAND_VIRTUAL_DISK_PARAMETERS, *PEXPAND_VIRTUAL_DISK_PARAMETERS; + +typedef struct _STORAGE_DEPENDENCY_INFO_TYPE_1 +{ + DEPENDENT_DISK_FLAG DependencyTypeFlags; + ULONG ProviderSpecificFlags; + VIRTUAL_STORAGE_TYPE VirtualStorageType; +} STORAGE_DEPENDENCY_INFO_TYPE_1, *PSTORAGE_DEPENDENCY_INFO_TYPE_1; + +typedef struct _STORAGE_DEPENDENCY_INFO_TYPE_2 +{ + DEPENDENT_DISK_FLAG DependencyTypeFlags; + ULONG ProviderSpecificFlags; + VIRTUAL_STORAGE_TYPE VirtualStorageType; + ULONG AncestorLevel; + PWSTR DependencyDeviceName; + PWSTR HostVolumeName; + PWSTR DependentVolumeName; + PWSTR DependentVolumeRelativePath; +} STORAGE_DEPENDENCY_INFO_TYPE_2, *PSTORAGE_DEPENDENCY_INFO_TYPE_2; + +typedef struct _STORAGE_DEPENDENCY_INFO +{ + STORAGE_DEPENDENCY_INFO_VERSION Version; + ULONG NumberEntries; +#if !defined(__WINESRC__) && (defined(_MSC_EXTENSIONS) || ((defined(__GNUC__) && __GNUC__ >= 3))) + __C89_NAMELESS union + { + STORAGE_DEPENDENCY_INFO_TYPE_1 Version1Entries[]; + STORAGE_DEPENDENCY_INFO_TYPE_2 Version2Entries[]; + } __C89_NAMELESSUNIONNAME; +#endif +} STORAGE_DEPENDENCY_INFO, *PSTORAGE_DEPENDENCY_INFO; + +typedef struct _VIRTUAL_DISK_PROGRESS { + DWORD OperationStatus; + ULONGLONG CurrentValue; + ULONGLONG CompletionValue; +} VIRTUAL_DISK_PROGRESS, *PVIRTUAL_DISK_PROGRESS; + +DWORD WINAPI GetStorageDependencyInformation(HANDLE obj, GET_STORAGE_DEPENDENCY_FLAG flags, ULONG size, STORAGE_DEPENDENCY_INFO *info, ULONG *used); + +#ifdef __cplusplus +} +#endif + +#endif /* __WINE_VIRTDISK_DLL_H */
Based on a patch by Michael Müller.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=42577 Signed-off-by: Gijs Vermeulen gijsvrm@gmail.com --- dlls/virtdisk/virtdisk.spec | 2 +- dlls/virtdisk/virtdisk_main.c | 37 +++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-)
diff --git a/dlls/virtdisk/virtdisk.spec b/dlls/virtdisk/virtdisk.spec index 2946b66d50..6bd5f146db 100644 --- a/dlls/virtdisk/virtdisk.spec +++ b/dlls/virtdisk/virtdisk.spec @@ -8,7 +8,7 @@ @ stub EnumerateVirtualDiskMetadata @ stub ExpandVirtualDisk @ stub GetAllAttachedVirtualDiskPhysicalPaths -@ stub GetStorageDependencyInformation +@ stdcall GetStorageDependencyInformation(long long long ptr ptr) @ stub GetVirtualDiskInformation @ stub GetVirtualDiskMetadata @ stub GetVirtualDiskOperationProgress diff --git a/dlls/virtdisk/virtdisk_main.c b/dlls/virtdisk/virtdisk_main.c index 0da0dca461..ff17df7fd4 100644 --- a/dlls/virtdisk/virtdisk_main.c +++ b/dlls/virtdisk/virtdisk_main.c @@ -22,10 +22,23 @@
#include "windef.h" #include "winbase.h" +#include "virtdisk.h" + #include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(virtdisk);
+typedef struct _STORAGE_DEPENDENCY_INFO_LOCAL +{ + STORAGE_DEPENDENCY_INFO_VERSION Version; + ULONG NumberEntries; + __C89_NAMELESS union + { + STORAGE_DEPENDENCY_INFO_TYPE_1 Version1Entries[1]; + STORAGE_DEPENDENCY_INFO_TYPE_2 Version2Entries[1]; + } __C89_NAMELESSUNIONNAME; +} STORAGE_DEPENDENCY_INFO_LOCAL; + /***************************************************** * DllMain (VIRTDISK.@) */ @@ -44,3 +57,27 @@ BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, void *reserved)
return TRUE; } + +DWORD WINAPI GetStorageDependencyInformation(HANDLE obj, GET_STORAGE_DEPENDENCY_FLAG flags, ULONG size, STORAGE_DEPENDENCY_INFO *info, ULONG *used) +{ + ULONG temp_size = size; + + FIXME("(%p, 0x%x, %u, %p, %p): stub\n", obj, flags, size, info, used); + + if (!info || !size) + return ERROR_INVALID_PARAMETER; + + if (info->Version == 1) + temp_size = offsetof(STORAGE_DEPENDENCY_INFO_LOCAL, Version1Entries[0]); + else if (info->Version == 2) + temp_size = offsetof(STORAGE_DEPENDENCY_INFO_LOCAL, Version2Entries[0]); + + if (used) *used = temp_size; + + if (size < temp_size) + return ERROR_INSUFFICIENT_BUFFER; + + info->NumberEntries = 0; + + return ERROR_SUCCESS; +}
Gijs Vermeulen gijsvrm@gmail.com writes:
@@ -22,10 +22,23 @@
#include "windef.h" #include "winbase.h" +#include "virtdisk.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(virtdisk);
+typedef struct _STORAGE_DEPENDENCY_INFO_LOCAL +{
- STORAGE_DEPENDENCY_INFO_VERSION Version;
- ULONG NumberEntries;
- __C89_NAMELESS union
- {
STORAGE_DEPENDENCY_INFO_TYPE_1 Version1Entries[1];
STORAGE_DEPENDENCY_INFO_TYPE_2 Version2Entries[1];
- } __C89_NAMELESSUNIONNAME;
+} STORAGE_DEPENDENCY_INFO_LOCAL;
You shouldn't need any of the nameless union stuff for the local definition. You may even want to get rid of this structure entirely, for what you are doing it doesn't seem useful.
Signed-off-by: Gijs Vermeulen gijsvrm@gmail.com --- configure | 1 + configure.ac | 1 + dlls/virtdisk/tests/Makefile.in | 4 ++ dlls/virtdisk/tests/virtdisk.c | 73 +++++++++++++++++++++++++++++++++ 4 files changed, 79 insertions(+) create mode 100644 dlls/virtdisk/tests/Makefile.in create mode 100644 dlls/virtdisk/tests/virtdisk.c
diff --git a/configure b/configure index a3916ee233..3a607280e2 100755 --- a/configure +++ b/configure @@ -19877,6 +19877,7 @@ wine_fn_config_makefile dlls/ver.dll16 enable_win16 wine_fn_config_makefile dlls/version enable_version wine_fn_config_makefile dlls/version/tests enable_tests wine_fn_config_makefile dlls/virtdisk enable_virtdisk +wine_fn_config_makefile dlls/virtdisk/tests enable_tests wine_fn_config_makefile dlls/vmm.vxd enable_win16 wine_fn_config_makefile dlls/vnbt.vxd enable_win16 wine_fn_config_makefile dlls/vnetbios.vxd enable_win16 diff --git a/configure.ac b/configure.ac index 006f7d9fc2..6936a71b6f 100644 --- a/configure.ac +++ b/configure.ac @@ -3733,6 +3733,7 @@ WINE_CONFIG_MAKEFILE(dlls/ver.dll16,enable_win16) WINE_CONFIG_MAKEFILE(dlls/version) WINE_CONFIG_MAKEFILE(dlls/version/tests) WINE_CONFIG_MAKEFILE(dlls/virtdisk) +WINE_CONFIG_MAKEFILE(dlls/virtdisk/tests) WINE_CONFIG_MAKEFILE(dlls/vmm.vxd,enable_win16) WINE_CONFIG_MAKEFILE(dlls/vnbt.vxd,enable_win16) WINE_CONFIG_MAKEFILE(dlls/vnetbios.vxd,enable_win16) diff --git a/dlls/virtdisk/tests/Makefile.in b/dlls/virtdisk/tests/Makefile.in new file mode 100644 index 0000000000..d0557cb08d --- /dev/null +++ b/dlls/virtdisk/tests/Makefile.in @@ -0,0 +1,4 @@ +TESTDLL = virtdisk.dll + +C_SRCS = \ + virtdisk.c diff --git a/dlls/virtdisk/tests/virtdisk.c b/dlls/virtdisk/tests/virtdisk.c new file mode 100644 index 0000000000..20aee76b21 --- /dev/null +++ b/dlls/virtdisk/tests/virtdisk.c @@ -0,0 +1,73 @@ +/* + * Copyright 2018 Gijs Vermeulen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "virtdisk.h" +#include "wine/heap.h" +#include "wine/test.h" + +typedef struct _STORAGE_DEPENDENCY_INFO_LOCAL +{ + STORAGE_DEPENDENCY_INFO_VERSION Version; + ULONG NumberEntries; + __C89_NAMELESS union + { + STORAGE_DEPENDENCY_INFO_TYPE_1 Version1Entries[1]; + STORAGE_DEPENDENCY_INFO_TYPE_2 Version2Entries[1]; + } __C89_NAMELESSUNIONNAME; +} STORAGE_DEPENDENCY_INFO_LOCAL; + +static DWORD (WINAPI *pGetStorageDependencyInformation)(HANDLE,GET_STORAGE_DEPENDENCY_FLAG,ULONG,STORAGE_DEPENDENCY_INFO*,ULONG*); + +static void test_GetStorageDependencyInformation(void) +{ + DWORD ret; + HANDLE handle; + STORAGE_DEPENDENCY_INFO *info; + ULONG size; + + handle = CreateFileA("C:", 0, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0); + ok(handle != INVALID_HANDLE_VALUE, "Expected a handle\n"); + + size = offsetof(STORAGE_DEPENDENCY_INFO_LOCAL, Version1Entries[0]); + info = heap_alloc(size); + + ret = pGetStorageDependencyInformation(handle, GET_STORAGE_DEPENDENCY_FLAG_DISK_HANDLE, 0, info, 0); + ok(ret == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", ret); + + ret = pGetStorageDependencyInformation(handle, GET_STORAGE_DEPENDENCY_FLAG_DISK_HANDLE, size, NULL, 0); + ok(ret == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", ret); + + heap_free(info); + CloseHandle(handle); +} + +START_TEST(virtdisk) +{ + HMODULE module = LoadLibraryA("virtdisk.dll"); + if(!module) + { + win_skip("virtdisk.dll not installed\n"); + return; + } + + pGetStorageDependencyInformation = (void *)GetProcAddress( module, "GetStorageDependencyInformation" ); + if (pGetStorageDependencyInformation) + test_GetStorageDependencyInformation(); + else + win_skip("GetStorageDependencyInformation is not available\n"); +}