예제 #1
0
파일: Registry.cpp 프로젝트: huyiice/ConEmu
void SettingsXML::ClearChildrenTail(IXMLDOMNode* apNode, IXMLDOMNode* apFirstClear)
{
	HRESULT hr;
	IXMLDOMNode* pNext = NULL;
	IXMLDOMNode *pNodeRmv = NULL;
	DOMNodeType  nodeType = NODE_INVALID;

	#ifdef _DEBUG
	BSTR bsDebug = NULL;
	if (pNext)
	{
		pNext->get_nodeType(&nodeType);
		pNext->get_xml(&bsDebug);
	}
	if (bsDebug) ::SysFreeString(bsDebug); bsDebug = NULL;
	#endif

	while (((hr = apFirstClear->get_nextSibling(&pNext)) == S_OK) && pNext)
	{
		pNext->get_nodeType(&nodeType);

		#ifdef _DEBUG
		pNext->get_xml(&bsDebug);
		if (bsDebug) ::SysFreeString(bsDebug); bsDebug = NULL;
		#endif

		hr = apNode->removeChild(pNext, &pNodeRmv);
		if (SUCCEEDED(hr) && (nodeType != NODE_TEXT))
			SetDataChanged();

		SafeRelease(pNodeRmv);
		SafeRelease(pNext);
	}

	apFirstClear->get_nodeType(&nodeType);
	hr = apNode->removeChild(apFirstClear, &pNodeRmv);
	if (SUCCEEDED(hr) && (nodeType != NODE_TEXT))
		SetDataChanged();

	SafeRelease(pNodeRmv);
	SafeRelease(apFirstClear);
}
예제 #2
0
IXMLDOMNode *CXML::NextChildNode(IXMLDOMNode **ppNode)
{
	if(!(*ppNode))
		return NULL;

	IXMLDOMNode * pNode = NULL;
	IXMLDOMNodeList * pChildList = NULL;
	
	// Get the list of child nodes of the current node

	m_hr = (*ppNode)->get_childNodes(&pChildList);
	if (!SUCCEEDED(m_hr))
		return NULL;
	// loop through the childs
	DOMNodeType nodeType;
	while(true)
	{
		// Get the node type of each child, if it is of NODE_ELEMENT type set it as current node
		m_hr = pChildList->nextNode(&pNode);
		if(!SUCCEEDED(m_hr))
		{
			pChildList->Release();
			return NULL;
		}
		if(!pNode) break;
		m_hr = pNode->get_nodeType(&nodeType);
		if(!SUCCEEDED(m_hr))
		{
			pChildList->Release();
			pNode->Release();
			return NULL;
		}

		if(nodeType == NODE_ELEMENT)
			break;
		if(pNode)
			pNode->Release();
	}

	if(pChildList)
		pChildList->Release();

	return pNode;
}
예제 #3
0
int DicomImageSet::insertFileItem(IXMLDOMDocument *pDom, IXMLDOMNode * pRoot, const QString &folderName, const QString &fileName)
{
	DicomImage * dicomImage = new DicomImage ();
	if (!dicomImage->readHeader((QDir(folderName).absoluteFilePath(fileName)).toStdString().c_str()))
	{
		//fail to resolve header information
		return 0;
	}
	int nElement;

	char * patientsName = dicomImage->getCharTag(DicomImage::TAG_PATIENTS_NAME, nElement);
	char * patientsId = dicomImage->getCharTag(DicomImage::TAG_PATIENT_ID, nElement);
	char * protocolName = dicomImage->getCharTag(DicomImage::TAG_PROTOCOL_NAME, nElement);
	double * pInstanceNumber = dicomImage->getNumericTag(DicomImage::TAG_INSTANCE_NUMBER, nElement);
	double * pAcquisitionNumber = dicomImage->getNumericTag(DicomImage::TAG_ACQUISITION_NUMBER, nElement);
	double * pAcquisitionDate = dicomImage->getNumericTag(DicomImage::TAG_ACQUISITION_DATE, nElement);
	int instanceNumber = pInstanceNumber?(int)pInstanceNumber[0]:-1;
	int acquisitionNumber = pAcquisitionNumber?(int)pAcquisitionNumber[0]:-1;
	int acquisitionDate = pAcquisitionDate?(int)pAcquisitionDate[0]:0;

	IXMLDOMNode * pParent = findParentNode(pDom, pRoot, patientsName, patientsId, acquisitionDate, protocolName, acquisitionNumber);

	if (!pParent)
	{
		return 0;
	}

	HRESULT hr = S_OK;
    IXMLDOMElement *pNode = NULL;
    CHK_HR(CreateElement(pDom, L"File", &pNode));
	CHK_HR(CreateAndAddAttributeNode(pDom, L"path", fileName.toStdWString().c_str(), pNode));
	CHK_HR(CreateAndAddAttributeNode(pDom, L"instance_number", QString::number(instanceNumber).toStdWString().c_str(), pNode));

	IXMLDOMNode * pSibling = NULL;
	CHK_HR(pParent->get_firstChild(&pSibling));
	int sibInstanceNumber = -1;
	VARIANT varInstanceNumber;
	DOMNodeType nodeType;
	while (pSibling && instanceNumber >= sibInstanceNumber)
	{
		CHK_HR(pSibling->get_nodeType(&nodeType));
		if(nodeType == NODE_ELEMENT)
		{
			CHK_HR(GetAttributeFromNode(pSibling, L"instance_number", &varInstanceNumber));
			sibInstanceNumber = QString::fromWCharArray(_bstr_t(varInstanceNumber)).toInt();
			if (instanceNumber < sibInstanceNumber)
			{
				break;
			}
		}
		IXMLDOMNode * tmpNode = NULL;
		CHK_HR(pSibling->get_nextSibling(&tmpNode));
		SAFE_RELEASE(pSibling);
		pSibling = tmpNode;
	}
	if (pSibling)
	{
		IXMLDOMNode * tmpNode = NULL;
		CHK_HR(pSibling->get_previousSibling(&tmpNode));
		SAFE_RELEASE(pSibling);
		pSibling = tmpNode;
	}
    CHK_HR(CreateAndAddTextNodeBefore(pDom, L"\n", pParent, pSibling));
    CHK_HR(InsertChildToParent(pNode, pSibling, pParent));

CleanUp:
    SAFE_RELEASE(pNode);

	return 1;
}
예제 #4
0
int DicomImageSet::readDatasetFile(const QString &datasetFileName, QTreeWidget *treeWidget)
{
    HRESULT hr = S_OK;
    IXMLDOMDocument *pXMLDom = NULL;
    IXMLDOMNodeList *pPatients = NULL;
    IXMLDOMNode *pPatient = NULL;
	DOMNodeType nodeType;
    VARIANT_BOOL varStatus;
    VARIANT varFileName;
	VARIANT varValue;
	BSTR bstrQuery;

    VariantInit(&varFileName);
    VariantInit(&varValue);

	QString queryPatient, queryDate, queryProtocol, queryCollection;

    CHK_HR(CreateAndInitDOM(&pXMLDom));

	CHK_HR(VariantFromString(datasetFileName.toStdWString().c_str(), varFileName));
    CHK_HR(pXMLDom->load(varFileName, &varStatus));
    if (varStatus != VARIANT_TRUE)
    {
        CHK_HR(ReportParseError(pXMLDom, "Failed to load DOM from stocks.xml."));
    }

	treeWidget->clear();
	treeWidget->setColumnCount(1);
	CHK_HR(pXMLDom->getElementsByTagName(L"Patient", &pPatients));
	if (pPatients)
	{
		long nPatients;
		CHK_HR(pPatients->get_length(&nPatients));
		for (long i=0; i<nPatients; ++i)
		{
			CHK_HR(pPatients->get_item(i, &pPatient));
			CHK_HR(GetAttributeFromNode(pPatient, L"patients_name", &varValue));
			queryPatient = QString::fromWCharArray(_bstr_t(varValue));
			QTreeWidgetItem * patientItem = new QTreeWidgetItem(treeWidget, QStringList(queryPatient));
			patientItem->setExpanded(true);

			IXMLDOMNodeList * pDates = NULL;
			CHK_HR(pPatient->get_childNodes(&pDates));
			long nDates;
			CHK_HR(pDates->get_length(&nDates));
			for (long j=0; j<nDates; ++j)
			{
				IXMLDOMNode * pDate = NULL;
				CHK_HR(pDates->get_item(j, &pDate));
				CHK_HR(pDate->get_nodeType(&nodeType));
				if(nodeType!=NODE_ELEMENT)
				{
					continue;
				}
				CHK_HR(GetAttributeFromNode(pDate, L"acquisition_date", &varValue));
				queryDate = QString::fromWCharArray(_bstr_t(varValue));
				int intDate = queryDate.toInt();
				QDate date = (QDate::fromString("1900-01-01", "yyyy-MM-dd")).addDays(intDate-693962);
				QTreeWidgetItem * dateItem = new QTreeWidgetItem(patientItem, QStringList(date.toString("yyyy-MM-dd")));
				dateItem->setExpanded(true);

				IXMLDOMNodeList * pProtocols = NULL;
				CHK_HR(pDate->get_childNodes(&pProtocols));
				long nProtocols;
				CHK_HR(pProtocols->get_length(&nProtocols));
				for (long j=0; j<nProtocols; ++j)
				{
					IXMLDOMNode * pProtocol = NULL;
					CHK_HR(pProtocols->get_item(j, &pProtocol));
					CHK_HR(pProtocol->get_nodeType(&nodeType));
					if(nodeType!=NODE_ELEMENT)
					{
						continue;
					}
					CHK_HR(GetAttributeFromNode(pProtocol, L"protocol_name", &varValue));
					queryProtocol = QString::fromWCharArray(_bstr_t(varValue));
					QTreeWidgetItem * protocolItem = new QTreeWidgetItem(dateItem, QStringList(queryProtocol));
					protocolItem->setExpanded(true);

					IXMLDOMNodeList * pCollections = NULL;
					CHK_HR(pProtocol->get_childNodes(&pCollections));
					long nCollections;
					CHK_HR(pCollections->get_length(&nCollections));
					for (long j=0; j<nCollections; ++j)
					{
						IXMLDOMNode * pCollection = NULL;
						CHK_HR(pCollections->get_item(j, &pCollection));
						CHK_HR(pCollection->get_nodeType(&nodeType));
						if(nodeType!=NODE_ELEMENT)
						{
							continue;
						}
						CHK_HR(GetAttributeFromNode(pCollection, L"acquisition_number", &varValue));
						queryCollection = QString::fromWCharArray(_bstr_t(varValue));
						QTreeWidgetItem * collectionItem = new QTreeWidgetItem(protocolItem);
						QString queryStr = QString("root/Patient[@patients_name = '%1']/Date[@acquisition_date = '%2']/Protocol[@protocol_name = '%3']/Collection[@acquisition_number = '%4']")
							.arg(queryPatient).arg(queryDate).arg(queryProtocol).arg(queryCollection);

						IXMLDOMElement * pDtiNode = NULL;
						bstrQuery = SysAllocString(QString(queryStr+"/DTI").toStdWString().c_str());
						CHK_ALLOC(bstrQuery);
						CHK_HR(pXMLDom->selectSingleNode(bstrQuery, (IXMLDOMNode**)&pDtiNode));
						SysFreeString(bstrQuery);
						if (pDtiNode)
						{
							collectionItem->setText(0,queryCollection+"*");
						} else
						{
							collectionItem->setText(0, queryCollection);
						}

						collectionItem->setData(0, Qt::UserRole, queryStr);
						collectionItem->setExpanded(true);


						protocolItem->addChild(collectionItem);
						SAFE_RELEASE(pCollection);
					}

					dateItem->addChild(protocolItem);
					SAFE_RELEASE(pProtocol);
				}

				patientItem->addChild(dateItem);
				SAFE_RELEASE(pDate);
			}
			treeWidget->insertTopLevelItem(i, patientItem);
			SAFE_RELEASE(pPatient);
		}
	}

CleanUp:
    SAFE_RELEASE(pXMLDom);
    SAFE_RELEASE(pPatients);
    SAFE_RELEASE(pPatient);
    VariantClear(&varFileName);

	return SUCCEEDED(hr);
}
예제 #5
0
/*
	Function name	: CXML::ReplaceNodeText
	Description	    : This Helper function replaces the existing text with the given text of 
					: the given node. 
	Return type		: bool 
	Argument        : IXMLDOMNode **pNode
	Argument        : CString &rcsNodeText
	Tested			: 
*/
bool CXML::ReplaceNodeText(IXMLDOMNode **pNode,CString &rcsNodeText)
{
	IXMLDOMText  * pTextNode = NULL;
	if(!(*pNode))
		return false;

	IXMLDOMNode * pTempNode = NULL;
	DOMNodeType nodeType;
	IXMLDOMNode * pINewNode = NULL;
	IXMLDOMNode * pIOldNode = NULL;
	IXMLDOMNodeList * pChildList = NULL;
	long nLen = 0,i=0;


	_bstr_t bstrData(rcsNodeText);

	m_hr = m_pXMLDoc->createTextNode(bstrData,&pTextNode);
	if(!SUCCEEDED(m_hr) || !pTextNode)
		goto on_Error;	


	m_hr = (*pNode)->get_childNodes(&pChildList);
	if(!SUCCEEDED(m_hr) || !pChildList)
		goto on_Error;
	
	m_hr = pChildList->get_length(&nLen);
	if(!SUCCEEDED(m_hr))
		goto on_Error;

	if(nLen == 0)	// no childs, if the tag is empty
	{
		bool bRet = CreateNodeText(pNode,rcsNodeText);
		if(pChildList)
			pChildList->Release();
		if(pTextNode)
			pTextNode->Release();
		return bRet;		
	}

	for(i =0; i< nLen;++i)
	{
		m_hr = pChildList->nextNode(&pTempNode);
		if(!SUCCEEDED(m_hr))
			goto on_Error;

		m_hr = pTempNode->get_nodeType(&nodeType);
		if(!SUCCEEDED(m_hr))
			goto on_Error;

		if(nodeType == NODE_TEXT)
			break;

		if(pTempNode)
		{
			pTempNode->Release();
			pTempNode = NULL;
		}
	}

	m_hr = (*pNode)->replaceChild(pTextNode,pTempNode,&pINewNode);
	if(!SUCCEEDED(m_hr) || !pINewNode)
			goto on_Error;

	if(pChildList)
		pChildList->Release();
	if(pTextNode)
		pTextNode->Release();
	if(pINewNode)
		pINewNode->Release();
	if(pTempNode)
		pTempNode->Release();

	return true;


on_Error:	// Release all the References

	if(pChildList)
		pChildList->Release();
	if(pTextNode)
		pTextNode->Release();
	if(pINewNode)
		pINewNode->Release();
	if(pTempNode)
		pTempNode->Release();
	
	return false; 
}
예제 #6
0
bool CXML::NextChildNode()
{
	if(!m_pICurrentNode)
		return false;

	IXMLDOMNode * pNode = NULL;
	IXMLDOMNode * pITempNode = m_pICurrentNode;
	pITempNode->AddRef();

	IXMLDOMNodeList * pChildList = NULL;
	
	// Get the list of child nodes of the current node

	m_hr = pITempNode->get_childNodes(&pChildList);
	pITempNode->Release();
	if (!SUCCEEDED(m_hr))
		return false;
	// loop through the childs
	DOMNodeType nodeType;
	while(true)
	{
		// Get the node type of each child, if it is of NODE_ELEMENT type set it as current node
		m_hr = pChildList->nextNode(&pNode);
		if(!SUCCEEDED(m_hr))
		{
			pChildList->Release();
			return false;
		}
		if(!pNode) break;
		m_hr = pNode->get_nodeType(&nodeType);
		if(!SUCCEEDED(m_hr))
		{
			pChildList->Release();
			pNode->Release();
			return false;
		}

		if(nodeType == NODE_ELEMENT)
			break;
		if(pNode)
			pNode->Release();
	}

	if(pChildList)
		pChildList->Release();

	if(pNode)
	{
		if(m_pICurrentNode)
		{
			m_pICurrentNode->Release();
			m_pICurrentNode = NULL;
		}

		m_pICurrentNode = pNode;
		m_pICurrentNode->AddRef();

		pNode->Release();
		return true;
	}
	return false;
	
}
예제 #7
0
파일: Registry.cpp 프로젝트: huyiice/ConEmu
bool SettingsXML::SetMultiLine(IXMLDOMNode* apNode, const wchar_t* asValue, long nAllLen)
{
	bool bRc = false;
	HRESULT hr;
	VARIANT_BOOL bHasChild = VARIANT_FALSE;
	DOMNodeType  nodeType = NODE_INVALID;
	BSTR bsNodeType = ::SysAllocString(L"line");
	VARIANT vtType; vtType.vt = VT_I4; vtType.lVal = NODE_ELEMENT;
	IXMLDOMNode* pNode = NULL;
	IXMLDOMNode* pNodeRmv = NULL;
	long nLen = 0;
	const wchar_t* psz = asValue;
	bool bNewNodeCreate = false;
	int iAddIndent = 1;
	bool bAddFirstNewLine = false;

	hr = apNode->get_firstChild(&pNode);
	if (pNode == NULL)
	{
		bAddFirstNewLine = true;
		iAddIndent = mi_Level + 1;
	}

	// Обновляем существующие
	while ((psz && *psz && nAllLen > 0) && (SUCCEEDED(hr) && pNode))
	{
		hr = pNode->get_nodeType(&nodeType);

		if (SUCCEEDED(hr) && (nodeType == NODE_ELEMENT))
		{
			if (!SetAttr(pNode, L"data", psz))
				goto wrap;

			nLen = _tcslen(psz)+1;
			psz += nLen;
			nAllLen -= nLen;
		}

		hr = pNode->get_nextSibling(&pNode);
	}

	// Добавляем что осталось
	while (psz && *psz && nAllLen > 0)
	{
		hr = mp_File->createNode(vtType, bsNodeType, L"", &pNode);

		if (FAILED(hr) || !pNode)
			goto wrap;

		if (!SetAttr(pNode, L"data", psz))
			goto wrap;

		if (bAddFirstNewLine)
		{
			AppendNewLine(apNode);
			bAddFirstNewLine = false;
		}
		AppendIndent(apNode, iAddIndent);

		hr = apNode->appendChild(pNode, &pNodeRmv);

		AppendNewLine(apNode);
		bNewNodeCreate = true;
		iAddIndent = mi_Level + 1;

		SafeRelease(pNode);
		SafeRelease(pNodeRmv);

		if (FAILED(hr))
			goto wrap;

		nLen = _tcslen(psz)+1;
		psz += nLen;
		nAllLen -= nLen;
	}

	// Очистить хвост (если элементов стало меньше)
	if (pNode)
	{
		ClearChildrenTail(apNode, pNode);
		AppendNewLine(apNode);
		bNewNodeCreate = true;
	}

	if (bNewNodeCreate)
	{
		AppendIndent(apNode, mi_Level);
	}

	bRc = true;
wrap:
	_ASSERTE(nAllLen <= 1);
	::SysFreeString(bsNodeType);
	return bRc;
}
예제 #8
0
파일: Registry.cpp 프로젝트: huyiice/ConEmu
IXMLDOMNode* SettingsXML::FindItem(IXMLDOMNode* apFrom, const wchar_t* asType, const wchar_t* asName, bool abAllowCreate)
{
	HRESULT hr = S_OK;
	IXMLDOMNodeList* pList = NULL;
	IXMLDOMNode* pChild = NULL;
	IXMLDOMNamedNodeMap* pAttrs = NULL;
	IXMLDOMAttribute *pIXMLDOMAttribute = NULL;
	IXMLDOMNode *pIXMLDOMNode = NULL;
	IXMLDOMNode *pName = NULL;
	BSTR bsText = NULL;
	BSTR bsCheck = NULL;
	DOMNodeType nodeTypeCheck = NODE_INVALID;
	BOOL lbEmpty = TRUE;
	int iLastIndent = 1;

	// Получить все дочерние элементы нужного типа
	if (apFrom == NULL)
	{
		hr = S_FALSE;
	}
	else
	{
		long lFound = 0;
		// key[@name="abc"], but it is case-sensitive, and may fails in theory
		bsText = lstrmerge(asType, L"[@name=\"", asName, L"\"]");
		hr = apFrom->selectNodes(bsText, &pList);
		if (SUCCEEDED(hr) && pList)
		{
			hr = pList->get_length(&lFound);
			if (FAILED(hr) || (lFound < 1))
			{
				SafeRelease(pList);
			}
		}
		SafeFree(bsText);
		// May be case-insensitive search will be succeeded?
		// However, it is very slow
		if (!pList)
		{
			bsText = ::SysAllocString(asType);
			hr = apFrom->selectNodes(bsText, &pList);
			::SysFreeString(bsText); bsText = NULL;
		}
	}

	if (SUCCEEDED(hr) && pList)
	{
		hr = pList->reset();

		while ((hr = pList->nextNode(&pIXMLDOMNode)) == S_OK && pIXMLDOMNode)
		{
			lbEmpty = FALSE;
			hr = pIXMLDOMNode->get_attributes(&pAttrs);

			if (SUCCEEDED(hr) && pAttrs)
			{
				bsText = GetAttr(pIXMLDOMNode, pAttrs, L"name");

				if (bsText)
				{
					if (lstrcmpi(bsText, asName) == 0)
					{
						::SysFreeString(bsText); bsText = NULL;
						pChild = pIXMLDOMNode; pIXMLDOMNode = NULL;
						break;
					}

					::SysFreeString(bsText); bsText = NULL;
				}
			}

			pIXMLDOMNode->Release(); pIXMLDOMNode = NULL;
		}

		pList->Release();
		//pList = NULL; -- для отладки
	}

	if (lbEmpty && abAllowCreate && (asType[0] == L'k'))
	{
		bsText = ::SysAllocString(L"value");
		hr = apFrom->selectNodes(bsText, &pList);
		::SysFreeString(bsText); bsText = NULL;
		if (SUCCEEDED(hr) && pList)
		{
			hr = pList->reset();
			if ((hr = pList->nextNode(&pIXMLDOMNode)) == S_OK && pIXMLDOMNode)
			{
				lbEmpty = FALSE;
				pIXMLDOMNode->Release(); pIXMLDOMNode = NULL;
			}
			pList->Release();
			//pList = NULL; -- для отладки
		}
	}

	if (!pChild && abAllowCreate)
	{
		if (asType[0] == L'k')
		{
			hr = apFrom->get_lastChild(&pChild);
			if (SUCCEEDED(hr) && pChild)
			{
				hr = pChild->get_nodeType(&nodeTypeCheck);
				if (SUCCEEDED(hr) && (nodeTypeCheck == NODE_TEXT))
				{
					hr = pChild->get_text(&bsCheck);
					if (SUCCEEDED(hr) && bsCheck)
					{
						iLastIndent = 0;
						LPCWSTR pszTabs = bsCheck;
						while (*pszTabs)
						{
							if (*(pszTabs++) == L'\t')
								iLastIndent++;
						}
						::SysFreeString(bsCheck); bsCheck = NULL;
					}
				}
			}
			SafeRelease(pChild);
		}

		VARIANT vtType; vtType.vt = VT_I4;
		vtType.lVal = NODE_ELEMENT;
		bsText = ::SysAllocString(asType);
		hr = mp_File->createNode(vtType, bsText, L"", &pChild);
		::SysFreeString(bsText); bsText = NULL;

		if (SUCCEEDED(hr) && pChild)
		{
			if (SetAttr(pChild, L"name", asName))
			{
				if (asType[0] == L'k')
				{
					AppendNewLine(pChild);
					mb_KeyEmpty = true;
					TouchKey(pChild);
				}

				if (asType[0] == L'k')
				{
					//if (mb_KeyEmpty)
					//AppendIndent(apFrom, lbEmpty ? (mi_Level-1) : mi_Level);
					AppendIndent(apFrom, (mi_Level-iLastIndent));
				}
				else if (mb_KeyEmpty)
				{
					AppendIndent(apFrom, !lbEmpty ? (mi_Level-1) : mi_Level);
				}
				else
				{
					AppendIndent(apFrom, 1);
				}
				hr = apFrom->appendChild(pChild, &pIXMLDOMNode);
				pChild->Release(); pChild = NULL;

				if (FAILED(hr))
				{
					pAttrs->Release(); pAttrs = NULL;
				}
				else
				{
					pChild = pIXMLDOMNode;
					pIXMLDOMNode = NULL;
				}

				AppendNewLine(apFrom);
				AppendIndent(apFrom, mi_Level-1);
				if ((asType[0] != L'k') && mb_KeyEmpty)
					mb_KeyEmpty = false;
			}
			else
			{
				pChild->Release(); pChild = NULL;
			}
		}
	}

	return pChild;
}
예제 #9
0
static HRESULT
ParseToolsList(IXMLDOMDocument* pXMLDom, BOOL bIsStandard)
{
    static const _bstr_t XMLFileTag(L"MSCONFIGTOOLFILE");
    static const _bstr_t XMLToolsTag(L"MSCONFIGTOOLS");

    HRESULT hr = S_OK;

    IXMLDOMNode    *pIterator = NULL, *pTmp = NULL;
    IXMLDOMElement* pEl       = NULL;
    DOMNodeType     type;
    _bstr_t         tagName;

    if (!pXMLDom)
        return E_POINTER; // E_INVALIDARG

    pXMLDom->get_documentElement(&pEl);

    pEl->get_tagName(&tagName.GetBSTR());
    _wcsupr(tagName);
    if (tagName == XMLFileTag)
    {
        pEl->get_firstChild(&pIterator); SAFE_RELEASE(pEl);
        while (pIterator)
        {
            pIterator->get_nodeType(&type);
            if (type == NODE_ELEMENT)
            {
                pIterator->QueryInterface(IID_PPV_ARG(IXMLDOMElement, &pEl) /* IID_PPV_ARGS(&pEl) */);

                pEl->get_tagName(&tagName.GetBSTR());
                _wcsupr(tagName);
                if (tagName == XMLToolsTag)
                {
                    pEl->get_firstChild(&pIterator); SAFE_RELEASE(pEl);
                    while (pIterator)
                    {
                        pIterator->QueryInterface(IID_PPV_ARG(IXMLDOMElement, &pEl) /* IID_PPV_ARGS(&pEl) */);
                        AddTool(pEl, bIsStandard);
                        SAFE_RELEASE(pEl);

                        pIterator->get_nextSibling(&pTmp);
                        SAFE_RELEASE(pIterator); pIterator = pTmp;
                    }
                    // SAFE_RELEASE(pIterator);

                    break;
                }

                SAFE_RELEASE(pEl);
            }

            pIterator->get_nextSibling(&pTmp);
            SAFE_RELEASE(pIterator); pIterator = pTmp;
        }
        // SAFE_RELEASE(pIterator);
    }
    else if (tagName == XMLToolsTag)
    {
        pEl->get_firstChild(&pIterator); SAFE_RELEASE(pEl);
        while (pIterator)
        {
            pIterator->QueryInterface(IID_PPV_ARG(IXMLDOMElement, &pEl) /* IID_PPV_ARGS(&pEl) */);
            AddTool(pEl, bIsStandard);
            SAFE_RELEASE(pEl);

            pIterator->get_nextSibling(&pTmp);
            SAFE_RELEASE(pIterator); pIterator = pTmp;
        }
        // SAFE_RELEASE(pIterator);
    }

    SAFE_RELEASE(pEl);

    return hr;
}
예제 #10
0
파일: Registry.cpp 프로젝트: mirror/conemu
//void SettingsXML::Save(const wchar_t *regName, const wchar_t *value)
//{
//	if (!value) value = L"";  // сюда мог придти и NULL
//
//	Save(regName, (LPCBYTE)value, REG_SZ, (_tcslen(value)+1)*sizeof(wchar_t));
//}
void SettingsXML::Save(const wchar_t *regName, LPCBYTE value, DWORD nType, DWORD nSize)
{
	HRESULT hr = S_OK;
	IXMLDOMNamedNodeMap* pAttrs = NULL;
	IXMLDOMNodeList* pList = NULL;
	IXMLDOMAttribute *pIXMLDOMAttribute = NULL;
	IXMLDOMNode *pNode = NULL;
	IXMLDOMNode* pChild = NULL;
	IXMLDOMNode *pNodeRmv = NULL;
	BSTR bsValue = NULL;
	BSTR bsType = NULL;
	bool bNeedSetType = false;
	// nType:
	// REG_DWORD:    сохранение числа в 16-ричном или 10-чном формате, в зависимости от того, что сейчас указано в xml ("dword"/"ulong"/"long")
	// REG_BINARY:   строго в hex (FF,FF,...)
	// REG_SZ:       ASCIIZ строка, можно проконтролировать, чтобы nSize/2 не был меньше длины строки
	// REG_MULTI_SZ: ASCIIZZ. При формировании <list...> нужно убедиться, что мы не вылезли за пределы nSize
	pChild = FindItem(mp_Key, L"value", regName, true); // создать, если его еще нету

	if (!pChild)
		goto wrap;

	hr = pChild->get_attributes(&pAttrs);

	if (FAILED(hr) || !pAttrs)
		goto wrap;

	bsType = GetAttr(pChild, pAttrs, L"type");

	switch(nType)
	{
		case REG_DWORD:
		{
			wchar_t szValue[32];

			if (bsType && (bsType[0] == L'u' || bsType[0] == L'U'))
			{
				_wsprintf(szValue, SKIPLEN(countof(szValue)) L"%u", *(LPDWORD)value);
			}
			else if (bsType && (bsType[0] == L'l' || bsType[0] == L'L'))
			{
				_wsprintf(szValue, SKIPLEN(countof(szValue)) L"%i", *(int*)value);
			}
			else
			{
				_wsprintf(szValue, SKIPLEN(countof(szValue)) L"%08x", *(LPDWORD)value);

				if (bsType) ::SysFreeString(bsType);

				// нужно добавить/установить тип
				bsType = ::SysAllocString(L"dword"); bNeedSetType = true;
			}

			bsValue = ::SysAllocString(szValue);
		} break;
		case REG_BINARY:
		{
			if (nSize == 1 && bsType && (bsType[0] == L'u' || bsType[0] == L'U'))
			{
				wchar_t szValue[4];
				BYTE bt = *value;
				_wsprintf(szValue, SKIPLEN(countof(szValue)) L"%u", (DWORD)bt);
				bsValue = ::SysAllocString(szValue);
			}
			else if (nSize == 1 && bsType && (bsType[0] == L'l' || bsType[0] == L'L'))
			{
				wchar_t szValue[4];
				char bt = *value;
				_wsprintf(szValue, SKIPLEN(countof(szValue)) L"%i", (int)bt);
				bsValue = ::SysAllocString(szValue);
			}
			else
			{
				DWORD nLen = nSize*2 + (nSize-1); // по 2 символа на байт + ',' между ними
				bsValue = ::SysAllocStringLen(NULL, nLen);
				nLen ++; // Чтобы далее не добавлять WCHAR на '\0'
				wchar_t* psz = (wchar_t*)bsValue;
				LPCBYTE  ptr = value;

				while(nSize)
				{
					_wsprintf(psz, SKIPLEN(nLen-(psz-bsValue)) L"%02x", (DWORD)*ptr);
					ptr++; nSize--; psz+=2;

					if (nSize)
						*(psz++) = L',';
				}

				if (bsType && lstrcmp(bsType, L"hex"))
				{
					// Допустим только "hex"
					::SysFreeString(bsType); bsType = NULL;
				}

				if (!bsType)
				{
					// нужно добавить/установить тип
					bsType = ::SysAllocString(L"hex"); bNeedSetType = true;
				}
			}
		} break;
		case REG_SZ:
		{
			wchar_t* psz = (wchar_t*)value;
			bsValue = ::SysAllocString(psz);

			if (bsType && lstrcmp(bsType, L"string"))
			{
				// Допустим только "string"
				::SysFreeString(bsType); bsType = NULL;
			}

			if (!bsType)
			{
				// нужно добавить/установить тип
				bsType = ::SysAllocString(L"string"); bNeedSetType = true;
			}
		} break;
		case REG_MULTI_SZ:
		{
			if (bsType && lstrcmp(bsType, L"multi"))
			{
				// Допустим только "multi"
				::SysFreeString(bsType); bsType = NULL;
			}

			if (!bsType)
			{
				// нужно добавить/установить тип
				bsType = ::SysAllocString(L"multi"); bNeedSetType = true;
			}
		} break;
		default:
			goto wrap; // не поддерживается
	}

	if (bNeedSetType)
	{
		_ASSERTE(bsType!=NULL);
		SetAttr(pChild, pAttrs, L"type", bsType);
		::SysFreeString(bsType); bsType = NULL;
	}

	// Теперь собственно значение
	if (nType != REG_MULTI_SZ)
	{
		_ASSERTE(bsValue != NULL);
		SetAttr(pChild, pAttrs, L"data", bsValue);
		::SysFreeString(bsValue); bsValue = NULL;
	}
	else     // Тут нужно формировать список элементов <list>
	{
		VARIANT_BOOL bHasChild = VARIANT_FALSE;
		DOMNodeType  nodeType = NODE_INVALID;
		// Если ранее был параметр "data" - удалить его из списка атрибутов
		hr = pAttrs->getNamedItem(L"data", &pNode);

		if (SUCCEEDED(hr) && pNode)
		{
			hr = pChild->removeChild(pNode, &pNodeRmv);
			pNode->Release(); pNode = NULL;

			if (pNodeRmv) { pNodeRmv->Release(); pNodeRmv = NULL; }
		}

		//TODO: может оставить перевод строки?
		// Сначала почистим
#ifdef _DEBUG
		hr = pChild->get_nodeType(&nodeType);
#endif
		hr = pChild->hasChildNodes(&bHasChild);

		if (bHasChild)
		{
			while((hr = pChild->get_firstChild(&pNode)) == S_OK && pNode)
			{
				hr = pNode->get_nodeType(&nodeType);
#ifdef _DEBUG
				BSTR bsDebug = NULL;
				pNode->get_text(&bsDebug);

				if (bsDebug) ::SysFreeString(bsDebug); bsDebug = NULL;

#endif
				hr = pChild->removeChild(pNode, &pNodeRmv);

				if (pNodeRmv) { pNodeRmv->Release(); pNodeRmv = NULL; }

				pNode->Release(); pNode = NULL;
			}
		}

		// Теперь - добавляем список
		wchar_t* psz = (wchar_t*)value;
		BSTR bsNodeType = ::SysAllocString(L"line");
		VARIANT vtType; vtType.vt = VT_I4; vtType.lVal = NODE_ELEMENT;
		long nAllLen = nSize/2; // длина в wchar_t
		long nLen = 0;

		while(psz && *psz && nAllLen > 0)
		{
			hr = mp_File->createNode(vtType, bsNodeType, L"", &pNode);

			if (FAILED(hr) || !pNode)
				break;

			if (!SetAttr(pNode, L"data", psz))
				break;

			hr = pChild->appendChild(pNode, &pNodeRmv);
			pNode->Release(); pNode = NULL;

			if (pNodeRmv) { pNodeRmv->Release(); pNodeRmv = NULL; }

			if (FAILED(hr))
				break;

			nLen = _tcslen(psz)+1;
			psz += nLen;
			nAllLen -= nLen;
		}

		_ASSERTE(nAllLen <= 1);
	}

	mb_Modified = true;
wrap:

	if (pIXMLDOMAttribute) { pIXMLDOMAttribute->Release(); pIXMLDOMAttribute = NULL; }

	if (pNode) { pNode->Release(); pNode = NULL; }

	if (pNodeRmv) { pNodeRmv->Release(); pNodeRmv = NULL; }

	if (pChild) { pChild->Release(); pChild = NULL; }

	if (pAttrs) { pAttrs->Release(); pAttrs = NULL; }

	if (bsValue) { ::SysFreeString(bsValue); bsValue = NULL; }

	if (bsType) { ::SysFreeString(bsType); bsType = NULL; }
}