mirror of https://github.com/tongzx/nt5src
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
674 lines
22 KiB
674 lines
22 KiB
//==========================================================================;
|
|
//
|
|
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
|
|
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
|
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
|
|
// PURPOSE.
|
|
//
|
|
// Copyright (C) Microsoft Corporation, 1992 - 1999 All Rights Reserved.
|
|
//
|
|
//--------------------------------------------------------------------------;
|
|
//
|
|
// chanlist.cpp Classes that keeps the channel list and country list
|
|
//
|
|
|
|
|
|
|
|
#include <streams.h> // quartz, includes windows
|
|
#include <measure.h> // performance measurement (MSR_)
|
|
#include <tchar.h>
|
|
|
|
#include "chanlist.h"
|
|
|
|
|
|
// -------------------------------------------------------------------------
|
|
// CChanList
|
|
// -------------------------------------------------------------------------
|
|
|
|
CChanList::CChanList(HRESULT *phr, long lCountry, long lFreqList, BOOL bIsCable, long TuningSpace)
|
|
: m_pList (NULL)
|
|
, m_pChannels (NULL)
|
|
, m_pChannelsAuto (NULL)
|
|
, m_lChannelCount (0)
|
|
, m_hGlobal (NULL)
|
|
, m_IsCable (bIsCable)
|
|
, m_lCountry (lCountry)
|
|
, m_lTuningSpace (TuningSpace)
|
|
, m_lFreqList (lFreqList)
|
|
, m_lMinTunerChannel (0)
|
|
, m_lMaxTunerChannel (0)
|
|
{
|
|
BOOL bFound = FALSE;
|
|
|
|
// Load the resource if not already loaded
|
|
|
|
if (m_pList == NULL) {
|
|
if (m_hRes = FindResource (g_hInst,
|
|
MAKEINTRESOURCE(lFreqList),
|
|
RT_RCDATA)) {
|
|
if (m_hGlobal = LoadResource (g_hInst, m_hRes)) {
|
|
m_pList = (long *) LockResource (m_hGlobal);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
ASSERT (m_pList != NULL);
|
|
if (m_pList == NULL)
|
|
{
|
|
*phr = HRESULT_FROM_WIN32(GetLastError());
|
|
|
|
return;
|
|
}
|
|
|
|
// Get the min and max channel numbers
|
|
m_ListHdr = * ((PCHANLISTHDR) m_pList);
|
|
|
|
// Create a pointer to the channels only
|
|
m_pChannels = (long *) ((BYTE *) m_pList + sizeof (CHANLISTHDR));
|
|
|
|
// Sanity check
|
|
m_lChannelCount = m_ListHdr.MaxChannel - m_ListHdr.MinChannel + 1;
|
|
ASSERT (m_lChannelCount > 0 && m_lChannelCount < 1000);
|
|
|
|
// Create a parallel list for the corrected frequencies from the registry
|
|
m_pChannelsAuto = new long [m_lChannelCount];
|
|
if (m_pChannelsAuto == NULL)
|
|
{
|
|
*phr = E_OUTOFMEMORY;
|
|
|
|
return;
|
|
}
|
|
|
|
// And set the list to the unitialized state
|
|
ZeroMemory (m_pChannelsAuto, sizeof(long) * m_lChannelCount);
|
|
|
|
// Finally, try to get the corrected frequencies from the Registry
|
|
ReadListFromRegistry (m_lTuningSpace);
|
|
|
|
}
|
|
|
|
CChanList::~CChanList()
|
|
{
|
|
// Win32 automatically frees the resources
|
|
|
|
m_hRes = NULL;
|
|
m_hGlobal = NULL;
|
|
m_pList = NULL;
|
|
|
|
delete [] m_pChannelsAuto; m_pChannelsAuto = NULL;
|
|
}
|
|
|
|
// Return TRUE if the default frequency is being returned
|
|
// Else, a fine-tune frequency is being returned, return FALSE.
|
|
//
|
|
// Note: Some channel lists contain a gap in the numbering. In this case,
|
|
// the returned frequency will be zero, and the method returns TRUE.
|
|
|
|
|
|
BOOL
|
|
CChanList::GetFrequency(long nChannel, long * pFrequency, BOOL fForceDefault)
|
|
{
|
|
// validate channel against legal range
|
|
if (nChannel < m_ListHdr.MinChannel || nChannel > m_ListHdr.MaxChannel)
|
|
{
|
|
*pFrequency = 0;
|
|
return TRUE;
|
|
}
|
|
|
|
if (!fForceDefault)
|
|
{
|
|
*pFrequency = *(m_pChannelsAuto + nChannel - m_ListHdr.MinChannel);
|
|
if (0 == *pFrequency)
|
|
{
|
|
*pFrequency = *(m_pChannels + nChannel - m_ListHdr.MinChannel);
|
|
fForceDefault = TRUE;
|
|
}
|
|
}
|
|
else
|
|
*pFrequency = *(m_pChannels + nChannel - m_ListHdr.MinChannel);
|
|
|
|
return fForceDefault;
|
|
}
|
|
|
|
BOOL
|
|
CChanList::SetAutoTuneFrequency(long nChannel, long Frequency)
|
|
{
|
|
if (nChannel < m_ListHdr.MinChannel || nChannel > m_ListHdr.MaxChannel)
|
|
return FALSE;
|
|
|
|
*(m_pChannelsAuto + nChannel - m_ListHdr.MinChannel) = Frequency;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
// Determine the min and max channels supported.
|
|
// This is then limited by the actual frequencies supported by the physical tuner.
|
|
|
|
void
|
|
CChanList::GetChannelMinMax(long *plChannelMin, long *plChannelMax,
|
|
long lTunerFreqMin, long lTunerFreqMax)
|
|
{
|
|
|
|
ASSERT (m_pChannels != NULL);
|
|
|
|
// Calc the actual channels supported by the physical tuner,
|
|
// this is only done the first time through
|
|
if (m_lMinTunerChannel == 0) {
|
|
long j;
|
|
|
|
// start at the bottom and work up
|
|
for (j = m_ListHdr.MinChannel; j <= m_ListHdr.MaxChannel; j++) {
|
|
if (m_pChannels[j - m_ListHdr.MinChannel] >= lTunerFreqMin) {
|
|
m_lMinTunerChannel = j;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// start at the top and work down
|
|
for (j = m_ListHdr.MaxChannel; j >= m_ListHdr.MinChannel; j--) {
|
|
m_lMaxTunerChannel = j;
|
|
if (m_pChannels[j - m_ListHdr.MinChannel] <= lTunerFreqMax) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
*plChannelMin = min (m_ListHdr.MinChannel, m_lMinTunerChannel);
|
|
*plChannelMax = min (m_ListHdr.MaxChannel, m_lMaxTunerChannel);
|
|
}
|
|
|
|
// Constants for the registry routines that follow
|
|
#define MAX_KEY_LEN 256
|
|
#define PROTECT_REGISTRY_ACCESS
|
|
#define CHANLIST_MUTEX_WAIT INFINITE
|
|
|
|
BOOL
|
|
CChanList::WriteListToRegistry(long lTuningSpace)
|
|
{
|
|
BOOL rc = FALSE;
|
|
|
|
DbgLog((LOG_TRACE, 2, TEXT("Entering WriteListToRegistry")));
|
|
|
|
#ifdef PROTECT_REGISTRY_ACCESS
|
|
HANDLE hMutex;
|
|
|
|
// Create (or open) the mutex that protects access to this part of the registry
|
|
hMutex = CreateMutex(NULL, FALSE, g_strRegAutoTuneName);
|
|
if (hMutex != NULL)
|
|
{
|
|
DbgLog((LOG_TRACE, 2, TEXT("Waiting for Mutex")));
|
|
// Wait for our turn
|
|
DWORD dwWait = WaitForSingleObject(hMutex, CHANLIST_MUTEX_WAIT);
|
|
if (WAIT_OBJECT_0 == dwWait)
|
|
{
|
|
#endif
|
|
HKEY hKeyTS;
|
|
long hr;
|
|
|
|
m_lTuningSpace = lTuningSpace;
|
|
|
|
// Open the hard-coded path (i.e. no path name computation necessary)
|
|
hr = RegCreateKeyEx(
|
|
HKEY_LOCAL_MACHINE,
|
|
g_strRegAutoTunePath,
|
|
0,
|
|
TEXT (""),
|
|
REG_OPTION_NON_VOLATILE,
|
|
KEY_ALL_ACCESS | KEY_EXECUTE,
|
|
NULL, // LPSECURITY_ATTRIBUTES
|
|
&hKeyTS,
|
|
NULL);
|
|
|
|
if (ERROR_SUCCESS == hr)
|
|
{
|
|
TCHAR szKeyText[MAX_KEY_LEN];
|
|
HKEY hKeyList;
|
|
|
|
// Now open the path specific to our TS and broadcast/cable designation
|
|
// The key consists of the prefix TS, the value of the TuningSpace,
|
|
// followed by "-1" if cable and "-0" if broadcast
|
|
wsprintf (szKeyText, TEXT("TS%d-%d"), lTuningSpace, m_IsCable);
|
|
|
|
#ifndef NOT_BACKWARD_COMPATIBLE
|
|
// We need to clean up old way of keeping fine-tuning info
|
|
DWORD dwType;
|
|
|
|
// Get the key type of the default value
|
|
hr = RegQueryValueEx(
|
|
hKeyTS, // handle of key to query
|
|
szKeyText, // default value
|
|
0, // reserved
|
|
&dwType, // address of buffer for value type
|
|
NULL,
|
|
NULL);
|
|
if (ERROR_SUCCESS == hr)
|
|
{
|
|
// Check if it has the old type
|
|
if (REG_BINARY == dwType)
|
|
{
|
|
DbgLog((LOG_TRACE, 2, TEXT("Detected old AutoTune format")));
|
|
|
|
// ... and clear its value
|
|
hr = RegDeleteValue(hKeyTS, szKeyText);
|
|
if (ERROR_SUCCESS != hr)
|
|
{
|
|
DbgLog((LOG_ERROR, 2, TEXT("Failed to clear old value of %s"), szKeyText));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DbgLog((LOG_ERROR, 2, TEXT("Unexpected type for %s"), szKeyText));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DbgLog((LOG_TRACE, 2, TEXT("Detected new AutoTune format")));
|
|
}
|
|
#endif
|
|
hr = RegCreateKeyEx(
|
|
hKeyTS,
|
|
szKeyText,
|
|
0,
|
|
TEXT(""),
|
|
REG_OPTION_NON_VOLATILE,
|
|
KEY_ALL_ACCESS | KEY_EXECUTE,
|
|
NULL, // LPSECURITY_ATTRIBUTES
|
|
&hKeyList,
|
|
NULL);
|
|
|
|
if (ERROR_SUCCESS == hr)
|
|
{
|
|
// Set/Create the value containing the fine-tuning list
|
|
hr = RegSetValueEx(
|
|
hKeyList,
|
|
g_strRegAutoTuneName,
|
|
0,
|
|
REG_BINARY,
|
|
(unsigned char *) m_pChannelsAuto,
|
|
m_lChannelCount * sizeof (DWORD));
|
|
|
|
if (ERROR_SUCCESS == hr)
|
|
rc = TRUE;
|
|
else
|
|
{
|
|
DbgLog((LOG_ERROR, 2, TEXT("Failed setting %s\\%s"),
|
|
szKeyText, g_strRegAutoTuneName
|
|
));
|
|
}
|
|
|
|
RegCloseKey(hKeyList);
|
|
}
|
|
|
|
RegCloseKey(hKeyTS);
|
|
}
|
|
else
|
|
{
|
|
DbgLog((LOG_ERROR, 2, TEXT("Failed creating/opening %s"), g_strRegAutoTunePath));
|
|
}
|
|
|
|
#ifdef PROTECT_REGISTRY_ACCESS
|
|
ReleaseMutex(hMutex);
|
|
}
|
|
else
|
|
{
|
|
DbgLog((LOG_ERROR, 2, TEXT("Failed waiting for mutex")));
|
|
}
|
|
|
|
CloseHandle(hMutex);
|
|
}
|
|
else
|
|
{
|
|
DbgLog((LOG_ERROR, 2, TEXT("Failed creating/opening mutex")));
|
|
}
|
|
#endif
|
|
|
|
DbgLog((LOG_TRACE, 2, TEXT("Leaving WriteListToRegistry, %s"),
|
|
rc ? TEXT("success") : TEXT("failure")
|
|
));
|
|
|
|
return rc;
|
|
}
|
|
|
|
BOOL
|
|
CChanList::ReadListFromRegistry(long lTuningSpace)
|
|
{
|
|
BOOL rc = FALSE;
|
|
|
|
DbgLog((LOG_TRACE, 2, TEXT("Entering ReadListFromRegistry")));
|
|
|
|
#ifdef PROTECT_REGISTRY_ACCESS
|
|
HANDLE hMutex;
|
|
|
|
// Create (or open) the mutex that protects access to this part of the registry
|
|
hMutex = CreateMutex(NULL, FALSE, g_strRegAutoTuneName);
|
|
if (hMutex != NULL)
|
|
{
|
|
DbgLog((LOG_TRACE, 2, TEXT("Waiting for Mutex")));
|
|
|
|
// Wait for our turn
|
|
DWORD dwWait = WaitForSingleObject(hMutex, CHANLIST_MUTEX_WAIT);
|
|
if (WAIT_OBJECT_0 == dwWait)
|
|
{
|
|
#endif
|
|
HKEY hKeyTS;
|
|
long hr;
|
|
|
|
m_lTuningSpace = lTuningSpace;
|
|
|
|
// Open the hard-coded path (i.e. no path name computation necessary)
|
|
hr = RegOpenKeyEx(
|
|
HKEY_LOCAL_MACHINE,
|
|
g_strRegAutoTunePath,
|
|
0,
|
|
KEY_READ,
|
|
&hKeyTS);
|
|
|
|
if (ERROR_SUCCESS == hr)
|
|
{
|
|
TCHAR szKeyText[MAX_KEY_LEN];
|
|
HKEY hKeyList;
|
|
|
|
// Now open the path specific to our TS and broadcast/cable designation
|
|
// The key consists of the prefix TS, the value of the TuningSpace,
|
|
// followed by "-1" if cable and "-0" if broadcast
|
|
wsprintf (szKeyText, TEXT("TS%d-%d"), lTuningSpace, m_IsCable);
|
|
|
|
// Try it as a key first (the new way to store fine-tuning)
|
|
hr = RegOpenKeyEx(
|
|
hKeyTS,
|
|
szKeyText,
|
|
0,
|
|
KEY_READ,
|
|
&hKeyList);
|
|
|
|
if (ERROR_SUCCESS == hr)
|
|
{
|
|
DbgLog((LOG_TRACE, 2, TEXT("Using new AutoTune format")));
|
|
|
|
TCHAR szName[MAX_KEY_LEN];
|
|
DWORD dwNameLength;
|
|
DWORD dwIndex, dwType;
|
|
DWORD dwSize = m_lChannelCount * sizeof (DWORD);
|
|
|
|
// First get the fine-tuning information
|
|
hr = RegQueryValueEx(
|
|
hKeyList, // handle of key to query
|
|
g_strRegAutoTuneName, // address of name of value to query
|
|
0, // reserved
|
|
0, // address of buffer for value type
|
|
(unsigned char *) m_pChannelsAuto, // address of data buffer
|
|
&dwSize); // address of data buffer size
|
|
|
|
if (ERROR_SUCCESS == hr)
|
|
rc = TRUE; // at least we got something
|
|
|
|
DbgLog((LOG_TRACE, 4, TEXT("Checking for frequency overrides")));
|
|
|
|
// Now check for frequency overrides
|
|
for (dwIndex = 0, hr = ERROR_SUCCESS; ERROR_SUCCESS == hr; dwIndex++)
|
|
{
|
|
// Initialize the size
|
|
dwNameLength = MAX_KEY_LEN;
|
|
|
|
// Get the next (or first) value
|
|
hr = RegEnumValue(
|
|
hKeyList,
|
|
dwIndex,
|
|
szName,
|
|
&dwNameLength,
|
|
NULL,
|
|
&dwType,
|
|
NULL,
|
|
NULL);
|
|
|
|
if (ERROR_SUCCESS == hr)
|
|
{
|
|
LPTSTR pszNext;
|
|
long nChannel;
|
|
|
|
// Try to convert the key name to a channel number
|
|
nChannel = _tcstol(szName, &pszNext, 10);
|
|
if (!*pszNext) // must be '\0' or we skip it
|
|
{
|
|
// See if the value is a DWORD
|
|
if (REG_DWORD == dwType)
|
|
{
|
|
DWORD Frequency, dwSize = sizeof(DWORD);
|
|
|
|
// Get the frequency override
|
|
hr = RegQueryValueEx(
|
|
hKeyList, // handle of key to query
|
|
szName, // address of name of value to query
|
|
0, // reserved
|
|
0, // address of buffer for value type
|
|
(BYTE *)&Frequency, // address of data buffer
|
|
&dwSize); // address of data buffer size
|
|
|
|
if (ERROR_SUCCESS == hr)
|
|
{
|
|
DbgLog((LOG_TRACE, 4, TEXT("Override, channel %d - frequency %d"),
|
|
nChannel, Frequency
|
|
));
|
|
|
|
if (!SetAutoTuneFrequency(nChannel, Frequency))
|
|
{
|
|
DbgLog((LOG_ERROR, 4, TEXT("Override failed, channel %d"),
|
|
nChannel
|
|
));
|
|
}
|
|
else
|
|
rc = TRUE; // at least we got something
|
|
}
|
|
else
|
|
{
|
|
DbgLog((LOG_ERROR, 4, TEXT("Cannot get value of key %s"),
|
|
szName
|
|
));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DbgLog((LOG_TRACE, 4, TEXT("Type of value for key %s not DWORD"),
|
|
szName
|
|
));
|
|
}
|
|
|
|
hr = ERROR_SUCCESS;
|
|
}
|
|
else
|
|
{
|
|
DbgLog((LOG_TRACE, 4, TEXT("Skipping \"%s\" value"),
|
|
szName
|
|
));
|
|
}
|
|
} // key enumeration
|
|
#if 0
|
|
else
|
|
{
|
|
if (ERROR_NO_MORE_ITEMS != hr)
|
|
{
|
|
LPVOID lpMsgBuf;
|
|
FormatMessage(
|
|
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
|
FORMAT_MESSAGE_FROM_SYSTEM |
|
|
FORMAT_MESSAGE_IGNORE_INSERTS,
|
|
NULL,
|
|
GetLastError(),
|
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
|
|
(LPTSTR) &lpMsgBuf,
|
|
0,
|
|
NULL
|
|
);
|
|
DbgLog((LOG_ERROR, 4, (LPCTSTR)lpMsgBuf));
|
|
// Free the buffer.
|
|
LocalFree( lpMsgBuf );
|
|
}
|
|
else if (0 == dwIndex)
|
|
{
|
|
DbgLog((LOG_TRACE, 4, TEXT("No values?@!")));
|
|
}
|
|
}
|
|
#endif
|
|
} // loop
|
|
|
|
RegCloseKey(hKeyList); // clean this up since we've clobbered hr
|
|
}
|
|
#ifndef NOT_BACKWARD_COMPATIBLE
|
|
else
|
|
{
|
|
DWORD dwSize = m_lChannelCount * sizeof (DWORD);
|
|
|
|
// Try getting the fine-tuning information the old way
|
|
hr = RegQueryValueEx(
|
|
hKeyTS, // handle of key to query
|
|
szKeyText, // address of name of value to query
|
|
0, // reserved
|
|
0, // address of buffer for value type
|
|
(unsigned char *)m_pChannelsAuto, // address of data buffer
|
|
&dwSize); // address of data buffer size
|
|
|
|
if (ERROR_SUCCESS == hr)
|
|
{
|
|
DbgLog((LOG_TRACE, 2, TEXT("Using old AutoTune format")));
|
|
|
|
rc = TRUE;
|
|
}
|
|
else
|
|
{
|
|
DbgLog((LOG_ERROR, 2, TEXT("Failed getting %s"),
|
|
szKeyText
|
|
));
|
|
}
|
|
}
|
|
#endif
|
|
|
|
RegCloseKey(hKeyTS);
|
|
}
|
|
else
|
|
{
|
|
DbgLog((LOG_ERROR, 2, TEXT("Failed opening %s"), g_strRegAutoTunePath));
|
|
}
|
|
|
|
#ifdef PROTECT_REGISTRY_ACCESS
|
|
ReleaseMutex(hMutex);
|
|
}
|
|
else
|
|
{
|
|
DbgLog((LOG_ERROR, 2, TEXT("Failed waiting for mutex")));
|
|
}
|
|
|
|
CloseHandle(hMutex);
|
|
}
|
|
else
|
|
{
|
|
DbgLog((LOG_ERROR, 2, TEXT("Failed creating/opening mutex")));
|
|
}
|
|
#endif
|
|
|
|
DbgLog((LOG_TRACE, 2, TEXT("Leaving ReadListFromRegistry, %s"),
|
|
rc ? TEXT("success") : TEXT("failure")
|
|
));
|
|
|
|
return rc;
|
|
}
|
|
|
|
// -------------------------------------------------------------------------
|
|
// CCountryList
|
|
// -------------------------------------------------------------------------
|
|
|
|
CCountryList::CCountryList()
|
|
: m_pList (NULL)
|
|
, m_hRes (NULL)
|
|
, m_hGlobal (NULL)
|
|
, m_LastCountry (-1)
|
|
, m_LastFreqListCable (-1)
|
|
, m_LastFreqListBroad (-1)
|
|
{
|
|
// Let's avoid creating a map until it is actually needed
|
|
}
|
|
|
|
CCountryList::~CCountryList()
|
|
{
|
|
// Win32 automatically frees the resources
|
|
|
|
m_hRes = NULL;
|
|
m_hGlobal = NULL;
|
|
m_pList = NULL;
|
|
}
|
|
|
|
|
|
// The country list is a table with four columns,
|
|
// column 1 = the long distance dialing code for the country
|
|
// column 2 = the cable frequency list
|
|
// column 3 = the broadcast frequency list
|
|
// column 4 = the analog video standard
|
|
|
|
BOOL
|
|
CCountryList::GetFrequenciesAndStandardFromCountry (
|
|
long lCountry,
|
|
long *plIndexCable,
|
|
long *plIndexBroad,
|
|
AnalogVideoStandard *plAnalogVideoStandard)
|
|
{
|
|
BOOL bFound = FALSE;
|
|
|
|
// Special case USA
|
|
|
|
if (lCountry == 1) {
|
|
*plIndexCable = F_USA_CABLE;
|
|
*plIndexBroad = F_USA_BROAD;
|
|
*plAnalogVideoStandard = AnalogVideo_NTSC_M;
|
|
return TRUE;
|
|
}
|
|
|
|
// Keeps a MRU list of one entry, see if it is the same
|
|
if (lCountry == m_LastCountry) {
|
|
*plIndexCable = m_LastFreqListCable;
|
|
*plIndexBroad = m_LastFreqListBroad;
|
|
*plAnalogVideoStandard = m_LastAnalogVideoStandard;
|
|
return TRUE;
|
|
}
|
|
|
|
// Load the resource if not already loaded
|
|
|
|
if (m_pList == NULL) {
|
|
if (m_hRes = FindResource (g_hInst,
|
|
MAKEINTRESOURCE (RCDATA_COUNTRYLIST),
|
|
RT_RCDATA)) {
|
|
if (m_hGlobal = LoadResource (g_hInst, m_hRes)) {
|
|
m_pList = (WORD *) LockResource (m_hGlobal);
|
|
}
|
|
}
|
|
}
|
|
|
|
ASSERT (m_pList != NULL);
|
|
|
|
if (m_pList == NULL) {
|
|
// Uh oh, must be out of memory.
|
|
// punt by returning the USA channel list
|
|
*plIndexCable = F_USA_CABLE;
|
|
*plIndexBroad = F_USA_BROAD;
|
|
*plAnalogVideoStandard = AnalogVideo_NTSC_M;
|
|
return FALSE;
|
|
}
|
|
|
|
PCOUNTRY_ENTRY pEntry = (PCOUNTRY_ENTRY) m_pList;
|
|
|
|
// A country code of Zero terminates the list!
|
|
while (pEntry->Country != 0) {
|
|
if (pEntry->Country == lCountry) {
|
|
bFound = TRUE;
|
|
m_LastCountry = lCountry;
|
|
*plIndexCable = m_LastFreqListCable = pEntry->IndexCable;
|
|
*plIndexBroad = m_LastFreqListBroad = pEntry->IndexBroadcast;
|
|
*plAnalogVideoStandard = m_LastAnalogVideoStandard =
|
|
(AnalogVideoStandard) pEntry->AnalogVideoStandard;
|
|
break;
|
|
}
|
|
pEntry++;
|
|
}
|
|
|
|
return bFound;
|
|
|
|
}
|