Exemplo n.º 1
0
bool CTunerBankCtrl::CreateCtrl(DWORD* ctrlID, DWORD* partialCtrlID, const TUNER_RESERVE& reserve) const
{
	if( this->hTunerProcess == NULL ){
		return false;
	}
	BYTE partialRecMode = reserve.recMode == RECMODE_VIEW ? 0 : min(reserve.partialRecMode, 2);
	WORD partialSID = 0;
	if( partialRecMode == 1 || partialRecMode == 2 ){
		if( FindPartialService(reserve.onid, reserve.tsid, reserve.sid, &partialSID, NULL) == false ){
			partialSID = 0;
			if( reserve.partialRecMode == 2 ){
				return false;
			}
		}
	}
	CSendCtrlCmd ctrlCmd;
	ctrlCmd.SetPipeSetting(CMD2_VIEW_CTRL_WAIT_CONNECT, CMD2_VIEW_CTRL_PIPE, this->tunerPid);
	DWORD newID;
	if( ctrlCmd.SendViewCreateCtrl(&newID) != CMD_SUCCESS ){
		return false;
	}

	if( partialRecMode == 2 ){
		//部分受信のみ
		*ctrlID = 0;
		*partialCtrlID = newID;
	}else{
		*ctrlID = newID;
		*partialCtrlID = 0;
		if( partialRecMode == 1 && partialSID != 0 && ctrlCmd.SendViewCreateCtrl(partialCtrlID) != CMD_SUCCESS ){
			*partialCtrlID = 0;
		}
	}
	SET_CTRL_MODE param;
	if( *ctrlID != 0 ){
		//通常
		param.ctrlID = *ctrlID;
		param.SID = reserve.recMode == RECMODE_ALL || reserve.recMode == RECMODE_ALL_NOB25 ? 0xFFFF : reserve.sid;
		param.enableScramble = reserve.recMode != RECMODE_ALL_NOB25 && reserve.recMode != RECMODE_SERVICE_NOB25;
		param.enableCaption = reserve.enableCaption;
		param.enableData = reserve.enableData;
		ctrlCmd.SendViewSetCtrlMode(param);
	}
	if( *partialCtrlID != 0 ){
		//部分受信
		param.ctrlID = *partialCtrlID;
		param.SID = partialSID;
		param.enableScramble = reserve.recMode != RECMODE_ALL_NOB25 && reserve.recMode != RECMODE_SERVICE_NOB25;
		param.enableCaption = reserve.enableCaption;
		param.enableData = reserve.enableData;
		ctrlCmd.SendViewSetCtrlMode(param);
	}
	SYSTEMTIME st;
	ConvertSystemTime(reserve.startTime, &st);
	wstring msg;
	Format(msg, L"%s %04d/%02d/%02d %02d:%02d:%02d〜 %s", reserve.stationName.c_str(),
	       st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, reserve.title.c_str());
	this->notifyManager.AddNotifyMsg(NOTIFY_UPDATE_PRE_REC_START, msg);
	return true;
}
Exemplo n.º 2
0
bool CTunerBankCtrl::DelReserve(DWORD reserveID)
{
	map<DWORD, TUNER_RESERVE>::iterator itr = this->reserveMap.find(reserveID);
	if( itr != this->reserveMap.end() ){
		if( itr->second.state != TR_IDLE ){
			//hTunerProcessは必ず!NULL
			CWatchBlock watchBlock(&this->watchContext);
			CSendCtrlCmd ctrlCmd;
			ctrlCmd.SetPipeSetting(CMD2_VIEW_CTRL_WAIT_CONNECT, CMD2_VIEW_CTRL_PIPE, this->tunerPid);
			for( int i = 0; i < 2; i++ ){
				if( itr->second.ctrlID[i] != 0 ){
					if( itr->second.state == TR_REC && itr->second.recMode != RECMODE_VIEW ){
						SET_CTRL_REC_STOP_PARAM param;
						param.ctrlID = itr->second.ctrlID[i];
						param.saveErrLog = this->saveErrLog;
						SET_CTRL_REC_STOP_RES_PARAM resVal;
						ctrlCmd.SendViewStopRec(param, &resVal);
					}
					ctrlCmd.SendViewDeleteCtrl(itr->second.ctrlID[i]);
				}
			}
			if( itr->second.state == TR_REC ){
				//録画終了に伴ってGUIキープが解除されたかもしれない
				this->tunerResetLock = true;
			}
		}
		this->reserveMap.erase(itr);
		return true;
	}
	return false;
}
Exemplo n.º 3
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(&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){
					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(&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){
				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;
}
Exemplo n.º 4
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(&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){
					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(&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){
				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;
}
Exemplo n.º 5
0
UINT WINAPI CBatManager::BatWorkThread(LPVOID param)
{
	CBatManager* sys = (CBatManager*)param;
	CSendCtrlCmd sendCtrl;

	while(1){
		if( ::WaitForSingleObject(sys->batWorkStopEvent, 1000) != WAIT_TIMEOUT ){
			//キャンセルされた
			break;
		}
		if( sys->workFlag == TRUE ){
			BAT_WORK_INFO work;
			if( sys->Lock() == TRUE ){
				if( sys->workList.size() == 0 ){
					sys->UnLock();
					break;
				}else{
					work = sys->workList[0];
				}
			}else{
				continue;
			}

			sys->UnLock();

			if( work.reserveInfo.recSetting.batFilePath.size() > 0 ){
				wstring batFilePath = L"";
				if( sys->CreateBatFile(&work, work.reserveInfo.recSetting.batFilePath, batFilePath) == TRUE ){
					wstring strExecute;
					Format(strExecute, L"\"%s\"", batFilePath.c_str());

					BOOL send = FALSE;
					DWORD PID = 0;
					map<DWORD, DWORD>::iterator itr;
					map<DWORD, DWORD> registGUIMap;
					if( sys->notifyManager != NULL ){
						sys->notifyManager->GetRegistGUI(&registGUIMap);
					}
					for( itr = registGUIMap.begin(); itr != registGUIMap.end(); itr++ ){
						wstring pipeName = L"";
						wstring waitEventName = L"";

						Format(pipeName, L"%s%d", CMD2_GUI_CTRL_PIPE, itr->first );
						Format(waitEventName, L"%s%d", CMD2_GUI_CTRL_WAIT_CONNECT, itr->first );

						sendCtrl.SetPipeSetting(waitEventName, pipeName);

						if( sendCtrl.SendGUIExecute(strExecute.c_str(), &PID) == CMD_SUCCESS ){
							send = TRUE;
							break;
						}
					}
					if( send == FALSE ){
						//GUI経由で起動できなかった
						PROCESS_INFORMATION pi;
						STARTUPINFO si;
						ZeroMemory(&si,sizeof(si));
						si.cb=sizeof(si);

						send = CreateProcess( NULL, (WCHAR*)strExecute.c_str(), NULL, NULL, FALSE, GetPriorityClass(GetCurrentProcess()), NULL, NULL, &si, &pi );
						if( send == TRUE ){
							CloseHandle(pi.hThread);
							CloseHandle(pi.hProcess);

							PID = pi.dwProcessId;
						}
					}
					if( send == TRUE ){
						//終了監視
						while(1){
							if( WaitForSingleObject( sys->batWorkStopEvent, 2000 ) != WAIT_TIMEOUT ){
								//中止
								break;
							}
							if( _FindOpenExeProcess(PID) == FALSE ){
								//終わった
								sys->lastSuspendMode = work.reserveInfo.recSetting.suspendMode;
								sys->lastRebootFlag = work.reserveInfo.recSetting.rebootFlag;
								break;
							}
						}
					}
				}else{
					_OutputDebugString(L"BATファイル作成エラー:%s", work.reserveInfo.recSetting.batFilePath);
				}
			}

			if( sys->Lock() == TRUE ){
				sys->workList.erase(sys->workList.begin());
				sys->UnLock();
			}
		}
	}
	sys->workFlag = FALSE;

	return 0;
}
Exemplo n.º 6
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;
}
Exemplo n.º 7
0
bool CTunerBankCtrl::RecStart(const TUNER_RESERVE& reserve, __int64 now) const
{
	if( this->hTunerProcess == NULL ){
		return false;
	}
	if( reserve.recMode == RECMODE_VIEW ){
		return true;
	}
	CSendCtrlCmd ctrlCmd;
	ctrlCmd.SetPipeSetting(CMD2_VIEW_CTRL_WAIT_CONNECT, CMD2_VIEW_CTRL_PIPE, this->tunerPid);
	bool isMainCtrl = true;
	for( int i = 0; i < 2; i++ ){
		if( reserve.ctrlID[i] != 0 ){
			SET_CTRL_REC_PARAM param;
			param.ctrlID = reserve.ctrlID[i];
			//saveFolder[].recFileNameが空でない限りこのフィールドが利用されることはない
			param.fileName = L"padding.ts";
			//同時出力用ファイル名
			param.saveFolder = i == 0 ? reserve.recFolder : reserve.partialRecFolder;
			if( param.saveFolder.empty() ){
				param.saveFolder.resize(1);
				wstring commonIniPath;
				GetCommonIniPath(commonIniPath);
				GetRecFolderPath(param.saveFolder[0].recFolder);
				param.saveFolder[0].writePlugIn = GetPrivateProfileToString(L"SET", L"RecWritePlugIn0", L"", commonIniPath.c_str());
				param.saveFolder[0].recNamePlugIn = this->recNamePlugInFileName;
			}else{
				for( size_t j = 0; j < param.saveFolder.size(); j++ ){
					if( CompareNoCase(param.saveFolder[j].recFolder, L"!Default") == 0 ){
						//注意: この置換は原作にはない
						GetRecFolderPath(param.saveFolder[j].recFolder);
					}
					if( param.saveFolder[j].recNamePlugIn.empty() ){
						param.saveFolder[j].recNamePlugIn = this->recNamePlugInFileName;
					}
				}
			}
			//recNamePlugInを展開して実ファイル名をセット
			for( size_t j = 0; j < param.saveFolder.size(); j++ ){
				param.saveFolder[j].recFileName.clear();
				if( param.saveFolder[j].recNamePlugIn.empty() == false ){
					WORD sid = reserve.sid;
					WORD eid = reserve.eid;
					wstring stationName = reserve.stationName;
					if( i != 0 ){
						FindPartialService(reserve.onid, reserve.tsid, reserve.sid, &sid, &stationName);
						eid = 0xFFFF;
					}
					wstring plugInPath;
					GetModuleFolderPath(plugInPath);
					plugInPath += L"\\RecName\\";
					{
						PLUGIN_RESERVE_INFO info;
						ConvertSystemTime(reserve.startTime, &info.startTime);
						info.durationSec = reserve.durationSecond;
						wcscpy_s(info.eventName, reserve.title.c_str());
						info.ONID = reserve.onid;
						info.TSID = reserve.tsid;
						info.SID = sid;
						info.EventID = eid;
						wcscpy_s(info.serviceName, stationName.c_str());
						wcscpy_s(info.bonDriverName, this->bonFileName.c_str());
						info.bonDriverID = this->tunerID >> 16;
						info.tunerID = this->tunerID & 0xFFFF;
						EPG_EVENT_INFO* epgInfo = NULL;
						if( info.EventID != 0xFFFF ){
							EPGDB_EVENT_INFO epgDBInfo;
							if( this->epgDBManager.SearchEpg(info.ONID, info.TSID, info.SID, info.EventID, &epgDBInfo) != FALSE ){
								epgInfo = new EPG_EVENT_INFO;
								CopyEpgInfo(epgInfo, &epgDBInfo);
							}
						}
						info.reserveID = reserve.reserveID;
						info.epgInfo = epgInfo;
						info.sizeOfStruct = 0;
						WCHAR name[512];
						DWORD size = 512;
						if( CReNamePlugInUtil::ConvertRecName3(&info, param.saveFolder[j].recNamePlugIn.c_str(), plugInPath.c_str(), name, &size) ){
							param.saveFolder[j].recFileName = name;
							CheckFileName(param.saveFolder[j].recFileName, this->recNameNoChkYen);
						}
						delete epgInfo;
					}
					param.saveFolder[j].recNamePlugIn.clear();
				}
				//実ファイル名は空にしない
				if( param.saveFolder[j].recFileName.empty() ){
					SYSTEMTIME st;
					ConvertSystemTime(max(reserve.startTime, now), &st);
					Format(param.saveFolder[j].recFileName, L"%04d%02d%02d%02d%02d%02X%02X%02d-%s.ts",
					       st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute,
					       this->tunerID >> 16, this->tunerID & 0xFFFF, param.ctrlID, reserve.title.c_str());
					CheckFileName(param.saveFolder[j].recFileName);
				}
			}
Exemplo n.º 8
0
vector<CTunerBankCtrl::CHECK_RESULT> CTunerBankCtrl::Check(vector<DWORD>* startedReserveIDList)
{
	vector<CHECK_RESULT> retList;

	if( this->hTunerProcess && WaitForSingleObject(this->hTunerProcess, 0) != WAIT_TIMEOUT ){
		//チューナが予期せず閉じられた
		CloseTuner();
		this->specialState = TR_IDLE;
		//TR_IDLEでない全予約を葬る
		for( map<DWORD, TUNER_RESERVE>::const_iterator itr = this->reserveMap.begin(); itr != this->reserveMap.end(); ){
			if( itr->second.state != TR_IDLE ){
				CHECK_RESULT ret;
				ret.type = CHECK_ERR_REC;
				ret.reserveID = itr->first;
				retList.push_back(ret);
				this->reserveMap.erase(itr++);
			}else{
				itr++;
			}
		}
	}

	CWatchBlock watchBlock(&this->watchContext);
	CSendCtrlCmd ctrlCmd;
	if( this->hTunerProcess ){
		//チューナ起動時にはこれを再度呼ぶこと
		ctrlCmd.SetPipeSetting(CMD2_VIEW_CTRL_WAIT_CONNECT, CMD2_VIEW_CTRL_PIPE, this->tunerPid);
	}

	if( this->specialState == TR_EPGCAP ){
		DWORD status;
		if( ctrlCmd.SendViewGetStatus(&status) == CMD_SUCCESS ){
			if( status != VIEW_APP_ST_GET_EPG ){
				//取得終わった
				OutputDebugString(L"epg end\r\n");
				CloseTuner();
				this->specialState = TR_IDLE;
			}
		}else{
			//エラー
			OutputDebugString(L"epg err\r\n");
			CloseTuner();
			this->specialState = TR_IDLE;
		}
	}else if( this->specialState == TR_NWTV ){
		//ネットワークモードではGUIキープできないのでBonDriverが変更されるかもしれない
		//BonDriverが変更されたチューナはこのバンクの管理下に置けないので、ネットワークモードを解除する
		wstring bonDriver;
		if( ctrlCmd.SendViewGetBonDrivere(&bonDriver) == CMD_SUCCESS && CompareNoCase(bonDriver, this->bonFileName) != 0 ){
			if( ctrlCmd.SendViewSetID(-1) == CMD_SUCCESS ){
				CBlockLock lock(&this->watchContext.lock);
				CloseHandle(this->hTunerProcess);
				this->hTunerProcess = NULL;
				this->specialState = TR_IDLE;
			}else{
				//ID剥奪に失敗したので消えてもらうしかない
				CloseNWTV();
			}
			//TODO: 汎用のログ用メッセージが存在しないので、やむを得ずNOTIFY_UPDATE_REC_ENDで警告する
			this->notifyManager.AddNotifyMsg(NOTIFY_UPDATE_REC_END,
				L"BonDriverが変更されたためNetworkモードを解除しました\r\n変更したBonDriverに録画の予定がないか注意してください");
		}
	}else if( this->hTunerProcess && this->tunerChLocked == false ){
		//GUIキープされていないのでBonDriverが変更されるかもしれない
		wstring bonDriver;
		if( ctrlCmd.SendViewGetBonDrivere(&bonDriver) == CMD_SUCCESS && CompareNoCase(bonDriver, this->bonFileName) != 0 ){
			if( ctrlCmd.SendViewSetID(-1) == CMD_SUCCESS ){
				CBlockLock lock(&this->watchContext.lock);
				CloseHandle(this->hTunerProcess);
				this->hTunerProcess = NULL;
			}else{
				//ID剥奪に失敗したので消えてもらうしかない
				CloseTuner();
			}
			//TR_IDLEでない全予約を葬る
			for( map<DWORD, TUNER_RESERVE>::const_iterator itr = this->reserveMap.begin(); itr != this->reserveMap.end(); ){
				if( itr->second.state != TR_IDLE ){
					CHECK_RESULT ret;
					ret.type = CHECK_ERR_REC;
					ret.reserveID = itr->first;
					retList.push_back(ret);
					this->reserveMap.erase(itr++);
				}else{
					itr++;
				}
			}
		}
	}

	this->delayTime = 0;
	this->epgCapDelayTime = 0;
	if( this->hTunerProcess && this->specialState != TR_NWTV ){
		//PC時計との誤差取得
		int delaySec;
		if( ctrlCmd.SendViewGetDelay(&delaySec) == CMD_SUCCESS ){
			//誤った値を掴んでおかしなことにならないよう、EPG取得中の値は状態遷移の参考にしない
			if( this->specialState == TR_EPGCAP ){
				this->epgCapDelayTime = delaySec * I64_1SEC;
			}else{
				this->delayTime = delaySec * I64_1SEC;
			}
		}
	}
	__int64 now = GetNowI64Time() + this->delayTime;

	//終了時間を過ぎた予約を回収し、TR_IDLE->TR_READY以外の遷移をする
	vector<pair<__int64, DWORD>> idleList;
	bool ngResetLock = false;
	for( map<DWORD, TUNER_RESERVE>::iterator itrRes = this->reserveMap.begin(); itrRes != this->reserveMap.end(); ){
		TUNER_RESERVE& r = itrRes->second;
		CHECK_RESULT ret;
		ret.type = 0;
		switch( r.state ){
		case TR_IDLE:
			if( r.startTime + r.endMargin + r.durationSecond * I64_1SEC < now ){
				ret.type = CHECK_ERR_PASS;
			}
			//開始順が秒精度なので、前後関係を確実にするため開始時間は必ず秒精度で扱う
			else if( (r.startTime - r.startMargin - this->recWakeTime) / I64_1SEC < now / I64_1SEC ){
				//録画開始recWakeTime前〜
				idleList.push_back(std::make_pair(r.startOrder, r.reserveID));
			}
			break;
		case TR_READY:
			if( r.startTime + r.endMargin + r.durationSecond * I64_1SEC < now ){
				for( int i = 0; i < 2; i++ ){
					if( r.ctrlID[i] != 0 ){
						ctrlCmd.SendViewDeleteCtrl(r.ctrlID[i]);
					}
				}
				ret.type = CHECK_ERR_PASS;
			}
			//パイプコマンドにはチャンネル変更の完了を調べる仕組みがないので、妥当な時間だけ待つ
			else if( GetTickCount() - this->tunerChChgTick > 5000 && r.startTime - r.startMargin < now ){
				//録画開始〜
				if( RecStart(r, now) ){
					//途中から開始されたか
					r.notStartHead = r.startTime - r.startMargin + 60 * I64_1SEC < now;
					r.appendPgInfo = false;
					r.savedPgInfo = false;
					r.state = TR_REC;
					if( r.recMode == RECMODE_VIEW ){
						//視聴予約でない予約が1つでもあれば「視聴モード」にしない
						map<DWORD, TUNER_RESERVE>::const_iterator itr;
						for( itr = this->reserveMap.begin(); itr != this->reserveMap.end(); itr++ ){
							if( itr->second.state != TR_IDLE && itr->second.recMode != RECMODE_VIEW ){
								break;
							}
						}
						if( itr == this->reserveMap.end() ){
							//「視聴モード」にするとGUIキープが解除されてしまうためチャンネルを把握することはできない
							ctrlCmd.SendViewSetStandbyRec(2);
							this->tunerChLocked = false;
							if( this->recView ){
								ctrlCmd.SendViewExecViewApp();
							}
						}
					}
					if( startedReserveIDList ){
						startedReserveIDList->push_back(r.reserveID);
					}
				}else{
					//開始できなかった
					ret.type = CHECK_ERR_RECSTART;
				}
			}
			break;
		case TR_REC:
			{
				//ステータス確認
				DWORD status;
				if( r.recMode != RECMODE_VIEW && ctrlCmd.SendViewGetStatus(&status) == CMD_SUCCESS && status != VIEW_APP_ST_REC ){
					//キャンセルされた?
					ret.type = CHECK_ERR_REC;
					this->tunerResetLock = true;
				}else if( r.startTime + r.endMargin + r.durationSecond * I64_1SEC < now ){
					ret.type = CHECK_ERR_REC;
					ret.continueRec = false;
					ret.drops = 0;
					ret.scrambles = 0;
					bool isMainCtrl = true;
					for( int i = 0; i < 2; i++ ){
						if( r.ctrlID[i] != 0 ){
							if( r.recMode == RECMODE_VIEW ){
								if( isMainCtrl ){
									ret.type = CHECK_END;
								}
							}else{
								SET_CTRL_REC_STOP_PARAM param;
								param.ctrlID = r.ctrlID[i];
								param.saveErrLog = this->saveErrLog;
								SET_CTRL_REC_STOP_RES_PARAM resVal;
								if( ctrlCmd.SendViewStopRec(param, &resVal) != CMD_SUCCESS ){
									if( isMainCtrl ){
										ret.type = CHECK_ERR_RECEND;
									}
								}else if( isMainCtrl ){
									ret.type = resVal.subRecFlag ? CHECK_END_END_SUBREC :
									           r.notStartHead ? CHECK_END_NOT_START_HEAD :
									           r.savedPgInfo == false ? CHECK_END_NOT_FIND_PF : CHECK_END;
									ret.recFilePath = resVal.recFilePath;
									ret.drops = resVal.drop;
									ret.scrambles = resVal.scramble;
									ret.epgStartTime = r.epgStartTime;
									ret.epgEventName = r.epgEventName;
								}
							}
							ctrlCmd.SendViewDeleteCtrl(r.ctrlID[i]);
							isMainCtrl = false;
						}
					}
					//録画終了に伴ってGUIキープが解除されたかもしれない
					this->tunerResetLock = true;
				}else{
					//番組情報確認
					if( r.savedPgInfo == false && r.recMode != RECMODE_VIEW ){
						GET_EPG_PF_INFO_PARAM val;
						val.ONID = r.onid;
						val.TSID = r.tsid;
						val.SID = r.sid;
						val.pfNextFlag = FALSE;
						EPGDB_EVENT_INFO resVal;
						if( ctrlCmd.SendViewGetEventPF(&val, &resVal) == CMD_SUCCESS &&
						    resVal.StartTimeFlag && resVal.DurationFlag &&
						    ConvertI64Time(resVal.start_time) <= r.startTime + 30 * I64_1SEC &&
						    r.startTime + 30 * I64_1SEC < ConvertI64Time(resVal.start_time) + resVal.durationSec * I64_1SEC &&
						    (r.eid == 0xFFFF || r.eid == resVal.event_id) ){
							//開始時間から30秒は過ぎているのでこの番組情報が録画中のもののはず
							r.savedPgInfo = true;
							r.epgStartTime = resVal.start_time;
							r.epgEventName = resVal.shortInfo ? resVal.shortInfo->event_name : L"";
							//ごく稀にAPR(改行)を含むため
							Replace(r.epgEventName, L"\r\n", L"");
							if( this->saveProgramInfo ){
								for( int i = 0; i < 2; i++ ){
									wstring recPath;
									if( r.ctrlID[i] != 0 && ctrlCmd.SendViewGetRecFilePath(r.ctrlID[i], &recPath) == CMD_SUCCESS ){
										SaveProgramInfo(recPath.c_str(), resVal, r.appendPgInfo);
									}
								}
							}
						}
					}
					//まだ録画中の予約があるのでGUIキープを再設定してはいけない
					ngResetLock = true;
				}
			}
			break;
		}
		if( ret.type != 0 ){
			ret.reserveID = itrRes->first;
			retList.push_back(ret);
			this->reserveMap.erase(itrRes++);
		}else{
			itrRes++;
		}
	}

	//TR_IDLE->TR_READYの遷移を待つ予約を開始順に並べる
	std::sort(idleList.begin(), idleList.end());

	//TR_IDLE->TR_READY(TR_REC)の遷移をする
	for( vector<pair<__int64, DWORD>>::const_iterator itrIdle = idleList.begin(); itrIdle != idleList.end(); itrIdle++ ){
		map<DWORD, TUNER_RESERVE>::iterator itrRes = this->reserveMap.find(itrIdle->second);
		TUNER_RESERVE& r = itrRes->second;
		CHECK_RESULT ret;
		ret.type = 0;
		if( this->hTunerProcess == NULL ){
			//チューナを起動する
			SET_CH_INFO initCh;
			initCh.ONID = r.onid;
			initCh.TSID = r.tsid;
			initCh.SID = r.sid;
			initCh.useSID = TRUE;
			initCh.useBonCh = FALSE;
			bool nwUdpTcp = this->recNW || r.recMode == RECMODE_VIEW;
			if( OpenTuner(this->recMinWake, nwUdpTcp, nwUdpTcp, true, &initCh) ){
				this->tunerONID = r.onid;
				this->tunerTSID = r.tsid;
				this->tunerChLocked = true;
				this->tunerResetLock = false;
				this->tunerChChgTick = GetTickCount();
				this->notifyManager.AddNotifyMsg(NOTIFY_UPDATE_PRE_REC_START, this->bonFileName);
				ctrlCmd.SetPipeSetting(CMD2_VIEW_CTRL_WAIT_CONNECT, CMD2_VIEW_CTRL_PIPE, this->tunerPid);
				r.retryOpenCount = 0;
			}else if( ++r.retryOpenCount >= 4 || r.retryOpenCount == 2 && CloseOtherTuner() == false ){
				//試行2回→他チューナ終了成功時さらに2回→起動できなかった
				ret.type = CHECK_ERR_OPEN;
			}
		}else{
			r.retryOpenCount = 0;
		}
		if( this->hTunerProcess && (r.startTime - r.startMargin) / I64_1SEC - READY_MARGIN < now / I64_1SEC ){
			//録画開始READY_MARGIN秒前〜
			//原作では録画制御作成は通常録画時60秒前、割り込み録画時15秒前だが
			//作成を前倒しする必要は特にないのと、チャンネル変更からEIT[p/f]取得までの時間を確保できるようこの秒数にした
			if( this->specialState == TR_EPGCAP ){
				//EPG取得をキャンセル(遷移中断)
				OutputDebugString(L"epg cancel\r\n");
				//CSendCtrlCmd::SendViewEpgCapStop()は送らない(即座にチューナ閉じるので意味がないため)
				CloseTuner();
				this->specialState = TR_IDLE;
				break;
			}else if( this->specialState == TR_NWTV ){
				//ネットワークモードを解除
				wstring bonDriver;
				DWORD status;
				if( ctrlCmd.SendViewGetBonDrivere(&bonDriver) == CMD_SUCCESS && CompareNoCase(bonDriver, this->bonFileName) == 0 &&
				    ctrlCmd.SendViewGetStatus(&status) == CMD_SUCCESS && (status == VIEW_APP_ST_NORMAL || status == VIEW_APP_ST_ERR_CH_CHG) ){
					//プロセスを引き継ぐ
					this->tunerONID = r.onid;
					this->tunerTSID = r.tsid;
					this->tunerChLocked = false;
					this->tunerResetLock = false;
					this->specialState = TR_IDLE;
				}else{
					//ネットワークモード終了(遷移中断)
					CloseNWTV();
					break;
				}
			}
			if( this->tunerONID != r.onid || this->tunerTSID != r.tsid ){
				//チャンネル違うので、TR_IDLEでない全予約の優先度を比べる
				map<DWORD, TUNER_RESERVE>::const_iterator itr;
				for( itr = this->reserveMap.begin(); itr != this->reserveMap.end(); itr++ ){
					if( itr->second.state != TR_IDLE && itr->second.effectivePriority < r.effectivePriority ){
						break;
					}
				}
				if( itr == this->reserveMap.end() ){
					//TR_IDLEでない全予約は自分よりも弱いので葬る
					for( itr = this->reserveMap.begin(); itr != this->reserveMap.end(); ){
						if( itr->second.state != TR_IDLE ){
							CHECK_RESULT retOther;
							retOther.type = CHECK_ERR_REC;
							retOther.reserveID = itr->first;
							retOther.continueRec = false;
							retOther.drops = 0;
							retOther.scrambles = 0;
							bool isMainCtrl = true;
							for( int i = 0; i < 2; i++ ){
								if( itr->second.ctrlID[i] != 0 ){
									if( itr->second.state == TR_REC ){
										if( isMainCtrl ){
											retOther.type = CHECK_END_NEXT_START_END;
										}
										if( itr->second.recMode != RECMODE_VIEW ){
											SET_CTRL_REC_STOP_PARAM param;
											param.ctrlID = itr->second.ctrlID[i];
											param.saveErrLog = this->saveErrLog;
											SET_CTRL_REC_STOP_RES_PARAM resVal;
											if( ctrlCmd.SendViewStopRec(param, &resVal) != CMD_SUCCESS ){
												if( isMainCtrl ){
													retOther.type = CHECK_ERR_RECEND;
												}
											}else if( isMainCtrl ){
												retOther.recFilePath = resVal.recFilePath;
												retOther.drops = resVal.drop;
												retOther.scrambles = resVal.scramble;
											}
										}
									}
									ctrlCmd.SendViewDeleteCtrl(itr->second.ctrlID[i]);
									isMainCtrl = false;
								}
							}
							retList.push_back(retOther);
							this->reserveMap.erase(itr++);
						}else{
							itr++;
						}
					}
					this->tunerONID = r.onid;
					this->tunerTSID = r.tsid;
					this->tunerChLocked = false;
					this->tunerResetLock = false;
				}
			}
			if( this->tunerONID == r.onid && this->tunerTSID == r.tsid ){
				if( this->tunerChLocked == false ){
					//チャンネル変更
					SET_CH_INFO chgCh;
					chgCh.ONID = r.onid;
					chgCh.TSID = r.tsid;
					chgCh.SID = r.sid;
					chgCh.useSID = TRUE;
					chgCh.useBonCh = FALSE;
					//「予約録画待機中」
					ctrlCmd.SendViewSetStandbyRec(1);
					if( ctrlCmd.SendViewSetCh(&chgCh) == CMD_SUCCESS ){
						this->tunerChLocked = true;
						this->tunerResetLock = false;
						this->tunerChChgTick = GetTickCount();
					}
				}
				if( this->tunerChLocked ){
					//同一チャンネルなので録画制御を作成できる
					bool continueRec = false;
					for( map<DWORD, TUNER_RESERVE>::const_iterator itr = this->reserveMap.begin(); itr != this->reserveMap.end(); itr++ ){
						if( itr->second.continueRecFlag &&
						    itr->second.state == TR_REC &&
						    itr->second.sid == r.sid &&
						    itr->second.recMode != RECMODE_VIEW &&
						    itr->second.recMode == r.recMode &&
						    itr->second.enableCaption == r.enableCaption &&
						    itr->second.enableData == r.enableData &&
						    itr->second.partialRecMode == r.partialRecMode ){
							//連続録画なので、同一制御IDで録画開始されたことにする。TR_RECまで遷移するので注意
							r.state = TR_REC;
							r.ctrlID[0] = itr->second.ctrlID[0];
							r.ctrlID[1] = itr->second.ctrlID[1];
							r.notStartHead = r.startTime - r.startMargin + 60 * I64_1SEC < now;
							r.appendPgInfo = itr->second.appendPgInfo || itr->second.savedPgInfo;
							r.savedPgInfo = false;
							//引継ぎ元を葬る
							CHECK_RESULT retOther;
							retOther.type = CHECK_ERR_REC;
							retOther.reserveID = itr->first;
							retOther.continueRec = true;
							retOther.drops = 0;
							retOther.scrambles = 0;
							for( int i = 0; i < 2; i++ ){
								if( itr->second.ctrlID[i] != 0 ){
									if( ctrlCmd.SendViewGetRecFilePath(itr->second.ctrlID[i], &retOther.recFilePath) == CMD_SUCCESS ){
										retOther.type = itr->second.notStartHead ? CHECK_END_NOT_START_HEAD :
										                itr->second.savedPgInfo == false ? CHECK_END_NOT_FIND_PF : CHECK_END;
										retOther.epgStartTime = itr->second.epgStartTime;
										retOther.epgEventName = itr->second.epgEventName;
									}
									break;
								}
							}
							retList.push_back(retOther);
							this->reserveMap.erase(itr);
							continueRec = true;
							break;
						}
					}
					if( continueRec == false ){
						if( CreateCtrl(&r.ctrlID[0], &r.ctrlID[1], r) ){
							r.state = TR_READY;
						}else{
							//作成できなかった
							ret.type = CHECK_ERR_CTRL;
						}
					}
				}
			}
		}
		if( ret.type != 0 ){
			ret.reserveID = itrRes->first;
			retList.push_back(ret);
			this->reserveMap.erase(itrRes);
		}
	}

	if( IsNeedOpenTuner() == false ){
		//チューナが必要なくなった
		CloseTuner();
	}
	if( this->hTunerProcess && this->specialState == TR_IDLE && this->tunerResetLock ){
		if( ngResetLock == false ){
			//「予約録画待機中」
			ctrlCmd.SendViewSetStandbyRec(1);
		}
		this->tunerResetLock = false;
	}
	return retList;
}