Vinzenz Feenstra has uploaded a new change for review.

Change subject: tray win32 impl
......................................................................

tray win32 impl

Change-Id: I3c0caa72b548bb3ce39e06f7dc879709dba89989
Signed-off-by: Vinzenz Feenstra <vfeen...@redhat.com>
---
A tray/win32/ovirt-tray/ovirt-tray.sln
A tray/win32/ovirt-tray/ovirt-tray/ovirt-tray.cpp
A tray/win32/ovirt-tray/ovirt-tray/ovirt-tray.rc
A tray/win32/ovirt-tray/ovirt-tray/ovirt-tray.vcproj
A tray/win32/ovirt-tray/ovirt-tray/resource.h
A tray/win32/ovirt-tray/pipeserver/ReadMe.txt
A tray/win32/ovirt-tray/pipeserver/bson.h
A tray/win32/ovirt-tray/pipeserver/critical_section.h
A tray/win32/ovirt-tray/pipeserver/dllmain.cpp
A tray/win32/ovirt-tray/pipeserver/function_storage.h
A tray/win32/ovirt-tray/pipeserver/handle.h
A tray/win32/ovirt-tray/pipeserver/handler_functions.h
A tray/win32/ovirt-tray/pipeserver/handler_impl.h
A tray/win32/ovirt-tray/pipeserver/iofunoverlapped.h
A tray/win32/ovirt-tray/pipeserver/message.h
A tray/win32/ovirt-tray/pipeserver/named_pipe.h
A tray/win32/ovirt-tray/pipeserver/pipeserver.cpp
A tray/win32/ovirt-tray/pipeserver/pipeserver.h
A tray/win32/ovirt-tray/pipeserver/pipeserver.vcproj
A tray/win32/ovirt-tray/pipeserver/ref_ptr.h
A tray/win32/ovirt-tray/pipeserver/service.h
A tray/win32/ovirt-tray/pipeserver/stdafx.cpp
A tray/win32/ovirt-tray/pipeserver/stdafx.h
A tray/win32/ovirt-tray/pipeserver/stream_service.h
A tray/win32/ovirt-tray/pipeserver/targetver.h
A tray/win32/ovirt-tray/pipeserver/utilities.h
26 files changed, 3,273 insertions(+), 0 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-guest-agent 
refs/changes/43/34443/1

diff --git a/tray/win32/ovirt-tray/ovirt-tray.sln 
b/tray/win32/ovirt-tray/ovirt-tray.sln
new file mode 100644
index 0000000..19c7376
--- /dev/null
+++ b/tray/win32/ovirt-tray/ovirt-tray.sln
@@ -0,0 +1,36 @@
+
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual Studio 2008
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ovirt-tray", 
"ovirt-tray\ovirt-tray.vcproj", "{D5C9FA9F-D75A-4090-B8EE-DE271B938FAC}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pipeserver", 
"pipeserver\pipeserver.vcproj", "{A87356ED-7C0B-42CA-9327-E7CDE9C4E481}"
+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
+               {D5C9FA9F-D75A-4090-B8EE-DE271B938FAC}.Debug|Win32.ActiveCfg = 
Debug|Win32
+               {D5C9FA9F-D75A-4090-B8EE-DE271B938FAC}.Debug|Win32.Build.0 = 
Debug|Win32
+               {D5C9FA9F-D75A-4090-B8EE-DE271B938FAC}.Debug|x64.ActiveCfg = 
Debug|x64
+               {D5C9FA9F-D75A-4090-B8EE-DE271B938FAC}.Debug|x64.Build.0 = 
Debug|x64
+               {D5C9FA9F-D75A-4090-B8EE-DE271B938FAC}.Release|Win32.ActiveCfg 
= Release|Win32
+               {D5C9FA9F-D75A-4090-B8EE-DE271B938FAC}.Release|Win32.Build.0 = 
Release|Win32
+               {D5C9FA9F-D75A-4090-B8EE-DE271B938FAC}.Release|x64.ActiveCfg = 
Release|x64
+               {D5C9FA9F-D75A-4090-B8EE-DE271B938FAC}.Release|x64.Build.0 = 
Release|x64
+               {A87356ED-7C0B-42CA-9327-E7CDE9C4E481}.Debug|Win32.ActiveCfg = 
Debug|Win32
+               {A87356ED-7C0B-42CA-9327-E7CDE9C4E481}.Debug|Win32.Build.0 = 
Debug|Win32
+               {A87356ED-7C0B-42CA-9327-E7CDE9C4E481}.Debug|x64.ActiveCfg = 
Debug|x64
+               {A87356ED-7C0B-42CA-9327-E7CDE9C4E481}.Debug|x64.Build.0 = 
Debug|x64
+               {A87356ED-7C0B-42CA-9327-E7CDE9C4E481}.Release|Win32.ActiveCfg 
= Release|Win32
+               {A87356ED-7C0B-42CA-9327-E7CDE9C4E481}.Release|Win32.Build.0 = 
Release|Win32
+               {A87356ED-7C0B-42CA-9327-E7CDE9C4E481}.Release|x64.ActiveCfg = 
Release|x64
+               {A87356ED-7C0B-42CA-9327-E7CDE9C4E481}.Release|x64.Build.0 = 
Release|x64
+       EndGlobalSection
+       GlobalSection(SolutionProperties) = preSolution
+               HideSolutionNode = FALSE
+       EndGlobalSection
+EndGlobal
diff --git a/tray/win32/ovirt-tray/ovirt-tray/ovirt-tray.cpp 
b/tray/win32/ovirt-tray/ovirt-tray/ovirt-tray.cpp
new file mode 100644
index 0000000..4eb45ec
--- /dev/null
+++ b/tray/win32/ovirt-tray/ovirt-tray/ovirt-tray.cpp
@@ -0,0 +1,136 @@
+#include <windows.h>
+#include <named_pipe.h>
+#include "resource.h"
+
+#include <strsafe.h>
+
+#pragma comment(lib, "strsafe.lib")
+
+UINT WM_TASKBARCREATED;
+
+static TCHAR const OVIRT_TRAY_CLS[] = TEXT("OVIRT_GUEST_AGENT_TRAY");
+
+enum {
+       WM_NOTIFY_ICON_MESSAGE = WM_USER + 1,
+       IDT_TIMER = 102030
+};
+
+void RegisterWindow();
+LRESULT CALLBACK WindowProc(HWND, UINT, WPARAM, LPARAM);
+NOTIFYICONDATA notify = {};
+
+Service g_ioService;
+NamedPipeStream g_pipe(g_ioService);
+
+static TCHAR const * const OVIRT_PIPE_NAME = 
TEXT("\\\\.\\pipe\\ovirt-agent-test");
+
+void ConnectPipe() {
+    if(g_pipe.IsOpen()) {
+        return;
+    }
+    DWORD result = g_pipe.Open(OVIRT_PIPE_NAME);
+    if(result == NO_ERROR) {
+        return;
+    }
+    else {
+        g_ioService.Post(ConnectPipe);
+        ::WaitNamedPipe(OVIRT_PIPE_NAME, 100);        
+    }
+}
+
+int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
+{      
+    g_ioService.Start();
+    g_ioService.Post(ConnectPipe);
+    
+       WM_TASKBARCREATED = RegisterWindowMessage(TEXT("TaskbarCreated"));
+
+       RegisterWindow();
+
+       HWND wnd = CreateWindow(OVIRT_TRAY_CLS, TEXT("ovirt-guest-agent"), 
WS_OVERLAPPEDWINDOW | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, 100, 100, 0, 0, 
0, 0);
+       
+       notify.cbSize = sizeof(notify);
+       notify.hWnd = wnd;
+       notify.hIcon = LoadIcon(0, IDI_APPLICATION);    
+       notify.uCallbackMessage = WM_NOTIFY_ICON_MESSAGE;
+       StringCchCopy(notify.szTip, 64, TEXT("ovirt-guest-agent"));
+       notify.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;       
+       Shell_NotifyIcon(NIM_ADD, &notify);
+       SetTimer(wnd, IDT_TIMER, 10000, 0);
+
+       MSG message;
+       while(GetMessage(&message, 0, 0, 0)) {
+               TranslateMessage(&message);
+               DispatchMessage(&message);
+       }
+       Shell_NotifyIcon(NIM_DELETE, &notify);
+    g_ioService.Stop();
+       return 0;
+}
+
+void RegisterWindow()
+{
+       WNDCLASSEX wcex = {};
+       wcex.cbSize = sizeof(wcex);
+       wcex.lpfnWndProc = (WNDPROC)WindowProc;
+       wcex.style = CS_HREDRAW | CS_VREDRAW;
+       wcex.lpszClassName = OVIRT_TRAY_CLS;
+       wcex.hIcon = LoadIcon(0, IDI_APPLICATION);
+       wcex.hIconSm = LoadIcon(0, IDI_APPLICATION);
+       wcex.hCursor = LoadCursor(0, IDC_ARROW);
+       wcex.hbrBackground = (HBRUSH)COLOR_BACKGROUND;
+       RegisterClassEx(&wcex);
+}
+
+BOOL CALLBACK AboutDlgProc(HWND h, UINT m, WPARAM w, LPARAM l) {
+       if(m == WM_COMMAND) {
+               if(LOWORD(w) == IDOK) {
+                       EndDialog(h, w);
+                       return TRUE;
+               }
+       }
+       return FALSE;
+}
+
+LRESULT CALLBACK WindowProc(HWND h, UINT m, WPARAM w, LPARAM l)
+{
+       if(m == WM_NOTIFY_ICON_MESSAGE) {
+               if(l == WM_LBUTTONUP) {
+                       MessageBox(0, TEXT("Geez"), TEXT("Click Click"), 
MB_OK|MB_ICONINFORMATION);
+               }
+               else if(l == WM_RBUTTONUP) {
+                       HMENU menu = LoadMenu(0, 
MAKEINTRESOURCE(IDR_TRAY_MENU));
+                       menu = GetSubMenu(menu, 0);
+                       POINT pt = {};
+                       GetCursorPos(&pt);
+                       INT result = TrackPopupMenu(menu, TPM_RETURNCMD, pt.x, 
pt.y, 0, h, 0);
+                       // TrackPopupMenu()
+                       if(ID_TRAYMENU_ABOUT == result) {                       
+                               DialogBox(0, MAKEINTRESOURCE(IDD_ABOUT_DIALOG), 
h, (DLGPROC)(AboutDlgProc));
+                       }
+                       if(ID_TRAYMENU_QUIT == result) {
+                               if(MessageBox(0, TEXT("Do you really want to 
quit the oVirt guest agent tray application?"), TEXT("Please confirm"), 
MB_ICONQUESTION|MB_YESNO) == IDYES) {
+                                       PostMessage(h, WM_CLOSE, 0, 0);
+                               }
+                       }
+               }
+               return 0;
+       }
+       if(m == WM_TIMER) {
+               switch(w) {
+                       case IDT_TIMER:
+                               {
+                                       StringCchCopy(notify.szInfo, 256, 
TEXT("The ovirt-guest-agent sends a notification"));
+                                       StringCchCopy(notify.szInfoTitle, 64, 
TEXT("ovirt-guest-agent notifies"));
+                                       notify.dwInfoFlags = NIIF_INFO;
+                                       notify.uFlags |= NIF_INFO;
+                                       Shell_NotifyIcon(NIM_MODIFY, &notify);
+                                       KillTimer(h, IDT_TIMER);
+                               }
+               }
+       }
+       if(m == WM_CLOSE) {
+               PostQuitMessage(0);
+       }
+       return DefWindowProc(h, m, w, l);
+}
\ No newline at end of file
diff --git a/tray/win32/ovirt-tray/ovirt-tray/ovirt-tray.rc 
b/tray/win32/ovirt-tray/ovirt-tray/ovirt-tray.rc
new file mode 100644
index 0000000..86d26f3
--- /dev/null
+++ b/tray/win32/ovirt-tray/ovirt-tray/ovirt-tray.rc
@@ -0,0 +1,120 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE 
+BEGIN
+    "resource.h\0"
+END
+
+2 TEXTINCLUDE 
+BEGIN
+    "#include ""afxres.h""\r\n"
+    "\0"
+END
+
+3 TEXTINCLUDE 
+BEGIN
+    "\r\n"
+    "\0"
+END
+
+#endif    // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Menu
+//
+
+IDR_TRAY_MENU MENU 
+BEGIN
+    POPUP "Tray Menu"
+    BEGIN
+        MENUITEM "&About",                      ID_TRAYMENU_ABOUT
+        MENUITEM SEPARATOR
+        MENUITEM "&Quit",                       ID_TRAYMENU_QUIT
+    END
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_ABOUT_DIALOG DIALOGEX 0, 0, 316, 183
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | 
WS_SYSMENU
+CAPTION "About oVirt Guest Tools"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+    DEFPUSHBUTTON   "OK",IDOK,259,162,50,14
+    LTEXT           "oVirt Guest Tools for 
Windows",IDC_GUEST_TOOLS_NAME,7,7,206,8
+    LTEXT           "Version 3.6.0",IDC_GUEST_TOOLS_VERSION,7,21,206,8
+    ICON            32512,IDC_GUEST_TOOLS_ICON,284,7,20,20
+    EDITTEXT        IDC_LICENSE_TEXT,7,38,302,117,ES_MULTILINE | 
ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_READONLY,WS_EX_CLIENTEDGE
+    LTEXT           "The oVirt Guest Tools are 
running.",IDC_GUEST_STATUS,7,168,205,8
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO 
+BEGIN
+    IDD_ABOUT_DIALOG, DIALOG
+    BEGIN
+        LEFTMARGIN, 7
+        RIGHTMARGIN, 309
+        TOPMARGIN, 7
+        BOTTOMMARGIN, 176
+        HORZGUIDE, 7
+        HORZGUIDE, 21
+        HORZGUIDE, 30
+    END
+END
+#endif    // APSTUDIO_INVOKED
+
+#endif    // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif    // not APSTUDIO_INVOKED
+
diff --git a/tray/win32/ovirt-tray/ovirt-tray/ovirt-tray.vcproj 
b/tray/win32/ovirt-tray/ovirt-tray/ovirt-tray.vcproj
new file mode 100644
index 0000000..0a80ec2
--- /dev/null
+++ b/tray/win32/ovirt-tray/ovirt-tray/ovirt-tray.vcproj
@@ -0,0 +1,355 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+       ProjectType="Visual C++"
+       Version="9.00"
+       Name="ovirt-tray"
+       ProjectGUID="{D5C9FA9F-D75A-4090-B8EE-DE271B938FAC}"
+       RootNamespace="ovirttray"
+       Keyword="Win32Proj"
+       TargetFrameworkVersion="196613"
+       >
+       <Platforms>
+               <Platform
+                       Name="Win32"
+               />
+               <Platform
+                       Name="x64"
+               />
+       </Platforms>
+       <ToolFiles>
+       </ToolFiles>
+       <Configurations>
+               <Configuration
+                       Name="Debug|Win32"
+                       OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+                       IntermediateDirectory="$(ConfigurationName)"
+                       ConfigurationType="1"
+                       CharacterSet="1"
+                       >
+                       <Tool
+                               Name="VCPreBuildEventTool"
+                       />
+                       <Tool
+                               Name="VCCustomBuildTool"
+                       />
+                       <Tool
+                               Name="VCXMLDataGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCWebServiceProxyGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCMIDLTool"
+                       />
+                       <Tool
+                               Name="VCCLCompilerTool"
+                               Optimization="0"
+                               
AdditionalIncludeDirectories="$(ProjectDir)\..\pipeserver"
+                               PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
+                               MinimalRebuild="true"
+                               BasicRuntimeChecks="3"
+                               RuntimeLibrary="3"
+                               UsePrecompiledHeader="0"
+                               WarningLevel="3"
+                               DebugInformationFormat="4"
+                       />
+                       <Tool
+                               Name="VCManagedResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCPreLinkEventTool"
+                       />
+                       <Tool
+                               Name="VCLinkerTool"
+                               LinkIncremental="2"
+                               GenerateDebugInformation="true"
+                               SubSystem="2"
+                               TargetMachine="1"
+                       />
+                       <Tool
+                               Name="VCALinkTool"
+                       />
+                       <Tool
+                               Name="VCManifestTool"
+                       />
+                       <Tool
+                               Name="VCXDCMakeTool"
+                       />
+                       <Tool
+                               Name="VCBscMakeTool"
+                       />
+                       <Tool
+                               Name="VCFxCopTool"
+                       />
+                       <Tool
+                               Name="VCAppVerifierTool"
+                       />
+                       <Tool
+                               Name="VCPostBuildEventTool"
+                       />
+               </Configuration>
+               <Configuration
+                       Name="Release|Win32"
+                       OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+                       IntermediateDirectory="$(ConfigurationName)"
+                       ConfigurationType="1"
+                       CharacterSet="1"
+                       WholeProgramOptimization="1"
+                       >
+                       <Tool
+                               Name="VCPreBuildEventTool"
+                       />
+                       <Tool
+                               Name="VCCustomBuildTool"
+                       />
+                       <Tool
+                               Name="VCXMLDataGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCWebServiceProxyGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCMIDLTool"
+                       />
+                       <Tool
+                               Name="VCCLCompilerTool"
+                               Optimization="2"
+                               EnableIntrinsicFunctions="true"
+                               
AdditionalIncludeDirectories="$(ProjectDir)\..\pipeserver"
+                               PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
+                               RuntimeLibrary="0"
+                               EnableFunctionLevelLinking="true"
+                               UsePrecompiledHeader="0"
+                               WarningLevel="3"
+                               DebugInformationFormat="3"
+                       />
+                       <Tool
+                               Name="VCManagedResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCPreLinkEventTool"
+                       />
+                       <Tool
+                               Name="VCLinkerTool"
+                               LinkIncremental="1"
+                               GenerateDebugInformation="true"
+                               SubSystem="2"
+                               OptimizeReferences="2"
+                               EnableCOMDATFolding="2"
+                               TargetMachine="1"
+                       />
+                       <Tool
+                               Name="VCALinkTool"
+                       />
+                       <Tool
+                               Name="VCManifestTool"
+                       />
+                       <Tool
+                               Name="VCXDCMakeTool"
+                       />
+                       <Tool
+                               Name="VCBscMakeTool"
+                       />
+                       <Tool
+                               Name="VCFxCopTool"
+                       />
+                       <Tool
+                               Name="VCAppVerifierTool"
+                       />
+                       <Tool
+                               Name="VCPostBuildEventTool"
+                       />
+               </Configuration>
+               <Configuration
+                       Name="Debug|x64"
+                       
OutputDirectory="$(SolutionDir)$(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="$(ProjectDir)\..\pipeserver"
+                               PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
+                               MinimalRebuild="true"
+                               BasicRuntimeChecks="3"
+                               RuntimeLibrary="3"
+                               UsePrecompiledHeader="0"
+                               WarningLevel="3"
+                               DebugInformationFormat="3"
+                       />
+                       <Tool
+                               Name="VCManagedResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCPreLinkEventTool"
+                       />
+                       <Tool
+                               Name="VCLinkerTool"
+                               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="VCPostBuildEventTool"
+                       />
+               </Configuration>
+               <Configuration
+                       Name="Release|x64"
+                       
OutputDirectory="$(SolutionDir)$(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"
+                               Optimization="2"
+                               EnableIntrinsicFunctions="true"
+                               
AdditionalIncludeDirectories="$(ProjectDir)\..\pipeserver"
+                               PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
+                               RuntimeLibrary="0"
+                               EnableFunctionLevelLinking="true"
+                               UsePrecompiledHeader="0"
+                               WarningLevel="3"
+                               DebugInformationFormat="3"
+                       />
+                       <Tool
+                               Name="VCManagedResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCPreLinkEventTool"
+                       />
+                       <Tool
+                               Name="VCLinkerTool"
+                               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="VCPostBuildEventTool"
+                       />
+               </Configuration>
+       </Configurations>
+       <References>
+       </References>
+       <Files>
+               <Filter
+                       Name="Source Files"
+                       Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+                       
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+                       >
+                       <File
+                               RelativePath=".\ovirt-tray.cpp"
+                               >
+                       </File>
+               </Filter>
+               <Filter
+                       Name="Header Files"
+                       Filter="h;hpp;hxx;hm;inl;inc;xsd"
+                       
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+                       >
+                       <File
+                               RelativePath=".\resource.h"
+                               >
+                       </File>
+               </Filter>
+               <Filter
+                       Name="Resource Files"
+                       
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+                       
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+                       >
+                       <File
+                               RelativePath=".\ovirt-tray.rc"
+                               >
+                       </File>
+               </Filter>
+       </Files>
+       <Globals>
+       </Globals>
+</VisualStudioProject>
diff --git a/tray/win32/ovirt-tray/ovirt-tray/resource.h 
b/tray/win32/ovirt-tray/ovirt-tray/resource.h
new file mode 100644
index 0000000..05be8ca
--- /dev/null
+++ b/tray/win32/ovirt-tray/ovirt-tray/resource.h
@@ -0,0 +1,24 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by ovirt-tray.rc
+//
+#define IDR_TRAY_MENU                   101
+#define IDD_ABOUT_DIALOG                102
+#define IDC_LICENSE_TEXT                1001
+#define IDC_GUEST_TOOLS_VERSION         1002
+#define IDC_GUEST_STATUS                1003
+#define IDC_GUEST_TOOLS_ICON            1004
+#define IDC_GUEST_TOOLS_NAME            1005
+#define ID_TRAYMENU_ABOUT               40001
+#define ID_TRAYMENU_QUIT                40002
+
+// Next default values for new objects
+// 
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE        103
+#define _APS_NEXT_COMMAND_VALUE         40003
+#define _APS_NEXT_CONTROL_VALUE         1006
+#define _APS_NEXT_SYMED_VALUE           101
+#endif
+#endif
diff --git a/tray/win32/ovirt-tray/pipeserver/ReadMe.txt 
b/tray/win32/ovirt-tray/pipeserver/ReadMe.txt
new file mode 100644
index 0000000..3d56182
--- /dev/null
+++ b/tray/win32/ovirt-tray/pipeserver/ReadMe.txt
@@ -0,0 +1,33 @@
+========================================================================
+    DYNAMIC LINK LIBRARY : pipeserver Project Overview
+========================================================================
+
+AppWizard has created this pipeserver DLL for you.
+
+This file contains a summary of what you will find in each of the files that
+make up your pipeserver application.
+
+
+pipeserver.vcproj
+    This is the main project file for VC++ projects generated using an 
Application Wizard.
+    It contains information about the version of Visual C++ that generated the 
file, and
+    information about the platforms, configurations, and project features 
selected with the
+    Application Wizard.
+
+pipeserver.cpp
+    This is the main DLL source file.
+
+/////////////////////////////////////////////////////////////////////////////
+Other standard files:
+
+StdAfx.h, StdAfx.cpp
+    These files are used to build a precompiled header (PCH) file
+    named pipeserver.pch and a precompiled types file named StdAfx.obj.
+
+/////////////////////////////////////////////////////////////////////////////
+Other notes:
+
+AppWizard uses "TODO:" comments to indicate parts of the source code you
+should add to or customize.
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/tray/win32/ovirt-tray/pipeserver/bson.h 
b/tray/win32/ovirt-tray/pipeserver/bson.h
new file mode 100644
index 0000000..166ddd6
--- /dev/null
+++ b/tray/win32/ovirt-tray/pipeserver/bson.h
@@ -0,0 +1,635 @@
+#pragma once
+
+#include <string>
+#include <vector>
+#include <unordered_map>
+#include <memory>
+#include <cassert>
+#include "ref_ptr.h"
+
+struct null_t{};
+namespace detail {
+    typedef unsigned char uint8_t;
+    typedef INT32 int32_t;
+    typedef INT64 int64_t;
+    
+
+    /* Basic types: All values are little endian encoded
+     * <uint8>      1 byte  (8-bit unsigned integer, two's complement)
+     * <int32>      4 bytes (32-bit signed integer, two's complement)
+     * <int64>      8 bytes (64-bit signed integer, two's complement)
+     * <double>     8 bytes (64-bit IEEE 754 floating point)
+     * 
+     * document     ::= size value
+     * value:       ::= 
+     *                byte
+     *              | bool
+     *              | int32
+     *              | int64
+     *              | double
+     *              | string
+     *              | list
+     *              | object
+     *              | map
+     *              | binary
+     *              | datetime
+     *              | null
+     * null         ::= '\x00'                          # 
+     * byte         ::= '\x01' <uint8>                  # 
+     * bool         ::= '\x02' ('\x00' | '\x01')        # '\x00' when false, 
'\x01' when true
+     * int32        ::= '\x03' <int32>                  # 
+     * int64        ::= '\x04' <int64>                  # 
+     * double       ::= '\x05' <double>                 # 
+     * string       ::= '\x06' size cstring             # size must match the 
number of elements in cstring including 0 termination
+     * list         ::= '\x07' size value*              # size must match the 
number of value elements
+     * object       ::= '\x08' size (string value)*     # size must match the 
number of (string value) tuples
+     * map          ::= '\x09' size (value value)*      # size must match the 
number of (value value) tuples
+     * binary       ::= '\x0A' size <uint8>*            # size must match 
count of <uint8> elements
+     * datetime     ::= '\x0B' size int64_t             # seconds since UTC 
epoch
+     * cstring      ::= <uint8>* '\x00'                 # 0-terminated utf-8 
encoded string
+     * size         ::= <int64>
+     */
+    
+    enum data_type {
+        kDataType_First     = 0x00,
+        kDataType_Null      = 0x00,
+        kDataType_Byte      = 0x01,
+        kDataType_Bool      = 0x02,
+        kDataType_Int32     = 0x03,
+        kDataType_Int64     = 0x04,
+        kDataType_Double    = 0x05,
+        kDataType_String    = 0x06,
+        kDataType_List      = 0x07,
+        kDataType_Object    = 0x08,
+        kDataType_Map       = 0x09,
+        kDataType_Binary    = 0x0A,
+        kDataType_DateTime  = 0x0B,
+        
+        // Leave at end
+        kDataType_Count,
+        kDataType_Last      = kDataType_Count - 1,
+        kDataType_Invalid   = -1
+    };       
+    
+    template< typename T >
+    void push(std::vector<uint8_t> & target, T v) {
+        uint8_t const * ptr = reinterpret_cast<uint8_t const *>(&v);
+        target.insert(target.end(), ptr, ptr + sizeof(v));
+    }
+
+    template< typename T >
+    void push(std::vector<uint8_t> & target, T const * tptr, size_t elements) {
+        uint8_t const * ptr = reinterpret_cast<uint8_t const *>(ptr);
+        target.insert(target.end(), ptr, ptr + (sizeof(T) * elements));
+    }
+    
+    template< typename Element, size_t SizeDiff >        
+    class data_view {
+    public:
+        typedef Element value_type;
+        typedef value_type const * iterator;
+        typedef value_type const * const_iterator;
+        typedef value_type const * const_pointer;
+        typedef size_t size_type;
+        static Element const EMPTY = 0;
+     
+        data_view()
+        : p_(&EMPTY)
+        , length_(0)
+        {}
+     
+        data_view(const_pointer b, const_pointer e) 
+        : p_(b)
+        , length_(size_type(e - b) >= SizeDiff ? size_type(e - b) - SizeDiff : 
0)
+        {
+            assert(b <= e);
+        }
+        
+        data_view(data_view const & that)
+        : p_(that.p_)
+        , length_(that.length_)
+        {}
+
+        value_type operator[](size_type index) const {
+            assert(index < length_);
+            return p_[index];
+        }        
+
+        const_iterator begin() const {
+            return p_;
+        }
+
+        const_iterator end() const {
+            return p_ + length_;
+        }
+
+        size_type size() const {
+            return length_;
+        }
+
+        const_pointer data() const {
+            return p_;
+        }
+        
+        size_t diff() const {
+            return SizeDiff;
+        }
+    protected:
+        const_pointer p_;
+        size_type  length_;
+    };
+    
+    typedef data_view<uint8_t, 0> binary_view;
+
+    class string_view : public data_view<char, 1> {
+    public:
+        string_view()
+        : data_view()
+        {}
+    
+        string_view(const_pointer b, const_pointer e)
+        : data_view(b, e)
+        {}
+        
+        const_pointer c_str() const {
+            return data();
+        }
+    };        
+    
+    class value {
+    protected:
+        // Only inheriting classes are 
+        // allowed to set the type
+        value(data_type type)
+        : type_(type)
+        {}
+    public:
+        value()
+        : type_(kDataType_Invalid)
+        {}
+    
+        data_type type() const {
+            return type_;
+        }
+        
+        bool valid() const {
+            return type_ != kDataType_Invalid
+                && type_ >= kDataType_First 
+                && type_ <= kDataType_Last
+                ;
+        }
+        
+        bool operator==(value const & rhs) const {
+            return equals(rhs);
+        }
+        
+        virtual void append(std::vector<uint8_t> & target) const = 0;        
+        virtual bool equals(value const & rhs) const = 0;
+        virtual size_t hash() const = 0;
+    protected:
+        data_type const type_;
+    };
+    
+    typedef ref_ptr<value> value_ptr;
+
+    bool consume(uint8_t const *& b, uint8_t const * e, uint8_t & target) {
+        return false;
+    }
+    bool consume(uint8_t const *& b, uint8_t const * e, int32_t & target) {
+        return false;
+    }
+    bool consume(uint8_t const *& b, uint8_t const * e, int64_t & target) {
+        return false;
+    }
+    bool consume(uint8_t const *& b, uint8_t const * e, double & target) {
+        return false;
+    }
+    bool consume(uint8_t const *& b, uint8_t const * e, value_ptr & target);
+    
+    template< typename T >    
+    bool consume(uint8_t const *& b, uint8_t const * e, ref_ptr<T> & target) {
+        return T::consume(b, e, target);
+    }
+    
+    class null_value : public value {
+    public:
+        null_value()
+        : value(kDataType_Null)
+        {}
+        
+        null_value(null_t const &)
+        : value(kDataType_Null)
+        {}
+        
+        static bool consume(uint8_t const *& b,
+                            uint8_t const * e,
+                            ref_ptr<null_value> & target);
+        void append(std::vector<uint8_t> & target) const {
+            push<uint8_t>(target, type());
+        }
+        bool equals(value const & rhs) const {
+            return true;
+        }
+        size_t hash() const { return 0; }
+    };
+    
+    template< typename PODType, data_type DataType >
+    class basic_pod_value : public value {        
+    public:
+        typedef value base_type;
+        basic_pod_value(PODType v = PODType())
+        : base_type(DataType)
+        , data_(v)
+        {}                
+
+        PODType value() const {
+            return data_;
+        }                
+        
+        void value(PODType v) {
+            data_ = v;
+        }
+
+        static bool consume(uint8_t const *& b,
+                            uint8_t const * e,
+                            ref_ptr<basic_pod_value> & target);
+        void append(std::vector<uint8_t> & target) const {
+            push<uint8_t>(target, DataType);
+            push<PODType>(target, data_);
+        }
+        bool equals(base_type const & rhs) const {
+            return rhs.type() == type()
+                && data_ == static_cast<basic_pod_value const &>(rhs).data_;
+        }
+        size_t hash() const {
+            return std::tr1::hash<PODType>()(data_);
+        }
+    protected:
+        PODType data_;
+    };
+    
+    typedef basic_pod_value<double, kDataType_Double>       double_value;
+    typedef basic_pod_value<uint8_t, kDataType_Byte>        byte_value;
+    typedef basic_pod_value<int32_t, kDataType_Int32>       int32_value;
+    typedef basic_pod_value<int64_t, kDataType_Int64>       int64_value;
+    typedef basic_pod_value<int64_t, kDataType_DateTime>    datetime_value;
+    
+    template< typename ViewType, data_type DataType >
+    class basic_view_value : public value {        
+    public:
+        typedef value base_type;
+        basic_view_value(ViewType view)
+        : base_type(DataType)
+        , data_(view)
+        {}                
+
+        ViewType value() const {
+            return data_;
+        }                
+
+        void value(ViewType v) {
+            data_ = v;
+        }
+
+        static bool consume(uint8_t const *& b,
+                            uint8_t const * e,
+                            ref_ptr<basic_view_value> & target)
+        {
+            uint8_t const * const backup = b;
+            bool result = false;
+            if(b < e) {
+                uint8_t t = kDataType_Invalid;
+                result = detail::consume(b, e, t) && t == DataType;
+                int64_t count = 0;
+                result = result && detail::consume(b, e, count);
+                result = (e - b) <= count;
+                if(result) {
+                    typedef ViewType::const_pointer ptr_t;
+                    target = new 
basic_view_value(ViewType(reinterpret_cast<ptr_t>(b), 
reinterpret_cast<ptr_t>(b) + count));
+                }
+            }
+            if(!result) {
+                b = backup;
+            }
+            return result;
+        }
+        void append(std::vector<uint8_t> & target) const {
+            push<uint8_t>(target, type());
+            push<int64_t>(target, data_.size() + data_.diff());
+            if(data_.size() > 0) {
+                push(target, data_.data(), data_.size() + data_.diff());
+            }
+        }
+        
+        bool equals(base_type const & rhs) const {            
+            return type() == rhs.type()
+                && static_cast<basic_view_value const &>(rhs).value().data() 
== value().data();
+        }
+        
+        size_t hash() const {
+            return std::tr1::hash<typename 
ViewType::const_pointer>()(data_.data());
+        }
+    protected:
+        ViewType data_;
+    };
+        
+    typedef basic_view_value<string_view, kDataType_String> string_value;
+    typedef basic_view_value<binary_view, kDataType_Binary> binary_value;
+    
+    class list_value : public value {
+    public:
+        typedef value base_type;
+    
+        list_value(std::vector<value_ptr> const & v)
+        : base_type(kDataType_List)
+        , data_(new std::vector<value_ptr>(v))
+        {}
+        
+        list_value(ref_ptr<std::vector<value_ptr> > const & v)
+        : base_type(kDataType_List)
+        , data_(v)
+        {}
+
+        list_value()
+        : base_type(kDataType_List)
+        , data_()
+        {}
+        
+        ref_ptr<std::vector<value_ptr> > value() const {
+            return data_;        
+        }    
+        
+        void value(std::vector<value_ptr> const & v) {
+            data_ = new std::vector<value_ptr>(v);
+        }
+        
+        static bool consume(uint8_t const *& b,
+                            uint8_t const * e,
+                            ref_ptr<list_value> & target)
+        {
+            ref_ptr<list_value> list;
+            bool result = false;
+            uint8_t const * backup = b;
+            if(b < e) {
+                uint8_t type8 = kDataType_Invalid;
+                result = detail::consume(b, e, type8);
+                int64_t count = 0;
+                result = result && detail::consume(b, e, count);
+                list = new list_value();
+                list->data_->resize(size_t(count));
+                for(int64_t i = 0; result && i < count; ++i) {
+                    result = detail::consume(b, e, (*list->data_)[i]);
+                }
+            }
+            if(!result) {
+                b = backup;
+            }
+            else {
+                target = list;
+            }
+            return result;
+        }
+                            
+        void append(std::vector<uint8_t> & target) const {
+            push<uint8_t>(target, type());
+            push<int64_t>(target, data_->size());            
+            for(std::vector<value_ptr>::const_iterator it = data_->begin(), 
end = data_->end(); it != end; ++it) {
+                (*it)->append(target);
+            }
+        }
+
+        bool equals(base_type const & rhs) const {            
+            return rhs.type() == type()
+                && data_.get() != 0 
+                && static_cast<list_value const &>(rhs).data_.get() != 0 
+                && (data_.get()) == static_cast<list_value const 
&>(rhs).data_.get();
+        }
+
+        size_t hash() const {
+            return size_t(data_.get());
+        }
+    protected:
+        ref_ptr<std::vector<value_ptr> > data_;
+    };
+
+    struct value_hasher {
+        size_t operator()(value_ptr const & v) const {
+            size_t result = 0;
+            if(v.get() && v->valid()) {
+                result = v->hash();
+            }
+            return result;
+        }     
+    };
+    
+    struct value_equals
+    : public std::binary_function<value_ptr, value_ptr, bool> {
+        bool operator()(value_ptr const & lhs, value_ptr const & rhs) const {
+            bool result = false;
+            if((lhs.get() != 0) == (rhs.get() != 0)) {
+                if(lhs.get() != 0 && rhs.get() != 0) {
+                    if(lhs->type() == rhs->type()) {
+                        return *lhs == *rhs;
+                    }
+                }
+            }
+            return result;
+        };    
+    };
+
+    template< typename Key >
+    class mapped_value : public value {
+    public:
+        typedef Key key_type;
+        typedef value_ptr value_type;
+        typedef std::tr1::unordered_map<key_type, value_type, value_hasher, 
value_equals> map_type;
+        typedef value base_type;
+
+        mapped_value(map_type const & v)
+        : base_type(kDataType_List)
+        , data_(new map_type(v))
+        {}
+
+        mapped_value(ref_ptr<map_type> const & v)
+        : base_type(kDataType_List)
+        , data_(v)
+        {}
+
+        mapped_value()
+        : base_type(kDataType_List)
+        , data_()
+        {}
+
+        ref_ptr<map_type> value() const {
+            return data_;        
+        }    
+
+        void value(map_type const & v) {
+            data_ = new map_type(v);
+        }
+
+        static bool consume(uint8_t const *& b,
+                            uint8_t const * e,
+                            ref_ptr<mapped_value> & target)
+        {
+            ref_ptr<mapped_value> map;
+            bool result = false;
+            uint8_t const * backup = b;
+            if(b < e) {
+                uint8_t type8 = kDataType_Invalid;
+                result = detail::consume(b, e, type8);
+                int64_t count = 0;
+                result = result && detail::consume(b, e, count);
+                map = new mapped_value();
+                for(int64_t i = 0; result && i < count; ++i) {
+                    key_type k;              
+                    result = result && detail::consume(b, e, k);
+                    value_type v;
+                    result = result && detail::consume(b, e, v);               
     
+                    (*map->data_)[k] = v;
+                }
+            }
+            if(!result) {
+                b = backup;
+            }
+            else {
+                target = map;
+            }
+            return result;
+        }
+
+        void append(std::vector<uint8_t> & target) const {
+            push<int64_t>(target, type());
+            push<int64_t>(target, data_->size());            
+            for(map_type::const_iterator it = data_->begin(), end = 
data_->end(); it != end; ++it) {
+                it->first->append(target);
+                it->second->append(target);
+            }
+        }
+        bool equals(base_type const & rhs) const {            
+            return rhs.type() == type()
+                && data_.get() != 0 
+                && static_cast<mapped_value const &>(rhs).data_.get() != 0 
+                && (data_.get()) == static_cast<mapped_value const 
&>(rhs).data_.get();
+        }
+        
+        size_t hash() const {
+            return size_t(data_.get());
+        }
+    protected:
+        ref_ptr<map_type> data_;
+    };
+ 
+    typedef mapped_value<ref_ptr<string_value> > object_value;
+    typedef mapped_value<value_ptr> map_value;
+
+
+    bool consume(uint8_t const *& b, uint8_t const * e, value_ptr & target) {
+        bool result = b < e;
+        if(result) {
+            switch(*b) {
+            case kDataType_Binary:
+                {
+                    ref_ptr<binary_value> starget;
+                    result = binary_value::consume(b, e, starget);
+                    if(result) {
+                        target = starget;
+                    }
+                }                
+                break;
+            case kDataType_Byte:
+                {
+                    ref_ptr<byte_value> starget;
+                    result = byte_value::consume(b, e, starget);
+                    if(result) {
+                        target = starget;
+                    }
+                }                
+                break;
+            case kDataType_DateTime:
+                {
+                    ref_ptr<datetime_value> starget;
+                    result = datetime_value::consume(b, e, starget);
+                    if(result) {
+                        target = starget;
+                    }
+                }                
+                break;
+            case kDataType_Double:
+                {
+                    ref_ptr<double_value> starget;
+                    result = double_value::consume(b, e, starget);
+                    if(result) {
+                        target = starget;
+                    }
+                }                
+                break;
+            case kDataType_Int32:
+                {
+                    ref_ptr<int32_value> starget;
+                    result = int32_value::consume(b, e, starget);
+                    if(result) {
+                        target = starget;
+                    }
+                }                
+                break;
+            case kDataType_Int64:
+                {
+                    ref_ptr<int64_value> starget;
+                    result = int64_value::consume(b, e, starget);
+                    if(result) {
+                        target = starget;
+                    }
+                }                
+                break;
+            case kDataType_List:
+                {
+                    ref_ptr<list_value> starget;
+                    result = list_value::consume(b, e, starget);
+                    if(result) {
+                        target = starget;
+                    }
+                }                
+                break;
+            case kDataType_Map:
+                {
+                    ref_ptr<map_value> starget;
+                    result = map_value::consume(b, e, starget);
+                    if(result) {
+                        target = starget;
+                    }
+                }                
+                break;
+            case kDataType_Null:
+                {
+                    ref_ptr<null_value> starget;
+                    result = null_value::consume(b, e, starget);
+                    if(result) {
+                        target = starget;
+                    }
+                }                
+                break;
+            case kDataType_Object:
+                {
+                    ref_ptr<object_value> starget;
+                    result = object_value::consume(b, e, starget);
+                    if(result) {
+                        target = starget;
+                    }
+                }                
+                break;
+            case kDataType_String:
+                {
+                    ref_ptr<string_value> starget;
+                    result = string_value::consume(b, e, starget);
+                    if(result) {
+                        target = starget;
+                    }
+                }                
+                break;
+            }
+        }
+        return false;
+    }
+}
+
diff --git a/tray/win32/ovirt-tray/pipeserver/critical_section.h 
b/tray/win32/ovirt-tray/pipeserver/critical_section.h
new file mode 100644
index 0000000..c5a5d6e
--- /dev/null
+++ b/tray/win32/ovirt-tray/pipeserver/critical_section.h
@@ -0,0 +1,48 @@
+#pragma once
+
+#include <windows.h>
+
+struct CriticalSection : CRITICAL_SECTION {
+    class Lock {
+        CriticalSection * cs_;
+    public:
+        Lock(CriticalSection & cs)
+            : cs_(&cs)
+        {
+            cs_->Accquire();
+        }
+
+        ~Lock() {
+            Release();
+        }
+
+        void Release() {
+            if (cs_) {
+                cs_->Release();
+            }
+            cs_ = 0;
+        }
+    };
+
+    CriticalSection()
+        : CRITICAL_SECTION()
+    {
+        ::InitializeCriticalSection(this);
+    }
+
+    ~CriticalSection() {
+        ::DeleteCriticalSection(this);
+    }
+
+    bool TryAccquire() {
+        return ::TryEnterCriticalSection(this) == TRUE;
+    }
+
+    void Accquire() {
+        ::EnterCriticalSection(this);
+    }
+
+    void Release() {
+        ::LeaveCriticalSection(this);
+    }
+};
diff --git a/tray/win32/ovirt-tray/pipeserver/dllmain.cpp 
b/tray/win32/ovirt-tray/pipeserver/dllmain.cpp
new file mode 100644
index 0000000..69b5891
--- /dev/null
+++ b/tray/win32/ovirt-tray/pipeserver/dllmain.cpp
@@ -0,0 +1,19 @@
+// dllmain.cpp : Defines the entry point for the DLL application.
+#include "stdafx.h"
+
+BOOL APIENTRY DllMain( HMODULE hModule,
+                       DWORD  ul_reason_for_call,
+                       LPVOID lpReserved
+                                        )
+{
+       switch (ul_reason_for_call)
+       {
+       case DLL_PROCESS_ATTACH:
+       case DLL_THREAD_ATTACH:
+       case DLL_THREAD_DETACH:
+       case DLL_PROCESS_DETACH:
+               break;
+       }
+       return TRUE;
+}
+
diff --git a/tray/win32/ovirt-tray/pipeserver/function_storage.h 
b/tray/win32/ovirt-tray/pipeserver/function_storage.h
new file mode 100644
index 0000000..912b44e
--- /dev/null
+++ b/tray/win32/ovirt-tray/pipeserver/function_storage.h
@@ -0,0 +1,42 @@
+#pragma once
+
+
+struct FunctionStorage {
+    struct X {};
+    union {
+        struct {
+            void * Object;
+            int (X::*Method)();
+        } MPtr;
+        int(*FunPtr) ();
+        char Static[32];
+        void * Dynamic;
+    } Data;
+};
+
+
+inline FunctionStorage MakeStorage(void(*f)()) {
+    FunctionStorage s;
+    s.Data.FunPtr = reinterpret_cast<int(*)()>(f);
+    return s;
+}
+
+template< typename F >
+inline FunctionStorage MakeStorage(F f) {
+    FunctionStorage s;
+    if (sizeof(f) <= sizeof(s.Data.Static)) {
+        new (&s.Data.Static) F(f);
+    }
+    else {
+        s.Data.Dynamic = new F(f);
+    }
+    return s;
+}
+
+template< typename ClassT, typename MethodT >
+inline FunctionStorage MakeStorage(ClassT * o, MethodT m) {
+    FunctionStorage s;
+    s.Data.MPtr.Object = o;
+    s.Data.MPtr.Method = reinterpret_cast<int(FunctionStorage::X::*)()>(m);
+    return s;
+}
diff --git a/tray/win32/ovirt-tray/pipeserver/handle.h 
b/tray/win32/ovirt-tray/pipeserver/handle.h
new file mode 100644
index 0000000..6f94115
--- /dev/null
+++ b/tray/win32/ovirt-tray/pipeserver/handle.h
@@ -0,0 +1,53 @@
+#pragma once
+
+#include <windows.h>
+#include <algorithm>
+
+struct Handle {
+
+    Handle(HANDLE h = INVALID_HANDLE_VALUE, bool auto_close = false)
+    : handle_(h)
+    , auto_close_(auto_close)
+    {}
+
+    ~Handle() {
+        if (auto_close_) {
+            Close();
+        }
+    }
+
+    void Close() {
+        if (IsValid()) {
+            ::CloseHandle(handle_);
+            handle_ = 0;
+        }
+    }
+
+    bool IsValid() const {
+        return handle_ != INVALID_HANDLE_VALUE
+            && handle_ != 0;
+    }
+
+    operator bool() const {
+        return IsValid();
+    }
+
+    operator HANDLE() const {
+        return handle_;
+    }
+
+    void Swap(Handle & other) {
+        std::swap(other.auto_close_, auto_close_);
+        std::swap(other.handle_, handle_);
+    }
+
+protected:
+    bool auto_close_;
+    HANDLE handle_;
+};
+
+struct AutoHandle : Handle {
+    AutoHandle(HANDLE h)
+    : Handle(h, true)
+    {}
+};
diff --git a/tray/win32/ovirt-tray/pipeserver/handler_functions.h 
b/tray/win32/ovirt-tray/pipeserver/handler_functions.h
new file mode 100644
index 0000000..0e0b76e
--- /dev/null
+++ b/tray/win32/ovirt-tray/pipeserver/handler_functions.h
@@ -0,0 +1,87 @@
+#pragma once
+
+#include "handler_impl.h"
+
+struct IOHandler {
+    IOHandler()
+    : storage_()
+    , handler_(0)
+    {}
+
+    IOHandler(IOHandler const & other)
+    : storage_(other ? other.handler_().Clone(other.storage_) : 
FunctionStorage())
+    , handler_(other.handler_)
+    {}
+
+    template< typename F >
+    IOHandler(F f)
+    : storage_(MakeStorage(f))
+    , handler_(MakeHandlerFun<HandlerT>::Get(f))
+    {}
+
+    template< typename ClassT, typename MethodT >
+    IOHandler(ClassT * o, MethodT * m)
+    : storage_(MakeStorage(o, m))
+    , handler_(MakeHandlerFun<HandlerT>::Get(o, m))
+    {}
+
+    ~IOHandler() {
+        if (handler_) {
+            handler_().Release(storage_);
+        }
+    }
+
+    operator bool() const {
+        return handler_ != 0;
+    }
+
+    void operator()(DWORD err, DWORD trans){
+        handler_().Call(storage_, err, trans);
+    }
+protected:
+    typedef FunctionHandlers<void(*)(FunctionStorage&, DWORD, DWORD)> HandlerT;
+    FunctionStorage storage_;
+    HandlerT (*handler_)();
+};
+
+struct CompletionHandler {
+    CompletionHandler()
+    : storage_()
+    , handler_(0)
+    {}
+
+    CompletionHandler(CompletionHandler const & other)
+        : storage_(other ? other.handler_().Clone(other.storage_) : 
FunctionStorage())
+        , handler_(other.handler_)
+    {}
+
+    template< typename F >
+    CompletionHandler(F f)
+        : storage_(MakeStorage(f))
+        , handler_(MakeHandlerFun<HandlerT>::Get(f))
+    {}
+
+    template< typename ClassT, typename MethodT >
+    CompletionHandler(ClassT * o, MethodT m)
+        : storage_(MakeStorage(o, m))
+        , handler_(MakeHandlerFun<HandlerT>::Get(o, m))
+    {}
+
+    ~CompletionHandler() {
+        if (handler_) {
+            handler_().Release(storage_);
+        }
+    }
+
+    operator bool() const {
+        return handler_ != 0;
+    }
+
+    void operator()(){
+        handler_().Call(storage_);
+    }
+protected:
+    typedef FunctionHandlers<void(*)(FunctionStorage&)> HandlerT;
+    FunctionStorage storage_;
+    HandlerT(*handler_)();
+};
\ No newline at end of file
diff --git a/tray/win32/ovirt-tray/pipeserver/handler_impl.h 
b/tray/win32/ovirt-tray/pipeserver/handler_impl.h
new file mode 100644
index 0000000..dd4a900
--- /dev/null
+++ b/tray/win32/ovirt-tray/pipeserver/handler_impl.h
@@ -0,0 +1,140 @@
+#pragma once
+
+#include "function_storage.h"
+
+template< typename CallSignature >
+struct FunctionHandlers {
+    typedef CallSignature CallSignatureType;
+
+    CallSignature Call;
+    void(*Release)(FunctionStorage &);
+    FunctionStorage(*Clone)(FunctionStorage const &);
+};
+
+template< typename T >
+struct GenFun {
+    typedef T(*Type)();
+};
+
+FunctionStorage SimpleClone(FunctionStorage const & s) {
+    return s;
+}
+
+template< typename T >
+FunctionStorage FunctorClone(FunctionStorage const & s) {
+    FunctionStorage tmp = {};
+    if (sizeof(T) <= sizeof(s.Data.Static)) {
+        new (tmp.Data.Static) T(*reinterpret_cast<T const*>(s.Data.Static));
+    }
+    else {
+        tmp.Data.Dynamic = new(std::nothrow) T(*reinterpret_cast<T 
const*>(s.Data.Dynamic));
+    }
+    return tmp;
+}
+
+void SimpleRelease(FunctionStorage&){}
+
+template< typename T >
+void FunctorRelease(FunctionStorage & s) {
+    if (sizeof(T) <= sizeof(s.Data.Static)) {
+        reinterpret_cast<T*>(s.Data.Static)->~T();
+    }
+    else {
+        delete reinterpret_cast<T*>(s.Data.Dynamic);
+    }
+}
+
+template< typename SignatureT >
+struct CallerImpl;
+
+template< typename HandlerT >
+HandlerT FunctionHandler() {
+    static HandlerT tmp = {
+        &CallerImpl<typename HandlerT::CallSignatureType>::Function,
+        &SimpleRelease,
+        &SimpleClone
+    };
+    return tmp;
+};
+
+template< typename HandlerT, typename FunctorT >
+HandlerT FunctorHandler() {
+    static HandlerT tmp = {
+        &CallerImpl<typename HandlerT::CallSignatureType>::Functor<FunctorT>,
+        &FunctorRelease<FunctorT>,
+        &FunctorClone<FunctorT>
+    };
+    return tmp;
+};
+
+template< typename HandlerT, typename ClassT, typename MethodT >
+HandlerT MethodHandler() {
+    static HandlerT tmp = {
+        &CallerImpl<typename HandlerT::CallSignatureType>::Method<ClassT, 
MethodT>,
+        &SimpleRelease,
+        &SimpleClone
+    };
+    return tmp;
+};
+
+template< typename HandlerT >
+struct MakeHandlerFun {
+    template< typename ClassT, typename MethodT >
+    static typename GenFun<HandlerT>::Type Get(ClassT * o, MethodT m)
+    {
+        // Method
+        return MethodHandler<HandlerT, ClassT, MethodT>;
+    }
+
+    static typename GenFun<HandlerT>::Type Get(typename 
HandlerT::CallSignatureType f) {
+        // Function
+        return FunctionHandler<HandlerT>;
+    }
+
+    template< typename F >
+    static typename GenFun<HandlerT>::Type Get(F f)
+    {
+        // Functor
+        return FunctorHandler<HandlerT, F>;
+    }
+};
+
+template<>
+struct CallerImpl<void(*)(FunctionStorage&, DWORD, DWORD)> {
+    static void Function(FunctionStorage&s, DWORD e, DWORD t) {
+        reinterpret_cast<void(*)(DWORD, DWORD)>(s.Data.FunPtr)(e, t);
+    }
+    template< typename C, typename M>
+    static void Method(FunctionStorage&s, DWORD e, DWORD t) {
+        
((*reinterpret_cast<C*>(s.Data.MPtr.Object)).*reinterpret_cast<M>(s.Data.MPtr.Method))(e,
 t);
+    }
+    template< typename C >
+    static void Functor(FunctionStorage&s, DWORD e, DWORD t) {
+        if (sizeof(C) <= sizeof(s.Data.Static)) {
+            (*reinterpret_cast<C*>(s.Data.Static))(e, t);
+        }
+        else {
+            (*reinterpret_cast<C*>(s.Data.Dynamic))(e, t);
+        }
+    }
+};
+
+template<>
+struct CallerImpl<void(*)(FunctionStorage&)> {
+    static void Function(FunctionStorage&s) {
+        reinterpret_cast<void(*)()>(s.Data.FunPtr)();
+    }
+    template< typename C, typename M>
+    static void Method(FunctionStorage&s) {
+        
((*reinterpret_cast<C*>(s.Data.MPtr.Object)).*reinterpret_cast<M>(s.Data.MPtr.Method))();
+    }
+    template< typename C >
+    static void Functor(FunctionStorage&s) {
+        if (sizeof(C) <= sizeof(s.Data.Static)) {
+            (*reinterpret_cast<C*>(s.Data.Static))();
+        }
+        else {
+            (*reinterpret_cast<C*>(s.Data.Dynamic))();
+        }
+    }
+};
diff --git a/tray/win32/ovirt-tray/pipeserver/iofunoverlapped.h 
b/tray/win32/ovirt-tray/pipeserver/iofunoverlapped.h
new file mode 100644
index 0000000..34a7c42
--- /dev/null
+++ b/tray/win32/ovirt-tray/pipeserver/iofunoverlapped.h
@@ -0,0 +1,49 @@
+#pragma once
+
+#include "critical_section.h"
+#include "handler_functions.h"
+#include "handle.h"
+
+struct IOFunOverlapped : OVERLAPPED {
+    int       References;
+    IOHandler Callable;
+    bool      Called;
+    CriticalSection Sync;
+
+    IOFunOverlapped(IOHandler callable)
+        : OVERLAPPED()
+        , References(1)
+        , Callable(callable)
+        , Called(false)
+        , Sync()
+    {
+        hEvent = CreateEvent(0, TRUE, FALSE, 0);        
+    }
+
+    ~IOFunOverlapped() {        
+        ::CloseHandle(hEvent);
+    }
+    
+    void AddRef() {
+        CriticalSection::Lock lock(Sync);
+        References += 1;
+    }
+    
+    void Release() {
+        bool del = false;
+        {
+            CriticalSection::Lock lock(Sync);
+            References -= 1;
+            del = References < 1;
+        }
+        if(del) delete this;
+    }
+
+    void Perform(DWORD error, DWORD trans) {
+        CriticalSection::Lock lock(Sync);
+        if (!Called && Callable) {
+            Called = true;
+            Callable(error, trans);
+        }
+    }
+};
diff --git a/tray/win32/ovirt-tray/pipeserver/message.h 
b/tray/win32/ovirt-tray/pipeserver/message.h
new file mode 100644
index 0000000..8a22df5
--- /dev/null
+++ b/tray/win32/ovirt-tray/pipeserver/message.h
@@ -0,0 +1,18 @@
+#pragma once
+
+struct MessageEntry {
+    UINT32 Length;
+    char const * Value;
+};
+
+struct MessageField {
+    MessageEntry Key;
+    MessageEntry Value;
+};
+
+struct Message {
+    UINT32 BodySize;
+    UINT32 FieldCount;
+    MessageField * Fields;
+};
+
diff --git a/tray/win32/ovirt-tray/pipeserver/named_pipe.h 
b/tray/win32/ovirt-tray/pipeserver/named_pipe.h
new file mode 100644
index 0000000..0afa98c
--- /dev/null
+++ b/tray/win32/ovirt-tray/pipeserver/named_pipe.h
@@ -0,0 +1,134 @@
+#pragma once
+
+#include <string>
+#include "stream_service.h"
+
+
+
+struct NamedPipeService : StreamService {
+    NamedPipeService(Service & service)
+    : StreamService(service)
+    {}
+
+    void Close(Handle & h) {
+        ::DisconnectNamedPipe(h);
+        StreamService::Close(h);
+    }
+
+    DWORD Open(Handle & h, TCHAR const * path) {
+        DWORD result = StreamService::Open(h, path);
+        if (result == NO_ERROR) {
+            DWORD mode = PIPE_READMODE_BYTE;
+            if (!::SetNamedPipeHandleState(h, &mode, NULL, NULL)) {
+                result = GetLastError();
+                Close(h);
+            }
+        }
+        return result;
+    }
+};
+
+typedef BasicStream<NamedPipeService> NamedPipeStream;
+
+struct NamedPipeAcceptor;
+struct NamedPipeAcceptor {
+    NamedPipeAcceptor(Service & service)
+    : service_(service)
+    , buffer_size_(0x10000)
+    , name_()
+    , attributes_(0)
+    , stream_(service)
+    {}
+
+    ~NamedPipeAcceptor() {
+        Close();
+    }
+
+    DWORD Open(std::basic_string<TCHAR> const & name, LPSECURITY_ATTRIBUTES 
attributes = 0) {
+        Close();
+        name_ = TEXT("\\\\.\\pipe\\") + name;
+        attributes_ = attributes;
+        return Create(stream_);
+    }
+
+    bool IsOpen() const {
+        return !name_.empty();
+    }
+
+    void Close() {
+        name_.clear();
+        stream_.Close();
+        attributes_ = 0;
+    }
+
+    DWORD AsyncAccept(NamedPipeStream & stream, IOHandler handler) {
+        DWORD result = NO_ERROR;
+        IOFunOverlapped * overlapped = new IOFunOverlapped(handler);
+        
+        if (!stream_.IsOpen()) {
+            result = Create(stream_);
+        }
+        if (!result) {
+            stream.Swap(stream_);
+            overlapped->AddRef();
+            BOOL connected = ::ConnectNamedPipe(stream.Native(), overlapped);
+            if (!connected) {
+                result = GetLastError();
+                switch (result)
+                {
+                case ERROR_PIPE_CONNECTED:
+                    overlapped->AddRef();
+                    service_.PostCompletionStatus(NO_ERROR, 0, overlapped);
+                    result = NO_ERROR;
+                    break;                    
+                case ERROR_IO_PENDING:                    
+                    result = NO_ERROR;
+                    break;
+                default:
+                    ::FlushFileBuffers(stream.Native());
+                    ::DisconnectNamedPipe(stream.Native());                    
+                case ERROR_NO_DATA:
+                    if (stream.Native()) {
+                        stream.Close();
+                    }
+                    service_.PostCompletionStatus(result, 0, overlapped);
+                    break;
+                }
+            }
+        }
+        overlapped->Release();
+        return result;
+    }
+protected:
+    DWORD Create(NamedPipeStream & stream) {
+        Handle h = ::CreateNamedPipe(
+            name_.c_str(),
+            PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
+            PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
+            PIPE_UNLIMITED_INSTANCES,
+            buffer_size_,
+            buffer_size_,
+            NMPWAIT_USE_DEFAULT_WAIT,
+            attributes_
+        );
+        if (!h) {
+            return GetLastError();
+        }
+        if (!service_.Register(h)) {
+            h.Close();
+            return GetLastError();
+        }
+        stream.Assign(h);
+        return ERROR_SUCCESS;
+    }
+private:
+    NamedPipeAcceptor(NamedPipeAcceptor const &);
+    NamedPipeAcceptor & operator=(NamedPipeAcceptor const &);
+protected:
+    Service & service_;
+    DWORD buffer_size_;
+    std::basic_string<TCHAR> name_;
+    LPSECURITY_ATTRIBUTES attributes_;
+    NamedPipeStream stream_;
+};
+
diff --git a/tray/win32/ovirt-tray/pipeserver/pipeserver.cpp 
b/tray/win32/ovirt-tray/pipeserver/pipeserver.cpp
new file mode 100644
index 0000000..8cdff4f
--- /dev/null
+++ b/tray/win32/ovirt-tray/pipeserver/pipeserver.cpp
@@ -0,0 +1,393 @@
+// pipeserver.cpp : Defines the exported functions for the DLL application.
+//
+
+#include "stdafx.h"
+#include "pipeserver.h"
+#include "named_pipe.h"
+#include "message.h"
+#include "bson.h"
+
+struct ClientSendHandler {
+    PipeConnection * connection;
+    std::vector<BYTE> * message;
+    void * userData;
+    OnMessageCompleted onCompletion;
+    ClientSendHandler(PipeConnection * connection, Message * message, void * 
userData, OnMessageCompleted onCompletion)
+    : connection(connection)
+    , message(new (std::nothrow) std::vector<BYTE>())
+    , userData(userData)
+    , onCompletion(onCompletion)        
+    {
+        ConvertToBuffer(message);
+    }
+private:
+    void AppendEntry(MessageEntry & entry) {
+        size_t idx = message->size();
+        message->insert(message->end(), 4, 0);        
+        *reinterpret_cast<UINT32*>(&(*message)[idx]) = entry.Length;
+        message->insert(message->end(), entry.Value, entry.Value + 
entry.Length);
+    }
+    
+    void AppendField(MessageField & field) {
+        AppendEntry(field.Key);
+        AppendEntry(field.Value);
+    }
+    
+    void ConvertToBuffer(Message * m) {
+        message->resize(sizeof(UINT32)* 2, 0);        
+        for(UINT32 i = 0; i < m->FieldCount; ++i) {
+            AppendField(m->Fields[i]);
+        }
+        UINT32 * hdr = reinterpret_cast<UINT32*>(&(*message)[0]);
+        hdr[0] = UINT32(message->size() - (sizeof(UINT32) * 2));
+        hdr[1] = m->FieldCount;
+    }
+public:    
+    BYTE const * buffer() const {
+        if(bufferLength() == 0) {
+            return 0;
+        }
+        return reinterpret_cast<BYTE const *>(&(*message)[0]);
+    }
+    
+    DWORD bufferLength() const {
+        if(!message) {
+            return 0;
+        }
+        return DWORD(message->size());
+    }
+    
+    void operator()(DWORD err, DWORD trans) {
+        delete message;
+        message = 0;
+        if(onCompletion) {
+            onCompletion(connection, trans, HRESULT_FROM_WIN32(err), userData);
+        }
+    }
+};
+
+struct AcceptResultHandler {
+    PipeServer * server;
+    PipeConnection * connection;
+    AcceptResultHandler(PipeServer *, PipeConnection *);
+    
+    void operator()(DWORD err, DWORD trans);
+};
+
+
+struct PipeConnection {
+    NamedPipeStream conn;
+    PipeServer * server;
+    
+    PipeConnection(PipeServer * server);
+    ~PipeConnection(){
+        Close();
+    }   
+    void Close();
+};
+
+struct PipeServer {
+    bool started;
+    Service service;
+    NamedPipeAcceptor acceptor;
+    SECURITY_ATTRIBUTES securityAttributes;
+    void * userData;
+    OnConnected onConnected;
+    OnError onError;
+    OnClientMessage onClientMessage;
+    OnClientError onClientError;
+
+    PipeServer(bool);
+    ~PipeServer();
+    void AcceptNext();
+    void Start(TCHAR const * name);
+    void Stop();
+    void ScheduleRead(PipeConnection * connection);
+};
+
+struct ClientMessageReadHandler {
+    PipeConnection * connection;
+    PipeServer * server;
+    Message * message;
+    char * buffer;
+    enum {
+        MSGSTATE_HEADER,
+        MSGSTATE_BODY,
+        MSGSTATE_DONE
+    } state;
+
+    ClientMessageReadHandler(ClientMessageReadHandler const & other)
+    : connection(other.connection)
+    , server(other.server)
+    , message(other.message)
+    , buffer(other.buffer)
+    , state(other.state)
+    {}
+    
+    ClientMessageReadHandler & operator=(ClientMessageReadHandler o) {
+        connection = o.connection;
+        server = o.server;
+        message = o.message;
+        buffer = o.buffer;
+        state = o.state;
+        return *this;
+    }
+
+    ClientMessageReadHandler(PipeServer * server, PipeConnection * connection)
+    : server(server)
+    , connection(connection)
+    , message(new (std::nothrow) Message())
+    , state(MSGSTATE_HEADER)
+    {
+        detail::map_value foo_map;
+        detail::list_value foo_list;
+        detail::binary_view foo_bin;
+        detail::string_view foo_str;
+        detail::int32_value foo_int32;
+        detail::int64_value foo_int64;
+        detail::byte_value  foo_byte;
+        DWORD result = 
connection->conn.AsyncRead(reinterpret_cast<BYTE*>(message), sizeof(UINT32) * 
2, *this);
+        if(result != NO_ERROR) {
+            server->onClientError(connection, result, server->userData);
+        }
+    }    
+
+    void operator()(DWORD err, DWORD bytes) {
+        if(state == MSGSTATE_HEADER) {
+            OnHeaderReceived(err, bytes);
+        }
+        else if(state == MSGSTATE_BODY) {
+            OnBodyReceived(err, bytes);
+        }        
+    }    
+
+    bool ReadSize(char const *& buffer, UINT32 & bytesLeft, UINT32 & target) {
+        if(bytesLeft < sizeof(UINT32)) {
+            return false;
+        }
+        bytesLeft -= sizeof(UINT32);
+        target = *reinterpret_cast<UINT32 const*>(buffer);
+        buffer += sizeof(UINT32);
+        return true;
+    } 
+    
+    bool ReadString(char const *& buffer, UINT32 length, UINT32 & bytesLeft, 
char const *& target, std::vector<std::string> & store) {
+        if(bytesLeft < length) {
+            return false;
+        }
+        bytesLeft -= length;
+        store.push_back(std::string(buffer, buffer + length));
+        buffer += length;
+        target = store.back().c_str();
+        return true;
+    }
+    
+    bool ReadEntry(char const *& buffer, UINT32 & bytesLeft, MessageEntry & 
entry, std::vector<std::string> & store) {
+        if(ReadSize(buffer, bytesLeft, entry.Length)) {
+            if(ReadString(buffer, entry.Length, bytesLeft, entry.Value, 
store)) {
+                return true;
+            }
+        }       
+        return false; 
+    }
+
+    void OnBodyReceived(DWORD err, DWORD bytes) {
+        if(err != NO_ERROR) {
+            if(server->onClientError) {
+                server->onClientError(connection, err, server->userData);
+            }
+        }
+        else if(bytes != message->BodySize) {
+            // We're still missing data, reschedule read
+        }
+        else {
+            state = MSGSTATE_DONE;
+            buffer[message->BodySize-1] = 0; // Enforce 0 termination
+            
+            std::vector<MessageField> fieldStore(message->FieldCount);
+            std::vector<std::string> stringStore;
+            stringStore.reserve(message->FieldCount * 2);
+            char const * ptr = buffer;
+            UINT32 bytesLeft = bytes;
+            for(size_t i = 0; i < fieldStore.size(); ++i) {                
+                if(!ReadEntry(ptr, bytesLeft, fieldStore[i].Key, stringStore)) 
{
+                    break;
+                }
+                if(!ReadEntry(ptr, bytesLeft, fieldStore[i].Value, 
stringStore)) {
+                    break;
+                }
+            }            
+            message->Fields = &fieldStore[0];
+            server->onClientMessage(connection, message, server->userData);
+            server->ScheduleRead(connection);
+        }
+        delete[] buffer;
+        delete message;
+    }
+
+    void OnHeaderReceived(DWORD err, DWORD bytes) {
+        if(err != NO_ERROR) {
+            // handle error
+            if(server->onClientError) {
+                server->onClientError(connection, err, server->userData);
+            }
+        }
+        else if(bytes != (sizeof(UINT32) * 2)) {
+            // We're still missing data, reschedule read
+        }
+        else {
+            buffer = new (std::nothrow) char[message->BodySize]();
+            state = MSGSTATE_BODY;
+            connection->conn.AsyncRead(reinterpret_cast<BYTE*>(buffer), 
message->BodySize, *this);
+        }
+    }
+};
+
+AcceptResultHandler::AcceptResultHandler(PipeServer * server, PipeConnection * 
connection)
+: server(server)
+, connection(connection)
+{}
+
+void AcceptResultHandler::operator ()(DWORD err, DWORD trans)
+{
+    if(err != 0) {
+        if(server->onError) {
+            server->onError(server, HRESULT_FROM_WIN32(err), server->userData);
+        }
+    }
+    else {
+        ULONG pid = 0;
+        ::GetNamedPipeClientProcessId(connection->conn.Native(), &pid);
+        server->onConnected(server, connection, pid, server->userData);
+        server->ScheduleRead(connection);
+    }
+    server->AcceptNext();
+}
+
+PipeServer::PipeServer(bool start)
+: started(start)
+, service()
+, acceptor(service)
+, securityAttributes()
+{
+}
+
+PipeServer::~PipeServer() {
+    Stop();
+    service.Stop();
+}
+
+void PipeServer::AcceptNext() {
+    PipeConnection * client = new PipeConnection(this);
+    HRESULT result = S_OK;
+    if(FAILED(result = HRESULT_FROM_WIN32(acceptor.AsyncAccept(client->conn, 
AcceptResultHandler(this, client))))) {
+        if(onError) {
+            onError(this, result, userData);
+        }
+    }
+}
+
+void PipeServer::Start(TCHAR const * name) {
+    InitializeSecurityAttribute(&securityAttributes);
+    HRESULT result = S_OK;
+    if(FAILED(result = HRESULT_FROM_WIN32(acceptor.Open(name, 
&securityAttributes)))) {
+        if(onError) {
+            onError(this, result, userData);
+        }
+    }
+    else {
+        this->AcceptNext();
+    }
+    if(started) service.Start();
+    else service.Run();
+}    
+
+void PipeServer::Stop() {
+    service.Stop();    
+    acceptor.Close();
+}
+
+void PipeServer::ScheduleRead(PipeConnection * connection) {
+    ClientMessageReadHandler(this, connection);
+}
+
+PipeConnection::PipeConnection(PipeServer * server)
+: conn(server->service)
+, server(server)
+{}    
+
+void PipeConnection::Close(){
+    conn.Close();
+}
+
+
+extern "C" {
+    PipeServer * PipeServer_NewWithThread(
+                        void * userData,
+                        OnConnected onConnected,
+                        OnError onError,
+                        OnClientMessage onClientMessage,
+                        OnClientError onClientError) {
+        
+        PipeServer * self = new (std::nothrow) PipeServer(true);
+        if(self) {
+            self->onClientError = onClientError;
+            self->onClientMessage = onClientMessage;
+            self->onConnected = onConnected;
+            self->onError = onError;
+            self->userData = userData;
+        }
+        return self;
+    }
+
+    PipeServer * PipeServer_New(
+                        void * userData,
+                        OnConnected onConnected,
+                        OnError onError,
+                        OnClientMessage onClientMessage,
+                        OnClientError onClientError) {
+
+            PipeServer * self = new (std::nothrow) PipeServer(false);
+            if(self) {
+                self->onClientError = onClientError;
+                self->onClientMessage = onClientMessage;
+                self->onConnected = onConnected;
+                self->onError = onError;
+                self->userData = userData;
+            }
+            return self;
+    }
+
+    void PipeServer_Start(PipeServer * self, TCHAR const * name) {
+        self->Start(name);        
+    }
+
+    void PipeServer_Stop(PipeServer * self) {
+        self->Stop();
+    }
+
+    void PipeServer_Free(PipeServer * self) {
+        delete self;
+    }
+
+       INT32 PipeConnection_Send(
+                        PipeConnection * connection,
+                        Message * message,
+                        void *userData,
+                        OnMessageCompleted onCompletion) {        
+        if(!message) {
+            return ERROR_INVALID_PARAMETER;
+        }
+        ClientSendHandler handler(connection, message, userData, onCompletion);
+        connection->conn.AsyncWrite(handler.buffer(), handler.bufferLength(), 
handler);
+        return 0;
+    }
+    
+    void PipeConnection_Close(PipeConnection * self) {
+        self->Close();
+    }
+
+    void PipeConnection_Free(PipeConnection * self) {
+        delete self;
+    }
+};
diff --git a/tray/win32/ovirt-tray/pipeserver/pipeserver.h 
b/tray/win32/ovirt-tray/pipeserver/pipeserver.h
new file mode 100644
index 0000000..f95326d
--- /dev/null
+++ b/tray/win32/ovirt-tray/pipeserver/pipeserver.h
@@ -0,0 +1,54 @@
+#include <windows.h>
+#include <Sddl.h>
+#include <string>
+#include <vector>
+#include <process.h>
+#include "message.h"
+#ifdef PIPESERVER_EXPORTS
+#define PIPESERVER_API __declspec(dllexport)
+#else
+#define PIPESERVER_API __declspec(dllimport)
+#endif
+
+inline void InitializeSecurityAttribute(LPSECURITY_ATTRIBUTES sa) {    
+       sa->nLength = sizeof(*sa);
+       sa->bInheritHandle = FALSE;
+       ConvertStringSecurityDescriptorToSecurityDescriptor(
+               TEXT("S:(ML;;NW;;;LW)D:(A;;0x12019f;;;WD)"), 
+               SDDL_REVISION_1, &sa->lpSecurityDescriptor, 0);
+}
+
+struct PipeServer;
+struct PipeConnection;
+extern "C" {
+       typedef void (*OnConnected)(PipeServer*, PipeConnection *, DWORD, void 
*);
+       typedef void (*OnClientMessage)(PipeConnection *, Message*, void *);
+       typedef void (*OnClientError)(PipeConnection *, INT32, void *);
+       typedef void (*OnError)(PipeServer *, INT32, void *);
+       typedef void (*OnMessageCompleted)(PipeConnection *, UINT32, INT32, 
void *);
+
+    PIPESERVER_API PipeServer * PipeServer_NewWithThread(
+                                    void * userData,
+                                    OnConnected onConnected,
+                                    OnError onError,
+                                    OnClientMessage onClientMessage,
+                                    OnClientError onClientError);
+       PIPESERVER_API PipeServer * PipeServer_New(
+                                       void * userData,
+                                       OnConnected onConnected,
+                                       OnError onError,
+                                       OnClientMessage onClientMessage,
+                                       OnClientError onClientError);
+    PIPESERVER_API void PipeServer_Start(PipeServer *, TCHAR const * name);
+       PIPESERVER_API void PipeServer_Stop(PipeServer *);
+       PIPESERVER_API void PipeServer_Free(PipeServer *);
+       
+       PIPESERVER_API INT32 PipeConnection_Send(
+                             PipeConnection * connection,
+                                            Message * message,
+                                            void *userData,
+                                            OnMessageCompleted onCompletion);
+
+       PIPESERVER_API void PipeConnection_Close(PipeConnection *);
+       PIPESERVER_API void PipeConnection_Free(PipeConnection *);
+};
\ No newline at end of file
diff --git a/tray/win32/ovirt-tray/pipeserver/pipeserver.vcproj 
b/tray/win32/ovirt-tray/pipeserver/pipeserver.vcproj
new file mode 100644
index 0000000..44ae4aa
--- /dev/null
+++ b/tray/win32/ovirt-tray/pipeserver/pipeserver.vcproj
@@ -0,0 +1,487 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+       ProjectType="Visual C++"
+       Version="9.00"
+       Name="pipeserver"
+       ProjectGUID="{A87356ED-7C0B-42CA-9327-E7CDE9C4E481}"
+       RootNamespace="pipeserver"
+       Keyword="Win32Proj"
+       TargetFrameworkVersion="196613"
+       >
+       <Platforms>
+               <Platform
+                       Name="Win32"
+               />
+               <Platform
+                       Name="x64"
+               />
+       </Platforms>
+       <ToolFiles>
+       </ToolFiles>
+       <Configurations>
+               <Configuration
+                       Name="Debug|Win32"
+                       OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+                       IntermediateDirectory="$(ConfigurationName)"
+                       ConfigurationType="2"
+                       CharacterSet="1"
+                       >
+                       <Tool
+                               Name="VCPreBuildEventTool"
+                       />
+                       <Tool
+                               Name="VCCustomBuildTool"
+                       />
+                       <Tool
+                               Name="VCXMLDataGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCWebServiceProxyGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCMIDLTool"
+                       />
+                       <Tool
+                               Name="VCCLCompilerTool"
+                               Optimization="0"
+                               
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;PIPESERVER_EXPORTS"
+                               MinimalRebuild="true"
+                               BasicRuntimeChecks="3"
+                               RuntimeLibrary="3"
+                               UsePrecompiledHeader="2"
+                               WarningLevel="3"
+                               DebugInformationFormat="4"
+                       />
+                       <Tool
+                               Name="VCManagedResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCPreLinkEventTool"
+                       />
+                       <Tool
+                               Name="VCLinkerTool"
+                               LinkIncremental="2"
+                               GenerateDebugInformation="true"
+                               SubSystem="2"
+                               TargetMachine="1"
+                       />
+                       <Tool
+                               Name="VCALinkTool"
+                       />
+                       <Tool
+                               Name="VCManifestTool"
+                       />
+                       <Tool
+                               Name="VCXDCMakeTool"
+                       />
+                       <Tool
+                               Name="VCBscMakeTool"
+                       />
+                       <Tool
+                               Name="VCFxCopTool"
+                       />
+                       <Tool
+                               Name="VCAppVerifierTool"
+                       />
+                       <Tool
+                               Name="VCPostBuildEventTool"
+                       />
+               </Configuration>
+               <Configuration
+                       Name="Release|Win32"
+                       OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+                       IntermediateDirectory="$(ConfigurationName)"
+                       ConfigurationType="2"
+                       CharacterSet="1"
+                       WholeProgramOptimization="1"
+                       >
+                       <Tool
+                               Name="VCPreBuildEventTool"
+                       />
+                       <Tool
+                               Name="VCCustomBuildTool"
+                       />
+                       <Tool
+                               Name="VCXMLDataGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCWebServiceProxyGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCMIDLTool"
+                       />
+                       <Tool
+                               Name="VCCLCompilerTool"
+                               Optimization="2"
+                               EnableIntrinsicFunctions="true"
+                               
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;PIPESERVER_EXPORTS"
+                               RuntimeLibrary="0"
+                               EnableFunctionLevelLinking="true"
+                               UsePrecompiledHeader="2"
+                               WarningLevel="3"
+                               DebugInformationFormat="3"
+                       />
+                       <Tool
+                               Name="VCManagedResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCPreLinkEventTool"
+                       />
+                       <Tool
+                               Name="VCLinkerTool"
+                               LinkIncremental="1"
+                               GenerateDebugInformation="true"
+                               SubSystem="2"
+                               OptimizeReferences="2"
+                               EnableCOMDATFolding="2"
+                               TargetMachine="1"
+                       />
+                       <Tool
+                               Name="VCALinkTool"
+                       />
+                       <Tool
+                               Name="VCManifestTool"
+                       />
+                       <Tool
+                               Name="VCXDCMakeTool"
+                       />
+                       <Tool
+                               Name="VCBscMakeTool"
+                       />
+                       <Tool
+                               Name="VCFxCopTool"
+                       />
+                       <Tool
+                               Name="VCAppVerifierTool"
+                       />
+                       <Tool
+                               Name="VCPostBuildEventTool"
+                       />
+               </Configuration>
+               <Configuration
+                       Name="Debug|x64"
+                       
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
+                       
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+                       ConfigurationType="2"
+                       CharacterSet="1"
+                       >
+                       <Tool
+                               Name="VCPreBuildEventTool"
+                       />
+                       <Tool
+                               Name="VCCustomBuildTool"
+                       />
+                       <Tool
+                               Name="VCXMLDataGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCWebServiceProxyGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCMIDLTool"
+                               TargetEnvironment="3"
+                       />
+                       <Tool
+                               Name="VCCLCompilerTool"
+                               Optimization="0"
+                               
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;PIPESERVER_EXPORTS"
+                               MinimalRebuild="true"
+                               BasicRuntimeChecks="3"
+                               RuntimeLibrary="3"
+                               UsePrecompiledHeader="2"
+                               WarningLevel="3"
+                               DebugInformationFormat="3"
+                       />
+                       <Tool
+                               Name="VCManagedResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCPreLinkEventTool"
+                       />
+                       <Tool
+                               Name="VCLinkerTool"
+                               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="VCPostBuildEventTool"
+                       />
+               </Configuration>
+               <Configuration
+                       Name="Release|x64"
+                       
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
+                       
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+                       ConfigurationType="2"
+                       CharacterSet="1"
+                       WholeProgramOptimization="1"
+                       >
+                       <Tool
+                               Name="VCPreBuildEventTool"
+                       />
+                       <Tool
+                               Name="VCCustomBuildTool"
+                       />
+                       <Tool
+                               Name="VCXMLDataGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCWebServiceProxyGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCMIDLTool"
+                               TargetEnvironment="3"
+                       />
+                       <Tool
+                               Name="VCCLCompilerTool"
+                               Optimization="2"
+                               EnableIntrinsicFunctions="true"
+                               
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;PIPESERVER_EXPORTS"
+                               RuntimeLibrary="0"
+                               EnableFunctionLevelLinking="true"
+                               UsePrecompiledHeader="2"
+                               WarningLevel="3"
+                               DebugInformationFormat="3"
+                       />
+                       <Tool
+                               Name="VCManagedResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCPreLinkEventTool"
+                       />
+                       <Tool
+                               Name="VCLinkerTool"
+                               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="VCPostBuildEventTool"
+                       />
+               </Configuration>
+       </Configurations>
+       <References>
+       </References>
+       <Files>
+               <Filter
+                       Name="Source Files"
+                       Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+                       
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+                       >
+                       <File
+                               RelativePath=".\dllmain.cpp"
+                               >
+                               <FileConfiguration
+                                       Name="Debug|Win32"
+                                       >
+                                       <Tool
+                                               Name="VCCLCompilerTool"
+                                               UsePrecompiledHeader="0"
+                                               CompileAsManaged="0"
+                                       />
+                               </FileConfiguration>
+                               <FileConfiguration
+                                       Name="Release|Win32"
+                                       >
+                                       <Tool
+                                               Name="VCCLCompilerTool"
+                                               UsePrecompiledHeader="0"
+                                               CompileAsManaged="0"
+                                       />
+                               </FileConfiguration>
+                               <FileConfiguration
+                                       Name="Debug|x64"
+                                       >
+                                       <Tool
+                                               Name="VCCLCompilerTool"
+                                               UsePrecompiledHeader="0"
+                                               CompileAsManaged="0"
+                                       />
+                               </FileConfiguration>
+                               <FileConfiguration
+                                       Name="Release|x64"
+                                       >
+                                       <Tool
+                                               Name="VCCLCompilerTool"
+                                               UsePrecompiledHeader="0"
+                                               CompileAsManaged="0"
+                                       />
+                               </FileConfiguration>
+                       </File>
+                       <File
+                               RelativePath=".\pipeserver.cpp"
+                               >
+                       </File>
+                       <File
+                               RelativePath=".\stdafx.cpp"
+                               >
+                               <FileConfiguration
+                                       Name="Debug|Win32"
+                                       >
+                                       <Tool
+                                               Name="VCCLCompilerTool"
+                                               UsePrecompiledHeader="1"
+                                       />
+                               </FileConfiguration>
+                               <FileConfiguration
+                                       Name="Release|Win32"
+                                       >
+                                       <Tool
+                                               Name="VCCLCompilerTool"
+                                               UsePrecompiledHeader="1"
+                                       />
+                               </FileConfiguration>
+                               <FileConfiguration
+                                       Name="Debug|x64"
+                                       >
+                                       <Tool
+                                               Name="VCCLCompilerTool"
+                                               UsePrecompiledHeader="1"
+                                       />
+                               </FileConfiguration>
+                               <FileConfiguration
+                                       Name="Release|x64"
+                                       >
+                                       <Tool
+                                               Name="VCCLCompilerTool"
+                                               UsePrecompiledHeader="1"
+                                       />
+                               </FileConfiguration>
+                       </File>
+               </Filter>
+               <Filter
+                       Name="Header Files"
+                       Filter="h;hpp;hxx;hm;inl;inc;xsd"
+                       
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+                       >
+                       <File
+                               RelativePath=".\bson.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath=".\critical_section.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath=".\function_storage.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath=".\handle.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath=".\handler_functions.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath=".\handler_impl.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath=".\iofunoverlapped.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath=".\message.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath=".\named_pipe.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath=".\pipeserver.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath=".\ref_ptr.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath=".\service.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath=".\stdafx.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath=".\stream_service.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath=".\targetver.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath=".\utilities.h"
+                               >
+                       </File>
+               </Filter>
+               <Filter
+                       Name="Resource Files"
+                       
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+                       
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+                       >
+               </Filter>
+               <File
+                       RelativePath=".\ReadMe.txt"
+                       >
+               </File>
+       </Files>
+       <Globals>
+       </Globals>
+</VisualStudioProject>
diff --git a/tray/win32/ovirt-tray/pipeserver/ref_ptr.h 
b/tray/win32/ovirt-tray/pipeserver/ref_ptr.h
new file mode 100644
index 0000000..be31db7
--- /dev/null
+++ b/tray/win32/ovirt-tray/pipeserver/ref_ptr.h
@@ -0,0 +1,107 @@
+#pragma once
+
+template <class T>
+class ref_ptr {
+public:
+    typedef T type;
+
+    template< typename U >
+    explicit ref_ptr(U * u)
+    : ptr_(u)
+    , refs_(new long(1))
+    {}
+    
+    explicit ref_ptr(T * u)
+    : ptr_(u)
+    , refs_(new long(1))
+    {}
+    
+    ref_ptr()
+    : ptr_()
+    , refs_()
+    {}
+
+    template< typename U >
+    ref_ptr(ref_ptr<U> const & other)
+    : ptr_(other.ptr_)
+    , refs_(other.refs_)
+    {
+        ++*refs_;
+    }
+
+
+    explicit ref_ptr(ref_ptr const & p) throw()
+        : ptr_(p.ptr_)
+        , refs_(p.refs_)
+    {
+        ++*refs_;
+    }
+
+    ~ref_ptr () {
+        release();
+    }
+
+    void swap(ref_ptr & other) {
+        std::swap(other.ptr_, ptr_);
+        std::swap(other.refs_, refs_);
+    }
+
+    ref_ptr & operator= (ref_ptr p) {
+        swap(p);
+        return *this;
+    }
+    
+    ref_ptr & operator=(T * p) {
+        ref_ptr tmp(p);
+        swap(tmp);
+        return *this;
+    }
+    
+    template< typename U >
+    ref_ptr & operator=(U * p) {
+        ref_ptr tmp(p);
+        swap(tmp);
+        return *this;
+    }
+
+    template< typename U >
+    ref_ptr & operator=(ref_ptr<U> const & p) {
+        ref_ptr<T> tmp = p;
+        swap(tmp);
+        return *this;
+    }
+        
+    T * get() const {
+        return ptr_;
+    }
+    
+    template< typename U >
+    U * dynamic_as() const {
+        return dynamic_cast<U*>(get())
+    }
+    
+    template< typename U >
+    U * static_as() const {
+        return static_cast<U*>(get())
+    }
+
+    T& operator*() const {
+        return *get();
+    }
+    T* operator->() const {
+        return get();
+    }
+
+private:
+    void release() {
+        if (--*refs_ == 0) {
+            delete refs_;
+            delete ptr_;
+        }
+    }
+
+protected:
+    T* ptr_;
+    long * refs_;
+
+};
diff --git a/tray/win32/ovirt-tray/pipeserver/service.h 
b/tray/win32/ovirt-tray/pipeserver/service.h
new file mode 100644
index 0000000..76cafbd
--- /dev/null
+++ b/tray/win32/ovirt-tray/pipeserver/service.h
@@ -0,0 +1,110 @@
+#pragma once
+
+#include <windows.h>
+#include <process.h>
+
+#include <vector>
+#include "utilities.h"
+#include "iofunoverlapped.h"
+
+struct CompletionWrapper {
+    CompletionWrapper(CompletionHandler callable)
+    : Callable(callable)
+    {}
+
+    void operator()(DWORD, DWORD) {
+        if(Callable) Callable();
+    }
+
+    CompletionHandler Callable;
+};
+
+enum {
+     OVERLAPPED_CONTAINS_RESULT = 1,
+};
+
+struct Service {
+
+    Service()
+    : port_(::CreateIoCompletionPort(INVALID_HANDLE_VALUE, 0, 0, 0))
+    {
+    }
+
+    ~Service()
+    {
+        Stop();
+    }
+
+    void Start() {
+        threads_.push_back((HANDLE) _beginthread(&Service::Run_, 0, this));
+    }
+
+    void Run() {
+        threads_.push_back(GetCurrentThread());        
+        RunInternal();
+    }
+
+    void Stop() {
+        if (!threads_.empty())  {
+            for (std::size_t i = 0; i < threads_.size(); ++i) {
+                ::PostQueuedCompletionStatus(port_, 0, 0, 0);
+            }
+            ::WaitForMultipleObjects(DWORD(threads_.size()), &threads_[0], 
TRUE, INFINITE);
+            threads_.clear();
+        }
+    }
+
+    DWORD PostCompletionStatus(DWORD err, DWORD trans, OVERLAPPED * 
overlapped) {
+        if (!::PostQueuedCompletionStatus(port_, err, trans, overlapped)) {
+            return GetLastError();
+        }
+        return NO_ERROR;
+    }    
+
+    DWORD Post(CompletionHandler f) {
+        if (::PostQueuedCompletionStatus(port_, 0, 0, new 
IOFunOverlapped(CompletionWrapper(f)))) {
+            return NO_ERROR;
+        }
+        return GetLastError();
+    }
+
+    bool Register(Handle & h) {
+        return ::CreateIoCompletionPort(h, port_, 0, 0) == port_;
+    }
+protected:
+    void RunInternal() {
+        DWORD transferred = 0;
+        ULONG_PTR key = 0;
+        LPOVERLAPPED overlapped = 0;
+        for(;;) {
+            BOOL getResult = ::GetQueuedCompletionStatus(port_, &transferred, 
&key, &overlapped, INFINITE);
+            if (getResult) {
+                if (key == 0 && transferred == 0 && overlapped == 0) {
+                    break;
+                }
+            }
+            if (overlapped) {
+                DWORD last_error = GetLastError();
+                if (!getResult) {
+                    overlapped->Internal = last_error;
+                    overlapped->InternalHigh = transferred;
+                }
+                else {
+                    last_error = NO_ERROR;
+                }
+                
reinterpret_cast<IOFunOverlapped*>(overlapped)->Perform(last_error, 
transferred);
+                reinterpret_cast<IOFunOverlapped*>(overlapped)->Release();
+            }
+        }
+    }
+
+    static void Run_(void * p) {
+        reinterpret_cast<Service*>(p)->RunInternal();
+    }
+private:
+    Service(Service const &);
+    Service & operator=(Service const &);
+private:
+    std::vector<HANDLE> threads_;
+    Handle port_;
+};
\ No newline at end of file
diff --git a/tray/win32/ovirt-tray/pipeserver/stdafx.cpp 
b/tray/win32/ovirt-tray/pipeserver/stdafx.cpp
new file mode 100644
index 0000000..5fcf8f2
--- /dev/null
+++ b/tray/win32/ovirt-tray/pipeserver/stdafx.cpp
@@ -0,0 +1,8 @@
+// stdafx.cpp : source file that includes just the standard includes
+// pipeserver.pch will be the pre-compiled header
+// stdafx.obj will contain the pre-compiled type information
+
+#include "stdafx.h"
+
+// TODO: reference any additional headers you need in STDAFX.H
+// and not in this file
diff --git a/tray/win32/ovirt-tray/pipeserver/stdafx.h 
b/tray/win32/ovirt-tray/pipeserver/stdafx.h
new file mode 100644
index 0000000..f3a0737
--- /dev/null
+++ b/tray/win32/ovirt-tray/pipeserver/stdafx.h
@@ -0,0 +1,16 @@
+// stdafx.h : include file for standard system include files,
+// or project specific include files that are used frequently, but
+// are changed infrequently
+//
+
+#pragma once
+
+#include "targetver.h"
+
+#define WIN32_LEAN_AND_MEAN             // Exclude rarely-used stuff from 
Windows headers
+// Windows Header Files:
+#include <windows.h>
+
+
+
+// TODO: reference additional headers your program requires here
diff --git a/tray/win32/ovirt-tray/pipeserver/stream_service.h 
b/tray/win32/ovirt-tray/pipeserver/stream_service.h
new file mode 100644
index 0000000..7026ce3
--- /dev/null
+++ b/tray/win32/ovirt-tray/pipeserver/stream_service.h
@@ -0,0 +1,136 @@
+#pragma once
+
+#include "service.h"
+#include "iofunoverlapped.h"
+
+
+struct StreamService {
+    StreamService(Service & s)
+    : service_(s)
+    {}
+
+    bool Register(Handle & h) {
+        return service_.Register(h);
+    }
+
+    DWORD Open(Handle & h, TCHAR const * path) {
+        h = ::CreateFile(path, GENERIC_READ | GENERIC_WRITE, 0, 0, 
OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
+        if (!h) {
+            return GetLastError();
+        }
+        if (!service_.Register(h)) {
+            return GetLastError();
+        }
+        return NO_ERROR;
+    }
+
+    void Close(Handle & h) {
+        h.Close();        
+    }
+
+    void Cancel(Handle & h) {
+        ::CancelIoEx(h, 0);
+    }
+
+    DWORD AsyncRead(Handle & h, BYTE * buffer, DWORD buffer_size, IOHandler 
completion) {        
+
+        IOFunOverlapped * trans = new IOFunOverlapped(completion);
+        DWORD transferred = 0;
+        trans->AddRef();
+        if (!::ReadFile(h, buffer, buffer_size, &transferred, trans)) {
+            if (GetLastError() != ERROR_IO_PENDING) {
+                // On an error we have to release both references
+                trans->Release();
+                trans->Release();
+                return GetLastError();
+            }
+        }
+        else {
+            trans->AddRef();
+            service_.PostCompletionStatus(NO_ERROR, transferred, trans);
+        }
+        trans->Release();
+        return ERROR_SUCCESS;
+    }
+
+    DWORD AsyncWrite(Handle & h, BYTE const * buffer, DWORD buffer_size, 
IOHandler completion) {
+        IOFunOverlapped * trans = new IOFunOverlapped(completion);
+        DWORD transferred = 0;
+        trans->AddRef();
+        if (!::WriteFile(h, buffer, buffer_size, &transferred, trans)) {
+            if (GetLastError() != ERROR_IO_PENDING) {
+                // On an error we have to release both references
+                trans->Release();
+                trans->Release();
+                return GetLastError();
+            }
+        }
+        else {
+            trans->AddRef();
+            service_.PostCompletionStatus(NO_ERROR, transferred, trans);
+        }
+        trans->Release();
+        return ERROR_SUCCESS;
+    }    
+
+protected:
+    Service & service_;
+};
+
+template< typename StreamServiceT = StreamService >
+struct BasicStream {
+    BasicStream(Service & s)
+    : handle_(INVALID_HANDLE_VALUE)
+    , service_(s)
+    , stream_service_(s)
+    {}    
+
+    void Swap(BasicStream & other) {
+        std::swap(handle_, other.handle_);
+    }
+
+    DWORD Open(TCHAR const * path) {
+        Close();
+        return stream_service_.Open(Native(), path);
+    }
+
+    void Assign(Handle & h) {
+        Close();
+        handle_ = h;
+    }
+
+    Handle & Native() {
+        return handle_;
+    }
+
+    void Cancel() {
+        stream_service_.Cancel(handle_);
+    }
+
+    void Close() {
+        stream_service_.Close(handle_);
+    }
+
+    bool IsOpen() const {
+        return handle_;
+    }
+
+    Service & GetService() {
+        return service_;
+    }
+
+    DWORD AsyncRead(BYTE * buffer, DWORD buffer_size, IOHandler completion) {
+        return stream_service_.AsyncRead(handle_, buffer, buffer_size, 
completion);
+    }
+
+    DWORD AsyncWrite(BYTE const * buffer, DWORD buffer_size, IOHandler 
completion) {
+        return stream_service_.AsyncWrite(handle_, buffer, buffer_size, 
completion);
+    }
+
+protected:
+    Handle handle_;
+    Service & service_;
+    StreamServiceT stream_service_;
+};
+
+typedef BasicStream<> Stream;
diff --git a/tray/win32/ovirt-tray/pipeserver/targetver.h 
b/tray/win32/ovirt-tray/pipeserver/targetver.h
new file mode 100644
index 0000000..c83c946
--- /dev/null
+++ b/tray/win32/ovirt-tray/pipeserver/targetver.h
@@ -0,0 +1,24 @@
+#pragma once
+
+// The following macros define the minimum required platform.  The minimum 
required platform
+// is the earliest version of Windows, Internet Explorer etc. that has the 
necessary features to run 
+// your application.  The macros work by enabling all features available on 
platform versions up to and 
+// including the version specified.
+
+// Modify the following defines if you have to target a platform prior to the 
ones specified below.
+// Refer to MSDN for the latest info on corresponding values for different 
platforms.
+#ifndef WINVER                          // Specifies that the minimum required 
platform is Windows Vista.
+#define WINVER 0x0501           // Change this to the appropriate value to 
target other versions of Windows.
+#endif
+
+#ifndef _WIN32_WINNT            // Specifies that the minimum required 
platform is Windows Vista.
+#define _WIN32_WINNT 0x0501     // Change this to the appropriate value to 
target other versions of Windows.
+#endif
+
+#ifndef _WIN32_WINDOWS          // Specifies that the minimum required 
platform is Windows 98.
+#define _WIN32_WINDOWS 0x0501 // Change this to the appropriate value to 
target Windows Me or later.
+#endif
+
+#ifndef _WIN32_IE                       // Specifies that the minimum required 
platform is Internet Explorer 7.0.
+#define _WIN32_IE 0x0600        // Change this to the appropriate value to 
target other versions of IE.
+#endif
diff --git a/tray/win32/ovirt-tray/pipeserver/utilities.h 
b/tray/win32/ovirt-tray/pipeserver/utilities.h
new file mode 100644
index 0000000..5f5844e
--- /dev/null
+++ b/tray/win32/ovirt-tray/pipeserver/utilities.h
@@ -0,0 +1,9 @@
+#pragma once
+
+#include <windows.h>
+
+inline DWORD GetPlatformThreadCount() {
+    SYSTEM_INFO info = {};
+    ::GetNativeSystemInfo(&info);
+    return info.dwNumberOfProcessors;
+}


-- 
To view, visit http://gerrit.ovirt.org/34443
To unsubscribe, visit http://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I3c0caa72b548bb3ce39e06f7dc879709dba89989
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-guest-agent
Gerrit-Branch: master
Gerrit-Owner: Vinzenz Feenstra <vfeen...@redhat.com>
_______________________________________________
Engine-patches mailing list
Engine-patches@ovirt.org
http://lists.ovirt.org/mailman/listinfo/engine-patches

Reply via email to