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.

621 lines
17 KiB

  1. #include <windows.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include "shlwapi.h"
  5. #include "parse.h"
  6. #include "wbemcli.h"
  7. #include "SComPtr.h"
  8. #include "rsop.h"
  9. /////////////////////////////////////////////////////////////////////
  10. // Reads all RSOP_IERegistryPolicySetting instances in the namespace and
  11. // stores them in a list.
  12. /////////////////////////////////////////////////////////////////////
  13. CRSOPRegData::CRSOPRegData():
  14. m_pData(NULL)
  15. {
  16. }
  17. CRSOPRegData::~CRSOPRegData()
  18. {
  19. Free();
  20. }
  21. /////////////////////////////////////////////////////////////////////
  22. void CRSOPRegData::Free()
  23. {
  24. __try
  25. {
  26. if (NULL != m_pData)
  27. {
  28. LPRSOPREGITEM lpTemp;
  29. do
  30. {
  31. lpTemp = m_pData->pNext;
  32. if (m_pData->lpData)
  33. LocalFree (m_pData->lpData);
  34. LocalFree (m_pData);
  35. m_pData = lpTemp;
  36. } while (lpTemp);
  37. }
  38. }
  39. __except(TRUE)
  40. {
  41. }
  42. }
  43. /////////////////////////////////////////////////////////////////////
  44. HRESULT CRSOPRegData::Initialize(BSTR bstrNamespace)
  45. {
  46. HRESULT hr = S_OK;
  47. __try
  48. {
  49. _bstr_t bstrWQL = L"WQL";
  50. _bstr_t bstrQuery = L"SELECT currentUser, registryKey, valueName, valueType, value, deleted, precedence, GPOID, command FROM RSOP_IERegistryPolicySetting";
  51. _bstr_t bstrRegistryKey = L"registryKey";
  52. _bstr_t bstrCurrentUser = L"currentUser";
  53. _bstr_t bstrValueName = L"valueName";
  54. _bstr_t bstrValueType = L"valueType";
  55. _bstr_t bstrValue = L"value";
  56. _bstr_t bstrDeleted = L"deleted";
  57. _bstr_t bstrPrecedence = L"precedence";
  58. _bstr_t bstrGPOid = L"GPOID";
  59. _bstr_t bstrCommand = L"command";
  60. // Create an instance of the WMI locator service
  61. ComPtr<IWbemLocator> pIWbemLocator = NULL;
  62. hr = CoCreateInstance(CLSID_WbemLocator, NULL, CLSCTX_INPROC_SERVER,
  63. IID_IWbemLocator, (LPVOID *) &pIWbemLocator);
  64. if (SUCCEEDED(hr))
  65. {
  66. // Connect to the server
  67. ComPtr<IWbemServices> pIWbemServices = NULL;
  68. hr = pIWbemLocator->ConnectServer(bstrNamespace, NULL, NULL, 0L, 0L, NULL,
  69. NULL, &pIWbemServices);
  70. if (SUCCEEDED(hr))
  71. {
  72. // Execute the query
  73. ComPtr<IEnumWbemClassObject> pEnum = NULL;
  74. hr = pIWbemServices->ExecQuery (bstrWQL, bstrQuery,
  75. WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
  76. NULL, &pEnum);
  77. if (SUCCEEDED(hr))
  78. {
  79. // Loop through the results
  80. ComPtr<IWbemClassObject> pRegObj = NULL;
  81. ULONG ulRet = 0;
  82. hr = pEnum->Next(WBEM_INFINITE, 1, &pRegObj, &ulRet);
  83. while (S_OK == hr && 0 != ulRet) // ulRet == 0 is "data not available" case
  84. {
  85. // Get the deleted flag & registry key
  86. _variant_t varDeleted;
  87. _variant_t varRegistryKey;
  88. hr = pRegObj->Get (bstrDeleted, 0, &varDeleted, NULL, NULL);
  89. if (SUCCEEDED(hr))
  90. hr = pRegObj->Get (bstrRegistryKey, 0, &varRegistryKey, NULL, NULL);
  91. // Get the class (current user or local machine)
  92. _variant_t varCurUser;
  93. if (SUCCEEDED(hr))
  94. hr = pRegObj->Get (bstrCurrentUser, 0, &varCurUser, NULL, NULL);
  95. // Get the value name
  96. _variant_t varValueName;
  97. if (SUCCEEDED(hr))
  98. hr = pRegObj->Get (bstrValueName, 0, &varValueName, NULL, NULL);
  99. // Get the value type
  100. _variant_t varValueType;
  101. if (SUCCEEDED(hr))
  102. hr = pRegObj->Get (bstrValueType, 0, &varValueType, NULL, NULL);
  103. // Get the value data
  104. _variant_t varData;
  105. if (SUCCEEDED(hr))
  106. hr = pRegObj->Get (bstrValue, 0, &varData, NULL, NULL);
  107. // Get the precedence
  108. _variant_t varPrecedence;
  109. if (SUCCEEDED(hr))
  110. hr = pRegObj->Get (bstrPrecedence, 0, &varPrecedence, NULL, NULL);
  111. // Get the command
  112. _variant_t varCommand;
  113. if (SUCCEEDED(hr))
  114. hr = pRegObj->Get (bstrCommand, 0, &varCommand, NULL, NULL);
  115. // Get the GPO ID
  116. _variant_t varGPOid;
  117. if (SUCCEEDED(hr))
  118. hr = pRegObj->Get (bstrGPOid, 0, &varGPOid, NULL, NULL);
  119. if (SUCCEEDED(hr))
  120. {
  121. LPTSTR lpGPOName;
  122. hr = GetGPOFriendlyName (pIWbemServices, varGPOid.bstrVal,
  123. bstrWQL, &lpGPOName);
  124. if (SUCCEEDED(hr))
  125. {
  126. BSTR bstrValueTemp = NULL;
  127. if (varValueName.vt != VT_NULL)
  128. bstrValueTemp = varValueName.bstrVal;
  129. DWORD dwDataSize = 0;
  130. LPBYTE lpData = NULL;
  131. if (varData.vt != VT_NULL)
  132. {
  133. SAFEARRAY *pSafeArray = varData.parray;
  134. dwDataSize = pSafeArray->rgsabound[0].cElements;
  135. lpData = (LPBYTE) pSafeArray->pvData;
  136. }
  137. if ((varValueType.uintVal == REG_NONE) && bstrValueTemp &&
  138. !lstrcmpi(bstrValueTemp, TEXT("**command")))
  139. {
  140. bstrValueTemp = varCommand.bstrVal;
  141. dwDataSize = 0;
  142. lpData = NULL;
  143. }
  144. AddNode((varCurUser.boolVal == 0) ? FALSE : TRUE,
  145. varRegistryKey.bstrVal, bstrValueTemp,
  146. varValueType.uintVal, dwDataSize, lpData,
  147. varPrecedence.uintVal, lpGPOName,
  148. (varDeleted.boolVal == 0) ? FALSE : TRUE);
  149. LocalFree (lpGPOName);
  150. }
  151. }
  152. hr = pEnum->Next(WBEM_INFINITE, 1, &pRegObj, &ulRet);
  153. }
  154. }
  155. }
  156. }
  157. }
  158. __except(TRUE)
  159. {
  160. }
  161. return hr;
  162. }
  163. /////////////////////////////////////////////////////////////////////
  164. HRESULT CRSOPRegData::GetGPOFriendlyName(IWbemServices *pIWbemServices,
  165. LPTSTR lpGPOID, BSTR bstrLanguage,
  166. LPTSTR *pGPOName)
  167. {
  168. HRESULT hr = NOERROR;
  169. __try
  170. {
  171. // Set the default
  172. *pGPOName = NULL;
  173. // Build the query
  174. ComPtr<IEnumWbemClassObject> pEnum = NULL;
  175. LPTSTR lpQuery = (LPTSTR) LocalAlloc (LPTR, ((lstrlen(lpGPOID) + 50) * sizeof(TCHAR)));
  176. if (NULL != lpQuery)
  177. {
  178. wsprintf (lpQuery, TEXT("SELECT name, id FROM RSOP_GPO where id=\"%s\""), lpGPOID);
  179. _bstr_t bstrQuery = lpQuery;
  180. // Execute the query
  181. hr = pIWbemServices->ExecQuery(bstrLanguage, bstrQuery,
  182. WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
  183. NULL, &pEnum);
  184. }
  185. else
  186. hr = E_OUTOFMEMORY;
  187. ComPtr<IWbemClassObject> pGPOObj;
  188. ULONG nObjects = 0;
  189. if (SUCCEEDED(hr))
  190. {
  191. // Loop through the results
  192. hr = pEnum->Next(WBEM_INFINITE, 1, &pGPOObj, &nObjects);
  193. }
  194. _bstr_t bstrName = L"name";
  195. _variant_t varGPOName;
  196. if (SUCCEEDED(hr) && nObjects > 0)
  197. {
  198. // Get the name
  199. hr = pGPOObj->Get(bstrName, 0, &varGPOName, NULL, NULL);
  200. if (SUCCEEDED(hr))
  201. {
  202. // Save the name
  203. *pGPOName = (LPTSTR) LocalAlloc (LPTR, (lstrlen(varGPOName.bstrVal) + 1) * sizeof(TCHAR));
  204. if (*pGPOName)
  205. {
  206. _bstr_t bstrVal = varGPOName.bstrVal;
  207. lstrcpy (*pGPOName, (LPCTSTR)bstrVal);
  208. hr = S_OK;
  209. }
  210. else
  211. hr = HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY);
  212. }
  213. }
  214. // Check for the "data not available case"
  215. else if (nObjects == 0)
  216. hr = S_OK;
  217. if (lpQuery)
  218. LocalFree (lpQuery);
  219. }
  220. __except(TRUE)
  221. {
  222. }
  223. return hr;
  224. }
  225. /////////////////////////////////////////////////////////////////////
  226. BOOL CRSOPRegData::AddNode(BOOL bHKCU, BSTR bstrKeyName, BSTR bstrValueName,
  227. DWORD dwType, DWORD dwDataSize, LPBYTE lpData,
  228. UINT uiPrecedence, LPTSTR lpGPOName, BOOL bDeleted)
  229. {
  230. BOOL bRet = FALSE;
  231. __try
  232. {
  233. // Calculate the size of the new registry item
  234. DWORD dwSize = sizeof (RSOPREGITEM);
  235. if (bstrKeyName)
  236. dwSize += ((SysStringLen(bstrKeyName) + 1) * sizeof(WCHAR));
  237. if (bstrValueName)
  238. dwSize += ((SysStringLen(bstrValueName) + 1) * sizeof(WCHAR));
  239. if (lpGPOName)
  240. dwSize += ((SysStringLen(lpGPOName) + 1) * sizeof(TCHAR));
  241. // Allocate space for it
  242. LPRSOPREGITEM lpItem = (LPRSOPREGITEM) LocalAlloc (LPTR, dwSize);
  243. if (!lpItem)
  244. return FALSE;
  245. // Fill in item
  246. lpItem->bHKCU = bHKCU;
  247. lpItem->dwType = dwType;
  248. lpItem->dwSize = dwDataSize;
  249. lpItem->uiPrecedence = uiPrecedence;
  250. lpItem->bDeleted = bDeleted;
  251. if (bstrKeyName)
  252. {
  253. lpItem->lpKeyName = (LPTSTR)(((LPBYTE)lpItem) + sizeof(RSOPREGITEM));
  254. lstrcpy (lpItem->lpKeyName, (LPCTSTR)bstrKeyName);
  255. }
  256. if (bstrValueName)
  257. {
  258. if (bstrKeyName)
  259. lpItem->lpValueName = lpItem->lpKeyName + lstrlen (lpItem->lpKeyName) + 1;
  260. else
  261. lpItem->lpValueName = (LPTSTR)(((LPBYTE)lpItem) + sizeof(RSOPREGITEM));
  262. lstrcpy (lpItem->lpValueName, (LPCTSTR)bstrValueName);
  263. }
  264. if (lpGPOName)
  265. {
  266. if (bstrValueName)
  267. lpItem->lpGPOName = lpItem->lpValueName + lstrlen (lpItem->lpValueName) + 1;
  268. else
  269. {
  270. if (bstrKeyName)
  271. lpItem->lpGPOName = lpItem->lpKeyName + lstrlen (lpItem->lpKeyName) + 1;
  272. else
  273. lpItem->lpGPOName = (LPTSTR)(((LPBYTE)lpItem) + sizeof(RSOPREGITEM));
  274. }
  275. lstrcpy (lpItem->lpGPOName, lpGPOName);
  276. }
  277. if (lpData)
  278. {
  279. lpItem->lpData = (LPBYTE) LocalAlloc (LPTR, dwDataSize);
  280. if (!lpItem->lpData)
  281. {
  282. LocalFree (lpItem);
  283. return FALSE;
  284. }
  285. CopyMemory (lpItem->lpData, lpData, dwDataSize);
  286. }
  287. // Add item to link list
  288. lpItem->pNext = m_pData;
  289. m_pData = lpItem;
  290. bRet = TRUE;
  291. }
  292. __except(TRUE)
  293. {
  294. }
  295. return bRet;
  296. }
  297. const TCHAR szDELETEPREFIX[] = TEXT("**del.");
  298. #ifndef NORM_STOP_ON_NULL
  299. #define NORM_STOP_ON_NULL 0x10000000
  300. #endif
  301. /////////////////////////////////////////////////////////////////////
  302. UINT CRSOPRegData::ReadValue(UINT uiPrecedence, BOOL bHKCU, LPTSTR pszKeyName,
  303. LPTSTR pszValueName, LPBYTE pData, DWORD dwMaxSize,
  304. DWORD *pdwType, LPTSTR *lpGPOName, LPRSOPREGITEM lpItem /*= NULL*/)
  305. {
  306. UINT iRet = ERROR_SUCCESS;
  307. __try
  308. {
  309. LPRSOPREGITEM lpTemp = NULL;
  310. BOOL bDeleted = FALSE;
  311. LPTSTR lpValueNameTemp = pszValueName;
  312. if (!lpItem)
  313. {
  314. lpTemp = m_pData;
  315. if (pszValueName)
  316. {
  317. INT iDelPrefixLen = lstrlen(szDELETEPREFIX);
  318. if (CompareString (LOCALE_USER_DEFAULT, NORM_IGNORECASE | NORM_STOP_ON_NULL,
  319. pszValueName, iDelPrefixLen,
  320. szDELETEPREFIX, iDelPrefixLen) == CSTR_EQUAL)
  321. {
  322. lpValueNameTemp = pszValueName + iDelPrefixLen;
  323. bDeleted = TRUE;
  324. }
  325. }
  326. // Find the item
  327. while (lpTemp)
  328. {
  329. if (pszKeyName && lpValueNameTemp &&
  330. lpTemp->lpKeyName && lpTemp->lpValueName)
  331. {
  332. if (bDeleted == lpTemp->bDeleted)
  333. {
  334. if ((uiPrecedence == 0) || (uiPrecedence == (UINT)lpTemp->uiPrecedence))
  335. {
  336. if (!lstrcmpi(lpTemp->lpValueName, lpValueNameTemp) &&
  337. !lstrcmpi(lpTemp->lpKeyName, pszKeyName) &&
  338. bHKCU == lpTemp->bHKCU)
  339. {
  340. break;
  341. }
  342. }
  343. }
  344. }
  345. else if (!pszKeyName && lpValueNameTemp &&
  346. !lpTemp->lpKeyName && lpTemp->lpValueName)
  347. {
  348. if (bDeleted == lpTemp->bDeleted)
  349. {
  350. if ((uiPrecedence == 0) || (uiPrecedence == (UINT)lpTemp->uiPrecedence))
  351. {
  352. if (!lstrcmpi(lpTemp->lpValueName, lpValueNameTemp) &&
  353. bHKCU == lpTemp->bHKCU)
  354. {
  355. break;
  356. }
  357. }
  358. }
  359. }
  360. else if (pszKeyName && !lpValueNameTemp &&
  361. lpTemp->lpKeyName && !lpTemp->lpValueName)
  362. {
  363. if (bDeleted == lpTemp->bDeleted)
  364. {
  365. if ((uiPrecedence == 0) || (uiPrecedence == (UINT)lpTemp->uiPrecedence))
  366. {
  367. if (!lstrcmpi(lpTemp->lpKeyName, pszKeyName) &&
  368. bHKCU == lpTemp->bHKCU)
  369. {
  370. break;
  371. }
  372. }
  373. }
  374. }
  375. lpTemp = lpTemp->pNext;
  376. }
  377. }
  378. else
  379. {
  380. // Read a specific item
  381. lpTemp = lpItem;
  382. }
  383. // Check to see if the item was found
  384. if (lpTemp)
  385. {
  386. // Check if the data will fit in the buffer passed in
  387. if (lpTemp->dwSize <= dwMaxSize)
  388. {
  389. // Copy the data
  390. if (lpTemp->lpData)
  391. CopyMemory (pData, lpTemp->lpData, lpTemp->dwSize);
  392. *pdwType = lpTemp->dwType;
  393. if (lpGPOName)
  394. *lpGPOName = lpTemp->lpGPOName;
  395. }
  396. else
  397. iRet = ERROR_NOT_ENOUGH_MEMORY;
  398. }
  399. else
  400. iRet = ERROR_FILE_NOT_FOUND;
  401. }
  402. __except(TRUE)
  403. {
  404. }
  405. return iRet;
  406. }
  407. #define MAXSTRLEN 1024
  408. /////////////////////////////////////////////////////////////////////
  409. // Reads the reg settings from WMI for a particular ADM file and stores
  410. // them in a PART array.
  411. /////////////////////////////////////////////////////////////////////
  412. void ReadRegSettingsForADM(LPADMFILE admfile, LPPARTDATA pPartData,
  413. BSTR bstrNamespace)
  414. {
  415. __try
  416. {
  417. CRSOPRegData RegData;
  418. RegData.Initialize(bstrNamespace);
  419. LPPART part = admfile->pParts;
  420. for( int i = 0; i < admfile->nParts; i++ )
  421. {
  422. BOOL bHKCU = (HKEY_LOCAL_MACHINE == part[i].hkClass) ? FALSE : TRUE;
  423. BYTE pbData[MAXSTRLEN];
  424. ZeroMemory(pbData, sizeof(pbData));
  425. DWORD dwType = REG_NONE;
  426. LPTSTR lpGPOName = NULL;
  427. UINT uiRet = RegData.ReadValue(1, bHKCU, part[i].value.szKeyname,
  428. part[i].value.szValueName, pbData,
  429. sizeof(pbData), &dwType, &lpGPOName);
  430. if ( ERROR_SUCCESS == uiRet)
  431. {
  432. // store data as numeric or string
  433. BOOL fNumeric = FALSE;
  434. DWORD dwValue = 0;
  435. _bstr_t bstrValue;
  436. if (REG_SZ != dwType) // Numeric
  437. {
  438. fNumeric = TRUE;
  439. memcpy(&dwValue, pbData, sizeof(dwValue));
  440. }
  441. else
  442. {
  443. // string data is always stored as wide strings
  444. if (NULL != pbData)
  445. bstrValue = (LPWSTR)pbData;
  446. }
  447. if (pPartData[i].value.szValue != NULL)
  448. LocalFree(pPartData[i].value.szValue);
  449. pPartData[i].value.szValue = NULL;
  450. if ((part[i].nType == PART_POLICY && part->fRequired) || part[i].nType == PART_CHECKBOX)
  451. {
  452. if (fNumeric)
  453. {
  454. if (dwValue == (DWORD) part[i].value.nValueOn)
  455. pPartData[i].value.dwValue = 1;
  456. else
  457. pPartData[i].value.dwValue = 0;
  458. }
  459. else // String
  460. {
  461. if (NULL != part[i].value.szValueOn && NULL != pbData &&
  462. 0 == StrCmp(part[i].value.szValueOn, (LPTSTR)bstrValue))
  463. {
  464. pPartData[i].value.dwValue = 1;
  465. }
  466. else
  467. pPartData[i].value.dwValue = 0;
  468. if (NULL != pbData)
  469. pPartData[i].value.szValue = StrDup((LPTSTR)bstrValue);
  470. }
  471. pPartData[i].value.fNumeric = TRUE;
  472. pPartData[i].fSave = TRUE;
  473. }
  474. else if (part[i].nType == PART_DROPDOWNLIST)
  475. {
  476. if (part[i].nSelectedAction != NO_ACTION && part[i].nActions > 0)
  477. {
  478. for(int nIndex = 0; nIndex < part[i].nActions; nIndex++)
  479. {
  480. if (fNumeric)
  481. {
  482. if (part[i].actionlist[nIndex].dwValue == dwValue && part[i].actionlist[nIndex].szName)
  483. {
  484. pPartData[i].value.szValue = StrDup(part[i].actionlist[nIndex].szName);
  485. pPartData[i].nSelectedAction = nIndex;
  486. }
  487. }
  488. else
  489. {
  490. if (NULL != part[i].actionlist[nIndex].szValue && NULL != pbData &&
  491. 0 == StrCmp(part[i].actionlist[nIndex].szValue, (LPTSTR)bstrValue) &&
  492. NULL != part[i].actionlist[nIndex].szName)
  493. {
  494. pPartData[i].value.szValue = StrDup(part[i].actionlist[nIndex].szName);
  495. pPartData[i].nSelectedAction = nIndex;
  496. }
  497. }
  498. }
  499. pPartData[i].fSave = TRUE;
  500. }
  501. pPartData[i].value.fNumeric = FALSE;
  502. }
  503. else if (part[i].nType == PART_LISTBOX && fNumeric)
  504. {
  505. // Allocate memory
  506. if (pPartData[i].nActions == 0)
  507. pPartData[i].actionlist = (LPACTIONLIST) HeapAlloc(GetProcessHeap(),
  508. HEAP_ZERO_MEMORY, sizeof(ACTIONLIST));
  509. if (pPartData[i].actionlist != NULL)
  510. {
  511. if (0 == pPartData[i].nActions)
  512. {
  513. pPartData[i].nActions = 1;
  514. pPartData[i].actionlist[0].value = (LPVALUE) HeapAlloc(GetProcessHeap(),
  515. HEAP_ZERO_MEMORY, sizeof(VALUE));
  516. }
  517. if (pPartData[i].actionlist[0].value != NULL)
  518. {
  519. TCHAR szValueName[10];
  520. int nItems = pPartData[i].actionlist[0].nValues;
  521. if (0 != nItems)
  522. {
  523. LPVOID lpTemp = (LPVALUE) HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
  524. pPartData[i].actionlist[0].value,
  525. sizeof(VALUE) * (nItems + 1));
  526. if (lpTemp != NULL)
  527. pPartData[i].actionlist[0].value = (LPVALUE)lpTemp;
  528. else
  529. continue;
  530. }
  531. if (part[i].value.szKeyname != NULL)
  532. pPartData[i].actionlist[0].value[nItems].szKeyname = StrDup(part[i].value.szKeyname);
  533. wnsprintf(szValueName, ARRAYSIZE(szValueName), TEXT("%d"), nItems + 1);
  534. pPartData[i].actionlist[0].value[nItems].szValueName = StrDup(szValueName);
  535. if (NULL != pbData)
  536. pPartData[i].actionlist[0].value[nItems].szValue = StrDup((LPTSTR)bstrValue);
  537. pPartData[i].actionlist[0].nValues++;
  538. pPartData[i].value.fNumeric = TRUE;
  539. pPartData[i].value.dwValue = 1;
  540. pPartData[i].fSave = TRUE;
  541. }
  542. }
  543. }
  544. else
  545. {
  546. if (NULL != pbData)
  547. pPartData[i].value.szValue = StrDup((LPTSTR)bstrValue);
  548. pPartData[i].value.dwValue = dwValue;
  549. pPartData[i].value.fNumeric = fNumeric;
  550. pPartData[i].fSave = TRUE;
  551. }
  552. }
  553. } // end for
  554. }
  555. __except(TRUE)
  556. {
  557. }
  558. }