xmlconfig.cpp

来自「symbian 下的helix player源代码」· C++ 代码 · 共 2,482 行 · 第 1/4 页

CPP
2,482
字号
		    {
			curr_level.AddLevel(name);
			_RemovePropFromList(pNewList, name);
			/*
			 * Here we need to try to set that value.
			 */
			_ResetProp(&curr_level, value, m_pRegistry);
			curr_level.RemoveLevel();
		    }
		}
		else
		{
		    // An End Tag

		    /*
		     * Here we need to try to delete everything that
		     * was not in the file.
		     */
		    if(strcasecmp(tag->m_name, "list") == 0)
		    {
			_HandlePropsRemovedFromFile(
			    &curr_level, pNewList,
			    m_pRegistry);
			curr_level.RemoveLevel();
			delete pNewList;
			pNewList = (CHXSimpleList*)levlist.RemoveHead();
		    }
		}
		break;
	    }
	}
    }
    
    _HandlePropsRemovedFromFile(&curr_level, pNewList, m_pRegistry);

    // cleanup
    if (fp) fclose(fp);
    HX_DELETE(tag);
    HX_DELETE(pNewList);
    HX_VECTOR_DELETE(pBuf);

    // send reconfig response
    m_ActiveSetsOutstanding--;
    MaybeSendReconfigResponse();

    return hResult;
}

#ifdef _WIN32
HX_RESULT
XMLConfig::ReconfigureFromReg(const char* pKeyname)
{
    HX_ASSERT(pKeyname && strlen(pKeyname));

    /* 
     * This should be a duplication of the above loop just using
     * the registry instead of a file.
     */

    /*
     * Pretend that there is one outstanding just to keep
     * the done methods from getting called, seeing a 0,
     * and sending the response until the end of this 
     * func.
     */
    m_ActiveSetsOutstanding++;

    CHXSimpleList levlist;
    CHXSimpleList indexlist;
    int curr_index = 0;
    UINT32 ulBufLen = 512;
    UINT32 ulRealBufLen = 512;
    char* pRegBuf = new char[512];

    UINT32 ulBufLen2 = 256;
    UINT32 ulRealBufLen2 = 256;
    char* pRegBuf2 = new char[256];

    UINT32 ulBufLen3 = 256;
    UINT32 ulRealBufLen3 = 256;
    char* pRegBuf3 = new char[256];
    FILETIME msbs;
    /*
     *  Add for level 0.
     */
    CHXSimpleList* pNewList = new CHXSimpleList;
    IHXValues* pValues = 0;

    _AddPropsToList(pNewList, "Config", m_pRegistry);
    XMLConfigString curr_level;
    curr_level.AddLevel("Config");

    char* pRegBase = new char[512];
    memset(pRegBase, 0, 512);
    SafeSprintf(pRegBase, 512, "Software\\RealNetworks\\%s\\%d.%d\\",
            m_szServerversion, m_ulMajor, m_ulMinor);
    UINT32 ulRegBase = strlen(pRegBase) + 1;

    HKEY hKey=0;
    LONG ret=0;
    BOOL bDone = 0;
    char* pc=0;
    /*
     * While we are not done...
     */
    while (!bDone)
    {
	pc = pRegBase + ulRegBase;
	SafeStrCpy(pc, curr_level.CharStar(), 512-ulRegBase);
	while (pc < pRegBase + 512 && *pc)
	{
	    if (*pc == '.')
	    {
		*pc = '\\';
	    }
	    pc++;
	}
	ret = RegOpenKeyEx(HKEY_CLASSES_ROOT, pRegBase, 0, KEY_READ, &hKey);
	if (ret != ERROR_SUCCESS)
	{
	    //XXXPM fix this
	    HX_ASSERT(0);
	}

	ulBufLen = ulRealBufLen;
	//XXXPM handle buffer too small
	ret = RegEnumKeyEx(hKey, curr_index,
	    pRegBuf, &ulBufLen, 0, NULL, NULL, &msbs);
	curr_index++;
	/*
	 * If it is a composite...
	 */
	if (ret == ERROR_SUCCESS)
	{
	    const char* name = pRegBuf;
	    _RemovePropFromList(pNewList, name);
	    curr_level.AddLevel(name);
	    levlist.AddHead((void*)pNewList);
	    indexlist.AddHead((void*)curr_index);
	    curr_index = 0;
	    pNewList = new CHXSimpleList;
	    _AddPropsToList(pNewList, curr_level.CharStar(), m_pRegistry);
	}
	/*
	 * It is a non composite value, so we need to get that value.
	 */
	else
	{
	    const char* name = pRegBuf;
	    const char* value = 0;
	    ulBufLen2 = ulRealBufLen2;
	    ulBufLen3 = ulRealBufLen3;
	    DWORD dwType;
	    //XXXPM handle buffer too small

	    ret = RegEnumValue(hKey, 0, pRegBuf2, &ulBufLen2, 0, &dwType, 
		               (unsigned char*)pRegBuf3, &ulBufLen3);
	    if (ret == ERROR_SUCCESS)
	    {
		value = pRegBuf3;
		_ResetProp(&curr_level, value, m_pRegistry);
		curr_level.RemoveLevel();
		delete pNewList;
		pNewList = (CHXSimpleList*)levlist.RemoveHead();
		curr_index = (int)indexlist.RemoveHead();
	    }
	    else
	    {
		/*
		 * Closing a composite.
		 */
		_HandlePropsRemovedFromFile(&curr_level, pNewList, m_pRegistry);
		curr_level.RemoveLevel();
		delete pNewList;
		if (!levlist.IsEmpty())
		{
		    pNewList = (CHXSimpleList*)levlist.RemoveHead();
		    curr_index = (int)indexlist.RemoveHead();
		}
		else
		{
		    pNewList = 0;
		    bDone = 1;
		}
	    }
	}
	RegCloseKey(hKey);

    }

    delete[] pRegBase;
    delete[] pRegBuf;
    delete[] pRegBuf2;
    delete[] pRegBuf3;

    m_ActiveSetsOutstanding--;
    MaybeSendReconfigResponse();

    return HXR_OK;
}
#endif

HX_RESULT
XMLConfig::_ResetProp(XMLConfigString* plevel, const char* value, IHXRegistry2* preg)
{
    HX_RESULT res = HXR_FAIL;
    IHXActiveRegistry* pActiveReg = 0;
    LONG32 ulCurrent;
    LONG32 ulNew;
    preg->QueryInterface(IID_IHXActiveRegistry,
	(void**)&pActiveReg);
    if (pActiveReg == 0)
    {
	return HXR_FAIL;
    }

    /*
     * If the prop exists, then figure out the type.
     */
    if (_PropExists(plevel, preg))
    {
	HXPropType type;
	type = preg->GetTypeByName(plevel->CharStar());
	switch (type)
	{
	case PT_INTEGER:
	    ulCurrent = 0;
	    ulNew = atoi(value);

	    /*
	     * If it is an int and we are not changing its value, then say ok and
	     * exit.
	     */
	    preg->GetIntByName(plevel->CharStar(),
		ulCurrent);
	    if (ulCurrent == ulNew)
	    {
		res = HXR_OK;
		goto done;
	    }

	    /*
	     * Try to set it by hand first.
	     */
	    res = preg->SetIntByName(plevel->CharStar(),
		atoi(value));

	    /*
	     * If it failed because it was active, then use the active reg
	     * to set it and add it to our outstanding actives count.
	     */
	    if (res == HXR_PROP_ACTIVE)
	    {
		m_ActiveSetsOutstanding ++;
		res = pActiveReg->SetActiveInt(plevel->CharStar(),
			    ulNew, this);
		if (res != HXR_OK)
		{
		    m_ActiveSetsOutstanding --;
		}
	    }
	    /*
	     * res should be set for good by now.
	     */
	    goto done;
	    
	case PT_STRING:
	    IHXBuffer* pCurrent = 0;

	    /*
	     * See if we are changing this string value at all.
	     */
	    preg->GetStrByName(plevel->CharStar(),
		pCurrent);
	    if (pCurrent)
	    {
		/*
		 * If we are not changing it at all then say ok and exit.
		 */
		if (!strcmp((const char*)pCurrent->GetBuffer(),
		    value))
		{
		    pCurrent->Release();
		    res = HXR_OK;
		    goto done;
		}
		pCurrent->Release();
	    }

	    /*
	     * We are changing it so get a new buffer and set it.
	     */
	    IHXBuffer* pBuffer = new CHXBuffer();
            pBuffer->AddRef();
	    pBuffer->Set((const unsigned char*)value, strlen(value) + 1);

	    res = preg->SetStrByName(plevel->CharStar(),
		pBuffer);

	    /*
	     * If we failed to set it because it is active, then use the
	     * active registry and add to our outstanding actives count.
	     */
	    if (res == HXR_PROP_ACTIVE)
	    {
		m_ActiveSetsOutstanding++;
		res = pActiveReg->SetActiveStr(plevel->CharStar(),
			    pBuffer, this);
		if (res != HXR_OK)
		{
		    m_ActiveSetsOutstanding --;
		}
	    }
	    pBuffer->Release();
	    goto done;

	}
	
    }
    else
    {
	/*
	 * This is the case where this prop was not already there,
	 * so figure out the type from the data.
	 */
	BOOL bIsNum = TRUE;
	const char* pc = value;
	while(*pc)
	{
	    if (*pc < '0' || *pc > '9')
	    {
		bIsNum = FALSE;
		break;
	    }
	    pc++;
	}
	if (pc == value)
	{
	    bIsNum = FALSE;
	}

	if (bIsNum)
	{
	    /*
	     * It should be an Integer type so attempt to Set it through the
	     * active reg.  (This acts like an add through the active reg.  Could
	     * have tried to add it by hand first, but didn't.
	     */
	    m_ActiveSetsOutstanding++;
	    res = pActiveReg->SetActiveInt(plevel->CharStar(),
		atoi(value), this);
	    if (res != HXR_OK)
	    {
		m_ActiveSetsOutstanding--;
	    }

	}
	else
	{
	    /*
	     * It should be a string type.  We will just try to do it through active.
	     * (see last comment).
	     */
	    IHXBuffer* pBuffer = new CHXBuffer();
            pBuffer->AddRef();
	    pBuffer->Set((const unsigned char*)value,
		strlen(value) + 1);
	    m_ActiveSetsOutstanding++;
	    res = pActiveReg->SetActiveStr(plevel->CharStar(),
		pBuffer, this);
	    if (res != HXR_OK)
	    {
		m_ActiveSetsOutstanding--;
	    }
	    pBuffer->Release();
	}
    }
done:;
    pActiveReg->Release();
    return res;
}

/************************************************************************
 * IHXActivePropUserResponse stuff.
 *
 * Called with status result on completion of set request.
 */
STDMETHODIMP
XMLConfig::SetActiveIntDone(HX_RESULT res,
				const char* pName,
				UINT32 ul,
				IHXBuffer* pInfo[],
				UINT32 ulNumInfo)
{
    m_ActiveSetsOutstanding--;
    MaybeSendReconfigResponse();
    return HXR_OK;
}

STDMETHODIMP
XMLConfig::SetActiveStrDone(HX_RESULT res,
				const char* pName,
				IHXBuffer* pBuffer,
				IHXBuffer* pInfo[],
				UINT32 ulNumInfo)
{
    m_ActiveSetsOutstanding--;
    MaybeSendReconfigResponse();
    return HXR_OK;
}

STDMETHODIMP
XMLConfig::SetActiveBufDone(HX_RESULT res,
				const char* pName,
				IHXBuffer* pBuffer,
				IHXBuffer* pInfo[],
				UINT32 ulNumInfo)
{
    m_ActiveSetsOutstanding--;
    MaybeSendReconfigResponse();
    return HXR_OK;
}

STDMETHODIMP
XMLConfig::DeleteActivePropDone(HX_RESULT res,
				const char* pName,
				IHXBuffer* pInfo[],
				UINT32 ulNumInfo)
{
    m_ActiveSetsOutstanding--;
    MaybeSendReconfigResponse();
    return HXR_OK;
}

void
XMLConfig::MaybeSendReconfigResponse()
{
    /*
     * If everything has not happened yet,
     * then bail.
     */
    if (m_ActiveSetsOutstanding)
    {
	return;
    }

    m_pReconfigureResponse->ReconfigServerDone(HXR_OK,
	0, 0);
    m_pReconfigureResponse->Release();
    m_pReconfigureResponse = 0;
}

void
XMLConfig::_HandlePropsRemovedFromFile(XMLConfigString* plevel,
				       CHXSimpleList* pList,
				       IHXRegistry2* preg)
{
    XMLPropInfo* pInfo;
    while (!pList->IsEmpty())
    {
	pInfo = (XMLPropInfo*)pList->RemoveHead();
	plevel->AddLevel(pInfo->m_pName);
	switch (pInfo->m_Type)
	{
	case PT_STRING:
	    {
		IHXBuffer* pval;
		pval = _GetDefaultValString(
		    plevel->CharStar(), preg);
		if (!pval)
		{
		    if (!preg->DeleteByName(
			plevel->CharStar()))
		    {
			IHXActiveRegistry* pActiveReg = 0;
			preg->QueryInterface(IID_IHXActiveRegistry,
			    (void**)&pActiveReg);
			if (pActiveReg)
			{
			    m_ActiveSetsOutstanding++;
			    if (HXR_OK != pActiveReg->DeleteActiveProp(
				plevel->CharStar(),
				this))
			    {
				m_ActiveSetsOutstanding--;
			    }
			    pActiveReg->Release();
			}
		    }
		}
		else
		{
		    if (HXR_PROP_ACTIVE == preg->SetStrByName(plevel->CharStar(),
			pval))
		    {
			IHXActiveRegistry* pActiveReg = 0;
			preg->QueryInterface(IID_IHXActiveRegistry,
			    (void**)&pActiveReg);
			if (pActiveReg)
			{
			    m_ActiveSetsOutstanding++;
			    if (HXR_OK != pActiveReg->SetActiveStr(
				plevel->CharStar(), pval,
				this))
			    {
				m_ActiveSetsOutstanding--;
			    }
			    pActiveReg->Release();
			}
		    }
		    pval->Release();
		}
	    }
	    break;

	case PT_INTEGER:
	    {
		INT32 i;
		if (!_GetDefaultValInt(
		    plevel->CharStar(),
		    &i, preg))
		{
		    if (!preg->DeleteByName(
			plevel->CharStar()))
		    {
			IHXActiveRegistry* pActiveReg = 0;
			preg->QueryInterface(IID_IHXActiveRegistry,
			    (void**)&pActiveReg);
			if (pActiveReg)
			{
			    m_ActiveSetsOutstanding++;
			    if (HXR_OK != pActiveReg->DeleteActiveProp(
				plevel->CharStar(),
				this))
			    {
				m_ActiveSetsOutstanding--;
			    }
			    pActiveReg->Release();
			}
		    }
		}
		else
		{
		    if (HXR_PROP_ACTIVE == preg->SetIntByName(plevel->CharStar(),
			i))
		    {
			IHXActiveRegistry* pActiveReg = 0;
			preg->QueryInterface(IID_IHXActiveRegistry,
			    (void**)&pActiveReg);
			if (pActiveReg)
			{
			    m_ActiveSetsOutstanding++;
			    if (HXR_OK != pActiveReg->SetActiveInt(
				plevel->CharStar(),
				i, this))
			    {
				m_ActiveSetsOutstanding--;
			    }
			    pActiveReg->Release();
			}
		    }
		}
	    }
	    break;

	case PT_COMPOSITE:
	    ///XXXPM there will be a bug here if we have default vars in sub lists and 
	    //we try and delete the list.  The default vals will not be found here.
	    IHXActiveRegistry* pActiveReg = 0;
	    preg->QueryInterface(IID_IHXActiveRegistry,
		(void**)&pActiveReg);
	    if (pActiveReg)
	    {
		m_ActiveSetsOutstanding++;
		HX_RESULT res;
		res = pActiveReg->DeleteActiveProp(plevel->CharStar(),
		    this);
		if (res != HXR_OK)
		{
		    m_ActiveSetsOutstanding--;
		}
		pActiveReg->Release();
	    }
	    break;

	}

	plevel->RemoveLevel();
	delete pInfo;
    }
	
}

IHXBuffer*
XMLConfig::_GetDefaultValString(const char* pProp,
				IHXRegistry2* preg)
{
    IHXBuffer* pBuffer = 0;
    char configdefaults[256]; /* Flawfinder: ignore */
    HX_ASSERT(strlen(pProp) < 220);
    SafeSprintf(configdefaults, 256, "configdefaults%s", strchr(pProp, '.'));
    preg->GetStrByName(configdefaults, pBuffer);
    return pBuffer;
}

int
XMLConfig::_GetDefaultValInt(const char* pProp, INT32* pOut,
			     IHXRegistry2* preg)
{
    char configdefaults[256]; /* Flawfinder: ignore */
    HX_ASSERT(strlen(pProp) < 220);
    SafeSprintf(configdefaults, 256, "configdefaults%s", strchr(pProp, '.'));
    if (HXR_OK != preg->GetIntByName(configdefaults, *pOut))
    {
	return 0;
    }
    return 1;
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?