Beispiel #1
0
int
CheckMountPoint(LPCWSTR	MountPoint)
{
	size_t	length = wcslen(MountPoint);

	if ((length == 1) ||
		(length == 2 && MountPoint[1] == L':') ||
		(length == 3 && MountPoint[1] == L':' && MountPoint[2] == L'\\')) {
		WCHAR driveLetter = MountPoint[0];
		
		if (IsValidDriveLetter(driveLetter)) {
			return DOKAN_SUCCESS;
		} else {
			DokanDbgPrintW(L"Dokan Error: bad drive letter %s\n", MountPoint);
			return DOKAN_DRIVE_LETTER_ERROR;
		}
	} else if (length > 3) {
		HANDLE handle = CreateFile(
						MountPoint, GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
						FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, NULL);
		if (handle == INVALID_HANDLE_VALUE) {
			DokanDbgPrintW(L"Dokan Error: bad mount point %s\n", MountPoint);
			return DOKAN_MOUNT_POINT_ERROR;
		}
		CloseHandle(handle);
		return DOKAN_SUCCESS;
	}
	return DOKAN_MOUNT_POINT_ERROR;
}
Beispiel #2
0
BOOL
CreateDriveLetter(WCHAR DriveLetter, LPCWSTR DeviceName)
{
	WCHAR   dosDevice[] = L"\\\\.\\C:";
	WCHAR   driveName[] = L"C:";
	WCHAR	rawDeviceName[MAX_PATH] = L"\\Device";
	HANDLE  device;

	dosDevice[4] = DriveLetter;
	driveName[0] = DriveLetter;
	wcscat_s(rawDeviceName, MAX_PATH, DeviceName);

	DokanDbgPrintW(L"DriveLetter: %c, DeviceName %s\n", DriveLetter, rawDeviceName);

	device = CreateFile(
		dosDevice,
		GENERIC_READ | GENERIC_WRITE,
		FILE_SHARE_READ | FILE_SHARE_WRITE,
		NULL,
		OPEN_EXISTING,
		FILE_FLAG_NO_BUFFERING,
		NULL
		);

    if (device != INVALID_HANDLE_VALUE) {
    	DokanDbgPrintW(L"DokanControl Mount failed: %c: is alredy used\n", DriveLetter);
		CloseHandle(device);
        return FALSE;
    }

    if (!DefineDosDevice(DDD_RAW_TARGET_PATH, driveName, rawDeviceName)) {
    	DokanDbgPrintW(L"DokanControl DefineDosDevice failed: %d\n", GetLastError());
        return FALSE;
    }

	device = CreateFile(
        dosDevice,
        GENERIC_READ | GENERIC_WRITE,
        FILE_SHARE_READ | FILE_SHARE_WRITE,
        NULL,
        OPEN_EXISTING,
        FILE_FLAG_NO_BUFFERING,
        NULL
        );

    if (device == INVALID_HANDLE_VALUE) {
    	DokanDbgPrintW(L"DokanControl Mount %c failed:%d\n", DriveLetter, GetLastError());
        DefineDosDevice(DDD_REMOVE_DEFINITION, dosDevice, NULL);
        return FALSE;
    }

	CloseHandle(device);
	return TRUE;
}
Beispiel #3
0
static BOOL DokanServiceCheck(LPCWSTR ServiceName) {
  SC_HANDLE controlHandle;
  SC_HANDLE serviceHandle;

  controlHandle = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);

  if (controlHandle == NULL) {
    DbgPrint("DokanServiceCheck: Failed to open Service Control Manager. error "
             "= %d\n",
             GetLastError());
    return FALSE;
  }

  serviceHandle =
      OpenService(controlHandle, ServiceName,
                  SERVICE_START | SERVICE_STOP | SERVICE_QUERY_STATUS);

  if (serviceHandle == NULL) {
    DokanDbgPrintW(
        L"DokanServiceCheck: Failed to open Service (%s). error = %d\n",
        ServiceName, GetLastError());
    CloseServiceHandle(controlHandle);
    return FALSE;
  }

  CloseServiceHandle(serviceHandle);
  CloseServiceHandle(controlHandle);

  return TRUE;
}
Beispiel #4
0
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;
  }
}
Beispiel #5
0
static BOOL
CheckMount(WCHAR drive)
{
    HANDLE pipe;
    DWORD readBytes;
    DWORD pipeMode;

    DOKAN_CONTROL control;
    ZeroMemory(&control, sizeof(DOKAN_CONTROL));

    control.Type = DOKAN_CONTROL_CHECK;
    control.Check.Drive = drive;

    DokanDbgPrintW(L"CheckMount Drive: %c\n", drive);

    pipe = CreateFile(DOKAN_CONTROL_PIPE,
                      GENERIC_READ|GENERIC_WRITE,
                      0, NULL, OPEN_EXISTING, 0, NULL);

    if (pipe == INVALID_HANDLE_VALUE) {
        if (GetLastError() == ERROR_ACCESS_DENIED) {
            DokanDbgPrintW(L"failed to connect DokanMounter service: access denied\n");
        } else {
            DokanDbgPrintW(L"failed to connect DokanMounter service: %d\n", GetLastError());
        }
        return FALSE;
    }

    pipeMode = PIPE_READMODE_MESSAGE|PIPE_WAIT;

    if(!SetNamedPipeHandleState(pipe, &pipeMode, NULL, NULL)) {
        DokanDbgPrintW(L"failed to set named pipe state\n");
        return FALSE;
    }


    if(!TransactNamedPipe(pipe, &control, sizeof(DOKAN_CONTROL),
                          &control, sizeof(DOKAN_CONTROL), &readBytes, NULL)) {

        DokanDbgPrintW(L"failed to transact named pipe\n");
    }

    if(control.Status != DOKAN_CONTROL_FAIL)
        return TRUE;
    else
        return FALSE;
}
Beispiel #6
0
static BOOL
CheckMount2(LPCWSTR FileName)
{
    std::wstring file = std::wstring(FileName) + L":SSHFSProperty.Permission";

    DokanDbgPrintW(L"Check SSHFS file %s\n", file.c_str());

    HANDLE handle = CreateFile(
                        file.c_str(),
                        FILE_GENERIC_READ,
                        FILE_SHARE_READ,
                        0,
                        OPEN_EXISTING,
                        0,
                        0);

    if (handle == INVALID_HANDLE_VALUE) {
        return FALSE;
    }
    CloseHandle(handle);
    return TRUE;
}
Beispiel #7
0
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;
}
Beispiel #8
0
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("DokanServiceControl: Failed to open Service Control "
                  "Manager. error = %d\n",
                  GetLastError());
    return FALSE;
  }

  serviceHandle =
      OpenService(controlHandle, ServiceName,
                  SERVICE_START | SERVICE_STOP | SERVICE_QUERY_STATUS | DELETE);

  if (serviceHandle == NULL) {
    DokanDbgPrintW(
        L"DokanServiceControl: Failed to open Service (%s). error = %d\n",
        ServiceName, GetLastError());
    CloseServiceHandle(controlHandle);
    return FALSE;
  }

  QueryServiceStatus(serviceHandle, &ss);

  if (Type == DOKAN_SERVICE_DELETE) {
    if (DeleteService(serviceHandle)) {
      DokanDbgPrintW(L"DokanServiceControl: Service (%s) deleted\n",
                     ServiceName);
      result = TRUE;
    } else {
      DokanDbgPrintW(
          L"DokanServiceControl: Failed to delete service (%s). error = %d\n",
          ServiceName, GetLastError());
      result = FALSE;
    }

  } else if (ss.dwCurrentState == SERVICE_STOPPED &&
             Type == DOKAN_SERVICE_START) {
    if (StartService(serviceHandle, 0, NULL)) {
      DokanDbgPrintW(L"DokanServiceControl: Service (%s) started\n",
                     ServiceName);
      result = TRUE;
    } else {
      DokanDbgPrintW(
          L"DokanServiceControl: Failed to start service (%s). error = %d\n",
          ServiceName, GetLastError());
      result = FALSE;
    }

  } else if (ss.dwCurrentState == SERVICE_RUNNING &&
             Type == DOKAN_SERVICE_STOP) {

    if (ControlService(serviceHandle, SERVICE_CONTROL_STOP, &ss)) {
      DokanDbgPrintW(L"DokanServiceControl: Service (%s) stopped\n",
                     ServiceName);
      result = TRUE;
    } else {
      DokanDbgPrintW(
          L"DokanServiceControl: Failed to stop service (%s). error = %d\n",
          ServiceName, GetLastError());
      result = FALSE;
    }
  }

  CloseServiceHandle(serviceHandle);
  CloseServiceHandle(controlHandle);

  Sleep(100);
  return result;
}
Beispiel #9
0
BOOL
OnInitDialog(HWND hwnd, LPARAM lParam)
{
    CSSHProperty::string_list*	files;
    PROPSHEETPAGE*	ppsp = (PROPSHEETPAGE*)lParam;

    files = (CSSHProperty::string_list*)ppsp->lParam;

    if (!files)
        return FALSE;

    // Store the filename in this window's user data area, for later use.
    SetWindowLong(hwnd, GWL_USERDATA, (LONG)files);

    CSSHProperty::string_list::iterator it = files->begin();

    int reads[3];
    int writes[3];
    int execs[3];

    ZeroMemory(reads, sizeof(reads));
    ZeroMemory(writes, sizeof(writes));
    ZeroMemory(execs, sizeof(execs));

    for (; it != files->end(); ++it) {
        std::wstring file = *it;
        file += L":SSHFSProperty.Permission";

        HANDLE hFile = CreateFile(
                           file.c_str(),
                           GENERIC_READ,
                           FILE_SHARE_READ,
                           NULL,
                           OPEN_EXISTING,
                           0,
                           NULL);

        if(hFile == INVALID_HANDLE_VALUE)
            continue;

        char buffer[32];
        ZeroMemory(buffer, sizeof(buffer));

        DWORD readBytes = 0;
        if (ReadFile(hFile, buffer, sizeof(buffer), &readBytes, NULL)) {
            int p = atoi(buffer);
            DokanDbgPrintW(L"%s, %d\n", file.c_str(), p);


            for(int i=0; i<3; ++i) {
                p = buffer[i] - '0';
                if (p & 0x1)
                    execs[i]++;
                if (p & 0x2)
                    writes[i]++;
                if (p & 0x4)
                    reads[i]++;
            }
        }

        CloseHandle(hFile);
    }

    int count = (int)files->size();

    CheckDlgButton(hwnd, IDC_W_READ,
                   reads[0] == 0 ? BST_UNCHECKED :
                   (reads[0] == count ? BST_CHECKED : BST_INDETERMINATE));
    CheckDlgButton(hwnd, IDC_W_WRITE,
                   writes[0] == 0 ? BST_UNCHECKED :
                   (writes[0] == count ? BST_CHECKED : BST_INDETERMINATE));
    CheckDlgButton(hwnd, IDC_W_EXEC,
                   execs[0] == 0 ? BST_UNCHECKED :
                   (execs[0] == count ? BST_CHECKED : BST_INDETERMINATE));

    CheckDlgButton(hwnd, IDC_G_READ,
                   reads[1] == 0 ? BST_UNCHECKED :
                   (reads[1] == count ? BST_CHECKED : BST_INDETERMINATE));
    CheckDlgButton(hwnd, IDC_G_WRITE,
                   writes[1] == 0 ? BST_UNCHECKED :
                   (writes[1] == count ? BST_CHECKED : BST_INDETERMINATE));
    CheckDlgButton(hwnd, IDC_G_EXEC,
                   execs[1] == 0 ? BST_UNCHECKED :
                   (execs[1] == count ? BST_CHECKED : BST_INDETERMINATE));

    CheckDlgButton(hwnd, IDC_O_READ,
                   reads[2] == 0 ? BST_UNCHECKED :
                   (reads[2] == count ? BST_CHECKED : BST_INDETERMINATE));
    CheckDlgButton(hwnd, IDC_O_WRITE,
                   writes[2] == 0 ? BST_UNCHECKED :
                   (writes[2] == count ? BST_CHECKED : BST_INDETERMINATE));
    CheckDlgButton(hwnd, IDC_O_EXEC,
                   execs[2] == 0 ? BST_UNCHECKED :
                   (execs[2] == count ? BST_CHECKED : BST_INDETERMINATE));


    return FALSE; // Take the default focus handling.
}
Beispiel #10
0
STDMETHODIMP
CSSHProperty::Initialize (
    LPCITEMIDLIST pidlFolder, LPDATAOBJECT pDataObj, HKEY hProgID )
{
    TCHAR     szFile[MAX_PATH];
    UINT      uNumFiles;
    HDROP     hdrop;
    FORMATETC etc = { CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
    STGMEDIUM stg;
    INITCOMMONCONTROLSEX iccex = { sizeof(INITCOMMONCONTROLSEX), ICC_DATE_CLASSES };
    BOOL	  mounted = FALSE;

    // Init the common controls.
    InitCommonControlsEx ( &iccex );

    // Read the list of folders from the data object.  They're stored in HDROP
    // form, so just get the HDROP handle and then use the drag 'n' drop APIs
    // on it.
    if (FAILED(pDataObj->GetData(&etc, &stg)))
        return E_INVALIDARG;

    // Get an HDROP handle.
    hdrop = (HDROP)GlobalLock(stg.hGlobal);

    if (NULL == hdrop)
    {
        ReleaseStgMedium(&stg);
        return E_INVALIDARG;
    }

    // Determine how many files are involved in this operation.
    uNumFiles = DragQueryFile(hdrop, 0xFFFFFFFF, NULL, 0);

    for (UINT uFile = 0; uFile < uNumFiles; uFile++ ) {

        // Get the next filename.
        if (0 == DragQueryFile(hdrop, uFile, szFile, MAX_PATH))
            continue;


        if (!mounted && CheckMount2(szFile))
            mounted = TRUE;

        // Skip over directories.  We *could* handle directories, since they
        // keep the creation time/date, but I'm just choosing not to do so
        // in this example project.
        //if ( PathIsDirectory ( szFile ) )
        //	continue;

        // Add the filename to our list o' files to act on.
        DokanDbgPrintW(L"add %s\n", szFile);
        m_lsFiles.push_back(szFile);
    }   // end for

    // Release resources.
    GlobalUnlock(stg.hGlobal);
    ReleaseStgMedium(&stg);

    // Check how many files were selected.  If the number is greater than the
    // maximum number of property pages, truncate our list.
    if (m_lsFiles.size() > MAXPROPPAGES)
        m_lsFiles.resize(MAXPROPPAGES);

    // If we found any files we can work with, return S_OK.  Otherwise,
    // return E_FAIL so we don't get called again for this right-click
    // operation.
    DokanDbgPrintW(mounted ? L"mounted\n" : L"not mounted\n");
    return (m_lsFiles.size() > 0 && mounted) ? S_OK : E_FAIL;
}