指定したファイルへACLを設定します。 InitializeSecurityDescriptor()関数でSECURITY_DESCRIPTORを生成し SetSecurityDescriptorDacl()関数でACLを設定して、SetFileSecurity()関数 にてファイルへ設定します。
#include <stdio.h>
#include <tchar.h>
#include <iostream>
#include <windows.h>
/*
指定したファイルのACLを取得する
*ppAclはNULL以外の場合はfree()で解放してください。
*/
HRESULT GetFileAcl
(
std::wstring oFilePath
, ACL** ppAcl
)
{
HRESULT hResult;
ACL* pResultAcl = NULL;
BOOL bRet;
DWORD dwSecurityDescriptorSize = 0;
// SECURITY_DESCRIPTORサイズの取得
bRet = GetFileSecurity(
oFilePath.c_str()
, DACL_SECURITY_INFORMATION
, NULL
, 0
, &dwSecurityDescriptorSize
);
if ( 0 == bRet ) {
DWORD dwResult = ::GetLastError();
// バッファサイズ不足以外はエラー
if ( dwResult != ERROR_INSUFFICIENT_BUFFER ) {
// エラー
return( HRESULT_FROM_WIN32( dwResult ) );
}
}
// SECURITY_DESCRIPTOR用メモリの確保
SECURITY_DESCRIPTOR* pSecurityDescriptor =
(SECURITY_DESCRIPTOR*)calloc( 1, dwSecurityDescriptorSize );
if ( NULL == pSecurityDescriptor ) {
// メモリ不足
return( E_OUTOFMEMORY );
}
// SECURITY_DESCRIPTORの取得
bRet = GetFileSecurity(
oFilePath.c_str()
, DACL_SECURITY_INFORMATION
, pSecurityDescriptor
, dwSecurityDescriptorSize
, &dwSecurityDescriptorSize
);
if ( 0 == bRet ) {
// エラー
hResult = HRESULT_FROM_WIN32( ::GetLastError() );
goto err;
}
/*
ACL情報の取得
*/
ACL_SIZE_INFORMATION tAclSizeInfomation;
ACL* pDacl = NULL;
{
BOOL bDaclPresent;
BOOL bDaclDefaulted;
// DACLのアドレスを取得
bRet = GetSecurityDescriptorDacl(
pSecurityDescriptor
, &bDaclPresent
, &pDacl
, &bDaclDefaulted
);
if ( 0 == bRet ) {
// エラー
hResult = HRESULT_FROM_WIN32( ::GetLastError() );
goto err;
}
// 権限を持っていない場合は正常ケースとする
if ( FALSE == bDaclPresent ) {
// エラー
hResult = S_OK;
goto err;
}
// ACL情報の取得
bRet = GetAclInformation( pDacl, &tAclSizeInfomation
, sizeof( tAclSizeInfomation ), AclSizeInformation );
if ( 0 == bRet ) {
// エラー
hResult = HRESULT_FROM_WIN32( ::GetLastError() );
goto err;
}
}
// DACLのサイズを取得
DWORD dwDaclSize = tAclSizeInfomation.AclBytesInUse
+ tAclSizeInfomation.AclBytesFree;
pResultAcl = (ACL*)calloc( 1, dwDaclSize );
if ( NULL == pResultAcl ) {
// メモリ不足
hResult = E_OUTOFMEMORY;
goto err;
}
// DACLのコピー
memcpy( pResultAcl, pDacl, dwDaclSize );
// 正常終了
hResult = S_OK;
err:
// ACLを返す
*ppAcl = pResultAcl;
// SECURITY_DESCRIPTORの解放
if ( pSecurityDescriptor ) {
free( pSecurityDescriptor );
}
// 正常終了
return( hResult );
}
/*
指定したファイルへACLを設定する
*/
HRESULT SetFileAcl
(
std::wstring oFilePath
, ACL* pAcl
)
{
SECURITY_DESCRIPTOR tSecurityDescriptor;
BOOL bRet;
// DACLを初期化
bRet = InitializeSecurityDescriptor( &tSecurityDescriptor
, SECURITY_DESCRIPTOR_REVISION );
if ( 0 == bRet ) {
// エラー
return( HRESULT_FROM_WIN32( ::GetLastError() ) );
}
// セキュリティ記述子にDACLの情報を設定する
bRet = SetSecurityDescriptorDacl( &tSecurityDescriptor, TRUE, pAcl, FALSE );
if ( 0 == bRet ) {
// エラー
return( HRESULT_FROM_WIN32( ::GetLastError() ) );
}
// ファイルにセキュリティ(セキュリティ記述子の情報)を設定する
bRet = SetFileSecurity(
oFilePath.c_str()
, DACL_SECURITY_INFORMATION
, &tSecurityDescriptor
);
if ( 0 == bRet ) {
// エラー
return( HRESULT_FROM_WIN32( ::GetLastError() ) );
}
// 正常終了
return( S_OK );
}
/*
指定したファイルへACLを設定する
*/
int _tmain
(
int argc
, _TCHAR* argv[]
)
{
// 標準出力にユニコード出力する
setlocale( LC_ALL, "Japanese" );
HRESULT hResult;
ACL* pAcl = NULL;
// ACLの取得
hResult = GetFileAcl( L"c:¥¥org¥¥test1.txt", &pAcl );
if ( S_OK == hResult ) {
// 権限あり
if ( NULL != pAcl ) {
// ACLの設定
hResult = SetFileAcl( L"c:¥¥org¥¥test2.txt", pAcl );
// メモリの解放
free( pAcl );
}
}
// 正常終了
return( 0 );
}