Exemple #1
0
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;
}
Exemple #2
0
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;
}