xref: /reactos/dll/win32/ws2_32/src/wsautil.c (revision 2196a06f)
1 /*
2  * COPYRIGHT:   See COPYING in the top level directory
3  * PROJECT:     ReactOS WinSock 2 API
4  * FILE:        dll/win32/ws2_32/src/wsautil.c
5  * PURPOSE:     Winsock Utility Functions
6  * PROGRAMMER:  Alex Ionescu (alex@relsoft.net)
7  */
8 
9 /* INCLUDES ******************************************************************/
10 
11 #include <ws2_32.h>
12 
13 /* FUNCTIONS *****************************************************************/
14 
15 HKEY
16 WSAAPI
17 WsOpenRegistryRoot(VOID)
18 {
19     HKEY WinsockRootKey;
20     INT ErrorCode;
21     ULONG CreateDisposition;
22 
23     /* Open Registry Key */
24     ErrorCode = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
25                              WINSOCK_ROOT,
26                              0,
27                              MAXIMUM_ALLOWED,
28                              &WinsockRootKey);
29 
30     /* Check if it wasn't found */
31     if (ErrorCode == ERROR_FILE_NOT_FOUND)
32     {
33         /* Create it */
34         ErrorCode = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
35                                    WINSOCK_ROOT,
36                                    0,
37                                    NULL,
38                                    REG_OPTION_NON_VOLATILE,
39                                    KEY_ALL_ACCESS,
40                                    NULL,
41                                    &WinsockRootKey,
42                                    &CreateDisposition);
43     }
44     else if (ErrorCode == ERROR_SUCCESS)
45     {
46         /* It already exists */
47         CreateDisposition = REG_OPENED_EXISTING_KEY;
48     }
49 
50     /* Check for failure */
51     if (ErrorCode != ERROR_SUCCESS) return NULL;
52 
53     /* Check if we had to create a new key */
54     if (CreateDisposition == REG_CREATED_NEW_KEY)
55     {
56         /* Write the Winsock Version */
57         RegSetValueEx(WinsockRootKey,
58                       "WinSock_Registry_Version",
59                       0,
60                       REG_SZ,
61                       (BYTE*)"2.2",
62                       4);
63     }
64     else
65     {
66         /* Read the Winsock Version */
67     }
68 
69     /* Return the key */
70     return WinsockRootKey;
71 }
72 
73 BOOL
74 WSAAPI
75 WsCheckCatalogState(IN HANDLE Event)
76 {
77     DWORD Return;
78 
79     /* Wait for the object */
80     Return = WaitForSingleObject(Event, 0);
81 
82     /* Check for the value */
83     if (Return == WAIT_OBJECT_0) return TRUE;
84 
85     /* If it timedout or anything else, return false */
86     return FALSE;
87 }
88 
89 INT
90 WSAAPI
91 WsApiProlog(OUT PWSPROCESS *Process,
92             OUT PWSTHREAD *Thread)
93 {
94     INT ErrorCode = WSANOTINITIALISED;
95 
96     /* Try to get the current process */
97     if ((*Process = WsGetProcess()))
98     {
99         /* And the current thread */
100         ErrorCode = WsThreadGetCurrentThread(*Process, Thread);
101     }
102 
103     /* Return init status */
104     return ErrorCode;
105 }
106 
107 INT
108 WSAAPI
109 WsSlowProlog(VOID)
110 {
111     PWSPROCESS Process;
112     PWSTHREAD Thread;
113 
114     /* Call the prolog */
115     return WsApiProlog(&Process, &Thread);
116 }
117 
118 INT
119 WSAAPI
120 WsSlowPrologTid(OUT LPWSATHREADID *ThreadId)
121 {
122     PWSPROCESS Process;
123     PWSTHREAD Thread;
124     INT ErrorCode;
125 
126     /* Call the prolog */
127     ErrorCode = WsApiProlog(&Process, &Thread);
128 
129     /* Check for success */
130     if (ErrorCode == ERROR_SUCCESS)
131     {
132         /* Return the Thread ID */
133         *ThreadId = &Thread->WahThreadId;
134     }
135 
136     /* Return status */
137     return ErrorCode;
138 }
139 
140 INT
141 WSAAPI
142 WsSetupCatalogProtection(IN HKEY CatalogKey,
143                          IN HANDLE CatalogEvent,
144                          OUT LPDWORD UniqueId)
145 {
146     INT ErrorCode;
147     HKEY RegistryKey;
148     DWORD NewUniqueId;
149     CHAR KeyBuffer[32];
150     DWORD RegType = REG_DWORD;
151     DWORD RegSize = sizeof(DWORD);
152 
153     /* Start loop */
154     do
155     {
156 #if 0
157         /* Ask for notifications */
158         ErrorCode = RegNotifyChangeKeyValue(CatalogKey,
159                                             FALSE,
160                                             REG_NOTIFY_CHANGE_NAME,
161                                             CatalogEvent,
162                                             TRUE);
163         if (ErrorCode != ERROR_SUCCESS)
164         {
165             /* Normalize error code */
166             ErrorCode = WSASYSCALLFAILURE;
167             break;
168         }
169 #endif
170 
171         /* Read the current ID */
172         ErrorCode = RegQueryValueEx(CatalogKey,
173                                     "Serial_Access_Num",
174                                     0,
175                                     &RegType,
176                                     (LPBYTE)&NewUniqueId,
177                                     &RegSize);
178         if (ErrorCode != ERROR_SUCCESS)
179         {
180             /* Critical failure */
181             ErrorCode = WSASYSCALLFAILURE;
182             break;
183         }
184 
185         /* Try to open it for writing */
186         sprintf(KeyBuffer, "%8.8lX", NewUniqueId);
187         ErrorCode = RegOpenKeyEx(CatalogKey,
188                                  KeyBuffer,
189                                  0,
190                                  MAXIMUM_ALLOWED,
191                                  &RegistryKey);
192 
193         /* If the key doesn't exist or is being delete, that's ok for us */
194         if ((ErrorCode == ERROR_FILE_NOT_FOUND) ||
195             (ErrorCode == ERROR_KEY_DELETED))
196         {
197             /* Set success and return the new ID */
198             ErrorCode = ERROR_SUCCESS;
199             *UniqueId = NewUniqueId;
200             break;
201         }
202         else if (ErrorCode != ERROR_SUCCESS)
203         {
204             /* Any other failure is bad */
205             ErrorCode = WSASYSCALLFAILURE;
206             break;
207         }
208 
209         /* If we could actually open the key, someone is using it :/ */
210         ErrorCode = RegCloseKey(RegistryKey);
211 
212         /* In case we break out prematurely */
213         ErrorCode = WSANO_RECOVERY;
214 
215         /* Keep looping until they let go of the registry writing */
216     } while (!WaitForSingleObject(CatalogEvent, 180 * 1000));
217 
218     /* Return error code */
219     return ErrorCode;
220 }
221 
222 INT
223 WSAAPI
224 MapUnicodeProtocolInfoToAnsi(IN LPWSAPROTOCOL_INFOW UnicodeInfo,
225                              OUT LPWSAPROTOCOL_INFOA AnsiInfo)
226 {
227     INT ReturnValue;
228 
229     /* Copy all the data that doesn't need converting */
230     RtlCopyMemory(AnsiInfo,
231                   UnicodeInfo,
232                   FIELD_OFFSET(WSAPROTOCOL_INFOA, szProtocol));
233 
234     /* Now convert the protocol string */
235     ReturnValue = WideCharToMultiByte(CP_ACP,
236                                       0,
237                                       UnicodeInfo->szProtocol,
238                                       -1,
239                                       AnsiInfo->szProtocol,
240                                       sizeof(AnsiInfo->szProtocol),
241                                       NULL,
242                                       NULL);
243     if (!ReturnValue) return WSASYSCALLFAILURE;
244 
245     /* Return success */
246     return ERROR_SUCCESS;
247 }
248 
249 /*
250  * @implemented
251  */
252 VOID
253 WSAAPI
254 WEP(VOID)
255 {
256     return;
257 }
258