Signed-off-by: Alex Henrie <alexhenrie24(a)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