BOOL DokanStart(PDOKAN_INSTANCE Instance) { EVENT_START eventStart; EVENT_DRIVER_INFO driverInfo; ULONG returnedLength = 0; ZeroMemory(&eventStart, sizeof(EVENT_START)); ZeroMemory(&driverInfo, sizeof(EVENT_DRIVER_INFO)); eventStart.UserVersion = DOKAN_DRIVER_VERSION; if (Instance->DokanOptions->Options & DOKAN_OPTION_ALT_STREAM) { eventStart.Flags |= DOKAN_EVENT_ALTERNATIVE_STREAM_ON; } if (Instance->DokanOptions->Options & DOKAN_OPTION_NETWORK) { eventStart.DeviceType = DOKAN_NETWORK_FILE_SYSTEM; } if (Instance->DokanOptions->Options & DOKAN_OPTION_REMOVABLE) { eventStart.Flags |= DOKAN_EVENT_REMOVABLE; } eventStart.IrpTimeout = Instance->DokanOptions->Timeout; SendToDevice( DOKAN_GLOBAL_DEVICE_NAME, IOCTL_EVENT_START, &eventStart, sizeof(EVENT_START), &driverInfo, sizeof(EVENT_DRIVER_INFO), &returnedLength); if (driverInfo.Status == DOKAN_START_FAILED) { if (driverInfo.DriverVersion != eventStart.UserVersion) { DokanDbgPrint( "Dokan Error: driver version mismatch, driver %X, dll %X\n", driverInfo.DriverVersion, eventStart.UserVersion); } else { DokanDbgPrint("Dokan Error: driver start error\n"); } return FALSE; } else if (driverInfo.Status == DOKAN_MOUNTED) { Instance->MountId = driverInfo.MountId; Instance->DeviceNumber = driverInfo.DeviceNumber; wcscpy_s(Instance->DeviceName, sizeof(Instance->DeviceName) / sizeof(WCHAR), driverInfo.DeviceName); return TRUE; } return FALSE; }
BOOL DOKANAPI DokanServiceInstall(LPCWSTR ServiceName, DWORD ServiceType, LPCWSTR ServiceFullPath) { SC_HANDLE controlHandle; SC_HANDLE serviceHandle; controlHandle = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE); if (controlHandle == NULL) { DokanDbgPrint("DokanServiceInstall: Failed to open Service Control " "Manager. error = %d\n", GetLastError()); return FALSE; } serviceHandle = CreateService(controlHandle, ServiceName, ServiceName, 0, ServiceType, SERVICE_AUTO_START, SERVICE_ERROR_IGNORE, ServiceFullPath, NULL, NULL, NULL, NULL, NULL); if (serviceHandle == NULL) { BOOL error = GetLastError(); if (error == ERROR_SERVICE_EXISTS) { DokanDbgPrintW( L"DokanServiceInstall: Service (%s) is already installed\n", ServiceName); } else { DokanDbgPrintW( L"DokanServiceInstall: Failed to install service (%s). error = %d\n", ServiceName, error); } CloseServiceHandle(controlHandle); return FALSE; } CloseServiceHandle(serviceHandle); CloseServiceHandle(controlHandle); DokanDbgPrintW(L"DokanServiceInstall: Service (%s) installed\n", ServiceName); if (DokanServiceControl(ServiceName, DOKAN_SERVICE_START)) { DokanDbgPrintW(L"DokanServiceInstall: Service (%s) started\n", ServiceName); return TRUE; } else { DokanDbgPrintW(L"DokanServiceInstall: Service (%s) start failed\n", ServiceName); return FALSE; } }
BOOL DOKANAPI DokanServiceInstall( LPCWSTR ServiceName, DWORD ServiceType, LPCWSTR ServiceFullPath) { SC_HANDLE controlHandle; SC_HANDLE serviceHandle; controlHandle = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE); if (controlHandle == NULL) { DokanDbgPrint("failed to open SCM"); return FALSE; } serviceHandle = CreateService(controlHandle, ServiceName, ServiceName, 0, ServiceType, SERVICE_AUTO_START, SERVICE_ERROR_IGNORE, ServiceFullPath, NULL, NULL, NULL, NULL, NULL); if (serviceHandle == NULL) { if (GetLastError() == ERROR_SERVICE_EXISTS) DokanDbgPrint("Service is already installed\n"); else DokanDbgPrint("failted to install service: %d\n", GetLastError()); CloseServiceHandle(controlHandle); return FALSE; } CloseServiceHandle(serviceHandle); CloseServiceHandle(controlHandle); DokanDbgPrint("Service isntalled\n"); if (DokanServiceControl(ServiceName, DOKAN_SERVICE_START)) { DokanDbgPrint("Service started\n"); return TRUE; } else { DokanDbgPrint("Service start failed\n"); return FALSE; } }
static BOOL DokanServiceControl( LPCWSTR ServiceName, ULONG Type) { SC_HANDLE controlHandle; SC_HANDLE serviceHandle; SERVICE_STATUS ss; BOOL result = TRUE; controlHandle = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT); if (controlHandle == NULL) { DokanDbgPrint("failed to open SCM: %d\n", GetLastError()); return FALSE; } serviceHandle = OpenService(controlHandle, ServiceName, SERVICE_START | SERVICE_STOP | SERVICE_QUERY_STATUS | DELETE); if (serviceHandle == NULL) { DokanDbgPrint("failed to open Service: %d\n", GetLastError()); CloseHandle(controlHandle); return FALSE; } QueryServiceStatus(serviceHandle, &ss); if (Type == DOKAN_SERVICE_DELETE) { if (DeleteService(serviceHandle)) { DokanDbgPrint("Service deleted\n"); result = TRUE; } else { DokanDbgPrint("failed to delete service: %d\n", GetLastError()); result = FALSE; } } else if (ss.dwCurrentState == SERVICE_STOPPED && Type == DOKAN_SERVICE_START) { if (StartService(serviceHandle, 0, NULL)) { DokanDbgPrint("Service started\n"); result = TRUE; } else { DokanDbgPrint("failed to start service: %d\n", GetLastError()); result = FALSE; } } else if (ss.dwCurrentState == SERVICE_RUNNING && Type == DOKAN_SERVICE_STOP) { if (ControlService(serviceHandle, SERVICE_CONTROL_STOP, &ss)) { DokanDbgPrint("Service stopped\n"); result = TRUE; } else { DokanDbgPrint("failed to stop service: %d\n", GetLastError()); result = FALSE; } } CloseServiceHandle(serviceHandle); CloseServiceHandle(controlHandle); Sleep(100); return result; }
int DOKANAPI DokanMain(PDOKAN_OPTIONS DokanOptions, PDOKAN_OPERATIONS DokanOperations) { ULONG threadNum = 0; ULONG i; int error; HANDLE device; HANDLE threadIds[DOKAN_MAX_THREAD]; 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)) { CloseHandle(device); return DOKAN_START_ERROR; } if (!DokanMount(instance->MountPoint, instance->DeviceName)) { SendReleaseIRP(instance->DeviceName); DokanDbgPrint("Dokan Error: DefineDosDevice Failed\n"); return DOKAN_MOUNT_ERROR; } DbgPrintW(L"mounted: %s -> %s\n", instance->MountPoint, instance->DeviceName); //Start Keep Alive thread threadIds[threadNum++] = (HANDLE)_beginthreadex( NULL, // Security Attributes 0, //stack size DokanKeepAlive, (PVOID)instance, // param 0, // create flag NULL); for (i = 0; i < DokanOptions->ThreadCount; ++i) { threadIds[threadNum++] = (HANDLE)_beginthreadex( NULL, // Security Attributes 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; }
BOOL OnApply(HWND hwnd, PSHNOTIFY* phdr) { CSSHProperty::string_list* files = (CSSHProperty::string_list*)GetWindowLong(hwnd, GWL_USERDATA); HANDLE hFile; CSSHProperty::string_list::iterator it = files->begin(); for(; it != files->end(); ++it) { std::wstring file = *it + L":SSHFSProperty.Permission"; hFile = CreateFile( file.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); if (hFile == INVALID_HANDLE_VALUE) continue; char buffer[32]; DWORD readBytes = 0; ZeroMemory(buffer, sizeof(buffer)); if (!ReadFile(hFile, buffer, sizeof(buffer), &readBytes, NULL)) { CloseHandle(hFile); continue; } CloseHandle(hFile); int owner = buffer[0] - '0'; UINT state; state = IsDlgButtonChecked(hwnd, IDC_W_EXEC); if (state == BST_CHECKED) owner |= 0x1; if (state == BST_UNCHECKED) owner &= ~0x1; state = IsDlgButtonChecked(hwnd, IDC_W_WRITE); if (state == BST_CHECKED) owner |= 0x2; if (state == BST_UNCHECKED) owner &= ~0x2; state = IsDlgButtonChecked(hwnd, IDC_W_READ); if (state == BST_CHECKED) owner |= 0x4; if (state == BST_UNCHECKED) owner &= ~0x4; int group = buffer[1] - '0'; state = IsDlgButtonChecked(hwnd, IDC_G_EXEC); if (state == BST_CHECKED) group |= 0x1; if (state == BST_UNCHECKED) group &= ~0x1; state = IsDlgButtonChecked(hwnd, IDC_G_WRITE); if (state == BST_CHECKED) group |= 0x2; if (state == BST_UNCHECKED) group &= ~0x2; state = IsDlgButtonChecked(hwnd, IDC_G_READ); if (state == BST_CHECKED) group |= 0x4; if (state == BST_UNCHECKED) group &= ~0x4; int other = buffer[2] - '0'; state = IsDlgButtonChecked(hwnd, IDC_O_EXEC); if (state == BST_CHECKED) other |= 0x1; if (state == BST_UNCHECKED) other &= ~0x1; state = IsDlgButtonChecked(hwnd, IDC_O_WRITE); if (state == BST_CHECKED) other |= 0x2; if (state == BST_UNCHECKED) other &= ~0x2; state = IsDlgButtonChecked(hwnd, IDC_O_READ); if (state == BST_CHECKED) other |= 0x4; if (state == BST_UNCHECKED) other &= ~0x4; char newpermission[32]; ZeroMemory(newpermission, sizeof(newpermission)); newpermission[0] = owner + '0'; newpermission[1] = group + '0'; newpermission[2] = other + '0'; bool changed = false; for(int i=0; i<3; ++i) if(buffer[i] != newpermission[i]) changed = true; buffer[3] = '\0'; DokanDbgPrint("SSHFSProperty: %s %s -> %s\n", file.c_str(), buffer, newpermission); if (changed) { hFile = CreateFile( file.c_str(), GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (hFile == INVALID_HANDLE_VALUE) continue; DWORD writtenBytes = 0; WriteFile(hFile, newpermission, 3, &writtenBytes, NULL); CloseHandle(hFile); } } // Return PSNRET_NOERROR to allow the sheet to close if the user clicked OK. SetWindowLong(hwnd, DWL_MSGRESULT, PSNRET_NOERROR); return TRUE; }