Sync with trunk rev.61910 to get latest improvements and bugfixes.
[reactos.git] / dll / win32 / ws2_32_new / src / wsautil.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS WinSock 2 API
4 * FILE: 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 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 }