Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

490 lines
11 KiB

  1. #include "pch.hxx"
  2. #include "strconst.h"
  3. #include <mimeole.h>
  4. #include <imnact.h>
  5. #include "imsgcont.h"
  6. #include <goptions.h>
  7. #include <thormsgs.h>
  8. #include "sigs.h"
  9. #include <shlwapi.h>
  10. #undef _INC_GOPTIONS_H
  11. #define DEFINE_OPTION_STRUCTS
  12. #include <goptions.h>
  13. #include "demand.h"
  14. #include "multiusr.h"
  15. IOptionBucketEx *g_pOpt = NULL;
  16. COptNotify *g_pOptNotify = NULL;
  17. BOOL g_fBadShutdown = FALSE;
  18. static OPTBCKTINIT g_init =
  19. {
  20. c_rgOptInfo,
  21. ARRAYSIZE(c_rgOptInfo),
  22. HKEY_CURRENT_USER,
  23. c_szRegRoot,
  24. c_rgszOptRegKey,
  25. COPTREGKEY
  26. };
  27. BOOL InitGlobalOptions(HKEY hkey, LPCSTR szRegOptRoot)
  28. {
  29. OPTBCKTINIT init;
  30. LPCOPTBCKTINIT pinit;
  31. HRESULT hr;
  32. Assert(NULL == g_pOpt);
  33. Assert(NULL == g_pOptNotify);
  34. g_init.hkey = MU_GetCurrentUserHKey();
  35. IF_NULLEXIT(g_pOptNotify = new COptNotify);
  36. IF_FAILEXIT(hr = CreateOptionBucketEx(&g_pOpt));
  37. pinit = &g_init;
  38. if (NULL != hkey)
  39. {
  40. Assert(NULL != szRegOptRoot);
  41. init = g_init;
  42. init.hkey = hkey;
  43. init.pszRegKeyBase = szRegOptRoot;
  44. pinit = &init;
  45. }
  46. IF_FAILEXIT(hr = g_pOpt->Initialize(pinit));
  47. IF_FAILEXIT(hr = g_pOpt->SetNotification((IOptionBucketNotify *)g_pOptNotify));
  48. // signature manager
  49. IF_FAILEXIT(hr = InitSignatureManager(pinit->hkey, pinit->pszRegKeyBase));
  50. // if the running regkey is still there, we shut down badly
  51. g_fBadShutdown = DwGetOption(OPT_ATHENA_RUNNING);
  52. SetDwOption(OPT_ATHENA_RUNNING, TRUE, NULL, 0);
  53. exit:
  54. return (S_OK == hr);
  55. }
  56. void DeInitGlobalOptions(void)
  57. {
  58. if (NULL != g_pOpt)
  59. {
  60. SetDwOption(OPT_ATHENA_RUNNING, FALSE, NULL, 0);
  61. g_pOpt->Release();
  62. g_pOpt = NULL;
  63. }
  64. if (NULL != g_pOptNotify)
  65. {
  66. g_pOptNotify->Release();
  67. g_pOptNotify = NULL;
  68. }
  69. DeinitSignatureManager();
  70. }
  71. DWORD DwGetOption(PROPID id)
  72. {
  73. Assert(NULL != g_pOpt);
  74. return(IDwGetOption(g_pOpt, id));
  75. }
  76. DWORD DwGetOptionDefault(PROPID id)
  77. {
  78. Assert(NULL != g_pOpt);
  79. return(IDwGetOptionDefault(g_pOpt, id));
  80. }
  81. DWORD GetOption(PROPID id, void *pv, DWORD cb)
  82. {
  83. Assert(NULL != g_pOpt);
  84. return(IGetOption(g_pOpt, id, pv, cb));
  85. }
  86. DWORD IDwGetOption(IOptionBucketEx *pOpt, PROPID id)
  87. {
  88. PROPVARIANT var;
  89. HRESULT hr;
  90. DWORD dw = 0;
  91. Assert(NULL != pOpt);
  92. // special case attachment checks to allow for ADM setting of group policy
  93. if ((id == OPT_SECURITY_ATTACHMENT) || (id == OPT_SECURITY_ATTACHMENT_LOCKED))
  94. {
  95. HKEY hkey;
  96. if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szRegFlat, 0, KEY_READ, &hkey))
  97. {
  98. DWORD dwVal, cb;
  99. cb = sizeof(dwVal);
  100. if (ERROR_SUCCESS == RegQueryValueEx(hkey, c_szBlockAttachments, 0, NULL, (LPBYTE)&dwVal, &cb))
  101. {
  102. // if set then unsafe attachments are both locked and also disallowed
  103. if (dwVal == 1)
  104. dw = 1;
  105. }
  106. RegCloseKey(hkey);
  107. }
  108. }
  109. if (!dw)
  110. {
  111. IF_FAILEXIT(hr = pOpt->GetProperty(MAKEPROPSTRING(id), &var, 0));
  112. Assert(VT_UI4 == var.vt);
  113. dw = var.ulVal;
  114. }
  115. exit:
  116. return(dw);
  117. }
  118. DWORD IDwGetOptionDefault(IOptionBucketEx *pOpt, PROPID id)
  119. {
  120. PROPVARIANT var;
  121. HRESULT hr;
  122. DWORD dw = 0;
  123. Assert(pOpt != NULL);
  124. IF_FAILEXIT(hr = pOpt->GetPropertyDefault(id, &var, 0));
  125. Assert(var.vt == VT_UI4);
  126. dw = var.ulVal;
  127. exit:
  128. return(dw);
  129. }
  130. DWORD IGetOption(IOptionBucketEx *pOpt, PROPID id, void *pv, DWORD cb)
  131. {
  132. PROPVARIANT var;
  133. HRESULT hr = S_OK;
  134. DWORD cbT = 0;
  135. LPBYTE pByte = NULL;
  136. Assert(NULL != pOpt);
  137. IF_FAILEXIT(hr = pOpt->GetProperty(MAKEPROPSTRING(id), &var, 0));
  138. switch (var.vt)
  139. {
  140. case VT_LPSTR:
  141. pByte = (LPBYTE)var.pszVal;
  142. cbT = lstrlen(var.pszVal) + 1;
  143. break;
  144. case VT_LPWSTR:
  145. pByte = (LPBYTE)var.pwszVal;
  146. cbT = (lstrlenW(var.pwszVal) + 1) * sizeof(WCHAR);
  147. break;
  148. case VT_BLOB:
  149. pByte = (LPBYTE)var.blob.pBlobData;
  150. cbT = var.blob.cbSize;
  151. break;
  152. default:
  153. Assert(FALSE);
  154. IF_FAILEXIT(hr = E_FAIL);
  155. break;
  156. }
  157. if (cb >= cbT && pByte)
  158. CopyMemory(pv, pByte, cbT);
  159. else
  160. IF_FAILEXIT(hr = E_FAIL);
  161. exit:
  162. MemFree(pByte);
  163. return (SUCCEEDED(hr) ? cbT : 0);
  164. }
  165. BOOL SetDwOption(PROPID id, DWORD dw, HWND hwnd, DWORD dwFlags)
  166. {
  167. Assert(NULL != g_pOpt);
  168. return(ISetOption(g_pOpt, id, &dw, sizeof(DWORD), hwnd, dwFlags));
  169. }
  170. BOOL SetOption(PROPID id, void *pv, DWORD cb, HWND hwnd, DWORD dwFlags)
  171. {
  172. Assert(NULL != g_pOpt);
  173. return(ISetOption(g_pOpt, id, pv, cb, hwnd, dwFlags));
  174. }
  175. BOOL ISetDwOption(IOptionBucketEx *pOpt, PROPID id, DWORD dw, HWND hwnd, DWORD dwFlags)
  176. {
  177. Assert(NULL != pOpt);
  178. return(ISetOption(pOpt, id, &dw, sizeof(DWORD), hwnd, dwFlags));
  179. }
  180. BOOL ISetOption(IOptionBucketEx *pOpt, PROPID id, void *pv, DWORD cb, HWND hwnd, DWORD dwFlags)
  181. {
  182. HRESULT hr;
  183. PROPINFO info;
  184. PROPVARIANT var;
  185. Assert(NULL != pOpt);
  186. Assert(NULL != pv);
  187. info.cbSize = sizeof(info);
  188. IF_FAILEXIT(hr = pOpt->GetPropertyInfo(id, &info, 0));
  189. var.vt = info.vt;
  190. switch(var.vt)
  191. {
  192. case VT_UI4:
  193. var.ulVal = *((DWORD *)pv);
  194. break;
  195. case VT_LPSTR:
  196. var.pszVal = (LPSTR)pv;
  197. break;
  198. case VT_LPWSTR:
  199. var.pwszVal = (LPWSTR)pv;
  200. break;
  201. case VT_BLOB:
  202. var.blob.cbSize = cb;
  203. var.blob.pBlobData = (BYTE *)pv;
  204. break;
  205. default:
  206. Assert(FALSE);
  207. IF_FAILEXIT(hr = E_FAIL);
  208. break;
  209. }
  210. IF_FAILEXIT(hr = pOpt->ISetProperty(hwnd, MAKEPROPSTRING(id), &var, dwFlags));
  211. // TODO: notify option objects that option changed
  212. exit:
  213. return(SUCCEEDED(hr));
  214. }
  215. HRESULT OptionAdvise(HWND hwnd)
  216. {
  217. Assert(NULL != g_pOptNotify);
  218. return(g_pOptNotify->Register(hwnd));
  219. }
  220. HRESULT OptionUnadvise(HWND hwnd)
  221. {
  222. Assert(NULL != g_pOptNotify);
  223. return(g_pOptNotify->Unregister(hwnd));
  224. }
  225. COptNotify::COptNotify(void)
  226. {
  227. m_cRef = 1;
  228. m_cHwnd = 0;
  229. m_cHwndBuf = 0;
  230. m_rgHwnd = NULL;
  231. }
  232. COptNotify::~COptNotify(void)
  233. {
  234. MemFree(m_rgHwnd);
  235. }
  236. STDMETHODIMP COptNotify::QueryInterface(REFIID riid, LPVOID *ppv)
  237. {
  238. if (NULL == ppv)
  239. return(E_INVALIDARG);
  240. if (IID_IUnknown == riid)
  241. {
  242. *ppv = (IUnknown *)this;
  243. }
  244. else if (IID_IOptionBucketNotify == riid)
  245. {
  246. *ppv = (IOptionBucketNotify *)this;
  247. }
  248. else
  249. {
  250. *ppv = NULL;
  251. return(E_NOINTERFACE);
  252. }
  253. ((IUnknown *)*ppv)->AddRef();
  254. return(S_OK);
  255. }
  256. STDMETHODIMP_(ULONG) COptNotify::AddRef(void)
  257. {
  258. return((ULONG)InterlockedIncrement(&m_cRef));
  259. }
  260. STDMETHODIMP_(ULONG) COptNotify::Release(void)
  261. {
  262. LONG cRef = InterlockedDecrement(&m_cRef);
  263. if (0 == cRef)
  264. delete this;
  265. return((ULONG)cRef);
  266. }
  267. #define CADVISEOPT 32
  268. HRESULT COptNotify::Register(HWND hwnd)
  269. {
  270. HRESULT hr = S_OK;
  271. int cbuf;
  272. if (m_cHwnd == m_cHwndBuf)
  273. {
  274. cbuf = m_cHwndBuf + CADVISEOPT;
  275. IF_NULLEXIT(MemRealloc((void **)&m_rgHwnd, sizeof(HWND) * cbuf));
  276. m_cHwndBuf = cbuf;
  277. }
  278. Assert(m_rgHwnd != NULL);
  279. m_rgHwnd[m_cHwnd] = hwnd;
  280. m_cHwnd++;
  281. exit:
  282. return hr;
  283. }
  284. HRESULT COptNotify::Unregister(HWND hwnd)
  285. {
  286. int index = 0;
  287. while (index < m_cHwnd)
  288. {
  289. if (m_rgHwnd[index] == hwnd)
  290. break;
  291. index++;
  292. }
  293. if (index >= m_cHwnd)
  294. return (E_FAIL);
  295. if (m_cHwnd == 1)
  296. {
  297. MemFree(m_rgHwnd);
  298. m_rgHwnd = NULL;
  299. m_cHwndBuf = 0;
  300. }
  301. else
  302. {
  303. while (index < m_cHwnd)
  304. {
  305. m_rgHwnd[index] = m_rgHwnd[index+1];
  306. index++;
  307. }
  308. }
  309. m_cHwnd--;
  310. return (S_OK);
  311. }
  312. STDMETHODIMP COptNotify::DoNotification(IOptionBucketEx *pBckt, HWND hwnd, PROPID id)
  313. {
  314. int i;
  315. for (i = 0; i < m_cHwnd; i++)
  316. {
  317. if (hwnd != m_rgHwnd[i] && IsWindow(m_rgHwnd[i]))
  318. PostMessage(m_rgHwnd[i], CM_OPTIONADVISE, id, 0);
  319. }
  320. return(S_OK);
  321. }
  322. void GetUserKeyPath(LPCSTR lpSubKey, LPSTR sz, int cch)
  323. {
  324. Assert(sz != NULL);
  325. Assert(cch >= MAX_PATH);
  326. LPCTSTR pszUserRoot = c_szRegRoot;
  327. if (lpSubKey == NULL)
  328. StrCpyN(sz, pszUserRoot, cch);
  329. else
  330. wnsprintf(sz, cch, c_szPathFileFmt, pszUserRoot, lpSubKey);
  331. }
  332. LONG AthUserCreateKey(LPCSTR lpSubKey, REGSAM samDesired, PHKEY phkResult, LPDWORD lpdwDisposition)
  333. {
  334. char sz[MAX_PATH];
  335. GetUserKeyPath(lpSubKey, sz, ARRAYSIZE(sz));
  336. return(RegCreateKeyEx(MU_GetCurrentUserHKey(), sz, 0, NULL, REG_OPTION_NON_VOLATILE,
  337. samDesired, NULL, phkResult, lpdwDisposition));
  338. }
  339. LONG AthUserOpenKey(LPCSTR lpSubKey, REGSAM samDesired, PHKEY phkResult)
  340. {
  341. char sz[MAX_PATH];
  342. GetUserKeyPath(lpSubKey, sz, ARRAYSIZE(sz));
  343. return(RegOpenKeyEx(MU_GetCurrentUserHKey(), sz, 0, samDesired, phkResult));
  344. }
  345. LONG AthUserDeleteKey(LPCSTR lpSubKey)
  346. {
  347. char sz[MAX_PATH];
  348. GetUserKeyPath(lpSubKey, sz, ARRAYSIZE(sz));
  349. return(SHDeleteKey(MU_GetCurrentUserHKey(), sz));
  350. }
  351. LONG AthUserGetValue(LPCSTR lpSubKey, LPCSTR lpValueName, LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData)
  352. {
  353. char sz[MAX_PATH];
  354. GetUserKeyPath(lpSubKey, sz, ARRAYSIZE(sz));
  355. return(SHGetValue(MU_GetCurrentUserHKey(), sz, lpValueName, lpType, lpData, lpcbData));
  356. }
  357. LONG AthUserSetValue(LPCSTR lpSubKey, LPCSTR lpValueName, DWORD dwType, CONST BYTE *lpData, DWORD cbData)
  358. {
  359. char sz[MAX_PATH];
  360. GetUserKeyPath(lpSubKey, sz, ARRAYSIZE(sz));
  361. return(SHSetValue(MU_GetCurrentUserHKey(), sz, lpValueName, dwType, lpData, cbData));
  362. }
  363. LONG AthUserDeleteValue(LPCSTR lpSubKey, LPCSTR lpValueName)
  364. {
  365. char sz[MAX_PATH];
  366. GetUserKeyPath(lpSubKey, sz, ARRAYSIZE(sz));
  367. return(SHDeleteValue(MU_GetCurrentUserHKey(), sz, lpValueName));
  368. }
  369. HKEY AthUserGetKeyRoot(void)
  370. {
  371. return(MU_GetCurrentUserHKey());
  372. }
  373. void AthUserGetKeyPath(LPSTR szKey, int cch)
  374. {
  375. Assert(cch >= MAX_PATH);
  376. LPCTSTR pszRegRoot = c_szRegRoot;
  377. Assert(pszRegRoot);
  378. StrCpyN(szKey, pszRegRoot, cch);
  379. }