📄 edit.cpp
字号:
ULONG n = --m_cRefs;
if ( 0 == n )
delete this;
return n;
}
STDMETHODIMP_(BOOL) IsDaclCanonical( PACL pDacl )
{
return true;
}
STDMETHODIMP LookupSids( ULONG cSids, PSID *rgpSids, LPDATAOBJECT *pSidNames )
{
SidTable * sids = new SidTable( cSids );
sids->AddRef();
for ( ULONG i = 0; i < cSids; ++i ) {
TCHAR Name[ MAX_PATH ];
TCHAR Domain[ MAX_PATH ];
SID_NAME_USE Use;
DWORD cbName = MAX_PATH;
DWORD cbDomain = MAX_PATH;
BOOL ok = LookupAccountSid( g_ComputerName+2, rgpSids[i], Name, &cbName, Domain, &cbDomain, &Use );
if ( ok ) {
TCHAR fullname[ 2*MAX_PATH ];
_stprintf( fullname, _T("%s (%s\\%s)"), Name, Domain, Name );
sids->Add( rgpSids[i], fullname, Use );
}
}
*pSidNames = sids;
return S_OK;
}
};
#endif
// This base class factors out common implementation between
// the window station and desktop implementations of ISecurityInformation.
// For instance, the Set/GetSecurity calls can be implemented once,
// since they both just call Set/GetSecurityInfo passing a handle
// (of either a winsta or a desktop).
struct CObjectSecurityInfoBase : ISecurityInformation
{
long m_cRefs;
DWORD m_grfExtraFlags;
const wchar_t* const m_pszObjectName;
const wchar_t* const m_pszPageTitle;
wchar_t m_Computer[ MAX_PATH ];
wchar_t * m_Name;
CObjectSecurityInfoBase( DWORD grfExtraFlags,
const wchar_t* pszObjectName,
const wchar_t* pszPageTitle = 0 )
: m_cRefs(0),
m_grfExtraFlags( grfExtraFlags ),
m_pszObjectName( pszObjectName ),
m_pszPageTitle( pszPageTitle )
{
_tcscpy( m_Computer, m_pszObjectName );
m_Name = _tcschr( m_Computer+2, '\\' );
if ( m_Name ) {
*m_Name++ = 0;
}
}
virtual ~CObjectSecurityInfoBase()
{
}
STDMETHODIMP QueryInterface( REFIID iid, void** ppv )
{
if ( iid == IID_ISecurityInformation || IID_IUnknown == iid ) {
*ppv = this;
} else if ( iid == IID_ISecurityInformation2 ) {
#if 0
CObjectSecurityInfoBase2 * I2 = new CObjectSecurityInfoBase2;
*ppv = I2;
#else
*ppv = NULL;
#endif
} else {
*ppv = NULL;
}
if ( *ppv == NULL )
return E_NOINTERFACE;
reinterpret_cast<IUnknown*>( *ppv )->AddRef();
return S_OK;
}
STDMETHODIMP_(ULONG) AddRef()
{
return ++m_cRefs;
}
STDMETHODIMP_(ULONG) Release()
{
ULONG n = --m_cRefs;
if ( 0 == n )
delete this;
return n;
}
STDMETHODIMP GetObjectInformation( SI_OBJECT_INFO * poi )
{
static bool LookedForDC = false;
static TCHAR * domainController = NULL;
if ( ! LookedForDC ) {
WKSTA_USER_INFO_1 * user = NULL;
NetWkstaUserGetInfo( NULL, 1, (BYTE **)&user );
NetGetDCName( NULL, user->wkui1_logon_domain, (BYTE **)&domainController );
NetApiBufferFree( user );
LookedForDC = true;
}
// We want to edit the DACL (PERMS), the OWNER,
// and we want the Advanced button
poi->dwFlags = SI_EDIT_OWNER | SI_EDIT_PERMS | m_grfExtraFlags;
// this determines the module used to discover stringtable entries
poi->hInstance = g_hInst;
poi->pszServerName = domainController ? domainController : m_Computer+2;
poi->pszObjectName = const_cast<wchar_t*>( m_pszObjectName );
poi->pszPageTitle = const_cast<wchar_t*>( m_pszPageTitle );
if ( m_pszPageTitle )
poi->dwFlags |= SI_PAGE_TITLE;
return S_OK;
}
STDMETHODIMP GetSecurity( SECURITY_INFORMATION ri, void** ppsd, BOOL bDefault )
{
// map directly onto the winsta/desktop security descriptor
SHARE_INFO_502 * Info502 = NULL;
DWORD status = NetShareGetInfo( m_Computer, (wchar_t *)m_Name, 502, (BYTE **)&Info502 );
if ( status == 0 ) {
PSECURITY_DESCRIPTOR sd = Info502->shi502_security_descriptor;
IsValidSecurityDescriptor( sd );
*ppsd = sd;
}
return status ? HRESULT_FROM_WIN32(status) : S_OK;
}
STDMETHODIMP SetSecurity( SECURITY_INFORMATION ri, void* psd )
{
// Get original sd
BYTE * sdOrig;
SHARE_INFO_502 * Info502 = NULL;
DWORD status = NetShareGetInfo( m_Computer, m_Name, 502, (BYTE **)&Info502 );
if ( status == 0 ) {
SetLastError( 0 );
IsValidSecurityDescriptor( Info502->shi502_security_descriptor );
GetLastError();
sdOrig = (BYTE *) Info502->shi502_security_descriptor;
} else {
return HRESULT_FROM_WIN32(status);
}
IsValidSecurityDescriptor( psd );
IsValidSecurityDescriptor( sdOrig );
// Combine with new SD components
PSECURITY_DESCRIPTOR sdAbs = UpdateSD( sdOrig, psd, ri );
if ( ! IsValidSecurityDescriptor( sdAbs ) )
return HRESULT_FROM_WIN32(GetLastError());
// convert to relative format
DWORD nb = 0;
MakeSelfRelativeSD( sdAbs, NULL, &nb );
PSECURITY_DESCRIPTOR sdRel = (BYTE *) LocalAlloc( LMEM_FIXED, nb );
if ( ! MakeSelfRelativeSD( sdAbs, sdRel, &nb ) )
return HRESULT_FROM_WIN32(GetLastError());
IsValidSecurityDescriptor( sdRel );
GetSecurityDescriptorLength( sdRel );
// Set updated sd
Info502->shi502_security_descriptor = sdRel;
status = NetShareSetInfo( m_Computer, m_Name, 502, (BYTE *)Info502, NULL );
LocalFree( sdAbs );
LocalFree( sdRel );
return status ? HRESULT_FROM_WIN32(status) : S_OK;
}
STDMETHODIMP PropertySheetPageCallback( HWND hwnd, UINT msg, SI_PAGE_TYPE pt )
{
// this is effectively a pass-through from the PropertySheet callback,
// which we don't care about for this sample
return S_OK;
}
};
struct CModifySharesSecurityInfo : CObjectSecurityInfoBase
{
CModifySharesSecurityInfo( const wchar_t* pszObjectTitle, const wchar_t* pszPageTitle = 0 )
: CObjectSecurityInfoBase( SI_CONTAINER | SI_NO_ACL_PROTECT, pszObjectTitle, pszPageTitle )
{
}
~CModifySharesSecurityInfo()
{
}
STDMETHODIMP GetAccessRights( const GUID*,
DWORD dwFlags,
SI_ACCESS** ppAccess,
ULONG* pcAccesses,
ULONG* piDefaultAccess )
{
// here's where we hand back the desktop permissions->strings mapping
*ppAccess = const_cast<SI_ACCESS*>( g_ModifySharesAccess );
*pcAccesses = sizeof g_ModifySharesAccess / sizeof *g_ModifySharesAccess;
*piDefaultAccess = 0;
return S_OK;
}
STDMETHODIMP MapGeneric( const GUID*, UCHAR* pAceFlags, ACCESS_MASK* pMask )
{
// here's where we hand back the desktop generic permissions mapping
MapGenericMask( pMask, &g_ModifySharesGenericMapping );
return S_OK;
}
STDMETHODIMP GetInheritTypes( SI_INHERIT_TYPE** ppInheritTypes, ULONG* pcInheritTypes )
{
// Desktops are not containers, and thus have no options for inheritable
// entries in the DACL or SACL. Since we didn't specify SI_CONTAINER in our
// GetObjectInformation call, this function will never be called.
return E_NOTIMPL;
}
};
int Properties( HINSTANCE hInst, HWND hParent, const TCHAR * shareName )
{
g_hInst = hInst;
typedef HPROPSHEETPAGE (WINAPI * typeCreateSecurityPage)( LPSECURITYINFO psi );
typedef BOOL (WINAPI * typeEditSecurity)( HWND hwndOwner, LPSECURITYINFO psi );
typeCreateSecurityPage pCreateSecurityPage = (typeCreateSecurityPage) GetProcAddress( LoadLibrary(L"ACLUI.DLL"), "CreateSecurityPage" );
typeEditSecurity pEditSecurity = (typeEditSecurity) GetProcAddress( LoadLibrary(L"ACLUI.DLL"), "EditSecurity" );
if ( pCreateSecurityPage == NULL || pEditSecurity == NULL ) {
MessageBox( hParent, _T("Sorry, the File Properties dialog is available only on Windows 2000 and later."),
APPNAME, MB_OK|MB_ICONINFORMATION );
return 0;
}
#if 1
CModifySharesSecurityInfo * si = new CModifySharesSecurityInfo( shareName, L"Share Permissions" );
si->AddRef();
(*pEditSecurity)( hParent, si );
si->Release();
return 0;
#else
// Convert our ISecurityInformation implementations into property pages
HPROPSHEETPAGE rghps[1];
{
CModifySharesSecurityInfo * si0 = new CModifySharesSecurityInfo( L"SrvsvcShareFileInfo", L"Share Security", L"Share Permissions" );
// CModifySharesSecurityInfo * si1 = new CModifySharesSecurityInfo( L"SrvsvcShareFileInfo", L"Creating File Shares", L"Modify File Shares" );
// CModifySharesSecurityInfo * si2 = new CModifySharesSecurityInfo( L"SrvsvcSharePrintInfo", L"Creating Print Shares", L"Modify Print Shares" );
// CModifySharesSecurityInfo * si3 = new CModifySharesSecurityInfo( L"SrvsvcShareAdminInfo", L"Creating Admin", L"Modify Admin Shares" );
return EditSecurity( hParent, si0 );
si0->AddRef();
// si1->AddRef();
// si2->AddRef();
// si3->AddRef();
rghps[0] = CreateSecurityPage( (LPSECURITYINFO) si0 );
// rghps[1] = CreateSecurityPage( si1 );
// rghps[2] = CreateSecurityPage( si2 );
// rghps[3] = CreateSecurityPage( si3 );
si0->Release();
// si1->Release();
// si2->Release();
// si3->Release();
}
// Wrap our two property pages in a modal dialog by calling PropertySheet
PROPSHEETHEADER psh; ZeroMemory( &psh, sizeof psh );
psh.dwSize = sizeof psh;
psh.hInstance = g_hInst;
psh.hwndParent = hParent;
psh.pszCaption = L"Share Properties";
psh.nPages = sizeof rghps / sizeof *rghps;
psh.phpage = rghps;
PropertySheet( &psh );
return 0;
#endif
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -