タイトル : ファイルのアクセス権を判定する関数 投稿日 : 2009/04/06(Mon) 11:15 投稿者 : はるちゃん
ファイルのアクセス権を判定する関数(Function )を作ったのですが、 フルコントロール(拒否)、変更(拒否)、読み取り(拒否)のときは うまく動作するのですが、書き込み(拒否)のときは、読み取りはOKなので 判定をOKにしたいのですが、どのようにすれば取得できるでしょうか? WINDOWS XP SP2 VB6 SP6 です、よろしくお願いします Option Explicit '■■ 定数宣言 ■■ Public Const GMEM_FIXED = &H0 ' 固定メモリ確保 '■■ API関数宣言 ■■ ' メモリの確保 Declare Function GlobalAlloc Lib "kernel32" ( _ ByVal wFlags As Long, _ ByVal dwBytes As Long) As Long ' 確保したメモリの開放 Declare Function GlobalFree Lib "kernel32" ( _ ByVal hMem As Long) As Long ' メモリブロックの移動 Declare Sub MoveMemory Lib "kernel32" Alias "RtlMoveMemory" ( _ pDest As Any, _ pSource As Any, _ ByVal dwLength As Long) '■■ 定数宣言 ■■ Public Const ERROR_INSUFFICIENT_BUFFER = 122 Enum ACL_INFORMATION_CLASS AclRevisionInformation = 1 '// ACL revision information AclSizeInformation = 2 '// ACL size information End Enum ' GetFileSecurity の RequestedInformation パラメータ Enum SECURITY_INFORMATION OWNER_SECURITY_INFORMATION = &H1 ' 所有者 GROUP_SECURITY_INFORMATION = &H2 ' アクセス権グループ DACL_SECURITY_INFORMATION = &H4 ' 任意のACL(アクセスの種類) SACL_SECURITY_INFORMATION = &H8 ' システムACL(アクセスの種類) End Enum ' LookupAccountName,LookupAccountSid の peUse パラメータ Enum SID_NAME_USE SidTypeUser ' ユーザーアカウント SidTypeGroup ' グローバルグループアカウント SidTypeDomain ' ドメインアカウント SidTypeAlias ' エイリアス SidTypeWellKnownGroup ' 有名なグループアカウント(Everyoneなど) SidTypeDeletedAccount ' 削除アカウント SidTypeInvalid ' 無効なアカウント SidTypeUnknown ' 不明 End Enum '// '// The following are the predefined ace types that go into the AceType '// field of an Ace header. '// Public Const ACCESS_ALLOWED_ACE_TYPE = &H0 ' アクセス許可ACE Public Const ACCESS_DENIED_ACE_TYPE = &H1 ' アクセス拒否ACE Public Const SYSTEM_AUDIT_ACE_TYPE = &H2 ' 監査ACE Public Const SYSTEM_ALARM_ACE_TYPE = &H3 ' 未サポート '// '// The following are the inherit flags that go into the AceFlags field '// of an Ace header. '// Public Const OBJECT_INHERIT_ACE = &H1 ' プライマリオブジェクトに含まれた他のコンテナがACEを継承する Public Const CONTAINER_INHERIT_ACE = &H2 ' プライマリオブジェクトに含まれたコンテナのみがACEを継承する Public Const NO_PROPAGATE_INHERIT_ACE = &H4 ' OBJECT_INHERIT_ACE,CONTAINER_INHERIT_ACE が指定されている場合子オブジェクトにACEを引き継がない Public Const INHERIT_ONLY_ACE = &H8 ' プライマリオブジェクトに含まれた他のコンテナのみがACEを継承する Public Const VALID_INHERIT_FLAGS = &HF ' '// The following are the currently defined ACE flags that go into the '// AceFlags field of an ACE header. Each ACE type has its own set of '// AceFlags. '// '// SUCCESSFUL_ACCESS_ACE_FLAG - used only with system audit and alarm ACE '// types to indicate that a message is generated for successful accesses. '// '// FAILED_ACCESS_ACE_FLAG - used only with system audit and alarm ACE types '// to indicate that a message is generated for failed accesses. '// '// '// SYSTEM_AUDIT and SYSTEM_ALARM AceFlags '// '// These control the signaling of audit and alarms for success or failure. '// Public Const SUCCESSFUL_ACCESS_ACE_FLAG = &H40 Public Const FAILED_ACCESS_ACE_FLAG = &H80 '■■ 構造体宣言 ■■ Type ACL_SIZE_INFORMATION AceCount As Long ' ACEの数 AclBytesInUse As Long ' 利用しているACLサイズ AclBytesFree As Long ' ACLの空きサイズ End Type Type ACE_HEADER AceType As Byte ' ACEタイプ AceFlags As Byte ' ACEフラグ AceSize As Integer ' ACEサイズ End Type '// '// We'll define the structure of the predefined ACE types. Pictorally '// the structure of the predefined ACE's is as follows: '// '// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 '// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 '// +---------------+-------+-------+---------------+---------------+ '// | AceFlags | Resd |Inherit| AceSize | AceType | '// +---------------+-------+-------+---------------+---------------+ '// | Mask | '// +---------------------------------------------------------------+ '// | | '// + + '// | | '// + Sid + '// | | '// + + '// | | '// +---------------------------------------------------------------+ '// '// Mask is the access mask associated with the ACE. This is either the '// access allowed, access denied, audit, or alarm mask. '// '// Sid is the Sid associated with the ACE. '// '// The following are the four predefined ACE types. '// Examine the AceType field in the Header to determine '// which structure is appropriate to use for casting. ' 以下の構造体は、ACE_HEADER構造体のAceTypeメンバの値により利用する構造体 ' を特定しますが、構造体が同じ構成の為、サンプルでは全てACCESS_ALLOWED_ACE ' 構造体を代用しています。 Type ACCESS_ALLOWED_ACE Header As ACE_HEADER ' ACE_HEADER 構造体 Mask As Long ' アクセスマスク SidStart As Long ' SIDの開始ポインタ End Type Type ACCESS_DENIED_ACE Header As ACE_HEADER Mask As Long SidStart As Long End Type Type SYSTEM_AUDIT_ACE Header As ACE_HEADER Mask As Long SidStart As Long End Type Type SYSTEM_ALARM_ACE Header As ACE_HEADER Mask As Long SidStart As Long End Type '■■ API関数宣言 ■■ '------------------------------------------------------ ' ファイルのセキュリティ情報の取得 '------------------------------------------------------ ' [I] lpFileName : 対象となるファイル名 ' [I] RequestedInformation : 取得するセキュリティ情報のタイプ(SECURITY_INFORMATIONの組み合わせ) ' [O] pSecurityDescriptor : 取得したSID ' [I] nLength : pSecurityDescriptorのサイズ ' [O] lpnLengthNeeded : バッファ必要サイズ ' ' 戻り値 : 0以外 = 成功 ' : 0 = 失敗 ' Declare Function GetFileSecurity Lib "advapi32.dll" Alias "GetFileSecurityA" ( _ ByVal lpFileName As String, _ ByVal RequestedInformation As SECURITY_INFORMATION, _ pSecurityDescriptor As Long, _ ByVal nLength As Long, _ lpnLengthNeeded As Long) As Long '------------------------------------------------------ ' セキュリティ情報より所有者SID取得 '------------------------------------------------------ ' [I] pSecurityDescriptor : SD(セキュリティ記述子) ' [O] pOwner : 所有者SID ' [O] lpbOwnerDefaulted : デフォルト所有者の場合(True) ' ' 戻り値 : 0以外 = 成功 ' : 0 = 失敗 ' Declare Function GetSecurityDescriptorOwner Lib "advapi32.dll" ( _ ByVal pSecurityDescriptor As Long, _ pOwner As Long, _ lpbOwnerDefaulted As Long) As Long '------------------------------------------------------ ' セキュリティ情報よりグループSID取得 '------------------------------------------------------ ' [I] pSecurityDescriptor : SD(セキュリティ記述子) ' [O] pGroup : グループSID ' [O] pbGroupDefaulted : デフォルトグループの場合(True) ' ' 戻り値 : 0以外 = 成功 ' : 0 = 失敗 ' Declare Function GetSecurityDescriptorGroup Lib "advapi32.dll" ( _ ByVal pSecurityDescriptor As Long, _ pGroup As Long, _ pbGroupDefaulted As Long) As Long '------------------------------------------------------ ' セキュリティ情報より任意ACL取得 '------------------------------------------------------ ' [I] pSecurityDescriptor : SD(セキュリティ記述子) ' [O] lpbDaclPresent : 任意ACLがある場合(True) ' [O] pDacl : 任意ACLのポインタ ' [O] lpbDaclDefaulted : デフォルト任意ACLの場合(True) ' ' 戻り値 : 0以外 = 成功 ' : 0 = 失敗 ' Declare Function GetSecurityDescriptorDacl Lib "advapi32.dll" ( _ ByVal pSecurityDescriptor As Long, _ lpbDaclPresent As Long, _ pDacl As Long, _ lpbDaclDefaulted As Long) As Long '------------------------------------------------------ ' ACL情報の取得 '------------------------------------------------------ ' [I] pAcl : 対象となるACL ' [O] pAclInformation : 取得したACL情報 ' [I] nAclInformationLength : pAclInformationのサイズ ' [I] dwAclInformationClass : 取得情報タイプ(ACL_INFORMATION_CLASS) ' ' 戻り値 : 0以外 = 成功 ' : 0 = 失敗 ' Declare Function GetAclInformation Lib "advapi32.dll" ( _ ByVal pAcl As Long, _ pAclInformation As Any, _ ByVal nAclInformationLength As Long, _ ByVal dwAclInformationClass As ACL_INFORMATION_CLASS) As Long '------------------------------------------------------ ' ACE情報の取得 '------------------------------------------------------ ' [I] pAcl : 対象となるACL ' [I] dwAceIndex : 取得するACEの位置(0が最初) ' [O] pAce : 取得したACEへのポインタ ' ' 戻り値 : 0以外 = 成功 ' : 0 = 失敗 ' Declare Function GetAce Lib "advapi32.dll" ( _ ByVal pAcl As Long, _ ByVal dwAceIndex As Long, _ pAce As Any) As Long ' ボリューム情報取得 '------------------------------------------------------ ' [ I ] lpRootPathName : ルートディレクトリ名 ' [I/O] lpVolumeNameBuffer : ボリューム名 ' [I/O] nVolumeNameSize : lpVolumeNameBufferのサイズ ' [I/O] lpVolumeSerialNumber : ボリュームシリアルナンバー ' [I/O] lpMaximumComponentLength : ファイル名構成要素の最大長 ' [I/O] lpFileSystemFlags : ファイルシステムフラグ ' [I/O] lpFileSystemNameBuffer : ファイルシステム名 ' [I/O] nFileSystemNameSize : lpFileSystemNameBufferのサイズ ' ' 戻り値 : 0以外 = 正常 ' : 0 = 失敗 ' Private Declare Function GetVolumeInformation Lib "kernel32" Alias "GetVolumeInformationA" ( _ ByVal lpRootPathName As String, _ ByVal lpVolumeNameBuffer As String, _ ByVal nVolumeNameSize As Long, _ lpVolumeSerialNumber As Long, _ lpMaximumComponentLength As Long, _ lpFileSystemFlags As Long, _ ByVal lpFileSystemNameBuffer As String, _ ByVal nFileSystemNameSize As Long) As Long 'add ed 2009/4/3 Public Function IsSECURITY(ByVal strFilePath As String) As Boolean Dim lngRet As Long ' 戻り値 Dim lngSd As Long ' SD(セキュリティ記述子)ポインタ Dim lngSdLength As Long ' SD(セキュリティ記述子)サイズ Dim strAccount As String ' アカウント名 Dim strDomain As String ' ドメイン名 Dim lngUse As Long ' 説明タイプ ' Dim strFilePath As String ' 対象ファイルフルパス Dim lngDacl As Long ' 任意ACLポインタ Dim lngDaclPresent As Long ' 任意ACLの有無 Dim lngDaclDefaulted As Long ' デフォルト任意ACLフラグ Dim tAclSizeInfo As ACL_SIZE_INFORMATION ' ACL_SIZE_INFORMATION 構造体 Dim lngAceCount As Long ' ACLに含まれるACEの数 Dim i As Long ' ループカウンタ Dim lngAce As Long ' ACEポインタ Dim tAccessAllowedAce As ACCESS_ALLOWED_ACE ' ACCESS_ALLOWED_ACE 構造体 Dim lngSid As Long ' SIDポインタ Dim strLine_Account As String * 30 ' アカウント名 Dim strLine_Permission As String ' パーミッション ' 選択ドライブがNTFSかチェック If Not IsNTFS(strFilePath) Then ' magb "選択ドライブはNTFSでない為、取得できません。" Exit Function End If '-------------------------------- ' ファイルのセキュリティ情報取得 '-------------------------------- ' 必要なSD(セキュリティ記述子)サイズ取得 If GetFileSecurity(strFilePath, _ DACL_SECURITY_INFORMATION, _ ByVal 0, 0, lngSdLength) = 0 Then If Err.LastDllError <> ERROR_INSUFFICIENT_BUFFER Then ' MsgBox mErr.fncGetErrorString(Err.LastDllError) Exit Function End If End If ' 必要なSD(セキュリティ記述子)サイズ確保 lngSd = GlobalAlloc(GMEM_FIXED, lngSdLength) ' ファイルのセキュリティ情報取得 If GetFileSecurity(strFilePath, _ DACL_SECURITY_INFORMATION, _ ByVal lngSd, ByVal lngSdLength, lngSdLength) = 0 Then ' MsgBox mErr.fncGetErrorString(Err.LastDllError) Call GlobalFree(lngSd) Exit Function End If '-------------------------------- ' 任意ACL情報取得 '-------------------------------- If GetSecurityDescriptorDacl(lngSd, lngDaclPresent, lngDacl, lngDaclDefaulted) = 0 Then ' MsgBox mErr.fncGetErrorString(Err.LastDllError) Call GlobalFree(lngSd) Exit Function End If ' 任意ACL情報がある場合 If lngDaclPresent <> 0 Then ' 任意ACL情報取得 If GetAclInformation(lngDacl, tAclSizeInfo, Len(tAclSizeInfo), AclSizeInformation) = 0 Then ' MsgBox mErr.fncGetErrorString(Err.LastDllError) Call GlobalFree(lngSd) Exit Function End If ' ACEの列挙開始 lngAceCount = tAclSizeInfo.AceCount For i = 0 To lngAceCount ' ACEの取得 If GetAce(ByVal lngDacl, ByVal i, lngAce) <> 0 Then ' ACEバッファ構造体にコピー MoveMemory tAccessAllowedAce, ByVal lngAce, ByVal LenB (tAccessAllowedAce) ' アクセス権文字列取得 If tAccessAllowedAce.Header.AceType = ACCESS_DENIED_ACE_TYPE Then IsSECURITY = True 'アクセス権なし Exit For End If End If Next i End If ' 後始末 Call GlobalFree(lngSd) End Function Public Function IsNTFS(ByVal strFilePath As String) As Boolean Dim strVolBuffer As String Dim strSystemName As String Dim strVol As String Dim lngSerialNum As Long Dim lngSystemFlags As Long Dim lngComponentLen As Long Dim lngRet As Long strVolBuffer = String(256, 0) strSystemName = String(256, 0) strVol = UCase(Mid(strFilePath, 1, 3)) lngRet = GetVolumeInformation(strVol, _ strVolBuffer, _ 255, _ lngSerialNum, _ lngComponentLen, _ lngSystemFlags, _ strSystemName, _ 255) If lngRet = 0 Then IsNTFS = False Else If UCase(Mid(strSystemName, 1, 4)) = "NTFS" Then IsNTFS = True Else IsNTFS = False End If End If End Function |