UINT WINAPI CBonCtrl::EpgCapBackThread(LPVOID param) { wstring folderPath; GetModuleFolderPath( folderPath ); wstring iniPath = folderPath; iniPath += L"\\BonCtrl.ini"; DWORD timeOut = GetPrivateProfileInt(L"EPGCAP", L"EpgCapTimeOut", 15, iniPath.c_str()); BOOL saveTimeOut = GetPrivateProfileInt(L"EPGCAP", L"EpgCapSaveTimeOut", 0, iniPath.c_str()); CBonCtrl* sys = (CBonCtrl*)param; if( ::WaitForSingleObject(sys->epgCapBackStopEvent, sys->epgCapBackStartWaitSec*1000) != WAIT_TIMEOUT ){ //キャンセルされた return 0; } if( sys->tsOut.IsRec() == TRUE ){ if( sys->enableRecEpgCap == FALSE ){ return 0; } }else{ if( sys->enableLiveEpgCap == FALSE ){ return 0; } } LONGLONG startTime = GetTimeCount(); wstring epgDataPath = L""; WORD ONID; WORD TSID; sys->tsOut.GetStreamID(&ONID, &TSID); if( sys->chUtil.IsEpgCapService(ONID, TSID) == FALSE ){ return 0; } sys->GetEpgDataFilePath(ONID, TSID, epgDataPath); sys->tsOut.StartSaveEPG(epgDataPath); sys->tsOut.ClearSectionStatus(); if( ::WaitForSingleObject(sys->epgCapBackStopEvent, 60*1000) != WAIT_TIMEOUT ){ //キャンセルされた sys->tsOut.StopSaveEPG(FALSE); return 0; } while(1){ //蓄積状態チェック BOOL chkNext = FALSE; BOOL leitFlag = sys->chUtil.IsPartial(ONID, TSID, sys->lastSID); EPG_SECTION_STATUS status = sys->tsOut.GetSectionStatus(leitFlag); if( ONID == 4 && sys->BSBasic == TRUE ){ if( status == EpgBasicAll || status == EpgHEITAll ){ chkNext = TRUE; } }else if( ONID == 6 && sys->CS1Basic == TRUE ){ if( status == EpgBasicAll || status == EpgHEITAll ){ chkNext = TRUE; } }else if( ONID == 7 && sys->CS2Basic == TRUE ){ if( status == EpgBasicAll || status == EpgHEITAll ){ chkNext = TRUE; } }else{ if( leitFlag == FALSE && status == EpgHEITAll ){ chkNext = TRUE; }else if( leitFlag == TRUE && status == EpgLEITAll ){ chkNext = TRUE; } } if( chkNext == TRUE ){ sys->tsOut.StopSaveEPG(TRUE); CSendCtrlCmd cmd; cmd.SetConnectTimeOut(1000); cmd.SendReloadEpg(); break; }else{ if( (startTime + timeOut*60 < GetTimeCount()) ){ //15分以上かかっているなら停止 sys->tsOut.StopSaveEPG(saveTimeOut); CSendCtrlCmd cmd; cmd.SetConnectTimeOut(1000); cmd.SendReloadEpg(); _OutputDebugString(L"++%d分でEPG取得完了せず or Ch変更でエラー", timeOut); break; } } if( ::WaitForSingleObject(sys->epgCapBackStopEvent, 10*1000) != WAIT_TIMEOUT ){ //キャンセルされた sys->tsOut.StopSaveEPG(FALSE); break; } } return 0; }
UINT WINAPI CNotifyManager::SendNotifyThread(LPVOID param) { CNotifyManager* sys = (CNotifyManager*)param; CSendCtrlCmd sendCtrl; map<DWORD,DWORD>::iterator itr; BOOL wait1Sec = FALSE; BOOL waitNotify = FALSE; DWORD waitNotifyTick; while(1){ map<DWORD, DWORD> registGUI; map<wstring, REGIST_TCP_INFO> registTCP; NOTIFY_SRV_INFO notifyInfo; if( wait1Sec != FALSE ){ wait1Sec = FALSE; Sleep(1000); } if( ::WaitForSingleObject(sys->notifyEvent, INFINITE) != WAIT_OBJECT_0 || sys->notifyStopFlag != FALSE ){ //キャンセルされた break; } //現在の情報取得 { CBlockLock lock(&sys->managerLock); if( sys->notifyList.empty() ){ continue; } registGUI = sys->registGUIMap; registTCP = sys->registTCPMap; if( waitNotify != FALSE && GetTickCount() - waitNotifyTick < 5000 ){ vector<NOTIFY_SRV_INFO>::const_iterator itrNotify; for( itrNotify = sys->notifyList.begin(); itrNotify != sys->notifyList.end(); itrNotify++ ){ if( itrNotify->notifyID <= 100 ){ break; } } if( itrNotify == sys->notifyList.end() ){ SetEvent(sys->notifyEvent); wait1Sec = TRUE; continue; } //NotifyID<=100の通知は遅延させず先に送る notifyInfo = *itrNotify; sys->notifyList.erase(itrNotify); }else{ waitNotify = FALSE; notifyInfo = sys->notifyList[0]; sys->notifyList.erase(sys->notifyList.begin()); //NotifyID>100の通知は遅延させる if( notifyInfo.notifyID > 100 ){ waitNotify = TRUE; waitNotifyTick = GetTickCount(); } } if( sys->notifyList.empty() == false ){ //次の通知がある SetEvent(sys->notifyEvent); } //送信済みリストに追加してウィンドウメッセージで知らせる sys->notifySentList.push_back(notifyInfo); if( sys->notifySentList.size() > 100 ){ sys->notifySentList.erase(sys->notifySentList.begin()); } if( sys->hwndNotify != NULL ){ PostMessage(sys->hwndNotify, sys->msgIDNotify, 0, 0); } } vector<DWORD> errID; for( itr = registGUI.begin(); itr != registGUI.end(); itr++){ if( sys->notifyStopFlag != FALSE ){ //キャンセルされた break; } { sendCtrl.SetSendMode(FALSE); sendCtrl.SetPipeSetting(CMD2_GUI_CTRL_WAIT_CONNECT, CMD2_GUI_CTRL_PIPE, itr->first); sendCtrl.SetConnectTimeOut(10*1000); DWORD err = sendCtrl.SendGUINotifyInfo2(¬ifyInfo); if( err == CMD_NON_SUPPORT ){ switch(notifyInfo.notifyID){ case NOTIFY_UPDATE_EPGDATA: err = sendCtrl.SendGUIUpdateEpgData(); break; case NOTIFY_UPDATE_RESERVE_INFO: case NOTIFY_UPDATE_REC_INFO: case NOTIFY_UPDATE_AUTOADD_EPG: case NOTIFY_UPDATE_AUTOADD_MANUAL: err = sendCtrl.SendGUIUpdateReserve(); break; case NOTIFY_UPDATE_SRV_STATUS: err = sendCtrl.SendGUIStatusChg((WORD)notifyInfo.param1); break; default: break; } } if( err != CMD_SUCCESS && err != CMD_NON_SUPPORT){ errID.push_back(itr->first); } } } map<wstring, REGIST_TCP_INFO>::iterator itrTCP; vector<wstring> errIP; for( itrTCP = registTCP.begin(); itrTCP != registTCP.end(); itrTCP++){ if( sys->notifyStopFlag != FALSE ){ //キャンセルされた break; } sendCtrl.SetSendMode(TRUE); sendCtrl.SetNWSetting(itrTCP->second.ip, itrTCP->second.port); sendCtrl.SetConnectTimeOut(10*1000); DWORD err = sendCtrl.SendGUINotifyInfo2(¬ifyInfo); if( err == CMD_NON_SUPPORT ){ switch(notifyInfo.notifyID){ case NOTIFY_UPDATE_EPGDATA: err = sendCtrl.SendGUIUpdateEpgData(); break; case NOTIFY_UPDATE_RESERVE_INFO: case NOTIFY_UPDATE_REC_INFO: case NOTIFY_UPDATE_AUTOADD_EPG: case NOTIFY_UPDATE_AUTOADD_MANUAL: err = sendCtrl.SendGUIUpdateReserve(); break; case NOTIFY_UPDATE_SRV_STATUS: err = sendCtrl.SendGUIStatusChg((WORD)notifyInfo.param1); break; default: break; } } if( err != CMD_SUCCESS && err != CMD_NON_SUPPORT){ errIP.push_back(itrTCP->first); } } //送信できなかったもの削除 CBlockLock lock(&sys->managerLock); for( size_t i=0; i<errID.size(); i++ ){ itr = sys->registGUIMap.find(errID[i]); if( itr != sys->registGUIMap.end() ){ sys->registGUIMap.erase(itr); } } for( size_t i=0; i<errIP.size(); i++ ){ itrTCP = sys->registTCPMap.find(errIP[i]); if( itrTCP != sys->registTCPMap.end() ){ _OutputDebugString(L"notifyErr %s:%d", itrTCP->second.ip.c_str(), itrTCP->second.port); sys->registTCPMap.erase(itrTCP); } } } return 0; }
UINT CNotifyManager::SendNotifyThread() { CSendCtrlCmd sendCtrl; BOOL wait1Sec = FALSE; BOOL waitNotify = FALSE; DWORD waitNotifyTick = 0; for(;;){ vector<DWORD> registGUI; vector<REGIST_TCP_INFO> registTCP; NOTIFY_SRV_INFO notifyInfo; if( wait1Sec != FALSE ){ wait1Sec = FALSE; Sleep(1000); } if( ::WaitForSingleObject(this->notifyEvent, INFINITE) != WAIT_OBJECT_0 || this->notifyStopFlag != FALSE ){ //キャンセルされた break; } //現在の情報取得 { CBlockLock lock(&this->managerLock); if( this->notifyList.empty() ){ continue; } registGUI = this->GetRegistGUI(); for( size_t i = 0; i < this->registGUIList.size(); ){ if( std::find(registGUI.begin(), registGUI.end(), this->registGUIList[i].first) == registGUI.end() ){ //終了したGUIを削除 this->UnRegistGUI(this->registGUIList[i].first); }else{ i++; } } registTCP = this->GetRegistTCP(); if( waitNotify != FALSE && GetTickCount() - waitNotifyTick < 5000 ){ vector<NOTIFY_SRV_INFO>::const_iterator itrNotify; for( itrNotify = this->notifyList.begin(); itrNotify != this->notifyList.end(); itrNotify++ ){ if( itrNotify->notifyID <= 100 ){ break; } } if( itrNotify == this->notifyList.end() ){ SetEvent(this->notifyEvent); wait1Sec = TRUE; continue; } //NotifyID<=100の通知は遅延させず先に送る notifyInfo = *itrNotify; this->notifyList.erase(itrNotify); }else{ waitNotify = FALSE; notifyInfo = this->notifyList[0]; this->notifyList.erase(this->notifyList.begin()); //NotifyID>100の通知は遅延させる if( notifyInfo.notifyID > 100 ){ waitNotify = TRUE; waitNotifyTick = GetTickCount(); } } if( this->notifyList.empty() == false ){ //次の通知がある SetEvent(this->notifyEvent); } //巡回カウンタをつける(0を避けるため奇数) this->notifyCount += 2; notifyInfo.param3 = this->notifyCount; //送信済みリストに追加してウィンドウメッセージで知らせる this->notifySentList.push_back(notifyInfo); if( this->notifySentList.size() > 100 ){ this->notifySentList.erase(this->notifySentList.begin()); if( this->notifyRemovePos != 0 ){ this->notifyRemovePos--; } } if( this->hwndNotify != NULL ){ PostMessage(this->hwndNotify, this->msgIDNotify, 0, 0); } } for( size_t i = 0; i < registGUI.size(); i++ ){ if( this->notifyStopFlag != FALSE ){ //キャンセルされた break; } { sendCtrl.SetSendMode(FALSE); sendCtrl.SetPipeSetting(CMD2_GUI_CTRL_WAIT_CONNECT, CMD2_GUI_CTRL_PIPE, registGUI[i]); sendCtrl.SetConnectTimeOut(10*1000); DWORD err = sendCtrl.SendGUINotifyInfo2(notifyInfo); if( err == CMD_NON_SUPPORT ){ switch(notifyInfo.notifyID){ case NOTIFY_UPDATE_EPGDATA: err = sendCtrl.SendGUIUpdateEpgData(); break; case NOTIFY_UPDATE_RESERVE_INFO: case NOTIFY_UPDATE_REC_INFO: case NOTIFY_UPDATE_AUTOADD_EPG: case NOTIFY_UPDATE_AUTOADD_MANUAL: err = sendCtrl.SendGUIUpdateReserve(); break; case NOTIFY_UPDATE_SRV_STATUS: err = sendCtrl.SendGUIStatusChg((WORD)notifyInfo.param1); break; default: break; } } } } for( size_t i = 0; i < registTCP.size(); i++ ){ if( this->notifyStopFlag != FALSE ){ //キャンセルされた break; } sendCtrl.SetSendMode(TRUE); sendCtrl.SetNWSetting(registTCP[i].ip, registTCP[i].port, L""); sendCtrl.SetConnectTimeOut(10*1000); DWORD err = sendCtrl.SendGUINotifyInfo2(notifyInfo); if( err == CMD_NON_SUPPORT ){ switch(notifyInfo.notifyID){ case NOTIFY_UPDATE_EPGDATA: err = sendCtrl.SendGUIUpdateEpgData(); break; case NOTIFY_UPDATE_RESERVE_INFO: case NOTIFY_UPDATE_REC_INFO: case NOTIFY_UPDATE_AUTOADD_EPG: case NOTIFY_UPDATE_AUTOADD_MANUAL: err = sendCtrl.SendGUIUpdateReserve(); break; case NOTIFY_UPDATE_SRV_STATUS: err = sendCtrl.SendGUIStatusChg((WORD)notifyInfo.param1); break; default: break; } } if( err != CMD_SUCCESS && err != CMD_NON_SUPPORT){ //送信できなかったもの削除 _OutputDebugString(L"notifyErr %s:%d\r\n", registTCP[i].ip.c_str(), registTCP[i].port); this->UnRegistTCP(registTCP[i]); } } } return 0; }
UINT WINAPI CNotifyManager::SendNotifyThread(LPVOID param) { CNotifyManager* sys = (CNotifyManager*)param; CSendCtrlCmd sendCtrl; map<DWORD,DWORD>::iterator itr; DWORD wait = 0; while(1){ map<DWORD, DWORD> registGUI; map<wstring, REGIST_TCP_INFO> registTCP; NOTIFY_SRV_INFO notifyInfo; if( ::WaitForSingleObject(sys->notifyStopEvent, wait) != WAIT_TIMEOUT ){ //キャンセルされた break; } //現在の情報取得 if( sys->NotifyLock() == FALSE ) return 0; registGUI = sys->registGUIMap; registTCP = sys->registTCPMap; if( sys->notifyList.size() > 0 ){ notifyInfo = sys->notifyList[0]; sys->notifyList.erase(sys->notifyList.begin()); }else{ //リストないので終了 sys->NotifyUnLock(); return 0; } sys->NotifyUnLock(); vector<DWORD> errID; for( itr = registGUI.begin(); itr != registGUI.end(); itr++){ if( ::WaitForSingleObject(sys->notifyStopEvent, 0) != WAIT_TIMEOUT ){ //キャンセルされた break; } if( _FindOpenExeProcess(itr->first) == TRUE ){ wstring pipe; wstring waitEvent; Format(pipe, L"%s%d", CMD2_GUI_CTRL_PIPE, itr->first); Format(waitEvent, L"%s%d", CMD2_GUI_CTRL_WAIT_CONNECT, itr->first); sendCtrl.SetSendMode(FALSE); sendCtrl.SetPipeSetting(waitEvent, pipe); sendCtrl.SetConnectTimeOut(5*1000); DWORD err = sendCtrl.SendGUINotifyInfo2(¬ifyInfo); if( err == CMD_NON_SUPPORT ){ switch(notifyInfo.notifyID){ case NOTIFY_UPDATE_EPGDATA: err = sendCtrl.SendGUIUpdateEpgData(); break; case NOTIFY_UPDATE_RESERVE_INFO: case NOTIFY_UPDATE_REC_INFO: case NOTIFY_UPDATE_AUTOADD_EPG: case NOTIFY_UPDATE_AUTOADD_MANUAL: err = sendCtrl.SendGUIUpdateReserve(); break; case NOTIFY_UPDATE_SRV_STATUS: err = sendCtrl.SendGUIStatusChg((WORD)notifyInfo.param1); break; default: break; } } if( err != CMD_SUCCESS && err != CMD_NON_SUPPORT){ errID.push_back(itr->first); } }else{ errID.push_back(itr->first); } } map<wstring, REGIST_TCP_INFO>::iterator itrTCP; vector<wstring> errIP; for( itrTCP = registTCP.begin(); itrTCP != registTCP.end(); itrTCP++){ if( ::WaitForSingleObject(sys->notifyStopEvent, 0) != WAIT_TIMEOUT ){ //キャンセルされた break; } sendCtrl.SetSendMode(TRUE); sendCtrl.SetNWSetting(itrTCP->second.ip, itrTCP->second.port); sendCtrl.SetConnectTimeOut(5*1000); DWORD err = sendCtrl.SendGUINotifyInfo2(¬ifyInfo); if( err == CMD_NON_SUPPORT ){ switch(notifyInfo.notifyID){ case NOTIFY_UPDATE_EPGDATA: err = sendCtrl.SendGUIUpdateEpgData(); break; case NOTIFY_UPDATE_RESERVE_INFO: case NOTIFY_UPDATE_REC_INFO: case NOTIFY_UPDATE_AUTOADD_EPG: case NOTIFY_UPDATE_AUTOADD_MANUAL: err = sendCtrl.SendGUIUpdateReserve(); break; case NOTIFY_UPDATE_SRV_STATUS: err = sendCtrl.SendGUIStatusChg((WORD)notifyInfo.param1); break; default: break; } } if( err != CMD_SUCCESS && err != CMD_NON_SUPPORT){ errIP.push_back(itrTCP->first); } } //送信できなかったもの削除 if( sys->NotifyLock() == FALSE ) return 0; if( notifyInfo.notifyID <= 100 ){ wait = 0; }else{ wait = 0; if( sys->notifyList.size() > 0 ){ if( sys->notifyList[0].notifyID > 100 ){ wait = 5*1000; } } } for( size_t i=0; i<errID.size(); i++ ){ itr = sys->registGUIMap.find(errID[i]); if( itr != sys->registGUIMap.end() ){ sys->registGUIMap.erase(itr); } } for( size_t i=0; i<errIP.size(); i++ ){ itrTCP = sys->registTCPMap.find(errIP[i]); if( itrTCP != sys->registTCPMap.end() ){ _OutputDebugString(L"notifyErr %s:%d", itrTCP->second.ip.c_str(), itrTCP->second.port); sys->registTCPMap.erase(itrTCP); } } sys->NotifyUnLock(); } return 0; }
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { if( _tcslen(lpCmdLine) > 0 ){ if( lpCmdLine[0] == '-' || lpCmdLine[0] == '/' ){ if( _tcsicmp( _T("install"), lpCmdLine+1 ) == 0 ){ WCHAR strExePath[512] = L""; GetModuleFileName(NULL, strExePath, 512); if( InstallService(strExePath, SERVICE_NAME,SERVICE_NAME) == FALSE ){ printf("インストールに失敗しました。Vista以降の場合は管理者権限が必要です。"); } return 0; }else if( _tcsicmp( _T("remove"), lpCmdLine+1 ) == 0 ){ if( RemoveService(SERVICE_NAME) == FALSE ){ printf("アンインストールに失敗しました。Vista以降の場合は管理者権限が必要です。"); } return 0; } } } if( IsInstallService(SERVICE_NAME) == FALSE ){ //普通にexeとして起動を行う g_hMutex = _CreateMutex(TRUE, EPG_TIMER_BON_SRV_MUTEX); int err = GetLastError(); if( g_hMutex != NULL ){ if( err != ERROR_ALREADY_EXISTS ) { //起動 StartMain(FALSE); }else{ // 起動されているので予約追加の確認 CSendCtrlCmd cmd; cmd.SetConnectTimeOut(1000); cmd.SendAddloadReserve(); } ::ReleaseMutex(g_hMutex); ::CloseHandle(g_hMutex); }else{ // 起動されているので予約追加の確認 CSendCtrlCmd cmd; cmd.SetConnectTimeOut(1000); cmd.SendAddloadReserve(); } }else{ //サービスとしてインストール済み if( IsStopService(SERVICE_NAME) == FALSE ){ g_hMutex = _CreateMutex(TRUE, EPG_TIMER_BON_SRV_MUTEX); int err = GetLastError(); if( g_hMutex != NULL && err != ERROR_ALREADY_EXISTS ) { //起動 SERVICE_TABLE_ENTRY dispatchTable[] = { { SERVICE_NAME, (LPSERVICE_MAIN_FUNCTION)service_main}, { NULL, NULL} }; if( StartServiceCtrlDispatcher(dispatchTable) == FALSE ){ OutputDebugString(_T("StartServiceCtrlDispatcher failed")); } }else{ // 起動されているので予約追加の確認 CSendCtrlCmd cmd; cmd.SetConnectTimeOut(1000); cmd.SendAddloadReserve(); } }else{ //Stop状態なので起動する StartServiceCtrl(SERVICE_NAME); } } return 0; }