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.

446 lines
12 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1993.
  5. //
  6. // File: share.cxx
  7. //
  8. // Contents: Shell extension handler for sharing
  9. //
  10. // Classes: CShare
  11. //
  12. // History: 4-Apr-95 BruceFo Created
  13. //
  14. //--------------------------------------------------------------------------
  15. #include "headers.hxx"
  16. #pragma hdrstop
  17. #include "shrpage.hxx"
  18. #include "shrpage2.hxx"
  19. #include "share.hxx"
  20. #include "acl.hxx"
  21. #include "util.hxx"
  22. #include "resource.h"
  23. //--------------------------------------------------------------------------
  24. //+-------------------------------------------------------------------------
  25. //
  26. // Member: CShare::CShare
  27. //
  28. // Synopsis: Constructor
  29. //
  30. // History: 4-Apr-95 BruceFo Created
  31. //
  32. //--------------------------------------------------------------------------
  33. CShare::CShare(VOID) :
  34. _uRefs(0),
  35. _fPathChecked(FALSE),
  36. _fMultipleSharesSelected (FALSE)
  37. {
  38. INIT_SIG(CShare);
  39. AddRef(); // give it the correct initial reference count. add to the DLL reference count
  40. _szPath[0] = 0;
  41. }
  42. //+-------------------------------------------------------------------------
  43. //
  44. // Member: CShare::~CShare
  45. //
  46. // Synopsis: Destructor
  47. //
  48. // History: 4-Apr-95 BruceFo Created
  49. //
  50. //--------------------------------------------------------------------------
  51. CShare::~CShare()
  52. {
  53. CHECK_SIG(CShare);
  54. }
  55. //
  56. // Retrieve a PIDL from the HIDA.
  57. //
  58. STDAPI_(LPITEMIDLIST)
  59. IDA_FullIDList(
  60. CIDA * pidaIn
  61. , UINT idxIn
  62. )
  63. {
  64. LPITEMIDLIST pidl = NULL;
  65. LPCITEMIDLIST pidlParent = IDA_GetIDListPtr( pidaIn, (UINT) -1 );
  66. if ( NULL != pidlParent )
  67. {
  68. LPCITEMIDLIST pidlRel = IDA_GetIDListPtr( pidaIn, idxIn );
  69. if ( NULL != pidlRel )
  70. {
  71. pidl = ILCombine( pidlParent, pidlRel );
  72. }
  73. }
  74. return pidl;
  75. }
  76. //+-------------------------------------------------------------------------
  77. //
  78. // Member: CShare::Initialize
  79. //
  80. // Derivation: IShellExtInit
  81. //
  82. // Synopsis: Initialize the shell extension. Stashes away the argument data.
  83. //
  84. // History: 4-Apr-95 BruceFo Created
  85. //
  86. // Notes: This method can be called more than once.
  87. //
  88. //--------------------------------------------------------------------------
  89. STDMETHODIMP
  90. CShare::Initialize(
  91. LPCITEMIDLIST /*pidlFolder*/,
  92. LPDATAOBJECT pDataObject,
  93. HKEY /*hkeyProgID*/
  94. )
  95. {
  96. CHECK_SIG(CShare);
  97. HRESULT hr = E_FAIL;
  98. if (pDataObject && _szPath[0] == 0)
  99. {
  100. STGMEDIUM medium;
  101. FORMATETC fmte = {CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
  102. hr = pDataObject->GetData(&fmte, &medium);
  103. if (SUCCEEDED(hr))
  104. {
  105. // Get the count of shares that have been selected. Display the page only
  106. // if 1 share is selected but not for multiple shares.
  107. UINT nCntFiles = ::DragQueryFile((HDROP) medium.hGlobal, (UINT)-1, _szPath, ARRAYLEN (_szPath));
  108. if ( nCntFiles > 1 )
  109. {
  110. _fMultipleSharesSelected = TRUE;
  111. }
  112. DragQueryFile((HDROP)medium.hGlobal, 0, _szPath, ARRAYLEN(_szPath));
  113. ReleaseStgMedium(&medium);
  114. hr = S_OK;
  115. }
  116. }
  117. if (FAILED(hr) && _szPath[0] == 0 )
  118. {
  119. STGMEDIUM med;
  120. LPIDA pida = DataObj_GetHIDA(pDataObject, &med);
  121. if (pida)
  122. {
  123. if (pida->cidl > 1)
  124. {
  125. _fMultipleSharesSelected = TRUE;
  126. }
  127. // Only grab the first guy.
  128. LPITEMIDLIST pidl = IDA_FullIDList( pida, 0 );
  129. if ( NULL != pidl )
  130. {
  131. LPCITEMIDLIST pidlParent = IDA_GetIDListPtr( pida, (UINT) -1 );
  132. if (NULL != pidlParent)
  133. {
  134. IShellFolder * psf;
  135. LPCITEMIDLIST pidlLast;
  136. hr = SHBindToParent(pidl, IID_IShellFolder, (void**)&psf, &pidlLast);
  137. if (SUCCEEDED(hr))
  138. {
  139. hr = DisplayNameOf(psf, pidlLast, SHGDN_NORMAL | SHGDN_FORPARSING, _szPath, ARRAYLEN(_szPath));
  140. psf->Release();
  141. }
  142. }
  143. ILFree(pidl);
  144. }
  145. HIDA_ReleaseStgMedium(pida, &med);
  146. }
  147. }
  148. return hr;
  149. }
  150. //+-------------------------------------------------------------------------
  151. //
  152. // Member: CShare::AddPages
  153. //
  154. // Derivation: IShellPropSheetExt
  155. //
  156. // Synopsis: (from shlobj.h)
  157. // "The explorer calls this member function when it finds a
  158. // registered property sheet extension for a particular type
  159. // of object. For each additional page, the extension creates
  160. // a page object by calling CreatePropertySheetPage API and
  161. // calls lpfnAddPage.
  162. //
  163. // Arguments: lpfnAddPage -- Specifies the callback function.
  164. // lParam -- Specifies the opaque handle to be passed to the
  165. // callback function.
  166. //
  167. // History: 4-Apr-95 BruceFo Created
  168. //
  169. //--------------------------------------------------------------------------
  170. STDMETHODIMP
  171. CShare::AddPages(
  172. LPFNADDPROPSHEETPAGE lpfnAddPage,
  173. LPARAM lParam
  174. )
  175. {
  176. CHECK_SIG(CShare);
  177. if (!_fMultipleSharesSelected && _OKToShare())
  178. {
  179. //
  180. // Create a property sheet page object from a dialog box.
  181. //
  182. BOOL bSimpleUI = IsSimpleUI();
  183. CShareBase* pPage = NULL;
  184. if (bSimpleUI)
  185. {
  186. pPage = new CSimpleSharingPage();
  187. }
  188. else
  189. {
  190. pPage = new CSharingPropertyPage(FALSE);
  191. }
  192. if (NULL != pPage)
  193. {
  194. appAssert(_szPath[0]);
  195. HRESULT hr = pPage->InitInstance(_szPath);
  196. if (SUCCEEDED(hr))
  197. {
  198. PROPSHEETPAGE psp;
  199. psp.dwSize = sizeof(psp); // no extra data.
  200. psp.dwFlags = PSP_USEREFPARENT | PSP_USECALLBACK;
  201. psp.hInstance = g_hInstance;
  202. psp.pszTemplate = bSimpleUI ? MAKEINTRESOURCE(IDD_SIMPLE_SHARE_PROPERTIES) : MAKEINTRESOURCE(IDD_SHARE_PROPERTIES);
  203. psp.hIcon = NULL;
  204. psp.pszTitle = NULL;
  205. psp.pfnDlgProc = CShareBase::DlgProcPage;
  206. psp.lParam = (LPARAM)pPage; // transfer ownership
  207. psp.pfnCallback = CShareBase::PageCallback;
  208. psp.pcRefParent = &g_NonOLEDLLRefs;
  209. // This AddRef's pPage. See CShareBase::PageCallback.
  210. HPROPSHEETPAGE hpage = CreatePropertySheetPage(&psp);
  211. if (NULL != hpage)
  212. {
  213. BOOL fAdded = (*lpfnAddPage)(hpage, lParam);
  214. if (!fAdded)
  215. {
  216. // This Release's pPage.
  217. DestroyPropertySheetPage(hpage);
  218. }
  219. // else the property sheet has a reference to pPage.
  220. }
  221. }
  222. // Release initial ref. This frees pPage is anything failed above.
  223. pPage->Release();
  224. }
  225. }
  226. return S_OK;
  227. }
  228. //+-------------------------------------------------------------------------
  229. //
  230. // Member: CShare::ReplacePages
  231. //
  232. // Derivation: IShellPropSheetExt
  233. //
  234. // Synopsis: (From shlobj.h)
  235. // "The explorer never calls this member of property sheet
  236. // extensions. The explorer calls this member of control panel
  237. // extensions, so that they can replace some of default control
  238. // panel pages (such as a page of mouse control panel)."
  239. //
  240. // Arguments: uPageID -- Specifies the page to be replaced.
  241. // lpfnReplace -- Specifies the callback function.
  242. // lParam -- Specifies the opaque handle to be passed to the
  243. // callback function.
  244. //
  245. // History: 4-Apr-95 BruceFo Created
  246. //
  247. //--------------------------------------------------------------------------
  248. STDMETHODIMP
  249. CShare::ReplacePage(
  250. UINT /*uPageID*/,
  251. LPFNADDPROPSHEETPAGE /*lpfnReplaceWith*/,
  252. LPARAM /*lParam*/
  253. )
  254. {
  255. CHECK_SIG(CShare);
  256. appAssert(!"CShare::ReplacePage called, not implemented");
  257. return E_NOTIMPL;
  258. }
  259. //+-------------------------------------------------------------------------
  260. //
  261. // Member: CShare::QueryContextMenu
  262. //
  263. // Derivation: IContextMenu
  264. //
  265. // Synopsis: Called when shell wants to add context menu items.
  266. //
  267. // History: 4-Apr-95 BruceFo Created
  268. //
  269. //--------------------------------------------------------------------------
  270. STDMETHODIMP
  271. CShare::QueryContextMenu(
  272. HMENU hmenu,
  273. UINT indexMenu,
  274. UINT idCmdFirst,
  275. UINT /*idCmdLast*/,
  276. UINT uFlags
  277. )
  278. {
  279. CHECK_SIG(CShare);
  280. if ((hmenu == NULL) || (uFlags & (CMF_DEFAULTONLY | CMF_VERBSONLY)))
  281. {
  282. return S_OK;
  283. }
  284. int cNumberAdded = 0;
  285. UINT idCmd = idCmdFirst;
  286. // 159891 remove context menu if multiple shares selected
  287. if (!_fMultipleSharesSelected && _OKToShare())
  288. {
  289. appAssert(_szPath[0]);
  290. WCHAR szShareMenuItem[50];
  291. LoadString(g_hInstance, IDS_SHARING, szShareMenuItem, ARRAYLEN(szShareMenuItem));
  292. if (InsertMenu(hmenu, indexMenu, MF_STRING | MF_BYPOSITION, idCmd++, szShareMenuItem))
  293. {
  294. cNumberAdded++;
  295. InsertMenu(hmenu, indexMenu, MF_SEPARATOR | MF_BYPOSITION, 0, NULL);
  296. }
  297. }
  298. return ResultFromScode(MAKE_SCODE(SEVERITY_SUCCESS, FACILITY_NULL, (USHORT)cNumberAdded));
  299. }
  300. //+-------------------------------------------------------------------------
  301. //
  302. // Member: CShare::InvokeCommand
  303. //
  304. // Derivation: IContextMenu
  305. //
  306. // Synopsis: Called when the shell wants to invoke a context menu item.
  307. //
  308. // History: 4-Apr-95 BruceFo Created
  309. //
  310. //--------------------------------------------------------------------------
  311. STDMETHODIMP
  312. CShare::InvokeCommand(
  313. LPCMINVOKECOMMANDINFO pici
  314. )
  315. {
  316. CHECK_SIG(CShare);
  317. HRESULT hr = E_INVALIDARG; // assume error.
  318. if (0 == HIWORD(pici->lpVerb))
  319. {
  320. appAssert(_szPath[0]);
  321. hr = ShowShareFolderUIW(pici->hwnd, _szPath);
  322. }
  323. else
  324. {
  325. // FEATURE: compare the strings if not a MAKEINTRESOURCE?
  326. }
  327. return hr;
  328. }
  329. //+-------------------------------------------------------------------------
  330. //
  331. // Member: CShare::GetCommandString
  332. //
  333. // Derivation: IContextMenu
  334. //
  335. // Synopsis: Called when the shell wants to get a help string or the
  336. // menu string.
  337. //
  338. // History: 4-Apr-95 BruceFo Created
  339. //
  340. //--------------------------------------------------------------------------
  341. STDMETHODIMP
  342. CShare::GetCommandString(
  343. UINT_PTR /*idCmd*/,
  344. UINT uType,
  345. UINT* /*pwReserved*/,
  346. LPSTR pszName,
  347. UINT cchMax
  348. )
  349. {
  350. CHECK_SIG(CShare);
  351. if (uType == GCS_HELPTEXT)
  352. {
  353. LoadStringW(g_hInstance, IDS_MENUHELP, (LPWSTR)pszName, cchMax);
  354. return NOERROR;
  355. }
  356. else
  357. {
  358. LoadStringW(g_hInstance, IDS_SHARING, (LPWSTR)pszName, cchMax);
  359. return NOERROR;
  360. }
  361. }
  362. //+-------------------------------------------------------------------------
  363. //
  364. // Member: CShare::_OKToShare
  365. //
  366. // Synopsis: Determine if it is ok to share the current object. It stashes
  367. // away the current path by querying the cached IDataObject.
  368. //
  369. // History: 4-Apr-95 BruceFo Created
  370. //
  371. //--------------------------------------------------------------------------
  372. BOOL
  373. CShare::_OKToShare(VOID)
  374. {
  375. CHECK_SIG(CShare);
  376. if (!_fPathChecked)
  377. {
  378. _fPathChecked = TRUE;
  379. _fOkToSharePath = (S_OK == CanShareFolderW(_szPath));
  380. }
  381. return _fOkToSharePath;
  382. }