2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS WinSock 2 API
5 * PURPOSE: Winsock Utility Functions
6 * PROGRAMMER: Alex Ionescu (alex@relsoft.net)
9 /* INCLUDES ******************************************************************/
13 /* FUNCTIONS *****************************************************************/
17 WsOpenRegistryRoot(VOID
)
21 ULONG CreateDisposition
;
23 /* Open Registry Key */
24 ErrorCode
= RegOpenKeyEx(HKEY_LOCAL_MACHINE
,
30 /* Check if it wasn't found */
31 if (ErrorCode
== ERROR_FILE_NOT_FOUND
)
34 RegCreateKeyEx(HKEY_LOCAL_MACHINE
,
38 REG_OPTION_NON_VOLATILE
,
44 else if (ErrorCode
== ERROR_SUCCESS
)
46 /* It already exists */
47 CreateDisposition
= REG_OPENED_EXISTING_KEY
;
50 /* Check for failure */
51 if (ErrorCode
!= ERROR_SUCCESS
) return NULL
;
53 /* Check if we had to create a new key */
54 if (CreateDisposition
== REG_CREATED_NEW_KEY
)
56 /* Write the Winsock Version */
57 RegSetValueEx(WinsockRootKey
,
58 "WinSock_Registry_Version",
66 /* Read the Winsock Version */
70 return WinsockRootKey
;
75 WsCheckCatalogState(IN HANDLE Event
)
79 /* Wait for the object */
80 Return
= WaitForSingleObject(Event
, 0);
82 /* Check for the value */
83 if (Return
== WAIT_OBJECT_0
) return TRUE
;
85 /* If it timedout or anything else, return false */
91 WsApiProlog(OUT PWSPROCESS
*Process
,
92 OUT PWSTHREAD
*Thread
)
94 INT ErrorCode
= WSANOTINITIALISED
;
96 /* Try to get the current process */
97 if ((*Process
= WsGetProcess()))
99 /* And the current thread */
100 ErrorCode
= WsThreadGetCurrentThread(*Process
, Thread
);
103 /* Return init status */
114 /* Call the prolog */
115 return WsApiProlog(&Process
, &Thread
);
120 WsSlowPrologTid(OUT LPWSATHREADID
*ThreadId
)
126 /* Call the prolog */
127 ErrorCode
= WsApiProlog(&Process
, &Thread
);
129 /* Check for success */
130 if (ErrorCode
== ERROR_SUCCESS
)
132 /* Return the Thread ID */
133 *ThreadId
= &Thread
->WahThreadId
;
142 WsSetupCatalogProtection(IN HKEY CatalogKey
,
143 IN HANDLE CatalogEvent
,
144 OUT LPDWORD UniqueId
)
150 DWORD RegType
= REG_DWORD
;
151 DWORD RegSize
= sizeof(DWORD
);
157 /* Ask for notifications */
158 ErrorCode
= RegNotifyChangeKeyValue(CatalogKey
,
160 REG_NOTIFY_CHANGE_NAME
,
163 if (ErrorCode
!= ERROR_SUCCESS
)
165 /* Normalize error code */
166 ErrorCode
= WSASYSCALLFAILURE
;
171 /* Read the current ID */
172 ErrorCode
= RegQueryValueEx(CatalogKey
,
176 (LPBYTE
)&NewUniqueId
,
178 if (ErrorCode
!= ERROR_SUCCESS
)
180 /* Critical failure */
181 ErrorCode
= WSASYSCALLFAILURE
;
185 /* Try to open it for writing */
186 sprintf(KeyBuffer
, "%8.8lX", NewUniqueId
);
187 ErrorCode
= RegOpenKeyEx(CatalogKey
,
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
))
197 /* Set success and return the new ID */
198 ErrorCode
= ERROR_SUCCESS
;
199 *UniqueId
= NewUniqueId
;
202 else if (ErrorCode
!= ERROR_SUCCESS
)
204 /* Any other failure is bad */
205 ErrorCode
= WSASYSCALLFAILURE
;
209 /* If we could actually open the key, someone is using it :/ */
210 ErrorCode
= RegCloseKey(RegistryKey
);
212 /* In case we break out prematurely */
213 ErrorCode
= WSANO_RECOVERY
;
215 /* Keep looping until they let go of the registry writing */
216 } while (!WaitForSingleObject(CatalogEvent
, 180 * 1000));
218 /* Return error code */
224 MapUnicodeProtocolInfoToAnsi(IN LPWSAPROTOCOL_INFOW UnicodeInfo
,
225 OUT LPWSAPROTOCOL_INFOA AnsiInfo
)
229 /* Copy all the data that doesn't need converting */
230 RtlCopyMemory(AnsiInfo
,
232 FIELD_OFFSET(WSAPROTOCOL_INFOA
, szProtocol
));
234 /* Now convert the protocol string */
235 ReturnValue
= WideCharToMultiByte(CP_ACP
,
237 UnicodeInfo
->szProtocol
,
239 AnsiInfo
->szProtocol
,
240 sizeof(AnsiInfo
->szProtocol
),
243 if (!ReturnValue
) return WSASYSCALLFAILURE
;
246 return ERROR_SUCCESS
;