Leaked source code of windows server 2003
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.

307 lines
6.9 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. try
  100. {
  101. if(bMatch)
  102. ReadValue(hkResult, NULL);
  103. else
  104. if(!ReadValues(hkResult))
  105. EnumSubKeys(hkResult, szKey);
  106. RegCloseKey(hkResult);
  107. hkResult = NULL;
  108. }
  109. catch (...)
  110. {
  111. if (hkResult != NULL)
  112. {
  113. RegCloseKey(hkResult);
  114. hkResult = NULL;
  115. }
  116. if (hKey != NULL)
  117. {
  118. RegCloseKey(hKey);
  119. hKey = NULL;
  120. }
  121. }
  122. }
  123. if (hKey != NULL)
  124. RegCloseKey(hKey);
  125. }
  126. }
  127. BOOL CMSPID::ReadValue(const HKEY& hKey, LPCTSTR szValueName)
  128. {
  129. DWORD cbData = NULL;
  130. TCHAR *szData = NULL;
  131. BOOL bMatch = FALSE;
  132. vector<TCHAR *>::iterator it;
  133. RegQueryValueEx(hKey, szValueName, NULL, NULL, (LPBYTE) szData, &cbData);
  134. if(cbData > 0)
  135. {
  136. szData = new TCHAR[cbData];
  137. ZeroMemory(szData,sizeof(szData));
  138. if(szData)
  139. {
  140. RegQueryValueEx(hKey, szValueName, NULL, NULL, (LPBYTE) szData, &cbData);
  141. bMatch = TRUE;
  142. for(it = m_vecBadPIDs.begin(); it != m_vecBadPIDs.end(); it++)
  143. {
  144. if(_tcsstr(_tcslwr(szData), *it))
  145. {
  146. bMatch = FALSE; //invalid PID
  147. break;
  148. }
  149. }
  150. }
  151. }
  152. if(bMatch)
  153. {
  154. TCHAR *pos1 = _tcsstr(m_szCurrKeyName, m_szMSSoftware); //The key under "Software\Microsoft" is the product name
  155. TCHAR *szProductName = NULL;
  156. if(pos1)
  157. {
  158. pos1+= _tcslen(m_szMSSoftware);
  159. pos1++;//past the backslash
  160. TCHAR *pos2 = _tcsstr(pos1, _T("\\"));
  161. if(pos2)
  162. {
  163. szProductName = new TCHAR[pos2 - pos1 + 1];
  164. if(szProductName)
  165. {
  166. _tcsncpy(szProductName, pos1, pos2 - pos1);
  167. szProductName[pos2 - pos1] = '\0';
  168. }
  169. }
  170. }
  171. if(szProductName)
  172. {
  173. if(m_bstrWindows && !_tcsicmp(szProductName, m_bstrWindows))
  174. {
  175. m_szWindowsPID = new TCHAR[_tcslen(szData) + 1];
  176. if(m_szWindowsPID)
  177. {
  178. ZeroMemory(m_szWindowsPID,sizeof(m_szWindowsPID));
  179. //_tcsncpy(m_szWindowsPID, szData,_tcslen(szData));
  180. /*for some reason, _tcsncpy sometimes seems to append garbage on the end
  181. of strings
  182. Since we've just 0'd the string, strcat should act like strcpy
  183. */
  184. _tcsncat(m_szWindowsPID, szData,_tcslen(szData));
  185. }
  186. }
  187. else if(m_bstrIE && !_tcsicmp(szProductName, m_bstrIE))
  188. {
  189. m_szIEPID = new TCHAR[_tcslen(szData) + 1];
  190. if(m_szIEPID)
  191. {
  192. ZeroMemory(m_szIEPID,sizeof(m_szIEPID));
  193. //_tcsncpy(m_szIEPID, szData,_tcslen(szData));
  194. /*for some reason, _tcsncpy sometimes seems to append garbage on the end
  195. of strings
  196. Since we've just 0'd the string, strcat should act like strcpy
  197. */
  198. _tcsncat(m_szIEPID,szData,_tcslen(szData));
  199. }
  200. }
  201. else
  202. {
  203. m_vecData.push_back(CComBSTR(szProductName));
  204. m_vecData.push_back(CComBSTR(szData));
  205. }
  206. delete[] szProductName;
  207. szProductName = NULL;
  208. }
  209. }
  210. if(szData)
  211. {
  212. delete[] szData;
  213. szData = NULL;
  214. }
  215. return bMatch;
  216. }
  217. BOOL CMSPID::ReadValues(const HKEY& hKey)
  218. {
  219. BOOL bRet = FALSE;
  220. vector<TCHAR *>::iterator it;
  221. for(it = m_vecPIDKeys.begin(); it != m_vecPIDKeys.end(); it++)
  222. {
  223. if(ReadValue(hKey, *it))
  224. break; //find just one
  225. }
  226. return bRet;
  227. }
  228. void CMSPID::EnumSubKeys(const HKEY& hKey, LPCTSTR szKey)
  229. {
  230. const LONG lMaxKeyLen = 2000;
  231. DWORD dwSubKeyLen = lMaxKeyLen;
  232. TCHAR szSubKeyName[lMaxKeyLen] = {0};
  233. TCHAR *szNewKey = NULL;
  234. DWORD dwIndex = 0;
  235. BOOL bSkip = FALSE;
  236. vector<TCHAR *>::iterator it;
  237. LONG lRet = RegEnumKeyEx(hKey, dwIndex++, szSubKeyName, &dwSubKeyLen, NULL, NULL, NULL, NULL);
  238. while(lRet == ERROR_SUCCESS)
  239. {
  240. bSkip = FALSE;
  241. for(it = m_vecKeysToSkip.begin(); it != m_vecKeysToSkip.end(); it++)
  242. {
  243. if(!_tcsicmp(szSubKeyName, *it))
  244. {
  245. bSkip = TRUE; //skip this subkey
  246. break;
  247. }
  248. }
  249. if(!bSkip)
  250. {
  251. //szNewKey = new TCHAR[_tcslen(szKey) + dwSubKeyLen + 2]; // slash & null
  252. CString szNewKey(szKey);
  253. if(szNewKey)
  254. {
  255. //_tcsncpy(szNewKey, szKey,_tcslen(szKey));
  256. szNewKey += _T("\\");
  257. //_tcsncat(szNewKey, _T("\\"),1);
  258. //_tcsncat(szNewKey, szSubKeyName,dwSubKeyLen);
  259. szNewKey += szSubKeyName;
  260. SearchKey(szNewKey);
  261. //delete[] szNewKey;
  262. //szNewKey = NULL;
  263. }
  264. }
  265. dwSubKeyLen = lMaxKeyLen;
  266. lRet = RegEnumKeyEx(hKey, dwIndex++, szSubKeyName, &dwSubKeyLen, NULL, NULL, NULL, NULL);
  267. }
  268. }