[WS2_32_NEW]
[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 /* Null terminate LineBuffer */
122 Buffer->LineBuffer[Read] = ANSI_NULL;
123
124 /* Find out where the line ends */
125 p1 = Buffer->LineBuffer;
126 p = strchr(Buffer->LineBuffer, '\n');
127
128 /* Bail out if the file is parsed */
129 if (!p) return NULL;
130
131 /* Calculate our new position */
132 n += (LONG)(p - p1) + 1;
133
134 /* Make it so we read from there next time */
135 SetFilePointer(DbHandle, n, 0, FILE_BEGIN);
136
137 /* Null-terminate the buffer so it only contains this line */
138 *p = ANSI_NULL;
139
140 /* If this line is a comment, skip it */
141 if (*p1 == '#') continue;
142
143 /* Get the entry in this line and null-terminate it */
144 Entry = GetProtoPatternMatch(p1, "#\n");
145 if (!Entry) continue;
146 *Entry = ANSI_NULL;
147
148 /* Start with the name */
149 Buffer->Protoent.p_name = p1;
150
151 /* Get the first tab and null-terminate */
152 Entry = GetProtoPatternMatch(p1, " \t");
153 if (!Entry) continue;
154 *Entry++ = ANSI_NULL;
155
156 /* Handle remaining tabs or spaces */
157 while (*Entry == ' ' || *Entry == '\t') Entry++;
158
159 /* Now move our read pointer */
160 p1 = GetProtoPatternMatch(Entry, " \t");
161 if (p1) *p1++ = ANSI_NULL;
162
163 /* This is where the address is */
164 Buffer->Protoent.p_proto = (short)atoi(Entry);
165
166 /* Setup the alias buffer */
167 Buffer->Protoent.p_aliases = Buffer->Aliases;
168 Aliases = Buffer->Protoent.p_aliases;
169
170 /* Check if the pointer is stil valid */
171 if (p1)
172 {
173 /* The first entry is here */
174 Entry = p1;
175
176 /* Loop while there are non-null entries */
177 while (Entry && *Entry)
178 {
179 /* Handle tabs and spaces */
180 while (*Entry == ' ' || *Entry == '\t') Entry++;
181
182 /* Make sure we don't go over the buffer */
183 if (Aliases < &Buffer->Protoent.p_aliases[MAXALIASES - 1])
184 {
185 /* Write the alias */
186 *Aliases++ = Entry;
187 }
188
189 /* Get to the next entry */
190 Entry = GetProtoPatternMatch(Entry, " \t");
191 if (Entry) *Entry++ = ANSI_NULL;
192 }
193 }
194
195 /* Terminate the list */
196 *Aliases = NULL;
197
198 /* Return to caller */
199 ReturnedProtoent = &Buffer->Protoent;
200 break;
201 }
202
203 /* Return whatever we got */
204 return ReturnedProtoent;
205 }
206
207 /*
208 * @implemented
209 */
210 LPPROTOENT
211 WSAAPI
212 getprotobynumber(IN INT number)
213 {
214 PWSPROCESS Process;
215 PWSTHREAD Thread;
216 INT ErrorCode;
217 PPROTOENT Protoent;
218 PVOID GetProtoBuffer;
219 HANDLE DbHandle;
220 DPRINT("getprotobynumber: %lx\n", number);
221
222 /* Enter prolog */
223 if ((ErrorCode = WsApiProlog(&Process, &Thread)) != ERROR_SUCCESS)
224 {
225 /* Leave now */
226 SetLastError(ErrorCode);
227 return NULL;
228 }
229
230 /* Get our buffer */
231 GetProtoBuffer = WsThreadGetProtoBuffer(Thread);
232 if (!GetProtoBuffer)
233 {
234 /* Fail */
235 SetLastError(WSANO_DATA);
236 return NULL;
237 }
238
239 /* Open the network database */
240 DbHandle = GetProtoOpenNetworkDatabase("protocol");
241 if (DbHandle == INVALID_HANDLE_VALUE)
242 {
243 /* Couldn't open the DB; fail */
244 SetLastError(WSANO_DATA);
245 return NULL;
246 }
247
248 /* Start the scan loop */
249 while (TRUE)
250 {
251 /* Get a protoent entry */
252 Protoent = GetProtoGetNextEnt(DbHandle, GetProtoBuffer);
253
254 /* Break if we didn't get any new one */
255 if (!Protoent) break;
256
257 /* Break if we have a match */
258 if (Protoent->p_proto == number) break;
259 }
260
261 /* Close the network database */
262 CloseHandle(DbHandle);
263
264 /* Set error if we don't have a protoent */
265 if (!Protoent) SetLastError(WSANO_DATA);
266
267 /* Return it */
268 return Protoent;
269 }
270
271 /*
272 * @implemented
273 */
274 LPPROTOENT
275 WSAAPI
276 getprotobyname(IN CONST CHAR FAR *name)
277 {
278 PWSPROCESS Process;
279 PWSTHREAD Thread;
280 INT ErrorCode;
281 PPROTOENT Protoent;
282 PVOID GetProtoBuffer;
283 HANDLE DbHandle;
284 DPRINT("getprotobyname: %s\n", name);
285
286 /* Enter prolog */
287 if ((ErrorCode = WsApiProlog(&Process, &Thread)) != ERROR_SUCCESS)
288 {
289 /* Leave now */
290 SetLastError(ErrorCode);
291 return NULL;
292 }
293
294 /* Get our buffer */
295 GetProtoBuffer = WsThreadGetProtoBuffer(Thread);
296 if (!GetProtoBuffer)
297 {
298 /* Fail */
299 SetLastError(WSANO_DATA);
300 return NULL;
301 }
302
303 /* Open the network database */
304 DbHandle = GetProtoOpenNetworkDatabase("protocol");
305 if (DbHandle == INVALID_HANDLE_VALUE)
306 {
307 /* Couldn't open the DB; fail */
308 SetLastError(WSANO_DATA);
309 return NULL;
310 }
311
312 /* Start the scan loop */
313 while (TRUE)
314 {
315 /* Get a protoent entry */
316 Protoent = GetProtoGetNextEnt(DbHandle, GetProtoBuffer);
317
318 /* Break if we didn't get any new one */
319 if (!Protoent) break;
320
321 /* Break if we have a match */
322 if (!_stricmp(Protoent->p_name, name)) break;
323 }
324
325 /* Close the network database */
326 CloseHandle(DbHandle);
327
328 /* Set error if we don't have a protoent */
329 if (!Protoent) SetLastError(WSANO_DATA);
330
331 /* Return it */
332 return Protoent;
333 }