[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[win-pv-devel] [PATCH 3/3] Add a new CConvCreator object to handle laptop/slate mode switch



This patch adds a new object derived from IDeviceCreator to interact
with the laptop/slate mode switch interface provided by a Windows
driver that binds to the ACPI CONV device.

It also adds code to support the documented PV interface for triggering
laptop/slate mode switch [1].

http://xenbits.xen.org/gitweb/?p=xen.git;a=commit;h=3bdb1400

Signed-off-by: Paul Durrant <paul.durrant@xxxxxxxxxx>
---
 src/xenagent/convdevice.cpp      | 137 +++++++++++++++++++++++++++++
 src/xenagent/convdevice.h        |  59 +++++++++++++
 src/xenagent/devicelist.cpp      |  16 ++++
 src/xenagent/devicelist.h        |   1 +
 src/xenagent/messages.mc         |   8 ++
 src/xenagent/service.cpp         | 183 +++++++++++++++++++++++++++++++++++++--
 src/xenagent/service.h           |  38 ++++++++
 vs2012/xenagent/xenagent.vcxproj |   1 +
 vs2013/xenagent/xenagent.vcxproj |   1 +
 vs2015/xenagent/xenagent.vcxproj |   1 +
 10 files changed, 439 insertions(+), 6 deletions(-)
 create mode 100644 src/xenagent/convdevice.cpp
 create mode 100644 src/xenagent/convdevice.h

diff --git a/src/xenagent/convdevice.cpp b/src/xenagent/convdevice.cpp
new file mode 100644
index 0000000..5ac40ff
--- /dev/null
+++ b/src/xenagent/convdevice.cpp
@@ -0,0 +1,137 @@
+/* Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms,
+ * with or without modification, are permitted provided
+ * that the following conditions are met:
+ *
+ * *   Redistributions of source code must retain the above
+ *     copyright notice, this list of conditions and the
+ *     following disclaimer.
+ * *   Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the
+ *     following disclaimer in the documentation and/or other
+ *     materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <windows.h>
+#include <stdio.h>
+#include <powrprof.h>
+#include <winuser.h>
+
+#include "service.h"
+#include "convdevice.h"
+#include "devicelist.h"
+
+CConvDevice::CConvDevice(const wchar_t* path) : CDevice(path)
+{
+}
+
+/*virtual*/ CConvDevice::~CConvDevice()
+{
+}
+
+void CConvDevice::SetMode(DWORD new_mode)
+{
+    DisablePrompt();
+
+    CXenAgent::Log("New mode = %s\n", new_mode ? "Laptop" : "Slate");
+
+    for (;;) {
+        BYTE buffer(0);
+        DWORD current_mode(CCONV_DEVICE_UNKNOWN_MODE);
+
+        if (!GetMode(&current_mode))
+            break;
+
+        CXenAgent::Log("Current mode = %s\n",
+                       current_mode ? "Laptop" : "Slate");
+
+        if (current_mode == new_mode)
+            break;
+
+        Write(&buffer, sizeof(buffer));
+        Sleep(1000); // yield
+    }
+}
+
+bool CConvDevice::DisablePrompt()
+{
+    HKEY key;
+    LRESULT lr;
+    std::string path;
+
+    path = "System\\CurrentControlSet\\Control\\PriorityControl";
+
+    lr = RegOpenKeyEx(HKEY_LOCAL_MACHINE, path.c_str(), 0, KEY_ALL_ACCESS,
+                      &key);
+    if (lr != ERROR_SUCCESS)
+        goto fail1;
+
+    DWORD type(REG_DWORD);
+    DWORD val(0);
+    DWORD length;
+
+    length = sizeof(val);
+    lr = RegSetValueEx(key, "ConvertibleSlateModePromptPreference", NULL,
+                       type, (LPBYTE)&val, length);
+    if (lr != ERROR_SUCCESS)
+        goto fail2;
+
+    RegCloseKey(key);
+
+    return true;
+
+fail2:
+    RegCloseKey(key);
+fail1:
+    return false;
+}
+
+bool CConvDevice::GetMode(DWORD *mode)
+{
+    HKEY key;
+    LRESULT lr;
+    std::string path;
+
+    path = "System\\CurrentControlSet\\Control\\PriorityControl";
+
+    lr = RegOpenKeyEx(HKEY_LOCAL_MACHINE, path.c_str(), 0, KEY_READ, &key);
+    if (lr != ERROR_SUCCESS)
+        goto fail1;
+
+    DWORD type;
+    DWORD val;
+    DWORD length;
+
+    length = sizeof(val);
+    lr = RegQueryValueEx(key, "ConvertibleSlateMode", NULL, &type,
+                         (LPBYTE)&val, &length);
+    if (lr != ERROR_SUCCESS || type != REG_DWORD)
+        goto fail2;
+
+    RegCloseKey(key);
+
+    *mode = val;
+    return true;
+
+fail2:
+    RegCloseKey(key);
+fail1:
+    return false;
+}
diff --git a/src/xenagent/convdevice.h b/src/xenagent/convdevice.h
new file mode 100644
index 0000000..90f8035
--- /dev/null
+++ b/src/xenagent/convdevice.h
@@ -0,0 +1,59 @@
+/* Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms,
+ * with or without modification, are permitted provided
+ * that the following conditions are met:
+ *
+ * *   Redistributions of source code must retain the above
+ *     copyright notice, this list of conditions and the
+ *     following disclaimer.
+ * *   Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the
+ *     following disclaimer in the documentation and/or other
+ *     materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef __XENAGENT_CONVDEVICE_H__
+#define __XENAGENT_CONVDEVICE_H__
+
+#include <windows.h>
+#include <string>
+#include "devicelist.h"
+
+enum {
+    CCONV_DEVICE_SLATE_MODE,
+    CCONV_DEVICE_LAPTOP_MODE,
+    CCONV_DEVICE_UNKNOWN_MODE
+};
+
+class CConvDevice : public CDevice
+{
+public:
+    CConvDevice(const wchar_t* path);
+    virtual ~CConvDevice();
+
+public:
+    void SetMode(DWORD mode);
+
+private:
+    bool DisablePrompt();
+    bool GetMode(DWORD *mode);
+};
+
+#endif
diff --git a/src/xenagent/devicelist.cpp b/src/xenagent/devicelist.cpp
index 2c110bc..b40b252 100644
--- a/src/xenagent/devicelist.cpp
+++ b/src/xenagent/devicelist.cpp
@@ -101,6 +101,22 @@ void CDevice::Close()
     m_handle = INVALID_HANDLE_VALUE;
 }
 
+bool CDevice::Write(void *buf, DWORD bufsz, DWORD *bytes /* = NULL*/)
+{
+    if (m_handle == INVALID_HANDLE_VALUE)
+        return false;
+
+    DWORD _bytes;
+    if (!WriteFile(m_handle,
+                   buf,
+                   bufsz,
+                   (bytes == NULL) ? &_bytes : bytes,
+                   NULL))
+        return false;
+
+    return true;
+}
+
 bool CDevice::Ioctl(DWORD ioctl, void* in, DWORD insz, void* out, DWORD outsz, 
DWORD* bytes /*= NULL*/)
 {
     if (m_handle == INVALID_HANDLE_VALUE)
diff --git a/src/xenagent/devicelist.h b/src/xenagent/devicelist.h
index 893bd43..5535ad5 100644
--- a/src/xenagent/devicelist.h
+++ b/src/xenagent/devicelist.h
@@ -49,6 +49,7 @@ public:
     void Close();
 
 protected:
+    bool Write(void *buf, DWORD bufsz, DWORD *bytes = NULL);
     bool Ioctl(DWORD ioctl, void* in, DWORD insz, void* out, DWORD outsz, 
DWORD* bytes = NULL);
 
 private:
diff --git a/src/xenagent/messages.mc b/src/xenagent/messages.mc
index a50021a..56f0e5d 100644
--- a/src/xenagent/messages.mc
+++ b/src/xenagent/messages.mc
@@ -108,3 +108,11 @@ SymbolicName=EVENT_XENUSER_UNEXPECTED
 Language=English
 The tools experienced an unexpected error.
 .
+
+MessageId=0x0009
+Facility=System
+Severity=Informational
+SymbolicName=EVENT_XENUSER_MODE_SWITCH
+Language=English
+The tools requested a mode switch.
+.
diff --git a/src/xenagent/service.cpp b/src/xenagent/service.cpp
index a2deca1..d917821 100644
--- a/src/xenagent/service.cpp
+++ b/src/xenagent/service.cpp
@@ -60,10 +60,12 @@ CCritSec::~CCritSec()
 
 CXenIfaceCreator::CXenIfaceCreator(CXenAgent& agent) :
     m_devlist(GUID_INTERFACE_XENIFACE), m_device(NULL),
-    m_ctxt_shutdown(NULL), m_ctxt_suspend(NULL), m_agent(agent)
+    m_ctxt_shutdown(NULL), m_ctxt_suspend(NULL),
+    m_ctxt_slate_mode(NULL), m_agent(agent)
 {
     m_evt_shutdown = CreateEvent(FALSE, NULL, NULL, FALSE);
     m_evt_suspend = CreateEvent(FALSE, NULL, NULL, FALSE);
+    m_evt_slate_mode = CreateEvent(FALSE, NULL, NULL, FALSE);
     m_count = 0;
 
     InitializeCriticalSection(&m_crit);
@@ -71,6 +73,7 @@ CXenIfaceCreator::CXenIfaceCreator(CXenAgent& agent) :
 
 CXenIfaceCreator::~CXenIfaceCreator()
 {
+    CloseHandle(m_evt_slate_mode);
     CloseHandle(m_evt_suspend);
     CloseHandle(m_evt_shutdown);
 
@@ -120,7 +123,12 @@ void CXenIfaceCreator::Log(const char* message)
         m_device = (CXenIfaceDevice*)dev;
 
         m_device->SuspendRegister(m_evt_suspend, &m_ctxt_suspend);
+
         StartShutdownWatch();
+
+        if (m_agent.ConvDevicePresent())
+            StartSlateModeWatch();
+
         SetXenTime();
     }
 }
@@ -135,6 +143,10 @@ void CXenIfaceCreator::Log(const char* message)
             m_device->SuspendDeregister(m_ctxt_suspend);
             m_ctxt_suspend = NULL;
         }
+
+        if (m_agent.ConvDevicePresent())
+            StopSlateModeWatch();
+
         StopShutdownWatch();
 
         m_device = NULL;
@@ -144,13 +156,21 @@ void CXenIfaceCreator::Log(const char* message)
 /*virtual*/ void CXenIfaceCreator::OnDeviceSuspend(CDevice* dev)
 {
     CXenAgent::Log("OnDeviceSuspend(%ws)\n", dev->Path());
+
+    if (m_agent.ConvDevicePresent())
+        StopSlateModeWatch();
+
     StopShutdownWatch();
 }
 
 /*virtual*/ void CXenIfaceCreator::OnDeviceResume(CDevice* dev)
 {
     CXenAgent::Log("OnDeviceResume(%ws)\n", dev->Path());
+
     StartShutdownWatch();
+
+    if (m_agent.ConvDevicePresent())
+        StartSlateModeWatch();
 }
 
 bool CXenIfaceCreator::CheckShutdown()
@@ -230,13 +250,36 @@ void CXenIfaceCreator::CheckSuspend()
 
     m_agent.EventLog(EVENT_XENUSER_UNSUSPENDED);
 
-    // recreate shutdown watch, as suspending deactivated the watch
+    // recreate watches, as suspending deactivated the watch
+    if (m_agent.ConvDevicePresent())
+        StopSlateModeWatch();
+
     StopShutdownWatch();
+
     StartShutdownWatch();
+
+    if (m_agent.ConvDevicePresent())
+        StartSlateModeWatch();
+
     SetXenTime();
     m_count = count;
 }
 
+bool CXenIfaceCreator::CheckSlateMode(std::string *mode)
+{
+    CCritSec crit(&m_crit);
+    if (m_device == NULL)
+        return false;
+
+    if (!m_device->StoreRead("control/laptop-slate-mode", *mode))
+        return false;
+
+    if (*mode != "")
+        m_device->StoreWrite("control/laptop-slate-mode", "");
+
+    return true;
+}
+
 void CXenIfaceCreator::StartShutdownWatch()
 {
     if (m_ctxt_shutdown)
@@ -264,6 +307,26 @@ void CXenIfaceCreator::StopShutdownWatch()
     m_ctxt_shutdown = NULL;
 }
 
+void CXenIfaceCreator::StartSlateModeWatch()
+{
+    if (m_ctxt_slate_mode)
+        return;
+
+    m_device->StoreAddWatch("control/laptop-slate-mode", m_evt_slate_mode, 
&m_ctxt_slate_mode);
+    m_device->StoreWrite("control/feature-laptop-slate-mode", "1");
+}
+
+void CXenIfaceCreator::StopSlateModeWatch()
+{
+    if (!m_ctxt_slate_mode)
+        return;
+
+    m_device->StoreRemove("control/feature-laptop-slate-mode");
+
+    m_device->StoreRemoveWatch(m_ctxt_slate_mode);
+    m_ctxt_slate_mode = NULL;
+}
+
 void CXenIfaceCreator::AcquireShutdownPrivilege()
 {
     HANDLE          token;
@@ -398,6 +461,94 @@ void CXenIfaceCreator::SetXenTime()
         SetLocalTime(&sys);
 }
 
+/* 317fc439-3f77-41c8-b09e-08ad63272aa3 */
+DEFINE_GUID(GUID_GPIOBUTTONS_LAPTOPSLATE_INTERFACE, \
+            0x317fc439, 0x3f77, 0x41c8, 0xb0, 0x9e, 0x08, 0xad, 0x63, 0x27, 
0x2a, 0xa3);
+
+CConvCreator::CConvCreator(CXenAgent& agent) :
+    m_devlist(GUID_GPIOBUTTONS_LAPTOPSLATE_INTERFACE), m_device(NULL),
+    m_agent(agent)
+{
+    InitializeCriticalSection(&m_crit);
+}
+
+CConvCreator::~CConvCreator()
+{
+    DeleteCriticalSection(&m_crit);
+}
+
+bool CConvCreator::Start(HANDLE svc)
+{
+    return m_devlist.Start(svc, this);
+}
+
+void CConvCreator::Stop()
+{
+    m_devlist.Stop();
+}
+
+void CConvCreator::OnDeviceEvent(DWORD evt, LPVOID data)
+{
+    m_devlist.OnDeviceEvent(evt, data);
+}
+
+void CConvCreator::OnPowerEvent(DWORD evt, LPVOID data)
+{
+    m_devlist.OnPowerEvent(evt, data);
+}
+
+void CConvCreator::SetSlateMode(std::string mode)
+{
+    CCritSec crit(&m_crit);
+    if (m_device == NULL)
+        return;
+
+    m_agent.EventLog(EVENT_XENUSER_MODE_SWITCH);
+
+    if (mode == "laptop")
+        m_device->SetMode(CCONV_DEVICE_LAPTOP_MODE);
+    else if (mode == "slate")
+        m_device->SetMode(CCONV_DEVICE_SLATE_MODE);
+}
+
+bool CConvCreator::DevicePresent()
+{
+    return m_device != NULL;
+}
+
+/*virtual*/ CDevice* CConvCreator::Create(const wchar_t* path)
+{
+    return new CConvDevice(path);
+}
+
+/*virtual*/ void CConvCreator::OnDeviceAdded(CDevice* dev)
+{
+    CXenAgent::Log("OnDeviceAdded(%ws)\n", dev->Path());
+
+    CCritSec crit(&m_crit);
+    if (m_device == NULL)
+        m_device = (CConvDevice*)dev;
+}
+
+/*virtual*/ void CConvCreator::OnDeviceRemoved(CDevice* dev)
+{
+    CXenAgent::Log("OnDeviceRemoved(%ws)\n", dev->Path());
+
+    CCritSec crit(&m_crit);
+    if (m_device == dev)
+        m_device = NULL;
+}
+
+/*virtual*/ void CConvCreator::OnDeviceSuspend(CDevice* dev)
+{
+    CXenAgent::Log("OnDeviceSuspend(%ws)\n", dev->Path());
+}
+
+/*virtual*/ void CConvCreator::OnDeviceResume(CDevice* dev)
+{
+    CXenAgent::Log("OnDeviceResume(%ws)\n", dev->Path());
+}
+
 static CXenAgent s_service;
 
 /*static*/ void CXenAgent::Log(const char* fmt, ...)
@@ -505,7 +656,8 @@ static CXenAgent s_service;
 #pragma warning(push)
 #pragma warning(disable:4355)
 
-CXenAgent::CXenAgent() : m_handle(NULL), m_evtlog(NULL), m_xeniface(*this)
+CXenAgent::CXenAgent() : m_handle(NULL), m_evtlog(NULL), m_xeniface(*this),
+                         m_conv(*this)
 {
     m_status.dwServiceType        = SERVICE_WIN32;
     m_status.dwCurrentState       = SERVICE_START_PENDING;
@@ -530,6 +682,7 @@ CXenAgent::~CXenAgent()
 void CXenAgent::OnServiceStart()
 {
     CXenAgent::Log("OnServiceStart()\n");
+    m_conv.Start(m_handle);
     m_xeniface.Start(m_handle);
 }
 
@@ -537,23 +690,28 @@ void CXenAgent::OnServiceStop()
 {
     CXenAgent::Log("OnServiceStop()\n");
     m_xeniface.Stop();
+    m_conv.Stop();
 }
 
 void CXenAgent::OnDeviceEvent(DWORD evt, LPVOID data)
 {
+    m_conv.OnDeviceEvent(evt, data);
     m_xeniface.OnDeviceEvent(evt, data);
 }
 
 void CXenAgent::OnPowerEvent(DWORD evt, LPVOID data)
 {
+    m_conv.OnPowerEvent(evt, data);
     m_xeniface.OnPowerEvent(evt, data);
 }
 
 bool CXenAgent::ServiceMainLoop()
 {
-    HANDLE  events[3] = { m_svc_stop, m_xeniface.m_evt_shutdown,
-                          m_xeniface.m_evt_suspend };
-    DWORD   wait = WaitForMultipleObjectsEx(3, events, FALSE, 60000, TRUE);
+    HANDLE  events[] = { m_svc_stop,
+                         m_xeniface.m_evt_shutdown,
+                         m_xeniface.m_evt_suspend,
+                         m_xeniface.m_evt_slate_mode };
+    DWORD   wait = WaitForMultipleObjectsEx(4, events, FALSE, 60000, TRUE);
 
     switch (wait) {
     case WAIT_OBJECT_0:
@@ -566,6 +724,14 @@ bool CXenAgent::ServiceMainLoop()
         m_xeniface.CheckSuspend();
         return true; // continue loop
 
+    case WAIT_OBJECT_0+3: {
+        std::string mode;
+
+        if (m_xeniface.CheckSlateMode(&mode))
+            m_conv.SetSlateMode(mode);
+
+        return true; // continue loop
+    }
     case WAIT_IO_COMPLETION:
     case WAIT_TIMEOUT:
         m_xeniface.CheckSuspend();
@@ -593,6 +759,11 @@ void CXenAgent::EventLog(DWORD evt)
     }
 }
 
+bool CXenAgent::ConvDevicePresent()
+{
+    return m_conv.DevicePresent();
+}
+
 void CXenAgent::SetServiceStatus(DWORD state, DWORD exit /*= 0*/, DWORD hint 
/*= 0*/)
 {
     m_status.dwCurrentState = state;
diff --git a/src/xenagent/service.h b/src/xenagent/service.h
index 6d359fe..60ecb16 100644
--- a/src/xenagent/service.h
+++ b/src/xenagent/service.h
@@ -39,6 +39,7 @@
 
 #include "devicelist.h"
 #include "xenifacedevice.h"
+#include "convdevice.h"
 
 class CXenAgent;
 
@@ -65,14 +66,18 @@ public: // IDeviceCreator
 public:
     bool CheckShutdown();
     void CheckSuspend();
+    bool CheckSlateMode(std::string *mode);
 
 public:
     HANDLE  m_evt_shutdown;
     HANDLE  m_evt_suspend;
+    HANDLE  m_evt_slate_mode;
 
 private:
     void StartShutdownWatch();
     void StopShutdownWatch();
+    void StartSlateModeWatch();
+    void StopSlateModeWatch();
     void AcquireShutdownPrivilege();
     bool IsHostTimeUTC();
     void AdjustXenTimeToUTC(FILETIME* time);
@@ -86,9 +91,38 @@ private:
     CRITICAL_SECTION    m_crit;
     void*               m_ctxt_shutdown;
     void*               m_ctxt_suspend;
+    void*               m_ctxt_slate_mode;
     DWORD               m_count;
 };
 
+class CConvCreator : public IDeviceCreator
+{
+public:
+    CConvCreator(CXenAgent&);
+    virtual ~CConvCreator();
+    CConvCreator& operator=(const CConvCreator&);
+
+    bool Start(HANDLE svc);
+    void Stop();
+    void OnDeviceEvent(DWORD evt, LPVOID data);
+    void OnPowerEvent(DWORD evt, LPVOID data);
+    void SetSlateMode(std::string mode);
+    bool DevicePresent();
+
+public:
+    virtual CDevice* Create(const wchar_t* path);
+    virtual void OnDeviceAdded(CDevice* dev);
+    virtual void OnDeviceRemoved(CDevice* dev);
+    virtual void OnDeviceSuspend(CDevice* dev);
+    virtual void OnDeviceResume(CDevice* dev);
+
+private:
+    CXenAgent&          m_agent;
+    CDeviceList         m_devlist;
+    CConvDevice*        m_device;
+    CRITICAL_SECTION    m_crit;
+};
+
 class CXenAgent
 {
 public: // statics
@@ -108,6 +142,9 @@ public: // ctor/dtor
 public:
     void EventLog(DWORD evt);
 
+public:
+    bool ConvDevicePresent();
+
 private: // service events
     void OnServiceStart();
     void OnServiceStop();
@@ -125,6 +162,7 @@ private: // service support
     HANDLE                  m_evtlog;
     HANDLE                  m_svc_stop;
     CXenIfaceCreator        m_xeniface;
+    CConvCreator            m_conv;
 };
 
 #endif
diff --git a/vs2012/xenagent/xenagent.vcxproj b/vs2012/xenagent/xenagent.vcxproj
index 7ae655e..f778e90 100644
--- a/vs2012/xenagent/xenagent.vcxproj
+++ b/vs2012/xenagent/xenagent.vcxproj
@@ -76,6 +76,7 @@
     <ClCompile Include="..\..\src\xenagent\service.cpp"/>
     <ClCompile Include="..\..\src\xenagent\devicelist.cpp"/>
     <ClCompile Include="..\..\src\xenagent\xenifacedevice.cpp"/>
+    <ClCompile Include="..\..\src\xenagent\convdevice.cpp"/>
   </ItemGroup>
   <ItemGroup>
     <ResourceCompile Include="..\..\src\xenagent\xenagent.rc" />
diff --git a/vs2013/xenagent/xenagent.vcxproj b/vs2013/xenagent/xenagent.vcxproj
index a2ad3f8..e51d8be 100644
--- a/vs2013/xenagent/xenagent.vcxproj
+++ b/vs2013/xenagent/xenagent.vcxproj
@@ -76,6 +76,7 @@
     <ClCompile Include="..\..\src\xenagent\service.cpp"/>
     <ClCompile Include="..\..\src\xenagent\devicelist.cpp"/>
     <ClCompile Include="..\..\src\xenagent\xenifacedevice.cpp"/>
+    <ClCompile Include="..\..\src\xenagent\convdevice.cpp"/>
   </ItemGroup>
   <ItemGroup>
     <ResourceCompile Include="..\..\src\xenagent\xenagent.rc" />
diff --git a/vs2015/xenagent/xenagent.vcxproj b/vs2015/xenagent/xenagent.vcxproj
index 5f87e6d..e7fec8e 100644
--- a/vs2015/xenagent/xenagent.vcxproj
+++ b/vs2015/xenagent/xenagent.vcxproj
@@ -71,6 +71,7 @@
     <ClCompile Include="..\..\src\xenagent\service.cpp"/>
     <ClCompile Include="..\..\src\xenagent\devicelist.cpp"/>
     <ClCompile Include="..\..\src\xenagent\xenifacedevice.cpp"/>
+    <ClCompile Include="..\..\src\xenagent\convdevice.cpp"/>
   </ItemGroup>
   <ItemGroup>
     <ResourceCompile Include="..\..\src\xenagent\xenagent.rc" />
-- 
2.5.3


_______________________________________________
win-pv-devel mailing list
win-pv-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/cgi-bin/mailman/listinfo/win-pv-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.