diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c index 03bf45d0a09..978919146cd 100644 --- a/dlls/ntdll/nt.c +++ b/dlls/ntdll/nt.c @@ -2937,6 +2937,19 @@ NTSTATUS WINAPI NtQuerySystemInformation( FIXME("info_class SYSTEM_INTERRUPT_INFORMATION\n"); } break; + case SystemTimeAdjustmentInformation: + { + SYSTEM_TIME_ADJUSTMENT_QUERY query = { 156250, 156250, TRUE }; + + len = sizeof(query); + if (Length == len) + { + if (!SystemInformation) ret = STATUS_ACCESS_VIOLATION; + else memcpy( SystemInformation, &query, len ); + } + else ret = STATUS_INFO_LENGTH_MISMATCH; + } + break; case SystemKernelDebuggerInformation: { SYSTEM_KERNEL_DEBUGGER_INFORMATION skdi; diff --git a/dlls/ntdll/tests/info.c b/dlls/ntdll/tests/info.c index 23d18b39837..f923cc7743f 100644 --- a/dlls/ntdll/tests/info.c +++ b/dlls/ntdll/tests/info.c @@ -23,6 +23,7 @@ #include static NTSTATUS (WINAPI * pNtQuerySystemInformation)(SYSTEM_INFORMATION_CLASS, PVOID, ULONG, PULONG); +static NTSTATUS (WINAPI * pNtSetSystemInformation)(SYSTEM_INFORMATION_CLASS, PVOID, ULONG); static NTSTATUS (WINAPI * pRtlGetNativeSystemInformation)(SYSTEM_INFORMATION_CLASS, PVOID, ULONG, PULONG); static NTSTATUS (WINAPI * pNtQuerySystemInformationEx)(SYSTEM_INFORMATION_CLASS, void*, ULONG, void*, ULONG, ULONG*); static NTSTATUS (WINAPI * pNtPowerInformation)(POWER_INFORMATION_LEVEL, PVOID, ULONG, PVOID, ULONG); @@ -76,6 +77,7 @@ static BOOL InitFunctionPtrs(void) } NTDLL_GET_PROC(NtQuerySystemInformation); + NTDLL_GET_PROC(NtSetSystemInformation); NTDLL_GET_PROC(RtlGetNativeSystemInformation); NTDLL_GET_PROC(NtPowerInformation); NTDLL_GET_PROC(NtQueryInformationProcess); @@ -740,6 +742,40 @@ static void test_query_interrupt(void) HeapFree( GetProcessHeap(), 0, sii); } +static void test_time_adjustment(void) +{ + SYSTEM_TIME_ADJUSTMENT_QUERY query; + SYSTEM_TIME_ADJUSTMENT adjust; + NTSTATUS status; + ULONG len; + + memset( &query, 0xcc, sizeof(query) ); + status = pNtQuerySystemInformation( SystemTimeAdjustmentInformation, &query, sizeof(query), &len ); + ok( status == STATUS_SUCCESS, "got %08x\n", status ); + ok( len == sizeof(query) || broken(!len) /* winxp */, "wrong len %u\n", len ); + ok( query.TimeAdjustmentDisabled == TRUE || query.TimeAdjustmentDisabled == FALSE, + "wrong value %x\n", query.TimeAdjustmentDisabled ); + + status = pNtQuerySystemInformation( SystemTimeAdjustmentInformation, &query, sizeof(query)-1, &len ); + ok( status == STATUS_INFO_LENGTH_MISMATCH, "got %08x\n", status ); + ok( len == sizeof(query) || broken(!len) /* winxp */, "wrong len %u\n", len ); + + status = pNtQuerySystemInformation( SystemTimeAdjustmentInformation, &query, sizeof(query)+1, &len ); + ok( status == STATUS_INFO_LENGTH_MISMATCH, "got %08x\n", status ); + ok( len == sizeof(query) || broken(!len) /* winxp */, "wrong len %u\n", len ); + + adjust.TimeAdjustment = query.TimeAdjustment; + adjust.TimeAdjustmentDisabled = query.TimeAdjustmentDisabled; + status = pNtSetSystemInformation( SystemTimeAdjustmentInformation, &adjust, sizeof(adjust) ); + ok( status == STATUS_SUCCESS || status == STATUS_PRIVILEGE_NOT_HELD, "got %08x\n", status ); + status = pNtSetSystemInformation( SystemTimeAdjustmentInformation, &adjust, sizeof(adjust)-1 ); + todo_wine + ok( status == STATUS_INFO_LENGTH_MISMATCH, "got %08x\n", status ); + status = pNtSetSystemInformation( SystemTimeAdjustmentInformation, &adjust, sizeof(adjust)+1 ); + todo_wine + ok( status == STATUS_INFO_LENGTH_MISMATCH, "got %08x\n", status ); +} + static void test_query_kerndebug(void) { NTSTATUS status; @@ -2632,6 +2668,10 @@ START_TEST(info) trace("Starting test_query_interrupt()\n"); test_query_interrupt(); + /* 0x1c SystemTimeAdjustmentInformation */ + trace("Starting test_time_adjustment()\n"); + test_time_adjustment(); + /* 0x23 SystemKernelDebuggerInformation */ trace("Starting test_query_kerndebug()\n"); test_query_kerndebug(); diff --git a/include/winternl.h b/include/winternl.h index 14455946ba2..edcbc5ca13d 100644 --- a/include/winternl.h +++ b/include/winternl.h @@ -1624,6 +1624,12 @@ typedef struct _SYSTEM_REGISTRY_QUOTA_INFORMATION { PVOID Reserved1; } SYSTEM_REGISTRY_QUOTA_INFORMATION, *PSYSTEM_REGISTRY_QUOTA_INFORMATION; +typedef struct _SYSTEM_TIME_ADJUSTMENT_QUERY { + ULONG TimeAdjustment; + ULONG TimeIncrement; + BOOLEAN TimeAdjustmentDisabled; +} SYSTEM_TIME_ADJUSTMENT_QUERY, *PSYSTEM_TIME_ADJUSTMENT_QUERY; + typedef struct _SYSTEM_TIME_ADJUSTMENT { ULONG TimeAdjustment; BOOLEAN TimeAdjustmentDisabled;