bool CDriverInfo::LoadTuningSpaceList(LoadTuningSpaceListMode Mode) { CAppMain &App=GetAppClass(); LPCTSTR pszFileName=m_FileName.c_str(); bool fUseDriver; if (Mode==LOADTUNINGSPACE_NOLOADDRIVER) { fUseDriver=false; } else if (Mode==LOADTUNINGSPACE_USEDRIVER) { fUseDriver=true; } else { CDriverManager::TunerSpec Spec; if (App.DriverManager.GetTunerSpec(pszFileName,&Spec) && (Spec.Flags & CDriverManager::TunerSpec::FLAG_NOENUMCHANNEL)!=0) fUseDriver=false; else fUseDriver=true; } if (!m_fChannelFileLoaded) { TCHAR szChannelFileName[MAX_PATH]; App.Core.GetChannelFileName(pszFileName,szChannelFileName,lengthof(szChannelFileName)); if (m_TuningSpaceList.LoadFromFile(szChannelFileName)) { #if 0 if (fUseDriver && Mode==LOADTUNINGSPACE_DEFAULT) { const int NumSpaces=m_TuningSpaceList.NumSpaces(); int i; for (i=0;i<NumSpaces;i++) { if (m_TuningSpaceList.GetTuningSpaceName(i)==NULL || m_TuningSpaceList.GetChannelList(i)->NumChannels()==0) break; } if (i==NumSpaces) fUseDriver=false; } #else if (Mode==LOADTUNINGSPACE_DEFAULT) fUseDriver=false; #endif m_fChannelFileLoaded=true; } else { if (!fUseDriver && !m_fDriverSpaceLoaded) return false; } } if (fUseDriver && !m_fDriverSpaceLoaded) { TCHAR szFilePath[MAX_PATH]; if (::PathIsRelative(pszFileName)) { TCHAR szTemp[MAX_PATH]; App.Core.GetDriverDirectory(szTemp,lengthof(szTemp)); ::PathAppend(szTemp,pszFileName); ::PathCanonicalize(szFilePath,szTemp); } else { ::lstrcpy(szFilePath,pszFileName); } HMODULE hLib=::GetModuleHandle(szFilePath); if (hLib!=NULL) { TCHAR szCurDriverPath[MAX_PATH]; if (App.CoreEngine.GetDriverPath(szCurDriverPath,lengthof(szCurDriverPath)) && IsEqualFileName(szFilePath,szCurDriverPath)) { m_DriverSpaceList=*App.ChannelManager.GetDriverTuningSpaceList(); m_fDriverSpaceLoaded=true; } } else if ((hLib=::LoadLibrary(szFilePath))!=NULL) { CreateBonDriverFunc pCreate= reinterpret_cast<CreateBonDriverFunc>(::GetProcAddress(hLib,"CreateBonDriver")); IBonDriver *pBonDriver; if (pCreate!=NULL && (pBonDriver=pCreate())!=NULL) { IBonDriver2 *pBonDriver2=dynamic_cast<IBonDriver2*>(pBonDriver); if (pBonDriver2!=NULL) { int NumSpaces; for (NumSpaces=0;pBonDriver2->EnumTuningSpace(NumSpaces)!=NULL;NumSpaces++); m_DriverSpaceList.Reserve(NumSpaces); TVTest::StringUtility::Assign(m_TunerName,pBonDriver2->GetTunerName()); for (int i=0;i<NumSpaces;i++) { CTuningSpaceInfo *pTuningSpaceInfo=m_DriverSpaceList.GetTuningSpaceInfo(i); LPCTSTR pszName=pBonDriver2->EnumTuningSpace(i); pTuningSpaceInfo->SetName(pszName); CChannelList *pChannelList=pTuningSpaceInfo->GetChannelList(); for (int j=0;(pszName=pBonDriver2->EnumChannelName(i,j))!=NULL;j++) { pChannelList->AddChannel(CChannelInfo(i,j,j+1,pszName)); } } m_fDriverSpaceLoaded=true; } pBonDriver->Release(); } ::FreeLibrary(hLib); } for (int i=0;i<m_TuningSpaceList.NumSpaces();i++) { if (m_TuningSpaceList.GetTuningSpaceName(i)==NULL) m_TuningSpaceList.GetTuningSpaceInfo(i)->SetName(m_DriverSpaceList.GetTuningSpaceName(i)); } } if (!m_fChannelFileLoaded && !m_fDriverSpaceLoaded) return false; return true; }
UINT WINAPI CBonDriverUtil::DriverThread(LPVOID param) { //BonDriverがCOMを利用するかもしれないため CoInitialize(NULL); CBonDriverUtil* sys = (CBonDriverUtil*)param; IBonDriver* bonIF = NULL; sys->bon2IF = NULL; HMODULE hModule = LoadLibrary((sys->loadDllFolder + L"\\" + sys->loadDllFileName).c_str()); if( hModule == NULL ){ OutputDebugString(L"★BonDriverがロードできません\r\n"); }else{ IBonDriver* (*funcCreateBonDriver)() = (IBonDriver*(*)())GetProcAddress(hModule, "CreateBonDriver"); if( funcCreateBonDriver == NULL ){ OutputDebugString(L"★GetProcAddressに失敗しました\r\n"); }else if( (bonIF = funcCreateBonDriver()) != NULL && (sys->bon2IF = dynamic_cast<IBonDriver2*>(bonIF)) != NULL ){ if( sys->bon2IF->OpenTuner() == FALSE ){ OutputDebugString(L"★OpenTunerに失敗しました\r\n"); }else{ sys->initChSetFlag = false; //チューナー名の取得 LPCWSTR tunerName = sys->bon2IF->GetTunerName(); sys->loadTunerName = tunerName ? tunerName : L""; Replace(sys->loadTunerName, L"(",L"("); Replace(sys->loadTunerName, L")",L")"); //チャンネル一覧の取得 sys->loadChList.clear(); for( DWORD countSpace = 0; ; countSpace++ ){ LPCWSTR spaceName = sys->bon2IF->EnumTuningSpace(countSpace); if( spaceName == NULL ){ break; } sys->loadChList.push_back(pair<wstring, vector<wstring>>(spaceName, vector<wstring>())); for( DWORD countCh = 0; ; countCh++ ){ LPCWSTR chName = sys->bon2IF->EnumChannelName(countSpace, countCh); if( chName == NULL ){ break; } sys->loadChList.back().second.push_back(chName); } } sys->hwndDriver = CreateWindow(L"BonDriverUtilWorker", NULL, WS_OVERLAPPEDWINDOW, 0, 0, 0, 0, HWND_MESSAGE, NULL, GetModuleHandle(NULL), sys); if( sys->hwndDriver == NULL ){ sys->bon2IF->CloseTuner(); } } } } if( sys->hwndDriver == NULL ){ //Openできなかった if( bonIF ){ bonIF->Release(); } if( hModule ){ FreeLibrary(hModule); } CoUninitialize(); return 0; } //メッセージループ MSG msg; while( GetMessage(&msg, NULL, 0, 0) > 0 ){ DispatchMessage(&msg); } sys->bon2IF->CloseTuner(); bonIF->Release(); FreeLibrary(hModule); CoUninitialize(); return 0; }
int main(int argc, char *argv[]) { int opt, bfind, ofind; char *bon, *output; DWORD dwSpace, dwChannel; // パラメータ処理 bon = output = NULL; bfind = ofind = 0; dwSpace = dwChannel = 0; while ((opt = getopt(argc, argv, "b:s:o:")) != -1) { switch (opt) { case 'b': // BonDriver指定 bon = optarg; bfind = 1; break; case 's': // 使用スペース指定(デフォルトは0) dwSpace = strtoul(optarg, NULL, 10); break; case 'o': // 出力先指定 output = optarg; ofind = 1; break; default: usage(argv[0]); } } if (!bfind) usage(argv[0]); // モジュールロード void *hModule = dlopen(bon, RTLD_LAZY); if (!hModule) { fprintf(stderr, "dlopen error: %s\n", dlerror()); return -1; } // 出力先指定無しなら標準出力へ if (!ofind) wfd = 1; else { wfd = open(output, O_CREAT|O_RDWR, S_IRUSR|S_IWUSR); if (wfd < 0) { perror("open"); dlclose(hModule); return -2; } } // インスタンス作成 IBonDriver *pIBon; IBonDriver2 *pIBon2; pIBon = pIBon2 = NULL; char *err; IBonDriver *(*f)() = (IBonDriver *(*)())dlsym(hModule, "CreateBonDriver"); if ((err = dlerror()) == NULL) { pIBon = f(); if (pIBon) pIBon2 = dynamic_cast<IBonDriver2 *>(pIBon); } else { fprintf(stderr, "dlsym error: %s\n", err); dlclose(hModule); close(wfd); return -2; } if (!pIBon || !pIBon2) { fprintf(stderr, "CreateBonDriver error: pIBon[%p] pIBon2[%p]\n", pIBon, pIBon2); dlclose(hModule); close(wfd); return -3; } // ここから実質のチューナオープン & TS取得処理 BOOL b = pIBon->OpenTuner(); if (!b) { fputs("OpenTuner error\n", stderr); pIBon->Release(); dlclose(hModule); close(wfd); return -3; } // チャンネル名列挙 std::vector<std::string> vChName; char buf[128]; LPCTSTR name; DWORD ch = 0; while (1) { name = pIBon2->EnumChannelName(dwSpace, ch++); if (name == NULL) break; RevConvert((char *)name, buf, sizeof(buf)); vChName.push_back(buf); } for (unsigned int i = 0; i < vChName.size(); i++) { fprintf(stderr, "[ %u : %s ] ", i, vChName[i].c_str()); if (i && (((i+1) % 3) == 0)) fputc('\n', stderr); } if ((vChName.size() % 3) != 0) fputc('\n', stderr); fputs("[ p : チャンネル一覧再表示 ] [ q : 終了 ]\n", stderr); // 停止シグナル用ハンドラ登録 struct sigaction sa; memset(&sa, 0, sizeof(sa)); sa.sa_handler = handler; // sa.sa_flags = SA_RESTART; sigemptyset(&sa.sa_mask); sigaction(SIGINT, &sa, NULL); sigaction(SIGTERM, &sa, NULL); // チャンネル選択ループ pthread_t hTsRead = 0; while (!bStop) { if (fgets(buf, sizeof(buf), stdin) == NULL) continue; if (buf[0] < '0' || buf[0] > '9') { if (buf[0] == 'q') { bStop = TRUE; break; } if (buf[0] == 'p') { for (unsigned int i = 0; i < vChName.size(); i++) { fprintf(stderr, "[ %u : %s ] ", i, vChName[i].c_str()); if (i && (((i+1) % 3) == 0)) fputc('\n', stderr); } if ((vChName.size() % 3) != 0) fputc('\n', stderr); fputs("[ p : チャンネル一覧再表示 ] [ q : 終了 ]\n", stderr); continue; } fprintf(stderr, "ch_no select error.\n"); continue; } dwChannel = strtoul(buf, NULL, 10); if (dwChannel < vChName.size()) { if (pIBon2->SetChannel(dwSpace, dwChannel) == TRUE) { if (!hTsRead) { if (pthread_create(&hTsRead, NULL, TsReader, pIBon)) { perror("pthread_create"); goto err; } } } else fprintf(stderr, "SetChannel(%u, %u) error.\n", dwSpace, dwChannel); } else fprintf(stderr, "ch_no select error.\n"); } pthread_join(hTsRead, NULL); err: if (ofind) close(wfd); // チューナクローズ pIBon->CloseTuner(); // インスタンス解放 & モジュールリリース pIBon->Release(); dlclose(hModule); return 0; }