Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygensocklife.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
1.7.6.1
|