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.

808 lines
22 KiB

  1. //
  2. // ISecurityInformation interface implementation
  3. //
  4. #include <aclui.h>
  5. #include "faxui.h"
  6. class CFaxSecurity : public ISecurityInformation
  7. {
  8. protected:
  9. ULONG m_cRef;
  10. STDMETHOD(MakeSelfRelativeCopy)(PSECURITY_DESCRIPTOR psdOriginal,
  11. PSECURITY_DESCRIPTOR* ppsdNew);
  12. public:
  13. CFaxSecurity() : m_cRef(1) {}
  14. virtual ~CFaxSecurity() {}
  15. // IUnknown methods
  16. STDMETHOD(QueryInterface)(REFIID, LPVOID *);
  17. STDMETHOD_(ULONG, AddRef)();
  18. STDMETHOD_(ULONG, Release)();
  19. // ISecurityInformation methods
  20. STDMETHOD(GetObjectInformation)(PSI_OBJECT_INFO pObjectInfo);
  21. STDMETHOD(GetSecurity)(SECURITY_INFORMATION si,
  22. PSECURITY_DESCRIPTOR *ppSD,
  23. BOOL fDefault);
  24. STDMETHOD(SetSecurity)(SECURITY_INFORMATION si,
  25. PSECURITY_DESCRIPTOR pSD);
  26. STDMETHOD(GetAccessRights)(const GUID* pguidObjectType,
  27. DWORD dwFlags,
  28. PSI_ACCESS *ppAccess,
  29. ULONG *pcAccesses,
  30. ULONG *piDefaultAccess);
  31. STDMETHOD(MapGeneric)(const GUID *pguidObjectType,
  32. UCHAR *pAceFlags,
  33. ACCESS_MASK *pmask);
  34. STDMETHOD(GetInheritTypes)(PSI_INHERIT_TYPE *ppInheritTypes,
  35. ULONG *pcInheritTypes);
  36. STDMETHOD(PropertySheetPageCallback)(HWND hwnd,
  37. UINT uMsg,
  38. SI_PAGE_TYPE uPage);
  39. };
  40. CFaxSecurity* g_pFaxSecurity = NULL;
  41. ///////////////////////////////////////////////////////////
  42. //
  43. // IUnknown methods
  44. //
  45. ///////////////////////////////////////////////////////////
  46. STDMETHODIMP_(ULONG)
  47. CFaxSecurity::AddRef()
  48. {
  49. return ++m_cRef;
  50. }
  51. STDMETHODIMP_(ULONG)
  52. CFaxSecurity::Release()
  53. {
  54. if (--m_cRef == 0)
  55. {
  56. delete this;
  57. g_pFaxSecurity = NULL;
  58. return 0;
  59. }
  60. return m_cRef;
  61. }
  62. STDMETHODIMP
  63. CFaxSecurity::QueryInterface(REFIID riid, LPVOID FAR* ppv)
  64. {
  65. if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_ISecurityInformation))
  66. {
  67. *ppv = (LPSECURITYINFO)this;
  68. m_cRef++;
  69. return S_OK;
  70. }
  71. else
  72. {
  73. *ppv = NULL;
  74. return E_NOINTERFACE;
  75. }
  76. }
  77. ///////////////////////////////////////////////////////////
  78. //
  79. // ISecurityInformation methods
  80. //
  81. ///////////////////////////////////////////////////////////
  82. STDMETHODIMP
  83. CFaxSecurity::GetObjectInformation(PSI_OBJECT_INFO pObjectInfo)
  84. // *** ISecurityInformation methods implementation ***
  85. /*
  86. - CFaxSecurity::GetObjectInformation
  87. -
  88. * Purpose:
  89. * Performs an access check against the fax service security descriptor
  90. *
  91. * Arguments:
  92. * [in] pObjectInfo - pointer to object information structure.
  93. *
  94. * Return:
  95. * OLE error code
  96. */
  97. {
  98. DWORD ec = ERROR_SUCCESS;
  99. if(!Connect(NULL, FALSE))
  100. {
  101. return S_FALSE;
  102. }
  103. HANDLE hPrivBeforeSE_TAKE_OWNERSHIP = INVALID_HANDLE_VALUE;
  104. HANDLE hPrivBeforeSE_SECURITY = INVALID_HANDLE_VALUE;
  105. if( pObjectInfo == NULL )
  106. {
  107. Error(("Invalid parameter - pObjectInfo == NULL\n"));
  108. Assert( pObjectInfo != NULL );
  109. return E_POINTER;
  110. }
  111. //
  112. // Set Flags
  113. //
  114. pObjectInfo->dwFlags = SI_EDIT_ALL |
  115. SI_NO_TREE_APPLY |
  116. SI_NO_ACL_PROTECT |
  117. SI_ADVANCED |
  118. SI_PAGE_TITLE;
  119. //
  120. // Check if to add SI_READONLY
  121. //
  122. if (!FaxAccessCheckEx(g_hFaxSvcHandle, WRITE_DAC, NULL))
  123. {
  124. ec = GetLastError();
  125. if (ERROR_SUCCESS == ec)
  126. {
  127. pObjectInfo->dwFlags |= SI_READONLY;
  128. }
  129. else
  130. {
  131. Error(("FaxAccessCheckEx(WRITE_DAC) failed with %d \n", ec));
  132. goto exit;
  133. }
  134. }
  135. //
  136. // Check if to add SI_OWNER_READONLY
  137. //
  138. hPrivBeforeSE_TAKE_OWNERSHIP = EnablePrivilege (SE_TAKE_OWNERSHIP_NAME);
  139. //
  140. // No error checking - If we failed we will get ERROR_ACCESS_DENIED in the access check
  141. //
  142. if (!FaxAccessCheckEx(g_hFaxSvcHandle,WRITE_OWNER, NULL))
  143. {
  144. ec = GetLastError();
  145. if (ERROR_SUCCESS == ec)
  146. {
  147. pObjectInfo->dwFlags |= SI_OWNER_READONLY;
  148. }
  149. else
  150. {
  151. Error(("FaxAccessCheckEx(WRITE_OWNER) failed with %d \n", ec));
  152. goto exit;
  153. }
  154. }
  155. //
  156. // Check if to remove SI_EDIT_AUDITS
  157. //
  158. hPrivBeforeSE_SECURITY = EnablePrivilege (SE_SECURITY_NAME);
  159. //
  160. // No error checking - If we failed we will get ERROR_ACCESS_DENIED in the access check
  161. //
  162. if (!FaxAccessCheckEx(g_hFaxSvcHandle, ACCESS_SYSTEM_SECURITY, NULL))
  163. {
  164. ec = GetLastError();
  165. if (ERROR_SUCCESS == ec)
  166. {
  167. pObjectInfo->dwFlags &= ~SI_EDIT_AUDITS;
  168. }
  169. else
  170. {
  171. Error(("FaxAccessCheckEx(ACCESS_SYSTEM_SECURITY) failed with %d \n", ec));
  172. goto exit;
  173. }
  174. }
  175. //
  176. // Set all other fields
  177. //
  178. static TCHAR tszPageTitle[MAX_PATH] = {0};
  179. if(LoadString((HINSTANCE)g_hResource, IDS_SECURITY_TITLE, tszPageTitle, ARR_SIZE(tszPageTitle)))
  180. {
  181. pObjectInfo->pszPageTitle = tszPageTitle;
  182. }
  183. else
  184. {
  185. ec = GetLastError();
  186. Error(("LoadString(IDS_SECURITY_TITLE) failed with %d \n", ec));
  187. pObjectInfo->pszPageTitle = NULL;
  188. }
  189. static TCHAR tszPrinterName[MAX_PATH] = {0};
  190. if(GetFirstLocalFaxPrinterName(tszPrinterName, ARR_SIZE(tszPrinterName)))
  191. {
  192. pObjectInfo->pszObjectName = tszPrinterName;
  193. }
  194. else
  195. {
  196. ec = GetLastError();
  197. Error(("GetFirstLocalFaxPrinterName() failed with %d \n", ec));
  198. pObjectInfo->pszObjectName = NULL;
  199. }
  200. pObjectInfo->hInstance = (HINSTANCE)g_hResource;
  201. pObjectInfo->pszServerName = NULL;
  202. exit:
  203. ReleasePrivilege (hPrivBeforeSE_SECURITY);
  204. ReleasePrivilege (hPrivBeforeSE_TAKE_OWNERSHIP);
  205. return HRESULT_FROM_WIN32(ec);
  206. } // CFaxSecurity::GetObjectInformation
  207. STDMETHODIMP
  208. CFaxSecurity::GetSecurity(SECURITY_INFORMATION si,
  209. PSECURITY_DESCRIPTOR* ppSD,
  210. BOOL fDefault)
  211. /*
  212. - CFaxSecurityInformation::GetSecurity
  213. -
  214. * Purpose:
  215. * requests a security descriptor for the securable object whose
  216. * security descriptor is being edited. The access control editor
  217. * calls this method to retrieve the object's current or default security descriptor.
  218. *
  219. * Arguments:
  220. * [in] RequestedInformation - security information.
  221. * [out] ppSecurityDescriptor - pointer to security descriptor.
  222. * [in] fDefault - not implemented
  223. *
  224. * Return:
  225. * OLE error code
  226. */
  227. {
  228. HRESULT hRc = S_OK;
  229. DWORD ec = ERROR_SUCCESS;
  230. PSECURITY_DESCRIPTOR pSecurityDescriptor = NULL;
  231. HANDLE hPrivBeforeSE_SECURITY = INVALID_HANDLE_VALUE;
  232. Assert(ppSD);
  233. if(!Connect(NULL, FALSE))
  234. {
  235. return S_FALSE;
  236. }
  237. if( fDefault == TRUE )
  238. {
  239. Error(("Non implemeted feature -> fDefault == TRUE\n"));
  240. return E_NOTIMPL;
  241. }
  242. if (si & SACL_SECURITY_INFORMATION)
  243. {
  244. hPrivBeforeSE_SECURITY = EnablePrivilege (SE_SECURITY_NAME);
  245. }
  246. //
  247. // Get the current relative descriptor from the fax server
  248. //
  249. if(!FaxGetSecurityEx(g_hFaxSvcHandle, si, &pSecurityDescriptor))
  250. {
  251. ec = GetLastError();
  252. Error(("FaxGetSecurityEx() failed with %d\n", ec));
  253. hRc = HRESULT_FROM_WIN32(ec);
  254. goto exit;
  255. }
  256. //
  257. // return a self relative descriptor copy allocated with LocalAlloc()
  258. //
  259. hRc = MakeSelfRelativeCopy( pSecurityDescriptor, ppSD );
  260. if( FAILED( hRc ) )
  261. {
  262. Error(("MakeSelfRelativeCopy() failed with %08X\n", hRc));
  263. goto exit;
  264. }
  265. Assert(S_OK == hRc);
  266. exit:
  267. if (pSecurityDescriptor)
  268. {
  269. FaxFreeBuffer(pSecurityDescriptor);
  270. }
  271. ReleasePrivilege (hPrivBeforeSE_SECURITY);
  272. return hRc;
  273. } // CFaxSecurity::GetSecurity
  274. STDMETHODIMP
  275. CFaxSecurity::SetSecurity(SECURITY_INFORMATION si,
  276. PSECURITY_DESCRIPTOR pSD)
  277. /*
  278. - CFaxSecurityInformation::SetSecurity
  279. -
  280. * Purpose:
  281. * Provides a security descriptor containing the security information
  282. * the user wants to apply to the securable object. The access control
  283. * editor calls this method when the user clicks the Okay or Apply buttons.
  284. *
  285. * Arguments:
  286. * [in] SecurityInformation - security information structure.
  287. * [in] pSecurityDescriptor - pointer to security descriptor.
  288. *
  289. * Return:
  290. * OLE error code
  291. */
  292. {
  293. HRESULT hRc = S_OK;
  294. DWORD ec = ERROR_SUCCESS;
  295. PSECURITY_DESCRIPTOR psdSelfRelativeCopy = NULL;
  296. HANDLE hPrivBeforeSE_TAKE_OWNERSHIP = INVALID_HANDLE_VALUE;
  297. HANDLE hPrivBeforeSE_SECURITY = INVALID_HANDLE_VALUE;
  298. Assert(pSD);
  299. Assert( IsValidSecurityDescriptor( pSD ));
  300. if(!Connect(NULL, FALSE))
  301. {
  302. return S_FALSE;
  303. }
  304. //
  305. // Prepare self relative descriptor
  306. //
  307. hRc = MakeSelfRelativeCopy( pSD, &psdSelfRelativeCopy );
  308. if( FAILED( hRc ) )
  309. {
  310. Error(("MakeSelfRelativeCopy() failed with %08X\n", hRc));
  311. goto exit;
  312. }
  313. if (si & OWNER_SECURITY_INFORMATION)
  314. {
  315. hPrivBeforeSE_TAKE_OWNERSHIP = EnablePrivilege (SE_TAKE_OWNERSHIP_NAME);
  316. }
  317. if (si & SACL_SECURITY_INFORMATION)
  318. {
  319. hPrivBeforeSE_SECURITY = EnablePrivilege (SE_SECURITY_NAME);
  320. }
  321. //
  322. // save the new relative descriptor to the fax server
  323. //
  324. if(!FaxSetSecurity(g_hFaxSvcHandle, si, psdSelfRelativeCopy))
  325. {
  326. ec = GetLastError();
  327. Error(("FaxSetSecurity() failed with %d\n", ec));
  328. hRc = HRESULT_FROM_WIN32(ec);
  329. goto exit;
  330. }
  331. Assert( S_OK == hRc || E_ACCESSDENIED == hRc);
  332. exit:
  333. if (psdSelfRelativeCopy)
  334. {
  335. ::LocalFree(psdSelfRelativeCopy);
  336. }
  337. ReleasePrivilege (hPrivBeforeSE_SECURITY);
  338. ReleasePrivilege (hPrivBeforeSE_TAKE_OWNERSHIP);
  339. return hRc;
  340. } // CFaxSecurity::SetSecurity
  341. STDMETHODIMP
  342. CFaxSecurity::GetAccessRights(const GUID* pguidObjectType,
  343. DWORD dwFlags,
  344. PSI_ACCESS* ppAccess,
  345. ULONG* pcAccesses,
  346. ULONG* piDefaultAccess)
  347. /*
  348. - CFaxSecurityInformation::GetAccessRights
  349. -
  350. * Purpose:
  351. * Requests information about the access rights that can be
  352. * controlled for a securable object. The access control
  353. * editor calls this method to retrieve display strings and
  354. * other information used to initialize the property pages.
  355. *
  356. * Arguments:
  357. * [in] pguidObjectType - Pointer to a GUID structure that
  358. * identifies the type of object for which
  359. * access rights are being requested.
  360. * [in] dwFlags - A set of bit flags that indicate the property
  361. * page being initialized
  362. * [out] ppAccess - Pointer to a variable that you should
  363. * set to a pointer to an array of SI_ACCESS
  364. * structures.
  365. * [out] pcAccesses - Pointer to a variable that you should set
  366. * to indicate the number of entries in the ppAccess array.
  367. * [out] piDefaultAccess - Pointer to a variable that you should set
  368. * to indicate the zero-based index of the array entry that contains
  369. * the default access rights.
  370. * The access control editor uses this entry as the initial access rights in a new ACE.
  371. *
  372. * Return:
  373. * OLE error code
  374. */
  375. {
  376. Assert( ppAccess );
  377. Assert( pcAccesses );
  378. Assert( piDefaultAccess );
  379. //
  380. // Access rights for the Basic security page
  381. //
  382. static SI_ACCESS siFaxBasicAccess[] =
  383. {
  384. // 0 Fax
  385. {
  386. &GUID_NULL,
  387. FAX_ACCESS_SUBMIT_HIGH | FAX_ACCESS_SUBMIT_NORMAL | FAX_ACCESS_SUBMIT | FAX_ACCESS_QUERY_IN_ARCHIVE,
  388. MAKEINTRESOURCE(IDS_RIGHT_FAX),
  389. SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC
  390. },
  391. // 1 Manage fax configuration
  392. {
  393. &GUID_NULL,
  394. FAX_ACCESS_MANAGE_CONFIG | FAX_ACCESS_QUERY_CONFIG,
  395. MAKEINTRESOURCE(IDS_RIGHT_MNG_CFG),
  396. SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC
  397. },
  398. // 2 Manage fax documents
  399. {
  400. &GUID_NULL,
  401. FAX_ACCESS_MANAGE_JOBS | FAX_ACCESS_QUERY_JOBS |
  402. FAX_ACCESS_MANAGE_IN_ARCHIVE | FAX_ACCESS_QUERY_IN_ARCHIVE |
  403. FAX_ACCESS_MANAGE_OUT_ARCHIVE | FAX_ACCESS_QUERY_OUT_ARCHIVE,
  404. MAKEINTRESOURCE(IDS_RIGHT_MNG_DOC),
  405. SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC
  406. }
  407. };
  408. //
  409. // Access rights for the Advanced security page
  410. //
  411. static SI_ACCESS siFaxAccess[] =
  412. {
  413. // 0 submit permission
  414. {
  415. &GUID_NULL,
  416. FAX_ACCESS_SUBMIT ,
  417. MAKEINTRESOURCE(IDS_FAXSEC_SUB_LOW),
  418. SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC
  419. },
  420. // 1 submit normal permission
  421. {
  422. &GUID_NULL,
  423. FAX_ACCESS_SUBMIT_NORMAL ,
  424. MAKEINTRESOURCE(IDS_FAXSEC_SUB_NORMAL),
  425. SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC
  426. },
  427. // 2 submit high permission
  428. {
  429. &GUID_NULL,
  430. FAX_ACCESS_SUBMIT_HIGH ,
  431. MAKEINTRESOURCE(IDS_FAXSEC_SUB_HIGH),
  432. SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC
  433. },
  434. // 3 query jobs
  435. {
  436. &GUID_NULL,
  437. FAX_ACCESS_QUERY_JOBS,
  438. MAKEINTRESOURCE(IDS_FAXSEC_JOB_QRY),
  439. SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC
  440. },
  441. // 4 Manage jobs
  442. {
  443. &GUID_NULL,
  444. FAX_ACCESS_MANAGE_JOBS,
  445. MAKEINTRESOURCE(IDS_FAXSEC_JOB_MNG),
  446. SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC
  447. },
  448. // 5 query configuration
  449. {
  450. &GUID_NULL,
  451. FAX_ACCESS_QUERY_CONFIG,
  452. MAKEINTRESOURCE(IDS_FAXSEC_CONFIG_QRY),
  453. SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC
  454. },
  455. // 6 Manage configuration
  456. {
  457. &GUID_NULL,
  458. FAX_ACCESS_MANAGE_CONFIG,
  459. MAKEINTRESOURCE(IDS_FAXSEC_CONFIG_SET),
  460. SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC
  461. },
  462. // 7 Query incoming faxes archive
  463. {
  464. &GUID_NULL,
  465. FAX_ACCESS_QUERY_IN_ARCHIVE,
  466. MAKEINTRESOURCE(IDS_FAXSEC_QRY_IN_ARCH),
  467. SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC
  468. },
  469. // 8 Manage incoming faxes archive
  470. {
  471. &GUID_NULL,
  472. FAX_ACCESS_MANAGE_IN_ARCHIVE,
  473. MAKEINTRESOURCE(IDS_FAXSEC_MNG_IN_ARCH),
  474. SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC
  475. },
  476. // 9 Query outgoing faxes archive
  477. {
  478. &GUID_NULL,
  479. FAX_ACCESS_QUERY_OUT_ARCHIVE,
  480. MAKEINTRESOURCE(IDS_FAXSEC_QRY_OUT_ARCH),
  481. SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC
  482. },
  483. // 10 Manage outgoing faxes archive
  484. {
  485. &GUID_NULL,
  486. FAX_ACCESS_MANAGE_OUT_ARCHIVE,
  487. MAKEINTRESOURCE(IDS_FAXSEC_MNG_OUT_ARCH),
  488. SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC
  489. },
  490. // specific permissions
  491. // 11 Read permission
  492. {
  493. &GUID_NULL,
  494. READ_CONTROL,
  495. MAKEINTRESOURCE(IDS_FAXSEC_READ_PERM),
  496. SI_ACCESS_SPECIFIC
  497. },
  498. // 12 Change Permissions
  499. {
  500. &GUID_NULL,
  501. WRITE_DAC,
  502. MAKEINTRESOURCE(IDS_FAXSEC_CHNG_PERM),
  503. SI_ACCESS_SPECIFIC
  504. },
  505. // 13 Take ownership
  506. {
  507. &GUID_NULL,
  508. WRITE_OWNER,
  509. MAKEINTRESOURCE(IDS_FAXSEC_CHNG_OWNER),
  510. SI_ACCESS_SPECIFIC
  511. }
  512. };
  513. *ppAccess = (0 == dwFlags) ? siFaxBasicAccess : siFaxAccess;
  514. *pcAccesses = ULONG((0 == dwFlags) ? ARR_SIZE(siFaxBasicAccess) : ARR_SIZE(siFaxAccess));
  515. *piDefaultAccess = (0 == dwFlags) ? 0 : 1;
  516. return S_OK;
  517. } // CFaxSecurity::GetAccessRights
  518. STDMETHODIMP
  519. CFaxSecurity::MapGeneric(const GUID* pguidObjectType,
  520. UCHAR* pAceFlags,
  521. ACCESS_MASK* pmask)
  522. /*
  523. - CFaxSecurityInformation::MapGeneric
  524. -
  525. * Purpose:
  526. * Requests that the generic access rights in an access mask
  527. * be mapped to their corresponding standard and specific access rights.
  528. *
  529. * Arguments:
  530. *
  531. * Return:
  532. * OLE error code
  533. */
  534. {
  535. static GENERIC_MAPPING genericMapping =
  536. {
  537. (STANDARD_RIGHTS_READ | FAX_GENERIC_READ), // GenericRead
  538. (STANDARD_RIGHTS_WRITE | FAX_GENERIC_WRITE), // GenericWrite
  539. (STANDARD_RIGHTS_EXECUTE | FAX_GENERIC_EXECUTE), // GenericExecute
  540. (READ_CONTROL | WRITE_DAC | WRITE_OWNER | FAX_GENERIC_ALL) // GenericAll
  541. };
  542. MapGenericMask(pmask, &genericMapping);
  543. return S_OK;
  544. }
  545. STDMETHODIMP
  546. CFaxSecurity::GetInheritTypes(PSI_INHERIT_TYPE* ppInheritTypes,
  547. ULONG* pcInheritTypes)
  548. {
  549. return E_NOTIMPL;
  550. }
  551. STDMETHODIMP
  552. CFaxSecurity::PropertySheetPageCallback(HWND hwnd,
  553. UINT uMsg,
  554. SI_PAGE_TYPE uPage)
  555. {
  556. return S_OK;
  557. }
  558. HRESULT
  559. CFaxSecurity::MakeSelfRelativeCopy(PSECURITY_DESCRIPTOR psdOriginal,
  560. PSECURITY_DESCRIPTOR* ppsdNew)
  561. /*
  562. - CFaxSecurityInformation::MakeSelfRelativeCopy
  563. -
  564. * Purpose:
  565. * This pravite method copies Security descriptors
  566. *
  567. * Arguments:
  568. *
  569. * Return:
  570. * OLE error code
  571. */
  572. {
  573. Assert( NULL != psdOriginal );
  574. //
  575. // we have to find out whether the original is already self-relative
  576. //
  577. SECURITY_DESCRIPTOR_CONTROL sdc = 0;
  578. PSECURITY_DESCRIPTOR psdSelfRelativeCopy = NULL;
  579. DWORD dwRevision = 0;
  580. DWORD cb = 0;
  581. Assert(IsValidSecurityDescriptor( psdOriginal ) );
  582. if( !::GetSecurityDescriptorControl( psdOriginal, &sdc, &dwRevision ) )
  583. {
  584. DWORD err = ::GetLastError();
  585. Error(("GetSecurityDescriptorControl() failed with %d\n", err));
  586. return HRESULT_FROM_WIN32( err );
  587. }
  588. if( sdc & SE_SELF_RELATIVE )
  589. {
  590. // the original is in self-relative format, just byte-copy it
  591. // get size
  592. cb = ::GetSecurityDescriptorLength( psdOriginal );
  593. // alloc the memory
  594. psdSelfRelativeCopy = (PSECURITY_DESCRIPTOR) ::LocalAlloc( LMEM_ZEROINIT, cb );
  595. if(NULL == psdSelfRelativeCopy)
  596. {
  597. Error(("Out of memory.\n"));
  598. return E_OUTOFMEMORY;
  599. }
  600. // make the copy
  601. ::memcpy( psdSelfRelativeCopy, psdOriginal, cb );
  602. }
  603. else
  604. {
  605. // the original is in absolute format, convert-copy it
  606. // get new size - it will fail and set cb to the correct buffer size
  607. ::MakeSelfRelativeSD( psdOriginal, NULL, &cb );
  608. // alloc the new amount of memory
  609. psdSelfRelativeCopy = (PSECURITY_DESCRIPTOR) ::LocalAlloc( LMEM_ZEROINIT, cb );
  610. if(!psdSelfRelativeCopy)
  611. {
  612. Error(("Out of memory.\n"));
  613. return E_OUTOFMEMORY; // just in case the exception is ignored
  614. }
  615. if( !::MakeSelfRelativeSD( psdOriginal, psdSelfRelativeCopy, &cb ) )
  616. {
  617. DWORD err = ::GetLastError();
  618. Error(("MakeSelfRelativeSD() failed with %d\n", err));
  619. ::LocalFree( psdSelfRelativeCopy );
  620. return HRESULT_FROM_WIN32( err );
  621. }
  622. }
  623. *ppsdNew = psdSelfRelativeCopy;
  624. return S_OK;
  625. }
  626. ///////////////////////////////////////////////////////////////////////////////
  627. //
  628. // This is the entry point function called from our code
  629. //
  630. ///////////////////////////////////////////////////////////////////////////////
  631. HMODULE g_hAclui = NULL;
  632. extern "C"
  633. HPROPSHEETPAGE
  634. CreateFaxSecurityPage()
  635. {
  636. HPROPSHEETPAGE hPage = NULL;
  637. HPROPSHEETPAGE (*pfCreateSecurityPage)(LPSECURITYINFO) = NULL;
  638. if(!IsWinXPOS())
  639. {
  640. //
  641. // The security page should bge added only to the local fax printer on XP OS.
  642. //
  643. Assert(FALSE);
  644. return NULL;
  645. }
  646. //
  647. // CreateSecurityPage() Requires Windows 2000 or later, so we connect to it dynamically
  648. //
  649. if(!g_hAclui)
  650. {
  651. g_hAclui = LoadLibrary(TEXT("aclui.dll"));
  652. if(!g_hAclui)
  653. {
  654. Error(("LoadLibrary(aclui.dll) failed with %d\n", GetLastError()));
  655. goto error;
  656. }
  657. }
  658. (FARPROC&)pfCreateSecurityPage = GetProcAddress(g_hAclui, "CreateSecurityPage");
  659. if(!pfCreateSecurityPage)
  660. {
  661. Error(("GetProcAddress(CreateSecurityPage) failed with %d\n", GetLastError()));
  662. goto error;
  663. }
  664. if(!g_pFaxSecurity)
  665. {
  666. g_pFaxSecurity = new CFaxSecurity();
  667. }
  668. if(!g_pFaxSecurity)
  669. {
  670. Error(("Out of memory.\n"));
  671. goto error;
  672. }
  673. hPage = pfCreateSecurityPage(g_pFaxSecurity);
  674. if(!hPage)
  675. {
  676. Error(("CreateSecurityPage() failed with %d\n", ::GetLastError()));
  677. goto error;
  678. }
  679. return hPage;
  680. error:
  681. if(g_hAclui)
  682. {
  683. FreeLibrary(g_hAclui);
  684. g_hAclui = NULL;
  685. }
  686. return NULL;
  687. }
  688. extern "C"
  689. void
  690. ReleaseFaxSecurity()
  691. {
  692. if(g_pFaxSecurity)
  693. {
  694. g_pFaxSecurity->Release();
  695. }
  696. if(g_hAclui)
  697. {
  698. FreeLibrary(g_hAclui);
  699. g_hAclui = NULL;
  700. }
  701. }