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.

217 lines
4.8 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1998 - 1999
  6. //
  7. // File: shellext.cpp
  8. //
  9. //--------------------------------------------------------------------------
  10. #include "pch.h"
  11. #include "util.h"
  12. #include "dsuiwiz.h"
  13. #include "shellext.h"
  14. #include "delegwiz.h"
  15. //#define _MMC_HACK
  16. #ifdef _MMC_HACK
  17. BOOL CALLBACK EnumThreadWndProc(HWND hwnd, /* enumerated HWND */
  18. LPARAM lParam /* pass a HWND* for return value*/ )
  19. {
  20. ASSERT(hwnd);
  21. HWND hParentWnd = GetParent(hwnd);
  22. // the main window of the MMC console should staitsfy this condition
  23. if ( ((hParentWnd == GetDesktopWindow()) || (hParentWnd == NULL)) && IsWindowVisible(hwnd) )
  24. {
  25. HWND* pH = (HWND*)lParam;
  26. *pH = hwnd;
  27. return FALSE; // stop enumerating
  28. }
  29. return TRUE;
  30. }
  31. HWND FindMMCMainWindow()
  32. {
  33. DWORD dwThreadID = ::GetCurrentThreadId();
  34. ASSERT(dwThreadID != 0);
  35. HWND hWnd = NULL;
  36. BOOL bEnum = EnumThreadWindows(dwThreadID, EnumThreadWndProc,(LPARAM)&hWnd);
  37. ASSERT(hWnd != NULL);
  38. return hWnd;
  39. }
  40. #endif // _MMC_HACK
  41. HWND _GetParentWindow(LPDATAOBJECT pDataObj )
  42. {
  43. HWND hWnd = NULL;
  44. STGMEDIUM ObjMedium = {TYMED_NULL};
  45. FORMATETC fmte = {(CLIPFORMAT)_Module.GetCfParentHwnd(),
  46. NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
  47. if (SUCCEEDED(pDataObj->GetData(&fmte, &ObjMedium)))
  48. {
  49. hWnd = *((HWND*)ObjMedium.hGlobal);
  50. ::ReleaseStgMedium(&ObjMedium);
  51. }
  52. #ifdef _MMC_HACK
  53. if (hWnd == NULL)
  54. hWnd = FindMMCMainWindow();
  55. #endif
  56. return hWnd;
  57. }
  58. HRESULT _GetObjectLDAPPath(IDataObject* pDataObj, CWString& szLDAPPath)
  59. {
  60. TRACE(L"entering _GetObjectLDAPPath()\n");
  61. if (pDataObj == NULL)
  62. {
  63. // no data object, no name
  64. szLDAPPath = L"";
  65. return E_INVALIDARG;
  66. }
  67. //crack the data object and get the name
  68. STGMEDIUM ObjMedium = {TYMED_NULL};
  69. FORMATETC fmte = {(CLIPFORMAT)_Module.GetCfDsObjectNames(),
  70. NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
  71. // Get the path to the DS object from the data object.
  72. HRESULT hr = pDataObj->GetData(&fmte, &ObjMedium);
  73. if (SUCCEEDED(hr))
  74. {
  75. LPDSOBJECTNAMES pDsObjectNames = (LPDSOBJECTNAMES)ObjMedium.hGlobal;
  76. if (pDsObjectNames->cItems == 1)
  77. {
  78. LPCWSTR lpsz = (LPCWSTR)ByteOffset(pDsObjectNames,
  79. pDsObjectNames->aObjects[0].offsetName);
  80. if ((lpsz == NULL) || (lpsz[0] == NULL))
  81. {
  82. szLDAPPath = L"";
  83. hr = E_INVALIDARG;
  84. }
  85. else
  86. {
  87. szLDAPPath = lpsz;
  88. }
  89. }
  90. else
  91. {
  92. szLDAPPath = L"";
  93. hr = E_INVALIDARG;
  94. }
  95. ::ReleaseStgMedium(&ObjMedium);
  96. }
  97. TRACE(L"returning from _GetObjectLDAPPath(_, %s), hr = 0x%x\n", (LPCWSTR)szLDAPPath, hr);
  98. return hr;
  99. }
  100. /////////////////////////////////////////////////////////////////////////
  101. // IShellExtInit methods
  102. STDMETHODIMP CShellExt::Initialize(
  103. LPCITEMIDLIST pidlFolder,
  104. LPDATAOBJECT lpdobj,
  105. HKEY hKeyProgID)
  106. {
  107. if (lpdobj == NULL)
  108. return E_INVALIDARG;
  109. m_hParentWnd = _GetParentWindow(lpdobj);
  110. if ((m_hParentWnd == NULL) || !::IsWindow(m_hParentWnd))
  111. return E_INVALIDARG;
  112. return _GetObjectLDAPPath(lpdobj, m_szObjectLDAPPath);
  113. }
  114. /////////////////////////////////////////////////////////////////////////
  115. // IContextMenu methods
  116. STDMETHODIMP CShellExt::QueryContextMenu(
  117. HMENU hMenu,
  118. UINT indexMenu,
  119. UINT idCmdFirst,
  120. UINT idCmdLast,
  121. UINT uFlags)
  122. {
  123. // only one menu item to insert (position zero)
  124. TCHAR szContextMenu[128];
  125. LoadStringHelper(IDS_DELEGWIZ_CONTEXT_MENU, szContextMenu, ARRAYSIZE(szContextMenu));
  126. UINT countMenuItems = 1;
  127. ::InsertMenu(hMenu, indexMenu, MF_STRING | MF_BYPOSITION,
  128. idCmdFirst /* + 0*/, szContextMenu);
  129. return MAKE_SCODE(SEVERITY_SUCCESS, 0, countMenuItems);
  130. }
  131. STDMETHODIMP CShellExt::GetCommandString(
  132. UINT_PTR idCmd,
  133. UINT uFlags,
  134. UINT * reserved,
  135. LPSTR pszName,
  136. UINT cchMax)
  137. {
  138. if (uFlags != GCS_HELPTEXT)
  139. {
  140. return S_OK;
  141. }
  142. //
  143. // Copy the requested string to the caller's buffer.
  144. //
  145. if (idCmd == 0) // we inserted the zero-th element
  146. {
  147. // this is really WCHAR, as Jim swears, so lets trust him...
  148. LPWSTR lpszHack = (LPWSTR)pszName;
  149. if (::LoadStringHelper(IDS_DELEGWIZ_CONTEXT_MENU_DESCR,
  150. lpszHack, cchMax))
  151. {
  152. return S_OK;
  153. }
  154. }
  155. return E_INVALIDARG;
  156. }
  157. STDMETHODIMP CShellExt::InvokeCommand(
  158. LPCMINVOKECOMMANDINFO lpcmi)
  159. {
  160. if (lpcmi == NULL)
  161. return E_INVALIDARG;
  162. //Check if you have read and write permission
  163. if( InitCheckAccess(m_hParentWnd, m_szObjectLDAPPath) != S_OK )
  164. {
  165. return S_OK;
  166. }
  167. if (!HIWORD(lpcmi->lpVerb))
  168. {
  169. UINT iCmd = LOWORD(lpcmi->lpVerb);
  170. if (iCmd == 0)
  171. {
  172. ASSERT(m_hParentWnd != NULL);
  173. CDelegWiz delegWiz;
  174. delegWiz.InitFromLDAPPath(m_szObjectLDAPPath);
  175. delegWiz.DoModal(m_hParentWnd);
  176. }
  177. }
  178. return S_OK;
  179. }