[2/2] ws2_32: Add WSAEnumNameSpaceProviders[A|W] implementation

Bruno Jesus 00cpxxx at gmail.com
Wed Feb 26 22:22:39 CST 2014


The concept is based in WSAEnumProtocols. The main difference is that
the strings containing the name of the provider are allocated after
the struct and set as pointers in it.
-------------- next part --------------

---
 dlls/ws2_32/socket.c     | 150 +++++++++++++++++++++++++++++++++++++++++++++--
 dlls/ws2_32/tests/sock.c |  18 ------
 2 files changed, 146 insertions(+), 22 deletions(-)

diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c
index 2a2c809..9e9b1c4 100644
--- a/dlls/ws2_32/socket.c
+++ b/dlls/ws2_32/socket.c
@@ -203,6 +203,23 @@ static const INT valid_protocols[] =
 
 #define IS_IPX_PROTO(X) ((X) >= WS_NSPROTO_IPX && (X) <= WS_NSPROTO_IPX + 255)
 
+/* names of namespaces */
+static const WCHAR NameSpaceDns[]  = {'T', 'c', 'p', 'i', 'p', '\0'};
+static const WCHAR NameSpaceNla[]  = {'N', 'L', 'A', 'v', '1', '\0'};
+
+/* Taken from WinXP */
+static const GUID NameSpaceIdDNS = { 0x22059D40, 0x7E9E, 0x11CF,
+                                     { 0xAE, 0x5A, 0x00, 0xAA, 0x00, 0xA7, 0x11, 0x2B } };
+static const GUID NameSpaceIdNLA = { 0x6642243A, 0x3BA8, 0x4AA6,
+                                     { 0xBA, 0xA5, 0x2E, 0x0B, 0xD7, 0x1F, 0xDD, 0x83 } };
+
+static const INT valid_namespaces[] =
+{
+    NS_DNS,
+    NS_NLA,
+    0
+};
+
 #if defined(IP_UNICAST_IF) && defined(SO_ATTACH_FILTER)
 # define LINUX_BOUND_IF
 struct interface_filter {
@@ -1836,6 +1853,133 @@ static INT WS_EnumProtocols( BOOL unicode, const INT *protocols, LPWSAPROTOCOL_I
     return items;
 }
 
+/*****************************************************************************
+ *          WS_EnterSingleNameSpaceW [internal]
+ *
+ *    enters the namespace information of one given namespace into the given
+ *    buffer.
+ *
+ * RETURNS
+ *    TRUE if a namespace was entered into the buffer.
+ *
+ * BUGS
+ *    - only implemented for NS_DNS and NS_NLA, missing other stuff from Windows >= 7
+ */
+static BOOL WS_EnterSingleNameSpaceW( INT ns, WCHAR *strbase, INT *offset, WSANAMESPACE_INFOW* name )
+{
+    memset( name, 0, sizeof(WSANAMESPACE_INFOW) );
+    name->dwNameSpace = ns;
+    name->lpszIdentifier = strbase + *offset * sizeof(WCHAR);
+
+    switch (ns)
+    {
+    case NS_DNS:
+        name->NSProviderId = NameSpaceIdDNS;
+        name->fActive = 1;
+        name->dwVersion = 0;
+        strcpyW( name->lpszIdentifier, NameSpaceDns );
+        *offset += sizeof(NameSpaceDns);
+        break;
+
+    case NS_NLA:
+        name->NSProviderId = NameSpaceIdNLA;
+        name->fActive = 1;
+        name->dwVersion = 0;
+        strcpyW( name->lpszIdentifier, NameSpaceNla );
+        *offset += sizeof(NameSpaceNla);
+        break;
+
+    default:
+        FIXME("unknown name space <0x%08x>\n", ns);
+        name->lpszIdentifier[0] = '\0';
+        (*offset)++;
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
+/*****************************************************************************
+ *          WS_EnterSingleNameSpaceA [internal]
+ *
+ *    see function WS_EnterSingleNameSpaceW
+ *
+ */
+static BOOL WS_EnterSingleNameSpaceA( INT ns, char *strbase, INT *offset, WSANAMESPACE_INFOA* name )
+{
+    union _namespace
+    {
+        WSANAMESPACE_INFOW namew;
+        /* enough space for the name space string after the struct */
+        char data[sizeof(WSANAMESPACE_INFOW) + 64 * sizeof(WCHAR)];
+    } nsdata;
+    WCHAR *wstrbase = (WCHAR *)(nsdata.data + sizeof(WSANAMESPACE_INFOW));
+    INT ret, woffset = 0;
+    memset( name, 0, sizeof(WSANAMESPACE_INFOA) );
+
+    ret = WS_EnterSingleNameSpaceW( ns, wstrbase, &woffset, &nsdata.namew );
+    if (ret)
+    {
+        /* convert the structure from W to A */
+        memcpy( name, &nsdata.namew, FIELD_OFFSET( WSANAMESPACE_INFOA, lpszIdentifier ) );
+        /* copy the namespace name after the struct */
+        name->lpszIdentifier = strbase + *offset;
+        WideCharToMultiByte( CP_ACP, 0, nsdata.namew.lpszIdentifier, -1,
+                             name->lpszIdentifier, -1, NULL, NULL );
+        *offset += woffset;
+    }
+
+    return ret;
+}
+
+static INT WS_EnumNameSpace( BOOL unicode, LPWSANAMESPACE_INFOW buffer, LPDWORD len )
+{
+    INT i, items = 0, namesize = 0, offset;
+    DWORD size;
+    char *strbase;
+    WCHAR *wstrbase;
+    union _name
+    {
+      LPWSANAMESPACE_INFOA a;
+      LPWSANAMESPACE_INFOW w;
+    } name;
+    name.w = buffer;
+
+    do
+    {
+        switch (valid_namespaces[items])
+        {
+          case NS_DNS: namesize += sizeof(NameSpaceDns); break;
+          case NS_NLA: namesize += sizeof(NameSpaceNla); break;
+        }
+    }
+    while (valid_namespaces[++items]);
+
+    size = unicode ? items * sizeof(WSANAMESPACE_INFOW) + namesize:
+                     items * sizeof(WSANAMESPACE_INFOA) + namesize / sizeof(WCHAR);
+
+    TRACE("unicode %d, buffer %p, length %p %d, items %d, required %d\n",
+          unicode, buffer, len, len ? *len : 0, items, size);
+
+    if (!len || *len < size || !buffer)
+    {
+        if (len) *len = size;
+        WSASetLastError(WSAEFAULT);
+        return SOCKET_ERROR;
+    }
+
+    wstrbase = (WCHAR *)(name.w + items);
+    strbase = (char *)(name.a + items);
+    for (i = offset = 0; i < items; i++)
+    {
+        if (unicode)
+            WS_EnterSingleNameSpaceW( valid_namespaces[i], wstrbase, &offset, &name.w[i] );
+        else
+            WS_EnterSingleNameSpaceA( valid_namespaces[i], strbase, &offset, &name.a[i] );
+    }
+    return items;
+}
+
 static BOOL ws_protocol_info(SOCKET s, int unicode, WSAPROTOCOL_INFOW *buffer, int *size)
 {
     NTSTATUS status;
@@ -7138,8 +7282,7 @@ INT WINAPI WSAAddressToStringW( LPSOCKADDR sockaddr, DWORD len,
  */
 INT WINAPI WSAEnumNameSpaceProvidersA( LPDWORD len, LPWSANAMESPACE_INFOA buffer )
 {
-    FIXME( "(%p %p) Stub!\n", len, buffer );
-    return 0;
+    return WS_EnumNameSpace( FALSE, (LPWSANAMESPACE_INFOW) buffer, len);
 }
 
 /***********************************************************************
@@ -7147,8 +7290,7 @@ INT WINAPI WSAEnumNameSpaceProvidersA( LPDWORD len, LPWSANAMESPACE_INFOA buffer
  */
 INT WINAPI WSAEnumNameSpaceProvidersW( LPDWORD len, LPWSANAMESPACE_INFOW buffer )
 {
-    FIXME( "(%p %p) Stub!\n", len, buffer );
-    return 0;
+    return WS_EnumNameSpace( TRUE, buffer, len);
 }
 
 /***********************************************************************
diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c
index 2a838b2..e4c7c71 100644
--- a/dlls/ws2_32/tests/sock.c
+++ b/dlls/ws2_32/tests/sock.c
@@ -7623,34 +7623,26 @@ static void test_WSAEnumNameSpaceProvidersA(void)
     SetLastError(0xdeadbeef);
     ret = pWSAEnumNameSpaceProvidersA(&blen, name);
     error = WSAGetLastError();
-todo_wine
     ok(ret == SOCKET_ERROR, "Expected failure, got %u\n", ret);
-todo_wine
     ok(error == WSAEFAULT, "Expected 10014, got %u\n", error);
 
     /* Invalid parameter tests */
     SetLastError(0xdeadbeef);
     ret = pWSAEnumNameSpaceProvidersA(NULL, name);
     error = WSAGetLastError();
-todo_wine
     ok(ret == SOCKET_ERROR, "Expected failure, got %u\n", ret);
-todo_wine
     ok(error == WSAEFAULT, "Expected 10014, got %u\n", error);
 
     SetLastError(0xdeadbeef);
     ret = pWSAEnumNameSpaceProvidersA(NULL, NULL);
     error = WSAGetLastError();
-todo_wine
     ok(ret == SOCKET_ERROR, "Expected failure, got %u\n", ret);
-todo_wine
     ok(error == WSAEFAULT, "Expected 10014, got %u\n", error);
 
     SetLastError(0xdeadbeef);
     ret = pWSAEnumNameSpaceProvidersA(&blen, NULL);
     error = WSAGetLastError();
-todo_wine
     ok(ret == SOCKET_ERROR, "Expected failure, got %u\n", ret);
-todo_wine
     ok(error == WSAEFAULT, "Expected 10014, got %u\n", error);
 
     name = HeapAlloc(GetProcessHeap(), 0, blen);
@@ -7661,7 +7653,6 @@ todo_wine
     }
 
     ret = pWSAEnumNameSpaceProvidersA(&blen, name);
-todo_wine
     ok(ret > 0, "Expected more than zero name space providers\n");
 
     for (i = 0;i < ret; i++)
@@ -7700,34 +7691,26 @@ static void test_WSAEnumNameSpaceProvidersW(void)
     SetLastError(0xdeadbeef);
     ret = pWSAEnumNameSpaceProvidersW(&blen, name);
     error = WSAGetLastError();
-todo_wine
     ok(ret == SOCKET_ERROR, "Expected failure, got %u\n", ret);
-todo_wine
     ok(error == WSAEFAULT, "Expected 10014, got %u\n", error);
 
     /* Invalid parameter tests */
     SetLastError(0xdeadbeef);
     ret = pWSAEnumNameSpaceProvidersW(NULL, name);
     error = WSAGetLastError();
-todo_wine
     ok(ret == SOCKET_ERROR, "Expected failure, got %u\n", ret);
-todo_wine
     ok(error == WSAEFAULT, "Expected 10014, got %u\n", error);
 
     SetLastError(0xdeadbeef);
     ret = pWSAEnumNameSpaceProvidersW(NULL, NULL);
     error = WSAGetLastError();
-todo_wine
     ok(ret == SOCKET_ERROR, "Expected failure, got %u\n", ret);
-todo_wine
     ok(error == WSAEFAULT, "Expected 10014, got %u\n", error);
 
     SetLastError(0xdeadbeef);
     ret = pWSAEnumNameSpaceProvidersW(&blen, NULL);
     error = WSAGetLastError();
-todo_wine
     ok(ret == SOCKET_ERROR, "Expected failure, got %u\n", ret);
-todo_wine
     ok(error == WSAEFAULT, "Expected 10014, got %u\n", error);
 
     name = HeapAlloc(GetProcessHeap(), 0, blen);
@@ -7738,7 +7721,6 @@ todo_wine
     }
 
     ret = pWSAEnumNameSpaceProvidersW(&blen, name);
-todo_wine
     ok(ret > 0, "Expected more than zero name space providers\n");
 
     for (i = 0;i < ret; i++)
-- 
1.8.3.2



More information about the wine-patches mailing list