Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygensockctrl.c
Go to the documentation of this file.
00001 /* 00002 * COPYRIGHT: See COPYING in the top level directory 00003 * PROJECT: ReactOS WinSock 2 API 00004 * FILE: socktrl.c 00005 * PURPOSE: Socket Control/State Support 00006 * PROGRAMMER: Alex Ionescu (alex@relsoft.net) 00007 */ 00008 00009 /* INCLUDES ******************************************************************/ 00010 #include "ws2_32.h" 00011 00012 //#define NDEBUG 00013 #include <debug.h> 00014 00015 /* DATA **********************************************************************/ 00016 00017 /* FUNCTIONS *****************************************************************/ 00018 00019 /* 00020 * @implemented 00021 */ 00022 INT 00023 WSAAPI 00024 connect(IN SOCKET s, 00025 IN CONST struct sockaddr *name, 00026 IN INT namelen) 00027 { 00028 PWSPROCESS Process; 00029 PWSTHREAD Thread; 00030 PWSSOCKET Socket; 00031 INT ErrorCode, OldErrorCode; 00032 INT Status; 00033 BOOLEAN TryAgain = TRUE; 00034 DPRINT("connect: %lx, %p, %lx\n", s, name, namelen); 00035 00036 /* Enter prolog */ 00037 if ((ErrorCode = WsApiProlog(&Process, &Thread)) == ERROR_SUCCESS) 00038 { 00039 /* Get the Socket Context */ 00040 if ((Socket = WsSockGetSocket(s))) 00041 { 00042 while (TRUE) 00043 { 00044 /* Make the call */ 00045 Status = Socket->Provider->Service.lpWSPConnect(s, 00046 name, 00047 namelen, 00048 NULL, 00049 NULL, 00050 NULL, 00051 NULL, 00052 &ErrorCode); 00053 00054 /* Check if error code was due to the host not being found */ 00055 if ((Status == SOCKET_ERROR) && 00056 ((ErrorCode == WSAEHOSTUNREACH) || 00057 (ErrorCode == WSAENETUNREACH))) 00058 { 00059 /* Check if we can try again */ 00060 if (TryAgain) 00061 { 00062 /* Save the old error code */ 00063 OldErrorCode = ErrorCode; 00064 00065 /* Make sure we don't retry 3 times */ 00066 TryAgain = FALSE; 00067 00068 /* Make the RAS Auto-dial attempt */ 00069 if (WSAttemptAutodialAddr(name, namelen)) continue; 00070 } 00071 else 00072 { 00073 /* Restore the error code */ 00074 ErrorCode = OldErrorCode; 00075 } 00076 } 00077 00078 /* Break out of the loop */ 00079 break; 00080 } 00081 00082 /* Deference the Socket Context */ 00083 WsSockDereference(Socket); 00084 00085 /* Return Provider Value */ 00086 if (Status == ERROR_SUCCESS) return Status; 00087 00088 /* If everything seemed fine, then the WSP call failed itself */ 00089 if (ErrorCode == NO_ERROR) ErrorCode = WSASYSCALLFAILURE; 00090 } 00091 else 00092 { 00093 /* No Socket Context Found */ 00094 ErrorCode = WSAENOTSOCK; 00095 } 00096 } 00097 00098 /* If this is Winsock 1.1, normalize the error code */ 00099 if ((ErrorCode == WSAEALREADY) && (LOBYTE(Process->Version) == 1)) 00100 { 00101 /* WS 1.1 apps expect this */ 00102 ErrorCode = WSAEINVAL; 00103 } 00104 00105 /* Return with an Error */ 00106 SetLastError(ErrorCode); 00107 return SOCKET_ERROR; 00108 } 00109 00110 /* 00111 * @implemented 00112 */ 00113 INT 00114 WSAAPI 00115 listen(IN SOCKET s, 00116 IN INT backlog) 00117 { 00118 PWSSOCKET Socket; 00119 INT Status; 00120 INT ErrorCode; 00121 DPRINT("connect: %lx, %lx\n", s, backlog); 00122 00123 /* Check for WSAStartup */ 00124 if ((ErrorCode = WsQuickProlog()) == ERROR_SUCCESS) 00125 { 00126 /* Get the Socket Context */ 00127 if ((Socket = WsSockGetSocket(s))) 00128 { 00129 /* Make the call */ 00130 Status = Socket->Provider->Service.lpWSPListen(s, 00131 backlog, 00132 &ErrorCode); 00133 /* Deference the Socket Context */ 00134 WsSockDereference(Socket); 00135 00136 /* Return Provider Value */ 00137 if (Status == ERROR_SUCCESS) return Status; 00138 00139 /* If everything seemed fine, then the WSP call failed itself */ 00140 if (ErrorCode == NO_ERROR) ErrorCode = WSASYSCALLFAILURE; 00141 } 00142 else 00143 { 00144 /* No Socket Context Found */ 00145 ErrorCode = WSAENOTSOCK; 00146 } 00147 } 00148 00149 /* Return with an Error */ 00150 SetLastError(ErrorCode); 00151 return SOCKET_ERROR; 00152 } 00153 00154 /* 00155 * @implemented 00156 */ 00157 INT 00158 WSAAPI 00159 getpeername(IN SOCKET s, 00160 OUT LPSOCKADDR name, 00161 IN OUT INT FAR* namelen) 00162 { 00163 PWSSOCKET Socket; 00164 INT Status; 00165 INT ErrorCode; 00166 DPRINT("getpeername: %lx, %p, %lx\n", s, name, namelen); 00167 00168 /* Check for WSAStartup */ 00169 if ((ErrorCode = WsQuickProlog()) == ERROR_SUCCESS) 00170 { 00171 /* Get the Socket Context */ 00172 if ((Socket = WsSockGetSocket(s))) 00173 { 00174 /* Make the call */ 00175 Status = Socket->Provider->Service.lpWSPGetPeerName(s, 00176 name, 00177 namelen, 00178 &ErrorCode); 00179 /* Deference the Socket Context */ 00180 WsSockDereference(Socket); 00181 00182 /* Return Provider Value */ 00183 if (Status == ERROR_SUCCESS) return Status; 00184 00185 /* If everything seemed fine, then the WSP call failed itself */ 00186 if (ErrorCode == NO_ERROR) ErrorCode = WSASYSCALLFAILURE; 00187 } 00188 else 00189 { 00190 /* No Socket Context Found */ 00191 ErrorCode = WSAENOTSOCK; 00192 } 00193 } 00194 00195 /* Return with an Error */ 00196 SetLastError(ErrorCode); 00197 return SOCKET_ERROR; 00198 } 00199 00200 /* 00201 * @implemented 00202 */ 00203 INT 00204 WSAAPI 00205 getsockname(IN SOCKET s, 00206 OUT LPSOCKADDR name, 00207 IN OUT INT FAR* namelen) 00208 { 00209 PWSSOCKET Socket; 00210 INT Status; 00211 INT ErrorCode; 00212 DPRINT("getsockname: %lx, %p, %lx\n", s, name, namelen); 00213 00214 /* Check for WSAStartup */ 00215 if ((ErrorCode = WsQuickProlog()) == ERROR_SUCCESS) 00216 { 00217 /* Get the Socket Context */ 00218 if ((Socket = WsSockGetSocket(s))) 00219 { 00220 /* Make the call */ 00221 Status = Socket->Provider->Service.lpWSPGetSockName(s, 00222 name, 00223 namelen, 00224 &ErrorCode); 00225 00226 /* Deference the Socket Context */ 00227 WsSockDereference(Socket); 00228 00229 /* Return Provider Value */ 00230 if (Status == ERROR_SUCCESS) return Status; 00231 00232 /* If everything seemed fine, then the WSP call failed itself */ 00233 if (ErrorCode == NO_ERROR) ErrorCode = WSASYSCALLFAILURE; 00234 } 00235 else 00236 { 00237 /* No Socket Context Found */ 00238 ErrorCode = WSAENOTSOCK; 00239 } 00240 } 00241 00242 /* Return with an Error */ 00243 SetLastError(ErrorCode); 00244 return SOCKET_ERROR; 00245 } 00246 00247 /* 00248 * @implemented 00249 */ 00250 INT 00251 WSAAPI 00252 getsockopt(IN SOCKET s, 00253 IN INT level, 00254 IN INT optname, 00255 OUT CHAR FAR* optval, 00256 IN OUT INT FAR* optlen) 00257 { 00258 PWSPROCESS Process; 00259 PWSTHREAD Thread; 00260 PWSSOCKET Socket; 00261 INT ErrorCode; 00262 INT Status; 00263 WSAPROTOCOL_INFOW ProtocolInfo; 00264 PCHAR OldOptVal = NULL; 00265 INT OldOptLen = 0; 00266 DPRINT("getsockopt: %lx, %lx, %lx\n", s, level, optname); 00267 00268 /* Enter prolog */ 00269 if ((ErrorCode = WsApiProlog(&Process, &Thread)) == ERROR_SUCCESS) 00270 { 00271 /* Check if we're getting the open type */ 00272 if ((level == SOL_SOCKET) && (optname == SO_OPENTYPE)) 00273 { 00274 /* Validate size */ 00275 if (!(optlen) || (*optlen < sizeof(INT))) 00276 { 00277 /* Fail */ 00278 SetLastError(WSAEFAULT); 00279 return SOCKET_ERROR; 00280 } 00281 00282 /* Set the open type */ 00283 *optval = (CHAR)Thread->OpenType; 00284 *optlen = sizeof(INT); 00285 return ERROR_SUCCESS; 00286 } 00287 00288 /* Get the Socket Context */ 00289 if ((Socket = WsSockGetSocket(s))) 00290 { 00291 /* Check if ANSI data was requested */ 00292 if ((level == SOL_SOCKET) && (optname == SO_PROTOCOL_INFOA)) 00293 { 00294 /* Validate size and pointers */ 00295 if(!(optval) || 00296 !(optlen) || 00297 (*optlen < sizeof(WSAPROTOCOL_INFOA))) 00298 { 00299 /* Set return size */ 00300 *optlen = sizeof(WSAPROTOCOL_INFOA); 00301 00302 /* Dereference the socket and fail */ 00303 WsSockDereference(Socket); 00304 SetLastError(WSAEFAULT); 00305 return SOCKET_ERROR; 00306 } 00307 00308 /* It worked. Save the values */ 00309 OldOptLen = *optlen; 00310 OldOptVal = optval; 00311 00312 /* Hack them so WSP will know how to deal with it */ 00313 *optlen = sizeof(WSAPROTOCOL_INFOW); 00314 optval = (PCHAR)&ProtocolInfo; 00315 optname = SO_PROTOCOL_INFOW; 00316 } 00317 00318 /* Make the call */ 00319 Status = Socket->Provider->Service.lpWSPGetSockOpt(s, 00320 level, 00321 optname, 00322 optval, 00323 optlen, 00324 &ErrorCode); 00325 00326 /* Deference the Socket Context */ 00327 WsSockDereference(Socket); 00328 00329 /* Check provider value */ 00330 if (Status == ERROR_SUCCESS) 00331 { 00332 /* Did we use the A->W hack? */ 00333 if (!OldOptVal) return Status; 00334 00335 /* We did, so we have to convert the unicode info to ansi */ 00336 ErrorCode = MapUnicodeProtocolInfoToAnsi(&ProtocolInfo, 00337 (LPWSAPROTOCOL_INFOA) 00338 OldOptVal); 00339 00340 /* Return the length */ 00341 *optlen = OldOptLen; 00342 00343 /* Return success if this worked */ 00344 if (ErrorCode == ERROR_SUCCESS) return Status; 00345 } 00346 00347 /* If everything seemed fine, then the WSP call failed itself */ 00348 if (ErrorCode == NO_ERROR) ErrorCode = WSASYSCALLFAILURE; 00349 } 00350 else 00351 { 00352 /* No Socket Context Found */ 00353 ErrorCode = WSAENOTSOCK; 00354 } 00355 } 00356 00357 /* Return with an Error */ 00358 SetLastError(ErrorCode); 00359 return SOCKET_ERROR; 00360 } 00361 00362 /* 00363 * @implemented 00364 */ 00365 INT 00366 WSAAPI 00367 setsockopt(IN SOCKET s, 00368 IN INT level, 00369 IN INT optname, 00370 IN CONST CHAR FAR* optval, 00371 IN INT optlen) 00372 { 00373 PWSPROCESS Process; 00374 PWSTHREAD Thread; 00375 PWSSOCKET Socket; 00376 INT ErrorCode; 00377 INT Status; 00378 DPRINT("setsockopt: %lx, %lx, %lx\n", s, level, optname); 00379 00380 /* Enter prolog */ 00381 if ((ErrorCode = WsApiProlog(&Process, &Thread)) == ERROR_SUCCESS) 00382 { 00383 /* Check if we're changing the open type */ 00384 if (level == SOL_SOCKET && optname == SO_OPENTYPE) 00385 { 00386 /* Validate size */ 00387 if (optlen < sizeof(INT)) 00388 { 00389 /* Fail */ 00390 SetLastError(WSAEFAULT); 00391 return SOCKET_ERROR; 00392 } 00393 00394 /* Set the open type */ 00395 Thread->OpenType = *optval; 00396 return ERROR_SUCCESS; 00397 } 00398 00399 /* Get the Socket Context */ 00400 if ((Socket = WsSockGetSocket(s))) 00401 { 00402 /* Make the call */ 00403 Status = Socket->Provider->Service.lpWSPSetSockOpt(s, 00404 level, 00405 optname, 00406 optval, 00407 optlen, 00408 &ErrorCode); 00409 00410 /* Deference the Socket Context */ 00411 WsSockDereference(Socket); 00412 00413 /* Return Provider Value */ 00414 if (Status == ERROR_SUCCESS) return Status; 00415 00416 /* If everything seemed fine, then the WSP call failed itself */ 00417 if (ErrorCode == NO_ERROR) ErrorCode = WSASYSCALLFAILURE; 00418 } 00419 else 00420 { 00421 /* No Socket Context Found */ 00422 ErrorCode = WSAENOTSOCK; 00423 } 00424 } 00425 00426 /* Return with an Error */ 00427 SetLastError(ErrorCode); 00428 return SOCKET_ERROR; 00429 } 00430 00431 /* 00432 * @implemented 00433 */ 00434 INT 00435 WSAAPI 00436 shutdown(IN SOCKET s, 00437 IN INT how) 00438 { 00439 PWSSOCKET Socket; 00440 INT Status; 00441 INT ErrorCode; 00442 DPRINT("shutdown: %lx, %lx\n", s, how); 00443 00444 /* Check for WSAStartup */ 00445 if ((ErrorCode = WsQuickProlog()) == ERROR_SUCCESS) 00446 { 00447 /* Get the Socket Context */ 00448 if ((Socket = WsSockGetSocket(s))) 00449 { 00450 /* Make the call */ 00451 Status = Socket->Provider->Service.lpWSPShutdown(s, how, &ErrorCode); 00452 00453 /* Deference the Socket Context */ 00454 WsSockDereference(Socket); 00455 00456 /* Return Provider Value */ 00457 if (Status == ERROR_SUCCESS) return Status; 00458 00459 /* If everything seemed fine, then the WSP call failed itself */ 00460 if (ErrorCode == NO_ERROR) ErrorCode = WSASYSCALLFAILURE; 00461 } 00462 else 00463 { 00464 /* No Socket Context Found */ 00465 ErrorCode = WSAENOTSOCK; 00466 } 00467 } 00468 00469 /* Return with an Error */ 00470 SetLastError(ErrorCode); 00471 return SOCKET_ERROR; 00472 } 00473 00474 /* 00475 * @implemented 00476 */ 00477 INT 00478 WSAAPI 00479 WSAConnect(IN SOCKET s, 00480 IN CONST struct sockaddr *name, 00481 IN INT namelen, 00482 IN LPWSABUF lpCallerData, 00483 OUT LPWSABUF lpCalleeData, 00484 IN LPQOS lpSQOS, 00485 IN LPQOS lpGQOS) 00486 { 00487 PWSSOCKET Socket; 00488 INT Status; 00489 INT ErrorCode; 00490 DPRINT("WSAConnect: %lx, %lx, %lx, %p\n", s, name, namelen, lpCallerData); 00491 00492 /* Check for WSAStartup */ 00493 if ((ErrorCode = WsQuickProlog()) == ERROR_SUCCESS) 00494 { 00495 /* Get the Socket Context */ 00496 if ((Socket = WsSockGetSocket(s))) 00497 { 00498 /* Make the call */ 00499 Status = Socket->Provider->Service.lpWSPConnect(s, 00500 name, 00501 namelen, 00502 lpCallerData, 00503 lpCalleeData, 00504 lpSQOS, 00505 lpGQOS, 00506 &ErrorCode); 00507 /* Deference the Socket Context */ 00508 WsSockDereference(Socket); 00509 00510 /* Return Provider Value */ 00511 if (Status == ERROR_SUCCESS) return Status; 00512 00513 /* If everything seemed fine, then the WSP call failed itself */ 00514 if (ErrorCode == NO_ERROR) ErrorCode = WSASYSCALLFAILURE; 00515 } 00516 else 00517 { 00518 /* No Socket Context Found */ 00519 ErrorCode = WSAENOTSOCK; 00520 } 00521 } 00522 00523 /* Return with an Error */ 00524 SetLastError(ErrorCode); 00525 return SOCKET_ERROR; 00526 } 00527 00528 /* 00529 * @implemented 00530 */ 00531 BOOL 00532 WSAAPI 00533 WSAGetOverlappedResult(IN SOCKET s, 00534 IN LPWSAOVERLAPPED lpOverlapped, 00535 OUT LPDWORD lpcbTransfer, 00536 IN BOOL fWait, 00537 OUT LPDWORD lpdwFlags) 00538 { 00539 PWSSOCKET Socket; 00540 INT Status; 00541 INT ErrorCode; 00542 DPRINT("WSAGetOverlappedResult: %lx, %lx\n", s, lpOverlapped); 00543 00544 /* Check for WSAStartup */ 00545 if ((ErrorCode = WsQuickProlog()) == ERROR_SUCCESS) 00546 { 00547 /* Get the Socket Context */ 00548 if ((Socket = WsSockGetSocket(s))) 00549 { 00550 /* Make the call */ 00551 Status = Socket->Provider->Service.lpWSPGetOverlappedResult(s, 00552 lpOverlapped, 00553 lpcbTransfer, 00554 fWait, 00555 lpdwFlags, 00556 &ErrorCode); 00557 /* Deference the Socket Context */ 00558 WsSockDereference(Socket); 00559 00560 /* Return Provider Value */ 00561 if (Status) return Status; 00562 } 00563 else 00564 { 00565 /* No Socket Context Found */ 00566 ErrorCode = WSAENOTSOCK; 00567 } 00568 } 00569 00570 /* Return with an Error */ 00571 SetLastError(ErrorCode); 00572 return FALSE; 00573 } Generated on Sun May 27 2012 04:27:11 for ReactOS by
1.7.6.1
|