[Spice-commits] 13 commits - common/stdint.h common/vdcommon.h vdagent/desktop_layout.h vdagent.sln vdagent/vdagent.cpp vdagent/vdagent.vcproj vdservice/vdi_port.cpp vdservice/vdi_port.h vdservice/vdservice.cpp vdservice/vdservice.vcproj
Alon Levy
alon at kemper.freedesktop.org
Mon Aug 23 08:50:50 PDT 2010
common/stdint.h | 4
common/vdcommon.h | 9 +
vdagent.sln | 14 +
vdagent/desktop_layout.h | 2
vdagent/vdagent.cpp | 252 +++++++++++++++++++++++++++++++----
vdagent/vdagent.vcproj | 322 ++++++++++++++++++++++++++++++++++++++++++++-
vdservice/vdi_port.cpp | 259 ++++++++++++++++++++++++++----------
vdservice/vdi_port.h | 30 ++--
vdservice/vdservice.cpp | 209 ++++++++++++++++++-----------
vdservice/vdservice.vcproj | 322 ++++++++++++++++++++++++++++++++++++++++++++-
10 files changed, 1223 insertions(+), 200 deletions(-)
New commits:
commit 8eb3e2e816714100d82db1f384a2c9c3d5046f10
Author: Arnon Gilboa <agilboa at redhat.com>
Date: Mon Aug 23 16:12:47 2010 +0300
vdagent: support basic clipboard support (disabled by default)
-add CLIPBOARD_ENABLED ifdefs in the agent for disabling clipboard support
-currently supports text only (UTF8)
diff --git a/vdagent/vdagent.cpp b/vdagent/vdagent.cpp
index 20e6205..b7510f2 100644
--- a/vdagent/vdagent.cpp
+++ b/vdagent/vdagent.cpp
@@ -19,6 +19,8 @@
#include "desktop_layout.h"
#include <lmcons.h>
+//#define CLIPBOARD_ENABLED
+
#define VD_AGENT_LOG_PATH TEXT("%svdagent.log")
#define VD_AGENT_WINCLASS_NAME TEXT("VDAGENT")
#define VD_INPUT_INTERVAL_MS 20
@@ -35,7 +37,9 @@ private:
void input_desktop_message_loop();
bool handle_mouse_event(VDAgentMouseState* state);
bool handle_mon_config(VDAgentMonitorsConfig* mon_config, uint32_t port);
+ bool handle_clipboard(VDAgentClipboard* clipboard, uint32_t size);
bool handle_control(VDPipeMessage* msg);
+ bool on_clipboard_change();
DWORD get_buttons_change(DWORD last_buttons_state, DWORD new_buttons_state,
DWORD mask, DWORD down_flag, DWORD up_flag);
static LRESULT CALLBACK wnd_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam);
@@ -45,12 +49,15 @@ private:
static void dispatch_message(VDAgentMessage* msg, uint32_t port);
uint8_t* write_lock(DWORD bytes = 0);
void write_unlock(DWORD bytes = 0);
+ bool write_clipboard();
bool connect_pipe();
bool send_input();
private:
static VDAgent* _singleton;
HWND _hwnd;
+ HWND _hwnd_next_viewer;
+ bool _clipboard_changer;
DWORD _buttons_state;
LONG _mouse_x;
LONG _mouse_y;
@@ -59,6 +66,9 @@ private:
HANDLE _desktop_switch_event;
VDAgentMessage* _in_msg;
uint32_t _in_msg_pos;
+ VDAgentMessage* _out_msg;
+ uint32_t _out_msg_pos;
+ uint32_t _out_msg_size;
bool _pending_input;
bool _pending_write;
bool _running;
@@ -80,12 +90,17 @@ VDAgent* VDAgent::get()
VDAgent::VDAgent()
: _hwnd (NULL)
+ , _hwnd_next_viewer (NULL)
+ , _clipboard_changer (false)
, _buttons_state (0)
, _mouse_x (0)
, _mouse_y (0)
, _input_time (0)
, _in_msg (NULL)
, _in_msg_pos (0)
+ , _out_msg (NULL)
+ , _out_msg_pos (0)
+ , _out_msg_size (0)
, _pending_input (false)
, _pending_write (false)
, _running (false)
@@ -224,6 +239,7 @@ void VDAgent::input_desktop_message_loop()
_running = false;
return;
}
+ _hwnd_next_viewer = SetClipboardViewer(_hwnd);
while (_running && !desktop_switch) {
wait_ret = MsgWaitForMultipleObjectsEx(1, &_desktop_switch_event, INFINITE, QS_ALLINPUT,
MWMO_ALERTABLE);
@@ -249,6 +265,7 @@ void VDAgent::input_desktop_message_loop()
KillTimer(_hwnd, VD_TIMER_ID);
_pending_input = false;
}
+ ChangeClipboardChain(_hwnd, _hwnd_next_viewer);
DestroyWindow(_hwnd);
CloseDesktop(hdesk);
}
@@ -407,6 +424,48 @@ bool VDAgent::handle_mon_config(VDAgentMonitorsConfig* mon_config, uint32_t port
return true;
}
+//FIXME: currently supports text only
+bool VDAgent::handle_clipboard(VDAgentClipboard* clipboard, uint32_t size)
+{
+ HGLOBAL clip_data;
+ LPVOID clip_buf;
+ int clip_size;
+ UINT format;
+ bool ret;
+
+ switch (clipboard->type) {
+ case VD_AGENT_CLIPBOARD_UTF8_TEXT:
+ format = CF_UNICODETEXT;
+ break;
+ default:
+ vd_printf("Unsupported clipboard type %u", clipboard->type);
+ return false;
+ }
+ if (!OpenClipboard(_hwnd)) {
+ return false;
+ }
+ clip_size = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)clipboard->data, -1, NULL, 0);
+ if (!clip_size || !(clip_data = GlobalAlloc(GMEM_DDESHARE, clip_size * sizeof(WCHAR)))) {
+ CloseClipboard();
+ return false;
+ }
+ if (!(clip_buf = GlobalLock(clip_data))) {
+ GlobalFree(clip_data);
+ CloseClipboard();
+ return false;
+ }
+ ret = !!MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)clipboard->data, -1, (LPWSTR)clip_buf, clip_size);
+ GlobalUnlock(clip_data);
+ if (ret) {
+ EmptyClipboard();
+ //FIXME: nicify (compare clip_data)
+ _clipboard_changer = true;
+ ret = !!SetClipboardData(format, clip_data);
+ }
+ CloseClipboard();
+ return ret;
+}
+
bool VDAgent::handle_control(VDPipeMessage* msg)
{
switch (msg->type) {
@@ -435,6 +494,78 @@ bool VDAgent::handle_control(VDPipeMessage* msg)
return true;
}
+#define MIN(a, b) ((a) > (b) ? (b) : (a))
+
+//FIXME: cleanup
+//FIXME: division to max size chunks should NOT be here, but in the service
+// here we should write the max possible size to the pipe
+bool VDAgent::write_clipboard()
+{
+ ASSERT(_out_msg);
+ DWORD n = MIN(sizeof(VDPipeMessage) + _out_msg_size - _out_msg_pos, VD_AGENT_MAX_DATA_SIZE);
+ VDPipeMessage* pipe_msg = (VDPipeMessage*)write_lock(n);
+ if (!pipe_msg) {
+ return false;
+ }
+ pipe_msg->type = VD_AGENT_COMMAND;
+ //FIXME: client port should be in vd_agent.h
+ pipe_msg->opaque = 1;
+ pipe_msg->size = n - sizeof(VDPipeMessage);
+ memcpy(pipe_msg->data, (char*)_out_msg + _out_msg_pos, n - sizeof(VDPipeMessage));
+ write_unlock(n);
+ if (!_pending_write) {
+ write_completion(0, 0, &_pipe_state.write.overlap);
+ }
+ _out_msg_pos += (n - sizeof(VDPipeMessage));
+ if (_out_msg_pos == _out_msg_size) {
+ delete[] (uint8_t *)_out_msg;
+ _out_msg = NULL;
+ _out_msg_size = 0;
+ _out_msg_pos = 0;
+ }
+ return true;
+}
+
+//FIXME: currently supports text only
+bool VDAgent::on_clipboard_change()
+{
+ UINT format = CF_UNICODETEXT;
+ HANDLE clip_data;
+ LPVOID clip_buf;
+ int clip_size;
+
+ if (_out_msg) {
+ vd_printf("clipboard change is already pending");
+ return false;
+ }
+ if (!IsClipboardFormatAvailable(format) || !OpenClipboard(_hwnd)) {
+ return false;
+ }
+ if (!(clip_data = GetClipboardData(format)) || !(clip_buf = GlobalLock(clip_data))) {
+ CloseClipboard();
+ return false;
+ }
+ clip_size = WideCharToMultiByte(CP_UTF8, 0, (LPCWSTR)clip_buf, -1, NULL, 0, NULL, NULL);
+ if (!clip_size) {
+ GlobalUnlock(clip_data);
+ CloseClipboard();
+ return false;
+ }
+ _out_msg_pos = 0;
+ _out_msg_size = sizeof(VDAgentMessage) + sizeof(VDAgentClipboard) + clip_size;
+ _out_msg = (VDAgentMessage*)new uint8_t[_out_msg_size];
+ _out_msg->protocol = VD_AGENT_PROTOCOL;
+ _out_msg->type = VD_AGENT_CLIPBOARD;
+ _out_msg->opaque = 0;
+ _out_msg->size = (uint32_t)(sizeof(VDAgentClipboard) + clip_size);
+ VDAgentClipboard* clipboard = (VDAgentClipboard*)_out_msg->data;
+ clipboard->type = VD_AGENT_CLIPBOARD_UTF8_TEXT;
+ WideCharToMultiByte(CP_UTF8, 0, (LPCWSTR)clip_buf, -1, (LPSTR)clipboard->data, clip_size, NULL, NULL);
+ GlobalUnlock(clip_data);
+ CloseClipboard();
+ return write_clipboard();
+}
+
bool VDAgent::connect_pipe()
{
VDAgent* a = _singleton;
@@ -479,6 +610,15 @@ void VDAgent::dispatch_message(VDAgentMessage* msg, uint32_t port)
a->_running = false;
}
break;
+#ifdef CLIPBOARD_ENABLED
+ case VD_AGENT_CLIPBOARD:
+ if (!a->handle_clipboard((VDAgentClipboard*)msg->data,
+ msg->size - sizeof(VDAgentClipboard))) {
+ vd_printf("handle_clipboard failed: %u", GetLastError());
+ a->_running = false;
+ }
+ break;
+#endif // CLIPBOARD_ENABLED
default:
vd_printf("Unsupported message type %u size %u", msg->type, msg->size);
}
@@ -577,6 +717,8 @@ VOID CALLBACK VDAgent::write_completion(DWORD err, DWORD bytes, LPOVERLAPPED ove
ps->write.start += bytes;
if (ps->write.start == ps->write.end) {
ps->write.start = ps->write.end = 0;
+ //DEBUG
+ while (a->_out_msg && a->write_clipboard());
} else if (WriteFileEx(ps->pipe, ps->write.data + ps->write.start,
ps->write.end - ps->write.start, overlap, write_completion)) {
a->_pending_write = true;
@@ -617,6 +759,23 @@ LRESULT CALLBACK VDAgent::wnd_proc(HWND hwnd, UINT message, WPARAM wparam, LPARA
case WM_TIMER:
a->send_input();
break;
+#ifdef CLIPBOARD_ENABLED
+ 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_DRAWCLIPBOARD:
+ if (!a->_clipboard_changer) {
+ a->on_clipboard_change();
+ } else {
+ a->_clipboard_changer = false;
+ }
+ SendMessage(a->_hwnd_next_viewer, message, wparam, lparam);
+ break;
+#endif // CLIPBOARD_ENABLED
default:
return DefWindowProc(hwnd, message, wparam, lparam);
}
commit 81cd5620d2e5046cb863d0bc584049b6a760b209
Author: Arnon Gilboa <agilboa at redhat.com>
Date: Mon Aug 23 16:03:47 2010 +0300
vdservice/vdagent: fixes leading to clipboard (aka large) message handling
-add VDAgent::dispatch_message()
-in VDAgent::read_completion() handle multi-chunk msgs
-fix chunk size bug in VDService::handle_pipe_data()
-add size to VDPipeMessage
diff --git a/common/vdcommon.h b/common/vdcommon.h
index 8d4b4de..f097de4 100644
--- a/common/vdcommon.h
+++ b/common/vdcommon.h
@@ -44,6 +44,7 @@ enum {
typedef __declspec (align(1)) struct VDPipeMessage {
uint32_t type;
uint32_t opaque;
+ uint32_t size;
uint8_t data[0];
} VDPipeMessage;
diff --git a/vdagent/vdagent.cpp b/vdagent/vdagent.cpp
index a578dfd..20e6205 100644
--- a/vdagent/vdagent.cpp
+++ b/vdagent/vdagent.cpp
@@ -42,6 +42,7 @@ private:
static VOID CALLBACK read_completion(DWORD err, DWORD bytes, LPOVERLAPPED overlap);
static VOID CALLBACK write_completion(DWORD err, DWORD bytes, LPOVERLAPPED overlap);
static DWORD WINAPI event_thread_proc(LPVOID param);
+ static void dispatch_message(VDAgentMessage* msg, uint32_t port);
uint8_t* write_lock(DWORD bytes = 0);
void write_unlock(DWORD bytes = 0);
bool connect_pipe();
@@ -56,6 +57,8 @@ private:
INPUT _input;
DWORD _input_time;
HANDLE _desktop_switch_event;
+ VDAgentMessage* _in_msg;
+ uint32_t _in_msg_pos;
bool _pending_input;
bool _pending_write;
bool _running;
@@ -81,6 +84,8 @@ VDAgent::VDAgent()
, _mouse_x (0)
, _mouse_y (0)
, _input_time (0)
+ , _in_msg (NULL)
+ , _in_msg_pos (0)
, _pending_input (false)
, _pending_write (false)
, _running (false)
@@ -386,6 +391,7 @@ bool VDAgent::handle_mon_config(VDAgentMonitorsConfig* mon_config, uint32_t port
}
reply_pipe_msg->type = VD_AGENT_COMMAND;
reply_pipe_msg->opaque = port;
+ reply_pipe_msg->size = sizeof(VDAgentMessage) + sizeof(VDAgentReply);
reply_msg = (VDAgentMessage*)reply_pipe_msg->data;
reply_msg->protocol = VD_AGENT_PROTOCOL;
reply_msg->type = VD_AGENT_REPLY;
@@ -456,6 +462,27 @@ bool VDAgent::connect_pipe()
vd_printf("Connected to service pipe");
return true;
}
+void VDAgent::dispatch_message(VDAgentMessage* msg, uint32_t port)
+{
+ VDAgent* a = _singleton;
+
+ switch (msg->type) {
+ case VD_AGENT_MOUSE_STATE:
+ if (!a->handle_mouse_event((VDAgentMouseState*)msg->data)) {
+ vd_printf("handle_mouse_event failed: %u", GetLastError());
+ a->_running = false;
+ }
+ break;
+ case VD_AGENT_MONITORS_CONFIG:
+ if (!a->handle_mon_config((VDAgentMonitorsConfig*)msg->data, port)) {
+ vd_printf("handle_mon_config failed: %u", GetLastError());
+ a->_running = false;
+ }
+ break;
+ default:
+ vd_printf("Unsupported message type %u size %u", msg->type, msg->size);
+ }
+}
VOID CALLBACK VDAgent::read_completion(DWORD err, DWORD bytes, LPOVERLAPPED overlap)
{
@@ -480,35 +507,43 @@ VOID CALLBACK VDAgent::read_completion(DWORD err, DWORD bytes, LPOVERLAPPED over
ps->read.start += sizeof(VDPipeMessage);
continue;
}
- if (len < VD_MESSAGE_HEADER_SIZE) {
+ if (len < sizeof(VDPipeMessage) + pipe_msg->size) {
break;
}
- VDAgentMessage* msg = (VDAgentMessage*)pipe_msg->data;
- if (len < VD_MESSAGE_HEADER_SIZE + msg->size) {
- break;
- }
- if (msg->protocol != VD_AGENT_PROTOCOL) {
- vd_printf("Invalid protocol %d", msg->protocol);
- a->_running = false;
- break;
- }
- switch (msg->type) {
- case VD_AGENT_MOUSE_STATE:
- if (!a->handle_mouse_event((VDAgentMouseState*)msg->data)) {
- vd_printf("handle_mouse_event failed: %d", GetLastError());
- a->_running = false;
+
+ //FIXME: cleanup, specific to one port
+ if (a->_in_msg_pos == 0 || pipe_msg->opaque == 2 /*FIXME!*/) {
+ if (len < VD_MESSAGE_HEADER_SIZE) {
+ break;
}
- break;
- case VD_AGENT_MONITORS_CONFIG:
- if (!a->handle_mon_config((VDAgentMonitorsConfig*)msg->data, pipe_msg->opaque)) {
- vd_printf("handle_mon_config failed: %d", GetLastError());
+ VDAgentMessage* msg = (VDAgentMessage*)pipe_msg->data;
+ if (msg->protocol != VD_AGENT_PROTOCOL) {
+ vd_printf("Invalid protocol %u bytes %u", msg->protocol, bytes);
a->_running = false;
+ break;
+ }
+ uint32_t msg_size = sizeof(VDAgentMessage) + msg->size;
+ if (pipe_msg->size == msg_size) {
+ dispatch_message(msg, pipe_msg->opaque);
+ } else {
+ ASSERT(pipe_msg->size < msg_size);
+ a->_in_msg = (VDAgentMessage*)new uint8_t[msg_size];
+ memcpy(a->_in_msg, pipe_msg->data, pipe_msg->size);
+ a->_in_msg_pos = pipe_msg->size;
+ }
+ } else {
+ memcpy((uint8_t*)a->_in_msg + a->_in_msg_pos, pipe_msg->data, pipe_msg->size);
+ a->_in_msg_pos += pipe_msg->size;
+ //vd_printf("DEBUG: pipe_msg size %u pos %u total %u", pipe_msg->size, a->_in_msg_pos, sizeof(VDAgentMessage) + a->_in_msg->size);
+ if (a->_in_msg_pos == sizeof(VDAgentMessage) + a->_in_msg->size) {
+ dispatch_message(a->_in_msg, 0);
+ a->_in_msg_pos = 0;
+ delete[] (uint8_t *)a->_in_msg;
+ a->_in_msg = NULL;
}
- break;
- default:
- vd_printf("Unsupported message type %d size %d", msg->type, msg->size);
}
- ps->read.start += (VD_MESSAGE_HEADER_SIZE + msg->size);
+
+ ps->read.start += (sizeof(VDPipeMessage) + pipe_msg->size);
if (ps->read.start == ps->read.end) {
ps->read.start = ps->read.end = 0;
}
@@ -554,10 +589,11 @@ VOID CALLBACK VDAgent::write_completion(DWORD err, DWORD bytes, LPOVERLAPPED ove
uint8_t* VDAgent::write_lock(DWORD bytes)
{
+ MUTEX_LOCK(_write_mutex);
if (_pipe_state.write.end + bytes <= sizeof(_pipe_state.write.data)) {
- MUTEX_LOCK(_write_mutex);
return &_pipe_state.write.data[_pipe_state.write.end];
} else {
+ MUTEX_UNLOCK(_write_mutex);
vd_printf("write buffer is full");
return NULL;
}
diff --git a/vdservice/vdservice.cpp b/vdservice/vdservice.cpp
index 29b225a..157734b 100644
--- a/vdservice/vdservice.cpp
+++ b/vdservice/vdservice.cpp
@@ -437,8 +437,10 @@ bool VDService::execute()
if (cont_read >= 0 && cont_write >= 0) {
cont = cont_read || cont_write;
} else if (cont_read == VDI_PORT_ERROR || cont_write == VDI_PORT_ERROR) {
+ vd_printf("VDI Port error, read %d write %d", cont_read, cont_write);
_running = false;
} else if (cont_read == VDI_PORT_RESET || cont_write == VDI_PORT_RESET) {
+ vd_printf("VDI Port reset, read %d write %d", cont_read, cont_write);
_chunk_size = _chunk_port = 0;
write_agent_control(VD_AGENT_RESET, ++_connection_id);
_pending_reset = true;
@@ -865,6 +867,7 @@ bool VDService::restart_agent(bool normal_restart)
void VDService::stop()
{
+ vd_printf("Service stopped");
_running = false;
if (_control_event && !SetEvent(_control_event)) {
vd_printf("SetEvent() failed: %u", GetLastError());
@@ -916,9 +919,9 @@ void VDService::read_pipe()
if (ps->read.end < sizeof(ps->read.data)) {
_pending_read = true;
if (ReadFile(ps->pipe, ps->read.data + ps->read.end, sizeof(ps->read.data) - ps->read.end,
- &bytes, &ps->read.overlap)) {
+ &bytes, &ps->read.overlap) || GetLastError() == ERROR_MORE_DATA) {
_pending_read = false;
- vd_printf("ReadFile without pending");
+ vd_printf("ReadFile without pending %u", bytes);
handle_pipe_data(bytes);
read_pipe();
} else if (GetLastError() != ERROR_IO_PENDING) {
@@ -932,12 +935,15 @@ void VDService::read_pipe()
}
}
+//FIXME: division to max size chunks should be here, not in the agent
void VDService::handle_pipe_data(DWORD bytes)
{
VDPipeState* ps = &_pipe_state;
DWORD read_size;
- _pending_read = false;
+ if (bytes) {
+ _pending_read = false;
+ }
if (!_running) {
return;
}
@@ -949,28 +955,31 @@ void VDService::handle_pipe_data(DWORD bytes)
ps->read.start += sizeof(VDPipeMessage);
continue;
}
- if (read_size < VD_MESSAGE_HEADER_SIZE) {
+ if (read_size < sizeof(VDPipeMessage) + pipe_msg->size) {
break;
}
- VDAgentMessage* msg = (VDAgentMessage*)pipe_msg->data;
- DWORD chunk_size = sizeof(VDAgentMessage) + msg->size;
- VDAgentDataChunk chunk;
- if (read_size < VD_MESSAGE_HEADER_SIZE + msg->size) {
+ if (_vdi_port->write_ring_free_space() < sizeof(VDAgentDataChunk) + pipe_msg->size) {
+ //vd_printf("DEBUG: no space in write ring %u", _vdi_port->write_ring_free_space());
break;
}
if (!_pending_reset) {
+ VDAgentDataChunk chunk;
chunk.port = pipe_msg->opaque;
- chunk.size = chunk_size;
+ chunk.size = pipe_msg->size;
if (_vdi_port->ring_write(&chunk, sizeof(chunk)) != sizeof(chunk) ||
- _vdi_port->ring_write(msg, chunk_size) != chunk_size) {
+ _vdi_port->ring_write(pipe_msg->data, chunk.size) != chunk.size) {
vd_printf("ring_write failed");
_running = false;
return;
}
}
- ps->read.start += (VD_MESSAGE_HEADER_SIZE + msg->size);
- if (ps->read.start == ps->read.end) {
- ps->read.start = ps->read.end = 0;
+ ps->read.start += (sizeof(VDPipeMessage) + pipe_msg->size);
+ }
+ if (ps->read.start == ps->read.end && !_pending_read) {
+ DWORD prev_read_end = ps->read.end;
+ ps->read.start = ps->read.end = 0;
+ if (prev_read_end == sizeof(ps->read.data)) {
+ read_pipe();
}
}
}
@@ -980,7 +989,7 @@ void VDService::handle_port_data()
VDPipeMessage* pipe_msg;
VDAgentDataChunk chunk;
int chunks_count = 0;
- DWORD count;
+ DWORD count = 0;
while (_running) {
if (!_chunk_size && _vdi_port->read_ring_size() >= sizeof(chunk)) {
@@ -990,9 +999,6 @@ void VDService::handle_port_data()
break;
}
count = sizeof(VDPipeMessage) + chunk.size;
- if (_pipe_state.write.start == _pipe_state.write.end) {
- _pipe_state.write.start = _pipe_state.write.end = 0;
- }
if (_pipe_state.write.end + count > sizeof(_pipe_state.write.data)) {
vd_printf("chunk is too large, size %u port %u", chunk.size, chunk.port);
_running = false;
@@ -1002,6 +1008,7 @@ void VDService::handle_port_data()
_chunk_port = chunk.port;
}
if (_chunk_size && _vdi_port->read_ring_size() >= _chunk_size) {
+ count = sizeof(VDPipeMessage) + _chunk_size;
ASSERT(_pipe_state.write.end + count <= sizeof(_pipe_state.write.data));
pipe_msg = (VDPipeMessage*)&_pipe_state.write.data[_pipe_state.write.end];
if (_vdi_port->ring_read(pipe_msg->data, _chunk_size) != _chunk_size) {
@@ -1012,6 +1019,7 @@ void VDService::handle_port_data()
if (_pipe_connected) {
pipe_msg->type = VD_AGENT_COMMAND;
pipe_msg->opaque = _chunk_port;
+ pipe_msg->size = _chunk_size;
_pipe_state.write.end += count;
chunks_count++;
} else {
commit feab0571017629960af5fc46cbaf0582f772e442
Author: Alon Levy <alevy at redhat.com>
Date: Mon Aug 23 15:26:05 2010 +0300
vdservice: change pipe write completion to use overlapped structure instead of completion routine
diff --git a/vdservice/vdservice.cpp b/vdservice/vdservice.cpp
index d30e305..29b225a 100644
--- a/vdservice/vdservice.cpp
+++ b/vdservice/vdservice.cpp
@@ -42,6 +42,7 @@
enum {
VD_EVENT_PIPE_READ = 0,
+ VD_EVENT_PIPE_WRITE,
VD_EVENT_CONTROL,
VD_EVENT_READ,
VD_EVENT_WRITE,
@@ -64,7 +65,7 @@ private:
static DWORD WINAPI control_handler(DWORD control, DWORD event_type,
LPVOID event_data, LPVOID context);
static VOID WINAPI main(DWORD argc, TCHAR * argv[]);
- static VOID CALLBACK write_completion(DWORD err, DWORD bytes, LPOVERLAPPED overlap);
+ void pipe_write_completion();
void write_agent_control(uint32_t type, uint32_t opaque);
void read_pipe();
void handle_pipe_data(DWORD bytes);
@@ -158,6 +159,7 @@ VDService::VDService()
ZeroMemory(_events, sizeof(_events));
_system_version = supported_system_version();
_control_event = CreateEvent(NULL, FALSE, FALSE, NULL);
+ _pipe_state.write.overlap.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
_pipe_state.read.overlap.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
_agent_path[0] = wchar_t('\0');
MUTEX_INIT(_agent_mutex);
@@ -167,6 +169,7 @@ VDService::VDService()
VDService::~VDService()
{
CloseHandle(_pipe_state.read.overlap.hEvent);
+ CloseHandle(_pipe_state.write.overlap.hEvent);
CloseHandle(_control_event);
delete _log;
}
@@ -419,6 +422,7 @@ bool VDService::execute()
}
vd_printf("Connected to server");
_events[VD_EVENT_PIPE_READ] = _pipe_state.read.overlap.hEvent;
+ _events[VD_EVENT_PIPE_WRITE] = _pipe_state.write.overlap.hEvent;
_events[VD_EVENT_CONTROL] = _control_event;
_events[VD_EVENT_READ] = _vdi_port->get_read_event();
_events[VD_EVENT_WRITE] = _vdi_port->get_write_event();
@@ -442,17 +446,20 @@ bool VDService::execute()
if (cont) {
handle_port_data();
}
+ if (cont_write) {
+ handle_pipe_data(0);
+ }
if (_running && (!cont || _pending_read || _pending_write)) {
DWORD events_count = _events[VD_EVENT_AGENT] ? VD_EVENTS_COUNT : VD_EVENTS_COUNT - 1;
- DWORD wait_ret = WaitForMultipleObjectsEx(events_count, _events, FALSE,
- cont ? 0 : INFINITE, TRUE);
+ DWORD wait_ret = WaitForMultipleObjects(events_count, _events, FALSE,
+ cont ? 0 : INFINITE);
switch (wait_ret) {
case WAIT_OBJECT_0 + VD_EVENT_PIPE_READ: {
DWORD bytes = 0;
if (_pipe_connected && _pending_read) {
_pending_read = false;
- if (GetOverlappedResult(_pipe_state.pipe, &_pipe_state.read.overlap, &bytes,
- FALSE)) {
+ if (GetOverlappedResult(_pipe_state.pipe, &_pipe_state.read.overlap,
+ &bytes, FALSE) || GetLastError() == ERROR_MORE_DATA) {
handle_pipe_data(bytes);
read_pipe();
} else {
@@ -463,6 +470,9 @@ bool VDService::execute()
}
break;
}
+ case WAIT_OBJECT_0 + VD_EVENT_PIPE_WRITE:
+ pipe_write_completion();
+ break;
case WAIT_OBJECT_0 + VD_EVENT_CONTROL:
vd_printf("Control event");
break;
@@ -480,11 +490,10 @@ bool VDService::execute()
kill_agent();
}
break;
- case WAIT_IO_COMPLETION:
case WAIT_TIMEOUT:
break;
default:
- vd_printf("WaitForMultipleObjectsEx failed %u", GetLastError());
+ vd_printf("WaitForMultipleObjects failed %u", GetLastError());
}
}
}
@@ -862,31 +871,40 @@ void VDService::stop()
}
}
-VOID CALLBACK VDService::write_completion(DWORD err, DWORD bytes, LPOVERLAPPED overlap)
+void VDService::pipe_write_completion()
{
- VDService* s = _singleton;
- VDPipeState* ps = &s->_pipe_state;
+ VDPipeState* ps = &this->_pipe_state;
+ DWORD bytes;
- s->_pending_write = false;
- if (!s->_running) {
- return;
- }
- if (err) {
- vd_printf("error %u", err);
+ if (!_running) {
return;
}
- ps->write.start += bytes;
+ if (_pending_write) {
+ if (GetOverlappedResult(_pipe_state.pipe, &_pipe_state.write.overlap, &bytes, FALSE)) {
+ ps->write.start += bytes;
+ if (ps->write.start == ps->write.end) {
+ ps->write.start = ps->write.end = 0;
+ }
+ } else if (GetLastError() == ERROR_IO_PENDING){
+ vd_printf("Overlapped write is pending");
+ return;
+ } else {
+ vd_printf("GetOverlappedResult() failed : %d", GetLastError());
+ }
+ _pending_write = false;
+ }
+
if (ps->write.start < ps->write.end) {
- s->_pending_write = true;
- if (!WriteFileEx(ps->pipe, ps->write.data + ps->write.start,
- ps->write.end - ps->write.start, overlap, write_completion)) {
- vd_printf("WriteFileEx() failed: %u", GetLastError());
- s->_pending_write = false;
- s->_pipe_connected = false;
- DisconnectNamedPipe(s->_pipe_state.pipe);
+ _pending_write = true;
+ if (!WriteFile(ps->pipe, ps->write.data + ps->write.start,
+ ps->write.end - ps->write.start, NULL, &_pipe_state.write.overlap)) {
+ vd_printf("WriteFile() failed: %u", GetLastError());
+ _pending_write = false;
+ _pipe_connected = false;
+ DisconnectNamedPipe(_pipe_state.pipe);
}
} else {
- s->_pending_write = false;
+ _pending_write = false;
}
}
@@ -1006,7 +1024,7 @@ void VDService::handle_port_data()
}
}
if (_pipe_connected && chunks_count && !_pending_write) {
- write_completion(0, 0, &_pipe_state.write.overlap);
+ pipe_write_completion();
}
}
@@ -1044,7 +1062,7 @@ void VDService::write_agent_control(uint32_t type, uint32_t opaque)
msg->opaque = opaque;
_pipe_state.write.end += sizeof(VDPipeMessage);
if (!_pending_write) {
- write_completion(0, 0, &_pipe_state.write.overlap);
+ pipe_write_completion();
}
}
commit f3277bd9b7760476966615f3a496db32dd37f717
Author: Alon Levy <alevy at redhat.com>
Date: Mon Aug 23 15:09:28 2010 +0300
vdservice: add debug only define for standalone executable
diff --git a/vdservice/vdservice.cpp b/vdservice/vdservice.cpp
index c608317..d30e305 100644
--- a/vdservice/vdservice.cpp
+++ b/vdservice/vdservice.cpp
@@ -24,6 +24,8 @@
#include "vdcommon.h"
#include "vdi_port.h"
+//#define DEBUG_VDSERVICE
+
#define VD_SERVICE_DISPLAY_NAME TEXT("RHEV Spice Agent")
#define VD_SERVICE_NAME TEXT("vdservice")
#define VD_SERVICE_DESCRIPTION TEXT("Enables Spice event injection and display configuration.")
@@ -171,8 +173,13 @@ VDService::~VDService()
bool VDService::run()
{
+#ifndef DEBUG_VDSERVICE
SERVICE_TABLE_ENTRY service_table[] = {{VD_SERVICE_NAME, main}, {0, 0}};
return !!StartServiceCtrlDispatcher(service_table);
+#else
+ main(0, NULL);
+ return true;
+#endif
}
bool VDService::install()
@@ -336,7 +343,9 @@ VOID WINAPI VDService::main(DWORD argc, TCHAR* argv[])
NULL);
if (!s->_status_handle) {
printf("RegisterServiceCtrlHandler failed\n");
+#ifndef DEBUG_VDSERVICE
return;
+#endif // DEBUG_VDSERVICE
}
// service is starting
@@ -358,7 +367,9 @@ VOID WINAPI VDService::main(DWORD argc, TCHAR* argv[])
// service is stopped
status->dwControlsAccepted &= ~VDSERVICE_ACCEPTED_CONTROLS;
status->dwCurrentState = SERVICE_STOPPED;
+#ifndef DEBUG_VDSERVICE
SetServiceStatus(s->_status_handle, status);
+#endif //DEBUG_VDSERVICE
}
typedef __declspec (align(1)) struct VDAgentDataChunk {
commit a32359a4dd7c9bdd0642fa3fc9f61a79218f3395
Author: Alon Levy <alevy at redhat.com>
Date: Mon Aug 23 15:06:31 2010 +0300
vdservice: use enum for events in main loop
diff --git a/vdservice/vdservice.cpp b/vdservice/vdservice.cpp
index 61f6a54..c608317 100644
--- a/vdservice/vdservice.cpp
+++ b/vdservice/vdservice.cpp
@@ -34,11 +34,19 @@
#define VD_AGENT_MAX_RESTARTS 10
#define VD_AGENT_RESTART_INTERVAL 3000
#define VD_AGENT_RESTART_COUNT_RESET_INTERVAL 60000
-#define VD_EVENTS_COUNT 5
#define WINLOGON_FILENAME TEXT("winlogon.exe")
#define CREATE_PROC_MAX_RETRIES 10
#define CREATE_PROC_INTERVAL_MS 500
+enum {
+ VD_EVENT_PIPE_READ = 0,
+ VD_EVENT_CONTROL,
+ VD_EVENT_READ,
+ VD_EVENT_WRITE,
+ VD_EVENT_AGENT, // Must be before last
+ VD_EVENTS_COUNT // Must be last
+};
+
class VDService {
public:
static VDService* get();
@@ -399,11 +407,11 @@ bool VDService::execute()
return false;
}
vd_printf("Connected to server");
- _events[0] = _pipe_state.read.overlap.hEvent;
- _events[1] = _control_event;
- _events[2] = _vdi_port->get_read_event();
- _events[3] = _vdi_port->get_write_event();
- _events[4] = _agent_proc_info.hProcess;
+ _events[VD_EVENT_PIPE_READ] = _pipe_state.read.overlap.hEvent;
+ _events[VD_EVENT_CONTROL] = _control_event;
+ _events[VD_EVENT_READ] = _vdi_port->get_read_event();
+ _events[VD_EVENT_WRITE] = _vdi_port->get_write_event();
+ _events[VD_EVENT_AGENT] = _agent_proc_info.hProcess;
_chunk_size = _chunk_port = 0;
read_pipe();
while (_running) {
@@ -424,12 +432,11 @@ bool VDService::execute()
handle_port_data();
}
if (_running && (!cont || _pending_read || _pending_write)) {
- DWORD events_count = _events[VD_EVENTS_COUNT - 1] ? VD_EVENTS_COUNT :
- VD_EVENTS_COUNT - 1;
+ DWORD events_count = _events[VD_EVENT_AGENT] ? VD_EVENTS_COUNT : VD_EVENTS_COUNT - 1;
DWORD wait_ret = WaitForMultipleObjectsEx(events_count, _events, FALSE,
cont ? 0 : INFINITE, TRUE);
switch (wait_ret) {
- case WAIT_OBJECT_0 + 0: {
+ case WAIT_OBJECT_0 + VD_EVENT_PIPE_READ: {
DWORD bytes = 0;
if (_pipe_connected && _pending_read) {
_pending_read = false;
@@ -445,16 +452,16 @@ bool VDService::execute()
}
break;
}
- case WAIT_OBJECT_0 + 1:
+ case WAIT_OBJECT_0 + VD_EVENT_CONTROL:
vd_printf("Control event");
break;
- case WAIT_OBJECT_0 + 2:
+ case WAIT_OBJECT_0 + VD_EVENT_READ:
_vdi_port->read_completion();
break;
- case WAIT_OBJECT_0 + 3:
+ case WAIT_OBJECT_0 + VD_EVENT_WRITE:
_vdi_port->write_completion();
break;
- case WAIT_OBJECT_0 + 4:
+ case WAIT_OBJECT_0 + VD_EVENT_AGENT:
vd_printf("Agent killed");
if (_system_version == SYS_VER_WIN_XP) {
restart_agent(false);
@@ -765,7 +772,7 @@ bool VDService::launch_agent()
vd_printf("ConnectNamedPipe() failed: %u", GetLastError());
return false;
}
- _events[VD_EVENTS_COUNT - 1] = _agent_proc_info.hProcess;
+ _events[VD_EVENT_AGENT] = _agent_proc_info.hProcess;
return true;
}
@@ -778,7 +785,7 @@ bool VDService::kill_agent()
if (!_agent_alive) {
return true;
}
- _events[VD_EVENTS_COUNT - 1] = 0;
+ _events[VD_EVENT_AGENT] = 0;
_agent_alive = false;
if (_pipe_connected) {
_pipe_connected = false;
commit a6c1ab59cac9f02b6f3263e07d3db82bdc6e7536
Author: Alon Levy <alevy at redhat.com>
Date: Mon Aug 23 14:57:02 2010 +0300
vdservice: remove dead defines in vdi_port.h
diff --git a/vdservice/vdi_port.h b/vdservice/vdi_port.h
index 08cfee1..a10b346 100644
--- a/vdservice/vdi_port.h
+++ b/vdservice/vdi_port.h
@@ -23,10 +23,6 @@
#define BUF_SIZE (1024 * 1024)
-#define BUF_READ (1 << 0)
-#define BUF_WRITE (1 << 1)
-#define BUF_ALL (BUF_READ | BUF_WRITE)
-
#define VDI_PORT_BLOCKED 0
#define VDI_PORT_RESET -1
#define VDI_PORT_ERROR -2
commit 1724de8a4312fcdb59f57e2e8738c624ce902a66
Author: Alon Levy <alevy at redhat.com>
Date: Mon Aug 23 14:50:41 2010 +0300
vdservice: replace vdiport device with virtio-serial device
replaced vdiport device by virtio-serial device which is also an easy
to use stream between guest and host but is already in qemu.
* VDIPortBuffer split off from VDIPort
* use setupapi to get device path
* setupapi.lib dependency added, magic GUID instead of a magic filename
* retry several times to open device, fixes startup race between driver
initialization and service start on boot.
* limit writes to device, a limitation of current windows driver.
* virtio-serial uses overlapped structure and events for async read/write
instead of vdi_port special event.
diff --git a/vdservice/vdi_port.cpp b/vdservice/vdi_port.cpp
index 4c0a99d..0d5c0e1 100644
--- a/vdservice/vdi_port.cpp
+++ b/vdservice/vdi_port.cpp
@@ -15,35 +15,35 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <windows.h>
+#include <setupapi.h>
#include "stdio.h"
#include "vdi_port.h"
#include "vdlog.h"
-#define VDI_PORT_DEV_NAME TEXT("\\\\.\\VDIPort")
-#define FILE_DEVICE_UNKNOWN 0x00000022
-#define METHOD_BUFFERED 0
-#define FILE_ANY_ACCESS 0
+const GUID GUID_VIOSERIAL_PORT =
+ {0x6fde7521, 0x1b65, 0x48ae, 0xb6, 0x28, 0x80, 0xbe, 0x62, 0x1, 0x60, 0x26};
-#define CTL_CODE(DeviceType, Function, Method, Access) ( \
- ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \
-)
+// Current limitation of virtio-serial windows driver (RHBZ 617000)
+#define VIOSERIAL_PORT_MAX_WRITE_BYTES 2048
-#define FIRST_AVAIL_IO_FUNC 0x800
-#define RED_TUNNEL_CTL_FUNC FIRST_AVAIL_IO_FUNC
-
-#define IOCTL_RED_TUNNEL_SET_EVENT \
- CTL_CODE(FILE_DEVICE_UNKNOWN, RED_TUNNEL_CTL_FUNC, METHOD_BUFFERED, FILE_ANY_ACCESS)
+// Retry initial connection to device. On boot when vdservice is started the device is
+// not immediately available (takes 2 seconds, 30 is for extreme load).
+#define VIOSERIAL_PORT_DEVICE_OPEN_MAX_RETRIES 30
+#define VIOSERIAL_PORT_DEVICE_OPEN_RETRY_INTERVAL_MS 1000
#define MIN(a, b) ((a) > (b) ? (b) : (a))
+VDIPort* VDIPort::_singleton;
+
VDIPort::VDIPort()
: _handle (INVALID_HANDLE_VALUE)
- , _event (NULL)
- , _write_start (_write_ring)
- , _write_end (_write_ring)
- , _read_start (_read_ring)
- , _read_end (_read_ring)
{
+ ZeroMemory(&_write, offsetof(VDIPortBuffer, ring));
+ _write.start = _write.end = _write.ring;
+ ZeroMemory(&_read, offsetof(VDIPortBuffer, ring));
+ _read.start = _read.end = _read.ring;
+ _singleton = this;
}
VDIPort::~VDIPort()
@@ -51,77 +51,172 @@ VDIPort::~VDIPort()
if (_handle != INVALID_HANDLE_VALUE) {
CloseHandle(_handle);
}
- if (_event) {
- CloseHandle(_event);
+ if (_read.overlap.hEvent) {
+ CloseHandle(_read.overlap.hEvent);
+ }
+ if (_write.overlap.hEvent) {
+ CloseHandle(_write.overlap.hEvent);
+ }
+}
+
+//Based on device.cpp from vioserial test app
+//FIXME: remove this call & lib?
+PTCHAR get_device_path(IN LPGUID interface_guid)
+{
+ HDEVINFO dev_info;
+ SP_DEVICE_INTERFACE_DATA dev_interface;
+ PSP_DEVICE_INTERFACE_DETAIL_DATA dev_interface_detail = NULL;
+ ULONG len, req_len = 0;
+
+ dev_info = SetupDiGetClassDevs(interface_guid, NULL, NULL,
+ DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
+ if (dev_info == INVALID_HANDLE_VALUE) {
+ vd_printf("Cannot get class devices");
+ return NULL;
+ }
+ dev_interface.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
+ if (!SetupDiEnumDeviceInterfaces(dev_info, 0, interface_guid, 0, &dev_interface)) {
+ vd_printf("Cannot get enumerate device interfaces");
+ SetupDiDestroyDeviceInfoList(dev_info);
+ return NULL;
}
+ SetupDiGetDeviceInterfaceDetail(dev_info, &dev_interface, NULL, 0, &req_len, NULL);
+ dev_interface_detail = (PSP_DEVICE_INTERFACE_DETAIL_DATA)LocalAlloc(LMEM_FIXED, req_len);
+ if (dev_interface_detail == NULL) {
+ vd_printf("Cannot allocate memory");
+ SetupDiDestroyDeviceInfoList(dev_info);
+ return NULL;
+ }
+ dev_interface_detail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
+ len = req_len;
+ if (!SetupDiGetDeviceInterfaceDetail(dev_info, &dev_interface, dev_interface_detail, len,
+ &req_len, NULL)) {
+ vd_printf("Cannot get device interface details.\n");
+ SetupDiDestroyDeviceInfoList(dev_info);
+ LocalFree(dev_interface_detail);
+ return NULL;
+ }
+ return dev_interface_detail->DevicePath;
}
bool VDIPort::init()
{
- DWORD io_ret_len;
- _handle = CreateFile(VDI_PORT_DEV_NAME, GENERIC_READ | GENERIC_WRITE, 0, NULL,
- OPEN_EXISTING, 0, NULL);
+ PTCHAR path = NULL;
+
+ for (int retry = 0; retry < VIOSERIAL_PORT_DEVICE_OPEN_MAX_RETRIES && path == NULL; retry++) {
+ if (path = get_device_path((LPGUID)&GUID_VIOSERIAL_PORT)) {
+ break;
+ }
+ Sleep(VIOSERIAL_PORT_DEVICE_OPEN_RETRY_INTERVAL_MS);
+ }
+ if (path == NULL) {
+ vd_printf("GetDevicePath failed - device/driver missing?");
+ return false;
+ }
+ _handle = CreateFile(path, GENERIC_READ | GENERIC_WRITE , 0, NULL,
+ OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
if (_handle == INVALID_HANDLE_VALUE) {
vd_printf("CreateFile() failed: %u", GetLastError());
return false;
}
- _event = CreateEvent(NULL, FALSE, FALSE, NULL);
- if (_event == NULL) {
+ _write.overlap.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+ if (_write.overlap.hEvent == NULL) {
vd_printf("CreateEvent() failed: %u", GetLastError());
return false;
}
- if (!DeviceIoControl(_handle, IOCTL_RED_TUNNEL_SET_EVENT, &_event, sizeof(_event),
- NULL, 0, &io_ret_len, NULL)) {
- vd_printf("DeviceIoControl() failed: %u", GetLastError());
+ _read.overlap.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+ if (_read.overlap.hEvent == NULL) {
+ vd_printf("CreateEvent() failed: %u", GetLastError());
return false;
}
return true;
}
+size_t VDIPort::write_ring_free_space()
+{
+ return (BUF_SIZE + _write.start - _write.end - 1) % BUF_SIZE;
+}
+
size_t VDIPort::ring_write(const void* buf, size_t size)
{
- size_t free_size = (BUF_SIZE + _write_start - _write_end - 1) % BUF_SIZE;
+ size_t free_size = (BUF_SIZE + _write.start - _write.end - 1) % BUF_SIZE;
size_t n;
if (size > free_size) {
size = free_size;
}
- if (_write_end < _write_start) {
- memcpy(_write_end, buf, size);
+ if (_write.end < _write.start) {
+ memcpy(_write.end, buf, size);
} else {
- n = MIN(size, (size_t)(&_write_ring[BUF_SIZE] - _write_end));
- memcpy(_write_end, buf, n);
+ n = MIN(size, (size_t)(&_write.ring[BUF_SIZE] - _write.end));
+ memcpy(_write.end, buf, n);
if (size > n) {
- memcpy(_write_ring, (uint8_t*)buf + n, size - n);
+ memcpy(_write.ring, (uint8_t*)buf + n, size - n);
}
}
- _write_end = _write_ring + (_write_end - _write_ring + size) % BUF_SIZE;
+ _write.end = _write.ring + (_write.end - _write.ring + size) % BUF_SIZE;
return size;
}
int VDIPort::write()
{
int size;
- int n;
+ int ret;
- if (_write_start == _write_end) {
+ //FIXME: return VDI_PORT_NO_DATA
+ if (_write.start == _write.end) {
return 0;
}
- if (_write_start < _write_end) {
- size = (int)(_write_end - _write_start);
- } else {
- size = (int)(&_write_ring[BUF_SIZE] - _write_start);
+ if (!_write.pending) {
+ if (_write.start < _write.end) {
+ size = (int)(_write.end - _write.start);
+ } else {
+ size = (int)(&_write.ring[BUF_SIZE] - _write.start);
+ }
+ size = MIN(size, VIOSERIAL_PORT_MAX_WRITE_BYTES);
+ _write.pending = true;
+ if (WriteFile(_handle, _write.start, size, NULL, &_write.overlap)) {
+ write_completion();
+ } if (GetLastError() != ERROR_IO_PENDING) {
+ return handle_error();
+ }
}
- if (!WriteFile(_handle, _write_start, size, (LPDWORD)&n, NULL)) {
- return handle_error();
+ ret = _write.bytes;
+ _write.bytes = 0;
+ return ret;
+}
+
+void VDIPort::write_completion()
+{
+ DWORD bytes;
+
+ if (!_write.pending) {
+ return;
}
- _write_start = _write_ring + (_write_start - _write_ring + n) % BUF_SIZE;
- return n;
+ if (!GetOverlappedResult(_handle, &_write.overlap, &bytes, FALSE)) {
+ vd_printf("GetOverlappedResult failed: %u", GetLastError());
+ return;
+ }
+ _write.start = _write.ring + (_write.start - _write.ring + bytes) % BUF_SIZE;
+ _write.bytes = bytes;
+ _write.pending = false;
}
size_t VDIPort::read_ring_size()
{
- return (BUF_SIZE + _read_end - _read_start) % BUF_SIZE;
+ return (BUF_SIZE + _read.end - _read.start) % BUF_SIZE;
+}
+
+size_t VDIPort::read_ring_continuous_remaining_size()
+{
+ DWORD size;
+
+ if (_read.start <= _read.end) {
+ size = MIN(BUF_SIZE - 1, (int)(&_read.ring[BUF_SIZE] - _read.end));
+ } else {
+ size = (DWORD)(_read.start - _read.end - 1);
+ }
+ return size;
}
size_t VDIPort::ring_read(void* buf, size_t size)
@@ -129,45 +224,67 @@ size_t VDIPort::ring_read(void* buf, size_t size)
size_t n;
size_t m = 0;
- if (_read_start == _read_end) {
+ if (_read.start == _read.end) {
return 0;
}
- if (_read_start < _read_end) {
- n = MIN(size, (size_t)(_read_end - _read_start));
- memcpy(buf, _read_start, n);
+ if (_read.start < _read.end) {
+ n = MIN(size, (size_t)(_read.end - _read.start));
+ memcpy(buf, _read.start, n);
} else {
- n = MIN(size, (size_t)(&_read_ring[BUF_SIZE] - _read_start));
- memcpy(buf, _read_start, n);
+ n = MIN(size, (size_t)(&_read.ring[BUF_SIZE] - _read.start));
+ memcpy(buf, _read.start, n);
if (size > n) {
- m = MIN(size - n, (size_t)(_read_end - _read_ring));
- memcpy((uint8_t*)buf + n, _read_ring, m);
+ m = MIN(size - n, (size_t)(_read.end - _read.ring));
+ memcpy((uint8_t*)buf + n, _read.ring, m);
}
}
- _read_start = _read_ring + (_read_start - _read_ring + n + m) % BUF_SIZE;
+ _read.start = _read.ring + (_read.start - _read.ring + n + m) % BUF_SIZE;
return n + m;
}
int VDIPort::read()
{
int size;
- int n;
+ int ret;
- if ((_read_end - _read_ring + 1) % BUF_SIZE == _read_start - _read_ring) {
- return 0;
- }
- if (_read_start == _read_end) {
- _read_start = _read_end = _read_ring;
- }
- if (_read_start <= _read_end) {
- size = MIN(BUF_SIZE - 1, (int)(&_read_ring[BUF_SIZE] - _read_end));
- } else {
- size = (int)(_read_start - _read_end - 1);
+ if (!_read.pending) {
+ //FIXME: read_ring_continuous_remaining_size? return VDI_PORT_BUFFER_FULL
+ if ((_read.end - _read.ring + 1) % BUF_SIZE == _read.start - _read.ring) {
+ vd_printf("DEBUG: buffer full");
+ return 0;
+ }
+ if (_read.start == _read.end) {
+ _read.start = _read.end = _read.ring;
+ }
+ if (_read.start <= _read.end) {
+ size = MIN(BUF_SIZE - 1, (int)(&_read.ring[BUF_SIZE] - _read.end));
+ } else {
+ size = (int)(_read.start - _read.end - 1);
+ }
+ _read.pending = true;
+ if (ReadFile(_handle, _read.end, size, NULL, &_read.overlap)) {
+ read_completion();
+ } else if (GetLastError() != ERROR_IO_PENDING) {
+ return handle_error();
+ }
}
- if (!ReadFile(_handle, _read_end, size, (LPDWORD)&n, NULL)) {
- return handle_error();
+ ret = _read.bytes;
+ _read.bytes = 0;
+ return ret;
+}
+
+void VDIPort::read_completion()
+{
+ DWORD bytes;
+
+ if (!GetOverlappedResult(_handle, &_read.overlap, &bytes, FALSE) &&
+ GetLastError() != ERROR_MORE_DATA) {
+ vd_printf("GetOverlappedResult failed: %u", GetLastError());
+ return;
}
- _read_end = _read_ring + (_read_end - _read_ring + n) % BUF_SIZE;
- return n;
+ _read.end = _read.ring + (_read.end - _read.ring + bytes) % BUF_SIZE;
+ _read.bytes = bytes;
+ _read.pending = false;
}
int VDIPort::handle_error()
@@ -175,8 +292,8 @@ int VDIPort::handle_error()
switch (GetLastError()) {
case ERROR_CONNECTION_INVALID:
vd_printf("port reset");
- _write_start = _write_end = _write_ring;
- _read_start = _read_end = _read_ring;
+ _write.start = _write.end = _write.ring;
+ _read.start = _read.end = _read.ring;
return VDI_PORT_RESET;
default:
vd_printf("port io failed: %u", GetLastError());
diff --git a/vdservice/vdi_port.h b/vdservice/vdi_port.h
index 3af3f18..08cfee1 100644
--- a/vdservice/vdi_port.h
+++ b/vdservice/vdi_port.h
@@ -31,30 +31,40 @@
#define VDI_PORT_RESET -1
#define VDI_PORT_ERROR -2
+typedef struct VDIPortBuffer {
+ OVERLAPPED overlap;
+ uint8_t* start;
+ uint8_t* end;
+ bool pending;
+ int bytes;
+ uint8_t ring[BUF_SIZE];
+} VDIPortBuffer;
+
class VDIPort {
public:
VDIPort();
~VDIPort();
bool init();
size_t ring_write(const void* buf, size_t size);
+ size_t write_ring_free_space();
size_t ring_read(void* buf, size_t size);
size_t read_ring_size();
+ size_t read_ring_continuous_remaining_size();
+ HANDLE get_write_event() { return _write.overlap.hEvent; }
+ HANDLE get_read_event() { return _read.overlap.hEvent; }
int write();
int read();
- HANDLE get_event() { return _event;}
+ void write_completion();
+ void read_completion();
private:
int handle_error();
private:
+ static VDIPort* _singleton;
HANDLE _handle;
- HANDLE _event;
- uint8_t _write_ring[BUF_SIZE];
- uint8_t* _write_start;
- uint8_t* _write_end;
- uint8_t _read_ring[BUF_SIZE];
- uint8_t* _read_start;
- uint8_t* _read_end;
+ VDIPortBuffer _write;
+ VDIPortBuffer _read;
};
// Ring notes:
diff --git a/vdservice/vdservice.cpp b/vdservice/vdservice.cpp
index 903fff6..61f6a54 100644
--- a/vdservice/vdservice.cpp
+++ b/vdservice/vdservice.cpp
@@ -34,7 +34,7 @@
#define VD_AGENT_MAX_RESTARTS 10
#define VD_AGENT_RESTART_INTERVAL 3000
#define VD_AGENT_RESTART_COUNT_RESET_INTERVAL 60000
-#define VD_EVENTS_COUNT 4
+#define VD_EVENTS_COUNT 5
#define WINLOGON_FILENAME TEXT("winlogon.exe")
#define CREATE_PROC_MAX_RETRIES 10
#define CREATE_PROC_INTERVAL_MS 500
@@ -399,10 +399,11 @@ bool VDService::execute()
return false;
}
vd_printf("Connected to server");
- _events[0] = _vdi_port->get_event();
- _events[1] = _pipe_state.read.overlap.hEvent;
- _events[2] = _control_event;
- _events[3] = _agent_proc_info.hProcess;
+ _events[0] = _pipe_state.read.overlap.hEvent;
+ _events[1] = _control_event;
+ _events[2] = _vdi_port->get_read_event();
+ _events[3] = _vdi_port->get_write_event();
+ _events[4] = _agent_proc_info.hProcess;
_chunk_size = _chunk_port = 0;
read_pipe();
while (_running) {
@@ -428,9 +429,7 @@ bool VDService::execute()
DWORD wait_ret = WaitForMultipleObjectsEx(events_count, _events, FALSE,
cont ? 0 : INFINITE, TRUE);
switch (wait_ret) {
- case WAIT_OBJECT_0:
- break;
- case WAIT_OBJECT_0 + 1: {
+ case WAIT_OBJECT_0 + 0: {
DWORD bytes = 0;
if (_pipe_connected && _pending_read) {
_pending_read = false;
@@ -446,10 +445,16 @@ bool VDService::execute()
}
break;
}
- case WAIT_OBJECT_0 + 2:
+ case WAIT_OBJECT_0 + 1:
vd_printf("Control event");
break;
+ case WAIT_OBJECT_0 + 2:
+ _vdi_port->read_completion();
+ break;
case WAIT_OBJECT_0 + 3:
+ _vdi_port->write_completion();
+ break;
+ case WAIT_OBJECT_0 + 4:
vd_printf("Agent killed");
if (_system_version == SYS_VER_WIN_XP) {
restart_agent(false);
diff --git a/vdservice/vdservice.vcproj b/vdservice/vdservice.vcproj
index 4e70a8b..85d5c8e 100644
--- a/vdservice/vdservice.vcproj
+++ b/vdservice/vdservice.vcproj
@@ -65,7 +65,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="WtsApi32.lib Userenv.lib Version.lib"
+ AdditionalDependencies="WtsApi32.lib Userenv.lib Version.lib setupapi.lib"
LinkIncremental="2"
GenerateDebugInformation="true"
SubSystem="1"
@@ -216,7 +216,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="WtsApi32.lib Userenv.lib Version.lib"
+ AdditionalDependencies="WtsApi32.lib Userenv.lib Version.lib setupapi.lib"
LinkIncremental="1"
GenerateDebugInformation="true"
SubSystem="1"
commit a17ccbf323768c3cb977f0f062366ba7cf7f19db
Author: Alon Levy <alevy at redhat.com>
Date: Mon Aug 23 14:46:01 2010 +0300
include path fixes because of spice-protcol updates
* mutex.h inlined into common/vdcommon.h
* vdagent.h renamed to spice/vd_agent.h
diff --git a/common/vdcommon.h b/common/vdcommon.h
index 2e4ed5d..8d4b4de 100644
--- a/common/vdcommon.h
+++ b/common/vdcommon.h
@@ -21,9 +21,15 @@
#pragma warning(disable:4200)
#include <windows.h>
-#include "vd_agent.h"
+#include "spice/vd_agent.h"
#include "vdlog.h"
+typedef CRITICAL_SECTION mutex_t;
+
+#define MUTEX_INIT(mutex) InitializeCriticalSection(&mutex)
+#define MUTEX_LOCK(mutex) EnterCriticalSection(&mutex)
+#define MUTEX_UNLOCK(mutex) LeaveCriticalSection(&mutex)
+
#define VD_SERVICE_PIPE_NAME TEXT("\\\\.\\pipe\\vdservicepipe")
#define VD_MESSAGE_HEADER_SIZE (sizeof(VDPipeMessage) + sizeof(VDAgentMessage))
#define VD_PIPE_BUF_SIZE (1024 * 1024)
diff --git a/vdagent/desktop_layout.h b/vdagent/desktop_layout.h
index 797a82c..dc8accb 100644
--- a/vdagent/desktop_layout.h
+++ b/vdagent/desktop_layout.h
@@ -18,8 +18,8 @@
#ifndef _H_DESKTOP_LAYOUT
#define _H_DESKTOP_LAYOUT
-#include "mutex.h"
#include <vector>
+#include "vdcommon.h"
class DisplayMode {
public:
diff --git a/vdservice/vdservice.cpp b/vdservice/vdservice.cpp
index 8139af4..903fff6 100644
--- a/vdservice/vdservice.cpp
+++ b/vdservice/vdservice.cpp
@@ -23,7 +23,6 @@
#include <tlhelp32.h>
#include "vdcommon.h"
#include "vdi_port.h"
-#include "mutex.h"
#define VD_SERVICE_DISPLAY_NAME TEXT("RHEV Spice Agent")
#define VD_SERVICE_NAME TEXT("vdservice")
commit c909771c0e6f7a529d0ec614d57dcd500b500990
Author: Arnon Gilboa <agilboa at agilboa.usersys.redhat.com>
Date: Sun Jun 6 12:51:04 2010 +0300
spice: vdagent: drop mouse event when SendInput fails due to DesktopSwitch event delay #598968
diff --git a/vdagent/vdagent.cpp b/vdagent/vdagent.cpp
index 332438b..a578dfd 100644
--- a/vdagent/vdagent.cpp
+++ b/vdagent/vdagent.cpp
@@ -262,7 +262,7 @@ DWORD VDAgent::get_buttons_change(DWORD last_buttons_state, DWORD new_buttons_st
bool VDAgent::send_input()
{
- UINT ret;
+ bool ret = true;
_desktop_layout->lock();
if (_pending_input) {
if (KillTimer(_hwnd, VD_TIMER_ID)) {
@@ -274,14 +274,13 @@ bool VDAgent::send_input()
return false;
}
}
- ret = SendInput(1, &_input, sizeof(INPUT));
- if (!ret) {
+ if (!SendInput(1, &_input, sizeof(INPUT)) && GetLastError() != ERROR_ACCESS_DENIED) {
vd_printf("SendInput failed: %d", GetLastError());
- _running = false;
+ ret = _running = false;
}
_input_time = GetTickCount();
_desktop_layout->unlock();
- return !!ret;
+ return ret;
}
bool VDAgent::handle_mouse_event(VDAgentMouseState* state)
commit b850d5a8c79b96dbe884276cef9feee0c3e8c424
Author: Arnon Gilboa <agilboa at agilboa.usersys.redhat.com>
Date: Mon Mar 22 17:17:18 2010 +0200
spice: vdagent: return error code -1 on service install/uninstall failure #576625
diff --git a/vdservice/vdservice.cpp b/vdservice/vdservice.cpp
index e8a773c..8139af4 100644
--- a/vdservice/vdservice.cpp
+++ b/vdservice/vdservice.cpp
@@ -44,9 +44,9 @@ class VDService {
public:
static VDService* get();
~VDService();
- void run();
- void install();
- void uninstall();
+ bool run();
+ bool install();
+ bool uninstall();
private:
VDService();
@@ -162,24 +162,26 @@ VDService::~VDService()
delete _log;
}
-void VDService::run()
+bool VDService::run()
{
SERVICE_TABLE_ENTRY service_table[] = {{VD_SERVICE_NAME, main}, {0, 0}};
- StartServiceCtrlDispatcher(service_table);
+ return !!StartServiceCtrlDispatcher(service_table);
}
-void VDService::install()
+bool VDService::install()
{
+ bool ret = false;
+
SC_HANDLE service_control_manager = OpenSCManager(0, 0, SC_MANAGER_CREATE_SERVICE);
if (!service_control_manager) {
printf("OpenSCManager failed\n");
- return;
+ return false;
}
TCHAR path[_MAX_PATH + 1];
if (!GetModuleFileName(0, path, sizeof(path) / sizeof(path[0]))) {
printf("GetModuleFileName failed\n");
CloseServiceHandle(service_control_manager);
- return;
+ return false;
}
SC_HANDLE service = CreateService(service_control_manager, VD_SERVICE_NAME,
VD_SERVICE_DISPLAY_NAME, SERVICE_ALL_ACCESS,
@@ -194,27 +196,32 @@ void VDService::install()
}
CloseServiceHandle(service);
printf("Service installed successfully\n");
+ ret = true;
} else if (GetLastError() == ERROR_SERVICE_EXISTS) {
printf("Service already exists\n");
+ ret = true;
} else {
printf("Service not installed successfully, error %d\n", GetLastError());
}
CloseServiceHandle(service_control_manager);
+ return ret;
}
-void VDService::uninstall()
+bool VDService::uninstall()
{
+ bool ret = false;
+
SC_HANDLE service_control_manager = OpenSCManager(0, 0, SC_MANAGER_CONNECT);
if (!service_control_manager) {
printf("OpenSCManager failed\n");
- return;
+ return false;
}
SC_HANDLE service = OpenService(service_control_manager, VD_SERVICE_NAME,
SERVICE_QUERY_STATUS | DELETE);
if (!service) {
printf("OpenService failed\n");
CloseServiceHandle(service_control_manager);
- return;
+ return false;
}
SERVICE_STATUS status;
if (!QueryServiceStatus(service, &status)) {
@@ -223,6 +230,7 @@ void VDService::uninstall()
printf("Service is still running\n");
} else if (DeleteService(service)) {
printf("Service removed successfully\n");
+ ret = true;
} else {
switch (GetLastError()) {
case ERROR_ACCESS_DENIED:
@@ -238,6 +246,7 @@ void VDService::uninstall()
}
CloseServiceHandle(service);
CloseServiceHandle(service_control_manager);
+ return ret;
}
const char* session_events[] = {
@@ -1019,23 +1028,25 @@ void VDService::write_agent_control(uint32_t type, uint32_t opaque)
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
+ bool success = false;
+
if (!supported_system_version()) {
printf("vdservice is not supported in this system version\n");
- return 0;
+ return -1;
}
VDService* vdservice = VDService::get();
if (argc > 1) {
if (lstrcmpi(argv[1], TEXT("install")) == 0) {
- vdservice->install();
+ success = vdservice->install();
} else if (lstrcmpi(argv[1], TEXT("uninstall")) == 0) {
- vdservice->uninstall();
+ success = vdservice->uninstall();
} else {
printf("Use: vdservice install / uninstall\n");
}
} else {
- vdservice->run();
+ success = vdservice->run();
}
delete vdservice;
- return 0;
+ return (success ? 0 : -1);
}
commit ce07dc8a8d7c015f8da90618a6097f21f57d0311
Author: Arnon Gilboa <agilboa at agilboa.usersys.redhat.com>
Date: Mon Mar 1 16:46:33 2010 +0200
spice: vdagent: upgrade solution & projects to vs2008
diff --git a/vdagent.sln b/vdagent.sln
index 1f0fc72..2622f2e 100644
--- a/vdagent.sln
+++ b/vdagent.sln
@@ -1,6 +1,6 @@

-Microsoft Visual Studio Solution File, Format Version 9.00
-# Visual Studio 2005
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual Studio 2008
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vdagent", "vdagent\vdagent.vcproj", "{CAD5A7E6-E9F5-4071-AFDA-25F76FDA5442}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vdservice", "vdservice\vdservice.vcproj", "{ADFE5E22-31D0-4343-AE9E-8102CC0051F9}"
diff --git a/vdagent/vdagent.vcproj b/vdagent/vdagent.vcproj
index ca65b07..f7f6bef 100644
--- a/vdagent/vdagent.vcproj
+++ b/vdagent/vdagent.vcproj
@@ -1,11 +1,12 @@
<?xml version="1.0" encoding="windows-1255"?>
<VisualStudioProject
ProjectType="Visual C++"
- Version="8.00"
+ Version="9.00"
Name="vdagent"
ProjectGUID="{CAD5A7E6-E9F5-4071-AFDA-25F76FDA5442}"
RootNamespace="redagent"
Keyword="Win32Proj"
+ TargetFrameworkVersion="131072"
>
<Platforms>
<Platform
@@ -50,7 +51,7 @@
RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="3"
- Detect64BitPortabilityProblems="true"
+ Detect64BitPortabilityProblems="false"
DebugInformationFormat="4"
/>
<Tool
@@ -68,6 +69,8 @@
LinkIncremental="2"
GenerateDebugInformation="true"
SubSystem="2"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
@@ -89,19 +92,15 @@
Name="VCAppVerifierTool"
/>
<Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
- Name="Release|Win32"
- OutputDirectory="$(ConfigurationName)"
- IntermediateDirectory="$(ConfigurationName)"
+ Name="Debug|x64"
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
- WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -117,16 +116,19 @@
/>
<Tool
Name="VCMIDLTool"
+ TargetEnvironment="3"
/>
<Tool
Name="VCCLCompilerTool"
+ Optimization="0"
AdditionalIncludeDirectories="..\common;$(SPICE_COMMON_DIR)"
- AdditionalUsingDirectories=""
- PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS,_WIN32_WINNT=0x0501"
- RuntimeLibrary="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS,_WIN32_WINNT=0x0501"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="3"
- Detect64BitPortabilityProblems="true"
+ Detect64BitPortabilityProblems="false"
DebugInformationFormat="3"
/>
<Tool
@@ -141,12 +143,12 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="Version.lib"
- LinkIncremental="1"
+ LinkIncremental="2"
GenerateDebugInformation="true"
SubSystem="2"
- OptimizeReferences="2"
- EnableCOMDATFolding="2"
- TargetMachine="1"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="17"
/>
<Tool
Name="VCALinkTool"
@@ -167,18 +169,16 @@
Name="VCAppVerifierTool"
/>
<Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
- Name="Debug|x64"
- OutputDirectory="$(PlatformName)\$(ConfigurationName)"
- IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+ Name="Release|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
+ WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -194,19 +194,16 @@
/>
<Tool
Name="VCMIDLTool"
- TargetEnvironment="3"
/>
<Tool
Name="VCCLCompilerTool"
- Optimization="0"
AdditionalIncludeDirectories="..\common;$(SPICE_COMMON_DIR)"
- PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS,_WIN32_WINNT=0x0501"
- MinimalRebuild="true"
- BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ AdditionalUsingDirectories=""
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS,_WIN32_WINNT=0x0501"
+ RuntimeLibrary="0"
UsePrecompiledHeader="0"
WarningLevel="3"
- Detect64BitPortabilityProblems="true"
+ Detect64BitPortabilityProblems="false"
DebugInformationFormat="3"
/>
<Tool
@@ -221,10 +218,14 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="Version.lib"
- LinkIncremental="2"
+ LinkIncremental="1"
GenerateDebugInformation="true"
SubSystem="2"
- TargetMachine="17"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
@@ -245,9 +246,6 @@
Name="VCAppVerifierTool"
/>
<Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
@@ -283,7 +281,7 @@
RuntimeLibrary="0"
UsePrecompiledHeader="0"
WarningLevel="3"
- Detect64BitPortabilityProblems="true"
+ Detect64BitPortabilityProblems="false"
DebugInformationFormat="3"
/>
<Tool
@@ -303,6 +301,8 @@
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
TargetMachine="17"
/>
<Tool
@@ -324,9 +324,6 @@
Name="VCAppVerifierTool"
/>
<Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
diff --git a/vdservice/vdservice.vcproj b/vdservice/vdservice.vcproj
index 8db43a9..4e70a8b 100644
--- a/vdservice/vdservice.vcproj
+++ b/vdservice/vdservice.vcproj
@@ -1,11 +1,12 @@
<?xml version="1.0" encoding="windows-1255"?>
<VisualStudioProject
ProjectType="Visual C++"
- Version="8.00"
+ Version="9.00"
Name="vdservice"
ProjectGUID="{ADFE5E22-31D0-4343-AE9E-8102CC0051F9}"
RootNamespace="redservice"
Keyword="Win32Proj"
+ TargetFrameworkVersion="131072"
>
<Platforms>
<Platform
@@ -50,7 +51,7 @@
RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="3"
- Detect64BitPortabilityProblems="true"
+ Detect64BitPortabilityProblems="false"
DebugInformationFormat="4"
/>
<Tool
@@ -68,6 +69,8 @@
LinkIncremental="2"
GenerateDebugInformation="true"
SubSystem="1"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
@@ -89,19 +92,15 @@
Name="VCAppVerifierTool"
/>
<Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
- Name="Release|Win32"
- OutputDirectory="$(ConfigurationName)"
- IntermediateDirectory="$(ConfigurationName)"
+ Name="Debug|x64"
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
- WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -117,15 +116,19 @@
/>
<Tool
Name="VCMIDLTool"
+ TargetEnvironment="3"
/>
<Tool
Name="VCCLCompilerTool"
+ Optimization="0"
AdditionalIncludeDirectories="..\common;$(SPICE_COMMON_DIR)"
- PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE,_WIN32_WINNT=0x0501"
- RuntimeLibrary="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE,_WIN32_WINNT=0x0501"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="3"
- Detect64BitPortabilityProblems="true"
+ Detect64BitPortabilityProblems="false"
DebugInformationFormat="3"
/>
<Tool
@@ -140,12 +143,12 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="WtsApi32.lib Userenv.lib Version.lib"
- LinkIncremental="1"
+ LinkIncremental="2"
GenerateDebugInformation="true"
SubSystem="1"
- OptimizeReferences="2"
- EnableCOMDATFolding="2"
- TargetMachine="1"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="17"
/>
<Tool
Name="VCALinkTool"
@@ -166,18 +169,16 @@
Name="VCAppVerifierTool"
/>
<Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
- Name="Debug|x64"
- OutputDirectory="$(PlatformName)\$(ConfigurationName)"
- IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+ Name="Release|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
+ WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
@@ -193,19 +194,15 @@
/>
<Tool
Name="VCMIDLTool"
- TargetEnvironment="3"
/>
<Tool
Name="VCCLCompilerTool"
- Optimization="0"
AdditionalIncludeDirectories="..\common;$(SPICE_COMMON_DIR)"
- PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE,_WIN32_WINNT=0x0501"
- MinimalRebuild="true"
- BasicRuntimeChecks="3"
- RuntimeLibrary="1"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE,_WIN32_WINNT=0x0501"
+ RuntimeLibrary="0"
UsePrecompiledHeader="0"
WarningLevel="3"
- Detect64BitPortabilityProblems="true"
+ Detect64BitPortabilityProblems="false"
DebugInformationFormat="3"
/>
<Tool
@@ -220,10 +217,14 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="WtsApi32.lib Userenv.lib Version.lib"
- LinkIncremental="2"
+ LinkIncremental="1"
GenerateDebugInformation="true"
SubSystem="1"
- TargetMachine="17"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
@@ -244,9 +245,6 @@
Name="VCAppVerifierTool"
/>
<Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
@@ -281,7 +279,7 @@
RuntimeLibrary="0"
UsePrecompiledHeader="0"
WarningLevel="3"
- Detect64BitPortabilityProblems="true"
+ Detect64BitPortabilityProblems="false"
DebugInformationFormat="3"
/>
<Tool
@@ -301,6 +299,8 @@
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
TargetMachine="17"
/>
<Tool
@@ -322,9 +322,6 @@
Name="VCAppVerifierTool"
/>
<Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
commit 8eafd5ef096a745968705c55b22ed3e64a3a8bf9
Author: Arnon Gilboa <agilboa at agilboa.usersys.redhat.com>
Date: Tue Feb 9 20:04:30 2010 +0200
spice: vdagent: support x64 arch
diff --git a/vdagent/vdagent.vcproj b/vdagent/vdagent.vcproj
index f012bc4..ca65b07 100644
--- a/vdagent/vdagent.vcproj
+++ b/vdagent/vdagent.vcproj
@@ -330,6 +330,163 @@
Name="VCPostBuildEventTool"
/>
</Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\common;$(SPICE_COMMON_DIR)"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS,_WIN32_WINNT=0x0501"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="Version.lib"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="..\common;$(SPICE_COMMON_DIR)"
+ AdditionalUsingDirectories=""
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS,_WIN32_WINNT=0x0501"
+ RuntimeLibrary="0"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="Version.lib"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
</Configurations>
<References>
</References>
diff --git a/vdservice/vdservice.vcproj b/vdservice/vdservice.vcproj
index 0616d08..8db43a9 100644
--- a/vdservice/vdservice.vcproj
+++ b/vdservice/vdservice.vcproj
@@ -328,6 +328,162 @@
Name="VCPostBuildEventTool"
/>
</Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\common;$(SPICE_COMMON_DIR)"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE,_WIN32_WINNT=0x0501"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="WtsApi32.lib Userenv.lib Version.lib"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="..\common;$(SPICE_COMMON_DIR)"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE,_WIN32_WINNT=0x0501"
+ RuntimeLibrary="0"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="WtsApi32.lib Userenv.lib Version.lib"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
</Configurations>
<References>
</References>
commit c1b6d6a8a121d4536803abffbed2b265fb4c76fc
Author: Arnon Gilboa <agilboa at agilboa.usersys.redhat.com>
Date: Tue Feb 9 20:04:30 2010 +0200
spice: vdagent: support x64 arch
diff --git a/common/stdint.h b/common/stdint.h
index 9316d56..250efb5 100644
--- a/common/stdint.h
+++ b/common/stdint.h
@@ -136,10 +136,14 @@ typedef unsigned long long uint_fast64_t;
/* 7.18.1.4 Integer types capable of holding object pointers */
+#ifndef _WIN64
+
typedef int intptr_t;
typedef unsigned uintptr_t;
+#endif
+
/* 7.18.1.5 Greatest-width integer types */
diff --git a/vdagent.sln b/vdagent.sln
index afb6513..1f0fc72 100644
--- a/vdagent.sln
+++ b/vdagent.sln
@@ -8,17 +8,27 @@ EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
+ Debug|x64 = Debug|x64
Release|Win32 = Release|Win32
+ Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{CAD5A7E6-E9F5-4071-AFDA-25F76FDA5442}.Debug|Win32.ActiveCfg = Debug|Win32
{CAD5A7E6-E9F5-4071-AFDA-25F76FDA5442}.Debug|Win32.Build.0 = Debug|Win32
+ {CAD5A7E6-E9F5-4071-AFDA-25F76FDA5442}.Debug|x64.ActiveCfg = Debug|x64
+ {CAD5A7E6-E9F5-4071-AFDA-25F76FDA5442}.Debug|x64.Build.0 = Debug|x64
{CAD5A7E6-E9F5-4071-AFDA-25F76FDA5442}.Release|Win32.ActiveCfg = Release|Win32
{CAD5A7E6-E9F5-4071-AFDA-25F76FDA5442}.Release|Win32.Build.0 = Release|Win32
+ {CAD5A7E6-E9F5-4071-AFDA-25F76FDA5442}.Release|x64.ActiveCfg = Release|x64
+ {CAD5A7E6-E9F5-4071-AFDA-25F76FDA5442}.Release|x64.Build.0 = Release|x64
{ADFE5E22-31D0-4343-AE9E-8102CC0051F9}.Debug|Win32.ActiveCfg = Debug|Win32
{ADFE5E22-31D0-4343-AE9E-8102CC0051F9}.Debug|Win32.Build.0 = Debug|Win32
+ {ADFE5E22-31D0-4343-AE9E-8102CC0051F9}.Debug|x64.ActiveCfg = Debug|x64
+ {ADFE5E22-31D0-4343-AE9E-8102CC0051F9}.Debug|x64.Build.0 = Debug|x64
{ADFE5E22-31D0-4343-AE9E-8102CC0051F9}.Release|Win32.ActiveCfg = Release|Win32
{ADFE5E22-31D0-4343-AE9E-8102CC0051F9}.Release|Win32.Build.0 = Release|Win32
+ {ADFE5E22-31D0-4343-AE9E-8102CC0051F9}.Release|x64.ActiveCfg = Release|x64
+ {ADFE5E22-31D0-4343-AE9E-8102CC0051F9}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/vdagent/vdagent.vcproj b/vdagent/vdagent.vcproj
index 954f865..f012bc4 100644
--- a/vdagent/vdagent.vcproj
+++ b/vdagent/vdagent.vcproj
@@ -11,6 +11,9 @@
<Platform
Name="Win32"
/>
+ <Platform
+ Name="x64"
+ />
</Platforms>
<ToolFiles>
</ToolFiles>
@@ -170,6 +173,163 @@
Name="VCPostBuildEventTool"
/>
</Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\common;$(SPICE_COMMON_DIR)"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS,_WIN32_WINNT=0x0501"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="Version.lib"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="..\common;$(SPICE_COMMON_DIR)"
+ AdditionalUsingDirectories=""
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS,_WIN32_WINNT=0x0501"
+ RuntimeLibrary="0"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="Version.lib"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
</Configurations>
<References>
</References>
diff --git a/vdservice/vdservice.vcproj b/vdservice/vdservice.vcproj
index bad8505..0616d08 100644
--- a/vdservice/vdservice.vcproj
+++ b/vdservice/vdservice.vcproj
@@ -11,6 +11,9 @@
<Platform
Name="Win32"
/>
+ <Platform
+ Name="x64"
+ />
</Platforms>
<ToolFiles>
</ToolFiles>
@@ -169,6 +172,162 @@
Name="VCPostBuildEventTool"
/>
</Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\common;$(SPICE_COMMON_DIR)"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE,_WIN32_WINNT=0x0501"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="WtsApi32.lib Userenv.lib Version.lib"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="..\common;$(SPICE_COMMON_DIR)"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE,_WIN32_WINNT=0x0501"
+ RuntimeLibrary="0"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="WtsApi32.lib Userenv.lib Version.lib"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
</Configurations>
<References>
</References>
More information about the Spice-commits
mailing list