dlls/ws2_32/socket.c
/***********************************************************************
 *              WS2_async_accept                (INTERNAL)
 *
 * This is the function called to satisfy the AcceptEx callback
 */
WS2_async_accept                (INTERNAL)
This is the function called to satisfy the AcceptEx callback
WS2_async_accept ( INTERNAL ) This is the function called to satisfy the AcceptEx callback
static NTSTATUS WS2_async_accept( void *arg, IO_STATUS_BLOCK *iosb, NTSTATUS status, void **apc )
{
    struct ws2_accept_async *wsa = arg;
    int len;
    char *addr;
    TRACE("status: 0x%x listen: %p, accept: %p\n", status, wsa->listen_socket, wsa->accept_socket);
    if (status == STATUS_ALERTED)
    {
        SERVER_START_REQ( accept_into_socket )
        {
            req->lhandle = wine_server_obj_handle( wsa->listen_socket );
            req->ahandle = wine_server_obj_handle( wsa->accept_socket );
            status = wine_server_call( req );
        }
        SERVER_END_REQ;
        if (status == STATUS_CANT_WAIT)
            return STATUS_PENDING;
        if (status == STATUS_INVALID_HANDLE)
        {
            FIXME("AcceptEx accepting socket closed but request was not cancelled\n");
            status = STATUS_CANCELLED;
        }
    }
    else if (status == STATUS_HANDLES_CLOSED)
        status = STATUS_CANCELLED;  
    if (status != STATUS_SUCCESS)
        goto finish;
    addr = ((char *)wsa->buf) + wsa->data_len;
    len = wsa->local_len - sizeof(int);
    WS_getsockname(HANDLE2SOCKET(wsa->accept_socket),
                   (struct WS_sockaddr *)(addr + sizeof(int)), &len);
    *(int *)addr = len;
    addr += wsa->local_len;
    len = wsa->remote_len - sizeof(int);
    WS_getpeername(HANDLE2SOCKET(wsa->accept_socket),
                   (struct WS_sockaddr *)(addr + sizeof(int)), &len);
    *(int *)addr = len;
    if (!wsa->read)
        goto finish;
    SERVER_START_REQ( register_async )
    {
        req->type           = ASYNC_TYPE_READ;
        req->async.handle   = wine_server_obj_handle( wsa->accept_socket );
        req->async.callback = wine_server_client_ptr( WS2_async_accept_recv );
        req->async.iosb     = wine_server_client_ptr( iosb );
        req->async.arg      = wine_server_client_ptr( wsa );
        status = wine_server_call( req );
    }
    SERVER_END_REQ;
    if (status != STATUS_PENDING)
        goto finish;
    return STATUS_MORE_PROCESSING_REQUIRED;
finish:
    iosb->u.Status = status;
    iosb->Information = 0;
    if (wsa->user_overlapped->hEvent)
        SetEvent(wsa->user_overlapped->hEvent);
    *apc = ws2_async_accept_apc;
    return status;
}
static NTSTATUS WS2_async_accept ( void * arg , IO_STATUS_BLOCK * iosb , NTSTATUS status , void * * apc ) { struct ws2_accept_async * wsa = arg ; int len ; char * addr ; TRACE ( " \n " , status , wsa -> listen_socket , wsa -> accept_socket ) ; if ( status == STATUS_ALERTED ) { SERVER_START_REQ ( accept_into_socket ) { req -> lhandle = wine_server_obj_handle ( wsa -> listen_socket ) ; req -> ahandle = wine_server_obj_handle ( wsa -> accept_socket ) ; status = wine_server_call ( req ) ; } SERVER_END_REQ ; if ( status == STATUS_CANT_WAIT ) return STATUS_PENDING ; if ( status == STATUS_INVALID_HANDLE ) { FIXME ( " \n " ) ; status = STATUS_CANCELLED ; } } else if ( status == STATUS_HANDLES_CLOSED ) status = STATUS_CANCELLED ; if ( status != STATUS_SUCCESS ) goto finish ; addr = ( ( char * ) wsa -> buf ) + wsa -> data_len ; len = wsa -> local_len - sizeof ( int ) ; WS_getsockname ( HANDLE2SOCKET ( wsa -> accept_socket ) , ( struct WS_sockaddr * ) ( addr + sizeof ( int ) ) , & len ) ; * ( int * ) addr = len ; addr += wsa -> local_len ; len = wsa -> remote_len - sizeof ( int ) ; WS_getpeername ( HANDLE2SOCKET ( wsa -> accept_socket ) , ( struct WS_sockaddr * ) ( addr + sizeof ( int ) ) , & len ) ; * ( int * ) addr = len ; if ( ! wsa -> read ) goto finish ; SERVER_START_REQ ( register_async ) { req -> type = ASYNC_TYPE_READ ; req -> async . handle = wine_server_obj_handle ( wsa -> accept_socket ) ; req -> async . callback = wine_server_client_ptr ( WS2_async_accept_recv ) ; req -> async . iosb = wine_server_client_ptr ( iosb ) ; req -> async . arg = wine_server_client_ptr ( wsa ) ; status = wine_server_call ( req ) ; } SERVER_END_REQ ; if ( status != STATUS_PENDING ) goto finish ; return STATUS_MORE_PROCESSING_REQUIRED ; finish : iosb -> u . Status = status ; iosb -> Information = 0 ; if ( wsa -> user_overlapped -> hEvent ) SetEvent ( wsa -> user_overlapped -> hEvent ) ; * apc = ws2_async_accept_apc ; return status ; }
WS2_async_accept                (INTERNAL)
 This is the function called to satisfy the AcceptEx callback
WS2_async_accept ( INTERNAL ) This is the function called to satisfy the AcceptEx callback
/* strange windows behavior */ /* WS2 Spec says size param is extra 16 bytes long...what do we put in it? */ /* The APC has finished but no completion should be sent for the operation yet, additional processing
     * needs to be performed by WS2_async_accept_recv() first. */