Source code of Windows XP (NT5)
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.

266 lines
5.6 KiB

  1. // MSPID.cpp : Implementation of CMSPID
  2. #include "stdafx.h"
  3. #include "msinfo32.h"
  4. #include "MSPID.h"
  5. /////////////////////////////////////////////////////////////////////////////
  6. // CMSPID
  7. //1) create a vector of Product Names & their PIDS.
  8. //2) create a safearray of variants and populate it with the values from the vector.
  9. //3) return a pointer to this safearray.
  10. STDMETHODIMP CMSPID::GetPIDInfo(VARIANT *pMachineName, VARIANT *pVal)
  11. {
  12. if(pMachineName->vt == VT_BSTR)
  13. {
  14. USES_CONVERSION;
  15. m_szMachineName = OLE2T(pMachineName->bstrVal);
  16. }
  17. SearchKey(m_szMSSoftware);
  18. if(m_szWindowsPID)
  19. {
  20. if(m_szIEPID)
  21. {
  22. //insert IE pid only if different from windows.
  23. if(_tcsicmp(m_szWindowsPID, m_szIEPID))
  24. {
  25. m_vecData.push_back(m_bstrIE);
  26. m_vecData.push_back(CComBSTR(m_szIEPID));
  27. }
  28. }
  29. m_vecData.push_back(m_bstrWindows);
  30. m_vecData.push_back(CComBSTR(m_szWindowsPID));
  31. }
  32. if(m_szWindowsPID)
  33. {
  34. delete[] m_szWindowsPID;
  35. m_szWindowsPID = NULL;
  36. }
  37. if(m_szIEPID)
  38. {
  39. delete[] m_szIEPID;
  40. m_szIEPID = NULL;
  41. }
  42. SAFEARRAY *pSa = NULL;
  43. SAFEARRAYBOUND rgsabound = {m_vecData.size(), 0};
  44. pSa = SafeArrayCreate(VT_VARIANT, 1, &rgsabound);
  45. VARIANT* pVar = NULL;
  46. SafeArrayAccessData(pSa, reinterpret_cast<void **>(&pVar));
  47. vector<CComBSTR>::iterator it;
  48. long lIdx = 0;
  49. for(it = m_vecData.begin(); it != m_vecData.end(); it++, lIdx++)
  50. {
  51. pVar[lIdx].vt = VT_BSTR;
  52. pVar[lIdx].bstrVal = SysAllocString((*it).m_str);
  53. }
  54. SafeArrayUnaccessData(pSa);
  55. VariantInit(pVal);
  56. pVal->vt = VT_ARRAY | VT_VARIANT;
  57. pVal->parray = pSa;
  58. return S_OK;
  59. }
  60. /*
  61. 1) connect to HKLM on a remote machine (trivial case is local)
  62. 2) open key "SOFTWARE\Microsoft"
  63. 3) use this key for item 4
  64. 4) if key is called "ProductID"
  65. get it's default value data
  66. else
  67. if key has a value called "ProductID"
  68. get it's data
  69. else
  70. while there are subkeys to enum
  71. {
  72. enum subkeys
  73. use next key for item 4
  74. }
  75. */
  76. void CMSPID::SearchKey(LPCTSTR szKey)
  77. {
  78. HKEY hkResult = NULL, hKey = NULL;
  79. if(ERROR_SUCCESS == RegConnectRegistry(m_szMachineName, HKEY_LOCAL_MACHINE, &hKey))
  80. {
  81. if(hKey != NULL && ERROR_SUCCESS == RegOpenKeyEx(hKey, szKey, 0, KEY_READ, &hkResult))
  82. {
  83. BOOL bMatch = FALSE;
  84. TCHAR *pos = _tcsrchr(szKey, '\\');
  85. if(pos)
  86. pos++;//past the "\"
  87. else
  88. pos = const_cast<TCHAR *>(szKey);
  89. vector<TCHAR *>::iterator it;
  90. for(it = m_vecPIDKeys.begin(); it != m_vecPIDKeys.end(); it++)
  91. {
  92. if(!_tcsicmp(pos, *it))
  93. {
  94. bMatch = TRUE;
  95. break;
  96. }
  97. }
  98. m_szCurrKeyName = szKey;
  99. if(bMatch)
  100. ReadValue(hkResult, NULL);
  101. else
  102. if(!ReadValues(hkResult))
  103. EnumSubKeys(hkResult, szKey);
  104. RegCloseKey(hkResult);
  105. }
  106. RegCloseKey(hKey);
  107. }
  108. }
  109. BOOL CMSPID::ReadValue(const HKEY& hKey, LPCTSTR szValueName)
  110. {
  111. DWORD cbData = NULL;
  112. TCHAR *szData = NULL;
  113. BOOL bMatch = FALSE;
  114. vector<TCHAR *>::iterator it;
  115. RegQueryValueEx(hKey, szValueName, NULL, NULL, (LPBYTE) szData, &cbData);
  116. if(cbData > 0)
  117. {
  118. szData = new TCHAR[cbData];
  119. if(szData)
  120. {
  121. RegQueryValueEx(hKey, szValueName, NULL, NULL, (LPBYTE) szData, &cbData);
  122. bMatch = TRUE;
  123. for(it = m_vecBadPIDs.begin(); it != m_vecBadPIDs.end(); it++)
  124. {
  125. if(_tcsstr(_tcslwr(szData), *it))
  126. {
  127. bMatch = FALSE; //invalid PID
  128. break;
  129. }
  130. }
  131. }
  132. }
  133. if(bMatch)
  134. {
  135. TCHAR *pos1 = _tcsstr(m_szCurrKeyName, m_szMSSoftware); //The key under "Software\Microsoft" is the product name
  136. TCHAR *szProductName = NULL;
  137. if(pos1)
  138. {
  139. pos1+= _tcslen(m_szMSSoftware);
  140. pos1++;//past the backslash
  141. TCHAR *pos2 = _tcsstr(pos1, _T("\\"));
  142. if(pos2)
  143. {
  144. szProductName = new TCHAR[pos2 - pos1 + 1];
  145. if(szProductName)
  146. {
  147. _tcsncpy(szProductName, pos1, pos2 - pos1);
  148. szProductName[pos2 - pos1] = '\0';
  149. }
  150. }
  151. }
  152. if(szProductName)
  153. {
  154. if(m_bstrWindows && !_tcsicmp(szProductName, m_bstrWindows))
  155. {
  156. m_szWindowsPID = new TCHAR[_tcslen(szData) + 1];
  157. if(m_szWindowsPID)
  158. _tcscpy(m_szWindowsPID, szData);
  159. }
  160. else if(m_bstrIE && !_tcsicmp(szProductName, m_bstrIE))
  161. {
  162. m_szIEPID = new TCHAR[_tcslen(szData) + 1];
  163. if(m_szIEPID)
  164. _tcscpy(m_szIEPID, szData);
  165. }
  166. else
  167. {
  168. m_vecData.push_back(CComBSTR(szProductName));
  169. m_vecData.push_back(CComBSTR(szData));
  170. }
  171. delete[] szProductName;
  172. szProductName = NULL;
  173. }
  174. }
  175. if(szData)
  176. {
  177. delete[] szData;
  178. szData = NULL;
  179. }
  180. return bMatch;
  181. }
  182. BOOL CMSPID::ReadValues(const HKEY& hKey)
  183. {
  184. BOOL bRet = FALSE;
  185. vector<TCHAR *>::iterator it;
  186. for(it = m_vecPIDKeys.begin(); it != m_vecPIDKeys.end(); it++)
  187. {
  188. if(ReadValue(hKey, *it))
  189. break; //find just one
  190. }
  191. return bRet;
  192. }
  193. void CMSPID::EnumSubKeys(const HKEY& hKey, LPCTSTR szKey)
  194. {
  195. const LONG lMaxKeyLen = 2000;
  196. DWORD dwSubKeyLen = lMaxKeyLen;
  197. TCHAR szSubKeyName[lMaxKeyLen] = {0};
  198. TCHAR *szNewKey = NULL;
  199. DWORD dwIndex = 0;
  200. BOOL bSkip = FALSE;
  201. vector<TCHAR *>::iterator it;
  202. LONG lRet = RegEnumKeyEx(hKey, dwIndex++, szSubKeyName, &dwSubKeyLen, NULL, NULL, NULL, NULL);
  203. while(lRet == ERROR_SUCCESS)
  204. {
  205. bSkip = FALSE;
  206. for(it = m_vecKeysToSkip.begin(); it != m_vecKeysToSkip.end(); it++)
  207. {
  208. if(!_tcsicmp(szSubKeyName, *it))
  209. {
  210. bSkip = TRUE; //skip this subkey
  211. break;
  212. }
  213. }
  214. if(!bSkip)
  215. {
  216. szNewKey = new TCHAR[_tcslen(szKey) + dwSubKeyLen + 2]; // slash & null
  217. if(szNewKey)
  218. {
  219. _tcscpy(szNewKey, szKey);
  220. _tcscat(szNewKey, _T("\\"));
  221. _tcscat(szNewKey, szSubKeyName);
  222. SearchKey(szNewKey);
  223. delete[] szNewKey;
  224. szNewKey = NULL;
  225. }
  226. }
  227. dwSubKeyLen = lMaxKeyLen;
  228. lRet = RegEnumKeyEx(hKey, dwIndex++, szSubKeyName, &dwSubKeyLen, NULL, NULL, NULL, NULL);
  229. }
  230. }