Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

15160 lines
456 KiB

  1. #include "gptext.h"
  2. #include <initguid.h>
  3. #include "Policy.h"
  4. #include "smartptr.h"
  5. #include "wbemtime.h"
  6. #define RSOP_HELP_FILE TEXT("gpedit.hlp")
  7. //
  8. // ADM directory name
  9. //
  10. const TCHAR g_szADM[] = TEXT("Adm");
  11. const TCHAR g_szNull[] = TEXT("");
  12. const TCHAR g_szStrings[] = TEXT("strings");
  13. const TCHAR szIFDEF[] = TEXT("#ifdef");
  14. const TCHAR szIF[] = TEXT("#if");
  15. const TCHAR szENDIF[] = TEXT("#endif");
  16. const TCHAR szIFNDEF[] = TEXT("#ifndef");
  17. const TCHAR szELSE[] = TEXT("#else");
  18. const TCHAR szVERSION[] = TEXT("version");
  19. const TCHAR szLT[] = TEXT("<");
  20. const TCHAR szLTE[] = TEXT("<=");
  21. const TCHAR szGT[] = TEXT(">");
  22. const TCHAR szGTE[] = TEXT(">=");
  23. const TCHAR szEQ[] = TEXT("==");
  24. const TCHAR szNE[] = TEXT("!=");
  25. const TCHAR szLISTBOX[] = TEXT("LISTBOX");
  26. const TCHAR szEDIT[] = TEXT("EDIT");
  27. const TCHAR szBUTTON[] = TEXT("BUTTON");
  28. const TCHAR szSTATIC[] = TEXT("STATIC");
  29. const TCHAR szCLASS[] = TEXT("CLASS");
  30. const TCHAR szCATEGORY[] = TEXT("CATEGORY");
  31. const TCHAR szPOLICY[] = TEXT("POLICY");
  32. const TCHAR szUSER[] = TEXT("USER");
  33. const TCHAR szMACHINE[] = TEXT("MACHINE");
  34. const TCHAR szCHECKBOX[] = TEXT("CHECKBOX");
  35. const TCHAR szTEXT[] = TEXT("TEXT");
  36. const TCHAR szEDITTEXT[] = TEXT("EDITTEXT");
  37. const TCHAR szNUMERIC[] = TEXT("NUMERIC");
  38. const TCHAR szCOMBOBOX[] = TEXT("COMBOBOX");
  39. const TCHAR szDROPDOWNLIST[] = TEXT("DROPDOWNLIST");
  40. const TCHAR szUPDOWN[] = UPDOWN_CLASS;
  41. const TCHAR szKEYNAME[] = TEXT("KEYNAME");
  42. const TCHAR szVALUENAME[] = TEXT("VALUENAME");
  43. const TCHAR szNAME[] = TEXT("NAME");
  44. const TCHAR szEND[] = TEXT("END");
  45. const TCHAR szPART[] = TEXT("PART");
  46. const TCHAR szSUGGESTIONS[] = TEXT("SUGGESTIONS");
  47. const TCHAR szDEFCHECKED[] = TEXT("DEFCHECKED");
  48. const TCHAR szDEFAULT[] = TEXT("DEFAULT");
  49. const TCHAR szMAXLENGTH[] = TEXT("MAXLEN");
  50. const TCHAR szMIN[] = TEXT("MIN");
  51. const TCHAR szMAX[] = TEXT("MAX");
  52. const TCHAR szSPIN[] = TEXT("SPIN");
  53. const TCHAR szREQUIRED[] = TEXT("REQUIRED");
  54. const TCHAR szOEMCONVERT[] = TEXT("OEMCONVERT");
  55. const TCHAR szTXTCONVERT[] = TEXT("TXTCONVERT");
  56. const TCHAR szEXPANDABLETEXT[] = TEXT("EXPANDABLETEXT");
  57. const TCHAR szVALUEON[] = TEXT("VALUEON");
  58. const TCHAR szVALUEOFF[] = TEXT("VALUEOFF");
  59. const TCHAR szVALUE[] = TEXT("VALUE");
  60. const TCHAR szACTIONLIST[] = TEXT("ACTIONLIST");
  61. const TCHAR szACTIONLISTON[] = TEXT("ACTIONLISTON");
  62. const TCHAR szACTIONLISTOFF[] = TEXT("ACTIONLISTOFF");
  63. const TCHAR szDELETE[] = TEXT("DELETE");
  64. const TCHAR szITEMLIST[] = TEXT("ITEMLIST");
  65. const TCHAR szSOFT[] = TEXT("SOFT");
  66. const TCHAR szVALUEPREFIX[] = TEXT("VALUEPREFIX");
  67. const TCHAR szADDITIVE[] = TEXT("ADDITIVE");
  68. const TCHAR szEXPLICITVALUE[] = TEXT("EXPLICITVALUE");
  69. const TCHAR szNOSORT[] = TEXT("NOSORT");
  70. const TCHAR szHELP[] = TEXT("EXPLAIN");
  71. const TCHAR szCLIENTEXT[] = TEXT("CLIENTEXT");
  72. const TCHAR szSUPPORTED[] = TEXT("SUPPORTED");
  73. const TCHAR szStringsSect[] = TEXT("[strings]");
  74. const TCHAR szStrings[] = TEXT("strings");
  75. const TCHAR szDELETEPREFIX[] = TEXT("**del.");
  76. const TCHAR szSOFTPREFIX[] = TEXT("**soft.");
  77. const TCHAR szDELVALS[] = TEXT("**delvals.");
  78. const TCHAR szNOVALUE[] = TEXT(" ");
  79. const TCHAR szUserPrefKey[] = TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Group Policy Editor");
  80. const TCHAR szPoliciesKey[] = TEXT("Software\\Policies\\Microsoft\\Windows\\Group Policy Editor");
  81. const TCHAR szDefaultTemplates[] = TEXT("DefaultTemplates");
  82. const TCHAR szAdditionalTemplates[] = TEXT("AdditionalTemplates");
  83. // list of legal keyword entries in "CATEGORY" section
  84. KEYWORDINFO pCategoryEntryCmpList[] = { {szKEYNAME,KYWD_ID_KEYNAME},
  85. {szCATEGORY,KYWD_ID_CATEGORY},{szPOLICY,KYWD_ID_POLICY},
  86. {szEND,KYWD_ID_END},{szHELP,KYWD_ID_HELP}, {NULL,0} };
  87. KEYWORDINFO pCategoryTypeCmpList[] = { {szCATEGORY,KYWD_ID_CATEGORY},
  88. {NULL,0} };
  89. // list of legal keyword entries in "POLICY" section
  90. KEYWORDINFO pPolicyEntryCmpList[] = { {szKEYNAME,KYWD_ID_KEYNAME},
  91. {szVALUENAME,KYWD_ID_VALUENAME}, {szPART,KYWD_ID_PART},
  92. {szVALUEON,KYWD_ID_VALUEON},{szVALUEOFF,KYWD_ID_VALUEOFF},
  93. {szACTIONLISTON,KYWD_ID_ACTIONLISTON},{szACTIONLISTOFF,KYWD_ID_ACTIONLISTOFF},
  94. {szEND,KYWD_ID_END},{szHELP,KYWD_ID_HELP}, {szCLIENTEXT,KYWD_ID_CLIENTEXT},
  95. {szSUPPORTED,KYWD_ID_SUPPORTED}, {NULL, 0} };
  96. KEYWORDINFO pPolicyTypeCmpList[] = { {szPOLICY,KYWD_ID_POLICY}, {NULL,0} };
  97. // list of legal keyword entries in "PART" section
  98. KEYWORDINFO pSettingsEntryCmpList[] = { {szCHECKBOX,KYWD_ID_CHECKBOX},
  99. {szTEXT,KYWD_ID_TEXT},{szEDITTEXT,KYWD_ID_EDITTEXT},
  100. {szNUMERIC,KYWD_ID_NUMERIC},{szCOMBOBOX,KYWD_ID_COMBOBOX},
  101. {szDROPDOWNLIST,KYWD_ID_DROPDOWNLIST},{szLISTBOX,KYWD_ID_LISTBOX},
  102. {szEND,KYWD_ID_END}, {szCLIENTEXT,KYWD_ID_CLIENTEXT}, {NULL,0}};
  103. KEYWORDINFO pSettingsTypeCmpList[] = {{szPART,KYWD_ID_PART},{NULL,0}};
  104. KEYWORDINFO pCheckboxCmpList[] = {
  105. {szKEYNAME,KYWD_ID_KEYNAME},{szVALUENAME,KYWD_ID_VALUENAME},
  106. {szVALUEON,KYWD_ID_VALUEON},{szVALUEOFF,KYWD_ID_VALUEOFF},
  107. {szACTIONLISTON,KYWD_ID_ACTIONLISTON},{szACTIONLISTOFF,KYWD_ID_ACTIONLISTOFF},
  108. {szDEFCHECKED, KYWD_ID_DEFCHECKED}, {szCLIENTEXT,KYWD_ID_CLIENTEXT},
  109. {szEND,KYWD_ID_END},{NULL,0} };
  110. KEYWORDINFO pTextCmpList[] = {{szEND,KYWD_ID_END},{NULL,0}};
  111. KEYWORDINFO pEditTextCmpList[] = {
  112. {szKEYNAME,KYWD_ID_KEYNAME},{szVALUENAME,KYWD_ID_VALUENAME},
  113. {szDEFAULT,KYWD_ID_EDITTEXT_DEFAULT},
  114. {szREQUIRED,KYWD_ID_REQUIRED},{szMAXLENGTH,KYWD_ID_MAXLENGTH},
  115. {szOEMCONVERT,KYWD_ID_OEMCONVERT},{szSOFT,KYWD_ID_SOFT},
  116. {szEND,KYWD_ID_END},{szEXPANDABLETEXT,KYWD_ID_EXPANDABLETEXT},
  117. {szCLIENTEXT,KYWD_ID_CLIENTEXT}, {NULL,0} };
  118. KEYWORDINFO pComboboxCmpList[] = {
  119. {szKEYNAME,KYWD_ID_KEYNAME},{szVALUENAME,KYWD_ID_VALUENAME},
  120. {szDEFAULT,KYWD_ID_COMBOBOX_DEFAULT},{szSUGGESTIONS,KYWD_ID_SUGGESTIONS},
  121. {szREQUIRED,KYWD_ID_REQUIRED},{szMAXLENGTH,KYWD_ID_MAXLENGTH},
  122. {szOEMCONVERT,KYWD_ID_OEMCONVERT},{szSOFT,KYWD_ID_SOFT},
  123. {szEND,KYWD_ID_END},{szNOSORT, KYWD_ID_NOSORT},
  124. {szEXPANDABLETEXT,KYWD_ID_EXPANDABLETEXT},{szCLIENTEXT,KYWD_ID_CLIENTEXT}, {NULL,0} };
  125. KEYWORDINFO pNumericCmpList[] = {
  126. {szKEYNAME,KYWD_ID_KEYNAME},{szVALUENAME,KYWD_ID_VALUENAME},
  127. {szMIN, KYWD_ID_MIN},{szMAX,KYWD_ID_MAX},{szSPIN,KYWD_ID_SPIN},
  128. {szDEFAULT,KYWD_ID_NUMERIC_DEFAULT},{szREQUIRED,KYWD_ID_REQUIRED},
  129. {szTXTCONVERT,KYWD_ID_TXTCONVERT},{szSOFT,KYWD_ID_SOFT},
  130. {szEND,KYWD_ID_END}, {szCLIENTEXT,KYWD_ID_CLIENTEXT}, {NULL,0} };
  131. KEYWORDINFO pDropdownlistCmpList[] = {
  132. {szKEYNAME,KYWD_ID_KEYNAME},{szVALUENAME,KYWD_ID_VALUENAME},
  133. {szREQUIRED,KYWD_ID_REQUIRED},{szITEMLIST,KYWD_ID_ITEMLIST},
  134. {szEND,KYWD_ID_END},{szNOSORT, KYWD_ID_NOSORT},{szCLIENTEXT,KYWD_ID_CLIENTEXT}, {NULL,0}};
  135. KEYWORDINFO pListboxCmpList[] = {
  136. {szKEYNAME,KYWD_ID_KEYNAME},{szVALUEPREFIX,KYWD_ID_VALUEPREFIX},
  137. {szADDITIVE,KYWD_ID_ADDITIVE},{szNOSORT, KYWD_ID_NOSORT},
  138. {szEXPLICITVALUE,KYWD_ID_EXPLICITVALUE},{szEXPANDABLETEXT,KYWD_ID_EXPANDABLETEXT},
  139. {szEND,KYWD_ID_END},{szCLIENTEXT,KYWD_ID_CLIENTEXT}, {NULL,0} };
  140. KEYWORDINFO pClassCmpList[] = { {szCLASS, KYWD_ID_CLASS},
  141. {szCATEGORY,KYWD_ID_CATEGORY}, {szStringsSect,KYWD_ID_STRINGSSECT},
  142. {NULL,0} };
  143. KEYWORDINFO pClassTypeCmpList[] = { {szUSER, KYWD_ID_USER},
  144. {szMACHINE,KYWD_ID_MACHINE}, {NULL,0} };
  145. KEYWORDINFO pVersionCmpList[] = { {szVERSION, KYWD_ID_VERSION}, {NULL,0}};
  146. KEYWORDINFO pOperatorCmpList[] = { {szGT, KYWD_ID_GT}, {szGTE,KYWD_ID_GTE},
  147. {szLT, KYWD_ID_LT}, {szLTE,KYWD_ID_LTE}, {szEQ,KYWD_ID_EQ},
  148. {szNE, KYWD_ID_NE}, {NULL,0}};
  149. //
  150. // Help ID's
  151. //
  152. DWORD aADMHelpIds[] = {
  153. // Templates dialog
  154. IDC_TEMPLATELIST, (IDH_HELPFIRST + 0),
  155. IDC_ADDTEMPLATES, (IDH_HELPFIRST + 1),
  156. IDC_REMOVETEMPLATES, (IDH_HELPFIRST + 2),
  157. 0, 0
  158. };
  159. DWORD aPolicyHelpIds[] = {
  160. // ADM Policy UI page
  161. IDC_NOCONFIG, (IDH_HELPFIRST + 11),
  162. IDC_ENABLED, (IDH_HELPFIRST + 12),
  163. IDC_DISABLED, (IDH_HELPFIRST + 13),
  164. IDC_POLICY_PREVIOUS, (IDH_HELPFIRST + 14),
  165. IDC_POLICY_NEXT, (IDH_HELPFIRST + 15),
  166. 0, 0
  167. };
  168. DWORD aExplainHelpIds[] = {
  169. // Explain page
  170. IDC_POLICY_PREVIOUS, (IDH_HELPFIRST + 14),
  171. IDC_POLICY_NEXT, (IDH_HELPFIRST + 15),
  172. 0, 0
  173. };
  174. DWORD aPrecedenceHelpIds[] = {
  175. // Precedence page
  176. IDC_POLICY_PRECEDENCE, (IDH_HELPFIRST + 16),
  177. IDC_POLICY_PREVIOUS, (IDH_HELPFIRST + 14),
  178. IDC_POLICY_NEXT, (IDH_HELPFIRST + 15),
  179. 0, 0
  180. };
  181. DWORD aFilteringHelpIds[] = {
  182. // Filtering options
  183. IDC_STATIC, (DWORD) (-1), // disabled help
  184. IDC_FILTERING_ICON, (DWORD) (-1), // disabled help
  185. IDC_SUPPORTEDONTITLE, (DWORD) (-1), // disabled help
  186. IDC_SUPPORTEDOPTION, (IDH_HELPFIRST + 20),
  187. IDC_FILTERLIST, (IDH_HELPFIRST + 21),
  188. IDC_SELECTALL, (IDH_HELPFIRST + 22),
  189. IDC_DESELECTALL, (IDH_HELPFIRST + 23),
  190. IDC_SHOWCONFIG, (IDH_HELPFIRST + 24),
  191. IDC_SHOWPOLICIES, (IDH_HELPFIRST + 25),
  192. 0, 0
  193. };
  194. #define GPE_KEY TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Group Policy Editor")
  195. #define GPE_POLICIES_KEY TEXT("Software\\Policies\\Microsoft\\Windows\\Group Policy Editor")
  196. #define POLICYONLY_VALUE TEXT("ShowPoliciesOnly")
  197. #define DISABLE_AUTOUPDATE_VALUE TEXT("DisableAutoADMUpdate")
  198. #define SOFTWARE_POLICIES TEXT("Software\\Policies")
  199. #define WINDOWS_POLICIES TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Policies")
  200. typedef struct _GPOERRORINFO
  201. {
  202. DWORD dwError;
  203. LPTSTR lpMsg;
  204. LPTSTR lpDetails;
  205. } GPOERRORINFO, *LPGPOERRORINFO;
  206. //
  207. // Help ids
  208. //
  209. DWORD aErrorHelpIds[] =
  210. {
  211. 0, 0
  212. };
  213. ///////////////////////////////////////////////////////////////////////////////
  214. // //
  215. // CPolicyComponentData object implementation //
  216. // //
  217. ///////////////////////////////////////////////////////////////////////////////
  218. CPolicyComponentData::CPolicyComponentData(BOOL bUser, BOOL bRSOP)
  219. {
  220. TCHAR szEvent[200];
  221. m_cRef = 1;
  222. InterlockedIncrement(&g_cRefThisDll);
  223. m_hwndFrame = NULL;
  224. m_pScope = NULL;
  225. m_pConsole = NULL;
  226. m_hRoot = NULL;
  227. m_hSWPolicies = NULL;
  228. m_pGPTInformation = NULL;
  229. m_pRSOPInformation = NULL;
  230. m_pRSOPRegistryData = NULL;
  231. m_pszNamespace = NULL;
  232. m_bUserScope = bUser;
  233. m_bRSOP = bRSOP;
  234. m_pMachineCategoryList = NULL;
  235. m_nMachineDataItems = 0;
  236. m_pUserCategoryList = NULL;
  237. m_nUserDataItems = 0;
  238. m_pSupportedStrings = 0;
  239. m_iSWPoliciesLen = lstrlen(SOFTWARE_POLICIES);
  240. m_iWinPoliciesLen = lstrlen(WINDOWS_POLICIES);
  241. m_bUseSupportedOnFilter = FALSE;
  242. if (bRSOP)
  243. {
  244. m_bShowConfigPoliciesOnly = TRUE;
  245. }
  246. else
  247. {
  248. m_bShowConfigPoliciesOnly = FALSE;
  249. }
  250. m_pSnapin = NULL;
  251. m_hTemplateThread = NULL;
  252. wsprintf (szEvent, TEXT("gptext: ADM files ready event, %d:%d"), bUser, GetTickCount());
  253. m_ADMEvent = CreateEvent (NULL, TRUE, FALSE, szEvent);
  254. if (!m_ADMEvent)
  255. {
  256. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::CPolicyComponentData: Failed to create ADM event with %d."),
  257. GetLastError()));
  258. }
  259. LoadString (g_hInstance, IDS_POLICY_NAME, m_szRootName, ROOT_NAME_SIZE);
  260. m_pExtraSettingsRoot = NULL;
  261. m_bExtraSettingsInitialized = FALSE;
  262. }
  263. CPolicyComponentData::~CPolicyComponentData()
  264. {
  265. //
  266. // Wait for the Template thread to finish before continuing.
  267. //
  268. if (m_hTemplateThread)
  269. WaitForSingleObject(m_hTemplateThread, INFINITE);
  270. FreeTemplates ();
  271. if (m_pExtraSettingsRoot)
  272. {
  273. FreeTable ((TABLEENTRY *)m_pExtraSettingsRoot);
  274. }
  275. if (m_pScope)
  276. {
  277. m_pScope->Release();
  278. }
  279. if (m_pConsole)
  280. {
  281. m_pConsole->Release();
  282. }
  283. if (m_pGPTInformation)
  284. {
  285. m_pGPTInformation->Release();
  286. }
  287. if (m_pRSOPInformation)
  288. {
  289. m_pRSOPInformation->Release();
  290. }
  291. if (m_pRSOPRegistryData)
  292. {
  293. FreeRSOPRegistryData();
  294. }
  295. if (m_pszNamespace)
  296. {
  297. LocalFree (m_pszNamespace);
  298. }
  299. CloseHandle (m_ADMEvent);
  300. if (m_hTemplateThread)
  301. CloseHandle (m_hTemplateThread);
  302. m_hTemplateThread = NULL;
  303. InterlockedDecrement(&g_cRefThisDll);
  304. }
  305. ///////////////////////////////////////////////////////////////////////////////
  306. // //
  307. // CPolicyComponentData object implementation (IUnknown) //
  308. // //
  309. ///////////////////////////////////////////////////////////////////////////////
  310. HRESULT CPolicyComponentData::QueryInterface (REFIID riid, void **ppv)
  311. {
  312. if (IsEqualIID(riid, IID_IComponentData) || IsEqualIID(riid, IID_IUnknown))
  313. {
  314. *ppv = (LPCOMPONENT)this;
  315. m_cRef++;
  316. return S_OK;
  317. }
  318. else if (IsEqualIID(riid, IID_IExtendContextMenu))
  319. {
  320. *ppv = (LPEXTENDCONTEXTMENU)this;
  321. m_cRef++;
  322. return S_OK;
  323. }
  324. else if (IsEqualIID(riid, IID_IPersistStreamInit))
  325. {
  326. *ppv = (LPPERSISTSTREAMINIT)this;
  327. m_cRef++;
  328. return S_OK;
  329. }
  330. else if (IsEqualIID(riid, IID_ISnapinHelp))
  331. {
  332. *ppv = (LPSNAPINHELP)this;
  333. m_cRef++;
  334. return S_OK;
  335. }
  336. else
  337. {
  338. *ppv = NULL;
  339. return E_NOINTERFACE;
  340. }
  341. }
  342. ULONG CPolicyComponentData::AddRef (void)
  343. {
  344. return ++m_cRef;
  345. }
  346. ULONG CPolicyComponentData::Release (void)
  347. {
  348. if (--m_cRef == 0) {
  349. delete this;
  350. return 0;
  351. }
  352. return m_cRef;
  353. }
  354. ///////////////////////////////////////////////////////////////////////////////
  355. // //
  356. // CPolicyComponentData object implementation (IComponentData) //
  357. // //
  358. ///////////////////////////////////////////////////////////////////////////////
  359. STDMETHODIMP CPolicyComponentData::Initialize(LPUNKNOWN pUnknown)
  360. {
  361. HRESULT hr;
  362. HBITMAP bmp16x16;
  363. LPIMAGELIST lpScopeImage;
  364. //
  365. // QI for IConsoleNameSpace
  366. //
  367. hr = pUnknown->QueryInterface(IID_IConsoleNameSpace2, (LPVOID *)&m_pScope);
  368. if (FAILED(hr))
  369. {
  370. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::Initialize: Failed to QI for IConsoleNameSpace.")));
  371. return hr;
  372. }
  373. //
  374. // QI for IConsole
  375. //
  376. hr = pUnknown->QueryInterface(IID_IConsole, (LPVOID *)&m_pConsole);
  377. if (FAILED(hr))
  378. {
  379. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::Initialize: Failed to QI for IConsole.")));
  380. m_pScope->Release();
  381. m_pScope = NULL;
  382. return hr;
  383. }
  384. m_pConsole->GetMainWindow (&m_hwndFrame);
  385. //
  386. // Query for the scope imagelist interface
  387. //
  388. hr = m_pConsole->QueryScopeImageList(&lpScopeImage);
  389. if (FAILED(hr))
  390. {
  391. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::Initialize: Failed to QI for scope imagelist.")));
  392. m_pScope->Release();
  393. m_pScope = NULL;
  394. m_pConsole->Release();
  395. m_pConsole=NULL;
  396. return hr;
  397. }
  398. // Load the bitmaps from the dll
  399. bmp16x16=LoadBitmap(g_hInstance, MAKEINTRESOURCE(IDB_16x16));
  400. // Set the images
  401. lpScopeImage->ImageListSetStrip(reinterpret_cast<LONG_PTR *>(bmp16x16),
  402. reinterpret_cast<LONG_PTR *>(bmp16x16),
  403. 0, RGB(255, 0, 255));
  404. lpScopeImage->Release();
  405. //
  406. // Create the root of the Extra Settings node if appropriate
  407. //
  408. if (m_bRSOP)
  409. {
  410. DWORD dwBufSize;
  411. REGITEM *pTmp;
  412. TCHAR szBuffer[100];
  413. m_pExtraSettingsRoot = (REGITEM *) GlobalAlloc(GPTR, sizeof(REGITEM));
  414. if (!m_pExtraSettingsRoot)
  415. {
  416. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::Initialize: GlobalAlloc failed with %d"), GetLastError()));
  417. return HRESULT_FROM_WIN32(GetLastError());
  418. }
  419. m_pExtraSettingsRoot->dwSize = sizeof(REGITEM);
  420. m_pExtraSettingsRoot->dwType = (ETYPE_ROOT | ETYPE_REGITEM);
  421. LoadString (g_hInstance, IDS_EXTRAREGSETTINGS, szBuffer, ARRAYSIZE(szBuffer));
  422. pTmp = (REGITEM *) AddDataToEntry((TABLEENTRY *)m_pExtraSettingsRoot,
  423. (BYTE *)szBuffer,(lstrlen(szBuffer)+1) * sizeof(TCHAR),&(m_pExtraSettingsRoot->uOffsetName),
  424. &dwBufSize);
  425. if (!pTmp)
  426. {
  427. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::Initialize: AddDataToEntry failed.")));
  428. return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
  429. }
  430. m_pExtraSettingsRoot = pTmp;
  431. }
  432. return S_OK;
  433. }
  434. STDMETHODIMP CPolicyComponentData::Destroy(VOID)
  435. {
  436. return S_OK;
  437. }
  438. STDMETHODIMP CPolicyComponentData::CreateComponent(LPCOMPONENT *ppComponent)
  439. {
  440. HRESULT hr;
  441. CPolicySnapIn *pSnapIn;
  442. DebugMsg((DM_VERBOSE, TEXT("CPolicyComponentData::CreateComponent: Entering.")));
  443. //
  444. // Initialize
  445. //
  446. *ppComponent = NULL;
  447. //
  448. // Create the snapin view
  449. //
  450. pSnapIn = new CPolicySnapIn(this);
  451. if (!pSnapIn)
  452. {
  453. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::CreateComponent: Failed to create CPolicySnapIn.")));
  454. return E_OUTOFMEMORY;
  455. }
  456. //
  457. // QI for IComponent
  458. //
  459. hr = pSnapIn->QueryInterface(IID_IComponent, (LPVOID *)ppComponent);
  460. pSnapIn->Release(); // release QI
  461. m_pSnapin = pSnapIn;
  462. return hr;
  463. }
  464. STDMETHODIMP CPolicyComponentData::QueryDataObject(MMC_COOKIE cookie, DATA_OBJECT_TYPES type,
  465. LPDATAOBJECT* ppDataObject)
  466. {
  467. HRESULT hr = E_NOINTERFACE;
  468. CPolicyDataObject *pDataObject;
  469. LPPOLICYDATAOBJECT pPolicyDataObject;
  470. //
  471. // Create a new DataObject
  472. //
  473. pDataObject = new CPolicyDataObject(this); // ref == 1
  474. if (!pDataObject)
  475. return E_OUTOFMEMORY;
  476. //
  477. // QI for the private GPTDataObject interface so we can set the cookie
  478. // and type information.
  479. //
  480. hr = pDataObject->QueryInterface(IID_IPolicyDataObject, (LPVOID *)&pPolicyDataObject);
  481. if (FAILED(hr))
  482. {
  483. pDataObject->Release();
  484. return (hr);
  485. }
  486. pPolicyDataObject->SetType(type);
  487. pPolicyDataObject->SetCookie(cookie);
  488. pPolicyDataObject->Release();
  489. //
  490. // QI for a normal IDataObject to return.
  491. //
  492. hr = pDataObject->QueryInterface(IID_IDataObject, (LPVOID *)ppDataObject);
  493. pDataObject->Release(); // release initial ref
  494. return hr;
  495. }
  496. STDMETHODIMP CPolicyComponentData::Notify(LPDATAOBJECT lpDataObject, MMC_NOTIFY_TYPE event, LPARAM arg, LPARAM param)
  497. {
  498. HRESULT hr = S_OK;
  499. switch(event)
  500. {
  501. case MMCN_EXPAND:
  502. if (arg == TRUE)
  503. if (m_bRSOP)
  504. {
  505. if (!m_pRSOPInformation)
  506. {
  507. lpDataObject->QueryInterface(IID_IRSOPInformation, (LPVOID *)&m_pRSOPInformation);
  508. if (m_pRSOPInformation)
  509. {
  510. m_pszNamespace = (LPOLESTR) LocalAlloc (LPTR, 350 * sizeof(TCHAR));
  511. if (m_pszNamespace)
  512. {
  513. if (m_pRSOPInformation->GetNamespace((m_bUserScope ? GPO_SECTION_USER : GPO_SECTION_MACHINE),
  514. m_pszNamespace, 350) == S_OK)
  515. {
  516. InitializeRSOPRegistryData();
  517. }
  518. else
  519. {
  520. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::Notify: Failed to query for namespace")));
  521. LocalFree (m_pszNamespace);
  522. m_pszNamespace = NULL;
  523. }
  524. }
  525. }
  526. }
  527. if (m_pszNamespace && m_pRSOPRegistryData)
  528. {
  529. hr = EnumerateScopePane(lpDataObject, (HSCOPEITEM)param);
  530. }
  531. }
  532. else
  533. {
  534. if (!m_pGPTInformation)
  535. {
  536. lpDataObject->QueryInterface(IID_IGPEInformation, (LPVOID *)&m_pGPTInformation);
  537. }
  538. if (m_pGPTInformation)
  539. {
  540. hr = EnumerateScopePane(lpDataObject, (HSCOPEITEM)param);
  541. }
  542. }
  543. break;
  544. default:
  545. break;
  546. }
  547. return hr;
  548. }
  549. STDMETHODIMP CPolicyComponentData::GetDisplayInfo(LPSCOPEDATAITEM pItem)
  550. {
  551. TABLEENTRY * pTableEntry;
  552. if (pItem == NULL)
  553. return E_POINTER;
  554. if (pItem->lParam == 0)
  555. {
  556. pItem->displayname = m_szRootName;
  557. }
  558. else
  559. {
  560. pTableEntry = (TABLEENTRY *)(pItem->lParam);
  561. pItem->displayname = GETNAMEPTR(pTableEntry);
  562. }
  563. return S_OK;
  564. }
  565. STDMETHODIMP CPolicyComponentData::CompareObjects(LPDATAOBJECT lpDataObjectA, LPDATAOBJECT lpDataObjectB)
  566. {
  567. HRESULT hr = S_FALSE;
  568. LPPOLICYDATAOBJECT pPolicyDataObjectA, pPolicyDataObjectB;
  569. MMC_COOKIE cookie1, cookie2;
  570. if (lpDataObjectA == NULL || lpDataObjectB == NULL)
  571. return E_POINTER;
  572. //
  573. // QI for the private GPTDataObject interface
  574. //
  575. if (FAILED(lpDataObjectA->QueryInterface(IID_IPolicyDataObject,
  576. (LPVOID *)&pPolicyDataObjectA)))
  577. {
  578. return S_FALSE;
  579. }
  580. if (FAILED(lpDataObjectB->QueryInterface(IID_IPolicyDataObject,
  581. (LPVOID *)&pPolicyDataObjectB)))
  582. {
  583. pPolicyDataObjectA->Release();
  584. return S_FALSE;
  585. }
  586. pPolicyDataObjectA->GetCookie(&cookie1);
  587. pPolicyDataObjectB->GetCookie(&cookie2);
  588. if (cookie1 == cookie2)
  589. {
  590. hr = S_OK;
  591. }
  592. pPolicyDataObjectA->Release();
  593. pPolicyDataObjectB->Release();
  594. return hr;
  595. }
  596. ///////////////////////////////////////////////////////////////////////////////
  597. // //
  598. // CPolicyComponentData object implementation (IExtendContextMenu) //
  599. // //
  600. ///////////////////////////////////////////////////////////////////////////////
  601. STDMETHODIMP CPolicyComponentData::AddMenuItems(LPDATAOBJECT piDataObject,
  602. LPCONTEXTMENUCALLBACK pCallback,
  603. LONG *pInsertionAllowed)
  604. {
  605. HRESULT hr = S_OK;
  606. TCHAR szMenuItem[100];
  607. TCHAR szDescription[250];
  608. CONTEXTMENUITEM item;
  609. LPPOLICYDATAOBJECT pPolicyDataObject;
  610. MMC_COOKIE cookie = -1;
  611. DATA_OBJECT_TYPES type = CCT_UNINITIALIZED;
  612. if (!m_bRSOP)
  613. {
  614. if (SUCCEEDED(piDataObject->QueryInterface(IID_IPolicyDataObject,
  615. (LPVOID *)&pPolicyDataObject)))
  616. {
  617. pPolicyDataObject->GetType(&type);
  618. pPolicyDataObject->GetCookie(&cookie);
  619. pPolicyDataObject->Release();
  620. }
  621. if ((type == CCT_SCOPE) && (cookie == 0))
  622. {
  623. LoadString (g_hInstance, IDS_TEMPLATES, szMenuItem, 100);
  624. LoadString (g_hInstance, IDS_TEMPLATESDESC, szDescription, 250);
  625. item.strName = szMenuItem;
  626. item.strStatusBarText = szDescription;
  627. item.lCommandID = IDM_TEMPLATES;
  628. item.lInsertionPointID = CCM_INSERTIONPOINTID_PRIMARY_TOP;
  629. item.fFlags = 0;
  630. item.fSpecialFlags = 0;
  631. hr = pCallback->AddItem(&item);
  632. if (FAILED(hr))
  633. return (hr);
  634. item.strName = szMenuItem;
  635. item.strStatusBarText = szDescription;
  636. item.lCommandID = IDM_TEMPLATES2;
  637. item.lInsertionPointID = CCM_INSERTIONPOINTID_PRIMARY_TASK;
  638. item.fFlags = 0;
  639. item.fSpecialFlags = 0;
  640. hr = pCallback->AddItem(&item);
  641. }
  642. }
  643. return (hr);
  644. }
  645. STDMETHODIMP CPolicyComponentData::Command(LONG lCommandID, LPDATAOBJECT piDataObject)
  646. {
  647. if ((lCommandID == IDM_TEMPLATES) || (lCommandID == IDM_TEMPLATES2))
  648. {
  649. m_bTemplatesColumn = 0;
  650. if (DialogBoxParam (g_hInstance, MAKEINTRESOURCE(IDD_TEMPLATES),
  651. m_hwndFrame, TemplatesDlgProc, (LPARAM) this))
  652. {
  653. //
  654. // Refresh the adm namespace
  655. //
  656. PostMessage (HWND_BROADCAST, m_pSnapin->m_uiRefreshMsg, 0, (LPARAM) GetCurrentProcessId());
  657. }
  658. }
  659. return S_OK;
  660. }
  661. ///////////////////////////////////////////////////////////////////////////////
  662. // //
  663. // CPolicyComponentData object implementation (IPersistStreamInit) //
  664. // //
  665. ///////////////////////////////////////////////////////////////////////////////
  666. STDMETHODIMP CPolicyComponentData::GetClassID(CLSID *pClassID)
  667. {
  668. if (!pClassID)
  669. {
  670. return E_FAIL;
  671. }
  672. if (m_bUserScope)
  673. *pClassID = CLSID_PolicySnapInUser;
  674. else
  675. *pClassID = CLSID_PolicySnapInMachine;
  676. return S_OK;
  677. }
  678. STDMETHODIMP CPolicyComponentData::IsDirty(VOID)
  679. {
  680. return S_FALSE;
  681. }
  682. STDMETHODIMP CPolicyComponentData::Load(IStream *pStm)
  683. {
  684. return S_OK;
  685. }
  686. STDMETHODIMP CPolicyComponentData::Save(IStream *pStm, BOOL fClearDirty)
  687. {
  688. return S_OK;
  689. }
  690. STDMETHODIMP CPolicyComponentData::GetSizeMax(ULARGE_INTEGER *pcbSize)
  691. {
  692. DWORD dwSize = 0;
  693. if (!pcbSize)
  694. {
  695. return E_FAIL;
  696. }
  697. ULISet32(*pcbSize, dwSize);
  698. return S_OK;
  699. }
  700. STDMETHODIMP CPolicyComponentData::InitNew(void)
  701. {
  702. return S_OK;
  703. }
  704. ///////////////////////////////////////////////////////////////////////////////
  705. // //
  706. // CPolicyComponentData object implementation (ISnapinHelp) //
  707. // //
  708. ///////////////////////////////////////////////////////////////////////////////
  709. STDMETHODIMP CPolicyComponentData::GetHelpTopic(LPOLESTR *lpCompiledHelpFile)
  710. {
  711. LPOLESTR lpHelpFile;
  712. lpHelpFile = (LPOLESTR) CoTaskMemAlloc (MAX_PATH * sizeof(WCHAR));
  713. if (!lpHelpFile)
  714. {
  715. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::GetHelpTopic: Failed to allocate memory.")));
  716. return E_OUTOFMEMORY;
  717. }
  718. ExpandEnvironmentStringsW (L"%SystemRoot%\\Help\\gptext.chm",
  719. lpHelpFile, MAX_PATH);
  720. *lpCompiledHelpFile = lpHelpFile;
  721. return S_OK;
  722. }
  723. ///////////////////////////////////////////////////////////////////////////////
  724. // //
  725. // CPolicyComponentData object implementation (Internal functions) //
  726. // //
  727. ///////////////////////////////////////////////////////////////////////////////
  728. HRESULT CPolicyComponentData::EnumerateScopePane (LPDATAOBJECT lpDataObject, HSCOPEITEM hParent)
  729. {
  730. SCOPEDATAITEM item;
  731. HRESULT hr;
  732. TABLEENTRY *pTemp = NULL;
  733. DWORD dwResult;
  734. CPolicySnapIn * pSnapin = NULL, *pSnapinTemp;
  735. BOOL bRootItem = FALSE;
  736. HANDLE hEvents[1];
  737. if (!m_hRoot)
  738. {
  739. DWORD dwID;
  740. m_hRoot = hParent;
  741. m_hTemplateThread = CreateThread (NULL, 0,
  742. (LPTHREAD_START_ROUTINE) LoadTemplatesThread,
  743. (LPVOID) this, 0, &dwID);
  744. if (m_hTemplateThread)
  745. {
  746. SetThreadPriority(m_hTemplateThread, THREAD_PRIORITY_LOWEST);
  747. }
  748. else
  749. {
  750. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::EnumerateScopePane: Failed to create adm thread with %d"),
  751. GetLastError()));
  752. LoadTemplates();
  753. }
  754. }
  755. if (m_hRoot == hParent)
  756. {
  757. item.mask = SDI_STR | SDI_STATE | SDI_IMAGE | SDI_OPENIMAGE | SDI_PARAM | SDI_CHILDREN;
  758. item.displayname = MMC_CALLBACK;
  759. item.nImage = 0;
  760. item.nOpenImage = 1;
  761. item.nState = 0;
  762. item.cChildren = 1;
  763. item.lParam = 0;
  764. item.relativeID = hParent;
  765. m_pScope->Expand(hParent);
  766. if (SUCCEEDED(m_pScope->InsertItem (&item)))
  767. {
  768. m_hSWPolicies = item.ID;
  769. }
  770. return S_OK;
  771. }
  772. hEvents[0] = m_ADMEvent;
  773. if (WaitForSingleObject (m_ADMEvent, 250) != WAIT_OBJECT_0)
  774. {
  775. DebugMsg((DM_VERBOSE, TEXT("CPolicyComponentData::EnumerateScopePane: Waiting for ADM event to be signaled.")));
  776. for (;;) {
  777. SetCursor (LoadCursor(NULL, IDC_WAIT));
  778. dwResult = MsgWaitForMultipleObjects(1, hEvents, FALSE, INFINITE, QS_ALLINPUT);
  779. if (dwResult == WAIT_OBJECT_0 ) {
  780. break;
  781. }
  782. else if (dwResult == WAIT_OBJECT_0 + 1 ) {
  783. MSG msg;
  784. while ( PeekMessage( &msg, 0, 0, 0, PM_REMOVE ) )
  785. {
  786. TranslateMessage(&msg);
  787. DispatchMessage(&msg);
  788. }
  789. }
  790. else {
  791. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::EnumerateScopePane: MsgWaitForMultipleObjects returned %d ."), dwResult));
  792. break;
  793. }
  794. }
  795. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::EnumerateScopePane: ADM event has been signaled.")));
  796. SetCursor (LoadCursor(NULL, IDC_ARROW));
  797. }
  798. item.mask = SDI_PARAM;
  799. item.ID = hParent;
  800. hr = m_pScope->GetItem (&item);
  801. if (FAILED(hr))
  802. return hr;
  803. EnterCriticalSection (&g_ADMCritSec);
  804. if (item.lParam)
  805. {
  806. pTemp = ((TABLEENTRY *)item.lParam)->pChild;
  807. }
  808. else
  809. {
  810. bRootItem = TRUE;
  811. if (m_bUserScope)
  812. {
  813. if (m_pUserCategoryList)
  814. {
  815. pTemp = m_pUserCategoryList->pChild;
  816. }
  817. else
  818. {
  819. DebugMsg((DM_VERBOSE, TEXT("CPolicyComponentData::EnumerateScopePane: Empty user list.")));
  820. }
  821. }
  822. else
  823. {
  824. if (m_pMachineCategoryList)
  825. {
  826. pTemp = m_pMachineCategoryList->pChild;
  827. }
  828. else
  829. {
  830. DebugMsg((DM_VERBOSE, TEXT("CPolicyComponentData::EnumerateScopePane: Empty machine list.")));
  831. }
  832. }
  833. }
  834. //
  835. // If the user has set the focus on a adm node and then saves the console file,
  836. // the IComponent won't be created yet. We need to create a temporary IComponent
  837. // to parse the data and then release it.
  838. //
  839. if (m_pSnapin)
  840. {
  841. pSnapinTemp = m_pSnapin;
  842. }
  843. else
  844. {
  845. pSnapinTemp = pSnapin = new CPolicySnapIn(this);
  846. }
  847. while (pTemp)
  848. {
  849. if (pTemp->dwType == ETYPE_CATEGORY)
  850. {
  851. BOOL bAdd = TRUE;
  852. if (m_bUseSupportedOnFilter)
  853. {
  854. bAdd = IsAnyPolicyAllowedPastFilter(pTemp);
  855. }
  856. if (bAdd && m_bShowConfigPoliciesOnly)
  857. {
  858. if (pSnapinTemp)
  859. {
  860. bAdd = pSnapinTemp->IsAnyPolicyEnabled(pTemp);
  861. }
  862. }
  863. if (bAdd)
  864. {
  865. m_pScope->Expand(hParent);
  866. item.mask = SDI_STR | SDI_STATE | SDI_IMAGE | SDI_OPENIMAGE | SDI_PARAM | SDI_CHILDREN;
  867. item.displayname = MMC_CALLBACK;
  868. item.nImage = 0;
  869. item.nOpenImage = 1;
  870. item.nState = 0;
  871. item.cChildren = (CheckForChildCategories(pTemp) ? 1 : 0);
  872. item.lParam = (LPARAM) pTemp;
  873. item.relativeID = hParent;
  874. m_pScope->InsertItem (&item);
  875. }
  876. }
  877. pTemp = pTemp->pNext;
  878. }
  879. //
  880. // Add the Extra Registry Settings node if appropriate
  881. //
  882. if (bRootItem && m_pExtraSettingsRoot)
  883. {
  884. if (!m_bExtraSettingsInitialized)
  885. {
  886. InitializeExtraSettings();
  887. m_bExtraSettingsInitialized = TRUE;
  888. if (LOWORD(dwDebugLevel) == DL_VERBOSE)
  889. {
  890. DumpRSOPRegistryData();
  891. }
  892. }
  893. if (m_pExtraSettingsRoot->pChild)
  894. {
  895. m_pScope->Expand(hParent);
  896. item.mask = SDI_STR | SDI_STATE | SDI_IMAGE | SDI_OPENIMAGE | SDI_PARAM | SDI_CHILDREN;
  897. item.displayname = MMC_CALLBACK;
  898. item.nImage = 0;
  899. item.nOpenImage = 1;
  900. item.nState = 0;
  901. item.cChildren = 0;
  902. item.lParam = (LPARAM) m_pExtraSettingsRoot;
  903. item.relativeID = hParent;
  904. m_pScope->InsertItem (&item);
  905. }
  906. }
  907. if (pSnapin)
  908. {
  909. pSnapin->Release();
  910. }
  911. LeaveCriticalSection (&g_ADMCritSec);
  912. return S_OK;
  913. }
  914. BOOL CPolicyComponentData::CheckForChildCategories (TABLEENTRY *pParent)
  915. {
  916. TABLEENTRY * pTemp;
  917. if (pParent->pChild)
  918. {
  919. pTemp = pParent->pChild;
  920. while (pTemp)
  921. {
  922. if (pTemp->dwType == ETYPE_CATEGORY)
  923. {
  924. return TRUE;
  925. }
  926. pTemp = pTemp->pNext;
  927. }
  928. }
  929. return FALSE;
  930. }
  931. #if DBG
  932. //
  933. // These are a couple of debugging helper functions that will dump
  934. // the adm namespace to the debugger. Call DumpCurrentTable() to
  935. // get the full namespace.
  936. //
  937. VOID CPolicyComponentData::DumpEntry (TABLEENTRY * pEntry, UINT uIndent)
  938. {
  939. UINT i;
  940. TCHAR szDebug[50];
  941. if (!pEntry)
  942. return;
  943. if (pEntry == (TABLEENTRY*) ULongToPtr(0xfeeefeee))
  944. {
  945. OutputDebugString (TEXT("Invalid memory address found.\r\n"));
  946. return;
  947. }
  948. while (pEntry)
  949. {
  950. if ((pEntry->dwType & ETYPE_CATEGORY) || (pEntry->dwType & ETYPE_POLICY))
  951. {
  952. for (i=0; i<uIndent; i++)
  953. OutputDebugString(TEXT(" "));
  954. OutputDebugString (GETNAMEPTR(pEntry));
  955. if (pEntry->pNext && pEntry->pChild)
  956. wsprintf (szDebug, TEXT(" (0x%x, 0x%x)"),pEntry->pNext, pEntry->pChild);
  957. else if (!pEntry->pNext && pEntry->pChild)
  958. wsprintf (szDebug, TEXT(" (NULL, 0x%x)"),pEntry->pChild);
  959. else if (pEntry->pNext && !pEntry->pChild)
  960. wsprintf (szDebug, TEXT(" (0x%x, NULL)"),pEntry->pNext);
  961. OutputDebugString (szDebug);
  962. OutputDebugString (TEXT("\r\n"));
  963. }
  964. if (pEntry->pChild)
  965. DumpEntry(pEntry->pChild, (uIndent + 4));
  966. pEntry = pEntry->pNext;
  967. }
  968. }
  969. VOID CPolicyComponentData::DumpCurrentTable (void)
  970. {
  971. OutputDebugString (TEXT("\r\n"));
  972. OutputDebugString (TEXT("\r\n"));
  973. DumpEntry (m_pListCurrent, 4);
  974. OutputDebugString (TEXT("\r\n"));
  975. OutputDebugString (TEXT("\r\n"));
  976. }
  977. #endif
  978. VOID CPolicyComponentData::FreeTemplates (void)
  979. {
  980. EnterCriticalSection (&g_ADMCritSec);
  981. if (m_pMachineCategoryList)
  982. {
  983. FreeTable(m_pMachineCategoryList);
  984. m_pMachineCategoryList = NULL;
  985. m_nMachineDataItems = 0;
  986. }
  987. if (m_pUserCategoryList)
  988. {
  989. FreeTable(m_pUserCategoryList);
  990. m_pUserCategoryList = NULL;
  991. m_nUserDataItems = 0;
  992. }
  993. if (m_pSupportedStrings)
  994. {
  995. FreeSupportedData(m_pSupportedStrings);
  996. m_pSupportedStrings = NULL;
  997. }
  998. LeaveCriticalSection (&g_ADMCritSec);
  999. }
  1000. DWORD CPolicyComponentData::LoadTemplatesThread (CPolicyComponentData * pCD)
  1001. {
  1002. HRESULT hr;
  1003. HINSTANCE hInstDLL;
  1004. hInstDLL = LoadLibrary (TEXT("gptext.dll"));
  1005. Sleep(0);
  1006. hr = pCD->LoadTemplates();
  1007. if (hInstDLL)
  1008. {
  1009. FreeLibraryAndExitThread (hInstDLL, (DWORD) hr);
  1010. }
  1011. return (DWORD)hr;
  1012. }
  1013. void CPolicyComponentData::AddTemplates(LPTSTR lpDest, LPCTSTR lpValueName, UINT idRes)
  1014. {
  1015. TCHAR szFiles[MAX_PATH];
  1016. TCHAR szSrc[MAX_PATH];
  1017. TCHAR szDest[MAX_PATH];
  1018. TCHAR szLogFile[MAX_PATH];
  1019. LPTSTR lpTemp, lpFileName, lpSrc, lpEnd;
  1020. HKEY hKey;
  1021. DWORD dwSize, dwType;
  1022. //
  1023. // Add the adm files. We get this list from 3 possible
  1024. // places. The resources, user preferences, policy.
  1025. //
  1026. lstrcpy (szDest, lpDest);
  1027. lpEnd = CheckSlash (szDest);
  1028. lstrcpy (szLogFile, lpDest);
  1029. lstrcat (szLogFile, TEXT("\\admfiles.ini"));
  1030. ExpandEnvironmentStrings (TEXT("%SystemRoot%\\Inf"), szSrc, ARRAYSIZE(szSrc));
  1031. lpSrc = CheckSlash (szSrc);
  1032. ZeroMemory (szFiles, sizeof(szFiles));
  1033. LoadString (g_hInstance, idRes, szFiles,
  1034. ARRAYSIZE(szFiles));
  1035. if (RegOpenKeyEx (HKEY_CURRENT_USER, szUserPrefKey, 0,
  1036. KEY_READ, &hKey) == ERROR_SUCCESS)
  1037. {
  1038. dwSize = sizeof(szFiles);
  1039. RegQueryValueEx (hKey, lpValueName, NULL, &dwType,
  1040. (LPBYTE) &szFiles, &dwSize);
  1041. RegCloseKey (hKey);
  1042. }
  1043. if (RegOpenKeyEx (HKEY_CURRENT_USER, szPoliciesKey, 0,
  1044. KEY_READ, &hKey) == ERROR_SUCCESS)
  1045. {
  1046. dwSize = sizeof(szFiles);
  1047. RegQueryValueEx (hKey, lpValueName, NULL, &dwType,
  1048. (LPBYTE) &szFiles, &dwSize);
  1049. RegCloseKey (hKey);
  1050. }
  1051. //
  1052. // Parse off the filenames
  1053. //
  1054. lpTemp = lpFileName = szFiles;
  1055. while (*lpTemp)
  1056. {
  1057. while (*lpTemp && (*lpTemp != TEXT(';')))
  1058. lpTemp++;
  1059. if (*lpTemp == TEXT(';'))
  1060. {
  1061. *lpTemp = TEXT('\0');
  1062. lpTemp++;
  1063. }
  1064. while (*lpFileName == TEXT(' '))
  1065. lpFileName++;
  1066. lstrcpy (lpEnd, lpFileName);
  1067. lstrcpy (lpSrc, lpFileName);
  1068. //
  1069. // Check if this file is already in the admfile.ini log
  1070. // If so, skip it
  1071. //
  1072. if (!GetPrivateProfileInt (TEXT("FileList"), lpFileName, 0, szLogFile))
  1073. {
  1074. if (CopyFile (szSrc, szDest, FALSE))
  1075. {
  1076. DebugMsg((DM_VERBOSE, TEXT("CPolicyComponentData::AddTemplates: Successfully copied %s to %s."), szSrc, szDest));
  1077. WritePrivateProfileString (TEXT("FileList"), lpFileName, TEXT("1"), szLogFile);
  1078. }
  1079. else
  1080. {
  1081. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::AddTemplates: Failed to copy %s to %s with %d."), szSrc, szDest, GetLastError()));
  1082. }
  1083. }
  1084. lpFileName = lpTemp;
  1085. }
  1086. SetFileAttributes (szLogFile, FILE_ATTRIBUTE_HIDDEN);
  1087. }
  1088. void CPolicyComponentData::AddDefaultTemplates(LPTSTR lpDest)
  1089. {
  1090. AddTemplates (lpDest, szDefaultTemplates, IDS_DEFAULTTEMPLATES);
  1091. }
  1092. void CPolicyComponentData::AddNewADMsToExistingGPO (LPTSTR lpDest)
  1093. {
  1094. TCHAR szLogFile[MAX_PATH];
  1095. WIN32_FILE_ATTRIBUTE_DATA fad;
  1096. //
  1097. // This method will add any new adm files to a GPO.
  1098. //
  1099. // Note: the admfiles.ini file is new post-W2k, so we have to do a special
  1100. // case when upgrading a GPO created by w2k to create that file and add
  1101. // the default filenames
  1102. //
  1103. lstrcpy (szLogFile, lpDest);
  1104. lstrcat (szLogFile, TEXT("\\admfiles.ini"));
  1105. if (!GetFileAttributesEx (szLogFile, GetFileExInfoStandard, &fad))
  1106. {
  1107. WritePrivateProfileString (TEXT("FileList"), TEXT("system.adm"), TEXT("1"), szLogFile);
  1108. WritePrivateProfileString (TEXT("FileList"), TEXT("inetres.adm"), TEXT("1"), szLogFile);
  1109. WritePrivateProfileString (TEXT("FileList"), TEXT("conf.adm"), TEXT("1"), szLogFile);
  1110. }
  1111. AddTemplates (lpDest, szAdditionalTemplates, IDS_ADDITIONALTTEMPLATES);
  1112. }
  1113. void CPolicyComponentData::UpdateExistingTemplates(LPTSTR lpDest)
  1114. {
  1115. WIN32_FILE_ATTRIBUTE_DATA fadSrc, fadDest;
  1116. TCHAR szSrc[MAX_PATH];
  1117. TCHAR szDest[MAX_PATH];
  1118. LPTSTR lpSrc, lpEnd;
  1119. WIN32_FIND_DATA fd;
  1120. HANDLE hFindFile;
  1121. BOOL bDisableAutoUpdate = FALSE;
  1122. HKEY hKey;
  1123. DWORD dwSize, dwType;
  1124. //
  1125. // Check if the user wants their ADM files updated automatically
  1126. //
  1127. if (RegOpenKeyEx (HKEY_CURRENT_USER, GPE_KEY, 0,
  1128. KEY_READ, &hKey) == ERROR_SUCCESS)
  1129. {
  1130. dwSize = sizeof(bDisableAutoUpdate);
  1131. RegQueryValueEx (hKey, DISABLE_AUTOUPDATE_VALUE, NULL, &dwType,
  1132. (LPBYTE) &bDisableAutoUpdate, &dwSize);
  1133. RegCloseKey (hKey);
  1134. }
  1135. if (RegOpenKeyEx (HKEY_CURRENT_USER, GPE_POLICIES_KEY, 0,
  1136. KEY_READ, &hKey) == ERROR_SUCCESS)
  1137. {
  1138. dwSize = sizeof(bDisableAutoUpdate);
  1139. RegQueryValueEx (hKey, DISABLE_AUTOUPDATE_VALUE, NULL, &dwType,
  1140. (LPBYTE) &bDisableAutoUpdate, &dwSize);
  1141. RegCloseKey (hKey);
  1142. }
  1143. if (bDisableAutoUpdate)
  1144. {
  1145. DebugMsg((DM_VERBOSE, TEXT("CPolicyComponentData::UpdateExistingTemplates: Automatic update of ADM files is disabled.")));
  1146. return;
  1147. }
  1148. //
  1149. // Add any new adm files shipped with the OS
  1150. //
  1151. AddNewADMsToExistingGPO (lpDest);
  1152. //
  1153. // Build the path to the source directory
  1154. //
  1155. ExpandEnvironmentStrings (TEXT("%SystemRoot%\\Inf"), szSrc, ARRAYSIZE(szSrc));
  1156. lpSrc = CheckSlash (szSrc);
  1157. //
  1158. // Build the path to the destination directory
  1159. //
  1160. lstrcpy (szDest, lpDest);
  1161. lpEnd = CheckSlash (szDest);
  1162. lstrcpy (lpEnd, TEXT("*.adm"));
  1163. //
  1164. // Enumerate the files
  1165. //
  1166. hFindFile = FindFirstFile(szDest, &fd);
  1167. if (hFindFile != INVALID_HANDLE_VALUE)
  1168. {
  1169. do
  1170. {
  1171. if (!(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
  1172. {
  1173. lstrcpy (lpEnd, fd.cFileName);
  1174. lstrcpy (lpSrc, fd.cFileName);
  1175. //
  1176. // Get the file attributes of the source and destination
  1177. //
  1178. ZeroMemory (&fadSrc, sizeof(fadSrc));
  1179. ZeroMemory (&fadDest, sizeof(fadDest));
  1180. GetFileAttributesEx (szSrc, GetFileExInfoStandard, &fadSrc);
  1181. GetFileAttributesEx (szDest, GetFileExInfoStandard, &fadDest);
  1182. //
  1183. // If the source is a different size and newer than the dest
  1184. // copy the .adm file
  1185. //
  1186. if ((fadSrc.nFileSizeHigh != fadDest.nFileSizeHigh) ||
  1187. (fadSrc.nFileSizeLow != fadDest.nFileSizeLow))
  1188. {
  1189. if (CompareFileTime(&fadSrc.ftLastWriteTime, &fadDest.ftLastWriteTime) == 1)
  1190. {
  1191. if (CopyFile (szSrc, szDest, FALSE))
  1192. DebugMsg((DM_VERBOSE, TEXT("CPolicyComponentData::UpdateExistingTemplates: Successfully copied %s to %s."), szSrc, szDest));
  1193. else
  1194. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::UpdateExistingTemplates: Failed to copy %s to %s with %d."), szSrc, szDest, GetLastError()));
  1195. }
  1196. }
  1197. }
  1198. } while (FindNextFile(hFindFile, &fd));
  1199. FindClose(hFindFile);
  1200. }
  1201. }
  1202. HRESULT CPolicyComponentData::LoadGPOTemplates (void)
  1203. {
  1204. WIN32_FIND_DATA fd;
  1205. TCHAR szPath[MAX_PATH];
  1206. LPTSTR lpEnd;
  1207. HANDLE hFindFile;
  1208. UINT iResult;
  1209. HRESULT hr;
  1210. hr = m_pGPTInformation->GetFileSysPath(GPO_SECTION_ROOT, szPath, MAX_PATH);
  1211. if (FAILED(hr))
  1212. {
  1213. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::LoadGPOTemplates: Failed to get gpt path.")));
  1214. return hr;
  1215. }
  1216. //
  1217. // Build the path name
  1218. //
  1219. lpEnd = CheckSlash (szPath);
  1220. lstrcpy (lpEnd, g_szADM);
  1221. iResult = CreateNestedDirectory (szPath, NULL);
  1222. //
  1223. // Based upon the return value, we either exit, add
  1224. // the default templates, or upgrade any existing templates
  1225. //
  1226. if (!iResult)
  1227. {
  1228. return E_FAIL;
  1229. }
  1230. if (iResult == 1)
  1231. {
  1232. AddDefaultTemplates(szPath);
  1233. }
  1234. else
  1235. {
  1236. DebugMsg((DM_VERBOSE, TEXT("CPolicyComponentData::LoadGPOTemplates: Updating templates")));
  1237. UpdateExistingTemplates(szPath);
  1238. DebugMsg((DM_VERBOSE, TEXT("CPolicyComponentData::LoadGPOTemplates: Finished updating templates")));
  1239. }
  1240. //
  1241. // Enumerate the files
  1242. //
  1243. lpEnd = CheckSlash (szPath);
  1244. lstrcpy (lpEnd, TEXT("*.adm"));
  1245. hFindFile = FindFirstFile(szPath, &fd);
  1246. if (hFindFile != INVALID_HANDLE_VALUE)
  1247. {
  1248. do
  1249. {
  1250. if (!(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
  1251. {
  1252. lstrcpy (lpEnd, fd.cFileName);
  1253. ParseTemplate (szPath);
  1254. }
  1255. } while (FindNextFile(hFindFile, &fd));
  1256. FindClose(hFindFile);
  1257. }
  1258. return S_OK;
  1259. }
  1260. #define WINLOGON_KEY TEXT("Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon")
  1261. #define SYSTEM_POLICIES_KEY TEXT("Software\\Policies\\Microsoft\\Windows\\System")
  1262. #define SLOW_LINK_TRANSFER_RATE 500 // Kbps
  1263. BOOL CPolicyComponentData::IsSlowLink (LPTSTR lpFileName)
  1264. {
  1265. LPTSTR lpComputerName = NULL, lpTemp;
  1266. LPSTR lpComputerNameA = NULL;
  1267. BOOL bResult = FALSE;
  1268. DWORD dwSize, dwResult, dwType;
  1269. struct hostent *hostp;
  1270. ULONG inaddr, ulSpeed, ulTransferRate;
  1271. LONG lResult;
  1272. HKEY hKey;
  1273. //
  1274. // Get the slow timeout
  1275. //
  1276. ulTransferRate = SLOW_LINK_TRANSFER_RATE;
  1277. lResult = RegOpenKeyEx(HKEY_CURRENT_USER,
  1278. WINLOGON_KEY,
  1279. 0,
  1280. KEY_READ,
  1281. &hKey);
  1282. if (lResult == ERROR_SUCCESS)
  1283. {
  1284. dwSize = sizeof(ulTransferRate);
  1285. RegQueryValueEx (hKey,
  1286. TEXT("GroupPolicyMinTransferRate"),
  1287. NULL,
  1288. &dwType,
  1289. (LPBYTE) &ulTransferRate,
  1290. &dwSize);
  1291. RegCloseKey (hKey);
  1292. }
  1293. lResult = RegOpenKeyEx(HKEY_CURRENT_USER,
  1294. SYSTEM_POLICIES_KEY,
  1295. 0,
  1296. KEY_READ,
  1297. &hKey);
  1298. if (lResult == ERROR_SUCCESS)
  1299. {
  1300. dwSize = sizeof(ulTransferRate);
  1301. RegQueryValueEx (hKey,
  1302. TEXT("GroupPolicyMinTransferRate"),
  1303. NULL,
  1304. &dwType,
  1305. (LPBYTE) &ulTransferRate,
  1306. &dwSize);
  1307. RegCloseKey (hKey);
  1308. }
  1309. //
  1310. // If the transfer rate is 0, then always download adm files
  1311. //
  1312. if (!ulTransferRate)
  1313. {
  1314. DebugMsg((DM_VERBOSE, TEXT("CPolicyComponentData::IsSlowLink: Slow link transfer rate is 0. Always download adm files.")));
  1315. goto Exit;
  1316. }
  1317. //
  1318. // Copy the namespace to a buffer we can edit and drop the leading \\ if present
  1319. //
  1320. lpComputerName = (LPTSTR) LocalAlloc (LPTR, (lstrlen(lpFileName) + 1) * sizeof(TCHAR));
  1321. if (!lpComputerName)
  1322. {
  1323. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::IsSlowLink: Failed to allocate memory for computer name with %d"),
  1324. GetLastError()));
  1325. goto Exit;
  1326. }
  1327. if ((*lpFileName == TEXT('\\')) && (*(lpFileName+1) == TEXT('\\')))
  1328. {
  1329. lstrcpy (lpComputerName, (lpFileName+2));
  1330. }
  1331. else
  1332. {
  1333. lstrcpy (lpComputerName, lpFileName);
  1334. }
  1335. //
  1336. // Find the slash between the computer name and the share name and replace it with null
  1337. //
  1338. lpTemp = lpComputerName;
  1339. while (*lpTemp && (*lpTemp != TEXT('\\')))
  1340. {
  1341. lpTemp++;
  1342. }
  1343. if (!(*lpTemp))
  1344. {
  1345. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::IsSlowLink: Didn't find slash between computer name and share name in %s"),
  1346. lpComputerName));
  1347. goto Exit;
  1348. }
  1349. *lpTemp = TEXT('\0');
  1350. //
  1351. // Allocate a buffer for the ANSI name
  1352. //
  1353. // Note this buffer is allocated twice as large so handle DBCS characters
  1354. //
  1355. dwSize = (lstrlen(lpComputerName) + 1) * 2;
  1356. lpComputerNameA = (LPSTR) LocalAlloc (LPTR, dwSize);
  1357. if (!lpComputerNameA)
  1358. {
  1359. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::IsSlowLink: Failed to allocate memory for ansi computer name with %d"),
  1360. GetLastError()));
  1361. goto Exit;
  1362. }
  1363. //
  1364. // Convert the computer name to ANSI
  1365. //
  1366. if (WideCharToMultiByte (CP_ACP, 0, lpComputerName, -1, lpComputerNameA, dwSize, NULL, NULL))
  1367. {
  1368. //
  1369. // Get the host information for the computer
  1370. //
  1371. hostp = gethostbyname(lpComputerNameA);
  1372. if (hostp)
  1373. {
  1374. //
  1375. // Get the ip address of the computer
  1376. //
  1377. inaddr = *(long *)hostp->h_addr;
  1378. //
  1379. // Get the transfer rate
  1380. //
  1381. dwResult = PingComputer (inaddr, &ulSpeed);
  1382. if (dwResult == ERROR_SUCCESS)
  1383. {
  1384. if (ulSpeed)
  1385. {
  1386. //
  1387. // If the delta time is greater that the timeout time, then this
  1388. // is a slow link.
  1389. //
  1390. if (ulSpeed < ulTransferRate)
  1391. {
  1392. bResult = TRUE;
  1393. }
  1394. }
  1395. }
  1396. else {
  1397. DebugMsg((DM_VERBOSE, TEXT("CPolicyComponentData::IsSlowLink: PingComputer failed with error %d. Treat it as slow link"), dwResult));
  1398. bResult = TRUE;
  1399. }
  1400. }
  1401. }
  1402. Exit:
  1403. if (lpComputerName)
  1404. {
  1405. LocalFree (lpComputerName);
  1406. }
  1407. if (lpComputerNameA)
  1408. {
  1409. LocalFree (lpComputerNameA);
  1410. }
  1411. return bResult;
  1412. }
  1413. HRESULT CPolicyComponentData::AddADMFile (LPTSTR lpFileName, LPTSTR lpFullFileName,
  1414. FILETIME *pFileTime, DWORD dwErr, LPRSOPADMFILE *lpHead)
  1415. {
  1416. LPRSOPADMFILE lpTemp;
  1417. if ((lstrlen(lpFileName) >= 100) || (lstrlen(lpFullFileName) >= MAX_PATH))
  1418. {
  1419. return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
  1420. }
  1421. //
  1422. // First, check if this file is already in the link list
  1423. //
  1424. lpTemp = *lpHead;
  1425. while (lpTemp)
  1426. {
  1427. if (!lstrcmpi(lpFileName, lpTemp->szFileName))
  1428. {
  1429. if (CompareFileTime(pFileTime, &lpTemp->FileTime) == 1)
  1430. {
  1431. lstrcpy (lpTemp->szFullFileName, lpFullFileName);
  1432. lpTemp->FileTime.dwLowDateTime = pFileTime->dwLowDateTime;
  1433. lpTemp->FileTime.dwHighDateTime = pFileTime->dwHighDateTime;
  1434. }
  1435. return S_OK;
  1436. }
  1437. lpTemp = lpTemp->pNext;
  1438. }
  1439. //
  1440. // Add a new node
  1441. //
  1442. lpTemp = (LPRSOPADMFILE) LocalAlloc (LPTR, sizeof(RSOPADMFILE));
  1443. if (!lpTemp)
  1444. {
  1445. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::AddADMFile: Failed to allocate memory for adm file node")));
  1446. return (HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY));
  1447. }
  1448. lstrcpy (lpTemp->szFileName, lpFileName);
  1449. lstrcpy (lpTemp->szFullFileName, lpFullFileName);
  1450. lpTemp->FileTime.dwLowDateTime = pFileTime->dwLowDateTime;
  1451. lpTemp->FileTime.dwHighDateTime = pFileTime->dwHighDateTime;
  1452. lpTemp->dwError = dwErr;
  1453. lpTemp->pNext = *lpHead;
  1454. *lpHead = lpTemp;
  1455. return S_OK;
  1456. }
  1457. HRESULT CPolicyComponentData::LoadRSOPTemplates (void)
  1458. {
  1459. BSTR pLanguage = NULL, pQuery = NULL;
  1460. BSTR pName = NULL, pLastWriteTime = NULL, pNamespace = NULL;
  1461. IEnumWbemClassObject * pEnum = NULL;
  1462. IWbemClassObject *pObjects[2];
  1463. HRESULT hr;
  1464. ULONG ulRet;
  1465. VARIANT varName, varLastWriteTime;
  1466. IWbemLocator *pIWbemLocator = NULL;
  1467. IWbemServices *pIWbemServices = NULL;
  1468. SYSTEMTIME SysTime;
  1469. FILETIME FileTime;
  1470. LPTSTR lpFileName;
  1471. LPRSOPADMFILE lpADMFiles = NULL, lpTemp, lpDelete, lpFailedAdmFiles = NULL;
  1472. DWORD dwFailedAdm = 0;
  1473. XBStr xbstrWbemTime;
  1474. DWORD dwError;
  1475. TCHAR szPath[MAX_PATH];
  1476. BOOL bSlowLink = FALSE;
  1477. DebugMsg((DM_VERBOSE, TEXT("CPolicyComponentData::LoadRSOPTemplates: Entering")));
  1478. CoInitialize(NULL);
  1479. //
  1480. // Allocate BSTRs for the query language and for the query itself
  1481. //
  1482. pLanguage = SysAllocString (TEXT("WQL"));
  1483. if (!pLanguage)
  1484. {
  1485. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::LoadRSOPTemplates: Failed to allocate memory for language")));
  1486. hr = HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY);
  1487. goto Exit;
  1488. }
  1489. pQuery = SysAllocString (TEXT("SELECT name, lastWriteTime FROM RSOP_AdministrativeTemplateFile"));
  1490. if (!pQuery)
  1491. {
  1492. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::LoadRSOPTemplates: Failed to allocate memory for query")));
  1493. hr = HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY);
  1494. goto Exit;
  1495. }
  1496. //
  1497. // Allocate BSTRs for the property names we want to retreive
  1498. //
  1499. pName = SysAllocString (TEXT("name"));
  1500. if (!pName)
  1501. {
  1502. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::LoadRSOPTemplates: Failed to allocate memory for name")));
  1503. hr = HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY);
  1504. goto Exit;
  1505. }
  1506. pLastWriteTime = SysAllocString (TEXT("lastWriteTime"));
  1507. if (!pLastWriteTime)
  1508. {
  1509. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::LoadRSOPTemplates: Failed to allocate memory for last write time")));
  1510. hr = HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY);
  1511. goto Exit;
  1512. }
  1513. //
  1514. // Create an instance of the WMI locator service
  1515. //
  1516. hr = CoCreateInstance(CLSID_WbemLocator, NULL, CLSCTX_INPROC_SERVER,
  1517. IID_IWbemLocator, (LPVOID *) &pIWbemLocator);
  1518. if (FAILED(hr))
  1519. {
  1520. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::LoadRSOPTemplates: CoCreateInstance failed with 0x%x"), hr));
  1521. goto Exit;
  1522. }
  1523. //
  1524. // Allocate a BSTR for the namespace
  1525. //
  1526. pNamespace = SysAllocString (m_pszNamespace);
  1527. if (!pNamespace)
  1528. {
  1529. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::LoadRSOPTemplates: Failed to allocate memory for namespace")));
  1530. hr = HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY);
  1531. goto Exit;
  1532. }
  1533. //
  1534. // Connect to the server
  1535. //
  1536. hr = pIWbemLocator->ConnectServer(pNamespace, NULL, NULL, 0L, 0L, NULL, NULL,
  1537. &pIWbemServices);
  1538. if (FAILED(hr))
  1539. {
  1540. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::LoadRSOPTemplates: ConnectServer failed with 0x%x"), hr));
  1541. goto Exit;
  1542. }
  1543. //
  1544. // Execute the query
  1545. //
  1546. hr = pIWbemServices->ExecQuery (pLanguage, pQuery,
  1547. WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
  1548. NULL, &pEnum);
  1549. if (FAILED(hr))
  1550. {
  1551. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::LoadRSOPTemplates: Failed to query for %s with 0x%x"),
  1552. pQuery, hr));
  1553. goto Exit;
  1554. }
  1555. //
  1556. // Loop through the results
  1557. //
  1558. while (pEnum->Next(WBEM_INFINITE, 1, pObjects, &ulRet) == S_OK)
  1559. {
  1560. //
  1561. // Check for the "data not available case"
  1562. //
  1563. if (ulRet == 0)
  1564. {
  1565. hr = S_OK;
  1566. goto Exit;
  1567. }
  1568. //
  1569. // Get the name
  1570. //
  1571. hr = pObjects[0]->Get (pName, 0, &varName, NULL, NULL);
  1572. if (SUCCEEDED(hr))
  1573. {
  1574. //
  1575. // Get the last write time
  1576. //
  1577. hr = pObjects[0]->Get (pLastWriteTime, 0, &varLastWriteTime, NULL, NULL);
  1578. if (SUCCEEDED(hr))
  1579. {
  1580. xbstrWbemTime = varLastWriteTime.bstrVal;
  1581. hr = WbemTimeToSystemTime(xbstrWbemTime, SysTime);
  1582. if (SUCCEEDED(hr))
  1583. {
  1584. SystemTimeToFileTime (&SysTime, &FileTime);
  1585. lpFileName = varName.bstrVal + lstrlen(varName.bstrVal);
  1586. while ((lpFileName > varName.bstrVal) && (*lpFileName != TEXT('\\')))
  1587. lpFileName--;
  1588. if (*lpFileName == TEXT('\\'))
  1589. {
  1590. lpFileName++;
  1591. }
  1592. AddADMFile (lpFileName, varName.bstrVal, &FileTime, 0, &lpADMFiles);
  1593. }
  1594. VariantClear (&varLastWriteTime);
  1595. }
  1596. VariantClear (&varName);
  1597. }
  1598. pObjects[0]->Release();
  1599. }
  1600. //
  1601. // Parse the adm files
  1602. //
  1603. lpTemp = lpADMFiles;
  1604. while (lpTemp)
  1605. {
  1606. SetLastError(ERROR_SUCCESS);
  1607. if (!bSlowLink)
  1608. {
  1609. bSlowLink = IsSlowLink (lpTemp->szFullFileName);
  1610. }
  1611. if (bSlowLink || !ParseTemplate(lpTemp->szFullFileName))
  1612. {
  1613. //
  1614. // If the adm file failed to parse for any of the reasons listed
  1615. // below, switch over to using the local copy of the ADM file
  1616. //
  1617. dwError = GetLastError();
  1618. if (bSlowLink || ((dwError != ERROR_SUCCESS) &&
  1619. (dwError != ERROR_ALREADY_DISPLAYED)))
  1620. {
  1621. if (bSlowLink)
  1622. {
  1623. DebugMsg((DM_VERBOSE, TEXT("CPolicyComponentData::LoadRSOPTemplates: Using local copy of %s due to slow link detection."),
  1624. lpTemp->szFileName));
  1625. }
  1626. else
  1627. {
  1628. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::LoadRSOPTemplates: Unable to parse template %s due to error %d. Switching to the local copy of %s."),
  1629. lpTemp->szFullFileName, dwError, lpTemp->szFileName));
  1630. AddADMFile (lpTemp->szFileName, lpTemp->szFullFileName, &(lpTemp->FileTime), dwError, &lpFailedAdmFiles);
  1631. dwFailedAdm++;
  1632. }
  1633. ExpandEnvironmentStrings (TEXT("%SystemRoot%\\inf\\"), szPath, MAX_PATH);
  1634. lstrcat (szPath, lpTemp->szFileName);
  1635. ParseTemplate (szPath);
  1636. }
  1637. }
  1638. lpDelete = lpTemp;
  1639. lpTemp = lpTemp->pNext;
  1640. LocalFree (lpDelete);
  1641. }
  1642. hr = S_OK;
  1643. //
  1644. // Format a error msg for the failed adm files
  1645. // ignore any errors
  1646. //
  1647. if (dwFailedAdm) {
  1648. LPTSTR lpErr = NULL, lpEnd = NULL;
  1649. TCHAR szErrFormat[MAX_PATH];
  1650. TCHAR szError[MAX_PATH];
  1651. szErrFormat[0] = TEXT('\0');
  1652. LoadString (g_hInstance, IDS_FAILED_RSOPFMT, szErrFormat, ARRAYSIZE(szErrFormat));
  1653. lpErr = (LPTSTR)LocalAlloc(LPTR, (600*dwFailedAdm)*sizeof(TCHAR));
  1654. if (!lpErr) {
  1655. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::LoadRSOPTemplates: Couldn't allocate memory for the error buffer."), GetLastError()));
  1656. goto Exit;
  1657. }
  1658. lpTemp = lpFailedAdmFiles;
  1659. lpEnd = lpErr;
  1660. while (lpTemp) {
  1661. szError[0] = TEXT('\0');
  1662. LoadMessage(lpTemp->dwError, szError, ARRAYSIZE(szError));
  1663. wsprintf(lpEnd, szErrFormat, lpTemp->szFileName, lpTemp->szFullFileName, szError);
  1664. lpEnd += lstrlen(lpEnd);
  1665. lpDelete = lpTemp;
  1666. lpTemp = lpTemp->pNext;
  1667. LocalFree (lpDelete);
  1668. }
  1669. // we cannot pass in a owner window handle here, b'cos this
  1670. // is being done in a seperate thread and the main thread can be
  1671. // waiting for the templatethread event
  1672. ReportAdmError(NULL, 0, IDS_RSOP_ADMFAILED, lpErr);
  1673. lpFailedAdmFiles = NULL;
  1674. LocalFree(lpErr);
  1675. }
  1676. Exit:
  1677. if (pEnum)
  1678. {
  1679. pEnum->Release();
  1680. }
  1681. if (pIWbemLocator)
  1682. {
  1683. pIWbemLocator->Release();
  1684. }
  1685. if (pIWbemServices)
  1686. {
  1687. pIWbemServices->Release();
  1688. }
  1689. if (pLanguage)
  1690. {
  1691. SysFreeString (pLanguage);
  1692. }
  1693. if (pQuery)
  1694. {
  1695. SysFreeString (pQuery);
  1696. }
  1697. if (pName)
  1698. {
  1699. SysFreeString (pName);
  1700. }
  1701. if (pLastWriteTime)
  1702. {
  1703. SysFreeString (pLastWriteTime);
  1704. }
  1705. if (pNamespace)
  1706. {
  1707. SysFreeString (pNamespace);
  1708. }
  1709. lpTemp = lpFailedAdmFiles;
  1710. while (lpTemp) {
  1711. lpDelete = lpTemp;
  1712. lpTemp = lpTemp->pNext;
  1713. LocalFree (lpDelete);
  1714. }
  1715. lpFailedAdmFiles = NULL;
  1716. CoUninitialize();
  1717. DebugMsg((DM_VERBOSE, TEXT("CPolicyComponentData::LoadRSOPTemplates: Leaving")));
  1718. return hr;
  1719. }
  1720. HRESULT CPolicyComponentData::LoadTemplates (void)
  1721. {
  1722. HRESULT hr = E_FAIL;
  1723. if (m_bUserScope)
  1724. {
  1725. DebugMsg((DM_VERBOSE, TEXT("CPolicyComponentData::LoadTemplates: Entering for User")));
  1726. }
  1727. else
  1728. {
  1729. DebugMsg((DM_VERBOSE, TEXT("CPolicyComponentData::LoadTemplates: Entering for Machine")));
  1730. }
  1731. //
  1732. // Reset the ADM event
  1733. //
  1734. ResetEvent (m_ADMEvent);
  1735. //
  1736. // Free any old templates
  1737. //
  1738. FreeTemplates ();
  1739. EnterCriticalSection (&g_ADMCritSec);
  1740. //
  1741. // Prepare to load the templates
  1742. //
  1743. m_nUserDataItems = 0;
  1744. m_nMachineDataItems = 0;
  1745. m_pMachineCategoryList = (TABLEENTRY *) GlobalAlloc(GPTR,sizeof(TABLEENTRY));
  1746. if (!m_pMachineCategoryList)
  1747. {
  1748. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::LoadTemplates: Failed to alloc memory with %d"),
  1749. GetLastError()));
  1750. goto Exit;
  1751. }
  1752. m_pUserCategoryList = (TABLEENTRY *) GlobalAlloc(GPTR,sizeof(TABLEENTRY));
  1753. if (!m_pUserCategoryList)
  1754. {
  1755. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::LoadTemplates: Failed to alloc memory with %d"),
  1756. GetLastError()));
  1757. GlobalFree (m_pMachineCategoryList);
  1758. goto Exit;
  1759. }
  1760. m_pMachineCategoryList->dwSize = m_pUserCategoryList->dwSize = sizeof(TABLEENTRY);
  1761. m_pMachineCategoryList->dwType = m_pUserCategoryList->dwType = ETYPE_ROOT;
  1762. //
  1763. // Load the appropriate template files
  1764. //
  1765. if (m_bRSOP)
  1766. {
  1767. hr = LoadRSOPTemplates();
  1768. }
  1769. else
  1770. {
  1771. hr = LoadGPOTemplates();
  1772. if (SUCCEEDED(hr))
  1773. {
  1774. TCHAR szUnknown[150];
  1775. LoadString (g_hInstance, IDS_NOSUPPORTINFO, szUnknown, ARRAYSIZE(szUnknown));
  1776. AddSupportedNode (&m_pSupportedStrings, szUnknown, TRUE);
  1777. if (m_bUserScope)
  1778. {
  1779. InitializeSupportInfo(m_pUserCategoryList, &m_pSupportedStrings);
  1780. }
  1781. else
  1782. {
  1783. InitializeSupportInfo(m_pMachineCategoryList, &m_pSupportedStrings);
  1784. }
  1785. }
  1786. }
  1787. Exit:
  1788. SetEvent (m_ADMEvent);
  1789. LeaveCriticalSection (&g_ADMCritSec);
  1790. DebugMsg((DM_VERBOSE, TEXT("CPolicyComponentData::LoadTemplates: Leaving")));
  1791. return hr;
  1792. }
  1793. BOOL CPolicyComponentData::ParseTemplate (LPTSTR lpFileName)
  1794. {
  1795. HANDLE hFile;
  1796. BOOL fMore;
  1797. UINT uRet;
  1798. LANGID langid;
  1799. TCHAR szLocalizedSection[20];
  1800. DWORD dwSize, dwRead;
  1801. LPVOID lpFile, lpTemp;
  1802. TCHAR szTempPath[MAX_PATH+1];
  1803. TCHAR szLocalPath[MAX_PATH+1];
  1804. //
  1805. // Verbose output
  1806. //
  1807. DebugMsg((DM_VERBOSE, TEXT("CPolicyComponentData::ParseTemplate: Loading <%s>..."),
  1808. lpFileName));
  1809. //
  1810. // Set defaults
  1811. //
  1812. m_nFileLine = 1;
  1813. m_pListCurrent = m_pMachineCategoryList;
  1814. m_pnDataItemCount = &m_nMachineDataItems;
  1815. m_pszParseFileName = lpFileName;
  1816. //
  1817. // Make a local copy of the adm file
  1818. //
  1819. if (!GetTempPath(ARRAYSIZE(szTempPath), szTempPath)) {
  1820. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::ParseTemplate: Failed to query for temp directory with error %d."), GetLastError()));
  1821. return FALSE;
  1822. }
  1823. if (!GetTempFileName (szTempPath, TEXT("adm"), 0, szLocalPath)) {
  1824. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::ParseTemplate: Failed to create temporary filename with error %d."), GetLastError()));
  1825. return FALSE;
  1826. }
  1827. DebugMsg((DM_VERBOSE, TEXT("CPolicyComponentData::ParseTemplate: Temp filename is <%s>"),
  1828. szLocalPath));
  1829. //
  1830. // Copy the file
  1831. //
  1832. if (!CopyFile(lpFileName, szLocalPath, FALSE)) {
  1833. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::ParseTemplate: Failed to copy adm file with error %d."), GetLastError()));
  1834. return FALSE;
  1835. }
  1836. DebugMsg((DM_VERBOSE, TEXT("CPolicyComponentData::ParseTemplate: ADM file copied successfully.")));
  1837. //
  1838. // Read in the adm file
  1839. //
  1840. hFile = CreateFile (szLocalPath, GENERIC_READ, FILE_SHARE_READ,
  1841. NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL |
  1842. FILE_FLAG_SEQUENTIAL_SCAN, NULL);
  1843. if (hFile == INVALID_HANDLE_VALUE)
  1844. {
  1845. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::ParseTemplate: Failed to load <%s> with %d"),
  1846. szLocalPath, GetLastError()));
  1847. DeleteFile (szLocalPath);
  1848. return FALSE;
  1849. }
  1850. dwSize = GetFileSize (hFile, NULL);
  1851. if (dwSize == 0xFFFFFFFF)
  1852. {
  1853. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::ParseTemplates: Failed to get file size with %d."),
  1854. GetLastError()));
  1855. CloseHandle (hFile);
  1856. DeleteFile (szLocalPath);
  1857. return FALSE;
  1858. }
  1859. if (!(lpFile = GlobalAlloc(GPTR, dwSize)))
  1860. {
  1861. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::ParseTemplates: Failed to allocate memory for %d bytes with %d."),
  1862. dwSize, GetLastError()));
  1863. CloseHandle (hFile);
  1864. DeleteFile (szLocalPath);
  1865. return FALSE;
  1866. }
  1867. if (!ReadFile (hFile, lpFile, dwSize, &dwRead, NULL))
  1868. {
  1869. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::ParseTemplates: Failed to read file with %d."),
  1870. GetLastError()));
  1871. GlobalFree(lpFile);
  1872. CloseHandle (hFile);
  1873. DeleteFile (szLocalPath);
  1874. return FALSE;
  1875. }
  1876. CloseHandle (hFile);
  1877. if (dwRead >= sizeof(WCHAR))
  1878. {
  1879. if (!IsTextUnicode(lpFile, dwRead, NULL))
  1880. {
  1881. if (!(lpTemp = GlobalAlloc(GPTR, dwSize * sizeof(WCHAR))))
  1882. {
  1883. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::ParseTemplates: Failed to allocate memory for %d WCHARS with %d."),
  1884. dwSize, GetLastError()));
  1885. GlobalFree(lpFile);
  1886. DeleteFile (szLocalPath);
  1887. return FALSE;
  1888. }
  1889. if ( !MultiByteToWideChar (CP_ACP, 0, (LPCSTR) lpFile, dwRead, (LPWSTR)lpTemp, dwRead) )
  1890. {
  1891. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::ParseTemplates: Failed to convert ANSI adm file to Unicode with %d."),
  1892. GetLastError()));
  1893. GlobalFree(lpTemp);
  1894. GlobalFree(lpFile);
  1895. DeleteFile (szLocalPath);
  1896. return FALSE;
  1897. }
  1898. GlobalFree (lpFile);
  1899. lpFile = lpTemp;
  1900. dwRead *= sizeof(WCHAR);
  1901. }
  1902. }
  1903. m_pFilePtr = (LPWSTR)lpFile;
  1904. m_pFileEnd = (LPWSTR)((LPBYTE)lpFile + dwRead - 1);
  1905. //
  1906. // Read in the string sections
  1907. //
  1908. langid = GetUserDefaultLangID();
  1909. wsprintf (szLocalizedSection, TEXT("%04x"), langid);
  1910. m_pLocaleStrings = GetStringSection (szLocalizedSection, szLocalPath);
  1911. wsprintf (szLocalizedSection, TEXT("%04x"), PRIMARYLANGID(langid));
  1912. m_pLanguageStrings = GetStringSection (szLocalizedSection, szLocalPath);
  1913. m_pDefaultStrings = GetStringSection (szStrings, szLocalPath);
  1914. DeleteFile (szLocalPath);
  1915. //
  1916. // Parse the file
  1917. //
  1918. m_fInComment = FALSE;
  1919. do {
  1920. uRet=ParseClass(&fMore);
  1921. } while (fMore && uRet == ERROR_SUCCESS);
  1922. //
  1923. // Cleanup
  1924. //
  1925. GlobalFree(lpFile);
  1926. if (m_pLocaleStrings)
  1927. {
  1928. GlobalFree(m_pLocaleStrings);
  1929. }
  1930. if (m_pLanguageStrings)
  1931. {
  1932. GlobalFree(m_pLanguageStrings);
  1933. }
  1934. if (m_pDefaultStrings)
  1935. {
  1936. GlobalFree(m_pDefaultStrings);
  1937. }
  1938. DebugMsg((DM_VERBOSE, TEXT("CPolicyComponentData::ParseTemplate: Finished.")));
  1939. return TRUE;
  1940. }
  1941. UINT CPolicyComponentData::ParseClass(BOOL *pfMore)
  1942. {
  1943. TCHAR szWordBuf[WORDBUFSIZE+1];
  1944. UINT uErr, nKeywordID, nClassID;
  1945. if (!GetNextWord(szWordBuf,ARRAYSIZE(szWordBuf),pfMore,&uErr))
  1946. return uErr;
  1947. if (!CompareKeyword(szWordBuf,pClassCmpList,&nKeywordID))
  1948. return ERROR_ALREADY_DISPLAYED;
  1949. switch (nKeywordID) {
  1950. case KYWD_ID_CATEGORY:
  1951. return ParseCategory(m_pListCurrent, FALSE,pfMore, NULL);
  1952. case KYWD_ID_CLASS:
  1953. if (!GetNextSectionWord(szWordBuf,ARRAYSIZE(szWordBuf),
  1954. pClassTypeCmpList,&nClassID,pfMore,&uErr))
  1955. return uErr;
  1956. switch (nClassID) {
  1957. case KYWD_ID_USER:
  1958. DebugMsg((DM_VERBOSE, TEXT("CPolicyComponentData::ParseClass: User section")));
  1959. m_pListCurrent = m_pUserCategoryList;
  1960. m_pnDataItemCount = &m_nUserDataItems;
  1961. m_bRetrieveString = (m_bUserScope ? TRUE : FALSE);
  1962. break;
  1963. case KYWD_ID_MACHINE:
  1964. DebugMsg((DM_VERBOSE, TEXT("CPolicyComponentData::ParseClass: Machine section")));
  1965. m_pListCurrent = m_pMachineCategoryList;
  1966. m_pnDataItemCount = &m_nMachineDataItems;
  1967. m_bRetrieveString = (m_bUserScope ? FALSE : TRUE);
  1968. break;
  1969. }
  1970. break;
  1971. // hack for localization: allow a "strings" section at the bottom, if we
  1972. // encounter that then we're thru with parsing
  1973. case KYWD_ID_STRINGSSECT:
  1974. *pfMore = FALSE; // that's all, folks
  1975. return ERROR_SUCCESS;
  1976. break;
  1977. }
  1978. return ERROR_SUCCESS;
  1979. }
  1980. TABLEENTRY * CPolicyComponentData::FindCategory(TABLEENTRY *pParent, LPTSTR lpName)
  1981. {
  1982. TABLEENTRY *pEntry = NULL, *pTemp;
  1983. if (m_bRetrieveString && pParent) {
  1984. pTemp = pParent->pChild;
  1985. while (pTemp) {
  1986. if (pTemp->dwType & ETYPE_CATEGORY) {
  1987. if (!lstrcmpi (lpName, GETNAMEPTR(pTemp))) {
  1988. pEntry = pTemp;
  1989. break;
  1990. }
  1991. }
  1992. pTemp = pTemp->pNext;
  1993. }
  1994. }
  1995. return pEntry;
  1996. }
  1997. /*******************************************************************
  1998. NAME: ParseEntry
  1999. SYNOPSIS: Main parsing "engine" for category, policy and part
  2000. parsing
  2001. NOTES: Allocates memory to build a temporary TABLEENTRY struct
  2002. describing the parsed information. Reads the beginning and end of a
  2003. section and loops through the words in each section, calling
  2004. a caller-defined ParseProc for each keyword to let the
  2005. caller handle appropriately. Passes the newly-constucted
  2006. TABLEENTRY to AddTableEntry to save it, and frees the temporary
  2007. memory.
  2008. This function is re-entrant.
  2009. The ENTRYDATA struct is declared on ParseEntry's stack
  2010. but used by the ParseProc to maintain state between
  2011. calls-- e.g., whether or not a key name has been found.
  2012. This can't be maintained as a static in the ParseProc because
  2013. the ParseProc may be reentered (for instance, if categories
  2014. have subcategories).
  2015. There are many possible error paths and there is some
  2016. memory dealloc that needs to be done in an error case. Rather
  2017. than do deallocs by hand on every error path or use a "goto
  2018. cleanup" (ick!), items to be freed are added to a "cleanup
  2019. list" and then CleanupAndReturn is called in an error condition,
  2020. which frees items on the list and returns a specified value.
  2021. ENTRY: ppes-- PARSEENTRYSTRUCT that specifes type of entry, the
  2022. parent table, a keyword list, a ParseProc callback
  2023. and other goodies
  2024. pfMore-- set to FALSE if at end of file
  2025. EXIT: ERROR_SUCCESS if successful, otherwise an error code
  2026. (can be ERROR_ALREADY_DISPLAYED)
  2027. ********************************************************************/
  2028. UINT CPolicyComponentData::ParseEntry(PARSEENTRYSTRUCT *ppes,BOOL *pfMore,
  2029. LPTSTR pKeyName)
  2030. {
  2031. TCHAR szWordBuf[WORDBUFSIZE+1];
  2032. UINT uErr,nListIndex;
  2033. BOOL fFoundEnd = FALSE;
  2034. PARSEPROCSTRUCT pps;
  2035. ENTRYDATA EntryData;
  2036. DWORD dwBufSize = DEFAULT_TMP_BUF_SIZE;
  2037. TABLEENTRY *pTmp = NULL;
  2038. BOOL bNewEntry = TRUE;
  2039. memset(&pps,0,sizeof(pps));
  2040. memset(&EntryData,0,sizeof(EntryData));
  2041. pps.pdwBufSize = &dwBufSize;
  2042. pps.pData = &EntryData;
  2043. pps.pData->fParentHasKey = ppes->fParentHasKey;
  2044. pps.pEntryCmpList = ppes->pEntryCmpList;
  2045. // get the entry name
  2046. if (!GetNextSectionWord(szWordBuf,ARRAYSIZE(szWordBuf),NULL,NULL,pfMore,&uErr)) {
  2047. return uErr;
  2048. }
  2049. if (ppes->dwEntryType & ETYPE_CATEGORY) {
  2050. pTmp = FindCategory (ppes->pParent, szWordBuf);
  2051. }
  2052. if (pTmp) {
  2053. bNewEntry = FALSE;
  2054. } else {
  2055. //
  2056. // Create a new table entry
  2057. //
  2058. if (!(pps.pTableEntry = (TABLEENTRY *) GlobalAlloc(GPTR,*pps.pdwBufSize)))
  2059. return ERROR_NOT_ENOUGH_MEMORY;
  2060. // initialize TABLEENTRY struct
  2061. pps.pTableEntry->dwSize = ppes->dwStructSize;
  2062. pps.pTableEntry->dwType = ppes->dwEntryType;
  2063. // store the entry name in pTableEntry
  2064. pTmp = (TABLEENTRY *) AddDataToEntry(pps.pTableEntry,
  2065. (BYTE *)szWordBuf,(lstrlen(szWordBuf)+1) * sizeof(TCHAR),&(pps.pTableEntry->uOffsetName),
  2066. pps.pdwBufSize);
  2067. if (!pTmp) {
  2068. GlobalFree ((HGLOBAL)pps.pTableEntry);
  2069. return ERROR_NOT_ENOUGH_MEMORY;
  2070. }
  2071. }
  2072. pps.pTableEntry = pTmp;
  2073. // loop through the body of the declaration
  2074. while (!fFoundEnd && GetNextSectionWord(szWordBuf,
  2075. ARRAYSIZE(szWordBuf),pps.pEntryCmpList,&nListIndex,pfMore,&uErr)) {
  2076. if ( (uErr = (*ppes->pParseProc) (this, nListIndex,&pps,pfMore,&fFoundEnd,pKeyName))
  2077. != ERROR_SUCCESS) {
  2078. if (bNewEntry) {
  2079. GlobalFree ((HGLOBAL)pps.pTableEntry);
  2080. }
  2081. return (uErr);
  2082. }
  2083. if (!bNewEntry) {
  2084. if (pTmp != pps.pTableEntry) {
  2085. //
  2086. // We need to fix up the link list of pointers in case the tableentry
  2087. // has moved due to a realloc
  2088. //
  2089. if (pps.pTableEntry->pPrev) {
  2090. pps.pTableEntry->pPrev->pNext = pps.pTableEntry;
  2091. } else {
  2092. ppes->pParent->pChild = pps.pTableEntry;
  2093. }
  2094. if (pps.pTableEntry->pNext) {
  2095. pps.pTableEntry->pNext->pPrev = pps.pTableEntry;
  2096. }
  2097. pTmp = pps.pTableEntry;
  2098. }
  2099. }
  2100. }
  2101. if (uErr != ERROR_SUCCESS) {
  2102. if (bNewEntry) {
  2103. GlobalFree ((HGLOBAL)pps.pTableEntry);
  2104. }
  2105. return (uErr);
  2106. }
  2107. // Last word was "END"
  2108. // get the keyword that goes with "END" ("END CATGORY", "END POLICY", etc.)
  2109. if (!GetNextSectionWord(szWordBuf,ARRAYSIZE(szWordBuf),
  2110. ppes->pTypeCmpList,&nListIndex,pfMore,&uErr)) {
  2111. if (bNewEntry) {
  2112. GlobalFree ((HGLOBAL)pps.pTableEntry);
  2113. }
  2114. return (uErr);
  2115. }
  2116. // call the object's parse proc one last time to let it object if
  2117. // key name or something like that is missing
  2118. if ( (uErr = (*ppes->pParseProc) (this, KYWD_DONE,&pps,pfMore,&fFoundEnd,pKeyName))
  2119. != ERROR_SUCCESS) {
  2120. if (bNewEntry) {
  2121. GlobalFree ((HGLOBAL)pps.pTableEntry);
  2122. }
  2123. return (uErr);
  2124. }
  2125. if (bNewEntry) {
  2126. // fix up linked list pointers. If parent has no children yet, make this
  2127. // 1st child; otherwise walk the list of children and insert this at the end
  2128. if (!ppes->pParent->pChild) {
  2129. ppes->pParent->pChild = pps.pTableEntry;
  2130. } else {
  2131. TABLEENTRY * pLastChild = ppes->pParent->pChild;
  2132. while (pLastChild->pNext) {
  2133. pLastChild = pLastChild->pNext;
  2134. }
  2135. pLastChild->pNext = pps.pTableEntry;
  2136. pps.pTableEntry->pPrev = pLastChild;
  2137. }
  2138. }
  2139. return ERROR_SUCCESS;
  2140. }
  2141. /*******************************************************************
  2142. NAME: ParseCategory
  2143. SYNOPSIS: Parses a category
  2144. NOTES: Sets up a PARSEENTRYSTRUCT and lets ParseEntry do the
  2145. work.
  2146. ********************************************************************/
  2147. UINT CPolicyComponentData::ParseCategory(TABLEENTRY * pParent,
  2148. BOOL fParentHasKey,BOOL *pfMore,
  2149. LPTSTR pKeyName)
  2150. {
  2151. PARSEENTRYSTRUCT pes;
  2152. pes.pParent = pParent;
  2153. pes.dwEntryType = ETYPE_CATEGORY;
  2154. pes.pEntryCmpList = pCategoryEntryCmpList;
  2155. pes.pTypeCmpList = pCategoryTypeCmpList;
  2156. pes.pParseProc = CategoryParseProc;
  2157. pes.dwStructSize = sizeof(CATEGORY);
  2158. pes.fHasSubtable = TRUE;
  2159. pes.fParentHasKey = fParentHasKey;
  2160. return ParseEntry(&pes,pfMore,pKeyName);
  2161. }
  2162. /*******************************************************************
  2163. NAME: CategoryParseProc
  2164. SYNOPSIS: Keyword callback ParseProc for category parsing
  2165. ENTRY: nMsg-- index into pEntryCmpList array which specifies
  2166. keyword that was found.
  2167. ppps-- pointer to PARSEPROCSTRUCT that contains useful
  2168. data like a pointer to the TABLEENTRY being built
  2169. and a pointer to an ENTRYDATA struct to maintain
  2170. state between calls to the ParseProc
  2171. ********************************************************************/
  2172. UINT CPolicyComponentData::CategoryParseProc(CPolicyComponentData * pCD,
  2173. UINT nMsg,PARSEPROCSTRUCT * ppps,
  2174. BOOL * pfMore,BOOL * pfFoundEnd,
  2175. LPTSTR pKeyName)
  2176. {
  2177. TCHAR szWordBuf[WORDBUFSIZE+1];
  2178. CATEGORY * pCategory = (CATEGORY *) ppps->pTableEntry;
  2179. TABLEENTRY * pOld = ppps->pTableEntry, *pTmp;
  2180. LPTSTR lpHelpBuf;
  2181. UINT uErr;
  2182. switch (nMsg) {
  2183. case KYWD_ID_KEYNAME:
  2184. // have we already found a key name?
  2185. if (ppps->pData->fHasKey) {
  2186. pCD->DisplayKeywordError(IDS_ParseErr_DUPLICATE_KEYNAME,
  2187. NULL,NULL);
  2188. return ERROR_ALREADY_DISPLAYED;
  2189. }
  2190. // get the key name
  2191. if (!pCD->GetNextSectionWord(szWordBuf,ARRAYSIZE(szWordBuf),
  2192. NULL,NULL,pfMore,&uErr))
  2193. return uErr;
  2194. // store the key name in pCategory
  2195. pTmp = (TABLEENTRY *) pCD->AddDataToEntry((TABLEENTRY *) pCategory,
  2196. (BYTE *)szWordBuf,(lstrlen(szWordBuf)+1) * sizeof(TCHAR),&(pCategory->uOffsetKeyName),
  2197. ppps->pdwBufSize);
  2198. if (!pTmp)
  2199. return ERROR_NOT_ENOUGH_MEMORY;
  2200. ppps->pTableEntry = pTmp;
  2201. ppps->pData->fHasKey = TRUE;
  2202. return ERROR_SUCCESS;
  2203. break;
  2204. case KYWD_ID_END:
  2205. *pfFoundEnd = TRUE;
  2206. return ERROR_SUCCESS;
  2207. break;
  2208. case KYWD_ID_POLICY:
  2209. case KYWD_ID_CATEGORY:
  2210. {
  2211. BOOL fHasKey = ppps->pData->fHasKey | ppps->pData->fParentHasKey;
  2212. if (nMsg == KYWD_ID_POLICY)
  2213. uErr=pCD->ParsePolicy((TABLEENTRY *) pCategory,fHasKey,pfMore,
  2214. (ppps->pData->fHasKey ? GETKEYNAMEPTR(pCategory) : pKeyName));
  2215. else
  2216. uErr=pCD->ParseCategory((TABLEENTRY *) pCategory,fHasKey,pfMore,
  2217. (ppps->pData->fHasKey ? GETKEYNAMEPTR(pCategory) : pKeyName));
  2218. }
  2219. return uErr;
  2220. break;
  2221. case KYWD_ID_HELP:
  2222. // have we already found a help string already?
  2223. if (pCategory->uOffsetHelp) {
  2224. pCD->DisplayKeywordError(IDS_ParseErr_DUPLICATE_HELP,
  2225. NULL,NULL);
  2226. return ERROR_ALREADY_DISPLAYED;
  2227. }
  2228. lpHelpBuf = (LPTSTR) LocalAlloc (LPTR, HELPBUFSIZE * sizeof(TCHAR));
  2229. if (!lpHelpBuf) {
  2230. pCD->DisplayKeywordError(IDS_ErrOUTOFMEMORY,NULL,NULL);
  2231. return ERROR_ALREADY_DISPLAYED;
  2232. }
  2233. // get the help string
  2234. if (!pCD->GetNextSectionWord(lpHelpBuf,HELPBUFSIZE,
  2235. NULL,NULL,pfMore,&uErr)) {
  2236. LocalFree (lpHelpBuf);
  2237. return uErr;
  2238. }
  2239. // store the help string
  2240. pTmp = (TABLEENTRY *) pCD->AddDataToEntry((TABLEENTRY *) pCategory,
  2241. (BYTE *)lpHelpBuf,(lstrlen(lpHelpBuf)+1) * sizeof(TCHAR),&(pCategory->uOffsetHelp),
  2242. ppps->pdwBufSize);
  2243. LocalFree (lpHelpBuf);
  2244. if (!pTmp)
  2245. return ERROR_NOT_ENOUGH_MEMORY;
  2246. ppps->pTableEntry = pTmp;
  2247. return ERROR_SUCCESS;
  2248. case KYWD_DONE:
  2249. if (!ppps->pData->fHasKey && pKeyName) {
  2250. // store the key name in pCategory
  2251. pTmp = (TABLEENTRY *) pCD->AddDataToEntry((TABLEENTRY *) pCategory,
  2252. (BYTE *)pKeyName,(lstrlen(pKeyName)+1) * sizeof(TCHAR),&(pCategory->uOffsetKeyName),
  2253. ppps->pdwBufSize);
  2254. if (!pTmp)
  2255. return ERROR_NOT_ENOUGH_MEMORY;
  2256. ppps->pTableEntry = pTmp;
  2257. ppps->pData->fHasKey = TRUE;
  2258. }
  2259. return ERROR_SUCCESS;
  2260. break;
  2261. default:
  2262. return ERROR_SUCCESS;
  2263. break;
  2264. }
  2265. }
  2266. /*******************************************************************
  2267. NAME: ParsePolicy
  2268. SYNOPSIS: Parses a policy
  2269. NOTES: Sets up a PARSEENTRYSTRUCT and lets ParseEntry do the
  2270. work.
  2271. ********************************************************************/
  2272. UINT CPolicyComponentData::ParsePolicy(TABLEENTRY * pParent,
  2273. BOOL fParentHasKey,BOOL *pfMore,
  2274. LPTSTR pKeyName)
  2275. {
  2276. PARSEENTRYSTRUCT pes;
  2277. pes.pParent = pParent;
  2278. pes.dwEntryType = ETYPE_POLICY;
  2279. pes.pEntryCmpList = pPolicyEntryCmpList;
  2280. pes.pTypeCmpList = pPolicyTypeCmpList;
  2281. pes.pParseProc = PolicyParseProc;
  2282. pes.dwStructSize = sizeof(POLICY);
  2283. pes.fHasSubtable = TRUE;
  2284. pes.fParentHasKey = fParentHasKey;
  2285. return ParseEntry(&pes,pfMore, pKeyName);
  2286. }
  2287. /*******************************************************************
  2288. NAME: PolicyParseProc
  2289. SYNOPSIS: Keyword callback ParseProc for policy parsing
  2290. ENTRY: nMsg-- index into pEntryCmpList array which specifies
  2291. keyword that was found.
  2292. ppps-- pointer to PARSEPROCSTRUCT that contains useful
  2293. data like a pointer to the TABLEENTRY being built
  2294. and a pointer to an ENTRYDATA struct to maintain
  2295. state between calls to the ParseProc
  2296. ********************************************************************/
  2297. UINT CPolicyComponentData::PolicyParseProc(CPolicyComponentData * pCD,
  2298. UINT nMsg,PARSEPROCSTRUCT * ppps,
  2299. BOOL * pfMore,BOOL * pfFoundEnd,LPTSTR pKeyName)
  2300. {
  2301. TCHAR szWordBuf[WORDBUFSIZE+1];
  2302. LPTSTR lpHelpBuf, lpKeyName;
  2303. POLICY * pPolicy = (POLICY *) ppps->pTableEntry;
  2304. TABLEENTRY * pOld = ppps->pTableEntry, *pTmp;
  2305. UINT uErr;
  2306. switch (nMsg) {
  2307. case KYWD_ID_KEYNAME:
  2308. // have we already found a key name?
  2309. if (ppps->pData->fHasKey) {
  2310. pCD->DisplayKeywordError(IDS_ParseErr_DUPLICATE_KEYNAME,
  2311. NULL,NULL);
  2312. return ERROR_ALREADY_DISPLAYED;
  2313. }
  2314. // get the key name
  2315. if (!pCD->GetNextSectionWord(szWordBuf,ARRAYSIZE(szWordBuf),
  2316. NULL,NULL,pfMore,&uErr))
  2317. return uErr;
  2318. // store the key name in pPolicy
  2319. pTmp = (TABLEENTRY *) pCD->AddDataToEntry((TABLEENTRY *) pPolicy,
  2320. (BYTE *)szWordBuf,(lstrlen(szWordBuf)+1)*sizeof(TCHAR),&(pPolicy->uOffsetKeyName),ppps->pdwBufSize);
  2321. if (!pTmp)
  2322. return ERROR_NOT_ENOUGH_MEMORY;
  2323. ppps->pTableEntry = pTmp;
  2324. ppps->pData->fHasKey = TRUE;
  2325. return ERROR_SUCCESS;
  2326. case KYWD_ID_VALUENAME:
  2327. // have we already found a key name?
  2328. if (ppps->pData->fHasValue) {
  2329. pCD->DisplayKeywordError(IDS_ParseErr_DUPLICATE_VALUENAME,
  2330. NULL,NULL);
  2331. return ERROR_ALREADY_DISPLAYED;
  2332. }
  2333. // get the key name
  2334. if (!pCD->GetNextSectionWord(szWordBuf,ARRAYSIZE(szWordBuf),
  2335. NULL,NULL,pfMore,&uErr))
  2336. return uErr;
  2337. // store the key name in pSettings
  2338. pTmp = (TABLEENTRY *) pCD->AddDataToEntry((TABLEENTRY *) pPolicy,
  2339. (BYTE *)szWordBuf,(lstrlen(szWordBuf)+1) * sizeof(TCHAR),&(pPolicy->uOffsetValueName),
  2340. ppps->pdwBufSize);
  2341. if (!pTmp)
  2342. return ERROR_NOT_ENOUGH_MEMORY;
  2343. ppps->pTableEntry = pTmp;
  2344. ppps->pData->fHasValue = TRUE;
  2345. return ERROR_SUCCESS;
  2346. case KYWD_ID_HELP:
  2347. // have we already found a help string already?
  2348. if (pPolicy->uOffsetHelp) {
  2349. pCD->DisplayKeywordError(IDS_ParseErr_DUPLICATE_HELP,
  2350. NULL,NULL);
  2351. return ERROR_ALREADY_DISPLAYED;
  2352. }
  2353. lpHelpBuf = (LPTSTR) LocalAlloc (LPTR, HELPBUFSIZE * sizeof(TCHAR));
  2354. if (!lpHelpBuf) {
  2355. pCD->DisplayKeywordError(IDS_ErrOUTOFMEMORY,NULL,NULL);
  2356. return ERROR_ALREADY_DISPLAYED;
  2357. }
  2358. // get the help string
  2359. if (!pCD->GetNextSectionWord(lpHelpBuf,HELPBUFSIZE,
  2360. NULL,NULL,pfMore,&uErr)) {
  2361. LocalFree (lpHelpBuf);
  2362. return uErr;
  2363. }
  2364. // store the help string
  2365. pTmp = (TABLEENTRY *) pCD->AddDataToEntry((TABLEENTRY *) pPolicy,
  2366. (BYTE *)lpHelpBuf,(lstrlen(lpHelpBuf)+1) * sizeof(TCHAR),&(pPolicy->uOffsetHelp),
  2367. ppps->pdwBufSize);
  2368. LocalFree (lpHelpBuf);
  2369. if (!pTmp)
  2370. return ERROR_NOT_ENOUGH_MEMORY;
  2371. ppps->pTableEntry = pTmp;
  2372. return ERROR_SUCCESS;
  2373. case KYWD_ID_CLIENTEXT:
  2374. // have we already found a clientext string already?
  2375. if (pPolicy->uOffsetClientExt) {
  2376. pCD->DisplayKeywordError(IDS_ParseErr_DUPLICATE_CLIENTEXT,
  2377. NULL,NULL);
  2378. return ERROR_ALREADY_DISPLAYED;
  2379. }
  2380. // get the key name
  2381. if (!pCD->GetNextSectionWord(szWordBuf,ARRAYSIZE(szWordBuf),
  2382. NULL,NULL,pfMore,&uErr))
  2383. return uErr;
  2384. if (!ValidateGuid(szWordBuf))
  2385. {
  2386. pCD->DisplayKeywordError(IDS_ParseErr_INVALID_CLIENTEXT,
  2387. NULL,NULL);
  2388. return ERROR_ALREADY_DISPLAYED;
  2389. }
  2390. // store the clientext string in pSettings
  2391. pTmp = (TABLEENTRY *) pCD->AddDataToEntry((TABLEENTRY *) pPolicy,
  2392. (BYTE *)szWordBuf,(lstrlen(szWordBuf)+1) * sizeof(TCHAR),&(pPolicy->uOffsetClientExt),
  2393. ppps->pdwBufSize);
  2394. if (!pTmp)
  2395. return ERROR_NOT_ENOUGH_MEMORY;
  2396. ppps->pTableEntry = pTmp;
  2397. return ERROR_SUCCESS;
  2398. case KYWD_ID_SUPPORTED:
  2399. // have we already found a supported string already?
  2400. if (pPolicy->uOffsetSupported) {
  2401. pCD->DisplayKeywordError(IDS_ParseErr_DUPLICATE_SUPPORTED,
  2402. NULL,NULL);
  2403. return ERROR_ALREADY_DISPLAYED;
  2404. }
  2405. // get the supported platforms
  2406. if (!pCD->GetNextSectionWord(szWordBuf,ARRAYSIZE(szWordBuf),
  2407. NULL,NULL,pfMore,&uErr))
  2408. return uErr;
  2409. // store the supported string in pSettings
  2410. pTmp = (TABLEENTRY *) pCD->AddDataToEntry((TABLEENTRY *) pPolicy,
  2411. (BYTE *)szWordBuf,(lstrlen(szWordBuf)+1) * sizeof(TCHAR),&(pPolicy->uOffsetSupported),
  2412. ppps->pdwBufSize);
  2413. if (!pTmp)
  2414. return ERROR_NOT_ENOUGH_MEMORY;
  2415. ppps->pTableEntry = pTmp;
  2416. return ERROR_SUCCESS;
  2417. case KYWD_ID_END:
  2418. *pfFoundEnd = TRUE;
  2419. return ERROR_SUCCESS;
  2420. case KYWD_ID_PART:
  2421. {
  2422. BOOL fHasKey = ppps->pData->fHasKey | ppps->pData->fParentHasKey;
  2423. return pCD->ParseSettings((TABLEENTRY *) pPolicy,fHasKey,pfMore,
  2424. (ppps->pData->fHasKey ? GETKEYNAMEPTR(pPolicy) : pKeyName));
  2425. }
  2426. case KYWD_ID_VALUEON:
  2427. return pCD->ParseValue(ppps,&pPolicy->uOffsetValue_On,
  2428. &ppps->pTableEntry,pfMore);
  2429. case KYWD_ID_VALUEOFF:
  2430. return pCD->ParseValue(ppps,&pPolicy->uOffsetValue_Off,
  2431. &ppps->pTableEntry,pfMore);
  2432. case KYWD_ID_ACTIONLISTON:
  2433. return pCD->ParseActionList(ppps,&pPolicy->uOffsetActionList_On,
  2434. &ppps->pTableEntry,szACTIONLISTON,pfMore);
  2435. case KYWD_ID_ACTIONLISTOFF:
  2436. return pCD->ParseActionList(ppps,&pPolicy->uOffsetActionList_Off,
  2437. &ppps->pTableEntry,szACTIONLISTOFF,pfMore);
  2438. case KYWD_DONE:
  2439. if (!ppps->pData->fHasKey) {
  2440. if (!ppps->pData->fParentHasKey) {
  2441. pCD->DisplayKeywordError(IDS_ParseErr_NO_KEYNAME,NULL,NULL);
  2442. return ERROR_ALREADY_DISPLAYED;
  2443. }
  2444. // store the key name in pPolicy
  2445. pTmp = (TABLEENTRY *) pCD->AddDataToEntry((TABLEENTRY *) pPolicy,
  2446. (BYTE *)pKeyName,(lstrlen(pKeyName)+1)*sizeof(TCHAR),&(pPolicy->uOffsetKeyName),ppps->pdwBufSize);
  2447. if (!pTmp)
  2448. return ERROR_NOT_ENOUGH_MEMORY;
  2449. ppps->pTableEntry = pTmp;
  2450. pPolicy = (POLICY *) pTmp;
  2451. ppps->pData->fHasKey = TRUE;
  2452. }
  2453. if (!pPolicy->uOffsetValueName && !pPolicy->pChild)
  2454. {
  2455. if ((!pPolicy->uOffsetValue_On && pPolicy->uOffsetValue_Off) ||
  2456. (pPolicy->uOffsetValue_On && !pPolicy->uOffsetValue_Off))
  2457. {
  2458. pCD->DisplayKeywordError(IDS_ParseErr_MISSINGVALUEON_OR_OFF,NULL,NULL);
  2459. return ERROR_ALREADY_DISPLAYED;
  2460. }
  2461. }
  2462. //
  2463. // Check if this is a real policy
  2464. //
  2465. lpKeyName = GETKEYNAMEPTR(ppps->pTableEntry);
  2466. if (!lpKeyName) {
  2467. return ERROR_INVALID_PARAMETER;
  2468. }
  2469. if (CompareString(LOCALE_USER_DEFAULT, NORM_IGNORECASE | NORM_STOP_ON_NULL,
  2470. lpKeyName, pCD->m_iSWPoliciesLen,
  2471. SOFTWARE_POLICIES, pCD->m_iSWPoliciesLen) == CSTR_EQUAL)
  2472. {
  2473. ((POLICY *) ppps->pTableEntry)->bTruePolicy = TRUE;
  2474. }
  2475. else if (CompareString(LOCALE_USER_DEFAULT, NORM_IGNORECASE | NORM_STOP_ON_NULL,
  2476. lpKeyName, pCD->m_iWinPoliciesLen,
  2477. WINDOWS_POLICIES, pCD->m_iWinPoliciesLen) == CSTR_EQUAL)
  2478. {
  2479. ((POLICY *) ppps->pTableEntry)->bTruePolicy = TRUE;
  2480. }
  2481. ( (POLICY *) ppps->pTableEntry)->uDataIndex = *pCD->m_pnDataItemCount;
  2482. (*pCD->m_pnDataItemCount) ++;
  2483. return ERROR_SUCCESS;
  2484. default:
  2485. break;
  2486. }
  2487. return ERROR_SUCCESS;
  2488. }
  2489. /*******************************************************************
  2490. NAME: ParseSettings
  2491. SYNOPSIS: Parses a policy setting
  2492. NOTES: Sets up a PARSEENTRYSTRUCT and lets ParseEntry do the
  2493. work.
  2494. ********************************************************************/
  2495. UINT CPolicyComponentData::ParseSettings(TABLEENTRY * pParent,
  2496. BOOL fParentHasKey,BOOL *pfMore,
  2497. LPTSTR pKeyName)
  2498. {
  2499. PARSEENTRYSTRUCT pes;
  2500. pes.pParent = pParent;
  2501. pes.dwEntryType = ETYPE_SETTING;
  2502. pes.pEntryCmpList = pSettingsEntryCmpList;
  2503. pes.pTypeCmpList = pSettingsTypeCmpList;
  2504. pes.pParseProc = SettingsParseProc;
  2505. pes.dwStructSize = sizeof(SETTINGS);
  2506. pes.fHasSubtable = FALSE;
  2507. pes.fParentHasKey = fParentHasKey;
  2508. return ParseEntry(&pes,pfMore, pKeyName);
  2509. }
  2510. /*******************************************************************
  2511. NAME: SettingsParseProc
  2512. SYNOPSIS: Keyword callback ParseProc for policy settings parsing
  2513. ENTRY: nMsg-- index into pEntryCmpList array which specifies
  2514. keyword that was found.
  2515. ppps-- pointer to PARSEPROCSTRUCT that contains useful
  2516. data like a pointer to the TABLEENTRY being built
  2517. and a pointer to an ENTRYDATA struct to maintain
  2518. state between calls to the ParseProc
  2519. ********************************************************************/
  2520. UINT CPolicyComponentData::SettingsParseProc(CPolicyComponentData *pCD,
  2521. UINT nMsg,PARSEPROCSTRUCT * ppps,
  2522. BOOL * pfMore,BOOL * pfFoundEnd,
  2523. LPTSTR pKeyName)
  2524. {
  2525. TCHAR szWordBuf[WORDBUFSIZE+1];
  2526. SETTINGS * pSettings = (SETTINGS *) ppps->pTableEntry;
  2527. BYTE * pObjectData = GETOBJECTDATAPTR(pSettings);
  2528. TABLEENTRY *pTmp;
  2529. UINT uErr;
  2530. switch (nMsg) {
  2531. case KYWD_ID_KEYNAME:
  2532. // have we already found a key name?
  2533. if (ppps->pData->fHasKey) {
  2534. pCD->DisplayKeywordError(IDS_ParseErr_DUPLICATE_KEYNAME,
  2535. NULL,NULL);
  2536. return ERROR_ALREADY_DISPLAYED;
  2537. }
  2538. // get the key name
  2539. if (!pCD->GetNextSectionWord(szWordBuf,ARRAYSIZE(szWordBuf),
  2540. NULL,NULL,pfMore,&uErr))
  2541. return uErr;
  2542. // store the key name in pSettings
  2543. pTmp = (TABLEENTRY *) pCD->AddDataToEntry((TABLEENTRY *) pSettings,
  2544. (BYTE *)szWordBuf,(lstrlen(szWordBuf)+1) * sizeof(TCHAR),&(pSettings->uOffsetKeyName),ppps->pdwBufSize);
  2545. if (!pTmp)
  2546. return ERROR_NOT_ENOUGH_MEMORY;
  2547. ppps->pTableEntry = pTmp;
  2548. ppps->pData->fHasKey = TRUE;
  2549. return ERROR_SUCCESS;
  2550. break;
  2551. case KYWD_ID_VALUENAME:
  2552. // have we already found a value name?
  2553. if (ppps->pData->fHasValue) {
  2554. pCD->DisplayKeywordError(IDS_ParseErr_DUPLICATE_VALUENAME,
  2555. NULL,NULL);
  2556. return ERROR_ALREADY_DISPLAYED;
  2557. }
  2558. // get the value name
  2559. if (!pCD->GetNextSectionWord(szWordBuf,ARRAYSIZE(szWordBuf),
  2560. NULL,NULL,pfMore,&uErr))
  2561. return uErr;
  2562. // store the value name in pSettings
  2563. pTmp = (TABLEENTRY *) pCD->AddDataToEntry((TABLEENTRY *) pSettings,
  2564. (BYTE *)szWordBuf,(lstrlen(szWordBuf)+1) * sizeof(TCHAR),&(pSettings->uOffsetValueName),
  2565. ppps->pdwBufSize);
  2566. if (!pTmp)
  2567. return ERROR_NOT_ENOUGH_MEMORY;
  2568. ppps->pTableEntry = pTmp;
  2569. ppps->pData->fHasValue = TRUE;
  2570. return ERROR_SUCCESS;
  2571. break;
  2572. case KYWD_ID_CLIENTEXT:
  2573. // have we already found a clientext string already?
  2574. if (pSettings->uOffsetClientExt) {
  2575. pCD->DisplayKeywordError(IDS_ParseErr_DUPLICATE_CLIENTEXT,
  2576. NULL,NULL);
  2577. return ERROR_ALREADY_DISPLAYED;
  2578. }
  2579. // get the clientext name
  2580. if (!pCD->GetNextSectionWord(szWordBuf,ARRAYSIZE(szWordBuf),
  2581. NULL,NULL,pfMore,&uErr))
  2582. return uErr;
  2583. if (!ValidateGuid(szWordBuf))
  2584. {
  2585. pCD->DisplayKeywordError(IDS_ParseErr_INVALID_CLIENTEXT,
  2586. NULL,NULL);
  2587. return ERROR_ALREADY_DISPLAYED;
  2588. }
  2589. // store the clientext string in pSettings
  2590. pTmp = (TABLEENTRY *) pCD->AddDataToEntry((TABLEENTRY *) pSettings,
  2591. (BYTE *)szWordBuf,(lstrlen(szWordBuf)+1) * sizeof(TCHAR),&(pSettings->uOffsetClientExt),
  2592. ppps->pdwBufSize);
  2593. if (!pTmp)
  2594. return ERROR_NOT_ENOUGH_MEMORY;
  2595. ppps->pTableEntry = pTmp;
  2596. return ERROR_SUCCESS;
  2597. case KYWD_ID_REQUIRED:
  2598. pSettings->dwFlags |= DF_REQUIRED;
  2599. return ERROR_SUCCESS;
  2600. break;
  2601. case KYWD_ID_EXPANDABLETEXT:
  2602. pSettings->dwFlags |= DF_EXPANDABLETEXT;
  2603. return ERROR_SUCCESS;
  2604. break;
  2605. case KYWD_ID_SUGGESTIONS:
  2606. return pCD->ParseSuggestions(ppps,&((POLICYCOMBOBOXINFO *)
  2607. (GETOBJECTDATAPTR(pSettings)))->uOffsetSuggestions,
  2608. &ppps->pTableEntry,pfMore);
  2609. case KYWD_ID_TXTCONVERT:
  2610. pSettings->dwFlags |= DF_TXTCONVERT;
  2611. return ERROR_SUCCESS;
  2612. break;
  2613. case KYWD_ID_END:
  2614. *pfFoundEnd = TRUE;
  2615. return ERROR_SUCCESS;
  2616. break;
  2617. case KYWD_ID_SOFT:
  2618. pSettings->dwFlags |= VF_SOFT;
  2619. return ERROR_SUCCESS;
  2620. break;
  2621. case KYWD_DONE:
  2622. if (!ppps->pData->fHasKey) {
  2623. if (!ppps->pData->fParentHasKey) {
  2624. pCD->DisplayKeywordError(IDS_ParseErr_NO_KEYNAME,NULL,NULL);
  2625. return ERROR_ALREADY_DISPLAYED;
  2626. }
  2627. // store the key name in pSettings
  2628. pTmp = (TABLEENTRY *) pCD->AddDataToEntry((TABLEENTRY *) pSettings,
  2629. (BYTE *)pKeyName,(lstrlen(pKeyName)+1) * sizeof(TCHAR),&(pSettings->uOffsetKeyName),ppps->pdwBufSize);
  2630. if (!pTmp)
  2631. return ERROR_NOT_ENOUGH_MEMORY;
  2632. ppps->pTableEntry = pTmp;
  2633. ppps->pData->fHasKey = TRUE;
  2634. }
  2635. if (!ppps->pData->fHasValue) {
  2636. pCD->DisplayKeywordError(IDS_ParseErr_NO_VALUENAME,NULL,NULL);
  2637. return ERROR_ALREADY_DISPLAYED;
  2638. }
  2639. ( (SETTINGS *) ppps->pTableEntry)->uDataIndex = *pCD->m_pnDataItemCount;
  2640. (*pCD->m_pnDataItemCount) ++;
  2641. return ERROR_SUCCESS;
  2642. break;
  2643. case KYWD_ID_CHECKBOX:
  2644. return (pCD->InitSettingsParse(ppps,ETYPE_SETTING | STYPE_CHECKBOX,
  2645. sizeof(CHECKBOXINFO),pCheckboxCmpList,&pSettings,&pObjectData));
  2646. break;
  2647. case KYWD_ID_TEXT:
  2648. ppps->pData->fHasValue = TRUE; // no key value for static text items
  2649. return (pCD->InitSettingsParse(ppps,ETYPE_SETTING | STYPE_TEXT,
  2650. 0,pTextCmpList,&pSettings,&pObjectData));
  2651. break;
  2652. case KYWD_ID_EDITTEXT:
  2653. uErr=pCD->InitSettingsParse(ppps,ETYPE_SETTING | STYPE_EDITTEXT,
  2654. sizeof(EDITTEXTINFO),pEditTextCmpList,&pSettings,&pObjectData);
  2655. if (uErr != ERROR_SUCCESS) return uErr;
  2656. {
  2657. EDITTEXTINFO *pEditTextInfo = (EDITTEXTINFO *)
  2658. (GETOBJECTDATAPTR(((SETTINGS *) ppps->pTableEntry)));
  2659. if (!pEditTextInfo) {
  2660. return ERROR_INVALID_PARAMETER;
  2661. }
  2662. pEditTextInfo->nMaxLen = MAXSTRLEN;
  2663. }
  2664. break;
  2665. case KYWD_ID_COMBOBOX:
  2666. uErr=pCD->InitSettingsParse(ppps,ETYPE_SETTING | STYPE_COMBOBOX,
  2667. sizeof(POLICYCOMBOBOXINFO),pComboboxCmpList,&pSettings,&pObjectData);
  2668. if (uErr != ERROR_SUCCESS) return uErr;
  2669. {
  2670. EDITTEXTINFO *pEditTextInfo = (EDITTEXTINFO *)
  2671. (GETOBJECTDATAPTR(((SETTINGS *) ppps->pTableEntry)));
  2672. pEditTextInfo->nMaxLen = MAXSTRLEN;
  2673. }
  2674. break;
  2675. case KYWD_ID_NUMERIC:
  2676. uErr=pCD->InitSettingsParse(ppps,ETYPE_SETTING | STYPE_NUMERIC,
  2677. sizeof(NUMERICINFO),pNumericCmpList,&pSettings,&pObjectData);
  2678. if (uErr != ERROR_SUCCESS) return uErr;
  2679. if (!pObjectData) return ERROR_INVALID_PARAMETER;
  2680. ( (NUMERICINFO *) pObjectData)->uDefValue = 1;
  2681. ( (NUMERICINFO *) pObjectData)->uMinValue = 1;
  2682. ( (NUMERICINFO *) pObjectData)->uMaxValue = 9999;
  2683. ( (NUMERICINFO *) pObjectData)->uSpinIncrement = 1;
  2684. break;
  2685. case KYWD_ID_DROPDOWNLIST:
  2686. ppps->pEntryCmpList = pDropdownlistCmpList;
  2687. ppps->pTableEntry->dwType = ETYPE_SETTING | STYPE_DROPDOWNLIST;
  2688. return ERROR_SUCCESS;
  2689. break;
  2690. case KYWD_ID_LISTBOX:
  2691. uErr=pCD->InitSettingsParse(ppps,ETYPE_SETTING | STYPE_LISTBOX,
  2692. sizeof(LISTBOXINFO),pListboxCmpList,&pSettings,&pObjectData);
  2693. if (uErr != ERROR_SUCCESS) return uErr;
  2694. // listboxes have no single value name, set the value name to ""
  2695. pTmp = (TABLEENTRY *) pCD->AddDataToEntry((TABLEENTRY *) pSettings,
  2696. (BYTE *) g_szNull,(lstrlen(g_szNull)+1) * sizeof(TCHAR),&(pSettings->uOffsetValueName),
  2697. ppps->pdwBufSize);
  2698. if (!pTmp)
  2699. return ERROR_NOT_ENOUGH_MEMORY;
  2700. ppps->pTableEntry = pTmp;
  2701. ppps->pData->fHasValue = TRUE;
  2702. return ERROR_SUCCESS;
  2703. break;
  2704. case KYWD_ID_EDITTEXT_DEFAULT:
  2705. case KYWD_ID_COMBOBOX_DEFAULT:
  2706. // get the default text
  2707. if (!pCD->GetNextSectionWord(szWordBuf,ARRAYSIZE(szWordBuf),
  2708. NULL,NULL,pfMore,&uErr))
  2709. return uErr;
  2710. // store the default text in pTableEntry
  2711. pTmp = (TABLEENTRY *) pCD->AddDataToEntry((TABLEENTRY *)
  2712. pSettings,(BYTE *)szWordBuf,(lstrlen(szWordBuf)+1) * sizeof(TCHAR),
  2713. &((EDITTEXTINFO *) (GETOBJECTDATAPTR(pSettings)))->uOffsetDefText,
  2714. ppps->pdwBufSize);
  2715. if (!pTmp)
  2716. return ERROR_NOT_ENOUGH_MEMORY;
  2717. ppps->pTableEntry = pTmp;
  2718. ((SETTINGS *) ppps->pTableEntry)->dwFlags |= DF_USEDEFAULT;
  2719. break;
  2720. case KYWD_ID_MAXLENGTH:
  2721. {
  2722. EDITTEXTINFO *pEditTextInfo = (EDITTEXTINFO *)
  2723. (GETOBJECTDATAPTR(pSettings));
  2724. if ((uErr=pCD->GetNextSectionNumericWord(
  2725. &pEditTextInfo->nMaxLen)) != ERROR_SUCCESS)
  2726. return uErr;
  2727. }
  2728. break;
  2729. case KYWD_ID_MAX:
  2730. if ((uErr=pCD->GetNextSectionNumericWord(
  2731. &((NUMERICINFO *)pObjectData)->uMaxValue)) != ERROR_SUCCESS)
  2732. return uErr;
  2733. break;
  2734. case KYWD_ID_MIN:
  2735. if ((uErr=pCD->GetNextSectionNumericWord(
  2736. &((NUMERICINFO *)pObjectData)->uMinValue)) != ERROR_SUCCESS)
  2737. return uErr;
  2738. break;
  2739. case KYWD_ID_SPIN:
  2740. if ((uErr=pCD->GetNextSectionNumericWord(
  2741. &((NUMERICINFO *)pObjectData)->uSpinIncrement)) != ERROR_SUCCESS)
  2742. return uErr;
  2743. break;
  2744. case KYWD_ID_NUMERIC_DEFAULT:
  2745. if ((uErr=pCD->GetNextSectionNumericWord(
  2746. &((NUMERICINFO *)pObjectData)->uDefValue)) != ERROR_SUCCESS)
  2747. return uErr;
  2748. pSettings->dwFlags |= (DF_DEFCHECKED | DF_USEDEFAULT);
  2749. break;
  2750. case KYWD_ID_DEFCHECKED:
  2751. pSettings->dwFlags |= (DF_DEFCHECKED | DF_USEDEFAULT);
  2752. break;
  2753. case KYWD_ID_VALUEON:
  2754. return pCD->ParseValue(ppps,&((CHECKBOXINFO *)
  2755. pObjectData)->uOffsetValue_On,
  2756. &ppps->pTableEntry,pfMore);
  2757. break;
  2758. case KYWD_ID_VALUEOFF:
  2759. return pCD->ParseValue(ppps,&((CHECKBOXINFO *)
  2760. pObjectData)->uOffsetValue_Off,
  2761. &ppps->pTableEntry,pfMore);
  2762. break;
  2763. case KYWD_ID_ACTIONLISTON:
  2764. return pCD->ParseActionList(ppps,&((CHECKBOXINFO *)
  2765. pObjectData)->uOffsetActionList_On,
  2766. &ppps->pTableEntry,szACTIONLISTON,pfMore);
  2767. break;
  2768. case KYWD_ID_ACTIONLISTOFF:
  2769. return pCD->ParseActionList(ppps,&((CHECKBOXINFO *)
  2770. pObjectData)->uOffsetActionList_Off,
  2771. &ppps->pTableEntry,szACTIONLISTOFF,pfMore);
  2772. break;
  2773. case KYWD_ID_ITEMLIST:
  2774. return pCD->ParseItemList(ppps,&pSettings->uOffsetObjectData,
  2775. pfMore);
  2776. break;
  2777. case KYWD_ID_VALUEPREFIX:
  2778. // get the string to be ised as prefix
  2779. if (!pCD->GetNextSectionWord(szWordBuf,ARRAYSIZE(szWordBuf),
  2780. NULL,NULL,pfMore,&uErr))
  2781. return uErr;
  2782. // store the string pTableEntry
  2783. pTmp = (TABLEENTRY *) pCD->AddDataToEntry((TABLEENTRY *)
  2784. pSettings,(BYTE *)szWordBuf,(lstrlen(szWordBuf)+1) * sizeof(TCHAR),
  2785. &((LISTBOXINFO *) (GETOBJECTDATAPTR(pSettings)))->uOffsetPrefix,
  2786. ppps->pdwBufSize);
  2787. if (!pTmp)
  2788. return ERROR_NOT_ENOUGH_MEMORY;
  2789. ppps->pTableEntry = pTmp;
  2790. break;
  2791. case KYWD_ID_ADDITIVE:
  2792. pSettings->dwFlags |= DF_ADDITIVE;
  2793. return ERROR_SUCCESS;
  2794. break;
  2795. case KYWD_ID_EXPLICITVALUE:
  2796. pSettings->dwFlags |= DF_EXPLICITVALNAME;
  2797. return ERROR_SUCCESS;
  2798. break;
  2799. case KYWD_ID_NOSORT:
  2800. pSettings->dwFlags |= DF_NOSORT;
  2801. break;
  2802. }
  2803. return ERROR_SUCCESS;
  2804. }
  2805. UINT CPolicyComponentData::InitSettingsParse(PARSEPROCSTRUCT *ppps,DWORD dwType,DWORD dwSize,
  2806. KEYWORDINFO * pKeyList,SETTINGS ** ppSettings,BYTE **ppObjectData)
  2807. {
  2808. TABLEENTRY *pTmp;
  2809. if (dwSize) {
  2810. // increase the buffer to fit object-specific data if specified
  2811. pTmp = (TABLEENTRY *) AddDataToEntry(ppps->pTableEntry,
  2812. NULL,dwSize,&( ((SETTINGS * )ppps->pTableEntry)->uOffsetObjectData),
  2813. ppps->pdwBufSize);
  2814. if (!pTmp) return ERROR_NOT_ENOUGH_MEMORY;
  2815. ppps->pTableEntry = pTmp;
  2816. }
  2817. else ( (SETTINGS *) ppps->pTableEntry)->uOffsetObjectData= 0;
  2818. ppps->pEntryCmpList = pKeyList;
  2819. ppps->pTableEntry->dwType = dwType;
  2820. *ppSettings = (SETTINGS *) ppps->pTableEntry;
  2821. *ppObjectData = GETOBJECTDATAPTR((*ppSettings));
  2822. return ERROR_SUCCESS;
  2823. }
  2824. UINT CPolicyComponentData::ParseValue_W(PARSEPROCSTRUCT * ppps,TCHAR * pszWordBuf,
  2825. DWORD cbWordBuf,DWORD * pdwValue,DWORD * pdwFlags,BOOL * pfMore)
  2826. {
  2827. UINT uErr;
  2828. *pdwFlags = 0;
  2829. *pdwValue = 0;
  2830. // get the next word
  2831. if (!GetNextSectionWord(pszWordBuf,cbWordBuf,
  2832. NULL,NULL,pfMore,&uErr))
  2833. return uErr;
  2834. // if this keyword is "SOFT", set the soft flag and get the next word
  2835. if (!lstrcmpi(szSOFT,pszWordBuf)) {
  2836. *pdwFlags |= VF_SOFT;
  2837. if (!GetNextSectionWord(pszWordBuf,cbWordBuf,
  2838. NULL,NULL,pfMore,&uErr))
  2839. return uErr;
  2840. }
  2841. // this word is either the value to use, or the keyword "NUMERIC"
  2842. // followed by a numeric value to use
  2843. if (!lstrcmpi(szNUMERIC,pszWordBuf)) {
  2844. // get the next word
  2845. if (!GetNextSectionWord(pszWordBuf,cbWordBuf,
  2846. NULL,NULL,pfMore,&uErr))
  2847. return uErr;
  2848. if (!StringToNum(pszWordBuf,(UINT *)pdwValue)) {
  2849. DisplayKeywordError(IDS_ParseErr_NOT_NUMERIC,
  2850. pszWordBuf,NULL);
  2851. return ERROR_ALREADY_DISPLAYED;
  2852. }
  2853. *pdwFlags |= VF_ISNUMERIC;
  2854. } else {
  2855. // "DELETE" is a special word
  2856. if (!lstrcmpi(pszWordBuf,szDELETE))
  2857. *pdwFlags |= VF_DELETE;
  2858. }
  2859. return ERROR_SUCCESS;
  2860. }
  2861. UINT CPolicyComponentData::ParseValue(PARSEPROCSTRUCT * ppps,UINT * puOffsetData,
  2862. TABLEENTRY ** ppTableEntryNew,BOOL * pfMore)
  2863. {
  2864. TCHAR szWordBuf[WORDBUFSIZE+1];
  2865. STATEVALUE * pStateValue;
  2866. DWORD dwValue;
  2867. DWORD dwFlags = 0;
  2868. DWORD dwAlloc;
  2869. UINT uErr;
  2870. TABLEENTRY *pTmp;
  2871. // call worker function
  2872. uErr=ParseValue_W(ppps,szWordBuf,ARRAYSIZE(szWordBuf),&dwValue,
  2873. &dwFlags,pfMore);
  2874. if (uErr != ERROR_SUCCESS) return uErr;
  2875. dwAlloc = sizeof(STATEVALUE);
  2876. if (!dwFlags) dwAlloc += (lstrlen(szWordBuf) + 1) * sizeof(TCHAR);
  2877. // allocate temporary buffer to build STATEVALUE struct
  2878. pStateValue = (STATEVALUE *) GlobalAlloc(GPTR,dwAlloc);
  2879. if (!pStateValue)
  2880. return ERROR_NOT_ENOUGH_MEMORY;
  2881. pStateValue->dwFlags = dwFlags;
  2882. if (dwFlags & VF_ISNUMERIC)
  2883. pStateValue->dwValue = dwValue;
  2884. else if (!dwFlags) {
  2885. lstrcpy(pStateValue->szValue,szWordBuf);
  2886. }
  2887. pTmp=(TABLEENTRY *) AddDataToEntry(ppps->pTableEntry,
  2888. (BYTE *) pStateValue,dwAlloc,puOffsetData,NULL);
  2889. GlobalFree(pStateValue);
  2890. if (!pTmp)
  2891. return ERROR_NOT_ENOUGH_MEMORY;
  2892. *ppTableEntryNew = pTmp;
  2893. return FALSE;
  2894. }
  2895. #define DEF_SUGGESTBUF_SIZE 1024
  2896. #define SUGGESTBUF_INCREMENT 256
  2897. UINT CPolicyComponentData::ParseSuggestions(PARSEPROCSTRUCT * ppps,UINT * puOffsetData,
  2898. TABLEENTRY ** ppTableEntryNew,BOOL * pfMore)
  2899. {
  2900. TCHAR szWordBuf[WORDBUFSIZE+1];
  2901. TCHAR *pTmpBuf, *pTmp;
  2902. DWORD dwAlloc=DEF_SUGGESTBUF_SIZE * sizeof(TCHAR);
  2903. DWORD dwUsed = 0;
  2904. BOOL fContinue = TRUE;
  2905. UINT uErr;
  2906. TABLEENTRY *pTmpTblEntry;
  2907. KEYWORDINFO pSuggestionsTypeCmpList[] = { {szSUGGESTIONS,KYWD_ID_SUGGESTIONS},
  2908. {NULL,0} };
  2909. if (!(pTmpBuf = (TCHAR *) GlobalAlloc(GPTR,dwAlloc)))
  2910. return ERROR_NOT_ENOUGH_MEMORY;
  2911. // get the next word
  2912. while (fContinue && GetNextSectionWord(szWordBuf,
  2913. ARRAYSIZE(szWordBuf),NULL,NULL,pfMore,&uErr)) {
  2914. // if this word is "END", add the whole list to the setting object data
  2915. if (!lstrcmpi(szEND,szWordBuf)) {
  2916. // get the next word after "END, make sure it's "SUGGESTIONS"
  2917. if (!GetNextSectionWord(szWordBuf,ARRAYSIZE(szWordBuf),
  2918. pSuggestionsTypeCmpList,NULL,pfMore,&uErr)) {
  2919. GlobalFree(pTmpBuf);
  2920. return uErr;
  2921. }
  2922. // doubly-NULL terminate the list
  2923. *(pTmpBuf+dwUsed) = '\0';
  2924. dwUsed++;
  2925. pTmpTblEntry=(TABLEENTRY *)AddDataToEntry(ppps->pTableEntry,
  2926. (BYTE *)pTmpBuf,(dwUsed * sizeof(TCHAR)),puOffsetData,NULL);
  2927. if (!pTmpTblEntry) {
  2928. GlobalFree(pTmpBuf);
  2929. return ERROR_NOT_ENOUGH_MEMORY;
  2930. }
  2931. *ppTableEntryNew = pTmpTblEntry;
  2932. fContinue = FALSE;
  2933. } else {
  2934. // pack the word into the temporary buffer
  2935. UINT nLength = lstrlen(szWordBuf);
  2936. DWORD dwNeeded = (dwUsed + nLength + 2) * sizeof(TCHAR);
  2937. // resize buffer as necessary
  2938. if (dwNeeded > dwAlloc) {
  2939. while (dwAlloc < dwNeeded)
  2940. dwAlloc += SUGGESTBUF_INCREMENT;
  2941. if (!(pTmp = (TCHAR *) GlobalReAlloc(pTmpBuf,dwAlloc,
  2942. GMEM_MOVEABLE | GMEM_ZEROINIT)))
  2943. {
  2944. GlobalFree (pTmpBuf);
  2945. return ERROR_NOT_ENOUGH_MEMORY;
  2946. }
  2947. pTmpBuf = pTmp;
  2948. }
  2949. lstrcpy(pTmpBuf + dwUsed,szWordBuf);
  2950. dwUsed += lstrlen(szWordBuf) +1;
  2951. }
  2952. }
  2953. GlobalFree(pTmpBuf);
  2954. return uErr;
  2955. }
  2956. UINT CPolicyComponentData::ParseActionList(PARSEPROCSTRUCT * ppps,UINT * puOffsetData,
  2957. TABLEENTRY ** ppTableEntryNew,
  2958. LPCTSTR pszKeyword,BOOL * pfMore)
  2959. {
  2960. TCHAR szWordBuf[WORDBUFSIZE+1];
  2961. ACTIONLIST *pActionList;
  2962. ACTION *pActionCurrent;
  2963. UINT uOffsetActionCurrent;
  2964. DWORD dwAlloc=(DEF_SUGGESTBUF_SIZE * sizeof(TCHAR));
  2965. DWORD dwUsed = sizeof(ACTION) + sizeof(UINT);
  2966. UINT uErr=ERROR_SUCCESS,nIndex;
  2967. BOOL fContinue = TRUE;
  2968. TABLEENTRY *pTmp;
  2969. KEYWORDINFO pActionlistTypeCmpList[] = { {szKEYNAME,KYWD_ID_KEYNAME},
  2970. {szVALUENAME,KYWD_ID_VALUENAME},{szVALUE,KYWD_ID_VALUE},
  2971. {szEND,KYWD_ID_END},{NULL,0} };
  2972. KEYWORDINFO pActionlistCmpList[] = { {pszKeyword,KYWD_ID_ACTIONLIST},
  2973. {NULL,0} };
  2974. BOOL fHasKeyName=FALSE,fHasValueName=FALSE;
  2975. if (!(pActionList = (ACTIONLIST *) GlobalAlloc(GPTR,dwAlloc)))
  2976. return ERROR_NOT_ENOUGH_MEMORY;
  2977. pActionCurrent = pActionList->Action;
  2978. uOffsetActionCurrent = sizeof(UINT);
  2979. // get the next word
  2980. while ((uErr == ERROR_SUCCESS) && fContinue &&
  2981. GetNextSectionWord(szWordBuf,ARRAYSIZE(szWordBuf),
  2982. pActionlistTypeCmpList,&nIndex,pfMore,&uErr)) {
  2983. switch (nIndex) {
  2984. case KYWD_ID_KEYNAME:
  2985. if (fHasKeyName) {
  2986. DisplayKeywordError(IDS_ParseErr_DUPLICATE_KEYNAME,
  2987. NULL,NULL);
  2988. uErr = ERROR_ALREADY_DISPLAYED;
  2989. break;
  2990. }
  2991. // get the next word, which is the key name
  2992. if (!GetNextSectionWord(szWordBuf,
  2993. ARRAYSIZE(szWordBuf),NULL,NULL,pfMore,&uErr))
  2994. break;
  2995. // store the key name away
  2996. if (!AddActionListString(szWordBuf,(lstrlen(szWordBuf)+1) * sizeof(TCHAR),
  2997. (BYTE **)&pActionList,
  2998. &pActionCurrent->uOffsetKeyName,&dwAlloc,&dwUsed)) {
  2999. uErr = ERROR_NOT_ENOUGH_MEMORY;
  3000. break;
  3001. }
  3002. fHasKeyName = TRUE;
  3003. pActionCurrent = (ACTION *) ((BYTE *) pActionList + uOffsetActionCurrent);
  3004. break;
  3005. case KYWD_ID_VALUENAME:
  3006. if (fHasValueName) {
  3007. DisplayKeywordError(IDS_ParseErr_DUPLICATE_KEYNAME,
  3008. NULL,NULL);
  3009. uErr = ERROR_ALREADY_DISPLAYED;
  3010. break;
  3011. }
  3012. // get the next word, which is the value name
  3013. if (!GetNextSectionWord(szWordBuf,
  3014. ARRAYSIZE(szWordBuf),NULL,NULL,pfMore,&uErr))
  3015. break;
  3016. // store the value name away
  3017. if (!AddActionListString(szWordBuf,(lstrlen(szWordBuf)+1) * sizeof(TCHAR),
  3018. (BYTE **)&pActionList,
  3019. &pActionCurrent->uOffsetValueName,&dwAlloc,&dwUsed)) {
  3020. uErr = ERROR_NOT_ENOUGH_MEMORY;
  3021. break;
  3022. }
  3023. fHasValueName = TRUE;
  3024. pActionCurrent = (ACTION *) ((BYTE *) pActionList + uOffsetActionCurrent);
  3025. break;
  3026. case KYWD_ID_VALUE:
  3027. if (!fHasValueName) {
  3028. DisplayKeywordError(IDS_ParseErr_NO_VALUENAME,
  3029. NULL,NULL);
  3030. uErr = ERROR_ALREADY_DISPLAYED;
  3031. break;
  3032. }
  3033. // call worker function to get value and value type
  3034. uErr=ParseValue_W(ppps,szWordBuf,ARRAYSIZE(szWordBuf),
  3035. &pActionCurrent->dwValue,&pActionCurrent->dwFlags,pfMore);
  3036. if (uErr != ERROR_SUCCESS)
  3037. break;
  3038. // if value is string, add it to buffer
  3039. if (!pActionCurrent->dwFlags && !AddActionListString(szWordBuf,
  3040. (lstrlen(szWordBuf)+1) * sizeof(TCHAR),(BYTE **)&pActionList,
  3041. &pActionCurrent->uOffsetValue,&dwAlloc,&dwUsed)) {
  3042. uErr = ERROR_NOT_ENOUGH_MEMORY;
  3043. break;
  3044. }
  3045. pActionCurrent = (ACTION *) ((BYTE *) pActionList + uOffsetActionCurrent);
  3046. // done with this action in the list, get ready for the next one
  3047. pActionList->nActionItems++;
  3048. fHasValueName = fHasKeyName = FALSE;
  3049. uOffsetActionCurrent = dwUsed;
  3050. // make room for next ACTION struct
  3051. if (!AddActionListString(NULL,sizeof(ACTION),(BYTE **)&pActionList,
  3052. &pActionCurrent->uOffsetNextAction,&dwAlloc,&dwUsed)) {
  3053. uErr = ERROR_NOT_ENOUGH_MEMORY;
  3054. break;
  3055. }
  3056. pActionCurrent = (ACTION *) ((BYTE *) pActionList + uOffsetActionCurrent);
  3057. break;
  3058. case KYWD_ID_END:
  3059. if (fHasKeyName || fHasValueName) {
  3060. DisplayKeywordError(IDS_ParseErr_NO_VALUENAME,
  3061. NULL,NULL);
  3062. uErr = ERROR_ALREADY_DISPLAYED;
  3063. break;
  3064. }
  3065. // make sure word following "END" is "ACTIONLIST"
  3066. if (!GetNextSectionWord(szWordBuf,ARRAYSIZE(szWordBuf),
  3067. pActionlistCmpList,NULL,pfMore,&uErr)) {
  3068. break;
  3069. }
  3070. // commit the action list we've built to table entry
  3071. pTmp=(TABLEENTRY *)AddDataToEntry(ppps->pTableEntry,
  3072. (BYTE *)pActionList,dwUsed,puOffsetData,NULL);
  3073. if (!pTmp) {
  3074. uErr=ERROR_NOT_ENOUGH_MEMORY;
  3075. } else {
  3076. *ppTableEntryNew = pTmp;
  3077. uErr = ERROR_SUCCESS;
  3078. fContinue = FALSE;
  3079. }
  3080. break;
  3081. }
  3082. }
  3083. GlobalFree(pActionList);
  3084. return uErr;
  3085. }
  3086. UINT CPolicyComponentData::ParseItemList(PARSEPROCSTRUCT * ppps,UINT * puOffsetData,
  3087. BOOL * pfMore)
  3088. {
  3089. // ptr to location to put the offset to next DROPDOWNINFO struct in chain
  3090. UINT * puLastOffsetPtr = puOffsetData;
  3091. TABLEENTRY * pTableEntryOld, *pTmp;
  3092. int nItemIndex=-1;
  3093. BOOL fHasItemName = FALSE,fHasActionList=FALSE,fHasValue=FALSE,fFirst=TRUE;
  3094. DROPDOWNINFO * pddi;
  3095. TCHAR szWordBuf[WORDBUFSIZE+1];
  3096. UINT uErr=ERROR_SUCCESS,nIndex;
  3097. KEYWORDINFO pItemlistTypeCmpList[] = { {szNAME,KYWD_ID_NAME},
  3098. {szACTIONLIST,KYWD_ID_ACTIONLIST},{szVALUE,KYWD_ID_VALUE},
  3099. {szEND,KYWD_ID_END},{szDEFAULT,KYWD_ID_DEFAULT},{NULL,0} };
  3100. KEYWORDINFO pItemlistCmpList[] = { {szITEMLIST,KYWD_ID_ITEMLIST},
  3101. {NULL,0} };
  3102. // get the next word
  3103. while ((uErr == ERROR_SUCCESS) &&
  3104. GetNextSectionWord(szWordBuf,ARRAYSIZE(szWordBuf),
  3105. pItemlistTypeCmpList,&nIndex,pfMore,&uErr)) {
  3106. switch (nIndex) {
  3107. case KYWD_ID_NAME:
  3108. // if this is the first keyword after a prior item
  3109. // (e.g., item and value flags both set) reset for next one
  3110. if (fHasItemName && fHasValue) {
  3111. fHasValue = fHasActionList= fHasItemName = FALSE;
  3112. puLastOffsetPtr = &pddi->uOffsetNextDropdowninfo;
  3113. }
  3114. if (fHasItemName) {
  3115. DisplayKeywordError(IDS_ParseErr_DUPLICATE_ITEMNAME,
  3116. NULL,NULL);
  3117. uErr = ERROR_ALREADY_DISPLAYED;
  3118. break;
  3119. }
  3120. // get the next word, which is the item name
  3121. if (!GetNextSectionWord(szWordBuf,
  3122. ARRAYSIZE(szWordBuf),NULL,NULL,pfMore,&uErr))
  3123. break;
  3124. // add room for a DROPDOWNINFO struct at end of buffer
  3125. pTableEntryOld=ppps->pTableEntry;
  3126. pTmp=(TABLEENTRY *)AddDataToEntry(ppps->pTableEntry,
  3127. NULL,sizeof(DROPDOWNINFO),puLastOffsetPtr,NULL);
  3128. if (!pTmp)
  3129. return ERROR_NOT_ENOUGH_MEMORY;
  3130. ppps->pTableEntry = pTmp;
  3131. // adjust pointer to offset, in case table moved
  3132. puLastOffsetPtr = (UINT *) (((BYTE *) puLastOffsetPtr) +
  3133. ((BYTE *) ppps->pTableEntry - (BYTE *) pTableEntryOld));
  3134. pddi = (DROPDOWNINFO *)
  3135. ((BYTE *) ppps->pTableEntry + *puLastOffsetPtr);
  3136. // store the key name away
  3137. pTableEntryOld=ppps->pTableEntry;
  3138. pTmp=(TABLEENTRY *)AddDataToEntry(ppps->pTableEntry,
  3139. (BYTE *)szWordBuf,(lstrlen(szWordBuf)+1)*sizeof(TCHAR),&pddi->uOffsetItemName,
  3140. NULL);
  3141. if (!pTmp)
  3142. return ERROR_NOT_ENOUGH_MEMORY;
  3143. ppps->pTableEntry = pTmp;
  3144. // adjust pointer to offset, in case table moved
  3145. puLastOffsetPtr = (UINT *) (((BYTE *) puLastOffsetPtr) +
  3146. ((BYTE *) ppps->pTableEntry - (BYTE *) pTableEntryOld));
  3147. pddi = (DROPDOWNINFO *)
  3148. ((BYTE *) ppps->pTableEntry + *puLastOffsetPtr);
  3149. nItemIndex++;
  3150. fHasItemName = TRUE;
  3151. break;
  3152. case KYWD_ID_DEFAULT:
  3153. if (nItemIndex<0) {
  3154. DisplayKeywordError(IDS_ParseErr_NO_ITEMNAME,
  3155. NULL,NULL);
  3156. uErr = ERROR_ALREADY_DISPLAYED;
  3157. break;
  3158. }
  3159. ( (SETTINGS *) ppps->pTableEntry)->dwFlags |= DF_USEDEFAULT;
  3160. ( (DROPDOWNINFO *) GETOBJECTDATAPTR(((SETTINGS *)ppps->pTableEntry)))
  3161. ->uDefaultItemIndex = nItemIndex;
  3162. break;
  3163. case KYWD_ID_VALUE:
  3164. if (!fHasItemName) {
  3165. DisplayKeywordError(IDS_ParseErr_NO_ITEMNAME,
  3166. NULL,NULL);
  3167. uErr = ERROR_ALREADY_DISPLAYED;
  3168. break;
  3169. }
  3170. // call worker function to get value and value type
  3171. uErr=ParseValue_W(ppps,szWordBuf,ARRAYSIZE(szWordBuf),
  3172. &pddi->dwValue,&pddi->dwFlags,pfMore);
  3173. if (uErr != ERROR_SUCCESS)
  3174. break;
  3175. // if value is string, add it to buffer
  3176. if (!pddi->dwFlags) {
  3177. // store the key name away
  3178. TABLEENTRY * pTmp;
  3179. pTableEntryOld = ppps->pTableEntry;
  3180. pTmp=(TABLEENTRY *) AddDataToEntry(ppps->pTableEntry,
  3181. (BYTE *)szWordBuf,(lstrlen(szWordBuf)+1)*sizeof(TCHAR),&pddi->uOffsetValue,
  3182. NULL);
  3183. if (!pTmp)
  3184. return ERROR_NOT_ENOUGH_MEMORY;
  3185. ppps->pTableEntry = pTmp;
  3186. // adjust pointer to offset, in case table moved
  3187. puLastOffsetPtr = (UINT *) (((BYTE *) puLastOffsetPtr) +
  3188. ((BYTE *) ppps->pTableEntry - (BYTE *) pTableEntryOld));
  3189. pddi = (DROPDOWNINFO *)
  3190. ((BYTE *) ppps->pTableEntry + *puLastOffsetPtr);
  3191. }
  3192. fHasValue = TRUE;
  3193. break;
  3194. case KYWD_ID_ACTIONLIST:
  3195. if (!fHasItemName) {
  3196. DisplayKeywordError(IDS_ParseErr_NO_ITEMNAME,
  3197. NULL,NULL);
  3198. uErr = ERROR_ALREADY_DISPLAYED;
  3199. break;
  3200. }
  3201. if (fHasActionList) {
  3202. DisplayKeywordError(IDS_ParseErr_DUPLICATE_ACTIONLIST,
  3203. NULL,NULL);
  3204. uErr = ERROR_ALREADY_DISPLAYED;
  3205. break;
  3206. }
  3207. pTableEntryOld=ppps->pTableEntry;
  3208. uErr=ParseActionList(ppps,&pddi->uOffsetActionList,
  3209. &ppps->pTableEntry,szACTIONLIST,pfMore);
  3210. if (uErr != ERROR_SUCCESS)
  3211. return uErr;
  3212. // adjust pointer to offset, in case table moved
  3213. puLastOffsetPtr = (UINT *) (((BYTE *) puLastOffsetPtr) +
  3214. ((BYTE *) ppps->pTableEntry - (BYTE *) pTableEntryOld));
  3215. pddi = (DROPDOWNINFO *)
  3216. ((BYTE *) ppps->pTableEntry + *puLastOffsetPtr);
  3217. fHasActionList = TRUE;
  3218. break;
  3219. case KYWD_ID_END:
  3220. if (!fHasItemName) {
  3221. DisplayKeywordError(IDS_ParseErr_NO_ITEMNAME,
  3222. NULL,NULL);
  3223. uErr = ERROR_ALREADY_DISPLAYED;
  3224. break;
  3225. }
  3226. if (!fHasValue) {
  3227. DisplayKeywordError(IDS_ParseErr_NO_VALUE,
  3228. NULL,NULL);
  3229. uErr = ERROR_ALREADY_DISPLAYED;
  3230. break;
  3231. }
  3232. // make sure word following "END" is "ITEMLIST"
  3233. if (!GetNextSectionWord(szWordBuf,ARRAYSIZE(szWordBuf),
  3234. pItemlistCmpList,NULL,pfMore,&uErr)) {
  3235. break;
  3236. }
  3237. return ERROR_SUCCESS;
  3238. break;
  3239. }
  3240. }
  3241. return uErr;
  3242. }
  3243. BOOL CPolicyComponentData::AddActionListString(TCHAR * pszData,DWORD cbData,BYTE ** ppBase,UINT * puOffset,
  3244. DWORD * pdwAlloc,DWORD *pdwUsed)
  3245. {
  3246. DWORD dwNeeded = *pdwUsed + cbData, dwAdd;
  3247. BYTE *pOldBase;
  3248. dwAdd = dwNeeded % sizeof(DWORD);
  3249. dwNeeded += dwAdd;
  3250. // realloc if necessary
  3251. if (dwNeeded > *pdwAlloc) {
  3252. while (*pdwAlloc < dwNeeded)
  3253. *pdwAlloc += SUGGESTBUF_INCREMENT;
  3254. pOldBase = *ppBase;
  3255. if (!(*ppBase = (BYTE *) GlobalReAlloc(*ppBase,*pdwAlloc,
  3256. GMEM_MOVEABLE | GMEM_ZEROINIT))) {
  3257. *ppBase = pOldBase; // restore the old value
  3258. return FALSE;
  3259. }
  3260. puOffset = (UINT *)(*ppBase + ((BYTE *)puOffset - pOldBase));
  3261. }
  3262. *puOffset = *pdwUsed;
  3263. if (pszData) memcpy(*ppBase + *puOffset,pszData,cbData);
  3264. *pdwUsed = dwNeeded;
  3265. return TRUE;
  3266. }
  3267. BYTE * CPolicyComponentData::AddDataToEntry(TABLEENTRY * pTableEntry,
  3268. BYTE * pData,UINT cbData,
  3269. UINT * puOffsetData,DWORD * pdwBufSize)
  3270. {
  3271. TABLEENTRY * pTemp;
  3272. DWORD dwNeeded,dwOldSize = pTableEntry->dwSize, dwNewDataSize, dwAdd;
  3273. // puOffsetData points to location that holds the offset to the
  3274. // new data-- size we're adding this to the end of the table, the
  3275. // offset will be the current size of the table. Set this offset
  3276. // in *puOffsetData. Also, notice we touch *puOffsetData BEFORE
  3277. // the realloc, in case puOffsetData points into the region being
  3278. // realloced and the block of memory moves.
  3279. //
  3280. *puOffsetData = pTableEntry->dwSize;
  3281. // reallocate entry buffer if necessary
  3282. dwNewDataSize = cbData;
  3283. dwAdd = dwNewDataSize % sizeof(DWORD);
  3284. dwNewDataSize += dwAdd;
  3285. dwNeeded = pTableEntry->dwSize + dwNewDataSize;
  3286. if (!(pTemp = (TABLEENTRY *) GlobalReAlloc(pTableEntry,
  3287. dwNeeded,GMEM_ZEROINIT | GMEM_MOVEABLE)))
  3288. return NULL;
  3289. pTableEntry = pTemp;
  3290. pTableEntry->dwSize = dwNeeded;
  3291. if (pData) memcpy((BYTE *)pTableEntry + dwOldSize,pData,cbData);
  3292. if (pdwBufSize) *pdwBufSize = pTableEntry->dwSize;
  3293. return (BYTE *) pTableEntry;
  3294. }
  3295. /*******************************************************************
  3296. NAME: CompareKeyword
  3297. SYNOPSIS: Compares a specified buffer to a list of valid keywords.
  3298. If it finds a match, the index of the match in the list
  3299. is returned in *pnListIndex. Otherwise an error message
  3300. is displayed.
  3301. EXIT: Returns TRUE if a keyword match is found, FALSE otherwise.
  3302. If TRUE, *pnListIndex contains matching index.
  3303. ********************************************************************/
  3304. BOOL CPolicyComponentData::CompareKeyword(TCHAR * szWord,KEYWORDINFO *pKeywordList,
  3305. UINT * pnListIndex)
  3306. {
  3307. KEYWORDINFO * pKeywordInfo = pKeywordList;
  3308. while (pKeywordInfo->pWord) {
  3309. if (!lstrcmpi(szWord,pKeywordInfo->pWord)) {
  3310. if (pnListIndex)
  3311. *pnListIndex = pKeywordInfo->nID;
  3312. return TRUE;
  3313. }
  3314. pKeywordInfo ++;
  3315. }
  3316. DisplayKeywordError(IDS_ParseErr_UNEXPECTED_KEYWORD,
  3317. szWord,pKeywordList);
  3318. return FALSE;
  3319. }
  3320. /*******************************************************************
  3321. NAME: GetNextWord
  3322. SYNOPSIS: Fills input buffer with next word in file stream
  3323. NOTES: Calls GetNextChar() to get character stream. Whitespace
  3324. and comments are skipped. Quoted strings are returned
  3325. as one word (including whitespace) with the quotes removed.
  3326. EXIT: If successful, returns a pointer to the input buffer
  3327. (szBuf). *pfMore indicates if there are more words to
  3328. be read. If an error occurs, its value is returned in *puErr.
  3329. ********************************************************************/
  3330. TCHAR * CPolicyComponentData::GetNextWord(TCHAR * szBuf,UINT cbBuf,BOOL * pfMore,
  3331. UINT * puErr)
  3332. {
  3333. TCHAR * pChar;
  3334. BOOL fInWord = FALSE;
  3335. BOOL fInQuote = FALSE;
  3336. BOOL fEmptyString = FALSE;
  3337. TCHAR * pWord = szBuf;
  3338. UINT cbWord = 0;
  3339. LPTSTR lpTemp;
  3340. // clear buffer to start with
  3341. lstrcpy(szBuf,g_szNull);
  3342. while (pChar = GetNextChar(pfMore,puErr)) {
  3343. // keep track of which file line we're on
  3344. if (IsEndOfLine(pChar)) m_nFileLine++;
  3345. // keep track of wheter we are inside quoted string or not
  3346. if (IsQuote(pChar) && !m_fInComment) {
  3347. if (!fInQuote)
  3348. fInQuote = TRUE; // entering quoted string
  3349. else {
  3350. fInQuote = FALSE; // leaving quoted string
  3351. if (cbWord == 0) {
  3352. // special case "" to be an empty string
  3353. DebugMsg((DM_VERBOSE, TEXT("CPolicyComponentData::GetNextWord: Found empty quotes")));
  3354. fEmptyString = TRUE;
  3355. }
  3356. break; // end of word
  3357. }
  3358. }
  3359. if (!fInQuote) {
  3360. // skip over lines with comments (';')
  3361. if (!m_fInComment && IsComment(pChar)) m_fInComment = TRUE;
  3362. if (m_fInComment) {
  3363. if (IsEndOfLine(pChar)) {
  3364. m_fInComment = FALSE;
  3365. }
  3366. continue;
  3367. }
  3368. if (IsWhitespace(pChar)) {
  3369. // if we haven't found word yet, skip over whitespace
  3370. if (!fInWord)
  3371. continue;
  3372. // otherwise, whitespace signals end of word
  3373. break;
  3374. }
  3375. }
  3376. // found a non-comment, non-whitespace character
  3377. if (!fInWord) fInWord = TRUE;
  3378. if (!IsQuote(pChar)) {
  3379. // add this character to word
  3380. *pWord = *pChar;
  3381. pWord++;
  3382. cbWord++;
  3383. if (cbWord >= cbBuf) {
  3384. *(pWord - 1) = TEXT('\0');
  3385. MsgBoxParam(NULL,IDS_WORDTOOLONG,szBuf,MB_ICONEXCLAMATION,MB_OK);
  3386. *puErr = ERROR_ALREADY_DISPLAYED;
  3387. goto Exit;
  3388. }
  3389. #if 0
  3390. if (IsDBCSLeadByte((BYTE) *pChar)) {
  3391. *pWord = *pChar;
  3392. pWord++;
  3393. cbWord++;
  3394. }
  3395. #endif
  3396. }
  3397. }
  3398. *pWord = '\0'; // null-terminate
  3399. // if found string a la '!!foo', then look for a string in the [strings]
  3400. // section with the key name 'foo' and use that instead. This is because
  3401. // our localization tools are brainless and require a [strings] section.
  3402. // So although template files are sectionless, we allow a [strings] section
  3403. // at the bottom.
  3404. if (IsLocalizedString(szBuf)) {
  3405. lpTemp = (LPTSTR) GlobalAlloc (GPTR, (cbBuf * sizeof(TCHAR)));
  3406. if (!lpTemp) {
  3407. *puErr = GetLastError();
  3408. return NULL;
  3409. }
  3410. if (GetString (m_pLocaleStrings, szBuf+2, lpTemp, cbBuf) ||
  3411. GetString (m_pLanguageStrings, szBuf+2, lpTemp, cbBuf) ||
  3412. GetString (m_pDefaultStrings, szBuf+2, lpTemp, cbBuf))
  3413. {
  3414. lstrcpy(szBuf, lpTemp);
  3415. GlobalFree (lpTemp);
  3416. }
  3417. else
  3418. {
  3419. DisplayKeywordError(IDS_ParseErr_STRING_NOT_FOUND,
  3420. szBuf,NULL);
  3421. *puErr=ERROR_ALREADY_DISPLAYED;
  3422. GlobalFree (lpTemp);
  3423. return NULL;
  3424. }
  3425. } else {
  3426. *puErr = ProcessIfdefs(szBuf,cbBuf,pfMore);
  3427. if (*puErr == ERROR_SUCCESS)
  3428. {
  3429. if ((szBuf[0] == TEXT('\0')) && (!fEmptyString))
  3430. {
  3431. fInWord = FALSE;
  3432. }
  3433. }
  3434. }
  3435. Exit:
  3436. if (*puErr != ERROR_SUCCESS || !fInWord) return NULL;
  3437. return szBuf;
  3438. }
  3439. /*******************************************************************
  3440. NAME: GetNextSectionWord
  3441. SYNOPSIS: Gets next word and warns if end-of-file encountered.
  3442. Optionally checks the keyword against a list of valid
  3443. keywords.
  3444. NOTES: Calls GetNextWord() to get word. This is called in
  3445. situations where we expect there to be another word
  3446. (e.g., inside a section) and it's an error if the
  3447. file ends.
  3448. ********************************************************************/
  3449. TCHAR * CPolicyComponentData::GetNextSectionWord(TCHAR * szBuf,UINT cbBuf,
  3450. KEYWORDINFO * pKeywordList,
  3451. UINT *pnListIndex,
  3452. BOOL * pfMore,UINT * puErr)
  3453. {
  3454. TCHAR * pch;
  3455. if (!(pch=GetNextWord(szBuf,cbBuf,pfMore,puErr))) {
  3456. if (!*pfMore && *puErr != ERROR_ALREADY_DISPLAYED) {
  3457. DisplayKeywordError(IDS_ParseErr_UNEXPECTED_EOF,
  3458. NULL,pKeywordList);
  3459. *puErr = ERROR_ALREADY_DISPLAYED;
  3460. }
  3461. return NULL;
  3462. }
  3463. if (pKeywordList && !CompareKeyword(szBuf,pKeywordList,pnListIndex)) {
  3464. *puErr = ERROR_ALREADY_DISPLAYED;
  3465. return NULL;
  3466. }
  3467. return pch;
  3468. }
  3469. /*******************************************************************
  3470. NAME: GetNextSectionNumericWord
  3471. SYNOPSIS: Gets next word and converts string to number. Warns if
  3472. not a numeric value
  3473. ********************************************************************/
  3474. UINT CPolicyComponentData::GetNextSectionNumericWord(UINT * pnVal)
  3475. {
  3476. UINT uErr;
  3477. TCHAR szWordBuf[WORDBUFSIZE];
  3478. BOOL fMore;
  3479. if (!GetNextSectionWord(szWordBuf,ARRAYSIZE(szWordBuf),
  3480. NULL,NULL,&fMore,&uErr))
  3481. return uErr;
  3482. if (!StringToNum(szWordBuf,pnVal)) {
  3483. DisplayKeywordError(IDS_ParseErr_NOT_NUMERIC,szWordBuf,
  3484. NULL);
  3485. return ERROR_ALREADY_DISPLAYED;
  3486. }
  3487. return ERROR_SUCCESS;
  3488. }
  3489. /*******************************************************************
  3490. NAME: GetNextChar
  3491. SYNOPSIS: Returns a pointer to the next character from the
  3492. file stream.
  3493. ********************************************************************/
  3494. TCHAR * CPolicyComponentData::GetNextChar(BOOL * pfMore,UINT * puErr)
  3495. {
  3496. TCHAR * pCurrentChar;
  3497. *puErr = ERROR_SUCCESS;
  3498. if (m_pFilePtr > m_pFileEnd) {
  3499. *pfMore = FALSE;
  3500. return NULL;
  3501. }
  3502. pCurrentChar = m_pFilePtr;
  3503. m_pFilePtr = CharNext(m_pFilePtr);
  3504. *pfMore = TRUE;
  3505. return pCurrentChar;
  3506. }
  3507. /*******************************************************************
  3508. NAME: GetString
  3509. SYNOPSIS: Returns the display string
  3510. ********************************************************************/
  3511. BOOL CPolicyComponentData::GetString (LPTSTR pStringSection,
  3512. LPTSTR lpStringName,
  3513. LPTSTR lpResult, DWORD dwSize)
  3514. {
  3515. LPTSTR lpTemp, lpDest;
  3516. DWORD dwCCH, dwIndex;
  3517. BOOL bFoundQuote = FALSE;
  3518. TCHAR cTestChar;
  3519. if (!pStringSection)
  3520. {
  3521. return FALSE;
  3522. }
  3523. if (!m_bRetrieveString)
  3524. {
  3525. lpResult = TEXT('\0');
  3526. return TRUE;
  3527. }
  3528. lpTemp = pStringSection;
  3529. dwCCH = lstrlen (lpStringName);
  3530. while (*lpTemp)
  3531. {
  3532. cTestChar = *(lpTemp + dwCCH);
  3533. if ((cTestChar == TEXT('=')) || (cTestChar == TEXT(' ')))
  3534. {
  3535. if (CompareString (LOCALE_USER_DEFAULT, NORM_IGNORECASE | NORM_STOP_ON_NULL,
  3536. lpStringName, dwCCH, lpTemp, dwCCH) == CSTR_EQUAL)
  3537. {
  3538. lpTemp += dwCCH;
  3539. while (*lpTemp == TEXT(' '))
  3540. lpTemp++;
  3541. if (*lpTemp == TEXT('='))
  3542. {
  3543. lpTemp++;
  3544. if (*lpTemp == TEXT('\"'))
  3545. {
  3546. lpTemp++;
  3547. bFoundQuote = TRUE;
  3548. }
  3549. lpDest = lpResult;
  3550. dwIndex = 0;
  3551. while (*lpTemp && (dwIndex < dwSize))
  3552. {
  3553. if ((*lpTemp == TEXT('\\')) && (*(lpTemp+1) == TEXT('\0')))
  3554. {
  3555. lpTemp += 2;
  3556. }
  3557. else
  3558. {
  3559. *lpDest = *lpTemp;
  3560. lpDest++;
  3561. lpTemp++;
  3562. dwIndex++;
  3563. }
  3564. }
  3565. if (dwIndex == dwSize)
  3566. {
  3567. lpDest--;
  3568. *lpDest = TEXT('\0');
  3569. MsgBoxParam(NULL,IDS_STRINGTOOLONG,lpResult,MB_ICONEXCLAMATION,MB_OK);
  3570. }
  3571. else
  3572. {
  3573. *lpDest = TEXT('\0');
  3574. }
  3575. if (bFoundQuote)
  3576. {
  3577. lpTemp = lpResult + lstrlen (lpResult) - 1;
  3578. if (*lpTemp == TEXT('\"'))
  3579. {
  3580. *lpTemp = TEXT('\0');
  3581. }
  3582. }
  3583. //
  3584. // Replace any \n combinations with a CR LF
  3585. //
  3586. lpTemp = lpResult;
  3587. while (*lpTemp)
  3588. {
  3589. if ((*lpTemp == TEXT('\\')) && (*(lpTemp + 1) == TEXT('n')))
  3590. {
  3591. *lpTemp = TEXT('\r');
  3592. lpTemp++;
  3593. *lpTemp = TEXT('\n');
  3594. }
  3595. lpTemp++;
  3596. }
  3597. return TRUE;
  3598. }
  3599. }
  3600. }
  3601. lpTemp += lstrlen (lpTemp) + 1;
  3602. }
  3603. return FALSE;
  3604. }
  3605. BOOL CPolicyComponentData::IsComment(TCHAR * pBuf)
  3606. {
  3607. return (*pBuf == TEXT(';'));
  3608. }
  3609. BOOL CPolicyComponentData::IsQuote(TCHAR * pBuf)
  3610. {
  3611. return (*pBuf == TEXT('\"'));
  3612. }
  3613. BOOL CPolicyComponentData::IsEndOfLine(TCHAR * pBuf)
  3614. {
  3615. return (*pBuf == TEXT('\r')); // CR
  3616. }
  3617. BOOL CPolicyComponentData::IsWhitespace(TCHAR * pBuf)
  3618. {
  3619. return ( *pBuf == TEXT(' ') // space
  3620. || *pBuf == TEXT('\r') // CR
  3621. || *pBuf == TEXT('\n') // LF
  3622. || *pBuf == TEXT('\t') // tab
  3623. || *pBuf == 0x001A // EOF
  3624. || *pBuf == 0xFEFF // Unicode marker
  3625. );
  3626. }
  3627. BOOL CPolicyComponentData::IsLocalizedString(TCHAR * pBuf)
  3628. {
  3629. return (*pBuf == TEXT('!') && *(pBuf+1) == TEXT('!'));
  3630. }
  3631. #define MSGSIZE 1024
  3632. #define FMTSIZE 512
  3633. VOID CPolicyComponentData::DisplayKeywordError(UINT uErrorID,TCHAR * szFound,
  3634. KEYWORDINFO * pExpectedList)
  3635. {
  3636. TCHAR * pMsg,*pFmt,*pErrTxt,*pTmp;
  3637. pMsg = (TCHAR *) GlobalAlloc(GPTR,(MSGSIZE * sizeof(TCHAR)));
  3638. pFmt = (TCHAR *) GlobalAlloc(GPTR,(FMTSIZE * sizeof(TCHAR)));
  3639. pErrTxt = (TCHAR *) GlobalAlloc(GPTR,(FMTSIZE * sizeof(TCHAR)));
  3640. pTmp = (TCHAR *) GlobalAlloc(GPTR,(FMTSIZE * sizeof(TCHAR)));
  3641. if (!pMsg || !pFmt || !pErrTxt || !pTmp) {
  3642. if (pMsg) GlobalFree(pMsg);
  3643. if (pFmt) GlobalFree(pFmt);
  3644. if (pErrTxt) GlobalFree(pErrTxt);
  3645. if (pTmp) GlobalFree(pTmp);
  3646. MsgBox(NULL,IDS_ErrOUTOFMEMORY,MB_ICONEXCLAMATION,MB_OK);
  3647. return;
  3648. }
  3649. LoadSz(IDS_ParseFmt_MSG_FORMAT,pFmt,FMTSIZE);
  3650. wsprintf(pMsg,pFmt,m_pszParseFileName,m_nFileLine,uErrorID,LoadSz(uErrorID,
  3651. pErrTxt,FMTSIZE));
  3652. if (szFound) {
  3653. LoadSz(IDS_ParseFmt_FOUND,pFmt,FMTSIZE);
  3654. wsprintf(pTmp,pFmt,szFound);
  3655. lstrcat(pMsg,pTmp);
  3656. }
  3657. if (pExpectedList) {
  3658. UINT nIndex=0;
  3659. LoadSz(IDS_ParseFmt_EXPECTED,pFmt,FMTSIZE);
  3660. lstrcpy(pErrTxt,g_szNull);
  3661. while (pExpectedList[nIndex].pWord) {
  3662. lstrcat(pErrTxt,pExpectedList[nIndex].pWord);
  3663. if (pExpectedList[nIndex+1].pWord) {
  3664. lstrcat(pErrTxt,TEXT(", "));
  3665. }
  3666. nIndex++;
  3667. }
  3668. wsprintf(pTmp,pFmt,pErrTxt);
  3669. lstrcat(pMsg,pTmp);
  3670. }
  3671. lstrcat(pMsg,LoadSz(IDS_ParseFmt_FATAL,pTmp,FMTSIZE));
  3672. DebugMsg((DM_WARNING, TEXT("Keyword error: %s"), pMsg));
  3673. MsgBoxSz(NULL,pMsg,MB_ICONEXCLAMATION,MB_OK);
  3674. GlobalFree(pMsg);
  3675. GlobalFree(pFmt);
  3676. GlobalFree(pErrTxt);
  3677. GlobalFree(pTmp);
  3678. }
  3679. int CPolicyComponentData::MsgBox(HWND hWnd,UINT nResource,UINT uIcon,UINT uButtons)
  3680. {
  3681. TCHAR szMsgBuf[REGBUFLEN];
  3682. TCHAR szSmallBuf[SMALLBUF];
  3683. LoadSz(IDS_POLICY_NAME,szSmallBuf,ARRAYSIZE(szSmallBuf));
  3684. LoadSz(nResource,szMsgBuf,ARRAYSIZE(szMsgBuf));
  3685. MessageBeep(uIcon);
  3686. return (MessageBox(hWnd,szMsgBuf,szSmallBuf,uIcon | uButtons));
  3687. }
  3688. int CPolicyComponentData::MsgBoxSz(HWND hWnd,LPTSTR szText,UINT uIcon,UINT uButtons)
  3689. {
  3690. TCHAR szSmallBuf[SMALLBUF];
  3691. LoadSz(IDS_POLICY_NAME,szSmallBuf,ARRAYSIZE(szSmallBuf));
  3692. MessageBeep(uIcon);
  3693. return (MessageBox(hWnd,szText,szSmallBuf,uIcon | uButtons));
  3694. }
  3695. int CPolicyComponentData::MsgBoxParam(HWND hWnd,UINT nResource,TCHAR * szReplaceText,UINT uIcon,
  3696. UINT uButtons)
  3697. {
  3698. TCHAR szFormat[REGBUFLEN];
  3699. LPTSTR lpMsgBuf;
  3700. INT iResult;
  3701. lpMsgBuf = (LPTSTR) LocalAlloc (LPTR, (lstrlen(szReplaceText) + 1 + REGBUFLEN) * sizeof(TCHAR));
  3702. if (!lpMsgBuf)
  3703. {
  3704. return 0;
  3705. }
  3706. LoadSz(nResource,szFormat,ARRAYSIZE(szFormat));
  3707. wsprintf(lpMsgBuf,szFormat,szReplaceText);
  3708. iResult = MsgBoxSz(hWnd,lpMsgBuf,uIcon,uButtons);
  3709. LocalFree (lpMsgBuf);
  3710. return iResult;
  3711. }
  3712. LPTSTR CPolicyComponentData::LoadSz(UINT idString,LPTSTR lpszBuf,UINT cbBuf)
  3713. {
  3714. // Clear the buffer and load the string
  3715. if ( lpszBuf )
  3716. {
  3717. *lpszBuf = TEXT('\0');
  3718. LoadString( g_hInstance, idString, lpszBuf, cbBuf );
  3719. }
  3720. return lpszBuf;
  3721. }
  3722. BOOL fFilterDirectives = TRUE;
  3723. UINT nGlobalNestedLevel = 0;
  3724. // reads up through the matching directive #endif in current scope
  3725. //and sets file pointer immediately past the directive
  3726. UINT CPolicyComponentData::FindMatchingDirective(BOOL *pfMore,BOOL fElseOK)
  3727. {
  3728. TCHAR szWordBuf[WORDBUFSIZE];
  3729. UINT uErr=ERROR_SUCCESS,nNestedLevel=1;
  3730. BOOL fContinue = TRUE;
  3731. // set the flag to stop catching '#' directives in low level word-fetching
  3732. // routine
  3733. fFilterDirectives = FALSE;
  3734. // keep reading words. Keep track of how many layers of #ifdefs deep we
  3735. // are. Every time we encounter an #ifdef or #ifndef, increment the level
  3736. // count (nNestedLevel) by one. For every #endif decrement the level count.
  3737. // When the level count hits zero, we've found the matching #endif.
  3738. while (nNestedLevel > 0) {
  3739. if (!GetNextSectionWord(szWordBuf,ARRAYSIZE(szWordBuf),NULL,NULL,
  3740. pfMore,&uErr))
  3741. break;
  3742. if (!lstrcmpi(szWordBuf,szIFDEF) || !lstrcmpi(szWordBuf,szIFNDEF) ||
  3743. !lstrcmpi(szWordBuf,szIF))
  3744. nNestedLevel ++;
  3745. else if (!lstrcmpi(szWordBuf,szENDIF)) {
  3746. nNestedLevel --;
  3747. }
  3748. else if (!lstrcmpi(szWordBuf,szELSE) && (nNestedLevel == 1)) {
  3749. if (fElseOK) {
  3750. // ignore "#else" unless it's on the same level as the #ifdef
  3751. // we're finding a match for (nNestedLevel == 1), in which
  3752. // case treat it as the matching directive
  3753. nNestedLevel --;
  3754. // increment global nesting so we expect an #endif to come along
  3755. // later to match this #else
  3756. nGlobalNestedLevel++;
  3757. } else {
  3758. // found a #else where we already had a #else in this level
  3759. DisplayKeywordError(IDS_ParseErr_UNMATCHED_DIRECTIVE,
  3760. szWordBuf,NULL);
  3761. return ERROR_ALREADY_DISPLAYED;
  3762. }
  3763. }
  3764. }
  3765. fFilterDirectives = TRUE;
  3766. return uErr;
  3767. }
  3768. // if the word in the word buffer is #ifdef, #if, #ifndef, #else or #endif,
  3769. // this function reads ahead an appropriate amount (
  3770. UINT CPolicyComponentData::ProcessIfdefs(TCHAR * pBuf,UINT cbBuf,BOOL * pfMore)
  3771. {
  3772. UINT uRet;
  3773. if (!fFilterDirectives)
  3774. return ERROR_SUCCESS;
  3775. if (!lstrcmpi(pBuf,szIFDEF)) {
  3776. // we've found an '#ifdef <something or other>, where ISV policy editors
  3777. // can understand particular keywords they make up. We don't have any
  3778. // #ifdef keywords of our own so always skip this
  3779. uRet = FindMatchingDirective(pfMore,TRUE);
  3780. if (uRet != ERROR_SUCCESS)
  3781. return uRet;
  3782. if (!GetNextWord(pBuf,cbBuf,pfMore,&uRet))
  3783. return uRet;
  3784. return ERROR_SUCCESS;
  3785. } else if (!lstrcmpi(pBuf,szIFNDEF)) {
  3786. // this is an #ifndef, and since nothing is ever ifdef'd for our policy
  3787. // editor, this always evaluates to TRUE
  3788. // keep reading this section but increment the nested level count,
  3789. // when we find the matching #endif or #else we'll be able to respond
  3790. // correctly
  3791. nGlobalNestedLevel ++;
  3792. // get next word (e.g. "foo" for #ifndef foo) and throw it away
  3793. if (!GetNextWord(pBuf,cbBuf,pfMore,&uRet))
  3794. return uRet;
  3795. // get next word and return it for real
  3796. if (!GetNextWord(pBuf,cbBuf,pfMore,&uRet))
  3797. return uRet;
  3798. return ERROR_SUCCESS;
  3799. } else if (!lstrcmpi(pBuf,szENDIF)) {
  3800. // if we ever encounter an #endif here, we must have processed
  3801. // the preceeding section. Just step over the #endif and go on
  3802. if (!nGlobalNestedLevel) {
  3803. // found an endif without a preceeding #if<xx>
  3804. DisplayKeywordError(IDS_ParseErr_UNMATCHED_DIRECTIVE,
  3805. pBuf,NULL);
  3806. return ERROR_ALREADY_DISPLAYED;
  3807. }
  3808. nGlobalNestedLevel--;
  3809. if (!GetNextWord(pBuf,cbBuf,pfMore,&uRet))
  3810. return uRet;
  3811. return ERROR_SUCCESS;
  3812. } else if (!lstrcmpi(pBuf,szIF)) {
  3813. // syntax is "#if VERSION (comparision) (version #)"
  3814. // e.g. "#if VERSION >= 2"
  3815. TCHAR szWordBuf[WORDBUFSIZE];
  3816. UINT nIndex,nVersion,nOperator;
  3817. BOOL fDirectiveTrue = FALSE;
  3818. // get the next word (must be "VERSION")
  3819. if (!GetNextSectionWord(szWordBuf,ARRAYSIZE(szWordBuf),
  3820. pVersionCmpList,&nIndex,pfMore,&uRet))
  3821. return uRet;
  3822. // get the comparison operator (>, <, ==, >=, <=)
  3823. if (!GetNextSectionWord(szWordBuf,ARRAYSIZE(szWordBuf),
  3824. pOperatorCmpList,&nOperator,pfMore,&uRet))
  3825. return uRet;
  3826. // get the version number
  3827. uRet=GetNextSectionNumericWord(&nVersion);
  3828. if (uRet != ERROR_SUCCESS)
  3829. return uRet;
  3830. // now evaluate the directive
  3831. switch (nOperator) {
  3832. case KYWD_ID_GT:
  3833. fDirectiveTrue = (CURRENT_ADM_VERSION > nVersion);
  3834. break;
  3835. case KYWD_ID_GTE:
  3836. fDirectiveTrue = (CURRENT_ADM_VERSION >= nVersion);
  3837. break;
  3838. case KYWD_ID_LT:
  3839. fDirectiveTrue = (CURRENT_ADM_VERSION < nVersion);
  3840. break;
  3841. case KYWD_ID_LTE:
  3842. fDirectiveTrue = (CURRENT_ADM_VERSION <= nVersion);
  3843. break;
  3844. case KYWD_ID_EQ:
  3845. fDirectiveTrue = (CURRENT_ADM_VERSION == nVersion);
  3846. break;
  3847. case KYWD_ID_NE:
  3848. fDirectiveTrue = (CURRENT_ADM_VERSION != nVersion);
  3849. break;
  3850. }
  3851. if (fDirectiveTrue) {
  3852. // keep reading this section but increment the nested level count,
  3853. // when we find the matching #endif or #else we'll be able to respond
  3854. // correctly
  3855. nGlobalNestedLevel ++;
  3856. } else {
  3857. // skip over this section
  3858. uRet = FindMatchingDirective(pfMore,TRUE);
  3859. if (uRet != ERROR_SUCCESS)
  3860. return uRet;
  3861. }
  3862. // get next word and return it for real
  3863. if (!GetNextWord(pBuf,cbBuf,pfMore,&uRet))
  3864. return uRet;
  3865. return ERROR_SUCCESS;
  3866. } else if (!lstrcmpi(pBuf,szELSE)) {
  3867. // found an #else, which means we took the upper branch, skip over
  3868. // the lower branch
  3869. if (!nGlobalNestedLevel) {
  3870. // found an #else without a preceeding #if<xx>
  3871. DisplayKeywordError(IDS_ParseErr_UNMATCHED_DIRECTIVE,
  3872. pBuf,NULL);
  3873. return ERROR_ALREADY_DISPLAYED;
  3874. }
  3875. nGlobalNestedLevel--;
  3876. uRet = FindMatchingDirective(pfMore,FALSE);
  3877. if (uRet != ERROR_SUCCESS)
  3878. return uRet;
  3879. if (!GetNextWord(pBuf,cbBuf,pfMore,&uRet))
  3880. return uRet;
  3881. return ERROR_SUCCESS;
  3882. }
  3883. return ERROR_SUCCESS;
  3884. }
  3885. /*******************************************************************
  3886. NAME: FreeTable
  3887. SYNOPSIS: Frees the specified table and all sub-tables of that
  3888. table.
  3889. NOTES: Walks through the table entries and calls itself to
  3890. recursively free sub-tables.
  3891. EXIT: Returns TRUE if successful, FALSE if a memory error
  3892. occurs.
  3893. ********************************************************************/
  3894. BOOL CPolicyComponentData::FreeTable(TABLEENTRY * pTableEntry)
  3895. {
  3896. TABLEENTRY * pNext = pTableEntry->pNext;
  3897. // free all children
  3898. if (pTableEntry->pChild)
  3899. FreeTable(pTableEntry->pChild);
  3900. GlobalFree(pTableEntry);
  3901. if (pNext) FreeTable(pNext);
  3902. return TRUE;
  3903. }
  3904. LPTSTR CPolicyComponentData::GetStringSection (LPCTSTR lpSection, LPCTSTR lpFileName)
  3905. {
  3906. DWORD dwSize, dwRead;
  3907. LPTSTR lpStrings;
  3908. //
  3909. // Read in the default strings section
  3910. //
  3911. dwSize = STRINGS_BUF_SIZE;
  3912. lpStrings = (TCHAR *) GlobalAlloc (GPTR, dwSize * sizeof(TCHAR));
  3913. if (!lpStrings)
  3914. {
  3915. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::GetStringSection: Failed to alloc memory for default strings with %d."),
  3916. GetLastError()));
  3917. return NULL;
  3918. }
  3919. do {
  3920. dwRead = GetPrivateProfileSection (lpSection,
  3921. lpStrings,
  3922. dwSize, lpFileName);
  3923. if (dwRead != (dwSize - 2))
  3924. {
  3925. break;
  3926. }
  3927. GlobalFree (lpStrings);
  3928. dwSize *= 2;
  3929. lpStrings = (TCHAR *) GlobalAlloc (GPTR, dwSize * sizeof(TCHAR));
  3930. if (!lpStrings)
  3931. {
  3932. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::GetStringSection: Failed to alloc memory for Default strings with %d."),
  3933. GetLastError()));
  3934. return FALSE;
  3935. }
  3936. } while (TRUE);
  3937. if (dwRead == 0)
  3938. {
  3939. GlobalFree (lpStrings);
  3940. lpStrings = NULL;
  3941. }
  3942. return lpStrings;
  3943. }
  3944. INT CPolicyComponentData::TemplatesSortCallback (LPARAM lParam1, LPARAM lParam2,
  3945. LPARAM lColumn)
  3946. {
  3947. LPTEMPLATEENTRY lpEntry1, lpEntry2;
  3948. INT iResult;
  3949. lpEntry1 = (LPTEMPLATEENTRY) lParam1;
  3950. lpEntry2 = (LPTEMPLATEENTRY) lParam2;
  3951. if (lColumn == 0)
  3952. {
  3953. iResult = lstrcmpi (lpEntry1->lpFileName, lpEntry2->lpFileName);
  3954. }
  3955. else if (lColumn == 1)
  3956. {
  3957. if (lpEntry1->dwSize < lpEntry2->dwSize)
  3958. {
  3959. iResult = -1;
  3960. }
  3961. else if (lpEntry1->dwSize > lpEntry2->dwSize)
  3962. {
  3963. iResult = 1;
  3964. }
  3965. else
  3966. {
  3967. iResult = 0;
  3968. }
  3969. }
  3970. else
  3971. {
  3972. iResult = CompareFileTime (&lpEntry1->ftTime, &lpEntry2->ftTime);
  3973. }
  3974. return iResult;
  3975. }
  3976. BOOL CPolicyComponentData::FillADMFiles (HWND hDlg)
  3977. {
  3978. TCHAR szPath[MAX_PATH];
  3979. TCHAR szDate[20];
  3980. TCHAR szTime[20];
  3981. TCHAR szBuffer[45];
  3982. HWND hLV;
  3983. INT iItem;
  3984. LVITEM item;
  3985. FILETIME filetime;
  3986. SYSTEMTIME systime;
  3987. WIN32_FIND_DATA fd;
  3988. LPTEMPLATEENTRY lpEntry;
  3989. HANDLE hFile;
  3990. LPTSTR lpEnd, lpTemp;
  3991. //
  3992. // Ask for the root of the GPT so we can access the
  3993. // adm files.
  3994. //
  3995. if (m_pGPTInformation->GetFileSysPath(GPO_SECTION_ROOT, szPath,
  3996. MAX_PATH) != S_OK)
  3997. {
  3998. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::FillADMFiles: Failed to get gpt path.")));
  3999. return FALSE;
  4000. }
  4001. //
  4002. // Create the directory
  4003. //
  4004. lpEnd = CheckSlash (szPath);
  4005. lstrcpy (lpEnd, g_szADM);
  4006. if (!CreateNestedDirectory(szPath, NULL))
  4007. {
  4008. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::FillADMFiles: Failed to create adm directory.")));
  4009. return FALSE;
  4010. }
  4011. //
  4012. // Prepare the listview
  4013. //
  4014. hLV = GetDlgItem (hDlg, IDC_TEMPLATELIST);
  4015. SendMessage (hLV, WM_SETREDRAW, FALSE, 0);
  4016. ListView_DeleteAllItems(hLV);
  4017. //
  4018. // Enumerate the files
  4019. //
  4020. lstrcat (szPath, TEXT("\\*.adm"));
  4021. hFile = FindFirstFile(szPath, &fd);
  4022. if (hFile != INVALID_HANDLE_VALUE)
  4023. {
  4024. do
  4025. {
  4026. if (!(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
  4027. {
  4028. lpEntry = (LPTEMPLATEENTRY) LocalAlloc (LPTR,
  4029. sizeof(TEMPLATEENTRY) + ((lstrlen(fd.cFileName) + 1) * sizeof(TCHAR)));
  4030. if (lpEntry)
  4031. {
  4032. lpEntry->lpFileName = (LPTSTR)((LPBYTE)lpEntry + sizeof(TEMPLATEENTRY));
  4033. lpEntry->dwSize = fd.nFileSizeLow / 1024;
  4034. if (lpEntry->dwSize == 0)
  4035. {
  4036. lpEntry->dwSize = 1;
  4037. }
  4038. lpEntry->ftTime.dwLowDateTime = fd.ftLastWriteTime.dwLowDateTime;
  4039. lpEntry->ftTime.dwHighDateTime = fd.ftLastWriteTime.dwHighDateTime;
  4040. lstrcpy (lpEntry->lpFileName, fd.cFileName);
  4041. //
  4042. // Add the filename
  4043. //
  4044. lpTemp = fd.cFileName + lstrlen (fd.cFileName) - 4;
  4045. if (*lpTemp == TEXT('.'))
  4046. {
  4047. *lpTemp = TEXT('\0');
  4048. }
  4049. item.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE | LVIF_PARAM;
  4050. item.iItem = 0;
  4051. item.iSubItem = 0;
  4052. item.state = 0;
  4053. item.stateMask = LVIS_SELECTED | LVIS_FOCUSED;
  4054. item.pszText = fd.cFileName;
  4055. item.iImage = 0;
  4056. item.lParam = (LPARAM) lpEntry;
  4057. iItem = (INT)SendMessage (hLV, LVM_INSERTITEM, 0, (LPARAM) &item);
  4058. if (iItem == -1)
  4059. {
  4060. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::FillADMFiles: Failed to insert item.")));
  4061. return FALSE;
  4062. }
  4063. //
  4064. // Add the size
  4065. //
  4066. wsprintf (szBuffer, TEXT("%dKB"), lpEntry->dwSize);
  4067. item.mask = LVIF_TEXT;
  4068. item.iItem = iItem;
  4069. item.iSubItem = 1;
  4070. item.pszText = szBuffer;
  4071. SendMessage (hLV, LVM_SETITEMTEXT, iItem, (LPARAM) &item);
  4072. //
  4073. // And the last modified date
  4074. //
  4075. FileTimeToLocalFileTime (&fd.ftLastWriteTime, &filetime);
  4076. FileTimeToSystemTime (&filetime, &systime);
  4077. GetDateFormat (LOCALE_USER_DEFAULT, DATE_SHORTDATE,
  4078. &systime, NULL, szDate, 20);
  4079. GetTimeFormat (LOCALE_USER_DEFAULT, TIME_NOSECONDS,
  4080. &systime, NULL, szTime, 20);
  4081. wsprintf (szBuffer, TEXT("%s %s"), szDate, szTime);
  4082. item.mask = LVIF_TEXT;
  4083. item.iItem = iItem;
  4084. item.iSubItem = 2;
  4085. item.pszText = szBuffer;
  4086. SendMessage (hLV, LVM_SETITEMTEXT, iItem, (LPARAM) &item);
  4087. }
  4088. else
  4089. {
  4090. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::FillADMFiles: Failed to allocate memory for an entry %d."),
  4091. GetLastError()));
  4092. }
  4093. }
  4094. } while (FindNextFile(hFile, &fd));
  4095. FindClose(hFile);
  4096. }
  4097. if (SendMessage(hLV, LVM_GETITEMCOUNT, 0, 0) > 0)
  4098. {
  4099. //
  4100. // Sort the listview
  4101. //
  4102. ListView_SortItems (hLV, TemplatesSortCallback, m_bTemplatesColumn);
  4103. //
  4104. // Select the first item
  4105. //
  4106. item.mask = LVIF_STATE;
  4107. item.iItem = 0;
  4108. item.iSubItem = 0;
  4109. item.state = LVIS_SELECTED | LVIS_FOCUSED;
  4110. item.stateMask = LVIS_SELECTED | LVIS_FOCUSED;
  4111. SendMessage (hLV, LVM_SETITEMSTATE, 0, (LPARAM) &item);
  4112. EnableWindow (GetDlgItem (hDlg, IDC_REMOVETEMPLATES), TRUE);
  4113. }
  4114. else
  4115. {
  4116. EnableWindow (GetDlgItem (hDlg, IDC_REMOVETEMPLATES), FALSE);
  4117. SetFocus (GetDlgItem (hDlg, IDC_ADDTEMPLATES));
  4118. }
  4119. SendMessage (hLV, WM_SETREDRAW, TRUE, 0);
  4120. return TRUE;
  4121. }
  4122. BOOL CPolicyComponentData::InitializeTemplatesDlg (HWND hDlg)
  4123. {
  4124. LVCOLUMN lvc;
  4125. LVITEM item;
  4126. TCHAR szTitle[50];
  4127. INT iNameWidth;
  4128. HIMAGELIST hLarge, hSmall;
  4129. HICON hIcon;
  4130. HWND hLV;
  4131. RECT rc;
  4132. hLV = GetDlgItem (hDlg, IDC_TEMPLATELIST);
  4133. GetClientRect (hLV, &rc);
  4134. //
  4135. // Create the imagelists
  4136. //
  4137. hLarge = ImageList_Create (32, 32, ILC_MASK, 1, 1);
  4138. if (!hLarge)
  4139. {
  4140. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::InitializeTemplatesDlg: Failed to create large imagelist.")));
  4141. return FALSE;
  4142. }
  4143. hSmall = ImageList_Create (16, 16, ILC_MASK, 1, 1);
  4144. if (!hSmall)
  4145. {
  4146. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::InitializeTemplatesDlg: Failed to create small imagelist.")));
  4147. ImageList_Destroy (hLarge);
  4148. return FALSE;
  4149. }
  4150. //
  4151. // Add the icon
  4152. //
  4153. hIcon = (HICON) LoadImage (g_hInstance, MAKEINTRESOURCE(IDI_DOCUMENT),
  4154. IMAGE_ICON, 32, 32, LR_DEFAULTCOLOR);
  4155. if ( hIcon )
  4156. {
  4157. ImageList_AddIcon (hLarge, hIcon);
  4158. DestroyIcon (hIcon);
  4159. }
  4160. hIcon = (HICON) LoadImage (g_hInstance, MAKEINTRESOURCE(IDI_DOCUMENT),
  4161. IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
  4162. if ( hIcon )
  4163. {
  4164. ImageList_AddIcon (hSmall, hIcon);
  4165. DestroyIcon (hIcon);
  4166. }
  4167. //
  4168. // Associate the imagelist with the listview.
  4169. // The listview will free this when the
  4170. // control is destroyed.
  4171. //
  4172. SendMessage (hLV, LVM_SETIMAGELIST, LVSIL_NORMAL, (LPARAM) hLarge);
  4173. SendMessage (hLV, LVM_SETIMAGELIST, LVSIL_SMALL, (LPARAM) hSmall);
  4174. //
  4175. // Set extended LV style for whole line selection
  4176. //
  4177. SendMessage(hLV, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_FULLROWSELECT);
  4178. //
  4179. // Insert the columns
  4180. //
  4181. LoadString (g_hInstance, IDS_NAME, szTitle, 50);
  4182. lvc.mask = LVCF_FMT | LVCF_SUBITEM | LVCF_TEXT | LVCF_WIDTH;
  4183. lvc.fmt = LVCFMT_LEFT;
  4184. iNameWidth = (int)(rc.right * .60);
  4185. lvc.cx = iNameWidth;
  4186. lvc.pszText = szTitle;
  4187. lvc.cchTextMax = 50;
  4188. lvc.iSubItem = 0;
  4189. SendMessage (hLV, LVM_INSERTCOLUMN, 0, (LPARAM) &lvc);
  4190. LoadString (g_hInstance, IDS_SIZE, szTitle, 50);
  4191. lvc.mask = LVCF_FMT | LVCF_SUBITEM | LVCF_TEXT | LVCF_WIDTH;
  4192. lvc.fmt = LVCFMT_RIGHT;
  4193. iNameWidth += (int)(rc.right * .15);
  4194. lvc.cx = (int)(rc.right * .15);
  4195. lvc.pszText = szTitle;
  4196. lvc.cchTextMax = 50;
  4197. lvc.iSubItem = 0;
  4198. SendMessage (hLV, LVM_INSERTCOLUMN, 1, (LPARAM) &lvc);
  4199. LoadString (g_hInstance, IDS_MODIFIED, szTitle, 50);
  4200. lvc.mask = LVCF_FMT | LVCF_SUBITEM | LVCF_TEXT | LVCF_WIDTH;
  4201. lvc.fmt = LVCFMT_LEFT;
  4202. lvc.cx = rc.right - iNameWidth;
  4203. lvc.pszText = szTitle;
  4204. lvc.cchTextMax = 50;
  4205. lvc.iSubItem = 1;
  4206. SendMessage (hLV, LVM_INSERTCOLUMN, 2, (LPARAM) &lvc);
  4207. //
  4208. // Fill the list view with the adm files
  4209. //
  4210. FillADMFiles (hDlg);
  4211. return TRUE;
  4212. }
  4213. BOOL CPolicyComponentData::AddTemplates(HWND hDlg)
  4214. {
  4215. OPENFILENAME ofn;
  4216. LVITEM item;
  4217. INT iCount, iResult;
  4218. BOOL bResult = FALSE;
  4219. LPTSTR lpFileName, lpTemp, lpEnd, lpSrcList = NULL;
  4220. DWORD dwListLen, dwTemp, dwNextString;
  4221. TCHAR szFilter[100];
  4222. TCHAR szTitle[100];
  4223. TCHAR szFile[2*MAX_PATH];
  4224. TCHAR szInf[MAX_PATH];
  4225. TCHAR szDest[MAX_PATH];
  4226. TCHAR szSrc[MAX_PATH];
  4227. SHFILEOPSTRUCT fileop;
  4228. //
  4229. // Prompt for new files
  4230. //
  4231. LoadString (g_hInstance, IDS_POLICYFILTER, szFilter, ARRAYSIZE(szFilter));
  4232. LoadString (g_hInstance, IDS_POLICYTITLE, szTitle, ARRAYSIZE(szTitle));
  4233. ExpandEnvironmentStrings (TEXT("%SystemRoot%\\Inf"), szInf, MAX_PATH);
  4234. lpTemp = szFilter;
  4235. while (*lpTemp)
  4236. {
  4237. if (*lpTemp == TEXT('#'))
  4238. *lpTemp = TEXT('\0');
  4239. lpTemp++;
  4240. }
  4241. ZeroMemory (&ofn, sizeof(ofn));
  4242. szFile[0] = TEXT('\0');
  4243. ofn.lStructSize = sizeof(ofn);
  4244. ofn.hwndOwner = hDlg;
  4245. ofn.hInstance = g_hInstance;
  4246. ofn.lpstrFilter = szFilter;
  4247. ofn.nFilterIndex = 1;
  4248. ofn.lpstrFile = szFile;
  4249. ofn.nMaxFile = 2*MAX_PATH;
  4250. ofn.lpstrInitialDir = szInf;
  4251. ofn.lpstrTitle = szTitle;
  4252. ofn.Flags = OFN_ALLOWMULTISELECT | OFN_NOCHANGEDIR | OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_EXPLORER;
  4253. if (!GetOpenFileName (&ofn))
  4254. {
  4255. return FALSE;
  4256. }
  4257. //
  4258. // Setup the destination
  4259. //
  4260. if (m_pGPTInformation->GetFileSysPath(GPO_SECTION_ROOT, szDest,
  4261. MAX_PATH) != S_OK)
  4262. {
  4263. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::AddTemplates: Failed to get gpt path.")));
  4264. return FALSE;
  4265. }
  4266. lpEnd = CheckSlash (szDest);
  4267. lstrcpy (lpEnd, g_szADM);
  4268. //
  4269. // Setup up the source
  4270. //
  4271. *(szFile + ofn.nFileOffset - 1) = TEXT('\0');
  4272. lstrcpyn (szSrc, szFile, MAX_PATH);
  4273. lpEnd = CheckSlash (szSrc);
  4274. lpFileName = szFile + lstrlen (szFile) + 1;
  4275. //
  4276. // Loop through the files copying and adding them to the list.
  4277. //
  4278. while (*lpFileName)
  4279. {
  4280. lpTemp = lpFileName + lstrlen (lpFileName) - 4;
  4281. if (!lstrcmpi(lpTemp, TEXT(".adm")))
  4282. {
  4283. lstrcpy (lpEnd, lpFileName);
  4284. if (lpSrcList)
  4285. {
  4286. dwTemp = dwListLen + ((lstrlen (szSrc) + 1) * sizeof(TCHAR));
  4287. lpTemp = (LPTSTR) LocalReAlloc (lpSrcList, dwTemp, LMEM_MOVEABLE | LMEM_ZEROINIT);
  4288. if (lpTemp)
  4289. {
  4290. lpSrcList = lpTemp;
  4291. dwListLen = dwTemp;
  4292. lstrcpy ((lpSrcList + dwNextString), szSrc);
  4293. dwNextString += lstrlen (szSrc) + 1;
  4294. }
  4295. else
  4296. {
  4297. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::AddTemplates: Failed to realloc memory for Src list. %d"),
  4298. GetLastError()));
  4299. }
  4300. }
  4301. else
  4302. {
  4303. dwListLen = (lstrlen (szSrc) + 2) * sizeof(TCHAR);
  4304. lpSrcList = (LPTSTR) LocalAlloc (LPTR, dwListLen);
  4305. if (lpSrcList)
  4306. {
  4307. lstrcpy (lpSrcList, szSrc);
  4308. dwNextString = lstrlen (lpSrcList) + 1;
  4309. }
  4310. else
  4311. {
  4312. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::AddTemplates: Failed to alloc memory for src list. %d"),
  4313. GetLastError()));
  4314. }
  4315. }
  4316. }
  4317. else
  4318. {
  4319. MsgBoxParam(hDlg, IDS_INVALIDADMFILE, lpFileName, MB_ICONERROR, MB_OK);
  4320. }
  4321. lpFileName = lpFileName + lstrlen (lpFileName) + 1;
  4322. }
  4323. if (lpSrcList)
  4324. {
  4325. fileop.hwnd = hDlg;
  4326. fileop.wFunc = FO_COPY;
  4327. fileop.pFrom = lpSrcList;
  4328. fileop.pTo = szDest;
  4329. fileop.fFlags = FOF_NOCONFIRMMKDIR;
  4330. iResult = SHFileOperation(&fileop);
  4331. if (!iResult)
  4332. {
  4333. bResult = TRUE;
  4334. }
  4335. else
  4336. {
  4337. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::AddTemplates: Failed to copy <%s> to <%s> with %d."),
  4338. szSrc, szDest, iResult));
  4339. }
  4340. LocalFree (lpSrcList);
  4341. if (bResult)
  4342. {
  4343. FillADMFiles (hDlg);
  4344. }
  4345. }
  4346. return bResult;
  4347. }
  4348. BOOL CPolicyComponentData::RemoveTemplates(HWND hDlg)
  4349. {
  4350. HWND hLV;
  4351. LVITEM item;
  4352. BOOL bResult = FALSE;
  4353. INT iResult, iIndex = -1;
  4354. LPTEMPLATEENTRY lpEntry;
  4355. LPTSTR lpEnd, lpTemp, lpDeleteList = NULL;
  4356. TCHAR szPath[MAX_PATH];
  4357. DWORD dwSize, dwListLen, dwTemp, dwNextString;
  4358. SHFILEOPSTRUCT fileop;
  4359. hLV = GetDlgItem (hDlg, IDC_TEMPLATELIST);
  4360. //
  4361. // Get the path to the adm directory
  4362. //
  4363. if (m_pGPTInformation->GetFileSysPath(GPO_SECTION_ROOT, szPath,
  4364. MAX_PATH) != S_OK)
  4365. {
  4366. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::AddTemplates: Failed to get gpt path.")));
  4367. return FALSE;
  4368. }
  4369. lpEnd = CheckSlash (szPath);
  4370. lstrcpy (lpEnd, g_szADM);
  4371. lpEnd = CheckSlash (szPath);
  4372. dwSize = MAX_PATH - (DWORD)(lpEnd - szPath);
  4373. //
  4374. // Build a list of selected items
  4375. //
  4376. while ((iIndex = ListView_GetNextItem (hLV, iIndex,
  4377. LVNI_ALL | LVNI_SELECTED)) != -1)
  4378. {
  4379. item.mask = LVIF_PARAM;
  4380. item.iItem = iIndex;
  4381. item.iSubItem = 0;
  4382. if (!ListView_GetItem (hLV, &item))
  4383. {
  4384. continue;
  4385. }
  4386. lpEntry = (LPTEMPLATEENTRY) item.lParam;
  4387. lstrcpyn (lpEnd, lpEntry->lpFileName, dwSize);
  4388. if (lpDeleteList)
  4389. {
  4390. dwTemp = dwListLen + ((lstrlen (szPath) + 1) * sizeof(TCHAR));
  4391. lpTemp = (LPTSTR) LocalReAlloc (lpDeleteList, dwTemp, LMEM_MOVEABLE | LMEM_ZEROINIT);
  4392. if (lpTemp)
  4393. {
  4394. lpDeleteList = lpTemp;
  4395. dwListLen = dwTemp;
  4396. lstrcpy ((lpDeleteList + dwNextString), szPath);
  4397. dwNextString += lstrlen (szPath) + 1;
  4398. }
  4399. else
  4400. {
  4401. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::RemoveTemplates: Failed to realloc memory for delete list. %d"),
  4402. GetLastError()));
  4403. }
  4404. }
  4405. else
  4406. {
  4407. dwListLen = (lstrlen (szPath) + 2) * sizeof(TCHAR);
  4408. lpDeleteList = (LPTSTR) LocalAlloc (LPTR, dwListLen);
  4409. if (lpDeleteList)
  4410. {
  4411. lstrcpy (lpDeleteList, szPath);
  4412. dwNextString = lstrlen (lpDeleteList) + 1;
  4413. }
  4414. else
  4415. {
  4416. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::RemoveTemplates: Failed to alloc memory for delete list. %d"),
  4417. GetLastError()));
  4418. }
  4419. }
  4420. }
  4421. if (lpDeleteList)
  4422. {
  4423. fileop.hwnd = hDlg;
  4424. fileop.wFunc = FO_DELETE;
  4425. fileop.pFrom = lpDeleteList;
  4426. fileop.pTo = NULL;
  4427. fileop.fFlags = FOF_NOCONFIRMATION | FOF_SILENT;
  4428. iResult = SHFileOperation(&fileop);
  4429. if (!iResult)
  4430. {
  4431. bResult = TRUE;
  4432. }
  4433. else
  4434. {
  4435. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::RemoveTemplates: Failed to delete file <%s> with %d."),
  4436. szPath, iResult));
  4437. }
  4438. LocalFree (lpDeleteList);
  4439. if (bResult)
  4440. {
  4441. FillADMFiles (hDlg);
  4442. }
  4443. }
  4444. return bResult;
  4445. }
  4446. INT_PTR CALLBACK CPolicyComponentData::TemplatesDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  4447. {
  4448. CPolicyComponentData * pCD;
  4449. static BOOL bTemplatesDirty;
  4450. switch (message)
  4451. {
  4452. case WM_INITDIALOG:
  4453. pCD = (CPolicyComponentData*) lParam;
  4454. SetWindowLongPtr (hDlg, DWLP_USER, (LONG_PTR) pCD);
  4455. bTemplatesDirty = FALSE;
  4456. if (!pCD->InitializeTemplatesDlg(hDlg))
  4457. {
  4458. EndDialog (hDlg, FALSE);
  4459. }
  4460. PostMessage (hDlg, WM_REFRESHDISPLAY, 0, 0);
  4461. break;
  4462. case WM_COMMAND:
  4463. switch (LOWORD(wParam))
  4464. {
  4465. case IDOK:
  4466. case IDCANCEL:
  4467. case IDCLOSE:
  4468. EndDialog (hDlg, bTemplatesDirty);
  4469. break;
  4470. case IDC_ADDTEMPLATES:
  4471. pCD = (CPolicyComponentData*) GetWindowLongPtr (hDlg, DWLP_USER);
  4472. if (pCD && pCD->AddTemplates(hDlg))
  4473. {
  4474. bTemplatesDirty = TRUE;
  4475. }
  4476. break;
  4477. case IDC_REMOVETEMPLATES:
  4478. pCD = (CPolicyComponentData*) GetWindowLongPtr (hDlg, DWLP_USER);
  4479. if (pCD && pCD->RemoveTemplates(hDlg))
  4480. {
  4481. bTemplatesDirty = TRUE;
  4482. }
  4483. break;
  4484. }
  4485. break;
  4486. case WM_NOTIFY:
  4487. if (((NMHDR FAR*)lParam)->code == LVN_DELETEITEM)
  4488. {
  4489. LVITEM item;
  4490. LPTEMPLATEENTRY lpEntry;
  4491. item.mask = LVIF_PARAM;
  4492. item.iItem = ((NMLISTVIEW FAR*)lParam)->iItem;
  4493. item.iSubItem = 0;
  4494. if (ListView_GetItem (GetDlgItem (hDlg, IDC_TEMPLATELIST), &item))
  4495. {
  4496. lpEntry = (LPTEMPLATEENTRY) item.lParam;
  4497. LocalFree (lpEntry);
  4498. }
  4499. }
  4500. else if (((NMHDR FAR*)lParam)->code == LVN_COLUMNCLICK)
  4501. {
  4502. pCD = (CPolicyComponentData*) GetWindowLongPtr (hDlg, DWLP_USER);
  4503. if (pCD)
  4504. {
  4505. pCD->m_bTemplatesColumn = ((NMLISTVIEW FAR*)lParam)->iSubItem;
  4506. ListView_SortItems (GetDlgItem (hDlg, IDC_TEMPLATELIST),
  4507. TemplatesSortCallback, pCD->m_bTemplatesColumn);
  4508. }
  4509. }
  4510. else
  4511. {
  4512. PostMessage (hDlg, WM_REFRESHDISPLAY, 0, 0);
  4513. }
  4514. break;
  4515. case WM_REFRESHDISPLAY:
  4516. if (ListView_GetNextItem (GetDlgItem(hDlg, IDC_TEMPLATELIST),
  4517. -1, LVNI_ALL | LVNI_SELECTED) == -1)
  4518. {
  4519. EnableWindow (GetDlgItem(hDlg, IDC_REMOVETEMPLATES), FALSE);
  4520. }
  4521. else
  4522. {
  4523. EnableWindow (GetDlgItem(hDlg, IDC_REMOVETEMPLATES), TRUE);
  4524. }
  4525. break;
  4526. case WM_HELP: // F1
  4527. WinHelp((HWND)((LPHELPINFO) lParam)->hItemHandle, HELP_FILE, HELP_WM_HELP,
  4528. (DWORD_PTR) (LPDWORD) aADMHelpIds);
  4529. return TRUE;
  4530. case WM_CONTEXTMENU: // right mouse click
  4531. WinHelp((HWND) wParam, HELP_FILE, HELP_CONTEXTMENU,
  4532. (DWORD_PTR) (LPDWORD) aADMHelpIds);
  4533. return TRUE;
  4534. }
  4535. return FALSE;
  4536. }
  4537. BOOL CPolicyComponentData::AddRSOPRegistryDataNode(LPTSTR lpKeyName, LPTSTR lpValueName, DWORD dwType,
  4538. DWORD dwDataSize, LPBYTE lpData, UINT uiPrecedence, LPTSTR lpGPOName, BOOL bDeleted)
  4539. {
  4540. DWORD dwSize;
  4541. LPRSOPREGITEM lpItem;
  4542. BOOL bSystemEntry = FALSE;
  4543. //
  4544. // Special case some registry key / values and do not add them to the link list.
  4545. // These registry entries are specific to snapins we write and we know for sure
  4546. // they have rsop UI that will show their values.
  4547. //
  4548. if (lpKeyName)
  4549. {
  4550. const TCHAR szCerts[] = TEXT("Software\\Policies\\Microsoft\\SystemCertificates");
  4551. int iCertLen = lstrlen (szCerts);
  4552. //
  4553. // Remove all system certificates
  4554. //
  4555. if (CompareString(LOCALE_USER_DEFAULT, NORM_IGNORECASE | NORM_STOP_ON_NULL,
  4556. lpKeyName, iCertLen, szCerts, iCertLen) == CSTR_EQUAL)
  4557. {
  4558. bSystemEntry = TRUE;
  4559. }
  4560. if ( ! bSystemEntry )
  4561. {
  4562. const TCHAR szCryptography[] = TEXT("Software\\Policies\\Microsoft\\Cryptography");
  4563. int iCryptographyLen = lstrlen (szCryptography);
  4564. if (CompareString(LOCALE_USER_DEFAULT, NORM_IGNORECASE | NORM_STOP_ON_NULL,
  4565. lpKeyName, iCryptographyLen, szCryptography, iCryptographyLen) == CSTR_EQUAL)
  4566. {
  4567. bSystemEntry = TRUE;
  4568. }
  4569. }
  4570. //
  4571. // Hide the digial signature policies for Software Installation
  4572. //
  4573. if (!lstrcmpi(lpKeyName, TEXT("Software\\Policies\\Microsoft\\Windows\\Installer")))
  4574. {
  4575. if (lpValueName)
  4576. {
  4577. if (!lstrcmpi(lpValueName, TEXT("InstallKnownPackagesOnly")))
  4578. {
  4579. bSystemEntry = TRUE;
  4580. }
  4581. else if (!lstrcmpi(lpValueName, TEXT("IgnoreSignaturePolicyForAdmins")))
  4582. {
  4583. bSystemEntry = TRUE;
  4584. }
  4585. }
  4586. }
  4587. }
  4588. if (bSystemEntry)
  4589. {
  4590. DebugMsg((DM_VERBOSE, TEXT("CPolicyComponentData::AddRSOPRegistryDataNode: Ignoring %s entry"), lpKeyName));
  4591. return TRUE;
  4592. }
  4593. //
  4594. // Calculate the size of the new registry item
  4595. //
  4596. dwSize = sizeof (RSOPREGITEM);
  4597. if (lpKeyName) {
  4598. dwSize += ((lstrlen(lpKeyName) + 1) * sizeof(TCHAR));
  4599. }
  4600. if (lpValueName) {
  4601. dwSize += ((lstrlen(lpValueName) + 1) * sizeof(TCHAR));
  4602. }
  4603. if (lpGPOName) {
  4604. dwSize += ((lstrlen(lpGPOName) + 1) * sizeof(TCHAR));
  4605. }
  4606. //
  4607. // Allocate space for it
  4608. //
  4609. lpItem = (LPRSOPREGITEM) LocalAlloc (LPTR, dwSize);
  4610. if (!lpItem) {
  4611. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::AddRSOPRegistryDataNode: Failed to allocate memory with %d"),
  4612. GetLastError()));
  4613. return FALSE;
  4614. }
  4615. //
  4616. // Fill in item
  4617. //
  4618. lpItem->dwType = dwType;
  4619. lpItem->dwSize = dwDataSize;
  4620. lpItem->uiPrecedence = uiPrecedence;
  4621. lpItem->bDeleted = bDeleted;
  4622. if (lpKeyName)
  4623. {
  4624. lpItem->lpKeyName = (LPTSTR)(((LPBYTE)lpItem) + sizeof(RSOPREGITEM));
  4625. lstrcpy (lpItem->lpKeyName, lpKeyName);
  4626. }
  4627. if (lpValueName)
  4628. {
  4629. if (lpKeyName)
  4630. {
  4631. lpItem->lpValueName = lpItem->lpKeyName + lstrlen (lpItem->lpKeyName) + 1;
  4632. }
  4633. else
  4634. {
  4635. lpItem->lpValueName = (LPTSTR)(((LPBYTE)lpItem) + sizeof(RSOPREGITEM));
  4636. }
  4637. lstrcpy (lpItem->lpValueName, lpValueName);
  4638. }
  4639. if (lpGPOName)
  4640. {
  4641. if (lpValueName)
  4642. {
  4643. lpItem->lpGPOName = lpItem->lpValueName + lstrlen (lpItem->lpValueName) + 1;
  4644. }
  4645. else
  4646. {
  4647. if (lpKeyName)
  4648. {
  4649. lpItem->lpGPOName = lpItem->lpKeyName + lstrlen (lpItem->lpKeyName) + 1;
  4650. }
  4651. else
  4652. {
  4653. lpItem->lpGPOName = (LPTSTR)(((LPBYTE)lpItem) + sizeof(RSOPREGITEM));
  4654. }
  4655. }
  4656. lstrcpy (lpItem->lpGPOName, lpGPOName);
  4657. }
  4658. if (lpData)
  4659. {
  4660. lpItem->lpData = (LPBYTE) LocalAlloc (LPTR, dwDataSize);
  4661. if (!lpItem->lpData) {
  4662. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::AddRSOPRegistryDataNode: Failed to allocate memory for data with %d"),
  4663. GetLastError()));
  4664. LocalFree (lpItem);
  4665. return FALSE;
  4666. }
  4667. CopyMemory (lpItem->lpData, lpData, dwDataSize);
  4668. }
  4669. //
  4670. // Add item to link list
  4671. //
  4672. lpItem->pNext = m_pRSOPRegistryData;
  4673. m_pRSOPRegistryData = lpItem;
  4674. return TRUE;
  4675. }
  4676. VOID CPolicyComponentData::FreeRSOPRegistryData(VOID)
  4677. {
  4678. LPRSOPREGITEM lpTemp;
  4679. if (!m_pRSOPRegistryData)
  4680. {
  4681. return;
  4682. }
  4683. do {
  4684. lpTemp = m_pRSOPRegistryData->pNext;
  4685. if (m_pRSOPRegistryData->lpData)
  4686. {
  4687. LocalFree (m_pRSOPRegistryData->lpData);
  4688. }
  4689. LocalFree (m_pRSOPRegistryData);
  4690. m_pRSOPRegistryData = lpTemp;
  4691. } while (lpTemp);
  4692. }
  4693. HRESULT CPolicyComponentData::InitializeRSOPRegistryData(VOID)
  4694. {
  4695. BSTR pLanguage = NULL, pQuery = NULL;
  4696. BSTR pRegistryKey = NULL, pValueName = NULL, pValueType = NULL, pValue = NULL, pDeleted = NULL;
  4697. BSTR pPrecedence = NULL, pGPOid = NULL, pNamespace = NULL, pCommand = NULL;
  4698. IEnumWbemClassObject * pEnum = NULL;
  4699. IWbemClassObject *pObjects[2];
  4700. HRESULT hr;
  4701. ULONG ulRet;
  4702. VARIANT varRegistryKey, varValueName, varValueType, varData, varDeleted;
  4703. VARIANT varPrecedence, varGPOid, varCommand;
  4704. SAFEARRAY * pSafeArray;
  4705. IWbemLocator *pIWbemLocator = NULL;
  4706. IWbemServices *pIWbemServices = NULL;
  4707. LPTSTR lpGPOName;
  4708. DWORD dwDataSize;
  4709. LPBYTE lpData;
  4710. BSTR pValueTemp;
  4711. DebugMsg((DM_VERBOSE, TEXT("CPolicySnapIn::InitializeRSOPRegistryData: Entering")));
  4712. //
  4713. // Allocate BSTRs for the query language and for the query itself
  4714. //
  4715. pLanguage = SysAllocString (TEXT("WQL"));
  4716. if (!pLanguage)
  4717. {
  4718. DebugMsg((DM_WARNING, TEXT("CPolicySnapIn::InitializeRSOPRegistryData: Failed to allocate memory for language")));
  4719. hr = HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY);
  4720. goto Exit;
  4721. }
  4722. pQuery = SysAllocString (TEXT("SELECT registryKey, valueName, valueType, value, deleted, precedence, GPOID, command FROM RSOP_RegistryPolicySetting"));
  4723. if (!pQuery)
  4724. {
  4725. DebugMsg((DM_WARNING, TEXT("CPolicySnapIn::InitializeRSOPRegistryData: Failed to allocate memory for query")));
  4726. hr = HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY);
  4727. goto Exit;
  4728. }
  4729. //
  4730. // Allocate BSTRs for the property names we want to retreive
  4731. //
  4732. pRegistryKey = SysAllocString (TEXT("registryKey"));
  4733. if (!pRegistryKey)
  4734. {
  4735. DebugMsg((DM_WARNING, TEXT("CPolicySnapIn::InitializeRSOPRegistryData: Failed to allocate memory for registryKey")));
  4736. hr = HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY);
  4737. goto Exit;
  4738. }
  4739. pValueName = SysAllocString (TEXT("valueName"));
  4740. if (!pValueName)
  4741. {
  4742. DebugMsg((DM_WARNING, TEXT("CPolicySnapIn::InitializeRSOPRegistryData: Failed to allocate memory for valueName")));
  4743. hr = HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY);
  4744. goto Exit;
  4745. }
  4746. pValueType = SysAllocString (TEXT("valueType"));
  4747. if (!pValueType)
  4748. {
  4749. DebugMsg((DM_WARNING, TEXT("CPolicySnapIn::InitializeRSOPRegistryData: Failed to allocate memory for valueType")));
  4750. hr = HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY);
  4751. goto Exit;
  4752. }
  4753. pValue = SysAllocString (TEXT("value"));
  4754. if (!pValue)
  4755. {
  4756. DebugMsg((DM_WARNING, TEXT("CPolicySnapIn::InitializeRSOPRegistryData: Failed to allocate memory for value")));
  4757. hr = HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY);
  4758. goto Exit;
  4759. }
  4760. pDeleted = SysAllocString (TEXT("deleted"));
  4761. if (!pDeleted)
  4762. {
  4763. DebugMsg((DM_WARNING, TEXT("CPolicySnapIn::InitializeRSOPRegistryData: Failed to allocate memory for deleted")));
  4764. hr = HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY);
  4765. goto Exit;
  4766. }
  4767. pPrecedence = SysAllocString (TEXT("precedence"));
  4768. if (!pPrecedence)
  4769. {
  4770. DebugMsg((DM_WARNING, TEXT("CPolicySnapIn::InitializeRSOPRegistryData: Failed to allocate memory for precedence")));
  4771. hr = HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY);
  4772. goto Exit;
  4773. }
  4774. pGPOid = SysAllocString (TEXT("GPOID"));
  4775. if (!pGPOid)
  4776. {
  4777. DebugMsg((DM_WARNING, TEXT("CPolicySnapIn::InitializeRSOPRegistryData: Failed to allocate memory for GPO id")));
  4778. hr = HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY);
  4779. goto Exit;
  4780. }
  4781. pCommand = SysAllocString (TEXT("command"));
  4782. if (!pCommand)
  4783. {
  4784. DebugMsg((DM_WARNING, TEXT("CPolicySnapIn::InitializeRSOPRegistryData: Failed to allocate memory for command")));
  4785. hr = HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY);
  4786. goto Exit;
  4787. }
  4788. //
  4789. // Create an instance of the WMI locator service
  4790. //
  4791. hr = CoCreateInstance(CLSID_WbemLocator, NULL, CLSCTX_INPROC_SERVER,
  4792. IID_IWbemLocator, (LPVOID *) &pIWbemLocator);
  4793. if (FAILED(hr))
  4794. {
  4795. DebugMsg((DM_WARNING, TEXT("CPolicySnapIn::InitializeRSOPRegistryData: CoCreateInstance failed with 0x%x"), hr));
  4796. goto Exit;
  4797. }
  4798. //
  4799. // Allocate a BSTR for the namespace
  4800. //
  4801. pNamespace = SysAllocString (m_pszNamespace);
  4802. if (!pNamespace)
  4803. {
  4804. DebugMsg((DM_WARNING, TEXT("CPolicySnapIn::InitializeRSOPRegistryData: Failed to allocate memory for namespace")));
  4805. hr = HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY);
  4806. goto Exit;
  4807. }
  4808. //
  4809. // Connect to the server
  4810. //
  4811. hr = pIWbemLocator->ConnectServer(pNamespace, NULL, NULL, 0L, 0L, NULL, NULL,
  4812. &pIWbemServices);
  4813. if (FAILED(hr))
  4814. {
  4815. DebugMsg((DM_WARNING, TEXT("CPolicySnapIn::InitializeRSOPRegistryData: ConnectServer failed with 0x%x"), hr));
  4816. goto Exit;
  4817. }
  4818. //
  4819. // Execute the query
  4820. //
  4821. hr = pIWbemServices->ExecQuery (pLanguage, pQuery,
  4822. WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
  4823. NULL, &pEnum);
  4824. if (FAILED(hr))
  4825. {
  4826. DebugMsg((DM_WARNING, TEXT("CPolicySnapIn::InitializeRSOPRegistryData: Failed to query for %s with 0x%x"),
  4827. pQuery, hr));
  4828. goto Exit;
  4829. }
  4830. //
  4831. // Loop through the results
  4832. //
  4833. while (pEnum->Next(WBEM_INFINITE, 1, pObjects, &ulRet) == S_OK)
  4834. {
  4835. //
  4836. // Check for the "data not available case"
  4837. //
  4838. if (ulRet == 0)
  4839. {
  4840. hr = S_OK;
  4841. goto Exit;
  4842. }
  4843. //
  4844. // Get the deleted flag
  4845. //
  4846. hr = pObjects[0]->Get (pDeleted, 0, &varDeleted, NULL, NULL);
  4847. if (SUCCEEDED(hr))
  4848. {
  4849. //
  4850. // Get the registry key
  4851. //
  4852. hr = pObjects[0]->Get (pRegistryKey, 0, &varRegistryKey, NULL, NULL);
  4853. if (SUCCEEDED(hr))
  4854. {
  4855. //
  4856. // Get the value name
  4857. //
  4858. hr = pObjects[0]->Get (pValueName, 0, &varValueName, NULL, NULL);
  4859. if (SUCCEEDED(hr))
  4860. {
  4861. //
  4862. // Get the value type
  4863. //
  4864. hr = pObjects[0]->Get (pValueType, 0, &varValueType, NULL, NULL);
  4865. if (SUCCEEDED(hr))
  4866. {
  4867. //
  4868. // Get the value data
  4869. //
  4870. hr = pObjects[0]->Get (pValue, 0, &varData, NULL, NULL);
  4871. if (SUCCEEDED(hr))
  4872. {
  4873. //
  4874. // Get the precedence
  4875. //
  4876. hr = pObjects[0]->Get (pPrecedence, 0, &varPrecedence, NULL, NULL);
  4877. if (SUCCEEDED(hr))
  4878. {
  4879. //
  4880. // Get the command
  4881. //
  4882. hr = pObjects[0]->Get (pCommand, 0, &varCommand, NULL, NULL);
  4883. if (SUCCEEDED(hr))
  4884. {
  4885. //
  4886. // Get the GPO ID
  4887. //
  4888. hr = pObjects[0]->Get (pGPOid, 0, &varGPOid, NULL, NULL);
  4889. if (SUCCEEDED(hr))
  4890. {
  4891. hr = GetGPOFriendlyName (pIWbemServices, varGPOid.bstrVal,
  4892. pLanguage, &lpGPOName);
  4893. if (SUCCEEDED(hr))
  4894. {
  4895. if (varValueName.vt != VT_NULL)
  4896. {
  4897. pValueTemp = varValueName.bstrVal;
  4898. }
  4899. else
  4900. {
  4901. pValueTemp = NULL;
  4902. }
  4903. if (varData.vt != VT_NULL)
  4904. {
  4905. pSafeArray = varData.parray;
  4906. dwDataSize = pSafeArray->rgsabound[0].cElements;
  4907. lpData = (LPBYTE) pSafeArray->pvData;
  4908. }
  4909. else
  4910. {
  4911. dwDataSize = 0;
  4912. lpData = NULL;
  4913. }
  4914. if ((varValueType.uintVal == REG_NONE) && pValueTemp &&
  4915. !lstrcmpi(pValueTemp, TEXT("**command")))
  4916. {
  4917. pValueTemp = varCommand.bstrVal;
  4918. dwDataSize = 0;
  4919. lpData = NULL;
  4920. }
  4921. AddRSOPRegistryDataNode(varRegistryKey.bstrVal, pValueTemp,
  4922. varValueType.uintVal, dwDataSize, lpData,
  4923. varPrecedence.uintVal, lpGPOName,
  4924. (varDeleted.boolVal == 0) ? FALSE : TRUE);
  4925. LocalFree (lpGPOName);
  4926. }
  4927. VariantClear (&varGPOid);
  4928. }
  4929. VariantClear (&varCommand);
  4930. }
  4931. VariantClear (&varPrecedence);
  4932. }
  4933. VariantClear (&varData);
  4934. }
  4935. VariantClear (&varValueType);
  4936. }
  4937. VariantClear (&varValueName);
  4938. }
  4939. VariantClear (&varRegistryKey);
  4940. }
  4941. VariantClear (&varDeleted);
  4942. }
  4943. pObjects[0]->Release();
  4944. }
  4945. hr = S_OK;
  4946. Exit:
  4947. if (pEnum)
  4948. {
  4949. pEnum->Release();
  4950. }
  4951. if (pIWbemLocator)
  4952. {
  4953. pIWbemLocator->Release();
  4954. }
  4955. if (pIWbemServices)
  4956. {
  4957. pIWbemServices->Release();
  4958. }
  4959. if (pLanguage)
  4960. {
  4961. SysFreeString (pLanguage);
  4962. }
  4963. if (pQuery)
  4964. {
  4965. SysFreeString (pQuery);
  4966. }
  4967. if (pRegistryKey)
  4968. {
  4969. SysFreeString (pRegistryKey);
  4970. }
  4971. if (pValueType)
  4972. {
  4973. SysFreeString (pValueType);
  4974. }
  4975. if (pValueName)
  4976. {
  4977. SysFreeString (pValueName);
  4978. }
  4979. if (pDeleted)
  4980. {
  4981. SysFreeString (pDeleted);
  4982. }
  4983. if (pValue)
  4984. {
  4985. SysFreeString (pValue);
  4986. }
  4987. if (pNamespace)
  4988. {
  4989. SysFreeString (pNamespace);
  4990. }
  4991. if (pPrecedence)
  4992. {
  4993. SysFreeString (pPrecedence);
  4994. }
  4995. if (pGPOid)
  4996. {
  4997. SysFreeString (pGPOid);
  4998. }
  4999. if (pCommand)
  5000. {
  5001. SysFreeString (pCommand);
  5002. }
  5003. DebugMsg((DM_VERBOSE, TEXT("CPolicySnapIn::InitializeRSOPRegistryData: Leaving")));
  5004. return hr;
  5005. }
  5006. HRESULT CPolicyComponentData::GetGPOFriendlyName(IWbemServices *pIWbemServices,
  5007. LPTSTR lpGPOID, BSTR pLanguage,
  5008. LPTSTR *pGPOName)
  5009. {
  5010. BSTR pQuery = NULL, pName = NULL;
  5011. LPTSTR lpQuery = NULL;
  5012. IEnumWbemClassObject * pEnum = NULL;
  5013. IWbemClassObject *pObjects[2];
  5014. HRESULT hr;
  5015. ULONG ulRet;
  5016. VARIANT varGPOName;
  5017. //
  5018. // Set the default
  5019. //
  5020. *pGPOName = NULL;
  5021. //
  5022. // Build the query
  5023. //
  5024. lpQuery = (LPTSTR) LocalAlloc (LPTR, ((lstrlen(lpGPOID) + 50) * sizeof(TCHAR)));
  5025. if (!lpQuery)
  5026. {
  5027. DebugMsg((DM_WARNING, TEXT("CPolicySnapIn::GetGPOFriendlyName: Failed to allocate memory for unicode query")));
  5028. hr = HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY);
  5029. goto Exit;
  5030. }
  5031. wsprintf (lpQuery, TEXT("SELECT name, id FROM RSOP_GPO where id=\"%s\""), lpGPOID);
  5032. pQuery = SysAllocString (lpQuery);
  5033. if (!pQuery)
  5034. {
  5035. DebugMsg((DM_WARNING, TEXT("CPolicySnapIn::GetGPOFriendlyName: Failed to allocate memory for query")));
  5036. hr = HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY);
  5037. goto Exit;
  5038. }
  5039. //
  5040. // Allocate BSTRs for the property names we want to retreive
  5041. //
  5042. pName = SysAllocString (TEXT("name"));
  5043. if (!pName)
  5044. {
  5045. DebugMsg((DM_WARNING, TEXT("CPolicySnapIn::GetGPOFriendlyName: Failed to allocate memory for name")));
  5046. hr = HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY);
  5047. goto Exit;
  5048. }
  5049. //
  5050. // Execute the query
  5051. //
  5052. hr = pIWbemServices->ExecQuery (pLanguage, pQuery,
  5053. WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
  5054. NULL, &pEnum);
  5055. if (FAILED(hr))
  5056. {
  5057. DebugMsg((DM_WARNING, TEXT("CPolicySnapIn::GetGPOFriendlyName: Failed to query for %s with 0x%x"),
  5058. pQuery, hr));
  5059. goto Exit;
  5060. }
  5061. //
  5062. // Loop through the results
  5063. //
  5064. hr = pEnum->Next(WBEM_INFINITE, 1, pObjects, &ulRet);
  5065. if (FAILED(hr))
  5066. {
  5067. DebugMsg((DM_WARNING, TEXT("CPolicySnapIn::GetGPOFriendlyName: Failed to get first item in query results for %s with 0x%x"),
  5068. pQuery, hr));
  5069. goto Exit;
  5070. }
  5071. //
  5072. // Check for the "data not available case"
  5073. //
  5074. if (ulRet == 0)
  5075. {
  5076. hr = S_OK;
  5077. goto Exit;
  5078. }
  5079. //
  5080. // Get the name
  5081. //
  5082. hr = pObjects[0]->Get (pName, 0, &varGPOName, NULL, NULL);
  5083. pObjects[0]->Release();
  5084. if (FAILED(hr))
  5085. {
  5086. DebugMsg((DM_WARNING, TEXT("CPolicySnapIn::GetGPOFriendlyName: Failed to get gponame in query results for %s with 0x%x"),
  5087. pQuery, hr));
  5088. goto Exit;
  5089. }
  5090. //
  5091. // Save the name
  5092. //
  5093. *pGPOName = (LPTSTR) LocalAlloc (LPTR, (lstrlen(varGPOName.bstrVal) + 1) * sizeof(TCHAR));
  5094. if (!(*pGPOName))
  5095. {
  5096. DebugMsg((DM_WARNING, TEXT("CPolicySnapIn::GetGPOFriendlyName: Failed to allocate memory for GPO Name")));
  5097. hr = HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY);
  5098. goto Exit;
  5099. }
  5100. lstrcpy (*pGPOName, varGPOName.bstrVal);
  5101. VariantClear (&varGPOName);
  5102. hr = S_OK;
  5103. Exit:
  5104. if (pEnum)
  5105. {
  5106. pEnum->Release();
  5107. }
  5108. if (pQuery)
  5109. {
  5110. SysFreeString (pQuery);
  5111. }
  5112. if (lpQuery)
  5113. {
  5114. LocalFree (lpQuery);
  5115. }
  5116. if (pName)
  5117. {
  5118. SysFreeString (pName);
  5119. }
  5120. return hr;
  5121. }
  5122. //
  5123. // Note: the data in the uiPrecedence argument is really a UINT. It's declared
  5124. // as a HKEY so the hkeyRoot variable that calls this method can be used for both
  5125. // GPE and RSOP mode.
  5126. //
  5127. UINT CPolicyComponentData::ReadRSOPRegistryValue(HKEY uiPrecedence, TCHAR * pszKeyName,
  5128. TCHAR * pszValueName, LPBYTE pData,
  5129. DWORD dwMaxSize, DWORD *dwType,
  5130. LPTSTR *lpGPOName, LPRSOPREGITEM lpItem)
  5131. {
  5132. LPRSOPREGITEM lpTemp;
  5133. BOOL bDeleted = FALSE;
  5134. LPTSTR lpValueNameTemp = pszValueName;
  5135. if (!lpItem)
  5136. {
  5137. lpTemp = m_pRSOPRegistryData;
  5138. if (pszValueName)
  5139. {
  5140. INT iDelPrefixLen = lstrlen(szDELETEPREFIX);
  5141. if (CompareString (LOCALE_USER_DEFAULT, NORM_IGNORECASE | NORM_STOP_ON_NULL,
  5142. pszValueName, iDelPrefixLen,
  5143. szDELETEPREFIX, iDelPrefixLen) == CSTR_EQUAL)
  5144. {
  5145. lpValueNameTemp = pszValueName+iDelPrefixLen;
  5146. bDeleted = TRUE;
  5147. }
  5148. }
  5149. //
  5150. // Find the item
  5151. //
  5152. while (lpTemp)
  5153. {
  5154. if (pszKeyName && lpValueNameTemp &&
  5155. lpTemp->lpKeyName && lpTemp->lpValueName)
  5156. {
  5157. if (bDeleted == lpTemp->bDeleted)
  5158. {
  5159. if ((uiPrecedence == 0) || (uiPrecedence == (HKEY)LongToHandle(lpTemp->uiPrecedence)))
  5160. {
  5161. if (!lstrcmpi(lpTemp->lpValueName, lpValueNameTemp) &&
  5162. !lstrcmpi(lpTemp->lpKeyName, pszKeyName))
  5163. {
  5164. break;
  5165. }
  5166. }
  5167. }
  5168. }
  5169. else if (!pszKeyName && lpValueNameTemp &&
  5170. !lpTemp->lpKeyName && lpTemp->lpValueName)
  5171. {
  5172. if (bDeleted == lpTemp->bDeleted)
  5173. {
  5174. if ((uiPrecedence == 0) || (uiPrecedence == (HKEY)LongToHandle(lpTemp->uiPrecedence)))
  5175. {
  5176. if (!lstrcmpi(lpTemp->lpValueName, lpValueNameTemp))
  5177. {
  5178. break;
  5179. }
  5180. }
  5181. }
  5182. }
  5183. else if (pszKeyName && !lpValueNameTemp &&
  5184. lpTemp->lpKeyName && !lpTemp->lpValueName)
  5185. {
  5186. if (bDeleted == lpTemp->bDeleted)
  5187. {
  5188. if ((uiPrecedence == 0) || (uiPrecedence == (HKEY)LongToHandle(lpTemp->uiPrecedence)))
  5189. {
  5190. if (!lstrcmpi(lpTemp->lpKeyName, pszKeyName))
  5191. {
  5192. break;
  5193. }
  5194. }
  5195. }
  5196. }
  5197. lpTemp = lpTemp->pNext;
  5198. }
  5199. }
  5200. else
  5201. {
  5202. //
  5203. // Read a specific item
  5204. //
  5205. lpTemp = lpItem;
  5206. }
  5207. //
  5208. // Exit now if the item wasn't found
  5209. //
  5210. if (!lpTemp)
  5211. {
  5212. return ERROR_FILE_NOT_FOUND;
  5213. }
  5214. //
  5215. // Check if the data will fit in the buffer passed in
  5216. //
  5217. if (lpTemp->dwSize > dwMaxSize)
  5218. {
  5219. 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"),
  5220. lpTemp->dwSize, dwMaxSize, pszKeyName, pszValueName));
  5221. return ERROR_NOT_ENOUGH_MEMORY;
  5222. }
  5223. //
  5224. // Copy the data
  5225. //
  5226. if (lpTemp->lpData)
  5227. {
  5228. CopyMemory (pData, lpTemp->lpData, lpTemp->dwSize);
  5229. }
  5230. *dwType = lpTemp->dwType;
  5231. if (lpGPOName)
  5232. {
  5233. *lpGPOName = lpTemp->lpGPOName;
  5234. }
  5235. return ERROR_SUCCESS;
  5236. }
  5237. //
  5238. // Note: the data in the uiPrecedence argument is really a UINT. It's declared
  5239. // as a HKEY so the hkeyRoot variable that calls this method can be used for both
  5240. // GPE and RSOP mode.
  5241. //
  5242. UINT CPolicyComponentData::EnumRSOPRegistryValues(HKEY uiPrecedence, TCHAR * pszKeyName,
  5243. TCHAR * pszValueName, DWORD dwMaxSize,
  5244. LPRSOPREGITEM *lpEnum)
  5245. {
  5246. LPRSOPREGITEM lpTemp;
  5247. if (lpEnum && *lpEnum)
  5248. {
  5249. lpTemp = (*lpEnum)->pNext;
  5250. }
  5251. else
  5252. {
  5253. lpTemp = m_pRSOPRegistryData;
  5254. }
  5255. //
  5256. // Find the next item
  5257. //
  5258. while (lpTemp)
  5259. {
  5260. if (!pszKeyName && !lpTemp->lpKeyName)
  5261. {
  5262. if (!lpTemp->bDeleted)
  5263. {
  5264. if ((uiPrecedence == 0) || (uiPrecedence == (HKEY)LongToHandle(lpTemp->uiPrecedence)))
  5265. {
  5266. break;
  5267. }
  5268. }
  5269. }
  5270. else if (pszKeyName && lpTemp->lpKeyName)
  5271. {
  5272. if (!lpTemp->bDeleted)
  5273. {
  5274. if ((uiPrecedence == 0) || (uiPrecedence == (HKEY)LongToHandle(lpTemp->uiPrecedence)))
  5275. {
  5276. if (!lstrcmpi(lpTemp->lpKeyName, pszKeyName))
  5277. {
  5278. break;
  5279. }
  5280. }
  5281. }
  5282. }
  5283. lpTemp = lpTemp->pNext;
  5284. }
  5285. //
  5286. // Exit now if an item wasn't found
  5287. //
  5288. if (!lpTemp)
  5289. {
  5290. *lpEnum = NULL;
  5291. return ERROR_NO_MORE_ITEMS;
  5292. }
  5293. if (lpTemp->lpValueName)
  5294. {
  5295. //
  5296. // Check if the value name will fit in the buffer passed in
  5297. //
  5298. if ((DWORD)(lstrlen(lpTemp->lpValueName) + 1) > dwMaxSize)
  5299. {
  5300. DebugMsg((DM_WARNING, TEXT("CPolicyComponentData::EnumRSOPRegistryValues: The valuename buffer size is too small")));
  5301. return ERROR_NOT_ENOUGH_MEMORY;
  5302. }
  5303. lstrcpy (pszValueName, lpTemp->lpValueName);
  5304. }
  5305. else
  5306. {
  5307. *pszValueName = TEXT('\0');
  5308. }
  5309. //
  5310. // Save the item pointer
  5311. //
  5312. *lpEnum = lpTemp;
  5313. return ERROR_SUCCESS;
  5314. }
  5315. //
  5316. // Note: the data in the uiPrecedence argument is really a UINT. It's declared
  5317. // as a HKEY so the hkeyRoot variable that calls this method can be used for both
  5318. // GPE and RSOP mode.
  5319. //
  5320. UINT CPolicyComponentData::FindRSOPRegistryEntry(HKEY uiPrecedence, TCHAR * pszKeyName,
  5321. TCHAR * pszValueName, LPRSOPREGITEM *lpEnum)
  5322. {
  5323. LPRSOPREGITEM lpTemp;
  5324. BOOL bDeleted = FALSE;
  5325. LPTSTR lpValueNameTemp = pszValueName;
  5326. if (lpEnum && *lpEnum)
  5327. {
  5328. lpTemp = (*lpEnum)->pNext;
  5329. }
  5330. else
  5331. {
  5332. lpTemp = m_pRSOPRegistryData;
  5333. }
  5334. if (pszValueName)
  5335. {
  5336. INT iDelPrefixLen = lstrlen(szDELETEPREFIX);
  5337. if (CompareString (LOCALE_USER_DEFAULT, NORM_IGNORECASE | NORM_STOP_ON_NULL,
  5338. pszValueName, iDelPrefixLen,
  5339. szDELETEPREFIX, iDelPrefixLen) == CSTR_EQUAL)
  5340. {
  5341. lpValueNameTemp = pszValueName+iDelPrefixLen;
  5342. bDeleted = TRUE;
  5343. }
  5344. }
  5345. //
  5346. // Find the next item
  5347. //
  5348. while (lpTemp)
  5349. {
  5350. if (pszKeyName && lpValueNameTemp &&
  5351. lpTemp->lpKeyName && lpTemp->lpValueName)
  5352. {
  5353. if (bDeleted == lpTemp->bDeleted)
  5354. {
  5355. if ((uiPrecedence == 0) || (uiPrecedence == (HKEY)LongToHandle(lpTemp->uiPrecedence)))
  5356. {
  5357. if (!lstrcmpi(lpTemp->lpValueName, lpValueNameTemp) &&
  5358. !lstrcmpi(lpTemp->lpKeyName, pszKeyName))
  5359. {
  5360. break;
  5361. }
  5362. }
  5363. }
  5364. }
  5365. else if (!pszKeyName && lpValueNameTemp &&
  5366. !lpTemp->lpKeyName && lpTemp->lpValueName)
  5367. {
  5368. if (bDeleted == lpTemp->bDeleted)
  5369. {
  5370. if ((uiPrecedence == 0) || (uiPrecedence == (HKEY)LongToHandle(lpTemp->uiPrecedence)))
  5371. {
  5372. if (!lstrcmpi(lpTemp->lpValueName, lpValueNameTemp))
  5373. {
  5374. break;
  5375. }
  5376. }
  5377. }
  5378. }
  5379. else if (pszKeyName && !lpValueNameTemp &&
  5380. lpTemp->lpKeyName && !lpTemp->lpValueName)
  5381. {
  5382. if (bDeleted == lpTemp->bDeleted)
  5383. {
  5384. if ((uiPrecedence == 0) || (uiPrecedence == (HKEY)LongToHandle(lpTemp->uiPrecedence)))
  5385. {
  5386. if (!lstrcmpi(lpTemp->lpKeyName, pszKeyName))
  5387. {
  5388. break;
  5389. }
  5390. }
  5391. }
  5392. }
  5393. lpTemp = lpTemp->pNext;
  5394. }
  5395. //
  5396. // Exit now if an item wasn't found
  5397. //
  5398. if (!lpTemp)
  5399. {
  5400. *lpEnum = NULL;
  5401. return ERROR_NO_MORE_ITEMS;
  5402. }
  5403. //
  5404. // Save the item pointer
  5405. //
  5406. *lpEnum = lpTemp;
  5407. return ERROR_SUCCESS;
  5408. }
  5409. VOID CPolicyComponentData::DumpRSOPRegistryData(void)
  5410. {
  5411. LPRSOPREGITEM lpTemp;
  5412. TCHAR szDebug[50];
  5413. lpTemp = m_pRSOPRegistryData;
  5414. if (m_bUserScope)
  5415. OutputDebugString (TEXT("\n\nDump of RSOP user registry data\n"));
  5416. else
  5417. OutputDebugString (TEXT("\n\nDump of RSOP computer registry data\n"));
  5418. while (lpTemp)
  5419. {
  5420. OutputDebugString (TEXT("\n\n"));
  5421. if (lpTemp->lpKeyName)
  5422. OutputDebugString (lpTemp->lpKeyName);
  5423. else
  5424. OutputDebugString (TEXT("NULL Key Name"));
  5425. OutputDebugString (TEXT("\n"));
  5426. if (lpTemp->lpValueName)
  5427. OutputDebugString (lpTemp->lpValueName);
  5428. else
  5429. OutputDebugString (TEXT("NULL Value Name"));
  5430. OutputDebugString (TEXT("\n"));
  5431. if (lpTemp->dwType == REG_DWORD)
  5432. {
  5433. wsprintf (szDebug, TEXT("REG_DWORD\n%d\n"), *((LPDWORD)lpTemp->lpData));
  5434. OutputDebugString (szDebug);
  5435. }
  5436. else if (lpTemp->dwType == REG_SZ)
  5437. {
  5438. OutputDebugString (TEXT("REG_SZ\n"));
  5439. if (lpTemp->lpData)
  5440. OutputDebugString ((LPTSTR)lpTemp->lpData);
  5441. OutputDebugString (TEXT("\n"));
  5442. }
  5443. else if (lpTemp->dwType == REG_EXPAND_SZ)
  5444. {
  5445. OutputDebugString (TEXT("REG_EXPAND_SZ\n"));
  5446. if (lpTemp->lpData)
  5447. OutputDebugString ((LPTSTR)lpTemp->lpData);
  5448. OutputDebugString (TEXT("\n"));
  5449. }
  5450. else if (lpTemp->dwType == REG_BINARY)
  5451. {
  5452. OutputDebugString (TEXT("REG_BINARY\n"));
  5453. OutputDebugString (TEXT("<Binary data not displayed>\n"));
  5454. }
  5455. else if (lpTemp->dwType == REG_NONE)
  5456. {
  5457. OutputDebugString (TEXT("REG_NONE\n"));
  5458. }
  5459. else
  5460. {
  5461. wsprintf (szDebug, TEXT("Unknown type: %d\n"), lpTemp->dwType);
  5462. OutputDebugString (szDebug);
  5463. }
  5464. wsprintf (szDebug, TEXT("Precedence: %d\n"), lpTemp->uiPrecedence);
  5465. OutputDebugString(szDebug);
  5466. wsprintf (szDebug, TEXT("Deleted: %d\n"), lpTemp->bDeleted);
  5467. OutputDebugString(szDebug);
  5468. wsprintf (szDebug, TEXT("bFoundInADM: %d\n"), lpTemp->bFoundInADM);
  5469. OutputDebugString(szDebug);
  5470. OutputDebugString (TEXT("GPOName: "));
  5471. if (lpTemp->lpGPOName)
  5472. OutputDebugString (lpTemp->lpGPOName);
  5473. else
  5474. OutputDebugString (TEXT("NULL GPO Name"));
  5475. OutputDebugString (TEXT("\n"));
  5476. lpTemp = lpTemp->pNext;
  5477. }
  5478. OutputDebugString (TEXT("\n\n"));
  5479. }
  5480. BOOL CPolicyComponentData::FindEntryInActionList(POLICY * pPolicy, ACTIONLIST * pActionList, LPTSTR lpKeyName, LPTSTR lpValueName)
  5481. {
  5482. UINT uIndex;
  5483. ACTION * pAction;
  5484. TCHAR * pszKeyName;
  5485. TCHAR * pszValueName;
  5486. //
  5487. // Loop through each of the entries to see if they match
  5488. //
  5489. for (uIndex = 0; uIndex < pActionList->nActionItems; uIndex++)
  5490. {
  5491. if (uIndex == 0)
  5492. {
  5493. pAction = &pActionList->Action[0];
  5494. }
  5495. else
  5496. {
  5497. pAction = (ACTION *)(((LPBYTE)pActionList) + pAction->uOffsetNextAction);
  5498. }
  5499. //
  5500. // Get the value and keynames
  5501. //
  5502. pszValueName = (TCHAR *)(((LPBYTE)pActionList) + pAction->uOffsetValueName);
  5503. if (pAction->uOffsetKeyName)
  5504. {
  5505. pszKeyName = (TCHAR *)(((LPBYTE)pActionList) + pAction->uOffsetKeyName);
  5506. }
  5507. else
  5508. {
  5509. pszKeyName = (TCHAR *)(((LPBYTE)pPolicy) + pPolicy->uOffsetKeyName);
  5510. }
  5511. if (!lstrcmpi(pszKeyName, lpKeyName) && !lstrcmpi(pszValueName, lpValueName)) {
  5512. return TRUE;
  5513. }
  5514. }
  5515. return FALSE;
  5516. }
  5517. BOOL CPolicyComponentData::FindEntryInTable(TABLEENTRY * pTable, LPTSTR lpKeyName, LPTSTR lpValueName)
  5518. {
  5519. POLICY * pEntry = (POLICY *) pTable;
  5520. if ((pEntry->dwType & ETYPE_POLICY) || (pEntry->dwType & ETYPE_SETTING))
  5521. {
  5522. if (!lstrcmpi(lpKeyName, GETKEYNAMEPTR(pEntry)))
  5523. {
  5524. if ( (!(GETVALUENAMEPTR(pEntry)) || (!lstrcmpi(GETVALUENAMEPTR(pEntry), TEXT("")))) ) {
  5525. if (pEntry->dwType & STYPE_LISTBOX) {
  5526. return TRUE;
  5527. }
  5528. }
  5529. else if (!lstrcmpi(lpValueName, GETVALUENAMEPTR(pEntry)))
  5530. {
  5531. return TRUE;
  5532. }
  5533. }
  5534. // look in the actionlists
  5535. // actionslist can be at 3 places. under policy itself or under the dropdown lists below
  5536. ACTIONLIST * pActionList;
  5537. if (pEntry->dwType & ETYPE_POLICY) {
  5538. if (pEntry->uOffsetActionList_On) {
  5539. pActionList = (ACTIONLIST *)(((LPBYTE)pEntry) + pEntry->uOffsetActionList_On);
  5540. if (FindEntryInActionList(pEntry, pActionList, lpKeyName, lpValueName))
  5541. return TRUE;
  5542. }
  5543. if (pEntry->uOffsetActionList_Off) {
  5544. pActionList = (ACTIONLIST *)(((LPBYTE)pEntry) + pEntry->uOffsetActionList_Off);
  5545. if (FindEntryInActionList(pEntry, pActionList, lpKeyName, lpValueName))
  5546. return TRUE;
  5547. }
  5548. }
  5549. if (pEntry->dwType & ETYPE_SETTING) {
  5550. SETTINGS * pSettings = (SETTINGS *)pTable;
  5551. if (pSettings) {
  5552. BYTE * pObjectData = GETOBJECTDATAPTR(pSettings);
  5553. if (pObjectData) {
  5554. if ((pEntry->dwType & STYPE_MASK) == STYPE_CHECKBOX) {
  5555. if (((CHECKBOXINFO *)pObjectData)->uOffsetActionList_On) {
  5556. pActionList = (ACTIONLIST *)(((LPBYTE)pEntry) + (((CHECKBOXINFO *)pObjectData)->uOffsetActionList_On));
  5557. if (FindEntryInActionList(pEntry, pActionList, lpKeyName, lpValueName))
  5558. return TRUE;
  5559. }
  5560. if (((CHECKBOXINFO *)pObjectData)->uOffsetActionList_Off) {
  5561. pActionList = (ACTIONLIST *)(((LPBYTE)pEntry) + (((CHECKBOXINFO *)pObjectData)->uOffsetActionList_Off));
  5562. if (FindEntryInActionList(pEntry, pActionList, lpKeyName, lpValueName))
  5563. return TRUE;
  5564. }
  5565. }
  5566. if ((pEntry->dwType & STYPE_MASK) == STYPE_DROPDOWNLIST) {
  5567. DROPDOWNINFO * pddi;
  5568. pddi = (DROPDOWNINFO *) pObjectData;
  5569. while (pddi) {
  5570. if (pddi->uOffsetActionList) {
  5571. pActionList = (ACTIONLIST *)(((LPBYTE)pEntry) + pddi->uOffsetActionList);
  5572. if (FindEntryInActionList(pEntry, pActionList, lpKeyName, lpValueName))
  5573. return TRUE;
  5574. }
  5575. if (pddi->uOffsetNextDropdowninfo) {
  5576. pddi = (DROPDOWNINFO *) ( (BYTE *) pEntry + pddi->uOffsetNextDropdowninfo);
  5577. }
  5578. else {
  5579. pddi = NULL;
  5580. }
  5581. }
  5582. }
  5583. }
  5584. }
  5585. }
  5586. }
  5587. if (pEntry->pChild)
  5588. {
  5589. if (FindEntryInTable(pEntry->pChild, lpKeyName, lpValueName))
  5590. {
  5591. return TRUE;
  5592. }
  5593. }
  5594. if (pEntry->pNext)
  5595. {
  5596. if (FindEntryInTable(pEntry->pNext, lpKeyName, lpValueName))
  5597. {
  5598. return TRUE;
  5599. }
  5600. }
  5601. return FALSE;
  5602. }
  5603. VOID CPolicyComponentData::AddEntryToList (TABLEENTRY *pItem)
  5604. {
  5605. TABLEENTRY *lpTemp;
  5606. lpTemp = m_pExtraSettingsRoot->pChild;
  5607. if (!lpTemp)
  5608. {
  5609. m_pExtraSettingsRoot->pChild = pItem;
  5610. return;
  5611. }
  5612. while (lpTemp->pNext)
  5613. {
  5614. lpTemp = lpTemp->pNext;
  5615. }
  5616. lpTemp->pNext = pItem;
  5617. pItem->pPrev = lpTemp;
  5618. }
  5619. VOID CPolicyComponentData::InitializeExtraSettings (VOID)
  5620. {
  5621. LPRSOPREGITEM lpTemp;
  5622. TCHAR szValueStr[MAX_PATH];
  5623. lpTemp = m_pRSOPRegistryData;
  5624. while (lpTemp)
  5625. {
  5626. //
  5627. // Build REGITEM structures for every registry entry that has a precedence of 1
  5628. // and that is not found in any adm file
  5629. //
  5630. if ((lpTemp->uiPrecedence == 1) && (lpTemp->dwType != REG_NONE) && (!lpTemp->bDeleted))
  5631. {
  5632. DWORD dwBufSize = 0;
  5633. REGITEM *pTmp, *pItem;
  5634. LPTSTR lpName;
  5635. //
  5636. // Check to see if this registry entry is used by any adm policy / part
  5637. //
  5638. if (m_bUserScope)
  5639. {
  5640. if (m_pUserCategoryList)
  5641. {
  5642. lpTemp->bFoundInADM = FindEntryInTable(m_pUserCategoryList,
  5643. lpTemp->lpKeyName,
  5644. lpTemp->lpValueName);
  5645. }
  5646. }
  5647. else
  5648. {
  5649. if (m_pMachineCategoryList)
  5650. {
  5651. lpTemp->bFoundInADM = FindEntryInTable(m_pMachineCategoryList,
  5652. lpTemp->lpKeyName,
  5653. lpTemp->lpValueName);
  5654. }
  5655. }
  5656. if (!lpTemp->bFoundInADM)
  5657. {
  5658. //
  5659. // Build regitem entry
  5660. //
  5661. pItem = (REGITEM *) GlobalAlloc(GPTR, sizeof(REGITEM));
  5662. if (pItem)
  5663. {
  5664. pItem->dwSize = sizeof(REGITEM);
  5665. pItem->dwType = ETYPE_REGITEM;
  5666. pItem->lpItem = lpTemp;
  5667. dwBufSize += lstrlen (lpTemp->lpKeyName) + 1;
  5668. if (lpTemp->lpValueName && *lpTemp->lpValueName)
  5669. {
  5670. dwBufSize += lstrlen (lpTemp->lpValueName) + 1;
  5671. }
  5672. lpName = (LPTSTR) LocalAlloc (LPTR, dwBufSize * sizeof(TCHAR));
  5673. if (lpName)
  5674. {
  5675. lstrcpy (lpName, lpTemp->lpKeyName);
  5676. if (lpTemp->lpValueName && *lpTemp->lpValueName)
  5677. {
  5678. lstrcat (lpName, TEXT("\\"));
  5679. lstrcat (lpName, lpTemp->lpValueName);
  5680. }
  5681. //
  5682. // Add the display name
  5683. //
  5684. pTmp = (REGITEM *) AddDataToEntry((TABLEENTRY *)pItem,
  5685. (BYTE *)lpName,(lstrlen(lpName)+1) * sizeof(TCHAR),&(pItem->uOffsetName),
  5686. &dwBufSize);
  5687. if (pTmp)
  5688. {
  5689. pItem = pTmp;
  5690. //
  5691. // Add the keyname
  5692. //
  5693. pTmp = (REGITEM *) AddDataToEntry((TABLEENTRY *)pItem,
  5694. (BYTE *)lpTemp->lpKeyName,(lstrlen(lpTemp->lpKeyName)+1) * sizeof(TCHAR),&(pItem->uOffsetKeyName),
  5695. &dwBufSize);
  5696. if (pTmp)
  5697. {
  5698. pItem = pTmp;
  5699. szValueStr[0] = TEXT('\0');
  5700. if (lpTemp->dwType == REG_DWORD)
  5701. {
  5702. wsprintf (szValueStr, TEXT("%d"), (DWORD) *((LPDWORD)lpTemp->lpData));
  5703. }
  5704. else if (lpTemp->dwType == REG_SZ)
  5705. {
  5706. lstrcpyn (szValueStr, (LPTSTR)lpTemp->lpData, ARRAYSIZE(szValueStr));
  5707. }
  5708. else if (lpTemp->dwType == REG_EXPAND_SZ)
  5709. {
  5710. lstrcpyn (szValueStr, (LPTSTR)lpTemp->lpData, ARRAYSIZE(szValueStr));
  5711. }
  5712. else if (lpTemp->dwType == REG_BINARY)
  5713. {
  5714. LoadString(g_hInstance, IDS_BINARYDATA, szValueStr, ARRAYSIZE(szValueStr));
  5715. }
  5716. else
  5717. {
  5718. LoadString(g_hInstance, IDS_UNKNOWNDATA, szValueStr, ARRAYSIZE(szValueStr));
  5719. }
  5720. //
  5721. // Add the value in string format
  5722. //
  5723. pTmp = (REGITEM *) AddDataToEntry((TABLEENTRY *)pItem,
  5724. (BYTE *)szValueStr,(lstrlen(szValueStr)+1) * sizeof(TCHAR),&(pItem->uOffsetValueStr),
  5725. &dwBufSize);
  5726. if (pTmp)
  5727. {
  5728. pItem = pTmp;
  5729. //
  5730. // Check if this is a real policy
  5731. //
  5732. if (CompareString(LOCALE_USER_DEFAULT, NORM_IGNORECASE | NORM_STOP_ON_NULL,
  5733. lpTemp->lpKeyName, m_iSWPoliciesLen,
  5734. SOFTWARE_POLICIES, m_iSWPoliciesLen) == CSTR_EQUAL)
  5735. {
  5736. pItem->bTruePolicy = TRUE;
  5737. }
  5738. else if (CompareString(LOCALE_USER_DEFAULT, NORM_IGNORECASE | NORM_STOP_ON_NULL,
  5739. lpTemp->lpKeyName, m_iWinPoliciesLen,
  5740. WINDOWS_POLICIES, m_iWinPoliciesLen) == CSTR_EQUAL)
  5741. {
  5742. pItem->bTruePolicy = TRUE;
  5743. }
  5744. AddEntryToList ((TABLEENTRY *)pItem);
  5745. }
  5746. else
  5747. {
  5748. GlobalFree (pItem);
  5749. }
  5750. }
  5751. else
  5752. {
  5753. GlobalFree (pItem);
  5754. }
  5755. }
  5756. else
  5757. {
  5758. GlobalFree (pItem);
  5759. }
  5760. LocalFree (lpName);
  5761. }
  5762. else
  5763. {
  5764. GlobalFree (pItem);
  5765. }
  5766. }
  5767. }
  5768. }
  5769. lpTemp = lpTemp->pNext;
  5770. }
  5771. }
  5772. BOOL CPolicyComponentData::DoesNodeExist (LPSUPPORTEDENTRY *pList, LPTSTR lpString)
  5773. {
  5774. LPSUPPORTEDENTRY lpItem;
  5775. if (!(*pList))
  5776. {
  5777. return FALSE;
  5778. }
  5779. lpItem = *pList;
  5780. while (lpItem)
  5781. {
  5782. if (!lstrcmpi(lpItem->lpString, lpString))
  5783. {
  5784. return TRUE;
  5785. }
  5786. lpItem = lpItem->pNext;
  5787. }
  5788. return FALSE;
  5789. }
  5790. BOOL CPolicyComponentData::CheckSupportedFilter (POLICY *pPolicy)
  5791. {
  5792. LPSUPPORTEDENTRY lpItem = m_pSupportedStrings;
  5793. LPTSTR lpString = GETSUPPORTEDPTR(pPolicy);
  5794. if (!lpItem || !m_bUseSupportedOnFilter)
  5795. {
  5796. return TRUE;
  5797. }
  5798. while (lpItem)
  5799. {
  5800. if (!lpString)
  5801. {
  5802. if (lpItem->bNull)
  5803. {
  5804. return lpItem->bEnabled;
  5805. }
  5806. }
  5807. else
  5808. {
  5809. if (!lstrcmpi(lpItem->lpString, lpString))
  5810. {
  5811. return lpItem->bEnabled;
  5812. }
  5813. }
  5814. lpItem = lpItem->pNext;
  5815. }
  5816. return TRUE;
  5817. }
  5818. BOOL CPolicyComponentData::IsAnyPolicyAllowedPastFilter(TABLEENTRY * pCategory)
  5819. {
  5820. TABLEENTRY * pEntry;
  5821. INT iState;
  5822. if (!pCategory || !pCategory->pChild)
  5823. {
  5824. return FALSE;
  5825. }
  5826. pEntry = pCategory->pChild;
  5827. while (pEntry)
  5828. {
  5829. if (pEntry->dwType & ETYPE_CATEGORY)
  5830. {
  5831. if (IsAnyPolicyAllowedPastFilter(pEntry))
  5832. {
  5833. return TRUE;
  5834. }
  5835. }
  5836. else if (pEntry->dwType & ETYPE_POLICY)
  5837. {
  5838. if (CheckSupportedFilter((POLICY *) pEntry))
  5839. {
  5840. return TRUE;
  5841. }
  5842. }
  5843. pEntry = pEntry->pNext;
  5844. }
  5845. return FALSE;
  5846. }
  5847. VOID CPolicyComponentData::AddSupportedNode (LPSUPPORTEDENTRY *pList, LPTSTR lpString,
  5848. BOOL bNull)
  5849. {
  5850. LPSUPPORTEDENTRY lpItem;
  5851. DWORD dwSize;
  5852. //
  5853. // Check if this item is already in the link list first
  5854. //
  5855. if (DoesNodeExist (pList, lpString))
  5856. {
  5857. return;
  5858. }
  5859. //
  5860. // Add it to the list
  5861. //
  5862. dwSize = sizeof(SUPPORTEDENTRY);
  5863. dwSize += ((lstrlen(lpString) + 1) * sizeof(TCHAR));
  5864. lpItem = (LPSUPPORTEDENTRY) LocalAlloc (LPTR, dwSize);
  5865. if (!lpItem)
  5866. {
  5867. return;
  5868. }
  5869. lpItem->lpString = (LPTSTR)(((LPBYTE)lpItem) + sizeof(SUPPORTEDENTRY));
  5870. lstrcpy (lpItem->lpString, lpString);
  5871. lpItem->bEnabled = TRUE;
  5872. lpItem->bNull = bNull;
  5873. lpItem->pNext = *pList;
  5874. *pList = lpItem;
  5875. }
  5876. VOID CPolicyComponentData::FreeSupportedData(LPSUPPORTEDENTRY lpList)
  5877. {
  5878. LPSUPPORTEDENTRY lpTemp;
  5879. do {
  5880. lpTemp = lpList->pNext;
  5881. LocalFree (lpList);
  5882. lpList = lpTemp;
  5883. } while (lpTemp);
  5884. }
  5885. VOID CPolicyComponentData::InitializeSupportInfo(TABLEENTRY * pTable, LPSUPPORTEDENTRY *pList)
  5886. {
  5887. POLICY * pEntry = (POLICY *) pTable;
  5888. LPTSTR lpString;
  5889. if (pEntry->dwType & ETYPE_POLICY)
  5890. {
  5891. lpString = GETSUPPORTEDPTR(pEntry);
  5892. if (lpString)
  5893. {
  5894. AddSupportedNode (pList, lpString, FALSE);
  5895. }
  5896. }
  5897. if (pEntry->pChild)
  5898. {
  5899. InitializeSupportInfo(pEntry->pChild, pList);
  5900. }
  5901. if (pEntry->pNext)
  5902. {
  5903. InitializeSupportInfo(pEntry->pNext, pList);
  5904. }
  5905. }
  5906. ///////////////////////////////////////////////////////////////////////////////
  5907. // //
  5908. // Class factory object implementation //
  5909. // //
  5910. ///////////////////////////////////////////////////////////////////////////////
  5911. CPolicyComponentDataCF::CPolicyComponentDataCF(BOOL bUser, BOOL bRSOP)
  5912. {
  5913. m_cRef = 1;
  5914. InterlockedIncrement(&g_cRefThisDll);
  5915. m_bUser = bUser;
  5916. m_bRSOP = bRSOP;
  5917. }
  5918. CPolicyComponentDataCF::~CPolicyComponentDataCF()
  5919. {
  5920. InterlockedDecrement(&g_cRefThisDll);
  5921. }
  5922. ///////////////////////////////////////////////////////////////////////////////
  5923. // //
  5924. // Class factory object implementation (IUnknown) //
  5925. // //
  5926. ///////////////////////////////////////////////////////////////////////////////
  5927. STDMETHODIMP_(ULONG)
  5928. CPolicyComponentDataCF::AddRef()
  5929. {
  5930. return ++m_cRef;
  5931. }
  5932. STDMETHODIMP_(ULONG)
  5933. CPolicyComponentDataCF::Release()
  5934. {
  5935. if (--m_cRef == 0)
  5936. {
  5937. delete this;
  5938. return 0;
  5939. }
  5940. return m_cRef;
  5941. }
  5942. STDMETHODIMP
  5943. CPolicyComponentDataCF::QueryInterface(REFIID riid, LPVOID FAR* ppv)
  5944. {
  5945. if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IClassFactory))
  5946. {
  5947. *ppv = (LPCLASSFACTORY)this;
  5948. m_cRef++;
  5949. return S_OK;
  5950. }
  5951. else
  5952. {
  5953. *ppv = NULL;
  5954. return E_NOINTERFACE;
  5955. }
  5956. }
  5957. ///////////////////////////////////////////////////////////////////////////////
  5958. // //
  5959. // Class factory object implementation (IClassFactory) //
  5960. // //
  5961. ///////////////////////////////////////////////////////////////////////////////
  5962. STDMETHODIMP
  5963. CPolicyComponentDataCF::CreateInstance(LPUNKNOWN pUnkOuter,
  5964. REFIID riid,
  5965. LPVOID FAR* ppvObj)
  5966. {
  5967. *ppvObj = NULL;
  5968. if (pUnkOuter)
  5969. return CLASS_E_NOAGGREGATION;
  5970. CPolicyComponentData *pComponentData = new CPolicyComponentData(m_bUser, m_bRSOP); // ref count == 1
  5971. if (!pComponentData)
  5972. return E_OUTOFMEMORY;
  5973. HRESULT hr = pComponentData->QueryInterface(riid, ppvObj);
  5974. pComponentData->Release(); // release initial ref
  5975. return hr;
  5976. }
  5977. STDMETHODIMP
  5978. CPolicyComponentDataCF::LockServer(BOOL fLock)
  5979. {
  5980. return E_NOTIMPL;
  5981. }
  5982. ///////////////////////////////////////////////////////////////////////////////
  5983. // //
  5984. // Class factory object creation (IClassFactory) //
  5985. // //
  5986. ///////////////////////////////////////////////////////////////////////////////
  5987. HRESULT CreatePolicyComponentDataClassFactory (REFCLSID rclsid, REFIID riid, LPVOID* ppv)
  5988. {
  5989. HRESULT hr;
  5990. //
  5991. // Admin Templates in editing mode
  5992. //
  5993. if (IsEqualCLSID (rclsid, CLSID_PolicySnapInMachine)) {
  5994. CPolicyComponentDataCF *pComponentDataCF = new CPolicyComponentDataCF(FALSE, FALSE); // ref == 1
  5995. if (!pComponentDataCF)
  5996. return E_OUTOFMEMORY;
  5997. hr = pComponentDataCF->QueryInterface(riid, ppv);
  5998. pComponentDataCF->Release(); // release initial ref
  5999. return hr;
  6000. }
  6001. if (IsEqualCLSID (rclsid, CLSID_PolicySnapInUser)) {
  6002. CPolicyComponentDataCF *pComponentDataCF = new CPolicyComponentDataCF(TRUE, FALSE); // ref == 1
  6003. if (!pComponentDataCF)
  6004. return E_OUTOFMEMORY;
  6005. hr = pComponentDataCF->QueryInterface(riid, ppv);
  6006. pComponentDataCF->Release(); // release initial ref
  6007. return hr;
  6008. }
  6009. //
  6010. // Admin Templates in RSOP mode
  6011. //
  6012. if (IsEqualCLSID (rclsid, CLSID_RSOPolicySnapInMachine)) {
  6013. CPolicyComponentDataCF *pComponentDataCF = new CPolicyComponentDataCF(FALSE, TRUE); // ref == 1
  6014. if (!pComponentDataCF)
  6015. return E_OUTOFMEMORY;
  6016. hr = pComponentDataCF->QueryInterface(riid, ppv);
  6017. pComponentDataCF->Release(); // release initial ref
  6018. return hr;
  6019. }
  6020. if (IsEqualCLSID (rclsid, CLSID_RSOPolicySnapInUser)) {
  6021. CPolicyComponentDataCF *pComponentDataCF = new CPolicyComponentDataCF(TRUE, TRUE); // ref == 1
  6022. if (!pComponentDataCF)
  6023. return E_OUTOFMEMORY;
  6024. hr = pComponentDataCF->QueryInterface(riid, ppv);
  6025. pComponentDataCF->Release(); // release initial ref
  6026. return hr;
  6027. }
  6028. return CLASS_E_CLASSNOTAVAILABLE;
  6029. }
  6030. unsigned int CPolicySnapIn::m_cfNodeType = RegisterClipboardFormat(CCF_NODETYPE);
  6031. ///////////////////////////////////////////////////////////////////////////////
  6032. // //
  6033. // CPolicySnapIn object implementation //
  6034. // //
  6035. ///////////////////////////////////////////////////////////////////////////////
  6036. CPolicySnapIn::CPolicySnapIn(CPolicyComponentData *pComponent)
  6037. {
  6038. m_cRef = 1;
  6039. InterlockedIncrement(&g_cRefThisDll);
  6040. m_pcd = pComponent;
  6041. m_pConsole = NULL;
  6042. m_pResult = NULL;
  6043. m_pHeader = NULL;
  6044. m_pConsoleVerb = NULL;
  6045. m_pDisplayHelp = NULL;
  6046. m_nColumn1Size = 350;
  6047. m_nColumn2Size = 100;
  6048. m_nColumn3Size = 200;
  6049. m_lViewMode = LVS_REPORT;
  6050. if (m_pcd->m_bRSOP)
  6051. {
  6052. m_bPolicyOnly = FALSE;
  6053. }
  6054. else
  6055. {
  6056. m_bPolicyOnly = TRUE;
  6057. }
  6058. m_dwPolicyOnlyPolicy = 2;
  6059. m_hMsgWindow = NULL;
  6060. m_uiRefreshMsg = RegisterWindowMessage (TEXT("ADM Template Reload"));
  6061. m_pCurrentPolicy = NULL;
  6062. m_hPropDlg = NULL;
  6063. LoadString(g_hInstance, IDS_NAME, m_pName, ARRAYSIZE(m_pName));
  6064. LoadString(g_hInstance, IDS_STATE, m_pState, ARRAYSIZE(m_pState));
  6065. LoadString(g_hInstance, IDS_SETTING, m_pSetting, ARRAYSIZE(m_pSetting));
  6066. LoadString(g_hInstance, IDS_GPONAME, m_pGPOName, ARRAYSIZE(m_pGPOName));
  6067. LoadString(g_hInstance, IDS_MULTIPLEGPOS, m_pMultipleGPOs, ARRAYSIZE(m_pMultipleGPOs));
  6068. LoadString(g_hInstance, IDS_ENABLED, m_pEnabled, ARRAYSIZE(m_pEnabled));
  6069. LoadString(g_hInstance, IDS_DISABLED, m_pDisabled, ARRAYSIZE(m_pDisabled));
  6070. LoadString(g_hInstance, IDS_NOTCONFIGURED, m_pNotConfigured, ARRAYSIZE(m_pNotConfigured));
  6071. }
  6072. CPolicySnapIn::~CPolicySnapIn()
  6073. {
  6074. InterlockedDecrement(&g_cRefThisDll);
  6075. if (m_pConsole != NULL)
  6076. {
  6077. m_pConsole->SetHeader(NULL);
  6078. m_pConsole->Release();
  6079. m_pConsole = NULL;
  6080. }
  6081. if (m_pHeader != NULL)
  6082. {
  6083. m_pHeader->Release();
  6084. m_pHeader = NULL;
  6085. }
  6086. if (m_pResult != NULL)
  6087. {
  6088. m_pResult->Release();
  6089. m_pResult = NULL;
  6090. }
  6091. if (m_pConsoleVerb != NULL)
  6092. {
  6093. m_pConsoleVerb->Release();
  6094. m_pConsoleVerb = NULL;
  6095. }
  6096. if (m_pDisplayHelp != NULL)
  6097. {
  6098. m_pDisplayHelp->Release();
  6099. m_pDisplayHelp = NULL;
  6100. }
  6101. }
  6102. ///////////////////////////////////////////////////////////////////////////////
  6103. // //
  6104. // CPolicySnapIn object implementation (IUnknown) //
  6105. // //
  6106. ///////////////////////////////////////////////////////////////////////////////
  6107. HRESULT CPolicySnapIn::QueryInterface (REFIID riid, void **ppv)
  6108. {
  6109. if (IsEqualIID(riid, IID_IComponent) || IsEqualIID(riid, IID_IUnknown))
  6110. {
  6111. *ppv = (LPCOMPONENT)this;
  6112. m_cRef++;
  6113. return S_OK;
  6114. }
  6115. else if (IsEqualIID(riid, IID_IExtendContextMenu))
  6116. {
  6117. *ppv = (LPEXTENDCONTEXTMENU)this;
  6118. m_cRef++;
  6119. return S_OK;
  6120. }
  6121. else if (IsEqualIID(riid, IID_IExtendPropertySheet))
  6122. {
  6123. *ppv = (LPEXTENDPROPERTYSHEET)this;
  6124. m_cRef++;
  6125. return S_OK;
  6126. }
  6127. else
  6128. {
  6129. *ppv = NULL;
  6130. return E_NOINTERFACE;
  6131. }
  6132. }
  6133. ULONG CPolicySnapIn::AddRef (void)
  6134. {
  6135. return ++m_cRef;
  6136. }
  6137. ULONG CPolicySnapIn::Release (void)
  6138. {
  6139. if (--m_cRef == 0) {
  6140. delete this;
  6141. return 0;
  6142. }
  6143. return m_cRef;
  6144. }
  6145. ///////////////////////////////////////////////////////////////////////////////
  6146. // //
  6147. // CPolicySnapIn object implementation (IComponent) //
  6148. // //
  6149. ///////////////////////////////////////////////////////////////////////////////
  6150. STDMETHODIMP CPolicySnapIn::Initialize(LPCONSOLE lpConsole)
  6151. {
  6152. HRESULT hr;
  6153. WNDCLASS wc;
  6154. HKEY hKey;
  6155. DWORD dwSize, dwType;
  6156. // Save the IConsole pointer
  6157. m_pConsole = lpConsole;
  6158. m_pConsole->AddRef();
  6159. hr = m_pConsole->QueryInterface(IID_IHeaderCtrl,
  6160. reinterpret_cast<void**>(&m_pHeader));
  6161. // Give the console the header control interface pointer
  6162. if (SUCCEEDED(hr))
  6163. m_pConsole->SetHeader(m_pHeader);
  6164. m_pConsole->QueryInterface(IID_IResultData,
  6165. reinterpret_cast<void**>(&m_pResult));
  6166. hr = m_pConsole->QueryConsoleVerb(&m_pConsoleVerb);
  6167. hr = m_pConsole->QueryInterface(IID_IDisplayHelp,
  6168. reinterpret_cast<void**>(&m_pDisplayHelp));
  6169. ZeroMemory (&wc, sizeof(wc));
  6170. wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
  6171. wc.lpfnWndProc = (WNDPROC)ClipWndProc;
  6172. wc.cbWndExtra = sizeof(DWORD);
  6173. wc.hInstance = (HINSTANCE) g_hInstance;
  6174. wc.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);
  6175. wc.lpszClassName = TEXT("ClipClass");
  6176. if (!RegisterClass(&wc))
  6177. {
  6178. if (GetLastError() != ERROR_CLASS_ALREADY_EXISTS)
  6179. {
  6180. DebugMsg((DM_WARNING, TEXT("CPolicySnapIn::Initialize: RegisterClass for clipclass failed with %d."),
  6181. GetLastError()));
  6182. return E_FAIL;
  6183. }
  6184. }
  6185. ZeroMemory (&wc, sizeof(wc));
  6186. wc.lpfnWndProc = (WNDPROC)MessageWndProc;
  6187. wc.cbWndExtra = sizeof(LPVOID);
  6188. wc.hInstance = (HINSTANCE) g_hInstance;
  6189. wc.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);
  6190. wc.lpszClassName = TEXT("GPMessageWindowClass");
  6191. if (!RegisterClass(&wc))
  6192. {
  6193. if (GetLastError() != ERROR_CLASS_ALREADY_EXISTS)
  6194. {
  6195. DebugMsg((DM_WARNING, TEXT("CPolicySnapIn::Initialize: RegisterClass for message window class failed with %d."),
  6196. GetLastError()));
  6197. return E_FAIL;
  6198. }
  6199. }
  6200. m_hMsgWindow = CreateWindow (TEXT("GPMessageWindowClass"), TEXT("GP Hidden Message Window"),
  6201. WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, 0, 0, NULL, NULL, NULL,
  6202. (LPVOID) this);
  6203. if (!m_hMsgWindow)
  6204. {
  6205. DebugMsg((DM_WARNING, TEXT("CPolicySnapIn::Initialize: CreateWindow failed with %d."),
  6206. GetLastError()));
  6207. return E_FAIL;
  6208. }
  6209. //
  6210. // Load the user's options
  6211. //
  6212. if (RegOpenKeyEx (HKEY_CURRENT_USER, GPE_POLICIES_KEY, 0,
  6213. KEY_READ, &hKey) == ERROR_SUCCESS)
  6214. {
  6215. dwSize = sizeof(m_dwPolicyOnlyPolicy);
  6216. RegQueryValueEx (hKey, POLICYONLY_VALUE, NULL, &dwType,
  6217. (LPBYTE) &m_dwPolicyOnlyPolicy, &dwSize);
  6218. RegCloseKey (hKey);
  6219. }
  6220. if (m_dwPolicyOnlyPolicy == 0)
  6221. {
  6222. m_bPolicyOnly = FALSE;
  6223. }
  6224. else if (m_dwPolicyOnlyPolicy == 1)
  6225. {
  6226. m_bPolicyOnly = TRUE;
  6227. }
  6228. return S_OK;
  6229. }
  6230. STDMETHODIMP CPolicySnapIn::Destroy(MMC_COOKIE cookie)
  6231. {
  6232. DestroyWindow (m_hMsgWindow);
  6233. if (m_pConsole != NULL)
  6234. {
  6235. m_pConsole->SetHeader(NULL);
  6236. m_pConsole->Release();
  6237. m_pConsole = NULL;
  6238. }
  6239. if (m_pHeader != NULL)
  6240. {
  6241. m_pHeader->Release();
  6242. m_pHeader = NULL;
  6243. }
  6244. if (m_pResult != NULL)
  6245. {
  6246. m_pResult->Release();
  6247. m_pResult = NULL;
  6248. }
  6249. if (m_pConsoleVerb != NULL)
  6250. {
  6251. m_pConsoleVerb->Release();
  6252. m_pConsoleVerb = NULL;
  6253. }
  6254. if (m_pDisplayHelp != NULL)
  6255. {
  6256. m_pDisplayHelp->Release();
  6257. m_pDisplayHelp = NULL;
  6258. }
  6259. return S_OK;
  6260. }
  6261. STDMETHODIMP CPolicySnapIn::Notify(LPDATAOBJECT lpDataObject, MMC_NOTIFY_TYPE event, LPARAM arg, LPARAM param)
  6262. {
  6263. HRESULT hr = S_OK;
  6264. switch(event)
  6265. {
  6266. case MMCN_COLUMNS_CHANGED:
  6267. hr = S_OK;
  6268. break;
  6269. case MMCN_DBLCLICK:
  6270. hr = S_FALSE;
  6271. break;
  6272. case MMCN_ADD_IMAGES:
  6273. HBITMAP hbmp16x16;
  6274. HBITMAP hbmp32x32;
  6275. hbmp16x16 = LoadBitmap(g_hInstance, MAKEINTRESOURCE(IDB_16x16));
  6276. if (hbmp16x16)
  6277. {
  6278. hbmp32x32 = LoadBitmap(g_hInstance, MAKEINTRESOURCE(IDB_32x32));
  6279. if (hbmp32x32)
  6280. {
  6281. LPIMAGELIST pImageList = (LPIMAGELIST) arg;
  6282. // Set the images
  6283. pImageList->ImageListSetStrip(reinterpret_cast<LONG_PTR *>(hbmp16x16),
  6284. reinterpret_cast<LONG_PTR *>(hbmp32x32),
  6285. 0, RGB(255, 0, 255));
  6286. DeleteObject(hbmp32x32);
  6287. }
  6288. DeleteObject(hbmp16x16);
  6289. }
  6290. break;
  6291. case MMCN_SHOW:
  6292. if (arg == TRUE)
  6293. {
  6294. RESULTDATAITEM resultItem;
  6295. LPPOLICYDATAOBJECT pPolicyDataObject;
  6296. TABLEENTRY * pNode, *pTemp = NULL;
  6297. MMC_COOKIE cookie;
  6298. INT i, iState;
  6299. BOOL bAdd;
  6300. //
  6301. // Get the cookie of the scope pane item
  6302. //
  6303. hr = lpDataObject->QueryInterface(IID_IPolicyDataObject, (LPVOID *)&pPolicyDataObject);
  6304. if (FAILED(hr))
  6305. return S_OK;
  6306. hr = pPolicyDataObject->GetCookie(&cookie);
  6307. pPolicyDataObject->Release(); // release initial ref
  6308. if (FAILED(hr))
  6309. return S_OK;
  6310. pNode = (TABLEENTRY *)cookie;
  6311. if (pNode)
  6312. {
  6313. pTemp = pNode->pChild;
  6314. }
  6315. //
  6316. // Prepare the view
  6317. //
  6318. m_pHeader->InsertColumn(0, m_pSetting, LVCFMT_LEFT, m_nColumn1Size);
  6319. m_pHeader->InsertColumn(1, m_pState, LVCFMT_CENTER, m_nColumn2Size);
  6320. if (m_pcd->m_bRSOP)
  6321. {
  6322. m_pHeader->InsertColumn(2, m_pGPOName, LVCFMT_CENTER, m_nColumn3Size);
  6323. }
  6324. m_pResult->SetViewMode(m_lViewMode);
  6325. //
  6326. // Add the Policies
  6327. //
  6328. while (pTemp)
  6329. {
  6330. if (pTemp->dwType == ETYPE_POLICY)
  6331. {
  6332. bAdd = TRUE;
  6333. if (m_pcd->m_bUseSupportedOnFilter)
  6334. {
  6335. bAdd = m_pcd->CheckSupportedFilter((POLICY *)pTemp);
  6336. }
  6337. if (bAdd && m_pcd->m_bShowConfigPoliciesOnly)
  6338. {
  6339. INT iState;
  6340. iState = GetPolicyState(pTemp, 1, NULL);
  6341. if (iState == -1)
  6342. {
  6343. bAdd = FALSE;
  6344. }
  6345. }
  6346. if (bAdd && m_bPolicyOnly)
  6347. {
  6348. if (((POLICY *) pTemp)->bTruePolicy != TRUE)
  6349. {
  6350. bAdd = FALSE;
  6351. }
  6352. }
  6353. if (bAdd)
  6354. {
  6355. resultItem.mask = RDI_STR | RDI_IMAGE | RDI_PARAM;
  6356. resultItem.str = MMC_CALLBACK;
  6357. if (((POLICY *) pTemp)->bTruePolicy)
  6358. {
  6359. resultItem.nImage = 4;
  6360. }
  6361. else
  6362. {
  6363. resultItem.nImage = 5;
  6364. }
  6365. resultItem.nCol = 0;
  6366. resultItem.lParam = (LPARAM) pTemp;
  6367. if (SUCCEEDED(m_pResult->InsertItem(&resultItem)))
  6368. {
  6369. resultItem.mask = RDI_STR;
  6370. resultItem.str = MMC_CALLBACK;
  6371. resultItem.bScopeItem = FALSE;
  6372. resultItem.nCol = 1;
  6373. m_pResult->SetItem(&resultItem);
  6374. }
  6375. }
  6376. }
  6377. else if (pTemp->dwType == ETYPE_REGITEM)
  6378. {
  6379. bAdd = TRUE;
  6380. if (m_bPolicyOnly)
  6381. {
  6382. if (((REGITEM *) pTemp)->bTruePolicy != TRUE)
  6383. {
  6384. bAdd = FALSE;
  6385. }
  6386. }
  6387. if (((REGITEM *) pTemp)->lpItem->bFoundInADM == TRUE)
  6388. {
  6389. bAdd = FALSE;
  6390. }
  6391. if (bAdd)
  6392. {
  6393. resultItem.mask = RDI_STR | RDI_IMAGE | RDI_PARAM;
  6394. resultItem.str = MMC_CALLBACK;
  6395. if (((REGITEM *) pTemp)->bTruePolicy)
  6396. {
  6397. resultItem.nImage = 4;
  6398. }
  6399. else
  6400. {
  6401. resultItem.nImage = 5;
  6402. }
  6403. resultItem.nCol = 0;
  6404. resultItem.lParam = (LPARAM) pTemp;
  6405. if (SUCCEEDED(m_pResult->InsertItem(&resultItem)))
  6406. {
  6407. resultItem.mask = RDI_STR;
  6408. resultItem.str = MMC_CALLBACK;
  6409. resultItem.bScopeItem = FALSE;
  6410. resultItem.nCol = 1;
  6411. m_pResult->SetItem(&resultItem);
  6412. }
  6413. }
  6414. }
  6415. pTemp = pTemp->pNext;
  6416. }
  6417. }
  6418. else
  6419. {
  6420. m_pHeader->GetColumnWidth(0, &m_nColumn1Size);
  6421. m_pHeader->GetColumnWidth(1, &m_nColumn2Size);
  6422. if (m_pcd->m_bRSOP)
  6423. {
  6424. m_pHeader->GetColumnWidth(2, &m_nColumn3Size);
  6425. }
  6426. m_pResult->GetViewMode(&m_lViewMode);
  6427. }
  6428. break;
  6429. case MMCN_SELECT:
  6430. {
  6431. LPPOLICYDATAOBJECT pPolicyDataObject;
  6432. DATA_OBJECT_TYPES type;
  6433. MMC_COOKIE cookie;
  6434. POLICY * pPolicy;
  6435. //
  6436. // See if this is one of our items.
  6437. //
  6438. hr = lpDataObject->QueryInterface(IID_IPolicyDataObject, (LPVOID *)&pPolicyDataObject);
  6439. if (FAILED(hr))
  6440. break;
  6441. pPolicyDataObject->GetType(&type);
  6442. pPolicyDataObject->GetCookie(&cookie);
  6443. pPolicyDataObject->Release();
  6444. if (m_pConsoleVerb)
  6445. {
  6446. //
  6447. // Set the default verb to open
  6448. //
  6449. m_pConsoleVerb->SetDefaultVerb(MMC_VERB_OPEN);
  6450. //
  6451. // If this is a result pane item or the root of the namespace
  6452. // nodes, enable the Properties menu item
  6453. //
  6454. if (type == CCT_RESULT)
  6455. {
  6456. if (HIWORD(arg))
  6457. {
  6458. m_pConsoleVerb->SetVerbState(MMC_VERB_PROPERTIES, ENABLED, TRUE);
  6459. m_pConsoleVerb->SetDefaultVerb(MMC_VERB_PROPERTIES);
  6460. }
  6461. }
  6462. }
  6463. if (m_hPropDlg && (type == CCT_RESULT) && HIWORD(arg))
  6464. {
  6465. pPolicy = (POLICY *)cookie;
  6466. if (pPolicy->dwType & ETYPE_POLICY)
  6467. {
  6468. m_pCurrentPolicy = pPolicy;
  6469. SendMessage (GetParent(m_hPropDlg), PSM_QUERYSIBLINGS, 1000, 0);
  6470. }
  6471. }
  6472. }
  6473. break;
  6474. case MMCN_CONTEXTHELP:
  6475. {
  6476. if (m_pDisplayHelp)
  6477. {
  6478. LPPOLICYDATAOBJECT pPolicyDataObject;
  6479. DATA_OBJECT_TYPES type;
  6480. MMC_COOKIE cookie;
  6481. LPOLESTR pszHelpTopic;
  6482. //
  6483. // See if this is one of our items.
  6484. //
  6485. hr = lpDataObject->QueryInterface(IID_IPolicyDataObject, (LPVOID *)&pPolicyDataObject);
  6486. if (FAILED(hr))
  6487. break;
  6488. pPolicyDataObject->Release();
  6489. //
  6490. // Display the admin templates help page
  6491. //
  6492. pszHelpTopic = (LPOLESTR) CoTaskMemAlloc (50 * sizeof(WCHAR));
  6493. if (pszHelpTopic)
  6494. {
  6495. lstrcpy (pszHelpTopic, TEXT("gpedit.chm::/adm.htm"));
  6496. m_pDisplayHelp->ShowTopic (pszHelpTopic);
  6497. }
  6498. }
  6499. }
  6500. break;
  6501. default:
  6502. hr = E_UNEXPECTED;
  6503. break;
  6504. }
  6505. return hr;
  6506. }
  6507. STDMETHODIMP CPolicySnapIn::GetDisplayInfo(LPRESULTDATAITEM pResult)
  6508. {
  6509. if (pResult)
  6510. {
  6511. if (pResult->bScopeItem == TRUE)
  6512. {
  6513. if (pResult->mask & RDI_STR)
  6514. {
  6515. if (pResult->nCol == 0)
  6516. {
  6517. if (pResult->lParam == 0)
  6518. {
  6519. pResult->str = m_pcd->m_szRootName;
  6520. }
  6521. else
  6522. {
  6523. TABLEENTRY * pTableEntry;
  6524. pTableEntry = (TABLEENTRY *)(pResult->lParam);
  6525. pResult->str = GETNAMEPTR(pTableEntry);
  6526. }
  6527. }
  6528. else
  6529. {
  6530. pResult->str = L"";
  6531. }
  6532. }
  6533. if (pResult->mask & RDI_IMAGE)
  6534. {
  6535. pResult->nImage = 0;
  6536. }
  6537. }
  6538. else
  6539. {
  6540. if (pResult->mask & RDI_STR)
  6541. {
  6542. TABLEENTRY * pTableEntry;
  6543. INT iState;
  6544. LPTSTR lpGPOName = NULL;
  6545. pTableEntry = (TABLEENTRY *)(pResult->lParam);
  6546. if (pTableEntry->dwType & ETYPE_REGITEM)
  6547. {
  6548. REGITEM *pItem = (REGITEM*)pTableEntry;
  6549. if (pResult->nCol == 0)
  6550. {
  6551. pResult->str = GETNAMEPTR(pTableEntry);
  6552. if (pResult->str == NULL)
  6553. {
  6554. pResult->str = (LPOLESTR)L"";
  6555. }
  6556. }
  6557. else if (pResult->nCol == 1)
  6558. {
  6559. pResult->str = GETVALUESTRPTR(pItem);
  6560. }
  6561. else if (pResult->nCol == 2)
  6562. {
  6563. pResult->str = pItem->lpItem->lpGPOName;
  6564. }
  6565. }
  6566. else
  6567. {
  6568. iState = GetPolicyState (pTableEntry, 1, &lpGPOName);
  6569. if (pResult->nCol == 0)
  6570. {
  6571. pResult->str = GETNAMEPTR(pTableEntry);
  6572. if (pResult->str == NULL)
  6573. {
  6574. pResult->str = (LPOLESTR)L"";
  6575. }
  6576. }
  6577. else if (pResult->nCol == 1)
  6578. {
  6579. if (iState == 1)
  6580. {
  6581. pResult->str = m_pEnabled;
  6582. }
  6583. else if (iState == 0)
  6584. {
  6585. pResult->str = m_pDisabled;
  6586. }
  6587. else
  6588. {
  6589. pResult->str = m_pNotConfigured;
  6590. }
  6591. }
  6592. else if (pResult->nCol == 2)
  6593. {
  6594. pResult->str = lpGPOName;
  6595. }
  6596. }
  6597. }
  6598. }
  6599. }
  6600. return S_OK;
  6601. }
  6602. STDMETHODIMP CPolicySnapIn::QueryDataObject(MMC_COOKIE cookie, DATA_OBJECT_TYPES type, LPDATAOBJECT *ppDataObject)
  6603. {
  6604. return m_pcd->QueryDataObject(cookie, type, ppDataObject);
  6605. }
  6606. STDMETHODIMP CPolicySnapIn::GetResultViewType(MMC_COOKIE cookie, LPOLESTR *ppViewType,
  6607. long *pViewOptions)
  6608. {
  6609. return S_FALSE;
  6610. }
  6611. STDMETHODIMP CPolicySnapIn::CompareObjects(LPDATAOBJECT lpDataObjectA, LPDATAOBJECT lpDataObjectB)
  6612. {
  6613. HRESULT hr = S_FALSE;
  6614. LPPOLICYDATAOBJECT pPolicyDataObjectA, pPolicyDataObjectB;
  6615. MMC_COOKIE cookie1, cookie2;
  6616. if (lpDataObjectA == NULL || lpDataObjectB == NULL)
  6617. return E_POINTER;
  6618. //
  6619. // QI for the private GPTDataObject interface
  6620. //
  6621. if (FAILED(lpDataObjectA->QueryInterface(IID_IPolicyDataObject,
  6622. (LPVOID *)&pPolicyDataObjectA)))
  6623. {
  6624. return S_FALSE;
  6625. }
  6626. if (FAILED(lpDataObjectB->QueryInterface(IID_IPolicyDataObject,
  6627. (LPVOID *)&pPolicyDataObjectB)))
  6628. {
  6629. pPolicyDataObjectA->Release();
  6630. return S_FALSE;
  6631. }
  6632. pPolicyDataObjectA->GetCookie(&cookie1);
  6633. pPolicyDataObjectB->GetCookie(&cookie2);
  6634. if (cookie1 == cookie2)
  6635. {
  6636. hr = S_OK;
  6637. }
  6638. pPolicyDataObjectA->Release();
  6639. pPolicyDataObjectB->Release();
  6640. return hr;
  6641. }
  6642. ///////////////////////////////////////////////////////////////////////////////
  6643. // //
  6644. // CPolicySnapIn:: object implementation (IExtendContextMenu) //
  6645. // //
  6646. ///////////////////////////////////////////////////////////////////////////////
  6647. STDMETHODIMP CPolicySnapIn::AddMenuItems(LPDATAOBJECT piDataObject,
  6648. LPCONTEXTMENUCALLBACK pCallback,
  6649. LONG *pInsertionAllowed)
  6650. {
  6651. HRESULT hr = S_OK;
  6652. TCHAR szMenuItem[100];
  6653. TCHAR szDescription[250];
  6654. CONTEXTMENUITEM item;
  6655. LPPOLICYDATAOBJECT pPolicyDataObject;
  6656. DATA_OBJECT_TYPES type = CCT_UNINITIALIZED;
  6657. MMC_COOKIE cookie;
  6658. POLICY *pPolicy;
  6659. if (SUCCEEDED(piDataObject->QueryInterface(IID_IPolicyDataObject,
  6660. (LPVOID *)&pPolicyDataObject)))
  6661. {
  6662. pPolicyDataObject->GetType(&type);
  6663. pPolicyDataObject->GetCookie(&cookie);
  6664. pPolicyDataObject->Release();
  6665. }
  6666. if (type == CCT_SCOPE)
  6667. {
  6668. pPolicy = (POLICY *)cookie;
  6669. if (*pInsertionAllowed & CCM_INSERTIONALLOWED_VIEW)
  6670. {
  6671. if (!m_pcd->m_bRSOP)
  6672. {
  6673. LoadString (g_hInstance, IDS_FILTERING, szMenuItem, 100);
  6674. LoadString (g_hInstance, IDS_FILTERINGDESC, szDescription, 250);
  6675. item.strName = szMenuItem;
  6676. item.strStatusBarText = szDescription;
  6677. item.lCommandID = IDM_FILTERING;
  6678. item.lInsertionPointID = CCM_INSERTIONPOINTID_PRIMARY_VIEW;
  6679. item.fFlags = 0;
  6680. item.fSpecialFlags = 0;
  6681. hr = pCallback->AddItem(&item);
  6682. }
  6683. }
  6684. }
  6685. return (hr);
  6686. }
  6687. STDMETHODIMP CPolicySnapIn::Command(LONG lCommandID, LPDATAOBJECT piDataObject)
  6688. {
  6689. if (lCommandID == IDM_FILTERING)
  6690. {
  6691. if (DialogBoxParam(g_hInstance,MAKEINTRESOURCE(IDD_POLICY_FILTERING),
  6692. m_pcd->m_hwndFrame, FilterDlgProc,(LPARAM) this))
  6693. {
  6694. //
  6695. // Refresh the display
  6696. //
  6697. m_pcd->m_pScope->DeleteItem (m_pcd->m_hSWPolicies, FALSE);
  6698. m_pcd->EnumerateScopePane (NULL, m_pcd->m_hSWPolicies);
  6699. }
  6700. }
  6701. return S_OK;
  6702. }
  6703. ///////////////////////////////////////////////////////////////////////////////
  6704. // //
  6705. // CPolicySnapIn object implementation (IExtendPropertySheet) //
  6706. // //
  6707. ///////////////////////////////////////////////////////////////////////////////
  6708. STDMETHODIMP CPolicySnapIn::CreatePropertyPages(LPPROPERTYSHEETCALLBACK lpProvider,
  6709. LONG_PTR handle, LPDATAOBJECT lpDataObject)
  6710. {
  6711. HRESULT hr;
  6712. PROPSHEETPAGE psp;
  6713. HPROPSHEETPAGE hPage[3];
  6714. LPPOLICYDATAOBJECT pPolicyDataObject;
  6715. MMC_COOKIE cookie;
  6716. LPSETTINGSINFO lpSettingsInfo;
  6717. //
  6718. // Make sure this is one of our objects
  6719. //
  6720. if (FAILED(lpDataObject->QueryInterface(IID_IPolicyDataObject,
  6721. (LPVOID *)&pPolicyDataObject)))
  6722. {
  6723. return S_OK;
  6724. }
  6725. //
  6726. // Get the cookie
  6727. //
  6728. pPolicyDataObject->GetCookie(&cookie);
  6729. pPolicyDataObject->Release();
  6730. m_pCurrentPolicy = (POLICY *)cookie;
  6731. //
  6732. // Allocate a settings info structure
  6733. //
  6734. lpSettingsInfo = (LPSETTINGSINFO) LocalAlloc(LPTR, sizeof(SETTINGSINFO));
  6735. if (!lpSettingsInfo)
  6736. {
  6737. DebugMsg((DM_WARNING, TEXT("CPolicySnapIn::CreatePropertyPages: Failed to allocate memory with %d."),
  6738. GetLastError()));
  6739. return S_OK;
  6740. }
  6741. lpSettingsInfo->pCS = this;
  6742. //
  6743. // Allocate a POLICYDLGINFO structure
  6744. //
  6745. lpSettingsInfo->pdi = (POLICYDLGINFO *) LocalAlloc(LPTR,sizeof(POLICYDLGINFO));
  6746. if (!lpSettingsInfo->pdi)
  6747. {
  6748. DebugMsg((DM_WARNING, TEXT("CPolicySnapIn::CreatePropertyPages: Failed to allocate memory with %d."),
  6749. GetLastError()));
  6750. LocalFree (lpSettingsInfo);
  6751. return S_OK;
  6752. }
  6753. //
  6754. // Initialize POLICYDLGINFO
  6755. //
  6756. lpSettingsInfo->pdi->dwControlTableSize = DEF_CONTROLS * sizeof(POLICYCTRLINFO);
  6757. lpSettingsInfo->pdi->nControls = 0;
  6758. lpSettingsInfo->pdi->pEntryRoot = (lpSettingsInfo->pCS->m_pcd->m_bUserScope ?
  6759. lpSettingsInfo->pCS->m_pcd->m_pUserCategoryList :
  6760. lpSettingsInfo->pCS->m_pcd->m_pMachineCategoryList);
  6761. lpSettingsInfo->pdi->hwndApp = lpSettingsInfo->pCS->m_pcd->m_hwndFrame;
  6762. lpSettingsInfo->pdi->pControlTable = (POLICYCTRLINFO *) LocalAlloc(LPTR,
  6763. lpSettingsInfo->pdi->dwControlTableSize);
  6764. if (!lpSettingsInfo->pdi->pControlTable) {
  6765. DebugMsg((DM_WARNING, TEXT("CPolicySnapIn::CreatePropertyPages: Failed to allocate memory with %d."),
  6766. GetLastError()));
  6767. LocalFree (lpSettingsInfo->pdi);
  6768. LocalFree (lpSettingsInfo);
  6769. return S_OK;
  6770. }
  6771. //
  6772. // Initialize the common fields in the property sheet structure
  6773. //
  6774. psp.dwSize = sizeof(PROPSHEETPAGE);
  6775. psp.dwFlags = 0;
  6776. psp.hInstance = g_hInstance;
  6777. psp.lParam = (LPARAM) lpSettingsInfo;
  6778. //
  6779. // Add the pages
  6780. //
  6781. if (m_pCurrentPolicy->dwType & ETYPE_REGITEM)
  6782. {
  6783. psp.pszTemplate = MAKEINTRESOURCE(IDD_POLICY_PRECEDENCE);
  6784. psp.pfnDlgProc = PolicyPrecedenceDlgProc;
  6785. hPage[0] = CreatePropertySheetPage(&psp);
  6786. if (hPage[0])
  6787. {
  6788. hr = lpProvider->AddPage(hPage[0]);
  6789. }
  6790. }
  6791. else
  6792. {
  6793. psp.pszTemplate = MAKEINTRESOURCE(IDD_POLICY);
  6794. psp.pfnDlgProc = PolicyDlgProc;
  6795. hPage[0] = CreatePropertySheetPage(&psp);
  6796. if (hPage[0])
  6797. {
  6798. hr = lpProvider->AddPage(hPage[0]);
  6799. psp.pszTemplate = MAKEINTRESOURCE(IDD_POLICY_HELP);
  6800. psp.pfnDlgProc = PolicyHelpDlgProc;
  6801. hPage[1] = CreatePropertySheetPage(&psp);
  6802. if (hPage[1])
  6803. {
  6804. hr = lpProvider->AddPage(hPage[1]);
  6805. if (m_pcd->m_bRSOP)
  6806. {
  6807. psp.pszTemplate = MAKEINTRESOURCE(IDD_POLICY_PRECEDENCE);
  6808. psp.pfnDlgProc = PolicyPrecedenceDlgProc;
  6809. hPage[2] = CreatePropertySheetPage(&psp);
  6810. if (hPage[2])
  6811. {
  6812. hr = lpProvider->AddPage(hPage[2]);
  6813. }
  6814. }
  6815. }
  6816. else
  6817. {
  6818. DebugMsg((DM_WARNING, TEXT("CPolicySnapIn::CreatePropertyPages: Failed to create property sheet page with %d."),
  6819. GetLastError()));
  6820. hr = E_FAIL;
  6821. }
  6822. }
  6823. else
  6824. {
  6825. DebugMsg((DM_WARNING, TEXT("CPolicySnapIn::CreatePropertyPages: Failed to create property sheet page with %d."),
  6826. GetLastError()));
  6827. hr = E_FAIL;
  6828. }
  6829. }
  6830. return (hr);
  6831. }
  6832. STDMETHODIMP CPolicySnapIn::QueryPagesFor(LPDATAOBJECT lpDataObject)
  6833. {
  6834. LPPOLICYDATAOBJECT pPolicyDataObject;
  6835. DATA_OBJECT_TYPES type;
  6836. if (SUCCEEDED(lpDataObject->QueryInterface(IID_IPolicyDataObject,
  6837. (LPVOID *)&pPolicyDataObject)))
  6838. {
  6839. pPolicyDataObject->GetType(&type);
  6840. pPolicyDataObject->Release();
  6841. if (type == CCT_RESULT)
  6842. {
  6843. if (!m_hPropDlg)
  6844. return S_OK;
  6845. // There's already a propety sheet open so we'll bring it to the front.
  6846. BringWindowToTop(GetParent(m_hPropDlg));
  6847. }
  6848. }
  6849. return S_FALSE;
  6850. }
  6851. ///////////////////////////////////////////////////////////////////////////////
  6852. // //
  6853. // CPolicySnapIn object implementation (Internal functions) //
  6854. // //
  6855. ///////////////////////////////////////////////////////////////////////////////
  6856. BOOL CPolicySnapIn::IsAnyPolicyEnabled(TABLEENTRY * pCategory)
  6857. {
  6858. TABLEENTRY * pEntry;
  6859. INT iState;
  6860. if (!pCategory || !pCategory->pChild)
  6861. {
  6862. return FALSE;
  6863. }
  6864. pEntry = pCategory->pChild;
  6865. while (pEntry)
  6866. {
  6867. if (pEntry->dwType & ETYPE_CATEGORY)
  6868. {
  6869. if (IsAnyPolicyEnabled(pEntry))
  6870. {
  6871. return TRUE;
  6872. }
  6873. }
  6874. else if (pEntry->dwType & ETYPE_POLICY)
  6875. {
  6876. iState = GetPolicyState(pEntry, 1, NULL);
  6877. if ((iState == 1) || (iState == 0))
  6878. {
  6879. return TRUE;
  6880. }
  6881. }
  6882. pEntry = pEntry->pNext;
  6883. }
  6884. return FALSE;
  6885. }
  6886. VOID CPolicySnapIn::RefreshSettingsControls(HWND hDlg)
  6887. {
  6888. BOOL fEnabled = FALSE;
  6889. INT iState;
  6890. LPTSTR lpSupported;
  6891. POLICY *pPolicy = (POLICY *)m_pCurrentPolicy;
  6892. FreeSettingsControls(hDlg);
  6893. SetDlgItemText (hDlg, IDC_POLICY, GETNAMEPTR(m_pCurrentPolicy));
  6894. if (pPolicy->bTruePolicy)
  6895. {
  6896. SendMessage (GetDlgItem(hDlg, IDC_POLICYICON), STM_SETIMAGE, IMAGE_ICON,
  6897. (LPARAM) (HANDLE) m_hPolicyIcon);
  6898. }
  6899. else
  6900. {
  6901. SendMessage (GetDlgItem(hDlg, IDC_POLICYICON), STM_SETIMAGE, IMAGE_ICON,
  6902. (LPARAM) (HANDLE) m_hPreferenceIcon);
  6903. }
  6904. lpSupported = GETSUPPORTEDPTR(pPolicy);
  6905. if (lpSupported)
  6906. {
  6907. ShowWindow (GetDlgItem(hDlg, IDC_SUPPORTEDTITLE), SW_SHOW);
  6908. ShowWindow (GetDlgItem(hDlg, IDC_SUPPORTED), SW_SHOW);
  6909. SetDlgItemText (hDlg, IDC_SUPPORTED, lpSupported);
  6910. }
  6911. else
  6912. {
  6913. SetDlgItemText (hDlg, IDC_SUPPORTED, TEXT(""));
  6914. ShowWindow (GetDlgItem(hDlg, IDC_SUPPORTEDTITLE), SW_HIDE);
  6915. ShowWindow (GetDlgItem(hDlg, IDC_SUPPORTED), SW_HIDE);
  6916. }
  6917. iState = GetPolicyState((TABLEENTRY *)m_pCurrentPolicy, 1, NULL);
  6918. if (iState == 1)
  6919. {
  6920. CheckRadioButton(hDlg, IDC_NOCONFIG, IDC_DISABLED, IDC_ENABLED);
  6921. fEnabled = TRUE;
  6922. }
  6923. else if (iState == 0)
  6924. {
  6925. CheckRadioButton(hDlg, IDC_NOCONFIG, IDC_DISABLED, IDC_DISABLED);
  6926. }
  6927. else
  6928. {
  6929. CheckRadioButton(hDlg, IDC_NOCONFIG, IDC_DISABLED, IDC_NOCONFIG);
  6930. }
  6931. if (m_pcd->m_bRSOP)
  6932. {
  6933. EnableWindow (GetDlgItem(hDlg, IDC_ENABLED), FALSE);
  6934. EnableWindow (GetDlgItem(hDlg, IDC_DISABLED), FALSE);
  6935. EnableWindow (GetDlgItem(hDlg, IDC_NOCONFIG), FALSE);
  6936. }
  6937. if (m_pCurrentPolicy->pChild) {
  6938. CreateSettingsControls(hDlg, (SETTINGS *) m_pCurrentPolicy->pChild, fEnabled);
  6939. InitializeSettingsControls(hDlg, fEnabled);
  6940. } else {
  6941. ShowScrollBar(GetDlgItem(hDlg,IDC_POLICY_SETTINGS),SB_BOTH, FALSE);
  6942. }
  6943. m_bDirty = FALSE;
  6944. PostMessage (GetParent(hDlg), PSM_UNCHANGED, (WPARAM) hDlg, 0);
  6945. SetPrevNextButtonState(hDlg);
  6946. }
  6947. HRESULT CPolicySnapIn::UpdateItemWorker (VOID)
  6948. {
  6949. HRESULTITEM hItem;
  6950. //
  6951. // Update the display
  6952. //
  6953. if (SUCCEEDED(m_pResult->FindItemByLParam((LPARAM)m_pCurrentPolicy, &hItem)))
  6954. {
  6955. if (m_pcd->m_bShowConfigPoliciesOnly)
  6956. m_pResult->DeleteItem(hItem, 0);
  6957. else
  6958. m_pResult->UpdateItem(hItem);
  6959. }
  6960. return S_OK;
  6961. }
  6962. HRESULT CPolicySnapIn::MoveFocusWorker (BOOL bPrevious)
  6963. {
  6964. HRESULTITEM hItem;
  6965. TABLEENTRY * pTemp;
  6966. HRESULT hr;
  6967. RESULTDATAITEM item;
  6968. INT iIndex = 0;
  6969. //
  6970. // Find the currently selected item's index
  6971. //
  6972. while (TRUE)
  6973. {
  6974. ZeroMemory (&item, sizeof(item));
  6975. item.mask = RDI_INDEX | RDI_PARAM;
  6976. item.nIndex = iIndex;
  6977. hr = m_pResult->GetItem (&item);
  6978. if (FAILED(hr))
  6979. {
  6980. return hr;
  6981. }
  6982. if (item.lParam == (LPARAM) m_pCurrentPolicy)
  6983. {
  6984. break;
  6985. }
  6986. iIndex++;
  6987. }
  6988. //
  6989. // Find the currently selected item's hItem
  6990. //
  6991. hr = m_pResult->FindItemByLParam((LPARAM)m_pCurrentPolicy, &hItem);
  6992. if (FAILED(hr))
  6993. {
  6994. return hr;
  6995. }
  6996. //
  6997. // Remove the focus from the original item
  6998. //
  6999. m_pResult->ModifyItemState(0, hItem, 0, LVIS_FOCUSED | LVIS_SELECTED);
  7000. m_pResult->UpdateItem(hItem);
  7001. //
  7002. // Adjust appropriately
  7003. //
  7004. if (bPrevious)
  7005. {
  7006. if (iIndex > 0)
  7007. {
  7008. iIndex--;
  7009. }
  7010. }
  7011. else
  7012. {
  7013. iIndex++;
  7014. }
  7015. //
  7016. // Get the lParam for the new item
  7017. //
  7018. ZeroMemory (&item, sizeof(item));
  7019. item.mask = RDI_INDEX | RDI_PARAM;
  7020. item.nIndex = iIndex;
  7021. hr = m_pResult->GetItem(&item);
  7022. if (FAILED(hr))
  7023. {
  7024. return hr;
  7025. }
  7026. //
  7027. // Find the hItem for the new item
  7028. //
  7029. hr = m_pResult->FindItemByLParam(item.lParam, &hItem);
  7030. if (FAILED(hr))
  7031. {
  7032. return hr;
  7033. }
  7034. //
  7035. // Save this as the currently selected item
  7036. //
  7037. m_pCurrentPolicy = (POLICY *)item.lParam;
  7038. //
  7039. // Set the focus on the new item
  7040. //
  7041. m_pResult->ModifyItemState(0, hItem, LVIS_FOCUSED | LVIS_SELECTED, 0);
  7042. m_pResult->UpdateItem(hItem);
  7043. return S_OK;
  7044. }
  7045. HRESULT CPolicySnapIn::MoveFocus (HWND hDlg, BOOL bPrevious)
  7046. {
  7047. //
  7048. // Send the move focus message to the hidden window on the main
  7049. // thread so it can use the mmc interfaces
  7050. //
  7051. SendMessage (m_hMsgWindow, WM_MOVEFOCUS, (WPARAM) bPrevious, 0);
  7052. //
  7053. // Update the display
  7054. //
  7055. SendMessage (GetParent(hDlg), PSM_QUERYSIBLINGS, 1000, 0);
  7056. return S_OK;
  7057. }
  7058. HRESULT CPolicySnapIn::SetPrevNextButtonStateWorker (HWND hDlg)
  7059. {
  7060. TABLEENTRY * pTemp;
  7061. HRESULT hr;
  7062. RESULTDATAITEM item;
  7063. INT iIndex = 0;
  7064. BOOL bPrev = FALSE, bNext = FALSE, bFound = FALSE;
  7065. //
  7066. // Loop through the items looking for Policies
  7067. //
  7068. while (TRUE)
  7069. {
  7070. ZeroMemory (&item, sizeof(item));
  7071. item.mask = RDI_INDEX | RDI_PARAM;
  7072. item.nIndex = iIndex;
  7073. hr = m_pResult->GetItem (&item);
  7074. if (FAILED(hr))
  7075. {
  7076. break;
  7077. }
  7078. if (item.lParam == (LPARAM) m_pCurrentPolicy)
  7079. {
  7080. bFound = TRUE;
  7081. }
  7082. else
  7083. {
  7084. pTemp = (TABLEENTRY *) item.lParam;
  7085. if ((pTemp->dwType & ETYPE_POLICY) || (pTemp->dwType & ETYPE_REGITEM))
  7086. {
  7087. if ((m_pcd->m_bShowConfigPoliciesOnly) && (pTemp->dwType & ETYPE_POLICY))
  7088. {
  7089. INT iState;
  7090. iState = GetPolicyState(pTemp, 1, NULL);
  7091. if ((iState == 1) || (iState == 0))
  7092. {
  7093. if (bFound)
  7094. {
  7095. bNext = TRUE;
  7096. }
  7097. else
  7098. {
  7099. bPrev = TRUE;
  7100. }
  7101. }
  7102. }
  7103. else
  7104. {
  7105. if (bFound)
  7106. {
  7107. bNext = TRUE;
  7108. }
  7109. else
  7110. {
  7111. bPrev = TRUE;
  7112. }
  7113. }
  7114. }
  7115. }
  7116. iIndex++;
  7117. }
  7118. if (!bNext && (GetFocus() == GetDlgItem(hDlg,IDC_POLICY_NEXT)))
  7119. {
  7120. SetFocus (GetNextDlgTabItem(hDlg, GetDlgItem(hDlg,IDC_POLICY_NEXT), TRUE));
  7121. }
  7122. EnableWindow (GetDlgItem(hDlg,IDC_POLICY_NEXT), bNext);
  7123. if (!bPrev && (GetFocus() == GetDlgItem(hDlg,IDC_POLICY_PREVIOUS)))
  7124. {
  7125. SetFocus (GetNextDlgTabItem(hDlg, GetDlgItem(hDlg,IDC_POLICY_PREVIOUS), FALSE));
  7126. }
  7127. EnableWindow (GetDlgItem(hDlg,IDC_POLICY_PREVIOUS), bPrev);
  7128. return S_OK;
  7129. }
  7130. HRESULT CPolicySnapIn::SetPrevNextButtonState (HWND hDlg)
  7131. {
  7132. //
  7133. // Send the SetPrevNext message to the hidden window on the main
  7134. // thread so it can use the mmc interfaces
  7135. //
  7136. SendMessage (m_hMsgWindow, WM_SETPREVNEXT, (WPARAM) hDlg, 0);
  7137. return S_OK;
  7138. }
  7139. INT_PTR CALLBACK CPolicySnapIn::PolicyDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  7140. {
  7141. LPSETTINGSINFO lpSettingsInfo;
  7142. switch (message)
  7143. {
  7144. case WM_INITDIALOG:
  7145. lpSettingsInfo = (LPSETTINGSINFO) (((LPPROPSHEETPAGE)lParam)->lParam);
  7146. if (!lpSettingsInfo) {
  7147. break;
  7148. }
  7149. SetWindowLongPtr (hDlg, DWLP_USER, (LONG_PTR) lpSettingsInfo);
  7150. lpSettingsInfo->pCS->m_hPropDlg = hDlg;
  7151. lpSettingsInfo->pdi->fActive=TRUE;
  7152. lpSettingsInfo->pCS->m_hPolicyIcon = (HICON) LoadImage (g_hInstance,
  7153. MAKEINTRESOURCE(IDI_POLICY2),
  7154. IMAGE_ICON, 16, 16,
  7155. LR_DEFAULTCOLOR);
  7156. lpSettingsInfo->pCS->m_hPreferenceIcon = (HICON) LoadImage (g_hInstance,
  7157. MAKEINTRESOURCE(IDI_POLICY3),
  7158. IMAGE_ICON, 16, 16,
  7159. LR_DEFAULTCOLOR);
  7160. // now that we've stored pointer to POLICYDLGINFO struct in our extra
  7161. // window data, send WM_USER to clip window to tell it to create a
  7162. // child container window (and store the handle in our POLICYDLGINFO)
  7163. SendDlgItemMessage(hDlg,IDC_POLICY_SETTINGS,WM_USER,0,0L);
  7164. lpSettingsInfo->pCS->RefreshSettingsControls(hDlg);
  7165. lpSettingsInfo->pCS->SetKeyboardHook(hDlg);
  7166. break;
  7167. case WM_MYCHANGENOTIFY:
  7168. lpSettingsInfo = (LPSETTINGSINFO) GetWindowLongPtr (hDlg, DWLP_USER);
  7169. if (lpSettingsInfo) {
  7170. lpSettingsInfo->pCS->m_bDirty = TRUE;
  7171. SendMessage (GetParent(hDlg), PSM_CHANGED, (WPARAM) hDlg, 0);
  7172. }
  7173. break;
  7174. case PSM_QUERYSIBLINGS:
  7175. if (wParam == 1000) {
  7176. lpSettingsInfo = (LPSETTINGSINFO) GetWindowLongPtr (hDlg, DWLP_USER);
  7177. if (!lpSettingsInfo) {
  7178. break;
  7179. }
  7180. lpSettingsInfo->pCS->RefreshSettingsControls(hDlg);
  7181. SendMessage (GetParent(hDlg), PSM_SETTITLE, PSH_PROPTITLE,
  7182. (LPARAM)GETNAMEPTR(lpSettingsInfo->pCS->m_pCurrentPolicy));
  7183. }
  7184. break;
  7185. case WM_COMMAND:
  7186. lpSettingsInfo = (LPSETTINGSINFO) GetWindowLongPtr (hDlg, DWLP_USER);
  7187. if (!lpSettingsInfo) {
  7188. break;
  7189. }
  7190. if ((LOWORD (wParam) == IDC_NOCONFIG) && (HIWORD (wParam) == BN_CLICKED))
  7191. {
  7192. lpSettingsInfo->pCS->InitializeSettingsControls(hDlg, FALSE);
  7193. PostMessage (hDlg, WM_MYCHANGENOTIFY, 0, 0);
  7194. }
  7195. if ((LOWORD (wParam) == IDC_ENABLED) && (HIWORD (wParam) == BN_CLICKED))
  7196. {
  7197. lpSettingsInfo->pCS->InitializeSettingsControls(hDlg, TRUE);
  7198. PostMessage (hDlg, WM_MYCHANGENOTIFY, 0, 0);
  7199. }
  7200. if ((LOWORD (wParam) == IDC_DISABLED) && (HIWORD (wParam) == BN_CLICKED))
  7201. {
  7202. lpSettingsInfo->pCS->InitializeSettingsControls(hDlg, FALSE);
  7203. PostMessage (hDlg, WM_MYCHANGENOTIFY, 0, 0);
  7204. }
  7205. if (LOWORD(wParam) == IDC_POLICY_NEXT)
  7206. {
  7207. if (SUCCEEDED(lpSettingsInfo->pCS->SaveSettings(hDlg)))
  7208. {
  7209. lpSettingsInfo->pCS->MoveFocus (hDlg, FALSE);
  7210. }
  7211. }
  7212. if (LOWORD(wParam) == IDC_POLICY_PREVIOUS)
  7213. {
  7214. if (SUCCEEDED(lpSettingsInfo->pCS->SaveSettings(hDlg)))
  7215. {
  7216. lpSettingsInfo->pCS->MoveFocus (hDlg, TRUE);
  7217. }
  7218. }
  7219. break;
  7220. case WM_NOTIFY:
  7221. lpSettingsInfo = (LPSETTINGSINFO) GetWindowLongPtr (hDlg, DWLP_USER);
  7222. if (!lpSettingsInfo) {
  7223. break;
  7224. }
  7225. switch (((NMHDR FAR*)lParam)->code)
  7226. {
  7227. case PSN_APPLY:
  7228. {
  7229. LPPSHNOTIFY lpNotify = (LPPSHNOTIFY) lParam;
  7230. if (FAILED(lpSettingsInfo->pCS->SaveSettings(hDlg)))
  7231. {
  7232. SetWindowLongPtr (hDlg, DWLP_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE);
  7233. return TRUE;
  7234. }
  7235. if (lpNotify->lParam)
  7236. {
  7237. lpSettingsInfo->pCS->RemoveKeyboardHook();
  7238. lpSettingsInfo->pCS->m_hPropDlg = NULL;
  7239. lpSettingsInfo->pCS->FreeSettingsControls(hDlg);
  7240. DestroyIcon(lpSettingsInfo->pCS->m_hPolicyIcon);
  7241. lpSettingsInfo->pCS->m_hPolicyIcon = NULL;
  7242. DestroyIcon(lpSettingsInfo->pCS->m_hPreferenceIcon);
  7243. lpSettingsInfo->pCS->m_hPreferenceIcon = NULL;
  7244. LocalFree (lpSettingsInfo->pdi->pControlTable);
  7245. LocalFree (lpSettingsInfo->pdi);
  7246. LocalFree (lpSettingsInfo);
  7247. SetWindowLongPtr (hDlg, DWLP_USER, (LONG_PTR) NULL);
  7248. }
  7249. SetWindowLongPtr (hDlg, DWLP_MSGRESULT, PSNRET_NOERROR);
  7250. return TRUE;
  7251. }
  7252. case PSN_RESET:
  7253. lpSettingsInfo->pCS->RemoveKeyboardHook();
  7254. lpSettingsInfo->pCS->m_hPropDlg = NULL;
  7255. SetWindowLongPtr (hDlg, DWLP_MSGRESULT, PSNRET_NOERROR);
  7256. return TRUE;
  7257. }
  7258. break;
  7259. case WM_HELP: // F1
  7260. WinHelp((HWND)((LPHELPINFO) lParam)->hItemHandle, HELP_FILE, HELP_WM_HELP,
  7261. (DWORD_PTR) (LPDWORD) aPolicyHelpIds);
  7262. return TRUE;
  7263. case WM_CONTEXTMENU: // right mouse click
  7264. WinHelp((HWND) wParam, HELP_FILE, HELP_CONTEXTMENU,
  7265. (DWORD_PTR) (LPDWORD) aPolicyHelpIds);
  7266. return TRUE;
  7267. }
  7268. return FALSE;
  7269. }
  7270. INT_PTR CALLBACK CPolicySnapIn::PolicyHelpDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  7271. {
  7272. LPSETTINGSINFO lpSettingsInfo;
  7273. switch (message)
  7274. {
  7275. case WM_INITDIALOG:
  7276. lpSettingsInfo = (LPSETTINGSINFO) (((LPPROPSHEETPAGE)lParam)->lParam);
  7277. if (!lpSettingsInfo) {
  7278. break;
  7279. }
  7280. SetWindowLongPtr (hDlg, DWLP_USER, (LONG_PTR) lpSettingsInfo);
  7281. wParam = 1000;
  7282. // fall through...
  7283. case PSM_QUERYSIBLINGS:
  7284. {
  7285. CPolicySnapIn * pCS;
  7286. LPTSTR lpHelpText;
  7287. if (wParam == 1000)
  7288. {
  7289. lpSettingsInfo = (LPSETTINGSINFO) GetWindowLongPtr (hDlg, DWLP_USER);
  7290. if (!lpSettingsInfo) {
  7291. break;
  7292. }
  7293. pCS = lpSettingsInfo->pCS;
  7294. SetDlgItemText (hDlg, IDC_POLICY_TITLE, GETNAMEPTR(pCS->m_pCurrentPolicy));
  7295. if (pCS->m_pCurrentPolicy->uOffsetHelp)
  7296. {
  7297. lpHelpText = (LPTSTR) ((BYTE *) pCS->m_pCurrentPolicy + pCS->m_pCurrentPolicy->uOffsetHelp);
  7298. SetDlgItemText (hDlg, IDC_POLICY_HELP, lpHelpText);
  7299. }
  7300. else
  7301. {
  7302. SetDlgItemText (hDlg, IDC_POLICY_HELP, TEXT(""));
  7303. }
  7304. pCS->SetPrevNextButtonState(hDlg);
  7305. }
  7306. PostMessage(hDlg, WM_MYREFRESH, 0, 0);
  7307. break;
  7308. }
  7309. case WM_MYREFRESH:
  7310. {
  7311. CPolicySnapIn * pCS;
  7312. BOOL bAlone;
  7313. lpSettingsInfo = (LPSETTINGSINFO) GetWindowLongPtr (hDlg, DWLP_USER);
  7314. pCS = lpSettingsInfo->pCS;
  7315. SendMessage(GetDlgItem(hDlg, IDC_POLICY_HELP), EM_SETSEL, -1, 0);
  7316. bAlone = !(((pCS->m_pCurrentPolicy)->pNext) ||
  7317. ((pCS->m_pCurrentPolicy)->pPrev) );
  7318. if (bAlone) {
  7319. SetFocus(GetDlgItem(GetParent(hDlg), IDOK));
  7320. }
  7321. break;
  7322. }
  7323. case WM_COMMAND:
  7324. lpSettingsInfo = (LPSETTINGSINFO) GetWindowLongPtr (hDlg, DWLP_USER);
  7325. if (!lpSettingsInfo) {
  7326. break;
  7327. }
  7328. if (LOWORD(wParam) == IDC_POLICY_NEXT)
  7329. {
  7330. lpSettingsInfo->pCS->MoveFocus (hDlg, FALSE);
  7331. }
  7332. if (LOWORD(wParam) == IDC_POLICY_PREVIOUS)
  7333. {
  7334. lpSettingsInfo->pCS->MoveFocus (hDlg, TRUE);
  7335. }
  7336. if (LOWORD(wParam) == IDCANCEL)
  7337. {
  7338. SendMessage(GetParent(hDlg), message, wParam, lParam);
  7339. }
  7340. break;
  7341. case WM_NOTIFY:
  7342. switch (((NMHDR FAR*)lParam)->code)
  7343. {
  7344. case PSN_APPLY:
  7345. case PSN_RESET:
  7346. SetWindowLongPtr (hDlg, DWLP_MSGRESULT, PSNRET_NOERROR);
  7347. return TRUE;
  7348. case PSN_SETACTIVE:
  7349. PostMessage(hDlg, WM_MYREFRESH, 0, 0);
  7350. break;
  7351. }
  7352. break;
  7353. case WM_HELP: // F1
  7354. WinHelp((HWND)((LPHELPINFO) lParam)->hItemHandle, HELP_FILE, HELP_WM_HELP,
  7355. (DWORD_PTR) (LPDWORD) aExplainHelpIds);
  7356. return TRUE;
  7357. case WM_CONTEXTMENU: // right mouse click
  7358. WinHelp((HWND) wParam, HELP_FILE, HELP_CONTEXTMENU,
  7359. (DWORD_PTR) (LPDWORD) aExplainHelpIds);
  7360. return TRUE;
  7361. }
  7362. return FALSE;
  7363. }
  7364. INT_PTR CALLBACK CPolicySnapIn::PolicyPrecedenceDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  7365. {
  7366. LPSETTINGSINFO lpSettingsInfo;
  7367. switch (message)
  7368. {
  7369. case WM_INITDIALOG:
  7370. {
  7371. RECT rc;
  7372. TCHAR szHeaderName[50];
  7373. INT iTotal = 0, iCurrent;
  7374. HWND hLV = GetDlgItem (hDlg, IDC_POLICY_PRECEDENCE);
  7375. LV_COLUMN col;
  7376. lpSettingsInfo = (LPSETTINGSINFO) (((LPPROPSHEETPAGE)lParam)->lParam);
  7377. if (!lpSettingsInfo) {
  7378. break;
  7379. }
  7380. SetWindowLongPtr (hDlg, DWLP_USER, (LONG_PTR) lpSettingsInfo);
  7381. //
  7382. // Add the columns
  7383. //
  7384. GetClientRect (hLV, &rc);
  7385. LoadString(g_hInstance, IDS_GPONAME, szHeaderName, ARRAYSIZE(szHeaderName));
  7386. col.mask = LVCF_FMT | LVCF_TEXT | LVCF_SUBITEM | LVCF_WIDTH;
  7387. col.fmt = LVCFMT_LEFT;
  7388. iCurrent = (int)(rc.right * .70);
  7389. iTotal += iCurrent;
  7390. col.cx = iCurrent;
  7391. col.pszText = szHeaderName;
  7392. col.iSubItem = 0;
  7393. ListView_InsertColumn (hLV, 0, &col);
  7394. LoadString(g_hInstance, IDS_SETTING, szHeaderName, ARRAYSIZE(szHeaderName));
  7395. col.iSubItem = 1;
  7396. col.cx = rc.right - iTotal;
  7397. col.fmt = LVCFMT_CENTER;
  7398. ListView_InsertColumn (hLV, 1, &col);
  7399. //
  7400. // Set extended LV styles
  7401. //
  7402. SendMessage(hLV, LVM_SETEXTENDEDLISTVIEWSTYLE, 0,
  7403. LVS_EX_FULLROWSELECT | LVS_EX_LABELTIP);
  7404. }
  7405. wParam = 1000;
  7406. // fall through...
  7407. case PSM_QUERYSIBLINGS:
  7408. {
  7409. CPolicySnapIn * pCS;
  7410. INT iState;
  7411. LPTSTR lpGPOName;
  7412. UINT uiPrecedence = 1;
  7413. LVITEM item;
  7414. INT iItem, iIndex = 0;
  7415. HWND hLV = GetDlgItem (hDlg, IDC_POLICY_PRECEDENCE);
  7416. if (wParam == 1000)
  7417. {
  7418. lpSettingsInfo = (LPSETTINGSINFO) GetWindowLongPtr (hDlg, DWLP_USER);
  7419. if (!lpSettingsInfo) {
  7420. break;
  7421. }
  7422. pCS = lpSettingsInfo->pCS;
  7423. SetDlgItemText (hDlg, IDC_POLICY_TITLE, GETNAMEPTR(pCS->m_pCurrentPolicy));
  7424. SendMessage (hLV, LVM_DELETEALLITEMS, 0, 0);
  7425. if (pCS->m_pCurrentPolicy->dwType & ETYPE_REGITEM)
  7426. {
  7427. LPRSOPREGITEM pItem = ((REGITEM*)pCS->m_pCurrentPolicy)->lpItem;
  7428. LPRSOPREGITEM lpEnum;
  7429. TCHAR szValueStr[MAX_PATH];
  7430. while (TRUE)
  7431. {
  7432. lpEnum = NULL;
  7433. if (pCS->m_pcd->FindRSOPRegistryEntry((HKEY) LongToHandle(uiPrecedence), pItem->lpKeyName,
  7434. pItem->lpValueName, &lpEnum) != ERROR_SUCCESS)
  7435. {
  7436. break;
  7437. }
  7438. //
  7439. // Add the GPO Name
  7440. //
  7441. item.mask = LVIF_TEXT | LVIF_STATE;
  7442. item.iItem = iIndex;
  7443. item.iSubItem = 0;
  7444. item.state = 0;
  7445. item.stateMask = LVIS_SELECTED | LVIS_FOCUSED;
  7446. item.pszText = lpEnum->lpGPOName;
  7447. iItem = (INT)SendMessage (hLV, LVM_INSERTITEM, 0, (LPARAM) &item);
  7448. if (iItem != -1)
  7449. {
  7450. szValueStr[0] = TEXT('\0');
  7451. if (pItem->dwType == REG_DWORD)
  7452. {
  7453. wsprintf (szValueStr, TEXT("%d"), *((LPDWORD)pItem->lpData));
  7454. }
  7455. else if (pItem->dwType == REG_SZ)
  7456. {
  7457. lstrcpyn (szValueStr, (LPTSTR)pItem->lpData, ARRAYSIZE(szValueStr));
  7458. }
  7459. else if (pItem->dwType == REG_EXPAND_SZ)
  7460. {
  7461. lstrcpyn (szValueStr, (LPTSTR)pItem->lpData, ARRAYSIZE(szValueStr));
  7462. }
  7463. else if (pItem->dwType == REG_BINARY)
  7464. {
  7465. LoadString(g_hInstance, IDS_BINARYDATA, szValueStr, ARRAYSIZE(szValueStr));
  7466. }
  7467. else
  7468. {
  7469. LoadString(g_hInstance, IDS_UNKNOWNDATA, szValueStr, ARRAYSIZE(szValueStr));
  7470. }
  7471. //
  7472. // Add the state
  7473. //
  7474. item.mask = LVIF_TEXT;
  7475. item.iItem = iItem;
  7476. item.iSubItem = 1;
  7477. item.pszText = szValueStr;
  7478. SendMessage (hLV, LVM_SETITEMTEXT, iItem, (LPARAM) &item);
  7479. }
  7480. uiPrecedence++;
  7481. iIndex++;
  7482. }
  7483. }
  7484. else
  7485. {
  7486. while (TRUE)
  7487. {
  7488. lpGPOName = NULL; // just in case we have missed a case
  7489. iState = pCS->GetPolicyState ((TABLEENTRY *)pCS->m_pCurrentPolicy, uiPrecedence, &lpGPOName);
  7490. if (iState == -1)
  7491. {
  7492. uiPrecedence++;
  7493. iState = pCS->GetPolicyState ((TABLEENTRY *)pCS->m_pCurrentPolicy, uiPrecedence, &lpGPOName);
  7494. if (iState == -1)
  7495. {
  7496. break;
  7497. }
  7498. }
  7499. //
  7500. // Add the GPO Name
  7501. //
  7502. item.mask = LVIF_TEXT | LVIF_STATE;
  7503. item.iItem = iIndex;
  7504. item.iSubItem = 0;
  7505. item.state = 0;
  7506. item.stateMask = LVIS_SELECTED | LVIS_FOCUSED;
  7507. item.pszText = lpGPOName ? lpGPOName : TEXT("");
  7508. iItem = (INT)SendMessage (hLV, LVM_INSERTITEM, 0, (LPARAM) &item);
  7509. if (iItem != -1)
  7510. {
  7511. //
  7512. // Add the state
  7513. //
  7514. item.mask = LVIF_TEXT;
  7515. item.iItem = iItem;
  7516. item.iSubItem = 1;
  7517. item.pszText = (iState == 1) ? pCS->m_pEnabled : pCS->m_pDisabled;
  7518. SendMessage (hLV, LVM_SETITEMTEXT, iItem, (LPARAM) &item);
  7519. }
  7520. uiPrecedence++;
  7521. iIndex++;
  7522. }
  7523. }
  7524. //
  7525. // Select the first item
  7526. //
  7527. item.mask = LVIF_STATE;
  7528. item.iItem = 0;
  7529. item.iSubItem = 0;
  7530. item.state = LVIS_SELECTED | LVIS_FOCUSED;
  7531. item.stateMask = LVIS_SELECTED | LVIS_FOCUSED;
  7532. SendMessage (hLV, LVM_SETITEMSTATE, 0, (LPARAM) &item);
  7533. pCS->SetPrevNextButtonState(hDlg);
  7534. }
  7535. break;
  7536. }
  7537. case WM_COMMAND:
  7538. lpSettingsInfo = (LPSETTINGSINFO) GetWindowLongPtr (hDlg, DWLP_USER);
  7539. if (!lpSettingsInfo) {
  7540. break;
  7541. }
  7542. if (LOWORD(wParam) == IDC_POLICY_NEXT)
  7543. {
  7544. lpSettingsInfo->pCS->MoveFocus (hDlg, FALSE);
  7545. }
  7546. if (LOWORD(wParam) == IDC_POLICY_PREVIOUS)
  7547. {
  7548. lpSettingsInfo->pCS->MoveFocus (hDlg, TRUE);
  7549. }
  7550. break;
  7551. case WM_NOTIFY:
  7552. switch (((NMHDR FAR*)lParam)->code)
  7553. {
  7554. case PSN_APPLY:
  7555. case PSN_RESET:
  7556. SetWindowLongPtr (hDlg, DWLP_MSGRESULT, PSNRET_NOERROR);
  7557. return TRUE;
  7558. }
  7559. break;
  7560. case WM_HELP: // F1
  7561. WinHelp((HWND)((LPHELPINFO) lParam)->hItemHandle, RSOP_HELP_FILE, HELP_WM_HELP,
  7562. (DWORD_PTR) (LPDWORD) aPrecedenceHelpIds);
  7563. return TRUE;
  7564. case WM_CONTEXTMENU: // right mouse click
  7565. WinHelp((HWND) wParam, RSOP_HELP_FILE, HELP_CONTEXTMENU,
  7566. (DWORD_PTR) (LPDWORD) aPrecedenceHelpIds);
  7567. return TRUE;
  7568. }
  7569. return FALSE;
  7570. }
  7571. LRESULT CPolicySnapIn::CallNextHook(int nCode, WPARAM wParam,LPARAM lParam)
  7572. {
  7573. if (m_hKbdHook)
  7574. {
  7575. return CallNextHookEx(
  7576. m_hKbdHook,
  7577. nCode,
  7578. wParam,
  7579. lParam);
  7580. }
  7581. else
  7582. {
  7583. DebugMsg((DM_WARNING, L"CPolicySnapIn::CallNextHook m_hKbdHook is Null"));
  7584. return 0;
  7585. }
  7586. }
  7587. HWND g_hDlgActive = NULL;
  7588. LRESULT CALLBACK CPolicySnapIn::KeyboardHookProc(int nCode, WPARAM wParam,LPARAM lParam)
  7589. {
  7590. LPSETTINGSINFO lpSettingsInfo;
  7591. lpSettingsInfo = (LPSETTINGSINFO) GetWindowLongPtr(g_hDlgActive, DWLP_USER);
  7592. if (!lpSettingsInfo)
  7593. {
  7594. DebugMsg((DM_WARNING, L"CPolicySnapIn::KeyboardHookProc:GetWindowLongPtr returned NULL"));
  7595. return 0;
  7596. }
  7597. if ( nCode < 0)
  7598. {
  7599. if (lpSettingsInfo->pCS)
  7600. {
  7601. return lpSettingsInfo->pCS->CallNextHook(nCode,
  7602. wParam,
  7603. lParam);
  7604. }
  7605. else
  7606. {
  7607. DebugMsg((DM_WARNING, L"CPolicySnapIn::KeyboardHookProc NULL CPolicySnapIn Pointer"));
  7608. return 0;
  7609. }
  7610. }
  7611. if (wParam == VK_TAB && !(lParam & 0x80000000)) { // tab key depressed
  7612. BOOL fShift = (GetKeyState(VK_SHIFT) & 0x80000000);
  7613. HWND hwndFocus = GetFocus();
  7614. HWND hChild;
  7615. POLICYDLGINFO * pdi;
  7616. int iIndex;
  7617. int iDelta;
  7618. pdi = lpSettingsInfo->pdi;
  7619. if (!pdi)
  7620. {
  7621. if (lpSettingsInfo->pCS)
  7622. {
  7623. return lpSettingsInfo->pCS->CallNextHook(nCode,
  7624. wParam,
  7625. lParam);
  7626. }
  7627. else
  7628. {
  7629. DebugMsg((DM_WARNING, L"CPolicySnapIn::KeyboardHookProc NULL CPolicySnapIn Pointer"));
  7630. return 0;
  7631. }
  7632. }
  7633. // see if the focus control is one of the setting controls
  7634. for (iIndex=0;iIndex<(int)pdi->nControls;iIndex++) {
  7635. if (pdi->pControlTable[iIndex].hwnd == hwndFocus) {
  7636. goto BreakOut;
  7637. }
  7638. hChild = GetWindow (pdi->pControlTable[iIndex].hwnd, GW_CHILD);
  7639. while (hChild) {
  7640. if (hChild == hwndFocus) {
  7641. goto BreakOut;
  7642. }
  7643. hChild = GetWindow (hChild, GW_HWNDNEXT);
  7644. }
  7645. }
  7646. BreakOut:
  7647. if (iIndex == (int) pdi->nControls)
  7648. {
  7649. if (lpSettingsInfo->pCS)
  7650. {
  7651. return lpSettingsInfo->pCS->CallNextHook(nCode,
  7652. wParam,
  7653. lParam);
  7654. }
  7655. else // no, we don't care
  7656. {
  7657. DebugMsg((DM_WARNING, L"CPolicySnapIn::KeyboardHookProc NULL CPolicySnapIn Pointer"));
  7658. return 0;
  7659. }
  7660. }
  7661. iDelta = (fShift ? -1 : 1);
  7662. // from the current setting control, scan forwards or backwards
  7663. // (depending if on shift state, this can be TAB or shift-TAB)
  7664. // to find the next control to give focus to
  7665. for (iIndex += iDelta;iIndex>=0 && iIndex<(int) pdi->nControls;
  7666. iIndex += iDelta) {
  7667. if (pdi->pControlTable[iIndex].uDataIndex !=
  7668. NO_DATA_INDEX &&
  7669. IsWindowEnabled(pdi->pControlTable[iIndex].hwnd)) {
  7670. // found it, set the focus on that control and return 1
  7671. // to eat the keystroke
  7672. SetFocus(pdi->pControlTable[iIndex].hwnd);
  7673. lpSettingsInfo->pCS->EnsureSettingControlVisible(g_hDlgActive,
  7674. pdi->pControlTable[iIndex].hwnd);
  7675. return 1;
  7676. }
  7677. }
  7678. // at first or last control in settings table, let dlg code
  7679. // handle it and give focus to next (or previous) control in dialog
  7680. }
  7681. else
  7682. {
  7683. if (lpSettingsInfo->pCS)
  7684. {
  7685. return lpSettingsInfo->pCS->CallNextHook(nCode,
  7686. wParam,
  7687. lParam);
  7688. }
  7689. else
  7690. {
  7691. DebugMsg((DM_WARNING, L"CPolicySnapIn::KeyboardHookProc NULL CPolicySnapIn Pointer"));
  7692. return 0;
  7693. }
  7694. }
  7695. return 0;
  7696. }
  7697. VOID CPolicySnapIn::SetKeyboardHook(HWND hDlg)
  7698. {
  7699. // hook the keyboard to trap TABs. If this fails for some reason,
  7700. // fail silently and go on, not critical that tabs work correctly
  7701. // (unless you have no mouse :) )
  7702. if (m_hKbdHook = SetWindowsHookEx(WH_KEYBOARD,
  7703. KeyboardHookProc,
  7704. g_hInstance,
  7705. GetCurrentThreadId()))
  7706. {
  7707. g_hDlgActive = hDlg;
  7708. }
  7709. }
  7710. VOID CPolicySnapIn::RemoveKeyboardHook(VOID)
  7711. {
  7712. if (m_hKbdHook) {
  7713. UnhookWindowsHookEx(m_hKbdHook);
  7714. g_hDlgActive = NULL;
  7715. m_hKbdHook = NULL;
  7716. }
  7717. }
  7718. INT CPolicySnapIn::GetPolicyState (TABLEENTRY *pTableEntry, UINT uiPrecedence, LPTSTR *lpGPOName)
  7719. {
  7720. DWORD dwData=0;
  7721. UINT uRet;
  7722. TCHAR * pszValueName;
  7723. TCHAR * pszKeyName;
  7724. DWORD dwFoundSettings=0, dwTemp;
  7725. BOOL fFound=FALSE,fCustomOn=FALSE, fCustomOff=FALSE;
  7726. HKEY hKeyRoot;
  7727. INT iRetVal = -1;
  7728. TABLEENTRY *pChild;
  7729. if (m_pcd->m_bRSOP)
  7730. {
  7731. hKeyRoot = (HKEY) LongToHandle(uiPrecedence);
  7732. }
  7733. else
  7734. {
  7735. if (m_pcd->m_pGPTInformation->GetRegistryKey(
  7736. (m_pcd->m_bUserScope ? GPO_SECTION_USER : GPO_SECTION_MACHINE),
  7737. &hKeyRoot) != S_OK)
  7738. {
  7739. DebugMsg((DM_WARNING, TEXT("CPolicySnapIn::GetPolicyState: Failed to get registry key handle.")));
  7740. return -1;
  7741. }
  7742. }
  7743. //
  7744. // Get the name of the value to read, if any
  7745. //
  7746. if (((POLICY *)pTableEntry)->uOffsetValueName)
  7747. {
  7748. pszKeyName = GETKEYNAMEPTR(pTableEntry);
  7749. pszValueName = GETVALUENAMEPTR(((POLICY *)pTableEntry));
  7750. //
  7751. // First look for custom on/off values
  7752. //
  7753. if (((POLICY *)pTableEntry)->uOffsetValue_On)
  7754. {
  7755. fCustomOn = TRUE;
  7756. if (CompareCustomValue(hKeyRoot,pszKeyName,pszValueName,
  7757. (STATEVALUE *) ((BYTE *) pTableEntry + ((POLICY *)
  7758. pTableEntry)->uOffsetValue_On),&dwFoundSettings,lpGPOName)) {
  7759. dwData = 1;
  7760. fFound =TRUE;
  7761. }
  7762. }
  7763. if (!fFound && ((POLICY *)pTableEntry)->uOffsetValue_Off)
  7764. {
  7765. fCustomOff = TRUE;
  7766. if (CompareCustomValue(hKeyRoot,pszKeyName,pszValueName,
  7767. (STATEVALUE *) ((BYTE *) pTableEntry + ((POLICY *)
  7768. pTableEntry)->uOffsetValue_Off),&dwFoundSettings,lpGPOName)) {
  7769. dwData = 0;
  7770. fFound = TRUE;
  7771. }
  7772. }
  7773. //
  7774. // Look for standard values if custom values have not been specified
  7775. //
  7776. if (!fCustomOn && !fCustomOff && ReadStandardValue(hKeyRoot, pszKeyName, pszValueName,
  7777. pTableEntry, &dwData, &dwFoundSettings, lpGPOName))
  7778. {
  7779. fFound = TRUE;
  7780. }
  7781. if (fFound)
  7782. {
  7783. if (dwData)
  7784. iRetVal = 1;
  7785. else
  7786. iRetVal = 0;
  7787. }
  7788. }
  7789. else if ((((POLICY *)pTableEntry)->uOffsetActionList_On) &&
  7790. CheckActionList((POLICY *)pTableEntry, hKeyRoot, TRUE, lpGPOName))
  7791. {
  7792. iRetVal = 1;
  7793. }
  7794. else if ((((POLICY *)pTableEntry)->uOffsetActionList_Off) &&
  7795. CheckActionList((POLICY *)pTableEntry, hKeyRoot, FALSE, lpGPOName))
  7796. {
  7797. iRetVal = 0;
  7798. }
  7799. else
  7800. {
  7801. BOOL bDisabled = TRUE;
  7802. //
  7803. // Process settings underneath this policy (if any)
  7804. //
  7805. if (pTableEntry->pChild) {
  7806. dwFoundSettings = 0;
  7807. pChild = pTableEntry->pChild;
  7808. while (pChild) {
  7809. dwTemp = 0;
  7810. LoadSettings(pChild, hKeyRoot, &dwTemp, lpGPOName);
  7811. dwFoundSettings |= dwTemp;
  7812. if ((dwTemp & FS_PRESENT) && (!(dwTemp & FS_DISABLED))) {
  7813. bDisabled = FALSE;
  7814. }
  7815. pChild = pChild->pNext;
  7816. }
  7817. if (dwFoundSettings) {
  7818. if (bDisabled)
  7819. iRetVal = 0;
  7820. else
  7821. iRetVal = 1;
  7822. }
  7823. }
  7824. }
  7825. if (!m_pcd->m_bRSOP)
  7826. {
  7827. RegCloseKey (hKeyRoot);
  7828. }
  7829. return iRetVal;
  7830. }
  7831. BOOL CPolicySnapIn::CheckActionList (POLICY * pPolicy, HKEY hKeyRoot, BOOL bActionListOn, LPTSTR *lpGPOName)
  7832. {
  7833. UINT uIndex;
  7834. ACTIONLIST * pActionList;
  7835. ACTION * pAction;
  7836. TCHAR szValue[MAXSTRLEN];
  7837. DWORD dwValue;
  7838. TCHAR szNewValueName[MAX_PATH+1];
  7839. TCHAR * pszKeyName;
  7840. TCHAR * pszValueName;
  7841. TCHAR * pszValue;
  7842. //
  7843. // Get the correct action list
  7844. //
  7845. if (bActionListOn)
  7846. {
  7847. pActionList = (ACTIONLIST *)(((LPBYTE)pPolicy) + pPolicy->uOffsetActionList_On);
  7848. }
  7849. else
  7850. {
  7851. pActionList = (ACTIONLIST *)(((LPBYTE)pPolicy) + pPolicy->uOffsetActionList_Off);
  7852. }
  7853. //
  7854. // Loop through each of the entries to see if they match
  7855. //
  7856. for (uIndex = 0; uIndex < pActionList->nActionItems; uIndex++)
  7857. {
  7858. if (uIndex == 0)
  7859. {
  7860. pAction = &pActionList->Action[0];
  7861. }
  7862. else
  7863. {
  7864. pAction = (ACTION *)(((LPBYTE)pActionList) + pAction->uOffsetNextAction);
  7865. }
  7866. //
  7867. // Get the value and keynames
  7868. //
  7869. pszValueName = (TCHAR *)(((LPBYTE)pActionList) + pAction->uOffsetValueName);
  7870. if (pAction->uOffsetKeyName)
  7871. {
  7872. pszKeyName = (TCHAR *)(((LPBYTE)pActionList) + pAction->uOffsetKeyName);
  7873. }
  7874. else
  7875. {
  7876. pszKeyName = (TCHAR *)(((LPBYTE)pPolicy) + pPolicy->uOffsetKeyName);
  7877. }
  7878. //
  7879. // Add prefixes if appropriate
  7880. //
  7881. PrependValueName(pszValueName, pAction->dwFlags,
  7882. szNewValueName, ARRAYSIZE(szNewValueName));
  7883. if (pAction->dwFlags & VF_ISNUMERIC)
  7884. {
  7885. if (ReadRegistryDWordValue(hKeyRoot, pszKeyName,
  7886. szNewValueName, &dwValue, lpGPOName) != ERROR_SUCCESS)
  7887. {
  7888. return FALSE;
  7889. }
  7890. if (dwValue != pAction->dwValue)
  7891. {
  7892. return FALSE;
  7893. }
  7894. }
  7895. else if (pAction->dwFlags & VF_DELETE)
  7896. {
  7897. //
  7898. // See if this is a value that's marked for deletion
  7899. // (valuename is prepended with "**del."
  7900. //
  7901. if ((ReadRegistryStringValue(hKeyRoot, pszKeyName, szNewValueName,
  7902. szValue,ARRAYSIZE(szValue),lpGPOName)) != ERROR_SUCCESS) {
  7903. return FALSE;
  7904. }
  7905. }
  7906. else
  7907. {
  7908. if (ReadRegistryStringValue(hKeyRoot, pszKeyName, szNewValueName,
  7909. szValue, ARRAYSIZE(szValue),lpGPOName) != ERROR_SUCCESS)
  7910. {
  7911. return FALSE;
  7912. }
  7913. pszValue = (TCHAR *)(((LPBYTE)pActionList) + pAction->uOffsetValue);
  7914. if (lstrcmpi(szValue,pszValue) != 0)
  7915. {
  7916. return FALSE;
  7917. }
  7918. }
  7919. }
  7920. return TRUE;
  7921. }
  7922. UINT CPolicySnapIn::LoadSettings(TABLEENTRY * pTableEntry,HKEY hkeyRoot,
  7923. DWORD * pdwFound, LPTSTR *lpGPOName)
  7924. {
  7925. UINT uRet = ERROR_SUCCESS;
  7926. TCHAR * pszValueName = NULL;
  7927. TCHAR * pszKeyName = NULL;
  7928. DWORD dwData=0,dwFlags,dwFoundSettings=0;
  7929. TCHAR szData[MAXSTRLEN];
  7930. BOOL fCustomOn=FALSE,fCustomOff=FALSE,fFound=FALSE;
  7931. BYTE * pObjectData = GETOBJECTDATAPTR(((SETTINGS *)pTableEntry));
  7932. TCHAR szNewValueName[MAX_PATH+1];
  7933. // get the name of the key to read
  7934. if (((SETTINGS *) pTableEntry)->uOffsetKeyName) {
  7935. pszKeyName = GETKEYNAMEPTR(((SETTINGS *) pTableEntry));
  7936. }
  7937. else return ERROR_NOT_ENOUGH_MEMORY;
  7938. // get the name of the value to read
  7939. if (((SETTINGS *) pTableEntry)->uOffsetValueName) {
  7940. pszValueName = GETVALUENAMEPTR(((SETTINGS *) pTableEntry));
  7941. }
  7942. else return ERROR_NOT_ENOUGH_MEMORY;
  7943. switch (pTableEntry->dwType & STYPE_MASK) {
  7944. case STYPE_EDITTEXT:
  7945. case STYPE_COMBOBOX:
  7946. dwFlags = ( (SETTINGS *) pTableEntry)->dwFlags;
  7947. // add prefixes if appropriate
  7948. PrependValueName(pszValueName,dwFlags,
  7949. szNewValueName,ARRAYSIZE(szNewValueName));
  7950. if ((uRet = ReadRegistryStringValue(hkeyRoot,pszKeyName,
  7951. szNewValueName,szData,ARRAYSIZE(szData),lpGPOName)) == ERROR_SUCCESS) {
  7952. // set flag that we found setting in registry/policy file
  7953. if (pdwFound)
  7954. *pdwFound |= FS_PRESENT;
  7955. } else if (!(dwFlags & VF_DELETE)) {
  7956. // see if this key is marked as deleted
  7957. PrependValueName(pszValueName,VF_DELETE,
  7958. szNewValueName,ARRAYSIZE(szNewValueName));
  7959. if ((uRet = ReadRegistryStringValue(hkeyRoot,pszKeyName,
  7960. szNewValueName,szData,ARRAYSIZE(szData) * sizeof(TCHAR),lpGPOName)) == ERROR_SUCCESS) {
  7961. // set flag that we found setting marked as deleted in
  7962. // policy file
  7963. if (pdwFound)
  7964. *pdwFound |= FS_DELETED;
  7965. }
  7966. }
  7967. return ERROR_SUCCESS;
  7968. break;
  7969. case STYPE_CHECKBOX:
  7970. if (!pObjectData) {
  7971. return ERROR_INVALID_PARAMETER;
  7972. }
  7973. // first look for custom on/off values
  7974. if (((CHECKBOXINFO *) pObjectData)->uOffsetValue_On) {
  7975. fCustomOn = TRUE;
  7976. if (CompareCustomValue(hkeyRoot,pszKeyName,pszValueName,
  7977. (STATEVALUE *) ((BYTE *) pTableEntry + ((CHECKBOXINFO *)
  7978. pObjectData)->uOffsetValue_On),&dwFoundSettings, lpGPOName)) {
  7979. dwData = 1;
  7980. fFound = TRUE;
  7981. }
  7982. }
  7983. if (!fFound && ((CHECKBOXINFO *) pObjectData)->uOffsetValue_Off) {
  7984. fCustomOff = TRUE;
  7985. if (CompareCustomValue(hkeyRoot,pszKeyName,pszValueName,
  7986. (STATEVALUE *) ((BYTE *) pTableEntry + ((CHECKBOXINFO *)
  7987. pObjectData)->uOffsetValue_Off),&dwFoundSettings, lpGPOName)) {
  7988. dwData = 0;
  7989. fFound = TRUE;
  7990. }
  7991. }
  7992. // look for standard values if custom values have not been specified
  7993. if (!fFound &&
  7994. ReadStandardValue(hkeyRoot,pszKeyName,pszValueName,
  7995. pTableEntry,&dwData,&dwFoundSettings, lpGPOName)) {
  7996. fFound = TRUE;
  7997. }
  7998. if (fFound) {
  7999. // set flag that we found setting in registry
  8000. if (pdwFound) {
  8001. *pdwFound |= dwFoundSettings;
  8002. if (dwData == 0) {
  8003. *pdwFound |= FS_DISABLED;
  8004. }
  8005. }
  8006. }
  8007. return ERROR_SUCCESS;
  8008. break;
  8009. case STYPE_NUMERIC:
  8010. if (ReadStandardValue(hkeyRoot,pszKeyName,pszValueName,
  8011. pTableEntry,&dwData,&dwFoundSettings,lpGPOName)) {
  8012. // set flag that we found setting in registry
  8013. if (pdwFound)
  8014. *pdwFound |= dwFoundSettings;
  8015. }
  8016. break;
  8017. case STYPE_DROPDOWNLIST:
  8018. if (ReadCustomValue(hkeyRoot,pszKeyName,pszValueName,
  8019. szData,ARRAYSIZE(szData),&dwData,&dwFlags, lpGPOName)) {
  8020. BOOL fMatch = FALSE;
  8021. if (dwFlags & VF_DELETE) {
  8022. // set flag that we found setting marked as deleted
  8023. // in policy file
  8024. if (pdwFound)
  8025. *pdwFound |= FS_DELETED;
  8026. return ERROR_SUCCESS;
  8027. }
  8028. // walk the list of DROPDOWNINFO structs (one for each state),
  8029. // and see if the value we found matches the value for the state
  8030. if ( ((SETTINGS *) pTableEntry)->uOffsetObjectData) {
  8031. DROPDOWNINFO * pddi = (DROPDOWNINFO *)
  8032. GETOBJECTDATAPTR( ((SETTINGS *) pTableEntry));
  8033. UINT nIndex = 0;
  8034. do {
  8035. if (dwFlags == pddi->dwFlags) {
  8036. if (pddi->dwFlags & VF_ISNUMERIC) {
  8037. if (dwData == pddi->dwValue)
  8038. fMatch = TRUE;
  8039. } else if (!pddi->dwFlags) {
  8040. if (!lstrcmpi(szData,(TCHAR *)((BYTE *)pTableEntry +
  8041. pddi->uOffsetValue)))
  8042. fMatch = TRUE;
  8043. }
  8044. }
  8045. if (!pddi->uOffsetNextDropdowninfo || fMatch)
  8046. break;
  8047. pddi = (DROPDOWNINFO *) ( (BYTE *) pTableEntry +
  8048. pddi->uOffsetNextDropdowninfo);
  8049. nIndex++;
  8050. } while (!fMatch);
  8051. if (fMatch) {
  8052. // set flag that we found setting in registry
  8053. if (pdwFound)
  8054. *pdwFound |= FS_PRESENT;
  8055. }
  8056. }
  8057. }
  8058. break;
  8059. case STYPE_LISTBOX:
  8060. return LoadListboxData(pTableEntry,hkeyRoot,
  8061. pszKeyName,pdwFound, NULL, lpGPOName);
  8062. break;
  8063. }
  8064. return ERROR_SUCCESS;
  8065. }
  8066. UINT CPolicySnapIn::LoadListboxData(TABLEENTRY * pTableEntry,HKEY hkeyRoot,
  8067. TCHAR * pszCurrentKeyName,DWORD * pdwFound, HGLOBAL * phGlobal, LPTSTR *lpGPOName)
  8068. {
  8069. HKEY hKey;
  8070. UINT nIndex=0,nLen;
  8071. TCHAR szValueName[MAX_PATH+1],szValueData[MAX_PATH+1];
  8072. DWORD cbValueName,cbValueData;
  8073. DWORD dwType,dwAlloc=1024 * sizeof(TCHAR),dwUsed=0;
  8074. HGLOBAL hBuf;
  8075. TCHAR * pBuf;
  8076. SETTINGS * pSettings = (SETTINGS *) pTableEntry;
  8077. LISTBOXINFO * pListboxInfo = (LISTBOXINFO *)
  8078. GETOBJECTDATAPTR(pSettings);
  8079. BOOL fFoundValues=FALSE,fFoundDelvals=FALSE;
  8080. UINT uRet=ERROR_SUCCESS;
  8081. LPRSOPREGITEM lpItem = NULL;
  8082. BOOL bMultiple;
  8083. if (m_pcd->m_bRSOP)
  8084. {
  8085. //
  8086. // If this is an additive listbox, we want to pick up entries from
  8087. // any GPO, not just the GPOs of precedence 1, so set hkeyRoot to 0
  8088. //
  8089. if ((pSettings->dwFlags & DF_ADDITIVE) && (hkeyRoot == (HKEY) 1))
  8090. {
  8091. hkeyRoot = (HKEY) 0;
  8092. }
  8093. }
  8094. else
  8095. {
  8096. if (RegOpenKeyEx(hkeyRoot,pszCurrentKeyName,0,KEY_READ,&hKey) != ERROR_SUCCESS)
  8097. return ERROR_SUCCESS; // nothing to do
  8098. }
  8099. // allocate a temp buffer to read entries into
  8100. if (!(hBuf = GlobalAlloc(GHND,dwAlloc)) ||
  8101. !(pBuf = (TCHAR *) GlobalLock(hBuf))) {
  8102. if (hBuf)
  8103. GlobalFree(hBuf);
  8104. return ERROR_NOT_ENOUGH_MEMORY;
  8105. }
  8106. while (TRUE) {
  8107. cbValueName=ARRAYSIZE(szValueName);
  8108. cbValueData=ARRAYSIZE(szValueData) * sizeof(TCHAR);
  8109. if (m_pcd->m_bRSOP)
  8110. {
  8111. uRet = m_pcd->EnumRSOPRegistryValues(hkeyRoot, pszCurrentKeyName,
  8112. szValueName, cbValueName,
  8113. &lpItem);
  8114. if (uRet == ERROR_SUCCESS)
  8115. {
  8116. //
  8117. // Check if the GPO name is changing
  8118. //
  8119. bMultiple = FALSE;
  8120. if (lpGPOName && *lpGPOName && lpItem->lpGPOName && (hkeyRoot == 0))
  8121. {
  8122. if (lstrcmpi(*lpGPOName, lpItem->lpGPOName))
  8123. {
  8124. bMultiple = TRUE;
  8125. }
  8126. }
  8127. uRet = m_pcd->ReadRSOPRegistryValue(hkeyRoot, pszCurrentKeyName,
  8128. szValueName, (LPBYTE)szValueData,
  8129. cbValueData, &dwType, lpGPOName,
  8130. lpItem);
  8131. if (bMultiple)
  8132. {
  8133. *lpGPOName = m_pMultipleGPOs;
  8134. }
  8135. }
  8136. }
  8137. else
  8138. {
  8139. uRet=RegEnumValue(hKey,nIndex,szValueName,&cbValueName,NULL,
  8140. &dwType,(LPBYTE)szValueData,&cbValueData);
  8141. }
  8142. // stop if we're out of items
  8143. if (uRet != ERROR_SUCCESS && uRet != ERROR_MORE_DATA)
  8144. break;
  8145. nIndex++;
  8146. if (szValueName[0] == TEXT('\0')) {
  8147. // if the value is empty, it is the key creation code
  8148. continue;
  8149. }
  8150. // if valuename prefixed with '**', it's a control code, ignore it
  8151. if (szValueName[0] == TEXT('*') && szValueName[1] == TEXT('*')) {
  8152. // if we found **delvals., then some sort of listbox stuff
  8153. // is going on, remember that we found this code
  8154. if (!lstrcmpi(szValueName,szDELVALS))
  8155. fFoundDelvals = TRUE;
  8156. continue;
  8157. }
  8158. // only process this item if enum was successful
  8159. // (so we'll skip items with weird errors like ERROR_MORE_DATA and
  8160. // but keep going with the enum)
  8161. if (uRet == ERROR_SUCCESS) {
  8162. TCHAR * pszData;
  8163. // if there's no value name prefix scheme specified (e.g.
  8164. // value names are "foo1", "foo2", etc), and the explicit valuename
  8165. // flag isn't set where we remember the value name as well as
  8166. // the data for every value, then we need the value name to
  8167. // be the same as the value data ("thing.exe=thing.exe").
  8168. if (!(pSettings->dwFlags & DF_EXPLICITVALNAME) &&
  8169. !(pListboxInfo->uOffsetPrefix) && !(pListboxInfo->uOffsetValue)) {
  8170. if (dwType != (DWORD)((pSettings->dwFlags & DF_EXPANDABLETEXT) ? REG_EXPAND_SZ : REG_SZ) ||
  8171. lstrcmpi(szValueName,szValueData))
  8172. continue; // skip this value if val name != val data
  8173. }
  8174. //
  8175. // If there is a valueprefix, only pick up values that start
  8176. // with that prefix
  8177. //
  8178. if (pListboxInfo->uOffsetPrefix) {
  8179. LPTSTR lpPrefix = (LPTSTR)((LPBYTE)pTableEntry + pListboxInfo->uOffsetPrefix);
  8180. INT iPrefixLen = lstrlen(lpPrefix);
  8181. if (CompareString(LOCALE_USER_DEFAULT, NORM_IGNORECASE | NORM_STOP_ON_NULL,
  8182. lpPrefix, iPrefixLen, szValueName,
  8183. iPrefixLen) != CSTR_EQUAL) {
  8184. continue;
  8185. }
  8186. }
  8187. // if explicit valuenames used, then copy the value name into
  8188. // buffer
  8189. if (pSettings->dwFlags & DF_EXPLICITVALNAME) {
  8190. nLen = lstrlen(szValueName) + 1;
  8191. if (!(pBuf=ResizeBuffer(pBuf,hBuf,(dwUsed+nLen+4) * sizeof(TCHAR),&dwAlloc)))
  8192. return ERROR_NOT_ENOUGH_MEMORY;
  8193. lstrcpy(pBuf+dwUsed,szValueName);
  8194. dwUsed += nLen;
  8195. }
  8196. // for default listbox type, value data is the actual "data"
  8197. // and value name either will be the same as the data or
  8198. // some prefix + "1", "2", etc. If there's a data value to
  8199. // write for each entry, then the "data" is the value name
  8200. // (e.g. "Larry = foo", "Dave = foo"), etc. If explicit value names
  8201. // are turned on, then both the value name and data are stored
  8202. // and editable
  8203. // copy value data into buffer
  8204. if (pListboxInfo->uOffsetValue) {
  8205. // data value set, use value name for data
  8206. pszData = szValueName;
  8207. } else pszData = szValueData;
  8208. nLen = lstrlen(pszData) + 1;
  8209. if (!(pBuf=ResizeBuffer(pBuf,hBuf,(dwUsed+nLen+4) * sizeof(TCHAR),&dwAlloc)))
  8210. return ERROR_NOT_ENOUGH_MEMORY;
  8211. lstrcpy(pBuf+dwUsed,pszData);
  8212. dwUsed += nLen;
  8213. fFoundValues=TRUE;
  8214. //
  8215. // Add the GPO name if this is RSOP mode
  8216. //
  8217. if (m_pcd->m_bRSOP)
  8218. {
  8219. nLen = lstrlen(lpItem->lpGPOName) + 1;
  8220. if (!(pBuf=ResizeBuffer(pBuf,hBuf,(dwUsed+nLen+4) * sizeof(TCHAR),&dwAlloc)))
  8221. return ERROR_NOT_ENOUGH_MEMORY;
  8222. lstrcpy(pBuf+dwUsed,lpItem->lpGPOName);
  8223. dwUsed += nLen;
  8224. }
  8225. }
  8226. }
  8227. // doubly null-terminate the buffer... safe to do this because we
  8228. // tacked on the extra "+4" in the ResizeBuffer calls above
  8229. *(pBuf+dwUsed) = TEXT('\0');
  8230. dwUsed++;
  8231. uRet = ERROR_SUCCESS;
  8232. if (fFoundValues) {
  8233. // set flag that we found setting in registry/policy file
  8234. if (pdwFound)
  8235. *pdwFound |= FS_PRESENT;
  8236. } else {
  8237. if (fFoundDelvals && pdwFound) {
  8238. *pdwFound |= FS_DELETED;
  8239. }
  8240. }
  8241. GlobalUnlock(hBuf);
  8242. if ((uRet == ERROR_SUCCESS) && phGlobal)
  8243. {
  8244. *phGlobal = hBuf;
  8245. }
  8246. else
  8247. {
  8248. GlobalFree(hBuf);
  8249. }
  8250. if (!m_pcd->m_bRSOP)
  8251. {
  8252. RegCloseKey(hKey);
  8253. }
  8254. return uRet;
  8255. }
  8256. BOOL CPolicySnapIn::ReadCustomValue(HKEY hkeyRoot,TCHAR * pszKeyName,TCHAR * pszValueName,
  8257. TCHAR * pszValue,UINT cbValue,DWORD * pdwValue,DWORD * pdwFlags,LPTSTR *lpGPOName)
  8258. {
  8259. HKEY hKey;
  8260. DWORD dwType,dwSize=cbValue * sizeof(TCHAR);
  8261. BOOL fSuccess = FALSE;
  8262. TCHAR szNewValueName[MAX_PATH+1];
  8263. *pdwValue=0;
  8264. *pszValue = TEXT('\0');
  8265. if (m_pcd->m_bRSOP)
  8266. {
  8267. if (m_pcd->ReadRSOPRegistryValue(hkeyRoot, pszKeyName, pszValueName, (LPBYTE)pszValue,
  8268. dwSize, &dwType, lpGPOName, NULL) == ERROR_SUCCESS)
  8269. {
  8270. if (dwType == REG_SZ)
  8271. {
  8272. // value returned in pszValueName
  8273. *pdwFlags = 0;
  8274. fSuccess = TRUE;
  8275. }
  8276. else if (dwType == REG_DWORD || dwType == REG_BINARY)
  8277. {
  8278. // copy value to *pdwValue
  8279. memcpy(pdwValue,pszValue,sizeof(DWORD));
  8280. *pdwFlags = VF_ISNUMERIC;
  8281. fSuccess = TRUE;
  8282. }
  8283. }
  8284. else
  8285. {
  8286. // see if this is a value that's marked for deletion
  8287. // (valuename is prepended with "**del."
  8288. PrependValueName(pszValueName,VF_DELETE,
  8289. szNewValueName,ARRAYSIZE(szNewValueName));
  8290. if (m_pcd->ReadRSOPRegistryValue(hkeyRoot, pszKeyName, szNewValueName, (LPBYTE)pszValue,
  8291. dwSize, &dwType, lpGPOName, NULL) == ERROR_SUCCESS)
  8292. {
  8293. fSuccess=TRUE;
  8294. *pdwFlags = VF_DELETE;
  8295. }
  8296. else
  8297. {
  8298. // see if this is a soft value
  8299. // (valuename is prepended with "**soft."
  8300. PrependValueName(pszValueName,VF_SOFT,
  8301. szNewValueName,ARRAYSIZE(szNewValueName));
  8302. if (m_pcd->ReadRSOPRegistryValue(hkeyRoot, pszKeyName, szNewValueName, (LPBYTE)pszValue,
  8303. dwSize, &dwType, lpGPOName, NULL) == ERROR_SUCCESS)
  8304. {
  8305. fSuccess=TRUE;
  8306. *pdwFlags = VF_SOFT;
  8307. }
  8308. }
  8309. }
  8310. }
  8311. else
  8312. {
  8313. if (RegOpenKeyEx(hkeyRoot,pszKeyName,0,KEY_READ,&hKey) == ERROR_SUCCESS) {
  8314. if (RegQueryValueEx(hKey,pszValueName,NULL,&dwType,(LPBYTE) pszValue,
  8315. &dwSize) == ERROR_SUCCESS) {
  8316. if (dwType == REG_SZ) {
  8317. // value returned in pszValueName
  8318. *pdwFlags = 0;
  8319. fSuccess = TRUE;
  8320. } else if (dwType == REG_DWORD || dwType == REG_BINARY) {
  8321. // copy value to *pdwValue
  8322. memcpy(pdwValue,pszValue,sizeof(DWORD));
  8323. *pdwFlags = VF_ISNUMERIC;
  8324. fSuccess = TRUE;
  8325. }
  8326. } else {
  8327. // see if this is a value that's marked for deletion
  8328. // (valuename is prepended with "**del."
  8329. PrependValueName(pszValueName,VF_DELETE,
  8330. szNewValueName,ARRAYSIZE(szNewValueName));
  8331. if (RegQueryValueEx(hKey,szNewValueName,NULL,&dwType,(LPBYTE) pszValue,
  8332. &dwSize) == ERROR_SUCCESS) {
  8333. fSuccess=TRUE;
  8334. *pdwFlags = VF_DELETE;
  8335. } else {
  8336. // see if this is a soft value
  8337. // (valuename is prepended with "**soft."
  8338. PrependValueName(pszValueName,VF_SOFT,
  8339. szNewValueName,ARRAYSIZE(szNewValueName));
  8340. if (RegQueryValueEx(hKey,szNewValueName,NULL,&dwType,(LPBYTE) pszValue,
  8341. &dwSize) == ERROR_SUCCESS) {
  8342. fSuccess=TRUE;
  8343. *pdwFlags = VF_SOFT;
  8344. }
  8345. }
  8346. }
  8347. RegCloseKey(hKey);
  8348. }
  8349. }
  8350. return fSuccess;
  8351. }
  8352. BOOL CPolicySnapIn::CompareCustomValue(HKEY hkeyRoot,TCHAR * pszKeyName,TCHAR * pszValueName,
  8353. STATEVALUE * pStateValue,DWORD * pdwFound, LPTSTR *lpGPOName)
  8354. {
  8355. TCHAR szValue[MAXSTRLEN];
  8356. DWORD dwValue;
  8357. TCHAR szNewValueName[MAX_PATH+1];
  8358. // add prefixes if appropriate
  8359. PrependValueName(pszValueName,pStateValue->dwFlags,
  8360. szNewValueName,ARRAYSIZE(szNewValueName));
  8361. if (pStateValue->dwFlags & VF_ISNUMERIC) {
  8362. if ((ReadRegistryDWordValue(hkeyRoot,pszKeyName,
  8363. szNewValueName,&dwValue,lpGPOName) == ERROR_SUCCESS) &&
  8364. dwValue == pStateValue->dwValue) {
  8365. *pdwFound = FS_PRESENT;
  8366. return TRUE;
  8367. }
  8368. } else if (pStateValue->dwFlags & VF_DELETE) {
  8369. // see if this is a value that's marked for deletion
  8370. // (valuename is prepended with "**del."
  8371. if ((ReadRegistryStringValue(hkeyRoot,pszKeyName,
  8372. szNewValueName,szValue,ARRAYSIZE(szValue),lpGPOName)) == ERROR_SUCCESS) {
  8373. *pdwFound = FS_DELETED;
  8374. return TRUE;
  8375. }
  8376. } else {
  8377. if ((ReadRegistryStringValue(hkeyRoot,pszKeyName,
  8378. szNewValueName,szValue,ARRAYSIZE(szValue),lpGPOName)) == ERROR_SUCCESS &&
  8379. !lstrcmpi(szValue,pStateValue->szValue)) {
  8380. *pdwFound = FS_PRESENT;
  8381. return TRUE;
  8382. }
  8383. }
  8384. return FALSE;
  8385. }
  8386. BOOL CPolicySnapIn::ReadStandardValue(HKEY hkeyRoot,TCHAR * pszKeyName,TCHAR * pszValueName,
  8387. TABLEENTRY * pTableEntry,DWORD * pdwData,DWORD * pdwFound, LPTSTR *lpGPOName)
  8388. {
  8389. UINT uRet;
  8390. TCHAR szNewValueName[MAX_PATH+1];
  8391. // add prefixes if appropriate
  8392. PrependValueName(pszValueName,((SETTINGS *) pTableEntry)->dwFlags,
  8393. szNewValueName,ARRAYSIZE(szNewValueName));
  8394. if ( ((SETTINGS *) pTableEntry)->dwFlags & DF_TXTCONVERT) {
  8395. // read numeric value as text if specified
  8396. TCHAR szNum[11];
  8397. uRet = ReadRegistryStringValue(hkeyRoot,pszKeyName,
  8398. szNewValueName,szNum,ARRAYSIZE(szNum),lpGPOName);
  8399. if (uRet == ERROR_SUCCESS) {
  8400. StringToNum(szNum, (UINT *)pdwData);
  8401. *pdwFound = FS_PRESENT;
  8402. return TRUE;
  8403. }
  8404. } else {
  8405. // read numeric value as binary
  8406. uRet = ReadRegistryDWordValue(hkeyRoot,pszKeyName,
  8407. szNewValueName,pdwData, lpGPOName);
  8408. if (uRet == ERROR_SUCCESS) {
  8409. *pdwFound = FS_PRESENT;
  8410. return TRUE;
  8411. }
  8412. }
  8413. // see if this settings has been marked as 'deleted'
  8414. TCHAR szVal[MAX_PATH+1];
  8415. *pdwData = 0;
  8416. PrependValueName(pszValueName,VF_DELETE,szNewValueName,
  8417. ARRAYSIZE(szNewValueName));
  8418. uRet=ReadRegistryStringValue(hkeyRoot,pszKeyName,
  8419. szNewValueName,szVal,ARRAYSIZE(szVal),lpGPOName);
  8420. if (uRet == ERROR_SUCCESS) {
  8421. *pdwFound = FS_DELETED;
  8422. return TRUE;
  8423. }
  8424. return FALSE;
  8425. }
  8426. // adds the special prefixes "**del." and "**soft." if writing to a policy file,
  8427. // and VF_DELETE/VF_SOFT flags are set
  8428. VOID CPolicySnapIn::PrependValueName(TCHAR * pszValueName,DWORD dwFlags,TCHAR * pszNewValueName,
  8429. UINT cbNewValueName)
  8430. {
  8431. UINT nValueNameLen = lstrlen(pszValueName);
  8432. lstrcpy(pszNewValueName, g_szNull);
  8433. if (cbNewValueName < nValueNameLen) // check length of buffer, just in case
  8434. return;
  8435. // prepend special prefixes for "delete" or "soft" values
  8436. if ((dwFlags & VF_DELETE) && (cbNewValueName > nValueNameLen +
  8437. ARRAYSIZE(szDELETEPREFIX))) {
  8438. lstrcpy(pszNewValueName,szDELETEPREFIX);
  8439. } else if ((dwFlags & VF_SOFT) && (cbNewValueName > nValueNameLen +
  8440. ARRAYSIZE(szSOFTPREFIX))) {
  8441. lstrcpy(pszNewValueName,szSOFTPREFIX);
  8442. }
  8443. lstrcat(pszNewValueName,pszValueName);
  8444. }
  8445. UINT CPolicySnapIn::WriteRegistryDWordValue(HKEY hkeyRoot,TCHAR * pszKeyName,TCHAR * pszValueName,
  8446. DWORD dwValue)
  8447. {
  8448. HKEY hKey;
  8449. UINT uRet;
  8450. if (!pszKeyName || !pszValueName)
  8451. return ERROR_INVALID_PARAMETER;
  8452. // create the key with appropriate name
  8453. if ( (uRet = RegCreateKey(hkeyRoot,pszKeyName,&hKey))
  8454. != ERROR_SUCCESS)
  8455. return uRet;
  8456. uRet = RegSetValueEx(hKey,pszValueName,0,REG_DWORD,
  8457. (LPBYTE) &dwValue,sizeof(dwValue));
  8458. RegCloseKey(hKey);
  8459. return uRet;
  8460. }
  8461. UINT CPolicySnapIn::ReadRegistryDWordValue(HKEY hkeyRoot,TCHAR * pszKeyName,TCHAR * pszValueName,
  8462. DWORD * pdwValue, LPTSTR *lpGPOName)
  8463. {
  8464. HKEY hKey;
  8465. UINT uRet;
  8466. DWORD dwType,dwSize = sizeof(DWORD);
  8467. if (!pszKeyName || !pszValueName)
  8468. return ERROR_INVALID_PARAMETER;
  8469. *pdwValue = 0;
  8470. if (m_pcd->m_bRSOP)
  8471. {
  8472. uRet = m_pcd->ReadRSOPRegistryValue(hkeyRoot, pszKeyName, pszValueName, (LPBYTE) pdwValue, 4,
  8473. &dwType, lpGPOName, NULL);
  8474. }
  8475. else
  8476. {
  8477. // open appropriate key
  8478. if ( (uRet = RegOpenKeyEx(hkeyRoot,pszKeyName,0,KEY_READ,&hKey))
  8479. != ERROR_SUCCESS)
  8480. return uRet;
  8481. uRet = RegQueryValueEx(hKey,pszValueName,0,&dwType,
  8482. (LPBYTE) pdwValue,&dwSize);
  8483. RegCloseKey(hKey);
  8484. }
  8485. return uRet;
  8486. }
  8487. UINT CPolicySnapIn::WriteRegistryStringValue(HKEY hkeyRoot,TCHAR * pszKeyName,TCHAR * pszValueName,
  8488. TCHAR * pszValue, BOOL bExpandable)
  8489. {
  8490. HKEY hKey;
  8491. UINT uRet;
  8492. if (!pszKeyName || !pszValueName)
  8493. return ERROR_INVALID_PARAMETER;
  8494. // create the key with appropriate name
  8495. if ( (uRet = RegCreateKey(hkeyRoot,pszKeyName,&hKey))
  8496. != ERROR_SUCCESS)
  8497. return uRet;
  8498. uRet = RegSetValueEx(hKey,pszValueName,0,
  8499. bExpandable ? REG_EXPAND_SZ : REG_SZ,
  8500. (LPBYTE) pszValue,(lstrlen(pszValue)+1) * sizeof(TCHAR));
  8501. RegCloseKey(hKey);
  8502. return uRet;
  8503. }
  8504. UINT CPolicySnapIn::ReadRegistryStringValue(HKEY hkeyRoot,TCHAR * pszKeyName,TCHAR * pszValueName,
  8505. TCHAR * pszValue,UINT cbValue, LPTSTR *lpGPOName)
  8506. {
  8507. HKEY hKey;
  8508. UINT uRet;
  8509. DWORD dwType;
  8510. DWORD dwSize = cbValue * sizeof(TCHAR);
  8511. if (!pszKeyName || !pszValueName)
  8512. return ERROR_INVALID_PARAMETER;
  8513. if (m_pcd->m_bRSOP)
  8514. {
  8515. uRet = m_pcd->ReadRSOPRegistryValue(hkeyRoot, pszKeyName, pszValueName, (LPBYTE) pszValue,
  8516. dwSize, &dwType, lpGPOName, NULL);
  8517. }
  8518. else
  8519. {
  8520. // create the key with appropriate name
  8521. if ( (uRet = RegOpenKeyEx(hkeyRoot,pszKeyName,0,KEY_READ,&hKey))
  8522. != ERROR_SUCCESS)
  8523. return uRet;
  8524. uRet = RegQueryValueEx(hKey,pszValueName,0,&dwType,
  8525. (LPBYTE) pszValue,&dwSize);
  8526. RegCloseKey(hKey);
  8527. }
  8528. return uRet;
  8529. }
  8530. UINT CPolicySnapIn::DeleteRegistryValue(HKEY hkeyRoot,TCHAR * pszKeyName,TCHAR * pszValueName)
  8531. {
  8532. HKEY hKey;
  8533. UINT uRet;
  8534. if (!pszKeyName || !pszValueName)
  8535. return ERROR_INVALID_PARAMETER;
  8536. // create the key with appropriate name
  8537. if ( (uRet = RegOpenKeyEx(hkeyRoot,pszKeyName,0,KEY_WRITE,&hKey))
  8538. != ERROR_SUCCESS)
  8539. return uRet;
  8540. uRet = RegDeleteValue(hKey,pszValueName);
  8541. RegCloseKey(hKey);
  8542. return uRet;
  8543. }
  8544. UINT CPolicySnapIn::WriteCustomValue_W(HKEY hkeyRoot,TCHAR * pszKeyName,TCHAR * pszValueName,
  8545. TCHAR * pszValue,DWORD dwValue,DWORD dwFlags,BOOL fErase)
  8546. {
  8547. UINT uRet=ERROR_SUCCESS;
  8548. TCHAR szNewValueName[MAX_PATH+1];
  8549. // first: "clean house" by deleting both the specified value name,
  8550. // and the value name with the delete (**del.) prefix.
  8551. // Then write the appropriate version back out if need be
  8552. PrependValueName(pszValueName,VF_DELETE,szNewValueName,
  8553. ARRAYSIZE(szNewValueName));
  8554. DeleteRegistryValue(hkeyRoot,pszKeyName,szNewValueName);
  8555. // add prefixes if appropriate
  8556. PrependValueName(pszValueName,(dwFlags & ~VF_DELETE),szNewValueName,
  8557. ARRAYSIZE(szNewValueName));
  8558. DeleteRegistryValue(hkeyRoot,pszKeyName,szNewValueName);
  8559. if (fErase) {
  8560. // just need to delete value, done above
  8561. uRet = ERROR_SUCCESS;
  8562. RegCleanUpValue (hkeyRoot, pszKeyName, pszValueName);
  8563. } else if (dwFlags & VF_DELETE) {
  8564. // need to delete value (done above) and mark as deleted if writing
  8565. // to policy file
  8566. uRet = ERROR_SUCCESS;
  8567. PrependValueName(pszValueName,VF_DELETE,szNewValueName,
  8568. ARRAYSIZE(szNewValueName));
  8569. uRet=WriteRegistryStringValue(hkeyRoot,pszKeyName,
  8570. szNewValueName, (TCHAR *)szNOVALUE, FALSE);
  8571. } else {
  8572. if (dwFlags & VF_ISNUMERIC) {
  8573. uRet=WriteRegistryDWordValue(hkeyRoot,pszKeyName,
  8574. szNewValueName,dwValue);
  8575. } else {
  8576. uRet = WriteRegistryStringValue(hkeyRoot,pszKeyName,
  8577. szNewValueName,pszValue,
  8578. (dwFlags & DF_EXPANDABLETEXT) ? TRUE : FALSE);
  8579. }
  8580. }
  8581. return uRet;
  8582. }
  8583. UINT CPolicySnapIn::WriteCustomValue(HKEY hkeyRoot,TCHAR * pszKeyName,TCHAR * pszValueName,
  8584. STATEVALUE * pStateValue,BOOL fErase)
  8585. {
  8586. // pull info out of STATEVALUE struct and call worker function
  8587. return WriteCustomValue_W(hkeyRoot,pszKeyName,pszValueName,
  8588. pStateValue->szValue,pStateValue->dwValue,pStateValue->dwFlags,
  8589. fErase);
  8590. }
  8591. // writes a numeric value given root key, key name and value name. The specified
  8592. // value is removed if fErase is TRUE. Normally if the data (dwData) is zero
  8593. // the value will be deleted, but if fWriteZero is TRUE then the value will
  8594. // be written as zero if the data is zero.
  8595. UINT CPolicySnapIn::WriteStandardValue(HKEY hkeyRoot,TCHAR * pszKeyName,TCHAR * pszValueName,
  8596. TABLEENTRY * pTableEntry,DWORD dwData,BOOL fErase,BOOL fWriteZero)
  8597. {
  8598. UINT uRet=ERROR_SUCCESS;
  8599. TCHAR szNewValueName[MAX_PATH+1];
  8600. // first: "clean house" by deleting both the specified value name,
  8601. // and the value name with the delete (**del.) prefix (if writing to policy
  8602. // file). Then write the appropriate version back out if need be
  8603. PrependValueName(pszValueName,VF_DELETE,szNewValueName,
  8604. ARRAYSIZE(szNewValueName));
  8605. DeleteRegistryValue(hkeyRoot,pszKeyName,szNewValueName);
  8606. DeleteRegistryValue(hkeyRoot,pszKeyName,pszValueName);
  8607. if (fErase) {
  8608. // just need to delete value, done above
  8609. uRet = ERROR_SUCCESS;
  8610. RegCleanUpValue (hkeyRoot, pszKeyName, pszValueName);
  8611. } else if ( ((SETTINGS *) pTableEntry)->dwFlags & DF_TXTCONVERT) {
  8612. // if specified, save value as text
  8613. TCHAR szNum[11];
  8614. wsprintf(szNum,TEXT("%lu"),dwData);
  8615. if (!dwData && !fWriteZero) {
  8616. // if value is 0, delete the value (done above), and mark
  8617. // it as deleted if writing to policy file
  8618. PrependValueName(pszValueName,VF_DELETE,szNewValueName,
  8619. ARRAYSIZE(szNewValueName));
  8620. uRet=WriteRegistryStringValue(hkeyRoot,pszKeyName,
  8621. szNewValueName,(TCHAR *)szNOVALUE, FALSE);
  8622. } else {
  8623. PrependValueName(pszValueName,((SETTINGS *)pTableEntry)->dwFlags,
  8624. szNewValueName,ARRAYSIZE(szNewValueName));
  8625. uRet = WriteRegistryStringValue(hkeyRoot,pszKeyName,
  8626. szNewValueName,szNum, FALSE);
  8627. }
  8628. } else {
  8629. if (!dwData && !fWriteZero) {
  8630. // if value is 0, delete the value (done above), and mark
  8631. // it as deleted if writing to policy file
  8632. PrependValueName(pszValueName,VF_DELETE,szNewValueName,
  8633. ARRAYSIZE(szNewValueName));
  8634. uRet=WriteRegistryStringValue(hkeyRoot,pszKeyName,
  8635. szNewValueName,(TCHAR *)szNOVALUE, FALSE);
  8636. } else {
  8637. // save value as binary
  8638. PrependValueName(pszValueName,((SETTINGS *)pTableEntry)->dwFlags,
  8639. szNewValueName,ARRAYSIZE(szNewValueName));
  8640. uRet=WriteRegistryDWordValue(hkeyRoot,pszKeyName,
  8641. szNewValueName,dwData);
  8642. }
  8643. }
  8644. return uRet;
  8645. }
  8646. TCHAR * CPolicySnapIn::ResizeBuffer(TCHAR * pBuf,HGLOBAL hBuf,DWORD dwNeeded,DWORD * pdwCurSize)
  8647. {
  8648. TCHAR * pNew;
  8649. if (dwNeeded <= *pdwCurSize) return pBuf; // nothing to do
  8650. *pdwCurSize = dwNeeded;
  8651. GlobalUnlock(hBuf);
  8652. if (!GlobalReAlloc(hBuf,dwNeeded,GHND))
  8653. return NULL;
  8654. if (!(pNew = (TCHAR *) GlobalLock(hBuf))) return NULL;
  8655. return pNew;
  8656. }
  8657. /*******************************************************************
  8658. NAME: MessageWndProc
  8659. SYNOPSIS: Window proc for GPMessageWndProc window
  8660. ********************************************************************/
  8661. LRESULT CALLBACK CPolicySnapIn::MessageWndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)
  8662. {
  8663. switch (message)
  8664. {
  8665. case WM_CREATE:
  8666. SetWindowLongPtr (hWnd, GWLP_USERDATA, (LONG_PTR)((CREATESTRUCT *) lParam)->lpCreateParams);
  8667. break;
  8668. case WM_MOVEFOCUS:
  8669. {
  8670. CPolicySnapIn * pPS;
  8671. pPS = (CPolicySnapIn *) GetWindowLongPtr (hWnd, GWLP_USERDATA);
  8672. if (pPS)
  8673. {
  8674. pPS->MoveFocusWorker ((BOOL)wParam);
  8675. }
  8676. }
  8677. break;
  8678. case WM_UPDATEITEM:
  8679. {
  8680. CPolicySnapIn * pPS;
  8681. pPS = (CPolicySnapIn *) GetWindowLongPtr (hWnd, GWLP_USERDATA);
  8682. if (pPS)
  8683. {
  8684. pPS->UpdateItemWorker ();
  8685. }
  8686. }
  8687. break;
  8688. case WM_SETPREVNEXT:
  8689. {
  8690. CPolicySnapIn * pPS;
  8691. pPS = (CPolicySnapIn *) GetWindowLongPtr (hWnd, GWLP_USERDATA);
  8692. if (pPS)
  8693. {
  8694. pPS->SetPrevNextButtonStateWorker ((HWND) wParam);
  8695. }
  8696. }
  8697. break;
  8698. default:
  8699. {
  8700. CPolicySnapIn * pPS;
  8701. pPS = (CPolicySnapIn *) GetWindowLongPtr (hWnd, GWLP_USERDATA);
  8702. if (pPS)
  8703. {
  8704. if (message == pPS->m_uiRefreshMsg)
  8705. {
  8706. if ((DWORD) lParam == GetCurrentProcessId())
  8707. {
  8708. if (!pPS->m_hPropDlg)
  8709. {
  8710. pPS->m_pcd->m_pScope->DeleteItem (pPS->m_pcd->m_hSWPolicies, FALSE);
  8711. pPS->m_pcd->LoadTemplates();
  8712. pPS->m_pcd->EnumerateScopePane (NULL, pPS->m_pcd->m_hSWPolicies);
  8713. }
  8714. }
  8715. }
  8716. }
  8717. return (DefWindowProc(hWnd, message, wParam, lParam));
  8718. }
  8719. }
  8720. return (0);
  8721. }
  8722. /*******************************************************************
  8723. NAME: ClipWndProc
  8724. SYNOPSIS: Window proc for ClipClass window
  8725. ********************************************************************/
  8726. LRESULT CALLBACK CPolicySnapIn::ClipWndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)
  8727. {
  8728. switch (message) {
  8729. case WM_CREATE:
  8730. if (!((CREATESTRUCT *) lParam)->lpCreateParams) {
  8731. // this is the clip window in the dialog box.
  8732. SetScrollRange(hWnd,SB_VERT,0,0,TRUE);
  8733. SetScrollRange(hWnd,SB_HORZ,0,0,TRUE);
  8734. } else {
  8735. // this is the container window
  8736. // store away the dialog box HWND (the grandparent of this
  8737. // window) because the pointer to instance data we need lives
  8738. // in the dialog's window data
  8739. SetWindowLong(hWnd,0,WT_SETTINGS);
  8740. }
  8741. break;
  8742. case WM_USER:
  8743. {
  8744. HWND hwndParent = GetParent(hWnd);
  8745. LPSETTINGSINFO lpSettingsInfo;
  8746. POLICYDLGINFO * pdi;
  8747. lpSettingsInfo = (LPSETTINGSINFO) GetWindowLongPtr(hwndParent, DWLP_USER);
  8748. if (!lpSettingsInfo)
  8749. return FALSE;
  8750. pdi = lpSettingsInfo->pdi;
  8751. if (!pdi)
  8752. return FALSE;
  8753. if (!lpSettingsInfo->hFontDlg)
  8754. lpSettingsInfo->hFontDlg = (HFONT) SendMessage(GetParent(hWnd),WM_GETFONT,0,0L);
  8755. // make a container window that is clipped by this windows
  8756. if (!(pdi->hwndSettings=CreateWindow(TEXT("ClipClass"),(TCHAR *) g_szNull,
  8757. WS_CHILD | WS_VISIBLE,0,0,400,400,hWnd,NULL,g_hInstance,
  8758. (LPVOID) hWnd)))
  8759. return FALSE;
  8760. SetWindowLong(hWnd,0,WT_CLIP);
  8761. return TRUE;
  8762. }
  8763. break;
  8764. case WM_VSCROLL:
  8765. case WM_HSCROLL:
  8766. if (GetWindowLong(hWnd,0) == WT_CLIP)
  8767. {
  8768. LPSETTINGSINFO lpSettingsInfo;
  8769. lpSettingsInfo = (LPSETTINGSINFO) GetWindowLongPtr(GetParent(hWnd), DWLP_USER);
  8770. if (!lpSettingsInfo)
  8771. return FALSE;
  8772. lpSettingsInfo->pCS->ProcessScrollBar(hWnd,wParam,
  8773. (message == WM_VSCROLL) ? TRUE : FALSE);
  8774. }
  8775. else goto defproc;
  8776. return 0;
  8777. case WM_COMMAND:
  8778. if (GetWindowLong(hWnd,0) == WT_SETTINGS) {
  8779. LPSETTINGSINFO lpSettingsInfo;
  8780. lpSettingsInfo = (LPSETTINGSINFO) GetWindowLongPtr(GetParent(GetParent(hWnd)), DWLP_USER);
  8781. if (!lpSettingsInfo)
  8782. break;
  8783. lpSettingsInfo->pCS->ProcessCommand(hWnd,wParam,(HWND) lParam, lpSettingsInfo->pdi);
  8784. }
  8785. break;
  8786. case WM_GETDLGCODE:
  8787. if (GetWindowLong(hWnd,0) == WT_CLIP) {
  8788. SetWindowLongPtr(GetParent(hWnd),DWLP_MSGRESULT,DLGC_WANTTAB |
  8789. DLGC_WANTALLKEYS);
  8790. return DLGC_WANTTAB | DLGC_WANTALLKEYS;
  8791. }
  8792. break;
  8793. case WM_SETFOCUS:
  8794. // if clip window gains keyboard focus, transfer focus to first
  8795. // control owned by settings window
  8796. if (GetWindowLong(hWnd,0) == WT_CLIP) {
  8797. HWND hwndParent = GetParent(hWnd);
  8798. POLICYDLGINFO * pdi;
  8799. INT nIndex;
  8800. BOOL fForward=TRUE;
  8801. HWND hwndPrev = GetDlgItem(hwndParent,IDC_POLICY_PREVIOUS);
  8802. HWND hwndNext = GetDlgItem(hwndParent,IDC_POLICY_NEXT);
  8803. HWND hwndOK = GetDlgItem(GetParent(hwndParent),IDOK);
  8804. int iDelta;
  8805. LPSETTINGSINFO lpSettingsInfo;
  8806. lpSettingsInfo = (LPSETTINGSINFO) GetWindowLongPtr(GetParent(hWnd), DWLP_USER);
  8807. if (!lpSettingsInfo)
  8808. return FALSE;
  8809. pdi = lpSettingsInfo->pdi;
  8810. if (!pdi)
  8811. return FALSE;
  8812. // if Previous Policy button lost focus, then we're going backwards
  8813. // in tab order; otherwise we're going forwards
  8814. if ( (HWND) wParam == hwndPrev)
  8815. fForward = FALSE;
  8816. else if ( (HWND) wParam == hwndNext)
  8817. fForward = FALSE;
  8818. else if ( (HWND) wParam == hwndOK)
  8819. fForward = FALSE;
  8820. // find the first control that has a data index (e.g. is
  8821. // not static text) and give it focus
  8822. if (pdi->nControls) {
  8823. if (fForward) { // search from start of table forwards
  8824. nIndex = 0;
  8825. iDelta = 1;
  8826. } else { // search from end of table backwards
  8827. nIndex = pdi->nControls-1;
  8828. iDelta = -1;
  8829. }
  8830. for (;nIndex>=0 && nIndex<(int)pdi->nControls;nIndex += iDelta) {
  8831. if (pdi->pControlTable[nIndex].uDataIndex !=
  8832. NO_DATA_INDEX &&
  8833. IsWindowEnabled(pdi->pControlTable[nIndex].hwnd)) {
  8834. SetFocus(pdi->pControlTable[nIndex].hwnd);
  8835. lpSettingsInfo->pCS->EnsureSettingControlVisible(hwndParent,
  8836. pdi->pControlTable[nIndex].hwnd);
  8837. return FALSE;
  8838. }
  8839. }
  8840. }
  8841. // only get here if there are no setting windows that can
  8842. // receive keyboard focus. Give keyboard focus to the
  8843. // next guy in line. This is the "OK" button, unless we
  8844. // shift-tabbed to get here from the "OK" button in which
  8845. // case the tree window is the next guy in line
  8846. if (fForward) {
  8847. if (IsWindowEnabled (hwndPrev))
  8848. SetFocus(hwndPrev);
  8849. else if (IsWindowEnabled (hwndNext))
  8850. SetFocus(hwndNext);
  8851. else
  8852. SetFocus(hwndOK);
  8853. } else {
  8854. if (IsDlgButtonChecked (hwndParent, IDC_ENABLED) == BST_CHECKED) {
  8855. SetFocus (GetDlgItem(hwndParent,IDC_ENABLED));
  8856. } else if (IsDlgButtonChecked (hwndParent, IDC_DISABLED) == BST_CHECKED) {
  8857. SetFocus (GetDlgItem(hwndParent,IDC_DISABLED));
  8858. } else {
  8859. SetFocus (GetDlgItem(hwndParent,IDC_NOCONFIG));
  8860. }
  8861. }
  8862. return FALSE;
  8863. }
  8864. break;
  8865. default:
  8866. defproc:
  8867. return (DefWindowProc(hWnd, message, wParam, lParam));
  8868. }
  8869. return (0);
  8870. }
  8871. /*******************************************************************
  8872. NAME: ProcessCommand
  8873. SYNOPSIS: WM_COMMAND handler for ClipClass window
  8874. ********************************************************************/
  8875. VOID CPolicySnapIn::ProcessCommand(HWND hWnd,WPARAM wParam,HWND hwndCtrl, POLICYDLGINFO * pdi)
  8876. {
  8877. // get instance-specific struct from dialog
  8878. UINT uID = GetWindowLong(hwndCtrl,GWL_ID);
  8879. if ( (uID >= IDD_SETTINGCTRL) && (uID < IDD_SETTINGCTRL+pdi->nControls)) {
  8880. POLICYCTRLINFO * pPolicyCtrlInfo= &pdi->pControlTable[uID - IDD_SETTINGCTRL];
  8881. switch (pPolicyCtrlInfo->dwType) {
  8882. case STYPE_CHECKBOX:
  8883. SendMessage(hwndCtrl,BM_SETCHECK,
  8884. !(SendMessage(hwndCtrl,BM_GETCHECK,0,0)),0);
  8885. break;
  8886. case STYPE_LISTBOX:
  8887. ShowListbox(hwndCtrl,pPolicyCtrlInfo->pSetting);
  8888. break;
  8889. default:
  8890. // nothing to do
  8891. break;
  8892. }
  8893. if ((HIWORD(wParam) == BN_CLICKED) ||
  8894. (HIWORD(wParam) == EN_CHANGE) ||
  8895. (HIWORD(wParam) == CBN_SELCHANGE) ||
  8896. (HIWORD(wParam) == CBN_EDITCHANGE))
  8897. {
  8898. PostMessage (GetParent(GetParent(hWnd)), WM_MYCHANGENOTIFY, 0, 0);
  8899. }
  8900. }
  8901. }
  8902. // scrolls the control window into view if it's not visible
  8903. VOID CPolicySnapIn::EnsureSettingControlVisible(HWND hDlg,HWND hwndCtrl)
  8904. {
  8905. // get the clip window, which owns the scroll bar
  8906. HWND hwndClip = GetDlgItem(hDlg,IDC_POLICY_SETTINGS);
  8907. POLICYDLGINFO * pdi;
  8908. UINT nPos = GetScrollPos(hwndClip,SB_VERT),ySettingWindowSize,yClipWindowSize;
  8909. UINT nExtra;
  8910. int iMin,iMax=0;
  8911. WINDOWPLACEMENT wp;
  8912. RECT rcCtrl;
  8913. LPSETTINGSINFO lpSettingsInfo;
  8914. lpSettingsInfo = (LPSETTINGSINFO) GetWindowLongPtr(hDlg, DWLP_USER);
  8915. if (!lpSettingsInfo)
  8916. return;
  8917. pdi = lpSettingsInfo->pdi;
  8918. if (!pdi)
  8919. return;
  8920. // find the scroll range
  8921. GetScrollRange(hwndClip,SB_VERT,&iMin,&iMax);
  8922. if (!iMax) // no scroll bar, nothing to do
  8923. return;
  8924. // find the y size of the settings window that contains the settings controls
  8925. // (this is clipped by the clip window in the dialog, scroll bar moves the
  8926. // setting window up and down behind the clip window)
  8927. wp.length = sizeof(wp);
  8928. if (!GetWindowPlacement(pdi->hwndSettings,&wp))
  8929. return; // unlikely to fail, but just bag out if it does rather than do something wacky
  8930. ySettingWindowSize=wp.rcNormalPosition.bottom-wp.rcNormalPosition.top;
  8931. // find y size of clip window
  8932. if (!GetWindowPlacement(hwndClip,&wp))
  8933. return; // unlikely to fail, but just bag out if it does rather than do something wacky
  8934. yClipWindowSize=wp.rcNormalPosition.bottom-wp.rcNormalPosition.top;
  8935. nExtra = ySettingWindowSize - yClipWindowSize;
  8936. // if setting window is smaller than clip window, there should be no
  8937. // scroll bar so we should never get here. Check just in case though...
  8938. if (ySettingWindowSize < yClipWindowSize)
  8939. return;
  8940. // get y position of control to be made visible
  8941. if (!GetWindowPlacement(hwndCtrl,&wp))
  8942. return;
  8943. rcCtrl = wp.rcNormalPosition;
  8944. rcCtrl.bottom = min ((int) ySettingWindowSize,rcCtrl.bottom + SC_YPAD);
  8945. rcCtrl.top = max ((int) 0,rcCtrl.top - SC_YPAD);
  8946. // if bottom of control is out of view, scroll the settings window up
  8947. if ((float) rcCtrl.bottom >
  8948. (float) (yClipWindowSize + ( (float) nPos/(float)iMax) * (ySettingWindowSize -
  8949. yClipWindowSize))) {
  8950. UINT nNewPos = (UINT)
  8951. ( ((float) (nExtra - (ySettingWindowSize - rcCtrl.bottom)) / (float) nExtra) * iMax);
  8952. SetScrollPos(hwndClip,SB_VERT,nNewPos,TRUE);
  8953. ProcessScrollBar(hwndClip,MAKELPARAM(SB_THUMBTRACK,nNewPos), TRUE);
  8954. return;
  8955. }
  8956. // if top of control is out of view, scroll the settings window down
  8957. if ((float) rcCtrl.top <
  8958. (float) ( (float) nPos/(float)iMax) * nExtra) {
  8959. UINT nNewPos = (UINT)
  8960. ( ((float) rcCtrl.top / (float) nExtra) * iMax);
  8961. SetScrollPos(hwndClip,SB_VERT,nNewPos,TRUE);
  8962. ProcessScrollBar(hwndClip,MAKELPARAM(SB_THUMBTRACK,nNewPos), TRUE);
  8963. return;
  8964. }
  8965. }
  8966. VOID CPolicySnapIn::ProcessScrollBar(HWND hWnd,WPARAM wParam,BOOL bVert)
  8967. {
  8968. UINT nPos = GetScrollPos(hWnd,bVert ? SB_VERT : SB_HORZ);
  8969. RECT rcParent,rcChild;
  8970. POLICYDLGINFO * pdi;
  8971. LPSETTINGSINFO lpSettingsInfo;
  8972. // get instance-specific struct from dialog
  8973. lpSettingsInfo = (LPSETTINGSINFO) GetWindowLongPtr(GetParent(hWnd), DWLP_USER);
  8974. if (!lpSettingsInfo)
  8975. return;
  8976. pdi = lpSettingsInfo->pdi;
  8977. if (!pdi)
  8978. return;
  8979. if (LOWORD(wParam) == SB_ENDSCROLL)
  8980. return;
  8981. switch (LOWORD(wParam)) {
  8982. case SB_THUMBPOSITION:
  8983. case SB_THUMBTRACK:
  8984. nPos = HIWORD(wParam);
  8985. break;
  8986. case SB_TOP:
  8987. nPos = 0;
  8988. break;
  8989. case SB_BOTTOM:
  8990. nPos = 100;
  8991. break;
  8992. case SB_LINEUP:
  8993. if (nPos >= 10)
  8994. nPos -= 10;
  8995. else
  8996. nPos = 0;
  8997. break;
  8998. case SB_LINEDOWN:
  8999. if (nPos <= 90)
  9000. nPos += 10;
  9001. else
  9002. nPos = 100;
  9003. break;
  9004. case SB_PAGEUP:
  9005. if (nPos >= 30)
  9006. nPos -= 30;
  9007. else
  9008. nPos = 0;
  9009. break;
  9010. case SB_PAGEDOWN:
  9011. if (nPos <= 70)
  9012. nPos += 30;
  9013. else
  9014. nPos = 100;
  9015. break;
  9016. }
  9017. SetScrollPos(hWnd,bVert ? SB_VERT : SB_HORZ,nPos,TRUE);
  9018. GetClientRect(hWnd,&rcParent);
  9019. GetClientRect(pdi->hwndSettings,&rcChild);
  9020. if (bVert)
  9021. {
  9022. SetWindowPos(pdi->hwndSettings,NULL,0,-(int) ((( (float)
  9023. (rcChild.bottom-rcChild.top)-(rcParent.bottom-rcParent.top))
  9024. /100.0) * (float) nPos),rcChild.right,rcChild.bottom,SWP_NOZORDER |
  9025. SWP_NOSIZE);
  9026. }
  9027. else
  9028. {
  9029. SetWindowPos(pdi->hwndSettings,NULL,-(int) ((( (float)
  9030. (rcChild.right-rcChild.left)-(rcParent.right-rcParent.left))
  9031. /100.0) * (float) nPos),rcChild.top, rcChild.right,rcChild.bottom,SWP_NOZORDER |
  9032. SWP_NOSIZE);
  9033. }
  9034. }
  9035. /*******************************************************************
  9036. NAME: FreeSettingsControls
  9037. SYNOPSIS: Frees all settings controls
  9038. ********************************************************************/
  9039. VOID CPolicySnapIn::FreeSettingsControls(HWND hDlg)
  9040. {
  9041. UINT nIndex;
  9042. HGLOBAL hData;
  9043. POLICYDLGINFO * pdi;
  9044. LPSETTINGSINFO lpSettingsInfo;
  9045. // get instance-specific struct from dialog
  9046. lpSettingsInfo = (LPSETTINGSINFO) GetWindowLongPtr(hDlg, DWLP_USER);
  9047. if (!lpSettingsInfo)
  9048. return;
  9049. pdi = lpSettingsInfo->pdi;
  9050. if (!pdi)
  9051. return;
  9052. for (nIndex=0;nIndex<pdi->nControls;nIndex++) {
  9053. if (pdi->pControlTable[nIndex].dwType == STYPE_LISTBOX)
  9054. {
  9055. hData = (HGLOBAL) GetWindowLongPtr (pdi->pControlTable[nIndex].hwnd,
  9056. GWLP_USERDATA);
  9057. if (hData)
  9058. {
  9059. GlobalFree (hData);
  9060. }
  9061. }
  9062. DestroyWindow(pdi->pControlTable[nIndex].hwnd);
  9063. }
  9064. pdi->pCurrentSettings = NULL;
  9065. pdi->nControls = 0;
  9066. SetScrollRange(pdi->hwndSettings,SB_VERT,0,0,TRUE);
  9067. SetScrollRange(pdi->hwndSettings,SB_HORZ,0,0,TRUE);
  9068. }
  9069. /*******************************************************************
  9070. NAME: CreateSettingsControls
  9071. SYNOPSIS: Creates controls in settings window
  9072. NOTES: Looks at a table of SETTINGS structs to determine
  9073. type of control to create and type-specific information.
  9074. For some types, more than one control can be created
  9075. (for instance, edit fields get a static control with
  9076. the title followed by an edit field control).
  9077. ENTRY: hDlg - owner dialog
  9078. hTable - table of SETTINGS structs containing setting
  9079. control information
  9080. ********************************************************************/
  9081. BOOL CPolicySnapIn::CreateSettingsControls(HWND hDlg,SETTINGS * pSetting,BOOL fEnable)
  9082. {
  9083. LPBYTE pObjectData;
  9084. POLICYDLGINFO * pdi;
  9085. UINT xMax=0,yStart=SC_YSPACING,nHeight,nWidth,yMax,xWindowMax;
  9086. HWND hwndControl,hwndBuddy,hwndParent;
  9087. RECT rcParent;
  9088. DWORD dwType, dwStyle;
  9089. UINT uEnable = (fEnable ? 0 : WS_DISABLED);
  9090. WINDOWPLACEMENT wp;
  9091. LPSETTINGSINFO lpSettingsInfo;
  9092. // get instance-specific struct from dialog
  9093. lpSettingsInfo = (LPSETTINGSINFO) GetWindowLongPtr(hDlg, DWLP_USER);
  9094. if (!lpSettingsInfo)
  9095. return FALSE;
  9096. pdi = lpSettingsInfo->pdi;
  9097. if (!pdi)
  9098. return FALSE;
  9099. wp.length = sizeof(wp);
  9100. if (!GetWindowPlacement(GetDlgItem(hDlg,IDC_POLICY_SETTINGS),&wp))
  9101. return FALSE;
  9102. xWindowMax = wp.rcNormalPosition.right - wp.rcNormalPosition.left;
  9103. pdi->pCurrentSettings = pSetting;
  9104. while (pSetting) {
  9105. pObjectData = GETOBJECTDATAPTR(pSetting);
  9106. dwType = pSetting->dwType & STYPE_MASK;
  9107. nWidth = 0;
  9108. nHeight = 0;
  9109. switch (dwType) {
  9110. case STYPE_TEXT:
  9111. // create static text control
  9112. if (!(hwndControl = CreateSetting(pdi,(TCHAR *) szSTATIC,
  9113. (TCHAR *) (GETNAMEPTR(pSetting)),0,SSTYLE_STATIC | uEnable,0,
  9114. yStart,0,15,STYPE_TEXT,NO_DATA_INDEX,0, lpSettingsInfo->hFontDlg)))
  9115. return FALSE;
  9116. AdjustWindowToText(hwndControl,(TCHAR *) (GETNAMEPTR(pSetting))
  9117. ,SC_XSPACING,yStart,0,&nWidth,&nHeight, lpSettingsInfo->hFontDlg);
  9118. yStart += nHeight + SC_YSPACING;
  9119. nWidth += SC_XSPACING;
  9120. break;
  9121. case STYPE_CHECKBOX:
  9122. // create checkbox control
  9123. if (!(hwndControl = CreateSetting(pdi,(TCHAR *) szBUTTON,
  9124. (TCHAR *) (GETNAMEPTR(pSetting)),0,SSTYLE_CHECKBOX | uEnable,
  9125. 0,yStart,200,nHeight,STYPE_CHECKBOX,pSetting->uDataIndex,
  9126. pSetting, lpSettingsInfo->hFontDlg)))
  9127. return FALSE;
  9128. nWidth = 20;
  9129. AdjustWindowToText(hwndControl,(TCHAR *) (GETNAMEPTR(pSetting))
  9130. ,SC_XSPACING,yStart,0,&nWidth,&nHeight, lpSettingsInfo->hFontDlg);
  9131. yStart += nHeight + SC_YSPACING;
  9132. nWidth += SC_XSPACING;
  9133. break;
  9134. case STYPE_EDITTEXT:
  9135. case STYPE_COMBOBOX:
  9136. // create static text with setting name
  9137. if (!(hwndControl = CreateSetting(pdi,(TCHAR *) szSTATIC,
  9138. GETNAMEPTR(pSetting),0,SSTYLE_STATIC | uEnable,0,0,0,0,
  9139. STYPE_TEXT,NO_DATA_INDEX,0, lpSettingsInfo->hFontDlg)))
  9140. return FALSE;
  9141. AdjustWindowToText(hwndControl,
  9142. GETNAMEPTR(pSetting),SC_XSPACING,yStart,SC_YPAD,
  9143. &nWidth,&nHeight, lpSettingsInfo->hFontDlg);
  9144. nWidth += SC_XSPACING + 5;
  9145. if (nWidth + SC_EDITWIDTH> xWindowMax) {
  9146. // if next control will stick out of settings window,
  9147. // put it on the next line
  9148. if (nWidth > xMax)
  9149. xMax = nWidth;
  9150. yStart += nHeight + SC_YCONTROLWRAP;
  9151. nWidth = SC_XINDENT;
  9152. } else {
  9153. SetWindowPos(hwndControl,NULL,SC_XSPACING,(yStart + SC_YTEXTDROP),0,0,SWP_NOZORDER | SWP_NOSIZE);
  9154. }
  9155. // create edit field or combo box control
  9156. if (dwType == STYPE_EDITTEXT) {
  9157. hwndControl = CreateSetting(pdi,(TCHAR *) szEDIT,(TCHAR *) g_szNull,
  9158. WS_EX_CLIENTEDGE,SSTYLE_EDITTEXT | uEnable,nWidth,yStart,SC_EDITWIDTH,nHeight,
  9159. STYPE_EDITTEXT,pSetting->uDataIndex,pSetting, lpSettingsInfo->hFontDlg);
  9160. } else {
  9161. dwStyle = SSTYLE_COMBOBOX | uEnable;
  9162. if (pSetting->dwFlags & DF_NOSORT) {
  9163. dwStyle &= ~CBS_SORT;
  9164. }
  9165. hwndControl = CreateSetting(pdi,(TCHAR *) szCOMBOBOX,(TCHAR *)g_szNull,
  9166. WS_EX_CLIENTEDGE,dwStyle,nWidth,yStart,SC_EDITWIDTH,nHeight*6,
  9167. STYPE_COMBOBOX,pSetting->uDataIndex,pSetting, lpSettingsInfo->hFontDlg);
  9168. }
  9169. if (!hwndControl) return FALSE;
  9170. // limit the text length appropriately
  9171. if (dwType == STYPE_COMBOBOX) {
  9172. SendMessage(hwndControl,CB_LIMITTEXT,
  9173. (WPARAM) ((POLICYCOMBOBOXINFO *) pObjectData)->nMaxLen,0L);
  9174. } else {
  9175. SendMessage(hwndControl,EM_SETLIMITTEXT,
  9176. (WPARAM) ((EDITTEXTINFO *) pObjectData)->nMaxLen,0L);
  9177. }
  9178. if (dwType == STYPE_COMBOBOX &&
  9179. ((POLICYCOMBOBOXINFO *) pObjectData)->uOffsetSuggestions)
  9180. InsertComboboxItems(hwndControl,(TCHAR *) ((LPBYTE)pSetting +
  9181. ((POLICYCOMBOBOXINFO *) pObjectData)->uOffsetSuggestions));
  9182. yStart += (UINT) ((float) nHeight*1.3) + SC_YSPACING;
  9183. nWidth += SC_EDITWIDTH;
  9184. break;
  9185. case STYPE_NUMERIC:
  9186. // create static text for setting
  9187. if (!(hwndControl = CreateSetting(pdi,(TCHAR *) szSTATIC,
  9188. GETNAMEPTR(pSetting),0,
  9189. SSTYLE_STATIC | uEnable,0,0,0,0,STYPE_TEXT,NO_DATA_INDEX,0, lpSettingsInfo->hFontDlg)))
  9190. return FALSE;
  9191. AdjustWindowToText(hwndControl,
  9192. GETNAMEPTR(pSetting),SC_XSPACING,(yStart + SC_YTEXTDROP),SC_YPAD,
  9193. &nWidth,&nHeight, lpSettingsInfo->hFontDlg);
  9194. nWidth += SC_XSPACING + 5;
  9195. // create edit field
  9196. if (!(hwndBuddy = CreateSetting(pdi,(TCHAR *) szEDIT,
  9197. (TCHAR *) g_szNull,WS_EX_CLIENTEDGE,SSTYLE_EDITTEXT | uEnable,nWidth,yStart,SC_UPDOWNWIDTH,
  9198. nHeight,STYPE_NUMERIC,pSetting->uDataIndex,pSetting, lpSettingsInfo->hFontDlg)))
  9199. return FALSE;
  9200. //SendMessage(hwndBuddy,EM_LIMITTEXT,4,0);
  9201. nWidth += SC_UPDOWNWIDTH;
  9202. // create spin (up-down) control if specifed
  9203. if (((NUMERICINFO *)pObjectData)->uSpinIncrement) {
  9204. UDACCEL udAccel = {0,0};
  9205. UINT nMax,nMin;
  9206. if (!(hwndControl = CreateSetting(pdi,(TCHAR *) szUPDOWN,
  9207. (TCHAR *) g_szNull,WS_EX_CLIENTEDGE,SSTYLE_UPDOWN | UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_UNSIGNED | uEnable,nWidth,yStart,SC_UPDOWNWIDTH2,
  9208. nHeight,STYPE_TEXT | STYPE_NUMERIC,NO_DATA_INDEX,0, lpSettingsInfo->hFontDlg)))
  9209. return FALSE;
  9210. nWidth += SC_UPDOWNWIDTH2;
  9211. nMax = ((NUMERICINFO *) pObjectData)->uMaxValue;
  9212. nMin = ((NUMERICINFO *) pObjectData)->uMinValue;
  9213. udAccel.nInc = ((NUMERICINFO *) pObjectData)->uSpinIncrement;
  9214. SendMessage(hwndControl,UDM_SETBUDDY,(WPARAM) hwndBuddy,0L);
  9215. SendMessage(hwndControl,UDM_SETRANGE32,(WPARAM) nMin,(LPARAM) nMax);
  9216. SendMessage(hwndControl,UDM_SETACCEL,1,(LPARAM) &udAccel);
  9217. }
  9218. yStart += nHeight + SC_YSPACING;
  9219. break;
  9220. case STYPE_DROPDOWNLIST:
  9221. // create text description
  9222. if (!(hwndControl = CreateSetting(pdi,(TCHAR *) szSTATIC,
  9223. GETNAMEPTR(pSetting),0,
  9224. SSTYLE_STATIC | uEnable,0,0,0,0,STYPE_TEXT,NO_DATA_INDEX,0, lpSettingsInfo->hFontDlg)))
  9225. return FALSE;
  9226. AdjustWindowToText(hwndControl,
  9227. GETNAMEPTR(pSetting),SC_XSPACING,yStart,SC_YPAD,&nWidth,&nHeight, lpSettingsInfo->hFontDlg);
  9228. nWidth += SC_XLEADING + 5;
  9229. if (nWidth + SC_EDITWIDTH> xWindowMax) {
  9230. // if next control will stick out of settings window,
  9231. // put it on the next line
  9232. if (nWidth > xMax)
  9233. xMax = nWidth;
  9234. yStart += nHeight + SC_YCONTROLWRAP;
  9235. nWidth = SC_XINDENT;
  9236. } else {
  9237. SetWindowPos(hwndControl,NULL,SC_XSPACING,(yStart + SC_YTEXTDROP),0,0,SWP_NOZORDER | SWP_NOSIZE);
  9238. }
  9239. dwStyle = SSTYLE_DROPDOWNLIST | uEnable;
  9240. if (pSetting->dwFlags & DF_NOSORT) {
  9241. dwStyle &= ~CBS_SORT;
  9242. }
  9243. // create drop down listbox
  9244. hwndControl = CreateSetting(pdi,(TCHAR *) szCOMBOBOX,(TCHAR *) g_szNull,
  9245. WS_EX_CLIENTEDGE,dwStyle,nWidth,yStart,SC_EDITWIDTH,nHeight*6,
  9246. STYPE_DROPDOWNLIST,pSetting->uDataIndex,pSetting, lpSettingsInfo->hFontDlg);
  9247. if (!hwndControl) return FALSE;
  9248. nWidth += SC_EDITWIDTH;
  9249. {
  9250. // insert dropdown list items into control
  9251. UINT uOffset = pSetting->uOffsetObjectData,nIndex=0;
  9252. DROPDOWNINFO * pddi;
  9253. int iSel;
  9254. while (uOffset) {
  9255. pddi = (DROPDOWNINFO *) ( (LPBYTE) pSetting + uOffset);
  9256. iSel=(int)SendMessage(hwndControl,CB_ADDSTRING,0,(LPARAM)
  9257. ((LPBYTE) pSetting + pddi->uOffsetItemName));
  9258. if (iSel<0) return FALSE;
  9259. SendMessage(hwndControl,CB_SETITEMDATA,iSel,nIndex);
  9260. nIndex++;
  9261. uOffset = pddi->uOffsetNextDropdowninfo;
  9262. }
  9263. }
  9264. yStart += (UINT) ((float) nHeight*1.3) + 1;
  9265. break;
  9266. case STYPE_LISTBOX:
  9267. {
  9268. TCHAR szShow[50];
  9269. // create static text with description
  9270. if (!(hwndControl = CreateSetting(pdi,(TCHAR *) szSTATIC,
  9271. GETNAMEPTR(pSetting),0,
  9272. SSTYLE_STATIC | uEnable,0,0,0,0,STYPE_TEXT,NO_DATA_INDEX,0, lpSettingsInfo->hFontDlg)))
  9273. return FALSE;
  9274. AdjustWindowToText(hwndControl,GETNAMEPTR(pSetting),SC_XSPACING,yStart,
  9275. SC_YPAD,&nWidth,&nHeight, lpSettingsInfo->hFontDlg);
  9276. nWidth += SC_XLEADING;
  9277. if (nWidth + LISTBOX_BTN_WIDTH> xWindowMax) {
  9278. // if next control will stick out of settings window,
  9279. // put it on the next line
  9280. if (nWidth > xMax)
  9281. xMax = nWidth;
  9282. yStart += nHeight + SC_YCONTROLWRAP;
  9283. nWidth = SC_XINDENT;
  9284. } else {
  9285. SetWindowPos(hwndControl,NULL,SC_XSPACING,(yStart + SC_YTEXTDROP),0,0,SWP_NOZORDER | SWP_NOSIZE);
  9286. }
  9287. // create pushbutton to show listbox contents
  9288. LoadString(g_hInstance, IDS_LISTBOX_SHOW, szShow, ARRAYSIZE(szShow));
  9289. hwndControl = CreateSetting(pdi,(TCHAR *) szBUTTON,szShow,0,
  9290. SSTYLE_LBBUTTON | uEnable,nWidth+5,yStart,
  9291. LISTBOX_BTN_WIDTH,nHeight,STYPE_LISTBOX,
  9292. pSetting->uDataIndex,pSetting, lpSettingsInfo->hFontDlg);
  9293. if (!hwndControl) return FALSE;
  9294. SetWindowLongPtr(hwndControl,GWLP_USERDATA,0);
  9295. nWidth += LISTBOX_BTN_WIDTH + SC_XLEADING;
  9296. yStart += nHeight+1;
  9297. }
  9298. }
  9299. if (nWidth > xMax)
  9300. xMax = nWidth;
  9301. pSetting = (SETTINGS *) pSetting->pNext;
  9302. }
  9303. yMax = yStart - 1;
  9304. SetWindowPos(pdi->hwndSettings,NULL,0,0,xMax,yMax,SWP_NOZORDER);
  9305. hwndParent = GetParent(pdi->hwndSettings);
  9306. GetClientRect(hwndParent,&rcParent);
  9307. if (yMax > (UINT) rcParent.bottom-rcParent.top) {
  9308. SetScrollRange(hwndParent,SB_VERT,0,100,TRUE);
  9309. SetScrollPos(hwndParent,SB_VERT,0,TRUE);
  9310. ShowScrollBar(hwndParent,SB_VERT, TRUE);
  9311. } else {
  9312. SetScrollRange(hwndParent,SB_VERT,0,0,TRUE);
  9313. ShowScrollBar(hwndParent,SB_VERT, FALSE);
  9314. }
  9315. if (xMax > (UINT) rcParent.right-rcParent.left) {
  9316. SetScrollRange(hwndParent,SB_HORZ,0,100,TRUE);
  9317. SetScrollPos(hwndParent,SB_HORZ,0,TRUE);
  9318. ShowScrollBar(hwndParent,SB_HORZ, TRUE);
  9319. } else {
  9320. SetScrollRange(hwndParent,SB_HORZ,0,0,TRUE);
  9321. ShowScrollBar(hwndParent,SB_HORZ, FALSE);
  9322. }
  9323. return TRUE;
  9324. }
  9325. VOID CPolicySnapIn::InsertComboboxItems(HWND hwndControl,TCHAR * pSuggestionList)
  9326. {
  9327. while (*pSuggestionList) {
  9328. SendMessage(hwndControl,CB_ADDSTRING,0,(LPARAM) pSuggestionList);
  9329. pSuggestionList += lstrlen(pSuggestionList) + 1;
  9330. }
  9331. }
  9332. /*******************************************************************
  9333. NAME: CreateSettings
  9334. SYNOPSIS: Creates a control and add it to the table of settings
  9335. controls
  9336. ********************************************************************/
  9337. HWND CPolicySnapIn::CreateSetting(POLICYDLGINFO * pdi,TCHAR * pszClassName,TCHAR * pszWindowName,
  9338. DWORD dwExStyle,DWORD dwStyle,int x,int y,int cx,int cy,DWORD dwType,UINT uIndex,
  9339. SETTINGS * pSetting, HFONT hFontDlg)
  9340. {
  9341. HWND hwndControl;
  9342. if (!(hwndControl = CreateWindowEx(WS_EX_NOPARENTNOTIFY | dwExStyle,
  9343. pszClassName,pszWindowName,dwStyle,x,y,cx,cy,pdi->hwndSettings,NULL,
  9344. g_hInstance,NULL))) return NULL;
  9345. if (!SetWindowData(pdi,hwndControl,dwType,uIndex,pSetting)) {
  9346. DestroyWindow(hwndControl);
  9347. return NULL;
  9348. }
  9349. SendMessage(hwndControl,WM_SETFONT,(WPARAM) hFontDlg,MAKELPARAM(TRUE,0));
  9350. return hwndControl;
  9351. }
  9352. BOOL CPolicySnapIn::SetWindowData(POLICYDLGINFO * pdi,HWND hwndControl,DWORD dwType,
  9353. UINT uDataIndex,SETTINGS * pSetting)
  9354. {
  9355. POLICYCTRLINFO PolicyCtrlInfo;
  9356. int iCtrl;
  9357. PolicyCtrlInfo.hwnd = hwndControl;
  9358. PolicyCtrlInfo.dwType = dwType;
  9359. PolicyCtrlInfo.uDataIndex = uDataIndex;
  9360. PolicyCtrlInfo.pSetting = pSetting;
  9361. iCtrl = AddControlHwnd(pdi,&PolicyCtrlInfo);
  9362. if (iCtrl < 0) return FALSE;
  9363. SetWindowLong(hwndControl,GWL_ID,iCtrl + IDD_SETTINGCTRL);
  9364. return TRUE;
  9365. }
  9366. int CPolicySnapIn::AddControlHwnd(POLICYDLGINFO * pdi,POLICYCTRLINFO * pPolicyCtrlInfo)
  9367. {
  9368. int iRet;
  9369. DWORD dwNeeded;
  9370. POLICYCTRLINFO * pTemp;
  9371. // grow table if necessary
  9372. dwNeeded = (pdi->nControls+1) * sizeof(POLICYCTRLINFO);
  9373. if (dwNeeded > pdi->dwControlTableSize) {
  9374. pTemp = (POLICYCTRLINFO *) LocalReAlloc(pdi->pControlTable,
  9375. dwNeeded,LMEM_ZEROINIT | LMEM_MOVEABLE);
  9376. if (!pTemp) return (-1);
  9377. pdi->pControlTable = pTemp;
  9378. pdi->dwControlTableSize = dwNeeded;
  9379. }
  9380. pdi->pControlTable[pdi->nControls] = *pPolicyCtrlInfo;
  9381. iRet = (int) pdi->nControls;
  9382. (pdi->nControls)++;
  9383. return iRet;
  9384. }
  9385. BOOL CPolicySnapIn::AdjustWindowToText(HWND hWnd,TCHAR * szText,UINT xStart,UINT yStart,
  9386. UINT yPad,UINT * pnWidth,UINT * pnHeight, HFONT hFontDlg)
  9387. {
  9388. SIZE size;
  9389. if (GetTextSize(hWnd,szText,&size, hFontDlg))
  9390. {
  9391. *pnHeight =size.cy + yPad;
  9392. *pnWidth += size.cx;
  9393. SetWindowPos(hWnd,NULL,xStart,yStart,*pnWidth,*pnHeight,SWP_NOZORDER);
  9394. }
  9395. return FALSE;
  9396. }
  9397. BOOL CPolicySnapIn::GetTextSize(HWND hWnd,TCHAR * szText,SIZE * pSize, HFONT hFontDlg)
  9398. {
  9399. HDC hDC;
  9400. BOOL fRet;
  9401. if (!(hDC = GetDC(hWnd))) return FALSE;
  9402. SelectObject(hDC, hFontDlg);
  9403. fRet=GetTextExtentPoint(hDC,szText,lstrlen(szText),pSize);
  9404. ReleaseDC(hWnd,hDC);
  9405. return fRet;
  9406. }
  9407. //*************************************************************
  9408. //
  9409. // SaveSettings()
  9410. //
  9411. // Purpose: Saves the results of the settings
  9412. //
  9413. // Parameters:
  9414. //
  9415. //
  9416. // Return: TRUE if successful
  9417. // FALSE if an error occurs
  9418. //
  9419. //*************************************************************
  9420. HRESULT CPolicySnapIn::SaveSettings(HWND hDlg)
  9421. {
  9422. UINT nIndex;
  9423. POLICYDLGINFO * pdi;
  9424. LPSETTINGSINFO lpSettingsInfo;
  9425. SETTINGS * pSetting;
  9426. HKEY hKeyRoot;
  9427. DWORD dwTemp;
  9428. UINT uRet = ERROR_SUCCESS, uPolicyState;
  9429. int iSel, iIndex;
  9430. LPTSTR lpBuffer;
  9431. BOOL fTranslated;
  9432. NUMERICINFO * pNumericInfo;
  9433. HRESULT hr;
  9434. LPBYTE pObjectData;
  9435. BOOL fErase;
  9436. DROPDOWNINFO * pddi;
  9437. GUID guidRegistryExt = REGISTRY_EXTENSION_GUID;
  9438. GUID guidSnapinMach = CLSID_PolicySnapInMachine;
  9439. GUID guidSnapinUser = CLSID_PolicySnapInUser;
  9440. GUID ClientGUID;
  9441. LPTSTR lpClientGUID;
  9442. TCHAR szFormat[100];
  9443. TCHAR szMsg[150];
  9444. BOOL bFoundNone; // used in the listbox case alone
  9445. //
  9446. // Check for RSOP mode
  9447. //
  9448. if (m_pcd->m_bRSOP)
  9449. {
  9450. DebugMsg((DM_VERBOSE, TEXT("CPolicySnapIn::SaveSettings: Running in RSOP mode, nothing to save.")));
  9451. return S_OK;
  9452. }
  9453. //
  9454. // Check the dirty bit
  9455. //
  9456. if (!m_bDirty)
  9457. {
  9458. DebugMsg((DM_VERBOSE, TEXT("CPolicySnapIn::SaveSettings: No changes detected. Exiting successfully.")));
  9459. return S_OK;
  9460. }
  9461. // get instance-specific struct from dialog
  9462. lpSettingsInfo = (LPSETTINGSINFO) GetWindowLongPtr(hDlg, DWLP_USER);
  9463. if (!lpSettingsInfo)
  9464. return E_FAIL;
  9465. pdi = lpSettingsInfo->pdi;
  9466. if (!pdi)
  9467. return E_FAIL;
  9468. if (m_pcd->m_pGPTInformation->GetRegistryKey(
  9469. (m_pcd->m_bUserScope ? GPO_SECTION_USER : GPO_SECTION_MACHINE),
  9470. &hKeyRoot) != S_OK)
  9471. {
  9472. DebugMsg((DM_WARNING, TEXT("CPolicySnapIn::SaveSettings: Failed to get registry key handle.")));
  9473. return S_FALSE;
  9474. }
  9475. //
  9476. // Get the policy state
  9477. //
  9478. if (IsDlgButtonChecked (hDlg, IDC_NOCONFIG) == BST_CHECKED)
  9479. {
  9480. uPolicyState = BST_INDETERMINATE;
  9481. }
  9482. else if (IsDlgButtonChecked (hDlg, IDC_ENABLED) == BST_CHECKED)
  9483. {
  9484. uPolicyState = BST_CHECKED;
  9485. }
  9486. else
  9487. {
  9488. uPolicyState = BST_UNCHECKED;
  9489. }
  9490. if (uPolicyState == BST_INDETERMINATE)
  9491. {
  9492. fErase = TRUE;
  9493. }
  9494. else
  9495. {
  9496. fErase = FALSE;
  9497. }
  9498. //
  9499. // Save the overall policy state
  9500. //
  9501. if (uPolicyState != BST_INDETERMINATE)
  9502. {
  9503. if (uPolicyState == BST_CHECKED)
  9504. dwTemp = 1;
  9505. else
  9506. dwTemp = 0;
  9507. if (dwTemp && m_pCurrentPolicy->uOffsetValue_On)
  9508. {
  9509. uRet= WriteCustomValue(hKeyRoot,GETKEYNAMEPTR(m_pCurrentPolicy),GETVALUENAMEPTR(m_pCurrentPolicy),
  9510. (STATEVALUE *) ((LPBYTE) m_pCurrentPolicy + m_pCurrentPolicy->uOffsetValue_On),
  9511. fErase);
  9512. }
  9513. else if (!dwTemp && m_pCurrentPolicy->uOffsetValue_Off)
  9514. {
  9515. uRet= WriteCustomValue(hKeyRoot,GETKEYNAMEPTR(m_pCurrentPolicy),GETVALUENAMEPTR(m_pCurrentPolicy),
  9516. (STATEVALUE *) ((LPBYTE) m_pCurrentPolicy + m_pCurrentPolicy->uOffsetValue_Off),
  9517. fErase);
  9518. }
  9519. else
  9520. {
  9521. if (m_pCurrentPolicy->uOffsetValueName)
  9522. {
  9523. uRet=WriteStandardValue(hKeyRoot,GETKEYNAMEPTR(m_pCurrentPolicy),GETVALUENAMEPTR(m_pCurrentPolicy),
  9524. (TABLEENTRY *)m_pCurrentPolicy,dwTemp,fErase,FALSE);
  9525. }
  9526. else
  9527. {
  9528. uRet = ERROR_SUCCESS;
  9529. }
  9530. }
  9531. if (uRet == ERROR_SUCCESS)
  9532. {
  9533. uRet = ProcessCheckboxActionLists(hKeyRoot,(TABLEENTRY *)m_pCurrentPolicy,
  9534. GETKEYNAMEPTR(m_pCurrentPolicy),dwTemp,FALSE, !dwTemp, TRUE);
  9535. }
  9536. else
  9537. {
  9538. DebugMsg((DM_WARNING, TEXT("CPolicySnapIn::SaveSettings: Failed to set registry value with %d."), uRet));
  9539. }
  9540. }
  9541. else
  9542. {
  9543. if (m_pCurrentPolicy->uOffsetValueName)
  9544. {
  9545. uRet=WriteStandardValue(hKeyRoot,GETKEYNAMEPTR(m_pCurrentPolicy),GETVALUENAMEPTR(m_pCurrentPolicy),
  9546. (TABLEENTRY *)m_pCurrentPolicy,0,TRUE,FALSE);
  9547. }
  9548. if (uRet == ERROR_SUCCESS)
  9549. {
  9550. uRet = ProcessCheckboxActionLists(hKeyRoot,(TABLEENTRY *)m_pCurrentPolicy,
  9551. GETKEYNAMEPTR(m_pCurrentPolicy),0,TRUE,FALSE, TRUE);
  9552. }
  9553. }
  9554. //
  9555. // Save the state of the parts
  9556. //
  9557. for (nIndex=0;nIndex<pdi->nControls;nIndex++)
  9558. {
  9559. pSetting = pdi->pControlTable[nIndex].pSetting;
  9560. if (pdi->pControlTable[nIndex].uDataIndex != NO_DATA_INDEX)
  9561. {
  9562. switch (pdi->pControlTable[nIndex].dwType)
  9563. {
  9564. case STYPE_CHECKBOX:
  9565. dwTemp = (DWORD)SendMessage(pdi->pControlTable[nIndex].hwnd,BM_GETCHECK,0,0L);
  9566. pObjectData = GETOBJECTDATAPTR(pSetting);
  9567. if (!pObjectData) {
  9568. return E_INVALIDARG;
  9569. }
  9570. if (dwTemp && ((CHECKBOXINFO *) pObjectData)->uOffsetValue_On) {
  9571. uRet= WriteCustomValue(hKeyRoot,GETKEYNAMEPTR(pSetting),GETVALUENAMEPTR(pSetting),
  9572. (STATEVALUE *) ((LPBYTE) pSetting + ((CHECKBOXINFO *)
  9573. pObjectData)->uOffsetValue_On),fErase);
  9574. } else if (!dwTemp && ((CHECKBOXINFO *) pObjectData)->uOffsetValue_Off) {
  9575. uRet= WriteCustomValue(hKeyRoot,GETKEYNAMEPTR(pSetting),GETVALUENAMEPTR(pSetting),
  9576. (STATEVALUE *) ((LPBYTE) pSetting + ((CHECKBOXINFO *)
  9577. pObjectData)->uOffsetValue_Off),fErase);
  9578. }
  9579. else uRet=WriteStandardValue(hKeyRoot,GETKEYNAMEPTR(pSetting),GETVALUENAMEPTR(pSetting),
  9580. (TABLEENTRY *)pSetting,dwTemp,fErase,FALSE);
  9581. if (uRet == ERROR_SUCCESS) {
  9582. uRet = ProcessCheckboxActionLists(hKeyRoot,(TABLEENTRY *)pSetting,
  9583. GETKEYNAMEPTR(pSetting),dwTemp,fErase,(uPolicyState == BST_UNCHECKED),FALSE);
  9584. } else {
  9585. DebugMsg((DM_WARNING, TEXT("CPolicySnapIn::SaveSettings: Failed to set registry value with %d."), uRet));
  9586. }
  9587. break;
  9588. case STYPE_EDITTEXT:
  9589. case STYPE_COMBOBOX:
  9590. if (uPolicyState == BST_CHECKED)
  9591. {
  9592. dwTemp = (DWORD)SendMessage(pdi->pControlTable[nIndex].hwnd,
  9593. WM_GETTEXTLENGTH,0,0);
  9594. if (!dwTemp)
  9595. {
  9596. if (pSetting->dwFlags & DF_REQUIRED)
  9597. {
  9598. m_pcd->MsgBoxParam(hDlg,IDS_ENTRYREQUIRED,GETNAMEPTR(pSetting),
  9599. MB_ICONINFORMATION,MB_OK);
  9600. RegCloseKey (hKeyRoot);
  9601. return E_FAIL;
  9602. }
  9603. }
  9604. lpBuffer = (LPTSTR) LocalAlloc (LPTR, (dwTemp + 1) * sizeof(TCHAR));
  9605. if (lpBuffer)
  9606. {
  9607. SendMessage(pdi->pControlTable[nIndex].hwnd,WM_GETTEXT,
  9608. (dwTemp+1),(LPARAM) lpBuffer);
  9609. uRet = WriteCustomValue_W(hKeyRoot,
  9610. GETKEYNAMEPTR(pSetting),
  9611. GETVALUENAMEPTR(pSetting),
  9612. lpBuffer, 0, pSetting->dwFlags, FALSE);
  9613. if (uRet != ERROR_SUCCESS)
  9614. {
  9615. DebugMsg((DM_WARNING, TEXT("CPolicySnapIn::SaveSettings: Failed to set registry value with %d."), uRet));
  9616. }
  9617. LocalFree (lpBuffer);
  9618. }
  9619. else
  9620. {
  9621. DebugMsg((DM_WARNING, TEXT("CPolicySnapIn::SaveSettings: Failed to allocate memory with %d."),
  9622. GetLastError()));
  9623. }
  9624. }
  9625. else
  9626. {
  9627. WriteCustomValue_W(hKeyRoot,GETKEYNAMEPTR(pSetting),GETVALUENAMEPTR(pSetting),
  9628. (LPTSTR)g_szNull,0,
  9629. (uPolicyState == BST_UNCHECKED) ? VF_DELETE : 0,
  9630. fErase);
  9631. }
  9632. break;
  9633. case STYPE_NUMERIC:
  9634. if (uPolicyState == BST_CHECKED)
  9635. {
  9636. if (pSetting->dwFlags & DF_REQUIRED)
  9637. {
  9638. dwTemp = (DWORD)SendMessage(pdi->pControlTable[nIndex].hwnd,
  9639. WM_GETTEXTLENGTH,0,0);
  9640. if (!dwTemp)
  9641. {
  9642. if (pSetting->dwFlags & DF_REQUIRED)
  9643. {
  9644. m_pcd->MsgBoxParam(hDlg,IDS_ENTRYREQUIRED,GETNAMEPTR(pSetting),
  9645. MB_ICONINFORMATION,MB_OK);
  9646. RegCloseKey (hKeyRoot);
  9647. return E_FAIL;
  9648. }
  9649. }
  9650. }
  9651. uRet=GetDlgItemInt(pdi->hwndSettings,nIndex+IDD_SETTINGCTRL,
  9652. &fTranslated,FALSE);
  9653. if (!fTranslated)
  9654. {
  9655. m_pcd->MsgBoxParam(hDlg,IDS_INVALIDNUM,
  9656. GETNAMEPTR(pSetting),MB_ICONINFORMATION,
  9657. MB_OK);
  9658. SetFocus(pdi->pControlTable[nIndex].hwnd);
  9659. SendMessage(pdi->pControlTable[nIndex].hwnd,
  9660. EM_SETSEL,0,-1);
  9661. RegCloseKey (hKeyRoot);
  9662. return E_FAIL;
  9663. }
  9664. // validate for max and min
  9665. pNumericInfo = (NUMERICINFO *) GETOBJECTDATAPTR(pSetting);
  9666. if (pNumericInfo && uRet < pNumericInfo->uMinValue)
  9667. {
  9668. LoadString(g_hInstance, IDS_NUMBERTOOSMALL, szFormat, ARRAYSIZE(szFormat));
  9669. wsprintf (szMsg, szFormat, uRet, pNumericInfo->uMinValue, pNumericInfo->uMinValue, uRet);
  9670. m_pcd->MsgBoxSz(hDlg,szMsg, MB_ICONINFORMATION, MB_OK);
  9671. uRet = pNumericInfo->uMinValue;
  9672. }
  9673. if (pNumericInfo && uRet > pNumericInfo->uMaxValue)
  9674. {
  9675. LoadString(g_hInstance, IDS_NUMBERTOOLARGE, szFormat, ARRAYSIZE(szFormat));
  9676. wsprintf (szMsg, szFormat, uRet, pNumericInfo->uMaxValue, pNumericInfo->uMaxValue, uRet);
  9677. m_pcd->MsgBoxSz(hDlg,szMsg, MB_ICONINFORMATION, MB_OK);
  9678. uRet = pNumericInfo->uMaxValue;
  9679. }
  9680. }
  9681. else
  9682. {
  9683. uRet = 0;
  9684. }
  9685. uRet=WriteStandardValue(hKeyRoot,GETKEYNAMEPTR(pSetting),
  9686. GETVALUENAMEPTR(pSetting),
  9687. (TABLEENTRY *)pSetting,uRet,
  9688. fErase,(uPolicyState == BST_UNCHECKED) ? FALSE : TRUE);
  9689. if (uRet != ERROR_SUCCESS)
  9690. {
  9691. DebugMsg((DM_WARNING, TEXT("CPolicySnapIn::SaveSettings: Failed to set registry value with %d."), uRet));
  9692. }
  9693. break;
  9694. case STYPE_DROPDOWNLIST:
  9695. if (uPolicyState == BST_CHECKED)
  9696. {
  9697. iSel = (int)SendMessage(pdi->pControlTable[nIndex].hwnd,
  9698. CB_GETCURSEL,0,0L);
  9699. iSel = (int)SendMessage(pdi->pControlTable[nIndex].hwnd,
  9700. CB_GETITEMDATA,iSel,0L);
  9701. if (iSel < 0)
  9702. {
  9703. m_pcd->MsgBoxParam(hDlg,IDS_ENTRYREQUIRED,GETNAMEPTR(pSetting),
  9704. MB_ICONINFORMATION,MB_OK);
  9705. SetFocus(pdi->pControlTable[nIndex].hwnd);
  9706. RegCloseKey (hKeyRoot);
  9707. return E_FAIL;
  9708. }
  9709. }
  9710. else
  9711. {
  9712. iSel = 0;
  9713. }
  9714. pddi = (DROPDOWNINFO *) GETOBJECTDATAPTR(pSetting);
  9715. iIndex = 0;
  9716. // walk the chain of DROPDOWNINFO structs to find the entry that
  9717. // we want to write. (for value n, find the nth struct)
  9718. while (iIndex < iSel) {
  9719. // selected val is higher than # of structs in chain,
  9720. // should never happen but check just in case...
  9721. if (!pddi->uOffsetNextDropdowninfo) {
  9722. RegCloseKey (hKeyRoot);
  9723. return ERROR_NOT_ENOUGH_MEMORY;
  9724. }
  9725. pddi = (DROPDOWNINFO *)
  9726. ((LPBYTE) pSetting + pddi->uOffsetNextDropdowninfo);
  9727. iIndex++;
  9728. }
  9729. uRet=WriteCustomValue_W(hKeyRoot,GETKEYNAMEPTR(pSetting),GETVALUENAMEPTR(pSetting),
  9730. (LPTSTR) ((LPBYTE)pSetting+pddi->uOffsetValue),pddi->dwValue,
  9731. pddi->dwFlags | ((uPolicyState == BST_UNCHECKED) ? VF_DELETE : 0),
  9732. fErase);
  9733. if (uRet == ERROR_SUCCESS && pddi->uOffsetActionList) {
  9734. uRet=WriteActionList(hKeyRoot,(ACTIONLIST *) ( (LPBYTE)
  9735. pSetting + pddi->uOffsetActionList),GETKEYNAMEPTR(pSetting),
  9736. fErase, (uPolicyState == BST_UNCHECKED));
  9737. }
  9738. if (uRet != ERROR_SUCCESS)
  9739. {
  9740. DebugMsg((DM_WARNING, TEXT("CPolicySnapIn::SaveSettings: Failed to set registry value with %d."), uRet));
  9741. }
  9742. break;
  9743. case STYPE_LISTBOX:
  9744. bFoundNone = FALSE;
  9745. SaveListboxData((HGLOBAL)GetWindowLongPtr (pdi->pControlTable[nIndex].hwnd, GWLP_USERDATA),
  9746. pSetting, hKeyRoot, GETKEYNAMEPTR(pSetting), fErase,
  9747. ((uPolicyState == BST_INDETERMINATE) ? FALSE : TRUE),
  9748. (uPolicyState == BST_CHECKED), &bFoundNone);
  9749. // if the policy is enabled and no values are set
  9750. if ((uPolicyState == BST_CHECKED) && (bFoundNone)) {
  9751. m_pcd->MsgBoxParam(hDlg,IDS_ENTRYREQUIRED,GETNAMEPTR(pSetting),
  9752. MB_ICONINFORMATION,MB_OK);
  9753. SetFocus(pdi->pControlTable[nIndex].hwnd);
  9754. RegCloseKey (hKeyRoot);
  9755. return E_FAIL;
  9756. }
  9757. break;
  9758. }
  9759. if (pSetting->uOffsetClientExt)
  9760. {
  9761. lpClientGUID = (LPTSTR) ((BYTE *) pSetting + pSetting->uOffsetClientExt);
  9762. StringToGuid (lpClientGUID, &ClientGUID);
  9763. m_pcd->m_pGPTInformation->PolicyChanged(!m_pcd->m_bUserScope, TRUE, &ClientGUID,
  9764. m_pcd->m_bUserScope ? &guidSnapinUser
  9765. : &guidSnapinMach );
  9766. }
  9767. }
  9768. }
  9769. hr = m_pcd->m_pGPTInformation->PolicyChanged(!m_pcd->m_bUserScope, TRUE, &guidRegistryExt,
  9770. m_pcd->m_bUserScope ? &guidSnapinUser
  9771. : &guidSnapinMach );
  9772. if (FAILED(hr))
  9773. {
  9774. LPTSTR lpError;
  9775. if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
  9776. FORMAT_MESSAGE_IGNORE_INSERTS,
  9777. 0, hr, 0, (LPTSTR) &lpError, 0, NULL))
  9778. {
  9779. m_pcd->MsgBoxParam(hDlg,IDS_POLICYCHANGEDFAILED,lpError,
  9780. MB_ICONERROR, MB_OK);
  9781. LocalFree (lpError);
  9782. }
  9783. }
  9784. if (m_pCurrentPolicy->uOffsetClientExt)
  9785. {
  9786. lpClientGUID = (LPTSTR) ((BYTE *) m_pCurrentPolicy + m_pCurrentPolicy->uOffsetClientExt);
  9787. StringToGuid (lpClientGUID, &ClientGUID);
  9788. m_pcd->m_pGPTInformation->PolicyChanged(!m_pcd->m_bUserScope, TRUE, &ClientGUID,
  9789. m_pcd->m_bUserScope ? &guidSnapinUser
  9790. : &guidSnapinMach );
  9791. }
  9792. RegCloseKey (hKeyRoot);
  9793. SendMessage (m_hMsgWindow, WM_UPDATEITEM, 0, 0);
  9794. if (SUCCEEDED(hr))
  9795. {
  9796. m_bDirty = FALSE;
  9797. PostMessage (GetParent(hDlg), PSM_UNCHANGED, (WPARAM) hDlg, 0);
  9798. }
  9799. return S_OK;
  9800. }
  9801. VOID CPolicySnapIn::DeleteOldListboxData(SETTINGS * pSetting, HKEY hkeyRoot,
  9802. TCHAR * pszCurrentKeyName)
  9803. {
  9804. HGLOBAL hData = NULL;
  9805. LPTSTR lpData;
  9806. HKEY hKey;
  9807. TCHAR szValueName[MAX_PATH+1];
  9808. INT nItem=1;
  9809. LISTBOXINFO * pListboxInfo = (LISTBOXINFO *) GETOBJECTDATAPTR(pSetting);
  9810. //
  9811. // Open the target registry key
  9812. //
  9813. if (RegOpenKeyEx (hkeyRoot, pszCurrentKeyName, 0, KEY_WRITE, &hKey) != ERROR_SUCCESS)
  9814. {
  9815. return;
  9816. }
  9817. //
  9818. // Load the old listbox data
  9819. //
  9820. if (LoadListboxData((TABLEENTRY *) pSetting, hkeyRoot,
  9821. pszCurrentKeyName, NULL, &hData, NULL) == ERROR_SUCCESS)
  9822. {
  9823. if (hData)
  9824. {
  9825. //
  9826. // Delete the listbox's old data
  9827. //
  9828. if ((lpData = (LPTSTR) GlobalLock(hData)))
  9829. {
  9830. while (*lpData) {
  9831. if (pSetting->dwFlags & DF_EXPLICITVALNAME)
  9832. {
  9833. // if explicit valuename flag set, entries are stored
  9834. // <value name>\0<value>\0....<value name>\0<value>\0\0
  9835. // otherwise, entries are stored
  9836. // <value>\0<value>\0....<value>\0
  9837. RegDeleteValue (hKey, lpData);
  9838. lpData += lstrlen(lpData) +1;
  9839. lpData += lstrlen(lpData) +1;
  9840. }
  9841. else
  9842. {
  9843. //
  9844. // Value name is either same as the data, or a prefix
  9845. // with a number
  9846. //
  9847. if (!pListboxInfo->uOffsetPrefix)
  9848. {
  9849. // if no prefix set, then name = data
  9850. RegDeleteValue (hKey, lpData);
  9851. lpData += lstrlen(lpData) +1;
  9852. }
  9853. else
  9854. {
  9855. // value name is "<prefix><n>" where n=1,2,etc.
  9856. wsprintf(szValueName,TEXT("%s%lu"),(TCHAR *) ((LPBYTE)pSetting +
  9857. pListboxInfo->uOffsetPrefix),nItem);
  9858. RegDeleteValue (hKey, szValueName);
  9859. lpData += lstrlen(lpData) +1;
  9860. nItem++;
  9861. }
  9862. }
  9863. }
  9864. GlobalUnlock(hData);
  9865. }
  9866. GlobalFree (hData);
  9867. }
  9868. }
  9869. RegCloseKey (hKey);
  9870. }
  9871. UINT CPolicySnapIn::SaveListboxData(HGLOBAL hData,SETTINGS * pSetting,HKEY hkeyRoot,
  9872. TCHAR * pszCurrentKeyName,BOOL fErase,BOOL fMarkDeleted, BOOL bEnabled, BOOL * bFoundNone)
  9873. {
  9874. UINT uOffset,uRet,nItem=1;
  9875. HKEY hKey;
  9876. TCHAR * pszData,* pszName;
  9877. TCHAR szValueName[MAX_PATH+1];
  9878. DWORD cbValueName, dwDisp;
  9879. LISTBOXINFO * pListboxInfo = (LISTBOXINFO *) GETOBJECTDATAPTR(pSetting);
  9880. // these checks need to be done first before any other operations are done
  9881. if ((bEnabled) && (!hData)) {
  9882. *bFoundNone = TRUE;
  9883. return ERROR_INVALID_PARAMETER;
  9884. }
  9885. if (bEnabled) {
  9886. pszData = (TCHAR *)GlobalLock (hData);
  9887. // if there are no items at all
  9888. if (!(*pszData)) {
  9889. *bFoundNone = TRUE;
  9890. GlobalUnlock(hData);
  9891. return ERROR_INVALID_PARAMETER;
  9892. }
  9893. GlobalUnlock(hData);
  9894. pszData = NULL;
  9895. }
  9896. *bFoundNone = FALSE;
  9897. if (fErase)
  9898. {
  9899. RegDelnode (hkeyRoot, pszCurrentKeyName);
  9900. RegCleanUpValue (hkeyRoot, pszCurrentKeyName, TEXT("some value that won't exist"));
  9901. return ERROR_SUCCESS;
  9902. }
  9903. if (pSetting->dwFlags & DF_ADDITIVE)
  9904. {
  9905. DeleteOldListboxData(pSetting, hkeyRoot, pszCurrentKeyName);
  9906. }
  9907. else
  9908. {
  9909. RegDelnode (hkeyRoot, pszCurrentKeyName);
  9910. }
  9911. uRet = RegCreateKeyEx (hkeyRoot,pszCurrentKeyName,0,NULL,
  9912. REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL,
  9913. &hKey, &dwDisp);
  9914. if (uRet != ERROR_SUCCESS)
  9915. return uRet;
  9916. uRet=ERROR_SUCCESS;
  9917. if (fMarkDeleted)
  9918. {
  9919. //
  9920. // Write a control code that will cause
  9921. // all values under that key to be deleted when client downloads from the file.
  9922. // Don't do this if listbox is additive (DF_ADDITIVE), in that case whatever
  9923. // we write here will be dumped in along with existing values
  9924. //
  9925. if (!(pSetting->dwFlags & DF_ADDITIVE))
  9926. {
  9927. uRet=WriteRegistryStringValue(hkeyRoot,pszCurrentKeyName,
  9928. (TCHAR *) szDELVALS,
  9929. (TCHAR *) szNOVALUE, FALSE);
  9930. }
  9931. }
  9932. if (hData) {
  9933. pszData = (TCHAR *)GlobalLock (hData);
  9934. while (*pszData && (uRet == ERROR_SUCCESS))
  9935. {
  9936. UINT nLen = lstrlen(pszData)+1;
  9937. if (pSetting->dwFlags & DF_EXPLICITVALNAME)
  9938. {
  9939. // value name specified for each item
  9940. pszName = pszData; // value name
  9941. pszData += nLen; // now pszData points to value data
  9942. nLen = lstrlen(pszData)+1;
  9943. }
  9944. else
  9945. {
  9946. // value name is either same as the data, or a prefix
  9947. // with a number
  9948. if (!pListboxInfo->uOffsetPrefix) {
  9949. // if no prefix set, then name = data
  9950. pszName = pszData;
  9951. } else {
  9952. // value name is "<prefix><n>" where n=1,2,etc.
  9953. wsprintf(szValueName,TEXT("%s%lu"),(TCHAR *) ((LPBYTE)pSetting +
  9954. pListboxInfo->uOffsetPrefix),nItem);
  9955. pszName = szValueName;
  9956. nItem++;
  9957. }
  9958. }
  9959. uRet=RegSetValueEx(hKey,pszName,0,
  9960. (pSetting->dwFlags & DF_EXPANDABLETEXT) ?
  9961. REG_EXPAND_SZ : REG_SZ, (LPBYTE) pszData,
  9962. (lstrlen(pszData) + 1) * sizeof(TCHAR));
  9963. pszData += nLen;
  9964. }
  9965. GlobalUnlock (hData);
  9966. }
  9967. RegCloseKey(hKey);
  9968. return uRet;
  9969. }
  9970. UINT CPolicySnapIn::ProcessCheckboxActionLists(HKEY hkeyRoot,TABLEENTRY * pTableEntry,
  9971. TCHAR * pszCurrentKeyName,DWORD dwData,
  9972. BOOL fErase, BOOL fMarkAsDeleted,
  9973. BOOL bPolicy)
  9974. {
  9975. UINT uOffsetActionList_On,uOffsetActionList_Off,uRet=ERROR_SUCCESS;
  9976. if (bPolicy)
  9977. {
  9978. POLICY * pPolicy = (POLICY *) pTableEntry;
  9979. uOffsetActionList_On = pPolicy->uOffsetActionList_On;
  9980. uOffsetActionList_Off = pPolicy->uOffsetActionList_Off;
  9981. }
  9982. else
  9983. {
  9984. LPBYTE pObjectData = GETOBJECTDATAPTR(((SETTINGS *)pTableEntry));
  9985. if (!pObjectData) {
  9986. return ERROR_INVALID_PARAMETER;
  9987. }
  9988. uOffsetActionList_On = ((CHECKBOXINFO *) pObjectData)
  9989. ->uOffsetActionList_On;
  9990. uOffsetActionList_Off = ((CHECKBOXINFO *) pObjectData)
  9991. ->uOffsetActionList_Off;
  9992. }
  9993. if (dwData)
  9994. {
  9995. if (uOffsetActionList_On)
  9996. {
  9997. uRet = WriteActionList(hkeyRoot,(ACTIONLIST *)
  9998. ((LPBYTE) pTableEntry + uOffsetActionList_On),
  9999. pszCurrentKeyName,fErase,fMarkAsDeleted);
  10000. }
  10001. }
  10002. else
  10003. {
  10004. if (uOffsetActionList_Off)
  10005. {
  10006. uRet = WriteActionList(hkeyRoot,(ACTIONLIST *)
  10007. ((LPBYTE) pTableEntry + uOffsetActionList_Off),
  10008. pszCurrentKeyName,fErase,FALSE);
  10009. }
  10010. else
  10011. {
  10012. if (uOffsetActionList_On)
  10013. {
  10014. uRet = WriteActionList(hkeyRoot,(ACTIONLIST *)
  10015. ((LPBYTE) pTableEntry + uOffsetActionList_On),
  10016. pszCurrentKeyName,fErase,TRUE);
  10017. }
  10018. }
  10019. }
  10020. return uRet;
  10021. }
  10022. UINT CPolicySnapIn::WriteActionList(HKEY hkeyRoot,ACTIONLIST * pActionList,
  10023. LPTSTR pszCurrentKeyName,BOOL fErase, BOOL fMarkAsDeleted)
  10024. {
  10025. UINT nCount;
  10026. LPTSTR pszValueName;
  10027. LPTSTR pszValue=NULL;
  10028. UINT uRet;
  10029. ACTION * pAction = pActionList->Action;
  10030. for (nCount=0;nCount < pActionList->nActionItems; nCount++)
  10031. {
  10032. //
  10033. // Not every action in the list has to have a key name. But if one
  10034. // is specified, use it and it becomes the current key name for the
  10035. // list until we encounter another one.
  10036. //
  10037. if (pAction->uOffsetKeyName)
  10038. {
  10039. pszCurrentKeyName = (LPTSTR) ((LPBYTE)pActionList + pAction->uOffsetKeyName);
  10040. }
  10041. //
  10042. // Every action must have a value name, enforced at parse time
  10043. //
  10044. pszValueName = (LPTSTR) ((LPBYTE)pActionList + pAction->uOffsetValueName);
  10045. //
  10046. // String values have a string elsewhere in buffer
  10047. //
  10048. if (!pAction->dwFlags && pAction->uOffsetValue)
  10049. {
  10050. pszValue = (LPTSTR) ((LPBYTE)pActionList + pAction->uOffsetValue);
  10051. }
  10052. //
  10053. // Write the value in list
  10054. //
  10055. uRet=WriteCustomValue_W(hkeyRoot,pszCurrentKeyName,pszValueName,
  10056. pszValue,pAction->dwValue,
  10057. pAction->dwFlags | (fMarkAsDeleted ? VF_DELETE : 0),
  10058. fErase);
  10059. if (uRet != ERROR_SUCCESS)
  10060. {
  10061. return uRet;
  10062. }
  10063. pAction = (ACTION*) ((LPBYTE) pActionList + pAction->uOffsetNextAction);
  10064. }
  10065. return ERROR_SUCCESS;
  10066. }
  10067. /*******************************************************************
  10068. NAME: FindComboboxItemData
  10069. SYNOPSIS: Returns the index of item in combobox whose item data
  10070. is equal to nData. Returns -1 if no items have data
  10071. which matches.
  10072. ********************************************************************/
  10073. int CPolicySnapIn::FindComboboxItemData(HWND hwndControl,UINT nData)
  10074. {
  10075. UINT nIndex;
  10076. for (nIndex=0;nIndex<(UINT) SendMessage(hwndControl,CB_GETCOUNT,0,0L);
  10077. nIndex++) {
  10078. if ((UINT) SendMessage(hwndControl,CB_GETITEMDATA,nIndex,0L) == nData)
  10079. return (int) nIndex;
  10080. }
  10081. return -1;
  10082. }
  10083. //*************************************************************
  10084. //
  10085. // InitializeSettingsControls()
  10086. //
  10087. // Purpose: Initializes the settings controls
  10088. //
  10089. // Parameters:
  10090. //
  10091. //
  10092. // Return: TRUE if successful
  10093. // FALSE if an error occurs
  10094. //
  10095. //*************************************************************
  10096. HRESULT CPolicySnapIn::InitializeSettingsControls(HWND hDlg, BOOL fEnable)
  10097. {
  10098. UINT nIndex;
  10099. POLICYDLGINFO * pdi;
  10100. LPSETTINGSINFO lpSettingsInfo;
  10101. SETTINGS * pSetting;
  10102. HKEY hKeyRoot;
  10103. DWORD dwTemp, dwData, dwFlags, dwFoundSettings;
  10104. UINT uRet;
  10105. int iSel;
  10106. HGLOBAL hData;
  10107. LPTSTR lpBuffer;
  10108. BOOL fTranslated, fFound;
  10109. NUMERICINFO * pNumericInfo;
  10110. TCHAR szBuffer[MAXSTRLEN];
  10111. TCHAR szNewValueName[MAX_PATH+1];
  10112. BOOL bChangeableState;
  10113. // get instance-specific struct from dialog
  10114. lpSettingsInfo = (LPSETTINGSINFO) GetWindowLongPtr(hDlg, DWLP_USER);
  10115. if (!lpSettingsInfo)
  10116. return E_FAIL;
  10117. pdi = lpSettingsInfo->pdi;
  10118. if (!pdi)
  10119. return E_FAIL;
  10120. if (m_pcd->m_bRSOP)
  10121. {
  10122. hKeyRoot = (HKEY) 1;
  10123. }
  10124. else
  10125. {
  10126. if (m_pcd->m_pGPTInformation->GetRegistryKey(
  10127. (m_pcd->m_bUserScope ? GPO_SECTION_USER : GPO_SECTION_MACHINE),
  10128. &hKeyRoot) != S_OK)
  10129. {
  10130. DebugMsg((DM_WARNING, TEXT("CPolicySnapIn::InitializeSettingsControls: Failed to get registry key handle.")));
  10131. return S_FALSE;
  10132. }
  10133. }
  10134. for (nIndex=0;nIndex<pdi->nControls;nIndex++)
  10135. {
  10136. pSetting = pdi->pControlTable[nIndex].pSetting;
  10137. if (pdi->pControlTable[nIndex].uDataIndex != NO_DATA_INDEX)
  10138. {
  10139. switch (pdi->pControlTable[nIndex].dwType)
  10140. {
  10141. case STYPE_CHECKBOX:
  10142. if (fEnable)
  10143. {
  10144. CHECKBOXINFO * pcbi = (CHECKBOXINFO *) GETOBJECTDATAPTR(pSetting);
  10145. //
  10146. // First look for custom on/off values
  10147. //
  10148. dwTemp = 0;
  10149. fFound = FALSE;
  10150. dwFoundSettings = 0;
  10151. if (pcbi->uOffsetValue_On)
  10152. {
  10153. if (CompareCustomValue(hKeyRoot,GETKEYNAMEPTR(pSetting),GETVALUENAMEPTR(pSetting),
  10154. (STATEVALUE *) ((BYTE *) pSetting + pcbi->uOffsetValue_On),
  10155. &dwFoundSettings, NULL))
  10156. {
  10157. dwTemp = 1;
  10158. fFound = TRUE;
  10159. }
  10160. }
  10161. if (!fFound && pcbi->uOffsetValue_Off)
  10162. {
  10163. if (CompareCustomValue(hKeyRoot,GETKEYNAMEPTR(pSetting),GETVALUENAMEPTR(pSetting),
  10164. (STATEVALUE *) ((BYTE *) pSetting+ pcbi->uOffsetValue_Off),
  10165. &dwFoundSettings, NULL))
  10166. {
  10167. dwTemp = 0;
  10168. fFound = TRUE;
  10169. }
  10170. }
  10171. //
  10172. // Look for standard values if custom values have not been specified
  10173. //
  10174. if (!fFound &&
  10175. ReadStandardValue(hKeyRoot,GETKEYNAMEPTR(pSetting),GETVALUENAMEPTR(pSetting),
  10176. (TABLEENTRY*)pSetting,&dwTemp,&dwFoundSettings,NULL))
  10177. {
  10178. fFound = TRUE;
  10179. }
  10180. //
  10181. // If still not found, check for the def checked flag
  10182. //
  10183. if (!fFound)
  10184. {
  10185. if (pSetting->dwFlags & DF_USEDEFAULT)
  10186. {
  10187. fFound = TRUE;
  10188. dwTemp = 1;
  10189. }
  10190. }
  10191. if (fFound && dwTemp)
  10192. {
  10193. SendMessage(pdi->pControlTable[nIndex].hwnd,BM_SETCHECK,BST_CHECKED,0L);
  10194. }
  10195. else
  10196. {
  10197. SendMessage(pdi->pControlTable[nIndex].hwnd,BM_SETCHECK,BST_UNCHECKED,0L);
  10198. }
  10199. }
  10200. else
  10201. {
  10202. SendMessage(pdi->pControlTable[nIndex].hwnd,BM_SETCHECK,BST_UNCHECKED,0L);
  10203. }
  10204. break;
  10205. case STYPE_EDITTEXT:
  10206. case STYPE_COMBOBOX:
  10207. szBuffer[0] = TEXT('\0');
  10208. if (fEnable)
  10209. {
  10210. uRet = ReadRegistryStringValue(hKeyRoot,
  10211. GETKEYNAMEPTR(pSetting),
  10212. GETVALUENAMEPTR(pSetting),
  10213. szBuffer, ARRAYSIZE(szBuffer),NULL);
  10214. //
  10215. // Use default text if it exists
  10216. //
  10217. if (uRet != ERROR_SUCCESS)
  10218. {
  10219. if (pSetting->dwFlags & DF_USEDEFAULT)
  10220. {
  10221. LPTSTR pszDefaultText;
  10222. EDITTEXTINFO * peti = ((EDITTEXTINFO *) GETOBJECTDATAPTR(pSetting));
  10223. pszDefaultText = (LPTSTR) ((LPBYTE)pSetting + peti->uOffsetDefText);
  10224. lstrcpy (szBuffer, pszDefaultText);
  10225. }
  10226. }
  10227. }
  10228. SendMessage (pdi->pControlTable[nIndex].hwnd, WM_SETTEXT,
  10229. 0, (LPARAM) szBuffer);
  10230. break;
  10231. case STYPE_NUMERIC:
  10232. if (fEnable)
  10233. {
  10234. if (ReadStandardValue(hKeyRoot,GETKEYNAMEPTR(pSetting),GETVALUENAMEPTR(pSetting),
  10235. (TABLEENTRY*)pSetting,&dwTemp,&dwFoundSettings,NULL) &&
  10236. (!(dwFoundSettings & FS_DELETED)))
  10237. {
  10238. SetDlgItemInt(pdi->hwndSettings,nIndex+IDD_SETTINGCTRL,
  10239. dwTemp,FALSE);
  10240. }
  10241. else
  10242. {
  10243. if (pSetting->dwFlags & DF_USEDEFAULT)
  10244. {
  10245. NUMERICINFO * pni = (NUMERICINFO *)GETOBJECTDATAPTR(pSetting);
  10246. SetDlgItemInt(pdi->hwndSettings,nIndex+IDD_SETTINGCTRL,
  10247. pni->uDefValue,FALSE);
  10248. }
  10249. }
  10250. }
  10251. else
  10252. {
  10253. SendMessage(pdi->pControlTable[nIndex].hwnd,WM_SETTEXT,0,(LPARAM) g_szNull);
  10254. }
  10255. break;
  10256. case STYPE_DROPDOWNLIST:
  10257. if (fEnable)
  10258. {
  10259. dwData = 0;
  10260. dwFlags = 0;
  10261. if (ReadCustomValue(hKeyRoot,GETKEYNAMEPTR(pSetting),
  10262. GETVALUENAMEPTR(pSetting),
  10263. szBuffer,ARRAYSIZE(szBuffer),
  10264. &dwData,&dwFlags, NULL) && (!(dwFlags & VF_DELETE)))
  10265. {
  10266. BOOL fMatch = FALSE;
  10267. //
  10268. // Walk the list of DROPDOWNINFO structs (one for each state),
  10269. // and see if the value we found matches the value for the state
  10270. //
  10271. if (pSetting->uOffsetObjectData)
  10272. {
  10273. DROPDOWNINFO * pddi = (DROPDOWNINFO *) GETOBJECTDATAPTR(pSetting);
  10274. iSel = 0;
  10275. do {
  10276. if (dwFlags == pddi->dwFlags)
  10277. {
  10278. if (pddi->dwFlags & VF_ISNUMERIC)
  10279. {
  10280. if (dwData == pddi->dwValue)
  10281. fMatch = TRUE;
  10282. }
  10283. else if (!pddi->dwFlags)
  10284. {
  10285. if (!lstrcmpi(szBuffer,(TCHAR *)((BYTE *)pSetting +
  10286. pddi->uOffsetValue)))
  10287. fMatch = TRUE;
  10288. }
  10289. }
  10290. if (!pddi->uOffsetNextDropdowninfo || fMatch)
  10291. break;
  10292. pddi = (DROPDOWNINFO *) ( (BYTE *) pSetting +
  10293. pddi->uOffsetNextDropdowninfo);
  10294. iSel++;
  10295. } while (!fMatch);
  10296. if (fMatch) {
  10297. SendMessage (pdi->pControlTable[nIndex].hwnd,
  10298. CB_SETCURSEL,
  10299. FindComboboxItemData(pdi->pControlTable[nIndex].hwnd, iSel),0);
  10300. }
  10301. }
  10302. }
  10303. else
  10304. {
  10305. if (pSetting->dwFlags & DF_USEDEFAULT)
  10306. {
  10307. DROPDOWNINFO * pddi = (DROPDOWNINFO *)GETOBJECTDATAPTR(pSetting);
  10308. SendMessage (pdi->pControlTable[nIndex].hwnd, CB_SETCURSEL,
  10309. FindComboboxItemData(pdi->pControlTable[nIndex].hwnd, pddi->uDefaultItemIndex),0);
  10310. }
  10311. }
  10312. }
  10313. else
  10314. {
  10315. SendMessage(pdi->pControlTable[nIndex].hwnd,CB_SETCURSEL,(UINT) -1,0L);
  10316. }
  10317. break;
  10318. case STYPE_LISTBOX:
  10319. hData = (HGLOBAL) GetWindowLongPtr (pdi->pControlTable[nIndex].hwnd, GWLP_USERDATA);
  10320. if (fEnable)
  10321. {
  10322. if (!hData)
  10323. {
  10324. if (LoadListboxData((TABLEENTRY *) pSetting, hKeyRoot,
  10325. GETKEYNAMEPTR(pSetting),NULL,
  10326. &hData, NULL) == ERROR_SUCCESS)
  10327. {
  10328. SetWindowLongPtr (pdi->pControlTable[nIndex].hwnd, GWLP_USERDATA, (LONG_PTR)hData);
  10329. }
  10330. }
  10331. }
  10332. else
  10333. {
  10334. if (hData)
  10335. {
  10336. GlobalFree (hData);
  10337. SetWindowLongPtr (pdi->pControlTable[nIndex].hwnd, GWLP_USERDATA, 0);
  10338. }
  10339. }
  10340. break;
  10341. }
  10342. }
  10343. //
  10344. // Decide if the part should be enabled or not
  10345. //
  10346. // Special case text, numeric and listbox controls.
  10347. // When the policy is disabled, text controls should still be enabled.
  10348. // Numeric controls are special because they use the NO_DATA_INDEX
  10349. // flag, so we need to check for those. Listbox controls are special
  10350. // in RSOP only.
  10351. //
  10352. bChangeableState = TRUE;
  10353. if (pdi->pControlTable[nIndex].uDataIndex == NO_DATA_INDEX)
  10354. {
  10355. if (pdi->pControlTable[nIndex].dwType != (STYPE_TEXT | STYPE_NUMERIC))
  10356. {
  10357. bChangeableState = FALSE;
  10358. }
  10359. }
  10360. if (pdi->pControlTable[nIndex].dwType == STYPE_LISTBOX)
  10361. {
  10362. if (m_pcd->m_bRSOP)
  10363. {
  10364. bChangeableState = FALSE;
  10365. }
  10366. }
  10367. if (bChangeableState)
  10368. EnableWindow(pdi->pControlTable[nIndex].hwnd, (m_pcd->m_bRSOP ? FALSE : fEnable));
  10369. else
  10370. EnableWindow(pdi->pControlTable[nIndex].hwnd,TRUE);
  10371. }
  10372. if (!m_pcd->m_bRSOP)
  10373. {
  10374. RegCloseKey (hKeyRoot);
  10375. }
  10376. return S_OK;
  10377. }
  10378. VOID CPolicySnapIn::ShowListbox(HWND hParent,SETTINGS * pSettings)
  10379. {
  10380. LISTBOXDLGINFO ListboxDlgInfo;
  10381. ListboxDlgInfo.pCS = this;
  10382. ListboxDlgInfo.pSettings = pSettings;
  10383. ListboxDlgInfo.hData = (HGLOBAL)GetWindowLongPtr (hParent, GWLP_USERDATA);
  10384. if (DialogBoxParam(g_hInstance,MAKEINTRESOURCE(IDD_POLICY_SHOWLISTBOX),hParent,
  10385. ShowListboxDlgProc,(LPARAM) &ListboxDlgInfo))
  10386. {
  10387. SetWindowLongPtr (hParent, GWLP_USERDATA, (LONG_PTR) ListboxDlgInfo.hData);
  10388. }
  10389. }
  10390. INT_PTR CALLBACK CPolicySnapIn::ShowListboxDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam,
  10391. LPARAM lParam)
  10392. {
  10393. switch (uMsg) {
  10394. case WM_INITDIALOG:
  10395. {
  10396. LISTBOXDLGINFO * pLBInfo = (LISTBOXDLGINFO *)lParam;
  10397. //
  10398. // Store away pointer to ListboxDlgInfo in window data
  10399. //
  10400. SetWindowLongPtr(hDlg,DWLP_USER,lParam);
  10401. if (!pLBInfo->pCS->InitShowlistboxDlg(hDlg)) {
  10402. pLBInfo->pCS->m_pcd->MsgBox(hDlg,IDS_ErrOUTOFMEMORY,MB_ICONEXCLAMATION,MB_OK);
  10403. EndDialog(hDlg,FALSE);
  10404. }
  10405. }
  10406. return TRUE;
  10407. case WM_COMMAND:
  10408. switch (wParam) {
  10409. case IDOK:
  10410. {
  10411. LISTBOXDLGINFO * pListboxDlgInfo =
  10412. (LISTBOXDLGINFO *) GetWindowLongPtr(hDlg,DWLP_USER);
  10413. if (!pListboxDlgInfo->pCS->m_pcd->m_bRSOP)
  10414. {
  10415. if (!pListboxDlgInfo->pCS->ProcessShowlistboxDlg(hDlg)) {
  10416. pListboxDlgInfo->pCS->m_pcd->MsgBox(hDlg,IDS_ErrOUTOFMEMORY,MB_ICONEXCLAMATION,MB_OK);
  10417. return FALSE;
  10418. }
  10419. }
  10420. EndDialog(hDlg,TRUE);
  10421. }
  10422. break;
  10423. case IDCANCEL:
  10424. EndDialog(hDlg,FALSE);
  10425. break;
  10426. case IDC_POLICY_ADD:
  10427. {
  10428. LISTBOXDLGINFO * pListboxDlgInfo =
  10429. (LISTBOXDLGINFO *) GetWindowLongPtr(hDlg,DWLP_USER);
  10430. pListboxDlgInfo->pCS->ListboxAdd(GetDlgItem(hDlg,IDC_POLICY_LISTBOX), (BOOL)
  10431. pListboxDlgInfo->pSettings->dwFlags & DF_EXPLICITVALNAME,
  10432. (BOOL)( ((LISTBOXINFO *)
  10433. GETOBJECTDATAPTR(pListboxDlgInfo->pSettings))->
  10434. uOffsetPrefix));
  10435. }
  10436. break;
  10437. case IDC_POLICY_REMOVE:
  10438. {
  10439. LISTBOXDLGINFO * pListboxDlgInfo =
  10440. (LISTBOXDLGINFO *) GetWindowLongPtr(hDlg,DWLP_USER);
  10441. pListboxDlgInfo->pCS->ListboxRemove(hDlg,GetDlgItem(hDlg,IDC_POLICY_LISTBOX));
  10442. }
  10443. break;
  10444. }
  10445. break;
  10446. case WM_NOTIFY:
  10447. if (wParam == IDC_POLICY_LISTBOX) {
  10448. if (((NMHDR FAR*)lParam)->code == LVN_ITEMCHANGED) {
  10449. LISTBOXDLGINFO * pListboxDlgInfo =
  10450. (LISTBOXDLGINFO *) GetWindowLongPtr(hDlg,DWLP_USER);
  10451. if (!pListboxDlgInfo->pCS->m_pcd->m_bRSOP)
  10452. {
  10453. pListboxDlgInfo->pCS->EnableShowListboxButtons(hDlg);
  10454. }
  10455. }
  10456. }
  10457. break;
  10458. }
  10459. return FALSE;
  10460. }
  10461. BOOL CPolicySnapIn::InitShowlistboxDlg(HWND hDlg)
  10462. {
  10463. LISTBOXDLGINFO * pListboxDlgInfo;
  10464. SETTINGS * pSettings;
  10465. LV_COLUMN lvc;
  10466. RECT rcListbox;
  10467. UINT uColWidth,uOffsetData;
  10468. HWND hwndListbox;
  10469. BOOL fSuccess=TRUE;
  10470. LONG lStyle;
  10471. TCHAR szBuffer[SMALLBUF];
  10472. LPTSTR lpData;
  10473. pListboxDlgInfo = (LISTBOXDLGINFO *)GetWindowLongPtr (hDlg, DWLP_USER);
  10474. if (!pListboxDlgInfo)
  10475. return FALSE;
  10476. pSettings = pListboxDlgInfo->pSettings;
  10477. hwndListbox = GetDlgItem(hDlg,IDC_POLICY_LISTBOX);
  10478. //
  10479. // Turn off the header if we don't need it
  10480. //
  10481. if (!m_pcd->m_bRSOP)
  10482. {
  10483. if (!(pSettings->dwFlags & DF_EXPLICITVALNAME))
  10484. {
  10485. lStyle = GetWindowLong (hwndListbox, GWL_STYLE);
  10486. lStyle |= LVS_NOCOLUMNHEADER;
  10487. SetWindowLong (hwndListbox, GWL_STYLE, lStyle);
  10488. }
  10489. }
  10490. SendMessage(hwndListbox, LVM_SETEXTENDEDLISTVIEWSTYLE, 0,
  10491. LVS_EX_FULLROWSELECT | LVS_EX_LABELTIP);
  10492. //
  10493. // Set the setting title in the dialog
  10494. //
  10495. SetDlgItemText(hDlg,IDC_POLICY_TITLE,GETNAMEPTR(pSettings));
  10496. GetClientRect(hwndListbox,&rcListbox);
  10497. uColWidth = rcListbox.right-rcListbox.left;
  10498. if (m_pcd->m_bRSOP)
  10499. {
  10500. if (pSettings->dwFlags & DF_EXPLICITVALNAME)
  10501. {
  10502. uColWidth /= 3;
  10503. }
  10504. else
  10505. {
  10506. uColWidth /= 2;
  10507. }
  10508. }
  10509. else
  10510. {
  10511. if (pSettings->dwFlags & DF_EXPLICITVALNAME)
  10512. {
  10513. uColWidth /= 2;
  10514. }
  10515. }
  10516. if (pSettings->dwFlags & DF_EXPLICITVALNAME) {
  10517. //
  10518. // add a 2nd column to the listview control
  10519. //
  10520. LoadString(g_hInstance,IDS_VALUENAME,szBuffer,ARRAYSIZE(szBuffer));
  10521. lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
  10522. lvc.fmt = LVCFMT_LEFT;
  10523. lvc.cx = uColWidth-1;
  10524. lvc.pszText = szBuffer;
  10525. lvc.cchTextMax = lstrlen(lvc.pszText)+1;
  10526. lvc.iSubItem = 0;
  10527. ListView_InsertColumn(hwndListbox,0,&lvc);
  10528. }
  10529. //
  10530. // Add a column to the listview control
  10531. //
  10532. LoadString(g_hInstance,IDS_VALUE,szBuffer,ARRAYSIZE(szBuffer));
  10533. lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
  10534. lvc.fmt = LVCFMT_LEFT;
  10535. lvc.cx = uColWidth;
  10536. lvc.pszText = szBuffer;
  10537. lvc.cchTextMax = lstrlen(lvc.pszText)+1;
  10538. lvc.iSubItem = (pSettings->dwFlags & DF_EXPLICITVALNAME ? 1 : 0);
  10539. ListView_InsertColumn(hwndListbox,lvc.iSubItem,&lvc);
  10540. if (m_pcd->m_bRSOP)
  10541. {
  10542. //
  10543. // Add the GPO Name column to the listview control
  10544. //
  10545. LoadString(g_hInstance,IDS_GPONAME,szBuffer,ARRAYSIZE(szBuffer));
  10546. lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
  10547. lvc.fmt = LVCFMT_LEFT;
  10548. lvc.cx = uColWidth;
  10549. lvc.pszText = szBuffer;
  10550. lvc.cchTextMax = lstrlen(lvc.pszText)+1;
  10551. lvc.iSubItem = (pSettings->dwFlags & DF_EXPLICITVALNAME ? 2 : 1);
  10552. ListView_InsertColumn(hwndListbox,lvc.iSubItem,&lvc);
  10553. }
  10554. if (m_pcd->m_bRSOP)
  10555. {
  10556. EnableWindow(GetDlgItem(hDlg,IDC_POLICY_REMOVE), FALSE);
  10557. EnableWindow(GetDlgItem(hDlg,IDC_POLICY_ADD), FALSE);
  10558. }
  10559. else
  10560. {
  10561. EnableShowListboxButtons(hDlg);
  10562. }
  10563. if (pListboxDlgInfo->hData)
  10564. {
  10565. //
  10566. // Insert the items from user's data buffer into the listbox
  10567. //
  10568. if ((lpData = (LPTSTR) GlobalLock(pListboxDlgInfo->hData)))
  10569. {
  10570. while (*lpData && fSuccess) {
  10571. LV_ITEM lvi;
  10572. lvi.pszText=lpData;
  10573. lvi.mask = LVIF_TEXT;
  10574. lvi.iItem=-1;
  10575. lvi.iSubItem=0;
  10576. lvi.cchTextMax = lstrlen(lpData)+1;
  10577. fSuccess=((lvi.iItem=ListView_InsertItem(hwndListbox,&lvi)) >= 0);
  10578. lpData += lstrlen(lpData) +1;
  10579. // if explicit valuename flag set, entries are stored
  10580. // <value name>\0<value>\0....<value name>\0<value>\0\0
  10581. // otherwise, entries are stored
  10582. // <value>\0<value>\0....<value>\0
  10583. if (pSettings->dwFlags & DF_EXPLICITVALNAME) {
  10584. if (fSuccess) {
  10585. if (*lpData) {
  10586. lvi.iSubItem=1;
  10587. lvi.pszText=lpData;
  10588. lvi.cchTextMax = lstrlen(lpData)+1;
  10589. fSuccess=(ListView_SetItem(hwndListbox,&lvi) >= 0);
  10590. }
  10591. lpData += lstrlen(lpData) +1;
  10592. }
  10593. }
  10594. if (m_pcd->m_bRSOP) {
  10595. if (fSuccess) {
  10596. if (*lpData) {
  10597. lvi.iSubItem=(pSettings->dwFlags & DF_EXPLICITVALNAME) ? 2 : 1;
  10598. lvi.pszText=lpData;
  10599. lvi.cchTextMax = lstrlen(lpData)+1;
  10600. fSuccess=(ListView_SetItem(hwndListbox,&lvi) >= 0);
  10601. }
  10602. lpData += lstrlen(lpData) +1;
  10603. }
  10604. }
  10605. }
  10606. GlobalUnlock(pListboxDlgInfo->hData);
  10607. }
  10608. else
  10609. {
  10610. fSuccess = FALSE;
  10611. }
  10612. }
  10613. return fSuccess;
  10614. }
  10615. BOOL CPolicySnapIn::ProcessShowlistboxDlg(HWND hDlg)
  10616. {
  10617. LISTBOXDLGINFO * pListboxDlgInfo = (LISTBOXDLGINFO *)
  10618. GetWindowLongPtr(hDlg,DWLP_USER); // get pointer to struct from window data
  10619. DWORD dwAlloc=1024 * sizeof(TCHAR),dwUsed=0;
  10620. HGLOBAL hBuf;
  10621. TCHAR * pBuf;
  10622. HWND hwndListbox = GetDlgItem(hDlg,IDC_POLICY_LISTBOX);
  10623. LV_ITEM lvi;
  10624. UINT nLen;
  10625. int nCount;
  10626. TCHAR pszText[MAX_PATH+1];
  10627. // allocate a temp buffer to read entries into
  10628. if (!(hBuf = GlobalAlloc(GHND,dwAlloc)) ||
  10629. !(pBuf = (TCHAR *) GlobalLock(hBuf))) {
  10630. if (hBuf)
  10631. GlobalFree(hBuf);
  10632. return FALSE;
  10633. }
  10634. lvi.mask = LVIF_TEXT;
  10635. lvi.iItem=0;
  10636. lvi.pszText = pszText;
  10637. lvi.cchTextMax = ARRAYSIZE(pszText);
  10638. nCount = ListView_GetItemCount(hwndListbox);
  10639. // retrieve the items out of listbox, pack into temp buffer
  10640. for (;lvi.iItem<nCount;lvi.iItem ++) {
  10641. lvi.iSubItem = 0;
  10642. if (ListView_GetItem(hwndListbox,&lvi)) {
  10643. nLen = lstrlen(lvi.pszText) + 1;
  10644. if (!(pBuf=ResizeBuffer(pBuf,hBuf,(dwUsed+nLen+4) * sizeof(TCHAR),&dwAlloc)))
  10645. return ERROR_NOT_ENOUGH_MEMORY;
  10646. lstrcpy(pBuf+dwUsed,lvi.pszText);
  10647. dwUsed += nLen;
  10648. }
  10649. if (pListboxDlgInfo->pSettings->dwFlags & DF_EXPLICITVALNAME) {
  10650. lvi.iSubItem = 1;
  10651. if (ListView_GetItem(hwndListbox,&lvi)) {
  10652. nLen = lstrlen(lvi.pszText) + 1;
  10653. if (!(pBuf=ResizeBuffer(pBuf,hBuf,(dwUsed+nLen+4) * sizeof(TCHAR),&dwAlloc)))
  10654. return ERROR_NOT_ENOUGH_MEMORY;
  10655. lstrcpy(pBuf+dwUsed,lvi.pszText);
  10656. dwUsed += nLen;
  10657. }
  10658. }
  10659. }
  10660. // doubly null-terminate the buffer... safe to do this because we
  10661. // tacked on the extra "+4" in the ResizeBuffer calls above
  10662. *(pBuf+dwUsed) = TEXT('\0');
  10663. dwUsed ++;
  10664. GlobalUnlock(hBuf);
  10665. if (pListboxDlgInfo->hData)
  10666. {
  10667. GlobalFree (pListboxDlgInfo->hData);
  10668. }
  10669. pListboxDlgInfo->hData = hBuf;
  10670. return TRUE;
  10671. }
  10672. VOID CPolicySnapIn::EnableShowListboxButtons(HWND hDlg)
  10673. {
  10674. BOOL fEnable;
  10675. // enable Remove button if there are any items selected
  10676. fEnable = (ListView_GetNextItem(GetDlgItem(hDlg,IDC_POLICY_LISTBOX),
  10677. -1,LVNI_SELECTED) >= 0);
  10678. EnableWindow(GetDlgItem(hDlg,IDC_POLICY_REMOVE),fEnable);
  10679. }
  10680. VOID CPolicySnapIn::ListboxRemove(HWND hDlg,HWND hwndListbox)
  10681. {
  10682. int nItem;
  10683. while ( (nItem=ListView_GetNextItem(hwndListbox,-1,LVNI_SELECTED))
  10684. >= 0) {
  10685. ListView_DeleteItem(hwndListbox,nItem);
  10686. }
  10687. EnableShowListboxButtons(hDlg);
  10688. }
  10689. VOID CPolicySnapIn::ListboxAdd(HWND hwndListbox, BOOL fExplicitValName,BOOL fValuePrefix)
  10690. {
  10691. ADDITEMINFO AddItemInfo;
  10692. LV_ITEM lvi;
  10693. ZeroMemory(&AddItemInfo,sizeof(AddItemInfo));
  10694. AddItemInfo.pCS = this;
  10695. AddItemInfo.fExplicitValName = fExplicitValName;
  10696. AddItemInfo.fValPrefix = fValuePrefix;
  10697. AddItemInfo.hwndListbox = hwndListbox;
  10698. //
  10699. // Bring up the appropriate add dialog-- one edit field ("type the thing
  10700. // to add") normally, two edit fields ("type the name of the thing, type
  10701. // the value of the thing") if the explicit value style is used
  10702. //
  10703. if (!DialogBoxParam(g_hInstance,MAKEINTRESOURCE((fExplicitValName ? IDD_POLICY_LBADD2 :
  10704. IDD_POLICY_LBADD)),hwndListbox,ListboxAddDlgProc,(LPARAM) &AddItemInfo))
  10705. return; // user cancelled
  10706. // add the item to the listbox
  10707. lvi.mask = LVIF_TEXT;
  10708. lvi.iItem=lvi.iSubItem=0;
  10709. lvi.pszText=(fExplicitValName ? AddItemInfo.szValueName :
  10710. AddItemInfo.szValueData);
  10711. lvi.cchTextMax = lstrlen(lvi.pszText)+1;
  10712. if ((lvi.iItem=ListView_InsertItem(hwndListbox,&lvi))<0) {
  10713. // if add fails, display out of memory error
  10714. m_pcd->MsgBox(hwndListbox,IDS_ErrOUTOFMEMORY,MB_ICONEXCLAMATION,MB_OK);
  10715. return;
  10716. }
  10717. if (fExplicitValName) {
  10718. lvi.iSubItem=1;
  10719. lvi.pszText=AddItemInfo.szValueData;
  10720. lvi.cchTextMax = lstrlen(lvi.pszText)+1;
  10721. if (ListView_SetItem(hwndListbox,&lvi) < 0) {
  10722. m_pcd->MsgBox(hwndListbox,IDS_ErrOUTOFMEMORY,MB_ICONEXCLAMATION,MB_OK);
  10723. return;
  10724. }
  10725. }
  10726. }
  10727. INT_PTR CALLBACK CPolicySnapIn::ListboxAddDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam,
  10728. LPARAM lParam)
  10729. {
  10730. switch (uMsg) {
  10731. case WM_INITDIALOG:
  10732. {
  10733. ADDITEMINFO * pAddItemInfo = (ADDITEMINFO *)lParam;
  10734. // store away pointer to additeminfo in window data
  10735. SetWindowLongPtr(hDlg,DWLP_USER,lParam);
  10736. SendDlgItemMessage(hDlg,IDC_POLICY_VALUENAME,EM_LIMITTEXT,MAX_PATH,0L);
  10737. SendDlgItemMessage(hDlg,IDC_POLICY_VALUEDATA,EM_LIMITTEXT,MAX_PATH,0L);
  10738. if (!pAddItemInfo->fExplicitValName) {
  10739. ShowWindow (GetDlgItem (hDlg, IDC_POLICY_VALUENAME), SW_HIDE);
  10740. }
  10741. }
  10742. break;
  10743. case WM_COMMAND:
  10744. switch (wParam) {
  10745. case IDOK:
  10746. {
  10747. ADDITEMINFO * pAddItemInfo = (ADDITEMINFO *)
  10748. GetWindowLongPtr(hDlg,DWLP_USER);
  10749. GetDlgItemText(hDlg,IDC_POLICY_VALUENAME,
  10750. pAddItemInfo->szValueName,
  10751. ARRAYSIZE(pAddItemInfo->szValueName));
  10752. GetDlgItemText(hDlg,IDC_POLICY_VALUEDATA,
  10753. pAddItemInfo->szValueData,
  10754. ARRAYSIZE(pAddItemInfo->szValueData));
  10755. // if explicit value names used, value name must
  10756. // not be empty, and it must be unique
  10757. if (pAddItemInfo->fExplicitValName) {
  10758. LV_FINDINFO lvfi;
  10759. int iSel;
  10760. if (!lstrlen(pAddItemInfo->szValueName)) {
  10761. // can't be empty
  10762. pAddItemInfo->pCS->m_pcd->MsgBox(hDlg,IDS_EMPTYVALUENAME,
  10763. MB_ICONINFORMATION,MB_OK);
  10764. SetFocus(GetDlgItem(hDlg,IDC_POLICY_VALUENAME));
  10765. return FALSE;
  10766. }
  10767. lvfi.flags = LVFI_STRING;
  10768. lvfi.psz = pAddItemInfo->szValueName;
  10769. iSel=ListView_FindItem(pAddItemInfo->hwndListbox,
  10770. -1,&lvfi);
  10771. if (iSel >= 0) {
  10772. // value name already used
  10773. pAddItemInfo->pCS->m_pcd->MsgBox(hDlg,IDS_VALUENAMENOTUNIQUE,
  10774. MB_ICONINFORMATION,MB_OK);
  10775. SetFocus(GetDlgItem(hDlg,IDC_POLICY_VALUENAME));
  10776. SendDlgItemMessage(hDlg,IDC_POLICY_VALUENAME,
  10777. EM_SETSEL,0,-1);
  10778. return FALSE;
  10779. }
  10780. } else if (!pAddItemInfo->fValPrefix) {
  10781. // if value name == value data, then value data
  10782. // must be unique
  10783. LV_FINDINFO lvfi;
  10784. int iSel;
  10785. if (!lstrlen(pAddItemInfo->szValueData)) {
  10786. // can't be empty
  10787. pAddItemInfo->pCS->m_pcd->MsgBox(hDlg,IDS_EMPTYVALUEDATA,
  10788. MB_ICONINFORMATION,MB_OK);
  10789. SetFocus(GetDlgItem(hDlg,IDC_POLICY_VALUEDATA));
  10790. return FALSE;
  10791. }
  10792. lvfi.flags = LVFI_STRING;
  10793. lvfi.psz = pAddItemInfo->szValueData;
  10794. iSel=ListView_FindItem(pAddItemInfo->hwndListbox,
  10795. -1,&lvfi);
  10796. if (iSel >= 0) {
  10797. // value name already used
  10798. pAddItemInfo->pCS->m_pcd->MsgBox(hDlg,IDS_VALUEDATANOTUNIQUE,
  10799. MB_ICONINFORMATION,MB_OK);
  10800. SetFocus(GetDlgItem(hDlg,IDC_POLICY_VALUEDATA));
  10801. SendDlgItemMessage(hDlg,IDC_POLICY_VALUEDATA,
  10802. EM_SETSEL,0,-1);
  10803. return FALSE;
  10804. }
  10805. }
  10806. else
  10807. {
  10808. if (!lstrlen(pAddItemInfo->szValueData)) {
  10809. // can't be empty
  10810. pAddItemInfo->pCS->m_pcd->MsgBox(hDlg,IDS_EMPTYVALUEDATA,
  10811. MB_ICONINFORMATION,MB_OK);
  10812. SetFocus(GetDlgItem(hDlg,IDC_POLICY_VALUEDATA));
  10813. return FALSE;
  10814. }
  10815. }
  10816. EndDialog(hDlg,TRUE);
  10817. }
  10818. break;
  10819. case IDCANCEL:
  10820. EndDialog(hDlg,FALSE);
  10821. break;
  10822. }
  10823. break;
  10824. }
  10825. return FALSE;
  10826. }
  10827. void CPolicySnapIn::InitializeFilterDialog (HWND hDlg)
  10828. {
  10829. INT iIndex;
  10830. RECT rect;
  10831. LV_COLUMN lvcol;
  10832. LONG lWidth;
  10833. DWORD dwCount = 0;
  10834. HWND hList = GetDlgItem(hDlg, IDC_FILTERLIST);
  10835. LPSUPPORTEDENTRY lpTemp;
  10836. LVITEM item;
  10837. //
  10838. // Count the number of Supported On strings
  10839. //
  10840. lpTemp = m_pcd->m_pSupportedStrings;
  10841. while (lpTemp)
  10842. {
  10843. lpTemp = lpTemp->pNext;
  10844. dwCount++;
  10845. }
  10846. //
  10847. // Decide on the column width
  10848. //
  10849. GetClientRect(hList, &rect);
  10850. if (dwCount > (DWORD)ListView_GetCountPerPage(hList))
  10851. {
  10852. lWidth = (rect.right - rect.left) - GetSystemMetrics(SM_CYHSCROLL);
  10853. }
  10854. else
  10855. {
  10856. lWidth = rect.right - rect.left;
  10857. }
  10858. //
  10859. // Insert the first column
  10860. //
  10861. memset(&lvcol, 0, sizeof(lvcol));
  10862. lvcol.mask = LVCF_FMT | LVCF_WIDTH;
  10863. lvcol.fmt = LVCFMT_LEFT;
  10864. lvcol.cx = lWidth;
  10865. ListView_InsertColumn(hList, 0, &lvcol);
  10866. //
  10867. // Turn on some listview features
  10868. //
  10869. SendMessage(hList, LVM_SETEXTENDEDLISTVIEWSTYLE, 0,
  10870. LVS_EX_FULLROWSELECT | LVS_EX_LABELTIP | LVS_EX_CHECKBOXES);
  10871. //
  10872. // Insert the Supported On strings
  10873. //
  10874. lpTemp = m_pcd->m_pSupportedStrings;
  10875. while (lpTemp)
  10876. {
  10877. ZeroMemory (&item, sizeof(item));
  10878. item.mask = LVIF_TEXT | LVIF_PARAM;
  10879. item.iItem = 0;
  10880. item.pszText = lpTemp->lpString;
  10881. item.lParam = (LPARAM) lpTemp;
  10882. iIndex = ListView_InsertItem (hList, &item);
  10883. if (iIndex > -1)
  10884. {
  10885. ZeroMemory (&item, sizeof(item));
  10886. item.mask = LVIF_STATE;
  10887. item.state = lpTemp->bEnabled ? INDEXTOSTATEIMAGEMASK(2) : INDEXTOSTATEIMAGEMASK(1);
  10888. item.stateMask = LVIS_STATEIMAGEMASK;
  10889. SendMessage (hList, LVM_SETITEMSTATE, (WPARAM)iIndex, (LPARAM)&item);
  10890. }
  10891. lpTemp = lpTemp->pNext;
  10892. }
  10893. //
  10894. // Select the first item
  10895. //
  10896. item.mask = LVIF_STATE;
  10897. item.iItem = 0;
  10898. item.iSubItem = 0;
  10899. item.state = LVIS_SELECTED | LVIS_FOCUSED;
  10900. item.stateMask = LVIS_SELECTED | LVIS_FOCUSED;
  10901. SendMessage (hList, LVM_SETITEMSTATE, 0, (LPARAM) &item);
  10902. //
  10903. // Initialize the checkboxes
  10904. //
  10905. if (m_pcd->m_bUseSupportedOnFilter)
  10906. {
  10907. CheckDlgButton (hDlg, IDC_SUPPORTEDOPTION, BST_CHECKED);
  10908. }
  10909. else
  10910. {
  10911. EnableWindow (GetDlgItem (hDlg, IDC_SUPPORTEDONTITLE), FALSE);
  10912. EnableWindow (GetDlgItem (hDlg, IDC_FILTERLIST), FALSE);
  10913. EnableWindow (GetDlgItem (hDlg, IDC_SELECTALL), FALSE);
  10914. EnableWindow (GetDlgItem (hDlg, IDC_DESELECTALL), FALSE);
  10915. }
  10916. if (m_pcd->m_bShowConfigPoliciesOnly)
  10917. {
  10918. CheckDlgButton (hDlg, IDC_SHOWCONFIG, BST_CHECKED);
  10919. }
  10920. if ((m_dwPolicyOnlyPolicy == 0) || (m_dwPolicyOnlyPolicy == 1))
  10921. {
  10922. if (m_dwPolicyOnlyPolicy == 1)
  10923. {
  10924. CheckDlgButton (hDlg, IDC_SHOWPOLICIES, BST_CHECKED);
  10925. }
  10926. EnableWindow (GetDlgItem (hDlg, IDC_SHOWPOLICIES), FALSE);
  10927. }
  10928. else
  10929. {
  10930. if (m_bPolicyOnly)
  10931. {
  10932. CheckDlgButton (hDlg, IDC_SHOWPOLICIES, BST_CHECKED);
  10933. }
  10934. }
  10935. }
  10936. INT_PTR CALLBACK CPolicySnapIn::FilterDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam,
  10937. LPARAM lParam)
  10938. {
  10939. CPolicySnapIn * pCS;
  10940. switch (uMsg)
  10941. {
  10942. case WM_INITDIALOG:
  10943. pCS = (CPolicySnapIn *) lParam;
  10944. SetWindowLongPtr (hDlg, DWLP_USER, (LONG_PTR) pCS);
  10945. if (pCS)
  10946. {
  10947. pCS->InitializeFilterDialog(hDlg);
  10948. }
  10949. break;
  10950. case WM_COMMAND:
  10951. switch (wParam)
  10952. {
  10953. case IDC_SUPPORTEDOPTION:
  10954. if (IsDlgButtonChecked (hDlg, IDC_SUPPORTEDOPTION) == BST_CHECKED)
  10955. {
  10956. EnableWindow (GetDlgItem (hDlg, IDC_SUPPORTEDONTITLE), TRUE);
  10957. EnableWindow (GetDlgItem (hDlg, IDC_FILTERLIST), TRUE);
  10958. EnableWindow (GetDlgItem (hDlg, IDC_SELECTALL), TRUE);
  10959. EnableWindow (GetDlgItem (hDlg, IDC_DESELECTALL), TRUE);
  10960. }
  10961. else
  10962. {
  10963. EnableWindow (GetDlgItem (hDlg, IDC_SUPPORTEDONTITLE), FALSE);
  10964. EnableWindow (GetDlgItem (hDlg, IDC_FILTERLIST), FALSE);
  10965. EnableWindow (GetDlgItem (hDlg, IDC_SELECTALL), FALSE);
  10966. EnableWindow (GetDlgItem (hDlg, IDC_DESELECTALL), FALSE);
  10967. }
  10968. break;
  10969. case IDC_SELECTALL:
  10970. {
  10971. LVITEM item;
  10972. ZeroMemory (&item, sizeof(item));
  10973. item.mask = LVIF_STATE;
  10974. item.state = INDEXTOSTATEIMAGEMASK(2);
  10975. item.stateMask = LVIS_STATEIMAGEMASK;
  10976. SendMessage (GetDlgItem (hDlg, IDC_FILTERLIST), LVM_SETITEMSTATE, (WPARAM)-1, (LPARAM)&item);
  10977. }
  10978. break;
  10979. case IDC_DESELECTALL:
  10980. {
  10981. LVITEM item;
  10982. ZeroMemory (&item, sizeof(item));
  10983. item.mask = LVIF_STATE;
  10984. item.state = INDEXTOSTATEIMAGEMASK(1);
  10985. item.stateMask = LVIS_STATEIMAGEMASK;
  10986. SendMessage (GetDlgItem (hDlg, IDC_FILTERLIST), LVM_SETITEMSTATE, (WPARAM)-1, (LPARAM)&item);
  10987. }
  10988. break;
  10989. case IDOK:
  10990. {
  10991. LVITEM item;
  10992. INT iIndex = 0;
  10993. LPSUPPORTEDENTRY lpItem;
  10994. pCS = (CPolicySnapIn *) GetWindowLongPtr(hDlg,DWLP_USER);
  10995. if (!pCS)
  10996. {
  10997. break;
  10998. }
  10999. if (IsDlgButtonChecked (hDlg, IDC_SUPPORTEDOPTION) == BST_CHECKED)
  11000. {
  11001. pCS->m_pcd->m_bUseSupportedOnFilter = TRUE;
  11002. while (TRUE)
  11003. {
  11004. ZeroMemory (&item, sizeof(item));
  11005. item.mask = LVIF_PARAM | LVIF_STATE;
  11006. item.iItem = iIndex;
  11007. item.stateMask = LVIS_STATEIMAGEMASK;
  11008. if (!ListView_GetItem (GetDlgItem (hDlg, IDC_FILTERLIST), &item))
  11009. {
  11010. break;
  11011. }
  11012. lpItem = (LPSUPPORTEDENTRY) item.lParam;
  11013. if (lpItem)
  11014. {
  11015. if (item.state == INDEXTOSTATEIMAGEMASK(2))
  11016. {
  11017. lpItem->bEnabled = TRUE;
  11018. }
  11019. else
  11020. {
  11021. lpItem->bEnabled = FALSE;
  11022. }
  11023. }
  11024. iIndex++;
  11025. }
  11026. }
  11027. else
  11028. {
  11029. pCS->m_pcd->m_bUseSupportedOnFilter = FALSE;
  11030. }
  11031. if (IsDlgButtonChecked (hDlg, IDC_SHOWCONFIG) == BST_CHECKED)
  11032. {
  11033. pCS->m_pcd->m_bShowConfigPoliciesOnly = TRUE;
  11034. }
  11035. else
  11036. {
  11037. pCS->m_pcd->m_bShowConfigPoliciesOnly = FALSE;
  11038. }
  11039. if (IsDlgButtonChecked (hDlg, IDC_SHOWPOLICIES) == BST_CHECKED)
  11040. {
  11041. pCS->m_bPolicyOnly = TRUE;
  11042. }
  11043. else
  11044. {
  11045. pCS->m_bPolicyOnly = FALSE;
  11046. }
  11047. EndDialog(hDlg,TRUE);
  11048. }
  11049. break;
  11050. case IDCANCEL:
  11051. EndDialog(hDlg,FALSE);
  11052. break;
  11053. }
  11054. break;
  11055. case WM_NOTIFY:
  11056. pCS = (CPolicySnapIn *) GetWindowLongPtr (hDlg, DWLP_USER);
  11057. if (!pCS) {
  11058. break;
  11059. }
  11060. switch (((NMHDR FAR*)lParam)->code)
  11061. {
  11062. case LVN_ITEMACTIVATE:
  11063. {
  11064. LPNMITEMACTIVATE pItem = (LPNMITEMACTIVATE) lParam;
  11065. LPSUPPORTEDENTRY lpItem;
  11066. LVITEM item;
  11067. HWND hLV = GetDlgItem(hDlg, IDC_FILTERLIST);
  11068. ZeroMemory (&item, sizeof(item));
  11069. item.mask = LVIF_STATE | LVIF_PARAM;
  11070. item.iItem = pItem->iItem;
  11071. item.stateMask = LVIS_STATEIMAGEMASK;
  11072. if (!ListView_GetItem (hLV, &item))
  11073. {
  11074. break;
  11075. }
  11076. lpItem = (LPSUPPORTEDENTRY) item.lParam;
  11077. if (!lpItem)
  11078. {
  11079. break;
  11080. }
  11081. if (lpItem)
  11082. {
  11083. if (item.state == INDEXTOSTATEIMAGEMASK(2))
  11084. {
  11085. item.state = INDEXTOSTATEIMAGEMASK(1);
  11086. }
  11087. else
  11088. {
  11089. item.state = INDEXTOSTATEIMAGEMASK(2);
  11090. }
  11091. item.mask = LVIF_STATE;
  11092. SendMessage (hLV, LVM_SETITEMSTATE, (WPARAM)pItem->iItem, (LPARAM)&item);
  11093. }
  11094. }
  11095. }
  11096. break;
  11097. case WM_HELP: // F1
  11098. WinHelp((HWND)((LPHELPINFO) lParam)->hItemHandle, HELP_FILE, HELP_WM_HELP,
  11099. (DWORD_PTR) (LPSTR) aFilteringHelpIds);
  11100. break;
  11101. case WM_CONTEXTMENU: // right mouse click
  11102. WinHelp((HWND) wParam, HELP_FILE, HELP_CONTEXTMENU,
  11103. (DWORD_PTR) (LPSTR) aFilteringHelpIds);
  11104. return (TRUE);
  11105. }
  11106. return FALSE;
  11107. }
  11108. unsigned int CPolicyDataObject::m_cfNodeType = RegisterClipboardFormat(CCF_NODETYPE);
  11109. unsigned int CPolicyDataObject::m_cfNodeTypeString = RegisterClipboardFormat(CCF_SZNODETYPE);
  11110. unsigned int CPolicyDataObject::m_cfDisplayName = RegisterClipboardFormat(CCF_DISPLAY_NAME);
  11111. unsigned int CPolicyDataObject::m_cfCoClass = RegisterClipboardFormat(CCF_SNAPIN_CLASSID);
  11112. unsigned int CPolicyDataObject::m_cfDescription = RegisterClipboardFormat(L"CCF_DESCRIPTION");
  11113. unsigned int CPolicyDataObject::m_cfHTMLDetails = RegisterClipboardFormat(L"CCF_HTML_DETAILS");
  11114. ///////////////////////////////////////////////////////////////////////////////
  11115. // //
  11116. // CPolicyDataObject implementation //
  11117. // //
  11118. ///////////////////////////////////////////////////////////////////////////////
  11119. CPolicyDataObject::CPolicyDataObject(CPolicyComponentData *pComponent)
  11120. {
  11121. m_cRef = 1;
  11122. InterlockedIncrement(&g_cRefThisDll);
  11123. m_pcd = pComponent;
  11124. m_pcd->AddRef();
  11125. m_type = CCT_UNINITIALIZED;
  11126. m_cookie = -1;
  11127. }
  11128. CPolicyDataObject::~CPolicyDataObject()
  11129. {
  11130. m_pcd->Release();
  11131. InterlockedDecrement(&g_cRefThisDll);
  11132. }
  11133. ///////////////////////////////////////////////////////////////////////////////
  11134. // //
  11135. // CPolicyDataObject object implementation (IUnknown) //
  11136. // //
  11137. ///////////////////////////////////////////////////////////////////////////////
  11138. HRESULT CPolicyDataObject::QueryInterface (REFIID riid, void **ppv)
  11139. {
  11140. if (IsEqualIID(riid, IID_IPolicyDataObject))
  11141. {
  11142. *ppv = (LPPOLICYDATAOBJECT)this;
  11143. m_cRef++;
  11144. return S_OK;
  11145. }
  11146. else if (IsEqualIID(riid, IID_IDataObject) ||
  11147. IsEqualIID(riid, IID_IUnknown))
  11148. {
  11149. *ppv = (LPDATAOBJECT)this;
  11150. m_cRef++;
  11151. return S_OK;
  11152. }
  11153. else
  11154. {
  11155. *ppv = NULL;
  11156. return E_NOINTERFACE;
  11157. }
  11158. }
  11159. ULONG CPolicyDataObject::AddRef (void)
  11160. {
  11161. return ++m_cRef;
  11162. }
  11163. ULONG CPolicyDataObject::Release (void)
  11164. {
  11165. if (--m_cRef == 0) {
  11166. delete this;
  11167. return 0;
  11168. }
  11169. return m_cRef;
  11170. }
  11171. ///////////////////////////////////////////////////////////////////////////////
  11172. // //
  11173. // CPolicyDataObject object implementation (IDataObject) //
  11174. // //
  11175. ///////////////////////////////////////////////////////////////////////////////
  11176. STDMETHODIMP CPolicyDataObject::GetDataHere(LPFORMATETC lpFormatetc, LPSTGMEDIUM lpMedium)
  11177. {
  11178. HRESULT hr = DV_E_CLIPFORMAT;
  11179. TCHAR szBuffer[300];
  11180. // Based on the CLIPFORMAT write data to the stream
  11181. const CLIPFORMAT cf = lpFormatetc->cfFormat;
  11182. if(cf == m_cfNodeType)
  11183. {
  11184. hr = CreateNodeTypeData(lpMedium);
  11185. }
  11186. else if(cf == m_cfNodeTypeString)
  11187. {
  11188. hr = CreateNodeTypeStringData(lpMedium);
  11189. }
  11190. else if (cf == m_cfDisplayName)
  11191. {
  11192. hr = CreateDisplayName(lpMedium);
  11193. }
  11194. else if (cf == m_cfCoClass)
  11195. {
  11196. hr = CreateCoClassID(lpMedium);
  11197. }
  11198. else if (cf == m_cfDescription)
  11199. {
  11200. hr = DV_E_TYMED;
  11201. if (lpMedium->tymed == TYMED_ISTREAM)
  11202. {
  11203. ULONG ulWritten;
  11204. if (m_cookie)
  11205. {
  11206. TABLEENTRY * pEntry = (TABLEENTRY *) m_cookie;
  11207. if (pEntry->dwType & ETYPE_POLICY)
  11208. {
  11209. POLICY * pPolicy = (POLICY *) m_cookie;
  11210. IStream *lpStream = lpMedium->pstm;
  11211. if (lpStream)
  11212. {
  11213. if (pPolicy->uOffsetHelp)
  11214. {
  11215. LPTSTR sz = (LPTSTR)((BYTE *)pPolicy + pPolicy->uOffsetHelp);
  11216. hr = lpStream->Write(sz, lstrlen(sz) * sizeof(TCHAR), &ulWritten);
  11217. }
  11218. if (!pPolicy->bTruePolicy)
  11219. {
  11220. LoadString (g_hInstance, IDS_PREFERENCE, szBuffer, ARRAYSIZE(szBuffer));
  11221. hr = lpStream->Write(szBuffer, lstrlen(szBuffer) * sizeof(TCHAR), &ulWritten);
  11222. }
  11223. }
  11224. }
  11225. else if (pEntry->dwType & ETYPE_CATEGORY)
  11226. {
  11227. CATEGORY * pCat = (CATEGORY *) m_cookie;
  11228. if (pCat->uOffsetHelp)
  11229. {
  11230. LPTSTR sz = (LPTSTR)((BYTE *)pCat + pCat->uOffsetHelp);
  11231. IStream *lpStream = lpMedium->pstm;
  11232. if (lpStream)
  11233. {
  11234. hr = lpStream->Write(sz, lstrlen(sz) * sizeof(TCHAR), &ulWritten);
  11235. }
  11236. }
  11237. }
  11238. else if (pEntry->dwType == (ETYPE_ROOT | ETYPE_REGITEM))
  11239. {
  11240. IStream *lpStream = lpMedium->pstm;
  11241. LoadString (g_hInstance, IDS_EXSETROOT_DESC, szBuffer, ARRAYSIZE(szBuffer));
  11242. if (lpStream)
  11243. {
  11244. hr = lpStream->Write(szBuffer, lstrlen(szBuffer) * sizeof(TCHAR), &ulWritten);
  11245. }
  11246. }
  11247. else if (pEntry->dwType == ETYPE_REGITEM)
  11248. {
  11249. IStream *lpStream = lpMedium->pstm;
  11250. LoadString (g_hInstance, IDS_EXSET_DESC, szBuffer, ARRAYSIZE(szBuffer));
  11251. if (lpStream)
  11252. {
  11253. REGITEM * pItem = (REGITEM *) m_cookie;
  11254. hr = lpStream->Write(szBuffer, lstrlen(szBuffer) * sizeof(TCHAR), &ulWritten);
  11255. if (!pItem->bTruePolicy)
  11256. {
  11257. LoadString (g_hInstance, IDS_PREFERENCE, szBuffer, ARRAYSIZE(szBuffer));
  11258. hr = lpStream->Write(szBuffer, lstrlen(szBuffer) * sizeof(TCHAR), &ulWritten);
  11259. }
  11260. }
  11261. }
  11262. }
  11263. else
  11264. {
  11265. LoadString (g_hInstance, IDS_POLICY_DESC, szBuffer, ARRAYSIZE(szBuffer));
  11266. IStream *lpStream = lpMedium->pstm;
  11267. if (lpStream)
  11268. {
  11269. hr = lpStream->Write(szBuffer, lstrlen(szBuffer) * sizeof(TCHAR), &ulWritten);
  11270. }
  11271. }
  11272. }
  11273. }
  11274. else if (cf == m_cfHTMLDetails)
  11275. {
  11276. hr = DV_E_TYMED;
  11277. if (lpMedium->tymed == TYMED_ISTREAM)
  11278. {
  11279. ULONG ulWritten;
  11280. if (m_cookie)
  11281. {
  11282. POLICY * pPolicy = (POLICY *) m_cookie;
  11283. if ((pPolicy->dwType & ETYPE_POLICY) || (pPolicy->dwType == ETYPE_REGITEM))
  11284. {
  11285. IStream *lpStream = lpMedium->pstm;
  11286. if(lpStream)
  11287. {
  11288. LPTSTR sz = GETSUPPORTEDPTR(pPolicy);
  11289. hr = lpStream->Write(g_szDisplayProperties, lstrlen(g_szDisplayProperties) * sizeof(TCHAR), &ulWritten);
  11290. if ((pPolicy->dwType & ETYPE_POLICY) && sz)
  11291. {
  11292. LoadString (g_hInstance, IDS_SUPPORTEDDESC, szBuffer, ARRAYSIZE(szBuffer));
  11293. hr = lpStream->Write(szBuffer, lstrlen(szBuffer) * sizeof(TCHAR), &ulWritten);
  11294. hr = lpStream->Write(sz, lstrlen(sz) * sizeof(TCHAR), &ulWritten);
  11295. }
  11296. }
  11297. }
  11298. }
  11299. }
  11300. }
  11301. return hr;
  11302. }
  11303. ///////////////////////////////////////////////////////////////////////////////
  11304. // //
  11305. // CPolicyDataObject object implementation (Internal functions) //
  11306. // //
  11307. ///////////////////////////////////////////////////////////////////////////////
  11308. HRESULT CPolicyDataObject::Create(LPVOID pBuffer, INT len, LPSTGMEDIUM lpMedium)
  11309. {
  11310. HRESULT hr = DV_E_TYMED;
  11311. // Do some simple validation
  11312. if (pBuffer == NULL || lpMedium == NULL)
  11313. return E_POINTER;
  11314. // Make sure the type medium is HGLOBAL
  11315. if (lpMedium->tymed == TYMED_HGLOBAL)
  11316. {
  11317. // Create the stream on the hGlobal passed in
  11318. LPSTREAM lpStream;
  11319. hr = CreateStreamOnHGlobal(lpMedium->hGlobal, FALSE, &lpStream);
  11320. if (SUCCEEDED(hr))
  11321. {
  11322. // Write to the stream the number of bytes
  11323. unsigned long written;
  11324. hr = lpStream->Write(pBuffer, len, &written);
  11325. // Because we told CreateStreamOnHGlobal with 'FALSE',
  11326. // only the stream is released here.
  11327. // Note - the caller (i.e. snap-in, object) will free the HGLOBAL
  11328. // at the correct time. This is according to the IDataObject specification.
  11329. lpStream->Release();
  11330. }
  11331. }
  11332. return hr;
  11333. }
  11334. HRESULT CPolicyDataObject::CreateNodeTypeData(LPSTGMEDIUM lpMedium)
  11335. {
  11336. LPRESULTITEM lpResultItem = (LPRESULTITEM) m_cookie;
  11337. if (m_cookie == -1)
  11338. return E_UNEXPECTED;
  11339. // Create the node type object in GUID format
  11340. if (m_pcd->m_bUserScope)
  11341. return Create((LPVOID)&NODEID_PolicyRootUser, sizeof(GUID), lpMedium);
  11342. else
  11343. return Create((LPVOID)&NODEID_PolicyRootMachine, sizeof(GUID), lpMedium);
  11344. }
  11345. HRESULT CPolicyDataObject::CreateNodeTypeStringData(LPSTGMEDIUM lpMedium)
  11346. {
  11347. TCHAR szNodeType[50];
  11348. if (m_cookie == -1)
  11349. return E_UNEXPECTED;
  11350. szNodeType[0] = TEXT('\0');
  11351. if (m_pcd->m_bUserScope)
  11352. StringFromGUID2 (NODEID_PolicyRootUser, szNodeType, 50);
  11353. else
  11354. StringFromGUID2 (NODEID_PolicyRootMachine, szNodeType, 50);
  11355. // Create the node type object in GUID string format
  11356. return Create((LPVOID)szNodeType, ((lstrlenW(szNodeType)+1) * sizeof(WCHAR)), lpMedium);
  11357. }
  11358. HRESULT CPolicyDataObject::CreateDisplayName(LPSTGMEDIUM lpMedium)
  11359. {
  11360. WCHAR szDisplayName[100] = {0};
  11361. LoadStringW (g_hInstance, IDS_POLICY_NAME, szDisplayName, 100);
  11362. return Create((LPVOID)szDisplayName, (lstrlenW(szDisplayName) + 1) * sizeof(WCHAR), lpMedium);
  11363. }
  11364. HRESULT CPolicyDataObject::CreateCoClassID(LPSTGMEDIUM lpMedium)
  11365. {
  11366. // Create the CoClass information
  11367. if (m_pcd->m_bUserScope)
  11368. return Create((LPVOID)&CLSID_PolicySnapInUser, sizeof(CLSID), lpMedium);
  11369. else
  11370. return Create((LPVOID)&CLSID_PolicySnapInMachine, sizeof(CLSID), lpMedium);
  11371. }
  11372. const TCHAR szViewDescript [] = TEXT("MMCViewExt 1.0 Object");
  11373. const TCHAR szViewGUID [] = TEXT("{B708457E-DB61-4C55-A92F-0D4B5E9B1224}");
  11374. const TCHAR szThreadingModel[] = TEXT("Apartment");
  11375. HRESULT RegisterPolicyExtension (REFGUID clsid, UINT uiStringId, REFGUID RootNodeID,
  11376. REFGUID ExtNodeId, LPTSTR lpSnapInNameIndirect)
  11377. {
  11378. TCHAR szSnapInKey[50];
  11379. TCHAR szSubKey[200];
  11380. TCHAR szSnapInName[100];
  11381. TCHAR szGUID[50];
  11382. DWORD dwDisp;
  11383. LONG lResult;
  11384. HKEY hKey;
  11385. //
  11386. // First register the extension
  11387. //
  11388. StringFromGUID2 (clsid, szSnapInKey, 50);
  11389. //
  11390. // Register SnapIn in HKEY_CLASSES_ROOT
  11391. //
  11392. LoadString (g_hInstance, uiStringId, szSnapInName, 100);
  11393. wsprintf (szSubKey, TEXT("CLSID\\%s"), szSnapInKey);
  11394. lResult = RegCreateKeyEx (HKEY_CLASSES_ROOT, szSubKey, 0, NULL,
  11395. REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL,
  11396. &hKey, &dwDisp);
  11397. if (lResult != ERROR_SUCCESS) {
  11398. return SELFREG_E_CLASS;
  11399. }
  11400. RegSetValueEx (hKey, NULL, 0, REG_SZ, (LPBYTE)szSnapInName,
  11401. (lstrlen(szSnapInName) + 1) * sizeof(TCHAR));
  11402. RegCloseKey (hKey);
  11403. wsprintf (szSubKey, TEXT("CLSID\\%s\\InProcServer32"), szSnapInKey);
  11404. lResult = RegCreateKeyEx (HKEY_CLASSES_ROOT, szSubKey, 0, NULL,
  11405. REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL,
  11406. &hKey, &dwDisp);
  11407. if (lResult != ERROR_SUCCESS) {
  11408. return SELFREG_E_CLASS;
  11409. }
  11410. RegSetValueEx (hKey, NULL, 0, REG_EXPAND_SZ, (LPBYTE)g_szSnapInLocation,
  11411. (lstrlen(g_szSnapInLocation) + 1) * sizeof(TCHAR));
  11412. RegSetValueEx (hKey, TEXT("ThreadingModel"), 0, REG_SZ, (LPBYTE)szThreadingModel,
  11413. (lstrlen(szThreadingModel) + 1) * sizeof(TCHAR));
  11414. RegCloseKey (hKey);
  11415. //
  11416. // Register SnapIn with MMC
  11417. //
  11418. wsprintf (szSubKey, TEXT("Software\\Microsoft\\MMC\\SnapIns\\%s"), szSnapInKey);
  11419. lResult = RegCreateKeyEx (HKEY_LOCAL_MACHINE, szSubKey, 0, NULL,
  11420. REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL,
  11421. &hKey, &dwDisp);
  11422. if (lResult != ERROR_SUCCESS) {
  11423. return SELFREG_E_CLASS;
  11424. }
  11425. RegSetValueEx (hKey, TEXT("NameString"), 0, REG_SZ, (LPBYTE)szSnapInName,
  11426. (lstrlen(szSnapInName) + 1) * sizeof(TCHAR));
  11427. RegSetValueEx (hKey, TEXT("NameStringIndirect"), 0, REG_SZ, (LPBYTE)lpSnapInNameIndirect,
  11428. (lstrlen(lpSnapInNameIndirect) + 1) * sizeof(TCHAR));
  11429. RegCloseKey (hKey);
  11430. StringFromGUID2 (RootNodeID, szGUID, 50);
  11431. wsprintf (szSubKey, TEXT("Software\\Microsoft\\MMC\\SnapIns\\%s\\NodeTypes\\%s"),
  11432. szSnapInKey, szGUID);
  11433. lResult = RegCreateKeyEx (HKEY_LOCAL_MACHINE, szSubKey, 0, NULL,
  11434. REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL,
  11435. &hKey, &dwDisp);
  11436. if (lResult != ERROR_SUCCESS) {
  11437. return SELFREG_E_CLASS;
  11438. }
  11439. RegCloseKey (hKey);
  11440. //
  11441. // Register in the NodeTypes key
  11442. //
  11443. StringFromGUID2 (RootNodeID, szGUID, 50);
  11444. wsprintf (szSubKey, TEXT("Software\\Microsoft\\MMC\\NodeTypes\\%s"), szGUID);
  11445. lResult = RegCreateKeyEx (HKEY_LOCAL_MACHINE, szSubKey, 0, NULL,
  11446. REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL,
  11447. &hKey, &dwDisp);
  11448. if (lResult != ERROR_SUCCESS) {
  11449. return SELFREG_E_CLASS;
  11450. }
  11451. RegCloseKey (hKey);
  11452. //
  11453. // Register for the view extension
  11454. //
  11455. lstrcat (szSubKey, TEXT("\\Extensions\\View"));
  11456. lResult = RegCreateKeyEx (HKEY_LOCAL_MACHINE, szSubKey, 0, NULL,
  11457. REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL,
  11458. &hKey, &dwDisp);
  11459. if (lResult != ERROR_SUCCESS) {
  11460. return SELFREG_E_CLASS;
  11461. }
  11462. RegSetValueEx (hKey, szViewGUID, 0, REG_SZ, (LPBYTE)szViewDescript,
  11463. (lstrlen(szViewDescript) + 1) * sizeof(TCHAR));
  11464. RegCloseKey (hKey);
  11465. //
  11466. // Register as an extension for various nodes
  11467. //
  11468. StringFromGUID2 (ExtNodeId, szGUID, 50);
  11469. wsprintf (szSubKey, TEXT("Software\\Microsoft\\MMC\\NodeTypes\\%s\\Extensions\\NameSpace"), szGUID);
  11470. lResult = RegCreateKeyEx (HKEY_LOCAL_MACHINE, szSubKey, 0, NULL,
  11471. REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL,
  11472. &hKey, &dwDisp);
  11473. if (lResult != ERROR_SUCCESS) {
  11474. return SELFREG_E_CLASS;
  11475. }
  11476. RegSetValueEx (hKey, szSnapInKey, 0, REG_SZ, (LPBYTE)szSnapInName,
  11477. (lstrlen(szSnapInName) + 1) * sizeof(TCHAR));
  11478. RegCloseKey (hKey);
  11479. return S_OK;
  11480. }
  11481. HRESULT RegisterPolicy(void)
  11482. {
  11483. HRESULT hr;
  11484. hr = RegisterPolicyExtension (CLSID_PolicySnapInMachine, IDS_POLICY_NAME_MACHINE,
  11485. NODEID_PolicyRootMachine, NODEID_MachineRoot, TEXT("@gptext.dll,-20"));
  11486. if (hr == S_OK)
  11487. {
  11488. hr = RegisterPolicyExtension (CLSID_PolicySnapInUser, IDS_POLICY_NAME_USER,
  11489. NODEID_PolicyRootUser, NODEID_UserRoot, TEXT("@gptext.dll,-21"));
  11490. }
  11491. if (hr == S_OK)
  11492. {
  11493. hr = RegisterPolicyExtension (CLSID_RSOPolicySnapInMachine, IDS_POLICY_NAME_MACHINE,
  11494. NODEID_RSOPolicyRootMachine, NODEID_RSOPMachineRoot, TEXT("@gptext.dll,-20"));
  11495. }
  11496. if (hr == S_OK)
  11497. {
  11498. hr = RegisterPolicyExtension (CLSID_RSOPolicySnapInUser, IDS_POLICY_NAME_USER,
  11499. NODEID_RSOPolicyRootUser, NODEID_RSOPUserRoot, TEXT("@gptext.dll,-21"));
  11500. }
  11501. return hr;
  11502. }
  11503. HRESULT UnregisterPolicyExtension (REFGUID clsid, REFGUID RootNodeID, REFGUID ExtNodeId)
  11504. {
  11505. TCHAR szSnapInKey[50];
  11506. TCHAR szSubKey[200];
  11507. TCHAR szGUID[50];
  11508. LONG lResult;
  11509. HKEY hKey;
  11510. DWORD dwDisp;
  11511. //
  11512. // First unregister the extension
  11513. //
  11514. StringFromGUID2 (clsid, szSnapInKey, 50);
  11515. wsprintf (szSubKey, TEXT("CLSID\\%s"), szSnapInKey);
  11516. RegDelnode (HKEY_CLASSES_ROOT, szSubKey);
  11517. wsprintf (szSubKey, TEXT("Software\\Microsoft\\MMC\\SnapIns\\%s"), szSnapInKey);
  11518. RegDelnode (HKEY_LOCAL_MACHINE, szSubKey);
  11519. StringFromGUID2 (RootNodeID, szGUID, 50);
  11520. wsprintf (szSubKey, TEXT("Software\\Microsoft\\MMC\\NodeTypes\\%s"), szGUID);
  11521. RegDelnode (HKEY_LOCAL_MACHINE, szSubKey);
  11522. StringFromGUID2 (ExtNodeId, szGUID, 50);
  11523. wsprintf (szSubKey, TEXT("Software\\Microsoft\\MMC\\NodeTypes\\%s\\Extensions\\NameSpace"), szGUID);
  11524. lResult = RegOpenKeyEx (HKEY_LOCAL_MACHINE, szSubKey, 0,
  11525. KEY_WRITE, &hKey);
  11526. if (lResult == ERROR_SUCCESS) {
  11527. RegDeleteValue (hKey, szSnapInKey);
  11528. RegCloseKey (hKey);
  11529. }
  11530. return S_OK;
  11531. }
  11532. HRESULT UnregisterPolicy(void)
  11533. {
  11534. HRESULT hr;
  11535. hr = UnregisterPolicyExtension (CLSID_PolicySnapInMachine, NODEID_PolicyRootMachine,
  11536. NODEID_Machine);
  11537. if (hr == S_OK)
  11538. {
  11539. hr = UnregisterPolicyExtension (CLSID_PolicySnapInUser, NODEID_PolicyRootUser,
  11540. NODEID_User);
  11541. }
  11542. if (hr == S_OK)
  11543. {
  11544. hr = UnregisterPolicyExtension (CLSID_RSOPolicySnapInMachine, NODEID_RSOPolicyRootMachine,
  11545. NODEID_RSOPMachineRoot);
  11546. }
  11547. if (hr == S_OK)
  11548. {
  11549. hr = UnregisterPolicyExtension (CLSID_RSOPolicySnapInUser, NODEID_RSOPolicyRootUser,
  11550. NODEID_RSOPUserRoot);
  11551. }
  11552. return hr;
  11553. }
  11554. VOID LoadMessage (DWORD dwID, LPTSTR lpBuffer, DWORD dwSize)
  11555. {
  11556. HINSTANCE hInstActiveDS;
  11557. HINSTANCE hInstWMI;
  11558. if (!FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM,
  11559. NULL, dwID,
  11560. MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL),
  11561. lpBuffer, dwSize, NULL))
  11562. {
  11563. hInstActiveDS = LoadLibrary (TEXT("activeds.dll"));
  11564. if (hInstActiveDS)
  11565. {
  11566. if (!FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_HMODULE,
  11567. hInstActiveDS, dwID,
  11568. MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL),
  11569. lpBuffer, dwSize, NULL))
  11570. {
  11571. hInstWMI = LoadLibrary (TEXT("wmiutils.dll"));
  11572. if (hInstWMI)
  11573. {
  11574. if (!FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_HMODULE,
  11575. hInstWMI, dwID,
  11576. MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL),
  11577. lpBuffer, dwSize, NULL))
  11578. {
  11579. DebugMsg((DM_WARNING, TEXT("LoadMessage: Failed to query error message text for %d due to error %d"),
  11580. dwID, GetLastError()));
  11581. wsprintf (lpBuffer, TEXT("%d (0x%x)"), dwID, dwID);
  11582. }
  11583. FreeLibrary (hInstWMI);
  11584. }
  11585. }
  11586. FreeLibrary (hInstActiveDS);
  11587. }
  11588. }
  11589. }
  11590. //*************************************************************
  11591. //
  11592. // ErrorDlgProc()
  11593. //
  11594. // Purpose: Dialog box procedure for errors
  11595. //
  11596. // Parameters:
  11597. //
  11598. //
  11599. // Return: TRUE if successful
  11600. // FALSE if an error occurs
  11601. //
  11602. //*************************************************************
  11603. INT_PTR CALLBACK ErrorDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  11604. {
  11605. switch (message)
  11606. {
  11607. case WM_INITDIALOG:
  11608. {
  11609. TCHAR szError[MAX_PATH];
  11610. LPGPOERRORINFO lpEI = (LPGPOERRORINFO) lParam;
  11611. HICON hIcon;
  11612. hIcon = LoadIcon (NULL, IDI_INFORMATION);
  11613. if (hIcon)
  11614. {
  11615. SendDlgItemMessage (hDlg, IDC_ERROR_ICON, STM_SETICON, (WPARAM)hIcon, 0);
  11616. }
  11617. SetDlgItemText (hDlg, IDC_ERRORTEXT, lpEI->lpMsg);
  11618. if (lpEI->lpDetails) {
  11619. // if details is provided use that
  11620. SetDlgItemText (hDlg, IDC_DETAILSTEXT, lpEI->lpDetails);
  11621. }
  11622. else {
  11623. szError[0] = TEXT('\0');
  11624. if (lpEI->dwError)
  11625. {
  11626. LoadMessage (lpEI->dwError, szError, ARRAYSIZE(szError));
  11627. }
  11628. if (szError[0] == TEXT('\0'))
  11629. {
  11630. LoadString (g_hInstance, IDS_NONE, szError, ARRAYSIZE(szError));
  11631. }
  11632. SetDlgItemText (hDlg, IDC_DETAILSTEXT, szError);
  11633. }
  11634. // this is the only way I know to remove focus from the details
  11635. PostMessage(hDlg, WM_MYREFRESH, 0, 0);
  11636. return TRUE;
  11637. }
  11638. case WM_MYREFRESH:
  11639. {
  11640. SetFocus(GetDlgItem(hDlg, IDCLOSE));
  11641. }
  11642. case WM_COMMAND:
  11643. if (LOWORD(wParam) == IDCLOSE || LOWORD(wParam) == IDCANCEL)
  11644. {
  11645. EndDialog(hDlg, TRUE);
  11646. return TRUE;
  11647. }
  11648. break;
  11649. case WM_HELP: // F1
  11650. WinHelp((HWND)((LPHELPINFO) lParam)->hItemHandle, HELP_FILE, HELP_WM_HELP,
  11651. (ULONG_PTR) (LPSTR) aErrorHelpIds);
  11652. break;
  11653. case WM_CONTEXTMENU: // right mouse click
  11654. WinHelp((HWND) wParam, HELP_FILE, HELP_CONTEXTMENU,
  11655. (ULONG_PTR) (LPSTR) aErrorHelpIds);
  11656. return (TRUE);
  11657. }
  11658. return FALSE;
  11659. }
  11660. //*************************************************************
  11661. //
  11662. // ReportError()
  11663. //
  11664. // Purpose: Displays an error message to the user
  11665. //
  11666. // Parameters: hParent - Parent window handle
  11667. // dwError - Error number
  11668. // idMsg - Error message id
  11669. //
  11670. // Return: TRUE if successful
  11671. // FALSE if an error occurs
  11672. //
  11673. // Comments:
  11674. //
  11675. // History: Date Author Comment
  11676. // 7/18/95 ericflo Created
  11677. //
  11678. //*************************************************************
  11679. BOOL ReportAdmError (HWND hParent, DWORD dwError, UINT idMsg, ...)
  11680. {
  11681. GPOERRORINFO ei;
  11682. TCHAR szMsg[MAX_PATH];
  11683. TCHAR szErrorMsg[2*MAX_PATH+40];
  11684. va_list marker;
  11685. //
  11686. // Load the error message
  11687. //
  11688. if (!LoadString (g_hInstance, idMsg, szMsg, MAX_PATH))
  11689. {
  11690. return FALSE;
  11691. }
  11692. //
  11693. // Plug in the arguments
  11694. //
  11695. va_start(marker, idMsg);
  11696. if (idMsg == IDS_RSOP_ADMFAILED) {
  11697. ei.lpDetails = va_arg(marker, LPTSTR);
  11698. wcscpy(szErrorMsg, szMsg);
  11699. }
  11700. else {
  11701. va_start(marker, idMsg);
  11702. wvsprintf(szErrorMsg, szMsg, marker);
  11703. }
  11704. va_end(marker);
  11705. //
  11706. // Display the message
  11707. //
  11708. ei.dwError = dwError;
  11709. ei.lpMsg = szErrorMsg;
  11710. DialogBoxParam (g_hInstance, MAKEINTRESOURCE(IDD_ERROR_ADMTEMPLATES), hParent,
  11711. ErrorDlgProc, (LPARAM) &ei);
  11712. return TRUE;
  11713. }