Author: hbelusca
Date: Sun Mar 5 00:40:22 2017
New Revision: 74068
URL:
http://svn.reactos.org/svn/reactos?rev=74068&view=rev
Log:
[WS2_32]
- Fix pointers verification in WSALookupServiceNextW and WSALookupServiceNextA;
- In WSALookupServiceNextA: Perform extra checks to see whether we failed the first local
buffer allocation, and if so, retrieve the needed size by calling a first time
WSALookupServiceNextW, then reallocate the temp buffer and redo a WSALookupServiceNextW
call (if it still fails, then we bail out).
CID 513448.
Modified:
trunk/reactos/dll/win32/ws2_32/src/rnr.c
Modified: trunk/reactos/dll/win32/ws2_32/src/rnr.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/ws2_32/src/rnr.c…
==============================================================================
--- trunk/reactos/dll/win32/ws2_32/src/rnr.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/ws2_32/src/rnr.c [iso-8859-1] Sun Mar 5 00:40:22 2017
@@ -403,9 +403,12 @@
return SOCKET_ERROR;
}
- /* Verify pointers */
+ /*
+ * Verify pointers. Note that the size of the buffer
+ * pointed by lpqsResults is given by *lpdwBufferLength.
+ */
if (IsBadReadPtr(lpdwBufferLength, sizeof(*lpdwBufferLength)) ||
- IsBadWritePtr(lpqsResults, sizeof(*lpqsResults)))
+ IsBadWritePtr(lpqsResults, *lpdwBufferLength))
{
/* It is invalid; fail */
SetLastError(WSAEFAULT);
@@ -449,9 +452,12 @@
DPRINT("WSALookupServiceNextA: %lx\n", hLookup);
- /* Verify pointers */
+ /*
+ * Verify pointers. Note that the size of the buffer
+ * pointed by lpqsResults is given by *lpdwBufferLength.
+ */
if (IsBadReadPtr(lpdwBufferLength, sizeof(*lpdwBufferLength)) ||
- IsBadWritePtr(lpqsResults, sizeof(*lpqsResults)))
+ IsBadWritePtr(lpqsResults, *lpdwBufferLength))
{
/* It is invalid; fail */
SetLastError(WSAEFAULT);
@@ -465,13 +471,24 @@
{
/* Allocate the buffer we'll use */
UnicodeQuerySet = HeapAlloc(WsSockHeap, 0, UnicodeQuerySetSize);
- if (!UnicodeQuerySet) UnicodeQuerySetSize = 0;
+ if (!UnicodeQuerySet)
+ {
+ /*
+ * We failed, possibly because the specified size was too large?
+ * Retrieve the needed buffer size with the WSALookupServiceNextW
+ * call and retry again a second time.
+ */
+ UnicodeQuerySetSize = 0;
+ }
}
else
{
- /* His buffer is too small */
+ /*
+ * The buffer is too small. Retrieve the needed buffer size with
+ * the WSALookupServiceNextW call and return it to the caller.
+ */
+ UnicodeQuerySet = NULL;
UnicodeQuerySetSize = 0;
- UnicodeQuerySet = NULL;
}
/* Call the Unicode Function */
@@ -479,13 +496,39 @@
dwControlFlags,
&UnicodeQuerySetSize,
UnicodeQuerySet);
+
+ /*
+ * Check whether we actually just retrieved the needed buffer size
+ * because our previous local allocation did fail. If so, allocate
+ * a new buffer and retry again.
+ */
+ if ( (!UnicodeQuerySet) && (*lpdwBufferLength >= sizeof(WSAQUERYSETW))
&&
+ (ErrorCode == SOCKET_ERROR) && (GetLastError() == WSAEFAULT) )
+ {
+ /* Allocate the buffer we'll use */
+ UnicodeQuerySet = HeapAlloc(WsSockHeap, 0, UnicodeQuerySetSize);
+ if (UnicodeQuerySet)
+ {
+ /* Call the Unicode Function */
+ ErrorCode = WSALookupServiceNextW(hLookup,
+ dwControlFlags,
+ &UnicodeQuerySetSize,
+ UnicodeQuerySet);
+ }
+ /*
+ * Otherwise the allocation failed and we
+ * fall back into the error checks below.
+ */
+ }
+
if (ErrorCode == ERROR_SUCCESS)
{
- /* Not convert to ANSI */
+ /* Now convert back to ANSI */
ErrorCode = MapUnicodeQuerySetToAnsi(UnicodeQuerySet,
lpdwBufferLength,
lpqsResults);
- if (ErrorCode != ERROR_SUCCESS) SetLastError(ErrorCode);
+ if (ErrorCode != ERROR_SUCCESS)
+ SetLastError(ErrorCode);
}
else
{
@@ -499,10 +542,11 @@
}
/* If we had a local buffer, free it */
- if (UnicodeQuerySet) HeapFree(WsSockHeap, 0, UnicodeQuerySet);
+ if (UnicodeQuerySet)
+ HeapFree(WsSockHeap, 0, UnicodeQuerySet);
/* Return to caller */
- return ErrorCode == ERROR_SUCCESS ? ErrorCode : SOCKET_ERROR;
+ return (ErrorCode == ERROR_SUCCESS) ? ErrorCode : SOCKET_ERROR;
}
/*