Alexandre Julliard : kernel32: Implement the memory resource notification functions.

Alexandre Julliard julliard at winehq.org
Mon Mar 12 11:59:56 CDT 2012


Module: wine
Branch: master
Commit: aeaf18077e42b23ff96cbd1192cb47948c767708
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=aeaf18077e42b23ff96cbd1192cb47948c767708

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Mon Mar 12 10:33:32 2012 +0100

kernel32: Implement the memory resource notification functions.

---

 dlls/kernel32/sync.c       |   60 +++++++++++++++++++++++++++++++++++++------
 dlls/kernel32/tests/sync.c |   39 ++++++++++++++++++++++++++++
 include/winbase.h          |    1 +
 3 files changed, 91 insertions(+), 9 deletions(-)

diff --git a/dlls/kernel32/sync.c b/dlls/kernel32/sync.c
index acbfab0..08ea8cc 100644
--- a/dlls/kernel32/sync.c
+++ b/dlls/kernel32/sync.c
@@ -2179,21 +2179,63 @@ BOOL WINAPI BindIoCompletionCallback( HANDLE FileHandle, LPOVERLAPPED_COMPLETION
 /***********************************************************************
  *           CreateMemoryResourceNotification   (KERNEL32.@)
  */
-HANDLE WINAPI CreateMemoryResourceNotification(MEMORY_RESOURCE_NOTIFICATION_TYPE nt)
-{
-    FIXME("(%d) stub\n", nt);
-    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-    return NULL;
+HANDLE WINAPI CreateMemoryResourceNotification(MEMORY_RESOURCE_NOTIFICATION_TYPE type)
+{
+    static const WCHAR lowmemW[] =
+        {'\\','K','e','r','n','e','l','O','b','j','e','c','t','s',
+         '\\','L','o','w','M','e','m','o','r','y','C','o','n','d','i','t','i','o','n',0};
+    static const WCHAR highmemW[] =
+        {'\\','K','e','r','n','e','l','O','b','j','e','c','t','s',
+         '\\','H','i','g','h','M','e','m','o','r','y','C','o','n','d','i','t','i','o','n',0};
+    HANDLE ret;
+    UNICODE_STRING nameW;
+    OBJECT_ATTRIBUTES attr;
+    NTSTATUS status;
+
+    switch (type)
+    {
+    case LowMemoryResourceNotification:
+        RtlInitUnicodeString( &nameW, lowmemW );
+        break;
+    case HighMemoryResourceNotification:
+        RtlInitUnicodeString( &nameW, highmemW );
+        break;
+    default:
+        SetLastError( ERROR_INVALID_PARAMETER );
+        return 0;
+    }
+
+    attr.Length                   = sizeof(attr);
+    attr.RootDirectory            = 0;
+    attr.ObjectName               = &nameW;
+    attr.Attributes               = 0;
+    attr.SecurityDescriptor       = NULL;
+    attr.SecurityQualityOfService = NULL;
+    status = NtOpenEvent( &ret, EVENT_ALL_ACCESS, &attr );
+    if (status != STATUS_SUCCESS)
+    {
+        SetLastError( RtlNtStatusToDosError(status) );
+        return 0;
+    }
+    return ret;
 }
 
 /***********************************************************************
  *          QueryMemoryResourceNotification   (KERNEL32.@)
  */
-BOOL WINAPI QueryMemoryResourceNotification(HANDLE rnh, PBOOL rs)
+BOOL WINAPI QueryMemoryResourceNotification(HANDLE handle, PBOOL state)
 {
-    FIXME("(%p, %p) stub\n", rnh, rs);
-    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-    return 0;
+    switch (WaitForSingleObject( handle, 0 ))
+    {
+    case WAIT_OBJECT_0:
+        *state = TRUE;
+        return TRUE;
+    case WAIT_TIMEOUT:
+        *state = FALSE;
+        return TRUE;
+    }
+    SetLastError( ERROR_INVALID_PARAMETER );
+    return FALSE;
 }
 
 #ifdef __i386__
diff --git a/dlls/kernel32/tests/sync.c b/dlls/kernel32/tests/sync.c
index 07bc2ca..3965458 100644
--- a/dlls/kernel32/tests/sync.c
+++ b/dlls/kernel32/tests/sync.c
@@ -35,6 +35,8 @@ static HANDLE (WINAPI *pCreateWaitableTimerA)(SECURITY_ATTRIBUTES*,BOOL,LPCSTR);
 static BOOL   (WINAPI *pDeleteTimerQueueEx)(HANDLE, HANDLE);
 static BOOL   (WINAPI *pDeleteTimerQueueTimer)(HANDLE, HANDLE, HANDLE);
 static HANDLE (WINAPI *pOpenWaitableTimerA)(DWORD,BOOL,LPCSTR);
+static HANDLE (WINAPI *pCreateMemoryResourceNotification)(MEMORY_RESOURCE_NOTIFICATION_TYPE);
+static BOOL   (WINAPI *pQueryMemoryResourceNotification)(HANDLE, PBOOL);
 
 static void test_signalandwait(void)
 {
@@ -300,6 +302,8 @@ static void test_event(void)
     SECURITY_ATTRIBUTES sa;
     SECURITY_DESCRIPTOR sd;
     ACL acl;
+    DWORD ret;
+    BOOL val;
 
     /* no sd */
     handle = CreateEventA(NULL, FALSE, FALSE, __FILE__ ": Test Event");
@@ -360,6 +364,39 @@ static void test_event(void)
     ok( GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %u\n", GetLastError());
 
     CloseHandle( handle );
+
+    /* resource notifications are events too */
+
+    if (!pCreateMemoryResourceNotification || !pQueryMemoryResourceNotification)
+    {
+        trace( "memory resource notifications not supported\n" );
+        return;
+    }
+    handle = pCreateMemoryResourceNotification( HighMemoryResourceNotification + 1 );
+    ok( !handle, "CreateMemoryResourceNotification succeeded\n" );
+    ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
+    ret = pQueryMemoryResourceNotification( handle, &val );
+    ok( !ret, "QueryMemoryResourceNotification succeeded\n" );
+    ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
+
+    handle = pCreateMemoryResourceNotification( LowMemoryResourceNotification );
+    ok( handle != 0, "CreateMemoryResourceNotification failed err %u\n", GetLastError() );
+    ret = WaitForSingleObject( handle, 10 );
+    ok( ret == WAIT_OBJECT_0 || ret == WAIT_TIMEOUT, "WaitForSingleObject wrong ret %u\n", ret );
+
+    val = ~0;
+    ret = pQueryMemoryResourceNotification( handle, &val );
+    ok( ret, "QueryMemoryResourceNotification failed err %u\n", GetLastError() );
+    ok( val == FALSE || val == TRUE, "wrong value %u\n", val );
+    ret = CloseHandle( handle );
+    ok( ret, "CloseHandle failed err %u\n", GetLastError() );
+
+    handle = CreateEventA(NULL, FALSE, FALSE, __FILE__ ": Test Event");
+    val = ~0;
+    ret = pQueryMemoryResourceNotification( handle, &val );
+    ok( ret, "QueryMemoryResourceNotification failed err %u\n", GetLastError() );
+    ok( val == FALSE || val == TRUE, "wrong value %u\n", val );
+    CloseHandle( handle );
 }
 
 static void test_semaphore(void)
@@ -1074,6 +1111,8 @@ START_TEST(sync)
     pDeleteTimerQueueEx = (void*)GetProcAddress(hdll, "DeleteTimerQueueEx");
     pDeleteTimerQueueTimer = (void*)GetProcAddress(hdll, "DeleteTimerQueueTimer");
     pOpenWaitableTimerA = (void*)GetProcAddress(hdll, "OpenWaitableTimerA");
+    pCreateMemoryResourceNotification = (void *)GetProcAddress(hdll, "CreateMemoryResourceNotification");
+    pQueryMemoryResourceNotification = (void *)GetProcAddress(hdll, "QueryMemoryResourceNotification");
 
     test_signalandwait();
     test_mutex();
diff --git a/include/winbase.h b/include/winbase.h
index 6ec9230..492c63b 100644
--- a/include/winbase.h
+++ b/include/winbase.h
@@ -2021,6 +2021,7 @@ WINBASEAPI BOOL        WINAPI QueryFullProcessImageNameA(HANDLE,DWORD,LPSTR,PDWO
 WINBASEAPI BOOL        WINAPI QueryFullProcessImageNameW(HANDLE,DWORD,LPWSTR,PDWORD);
 #define                       QueryFullProcessImageName WINELIB_NAME_AW(QueryFullProcessImageName)
 WINBASEAPI BOOL        WINAPI QueryInformationJobObject(HANDLE,JOBOBJECTINFOCLASS,LPVOID,DWORD,DWORD*);
+WINBASEAPI BOOL        WINAPI QueryMemoryResourceNotification(HANDLE,PBOOL);
 WINBASEAPI BOOL        WINAPI QueryPerformanceCounter(LARGE_INTEGER*);
 WINBASEAPI BOOL        WINAPI QueryPerformanceFrequency(LARGE_INTEGER*);
 WINBASEAPI DWORD       WINAPI QueueUserAPC(PAPCFUNC,HANDLE,ULONG_PTR);




More information about the wine-cvs mailing list