fdf621934b2f1e4dc83fb9464f4c384cc45ea886
[reactos.git] / reactos / dll / win32 / ws2_32_new / src / getproto.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS WinSock 2 API
4 * FILE: dll/win32/ws2_32_new/src/getproto.c
5 * PURPOSE: GetProtoByY Functions.
6 * PROGRAMMER: Alex Ionescu (alex@relsoft.net)
7 */
8
9 /* INCLUDES ******************************************************************/
10
11 #include <ws2_32.h>
12
13 #define NDEBUG
14 #include <debug.h>
15
16 /* FUNCTIONS *****************************************************************/
17
18 HANDLE
19 WSAAPI
20 GetProtoOpenNetworkDatabase(PCHAR Name)
21 {
22 CHAR ExpandedPath[MAX_PATH];
23 CHAR DatabasePath[MAX_PATH];
24 INT ErrorCode;
25 HKEY DatabaseKey;
26 DWORD RegType;
27 DWORD RegSize = sizeof(DatabasePath);
28
29 /* Open the database path key */
30 ErrorCode = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
31 "System\\CurrentControlSet\\Services\\Tcpip\\Parameters",
32 0,
33 KEY_READ,
34 &DatabaseKey);
35 if (ErrorCode == NO_ERROR)
36 {
37 /* Read the actual path */
38 ErrorCode = RegQueryValueEx(DatabaseKey,
39 "DatabasePath",
40 NULL,
41 &RegType,
42 (LPBYTE)DatabasePath,
43 &RegSize);
44
45 /* Close the key */
46 RegCloseKey(DatabaseKey);
47
48 /* Expand the name */
49 ExpandEnvironmentStrings(DatabasePath, ExpandedPath, MAX_PATH);
50 }
51 else
52 {
53 /* Use defalt path */
54 GetSystemDirectory(ExpandedPath, MAX_PATH);
55 strcat(ExpandedPath, "DRIVERS\\ETC\\");
56 }
57
58 /* Make sure that the path is backslash-terminated */
59 if (ExpandedPath[strlen(ExpandedPath) - 1] != '\\')
60 {
61 /* It isn't, so add it ourselves */
62 strcat(ExpandedPath, "\\");
63 }
64
65 /* Add the database name */
66 strcat(ExpandedPath, Name);
67
68 /* Return a handle to the file */
69 return CreateFile(ExpandedPath,
70 FILE_READ_ACCESS,
71 0,
72 NULL,
73 OPEN_EXISTING,
74 FILE_ATTRIBUTE_NORMAL,
75 NULL);
76 }
77
78 PCHAR
79 WSAAPI
80 GetProtoPatternMatch(IN PCHAR Buffer,
81 IN PCHAR Lookup)
82 {
83 CHAR ScanChar;
84
85 /* Loop as long as we have data */
86 while ((ScanChar = *Buffer))
87 {
88 /* Check for a match and return its pointer if found */
89 if (strchr(Lookup, ScanChar)) return Buffer;
90
91 /* Keep going */
92 Buffer++;
93 }
94
95 /* Nothing found */
96 return NULL;
97 }
98
99 PPROTOENT
100 WSAAPI
101 GetProtoGetNextEnt(IN HANDLE DbHandle,
102 IN PWSPROTO_BUFFER Buffer)
103 {
104 DWORD Read;
105 LONG n;
106 PCHAR p, p1, Entry, *Aliases;
107 PPROTOENT ReturnedProtoent;
108
109 /* Find out where we currently are in the file */
110 n = SetFilePointer(DbHandle, 0, 0, FILE_CURRENT);
111
112 while (TRUE)
113 {
114 /* Read 512 bytes */
115 if (!ReadFile(DbHandle,
116 Buffer->LineBuffer,
117 512,
118 &Read,
119 NULL)) return NULL;
120
121 /* Find out where the line ends */
122 p1 = Buffer->LineBuffer;
123 p = strchr(Buffer->LineBuffer, '\n');
124
125 /* Bail out if the file is parsed */
126 if (!p) return NULL;
127
128 /* Calculate our new position */
129 n += (LONG)(p - p1) + 1;
130
131 /* Make it so we read from there next time */
132 SetFilePointer(DbHandle, n, 0, FILE_BEGIN);
133
134 /* Null-terminate the buffer so it only contains this line */
135 *p = ANSI_NULL;
136
137 /* If this line is a comment, skip it */
138 if (*p1 == '#') continue;
139
140 /* Get the entry in this line and null-terminate it */
141 Entry = GetProtoPatternMatch(p1, "#\n");
142 if (!Entry) continue;
143 *Entry = ANSI_NULL;
144
145 /* Start with the name */
146 Buffer->Protoent.p_name = p1;
147
148 /* Get the first tab and null-terminate */
149 Entry = GetProtoPatternMatch(p1, " \t");
150 if (!Entry) continue;
151 *Entry++ = ANSI_NULL;
152
153 /* Handle remaining tabs or spaces */
154 while (*Entry == ' ' || *Entry == '\t') Entry++;
155
156 /* Now move our read pointer */
157 p1 = GetProtoPatternMatch(Entry, " \t");
158 if (p1) *p1++ = ANSI_NULL;
159
160 /* This is where the address is */
161 Buffer->Protoent.p_proto = (short)atoi(Entry);
162
163 /* Setup the alias buffer */
164 Buffer->Protoent.p_aliases = Buffer->Aliases;
165 Aliases = Buffer->Protoent.p_aliases;
166
167 /* Check if the pointer is stil valid */
168 if (p1)
169 {
170 /* The first entry is here */
171 Entry = p1;
172
173 /* Loop while there are non-null entries */
174 while (Entry && *Entry)
175 {
176 /* Handle tabs and spaces */
177 while (*Entry == ' ' || *Entry == '\t') Entry++;
178
179 /* Make sure we don't go over the buffer */
180 if (Aliases < &Buffer->Protoent.p_aliases[MAXALIASES - 1])
181 {
182 /* Write the alias */
183 *Aliases++ = Entry;
184 }
185
186 /* Get to the next entry */
187 Entry = GetProtoPatternMatch(Entry, " \t");
188 if (Entry) *Entry++ = ANSI_NULL;
189 }
190 }
191
192 /* Terminate the list */
193 *Aliases = NULL;
194
195 /* Return to caller */
196 ReturnedProtoent = &Buffer->Protoent;
197 break;
198 }
199
200 /* Return whatever we got */
201 return ReturnedProtoent;
202 }
203
204 /*
205 * @implemented
206 */
207 LPPROTOENT
208 WSAAPI
209 getprotobynumber(IN INT number)
210 {
211 PWSPROCESS Process;
212 PWSTHREAD Thread;
213 INT ErrorCode;
214 PPROTOENT Protoent;
215 PVOID GetProtoBuffer;
216 HANDLE DbHandle;
217 DPRINT("getprotobynumber: %lx\n", number);
218
219 /* Enter prolog */
220 if ((ErrorCode = WsApiProlog(&Process, &Thread)) != ERROR_SUCCESS)
221 {
222 /* Leave now */
223 SetLastError(ErrorCode);
224 return NULL;
225 }
226
227 /* Get our buffer */
228 GetProtoBuffer = WsThreadGetProtoBuffer(Thread);
229 if (!GetProtoBuffer)
230 {
231 /* Fail */
232 SetLastError(WSANO_DATA);
233 return NULL;
234 }
235
236 /* Open the network database */
237 DbHandle = GetProtoOpenNetworkDatabase("protocol");
238 if (DbHandle == INVALID_HANDLE_VALUE)
239 {
240 /* Couldn't open the DB; fail */
241 SetLastError(WSANO_DATA);
242 return NULL;
243 }
244
245 /* Start the scan loop */
246 while (TRUE)
247 {
248 /* Get a protoent entry */
249 Protoent = GetProtoGetNextEnt(DbHandle, GetProtoBuffer);
250
251 /* Break if we didn't get any new one */
252 if (!Protoent) break;
253
254 /* Break if we have a match */
255 if (Protoent->p_proto == number) break;
256 }
257
258 /* Close the network database */
259 CloseHandle(DbHandle);
260
261 /* Set error if we don't have a protoent */
262 if (!Protoent) SetLastError(WSANO_DATA);
263
264 /* Return it */
265 return Protoent;
266 }
267
268 /*
269 * @implemented
270 */
271 LPPROTOENT
272 WSAAPI
273 getprotobyname(IN CONST CHAR FAR *name)
274 {
275 PWSPROCESS Process;
276 PWSTHREAD Thread;
277 INT ErrorCode;
278 PPROTOENT Protoent;
279 PVOID GetProtoBuffer;
280 HANDLE DbHandle;
281 DPRINT("getprotobyname: %s\n", name);
282
283 /* Enter prolog */
284 if ((ErrorCode = WsApiProlog(&Process, &Thread)) != ERROR_SUCCESS)
285 {
286 /* Leave now */
287 SetLastError(ErrorCode);
288 return NULL;
289 }
290
291 /* Get our buffer */
292 GetProtoBuffer = WsThreadGetProtoBuffer(Thread);
293 if (!GetProtoBuffer)
294 {
295 /* Fail */
296 SetLastError(WSANO_DATA);
297 return NULL;
298 }
299
300 /* Open the network database */
301 DbHandle = GetProtoOpenNetworkDatabase("protocol");
302 if (DbHandle == INVALID_HANDLE_VALUE)
303 {
304 /* Couldn't open the DB; fail */
305 SetLastError(WSANO_DATA);
306 return NULL;
307 }
308
309 /* Start the scan loop */
310 while (TRUE)
311 {
312 /* Get a protoent entry */
313 Protoent = GetProtoGetNextEnt(DbHandle, GetProtoBuffer);
314
315 /* Break if we didn't get any new one */
316 if (!Protoent) break;
317
318 /* Break if we have a match */
319 if (!_stricmp(Protoent->p_name, name)) break;
320 }
321
322 /* Close the network database */
323 CloseHandle(DbHandle);
324
325 /* Set error if we don't have a protoent */
326 if (!Protoent) SetLastError(WSANO_DATA);
327
328 /* Return it */
329 return Protoent;
330 }