diff --git a/module/os/windows/driver.c b/module/os/windows/driver.c index f1df2426e05c..d153eb553ab3 100644 --- a/module/os/windows/driver.c +++ b/module/os/windows/driver.c @@ -38,6 +38,9 @@ #include "Trace.h" DRIVER_INITIALIZE DriverEntry; +DRIVER_UNLOAD OpenZFS_Fini; +#pragma alloc_text(INIT, DriverEntry) +#pragma alloc_text(PAGE, OpenZFS_Fini) extern int initDbgCircularBuffer(void); extern int finiDbgCircularBuffer(void); @@ -65,12 +68,10 @@ PDRIVER_DISPATCH STOR_MajorFunction[IRP_MJ_MAXIMUM_FUNCTION + 1]; wzvolDriverInfo STOR_wzvolDriverInfo; -DRIVER_UNLOAD OpenZFS_Fini; - -extern _Function_class_(WORKER_THREAD_ROUTINE) +extern _Function_class_(IO_WORKITEM_ROUTINE) void __stdcall -sysctl_os_registry_change(PVOID Parameter); - +sysctl_os_registry_change(DEVICE_OBJECT *DeviceObject, + PVOID Parameter); void OpenZFS_Fini(PDRIVER_OBJECT DriverObject) @@ -84,12 +85,12 @@ OpenZFS_Fini(PDRIVER_OBJECT DriverObject) STOR_DriverUnload = NULL; } + sysctl_os_fini(); + zfs_kmod_fini(); system_taskq_fini(); - sysctl_os_fini(); - spl_stop(); #ifdef DBG if (KD_DEBUGGER_ENABLED && !KD_DEBUGGER_NOT_PRESENT) { @@ -99,11 +100,6 @@ OpenZFS_Fini(PDRIVER_OBJECT DriverObject) #endif finiDbgCircularBuffer(); - if (STOR_wzvolDriverInfo.zvContextArray) { - ExFreePoolWithTag(STOR_wzvolDriverInfo.zvContextArray, - MP_TAG_GENERAL); - STOR_wzvolDriverInfo.zvContextArray = NULL; - } ZFSWppCleanup(DriverObject); KdPrintEx((DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, @@ -172,7 +168,7 @@ DriverEntry(_In_ PDRIVER_OBJECT DriverObject, zfs_vfsops_init(); /* Start monitoring Registry for changes */ - sysctl_os_registry_change(pRegistryPath); + sysctl_os_registry_change(DriverObject->DeviceObject, pRegistryPath); KdPrintEx((DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "OpenZFS: Started\n")); diff --git a/module/os/windows/zfs/zfs_vnops_windows.c b/module/os/windows/zfs/zfs_vnops_windows.c index 5fe6265af7c9..0bc69e4a5b64 100644 --- a/module/os/windows/zfs/zfs_vnops_windows.c +++ b/module/os/windows/zfs/zfs_vnops_windows.c @@ -6633,7 +6633,8 @@ _Function_class_(DRIVER_DISPATCH) Status = pnp_query_di(DeviceObject, Irp, IrpSp); break; default: - dprintf("Unknown IRP_MJ_PNP(ioctl): 0x%x\n", IrpSp->MinorFunction); + dprintf("Unknown IRP_MJ_PNP(ioctl): 0x%x\n", + IrpSp->MinorFunction); break; } break; @@ -6883,7 +6884,8 @@ _Function_class_(DRIVER_DISPATCH) Status = STATUS_SUCCESS; break; default: - dprintf("Unknown IRP_MJ_PNP(disk): 0x%x\n", IrpSp->MinorFunction); + dprintf("Unknown IRP_MJ_PNP(disk): 0x%x\n", + IrpSp->MinorFunction); break; } break; @@ -7233,7 +7235,8 @@ _Function_class_(DRIVER_DISPATCH) break; } - dprintf("TargetDeviceRelations: returning DO %p\n", DeviceObject); + dprintf("TargetDeviceRelations: returning %p\n", + DeviceObject); /* The PnP manager will remove this when it is done with device */ ObReferenceObject(DeviceObject); @@ -7278,7 +7281,8 @@ _Function_class_(DRIVER_DISPATCH) Irp, IrpSp); break; default: - dprintf("Unknown IRP_MJ_PNP(fs): 0x%x\n", IrpSp->MinorFunction); + dprintf("Unknown IRP_MJ_PNP(fs): 0x%x\n", + IrpSp->MinorFunction); break; } break; diff --git a/module/os/windows/zfs/zfs_windows_zvol.c b/module/os/windows/zfs/zfs_windows_zvol.c index 055d35ebc16c..11d2c9b5239b 100644 --- a/module/os/windows/zfs/zfs_windows_zvol.c +++ b/module/os/windows/zfs/zfs_windows_zvol.c @@ -34,18 +34,99 @@ extern PDRIVER_OBJECT WIN_DriverObject; static pHW_HBA_EXT STOR_HBAExt = NULL; -static uint64_t windows_zvol_enabled = 0; +static uint64_t windows_zvol_enabled = 1; ZFS_MODULE_PARAM(, windows_, zvol_enabled, U64, ZMOD_RW, - "Windows: enable zvol"); + "Windows: enable zvol"); + +NTSYSCALLAPI NTSTATUS NTAPI ZwQuerySystemInformation( + ULONG SystemInformationClass, + PVOID SystemInformation, + ULONG SystemInformationLength, + PULONG ReturnLength +); + +typedef struct _SYSTEM_MODULE { + ULONG Reserved[2]; +#ifdef _WIN64 + ULONG Unknown3; + ULONG Unknown4; +#endif + PVOID Base; + ULONG Size; + ULONG Flags; + USHORT Index; + USHORT Unknown; + USHORT LoadCount; + USHORT ModuleNameOffset; + CHAR ImageName[256]; +} SYSTEM_MODULE, *PSYSTEM_MODULE; + +typedef struct _SYSTEM_MODULE_INFORMATION { + ULONG ModulesCount; + SYSTEM_MODULE Modules[1]; +} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION; + +#define SystemModuleInformation 11 + +static void +ListLoadedDrivers(void) +{ + ULONG bufferLength = 0; + boolean_t skipLoad = FALSE; + + ZwQuerySystemInformation(SystemModuleInformation, NULL, 0, + &bufferLength); + + PVOID buffer = ExAllocatePoolWithTag(NonPagedPoolNx, bufferLength, + 'sysm'); + + if (buffer == NULL) + return; + + if (NT_SUCCESS(ZwQuerySystemInformation(SystemModuleInformation, + buffer, bufferLength, &bufferLength))) { + PSYSTEM_MODULE_INFORMATION moduleInformation = + (PSYSTEM_MODULE_INFORMATION)buffer; + for (ULONG i = 0; i < moduleInformation->ModulesCount; ++i) { + dprintf("Driver: %s\n", + moduleInformation->Modules[i].ImageName); + + if (strncmp("\\SystemRoot\\system32\\ambakdrv.sys", + moduleInformation->Modules[i].ImageName, + sizeof (moduleInformation->Modules[i].ImageName)) + == 0) + skipLoad = TRUE; + } + } -// Verbose + ExFreePoolWithTag(buffer, 'sysm'); + + if (!skipLoad) + return; + + if (windows_zvol_enabled == 1) { + dprintf( + "Aomei Backupper (ambakdrv.sys) detected as installed.\n" + "It is known to crash with OpenZFS's zvol. Set Registry entry\n" + "windows_zvol_enabled to 2 to force load OpenZFS with zvol support.\n"); + xprintf("Skipping ZVOL due to ambakdrv.sys\n"); + windows_zvol_enabled = 0; + } else if (windows_zvol_enabled == 2) { + dprintf("Force loading OpenZFS with zvol support, " + "and Aomei ambakdrv.sys installed.\n"); + xprintf("Forcing ZVOL despite ambakdrv.sys\n"); + } + +} int -zvol_start(PDRIVER_OBJECT DriverObject, PUNICODE_STRING pRegistryPath) +zvol_start(PDRIVER_OBJECT DriverObject, PUNICODE_STRING pRegistryPath) { + VIRTUAL_HW_INITIALIZATION_DATA hwInitData; pwzvolDriverInfo pwzvolDrvInfo; NTSTATUS status; - VIRTUAL_HW_INITIALIZATION_DATA hwInitData; + + ListLoadedDrivers(); if (windows_zvol_enabled == 0) return (STATUS_FS_DRIVER_REQUIRED); @@ -652,7 +733,9 @@ wzvol_HandleQueryCapabilities( UNREFERENCED_PARAMETER(pHBAExt); - dprintf("%s: entry\n", __func__); + dprintf("%s: entry: sizeof %d DataTransferLength %d\n", + __func__, sizeof (*pStorageCapabilities), + pSrb->DataTransferLength); RtlZeroMemory(pStorageCapabilities, pSrb->DataTransferLength); @@ -1028,6 +1111,17 @@ wzvol_HwFreeAdapterResources(__in pHW_HBA_EXT pHBAExt) #endif + VERIFY0(pHBAExt->pwzvolDrvObj->DrvInfoNbrMPHBAObj); + + dprintf("Freeing zcContextArray %p\n", + STOR_wzvolDriverInfo.zvContextArray); + + if (STOR_wzvolDriverInfo.zvContextArray) { + ExFreePoolWithTag(STOR_wzvolDriverInfo.zvContextArray, + MP_TAG_GENERAL); + STOR_wzvolDriverInfo.zvContextArray = NULL; + } + if (STOR_HBAExt == pHBAExt) STOR_HBAExt = NULL; } @@ -1088,23 +1182,17 @@ wzvol_ProcServReq( __in pHW_HBA_EXT pHBAExt, __in PIRP pIrp) { - -#if 1 dprintf("MpProcServReq entered\n"); wzvol_QueueServiceIrp(pHBAExt, pIrp); -#endif } void wzvol_CompServReq(__in pHW_HBA_EXT pHBAExt) { - -#if 1 dprintf("MpHwCompServReq entered\n"); wzvol_QueueServiceIrp(pHBAExt, NULL); -#endif } void