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.

254 lines
5.9 KiB

  1. // AclPage.cpp : Implementation of ISecurityInformation and IDataObject
  2. #include "stdafx.h"
  3. #include "AclPage.h"
  4. #include "windns.h"
  5. #include "resource.h"
  6. #ifdef _DEBUG
  7. #define new DEBUG_NEW
  8. #undef THIS_FILE
  9. static char THIS_FILE[] = __FILE__;
  10. #endif
  11. ///////////////////////////////////////////////////////
  12. // class CFileSecurityDataObject
  13. CFileSecurityDataObject::CFileSecurityDataObject()
  14. : m_cRef(1)
  15. {
  16. }
  17. CFileSecurityDataObject::~CFileSecurityDataObject()
  18. {
  19. TRACE(_T("CFileSecurityDataObject::~CFileSecurityDataObject m_cRef=%d\n"), m_cRef);
  20. }
  21. void
  22. CFileSecurityDataObject::Initialize(
  23. IN LPCTSTR lpszComputerName,
  24. IN LPCTSTR lpszFolder
  25. )
  26. {
  27. m_cstrComputerName = lpszComputerName;
  28. m_cstrFolder = lpszFolder;
  29. GetFullPathLocalOrRemote(lpszComputerName, lpszFolder, m_cstrPath);
  30. m_cfIDList = (CLIPFORMAT)RegisterClipboardFormat(CFSTR_SHELLIDLIST);
  31. }
  32. ////////////////////////////////
  33. // IUnknown methods
  34. ////////////////////////////////
  35. STDMETHODIMP
  36. CFileSecurityDataObject::QueryInterface(REFIID riid, LPVOID *ppv)
  37. {
  38. if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IDataObject))
  39. {
  40. *ppv = this;
  41. m_cRef++;
  42. return S_OK;
  43. } else
  44. {
  45. *ppv = NULL;
  46. return E_NOINTERFACE;
  47. }
  48. }
  49. STDMETHODIMP_(ULONG)
  50. CFileSecurityDataObject::AddRef()
  51. {
  52. return ++m_cRef;
  53. }
  54. STDMETHODIMP_(ULONG)
  55. CFileSecurityDataObject::Release()
  56. {
  57. if (--m_cRef == 0)
  58. {
  59. delete this;
  60. return 0;
  61. }
  62. return m_cRef;
  63. }
  64. STDMETHODIMP
  65. CFileSecurityDataObject::GetData(
  66. FORMATETC __RPC_FAR * pFormatEtcIn,
  67. STGMEDIUM __RPC_FAR * pMedium
  68. )
  69. {
  70. ASSERT(pFormatEtcIn);
  71. ASSERT(pMedium);
  72. if (m_cfIDList != pFormatEtcIn->cfFormat)
  73. return DV_E_FORMATETC;
  74. LPITEMIDLIST pidl = NULL;
  75. LPITEMIDLIST pidlR = NULL;
  76. HRESULT hr = GetFolderPIDList(&pidl);
  77. if (SUCCEEDED(hr))
  78. {
  79. pidlR = ILClone(ILFindLastID(pidl)); // relative IDList
  80. ILRemoveLastID(pidl); // folder IDList
  81. int cidl = 1;
  82. UINT offset = sizeof(CIDA) + sizeof(UINT)*cidl;
  83. UINT cbFolder = ILGetSize(pidl);
  84. UINT cbRelative = ILGetSize(pidlR);
  85. UINT cbTotal = offset + cbFolder + cbRelative;
  86. HGLOBAL hGlobal = ::GlobalAlloc (GPTR, cbTotal);
  87. if ( hGlobal )
  88. {
  89. LPIDA pida = (LPIDA)hGlobal;
  90. pida->cidl = cidl;
  91. pida->aoffset[0] = offset;
  92. MoveMemory(((LPBYTE)hGlobal+offset), pidl, cbFolder);
  93. offset += cbFolder;
  94. pida->aoffset[1] = offset;
  95. MoveMemory(((LPBYTE)hGlobal+offset), pidlR, cbRelative);
  96. pMedium->hGlobal = hGlobal;
  97. } else
  98. {
  99. hr = E_OUTOFMEMORY;
  100. }
  101. if (pidl)
  102. ILFree(pidl);
  103. if (pidlR)
  104. ILFree(pidlR);
  105. }
  106. return hr;
  107. }
  108. HRESULT
  109. CFileSecurityDataObject::GetFolderPIDList(
  110. OUT LPITEMIDLIST *ppidl
  111. )
  112. {
  113. ASSERT(!m_cstrPath.IsEmpty());
  114. ASSERT(ppidl);
  115. ASSERT(!*ppidl); // prevent memory leak
  116. *ppidl = ILCreateFromPath(m_cstrPath);
  117. return ((*ppidl) ? S_OK : E_FAIL);
  118. }
  119. ///////////////////////////////////////////////
  120. // File security
  121. // Security Shell extension CLSID - {1F2E5C40-9550-11CE-99D2-00AA006E086C}
  122. const CLSID CLSID_ShellExtSecurity =
  123. {0x1F2E5C40, 0x9550, 0x11CE, {0x99, 0xD2, 0x0, 0xAA, 0x0, 0x6E, 0x08, 0x6C}};
  124. BOOL CALLBACK
  125. AddPageProc(HPROPSHEETPAGE hPage, LPARAM lParam)
  126. {
  127. // pass out the created page handle
  128. *((HPROPSHEETPAGE *)lParam) = hPage;
  129. return TRUE;
  130. }
  131. HRESULT
  132. CreateFileSecurityPropPage(
  133. HPROPSHEETPAGE *phOutPage,
  134. LPDATAOBJECT pDataObject
  135. )
  136. {
  137. ASSERT(phOutPage);
  138. ASSERT(pDataObject);
  139. IShellExtInit *piShellExtInit = NULL;
  140. HRESULT hr = CoCreateInstance(CLSID_ShellExtSecurity,
  141. NULL,
  142. CLSCTX_INPROC_SERVER,
  143. IID_IShellExtInit,
  144. (void **)&piShellExtInit);
  145. if (SUCCEEDED(hr))
  146. {
  147. hr = piShellExtInit->Initialize(NULL, pDataObject, 0);
  148. if (SUCCEEDED(hr))
  149. {
  150. IShellPropSheetExt *piSPSE = NULL;
  151. hr = piShellExtInit->QueryInterface(IID_IShellPropSheetExt, (void **)&piSPSE);
  152. if (SUCCEEDED(hr))
  153. {
  154. hr = piSPSE->AddPages(AddPageProc, (LPARAM)phOutPage);
  155. piSPSE->Release();
  156. }
  157. }
  158. piShellExtInit->Release();
  159. }
  160. return hr;
  161. }
  162. INT_PTR
  163. PopupPermissionDialog(
  164. HWND hWnd,
  165. LPCTSTR target,
  166. LPCTSTR folder
  167. )
  168. {
  169. INT_PTR iReturn = -2;
  170. HPROPSHEETPAGE phPages[1];
  171. int cPages = 1;
  172. CString cstrSheetTitle = folder;
  173. CString path;
  174. GetFullPathLocalOrRemote(target, folder, path);
  175. if (!SupportsSecurityACLs(path))
  176. {
  177. DoHelpMessageBox(hWnd,IDS_FAT_DRIVE_WARNING, MB_APPLMODAL | MB_OK | MB_ICONEXCLAMATION, 0);
  178. return 0;
  179. }
  180. phPages[0] = 0;
  181. HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
  182. if (FAILED(hr))
  183. {return iReturn;}
  184. // create "File Security" property page
  185. CFileSecurityDataObject *pfsDataObject = new CFileSecurityDataObject;
  186. if (!pfsDataObject)
  187. {
  188. hr = E_OUTOFMEMORY;
  189. // destroy pages that have not been passed to the PropertySheet function
  190. DestroyPropertySheetPage(phPages[0]);
  191. goto PopupPermissionDialog_Exit;
  192. }
  193. pfsDataObject->Initialize(target, folder);
  194. hr = CreateFileSecurityPropPage(&(phPages[0]), pfsDataObject);
  195. if (SUCCEEDED(hr))
  196. {
  197. cPages = 1;
  198. PROPSHEETHEADER psh;
  199. ZeroMemory(&psh, sizeof(psh));
  200. psh.dwSize = sizeof(psh);
  201. psh.dwFlags = PSH_DEFAULT | PSH_NOAPPLYNOW;
  202. psh.hwndParent = hWnd;
  203. psh.hInstance = AfxGetResourceHandle();
  204. psh.pszCaption = cstrSheetTitle;
  205. psh.nPages = cPages;
  206. psh.phpage = phPages;
  207. // create the property sheet
  208. iReturn = PropertySheet(&psh);
  209. }
  210. pfsDataObject->Release();
  211. PopupPermissionDialog_Exit:
  212. CoUninitialize();
  213. return iReturn;
  214. }