static void global_close_pipe(struct wpa_global_dst *dst) { wpa_printf(MSG_DEBUG, "CTRL: close pipe %p", dst); if (dst->overlap.hEvent) { eloop_unregister_event(dst->overlap.hEvent, sizeof(dst->overlap.hEvent)); CloseHandle(dst->overlap.hEvent); } if (dst->pipe != INVALID_HANDLE_VALUE) { /* * Could use FlushFileBuffers() here to guarantee that all data * gets delivered to the client, but that can block, so let's * not do this for now. * FlushFileBuffers(dst->pipe); */ CloseHandle(dst->pipe); } if (dst->prev) dst->prev->next = dst->next; else dst->priv->ctrl_dst = dst->next; if (dst->next) dst->next->prev = dst->prev; os_free(dst->rsp_buf); os_free(dst); }
void l2_packet_deinit(struct l2_packet_data *l2) { if (l2 == NULL) return; if (l2_ndisuio_global) { l2_ndisuio_global->refcount--; l2_ndisuio_global->l2[l2_ndisuio_global->refcount] = NULL; if (l2_ndisuio_global->refcount) { wpa_printf(MSG_DEBUG, "L2(NDISUIO): restore filtering " "ethertype to %04x", l2_ndisuio_global->first_proto); l2_ndisuio_set_ether_type( l2_ndisuio_global->first_proto); return; } #ifdef _WIN32_WCE wpa_printf(MSG_DEBUG, "L2(NDISUIO): Waiting for RX thread to " "stop"); SetEvent(l2_ndisuio_global->stop_request); /* * Cancel pending ReadFile() in the RX thread (if we were still * connected at this point). */ if (!DeviceIoControl(driver_ndis_get_ndisuio_handle(), IOCTL_CANCEL_READ, NULL, 0, NULL, 0, NULL, NULL)) { wpa_printf(MSG_DEBUG, "L2(NDISUIO): IOCTL_CANCEL_READ " "failed: %d", (int) GetLastError()); /* RX thread will exit blocking ReadFile once NDISUIO * notices that the adapter is disconnected. */ } WaitForSingleObject(l2_ndisuio_global->rx_thread, INFINITE); wpa_printf(MSG_DEBUG, "L2(NDISUIO): RX thread exited"); CloseHandle(l2_ndisuio_global->rx_thread); CloseHandle(l2_ndisuio_global->stop_request); CloseHandle(l2_ndisuio_global->ready_for_read); CloseHandle(l2_ndisuio_global->rx_processed); #endif /* _WIN32_WCE */ os_free(l2_ndisuio_global); l2_ndisuio_global = NULL; } #ifndef _WIN32_WCE CancelIo(driver_ndis_get_ndisuio_handle()); #endif /* _WIN32_WCE */ eloop_unregister_event(l2->rx_avail, sizeof(l2->rx_avail)); CloseHandle(l2->rx_avail); os_free(l2); }
static void l2_packet_deinit_timeout(void *eloop_ctx, void *timeout_ctx) { struct l2_packet_data *l2 = eloop_ctx; if (l2->rx_thread_done && WaitForSingleObject(l2->rx_thread_done, 2000) != WAIT_OBJECT_0) { wpa_printf(MSG_DEBUG, "l2_packet_winpcap: RX thread did not " "exit - kill it\n"); TerminateThread(l2->rx_thread, 0); } CloseHandle(l2->rx_thread_done); CloseHandle(l2->rx_thread); if (l2->pcap) pcap_close(l2->pcap); eloop_unregister_event(l2->rx_avail, sizeof(l2->rx_avail)); CloseHandle(l2->rx_avail); CloseHandle(l2->rx_done); CloseHandle(l2->rx_notify); os_free(l2); }
struct l2_packet_data * l2_packet_init( const char *ifname, const u8 *own_addr, unsigned short protocol, void (*rx_callback)(void *ctx, const u8 *src_addr, const u8 *buf, size_t len), void *rx_callback_ctx, int l2_hdr) { struct l2_packet_data *l2; if (l2_ndisuio_global == NULL) { l2_ndisuio_global = os_zalloc(sizeof(*l2_ndisuio_global)); if (l2_ndisuio_global == NULL) return NULL; l2_ndisuio_global->first_proto = protocol; } if (l2_ndisuio_global->refcount >= 2) { wpa_printf(MSG_ERROR, "L2(NDISUIO): Not more than two " "simultaneous connections allowed"); return NULL; } l2_ndisuio_global->refcount++; l2 = os_zalloc(sizeof(struct l2_packet_data)); if (l2 == NULL) return NULL; l2_ndisuio_global->l2[l2_ndisuio_global->refcount - 1] = l2; os_strlcpy(l2->ifname, ifname, sizeof(l2->ifname)); l2->rx_callback = rx_callback; l2->rx_callback_ctx = rx_callback_ctx; l2->l2_hdr = l2_hdr; if (own_addr) os_memcpy(l2->own_addr, own_addr, ETH_ALEN); if (l2_ndisuio_set_ether_type(protocol) < 0) { os_free(l2); return NULL; } if (l2_ndisuio_global->refcount > 1) { wpa_printf(MSG_DEBUG, "L2(NDISUIO): Temporarily setting " "filtering ethertype to %04x", protocol); if (l2_ndisuio_global->l2[0]) l2->rx_avail = l2_ndisuio_global->l2[0]->rx_avail; return l2; } l2->rx_avail = CreateEvent(NULL, TRUE, FALSE, NULL); if (l2->rx_avail == NULL) { os_free(l2); return NULL; } eloop_register_event(l2->rx_avail, sizeof(l2->rx_avail), l2_packet_rx_event, l2, NULL); #ifdef _WIN32_WCE l2_ndisuio_global->stop_request = CreateEvent(NULL, TRUE, FALSE, NULL); /* * This event is being set based on media connect/disconnect * notifications in driver_ndis.c. */ l2_ndisuio_global->ready_for_read = CreateEvent(NULL, TRUE, FALSE, TEXT("WpaSupplicantConnected")); l2_ndisuio_global->rx_processed = CreateEvent(NULL, TRUE, FALSE, NULL); if (l2_ndisuio_global->stop_request == NULL || l2_ndisuio_global->ready_for_read == NULL || l2_ndisuio_global->rx_processed == NULL) { if (l2_ndisuio_global->stop_request) { CloseHandle(l2_ndisuio_global->stop_request); l2_ndisuio_global->stop_request = NULL; } if (l2_ndisuio_global->ready_for_read) { CloseHandle(l2_ndisuio_global->ready_for_read); l2_ndisuio_global->ready_for_read = NULL; } if (l2_ndisuio_global->rx_processed) { CloseHandle(l2_ndisuio_global->rx_processed); l2_ndisuio_global->rx_processed = NULL; } eloop_unregister_event(l2->rx_avail, sizeof(l2->rx_avail)); os_free(l2); return NULL; } l2_ndisuio_global->rx_thread = CreateThread(NULL, 0, l2_packet_rx_thread, l2, 0, NULL); if (l2_ndisuio_global->rx_thread == NULL) { wpa_printf(MSG_INFO, "L2(NDISUIO): Failed to create RX " "thread: %d", (int) GetLastError()); eloop_unregister_event(l2->rx_avail, sizeof(l2->rx_avail)); CloseHandle(l2_ndisuio_global->stop_request); l2_ndisuio_global->stop_request = NULL; os_free(l2); return NULL; } #else /* _WIN32_WCE */ l2_ndisuio_start_read(l2, 0); #endif /* _WIN32_WCE */ return l2; }