bool VDAgent::handle_clipboard_grab(VDAgentClipboardGrab* clipboard_grab, uint32_t size)
{
    std::set<uint32_t> grab_formats;

    _grab_types.clear();
    for (uint32_t i = 0; i < size / sizeof(clipboard_grab->types[0]); i++) {
        vd_printf("grab type %u", clipboard_grab->types[i]);
        uint32_t format = get_clipboard_format(clipboard_grab->types[i]);
        //On first supported type, open and empty the clipboard
        if (format && grab_formats.empty()) {
            if (!OpenClipboard(_hwnd)) {
                return false;
            }
            EmptyClipboard();
        }
        //For all supported type set delayed rendering
        if (format) {
            _grab_types.insert(clipboard_grab->types[i]);
            if (grab_formats.insert(format).second) {
                SetClipboardData(format, NULL);
            }
        }
    }
    if (grab_formats.empty()) {
        vd_printf("No supported clipboard types in client grab");
        return true;
    }
    CloseClipboard();
    set_clipboard_owner(owner_client);
    return true;
}
void VDAgent::write_completion(DWORD err, DWORD bytes, LPOVERLAPPED overlapped)
{
    VDAgent* a = _singleton;
    VDIChunk* chunk;
    DWORD count;

    ASSERT(!a->_message_queue.empty());
    if (err != 0) {
        vd_printf("vio_serial write completion error %lu", err);
        a->_running = false;
        return;
    }
    MUTEX_LOCK(a->_message_mutex);
    a->_write_pos += bytes;
    chunk = a->_message_queue.front();
    count = sizeof(VDIChunk) + chunk->hdr.size - a->_write_pos;
    if (count == 0) {
        a->_message_queue.pop();
        a->_write_pos = 0;
        delete chunk;
        if (!a->_message_queue.empty()) {
            chunk = a->_message_queue.front();
            count = sizeof(VDIChunk) + chunk->hdr.size;
        }
    }
    if (count) {
        if (!WriteFileEx(a->_vio_serial, (char*)chunk + a->_write_pos, count, overlapped,
                         write_completion) && GetLastError() != ERROR_IO_PENDING) {
            vd_printf("vio_serial write error %lu", GetLastError());
            a->_running = false;
        }
    }
    MUTEX_UNLOCK(a->_message_mutex);
}
예제 #3
0
파일: vdservice.cpp 프로젝트: damouse/PCC
DWORD WINAPI VDService::control_handler(DWORD control, DWORD event_type, LPVOID event_data,
                                        LPVOID context)
{
    VDService* s = _singleton;
    DWORD ret = NO_ERROR;

    ASSERT(s);
    switch (control) {
    case SERVICE_CONTROL_STOP:
    case SERVICE_CONTROL_SHUTDOWN:
        vd_printf("Stop service");
        s->_status.dwCurrentState = SERVICE_STOP_PENDING;
        SetServiceStatus(s->_status_handle, &s->_status);
        s->stop();
        break;
    case SERVICE_CONTROL_INTERROGATE:
        vd_printf("Interrogate service");
        SetServiceStatus(s->_status_handle, &s->_status);
        break;
    case SERVICE_CONTROL_SESSIONCHANGE: {
        DWORD session_id = ((WTSSESSION_NOTIFICATION*)event_data)->dwSessionId;
        vd_printf("Session %lu %s", session_id, session_events[event_type]);
        SetServiceStatus(s->_status_handle, &s->_status);
        if (event_type == WTS_CONSOLE_CONNECT) {
            s->_session_id = session_id;
            s->set_control_event(VD_CONTROL_RESTART_AGENT);
        }
        break;
    }
    default:
        vd_printf("Unsupported control %lu", control);
        ret = ERROR_CALL_NOT_IMPLEMENTED;
    }
    return ret;
}
bool VDAgent::send_input()
{
    bool ret = true;
    _desktop_layout->lock();
    if (_pending_input) {
        if (KillTimer(_hwnd, VD_TIMER_ID)) {
            _pending_input = false;
        } else {
            vd_printf("KillTimer failed: %lu", GetLastError());
            _running = false;
            _desktop_layout->unlock();
            return false;
        }
    }
    if (!SendInput(1, &_input, sizeof(INPUT))) {
        DWORD err = GetLastError();
        // Don't stop agent due to UIPI blocking, which is usually only for specific windows
        // of system security applications (anti-viruses etc.)
        if (err != ERROR_SUCCESS && err != ERROR_ACCESS_DENIED) {
            vd_printf("SendInput failed: %lu", err);
            ret = _running = false;
        }
    }
    _input_time = GetTickCount();
    _desktop_layout->unlock();
    return ret;
}
void VDAgent::handle_control_event()
{
    MUTEX_LOCK(_control_mutex);
    while (_control_queue.size()) {
        int control_command = _control_queue.front();
        _control_queue.pop();
        vd_printf("Control command %d", control_command);
        switch (control_command) {
        case CONTROL_STOP:
            _running = false;
            break;
        case CONTROL_DESKTOP_SWITCH:
            _desktop_switch = true;
            break;
        case CONTROL_LOGON:
            vd_printf("session logon");
            // loading the display settings for the current session's logged on user only
            // after 1) we receive logon event, and 2) the desktop switched from Winlogon
            if (!_logon_desktop) {
                vd_printf("LOGON display setting");
                _display_setting.load();
            } else {
                _logon_occured = true;
            }
            break;
        case CONTROL_CLIPBOARD:
            _clipboard_tick = 0;
            break;
        default:
            vd_printf("Unsupported control command %u", control_command);
        }
    }
    MUTEX_UNLOCK(_control_mutex);
}
void VDAgent::dispatch_message(VDAgentMessage* msg, uint32_t port)
{
    bool res = true;

    switch (msg->type) {
    case VD_AGENT_MOUSE_STATE:
        res = handle_mouse_event((VDAgentMouseState*)msg->data);
        break;
    case VD_AGENT_MONITORS_CONFIG:
        res = handle_mon_config((VDAgentMonitorsConfig*)msg->data, port);
        break;
    case VD_AGENT_CLIPBOARD:
        handle_clipboard((VDAgentClipboard*)msg->data, msg->size - sizeof(VDAgentClipboard));
        break;
    case VD_AGENT_CLIPBOARD_GRAB:
        handle_clipboard_grab((VDAgentClipboardGrab*)msg->data, msg->size);        
        break;
    case VD_AGENT_CLIPBOARD_REQUEST:
        res = handle_clipboard_request((VDAgentClipboardRequest*)msg->data);
        if (!res) {
            VDAgentClipboard clipboard = {VD_AGENT_CLIPBOARD_NONE};
            res = write_message(VD_AGENT_CLIPBOARD, sizeof(clipboard), &clipboard);
        }
        break;
    case VD_AGENT_CLIPBOARD_RELEASE:
        handle_clipboard_release();
        break;
    case VD_AGENT_DISPLAY_CONFIG:
        res = handle_display_config((VDAgentDisplayConfig*)msg->data, port);
        break;
    case VD_AGENT_ANNOUNCE_CAPABILITIES:
        res = handle_announce_capabilities((VDAgentAnnounceCapabilities*)msg->data, msg->size);
        break;
    case VD_AGENT_FILE_XFER_START:
    case VD_AGENT_FILE_XFER_STATUS:
    case VD_AGENT_FILE_XFER_DATA: {
        VDAgentFileXferStatusMessage status;
        if (_file_xfer.dispatch(msg, &status)) {
            write_message(VD_AGENT_FILE_XFER_STATUS, sizeof(status), &status);
        }
        break;
    }
    case VD_AGENT_CLIENT_DISCONNECTED:
        vd_printf("Client disconnected, agent to be restarted");
        set_control_event(CONTROL_STOP);
        break;
    case VD_AGENT_MAX_CLIPBOARD:
        res = handle_max_clipboard((VDAgentMaxClipboard*)msg->data, msg->size);
        break;
    default:
        vd_printf("Unsupported message type %u size %u", msg->type, msg->size);
    }
    if (!res) {
        vd_printf("handling message type %u failed: %lu", msg->type, GetLastError());
        _running = false;
    }
}
예제 #7
0
파일: int_handlers.c 프로젝트: yuki74w/TRON
/*
==================================================================================
 Funtion	:handle_tss_error
 Input		:struct ctx_reg *reg
 		 < context register information >
 		 uint32_t error_code
 		 < error code>
 Output		:void
 Return		:void
 Description	:default handler(10) for tss error exception
==================================================================================
*/
LOCAL void handle_tss_error(struct ctx_reg *reg, uint32_t error_code)
{
	static tss_error = 0;
	
	if (tss_error++) {
		vd_printf("error code:%u\n", error_code);
		vd_printf("tss error[0x%08X]\n", error_code);
		for (;;);
	}
}
LRESULT CALLBACK VDAgent::wnd_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
{
    VDAgent* a = _singleton;

    switch (message) {
    case WM_DISPLAYCHANGE:
        vd_printf("Display change");
        // the desktop layout needs to be updated for the mouse
        // position to be scaled correctly
        if (!a->_updating_display_config)
            a->_desktop_layout->get_displays();
        break;
    case WM_TIMER:
        a->send_input();
        break;
    case WM_CHANGECBCHAIN:
        if (a->_hwnd_next_viewer == (HWND)wparam) {
            a->_hwnd_next_viewer = (HWND)lparam;
        } else if (a->_hwnd_next_viewer) {
            SendMessage(a->_hwnd_next_viewer, message, wparam, lparam);
        }
        break;
    case WM_CLIPBOARDUPDATE:
    case WM_DRAWCLIPBOARD:
        if (a->_hwnd != GetClipboardOwner()) {
            a->set_clipboard_owner(a->owner_none);
            a->on_clipboard_grab();
        }
        if (a->_hwnd_next_viewer) {
            SendMessage(a->_hwnd_next_viewer, message, wparam, lparam);
        }
        break;
    case WM_RENDERFORMAT:
        a->on_clipboard_request((UINT)wparam);
        break;
    case WM_ENDSESSION:
        if (wparam) {
            vd_printf("Session ended");
            if (a->_clipboard_owner == owner_guest) {
                a->set_clipboard_owner(owner_none);
            }
            a->set_control_event(CONTROL_STOP);
        }
        break;
    case WM_WTSSESSION_CHANGE:
        if (wparam == WTS_SESSION_LOGON) {
            a->set_control_event(CONTROL_LOGON);
        }
        break;
    default:
        return DefWindowProc(hwnd, message, wparam, lparam);
    }
    return 0;
}
bool VDAgent::handle_max_clipboard(VDAgentMaxClipboard *msg, uint32_t size)
{
    if (size != sizeof(VDAgentMaxClipboard)) {
        vd_printf("VDAgentMaxClipboard: unexpected msg size %u (expected %lu)",
                  size, (unsigned long)sizeof(VDAgentMaxClipboard));
        return false;
    }
    vd_printf("Set max clipboard size: %d", msg->max);
    _max_clipboard = msg->max;
    return true;
}
void VDAgent::on_clipboard_grab()
{
    uint32_t types[clipboard_formats_count * VD_CLIPBOARD_FORMAT_MAX_TYPES];
    int count = 0;

    if (!VD_AGENT_HAS_CAPABILITY(_client_caps, _client_caps_size,
                                 VD_AGENT_CAP_CLIPBOARD_BY_DEMAND)) {
        return;
    }
    if (CountClipboardFormats() == 0) {
        return;
    }
    for (unsigned int i = 0; i < clipboard_formats_count; i++) {
        if (IsClipboardFormatAvailable(clipboard_formats[i].format)) {
            for (uint32_t* ptype = clipboard_formats[i].types; *ptype; ptype++) {
                types[count++] = *ptype;
            }
        }
    }
    if (count) {
        write_message(VD_AGENT_CLIPBOARD_GRAB, count * sizeof(types[0]), types);
        set_clipboard_owner(owner_guest);
    } else {
        UINT format = 0;
        while ((format = EnumClipboardFormats(format))) {
            vd_printf("Unsupported clipboard format %u", format);
        }
    }  
}
void log_version()
{
    DWORD handle;
    TCHAR module_fname[MAX_PATH];
    TCHAR* info_buf = NULL;

    try {
        if (!GetModuleFileName(NULL, module_fname, MAX_PATH)) {
            throw;
        }
        DWORD version_inf_size = GetFileVersionInfoSize(module_fname, &handle);
        if (version_inf_size == 0) {
            throw;
        }
        TCHAR* info_buf = new TCHAR[version_inf_size];
        if (!GetFileVersionInfo(module_fname, handle, version_inf_size, info_buf)) {
            throw;
        }
        UINT size;
        VS_FIXEDFILEINFO* file_info;
        if (!VerQueryValue(info_buf, L"\\", (VOID**)&file_info, &size) ||
                size < sizeof(VS_FIXEDFILEINFO)) {
            throw;
        }
        vd_printf("%ld.%ld.%ld.%ld",
            file_info->dwFileVersionMS >> 16,
            file_info->dwFileVersionMS & 0x0ffff,
            file_info->dwFileVersionLS >> 16,
            file_info->dwFileVersionLS & 0x0ffff);
    } catch (...) {
        vd_printf("get version info failed");
    }
    delete[] info_buf;
}
예제 #12
0
파일: pit.c 프로젝트: Ninals-GitHub/TRON
/*
_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
 Funtion	:initPit
 Input		:void
 Output		:void
 Return		:ER
 		 < error status >
 Description	:intialize a programmable interval timer
_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
*/
EXPORT ER initPit(void)
{
	ER err;
	uint32_t fperiod;
	
	/* -------------------------------------------------------------------- */
	/* register timer interrupt for irq 0					*/
	/* -------------------------------------------------------------------- */
	err = register_int_handler(INT_IRQ0, pit_intterupt);

	if (err) {
		vd_printf("err[%d]:cannot register pit interrupt handler\n", err);
		return(err);
	}

	if (PIT_CLOCK < TIMER_PERIOD) {
		fperiod = PIT_CLOCK;
		TIMER_PERIOD = PIT_CLOCK;
	} else {
		fperiod = (uint32_t)(1000 / TIMER_PERIOD);
	}

	/* -------------------------------------------------------------------- */
	/* set 10 ms interval							*/
	/* -------------------------------------------------------------------- */
	setPitCounter(fperiod, PIT_COUNTER0, PIT_COM_MODE_SQUAREWAVE);

	/* -------------------------------------------------------------------- */
	/* enable irq 0								*/
	/* -------------------------------------------------------------------- */
	reqEnableIrq(INT_IRQ0);

	return(E_OK);
}
void VDAgent::event_dispatcher(DWORD timeout, DWORD wake_mask)
{
    HANDLE events[] = {_control_event, _stop_event};
    DWORD event_count = _stop_event ? 2 : 1;
    DWORD wait_ret;
    MSG msg;

    wait_ret = MsgWaitForMultipleObjectsEx(event_count, events, timeout, wake_mask, MWMO_ALERTABLE);
    if (wait_ret == WAIT_OBJECT_0 + event_count) {
        while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        return;
    }
    switch (wait_ret) {
    case WAIT_OBJECT_0:
        handle_control_event();
        break;
    case WAIT_OBJECT_0 + 1:
        _running = false;
        break;
    case WAIT_IO_COMPLETION:
    case WAIT_TIMEOUT:
        break;
    default:
        vd_printf("MsgWaitForMultipleObjectsEx failed: %lu %lu", wait_ret, GetLastError());
        _running = false;
    }
}
bool VDAgent::handle_clipboard(VDAgentClipboard* clipboard, uint32_t size)
{
    HANDLE clip_data;
    UINT format;
    bool ret = false;

    if (_clipboard_owner != owner_client) {
        vd_printf("Received clipboard data from client while clipboard is not owned by client");
        goto fin;
    }
    if (clipboard->type == VD_AGENT_CLIPBOARD_NONE) {
        goto fin;
    }
    switch (clipboard->type) {
    case VD_AGENT_CLIPBOARD_UTF8_TEXT:
        clip_data = utf8_alloc((LPCSTR)clipboard->data, size);
        break;
    case VD_AGENT_CLIPBOARD_IMAGE_PNG:
    case VD_AGENT_CLIPBOARD_IMAGE_BMP: {
        DWORD cximage_format = get_cximage_format(clipboard->type);
        ASSERT(cximage_format);
        CxImage image(clipboard->data, size, cximage_format);
        clip_data = image.CopyToHandle();
        break;
    }
    default:
        vd_printf("Unsupported clipboard type %u", clipboard->type);
        goto fin;
    }
    format = get_clipboard_format(clipboard->type);
    if (format == 0) {
        vd_printf("Unknown clipboard format, type %u", clipboard->type);
        goto fin;
    }
    ret = !!SetClipboardData(format, clip_data);
    if (!ret) {
        DWORD err = GetLastError();
        if (err == ERROR_NOT_ENOUGH_MEMORY) {
            vd_printf("Not enough memory to set clipboard data, size %u bytes", size);
        } else {
            vd_printf("SetClipboardData failed: %lu", err);
        }
    }
fin:
    set_control_event(CONTROL_CLIPBOARD);
    return ret;
}
void VDAgent::set_control_event(int control_command)
{
    MUTEX_LOCK(_control_mutex);
    _control_queue.push(control_command);
    if (_control_event && !SetEvent(_control_event)) {
        vd_printf("SetEvent() failed: %lu", GetLastError());
    }
    MUTEX_UNLOCK(_control_mutex);
}
예제 #16
0
/*
 * Get memory
 */
LOCAL void* imalloc( size_t size, IMACB *imacb )
{
	QUEUE	*q;
	void	*mem;
	UW	imask;

	/* If it is smaller than the minimum fragment size,
	   allocate the minimum size to it. */
	if ( size < MIN_FRAGMENT ) {
		size = MIN_FRAGMENT;
	}
	size = ROUND(size);

	DI(imask);  /* Exclusive control by interrupt disable */

	/* Search FreeQue */
	q = searchFreeArea(size, imacb);
	if ( q != &imacb->freeque ) {
		/* There is free area: Split from FreeQue once */
		removeFreeQue(q);

		q = q - 1;
	} else {
		/* Reserve new pages because there is no free space */
		QUEUE	*e;
		size_t	n;

		/* Reserve pages */
		EI(imask);
		n = PageCount(size + sizeof(QUEUE) * 2);
		q = GetSysMemBlk(n, imacb->mematr);
		if ( q == NULL ) {
			goto err_ret;  /* Insufficient memory */
		}
		DI(imask);

		/* Register on AreaQue */
		e = (QUEUE*)((VB*)q + n * pagesz) - 1;
		insertAreaQue(&imacb->areaque, e);
		insertAreaQue(&imacb->areaque, q);
		setAreaFlag(q, AREA_TOP);
		setAreaFlag(e, AREA_END);
	}
	
	/* Allocate memory */
	mem = mem_alloc(q, size, imacb);

	EI(imask);
	return mem;

err_ret:
#ifdef DEBUG
	TM_DEBUG_PRINT(("imalloc error\n"));
#endif
	vd_printf("error imalloc\n");
	return NULL;
}
void VDAgent::handle_clipboard_release()
{
    if (_clipboard_owner != owner_client) {
        vd_printf("Received clipboard release from client while clipboard is not owned by client");
        return;
    }
    set_control_event(CONTROL_CLIPBOARD);
    set_clipboard_owner(owner_none);
}
예제 #18
0
파일: int_handlers.c 프로젝트: yuki74w/TRON
/*
==================================================================================
 Funtion	:handle_debug
 Input		:struct ctx_reg *reg
 		 < context register information >
 Output		:void
 Return		:void
 Description	:default handler(1) for debug exception
==================================================================================
*/
LOCAL void handle_debug(struct ctx_reg *reg)
{
	static count = 0;
	
	if (!count) {
		vd_printf("debug\n");
		count++;
	}
}
bool VDAgent::init_vio_serial()
{
    _vio_serial = CreateFile(VIOSERIAL_PORT_PATH, GENERIC_READ | GENERIC_WRITE , 0, NULL,
                             OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
    if (_vio_serial == INVALID_HANDLE_VALUE) {
        vd_printf("Failed opening %ls, error %lu", VIOSERIAL_PORT_PATH, GetLastError());
        return false;
    }
    return true;
}
DWORD WINAPI VDAgent::event_thread_proc(LPVOID param)
{
    HANDLE desktop_event = OpenEvent(SYNCHRONIZE, FALSE, L"WinSta0_DesktopSwitch");
    if (!desktop_event) {
        vd_printf("OpenEvent() failed: %lu", GetLastError());
        return 1;
    }
    while (_singleton->_running) {
        DWORD wait_ret = WaitForSingleObject(desktop_event, INFINITE);
        switch (wait_ret) {
        case WAIT_OBJECT_0:
            _singleton->set_control_event(CONTROL_DESKTOP_SWITCH);
            break;
        case WAIT_TIMEOUT:
        default:
            vd_printf("WaitForSingleObject(): %lu", wait_ret);
        }
    }
    CloseHandle(desktop_event);
    return 0;
}
bool VDAgent::handle_announce_capabilities(VDAgentAnnounceCapabilities* announce_capabilities,
                                           uint32_t msg_size)
{
    uint32_t caps_size = VD_AGENT_CAPS_SIZE_FROM_MSG_SIZE(msg_size);

    vd_printf("Got capabilities (%d)", caps_size);
    for (uint32_t i = 0 ; i < caps_size; ++i) {
        vd_printf("%X", announce_capabilities->caps[i]);
    }
    if (caps_size != _client_caps_size) {
        delete[] _client_caps;
        _client_caps = new uint32_t[caps_size];
        ASSERT(_client_caps != NULL);
        _client_caps_size = caps_size;
    }
    memcpy(_client_caps, announce_capabilities->caps, sizeof(_client_caps[0]) * caps_size);
    if (announce_capabilities->request) {
        return send_announce_capabilities(false);
    }
    return true;
}
bool VDAgent::send_announce_capabilities(bool request)
{
    DWORD msg_size;
    VDIChunk* caps_chunk;
    VDAgentMessage* caps_msg;
    VDAgentAnnounceCapabilities* caps;
    uint32_t caps_size;
    uint32_t internal_msg_size = sizeof(VDAgentAnnounceCapabilities) + VD_AGENT_CAPS_BYTES;

    msg_size = VD_MESSAGE_HEADER_SIZE + internal_msg_size;
    caps_chunk = new_chunk(msg_size);
    if (!caps_chunk) {
        return false;
    }
    caps_size = VD_AGENT_CAPS_SIZE;
    caps_chunk->hdr.port = VDP_CLIENT_PORT;
    caps_chunk->hdr.size = sizeof(VDAgentMessage) + internal_msg_size;
    caps_msg = (VDAgentMessage*)caps_chunk->data;
    caps_msg->protocol = VD_AGENT_PROTOCOL;
    caps_msg->type = VD_AGENT_ANNOUNCE_CAPABILITIES;
    caps_msg->opaque = 0;
    caps_msg->size = internal_msg_size;
    caps = (VDAgentAnnounceCapabilities*)caps_msg->data;
    caps->request = request;
    memset(caps->caps, 0, VD_AGENT_CAPS_BYTES);
    VD_AGENT_SET_CAPABILITY(caps->caps, VD_AGENT_CAP_MOUSE_STATE);
    VD_AGENT_SET_CAPABILITY(caps->caps, VD_AGENT_CAP_MONITORS_CONFIG);
    VD_AGENT_SET_CAPABILITY(caps->caps, VD_AGENT_CAP_REPLY);
    VD_AGENT_SET_CAPABILITY(caps->caps, VD_AGENT_CAP_DISPLAY_CONFIG);
    VD_AGENT_SET_CAPABILITY(caps->caps, VD_AGENT_CAP_CLIPBOARD_BY_DEMAND);
    VD_AGENT_SET_CAPABILITY(caps->caps, VD_AGENT_CAP_SPARSE_MONITORS_CONFIG);
    VD_AGENT_SET_CAPABILITY(caps->caps, VD_AGENT_CAP_GUEST_LINEEND_CRLF);
    VD_AGENT_SET_CAPABILITY(caps->caps, VD_AGENT_CAP_MAX_CLIPBOARD);
    vd_printf("Sending capabilities:");
    for (uint32_t i = 0 ; i < caps_size; ++i) {
        vd_printf("%X", caps->caps[i]);
    }
    enqueue_chunk(caps_chunk);
    return true;
}
예제 #23
0
파일: vdservice.cpp 프로젝트: damouse/PCC
bool VDService::launch_agent()
{
    STARTUPINFO startup_info;
    BOOL ret = FALSE;

    ZeroMemory(&startup_info, sizeof(startup_info));
    startup_info.cb = sizeof(startup_info);
    startup_info.lpDesktop = const_cast<LPTSTR>(TEXT("Winsta0\\winlogon"));
    ZeroMemory(&_agent_proc_info, sizeof(_agent_proc_info));
    if (_system_version == SYS_VER_WIN_XP_CLASS) {
        if (_session_id == 0) {
            ret = CreateProcess(_agent_path, _agent_path, NULL, NULL, FALSE, 0, NULL, NULL,
                                &startup_info, &_agent_proc_info);
        } else {
            for (int i = 0; i < CREATE_PROC_MAX_RETRIES; i++) {
                ret = create_session_process_as_user(_session_id, TRUE, NULL, NULL, _agent_path,
                                                     NULL, NULL, FALSE, 0, NULL, NULL,
                                                     &startup_info, &_agent_proc_info);
                if (ret) {
                    vd_printf("create_session_process_as_user #%d", i);
                    break;
                }
                Sleep(CREATE_PROC_INTERVAL_MS);
            }
        }
    } else if (_system_version == SYS_VER_WIN_7_CLASS) {
        startup_info.lpDesktop = const_cast<LPTSTR>(TEXT("Winsta0\\default"));
        ret = create_process_as_user(_session_id, _agent_path, _agent_path, NULL, NULL, FALSE, 0,
                                     NULL, NULL, &startup_info, &_agent_proc_info);
    } else {
        vd_printf("Not supported in this system version");
        return false;
    }
    if (!ret) {
        vd_printf("CreateProcess() failed: %lu", GetLastError());
        return false;
    }
    _agent_alive = true;
    return true;
}
예제 #24
0
파일: vdservice.cpp 프로젝트: damouse/PCC
bool VDService::kill_agent()
{
    DWORD exit_code = 0;
    DWORD wait_ret;
    HANDLE proc_handle;
    bool ret = true;

    if (!_agent_alive) {
        return true;
    }
    _agent_alive = false;
    proc_handle = _agent_proc_info.hProcess;
    _agent_proc_info.hProcess = 0;
    SetEvent(_agent_stop_event);
    if (GetProcessId(proc_handle)) {
        wait_ret = WaitForSingleObject(proc_handle, VD_AGENT_TIMEOUT);
        switch (wait_ret) {
        case WAIT_OBJECT_0:
            if (GetExitCodeProcess(proc_handle, &exit_code)) {
                ret = (exit_code != STILL_ACTIVE);
            } else {
                vd_printf("GetExitCodeProcess() failed: %lu", GetLastError());
            }
            break;
        case WAIT_TIMEOUT:
            vd_printf("Wait timeout");
            ret = false;
            break;
        case WAIT_FAILED:
        default:
            vd_printf("WaitForSingleObject() failed: %lu", GetLastError());
            break;
        }
    }
    ResetEvent(_agent_stop_event);
    CloseHandle(proc_handle);
    CloseHandle(_agent_proc_info.hThread);
    ZeroMemory(&_agent_proc_info, sizeof(_agent_proc_info));
    return ret;
}
예제 #25
0
파일: int_handlers.c 프로젝트: yuki74w/TRON
/*
_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
 Funtion	:page_fault_handler
 Input		:uint32_t int_num
 		 < interrupt number >
 		 struct ctx_reg *reg
 		 < context register information >
 		 uint32_t error_code
 		 < error code >
 		 unsigned long fault_address
 		 < address at which fault occurs >
 Output		:void
 Return		:void
 Description	:handler for page fault
_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
*/
EXPORT void page_fault_handler(uint32_t int_num, struct ctx_reg *reg,
			uint32_t error_code, unsigned long fault_address)
{
	static int count = 0;

	if (1 <= count) {
		
	} else {
		vd_printf("page fault[0x%08X]\n", fault_address);
		vd_printf("error code:%u\n", error_code);
		vd_printf("eax:0x%08X ", reg->eax);
		vd_printf("ebx:0x%08X ", reg->ebx);
		vd_printf("ecx:0x%08X\n", reg->ecx);
		vd_printf("eip:0x%08X ", reg->eip);
		vd_printf("eflags:0x%08X ", reg->eflags);
		vd_printf("cs:0x%08X\n", reg->cs);
		vd_printf("esp:0x%08X ", reg->esp);
		vd_printf("ss:0x%08X\n", reg->ss);

		count++;
	}
}
예제 #26
0
/*
==================================================================================
 Funtion	:ramfs_mount
 Input		:struct file_system_type *fs_type
 		 < file system type of ramfs >
 		 int flags
 		 < mount flags >
 		 const char *dev_name
 		 < device name to mount >
 		 void *data
 		 < mount options >
 Output		:void
 Return		:struct dentry*
 		 < root dentry of ramfs >
 Description	:mount ramfs
==================================================================================
*/
LOCAL struct dentry* ramfs_mount(struct file_system_type *fs_type, int flags,
					const char *dev_name, void *data)
{
	int err;
	
	root_sb = sb_cache_alloc(fs_type, 0);
	
	if (UNLIKELY(!root_sb)) {
		vd_printf("ramfs_mount:error:root sb\n");
		return(NULL);
	}
	
	vd_printf("ramfs_fill_super\n");
	err = ramfs_fill_super(root_sb, NULL, 0);
	
	if (UNLIKELY(err)) {
		sb_cache_free(root_sb);
		return(NULL);
	}
	
	return(root_sb->s_root);
}
void VDAgent::handle_chunk(VDIChunk* chunk)
{
    //FIXME: currently assumes that multi-part msg arrives only from client port
    if (_in_msg_pos == 0 || chunk->hdr.port == VDP_SERVER_PORT) {
        if (chunk->hdr.size < sizeof(VDAgentMessage)) {
            return;
        }
        VDAgentMessage* msg = (VDAgentMessage*)chunk->data;
        if (msg->protocol != VD_AGENT_PROTOCOL) {
            vd_printf("Invalid protocol %u", msg->protocol);
            _running = false;
            return;
        }
        uint32_t msg_size = sizeof(VDAgentMessage) + msg->size;
        if (chunk->hdr.size == msg_size) {
            dispatch_message(msg, chunk->hdr.port);
        } else {
            ASSERT(chunk->hdr.size < msg_size);
            _in_msg = (VDAgentMessage*)new uint8_t[msg_size];
            memcpy(_in_msg, chunk->data, chunk->hdr.size);
            _in_msg_pos = chunk->hdr.size;
        }
    } else {
        memcpy((uint8_t*)_in_msg + _in_msg_pos, chunk->data, chunk->hdr.size);
        _in_msg_pos += chunk->hdr.size;
        // update clipboard tick on each clipboard chunk for timeout setting
        if (_in_msg->type == VD_AGENT_CLIPBOARD && _clipboard_tick) {
            _clipboard_tick = GetTickCount();
        }
        if (_in_msg_pos == sizeof(VDAgentMessage) + _in_msg->size) {
            if (_in_msg->type == VD_AGENT_CLIPBOARD && !_clipboard_tick) {
                vd_printf("Clipboard received but dropped due to timeout");
            } else {
                dispatch_message(_in_msg, 0);
            }
            cleanup_in_msg();
        }
    }
}
예제 #28
0
/*
_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
 Funtion	:init_super_block
 Input		:void
 Output		:void
 Return		:int
 		 < result >
 Description	:initialize super block management
_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
*/
EXPORT int init_super_block(void)
{
    super_block_cache = kmem_cache_create(super_block_cache_name,
                                          sizeof(struct super_block), 0, 0, NULL);

    if (UNLIKELY(!super_block_cache)) {
        vd_printf("error:super_block_cache\n");
        return(-ENOMEM);
    }

    next_ino = 1;

    return(0);
}
VOID VDAgent::read_completion(DWORD err, DWORD bytes, LPOVERLAPPED overlapped)
{
    VDAgent* a = _singleton;
    VDIChunk* chunk = (VDIChunk*)a->_read_buf;
    DWORD count;

    if (err != 0 && err != ERROR_OPERATION_ABORTED && err != ERROR_NO_SYSTEM_RESOURCES) {
        vd_printf("vio_serial read completion error %lu", err);
        a->_running = false;
        return;
    }

    a->_read_pos += bytes;
    if (a->_read_pos < sizeof(VDIChunk)) {
        count = sizeof(VDIChunk) - a->_read_pos;
    } else if (a->_read_pos == sizeof(VDIChunk)) {
        count = chunk->hdr.size;
        if (a->_read_pos + count > sizeof(a->_read_buf)) {
            vd_printf("chunk is too large, size %u port %u", chunk->hdr.size, chunk->hdr.port);
            a->_running = false;
            return;
        }
    } else if (a->_read_pos == sizeof(VDIChunk) + chunk->hdr.size){
        a->handle_chunk(chunk);
        count = sizeof(VDIChunk);
        a->_read_pos = 0;
    } else {
        ASSERT(a->_read_pos < sizeof(VDIChunk) + chunk->hdr.size);
        count = sizeof(VDIChunk) + chunk->hdr.size - a->_read_pos;
    }

    if (!ReadFileEx(a->_vio_serial, a->_read_buf + a->_read_pos, count, overlapped,
                    read_completion) && GetLastError() != ERROR_IO_PENDING) {
        vd_printf("vio_serial read error %lu", GetLastError());
        a->_running = false;
    }
}
// In delayed rendering, Windows requires us to SetClipboardData before we return from
// handling WM_RENDERFORMAT. Therefore, we try our best by sending CLIPBOARD_REQUEST to the
// agent, while waiting alertably for a while (hoping for good) for receiving CLIPBOARD data
// or CLIPBOARD_RELEASE from the agent, which both will signal clipboard_event.
// In case of unsupported format, wrong clipboard owner or no clipboard capability, we do nothing in
// WM_RENDERFORMAT and return immediately.
// FIXME: need to be handled using request queue
void VDAgent::on_clipboard_request(UINT format)
{
    uint32_t type;

    if (_clipboard_owner != owner_client) {
        vd_printf("Received render request event for format %u"
                  "while clipboard is not owned by client", format);
        return;
    }
    if (!(type = get_clipboard_type(format))) {
        vd_printf("Unsupported clipboard format %u", format);
        return;
    }
    if (!VD_AGENT_HAS_CAPABILITY(_client_caps, _client_caps_size,
                                 VD_AGENT_CAP_CLIPBOARD_BY_DEMAND)) {
        return;
    }

    VDAgentClipboardRequest request = {type};
    if (!write_message(VD_AGENT_CLIPBOARD_REQUEST, sizeof(request), &request)) {
        return;
    }

    _clipboard_tick = GetTickCount();
    while (_running && _clipboard_tick &&
           GetTickCount() < _clipboard_tick + VD_CLIPBOARD_TIMEOUT_MS) {
        event_dispatcher(VD_CLIPBOARD_TIMEOUT_MS, 0);
    }

    if (_clipboard_tick) {
        vd_printf("Clipboard wait timeout");
        _clipboard_tick = 0;
    } else {
        // reset incoming message state only upon completion (even after timeout)
        cleanup_in_msg();
    }
}