Beispiel #1
0
BOOL
DokanMount(
	ULONG	DeviceNumber,
	WCHAR	DriveLetter)
{
	HANDLE pipe;
	DOKAN_CONTROL control;

	ZeroMemory(&control, sizeof(DOKAN_CONTROL));
	control.Type = DOKAN_CONTROL_MOUNT;

	control.Mount.Device = DeviceNumber;
	control.Mount.Drive = DriveLetter;

	return  DokanControl(&control);
}
Beispiel #2
0
BOOL DOKANAPI
DokanUnmount(
	WCHAR DriveLetter)
{
	HANDLE pipe;
	DOKAN_CONTROL control;


	SendReleaseIRP(DriveLetter);

	ZeroMemory(&control, sizeof(DOKAN_CONTROL));
	control.Type = DOKAN_CONTROL_UNMOUNT;
	control.Unmount.Drive = DriveLetter;

	if (DokanControl(&control)) {
		return TRUE;
	} else {
		return FALSE;
	}
}
Beispiel #3
0
static VOID WINAPI ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv)
{
	DWORD			eventNo;
	HANDLE			pipe, device;
	HANDLE			eventConnect, eventUnmount;
	HANDLE			eventArray[3];
	DOKAN_CONTROL	control, unmount;
	OVERLAPPED		ov, driver;
	ULONG			returnedBytes;
	EVENT_CONTEXT	eventContext;
	SECURITY_ATTRIBUTES sa;

	UNREFERENCED_PARAMETER(dwArgc);
	UNREFERENCED_PARAMETER(lpszArgv);

    InitializeCriticalSectionAndSpinCount(&g_CriticalSection, 4000);
	InitializeListHead(&g_MountList);

	g_StatusHandle = RegisterServiceCtrlHandlerEx(L"DokanMounter", HandlerEx, NULL);

	// extend completion time
	g_ServiceStatus.dwServiceType				= SERVICE_WIN32_OWN_PROCESS;
	g_ServiceStatus.dwWin32ExitCode				= NO_ERROR;
	g_ServiceStatus.dwControlsAccepted			= SERVICE_ACCEPT_STOP;
	g_ServiceStatus.dwServiceSpecificExitCode	= 0;
	g_ServiceStatus.dwWaitHint					= 30000;
	g_ServiceStatus.dwCheckPoint				= 1;
	g_ServiceStatus.dwCurrentState				= SERVICE_START_PENDING;
	SetServiceStatus(g_StatusHandle, &g_ServiceStatus);

	BuildSecurityAttributes(&sa);

	pipe = CreateNamedPipe(DOKAN_CONTROL_PIPE,
		PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, 
		PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
		1, sizeof(control), sizeof(control), 1000, &sa);

	if (pipe == INVALID_HANDLE_VALUE) {
		// TODO: should do something
		DbgPrintW(L"DokanMounter: failed to create named pipe: %d\n", GetLastError());
	}

	device = CreateFile(
				DOKAN_GLOBAL_DEVICE_NAME,			// lpFileName
				GENERIC_READ | GENERIC_WRITE,       // dwDesiredAccess
				FILE_SHARE_READ | FILE_SHARE_WRITE, // dwShareMode
				NULL,                               // lpSecurityAttributes
				OPEN_EXISTING,                      // dwCreationDistribution
				FILE_FLAG_OVERLAPPED,               // dwFlagsAndAttributes
				NULL                                // hTemplateFile
			);
	
	if (device == INVALID_HANDLE_VALUE) {
		// TODO: should do something
		DbgPrintW(L"DokanMounter: failed to open device: %d\n", GetLastError());
	}

	eventConnect = CreateEvent(NULL, FALSE, FALSE, NULL);
	eventUnmount = CreateEvent(NULL, FALSE, FALSE, NULL);
	g_EventControl = CreateEvent(NULL, TRUE, FALSE, NULL);

	g_ServiceStatus.dwWaitHint     = 0;
	g_ServiceStatus.dwCheckPoint   = 0;
	g_ServiceStatus.dwCurrentState = SERVICE_RUNNING;
	SetServiceStatus(g_StatusHandle, &g_ServiceStatus);

	for (;;) {
		ZeroMemory(&ov, sizeof(OVERLAPPED));
		ZeroMemory(&driver, sizeof(OVERLAPPED));
		ZeroMemory(&eventContext, sizeof(EVENT_CONTEXT));

		ov.hEvent = eventConnect;
		driver.hEvent = eventUnmount;

		ConnectNamedPipe(pipe, &ov);
		if (!DeviceIoControl(device, IOCTL_SERVICE_WAIT, NULL, 0,
			&eventContext, sizeof(EVENT_CONTEXT), NULL, &driver)) {
			DWORD error = GetLastError();
			if (error != 997) {
				DbgPrintW(L"DokanMounter: DeviceIoControl error: %d\n", error);
			}
		}

		eventArray[0] = eventConnect;
		eventArray[1] = eventUnmount;
		eventArray[2] = g_EventControl;

		eventNo = WaitForMultipleObjects(3, eventArray, FALSE, INFINITE) - WAIT_OBJECT_0;

		DbgPrintW(L"DokanMounter: get an event\n");

		if (eventNo == 0) {

			DWORD result = 0;

			ZeroMemory(&control, sizeof(control));
			if (ReadFile(pipe, &control, sizeof(control), &result, NULL)) {
				DokanControl(&control);
				WriteFile(pipe, &control, sizeof(control), &result, NULL);
			}
			FlushFileBuffers(pipe);
			DisconnectNamedPipe(pipe);
		
		} else if (eventNo == 1) {

			if (GetOverlappedResult(device, &driver, &returnedBytes, FALSE)) {
				if (returnedBytes == sizeof(EVENT_CONTEXT)) {
					DbgPrintW(L"DokanMounter: Unmount\n");

					ZeroMemory(&unmount, sizeof(DOKAN_CONTROL));
					unmount.Type = DOKAN_CONTROL_UNMOUNT;
					unmount.Option = eventContext.Operation.Unmount.Option;
					wcscpy_s(unmount.DeviceName, sizeof(unmount.DeviceName) / sizeof(WCHAR),
						eventContext.Operation.Unmount.DeviceName);
					DokanControl(&unmount);
				} else {
					DbgPrintW(L"DokanMounter: Unmount error\n", control.Type);
				}
			}

		} else if (eventNo == 2) {
			DbgPrintW(L"DokanMounter: stop mounter service\n");
			g_ServiceStatus.dwWaitHint     = 0;
			g_ServiceStatus.dwCheckPoint   = 0;
			g_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
			SetServiceStatus(g_StatusHandle, &g_ServiceStatus);

			break;
		}
		else
			break;
	}


	CloseHandle(pipe);
	CloseHandle(eventConnect);
	CloseHandle(g_EventControl);
	CloseHandle(device);
	CloseHandle(eventUnmount);

	DeleteCriticalSection(&g_CriticalSection);

	return;
}