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.
809 lines
22 KiB
809 lines
22 KiB
//
|
|
// ISecurityInformation interface implementation
|
|
//
|
|
|
|
#include <aclui.h>
|
|
#include "faxui.h"
|
|
|
|
class CFaxSecurity : public ISecurityInformation
|
|
{
|
|
protected:
|
|
ULONG m_cRef;
|
|
|
|
STDMETHOD(MakeSelfRelativeCopy)(PSECURITY_DESCRIPTOR psdOriginal,
|
|
PSECURITY_DESCRIPTOR* ppsdNew);
|
|
public:
|
|
CFaxSecurity() : m_cRef(1) {}
|
|
virtual ~CFaxSecurity() {}
|
|
|
|
// IUnknown methods
|
|
STDMETHOD(QueryInterface)(REFIID, LPVOID *);
|
|
STDMETHOD_(ULONG, AddRef)();
|
|
STDMETHOD_(ULONG, Release)();
|
|
|
|
// ISecurityInformation methods
|
|
STDMETHOD(GetObjectInformation)(PSI_OBJECT_INFO pObjectInfo);
|
|
|
|
STDMETHOD(GetSecurity)(SECURITY_INFORMATION si,
|
|
PSECURITY_DESCRIPTOR *ppSD,
|
|
BOOL fDefault);
|
|
|
|
STDMETHOD(SetSecurity)(SECURITY_INFORMATION si,
|
|
PSECURITY_DESCRIPTOR pSD);
|
|
|
|
STDMETHOD(GetAccessRights)(const GUID* pguidObjectType,
|
|
DWORD dwFlags,
|
|
PSI_ACCESS *ppAccess,
|
|
ULONG *pcAccesses,
|
|
ULONG *piDefaultAccess);
|
|
|
|
STDMETHOD(MapGeneric)(const GUID *pguidObjectType,
|
|
UCHAR *pAceFlags,
|
|
ACCESS_MASK *pmask);
|
|
|
|
STDMETHOD(GetInheritTypes)(PSI_INHERIT_TYPE *ppInheritTypes,
|
|
ULONG *pcInheritTypes);
|
|
|
|
STDMETHOD(PropertySheetPageCallback)(HWND hwnd,
|
|
UINT uMsg,
|
|
SI_PAGE_TYPE uPage);
|
|
};
|
|
|
|
|
|
CFaxSecurity* g_pFaxSecurity = NULL;
|
|
|
|
|
|
///////////////////////////////////////////////////////////
|
|
//
|
|
// IUnknown methods
|
|
//
|
|
///////////////////////////////////////////////////////////
|
|
|
|
STDMETHODIMP_(ULONG)
|
|
CFaxSecurity::AddRef()
|
|
{
|
|
return ++m_cRef;
|
|
}
|
|
|
|
STDMETHODIMP_(ULONG)
|
|
CFaxSecurity::Release()
|
|
{
|
|
if (--m_cRef == 0)
|
|
{
|
|
delete this;
|
|
g_pFaxSecurity = NULL;
|
|
return 0;
|
|
}
|
|
|
|
return m_cRef;
|
|
}
|
|
|
|
STDMETHODIMP
|
|
CFaxSecurity::QueryInterface(REFIID riid, LPVOID FAR* ppv)
|
|
{
|
|
if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_ISecurityInformation))
|
|
{
|
|
*ppv = (LPSECURITYINFO)this;
|
|
m_cRef++;
|
|
return S_OK;
|
|
}
|
|
else
|
|
{
|
|
*ppv = NULL;
|
|
return E_NOINTERFACE;
|
|
}
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////
|
|
//
|
|
// ISecurityInformation methods
|
|
//
|
|
///////////////////////////////////////////////////////////
|
|
|
|
STDMETHODIMP
|
|
CFaxSecurity::GetObjectInformation(PSI_OBJECT_INFO pObjectInfo)
|
|
// *** ISecurityInformation methods implementation ***
|
|
/*
|
|
- CFaxSecurity::GetObjectInformation
|
|
-
|
|
* Purpose:
|
|
* Performs an access check against the fax service security descriptor
|
|
*
|
|
* Arguments:
|
|
* [in] pObjectInfo - pointer to object information structure.
|
|
*
|
|
* Return:
|
|
* OLE error code
|
|
*/
|
|
{
|
|
DWORD ec = ERROR_SUCCESS;
|
|
|
|
if(!Connect(NULL, FALSE))
|
|
{
|
|
return S_FALSE;
|
|
}
|
|
|
|
HANDLE hPrivBeforeSE_TAKE_OWNERSHIP = INVALID_HANDLE_VALUE;
|
|
HANDLE hPrivBeforeSE_SECURITY = INVALID_HANDLE_VALUE;
|
|
|
|
if( pObjectInfo == NULL )
|
|
{
|
|
Error(("Invalid parameter - pObjectInfo == NULL\n"));
|
|
Assert( pObjectInfo != NULL );
|
|
return E_POINTER;
|
|
}
|
|
|
|
//
|
|
// Set Flags
|
|
//
|
|
pObjectInfo->dwFlags = SI_EDIT_ALL |
|
|
SI_NO_TREE_APPLY |
|
|
SI_NO_ACL_PROTECT |
|
|
SI_ADVANCED |
|
|
SI_PAGE_TITLE;
|
|
|
|
//
|
|
// Check if to add SI_READONLY
|
|
//
|
|
if (!FaxAccessCheckEx(g_hFaxSvcHandle, WRITE_DAC, NULL))
|
|
{
|
|
ec = GetLastError();
|
|
if (ERROR_SUCCESS == ec)
|
|
{
|
|
pObjectInfo->dwFlags |= SI_READONLY;
|
|
}
|
|
else
|
|
{
|
|
Error(("FaxAccessCheckEx(WRITE_DAC) failed with %d \n", ec));
|
|
goto exit;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check if to add SI_OWNER_READONLY
|
|
//
|
|
hPrivBeforeSE_TAKE_OWNERSHIP = EnablePrivilege (SE_TAKE_OWNERSHIP_NAME);
|
|
//
|
|
// No error checking - If we failed we will get ERROR_ACCESS_DENIED in the access check
|
|
//
|
|
if (!FaxAccessCheckEx(g_hFaxSvcHandle,WRITE_OWNER, NULL))
|
|
{
|
|
ec = GetLastError();
|
|
if (ERROR_SUCCESS == ec)
|
|
{
|
|
pObjectInfo->dwFlags |= SI_OWNER_READONLY;
|
|
}
|
|
else
|
|
{
|
|
Error(("FaxAccessCheckEx(WRITE_OWNER) failed with %d \n", ec));
|
|
goto exit;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check if to remove SI_EDIT_AUDITS
|
|
//
|
|
hPrivBeforeSE_SECURITY = EnablePrivilege (SE_SECURITY_NAME);
|
|
//
|
|
// No error checking - If we failed we will get ERROR_ACCESS_DENIED in the access check
|
|
//
|
|
if (!FaxAccessCheckEx(g_hFaxSvcHandle, ACCESS_SYSTEM_SECURITY, NULL))
|
|
{
|
|
ec = GetLastError();
|
|
if (ERROR_SUCCESS == ec)
|
|
{
|
|
pObjectInfo->dwFlags &= ~SI_EDIT_AUDITS;
|
|
}
|
|
else
|
|
{
|
|
Error(("FaxAccessCheckEx(ACCESS_SYSTEM_SECURITY) failed with %d \n", ec));
|
|
goto exit;
|
|
}
|
|
}
|
|
|
|
|
|
//
|
|
// Set all other fields
|
|
//
|
|
static TCHAR tszPageTitle[MAX_PATH] = {0};
|
|
if(LoadString((HINSTANCE)g_hResource, IDS_SECURITY_TITLE, tszPageTitle, ARR_SIZE(tszPageTitle)))
|
|
{
|
|
pObjectInfo->pszPageTitle = tszPageTitle;
|
|
}
|
|
else
|
|
{
|
|
ec = GetLastError();
|
|
Error(("LoadString(IDS_SECURITY_TITLE) failed with %d \n", ec));
|
|
|
|
pObjectInfo->pszPageTitle = NULL;
|
|
}
|
|
|
|
static TCHAR tszPrinterName[MAX_PATH] = {0};
|
|
if(GetFirstLocalFaxPrinterName(tszPrinterName, ARR_SIZE(tszPrinterName)))
|
|
{
|
|
pObjectInfo->pszObjectName = tszPrinterName;
|
|
}
|
|
else
|
|
{
|
|
ec = GetLastError();
|
|
Error(("GetFirstLocalFaxPrinterName() failed with %d \n", ec));
|
|
|
|
pObjectInfo->pszObjectName = NULL;
|
|
}
|
|
|
|
pObjectInfo->hInstance = (HINSTANCE)g_hResource;
|
|
pObjectInfo->pszServerName = NULL;
|
|
|
|
exit:
|
|
ReleasePrivilege (hPrivBeforeSE_SECURITY);
|
|
ReleasePrivilege (hPrivBeforeSE_TAKE_OWNERSHIP);
|
|
return HRESULT_FROM_WIN32(ec);
|
|
|
|
} // CFaxSecurity::GetObjectInformation
|
|
|
|
|
|
STDMETHODIMP
|
|
CFaxSecurity::GetSecurity(SECURITY_INFORMATION si,
|
|
PSECURITY_DESCRIPTOR* ppSD,
|
|
BOOL fDefault)
|
|
/*
|
|
- CFaxSecurityInformation::GetSecurity
|
|
-
|
|
* Purpose:
|
|
* requests a security descriptor for the securable object whose
|
|
* security descriptor is being edited. The access control editor
|
|
* calls this method to retrieve the object's current or default security descriptor.
|
|
*
|
|
* Arguments:
|
|
* [in] RequestedInformation - security information.
|
|
* [out] ppSecurityDescriptor - pointer to security descriptor.
|
|
* [in] fDefault - not implemented
|
|
*
|
|
* Return:
|
|
* OLE error code
|
|
*/
|
|
{
|
|
HRESULT hRc = S_OK;
|
|
DWORD ec = ERROR_SUCCESS;
|
|
|
|
PSECURITY_DESCRIPTOR pSecurityDescriptor = NULL;
|
|
|
|
HANDLE hPrivBeforeSE_SECURITY = INVALID_HANDLE_VALUE;
|
|
|
|
Assert(ppSD);
|
|
|
|
if(!Connect(NULL, FALSE))
|
|
{
|
|
return S_FALSE;
|
|
}
|
|
|
|
if( fDefault == TRUE )
|
|
{
|
|
Error(("Non implemeted feature -> fDefault == TRUE\n"));
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
if (si & SACL_SECURITY_INFORMATION)
|
|
{
|
|
hPrivBeforeSE_SECURITY = EnablePrivilege (SE_SECURITY_NAME);
|
|
}
|
|
|
|
//
|
|
// Get the current relative descriptor from the fax server
|
|
//
|
|
if(!FaxGetSecurityEx(g_hFaxSvcHandle, si, &pSecurityDescriptor))
|
|
{
|
|
ec = GetLastError();
|
|
Error(("FaxGetSecurityEx() failed with %d\n", ec));
|
|
hRc = HRESULT_FROM_WIN32(ec);
|
|
goto exit;
|
|
}
|
|
|
|
//
|
|
// return a self relative descriptor copy allocated with LocalAlloc()
|
|
//
|
|
hRc = MakeSelfRelativeCopy( pSecurityDescriptor, ppSD );
|
|
if( FAILED( hRc ) )
|
|
{
|
|
Error(("MakeSelfRelativeCopy() failed with %08X\n", hRc));
|
|
goto exit;
|
|
}
|
|
|
|
Assert(S_OK == hRc);
|
|
|
|
exit:
|
|
if (pSecurityDescriptor)
|
|
{
|
|
FaxFreeBuffer(pSecurityDescriptor);
|
|
}
|
|
ReleasePrivilege (hPrivBeforeSE_SECURITY);
|
|
|
|
return hRc;
|
|
|
|
} // CFaxSecurity::GetSecurity
|
|
|
|
STDMETHODIMP
|
|
CFaxSecurity::SetSecurity(SECURITY_INFORMATION si,
|
|
PSECURITY_DESCRIPTOR pSD)
|
|
/*
|
|
- CFaxSecurityInformation::SetSecurity
|
|
-
|
|
* Purpose:
|
|
* Provides a security descriptor containing the security information
|
|
* the user wants to apply to the securable object. The access control
|
|
* editor calls this method when the user clicks the Okay or Apply buttons.
|
|
*
|
|
* Arguments:
|
|
* [in] SecurityInformation - security information structure.
|
|
* [in] pSecurityDescriptor - pointer to security descriptor.
|
|
*
|
|
* Return:
|
|
* OLE error code
|
|
*/
|
|
{
|
|
HRESULT hRc = S_OK;
|
|
DWORD ec = ERROR_SUCCESS;
|
|
|
|
PSECURITY_DESCRIPTOR psdSelfRelativeCopy = NULL;
|
|
|
|
HANDLE hPrivBeforeSE_TAKE_OWNERSHIP = INVALID_HANDLE_VALUE;
|
|
HANDLE hPrivBeforeSE_SECURITY = INVALID_HANDLE_VALUE;
|
|
|
|
Assert(pSD);
|
|
Assert( IsValidSecurityDescriptor( pSD ));
|
|
|
|
if(!Connect(NULL, FALSE))
|
|
{
|
|
return S_FALSE;
|
|
}
|
|
|
|
//
|
|
// Prepare self relative descriptor
|
|
//
|
|
hRc = MakeSelfRelativeCopy( pSD, &psdSelfRelativeCopy );
|
|
if( FAILED( hRc ) )
|
|
{
|
|
Error(("MakeSelfRelativeCopy() failed with %08X\n", hRc));
|
|
goto exit;
|
|
}
|
|
|
|
if (si & OWNER_SECURITY_INFORMATION)
|
|
{
|
|
hPrivBeforeSE_TAKE_OWNERSHIP = EnablePrivilege (SE_TAKE_OWNERSHIP_NAME);
|
|
}
|
|
|
|
if (si & SACL_SECURITY_INFORMATION)
|
|
{
|
|
hPrivBeforeSE_SECURITY = EnablePrivilege (SE_SECURITY_NAME);
|
|
}
|
|
|
|
//
|
|
// save the new relative descriptor to the fax server
|
|
//
|
|
if(!FaxSetSecurity(g_hFaxSvcHandle, si, psdSelfRelativeCopy))
|
|
{
|
|
ec = GetLastError();
|
|
Error(("FaxSetSecurity() failed with %d\n", ec));
|
|
hRc = HRESULT_FROM_WIN32(ec);
|
|
goto exit;
|
|
}
|
|
|
|
Assert( S_OK == hRc || E_ACCESSDENIED == hRc);
|
|
|
|
exit:
|
|
if (psdSelfRelativeCopy)
|
|
{
|
|
::LocalFree(psdSelfRelativeCopy);
|
|
}
|
|
|
|
ReleasePrivilege (hPrivBeforeSE_SECURITY);
|
|
ReleasePrivilege (hPrivBeforeSE_TAKE_OWNERSHIP);
|
|
|
|
return hRc;
|
|
|
|
} // CFaxSecurity::SetSecurity
|
|
|
|
STDMETHODIMP
|
|
CFaxSecurity::GetAccessRights(const GUID* pguidObjectType,
|
|
DWORD dwFlags,
|
|
PSI_ACCESS* ppAccess,
|
|
ULONG* pcAccesses,
|
|
ULONG* piDefaultAccess)
|
|
/*
|
|
- CFaxSecurityInformation::GetAccessRights
|
|
-
|
|
* Purpose:
|
|
* Requests information about the access rights that can be
|
|
* controlled for a securable object. The access control
|
|
* editor calls this method to retrieve display strings and
|
|
* other information used to initialize the property pages.
|
|
*
|
|
* Arguments:
|
|
* [in] pguidObjectType - Pointer to a GUID structure that
|
|
* identifies the type of object for which
|
|
* access rights are being requested.
|
|
* [in] dwFlags - A set of bit flags that indicate the property
|
|
* page being initialized
|
|
* [out] ppAccess - Pointer to a variable that you should
|
|
* set to a pointer to an array of SI_ACCESS
|
|
* structures.
|
|
* [out] pcAccesses - Pointer to a variable that you should set
|
|
* to indicate the number of entries in the ppAccess array.
|
|
* [out] piDefaultAccess - Pointer to a variable that you should set
|
|
* to indicate the zero-based index of the array entry that contains
|
|
* the default access rights.
|
|
* The access control editor uses this entry as the initial access rights in a new ACE.
|
|
*
|
|
* Return:
|
|
* OLE error code
|
|
*/
|
|
{
|
|
Assert( ppAccess );
|
|
Assert( pcAccesses );
|
|
Assert( piDefaultAccess );
|
|
|
|
//
|
|
// Access rights for the Basic security page
|
|
//
|
|
static SI_ACCESS siFaxBasicAccess[] =
|
|
{
|
|
// 0 Fax
|
|
{
|
|
&GUID_NULL,
|
|
FAX_ACCESS_SUBMIT_HIGH | FAX_ACCESS_SUBMIT_NORMAL | FAX_ACCESS_SUBMIT | FAX_ACCESS_QUERY_IN_ARCHIVE,
|
|
MAKEINTRESOURCE(IDS_RIGHT_FAX),
|
|
SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC
|
|
},
|
|
// 1 Manage fax configuration
|
|
{
|
|
&GUID_NULL,
|
|
FAX_ACCESS_MANAGE_CONFIG | FAX_ACCESS_QUERY_CONFIG,
|
|
MAKEINTRESOURCE(IDS_RIGHT_MNG_CFG),
|
|
SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC
|
|
},
|
|
// 2 Manage fax documents
|
|
{
|
|
&GUID_NULL,
|
|
FAX_ACCESS_MANAGE_JOBS | FAX_ACCESS_QUERY_JOBS |
|
|
FAX_ACCESS_MANAGE_IN_ARCHIVE | FAX_ACCESS_QUERY_IN_ARCHIVE |
|
|
FAX_ACCESS_MANAGE_OUT_ARCHIVE | FAX_ACCESS_QUERY_OUT_ARCHIVE,
|
|
MAKEINTRESOURCE(IDS_RIGHT_MNG_DOC),
|
|
SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC
|
|
}
|
|
};
|
|
|
|
//
|
|
// Access rights for the Advanced security page
|
|
//
|
|
static SI_ACCESS siFaxAccess[] =
|
|
{
|
|
// 0 submit permission
|
|
{
|
|
&GUID_NULL,
|
|
FAX_ACCESS_SUBMIT ,
|
|
MAKEINTRESOURCE(IDS_FAXSEC_SUB_LOW),
|
|
SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC
|
|
},
|
|
// 1 submit normal permission
|
|
{
|
|
&GUID_NULL,
|
|
FAX_ACCESS_SUBMIT_NORMAL ,
|
|
MAKEINTRESOURCE(IDS_FAXSEC_SUB_NORMAL),
|
|
SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC
|
|
},
|
|
// 2 submit high permission
|
|
{
|
|
&GUID_NULL,
|
|
FAX_ACCESS_SUBMIT_HIGH ,
|
|
MAKEINTRESOURCE(IDS_FAXSEC_SUB_HIGH),
|
|
SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC
|
|
},
|
|
// 3 query jobs
|
|
{
|
|
&GUID_NULL,
|
|
FAX_ACCESS_QUERY_JOBS,
|
|
MAKEINTRESOURCE(IDS_FAXSEC_JOB_QRY),
|
|
SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC
|
|
},
|
|
// 4 Manage jobs
|
|
{
|
|
&GUID_NULL,
|
|
FAX_ACCESS_MANAGE_JOBS,
|
|
MAKEINTRESOURCE(IDS_FAXSEC_JOB_MNG),
|
|
SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC
|
|
},
|
|
// 5 query configuration
|
|
{
|
|
&GUID_NULL,
|
|
FAX_ACCESS_QUERY_CONFIG,
|
|
MAKEINTRESOURCE(IDS_FAXSEC_CONFIG_QRY),
|
|
SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC
|
|
},
|
|
// 6 Manage configuration
|
|
{
|
|
&GUID_NULL,
|
|
FAX_ACCESS_MANAGE_CONFIG,
|
|
MAKEINTRESOURCE(IDS_FAXSEC_CONFIG_SET),
|
|
SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC
|
|
},
|
|
// 7 Query incoming faxes archive
|
|
{
|
|
&GUID_NULL,
|
|
FAX_ACCESS_QUERY_IN_ARCHIVE,
|
|
MAKEINTRESOURCE(IDS_FAXSEC_QRY_IN_ARCH),
|
|
SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC
|
|
},
|
|
// 8 Manage incoming faxes archive
|
|
{
|
|
&GUID_NULL,
|
|
FAX_ACCESS_MANAGE_IN_ARCHIVE,
|
|
MAKEINTRESOURCE(IDS_FAXSEC_MNG_IN_ARCH),
|
|
SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC
|
|
},
|
|
// 9 Query outgoing faxes archive
|
|
{
|
|
&GUID_NULL,
|
|
FAX_ACCESS_QUERY_OUT_ARCHIVE,
|
|
MAKEINTRESOURCE(IDS_FAXSEC_QRY_OUT_ARCH),
|
|
SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC
|
|
},
|
|
// 10 Manage outgoing faxes archive
|
|
{
|
|
&GUID_NULL,
|
|
FAX_ACCESS_MANAGE_OUT_ARCHIVE,
|
|
MAKEINTRESOURCE(IDS_FAXSEC_MNG_OUT_ARCH),
|
|
SI_ACCESS_GENERAL | SI_ACCESS_SPECIFIC
|
|
},
|
|
// specific permissions
|
|
// 11 Read permission
|
|
{
|
|
&GUID_NULL,
|
|
READ_CONTROL,
|
|
MAKEINTRESOURCE(IDS_FAXSEC_READ_PERM),
|
|
SI_ACCESS_SPECIFIC
|
|
},
|
|
// 12 Change Permissions
|
|
{
|
|
&GUID_NULL,
|
|
WRITE_DAC,
|
|
MAKEINTRESOURCE(IDS_FAXSEC_CHNG_PERM),
|
|
SI_ACCESS_SPECIFIC
|
|
},
|
|
// 13 Take ownership
|
|
{
|
|
&GUID_NULL,
|
|
WRITE_OWNER,
|
|
MAKEINTRESOURCE(IDS_FAXSEC_CHNG_OWNER),
|
|
SI_ACCESS_SPECIFIC
|
|
}
|
|
};
|
|
|
|
*ppAccess = (0 == dwFlags) ? siFaxBasicAccess : siFaxAccess;
|
|
*pcAccesses = ULONG((0 == dwFlags) ? ARR_SIZE(siFaxBasicAccess) : ARR_SIZE(siFaxAccess));
|
|
*piDefaultAccess = (0 == dwFlags) ? 0 : 1;
|
|
|
|
return S_OK;
|
|
|
|
} // CFaxSecurity::GetAccessRights
|
|
|
|
|
|
STDMETHODIMP
|
|
CFaxSecurity::MapGeneric(const GUID* pguidObjectType,
|
|
UCHAR* pAceFlags,
|
|
ACCESS_MASK* pmask)
|
|
/*
|
|
- CFaxSecurityInformation::MapGeneric
|
|
-
|
|
* Purpose:
|
|
* Requests that the generic access rights in an access mask
|
|
* be mapped to their corresponding standard and specific access rights.
|
|
*
|
|
* Arguments:
|
|
*
|
|
* Return:
|
|
* OLE error code
|
|
*/
|
|
{
|
|
static GENERIC_MAPPING genericMapping =
|
|
{
|
|
(STANDARD_RIGHTS_READ | FAX_GENERIC_READ), // GenericRead
|
|
(STANDARD_RIGHTS_WRITE | FAX_GENERIC_WRITE), // GenericWrite
|
|
(STANDARD_RIGHTS_EXECUTE | FAX_GENERIC_EXECUTE), // GenericExecute
|
|
(READ_CONTROL | WRITE_DAC | WRITE_OWNER | FAX_GENERIC_ALL) // GenericAll
|
|
};
|
|
|
|
MapGenericMask(pmask, &genericMapping);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP
|
|
CFaxSecurity::GetInheritTypes(PSI_INHERIT_TYPE* ppInheritTypes,
|
|
ULONG* pcInheritTypes)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP
|
|
CFaxSecurity::PropertySheetPageCallback(HWND hwnd,
|
|
UINT uMsg,
|
|
SI_PAGE_TYPE uPage)
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
HRESULT
|
|
CFaxSecurity::MakeSelfRelativeCopy(PSECURITY_DESCRIPTOR psdOriginal,
|
|
PSECURITY_DESCRIPTOR* ppsdNew)
|
|
/*
|
|
- CFaxSecurityInformation::MakeSelfRelativeCopy
|
|
-
|
|
* Purpose:
|
|
* This pravite method copies Security descriptors
|
|
*
|
|
* Arguments:
|
|
*
|
|
* Return:
|
|
* OLE error code
|
|
*/
|
|
{
|
|
Assert( NULL != psdOriginal );
|
|
|
|
//
|
|
// we have to find out whether the original is already self-relative
|
|
//
|
|
SECURITY_DESCRIPTOR_CONTROL sdc = 0;
|
|
PSECURITY_DESCRIPTOR psdSelfRelativeCopy = NULL;
|
|
DWORD dwRevision = 0;
|
|
DWORD cb = 0;
|
|
|
|
Assert(IsValidSecurityDescriptor( psdOriginal ) );
|
|
|
|
if( !::GetSecurityDescriptorControl( psdOriginal, &sdc, &dwRevision ) )
|
|
{
|
|
DWORD err = ::GetLastError();
|
|
Error(("GetSecurityDescriptorControl() failed with %d\n", err));
|
|
return HRESULT_FROM_WIN32( err );
|
|
}
|
|
|
|
if( sdc & SE_SELF_RELATIVE )
|
|
{
|
|
// the original is in self-relative format, just byte-copy it
|
|
|
|
// get size
|
|
cb = ::GetSecurityDescriptorLength( psdOriginal );
|
|
|
|
// alloc the memory
|
|
psdSelfRelativeCopy = (PSECURITY_DESCRIPTOR) ::LocalAlloc( LMEM_ZEROINIT, cb );
|
|
if(NULL == psdSelfRelativeCopy)
|
|
{
|
|
Error(("Out of memory.\n"));
|
|
return E_OUTOFMEMORY;
|
|
}
|
|
|
|
// make the copy
|
|
::memcpy( psdSelfRelativeCopy, psdOriginal, cb );
|
|
}
|
|
else
|
|
{
|
|
// the original is in absolute format, convert-copy it
|
|
|
|
// get new size - it will fail and set cb to the correct buffer size
|
|
::MakeSelfRelativeSD( psdOriginal, NULL, &cb );
|
|
|
|
// alloc the new amount of memory
|
|
psdSelfRelativeCopy = (PSECURITY_DESCRIPTOR) ::LocalAlloc( LMEM_ZEROINIT, cb );
|
|
if(!psdSelfRelativeCopy)
|
|
{
|
|
Error(("Out of memory.\n"));
|
|
return E_OUTOFMEMORY; // just in case the exception is ignored
|
|
}
|
|
|
|
if( !::MakeSelfRelativeSD( psdOriginal, psdSelfRelativeCopy, &cb ) )
|
|
{
|
|
DWORD err = ::GetLastError();
|
|
Error(("MakeSelfRelativeSD() failed with %d\n", err));
|
|
|
|
::LocalFree( psdSelfRelativeCopy );
|
|
|
|
return HRESULT_FROM_WIN32( err );
|
|
}
|
|
}
|
|
|
|
*ppsdNew = psdSelfRelativeCopy;
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// This is the entry point function called from our code
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
HMODULE g_hAclui = NULL;
|
|
|
|
extern "C"
|
|
HPROPSHEETPAGE
|
|
CreateFaxSecurityPage()
|
|
{
|
|
HPROPSHEETPAGE hPage = NULL;
|
|
HPROPSHEETPAGE (*pfCreateSecurityPage)(LPSECURITYINFO) = NULL;
|
|
|
|
if(!IsWinXPOS())
|
|
{
|
|
//
|
|
// The security page should bge added only to the local fax printer on XP OS.
|
|
//
|
|
Assert(FALSE);
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// CreateSecurityPage() Requires Windows 2000 or later, so we connect to it dynamically
|
|
//
|
|
if(!g_hAclui)
|
|
{
|
|
g_hAclui = LoadLibrary(TEXT("aclui.dll"));
|
|
if(!g_hAclui)
|
|
{
|
|
Error(("LoadLibrary(aclui.dll) failed with %d\n", GetLastError()));
|
|
goto error;
|
|
}
|
|
}
|
|
|
|
(FARPROC&)pfCreateSecurityPage = GetProcAddress(g_hAclui, "CreateSecurityPage");
|
|
if(!pfCreateSecurityPage)
|
|
{
|
|
Error(("GetProcAddress(CreateSecurityPage) failed with %d\n", GetLastError()));
|
|
goto error;
|
|
}
|
|
|
|
if(!g_pFaxSecurity)
|
|
{
|
|
g_pFaxSecurity = new CFaxSecurity();
|
|
}
|
|
|
|
if(!g_pFaxSecurity)
|
|
{
|
|
Error(("Out of memory.\n"));
|
|
goto error;
|
|
}
|
|
|
|
hPage = pfCreateSecurityPage(g_pFaxSecurity);
|
|
if(!hPage)
|
|
{
|
|
Error(("CreateSecurityPage() failed with %d\n", ::GetLastError()));
|
|
goto error;
|
|
}
|
|
|
|
return hPage;
|
|
|
|
error:
|
|
|
|
if(g_hAclui)
|
|
{
|
|
FreeLibrary(g_hAclui);
|
|
g_hAclui = NULL;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
extern "C"
|
|
void
|
|
ReleaseFaxSecurity()
|
|
{
|
|
if(g_pFaxSecurity)
|
|
{
|
|
g_pFaxSecurity->Release();
|
|
}
|
|
|
|
if(g_hAclui)
|
|
{
|
|
FreeLibrary(g_hAclui);
|
|
g_hAclui = NULL;
|
|
}
|
|
}
|