void StatusWindow::SendCommand(StatusCommand *_command) { if(hasFailed) { return; } EnterCriticalSection(&csReentrant); EnterCriticalSection(&csThreadAlive); if(!threadAlive) { if(otherThread != NULL) { CloseHandle(otherThread); } ResetEvent(eventCommandSent); ResetEvent(eventCommandAcknowledged); otherThread = CreateThread(NULL, 0, StatusWindow::ThreadProc, (LPVOID)this, 0, NULL); if(otherThread == NULL) { hasFailed = true; LeaveCriticalSection(&csReentrant); LeaveCriticalSection(&csThreadAlive); return; } CommandInit cmdInit; command = &cmdInit; SetEvent(eventCommandSent); DWORD rv; rv = WaitForSingleObject(eventCommandAcknowledged, 10000); if(rv != WAIT_OBJECT_0) { MessageBox(parentWindow, "Error while waiting for new thread.\r\n\r\nThere may be a stray thread lying around now,\r\nSuggest closing 3D Studio and checking the process list.", "Error", MB_OK | MB_ICONERROR); TerminateThread(otherThread, 0); CloseHandle(otherThread); hasFailed = true; LeaveCriticalSection(&csReentrant); LeaveCriticalSection(&csThreadAlive); return; } threadAlive = true; } command = _command; if(command->type == StatusCommand::COMMAND_CLOSE) threadAlive = false; SetEvent(eventCommandSent); DWORD rv; rv = WaitForSingleObject(eventCommandAcknowledged, 10000); if(rv != WAIT_OBJECT_0) { MessageBox(parentWindow, "Error while waiting for new thread.\r\n\r\nThere may be a stray thread lying around now,\r\nSuggest closing 3D Studio and checking the process list.", "Error", MB_OK | MB_ICONERROR); TerminateThread(otherThread, 0); CloseHandle(otherThread); hasFailed = true; LeaveCriticalSection(&csReentrant); LeaveCriticalSection(&csThreadAlive); return; } LeaveCriticalSection(&csThreadAlive); LeaveCriticalSection(&csReentrant); }
void CAudioCapture::Cancel(void) { if (m_hEvents[CANCEL_EVENT]) SetEvent(m_hEvents[CANCEL_EVENT]); }
NOEXPORT LRESULT CALLBACK window_proc(HWND main_window_handle, UINT message, WPARAM wParam, LPARAM lParam) { NOTIFYICONDATA nid; POINT pt; RECT rect; SERVICE_OPTIONS *section; unsigned int section_number; #if 0 if(message!=WM_CTLCOLORSTATIC && message!=WM_TIMER) s_log(LOG_DEBUG, "Window message: %d", message); #endif switch(message) { case WM_CREATE: #ifdef _WIN32_WCE /* create command bar */ command_bar_handle=CommandBar_Create(ghInst, main_window_handle, 1); if(!command_bar_handle) error_box("CommandBar_Create"); if(!CommandBar_InsertMenubar(command_bar_handle, ghInst, IDM_MAINMENU, 0)) error_box("CommandBar_InsertMenubar"); if(!CommandBar_AddAdornments(command_bar_handle, 0, 0)) error_box("CommandBar_AddAdornments"); #endif /* create child edit window */ edit_handle=CreateWindow(TEXT("EDIT"), NULL, WS_CHILD|WS_VISIBLE|WS_HSCROLL|WS_VSCROLL|ES_MULTILINE|ES_READONLY, 0, 0, 0, 0, main_window_handle, (HMENU)IDE_EDIT, ghInst, NULL); #ifndef _WIN32_WCE SendMessage(edit_handle, WM_SETFONT, (WPARAM)CreateFont(-12, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_RASTER_PRECIS, CLIP_DEFAULT_PRECIS, PROOF_QUALITY, DEFAULT_PITCH, TEXT("Courier")), MAKELPARAM(FALSE, 0)); /* no need to redraw right, now */ #endif /* NOTE: there's no return statement here -> proceeding with resize */ case WM_SIZE: GetClientRect(main_window_handle, &rect); #ifdef _WIN32_WCE MoveWindow(edit_handle, 0, CommandBar_Height(command_bar_handle), rect.right, rect.bottom-CommandBar_Height(command_bar_handle), TRUE); #else MoveWindow(edit_handle, 0, 0, rect.right, rect.bottom, TRUE); #endif UpdateWindow(edit_handle); /* CommandBar_Show(command_bar_handle, TRUE); */ return TRUE; case WM_SETFOCUS: SetFocus(edit_handle); return TRUE; case WM_TIMER: if(visible) update_logs(); return TRUE; case WM_CLOSE: ShowWindow(main_window_handle, SW_HIDE); return TRUE; case WM_SHOWWINDOW: visible=wParam; /* setup global variable */ if(tray_menu_handle) CheckMenuItem(tray_menu_handle, IDM_SHOW_LOG, visible ? MF_CHECKED : MF_UNCHECKED); if(visible) update_logs(); return TRUE; case WM_DESTROY: #ifdef _WIN32_WCE CommandBar_Destroy(command_bar_handle); #else if(main_menu_handle) DestroyMenu(main_menu_handle); #endif if(tray_menu_handle) DestroyMenu(tray_menu_handle); ZeroMemory(&nid, sizeof nid); nid.cbSize=sizeof nid; nid.hWnd=main_window_handle; nid.uID=1; nid.uFlags=NIF_TIP; /* not really sure what to put here, but it works */ Shell_NotifyIcon(NIM_DELETE, &nid); /* this removes the icon */ PostQuitMessage(0); KillTimer(main_window_handle, 0x29a); return TRUE; case WM_COMMAND: if(wParam>=IDM_PEER_MENU && wParam<IDM_PEER_MENU+number_of_sections) { for(section=service_options.next, section_number=0; section && wParam!=IDM_PEER_MENU+section_number; section=section->next, ++section_number) ; if(!section) return TRUE; if(save_text_file(section->file, section->chain)) return TRUE; #ifndef _WIN32_WCE if(main_menu_handle) CheckMenuItem(main_menu_handle, wParam, MF_CHECKED); #endif if(tray_menu_handle) CheckMenuItem(tray_menu_handle, wParam, MF_CHECKED); message_box(section->help, MB_ICONINFORMATION); return TRUE; } switch(wParam) { case IDM_ABOUT: DialogBox(ghInst, TEXT("AboutBox"), main_window_handle, (DLGPROC)about_proc); break; case IDM_SHOW_LOG: if(visible) { ShowWindow(main_window_handle, SW_HIDE); /* hide window */ } else { ShowWindow(main_window_handle, SW_SHOWNORMAL); /* show window */ SetForegroundWindow(main_window_handle); /* bring on top */ } break; case IDM_CLOSE: ShowWindow(main_window_handle, SW_HIDE); /* hide window */ break; case IDM_EXIT: if(!error_mode) /* signal_pipe is active */ signal_post(SIGNAL_TERMINATE); DestroyWindow(main_window_handle); break; case IDM_SAVE_LOG: if(!cmdline.service) /* security */ save_log(); break; case IDM_EDIT_CONFIG: #ifndef _WIN32_WCE if(!cmdline.service) /* security */ edit_config(main_window_handle); #endif break; case IDM_RELOAD_CONFIG: if(error_mode) /* unlock daemon_thread */ SetEvent(config_ready); else /* signal_pipe is active */ signal_post(SIGNAL_RELOAD_CONFIG); break; case IDM_REOPEN_LOG: signal_post(SIGNAL_REOPEN_LOG); break; case IDM_MANPAGE: #ifndef _WIN32_WCE if(!cmdline.service) /* security */ ShellExecute(main_window_handle, TEXT("open"), TEXT("stunnel.html"), NULL, NULL, SW_SHOWNORMAL); #endif break; case IDM_HOMEPAGE: #ifndef _WIN32_WCE if(!cmdline.service) /* security */ ShellExecute(main_window_handle, TEXT("open"), TEXT("http://www.stunnel.org/"), NULL, NULL, SW_SHOWNORMAL); #endif break; } return TRUE; case WM_SYSTRAY: /* a taskbar event */ switch(lParam) { #ifdef _WIN32_WCE case WM_LBUTTONDOWN: /* no right mouse button on Windows CE */ GetWindowRect(GetDesktopWindow(), &rect); /* no cursor position */ pt.x=rect.right; pt.y=rect.bottom-25; #else case WM_RBUTTONDOWN: GetCursorPos(&pt); #endif SetForegroundWindow(main_window_handle); TrackPopupMenuEx(GetSubMenu(tray_menu_handle, 0), TPM_BOTTOMALIGN, pt.x, pt.y, main_window_handle, NULL); PostMessage(main_window_handle, WM_NULL, 0, 0); break; #ifndef _WIN32_WCE case WM_LBUTTONDBLCLK: /* switch log window visibility */ if(visible) { ShowWindow(main_window_handle, SW_HIDE); /* hide window */ } else { ShowWindow(main_window_handle, SW_SHOWNORMAL); /* show window */ SetForegroundWindow(main_window_handle); /* bring on top */ } break; #endif } return TRUE; case WM_VALID_CONFIG: valid_config(); return TRUE; case WM_INVALID_CONFIG: invalid_config(); return TRUE; case WM_LOG: win_log((LPSTR)wParam); return TRUE; case WM_NEW_CHAIN: #ifndef _WIN32_WCE if(main_menu_handle) EnableMenuItem(main_menu_handle, IDM_PEER_MENU+wParam, MF_ENABLED); #endif if(tray_menu_handle) EnableMenuItem(tray_menu_handle, IDM_PEER_MENU+wParam, MF_ENABLED); return TRUE; case WM_CLIENTS: update_tray_icon((int)wParam); return TRUE; } return DefWindowProc(main_window_handle, message, wParam, lParam); }
/** Creates a new connection based on the settings found in the "instance" parameter * It will use the callbacks registered on the structure to process the pre/post connect operations * that the caller requires. * @see struct rdp_freerdp in freerdp.h * * @param instance - pointer to a rdp_freerdp structure that contains base information to establish the connection. * On return, this function will be initialized with the new connection's settings. * * @return TRUE if successful. FALSE otherwise. * */ BOOL freerdp_connect(freerdp* instance) { UINT status2 = CHANNEL_RC_OK; rdpRdp* rdp; BOOL status = TRUE; rdpSettings* settings; ConnectionResultEventArgs e; if (!instance) return FALSE; /* We always set the return code to 0 before we start the connect sequence*/ connectErrorCode = 0; freerdp_set_last_error(instance->context, FREERDP_ERROR_SUCCESS); clearChannelError(instance->context); ResetEvent(instance->context->abortEvent); rdp = instance->context->rdp; settings = instance->settings; instance->context->codecs = codecs_new(instance->context); IFCALLRET(instance->PreConnect, status, instance); if (status) status2 = freerdp_channels_pre_connect(instance->context->channels, instance); if (settings->KeyboardLayout == KBD_JAPANESE_INPUT_SYSTEM_MS_IME2002) { settings->KeyboardType = 7; settings->KeyboardSubType = 2; settings->KeyboardFunctionKey = 12; } if (!status || (status2 != CHANNEL_RC_OK)) { if (!freerdp_get_last_error(rdp->context)) freerdp_set_last_error(instance->context, FREERDP_ERROR_PRE_CONNECT_FAILED); WLog_ERR(TAG, "freerdp_pre_connect failed"); goto freerdp_connect_finally; } status = rdp_client_connect(rdp); /* --authonly tests the connection without a UI */ if (instance->settings->AuthenticationOnly) { WLog_ERR(TAG, "Authentication only, exit status %"PRId32"", !status); goto freerdp_connect_finally; } if (!status) goto freerdp_connect_finally; if (status) { UINT status2; if (instance->settings->DumpRemoteFx) { instance->update->pcap_rfx = pcap_open(instance->settings->DumpRemoteFxFile, TRUE); if (instance->update->pcap_rfx) instance->update->dump_rfx = TRUE; } IFCALLRET(instance->PostConnect, status, instance); if (status) status2 = freerdp_channels_post_connect(instance->context->channels, instance); if (!status || (status2 != CHANNEL_RC_OK) || !update_post_connect(instance->update)) { WLog_ERR(TAG, "freerdp_post_connect failed"); if (!freerdp_get_last_error(rdp->context)) freerdp_set_last_error(instance->context, FREERDP_ERROR_POST_CONNECT_FAILED); status = FALSE; goto freerdp_connect_finally; } if (instance->settings->PlayRemoteFx) { wStream* s; rdpUpdate* update; pcap_record record; update = instance->update; update->pcap_rfx = pcap_open(settings->PlayRemoteFxFile, FALSE); if (!update->pcap_rfx) { status = FALSE; goto freerdp_connect_finally; } else { update->play_rfx = TRUE; } while (pcap_has_next_record(update->pcap_rfx)) { pcap_get_next_record_header(update->pcap_rfx, &record); if (!(s = StreamPool_Take(rdp->transport->ReceivePool, record.length))) break; record.data = Stream_Buffer(s); pcap_get_next_record_content(update->pcap_rfx, &record); Stream_SetLength(s, record.length); Stream_SetPosition(s, 0); update->BeginPaint(update->context); update_recv_surfcmds(update, s); update->EndPaint(update->context); Stream_Release(s); } pcap_close(update->pcap_rfx); update->pcap_rfx = NULL; status = TRUE; goto freerdp_connect_finally; } } if (rdp->errorInfo == ERRINFO_SERVER_INSUFFICIENT_PRIVILEGES) freerdp_set_last_error(instance->context, FREERDP_ERROR_INSUFFICIENT_PRIVILEGES); SetEvent(rdp->transport->connectedEvent); freerdp_connect_finally: EventArgsInit(&e, "freerdp"); e.result = status ? 0 : -1; PubSub_OnConnectionResult(instance->context->pubSub, instance->context, &e); if (!status) freerdp_disconnect(instance); return status; }
/*! \internal \brief Uninitializes a module \note Should only be called from the context of the registrar thread */ void kmmint_exit_module(kmm_module_i * m) { kmm_plugin_i * p; /* Exiting a module happens in two stages. If the module state is running (there are active plugins) then those plugins must be exited. This has to be done from the plugin threads. The signal for the plugins to exit must be issued from the registrar. Therefore, we post messages to the registrar for each plugin we want to remove and exit kmmint_exit_module(). When the last plugin is exited, the plugin management code automatically signalls the registrar to remove the module. kmmint_exit_module() gets called again. This is the second stage, where we call exit_module() for the module and start unloading everything. */ EnterCriticalSection(&cs_kmm); /* get rid of any dangling uninitialized plugins */ LPOP(&(m->plugins), &p); while(p) { p->flags &= ~KMM_PLUGIN_FLAG_IN_MODLIST; kmmint_exit_plugin(p); /* release hold from kmm_provide_plugin() */ kmm_release_plugin(kmm_handle_from_plugin(p)); LPOP(&(m->plugins), &p); } if(m->state == KMM_MODULE_STATE_RUNNING) { int np = 0; m->state = KMM_MODULE_STATE_EXITPLUG; p = kmm_listed_plugins; while(p) { if(p->module == m && (p->flags & KMM_PLUGIN_FLAG_IN_MODCOUNT)) { kmm_hold_plugin(kmm_handle_from_plugin(p)); kmq_post_message(KMSG_KMM, KMSG_KMM_I_REG, KMM_REG_EXIT_PLUGIN, (void *) p); np++; } p = LNEXT(p); } #ifdef DEBUG assert(np == m->plugin_count); #endif if(np > 0) { /* we have to go back and wait for the plugins to exit. when the last plugin exits, it automatically posts EXIT_MODULE. We can pick up from there when this happens. */ LeaveCriticalSection(&cs_kmm); return; } } else { #ifdef DEBUG assert(m->plugin_count == 0 || m->state == KMM_MODULE_STATE_EXITPLUG); #endif /* if there are still plug-ins waiting to be unloaded, then we have to go back and wait for them to finish. Once they are done, kmmint_exit_module() will get called again. */ if (m->plugin_count > 0) { LeaveCriticalSection(&cs_kmm); return; } } if(m->flags & KMM_MODULE_FLAG_INITP) { exit_module_t p_exit_module; if(m->state > 0) m->state = KMM_MODULE_STATE_EXIT; p_exit_module = (exit_module_t) GetProcAddress(m->h_module, EXP_EXIT_MODULE); if(p_exit_module) { LeaveCriticalSection(&cs_kmm); (*p_exit_module)(kmm_handle_from_module(m)); EnterCriticalSection(&cs_kmm); } } if(m->state > 0) m->state = KMM_MODULE_STATE_EXITED; LeaveCriticalSection(&cs_kmm); if(!(m->flags & KMM_MODULE_FLAG_NOUNLOAD) && m->h_module) { FreeLibrary(m->h_module); } if(!(m->flags & KMM_MODULE_FLAG_NOUNLOAD) && m->h_resource && (m->h_resource != m->h_module)) { FreeLibrary(m->h_resource); } m->h_module = NULL; m->h_resource = NULL; if (m->flags & KMM_MODULE_FLAG_LOADED) { #ifdef DEBUG assert(kmm_active_modules > 0); #endif kmm_active_modules--; } m->flags = 0; /* release the hold obtained in kmmint_init_module() */ kmm_release_module(kmm_handle_from_module(m)); /* Last but not least, now see if there are any modules left that are running. If not, we can safely signal an exit. */ if (kmm_active_modules == 0) { SetEvent(evt_exit); } }
int WIN_cond_signal(ortp_cond_t * hCond) { SetEvent(*hCond); return 0; }
/****************************************************************************** * * Name: MrvDrvSend() * * Description: NDIS miniport serialized send packet routine * * Conditions for Use: Protocol driver will call this routine to pass Tx NDIS_PACKET * * Arguments: * IN NDIS_HANDLE MiniportAdapterContext * IN PPNDIS_PACKET Packet * IN UINT Flags * * Return Value: NDIS_STATUS_RESOURCES or NDIS_STATUS_PENDING * * Notes: * *****************************************************************************/ NDIS_STATUS MrvDrvSend( IN NDIS_HANDLE MiniportAdapterContext, IN PNDIS_PACKET Packet, IN UINT Flags) { PMRVDRV_ADAPTER Adapter; NDIS_STATUS Status; PNDIS_BUFFER pBuffer; UINT BufferCount; UINT Length; UINT TotalPacketLength = 0; PVOID pVirtualAddr; PTxCtrlNode pTxNode; PUCHAR pHeader = NULL; Status = NDIS_STATUS_SUCCESS; Adapter = (PMRVDRV_ADAPTER)MiniportAdapterContext; DBGPRINT(DBG_TX, (L"+MrvDrvSend()\n")); // printf ("+MrvDrvSend()\n"); // In Deep Sleep Mode no packet can be sent out //012207 //if (Adapter->IsDeepSleep) if( !IsThisDsState(Adapter, DS_STATE_NONE) ) { //Status = NDIS_STATUS_NO_CABLE; return NDIS_STATUS_FAILURE; } // Check device removal status if( Adapter->SurpriseRemoved == TRUE ) { DBGPRINT(DBG_TX|DBG_WARNING,(TEXT("[MrvSend]: NDIS_STATUS_FAILURE by supriseRemoved\r\n"))); return NDIS_STATUS_FAILURE; } if( Adapter->bIsPendingReset == TRUE || Adapter->ChipResetting == 1) { DBGPRINT(DBG_TX|DBG_CMD|DBG_WARNING,(L"[MrvSend]: NDIS RETURN FAILURE by bIsPendingReset or ChipReset\r\n")); return NDIS_STATUS_FAILURE; } if ( Adapter->MediaConnectStatus == NdisMediaStateDisconnected ) { DBGPRINT(DBG_TX|DBG_WARNING, (L"***WARNING: OS attempted to send packet while disconnected!\r\n")); if (IsIndicateDisconnect(Adapter) == TRUE) { Ndis_MediaStatus_Notify(Adapter,NDIS_STATUS_MEDIA_DISCONNECT); } else { NdisMSleep(100000); ///Sleep 100ms temporally } //dralee_20060712 ResetAllScanTypeAndPower(Adapter); CleanUpSingleTxBuffer(Adapter); ResetRxPDQ(Adapter); return NDIS_STATUS_FAILURE; } if( Adapter->bIsScanInProgress == TRUE ) { return NDIS_STATUS_SUCCESS; } *((ULONG *)(&Packet->MacReserved[0])) = GetTickCount(); // check if in key absent state, if so, block all packet other than // 802.1x if ( (Adapter->EncryptionStatus == Ndis802_11Encryption2KeyAbsent )|| (Adapter->EncryptionStatus == Ndis802_11Encryption3KeyAbsent ) ) { pTxNode = &Adapter->TxNode; NdisQueryPacket( Packet, NULL, &BufferCount, &pBuffer, &TotalPacketLength ); if (!pBuffer || !BufferCount || !TotalPacketLength) { return NDIS_STATUS_FAILURE; } NdisQueryBuffer(pBuffer, &pVirtualAddr, &Length); pHeader = (PUCHAR)pVirtualAddr; if ( TotalPacketLength < 14 ) { // malformed packet, blocked! DBGPRINT(DBG_TX|DBG_WARNING,(L"Got packet with size less than 14 bytes, reject!\n")); return NDIS_STATUS_FAILURE; } if ( (pHeader[12] != 0x88) || (pHeader[13] != 0x8E) ) { DBGPRINT(DBG_TX|DBG_WARNING,(L"Still no key and packet type(0x%x 0x%x)is not 802.1x , drop!\n", pHeader[12], pHeader[13])); return NDIS_STATUS_FAILURE; } }// if ( (Adapter->EncryptionStatus == Ndis802_11Encryption2KeyAbsent )|| (Adapter->EncryptionStatus == Ndis802_11Encryption3KeyAbsent ) ) if(Adapter->TCloseWZCFlag==WZC_Ignore_Send_EAPOL_START) { if ( (Adapter->EncryptionStatus == Ndis802_11Encryption2Enabled )||(Adapter->EncryptionStatus == Ndis802_11Encryption2KeyAbsent )||(Adapter->EncryptionStatus == Ndis802_11Encryption3Enabled )||(Adapter->EncryptionStatus == Ndis802_11Encryption3KeyAbsent ) ) { pTxNode = &Adapter->TxNode; NdisQueryPacket( Packet, NULL, &BufferCount, &pBuffer, &TotalPacketLength ); if (!pBuffer || !BufferCount || !TotalPacketLength) { return NDIS_STATUS_FAILURE; } NdisQueryBuffer(pBuffer, &pVirtualAddr, &Length); pHeader = (PUCHAR)pVirtualAddr; if ( (pHeader[12] == 0x88) && (pHeader[13] == 0x8E)&& (pHeader[14] == 0x01) &&(pHeader[15] == 0x01) ) { DBGPRINT(DBG_TX|DBG_HELP,(L"Temporary don't send EAPOL-start!!EncryptionStatus=0x%x, (0x%x, 0x%x, 0x%x, 0x%x)\n", Adapter->EncryptionStatus, pHeader[12], pHeader[13], pHeader[14], pHeader[15])); return NDIS_STATUS_SUCCESS; } } } EnterCriticalSection(&Adapter->TxCriticalSection); if(Adapter->TxPacketCount >= (MAX_TX_PACKETS-1) ) { UCHAR sts; //DBGPRINT(DBG_ERROR,(L"Tx queue is still full (count=%d), return FAILURE for this packet\r\n",Adapter->TxPacketCount)); sts = TxPacketEnQueue(Adapter, Packet); if( sts == TRUE ) //101607 { Adapter->TxPacketCount++; LeaveCriticalSection(&Adapter->TxCriticalSection); return NDIS_STATUS_SUCCESS; } else if ( sts == EQ_REPLACE_QUEUE ) { LeaveCriticalSection(&Adapter->TxCriticalSection); DBGPRINT(DBG_ERROR,(L"Replace a queued packet:%d\n\r",Adapter->TxPacketCount)); return NDIS_STATUS_SUCCESS; } else { LeaveCriticalSection(&Adapter->TxCriticalSection); //NdisMSleep(2000); DBGPRINT(DBG_ERROR,(L"Throw out current packet:%d\n\r",Adapter->TxPacketCount)); //return success otherwise the endpoint may retransmit this packet that low down the throughput. return NDIS_STATUS_SUCCESS; } } //record how many tx pkt is sent. Adapter->TxPacketSend++; DBGPRINT(DBG_TX|DBG_HELP,(L"[Marvell:MrvDrvSend] Adapter->TxPacketSend=%d\n", Adapter->TxPacketSend)); if ( TxPacketEnQueue(Adapter, Packet) != TRUE) { LeaveCriticalSection(&Adapter->TxCriticalSection); return NDIS_STATUS_SUCCESS; } Adapter->TxPacketCount++; LeaveCriticalSection(&Adapter->TxCriticalSection); if ( Adapter->SentPacket == NULL && Adapter->TxLock == 0 ) { // Fire TxThread! Adapter->SoftIntStatus |= MRVL_SOFT_INT_TxRequest; SetEvent(Adapter->hControllerInterruptEvent); } return NDIS_STATUS_SUCCESS; return Status; }
DWORD WINAPI Transporter(LPVOID lpParam) { //create message queue and signalize MSG msg; PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE); if (!SetEvent(ghTransporterQueueEvent)) { return (EXIT_FAILURE); } //waiting until store thread create message queue WaitForSingleObject(ghStoreQueueEvent, INFINITE); //waiting until power block threads create message queues WaitForMultipleObjects(nBlocks, ghPowerBlockQueueEvent, TRUE, INFINITE); //message loop BOOL bRetFI, bRetPB; int fuelWeight; int emptyBlock; while (TRUE) { //check terminate flag if (terminate) { break; } //initial transport position setfillstyle(1, cGREY); bar(30, 260, 50, 280); //post the message to store that transporter is waiting the load if (PostThreadMessage( dwThreadStoreId, //thread id destination WM_TRANSPORT_EMPTY, //message type 0, //no parameters 0 ) == 0) { //handle error return (EXIT_FAILURE); } //waiting for the store fuel item if ((bRetFI = GetMessage( &msg, //pointer to MSG structure NULL, //retrive messages from any windows belong this thread WM_FUEL_LOADING, //message filtering WM_FUEL_LOADING )) == 0) { //WM_QUIT arrived //terminate the thread break; } else if (bRetFI == -1) { //handle error return (EXIT_FAILURE); } else { //visualisation of loading state setfillstyle(1, cGREEN); bar(30, 260, 50, 280); //get fuel weight value fuelWeight = (int)msg.lParam; //waiting for the first empty power block if ((bRetPB = GetMessage( &msg, //pointer to MSG structure NULL, //retrive messages from any windows belong this thread WM_POWER_BLOCK_EMPTY, //message filtering WM_POWER_BLOCK_EMPTY )) == 0) { //WM_QUIT arrived //terminate the thread break; } else if (bRetPB == -1) { //handle error return (EXIT_FAILURE); } else { //get number of empty power block emptyBlock = (int)msg.lParam; } } //visualisation of transferring fuel to appropriate power block for (int i = 0; i < emptyBlock * 80 + 80; ++i) { setfillstyle(1, cGREEN); bar(i + 30, 260, i + 50, 280); delay(SUSPEND_FACT / 50); setfillstyle(1, cWHITE); bar(i + 30, 260, i + 50, 280); } //unload transport position setfillstyle(1, cGREEN); bar(emptyBlock * 80 + 110, 260, emptyBlock * 80 + 130, 280); //post message that transporter is arrived if (PostThreadMessage( dwThreadPowerBlockId[emptyBlock], //thread id destination WM_FUEL_ARRIVED, //message type 0, (LPARAM)fuelWeight //take the fuel weight ) == 0) { //handle error return (EXIT_FAILURE); } //waiting until power block unload the fuel if ((bRetPB = GetMessage(&msg, //pointer to MSG structure NULL, //retrive messages from any windows belong this thread WM_FUEL_UNLOAD, //message filtering WM_FUEL_UNLOAD )) == 0) { //WM_QUIT arrived //terminate the thread break; } else if (bRetPB == -1) { //handle error return (EXIT_FAILURE); } else { //visualisation of transferring back to store fuel item for (int i = emptyBlock * 80 + 80; i >= 0; --i) { setfillstyle(1, cGREY); bar(i + 30, 260, i + 50, 280); delay(SUSPEND_FACT / 100); setfillstyle(1, cWHITE); bar(i + 30, 260, i + 50, 280); } } } return (EXIT_SUCCESS); }
DWORD WINAPI PowerBlock(LPVOID lpParam) { //adduction parameter to index value int index = *((int *)lpParam); //create message queue and signalize MSG msg; PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE); if (!SetEvent(ghPowerBlockQueueEvent[index])) { return (EXIT_FAILURE); } //waiting until transporter thread create message queue WaitForSingleObject(ghTransporterQueueEvent, INFINITE); //message loop BOOL bRet; int fuelWeight; while (TRUE) { //check terminate flag if (terminate) { break; } //post the message to transporter that power block is empty if (PostThreadMessage( dwThreadTransporterId, //thread id destination WM_POWER_BLOCK_EMPTY, //message type 0, (LPARAM)index //number of power block ) == 0) { //handle error return (EXIT_FAILURE); } //waiting for the transporter if ((bRet = GetMessage( &msg, //pointer to MSG structure NULL, //retrive messages from any windows belong this thread WM_FUEL_ARRIVED, //message filtering WM_FUEL_ARRIVED )) == 0) { //WM_QUIT arrived //terminate the thread break; } else if (bRet == -1) { //handle error return (EXIT_FAILURE); } else { //get fuel weight value fuelWeight = (int)msg.lParam; } //visualisation of loading fuel to appropriate power block for (int i = 0; i < fuelWeight; ++i) { delay(SUSPEND_FACT / 2); setfillstyle(1, cGREEN); bar(index * 80 + 90, 235 - i * 25, index * 80 + 150, 255 - i * 25); } //post the message that power block is full if (PostThreadMessage( dwThreadTransporterId, //thread id destination WM_FUEL_UNLOAD, //message type 0, 0 //take the fuel weight ) == 0) { //handle error return (EXIT_FAILURE); } //visualisation of consumption the fuel for (int i = maxLoad - fuelWeight; i < maxLoad; ++i) { delay(SUSPEND_FACT * 20); setfillstyle(1, cWHITE); bar(index * 80 + 90, i * 25 + 10, index * 80 + 150, i * 25 + 30); } } return (EXIT_SUCCESS); }
DWORD WINAPI BadConnection(LPVOID Param) { MSG msg; HWND hBadConnect; HACCOUNT ActualAccount; struct BadConnectionParam MyParam; NOTIFYICONDATA nid; char *NotIconText = Translate(" - connection error"), *src; TCHAR *dest; int i; MyParam=*(struct BadConnectionParam *)Param; ActualAccount=MyParam.account; #ifdef DEBUG_SYNCHRO DebugLog(SynchroFile,"BadConnect:Incrementing \"using threads\" %x (account %x)\n",ActualAccount->UsingThreads,ActualAccount); #endif SCIncFcn(ActualAccount->UsingThreads); // we will not use params in stack anymore SetEvent(MyParam.ThreadRunningEV); __try { hBadConnect=CreateDialogParam(YAMNVar.hInst,MAKEINTRESOURCE(IDD_DLGBADCONNECT),NULL,DlgProcYAMNBadConnection,(LPARAM)&MyParam); SendMessage(hBadConnect,WM_SETICON,ICON_BIG,(LPARAM)g_LoadIconEx(3)); SendMessage(hBadConnect,WM_SETICON,ICON_SMALL,(LPARAM)g_LoadIconEx(3)); memset(&nid, 0, sizeof(nid)); nid.cbSize=sizeof(NOTIFYICONDATA); nid.hWnd=hBadConnect; nid.hIcon=g_LoadIconEx(3); nid.uID=0; nid.uFlags=NIF_ICON | NIF_MESSAGE | NIF_TIP; nid.uCallbackMessage=WM_YAMN_NOTIFYICON; #ifdef DEBUG_SYNCHRO DebugLog(SynchroFile,"BadConnect:ActualAccountSO-read wait\n"); #endif if (WAIT_OBJECT_0 != WaitToReadFcn(ActualAccount->AccountAccessSO)) { #ifdef DEBUG_SYNCHRO DebugLog(SynchroFile,"BadConnect:ActualAccountSO-read wait failed\n"); #endif return 0; } #ifdef DEBUG_SYNCHRO DebugLog(SynchroFile,"BadConnect:ActualAccountSO-read enter\n"); #endif for (src=ActualAccount->Name,dest=nid.szTip,i=0;(*src != (TCHAR)0) && (i+1<sizeof(nid.szTip));*dest++=*src++); for (src=NotIconText;(*src != (TCHAR)0) && (i+1<sizeof(nid.szTip));*dest++=*src++); *dest=(TCHAR)0; if (ActualAccount->BadConnectN.Flags & YAMN_ACC_SND) CallService(MS_SKIN_PLAYSOUND,0,(LPARAM)YAMN_CONNECTFAILSOUND); if (ActualAccount->BadConnectN.Flags & YAMN_ACC_MSG) ShowWindow(hBadConnect,SW_SHOWNORMAL); if (ActualAccount->BadConnectN.Flags & YAMN_ACC_ICO) Shell_NotifyIcon(NIM_ADD,&nid); #ifdef DEBUG_SYNCHRO DebugLog(SynchroFile,"BadConnect:ActualAccountSO-read done\n"); #endif ReadDoneFcn(ActualAccount->AccountAccessSO); UpdateWindow(hBadConnect); while(GetMessage(&msg,NULL,0,0)) { TranslateMessage(&msg); DispatchMessage(&msg); } // now, write to file. Why? Because we want to write when was new mail last checked if ((ActualAccount->Plugin->Fcn != NULL) && (ActualAccount->Plugin->Fcn->WriteAccountsFcnPtr != NULL) && ActualAccount->AbleToWork) ActualAccount->Plugin->Fcn->WriteAccountsFcnPtr(); } __finally { #ifdef DEBUG_SYNCHRO DebugLog(SynchroFile,"BadConnect:Decrementing \"using threads\" %x (account %x)\n",ActualAccount->UsingThreads,ActualAccount); #endif SCDecFcn(ActualAccount->UsingThreads); } return 0; }
DWORD WINAPI Store(LPVOID lpParam) { //initialize the pseudorandom numbers generator unsigned int seed; seed = (unsigned int)time(NULL); srand(seed); //create message queue and signalize MSG msg; PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE); if (!SetEvent(ghStoreQueueEvent)) { return (EXIT_FAILURE); } //waiting until transporter thread create message queue WaitForSingleObject(ghTransporterQueueEvent, INFINITE); //message loop BOOL bRet; int fuelWeight; while (TRUE) { //check terminate flag if (terminate) { break; } //calculate fuel weight //it has mass range from 1 to maxLoad fuelWeight = rand() % maxLoad + 1; //visualisation of production of the fuel for (int i = 0; i < fuelWeight; ++i) { delay(SUSPEND_FACT * 2); setfillstyle(1, cGREY); bar(10, 235 - i * 25, 70, 255 - i * 25); } //wait the transporter if ((bRet = GetMessage(&msg, //pointer to MSG structure NULL, //retrive messages from any windows belong this thread WM_TRANSPORT_EMPTY, //message filtering WM_TRANSPORT_EMPTY)) == 0) { //WM_QUIT arrived //terminate the thread break; } else if (bRet == -1) { //handle error return (EXIT_FAILURE); } else { //load the fuel to the transporter //visualisation of load process for (int i = maxLoad - fuelWeight; i < maxLoad; ++i) { delay(SUSPEND_FACT / 2); setfillstyle(1, cWHITE); bar(10, i * 25 + 10, 70, i * 25 + 30); } //post the message if (PostThreadMessage(dwThreadTransporterId, //message for transporter thread WM_FUEL_LOADING, //message type 0, //no WPARAM (LPARAM)fuelWeight) //pass fuel weight as LPARAM == 0) { //handle error return (EXIT_FAILURE); } } } return (EXIT_SUCCESS); }
HRESULT WINAPI BaseRendererImpl_Receive(BaseRenderer *This, IMediaSample * pSample) { HRESULT hr = S_OK; REFERENCE_TIME start, stop; AM_MEDIA_TYPE *pmt; TRACE("(%p)->%p\n", This, pSample); if (This->pInputPin->end_of_stream || This->pInputPin->flushing) return S_FALSE; if (This->filter.state == State_Stopped) return VFW_E_WRONG_STATE; if (IMediaSample_GetMediaType(pSample, &pmt) == S_OK) { if (FAILED(This->pFuncsTable->pfnCheckMediaType(This, pmt))) { return VFW_E_TYPE_NOT_ACCEPTED; } } This->pMediaSample = pSample; IMediaSample_AddRef(pSample); if (This->pFuncsTable->pfnPrepareReceive) hr = This->pFuncsTable->pfnPrepareReceive(This, pSample); if (FAILED(hr)) { if (hr == VFW_E_SAMPLE_REJECTED) return S_OK; else return hr; } if (This->pFuncsTable->pfnPrepareRender) This->pFuncsTable->pfnPrepareRender(This); EnterCriticalSection(&This->csRenderLock); if ( This->filter.state == State_Paused ) { if (This->pFuncsTable->pfnOnReceiveFirstSample) This->pFuncsTable->pfnOnReceiveFirstSample(This, pSample); SetEvent(This->evComplete); } /* Wait for render Time */ if (SUCCEEDED(IMediaSample_GetTime(pSample, &start, &stop))) { hr = S_FALSE; RendererPosPassThru_RegisterMediaTime(This->pPosition, start); if (This->pFuncsTable->pfnShouldDrawSampleNow) hr = This->pFuncsTable->pfnShouldDrawSampleNow(This, pSample, &start, &stop); if (hr == S_OK) ;/* Do not wait: drop through */ else if (hr == S_FALSE) { if (This->pFuncsTable->pfnOnWaitStart) This->pFuncsTable->pfnOnWaitStart(This); LeaveCriticalSection(&This->csRenderLock); hr = QualityControlRender_WaitFor(This->qcimpl, pSample, This->RenderEvent); EnterCriticalSection(&This->csRenderLock); if (This->pFuncsTable->pfnOnWaitEnd) This->pFuncsTable->pfnOnWaitEnd(This); } else { LeaveCriticalSection(&This->csRenderLock); /* Drop Sample */ return S_OK; } } if (SUCCEEDED(hr)) { QualityControlRender_BeginRender(This->qcimpl); hr = This->pFuncsTable->pfnDoRenderSample(This, pSample); QualityControlRender_EndRender(This->qcimpl); } QualityControlRender_DoQOS(This->qcimpl); BaseRendererImpl_ClearPendingSample(This); LeaveCriticalSection(&This->csRenderLock); return hr; }
static int directsound_stream_init(cubeb * context, cubeb_stream ** stream, char const * stream_name, cubeb_stream_params stream_params, unsigned int latency, cubeb_data_callback data_callback, cubeb_state_callback state_callback, void * user_ptr) { struct cubeb_list_node * node; assert(context); *stream = NULL; /* create primary buffer */ DSBUFFERDESC bd; bd.dwSize = sizeof(DSBUFFERDESC); bd.dwFlags = DSBCAPS_PRIMARYBUFFER; bd.dwBufferBytes = 0; bd.dwReserved = 0; bd.lpwfxFormat = NULL; bd.guid3DAlgorithm = DS3DALG_DEFAULT; LPDIRECTSOUNDBUFFER primary; if (FAILED(context->dsound->CreateSoundBuffer(&bd, &primary, NULL))) { return 1; } WAVEFORMATEXTENSIBLE wfx; wfx.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE; wfx.Format.nChannels = stream_params.channels; wfx.Format.nSamplesPerSec = stream_params.rate; wfx.Format.cbSize = sizeof(wfx) - sizeof(wfx.Format); /* XXX fix channel mappings */ wfx.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT; switch (stream_params.format) { case CUBEB_SAMPLE_S16LE: wfx.Format.wBitsPerSample = 16; wfx.SubFormat = KSDATAFORMAT_SUBTYPE_PCM; break; case CUBEB_SAMPLE_FLOAT32LE: wfx.Format.wBitsPerSample = 32; wfx.SubFormat = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT; break; default: return CUBEB_ERROR_INVALID_FORMAT; } wfx.Format.nBlockAlign = (wfx.Format.wBitsPerSample * wfx.Format.nChannels) / 8; wfx.Format.nAvgBytesPerSec = wfx.Format.nSamplesPerSec * wfx.Format.nBlockAlign; wfx.Samples.wValidBitsPerSample = wfx.Format.wBitsPerSample; if (FAILED(primary->SetFormat((LPWAVEFORMATEX) &wfx))) { /* XXX free primary */ return CUBEB_ERROR; } primary->Release(); cubeb_stream * stm = (cubeb_stream *) calloc(1, sizeof(*stm)); assert(stm); stm->context = context; stm->params = stream_params; stm->data_callback = data_callback; stm->state_callback = state_callback; stm->user_ptr = user_ptr; InitializeCriticalSection(&stm->lock); /* create secondary buffer */ bd.dwFlags = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_GLOBALFOCUS | DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLPOSITIONNOTIFY; bd.dwBufferBytes = (DWORD) (wfx.Format.nSamplesPerSec / 1000.0 * latency * bytes_per_frame(stream_params)); if (bd.dwBufferBytes % bytes_per_frame(stream_params) != 0) { bd.dwBufferBytes += bytes_per_frame(stream_params) - (bd.dwBufferBytes % bytes_per_frame(stream_params)); } bd.lpwfxFormat = (LPWAVEFORMATEX) &wfx; if (FAILED(context->dsound->CreateSoundBuffer(&bd, &stm->buffer, NULL))) { return CUBEB_ERROR; } stm->buffer_size = bd.dwBufferBytes; LPDIRECTSOUNDNOTIFY notify; if (stm->buffer->QueryInterface(IID_IDirectSoundNotify, (LPVOID *) ¬ify) != DS_OK) { /* XXX free resources */ return CUBEB_ERROR; } DSBPOSITIONNOTIFY note[3]; for (int i = 0; i < 3; ++i) { note[i].dwOffset = (stm->buffer_size / 4) * i; note[i].hEventNotify = context->streams_event; } if (notify->SetNotificationPositions(3, note) != DS_OK) { /* XXX free resources */ return CUBEB_ERROR; } notify->Release(); refill_stream(stm, 1); /* XXX remove this, just a test that double refill does not overwrite existing data */ refill_stream(stm, 0); uint64_t pos; cubeb_stream_get_position(stm, &pos); stm->node = (struct cubeb_list_node *) calloc(1, sizeof(*node)); stm->node->stream = stm; EnterCriticalSection(&context->lock); if (!context->streams) { context->streams = stm->node; } else { node = context->streams; while (node->next) { node = node->next; } node->next = stm->node; stm->node->prev = node; } LeaveCriticalSection(&context->lock); SetEvent(context->streams_event); *stream = stm; return CUBEB_OK; }
DWORD Scheduler::SchedulerThreadProcPrivate() { HRESULT hr = S_OK; MSG msg; LONG lWait = INFINITE; BOOL bExitThread = FALSE; // Force the system to create a message queue for this thread. // (See MSDN documentation for PostThreadMessage.) PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE); // Signal to the scheduler that the thread is ready. SetEvent(m_hThreadReadyEvent); while( !bExitThread ) { // Wait for a thread message OR until the wait time expires. DWORD dwResult = MsgWaitForMultipleObjects(0, NULL, FALSE, lWait, QS_POSTMESSAGE); if (dwResult == WAIT_TIMEOUT) { // If we timed out, then process the samples in the queue hr = ProcessSamplesInQueue(&lWait); if (FAILED(hr)) { bExitThread = TRUE; } } while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { BOOL bProcessSamples = TRUE; switch (msg.message) { case eTerminate: bExitThread = TRUE; break; case eFlush: // Flushing: Clear the sample queue and set the event. m_ScheduledSamples.Clear(); lWait = INFINITE; SetEvent(m_hFlushEvent); break; case eSchedule: // Process as many samples as we can. if (bProcessSamples) { hr = ProcessSamplesInQueue(&lWait); if (FAILED(hr)) { bExitThread = TRUE; } bProcessSamples = (lWait != INFINITE); } break; } // switch } // while PeekMessage } // while (!bExitThread) return (SUCCEEDED(hr) ? 0 : 1); }
static void __serial_check_fds(SERIAL_DEVICE* serial) { IRP* irp; IRP* prev; SERIAL_TTY* tty; UINT32 result = 0; BOOL irp_completed = FALSE; ZeroMemory(&serial->tv, sizeof(struct timeval)); tty = serial->tty; /* scan every pending */ irp = list_peek(serial->pending_irps); while (irp) { DEBUG_SVC("MajorFunction %u", irp->MajorFunction); switch (irp->MajorFunction) { case IRP_MJ_READ: if (FD_ISSET(tty->fd, &serial->read_fds)) { irp->IoStatus = STATUS_SUCCESS; serial_process_irp_read(serial, irp); irp_completed = TRUE; } break; case IRP_MJ_WRITE: if (FD_ISSET(tty->fd, &serial->write_fds)) { irp->IoStatus = STATUS_SUCCESS; serial_process_irp_write(serial, irp); irp_completed = TRUE; } break; case IRP_MJ_DEVICE_CONTROL: if (serial_tty_get_event(tty, &result)) { DEBUG_SVC("got event result %u", result); irp->IoStatus = STATUS_SUCCESS; stream_write_UINT32(irp->output, result); irp->Complete(irp); irp_completed = TRUE; } break; default: DEBUG_SVC("no request found"); break; } prev = irp; irp = (IRP*) list_next(serial->pending_irps, irp); if (irp_completed || (prev->IoStatus == STATUS_SUCCESS)) { list_remove(serial->pending_irps, prev); SetEvent(serial->in_event); } } }
BOOL DebugMainLoop(void) { BOOL fFinished = FALSE; BOOL fTerminating = FALSE; while (!fFinished) { DEBUG_EVENT DebugEvent; // debugging event information DWORD dwContinueStatus = DBG_CONTINUE; // exception continuation PPROCESS_INFO pProcessInfo; PTHREAD_INFO pThreadInfo; // Wait for a debugging event to occur. The second parameter indicates // that the function does not return until a debugging event occurs. if(!WaitForDebugEvent(&DebugEvent, INFINITE)) { OutputDebug("WaitForDebugEvent: 0x%08lx", GetLastError()); return FALSE; } // Process the debugging event code. switch (DebugEvent.dwDebugEventCode) { case EXCEPTION_DEBUG_EVENT: { PEXCEPTION_RECORD pExceptionRecord = &DebugEvent.u.Exception.ExceptionRecord; NTSTATUS ExceptionCode = pExceptionRecord->ExceptionCode; // Process the exception code. When handling // exceptions, remember to set the continuation // status parameter (dwContinueStatus). This value // is used by the ContinueDebugEvent function. if (debugOptions.verbose_flag) { lprintf("EXCEPTION PID=%lu TID=%lu ExceptionCode=0x%lx dwFirstChance=%lu\n", DebugEvent.dwProcessId, DebugEvent.dwThreadId, pExceptionRecord->ExceptionCode, DebugEvent.u.Exception.dwFirstChance ); } // Find the process in the process list pProcessInfo = &g_Processes[DebugEvent.dwProcessId]; dwContinueStatus = DBG_EXCEPTION_NOT_HANDLED; if (DebugEvent.u.Exception.dwFirstChance) { if (pExceptionRecord->ExceptionCode == (DWORD)STATUS_BREAKPOINT) { // Signal the aedebug event if (!pProcessInfo->fBreakpointSignalled) { pProcessInfo->fBreakpointSignalled = TRUE; if (debugOptions.hEvent) { SetEvent(debugOptions.hEvent); CloseHandle(debugOptions.hEvent); } if (debugOptions.dwThreadId) { DWORD dwThreadId = debugOptions.dwThreadId; const DWORD dwFailed = (DWORD)-1; DWORD dwRet = dwFailed; pThreadInfo = &pProcessInfo->Threads[dwThreadId]; HANDLE hThread = pThreadInfo->hThread; if (hThread != NULL) { dwRet = ResumeThread(hThread); } if (dwRet == dwFailed) { lprintf("error: failed to resume thread %lu\n", dwThreadId); } } /* * We ignore first-chance breakpoints by default. * * We get one of these whenever we attach to a process. * But in some cases, we never get a second-chance, e.g., * when we're attached through MSVCRT's abort(). */ if (!debugOptions.breakpoint_flag) { dwContinueStatus = DBG_CONTINUE; break; } } } if (ExceptionCode == STATUS_WX86_BREAKPOINT) { if (!pProcessInfo->fWowBreakpointSignalled) { pProcessInfo->fWowBreakpointSignalled = TRUE; dwContinueStatus = DBG_CONTINUE; break; } } /* * Ignore thread naming exception. * * http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx * * TODO: Note down the thread name */ if (ExceptionCode == 0x406d1388) { dwContinueStatus = DBG_CONTINUE; break; } if (ExceptionCode == DBG_CONTROL_C || ExceptionCode == DBG_CONTROL_BREAK) { dwContinueStatus = DBG_CONTINUE; } else if (!debugOptions.first_chance) { // Ignore other first change exceptions break; } } dumpException(pProcessInfo->hProcess, &DebugEvent.u.Exception.ExceptionRecord); // Find the thread in the thread list THREAD_INFO_LIST::const_iterator it; for (it = pProcessInfo->Threads.begin(); it != pProcessInfo->Threads.end(); ++it) { DWORD dwThreadId = it->first; HANDLE hThread = it->second.hThread; if (dwThreadId != DebugEvent.dwThreadId && ExceptionCode != STATUS_BREAKPOINT && ExceptionCode != STATUS_WX86_BREAKPOINT && ExceptionCode != DBG_CONTROL_C && ExceptionCode != DBG_CONTROL_BREAK) { continue; } CONTEXT Context; if (!getThreadContext(pProcessInfo->hProcess, hThread, &Context)) { continue; } dumpStack(pProcessInfo->hProcess, hThread, &Context); if (!DebugEvent.u.Exception.dwFirstChance) { EXCEPTION_POINTERS ExceptionPointers; ExceptionPointers.ExceptionRecord = pExceptionRecord; ExceptionPointers.ContextRecord = &Context; MINIDUMP_EXCEPTION_INFORMATION ExceptionParam; ExceptionParam.ThreadId = DebugEvent.dwThreadId; ExceptionParam.ExceptionPointers = &ExceptionPointers; ExceptionParam.ClientPointers = FALSE; writeDump(DebugEvent.dwProcessId, pProcessInfo, &ExceptionParam); } } if (!DebugEvent.u.Exception.dwFirstChance) { /* * Terminate the process. As continuing would cause the JIT debugger * to be invoked again. */ fTerminating = TRUE; TerminateProcess(pProcessInfo->hProcess, (UINT)ExceptionCode); } break; } case CREATE_THREAD_DEBUG_EVENT: if (debugOptions.verbose_flag) { lprintf("CREATE_THREAD PID=%lu TID=%lu\n", DebugEvent.dwProcessId, DebugEvent.dwThreadId ); } // Add the thread to the thread list pProcessInfo = &g_Processes[DebugEvent.dwProcessId]; pThreadInfo = &pProcessInfo->Threads[DebugEvent.dwThreadId]; pThreadInfo->hThread = DebugEvent.u.CreateThread.hThread; break; case CREATE_PROCESS_DEBUG_EVENT: { HANDLE hFile = DebugEvent.u.CreateProcessInfo.hFile; char szImageName[MAX_PATH]; char *lpImageName = NULL; if (hFile && GetFileNameFromHandle(hFile, szImageName, _countof(szImageName))) { lpImageName = szImageName; } if (debugOptions.verbose_flag) { PCSTR lpModuleName = lpImageName ? getBaseName(lpImageName) : ""; lprintf("CREATE_PROCESS PID=%lu TID=%lu lpBaseOfImage=%p %s\n", DebugEvent.dwProcessId, DebugEvent.dwThreadId, DebugEvent.u.CreateProcessInfo.lpBaseOfImage, lpModuleName ); } HANDLE hProcess = DebugEvent.u.CreateProcessInfo.hProcess; pProcessInfo = &g_Processes[DebugEvent.dwProcessId]; pProcessInfo->hProcess = hProcess; pProcessInfo->fDumpWritten = !debugOptions.minidump; pThreadInfo = &pProcessInfo->Threads[DebugEvent.dwThreadId]; pThreadInfo->hThread = DebugEvent.u.CreateProcessInfo.hThread; if (!InitializeSym(hProcess, FALSE)) { OutputDebug("error: SymInitialize failed: 0x%08lx\n", GetLastError()); exit(EXIT_FAILURE); } SymRegisterCallback64(hProcess, &symCallback, 0); loadModule(hProcess, hFile, lpImageName, DebugEvent.u.CreateProcessInfo.lpBaseOfImage); break; } case EXIT_THREAD_DEBUG_EVENT: if (debugOptions.verbose_flag) { lprintf("EXIT_THREAD PID=%lu TID=%lu dwExitCode=0x%lx\n", DebugEvent.dwProcessId, DebugEvent.dwThreadId, DebugEvent.u.ExitThread.dwExitCode ); } // Remove the thread from the thread list pProcessInfo = &g_Processes[DebugEvent.dwProcessId]; // Dump the stack on abort() if (!fTerminating && isAbnormalExitCode(DebugEvent.u.ExitThread.dwExitCode)) { pThreadInfo = &pProcessInfo->Threads[DebugEvent.dwThreadId]; HANDLE hProcess = pProcessInfo->hProcess; HANDLE hThread = pThreadInfo->hThread; CONTEXT Context; if (getThreadContext(hProcess, hThread, &Context)) { dumpStack(hProcess, hThread, &Context); } } pProcessInfo->Threads.erase(DebugEvent.dwThreadId); break; case EXIT_PROCESS_DEBUG_EVENT: { if (debugOptions.verbose_flag) { lprintf("EXIT_PROCESS PID=%lu TID=%lu dwExitCode=0x%lx\n", DebugEvent.dwProcessId, DebugEvent.dwThreadId, DebugEvent.u.ExitProcess.dwExitCode ); } pProcessInfo = &g_Processes[DebugEvent.dwProcessId]; // Dump the stack on abort() if (!fTerminating && isAbnormalExitCode(DebugEvent.u.ExitThread.dwExitCode)) { pThreadInfo = &pProcessInfo->Threads[DebugEvent.dwThreadId]; HANDLE hProcess = pProcessInfo->hProcess; HANDLE hThread = pThreadInfo->hThread; CONTEXT Context; if (getThreadContext(hProcess, hThread, &Context)) { dumpStack(hProcess, hThread, &Context); } writeDump(DebugEvent.dwProcessId, pProcessInfo, nullptr); } // Remove the process from the process list g_Processes.erase(DebugEvent.dwProcessId); if (!SymCleanup(pProcessInfo->hProcess)) { OutputDebug("SymCleanup failed with 0x%08lx\n", GetLastError()); } if (g_Processes.empty()) { fFinished = TRUE; } break; } case LOAD_DLL_DEBUG_EVENT: { HANDLE hFile = DebugEvent.u.LoadDll.hFile; char szImageName[MAX_PATH]; char *lpImageName = NULL; if (hFile && GetFileNameFromHandle(hFile, szImageName, _countof(szImageName))) { lpImageName = szImageName; } if (debugOptions.verbose_flag) { PCSTR lpModuleName = lpImageName ? getBaseName(lpImageName) : ""; lprintf("LOAD_DLL PID=%lu TID=%lu lpBaseOfDll=%p %s\n", DebugEvent.dwProcessId, DebugEvent.dwThreadId, DebugEvent.u.LoadDll.lpBaseOfDll, lpModuleName ); } pProcessInfo = &g_Processes[DebugEvent.dwProcessId]; loadModule(pProcessInfo->hProcess, hFile, lpImageName, DebugEvent.u.LoadDll.lpBaseOfDll); break; } case UNLOAD_DLL_DEBUG_EVENT: if (debugOptions.verbose_flag) { lprintf("UNLOAD_DLL PID=%lu TID=%lu lpBaseOfDll=%p\n", DebugEvent.dwProcessId, DebugEvent.dwThreadId, DebugEvent.u.UnloadDll.lpBaseOfDll ); } pProcessInfo = &g_Processes[DebugEvent.dwProcessId]; SymUnloadModule64(pProcessInfo->hProcess, (UINT_PTR)DebugEvent.u.UnloadDll.lpBaseOfDll); break; case OUTPUT_DEBUG_STRING_EVENT: { if (debugOptions.verbose_flag) { lprintf("OUTPUT_DEBUG_STRING PID=%lu TID=%lu\n", DebugEvent.dwProcessId, DebugEvent.dwThreadId ); } pProcessInfo = &g_Processes[DebugEvent.dwProcessId]; assert(!DebugEvent.u.DebugString.fUnicode); LPSTR lpDebugStringData = readProcessString(pProcessInfo->hProcess, DebugEvent.u.DebugString.lpDebugStringData, DebugEvent.u.DebugString.nDebugStringLength); lprintf("%s", lpDebugStringData); free(lpDebugStringData); break; } case RIP_EVENT: if (debugOptions.verbose_flag) { lprintf("RIP PID=%lu TID=%lu\n", DebugEvent.dwProcessId, DebugEvent.dwThreadId ); } break; default: if (debugOptions.verbose_flag) { lprintf("EVENT%lu PID=%lu TID=%lu\n", DebugEvent.dwDebugEventCode, DebugEvent.dwProcessId, DebugEvent.dwThreadId ); } break; } // Resume executing the thread that reported the debugging event. ContinueDebugEvent( DebugEvent.dwProcessId, DebugEvent.dwThreadId, dwContinueStatus ); } return TRUE; }
/****************************************************************************** * * Name: MrvDrvCheckForHang() * * Description: * NDIS miniport check for hang routine. * * Conditions for Use: * Will be called by NDIS wrapper to determine current station operation status. * If the station is not responding, NDIS wrapper will call MrvDrvReset() to reset * the station. Driver first check and use current HW status stored in device * object to report system then update the status and send command to query HW status. * * Arguments: * IN NDIS_HANDLE MiniportAdapterContext * * Return Value: * TRUE if the NIC HW is not operating properly * FALSE if the NIC HW is OK * * Notes: According to Microsoft NDIS document, this function is normally called * by NDIS wrapper approximately every 2 seconds. * *****************************************************************************/ BOOLEAN MrvDrvCheckForHang( IN NDIS_HANDLE MiniportAdapterContext ) { PMRVDRV_ADAPTER Adapter; UCHAR ucHostIntStatus; UCHAR ucCardStatus; SD_API_STATUS status; DBGPRINT(DBG_LOAD|DBG_WARNING,(L"INIT - Enter MrvDrvCheckForHang\n")); //return FALSE; //tt ra fail Adapter = (PMRVDRV_ADAPTER)MiniportAdapterContext; if ( Adapter->SurpriseRemoved ) { DBGPRINT(DBG_WARNING, (L"[MRVL] in CheckForHang, card is removed, return FALSE directly\n") ); return FALSE; } if ( Adapter->SentPacket ) { Adapter->dwTxTimeoutCount ++; if ( Adapter->dwTxTimeoutCount > MRVDRV_TX_TIMEOUT_COUNT_THRESHOLD ) { DBGPRINT( DBG_ERROR, (L"Tx timeout!\n") ); Adapter->TxPktTimerIsSet=TRUE; NdisMSetTimer(&Adapter->MrvDrvTxPktTimer, 0); Adapter->dwTxTimeoutCount = 0; } } //012207 // We won't check in deepsleep, ps mode, HostSleep and D3 state. // In Deep Sleep Mode no packet can be sent out if( !IsThisDsState(Adapter, DS_STATE_NONE) ) return FALSE; if( (!IsThisHostPowerState(Adapter, HTWK_STATE_FULL_POWER)) || (Adapter->psState == PS_STATE_SLEEP) || (Adapter->CurPowerState != NdisDeviceStateD0) ) return FALSE; if ( Adapter->IntWARTimeoutCount ) AutoDeepSleepCounter(Adapter); else Adapter->AutoDsRec.timer = 0; //060407 flag to start auto deep sleep counter //This flag also used to interrupt missing. if(((++Adapter->IntWARTimeoutCount) & 0x1) == 0 ) return FALSE; //Adapter->IntWARTimeoutCount = 0; if( IsThisDsState(Adapter, DS_STATE_SLEEP) ) return FALSE; status = If_ReadRegister(Adapter, //SD_IO_READ , 1, // function 1 HCR_HOST_INT_STATUS_REGISTER, FALSE, &ucHostIntStatus, sizeof(ucHostIntStatus)); if (!SD_API_SUCCESS(status)) { DBGPRINT(DBG_ERROR, (L"Read error in CheckForHang()\r\n") ); return FALSE; } if( ucHostIntStatus & (UPLOAD_HOST_INT_STATUS_RDY | DOWNLOAD_HOST_INT_STATUS_RDY) ) { EnterCriticalSection(&Adapter->IntCriticalSection); Adapter->ucGHostIntStatus |= ucHostIntStatus; LeaveCriticalSection(&Adapter->IntCriticalSection); ucCardStatus = ~ucHostIntStatus; ucCardStatus &= 0x1f; status = If_WriteRegister(Adapter, //SD_IO_WRITE, 1, HCR_HOST_INT_STATUS_REGISTER, FALSE, &ucCardStatus, // reg sizeof(ucCardStatus)); if (!SD_API_SUCCESS(status)) { DBGPRINT(DBG_ISR,(L"Unable to clear Host interrupt status register\r\n")); return FALSE; } SetEvent(Adapter->hControllerInterruptEvent); } return FALSE; }
DWORD AbstractGattService::MessagePumpThreadProc( ) { DWORD hr = S_OK; DWORD dwRet; WNDCLASSEX wce; wce.cbSize = sizeof(WNDCLASSEX); wce.style = 0; wce.lpfnWndProc = (WNDPROC) s_WndProc; wce.cbClsExtra = 0; wce.cbWndExtra = 0; wce.hInstance = g_hInstance; wce.hIcon = NULL; wce.hIconSm = NULL; wce.hCursor = NULL; wce.hbrBackground = NULL; wce.lpszMenuName = NULL; wce.lpszClassName = GATT_SERVICE_CLASSNAME; if (!RegisterClassEx(&wce)) { dwRet = GetLastError(); if(ERROR_CLASS_ALREADY_EXISTS != dwRet) { m_hrMessagePumpStartStatus = HRESULT_FROM_WIN32(dwRet); hr = m_hrMessagePumpStartStatus; SetEvent(m_hMessagePumpInitialized); CHECK_HR(hr, "Failed to register the Window class"); } } if (SUCCEEDED(hr)) { m_hWnd = CreateWindow(GATT_SERVICE_CLASSNAME, NULL, WS_OVERLAPPEDWINDOW, 0, 0, 0, 0, HWND_MESSAGE, // Message only window, skips UI initialization (HMENU) NULL, g_hInstance, (LPVOID)this); if(NULL == m_hWnd) { hr = HRESULT_FROM_WIN32(GetLastError()); m_hrMessagePumpStartStatus = hr; SetEvent(m_hMessagePumpInitialized); CHECK_HR(hr, "Failed to create the window"); } } if (SUCCEEDED(hr)) { // // Now notify that we are initialized and start the message pump // m_hrMessagePumpStartStatus = S_OK; SetEvent(m_hMessagePumpInitialized); DWORD dwWaitVal = (DWORD)-1; // // Message pump // do { MSG msg; while (PeekMessage( &msg, NULL, 0, 0, PM_REMOVE )) { TranslateMessage( &msg ); DispatchMessage( &msg ); } // No timeout. We keep processing messages, until the wait handle is signaled. dwWaitVal = MsgWaitForMultipleObjects( 1, &m_hMessagePumpTerminate, FALSE, INFINITE, QS_ALLINPUT ); } while (WAIT_OBJECT_0 != dwWaitVal); } return hr; }
int ortp_server_pipe_close(ortp_pipe_t spipe){ SetEvent(event); //CancelIoEx(spipe,NULL); /*vista only*/ return CloseHandle(spipe); }
void XBPython::PulseGlobalEvent() { SetEvent(m_globalEvent); }
void setChannelError(rdpContext* context, UINT errorNum, char* description) { context->channelErrorNum = errorNum; strncpy(context->errorDescription, description, 499); SetEvent(context->channelErrorEvent); }
STDMETHODIMP CStreamSwitcherInputPin::NotifyEndOfStream(HANDLE hNotifyEvent) { if(m_hNotifyEvent) SetEvent(m_hNotifyEvent); m_hNotifyEvent = hNotifyEvent; return S_OK; }
int main(int argc, char** argv) { HANDLE lib; HANDLE event; ULONG_PTR hThread; int reloaded = 0; USE_USER32(); #ifdef USE_DYNAMO dynamorio_app_init(); dynamorio_app_start(); #endif #ifdef LINUX /* though win32/ */ intercept_signal(SIGSEGV, signal_handler); #else /* note that can't normally if we have a debugger attached this * will not get this executed */ SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER) our_top_handler); #endif event = CreateEvent(NULL, TRUE, FALSE, NULL); hThread = _beginthreadex(NULL, 0, run_func, event, 0, NULL); /* need to run as long as necessary to hit the required faults */ while (transitions < NUM_TRANSITIONS) { lib = LoadLibrary("win32.reload-race.dll.dll"); if (lib == NULL) { print("error loading library\n"); break; } else { reloaded++; #if VERBOSE print("reloaded %d times %d\n", reloaded); #endif import1 = (funptr) GetProcAddress(lib, (LPCSTR)"import_me1"); import2 = (funptr) GetProcAddress(lib, (LPCSTR)"import_me2"); /* may want to explicitly sleep here but that may be slower */ if (reloaded % 2 == 0) YIELD(); FreeLibrary(lib); if (reloaded % 3 == 0) YIELD(); } } SetEvent(event); WaitForSingleObject((HANDLE)hThread, INFINITE); print("main loop done\n"); check_mem_usage(); #if VERBOSE print("reloaded %d times %d\n", reloaded); #endif #ifdef USE_DYNAMO dynamorio_app_stop(); dynamorio_app_exit(); #endif return 0; }
bool WaitObjectContainer::Wait(unsigned long milliseconds) { if (m_noWait || (m_handles.empty() && !m_firstEventTime)) { SetLastResult(LASTRESULT_NOWAIT); return true; } bool timeoutIsScheduledEvent = false; if (m_firstEventTime) { double timeToFirstEvent = SaturatingSubtract(m_firstEventTime, m_eventTimer.ElapsedTimeAsDouble()); if (timeToFirstEvent <= milliseconds) { milliseconds = (unsigned long)timeToFirstEvent; timeoutIsScheduledEvent = true; } if (m_handles.empty() || !milliseconds) { if (milliseconds) Sleep(milliseconds); SetLastResult(timeoutIsScheduledEvent ? LASTRESULT_SCHEDULED : LASTRESULT_TIMEOUT); return timeoutIsScheduledEvent; } } if (m_handles.size() > MAXIMUM_WAIT_OBJECTS) { // too many wait objects for a single WaitForMultipleObjects call, so use multiple threads static const unsigned int WAIT_OBJECTS_PER_THREAD = MAXIMUM_WAIT_OBJECTS-1; unsigned int nThreads = (unsigned int)((m_handles.size() + WAIT_OBJECTS_PER_THREAD - 1) / WAIT_OBJECTS_PER_THREAD); if (nThreads > MAXIMUM_WAIT_OBJECTS) // still too many wait objects, maybe implement recursive threading later? throw Err("WaitObjectContainer: number of wait objects exceeds limit"); CreateThreads(nThreads); DWORD error = S_OK; for (unsigned int i=0; i<m_threads.size(); i++) { WaitingThreadData &thread = *m_threads[i]; while (!thread.waitingToWait) // spin until thread is in the initial "waiting to wait" state Sleep(0); if (i<nThreads) { thread.waitHandles = &m_handles[i*WAIT_OBJECTS_PER_THREAD]; thread.count = UnsignedMin(WAIT_OBJECTS_PER_THREAD, m_handles.size() - i*WAIT_OBJECTS_PER_THREAD); thread.error = &error; } else thread.count = 0; } ResetEvent(m_stopWaiting); PulseEvent(m_startWaiting); DWORD result = ::WaitForSingleObject(m_stopWaiting, milliseconds); if (result == WAIT_OBJECT_0) { if (error == S_OK) return true; else throw Err("WaitObjectContainer: WaitForMultipleObjects in thread failed with error " + IntToString(error)); } SetEvent(m_stopWaiting); if (result == WAIT_TIMEOUT) { SetLastResult(timeoutIsScheduledEvent ? LASTRESULT_SCHEDULED : LASTRESULT_TIMEOUT); return timeoutIsScheduledEvent; } else throw Err("WaitObjectContainer: WaitForSingleObject failed with error " + IntToString(::GetLastError())); } else { #if TRACE_WAIT static Timer t(Timer::MICROSECONDS); static unsigned long lastTime = 0; unsigned long timeBeforeWait = t.ElapsedTime(); #endif DWORD result = ::WaitForMultipleObjects((DWORD)m_handles.size(), &m_handles[0], FALSE, milliseconds); #if TRACE_WAIT if (milliseconds > 0) { unsigned long timeAfterWait = t.ElapsedTime(); OutputDebugString(("Handles " + IntToString(m_handles.size()) + ", Woke up by " + IntToString(result-WAIT_OBJECT_0) + ", Busied for " + IntToString(timeBeforeWait-lastTime) + " us, Waited for " + IntToString(timeAfterWait-timeBeforeWait) + " us, max " + IntToString(milliseconds) + "ms\n").c_str()); lastTime = timeAfterWait; } #endif if (result >= WAIT_OBJECT_0 && result < WAIT_OBJECT_0 + m_handles.size()) { if (result == m_lastResult) m_sameResultCount++; else { m_lastResult = result; m_sameResultCount = 0; } return true; } else if (result == WAIT_TIMEOUT) { SetLastResult(timeoutIsScheduledEvent ? LASTRESULT_SCHEDULED : LASTRESULT_TIMEOUT); return timeoutIsScheduledEvent; } else throw Err("WaitObjectContainer: WaitForMultipleObjects failed with error " + IntToString(::GetLastError())); } }
void CAudioCapture::Stop(void) { if (m_hEvents[CAPTURE_EVENT]) SetEvent(m_hEvents[CAPTURE_EVENT]); }
int transport_write(rdpTransport* transport, wStream* s) { int length; int status = -1; WaitForSingleObject(transport->WriteMutex, INFINITE); length = Stream_GetPosition(s); Stream_SetPosition(s, 0); #ifdef WITH_DEBUG_TRANSPORT if (length > 0) { fprintf(stderr, "Local > Remote\n"); winpr_HexDump(Stream_Buffer(s), length); } #endif if (length > 0) { WLog_Packet(transport->log, WLOG_TRACE, Stream_Buffer(s), length, WLOG_PACKET_OUTBOUND); } while (length > 0) { if (transport->layer == TRANSPORT_LAYER_TLS) status = tls_write(transport->TlsOut, Stream_Pointer(s), length); else if (transport->layer == TRANSPORT_LAYER_TCP) status = tcp_write(transport->TcpOut, Stream_Pointer(s), length); else if (transport->layer == TRANSPORT_LAYER_TSG) status = tsg_write(transport->tsg, Stream_Pointer(s), length); else if (transport->layer == TRANSPORT_LAYER_TSG_TLS) status = tls_write(transport->TsgTls, Stream_Pointer(s), length); if (status < 0) break; /* error occurred */ if (status == 0) { /* when sending is blocked in nonblocking mode, the receiving buffer should be checked */ if (!transport->blocking) { /* and in case we do have buffered some data, we set the event so next loop will get it */ if (transport_read_nonblocking(transport) > 0) SetEvent(transport->ReceiveEvent); } if (transport->layer == TRANSPORT_LAYER_TLS) tls_wait_write(transport->TlsOut); else if (transport->layer == TRANSPORT_LAYER_TCP) tcp_wait_write(transport->TcpOut); else if (transport->layer == TRANSPORT_LAYER_TSG_TLS) tls_wait_write(transport->TsgTls); else USleep(transport->SleepInterval); } length -= status; Stream_Seek(s, status); } if (status < 0) { /* A write error indicates that the peer has dropped the connection */ transport->layer = TRANSPORT_LAYER_CLOSED; } if (s->pool) Stream_Release(s); ReleaseMutex(transport->WriteMutex); return status; }
int CAudioCapture::Start() { MMRESULT res = MMSYSERR_NOERROR; if (m_hWaveIn == NULL) { ZeroMemory(&m_waveHdrA, sizeof(WAVEHDR)); ZeroMemory(&m_waveHdrB, sizeof(WAVEHDR)); m_ulCapturedBytes = 0; OutputDebugStringW(L"WAV: Starting the Wave capture..\n"); if ((m_hFile != INVALID_HANDLE_VALUE) || ((m_hFile = CreateFile(lpRawFileName, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, NULL)) == INVALID_HANDLE_VALUE)) { return MMSYSERR_NOMEM; } if ((res = waveInOpen((LPHWAVEIN )&m_hWaveIn, 0, &m_wfx, (DWORD_PTR)waveInProc, (DWORD_PTR)this, (WAVE_FORMAT_DIRECT | CALLBACK_FUNCTION))) == MMSYSERR_NOERROR) { // we want our double buffers to be multiples of 1 second, 500ms or at worst case 100ms // so that we can count up the capture time based on buffer fills. if (m_wfx.nAvgBytesPerSec > 64000) { // over 512 kbps use 100ms buffers m_waveHdrA.dwBufferLength = m_wfx.nAvgBytesPerSec / 10; m_waveHdrB.dwBufferLength = m_waveHdrA.dwBufferLength; } else if (m_wfx.nAvgBytesPerSec > 32000) { // 256-512 kbps use 500ms buffers m_waveHdrA.dwBufferLength = m_wfx.nAvgBytesPerSec / 2; m_waveHdrB.dwBufferLength = m_waveHdrA.dwBufferLength; } else { // under 254 kbps use 1s buffers m_waveHdrA.dwBufferLength = m_wfx.nAvgBytesPerSec; m_waveHdrB.dwBufferLength = m_waveHdrA.dwBufferLength; } m_waveHdrA.lpData = new char[m_waveHdrA.dwBufferLength]; m_waveHdrB.lpData = new char[m_waveHdrB.dwBufferLength]; if ((!m_waveHdrA.lpData) || (!m_waveHdrB.lpData)) { OutputDebugStringW(L"Unable to allocate memory for audio capture buffers\n"); waveInClose(m_hWaveIn); m_hWaveIn = NULL; delete [] m_waveHdrA.lpData; m_waveHdrA.lpData = NULL; delete [] m_waveHdrB.lpData; m_waveHdrB.lpData = NULL; return MMSYSERR_NOMEM; } m_bUseBufferA = TRUE; if ((res = waveInPrepareHeader(m_hWaveIn, &m_waveHdrA, sizeof(WAVEHDR))) == MMSYSERR_NOERROR) { if ((res = waveInAddBuffer(m_hWaveIn, &m_waveHdrA, sizeof(WAVEHDR))) == MMSYSERR_NOERROR) { if ((res = waveInPrepareHeader(m_hWaveIn, &m_waveHdrB, sizeof(WAVEHDR))) == MMSYSERR_NOERROR) { if ((res = waveInAddBuffer(m_hWaveIn, &m_waveHdrB, sizeof(WAVEHDR))) == MMSYSERR_NOERROR) { m_hEvents[CAPTURE_EVENT] = CreateEvent(NULL, FALSE, FALSE, NULL); m_hEvents[CANCEL_EVENT] = CreateEvent(NULL, FALSE, FALSE, NULL); if (m_hEvents[CAPTURE_EVENT] && m_hEvents[CANCEL_EVENT]) { CloseHandle(CreateThread(NULL, 0, threadProc, (LPVOID)this, 0, NULL)); if ((res = waveInStart(m_hWaveIn)) == MMSYSERR_NOERROR) { return res; } SetEvent(m_hEvents[CANCEL_EVENT]); } else { CloseHandle(m_hEvents[CAPTURE_EVENT]); m_hEvents[CAPTURE_EVENT] = NULL; CloseHandle(m_hEvents[CANCEL_EVENT]); m_hEvents[CANCEL_EVENT] = NULL; } } waveInUnprepareHeader(m_hWaveIn, &m_waveHdrB, sizeof(WAVEHDR)); } } waveInUnprepareHeader(m_hWaveIn, &m_waveHdrA, sizeof(WAVEHDR)); } waveInClose(m_hWaveIn); m_hWaveIn = NULL; delete [] m_waveHdrA.lpData; m_waveHdrA.lpData = NULL; delete [] m_waveHdrB.lpData; m_waveHdrB.lpData = NULL; } else { if(res == MMSYSERR_ALLOCATED) { OutputDebugStringW(L"WAV: Wavein: MMSYSERR_ALLOCATED..\n"); } else if(res == MMSYSERR_NODRIVER) { OutputDebugStringW(L"WAV: Wavein: MMSYSERR_NODRIVER..\n"); } else if(res == MMSYSERR_BADDEVICEID) { OutputDebugStringW(L"WAV: Wavein: MMSYSERR_BADDEVICEID..\n"); } else if(res == MMSYSERR_NOMEM) { OutputDebugStringW(L"WAV: Wavein: MMSYSERR_NOMEM..\n"); } else if(res == WAVERR_BADFORMAT) { OutputDebugStringW(L"WAV: Waven WAVERR_BADFORMAT..\n"); } OutputDebugStringW(L"WAV: Wavin failure..\n"); } } else { OutputDebugStringW(L"WAV: Restarting WaveIn capture ..\n"); m_waveHdrA.dwBytesRecorded = 0; m_waveHdrB.dwBytesRecorded = 0; m_bUseBufferA = TRUE; waveInAddBuffer(m_hWaveIn, &m_waveHdrA, sizeof(WAVEHDR)); waveInAddBuffer(m_hWaveIn, &m_waveHdrB, sizeof(WAVEHDR)); OutputDebugStringW(L"WAV: WaveIn capture restarted..\n"); } return res; }
DWORD ThreadForTx(PSPI_PUBLIC_CONTEXT pSpiPublic) { volatile S3C2450_HSSPI_REG *pSPIregs = pSpiPublic->pHSSPIregs; // for HS-SPI volatile S3C2450_INTR_REG *pINTRregs = pSpiPublic->pINTRregs; volatile S3C2450_DMA_REG *pDMAregs = pSpiPublic->pDMAregs; PSPI_PRIVATE_CONTEXT pSpiPrivate; DWORD dwTxCount; PBYTE pTxBuffer; DWORD dwOldPerm; PBYTE pTestBuffer; DWORD dwTestCount; do { WaitForSingleObject(pSpiPublic->hTxEvent, INFINITE); pSpiPrivate = (PSPI_PRIVATE_CONTEXT) pSpiPublic->pSpiPrivate; dwTestCount = dwTxCount = pSpiPrivate->dwTxCount; dwOldPerm = SetProcPermissions((DWORD)-1); pTestBuffer = pTxBuffer = (PBYTE) MapPtrToProcess(pSpiPrivate->pTxBuffer, (HANDLE) GetCurrentProcessId()); RETAILMSG(1,(TEXT("pTxBuffer : 0x%X, dwTxCount : %d \r\n"), pTxBuffer, dwTxCount)); //Reset pSPIregs->CH_CFG |= SW_RST; RETAILMSG(1,(TEXT("\n HS SPI reset\n"))); pSPIregs->CH_CFG &= ~SW_RST; if(pSpiPrivate->bUseTxIntr) // INT + TX { RETAILMSG(1,(TEXT("[HSPI DD] Thread for TX : USE INT \r\n"))); pSpiPrivate->State = STATE_TXINTR; /* if(pSpiPrivate->dwMode == SPI_MASTER_MODE) { pSPIregs->CH_CFG = 0x0; pSPIregs->CLK_CFG = pSpiPrivate->TxSPIregs.CLK_CFG; pSPIregs->MODE_CFG = (TX_TRIG_LEVEL<<5); } else { pSPIregs->CH_CFG = (0x1<<4); pSPIregs->CLK_CFG = pSpiPrivate->TxSPIregs.CLK_CFG; pSPIregs->MODE_CFG = (TX_TRIG_LEVEL<<5); } pSPIregs->SP_INT_EN = (1<<0); pSPIregs->PENDING_CLR_REG = (0x1f); pSPIregs->CH_CFG = (1<<0); if(pSpiPrivate->dwMode == SPI_MASTER_MODE) { RETAILMSG(1,(TEXT("[HSPI DD] Thread for TX : MASTER MODE \r\n"))); pSPIregs->SLAVE_SELECTION_REG = 0; } else{ RETAILMSG(1,(TEXT("[HSPI DD] Thread for TX : SLAVE MODE \r\n"))); } WaitForSingleObject(pSpiPublic->hTxIntrDoneEvent, INFINITE); while(((pSPIregs ->SPI_STATUS>>6) & 0x7f)); while(!((pSPIregs ->SPI_STATUS>>21) & 0x1)); */ } else if(pSpiPrivate->bUseTxDMA) // DMA + TX { DWORD dwDmaLen = dwTxCount & 0xFFFFF ; RETAILMSG(1,(TEXT("[HSPI DD] Thread for TX : USE DMA (TxCount : %d) \r\n"),dwDmaLen)); pSpiPrivate->State = STATE_TXDMA; VirtualCopy((PVOID)pSpiPrivate->pTxBuffer, (PVOID)((ULONG) pSpiPrivate->pTxDMABuffer>>8), sizeof(dwTxCount), PAGE_READWRITE | PAGE_NOCACHE | PAGE_PHYSICAL); if(pSpiPrivate->dwMode == SPI_MASTER_MODE) { pSPIregs->CH_CFG = pSpiPrivate->TxSPIregs.CH_CFG; pSPIregs->CLK_CFG = pSpiPrivate->TxSPIregs.CLK_CFG; pSPIregs->MODE_CFG = pSpiPrivate->TxSPIregs.MODE_CFG; }else { pSPIregs->CH_CFG = pSpiPrivate->TxSPIregs.CH_CFG; pSPIregs->CLK_CFG = pSpiPrivate->TxSPIregs.CLK_CFG; pSPIregs->MODE_CFG = pSpiPrivate->TxSPIregs.MODE_CFG; } if(dwDmaLen > 0) { pSPIregs->MODE_CFG |= TX_DMA_ON|DMA_SINGLE; pSPIregs->CH_CFG |= TX_CH_ON; pDMAregs->DISRC4 = (UINT)pSpiPrivate->pTxDMABuffer; pDMAregs->DISRCC4 = ~(DESTINATION_PERIPHERAL_BUS | FIXED_DESTINATION_ADDRESS); pDMAregs->DIDST4 = (UINT)SPI_TX_DATA_PHY_ADDR; pDMAregs->DIDSTC4 = (SOURCE_PERIPHERAL_BUS | FIXED_SOURCE_ADDRESS); // pDMAregs->DCON4 = HANDSHAKE_MODE |GENERATE_INTERRUPT |PADDRFIX |NO_DMA_AUTO_RELOAD | dwDmaLen; pDMAregs->DCON4 = HANDSHAKE_MODE |GENERATE_INTERRUPT |NO_DMA_AUTO_RELOAD | dwDmaLen; pDMAregs->DMAREQSEL4 = ( DMAREQSEL_SPI_0TX | DMA_TRIGGERED_BY_HARDWARE ); if(pSpiPrivate->dwMode == SPI_MASTER_MODE) { RETAILMSG(1,(TEXT("[HSPI DD] Thread for TX : MASTER MODE \r\n"))); MASTER_CS_ENABLE; } else { RETAILMSG(1,(TEXT("[HSPI DD] Thread for TX : SLAVE MODE \r\n"))); } pDMAregs->DMASKTRIG4 = ENABLE_DMA_CHANNEL; WaitForSingleObject(pSpiPublic->hTxDmaDoneDoneEvent, INFINITE); pSpiPrivate->dwTxCount -= dwDmaLen; pSpiPrivate->pTxBuffer = (((PUINT) pSpiPrivate->pTxBuffer) + dwDmaLen); } VirtualFree((PVOID)pTxBuffer, 0, MEM_RELEASE); while(((pSPIregs ->SPI_STATUS>>6) & 0x7f)); while(!(pSPIregs ->SPI_STATUS & TX_DONE)); } else // POLLING + TX { RETAILMSG(1,(TEXT("[HSPI DD] Thread for TX : USE Polling (TxCount : %d) \r\n"), dwTxCount)); if(pSpiPrivate->dwMode == SPI_MASTER_MODE) { pSPIregs->CH_CFG = pSpiPrivate->TxSPIregs.CH_CFG; pSPIregs->CLK_CFG = pSpiPrivate->TxSPIregs.CLK_CFG; pSPIregs->MODE_CFG = pSpiPrivate->TxSPIregs.MODE_CFG; } else{ pSPIregs->CH_CFG = pSpiPrivate->TxSPIregs.CH_CFG; pSPIregs->CLK_CFG = pSpiPrivate->TxSPIregs.CLK_CFG; pSPIregs->MODE_CFG = pSpiPrivate->TxSPIregs.MODE_CFG; } pSPIregs->CH_CFG |= TX_CH_ON; if(pSpiPrivate->dwMode == SPI_MASTER_MODE) { RETAILMSG(1,(TEXT("[HSPI DD] Thread for TX : MASTER MODE \r\n"))); MASTER_CS_ENABLE; } else { RETAILMSG(1,(TEXT("[HSPI DD] Thread for TX : SLAVE MODE \r\n"))); } do { while(((pSPIregs ->SPI_STATUS>>6) & 0x7f)==FIFO_FULL); pSPIregs->SPI_TX_DATA = *(PBYTE)pSpiPrivate->pTxBuffer; } while(--pSpiPrivate->dwTxCount > 0 && ++(PBYTE)pSpiPrivate->pTxBuffer); while(((pSPIregs ->SPI_STATUS>>6) & 0x7f)); while(!(pSPIregs ->SPI_STATUS & TX_DONE)); } pSpiPrivate->dwTxCount = dwTestCount - pSpiPrivate->dwTxCount; #ifdef TEST_MODE do { RETAILMSG(1,(TEXT("WRITE BYTE : %02X(dwTxCount : %d)\n"), *pTestBuffer, dwTestCount)); } while( (--dwTestCount > 0) && ++pTestBuffer); #endif RETAILMSG(FALSE,(TEXT("[HSPI DD] TX_CH_OFF \n"))); pSPIregs->CH_CFG &= ~TX_CH_ON; if(pSpiPrivate->dwMode == SPI_MASTER_MODE) MASTER_CS_DISABLE; UnMapPtr(pTxBuffer); SetProcPermissions(dwOldPerm); SetEvent(pSpiPublic->hTxDoneEvent); } while(TRUE);
int zmq::make_fdpair (fd_t *r_, fd_t *w_) { #if defined ZMQ_HAVE_EVENTFD int flags = 0; #if defined ZMQ_HAVE_EVENTFD_CLOEXEC // Setting this option result in sane behaviour when exec() functions // are used. Old sockets are closed and don't block TCP ports, avoid // leaks, etc. flags |= EFD_CLOEXEC; #endif fd_t fd = eventfd (0, flags); if (fd == -1) { errno_assert (errno == ENFILE || errno == EMFILE); *w_ = *r_ = -1; return -1; } else { *w_ = *r_ = fd; return 0; } #elif defined ZMQ_HAVE_WINDOWS #if !defined _WIN32_WCE && !defined ZMQ_HAVE_WINDOWS_UWP // Windows CE does not manage security attributes SECURITY_DESCRIPTOR sd; SECURITY_ATTRIBUTES sa; memset (&sd, 0, sizeof sd); memset (&sa, 0, sizeof sa); InitializeSecurityDescriptor (&sd, SECURITY_DESCRIPTOR_REVISION); SetSecurityDescriptorDacl (&sd, TRUE, 0, FALSE); sa.nLength = sizeof (SECURITY_ATTRIBUTES); sa.lpSecurityDescriptor = &sd; #endif // This function has to be in a system-wide critical section so that // two instances of the library don't accidentally create signaler // crossing the process boundary. // We'll use named event object to implement the critical section. // Note that if the event object already exists, the CreateEvent requests // EVENT_ALL_ACCESS access right. If this fails, we try to open // the event object asking for SYNCHRONIZE access only. HANDLE sync = NULL; // Create critical section only if using fixed signaler port // Use problematic Event implementation for compatibility if using old port 5905. // Otherwise use Mutex implementation. int event_signaler_port = 5905; if (signaler_port == event_signaler_port) { #if !defined _WIN32_WCE && !defined ZMQ_HAVE_WINDOWS_UWP sync = CreateEventW (&sa, FALSE, TRUE, L"Global\\zmq-signaler-port-sync"); #else sync = CreateEventW (NULL, FALSE, TRUE, L"Global\\zmq-signaler-port-sync"); #endif if (sync == NULL && GetLastError () == ERROR_ACCESS_DENIED) sync = OpenEventW (SYNCHRONIZE | EVENT_MODIFY_STATE, FALSE, L"Global\\zmq-signaler-port-sync"); win_assert (sync != NULL); } else if (signaler_port != 0) { wchar_t mutex_name[MAX_PATH]; #ifdef __MINGW32__ _snwprintf (mutex_name, MAX_PATH, L"Global\\zmq-signaler-port-%d", signaler_port); #else swprintf (mutex_name, MAX_PATH, L"Global\\zmq-signaler-port-%d", signaler_port); #endif #if !defined _WIN32_WCE && !defined ZMQ_HAVE_WINDOWS_UWP sync = CreateMutexW (&sa, FALSE, mutex_name); #else sync = CreateMutexW (NULL, FALSE, mutex_name); #endif if (sync == NULL && GetLastError () == ERROR_ACCESS_DENIED) sync = OpenMutexW (SYNCHRONIZE, FALSE, mutex_name); win_assert (sync != NULL); } // Windows has no 'socketpair' function. CreatePipe is no good as pipe // handles cannot be polled on. Here we create the socketpair by hand. *w_ = INVALID_SOCKET; *r_ = INVALID_SOCKET; // Create listening socket. SOCKET listener; listener = open_socket (AF_INET, SOCK_STREAM, 0); wsa_assert (listener != INVALID_SOCKET); // Set SO_REUSEADDR and TCP_NODELAY on listening socket. BOOL so_reuseaddr = 1; int rc = setsockopt (listener, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast<char *> (&so_reuseaddr), sizeof so_reuseaddr); wsa_assert (rc != SOCKET_ERROR); tune_socket (listener); // Init sockaddr to signaler port. struct sockaddr_in addr; memset (&addr, 0, sizeof addr); addr.sin_family = AF_INET; addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK); addr.sin_port = htons (signaler_port); // Create the writer socket. *w_ = open_socket (AF_INET, SOCK_STREAM, 0); wsa_assert (*w_ != INVALID_SOCKET); // Set TCP_NODELAY on writer socket. tune_socket (*w_); if (sync != NULL) { // Enter the critical section. DWORD dwrc = WaitForSingleObject (sync, INFINITE); zmq_assert (dwrc == WAIT_OBJECT_0 || dwrc == WAIT_ABANDONED); } // Bind listening socket to signaler port. rc = bind (listener, reinterpret_cast<const struct sockaddr *> (&addr), sizeof addr); if (rc != SOCKET_ERROR && signaler_port == 0) { // Retrieve ephemeral port number int addrlen = sizeof addr; rc = getsockname (listener, reinterpret_cast<struct sockaddr *> (&addr), &addrlen); } // Listen for incoming connections. if (rc != SOCKET_ERROR) rc = listen (listener, 1); // Connect writer to the listener. if (rc != SOCKET_ERROR) rc = connect (*w_, reinterpret_cast<struct sockaddr *> (&addr), sizeof addr); // Accept connection from writer. if (rc != SOCKET_ERROR) *r_ = accept (listener, NULL, NULL); // Send/receive large chunk to work around TCP slow start // This code is a workaround for #1608 if (*r_ != INVALID_SOCKET) { size_t dummy_size = 1024 * 1024; // 1M to overload default receive buffer unsigned char *dummy = static_cast<unsigned char *> (malloc (dummy_size)); wsa_assert (dummy); int still_to_send = static_cast<int> (dummy_size); int still_to_recv = static_cast<int> (dummy_size); while (still_to_send || still_to_recv) { int nbytes; if (still_to_send > 0) { nbytes = ::send ( *w_, reinterpret_cast<char *> (dummy + dummy_size - still_to_send), still_to_send, 0); wsa_assert (nbytes != SOCKET_ERROR); still_to_send -= nbytes; } nbytes = ::recv ( *r_, reinterpret_cast<char *> (dummy + dummy_size - still_to_recv), still_to_recv, 0); wsa_assert (nbytes != SOCKET_ERROR); still_to_recv -= nbytes; } free (dummy); } // Save errno if error occurred in bind/listen/connect/accept. int saved_errno = 0; if (*r_ == INVALID_SOCKET) saved_errno = WSAGetLastError (); // We don't need the listening socket anymore. Close it. rc = closesocket (listener); wsa_assert (rc != SOCKET_ERROR); if (sync != NULL) { // Exit the critical section. BOOL brc; if (signaler_port == event_signaler_port) brc = SetEvent (sync); else brc = ReleaseMutex (sync); win_assert (brc != 0); // Release the kernel object brc = CloseHandle (sync); win_assert (brc != 0); } if (*r_ != INVALID_SOCKET) { make_socket_noninheritable (*r_); return 0; } // Cleanup writer if connection failed if (*w_ != INVALID_SOCKET) { rc = closesocket (*w_); wsa_assert (rc != SOCKET_ERROR); *w_ = INVALID_SOCKET; } // Set errno from saved value errno = wsa_error_to_errno (saved_errno); return -1; #elif defined ZMQ_HAVE_OPENVMS // Whilst OpenVMS supports socketpair - it maps to AF_INET only. Further, // it does not set the socket options TCP_NODELAY and TCP_NODELACK which // can lead to performance problems. // // The bug will be fixed in V5.6 ECO4 and beyond. In the meantime, we'll // create the socket pair manually. struct sockaddr_in lcladdr; memset (&lcladdr, 0, sizeof lcladdr); lcladdr.sin_family = AF_INET; lcladdr.sin_addr.s_addr = htonl (INADDR_LOOPBACK); lcladdr.sin_port = 0; int listener = open_socket (AF_INET, SOCK_STREAM, 0); errno_assert (listener != -1); int on = 1; int rc = setsockopt (listener, IPPROTO_TCP, TCP_NODELAY, &on, sizeof on); errno_assert (rc != -1); rc = setsockopt (listener, IPPROTO_TCP, TCP_NODELACK, &on, sizeof on); errno_assert (rc != -1); rc = bind (listener, (struct sockaddr *) &lcladdr, sizeof lcladdr); errno_assert (rc != -1); socklen_t lcladdr_len = sizeof lcladdr; rc = getsockname (listener, (struct sockaddr *) &lcladdr, &lcladdr_len); errno_assert (rc != -1); rc = listen (listener, 1); errno_assert (rc != -1); *w_ = open_socket (AF_INET, SOCK_STREAM, 0); errno_assert (*w_ != -1); rc = setsockopt (*w_, IPPROTO_TCP, TCP_NODELAY, &on, sizeof on); errno_assert (rc != -1); rc = setsockopt (*w_, IPPROTO_TCP, TCP_NODELACK, &on, sizeof on); errno_assert (rc != -1); rc = connect (*w_, (struct sockaddr *) &lcladdr, sizeof lcladdr); errno_assert (rc != -1); *r_ = accept (listener, NULL, NULL); errno_assert (*r_ != -1); close (listener); return 0; #elif defined ZMQ_HAVE_VXWORKS struct sockaddr_in lcladdr; memset (&lcladdr, 0, sizeof lcladdr); lcladdr.sin_family = AF_INET; lcladdr.sin_addr.s_addr = htonl (INADDR_LOOPBACK); lcladdr.sin_port = 0; int listener = open_socket (AF_INET, SOCK_STREAM, 0); errno_assert (listener != -1); int on = 1; int rc = setsockopt (listener, IPPROTO_TCP, TCP_NODELAY, (char *) &on, sizeof on); errno_assert (rc != -1); rc = bind (listener, (struct sockaddr *) &lcladdr, sizeof lcladdr); errno_assert (rc != -1); socklen_t lcladdr_len = sizeof lcladdr; rc = getsockname (listener, (struct sockaddr *) &lcladdr, (int *) &lcladdr_len); errno_assert (rc != -1); rc = listen (listener, 1); errno_assert (rc != -1); *w_ = open_socket (AF_INET, SOCK_STREAM, 0); errno_assert (*w_ != -1); rc = setsockopt (*w_, IPPROTO_TCP, TCP_NODELAY, (char *) &on, sizeof on); errno_assert (rc != -1); rc = connect (*w_, (struct sockaddr *) &lcladdr, sizeof lcladdr); errno_assert (rc != -1); *r_ = accept (listener, NULL, NULL); errno_assert (*r_ != -1); close (listener); return 0; #else // All other implementations support socketpair() int sv[2]; int type = SOCK_STREAM; // Setting this option result in sane behaviour when exec() functions // are used. Old sockets are closed and don't block TCP ports, avoid // leaks, etc. #if defined ZMQ_HAVE_SOCK_CLOEXEC type |= SOCK_CLOEXEC; #endif int rc = socketpair (AF_UNIX, type, 0, sv); if (rc == -1) { errno_assert (errno == ENFILE || errno == EMFILE); *w_ = *r_ = -1; return -1; } else { make_socket_noninheritable (sv[0]); make_socket_noninheritable (sv[1]); *w_ = sv[0]; *r_ = sv[1]; return 0; } #endif }
DWORD WINAPI StatusWindow::ThreadProc(LPVOID lpParameter) { HANDLE eventList[1]; StatusWindow *me = (StatusWindow *)lpParameter; bool waitingForClose = false; eventList[0] = me->eventCommandSent; me->dialog = CreateDialogParam(hInstance, MAKEINTRESOURCE(IDD_STATUSWINDOW), NULL, StatusWindow::MainDialogProc, (LPARAM)me); MSG msg; while(1) { DWORD rv; rv = MsgWaitForMultipleObjects(1, eventList, FALSE, INFINITE, QS_ALLEVENTS); if((rv >= WAIT_OBJECT_0) && (rv < WAIT_OBJECT_0 + 1)) { if(rv == WAIT_OBJECT_0) { switch(me->command->type) { case StatusCommand::COMMAND_CLOSE: // csThreadAlive is going to be entered already by the other thread DestroyWindow(me->dialog); // Pump the remaining messages while(GetMessage(&msg, NULL, 0, 0) > 0); SetEvent(me->eventCommandAcknowledged); return(TRUE); case StatusCommand::COMMAND_LOGMESSAGE: int length; length = GetWindowTextLength(GetDlgItem(me->dialog, IDC_LOG)); SendDlgItemMessage(me->dialog, IDC_LOG, EM_SETSEL, length, length); SendDlgItemMessage(me->dialog, IDC_LOG, EM_REPLACESEL, 0, (LPARAM)(TCHAR *)(static_cast<CommandLogMessage *>(me->command))->message); SendDlgItemMessage(me->dialog, IDC_LOG, WM_VSCROLL, SB_BOTTOM, (LPARAM)NULL); SetEvent(me->eventCommandAcknowledged); break; case StatusCommand::COMMAND_WAITFORCLOSE: waitingForClose = true; break; default: SetEvent(me->eventCommandAcknowledged); break; } } } else if(rv == WAIT_OBJECT_0 + 1) { while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) != 0) { if(msg.message == WM_QUIT) { if(waitingForClose) { me->threadAlive = false; SetEvent(me->eventCommandAcknowledged); } else { // Flushes the messages and sets threadAlive to false me->CleanupThread(); } return(TRUE); } if(!IsDialogMessage(me->dialog, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } } } } }