[PATCH resend] ws2_32: Read protocol table from a file

Alex Henrie alexhenrie24 at gmail.com
Thu Jan 14 18:51:32 CST 2021


Signed-off-by: Alex Henrie <alexhenrie24 at gmail.com>
---
I intend to extend read_protocol_table and parse_next_protocol to read
and parse the services file as well, since the file formats are nearly
identical.
---
 dlls/ws2_32/protocols.tsv |  39 +++++++++
 dlls/ws2_32/socket.c      | 163 ++++++++++++++++++++++++++++++--------
 dlls/ws2_32/version.rc    |   3 +
 loader/wine.inf.in        |  12 ++-
 4 files changed, 181 insertions(+), 36 deletions(-)
 create mode 100644 dlls/ws2_32/protocols.tsv

diff --git a/dlls/ws2_32/protocols.tsv b/dlls/ws2_32/protocols.tsv
new file mode 100644
index 00000000000..288bd739f15
--- /dev/null
+++ b/dlls/ws2_32/protocols.tsv
@@ -0,0 +1,39 @@
+# Table of Internet protocols
+#
+# Copyright (c) 2020 The Wine Project
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+
+# Format: <name> <number> [<alias>...]
+
+ip	0	IP
+icmp	1	ICMP
+ggp	3	GGP
+tcp	6	TCP
+egp	8	EGP
+pup	12	PUP
+udp	17	UDP
+hmp	20	HMP
+xns-idp	22	XNS-IDP
+rdp	27	RDP
+ipv6	41	IPv6
+ipv6-route	43	IPv6-Route
+ipv6-frag	44	IPv6-Frag
+esp	50	ESP
+ah	51	AH
+ipv6-icmp	58	IPv6-ICMP
+ipv6-nonxt	59	IPv6-NoNxt
+ipv6-opts	60	IPv6-Opts
+rvd	66	RVD
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c
index 0579ede8772..2d271e825bc 100644
--- a/dlls/ws2_32/socket.c
+++ b/dlls/ws2_32/socket.c
@@ -182,6 +182,8 @@
 
 #define FILE_USE_FILE_POINTER_POSITION ((LONGLONG)-2)
 
+#define MAX_NAMES 4
+
 WINE_DEFAULT_DEBUG_CHANNEL(winsock);
 WINE_DECLARE_DEBUG_CHANNEL(winediag);
 
@@ -6311,28 +6313,112 @@ struct WS_hostent* WINAPI WS_gethostbyname(const char* name)
 }
 
 
-static const struct { int prot; const char *names[3]; } protocols[] =
-{
-    {   0, { "ip", "IP" }},
-    {   1, { "icmp", "ICMP" }},
-    {   3, { "ggp", "GGP" }},
-    {   6, { "tcp", "TCP" }},
-    {   8, { "egp", "EGP" }},
-    {  12, { "pup", "PUP" }},
-    {  17, { "udp", "UDP" }},
-    {  20, { "hmp", "HMP" }},
-    {  22, { "xns-idp", "XNS-IDP" }},
-    {  27, { "rdp", "RDP" }},
-    {  41, { "ipv6", "IPv6" }},
-    {  43, { "ipv6-route", "IPv6-Route" }},
-    {  44, { "ipv6-frag", "IPv6-Frag" }},
-    {  50, { "esp", "ESP" }},
-    {  51, { "ah", "AH" }},
-    {  58, { "ipv6-icmp", "IPv6-ICMP" }},
-    {  59, { "ipv6-nonxt", "IPv6-NoNxt" }},
-    {  60, { "ipv6-opts", "IPv6-Opts" }},
-    {  66, { "rvd", "RVD" }},
-};
+static char * read_protocol_table(void)
+{
+    static const WCHAR drivers_etc_protocol[] = {'\\','d','r','i','v','e','r','s',
+                                                 '\\','e','t','c',
+                                                 '\\','p','r','o','t','o','c','o','l',0};
+    WCHAR table_path[MAX_PATH];
+    HANDLE table_file;
+    DWORD table_len, bytes_read;
+    BOOL ret;
+    char *table_text;
+
+    GetSystemDirectoryW(table_path, ARRAY_SIZE(table_path));
+    lstrcatW(table_path, drivers_etc_protocol);
+
+    table_file = CreateFileW(table_path, GENERIC_READ, FILE_SHARE_READ, NULL,
+                             OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+    if (table_file == INVALID_HANDLE_VALUE)
+        return NULL;
+
+    table_len = GetFileSize(table_file, NULL);
+    if (!table_len)
+    {
+        CloseHandle(table_file);
+        return NULL;
+    }
+
+    table_text = HeapAlloc(GetProcessHeap(), 0, table_len + 1);
+    if (!table_text)
+    {
+        CloseHandle(table_file);
+        return NULL;
+    }
+
+    ret = ReadFile(table_file, table_text, table_len, &bytes_read, NULL);
+    if (!ret || bytes_read != table_len)
+    {
+        CloseHandle(table_file);
+        HeapFree(GetProcessHeap(), 0, table_text);
+        return NULL;
+    }
+
+    CloseHandle(table_file);
+    table_text[table_len] = 0;
+    return table_text;
+}
+
+static char * get_field(char *line)
+{
+    char *field;
+    /* ignore sequences of whitespace between fields */
+    while ((field = strtok(line, " \t\r")))
+    {
+        if (field[0])
+            break;
+    }
+    return field;
+}
+
+static char * parse_next_protocol(char *current_line, int *number, char *names[MAX_NAMES])
+{
+    char *next_line;
+    char *comment;
+    int i;
+
+    while (current_line)
+    {
+        next_line = strchr(current_line, '\n');
+        if (next_line)
+        {
+            next_line[0] = 0;
+            next_line++;
+        }
+
+        comment = strchr(current_line, '#');
+        if (comment)
+            *comment = 0;
+
+        names[0] = get_field(current_line);
+        if (!names[0])
+        {
+            /* this line is empty, all whitespace, or a comment */
+            current_line = next_line;
+            continue;
+        }
+
+        names[1] = get_field(NULL);
+        if (!names[1])
+        {
+            /* lines that only have one field are ignored too */
+            current_line = next_line;
+            continue;
+        }
+        /* if the second field is not actually a number, it is treated as 0 */
+        *number = atoi(names[1]);
+
+        for (i = 1;; i++)
+        {
+            names[i] = (i == MAX_NAMES - 1 ? NULL : get_field(NULL));
+            if (!names[i]) break;
+        }
+
+        return next_line;
+    }
+
+    return NULL;
+}
 
 /***********************************************************************
  *		getprotobyname		(WS2_32.53)
@@ -6340,21 +6426,31 @@ static const struct { int prot; const char *names[3]; } protocols[] =
 struct WS_protoent* WINAPI WS_getprotobyname(const char* name)
 {
     struct WS_protoent* retval = NULL;
+    char *table_text = read_protocol_table();
+    char *current_line = table_text;
+    int row_number;
+    char *row_names[MAX_NAMES];
     unsigned int i;
 
-    for (i = 0; i < ARRAY_SIZE(protocols); i++)
+    while ((current_line = parse_next_protocol( current_line, &row_number, row_names )))
     {
-        if (_strnicmp( protocols[i].names[0], name, -1 )) continue;
-        retval = WS_create_pe( protocols[i].names[0], (char **)protocols[i].names + 1,
-                               protocols[i].prot );
-        break;
+        for (i = 0; row_names[i]; i++)
+        {
+            if (!_strnicmp( row_names[i], name, -1 ))
+            {
+                retval = WS_create_pe( row_names[0], (char **)row_names + 1, row_number );
+                goto found;
+            }
+        }
     }
     if (!retval)
     {
         WARN( "protocol %s not found\n", debugstr_a(name) );
         SetLastError(WSANO_DATA);
     }
+found:
     TRACE( "%s ret %p\n", debugstr_a(name), retval );
+    if (table_text) HeapFree( GetProcessHeap(), 0, table_text );
     return retval;
 }
 
@@ -6365,13 +6461,15 @@ struct WS_protoent* WINAPI WS_getprotobyname(const char* name)
 struct WS_protoent* WINAPI WS_getprotobynumber(int number)
 {
     struct WS_protoent* retval = NULL;
-    unsigned int i;
+    char *table_text = read_protocol_table();
+    char *current_line = table_text;
+    int row_number;
+    char *row_names[MAX_NAMES];
 
-    for (i = 0; i < ARRAY_SIZE(protocols); i++)
+    while ((current_line = parse_next_protocol( current_line, &row_number, row_names )))
     {
-        if (protocols[i].prot != number) continue;
-        retval = WS_create_pe( protocols[i].names[0], (char **)protocols[i].names + 1,
-                               protocols[i].prot );
+        if (row_number != number) continue;
+        retval = WS_create_pe( row_names[0], (char **)row_names + 1, row_number );
         break;
     }
     if (!retval)
@@ -6380,6 +6478,7 @@ struct WS_protoent* WINAPI WS_getprotobynumber(int number)
         SetLastError(WSANO_DATA);
     }
     TRACE("%i ret %p\n", number, retval);
+    if (table_text) HeapFree( GetProcessHeap(), 0, table_text );
     return retval;
 }
 
diff --git a/dlls/ws2_32/version.rc b/dlls/ws2_32/version.rc
index 52dbb1b2c48..a68f9885805 100644
--- a/dlls/ws2_32/version.rc
+++ b/dlls/ws2_32/version.rc
@@ -16,6 +16,9 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+/* @makedep: protocols.tsv */
+1 WINE_DATA_FILE protocols.tsv
+
 #define WINE_FILEDESCRIPTION_STR "Wine core dll"
 #define WINE_FILENAME_STR "ws2_32.dll"
 #define WINE_FILEVERSION 5,1,2600,5512
diff --git a/loader/wine.inf.in b/loader/wine.inf.in
index 1df9c21203e..4f730865555 100644
--- a/loader/wine.inf.in
+++ b/loader/wine.inf.in
@@ -30,7 +30,7 @@ signature="$CHICAGO$"
 RegisterDlls=RegisterDllsSection
 WineFakeDlls=FakeDllsWin32,FakeDlls
 UpdateInis=SystemIni
-CopyFiles=ColorFiles,InfFiles,NlsFiles,SortFiles
+CopyFiles=ColorFiles,EtcFiles,InfFiles,NlsFiles,SortFiles
 AddReg=\
     Classes,\
     ContentIndex,\
@@ -54,7 +54,7 @@ AddReg=\
 RegisterDlls=RegisterDllsSection
 WineFakeDlls=FakeDllsWin32,FakeDlls
 UpdateInis=SystemIni
-CopyFiles=ColorFiles,InfFiles,NlsFiles,SortFiles
+CopyFiles=ColorFiles,EtcFiles,InfFiles,NlsFiles,SortFiles
 AddReg=\
     Classes,\
     ContentIndex,\
@@ -80,7 +80,7 @@ RegisterDlls=RegisterDllsSection
 WineFakeDlls=FakeDllsWin64,FakeDlls
 WinePreInstall=Wow64
 UpdateInis=SystemIni
-CopyFiles=ColorFiles,InfFiles,NlsFiles,SortFiles
+CopyFiles=ColorFiles,EtcFiles,InfFiles,NlsFiles,SortFiles
 AddReg=\
     Classes,\
     ContentIndex,\
@@ -107,7 +107,7 @@ RegisterDlls=RegisterDllsSection
 WineFakeDlls=FakeDllsWin64,FakeDlls
 WinePreInstall=Wow64
 UpdateInis=SystemIni
-CopyFiles=ColorFiles,InfFiles,NlsFiles,SortFiles
+CopyFiles=ColorFiles,EtcFiles,InfFiles,NlsFiles,SortFiles
 AddReg=\
     Classes,\
     ContentIndex,\
@@ -4080,6 +4080,9 @@ HKLM,Software\Wine\LicenseInformation,"Shell-PremiumInBoxGames-Chess-EnableGame"
 [ColorFiles]
 srgb color space profile.icm,"@mscms.dll,-1"
 
+[EtcFiles]
+protocol,"@ws2_32.dll,-1"
+
 [InfFiles]
 winebus.inf,"@winebus.sys,-1"
 winehid.inf,"@winehid.sys,-1"
@@ -4168,6 +4171,7 @@ SortFiles = nls
 
 [DestinationDirs]
 ColorFiles = 23
+EtcFiles = 12,etc
 InfFiles  = 17
 NlsFiles  = 11
 SortFiles = 10,globalization\sorting
-- 
2.30.0




More information about the wine-devel mailing list