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.

16224 lines
504 KiB

  1. #include "gptext.h"
  2. #include <initguid.h>
  3. #include "Policy.h"
  4. #include "smartptr.h"
  5. #include "wbemtime.h"
  6. #include <strsafe.h>
  7. #define RSOP_HELP_FILE TEXT("gpedit.hlp")
  8. //
  9. // ADM directory name
  10. //
  11. const TCHAR g_szADM[] = TEXT("Adm");
  12. const TCHAR g_szNull[] = TEXT("");
  13. const TCHAR g_szStrings[] = TEXT("strings");
  14. const TCHAR szIFDEF[] = TEXT("#ifdef");
  15. const TCHAR szIF[] = TEXT("#if");
  16. const TCHAR szENDIF[] = TEXT("#endif");
  17. const TCHAR szIFNDEF[] = TEXT("#ifndef");
  18. const TCHAR szELSE[] = TEXT("#else");
  19. const TCHAR szVERSION[] = TEXT("version");
  20. const TCHAR szLT[] = TEXT("<");
  21. const TCHAR szLTE[] = TEXT("<=");
  22. const TCHAR szGT[] = TEXT(">");
  23. const TCHAR szGTE[] = TEXT(">=");
  24. const TCHAR szEQ[] = TEXT("==");
  25. const TCHAR szNE[] = TEXT("!=");
  26. const TCHAR szLISTBOX[] = TEXT("LISTBOX");
  27. const TCHAR szEDIT[] = TEXT("EDIT");
  28. const TCHAR szBUTTON[] = TEXT("BUTTON");
  29. const TCHAR szSTATIC[] = TEXT("STATIC");
  30. const TCHAR szCLASS[] = TEXT("CLASS");
  31. const TCHAR szCATEGORY[] = TEXT("CATEGORY");
  32. const TCHAR szPOLICY[] = TEXT("POLICY");
  33. const TCHAR szUSER[] = TEXT("USER");
  34. const TCHAR szMACHINE[] = TEXT("MACHINE");
  35. const TCHAR szCHECKBOX[] = TEXT("CHECKBOX");
  36. const TCHAR szTEXT[] = TEXT("TEXT");
  37. const TCHAR szEDITTEXT[] = TEXT("EDITTEXT");
  38. const TCHAR szNUMERIC[] = TEXT("NUMERIC");
  39. const TCHAR szCOMBOBOX[] = TEXT("COMBOBOX");
  40. const TCHAR szDROPDOWNLIST[] = TEXT("DROPDOWNLIST");
  41. const TCHAR szUPDOWN[] = UPDOWN_CLASS;
  42. const TCHAR szKEYNAME[] = TEXT("KEYNAME");
  43. const TCHAR szVALUENAME[] = TEXT("VALUENAME");
  44. const TCHAR szNAME[] = TEXT("NAME");
  45. const TCHAR szEND[] = TEXT("END");
  46. const TCHAR szPART[] = TEXT("PART");
  47. const TCHAR szSUGGESTIONS[] = TEXT("SUGGESTIONS");
  48. const TCHAR szDEFCHECKED[] = TEXT("DEFCHECKED");
  49. const TCHAR szDEFAULT[] = TEXT("DEFAULT");
  50. const TCHAR szMAXLENGTH[] = TEXT("MAXLEN");
  51. const TCHAR szMIN[] = TEXT("MIN");
  52. const TCHAR szMAX[] = TEXT("MAX");
  53. const TCHAR szSPIN[] = TEXT("SPIN");
  54. const TCHAR szREQUIRED[] = TEXT("REQUIRED");
  55. const TCHAR szOEMCONVERT[] = TEXT("OEMCONVERT");
  56. const TCHAR szTXTCONVERT[] = TEXT("TXTCONVERT");
  57. const TCHAR szEXPANDABLETEXT[] = TEXT("EXPANDABLETEXT");
  58. const TCHAR szVALUEON[] = TEXT("VALUEON");
  59. const TCHAR szVALUEOFF[] = TEXT("VALUEOFF");
  60. const TCHAR szVALUE[] = TEXT("VALUE");
  61. const TCHAR szACTIONLIST[] = TEXT("ACTIONLIST");
  62. const TCHAR szACTIONLISTON[] = TEXT("ACTIONLISTON");
  63. const TCHAR szACTIONLISTOFF[] = TEXT("ACTIONLISTOFF");
  64. const TCHAR szDELETE[] = TEXT("DELETE");
  65. const TCHAR szITEMLIST[] = TEXT("ITEMLIST");
  66. const TCHAR szSOFT[] = TEXT("SOFT");
  67. const TCHAR szVALUEPREFIX[] = TEXT("VALUEPREFIX");
  68. const TCHAR szADDITIVE[] = TEXT("ADDITIVE");
  69. const TCHAR szEXPLICITVALUE[] = TEXT("EXPLICITVALUE");
  70. const TCHAR szNOSORT[] = TEXT("NOSORT");
  71. const TCHAR szHELP[] = TEXT("EXPLAIN");
  72. const TCHAR szCLIENTEXT[] = TEXT("CLIENTEXT");
  73. const TCHAR szSUPPORTED[] = TEXT("SUPPORTED");
  74. const TCHAR szStringsSect[] = TEXT("[strings]");
  75. const TCHAR szStrings[] = TEXT("strings");
  76. const TCHAR szDELETEPREFIX[] = TEXT("**del.");
  77. const TCHAR szSOFTPREFIX[] = TEXT("**soft.");
  78. const TCHAR szDELVALS[] = TEXT("**delvals.");
  79. const TCHAR szNOVALUE[] = TEXT(" ");
  80. const TCHAR szUserPrefKey[] = TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Group Policy Editor");
  81. const TCHAR szPoliciesKey[] = TEXT("Software\\Policies\\Microsoft\\Windows\\Group Policy Editor");
  82. const TCHAR szDefaultTemplates[] = TEXT("DefaultTemplates");
  83. const TCHAR szAdditionalTemplates[] = TEXT("AdditionalTemplates");
  84. // list of legal keyword entries in "CATEGORY" section
  85. KEYWORDINFO pCategoryEntryCmpList[] = { {szKEYNAME,KYWD_ID_KEYNAME},
  86. {szCATEGORY,KYWD_ID_CATEGORY},{szPOLICY,KYWD_ID_POLICY},
  87. {szEND,KYWD_ID_END},{szHELP,KYWD_ID_HELP}, {NULL,0} };
  88. KEYWORDINFO pCategoryTypeCmpList[] = { {szCATEGORY,KYWD_ID_CATEGORY},
  89. {NULL,0} };
  90. // list of legal keyword entries in "POLICY" section
  91. KEYWORDINFO pPolicyEntryCmpList[] = { {szKEYNAME,KYWD_ID_KEYNAME},
  92. {szVALUENAME,KYWD_ID_VALUENAME}, {szPART,KYWD_ID_PART},
  93. {szVALUEON,KYWD_ID_VALUEON},{szVALUEOFF,KYWD_ID_VALUEOFF},
  94. {szACTIONLISTON,KYWD_ID_ACTIONLISTON},{szACTIONLISTOFF,KYWD_ID_ACTIONLISTOFF},
  95. {szEND,KYWD_ID_END},{szHELP,KYWD_ID_HELP}, {szCLIENTEXT,KYWD_ID_CLIENTEXT},
  96. {szSUPPORTED,KYWD_ID_SUPPORTED}, {NULL, 0} };
  97. KEYWORDINFO pPolicyTypeCmpList[] = { {szPOLICY,KYWD_ID_POLICY}, {NULL,0} };
  98. // list of legal keyword entries in "PART" section
  99. KEYWORDINFO pSettingsEntryCmpList[] = { {szCHECKBOX,KYWD_ID_CHECKBOX},
  100. {szTEXT,KYWD_ID_TEXT},{szEDITTEXT,KYWD_ID_EDITTEXT},
  101. {szNUMERIC,KYWD_ID_NUMERIC},{szCOMBOBOX,KYWD_ID_COMBOBOX},
  102. {szDROPDOWNLIST,KYWD_ID_DROPDOWNLIST},{szLISTBOX,KYWD_ID_LISTBOX},
  103. {szEND,KYWD_ID_END}, {szCLIENTEXT,KYWD_ID_CLIENTEXT}, {NULL,0}};
  104. KEYWORDINFO pSettingsTypeCmpList[] = {{szPART,KYWD_ID_PART},{NULL,0}};
  105. KEYWORDINFO pCheckboxCmpList[] = {
  106. {szKEYNAME,KYWD_ID_KEYNAME},{szVALUENAME,KYWD_ID_VALUENAME},
  107. {szVALUEON,KYWD_ID_VALUEON},{szVALUEOFF,KYWD_ID_VALUEOFF},
  108. {szACTIONLISTON,KYWD_ID_ACTIONLISTON},{szACTIONLISTOFF,KYWD_ID_ACTIONLISTOFF},
  109. {szDEFCHECKED, KYWD_ID_DEFCHECKED}, {szCLIENTEXT,KYWD_ID_CLIENTEXT},
  110. {szEND,KYWD_ID_END},{NULL,0} };
  111. KEYWORDINFO pTextCmpList[] = {{szEND,KYWD_ID_END},{NULL,0}};
  112. KEYWORDINFO pEditTextCmpList[] = {
  113. {szKEYNAME,KYWD_ID_KEYNAME},{szVALUENAME,KYWD_ID_VALUENAME},
  114. {szDEFAULT,KYWD_ID_EDITTEXT_DEFAULT},
  115. {szREQUIRED,KYWD_ID_REQUIRED},{szMAXLENGTH,KYWD_ID_MAXLENGTH},
  116. {szOEMCONVERT,KYWD_ID_OEMCONVERT},{szSOFT,KYWD_ID_SOFT},
  117. {szEND,KYWD_ID_END},{szEXPANDABLETEXT,KYWD_ID_EXPANDABLETEXT},
  118. {szCLIENTEXT,KYWD_ID_CLIENTEXT}, {NULL,0} };
  119. KEYWORDINFO pComboboxCmpList[] = {
  120. {szKEYNAME,KYWD_ID_KEYNAME},{szVALUENAME,KYWD_ID_VALUENAME},
  121. {szDEFAULT,KYWD_ID_COMBOBOX_DEFAULT},{szSUGGESTIONS,KYWD_ID_SUGGESTIONS},
  122. {szREQUIRED,KYWD_ID_REQUIRED},{szMAXLENGTH,KYWD_ID_MAXLENGTH},
  123. {szOEMCONVERT,KYWD_ID_OEMCONVERT},{szSOFT,KYWD_ID_SOFT},
  124. {szEND,KYWD_ID_END},{szNOSORT, KYWD_ID_NOSORT},
  125. {szEXPANDABLETEXT,KYWD_ID_EXPANDABLETEXT},{szCLIENTEXT,KYWD_ID_CLIENTEXT}, {NULL,0} };
  126. KEYWORDINFO pNumericCmpList[] = {
  127. {szKEYNAME,KYWD_ID_KEYNAME},{szVALUENAME,KYWD_ID_VALUENAME},
  128. {szMIN, KYWD_ID_MIN},{szMAX,KYWD_ID_MAX},{szSPIN,KYWD_ID_SPIN},
  129. {szDEFAULT,KYWD_ID_NUMERIC_DEFAULT},{szREQUIRED,KYWD_ID_REQUIRED},
  130. {szTXTCONVERT,KYWD_ID_TXTCONVERT},{szSOFT,KYWD_ID_SOFT},
  131. {szEND,KYWD_ID_END}, {szCLIENTEXT,KYWD_ID_CLIENTEXT}, {NULL,0} };
  132. KEYWORDINFO pDropdownlistCmpList[] = {
  133. {szKEYNAME,KYWD_ID_KEYNAME},{szVALUENAME,KYWD_ID_VALUENAME},
  134. {szREQUIRED,KYWD_ID_REQUIRED},{szITEMLIST,KYWD_ID_ITEMLIST},
  135. {szEND,KYWD_ID_END},{szNOSORT, KYWD_ID_NOSORT},{szCLIENTEXT,KYWD_ID_CLIENTEXT}, {NULL,0}};
  136. KEYWORDINFO pListboxCmpList[] = {
  137. {szKEYNAME,KYWD_ID_KEYNAME},{szVALUEPREFIX,KYWD_ID_VALUEPREFIX},
  138. {szADDITIVE,KYWD_ID_ADDITIVE},{szNOSORT, KYWD_ID_NOSORT},
  139. {szEXPLICITVALUE,KYWD_ID_EXPLICITVALUE},{szEXPANDABLETEXT,KYWD_ID_EXPANDABLETEXT},
  140. {szEND,KYWD_ID_END},{szCLIENTEXT,KYWD_ID_CLIENTEXT}, {NULL,0} };
  141. KEYWORDINFO pClassCmpList[] = { {szCLASS, KYWD_ID_CLASS},
  142. {szCATEGORY,KYWD_ID_CATEGORY}, {szStringsSect,KYWD_ID_STRINGSSECT},
  143. {NULL,0} };
  144. KEYWORDINFO pClassTypeCmpList[] = { {szUSER, KYWD_ID_USER},
  145. {szMACHINE,KYWD_ID_MACHINE}, {NULL,0} };
  146. KEYWORDINFO pVersionCmpList[] = { {szVERSION, KYWD_ID_VERSION}, {NULL,0}};
  147. KEYWORDINFO pOperatorCmpList[] = { {szGT, KYWD_ID_GT}, {szGTE,KYWD_ID_GTE},
  148. {szLT, KYWD_ID_LT}, {szLTE,KYWD_ID_LTE}, {szEQ,KYWD_ID_EQ},
  149. {szNE, KYWD_ID_NE}, {NULL,0}};
  150. //
  151. // Help ID's
  152. //
  153. DWORD aADMHelpIds[] = {
  154. // Templates dialog
  155. IDC_TEMPLATELIST, (IDH_HELPFIRST + 0),
  156. IDC_ADDTEMPLATES, (IDH_HELPFIRST + 1),
  157. IDC_REMOVETEMPLATES, (IDH_HELPFIRST + 2),
  158. 0, 0
  159. };
  160. DWORD aPolicyHelpIds[] = {
  161. // ADM Policy UI page
  162. IDC_NOCONFIG, (IDH_HELPFIRST + 11),
  163. IDC_ENABLED, (IDH_HELPFIRST + 12),
  164. IDC_DISABLED, (IDH_HELPFIRST + 13),
  165. IDC_POLICY_PREVIOUS, (IDH_HELPFIRST + 14),
  166. IDC_POLICY_NEXT, (IDH_HELPFIRST + 15),
  167. 0, 0
  168. };
  169. DWORD aExplainHelpIds[] = {
  170. // Explain page
  171. IDC_POLICY_PREVIOUS, (IDH_HELPFIRST + 14),
  172. IDC_POLICY_NEXT, (IDH_HELPFIRST + 15),
  173. 0, 0
  174. };
  175. DWORD aPrecedenceHelpIds[] = {
  176. // Precedence page
  177. IDC_POLICY_PRECEDENCE, (IDH_HELPFIRST + 16),
  178. IDC_POLICY_PREVIOUS, (IDH_HELPFIRST + 14),
  179. IDC_POLICY_NEXT, (IDH_HELPFIRST + 15),
  180. 0, 0
  181. };
  182. DWORD aFilteringHelpIds[] = {
  183. // Filtering options
  184. IDC_STATIC, (DWORD) (-1), // disabled help
  185. IDC_FILTERING_ICON, (DWORD) (-1), // disabled help
  186. IDC_SUPPORTEDONTITLE, (DWORD) (-1), // disabled help
  187. IDC_SUPPORTEDOPTION, (IDH_HELPFIRST + 20),
  188. IDC_FILTERLIST, (IDH_HELPFIRST + 21),
  189. IDC_SELECTALL, (IDH_HELPFIRST + 22),
  190. IDC_DESELECTALL, (IDH_HELPFIRST + 23),
  191. IDC_SHOWCONFIG, (IDH_HELPFIRST + 24),
  192. IDC_SHOWPOLICIES, (IDH_HELPFIRST + 25),
  193. 0, 0
  194. };
  195. #define ADM_USELOCAL_KEY TEXT("Software\\Policies\\Microsoft\\Windows\\Group Policy")
  196. #define GPE_KEY TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Group Policy Editor")
  197. #define GPE_POLICIES_KEY TEXT("Software\\Policies\\Microsoft\\Windows\\Group Policy Editor")
  198. #define ADM_USELOCAL_VALUE TEXT("OnlyUseLocalAdminFiles")
  199. #define POLICYONLY_VALUE TEXT("ShowPoliciesOnly")
  200. #define DISABLE_AUTOUPDATE_VALUE TEXT("DisableAutoADMUpdate")
  201. #define SOFTWARE_POLICIES TEXT("Software\\Policies")
  202. #define WINDOWS_POLICIES TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Policies")
  203. typedef struct _GPOERRORINFO
  204. {
  205. DWORD dwError;
  206. LPTSTR lpMsg;
  207. LPTSTR lpDetails;
  208. } GPOERRORINFO, *LPGPOERRORINFO;
  209. //
  210. // Help ids
  211. //
  212. DWORD aErrorHelpIds[] =
  213. {
  214. 0, 0
  215. };
  216. LPHASHTABLE CreateHashTable (void);
  217. VOID FreeHashTable (LPHASHTABLE lpTable);
  218. ULONG CalculateHashInfo(LPTSTR lpName, DWORD dwChars, DWORD *pdwHashValue);
  219. BOOL AddHashEntry (LPHASHTABLE lpTable, LPTSTR lpName, DWORD dwChars);
  220. LPTSTR FindHashEntry (LPHASHTABLE lpTable, LPTSTR lpName, DWORD dwChars);
  221. #if DBG
  222. VOID DumpHashTableDetails (LPHASHTABLE lpTable);
  223. #endif
  224. ///////////////////////////////////////////////////////////////////////////////
  225. // //
  226. // CPolicyComponentData object implementation //
  227. // //
  228. ///////////////////////////////////////////////////////////////////////////////
  229. CPolicyComponentData::CPolicyComponentData(BOOL bUser, BOOL bRSOP)
  230. {
  231. TCHAR szEvent[200];
  232. HRESULT hr = S_OK;
  233. m_cRef = 1;
  234. InterlockedIncrement(&g_cRefThisDll);
  235. m_hwndFrame = NULL;
  236. m_pScope = NULL;
  237. m_pConsole = NULL;
  238. m_hRoot = NULL;
  239. m_hSWPolicies = NULL;
  240. m_pGPTInformation = NULL;
  241. m_pRSOPInformation = NULL;
  242. m_pRSOPRegistryData = NULL;
  243. m_pszNamespace = NULL;
  244. m_bUserScope = bUser;
  245. m_bRSOP = bRSOP;
  246. m_pMachineCategoryList = NULL;
  247. m_nMachineDataItems = 0;
  248. m_pUserCategoryList = NULL;
  249. m_nUserDataItems = 0;
  250. m_pSupportedStrings = 0;
  251. m_iSWPoliciesLen = lstrlen(SOFTWARE_POLICIES);
  252. m_iWinPoliciesLen = lstrlen(WINDOWS_POLICIES);
  253. m_bUseSupportedOnFilter = FALSE;
  254. m_pDefaultHashTable = NULL;
  255. m_pLanguageHashTable = NULL;
  256. m_pLocaleHashTable = NULL;
  257. if (bRSOP)
  258. {
  259. m_bShowConfigPoliciesOnly = TRUE;
  260. }
  261. else
  262. {
  263. m_bShowConfigPoliciesOnly = FALSE;
  264. }
  265. m_pSnapin = NULL;
  266. m_hTemplateThread = NULL;
  267. hr = StringCchPrintf (szEvent, ARRAYSIZE(szEvent), TEXT("gptext: ADM files ready event, %d:%d"), bUser, GetTickCount());
  268. ASSERT(SUCCEEDED(hr));
  269. m_ADMEvent = CreateEvent (NULL, TRUE, FALSE, szEvent);
  270. if (!m_ADMEvent)
  271. {
  272. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::CPolicyComponentData: Failed to create ADM event with %d."),
  273. GetLastError()));
  274. }
  275. LoadString (g_hInstance, IDS_POLICY_NAME, m_szRootName, ROOT_NAME_SIZE);
  276. m_pExtraSettingsRoot = NULL;
  277. m_bExtraSettingsInitialized = FALSE;
  278. }
  279. CPolicyComponentData::~CPolicyComponentData()
  280. {
  281. //
  282. // Wait for the Template thread to finish before continuing.
  283. //
  284. if (m_hTemplateThread)
  285. WaitForSingleObject(m_hTemplateThread, INFINITE);
  286. FreeTemplates ();
  287. if (m_pExtraSettingsRoot)
  288. {
  289. FreeTable ((TABLEENTRY *)m_pExtraSettingsRoot);
  290. }
  291. if (m_pScope)
  292. {
  293. m_pScope->Release();
  294. }
  295. if (m_pConsole)
  296. {
  297. m_pConsole->Release();
  298. }
  299. if (m_pGPTInformation)
  300. {
  301. m_pGPTInformation->Release();
  302. }
  303. if (m_pRSOPInformation)
  304. {
  305. m_pRSOPInformation->Release();
  306. }
  307. if (m_pRSOPRegistryData)
  308. {
  309. FreeRSOPRegistryData();
  310. }
  311. if (m_pszNamespace)
  312. {
  313. LocalFree (m_pszNamespace);
  314. }
  315. CloseHandle (m_ADMEvent);
  316. if (m_hTemplateThread)
  317. CloseHandle (m_hTemplateThread);
  318. m_hTemplateThread = NULL;
  319. InterlockedDecrement(&g_cRefThisDll);
  320. }
  321. ///////////////////////////////////////////////////////////////////////////////
  322. // //
  323. // CPolicyComponentData object implementation (IUnknown) //
  324. // //
  325. ///////////////////////////////////////////////////////////////////////////////
  326. HRESULT CPolicyComponentData::QueryInterface (REFIID riid, void **ppv)
  327. {
  328. if (IsEqualIID(riid, IID_IComponentData) || IsEqualIID(riid, IID_IUnknown))
  329. {
  330. *ppv = (LPCOMPONENT)this;
  331. m_cRef++;
  332. return S_OK;
  333. }
  334. else if (IsEqualIID(riid, IID_IExtendContextMenu))
  335. {
  336. *ppv = (LPEXTENDCONTEXTMENU)this;
  337. m_cRef++;
  338. return S_OK;
  339. }
  340. else if (IsEqualIID(riid, IID_IPersistStreamInit))
  341. {
  342. *ppv = (LPPERSISTSTREAMINIT)this;
  343. m_cRef++;
  344. return S_OK;
  345. }
  346. else if (IsEqualIID(riid, IID_ISnapinHelp))
  347. {
  348. *ppv = (LPSNAPINHELP)this;
  349. m_cRef++;
  350. return S_OK;
  351. }
  352. else
  353. {
  354. *ppv = NULL;
  355. return E_NOINTERFACE;
  356. }
  357. }
  358. ULONG CPolicyComponentData::AddRef (void)
  359. {
  360. return ++m_cRef;
  361. }
  362. ULONG CPolicyComponentData::Release (void)
  363. {
  364. if (--m_cRef == 0) {
  365. delete this;
  366. return 0;
  367. }
  368. return m_cRef;
  369. }
  370. ///////////////////////////////////////////////////////////////////////////////
  371. // //
  372. // CPolicyComponentData object implementation (IComponentData) //
  373. // //
  374. ///////////////////////////////////////////////////////////////////////////////
  375. STDMETHODIMP CPolicyComponentData::Initialize(LPUNKNOWN pUnknown)
  376. {
  377. HRESULT hr;
  378. HBITMAP bmp16x16;
  379. LPIMAGELIST lpScopeImage;
  380. //
  381. // QI for IConsoleNameSpace
  382. //
  383. hr = pUnknown->QueryInterface(IID_IConsoleNameSpace2, (LPVOID *)&m_pScope);
  384. if (FAILED(hr))
  385. {
  386. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::Initialize: Failed to QI for IConsoleNameSpace.")));
  387. return hr;
  388. }
  389. //
  390. // QI for IConsole
  391. //
  392. hr = pUnknown->QueryInterface(IID_IConsole, (LPVOID *)&m_pConsole);
  393. if (FAILED(hr))
  394. {
  395. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::Initialize: Failed to QI for IConsole.")));
  396. m_pScope->Release();
  397. m_pScope = NULL;
  398. return hr;
  399. }
  400. m_pConsole->GetMainWindow (&m_hwndFrame);
  401. //
  402. // Query for the scope imagelist interface
  403. //
  404. hr = m_pConsole->QueryScopeImageList(&lpScopeImage);
  405. if (FAILED(hr))
  406. {
  407. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::Initialize: Failed to QI for scope imagelist.")));
  408. m_pScope->Release();
  409. m_pScope = NULL;
  410. m_pConsole->Release();
  411. m_pConsole=NULL;
  412. return hr;
  413. }
  414. // Load the bitmaps from the dll
  415. bmp16x16=LoadBitmap(g_hInstance, MAKEINTRESOURCE(IDB_16x16));
  416. // Set the images
  417. lpScopeImage->ImageListSetStrip(reinterpret_cast<LONG_PTR *>(bmp16x16),
  418. reinterpret_cast<LONG_PTR *>(bmp16x16),
  419. 0, RGB(255, 0, 255));
  420. lpScopeImage->Release();
  421. //
  422. // Create the root of the Extra Settings node if appropriate
  423. //
  424. if (m_bRSOP)
  425. {
  426. DWORD dwBufSize;
  427. REGITEM *pTmp;
  428. TCHAR szBuffer[100];
  429. m_pExtraSettingsRoot = (REGITEM *) GlobalAlloc(GPTR, sizeof(REGITEM));
  430. if (!m_pExtraSettingsRoot)
  431. {
  432. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::Initialize: GlobalAlloc failed with %d"), GetLastError()));
  433. return HRESULT_FROM_WIN32(GetLastError());
  434. }
  435. m_pExtraSettingsRoot->dwSize = sizeof(REGITEM);
  436. m_pExtraSettingsRoot->dwType = (ETYPE_ROOT | ETYPE_REGITEM);
  437. LoadString (g_hInstance, IDS_EXTRAREGSETTINGS, szBuffer, ARRAYSIZE(szBuffer));
  438. pTmp = (REGITEM *) AddDataToEntry((TABLEENTRY *)m_pExtraSettingsRoot,
  439. (BYTE *)szBuffer,(lstrlen(szBuffer)+1) * sizeof(TCHAR),&(m_pExtraSettingsRoot->uOffsetName),
  440. &dwBufSize);
  441. if (!pTmp)
  442. {
  443. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::Initialize: AddDataToEntry failed.")));
  444. return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
  445. }
  446. m_pExtraSettingsRoot = pTmp;
  447. }
  448. return S_OK;
  449. }
  450. STDMETHODIMP CPolicyComponentData::Destroy(VOID)
  451. {
  452. return S_OK;
  453. }
  454. STDMETHODIMP CPolicyComponentData::CreateComponent(LPCOMPONENT *ppComponent)
  455. {
  456. HRESULT hr;
  457. CPolicySnapIn *pSnapIn;
  458. DebugMsg((DM_VERBOSE, TEXT("CPolicyComponentData::CreateComponent: Entering.")));
  459. //
  460. // Initialize
  461. //
  462. *ppComponent = NULL;
  463. //
  464. // Create the snapin view
  465. //
  466. pSnapIn = new CPolicySnapIn(this);
  467. if (!pSnapIn)
  468. {
  469. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::CreateComponent: Failed to create CPolicySnapIn.")));
  470. return E_OUTOFMEMORY;
  471. }
  472. //
  473. // QI for IComponent
  474. //
  475. hr = pSnapIn->QueryInterface(IID_IComponent, (LPVOID *)ppComponent);
  476. pSnapIn->Release(); // release QI
  477. m_pSnapin = pSnapIn;
  478. return hr;
  479. }
  480. STDMETHODIMP CPolicyComponentData::QueryDataObject(MMC_COOKIE cookie, DATA_OBJECT_TYPES type,
  481. LPDATAOBJECT* ppDataObject)
  482. {
  483. HRESULT hr = E_NOINTERFACE;
  484. CPolicyDataObject *pDataObject;
  485. LPPOLICYDATAOBJECT pPolicyDataObject;
  486. //
  487. // Create a new DataObject
  488. //
  489. pDataObject = new CPolicyDataObject(this); // ref == 1
  490. if (!pDataObject)
  491. return E_OUTOFMEMORY;
  492. //
  493. // QI for the private GPTDataObject interface so we can set the cookie
  494. // and type information.
  495. //
  496. hr = pDataObject->QueryInterface(IID_IPolicyDataObject, (LPVOID *)&pPolicyDataObject);
  497. if (FAILED(hr))
  498. {
  499. pDataObject->Release();
  500. return (hr);
  501. }
  502. pPolicyDataObject->SetType(type);
  503. pPolicyDataObject->SetCookie(cookie);
  504. pPolicyDataObject->Release();
  505. //
  506. // QI for a normal IDataObject to return.
  507. //
  508. hr = pDataObject->QueryInterface(IID_IDataObject, (LPVOID *)ppDataObject);
  509. pDataObject->Release(); // release initial ref
  510. return hr;
  511. }
  512. STDMETHODIMP CPolicyComponentData::Notify(LPDATAOBJECT lpDataObject, MMC_NOTIFY_TYPE event, LPARAM arg, LPARAM param)
  513. {
  514. HRESULT hr = S_OK;
  515. switch(event)
  516. {
  517. case MMCN_REMOVE_CHILDREN:
  518. if ( ((HSCOPEITEM)arg != NULL) && m_bRSOP && (m_pRSOPInformation != NULL) )
  519. {
  520. if ( (m_hRoot == NULL) || ((HSCOPEITEM)arg == m_hRoot) )
  521. {
  522. FreeRSOPRegistryData();
  523. m_hRoot = NULL;
  524. m_hSWPolicies = NULL;
  525. m_pRSOPInformation->Release();
  526. m_pRSOPInformation = NULL;
  527. }
  528. }
  529. break;
  530. case MMCN_EXPAND:
  531. if (arg == TRUE)
  532. if (m_bRSOP)
  533. {
  534. if ( m_pRSOPInformation == NULL )
  535. {
  536. lpDataObject->QueryInterface(IID_IRSOPInformation, (LPVOID *)&m_pRSOPInformation);
  537. if (m_pRSOPInformation)
  538. {
  539. m_pszNamespace = (LPOLESTR) LocalAlloc (LPTR, 350 * sizeof(TCHAR));
  540. if (m_pszNamespace)
  541. {
  542. if (m_pRSOPInformation->GetNamespace((m_bUserScope ? GPO_SECTION_USER : GPO_SECTION_MACHINE),
  543. m_pszNamespace, 350) == S_OK)
  544. {
  545. InitializeRSOPRegistryData();
  546. // Check if there are any entries
  547. if ( m_pRSOPRegistryData == NULL )
  548. {
  549. LocalFree( m_pszNamespace );
  550. m_pszNamespace = NULL;
  551. m_pRSOPInformation->Release();
  552. m_pRSOPInformation = NULL;
  553. }
  554. }
  555. else
  556. {
  557. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::Notify: Failed to query for namespace")));
  558. LocalFree (m_pszNamespace);
  559. m_pszNamespace = NULL;
  560. }
  561. }
  562. }
  563. }
  564. if (m_pszNamespace && m_pRSOPRegistryData)
  565. {
  566. hr = EnumerateScopePane(lpDataObject, (HSCOPEITEM)param);
  567. }
  568. }
  569. else
  570. {
  571. if (!m_pGPTInformation)
  572. {
  573. lpDataObject->QueryInterface(IID_IGPEInformation, (LPVOID *)&m_pGPTInformation);
  574. }
  575. if (m_pGPTInformation)
  576. {
  577. hr = EnumerateScopePane(lpDataObject, (HSCOPEITEM)param);
  578. }
  579. }
  580. break;
  581. default:
  582. break;
  583. }
  584. return hr;
  585. }
  586. STDMETHODIMP CPolicyComponentData::GetDisplayInfo(LPSCOPEDATAITEM pItem)
  587. {
  588. TABLEENTRY * pTableEntry;
  589. if (pItem == NULL)
  590. return E_POINTER;
  591. if (pItem->lParam == 0)
  592. {
  593. pItem->displayname = m_szRootName;
  594. }
  595. else
  596. {
  597. pTableEntry = (TABLEENTRY *)(pItem->lParam);
  598. pItem->displayname = GETNAMEPTR(pTableEntry);
  599. }
  600. return S_OK;
  601. }
  602. STDMETHODIMP CPolicyComponentData::CompareObjects(LPDATAOBJECT lpDataObjectA, LPDATAOBJECT lpDataObjectB)
  603. {
  604. HRESULT hr = S_FALSE;
  605. LPPOLICYDATAOBJECT pPolicyDataObjectA, pPolicyDataObjectB;
  606. MMC_COOKIE cookie1, cookie2;
  607. if (lpDataObjectA == NULL || lpDataObjectB == NULL)
  608. return E_POINTER;
  609. //
  610. // QI for the private GPTDataObject interface
  611. //
  612. if (FAILED(lpDataObjectA->QueryInterface(IID_IPolicyDataObject,
  613. (LPVOID *)&pPolicyDataObjectA)))
  614. {
  615. return S_FALSE;
  616. }
  617. if (FAILED(lpDataObjectB->QueryInterface(IID_IPolicyDataObject,
  618. (LPVOID *)&pPolicyDataObjectB)))
  619. {
  620. pPolicyDataObjectA->Release();
  621. return S_FALSE;
  622. }
  623. pPolicyDataObjectA->GetCookie(&cookie1);
  624. pPolicyDataObjectB->GetCookie(&cookie2);
  625. if (cookie1 == cookie2)
  626. {
  627. hr = S_OK;
  628. }
  629. pPolicyDataObjectA->Release();
  630. pPolicyDataObjectB->Release();
  631. return hr;
  632. }
  633. ///////////////////////////////////////////////////////////////////////////////
  634. // //
  635. // CPolicyComponentData object implementation (IExtendContextMenu) //
  636. // //
  637. ///////////////////////////////////////////////////////////////////////////////
  638. STDMETHODIMP CPolicyComponentData::AddMenuItems(LPDATAOBJECT piDataObject,
  639. LPCONTEXTMENUCALLBACK pCallback,
  640. LONG *pInsertionAllowed)
  641. {
  642. HRESULT hr = S_OK;
  643. TCHAR szMenuItem[100];
  644. TCHAR szDescription[250];
  645. CONTEXTMENUITEM item;
  646. LPPOLICYDATAOBJECT pPolicyDataObject;
  647. MMC_COOKIE cookie = -1;
  648. DATA_OBJECT_TYPES type = CCT_UNINITIALIZED;
  649. if (!m_bRSOP)
  650. {
  651. if (SUCCEEDED(piDataObject->QueryInterface(IID_IPolicyDataObject,
  652. (LPVOID *)&pPolicyDataObject)))
  653. {
  654. pPolicyDataObject->GetType(&type);
  655. pPolicyDataObject->GetCookie(&cookie);
  656. pPolicyDataObject->Release();
  657. }
  658. if ((type == CCT_SCOPE) && (cookie == 0))
  659. {
  660. LoadString (g_hInstance, IDS_TEMPLATES, szMenuItem, 100);
  661. LoadString (g_hInstance, IDS_TEMPLATESDESC, szDescription, 250);
  662. item.strName = szMenuItem;
  663. item.strStatusBarText = szDescription;
  664. item.lCommandID = IDM_TEMPLATES;
  665. item.lInsertionPointID = CCM_INSERTIONPOINTID_PRIMARY_TOP;
  666. item.fFlags = 0;
  667. item.fSpecialFlags = 0;
  668. hr = pCallback->AddItem(&item);
  669. if (FAILED(hr))
  670. return (hr);
  671. item.strName = szMenuItem;
  672. item.strStatusBarText = szDescription;
  673. item.lCommandID = IDM_TEMPLATES2;
  674. item.lInsertionPointID = CCM_INSERTIONPOINTID_PRIMARY_TASK;
  675. item.fFlags = 0;
  676. item.fSpecialFlags = 0;
  677. hr = pCallback->AddItem(&item);
  678. }
  679. }
  680. return (hr);
  681. }
  682. STDMETHODIMP CPolicyComponentData::Command(LONG lCommandID, LPDATAOBJECT piDataObject)
  683. {
  684. if ((lCommandID == IDM_TEMPLATES) || (lCommandID == IDM_TEMPLATES2))
  685. {
  686. m_bTemplatesColumn = 0;
  687. if (DialogBoxParam (g_hInstance, MAKEINTRESOURCE(IDD_TEMPLATES),
  688. m_hwndFrame, TemplatesDlgProc, (LPARAM) this))
  689. {
  690. //
  691. // Refresh the adm namespace
  692. //
  693. PostMessage (HWND_BROADCAST, m_pSnapin->m_uiRefreshMsg, 0, (LPARAM) GetCurrentProcessId());
  694. }
  695. }
  696. return S_OK;
  697. }
  698. ///////////////////////////////////////////////////////////////////////////////
  699. // //
  700. // CPolicyComponentData object implementation (IPersistStreamInit) //
  701. // //
  702. ///////////////////////////////////////////////////////////////////////////////
  703. STDMETHODIMP CPolicyComponentData::GetClassID(CLSID *pClassID)
  704. {
  705. if (!pClassID)
  706. {
  707. return E_FAIL;
  708. }
  709. if (m_bUserScope)
  710. *pClassID = CLSID_PolicySnapInUser;
  711. else
  712. *pClassID = CLSID_PolicySnapInMachine;
  713. return S_OK;
  714. }
  715. STDMETHODIMP CPolicyComponentData::IsDirty(VOID)
  716. {
  717. return S_FALSE;
  718. }
  719. STDMETHODIMP CPolicyComponentData::Load(IStream *pStm)
  720. {
  721. return S_OK;
  722. }
  723. STDMETHODIMP CPolicyComponentData::Save(IStream *pStm, BOOL fClearDirty)
  724. {
  725. return S_OK;
  726. }
  727. STDMETHODIMP CPolicyComponentData::GetSizeMax(ULARGE_INTEGER *pcbSize)
  728. {
  729. DWORD dwSize = 0;
  730. if (!pcbSize)
  731. {
  732. return E_FAIL;
  733. }
  734. ULISet32(*pcbSize, dwSize);
  735. return S_OK;
  736. }
  737. STDMETHODIMP CPolicyComponentData::InitNew(void)
  738. {
  739. return S_OK;
  740. }
  741. ///////////////////////////////////////////////////////////////////////////////
  742. // //
  743. // CPolicyComponentData object implementation (ISnapinHelp) //
  744. // //
  745. ///////////////////////////////////////////////////////////////////////////////
  746. STDMETHODIMP CPolicyComponentData::GetHelpTopic(LPOLESTR *lpCompiledHelpFile)
  747. {
  748. LPOLESTR lpHelpFile;
  749. lpHelpFile = (LPOLESTR) CoTaskMemAlloc (MAX_PATH * sizeof(WCHAR));
  750. if (!lpHelpFile)
  751. {
  752. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::GetHelpTopic: Failed to allocate memory.")));
  753. return E_OUTOFMEMORY;
  754. }
  755. ExpandEnvironmentStringsW (L"%SystemRoot%\\Help\\gptext.chm",
  756. lpHelpFile, MAX_PATH);
  757. *lpCompiledHelpFile = lpHelpFile;
  758. return S_OK;
  759. }
  760. ///////////////////////////////////////////////////////////////////////////////
  761. // //
  762. // CPolicyComponentData object implementation (Internal functions) //
  763. // //
  764. ///////////////////////////////////////////////////////////////////////////////
  765. HRESULT CPolicyComponentData::EnumerateScopePane (LPDATAOBJECT lpDataObject, HSCOPEITEM hParent)
  766. {
  767. SCOPEDATAITEM item;
  768. HRESULT hr;
  769. TABLEENTRY *pTemp = NULL;
  770. DWORD dwResult;
  771. CPolicySnapIn * pSnapin = NULL, *pSnapinTemp;
  772. BOOL bRootItem = FALSE;
  773. HANDLE hEvents[1];
  774. if (!m_hRoot)
  775. {
  776. DWORD dwID;
  777. m_hRoot = hParent;
  778. m_hTemplateThread = CreateThread (NULL, 0,
  779. (LPTHREAD_START_ROUTINE) LoadTemplatesThread,
  780. (LPVOID) this, 0, &dwID);
  781. if (m_hTemplateThread)
  782. {
  783. SetThreadPriority(m_hTemplateThread, THREAD_PRIORITY_LOWEST);
  784. }
  785. else
  786. {
  787. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::EnumerateScopePane: Failed to create adm thread with %d"),
  788. GetLastError()));
  789. LoadTemplates();
  790. }
  791. }
  792. if (m_hRoot == hParent)
  793. {
  794. item.mask = SDI_STR | SDI_STATE | SDI_IMAGE | SDI_OPENIMAGE | SDI_PARAM | SDI_CHILDREN;
  795. item.displayname = MMC_CALLBACK;
  796. item.nImage = 0;
  797. item.nOpenImage = 1;
  798. item.nState = 0;
  799. item.cChildren = 1;
  800. item.lParam = 0;
  801. item.relativeID = hParent;
  802. m_pScope->Expand(hParent);
  803. if (SUCCEEDED(m_pScope->InsertItem (&item)))
  804. {
  805. m_hSWPolicies = item.ID;
  806. }
  807. return S_OK;
  808. }
  809. hEvents[0] = m_ADMEvent;
  810. if (WaitForSingleObject (m_ADMEvent, 250) != WAIT_OBJECT_0)
  811. {
  812. DebugMsg((DM_VERBOSE, TEXT("CPolicyComponentData::EnumerateScopePane: Waiting for ADM event to be signaled.")));
  813. for (;;) {
  814. SetCursor (LoadCursor(NULL, IDC_WAIT));
  815. dwResult = MsgWaitForMultipleObjects(1, hEvents, FALSE, INFINITE, QS_ALLINPUT);
  816. if (dwResult == WAIT_OBJECT_0 ) {
  817. break;
  818. }
  819. else if (dwResult == WAIT_OBJECT_0 + 1 ) {
  820. MSG msg;
  821. while ( PeekMessage( &msg, 0, 0, 0, PM_REMOVE ) )
  822. {
  823. TranslateMessage(&msg);
  824. DispatchMessage(&msg);
  825. }
  826. }
  827. else {
  828. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::EnumerateScopePane: MsgWaitForMultipleObjects returned %d ."), dwResult));
  829. break;
  830. }
  831. }
  832. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::EnumerateScopePane: ADM event has been signaled.")));
  833. SetCursor (LoadCursor(NULL, IDC_ARROW));
  834. }
  835. item.mask = SDI_PARAM;
  836. item.ID = hParent;
  837. hr = m_pScope->GetItem (&item);
  838. if (FAILED(hr))
  839. return hr;
  840. EnterCriticalSection (&g_ADMCritSec);
  841. if (item.lParam)
  842. {
  843. pTemp = ((TABLEENTRY *)item.lParam)->pChild;
  844. }
  845. else
  846. {
  847. bRootItem = TRUE;
  848. if (m_bUserScope)
  849. {
  850. if (m_pUserCategoryList)
  851. {
  852. pTemp = m_pUserCategoryList->pChild;
  853. }
  854. else
  855. {
  856. DebugMsg((DM_VERBOSE, TEXT("CPolicyComponentData::EnumerateScopePane: Empty user list.")));
  857. }
  858. }
  859. else
  860. {
  861. if (m_pMachineCategoryList)
  862. {
  863. pTemp = m_pMachineCategoryList->pChild;
  864. }
  865. else
  866. {
  867. DebugMsg((DM_VERBOSE, TEXT("CPolicyComponentData::EnumerateScopePane: Empty machine list.")));
  868. }
  869. }
  870. }
  871. //
  872. // If the user has set the focus on a adm node and then saves the console file,
  873. // the IComponent won't be created yet. We need to create a temporary IComponent
  874. // to parse the data and then release it.
  875. //
  876. if (m_pSnapin)
  877. {
  878. pSnapinTemp = m_pSnapin;
  879. }
  880. else
  881. {
  882. pSnapinTemp = pSnapin = new CPolicySnapIn(this);
  883. }
  884. while (pTemp)
  885. {
  886. if (pTemp->dwType == ETYPE_CATEGORY)
  887. {
  888. BOOL bAdd = TRUE;
  889. if (m_bUseSupportedOnFilter)
  890. {
  891. bAdd = IsAnyPolicyAllowedPastFilter(pTemp);
  892. }
  893. if (bAdd && m_bShowConfigPoliciesOnly)
  894. {
  895. if (pSnapinTemp)
  896. {
  897. bAdd = pSnapinTemp->IsAnyPolicyEnabled(pTemp);
  898. }
  899. }
  900. if (bAdd)
  901. {
  902. m_pScope->Expand(hParent);
  903. item.mask = SDI_STR | SDI_STATE | SDI_IMAGE | SDI_OPENIMAGE | SDI_PARAM | SDI_CHILDREN;
  904. item.displayname = MMC_CALLBACK;
  905. item.nImage = 0;
  906. item.nOpenImage = 1;
  907. item.nState = 0;
  908. item.cChildren = (CheckForChildCategories(pTemp) ? 1 : 0);
  909. item.lParam = (LPARAM) pTemp;
  910. item.relativeID = hParent;
  911. m_pScope->InsertItem (&item);
  912. }
  913. }
  914. pTemp = pTemp->pNext;
  915. }
  916. //
  917. // Add the Extra Registry Settings node if appropriate
  918. //
  919. if (bRootItem && m_pExtraSettingsRoot)
  920. {
  921. if (!m_bExtraSettingsInitialized)
  922. {
  923. InitializeExtraSettings();
  924. m_bExtraSettingsInitialized = TRUE;
  925. if (LOWORD(dwDebugLevel) == DL_VERBOSE)
  926. {
  927. DumpRSOPRegistryData();
  928. }
  929. }
  930. if (m_pExtraSettingsRoot->pChild)
  931. {
  932. m_pScope->Expand(hParent);
  933. item.mask = SDI_STR | SDI_STATE | SDI_IMAGE | SDI_OPENIMAGE | SDI_PARAM | SDI_CHILDREN;
  934. item.displayname = MMC_CALLBACK;
  935. item.nImage = 0;
  936. item.nOpenImage = 1;
  937. item.nState = 0;
  938. item.cChildren = 0;
  939. item.lParam = (LPARAM) m_pExtraSettingsRoot;
  940. item.relativeID = hParent;
  941. m_pScope->InsertItem (&item);
  942. }
  943. }
  944. if (pSnapin)
  945. {
  946. pSnapin->Release();
  947. }
  948. LeaveCriticalSection (&g_ADMCritSec);
  949. return S_OK;
  950. }
  951. BOOL CPolicyComponentData::CheckForChildCategories (TABLEENTRY *pParent)
  952. {
  953. TABLEENTRY * pTemp;
  954. if (pParent->pChild)
  955. {
  956. pTemp = pParent->pChild;
  957. while (pTemp)
  958. {
  959. if (pTemp->dwType == ETYPE_CATEGORY)
  960. {
  961. return TRUE;
  962. }
  963. pTemp = pTemp->pNext;
  964. }
  965. }
  966. return FALSE;
  967. }
  968. #if DBG
  969. //
  970. // These are a couple of debugging helper functions that will dump
  971. // the adm namespace to the debugger. Call DumpCurrentTable() to
  972. // get the full namespace.
  973. //
  974. VOID CPolicyComponentData::DumpEntry (TABLEENTRY * pEntry, UINT uIndent)
  975. {
  976. UINT i;
  977. TCHAR szDebug[50];
  978. if (!pEntry)
  979. return;
  980. if (pEntry == (TABLEENTRY*) ULongToPtr(0xfeeefeee))
  981. {
  982. OutputDebugString (TEXT("Invalid memory address found.\r\n"));
  983. return;
  984. }
  985. while (pEntry)
  986. {
  987. if ((pEntry->dwType & ETYPE_CATEGORY) || (pEntry->dwType & ETYPE_POLICY))
  988. {
  989. for (i=0; i<uIndent; i++)
  990. OutputDebugString(TEXT(" "));
  991. OutputDebugString (GETNAMEPTR(pEntry));
  992. if (pEntry->pNext && pEntry->pChild)
  993. StringCchPrintf (szDebug, ARRAYSIZE(szDebug), TEXT(" (0x%x, 0x%x)"),pEntry->pNext, pEntry->pChild);
  994. else if (!pEntry->pNext && pEntry->pChild)
  995. StringCchPrintf (szDebug, ARRAYSIZE(szDebug), TEXT(" (NULL, 0x%x)"),pEntry->pChild);
  996. else if (pEntry->pNext && !pEntry->pChild)
  997. StringCchPrintf (szDebug, ARRAYSIZE(szDebug), TEXT(" (0x%x, NULL)"),pEntry->pNext);
  998. OutputDebugString (szDebug);
  999. OutputDebugString (TEXT("\r\n"));
  1000. }
  1001. if (pEntry->pChild)
  1002. DumpEntry(pEntry->pChild, (uIndent + 4));
  1003. pEntry = pEntry->pNext;
  1004. }
  1005. }
  1006. VOID CPolicyComponentData::DumpCurrentTable (void)
  1007. {
  1008. OutputDebugString (TEXT("\r\n"));
  1009. OutputDebugString (TEXT("\r\n"));
  1010. DumpEntry (m_pListCurrent, 4);
  1011. OutputDebugString (TEXT("\r\n"));
  1012. OutputDebugString (TEXT("\r\n"));
  1013. }
  1014. #endif
  1015. VOID CPolicyComponentData::FreeTemplates (void)
  1016. {
  1017. EnterCriticalSection (&g_ADMCritSec);
  1018. if (m_pMachineCategoryList)
  1019. {
  1020. FreeTable(m_pMachineCategoryList);
  1021. m_pMachineCategoryList = NULL;
  1022. m_nMachineDataItems = 0;
  1023. }
  1024. if (m_pUserCategoryList)
  1025. {
  1026. FreeTable(m_pUserCategoryList);
  1027. m_pUserCategoryList = NULL;
  1028. m_nUserDataItems = 0;
  1029. }
  1030. if (m_pSupportedStrings)
  1031. {
  1032. FreeSupportedData(m_pSupportedStrings);
  1033. m_pSupportedStrings = NULL;
  1034. }
  1035. LeaveCriticalSection (&g_ADMCritSec);
  1036. }
  1037. ////////////////////////////////////////////////////////////////////////////
  1038. // //
  1039. // BOOL CPolicyComponentData::IsADMAutoUpdateDisabled() //
  1040. // //
  1041. // Purpose: Checks if autoupdate of ADM templates is disabled or not //
  1042. // //
  1043. // Returns: TRUE if autoupdate is disabled. //
  1044. // FALSE otherwise //
  1045. // //
  1046. ////////////////////////////////////////////////////////////////////////////
  1047. BOOL CPolicyComponentData::IsADMAutoUpdateDisabled(void)
  1048. {
  1049. BOOL bDisableAutoUpdate = FALSE;
  1050. HKEY hKey;
  1051. DWORD dwSize;
  1052. DWORD dwType;
  1053. if (RegOpenKeyEx (HKEY_CURRENT_USER, GPE_KEY, 0,
  1054. KEY_READ, &hKey) == ERROR_SUCCESS)
  1055. {
  1056. dwSize = sizeof(bDisableAutoUpdate);
  1057. RegQueryValueEx (hKey, DISABLE_AUTOUPDATE_VALUE, NULL, &dwType,
  1058. (LPBYTE) &bDisableAutoUpdate, &dwSize);
  1059. RegCloseKey (hKey);
  1060. }
  1061. if (RegOpenKeyEx (HKEY_CURRENT_USER, GPE_POLICIES_KEY, 0,
  1062. KEY_READ, &hKey) == ERROR_SUCCESS)
  1063. {
  1064. dwSize = sizeof(bDisableAutoUpdate);
  1065. RegQueryValueEx (hKey, DISABLE_AUTOUPDATE_VALUE, NULL, &dwType,
  1066. (LPBYTE) &bDisableAutoUpdate, &dwSize);
  1067. RegCloseKey (hKey);
  1068. }
  1069. if (bDisableAutoUpdate)
  1070. {
  1071. DebugMsg((DM_VERBOSE, TEXT("IsADMAutoUpdateDisabled: Automatic update of ADM files is disabled.")));
  1072. return TRUE;
  1073. }
  1074. return FALSE;
  1075. }
  1076. DWORD CPolicyComponentData::LoadTemplatesThread (CPolicyComponentData * pCD)
  1077. {
  1078. HRESULT hr;
  1079. HINSTANCE hInstDLL;
  1080. hInstDLL = LoadLibrary (TEXT("gptext.dll"));
  1081. Sleep(0);
  1082. hr = pCD->LoadTemplates();
  1083. if (hInstDLL)
  1084. {
  1085. FreeLibraryAndExitThread (hInstDLL, (DWORD) hr);
  1086. }
  1087. return (DWORD)hr;
  1088. }
  1089. void CPolicyComponentData::AddTemplates(LPTSTR lpDest, LPCTSTR lpValueName, UINT idRes)
  1090. {
  1091. TCHAR szFiles[MAX_PATH];
  1092. TCHAR szSrc[MAX_PATH];
  1093. TCHAR szDest[MAX_PATH];
  1094. TCHAR szLogFile[MAX_PATH];
  1095. LPTSTR lpTemp, lpFileName, lpSrc, lpEnd;
  1096. HKEY hKey;
  1097. DWORD dwSize, dwType;
  1098. HRESULT hr = S_OK;
  1099. //
  1100. // Add the adm files. We get this list from 3 possible
  1101. // places. The resources, user preferences, policy.
  1102. //
  1103. hr = StringCchCopy (szDest, ARRAYSIZE(szDest), lpDest);
  1104. ASSERT(SUCCEEDED(hr));
  1105. lpEnd = CheckSlash (szDest);
  1106. hr = StringCchCopy (szLogFile, ARRAYSIZE(szLogFile), lpDest);
  1107. ASSERT(SUCCEEDED(hr));
  1108. hr = StringCchCat (szLogFile, ARRAYSIZE(szLogFile), TEXT("\\admfiles.ini"));
  1109. ASSERT(SUCCEEDED(hr));
  1110. ExpandEnvironmentStrings (TEXT("%SystemRoot%\\Inf"), szSrc, ARRAYSIZE(szSrc));
  1111. lpSrc = CheckSlash (szSrc);
  1112. ZeroMemory (szFiles, sizeof(szFiles));
  1113. LoadString (g_hInstance, idRes, szFiles,
  1114. ARRAYSIZE(szFiles));
  1115. if (RegOpenKeyEx (HKEY_CURRENT_USER, szUserPrefKey, 0,
  1116. KEY_READ, &hKey) == ERROR_SUCCESS)
  1117. {
  1118. dwSize = sizeof(szFiles);
  1119. RegQueryValueEx (hKey, lpValueName, NULL, &dwType,
  1120. (LPBYTE) szFiles, &dwSize);
  1121. RegCloseKey (hKey);
  1122. }
  1123. if (RegOpenKeyEx (HKEY_CURRENT_USER, szPoliciesKey, 0,
  1124. KEY_READ, &hKey) == ERROR_SUCCESS)
  1125. {
  1126. dwSize = sizeof(szFiles);
  1127. RegQueryValueEx (hKey, lpValueName, NULL, &dwType,
  1128. (LPBYTE) szFiles, &dwSize);
  1129. RegCloseKey (hKey);
  1130. }
  1131. //
  1132. // Parse off the filenames
  1133. //
  1134. lpTemp = lpFileName = szFiles;
  1135. while (*lpTemp)
  1136. {
  1137. while (*lpTemp && (*lpTemp != TEXT(';')))
  1138. lpTemp++;
  1139. if (*lpTemp == TEXT(';'))
  1140. {
  1141. *lpTemp = TEXT('\0');
  1142. lpTemp++;
  1143. }
  1144. while (*lpFileName == TEXT(' '))
  1145. lpFileName++;
  1146. hr = StringCchCopy (lpEnd, ARRAYSIZE(szDest) - (lpEnd - szDest), lpFileName);
  1147. ASSERT(SUCCEEDED(hr));
  1148. hr = StringCchCopy (lpSrc, ARRAYSIZE(szSrc) - (lpSrc - szSrc), lpFileName);
  1149. ASSERT(SUCCEEDED(hr));
  1150. //
  1151. // Check if this file is already in the admfile.ini log
  1152. // If so, skip it
  1153. //
  1154. if (!GetPrivateProfileInt (TEXT("FileList"), lpFileName, 0, szLogFile))
  1155. {
  1156. if (CopyFile (szSrc, szDest, FALSE))
  1157. {
  1158. DebugMsg((DM_VERBOSE, TEXT("CPolicyComponentData::AddTemplates: Successfully copied %s to %s."), szSrc, szDest));
  1159. WritePrivateProfileString (TEXT("FileList"), lpFileName, TEXT("1"), szLogFile);
  1160. }
  1161. else
  1162. {
  1163. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::AddTemplates: Failed to copy %s to %s with %d."), szSrc, szDest, GetLastError()));
  1164. }
  1165. }
  1166. lpFileName = lpTemp;
  1167. }
  1168. SetFileAttributes (szLogFile, FILE_ATTRIBUTE_HIDDEN);
  1169. }
  1170. void CPolicyComponentData::AddDefaultTemplates(LPTSTR lpDest)
  1171. {
  1172. AddTemplates (lpDest, szDefaultTemplates, IDS_DEFAULTTEMPLATES);
  1173. }
  1174. void CPolicyComponentData::AddNewADMsToExistingGPO (LPTSTR lpDest)
  1175. {
  1176. TCHAR szLogFile[MAX_PATH];
  1177. WIN32_FILE_ATTRIBUTE_DATA fad;
  1178. HRESULT hr = S_OK;
  1179. //
  1180. // This method will add any new adm files to a GPO.
  1181. //
  1182. // Note: the admfiles.ini file is new post-W2k, so we have to do a special
  1183. // case when upgrading a GPO created by w2k to create that file and add
  1184. // the default filenames
  1185. //
  1186. hr = StringCchCopy (szLogFile, ARRAYSIZE(szLogFile), lpDest);
  1187. ASSERT(SUCCEEDED(hr));
  1188. hr = StringCchCat (szLogFile, ARRAYSIZE(szLogFile), TEXT("\\admfiles.ini"));
  1189. ASSERT(SUCCEEDED(hr));
  1190. if (!GetFileAttributesEx (szLogFile, GetFileExInfoStandard, &fad))
  1191. {
  1192. WritePrivateProfileString (TEXT("FileList"), TEXT("system.adm"), TEXT("1"), szLogFile);
  1193. WritePrivateProfileString (TEXT("FileList"), TEXT("inetres.adm"), TEXT("1"), szLogFile);
  1194. WritePrivateProfileString (TEXT("FileList"), TEXT("conf.adm"), TEXT("1"), szLogFile);
  1195. }
  1196. AddTemplates (lpDest, szAdditionalTemplates, IDS_ADDITIONALTTEMPLATES);
  1197. }
  1198. HRESULT CPolicyComponentData::CreateAdmIniFile (WCHAR *szAdmDirPath)
  1199. {
  1200. WCHAR szIniFilePath[MAX_PATH];
  1201. WCHAR szFileList[MAX_PATH];
  1202. WCHAR *lpStart;
  1203. WCHAR *lpCharLoc;
  1204. HRESULT hr;
  1205. hr = StringCchCopy(szIniFilePath, ARRAYSIZE(szIniFilePath), szAdmDirPath);
  1206. if (FAILED(hr))
  1207. {
  1208. return hr;
  1209. }
  1210. if (lstrlen (szIniFilePath) < MAX_PATH - 1)
  1211. {
  1212. CheckSlash (szIniFilePath);
  1213. }
  1214. else
  1215. {
  1216. return STRSAFE_E_INSUFFICIENT_BUFFER;
  1217. }
  1218. hr = StringCchCat (szIniFilePath, ARRAYSIZE(szIniFilePath), L"admfiles.ini");
  1219. if (FAILED(hr))
  1220. {
  1221. return hr;
  1222. }
  1223. if (LoadString (g_hInstance, IDS_DEFAULTTEMPLATES, szFileList, ARRAYSIZE(szFileList)) == 0)
  1224. {
  1225. return HRESULT_FROM_WIN32(GetLastError());
  1226. }
  1227. lpStart = szFileList;
  1228. lpCharLoc = szFileList;
  1229. while (lpCharLoc)
  1230. {
  1231. lpCharLoc = wcschr (lpStart, L';');
  1232. if (lpCharLoc)
  1233. {
  1234. *lpCharLoc = L'\0';
  1235. }
  1236. if (!WritePrivateProfileString (L"FileList", lpStart, L"1", szIniFilePath))
  1237. {
  1238. return HRESULT_FROM_WIN32(GetLastError());
  1239. }
  1240. if (lpCharLoc)
  1241. {
  1242. lpStart = lpCharLoc + 1;
  1243. }
  1244. }
  1245. (void) SetFileAttributes (szIniFilePath, FILE_ATTRIBUTE_HIDDEN);
  1246. return S_OK;
  1247. }
  1248. void CPolicyComponentData::UpdateExistingTemplates(LPTSTR lpDest)
  1249. {
  1250. WIN32_FILE_ATTRIBUTE_DATA fadSrc, fadDest;
  1251. TCHAR szSrc[MAX_PATH];
  1252. TCHAR szDest[MAX_PATH];
  1253. LPTSTR lpSrc, lpEnd;
  1254. WIN32_FIND_DATA fd;
  1255. HANDLE hFindFile;
  1256. HRESULT hr = S_OK;
  1257. //
  1258. // Add any new adm files shipped with the OS
  1259. //
  1260. AddNewADMsToExistingGPO (lpDest);
  1261. //
  1262. // Build the path to the source directory
  1263. //
  1264. ExpandEnvironmentStrings (TEXT("%SystemRoot%\\Inf"), szSrc, ARRAYSIZE(szSrc));
  1265. lpSrc = CheckSlash (szSrc);
  1266. //
  1267. // Build the path to the destination directory
  1268. //
  1269. hr = StringCchCopy (szDest, ARRAYSIZE(szDest), lpDest);
  1270. ASSERT(SUCCEEDED(hr));
  1271. lpEnd = CheckSlash (szDest);
  1272. hr = StringCchCopy (lpEnd, ARRAYSIZE(szDest) - (lpEnd - szDest), TEXT("*.adm"));
  1273. ASSERT(SUCCEEDED(hr));
  1274. //
  1275. // Enumerate the files
  1276. //
  1277. hFindFile = FindFirstFile(szDest, &fd);
  1278. if (hFindFile != INVALID_HANDLE_VALUE)
  1279. {
  1280. do
  1281. {
  1282. if (!(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
  1283. {
  1284. hr = StringCchCopy (lpEnd, ARRAYSIZE(szDest) - (lpEnd - szDest), fd.cFileName);
  1285. ASSERT(SUCCEEDED(hr));
  1286. hr = StringCchCopy (lpSrc, ARRAYSIZE(szSrc) - (lpSrc - szSrc), fd.cFileName);
  1287. ASSERT(SUCCEEDED(hr));
  1288. //
  1289. // Get the file attributes of the source and destination
  1290. //
  1291. ZeroMemory (&fadSrc, sizeof(fadSrc));
  1292. ZeroMemory (&fadDest, sizeof(fadDest));
  1293. GetFileAttributesEx (szSrc, GetFileExInfoStandard, &fadSrc);
  1294. GetFileAttributesEx (szDest, GetFileExInfoStandard, &fadDest);
  1295. //
  1296. // If the source is a newer than the dest
  1297. // copy the .adm file
  1298. //
  1299. BOOL bUpdateNeeded;
  1300. bUpdateNeeded = FALSE;
  1301. //
  1302. // Check the time stamp to see if the
  1303. // source is newer than the destination -- if so, an update is needed
  1304. //
  1305. if (CompareFileTime(&fadSrc.ftLastWriteTime, &fadDest.ftLastWriteTime) == 1)
  1306. {
  1307. bUpdateNeeded = TRUE;
  1308. }
  1309. if ( bUpdateNeeded )
  1310. {
  1311. if (CopyFile (szSrc, szDest, FALSE))
  1312. DebugMsg((DM_VERBOSE, TEXT("CPolicyComponentData::UpdateExistingTemplates: Successfully copied %s to %s."), szSrc, szDest));
  1313. else
  1314. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::UpdateExistingTemplates: Failed to copy %s to %s with %d."), szSrc, szDest, GetLastError()));
  1315. }
  1316. }
  1317. } while (FindNextFile(hFindFile, &fd));
  1318. FindClose(hFindFile);
  1319. }
  1320. }
  1321. HRESULT CPolicyComponentData::LoadGPOTemplates (void)
  1322. {
  1323. LPTSTR lpEnd;
  1324. UINT iResult;
  1325. HKEY hAdmKey;
  1326. DWORD dwError;
  1327. DWORD dwRegVal = 0;
  1328. DWORD dwSize;
  1329. TCHAR szPath[MAX_PATH];
  1330. BOOL bADMAutoUpdateDisabled = FALSE;
  1331. BOOL bReadFromINF = FALSE;
  1332. HRESULT hr;
  1333. //
  1334. // Get the path to the GPO directory in sysvol
  1335. //
  1336. hr = m_pGPTInformation->GetFileSysPath(GPO_SECTION_ROOT, szPath, MAX_PATH);
  1337. if (FAILED(hr))
  1338. {
  1339. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::LoadGPOTemplates: Failed to get gpt path.")));
  1340. return hr;
  1341. }
  1342. //
  1343. // Build the ADM path name
  1344. //
  1345. (void) CheckSlash (szPath);
  1346. hr = StringCchCat (szPath, ARRAYSIZE(szPath), g_szADM);
  1347. if (FAILED(hr))
  1348. {
  1349. return hr;
  1350. }
  1351. //
  1352. // Create ADM directory, if it doesn't exist
  1353. //
  1354. iResult = CreateNestedDirectory (szPath, NULL);
  1355. if (!iResult)
  1356. {
  1357. return E_FAIL;
  1358. }
  1359. //
  1360. // Check if adm use local adm policy is set
  1361. //
  1362. dwError = RegOpenKeyEx(HKEY_LOCAL_MACHINE, ADM_USELOCAL_KEY, 0, KEY_EXECUTE, &hAdmKey);
  1363. if ( ERROR_SUCCESS == dwError )
  1364. {
  1365. dwSize = sizeof(DWORD);
  1366. dwError = RegQueryValueEx(hAdmKey, ADM_USELOCAL_VALUE, NULL, NULL, (LPBYTE) &dwRegVal, &dwSize);
  1367. if ( ERROR_SUCCESS == dwError && 1 == dwRegVal)
  1368. {
  1369. bReadFromINF = TRUE;
  1370. }
  1371. RegCloseKey(hAdmKey);
  1372. }
  1373. if (!bReadFromINF)
  1374. {
  1375. //
  1376. // Check if the user wants their ADM files updated automatically
  1377. //
  1378. bADMAutoUpdateDisabled = IsADMAutoUpdateDisabled();
  1379. if (bADMAutoUpdateDisabled)
  1380. {
  1381. if (1 == iResult)
  1382. {
  1383. //
  1384. // Empty ADM directory is created. Read from INF
  1385. //
  1386. bReadFromINF = TRUE;
  1387. }
  1388. else
  1389. {
  1390. //
  1391. // Check if any files of type *.adm exists
  1392. // If not, read from INF directory
  1393. //
  1394. hr = IsFilePresent (szPath, L"*.adm");
  1395. if (SUCCEEDED(hr))
  1396. {
  1397. if (S_FALSE == hr)
  1398. {
  1399. bReadFromINF = TRUE;
  1400. }
  1401. }
  1402. else
  1403. {
  1404. return hr;
  1405. }
  1406. }
  1407. }
  1408. else
  1409. {
  1410. if (1 == iResult)
  1411. {
  1412. DebugMsg((DM_VERBOSE, TEXT("CPolicyComponentData::LoadGPOTemplates: adding default templates")));
  1413. AddDefaultTemplates(szPath);
  1414. }
  1415. else
  1416. {
  1417. DebugMsg((DM_VERBOSE, TEXT("CPolicyComponentData::LoadGPOTemplates: Updating templates")));
  1418. UpdateExistingTemplates(szPath);
  1419. DebugMsg((DM_VERBOSE, TEXT("CPolicyComponentData::LoadGPOTemplates: Finished updating templates")));
  1420. }
  1421. }
  1422. }
  1423. if (bReadFromINF)
  1424. {
  1425. //
  1426. // Create admfiles.ini file if Adm file is created
  1427. // This need not be done when update is done since
  1428. // AddDefaultTemplates function creates this file.
  1429. //
  1430. if (1 == iResult)
  1431. {
  1432. hr = CreateAdmIniFile (szPath);
  1433. if (FAILED(hr))
  1434. {
  1435. return hr;
  1436. }
  1437. }
  1438. DebugMsg((DM_VERBOSE, TEXT("CPolicyComponentData::LoadGPOTemplates: Reading from inf")));
  1439. iResult = ExpandEnvironmentStrings ( L"%SystemRoot%\\inf", szPath, MAX_PATH);
  1440. if (0 == iResult )
  1441. {
  1442. dwError = GetLastError();
  1443. return (HRESULT_FROM_WIN32(dwError));
  1444. }
  1445. }
  1446. //
  1447. // Enumerate the files
  1448. //
  1449. lpEnd = CheckSlash (szPath);
  1450. hr = StringCchCopy (lpEnd, ARRAYSIZE(szPath) - (lpEnd - szPath), TEXT("*.adm"));
  1451. if (FAILED(hr))
  1452. {
  1453. return hr;
  1454. }
  1455. HANDLE hFindFile;
  1456. WIN32_FIND_DATA fd;
  1457. hFindFile = FindFirstFile(szPath, &fd);
  1458. if (hFindFile != INVALID_HANDLE_VALUE)
  1459. {
  1460. do
  1461. {
  1462. if (!(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
  1463. {
  1464. hr = StringCchCopy (lpEnd, ARRAYSIZE(szPath) - (lpEnd - szPath), fd.cFileName);
  1465. if (FAILED(hr))
  1466. {
  1467. FindClose(hFindFile);
  1468. return hr;
  1469. }
  1470. ParseTemplate (szPath);
  1471. }
  1472. } while (FindNextFile(hFindFile, &fd));
  1473. FindClose(hFindFile);
  1474. }
  1475. return S_OK;
  1476. }
  1477. #define WINLOGON_KEY TEXT("Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon")
  1478. #define SYSTEM_POLICIES_KEY TEXT("Software\\Policies\\Microsoft\\Windows\\System")
  1479. #define SLOW_LINK_TRANSFER_RATE 500 // Kbps
  1480. BOOL CPolicyComponentData::IsSlowLink (LPTSTR lpFileName)
  1481. {
  1482. LPTSTR lpComputerName = NULL, lpTemp;
  1483. LPSTR lpComputerNameA = NULL;
  1484. BOOL bResult = FALSE;
  1485. DWORD dwSize, dwResult, dwType;
  1486. struct hostent *hostp;
  1487. ULONG inaddr, ulSpeed, ulTransferRate;
  1488. LONG lResult;
  1489. HKEY hKey;
  1490. HRESULT hr = S_OK;
  1491. DWORD dwLen = 0;
  1492. //
  1493. // Get the slow timeout
  1494. //
  1495. ulTransferRate = SLOW_LINK_TRANSFER_RATE;
  1496. lResult = RegOpenKeyEx(HKEY_CURRENT_USER,
  1497. WINLOGON_KEY,
  1498. 0,
  1499. KEY_READ,
  1500. &hKey);
  1501. if (lResult == ERROR_SUCCESS)
  1502. {
  1503. dwSize = sizeof(ulTransferRate);
  1504. RegQueryValueEx (hKey,
  1505. TEXT("GroupPolicyMinTransferRate"),
  1506. NULL,
  1507. &dwType,
  1508. (LPBYTE) &ulTransferRate,
  1509. &dwSize);
  1510. RegCloseKey (hKey);
  1511. }
  1512. lResult = RegOpenKeyEx(HKEY_CURRENT_USER,
  1513. SYSTEM_POLICIES_KEY,
  1514. 0,
  1515. KEY_READ,
  1516. &hKey);
  1517. if (lResult == ERROR_SUCCESS)
  1518. {
  1519. dwSize = sizeof(ulTransferRate);
  1520. RegQueryValueEx (hKey,
  1521. TEXT("GroupPolicyMinTransferRate"),
  1522. NULL,
  1523. &dwType,
  1524. (LPBYTE) &ulTransferRate,
  1525. &dwSize);
  1526. RegCloseKey (hKey);
  1527. }
  1528. //
  1529. // If the transfer rate is 0, then always download adm files
  1530. //
  1531. if (!ulTransferRate)
  1532. {
  1533. DebugMsg((DM_VERBOSE, TEXT("CPolicyComponentData::IsSlowLink: Slow link transfer rate is 0. Always download adm files.")));
  1534. goto Exit;
  1535. }
  1536. //
  1537. // Copy the namespace to a buffer we can edit and drop the leading \\ if present
  1538. //
  1539. dwLen = lstrlen(lpFileName) + 1;
  1540. lpComputerName = (LPTSTR) LocalAlloc (LPTR, (dwLen) * sizeof(TCHAR));
  1541. if (!lpComputerName)
  1542. {
  1543. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::IsSlowLink: Failed to allocate memory for computer name with %d"),
  1544. GetLastError()));
  1545. goto Exit;
  1546. }
  1547. if ((*lpFileName == TEXT('\\')) && (*(lpFileName+1) == TEXT('\\')))
  1548. {
  1549. hr = StringCchCopy (lpComputerName, dwLen, (lpFileName+2));
  1550. }
  1551. else
  1552. {
  1553. hr = StringCchCopy (lpComputerName, dwLen, lpFileName);
  1554. }
  1555. ASSERT(SUCCEEDED(hr));
  1556. //
  1557. // Find the slash between the computer name and the share name and replace it with null
  1558. //
  1559. lpTemp = lpComputerName;
  1560. while (*lpTemp && (*lpTemp != TEXT('\\')))
  1561. {
  1562. lpTemp++;
  1563. }
  1564. if (!(*lpTemp))
  1565. {
  1566. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::IsSlowLink: Didn't find slash between computer name and share name in %s"),
  1567. lpComputerName));
  1568. goto Exit;
  1569. }
  1570. *lpTemp = TEXT('\0');
  1571. //
  1572. // Allocate a buffer for the ANSI name
  1573. //
  1574. // Note this buffer is allocated twice as large so handle DBCS characters
  1575. //
  1576. dwSize = (lstrlen(lpComputerName) + 1) * 2;
  1577. lpComputerNameA = (LPSTR) LocalAlloc (LPTR, dwSize);
  1578. if (!lpComputerNameA)
  1579. {
  1580. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::IsSlowLink: Failed to allocate memory for ansi computer name with %d"),
  1581. GetLastError()));
  1582. goto Exit;
  1583. }
  1584. //
  1585. // Convert the computer name to ANSI
  1586. //
  1587. if (WideCharToMultiByte (CP_ACP, 0, lpComputerName, -1, lpComputerNameA, dwSize, NULL, NULL))
  1588. {
  1589. //
  1590. // Get the host information for the computer
  1591. //
  1592. hostp = gethostbyname(lpComputerNameA);
  1593. if (hostp)
  1594. {
  1595. //
  1596. // Get the ip address of the computer
  1597. //
  1598. inaddr = *(long *)hostp->h_addr;
  1599. //
  1600. // Get the transfer rate
  1601. //
  1602. dwResult = PingComputer (inaddr, &ulSpeed);
  1603. if (dwResult == ERROR_SUCCESS)
  1604. {
  1605. if (ulSpeed)
  1606. {
  1607. //
  1608. // If the delta time is greater that the timeout time, then this
  1609. // is a slow link.
  1610. //
  1611. if (ulSpeed < ulTransferRate)
  1612. {
  1613. bResult = TRUE;
  1614. }
  1615. }
  1616. }
  1617. else {
  1618. DebugMsg((DM_VERBOSE, TEXT("CPolicyComponentData::IsSlowLink: PingComputer failed with error %d. Treat it as slow link"), dwResult));
  1619. bResult = TRUE;
  1620. }
  1621. }
  1622. }
  1623. Exit:
  1624. if (lpComputerName)
  1625. {
  1626. LocalFree (lpComputerName);
  1627. }
  1628. if (lpComputerNameA)
  1629. {
  1630. LocalFree (lpComputerNameA);
  1631. }
  1632. return bResult;
  1633. }
  1634. HRESULT CPolicyComponentData::AddADMFile (LPTSTR lpFileName, LPTSTR lpFullFileName,
  1635. FILETIME *pFileTime, DWORD dwErr, LPRSOPADMFILE *lpHead)
  1636. {
  1637. LPRSOPADMFILE lpTemp;
  1638. HRESULT hr = S_OK;
  1639. //
  1640. // First, check if this file is already in the link list
  1641. //
  1642. lpTemp = *lpHead;
  1643. while (lpTemp)
  1644. {
  1645. if (!lstrcmpi(lpFileName, lpTemp->szFileName))
  1646. {
  1647. if (CompareFileTime(pFileTime, &lpTemp->FileTime) == 1)
  1648. {
  1649. hr = StringCchCopy (lpTemp->szFullFileName, ARRAYSIZE(lpTemp->szFullFileName), lpFullFileName);
  1650. if(FAILED(hr))
  1651. return hr;
  1652. lpTemp->FileTime.dwLowDateTime = pFileTime->dwLowDateTime;
  1653. lpTemp->FileTime.dwHighDateTime = pFileTime->dwHighDateTime;
  1654. }
  1655. return S_OK;
  1656. }
  1657. lpTemp = lpTemp->pNext;
  1658. }
  1659. //
  1660. // Add a new node
  1661. //
  1662. lpTemp = (LPRSOPADMFILE) LocalAlloc (LPTR, sizeof(RSOPADMFILE));
  1663. if (!lpTemp)
  1664. {
  1665. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::AddADMFile: Failed to allocate memory for adm file node")));
  1666. return (HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY));
  1667. }
  1668. hr = StringCchCopy (lpTemp->szFileName, ARRAYSIZE(lpTemp->szFileName), lpFileName);
  1669. if (FAILED(hr))
  1670. {
  1671. LocalFree(lpTemp);
  1672. return hr;
  1673. }
  1674. hr = StringCchCopy (lpTemp->szFullFileName, ARRAYSIZE(lpTemp->szFullFileName), lpFullFileName);
  1675. if (FAILED(hr))
  1676. {
  1677. LocalFree(lpTemp);
  1678. return hr;
  1679. }
  1680. lpTemp->FileTime.dwLowDateTime = pFileTime->dwLowDateTime;
  1681. lpTemp->FileTime.dwHighDateTime = pFileTime->dwHighDateTime;
  1682. lpTemp->dwError = dwErr;
  1683. lpTemp->pNext = *lpHead;
  1684. *lpHead = lpTemp;
  1685. return S_OK;
  1686. }
  1687. ///////////////////////////////////////////////////////////////////////////
  1688. // //
  1689. // HRESULT CPolicyComponentData::GetLocalADMFiles(LPRSOPADMFILE *lpHead) //
  1690. // //
  1691. // Purpose: Prepares a list of the *.adm filees present in %windir%\inf //
  1692. // directory //
  1693. // //
  1694. // Parameters: //
  1695. // lpHead [IN OUT] - Linked list containing list of file names //
  1696. // //
  1697. ////////////////////////////////////////////////////////////////////////////
  1698. HRESULT CPolicyComponentData::GetLocalADMFiles(
  1699. LPRSOPADMFILE *lpHead)
  1700. {
  1701. WCHAR szPath[MAX_PATH];
  1702. WCHAR szFileName[MAX_PATH];
  1703. WCHAR szFullFileName[MAX_PATH];
  1704. WCHAR *pTemp;
  1705. HANDLE hFindFile;
  1706. HRESULT hr;
  1707. FILETIME FileTime;
  1708. WIN32_FIND_DATA fd;
  1709. ExpandEnvironmentStrings (L"%SystemRoot%\\Inf", szPath, ARRAYSIZE(szPath));
  1710. pTemp = CheckSlash (szPath);
  1711. hr = StringCchCopy (pTemp, ARRAYSIZE(szPath) - (pTemp - szPath), L"*.adm");
  1712. ASSERT(SUCCEEDED(hr));
  1713. FileTime.dwLowDateTime = 0;
  1714. FileTime.dwHighDateTime = 0;
  1715. //
  1716. // Enumerate the files
  1717. //
  1718. hFindFile = FindFirstFile(szPath, &fd);
  1719. if (hFindFile != INVALID_HANDLE_VALUE)
  1720. {
  1721. do
  1722. {
  1723. if (!(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
  1724. {
  1725. hr = StringCchCopy (szFileName, ARRAYSIZE(szFileName), fd.cFileName);
  1726. if (FAILED(hr))
  1727. {
  1728. FindClose(hFindFile);
  1729. return hr;
  1730. }
  1731. ExpandEnvironmentStrings (L"%SystemRoot%\\Inf\\", szFullFileName, ARRAYSIZE(szPath));
  1732. hr = StringCchCat (szFullFileName, ARRAYSIZE(szFileName), szFileName);
  1733. if (FAILED(hr))
  1734. {
  1735. FindClose(hFindFile);
  1736. return hr;
  1737. }
  1738. hr = AddADMFile (szFileName, szFullFileName, &FileTime, 0, lpHead);
  1739. if (FAILED(hr))
  1740. {
  1741. FindClose(hFindFile);
  1742. return hr;
  1743. }
  1744. }
  1745. } while (FindNextFile(hFindFile, &fd));
  1746. FindClose(hFindFile);
  1747. }
  1748. return S_OK;
  1749. }
  1750. HRESULT CPolicyComponentData::LoadRSOPTemplates (void)
  1751. {
  1752. BSTR pLanguage = NULL, pQuery = NULL;
  1753. BSTR pName = NULL, pLastWriteTime = NULL, pNamespace = NULL;
  1754. IEnumWbemClassObject * pEnum = NULL;
  1755. IWbemClassObject *pObjects[2];
  1756. HRESULT hr;
  1757. ULONG ulRet;
  1758. VARIANT varName, varLastWriteTime;
  1759. IWbemLocator *pIWbemLocator = NULL;
  1760. IWbemServices *pIWbemServices = NULL;
  1761. SYSTEMTIME SysTime;
  1762. FILETIME FileTime;
  1763. LPTSTR lpFileName;
  1764. LPRSOPADMFILE lpADMFiles = NULL, lpTemp, lpDelete, lpFailedAdmFiles = NULL;
  1765. DWORD dwFailedAdm = 0;
  1766. XBStr xbstrWbemTime;
  1767. DWORD dwError;
  1768. TCHAR szPath[MAX_PATH];
  1769. BOOL bSlowLink = FALSE;
  1770. DebugMsg((DM_VERBOSE, TEXT("CPolicyComponentData::LoadRSOPTemplates: Entering")));
  1771. CoInitialize(NULL);
  1772. //
  1773. // First get the local ADM files
  1774. // Any ADM Files found in the sysvol will be overwrite local ADM files
  1775. //
  1776. GetLocalADMFiles(&lpADMFiles);
  1777. //
  1778. // Allocate BSTRs for the query language and for the query itself
  1779. //
  1780. pLanguage = SysAllocString (TEXT("WQL"));
  1781. if (!pLanguage)
  1782. {
  1783. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::LoadRSOPTemplates: Failed to allocate memory for language")));
  1784. hr = HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY);
  1785. goto Exit;
  1786. }
  1787. pQuery = SysAllocString (TEXT("SELECT name, lastWriteTime FROM RSOP_AdministrativeTemplateFile"));
  1788. if (!pQuery)
  1789. {
  1790. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::LoadRSOPTemplates: Failed to allocate memory for query")));
  1791. hr = HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY);
  1792. goto Exit;
  1793. }
  1794. //
  1795. // Allocate BSTRs for the property names we want to retreive
  1796. //
  1797. pName = SysAllocString (TEXT("name"));
  1798. if (!pName)
  1799. {
  1800. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::LoadRSOPTemplates: Failed to allocate memory for name")));
  1801. hr = HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY);
  1802. goto Exit;
  1803. }
  1804. pLastWriteTime = SysAllocString (TEXT("lastWriteTime"));
  1805. if (!pLastWriteTime)
  1806. {
  1807. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::LoadRSOPTemplates: Failed to allocate memory for last write time")));
  1808. hr = HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY);
  1809. goto Exit;
  1810. }
  1811. //
  1812. // Create an instance of the WMI locator service
  1813. //
  1814. hr = CoCreateInstance(CLSID_WbemLocator, NULL, CLSCTX_INPROC_SERVER,
  1815. IID_IWbemLocator, (LPVOID *) &pIWbemLocator);
  1816. if (FAILED(hr))
  1817. {
  1818. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::LoadRSOPTemplates: CoCreateInstance failed with 0x%x"), hr));
  1819. goto Exit;
  1820. }
  1821. //
  1822. // Allocate a BSTR for the namespace
  1823. //
  1824. pNamespace = SysAllocString (m_pszNamespace);
  1825. if (!pNamespace)
  1826. {
  1827. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::LoadRSOPTemplates: Failed to allocate memory for namespace")));
  1828. hr = HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY);
  1829. goto Exit;
  1830. }
  1831. //
  1832. // Connect to the server
  1833. //
  1834. hr = pIWbemLocator->ConnectServer(pNamespace, NULL, NULL, 0L, 0L, NULL, NULL,
  1835. &pIWbemServices);
  1836. if (FAILED(hr))
  1837. {
  1838. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::LoadRSOPTemplates: ConnectServer failed with 0x%x"), hr));
  1839. goto Exit;
  1840. }
  1841. // Set the proper security to encrypt the data
  1842. hr = CoSetProxyBlanket(pIWbemServices,
  1843. RPC_C_AUTHN_DEFAULT,
  1844. RPC_C_AUTHZ_DEFAULT,
  1845. COLE_DEFAULT_PRINCIPAL,
  1846. RPC_C_AUTHN_LEVEL_PKT_PRIVACY,
  1847. RPC_C_IMP_LEVEL_IMPERSONATE,
  1848. NULL,
  1849. 0);
  1850. if (FAILED(hr))
  1851. {
  1852. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::LoadRSOPTemplates: CoSetProxyBlanket failed with 0x%x"), hr));
  1853. goto Exit;
  1854. }
  1855. //
  1856. // Execute the query
  1857. //
  1858. hr = pIWbemServices->ExecQuery (pLanguage, pQuery,
  1859. WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
  1860. NULL, &pEnum);
  1861. if (FAILED(hr))
  1862. {
  1863. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::LoadRSOPTemplates: Failed to query for %s with 0x%x"),
  1864. pQuery, hr));
  1865. goto Exit;
  1866. }
  1867. //
  1868. // Loop through the results
  1869. //
  1870. while (pEnum->Next(WBEM_INFINITE, 1, pObjects, &ulRet) == S_OK)
  1871. {
  1872. //
  1873. // Check for the "data not available case"
  1874. //
  1875. if (ulRet == 0)
  1876. {
  1877. hr = S_OK;
  1878. goto Exit;
  1879. }
  1880. //
  1881. // Get the name
  1882. //
  1883. hr = pObjects[0]->Get (pName, 0, &varName, NULL, NULL);
  1884. if (SUCCEEDED(hr))
  1885. {
  1886. //
  1887. // Get the last write time
  1888. //
  1889. hr = pObjects[0]->Get (pLastWriteTime, 0, &varLastWriteTime, NULL, NULL);
  1890. if (SUCCEEDED(hr))
  1891. {
  1892. xbstrWbemTime = varLastWriteTime.bstrVal;
  1893. hr = WbemTimeToSystemTime(xbstrWbemTime, SysTime);
  1894. if (SUCCEEDED(hr))
  1895. {
  1896. SystemTimeToFileTime (&SysTime, &FileTime);
  1897. lpFileName = varName.bstrVal + lstrlen(varName.bstrVal);
  1898. while ((lpFileName > varName.bstrVal) && (*lpFileName != TEXT('\\')))
  1899. lpFileName--;
  1900. if (*lpFileName == TEXT('\\'))
  1901. {
  1902. lpFileName++;
  1903. }
  1904. AddADMFile (lpFileName, varName.bstrVal, &FileTime, 0, &lpADMFiles);
  1905. }
  1906. VariantClear (&varLastWriteTime);
  1907. }
  1908. VariantClear (&varName);
  1909. }
  1910. pObjects[0]->Release();
  1911. }
  1912. //
  1913. // Parse the adm files
  1914. //
  1915. lpTemp = lpADMFiles;
  1916. while (lpTemp)
  1917. {
  1918. SetLastError(ERROR_SUCCESS);
  1919. if (!bSlowLink)
  1920. {
  1921. bSlowLink = IsSlowLink (lpTemp->szFullFileName);
  1922. }
  1923. if (bSlowLink || !ParseTemplate(lpTemp->szFullFileName))
  1924. {
  1925. //
  1926. // If the adm file failed to parse for any of the reasons listed
  1927. // below, switch over to using the local copy of the ADM file
  1928. //
  1929. dwError = GetLastError();
  1930. if (bSlowLink || ((dwError != ERROR_SUCCESS) &&
  1931. (dwError != ERROR_ALREADY_DISPLAYED)))
  1932. {
  1933. if (bSlowLink)
  1934. {
  1935. DebugMsg((DM_VERBOSE, TEXT("CPolicyComponentData::LoadRSOPTemplates: Using local copy of %s due to slow link detection."),
  1936. lpTemp->szFileName));
  1937. }
  1938. else
  1939. {
  1940. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::LoadRSOPTemplates: Unable to parse template %s due to error %d. Switching to the local copy of %s."),
  1941. lpTemp->szFullFileName, dwError, lpTemp->szFileName));
  1942. AddADMFile (lpTemp->szFileName, lpTemp->szFullFileName, &(lpTemp->FileTime), dwError, &lpFailedAdmFiles);
  1943. dwFailedAdm++;
  1944. }
  1945. ExpandEnvironmentStrings (TEXT("%SystemRoot%\\inf\\"), szPath, MAX_PATH);
  1946. hr = StringCchCat (szPath, ARRAYSIZE(szPath), lpTemp->szFileName);
  1947. ASSERT(SUCCEEDED(hr));
  1948. ParseTemplate (szPath);
  1949. }
  1950. }
  1951. lpDelete = lpTemp;
  1952. lpTemp = lpTemp->pNext;
  1953. LocalFree (lpDelete);
  1954. }
  1955. hr = S_OK;
  1956. //
  1957. // Format a error msg for the failed adm files
  1958. // ignore any errors
  1959. //
  1960. if (dwFailedAdm) {
  1961. LPTSTR lpErr = NULL, lpEnd = NULL;
  1962. TCHAR szErrFormat[MAX_PATH];
  1963. TCHAR szError[MAX_PATH];
  1964. LoadString (g_hInstance, IDS_FAILED_RSOPFMT, szErrFormat, ARRAYSIZE(szErrFormat));
  1965. lpErr = (LPTSTR)LocalAlloc(LPTR, (600*dwFailedAdm)*sizeof(TCHAR));
  1966. if (!lpErr) {
  1967. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::LoadRSOPTemplates: Couldn't allocate memory for the error buffer."), GetLastError()));
  1968. goto Exit;
  1969. }
  1970. lpTemp = lpFailedAdmFiles;
  1971. lpEnd = lpErr;
  1972. while (lpTemp) {
  1973. LoadMessage(lpTemp->dwError, szError, ARRAYSIZE(szError));
  1974. hr = StringCchPrintf(lpEnd, 600*dwFailedAdm - (lpEnd - lpErr), szErrFormat, lpTemp->szFileName, lpTemp->szFullFileName, szError);
  1975. ASSERT(SUCCEEDED(hr));
  1976. lpEnd += lstrlen(lpEnd);
  1977. lpDelete = lpTemp;
  1978. lpTemp = lpTemp->pNext;
  1979. LocalFree (lpDelete);
  1980. }
  1981. // we cannot pass in a owner window handle here, b'cos this
  1982. // is being done in a seperate thread and the main thread can be
  1983. // waiting for the templatethread event
  1984. ReportAdmError(NULL, 0, IDS_RSOP_ADMFAILED, lpErr);
  1985. lpFailedAdmFiles = NULL;
  1986. LocalFree(lpErr);
  1987. }
  1988. Exit:
  1989. if (pEnum)
  1990. {
  1991. pEnum->Release();
  1992. }
  1993. if (pIWbemLocator)
  1994. {
  1995. pIWbemLocator->Release();
  1996. }
  1997. if (pIWbemServices)
  1998. {
  1999. pIWbemServices->Release();
  2000. }
  2001. if (pLanguage)
  2002. {
  2003. SysFreeString (pLanguage);
  2004. }
  2005. if (pQuery)
  2006. {
  2007. SysFreeString (pQuery);
  2008. }
  2009. if (pName)
  2010. {
  2011. SysFreeString (pName);
  2012. }
  2013. if (pLastWriteTime)
  2014. {
  2015. SysFreeString (pLastWriteTime);
  2016. }
  2017. if (pNamespace)
  2018. {
  2019. SysFreeString (pNamespace);
  2020. }
  2021. lpTemp = lpFailedAdmFiles;
  2022. while (lpTemp) {
  2023. lpDelete = lpTemp;
  2024. lpTemp = lpTemp->pNext;
  2025. LocalFree (lpDelete);
  2026. }
  2027. lpFailedAdmFiles = NULL;
  2028. CoUninitialize();
  2029. DebugMsg((DM_VERBOSE, TEXT("CPolicyComponentData::LoadRSOPTemplates: Leaving")));
  2030. return hr;
  2031. }
  2032. HRESULT CPolicyComponentData::LoadTemplates (void)
  2033. {
  2034. HRESULT hr = E_FAIL;
  2035. if (m_bUserScope)
  2036. {
  2037. DebugMsg((DM_VERBOSE, TEXT("CPolicyComponentData::LoadTemplates: Entering for User")));
  2038. }
  2039. else
  2040. {
  2041. DebugMsg((DM_VERBOSE, TEXT("CPolicyComponentData::LoadTemplates: Entering for Machine")));
  2042. }
  2043. //
  2044. // Reset the ADM event
  2045. //
  2046. ResetEvent (m_ADMEvent);
  2047. //
  2048. // Free any old templates
  2049. //
  2050. FreeTemplates ();
  2051. EnterCriticalSection (&g_ADMCritSec);
  2052. //
  2053. // Prepare to load the templates
  2054. //
  2055. m_nUserDataItems = 0;
  2056. m_nMachineDataItems = 0;
  2057. m_pMachineCategoryList = (TABLEENTRY *) GlobalAlloc(GPTR,sizeof(TABLEENTRY));
  2058. if (!m_pMachineCategoryList)
  2059. {
  2060. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::LoadTemplates: Failed to alloc memory with %d"),
  2061. GetLastError()));
  2062. goto Exit;
  2063. }
  2064. m_pUserCategoryList = (TABLEENTRY *) GlobalAlloc(GPTR,sizeof(TABLEENTRY));
  2065. if (!m_pUserCategoryList)
  2066. {
  2067. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::LoadTemplates: Failed to alloc memory with %d"),
  2068. GetLastError()));
  2069. GlobalFree (m_pMachineCategoryList);
  2070. goto Exit;
  2071. }
  2072. m_pMachineCategoryList->dwSize = m_pUserCategoryList->dwSize = sizeof(TABLEENTRY);
  2073. m_pMachineCategoryList->dwType = m_pUserCategoryList->dwType = ETYPE_ROOT;
  2074. //
  2075. // Load the appropriate template files
  2076. //
  2077. if (m_bRSOP)
  2078. {
  2079. hr = LoadRSOPTemplates();
  2080. }
  2081. else
  2082. {
  2083. hr = LoadGPOTemplates();
  2084. if (SUCCEEDED(hr))
  2085. {
  2086. TCHAR szUnknown[150];
  2087. LoadString (g_hInstance, IDS_NOSUPPORTINFO, szUnknown, ARRAYSIZE(szUnknown));
  2088. AddSupportedNode (&m_pSupportedStrings, szUnknown, TRUE);
  2089. if (m_bUserScope)
  2090. {
  2091. InitializeSupportInfo(m_pUserCategoryList, &m_pSupportedStrings);
  2092. }
  2093. else
  2094. {
  2095. InitializeSupportInfo(m_pMachineCategoryList, &m_pSupportedStrings);
  2096. }
  2097. }
  2098. }
  2099. Exit:
  2100. SetEvent (m_ADMEvent);
  2101. LeaveCriticalSection (&g_ADMCritSec);
  2102. DebugMsg((DM_VERBOSE, TEXT("CPolicyComponentData::LoadTemplates: Leaving")));
  2103. return hr;
  2104. }
  2105. BOOL CPolicyComponentData::ParseTemplate (LPTSTR lpFileName)
  2106. {
  2107. HANDLE hFile;
  2108. BOOL fMore;
  2109. UINT uRet;
  2110. LANGID langid;
  2111. TCHAR szLocalizedSection[20];
  2112. DWORD dwSize, dwRead;
  2113. LPVOID lpFile, lpTemp;
  2114. HRESULT hr = S_OK;
  2115. //
  2116. // Verbose output
  2117. //
  2118. DebugMsg((DM_VERBOSE, TEXT("CPolicyComponentData::ParseTemplate: Loading <%s>..."),
  2119. lpFileName));
  2120. //
  2121. // Set defaults
  2122. //
  2123. m_nFileLine = 1;
  2124. m_pListCurrent = m_pMachineCategoryList;
  2125. m_pnDataItemCount = &m_nMachineDataItems;
  2126. m_pszParseFileName = lpFileName;
  2127. //
  2128. // Read in the adm file
  2129. //
  2130. hFile = CreateFile (lpFileName, GENERIC_READ, FILE_SHARE_READ,
  2131. NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL |
  2132. FILE_FLAG_SEQUENTIAL_SCAN, NULL);
  2133. if (hFile == INVALID_HANDLE_VALUE)
  2134. {
  2135. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::ParseTemplate: Failed to load <%s> with %d"),
  2136. lpFileName, GetLastError()));
  2137. return FALSE;
  2138. }
  2139. dwSize = GetFileSize (hFile, NULL);
  2140. if (dwSize == 0xFFFFFFFF)
  2141. {
  2142. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::ParseTemplates: Failed to get file size with %d."),
  2143. GetLastError()));
  2144. CloseHandle (hFile);
  2145. return FALSE;
  2146. }
  2147. if (!(lpFile = GlobalAlloc(GPTR, dwSize)))
  2148. {
  2149. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::ParseTemplates: Failed to allocate memory for %d bytes with %d."),
  2150. dwSize, GetLastError()));
  2151. CloseHandle (hFile);
  2152. return FALSE;
  2153. }
  2154. if (!ReadFile (hFile, lpFile, dwSize, &dwRead, NULL))
  2155. {
  2156. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::ParseTemplates: Failed to read file with %d."),
  2157. GetLastError()));
  2158. GlobalFree(lpFile);
  2159. CloseHandle (hFile);
  2160. return FALSE;
  2161. }
  2162. CloseHandle (hFile);
  2163. DebugMsg((DM_VERBOSE, TEXT("CPolicyComponentData::ParseTemplate: Finished reading file.")));
  2164. if (dwRead >= sizeof(WCHAR))
  2165. {
  2166. if (!IsTextUnicode(lpFile, dwRead, NULL))
  2167. {
  2168. if (!(lpTemp = GlobalAlloc(GPTR, dwSize * sizeof(WCHAR))))
  2169. {
  2170. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::ParseTemplates: Failed to allocate memory for %d WCHARS with %d."),
  2171. dwSize, GetLastError()));
  2172. GlobalFree(lpFile);
  2173. return FALSE;
  2174. }
  2175. if ( !MultiByteToWideChar (CP_ACP, 0, (LPCSTR) lpFile, dwRead, (LPWSTR)lpTemp, dwRead) )
  2176. {
  2177. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::ParseTemplates: Failed to convert ANSI adm file to Unicode with %d."),
  2178. GetLastError()));
  2179. GlobalFree(lpTemp);
  2180. GlobalFree(lpFile);
  2181. return FALSE;
  2182. }
  2183. GlobalFree (lpFile);
  2184. lpFile = lpTemp;
  2185. dwRead *= sizeof(WCHAR);
  2186. }
  2187. }
  2188. m_pFilePtr = (LPWSTR)lpFile;
  2189. m_pFileEnd = (LPWSTR)((LPBYTE)lpFile + dwRead - 1);
  2190. //
  2191. // Read in the string sections
  2192. //
  2193. langid = GetUserDefaultLangID();
  2194. hr = StringCchPrintf (szLocalizedSection, ARRAYSIZE(szLocalizedSection), TEXT("[%04x]"), langid);
  2195. ASSERT(SUCCEEDED(hr));
  2196. m_pLocaleStrings = FindSection (szLocalizedSection);
  2197. if (m_pLocaleStrings)
  2198. {
  2199. m_pLocaleStrings += lstrlen(szLocalizedSection) + 2;
  2200. m_pLocaleStrings = CreateStringArray(m_pLocaleStrings);
  2201. m_pLocaleHashTable = CreateHashTable();
  2202. FillHashTable(m_pLocaleHashTable, m_pLocaleStrings);
  2203. }
  2204. hr = StringCchPrintf (szLocalizedSection, ARRAYSIZE(szLocalizedSection), TEXT("[%04x]"), PRIMARYLANGID(langid));
  2205. ASSERT(SUCCEEDED(hr));
  2206. m_pLanguageStrings = FindSection (szLocalizedSection);
  2207. if (m_pLanguageStrings)
  2208. {
  2209. m_pLanguageStrings += lstrlen(szLocalizedSection) + 2;
  2210. m_pLanguageStrings = CreateStringArray(m_pLanguageStrings);
  2211. m_pLanguageHashTable = CreateHashTable();
  2212. FillHashTable(m_pLanguageHashTable, m_pLanguageStrings);
  2213. }
  2214. m_pDefaultStrings = FindSection ((LPTSTR)szStringsSect);
  2215. if (m_pDefaultStrings)
  2216. {
  2217. LPTSTR lpEnd;
  2218. m_pDefaultStrings += lstrlen(szStringsSect) + 2;
  2219. lpEnd = m_pDefaultStrings;
  2220. m_pDefaultStrings = CreateStringArray(m_pDefaultStrings);
  2221. m_pDefaultHashTable = CreateHashTable();
  2222. FillHashTable(m_pDefaultHashTable, m_pDefaultStrings);
  2223. #if DBG
  2224. //DumpHashTableDetails (m_pDefaultHashTable);
  2225. #endif
  2226. //
  2227. // Now that all the string arrays are created, we can remove the strings
  2228. // from the end of the adm file so we don't have 2 copies of the strings
  2229. // in memory at the same time. Note, the [Strings] section has to come
  2230. // before the language or locale sections (because [strings] is a tag to the parser
  2231. // to stop parsing the adm language). So, we can safely chop off the file
  2232. // right after the [strings] tag.
  2233. //
  2234. GlobalReAlloc (m_pFilePtr, (lpEnd - m_pFilePtr + 1) * sizeof(WCHAR), 0);
  2235. m_pFileEnd = lpEnd;
  2236. }
  2237. //
  2238. // Parse the file
  2239. //
  2240. m_fInComment = FALSE;
  2241. do {
  2242. uRet=ParseClass(&fMore);
  2243. } while (fMore && uRet == ERROR_SUCCESS);
  2244. //
  2245. // Cleanup
  2246. //
  2247. GlobalFree(lpFile);
  2248. if (m_pLocaleStrings)
  2249. {
  2250. GlobalFree(m_pLocaleStrings);
  2251. }
  2252. if (m_pLanguageStrings)
  2253. {
  2254. GlobalFree(m_pLanguageStrings);
  2255. }
  2256. if (m_pDefaultStrings)
  2257. {
  2258. GlobalFree(m_pDefaultStrings);
  2259. }
  2260. if (m_pLocaleHashTable)
  2261. {
  2262. FreeHashTable (m_pLocaleHashTable);
  2263. m_pLocaleHashTable = NULL;
  2264. }
  2265. if (m_pLanguageHashTable)
  2266. {
  2267. FreeHashTable (m_pLanguageHashTable);
  2268. m_pLanguageHashTable = NULL;
  2269. }
  2270. if (m_pDefaultHashTable)
  2271. {
  2272. FreeHashTable (m_pDefaultHashTable);
  2273. m_pDefaultHashTable = NULL;
  2274. }
  2275. DebugMsg((DM_VERBOSE, TEXT("CPolicyComponentData::ParseTemplate: Finished.")));
  2276. return TRUE;
  2277. }
  2278. UINT CPolicyComponentData::ParseClass(BOOL *pfMore)
  2279. {
  2280. TCHAR szWordBuf[WORDBUFSIZE+1];
  2281. UINT uErr, nKeywordID, nClassID;
  2282. if (!GetNextWord(szWordBuf,ARRAYSIZE(szWordBuf),pfMore,&uErr))
  2283. return uErr;
  2284. if (!CompareKeyword(szWordBuf,pClassCmpList,&nKeywordID))
  2285. return ERROR_ALREADY_DISPLAYED;
  2286. switch (nKeywordID) {
  2287. case KYWD_ID_CATEGORY:
  2288. return ParseCategory(m_pListCurrent, FALSE,pfMore, NULL);
  2289. case KYWD_ID_CLASS:
  2290. if (!GetNextSectionWord(szWordBuf,ARRAYSIZE(szWordBuf),
  2291. pClassTypeCmpList,&nClassID,pfMore,&uErr))
  2292. return uErr;
  2293. switch (nClassID) {
  2294. case KYWD_ID_USER:
  2295. DebugMsg((DM_VERBOSE, TEXT("CPolicyComponentData::ParseClass: User section")));
  2296. m_pListCurrent = m_pUserCategoryList;
  2297. m_pnDataItemCount = &m_nUserDataItems;
  2298. m_bRetrieveString = (m_bUserScope ? TRUE : FALSE);
  2299. break;
  2300. case KYWD_ID_MACHINE:
  2301. DebugMsg((DM_VERBOSE, TEXT("CPolicyComponentData::ParseClass: Machine section")));
  2302. m_pListCurrent = m_pMachineCategoryList;
  2303. m_pnDataItemCount = &m_nMachineDataItems;
  2304. m_bRetrieveString = (m_bUserScope ? FALSE : TRUE);
  2305. break;
  2306. }
  2307. break;
  2308. // hack for localization: allow a "strings" section at the bottom, if we
  2309. // encounter that then we're thru with parsing
  2310. case KYWD_ID_STRINGSSECT:
  2311. *pfMore = FALSE; // that's all, folks
  2312. return ERROR_SUCCESS;
  2313. break;
  2314. }
  2315. return ERROR_SUCCESS;
  2316. }
  2317. TABLEENTRY * CPolicyComponentData::FindCategory(TABLEENTRY *pParent, LPTSTR lpName)
  2318. {
  2319. TABLEENTRY *pEntry = NULL, *pTemp;
  2320. if (m_bRetrieveString && pParent) {
  2321. pTemp = pParent->pChild;
  2322. while (pTemp) {
  2323. if (pTemp->dwType & ETYPE_CATEGORY) {
  2324. if (!lstrcmpi (lpName, GETNAMEPTR(pTemp))) {
  2325. pEntry = pTemp;
  2326. break;
  2327. }
  2328. }
  2329. pTemp = pTemp->pNext;
  2330. }
  2331. }
  2332. return pEntry;
  2333. }
  2334. /*******************************************************************
  2335. NAME: ParseEntry
  2336. SYNOPSIS: Main parsing "engine" for category, policy and part
  2337. parsing
  2338. NOTES: Allocates memory to build a temporary TABLEENTRY struct
  2339. describing the parsed information. Reads the beginning and end of a
  2340. section and loops through the words in each section, calling
  2341. a caller-defined ParseProc for each keyword to let the
  2342. caller handle appropriately. Passes the newly-constucted
  2343. TABLEENTRY to AddTableEntry to save it, and frees the temporary
  2344. memory.
  2345. This function is re-entrant.
  2346. The ENTRYDATA struct is declared on ParseEntry's stack
  2347. but used by the ParseProc to maintain state between
  2348. calls-- e.g., whether or not a key name has been found.
  2349. This can't be maintained as a static in the ParseProc because
  2350. the ParseProc may be reentered (for instance, if categories
  2351. have subcategories).
  2352. There are many possible error paths and there is some
  2353. memory dealloc that needs to be done in an error case. Rather
  2354. than do deallocs by hand on every error path or use a "goto
  2355. cleanup" (ick!), items to be freed are added to a "cleanup
  2356. list" and then CleanupAndReturn is called in an error condition,
  2357. which frees items on the list and returns a specified value.
  2358. ENTRY: ppes-- PARSEENTRYSTRUCT that specifes type of entry, the
  2359. parent table, a keyword list, a ParseProc callback
  2360. and other goodies
  2361. pfMore-- set to FALSE if at end of file
  2362. EXIT: ERROR_SUCCESS if successful, otherwise an error code
  2363. (can be ERROR_ALREADY_DISPLAYED)
  2364. ********************************************************************/
  2365. UINT CPolicyComponentData::ParseEntry(PARSEENTRYSTRUCT *ppes,BOOL *pfMore,
  2366. LPTSTR pKeyName)
  2367. {
  2368. TCHAR szWordBuf[WORDBUFSIZE+1];
  2369. UINT uErr,nListIndex;
  2370. BOOL fFoundEnd = FALSE;
  2371. PARSEPROCSTRUCT pps;
  2372. ENTRYDATA EntryData;
  2373. DWORD dwBufSize = DEFAULT_TMP_BUF_SIZE;
  2374. TABLEENTRY *pTmp = NULL;
  2375. BOOL bNewEntry = TRUE;
  2376. memset(&pps,0,sizeof(pps));
  2377. memset(&EntryData,0,sizeof(EntryData));
  2378. pps.pdwBufSize = &dwBufSize;
  2379. pps.pData = &EntryData;
  2380. pps.pData->fParentHasKey = ppes->fParentHasKey;
  2381. pps.pEntryCmpList = ppes->pEntryCmpList;
  2382. // get the entry name
  2383. if (!GetNextSectionWord(szWordBuf,ARRAYSIZE(szWordBuf),NULL,NULL,pfMore,&uErr)) {
  2384. return uErr;
  2385. }
  2386. if (ppes->dwEntryType & ETYPE_CATEGORY) {
  2387. pTmp = FindCategory (ppes->pParent, szWordBuf);
  2388. }
  2389. if (pTmp) {
  2390. bNewEntry = FALSE;
  2391. } else {
  2392. //
  2393. // Create a new table entry
  2394. //
  2395. if (!(pps.pTableEntry = (TABLEENTRY *) GlobalAlloc(GPTR,*pps.pdwBufSize)))
  2396. return ERROR_NOT_ENOUGH_MEMORY;
  2397. // initialize TABLEENTRY struct
  2398. pps.pTableEntry->dwSize = ppes->dwStructSize;
  2399. pps.pTableEntry->dwType = ppes->dwEntryType;
  2400. // store the entry name in pTableEntry
  2401. pTmp = (TABLEENTRY *) AddDataToEntry(pps.pTableEntry,
  2402. (BYTE *)szWordBuf,(lstrlen(szWordBuf)+1) * sizeof(TCHAR),&(pps.pTableEntry->uOffsetName),
  2403. pps.pdwBufSize);
  2404. if (!pTmp) {
  2405. GlobalFree ((HGLOBAL)pps.pTableEntry);
  2406. return ERROR_NOT_ENOUGH_MEMORY;
  2407. }
  2408. }
  2409. pps.pTableEntry = pTmp;
  2410. // loop through the body of the declaration
  2411. while (!fFoundEnd && GetNextSectionWord(szWordBuf,
  2412. ARRAYSIZE(szWordBuf),pps.pEntryCmpList,&nListIndex,pfMore,&uErr)) {
  2413. if ( (uErr = (*ppes->pParseProc) (this, nListIndex,&pps,pfMore,&fFoundEnd,pKeyName))
  2414. != ERROR_SUCCESS) {
  2415. if (bNewEntry) {
  2416. GlobalFree ((HGLOBAL)pps.pTableEntry);
  2417. }
  2418. return (uErr);
  2419. }
  2420. if (!bNewEntry) {
  2421. if (pTmp != pps.pTableEntry) {
  2422. //
  2423. // We need to fix up the link list of pointers in case the tableentry
  2424. // has moved due to a realloc
  2425. //
  2426. if (pps.pTableEntry->pPrev) {
  2427. pps.pTableEntry->pPrev->pNext = pps.pTableEntry;
  2428. } else {
  2429. ppes->pParent->pChild = pps.pTableEntry;
  2430. }
  2431. if (pps.pTableEntry->pNext) {
  2432. pps.pTableEntry->pNext->pPrev = pps.pTableEntry;
  2433. }
  2434. pTmp = pps.pTableEntry;
  2435. }
  2436. }
  2437. }
  2438. if (uErr != ERROR_SUCCESS) {
  2439. if (bNewEntry) {
  2440. GlobalFree ((HGLOBAL)pps.pTableEntry);
  2441. }
  2442. return (uErr);
  2443. }
  2444. // Last word was "END"
  2445. // get the keyword that goes with "END" ("END CATGORY", "END POLICY", etc.)
  2446. if (!GetNextSectionWord(szWordBuf,ARRAYSIZE(szWordBuf),
  2447. ppes->pTypeCmpList,&nListIndex,pfMore,&uErr)) {
  2448. if (bNewEntry) {
  2449. GlobalFree ((HGLOBAL)pps.pTableEntry);
  2450. }
  2451. return (uErr);
  2452. }
  2453. // call the object's parse proc one last time to let it object if
  2454. // key name or something like that is missing
  2455. if ( (uErr = (*ppes->pParseProc) (this, KYWD_DONE,&pps,pfMore,&fFoundEnd,pKeyName))
  2456. != ERROR_SUCCESS) {
  2457. if (bNewEntry) {
  2458. GlobalFree ((HGLOBAL)pps.pTableEntry);
  2459. }
  2460. return (uErr);
  2461. }
  2462. if (bNewEntry) {
  2463. // fix up linked list pointers. If parent has no children yet, make this
  2464. // 1st child; otherwise walk the list of children and insert this at the end
  2465. if (!ppes->pParent->pChild) {
  2466. ppes->pParent->pChild = pps.pTableEntry;
  2467. } else {
  2468. TABLEENTRY * pLastChild = ppes->pParent->pChild;
  2469. while (pLastChild->pNext) {
  2470. pLastChild = pLastChild->pNext;
  2471. }
  2472. pLastChild->pNext = pps.pTableEntry;
  2473. pps.pTableEntry->pPrev = pLastChild;
  2474. }
  2475. }
  2476. return ERROR_SUCCESS;
  2477. }
  2478. /*******************************************************************
  2479. NAME: ParseCategory
  2480. SYNOPSIS: Parses a category
  2481. NOTES: Sets up a PARSEENTRYSTRUCT and lets ParseEntry do the
  2482. work.
  2483. ********************************************************************/
  2484. UINT CPolicyComponentData::ParseCategory(TABLEENTRY * pParent,
  2485. BOOL fParentHasKey,BOOL *pfMore,
  2486. LPTSTR pKeyName)
  2487. {
  2488. PARSEENTRYSTRUCT pes;
  2489. pes.pParent = pParent;
  2490. pes.dwEntryType = ETYPE_CATEGORY;
  2491. pes.pEntryCmpList = pCategoryEntryCmpList;
  2492. pes.pTypeCmpList = pCategoryTypeCmpList;
  2493. pes.pParseProc = CategoryParseProc;
  2494. pes.dwStructSize = sizeof(CATEGORY);
  2495. pes.fHasSubtable = TRUE;
  2496. pes.fParentHasKey = fParentHasKey;
  2497. return ParseEntry(&pes,pfMore,pKeyName);
  2498. }
  2499. /*******************************************************************
  2500. NAME: CategoryParseProc
  2501. SYNOPSIS: Keyword callback ParseProc for category parsing
  2502. ENTRY: nMsg-- index into pEntryCmpList array which specifies
  2503. keyword that was found.
  2504. ppps-- pointer to PARSEPROCSTRUCT that contains useful
  2505. data like a pointer to the TABLEENTRY being built
  2506. and a pointer to an ENTRYDATA struct to maintain
  2507. state between calls to the ParseProc
  2508. ********************************************************************/
  2509. UINT CPolicyComponentData::CategoryParseProc(CPolicyComponentData * pCD,
  2510. UINT nMsg,PARSEPROCSTRUCT * ppps,
  2511. BOOL * pfMore,BOOL * pfFoundEnd,
  2512. LPTSTR pKeyName)
  2513. {
  2514. TCHAR szWordBuf[WORDBUFSIZE+1];
  2515. CATEGORY * pCategory = (CATEGORY *) ppps->pTableEntry;
  2516. TABLEENTRY * pOld = ppps->pTableEntry, *pTmp;
  2517. LPTSTR lpHelpBuf;
  2518. UINT uErr;
  2519. switch (nMsg) {
  2520. case KYWD_ID_KEYNAME:
  2521. // have we already found a key name?
  2522. if (ppps->pData->fHasKey) {
  2523. pCD->DisplayKeywordError(IDS_ParseErr_DUPLICATE_KEYNAME,
  2524. NULL,NULL);
  2525. return ERROR_ALREADY_DISPLAYED;
  2526. }
  2527. // get the key name
  2528. if (!pCD->GetNextSectionWord(szWordBuf,ARRAYSIZE(szWordBuf),
  2529. NULL,NULL,pfMore,&uErr))
  2530. return uErr;
  2531. // store the key name in pCategory
  2532. pTmp = (TABLEENTRY *) pCD->AddDataToEntry((TABLEENTRY *) pCategory,
  2533. (BYTE *)szWordBuf,(lstrlen(szWordBuf)+1) * sizeof(TCHAR),&(pCategory->uOffsetKeyName),
  2534. ppps->pdwBufSize);
  2535. if (!pTmp)
  2536. return ERROR_NOT_ENOUGH_MEMORY;
  2537. ppps->pTableEntry = pTmp;
  2538. ppps->pData->fHasKey = TRUE;
  2539. return ERROR_SUCCESS;
  2540. break;
  2541. case KYWD_ID_END:
  2542. *pfFoundEnd = TRUE;
  2543. return ERROR_SUCCESS;
  2544. break;
  2545. case KYWD_ID_POLICY:
  2546. case KYWD_ID_CATEGORY:
  2547. {
  2548. BOOL fHasKey = ppps->pData->fHasKey | ppps->pData->fParentHasKey;
  2549. if (nMsg == KYWD_ID_POLICY)
  2550. uErr=pCD->ParsePolicy((TABLEENTRY *) pCategory,fHasKey,pfMore,
  2551. (ppps->pData->fHasKey ? GETKEYNAMEPTR(pCategory) : pKeyName));
  2552. else
  2553. uErr=pCD->ParseCategory((TABLEENTRY *) pCategory,fHasKey,pfMore,
  2554. (ppps->pData->fHasKey ? GETKEYNAMEPTR(pCategory) : pKeyName));
  2555. }
  2556. return uErr;
  2557. break;
  2558. case KYWD_ID_HELP:
  2559. // have we already found a help string already?
  2560. if (pCategory->uOffsetHelp) {
  2561. pCD->DisplayKeywordError(IDS_ParseErr_DUPLICATE_HELP,
  2562. NULL,NULL);
  2563. return ERROR_ALREADY_DISPLAYED;
  2564. }
  2565. lpHelpBuf = (LPTSTR) LocalAlloc (LPTR, HELPBUFSIZE * sizeof(TCHAR));
  2566. if (!lpHelpBuf) {
  2567. pCD->DisplayKeywordError(IDS_ErrOUTOFMEMORY,NULL,NULL);
  2568. return ERROR_ALREADY_DISPLAYED;
  2569. }
  2570. // get the help string
  2571. if (!pCD->GetNextSectionWord(lpHelpBuf,HELPBUFSIZE,
  2572. NULL,NULL,pfMore,&uErr)) {
  2573. LocalFree (lpHelpBuf);
  2574. return uErr;
  2575. }
  2576. // store the help string
  2577. pTmp = (TABLEENTRY *) pCD->AddDataToEntry((TABLEENTRY *) pCategory,
  2578. (BYTE *)lpHelpBuf,(lstrlen(lpHelpBuf)+1) * sizeof(TCHAR),&(pCategory->uOffsetHelp),
  2579. ppps->pdwBufSize);
  2580. LocalFree (lpHelpBuf);
  2581. if (!pTmp)
  2582. return ERROR_NOT_ENOUGH_MEMORY;
  2583. ppps->pTableEntry = pTmp;
  2584. return ERROR_SUCCESS;
  2585. case KYWD_DONE:
  2586. if (!ppps->pData->fHasKey && pKeyName) {
  2587. // store the key name in pCategory
  2588. pTmp = (TABLEENTRY *) pCD->AddDataToEntry((TABLEENTRY *) pCategory,
  2589. (BYTE *)pKeyName,(lstrlen(pKeyName)+1) * sizeof(TCHAR),&(pCategory->uOffsetKeyName),
  2590. ppps->pdwBufSize);
  2591. if (!pTmp)
  2592. return ERROR_NOT_ENOUGH_MEMORY;
  2593. ppps->pTableEntry = pTmp;
  2594. ppps->pData->fHasKey = TRUE;
  2595. }
  2596. return ERROR_SUCCESS;
  2597. break;
  2598. default:
  2599. return ERROR_SUCCESS;
  2600. break;
  2601. }
  2602. }
  2603. /*******************************************************************
  2604. NAME: ParsePolicy
  2605. SYNOPSIS: Parses a policy
  2606. NOTES: Sets up a PARSEENTRYSTRUCT and lets ParseEntry do the
  2607. work.
  2608. ********************************************************************/
  2609. UINT CPolicyComponentData::ParsePolicy(TABLEENTRY * pParent,
  2610. BOOL fParentHasKey,BOOL *pfMore,
  2611. LPTSTR pKeyName)
  2612. {
  2613. PARSEENTRYSTRUCT pes;
  2614. pes.pParent = pParent;
  2615. pes.dwEntryType = ETYPE_POLICY;
  2616. pes.pEntryCmpList = pPolicyEntryCmpList;
  2617. pes.pTypeCmpList = pPolicyTypeCmpList;
  2618. pes.pParseProc = PolicyParseProc;
  2619. pes.dwStructSize = sizeof(POLICY);
  2620. pes.fHasSubtable = TRUE;
  2621. pes.fParentHasKey = fParentHasKey;
  2622. return ParseEntry(&pes,pfMore, pKeyName);
  2623. }
  2624. /*******************************************************************
  2625. NAME: PolicyParseProc
  2626. SYNOPSIS: Keyword callback ParseProc for policy parsing
  2627. ENTRY: nMsg-- index into pEntryCmpList array which specifies
  2628. keyword that was found.
  2629. ppps-- pointer to PARSEPROCSTRUCT that contains useful
  2630. data like a pointer to the TABLEENTRY being built
  2631. and a pointer to an ENTRYDATA struct to maintain
  2632. state between calls to the ParseProc
  2633. ********************************************************************/
  2634. UINT CPolicyComponentData::PolicyParseProc(CPolicyComponentData * pCD,
  2635. UINT nMsg,PARSEPROCSTRUCT * ppps,
  2636. BOOL * pfMore,BOOL * pfFoundEnd,LPTSTR pKeyName)
  2637. {
  2638. TCHAR szWordBuf[WORDBUFSIZE+1];
  2639. LPTSTR lpHelpBuf, lpKeyName;
  2640. POLICY * pPolicy = (POLICY *) ppps->pTableEntry;
  2641. TABLEENTRY * pOld = ppps->pTableEntry, *pTmp;
  2642. UINT uErr;
  2643. switch (nMsg) {
  2644. case KYWD_ID_KEYNAME:
  2645. // have we already found a key name?
  2646. if (ppps->pData->fHasKey) {
  2647. pCD->DisplayKeywordError(IDS_ParseErr_DUPLICATE_KEYNAME,
  2648. NULL,NULL);
  2649. return ERROR_ALREADY_DISPLAYED;
  2650. }
  2651. // get the key name
  2652. if (!pCD->GetNextSectionWord(szWordBuf,ARRAYSIZE(szWordBuf),
  2653. NULL,NULL,pfMore,&uErr))
  2654. return uErr;
  2655. // store the key name in pPolicy
  2656. pTmp = (TABLEENTRY *) pCD->AddDataToEntry((TABLEENTRY *) pPolicy,
  2657. (BYTE *)szWordBuf,(lstrlen(szWordBuf)+1)*sizeof(TCHAR),&(pPolicy->uOffsetKeyName),ppps->pdwBufSize);
  2658. if (!pTmp)
  2659. return ERROR_NOT_ENOUGH_MEMORY;
  2660. ppps->pTableEntry = pTmp;
  2661. ppps->pData->fHasKey = TRUE;
  2662. return ERROR_SUCCESS;
  2663. case KYWD_ID_VALUENAME:
  2664. // have we already found a key name?
  2665. if (ppps->pData->fHasValue) {
  2666. pCD->DisplayKeywordError(IDS_ParseErr_DUPLICATE_VALUENAME,
  2667. NULL,NULL);
  2668. return ERROR_ALREADY_DISPLAYED;
  2669. }
  2670. // get the key name
  2671. if (!pCD->GetNextSectionWord(szWordBuf,ARRAYSIZE(szWordBuf),
  2672. NULL,NULL,pfMore,&uErr))
  2673. return uErr;
  2674. // store the key name in pSettings
  2675. pTmp = (TABLEENTRY *) pCD->AddDataToEntry((TABLEENTRY *) pPolicy,
  2676. (BYTE *)szWordBuf,(lstrlen(szWordBuf)+1) * sizeof(TCHAR),&(pPolicy->uOffsetValueName),
  2677. ppps->pdwBufSize);
  2678. if (!pTmp)
  2679. return ERROR_NOT_ENOUGH_MEMORY;
  2680. ppps->pTableEntry = pTmp;
  2681. ppps->pData->fHasValue = TRUE;
  2682. return ERROR_SUCCESS;
  2683. case KYWD_ID_HELP:
  2684. // have we already found a help string already?
  2685. if (pPolicy->uOffsetHelp) {
  2686. pCD->DisplayKeywordError(IDS_ParseErr_DUPLICATE_HELP,
  2687. NULL,NULL);
  2688. return ERROR_ALREADY_DISPLAYED;
  2689. }
  2690. lpHelpBuf = (LPTSTR) LocalAlloc (LPTR, HELPBUFSIZE * sizeof(TCHAR));
  2691. if (!lpHelpBuf) {
  2692. pCD->DisplayKeywordError(IDS_ErrOUTOFMEMORY,NULL,NULL);
  2693. return ERROR_ALREADY_DISPLAYED;
  2694. }
  2695. // get the help string
  2696. if (!pCD->GetNextSectionWord(lpHelpBuf,HELPBUFSIZE,
  2697. NULL,NULL,pfMore,&uErr)) {
  2698. LocalFree (lpHelpBuf);
  2699. return uErr;
  2700. }
  2701. // store the help string
  2702. pTmp = (TABLEENTRY *) pCD->AddDataToEntry((TABLEENTRY *) pPolicy,
  2703. (BYTE *)lpHelpBuf,(lstrlen(lpHelpBuf)+1) * sizeof(TCHAR),&(pPolicy->uOffsetHelp),
  2704. ppps->pdwBufSize);
  2705. LocalFree (lpHelpBuf);
  2706. if (!pTmp)
  2707. return ERROR_NOT_ENOUGH_MEMORY;
  2708. ppps->pTableEntry = pTmp;
  2709. return ERROR_SUCCESS;
  2710. case KYWD_ID_CLIENTEXT:
  2711. // have we already found a clientext string already?
  2712. if (pPolicy->uOffsetClientExt) {
  2713. pCD->DisplayKeywordError(IDS_ParseErr_DUPLICATE_CLIENTEXT,
  2714. NULL,NULL);
  2715. return ERROR_ALREADY_DISPLAYED;
  2716. }
  2717. // get the key name
  2718. if (!pCD->GetNextSectionWord(szWordBuf,ARRAYSIZE(szWordBuf),
  2719. NULL,NULL,pfMore,&uErr))
  2720. return uErr;
  2721. if (!ValidateGuid(szWordBuf))
  2722. {
  2723. pCD->DisplayKeywordError(IDS_ParseErr_INVALID_CLIENTEXT,
  2724. NULL,NULL);
  2725. return ERROR_ALREADY_DISPLAYED;
  2726. }
  2727. // store the clientext string in pSettings
  2728. pTmp = (TABLEENTRY *) pCD->AddDataToEntry((TABLEENTRY *) pPolicy,
  2729. (BYTE *)szWordBuf,(lstrlen(szWordBuf)+1) * sizeof(TCHAR),&(pPolicy->uOffsetClientExt),
  2730. ppps->pdwBufSize);
  2731. if (!pTmp)
  2732. return ERROR_NOT_ENOUGH_MEMORY;
  2733. ppps->pTableEntry = pTmp;
  2734. return ERROR_SUCCESS;
  2735. case KYWD_ID_SUPPORTED:
  2736. // have we already found a supported string already?
  2737. if (pPolicy->uOffsetSupported) {
  2738. pCD->DisplayKeywordError(IDS_ParseErr_DUPLICATE_SUPPORTED,
  2739. NULL,NULL);
  2740. return ERROR_ALREADY_DISPLAYED;
  2741. }
  2742. // get the supported platforms
  2743. if (!pCD->GetNextSectionWord(szWordBuf,ARRAYSIZE(szWordBuf),
  2744. NULL,NULL,pfMore,&uErr))
  2745. return uErr;
  2746. // store the supported string in pSettings
  2747. pTmp = (TABLEENTRY *) pCD->AddDataToEntry((TABLEENTRY *) pPolicy,
  2748. (BYTE *)szWordBuf,(lstrlen(szWordBuf)+1) * sizeof(TCHAR),&(pPolicy->uOffsetSupported),
  2749. ppps->pdwBufSize);
  2750. if (!pTmp)
  2751. return ERROR_NOT_ENOUGH_MEMORY;
  2752. ppps->pTableEntry = pTmp;
  2753. return ERROR_SUCCESS;
  2754. case KYWD_ID_END:
  2755. *pfFoundEnd = TRUE;
  2756. return ERROR_SUCCESS;
  2757. case KYWD_ID_PART:
  2758. {
  2759. BOOL fHasKey = ppps->pData->fHasKey | ppps->pData->fParentHasKey;
  2760. return pCD->ParseSettings((TABLEENTRY *) pPolicy,fHasKey,pfMore,
  2761. (ppps->pData->fHasKey ? GETKEYNAMEPTR(pPolicy) : pKeyName));
  2762. }
  2763. case KYWD_ID_VALUEON:
  2764. return pCD->ParseValue(ppps,&pPolicy->uOffsetValue_On,
  2765. &ppps->pTableEntry,pfMore);
  2766. case KYWD_ID_VALUEOFF:
  2767. return pCD->ParseValue(ppps,&pPolicy->uOffsetValue_Off,
  2768. &ppps->pTableEntry,pfMore);
  2769. case KYWD_ID_ACTIONLISTON:
  2770. return pCD->ParseActionList(ppps,&pPolicy->uOffsetActionList_On,
  2771. &ppps->pTableEntry,szACTIONLISTON,pfMore);
  2772. case KYWD_ID_ACTIONLISTOFF:
  2773. return pCD->ParseActionList(ppps,&pPolicy->uOffsetActionList_Off,
  2774. &ppps->pTableEntry,szACTIONLISTOFF,pfMore);
  2775. case KYWD_DONE:
  2776. if (!ppps->pData->fHasKey) {
  2777. if (!ppps->pData->fParentHasKey) {
  2778. pCD->DisplayKeywordError(IDS_ParseErr_NO_KEYNAME,NULL,NULL);
  2779. return ERROR_ALREADY_DISPLAYED;
  2780. }
  2781. // store the key name in pPolicy
  2782. pTmp = (TABLEENTRY *) pCD->AddDataToEntry((TABLEENTRY *) pPolicy,
  2783. (BYTE *)pKeyName,(lstrlen(pKeyName)+1)*sizeof(TCHAR),&(pPolicy->uOffsetKeyName),ppps->pdwBufSize);
  2784. if (!pTmp)
  2785. return ERROR_NOT_ENOUGH_MEMORY;
  2786. ppps->pTableEntry = pTmp;
  2787. pPolicy = (POLICY *) pTmp;
  2788. ppps->pData->fHasKey = TRUE;
  2789. }
  2790. if (!pPolicy->uOffsetValueName && !pPolicy->pChild)
  2791. {
  2792. if ((!pPolicy->uOffsetValue_On && pPolicy->uOffsetValue_Off) ||
  2793. (pPolicy->uOffsetValue_On && !pPolicy->uOffsetValue_Off))
  2794. {
  2795. pCD->DisplayKeywordError(IDS_ParseErr_MISSINGVALUEON_OR_OFF,NULL,NULL);
  2796. return ERROR_ALREADY_DISPLAYED;
  2797. }
  2798. }
  2799. //
  2800. // Check if this is a real policy
  2801. //
  2802. lpKeyName = GETKEYNAMEPTR(ppps->pTableEntry);
  2803. if (!lpKeyName) {
  2804. return ERROR_INVALID_PARAMETER;
  2805. }
  2806. if (CompareString(LOCALE_INVARIANT, NORM_IGNORECASE | NORM_STOP_ON_NULL,
  2807. lpKeyName, pCD->m_iSWPoliciesLen,
  2808. SOFTWARE_POLICIES, pCD->m_iSWPoliciesLen) == CSTR_EQUAL)
  2809. {
  2810. ((POLICY *) ppps->pTableEntry)->bTruePolicy = TRUE;
  2811. }
  2812. else if (CompareString(LOCALE_INVARIANT, NORM_IGNORECASE | NORM_STOP_ON_NULL,
  2813. lpKeyName, pCD->m_iWinPoliciesLen,
  2814. WINDOWS_POLICIES, pCD->m_iWinPoliciesLen) == CSTR_EQUAL)
  2815. {
  2816. ((POLICY *) ppps->pTableEntry)->bTruePolicy = TRUE;
  2817. }
  2818. ( (POLICY *) ppps->pTableEntry)->uDataIndex = *pCD->m_pnDataItemCount;
  2819. (*pCD->m_pnDataItemCount) ++;
  2820. return ERROR_SUCCESS;
  2821. default:
  2822. break;
  2823. }
  2824. return ERROR_SUCCESS;
  2825. }
  2826. /*******************************************************************
  2827. NAME: ParseSettings
  2828. SYNOPSIS: Parses a policy setting
  2829. NOTES: Sets up a PARSEENTRYSTRUCT and lets ParseEntry do the
  2830. work.
  2831. ********************************************************************/
  2832. UINT CPolicyComponentData::ParseSettings(TABLEENTRY * pParent,
  2833. BOOL fParentHasKey,BOOL *pfMore,
  2834. LPTSTR pKeyName)
  2835. {
  2836. PARSEENTRYSTRUCT pes;
  2837. pes.pParent = pParent;
  2838. pes.dwEntryType = ETYPE_SETTING;
  2839. pes.pEntryCmpList = pSettingsEntryCmpList;
  2840. pes.pTypeCmpList = pSettingsTypeCmpList;
  2841. pes.pParseProc = SettingsParseProc;
  2842. pes.dwStructSize = sizeof(SETTINGS);
  2843. pes.fHasSubtable = FALSE;
  2844. pes.fParentHasKey = fParentHasKey;
  2845. return ParseEntry(&pes,pfMore, pKeyName);
  2846. }
  2847. /*******************************************************************
  2848. NAME: SettingsParseProc
  2849. SYNOPSIS: Keyword callback ParseProc for policy settings parsing
  2850. ENTRY: nMsg-- index into pEntryCmpList array which specifies
  2851. keyword that was found.
  2852. ppps-- pointer to PARSEPROCSTRUCT that contains useful
  2853. data like a pointer to the TABLEENTRY being built
  2854. and a pointer to an ENTRYDATA struct to maintain
  2855. state between calls to the ParseProc
  2856. ********************************************************************/
  2857. UINT CPolicyComponentData::SettingsParseProc(CPolicyComponentData *pCD,
  2858. UINT nMsg,PARSEPROCSTRUCT * ppps,
  2859. BOOL * pfMore,BOOL * pfFoundEnd,
  2860. LPTSTR pKeyName)
  2861. {
  2862. TCHAR szWordBuf[WORDBUFSIZE+1];
  2863. SETTINGS * pSettings = (SETTINGS *) ppps->pTableEntry;
  2864. BYTE * pObjectData = GETOBJECTDATAPTR(pSettings);
  2865. TABLEENTRY *pTmp;
  2866. UINT uErr;
  2867. switch (nMsg) {
  2868. case KYWD_ID_KEYNAME:
  2869. // have we already found a key name?
  2870. if (ppps->pData->fHasKey) {
  2871. pCD->DisplayKeywordError(IDS_ParseErr_DUPLICATE_KEYNAME,
  2872. NULL,NULL);
  2873. return ERROR_ALREADY_DISPLAYED;
  2874. }
  2875. // get the key name
  2876. if (!pCD->GetNextSectionWord(szWordBuf,ARRAYSIZE(szWordBuf),
  2877. NULL,NULL,pfMore,&uErr))
  2878. return uErr;
  2879. // store the key name in pSettings
  2880. pTmp = (TABLEENTRY *) pCD->AddDataToEntry((TABLEENTRY *) pSettings,
  2881. (BYTE *)szWordBuf,(lstrlen(szWordBuf)+1) * sizeof(TCHAR),&(pSettings->uOffsetKeyName),ppps->pdwBufSize);
  2882. if (!pTmp)
  2883. return ERROR_NOT_ENOUGH_MEMORY;
  2884. ppps->pTableEntry = pTmp;
  2885. ppps->pData->fHasKey = TRUE;
  2886. return ERROR_SUCCESS;
  2887. break;
  2888. case KYWD_ID_VALUENAME:
  2889. // have we already found a value name?
  2890. if (ppps->pData->fHasValue) {
  2891. pCD->DisplayKeywordError(IDS_ParseErr_DUPLICATE_VALUENAME,
  2892. NULL,NULL);
  2893. return ERROR_ALREADY_DISPLAYED;
  2894. }
  2895. // get the value name
  2896. if (!pCD->GetNextSectionWord(szWordBuf,ARRAYSIZE(szWordBuf),
  2897. NULL,NULL,pfMore,&uErr))
  2898. return uErr;
  2899. // store the value name in pSettings
  2900. pTmp = (TABLEENTRY *) pCD->AddDataToEntry((TABLEENTRY *) pSettings,
  2901. (BYTE *)szWordBuf,(lstrlen(szWordBuf)+1) * sizeof(TCHAR),&(pSettings->uOffsetValueName),
  2902. ppps->pdwBufSize);
  2903. if (!pTmp)
  2904. return ERROR_NOT_ENOUGH_MEMORY;
  2905. ppps->pTableEntry = pTmp;
  2906. ppps->pData->fHasValue = TRUE;
  2907. return ERROR_SUCCESS;
  2908. break;
  2909. case KYWD_ID_CLIENTEXT:
  2910. // have we already found a clientext string already?
  2911. if (pSettings->uOffsetClientExt) {
  2912. pCD->DisplayKeywordError(IDS_ParseErr_DUPLICATE_CLIENTEXT,
  2913. NULL,NULL);
  2914. return ERROR_ALREADY_DISPLAYED;
  2915. }
  2916. // get the clientext name
  2917. if (!pCD->GetNextSectionWord(szWordBuf,ARRAYSIZE(szWordBuf),
  2918. NULL,NULL,pfMore,&uErr))
  2919. return uErr;
  2920. if (!ValidateGuid(szWordBuf))
  2921. {
  2922. pCD->DisplayKeywordError(IDS_ParseErr_INVALID_CLIENTEXT,
  2923. NULL,NULL);
  2924. return ERROR_ALREADY_DISPLAYED;
  2925. }
  2926. // store the clientext string in pSettings
  2927. pTmp = (TABLEENTRY *) pCD->AddDataToEntry((TABLEENTRY *) pSettings,
  2928. (BYTE *)szWordBuf,(lstrlen(szWordBuf)+1) * sizeof(TCHAR),&(pSettings->uOffsetClientExt),
  2929. ppps->pdwBufSize);
  2930. if (!pTmp)
  2931. return ERROR_NOT_ENOUGH_MEMORY;
  2932. ppps->pTableEntry = pTmp;
  2933. return ERROR_SUCCESS;
  2934. case KYWD_ID_REQUIRED:
  2935. pSettings->dwFlags |= DF_REQUIRED;
  2936. return ERROR_SUCCESS;
  2937. break;
  2938. case KYWD_ID_EXPANDABLETEXT:
  2939. pSettings->dwFlags |= DF_EXPANDABLETEXT;
  2940. return ERROR_SUCCESS;
  2941. break;
  2942. case KYWD_ID_SUGGESTIONS:
  2943. return pCD->ParseSuggestions(ppps,&((POLICYCOMBOBOXINFO *)
  2944. (GETOBJECTDATAPTR(pSettings)))->uOffsetSuggestions,
  2945. &ppps->pTableEntry,pfMore);
  2946. case KYWD_ID_TXTCONVERT:
  2947. pSettings->dwFlags |= DF_TXTCONVERT;
  2948. return ERROR_SUCCESS;
  2949. break;
  2950. case KYWD_ID_END:
  2951. *pfFoundEnd = TRUE;
  2952. return ERROR_SUCCESS;
  2953. break;
  2954. case KYWD_ID_SOFT:
  2955. pSettings->dwFlags |= VF_SOFT;
  2956. return ERROR_SUCCESS;
  2957. break;
  2958. case KYWD_DONE:
  2959. if (!ppps->pData->fHasKey) {
  2960. if (!ppps->pData->fParentHasKey) {
  2961. pCD->DisplayKeywordError(IDS_ParseErr_NO_KEYNAME,NULL,NULL);
  2962. return ERROR_ALREADY_DISPLAYED;
  2963. }
  2964. // store the key name in pSettings
  2965. pTmp = (TABLEENTRY *) pCD->AddDataToEntry((TABLEENTRY *) pSettings,
  2966. (BYTE *)pKeyName,(lstrlen(pKeyName)+1) * sizeof(TCHAR),&(pSettings->uOffsetKeyName),ppps->pdwBufSize);
  2967. if (!pTmp)
  2968. return ERROR_NOT_ENOUGH_MEMORY;
  2969. ppps->pTableEntry = pTmp;
  2970. ppps->pData->fHasKey = TRUE;
  2971. }
  2972. if (!ppps->pData->fHasValue) {
  2973. pCD->DisplayKeywordError(IDS_ParseErr_NO_VALUENAME,NULL,NULL);
  2974. return ERROR_ALREADY_DISPLAYED;
  2975. }
  2976. ( (SETTINGS *) ppps->pTableEntry)->uDataIndex = *pCD->m_pnDataItemCount;
  2977. (*pCD->m_pnDataItemCount) ++;
  2978. return ERROR_SUCCESS;
  2979. break;
  2980. case KYWD_ID_CHECKBOX:
  2981. return (pCD->InitSettingsParse(ppps,ETYPE_SETTING | STYPE_CHECKBOX,
  2982. sizeof(CHECKBOXINFO),pCheckboxCmpList,&pSettings,&pObjectData));
  2983. break;
  2984. case KYWD_ID_TEXT:
  2985. ppps->pData->fHasValue = TRUE; // no key value for static text items
  2986. return (pCD->InitSettingsParse(ppps,ETYPE_SETTING | STYPE_TEXT,
  2987. 0,pTextCmpList,&pSettings,&pObjectData));
  2988. break;
  2989. case KYWD_ID_EDITTEXT:
  2990. uErr=pCD->InitSettingsParse(ppps,ETYPE_SETTING | STYPE_EDITTEXT,
  2991. sizeof(EDITTEXTINFO),pEditTextCmpList,&pSettings,&pObjectData);
  2992. if (uErr != ERROR_SUCCESS) return uErr;
  2993. {
  2994. EDITTEXTINFO *pEditTextInfo = (EDITTEXTINFO *)
  2995. (GETOBJECTDATAPTR(((SETTINGS *) ppps->pTableEntry)));
  2996. if (!pEditTextInfo) {
  2997. return ERROR_INVALID_PARAMETER;
  2998. }
  2999. pEditTextInfo->nMaxLen = MAXSTRLEN-1;
  3000. }
  3001. break;
  3002. case KYWD_ID_COMBOBOX:
  3003. uErr=pCD->InitSettingsParse(ppps,ETYPE_SETTING | STYPE_COMBOBOX,
  3004. sizeof(POLICYCOMBOBOXINFO),pComboboxCmpList,&pSettings,&pObjectData);
  3005. if (uErr != ERROR_SUCCESS) return uErr;
  3006. {
  3007. EDITTEXTINFO *pEditTextInfo = (EDITTEXTINFO *)
  3008. (GETOBJECTDATAPTR(((SETTINGS *) ppps->pTableEntry)));
  3009. pEditTextInfo->nMaxLen = MAXSTRLEN-1;
  3010. }
  3011. break;
  3012. case KYWD_ID_NUMERIC:
  3013. uErr=pCD->InitSettingsParse(ppps,ETYPE_SETTING | STYPE_NUMERIC,
  3014. sizeof(NUMERICINFO),pNumericCmpList,&pSettings,&pObjectData);
  3015. if (uErr != ERROR_SUCCESS) return uErr;
  3016. if (!pObjectData) return ERROR_INVALID_PARAMETER;
  3017. ( (NUMERICINFO *) pObjectData)->uDefValue = 1;
  3018. ( (NUMERICINFO *) pObjectData)->uMinValue = 1;
  3019. ( (NUMERICINFO *) pObjectData)->uMaxValue = 9999;
  3020. ( (NUMERICINFO *) pObjectData)->uSpinIncrement = 1;
  3021. break;
  3022. case KYWD_ID_DROPDOWNLIST:
  3023. ppps->pEntryCmpList = pDropdownlistCmpList;
  3024. ppps->pTableEntry->dwType = ETYPE_SETTING | STYPE_DROPDOWNLIST;
  3025. return ERROR_SUCCESS;
  3026. break;
  3027. case KYWD_ID_LISTBOX:
  3028. uErr=pCD->InitSettingsParse(ppps,ETYPE_SETTING | STYPE_LISTBOX,
  3029. sizeof(LISTBOXINFO),pListboxCmpList,&pSettings,&pObjectData);
  3030. if (uErr != ERROR_SUCCESS) return uErr;
  3031. // listboxes have no single value name, set the value name to ""
  3032. pTmp = (TABLEENTRY *) pCD->AddDataToEntry((TABLEENTRY *) pSettings,
  3033. (BYTE *) g_szNull,(lstrlen(g_szNull)+1) * sizeof(TCHAR),&(pSettings->uOffsetValueName),
  3034. ppps->pdwBufSize);
  3035. if (!pTmp)
  3036. return ERROR_NOT_ENOUGH_MEMORY;
  3037. ppps->pTableEntry = pTmp;
  3038. ppps->pData->fHasValue = TRUE;
  3039. return ERROR_SUCCESS;
  3040. break;
  3041. case KYWD_ID_EDITTEXT_DEFAULT:
  3042. case KYWD_ID_COMBOBOX_DEFAULT:
  3043. // get the default text
  3044. if (!pCD->GetNextSectionWord(szWordBuf,ARRAYSIZE(szWordBuf),
  3045. NULL,NULL,pfMore,&uErr))
  3046. return uErr;
  3047. // store the default text in pTableEntry
  3048. pTmp = (TABLEENTRY *) pCD->AddDataToEntry((TABLEENTRY *)
  3049. pSettings,(BYTE *)szWordBuf,(lstrlen(szWordBuf)+1) * sizeof(TCHAR),
  3050. &((EDITTEXTINFO *) (GETOBJECTDATAPTR(pSettings)))->uOffsetDefText,
  3051. ppps->pdwBufSize);
  3052. if (!pTmp)
  3053. return ERROR_NOT_ENOUGH_MEMORY;
  3054. ppps->pTableEntry = pTmp;
  3055. ((SETTINGS *) ppps->pTableEntry)->dwFlags |= DF_USEDEFAULT;
  3056. break;
  3057. case KYWD_ID_MAXLENGTH:
  3058. {
  3059. EDITTEXTINFO *pEditTextInfo = (EDITTEXTINFO *)
  3060. (GETOBJECTDATAPTR(pSettings));
  3061. if ((uErr=pCD->GetNextSectionNumericWord(
  3062. &pEditTextInfo->nMaxLen)) != ERROR_SUCCESS)
  3063. return uErr;
  3064. }
  3065. break;
  3066. case KYWD_ID_MAX:
  3067. if ((uErr=pCD->GetNextSectionNumericWord(
  3068. &((NUMERICINFO *)pObjectData)->uMaxValue)) != ERROR_SUCCESS)
  3069. return uErr;
  3070. break;
  3071. case KYWD_ID_MIN:
  3072. if ((uErr=pCD->GetNextSectionNumericWord(
  3073. &((NUMERICINFO *)pObjectData)->uMinValue)) != ERROR_SUCCESS)
  3074. return uErr;
  3075. break;
  3076. case KYWD_ID_SPIN:
  3077. if ((uErr=pCD->GetNextSectionNumericWord(
  3078. &((NUMERICINFO *)pObjectData)->uSpinIncrement)) != ERROR_SUCCESS)
  3079. return uErr;
  3080. break;
  3081. case KYWD_ID_NUMERIC_DEFAULT:
  3082. if ((uErr=pCD->GetNextSectionNumericWord(
  3083. &((NUMERICINFO *)pObjectData)->uDefValue)) != ERROR_SUCCESS)
  3084. return uErr;
  3085. pSettings->dwFlags |= (DF_DEFCHECKED | DF_USEDEFAULT);
  3086. break;
  3087. case KYWD_ID_DEFCHECKED:
  3088. pSettings->dwFlags |= (DF_DEFCHECKED | DF_USEDEFAULT);
  3089. break;
  3090. case KYWD_ID_VALUEON:
  3091. return pCD->ParseValue(ppps,&((CHECKBOXINFO *)
  3092. pObjectData)->uOffsetValue_On,
  3093. &ppps->pTableEntry,pfMore);
  3094. break;
  3095. case KYWD_ID_VALUEOFF:
  3096. return pCD->ParseValue(ppps,&((CHECKBOXINFO *)
  3097. pObjectData)->uOffsetValue_Off,
  3098. &ppps->pTableEntry,pfMore);
  3099. break;
  3100. case KYWD_ID_ACTIONLISTON:
  3101. return pCD->ParseActionList(ppps,&((CHECKBOXINFO *)
  3102. pObjectData)->uOffsetActionList_On,
  3103. &ppps->pTableEntry,szACTIONLISTON,pfMore);
  3104. break;
  3105. case KYWD_ID_ACTIONLISTOFF:
  3106. return pCD->ParseActionList(ppps,&((CHECKBOXINFO *)
  3107. pObjectData)->uOffsetActionList_Off,
  3108. &ppps->pTableEntry,szACTIONLISTOFF,pfMore);
  3109. break;
  3110. case KYWD_ID_ITEMLIST:
  3111. return pCD->ParseItemList(ppps,&pSettings->uOffsetObjectData,
  3112. pfMore);
  3113. break;
  3114. case KYWD_ID_VALUEPREFIX:
  3115. // get the string to be ised as prefix
  3116. if (!pCD->GetNextSectionWord(szWordBuf,ARRAYSIZE(szWordBuf),
  3117. NULL,NULL,pfMore,&uErr))
  3118. return uErr;
  3119. // store the string pTableEntry
  3120. pTmp = (TABLEENTRY *) pCD->AddDataToEntry((TABLEENTRY *)
  3121. pSettings,(BYTE *)szWordBuf,(lstrlen(szWordBuf)+1) * sizeof(TCHAR),
  3122. &((LISTBOXINFO *) (GETOBJECTDATAPTR(pSettings)))->uOffsetPrefix,
  3123. ppps->pdwBufSize);
  3124. if (!pTmp)
  3125. return ERROR_NOT_ENOUGH_MEMORY;
  3126. ppps->pTableEntry = pTmp;
  3127. break;
  3128. case KYWD_ID_ADDITIVE:
  3129. pSettings->dwFlags |= DF_ADDITIVE;
  3130. return ERROR_SUCCESS;
  3131. break;
  3132. case KYWD_ID_EXPLICITVALUE:
  3133. pSettings->dwFlags |= DF_EXPLICITVALNAME;
  3134. return ERROR_SUCCESS;
  3135. break;
  3136. case KYWD_ID_NOSORT:
  3137. pSettings->dwFlags |= DF_NOSORT;
  3138. break;
  3139. }
  3140. return ERROR_SUCCESS;
  3141. }
  3142. UINT CPolicyComponentData::InitSettingsParse(PARSEPROCSTRUCT *ppps,DWORD dwType,DWORD dwSize,
  3143. KEYWORDINFO * pKeyList,SETTINGS ** ppSettings,BYTE **ppObjectData)
  3144. {
  3145. TABLEENTRY *pTmp;
  3146. if (dwSize) {
  3147. // increase the buffer to fit object-specific data if specified
  3148. pTmp = (TABLEENTRY *) AddDataToEntry(ppps->pTableEntry,
  3149. NULL,dwSize,&( ((SETTINGS * )ppps->pTableEntry)->uOffsetObjectData),
  3150. ppps->pdwBufSize);
  3151. if (!pTmp) return ERROR_NOT_ENOUGH_MEMORY;
  3152. ppps->pTableEntry = pTmp;
  3153. }
  3154. else ( (SETTINGS *) ppps->pTableEntry)->uOffsetObjectData= 0;
  3155. ppps->pEntryCmpList = pKeyList;
  3156. ppps->pTableEntry->dwType = dwType;
  3157. *ppSettings = (SETTINGS *) ppps->pTableEntry;
  3158. *ppObjectData = GETOBJECTDATAPTR((*ppSettings));
  3159. return ERROR_SUCCESS;
  3160. }
  3161. UINT CPolicyComponentData::ParseValue_W(PARSEPROCSTRUCT * ppps,TCHAR * pszWordBuf,
  3162. DWORD cbWordBuf,DWORD * pdwValue,DWORD * pdwFlags,BOOL * pfMore)
  3163. {
  3164. UINT uErr;
  3165. *pdwFlags = 0;
  3166. *pdwValue = 0;
  3167. // get the next word
  3168. if (!GetNextSectionWord(pszWordBuf,cbWordBuf,
  3169. NULL,NULL,pfMore,&uErr))
  3170. return uErr;
  3171. // if this keyword is "SOFT", set the soft flag and get the next word
  3172. if (!lstrcmpi(szSOFT,pszWordBuf)) {
  3173. *pdwFlags |= VF_SOFT;
  3174. if (!GetNextSectionWord(pszWordBuf,cbWordBuf,
  3175. NULL,NULL,pfMore,&uErr))
  3176. return uErr;
  3177. }
  3178. // this word is either the value to use, or the keyword "NUMERIC"
  3179. // followed by a numeric value to use
  3180. if (!lstrcmpi(szNUMERIC,pszWordBuf)) {
  3181. // get the next word
  3182. if (!GetNextSectionWord(pszWordBuf,cbWordBuf,
  3183. NULL,NULL,pfMore,&uErr))
  3184. return uErr;
  3185. if (!StringToNum(pszWordBuf,(UINT *)pdwValue)) {
  3186. DisplayKeywordError(IDS_ParseErr_NOT_NUMERIC,
  3187. pszWordBuf,NULL);
  3188. return ERROR_ALREADY_DISPLAYED;
  3189. }
  3190. *pdwFlags |= VF_ISNUMERIC;
  3191. } else {
  3192. // "DELETE" is a special word
  3193. if (!lstrcmpi(pszWordBuf,szDELETE))
  3194. *pdwFlags |= VF_DELETE;
  3195. }
  3196. return ERROR_SUCCESS;
  3197. }
  3198. UINT CPolicyComponentData::ParseValue(PARSEPROCSTRUCT * ppps,UINT * puOffsetData,
  3199. TABLEENTRY ** ppTableEntryNew,BOOL * pfMore)
  3200. {
  3201. TCHAR szWordBuf[WORDBUFSIZE+1];
  3202. STATEVALUE * pStateValue;
  3203. DWORD dwValue;
  3204. DWORD dwFlags = 0;
  3205. DWORD dwAlloc;
  3206. UINT uErr;
  3207. TABLEENTRY *pTmp;
  3208. HRESULT hr = S_OK;
  3209. // call worker function
  3210. uErr=ParseValue_W(ppps,szWordBuf,ARRAYSIZE(szWordBuf),&dwValue,
  3211. &dwFlags,pfMore);
  3212. if (uErr != ERROR_SUCCESS) return uErr;
  3213. dwAlloc = sizeof(STATEVALUE);
  3214. if (!dwFlags) dwAlloc += (lstrlen(szWordBuf) + 1) * sizeof(TCHAR);
  3215. // allocate temporary buffer to build STATEVALUE struct
  3216. pStateValue = (STATEVALUE *) GlobalAlloc(GPTR,dwAlloc);
  3217. if (!pStateValue)
  3218. return ERROR_NOT_ENOUGH_MEMORY;
  3219. pStateValue->dwFlags = dwFlags;
  3220. if (dwFlags & VF_ISNUMERIC)
  3221. pStateValue->dwValue = dwValue;
  3222. else if (!dwFlags) {
  3223. hr = StringCchCopy(pStateValue->szValue, lstrlen(szWordBuf) + 1, szWordBuf);
  3224. ASSERT(SUCCEEDED(hr));
  3225. }
  3226. pTmp=(TABLEENTRY *) AddDataToEntry(ppps->pTableEntry,
  3227. (BYTE *) pStateValue,dwAlloc,puOffsetData,NULL);
  3228. GlobalFree(pStateValue);
  3229. if (!pTmp)
  3230. return ERROR_NOT_ENOUGH_MEMORY;
  3231. *ppTableEntryNew = pTmp;
  3232. return FALSE;
  3233. }
  3234. #define DEF_SUGGESTBUF_SIZE 1024
  3235. #define SUGGESTBUF_INCREMENT 256
  3236. UINT CPolicyComponentData::ParseSuggestions(PARSEPROCSTRUCT * ppps,UINT * puOffsetData,
  3237. TABLEENTRY ** ppTableEntryNew,BOOL * pfMore)
  3238. {
  3239. TCHAR szWordBuf[WORDBUFSIZE+1];
  3240. TCHAR *pTmpBuf, *pTmp;
  3241. DWORD dwAlloc=DEF_SUGGESTBUF_SIZE * sizeof(TCHAR);
  3242. DWORD dwUsed = 0;
  3243. BOOL fContinue = TRUE;
  3244. UINT uErr;
  3245. TABLEENTRY *pTmpTblEntry;
  3246. HRESULT hr = S_OK;
  3247. KEYWORDINFO pSuggestionsTypeCmpList[] = { {szSUGGESTIONS,KYWD_ID_SUGGESTIONS},
  3248. {NULL,0} };
  3249. if (!(pTmpBuf = (TCHAR *) GlobalAlloc(GPTR,dwAlloc)))
  3250. return ERROR_NOT_ENOUGH_MEMORY;
  3251. // get the next word
  3252. while (fContinue && GetNextSectionWord(szWordBuf,
  3253. ARRAYSIZE(szWordBuf),NULL,NULL,pfMore,&uErr)) {
  3254. // if this word is "END", add the whole list to the setting object data
  3255. if (!lstrcmpi(szEND,szWordBuf)) {
  3256. // get the next word after "END, make sure it's "SUGGESTIONS"
  3257. if (!GetNextSectionWord(szWordBuf,ARRAYSIZE(szWordBuf),
  3258. pSuggestionsTypeCmpList,NULL,pfMore,&uErr)) {
  3259. GlobalFree(pTmpBuf);
  3260. return uErr;
  3261. }
  3262. // doubly-NULL terminate the list
  3263. *(pTmpBuf+dwUsed) = '\0';
  3264. dwUsed++;
  3265. pTmpTblEntry=(TABLEENTRY *)AddDataToEntry(ppps->pTableEntry,
  3266. (BYTE *)pTmpBuf,(dwUsed * sizeof(TCHAR)),puOffsetData,NULL);
  3267. if (!pTmpTblEntry) {
  3268. GlobalFree(pTmpBuf);
  3269. return ERROR_NOT_ENOUGH_MEMORY;
  3270. }
  3271. *ppTableEntryNew = pTmpTblEntry;
  3272. fContinue = FALSE;
  3273. } else {
  3274. // pack the word into the temporary buffer
  3275. UINT nLength = lstrlen(szWordBuf);
  3276. DWORD dwNeeded = (dwUsed + nLength + 2) * sizeof(TCHAR);
  3277. // resize buffer as necessary
  3278. if (dwNeeded > dwAlloc) {
  3279. while (dwAlloc < dwNeeded)
  3280. dwAlloc += SUGGESTBUF_INCREMENT;
  3281. if (!(pTmp = (TCHAR *) GlobalReAlloc(pTmpBuf,dwAlloc,
  3282. GMEM_MOVEABLE | GMEM_ZEROINIT)))
  3283. {
  3284. GlobalFree (pTmpBuf);
  3285. return ERROR_NOT_ENOUGH_MEMORY;
  3286. }
  3287. pTmpBuf = pTmp;
  3288. }
  3289. hr = StringCchCopy(pTmpBuf + dwUsed, dwNeeded - dwUsed, szWordBuf);
  3290. ASSERT(SUCCEEDED(hr));
  3291. dwUsed += lstrlen(szWordBuf) +1;
  3292. }
  3293. }
  3294. GlobalFree(pTmpBuf);
  3295. return uErr;
  3296. }
  3297. UINT CPolicyComponentData::ParseActionList(PARSEPROCSTRUCT * ppps,UINT * puOffsetData,
  3298. TABLEENTRY ** ppTableEntryNew,
  3299. LPCTSTR pszKeyword,BOOL * pfMore)
  3300. {
  3301. TCHAR szWordBuf[WORDBUFSIZE+1];
  3302. ACTIONLIST *pActionList;
  3303. ACTION *pActionCurrent;
  3304. UINT uOffsetActionCurrent;
  3305. DWORD dwAlloc=(DEF_SUGGESTBUF_SIZE * sizeof(TCHAR));
  3306. DWORD dwUsed = sizeof(ACTION) + sizeof(UINT);
  3307. UINT uErr=ERROR_SUCCESS,nIndex;
  3308. BOOL fContinue = TRUE;
  3309. TABLEENTRY *pTmp;
  3310. KEYWORDINFO pActionlistTypeCmpList[] = { {szKEYNAME,KYWD_ID_KEYNAME},
  3311. {szVALUENAME,KYWD_ID_VALUENAME},{szVALUE,KYWD_ID_VALUE},
  3312. {szEND,KYWD_ID_END},{NULL,0} };
  3313. KEYWORDINFO pActionlistCmpList[] = { {pszKeyword,KYWD_ID_ACTIONLIST},
  3314. {NULL,0} };
  3315. BOOL fHasKeyName=FALSE,fHasValueName=FALSE;
  3316. if (!(pActionList = (ACTIONLIST *) GlobalAlloc(GPTR,dwAlloc)))
  3317. return ERROR_NOT_ENOUGH_MEMORY;
  3318. pActionCurrent = pActionList->Action;
  3319. uOffsetActionCurrent = sizeof(UINT);
  3320. // get the next word
  3321. while ((uErr == ERROR_SUCCESS) && fContinue &&
  3322. GetNextSectionWord(szWordBuf,ARRAYSIZE(szWordBuf),
  3323. pActionlistTypeCmpList,&nIndex,pfMore,&uErr)) {
  3324. switch (nIndex) {
  3325. case KYWD_ID_KEYNAME:
  3326. if (fHasKeyName) {
  3327. DisplayKeywordError(IDS_ParseErr_DUPLICATE_KEYNAME,
  3328. NULL,NULL);
  3329. uErr = ERROR_ALREADY_DISPLAYED;
  3330. break;
  3331. }
  3332. // get the next word, which is the key name
  3333. if (!GetNextSectionWord(szWordBuf,
  3334. ARRAYSIZE(szWordBuf),NULL,NULL,pfMore,&uErr))
  3335. break;
  3336. // store the key name away
  3337. if (!AddActionListString(szWordBuf,(lstrlen(szWordBuf)+1) * sizeof(TCHAR),
  3338. (BYTE **)&pActionList,
  3339. &pActionCurrent->uOffsetKeyName,&dwAlloc,&dwUsed)) {
  3340. uErr = ERROR_NOT_ENOUGH_MEMORY;
  3341. break;
  3342. }
  3343. fHasKeyName = TRUE;
  3344. pActionCurrent = (ACTION *) ((BYTE *) pActionList + uOffsetActionCurrent);
  3345. break;
  3346. case KYWD_ID_VALUENAME:
  3347. if (fHasValueName) {
  3348. DisplayKeywordError(IDS_ParseErr_DUPLICATE_KEYNAME,
  3349. NULL,NULL);
  3350. uErr = ERROR_ALREADY_DISPLAYED;
  3351. break;
  3352. }
  3353. // get the next word, which is the value name
  3354. if (!GetNextSectionWord(szWordBuf,
  3355. ARRAYSIZE(szWordBuf),NULL,NULL,pfMore,&uErr))
  3356. break;
  3357. // store the value name away
  3358. if (!AddActionListString(szWordBuf,(lstrlen(szWordBuf)+1) * sizeof(TCHAR),
  3359. (BYTE **)&pActionList,
  3360. &pActionCurrent->uOffsetValueName,&dwAlloc,&dwUsed)) {
  3361. uErr = ERROR_NOT_ENOUGH_MEMORY;
  3362. break;
  3363. }
  3364. fHasValueName = TRUE;
  3365. pActionCurrent = (ACTION *) ((BYTE *) pActionList + uOffsetActionCurrent);
  3366. break;
  3367. case KYWD_ID_VALUE:
  3368. if (!fHasValueName) {
  3369. DisplayKeywordError(IDS_ParseErr_NO_VALUENAME,
  3370. NULL,NULL);
  3371. uErr = ERROR_ALREADY_DISPLAYED;
  3372. break;
  3373. }
  3374. // call worker function to get value and value type
  3375. uErr=ParseValue_W(ppps,szWordBuf,ARRAYSIZE(szWordBuf),
  3376. &pActionCurrent->dwValue,&pActionCurrent->dwFlags,pfMore);
  3377. if (uErr != ERROR_SUCCESS)
  3378. break;
  3379. // if value is string, add it to buffer
  3380. if (!pActionCurrent->dwFlags && !AddActionListString(szWordBuf,
  3381. (lstrlen(szWordBuf)+1) * sizeof(TCHAR),(BYTE **)&pActionList,
  3382. &pActionCurrent->uOffsetValue,&dwAlloc,&dwUsed)) {
  3383. uErr = ERROR_NOT_ENOUGH_MEMORY;
  3384. break;
  3385. }
  3386. pActionCurrent = (ACTION *) ((BYTE *) pActionList + uOffsetActionCurrent);
  3387. // done with this action in the list, get ready for the next one
  3388. pActionList->nActionItems++;
  3389. fHasValueName = fHasKeyName = FALSE;
  3390. uOffsetActionCurrent = dwUsed;
  3391. // make room for next ACTION struct
  3392. if (!AddActionListString(NULL,sizeof(ACTION),(BYTE **)&pActionList,
  3393. &pActionCurrent->uOffsetNextAction,&dwAlloc,&dwUsed)) {
  3394. uErr = ERROR_NOT_ENOUGH_MEMORY;
  3395. break;
  3396. }
  3397. pActionCurrent = (ACTION *) ((BYTE *) pActionList + uOffsetActionCurrent);
  3398. break;
  3399. case KYWD_ID_END:
  3400. if (fHasKeyName || fHasValueName) {
  3401. DisplayKeywordError(IDS_ParseErr_NO_VALUENAME,
  3402. NULL,NULL);
  3403. uErr = ERROR_ALREADY_DISPLAYED;
  3404. break;
  3405. }
  3406. // make sure word following "END" is "ACTIONLIST"
  3407. if (!GetNextSectionWord(szWordBuf,ARRAYSIZE(szWordBuf),
  3408. pActionlistCmpList,NULL,pfMore,&uErr)) {
  3409. break;
  3410. }
  3411. // commit the action list we've built to table entry
  3412. pTmp=(TABLEENTRY *)AddDataToEntry(ppps->pTableEntry,
  3413. (BYTE *)pActionList,dwUsed,puOffsetData,NULL);
  3414. if (!pTmp) {
  3415. uErr=ERROR_NOT_ENOUGH_MEMORY;
  3416. } else {
  3417. *ppTableEntryNew = pTmp;
  3418. uErr = ERROR_SUCCESS;
  3419. fContinue = FALSE;
  3420. }
  3421. break;
  3422. }
  3423. }
  3424. GlobalFree(pActionList);
  3425. return uErr;
  3426. }
  3427. UINT CPolicyComponentData::ParseItemList(PARSEPROCSTRUCT * ppps,UINT * puOffsetData,
  3428. BOOL * pfMore)
  3429. {
  3430. // ptr to location to put the offset to next DROPDOWNINFO struct in chain
  3431. UINT * puLastOffsetPtr = puOffsetData;
  3432. TABLEENTRY * pTableEntryOld, *pTmp;
  3433. int nItemIndex=-1;
  3434. BOOL fHasItemName = FALSE,fHasActionList=FALSE,fHasValue=FALSE,fFirst=TRUE;
  3435. DROPDOWNINFO * pddi;
  3436. TCHAR szWordBuf[WORDBUFSIZE+1];
  3437. UINT uErr=ERROR_SUCCESS,nIndex;
  3438. KEYWORDINFO pItemlistTypeCmpList[] = { {szNAME,KYWD_ID_NAME},
  3439. {szACTIONLIST,KYWD_ID_ACTIONLIST},{szVALUE,KYWD_ID_VALUE},
  3440. {szEND,KYWD_ID_END},{szDEFAULT,KYWD_ID_DEFAULT},{NULL,0} };
  3441. KEYWORDINFO pItemlistCmpList[] = { {szITEMLIST,KYWD_ID_ITEMLIST},
  3442. {NULL,0} };
  3443. // get the next word
  3444. while ((uErr == ERROR_SUCCESS) &&
  3445. GetNextSectionWord(szWordBuf,ARRAYSIZE(szWordBuf),
  3446. pItemlistTypeCmpList,&nIndex,pfMore,&uErr)) {
  3447. switch (nIndex) {
  3448. case KYWD_ID_NAME:
  3449. // if this is the first keyword after a prior item
  3450. // (e.g., item and value flags both set) reset for next one
  3451. if (fHasItemName && fHasValue) {
  3452. fHasValue = fHasActionList= fHasItemName = FALSE;
  3453. puLastOffsetPtr = &pddi->uOffsetNextDropdowninfo;
  3454. }
  3455. if (fHasItemName) {
  3456. DisplayKeywordError(IDS_ParseErr_DUPLICATE_ITEMNAME,
  3457. NULL,NULL);
  3458. uErr = ERROR_ALREADY_DISPLAYED;
  3459. break;
  3460. }
  3461. // get the next word, which is the item name
  3462. if (!GetNextSectionWord(szWordBuf,
  3463. ARRAYSIZE(szWordBuf),NULL,NULL,pfMore,&uErr))
  3464. break;
  3465. // add room for a DROPDOWNINFO struct at end of buffer
  3466. pTableEntryOld=ppps->pTableEntry;
  3467. pTmp=(TABLEENTRY *)AddDataToEntry(ppps->pTableEntry,
  3468. NULL,sizeof(DROPDOWNINFO),puLastOffsetPtr,NULL);
  3469. if (!pTmp)
  3470. return ERROR_NOT_ENOUGH_MEMORY;
  3471. ppps->pTableEntry = pTmp;
  3472. // adjust pointer to offset, in case table moved
  3473. puLastOffsetPtr = (UINT *) (((BYTE *) puLastOffsetPtr) +
  3474. ((BYTE *) ppps->pTableEntry - (BYTE *) pTableEntryOld));
  3475. pddi = (DROPDOWNINFO *)
  3476. ((BYTE *) ppps->pTableEntry + *puLastOffsetPtr);
  3477. // store the key name away
  3478. pTableEntryOld=ppps->pTableEntry;
  3479. pTmp=(TABLEENTRY *)AddDataToEntry(ppps->pTableEntry,
  3480. (BYTE *)szWordBuf,(lstrlen(szWordBuf)+1)*sizeof(TCHAR),&pddi->uOffsetItemName,
  3481. NULL);
  3482. if (!pTmp)
  3483. return ERROR_NOT_ENOUGH_MEMORY;
  3484. ppps->pTableEntry = pTmp;
  3485. // adjust pointer to offset, in case table moved
  3486. puLastOffsetPtr = (UINT *) (((BYTE *) puLastOffsetPtr) +
  3487. ((BYTE *) ppps->pTableEntry - (BYTE *) pTableEntryOld));
  3488. pddi = (DROPDOWNINFO *)
  3489. ((BYTE *) ppps->pTableEntry + *puLastOffsetPtr);
  3490. nItemIndex++;
  3491. fHasItemName = TRUE;
  3492. break;
  3493. case KYWD_ID_DEFAULT:
  3494. if (nItemIndex<0) {
  3495. DisplayKeywordError(IDS_ParseErr_NO_ITEMNAME,
  3496. NULL,NULL);
  3497. uErr = ERROR_ALREADY_DISPLAYED;
  3498. break;
  3499. }
  3500. ( (SETTINGS *) ppps->pTableEntry)->dwFlags |= DF_USEDEFAULT;
  3501. ( (DROPDOWNINFO *) GETOBJECTDATAPTR(((SETTINGS *)ppps->pTableEntry)))
  3502. ->uDefaultItemIndex = nItemIndex;
  3503. break;
  3504. case KYWD_ID_VALUE:
  3505. if (!fHasItemName) {
  3506. DisplayKeywordError(IDS_ParseErr_NO_ITEMNAME,
  3507. NULL,NULL);
  3508. uErr = ERROR_ALREADY_DISPLAYED;
  3509. break;
  3510. }
  3511. // call worker function to get value and value type
  3512. uErr=ParseValue_W(ppps,szWordBuf,ARRAYSIZE(szWordBuf),
  3513. &pddi->dwValue,&pddi->dwFlags,pfMore);
  3514. if (uErr != ERROR_SUCCESS)
  3515. break;
  3516. // if value is string, add it to buffer
  3517. if (!pddi->dwFlags) {
  3518. // store the key name away
  3519. TABLEENTRY * pTmpTable;
  3520. pTableEntryOld = ppps->pTableEntry;
  3521. pTmpTable = (TABLEENTRY *) AddDataToEntry(ppps->pTableEntry,
  3522. (BYTE *)szWordBuf,(lstrlen(szWordBuf)+1)*sizeof(TCHAR),&pddi->uOffsetValue,
  3523. NULL);
  3524. if (!pTmpTable)
  3525. return ERROR_NOT_ENOUGH_MEMORY;
  3526. ppps->pTableEntry = pTmpTable;
  3527. // adjust pointer to offset, in case table moved
  3528. puLastOffsetPtr = (UINT *) (((BYTE *) puLastOffsetPtr) +
  3529. ((BYTE *) ppps->pTableEntry - (BYTE *) pTableEntryOld));
  3530. pddi = (DROPDOWNINFO *)
  3531. ((BYTE *) ppps->pTableEntry + *puLastOffsetPtr);
  3532. }
  3533. fHasValue = TRUE;
  3534. break;
  3535. case KYWD_ID_ACTIONLIST:
  3536. if (!fHasItemName) {
  3537. DisplayKeywordError(IDS_ParseErr_NO_ITEMNAME,
  3538. NULL,NULL);
  3539. uErr = ERROR_ALREADY_DISPLAYED;
  3540. break;
  3541. }
  3542. if (fHasActionList) {
  3543. DisplayKeywordError(IDS_ParseErr_DUPLICATE_ACTIONLIST,
  3544. NULL,NULL);
  3545. uErr = ERROR_ALREADY_DISPLAYED;
  3546. break;
  3547. }
  3548. pTableEntryOld=ppps->pTableEntry;
  3549. uErr=ParseActionList(ppps,&pddi->uOffsetActionList,
  3550. &ppps->pTableEntry,szACTIONLIST,pfMore);
  3551. if (uErr != ERROR_SUCCESS)
  3552. return uErr;
  3553. // adjust pointer to offset, in case table moved
  3554. puLastOffsetPtr = (UINT *) (((BYTE *) puLastOffsetPtr) +
  3555. ((BYTE *) ppps->pTableEntry - (BYTE *) pTableEntryOld));
  3556. pddi = (DROPDOWNINFO *)
  3557. ((BYTE *) ppps->pTableEntry + *puLastOffsetPtr);
  3558. fHasActionList = TRUE;
  3559. break;
  3560. case KYWD_ID_END:
  3561. if (!fHasItemName) {
  3562. DisplayKeywordError(IDS_ParseErr_NO_ITEMNAME,
  3563. NULL,NULL);
  3564. uErr = ERROR_ALREADY_DISPLAYED;
  3565. break;
  3566. }
  3567. if (!fHasValue) {
  3568. DisplayKeywordError(IDS_ParseErr_NO_VALUE,
  3569. NULL,NULL);
  3570. uErr = ERROR_ALREADY_DISPLAYED;
  3571. break;
  3572. }
  3573. // make sure word following "END" is "ITEMLIST"
  3574. if (!GetNextSectionWord(szWordBuf,ARRAYSIZE(szWordBuf),
  3575. pItemlistCmpList,NULL,pfMore,&uErr)) {
  3576. break;
  3577. }
  3578. return ERROR_SUCCESS;
  3579. break;
  3580. }
  3581. }
  3582. return uErr;
  3583. }
  3584. BOOL CPolicyComponentData::AddActionListString(TCHAR * pszData,DWORD cbData,BYTE ** ppBase,UINT * puOffset,
  3585. DWORD * pdwAlloc,DWORD *pdwUsed)
  3586. {
  3587. DWORD dwNeeded = *pdwUsed + cbData, dwAdd;
  3588. dwAdd = dwNeeded % sizeof(DWORD);
  3589. dwNeeded += dwAdd;
  3590. // realloc if necessary
  3591. if (dwNeeded > *pdwAlloc) {
  3592. while (*pdwAlloc < dwNeeded)
  3593. {
  3594. *pdwAlloc += SUGGESTBUF_INCREMENT;
  3595. }
  3596. BYTE *pNewBase = (BYTE *) GlobalReAlloc(*ppBase,*pdwAlloc,GMEM_MOVEABLE | GMEM_ZEROINIT);
  3597. if ( pNewBase == NULL )
  3598. {
  3599. return FALSE;
  3600. }
  3601. puOffset = (UINT *)(pNewBase + ((BYTE *)puOffset - *ppBase));
  3602. *ppBase = pNewBase;
  3603. }
  3604. *puOffset = *pdwUsed;
  3605. if (pszData) memcpy(*ppBase + *puOffset,pszData,cbData);
  3606. *pdwUsed = dwNeeded;
  3607. return TRUE;
  3608. }
  3609. BYTE * CPolicyComponentData::AddDataToEntry(TABLEENTRY * pTableEntry,
  3610. BYTE * pData,UINT cbData,
  3611. UINT * puOffsetData,DWORD * pdwBufSize)
  3612. {
  3613. TABLEENTRY * pTemp;
  3614. DWORD dwNeeded,dwOldSize = pTableEntry->dwSize, dwNewDataSize, dwAdd;
  3615. // puOffsetData points to location that holds the offset to the
  3616. // new data-- size we're adding this to the end of the table, the
  3617. // offset will be the current size of the table. Set this offset
  3618. // in *puOffsetData. Also, notice we touch *puOffsetData BEFORE
  3619. // the realloc, in case puOffsetData points into the region being
  3620. // realloced and the block of memory moves.
  3621. //
  3622. *puOffsetData = pTableEntry->dwSize;
  3623. // reallocate entry buffer if necessary
  3624. dwNewDataSize = cbData;
  3625. dwAdd = dwNewDataSize % sizeof(DWORD);
  3626. dwNewDataSize += dwAdd;
  3627. dwNeeded = pTableEntry->dwSize + dwNewDataSize;
  3628. if (!(pTemp = (TABLEENTRY *) GlobalReAlloc(pTableEntry,
  3629. dwNeeded,GMEM_ZEROINIT | GMEM_MOVEABLE)))
  3630. return NULL;
  3631. pTableEntry = pTemp;
  3632. pTableEntry->dwSize = dwNeeded;
  3633. if (pData) memcpy((BYTE *)pTableEntry + dwOldSize,pData,cbData);
  3634. if (pdwBufSize) *pdwBufSize = pTableEntry->dwSize;
  3635. return (BYTE *) pTableEntry;
  3636. }
  3637. /*******************************************************************
  3638. NAME: CompareKeyword
  3639. SYNOPSIS: Compares a specified buffer to a list of valid keywords.
  3640. If it finds a match, the index of the match in the list
  3641. is returned in *pnListIndex. Otherwise an error message
  3642. is displayed.
  3643. EXIT: Returns TRUE if a keyword match is found, FALSE otherwise.
  3644. If TRUE, *pnListIndex contains matching index.
  3645. ********************************************************************/
  3646. BOOL CPolicyComponentData::CompareKeyword(TCHAR * szWord,KEYWORDINFO *pKeywordList,
  3647. UINT * pnListIndex)
  3648. {
  3649. KEYWORDINFO * pKeywordInfo = pKeywordList;
  3650. while (pKeywordInfo->pWord) {
  3651. if (!lstrcmpi(szWord,pKeywordInfo->pWord)) {
  3652. if (pnListIndex)
  3653. *pnListIndex = pKeywordInfo->nID;
  3654. return TRUE;
  3655. }
  3656. pKeywordInfo ++;
  3657. }
  3658. DisplayKeywordError(IDS_ParseErr_UNEXPECTED_KEYWORD,
  3659. szWord,pKeywordList);
  3660. return FALSE;
  3661. }
  3662. /*******************************************************************
  3663. NAME: GetNextWord
  3664. SYNOPSIS: Fills input buffer with next word in file stream
  3665. NOTES: Calls GetNextChar() to get character stream. Whitespace
  3666. and comments are skipped. Quoted strings are returned
  3667. as one word (including whitespace) with the quotes removed.
  3668. EXIT: If successful, returns a pointer to the input buffer
  3669. (szBuf). *pfMore indicates if there are more words to
  3670. be read. If an error occurs, its value is returned in *puErr.
  3671. ********************************************************************/
  3672. TCHAR * CPolicyComponentData::GetNextWord(TCHAR * szBuf,UINT cbBuf,BOOL * pfMore,
  3673. UINT * puErr)
  3674. {
  3675. TCHAR * pChar;
  3676. BOOL fInWord = FALSE;
  3677. BOOL fInQuote = FALSE;
  3678. BOOL fEmptyString = FALSE;
  3679. TCHAR * pWord = szBuf;
  3680. UINT cbWord = 0;
  3681. LPTSTR lpTemp;
  3682. HRESULT hr = S_OK;
  3683. // clear buffer to start with
  3684. (void) StringCchCopy(szBuf, cbBuf, g_szNull);
  3685. while (pChar = GetNextChar(pfMore,puErr)) {
  3686. // keep track of which file line we're on
  3687. if (IsEndOfLine(pChar)) m_nFileLine++;
  3688. // keep track of wheter we are inside quoted string or not
  3689. if (IsQuote(pChar) && !m_fInComment) {
  3690. if (!fInQuote)
  3691. fInQuote = TRUE; // entering quoted string
  3692. else {
  3693. fInQuote = FALSE; // leaving quoted string
  3694. if (cbWord == 0) {
  3695. // special case "" to be an empty string
  3696. DebugMsg((DM_VERBOSE, TEXT("CPolicyComponentData::GetNextWord: Found empty quotes")));
  3697. fEmptyString = TRUE;
  3698. }
  3699. break; // end of word
  3700. }
  3701. }
  3702. if (!fInQuote) {
  3703. // skip over lines with comments (';')
  3704. if (!m_fInComment && IsComment(pChar)) {
  3705. m_fInComment = TRUE;
  3706. }
  3707. if (m_fInComment) {
  3708. if (IsEndOfLine(pChar)) {
  3709. m_fInComment = FALSE;
  3710. }
  3711. continue;
  3712. }
  3713. if (IsWhitespace(pChar)) {
  3714. // if we haven't found word yet, skip over whitespace
  3715. if (!fInWord)
  3716. continue;
  3717. // otherwise, whitespace signals end of word
  3718. break;
  3719. }
  3720. }
  3721. // found a non-comment, non-whitespace character
  3722. if (!fInWord) fInWord = TRUE;
  3723. if (!IsQuote(pChar)) {
  3724. // add this character to word
  3725. *pWord = *pChar;
  3726. pWord++;
  3727. cbWord++;
  3728. if (cbWord >= cbBuf) {
  3729. *(pWord - 1) = TEXT('\0');
  3730. MsgBoxParam(NULL,IDS_WORDTOOLONG,szBuf,MB_ICONEXCLAMATION,MB_OK);
  3731. *puErr = ERROR_ALREADY_DISPLAYED;
  3732. goto Exit;
  3733. }
  3734. #if 0
  3735. if (IsDBCSLeadByte((BYTE) *pChar)) {
  3736. *pWord = *pChar;
  3737. pWord++;
  3738. cbWord++;
  3739. }
  3740. #endif
  3741. }
  3742. }
  3743. *pWord = '\0'; // null-terminate
  3744. // if found string a la '!!abc', then look for a string in the [strings]
  3745. // section with the key name 'abc' and use that instead. This is because
  3746. // our localization tools are brainless and require a [strings] section.
  3747. // So although template files are sectionless, we allow a [strings] section
  3748. // at the bottom.
  3749. if (IsLocalizedString(szBuf)) {
  3750. lpTemp = (LPTSTR) GlobalAlloc (GPTR, (cbBuf * sizeof(TCHAR)));
  3751. if (!lpTemp) {
  3752. *puErr = GetLastError();
  3753. return NULL;
  3754. }
  3755. if (GetString (m_pLocaleHashTable, szBuf+2, lpTemp, cbBuf) ||
  3756. GetString (m_pLanguageHashTable, szBuf+2, lpTemp, cbBuf) ||
  3757. GetString (m_pDefaultHashTable, szBuf+2, lpTemp, cbBuf))
  3758. {
  3759. hr = StringCchCopy(szBuf, cbBuf, lpTemp);
  3760. ASSERT(SUCCEEDED(hr));
  3761. GlobalFree (lpTemp);
  3762. }
  3763. else
  3764. {
  3765. DisplayKeywordError(IDS_ParseErr_STRING_NOT_FOUND,
  3766. szBuf,NULL);
  3767. *puErr=ERROR_ALREADY_DISPLAYED;
  3768. GlobalFree (lpTemp);
  3769. return NULL;
  3770. }
  3771. } else {
  3772. *puErr = ProcessIfdefs(szBuf,cbBuf,pfMore);
  3773. if (*puErr == ERROR_SUCCESS)
  3774. {
  3775. if ((szBuf[0] == TEXT('\0')) && (!fEmptyString))
  3776. {
  3777. fInWord = FALSE;
  3778. }
  3779. }
  3780. }
  3781. Exit:
  3782. if (*puErr != ERROR_SUCCESS || !fInWord) return NULL;
  3783. return szBuf;
  3784. }
  3785. /*******************************************************************
  3786. NAME: GetNextSectionWord
  3787. SYNOPSIS: Gets next word and warns if end-of-file encountered.
  3788. Optionally checks the keyword against a list of valid
  3789. keywords.
  3790. NOTES: Calls GetNextWord() to get word. This is called in
  3791. situations where we expect there to be another word
  3792. (e.g., inside a section) and it's an error if the
  3793. file ends.
  3794. ********************************************************************/
  3795. TCHAR * CPolicyComponentData::GetNextSectionWord(TCHAR * szBuf,UINT cbBuf,
  3796. KEYWORDINFO * pKeywordList,
  3797. UINT *pnListIndex,
  3798. BOOL * pfMore,UINT * puErr)
  3799. {
  3800. TCHAR * pch;
  3801. if (!(pch=GetNextWord(szBuf,cbBuf,pfMore,puErr))) {
  3802. if (!*pfMore && *puErr != ERROR_ALREADY_DISPLAYED) {
  3803. DisplayKeywordError(IDS_ParseErr_UNEXPECTED_EOF,
  3804. NULL,pKeywordList);
  3805. *puErr = ERROR_ALREADY_DISPLAYED;
  3806. }
  3807. return NULL;
  3808. }
  3809. if (pKeywordList && !CompareKeyword(szBuf,pKeywordList,pnListIndex)) {
  3810. *puErr = ERROR_ALREADY_DISPLAYED;
  3811. return NULL;
  3812. }
  3813. return pch;
  3814. }
  3815. /*******************************************************************
  3816. NAME: GetNextSectionNumericWord
  3817. SYNOPSIS: Gets next word and converts string to number. Warns if
  3818. not a numeric value
  3819. ********************************************************************/
  3820. UINT CPolicyComponentData::GetNextSectionNumericWord(UINT * pnVal)
  3821. {
  3822. UINT uErr;
  3823. TCHAR szWordBuf[WORDBUFSIZE];
  3824. BOOL fMore;
  3825. if (!GetNextSectionWord(szWordBuf,ARRAYSIZE(szWordBuf),
  3826. NULL,NULL,&fMore,&uErr))
  3827. return uErr;
  3828. if (!StringToNum(szWordBuf,pnVal)) {
  3829. DisplayKeywordError(IDS_ParseErr_NOT_NUMERIC,szWordBuf,
  3830. NULL);
  3831. return ERROR_ALREADY_DISPLAYED;
  3832. }
  3833. return ERROR_SUCCESS;
  3834. }
  3835. /*******************************************************************
  3836. NAME: GetNextChar
  3837. SYNOPSIS: Returns a pointer to the next character from the
  3838. file stream.
  3839. ********************************************************************/
  3840. TCHAR * CPolicyComponentData::GetNextChar(BOOL * pfMore,UINT * puErr)
  3841. {
  3842. TCHAR * pCurrentChar;
  3843. *puErr = ERROR_SUCCESS;
  3844. if (m_pFilePtr > m_pFileEnd) {
  3845. *pfMore = FALSE;
  3846. return NULL;
  3847. }
  3848. pCurrentChar = m_pFilePtr;
  3849. m_pFilePtr = CharNext(m_pFilePtr);
  3850. *pfMore = TRUE;
  3851. return pCurrentChar;
  3852. }
  3853. /*******************************************************************
  3854. NAME: GetString
  3855. SYNOPSIS: Returns the display string
  3856. ********************************************************************/
  3857. BOOL CPolicyComponentData::GetString (LPHASHTABLE lpHashTable,
  3858. LPTSTR lpStringName,
  3859. LPTSTR lpResult, DWORD dwSize)
  3860. {
  3861. LPTSTR lpTemp, lpDest;
  3862. DWORD dwCCH, dwIndex;
  3863. BOOL bFoundQuote = FALSE;
  3864. TCHAR cTestChar;
  3865. if (!lpHashTable)
  3866. {
  3867. return FALSE;
  3868. }
  3869. if (!m_bRetrieveString)
  3870. {
  3871. lpResult = TEXT('\0');
  3872. return TRUE;
  3873. }
  3874. dwCCH = lstrlen (lpStringName);
  3875. lpTemp = FindHashEntry (lpHashTable, lpStringName, dwCCH);
  3876. if (!lpTemp)
  3877. {
  3878. return FALSE;
  3879. }
  3880. lpTemp += dwCCH;
  3881. while (*lpTemp == TEXT(' '))
  3882. lpTemp++;
  3883. if (*lpTemp == TEXT('='))
  3884. {
  3885. lpTemp++;
  3886. if (*lpTemp == TEXT('\"'))
  3887. {
  3888. lpTemp++;
  3889. bFoundQuote = TRUE;
  3890. }
  3891. lpDest = lpResult;
  3892. dwIndex = 0;
  3893. while (*lpTemp && (dwIndex < dwSize))
  3894. {
  3895. *lpDest = *lpTemp;
  3896. lpDest++;
  3897. lpTemp++;
  3898. dwIndex++;
  3899. }
  3900. if (dwIndex == dwSize)
  3901. {
  3902. lpDest--;
  3903. *lpDest = TEXT('\0');
  3904. MsgBoxParam(NULL,IDS_STRINGTOOLONG,lpResult,MB_ICONEXCLAMATION,MB_OK);
  3905. }
  3906. else
  3907. {
  3908. *lpDest = TEXT('\0');
  3909. }
  3910. if (bFoundQuote)
  3911. {
  3912. lpTemp = lpResult + lstrlen (lpResult) - 1;
  3913. if (*lpTemp == TEXT('\"'))
  3914. {
  3915. *lpTemp = TEXT('\0');
  3916. }
  3917. }
  3918. //
  3919. // Replace any \n combinations with a CR LF
  3920. //
  3921. lpTemp = lpResult;
  3922. while (*lpTemp)
  3923. {
  3924. if ((*lpTemp == TEXT('\\')) && (*(lpTemp + 1) == TEXT('n')))
  3925. {
  3926. *lpTemp = TEXT('\r');
  3927. lpTemp++;
  3928. *lpTemp = TEXT('\n');
  3929. }
  3930. lpTemp++;
  3931. }
  3932. return TRUE;
  3933. }
  3934. return FALSE;
  3935. }
  3936. VOID CPolicyComponentData::FillHashTable(LPHASHTABLE lpTable, LPTSTR lpStrings)
  3937. {
  3938. LPTSTR lpTemp, lpStart;
  3939. lpTemp = lpStrings;
  3940. while (*lpTemp)
  3941. {
  3942. lpStart = lpTemp;
  3943. while ((*lpTemp) && (*lpTemp != TEXT(' ')) && (*lpTemp != TEXT('=')))
  3944. {
  3945. lpTemp++;
  3946. }
  3947. if (!(*lpTemp))
  3948. {
  3949. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::FillHashTable: Found end of line when expected a equal sign. Line found: %s"), lpStart));
  3950. return;
  3951. }
  3952. // The string will not be longer than 2^32 characters
  3953. ASSERT( (lpTemp - lpStart) <= 0xffffffff );
  3954. DWORD entryLength = (DWORD)(lpTemp - lpStart);
  3955. AddHashEntry (lpTable, lpStart, entryLength);
  3956. while (*lpTemp)
  3957. {
  3958. lpTemp++;
  3959. }
  3960. lpTemp++;
  3961. }
  3962. }
  3963. //
  3964. // CreateStringArray takes a string section and converts it to a array of strings.
  3965. // Each string is null terminated and the entire array is double null terminated at
  3966. // the end. This function is very similary to GetPrivateProfileSection, but considerably
  3967. // faster to execute.
  3968. //
  3969. LPTSTR CPolicyComponentData::CreateStringArray(LPTSTR lpStrings)
  3970. {
  3971. LPTSTR lpStrArray, lpSrc, lpDest;
  3972. DWORD dwIndex = 0;
  3973. TCHAR chLetter = 0;
  3974. lpStrArray = (LPTSTR) GlobalAlloc (GPTR, (m_pFileEnd - lpStrings + 1) * sizeof(WCHAR));
  3975. if (!lpStrArray)
  3976. {
  3977. return NULL;
  3978. }
  3979. lpSrc = lpStrings;
  3980. lpDest = lpStrArray;
  3981. while (lpSrc <= m_pFileEnd)
  3982. {
  3983. if (dwIndex == 0)
  3984. {
  3985. //
  3986. // Strip the white space off of the front of the line
  3987. //
  3988. while (*lpSrc == TEXT(' '))
  3989. {
  3990. lpSrc++;
  3991. }
  3992. //
  3993. // If we found a square bracket open, that is the beginning of a different
  3994. // string section. Exit now.
  3995. //
  3996. if (*lpSrc == TEXT('['))
  3997. {
  3998. break;
  3999. }
  4000. //
  4001. // If we found a semi-colon, this line is commented out
  4002. //
  4003. if (*lpSrc == TEXT(';'))
  4004. {
  4005. while (*lpSrc != TEXT('\r'))
  4006. {
  4007. lpSrc++;
  4008. }
  4009. lpSrc += 2;
  4010. }
  4011. }
  4012. if ((dwIndex == 0) && (*lpSrc == TEXT('\r')))
  4013. {
  4014. //
  4015. // Found a blank line
  4016. //
  4017. lpSrc += 2;
  4018. }
  4019. else
  4020. {
  4021. //
  4022. // Handle CR / LF combinations. Two cases:
  4023. // 1) If the line ends with a backslash, then the user has more text on the
  4024. // next line down (a continuation)
  4025. // 2) If the line does not end with a backslash, then that is the end of a
  4026. // string variable. Null terminate the string.
  4027. //
  4028. if (*lpSrc == TEXT('\r'))
  4029. {
  4030. //
  4031. // If the previous character was a backsash, we back the destination
  4032. // pointer up by 1 so that the backslash is removed.
  4033. //
  4034. if (chLetter == TEXT('\\'))
  4035. {
  4036. lpDest--;
  4037. }
  4038. else
  4039. {
  4040. *lpDest = TEXT('\0');
  4041. lpDest++;
  4042. dwIndex = 0;
  4043. }
  4044. lpSrc += 2;
  4045. }
  4046. else
  4047. {
  4048. chLetter = *lpDest = *lpSrc;
  4049. lpDest++;
  4050. lpSrc++;
  4051. dwIndex++;
  4052. }
  4053. }
  4054. }
  4055. return lpStrArray;
  4056. }
  4057. LPTSTR CPolicyComponentData::FindSection (LPTSTR lpSection)
  4058. {
  4059. LPTSTR lpTemp = m_pFilePtr;
  4060. DWORD dwColumn = 0;
  4061. DWORD dwStrLen = lstrlen (lpSection);
  4062. while (lpTemp < m_pFileEnd)
  4063. {
  4064. if ((*lpTemp == TEXT('[')) && (dwColumn == 0))
  4065. {
  4066. if (CompareString (LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE, lpTemp, dwStrLen,
  4067. lpSection, dwStrLen) == CSTR_EQUAL)
  4068. {
  4069. return lpTemp;
  4070. }
  4071. }
  4072. dwColumn++;
  4073. if (*lpTemp == TEXT('\n'))
  4074. {
  4075. dwColumn = 0;
  4076. }
  4077. lpTemp++;
  4078. }
  4079. return NULL;
  4080. }
  4081. BOOL CPolicyComponentData::IsComment(TCHAR * pBuf)
  4082. {
  4083. return (*pBuf == TEXT(';'));
  4084. }
  4085. BOOL CPolicyComponentData::IsQuote(TCHAR * pBuf)
  4086. {
  4087. return (*pBuf == TEXT('\"'));
  4088. }
  4089. BOOL CPolicyComponentData::IsEndOfLine(TCHAR * pBuf)
  4090. {
  4091. return (*pBuf == TEXT('\r')); // CR
  4092. }
  4093. BOOL CPolicyComponentData::IsWhitespace(TCHAR * pBuf)
  4094. {
  4095. return ( *pBuf == TEXT(' ') // space
  4096. || *pBuf == TEXT('\r') // CR
  4097. || *pBuf == TEXT('\n') // LF
  4098. || *pBuf == TEXT('\t') // tab
  4099. || *pBuf == 0x001A // EOF
  4100. || *pBuf == 0xFEFF // Unicode marker
  4101. );
  4102. }
  4103. BOOL CPolicyComponentData::IsLocalizedString(TCHAR * pBuf)
  4104. {
  4105. return (*pBuf == TEXT('!') && *(pBuf+1) == TEXT('!'));
  4106. }
  4107. #define MSGSIZE 1024
  4108. #define FMTSIZE 512
  4109. VOID CPolicyComponentData::DisplayKeywordError(UINT uErrorID,TCHAR * szFound,
  4110. KEYWORDINFO * pExpectedList)
  4111. {
  4112. TCHAR * pMsg,*pFmt,*pErrTxt,*pTmp;
  4113. pMsg = (TCHAR *) GlobalAlloc(GPTR,(MSGSIZE * sizeof(TCHAR)));
  4114. pFmt = (TCHAR *) GlobalAlloc(GPTR,(FMTSIZE * sizeof(TCHAR)));
  4115. pErrTxt = (TCHAR *) GlobalAlloc(GPTR,(FMTSIZE * sizeof(TCHAR)));
  4116. pTmp = (TCHAR *) GlobalAlloc(GPTR,(FMTSIZE * sizeof(TCHAR)));
  4117. if (!pMsg || !pFmt || !pErrTxt || !pTmp) {
  4118. if (pMsg) GlobalFree(pMsg);
  4119. if (pFmt) GlobalFree(pFmt);
  4120. if (pErrTxt) GlobalFree(pErrTxt);
  4121. if (pTmp) GlobalFree(pTmp);
  4122. MsgBox(NULL,IDS_ErrOUTOFMEMORY,MB_ICONEXCLAMATION,MB_OK);
  4123. return;
  4124. }
  4125. LoadSz(IDS_ParseFmt_MSG_FORMAT,pFmt,FMTSIZE);
  4126. (void) StringCchPrintf(pMsg, MSGSIZE, pFmt, m_pszParseFileName, m_nFileLine,uErrorID, LoadSz(uErrorID,
  4127. pErrTxt,FMTSIZE));
  4128. if (szFound) {
  4129. LoadSz(IDS_ParseFmt_FOUND,pFmt,FMTSIZE);
  4130. (void) StringCchPrintf(pTmp, FMTSIZE, pFmt, szFound);
  4131. (void) StringCchCat(pMsg, MSGSIZE, pTmp);
  4132. }
  4133. if (pExpectedList) {
  4134. UINT nIndex=0;
  4135. LoadSz(IDS_ParseFmt_EXPECTED,pFmt,FMTSIZE);
  4136. (void) StringCchCopy(pErrTxt, FMTSIZE, g_szNull);
  4137. while (pExpectedList[nIndex].pWord) {
  4138. (void) StringCchCat(pErrTxt, FMTSIZE, pExpectedList[nIndex].pWord);
  4139. if (pExpectedList[nIndex+1].pWord) {
  4140. (void) StringCchCat(pErrTxt, FMTSIZE, TEXT(", "));
  4141. }
  4142. nIndex++;
  4143. }
  4144. (void) StringCchPrintf(pTmp, FMTSIZE, pFmt, pErrTxt);
  4145. (void) StringCchCat(pMsg, MSGSIZE, pTmp);
  4146. }
  4147. (void) StringCchCat(pMsg, MSGSIZE, LoadSz(IDS_ParseFmt_FATAL, pTmp, FMTSIZE));
  4148. DebugMsg((DM_WARNING, TEXT("Keyword error: %s"), pMsg));
  4149. MsgBoxSz(NULL,pMsg,MB_ICONEXCLAMATION,MB_OK);
  4150. GlobalFree(pMsg);
  4151. GlobalFree(pFmt);
  4152. GlobalFree(pErrTxt);
  4153. GlobalFree(pTmp);
  4154. }
  4155. int CPolicyComponentData::MsgBox(HWND hWnd,UINT nResource,UINT uIcon,UINT uButtons)
  4156. {
  4157. TCHAR szMsgBuf[REGBUFLEN];
  4158. TCHAR szSmallBuf[SMALLBUF];
  4159. LoadSz(IDS_POLICY_NAME,szSmallBuf,ARRAYSIZE(szSmallBuf));
  4160. LoadSz(nResource,szMsgBuf,ARRAYSIZE(szMsgBuf));
  4161. MessageBeep(uIcon);
  4162. return (MessageBox(hWnd,szMsgBuf,szSmallBuf,uIcon | uButtons));
  4163. }
  4164. int CPolicyComponentData::MsgBoxSz(HWND hWnd,LPTSTR szText,UINT uIcon,UINT uButtons)
  4165. {
  4166. TCHAR szSmallBuf[SMALLBUF];
  4167. LoadSz(IDS_POLICY_NAME,szSmallBuf,ARRAYSIZE(szSmallBuf));
  4168. MessageBeep(uIcon);
  4169. return (MessageBox(hWnd,szText,szSmallBuf,uIcon | uButtons));
  4170. }
  4171. int CPolicyComponentData::MsgBoxParam(HWND hWnd,UINT nResource,TCHAR * szReplaceText,UINT uIcon,
  4172. UINT uButtons)
  4173. {
  4174. TCHAR szFormat[REGBUFLEN];
  4175. LPTSTR lpMsgBuf;
  4176. INT iResult;
  4177. HRESULT hr = S_OK;
  4178. DWORD dwMsgLen = lstrlen(szReplaceText) + 1 + REGBUFLEN;
  4179. lpMsgBuf = (LPTSTR) LocalAlloc (LPTR, (dwMsgLen) * sizeof(TCHAR));
  4180. if (!lpMsgBuf)
  4181. {
  4182. return 0;
  4183. }
  4184. LoadSz(nResource,szFormat,ARRAYSIZE(szFormat));
  4185. hr = StringCchPrintf(lpMsgBuf, dwMsgLen, szFormat, szReplaceText);
  4186. ASSERT(SUCCEEDED(hr));
  4187. iResult = MsgBoxSz(hWnd,lpMsgBuf,uIcon,uButtons);
  4188. LocalFree (lpMsgBuf);
  4189. return iResult;
  4190. }
  4191. LPTSTR CPolicyComponentData::LoadSz(UINT idString,LPTSTR lpszBuf,UINT cbBuf)
  4192. {
  4193. // Clear the buffer and load the string
  4194. if ( lpszBuf )
  4195. {
  4196. *lpszBuf = TEXT('\0');
  4197. LoadString( g_hInstance, idString, lpszBuf, cbBuf );
  4198. }
  4199. return lpszBuf;
  4200. }
  4201. BOOL fFilterDirectives = TRUE;
  4202. UINT nGlobalNestedLevel = 0;
  4203. // reads up through the matching directive #endif in current scope
  4204. //and sets file pointer immediately past the directive
  4205. UINT CPolicyComponentData::FindMatchingDirective(BOOL *pfMore,BOOL fElseOK)
  4206. {
  4207. TCHAR szWordBuf[WORDBUFSIZE];
  4208. UINT uErr=ERROR_SUCCESS,nNestedLevel=1;
  4209. BOOL fContinue = TRUE;
  4210. // set the flag to stop catching '#' directives in low level word-fetching
  4211. // routine
  4212. fFilterDirectives = FALSE;
  4213. // keep reading words. Keep track of how many layers of #ifdefs deep we
  4214. // are. Every time we encounter an #ifdef or #ifndef, increment the level
  4215. // count (nNestedLevel) by one. For every #endif decrement the level count.
  4216. // When the level count hits zero, we've found the matching #endif.
  4217. while (nNestedLevel > 0) {
  4218. if (!GetNextSectionWord(szWordBuf,ARRAYSIZE(szWordBuf),NULL,NULL,
  4219. pfMore,&uErr))
  4220. break;
  4221. if (!lstrcmpi(szWordBuf,szIFDEF) || !lstrcmpi(szWordBuf,szIFNDEF) ||
  4222. !lstrcmpi(szWordBuf,szIF))
  4223. nNestedLevel ++;
  4224. else if (!lstrcmpi(szWordBuf,szENDIF)) {
  4225. nNestedLevel --;
  4226. }
  4227. else if (!lstrcmpi(szWordBuf,szELSE) && (nNestedLevel == 1)) {
  4228. if (fElseOK) {
  4229. // ignore "#else" unless it's on the same level as the #ifdef
  4230. // we're finding a match for (nNestedLevel == 1), in which
  4231. // case treat it as the matching directive
  4232. nNestedLevel --;
  4233. // increment global nesting so we expect an #endif to come along
  4234. // later to match this #else
  4235. nGlobalNestedLevel++;
  4236. } else {
  4237. // found a #else where we already had a #else in this level
  4238. DisplayKeywordError(IDS_ParseErr_UNMATCHED_DIRECTIVE,
  4239. szWordBuf,NULL);
  4240. return ERROR_ALREADY_DISPLAYED;
  4241. }
  4242. }
  4243. }
  4244. fFilterDirectives = TRUE;
  4245. return uErr;
  4246. }
  4247. // if the word in the word buffer is #ifdef, #if, #ifndef, #else or #endif,
  4248. // this function reads ahead an appropriate amount (
  4249. UINT CPolicyComponentData::ProcessIfdefs(TCHAR * pBuf,UINT cbBuf,BOOL * pfMore)
  4250. {
  4251. UINT uRet;
  4252. if (!fFilterDirectives)
  4253. return ERROR_SUCCESS;
  4254. if (!lstrcmpi(pBuf,szIFDEF)) {
  4255. // we've found an '#ifdef <something or other>, where ISV policy editors
  4256. // can understand particular keywords they make up. We don't have any
  4257. // #ifdef keywords of our own so always skip this
  4258. uRet = FindMatchingDirective(pfMore,TRUE);
  4259. if (uRet != ERROR_SUCCESS)
  4260. return uRet;
  4261. if (!GetNextWord(pBuf,cbBuf,pfMore,&uRet))
  4262. return uRet;
  4263. return ERROR_SUCCESS;
  4264. } else if (!lstrcmpi(pBuf,szIFNDEF)) {
  4265. // this is an #ifndef, and since nothing is ever ifdef'd for our policy
  4266. // editor, this always evaluates to TRUE
  4267. // keep reading this section but increment the nested level count,
  4268. // when we find the matching #endif or #else we'll be able to respond
  4269. // correctly
  4270. nGlobalNestedLevel ++;
  4271. // get next word (e.g. "abc" for #ifndef abc) and throw it away
  4272. if (!GetNextWord(pBuf,cbBuf,pfMore,&uRet))
  4273. return uRet;
  4274. // get next word and return it for real
  4275. if (!GetNextWord(pBuf,cbBuf,pfMore,&uRet))
  4276. return uRet;
  4277. return ERROR_SUCCESS;
  4278. } else if (!lstrcmpi(pBuf,szENDIF)) {
  4279. // if we ever encounter an #endif here, we must have processed
  4280. // the preceeding section. Just step over the #endif and go on
  4281. if (!nGlobalNestedLevel) {
  4282. // found an endif without a preceeding #if<xx>
  4283. DisplayKeywordError(IDS_ParseErr_UNMATCHED_DIRECTIVE,
  4284. pBuf,NULL);
  4285. return ERROR_ALREADY_DISPLAYED;
  4286. }
  4287. nGlobalNestedLevel--;
  4288. if (!GetNextWord(pBuf,cbBuf,pfMore,&uRet))
  4289. return uRet;
  4290. return ERROR_SUCCESS;
  4291. } else if (!lstrcmpi(pBuf,szIF)) {
  4292. // syntax is "#if VERSION (comparision) (version #)"
  4293. // e.g. "#if VERSION >= 2"
  4294. TCHAR szWordBuf[WORDBUFSIZE];
  4295. UINT nIndex,nVersion,nOperator;
  4296. BOOL fDirectiveTrue = FALSE;
  4297. // get the next word (must be "VERSION")
  4298. if (!GetNextSectionWord(szWordBuf,ARRAYSIZE(szWordBuf),
  4299. pVersionCmpList,&nIndex,pfMore,&uRet))
  4300. return uRet;
  4301. // get the comparison operator (>, <, ==, >=, <=)
  4302. if (!GetNextSectionWord(szWordBuf,ARRAYSIZE(szWordBuf),
  4303. pOperatorCmpList,&nOperator,pfMore,&uRet))
  4304. return uRet;
  4305. // get the version number
  4306. uRet=GetNextSectionNumericWord(&nVersion);
  4307. if (uRet != ERROR_SUCCESS)
  4308. return uRet;
  4309. // now evaluate the directive
  4310. switch (nOperator) {
  4311. case KYWD_ID_GT:
  4312. fDirectiveTrue = (CURRENT_ADM_VERSION > nVersion);
  4313. break;
  4314. case KYWD_ID_GTE:
  4315. fDirectiveTrue = (CURRENT_ADM_VERSION >= nVersion);
  4316. break;
  4317. case KYWD_ID_LT:
  4318. fDirectiveTrue = (CURRENT_ADM_VERSION < nVersion);
  4319. break;
  4320. case KYWD_ID_LTE:
  4321. fDirectiveTrue = (CURRENT_ADM_VERSION <= nVersion);
  4322. break;
  4323. case KYWD_ID_EQ:
  4324. fDirectiveTrue = (CURRENT_ADM_VERSION == nVersion);
  4325. break;
  4326. case KYWD_ID_NE:
  4327. fDirectiveTrue = (CURRENT_ADM_VERSION != nVersion);
  4328. break;
  4329. }
  4330. if (fDirectiveTrue) {
  4331. // keep reading this section but increment the nested level count,
  4332. // when we find the matching #endif or #else we'll be able to respond
  4333. // correctly
  4334. nGlobalNestedLevel ++;
  4335. } else {
  4336. // skip over this section
  4337. uRet = FindMatchingDirective(pfMore,TRUE);
  4338. if (uRet != ERROR_SUCCESS)
  4339. return uRet;
  4340. }
  4341. // get next word and return it for real
  4342. if (!GetNextWord(pBuf,cbBuf,pfMore,&uRet))
  4343. return uRet;
  4344. return ERROR_SUCCESS;
  4345. } else if (!lstrcmpi(pBuf,szELSE)) {
  4346. // found an #else, which means we took the upper branch, skip over
  4347. // the lower branch
  4348. if (!nGlobalNestedLevel) {
  4349. // found an #else without a preceeding #if<xx>
  4350. DisplayKeywordError(IDS_ParseErr_UNMATCHED_DIRECTIVE,
  4351. pBuf,NULL);
  4352. return ERROR_ALREADY_DISPLAYED;
  4353. }
  4354. nGlobalNestedLevel--;
  4355. uRet = FindMatchingDirective(pfMore,FALSE);
  4356. if (uRet != ERROR_SUCCESS)
  4357. return uRet;
  4358. if (!GetNextWord(pBuf,cbBuf,pfMore,&uRet))
  4359. return uRet;
  4360. return ERROR_SUCCESS;
  4361. }
  4362. return ERROR_SUCCESS;
  4363. }
  4364. /*******************************************************************
  4365. NAME: FreeTable
  4366. SYNOPSIS: Frees the specified table and all sub-tables of that
  4367. table.
  4368. NOTES: Walks through the table entries and calls itself to
  4369. recursively free sub-tables.
  4370. EXIT: Returns TRUE if successful, FALSE if a memory error
  4371. occurs.
  4372. ********************************************************************/
  4373. BOOL CPolicyComponentData::FreeTable(TABLEENTRY * pTableEntry)
  4374. {
  4375. TABLEENTRY * pNext = pTableEntry->pNext;
  4376. // free all children
  4377. if (pTableEntry->pChild)
  4378. FreeTable(pTableEntry->pChild);
  4379. GlobalFree(pTableEntry);
  4380. if (pNext) FreeTable(pNext);
  4381. return TRUE;
  4382. }
  4383. LPTSTR CPolicyComponentData::GetStringSection (LPCTSTR lpSection, LPCTSTR lpFileName)
  4384. {
  4385. DWORD dwSize, dwRead;
  4386. LPTSTR lpStrings;
  4387. //
  4388. // Read in the default strings section
  4389. //
  4390. dwSize = STRINGS_BUF_SIZE;
  4391. lpStrings = (TCHAR *) GlobalAlloc (GPTR, dwSize * sizeof(TCHAR));
  4392. if (!lpStrings)
  4393. {
  4394. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::GetStringSection: Failed to alloc memory for default strings with %d."),
  4395. GetLastError()));
  4396. return NULL;
  4397. }
  4398. do {
  4399. dwRead = GetPrivateProfileSection (lpSection,
  4400. lpStrings,
  4401. dwSize, lpFileName);
  4402. if (dwRead != (dwSize - 2))
  4403. {
  4404. break;
  4405. }
  4406. GlobalFree (lpStrings);
  4407. dwSize *= 2;
  4408. lpStrings = (TCHAR *) GlobalAlloc (GPTR, dwSize * sizeof(TCHAR));
  4409. if (!lpStrings)
  4410. {
  4411. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::GetStringSection: Failed to alloc memory for Default strings with %d."),
  4412. GetLastError()));
  4413. return FALSE;
  4414. }
  4415. } while (TRUE);
  4416. if (dwRead == 0)
  4417. {
  4418. GlobalFree (lpStrings);
  4419. lpStrings = NULL;
  4420. }
  4421. return lpStrings;
  4422. }
  4423. INT CPolicyComponentData::TemplatesSortCallback (LPARAM lParam1, LPARAM lParam2,
  4424. LPARAM lColumn)
  4425. {
  4426. LPTEMPLATEENTRY lpEntry1, lpEntry2;
  4427. INT iResult;
  4428. lpEntry1 = (LPTEMPLATEENTRY) lParam1;
  4429. lpEntry2 = (LPTEMPLATEENTRY) lParam2;
  4430. if (lColumn == 0)
  4431. {
  4432. iResult = lstrcmpi (lpEntry1->lpFileName, lpEntry2->lpFileName);
  4433. }
  4434. else if (lColumn == 1)
  4435. {
  4436. if (lpEntry1->dwSize < lpEntry2->dwSize)
  4437. {
  4438. iResult = -1;
  4439. }
  4440. else if (lpEntry1->dwSize > lpEntry2->dwSize)
  4441. {
  4442. iResult = 1;
  4443. }
  4444. else
  4445. {
  4446. iResult = 0;
  4447. }
  4448. }
  4449. else
  4450. {
  4451. iResult = CompareFileTime (&lpEntry1->ftTime, &lpEntry2->ftTime);
  4452. }
  4453. return iResult;
  4454. }
  4455. BOOL CPolicyComponentData::FillADMFiles (HWND hDlg)
  4456. {
  4457. TCHAR szPath[MAX_PATH];
  4458. TCHAR szDate[20];
  4459. TCHAR szTime[20];
  4460. TCHAR szBuffer[45];
  4461. HWND hLV;
  4462. INT iItem;
  4463. LVITEM item;
  4464. FILETIME filetime;
  4465. SYSTEMTIME systime;
  4466. WIN32_FIND_DATA fd;
  4467. LPTEMPLATEENTRY lpEntry;
  4468. HANDLE hFile;
  4469. LPTSTR lpEnd, lpTemp;
  4470. HRESULT hr = S_OK;
  4471. XLastError xe;
  4472. //
  4473. // Ask for the root of the GPT so we can access the
  4474. // adm files.
  4475. //
  4476. if (m_pGPTInformation->GetFileSysPath(GPO_SECTION_ROOT, szPath,
  4477. MAX_PATH) != S_OK)
  4478. {
  4479. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::FillADMFiles: Failed to get gpt path.")));
  4480. return FALSE;
  4481. }
  4482. //
  4483. // Create the directory
  4484. //
  4485. lpEnd = CheckSlash (szPath);
  4486. hr = StringCchCopy (lpEnd, ARRAYSIZE(szPath) - (lpEnd - szPath), g_szADM);
  4487. if (FAILED(hr))
  4488. {
  4489. xe = HRESULT_CODE(hr);
  4490. return FALSE;
  4491. }
  4492. if (!CreateNestedDirectory(szPath, NULL))
  4493. {
  4494. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::FillADMFiles: Failed to create adm directory.")));
  4495. return FALSE;
  4496. }
  4497. //
  4498. // Prepare the listview
  4499. //
  4500. hLV = GetDlgItem (hDlg, IDC_TEMPLATELIST);
  4501. SendMessage (hLV, WM_SETREDRAW, FALSE, 0);
  4502. ListView_DeleteAllItems(hLV);
  4503. //
  4504. // Enumerate the files
  4505. //
  4506. hr = StringCchCat (szPath, ARRAYSIZE(szPath), TEXT("\\*.adm"));
  4507. if (FAILED(hr))
  4508. {
  4509. xe = HRESULT_CODE(hr);
  4510. return FALSE;
  4511. }
  4512. hFile = FindFirstFile(szPath, &fd);
  4513. if (hFile != INVALID_HANDLE_VALUE)
  4514. {
  4515. do
  4516. {
  4517. if (!(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
  4518. {
  4519. lpEntry = (LPTEMPLATEENTRY) LocalAlloc (LPTR,
  4520. sizeof(TEMPLATEENTRY) + ((lstrlen(fd.cFileName) + 1) * sizeof(TCHAR)));
  4521. if (lpEntry)
  4522. {
  4523. lpEntry->lpFileName = (LPTSTR)((LPBYTE)lpEntry + sizeof(TEMPLATEENTRY));
  4524. lpEntry->dwSize = fd.nFileSizeLow / 1024;
  4525. if (lpEntry->dwSize == 0)
  4526. {
  4527. lpEntry->dwSize = 1;
  4528. }
  4529. lpEntry->ftTime.dwLowDateTime = fd.ftLastWriteTime.dwLowDateTime;
  4530. lpEntry->ftTime.dwHighDateTime = fd.ftLastWriteTime.dwHighDateTime;
  4531. hr = StringCchCopy (lpEntry->lpFileName, lstrlen(fd.cFileName) + 1, fd.cFileName);
  4532. ASSERT(SUCCEEDED(hr));
  4533. //
  4534. // Add the filename
  4535. //
  4536. lpTemp = fd.cFileName + lstrlen (fd.cFileName) - 4;
  4537. if (*lpTemp == TEXT('.'))
  4538. {
  4539. *lpTemp = TEXT('\0');
  4540. }
  4541. item.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE | LVIF_PARAM;
  4542. item.iItem = 0;
  4543. item.iSubItem = 0;
  4544. item.state = 0;
  4545. item.stateMask = LVIS_SELECTED | LVIS_FOCUSED;
  4546. item.pszText = fd.cFileName;
  4547. item.iImage = 0;
  4548. item.lParam = (LPARAM) lpEntry;
  4549. iItem = (INT)SendMessage (hLV, LVM_INSERTITEM, 0, (LPARAM) &item);
  4550. if (iItem == -1)
  4551. {
  4552. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::FillADMFiles: Failed to insert item.")));
  4553. return FALSE;
  4554. }
  4555. //
  4556. // Add the size
  4557. //
  4558. hr = StringCchPrintf (szBuffer, ARRAYSIZE(szBuffer), TEXT("%dKB"), lpEntry->dwSize);
  4559. ASSERT(SUCCEEDED(hr));
  4560. item.mask = LVIF_TEXT;
  4561. item.iItem = iItem;
  4562. item.iSubItem = 1;
  4563. item.pszText = szBuffer;
  4564. SendMessage (hLV, LVM_SETITEMTEXT, iItem, (LPARAM) &item);
  4565. //
  4566. // And the last modified date
  4567. //
  4568. FileTimeToLocalFileTime (&fd.ftLastWriteTime, &filetime);
  4569. FileTimeToSystemTime (&filetime, &systime);
  4570. GetDateFormat (LOCALE_USER_DEFAULT, DATE_SHORTDATE,
  4571. &systime, NULL, szDate, 20);
  4572. GetTimeFormat (LOCALE_USER_DEFAULT, TIME_NOSECONDS,
  4573. &systime, NULL, szTime, 20);
  4574. hr = StringCchPrintf (szBuffer, ARRAYSIZE(szBuffer), TEXT("%s %s"), szDate, szTime);
  4575. ASSERT(SUCCEEDED(hr));
  4576. item.mask = LVIF_TEXT;
  4577. item.iItem = iItem;
  4578. item.iSubItem = 2;
  4579. item.pszText = szBuffer;
  4580. SendMessage (hLV, LVM_SETITEMTEXT, iItem, (LPARAM) &item);
  4581. }
  4582. else
  4583. {
  4584. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::FillADMFiles: Failed to allocate memory for an entry %d."),
  4585. GetLastError()));
  4586. }
  4587. }
  4588. } while (FindNextFile(hFile, &fd));
  4589. FindClose(hFile);
  4590. }
  4591. if (SendMessage(hLV, LVM_GETITEMCOUNT, 0, 0) > 0)
  4592. {
  4593. //
  4594. // Sort the listview
  4595. //
  4596. ListView_SortItems (hLV, TemplatesSortCallback, m_bTemplatesColumn);
  4597. //
  4598. // Select the first item
  4599. //
  4600. item.mask = LVIF_STATE;
  4601. item.iItem = 0;
  4602. item.iSubItem = 0;
  4603. item.state = LVIS_SELECTED | LVIS_FOCUSED;
  4604. item.stateMask = LVIS_SELECTED | LVIS_FOCUSED;
  4605. SendMessage (hLV, LVM_SETITEMSTATE, 0, (LPARAM) &item);
  4606. EnableWindow (GetDlgItem (hDlg, IDC_REMOVETEMPLATES), TRUE);
  4607. }
  4608. else
  4609. {
  4610. EnableWindow (GetDlgItem (hDlg, IDC_REMOVETEMPLATES), FALSE);
  4611. SetFocus (GetDlgItem (hDlg, IDC_ADDTEMPLATES));
  4612. }
  4613. SendMessage (hLV, WM_SETREDRAW, TRUE, 0);
  4614. return TRUE;
  4615. }
  4616. BOOL CPolicyComponentData::InitializeTemplatesDlg (HWND hDlg)
  4617. {
  4618. LVCOLUMN lvc;
  4619. LVITEM item;
  4620. TCHAR szTitle[50];
  4621. INT iNameWidth;
  4622. HIMAGELIST hLarge, hSmall;
  4623. HICON hIcon;
  4624. HWND hLV;
  4625. RECT rc;
  4626. hLV = GetDlgItem (hDlg, IDC_TEMPLATELIST);
  4627. GetClientRect (hLV, &rc);
  4628. //
  4629. // Create the imagelists
  4630. //
  4631. hLarge = ImageList_Create (32, 32, ILC_MASK, 1, 1);
  4632. if (!hLarge)
  4633. {
  4634. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::InitializeTemplatesDlg: Failed to create large imagelist.")));
  4635. return FALSE;
  4636. }
  4637. hSmall = ImageList_Create (16, 16, ILC_MASK, 1, 1);
  4638. if (!hSmall)
  4639. {
  4640. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::InitializeTemplatesDlg: Failed to create small imagelist.")));
  4641. ImageList_Destroy (hLarge);
  4642. return FALSE;
  4643. }
  4644. //
  4645. // Add the icon
  4646. //
  4647. hIcon = (HICON) LoadImage (g_hInstance, MAKEINTRESOURCE(IDI_DOCUMENT),
  4648. IMAGE_ICON, 32, 32, LR_DEFAULTCOLOR);
  4649. if ( hIcon )
  4650. {
  4651. ImageList_AddIcon (hLarge, hIcon);
  4652. DestroyIcon (hIcon);
  4653. }
  4654. hIcon = (HICON) LoadImage (g_hInstance, MAKEINTRESOURCE(IDI_DOCUMENT),
  4655. IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
  4656. if ( hIcon )
  4657. {
  4658. ImageList_AddIcon (hSmall, hIcon);
  4659. DestroyIcon (hIcon);
  4660. }
  4661. //
  4662. // Associate the imagelist with the listview.
  4663. // The listview will free this when the
  4664. // control is destroyed.
  4665. //
  4666. SendMessage (hLV, LVM_SETIMAGELIST, LVSIL_NORMAL, (LPARAM) hLarge);
  4667. SendMessage (hLV, LVM_SETIMAGELIST, LVSIL_SMALL, (LPARAM) hSmall);
  4668. //
  4669. // Set extended LV style for whole line selection
  4670. //
  4671. SendMessage(hLV, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_FULLROWSELECT);
  4672. //
  4673. // Insert the columns
  4674. //
  4675. LoadString (g_hInstance, IDS_NAME, szTitle, 50);
  4676. lvc.mask = LVCF_FMT | LVCF_SUBITEM | LVCF_TEXT | LVCF_WIDTH;
  4677. lvc.fmt = LVCFMT_LEFT;
  4678. iNameWidth = (int)(rc.right * .60);
  4679. lvc.cx = iNameWidth;
  4680. lvc.pszText = szTitle;
  4681. lvc.cchTextMax = 50;
  4682. lvc.iSubItem = 0;
  4683. SendMessage (hLV, LVM_INSERTCOLUMN, 0, (LPARAM) &lvc);
  4684. LoadString (g_hInstance, IDS_SIZE, szTitle, 50);
  4685. lvc.mask = LVCF_FMT | LVCF_SUBITEM | LVCF_TEXT | LVCF_WIDTH;
  4686. lvc.fmt = LVCFMT_RIGHT;
  4687. iNameWidth += (int)(rc.right * .15);
  4688. lvc.cx = (int)(rc.right * .15);
  4689. lvc.pszText = szTitle;
  4690. lvc.cchTextMax = 50;
  4691. lvc.iSubItem = 0;
  4692. SendMessage (hLV, LVM_INSERTCOLUMN, 1, (LPARAM) &lvc);
  4693. LoadString (g_hInstance, IDS_MODIFIED, szTitle, 50);
  4694. lvc.mask = LVCF_FMT | LVCF_SUBITEM | LVCF_TEXT | LVCF_WIDTH;
  4695. lvc.fmt = LVCFMT_LEFT;
  4696. lvc.cx = rc.right - iNameWidth;
  4697. lvc.pszText = szTitle;
  4698. lvc.cchTextMax = 50;
  4699. lvc.iSubItem = 1;
  4700. SendMessage (hLV, LVM_INSERTCOLUMN, 2, (LPARAM) &lvc);
  4701. //
  4702. // Fill the list view with the adm files
  4703. //
  4704. FillADMFiles (hDlg);
  4705. return TRUE;
  4706. }
  4707. BOOL CPolicyComponentData::AddTemplates(HWND hDlg)
  4708. {
  4709. OPENFILENAME ofn;
  4710. LVITEM item;
  4711. INT iCount, iResult;
  4712. BOOL bResult = FALSE;
  4713. LPTSTR lpFileName, lpTemp, lpEnd, lpSrcList = NULL;
  4714. DWORD dwListLen, dwTemp, dwNextString;
  4715. TCHAR szFilter[100];
  4716. TCHAR szTitle[100];
  4717. TCHAR szFile[2*MAX_PATH];
  4718. TCHAR szInf[MAX_PATH];
  4719. TCHAR szDest[MAX_PATH];
  4720. TCHAR szSrc[2*MAX_PATH];
  4721. SHFILEOPSTRUCT fileop;
  4722. HRESULT hr = S_OK;
  4723. XLastError xe;
  4724. //
  4725. // Prompt for new files
  4726. //
  4727. LoadString (g_hInstance, IDS_POLICYFILTER, szFilter, ARRAYSIZE(szFilter));
  4728. LoadString (g_hInstance, IDS_POLICYTITLE, szTitle, ARRAYSIZE(szTitle));
  4729. ExpandEnvironmentStrings (TEXT("%SystemRoot%\\Inf"), szInf, MAX_PATH);
  4730. lpTemp = szFilter;
  4731. while (*lpTemp)
  4732. {
  4733. if (*lpTemp == TEXT('#'))
  4734. *lpTemp = TEXT('\0');
  4735. lpTemp++;
  4736. }
  4737. ZeroMemory (&ofn, sizeof(ofn));
  4738. szFile[0] = TEXT('\0');
  4739. ofn.lStructSize = sizeof(ofn);
  4740. ofn.hwndOwner = hDlg;
  4741. ofn.hInstance = g_hInstance;
  4742. ofn.lpstrFilter = szFilter;
  4743. ofn.nFilterIndex = 1;
  4744. ofn.lpstrFile = szFile;
  4745. ofn.nMaxFile = 2*MAX_PATH;
  4746. ofn.lpstrInitialDir = szInf;
  4747. ofn.lpstrTitle = szTitle;
  4748. ofn.Flags = OFN_ALLOWMULTISELECT | OFN_NOCHANGEDIR | OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_EXPLORER;
  4749. if (!GetOpenFileName (&ofn))
  4750. {
  4751. return FALSE;
  4752. }
  4753. //
  4754. // Setup the destination
  4755. //
  4756. if (m_pGPTInformation->GetFileSysPath(GPO_SECTION_ROOT, szDest,
  4757. MAX_PATH) != S_OK)
  4758. {
  4759. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::AddTemplates: Failed to get gpt path.")));
  4760. return FALSE;
  4761. }
  4762. lpEnd = CheckSlash (szDest);
  4763. hr = StringCchCopy (lpEnd, ARRAYSIZE(szDest) - (lpEnd - szDest), g_szADM);
  4764. if (FAILED(hr))
  4765. {
  4766. xe = HRESULT_CODE(hr);
  4767. return FALSE;
  4768. }
  4769. //
  4770. // Setup up the source
  4771. //
  4772. *(szFile + ofn.nFileOffset - 1) = TEXT('\0');
  4773. hr = StringCchCopy (szSrc, ARRAYSIZE(szSrc), szFile);
  4774. if (FAILED(hr))
  4775. {
  4776. xe = HRESULT_CODE(hr);
  4777. return FALSE;
  4778. }
  4779. lpEnd = CheckSlash (szSrc);
  4780. lpFileName = szFile + lstrlen (szFile) + 1;
  4781. //
  4782. // Loop through the files copying and adding them to the list.
  4783. //
  4784. while (*lpFileName)
  4785. {
  4786. lpTemp = lpFileName + lstrlen (lpFileName) - 4;
  4787. if (CompareString(LOCALE_INVARIANT, NORM_IGNORECASE, lpTemp, -1, TEXT(".adm"), -1) == CSTR_EQUAL)
  4788. {
  4789. hr = StringCchCopy (lpEnd, ARRAYSIZE(szSrc) - (lpEnd - szSrc), lpFileName);
  4790. ASSERT(SUCCEEDED(hr));
  4791. if (lpSrcList)
  4792. {
  4793. dwTemp = dwListLen + ((lstrlen (szSrc) + 1) * sizeof(TCHAR));
  4794. lpTemp = (LPTSTR) LocalReAlloc (lpSrcList, dwTemp, LMEM_MOVEABLE | LMEM_ZEROINIT);
  4795. if (lpTemp)
  4796. {
  4797. lpSrcList = lpTemp;
  4798. dwListLen = dwTemp;
  4799. hr = StringCchCopy ((lpSrcList + dwNextString), lstrlen(szSrc) + 1, szSrc);
  4800. ASSERT(SUCCEEDED(hr));
  4801. dwNextString += lstrlen (szSrc) + 1;
  4802. }
  4803. else
  4804. {
  4805. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::AddTemplates: Failed to realloc memory for Src list. %d"),
  4806. GetLastError()));
  4807. }
  4808. }
  4809. else
  4810. {
  4811. dwListLen = (lstrlen (szSrc) + 2) * sizeof(TCHAR);
  4812. lpSrcList = (LPTSTR) LocalAlloc (LPTR, dwListLen);
  4813. if (lpSrcList)
  4814. {
  4815. hr = StringCchCopy (lpSrcList, dwListLen/sizeof(TCHAR), szSrc);
  4816. ASSERT(SUCCEEDED(hr));
  4817. dwNextString = lstrlen (lpSrcList) + 1;
  4818. }
  4819. else
  4820. {
  4821. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::AddTemplates: Failed to alloc memory for src list. %d"),
  4822. GetLastError()));
  4823. }
  4824. }
  4825. }
  4826. else
  4827. {
  4828. MsgBoxParam(hDlg, IDS_INVALIDADMFILE, lpFileName, MB_ICONERROR, MB_OK);
  4829. }
  4830. lpFileName = lpFileName + lstrlen (lpFileName) + 1;
  4831. }
  4832. if (lpSrcList)
  4833. {
  4834. fileop.hwnd = hDlg;
  4835. fileop.wFunc = FO_COPY;
  4836. fileop.pFrom = lpSrcList;
  4837. fileop.pTo = szDest;
  4838. fileop.fFlags = FOF_NOCONFIRMMKDIR;
  4839. iResult = SHFileOperation(&fileop);
  4840. if (!iResult)
  4841. {
  4842. bResult = TRUE;
  4843. }
  4844. else
  4845. {
  4846. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::AddTemplates: Failed to copy <%s> to <%s> with %d."),
  4847. szSrc, szDest, iResult));
  4848. }
  4849. LocalFree (lpSrcList);
  4850. if (bResult)
  4851. {
  4852. FillADMFiles (hDlg);
  4853. }
  4854. }
  4855. return bResult;
  4856. }
  4857. BOOL CPolicyComponentData::RemoveTemplates(HWND hDlg)
  4858. {
  4859. HWND hLV;
  4860. LVITEM item;
  4861. BOOL bResult = FALSE;
  4862. INT iResult, iIndex = -1;
  4863. LPTEMPLATEENTRY lpEntry;
  4864. LPTSTR lpEnd, lpTemp, lpDeleteList = NULL;
  4865. TCHAR szPath[MAX_PATH];
  4866. DWORD dwSize, dwListLen, dwTemp, dwNextString;
  4867. SHFILEOPSTRUCT fileop;
  4868. HRESULT hr = S_OK;
  4869. XLastError xe;
  4870. hLV = GetDlgItem (hDlg, IDC_TEMPLATELIST);
  4871. //
  4872. // Get the path to the adm directory
  4873. //
  4874. if (m_pGPTInformation->GetFileSysPath(GPO_SECTION_ROOT, szPath,
  4875. MAX_PATH) != S_OK)
  4876. {
  4877. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::AddTemplates: Failed to get gpt path.")));
  4878. return FALSE;
  4879. }
  4880. lpEnd = CheckSlash (szPath);
  4881. hr = StringCchCopy (lpEnd, MAX_PATH - (lpEnd - szPath), g_szADM);
  4882. if (FAILED(hr))
  4883. {
  4884. xe = HRESULT_CODE(hr);
  4885. return bResult;
  4886. }
  4887. lpEnd = CheckSlash (szPath);
  4888. dwSize = MAX_PATH - (DWORD)(lpEnd - szPath);
  4889. //
  4890. // Build a list of selected items
  4891. //
  4892. while ((iIndex = ListView_GetNextItem (hLV, iIndex,
  4893. LVNI_ALL | LVNI_SELECTED)) != -1)
  4894. {
  4895. item.mask = LVIF_PARAM;
  4896. item.iItem = iIndex;
  4897. item.iSubItem = 0;
  4898. if (!ListView_GetItem (hLV, &item))
  4899. {
  4900. continue;
  4901. }
  4902. lpEntry = (LPTEMPLATEENTRY) item.lParam;
  4903. lstrcpyn (lpEnd, lpEntry->lpFileName, dwSize);
  4904. if (lpDeleteList)
  4905. {
  4906. dwTemp = dwListLen + ((lstrlen (szPath) + 1) * sizeof(TCHAR));
  4907. lpTemp = (LPTSTR) LocalReAlloc (lpDeleteList, dwTemp, LMEM_MOVEABLE | LMEM_ZEROINIT);
  4908. if (lpTemp)
  4909. {
  4910. lpDeleteList = lpTemp;
  4911. dwListLen = dwTemp;
  4912. hr = StringCchCopy ((lpDeleteList + dwNextString), lstrlen(szPath) + 1, szPath);
  4913. ASSERT(SUCCEEDED(hr));
  4914. dwNextString += lstrlen (szPath) + 1;
  4915. }
  4916. else
  4917. {
  4918. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::RemoveTemplates: Failed to realloc memory for delete list. %d"),
  4919. GetLastError()));
  4920. }
  4921. }
  4922. else
  4923. {
  4924. dwListLen = (lstrlen (szPath) + 2) * sizeof(TCHAR);
  4925. lpDeleteList = (LPTSTR) LocalAlloc (LPTR, dwListLen);
  4926. if (lpDeleteList)
  4927. {
  4928. hr = StringCchCopy (lpDeleteList, dwListLen/sizeof(WCHAR), szPath);
  4929. ASSERT(SUCCEEDED(hr));
  4930. dwNextString = lstrlen (lpDeleteList) + 1;
  4931. }
  4932. else
  4933. {
  4934. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::RemoveTemplates: Failed to alloc memory for delete list. %d"),
  4935. GetLastError()));
  4936. }
  4937. }
  4938. }
  4939. if (lpDeleteList)
  4940. {
  4941. fileop.hwnd = hDlg;
  4942. fileop.wFunc = FO_DELETE;
  4943. fileop.pFrom = lpDeleteList;
  4944. fileop.pTo = NULL;
  4945. fileop.fFlags = FOF_NOCONFIRMATION | FOF_SILENT;
  4946. iResult = SHFileOperation(&fileop);
  4947. if (!iResult)
  4948. {
  4949. bResult = TRUE;
  4950. }
  4951. else
  4952. {
  4953. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::RemoveTemplates: Failed to delete file <%s> with %d."),
  4954. szPath, iResult));
  4955. }
  4956. LocalFree (lpDeleteList);
  4957. if (bResult)
  4958. {
  4959. FillADMFiles (hDlg);
  4960. }
  4961. }
  4962. return bResult;
  4963. }
  4964. INT_PTR CALLBACK CPolicyComponentData::TemplatesDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  4965. {
  4966. CPolicyComponentData * pCD;
  4967. static BOOL bTemplatesDirty;
  4968. switch (message)
  4969. {
  4970. case WM_INITDIALOG:
  4971. pCD = (CPolicyComponentData*) lParam;
  4972. SetWindowLongPtr (hDlg, DWLP_USER, (LONG_PTR) pCD);
  4973. bTemplatesDirty = FALSE;
  4974. if (!pCD->InitializeTemplatesDlg(hDlg))
  4975. {
  4976. EndDialog (hDlg, FALSE);
  4977. }
  4978. PostMessage (hDlg, WM_REFRESHDISPLAY, 0, 0);
  4979. break;
  4980. case WM_COMMAND:
  4981. switch (LOWORD(wParam))
  4982. {
  4983. case IDOK:
  4984. case IDCANCEL:
  4985. case IDCLOSE:
  4986. EndDialog (hDlg, bTemplatesDirty);
  4987. break;
  4988. case IDC_ADDTEMPLATES:
  4989. pCD = (CPolicyComponentData*) GetWindowLongPtr (hDlg, DWLP_USER);
  4990. if (pCD && pCD->AddTemplates(hDlg))
  4991. {
  4992. bTemplatesDirty = TRUE;
  4993. }
  4994. break;
  4995. case IDC_REMOVETEMPLATES:
  4996. pCD = (CPolicyComponentData*) GetWindowLongPtr (hDlg, DWLP_USER);
  4997. if (pCD && pCD->RemoveTemplates(hDlg))
  4998. {
  4999. bTemplatesDirty = TRUE;
  5000. }
  5001. break;
  5002. }
  5003. break;
  5004. case WM_NOTIFY:
  5005. if (((NMHDR FAR*)lParam)->code == LVN_DELETEITEM)
  5006. {
  5007. LVITEM item;
  5008. LPTEMPLATEENTRY lpEntry;
  5009. item.mask = LVIF_PARAM;
  5010. item.iItem = ((NMLISTVIEW FAR*)lParam)->iItem;
  5011. item.iSubItem = 0;
  5012. if (ListView_GetItem (GetDlgItem (hDlg, IDC_TEMPLATELIST), &item))
  5013. {
  5014. lpEntry = (LPTEMPLATEENTRY) item.lParam;
  5015. LocalFree (lpEntry);
  5016. }
  5017. }
  5018. else if (((NMHDR FAR*)lParam)->code == LVN_COLUMNCLICK)
  5019. {
  5020. pCD = (CPolicyComponentData*) GetWindowLongPtr (hDlg, DWLP_USER);
  5021. if (pCD)
  5022. {
  5023. pCD->m_bTemplatesColumn = ((NMLISTVIEW FAR*)lParam)->iSubItem;
  5024. ListView_SortItems (GetDlgItem (hDlg, IDC_TEMPLATELIST),
  5025. TemplatesSortCallback, pCD->m_bTemplatesColumn);
  5026. }
  5027. }
  5028. else
  5029. {
  5030. PostMessage (hDlg, WM_REFRESHDISPLAY, 0, 0);
  5031. }
  5032. break;
  5033. case WM_REFRESHDISPLAY:
  5034. if (ListView_GetNextItem (GetDlgItem(hDlg, IDC_TEMPLATELIST),
  5035. -1, LVNI_ALL | LVNI_SELECTED) == -1)
  5036. {
  5037. EnableWindow (GetDlgItem(hDlg, IDC_REMOVETEMPLATES), FALSE);
  5038. }
  5039. else
  5040. {
  5041. EnableWindow (GetDlgItem(hDlg, IDC_REMOVETEMPLATES), TRUE);
  5042. }
  5043. break;
  5044. case WM_HELP: // F1
  5045. WinHelp((HWND)((LPHELPINFO) lParam)->hItemHandle, HELP_FILE, HELP_WM_HELP,
  5046. (DWORD_PTR) (LPDWORD) aADMHelpIds);
  5047. return TRUE;
  5048. case WM_CONTEXTMENU: // right mouse click
  5049. WinHelp((HWND) wParam, HELP_FILE, HELP_CONTEXTMENU,
  5050. (DWORD_PTR) (LPDWORD) aADMHelpIds);
  5051. return TRUE;
  5052. }
  5053. return FALSE;
  5054. }
  5055. BOOL CPolicyComponentData::AddRSOPRegistryDataNode(LPTSTR lpKeyName, LPTSTR lpValueName, DWORD dwType,
  5056. DWORD dwDataSize, LPBYTE lpData, UINT uiPrecedence, LPTSTR lpGPOName, BOOL bDeleted)
  5057. {
  5058. DWORD dwSize;
  5059. LPRSOPREGITEM lpItem;
  5060. BOOL bSystemEntry = FALSE;
  5061. HRESULT hr = S_OK;
  5062. //
  5063. // Special case some registry key / values and do not add them to the link list.
  5064. // These registry entries are specific to snapins we write and we know for sure
  5065. // they have rsop UI that will show their values.
  5066. //
  5067. if (lpKeyName)
  5068. {
  5069. const TCHAR szCerts[] = TEXT("Software\\Policies\\Microsoft\\SystemCertificates");
  5070. int iCertLen = lstrlen (szCerts);
  5071. //
  5072. // Remove all system certificates
  5073. //
  5074. if (CompareString(LOCALE_INVARIANT, NORM_IGNORECASE | NORM_STOP_ON_NULL,
  5075. lpKeyName, iCertLen, szCerts, iCertLen) == CSTR_EQUAL)
  5076. {
  5077. bSystemEntry = TRUE;
  5078. }
  5079. if ( ! bSystemEntry )
  5080. {
  5081. const TCHAR szCryptography[] = TEXT("Software\\Policies\\Microsoft\\Cryptography");
  5082. int iCryptographyLen = lstrlen (szCryptography);
  5083. if (CompareString(LOCALE_INVARIANT, NORM_IGNORECASE | NORM_STOP_ON_NULL,
  5084. lpKeyName, iCryptographyLen, szCryptography, iCryptographyLen) == CSTR_EQUAL)
  5085. {
  5086. bSystemEntry = TRUE;
  5087. }
  5088. }
  5089. //
  5090. // Hide the digial signature policies for Software Installation
  5091. //
  5092. if (CompareString(LOCALE_INVARIANT, NORM_IGNORECASE | NORM_STOP_ON_NULL,
  5093. lpKeyName, -1, TEXT("Software\\Policies\\Microsoft\\Windows\\Installer"), -1) == CSTR_EQUAL)
  5094. {
  5095. if (lpValueName)
  5096. {
  5097. if (CompareString(LOCALE_INVARIANT, NORM_IGNORECASE | NORM_STOP_ON_NULL,
  5098. lpValueName, -1, TEXT("InstallKnownPackagesOnly"), -1) == CSTR_EQUAL)
  5099. {
  5100. bSystemEntry = TRUE;
  5101. }
  5102. else if (CompareString(LOCALE_INVARIANT, NORM_IGNORECASE | NORM_STOP_ON_NULL,
  5103. lpValueName, -1, TEXT("IgnoreSignaturePolicyForAdmins"), -1) == CSTR_EQUAL)
  5104. {
  5105. bSystemEntry = TRUE;
  5106. }
  5107. }
  5108. }
  5109. //
  5110. // Hide all the SAFER policies
  5111. //
  5112. const TCHAR szSaferKey[] = TEXT("Software\\Policies\\Microsoft\\Windows\\Safer");
  5113. int iSaferKeyLen = sizeof(szSaferKey) / sizeof(TCHAR) - 1;
  5114. if (CompareString(LOCALE_USER_DEFAULT, NORM_IGNORECASE | NORM_STOP_ON_NULL,
  5115. lpKeyName, iSaferKeyLen, szSaferKey, iSaferKeyLen) == CSTR_EQUAL)
  5116. {
  5117. bSystemEntry = TRUE;
  5118. }
  5119. }
  5120. if (bSystemEntry)
  5121. {
  5122. DebugMsg((DM_VERBOSE, TEXT("CPolicyComponentData::AddRSOPRegistryDataNode: Ignoring %s entry"), lpKeyName));
  5123. return TRUE;
  5124. }
  5125. //
  5126. // Calculate the size of the new registry item
  5127. //
  5128. dwSize = sizeof (RSOPREGITEM);
  5129. if (lpKeyName) {
  5130. dwSize += ((lstrlen(lpKeyName) + 1) * sizeof(TCHAR));
  5131. }
  5132. if (lpValueName) {
  5133. dwSize += ((lstrlen(lpValueName) + 1) * sizeof(TCHAR));
  5134. }
  5135. if (lpGPOName) {
  5136. dwSize += ((lstrlen(lpGPOName) + 1) * sizeof(TCHAR));
  5137. }
  5138. //
  5139. // Allocate space for it
  5140. //
  5141. lpItem = (LPRSOPREGITEM) LocalAlloc (LPTR, dwSize);
  5142. if (!lpItem) {
  5143. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::AddRSOPRegistryDataNode: Failed to allocate memory with %d"),
  5144. GetLastError()));
  5145. return FALSE;
  5146. }
  5147. //
  5148. // Fill in item
  5149. //
  5150. lpItem->dwType = dwType;
  5151. lpItem->dwSize = dwDataSize;
  5152. lpItem->uiPrecedence = uiPrecedence;
  5153. lpItem->bDeleted = bDeleted;
  5154. if (lpKeyName)
  5155. {
  5156. lpItem->lpKeyName = (LPTSTR)(((LPBYTE)lpItem) + sizeof(RSOPREGITEM));
  5157. hr = StringCchCopy (lpItem->lpKeyName, lstrlen(lpKeyName) + 1, lpKeyName);
  5158. ASSERT(SUCCEEDED(hr));
  5159. }
  5160. if (lpValueName)
  5161. {
  5162. if (lpKeyName)
  5163. {
  5164. lpItem->lpValueName = lpItem->lpKeyName + lstrlen (lpItem->lpKeyName) + 1;
  5165. }
  5166. else
  5167. {
  5168. lpItem->lpValueName = (LPTSTR)(((LPBYTE)lpItem) + sizeof(RSOPREGITEM));
  5169. }
  5170. hr = StringCchCopy (lpItem->lpValueName, lstrlen(lpValueName) + 1, lpValueName);
  5171. ASSERT(SUCCEEDED(hr));
  5172. }
  5173. if (lpGPOName)
  5174. {
  5175. if (lpValueName)
  5176. {
  5177. lpItem->lpGPOName = lpItem->lpValueName + lstrlen (lpItem->lpValueName) + 1;
  5178. }
  5179. else
  5180. {
  5181. if (lpKeyName)
  5182. {
  5183. lpItem->lpGPOName = lpItem->lpKeyName + lstrlen (lpItem->lpKeyName) + 1;
  5184. }
  5185. else
  5186. {
  5187. lpItem->lpGPOName = (LPTSTR)(((LPBYTE)lpItem) + sizeof(RSOPREGITEM));
  5188. }
  5189. }
  5190. hr = StringCchCopy (lpItem->lpGPOName, lstrlen(lpGPOName) + 1, lpGPOName);
  5191. ASSERT(SUCCEEDED(hr));
  5192. }
  5193. if (lpData)
  5194. {
  5195. lpItem->lpData = (LPBYTE) LocalAlloc (LPTR, dwDataSize);
  5196. if (!lpItem->lpData) {
  5197. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::AddRSOPRegistryDataNode: Failed to allocate memory for data with %d"),
  5198. GetLastError()));
  5199. LocalFree (lpItem);
  5200. return FALSE;
  5201. }
  5202. CopyMemory (lpItem->lpData, lpData, dwDataSize);
  5203. }
  5204. //
  5205. // Add item to link list
  5206. //
  5207. lpItem->pNext = m_pRSOPRegistryData;
  5208. m_pRSOPRegistryData = lpItem;
  5209. return TRUE;
  5210. }
  5211. VOID CPolicyComponentData::FreeRSOPRegistryData(VOID)
  5212. {
  5213. LPRSOPREGITEM lpTemp;
  5214. if (!m_pRSOPRegistryData)
  5215. {
  5216. return;
  5217. }
  5218. do {
  5219. lpTemp = m_pRSOPRegistryData->pNext;
  5220. if (m_pRSOPRegistryData->lpData)
  5221. {
  5222. LocalFree (m_pRSOPRegistryData->lpData);
  5223. }
  5224. LocalFree (m_pRSOPRegistryData);
  5225. m_pRSOPRegistryData = lpTemp;
  5226. } while (lpTemp);
  5227. }
  5228. HRESULT CPolicyComponentData::InitializeRSOPRegistryData(VOID)
  5229. {
  5230. BSTR pLanguage = NULL, pQuery = NULL;
  5231. BSTR pRegistryKey = NULL, pValueName = NULL, pValueType = NULL, pValue = NULL, pDeleted = NULL;
  5232. BSTR pPrecedence = NULL, pGPOid = NULL, pNamespace = NULL, pCommand = NULL;
  5233. IEnumWbemClassObject * pEnum = NULL;
  5234. IWbemClassObject *pObjects[2];
  5235. HRESULT hr;
  5236. ULONG ulRet;
  5237. VARIANT varRegistryKey, varValueName, varValueType, varData, varDeleted;
  5238. VARIANT varPrecedence, varGPOid, varCommand;
  5239. SAFEARRAY * pSafeArray;
  5240. IWbemLocator *pIWbemLocator = NULL;
  5241. IWbemServices *pIWbemServices = NULL;
  5242. LPTSTR lpGPOName;
  5243. DWORD dwDataSize;
  5244. LPBYTE lpData;
  5245. BSTR pValueTemp;
  5246. DebugMsg((DM_VERBOSE, TEXT("CPolicySnapIn::InitializeRSOPRegistryData: Entering")));
  5247. //
  5248. // Allocate BSTRs for the query language and for the query itself
  5249. //
  5250. pLanguage = SysAllocString (TEXT("WQL"));
  5251. if (!pLanguage)
  5252. {
  5253. DebugMsg((DM_WARNING, TEXT("CPolicySnapIn::InitializeRSOPRegistryData: Failed to allocate memory for language")));
  5254. hr = HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY);
  5255. goto Exit;
  5256. }
  5257. pQuery = SysAllocString (TEXT("SELECT registryKey, valueName, valueType, value, deleted, precedence, GPOID, command FROM RSOP_RegistryPolicySetting"));
  5258. if (!pQuery)
  5259. {
  5260. DebugMsg((DM_WARNING, TEXT("CPolicySnapIn::InitializeRSOPRegistryData: Failed to allocate memory for query")));
  5261. hr = HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY);
  5262. goto Exit;
  5263. }
  5264. //
  5265. // Allocate BSTRs for the property names we want to retreive
  5266. //
  5267. pRegistryKey = SysAllocString (TEXT("registryKey"));
  5268. if (!pRegistryKey)
  5269. {
  5270. DebugMsg((DM_WARNING, TEXT("CPolicySnapIn::InitializeRSOPRegistryData: Failed to allocate memory for registryKey")));
  5271. hr = HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY);
  5272. goto Exit;
  5273. }
  5274. pValueName = SysAllocString (TEXT("valueName"));
  5275. if (!pValueName)
  5276. {
  5277. DebugMsg((DM_WARNING, TEXT("CPolicySnapIn::InitializeRSOPRegistryData: Failed to allocate memory for valueName")));
  5278. hr = HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY);
  5279. goto Exit;
  5280. }
  5281. pValueType = SysAllocString (TEXT("valueType"));
  5282. if (!pValueType)
  5283. {
  5284. DebugMsg((DM_WARNING, TEXT("CPolicySnapIn::InitializeRSOPRegistryData: Failed to allocate memory for valueType")));
  5285. hr = HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY);
  5286. goto Exit;
  5287. }
  5288. pValue = SysAllocString (TEXT("value"));
  5289. if (!pValue)
  5290. {
  5291. DebugMsg((DM_WARNING, TEXT("CPolicySnapIn::InitializeRSOPRegistryData: Failed to allocate memory for value")));
  5292. hr = HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY);
  5293. goto Exit;
  5294. }
  5295. pDeleted = SysAllocString (TEXT("deleted"));
  5296. if (!pDeleted)
  5297. {
  5298. DebugMsg((DM_WARNING, TEXT("CPolicySnapIn::InitializeRSOPRegistryData: Failed to allocate memory for deleted")));
  5299. hr = HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY);
  5300. goto Exit;
  5301. }
  5302. pPrecedence = SysAllocString (TEXT("precedence"));
  5303. if (!pPrecedence)
  5304. {
  5305. DebugMsg((DM_WARNING, TEXT("CPolicySnapIn::InitializeRSOPRegistryData: Failed to allocate memory for precedence")));
  5306. hr = HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY);
  5307. goto Exit;
  5308. }
  5309. pGPOid = SysAllocString (TEXT("GPOID"));
  5310. if (!pGPOid)
  5311. {
  5312. DebugMsg((DM_WARNING, TEXT("CPolicySnapIn::InitializeRSOPRegistryData: Failed to allocate memory for GPO id")));
  5313. hr = HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY);
  5314. goto Exit;
  5315. }
  5316. pCommand = SysAllocString (TEXT("command"));
  5317. if (!pCommand)
  5318. {
  5319. DebugMsg((DM_WARNING, TEXT("CPolicySnapIn::InitializeRSOPRegistryData: Failed to allocate memory for command")));
  5320. hr = HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY);
  5321. goto Exit;
  5322. }
  5323. //
  5324. // Create an instance of the WMI locator service
  5325. //
  5326. hr = CoCreateInstance(CLSID_WbemLocator, NULL, CLSCTX_INPROC_SERVER,
  5327. IID_IWbemLocator, (LPVOID *) &pIWbemLocator);
  5328. if (FAILED(hr))
  5329. {
  5330. DebugMsg((DM_WARNING, TEXT("CPolicySnapIn::InitializeRSOPRegistryData: CoCreateInstance failed with 0x%x"), hr));
  5331. goto Exit;
  5332. }
  5333. //
  5334. // Allocate a BSTR for the namespace
  5335. //
  5336. pNamespace = SysAllocString (m_pszNamespace);
  5337. if (!pNamespace)
  5338. {
  5339. DebugMsg((DM_WARNING, TEXT("CPolicySnapIn::InitializeRSOPRegistryData: Failed to allocate memory for namespace")));
  5340. hr = HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY);
  5341. goto Exit;
  5342. }
  5343. //
  5344. // Connect to the server
  5345. //
  5346. hr = pIWbemLocator->ConnectServer(pNamespace, NULL, NULL, 0L, 0L, NULL, NULL,
  5347. &pIWbemServices);
  5348. if (FAILED(hr))
  5349. {
  5350. DebugMsg((DM_WARNING, TEXT("CPolicySnapIn::InitializeRSOPRegistryData: ConnectServer failed with 0x%x"), hr));
  5351. goto Exit;
  5352. }
  5353. // Set the proper security to encrypt the data
  5354. hr = CoSetProxyBlanket(pIWbemServices,
  5355. RPC_C_AUTHN_DEFAULT,
  5356. RPC_C_AUTHZ_DEFAULT,
  5357. COLE_DEFAULT_PRINCIPAL,
  5358. RPC_C_AUTHN_LEVEL_PKT_PRIVACY,
  5359. RPC_C_IMP_LEVEL_IMPERSONATE,
  5360. NULL,
  5361. 0);
  5362. if (FAILED(hr))
  5363. {
  5364. DebugMsg((DM_WARNING, TEXT("CPolicySnapIn::InitializeRSOPRegistryData: CoSetProxyBlanket failed with 0x%x"), hr));
  5365. goto Exit;
  5366. }
  5367. //
  5368. // Execute the query
  5369. //
  5370. hr = pIWbemServices->ExecQuery (pLanguage, pQuery,
  5371. WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
  5372. NULL, &pEnum);
  5373. if (FAILED(hr))
  5374. {
  5375. DebugMsg((DM_WARNING, TEXT("CPolicySnapIn::InitializeRSOPRegistryData: Failed to query for %s with 0x%x"),
  5376. pQuery, hr));
  5377. goto Exit;
  5378. }
  5379. //
  5380. // Loop through the results
  5381. //
  5382. while (pEnum->Next(WBEM_INFINITE, 1, pObjects, &ulRet) == S_OK)
  5383. {
  5384. //
  5385. // Check for the "data not available case"
  5386. //
  5387. if (ulRet == 0)
  5388. {
  5389. hr = S_OK;
  5390. goto Exit;
  5391. }
  5392. //
  5393. // Get the deleted flag
  5394. //
  5395. hr = pObjects[0]->Get (pDeleted, 0, &varDeleted, NULL, NULL);
  5396. if (SUCCEEDED(hr))
  5397. {
  5398. //
  5399. // Get the registry key
  5400. //
  5401. hr = pObjects[0]->Get (pRegistryKey, 0, &varRegistryKey, NULL, NULL);
  5402. if (SUCCEEDED(hr))
  5403. {
  5404. //
  5405. // Get the value name
  5406. //
  5407. hr = pObjects[0]->Get (pValueName, 0, &varValueName, NULL, NULL);
  5408. if (SUCCEEDED(hr))
  5409. {
  5410. //
  5411. // Get the value type
  5412. //
  5413. hr = pObjects[0]->Get (pValueType, 0, &varValueType, NULL, NULL);
  5414. if (SUCCEEDED(hr))
  5415. {
  5416. //
  5417. // Get the value data
  5418. //
  5419. hr = pObjects[0]->Get (pValue, 0, &varData, NULL, NULL);
  5420. if (SUCCEEDED(hr))
  5421. {
  5422. //
  5423. // Get the precedence
  5424. //
  5425. hr = pObjects[0]->Get (pPrecedence, 0, &varPrecedence, NULL, NULL);
  5426. if (SUCCEEDED(hr))
  5427. {
  5428. //
  5429. // Get the command
  5430. //
  5431. hr = pObjects[0]->Get (pCommand, 0, &varCommand, NULL, NULL);
  5432. if (SUCCEEDED(hr))
  5433. {
  5434. //
  5435. // Get the GPO ID
  5436. //
  5437. hr = pObjects[0]->Get (pGPOid, 0, &varGPOid, NULL, NULL);
  5438. if (SUCCEEDED(hr))
  5439. {
  5440. hr = GetGPOFriendlyName (pIWbemServices, varGPOid.bstrVal,
  5441. pLanguage, &lpGPOName);
  5442. if (SUCCEEDED(hr))
  5443. {
  5444. if (varValueName.vt != VT_NULL)
  5445. {
  5446. pValueTemp = varValueName.bstrVal;
  5447. }
  5448. else
  5449. {
  5450. pValueTemp = NULL;
  5451. }
  5452. if (varData.vt != VT_NULL)
  5453. {
  5454. pSafeArray = varData.parray;
  5455. dwDataSize = pSafeArray->rgsabound[0].cElements;
  5456. lpData = (LPBYTE) pSafeArray->pvData;
  5457. }
  5458. else
  5459. {
  5460. dwDataSize = 0;
  5461. lpData = NULL;
  5462. }
  5463. if ((varValueType.uintVal == REG_NONE) && pValueTemp &&
  5464. (CompareString(LOCALE_INVARIANT, NORM_IGNORECASE | NORM_STOP_ON_NULL,
  5465. pValueTemp, -1, TEXT("**command"), -1) == CSTR_EQUAL))
  5466. {
  5467. pValueTemp = varCommand.bstrVal;
  5468. dwDataSize = 0;
  5469. lpData = NULL;
  5470. }
  5471. AddRSOPRegistryDataNode(varRegistryKey.bstrVal, pValueTemp,
  5472. varValueType.uintVal, dwDataSize, lpData,
  5473. varPrecedence.uintVal, lpGPOName,
  5474. (varDeleted.boolVal == 0) ? FALSE : TRUE);
  5475. LocalFree (lpGPOName);
  5476. }
  5477. VariantClear (&varGPOid);
  5478. }
  5479. VariantClear (&varCommand);
  5480. }
  5481. VariantClear (&varPrecedence);
  5482. }
  5483. VariantClear (&varData);
  5484. }
  5485. VariantClear (&varValueType);
  5486. }
  5487. VariantClear (&varValueName);
  5488. }
  5489. VariantClear (&varRegistryKey);
  5490. }
  5491. VariantClear (&varDeleted);
  5492. }
  5493. pObjects[0]->Release();
  5494. }
  5495. hr = S_OK;
  5496. Exit:
  5497. if (pEnum)
  5498. {
  5499. pEnum->Release();
  5500. }
  5501. if (pIWbemLocator)
  5502. {
  5503. pIWbemLocator->Release();
  5504. }
  5505. if (pIWbemServices)
  5506. {
  5507. pIWbemServices->Release();
  5508. }
  5509. if (pLanguage)
  5510. {
  5511. SysFreeString (pLanguage);
  5512. }
  5513. if (pQuery)
  5514. {
  5515. SysFreeString (pQuery);
  5516. }
  5517. if (pRegistryKey)
  5518. {
  5519. SysFreeString (pRegistryKey);
  5520. }
  5521. if (pValueType)
  5522. {
  5523. SysFreeString (pValueType);
  5524. }
  5525. if (pValueName)
  5526. {
  5527. SysFreeString (pValueName);
  5528. }
  5529. if (pDeleted)
  5530. {
  5531. SysFreeString (pDeleted);
  5532. }
  5533. if (pValue)
  5534. {
  5535. SysFreeString (pValue);
  5536. }
  5537. if (pNamespace)
  5538. {
  5539. SysFreeString (pNamespace);
  5540. }
  5541. if (pPrecedence)
  5542. {
  5543. SysFreeString (pPrecedence);
  5544. }
  5545. if (pGPOid)
  5546. {
  5547. SysFreeString (pGPOid);
  5548. }
  5549. if (pCommand)
  5550. {
  5551. SysFreeString (pCommand);
  5552. }
  5553. DebugMsg((DM_VERBOSE, TEXT("CPolicySnapIn::InitializeRSOPRegistryData: Leaving")));
  5554. return hr;
  5555. }
  5556. HRESULT CPolicyComponentData::GetGPOFriendlyName(IWbemServices *pIWbemServices,
  5557. LPTSTR lpGPOID, BSTR pLanguage,
  5558. LPTSTR *pGPOName)
  5559. {
  5560. BSTR pQuery = NULL, pName = NULL;
  5561. LPTSTR lpQuery = NULL;
  5562. IEnumWbemClassObject * pEnum = NULL;
  5563. IWbemClassObject *pObjects[2];
  5564. HRESULT hr;
  5565. ULONG ulRet;
  5566. VARIANT varGPOName;
  5567. DWORD dwGPONameLen = 0;
  5568. //
  5569. // Set the default
  5570. //
  5571. *pGPOName = NULL;
  5572. //
  5573. // Build the query
  5574. //
  5575. DWORD dwQryLen = lstrlen(lpGPOID) + 50;
  5576. lpQuery = (LPTSTR) LocalAlloc (LPTR, ( dwQryLen * sizeof(TCHAR)));
  5577. if (!lpQuery)
  5578. {
  5579. DebugMsg((DM_WARNING, TEXT("CPolicySnapIn::GetGPOFriendlyName: Failed to allocate memory for unicode query")));
  5580. hr = HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY);
  5581. goto Exit;
  5582. }
  5583. hr = StringCchPrintf (lpQuery, dwQryLen, TEXT("SELECT name, id FROM RSOP_GPO where id=\"%s\""), lpGPOID);
  5584. ASSERT(SUCCEEDED(hr));
  5585. pQuery = SysAllocString (lpQuery);
  5586. if (!pQuery)
  5587. {
  5588. DebugMsg((DM_WARNING, TEXT("CPolicySnapIn::GetGPOFriendlyName: Failed to allocate memory for query")));
  5589. hr = HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY);
  5590. goto Exit;
  5591. }
  5592. //
  5593. // Allocate BSTRs for the property names we want to retreive
  5594. //
  5595. pName = SysAllocString (TEXT("name"));
  5596. if (!pName)
  5597. {
  5598. DebugMsg((DM_WARNING, TEXT("CPolicySnapIn::GetGPOFriendlyName: Failed to allocate memory for name")));
  5599. hr = HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY);
  5600. goto Exit;
  5601. }
  5602. //
  5603. // Execute the query
  5604. //
  5605. hr = pIWbemServices->ExecQuery (pLanguage, pQuery,
  5606. WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
  5607. NULL, &pEnum);
  5608. if (FAILED(hr))
  5609. {
  5610. DebugMsg((DM_WARNING, TEXT("CPolicySnapIn::GetGPOFriendlyName: Failed to query for %s with 0x%x"),
  5611. pQuery, hr));
  5612. goto Exit;
  5613. }
  5614. //
  5615. // Loop through the results
  5616. //
  5617. hr = pEnum->Next(WBEM_INFINITE, 1, pObjects, &ulRet);
  5618. if (FAILED(hr))
  5619. {
  5620. DebugMsg((DM_WARNING, TEXT("CPolicySnapIn::GetGPOFriendlyName: Failed to get first item in query results for %s with 0x%x"),
  5621. pQuery, hr));
  5622. goto Exit;
  5623. }
  5624. //
  5625. // Check for the "data not available case"
  5626. //
  5627. if (ulRet == 0)
  5628. {
  5629. hr = S_OK;
  5630. goto Exit;
  5631. }
  5632. //
  5633. // Get the name
  5634. //
  5635. hr = pObjects[0]->Get (pName, 0, &varGPOName, NULL, NULL);
  5636. pObjects[0]->Release();
  5637. if (FAILED(hr))
  5638. {
  5639. DebugMsg((DM_WARNING, TEXT("CPolicySnapIn::GetGPOFriendlyName: Failed to get gponame in query results for %s with 0x%x"),
  5640. pQuery, hr));
  5641. goto Exit;
  5642. }
  5643. //
  5644. // Save the name
  5645. //
  5646. dwGPONameLen = lstrlen(varGPOName.bstrVal) + 1;
  5647. *pGPOName = (LPTSTR) LocalAlloc (LPTR, (dwGPONameLen) * sizeof(TCHAR));
  5648. if (!(*pGPOName))
  5649. {
  5650. DebugMsg((DM_WARNING, TEXT("CPolicySnapIn::GetGPOFriendlyName: Failed to allocate memory for GPO Name")));
  5651. hr = HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY);
  5652. goto Exit;
  5653. }
  5654. hr = StringCchCopy (*pGPOName, dwGPONameLen, varGPOName.bstrVal);
  5655. ASSERT(SUCCEEDED(hr));
  5656. VariantClear (&varGPOName);
  5657. hr = S_OK;
  5658. Exit:
  5659. if (pEnum)
  5660. {
  5661. pEnum->Release();
  5662. }
  5663. if (pQuery)
  5664. {
  5665. SysFreeString (pQuery);
  5666. }
  5667. if (lpQuery)
  5668. {
  5669. LocalFree (lpQuery);
  5670. }
  5671. if (pName)
  5672. {
  5673. SysFreeString (pName);
  5674. }
  5675. return hr;
  5676. }
  5677. //
  5678. // Note: the data in the uiPrecedence argument is really a UINT. It's declared
  5679. // as a HKEY so the hkeyRoot variable that calls this method can be used for both
  5680. // GPE and RSOP mode.
  5681. //
  5682. UINT CPolicyComponentData::ReadRSOPRegistryValue(HKEY uiPrecedence, TCHAR * pszKeyName,
  5683. TCHAR * pszValueName, LPBYTE pData,
  5684. DWORD dwMaxSize, DWORD *dwType,
  5685. LPTSTR *lpGPOName, LPRSOPREGITEM lpItem)
  5686. {
  5687. LPRSOPREGITEM lpTemp;
  5688. BOOL bDeleted = FALSE;
  5689. LPTSTR lpValueNameTemp = pszValueName;
  5690. if (!lpItem)
  5691. {
  5692. lpTemp = m_pRSOPRegistryData;
  5693. if (pszValueName)
  5694. {
  5695. INT iDelPrefixLen = lstrlen(szDELETEPREFIX);
  5696. if (CompareString (LOCALE_USER_DEFAULT, NORM_IGNORECASE | NORM_STOP_ON_NULL,
  5697. pszValueName, iDelPrefixLen,
  5698. szDELETEPREFIX, iDelPrefixLen) == CSTR_EQUAL)
  5699. {
  5700. lpValueNameTemp = pszValueName+iDelPrefixLen;
  5701. bDeleted = TRUE;
  5702. }
  5703. }
  5704. //
  5705. // Find the item
  5706. //
  5707. while (lpTemp)
  5708. {
  5709. if (pszKeyName && lpValueNameTemp &&
  5710. lpTemp->lpKeyName && lpTemp->lpValueName)
  5711. {
  5712. if (bDeleted == lpTemp->bDeleted)
  5713. {
  5714. if ((uiPrecedence == 0) || (uiPrecedence == (HKEY)LongToHandle(lpTemp->uiPrecedence)))
  5715. {
  5716. if (!lstrcmpi(lpTemp->lpValueName, lpValueNameTemp) &&
  5717. !lstrcmpi(lpTemp->lpKeyName, pszKeyName))
  5718. {
  5719. break;
  5720. }
  5721. }
  5722. }
  5723. }
  5724. else if (!pszKeyName && lpValueNameTemp &&
  5725. !lpTemp->lpKeyName && lpTemp->lpValueName)
  5726. {
  5727. if (bDeleted == lpTemp->bDeleted)
  5728. {
  5729. if ((uiPrecedence == 0) || (uiPrecedence == (HKEY)LongToHandle(lpTemp->uiPrecedence)))
  5730. {
  5731. if (!lstrcmpi(lpTemp->lpValueName, lpValueNameTemp))
  5732. {
  5733. break;
  5734. }
  5735. }
  5736. }
  5737. }
  5738. else if (pszKeyName && !lpValueNameTemp &&
  5739. lpTemp->lpKeyName && !lpTemp->lpValueName)
  5740. {
  5741. if (bDeleted == lpTemp->bDeleted)
  5742. {
  5743. if ((uiPrecedence == 0) || (uiPrecedence == (HKEY)LongToHandle(lpTemp->uiPrecedence)))
  5744. {
  5745. if (!lstrcmpi(lpTemp->lpKeyName, pszKeyName))
  5746. {
  5747. break;
  5748. }
  5749. }
  5750. }
  5751. }
  5752. lpTemp = lpTemp->pNext;
  5753. }
  5754. }
  5755. else
  5756. {
  5757. //
  5758. // Read a specific item
  5759. //
  5760. lpTemp = lpItem;
  5761. }
  5762. //
  5763. // Exit now if the item wasn't found
  5764. //
  5765. if (!lpTemp)
  5766. {
  5767. return ERROR_FILE_NOT_FOUND;
  5768. }
  5769. //
  5770. // Check if the data will fit in the buffer passed in
  5771. //
  5772. if (lpTemp->dwSize > dwMaxSize)
  5773. {
  5774. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::ReadRSOPRegistryValue: The returned data size of %d is greater than the buffer size passed in of %d for %s\\%s"),
  5775. lpTemp->dwSize, dwMaxSize, pszKeyName, pszValueName));
  5776. return ERROR_NOT_ENOUGH_MEMORY;
  5777. }
  5778. //
  5779. // Copy the data
  5780. //
  5781. if (lpTemp->lpData)
  5782. {
  5783. CopyMemory (pData, lpTemp->lpData, lpTemp->dwSize);
  5784. }
  5785. *dwType = lpTemp->dwType;
  5786. if (lpGPOName)
  5787. {
  5788. *lpGPOName = lpTemp->lpGPOName;
  5789. }
  5790. return ERROR_SUCCESS;
  5791. }
  5792. //
  5793. // Note: the data in the uiPrecedence argument is really a UINT. It's declared
  5794. // as a HKEY so the hkeyRoot variable that calls this method can be used for both
  5795. // GPE and RSOP mode.
  5796. //
  5797. UINT CPolicyComponentData::EnumRSOPRegistryValues(HKEY uiPrecedence, TCHAR * pszKeyName,
  5798. TCHAR * pszValueName, DWORD dwMaxSize,
  5799. LPRSOPREGITEM *lpEnum)
  5800. {
  5801. LPRSOPREGITEM lpTemp;
  5802. HRESULT hr = S_OK;
  5803. if (lpEnum && *lpEnum)
  5804. {
  5805. lpTemp = (*lpEnum)->pNext;
  5806. }
  5807. else
  5808. {
  5809. lpTemp = m_pRSOPRegistryData;
  5810. }
  5811. //
  5812. // Find the next item
  5813. //
  5814. while (lpTemp)
  5815. {
  5816. if (!pszKeyName && !lpTemp->lpKeyName)
  5817. {
  5818. if (!lpTemp->bDeleted)
  5819. {
  5820. if ((uiPrecedence == 0) || (uiPrecedence == (HKEY)LongToHandle(lpTemp->uiPrecedence)))
  5821. {
  5822. break;
  5823. }
  5824. }
  5825. }
  5826. else if (pszKeyName && lpTemp->lpKeyName)
  5827. {
  5828. if (!lpTemp->bDeleted)
  5829. {
  5830. if ((uiPrecedence == 0) || (uiPrecedence == (HKEY)LongToHandle(lpTemp->uiPrecedence)))
  5831. {
  5832. if (!lstrcmpi(lpTemp->lpKeyName, pszKeyName))
  5833. {
  5834. break;
  5835. }
  5836. }
  5837. }
  5838. }
  5839. lpTemp = lpTemp->pNext;
  5840. }
  5841. //
  5842. // Exit now if an item wasn't found
  5843. //
  5844. if (!lpTemp)
  5845. {
  5846. *lpEnum = NULL;
  5847. return ERROR_NO_MORE_ITEMS;
  5848. }
  5849. if (lpTemp->lpValueName)
  5850. {
  5851. //
  5852. // Check if the value name will fit in the buffer passed in
  5853. //
  5854. if ((DWORD)(lstrlen(lpTemp->lpValueName) + 1) > dwMaxSize)
  5855. {
  5856. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::EnumRSOPRegistryValues: The valuename buffer size is too small")));
  5857. return ERROR_NOT_ENOUGH_MEMORY;
  5858. }
  5859. hr = StringCchCopy (pszValueName, dwMaxSize, lpTemp->lpValueName);
  5860. ASSERT(SUCCEEDED(hr));
  5861. }
  5862. else
  5863. {
  5864. *pszValueName = TEXT('\0');
  5865. }
  5866. //
  5867. // Save the item pointer
  5868. //
  5869. *lpEnum = lpTemp;
  5870. return ERROR_SUCCESS;
  5871. }
  5872. //
  5873. // Note: the data in the uiPrecedence argument is really a UINT. It's declared
  5874. // as a HKEY so the hkeyRoot variable that calls this method can be used for both
  5875. // GPE and RSOP mode.
  5876. //
  5877. UINT CPolicyComponentData::FindRSOPRegistryEntry(HKEY uiPrecedence, TCHAR * pszKeyName,
  5878. TCHAR * pszValueName, LPRSOPREGITEM *lpEnum)
  5879. {
  5880. LPRSOPREGITEM lpTemp;
  5881. BOOL bDeleted = FALSE;
  5882. LPTSTR lpValueNameTemp = pszValueName;
  5883. if (lpEnum && *lpEnum)
  5884. {
  5885. lpTemp = (*lpEnum)->pNext;
  5886. }
  5887. else
  5888. {
  5889. lpTemp = m_pRSOPRegistryData;
  5890. }
  5891. if (pszValueName)
  5892. {
  5893. INT iDelPrefixLen = lstrlen(szDELETEPREFIX);
  5894. if (CompareString (LOCALE_USER_DEFAULT, NORM_IGNORECASE | NORM_STOP_ON_NULL,
  5895. pszValueName, iDelPrefixLen,
  5896. szDELETEPREFIX, iDelPrefixLen) == CSTR_EQUAL)
  5897. {
  5898. lpValueNameTemp = pszValueName+iDelPrefixLen;
  5899. bDeleted = TRUE;
  5900. }
  5901. }
  5902. //
  5903. // Find the next item
  5904. //
  5905. while (lpTemp)
  5906. {
  5907. if (pszKeyName && lpValueNameTemp &&
  5908. lpTemp->lpKeyName && lpTemp->lpValueName)
  5909. {
  5910. if (bDeleted == lpTemp->bDeleted)
  5911. {
  5912. if ((uiPrecedence == 0) || (uiPrecedence == (HKEY)LongToHandle(lpTemp->uiPrecedence)))
  5913. {
  5914. if (!lstrcmpi(lpTemp->lpValueName, lpValueNameTemp) &&
  5915. !lstrcmpi(lpTemp->lpKeyName, pszKeyName))
  5916. {
  5917. break;
  5918. }
  5919. }
  5920. }
  5921. }
  5922. else if (!pszKeyName && lpValueNameTemp &&
  5923. !lpTemp->lpKeyName && lpTemp->lpValueName)
  5924. {
  5925. if (bDeleted == lpTemp->bDeleted)
  5926. {
  5927. if ((uiPrecedence == 0) || (uiPrecedence == (HKEY)LongToHandle(lpTemp->uiPrecedence)))
  5928. {
  5929. if (!lstrcmpi(lpTemp->lpValueName, lpValueNameTemp))
  5930. {
  5931. break;
  5932. }
  5933. }
  5934. }
  5935. }
  5936. else if (pszKeyName && !lpValueNameTemp &&
  5937. lpTemp->lpKeyName && !lpTemp->lpValueName)
  5938. {
  5939. if (bDeleted == lpTemp->bDeleted)
  5940. {
  5941. if ((uiPrecedence == 0) || (uiPrecedence == (HKEY)LongToHandle(lpTemp->uiPrecedence)))
  5942. {
  5943. if (!lstrcmpi(lpTemp->lpKeyName, pszKeyName))
  5944. {
  5945. break;
  5946. }
  5947. }
  5948. }
  5949. }
  5950. lpTemp = lpTemp->pNext;
  5951. }
  5952. //
  5953. // Exit now if an item wasn't found
  5954. //
  5955. if (!lpTemp)
  5956. {
  5957. *lpEnum = NULL;
  5958. return ERROR_NO_MORE_ITEMS;
  5959. }
  5960. //
  5961. // Save the item pointer
  5962. //
  5963. *lpEnum = lpTemp;
  5964. return ERROR_SUCCESS;
  5965. }
  5966. VOID CPolicyComponentData::DumpRSOPRegistryData(void)
  5967. {
  5968. LPRSOPREGITEM lpTemp;
  5969. TCHAR szDebug[50];
  5970. lpTemp = m_pRSOPRegistryData;
  5971. if (m_bUserScope)
  5972. OutputDebugString (TEXT("\n\nDump of RSOP user registry data\n"));
  5973. else
  5974. OutputDebugString (TEXT("\n\nDump of RSOP computer registry data\n"));
  5975. while (lpTemp)
  5976. {
  5977. OutputDebugString (TEXT("\n\n"));
  5978. if (lpTemp->lpKeyName)
  5979. OutputDebugString (lpTemp->lpKeyName);
  5980. else
  5981. OutputDebugString (TEXT("NULL Key Name"));
  5982. OutputDebugString (TEXT("\n"));
  5983. if (lpTemp->lpValueName)
  5984. OutputDebugString (lpTemp->lpValueName);
  5985. else
  5986. OutputDebugString (TEXT("NULL Value Name"));
  5987. OutputDebugString (TEXT("\n"));
  5988. if (lpTemp->dwType == REG_DWORD)
  5989. {
  5990. (void) StringCchPrintf (szDebug, ARRAYSIZE(szDebug), TEXT("REG_DWORD\n%d\n"), *((LPDWORD)lpTemp->lpData));
  5991. OutputDebugString (szDebug);
  5992. }
  5993. else if (lpTemp->dwType == REG_SZ)
  5994. {
  5995. OutputDebugString (TEXT("REG_SZ\n"));
  5996. if (lpTemp->lpData)
  5997. OutputDebugString ((LPTSTR)lpTemp->lpData);
  5998. OutputDebugString (TEXT("\n"));
  5999. }
  6000. else if (lpTemp->dwType == REG_EXPAND_SZ)
  6001. {
  6002. OutputDebugString (TEXT("REG_EXPAND_SZ\n"));
  6003. if (lpTemp->lpData)
  6004. OutputDebugString ((LPTSTR)lpTemp->lpData);
  6005. OutputDebugString (TEXT("\n"));
  6006. }
  6007. else if (lpTemp->dwType == REG_BINARY)
  6008. {
  6009. OutputDebugString (TEXT("REG_BINARY\n"));
  6010. OutputDebugString (TEXT("<Binary data not displayed>\n"));
  6011. }
  6012. else if (lpTemp->dwType == REG_NONE)
  6013. {
  6014. OutputDebugString (TEXT("REG_NONE\n"));
  6015. }
  6016. else
  6017. {
  6018. (void) StringCchPrintf (szDebug, ARRAYSIZE(szDebug), TEXT("Unknown type: %d\n"), lpTemp->dwType);
  6019. OutputDebugString (szDebug);
  6020. }
  6021. (void) StringCchPrintf (szDebug, ARRAYSIZE(szDebug), TEXT("Precedence: %d\n"), lpTemp->uiPrecedence);
  6022. OutputDebugString(szDebug);
  6023. (void) StringCchPrintf (szDebug, ARRAYSIZE(szDebug), TEXT("Deleted: %d\n"), lpTemp->bDeleted);
  6024. OutputDebugString(szDebug);
  6025. (void) StringCchPrintf (szDebug, ARRAYSIZE(szDebug), TEXT("bFoundInADM: %d\n"), lpTemp->bFoundInADM);
  6026. OutputDebugString(szDebug);
  6027. OutputDebugString (TEXT("GPOName: "));
  6028. if (lpTemp->lpGPOName)
  6029. OutputDebugString (lpTemp->lpGPOName);
  6030. else
  6031. OutputDebugString (TEXT("NULL GPO Name"));
  6032. OutputDebugString (TEXT("\n"));
  6033. lpTemp = lpTemp->pNext;
  6034. }
  6035. OutputDebugString (TEXT("\n\n"));
  6036. }
  6037. BOOL CPolicyComponentData::FindEntryInActionList(POLICY * pPolicy, ACTIONLIST * pActionList, LPTSTR lpKeyName, LPTSTR lpValueName)
  6038. {
  6039. UINT uIndex;
  6040. ACTION * pAction = NULL;
  6041. TCHAR * pszKeyName = NULL;
  6042. TCHAR * pszValueName = NULL;
  6043. //
  6044. // Loop through each of the entries to see if they match
  6045. //
  6046. pAction = &pActionList->Action[0];
  6047. for (uIndex = 0; uIndex < pActionList->nActionItems; uIndex++)
  6048. {
  6049. if (uIndex == 0)
  6050. {
  6051. // already set up pAction
  6052. }
  6053. else
  6054. {
  6055. pAction = (ACTION *)(((LPBYTE)pActionList) + pAction->uOffsetNextAction);
  6056. }
  6057. //
  6058. // Get the value and keynames
  6059. //
  6060. pszValueName = (TCHAR *)(((LPBYTE)pActionList) + pAction->uOffsetValueName);
  6061. if (pAction->uOffsetKeyName)
  6062. {
  6063. pszKeyName = (TCHAR *)(((LPBYTE)pActionList) + pAction->uOffsetKeyName);
  6064. }
  6065. else
  6066. {
  6067. pszKeyName = (TCHAR *)(((LPBYTE)pPolicy) + pPolicy->uOffsetKeyName);
  6068. }
  6069. if (!lstrcmpi(pszKeyName, lpKeyName) && !lstrcmpi(pszValueName, lpValueName)) {
  6070. return TRUE;
  6071. }
  6072. }
  6073. return FALSE;
  6074. }
  6075. BOOL CPolicyComponentData::FindEntryInTable(TABLEENTRY * pTable, LPTSTR lpKeyName, LPTSTR lpValueName)
  6076. {
  6077. POLICY * pEntry = (POLICY *) pTable;
  6078. if ((pEntry->dwType & ETYPE_POLICY) || (pEntry->dwType & ETYPE_SETTING))
  6079. {
  6080. if (!lstrcmpi(lpKeyName, GETKEYNAMEPTR(pEntry)))
  6081. {
  6082. if ( (!(GETVALUENAMEPTR(pEntry)) || (!lstrcmpi(GETVALUENAMEPTR(pEntry), TEXT("")))) ) {
  6083. if (pEntry->dwType & STYPE_LISTBOX) {
  6084. return TRUE;
  6085. }
  6086. }
  6087. else if (!lstrcmpi(lpValueName, GETVALUENAMEPTR(pEntry)))
  6088. {
  6089. return TRUE;
  6090. }
  6091. }
  6092. // look in the actionlists
  6093. // actionslist can be at 3 places. under policy itself or under the dropdown lists below
  6094. ACTIONLIST * pActionList;
  6095. if (pEntry->dwType & ETYPE_POLICY) {
  6096. if (pEntry->uOffsetActionList_On) {
  6097. pActionList = (ACTIONLIST *)(((LPBYTE)pEntry) + pEntry->uOffsetActionList_On);
  6098. if (FindEntryInActionList(pEntry, pActionList, lpKeyName, lpValueName))
  6099. return TRUE;
  6100. }
  6101. if (pEntry->uOffsetActionList_Off) {
  6102. pActionList = (ACTIONLIST *)(((LPBYTE)pEntry) + pEntry->uOffsetActionList_Off);
  6103. if (FindEntryInActionList(pEntry, pActionList, lpKeyName, lpValueName))
  6104. return TRUE;
  6105. }
  6106. }
  6107. if (pEntry->dwType & ETYPE_SETTING) {
  6108. SETTINGS * pSettings = (SETTINGS *)pTable;
  6109. if (pSettings) {
  6110. BYTE * pObjectData = GETOBJECTDATAPTR(pSettings);
  6111. if (pObjectData) {
  6112. if ((pEntry->dwType & STYPE_MASK) == STYPE_CHECKBOX) {
  6113. if (((CHECKBOXINFO *)pObjectData)->uOffsetActionList_On) {
  6114. pActionList = (ACTIONLIST *)(((LPBYTE)pEntry) + (((CHECKBOXINFO *)pObjectData)->uOffsetActionList_On));
  6115. if (FindEntryInActionList(pEntry, pActionList, lpKeyName, lpValueName))
  6116. return TRUE;
  6117. }
  6118. if (((CHECKBOXINFO *)pObjectData)->uOffsetActionList_Off) {
  6119. pActionList = (ACTIONLIST *)(((LPBYTE)pEntry) + (((CHECKBOXINFO *)pObjectData)->uOffsetActionList_Off));
  6120. if (FindEntryInActionList(pEntry, pActionList, lpKeyName, lpValueName))
  6121. return TRUE;
  6122. }
  6123. }
  6124. if ((pEntry->dwType & STYPE_MASK) == STYPE_DROPDOWNLIST) {
  6125. DROPDOWNINFO * pddi;
  6126. pddi = (DROPDOWNINFO *) pObjectData;
  6127. while (pddi) {
  6128. if (pddi->uOffsetActionList) {
  6129. pActionList = (ACTIONLIST *)(((LPBYTE)pEntry) + pddi->uOffsetActionList);
  6130. if (FindEntryInActionList(pEntry, pActionList, lpKeyName, lpValueName))
  6131. return TRUE;
  6132. }
  6133. if (pddi->uOffsetNextDropdowninfo) {
  6134. pddi = (DROPDOWNINFO *) ( (BYTE *) pEntry + pddi->uOffsetNextDropdowninfo);
  6135. }
  6136. else {
  6137. pddi = NULL;
  6138. }
  6139. }
  6140. }
  6141. }
  6142. }
  6143. }
  6144. }
  6145. if (pEntry->pChild)
  6146. {
  6147. if (FindEntryInTable(pEntry->pChild, lpKeyName, lpValueName))
  6148. {
  6149. return TRUE;
  6150. }
  6151. }
  6152. if (pEntry->pNext)
  6153. {
  6154. if (FindEntryInTable(pEntry->pNext, lpKeyName, lpValueName))
  6155. {
  6156. return TRUE;
  6157. }
  6158. }
  6159. return FALSE;
  6160. }
  6161. VOID CPolicyComponentData::AddEntryToList (TABLEENTRY *pItem)
  6162. {
  6163. TABLEENTRY *lpTemp;
  6164. lpTemp = m_pExtraSettingsRoot->pChild;
  6165. if (!lpTemp)
  6166. {
  6167. m_pExtraSettingsRoot->pChild = pItem;
  6168. return;
  6169. }
  6170. while (lpTemp->pNext)
  6171. {
  6172. lpTemp = lpTemp->pNext;
  6173. }
  6174. lpTemp->pNext = pItem;
  6175. pItem->pPrev = lpTemp;
  6176. }
  6177. VOID CPolicyComponentData::InitializeExtraSettings (VOID)
  6178. {
  6179. LPRSOPREGITEM lpTemp;
  6180. TCHAR szValueStr[MAX_PATH];
  6181. HRESULT hr = S_OK;
  6182. lpTemp = m_pRSOPRegistryData;
  6183. while (lpTemp)
  6184. {
  6185. //
  6186. // Build REGITEM structures for every registry entry that has a precedence of 1
  6187. // and that is not found in any adm file
  6188. //
  6189. if ((lpTemp->uiPrecedence == 1) && (lpTemp->dwType != REG_NONE) && (!lpTemp->bDeleted))
  6190. {
  6191. DWORD dwBufSize = 0;
  6192. REGITEM *pTmp, *pItem;
  6193. LPTSTR lpName;
  6194. //
  6195. // Check to see if this registry entry is used by any adm policy / part
  6196. //
  6197. if (m_bUserScope)
  6198. {
  6199. if (m_pUserCategoryList)
  6200. {
  6201. lpTemp->bFoundInADM = FindEntryInTable(m_pUserCategoryList,
  6202. lpTemp->lpKeyName,
  6203. lpTemp->lpValueName);
  6204. }
  6205. }
  6206. else
  6207. {
  6208. if (m_pMachineCategoryList)
  6209. {
  6210. lpTemp->bFoundInADM = FindEntryInTable(m_pMachineCategoryList,
  6211. lpTemp->lpKeyName,
  6212. lpTemp->lpValueName);
  6213. }
  6214. }
  6215. if (!lpTemp->bFoundInADM)
  6216. {
  6217. //
  6218. // Build regitem entry
  6219. //
  6220. pItem = (REGITEM *) GlobalAlloc(GPTR, sizeof(REGITEM));
  6221. if (pItem)
  6222. {
  6223. pItem->dwSize = sizeof(REGITEM);
  6224. pItem->dwType = ETYPE_REGITEM;
  6225. pItem->lpItem = lpTemp;
  6226. dwBufSize += lstrlen (lpTemp->lpKeyName) + 1;
  6227. if (lpTemp->lpValueName && *lpTemp->lpValueName)
  6228. {
  6229. dwBufSize += lstrlen (lpTemp->lpValueName) + 1;
  6230. }
  6231. lpName = (LPTSTR) LocalAlloc (LPTR, dwBufSize * sizeof(TCHAR));
  6232. if (lpName)
  6233. {
  6234. hr = StringCchCopy (lpName, dwBufSize, lpTemp->lpKeyName);
  6235. ASSERT(SUCCEEDED(hr));
  6236. if (lpTemp->lpValueName && *lpTemp->lpValueName)
  6237. {
  6238. hr = StringCchCat (lpName, dwBufSize, TEXT("\\"));
  6239. ASSERT(SUCCEEDED(hr));
  6240. hr = StringCchCat (lpName, dwBufSize, lpTemp->lpValueName);
  6241. ASSERT(SUCCEEDED(hr));
  6242. }
  6243. //
  6244. // Add the display name
  6245. //
  6246. pTmp = (REGITEM *) AddDataToEntry((TABLEENTRY *)pItem,
  6247. (BYTE *)lpName,(lstrlen(lpName)+1) * sizeof(TCHAR),&(pItem->uOffsetName),
  6248. &dwBufSize);
  6249. if (pTmp)
  6250. {
  6251. pItem = pTmp;
  6252. //
  6253. // Add the keyname
  6254. //
  6255. pTmp = (REGITEM *) AddDataToEntry((TABLEENTRY *)pItem,
  6256. (BYTE *)lpTemp->lpKeyName,(lstrlen(lpTemp->lpKeyName)+1) * sizeof(TCHAR),&(pItem->uOffsetKeyName),
  6257. &dwBufSize);
  6258. if (pTmp)
  6259. {
  6260. pItem = pTmp;
  6261. szValueStr[0] = TEXT('\0');
  6262. if (lpTemp->dwType == REG_DWORD)
  6263. {
  6264. hr = StringCchPrintf (szValueStr, ARRAYSIZE(szValueStr), TEXT("%d"), (DWORD) *((LPDWORD)lpTemp->lpData));
  6265. ASSERT(SUCCEEDED(hr));
  6266. }
  6267. else if (lpTemp->dwType == REG_SZ)
  6268. {
  6269. lstrcpyn (szValueStr, (LPTSTR)lpTemp->lpData, ARRAYSIZE(szValueStr));
  6270. }
  6271. else if (lpTemp->dwType == REG_EXPAND_SZ)
  6272. {
  6273. lstrcpyn (szValueStr, (LPTSTR)lpTemp->lpData, ARRAYSIZE(szValueStr));
  6274. }
  6275. else if (lpTemp->dwType == REG_BINARY)
  6276. {
  6277. LoadString(g_hInstance, IDS_BINARYDATA, szValueStr, ARRAYSIZE(szValueStr));
  6278. }
  6279. else
  6280. {
  6281. LoadString(g_hInstance, IDS_UNKNOWNDATA, szValueStr, ARRAYSIZE(szValueStr));
  6282. }
  6283. //
  6284. // Add the value in string format
  6285. //
  6286. pTmp = (REGITEM *) AddDataToEntry((TABLEENTRY *)pItem,
  6287. (BYTE *)szValueStr,(lstrlen(szValueStr)+1) * sizeof(TCHAR),&(pItem->uOffsetValueStr),
  6288. &dwBufSize);
  6289. if (pTmp)
  6290. {
  6291. pItem = pTmp;
  6292. //
  6293. // Check if this is a real policy
  6294. //
  6295. if (CompareString(LOCALE_INVARIANT, NORM_IGNORECASE | NORM_STOP_ON_NULL,
  6296. lpTemp->lpKeyName, m_iSWPoliciesLen,
  6297. SOFTWARE_POLICIES, m_iSWPoliciesLen) == CSTR_EQUAL)
  6298. {
  6299. pItem->bTruePolicy = TRUE;
  6300. }
  6301. else if (CompareString(LOCALE_INVARIANT, NORM_IGNORECASE | NORM_STOP_ON_NULL,
  6302. lpTemp->lpKeyName, m_iWinPoliciesLen,
  6303. WINDOWS_POLICIES, m_iWinPoliciesLen) == CSTR_EQUAL)
  6304. {
  6305. pItem->bTruePolicy = TRUE;
  6306. }
  6307. AddEntryToList ((TABLEENTRY *)pItem);
  6308. }
  6309. else
  6310. {
  6311. GlobalFree (pItem);
  6312. }
  6313. }
  6314. else
  6315. {
  6316. GlobalFree (pItem);
  6317. }
  6318. }
  6319. else
  6320. {
  6321. GlobalFree (pItem);
  6322. }
  6323. LocalFree (lpName);
  6324. }
  6325. else
  6326. {
  6327. GlobalFree (pItem);
  6328. }
  6329. }
  6330. }
  6331. }
  6332. lpTemp = lpTemp->pNext;
  6333. }
  6334. }
  6335. BOOL CPolicyComponentData::DoesNodeExist (LPSUPPORTEDENTRY *pList, LPTSTR lpString)
  6336. {
  6337. LPSUPPORTEDENTRY lpItem;
  6338. if (!(*pList))
  6339. {
  6340. return FALSE;
  6341. }
  6342. lpItem = *pList;
  6343. while (lpItem)
  6344. {
  6345. if (!lstrcmpi(lpItem->lpString, lpString))
  6346. {
  6347. return TRUE;
  6348. }
  6349. lpItem = lpItem->pNext;
  6350. }
  6351. return FALSE;
  6352. }
  6353. BOOL CPolicyComponentData::CheckSupportedFilter (POLICY *pPolicy)
  6354. {
  6355. LPSUPPORTEDENTRY lpItem = m_pSupportedStrings;
  6356. LPTSTR lpString = GETSUPPORTEDPTR(pPolicy);
  6357. if (!lpItem || !m_bUseSupportedOnFilter)
  6358. {
  6359. return TRUE;
  6360. }
  6361. while (lpItem)
  6362. {
  6363. if (!lpString)
  6364. {
  6365. if (lpItem->bNull)
  6366. {
  6367. return lpItem->bEnabled;
  6368. }
  6369. }
  6370. else
  6371. {
  6372. if (!lstrcmpi(lpItem->lpString, lpString))
  6373. {
  6374. return lpItem->bEnabled;
  6375. }
  6376. }
  6377. lpItem = lpItem->pNext;
  6378. }
  6379. return TRUE;
  6380. }
  6381. BOOL CPolicyComponentData::IsAnyPolicyAllowedPastFilter(TABLEENTRY * pCategory)
  6382. {
  6383. TABLEENTRY * pEntry;
  6384. INT iState;
  6385. if (!pCategory || !pCategory->pChild)
  6386. {
  6387. return FALSE;
  6388. }
  6389. pEntry = pCategory->pChild;
  6390. while (pEntry)
  6391. {
  6392. if (pEntry->dwType & ETYPE_CATEGORY)
  6393. {
  6394. if (IsAnyPolicyAllowedPastFilter(pEntry))
  6395. {
  6396. return TRUE;
  6397. }
  6398. }
  6399. else if (pEntry->dwType & ETYPE_POLICY)
  6400. {
  6401. if (CheckSupportedFilter((POLICY *) pEntry))
  6402. {
  6403. return TRUE;
  6404. }
  6405. }
  6406. pEntry = pEntry->pNext;
  6407. }
  6408. return FALSE;
  6409. }
  6410. VOID CPolicyComponentData::AddSupportedNode (LPSUPPORTEDENTRY *pList, LPTSTR lpString,
  6411. BOOL bNull)
  6412. {
  6413. LPSUPPORTEDENTRY lpItem;
  6414. DWORD dwSize;
  6415. //
  6416. // Check if this item is already in the link list first
  6417. //
  6418. if (DoesNodeExist (pList, lpString))
  6419. {
  6420. return;
  6421. }
  6422. //
  6423. // Add it to the list
  6424. //
  6425. dwSize = sizeof(SUPPORTEDENTRY);
  6426. dwSize += ((lstrlen(lpString) + 1) * sizeof(TCHAR));
  6427. lpItem = (LPSUPPORTEDENTRY) LocalAlloc (LPTR, dwSize);
  6428. if (!lpItem)
  6429. {
  6430. return;
  6431. }
  6432. lpItem->lpString = (LPTSTR)(((LPBYTE)lpItem) + sizeof(SUPPORTEDENTRY));
  6433. (void) StringCchCopy (lpItem->lpString, lstrlen(lpString) + 1, lpString);
  6434. lpItem->bEnabled = TRUE;
  6435. lpItem->bNull = bNull;
  6436. lpItem->pNext = *pList;
  6437. *pList = lpItem;
  6438. }
  6439. VOID CPolicyComponentData::FreeSupportedData(LPSUPPORTEDENTRY lpList)
  6440. {
  6441. LPSUPPORTEDENTRY lpTemp;
  6442. do {
  6443. lpTemp = lpList->pNext;
  6444. LocalFree (lpList);
  6445. lpList = lpTemp;
  6446. } while (lpTemp);
  6447. }
  6448. VOID CPolicyComponentData::InitializeSupportInfo(TABLEENTRY * pTable, LPSUPPORTEDENTRY *pList)
  6449. {
  6450. POLICY * pEntry = (POLICY *) pTable;
  6451. LPTSTR lpString;
  6452. if (pEntry->dwType & ETYPE_POLICY)
  6453. {
  6454. lpString = GETSUPPORTEDPTR(pEntry);
  6455. if (lpString)
  6456. {
  6457. AddSupportedNode (pList, lpString, FALSE);
  6458. }
  6459. }
  6460. if (pEntry->pChild)
  6461. {
  6462. InitializeSupportInfo(pEntry->pChild, pList);
  6463. }
  6464. if (pEntry->pNext)
  6465. {
  6466. InitializeSupportInfo(pEntry->pNext, pList);
  6467. }
  6468. }
  6469. ///////////////////////////////////////////////////////////////////////////////
  6470. // //
  6471. // Class factory object implementation //
  6472. // //
  6473. ///////////////////////////////////////////////////////////////////////////////
  6474. CPolicyComponentDataCF::CPolicyComponentDataCF(BOOL bUser, BOOL bRSOP)
  6475. {
  6476. m_cRef = 1;
  6477. InterlockedIncrement(&g_cRefThisDll);
  6478. m_bUser = bUser;
  6479. m_bRSOP = bRSOP;
  6480. }
  6481. CPolicyComponentDataCF::~CPolicyComponentDataCF()
  6482. {
  6483. InterlockedDecrement(&g_cRefThisDll);
  6484. }
  6485. ///////////////////////////////////////////////////////////////////////////////
  6486. // //
  6487. // Class factory object implementation (IUnknown) //
  6488. // //
  6489. ///////////////////////////////////////////////////////////////////////////////
  6490. STDMETHODIMP_(ULONG)
  6491. CPolicyComponentDataCF::AddRef()
  6492. {
  6493. return ++m_cRef;
  6494. }
  6495. STDMETHODIMP_(ULONG)
  6496. CPolicyComponentDataCF::Release()
  6497. {
  6498. if (--m_cRef == 0)
  6499. {
  6500. delete this;
  6501. return 0;
  6502. }
  6503. return m_cRef;
  6504. }
  6505. STDMETHODIMP
  6506. CPolicyComponentDataCF::QueryInterface(REFIID riid, LPVOID FAR* ppv)
  6507. {
  6508. if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IClassFactory))
  6509. {
  6510. *ppv = (LPCLASSFACTORY)this;
  6511. m_cRef++;
  6512. return S_OK;
  6513. }
  6514. else
  6515. {
  6516. *ppv = NULL;
  6517. return E_NOINTERFACE;
  6518. }
  6519. }
  6520. ///////////////////////////////////////////////////////////////////////////////
  6521. // //
  6522. // Class factory object implementation (IClassFactory) //
  6523. // //
  6524. ///////////////////////////////////////////////////////////////////////////////
  6525. STDMETHODIMP
  6526. CPolicyComponentDataCF::CreateInstance(LPUNKNOWN pUnkOuter,
  6527. REFIID riid,
  6528. LPVOID FAR* ppvObj)
  6529. {
  6530. *ppvObj = NULL;
  6531. if (pUnkOuter)
  6532. return CLASS_E_NOAGGREGATION;
  6533. CPolicyComponentData *pComponentData = new CPolicyComponentData(m_bUser, m_bRSOP); // ref count == 1
  6534. if (!pComponentData)
  6535. return E_OUTOFMEMORY;
  6536. HRESULT hr = pComponentData->QueryInterface(riid, ppvObj);
  6537. pComponentData->Release(); // release initial ref
  6538. return hr;
  6539. }
  6540. STDMETHODIMP
  6541. CPolicyComponentDataCF::LockServer(BOOL fLock)
  6542. {
  6543. return E_NOTIMPL;
  6544. }
  6545. ///////////////////////////////////////////////////////////////////////////////
  6546. // //
  6547. // Class factory object creation (IClassFactory) //
  6548. // //
  6549. ///////////////////////////////////////////////////////////////////////////////
  6550. HRESULT CreatePolicyComponentDataClassFactory (REFCLSID rclsid, REFIID riid, LPVOID* ppv)
  6551. {
  6552. HRESULT hr;
  6553. //
  6554. // Admin Templates in editing mode
  6555. //
  6556. if (IsEqualCLSID (rclsid, CLSID_PolicySnapInMachine)) {
  6557. CPolicyComponentDataCF *pComponentDataCF = new CPolicyComponentDataCF(FALSE, FALSE); // ref == 1
  6558. if (!pComponentDataCF)
  6559. return E_OUTOFMEMORY;
  6560. hr = pComponentDataCF->QueryInterface(riid, ppv);
  6561. pComponentDataCF->Release(); // release initial ref
  6562. return hr;
  6563. }
  6564. if (IsEqualCLSID (rclsid, CLSID_PolicySnapInUser)) {
  6565. CPolicyComponentDataCF *pComponentDataCF = new CPolicyComponentDataCF(TRUE, FALSE); // ref == 1
  6566. if (!pComponentDataCF)
  6567. return E_OUTOFMEMORY;
  6568. hr = pComponentDataCF->QueryInterface(riid, ppv);
  6569. pComponentDataCF->Release(); // release initial ref
  6570. return hr;
  6571. }
  6572. //
  6573. // Admin Templates in RSOP mode
  6574. //
  6575. if (IsEqualCLSID (rclsid, CLSID_RSOPolicySnapInMachine)) {
  6576. CPolicyComponentDataCF *pComponentDataCF = new CPolicyComponentDataCF(FALSE, TRUE); // ref == 1
  6577. if (!pComponentDataCF)
  6578. return E_OUTOFMEMORY;
  6579. hr = pComponentDataCF->QueryInterface(riid, ppv);
  6580. pComponentDataCF->Release(); // release initial ref
  6581. return hr;
  6582. }
  6583. if (IsEqualCLSID (rclsid, CLSID_RSOPolicySnapInUser)) {
  6584. CPolicyComponentDataCF *pComponentDataCF = new CPolicyComponentDataCF(TRUE, TRUE); // ref == 1
  6585. if (!pComponentDataCF)
  6586. return E_OUTOFMEMORY;
  6587. hr = pComponentDataCF->QueryInterface(riid, ppv);
  6588. pComponentDataCF->Release(); // release initial ref
  6589. return hr;
  6590. }
  6591. return CLASS_E_CLASSNOTAVAILABLE;
  6592. }
  6593. unsigned int CPolicySnapIn::m_cfNodeType = RegisterClipboardFormat(CCF_NODETYPE);
  6594. ///////////////////////////////////////////////////////////////////////////////
  6595. // //
  6596. // CPolicySnapIn object implementation //
  6597. // //
  6598. ///////////////////////////////////////////////////////////////////////////////
  6599. CPolicySnapIn::CPolicySnapIn(CPolicyComponentData *pComponent)
  6600. {
  6601. m_cRef = 1;
  6602. InterlockedIncrement(&g_cRefThisDll);
  6603. m_pcd = pComponent;
  6604. m_pConsole = NULL;
  6605. m_pResult = NULL;
  6606. m_pHeader = NULL;
  6607. m_pConsoleVerb = NULL;
  6608. m_pDisplayHelp = NULL;
  6609. m_nColumn1Size = 350;
  6610. m_nColumn2Size = 100;
  6611. m_nColumn3Size = 200;
  6612. m_lViewMode = LVS_REPORT;
  6613. if (m_pcd->m_bRSOP)
  6614. {
  6615. m_bPolicyOnly = FALSE;
  6616. }
  6617. else
  6618. {
  6619. m_bPolicyOnly = TRUE;
  6620. }
  6621. m_dwPolicyOnlyPolicy = 2;
  6622. m_hMsgWindow = NULL;
  6623. m_uiRefreshMsg = RegisterWindowMessage (TEXT("ADM Template Reload"));
  6624. m_pCurrentPolicy = NULL;
  6625. m_hPropDlg = NULL;
  6626. LoadString(g_hInstance, IDS_NAME, m_pName, ARRAYSIZE(m_pName));
  6627. LoadString(g_hInstance, IDS_STATE, m_pState, ARRAYSIZE(m_pState));
  6628. LoadString(g_hInstance, IDS_SETTING, m_pSetting, ARRAYSIZE(m_pSetting));
  6629. LoadString(g_hInstance, IDS_GPONAME, m_pGPOName, ARRAYSIZE(m_pGPOName));
  6630. LoadString(g_hInstance, IDS_MULTIPLEGPOS, m_pMultipleGPOs, ARRAYSIZE(m_pMultipleGPOs));
  6631. LoadString(g_hInstance, IDS_ENABLED, m_pEnabled, ARRAYSIZE(m_pEnabled));
  6632. LoadString(g_hInstance, IDS_DISABLED, m_pDisabled, ARRAYSIZE(m_pDisabled));
  6633. LoadString(g_hInstance, IDS_NOTCONFIGURED, m_pNotConfigured, ARRAYSIZE(m_pNotConfigured));
  6634. }
  6635. CPolicySnapIn::~CPolicySnapIn()
  6636. {
  6637. InterlockedDecrement(&g_cRefThisDll);
  6638. if (m_pConsole != NULL)
  6639. {
  6640. m_pConsole->SetHeader(NULL);
  6641. m_pConsole->Release();
  6642. m_pConsole = NULL;
  6643. }
  6644. if (m_pHeader != NULL)
  6645. {
  6646. m_pHeader->Release();
  6647. m_pHeader = NULL;
  6648. }
  6649. if (m_pResult != NULL)
  6650. {
  6651. m_pResult->Release();
  6652. m_pResult = NULL;
  6653. }
  6654. if (m_pConsoleVerb != NULL)
  6655. {
  6656. m_pConsoleVerb->Release();
  6657. m_pConsoleVerb = NULL;
  6658. }
  6659. if (m_pDisplayHelp != NULL)
  6660. {
  6661. m_pDisplayHelp->Release();
  6662. m_pDisplayHelp = NULL;
  6663. }
  6664. }
  6665. ///////////////////////////////////////////////////////////////////////////////
  6666. // //
  6667. // CPolicySnapIn object implementation (IUnknown) //
  6668. // //
  6669. ///////////////////////////////////////////////////////////////////////////////
  6670. HRESULT CPolicySnapIn::QueryInterface (REFIID riid, void **ppv)
  6671. {
  6672. if (IsEqualIID(riid, IID_IComponent) || IsEqualIID(riid, IID_IUnknown))
  6673. {
  6674. *ppv = (LPCOMPONENT)this;
  6675. m_cRef++;
  6676. return S_OK;
  6677. }
  6678. else if (IsEqualIID(riid, IID_IExtendContextMenu))
  6679. {
  6680. *ppv = (LPEXTENDCONTEXTMENU)this;
  6681. m_cRef++;
  6682. return S_OK;
  6683. }
  6684. else if (IsEqualIID(riid, IID_IExtendPropertySheet))
  6685. {
  6686. *ppv = (LPEXTENDPROPERTYSHEET)this;
  6687. m_cRef++;
  6688. return S_OK;
  6689. }
  6690. else
  6691. {
  6692. *ppv = NULL;
  6693. return E_NOINTERFACE;
  6694. }
  6695. }
  6696. ULONG CPolicySnapIn::AddRef (void)
  6697. {
  6698. return ++m_cRef;
  6699. }
  6700. ULONG CPolicySnapIn::Release (void)
  6701. {
  6702. if (--m_cRef == 0) {
  6703. delete this;
  6704. return 0;
  6705. }
  6706. return m_cRef;
  6707. }
  6708. ///////////////////////////////////////////////////////////////////////////////
  6709. // //
  6710. // CPolicySnapIn object implementation (IComponent) //
  6711. // //
  6712. ///////////////////////////////////////////////////////////////////////////////
  6713. STDMETHODIMP CPolicySnapIn::Initialize(LPCONSOLE lpConsole)
  6714. {
  6715. HRESULT hr;
  6716. WNDCLASS wc;
  6717. HKEY hKey;
  6718. DWORD dwSize, dwType;
  6719. // Save the IConsole pointer
  6720. m_pConsole = lpConsole;
  6721. m_pConsole->AddRef();
  6722. hr = m_pConsole->QueryInterface(IID_IHeaderCtrl,
  6723. reinterpret_cast<void**>(&m_pHeader));
  6724. // Give the console the header control interface pointer
  6725. if (SUCCEEDED(hr))
  6726. m_pConsole->SetHeader(m_pHeader);
  6727. m_pConsole->QueryInterface(IID_IResultData,
  6728. reinterpret_cast<void**>(&m_pResult));
  6729. hr = m_pConsole->QueryConsoleVerb(&m_pConsoleVerb);
  6730. hr = m_pConsole->QueryInterface(IID_IDisplayHelp,
  6731. reinterpret_cast<void**>(&m_pDisplayHelp));
  6732. ZeroMemory (&wc, sizeof(wc));
  6733. wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
  6734. wc.lpfnWndProc = ClipWndProc;
  6735. wc.cbWndExtra = sizeof(DWORD);
  6736. wc.hInstance = (HINSTANCE) g_hInstance;
  6737. wc.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);
  6738. wc.lpszClassName = TEXT("ClipClass");
  6739. if (!RegisterClass(&wc))
  6740. {
  6741. if (GetLastError() != ERROR_CLASS_ALREADY_EXISTS)
  6742. {
  6743. DebugMsg((DM_WARNING, TEXT("CPolicySnapIn::Initialize: RegisterClass for clipclass failed with %d."),
  6744. GetLastError()));
  6745. return E_FAIL;
  6746. }
  6747. }
  6748. ZeroMemory (&wc, sizeof(wc));
  6749. wc.lpfnWndProc = MessageWndProc;
  6750. wc.cbWndExtra = sizeof(LPVOID);
  6751. wc.hInstance = (HINSTANCE) g_hInstance;
  6752. wc.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);
  6753. wc.lpszClassName = TEXT("GPMessageWindowClass");
  6754. if (!RegisterClass(&wc))
  6755. {
  6756. if (GetLastError() != ERROR_CLASS_ALREADY_EXISTS)
  6757. {
  6758. DebugMsg((DM_WARNING, TEXT("CPolicySnapIn::Initialize: RegisterClass for message window class failed with %d."),
  6759. GetLastError()));
  6760. return E_FAIL;
  6761. }
  6762. }
  6763. m_hMsgWindow = CreateWindow (TEXT("GPMessageWindowClass"), TEXT("GP Hidden Message Window"),
  6764. WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, 0, 0, NULL, NULL, NULL,
  6765. (LPVOID) this);
  6766. if (!m_hMsgWindow)
  6767. {
  6768. DebugMsg((DM_WARNING, TEXT("CPolicySnapIn::Initialize: CreateWindow failed with %d."),
  6769. GetLastError()));
  6770. return E_FAIL;
  6771. }
  6772. //
  6773. // Load the user's options
  6774. //
  6775. if (RegOpenKeyEx (HKEY_CURRENT_USER, GPE_POLICIES_KEY, 0,
  6776. KEY_READ, &hKey) == ERROR_SUCCESS)
  6777. {
  6778. dwSize = sizeof(m_dwPolicyOnlyPolicy);
  6779. RegQueryValueEx (hKey, POLICYONLY_VALUE, NULL, &dwType,
  6780. (LPBYTE) &m_dwPolicyOnlyPolicy, &dwSize);
  6781. RegCloseKey (hKey);
  6782. }
  6783. if (m_dwPolicyOnlyPolicy == 0)
  6784. {
  6785. m_bPolicyOnly = FALSE;
  6786. }
  6787. else if (m_dwPolicyOnlyPolicy == 1)
  6788. {
  6789. m_bPolicyOnly = TRUE;
  6790. }
  6791. return S_OK;
  6792. }
  6793. STDMETHODIMP CPolicySnapIn::Destroy(MMC_COOKIE cookie)
  6794. {
  6795. DestroyWindow (m_hMsgWindow);
  6796. if (m_pConsole != NULL)
  6797. {
  6798. m_pConsole->SetHeader(NULL);
  6799. m_pConsole->Release();
  6800. m_pConsole = NULL;
  6801. }
  6802. if (m_pHeader != NULL)
  6803. {
  6804. m_pHeader->Release();
  6805. m_pHeader = NULL;
  6806. }
  6807. if (m_pResult != NULL)
  6808. {
  6809. m_pResult->Release();
  6810. m_pResult = NULL;
  6811. }
  6812. if (m_pConsoleVerb != NULL)
  6813. {
  6814. m_pConsoleVerb->Release();
  6815. m_pConsoleVerb = NULL;
  6816. }
  6817. if (m_pDisplayHelp != NULL)
  6818. {
  6819. m_pDisplayHelp->Release();
  6820. m_pDisplayHelp = NULL;
  6821. }
  6822. return S_OK;
  6823. }
  6824. STDMETHODIMP CPolicySnapIn::Notify(LPDATAOBJECT lpDataObject, MMC_NOTIFY_TYPE event, LPARAM arg, LPARAM param)
  6825. {
  6826. HRESULT hr = S_OK;
  6827. switch(event)
  6828. {
  6829. case MMCN_COLUMNS_CHANGED:
  6830. hr = S_OK;
  6831. break;
  6832. case MMCN_DBLCLICK:
  6833. hr = S_FALSE;
  6834. break;
  6835. case MMCN_ADD_IMAGES:
  6836. HBITMAP hbmp16x16;
  6837. HBITMAP hbmp32x32;
  6838. hbmp16x16 = LoadBitmap(g_hInstance, MAKEINTRESOURCE(IDB_16x16));
  6839. if (hbmp16x16)
  6840. {
  6841. hbmp32x32 = LoadBitmap(g_hInstance, MAKEINTRESOURCE(IDB_32x32));
  6842. if (hbmp32x32)
  6843. {
  6844. LPIMAGELIST pImageList = (LPIMAGELIST) arg;
  6845. // Set the images
  6846. pImageList->ImageListSetStrip(reinterpret_cast<LONG_PTR *>(hbmp16x16),
  6847. reinterpret_cast<LONG_PTR *>(hbmp32x32),
  6848. 0, RGB(255, 0, 255));
  6849. DeleteObject(hbmp32x32);
  6850. }
  6851. DeleteObject(hbmp16x16);
  6852. }
  6853. break;
  6854. case MMCN_SHOW:
  6855. if (arg == TRUE)
  6856. {
  6857. RESULTDATAITEM resultItem;
  6858. LPPOLICYDATAOBJECT pPolicyDataObject;
  6859. TABLEENTRY * pNode, *pTemp = NULL;
  6860. MMC_COOKIE cookie;
  6861. INT i, iState;
  6862. BOOL bAdd;
  6863. //
  6864. // Get the cookie of the scope pane item
  6865. //
  6866. hr = lpDataObject->QueryInterface(IID_IPolicyDataObject, (LPVOID *)&pPolicyDataObject);
  6867. if (FAILED(hr))
  6868. return S_OK;
  6869. hr = pPolicyDataObject->GetCookie(&cookie);
  6870. pPolicyDataObject->Release(); // release initial ref
  6871. if (FAILED(hr))
  6872. return S_OK;
  6873. pNode = (TABLEENTRY *)cookie;
  6874. if (pNode)
  6875. {
  6876. pTemp = pNode->pChild;
  6877. }
  6878. //
  6879. // Prepare the view
  6880. //
  6881. m_pHeader->InsertColumn(0, m_pSetting, LVCFMT_LEFT, m_nColumn1Size);
  6882. m_pHeader->InsertColumn(1, m_pState, LVCFMT_CENTER, m_nColumn2Size);
  6883. if (m_pcd->m_bRSOP)
  6884. {
  6885. m_pHeader->InsertColumn(2, m_pGPOName, LVCFMT_CENTER, m_nColumn3Size);
  6886. }
  6887. m_pResult->SetViewMode(m_lViewMode);
  6888. //
  6889. // Add the Policies
  6890. //
  6891. while (pTemp)
  6892. {
  6893. if (pTemp->dwType == ETYPE_POLICY)
  6894. {
  6895. bAdd = TRUE;
  6896. if (m_pcd->m_bUseSupportedOnFilter)
  6897. {
  6898. bAdd = m_pcd->CheckSupportedFilter((POLICY *)pTemp);
  6899. }
  6900. if (bAdd && m_pcd->m_bShowConfigPoliciesOnly)
  6901. {
  6902. iState = GetPolicyState(pTemp, 1, NULL);
  6903. if (iState == -1)
  6904. {
  6905. bAdd = FALSE;
  6906. }
  6907. }
  6908. if (bAdd && m_bPolicyOnly)
  6909. {
  6910. if (((POLICY *) pTemp)->bTruePolicy != TRUE)
  6911. {
  6912. bAdd = FALSE;
  6913. }
  6914. }
  6915. if (bAdd)
  6916. {
  6917. resultItem.mask = RDI_STR | RDI_IMAGE | RDI_PARAM;
  6918. resultItem.str = MMC_CALLBACK;
  6919. if (((POLICY *) pTemp)->bTruePolicy)
  6920. {
  6921. resultItem.nImage = 4;
  6922. }
  6923. else
  6924. {
  6925. resultItem.nImage = 5;
  6926. }
  6927. resultItem.nCol = 0;
  6928. resultItem.lParam = (LPARAM) pTemp;
  6929. if (SUCCEEDED(m_pResult->InsertItem(&resultItem)))
  6930. {
  6931. resultItem.mask = RDI_STR;
  6932. resultItem.str = MMC_CALLBACK;
  6933. resultItem.bScopeItem = FALSE;
  6934. resultItem.nCol = 1;
  6935. m_pResult->SetItem(&resultItem);
  6936. }
  6937. }
  6938. }
  6939. else if (pTemp->dwType == ETYPE_REGITEM)
  6940. {
  6941. bAdd = TRUE;
  6942. if (m_bPolicyOnly)
  6943. {
  6944. if (((REGITEM *) pTemp)->bTruePolicy != TRUE)
  6945. {
  6946. bAdd = FALSE;
  6947. }
  6948. }
  6949. if (((REGITEM *) pTemp)->lpItem->bFoundInADM == TRUE)
  6950. {
  6951. bAdd = FALSE;
  6952. }
  6953. if (bAdd)
  6954. {
  6955. resultItem.mask = RDI_STR | RDI_IMAGE | RDI_PARAM;
  6956. resultItem.str = MMC_CALLBACK;
  6957. if (((REGITEM *) pTemp)->bTruePolicy)
  6958. {
  6959. resultItem.nImage = 4;
  6960. }
  6961. else
  6962. {
  6963. resultItem.nImage = 5;
  6964. }
  6965. resultItem.nCol = 0;
  6966. resultItem.lParam = (LPARAM) pTemp;
  6967. if (SUCCEEDED(m_pResult->InsertItem(&resultItem)))
  6968. {
  6969. resultItem.mask = RDI_STR;
  6970. resultItem.str = MMC_CALLBACK;
  6971. resultItem.bScopeItem = FALSE;
  6972. resultItem.nCol = 1;
  6973. m_pResult->SetItem(&resultItem);
  6974. }
  6975. }
  6976. }
  6977. pTemp = pTemp->pNext;
  6978. }
  6979. }
  6980. else
  6981. {
  6982. m_pHeader->GetColumnWidth(0, &m_nColumn1Size);
  6983. m_pHeader->GetColumnWidth(1, &m_nColumn2Size);
  6984. if (m_pcd->m_bRSOP)
  6985. {
  6986. m_pHeader->GetColumnWidth(2, &m_nColumn3Size);
  6987. }
  6988. m_pResult->GetViewMode(&m_lViewMode);
  6989. }
  6990. break;
  6991. case MMCN_SELECT:
  6992. {
  6993. LPPOLICYDATAOBJECT pPolicyDataObject;
  6994. DATA_OBJECT_TYPES type;
  6995. MMC_COOKIE cookie;
  6996. POLICY * pPolicy;
  6997. //
  6998. // See if this is one of our items.
  6999. //
  7000. hr = lpDataObject->QueryInterface(IID_IPolicyDataObject, (LPVOID *)&pPolicyDataObject);
  7001. if (FAILED(hr))
  7002. break;
  7003. pPolicyDataObject->GetType(&type);
  7004. pPolicyDataObject->GetCookie(&cookie);
  7005. pPolicyDataObject->Release();
  7006. if (m_pConsoleVerb)
  7007. {
  7008. //
  7009. // Set the default verb to open
  7010. //
  7011. m_pConsoleVerb->SetDefaultVerb(MMC_VERB_OPEN);
  7012. //
  7013. // If this is a result pane item or the root of the namespace
  7014. // nodes, enable the Properties menu item
  7015. //
  7016. if (type == CCT_RESULT)
  7017. {
  7018. if (HIWORD(arg))
  7019. {
  7020. m_pConsoleVerb->SetVerbState(MMC_VERB_PROPERTIES, ENABLED, TRUE);
  7021. m_pConsoleVerb->SetDefaultVerb(MMC_VERB_PROPERTIES);
  7022. }
  7023. }
  7024. }
  7025. if (m_hPropDlg && (type == CCT_RESULT) && HIWORD(arg))
  7026. {
  7027. pPolicy = (POLICY *)cookie;
  7028. if (pPolicy->dwType & ETYPE_POLICY)
  7029. {
  7030. m_pCurrentPolicy = pPolicy;
  7031. SendMessage (GetParent(m_hPropDlg), PSM_QUERYSIBLINGS, 1000, 0);
  7032. }
  7033. }
  7034. }
  7035. break;
  7036. case MMCN_CONTEXTHELP:
  7037. {
  7038. if (m_pDisplayHelp)
  7039. {
  7040. LPPOLICYDATAOBJECT pPolicyDataObject;
  7041. DATA_OBJECT_TYPES type;
  7042. MMC_COOKIE cookie;
  7043. LPOLESTR pszHelpTopic;
  7044. //
  7045. // See if this is one of our items.
  7046. //
  7047. hr = lpDataObject->QueryInterface(IID_IPolicyDataObject, (LPVOID *)&pPolicyDataObject);
  7048. if (FAILED(hr))
  7049. break;
  7050. pPolicyDataObject->Release();
  7051. //
  7052. // Display the admin templates help page
  7053. //
  7054. DWORD dwHlpLen = 50;
  7055. pszHelpTopic = (LPOLESTR) CoTaskMemAlloc (dwHlpLen * sizeof(WCHAR));
  7056. if (pszHelpTopic)
  7057. {
  7058. hr = StringCchCopy (pszHelpTopic, dwHlpLen, TEXT("gpedit.chm::/adm.htm"));
  7059. ASSERT(SUCCEEDED(hr));
  7060. m_pDisplayHelp->ShowTopic (pszHelpTopic);
  7061. }
  7062. }
  7063. }
  7064. break;
  7065. default:
  7066. hr = E_UNEXPECTED;
  7067. break;
  7068. }
  7069. return hr;
  7070. }
  7071. STDMETHODIMP CPolicySnapIn::GetDisplayInfo(LPRESULTDATAITEM pResult)
  7072. {
  7073. if (pResult)
  7074. {
  7075. if (pResult->bScopeItem == TRUE)
  7076. {
  7077. if (pResult->mask & RDI_STR)
  7078. {
  7079. if (pResult->nCol == 0)
  7080. {
  7081. if (pResult->lParam == 0)
  7082. {
  7083. pResult->str = m_pcd->m_szRootName;
  7084. }
  7085. else
  7086. {
  7087. TABLEENTRY * pTableEntry;
  7088. pTableEntry = (TABLEENTRY *)(pResult->lParam);
  7089. pResult->str = GETNAMEPTR(pTableEntry);
  7090. }
  7091. }
  7092. else
  7093. {
  7094. pResult->str = L"";
  7095. }
  7096. }
  7097. if (pResult->mask & RDI_IMAGE)
  7098. {
  7099. pResult->nImage = 0;
  7100. }
  7101. }
  7102. else
  7103. {
  7104. if (pResult->mask & RDI_STR)
  7105. {
  7106. TABLEENTRY * pTableEntry;
  7107. INT iState;
  7108. LPTSTR lpGPOName = NULL;
  7109. pTableEntry = (TABLEENTRY *)(pResult->lParam);
  7110. if (pTableEntry->dwType & ETYPE_REGITEM)
  7111. {
  7112. REGITEM *pItem = (REGITEM*)pTableEntry;
  7113. if (pResult->nCol == 0)
  7114. {
  7115. pResult->str = GETNAMEPTR(pTableEntry);
  7116. if (pResult->str == NULL)
  7117. {
  7118. pResult->str = (LPOLESTR)L"";
  7119. }
  7120. }
  7121. else if (pResult->nCol == 1)
  7122. {
  7123. pResult->str = GETVALUESTRPTR(pItem);
  7124. }
  7125. else if (pResult->nCol == 2)
  7126. {
  7127. pResult->str = pItem->lpItem->lpGPOName;
  7128. }
  7129. }
  7130. else
  7131. {
  7132. iState = GetPolicyState (pTableEntry, 1, &lpGPOName);
  7133. if (pResult->nCol == 0)
  7134. {
  7135. pResult->str = GETNAMEPTR(pTableEntry);
  7136. if (pResult->str == NULL)
  7137. {
  7138. pResult->str = (LPOLESTR)L"";
  7139. }
  7140. }
  7141. else if (pResult->nCol == 1)
  7142. {
  7143. if (iState == 1)
  7144. {
  7145. pResult->str = m_pEnabled;
  7146. }
  7147. else if (iState == 0)
  7148. {
  7149. pResult->str = m_pDisabled;
  7150. }
  7151. else
  7152. {
  7153. pResult->str = m_pNotConfigured;
  7154. }
  7155. }
  7156. else if (pResult->nCol == 2)
  7157. {
  7158. pResult->str = lpGPOName;
  7159. }
  7160. }
  7161. }
  7162. }
  7163. }
  7164. return S_OK;
  7165. }
  7166. STDMETHODIMP CPolicySnapIn::QueryDataObject(MMC_COOKIE cookie, DATA_OBJECT_TYPES type, LPDATAOBJECT *ppDataObject)
  7167. {
  7168. return m_pcd->QueryDataObject(cookie, type, ppDataObject);
  7169. }
  7170. STDMETHODIMP CPolicySnapIn::GetResultViewType(MMC_COOKIE cookie, LPOLESTR *ppViewType,
  7171. long *pViewOptions)
  7172. {
  7173. return S_FALSE;
  7174. }
  7175. STDMETHODIMP CPolicySnapIn::CompareObjects(LPDATAOBJECT lpDataObjectA, LPDATAOBJECT lpDataObjectB)
  7176. {
  7177. HRESULT hr = S_FALSE;
  7178. LPPOLICYDATAOBJECT pPolicyDataObjectA, pPolicyDataObjectB;
  7179. MMC_COOKIE cookie1, cookie2;
  7180. if (lpDataObjectA == NULL || lpDataObjectB == NULL)
  7181. return E_POINTER;
  7182. //
  7183. // QI for the private GPTDataObject interface
  7184. //
  7185. if (FAILED(lpDataObjectA->QueryInterface(IID_IPolicyDataObject,
  7186. (LPVOID *)&pPolicyDataObjectA)))
  7187. {
  7188. return S_FALSE;
  7189. }
  7190. if (FAILED(lpDataObjectB->QueryInterface(IID_IPolicyDataObject,
  7191. (LPVOID *)&pPolicyDataObjectB)))
  7192. {
  7193. pPolicyDataObjectA->Release();
  7194. return S_FALSE;
  7195. }
  7196. pPolicyDataObjectA->GetCookie(&cookie1);
  7197. pPolicyDataObjectB->GetCookie(&cookie2);
  7198. if (cookie1 == cookie2)
  7199. {
  7200. hr = S_OK;
  7201. }
  7202. pPolicyDataObjectA->Release();
  7203. pPolicyDataObjectB->Release();
  7204. return hr;
  7205. }
  7206. ///////////////////////////////////////////////////////////////////////////////
  7207. // //
  7208. // CPolicySnapIn:: object implementation (IExtendContextMenu) //
  7209. // //
  7210. ///////////////////////////////////////////////////////////////////////////////
  7211. STDMETHODIMP CPolicySnapIn::AddMenuItems(LPDATAOBJECT piDataObject,
  7212. LPCONTEXTMENUCALLBACK pCallback,
  7213. LONG *pInsertionAllowed)
  7214. {
  7215. HRESULT hr = S_OK;
  7216. TCHAR szMenuItem[100];
  7217. TCHAR szDescription[250];
  7218. CONTEXTMENUITEM item;
  7219. LPPOLICYDATAOBJECT pPolicyDataObject;
  7220. DATA_OBJECT_TYPES type = CCT_UNINITIALIZED;
  7221. MMC_COOKIE cookie;
  7222. POLICY *pPolicy;
  7223. if (SUCCEEDED(piDataObject->QueryInterface(IID_IPolicyDataObject,
  7224. (LPVOID *)&pPolicyDataObject)))
  7225. {
  7226. pPolicyDataObject->GetType(&type);
  7227. pPolicyDataObject->GetCookie(&cookie);
  7228. pPolicyDataObject->Release();
  7229. }
  7230. if (type == CCT_SCOPE)
  7231. {
  7232. pPolicy = (POLICY *)cookie;
  7233. if (*pInsertionAllowed & CCM_INSERTIONALLOWED_VIEW)
  7234. {
  7235. if (!m_pcd->m_bRSOP)
  7236. {
  7237. LoadString (g_hInstance, IDS_FILTERING, szMenuItem, 100);
  7238. LoadString (g_hInstance, IDS_FILTERINGDESC, szDescription, 250);
  7239. item.strName = szMenuItem;
  7240. item.strStatusBarText = szDescription;
  7241. item.lCommandID = IDM_FILTERING;
  7242. item.lInsertionPointID = CCM_INSERTIONPOINTID_PRIMARY_VIEW;
  7243. item.fFlags = 0;
  7244. item.fSpecialFlags = 0;
  7245. hr = pCallback->AddItem(&item);
  7246. }
  7247. }
  7248. }
  7249. return (hr);
  7250. }
  7251. STDMETHODIMP CPolicySnapIn::Command(LONG lCommandID, LPDATAOBJECT piDataObject)
  7252. {
  7253. if (lCommandID == IDM_FILTERING)
  7254. {
  7255. if (DialogBoxParam(g_hInstance,MAKEINTRESOURCE(IDD_POLICY_FILTERING),
  7256. m_pcd->m_hwndFrame, FilterDlgProc,(LPARAM) this))
  7257. {
  7258. //
  7259. // Refresh the display
  7260. //
  7261. m_pcd->m_pScope->DeleteItem (m_pcd->m_hSWPolicies, FALSE);
  7262. m_pcd->EnumerateScopePane (NULL, m_pcd->m_hSWPolicies);
  7263. }
  7264. }
  7265. return S_OK;
  7266. }
  7267. ///////////////////////////////////////////////////////////////////////////////
  7268. // //
  7269. // CPolicySnapIn object implementation (IExtendPropertySheet) //
  7270. // //
  7271. ///////////////////////////////////////////////////////////////////////////////
  7272. STDMETHODIMP CPolicySnapIn::CreatePropertyPages(LPPROPERTYSHEETCALLBACK lpProvider,
  7273. LONG_PTR handle, LPDATAOBJECT lpDataObject)
  7274. {
  7275. HRESULT hr;
  7276. PROPSHEETPAGE psp;
  7277. HPROPSHEETPAGE hPage[3];
  7278. LPPOLICYDATAOBJECT pPolicyDataObject;
  7279. MMC_COOKIE cookie;
  7280. LPSETTINGSINFO lpSettingsInfo;
  7281. //
  7282. // Make sure this is one of our objects
  7283. //
  7284. if (FAILED(lpDataObject->QueryInterface(IID_IPolicyDataObject,
  7285. (LPVOID *)&pPolicyDataObject)))
  7286. {
  7287. return S_OK;
  7288. }
  7289. //
  7290. // Get the cookie
  7291. //
  7292. pPolicyDataObject->GetCookie(&cookie);
  7293. pPolicyDataObject->Release();
  7294. m_pCurrentPolicy = (POLICY *)cookie;
  7295. //
  7296. // Allocate a settings info structure
  7297. //
  7298. lpSettingsInfo = (LPSETTINGSINFO) LocalAlloc(LPTR, sizeof(SETTINGSINFO));
  7299. if (!lpSettingsInfo)
  7300. {
  7301. DebugMsg((DM_WARNING, TEXT("CPolicySnapIn::CreatePropertyPages: Failed to allocate memory with %d."),
  7302. GetLastError()));
  7303. return S_OK;
  7304. }
  7305. lpSettingsInfo->pCS = this;
  7306. //
  7307. // Allocate a POLICYDLGINFO structure
  7308. //
  7309. lpSettingsInfo->pdi = (POLICYDLGINFO *) LocalAlloc(LPTR,sizeof(POLICYDLGINFO));
  7310. if (!lpSettingsInfo->pdi)
  7311. {
  7312. DebugMsg((DM_WARNING, TEXT("CPolicySnapIn::CreatePropertyPages: Failed to allocate memory with %d."),
  7313. GetLastError()));
  7314. LocalFree (lpSettingsInfo);
  7315. return S_OK;
  7316. }
  7317. //
  7318. // Initialize POLICYDLGINFO
  7319. //
  7320. lpSettingsInfo->pdi->dwControlTableSize = DEF_CONTROLS * sizeof(POLICYCTRLINFO);
  7321. lpSettingsInfo->pdi->nControls = 0;
  7322. lpSettingsInfo->pdi->pEntryRoot = (lpSettingsInfo->pCS->m_pcd->m_bUserScope ?
  7323. lpSettingsInfo->pCS->m_pcd->m_pUserCategoryList :
  7324. lpSettingsInfo->pCS->m_pcd->m_pMachineCategoryList);
  7325. lpSettingsInfo->pdi->hwndApp = lpSettingsInfo->pCS->m_pcd->m_hwndFrame;
  7326. lpSettingsInfo->pdi->pControlTable = (POLICYCTRLINFO *) LocalAlloc(LPTR,
  7327. lpSettingsInfo->pdi->dwControlTableSize);
  7328. if (!lpSettingsInfo->pdi->pControlTable) {
  7329. DebugMsg((DM_WARNING, TEXT("CPolicySnapIn::CreatePropertyPages: Failed to allocate memory with %d."),
  7330. GetLastError()));
  7331. LocalFree (lpSettingsInfo->pdi);
  7332. LocalFree (lpSettingsInfo);
  7333. return S_OK;
  7334. }
  7335. //
  7336. // Initialize the common fields in the property sheet structure
  7337. //
  7338. psp.dwSize = sizeof(PROPSHEETPAGE);
  7339. psp.dwFlags = 0;
  7340. psp.hInstance = g_hInstance;
  7341. psp.lParam = (LPARAM) lpSettingsInfo;
  7342. //
  7343. // Add the pages
  7344. //
  7345. if (m_pCurrentPolicy->dwType & ETYPE_REGITEM)
  7346. {
  7347. psp.pszTemplate = MAKEINTRESOURCE(IDD_POLICY_PRECEDENCE);
  7348. psp.pfnDlgProc = PolicyPrecedenceDlgProc;
  7349. hPage[0] = CreatePropertySheetPage(&psp);
  7350. if (hPage[0])
  7351. {
  7352. hr = lpProvider->AddPage(hPage[0]);
  7353. }
  7354. }
  7355. else
  7356. {
  7357. psp.pszTemplate = MAKEINTRESOURCE(IDD_POLICY);
  7358. psp.pfnDlgProc = PolicyDlgProc;
  7359. hPage[0] = CreatePropertySheetPage(&psp);
  7360. if (hPage[0])
  7361. {
  7362. hr = lpProvider->AddPage(hPage[0]);
  7363. psp.pszTemplate = MAKEINTRESOURCE(IDD_POLICY_HELP);
  7364. psp.pfnDlgProc = PolicyHelpDlgProc;
  7365. hPage[1] = CreatePropertySheetPage(&psp);
  7366. if (hPage[1])
  7367. {
  7368. hr = lpProvider->AddPage(hPage[1]);
  7369. if (m_pcd->m_bRSOP)
  7370. {
  7371. psp.pszTemplate = MAKEINTRESOURCE(IDD_POLICY_PRECEDENCE);
  7372. psp.pfnDlgProc = PolicyPrecedenceDlgProc;
  7373. hPage[2] = CreatePropertySheetPage(&psp);
  7374. if (hPage[2])
  7375. {
  7376. hr = lpProvider->AddPage(hPage[2]);
  7377. }
  7378. }
  7379. }
  7380. else
  7381. {
  7382. DebugMsg((DM_WARNING, TEXT("CPolicySnapIn::CreatePropertyPages: Failed to create property sheet page with %d."),
  7383. GetLastError()));
  7384. hr = E_FAIL;
  7385. }
  7386. }
  7387. else
  7388. {
  7389. DebugMsg((DM_WARNING, TEXT("CPolicySnapIn::CreatePropertyPages: Failed to create property sheet page with %d."),
  7390. GetLastError()));
  7391. hr = E_FAIL;
  7392. }
  7393. }
  7394. return (hr);
  7395. }
  7396. STDMETHODIMP CPolicySnapIn::QueryPagesFor(LPDATAOBJECT lpDataObject)
  7397. {
  7398. LPPOLICYDATAOBJECT pPolicyDataObject;
  7399. DATA_OBJECT_TYPES type;
  7400. if (SUCCEEDED(lpDataObject->QueryInterface(IID_IPolicyDataObject,
  7401. (LPVOID *)&pPolicyDataObject)))
  7402. {
  7403. pPolicyDataObject->GetType(&type);
  7404. pPolicyDataObject->Release();
  7405. if (type == CCT_RESULT)
  7406. {
  7407. if (!m_hPropDlg)
  7408. return S_OK;
  7409. // There's already a propety sheet open so we'll bring it to the front.
  7410. BringWindowToTop(GetParent(m_hPropDlg));
  7411. }
  7412. }
  7413. return S_FALSE;
  7414. }
  7415. ///////////////////////////////////////////////////////////////////////////////
  7416. // //
  7417. // CPolicySnapIn object implementation (Internal functions) //
  7418. // //
  7419. ///////////////////////////////////////////////////////////////////////////////
  7420. BOOL CPolicySnapIn::IsAnyPolicyEnabled(TABLEENTRY * pCategory)
  7421. {
  7422. TABLEENTRY * pEntry;
  7423. INT iState;
  7424. if (!pCategory || !pCategory->pChild)
  7425. {
  7426. return FALSE;
  7427. }
  7428. pEntry = pCategory->pChild;
  7429. while (pEntry)
  7430. {
  7431. if (pEntry->dwType & ETYPE_CATEGORY)
  7432. {
  7433. if (IsAnyPolicyEnabled(pEntry))
  7434. {
  7435. return TRUE;
  7436. }
  7437. }
  7438. else if (pEntry->dwType & ETYPE_POLICY)
  7439. {
  7440. iState = GetPolicyState(pEntry, 1, NULL);
  7441. if ((iState == 1) || (iState == 0))
  7442. {
  7443. return TRUE;
  7444. }
  7445. }
  7446. pEntry = pEntry->pNext;
  7447. }
  7448. return FALSE;
  7449. }
  7450. VOID CPolicySnapIn::RefreshSettingsControls(HWND hDlg)
  7451. {
  7452. BOOL fEnabled = FALSE;
  7453. INT iState;
  7454. LPTSTR lpSupported;
  7455. POLICY *pPolicy = (POLICY *)m_pCurrentPolicy;
  7456. FreeSettingsControls(hDlg);
  7457. SetDlgItemText (hDlg, IDC_POLICY, GETNAMEPTR(m_pCurrentPolicy));
  7458. if (pPolicy->bTruePolicy)
  7459. {
  7460. SendMessage (GetDlgItem(hDlg, IDC_POLICYICON), STM_SETIMAGE, IMAGE_ICON,
  7461. (LPARAM) (HANDLE) m_hPolicyIcon);
  7462. }
  7463. else
  7464. {
  7465. SendMessage (GetDlgItem(hDlg, IDC_POLICYICON), STM_SETIMAGE, IMAGE_ICON,
  7466. (LPARAM) (HANDLE) m_hPreferenceIcon);
  7467. }
  7468. lpSupported = GETSUPPORTEDPTR(pPolicy);
  7469. if (lpSupported)
  7470. {
  7471. ShowWindow (GetDlgItem(hDlg, IDC_SUPPORTEDTITLE), SW_SHOW);
  7472. ShowWindow (GetDlgItem(hDlg, IDC_SUPPORTED), SW_SHOW);
  7473. SetDlgItemText (hDlg, IDC_SUPPORTED, lpSupported);
  7474. }
  7475. else
  7476. {
  7477. SetDlgItemText (hDlg, IDC_SUPPORTED, TEXT(""));
  7478. ShowWindow (GetDlgItem(hDlg, IDC_SUPPORTEDTITLE), SW_HIDE);
  7479. ShowWindow (GetDlgItem(hDlg, IDC_SUPPORTED), SW_HIDE);
  7480. }
  7481. iState = GetPolicyState((TABLEENTRY *)m_pCurrentPolicy, 1, NULL);
  7482. if (iState == 1)
  7483. {
  7484. CheckRadioButton(hDlg, IDC_NOCONFIG, IDC_DISABLED, IDC_ENABLED);
  7485. fEnabled = TRUE;
  7486. }
  7487. else if (iState == 0)
  7488. {
  7489. CheckRadioButton(hDlg, IDC_NOCONFIG, IDC_DISABLED, IDC_DISABLED);
  7490. }
  7491. else
  7492. {
  7493. CheckRadioButton(hDlg, IDC_NOCONFIG, IDC_DISABLED, IDC_NOCONFIG);
  7494. }
  7495. if (m_pcd->m_bRSOP)
  7496. {
  7497. EnableWindow (GetDlgItem(hDlg, IDC_ENABLED), FALSE);
  7498. EnableWindow (GetDlgItem(hDlg, IDC_DISABLED), FALSE);
  7499. EnableWindow (GetDlgItem(hDlg, IDC_NOCONFIG), FALSE);
  7500. }
  7501. if (m_pCurrentPolicy->pChild) {
  7502. CreateSettingsControls(hDlg, (SETTINGS *) m_pCurrentPolicy->pChild, fEnabled);
  7503. InitializeSettingsControls(hDlg, fEnabled);
  7504. } else {
  7505. ShowScrollBar(GetDlgItem(hDlg,IDC_POLICY_SETTINGS),SB_BOTH, FALSE);
  7506. }
  7507. m_bDirty = FALSE;
  7508. PostMessage (GetParent(hDlg), PSM_UNCHANGED, (WPARAM) hDlg, 0);
  7509. SetPrevNextButtonState(hDlg);
  7510. }
  7511. HRESULT CPolicySnapIn::UpdateItemWorker (VOID)
  7512. {
  7513. HRESULTITEM hItem;
  7514. //
  7515. // Update the display
  7516. //
  7517. if (SUCCEEDED(m_pResult->FindItemByLParam((LPARAM)m_pCurrentPolicy, &hItem)))
  7518. {
  7519. if (m_pcd->m_bShowConfigPoliciesOnly)
  7520. m_pResult->DeleteItem(hItem, 0);
  7521. else
  7522. m_pResult->UpdateItem(hItem);
  7523. }
  7524. return S_OK;
  7525. }
  7526. HRESULT CPolicySnapIn::MoveFocusWorker (BOOL bPrevious)
  7527. {
  7528. HRESULTITEM hItem;
  7529. TABLEENTRY * pTemp;
  7530. HRESULT hr;
  7531. RESULTDATAITEM item;
  7532. INT iIndex = 0;
  7533. //
  7534. // Find the currently selected item's index
  7535. //
  7536. while (TRUE)
  7537. {
  7538. ZeroMemory (&item, sizeof(item));
  7539. item.mask = RDI_INDEX | RDI_PARAM;
  7540. item.nIndex = iIndex;
  7541. hr = m_pResult->GetItem (&item);
  7542. if (FAILED(hr))
  7543. {
  7544. return hr;
  7545. }
  7546. if (item.lParam == (LPARAM) m_pCurrentPolicy)
  7547. {
  7548. break;
  7549. }
  7550. iIndex++;
  7551. }
  7552. //
  7553. // Find the currently selected item's hItem
  7554. //
  7555. hr = m_pResult->FindItemByLParam((LPARAM)m_pCurrentPolicy, &hItem);
  7556. if (FAILED(hr))
  7557. {
  7558. return hr;
  7559. }
  7560. //
  7561. // Remove the focus from the original item
  7562. //
  7563. m_pResult->ModifyItemState(0, hItem, 0, LVIS_FOCUSED | LVIS_SELECTED);
  7564. m_pResult->UpdateItem(hItem);
  7565. //
  7566. // Adjust appropriately
  7567. //
  7568. if (bPrevious)
  7569. {
  7570. if (iIndex > 0)
  7571. {
  7572. iIndex--;
  7573. }
  7574. }
  7575. else
  7576. {
  7577. iIndex++;
  7578. }
  7579. //
  7580. // Get the lParam for the new item
  7581. //
  7582. ZeroMemory (&item, sizeof(item));
  7583. item.mask = RDI_INDEX | RDI_PARAM;
  7584. item.nIndex = iIndex;
  7585. hr = m_pResult->GetItem(&item);
  7586. if (FAILED(hr))
  7587. {
  7588. return hr;
  7589. }
  7590. //
  7591. // Find the hItem for the new item
  7592. //
  7593. hr = m_pResult->FindItemByLParam(item.lParam, &hItem);
  7594. if (FAILED(hr))
  7595. {
  7596. return hr;
  7597. }
  7598. //
  7599. // Save this as the currently selected item
  7600. //
  7601. m_pCurrentPolicy = (POLICY *)item.lParam;
  7602. //
  7603. // Set the focus on the new item
  7604. //
  7605. m_pResult->ModifyItemState(0, hItem, LVIS_FOCUSED | LVIS_SELECTED, 0);
  7606. m_pResult->UpdateItem(hItem);
  7607. return S_OK;
  7608. }
  7609. HRESULT CPolicySnapIn::MoveFocus (HWND hDlg, BOOL bPrevious)
  7610. {
  7611. //
  7612. // Send the move focus message to the hidden window on the main
  7613. // thread so it can use the mmc interfaces
  7614. //
  7615. SendMessage (m_hMsgWindow, WM_MOVEFOCUS, (WPARAM) bPrevious, 0);
  7616. //
  7617. // Update the display
  7618. //
  7619. SendMessage (GetParent(hDlg), PSM_QUERYSIBLINGS, 1000, 0);
  7620. return S_OK;
  7621. }
  7622. HRESULT CPolicySnapIn::SetPrevNextButtonStateWorker (HWND hDlg)
  7623. {
  7624. TABLEENTRY * pTemp;
  7625. HRESULT hr;
  7626. RESULTDATAITEM item;
  7627. INT iIndex = 0;
  7628. BOOL bPrev = FALSE, bNext = FALSE, bFound = FALSE;
  7629. //
  7630. // Loop through the items looking for Policies
  7631. //
  7632. while (TRUE)
  7633. {
  7634. ZeroMemory (&item, sizeof(item));
  7635. item.mask = RDI_INDEX | RDI_PARAM;
  7636. item.nIndex = iIndex;
  7637. hr = m_pResult->GetItem (&item);
  7638. if (FAILED(hr))
  7639. {
  7640. break;
  7641. }
  7642. if (item.lParam == (LPARAM) m_pCurrentPolicy)
  7643. {
  7644. bFound = TRUE;
  7645. }
  7646. else
  7647. {
  7648. pTemp = (TABLEENTRY *) item.lParam;
  7649. if ((pTemp->dwType & ETYPE_POLICY) || (pTemp->dwType & ETYPE_REGITEM))
  7650. {
  7651. if ((m_pcd->m_bShowConfigPoliciesOnly) && (pTemp->dwType & ETYPE_POLICY))
  7652. {
  7653. INT iState;
  7654. iState = GetPolicyState(pTemp, 1, NULL);
  7655. if ((iState == 1) || (iState == 0))
  7656. {
  7657. if (bFound)
  7658. {
  7659. bNext = TRUE;
  7660. }
  7661. else
  7662. {
  7663. bPrev = TRUE;
  7664. }
  7665. }
  7666. }
  7667. else
  7668. {
  7669. if (bFound)
  7670. {
  7671. bNext = TRUE;
  7672. }
  7673. else
  7674. {
  7675. bPrev = TRUE;
  7676. }
  7677. }
  7678. }
  7679. }
  7680. iIndex++;
  7681. }
  7682. if (!bNext && (GetFocus() == GetDlgItem(hDlg,IDC_POLICY_NEXT)))
  7683. {
  7684. SetFocus (GetNextDlgTabItem(hDlg, GetDlgItem(hDlg,IDC_POLICY_NEXT), TRUE));
  7685. }
  7686. EnableWindow (GetDlgItem(hDlg,IDC_POLICY_NEXT), bNext);
  7687. if (!bPrev && (GetFocus() == GetDlgItem(hDlg,IDC_POLICY_PREVIOUS)))
  7688. {
  7689. SetFocus (GetNextDlgTabItem(hDlg, GetDlgItem(hDlg,IDC_POLICY_PREVIOUS), FALSE));
  7690. }
  7691. EnableWindow (GetDlgItem(hDlg,IDC_POLICY_PREVIOUS), bPrev);
  7692. return S_OK;
  7693. }
  7694. HRESULT CPolicySnapIn::SetPrevNextButtonState (HWND hDlg)
  7695. {
  7696. //
  7697. // Send the SetPrevNext message to the hidden window on the main
  7698. // thread so it can use the mmc interfaces
  7699. //
  7700. SendMessage (m_hMsgWindow, WM_SETPREVNEXT, (WPARAM) hDlg, 0);
  7701. return S_OK;
  7702. }
  7703. INT_PTR CALLBACK CPolicySnapIn::PolicyDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  7704. {
  7705. LPSETTINGSINFO lpSettingsInfo;
  7706. switch (message)
  7707. {
  7708. case WM_INITDIALOG:
  7709. lpSettingsInfo = (LPSETTINGSINFO) (((LPPROPSHEETPAGE)lParam)->lParam);
  7710. if (!lpSettingsInfo) {
  7711. break;
  7712. }
  7713. SetWindowLongPtr (hDlg, DWLP_USER, (LONG_PTR) lpSettingsInfo);
  7714. lpSettingsInfo->pCS->m_hPropDlg = hDlg;
  7715. lpSettingsInfo->pdi->fActive=TRUE;
  7716. lpSettingsInfo->pCS->m_hPolicyIcon = (HICON) LoadImage (g_hInstance,
  7717. MAKEINTRESOURCE(IDI_POLICY2),
  7718. IMAGE_ICON, 16, 16,
  7719. LR_DEFAULTCOLOR);
  7720. lpSettingsInfo->pCS->m_hPreferenceIcon = (HICON) LoadImage (g_hInstance,
  7721. MAKEINTRESOURCE(IDI_POLICY3),
  7722. IMAGE_ICON, 16, 16,
  7723. LR_DEFAULTCOLOR);
  7724. // now that we've stored pointer to POLICYDLGINFO struct in our extra
  7725. // window data, send WM_USER to clip window to tell it to create a
  7726. // child container window (and store the handle in our POLICYDLGINFO)
  7727. SendDlgItemMessage(hDlg,IDC_POLICY_SETTINGS,WM_USER,0,0L);
  7728. lpSettingsInfo->pCS->RefreshSettingsControls(hDlg);
  7729. lpSettingsInfo->pCS->SetKeyboardHook(hDlg);
  7730. break;
  7731. case WM_MYCHANGENOTIFY:
  7732. lpSettingsInfo = (LPSETTINGSINFO) GetWindowLongPtr (hDlg, DWLP_USER);
  7733. if (lpSettingsInfo) {
  7734. lpSettingsInfo->pCS->m_bDirty = TRUE;
  7735. SendMessage (GetParent(hDlg), PSM_CHANGED, (WPARAM) hDlg, 0);
  7736. }
  7737. break;
  7738. case PSM_QUERYSIBLINGS:
  7739. if (wParam == 1000) {
  7740. lpSettingsInfo = (LPSETTINGSINFO) GetWindowLongPtr (hDlg, DWLP_USER);
  7741. if (!lpSettingsInfo) {
  7742. break;
  7743. }
  7744. lpSettingsInfo->pCS->RefreshSettingsControls(hDlg);
  7745. SendMessage (GetParent(hDlg), PSM_SETTITLE, PSH_PROPTITLE,
  7746. (LPARAM)GETNAMEPTR(lpSettingsInfo->pCS->m_pCurrentPolicy));
  7747. }
  7748. break;
  7749. case WM_COMMAND:
  7750. lpSettingsInfo = (LPSETTINGSINFO) GetWindowLongPtr (hDlg, DWLP_USER);
  7751. if (!lpSettingsInfo) {
  7752. break;
  7753. }
  7754. if ((LOWORD (wParam) == IDC_NOCONFIG) && (HIWORD (wParam) == BN_CLICKED))
  7755. {
  7756. lpSettingsInfo->pCS->InitializeSettingsControls(hDlg, FALSE);
  7757. PostMessage (hDlg, WM_MYCHANGENOTIFY, 0, 0);
  7758. }
  7759. if ((LOWORD (wParam) == IDC_ENABLED) && (HIWORD (wParam) == BN_CLICKED))
  7760. {
  7761. lpSettingsInfo->pCS->InitializeSettingsControls(hDlg, TRUE);
  7762. PostMessage (hDlg, WM_MYCHANGENOTIFY, 0, 0);
  7763. }
  7764. if ((LOWORD (wParam) == IDC_DISABLED) && (HIWORD (wParam) == BN_CLICKED))
  7765. {
  7766. lpSettingsInfo->pCS->InitializeSettingsControls(hDlg, FALSE);
  7767. PostMessage (hDlg, WM_MYCHANGENOTIFY, 0, 0);
  7768. }
  7769. if (LOWORD(wParam) == IDC_POLICY_NEXT)
  7770. {
  7771. if (SUCCEEDED(lpSettingsInfo->pCS->SaveSettings(hDlg)))
  7772. {
  7773. lpSettingsInfo->pCS->MoveFocus (hDlg, FALSE);
  7774. }
  7775. }
  7776. if (LOWORD(wParam) == IDC_POLICY_PREVIOUS)
  7777. {
  7778. if (SUCCEEDED(lpSettingsInfo->pCS->SaveSettings(hDlg)))
  7779. {
  7780. lpSettingsInfo->pCS->MoveFocus (hDlg, TRUE);
  7781. }
  7782. }
  7783. break;
  7784. case WM_NOTIFY:
  7785. lpSettingsInfo = (LPSETTINGSINFO) GetWindowLongPtr (hDlg, DWLP_USER);
  7786. if (!lpSettingsInfo) {
  7787. break;
  7788. }
  7789. switch (((NMHDR FAR*)lParam)->code)
  7790. {
  7791. case PSN_APPLY:
  7792. {
  7793. LPPSHNOTIFY lpNotify = (LPPSHNOTIFY) lParam;
  7794. if (FAILED(lpSettingsInfo->pCS->SaveSettings(hDlg)))
  7795. {
  7796. SetWindowLongPtr (hDlg, DWLP_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE);
  7797. return TRUE;
  7798. }
  7799. if (lpNotify->lParam)
  7800. {
  7801. lpSettingsInfo->pCS->RemoveKeyboardHook();
  7802. lpSettingsInfo->pCS->m_hPropDlg = NULL;
  7803. lpSettingsInfo->pCS->FreeSettingsControls(hDlg);
  7804. DestroyIcon(lpSettingsInfo->pCS->m_hPolicyIcon);
  7805. lpSettingsInfo->pCS->m_hPolicyIcon = NULL;
  7806. DestroyIcon(lpSettingsInfo->pCS->m_hPreferenceIcon);
  7807. lpSettingsInfo->pCS->m_hPreferenceIcon = NULL;
  7808. LocalFree (lpSettingsInfo->pdi->pControlTable);
  7809. LocalFree (lpSettingsInfo->pdi);
  7810. LocalFree (lpSettingsInfo);
  7811. SetWindowLongPtr (hDlg, DWLP_USER, (LONG_PTR) NULL);
  7812. }
  7813. SetWindowLongPtr (hDlg, DWLP_MSGRESULT, PSNRET_NOERROR);
  7814. return TRUE;
  7815. }
  7816. case PSN_RESET:
  7817. lpSettingsInfo->pCS->RemoveKeyboardHook();
  7818. lpSettingsInfo->pCS->m_hPropDlg = NULL;
  7819. SetWindowLongPtr (hDlg, DWLP_MSGRESULT, PSNRET_NOERROR);
  7820. return TRUE;
  7821. }
  7822. break;
  7823. case WM_HELP: // F1
  7824. WinHelp((HWND)((LPHELPINFO) lParam)->hItemHandle, HELP_FILE, HELP_WM_HELP,
  7825. (DWORD_PTR) (LPDWORD) aPolicyHelpIds);
  7826. return TRUE;
  7827. case WM_CONTEXTMENU: // right mouse click
  7828. WinHelp((HWND) wParam, HELP_FILE, HELP_CONTEXTMENU,
  7829. (DWORD_PTR) (LPDWORD) aPolicyHelpIds);
  7830. return TRUE;
  7831. }
  7832. return FALSE;
  7833. }
  7834. INT_PTR CALLBACK CPolicySnapIn::PolicyHelpDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  7835. {
  7836. LPSETTINGSINFO lpSettingsInfo;
  7837. switch (message)
  7838. {
  7839. case WM_INITDIALOG:
  7840. lpSettingsInfo = (LPSETTINGSINFO) (((LPPROPSHEETPAGE)lParam)->lParam);
  7841. if (!lpSettingsInfo) {
  7842. break;
  7843. }
  7844. SetWindowLongPtr (hDlg, DWLP_USER, (LONG_PTR) lpSettingsInfo);
  7845. wParam = 1000;
  7846. // fall through...
  7847. case PSM_QUERYSIBLINGS:
  7848. {
  7849. CPolicySnapIn * pCS;
  7850. LPTSTR lpHelpText;
  7851. if (wParam == 1000)
  7852. {
  7853. lpSettingsInfo = (LPSETTINGSINFO) GetWindowLongPtr (hDlg, DWLP_USER);
  7854. if (!lpSettingsInfo) {
  7855. break;
  7856. }
  7857. pCS = lpSettingsInfo->pCS;
  7858. SetDlgItemText (hDlg, IDC_POLICY_TITLE, GETNAMEPTR(pCS->m_pCurrentPolicy));
  7859. if (pCS->m_pCurrentPolicy->uOffsetHelp)
  7860. {
  7861. lpHelpText = (LPTSTR) ((BYTE *) pCS->m_pCurrentPolicy + pCS->m_pCurrentPolicy->uOffsetHelp);
  7862. SetDlgItemText (hDlg, IDC_POLICY_HELP, lpHelpText);
  7863. }
  7864. else
  7865. {
  7866. SetDlgItemText (hDlg, IDC_POLICY_HELP, TEXT(""));
  7867. }
  7868. pCS->SetPrevNextButtonState(hDlg);
  7869. }
  7870. PostMessage(hDlg, WM_MYREFRESH, 0, 0);
  7871. break;
  7872. }
  7873. case WM_MYREFRESH:
  7874. {
  7875. CPolicySnapIn * pCS;
  7876. BOOL bAlone;
  7877. lpSettingsInfo = (LPSETTINGSINFO) GetWindowLongPtr (hDlg, DWLP_USER);
  7878. pCS = lpSettingsInfo->pCS;
  7879. SendMessage(GetDlgItem(hDlg, IDC_POLICY_HELP), EM_SETSEL, -1, 0);
  7880. bAlone = !(((pCS->m_pCurrentPolicy)->pNext) ||
  7881. ((pCS->m_pCurrentPolicy)->pPrev) );
  7882. if (bAlone) {
  7883. SetFocus(GetDlgItem(GetParent(hDlg), IDOK));
  7884. }
  7885. break;
  7886. }
  7887. case WM_COMMAND:
  7888. lpSettingsInfo = (LPSETTINGSINFO) GetWindowLongPtr (hDlg, DWLP_USER);
  7889. if (!lpSettingsInfo) {
  7890. break;
  7891. }
  7892. if (LOWORD(wParam) == IDC_POLICY_NEXT)
  7893. {
  7894. lpSettingsInfo->pCS->MoveFocus (hDlg, FALSE);
  7895. }
  7896. if (LOWORD(wParam) == IDC_POLICY_PREVIOUS)
  7897. {
  7898. lpSettingsInfo->pCS->MoveFocus (hDlg, TRUE);
  7899. }
  7900. if (LOWORD(wParam) == IDCANCEL)
  7901. {
  7902. SendMessage(GetParent(hDlg), message, wParam, lParam);
  7903. }
  7904. break;
  7905. case WM_NOTIFY:
  7906. switch (((NMHDR FAR*)lParam)->code)
  7907. {
  7908. case PSN_APPLY:
  7909. case PSN_RESET:
  7910. SetWindowLongPtr (hDlg, DWLP_MSGRESULT, PSNRET_NOERROR);
  7911. return TRUE;
  7912. case PSN_SETACTIVE:
  7913. PostMessage(hDlg, WM_MYREFRESH, 0, 0);
  7914. break;
  7915. }
  7916. break;
  7917. case WM_HELP: // F1
  7918. WinHelp((HWND)((LPHELPINFO) lParam)->hItemHandle, HELP_FILE, HELP_WM_HELP,
  7919. (DWORD_PTR) (LPDWORD) aExplainHelpIds);
  7920. return TRUE;
  7921. case WM_CONTEXTMENU: // right mouse click
  7922. WinHelp((HWND) wParam, HELP_FILE, HELP_CONTEXTMENU,
  7923. (DWORD_PTR) (LPDWORD) aExplainHelpIds);
  7924. return TRUE;
  7925. }
  7926. return FALSE;
  7927. }
  7928. INT_PTR CALLBACK CPolicySnapIn::PolicyPrecedenceDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  7929. {
  7930. LPSETTINGSINFO lpSettingsInfo;
  7931. HRESULT hr = S_OK;
  7932. switch (message)
  7933. {
  7934. case WM_INITDIALOG:
  7935. {
  7936. RECT rc;
  7937. TCHAR szHeaderName[50];
  7938. INT iTotal = 0, iCurrent;
  7939. HWND hLV = GetDlgItem (hDlg, IDC_POLICY_PRECEDENCE);
  7940. LV_COLUMN col;
  7941. lpSettingsInfo = (LPSETTINGSINFO) (((LPPROPSHEETPAGE)lParam)->lParam);
  7942. if (!lpSettingsInfo) {
  7943. break;
  7944. }
  7945. SetWindowLongPtr (hDlg, DWLP_USER, (LONG_PTR) lpSettingsInfo);
  7946. //
  7947. // Add the columns
  7948. //
  7949. GetClientRect (hLV, &rc);
  7950. LoadString(g_hInstance, IDS_GPONAME, szHeaderName, ARRAYSIZE(szHeaderName));
  7951. col.mask = LVCF_FMT | LVCF_TEXT | LVCF_SUBITEM | LVCF_WIDTH;
  7952. col.fmt = LVCFMT_LEFT;
  7953. iCurrent = (int)(rc.right * .70);
  7954. iTotal += iCurrent;
  7955. col.cx = iCurrent;
  7956. col.pszText = szHeaderName;
  7957. col.iSubItem = 0;
  7958. ListView_InsertColumn (hLV, 0, &col);
  7959. LoadString(g_hInstance, IDS_SETTING, szHeaderName, ARRAYSIZE(szHeaderName));
  7960. col.iSubItem = 1;
  7961. col.cx = rc.right - iTotal;
  7962. col.fmt = LVCFMT_CENTER;
  7963. ListView_InsertColumn (hLV, 1, &col);
  7964. //
  7965. // Set extended LV styles
  7966. //
  7967. SendMessage(hLV, LVM_SETEXTENDEDLISTVIEWSTYLE, 0,
  7968. LVS_EX_FULLROWSELECT | LVS_EX_LABELTIP);
  7969. }
  7970. wParam = 1000;
  7971. // fall through...
  7972. case PSM_QUERYSIBLINGS:
  7973. {
  7974. CPolicySnapIn * pCS;
  7975. INT iState;
  7976. LPTSTR lpGPOName;
  7977. UINT uiPrecedence = 1;
  7978. LVITEM item;
  7979. INT iItem, iIndex = 0;
  7980. HWND hLV = GetDlgItem (hDlg, IDC_POLICY_PRECEDENCE);
  7981. if (wParam == 1000)
  7982. {
  7983. lpSettingsInfo = (LPSETTINGSINFO) GetWindowLongPtr (hDlg, DWLP_USER);
  7984. if (!lpSettingsInfo) {
  7985. break;
  7986. }
  7987. pCS = lpSettingsInfo->pCS;
  7988. SetDlgItemText (hDlg, IDC_POLICY_TITLE, GETNAMEPTR(pCS->m_pCurrentPolicy));
  7989. SendMessage (hLV, LVM_DELETEALLITEMS, 0, 0);
  7990. if (pCS->m_pCurrentPolicy->dwType & ETYPE_REGITEM)
  7991. {
  7992. LPRSOPREGITEM pItem = ((REGITEM*)pCS->m_pCurrentPolicy)->lpItem;
  7993. LPRSOPREGITEM lpEnum;
  7994. TCHAR szValueStr[MAX_PATH];
  7995. while (TRUE)
  7996. {
  7997. lpEnum = NULL;
  7998. if (pCS->m_pcd->FindRSOPRegistryEntry((HKEY) LongToHandle(uiPrecedence), pItem->lpKeyName,
  7999. pItem->lpValueName, &lpEnum) != ERROR_SUCCESS)
  8000. {
  8001. break;
  8002. }
  8003. //
  8004. // Add the GPO Name
  8005. //
  8006. item.mask = LVIF_TEXT | LVIF_STATE;
  8007. item.iItem = iIndex;
  8008. item.iSubItem = 0;
  8009. item.state = 0;
  8010. item.stateMask = LVIS_SELECTED | LVIS_FOCUSED;
  8011. item.pszText = lpEnum->lpGPOName;
  8012. iItem = (INT)SendMessage (hLV, LVM_INSERTITEM, 0, (LPARAM) &item);
  8013. if (iItem != -1)
  8014. {
  8015. szValueStr[0] = TEXT('\0');
  8016. if (pItem->dwType == REG_DWORD)
  8017. {
  8018. hr = StringCchPrintf (szValueStr, ARRAYSIZE(szValueStr), TEXT("%d"), *((LPDWORD)pItem->lpData));
  8019. ASSERT(SUCCEEDED(hr));
  8020. }
  8021. else if (pItem->dwType == REG_SZ)
  8022. {
  8023. lstrcpyn (szValueStr, (LPTSTR)pItem->lpData, ARRAYSIZE(szValueStr));
  8024. }
  8025. else if (pItem->dwType == REG_EXPAND_SZ)
  8026. {
  8027. lstrcpyn (szValueStr, (LPTSTR)pItem->lpData, ARRAYSIZE(szValueStr));
  8028. }
  8029. else if (pItem->dwType == REG_BINARY)
  8030. {
  8031. LoadString(g_hInstance, IDS_BINARYDATA, szValueStr, ARRAYSIZE(szValueStr));
  8032. }
  8033. else
  8034. {
  8035. LoadString(g_hInstance, IDS_UNKNOWNDATA, szValueStr, ARRAYSIZE(szValueStr));
  8036. }
  8037. //
  8038. // Add the state
  8039. //
  8040. item.mask = LVIF_TEXT;
  8041. item.iItem = iItem;
  8042. item.iSubItem = 1;
  8043. item.pszText = szValueStr;
  8044. SendMessage (hLV, LVM_SETITEMTEXT, iItem, (LPARAM) &item);
  8045. }
  8046. uiPrecedence++;
  8047. iIndex++;
  8048. }
  8049. }
  8050. else
  8051. {
  8052. while (TRUE)
  8053. {
  8054. lpGPOName = NULL; // just in case we have missed a case
  8055. iState = pCS->GetPolicyState ((TABLEENTRY *)pCS->m_pCurrentPolicy, uiPrecedence, &lpGPOName);
  8056. if (iState == -1)
  8057. {
  8058. uiPrecedence++;
  8059. iState = pCS->GetPolicyState ((TABLEENTRY *)pCS->m_pCurrentPolicy, uiPrecedence, &lpGPOName);
  8060. if (iState == -1)
  8061. {
  8062. break;
  8063. }
  8064. }
  8065. //
  8066. // Add the GPO Name
  8067. //
  8068. item.mask = LVIF_TEXT | LVIF_STATE;
  8069. item.iItem = iIndex;
  8070. item.iSubItem = 0;
  8071. item.state = 0;
  8072. item.stateMask = LVIS_SELECTED | LVIS_FOCUSED;
  8073. item.pszText = lpGPOName ? lpGPOName : TEXT("");
  8074. iItem = (INT)SendMessage (hLV, LVM_INSERTITEM, 0, (LPARAM) &item);
  8075. if (iItem != -1)
  8076. {
  8077. //
  8078. // Add the state
  8079. //
  8080. item.mask = LVIF_TEXT;
  8081. item.iItem = iItem;
  8082. item.iSubItem = 1;
  8083. item.pszText = (iState == 1) ? pCS->m_pEnabled : pCS->m_pDisabled;
  8084. SendMessage (hLV, LVM_SETITEMTEXT, iItem, (LPARAM) &item);
  8085. }
  8086. uiPrecedence++;
  8087. iIndex++;
  8088. }
  8089. }
  8090. //
  8091. // Select the first item
  8092. //
  8093. item.mask = LVIF_STATE;
  8094. item.iItem = 0;
  8095. item.iSubItem = 0;
  8096. item.state = LVIS_SELECTED | LVIS_FOCUSED;
  8097. item.stateMask = LVIS_SELECTED | LVIS_FOCUSED;
  8098. SendMessage (hLV, LVM_SETITEMSTATE, 0, (LPARAM) &item);
  8099. pCS->SetPrevNextButtonState(hDlg);
  8100. }
  8101. break;
  8102. }
  8103. case WM_COMMAND:
  8104. lpSettingsInfo = (LPSETTINGSINFO) GetWindowLongPtr (hDlg, DWLP_USER);
  8105. if (!lpSettingsInfo) {
  8106. break;
  8107. }
  8108. if (LOWORD(wParam) == IDC_POLICY_NEXT)
  8109. {
  8110. lpSettingsInfo->pCS->MoveFocus (hDlg, FALSE);
  8111. }
  8112. if (LOWORD(wParam) == IDC_POLICY_PREVIOUS)
  8113. {
  8114. lpSettingsInfo->pCS->MoveFocus (hDlg, TRUE);
  8115. }
  8116. break;
  8117. case WM_NOTIFY:
  8118. switch (((NMHDR FAR*)lParam)->code)
  8119. {
  8120. case PSN_APPLY:
  8121. case PSN_RESET:
  8122. SetWindowLongPtr (hDlg, DWLP_MSGRESULT, PSNRET_NOERROR);
  8123. return TRUE;
  8124. }
  8125. break;
  8126. case WM_HELP: // F1
  8127. WinHelp((HWND)((LPHELPINFO) lParam)->hItemHandle, RSOP_HELP_FILE, HELP_WM_HELP,
  8128. (DWORD_PTR) (LPDWORD) aPrecedenceHelpIds);
  8129. return TRUE;
  8130. case WM_CONTEXTMENU: // right mouse click
  8131. WinHelp((HWND) wParam, RSOP_HELP_FILE, HELP_CONTEXTMENU,
  8132. (DWORD_PTR) (LPDWORD) aPrecedenceHelpIds);
  8133. return TRUE;
  8134. }
  8135. return FALSE;
  8136. }
  8137. LRESULT CPolicySnapIn::CallNextHook(int nCode, WPARAM wParam,LPARAM lParam)
  8138. {
  8139. if (m_hKbdHook)
  8140. {
  8141. return CallNextHookEx(
  8142. m_hKbdHook,
  8143. nCode,
  8144. wParam,
  8145. lParam);
  8146. }
  8147. else
  8148. {
  8149. DebugMsg((DM_WARNING, L"CPolicySnapIn::CallNextHook m_hKbdHook is Null"));
  8150. return 0;
  8151. }
  8152. }
  8153. HWND g_hDlgActive = NULL;
  8154. LRESULT CALLBACK CPolicySnapIn::KeyboardHookProc(int nCode, WPARAM wParam,LPARAM lParam)
  8155. {
  8156. LPSETTINGSINFO lpSettingsInfo;
  8157. lpSettingsInfo = (LPSETTINGSINFO) GetWindowLongPtr(g_hDlgActive, DWLP_USER);
  8158. if (!lpSettingsInfo)
  8159. {
  8160. DebugMsg((DM_WARNING, L"CPolicySnapIn::KeyboardHookProc:GetWindowLongPtr returned NULL"));
  8161. return 0;
  8162. }
  8163. if ( nCode < 0)
  8164. {
  8165. if (lpSettingsInfo->pCS)
  8166. {
  8167. return lpSettingsInfo->pCS->CallNextHook(nCode,
  8168. wParam,
  8169. lParam);
  8170. }
  8171. else
  8172. {
  8173. DebugMsg((DM_WARNING, L"CPolicySnapIn::KeyboardHookProc NULL CPolicySnapIn Pointer"));
  8174. return 0;
  8175. }
  8176. }
  8177. if (wParam == VK_TAB && !(lParam & 0x80000000)) { // tab key depressed
  8178. BOOL fShift = (GetKeyState(VK_SHIFT) & 0x80000000);
  8179. HWND hwndFocus = GetFocus();
  8180. HWND hChild;
  8181. POLICYDLGINFO * pdi;
  8182. int iIndex;
  8183. int iDelta;
  8184. pdi = lpSettingsInfo->pdi;
  8185. if (!pdi)
  8186. {
  8187. if (lpSettingsInfo->pCS)
  8188. {
  8189. return lpSettingsInfo->pCS->CallNextHook(nCode,
  8190. wParam,
  8191. lParam);
  8192. }
  8193. else
  8194. {
  8195. DebugMsg((DM_WARNING, L"CPolicySnapIn::KeyboardHookProc NULL CPolicySnapIn Pointer"));
  8196. return 0;
  8197. }
  8198. }
  8199. // see if the focus control is one of the setting controls
  8200. for (iIndex=0;iIndex<(int)pdi->nControls;iIndex++) {
  8201. if (pdi->pControlTable[iIndex].hwnd == hwndFocus) {
  8202. goto BreakOut;
  8203. }
  8204. hChild = GetWindow (pdi->pControlTable[iIndex].hwnd, GW_CHILD);
  8205. while (hChild) {
  8206. if (hChild == hwndFocus) {
  8207. goto BreakOut;
  8208. }
  8209. hChild = GetWindow (hChild, GW_HWNDNEXT);
  8210. }
  8211. }
  8212. BreakOut:
  8213. if (iIndex == (int) pdi->nControls)
  8214. {
  8215. if (lpSettingsInfo->pCS)
  8216. {
  8217. return lpSettingsInfo->pCS->CallNextHook(nCode,
  8218. wParam,
  8219. lParam);
  8220. }
  8221. else // no, we don't care
  8222. {
  8223. DebugMsg((DM_WARNING, L"CPolicySnapIn::KeyboardHookProc NULL CPolicySnapIn Pointer"));
  8224. return 0;
  8225. }
  8226. }
  8227. iDelta = (fShift ? -1 : 1);
  8228. // from the current setting control, scan forwards or backwards
  8229. // (depending if on shift state, this can be TAB or shift-TAB)
  8230. // to find the next control to give focus to
  8231. for (iIndex += iDelta;iIndex>=0 && iIndex<(int) pdi->nControls;
  8232. iIndex += iDelta) {
  8233. if (pdi->pControlTable[iIndex].uDataIndex !=
  8234. NO_DATA_INDEX &&
  8235. IsWindowEnabled(pdi->pControlTable[iIndex].hwnd)) {
  8236. // found it, set the focus on that control and return 1
  8237. // to eat the keystroke
  8238. SetFocus(pdi->pControlTable[iIndex].hwnd);
  8239. lpSettingsInfo->pCS->EnsureSettingControlVisible(g_hDlgActive,
  8240. pdi->pControlTable[iIndex].hwnd);
  8241. return 1;
  8242. }
  8243. }
  8244. // at first or last control in settings table, let dlg code
  8245. // handle it and give focus to next (or previous) control in dialog
  8246. }
  8247. else
  8248. {
  8249. if (lpSettingsInfo->pCS)
  8250. {
  8251. return lpSettingsInfo->pCS->CallNextHook(nCode,
  8252. wParam,
  8253. lParam);
  8254. }
  8255. else
  8256. {
  8257. DebugMsg((DM_WARNING, L"CPolicySnapIn::KeyboardHookProc NULL CPolicySnapIn Pointer"));
  8258. return 0;
  8259. }
  8260. }
  8261. return 0;
  8262. }
  8263. VOID CPolicySnapIn::SetKeyboardHook(HWND hDlg)
  8264. {
  8265. // hook the keyboard to trap TABs. If this fails for some reason,
  8266. // fail silently and go on, not critical that tabs work correctly
  8267. // (unless you have no mouse :) )
  8268. if (m_hKbdHook = SetWindowsHookEx(WH_KEYBOARD,
  8269. KeyboardHookProc,
  8270. g_hInstance,
  8271. GetCurrentThreadId()))
  8272. {
  8273. g_hDlgActive = hDlg;
  8274. }
  8275. }
  8276. VOID CPolicySnapIn::RemoveKeyboardHook(VOID)
  8277. {
  8278. if (m_hKbdHook) {
  8279. UnhookWindowsHookEx(m_hKbdHook);
  8280. g_hDlgActive = NULL;
  8281. m_hKbdHook = NULL;
  8282. }
  8283. }
  8284. INT CPolicySnapIn::GetPolicyState (TABLEENTRY *pTableEntry, UINT uiPrecedence, LPTSTR *lpGPOName)
  8285. {
  8286. DWORD dwData=0;
  8287. UINT uRet;
  8288. TCHAR * pszValueName;
  8289. TCHAR * pszKeyName;
  8290. DWORD dwFoundSettings=0, dwTemp;
  8291. BOOL fFound=FALSE,fCustomOn=FALSE, fCustomOff=FALSE;
  8292. HKEY hKeyRoot;
  8293. INT iRetVal = -1;
  8294. TABLEENTRY *pChild;
  8295. if (m_pcd->m_bRSOP)
  8296. {
  8297. hKeyRoot = (HKEY) LongToHandle(uiPrecedence);
  8298. }
  8299. else
  8300. {
  8301. if (m_pcd->m_pGPTInformation->GetRegistryKey(
  8302. (m_pcd->m_bUserScope ? GPO_SECTION_USER : GPO_SECTION_MACHINE),
  8303. &hKeyRoot) != S_OK)
  8304. {
  8305. DebugMsg((DM_WARNING, TEXT("CPolicySnapIn::GetPolicyState: Failed to get registry key handle.")));
  8306. return -1;
  8307. }
  8308. }
  8309. //
  8310. // Get the name of the value to read, if any
  8311. //
  8312. if (((POLICY *)pTableEntry)->uOffsetValueName)
  8313. {
  8314. pszKeyName = GETKEYNAMEPTR(pTableEntry);
  8315. pszValueName = GETVALUENAMEPTR(((POLICY *)pTableEntry));
  8316. //
  8317. // First look for custom on/off values
  8318. //
  8319. if (((POLICY *)pTableEntry)->uOffsetValue_On)
  8320. {
  8321. fCustomOn = TRUE;
  8322. if (CompareCustomValue(hKeyRoot,pszKeyName,pszValueName,
  8323. (STATEVALUE *) ((BYTE *) pTableEntry + ((POLICY *)
  8324. pTableEntry)->uOffsetValue_On),&dwFoundSettings,lpGPOName)) {
  8325. dwData = 1;
  8326. fFound =TRUE;
  8327. }
  8328. }
  8329. if (!fFound && ((POLICY *)pTableEntry)->uOffsetValue_Off)
  8330. {
  8331. fCustomOff = TRUE;
  8332. if (CompareCustomValue(hKeyRoot,pszKeyName,pszValueName,
  8333. (STATEVALUE *) ((BYTE *) pTableEntry + ((POLICY *)
  8334. pTableEntry)->uOffsetValue_Off),&dwFoundSettings,lpGPOName)) {
  8335. dwData = 0;
  8336. fFound = TRUE;
  8337. }
  8338. }
  8339. //
  8340. // Look for standard values if custom values have not been specified
  8341. //
  8342. if (!fCustomOn && !fCustomOff && ReadStandardValue(hKeyRoot, pszKeyName, pszValueName,
  8343. pTableEntry, &dwData, &dwFoundSettings, lpGPOName))
  8344. {
  8345. fFound = TRUE;
  8346. }
  8347. if (fFound)
  8348. {
  8349. if (dwData)
  8350. iRetVal = 1;
  8351. else
  8352. iRetVal = 0;
  8353. }
  8354. }
  8355. else if ((((POLICY *)pTableEntry)->uOffsetActionList_On) &&
  8356. CheckActionList((POLICY *)pTableEntry, hKeyRoot, TRUE, lpGPOName))
  8357. {
  8358. iRetVal = 1;
  8359. }
  8360. else if ((((POLICY *)pTableEntry)->uOffsetActionList_Off) &&
  8361. CheckActionList((POLICY *)pTableEntry, hKeyRoot, FALSE, lpGPOName))
  8362. {
  8363. iRetVal = 0;
  8364. }
  8365. else
  8366. {
  8367. BOOL bDisabled = TRUE;
  8368. //
  8369. // Process settings underneath this policy (if any)
  8370. //
  8371. if (pTableEntry->pChild) {
  8372. dwFoundSettings = 0;
  8373. pChild = pTableEntry->pChild;
  8374. while (pChild) {
  8375. dwTemp = 0;
  8376. LoadSettings(pChild, hKeyRoot, &dwTemp, lpGPOName);
  8377. dwFoundSettings |= dwTemp;
  8378. if ((dwTemp & FS_PRESENT) && (!(dwTemp & FS_DISABLED))) {
  8379. bDisabled = FALSE;
  8380. }
  8381. pChild = pChild->pNext;
  8382. }
  8383. if (dwFoundSettings) {
  8384. if (bDisabled)
  8385. iRetVal = 0;
  8386. else
  8387. iRetVal = 1;
  8388. }
  8389. }
  8390. }
  8391. if (!m_pcd->m_bRSOP)
  8392. {
  8393. RegCloseKey (hKeyRoot);
  8394. }
  8395. return iRetVal;
  8396. }
  8397. BOOL CPolicySnapIn::CheckActionList (POLICY * pPolicy, HKEY hKeyRoot, BOOL bActionListOn, LPTSTR *lpGPOName)
  8398. {
  8399. UINT uIndex;
  8400. ACTIONLIST * pActionList;
  8401. ACTION * pAction;
  8402. TCHAR szValue[MAXSTRLEN];
  8403. DWORD dwValue;
  8404. TCHAR szNewValueName[MAX_PATH+1];
  8405. TCHAR * pszKeyName;
  8406. TCHAR * pszValueName;
  8407. TCHAR * pszValue;
  8408. //
  8409. // Get the correct action list
  8410. //
  8411. if (bActionListOn)
  8412. {
  8413. pActionList = (ACTIONLIST *)(((LPBYTE)pPolicy) + pPolicy->uOffsetActionList_On);
  8414. }
  8415. else
  8416. {
  8417. pActionList = (ACTIONLIST *)(((LPBYTE)pPolicy) + pPolicy->uOffsetActionList_Off);
  8418. }
  8419. //
  8420. // Loop through each of the entries to see if they match
  8421. //
  8422. for (uIndex = 0; uIndex < pActionList->nActionItems; uIndex++)
  8423. {
  8424. if (uIndex == 0)
  8425. {
  8426. pAction = &pActionList->Action[0];
  8427. }
  8428. else
  8429. {
  8430. pAction = (ACTION *)(((LPBYTE)pActionList) + pAction->uOffsetNextAction);
  8431. }
  8432. //
  8433. // Get the value and keynames
  8434. //
  8435. pszValueName = (TCHAR *)(((LPBYTE)pActionList) + pAction->uOffsetValueName);
  8436. if (pAction->uOffsetKeyName)
  8437. {
  8438. pszKeyName = (TCHAR *)(((LPBYTE)pActionList) + pAction->uOffsetKeyName);
  8439. }
  8440. else
  8441. {
  8442. pszKeyName = (TCHAR *)(((LPBYTE)pPolicy) + pPolicy->uOffsetKeyName);
  8443. }
  8444. //
  8445. // Add prefixes if appropriate
  8446. //
  8447. PrependValueName(pszValueName, pAction->dwFlags,
  8448. szNewValueName, ARRAYSIZE(szNewValueName));
  8449. if (pAction->dwFlags & VF_ISNUMERIC)
  8450. {
  8451. if (ReadRegistryDWordValue(hKeyRoot, pszKeyName,
  8452. szNewValueName, &dwValue, lpGPOName) != ERROR_SUCCESS)
  8453. {
  8454. return FALSE;
  8455. }
  8456. if (dwValue != pAction->dwValue)
  8457. {
  8458. return FALSE;
  8459. }
  8460. }
  8461. else if (pAction->dwFlags & VF_DELETE)
  8462. {
  8463. //
  8464. // See if this is a value that's marked for deletion
  8465. // (valuename is prepended with "**del."
  8466. //
  8467. if ((ReadRegistryStringValue(hKeyRoot, pszKeyName, szNewValueName,
  8468. szValue,ARRAYSIZE(szValue),lpGPOName)) != ERROR_SUCCESS) {
  8469. return FALSE;
  8470. }
  8471. }
  8472. else
  8473. {
  8474. if (ReadRegistryStringValue(hKeyRoot, pszKeyName, szNewValueName,
  8475. szValue, ARRAYSIZE(szValue),lpGPOName) != ERROR_SUCCESS)
  8476. {
  8477. return FALSE;
  8478. }
  8479. pszValue = (TCHAR *)(((LPBYTE)pActionList) + pAction->uOffsetValue);
  8480. if (lstrcmpi(szValue,pszValue) != 0)
  8481. {
  8482. return FALSE;
  8483. }
  8484. }
  8485. }
  8486. return TRUE;
  8487. }
  8488. UINT CPolicySnapIn::LoadSettings(TABLEENTRY * pTableEntry,HKEY hkeyRoot,
  8489. DWORD * pdwFound, LPTSTR *lpGPOName)
  8490. {
  8491. UINT uRet = ERROR_SUCCESS;
  8492. TCHAR * pszValueName = NULL;
  8493. TCHAR * pszKeyName = NULL;
  8494. DWORD dwData=0,dwFlags,dwFoundSettings=0;
  8495. TCHAR szData[MAXSTRLEN];
  8496. BOOL fCustomOn=FALSE,fCustomOff=FALSE,fFound=FALSE;
  8497. BYTE * pObjectData = GETOBJECTDATAPTR(((SETTINGS *)pTableEntry));
  8498. TCHAR szNewValueName[MAX_PATH+1];
  8499. // get the name of the key to read
  8500. if (((SETTINGS *) pTableEntry)->uOffsetKeyName) {
  8501. pszKeyName = GETKEYNAMEPTR(((SETTINGS *) pTableEntry));
  8502. }
  8503. else return ERROR_NOT_ENOUGH_MEMORY;
  8504. // get the name of the value to read
  8505. if (((SETTINGS *) pTableEntry)->uOffsetValueName) {
  8506. pszValueName = GETVALUENAMEPTR(((SETTINGS *) pTableEntry));
  8507. }
  8508. else return ERROR_NOT_ENOUGH_MEMORY;
  8509. switch (pTableEntry->dwType & STYPE_MASK) {
  8510. case STYPE_EDITTEXT:
  8511. case STYPE_COMBOBOX:
  8512. dwFlags = ( (SETTINGS *) pTableEntry)->dwFlags;
  8513. // add prefixes if appropriate
  8514. PrependValueName(pszValueName,dwFlags,
  8515. szNewValueName,ARRAYSIZE(szNewValueName));
  8516. if ((uRet = ReadRegistryStringValue(hkeyRoot,pszKeyName,
  8517. szNewValueName,szData,ARRAYSIZE(szData),lpGPOName)) == ERROR_SUCCESS) {
  8518. // set flag that we found setting in registry/policy file
  8519. if (pdwFound)
  8520. *pdwFound |= FS_PRESENT;
  8521. } else if (!(dwFlags & VF_DELETE)) {
  8522. // see if this key is marked as deleted
  8523. PrependValueName(pszValueName,VF_DELETE,
  8524. szNewValueName,ARRAYSIZE(szNewValueName));
  8525. if ((uRet = ReadRegistryStringValue(hkeyRoot,pszKeyName,
  8526. szNewValueName,szData,ARRAYSIZE(szData) * sizeof(TCHAR),lpGPOName)) == ERROR_SUCCESS) {
  8527. // set flag that we found setting marked as deleted in
  8528. // policy file
  8529. if (pdwFound)
  8530. *pdwFound |= FS_DELETED;
  8531. }
  8532. }
  8533. return ERROR_SUCCESS;
  8534. break;
  8535. case STYPE_CHECKBOX:
  8536. if (!pObjectData) {
  8537. return ERROR_INVALID_PARAMETER;
  8538. }
  8539. // first look for custom on/off values
  8540. if (((CHECKBOXINFO *) pObjectData)->uOffsetValue_On) {
  8541. fCustomOn = TRUE;
  8542. if (CompareCustomValue(hkeyRoot,pszKeyName,pszValueName,
  8543. (STATEVALUE *) ((BYTE *) pTableEntry + ((CHECKBOXINFO *)
  8544. pObjectData)->uOffsetValue_On),&dwFoundSettings, lpGPOName)) {
  8545. dwData = 1;
  8546. fFound = TRUE;
  8547. }
  8548. }
  8549. if (!fFound && ((CHECKBOXINFO *) pObjectData)->uOffsetValue_Off) {
  8550. fCustomOff = TRUE;
  8551. if (CompareCustomValue(hkeyRoot,pszKeyName,pszValueName,
  8552. (STATEVALUE *) ((BYTE *) pTableEntry + ((CHECKBOXINFO *)
  8553. pObjectData)->uOffsetValue_Off),&dwFoundSettings, lpGPOName)) {
  8554. dwData = 0;
  8555. fFound = TRUE;
  8556. }
  8557. }
  8558. // look for standard values if custom values have not been specified
  8559. if (!fFound &&
  8560. ReadStandardValue(hkeyRoot,pszKeyName,pszValueName,
  8561. pTableEntry,&dwData,&dwFoundSettings, lpGPOName)) {
  8562. fFound = TRUE;
  8563. }
  8564. if (fFound) {
  8565. // set flag that we found setting in registry
  8566. if (pdwFound) {
  8567. *pdwFound |= dwFoundSettings;
  8568. if (dwData == 0) {
  8569. *pdwFound |= FS_DISABLED;
  8570. }
  8571. }
  8572. }
  8573. return ERROR_SUCCESS;
  8574. break;
  8575. case STYPE_NUMERIC:
  8576. if (ReadStandardValue(hkeyRoot,pszKeyName,pszValueName,
  8577. pTableEntry,&dwData,&dwFoundSettings,lpGPOName)) {
  8578. // set flag that we found setting in registry
  8579. if (pdwFound)
  8580. *pdwFound |= dwFoundSettings;
  8581. }
  8582. break;
  8583. case STYPE_DROPDOWNLIST:
  8584. if (ReadCustomValue(hkeyRoot,pszKeyName,pszValueName,
  8585. szData,ARRAYSIZE(szData),&dwData,&dwFlags, lpGPOName)) {
  8586. BOOL fMatch = FALSE;
  8587. if (dwFlags & VF_DELETE) {
  8588. // set flag that we found setting marked as deleted
  8589. // in policy file
  8590. if (pdwFound)
  8591. *pdwFound |= FS_DELETED;
  8592. return ERROR_SUCCESS;
  8593. }
  8594. // walk the list of DROPDOWNINFO structs (one for each state),
  8595. // and see if the value we found matches the value for the state
  8596. if ( ((SETTINGS *) pTableEntry)->uOffsetObjectData) {
  8597. DROPDOWNINFO * pddi = (DROPDOWNINFO *)
  8598. GETOBJECTDATAPTR( ((SETTINGS *) pTableEntry));
  8599. UINT nIndex = 0;
  8600. do {
  8601. if (dwFlags == pddi->dwFlags) {
  8602. if (pddi->dwFlags & VF_ISNUMERIC) {
  8603. if (dwData == pddi->dwValue)
  8604. fMatch = TRUE;
  8605. } else if (!pddi->dwFlags) {
  8606. if (!lstrcmpi(szData,(TCHAR *)((BYTE *)pTableEntry +
  8607. pddi->uOffsetValue)))
  8608. fMatch = TRUE;
  8609. }
  8610. }
  8611. if (!pddi->uOffsetNextDropdowninfo || fMatch)
  8612. break;
  8613. pddi = (DROPDOWNINFO *) ( (BYTE *) pTableEntry +
  8614. pddi->uOffsetNextDropdowninfo);
  8615. nIndex++;
  8616. } while (!fMatch);
  8617. if (fMatch) {
  8618. // set flag that we found setting in registry
  8619. if (pdwFound)
  8620. *pdwFound |= FS_PRESENT;
  8621. }
  8622. }
  8623. }
  8624. break;
  8625. case STYPE_LISTBOX:
  8626. return LoadListboxData(pTableEntry,hkeyRoot,
  8627. pszKeyName,pdwFound, NULL, lpGPOName);
  8628. break;
  8629. }
  8630. return ERROR_SUCCESS;
  8631. }
  8632. UINT CPolicySnapIn::LoadListboxData(TABLEENTRY * pTableEntry,HKEY hkeyRoot,
  8633. TCHAR * pszCurrentKeyName,DWORD * pdwFound, HGLOBAL * phGlobal, LPTSTR *lpGPOName)
  8634. {
  8635. HKEY hKey = NULL;
  8636. UINT nIndex=0,nLen;
  8637. TCHAR szValueName[MAX_PATH+1],szValueData[MAX_PATH+1];
  8638. DWORD cbValueName,cbValueData;
  8639. DWORD dwType,dwAlloc=1024 * sizeof(TCHAR),dwUsed=0;
  8640. HGLOBAL hBuf;
  8641. TCHAR * pBuf;
  8642. SETTINGS * pSettings = (SETTINGS *) pTableEntry;
  8643. LISTBOXINFO * pListboxInfo = (LISTBOXINFO *)
  8644. GETOBJECTDATAPTR(pSettings);
  8645. BOOL fFoundValues=FALSE,fFoundDelvals=FALSE;
  8646. UINT uRet=ERROR_SUCCESS;
  8647. LPRSOPREGITEM lpItem = NULL;
  8648. BOOL bMultiple;
  8649. HRESULT hr = S_OK;
  8650. DWORD dwBufLen = 0;
  8651. if (m_pcd->m_bRSOP)
  8652. {
  8653. //
  8654. // If this is an additive listbox, we want to pick up entries from
  8655. // any GPO, not just the GPOs of precedence 1, so set hkeyRoot to 0
  8656. //
  8657. if ((pSettings->dwFlags & DF_ADDITIVE) && (hkeyRoot == (HKEY) 1))
  8658. {
  8659. hkeyRoot = (HKEY) 0;
  8660. }
  8661. }
  8662. else
  8663. {
  8664. if (RegOpenKeyEx(hkeyRoot,pszCurrentKeyName,0,KEY_READ,&hKey) != ERROR_SUCCESS)
  8665. return ERROR_SUCCESS; // nothing to do
  8666. }
  8667. // allocate a temp buffer to read entries into
  8668. if (!(hBuf = GlobalAlloc(GHND,dwAlloc)) ||
  8669. !(pBuf = (TCHAR *) GlobalLock(hBuf))) {
  8670. if (hBuf)
  8671. GlobalFree(hBuf);
  8672. uRet = ERROR_NOT_ENOUGH_MEMORY;
  8673. goto CPolicySnapin_LoadListBoxData_exit;
  8674. }
  8675. while (TRUE) {
  8676. cbValueName=ARRAYSIZE(szValueName);
  8677. cbValueData=ARRAYSIZE(szValueData) * sizeof(TCHAR);
  8678. if (m_pcd->m_bRSOP)
  8679. {
  8680. uRet = m_pcd->EnumRSOPRegistryValues(hkeyRoot, pszCurrentKeyName,
  8681. szValueName, cbValueName,
  8682. &lpItem);
  8683. if (uRet == ERROR_SUCCESS)
  8684. {
  8685. //
  8686. // Check if the GPO name is changing
  8687. //
  8688. bMultiple = FALSE;
  8689. if (lpGPOName && *lpGPOName && lpItem->lpGPOName && (hkeyRoot == 0))
  8690. {
  8691. if (lstrcmpi(*lpGPOName, lpItem->lpGPOName))
  8692. {
  8693. bMultiple = TRUE;
  8694. }
  8695. }
  8696. uRet = m_pcd->ReadRSOPRegistryValue(hkeyRoot, pszCurrentKeyName,
  8697. szValueName, (LPBYTE)szValueData,
  8698. cbValueData, &dwType, lpGPOName,
  8699. lpItem);
  8700. if (bMultiple)
  8701. {
  8702. *lpGPOName = m_pMultipleGPOs;
  8703. }
  8704. }
  8705. }
  8706. else
  8707. {
  8708. uRet=RegEnumValue(hKey,nIndex,szValueName,&cbValueName,NULL,
  8709. &dwType,(LPBYTE)szValueData,&cbValueData);
  8710. }
  8711. // stop if we're out of items
  8712. if (uRet != ERROR_SUCCESS && uRet != ERROR_MORE_DATA)
  8713. break;
  8714. nIndex++;
  8715. if (szValueName[0] == TEXT('\0')) {
  8716. // if the value is empty, it is the key creation code
  8717. continue;
  8718. }
  8719. // if valuename prefixed with '**', it's a control code, ignore it
  8720. if (szValueName[0] == TEXT('*') && szValueName[1] == TEXT('*')) {
  8721. // if we found **delvals., then some sort of listbox stuff
  8722. // is going on, remember that we found this code
  8723. if (!lstrcmpi(szValueName,szDELVALS))
  8724. fFoundDelvals = TRUE;
  8725. continue;
  8726. }
  8727. // only process this item if enum was successful
  8728. // (so we'll skip items with weird errors like ERROR_MORE_DATA and
  8729. // but keep going with the enum)
  8730. if (uRet == ERROR_SUCCESS) {
  8731. TCHAR * pszData;
  8732. // if there's no value name prefix scheme specified (e.g.
  8733. // value names are "abc1", "abc2", etc), and the explicit valuename
  8734. // flag isn't set where we remember the value name as well as
  8735. // the data for every value, then we need the value name to
  8736. // be the same as the value data ("thing.exe=thing.exe").
  8737. if (!(pSettings->dwFlags & DF_EXPLICITVALNAME) &&
  8738. !(pListboxInfo->uOffsetPrefix) && !(pListboxInfo->uOffsetValue)) {
  8739. if (dwType != (DWORD)((pSettings->dwFlags & DF_EXPANDABLETEXT) ? REG_EXPAND_SZ : REG_SZ) ||
  8740. lstrcmpi(szValueName,szValueData))
  8741. continue; // skip this value if val name != val data
  8742. }
  8743. //
  8744. // If there is a valueprefix, only pick up values that start
  8745. // with that prefix
  8746. //
  8747. if (pListboxInfo->uOffsetPrefix) {
  8748. LPTSTR lpPrefix = (LPTSTR)((LPBYTE)pTableEntry + pListboxInfo->uOffsetPrefix);
  8749. INT iPrefixLen = lstrlen(lpPrefix);
  8750. if (CompareString(LOCALE_USER_DEFAULT, NORM_IGNORECASE | NORM_STOP_ON_NULL,
  8751. lpPrefix, iPrefixLen, szValueName,
  8752. iPrefixLen) != CSTR_EQUAL) {
  8753. continue;
  8754. }
  8755. }
  8756. // if explicit valuenames used, then copy the value name into
  8757. // buffer
  8758. if (pSettings->dwFlags & DF_EXPLICITVALNAME) {
  8759. nLen = lstrlen(szValueName) + 1;
  8760. dwBufLen = dwUsed+nLen+4;
  8761. if (!(pBuf=ResizeBuffer(pBuf,hBuf,(dwBufLen) * sizeof(TCHAR),&dwAlloc)))
  8762. {
  8763. uRet = ERROR_NOT_ENOUGH_MEMORY;
  8764. goto CPolicySnapin_LoadListBoxData_exit;
  8765. }
  8766. hr = StringCchCopy(pBuf+dwUsed, dwBufLen - dwUsed, szValueName);
  8767. ASSERT(SUCCEEDED(hr));
  8768. dwUsed += nLen;
  8769. }
  8770. // for default listbox type, value data is the actual "data"
  8771. // and value name either will be the same as the data or
  8772. // some prefix + "1", "2", etc. If there's a data value to
  8773. // write for each entry, then the "data" is the value name
  8774. // (e.g. "Larry = abc", "Dave = abc"), etc. If explicit value names
  8775. // are turned on, then both the value name and data are stored
  8776. // and editable
  8777. // copy value data into buffer
  8778. if (pListboxInfo->uOffsetValue) {
  8779. // data value set, use value name for data
  8780. pszData = szValueName;
  8781. } else pszData = szValueData;
  8782. nLen = lstrlen(pszData) + 1;
  8783. dwBufLen = dwUsed+nLen+4;
  8784. if (!(pBuf=ResizeBuffer(pBuf,hBuf,(dwBufLen) * sizeof(TCHAR),&dwAlloc)))
  8785. {
  8786. uRet = ERROR_NOT_ENOUGH_MEMORY;
  8787. goto CPolicySnapin_LoadListBoxData_exit;
  8788. }
  8789. hr = StringCchCopy(pBuf+dwUsed, dwBufLen - dwUsed, pszData);
  8790. ASSERT(SUCCEEDED(hr));
  8791. dwUsed += nLen;
  8792. fFoundValues=TRUE;
  8793. //
  8794. // Add the GPO name if this is RSOP mode
  8795. //
  8796. if (m_pcd->m_bRSOP)
  8797. {
  8798. nLen = lstrlen(lpItem->lpGPOName) + 1;
  8799. dwBufLen = dwUsed+nLen+4;
  8800. if (!(pBuf=ResizeBuffer(pBuf,hBuf,(dwBufLen) * sizeof(TCHAR),&dwAlloc)))
  8801. {
  8802. uRet = ERROR_NOT_ENOUGH_MEMORY;
  8803. goto CPolicySnapin_LoadListBoxData_exit;
  8804. }
  8805. hr = StringCchCopy(pBuf+dwUsed, dwBufLen - dwUsed, lpItem->lpGPOName);
  8806. ASSERT(SUCCEEDED(hr));
  8807. dwUsed += nLen;
  8808. }
  8809. }
  8810. }
  8811. // doubly null-terminate the buffer... safe to do this because we
  8812. // tacked on the extra "+4" in the ResizeBuffer calls above
  8813. *(pBuf+dwUsed) = TEXT('\0');
  8814. dwUsed++;
  8815. uRet = ERROR_SUCCESS;
  8816. if (fFoundValues) {
  8817. // set flag that we found setting in registry/policy file
  8818. if (pdwFound)
  8819. *pdwFound |= FS_PRESENT;
  8820. } else {
  8821. if (fFoundDelvals && pdwFound) {
  8822. *pdwFound |= FS_DELETED;
  8823. }
  8824. }
  8825. GlobalUnlock(hBuf);
  8826. if ((uRet == ERROR_SUCCESS) && phGlobal)
  8827. {
  8828. *phGlobal = hBuf;
  8829. }
  8830. else
  8831. {
  8832. GlobalFree(hBuf);
  8833. }
  8834. CPolicySnapin_LoadListBoxData_exit:
  8835. if (hKey)
  8836. {
  8837. RegCloseKey(hKey);
  8838. }
  8839. return uRet;
  8840. }
  8841. BOOL CPolicySnapIn::ReadCustomValue(HKEY hkeyRoot,TCHAR * pszKeyName,TCHAR * pszValueName,
  8842. TCHAR * pszValue,UINT cbValue,DWORD * pdwValue,DWORD * pdwFlags,LPTSTR *lpGPOName)
  8843. {
  8844. HKEY hKey;
  8845. DWORD dwType,dwSize=cbValue * sizeof(TCHAR);
  8846. BOOL fSuccess = FALSE;
  8847. TCHAR szNewValueName[MAX_PATH+1];
  8848. *pdwValue=0;
  8849. *pszValue = TEXT('\0');
  8850. if (m_pcd->m_bRSOP)
  8851. {
  8852. if (m_pcd->ReadRSOPRegistryValue(hkeyRoot, pszKeyName, pszValueName, (LPBYTE)pszValue,
  8853. dwSize, &dwType, lpGPOName, NULL) == ERROR_SUCCESS)
  8854. {
  8855. if (dwType == REG_SZ)
  8856. {
  8857. // value returned in pszValueName
  8858. *pdwFlags = 0;
  8859. fSuccess = TRUE;
  8860. }
  8861. else if (dwType == REG_DWORD || dwType == REG_BINARY)
  8862. {
  8863. // copy value to *pdwValue
  8864. memcpy(pdwValue,pszValue,sizeof(DWORD));
  8865. *pdwFlags = VF_ISNUMERIC;
  8866. fSuccess = TRUE;
  8867. }
  8868. }
  8869. else
  8870. {
  8871. // see if this is a value that's marked for deletion
  8872. // (valuename is prepended with "**del."
  8873. PrependValueName(pszValueName,VF_DELETE,
  8874. szNewValueName,ARRAYSIZE(szNewValueName));
  8875. if (m_pcd->ReadRSOPRegistryValue(hkeyRoot, pszKeyName, szNewValueName, (LPBYTE)pszValue,
  8876. dwSize, &dwType, lpGPOName, NULL) == ERROR_SUCCESS)
  8877. {
  8878. fSuccess=TRUE;
  8879. *pdwFlags = VF_DELETE;
  8880. }
  8881. else
  8882. {
  8883. // see if this is a soft value
  8884. // (valuename is prepended with "**soft."
  8885. PrependValueName(pszValueName,VF_SOFT,
  8886. szNewValueName,ARRAYSIZE(szNewValueName));
  8887. if (m_pcd->ReadRSOPRegistryValue(hkeyRoot, pszKeyName, szNewValueName, (LPBYTE)pszValue,
  8888. dwSize, &dwType, lpGPOName, NULL) == ERROR_SUCCESS)
  8889. {
  8890. fSuccess=TRUE;
  8891. *pdwFlags = VF_SOFT;
  8892. }
  8893. }
  8894. }
  8895. }
  8896. else
  8897. {
  8898. if (RegOpenKeyEx(hkeyRoot,pszKeyName,0,KEY_READ,&hKey) == ERROR_SUCCESS) {
  8899. if (RegQueryValueEx(hKey,pszValueName,NULL,&dwType,(LPBYTE) pszValue,
  8900. &dwSize) == ERROR_SUCCESS) {
  8901. if (dwType == REG_SZ) {
  8902. // value returned in pszValueName
  8903. *pdwFlags = 0;
  8904. fSuccess = TRUE;
  8905. } else if (dwType == REG_DWORD || dwType == REG_BINARY) {
  8906. // copy value to *pdwValue
  8907. memcpy(pdwValue,pszValue,sizeof(DWORD));
  8908. *pdwFlags = VF_ISNUMERIC;
  8909. fSuccess = TRUE;
  8910. }
  8911. } else {
  8912. // see if this is a value that's marked for deletion
  8913. // (valuename is prepended with "**del."
  8914. PrependValueName(pszValueName,VF_DELETE,
  8915. szNewValueName,ARRAYSIZE(szNewValueName));
  8916. if (RegQueryValueEx(hKey,szNewValueName,NULL,&dwType,(LPBYTE) pszValue,
  8917. &dwSize) == ERROR_SUCCESS) {
  8918. fSuccess=TRUE;
  8919. *pdwFlags = VF_DELETE;
  8920. } else {
  8921. // see if this is a soft value
  8922. // (valuename is prepended with "**soft."
  8923. PrependValueName(pszValueName,VF_SOFT,
  8924. szNewValueName,ARRAYSIZE(szNewValueName));
  8925. if (RegQueryValueEx(hKey,szNewValueName,NULL,&dwType,(LPBYTE) pszValue,
  8926. &dwSize) == ERROR_SUCCESS) {
  8927. fSuccess=TRUE;
  8928. *pdwFlags = VF_SOFT;
  8929. }
  8930. }
  8931. }
  8932. RegCloseKey(hKey);
  8933. }
  8934. }
  8935. return fSuccess;
  8936. }
  8937. BOOL CPolicySnapIn::CompareCustomValue(HKEY hkeyRoot,TCHAR * pszKeyName,TCHAR * pszValueName,
  8938. STATEVALUE * pStateValue,DWORD * pdwFound, LPTSTR *lpGPOName)
  8939. {
  8940. TCHAR szValue[MAXSTRLEN];
  8941. DWORD dwValue;
  8942. TCHAR szNewValueName[MAX_PATH+1];
  8943. // add prefixes if appropriate
  8944. PrependValueName(pszValueName,pStateValue->dwFlags,
  8945. szNewValueName,ARRAYSIZE(szNewValueName));
  8946. if (pStateValue->dwFlags & VF_ISNUMERIC) {
  8947. if ((ReadRegistryDWordValue(hkeyRoot,pszKeyName,
  8948. szNewValueName,&dwValue,lpGPOName) == ERROR_SUCCESS) &&
  8949. dwValue == pStateValue->dwValue) {
  8950. *pdwFound = FS_PRESENT;
  8951. return TRUE;
  8952. }
  8953. } else if (pStateValue->dwFlags & VF_DELETE) {
  8954. // see if this is a value that's marked for deletion
  8955. // (valuename is prepended with "**del."
  8956. if ((ReadRegistryStringValue(hkeyRoot,pszKeyName,
  8957. szNewValueName,szValue,ARRAYSIZE(szValue),lpGPOName)) == ERROR_SUCCESS) {
  8958. *pdwFound = FS_DELETED;
  8959. return TRUE;
  8960. }
  8961. } else {
  8962. if ((ReadRegistryStringValue(hkeyRoot,pszKeyName,
  8963. szNewValueName,szValue,ARRAYSIZE(szValue),lpGPOName)) == ERROR_SUCCESS &&
  8964. !lstrcmpi(szValue,pStateValue->szValue)) {
  8965. *pdwFound = FS_PRESENT;
  8966. return TRUE;
  8967. }
  8968. }
  8969. return FALSE;
  8970. }
  8971. BOOL CPolicySnapIn::ReadStandardValue(HKEY hkeyRoot,TCHAR * pszKeyName,TCHAR * pszValueName,
  8972. TABLEENTRY * pTableEntry,DWORD * pdwData,DWORD * pdwFound, LPTSTR *lpGPOName)
  8973. {
  8974. UINT uRet;
  8975. TCHAR szNewValueName[MAX_PATH+1];
  8976. // add prefixes if appropriate
  8977. PrependValueName(pszValueName,((SETTINGS *) pTableEntry)->dwFlags,
  8978. szNewValueName,ARRAYSIZE(szNewValueName));
  8979. if ( ((SETTINGS *) pTableEntry)->dwFlags & DF_TXTCONVERT) {
  8980. // read numeric value as text if specified
  8981. TCHAR szNum[11];
  8982. uRet = ReadRegistryStringValue(hkeyRoot,pszKeyName,
  8983. szNewValueName,szNum,ARRAYSIZE(szNum),lpGPOName);
  8984. if (uRet == ERROR_SUCCESS) {
  8985. StringToNum(szNum, (UINT *)pdwData);
  8986. *pdwFound = FS_PRESENT;
  8987. return TRUE;
  8988. }
  8989. } else {
  8990. // read numeric value as binary
  8991. uRet = ReadRegistryDWordValue(hkeyRoot,pszKeyName,
  8992. szNewValueName,pdwData, lpGPOName);
  8993. if (uRet == ERROR_SUCCESS) {
  8994. *pdwFound = FS_PRESENT;
  8995. return TRUE;
  8996. }
  8997. }
  8998. // see if this settings has been marked as 'deleted'
  8999. TCHAR szVal[MAX_PATH+1];
  9000. *pdwData = 0;
  9001. PrependValueName(pszValueName,VF_DELETE,szNewValueName,
  9002. ARRAYSIZE(szNewValueName));
  9003. uRet=ReadRegistryStringValue(hkeyRoot,pszKeyName,
  9004. szNewValueName,szVal,ARRAYSIZE(szVal),lpGPOName);
  9005. if (uRet == ERROR_SUCCESS) {
  9006. *pdwFound = FS_DELETED;
  9007. return TRUE;
  9008. }
  9009. return FALSE;
  9010. }
  9011. // adds the special prefixes "**del." and "**soft." if writing to a policy file,
  9012. // and VF_DELETE/VF_SOFT flags are set
  9013. VOID CPolicySnapIn::PrependValueName(TCHAR * pszValueName,DWORD dwFlags,TCHAR * pszNewValueName,
  9014. UINT cbNewValueName)
  9015. {
  9016. UINT nValueNameLen = lstrlen(pszValueName) + 1;
  9017. HRESULT hr = S_OK;
  9018. (void) StringCchCopy(pszNewValueName, cbNewValueName, g_szNull);
  9019. if (cbNewValueName < nValueNameLen) // check length of buffer, just in case
  9020. return;
  9021. // prepend special prefixes for "delete" or "soft" values
  9022. if ((dwFlags & VF_DELETE) && (cbNewValueName > nValueNameLen +
  9023. ARRAYSIZE(szDELETEPREFIX))) {
  9024. (void) StringCchCopy(pszNewValueName, cbNewValueName, szDELETEPREFIX);
  9025. } else if ((dwFlags & VF_SOFT) && (cbNewValueName > nValueNameLen +
  9026. ARRAYSIZE(szSOFTPREFIX))) {
  9027. (void) StringCchCopy(pszNewValueName, cbNewValueName, szSOFTPREFIX);
  9028. }
  9029. (void) StringCchCat(pszNewValueName, cbNewValueName, pszValueName);
  9030. }
  9031. UINT CPolicySnapIn::WriteRegistryDWordValue(HKEY hkeyRoot,TCHAR * pszKeyName,TCHAR * pszValueName,
  9032. DWORD dwValue)
  9033. {
  9034. HKEY hKey;
  9035. UINT uRet;
  9036. if (!pszKeyName || !pszValueName)
  9037. return ERROR_INVALID_PARAMETER;
  9038. // create the key with appropriate name
  9039. if ( (uRet = RegCreateKey(hkeyRoot,pszKeyName,&hKey))
  9040. != ERROR_SUCCESS)
  9041. return uRet;
  9042. uRet = RegSetValueEx(hKey,pszValueName,0,REG_DWORD,
  9043. (LPBYTE) &dwValue,sizeof(dwValue));
  9044. RegCloseKey(hKey);
  9045. return uRet;
  9046. }
  9047. UINT CPolicySnapIn::ReadRegistryDWordValue(HKEY hkeyRoot,TCHAR * pszKeyName,TCHAR * pszValueName,
  9048. DWORD * pdwValue, LPTSTR *lpGPOName)
  9049. {
  9050. HKEY hKey;
  9051. UINT uRet;
  9052. DWORD dwType,dwSize = sizeof(DWORD);
  9053. if (!pszKeyName || !pszValueName)
  9054. return ERROR_INVALID_PARAMETER;
  9055. *pdwValue = 0;
  9056. if (m_pcd->m_bRSOP)
  9057. {
  9058. uRet = m_pcd->ReadRSOPRegistryValue(hkeyRoot, pszKeyName, pszValueName, (LPBYTE) pdwValue, 4,
  9059. &dwType, lpGPOName, NULL);
  9060. }
  9061. else
  9062. {
  9063. // open appropriate key
  9064. if ( (uRet = RegOpenKeyEx(hkeyRoot,pszKeyName,0,KEY_READ,&hKey))
  9065. != ERROR_SUCCESS)
  9066. return uRet;
  9067. uRet = RegQueryValueEx(hKey,pszValueName,0,&dwType,
  9068. (LPBYTE) pdwValue,&dwSize);
  9069. RegCloseKey(hKey);
  9070. }
  9071. return uRet;
  9072. }
  9073. UINT CPolicySnapIn::WriteRegistryStringValue(HKEY hkeyRoot,TCHAR * pszKeyName,TCHAR * pszValueName,
  9074. TCHAR * pszValue, BOOL bExpandable)
  9075. {
  9076. HKEY hKey;
  9077. UINT uRet;
  9078. if (!pszKeyName || !pszValueName)
  9079. return ERROR_INVALID_PARAMETER;
  9080. // create the key with appropriate name
  9081. if ( (uRet = RegCreateKey(hkeyRoot,pszKeyName,&hKey))
  9082. != ERROR_SUCCESS)
  9083. return uRet;
  9084. uRet = RegSetValueEx(hKey,pszValueName,0,
  9085. bExpandable ? REG_EXPAND_SZ : REG_SZ,
  9086. (LPBYTE) pszValue,(lstrlen(pszValue)+1) * sizeof(TCHAR));
  9087. RegCloseKey(hKey);
  9088. return uRet;
  9089. }
  9090. UINT CPolicySnapIn::ReadRegistryStringValue(HKEY hkeyRoot,TCHAR * pszKeyName,TCHAR * pszValueName,
  9091. TCHAR * pszValue,UINT cbValue, LPTSTR *lpGPOName)
  9092. {
  9093. HKEY hKey;
  9094. UINT uRet;
  9095. DWORD dwType;
  9096. DWORD dwSize = cbValue * sizeof(TCHAR);
  9097. if (!pszKeyName || !pszValueName)
  9098. return ERROR_INVALID_PARAMETER;
  9099. if (m_pcd->m_bRSOP)
  9100. {
  9101. uRet = m_pcd->ReadRSOPRegistryValue(hkeyRoot, pszKeyName, pszValueName, (LPBYTE) pszValue,
  9102. dwSize, &dwType, lpGPOName, NULL);
  9103. }
  9104. else
  9105. {
  9106. // create the key with appropriate name
  9107. if ( (uRet = RegOpenKeyEx(hkeyRoot,pszKeyName,0,KEY_READ,&hKey))
  9108. != ERROR_SUCCESS)
  9109. return uRet;
  9110. uRet = RegQueryValueEx(hKey,pszValueName,0,&dwType,
  9111. (LPBYTE) pszValue,&dwSize);
  9112. RegCloseKey(hKey);
  9113. }
  9114. return uRet;
  9115. }
  9116. UINT CPolicySnapIn::DeleteRegistryValue(HKEY hkeyRoot,TCHAR * pszKeyName,TCHAR * pszValueName)
  9117. {
  9118. HKEY hKey;
  9119. UINT uRet;
  9120. if (!pszKeyName || !pszValueName)
  9121. return ERROR_INVALID_PARAMETER;
  9122. // create the key with appropriate name
  9123. if ( (uRet = RegOpenKeyEx(hkeyRoot,pszKeyName,0,KEY_WRITE,&hKey))
  9124. != ERROR_SUCCESS)
  9125. return uRet;
  9126. uRet = RegDeleteValue(hKey,pszValueName);
  9127. RegCloseKey(hKey);
  9128. return uRet;
  9129. }
  9130. UINT CPolicySnapIn::WriteCustomValue_W(HKEY hkeyRoot,TCHAR * pszKeyName,TCHAR * pszValueName,
  9131. TCHAR * pszValue,DWORD dwValue,DWORD dwFlags,BOOL fErase)
  9132. {
  9133. UINT uRet=ERROR_SUCCESS;
  9134. TCHAR szNewValueName[MAX_PATH+1];
  9135. // first: "clean house" by deleting both the specified value name,
  9136. // and the value name with the delete (**del.) prefix.
  9137. // Then write the appropriate version back out if need be
  9138. PrependValueName(pszValueName,VF_DELETE,szNewValueName,
  9139. ARRAYSIZE(szNewValueName));
  9140. DeleteRegistryValue(hkeyRoot,pszKeyName,szNewValueName);
  9141. // add prefixes if appropriate
  9142. PrependValueName(pszValueName,(dwFlags & ~VF_DELETE),szNewValueName,
  9143. ARRAYSIZE(szNewValueName));
  9144. DeleteRegistryValue(hkeyRoot,pszKeyName,szNewValueName);
  9145. if (fErase) {
  9146. // just need to delete value, done above
  9147. uRet = ERROR_SUCCESS;
  9148. RegCleanUpValue (hkeyRoot, pszKeyName, pszValueName);
  9149. } else if (dwFlags & VF_DELETE) {
  9150. // need to delete value (done above) and mark as deleted if writing
  9151. // to policy file
  9152. uRet = ERROR_SUCCESS;
  9153. PrependValueName(pszValueName,VF_DELETE,szNewValueName,
  9154. ARRAYSIZE(szNewValueName));
  9155. uRet=WriteRegistryStringValue(hkeyRoot,pszKeyName,
  9156. szNewValueName, (TCHAR *)szNOVALUE, FALSE);
  9157. } else {
  9158. if (dwFlags & VF_ISNUMERIC) {
  9159. uRet=WriteRegistryDWordValue(hkeyRoot,pszKeyName,
  9160. szNewValueName,dwValue);
  9161. } else {
  9162. uRet = WriteRegistryStringValue(hkeyRoot,pszKeyName,
  9163. szNewValueName,pszValue,
  9164. (dwFlags & DF_EXPANDABLETEXT) ? TRUE : FALSE);
  9165. }
  9166. }
  9167. return uRet;
  9168. }
  9169. UINT CPolicySnapIn::WriteCustomValue(HKEY hkeyRoot,TCHAR * pszKeyName,TCHAR * pszValueName,
  9170. STATEVALUE * pStateValue,BOOL fErase)
  9171. {
  9172. // pull info out of STATEVALUE struct and call worker function
  9173. return WriteCustomValue_W(hkeyRoot,pszKeyName,pszValueName,
  9174. pStateValue->szValue,pStateValue->dwValue,pStateValue->dwFlags,
  9175. fErase);
  9176. }
  9177. // writes a numeric value given root key, key name and value name. The specified
  9178. // value is removed if fErase is TRUE. Normally if the data (dwData) is zero
  9179. // the value will be deleted, but if fWriteZero is TRUE then the value will
  9180. // be written as zero if the data is zero.
  9181. UINT CPolicySnapIn::WriteStandardValue(HKEY hkeyRoot,TCHAR * pszKeyName,TCHAR * pszValueName,
  9182. TABLEENTRY * pTableEntry,DWORD dwData,BOOL fErase,BOOL fWriteZero)
  9183. {
  9184. UINT uRet=ERROR_SUCCESS;
  9185. TCHAR szNewValueName[MAX_PATH+1];
  9186. HRESULT hr = S_OK;
  9187. // first: "clean house" by deleting both the specified value name,
  9188. // and the value name with the delete (**del.) prefix (if writing to policy
  9189. // file). Then write the appropriate version back out if need be
  9190. PrependValueName(pszValueName,VF_DELETE,szNewValueName,
  9191. ARRAYSIZE(szNewValueName));
  9192. DeleteRegistryValue(hkeyRoot,pszKeyName,szNewValueName);
  9193. DeleteRegistryValue(hkeyRoot,pszKeyName,pszValueName);
  9194. if (fErase) {
  9195. // just need to delete value, done above
  9196. uRet = ERROR_SUCCESS;
  9197. RegCleanUpValue (hkeyRoot, pszKeyName, pszValueName);
  9198. } else if ( ((SETTINGS *) pTableEntry)->dwFlags & DF_TXTCONVERT) {
  9199. // if specified, save value as text
  9200. TCHAR szNum[11];
  9201. hr = StringCchPrintf(szNum, ARRAYSIZE(szNum), TEXT("%lu"),dwData);
  9202. ASSERT(SUCCEEDED(hr));
  9203. if (!dwData && !fWriteZero) {
  9204. // if value is 0, delete the value (done above), and mark
  9205. // it as deleted if writing to policy file
  9206. PrependValueName(pszValueName,VF_DELETE,szNewValueName,
  9207. ARRAYSIZE(szNewValueName));
  9208. uRet=WriteRegistryStringValue(hkeyRoot,pszKeyName,
  9209. szNewValueName,(TCHAR *)szNOVALUE, FALSE);
  9210. } else {
  9211. PrependValueName(pszValueName,((SETTINGS *)pTableEntry)->dwFlags,
  9212. szNewValueName,ARRAYSIZE(szNewValueName));
  9213. uRet = WriteRegistryStringValue(hkeyRoot,pszKeyName,
  9214. szNewValueName,szNum, FALSE);
  9215. }
  9216. } else {
  9217. if (!dwData && !fWriteZero) {
  9218. // if value is 0, delete the value (done above), and mark
  9219. // it as deleted if writing to policy file
  9220. PrependValueName(pszValueName,VF_DELETE,szNewValueName,
  9221. ARRAYSIZE(szNewValueName));
  9222. uRet=WriteRegistryStringValue(hkeyRoot,pszKeyName,
  9223. szNewValueName,(TCHAR *)szNOVALUE, FALSE);
  9224. } else {
  9225. // save value as binary
  9226. PrependValueName(pszValueName,((SETTINGS *)pTableEntry)->dwFlags,
  9227. szNewValueName,ARRAYSIZE(szNewValueName));
  9228. uRet=WriteRegistryDWordValue(hkeyRoot,pszKeyName,
  9229. szNewValueName,dwData);
  9230. return 0;
  9231. }
  9232. }
  9233. return uRet;
  9234. }
  9235. TCHAR * CPolicySnapIn::ResizeBuffer(TCHAR * pBuf,HGLOBAL hBuf,DWORD dwNeeded,DWORD * pdwCurSize)
  9236. {
  9237. TCHAR * pNew;
  9238. if (dwNeeded <= *pdwCurSize) return pBuf; // nothing to do
  9239. *pdwCurSize = dwNeeded;
  9240. GlobalUnlock(hBuf);
  9241. if (!GlobalReAlloc(hBuf,dwNeeded,GHND))
  9242. return NULL;
  9243. if (!(pNew = (TCHAR *) GlobalLock(hBuf))) return NULL;
  9244. return pNew;
  9245. }
  9246. /*******************************************************************
  9247. NAME: MessageWndProc
  9248. SYNOPSIS: Window proc for GPMessageWndProc window
  9249. ********************************************************************/
  9250. LRESULT CALLBACK CPolicySnapIn::MessageWndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)
  9251. {
  9252. switch (message)
  9253. {
  9254. case WM_CREATE:
  9255. SetWindowLongPtr (hWnd, GWLP_USERDATA, (LONG_PTR)((CREATESTRUCT *) lParam)->lpCreateParams);
  9256. break;
  9257. case WM_MOVEFOCUS:
  9258. {
  9259. CPolicySnapIn * pPS;
  9260. pPS = (CPolicySnapIn *) GetWindowLongPtr (hWnd, GWLP_USERDATA);
  9261. if (pPS)
  9262. {
  9263. pPS->MoveFocusWorker ((BOOL)wParam);
  9264. }
  9265. }
  9266. break;
  9267. case WM_UPDATEITEM:
  9268. {
  9269. CPolicySnapIn * pPS;
  9270. pPS = (CPolicySnapIn *) GetWindowLongPtr (hWnd, GWLP_USERDATA);
  9271. if (pPS)
  9272. {
  9273. pPS->UpdateItemWorker ();
  9274. }
  9275. }
  9276. break;
  9277. case WM_SETPREVNEXT:
  9278. {
  9279. CPolicySnapIn * pPS;
  9280. pPS = (CPolicySnapIn *) GetWindowLongPtr (hWnd, GWLP_USERDATA);
  9281. if (pPS)
  9282. {
  9283. pPS->SetPrevNextButtonStateWorker ((HWND) wParam);
  9284. }
  9285. }
  9286. break;
  9287. default:
  9288. {
  9289. CPolicySnapIn * pPS;
  9290. pPS = (CPolicySnapIn *) GetWindowLongPtr (hWnd, GWLP_USERDATA);
  9291. if (pPS)
  9292. {
  9293. if (message == pPS->m_uiRefreshMsg)
  9294. {
  9295. if ((DWORD) lParam == GetCurrentProcessId())
  9296. {
  9297. if (!pPS->m_hPropDlg)
  9298. {
  9299. pPS->m_pcd->m_pScope->DeleteItem (pPS->m_pcd->m_hSWPolicies, FALSE);
  9300. pPS->m_pcd->LoadTemplates();
  9301. pPS->m_pcd->EnumerateScopePane (NULL, pPS->m_pcd->m_hSWPolicies);
  9302. }
  9303. }
  9304. }
  9305. }
  9306. return (DefWindowProc(hWnd, message, wParam, lParam));
  9307. }
  9308. }
  9309. return (0);
  9310. }
  9311. /*******************************************************************
  9312. NAME: ClipWndProc
  9313. SYNOPSIS: Window proc for ClipClass window
  9314. ********************************************************************/
  9315. LRESULT CALLBACK CPolicySnapIn::ClipWndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)
  9316. {
  9317. switch (message) {
  9318. case WM_CREATE:
  9319. if (!((CREATESTRUCT *) lParam)->lpCreateParams) {
  9320. // this is the clip window in the dialog box.
  9321. SetScrollRange(hWnd,SB_VERT,0,0,TRUE);
  9322. SetScrollRange(hWnd,SB_HORZ,0,0,TRUE);
  9323. } else {
  9324. // this is the container window
  9325. // store away the dialog box HWND (the grandparent of this
  9326. // window) because the pointer to instance data we need lives
  9327. // in the dialog's window data
  9328. SetWindowLong(hWnd,0,WT_SETTINGS);
  9329. }
  9330. break;
  9331. case WM_USER:
  9332. {
  9333. HWND hwndParent = GetParent(hWnd);
  9334. LPSETTINGSINFO lpSettingsInfo;
  9335. POLICYDLGINFO * pdi;
  9336. lpSettingsInfo = (LPSETTINGSINFO) GetWindowLongPtr(hwndParent, DWLP_USER);
  9337. if (!lpSettingsInfo)
  9338. return FALSE;
  9339. pdi = lpSettingsInfo->pdi;
  9340. if (!pdi)
  9341. return FALSE;
  9342. if (!lpSettingsInfo->hFontDlg)
  9343. lpSettingsInfo->hFontDlg = (HFONT) SendMessage(GetParent(hWnd),WM_GETFONT,0,0L);
  9344. // make a container window that is clipped by this windows
  9345. if (!(pdi->hwndSettings=CreateWindow(TEXT("ClipClass"),(TCHAR *) g_szNull,
  9346. WS_CHILD | WS_VISIBLE,0,0,400,400,hWnd,NULL,g_hInstance,
  9347. (LPVOID) hWnd)))
  9348. return FALSE;
  9349. SetWindowLong(hWnd,0,WT_CLIP);
  9350. return TRUE;
  9351. }
  9352. break;
  9353. case WM_VSCROLL:
  9354. case WM_HSCROLL:
  9355. if (GetWindowLong(hWnd,0) == WT_CLIP)
  9356. {
  9357. LPSETTINGSINFO lpSettingsInfo;
  9358. lpSettingsInfo = (LPSETTINGSINFO) GetWindowLongPtr(GetParent(hWnd), DWLP_USER);
  9359. if (!lpSettingsInfo)
  9360. return FALSE;
  9361. lpSettingsInfo->pCS->ProcessScrollBar(hWnd,wParam,
  9362. (message == WM_VSCROLL) ? TRUE : FALSE);
  9363. }
  9364. else goto defproc;
  9365. return 0;
  9366. case WM_COMMAND:
  9367. if (GetWindowLong(hWnd,0) == WT_SETTINGS) {
  9368. LPSETTINGSINFO lpSettingsInfo;
  9369. lpSettingsInfo = (LPSETTINGSINFO) GetWindowLongPtr(GetParent(GetParent(hWnd)), DWLP_USER);
  9370. if (!lpSettingsInfo)
  9371. break;
  9372. lpSettingsInfo->pCS->ProcessCommand(hWnd,wParam,(HWND) lParam, lpSettingsInfo->pdi);
  9373. }
  9374. break;
  9375. case WM_GETDLGCODE:
  9376. if (GetWindowLong(hWnd,0) == WT_CLIP) {
  9377. SetWindowLongPtr(GetParent(hWnd),DWLP_MSGRESULT,DLGC_WANTTAB |
  9378. DLGC_WANTALLKEYS);
  9379. return DLGC_WANTTAB | DLGC_WANTALLKEYS;
  9380. }
  9381. break;
  9382. case WM_SETFOCUS:
  9383. // if clip window gains keyboard focus, transfer focus to first
  9384. // control owned by settings window
  9385. if (GetWindowLong(hWnd,0) == WT_CLIP) {
  9386. HWND hwndParent = GetParent(hWnd);
  9387. POLICYDLGINFO * pdi;
  9388. INT nIndex;
  9389. BOOL fForward=TRUE;
  9390. HWND hwndPrev = GetDlgItem(hwndParent,IDC_POLICY_PREVIOUS);
  9391. HWND hwndNext = GetDlgItem(hwndParent,IDC_POLICY_NEXT);
  9392. HWND hwndOK = GetDlgItem(GetParent(hwndParent),IDOK);
  9393. int iDelta;
  9394. LPSETTINGSINFO lpSettingsInfo;
  9395. lpSettingsInfo = (LPSETTINGSINFO) GetWindowLongPtr(GetParent(hWnd), DWLP_USER);
  9396. if (!lpSettingsInfo)
  9397. return FALSE;
  9398. pdi = lpSettingsInfo->pdi;
  9399. if (!pdi)
  9400. return FALSE;
  9401. // if Previous Policy button lost focus, then we're going backwards
  9402. // in tab order; otherwise we're going forwards
  9403. if ( (HWND) wParam == hwndPrev)
  9404. fForward = FALSE;
  9405. else if ( (HWND) wParam == hwndNext)
  9406. fForward = FALSE;
  9407. else if ( (HWND) wParam == hwndOK)
  9408. fForward = FALSE;
  9409. // find the first control that has a data index (e.g. is
  9410. // not static text) and give it focus
  9411. if (pdi->nControls) {
  9412. if (fForward) { // search from start of table forwards
  9413. nIndex = 0;
  9414. iDelta = 1;
  9415. } else { // search from end of table backwards
  9416. nIndex = pdi->nControls-1;
  9417. iDelta = -1;
  9418. }
  9419. for (;nIndex>=0 && nIndex<(int)pdi->nControls;nIndex += iDelta) {
  9420. if (pdi->pControlTable[nIndex].uDataIndex !=
  9421. NO_DATA_INDEX &&
  9422. IsWindowEnabled(pdi->pControlTable[nIndex].hwnd)) {
  9423. SetFocus(pdi->pControlTable[nIndex].hwnd);
  9424. lpSettingsInfo->pCS->EnsureSettingControlVisible(hwndParent,
  9425. pdi->pControlTable[nIndex].hwnd);
  9426. return FALSE;
  9427. }
  9428. }
  9429. }
  9430. // only get here if there are no setting windows that can
  9431. // receive keyboard focus. Give keyboard focus to the
  9432. // next guy in line. This is the "OK" button, unless we
  9433. // shift-tabbed to get here from the "OK" button in which
  9434. // case the tree window is the next guy in line
  9435. if (fForward) {
  9436. if (IsWindowEnabled (hwndPrev))
  9437. SetFocus(hwndPrev);
  9438. else if (IsWindowEnabled (hwndNext))
  9439. SetFocus(hwndNext);
  9440. else
  9441. SetFocus(hwndOK);
  9442. } else {
  9443. if (IsDlgButtonChecked (hwndParent, IDC_ENABLED) == BST_CHECKED) {
  9444. SetFocus (GetDlgItem(hwndParent,IDC_ENABLED));
  9445. } else if (IsDlgButtonChecked (hwndParent, IDC_DISABLED) == BST_CHECKED) {
  9446. SetFocus (GetDlgItem(hwndParent,IDC_DISABLED));
  9447. } else {
  9448. SetFocus (GetDlgItem(hwndParent,IDC_NOCONFIG));
  9449. }
  9450. }
  9451. return FALSE;
  9452. }
  9453. break;
  9454. default:
  9455. defproc:
  9456. return (DefWindowProc(hWnd, message, wParam, lParam));
  9457. }
  9458. return (0);
  9459. }
  9460. /*******************************************************************
  9461. NAME: ProcessCommand
  9462. SYNOPSIS: WM_COMMAND handler for ClipClass window
  9463. ********************************************************************/
  9464. VOID CPolicySnapIn::ProcessCommand(HWND hWnd,WPARAM wParam,HWND hwndCtrl, POLICYDLGINFO * pdi)
  9465. {
  9466. // get instance-specific struct from dialog
  9467. UINT uID = GetWindowLong(hwndCtrl,GWL_ID);
  9468. if ( (uID >= IDD_SETTINGCTRL) && (uID < IDD_SETTINGCTRL+pdi->nControls)) {
  9469. POLICYCTRLINFO * pPolicyCtrlInfo= &pdi->pControlTable[uID - IDD_SETTINGCTRL];
  9470. switch (pPolicyCtrlInfo->dwType) {
  9471. case STYPE_CHECKBOX:
  9472. SendMessage(hwndCtrl,BM_SETCHECK,
  9473. !(SendMessage(hwndCtrl,BM_GETCHECK,0,0)),0);
  9474. break;
  9475. case STYPE_LISTBOX:
  9476. ShowListbox(hwndCtrl,pPolicyCtrlInfo->pSetting);
  9477. break;
  9478. default:
  9479. // nothing to do
  9480. break;
  9481. }
  9482. if ((HIWORD(wParam) == BN_CLICKED) ||
  9483. (HIWORD(wParam) == EN_CHANGE) ||
  9484. (HIWORD(wParam) == CBN_SELCHANGE) ||
  9485. (HIWORD(wParam) == CBN_EDITCHANGE))
  9486. {
  9487. PostMessage (GetParent(GetParent(hWnd)), WM_MYCHANGENOTIFY, 0, 0);
  9488. }
  9489. }
  9490. }
  9491. // scrolls the control window into view if it's not visible
  9492. VOID CPolicySnapIn::EnsureSettingControlVisible(HWND hDlg,HWND hwndCtrl)
  9493. {
  9494. // get the clip window, which owns the scroll bar
  9495. HWND hwndClip = GetDlgItem(hDlg,IDC_POLICY_SETTINGS);
  9496. POLICYDLGINFO * pdi;
  9497. UINT nPos = GetScrollPos(hwndClip,SB_VERT),ySettingWindowSize,yClipWindowSize;
  9498. UINT nExtra;
  9499. int iMin,iMax=0;
  9500. WINDOWPLACEMENT wp;
  9501. RECT rcCtrl;
  9502. LPSETTINGSINFO lpSettingsInfo;
  9503. lpSettingsInfo = (LPSETTINGSINFO) GetWindowLongPtr(hDlg, DWLP_USER);
  9504. if (!lpSettingsInfo)
  9505. return;
  9506. pdi = lpSettingsInfo->pdi;
  9507. if (!pdi)
  9508. return;
  9509. // find the scroll range
  9510. GetScrollRange(hwndClip,SB_VERT,&iMin,&iMax);
  9511. if (!iMax) // no scroll bar, nothing to do
  9512. return;
  9513. // find the y size of the settings window that contains the settings controls
  9514. // (this is clipped by the clip window in the dialog, scroll bar moves the
  9515. // setting window up and down behind the clip window)
  9516. wp.length = sizeof(wp);
  9517. if (!GetWindowPlacement(pdi->hwndSettings,&wp))
  9518. return; // unlikely to fail, but just bag out if it does rather than do something wacky
  9519. ySettingWindowSize=wp.rcNormalPosition.bottom-wp.rcNormalPosition.top;
  9520. // find y size of clip window
  9521. if (!GetWindowPlacement(hwndClip,&wp))
  9522. return; // unlikely to fail, but just bag out if it does rather than do something wacky
  9523. yClipWindowSize=wp.rcNormalPosition.bottom-wp.rcNormalPosition.top;
  9524. nExtra = ySettingWindowSize - yClipWindowSize;
  9525. // if setting window is smaller than clip window, there should be no
  9526. // scroll bar so we should never get here. Check just in case though...
  9527. if (ySettingWindowSize < yClipWindowSize)
  9528. return;
  9529. // get y position of control to be made visible
  9530. if (!GetWindowPlacement(hwndCtrl,&wp))
  9531. return;
  9532. rcCtrl = wp.rcNormalPosition;
  9533. rcCtrl.bottom = min ((int) ySettingWindowSize,rcCtrl.bottom + SC_YPAD);
  9534. rcCtrl.top = max ((int) 0,rcCtrl.top - SC_YPAD);
  9535. // if bottom of control is out of view, scroll the settings window up
  9536. if ((float) rcCtrl.bottom >
  9537. (float) (yClipWindowSize + ( (float) nPos/(float)iMax) * (ySettingWindowSize -
  9538. yClipWindowSize))) {
  9539. UINT nNewPos = (UINT)
  9540. ( ((float) (nExtra - (ySettingWindowSize - rcCtrl.bottom)) / (float) nExtra) * iMax);
  9541. SetScrollPos(hwndClip,SB_VERT,nNewPos,TRUE);
  9542. ProcessScrollBar(hwndClip,MAKELPARAM(SB_THUMBTRACK,nNewPos), TRUE);
  9543. return;
  9544. }
  9545. // if top of control is out of view, scroll the settings window down
  9546. if ((float) rcCtrl.top <
  9547. (float) ( (float) nPos/(float)iMax) * nExtra) {
  9548. UINT nNewPos = (UINT)
  9549. ( ((float) rcCtrl.top / (float) nExtra) * iMax);
  9550. SetScrollPos(hwndClip,SB_VERT,nNewPos,TRUE);
  9551. ProcessScrollBar(hwndClip,MAKELPARAM(SB_THUMBTRACK,nNewPos), TRUE);
  9552. return;
  9553. }
  9554. }
  9555. VOID CPolicySnapIn::ProcessScrollBar(HWND hWnd,WPARAM wParam,BOOL bVert)
  9556. {
  9557. UINT nPos = GetScrollPos(hWnd,bVert ? SB_VERT : SB_HORZ);
  9558. RECT rcParent,rcChild;
  9559. POLICYDLGINFO * pdi;
  9560. LPSETTINGSINFO lpSettingsInfo;
  9561. // get instance-specific struct from dialog
  9562. lpSettingsInfo = (LPSETTINGSINFO) GetWindowLongPtr(GetParent(hWnd), DWLP_USER);
  9563. if (!lpSettingsInfo)
  9564. return;
  9565. pdi = lpSettingsInfo->pdi;
  9566. if (!pdi)
  9567. return;
  9568. if (LOWORD(wParam) == SB_ENDSCROLL)
  9569. return;
  9570. switch (LOWORD(wParam)) {
  9571. case SB_THUMBPOSITION:
  9572. case SB_THUMBTRACK:
  9573. nPos = HIWORD(wParam);
  9574. break;
  9575. case SB_TOP:
  9576. nPos = 0;
  9577. break;
  9578. case SB_BOTTOM:
  9579. nPos = 100;
  9580. break;
  9581. case SB_LINEUP:
  9582. if (nPos >= 10)
  9583. nPos -= 10;
  9584. else
  9585. nPos = 0;
  9586. break;
  9587. case SB_LINEDOWN:
  9588. if (nPos <= 90)
  9589. nPos += 10;
  9590. else
  9591. nPos = 100;
  9592. break;
  9593. case SB_PAGEUP:
  9594. if (nPos >= 30)
  9595. nPos -= 30;
  9596. else
  9597. nPos = 0;
  9598. break;
  9599. case SB_PAGEDOWN:
  9600. if (nPos <= 70)
  9601. nPos += 30;
  9602. else
  9603. nPos = 100;
  9604. break;
  9605. }
  9606. SetScrollPos(hWnd,bVert ? SB_VERT : SB_HORZ,nPos,TRUE);
  9607. GetClientRect(hWnd,&rcParent);
  9608. GetClientRect(pdi->hwndSettings,&rcChild);
  9609. if (bVert)
  9610. {
  9611. SetWindowPos(pdi->hwndSettings,NULL,0,-(int) ((( (float)
  9612. (rcChild.bottom-rcChild.top)-(rcParent.bottom-rcParent.top))
  9613. /100.0) * (float) nPos),rcChild.right,rcChild.bottom,SWP_NOZORDER |
  9614. SWP_NOSIZE);
  9615. }
  9616. else
  9617. {
  9618. SetWindowPos(pdi->hwndSettings,NULL,-(int) ((( (float)
  9619. (rcChild.right-rcChild.left)-(rcParent.right-rcParent.left))
  9620. /100.0) * (float) nPos),rcChild.top, rcChild.right,rcChild.bottom,SWP_NOZORDER |
  9621. SWP_NOSIZE);
  9622. }
  9623. }
  9624. /*******************************************************************
  9625. NAME: FreeSettingsControls
  9626. SYNOPSIS: Frees all settings controls
  9627. ********************************************************************/
  9628. VOID CPolicySnapIn::FreeSettingsControls(HWND hDlg)
  9629. {
  9630. UINT nIndex;
  9631. HGLOBAL hData;
  9632. POLICYDLGINFO * pdi;
  9633. LPSETTINGSINFO lpSettingsInfo;
  9634. // get instance-specific struct from dialog
  9635. lpSettingsInfo = (LPSETTINGSINFO) GetWindowLongPtr(hDlg, DWLP_USER);
  9636. if (!lpSettingsInfo)
  9637. return;
  9638. pdi = lpSettingsInfo->pdi;
  9639. if (!pdi)
  9640. return;
  9641. for (nIndex=0;nIndex<pdi->nControls;nIndex++) {
  9642. if (pdi->pControlTable[nIndex].dwType == STYPE_LISTBOX)
  9643. {
  9644. hData = (HGLOBAL) GetWindowLongPtr (pdi->pControlTable[nIndex].hwnd,
  9645. GWLP_USERDATA);
  9646. if (hData)
  9647. {
  9648. GlobalFree (hData);
  9649. }
  9650. }
  9651. DestroyWindow(pdi->pControlTable[nIndex].hwnd);
  9652. }
  9653. pdi->pCurrentSettings = NULL;
  9654. pdi->nControls = 0;
  9655. SetScrollRange(pdi->hwndSettings,SB_VERT,0,0,TRUE);
  9656. SetScrollRange(pdi->hwndSettings,SB_HORZ,0,0,TRUE);
  9657. }
  9658. /*******************************************************************
  9659. NAME: CreateSettingsControls
  9660. SYNOPSIS: Creates controls in settings window
  9661. NOTES: Looks at a table of SETTINGS structs to determine
  9662. type of control to create and type-specific information.
  9663. For some types, more than one control can be created
  9664. (for instance, edit fields get a static control with
  9665. the title followed by an edit field control).
  9666. ENTRY: hDlg - owner dialog
  9667. hTable - table of SETTINGS structs containing setting
  9668. control information
  9669. ********************************************************************/
  9670. BOOL CPolicySnapIn::CreateSettingsControls(HWND hDlg,SETTINGS * pSetting,BOOL fEnable)
  9671. {
  9672. LPBYTE pObjectData;
  9673. POLICYDLGINFO * pdi;
  9674. UINT xMax=0,yStart=SC_YSPACING,nHeight,nWidth,yMax,xWindowMax;
  9675. HWND hwndControl,hwndBuddy,hwndParent;
  9676. RECT rcParent;
  9677. DWORD dwType, dwStyle;
  9678. UINT uEnable = (fEnable ? 0 : WS_DISABLED);
  9679. WINDOWPLACEMENT wp;
  9680. LPSETTINGSINFO lpSettingsInfo;
  9681. // get instance-specific struct from dialog
  9682. lpSettingsInfo = (LPSETTINGSINFO) GetWindowLongPtr(hDlg, DWLP_USER);
  9683. if (!lpSettingsInfo)
  9684. return FALSE;
  9685. pdi = lpSettingsInfo->pdi;
  9686. if (!pdi)
  9687. return FALSE;
  9688. wp.length = sizeof(wp);
  9689. if (!GetWindowPlacement(GetDlgItem(hDlg,IDC_POLICY_SETTINGS),&wp))
  9690. return FALSE;
  9691. xWindowMax = wp.rcNormalPosition.right - wp.rcNormalPosition.left;
  9692. pdi->pCurrentSettings = pSetting;
  9693. while (pSetting) {
  9694. pObjectData = GETOBJECTDATAPTR(pSetting);
  9695. dwType = pSetting->dwType & STYPE_MASK;
  9696. nWidth = 0;
  9697. nHeight = 0;
  9698. switch (dwType) {
  9699. case STYPE_TEXT:
  9700. // create static text control
  9701. if (!(hwndControl = CreateSetting(pdi,(TCHAR *) szSTATIC,
  9702. (TCHAR *) (GETNAMEPTR(pSetting)),0,SSTYLE_STATIC | uEnable,0,
  9703. yStart,0,15,STYPE_TEXT,NO_DATA_INDEX,0, lpSettingsInfo->hFontDlg)))
  9704. return FALSE;
  9705. AdjustWindowToText(hwndControl,(TCHAR *) (GETNAMEPTR(pSetting))
  9706. ,SC_XSPACING,yStart,0,&nWidth,&nHeight, lpSettingsInfo->hFontDlg);
  9707. yStart += nHeight + SC_YSPACING;
  9708. nWidth += SC_XSPACING;
  9709. break;
  9710. case STYPE_CHECKBOX:
  9711. // create checkbox control
  9712. if (!(hwndControl = CreateSetting(pdi,(TCHAR *) szBUTTON,
  9713. (TCHAR *) (GETNAMEPTR(pSetting)),0,SSTYLE_CHECKBOX | uEnable,
  9714. 0,yStart,200,nHeight,STYPE_CHECKBOX,pSetting->uDataIndex,
  9715. pSetting, lpSettingsInfo->hFontDlg)))
  9716. return FALSE;
  9717. nWidth = 20;
  9718. AdjustWindowToText(hwndControl,(TCHAR *) (GETNAMEPTR(pSetting))
  9719. ,SC_XSPACING,yStart,0,&nWidth,&nHeight, lpSettingsInfo->hFontDlg);
  9720. yStart += nHeight + SC_YSPACING;
  9721. nWidth += SC_XSPACING;
  9722. break;
  9723. case STYPE_EDITTEXT:
  9724. case STYPE_COMBOBOX:
  9725. // create static text with setting name
  9726. if (!(hwndControl = CreateSetting(pdi,(TCHAR *) szSTATIC,
  9727. GETNAMEPTR(pSetting),0,SSTYLE_STATIC | uEnable,0,0,0,0,
  9728. STYPE_TEXT,NO_DATA_INDEX,0, lpSettingsInfo->hFontDlg)))
  9729. return FALSE;
  9730. AdjustWindowToText(hwndControl,
  9731. GETNAMEPTR(pSetting),SC_XSPACING,yStart,SC_YPAD,
  9732. &nWidth,&nHeight, lpSettingsInfo->hFontDlg);
  9733. nWidth += SC_XSPACING + 5;
  9734. if (nWidth + SC_EDITWIDTH> xWindowMax) {
  9735. // if next control will stick out of settings window,
  9736. // put it on the next line
  9737. if (nWidth > xMax)
  9738. xMax = nWidth;
  9739. yStart += nHeight + SC_YCONTROLWRAP;
  9740. nWidth = SC_XINDENT;
  9741. } else {
  9742. SetWindowPos(hwndControl,NULL,SC_XSPACING,(yStart + SC_YTEXTDROP),0,0,SWP_NOZORDER | SWP_NOSIZE);
  9743. }
  9744. // create edit field or combo box control
  9745. if (dwType == STYPE_EDITTEXT) {
  9746. hwndControl = CreateSetting(pdi,(TCHAR *) szEDIT,(TCHAR *) g_szNull,
  9747. WS_EX_CLIENTEDGE,SSTYLE_EDITTEXT | uEnable,nWidth,yStart,SC_EDITWIDTH,nHeight,
  9748. STYPE_EDITTEXT,pSetting->uDataIndex,pSetting, lpSettingsInfo->hFontDlg);
  9749. } else {
  9750. dwStyle = SSTYLE_COMBOBOX | uEnable;
  9751. if (pSetting->dwFlags & DF_NOSORT) {
  9752. dwStyle &= ~CBS_SORT;
  9753. }
  9754. hwndControl = CreateSetting(pdi,(TCHAR *) szCOMBOBOX,(TCHAR *)g_szNull,
  9755. WS_EX_CLIENTEDGE,dwStyle,nWidth,yStart,SC_EDITWIDTH,nHeight*6,
  9756. STYPE_COMBOBOX,pSetting->uDataIndex,pSetting, lpSettingsInfo->hFontDlg);
  9757. }
  9758. if (!hwndControl) return FALSE;
  9759. // limit the text length appropriately
  9760. if (dwType == STYPE_COMBOBOX) {
  9761. SendMessage(hwndControl,CB_LIMITTEXT,
  9762. (WPARAM) ((POLICYCOMBOBOXINFO *) pObjectData)->nMaxLen,0L);
  9763. } else {
  9764. SendMessage(hwndControl,EM_SETLIMITTEXT,
  9765. (WPARAM) ((EDITTEXTINFO *) pObjectData)->nMaxLen,0L);
  9766. }
  9767. if (dwType == STYPE_COMBOBOX &&
  9768. ((POLICYCOMBOBOXINFO *) pObjectData)->uOffsetSuggestions)
  9769. InsertComboboxItems(hwndControl,(TCHAR *) ((LPBYTE)pSetting +
  9770. ((POLICYCOMBOBOXINFO *) pObjectData)->uOffsetSuggestions));
  9771. yStart += (UINT) ((float) nHeight*1.3) + SC_YSPACING;
  9772. nWidth += SC_EDITWIDTH;
  9773. break;
  9774. case STYPE_NUMERIC:
  9775. // create static text for setting
  9776. if (!(hwndControl = CreateSetting(pdi,(TCHAR *) szSTATIC,
  9777. GETNAMEPTR(pSetting),0,
  9778. SSTYLE_STATIC | uEnable,0,0,0,0,STYPE_TEXT,NO_DATA_INDEX,0, lpSettingsInfo->hFontDlg)))
  9779. return FALSE;
  9780. AdjustWindowToText(hwndControl,
  9781. GETNAMEPTR(pSetting),SC_XSPACING,(yStart + SC_YTEXTDROP),SC_YPAD,
  9782. &nWidth,&nHeight, lpSettingsInfo->hFontDlg);
  9783. nWidth += SC_XSPACING + 5;
  9784. // create edit field
  9785. if (!(hwndBuddy = CreateSetting(pdi,(TCHAR *) szEDIT,
  9786. (TCHAR *) g_szNull,WS_EX_CLIENTEDGE,SSTYLE_EDITTEXT | uEnable,nWidth,yStart,SC_UPDOWNWIDTH,
  9787. nHeight,STYPE_NUMERIC,pSetting->uDataIndex,pSetting, lpSettingsInfo->hFontDlg)))
  9788. return FALSE;
  9789. //SendMessage(hwndBuddy,EM_LIMITTEXT,4,0);
  9790. nWidth += SC_UPDOWNWIDTH;
  9791. // create spin (up-down) control if specifed
  9792. if (((NUMERICINFO *)pObjectData)->uSpinIncrement) {
  9793. UDACCEL udAccel = {0,0};
  9794. UINT nMax,nMin;
  9795. if (!(hwndControl = CreateSetting(pdi,(TCHAR *) szUPDOWN,
  9796. (TCHAR *) g_szNull,WS_EX_CLIENTEDGE,SSTYLE_UPDOWN | UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_UNSIGNED | uEnable,nWidth,yStart,SC_UPDOWNWIDTH2,
  9797. nHeight,STYPE_TEXT | STYPE_NUMERIC,NO_DATA_INDEX,0, lpSettingsInfo->hFontDlg)))
  9798. return FALSE;
  9799. nWidth += SC_UPDOWNWIDTH2;
  9800. nMax = ((NUMERICINFO *) pObjectData)->uMaxValue;
  9801. nMin = ((NUMERICINFO *) pObjectData)->uMinValue;
  9802. udAccel.nInc = ((NUMERICINFO *) pObjectData)->uSpinIncrement;
  9803. SendMessage(hwndControl,UDM_SETBUDDY,(WPARAM) hwndBuddy,0L);
  9804. SendMessage(hwndControl,UDM_SETRANGE32,(WPARAM) nMin,(LPARAM) nMax);
  9805. SendMessage(hwndControl,UDM_SETACCEL,1,(LPARAM) &udAccel);
  9806. }
  9807. yStart += nHeight + SC_YSPACING;
  9808. break;
  9809. case STYPE_DROPDOWNLIST:
  9810. // create text description
  9811. if (!(hwndControl = CreateSetting(pdi,(TCHAR *) szSTATIC,
  9812. GETNAMEPTR(pSetting),0,
  9813. SSTYLE_STATIC | uEnable,0,0,0,0,STYPE_TEXT,NO_DATA_INDEX,0, lpSettingsInfo->hFontDlg)))
  9814. return FALSE;
  9815. AdjustWindowToText(hwndControl,
  9816. GETNAMEPTR(pSetting),SC_XSPACING,yStart,SC_YPAD,&nWidth,&nHeight, lpSettingsInfo->hFontDlg);
  9817. nWidth += SC_XLEADING + 5;
  9818. if (nWidth + SC_EDITWIDTH> xWindowMax) {
  9819. // if next control will stick out of settings window,
  9820. // put it on the next line
  9821. if (nWidth > xMax)
  9822. xMax = nWidth;
  9823. yStart += nHeight + SC_YCONTROLWRAP;
  9824. nWidth = SC_XINDENT;
  9825. } else {
  9826. SetWindowPos(hwndControl,NULL,SC_XSPACING,(yStart + SC_YTEXTDROP),0,0,SWP_NOZORDER | SWP_NOSIZE);
  9827. }
  9828. dwStyle = SSTYLE_DROPDOWNLIST | uEnable;
  9829. if (pSetting->dwFlags & DF_NOSORT) {
  9830. dwStyle &= ~CBS_SORT;
  9831. }
  9832. // create drop down listbox
  9833. hwndControl = CreateSetting(pdi,(TCHAR *) szCOMBOBOX,(TCHAR *) g_szNull,
  9834. WS_EX_CLIENTEDGE,dwStyle,nWidth,yStart,SC_EDITWIDTH,nHeight*6,
  9835. STYPE_DROPDOWNLIST,pSetting->uDataIndex,pSetting, lpSettingsInfo->hFontDlg);
  9836. if (!hwndControl) return FALSE;
  9837. nWidth += SC_EDITWIDTH;
  9838. {
  9839. // insert dropdown list items into control
  9840. UINT uOffset = pSetting->uOffsetObjectData,nIndex=0;
  9841. DROPDOWNINFO * pddi;
  9842. int iSel;
  9843. while (uOffset) {
  9844. pddi = (DROPDOWNINFO *) ( (LPBYTE) pSetting + uOffset);
  9845. iSel=(int)SendMessage(hwndControl,CB_ADDSTRING,0,(LPARAM)
  9846. ((LPBYTE) pSetting + pddi->uOffsetItemName));
  9847. if (iSel<0) return FALSE;
  9848. SendMessage(hwndControl,CB_SETITEMDATA,iSel,nIndex);
  9849. nIndex++;
  9850. uOffset = pddi->uOffsetNextDropdowninfo;
  9851. }
  9852. }
  9853. yStart += (UINT) ((float) nHeight*1.3) + 1;
  9854. break;
  9855. case STYPE_LISTBOX:
  9856. {
  9857. TCHAR szShow[50];
  9858. // create static text with description
  9859. if (!(hwndControl = CreateSetting(pdi,(TCHAR *) szSTATIC,
  9860. GETNAMEPTR(pSetting),0,
  9861. SSTYLE_STATIC | uEnable,0,0,0,0,STYPE_TEXT,NO_DATA_INDEX,0, lpSettingsInfo->hFontDlg)))
  9862. return FALSE;
  9863. AdjustWindowToText(hwndControl,GETNAMEPTR(pSetting),SC_XSPACING,yStart,
  9864. SC_YPAD,&nWidth,&nHeight, lpSettingsInfo->hFontDlg);
  9865. nWidth += SC_XLEADING;
  9866. if (nWidth + LISTBOX_BTN_WIDTH> xWindowMax) {
  9867. // if next control will stick out of settings window,
  9868. // put it on the next line
  9869. if (nWidth > xMax)
  9870. xMax = nWidth;
  9871. yStart += nHeight + SC_YCONTROLWRAP;
  9872. nWidth = SC_XINDENT;
  9873. } else {
  9874. SetWindowPos(hwndControl,NULL,SC_XSPACING,(yStart + SC_YTEXTDROP),0,0,SWP_NOZORDER | SWP_NOSIZE);
  9875. }
  9876. // create pushbutton to show listbox contents
  9877. LoadString(g_hInstance, IDS_LISTBOX_SHOW, szShow, ARRAYSIZE(szShow));
  9878. hwndControl = CreateSetting(pdi,(TCHAR *) szBUTTON,szShow,0,
  9879. SSTYLE_LBBUTTON | uEnable,nWidth+5,yStart,
  9880. LISTBOX_BTN_WIDTH,nHeight,STYPE_LISTBOX,
  9881. pSetting->uDataIndex,pSetting, lpSettingsInfo->hFontDlg);
  9882. if (!hwndControl) return FALSE;
  9883. SetWindowLongPtr(hwndControl,GWLP_USERDATA,0);
  9884. nWidth += LISTBOX_BTN_WIDTH + SC_XLEADING;
  9885. yStart += nHeight+1;
  9886. }
  9887. }
  9888. if (nWidth > xMax)
  9889. xMax = nWidth;
  9890. pSetting = (SETTINGS *) pSetting->pNext;
  9891. }
  9892. yMax = yStart - 1;
  9893. SetWindowPos(pdi->hwndSettings,NULL,0,0,xMax,yMax,SWP_NOZORDER);
  9894. hwndParent = GetParent(pdi->hwndSettings);
  9895. GetClientRect(hwndParent,&rcParent);
  9896. if (yMax > (UINT) rcParent.bottom-rcParent.top) {
  9897. SetScrollRange(hwndParent,SB_VERT,0,100,TRUE);
  9898. SetScrollPos(hwndParent,SB_VERT,0,TRUE);
  9899. ShowScrollBar(hwndParent,SB_VERT, TRUE);
  9900. } else {
  9901. SetScrollRange(hwndParent,SB_VERT,0,0,TRUE);
  9902. ShowScrollBar(hwndParent,SB_VERT, FALSE);
  9903. }
  9904. if (xMax > (UINT) rcParent.right-rcParent.left) {
  9905. SetScrollRange(hwndParent,SB_HORZ,0,100,TRUE);
  9906. SetScrollPos(hwndParent,SB_HORZ,0,TRUE);
  9907. ShowScrollBar(hwndParent,SB_HORZ, TRUE);
  9908. } else {
  9909. SetScrollRange(hwndParent,SB_HORZ,0,0,TRUE);
  9910. ShowScrollBar(hwndParent,SB_HORZ, FALSE);
  9911. }
  9912. return TRUE;
  9913. }
  9914. VOID CPolicySnapIn::InsertComboboxItems(HWND hwndControl,TCHAR * pSuggestionList)
  9915. {
  9916. while (*pSuggestionList) {
  9917. SendMessage(hwndControl,CB_ADDSTRING,0,(LPARAM) pSuggestionList);
  9918. pSuggestionList += lstrlen(pSuggestionList) + 1;
  9919. }
  9920. }
  9921. /*******************************************************************
  9922. NAME: CreateSettings
  9923. SYNOPSIS: Creates a control and add it to the table of settings
  9924. controls
  9925. ********************************************************************/
  9926. HWND CPolicySnapIn::CreateSetting(POLICYDLGINFO * pdi,TCHAR * pszClassName,TCHAR * pszWindowName,
  9927. DWORD dwExStyle,DWORD dwStyle,int x,int y,int cx,int cy,DWORD dwType,UINT uIndex,
  9928. SETTINGS * pSetting, HFONT hFontDlg)
  9929. {
  9930. HWND hwndControl;
  9931. if (!(hwndControl = CreateWindowEx(WS_EX_NOPARENTNOTIFY | dwExStyle,
  9932. pszClassName,pszWindowName,dwStyle,x,y,cx,cy,pdi->hwndSettings,NULL,
  9933. g_hInstance,NULL))) return NULL;
  9934. if (!SetWindowData(pdi,hwndControl,dwType,uIndex,pSetting)) {
  9935. DestroyWindow(hwndControl);
  9936. return NULL;
  9937. }
  9938. SendMessage(hwndControl,WM_SETFONT,(WPARAM) hFontDlg,MAKELPARAM(TRUE,0));
  9939. return hwndControl;
  9940. }
  9941. BOOL CPolicySnapIn::SetWindowData(POLICYDLGINFO * pdi,HWND hwndControl,DWORD dwType,
  9942. UINT uDataIndex,SETTINGS * pSetting)
  9943. {
  9944. POLICYCTRLINFO PolicyCtrlInfo;
  9945. int iCtrl;
  9946. PolicyCtrlInfo.hwnd = hwndControl;
  9947. PolicyCtrlInfo.dwType = dwType;
  9948. PolicyCtrlInfo.uDataIndex = uDataIndex;
  9949. PolicyCtrlInfo.pSetting = pSetting;
  9950. iCtrl = AddControlHwnd(pdi,&PolicyCtrlInfo);
  9951. if (iCtrl < 0) return FALSE;
  9952. SetWindowLong(hwndControl,GWL_ID,iCtrl + IDD_SETTINGCTRL);
  9953. return TRUE;
  9954. }
  9955. int CPolicySnapIn::AddControlHwnd(POLICYDLGINFO * pdi,POLICYCTRLINFO * pPolicyCtrlInfo)
  9956. {
  9957. int iRet;
  9958. DWORD dwNeeded;
  9959. POLICYCTRLINFO * pTemp;
  9960. // grow table if necessary
  9961. dwNeeded = (pdi->nControls+1) * sizeof(POLICYCTRLINFO);
  9962. if (dwNeeded > pdi->dwControlTableSize) {
  9963. pTemp = (POLICYCTRLINFO *) LocalReAlloc(pdi->pControlTable,
  9964. dwNeeded,LMEM_ZEROINIT | LMEM_MOVEABLE);
  9965. if (!pTemp) return (-1);
  9966. pdi->pControlTable = pTemp;
  9967. pdi->dwControlTableSize = dwNeeded;
  9968. }
  9969. pdi->pControlTable[pdi->nControls] = *pPolicyCtrlInfo;
  9970. iRet = (int) pdi->nControls;
  9971. (pdi->nControls)++;
  9972. return iRet;
  9973. }
  9974. BOOL CPolicySnapIn::AdjustWindowToText(HWND hWnd,TCHAR * szText,UINT xStart,UINT yStart,
  9975. UINT yPad,UINT * pnWidth,UINT * pnHeight, HFONT hFontDlg)
  9976. {
  9977. SIZE size;
  9978. if (GetTextSize(hWnd,szText,&size, hFontDlg))
  9979. {
  9980. *pnHeight =size.cy + yPad;
  9981. *pnWidth += size.cx;
  9982. SetWindowPos(hWnd,NULL,xStart,yStart,*pnWidth,*pnHeight,SWP_NOZORDER);
  9983. }
  9984. return FALSE;
  9985. }
  9986. BOOL CPolicySnapIn::GetTextSize(HWND hWnd,TCHAR * szText,SIZE * pSize, HFONT hFontDlg)
  9987. {
  9988. HDC hDC;
  9989. BOOL fRet;
  9990. if (!(hDC = GetDC(hWnd))) return FALSE;
  9991. SelectObject(hDC, hFontDlg);
  9992. fRet=GetTextExtentPoint(hDC,szText,lstrlen(szText),pSize);
  9993. ReleaseDC(hWnd,hDC);
  9994. return fRet;
  9995. }
  9996. //*************************************************************
  9997. //
  9998. // SaveSettings()
  9999. //
  10000. // Purpose: Saves the results of the settings
  10001. //
  10002. // Parameters:
  10003. //
  10004. //
  10005. // Return: TRUE if successful
  10006. // FALSE if an error occurs
  10007. //
  10008. //*************************************************************
  10009. HRESULT CPolicySnapIn::SaveSettings(HWND hDlg)
  10010. {
  10011. UINT nIndex;
  10012. POLICYDLGINFO * pdi;
  10013. LPSETTINGSINFO lpSettingsInfo;
  10014. SETTINGS * pSetting;
  10015. HKEY hKeyRoot;
  10016. DWORD dwTemp;
  10017. UINT uRet = ERROR_SUCCESS, uPolicyState;
  10018. int iSel, iIndex;
  10019. LPTSTR lpBuffer;
  10020. BOOL fTranslated;
  10021. NUMERICINFO * pNumericInfo;
  10022. HRESULT hr;
  10023. LPBYTE pObjectData;
  10024. BOOL fErase;
  10025. DROPDOWNINFO * pddi;
  10026. GUID guidRegistryExt = REGISTRY_EXTENSION_GUID;
  10027. GUID guidSnapinMach = CLSID_PolicySnapInMachine;
  10028. GUID guidSnapinUser = CLSID_PolicySnapInUser;
  10029. GUID ClientGUID;
  10030. LPTSTR lpClientGUID;
  10031. TCHAR szFormat[100];
  10032. TCHAR szMsg[150];
  10033. BOOL bFoundNone; // used in the listbox case alone
  10034. //
  10035. // Check for RSOP mode
  10036. //
  10037. if (m_pcd->m_bRSOP)
  10038. {
  10039. DebugMsg((DM_VERBOSE, TEXT("CPolicySnapIn::SaveSettings: Running in RSOP mode, nothing to save.")));
  10040. return S_OK;
  10041. }
  10042. //
  10043. // Check the dirty bit
  10044. //
  10045. if (!m_bDirty)
  10046. {
  10047. DebugMsg((DM_VERBOSE, TEXT("CPolicySnapIn::SaveSettings: No changes detected. Exiting successfully.")));
  10048. return S_OK;
  10049. }
  10050. // get instance-specific struct from dialog
  10051. lpSettingsInfo = (LPSETTINGSINFO) GetWindowLongPtr(hDlg, DWLP_USER);
  10052. if (!lpSettingsInfo)
  10053. return E_FAIL;
  10054. pdi = lpSettingsInfo->pdi;
  10055. if (!pdi)
  10056. return E_FAIL;
  10057. if (m_pcd->m_pGPTInformation->GetRegistryKey(
  10058. (m_pcd->m_bUserScope ? GPO_SECTION_USER : GPO_SECTION_MACHINE),
  10059. &hKeyRoot) != S_OK)
  10060. {
  10061. DebugMsg((DM_WARNING, TEXT("CPolicySnapIn::SaveSettings: Failed to get registry key handle.")));
  10062. return S_FALSE;
  10063. }
  10064. //
  10065. // Get the policy state
  10066. //
  10067. if (IsDlgButtonChecked (hDlg, IDC_NOCONFIG) == BST_CHECKED)
  10068. {
  10069. uPolicyState = BST_INDETERMINATE;
  10070. }
  10071. else if (IsDlgButtonChecked (hDlg, IDC_ENABLED) == BST_CHECKED)
  10072. {
  10073. uPolicyState = BST_CHECKED;
  10074. }
  10075. else
  10076. {
  10077. uPolicyState = BST_UNCHECKED;
  10078. }
  10079. if (uPolicyState == BST_INDETERMINATE)
  10080. {
  10081. fErase = TRUE;
  10082. }
  10083. else
  10084. {
  10085. fErase = FALSE;
  10086. }
  10087. //
  10088. // Validate the state of the parts
  10089. //
  10090. for (nIndex=0;nIndex<pdi->nControls;nIndex++)
  10091. {
  10092. pSetting = pdi->pControlTable[nIndex].pSetting;
  10093. if (pdi->pControlTable[nIndex].uDataIndex != NO_DATA_INDEX)
  10094. {
  10095. switch (pdi->pControlTable[nIndex].dwType)
  10096. {
  10097. case STYPE_CHECKBOX:
  10098. if (BST_CHECKED == uPolicyState)
  10099. {
  10100. pObjectData = GETOBJECTDATAPTR(pSetting);
  10101. if (!pObjectData)
  10102. {
  10103. return E_INVALIDARG;
  10104. }
  10105. }
  10106. break;
  10107. case STYPE_EDITTEXT:
  10108. case STYPE_COMBOBOX:
  10109. if (uPolicyState == BST_CHECKED)
  10110. {
  10111. dwTemp = (DWORD)SendMessage(pdi->pControlTable[nIndex].hwnd,
  10112. WM_GETTEXTLENGTH,0,0);
  10113. if (!dwTemp)
  10114. {
  10115. if (pSetting->dwFlags & DF_REQUIRED)
  10116. {
  10117. m_pcd->MsgBoxParam(hDlg,IDS_ENTRYREQUIRED,GETNAMEPTR(pSetting),
  10118. MB_ICONINFORMATION,MB_OK);
  10119. RegCloseKey (hKeyRoot);
  10120. return E_FAIL;
  10121. }
  10122. }
  10123. }
  10124. break;
  10125. case STYPE_NUMERIC:
  10126. if (uPolicyState == BST_CHECKED)
  10127. {
  10128. if (pSetting->dwFlags & DF_REQUIRED)
  10129. {
  10130. dwTemp = (DWORD)SendMessage(pdi->pControlTable[nIndex].hwnd,
  10131. WM_GETTEXTLENGTH,0,0);
  10132. if (!dwTemp)
  10133. {
  10134. if (pSetting->dwFlags & DF_REQUIRED)
  10135. {
  10136. m_pcd->MsgBoxParam(hDlg,IDS_ENTRYREQUIRED,GETNAMEPTR(pSetting),
  10137. MB_ICONINFORMATION,MB_OK);
  10138. RegCloseKey (hKeyRoot);
  10139. return E_FAIL;
  10140. }
  10141. }
  10142. }
  10143. uRet=GetDlgItemInt(pdi->hwndSettings,nIndex+IDD_SETTINGCTRL,
  10144. &fTranslated,FALSE);
  10145. if (!fTranslated)
  10146. {
  10147. m_pcd->MsgBoxParam(hDlg,IDS_INVALIDNUM,
  10148. GETNAMEPTR(pSetting),MB_ICONINFORMATION,
  10149. MB_OK);
  10150. SetFocus(pdi->pControlTable[nIndex].hwnd);
  10151. SendMessage(pdi->pControlTable[nIndex].hwnd,
  10152. EM_SETSEL,0,-1);
  10153. RegCloseKey (hKeyRoot);
  10154. return E_FAIL;
  10155. }
  10156. }
  10157. break;
  10158. case STYPE_DROPDOWNLIST:
  10159. if (uPolicyState == BST_CHECKED)
  10160. {
  10161. iSel = (int)SendMessage(pdi->pControlTable[nIndex].hwnd,
  10162. CB_GETCURSEL,0,0L);
  10163. iSel = (int)SendMessage(pdi->pControlTable[nIndex].hwnd,
  10164. CB_GETITEMDATA,iSel,0L);
  10165. if (iSel < 0)
  10166. {
  10167. m_pcd->MsgBoxParam(hDlg,IDS_ENTRYREQUIRED,GETNAMEPTR(pSetting),
  10168. MB_ICONINFORMATION,MB_OK);
  10169. SetFocus(pdi->pControlTable[nIndex].hwnd);
  10170. RegCloseKey (hKeyRoot);
  10171. return E_FAIL;
  10172. }
  10173. }
  10174. else
  10175. {
  10176. iSel = 0;
  10177. }
  10178. pddi = (DROPDOWNINFO *) GETOBJECTDATAPTR(pSetting);
  10179. iIndex = 0;
  10180. // walk the chain of DROPDOWNINFO structs to find the entry that
  10181. // we want to write. (for value n, find the nth struct)
  10182. while (iIndex < iSel)
  10183. {
  10184. // selected val is higher than # of structs in chain,
  10185. // should never happen but check just in case...
  10186. if (!pddi->uOffsetNextDropdowninfo)
  10187. {
  10188. RegCloseKey (hKeyRoot);
  10189. return ERROR_NOT_ENOUGH_MEMORY;
  10190. }
  10191. pddi = (DROPDOWNINFO *)
  10192. ((LPBYTE) pSetting + pddi->uOffsetNextDropdowninfo);
  10193. iIndex++;
  10194. }
  10195. break;
  10196. case STYPE_LISTBOX:
  10197. HGLOBAL hData = (HGLOBAL)GetWindowLongPtr (pdi->pControlTable[nIndex].hwnd, GWLP_USERDATA);
  10198. BOOL bEnabled;
  10199. WCHAR *pszData;
  10200. bFoundNone = FALSE;
  10201. bEnabled = (uPolicyState == BST_INDETERMINATE) ? FALSE : TRUE;
  10202. if ((bEnabled) && (!hData))
  10203. {
  10204. bFoundNone = TRUE;
  10205. }
  10206. else if (bEnabled)
  10207. {
  10208. pszData = (TCHAR *)GlobalLock (hData);
  10209. GlobalUnlock(hData);
  10210. // if there are no items at all
  10211. if (!(*pszData))
  10212. {
  10213. bFoundNone = TRUE;
  10214. }
  10215. pszData = NULL;
  10216. }
  10217. // if the policy is enabled and no values are set
  10218. if ((uPolicyState == BST_CHECKED) && (bFoundNone))
  10219. {
  10220. m_pcd->MsgBoxParam(hDlg,IDS_ENTRYREQUIRED,GETNAMEPTR(pSetting),
  10221. MB_ICONINFORMATION,MB_OK);
  10222. SetFocus(pdi->pControlTable[nIndex].hwnd);
  10223. RegCloseKey (hKeyRoot);
  10224. return E_FAIL;
  10225. }
  10226. break;
  10227. }
  10228. }
  10229. }
  10230. //
  10231. // Save the overall policy state
  10232. //
  10233. if (uPolicyState != BST_INDETERMINATE)
  10234. {
  10235. if (uPolicyState == BST_CHECKED)
  10236. dwTemp = 1;
  10237. else
  10238. dwTemp = 0;
  10239. if (dwTemp && m_pCurrentPolicy->uOffsetValue_On)
  10240. {
  10241. uRet= WriteCustomValue(hKeyRoot,GETKEYNAMEPTR(m_pCurrentPolicy),GETVALUENAMEPTR(m_pCurrentPolicy),
  10242. (STATEVALUE *) ((LPBYTE) m_pCurrentPolicy + m_pCurrentPolicy->uOffsetValue_On),
  10243. fErase);
  10244. }
  10245. else if (!dwTemp && m_pCurrentPolicy->uOffsetValue_Off)
  10246. {
  10247. uRet= WriteCustomValue(hKeyRoot,GETKEYNAMEPTR(m_pCurrentPolicy),GETVALUENAMEPTR(m_pCurrentPolicy),
  10248. (STATEVALUE *) ((LPBYTE) m_pCurrentPolicy + m_pCurrentPolicy->uOffsetValue_Off),
  10249. fErase);
  10250. }
  10251. else
  10252. {
  10253. if (m_pCurrentPolicy->uOffsetValueName)
  10254. {
  10255. uRet=WriteStandardValue(hKeyRoot,GETKEYNAMEPTR(m_pCurrentPolicy),GETVALUENAMEPTR(m_pCurrentPolicy),
  10256. (TABLEENTRY *)m_pCurrentPolicy,dwTemp,fErase,FALSE);
  10257. }
  10258. else
  10259. {
  10260. uRet = ERROR_SUCCESS;
  10261. }
  10262. }
  10263. if (uRet == ERROR_SUCCESS)
  10264. {
  10265. uRet = ProcessCheckboxActionLists(hKeyRoot,(TABLEENTRY *)m_pCurrentPolicy,
  10266. GETKEYNAMEPTR(m_pCurrentPolicy),dwTemp,FALSE, !dwTemp, TRUE);
  10267. }
  10268. else
  10269. {
  10270. DebugMsg((DM_WARNING, TEXT("CPolicySnapIn::SaveSettings: Failed to set registry value with %d."), uRet));
  10271. }
  10272. }
  10273. else
  10274. {
  10275. if (m_pCurrentPolicy->uOffsetValueName)
  10276. {
  10277. uRet=WriteStandardValue(hKeyRoot,GETKEYNAMEPTR(m_pCurrentPolicy),GETVALUENAMEPTR(m_pCurrentPolicy),
  10278. (TABLEENTRY *)m_pCurrentPolicy,0,TRUE,FALSE);
  10279. }
  10280. if (uRet == ERROR_SUCCESS)
  10281. {
  10282. uRet = ProcessCheckboxActionLists(hKeyRoot,(TABLEENTRY *)m_pCurrentPolicy,
  10283. GETKEYNAMEPTR(m_pCurrentPolicy),0,TRUE,FALSE, TRUE);
  10284. }
  10285. }
  10286. //
  10287. // Save the state of the parts
  10288. //
  10289. for (nIndex=0;nIndex<pdi->nControls;nIndex++)
  10290. {
  10291. pSetting = pdi->pControlTable[nIndex].pSetting;
  10292. if (pdi->pControlTable[nIndex].uDataIndex != NO_DATA_INDEX)
  10293. {
  10294. switch (pdi->pControlTable[nIndex].dwType)
  10295. {
  10296. case STYPE_CHECKBOX:
  10297. dwTemp = (DWORD)SendMessage(pdi->pControlTable[nIndex].hwnd,BM_GETCHECK,0,0L);
  10298. pObjectData = GETOBJECTDATAPTR(pSetting);
  10299. if (!pObjectData)
  10300. {
  10301. if (BST_CHECKED == uPolicyState)
  10302. {
  10303. return E_INVALIDARG;
  10304. }
  10305. else
  10306. {
  10307. break;
  10308. }
  10309. }
  10310. if (dwTemp && ((CHECKBOXINFO *) pObjectData)->uOffsetValue_On)
  10311. {
  10312. uRet= WriteCustomValue(hKeyRoot,
  10313. GETKEYNAMEPTR(pSetting),
  10314. GETVALUENAMEPTR(pSetting),
  10315. (STATEVALUE *) ((LPBYTE) pSetting + ((CHECKBOXINFO *) pObjectData)->uOffsetValue_On),
  10316. fErase);
  10317. }
  10318. else if (!dwTemp && ((CHECKBOXINFO *) pObjectData)->uOffsetValue_Off)
  10319. {
  10320. uRet= WriteCustomValue(hKeyRoot,GETKEYNAMEPTR(pSetting),
  10321. GETVALUENAMEPTR(pSetting),
  10322. (STATEVALUE *) ((LPBYTE) pSetting + ((CHECKBOXINFO *) pObjectData)->uOffsetValue_Off),
  10323. fErase);
  10324. }
  10325. else
  10326. {
  10327. uRet=WriteStandardValue(hKeyRoot,
  10328. GETKEYNAMEPTR(pSetting),
  10329. GETVALUENAMEPTR(pSetting),
  10330. (TABLEENTRY *)pSetting,
  10331. dwTemp,
  10332. fErase,
  10333. FALSE);
  10334. }
  10335. if (uRet == ERROR_SUCCESS)
  10336. {
  10337. uRet = ProcessCheckboxActionLists(hKeyRoot,(TABLEENTRY *)pSetting,
  10338. GETKEYNAMEPTR(pSetting),
  10339. dwTemp,
  10340. fErase,
  10341. (uPolicyState == BST_UNCHECKED),
  10342. FALSE);
  10343. }
  10344. else
  10345. {
  10346. DebugMsg((DM_WARNING, TEXT("CPolicySnapIn::SaveSettings: Failed to set registry value with %d."), uRet));
  10347. }
  10348. break;
  10349. case STYPE_EDITTEXT:
  10350. case STYPE_COMBOBOX:
  10351. if (uPolicyState == BST_CHECKED)
  10352. {
  10353. dwTemp = (DWORD)SendMessage(pdi->pControlTable[nIndex].hwnd,
  10354. WM_GETTEXTLENGTH,0,0);
  10355. if (!dwTemp)
  10356. {
  10357. if (pSetting->dwFlags & DF_REQUIRED)
  10358. {
  10359. m_pcd->MsgBoxParam(hDlg,IDS_ENTRYREQUIRED,GETNAMEPTR(pSetting),
  10360. MB_ICONINFORMATION,MB_OK);
  10361. RegCloseKey (hKeyRoot);
  10362. return E_FAIL;
  10363. }
  10364. }
  10365. lpBuffer = (LPTSTR) LocalAlloc (LPTR, (dwTemp + 1) * sizeof(TCHAR));
  10366. if (lpBuffer)
  10367. {
  10368. SendMessage(pdi->pControlTable[nIndex].hwnd,WM_GETTEXT,
  10369. (dwTemp+1),(LPARAM) lpBuffer);
  10370. uRet = WriteCustomValue_W(hKeyRoot,
  10371. GETKEYNAMEPTR(pSetting),
  10372. GETVALUENAMEPTR(pSetting),
  10373. lpBuffer, 0, pSetting->dwFlags, FALSE);
  10374. if (uRet != ERROR_SUCCESS)
  10375. {
  10376. DebugMsg((DM_WARNING, TEXT("CPolicySnapIn::SaveSettings: Failed to set registry value with %d."), uRet));
  10377. }
  10378. LocalFree (lpBuffer);
  10379. }
  10380. else
  10381. {
  10382. DebugMsg((DM_WARNING, TEXT("CPolicySnapIn::SaveSettings: Failed to allocate memory with %d."),
  10383. GetLastError()));
  10384. }
  10385. }
  10386. else
  10387. {
  10388. WriteCustomValue_W(hKeyRoot,GETKEYNAMEPTR(pSetting),GETVALUENAMEPTR(pSetting),
  10389. (LPTSTR)g_szNull,0,
  10390. (uPolicyState == BST_UNCHECKED) ? VF_DELETE : 0,
  10391. fErase);
  10392. }
  10393. break;
  10394. case STYPE_NUMERIC:
  10395. if (uPolicyState == BST_CHECKED)
  10396. {
  10397. if (pSetting->dwFlags & DF_REQUIRED)
  10398. {
  10399. dwTemp = (DWORD)SendMessage(pdi->pControlTable[nIndex].hwnd,
  10400. WM_GETTEXTLENGTH,0,0);
  10401. if (!dwTemp)
  10402. {
  10403. if (pSetting->dwFlags & DF_REQUIRED)
  10404. {
  10405. m_pcd->MsgBoxParam(hDlg,IDS_ENTRYREQUIRED,GETNAMEPTR(pSetting),
  10406. MB_ICONINFORMATION,MB_OK);
  10407. RegCloseKey (hKeyRoot);
  10408. return E_FAIL;
  10409. }
  10410. }
  10411. }
  10412. uRet=GetDlgItemInt(pdi->hwndSettings,nIndex+IDD_SETTINGCTRL,
  10413. &fTranslated,FALSE);
  10414. // validate for max and min
  10415. pNumericInfo = (NUMERICINFO *) GETOBJECTDATAPTR(pSetting);
  10416. if (pNumericInfo && uRet < pNumericInfo->uMinValue)
  10417. {
  10418. LoadString(g_hInstance, IDS_NUMBERTOOSMALL, szFormat, ARRAYSIZE(szFormat));
  10419. hr = StringCchPrintf(szMsg, ARRAYSIZE(szMsg), szFormat, uRet, pNumericInfo->uMinValue, pNumericInfo->uMinValue, uRet);
  10420. ASSERT(SUCCEEDED(hr));
  10421. m_pcd->MsgBoxSz(hDlg,szMsg, MB_ICONINFORMATION, MB_OK);
  10422. uRet = pNumericInfo->uMinValue;
  10423. }
  10424. if (pNumericInfo && uRet > pNumericInfo->uMaxValue)
  10425. {
  10426. LoadString(g_hInstance, IDS_NUMBERTOOLARGE, szFormat, ARRAYSIZE(szFormat));
  10427. hr = StringCchPrintf (szMsg, ARRAYSIZE(szMsg), szFormat, uRet, pNumericInfo->uMaxValue, pNumericInfo->uMaxValue, uRet);
  10428. ASSERT(SUCCEEDED(hr));
  10429. m_pcd->MsgBoxSz(hDlg,szMsg, MB_ICONINFORMATION, MB_OK);
  10430. uRet = pNumericInfo->uMaxValue;
  10431. }
  10432. }
  10433. else
  10434. {
  10435. uRet = 0;
  10436. }
  10437. uRet=WriteStandardValue(hKeyRoot,GETKEYNAMEPTR(pSetting),
  10438. GETVALUENAMEPTR(pSetting),
  10439. (TABLEENTRY *)pSetting,uRet,
  10440. fErase,(uPolicyState == BST_UNCHECKED) ? FALSE : TRUE);
  10441. if (uRet != ERROR_SUCCESS)
  10442. {
  10443. DebugMsg((DM_WARNING, TEXT("CPolicySnapIn::SaveSettings: Failed to set registry value with %d."), uRet));
  10444. }
  10445. break;
  10446. case STYPE_DROPDOWNLIST:
  10447. if (uPolicyState == BST_CHECKED)
  10448. {
  10449. iSel = (int)SendMessage(pdi->pControlTable[nIndex].hwnd,
  10450. CB_GETCURSEL,0,0L);
  10451. iSel = (int)SendMessage(pdi->pControlTable[nIndex].hwnd,
  10452. CB_GETITEMDATA,iSel,0L);
  10453. if (iSel < 0)
  10454. {
  10455. m_pcd->MsgBoxParam(hDlg,IDS_ENTRYREQUIRED,GETNAMEPTR(pSetting),
  10456. MB_ICONINFORMATION,MB_OK);
  10457. SetFocus(pdi->pControlTable[nIndex].hwnd);
  10458. RegCloseKey (hKeyRoot);
  10459. return E_FAIL;
  10460. }
  10461. }
  10462. else
  10463. {
  10464. iSel = 0;
  10465. }
  10466. pddi = (DROPDOWNINFO *) GETOBJECTDATAPTR(pSetting);
  10467. iIndex = 0;
  10468. // walk the chain of DROPDOWNINFO structs to find the entry that
  10469. // we want to write. (for value n, find the nth struct)
  10470. while (iIndex < iSel) {
  10471. // selected val is higher than # of structs in chain,
  10472. // should never happen but check just in case...
  10473. if (!pddi->uOffsetNextDropdowninfo)
  10474. {
  10475. RegCloseKey (hKeyRoot);
  10476. return ERROR_NOT_ENOUGH_MEMORY;
  10477. }
  10478. pddi = (DROPDOWNINFO *)
  10479. ((LPBYTE) pSetting + pddi->uOffsetNextDropdowninfo);
  10480. iIndex++;
  10481. }
  10482. uRet=WriteCustomValue_W(hKeyRoot,GETKEYNAMEPTR(pSetting),GETVALUENAMEPTR(pSetting),
  10483. (LPTSTR) ((LPBYTE)pSetting+pddi->uOffsetValue),pddi->dwValue,
  10484. pddi->dwFlags | ((uPolicyState == BST_UNCHECKED) ? VF_DELETE : 0),
  10485. fErase);
  10486. if (uRet == ERROR_SUCCESS && pddi->uOffsetActionList) {
  10487. uRet=WriteActionList(hKeyRoot,(ACTIONLIST *) ( (LPBYTE)
  10488. pSetting + pddi->uOffsetActionList),GETKEYNAMEPTR(pSetting),
  10489. fErase, (uPolicyState == BST_UNCHECKED));
  10490. }
  10491. if (uRet != ERROR_SUCCESS)
  10492. {
  10493. DebugMsg((DM_WARNING, TEXT("CPolicySnapIn::SaveSettings: Failed to set registry value with %d."), uRet));
  10494. }
  10495. break;
  10496. case STYPE_LISTBOX:
  10497. bFoundNone = FALSE;
  10498. SaveListboxData((HGLOBAL)GetWindowLongPtr (pdi->pControlTable[nIndex].hwnd, GWLP_USERDATA),
  10499. pSetting, hKeyRoot, GETKEYNAMEPTR(pSetting), fErase,
  10500. ((uPolicyState == BST_INDETERMINATE) ? FALSE : TRUE),
  10501. (uPolicyState == BST_CHECKED), &bFoundNone);
  10502. // if the policy is enabled and no values are set
  10503. if ((uPolicyState == BST_CHECKED) && (bFoundNone)) {
  10504. m_pcd->MsgBoxParam(hDlg,IDS_ENTRYREQUIRED,GETNAMEPTR(pSetting),
  10505. MB_ICONINFORMATION,MB_OK);
  10506. SetFocus(pdi->pControlTable[nIndex].hwnd);
  10507. RegCloseKey (hKeyRoot);
  10508. return E_FAIL;
  10509. }
  10510. break;
  10511. }
  10512. if (pSetting->uOffsetClientExt)
  10513. {
  10514. lpClientGUID = (LPTSTR) ((BYTE *) pSetting + pSetting->uOffsetClientExt);
  10515. StringToGuid (lpClientGUID, &ClientGUID);
  10516. m_pcd->m_pGPTInformation->PolicyChanged(!m_pcd->m_bUserScope, TRUE, &ClientGUID,
  10517. m_pcd->m_bUserScope ? &guidSnapinUser
  10518. : &guidSnapinMach );
  10519. }
  10520. }
  10521. }
  10522. hr = m_pcd->m_pGPTInformation->PolicyChanged(!m_pcd->m_bUserScope, TRUE, &guidRegistryExt,
  10523. m_pcd->m_bUserScope ? &guidSnapinUser
  10524. : &guidSnapinMach );
  10525. if (FAILED(hr))
  10526. {
  10527. LPTSTR lpError;
  10528. if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
  10529. FORMAT_MESSAGE_IGNORE_INSERTS,
  10530. 0, hr, 0, (LPTSTR) &lpError, 0, NULL))
  10531. {
  10532. m_pcd->MsgBoxParam(hDlg,IDS_POLICYCHANGEDFAILED,lpError,
  10533. MB_ICONERROR, MB_OK);
  10534. LocalFree (lpError);
  10535. }
  10536. }
  10537. if (m_pCurrentPolicy->uOffsetClientExt)
  10538. {
  10539. lpClientGUID = (LPTSTR) ((BYTE *) m_pCurrentPolicy + m_pCurrentPolicy->uOffsetClientExt);
  10540. StringToGuid (lpClientGUID, &ClientGUID);
  10541. m_pcd->m_pGPTInformation->PolicyChanged(!m_pcd->m_bUserScope, TRUE, &ClientGUID,
  10542. m_pcd->m_bUserScope ? &guidSnapinUser
  10543. : &guidSnapinMach );
  10544. }
  10545. RegCloseKey (hKeyRoot);
  10546. SendMessage (m_hMsgWindow, WM_UPDATEITEM, 0, 0);
  10547. if (SUCCEEDED(hr))
  10548. {
  10549. m_bDirty = FALSE;
  10550. PostMessage (GetParent(hDlg), PSM_UNCHANGED, (WPARAM) hDlg, 0);
  10551. }
  10552. return S_OK;
  10553. }
  10554. VOID CPolicySnapIn::DeleteOldListboxData(SETTINGS * pSetting, HKEY hkeyRoot,
  10555. TCHAR * pszCurrentKeyName)
  10556. {
  10557. HGLOBAL hData = NULL;
  10558. LPTSTR lpData;
  10559. HKEY hKey;
  10560. TCHAR szValueName[MAX_PATH+1];
  10561. INT nItem=1;
  10562. LISTBOXINFO * pListboxInfo = (LISTBOXINFO *) GETOBJECTDATAPTR(pSetting);
  10563. HRESULT hr = S_OK;
  10564. //
  10565. // Open the target registry key
  10566. //
  10567. if (RegOpenKeyEx (hkeyRoot, pszCurrentKeyName, 0, KEY_WRITE, &hKey) != ERROR_SUCCESS)
  10568. {
  10569. return;
  10570. }
  10571. //
  10572. // Load the old listbox data
  10573. //
  10574. if (LoadListboxData((TABLEENTRY *) pSetting, hkeyRoot,
  10575. pszCurrentKeyName, NULL, &hData, NULL) == ERROR_SUCCESS)
  10576. {
  10577. if (hData)
  10578. {
  10579. //
  10580. // Delete the listbox's old data
  10581. //
  10582. if ((lpData = (LPTSTR) GlobalLock(hData)))
  10583. {
  10584. while (*lpData) {
  10585. if (pSetting->dwFlags & DF_EXPLICITVALNAME)
  10586. {
  10587. // if explicit valuename flag set, entries are stored
  10588. // <value name>\0<value>\0....<value name>\0<value>\0\0
  10589. // otherwise, entries are stored
  10590. // <value>\0<value>\0....<value>\0
  10591. RegDeleteValue (hKey, lpData);
  10592. lpData += lstrlen(lpData) +1;
  10593. lpData += lstrlen(lpData) +1;
  10594. }
  10595. else
  10596. {
  10597. //
  10598. // Value name is either same as the data, or a prefix
  10599. // with a number
  10600. //
  10601. if (!pListboxInfo->uOffsetPrefix)
  10602. {
  10603. // if no prefix set, then name = data
  10604. RegDeleteValue (hKey, lpData);
  10605. lpData += lstrlen(lpData) +1;
  10606. }
  10607. else
  10608. {
  10609. // value name is "<prefix><n>" where n=1,2,etc.
  10610. hr = StringCchPrintf(szValueName, ARRAYSIZE(szValueName), TEXT("%s%lu"),(TCHAR *) ((LPBYTE)pSetting +
  10611. pListboxInfo->uOffsetPrefix),nItem);
  10612. ASSERT(SUCCEEDED(hr));
  10613. RegDeleteValue (hKey, szValueName);
  10614. lpData += lstrlen(lpData) +1;
  10615. nItem++;
  10616. }
  10617. }
  10618. }
  10619. GlobalUnlock(hData);
  10620. }
  10621. GlobalFree (hData);
  10622. }
  10623. }
  10624. RegCloseKey (hKey);
  10625. }
  10626. UINT CPolicySnapIn::SaveListboxData(HGLOBAL hData,SETTINGS * pSetting,HKEY hkeyRoot,
  10627. TCHAR * pszCurrentKeyName,BOOL fErase,BOOL fMarkDeleted, BOOL bEnabled, BOOL * bFoundNone)
  10628. {
  10629. UINT uOffset,uRet,nItem=1;
  10630. HKEY hKey;
  10631. TCHAR * pszData,* pszName;
  10632. TCHAR szValueName[MAX_PATH+1];
  10633. DWORD cbValueName, dwDisp;
  10634. LISTBOXINFO * pListboxInfo = (LISTBOXINFO *) GETOBJECTDATAPTR(pSetting);
  10635. HRESULT hr = S_OK;
  10636. // these checks need to be done first before any other operations are done
  10637. if ((bEnabled) && (!hData)) {
  10638. *bFoundNone = TRUE;
  10639. return ERROR_INVALID_PARAMETER;
  10640. }
  10641. if (bEnabled) {
  10642. pszData = (TCHAR *)GlobalLock (hData);
  10643. // if there are no items at all
  10644. if (!(*pszData)) {
  10645. *bFoundNone = TRUE;
  10646. GlobalUnlock(hData);
  10647. return ERROR_INVALID_PARAMETER;
  10648. }
  10649. GlobalUnlock(hData);
  10650. pszData = NULL;
  10651. }
  10652. *bFoundNone = FALSE;
  10653. if (fErase)
  10654. {
  10655. RegDelnode (hkeyRoot, pszCurrentKeyName);
  10656. RegCleanUpValue (hkeyRoot, pszCurrentKeyName, TEXT("some value that won't exist"));
  10657. return ERROR_SUCCESS;
  10658. }
  10659. if (pSetting->dwFlags & DF_ADDITIVE)
  10660. {
  10661. DeleteOldListboxData(pSetting, hkeyRoot, pszCurrentKeyName);
  10662. }
  10663. else
  10664. {
  10665. RegDelnode (hkeyRoot, pszCurrentKeyName);
  10666. }
  10667. uRet = RegCreateKeyEx (hkeyRoot,pszCurrentKeyName,0,NULL,
  10668. REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL,
  10669. &hKey, &dwDisp);
  10670. if (uRet != ERROR_SUCCESS)
  10671. return uRet;
  10672. uRet=ERROR_SUCCESS;
  10673. if (fMarkDeleted)
  10674. {
  10675. //
  10676. // Write a control code that will cause
  10677. // all values under that key to be deleted when client downloads from the file.
  10678. // Don't do this if listbox is additive (DF_ADDITIVE), in that case whatever
  10679. // we write here will be dumped in along with existing values
  10680. //
  10681. if (!(pSetting->dwFlags & DF_ADDITIVE))
  10682. {
  10683. uRet=WriteRegistryStringValue(hkeyRoot,pszCurrentKeyName,
  10684. (TCHAR *) szDELVALS,
  10685. (TCHAR *) szNOVALUE, FALSE);
  10686. }
  10687. }
  10688. if (hData) {
  10689. pszData = (TCHAR *)GlobalLock (hData);
  10690. while (*pszData && (uRet == ERROR_SUCCESS))
  10691. {
  10692. UINT nLen = lstrlen(pszData)+1;
  10693. if (pSetting->dwFlags & DF_EXPLICITVALNAME)
  10694. {
  10695. // value name specified for each item
  10696. pszName = pszData; // value name
  10697. pszData += nLen; // now pszData points to value data
  10698. nLen = lstrlen(pszData)+1;
  10699. }
  10700. else
  10701. {
  10702. // value name is either same as the data, or a prefix
  10703. // with a number
  10704. if (!pListboxInfo->uOffsetPrefix) {
  10705. // if no prefix set, then name = data
  10706. pszName = pszData;
  10707. } else {
  10708. // value name is "<prefix><n>" where n=1,2,etc.
  10709. hr = StringCchPrintf(szValueName, ARRAYSIZE(szValueName), TEXT("%s%lu"),(TCHAR *) ((LPBYTE)pSetting +
  10710. pListboxInfo->uOffsetPrefix),nItem);
  10711. ASSERT(SUCCEEDED(hr));
  10712. pszName = szValueName;
  10713. nItem++;
  10714. }
  10715. }
  10716. uRet=RegSetValueEx(hKey,pszName,0,
  10717. (pSetting->dwFlags & DF_EXPANDABLETEXT) ?
  10718. REG_EXPAND_SZ : REG_SZ, (LPBYTE) pszData,
  10719. (lstrlen(pszData) + 1) * sizeof(TCHAR));
  10720. pszData += nLen;
  10721. }
  10722. GlobalUnlock (hData);
  10723. }
  10724. RegCloseKey(hKey);
  10725. return uRet;
  10726. }
  10727. UINT CPolicySnapIn::ProcessCheckboxActionLists(HKEY hkeyRoot,TABLEENTRY * pTableEntry,
  10728. TCHAR * pszCurrentKeyName,DWORD dwData,
  10729. BOOL fErase, BOOL fMarkAsDeleted,
  10730. BOOL bPolicy)
  10731. {
  10732. UINT uOffsetActionList_On,uOffsetActionList_Off,uRet=ERROR_SUCCESS;
  10733. if (bPolicy)
  10734. {
  10735. POLICY * pPolicy = (POLICY *) pTableEntry;
  10736. uOffsetActionList_On = pPolicy->uOffsetActionList_On;
  10737. uOffsetActionList_Off = pPolicy->uOffsetActionList_Off;
  10738. }
  10739. else
  10740. {
  10741. LPBYTE pObjectData = GETOBJECTDATAPTR(((SETTINGS *)pTableEntry));
  10742. if (!pObjectData) {
  10743. return ERROR_INVALID_PARAMETER;
  10744. }
  10745. uOffsetActionList_On = ((CHECKBOXINFO *) pObjectData)
  10746. ->uOffsetActionList_On;
  10747. uOffsetActionList_Off = ((CHECKBOXINFO *) pObjectData)
  10748. ->uOffsetActionList_Off;
  10749. }
  10750. if (dwData)
  10751. {
  10752. if (uOffsetActionList_On)
  10753. {
  10754. uRet = WriteActionList(hkeyRoot,(ACTIONLIST *)
  10755. ((LPBYTE) pTableEntry + uOffsetActionList_On),
  10756. pszCurrentKeyName,fErase,fMarkAsDeleted);
  10757. }
  10758. }
  10759. else
  10760. {
  10761. if (uOffsetActionList_Off)
  10762. {
  10763. uRet = WriteActionList(hkeyRoot,(ACTIONLIST *)
  10764. ((LPBYTE) pTableEntry + uOffsetActionList_Off),
  10765. pszCurrentKeyName,fErase,FALSE);
  10766. }
  10767. else
  10768. {
  10769. if (uOffsetActionList_On)
  10770. {
  10771. uRet = WriteActionList(hkeyRoot,(ACTIONLIST *)
  10772. ((LPBYTE) pTableEntry + uOffsetActionList_On),
  10773. pszCurrentKeyName,fErase,TRUE);
  10774. }
  10775. }
  10776. }
  10777. return uRet;
  10778. }
  10779. UINT CPolicySnapIn::WriteActionList(HKEY hkeyRoot,ACTIONLIST * pActionList,
  10780. LPTSTR pszCurrentKeyName,BOOL fErase, BOOL fMarkAsDeleted)
  10781. {
  10782. UINT nCount;
  10783. LPTSTR pszValueName;
  10784. LPTSTR pszValue=NULL;
  10785. UINT uRet;
  10786. ACTION * pAction = pActionList->Action;
  10787. for (nCount=0;nCount < pActionList->nActionItems; nCount++)
  10788. {
  10789. //
  10790. // Not every action in the list has to have a key name. But if one
  10791. // is specified, use it and it becomes the current key name for the
  10792. // list until we encounter another one.
  10793. //
  10794. if (pAction->uOffsetKeyName)
  10795. {
  10796. pszCurrentKeyName = (LPTSTR) ((LPBYTE)pActionList + pAction->uOffsetKeyName);
  10797. }
  10798. //
  10799. // Every action must have a value name, enforced at parse time
  10800. //
  10801. pszValueName = (LPTSTR) ((LPBYTE)pActionList + pAction->uOffsetValueName);
  10802. //
  10803. // String values have a string elsewhere in buffer
  10804. //
  10805. if (!pAction->dwFlags && pAction->uOffsetValue)
  10806. {
  10807. pszValue = (LPTSTR) ((LPBYTE)pActionList + pAction->uOffsetValue);
  10808. }
  10809. //
  10810. // Write the value in list
  10811. //
  10812. uRet=WriteCustomValue_W(hkeyRoot,pszCurrentKeyName,pszValueName,
  10813. pszValue,pAction->dwValue,
  10814. pAction->dwFlags | (fMarkAsDeleted ? VF_DELETE : 0),
  10815. fErase);
  10816. if (uRet != ERROR_SUCCESS)
  10817. {
  10818. return uRet;
  10819. }
  10820. pAction = (ACTION*) ((LPBYTE) pActionList + pAction->uOffsetNextAction);
  10821. }
  10822. return ERROR_SUCCESS;
  10823. }
  10824. /*******************************************************************
  10825. NAME: FindComboboxItemData
  10826. SYNOPSIS: Returns the index of item in combobox whose item data
  10827. is equal to nData. Returns -1 if no items have data
  10828. which matches.
  10829. ********************************************************************/
  10830. int CPolicySnapIn::FindComboboxItemData(HWND hwndControl,UINT nData)
  10831. {
  10832. UINT nIndex;
  10833. for (nIndex=0;nIndex<(UINT) SendMessage(hwndControl,CB_GETCOUNT,0,0L);
  10834. nIndex++) {
  10835. if ((UINT) SendMessage(hwndControl,CB_GETITEMDATA,nIndex,0L) == nData)
  10836. return (int) nIndex;
  10837. }
  10838. return -1;
  10839. }
  10840. //*************************************************************
  10841. //
  10842. // InitializeSettingsControls()
  10843. //
  10844. // Purpose: Initializes the settings controls
  10845. //
  10846. // Parameters:
  10847. //
  10848. //
  10849. // Return: TRUE if successful
  10850. // FALSE if an error occurs
  10851. //
  10852. //*************************************************************
  10853. HRESULT CPolicySnapIn::InitializeSettingsControls(HWND hDlg, BOOL fEnable)
  10854. {
  10855. UINT nIndex;
  10856. POLICYDLGINFO * pdi;
  10857. LPSETTINGSINFO lpSettingsInfo;
  10858. SETTINGS * pSetting;
  10859. HKEY hKeyRoot;
  10860. DWORD dwTemp, dwData, dwFlags, dwFoundSettings;
  10861. UINT uRet;
  10862. int iSel;
  10863. HGLOBAL hData;
  10864. LPTSTR lpBuffer;
  10865. BOOL fTranslated, fFound;
  10866. NUMERICINFO * pNumericInfo;
  10867. TCHAR szBuffer[MAXSTRLEN];
  10868. TCHAR szNewValueName[MAX_PATH+1];
  10869. BOOL bChangeableState;
  10870. HRESULT hr = S_OK;
  10871. // get instance-specific struct from dialog
  10872. lpSettingsInfo = (LPSETTINGSINFO) GetWindowLongPtr(hDlg, DWLP_USER);
  10873. if (!lpSettingsInfo)
  10874. return E_FAIL;
  10875. pdi = lpSettingsInfo->pdi;
  10876. if (!pdi)
  10877. return E_FAIL;
  10878. if (m_pcd->m_bRSOP)
  10879. {
  10880. hKeyRoot = (HKEY) 1;
  10881. }
  10882. else
  10883. {
  10884. if (m_pcd->m_pGPTInformation->GetRegistryKey(
  10885. (m_pcd->m_bUserScope ? GPO_SECTION_USER : GPO_SECTION_MACHINE),
  10886. &hKeyRoot) != S_OK)
  10887. {
  10888. DebugMsg((DM_WARNING, TEXT("CPolicySnapIn::InitializeSettingsControls: Failed to get registry key handle.")));
  10889. return S_FALSE;
  10890. }
  10891. }
  10892. for (nIndex=0;nIndex<pdi->nControls;nIndex++)
  10893. {
  10894. pSetting = pdi->pControlTable[nIndex].pSetting;
  10895. if (pdi->pControlTable[nIndex].uDataIndex != NO_DATA_INDEX)
  10896. {
  10897. switch (pdi->pControlTable[nIndex].dwType)
  10898. {
  10899. case STYPE_CHECKBOX:
  10900. if (fEnable)
  10901. {
  10902. CHECKBOXINFO * pcbi = (CHECKBOXINFO *) GETOBJECTDATAPTR(pSetting);
  10903. //
  10904. // First look for custom on/off values
  10905. //
  10906. dwTemp = 0;
  10907. fFound = FALSE;
  10908. dwFoundSettings = 0;
  10909. if (pcbi->uOffsetValue_On)
  10910. {
  10911. if (CompareCustomValue(hKeyRoot,GETKEYNAMEPTR(pSetting),GETVALUENAMEPTR(pSetting),
  10912. (STATEVALUE *) ((BYTE *) pSetting + pcbi->uOffsetValue_On),
  10913. &dwFoundSettings, NULL))
  10914. {
  10915. dwTemp = 1;
  10916. fFound = TRUE;
  10917. }
  10918. }
  10919. if (!fFound && pcbi->uOffsetValue_Off)
  10920. {
  10921. if (CompareCustomValue(hKeyRoot,GETKEYNAMEPTR(pSetting),GETVALUENAMEPTR(pSetting),
  10922. (STATEVALUE *) ((BYTE *) pSetting+ pcbi->uOffsetValue_Off),
  10923. &dwFoundSettings, NULL))
  10924. {
  10925. dwTemp = 0;
  10926. fFound = TRUE;
  10927. }
  10928. }
  10929. //
  10930. // Look for standard values if custom values have not been specified
  10931. //
  10932. if (!fFound &&
  10933. ReadStandardValue(hKeyRoot,GETKEYNAMEPTR(pSetting),GETVALUENAMEPTR(pSetting),
  10934. (TABLEENTRY*)pSetting,&dwTemp,&dwFoundSettings,NULL))
  10935. {
  10936. fFound = TRUE;
  10937. }
  10938. //
  10939. // If still not found, check for the def checked flag
  10940. //
  10941. if (!fFound)
  10942. {
  10943. if (pSetting->dwFlags & DF_USEDEFAULT)
  10944. {
  10945. fFound = TRUE;
  10946. dwTemp = 1;
  10947. }
  10948. }
  10949. if (fFound && dwTemp)
  10950. {
  10951. SendMessage(pdi->pControlTable[nIndex].hwnd,BM_SETCHECK,BST_CHECKED,0L);
  10952. }
  10953. else
  10954. {
  10955. SendMessage(pdi->pControlTable[nIndex].hwnd,BM_SETCHECK,BST_UNCHECKED,0L);
  10956. }
  10957. }
  10958. else
  10959. {
  10960. SendMessage(pdi->pControlTable[nIndex].hwnd,BM_SETCHECK,BST_UNCHECKED,0L);
  10961. }
  10962. break;
  10963. case STYPE_EDITTEXT:
  10964. case STYPE_COMBOBOX:
  10965. szBuffer[0] = TEXT('\0');
  10966. if (fEnable)
  10967. {
  10968. uRet = ReadRegistryStringValue(hKeyRoot,
  10969. GETKEYNAMEPTR(pSetting),
  10970. GETVALUENAMEPTR(pSetting),
  10971. szBuffer, ARRAYSIZE(szBuffer),NULL);
  10972. //
  10973. // Use default text if it exists
  10974. //
  10975. if (uRet != ERROR_SUCCESS)
  10976. {
  10977. if (pSetting->dwFlags & DF_USEDEFAULT)
  10978. {
  10979. LPTSTR pszDefaultText;
  10980. EDITTEXTINFO * peti = ((EDITTEXTINFO *) GETOBJECTDATAPTR(pSetting));
  10981. pszDefaultText = (LPTSTR) ((LPBYTE)pSetting + peti->uOffsetDefText);
  10982. hr = StringCchCopy (szBuffer, ARRAYSIZE(szBuffer), pszDefaultText);
  10983. ASSERT(SUCCEEDED(hr));
  10984. }
  10985. }
  10986. }
  10987. SendMessage (pdi->pControlTable[nIndex].hwnd, WM_SETTEXT,
  10988. 0, (LPARAM) szBuffer);
  10989. break;
  10990. case STYPE_NUMERIC:
  10991. if (fEnable)
  10992. {
  10993. if (ReadStandardValue(hKeyRoot,GETKEYNAMEPTR(pSetting),GETVALUENAMEPTR(pSetting),
  10994. (TABLEENTRY*)pSetting,&dwTemp,&dwFoundSettings,NULL) &&
  10995. (!(dwFoundSettings & FS_DELETED)))
  10996. {
  10997. SetDlgItemInt(pdi->hwndSettings,nIndex+IDD_SETTINGCTRL,
  10998. dwTemp,FALSE);
  10999. }
  11000. else
  11001. {
  11002. if (pSetting->dwFlags & DF_USEDEFAULT)
  11003. {
  11004. NUMERICINFO * pni = (NUMERICINFO *)GETOBJECTDATAPTR(pSetting);
  11005. SetDlgItemInt(pdi->hwndSettings,nIndex+IDD_SETTINGCTRL,
  11006. pni->uDefValue,FALSE);
  11007. }
  11008. }
  11009. }
  11010. else
  11011. {
  11012. SendMessage(pdi->pControlTable[nIndex].hwnd,WM_SETTEXT,0,(LPARAM) g_szNull);
  11013. }
  11014. break;
  11015. case STYPE_DROPDOWNLIST:
  11016. if (fEnable)
  11017. {
  11018. dwData = 0;
  11019. dwFlags = 0;
  11020. if (ReadCustomValue(hKeyRoot,GETKEYNAMEPTR(pSetting),
  11021. GETVALUENAMEPTR(pSetting),
  11022. szBuffer,ARRAYSIZE(szBuffer),
  11023. &dwData,&dwFlags, NULL) && (!(dwFlags & VF_DELETE)))
  11024. {
  11025. BOOL fMatch = FALSE;
  11026. //
  11027. // Walk the list of DROPDOWNINFO structs (one for each state),
  11028. // and see if the value we found matches the value for the state
  11029. //
  11030. if (pSetting->uOffsetObjectData)
  11031. {
  11032. DROPDOWNINFO * pddi = (DROPDOWNINFO *) GETOBJECTDATAPTR(pSetting);
  11033. iSel = 0;
  11034. do {
  11035. if (dwFlags == pddi->dwFlags)
  11036. {
  11037. if (pddi->dwFlags & VF_ISNUMERIC)
  11038. {
  11039. if (dwData == pddi->dwValue)
  11040. fMatch = TRUE;
  11041. }
  11042. else if (!pddi->dwFlags)
  11043. {
  11044. if (!lstrcmpi(szBuffer,(TCHAR *)((BYTE *)pSetting +
  11045. pddi->uOffsetValue)))
  11046. fMatch = TRUE;
  11047. }
  11048. }
  11049. if (!pddi->uOffsetNextDropdowninfo || fMatch)
  11050. break;
  11051. pddi = (DROPDOWNINFO *) ( (BYTE *) pSetting +
  11052. pddi->uOffsetNextDropdowninfo);
  11053. iSel++;
  11054. } while (!fMatch);
  11055. if (fMatch) {
  11056. SendMessage (pdi->pControlTable[nIndex].hwnd,
  11057. CB_SETCURSEL,
  11058. FindComboboxItemData(pdi->pControlTable[nIndex].hwnd, iSel),0);
  11059. }
  11060. }
  11061. }
  11062. else
  11063. {
  11064. if (pSetting->dwFlags & DF_USEDEFAULT)
  11065. {
  11066. DROPDOWNINFO * pddi = (DROPDOWNINFO *)GETOBJECTDATAPTR(pSetting);
  11067. if ( pddi )
  11068. {
  11069. SendMessage (pdi->pControlTable[nIndex].hwnd, CB_SETCURSEL,
  11070. FindComboboxItemData(pdi->pControlTable[nIndex].hwnd, pddi->uDefaultItemIndex),0);
  11071. }
  11072. }
  11073. }
  11074. }
  11075. else
  11076. {
  11077. SendMessage(pdi->pControlTable[nIndex].hwnd,CB_SETCURSEL,(UINT) -1,0L);
  11078. }
  11079. break;
  11080. case STYPE_LISTBOX:
  11081. hData = (HGLOBAL) GetWindowLongPtr (pdi->pControlTable[nIndex].hwnd, GWLP_USERDATA);
  11082. if (fEnable)
  11083. {
  11084. if (!hData)
  11085. {
  11086. if (LoadListboxData((TABLEENTRY *) pSetting, hKeyRoot,
  11087. GETKEYNAMEPTR(pSetting),NULL,
  11088. &hData, NULL) == ERROR_SUCCESS)
  11089. {
  11090. SetWindowLongPtr (pdi->pControlTable[nIndex].hwnd, GWLP_USERDATA, (LONG_PTR)hData);
  11091. }
  11092. }
  11093. }
  11094. else
  11095. {
  11096. if (hData)
  11097. {
  11098. GlobalFree (hData);
  11099. SetWindowLongPtr (pdi->pControlTable[nIndex].hwnd, GWLP_USERDATA, 0);
  11100. }
  11101. }
  11102. break;
  11103. }
  11104. }
  11105. //
  11106. // Decide if the part should be enabled or not
  11107. //
  11108. // Special case text, numeric and listbox controls.
  11109. // When the policy is disabled, text controls should still be enabled.
  11110. // Numeric controls are special because they use the NO_DATA_INDEX
  11111. // flag, so we need to check for those. Listbox controls are special
  11112. // in RSOP only.
  11113. //
  11114. bChangeableState = TRUE;
  11115. if (pdi->pControlTable[nIndex].uDataIndex == NO_DATA_INDEX)
  11116. {
  11117. if (pdi->pControlTable[nIndex].dwType != (STYPE_TEXT | STYPE_NUMERIC))
  11118. {
  11119. bChangeableState = FALSE;
  11120. }
  11121. }
  11122. if (pdi->pControlTable[nIndex].dwType == STYPE_LISTBOX)
  11123. {
  11124. if (m_pcd->m_bRSOP)
  11125. {
  11126. bChangeableState = FALSE;
  11127. }
  11128. }
  11129. if (bChangeableState)
  11130. {
  11131. if (m_pcd->m_bRSOP && (STYPE_EDITTEXT == pdi->pControlTable[nIndex].dwType) )
  11132. {
  11133. EnableWindow(pdi->pControlTable[nIndex].hwnd, TRUE);
  11134. SendMessage( pdi->pControlTable[nIndex].hwnd, EM_SETREADONLY, TRUE, 0);
  11135. }
  11136. else
  11137. EnableWindow(pdi->pControlTable[nIndex].hwnd, (m_pcd->m_bRSOP ? FALSE :fEnable));
  11138. }
  11139. else
  11140. EnableWindow(pdi->pControlTable[nIndex].hwnd,TRUE);
  11141. }
  11142. if (!m_pcd->m_bRSOP)
  11143. {
  11144. RegCloseKey (hKeyRoot);
  11145. }
  11146. return S_OK;
  11147. }
  11148. VOID CPolicySnapIn::ShowListbox(HWND hParent,SETTINGS * pSettings)
  11149. {
  11150. LISTBOXDLGINFO ListboxDlgInfo;
  11151. ListboxDlgInfo.pCS = this;
  11152. ListboxDlgInfo.pSettings = pSettings;
  11153. ListboxDlgInfo.hData = (HGLOBAL)GetWindowLongPtr (hParent, GWLP_USERDATA);
  11154. if (DialogBoxParam(g_hInstance,MAKEINTRESOURCE(IDD_POLICY_SHOWLISTBOX),hParent,
  11155. ShowListboxDlgProc,(LPARAM) &ListboxDlgInfo))
  11156. {
  11157. SetWindowLongPtr (hParent, GWLP_USERDATA, (LONG_PTR) ListboxDlgInfo.hData);
  11158. }
  11159. }
  11160. INT_PTR CALLBACK CPolicySnapIn::ShowListboxDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam,
  11161. LPARAM lParam)
  11162. {
  11163. switch (uMsg) {
  11164. case WM_INITDIALOG:
  11165. {
  11166. LISTBOXDLGINFO * pLBInfo = (LISTBOXDLGINFO *)lParam;
  11167. //
  11168. // Store away pointer to ListboxDlgInfo in window data
  11169. //
  11170. SetWindowLongPtr(hDlg,DWLP_USER,lParam);
  11171. if (!pLBInfo->pCS->InitShowlistboxDlg(hDlg)) {
  11172. pLBInfo->pCS->m_pcd->MsgBox(hDlg,IDS_ErrOUTOFMEMORY,MB_ICONEXCLAMATION,MB_OK);
  11173. EndDialog(hDlg,FALSE);
  11174. }
  11175. }
  11176. return TRUE;
  11177. case WM_COMMAND:
  11178. switch (wParam) {
  11179. case IDOK:
  11180. {
  11181. LISTBOXDLGINFO * pListboxDlgInfo =
  11182. (LISTBOXDLGINFO *) GetWindowLongPtr(hDlg,DWLP_USER);
  11183. if (!pListboxDlgInfo->pCS->m_pcd->m_bRSOP)
  11184. {
  11185. if (!pListboxDlgInfo->pCS->ProcessShowlistboxDlg(hDlg)) {
  11186. pListboxDlgInfo->pCS->m_pcd->MsgBox(hDlg,IDS_ErrOUTOFMEMORY,MB_ICONEXCLAMATION,MB_OK);
  11187. return FALSE;
  11188. }
  11189. }
  11190. EndDialog(hDlg,TRUE);
  11191. }
  11192. break;
  11193. case IDCANCEL:
  11194. EndDialog(hDlg,FALSE);
  11195. break;
  11196. case IDC_POLICY_ADD:
  11197. {
  11198. LISTBOXDLGINFO * pListboxDlgInfo =
  11199. (LISTBOXDLGINFO *) GetWindowLongPtr(hDlg,DWLP_USER);
  11200. pListboxDlgInfo->pCS->ListboxAdd(GetDlgItem(hDlg,IDC_POLICY_LISTBOX), (BOOL)
  11201. pListboxDlgInfo->pSettings->dwFlags & DF_EXPLICITVALNAME,
  11202. (BOOL)( ((LISTBOXINFO *)
  11203. GETOBJECTDATAPTR(pListboxDlgInfo->pSettings))->
  11204. uOffsetPrefix));
  11205. }
  11206. break;
  11207. case IDC_POLICY_REMOVE:
  11208. {
  11209. LISTBOXDLGINFO * pListboxDlgInfo =
  11210. (LISTBOXDLGINFO *) GetWindowLongPtr(hDlg,DWLP_USER);
  11211. pListboxDlgInfo->pCS->ListboxRemove(hDlg,GetDlgItem(hDlg,IDC_POLICY_LISTBOX));
  11212. }
  11213. break;
  11214. }
  11215. break;
  11216. case WM_NOTIFY:
  11217. if (wParam == IDC_POLICY_LISTBOX) {
  11218. if (((NMHDR FAR*)lParam)->code == LVN_ITEMCHANGED) {
  11219. LISTBOXDLGINFO * pListboxDlgInfo =
  11220. (LISTBOXDLGINFO *) GetWindowLongPtr(hDlg,DWLP_USER);
  11221. if (!pListboxDlgInfo->pCS->m_pcd->m_bRSOP)
  11222. {
  11223. pListboxDlgInfo->pCS->EnableShowListboxButtons(hDlg);
  11224. }
  11225. }
  11226. }
  11227. break;
  11228. }
  11229. return FALSE;
  11230. }
  11231. BOOL CPolicySnapIn::InitShowlistboxDlg(HWND hDlg)
  11232. {
  11233. LISTBOXDLGINFO * pListboxDlgInfo;
  11234. SETTINGS * pSettings;
  11235. LV_COLUMN lvc;
  11236. RECT rcListbox;
  11237. UINT uColWidth,uOffsetData;
  11238. HWND hwndListbox;
  11239. BOOL fSuccess=TRUE;
  11240. LONG lStyle;
  11241. TCHAR szBuffer[SMALLBUF];
  11242. LPTSTR lpData;
  11243. pListboxDlgInfo = (LISTBOXDLGINFO *)GetWindowLongPtr (hDlg, DWLP_USER);
  11244. if (!pListboxDlgInfo)
  11245. return FALSE;
  11246. pSettings = pListboxDlgInfo->pSettings;
  11247. hwndListbox = GetDlgItem(hDlg,IDC_POLICY_LISTBOX);
  11248. //
  11249. // Turn off the header if we don't need it
  11250. //
  11251. if (!m_pcd->m_bRSOP)
  11252. {
  11253. if (!(pSettings->dwFlags & DF_EXPLICITVALNAME))
  11254. {
  11255. lStyle = GetWindowLong (hwndListbox, GWL_STYLE);
  11256. lStyle |= LVS_NOCOLUMNHEADER;
  11257. SetWindowLong (hwndListbox, GWL_STYLE, lStyle);
  11258. }
  11259. }
  11260. SendMessage(hwndListbox, LVM_SETEXTENDEDLISTVIEWSTYLE, 0,
  11261. LVS_EX_FULLROWSELECT | LVS_EX_LABELTIP);
  11262. //
  11263. // Set the setting title in the dialog
  11264. //
  11265. SetDlgItemText(hDlg,IDC_POLICY_TITLE,GETNAMEPTR(pSettings));
  11266. GetClientRect(hwndListbox,&rcListbox);
  11267. uColWidth = rcListbox.right-rcListbox.left;
  11268. if (m_pcd->m_bRSOP)
  11269. {
  11270. if (pSettings->dwFlags & DF_EXPLICITVALNAME)
  11271. {
  11272. uColWidth /= 3;
  11273. }
  11274. else
  11275. {
  11276. uColWidth /= 2;
  11277. }
  11278. }
  11279. else
  11280. {
  11281. if (pSettings->dwFlags & DF_EXPLICITVALNAME)
  11282. {
  11283. uColWidth /= 2;
  11284. }
  11285. }
  11286. if (pSettings->dwFlags & DF_EXPLICITVALNAME) {
  11287. //
  11288. // add a 2nd column to the listview control
  11289. //
  11290. LoadString(g_hInstance,IDS_VALUENAME,szBuffer,ARRAYSIZE(szBuffer));
  11291. lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
  11292. lvc.fmt = LVCFMT_LEFT;
  11293. lvc.cx = uColWidth-1;
  11294. lvc.pszText = szBuffer;
  11295. lvc.cchTextMax = lstrlen(lvc.pszText)+1;
  11296. lvc.iSubItem = 0;
  11297. ListView_InsertColumn(hwndListbox,0,&lvc);
  11298. }
  11299. //
  11300. // Add a column to the listview control
  11301. //
  11302. LoadString(g_hInstance,IDS_VALUE,szBuffer,ARRAYSIZE(szBuffer));
  11303. lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
  11304. lvc.fmt = LVCFMT_LEFT;
  11305. lvc.cx = uColWidth;
  11306. lvc.pszText = szBuffer;
  11307. lvc.cchTextMax = lstrlen(lvc.pszText)+1;
  11308. lvc.iSubItem = (pSettings->dwFlags & DF_EXPLICITVALNAME ? 1 : 0);
  11309. ListView_InsertColumn(hwndListbox,lvc.iSubItem,&lvc);
  11310. if (m_pcd->m_bRSOP)
  11311. {
  11312. //
  11313. // Add the GPO Name column to the listview control
  11314. //
  11315. LoadString(g_hInstance,IDS_GPONAME,szBuffer,ARRAYSIZE(szBuffer));
  11316. lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
  11317. lvc.fmt = LVCFMT_LEFT;
  11318. lvc.cx = uColWidth;
  11319. lvc.pszText = szBuffer;
  11320. lvc.cchTextMax = lstrlen(lvc.pszText)+1;
  11321. lvc.iSubItem = (pSettings->dwFlags & DF_EXPLICITVALNAME ? 2 : 1);
  11322. ListView_InsertColumn(hwndListbox,lvc.iSubItem,&lvc);
  11323. }
  11324. if (m_pcd->m_bRSOP)
  11325. {
  11326. EnableWindow(GetDlgItem(hDlg,IDC_POLICY_REMOVE), FALSE);
  11327. EnableWindow(GetDlgItem(hDlg,IDC_POLICY_ADD), FALSE);
  11328. }
  11329. else
  11330. {
  11331. EnableShowListboxButtons(hDlg);
  11332. }
  11333. if (pListboxDlgInfo->hData)
  11334. {
  11335. //
  11336. // Insert the items from user's data buffer into the listbox
  11337. //
  11338. if ((lpData = (LPTSTR) GlobalLock(pListboxDlgInfo->hData)))
  11339. {
  11340. while (*lpData && fSuccess) {
  11341. LV_ITEM lvi;
  11342. lvi.pszText=lpData;
  11343. lvi.mask = LVIF_TEXT;
  11344. lvi.iItem=-1;
  11345. lvi.iSubItem=0;
  11346. lvi.cchTextMax = lstrlen(lpData)+1;
  11347. fSuccess=((lvi.iItem=ListView_InsertItem(hwndListbox,&lvi)) >= 0);
  11348. lpData += lstrlen(lpData) +1;
  11349. // if explicit valuename flag set, entries are stored
  11350. // <value name>\0<value>\0....<value name>\0<value>\0\0
  11351. // otherwise, entries are stored
  11352. // <value>\0<value>\0....<value>\0
  11353. if (pSettings->dwFlags & DF_EXPLICITVALNAME) {
  11354. if (fSuccess) {
  11355. if (*lpData) {
  11356. lvi.iSubItem=1;
  11357. lvi.pszText=lpData;
  11358. lvi.cchTextMax = lstrlen(lpData)+1;
  11359. fSuccess=(ListView_SetItem(hwndListbox,&lvi) >= 0);
  11360. }
  11361. lpData += lstrlen(lpData) +1;
  11362. }
  11363. }
  11364. if (m_pcd->m_bRSOP) {
  11365. if (fSuccess) {
  11366. if (*lpData) {
  11367. lvi.iSubItem=(pSettings->dwFlags & DF_EXPLICITVALNAME) ? 2 : 1;
  11368. lvi.pszText=lpData;
  11369. lvi.cchTextMax = lstrlen(lpData)+1;
  11370. fSuccess=(ListView_SetItem(hwndListbox,&lvi) >= 0);
  11371. }
  11372. lpData += lstrlen(lpData) +1;
  11373. }
  11374. }
  11375. }
  11376. GlobalUnlock(pListboxDlgInfo->hData);
  11377. }
  11378. else
  11379. {
  11380. fSuccess = FALSE;
  11381. }
  11382. }
  11383. return fSuccess;
  11384. }
  11385. BOOL CPolicySnapIn::ProcessShowlistboxDlg(HWND hDlg)
  11386. {
  11387. LISTBOXDLGINFO * pListboxDlgInfo = (LISTBOXDLGINFO *)
  11388. GetWindowLongPtr(hDlg,DWLP_USER); // get pointer to struct from window data
  11389. DWORD dwAlloc=1024 * sizeof(TCHAR),dwUsed=0;
  11390. HGLOBAL hBuf;
  11391. TCHAR * pBuf;
  11392. HWND hwndListbox = GetDlgItem(hDlg,IDC_POLICY_LISTBOX);
  11393. LV_ITEM lvi;
  11394. UINT nLen;
  11395. int nCount;
  11396. TCHAR pszText[MAX_PATH+1];
  11397. HRESULT hr = S_OK;
  11398. DWORD dwBufLen;
  11399. // allocate a temp buffer to read entries into
  11400. if (!(hBuf = GlobalAlloc(GHND,dwAlloc)) ||
  11401. !(pBuf = (TCHAR *) GlobalLock(hBuf))) {
  11402. if (hBuf)
  11403. GlobalFree(hBuf);
  11404. return FALSE;
  11405. }
  11406. lvi.mask = LVIF_TEXT;
  11407. lvi.iItem=0;
  11408. lvi.pszText = pszText;
  11409. lvi.cchTextMax = ARRAYSIZE(pszText);
  11410. nCount = ListView_GetItemCount(hwndListbox);
  11411. // retrieve the items out of listbox, pack into temp buffer
  11412. for (;lvi.iItem<nCount;lvi.iItem ++) {
  11413. lvi.iSubItem = 0;
  11414. if (ListView_GetItem(hwndListbox,&lvi)) {
  11415. nLen = lstrlen(lvi.pszText) + 1;
  11416. dwBufLen = dwUsed+nLen+4;
  11417. if (!(pBuf=ResizeBuffer(pBuf,hBuf,(dwBufLen) * sizeof(TCHAR),&dwAlloc)))
  11418. return ERROR_NOT_ENOUGH_MEMORY;
  11419. hr = StringCchCopy(pBuf+dwUsed, dwBufLen - dwUsed, lvi.pszText);
  11420. ASSERT(SUCCEEDED(hr));
  11421. dwUsed += nLen;
  11422. }
  11423. if (pListboxDlgInfo->pSettings->dwFlags & DF_EXPLICITVALNAME) {
  11424. lvi.iSubItem = 1;
  11425. if (ListView_GetItem(hwndListbox,&lvi)) {
  11426. nLen = lstrlen(lvi.pszText) + 1;
  11427. dwBufLen = dwUsed+nLen+4;
  11428. if (!(pBuf=ResizeBuffer(pBuf,hBuf,(dwBufLen) * sizeof(TCHAR),&dwAlloc)))
  11429. return ERROR_NOT_ENOUGH_MEMORY;
  11430. hr = StringCchCopy(pBuf+dwUsed, dwBufLen - dwUsed, lvi.pszText);
  11431. ASSERT(SUCCEEDED(hr));
  11432. dwUsed += nLen;
  11433. }
  11434. }
  11435. }
  11436. // doubly null-terminate the buffer... safe to do this because we
  11437. // tacked on the extra "+4" in the ResizeBuffer calls above
  11438. *(pBuf+dwUsed) = TEXT('\0');
  11439. dwUsed ++;
  11440. GlobalUnlock(hBuf);
  11441. if (pListboxDlgInfo->hData)
  11442. {
  11443. GlobalFree (pListboxDlgInfo->hData);
  11444. }
  11445. pListboxDlgInfo->hData = hBuf;
  11446. return TRUE;
  11447. }
  11448. VOID CPolicySnapIn::EnableShowListboxButtons(HWND hDlg)
  11449. {
  11450. BOOL fEnable;
  11451. // enable Remove button if there are any items selected
  11452. fEnable = (ListView_GetNextItem(GetDlgItem(hDlg,IDC_POLICY_LISTBOX),
  11453. -1,LVNI_SELECTED) >= 0);
  11454. EnableWindow(GetDlgItem(hDlg,IDC_POLICY_REMOVE),fEnable);
  11455. }
  11456. VOID CPolicySnapIn::ListboxRemove(HWND hDlg,HWND hwndListbox)
  11457. {
  11458. int nItem;
  11459. while ( (nItem=ListView_GetNextItem(hwndListbox,-1,LVNI_SELECTED))
  11460. >= 0) {
  11461. ListView_DeleteItem(hwndListbox,nItem);
  11462. }
  11463. EnableShowListboxButtons(hDlg);
  11464. }
  11465. VOID CPolicySnapIn::ListboxAdd(HWND hwndListbox, BOOL fExplicitValName,BOOL fValuePrefix)
  11466. {
  11467. ADDITEMINFO AddItemInfo;
  11468. LV_ITEM lvi;
  11469. ZeroMemory(&AddItemInfo,sizeof(AddItemInfo));
  11470. AddItemInfo.pCS = this;
  11471. AddItemInfo.fExplicitValName = fExplicitValName;
  11472. AddItemInfo.fValPrefix = fValuePrefix;
  11473. AddItemInfo.hwndListbox = hwndListbox;
  11474. //
  11475. // Bring up the appropriate add dialog-- one edit field ("type the thing
  11476. // to add") normally, two edit fields ("type the name of the thing, type
  11477. // the value of the thing") if the explicit value style is used
  11478. //
  11479. if (!DialogBoxParam(g_hInstance,MAKEINTRESOURCE((fExplicitValName ? IDD_POLICY_LBADD2 :
  11480. IDD_POLICY_LBADD)),hwndListbox,ListboxAddDlgProc,(LPARAM) &AddItemInfo))
  11481. return; // user cancelled
  11482. // add the item to the listbox
  11483. lvi.mask = LVIF_TEXT;
  11484. lvi.iItem=lvi.iSubItem=0;
  11485. lvi.pszText=(fExplicitValName ? AddItemInfo.szValueName :
  11486. AddItemInfo.szValueData);
  11487. lvi.cchTextMax = lstrlen(lvi.pszText)+1;
  11488. if ((lvi.iItem=ListView_InsertItem(hwndListbox,&lvi))<0) {
  11489. // if add fails, display out of memory error
  11490. m_pcd->MsgBox(hwndListbox,IDS_ErrOUTOFMEMORY,MB_ICONEXCLAMATION,MB_OK);
  11491. return;
  11492. }
  11493. if (fExplicitValName) {
  11494. lvi.iSubItem=1;
  11495. lvi.pszText=AddItemInfo.szValueData;
  11496. lvi.cchTextMax = lstrlen(lvi.pszText)+1;
  11497. if (ListView_SetItem(hwndListbox,&lvi) < 0) {
  11498. m_pcd->MsgBox(hwndListbox,IDS_ErrOUTOFMEMORY,MB_ICONEXCLAMATION,MB_OK);
  11499. return;
  11500. }
  11501. }
  11502. }
  11503. INT_PTR CALLBACK CPolicySnapIn::ListboxAddDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam,
  11504. LPARAM lParam)
  11505. {
  11506. switch (uMsg) {
  11507. case WM_INITDIALOG:
  11508. {
  11509. ADDITEMINFO * pAddItemInfo = (ADDITEMINFO *)lParam;
  11510. // store away pointer to additeminfo in window data
  11511. SetWindowLongPtr(hDlg,DWLP_USER,lParam);
  11512. SendDlgItemMessage(hDlg,IDC_POLICY_VALUENAME,EM_LIMITTEXT,MAX_PATH,0L);
  11513. SendDlgItemMessage(hDlg,IDC_POLICY_VALUEDATA,EM_LIMITTEXT,MAX_PATH,0L);
  11514. if (!pAddItemInfo->fExplicitValName) {
  11515. ShowWindow (GetDlgItem (hDlg, IDC_POLICY_VALUENAME), SW_HIDE);
  11516. }
  11517. }
  11518. break;
  11519. case WM_COMMAND:
  11520. switch (wParam) {
  11521. case IDOK:
  11522. {
  11523. ADDITEMINFO * pAddItemInfo = (ADDITEMINFO *)
  11524. GetWindowLongPtr(hDlg,DWLP_USER);
  11525. GetDlgItemText(hDlg,IDC_POLICY_VALUENAME,
  11526. pAddItemInfo->szValueName,
  11527. ARRAYSIZE(pAddItemInfo->szValueName));
  11528. GetDlgItemText(hDlg,IDC_POLICY_VALUEDATA,
  11529. pAddItemInfo->szValueData,
  11530. ARRAYSIZE(pAddItemInfo->szValueData));
  11531. // if explicit value names used, value name must
  11532. // not be empty, and it must be unique
  11533. if (pAddItemInfo->fExplicitValName) {
  11534. LV_FINDINFO lvfi;
  11535. int iSel;
  11536. if (!lstrlen(pAddItemInfo->szValueName)) {
  11537. // can't be empty
  11538. pAddItemInfo->pCS->m_pcd->MsgBox(hDlg,IDS_EMPTYVALUENAME,
  11539. MB_ICONINFORMATION,MB_OK);
  11540. SetFocus(GetDlgItem(hDlg,IDC_POLICY_VALUENAME));
  11541. return FALSE;
  11542. }
  11543. lvfi.flags = LVFI_STRING;
  11544. lvfi.psz = pAddItemInfo->szValueName;
  11545. iSel=ListView_FindItem(pAddItemInfo->hwndListbox,
  11546. -1,&lvfi);
  11547. if (iSel >= 0) {
  11548. // value name already used
  11549. pAddItemInfo->pCS->m_pcd->MsgBox(hDlg,IDS_VALUENAMENOTUNIQUE,
  11550. MB_ICONINFORMATION,MB_OK);
  11551. SetFocus(GetDlgItem(hDlg,IDC_POLICY_VALUENAME));
  11552. SendDlgItemMessage(hDlg,IDC_POLICY_VALUENAME,
  11553. EM_SETSEL,0,-1);
  11554. return FALSE;
  11555. }
  11556. } else if (!pAddItemInfo->fValPrefix) {
  11557. // if value name == value data, then value data
  11558. // must be unique
  11559. LV_FINDINFO lvfi;
  11560. int iSel;
  11561. if (!lstrlen(pAddItemInfo->szValueData)) {
  11562. // can't be empty
  11563. pAddItemInfo->pCS->m_pcd->MsgBox(hDlg,IDS_EMPTYVALUEDATA,
  11564. MB_ICONINFORMATION,MB_OK);
  11565. SetFocus(GetDlgItem(hDlg,IDC_POLICY_VALUEDATA));
  11566. return FALSE;
  11567. }
  11568. lvfi.flags = LVFI_STRING;
  11569. lvfi.psz = pAddItemInfo->szValueData;
  11570. iSel=ListView_FindItem(pAddItemInfo->hwndListbox,
  11571. -1,&lvfi);
  11572. if (iSel >= 0) {
  11573. // value name already used
  11574. pAddItemInfo->pCS->m_pcd->MsgBox(hDlg,IDS_VALUEDATANOTUNIQUE,
  11575. MB_ICONINFORMATION,MB_OK);
  11576. SetFocus(GetDlgItem(hDlg,IDC_POLICY_VALUEDATA));
  11577. SendDlgItemMessage(hDlg,IDC_POLICY_VALUEDATA,
  11578. EM_SETSEL,0,-1);
  11579. return FALSE;
  11580. }
  11581. }
  11582. else
  11583. {
  11584. if (!lstrlen(pAddItemInfo->szValueData)) {
  11585. // can't be empty
  11586. pAddItemInfo->pCS->m_pcd->MsgBox(hDlg,IDS_EMPTYVALUEDATA,
  11587. MB_ICONINFORMATION,MB_OK);
  11588. SetFocus(GetDlgItem(hDlg,IDC_POLICY_VALUEDATA));
  11589. return FALSE;
  11590. }
  11591. }
  11592. EndDialog(hDlg,TRUE);
  11593. }
  11594. break;
  11595. case IDCANCEL:
  11596. EndDialog(hDlg,FALSE);
  11597. break;
  11598. }
  11599. break;
  11600. }
  11601. return FALSE;
  11602. }
  11603. void CPolicySnapIn::InitializeFilterDialog (HWND hDlg)
  11604. {
  11605. INT iIndex;
  11606. RECT rect;
  11607. LV_COLUMN lvcol;
  11608. LONG lWidth;
  11609. DWORD dwCount = 0;
  11610. HWND hList = GetDlgItem(hDlg, IDC_FILTERLIST);
  11611. LPSUPPORTEDENTRY lpTemp;
  11612. LVITEM item;
  11613. //
  11614. // Count the number of Supported On strings
  11615. //
  11616. lpTemp = m_pcd->m_pSupportedStrings;
  11617. while (lpTemp)
  11618. {
  11619. lpTemp = lpTemp->pNext;
  11620. dwCount++;
  11621. }
  11622. //
  11623. // Decide on the column width
  11624. //
  11625. GetClientRect(hList, &rect);
  11626. if (dwCount > (DWORD)ListView_GetCountPerPage(hList))
  11627. {
  11628. lWidth = (rect.right - rect.left) - GetSystemMetrics(SM_CYHSCROLL);
  11629. }
  11630. else
  11631. {
  11632. lWidth = rect.right - rect.left;
  11633. }
  11634. //
  11635. // Insert the first column
  11636. //
  11637. memset(&lvcol, 0, sizeof(lvcol));
  11638. lvcol.mask = LVCF_FMT | LVCF_WIDTH;
  11639. lvcol.fmt = LVCFMT_LEFT;
  11640. lvcol.cx = lWidth;
  11641. ListView_InsertColumn(hList, 0, &lvcol);
  11642. //
  11643. // Turn on some listview features
  11644. //
  11645. SendMessage(hList, LVM_SETEXTENDEDLISTVIEWSTYLE, 0,
  11646. LVS_EX_FULLROWSELECT | LVS_EX_LABELTIP | LVS_EX_CHECKBOXES);
  11647. //
  11648. // Insert the Supported On strings
  11649. //
  11650. lpTemp = m_pcd->m_pSupportedStrings;
  11651. while (lpTemp)
  11652. {
  11653. ZeroMemory (&item, sizeof(item));
  11654. item.mask = LVIF_TEXT | LVIF_PARAM;
  11655. item.iItem = 0;
  11656. item.pszText = lpTemp->lpString;
  11657. item.lParam = (LPARAM) lpTemp;
  11658. iIndex = ListView_InsertItem (hList, &item);
  11659. if (iIndex > -1)
  11660. {
  11661. ZeroMemory (&item, sizeof(item));
  11662. item.mask = LVIF_STATE;
  11663. item.state = lpTemp->bEnabled ? INDEXTOSTATEIMAGEMASK(2) : INDEXTOSTATEIMAGEMASK(1);
  11664. item.stateMask = LVIS_STATEIMAGEMASK;
  11665. SendMessage (hList, LVM_SETITEMSTATE, (WPARAM)iIndex, (LPARAM)&item);
  11666. }
  11667. lpTemp = lpTemp->pNext;
  11668. }
  11669. //
  11670. // Select the first item
  11671. //
  11672. item.mask = LVIF_STATE;
  11673. item.iItem = 0;
  11674. item.iSubItem = 0;
  11675. item.state = LVIS_SELECTED | LVIS_FOCUSED;
  11676. item.stateMask = LVIS_SELECTED | LVIS_FOCUSED;
  11677. SendMessage (hList, LVM_SETITEMSTATE, 0, (LPARAM) &item);
  11678. //
  11679. // Initialize the checkboxes
  11680. //
  11681. if (m_pcd->m_bUseSupportedOnFilter)
  11682. {
  11683. CheckDlgButton (hDlg, IDC_SUPPORTEDOPTION, BST_CHECKED);
  11684. }
  11685. else
  11686. {
  11687. EnableWindow (GetDlgItem (hDlg, IDC_SUPPORTEDONTITLE), FALSE);
  11688. EnableWindow (GetDlgItem (hDlg, IDC_FILTERLIST), FALSE);
  11689. EnableWindow (GetDlgItem (hDlg, IDC_SELECTALL), FALSE);
  11690. EnableWindow (GetDlgItem (hDlg, IDC_DESELECTALL), FALSE);
  11691. }
  11692. if (m_pcd->m_bShowConfigPoliciesOnly)
  11693. {
  11694. CheckDlgButton (hDlg, IDC_SHOWCONFIG, BST_CHECKED);
  11695. }
  11696. if ((m_dwPolicyOnlyPolicy == 0) || (m_dwPolicyOnlyPolicy == 1))
  11697. {
  11698. if (m_dwPolicyOnlyPolicy == 1)
  11699. {
  11700. CheckDlgButton (hDlg, IDC_SHOWPOLICIES, BST_CHECKED);
  11701. }
  11702. EnableWindow (GetDlgItem (hDlg, IDC_SHOWPOLICIES), FALSE);
  11703. }
  11704. else
  11705. {
  11706. if (m_bPolicyOnly)
  11707. {
  11708. CheckDlgButton (hDlg, IDC_SHOWPOLICIES, BST_CHECKED);
  11709. }
  11710. }
  11711. }
  11712. INT_PTR CALLBACK CPolicySnapIn::FilterDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam,
  11713. LPARAM lParam)
  11714. {
  11715. CPolicySnapIn * pCS;
  11716. switch (uMsg)
  11717. {
  11718. case WM_INITDIALOG:
  11719. pCS = (CPolicySnapIn *) lParam;
  11720. SetWindowLongPtr (hDlg, DWLP_USER, (LONG_PTR) pCS);
  11721. if (pCS)
  11722. {
  11723. pCS->InitializeFilterDialog(hDlg);
  11724. }
  11725. break;
  11726. case WM_COMMAND:
  11727. switch (wParam)
  11728. {
  11729. case IDC_SUPPORTEDOPTION:
  11730. if (IsDlgButtonChecked (hDlg, IDC_SUPPORTEDOPTION) == BST_CHECKED)
  11731. {
  11732. EnableWindow (GetDlgItem (hDlg, IDC_SUPPORTEDONTITLE), TRUE);
  11733. EnableWindow (GetDlgItem (hDlg, IDC_FILTERLIST), TRUE);
  11734. EnableWindow (GetDlgItem (hDlg, IDC_SELECTALL), TRUE);
  11735. EnableWindow (GetDlgItem (hDlg, IDC_DESELECTALL), TRUE);
  11736. }
  11737. else
  11738. {
  11739. EnableWindow (GetDlgItem (hDlg, IDC_SUPPORTEDONTITLE), FALSE);
  11740. EnableWindow (GetDlgItem (hDlg, IDC_FILTERLIST), FALSE);
  11741. EnableWindow (GetDlgItem (hDlg, IDC_SELECTALL), FALSE);
  11742. EnableWindow (GetDlgItem (hDlg, IDC_DESELECTALL), FALSE);
  11743. }
  11744. break;
  11745. case IDC_SELECTALL:
  11746. {
  11747. LVITEM item;
  11748. ZeroMemory (&item, sizeof(item));
  11749. item.mask = LVIF_STATE;
  11750. item.state = INDEXTOSTATEIMAGEMASK(2);
  11751. item.stateMask = LVIS_STATEIMAGEMASK;
  11752. SendMessage (GetDlgItem (hDlg, IDC_FILTERLIST), LVM_SETITEMSTATE, (WPARAM)-1, (LPARAM)&item);
  11753. }
  11754. break;
  11755. case IDC_DESELECTALL:
  11756. {
  11757. LVITEM item;
  11758. ZeroMemory (&item, sizeof(item));
  11759. item.mask = LVIF_STATE;
  11760. item.state = INDEXTOSTATEIMAGEMASK(1);
  11761. item.stateMask = LVIS_STATEIMAGEMASK;
  11762. SendMessage (GetDlgItem (hDlg, IDC_FILTERLIST), LVM_SETITEMSTATE, (WPARAM)-1, (LPARAM)&item);
  11763. }
  11764. break;
  11765. case IDOK:
  11766. {
  11767. LVITEM item;
  11768. INT iIndex = 0;
  11769. LPSUPPORTEDENTRY lpItem;
  11770. pCS = (CPolicySnapIn *) GetWindowLongPtr(hDlg,DWLP_USER);
  11771. if (!pCS)
  11772. {
  11773. break;
  11774. }
  11775. if (IsDlgButtonChecked (hDlg, IDC_SUPPORTEDOPTION) == BST_CHECKED)
  11776. {
  11777. pCS->m_pcd->m_bUseSupportedOnFilter = TRUE;
  11778. while (TRUE)
  11779. {
  11780. ZeroMemory (&item, sizeof(item));
  11781. item.mask = LVIF_PARAM | LVIF_STATE;
  11782. item.iItem = iIndex;
  11783. item.stateMask = LVIS_STATEIMAGEMASK;
  11784. if (!ListView_GetItem (GetDlgItem (hDlg, IDC_FILTERLIST), &item))
  11785. {
  11786. break;
  11787. }
  11788. lpItem = (LPSUPPORTEDENTRY) item.lParam;
  11789. if (lpItem)
  11790. {
  11791. if (item.state == INDEXTOSTATEIMAGEMASK(2))
  11792. {
  11793. lpItem->bEnabled = TRUE;
  11794. }
  11795. else
  11796. {
  11797. lpItem->bEnabled = FALSE;
  11798. }
  11799. }
  11800. iIndex++;
  11801. }
  11802. }
  11803. else
  11804. {
  11805. pCS->m_pcd->m_bUseSupportedOnFilter = FALSE;
  11806. }
  11807. if (IsDlgButtonChecked (hDlg, IDC_SHOWCONFIG) == BST_CHECKED)
  11808. {
  11809. pCS->m_pcd->m_bShowConfigPoliciesOnly = TRUE;
  11810. }
  11811. else
  11812. {
  11813. pCS->m_pcd->m_bShowConfigPoliciesOnly = FALSE;
  11814. }
  11815. if (IsDlgButtonChecked (hDlg, IDC_SHOWPOLICIES) == BST_CHECKED)
  11816. {
  11817. pCS->m_bPolicyOnly = TRUE;
  11818. }
  11819. else
  11820. {
  11821. pCS->m_bPolicyOnly = FALSE;
  11822. }
  11823. EndDialog(hDlg,TRUE);
  11824. }
  11825. break;
  11826. case IDCANCEL:
  11827. EndDialog(hDlg,FALSE);
  11828. break;
  11829. }
  11830. break;
  11831. case WM_NOTIFY:
  11832. pCS = (CPolicySnapIn *) GetWindowLongPtr (hDlg, DWLP_USER);
  11833. if (!pCS) {
  11834. break;
  11835. }
  11836. switch (((NMHDR FAR*)lParam)->code)
  11837. {
  11838. case LVN_ITEMACTIVATE:
  11839. {
  11840. LPNMITEMACTIVATE pItem = (LPNMITEMACTIVATE) lParam;
  11841. LPSUPPORTEDENTRY lpItem;
  11842. LVITEM item;
  11843. HWND hLV = GetDlgItem(hDlg, IDC_FILTERLIST);
  11844. ZeroMemory (&item, sizeof(item));
  11845. item.mask = LVIF_STATE | LVIF_PARAM;
  11846. item.iItem = pItem->iItem;
  11847. item.stateMask = LVIS_STATEIMAGEMASK;
  11848. if (!ListView_GetItem (hLV, &item))
  11849. {
  11850. break;
  11851. }
  11852. lpItem = (LPSUPPORTEDENTRY) item.lParam;
  11853. if (!lpItem)
  11854. {
  11855. break;
  11856. }
  11857. if (lpItem)
  11858. {
  11859. if (item.state == INDEXTOSTATEIMAGEMASK(2))
  11860. {
  11861. item.state = INDEXTOSTATEIMAGEMASK(1);
  11862. }
  11863. else
  11864. {
  11865. item.state = INDEXTOSTATEIMAGEMASK(2);
  11866. }
  11867. item.mask = LVIF_STATE;
  11868. SendMessage (hLV, LVM_SETITEMSTATE, (WPARAM)pItem->iItem, (LPARAM)&item);
  11869. }
  11870. }
  11871. }
  11872. break;
  11873. case WM_HELP: // F1
  11874. WinHelp((HWND)((LPHELPINFO) lParam)->hItemHandle, HELP_FILE, HELP_WM_HELP,
  11875. (DWORD_PTR) (LPSTR) aFilteringHelpIds);
  11876. break;
  11877. case WM_CONTEXTMENU: // right mouse click
  11878. WinHelp((HWND) wParam, HELP_FILE, HELP_CONTEXTMENU,
  11879. (DWORD_PTR) (LPSTR) aFilteringHelpIds);
  11880. return (TRUE);
  11881. }
  11882. return FALSE;
  11883. }
  11884. unsigned int CPolicyDataObject::m_cfNodeType = RegisterClipboardFormat(CCF_NODETYPE);
  11885. unsigned int CPolicyDataObject::m_cfNodeTypeString = RegisterClipboardFormat(CCF_SZNODETYPE);
  11886. unsigned int CPolicyDataObject::m_cfDisplayName = RegisterClipboardFormat(CCF_DISPLAY_NAME);
  11887. unsigned int CPolicyDataObject::m_cfCoClass = RegisterClipboardFormat(CCF_SNAPIN_CLASSID);
  11888. unsigned int CPolicyDataObject::m_cfDescription = RegisterClipboardFormat(L"CCF_DESCRIPTION");
  11889. unsigned int CPolicyDataObject::m_cfHTMLDetails = RegisterClipboardFormat(L"CCF_HTML_DETAILS");
  11890. ///////////////////////////////////////////////////////////////////////////////
  11891. // //
  11892. // CPolicyDataObject implementation //
  11893. // //
  11894. ///////////////////////////////////////////////////////////////////////////////
  11895. CPolicyDataObject::CPolicyDataObject(CPolicyComponentData *pComponent)
  11896. {
  11897. m_cRef = 1;
  11898. InterlockedIncrement(&g_cRefThisDll);
  11899. m_pcd = pComponent;
  11900. m_pcd->AddRef();
  11901. m_type = CCT_UNINITIALIZED;
  11902. m_cookie = -1;
  11903. }
  11904. CPolicyDataObject::~CPolicyDataObject()
  11905. {
  11906. m_pcd->Release();
  11907. InterlockedDecrement(&g_cRefThisDll);
  11908. }
  11909. ///////////////////////////////////////////////////////////////////////////////
  11910. // //
  11911. // CPolicyDataObject object implementation (IUnknown) //
  11912. // //
  11913. ///////////////////////////////////////////////////////////////////////////////
  11914. HRESULT CPolicyDataObject::QueryInterface (REFIID riid, void **ppv)
  11915. {
  11916. if (IsEqualIID(riid, IID_IPolicyDataObject))
  11917. {
  11918. *ppv = (LPPOLICYDATAOBJECT)this;
  11919. m_cRef++;
  11920. return S_OK;
  11921. }
  11922. else if (IsEqualIID(riid, IID_IDataObject) ||
  11923. IsEqualIID(riid, IID_IUnknown))
  11924. {
  11925. *ppv = (LPDATAOBJECT)this;
  11926. m_cRef++;
  11927. return S_OK;
  11928. }
  11929. else
  11930. {
  11931. *ppv = NULL;
  11932. return E_NOINTERFACE;
  11933. }
  11934. }
  11935. ULONG CPolicyDataObject::AddRef (void)
  11936. {
  11937. return ++m_cRef;
  11938. }
  11939. ULONG CPolicyDataObject::Release (void)
  11940. {
  11941. if (--m_cRef == 0) {
  11942. delete this;
  11943. return 0;
  11944. }
  11945. return m_cRef;
  11946. }
  11947. ///////////////////////////////////////////////////////////////////////////////
  11948. // //
  11949. // CPolicyDataObject object implementation (IDataObject) //
  11950. // //
  11951. ///////////////////////////////////////////////////////////////////////////////
  11952. STDMETHODIMP CPolicyDataObject::GetDataHere(LPFORMATETC lpFormatetc, LPSTGMEDIUM lpMedium)
  11953. {
  11954. HRESULT hr = DV_E_CLIPFORMAT;
  11955. TCHAR szBuffer[300];
  11956. // Based on the CLIPFORMAT write data to the stream
  11957. const CLIPFORMAT cf = lpFormatetc->cfFormat;
  11958. if(cf == m_cfNodeType)
  11959. {
  11960. hr = CreateNodeTypeData(lpMedium);
  11961. }
  11962. else if(cf == m_cfNodeTypeString)
  11963. {
  11964. hr = CreateNodeTypeStringData(lpMedium);
  11965. }
  11966. else if (cf == m_cfDisplayName)
  11967. {
  11968. hr = CreateDisplayName(lpMedium);
  11969. }
  11970. else if (cf == m_cfCoClass)
  11971. {
  11972. hr = CreateCoClassID(lpMedium);
  11973. }
  11974. else if (cf == m_cfDescription)
  11975. {
  11976. hr = DV_E_TYMED;
  11977. if (lpMedium->tymed == TYMED_ISTREAM)
  11978. {
  11979. ULONG ulWritten;
  11980. if (m_cookie)
  11981. {
  11982. TABLEENTRY * pEntry = (TABLEENTRY *) m_cookie;
  11983. if (pEntry->dwType & ETYPE_POLICY)
  11984. {
  11985. POLICY * pPolicy = (POLICY *) m_cookie;
  11986. IStream *lpStream = lpMedium->pstm;
  11987. if (lpStream)
  11988. {
  11989. if (pPolicy->uOffsetHelp)
  11990. {
  11991. LPTSTR sz = (LPTSTR)((BYTE *)pPolicy + pPolicy->uOffsetHelp);
  11992. hr = lpStream->Write(sz, lstrlen(sz) * sizeof(TCHAR), &ulWritten);
  11993. }
  11994. if (!pPolicy->bTruePolicy)
  11995. {
  11996. LoadString (g_hInstance, IDS_PREFERENCE, szBuffer, ARRAYSIZE(szBuffer));
  11997. hr = lpStream->Write(szBuffer, lstrlen(szBuffer) * sizeof(TCHAR), &ulWritten);
  11998. }
  11999. }
  12000. }
  12001. else if (pEntry->dwType & ETYPE_CATEGORY)
  12002. {
  12003. CATEGORY * pCat = (CATEGORY *) m_cookie;
  12004. if (pCat->uOffsetHelp)
  12005. {
  12006. LPTSTR sz = (LPTSTR)((BYTE *)pCat + pCat->uOffsetHelp);
  12007. IStream *lpStream = lpMedium->pstm;
  12008. if (lpStream)
  12009. {
  12010. hr = lpStream->Write(sz, lstrlen(sz) * sizeof(TCHAR), &ulWritten);
  12011. }
  12012. }
  12013. }
  12014. else if (pEntry->dwType == (ETYPE_ROOT | ETYPE_REGITEM))
  12015. {
  12016. IStream *lpStream = lpMedium->pstm;
  12017. LoadString (g_hInstance, IDS_EXSETROOT_DESC, szBuffer, ARRAYSIZE(szBuffer));
  12018. if (lpStream)
  12019. {
  12020. hr = lpStream->Write(szBuffer, lstrlen(szBuffer) * sizeof(TCHAR), &ulWritten);
  12021. }
  12022. }
  12023. else if (pEntry->dwType == ETYPE_REGITEM)
  12024. {
  12025. IStream *lpStream = lpMedium->pstm;
  12026. LoadString (g_hInstance, IDS_EXSET_DESC, szBuffer, ARRAYSIZE(szBuffer));
  12027. if (lpStream)
  12028. {
  12029. REGITEM * pItem = (REGITEM *) m_cookie;
  12030. hr = lpStream->Write(szBuffer, lstrlen(szBuffer) * sizeof(TCHAR), &ulWritten);
  12031. if (!pItem->bTruePolicy)
  12032. {
  12033. LoadString (g_hInstance, IDS_PREFERENCE, szBuffer, ARRAYSIZE(szBuffer));
  12034. hr = lpStream->Write(szBuffer, lstrlen(szBuffer) * sizeof(TCHAR), &ulWritten);
  12035. }
  12036. }
  12037. }
  12038. }
  12039. else
  12040. {
  12041. LoadString (g_hInstance, IDS_POLICY_DESC, szBuffer, ARRAYSIZE(szBuffer));
  12042. IStream *lpStream = lpMedium->pstm;
  12043. if (lpStream)
  12044. {
  12045. hr = lpStream->Write(szBuffer, lstrlen(szBuffer) * sizeof(TCHAR), &ulWritten);
  12046. }
  12047. }
  12048. }
  12049. }
  12050. else if (cf == m_cfHTMLDetails)
  12051. {
  12052. hr = DV_E_TYMED;
  12053. if (lpMedium->tymed == TYMED_ISTREAM)
  12054. {
  12055. ULONG ulWritten;
  12056. if (m_cookie)
  12057. {
  12058. POLICY * pPolicy = (POLICY *) m_cookie;
  12059. if ((pPolicy->dwType & ETYPE_POLICY) || (pPolicy->dwType == ETYPE_REGITEM))
  12060. {
  12061. IStream *lpStream = lpMedium->pstm;
  12062. if(lpStream)
  12063. {
  12064. LPTSTR sz = GETSUPPORTEDPTR(pPolicy);
  12065. hr = lpStream->Write(g_szDisplayProperties, lstrlen(g_szDisplayProperties) * sizeof(TCHAR), &ulWritten);
  12066. if ((pPolicy->dwType & ETYPE_POLICY) && sz)
  12067. {
  12068. LoadString (g_hInstance, IDS_SUPPORTEDDESC, szBuffer, ARRAYSIZE(szBuffer));
  12069. hr = lpStream->Write(szBuffer, lstrlen(szBuffer) * sizeof(TCHAR), &ulWritten);
  12070. hr = lpStream->Write(sz, lstrlen(sz) * sizeof(TCHAR), &ulWritten);
  12071. }
  12072. }
  12073. }
  12074. }
  12075. }
  12076. }
  12077. return hr;
  12078. }
  12079. ///////////////////////////////////////////////////////////////////////////////
  12080. // //
  12081. // CPolicyDataObject object implementation (Internal functions) //
  12082. // //
  12083. ///////////////////////////////////////////////////////////////////////////////
  12084. HRESULT CPolicyDataObject::Create(LPVOID pBuffer, INT len, LPSTGMEDIUM lpMedium)
  12085. {
  12086. HRESULT hr = DV_E_TYMED;
  12087. // Do some simple validation
  12088. if (pBuffer == NULL || lpMedium == NULL)
  12089. return E_POINTER;
  12090. // Make sure the type medium is HGLOBAL
  12091. if (lpMedium->tymed == TYMED_HGLOBAL)
  12092. {
  12093. // Create the stream on the hGlobal passed in
  12094. LPSTREAM lpStream;
  12095. hr = CreateStreamOnHGlobal(lpMedium->hGlobal, FALSE, &lpStream);
  12096. if (SUCCEEDED(hr))
  12097. {
  12098. // Write to the stream the number of bytes
  12099. unsigned long written;
  12100. hr = lpStream->Write(pBuffer, len, &written);
  12101. // Because we told CreateStreamOnHGlobal with 'FALSE',
  12102. // only the stream is released here.
  12103. // Note - the caller (i.e. snap-in, object) will free the HGLOBAL
  12104. // at the correct time. This is according to the IDataObject specification.
  12105. lpStream->Release();
  12106. }
  12107. }
  12108. return hr;
  12109. }
  12110. HRESULT CPolicyDataObject::CreateNodeTypeData(LPSTGMEDIUM lpMedium)
  12111. {
  12112. LPRESULTITEM lpResultItem = (LPRESULTITEM) m_cookie;
  12113. if (m_cookie == -1)
  12114. return E_UNEXPECTED;
  12115. // Create the node type object in GUID format
  12116. if (m_pcd->m_bUserScope)
  12117. return Create((LPVOID)&NODEID_PolicyRootUser, sizeof(GUID), lpMedium);
  12118. else
  12119. return Create((LPVOID)&NODEID_PolicyRootMachine, sizeof(GUID), lpMedium);
  12120. }
  12121. HRESULT CPolicyDataObject::CreateNodeTypeStringData(LPSTGMEDIUM lpMedium)
  12122. {
  12123. TCHAR szNodeType[50];
  12124. if (m_cookie == -1)
  12125. return E_UNEXPECTED;
  12126. szNodeType[0] = TEXT('\0');
  12127. if (m_pcd->m_bUserScope)
  12128. StringFromGUID2 (NODEID_PolicyRootUser, szNodeType, 50);
  12129. else
  12130. StringFromGUID2 (NODEID_PolicyRootMachine, szNodeType, 50);
  12131. // Create the node type object in GUID string format
  12132. return Create((LPVOID)szNodeType, ((lstrlenW(szNodeType)+1) * sizeof(WCHAR)), lpMedium);
  12133. }
  12134. HRESULT CPolicyDataObject::CreateDisplayName(LPSTGMEDIUM lpMedium)
  12135. {
  12136. WCHAR szDisplayName[100] = {0};
  12137. LoadStringW (g_hInstance, IDS_POLICY_NAME, szDisplayName, 100);
  12138. return Create((LPVOID)szDisplayName, (lstrlenW(szDisplayName) + 1) * sizeof(WCHAR), lpMedium);
  12139. }
  12140. HRESULT CPolicyDataObject::CreateCoClassID(LPSTGMEDIUM lpMedium)
  12141. {
  12142. // Create the CoClass information
  12143. if (m_pcd->m_bUserScope)
  12144. return Create((LPVOID)&CLSID_PolicySnapInUser, sizeof(CLSID), lpMedium);
  12145. else
  12146. return Create((LPVOID)&CLSID_PolicySnapInMachine, sizeof(CLSID), lpMedium);
  12147. }
  12148. const TCHAR szViewDescript [] = TEXT("MMCViewExt 1.0 Object");
  12149. const TCHAR szViewGUID [] = TEXT("{B708457E-DB61-4C55-A92F-0D4B5E9B1224}");
  12150. const TCHAR szThreadingModel[] = TEXT("Apartment");
  12151. HRESULT RegisterPolicyExtension (REFGUID clsid, UINT uiStringId, REFGUID RootNodeID,
  12152. REFGUID ExtNodeId, LPTSTR lpSnapInNameIndirect)
  12153. {
  12154. TCHAR szSnapInKey[50];
  12155. TCHAR szSubKey[200];
  12156. TCHAR szSnapInName[100];
  12157. TCHAR szGUID[50];
  12158. DWORD dwDisp;
  12159. LONG lResult;
  12160. HKEY hKey;
  12161. HRESULT hr = S_OK;
  12162. //
  12163. // First register the extension
  12164. //
  12165. StringFromGUID2 (clsid, szSnapInKey, 50);
  12166. //
  12167. // Register SnapIn in HKEY_CLASSES_ROOT
  12168. //
  12169. LoadString (g_hInstance, uiStringId, szSnapInName, 100);
  12170. hr = StringCchPrintf (szSubKey, ARRAYSIZE(szSubKey), TEXT("CLSID\\%s"), szSnapInKey);
  12171. ASSERT(SUCCEEDED(hr));
  12172. lResult = RegCreateKeyEx (HKEY_CLASSES_ROOT, szSubKey, 0, NULL,
  12173. REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL,
  12174. &hKey, &dwDisp);
  12175. if (lResult != ERROR_SUCCESS) {
  12176. return SELFREG_E_CLASS;
  12177. }
  12178. RegSetValueEx (hKey, NULL, 0, REG_SZ, (LPBYTE)szSnapInName,
  12179. (lstrlen(szSnapInName) + 1) * sizeof(TCHAR));
  12180. RegCloseKey (hKey);
  12181. hr = StringCchPrintf (szSubKey, ARRAYSIZE(szSubKey), TEXT("CLSID\\%s\\InProcServer32"), szSnapInKey);
  12182. ASSERT(SUCCEEDED(hr));
  12183. lResult = RegCreateKeyEx (HKEY_CLASSES_ROOT, szSubKey, 0, NULL,
  12184. REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL,
  12185. &hKey, &dwDisp);
  12186. if (lResult != ERROR_SUCCESS) {
  12187. return SELFREG_E_CLASS;
  12188. }
  12189. RegSetValueEx (hKey, NULL, 0, REG_EXPAND_SZ, (LPBYTE)g_szSnapInLocation,
  12190. (lstrlen(g_szSnapInLocation) + 1) * sizeof(TCHAR));
  12191. RegSetValueEx (hKey, TEXT("ThreadingModel"), 0, REG_SZ, (LPBYTE)szThreadingModel,
  12192. (lstrlen(szThreadingModel) + 1) * sizeof(TCHAR));
  12193. RegCloseKey (hKey);
  12194. //
  12195. // Register SnapIn with MMC
  12196. //
  12197. hr = StringCchPrintf (szSubKey, ARRAYSIZE(szSubKey), TEXT("Software\\Microsoft\\MMC\\SnapIns\\%s"), szSnapInKey);
  12198. ASSERT(SUCCEEDED(hr));
  12199. lResult = RegCreateKeyEx (HKEY_LOCAL_MACHINE, szSubKey, 0, NULL,
  12200. REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL,
  12201. &hKey, &dwDisp);
  12202. if (lResult != ERROR_SUCCESS) {
  12203. return SELFREG_E_CLASS;
  12204. }
  12205. RegSetValueEx (hKey, TEXT("NameString"), 0, REG_SZ, (LPBYTE)szSnapInName,
  12206. (lstrlen(szSnapInName) + 1) * sizeof(TCHAR));
  12207. RegSetValueEx (hKey, TEXT("NameStringIndirect"), 0, REG_SZ, (LPBYTE)lpSnapInNameIndirect,
  12208. (lstrlen(lpSnapInNameIndirect) + 1) * sizeof(TCHAR));
  12209. RegCloseKey (hKey);
  12210. StringFromGUID2 (RootNodeID, szGUID, 50);
  12211. hr = StringCchPrintf (szSubKey, ARRAYSIZE(szSubKey), TEXT("Software\\Microsoft\\MMC\\SnapIns\\%s\\NodeTypes\\%s"),
  12212. szSnapInKey, szGUID);
  12213. ASSERT(SUCCEEDED(hr));
  12214. lResult = RegCreateKeyEx (HKEY_LOCAL_MACHINE, szSubKey, 0, NULL,
  12215. REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL,
  12216. &hKey, &dwDisp);
  12217. if (lResult != ERROR_SUCCESS) {
  12218. return SELFREG_E_CLASS;
  12219. }
  12220. RegCloseKey (hKey);
  12221. //
  12222. // Register in the NodeTypes key
  12223. //
  12224. StringFromGUID2 (RootNodeID, szGUID, 50);
  12225. hr = StringCchPrintf (szSubKey, ARRAYSIZE(szSubKey), TEXT("Software\\Microsoft\\MMC\\NodeTypes\\%s"), szGUID);
  12226. ASSERT(SUCCEEDED(hr));
  12227. lResult = RegCreateKeyEx (HKEY_LOCAL_MACHINE, szSubKey, 0, NULL,
  12228. REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL,
  12229. &hKey, &dwDisp);
  12230. if (lResult != ERROR_SUCCESS) {
  12231. return SELFREG_E_CLASS;
  12232. }
  12233. RegCloseKey (hKey);
  12234. //
  12235. // Register for the view extension
  12236. //
  12237. hr = StringCchCat (szSubKey, ARRAYSIZE(szSubKey), TEXT("\\Extensions\\View"));
  12238. ASSERT(SUCCEEDED(hr));
  12239. lResult = RegCreateKeyEx (HKEY_LOCAL_MACHINE, szSubKey, 0, NULL,
  12240. REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL,
  12241. &hKey, &dwDisp);
  12242. if (lResult != ERROR_SUCCESS) {
  12243. return SELFREG_E_CLASS;
  12244. }
  12245. RegSetValueEx (hKey, szViewGUID, 0, REG_SZ, (LPBYTE)szViewDescript,
  12246. (lstrlen(szViewDescript) + 1) * sizeof(TCHAR));
  12247. RegCloseKey (hKey);
  12248. //
  12249. // Register as an extension for various nodes
  12250. //
  12251. StringFromGUID2 (ExtNodeId, szGUID, 50);
  12252. hr = StringCchPrintf (szSubKey, ARRAYSIZE(szSubKey), TEXT("Software\\Microsoft\\MMC\\NodeTypes\\%s\\Extensions\\NameSpace"), szGUID);
  12253. ASSERT(SUCCEEDED(hr));
  12254. lResult = RegCreateKeyEx (HKEY_LOCAL_MACHINE, szSubKey, 0, NULL,
  12255. REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL,
  12256. &hKey, &dwDisp);
  12257. if (lResult != ERROR_SUCCESS) {
  12258. return SELFREG_E_CLASS;
  12259. }
  12260. RegSetValueEx (hKey, szSnapInKey, 0, REG_SZ, (LPBYTE)szSnapInName,
  12261. (lstrlen(szSnapInName) + 1) * sizeof(TCHAR));
  12262. RegCloseKey (hKey);
  12263. return S_OK;
  12264. }
  12265. HRESULT RegisterPolicy(void)
  12266. {
  12267. HRESULT hr;
  12268. hr = RegisterPolicyExtension (CLSID_PolicySnapInMachine, IDS_POLICY_NAME_MACHINE,
  12269. NODEID_PolicyRootMachine, NODEID_MachineRoot, TEXT("@gptext.dll,-20"));
  12270. if (hr == S_OK)
  12271. {
  12272. hr = RegisterPolicyExtension (CLSID_PolicySnapInUser, IDS_POLICY_NAME_USER,
  12273. NODEID_PolicyRootUser, NODEID_UserRoot, TEXT("@gptext.dll,-21"));
  12274. }
  12275. if (hr == S_OK)
  12276. {
  12277. hr = RegisterPolicyExtension (CLSID_RSOPolicySnapInMachine, IDS_POLICY_NAME_MACHINE,
  12278. NODEID_RSOPolicyRootMachine, NODEID_RSOPMachineRoot, TEXT("@gptext.dll,-20"));
  12279. }
  12280. if (hr == S_OK)
  12281. {
  12282. hr = RegisterPolicyExtension (CLSID_RSOPolicySnapInUser, IDS_POLICY_NAME_USER,
  12283. NODEID_RSOPolicyRootUser, NODEID_RSOPUserRoot, TEXT("@gptext.dll,-21"));
  12284. }
  12285. return hr;
  12286. }
  12287. HRESULT UnregisterPolicyExtension (REFGUID clsid, REFGUID RootNodeID, REFGUID ExtNodeId)
  12288. {
  12289. TCHAR szSnapInKey[50];
  12290. TCHAR szSubKey[200];
  12291. TCHAR szGUID[50];
  12292. LONG lResult;
  12293. HKEY hKey;
  12294. DWORD dwDisp;
  12295. HRESULT hr = S_OK;
  12296. //
  12297. // First unregister the extension
  12298. //
  12299. StringFromGUID2 (clsid, szSnapInKey, 50);
  12300. hr = StringCchPrintf (szSubKey, ARRAYSIZE(szSubKey), TEXT("CLSID\\%s"), szSnapInKey);
  12301. ASSERT(SUCCEEDED(hr));
  12302. RegDelnode (HKEY_CLASSES_ROOT, szSubKey);
  12303. hr = StringCchPrintf (szSubKey, ARRAYSIZE(szSubKey), TEXT("Software\\Microsoft\\MMC\\SnapIns\\%s"), szSnapInKey);
  12304. ASSERT(SUCCEEDED(hr));
  12305. RegDelnode (HKEY_LOCAL_MACHINE, szSubKey);
  12306. StringFromGUID2 (RootNodeID, szGUID, 50);
  12307. hr = StringCchPrintf (szSubKey, ARRAYSIZE(szSubKey), TEXT("Software\\Microsoft\\MMC\\NodeTypes\\%s"), szGUID);
  12308. ASSERT(SUCCEEDED(hr));
  12309. RegDelnode (HKEY_LOCAL_MACHINE, szSubKey);
  12310. StringFromGUID2 (ExtNodeId, szGUID, 50);
  12311. hr = StringCchPrintf (szSubKey, ARRAYSIZE(szSubKey), TEXT("Software\\Microsoft\\MMC\\NodeTypes\\%s\\Extensions\\NameSpace"), szGUID);
  12312. ASSERT(SUCCEEDED(hr));
  12313. lResult = RegOpenKeyEx (HKEY_LOCAL_MACHINE, szSubKey, 0,
  12314. KEY_WRITE, &hKey);
  12315. if (lResult == ERROR_SUCCESS) {
  12316. RegDeleteValue (hKey, szSnapInKey);
  12317. RegCloseKey (hKey);
  12318. }
  12319. return S_OK;
  12320. }
  12321. HRESULT UnregisterPolicy(void)
  12322. {
  12323. HRESULT hr;
  12324. hr = UnregisterPolicyExtension (CLSID_PolicySnapInMachine, NODEID_PolicyRootMachine,
  12325. NODEID_Machine);
  12326. if (hr == S_OK)
  12327. {
  12328. hr = UnregisterPolicyExtension (CLSID_PolicySnapInUser, NODEID_PolicyRootUser,
  12329. NODEID_User);
  12330. }
  12331. if (hr == S_OK)
  12332. {
  12333. hr = UnregisterPolicyExtension (CLSID_RSOPolicySnapInMachine, NODEID_RSOPolicyRootMachine,
  12334. NODEID_RSOPMachineRoot);
  12335. }
  12336. if (hr == S_OK)
  12337. {
  12338. hr = UnregisterPolicyExtension (CLSID_RSOPolicySnapInUser, NODEID_RSOPolicyRootUser,
  12339. NODEID_RSOPUserRoot);
  12340. }
  12341. return hr;
  12342. }
  12343. VOID LoadMessage (DWORD dwID, LPTSTR lpBuffer, DWORD dwSize)
  12344. {
  12345. HINSTANCE hInstActiveDS;
  12346. HINSTANCE hInstWMI;
  12347. if (!FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM,
  12348. NULL, dwID,
  12349. MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL),
  12350. lpBuffer, dwSize, NULL))
  12351. {
  12352. hInstActiveDS = LoadLibrary (TEXT("activeds.dll"));
  12353. if (hInstActiveDS)
  12354. {
  12355. if (!FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_HMODULE,
  12356. hInstActiveDS, dwID,
  12357. MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL),
  12358. lpBuffer, dwSize, NULL))
  12359. {
  12360. hInstWMI = LoadLibrary (TEXT("wmiutils.dll"));
  12361. if (hInstWMI)
  12362. {
  12363. if (!FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_HMODULE,
  12364. hInstWMI, dwID,
  12365. MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL),
  12366. lpBuffer, dwSize, NULL))
  12367. {
  12368. DebugMsg((DM_WARNING, TEXT("LoadMessage: Failed to query error message text for %d due to error %d"),
  12369. dwID, GetLastError()));
  12370. (void) StringCchPrintf (lpBuffer, dwSize, TEXT("%d (0x%x)"), dwID, dwID);
  12371. }
  12372. FreeLibrary (hInstWMI);
  12373. }
  12374. }
  12375. FreeLibrary (hInstActiveDS);
  12376. }
  12377. }
  12378. }
  12379. //*************************************************************
  12380. //
  12381. // ErrorDlgProc()
  12382. //
  12383. // Purpose: Dialog box procedure for errors
  12384. //
  12385. // Parameters:
  12386. //
  12387. //
  12388. // Return: TRUE if successful
  12389. // FALSE if an error occurs
  12390. //
  12391. //*************************************************************
  12392. INT_PTR CALLBACK ErrorDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  12393. {
  12394. switch (message)
  12395. {
  12396. case WM_INITDIALOG:
  12397. {
  12398. TCHAR szError[MAX_PATH];
  12399. LPGPOERRORINFO lpEI = (LPGPOERRORINFO) lParam;
  12400. HICON hIcon;
  12401. hIcon = LoadIcon (NULL, IDI_INFORMATION);
  12402. if (hIcon)
  12403. {
  12404. SendDlgItemMessage (hDlg, IDC_ERROR_ICON, STM_SETICON, (WPARAM)hIcon, 0);
  12405. }
  12406. SetDlgItemText (hDlg, IDC_ERRORTEXT, lpEI->lpMsg);
  12407. if (lpEI->lpDetails) {
  12408. // if details is provided use that
  12409. SetDlgItemText (hDlg, IDC_DETAILSTEXT, lpEI->lpDetails);
  12410. }
  12411. else {
  12412. szError[0] = TEXT('\0');
  12413. if (lpEI->dwError)
  12414. {
  12415. LoadMessage (lpEI->dwError, szError, ARRAYSIZE(szError));
  12416. }
  12417. if (szError[0] == TEXT('\0'))
  12418. {
  12419. LoadString (g_hInstance, IDS_NONE, szError, ARRAYSIZE(szError));
  12420. }
  12421. SetDlgItemText (hDlg, IDC_DETAILSTEXT, szError);
  12422. }
  12423. // this is the only way I know to remove focus from the details
  12424. PostMessage(hDlg, WM_MYREFRESH, 0, 0);
  12425. return TRUE;
  12426. }
  12427. case WM_MYREFRESH:
  12428. {
  12429. SetFocus(GetDlgItem(hDlg, IDCLOSE));
  12430. }
  12431. case WM_COMMAND:
  12432. if (LOWORD(wParam) == IDCLOSE || LOWORD(wParam) == IDCANCEL)
  12433. {
  12434. EndDialog(hDlg, TRUE);
  12435. return TRUE;
  12436. }
  12437. break;
  12438. case WM_HELP: // F1
  12439. WinHelp((HWND)((LPHELPINFO) lParam)->hItemHandle, HELP_FILE, HELP_WM_HELP,
  12440. (ULONG_PTR) (LPSTR) aErrorHelpIds);
  12441. break;
  12442. case WM_CONTEXTMENU: // right mouse click
  12443. WinHelp((HWND) wParam, HELP_FILE, HELP_CONTEXTMENU,
  12444. (ULONG_PTR) (LPSTR) aErrorHelpIds);
  12445. return (TRUE);
  12446. }
  12447. return FALSE;
  12448. }
  12449. //*************************************************************
  12450. //
  12451. // ReportError()
  12452. //
  12453. // Purpose: Displays an error message to the user
  12454. //
  12455. // Parameters: hParent - Parent window handle
  12456. // dwError - Error number
  12457. // idMsg - Error message id
  12458. //
  12459. // Return: TRUE if successful
  12460. // FALSE if an error occurs
  12461. //
  12462. // Comments:
  12463. //
  12464. // History: Date Author Comment
  12465. // 7/18/95 ericflo Created
  12466. //
  12467. //*************************************************************
  12468. BOOL ReportAdmError (HWND hParent, DWORD dwError, UINT idMsg, ...)
  12469. {
  12470. GPOERRORINFO ei;
  12471. TCHAR szMsg[MAX_PATH];
  12472. TCHAR szErrorMsg[2*MAX_PATH+40];
  12473. va_list marker;
  12474. HRESULT hr = S_OK;
  12475. //
  12476. // Load the error message
  12477. //
  12478. if (!LoadString (g_hInstance, idMsg, szMsg, MAX_PATH))
  12479. {
  12480. return FALSE;
  12481. }
  12482. //
  12483. // Plug in the arguments
  12484. //
  12485. va_start(marker, idMsg);
  12486. if (idMsg == IDS_RSOP_ADMFAILED) {
  12487. ei.lpDetails = va_arg(marker, LPTSTR);
  12488. (void) StringCchCopy(szErrorMsg, ARRAYSIZE(szErrorMsg), szMsg);
  12489. }
  12490. else {
  12491. va_start(marker, idMsg);
  12492. (void) StringCchVPrintf(szErrorMsg, ARRAYSIZE(szErrorMsg), szMsg, marker);
  12493. }
  12494. va_end(marker);
  12495. //
  12496. // Display the message
  12497. //
  12498. ei.dwError = dwError;
  12499. ei.lpMsg = szErrorMsg;
  12500. DialogBoxParam (g_hInstance, MAKEINTRESOURCE(IDD_ERROR_ADMTEMPLATES), hParent,
  12501. ErrorDlgProc, (LPARAM) &ei);
  12502. return TRUE;
  12503. }
  12504. LPHASHTABLE CreateHashTable (void)
  12505. {
  12506. LPHASHTABLE lpTable;
  12507. lpTable = (LPHASHTABLE)LocalAlloc (LPTR, sizeof(LPHASHTABLE) * HASH_BUCKET_COUNT);
  12508. return lpTable;
  12509. }
  12510. VOID FreeHashTable (LPHASHTABLE lpTable)
  12511. {
  12512. INT i;
  12513. LPHASHENTRY lpItem, lpNext;
  12514. for (i = 0; i < HASH_BUCKET_COUNT; i++)
  12515. {
  12516. lpItem = lpTable->lpEntries[i];
  12517. while (lpItem)
  12518. {
  12519. lpNext = lpItem->pNext;
  12520. LocalFree (lpItem);
  12521. lpItem = lpNext;
  12522. }
  12523. }
  12524. LocalFree (lpTable);
  12525. }
  12526. ULONG CalculateHashInfo(LPTSTR lpName, DWORD dwChars, DWORD *pdwHashValue)
  12527. {
  12528. DWORD dwHash = 314159269;
  12529. DWORD dwIndex;
  12530. CharLowerBuff (lpName, dwChars);
  12531. for (dwIndex = 0; dwIndex < dwChars; dwIndex++)
  12532. {
  12533. dwHash ^= (dwHash<<11) + (dwHash<<5) + (dwHash>>2) + (unsigned int) lpName[dwIndex];
  12534. }
  12535. dwHash = (dwHash & 0x7FFFFFFF);
  12536. *pdwHashValue = dwHash;
  12537. return (dwHash % HASH_BUCKET_COUNT);
  12538. }
  12539. BOOL AddHashEntry (LPHASHTABLE lpTable, LPTSTR lpName, DWORD dwChars)
  12540. {
  12541. DWORD dwHashValue, dwBucket;
  12542. LPHASHENTRY lpTemp, lpItem;
  12543. dwBucket = CalculateHashInfo(lpName, dwChars, &dwHashValue);
  12544. lpItem = (LPHASHENTRY) LocalAlloc (LPTR, sizeof(HASHENTRY));
  12545. if (!lpItem)
  12546. {
  12547. return FALSE;
  12548. }
  12549. lpItem->dwHashValue = dwHashValue;
  12550. lpItem->dwVariableLength = dwChars;
  12551. lpItem->lpStringEntry = lpName;
  12552. lpTemp = lpTable->lpEntries[dwBucket];
  12553. if (lpTemp)
  12554. {
  12555. while (lpTemp->pNext)
  12556. {
  12557. lpTemp = lpTemp->pNext;
  12558. }
  12559. lpTemp->pNext = lpItem;
  12560. }
  12561. else
  12562. {
  12563. lpTable->lpEntries[dwBucket] = lpItem;
  12564. }
  12565. return TRUE;
  12566. }
  12567. LPTSTR FindHashEntry (LPHASHTABLE lpTable, LPTSTR lpName, DWORD dwChars)
  12568. {
  12569. DWORD dwHashValue, dwBucket;
  12570. LPHASHENTRY lpTemp, lpItem;
  12571. dwBucket = CalculateHashInfo(lpName, dwChars, &dwHashValue);
  12572. lpTemp = lpTable->lpEntries[dwBucket];
  12573. if (lpTemp)
  12574. {
  12575. while (lpTemp)
  12576. {
  12577. if ((lpTemp->dwHashValue == dwHashValue) && (lpTemp->dwVariableLength == dwChars))
  12578. {
  12579. if (CompareString (LOCALE_USER_DEFAULT, NORM_IGNORECASE,
  12580. lpTemp->lpStringEntry, dwChars,
  12581. lpName, dwChars) == CSTR_EQUAL)
  12582. {
  12583. return lpTemp->lpStringEntry;
  12584. }
  12585. }
  12586. lpTemp = lpTemp->pNext;
  12587. }
  12588. }
  12589. return NULL;
  12590. }
  12591. #if DBG
  12592. VOID DumpHashTableDetails (LPHASHTABLE lpTable)
  12593. {
  12594. INT i;
  12595. DWORD dwCount = 0;
  12596. LPHASHENTRY lpItem, lpNext;
  12597. for (i = 0; i < HASH_BUCKET_COUNT; i++)
  12598. {
  12599. dwCount = 0;
  12600. lpItem = lpTable->lpEntries[i];
  12601. while (lpItem)
  12602. {
  12603. dwCount++;
  12604. lpItem = lpItem->pNext;
  12605. }
  12606. DebugMsg((DM_VERBOSE, TEXT("Hash Bucket %d has %d entries"), i, dwCount));
  12607. }
  12608. }
  12609. #endif