|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [win-pv-devel] [PATCH 13/20] Add SetXenTime functionality
Signed-off-by: Owen Smith <owen.smith@xxxxxxxxxx>
---
src/liteagent/LiteAgent.cpp | 116 ++++++++++++++++++++++++++++++++++++++++++--
src/liteagent/LiteAgent.h | 3 ++
2 files changed, 116 insertions(+), 3 deletions(-)
diff --git a/src/liteagent/LiteAgent.cpp b/src/liteagent/LiteAgent.cpp
index 480447d..b61967f 100644
--- a/src/liteagent/LiteAgent.cpp
+++ b/src/liteagent/LiteAgent.cpp
@@ -36,6 +36,12 @@
#include "LiteAgent.h"
#include "xeniface_ioctls.h"
+#define XENTOOLS_INSTALL_REG_KEY "SOFTWARE\\Citrix\\XenTools"
+
+#ifdef _WIN64
+#define XENTOOLS_INSTALL_REG_KEY64 "SOFTWARE\\Wow6432Node\\Citrix\\XenTools"
+#endif
+
int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE ignore, LPSTR lpCmdLine,
int nCmdShow)
{
if (strlen(lpCmdLine) != 0) {
@@ -205,7 +211,6 @@ CLiteAgent::~CLiteAgent()
{
CLiteAgent::Log("OnDeviceRemoved(%ws)\n", dev->Path());
if ((CXenIfaceItf*)dev == m_dev) {
- m_dev = NULL;
// active device removed
CLiteAgent::Log("Active Device Removed\n");
@@ -220,6 +225,9 @@ CLiteAgent::~CLiteAgent()
// unregister watch
m_dev->StoreRemoveWatch(m_ctxt_shutdown);
m_ctxt_shutdown = NULL;
+
+ // remove internal reference
+ m_dev = NULL;
}
}
@@ -246,6 +254,7 @@ bool CLiteAgent::ServiceMainLoop()
DWORD wait = WaitForMultipleObjects(3, evts, FALSE, INFINITE);
switch (wait) {
case WAIT_OBJECT_0:
+ CLiteAgent::Log("Stop event set\n");
return false; // service stop event
case WAIT_OBJECT_0+1:
@@ -272,7 +281,6 @@ void CLiteAgent::OnShutdown()
std::string type;
m_dev->StoreRead("control/shutdown", type);
-
CLiteAgent::Log("OnShutdown(%s)\n", type.c_str());
}
@@ -293,17 +301,119 @@ void CLiteAgent::OnSuspend()
void CLiteAgent::SetXenTime()
{
CLiteAgent::Log("SetXenTime()\n");
+
+ FILETIME now = { 0 };
+ if (!m_dev->SharedInfoGetTime(&now))
+ return;
+
+ bool IsUtc = HostTimeIsUtc();
+ if (IsUtc)
+ AdjustXenTimeToUtc(&now);
+
+ SYSTEMTIME sys = { 0 };
+ if (!FileTimeToSystemTime(&now, &sys))
+ return;
+
+ SYSTEMTIME cur = { 0 };
+ GetLocalTime(&cur);
+ CLiteAgent::Log("Time Now = %d/%d/%d %d:%02d:%02d.%d\n",
+ cur.wYear, cur.wMonth, cur.wDay,
+ cur.wHour, cur.wMinute, cur.wSecond, cur.wMilliseconds);
+ CLiteAgent::Log("New Time = %d/%d/%d %d:%02d:%02d.%d\n",
+ sys.wYear, sys.wMonth, sys.wDay,
+ sys.wHour, sys.wMinute, sys.wSecond, sys.wMilliseconds);
+ if (IsUtc)
+ SetSystemTime(&sys);
+ else
+ SetLocalTime(&sys);
}
void CLiteAgent::KickXapi()
{
char value[32];
- _snprintf_s(value, sizeof(value), 31, "%I64d", m_update);
+ _snprintf_s(value, sizeof(value), 31, "%I64d", (__int64)m_update);
m_dev->StoreWrite("data/update_cnt", value);
m_dev->StoreWrite("data/updated", "1");
++m_update;
}
+bool CLiteAgent::HostTimeIsUtc()
+{
+#ifdef _WIN64
+ if (RegMatchStr(XENTOOLS_INSTALL_REG_KEY64, "HostTime", "UTC"))
+ return true;
+#endif
+ if (RegMatchStr(XENTOOLS_INSTALL_REG_KEY, "HostTime", "UTC"))
+ return true;
+
+ return false;
+}
+
+void CLiteAgent::AdjustXenTimeToUtc(FILETIME* now)
+{
+ std::string vm;
+ if (!m_dev->StoreRead("vm", vm))
+ return;
+
+ std::string offs;
+ if (!m_dev->StoreRead(vm + "/rtc/timeoffset", offs)) {
+ if (!m_dev->StoreRead("platform/timeoffset", offs))
+ return;
+ }
+
+ long offset = (long)atoi(offs.c_str());
+
+ LARGE_INTEGER loffs;
+ loffs.QuadPart = (LONGLONG)offset * 1000000;
+
+ ULARGE_INTEGER lnow;
+ lnow.LowPart = now->dwLowDateTime;
+ lnow.HighPart = now->dwHighDateTime;
+
+ lnow.QuadPart -= loffs.QuadPart;
+
+ now->dwLowDateTime = lnow.LowPart;
+ now->dwHighDateTime = lnow.HighPart;
+}
+
+bool CLiteAgent::RegMatchStr(const char* path, const char* name, const char*
value)
+{
+ HKEY key;
+ LRESULT lr;
+ bool match = false;
+
+ lr = RegOpenKeyEx(HKEY_LOCAL_MACHINE, path, 0, KEY_READ, &key);
+ if (lr != ERROR_SUCCESS)
+ return false;
+
+ long size = 32;
+ DWORD length;
+ char* buffer = NULL;
+ do {
+ length = size;
+ if (buffer)
+ delete [] buffer;
+
+ buffer = new char[size];
+ if (buffer == NULL)
+ goto done;
+
+ lr = RegQueryValueEx(key, name, NULL, NULL, (LPBYTE)buffer, &length);
+ size *= 2;
+ } while (lr == ERROR_MORE_DATA);
+ if (lr != ERROR_SUCCESS)
+ goto done;
+ if (_strnicoll(value, buffer, length))
+ goto done;
+ match = true;
+
+done:
+ if (buffer)
+ delete [] buffer;
+ RegCloseKey(key);
+ return match;
+}
+
void CLiteAgent::SetServiceStatus(DWORD state, DWORD exit /*= 0*/, DWORD hint
/*= 0*/)
{
m_status.dwCurrentState = state;
diff --git a/src/liteagent/LiteAgent.h b/src/liteagent/LiteAgent.h
index 8ab062a..97c6514 100644
--- a/src/liteagent/LiteAgent.h
+++ b/src/liteagent/LiteAgent.h
@@ -72,6 +72,9 @@ private: // service events
void OnSuspend();
void SetXenTime();
void KickXapi();
+ bool HostTimeIsUtc();
+ void AdjustXenTimeToUtc(FILETIME* now);
+ bool RegMatchStr(const char* path, const char* name, const char* value);
private: // service support
void SetServiceStatus(DWORD state, DWORD exit = 0, DWORD hint = 0);
--
1.9.4.msysgit.1
_______________________________________________
win-pv-devel mailing list
win-pv-devel@xxxxxxxxxxxxxxxxxxxx
http://lists.xenproject.org/cgi-bin/mailman/listinfo/win-pv-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |