The `async_socket_win32` takes ownership of the provided `SOCKET_TRANSPORT_HANDLE` and is responsible for closing it. For that reason, it is not possible to re-open the `async_socket` after closing it. This is due to the fact that the socket is created by some external event, such as accepting an incoming connection and closing the underlying socket is not reversible.
**SRS_ASYNC_SOCKET_WIN32_42_004: [** `async_socket_create` shall increment the reference count on `execution_engine`. **]**
**SRS_ASYNC_SOCKET_WIN32_01_035: [** `async_socket_create` shall obtain the `PTP_POOL` from the execution engine passed to `async_socket_create` by calling `execution_engine_win32_get_threadpool`. **]**
**SRS_ASYNC_SOCKET_WIN32_01_093: [** While `async_socket` is OPENING or CLOSING, `async_socket_destroy` shall wait for the open to complete either successfully or with error. **]**
**SRS_ASYNC_SOCKET_WIN32_01_015: [** If `async_socket` is already OPEN or OPENING, `async_socket_open_async` shall fail and return a non-zero value. **]**
**SRS_ASYNC_SOCKET_WIN32_01_016: [** Otherwise `async_socket_open_async` shall initialize a thread pool environment by calling `InitializeThreadpoolEnvironment`. **]**
**SRS_ASYNC_SOCKET_WIN32_01_036: [** `async_socket_open_async` shall set the thread pool for the environment to the pool obtained from the execution engine by calling `SetThreadpoolCallbackPool`. **]**
**SRS_ASYNC_SOCKET_WIN32_01_058: [** `async_socket_open_async` shall create a threadpool IO by calling `CreateThreadpoolIo` and passing `socket_transport_get_underlying_socket`, the callback environment to it and `on_io_complete` as callback. **]**
**SRS_ASYNC_SOCKET_WIN32_01_020: [** `async_socket_close` shall wait for all executing `async_socket_send_async` and `async_socket_receive_async` APIs. **]**
**SRS_ASYNC_SOCKET_WIN32_01_040: [** `async_socket_close` shall wait for any executing callbacks by calling `WaitForThreadpoolIoCallbacks`, passing FALSE as `fCancelPendingCallbacks`. **]**
**SRS_ASYNC_SOCKET_WIN32_01_059: [** `async_socket_close` shall close the threadpool IO created in `async_socket_open_async` by calling `CloseThreadpoolIo`. **]**
**SRS_ASYNC_SOCKET_WIN32_01_089: [** If any of the buffers in `payload` has `buffer` set to NULL, `async_socket_send_async` shall fail and return `ASYNC_SOCKET_SEND_SYNC_ERROR`. **]**
**SRS_ASYNC_SOCKET_WIN32_01_090: [** If any of the buffers in `payload` has `length` set to 0, `async_socket_send_async` shall fail and return `ASYNC_SOCKET_SEND_SYNC_ERROR`. **]**
**SRS_ASYNC_SOCKET_WIN32_01_101: [** If the sum of buffer lengths for all the buffers in `payload` is greater than `UINT32_MAX`, `async_socket_send_async` shall fail and return `ASYNC_SOCKET_SEND_SYNC_ERROR`. **]**
**SRS_ASYNC_SOCKET_WIN32_01_026: [** If `on_send_complete` is NULL, `async_socket_send_async` shall fail and return `ASYNC_SOCKET_SEND_SYNC_ERROR`. **]**
**SRS_ASYNC_SOCKET_WIN32_01_097: [** If `async_socket` is not OPEN, `async_socket_send_async` shall fail and return `ASYNC_SOCKET_SEND_SYNC_NOT_OPEN`. **]**
**SRS_ASYNC_SOCKET_WIN32_01_028: [** Otherwise `async_socket_send_async` shall create a context for the send where the `payload`, `on_send_complete` and `on_send_complete_context` shall be stored. **]**
**SRS_ASYNC_SOCKET_WIN32_01_103: [** If the amount of memory needed to allocate the context and the `SOCKET_BUFFER` items is exceeding UINT32_MAX, `async_socket_send_async` shall fail and return `ASYNC_SOCKET_SEND_SYNC_ERROR`. **]**
**SRS_ASYNC_SOCKET_WIN32_01_056: [** `async_socket_send_async` shall set the `SOCKET_BUFFER` items to point to the memory/length of the buffers in `payload`. **]**
**SRS_ASYNC_SOCKET_WIN32_01_057: [** An event to be used for the `OVERLAPPED` structure passed to `socket_transport_send` shall be created and stored in the context. **]**
**SRS_ASYNC_SOCKET_WIN32_01_061: [** The `SOCKET_BUFFER` array associated with the context shall be sent by calling `socket_transport_send` and passing to it the `OVERLAPPED` structure with the event that was just created, `flags` set to 0, and `bytes_sent` set to NULL. **]**
**SRS_ASYNC_SOCKET_WIN32_01_106: [** If `socket_transport_send` fails with any other error, `async_socket_send_async` shall call `CancelThreadpoolIo` and return `ASYNC_SOCKET_SEND_SYNC_ERROR`. **]**
**SRS_ASYNC_SOCKET_WIN32_01_091: [** If any of the buffers in `payload` has `buffer` set to NULL, `async_socket_receive_async` shall fail and return a non-zero value. **]**
**SRS_ASYNC_SOCKET_WIN32_01_092: [** If any of the buffers in `payload` has `length` set to 0, `async_socket_receive_async` shall fail and return a non-zero value. **]**
**SRS_ASYNC_SOCKET_WIN32_01_096: [** If the sum of buffer lengths for all the buffers in `payload` is greater than `UINT32_MAX`, `async_socket_receive_async` shall fail and return a non-zero value. **]**
**SRS_ASYNC_SOCKET_WIN32_01_077: [** Otherwise `async_socket_receive_async` shall create a context for the send where the `payload`, `on_receive_complete` and `on_receive_complete_context` shall be stored. **]**
**SRS_ASYNC_SOCKET_WIN32_01_079: [** `async_socket_receive_async` shall set the WSABUF items to point to the memory/length of the buffers in `payload`. **]**
**SRS_ASYNC_SOCKET_WIN32_01_080: [** An event to be used for the `OVERLAPPED` structure passed to `socket_transport_receive` shall be created and stored in the context. **]**
**SRS_ASYNC_SOCKET_WIN32_01_082: [** A receive shall be started for the `WSABUF` array associated with the context calling `socket_transport_receive` and passing to it the `OVERLAPPED` structure with the event that was just created, `flags` set to 0, and `bytes_sent` set to NULL. **]**
**SRS_ASYNC_SOCKET_WIN32_01_105: [** If `socket_transport_receive` fails with any other error, `async_socket_receive_async` shall call `CancelThreadpoolIo` and return a non-zero value. **]**
- **SRS_ASYNC_SOCKET_WIN32_01_066: [** If `io_result` is `NO_ERROR`, the `on_send_complete` callback passed to `async_socket_send_async` shall be called with `on_send_complete_context` as argument and `ASYNC_SOCKET_SEND_OK`. **]**
- **SRS_ASYNC_SOCKET_WIN32_01_067: [** If `io_result` is not `NO_ERROR`, the `on_send_complete` callback passed to `async_socket_send_async` shall be called with `on_send_complete_context` as argument and `ASYNC_SOCKET_SEND_ERROR`. **]**
- **SRS_ASYNC_SOCKET_WIN32_01_102: [** If `io_result` is `NO_ERROR`, but the number of bytes send is different than the sum of all buffer sizes passed to `async_socket_send_async`, the `on_send_complete` callback passed to `async_socket_send_async` shall be called with `on_send_complete_context` as context and `ASYNC_SOCKET_SEND_ERROR`. **]**
- **SRS_ASYNC_SOCKET_WIN32_01_069: [** If `io_result` is `NO_ERROR`, the `on_receive_complete` callback passed to `async_socket_receive_async` shall be called with `on_receive_complete_context` as context, `ASYNC_SOCKET_RECEIVE_OK` as result and `number_of_bytes_transferred` as `bytes_received`. **]**
- **SRS_ASYNC_SOCKET_WIN32_42_001: [** If `io_result` is `ERROR_NETNAME_DELETED` or `ERROR_CONNECTION_ABORTED`, the `on_receive_complete` callback passed to `async_socket_receive_async` shall be called with `on_receive_complete_context` as context, `ASYNC_SOCKET_RECEIVE_ABANDONED` as result and 0 for `bytes_received`. **]**
- **SRS_ASYNC_SOCKET_WIN32_01_070: [** If `io_result` is not `NO_ERROR`, the `on_receive_complete` callback passed to `async_socket_receive_async` shall be called with `on_receive_complete_context` as context, `ASYNC_SOCKET_RECEIVE_ERROR` as result and 0 for `bytes_received`. **]**
- **SRS_ASYNC_SOCKET_WIN32_01_095: [** If `io_result` is `NO_ERROR`, but the number of bytes received is greater than the sum of all buffer sizes passed to `async_socket_receive_async`, the `on_receive_complete` callback passed to `async_socket_receive_async` shall be called with `on_receive_complete_context` as context, `ASYNC_SOCKET_RECEIVE_ERROR` as result and `number_of_bytes_transferred` for `bytes_received`. **]**
- **SRS_ASYNC_SOCKET_WIN32_42_003: [** If `io_result` is `NO_ERROR`, but the number of bytes received is 0, the `on_receive_complete` callback passed to `async_socket_receive_async` shall be called with `on_receive_complete_context` as context, `ASYNC_SOCKET_RECEIVE_ABANDONED` as result and 0 for `bytes_received`. **]**
**SRS_ASYNC_SOCKET_WIN32_01_068: [** `on_io_complete` shall close the event handle created in `async_socket_send_async`/`async_socket_receive_async`. **]**