VOID DokanDeleteDeviceObject(__in PDokanDCB Dcb) { PDokanVCB vcb; DOKAN_CONTROL dokanControl; PMOUNT_ENTRY mountEntry = NULL; ASSERT(GetIdentifierType(Dcb) == DCB); vcb = Dcb->Vcb; if (Dcb->SymbolicLinkName == NULL) { DDbgPrint(" Symbolic Name already deleted, so go out here\n"); return; } RtlZeroMemory(&dokanControl, sizeof(dokanControl)); RtlCopyMemory(dokanControl.DeviceName, Dcb->DiskDeviceName->Buffer, Dcb->DiskDeviceName->Length); mountEntry = FindMountEntry(Dcb->Global, &dokanControl); if (mountEntry != NULL) { if (mountEntry->MountControl.Type == FILE_DEVICE_NETWORK_FILE_SYSTEM) { // Run FsRtlDeregisterUncProvider in System thread. HANDLE handle; PKTHREAD thread; OBJECT_ATTRIBUTES objectAttribs; NTSTATUS status; InitializeObjectAttributes(&objectAttribs, NULL, OBJ_KERNEL_HANDLE, NULL, NULL); status = PsCreateSystemThread( &handle, THREAD_ALL_ACCESS, &objectAttribs, NULL, NULL, (PKSTART_ROUTINE)DokanDeregisterUncProvider, Dcb); if (!NT_SUCCESS(status)) { DDbgPrint("PsCreateSystemThread failed: 0x%X\n", status); } else { ObReferenceObjectByHandle(handle, THREAD_ALL_ACCESS, NULL, KernelMode, &thread, NULL); ZwClose(handle); KeWaitForSingleObject(thread, Executive, KernelMode, FALSE, NULL); ObDereferenceObject(thread); } } RemoveMountEntry(Dcb->Global, mountEntry); } else { DDbgPrint(" Cannot found associated mount entry.\n"); } DDbgPrint(" Delete Symbolic Name: %wZ\n", Dcb->SymbolicLinkName); IoDeleteSymbolicLink(Dcb->SymbolicLinkName); if (Dcb->MountedDeviceInterfaceName.Buffer != NULL) { IoSetDeviceInterfaceState(&Dcb->MountedDeviceInterfaceName, FALSE); RtlFreeUnicodeString(&Dcb->MountedDeviceInterfaceName); RtlInitUnicodeString(&Dcb->MountedDeviceInterfaceName, NULL); } if (Dcb->DiskDeviceInterfaceName.Buffer != NULL) { IoSetDeviceInterfaceState(&Dcb->DiskDeviceInterfaceName, FALSE); RtlFreeUnicodeString(&Dcb->DiskDeviceInterfaceName); RtlInitUnicodeString(&Dcb->DiskDeviceInterfaceName, NULL); } FreeDcbNames(Dcb); if (Dcb->DeviceObject->Vpb) { Dcb->DeviceObject->Vpb->DeviceObject = NULL; Dcb->DeviceObject->Vpb->RealDevice = NULL; Dcb->DeviceObject->Vpb->Flags = 0; } if (vcb != NULL) { DDbgPrint(" FCB allocated: %d\n", vcb->FcbAllocated); DDbgPrint(" FCB freed: %d\n", vcb->FcbFreed); DDbgPrint(" CCB allocated: %d\n", vcb->CcbAllocated); DDbgPrint(" CCB freed: %d\n", vcb->CcbFreed); // delete volDeviceObject DDbgPrint(" Delete Volume DeviceObject\n"); IoDeleteDevice(vcb->DeviceObject); } // delete diskDeviceObject DDbgPrint(" Delete Disk DeviceObject\n"); IoDeleteDevice(Dcb->DeviceObject); }
static VOID DokanControl(PDOKAN_CONTROL Control) { PMOUNT_ENTRY mountEntry; Control->Status = DOKAN_CONTROL_FAIL; switch (Control->Type) { case DOKAN_CONTROL_MOUNT: DbgPrintW(L"DokanControl Mount\n"); if (DokanControlMount(Control->MountPoint, Control->DeviceName)) { Control->Status = DOKAN_CONTROL_SUCCESS; InsertMountEntry(Control); } else { Control->Status = DOKAN_CONTROL_FAIL; } break; case DOKAN_CONTROL_UNMOUNT: DbgPrintW(L"DokanControl Unmount\n"); mountEntry = FindMountEntry(Control); if (mountEntry == NULL) { if (!wcslen(Control->MountPoint)) FindMountPoint(Control); DbgPrintW(L"DokanControl MountEntry not found. Try unmount '%s' force: %d\n", Control->MountPoint, Control->Option); if (Control->Option == DOKAN_CONTROL_OPTION_FORCE_UNMOUNT && DokanControlUnmount(Control->MountPoint)) { Control->Status = DOKAN_CONTROL_SUCCESS; break; } Control->Status = DOKAN_CONTROL_FAIL; break; } if (DokanControlUnmount(mountEntry->MountControl.MountPoint)) { Control->Status = DOKAN_CONTROL_SUCCESS; if (Control->DeviceName[0] == L'\0') { wcscpy_s(Control->DeviceName, sizeof(Control->DeviceName) / sizeof(WCHAR), mountEntry->MountControl.DeviceName); } RemoveMountEntry(mountEntry); } else { mountEntry->MountControl.Status = DOKAN_CONTROL_FAIL; Control->Status = DOKAN_CONTROL_FAIL; } break; case DOKAN_CONTROL_CHECK: { DbgPrint("DokanControl Check\n"); Control->Status = 0; } break; case DOKAN_CONTROL_FIND: { DbgPrintW(L"DokanControl Find\n"); DokanControlFind(Control); } break; case DOKAN_CONTROL_LIST: { DbgPrintW(L"DokanControl List\n"); DokanControlList(Control); } break; default: DbgPrintW(L"DokanControl UnknownType %u\n", Control->Type); } return; }
static VOID DokanControl(PDOKAN_CONTROL Control) { PMOUNT_ENTRY mountEntry; ULONG index = 0; DWORD written = 0; Control->Status = DOKAN_CONTROL_FAIL; switch (Control->Type) { case DOKAN_CONTROL_MOUNT: DbgPrintW(L"DokanControl Mount\n"); // if (DokanControlMount(Control->MountPoint, Control->DeviceName)) { Control->Status = DOKAN_CONTROL_SUCCESS; InsertMountEntry(Control); DbgPrintW(L"DriveLetter: %c, DeviceName %s\n", Control->MountPoint[0], Control->DeviceName); // } else { // Control->Status = DOKAN_CONTROL_FAIL; // } break; case DOKAN_CONTROL_UNMOUNT: DbgPrintW(L"DokanControl Unmount\n"); mountEntry = FindMountEntry(Control); if (mountEntry == NULL) { if (Control->Option == DOKAN_CONTROL_OPTION_FORCE_UNMOUNT ) { Control->Status = DOKAN_CONTROL_SUCCESS; break; } Control->Status = DOKAN_CONTROL_FAIL; break; } // if (DokanControlUnmount(mountEntry->MountControl.MountPoint)) { Control->Status = DOKAN_CONTROL_SUCCESS; if (wcslen(Control->DeviceName) == 0) { wcscpy_s(Control->DeviceName, sizeof(Control->DeviceName) / sizeof(WCHAR), mountEntry->MountControl.DeviceName); } RemoveMountEntry(mountEntry); // } else { // mountEntry->MountControl.Status = DOKAN_CONTROL_FAIL; // Control->Status = DOKAN_CONTROL_FAIL; // } break; case DOKAN_CONTROL_CHECK: { DbgPrint("DokanControl Check\n"); Control->Status = 0; } break; case DOKAN_CONTROL_FIND: { DbgPrintW(L"DokanControl Find\n"); DokanControlFind(Control); } break; case DOKAN_CONTROL_LIST: { DbgPrintW(L"DokanControl List\n"); DokanControlList(Control); } break; default: DbgPrintW(L"DokanControl UnknownType %u\n", Control->Type); } return; }