BOOL DokanControlMount( LPCWSTR MountPoint, LPCWSTR DeviceName) { ULONG length = wcslen(MountPoint); if (length == 1 || (length == 2 && MountPoint[1] == L':') || (length == 3 && MountPoint[1] == L':' && MountPoint[2] == L'\\')) { return CreateDriveLetter(MountPoint[0], DeviceName); } else if (length > 3) { return CreateMountPoint(MountPoint, DeviceName); } return FALSE; }
int DOKANAPI DokanMain(PDOKAN_OPTIONS DokanOptions, PDOKAN_OPERATIONS DokanOperations) { ULONG threadNum = 0; ULONG i; BOOL status; int error; HANDLE device; HANDLE threadIds[DOKAN_MAX_THREAD]; ULONG returnedLength; char buffer[1024]; BOOL useMountPoint = FALSE; PDOKAN_INSTANCE instance; g_DebugMode = DokanOptions->Options & DOKAN_OPTION_DEBUG; g_UseStdErr = DokanOptions->Options & DOKAN_OPTION_STDERR; if (g_DebugMode) { DbgPrintW(L"Dokan: debug mode on\n"); } if (g_UseStdErr) { DbgPrintW(L"Dokan: use stderr\n"); g_DebugMode = TRUE; } if (DokanOptions->ThreadCount == 0) { DokanOptions->ThreadCount = 5; } else if (DOKAN_MAX_THREAD-1 < DokanOptions->ThreadCount) { // DOKAN_MAX_THREAD includes DokanKeepAlive thread, so // available thread is DOKAN_MAX_THREAD -1 DokanDbgPrintW(L"Dokan Error: too many thread count %d\n", DokanOptions->ThreadCount); DokanOptions->ThreadCount = DOKAN_MAX_THREAD-1; } if (DOKAN_MOUNT_POINT_SUPPORTED_VERSION <= DokanOptions->Version && DokanOptions->MountPoint) { error = CheckMountPoint(DokanOptions->MountPoint); if (error != DOKAN_SUCCESS) { return error; } useMountPoint = TRUE; } else if (!IsValidDriveLetter((WCHAR)DokanOptions->Version)) { // Older versions use the first 2 bytes of DokanOptions struct as DriveLetter. DokanDbgPrintW(L"Dokan Error: bad drive letter %wc\n", (WCHAR)DokanOptions->Version); return DOKAN_DRIVE_LETTER_ERROR; } device = CreateFile( DOKAN_GLOBAL_DEVICE_NAME, // lpFileName GENERIC_READ|GENERIC_WRITE, // dwDesiredAccess FILE_SHARE_READ|FILE_SHARE_WRITE, // dwShareMode NULL, // lpSecurityAttributes OPEN_EXISTING, // dwCreationDistribution 0, // dwFlagsAndAttributes NULL // hTemplateFile ); if (device == INVALID_HANDLE_VALUE){ DokanDbgPrintW(L"Dokan Error: CreatFile Failed %s: %d\n", DOKAN_GLOBAL_DEVICE_NAME, GetLastError()); return DOKAN_DRIVER_INSTALL_ERROR; } DbgPrint("device opened\n"); instance = NewDokanInstance(); instance->DokanOptions = DokanOptions; instance->DokanOperations = DokanOperations; if (useMountPoint) { wcscpy_s(instance->MountPoint, sizeof(instance->MountPoint) / sizeof(WCHAR), DokanOptions->MountPoint); } else { // Older versions use the first 2 bytes of DokanOptions struct as DriveLetter. instance->MountPoint[0] = (WCHAR)DokanOptions->Version; instance->MountPoint[1] = L':'; instance->MountPoint[2] = L'\\'; } if (!DokanStart(instance)) { return DOKAN_START_ERROR; } if (!DokanMount(instance->MountPoint, instance->DeviceName)) { SendReleaseIRP(instance->DeviceName); DokanDbgPrint("Dokan Error: DefineDosDevice Failed\n"); return DOKAN_MOUNT_ERROR; } if (!CreateDriveLetter(instance->MountPoint[0], instance->DeviceName)) return DOKAN_MOUNT_ERROR; DbgPrintW(L"mounted: %s -> %s\n", instance->MountPoint, instance->DeviceName); if (DokanOptions->Options & DOKAN_OPTION_KEEP_ALIVE) { threadIds[threadNum++] = (HANDLE)_beginthreadex( NULL, // Security Atributes 0, //stack size DokanKeepAlive, instance, // param 0, // create flag NULL); } for (i = 0; i < DokanOptions->ThreadCount; ++i) { threadIds[threadNum++] = (HANDLE)_beginthreadex( NULL, // Security Atributes 0, //stack size DokanLoop, (PVOID)instance, // param 0, // create flag NULL); } // wait for thread terminations WaitForMultipleObjects(threadNum, threadIds, TRUE, INFINITE); for (i = 0; i < threadNum; ++i) { CloseHandle(threadIds[i]); } CloseHandle(device); Sleep(1000); DbgPrint("\nunload\n"); DeleteDokanInstance(instance); return DOKAN_SUCCESS; }