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.

353 lines
11 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1997 - 1999
  6. //
  7. // File: security.cpp
  8. //
  9. // Invoke the security UI for DS objects
  10. //
  11. //--------------------------------------------------------------------------
  12. #include "pch.h"
  13. #include <dssec.h>
  14. /*-----------------------------------------------------------------------------
  15. / CDsSecurityClassFactory
  16. / Class factory for the Security property page and context menu
  17. /----------------------------------------------------------------------------*/
  18. #undef CLASS_NAME
  19. #define CLASS_NAME CDsSecurityClassFactory
  20. #include <unknown.inc>
  21. STDMETHODIMP
  22. CDsSecurityClassFactory::QueryInterface(REFIID riid, LPVOID* ppvObject)
  23. {
  24. INTERFACES iface[] =
  25. {
  26. &IID_IClassFactory, (LPCLASSFACTORY)this,
  27. };
  28. return HandleQueryInterface(riid, ppvObject, iface, ARRAYSIZE(iface));
  29. }
  30. /*-----------------------------------------------------------------------------
  31. / IClassFactory methods
  32. /----------------------------------------------------------------------------*/
  33. STDMETHODIMP
  34. CDsSecurityClassFactory::CreateInstance(LPUNKNOWN punkOuter,
  35. REFIID riid,
  36. LPVOID* ppvObject)
  37. {
  38. HRESULT hr;
  39. CDsSecurity* pDsSecurity;
  40. TraceEnter(TRACE_SECURITY, "CDsSecurityClassFactory::CreateInstance");
  41. TraceGUID("Interface requested", riid);
  42. TraceAssert(ppvObject);
  43. if (punkOuter)
  44. ExitGracefully(hr, CLASS_E_NOAGGREGATION, "Aggregation is not supported");
  45. pDsSecurity = new CDsSecurity;
  46. if (!pDsSecurity)
  47. ExitGracefully(hr, E_OUTOFMEMORY, "Failed to allocate CDsSecurity");
  48. hr = pDsSecurity->QueryInterface(riid, ppvObject);
  49. if (FAILED(hr))
  50. delete pDsSecurity;
  51. exit_gracefully:
  52. TraceLeaveResult(hr);
  53. }
  54. /*---------------------------------------------------------------------------*/
  55. STDMETHODIMP
  56. CDsSecurityClassFactory::LockServer(BOOL /*fLock*/)
  57. {
  58. return E_NOTIMPL; // not supported
  59. }
  60. /*-----------------------------------------------------------------------------
  61. / CDsSecurity
  62. / Security property page and context menu shell extension
  63. /----------------------------------------------------------------------------*/
  64. // Destructor
  65. CDsSecurity::~CDsSecurity()
  66. {
  67. DoRelease(m_pSI);
  68. }
  69. // IUnknown bits
  70. #undef CLASS_NAME
  71. #define CLASS_NAME CDsSecurity
  72. #include "unknown.inc"
  73. STDMETHODIMP
  74. CDsSecurity::QueryInterface(REFIID riid, LPVOID* ppvObject)
  75. {
  76. INTERFACES iface[] =
  77. {
  78. &IID_IShellExtInit, (LPSHELLEXTINIT)this,
  79. &IID_IShellPropSheetExt, (LPSHELLPROPSHEETEXT)this,
  80. &IID_IContextMenu, (LPCONTEXTMENU)this,
  81. };
  82. return HandleQueryInterface(riid, ppvObject, iface, ARRAYSIZE(iface));
  83. }
  84. /*----------------------------------------------------------------------------
  85. / IShellExtInit
  86. /----------------------------------------------------------------------------*/
  87. STDMETHODIMP
  88. CDsSecurity::Initialize(LPCITEMIDLIST /*pIDFolder*/,
  89. LPDATAOBJECT pDataObj,
  90. HKEY /*hKeyID*/)
  91. {
  92. HRESULT hr;
  93. FORMATETC fe = {0, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
  94. STGMEDIUM medObjectNames = {0};
  95. STGMEDIUM medDisplayOptions = {0};
  96. LPDSOBJECTNAMES pDsObjects;
  97. LPWSTR pObjectPath;
  98. LPWSTR pClass = NULL;
  99. DWORD dwFlags = 0;
  100. LPWSTR pszServer = NULL;
  101. LPWSTR pszUserName = NULL;
  102. LPWSTR pszPassword = NULL;
  103. static CLIPFORMAT cfDsObjectNames = 0;
  104. static CLIPFORMAT cfDsDisplayOptions = 0;
  105. TraceEnter(TRACE_SECURITY, "CDsSecurity::Initialize");
  106. DoRelease(m_pSI);
  107. // Call the data object to get the array of DS names and classes. This
  108. // is stored using a private clipboard format - so we must first
  109. // try and register it.
  110. if (!cfDsObjectNames)
  111. cfDsObjectNames = (CLIPFORMAT)RegisterClipboardFormat(CFSTR_DSOBJECTNAMES);
  112. if (!cfDsObjectNames)
  113. ExitGracefully(hr, E_FAIL, "Clipboard format failed to register");
  114. fe.cfFormat = cfDsObjectNames; // set the clipboard format
  115. if (!pDataObj)
  116. ExitGracefully(hr, E_INVALIDARG, "No data object given");
  117. hr = pDataObj->GetData(&fe, &medObjectNames);
  118. FailGracefully(hr, "Failed to get selected objects");
  119. pDsObjects = (LPDSOBJECTNAMES)medObjectNames.hGlobal;
  120. TraceAssert(pDsObjects);
  121. if (!(pDsObjects->aObjects[0].dwProviderFlags & DSPROVIDER_ADVANCED))
  122. ExitGracefully(hr, E_FAIL, "Security page only shown in advanced mode");
  123. if (1 != pDsObjects->cItems)
  124. ExitGracefully(hr, E_FAIL, "Multiple selection not supported");
  125. // Get the object path
  126. pObjectPath = (LPWSTR)ByteOffset(pDsObjects, pDsObjects->aObjects[0].offsetName);
  127. Trace((TEXT("Name \"%s\""), pObjectPath));
  128. // Get the class name
  129. if (pDsObjects->aObjects[0].offsetClass)
  130. {
  131. pClass = (LPWSTR)ByteOffset(pDsObjects, pDsObjects->aObjects[0].offsetClass);
  132. Trace((TEXT("Class \"%s\""), pClass));
  133. }
  134. // DSOBJECT_READONLYPAGES is no longer used
  135. #ifdef DSOBJECT_READONLYPAGES
  136. if (pDsObjects->aObjects[0].dwFlags & DSOBJECT_READONLYPAGES)
  137. dwFlags = DSSI_READ_ONLY;
  138. #endif
  139. //
  140. // Get server name and user credentials from the data object
  141. //
  142. if (!cfDsDisplayOptions)
  143. cfDsDisplayOptions = (CLIPFORMAT)RegisterClipboardFormat(CFSTR_DS_DISPLAY_SPEC_OPTIONS);
  144. if (cfDsDisplayOptions)
  145. {
  146. fe.cfFormat = cfDsDisplayOptions;
  147. hr = pDataObj->GetData(&fe, &medDisplayOptions);
  148. if (SUCCEEDED(hr))
  149. {
  150. LPDSDISPLAYSPECOPTIONS pDisplayOptions = (LPDSDISPLAYSPECOPTIONS)medDisplayOptions.hGlobal;
  151. if (pDisplayOptions->dwFlags & DSDSOF_HASUSERANDSERVERINFO)
  152. {
  153. if (pDisplayOptions->offsetServer)
  154. pszServer = (LPWSTR)ByteOffset(pDisplayOptions, pDisplayOptions->offsetServer);
  155. if (pDisplayOptions->offsetUserName)
  156. pszUserName = (LPWSTR)ByteOffset(pDisplayOptions, pDisplayOptions->offsetUserName);
  157. if (pDisplayOptions->offsetPassword)
  158. pszPassword = (LPWSTR)ByteOffset(pDisplayOptions, pDisplayOptions->offsetPassword);
  159. Trace((TEXT("Display Options: server = %s; user = %s; pw = %s"),
  160. pszServer?pszServer:TEXT("none"),
  161. pszUserName?pszUserName:TEXT("none"),
  162. pszPassword?pszPassword:TEXT("none")));
  163. }
  164. }
  165. }
  166. //
  167. // Create and initialize the ISecurityInformation object.
  168. //
  169. hr = DSCreateISecurityInfoObjectEx(pObjectPath,
  170. pClass,
  171. pszServer,
  172. pszUserName,
  173. pszPassword,
  174. dwFlags,
  175. &m_pSI,
  176. NULL,
  177. NULL,
  178. 0);
  179. exit_gracefully:
  180. ReleaseStgMedium(&medDisplayOptions);
  181. ReleaseStgMedium(&medObjectNames);
  182. TraceLeaveResult(hr);
  183. }
  184. /*----------------------------------------------------------------------------
  185. / IShellPropSheetExt
  186. /----------------------------------------------------------------------------*/
  187. STDMETHODIMP
  188. CDsSecurity::AddPages(LPFNADDPROPSHEETPAGE lpfnAddPage,
  189. LPARAM lParam)
  190. {
  191. HRESULT hr = E_FAIL;
  192. TraceEnter(TRACE_SECURITY, "CDsSecurity::AddPages");
  193. if (m_pSI != NULL)
  194. {
  195. HPROPSHEETPAGE hPermPage = NULL;
  196. hr = _CreateSecurityPage(m_pSI, &hPermPage);
  197. if (NULL != hPermPage && !lpfnAddPage(hPermPage, lParam))
  198. DestroyPropertySheetPage(hPermPage);
  199. }
  200. TraceLeaveResult(hr);
  201. }
  202. /*---------------------------------------------------------------------------*/
  203. STDMETHODIMP
  204. CDsSecurity::ReplacePage(UINT /* uPageID */,
  205. LPFNADDPROPSHEETPAGE /* lpfnReplaceWith */,
  206. LPARAM /* lParam */)
  207. {
  208. return E_NOTIMPL;
  209. }
  210. /*----------------------------------------------------------------------------
  211. / IContextMenu
  212. /----------------------------------------------------------------------------*/
  213. STDMETHODIMP
  214. CDsSecurity::QueryContextMenu(HMENU hMenu,
  215. UINT indexMenu,
  216. UINT idCmdFirst,
  217. UINT /*idCmdLast*/,
  218. UINT /*uFlags*/)
  219. {
  220. TCHAR szBuffer[MAX_PATH];
  221. MENUITEMINFO mii;
  222. int idMax = idCmdFirst;
  223. TraceEnter(TRACE_SECURITY, "CDsSecurity::QueryContextMenu");
  224. mii.cbSize = sizeof(mii);
  225. mii.fMask = MIIM_TYPE | MIIM_ID;
  226. mii.fType = MFT_STRING;
  227. //NTRAID#NTBUG9-578983-2002/04/02-hiteshr
  228. // Merge our verbs into the menu we were given
  229. LoadString(GLOBAL_HINSTANCE, IDS_SECURITY, szBuffer, ARRAYSIZE(szBuffer));
  230. mii.dwTypeData = szBuffer;
  231. mii.cch = lstrlen(szBuffer);
  232. mii.wID = idMax++;
  233. InsertMenuItem(hMenu,
  234. indexMenu++,
  235. TRUE /*fByPosition*/,
  236. &mii);
  237. TraceLeaveValue(ResultFromShort(idMax - idCmdFirst));
  238. }
  239. /*---------------------------------------------------------------------------*/
  240. STDMETHODIMP
  241. CDsSecurity::InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi)
  242. {
  243. HRESULT hr = E_FAIL;
  244. TraceEnter(TRACE_SECURITY, "CDsSecurity::InvokeCommand");
  245. if (HIWORD(lpcmi->lpVerb) != 0)
  246. TraceLeaveResult(E_NOTIMPL);
  247. TraceAssert(LOWORD(lpcmi->lpVerb) == 0);
  248. // REVIEW If they ever get around to making property pages work
  249. // for DS objects, we can replace this with
  250. // ShellExecuteEx(verb=Properties, parameters=Security) [see ..\rshx32\rshx32.cpp]
  251. if (m_pSI != NULL)
  252. hr = _EditSecurity(lpcmi->hwnd, m_pSI);
  253. TraceLeaveResult(hr);
  254. }
  255. /*---------------------------------------------------------------------------*/
  256. STDMETHODIMP
  257. CDsSecurity::GetCommandString(UINT_PTR /*idCmd*/,
  258. UINT uFlags,
  259. LPUINT /*reserved*/,
  260. LPSTR pszName,
  261. UINT ccMax)
  262. {
  263. if (uFlags == GCS_HELPTEXT)
  264. {
  265. LoadString(GLOBAL_HINSTANCE, IDS_SECURITYHELP, (LPTSTR)pszName, ccMax);
  266. return S_OK;
  267. }
  268. return E_NOTIMPL;
  269. }