VOID DokanUnload(__in PDRIVER_OBJECT DriverObject) /*++ Routine Description: This routine gets called to remove the driver from the system. Arguments: DriverObject - the system supplied driver object. Return Value: NTSTATUS --*/ { PDEVICE_OBJECT deviceObject = DriverObject->DeviceObject; WCHAR symbolicLinkBuf[] = DOKAN_GLOBAL_SYMBOLIC_LINK_NAME; UNICODE_STRING symbolicLinkName; PDOKAN_GLOBAL dokanGlobal; DDbgPrint("==> DokanUnload\n"); PAGED_CODE(); dokanGlobal = deviceObject->DeviceExtension; if (GetIdentifierType(dokanGlobal) == DGL) { DDbgPrint(" Delete Global DeviceObject\n"); KeSetEvent(&dokanGlobal->KillDeleteDeviceEvent, 0, FALSE); RtlInitUnicodeString(&symbolicLinkName, symbolicLinkBuf); IoDeleteSymbolicLink(&symbolicLinkName); IoUnregisterFileSystem(dokanGlobal->FsDiskDeviceObject); IoUnregisterFileSystem(dokanGlobal->FsCdDeviceObject); IoDeleteDevice(dokanGlobal->FsDiskDeviceObject); IoDeleteDevice(dokanGlobal->FsCdDeviceObject); IoDeleteDevice(deviceObject); } ExDeleteNPagedLookasideList(&DokanIrpEntryLookasideList); ExDeleteLookasideListEx(&g_DokanCCBLookasideList); ExDeleteLookasideListEx(&g_DokanFCBLookasideList); ExDeleteLookasideListEx(&g_DokanEResourceLookasideList); DDbgPrint("<== DokanUnload\n"); }
VOID DokanUnload(__in PDRIVER_OBJECT DriverObject) /*++ Routine Description: This routine gets called to remove the driver from the system. Arguments: DriverObject - the system supplied driver object. Return Value: NTSTATUS --*/ { PDEVICE_OBJECT deviceObject = DriverObject->DeviceObject; PDOKAN_GLOBAL dokanGlobal; DDbgPrint("==> DokanUnload\n"); PAGED_CODE(); dokanGlobal = deviceObject->DeviceExtension; if (GetIdentifierType(dokanGlobal) == DGL) { DDbgPrint(" Delete Global DeviceObject\n"); CleanupGlobalDiskDevice(dokanGlobal); ExFreePool(DriverObject->FastIoDispatch); } ExDeleteNPagedLookasideList(&DokanIrpEntryLookasideList); ExDeleteLookasideListEx(&g_DokanCCBLookasideList); ExDeleteLookasideListEx(&g_DokanFCBLookasideList); ExDeleteLookasideListEx(&g_DokanEResourceLookasideList); DDbgPrint("<== DokanUnload\n"); }
NTSTATUS DriverEntry(__in PDRIVER_OBJECT DriverObject, __in PUNICODE_STRING RegistryPath) /*++ Routine Description: This routine gets called by the system to initialize the driver. Arguments: DriverObject - the system supplied driver object. RegistryPath - the system supplied registry path for this driver. Return Value: NTSTATUS --*/ { NTSTATUS status; PFAST_IO_DISPATCH fastIoDispatch; FS_FILTER_CALLBACKS filterCallbacks; PDOKAN_GLOBAL dokanGlobal = NULL; UNREFERENCED_PARAMETER(RegistryPath); DDbgPrint("==> DriverEntry ver.%x, %s %s\n", DOKAN_DRIVER_VERSION, __DATE__, __TIME__); status = DokanCreateGlobalDiskDevice(DriverObject, &dokanGlobal); if (NT_ERROR(status)) { return status; } // // Set up dispatch entry points for the driver. // DriverObject->DriverUnload = DokanUnload; DriverObject->MajorFunction[IRP_MJ_CREATE] = DokanBuildRequest; DriverObject->MajorFunction[IRP_MJ_CLOSE] = DokanBuildRequest; DriverObject->MajorFunction[IRP_MJ_CLEANUP] = DokanBuildRequest; DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DokanBuildRequest; DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = DokanBuildRequest; DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] = DokanBuildRequest; DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] = DokanBuildRequest; DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] = DokanBuildRequest; DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] = DokanBuildRequest; DriverObject->MajorFunction[IRP_MJ_SET_VOLUME_INFORMATION] = DokanBuildRequest; DriverObject->MajorFunction[IRP_MJ_READ] = DokanBuildRequest; DriverObject->MajorFunction[IRP_MJ_WRITE] = DokanBuildRequest; DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = DokanBuildRequest; DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = DokanBuildRequest; DriverObject->MajorFunction[IRP_MJ_PNP] = DokanBuildRequest; DriverObject->MajorFunction[IRP_MJ_LOCK_CONTROL] = DokanBuildRequest; DriverObject->MajorFunction[IRP_MJ_QUERY_SECURITY] = DokanBuildRequest; DriverObject->MajorFunction[IRP_MJ_SET_SECURITY] = DokanBuildRequest; fastIoDispatch = ExAllocatePool(sizeof(FAST_IO_DISPATCH)); if (!fastIoDispatch) { CleanupGlobalDiskDevice(dokanGlobal); DDbgPrint(" ExAllocatePool failed"); return STATUS_INSUFFICIENT_RESOURCES; } RtlZeroMemory(fastIoDispatch, sizeof(FAST_IO_DISPATCH)); fastIoDispatch->SizeOfFastIoDispatch = sizeof(FAST_IO_DISPATCH); fastIoDispatch->FastIoCheckIfPossible = DokanFastIoCheckIfPossible; // fastIoDispatch->FastIoRead = DokanFastIoRead; fastIoDispatch->FastIoRead = FsRtlCopyRead; fastIoDispatch->FastIoWrite = FsRtlCopyWrite; fastIoDispatch->AcquireFileForNtCreateSection = DokanAcquireForCreateSection; fastIoDispatch->ReleaseFileForNtCreateSection = DokanReleaseForCreateSection; fastIoDispatch->MdlRead = FsRtlMdlReadDev; fastIoDispatch->MdlReadComplete = FsRtlMdlReadCompleteDev; fastIoDispatch->PrepareMdlWrite = FsRtlPrepareMdlWriteDev; fastIoDispatch->MdlWriteComplete = FsRtlMdlWriteCompleteDev; DriverObject->FastIoDispatch = fastIoDispatch; #if _WIN32_WINNT >= _WIN32_WINNT_WIN8 ExInitializeNPagedLookasideList(&DokanIrpEntryLookasideList, NULL, NULL, POOL_NX_ALLOCATION, sizeof(IRP_ENTRY), TAG, 0); #else ExInitializeNPagedLookasideList(&DokanIrpEntryLookasideList, NULL, NULL, 0, sizeof(IRP_ENTRY), TAG, 0); #endif #if _WIN32_WINNT < 0x0501 RtlInitUnicodeString(&functionName, L"FsRtlTeardownPerStreamContexts"); DokanFsRtlTeardownPerStreamContexts = MmGetSystemRoutineAddress(&functionName); #endif RtlZeroMemory(&filterCallbacks, sizeof(FS_FILTER_CALLBACKS)); // only be used by filter driver? filterCallbacks.SizeOfFsFilterCallbacks = sizeof(FS_FILTER_CALLBACKS); filterCallbacks.PreAcquireForSectionSynchronization = DokanFilterCallbackAcquireForCreateSection; status = FsRtlRegisterFileSystemFilterCallbacks(DriverObject, &filterCallbacks); if (!NT_SUCCESS(status)) { CleanupGlobalDiskDevice(dokanGlobal); ExFreePool(DriverObject->FastIoDispatch); DDbgPrint(" FsRtlRegisterFileSystemFilterCallbacks returned 0x%x\n", status); return status; } if (!DokanLookasideCreate(&g_DokanCCBLookasideList, sizeof(DokanCCB))) { DDbgPrint(" DokanLookasideCreate g_DokanCCBLookasideList failed"); CleanupGlobalDiskDevice(dokanGlobal); ExFreePool(DriverObject->FastIoDispatch); return STATUS_INSUFFICIENT_RESOURCES; } if (!DokanLookasideCreate(&g_DokanFCBLookasideList, sizeof(DokanFCB))) { DDbgPrint(" DokanLookasideCreate g_DokanFCBLookasideList failed"); CleanupGlobalDiskDevice(dokanGlobal); ExFreePool(DriverObject->FastIoDispatch); ExDeleteLookasideListEx(&g_DokanCCBLookasideList); return STATUS_INSUFFICIENT_RESOURCES; } if (!DokanLookasideCreate(&g_DokanEResourceLookasideList, sizeof(ERESOURCE))) { DDbgPrint(" DokanLookasideCreate g_DokanEResourceLookasideList failed"); CleanupGlobalDiskDevice(dokanGlobal); ExFreePool(DriverObject->FastIoDispatch); ExDeleteLookasideListEx(&g_DokanCCBLookasideList); ExDeleteLookasideListEx(&g_DokanFCBLookasideList); return STATUS_INSUFFICIENT_RESOURCES; } DDbgPrint("<== DriverEntry\n"); return (status); }