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

socklife.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:        socklife.c
00005  * PURPOSE:     Socket Lifetime 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 SOCKET
00023 WSAAPI
00024 accept(IN  SOCKET s,
00025        OUT LPSOCKADDR addr,
00026        OUT INT FAR* addrlen)
00027 {
00028     /* Let WSA do it */
00029     return WSAAccept(s, addr, addrlen, NULL, 0);
00030 }
00031 
00032 /*
00033  * @implemented
00034  */
00035 INT
00036 WSAAPI
00037 bind(IN SOCKET s,
00038      IN CONST struct sockaddr *name,
00039      IN INT namelen)
00040 {
00041     PWSSOCKET Socket;
00042     INT Status;
00043     INT ErrorCode;
00044     DPRINT("bind: %lx, %p, %lx\n", s, name, namelen);
00045 
00046     /* Check for WSAStartup */
00047     if ((ErrorCode = WsQuickProlog()) == ERROR_SUCCESS)
00048     {
00049         /* Get the Socket Context */
00050         if ((Socket = WsSockGetSocket(s)))
00051         {
00052             /* Make the call */
00053             Status = Socket->Provider->Service.lpWSPBind(s,
00054                                                          name, 
00055                                                          namelen,
00056                                                          &ErrorCode);
00057             /* Deference the Socket Context */
00058             WsSockDereference(Socket);
00059 
00060             /* Return Provider Value */
00061             if (Status == ERROR_SUCCESS) return Status;
00062 
00063             /* If everything seemed fine, then the WSP call failed itself */
00064             if (ErrorCode == NO_ERROR) ErrorCode = WSASYSCALLFAILURE;
00065         }
00066         else
00067         {
00068             /* No Socket Context Found */
00069             ErrorCode = WSAENOTSOCK;
00070         }
00071     }
00072 
00073     /* Return with an Error */
00074     SetLastError(ErrorCode);
00075     return SOCKET_ERROR;
00076 }
00077 
00078 /*
00079  * @implemented
00080  */
00081 INT
00082 WSAAPI
00083 closesocket(IN SOCKET s)
00084 {
00085     PWSSOCKET Socket;
00086     INT Status;
00087     INT ErrorCode;
00088     DPRINT("closesocket: %lx\n", s);
00089 
00090     /* Check for WSAStartup */
00091     if ((ErrorCode = WsQuickProlog()) == ERROR_SUCCESS)
00092     {
00093         /* Get the Socket Context */
00094         if ((Socket = WsSockGetSocket(s)))
00095         {
00096             /* Make the call */
00097             Status = Socket->Provider->Service.lpWSPCloseSocket(s, &ErrorCode);
00098 
00099             /* Check if this is a provider socket */
00100             if ((Status == ERROR_SUCCESS) && (Socket->IsProvider))
00101             {
00102                 /* Disassociate the handle */
00103                 if (WsSockDisassociateHandle(Socket) == ERROR_SUCCESS)
00104                 {
00105                     /* Deference the Socket Context */
00106                     WsSockDereference(Socket);
00107                 }
00108 
00109                 /* Remove the last reference */
00110                 WsSockDereference(Socket);
00111 
00112                 /* Return success if everything is OK */
00113                 if (ErrorCode == ERROR_SUCCESS) return ErrorCode;
00114             }
00115         }
00116         else
00117         {
00118             /* No Socket Context Found */
00119             ErrorCode = WSAENOTSOCK;
00120         }
00121     }
00122 
00123     /* Return with an Error */
00124     SetLastError(ErrorCode);
00125     return SOCKET_ERROR;
00126 }
00127 
00128 /*
00129  * @implemented
00130  */
00131 SOCKET
00132 WSAAPI
00133 socket(IN INT af,
00134        IN INT type,
00135        IN INT protocol)
00136 {
00137     PWSPROCESS Process;
00138     PWSTHREAD Thread;
00139     DWORD Flags = 0;
00140     INT ErrorCode;
00141     DPRINT("socket: %lx, %lx, %lx\n", af, type, protocol);
00142 
00143     /* Enter prolog */
00144     if ((ErrorCode = WsApiProlog(&Process, &Thread)) != ERROR_SUCCESS)
00145     {
00146         /* Fail here */
00147         SetLastError(ErrorCode);
00148         return INVALID_SOCKET;
00149     }
00150 
00151     /* Check the current open type and use overlapped if it's default */
00152     if (!Thread->OpenType) Flags = WSA_FLAG_OVERLAPPED;
00153 
00154     /* Make the protocol negative if this is NETBIOS */
00155     if ((af == AF_NETBIOS) && (protocol > 0)) protocol *= -1;
00156 
00157     /* Now let WSA handle it */
00158     return WSASocketW(af, type, protocol, NULL, 0, Flags);
00159 }
00160 
00161 /*
00162  * @unimplemented
00163  */
00164 INT
00165 WSPAPI
00166 WPUCloseSocketHandle(IN SOCKET s,
00167                      OUT LPINT lpErrno)
00168 {
00169     UNIMPLEMENTED;
00170     return 0;
00171 }
00172 
00173 /*
00174  * @unimplemented
00175  */
00176 SOCKET
00177 WSPAPI
00178 WPUCreateSocketHandle(IN DWORD dwCatalogEntryId,
00179                       IN DWORD_PTR dwContext,
00180                       OUT LPINT lpErrno)
00181 {
00182     UNIMPLEMENTED;
00183     return (SOCKET)0;
00184 }
00185 
00186 /*
00187  * @implemented
00188  */
00189 SOCKET
00190 WSPAPI
00191 WPUModifyIFSHandle(IN DWORD dwCatalogEntryId,
00192                    IN SOCKET ProposedHandle,
00193                    OUT LPINT lpErrno)
00194 {
00195     SOCKET Handle = INVALID_SOCKET;
00196     DWORD ErrorCode = ERROR_SUCCESS;
00197     PWSPROCESS Process;
00198     PTCATALOG Catalog;
00199     PTCATALOG_ENTRY Entry;
00200     PWSSOCKET Socket;
00201     DPRINT("WPUModifyIFSHandle: %lx, %lx\n", dwCatalogEntryId, ProposedHandle);
00202 
00203     /* Get the current process */
00204     if ((Process = WsGetProcess()))
00205     {
00206         /* Get the Transport Catalog */
00207         if ((Catalog = WsProcGetTCatalog(Process)))
00208         {
00209             /* Get the entry for this ID */
00210             ErrorCode = WsTcGetEntryFromCatalogEntryId(Catalog,
00211                                                        dwCatalogEntryId,
00212                                                        &Entry);
00213             /* Check for success */
00214             if (ErrorCode == ERROR_SUCCESS)
00215             {
00216                 /* Create a socket object */
00217                 if ((Socket = WsSockAllocate()))
00218                 {
00219                     /* Initialize it */
00220                     WsSockInitialize(Socket, Entry);
00221 
00222                     /* Associate it */
00223                     ErrorCode = WsSockAssociateHandle(Socket,
00224                                                       ProposedHandle,
00225                                                       TRUE);
00226                     /* Check for success */
00227                     if (ErrorCode == ERROR_SUCCESS)
00228                     {
00229                         /* Return */
00230                         Handle = ProposedHandle;
00231                         *lpErrno = ERROR_SUCCESS;
00232                     }
00233                     else
00234                     {
00235                         /* Fail */
00236                         WsSockDereference(Socket);
00237                         *lpErrno = ErrorCode;
00238                     }
00239 
00240                     /* Dereference the extra count */
00241                     WsSockDereference(Socket);
00242                 }
00243                 else
00244                 {
00245                     /* No memory to allocate a socket */
00246                     *lpErrno = WSAENOBUFS;
00247                 }
00248 
00249                 /* Dereference the catalog entry */
00250                 WsTcEntryDereference(Entry);
00251             }
00252             else
00253             {
00254                 /* Entry not found */
00255                 *lpErrno = ErrorCode;
00256             }
00257         }
00258         else
00259         {
00260             /* Catalog not found */
00261             *lpErrno = WSANOTINITIALISED;
00262         }
00263     }
00264     else
00265     {
00266         /* Process not ready */
00267         *lpErrno = WSANOTINITIALISED;
00268     }
00269 
00270     /* Return */
00271     return Handle;
00272 }
00273 
00274 /*
00275  * @unimplemented
00276  */
00277 INT
00278 WSPAPI
00279 WPUQuerySocketHandleContext(IN SOCKET s,
00280                             OUT PDWORD_PTR lpContext,
00281                             OUT LPINT lpErrno)
00282 {
00283     UNIMPLEMENTED;
00284     return 0;
00285 }
00286 
00287 /*
00288  * @implemented
00289  */
00290 SOCKET
00291 WSAAPI
00292 WSAAccept(IN SOCKET s,
00293           OUT LPSOCKADDR addr,
00294           IN OUT LPINT addrlen,
00295           IN LPCONDITIONPROC lpfnCondition,
00296           IN DWORD_PTR dwCallbackData)
00297 {
00298     PWSPROCESS Process;
00299     PWSTHREAD Thread;
00300     PWSSOCKET Socket;
00301     DWORD OpenType;
00302     INT ErrorCode;
00303     SOCKET Status;
00304     DPRINT("WSAAccept: %lx, %lx, %lx, %p\n", s, addr, addrlen, lpfnCondition);
00305 
00306     /* Enter prolog */
00307     if ((ErrorCode = WsApiProlog(&Process, &Thread)) == ERROR_SUCCESS)
00308     {
00309         /* Get the Socket Context */
00310         if ((Socket = WsSockGetSocket(s)))
00311         {
00312             /* Get the old open type and set new one */
00313             OpenType = Thread->OpenType;
00314             Thread->OpenType = Socket->Overlapped ? 0 : SO_SYNCHRONOUS_NONALERT;
00315 
00316             /* Make the call */
00317             Status = Socket->Provider->Service.lpWSPAccept(s,
00318                                                            addr,
00319                                                            addrlen,
00320                                                            lpfnCondition,
00321                                                            dwCallbackData,
00322                                                            &ErrorCode);
00323             /* Restore open type */
00324             Thread->OpenType = OpenType;
00325 
00326             /* Deference the Socket Context */
00327             WsSockDereference(Socket);
00328 
00329             /* Check if we got a valid socket */
00330             if (Status != INVALID_SOCKET)
00331             {
00332                 /* Check if we got a new socket */
00333                 if (Status != s)
00334                 {
00335                     /* Add a new reference */
00336                     WsSockAddApiReference(Status);
00337                 }
00338 
00339                 /* Return */
00340                 return Status;
00341             }
00342         }
00343         else
00344         {
00345             /* No Socket Context Found */
00346             ErrorCode = WSAENOTSOCK;
00347         }
00348     }
00349 
00350     /* Return with an Error */
00351     SetLastError(ErrorCode);
00352     return INVALID_SOCKET;
00353 }
00354 
00355 /*
00356  * @implemented
00357  */
00358 SOCKET
00359 WSAAPI
00360 WSAJoinLeaf(IN SOCKET s,
00361             IN CONST struct sockaddr *name,
00362             IN INT namelen,
00363             IN LPWSABUF lpCallerData,
00364             OUT LPWSABUF lpCalleeData,
00365             IN LPQOS lpSQOS,
00366             IN LPQOS lpGQOS,
00367             IN DWORD dwFlags)
00368 {
00369     PWSPROCESS Process;
00370     PWSTHREAD Thread;
00371     PWSSOCKET Socket;
00372     DWORD OpenType;
00373     INT ErrorCode;
00374     SOCKET Status;
00375     DPRINT("WSAJoinLeaf: %lx, %lx, %lx\n", s, name, namelen);
00376 
00377     /* Enter prolog */
00378     if ((ErrorCode = WsApiProlog(&Process, &Thread)) == ERROR_SUCCESS)
00379     {
00380         /* Get the Socket Context */
00381         if ((Socket = WsSockGetSocket(s)))
00382         {
00383             /* Get the old open type and set new one */
00384             OpenType = Thread->OpenType;
00385             Thread->OpenType = Socket->Overlapped ? 0 : SO_SYNCHRONOUS_NONALERT;
00386 
00387             /* Make the call */
00388             Status = Socket->Provider->Service.lpWSPJoinLeaf(s,
00389                                                              name,
00390                                                              namelen,
00391                                                              lpCallerData,
00392                                                              lpCalleeData,
00393                                                              lpSQOS,
00394                                                              lpGQOS,
00395                                                              dwFlags,
00396                                                              &ErrorCode);
00397             /* Restore open type */
00398             Thread->OpenType = OpenType;
00399 
00400             /* Deference the Socket Context */
00401             WsSockDereference(Socket);
00402 
00403             /* Check if we got a valid socket */
00404             if (Status != INVALID_SOCKET)
00405             {
00406                 /* Check if we got a new socket */
00407                 if (Status != s)
00408                 {
00409                     /* Add a new reference */
00410                     WsSockAddApiReference(Status);
00411                 }
00412 
00413                 /* Return */
00414                 return Status;
00415             }
00416         }
00417         else
00418         {
00419             /* No Socket Context Found */
00420             ErrorCode = WSAENOTSOCK;
00421         }
00422     }
00423 
00424     /* Return with an Error */
00425     SetLastError(ErrorCode);
00426     return INVALID_SOCKET;
00427 }
00428 
00429 /*
00430  * @implemented
00431  */
00432 SOCKET
00433 WSAAPI
00434 WSASocketA(IN INT af,
00435            IN INT type,
00436            IN INT protocol,
00437            IN LPWSAPROTOCOL_INFOA lpProtocolInfo,
00438            IN GROUP g,
00439            IN DWORD dwFlags)
00440 {
00441     WSAPROTOCOL_INFOW ProtocolInfoW;
00442     LPWSAPROTOCOL_INFOW p = &ProtocolInfoW;
00443 
00444     /* Convert Protocol Info to Wide */
00445     if (lpProtocolInfo) 
00446     {    
00447         /* Copy the Data */
00448         memcpy(&ProtocolInfoW,
00449                lpProtocolInfo,
00450                sizeof(WSAPROTOCOL_INFOA) - sizeof(CHAR) * (WSAPROTOCOL_LEN + 1));
00451 
00452         /* Convert the String */
00453         MultiByteToWideChar(CP_ACP,
00454                             0,
00455                             lpProtocolInfo->szProtocol,
00456                             -1,
00457                             ProtocolInfoW.szProtocol,
00458                             sizeof(ProtocolInfoW.szProtocol) / sizeof(WCHAR));
00459     } 
00460     else 
00461     {
00462         /* No Protocol Info Specified */
00463         p = NULL;
00464     }
00465 
00466     /* Call the Unicode Function */
00467     return WSASocketW(af,
00468                       type,
00469                       protocol,
00470                       p,
00471                       g,
00472                       dwFlags);
00473 }
00474 
00475 /*
00476  * @implemented
00477  */
00478 SOCKET
00479 WSAAPI 
00480 WSASocketW(IN INT af,
00481            IN INT type,
00482            IN INT protocol,
00483            IN LPWSAPROTOCOL_INFOW lpProtocolInfo,
00484            IN GROUP g,
00485            IN DWORD dwFlags)
00486 {
00487     PWSPROCESS Process;
00488     PWSTHREAD Thread;
00489     INT ErrorCode;
00490     PTCATALOG Catalog;
00491     DWORD CatalogId;
00492     PTCATALOG_ENTRY CatalogEntry;
00493     LPWSAPROTOCOL_INFOW ProtocolInfo;
00494     DWORD OpenType;
00495     SOCKET Status = INVALID_SOCKET;
00496     DPRINT("WSASocketW: %lx, %lx, %lx, %p\n", af, type, protocol, lpProtocolInfo);
00497 
00498     /* Enter prolog */
00499     if ((ErrorCode = WsApiProlog(&Process, &Thread)) != ERROR_SUCCESS)
00500     {
00501         /* Fail now */
00502         SetLastError(ErrorCode);
00503         return INVALID_SOCKET;
00504     }
00505 
00506     /* Get the catalog */
00507     Catalog = WsProcGetTCatalog(Process);
00508 
00509     /* Find a Provider for the Catalog ID */
00510     if (lpProtocolInfo) 
00511     {   
00512         /* Get the catalog ID */
00513         CatalogId = lpProtocolInfo->dwCatalogEntryId;
00514 
00515         /* Get the Catalog Entry */
00516         ErrorCode = WsTcGetEntryFromCatalogEntryId(Catalog,
00517                                                    CatalogId,
00518                                                    &CatalogEntry);
00519     }
00520     else  
00521     {   
00522         /* No ID */
00523         CatalogId = 0;
00524 
00525 DoLookup:
00526         /* Get the Catalog Data from the Socket Info */
00527         ErrorCode = WsTcGetEntryFromTriplet(Catalog,
00528                                             af,
00529                                             type,
00530                                             protocol,
00531                                             CatalogId,
00532                                             &CatalogEntry);
00533     }
00534 
00535     /* Check for Success */
00536     if (ErrorCode == ERROR_SUCCESS)
00537     {
00538         /* Use the default Protocol Info if none given */
00539         ProtocolInfo = lpProtocolInfo ? lpProtocolInfo : &CatalogEntry->ProtocolInfo;
00540 
00541         /* Save the open type and set new one */
00542         OpenType = Thread->OpenType;
00543         Thread->OpenType = (dwFlags & WSA_FLAG_OVERLAPPED) ?
00544                             0 : SO_SYNCHRONOUS_NONALERT;
00545 
00546         /* Call the Provider to create the Socket */
00547         Status = CatalogEntry->Provider->Service.lpWSPSocket(af,
00548                                                              type,
00549                                                              protocol,
00550                                                              ProtocolInfo,
00551                                                              g,
00552                                                              dwFlags,
00553                                                              &ErrorCode);
00554         /* Restore open type */
00555         Thread->OpenType = OpenType;
00556 
00557         /* Get the catalog ID now, and dereference */
00558         CatalogId = ProtocolInfo->dwCatalogEntryId;
00559         WsTcEntryDereference(CatalogEntry);
00560 
00561         /* Did we fail with WSAEINPROGRESS and had no specific provider? */
00562         if ((Status == INVALID_SOCKET) && 
00563             (ErrorCode == WSAEINPROGRESS) && 
00564             !(lpProtocolInfo))
00565         {
00566             /* In that case, restart the lookup from this ID */
00567             goto DoLookup;
00568         }
00569 
00570         /* Check if we got a valid socket */
00571         if (Status != INVALID_SOCKET)
00572         {
00573             /* Add an API reference and return */
00574             WsSockAddApiReference(Status);
00575             return Status;
00576         }
00577     }
00578 
00579     /* Return with an Error */
00580     SetLastError(ErrorCode);
00581     return INVALID_SOCKET;
00582 }

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.