[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 |