SetSystemTimeAdjustmentPrecise 函数 (sysinfoapi.h)
启用或禁用对系统时间时钟的定期时间调整。 启用后,此类时间调整可用于将一天中的时间与某些其他时间源信息同步。
语法
BOOL SetSystemTimeAdjustmentPrecise(
[in] DWORD64 dwTimeAdjustment,
[in] BOOL bTimeAdjustmentDisabled
);
参数
[in] dwTimeAdjustment
提供调整后的时钟更新频率。
[in] bTimeAdjustmentDisabled
提供一个标志,该标志指定系统要使用的时间调整模式。
值为 TRUE 表示系统应使用自己的内部机制同步一天中的时间。 在这种情况下, 将忽略 dwTimeAdjustment 的值。
值为 FALSE 表示应用程序处于控制状态,并且指定值 dwTimeAdjustment 将在每次时钟更新中断时添加到一天中的时间时钟。
返回值
如果函数成功,则返回值为非零。
如果函数失败,则返回值为零。 要获得更多的错误信息,请调用 GetLastError。 函数可能失败的一种方式是调用方没有SE_SYSTEMTIME_NAME特权。
注解
若要使用此函数,调用方必须具有系统时间特权 (SE_SYSTEMTIME_NAME) 。 默认情况下,此权限处于禁用状态。 使用 AdjustTokenPrivileges 函数在调用此函数之前启用特权,然后在函数调用后禁用该特权。 有关详细信息,请参阅下面的代码示例。
示例
此示例演示如何启用系统时间权限、使用 GetSystemTimeAdjustmentPrecise 和 SetSystemTimeAdjustmentPrecise 调整系统时钟,以及如何整齐地打印当前系统时间调整。
/******************************************************************
*
* ObtainRequiredPrivileges
*
* Enables system time adjustment privilege.
*
******************************************************************/
HRESULT
ObtainRequiredPrivileges()
{
HRESULT hr;
HANDLE hProcToken = NULL;
TOKEN_PRIVILEGES tp = {0};
LUID luid;
if (!LookupPrivilegeValue(NULL, SE_SYSTEMTIME_NAME, &luid))
{
hr = HRESULT_FROM_WIN32(GetLastError());
printf("Failed to lookup privilege value. hr=0x%08x\n", hr);
return hr;
}
// get the token for our process
if (!OpenProcessToken(GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
&hProcToken))
{
hr = HRESULT_FROM_WIN32(GetLastError());
printf("Failed to open process token. hr=0x%08x\n", hr);
return hr;
}
// Enable just the SYSTEMTIME privilege
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if (!AdjustTokenPrivileges(hProcToken, FALSE, &tp, 0, NULL, NULL))
{
hr = HRESULT_FROM_WIN32(GetLastError());
printf("Failed to adjust process token privileges. hr=0x%08x\n", hr);
}
else
{
hr = S_OK;
printf("Added SYSTEMTIME privilege to the process token\n");
}
if (NULL != hProcToken)
{
CloseHandle(hProcToken);
}
return hr;
}
/******************************************************************
*
* PrintCurrentClockAdjustments
*
* Prints current values of the system time adjustments.
*
******************************************************************/
void
PrintCurrentClockAdjustments()
{
// More granular clock adjustments
DWORD64 ullCurrentAdjustment = 0;
DWORD64 ullTimeIncrement = 0;
BOOL bEnabledPrecise = 0;
HRESULT hrPrecise = S_OK;
// Legacy clock adjustments
DWORD dwCurrentAdjustment = 0;
DWORD dwTimeIncrement = 0;
BOOL bEnabled = 0;
HRESULT hr = S_OK;
if (!GetSystemTimeAdjustmentPrecise(&ullCurrentAdjustment, &ullTimeIncrement, &bEnabledPrecise))
{
hrPrecise = HRESULT_FROM_WIN32(GetLastError());
}
if (!GetSystemTimeAdjustment(&dwCurrentAdjustment, &dwTimeIncrement, &bEnabled))
{
hr = HRESULT_FROM_WIN32(GetLastError());
}
printf("Precise_ADJ:%I64u Precise_INCR:%I64u Precise_EN:%d Precise_hr:0x%08x ADJ:%u INCR:%u EN:%d hr:0x%08x\n",
ullCurrentAdjustment, ullTimeIncrement, bEnabledPrecise, hrPrecise,
dwCurrentAdjustment, dwTimeIncrement, bEnabled, hr);
}
/******************************************************************
*
* RunNewAdjustmentSequence
*
* Adjust the system time using high-resolution
* GetSystemTimeAdjustmentPrecise() and SetSystemTimeAdjustmentPrecise() API.
*
******************************************************************/
void
RunNewAdjustmentSequence(DWORD dwPPMAdjustment)
{
DWORD64 ullCurrentAdjustment = 0;
DWORD64 ullTimeIncrement = 0;
BOOL bEnabledPrecise = 0;
LARGE_INTEGER liPerfCounterFrequency = {0};
DWORD dwNewAdjustmentUnits;
const DWORD cMicroSecondsPerSecond = 1000000;
if (dwPPMAdjustment > 1000)
{
printf("Adjustment too large. Skipping new adjustment sequence.\n");
return;
}
printf("Starting adjustment sequence using new API...\n");
if (!GetSystemTimeAdjustmentPrecise(&ullCurrentAdjustment, &ullTimeIncrement, &bEnabledPrecise))
{
printf("Failed to read the system time adjustment. Adjustment sequence aborted. hr:0x%08x\n",
HRESULT_FROM_WIN32(GetLastError()));
return;
}
(void)QueryPerformanceFrequency(&liPerfCounterFrequency);
printf("System Performance Counter Frequency: %I64u\n",
liPerfCounterFrequency.QuadPart);
dwNewAdjustmentUnits = (DWORD)(((float) dwPPMAdjustment * liPerfCounterFrequency.QuadPart/ cMicroSecondsPerSecond));
printf("Adjusting the system clock by +%d PPM (+%d new units)\n",
dwPPMAdjustment, dwNewAdjustmentUnits);
if (!SetSystemTimeAdjustmentPrecise(ullCurrentAdjustment + dwNewAdjustmentUnits, FALSE))
{
printf("Failed to set the system time adjustment. hr:0x%08x\n",
HRESULT_FROM_WIN32(GetLastError()));
}
PrintCurrentClockAdjustments();
printf("Restoring system clock adjustment settings\n");
if (!SetSystemTimeAdjustmentPrecise(ullCurrentAdjustment, FALSE))
{
printf("Failed to set the system time adjustment. hr:0x%08x\n",
HRESULT_FROM_WIN32(GetLastError()));
}
PrintCurrentClockAdjustments();
printf("Adjusting the system clock by -%d PPM (-%d new units)\n",
dwPPMAdjustment, dwNewAdjustmentUnits);
if (!SetSystemTimeAdjustmentPrecise(ullCurrentAdjustment - dwNewAdjustmentUnits, FALSE))
{
printf("Failed to set the system time adjustment. hr:0x%08x\n",
HRESULT_FROM_WIN32(GetLastError()));
}
PrintCurrentClockAdjustments();
printf("Restoring system clock adjustment settings\n");
if (!SetSystemTimeAdjustmentPrecise(ullCurrentAdjustment, FALSE))
{
printf("Failed to set the system time adjustment. hr:0x%08x\n",
HRESULT_FROM_WIN32(GetLastError()));
}
PrintCurrentClockAdjustments();
printf("Adjustment sequence complete\n\n");
}
要求
最低受支持的客户端 | Windows 10 [仅限桌面应用] |
最低受支持的服务器 | Windows Server 2016 [仅限桌面应用] |
目标平台 | Windows |
标头 | sysinfoapi.h |
Library | Mincore.lib |
DLL | Api-ms-win-core-version-l1-2-3.dll |