Commit 7bd852c6 authored by Jacek Caban's avatar Jacek Caban Committed by Alexandre Julliard

ntdll: Added NtNotifyChangeMultipleKeys implementation.

parent e0d51609
...@@ -205,7 +205,7 @@ ...@@ -205,7 +205,7 @@
# @ stub NtModifyBootEntry # @ stub NtModifyBootEntry
@ stdcall NtNotifyChangeDirectoryFile(long long ptr ptr ptr ptr long long long) @ stdcall NtNotifyChangeDirectoryFile(long long ptr ptr ptr ptr long long long)
@ stdcall NtNotifyChangeKey(long long ptr ptr ptr long long ptr long long) @ stdcall NtNotifyChangeKey(long long ptr ptr ptr long long ptr long long)
# @ stub NtNotifyChangeMultipleKeys @ stdcall NtNotifyChangeMultipleKeys(long long ptr long ptr ptr ptr long long ptr long long)
@ stdcall NtOpenDirectoryObject(long long long) @ stdcall NtOpenDirectoryObject(long long long)
@ stdcall NtOpenEvent(long long long) @ stdcall NtOpenEvent(long long long)
@ stub NtOpenEventPair @ stub NtOpenEventPair
...@@ -1121,7 +1121,7 @@ ...@@ -1121,7 +1121,7 @@
# @ stub ZwModifyBootEntry # @ stub ZwModifyBootEntry
@ stdcall ZwNotifyChangeDirectoryFile(long long ptr ptr ptr ptr long long long) NtNotifyChangeDirectoryFile @ stdcall ZwNotifyChangeDirectoryFile(long long ptr ptr ptr ptr long long long) NtNotifyChangeDirectoryFile
@ stdcall ZwNotifyChangeKey(long long ptr ptr ptr long long ptr long long) NtNotifyChangeKey @ stdcall ZwNotifyChangeKey(long long ptr ptr ptr long long ptr long long) NtNotifyChangeKey
# @ stub ZwNotifyChangeMultipleKeys @ stdcall ZwNotifyChangeMultipleKeys(long long ptr long ptr ptr ptr long long ptr long long) NtNotifyChangeMultipleKeys
@ stdcall ZwOpenDirectoryObject(long long long) NtOpenDirectoryObject @ stdcall ZwOpenDirectoryObject(long long long) NtOpenDirectoryObject
@ stdcall ZwOpenEvent(long long long) NtOpenEvent @ stdcall ZwOpenEvent(long long long) NtOpenEvent
@ stub ZwOpenEventPair @ stub ZwOpenEventPair
......
...@@ -633,28 +633,30 @@ NTSTATUS WINAPI NtLoadKey( const OBJECT_ATTRIBUTES *attr, OBJECT_ATTRIBUTES *fil ...@@ -633,28 +633,30 @@ NTSTATUS WINAPI NtLoadKey( const OBJECT_ATTRIBUTES *attr, OBJECT_ATTRIBUTES *fil
} }
/****************************************************************************** /******************************************************************************
* NtNotifyChangeKey [NTDLL.@] * NtNotifyChangeMultipleKeys [NTDLL.@]
* ZwNotifyChangeKey [NTDLL.@] * ZwNotifyChangeMultipleKeys [NTDLL.@]
*/ */
NTSTATUS WINAPI NtNotifyChangeKey( NTSTATUS WINAPI NtNotifyChangeMultipleKeys(
IN HANDLE KeyHandle, HANDLE KeyHandle,
IN HANDLE Event, ULONG Count,
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, OBJECT_ATTRIBUTES *SubordinateObjects,
IN PVOID ApcContext OPTIONAL, HANDLE Event,
OUT PIO_STATUS_BLOCK IoStatusBlock, PIO_APC_ROUTINE ApcRoutine,
IN ULONG CompletionFilter, PVOID ApcContext,
IN BOOLEAN WatchSubtree, PIO_STATUS_BLOCK IoStatusBlock,
OUT PVOID ChangeBuffer, ULONG CompletionFilter,
IN ULONG Length, BOOLEAN WatchSubtree,
IN BOOLEAN Asynchronous) PVOID ChangeBuffer,
ULONG Length,
BOOLEAN Asynchronous)
{ {
NTSTATUS ret; NTSTATUS ret;
TRACE("(%p,%p,%p,%p,%p,0x%08x, 0x%08x,%p,0x%08x,0x%08x)\n", TRACE("(%p,%u,%p,%p,%p,%p,%p,0x%08x, 0x%08x,%p,0x%08x,0x%08x)\n",
KeyHandle, Event, ApcRoutine, ApcContext, IoStatusBlock, CompletionFilter, KeyHandle, Count, SubordinateObjects, Event, ApcRoutine, ApcContext, IoStatusBlock, CompletionFilter,
Asynchronous, ChangeBuffer, Length, WatchSubtree); Asynchronous, ChangeBuffer, Length, WatchSubtree);
if (ApcRoutine || ApcContext || ChangeBuffer || Length) if (Count || SubordinateObjects || ApcRoutine || ApcContext || ChangeBuffer || Length)
FIXME("Unimplemented optional parameter\n"); FIXME("Unimplemented optional parameter\n");
if (!Asynchronous) if (!Asynchronous)
...@@ -687,6 +689,27 @@ NTSTATUS WINAPI NtNotifyChangeKey( ...@@ -687,6 +689,27 @@ NTSTATUS WINAPI NtNotifyChangeKey(
} }
/****************************************************************************** /******************************************************************************
* NtNotifyChangeKey [NTDLL.@]
* ZwNotifyChangeKey [NTDLL.@]
*/
NTSTATUS WINAPI NtNotifyChangeKey(
IN HANDLE KeyHandle,
IN HANDLE Event,
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
IN PVOID ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN ULONG CompletionFilter,
IN BOOLEAN WatchSubtree,
OUT PVOID ChangeBuffer,
IN ULONG Length,
IN BOOLEAN Asynchronous)
{
return NtNotifyChangeMultipleKeys(KeyHandle, 0, NULL, Event, ApcRoutine, ApcContext,
IoStatusBlock, CompletionFilter, WatchSubtree,
ChangeBuffer, Length, Asynchronous);
}
/******************************************************************************
* NtQueryMultipleValueKey [NTDLL] * NtQueryMultipleValueKey [NTDLL]
* ZwQueryMultipleValueKey * ZwQueryMultipleValueKey
*/ */
......
...@@ -147,6 +147,8 @@ static LPVOID (WINAPI * pRtlAllocateHeap)(PVOID,ULONG,ULONG); ...@@ -147,6 +147,8 @@ static LPVOID (WINAPI * pRtlAllocateHeap)(PVOID,ULONG,ULONG);
static NTSTATUS (WINAPI * pRtlZeroMemory)(PVOID, ULONG); static NTSTATUS (WINAPI * pRtlZeroMemory)(PVOID, ULONG);
static NTSTATUS (WINAPI * pRtlpNtQueryValueKey)(HANDLE,ULONG*,PBYTE,DWORD*,void *); static NTSTATUS (WINAPI * pRtlpNtQueryValueKey)(HANDLE,ULONG*,PBYTE,DWORD*,void *);
static NTSTATUS (WINAPI * pNtNotifyChangeKey)(HANDLE,HANDLE,PIO_APC_ROUTINE,PVOID,PIO_STATUS_BLOCK,ULONG,BOOLEAN,PVOID,ULONG,BOOLEAN); static NTSTATUS (WINAPI * pNtNotifyChangeKey)(HANDLE,HANDLE,PIO_APC_ROUTINE,PVOID,PIO_STATUS_BLOCK,ULONG,BOOLEAN,PVOID,ULONG,BOOLEAN);
static NTSTATUS (WINAPI * pNtNotifyChangeMultipleKeys)(HANDLE,ULONG,OBJECT_ATTRIBUTES*,HANDLE,PIO_APC_ROUTINE,
void*,IO_STATUS_BLOCK*,ULONG,BOOLEAN,void*,ULONG,BOOLEAN);
static NTSTATUS (WINAPI * pNtWaitForSingleObject)(HANDLE,BOOLEAN,const LARGE_INTEGER*); static NTSTATUS (WINAPI * pNtWaitForSingleObject)(HANDLE,BOOLEAN,const LARGE_INTEGER*);
static HMODULE hntdll = 0; static HMODULE hntdll = 0;
...@@ -201,6 +203,7 @@ static BOOL InitFunctionPtrs(void) ...@@ -201,6 +203,7 @@ static BOOL InitFunctionPtrs(void)
/* optional functions */ /* optional functions */
pNtQueryLicenseValue = (void *)GetProcAddress(hntdll, "NtQueryLicenseValue"); pNtQueryLicenseValue = (void *)GetProcAddress(hntdll, "NtQueryLicenseValue");
pNtOpenKeyEx = (void *)GetProcAddress(hntdll, "NtOpenKeyEx"); pNtOpenKeyEx = (void *)GetProcAddress(hntdll, "NtOpenKeyEx");
pNtNotifyChangeMultipleKeys = (void *)GetProcAddress(hntdll, "NtNotifyChangeMultipleKeys");
return TRUE; return TRUE;
} }
...@@ -1516,7 +1519,6 @@ static void test_notify(void) ...@@ -1516,7 +1519,6 @@ static void test_notify(void)
NTSTATUS status; NTSTATUS status;
InitializeObjectAttributes(&attr, &winetestpath, 0, 0, 0); InitializeObjectAttributes(&attr, &winetestpath, 0, 0, 0);
status = pNtOpenKey(&key, KEY_ALL_ACCESS, &attr); status = pNtOpenKey(&key, KEY_ALL_ACCESS, &attr);
ok(status == STATUS_SUCCESS, "NtOpenKey Failed: 0x%08x\n", status); ok(status == STATUS_SUCCESS, "NtOpenKey Failed: 0x%08x\n", status);
...@@ -1543,8 +1545,40 @@ static void test_notify(void) ...@@ -1543,8 +1545,40 @@ static void test_notify(void)
status = pNtDeleteKey(subkey); status = pNtDeleteKey(subkey);
ok(status == STATUS_SUCCESS, "NtDeleteSubkey failed: %x\n", status); ok(status == STATUS_SUCCESS, "NtDeleteSubkey failed: %x\n", status);
pNtClose(subkey); pNtClose(subkey);
pNtClose(key); pNtClose(key);
if (pNtNotifyChangeMultipleKeys)
{
InitializeObjectAttributes(&attr, &winetestpath, 0, 0, 0);
status = pNtOpenKey(&key, KEY_ALL_ACCESS, &attr);
ok(status == STATUS_SUCCESS, "NtOpenKey Failed: 0x%08x\n", status);
status = pNtNotifyChangeMultipleKeys(key, 0, NULL, event, NULL, NULL, &iosb, REG_NOTIFY_CHANGE_NAME, FALSE, NULL, 0, TRUE);
ok(status == STATUS_PENDING, "NtNotifyChangeKey returned %x\n", status);
timeout.QuadPart = 0;
status = pNtWaitForSingleObject(event, FALSE, &timeout);
ok(status == STATUS_TIMEOUT, "NtWaitForSingleObject returned %x\n", status);
attr.RootDirectory = key;
attr.ObjectName = &str;
pRtlCreateUnicodeStringFromAsciiz(&str, "test_subkey");
status = pNtCreateKey(&subkey, GENERIC_ALL, &attr, 0, 0, 0, 0);
ok(status == STATUS_SUCCESS, "NtCreateKey failed: 0x%08x\n", status);
status = pNtWaitForSingleObject(event, FALSE, &timeout);
ok(status == STATUS_SUCCESS, "NtWaitForSingleObject returned %x\n", status);
status = pNtDeleteKey(subkey);
ok(status == STATUS_SUCCESS, "NtDeleteSubkey failed: %x\n", status);
pNtClose(subkey);
pNtClose(key);
}
else
{
win_skip("NtNotifyChangeMultipleKeys not available\n");
}
pNtClose(event); pNtClose(event);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment