From: "Hao Peng" Subject: [PATCH] iphlpapi: call SetLastError in NotifyAddrChange/NotifyRouteChange(try 2) Message-Id: Date: Tue, 4 Nov 2014 15:16:49 +0800 call SetLastError in NotifyAddrChange/NotifyRouteChange, to make apps can get WSA_IO_PENDING error code after async operation through GetLastError. Thanks to Sebastian Lackner for comments. superseded patch 107390. --- dlls/iphlpapi/iphlpapi_main.c | 18 ++++++++++++++++-- dlls/iphlpapi/tests/iphlpapi.c | 39 +++++++++++++++++++++++---------------- 2 files changed, 39 insertions(+), 18 deletions(-) diff --git a/dlls/iphlpapi/iphlpapi_main.c b/dlls/iphlpapi/iphlpapi_main.c index c06b69f..c3bc713 100644 --- a/dlls/iphlpapi/iphlpapi_main.c +++ b/dlls/iphlpapi/iphlpapi_main.c @@ -2285,9 +2285,15 @@ DWORD WINAPI IpRenewAddress(PIP_ADAPTER_INDEX_MAP AdapterInfo) */ DWORD WINAPI NotifyAddrChange(PHANDLE Handle, LPOVERLAPPED overlapped) { + if (!overlapped) + { + FIXME("Synchronous method not supported\n"); + return ERROR_NOT_SUPPORTED; + } FIXME("(Handle %p, overlapped %p): stub\n", Handle, overlapped); if (Handle) *Handle = INVALID_HANDLE_VALUE; - if (overlapped) ((IO_STATUS_BLOCK *) overlapped)->u.Status = STATUS_PENDING; + ((IO_STATUS_BLOCK *) overlapped)->u.Status = STATUS_PENDING; + SetLastError(WSA_IO_PENDING); return ERROR_IO_PENDING; } @@ -2323,8 +2329,16 @@ DWORD WINAPI NotifyIpInterfaceChange(ULONG family, PVOID callback, PVOID context */ DWORD WINAPI NotifyRouteChange(PHANDLE Handle, LPOVERLAPPED overlapped) { + if (!overlapped) + { + FIXME("Synchronous method not supported\n"); + return ERROR_NOT_SUPPORTED; + } FIXME("(Handle %p, overlapped %p): stub\n", Handle, overlapped); - return ERROR_NOT_SUPPORTED; + if (Handle) *Handle = INVALID_HANDLE_VALUE; + ((IO_STATUS_BLOCK *) overlapped)->u.Status = STATUS_PENDING; + SetLastError(WSA_IO_PENDING); + return ERROR_IO_PENDING; } diff --git a/dlls/iphlpapi/tests/iphlpapi.c b/dlls/iphlpapi/tests/iphlpapi.c index b2d81c0..259757a 100644 --- a/dlls/iphlpapi/tests/iphlpapi.c +++ b/dlls/iphlpapi/tests/iphlpapi.c @@ -46,6 +46,8 @@ #define ICMP_MINLEN 8 /* copied from dlls/iphlpapi/ip_icmp.h file */ +typedef DWORD (WINAPI *LP_NOTIFYCHANGE)(PHANDLE,LPOVERLAPPED); + static HMODULE hLibrary = NULL; static DWORD (WINAPI *pGetNumberOfInterfaces)(PDWORD); @@ -70,7 +72,8 @@ static DWORD (WINAPI *pGetTcpTable)(PMIB_TCPTABLE,PDWORD,BOOL); static DWORD (WINAPI *pGetUdpTable)(PMIB_UDPTABLE,PDWORD,BOOL); static DWORD (WINAPI *pGetPerAdapterInfo)(ULONG,PIP_PER_ADAPTER_INFO,PULONG); static DWORD (WINAPI *pGetAdaptersAddresses)(ULONG,ULONG,PVOID,PIP_ADAPTER_ADDRESSES,PULONG); -static DWORD (WINAPI *pNotifyAddrChange)(PHANDLE,LPOVERLAPPED); +static LP_NOTIFYCHANGE pNotifyAddrChange; +static LP_NOTIFYCHANGE pNotifyRouteChange; static BOOL (WINAPI *pCancelIPChangeNotify)(LPOVERLAPPED); static DWORD (WINAPI *pGetExtendedTcpTable)(PVOID,PDWORD,BOOL,ULONG,TCP_TABLE_CLASS,ULONG); static DWORD (WINAPI *pGetExtendedUdpTable)(PVOID,PDWORD,BOOL,ULONG,UDP_TABLE_CLASS,ULONG); @@ -105,6 +108,7 @@ static void loadIPHlpApi(void) pGetPerAdapterInfo = (void *)GetProcAddress(hLibrary, "GetPerAdapterInfo"); pGetAdaptersAddresses = (void *)GetProcAddress(hLibrary, "GetAdaptersAddresses"); pNotifyAddrChange = (void *)GetProcAddress(hLibrary, "NotifyAddrChange"); + pNotifyRouteChange = (void *)GetProcAddress(hLibrary, "NotifyRouteChange"); pCancelIPChangeNotify = (void *)GetProcAddress(hLibrary, "CancelIPChangeNotify"); pGetExtendedTcpTable = (void *)GetProcAddress(hLibrary, "GetExtendedTcpTable"); pGetExtendedUdpTable = (void *)GetProcAddress(hLibrary, "GetExtendedUdpTable"); @@ -1197,16 +1201,16 @@ static void testGetPerAdapterInfo(void) HeapFree( GetProcessHeap(), 0, buffer ); } -static void testNotifyAddrChange(void) +static void testNotifyChange(LP_NOTIFYCHANGE pNotifyChange, LPCSTR name) { DWORD ret, bytes; OVERLAPPED overlapped; HANDLE handle; BOOL success; - if (!pNotifyAddrChange) + if (!pNotifyChange) { - win_skip("NotifyAddrChange not present\n"); + win_skip("%s not present\n", name); return; } if (!pCancelIPChangeNotify) @@ -1217,15 +1221,15 @@ static void testNotifyAddrChange(void) handle = NULL; ZeroMemory(&overlapped, sizeof(overlapped)); - ret = pNotifyAddrChange(&handle, &overlapped); + ret = pNotifyChange(&handle, &overlapped); if (ret == ERROR_NOT_SUPPORTED) { - win_skip("NotifyAddrChange is not supported\n"); + win_skip("%s is not supported\n", name); return; } - ok(ret == ERROR_IO_PENDING, "NotifyAddrChange returned %d, expected ERROR_IO_PENDING\n", ret); + ok(ret == ERROR_IO_PENDING, "%s returned %d, expected ERROR_IO_PENDING\n", name, ret); ret = GetLastError(); - todo_wine ok(ret == ERROR_IO_PENDING, "GetLastError returned %d, expected ERROR_IO_PENDING\n", ret); + ok(ret == ERROR_IO_PENDING, "GetLastError returned %d, expected ERROR_IO_PENDING\n", ret); success = pCancelIPChangeNotify(&overlapped); todo_wine ok(success == TRUE, "CancelIPChangeNotify returned FALSE, expected TRUE\n"); @@ -1236,15 +1240,16 @@ static void testNotifyAddrChange(void) handle = NULL; ZeroMemory(&overlapped, sizeof(overlapped)); overlapped.hEvent = CreateEventW(NULL, FALSE, FALSE, NULL); - ret = pNotifyAddrChange(&handle, &overlapped); - ok(ret == ERROR_IO_PENDING, "NotifyAddrChange returned %d, expected ERROR_IO_PENDING\n", ret); - todo_wine ok(handle != INVALID_HANDLE_VALUE, "NotifyAddrChange returned invalid file handle\n"); + ret = pNotifyChange(&handle, &overlapped); + ok(ret == ERROR_IO_PENDING, "%s returned %d, expected ERROR_IO_PENDING\n", name, ret); + todo_wine ok(handle != INVALID_HANDLE_VALUE, "%s returned invalid file handle\n", name); success = GetOverlappedResult(handle, &overlapped, &bytes, FALSE); ok(success == FALSE, "GetOverlappedResult returned TRUE, expected FALSE\n"); ret = GetLastError(); ok(ret == ERROR_IO_INCOMPLETE, "GetLastError returned %d, expected ERROR_IO_INCOMPLETE\n", ret); success = pCancelIPChangeNotify(&overlapped); todo_wine ok(success == TRUE, "CancelIPChangeNotify returned FALSE, expected TRUE\n"); + CloseHandle(overlapped.hEvent); if (winetest_interactive) { @@ -1253,10 +1258,11 @@ static void testNotifyAddrChange(void) overlapped.hEvent = CreateEventW(NULL, FALSE, FALSE, NULL); trace("Testing asynchronous ipv4 address change notification. Please " "change the ipv4 address of one of your network interfaces\n"); - ret = pNotifyAddrChange(&handle, &overlapped); - ok(ret == ERROR_IO_PENDING, "NotifyAddrChange returned %d, expected NO_ERROR\n", ret); + ret = pNotifyChange(&handle, &overlapped); + ok(ret == ERROR_IO_PENDING, "%s returned %d, expected NO_ERROR\n", name, ret); success = GetOverlappedResult(handle, &overlapped, &bytes, TRUE); ok(success == TRUE, "GetOverlappedResult returned FALSE, expected TRUE\n"); + CloseHandle(overlapped.hEvent); } /* test synchronous functionality */ @@ -1264,8 +1270,8 @@ static void testNotifyAddrChange(void) { trace("Testing synchronous ipv4 address change notification. Please " "change the ipv4 address of one of your network interfaces\n"); - ret = pNotifyAddrChange(NULL, NULL); - todo_wine ok(ret == NO_ERROR, "NotifyAddrChange returned %d, expected NO_ERROR\n", ret); + ret = pNotifyChange(NULL, NULL); + todo_wine ok(ret == NO_ERROR, "%s returned %d, expected NO_ERROR\n", name, ret); } } @@ -1285,7 +1291,8 @@ UnenableRouter static void testWin2KFunctions(void) { testGetPerAdapterInfo(); - testNotifyAddrChange(); + testNotifyChange(pNotifyAddrChange, "NotifyAddrChange"); + testNotifyChange(pNotifyRouteChange, "NotifyRouteChange"); } static void test_GetAdaptersAddresses(void)