ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

sockctrl.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.