#include "stdafx.h" #include #include #include #include #include #include #include #include "devenum.h" #include "initguid.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif class CDeviceLister2:public CDeviceLister{ IXMLDOMElementPtr nodeChips; IXMLDOMElementPtr nodeModels; IXMLDOMElementPtr nodeProjects; public: //std::map m_prjInfo; //std::map m_modelInfo; virtual ~CDeviceLister2(){} BOOL InitXMLDOMNodes(char * fileName); void EnumerateDevices(int ver); BOOL FindProjectInfo(char* ProjectName,int Apiver,char*CustomID,CardLoadInfo& cardLoadInfo); BOOL FindProjectInfo(char* ProjectName,int Apiver,CardLoadInfo& cardLoadInfo); }; CDeviceLister* CreateDeviceLister() { return new CDeviceLister2; } ////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////// ////////////////////XML Utils../////////////////////////////// ////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////// #define for_ChildNodeEnum(a,b) for(IXMLDOMElementPtr b=a->firstChild;b;b=b->nextSibling) DWORD GetAttrValueHex(IXMLDOMElementPtr node,char* attrName); DWORD GetAttrValueNum(IXMLDOMElementPtr node,char* attrName); BOOL GetAttrValueString(IXMLDOMElementPtr node,char* attrName,char * buffer); IXMLDOMNodePtr FindNamedFirstChild(IXMLDOMNodePtr nodeParent,BSTR findingName); BOOL ParseHWID(char * lpHWID, DWORD* ven,DWORD* dev,DWORD* subsys); DWORD GetAttrValueHex(IXMLDOMElementPtr node,char* attrName) { DWORD value=0; _variant_t v=node->getAttribute(attrName); if(v.vt!=VT_NULL){ sscanf((char*)_bstr_t(v),"%x",&value); } return value; } DWORD GetAttrValueNum(IXMLDOMElementPtr node,char* attrName) { #if 0 IXMLDOMNodePtr attr=node->attributes->getNamedItem(attrName); if(attr){ _variant_t value = attr->nodeValue; return (long)value; } return 0; #else _variant_t v=node->getAttribute(attrName); if(v.vt!=VT_NULL){ return (long)v; } return 0; #endif } BOOL GetAttrValueString(IXMLDOMElementPtr node,char* attrName,char * buffer) { #if 0 strcpy(buffer,(char*)(_bstr_t(node->getAttribute(attrName)))); return TRUE; #else _variant_t v=node->getAttribute(attrName); if(v.vt!=VT_NULL){ strcpy(buffer,(char*)(_bstr_t(node->getAttribute(attrName)))); return TRUE; } return FALSE; #endif } BOOL SetAttrValueHex(IXMLDOMElementPtr node,char* attrName,DWORD v) { char text[80]; sprintf(text,"%x",v); _variant_t value=text; node->setAttribute(attrName,value); return TRUE; } BOOL SetAttrValueNum(IXMLDOMElementPtr node,char* attrName,long v) { _variant_t value(v,VT_I4); node->setAttribute(attrName,value); return TRUE; } BOOL SetAttrValueString(IXMLDOMElementPtr node,char* attrName,LPCSTR buffer) { _variant_t value=buffer; node->setAttribute(attrName,value); return TRUE; } IXMLDOMNodePtr FindNamedFirstChild(IXMLDOMNodePtr nodeParent,BSTR findingName) { for(IXMLDOMNodePtr node = nodeParent->firstChild;node;node=node->nextSibling){ if(_wcsicmp(findingName, node->nodeName)==0){ return node; } } return NULL; } //ÇϳªÀÇ Ä¨¿¡ ÀÖ´Â dev id°¡ ´Ù¸¥ Ĩ¿¡ ÀÖ´Â dev id¿Í °°À» ¼ö ¾ø´Ù¶ó°í °¡Á¤ÇÑ´Ù. BOOL ParseHWID(char * lpHWID, DWORD* ven,DWORD* dev,DWORD* subsys) { if(strnicmp("PCI\\",lpHWID ,4)!=0)return FALSE; if ((strstr(lpHWID,"VEN_")==NULL) || (strstr(lpHWID,"DEV_")==NULL) || (strstr(lpHWID,"SUBSYS_")==NULL)) { return FALSE; } sscanf(strstr(lpHWID,"VEN_")+4,"%x",ven); sscanf(strstr(lpHWID,"DEV_")+4,"%x",dev); sscanf(strstr(lpHWID,"SUBSYS_")+7,"%x",subsys); return TRUE; } BOOL CDeviceLister2::FindProjectInfo(char* ProjectName,int Apiver,char*CustomID,CardLoadInfo& cardLoadInfo) { if(CustomID==NULL || CustomID[0]==0) return FindProjectInfo(ProjectName,Apiver,cardLoadInfo); IXMLDOMElementPtr Project;// = nodeProjects->getElementsByTagName(ProjectName)->item[0]; for_ChildNodeEnum(nodeProjects,nodeProject){ if(_wcsicmp(L"Category",nodeProject->nodeName)==0){ char name[80]; GetAttrValueString(nodeProject,"Name",name); if(stricmp(name,ProjectName)==0){ Project=nodeProject; break; } } } if(Project==NULL)return FALSE; IXMLDOMElementPtr Api ;//= Project->getElementsByTagName(APIName)->item[0]; for_ChildNodeEnum(Project,node2){ if(_wcsicmp(L"API",node2->nodeName)==0 && Apiver==GetAttrValueNum(node2,"Ver")){ Api=node2; break; } } if(Api==NULL)return FALSE; IXMLDOMElementPtr DefCardMng = Api->getElementsByTagName("DefaultCardManager")->item[0]; //Ä«µå¿¡ º¹¼öÀÇ DLLÀÌ ÀÖÀ» °æ¿ì °¢°¢ÀÇ dll¿¡ ´ëÇÑ ·çÇÁ.. if(DefCardMng){ GetAttrValueString(DefCardMng,"Name",cardLoadInfo.DefaultCardManger); } int count =0; for_ChildNodeEnum(Api,Dlls){ if(_wcsicmp(L"DLL",Dlls->nodeName)!=0 )continue; for_ChildNodeEnum(Dlls,Dll){ char temp[64]; GetAttrValueString(Dll,"CustomID",temp); if(stricmp(temp,CustomID)==0){ //We found it... char Func[16]; DWORD FuncFlag=0; GetAttrValueString(Dlls,"Function",Func); if(Func[0]=='V')FuncFlag|=FUNCTION_VIDEO; if(Func[1]=='A')FuncFlag|=FUNCTION_AUDIO; if(Func[2]=='R')FuncFlag|=FUNCTION_OVERAY; if(Func[3]=='C')FuncFlag|=FUNCTION_CODEC; cardLoadInfo.DLLs[count].dwSupportedFunctions=FuncFlag; GetAttrValueString(Dll,"DllName",cardLoadInfo.DLLs[count].DllName); count++; break; } } } cardLoadInfo.DllCount=count; return TRUE; } BOOL CDeviceLister2::FindProjectInfo(char* ProjectName,int Apiver,CardLoadInfo& cardLoadInfo) { IXMLDOMElementPtr Project;// = nodeProjects->getElementsByTagName(ProjectName)->item[0]; for_ChildNodeEnum(nodeProjects,nodeProject){ if(_wcsicmp(L"Category",nodeProject->nodeName)==0){ char name[80]; GetAttrValueString(nodeProject,"Name",name); if(stricmp(name,ProjectName)==0){ Project=nodeProject; break; } } } if(Project==NULL)return FALSE; IXMLDOMElementPtr Api ;//= Project->getElementsByTagName(APIName)->item[0]; for_ChildNodeEnum(Project,node2){ if(_wcsicmp(L"API",node2->nodeName)==0 && Apiver==GetAttrValueNum(node2,"Ver")){ Api=node2; break; } } if(Api==NULL)return FALSE; IXMLDOMElementPtr DefCardMng = Api->getElementsByTagName("DefaultCardManager")->item[0]; //Ä«µå¿¡ º¹¼öÀÇ DLLÀÌ ÀÖÀ» °æ¿ì °¢°¢ÀÇ dll¿¡ ´ëÇÑ ·çÇÁ.. if(DefCardMng){ GetAttrValueString(DefCardMng,"Name",cardLoadInfo.DefaultCardManger); } int count =0; for_ChildNodeEnum(Api,Dlls){ if(_wcsicmp(L"DLL",Dlls->nodeName)!=0 )continue; IXMLDOMElementPtr Dll=Dlls->getElementsByTagName("DLLEntity")->item[0]; if(Dll){ //We found it... char Func[16]; DWORD FuncFlag=0; GetAttrValueString(Dlls,"Function",Func); if(Func[0]=='V')FuncFlag|=FUNCTION_VIDEO; if(Func[1]=='A')FuncFlag|=FUNCTION_AUDIO; if(Func[2]=='R')FuncFlag|=FUNCTION_CODEC; if(Func[3]=='C')FuncFlag|=FUNCTION_OVERAY; cardLoadInfo.DLLs[count].dwSupportedFunctions=FuncFlag; GetAttrValueString(Dll,"DllName",cardLoadInfo.DLLs[count].DllName); count++; } } cardLoadInfo.DllCount=count; return TRUE; } BOOL FindChipName(IXMLDOMNodePtr nodeChips,DWORD ven,DWORD dev,char ChipName[]) { BOOL foundChip=FALSE; for_ChildNodeEnum(nodeChips,node){ //Chip Node¿¡ VendorID°¡ °°ÀºÁö °Ë»ç.. if(_wcsicmp(L"Chip",node->nodeName)!=0 || ven!=GetAttrValueHex(node,"VendorID"))continue; for_ChildNodeEnum(node,node2){ if(_wcsicmp(L"Dev",node2->nodeName)!=0 || dev!=GetAttrValueHex(node2,"ID"))continue; GetAttrValueString(node,"Name",ChipName); return TRUE; } } //ChipÀ» ¹ß°ßÇÏÁö ¸øÇßÀ¸¹Ç·Î ... return FALSE; } int FindModelInfo(IXMLDOMElementPtr nodeChips, IXMLDOMElementPtr nodeModels, char * lpHWID, char * serviceName, ModelInfo* modelInfos) { DWORD ven,dev,subsys; if (!ParseHWID(lpHWID,&ven,&dev,&subsys)) { return 0; } //ModelInfo modelInfoArray[8]; int modelCount=0; char ChipName[16]; if(!FindChipName(nodeChips,ven,dev,ChipName))return FALSE; for_ChildNodeEnum(nodeModels,nodeModel){ if(_wcsicmp(L"Model",nodeModel->nodeName)!=0)continue; //IXMLDOMNodePtr nodeChips=FindNamedFirstChild(nodeModel,L"Chips"); IXMLDOMNodePtr nodeChips = nodeModel->getElementsByTagName("Chips")->item[0]; if(nodeChips==NULL)continue; for_ChildNodeEnum(nodeChips,nodeChip){ char svcName[128]; if(GetAttrValueString(nodeChip,"Service",svcName)){ if(stricmp(svcName,serviceName)!=0) continue; } if(subsys==GetAttrValueHex(nodeChip,"SubSystemID") || subsys==0){ ModelInfo& modelInfo = modelInfos[modelCount++]; #if 0 lstrcpy(modelInfo.ModelName,(char*)(_bstr_t)nodeModel->getAttribute("Name")); lstrcpy(modelInfo.ProjectName,(char*)(_bstr_t)nodeModel->getAttribute("Category")); lstrcpy(modelInfo.CustomID,(char*)(_bstr_t)nodeModel->getAttribute("CustomID")); modelInfo.DefModelID= GetAttrValueHex(nodeModel,"DefModelID"); modelInfo.CapAudioModelID= GetAttrValueHex(nodeModel,"CapAudioModelID"); //modelInfo.ActivationCode; char buffer[128]; GetAttrValueString(nodeModel,"ActivationCode",buffer); #else GetAttrValueString(nodeModel,"Name",modelInfo.ModelName); GetAttrValueString(nodeModel,"Category",modelInfo.ProjectName); if(!GetAttrValueString(nodeModel,"CustomID",modelInfo.CustomID)){ modelInfo.CustomID[0]=0; } modelInfo.DefModelID= (WORD)GetAttrValueHex(nodeModel,"DefModelID"); modelInfo.CapAudioModelID= (WORD)GetAttrValueHex(nodeModel,"CapAudioModelID"); //modelInfo.ActivationCode; char buffer[128]; GetAttrValueString(nodeModel,"ActivationCode",buffer); #endif UINT a[16]; BYTE* b=modelInfo.ActivationCode; sscanf(buffer,"%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x", a+0,a+1,a+2,a+3,a+4,a+5,a+6,a+7,a+8,a+9,a+10,a+11,a+12,a+13,a+14,a+15); for(int i=0;i<16;i++){ b[i]=a[i]; } //printf(modelInfo.ModelName); //return TRUE; } } } return modelCount; } void CDeviceLister2::EnumerateDevices(int ver) { HDEVINFO devs = INVALID_HANDLE_VALUE; devs = SetupDiGetClassDevs(NULL,NULL,NULL,DIGCF_ALLCLASSES|DIGCF_PRESENT);// ,NULL,NULL,NULL); SP_DEVINFO_DATA devInfo; devInfo.cbSize = sizeof(devInfo); for(int devIndex=0;SetupDiEnumDeviceInfo(devs,devIndex,&devInfo);devIndex++) { DWORD dataType; DWORD reqSize; BYTE buffer[1024]; BYTE serviceName[128]; if(SetupDiGetDeviceRegistryProperty(devs,&devInfo,SPDRP_HARDWAREID,&dataType,(LPBYTE)buffer,1024,&reqSize)){ SetupDiGetDeviceRegistryProperty(devs,&devInfo,SPDRP_SERVICE,&dataType,(LPBYTE)serviceName,128,&reqSize); if(strnicmp("PCI\\",(char*)buffer ,4)==0){ ModelInfo modelInfos[8]; ZeroMemory(modelInfos,sizeof(modelInfos)); int matchCount=FindModelInfo(nodeChips,nodeModels,(char*)buffer,(char*)serviceName,modelInfos); if(matchCount>0){ for(int modelIdx=0;modelIdx m_prjInfo; // std::map m_modelInfo; if(m_modelInfo.find(modelInfo.ModelName)==m_modelInfo.end()){ m_modelInfo[modelInfo.ModelName]=modelInfo; } if(m_prjInfo.find(modelInfo.ProjectName)==m_prjInfo.end()){ CardLoadInfo cardLoadInfo={0,}; if(FindProjectInfo(modelInfo.ProjectName,ver,modelInfo.CustomID,cardLoadInfo)){ m_prjInfo[modelInfo.ProjectName]=cardLoadInfo; }else{ m_prjInfo.erase(modelInfo.ProjectName); } } } } } } } if(devs != INVALID_HANDLE_VALUE) { SetupDiDestroyDeviceInfoList(devs); } } BOOL CDeviceLister2::InitXMLDOMNodes(char * fileName) { try { IXMLDOMDocumentPtr docPtr; //init HRESULT hr=docPtr.CreateInstance("msxml2.domdocument"); if(FAILED(hr)){ MessageBox(NULL,"Can't Create XML DOM Object\n Install MSXML 3.0 or higher","Error",MB_OK); throw hr; } // load a document _variant_t varXml(fileName); _variant_t varOut((bool)TRUE); docPtr->async=FALSE; varOut = docPtr->load(varXml); if ((bool)varOut == FALSE)throw(0); #if 1 nodeChips = docPtr->documentElement->getElementsByTagName("Chips")->item[0]; nodeModels = docPtr->documentElement->getElementsByTagName("Models")->item[0]; nodeProjects = docPtr->documentElement->getElementsByTagName("Categorys")->item[0]; if(nodeChips==NULL || nodeModels==NULL || nodeProjects==NULL)throw(0); #else nodeChips = FindNamedFirstChild(docPtr->documentElement,L"Chips"); nodeModels= FindNamedFirstChild(docPtr->documentElement,L"Models"); nodeProjects= FindNamedFirstChild(docPtr->documentElement,L"Categorys"); #endif return TRUE; } catch(...) { //MessageBox(NULL, "Exception occurred","Error", MB_OK); return FALSE; } } /////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////// /* BOOL SetAttrValueHex(IXMLDOMElementPtr node,char* attrName,DWORD v) { char text[80]; sprintf(text,"%x",v); _variant_t value=text; node->setAttribute(attrName,value); return TRUE; } BOOL SetAttrValueNum(IXMLDOMElementPtr node,char* attrName,long v) { _variant_t value(v,VT_I4); node->setAttribute(attrName,value); return TRUE; } BOOL SetAttrValueString(IXMLDOMElementPtr node,char* attrName,LPCSTR buffer) { _variant_t value=buffer; node->setAttribute(attrName,value); return TRUE; } */ void OutputDebugStringF(char * format,...); DEFINE_GUID (IID_ISettingStorage, 0x5B1727D9,0x40F3,0x4d0e,0x99,0x97,0x93,0xAD,0xB3,0x99,0x94,0xB4); CSettingStorage::CSettingStorage():m_refCount(1) { m_node=NULL; m_pParent=NULL; m_fileName=NULL; } CSettingStorage::~CSettingStorage() { if(m_node){ if(m_pParent==NULL){ m_node->ownerDocument->save(m_fileName); }else{ m_pParent->Release(); } } if (m_fileName) delete m_fileName; } HRESULT CSettingStorage::QueryInterface( REFIID riid,void __RPC_FAR *__RPC_FAR *ppvObject) { if(riid==IID_IUnknown){ *ppvObject = (ISettingStorage*)this; AddRef(); return S_OK; }else if(riid==IID_ISettingStorage){ AddRef(); *ppvObject = (ISettingStorage*)this; return S_OK; }else{ return E_NOINTERFACE; } } ULONG CSettingStorage::AddRef( void) { // OutputDebugStringF("CSettingStorage::Addref%d\n",m_refCount); return InterlockedIncrement(&m_refCount); } ULONG CSettingStorage::Release( void) { // OutputDebugStringF("CSettingStorage::Release%d\n",m_refCount); LONG res= InterlockedDecrement(&m_refCount); if(res==0) { try { delete this; } catch(_com_error& err) { _bstr_t bstr = err.Description(); char str[128]; _snprintf(str, 128, "File: \'%s\' may be read-only file. Make it writable.", m_fileName); MessageBox(NULL, str, (char*)bstr, MB_ICONWARNING); } } return res; } //node¸¦ ã´Â´Ù.. IXMLDOMElementPtr FindNodeNamed(IXMLDOMElementPtr nodeParent,LPCSTR tagName,LPCSTR name) { int i=0; IXMLDOMNodeListPtr list=nodeParent->getElementsByTagName(tagName); for(i=0;;i++){ IXMLDOMElementPtr node=list->item[i]; if(node){ char nameRet[80]; GetAttrValueString(node,"Name",nameRet); if(stricmp(nameRet,name)==0){ return node; } }else{ break; } } return NULL; } static int GetHex(char c) { if('0'<=c&&c<='9')return c-'0'; if('a'<=c&&c<='f')return c-'a'+10; if('A'<=c&&c<='F')return c-'A'+10; return 0; } static int SetHex(int c) { if(0<=c&&c<=9)return c+'0'; if(10<=c&&c<=15)return c-10+'A'; return 0; } HRESULT CSettingStorage::Read(LPCSTR name,SSVType* pvType,DWORD* plen,void* data) { IXMLDOMElementPtr node=FindNodeNamed(m_node,"Setting",name); if(node==NULL){ return E_FAIL; }else{ SSVType vType=(SSVType)GetAttrValueNum(node,"Type"); DWORD len=GetAttrValueNum(node,"Length"); if(data){ if(vType==SSVT_DWORD){ *(DWORD*)data=GetAttrValueNum(node,"Data"); }else if(vType==SSVT_BIN){ char * buf=new char[len*2+1]; GetAttrValueString(node,"Data",buf); for(int i=0;iownerDocument->createElement("Setting"); m_node->appendChild(node); SetAttrValueString(node,"Name",name); } SetAttrValueNum(node,"Type",vType); SetAttrValueNum(node,"Length",len); if(vType==SSVT_DWORD){ SetAttrValueNum(node,"Data",*(DWORD*)data); }else if(vType==SSVT_BIN){ char * buf=new char[len*2+1]; buf[len*2]=0; for(int i=0;i>4)&0xF); buf[i*2+1]=SetHex((c)&0xF); } SetAttrValueString(node,"Data",buf); delete buf; }else if(vType==SSVT_TEXT){ //é© SetAttrValueString(node,"Data",(char*)data); } if(node){ if(m_pParent!=NULL){ node->ownerDocument->save(m_pParent->m_fileName); } } return E_NOTIMPL; } HRESULT CSettingStorage::MakeStorage(LPCSTR name,ISettingStorage** pStorage) { IXMLDOMElementPtr node=FindNodeNamed(m_node,"Settings",name); if(node==NULL){ //»õ·Î ¸¸µç´Ù.. node=m_node->ownerDocument->createElement("Settings"); m_node->appendChild(node); SetAttrValueString(node,"Name",name); } CSettingStorage* pnewStorage=new CSettingStorage; pnewStorage->m_node=node; pnewStorage->m_pParent=this; AddRef(); *pStorage=pnewStorage; return S_OK; return E_NOTIMPL; } HRESULT CSettingStorage::GetStorage(LPCSTR name,ISettingStorage** pStorage) { IXMLDOMElementPtr node=FindNodeNamed(m_node,"Settings",name); if(node==NULL){ return E_FAIL; }else{ CSettingStorage* pnewStorage=new CSettingStorage; pnewStorage->m_node=node; pnewStorage->m_pParent=this; AddRef(); *pStorage=pnewStorage; return S_OK; } } HRESULT CSettingStorage::Reset() { return E_NOTIMPL; } BOOL CSettingStorage::Create(LPCSTR filename) { IXMLDOMDocumentPtr docPtr; //init docPtr.CreateInstance("msxml2.domdocument"); //bIsRoot=TRUE; if(docPtr==NULL)return FALSE; m_fileName=new char[MAX_PATH]; lstrcpy(m_fileName,filename); // load a document _variant_t varXml(filename); _variant_t varOut((bool)TRUE); varOut = docPtr->load(varXml); if ((bool)varOut == FALSE){ docPtr->loadXML("\n"); varOut = docPtr->save(varXml); if ((bool)varOut == FALSE){ //loadµµ ¾ÈµÇ°í saveµµ ¾ÈµÈ´Ù.. //return FALSE; } } m_node=docPtr->documentElement; return TRUE; } BOOL CreateStorage(LPCSTR fileName,ISettingStorage** ppStorage) { CSettingStorage * pStorage=new CSettingStorage; if(pStorage->Create(fileName)){ *ppStorage=pStorage; return TRUE; }else{ delete pStorage; return FALSE; } } /* void main() { CoInitialize(NULL); //CDeviceLister* plister=new CDeviceLister2(); //CDeviceLister* plister=CreateDeviceLister(); plister->InitXMLDOMNodes("C:\\Models.xml"); plister->EnumerateDevices(); delete plister; CoUninitialize(); } */