powered by simpleCommunicator - 2.0.52     © 2025 Programmizd 02
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Установка разрешений для папки (Vista).
10 сообщений из 10, страница 1 из 1
Установка разрешений для папки (Vista).
    #35990532
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Столкнулся с некоторой некорректностью работы собственной проги в висте.
Один из способов борьбы отключение UMC, другой - наделение каких то exe-шников правами администратора (через реестр при установке). Докопался до следующего камня. Число проблем резко снижается, если поиграться с "разрешениями" для папки:чтение-запись и т.п. Т.е. чтобы минимизировать проблемы и не париться надо открыть для папки своей программы "полный доступ" для Компьютер\Пользователи. После долгих копаний научился наконец это делать "ручками", что вообщем то тоже не тривиально. Теперь думаю как это сделать программно. Перелопатив реестр, возникла мысль что копать надо не туда и делается все на уровне файловой системы NTFS а не на уровне OS Vista. Есть лог программы, которая подобное делает "типа грамотно" на висте.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
Starting folder permissions definition.
Folder D:\ProgramData\Proga\...\
  Calling CreateFile... Done.
  Calling AllocateAndInitializeSid... Done.
    Calling GetSecurityInfo... Done.
    Calling SetEntriesInAcl... Done.
    Calling SetSecurityInfo... Done.
  Calling AddAceToObjectsSecurityDescriptor... Done.
  Calling AllocateAndInitializeSid... Done.
  Calling AllocateAndInitializeSid... Done.
    Calling GetSecurityInfo... Done.
    Calling SetEntriesInAcl... Done.
    Calling SetSecurityInfo... Done.
  Calling AddAceToObjectsSecurityDescriptor... Done.
Folder permissions definition completed.
Отсюда тонкий намек на те API, в которые надо копать...
Сейчас понятно пойду рыть в google,Microsoft и т.п.
Но м.б. кто-то знает примеры на VB?
...
Рейтинг: 0 / 0
Установка разрешений для папки (Vista).
    #35990561
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ответ собственно вот готовый:
http://allapi.mentalis.org/apilist/9C3BBC69930313A7D25B3142EF2C084B.html

То чего хочу в примитиве делается командой:

Код: plaintext
1.
   SetAccess sUserName, sFolderName, GENERIC_ALL
    'где sUserName="Пользователи", sFolderName=нужная папка

Остался ма...ленький вопрос.
"Пользователи" в зависимости от language будут называться иначе, "Администраторы" кстати тоже и как вычислить эти "стандартные" имена user-ов на компьютере с произвольным языком???...
...
Рейтинг: 0 / 0
Установка разрешений для папки (Vista).
    #35990568
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да, темный лес...после применения таких команд пишет "разрешения не упорядочены", как бы грамотно то сделать.
...
Рейтинг: 0 / 0
Установка разрешений для папки (Vista).
    #35990583
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Как вычислять "Администраторы-юзеры" нашел..
http://support.microsoft.com/kb/288900

Код: plaintext
1.
2.
3.
4.
5.
6.
Declare Function LookupAccountSid Lib "advapi32.dll" _
      Alias "LookupAccountSidA" (ByVal lpSystemName As String, _
      ByVal Sid As Long, ByVal Name As String, cbName As Long, _
      ByVal ReferencedDomainName As String, _
      cbReferencedDomainName As Long, peUse As Integer) As Long
'...
ConstructUniversalAndNTWellKnownSids
...
Рейтинг: 0 / 0
Установка разрешений для папки (Vista).
    #35991412
Фотография Игорь Горбонос
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
> Автор: Дмитрий77

Что-то не могу найти ссылку, в МСДН была статья, я на её основе делал изменение прав на реестр, папки и файлы для
различных пользователей
+
HOWTO: Set Security on a NTFS Folder Programmatically

Q240176


--------------------------------------------------------------------------------
The information in this article applies to:

Microsoft Visual Basic Learning, Professional, and Enterprise Editions for Windows, versions 5.0, 6.0, on platform(s):
The Microsoft Windows NT operating system

--------------------------------------------------------------------------------


SUMMARY
This article describes how to set security on a folder using security APIs from Visual Basic. The folder needs to be
created on an NTFS partition and you need to be a member of the Administrators group. You also need to have read/write
permission (READ_CONTRIOL and WRITE_DAC).

This is a modification to the code described in the article Q194757 "HOWTO: Add an Access-Allowed ACE to a File Through
Visual Basic"



MORE INFORMATION
All objects in Microsoft Windows NT have security attributes that are described by a Security Descriptor. The Security
Descriptor contains information about who owns the object and who has access to the object. The Security Descriptor
contains an Access Control List (ACL) specifying the permissions for users and groups on the object. There are two types
of ACLs: discretionary and system. The discretionary ACL (DACL) is controlled by the owner of the object. The DACL
contains an entry for each user, global group, or local group given access permission to the object. Each of these
entries in the list has an Access Control Entry (ACE). An ACE contains an ACE_HEADER structure, along with the access
permission for that ACE type and the Security Identifier (SID). The ACE_HEADER defines the type of ACE
(ACCESS_ALLOWED_ACE_TYPE or ACCESS_DENIED_ACE_TYPE), the size of the ACE, and the control flags for the ACE. The access
permission determine the type of permission (that is, read, write, and so on) that the user or group has. The process
below describes how to modify the DACL for a directory. This requires adding two ACEs. One ACE for the directory itself
and any subdirectories and another ACE for any files in the directory.


Note
The following code changes permissions on a folder to Add & Read or Change.


The folder needs to be created on an NTFS partition.


You need to be an Administrator on the machine in question and have read/write (READ_CONTROL and WRITE_DAC) access to
the file or directory.


Step to Reproduce Behavior
Create a Standard EXE project in Visual Basic. Form1 is created by default.


Add two Textboxes (Text1 and Text2) and two CommandButtons (Command1 and Command2) to Form1.


Add the following code to the General Declarations of Form1.



Private Sub Command1_Click()
Dim sUserName As String
Dim sFolderName As String
sUserName = Trim$(CStr(Text2.Text))
sFolderName = Trim$(CStr(Text1.Text))
SetAccess sUserName, sFolderName, GENERIC_READ Or GENERIC_EXECUTE Or DELETE Or GENERIC_WRITE
End Sub
Private Sub Command2_Click()
Dim sUserName As String
Dim sFolderName As String
sUserName = Trim$(Text2.Text)
sFolderName = Trim$(Text1.Text)
SetAccess sUserName, sFolderName, GENERIC_EXECUTE Or GENERIC_READ
End Sub
Private Sub Form_Load()
Text1.Text = "enter folder name"
Text2.Text = "enter username"
Command1.Caption = "Change"
Command2.Caption = "Read && Add"
End Sub
Add a Module (Module1) to the project and add the following code to General Declarations.



Option Explicit

' Constants used within our API calls. Refer to the MSDN for more
' information on how/what these constants are used for.

' Memory constants used through various memory API calls.
Public Const GMEM_MOVEABLE = &H2
Public Const LMEM_FIXED = &H0
Public Const LMEM_ZEROINIT = &H40
Public Const LPTR = (LMEM_FIXED + LMEM_ZEROINIT)
Public Const GENERIC_READ = &H80000000
Public Const GENERIC_ALL = &H10000000
Public Const GENERIC_EXECUTE = &H20000000
Public Const GENERIC_WRITE = &H40000000

' The file/security API call constants.
' Refer to the MSDN for more information on how/what these constants
' are used for.
Public Const DACL_SECURITY_INFORMATION = &H4
Public Const SECURITY_DESCRIPTOR_REVISION = 1
Public Const SECURITY_DESCRIPTOR_MIN_LENGTH = 20
Public Const SD_SIZE = (65536 + SECURITY_DESCRIPTOR_MIN_LENGTH)
Public Const ACL_REVISION2 = 2
Public Const ACL_REVISION = 2
Public Const MAXDWORD = &HFFFFFFFF
Public Const SidTypeUser = 1
Public Const AclSizeInformation = 2

' The following are the inherit flags that go into the AceFlags field
' of an Ace header.

Public Const OBJECT_INHERIT_ACE = &H1
Public Const CONTAINER_INHERIT_ACE = &H2
Public Const NO_PROPAGATE_INHERIT_ACE = &H4
Public Const INHERIT_ONLY_ACE = &H8
Public Const INHERITED_ACE = &H10
Public Const VALID_INHERIT_FLAGS = &H1F
Public Const DELETE = &H10000

' Structures used by our API calls.
' Refer to the MSDN for more information on how/what these
' structures are used for.
Type ACE_HEADER
AceType As Byte
AceFlags As Byte
AceSize As Integer
End Type


Public Type ACCESS_DENIED_ACE
Header As ACE_HEADER
Mask As Long
SidStart As Long
End Type

Type ACCESS_ALLOWED_ACE
Header As ACE_HEADER
Mask As Long
SidStart As Long
End Type

Type ACL
AclRevision As Byte
Sbz1 As Byte
AclSize As Integer
AceCount As Integer
Sbz2 As Integer
End Type

Type ACL_SIZE_INFORMATION
AceCount As Long
AclBytesInUse As Long
AclBytesFree As Long
End Type

Type SECURITY_DESCRIPTOR
Revision As Byte
Sbz1 As Byte
Control As Long
Owner As Long
Group As Long
sACL As ACL
Dacl As ACL
End Type

' API calls used within this sample. Refer to the MSDN for more
' information on how/what these APIs do.

Declare Function GetComputerName Lib "kernel32" Alias _
"GetComputerNameA" (ByVal lpBuffer As String, _
nSize As Long) As Long

Declare Function GetUserName Lib "advapi32.dll" Alias _
"GetUserNameA" (ByVal lpBuffer As String, nSize As Long) As Long

Declare Function LookupAccountName Lib "advapi32.dll" Alias _
"LookupAccountNameA" (lpSystemName As String, _
ByVal lpAccountName As String, sid As Any, cbSid As Long, _
ByVal ReferencedDomainName As String, _
cbReferencedDomainName As Long, peUse As Long) As Long

Declare Function InitializeSecurityDescriptor Lib "advapi32.dll" _
(pSecurityDescriptor As SECURITY_DESCRIPTOR, _
ByVal dwRevision As Long) As Long

Declare Function GetSecurityDescriptorDacl Lib "advapi32.dll" _
(pSecurityDescriptor As Byte, lpbDaclPresent As Long, _
pDacl As Long, lpbDaclDefaulted As Long) As Long

Declare Function GetFileSecurityN Lib "advapi32.dll" Alias _
"GetFileSecurityA" (ByVal lpFileName As String, _
ByVal RequestedInformation As Long, _
ByVal pSecurityDescriptor As Long, ByVal nLength As Long, _
lpnLengthNeeded As Long) As Long

Declare Function GetFileSecurity Lib "advapi32.dll" Alias _
"GetFileSecurityA" (ByVal lpFileName As String, _
ByVal RequestedInformation As Long, _
pSecurityDescriptor As Byte, ByVal nLength As Long, _
lpnLengthNeeded As Long) As Long

Declare Function GetAclInformation Lib "advapi32.dll" _
(ByVal pAcl As Long, pAclInformation As Any, _
ByVal nAclInformationLength As Long, _
ByVal dwAclInformationClass As Long) As Long

Public Declare Function EqualSid Lib "advapi32.dll" (pSid1 As Byte, ByVal pSid2 As Long) As Long

Declare Function GetLengthSid Lib "advapi32.dll" (pSid As Any) As _
Long

Declare Function InitializeAcl Lib "advapi32.dll" (pAcl As Byte, _
ByVal nAclLength As Long, ByVal dwAclRevision As Long) As Long

Declare Function GetAce Lib "advapi32.dll" (ByVal pAcl As Long, _
ByVal dwAceIndex As Long, pace As Any) As Long

Declare Function AddAce Lib "advapi32.dll" (ByVal pAcl As Long, _
ByVal dwAceRevision As Long, ByVal dwStartingAceIndex As Long, _
ByVal pAceList As Long, ByVal nAceListLength As Long) As Long

Declare Function AddAccessAllowedAce Lib "advapi32.dll" _
(pAcl As Byte, ByVal dwAceRevision As Long, _
ByVal AccessMask As Long, pSid As Byte) As Long

Public Declare Function AddAccessDeniedAce Lib "advapi32.dll" _
(pAcl As Byte, ByVal dwAceRevision As Long, _
ByVal AccessMask As Long, pSid As Byte) As Long

Declare Function SetSecurityDescriptorDacl Lib "advapi32.dll" _
(pSecurityDescriptor As SECURITY_DESCRIPTOR, _
ByVal bDaclPresent As Long, pDacl As Byte, _
ByVal bDaclDefaulted As Long) As Long

Declare Function SetFileSecurity Lib "advapi32.dll" Alias _
"SetFileSecurityA" (ByVal lpFileName As String, _
ByVal SecurityInformation As Long, _
pSecurityDescriptor As SECURITY_DESCRIPTOR) As Long

Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
(hpvDest As Any, ByVal hpvSource As Long, ByVal cbCopy As Long)

Public Sub SetAccess(sUserName As String, sFileName As String, lMask As Long)
Dim lResult As Long ' Result of various API calls.
Dim I As Integer ' Used in looping.
Dim bUserSid(255) As Byte ' This will contain your SID.
Dim bTempSid(255) As Byte ' This will contain the Sid of each ACE in the ACL .
Dim sSystemName As String ' Name of this computer system.

Dim lSystemNameLength As Long ' Length of string that contains
' the name of this system.

Dim lLengthUserName As Long ' Max length of user name.

'Dim sUserName As String * 255 ' String to hold the current user
' name.


Dim lUserSID As Long ' Used to hold the SID of the
' current user.

Dim lTempSid As Long ' Used to hold the SID of each ACE in the ACL
Dim lUserSIDSize As Long ' Size of the SID.
Dim sDomainName As String * 255 ' Domain the user belongs to.
Dim lDomainNameLength As Long ' Length of domain name needed.

Dim lSIDType As Long ' The type of SID info we are
' getting back.

Dim sFileSD As SECURITY_DESCRIPTOR ' SD of the file we want.

Dim bSDBuf() As Byte ' Buffer that holds the security
' descriptor for this file.

Dim lFileSDSize As Long ' Size of the File SD.
Dim lSizeNeeded As Long ' Size needed for SD for file.


Dim sNewSD As SECURITY_DESCRIPTOR ' New security descriptor.

Dim sACL As ACL ' Used in grabbing the DACL from
' the File SD.

Dim lDaclPresent As Long ' Used in grabbing the DACL from
' the File SD.

Dim lDaclDefaulted As Long ' Used in grabbing the DACL from
' the File SD.

Dim sACLInfo As ACL_SIZE_INFORMATION ' Used in grabbing the ACL
' from the File SD.

Dim lACLSize As Long ' Size of the ACL structure used
' to get the ACL from the File SD.

Dim pAcl As Long ' Current ACL for this file.
Dim lNewACLSize As Long ' Size of new ACL to create.
Dim bNewACL() As Byte ' Buffer to hold new ACL.

Dim sCurrentACE As ACCESS_ALLOWED_ACE ' Current ACE.
Dim pCurrentAce As Long ' Our current ACE.

Dim nRecordNumber As Long

' Get the SID of the user. (Refer to the MSDN for more information on SIDs
' and their function/purpose in the operating system.) Get the SID of this
' user by using the LookupAccountName API. In order to use the SID
' of the current user account, call the LookupAccountName API
' twice. The first time is to get the required sizes of the SID
' and the DomainName string. The second call is to actually get
' the desired information.

lResult = LookupAccountName(vbNullString, sUserName, _
bUserSid(0), 255, sDomainName, lDomainNameLength, _
lSIDType)

' Now set the sDomainName string buffer to its proper size before
' calling the API again.
sDomainName = Space(lDomainNameLength)

' Call the LookupAccountName again to get the actual SID for user.
lResult = LookupAccountName(vbNullString, sUserName, _
bUserSid(0), 255, sDomainName, lDomainNameLength, _
lSIDType)

' Return value of zero means the call to LookupAccountName failed;
' test for this before you continue.
If (lResult = 0) Then
MsgBox "Error: Unable to Lookup the Current User Account: " _
& sUserName
Exit Sub
End If

' You now have the SID for the user who is logged on.
' The SID is of interest since it will get the security descriptor
' for the file that the user is interested in.
' The GetFileSecurity API will retrieve the Security Descriptor
' for the file. However, you must call this API twice: once to get
' the proper size for the Security Descriptor and once to get the
' actual Security Descriptor information.

lResult = GetFileSecurityN(sFileName, DACL_SECURITY_INFORMATION, _
0, 0, lSizeNeeded)

' Redimension the Security Descriptor buffer to the proper size.
ReDim bSDBuf(lSizeNeeded)

' Now get the actual Security Descriptor for the file.
lResult = GetFileSecurity(sFileName, DACL_SECURITY_INFORMATION, _
bSDBuf(0), lSizeNeeded, lSizeNeeded)

' A return code of zero means the call failed; test for this
' before continuing.
If (lResult = 0) Then
MsgBox "Error: Unable to Get the File Security Descriptor"
Exit Sub
End If

' Call InitializeSecurityDescriptor to build a new SD for the
' file.
lResult = InitializeSecurityDescriptor(sNewSD, _
SECURITY_DESCRIPTOR_REVISION)

' A return code of zero means the call failed; test for this
' before continuing.
If (lResult = 0) Then
MsgBox "Error: Unable to Initialize New Security Descriptor"
Exit Sub
End If

' You now have the file's SD and a new Security Descriptor
' that will replace the current one. Next, pull the DACL from
' the SD. To do so, call the GetSecurityDescriptorDacl API
' function.

lResult = GetSecurityDescriptorDacl(bSDBuf(0), lDaclPresent, _
pAcl, lDaclDefaulted)

' A return code of zero means the call failed; test for this
' before continuing.
If (lResult = 0) Then
MsgBox "Error: Unable to Get DACL from File Security " _
& "Descriptor"
Exit Sub
End If

' You have the file's SD, and want to now pull the ACL from the
' SD. To do so, call the GetACLInformation API function.
' See if ACL exists for this file before getting the ACL
' information.
If (lDaclPresent = False) Then
MsgBox "Error: No ACL Information Available for this File"
Exit Sub
End If

' Attempt to get the ACL from the file's Security Descriptor.
lResult = GetAclInformation(pAcl, sACLInfo, Len(sACLInfo), 2&)

' A return code of zero means the call failed; test for this
' before continuing.
If (lResult = 0) Then
MsgBox "Error: Unable to Get ACL from File Security Descriptor"
Exit Sub
End If

' Now that you have the ACL information, compute the new ACL size
' requirements.
lNewACLSize = sACLInfo.AclBytesInUse + (Len(sCurrentACE) + _
GetLengthSid(bUserSid(0))) * 2 - 4

' Resize our new ACL buffer to its proper size.
ReDim bNewACL(lNewACLSize)

' Use the InitializeAcl API function call to initialize the new
' ACL.
lResult = InitializeAcl(bNewACL(0), lNewACLSize, ACL_REVISION)

' A return code of zero means the call failed; test for this
' before continuing.
If (lResult = 0) Then
MsgBox "Error: Unable to Initialize New ACL"
Exit Sub
End If

' If a DACL is present, copy it to a new DACL.
If (lDaclPresent) Then

' Copy the ACEs from the file to the new ACL.
If (sACLInfo.AceCount > 0) Then

' Grab each ACE and stuff them into the new ACL.
nRecordNumber = 0
For I = 0 To (sACLInfo.AceCount - 1)

' Attempt to grab the next ACE.
lResult = GetAce(pAcl, I, pCurrentAce)

' Make sure you have the current ACE under question.
If (lResult = 0) Then
MsgBox "Error: Unable to Obtain ACE (" & I & ")"
Exit Sub
End If

' You have a pointer to the ACE. Place it
' into a structure, so you can get at its size.
CopyMemory sCurrentACE, pCurrentAce, LenB(sCurrentACE)

'Skip adding the ACE to the ACL if this is same usersid
lTempSid = pCurrentAce + 8
If EqualSid(bUserSid(0), lTempSid) = 0 Then

' Now that you have the ACE, add it to the new ACL.
lResult = AddAce(VarPtr(bNewACL(0)), ACL_REVISION, _
MAXDWORD, pCurrentAce, _
sCurrentACE.Header.AceSize)

' Make sure you have the current ACE under question.
If (lResult = 0) Then
MsgBox "Error: Unable to Add ACE to New ACL"
Exit Sub
End If
nRecordNumber = nRecordNumber + 1
End If

Next I

' You have now rebuilt a new ACL and want to add it to
' the newly created DACL.
lResult = AddAccessAllowedAce(bNewACL(0), ACL_REVISION, _
lMask, bUserSid(0))

' Make sure added the ACL to the DACL.
If (lResult = 0) Then
MsgBox "Error: Unable to Add ACL to DACL"
Exit Sub
End If

'If it's directory, we need to add inheritance staff.
If GetAttr(sFileName) And vbDirectory Then

' Attempt to grab the next ACE which is what we just added.
lResult = GetAce(VarPtr(bNewACL(0)), nRecordNumber, pCurrentAce)

' Make sure you have the current ACE under question.
If (lResult = 0) Then
MsgBox "Error: Unable to Obtain ACE (" & I & ")"
Exit Sub
End If
' You have a pointer to the ACE. Place it
' into a structure, so you can get at its size.
CopyMemory sCurrentACE, pCurrentAce, LenB(sCurrentACE)
sCurrentACE.Header.AceFlags = OBJECT_INHERIT_ACE + INHERIT_ONLY_ACE
CopyMemory ByVal pCurrentAce, VarPtr(sCurrentACE), LenB(sCurrentACE)

'add another ACE for files
lResult = AddAccessAllowedAce(bNewACL(0), ACL_REVISION, _
lMask, bUserSid(0))

' Make sure added the ACL to the DACL.
If (lResult = 0) Then
MsgBox "Error: Unable to Add ACL to DACL"
Exit Sub
End If

' Attempt to grab the next ACE.
lResult = GetAce(VarPtr(bNewACL(0)), nRecordNumber + 1, pCurrentAce)

' Make sure you have the current ACE under question.
If (lResult = 0) Then
MsgBox "Error: Unable to Obtain ACE (" & I & ")"
Exit Sub
End If

CopyMemory sCurrentACE, pCurrentAce, LenB(sCurrentACE)
sCurrentACE.Header.AceFlags = CONTAINER_INHERIT_ACE
CopyMemory ByVal pCurrentAce, VarPtr(sCurrentACE), LenB(sCurrentACE)
End If


' Set the file's Security Descriptor to the new DACL.
lResult = SetSecurityDescriptorDacl(sNewSD, 1, _
bNewACL(0), 0)

' Make sure you set the SD to the new DACL.
If (lResult = 0) Then
MsgBox "Error: " & _
"Unable to Set New DACL to Security Descriptor"
Exit Sub
End If

' The final step is to add the Security Descriptor back to
' the file!
lResult = SetFileSecurity(sFileName, _
DACL_SECURITY_INFORMATION, sNewSD)

' Make sure you added the Security Descriptor to the file!
If (lResult = 0) Then
MsgBox "Error: Unable to Set New Security Descriptor " _
& " to File : " & sFileName
MsgBox Err.LastDllError
Else
MsgBox "Updated Security Descriptor on File: " _
& sFileName
End If

End If

End If

End Sub
Run the application.


In the Test1 TextBox, enter the name of the folder you want to change permissions on. (D:\test is entered by default.)
In the Test2 Textbox, enter the name of the user you want to give these permissions to.


Click the Add & Read permissions button to give Add & Read permissions to the folder, or click the Change Permissions
button to give Change permissions to the folder.


To check the permissions on the folder, right-click Explorer. Select the Properties menu item, and click the Security
Tab of the Properties dialog box. On the Security tab, click the Permissions button. The specific account should say Add
& Read or Change depending on which button you clicked in the preceding sample.


Again, the folder needs to be created on an NTFS partition, and you need to be an Administrator on the computer in
question and have read/write (READ_CONTROL and WRITE_DAC) access to the file or directory.



REFERENCES
For additional information on using NT Security through code, click the article numbers below to view the articles in
the Microsoft Knowledge Base:

Q194757 HOWTO: Add an Access-Allowed ACE to a File Through Visual Basic
Q115948 Creating Access Control Lists for Directories
Q202179 HOWTO: Call Windows API Functions with Special Requirements from Visual Basic



Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
Установка разрешений для папки (Vista).
    #35991912
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Игорь, а ссылка что я привел то же самое и есть.
'Example from MSDN (Q240176)
http://allapi.mentalis.org/apilist/9C3BBC69930313A7D25B3142EF2C084B.html

Вопрос только как быть "разрешения не упорядочены", кот. выдается Вистой при "просмотре результатов"?
Когда папка создается вручную или инсталлятором, то часть разрешений уже стоит, причем они "унаследованы"-галочки подобесцвечены, эта штука ставит "черные" галочки разрешений, отсюда видимо конфликтик, м.б. и не повлияет на результат, но понятно что не есть good.
Можно конечно попробовать вначале функцию:

Код: plaintext
Public Sub RemoveAccess(sUserName As String, sFileName As String)

Вот здесь,это измененный код той статьи о кот.говорим.
http://www.andreavb.com/forum/viewtopic_6662.html
и только потом
Код: plaintext
1.
  SetAccess sUserName, sFolderName, GENERIC_ALL
    'где sUserName="Пользователи", sFolderName=нужная папка

Вечером буду экспериментировать-проверять, ибо днем вынужден сидеть под XP.

М.б.надо не "полный доступ", а добавить "особые разрешения" записи-изменения, чтобы не нарушать наследование, ну надо думать где там в коде чего втыкать тогда, замороченно все...
"Неупорядоченность" скорее всего возникает из-за того что дописываю разрешения поверх существующих, винды все допустим делают грамотно если "ручками", а API не всегда, особенно когда "кривыми ручками", а они кривые так как моему опыту в висте еще месяца нету.

Честно, не знаю насколько корректно делать это именно для "пользователи", смысл что программа устанавливается по умолчанию в "Program Files", причем работает с меняющимися файлами кот. там же или в подпапках меняются-образуются-удаляются.
С т.зр. идеологии висты правильнее бы конечно данные держать в "ProgramData", тем более папки созданные в "ProgramData" вроде как наследуют права на запись-изменение-удаление.
Но...это всю прогу переписывать, ошибок точно насажаю...плюс оставить совместимость с xp/2003 еще надо...
...
Рейтинг: 0 / 0
Установка разрешений для папки (Vista).
    #35992711
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
О, родил одну нужную строчку:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
D:\Users\Dima>icacls "d:\test" /grant Пользователи:(OI)(CI)F /T

ICACLS name [/grant[:r] Sid:perm[...]]
       [/deny Sid:perm [...]]
       [/remove[:g|:d]] Sid[...]] [/T] [/C] [/L] [/Q]
       [/setintegritylevel Level:policy[...]]
    /grant[:r] Sid:perm предоставляет указанному пользователю права доступа. При
 использовании :r
        эти права заменяют любые ранее предоставленные явные разрешения.
        Если :r не используется, разрешения добавляются
          к любым ранее предоставленным явным разрешениям.
        последовательность простых прав:
                F - полный доступ
                    M - доступ на изменение
                    RX - доступ на чтение и выполнение
                    R - доступ только на чтение
                    W - доступ только на запись
            в скобках список определенных прав, разделенных запятыми:
                D    - удаление
                    RC   - чтение
                    WDAC - запись DAC
                    WO   - смена владельца
                    S    - синхронизация
                    AS   - доступ к безопасности системы
                    MA   - максимально возможный
                    GR   - общее чтение
                    GW   - общая запись
                    GE   - общее выполнение
                    GA   - все общие
                    RD   - чтение данных, перечисление содержимого папки
                    WD   - запись данных, создание файлов
                    AD   - добавление данных, создание папок
                    REA  - чтение дополнительных атрибутов
                    WEA  - запись дополнительных атрибутов
                    X    - выполнение файлов и обзор папок
                    DC   - удаление вложенных объектов
                    RA   - чтение атрибутов
                    WA   - запись атрибутов
            права наследования могут предшествовать любой форме и применяются
            только к папкам:
                (OI) - наследуют объекты
                    (CI) - наследуют контейнеры
                    (IO) - только наследование
                    (NP) - не распространять наследование

И все корректно.
А который cacls.exe - так он повторяет все те глюки что есть в приведенном VB-коде
В баню такие API!
Ну а "Пользователи" так и быть через API вычислю...
...
Рейтинг: 0 / 0
Установка разрешений для папки (Vista).
    #35992727
Фотография Игорь Горбонос
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
> Автор: Дмитрий77
> В баню такие API!

Там в статье была оговорка
MSDNThe information in this article applies to:

Microsoft Visual Basic Learning, Professional, and Enterprise Editions for Windows, versions 5.0, 6.0, on platform(s):
The Microsoft Windows NT operating system
Вполне может быть, что там пересмотрели концепцию и доввели новые АПИ-функции ;)


Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
Установка разрешений для папки (Vista).
    #35992780
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Так эти оговорки во всех приличных статьях для VB6. Если API и есть (отчего ж не быть) то примеров для VB6 вряд ли уже когда-либо будет.

Или вы считаете дурным тоном использование системных утилит вместо API? Ну перепишу я себе этот кусок кода, дай бог чтоб там не было ошибок, и я не ошибся при копировании. Я все равно там почти ничего не понимаю. А здесь хоть немного знаний поднабрался, ибо разбираться в синтаксисе командных строк таких утилит равно как и в премудростях висты само по себе дело нелегкое.
Я напр. очень долго искал в google как записать вот это место:
(OI)(CI)
и до сих пор до конца не понимаю, что там чего наследует, но если я применю оба этих ключа, то все вложенные папки и файлы, а также вновь создаваемые будут также иметь "полный доступ", что худо-бедно задачу решает.
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
Установка разрешений для папки (Vista).
    #38607833
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77Или вы считаете дурным тоном использование системных утилит вместо API?

Пользовался каклсом, был 5 лет счастлив.

НО ОНИ МЕНЯ ВЫВЕЛИ ИЗ СЕБЯ!!!

Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
' ==icacls.exe "C:\Documents and Settings\All Users\Application Data\Proga" /grant Пользователи:(OI)(CI)F /T
' DoFullAccessFileFolder("C:\Documents and Settings\All Users\Application Data\Proga")
Public Function DoFullAccessFileFolder(FileFolderPath As String) As Long
  DoFullAccessFileFolder = AddAceToObjectsSecurityDescriptor(FileFolderPath, _
   SE_FILE_OBJECT, _
   ConstructUniversalAndNTWellKnownSids("Users"), _
   GENERIC_ALL, _
   GRANT_ACCESS, _
   CONTAINER_INHERIT_ACE Or OBJECT_INHERIT_ACE)
End Function

' DoFullAccessRegistryEntry("MACHINE\SOFTWARE\MyProga")
' MACHINE -для HKLM
Public Function DoFullAccessRegistryEntry(RegistryPath As String) As Long
  DoFullAccessRegistryEntry = AddAceToObjectsSecurityDescriptor(RegistryPath, _
   SE_REGISTRY_KEY, _
   ConstructUniversalAndNTWellKnownSids("Users"), _
   GENERIC_ALL, _
   GRANT_ACCESS, _
   CONTAINER_INHERIT_ACE Or OBJECT_INHERIT_ACE)
End Function

Public Function AddAceToObjectsSecurityDescriptor(pszObjName As String, _
 ObjectType As SE_OBJECT_TYPE, pszTrustee As String, _
 dwAccessRights As Long, AccessMode As ACCESS_MODE, dwInheritance As Long) As Long
 
  Dim dwRes As Long
  Dim pOldDACL As Long, pNewDACL As Long
  Dim pSD As Long
  Dim ea As EXPLICIT_ACCESS
 
  If (pszObjName = "") Then
    AddAceToObjectsSecurityDescriptor = ERROR_INVALID_PARAMETER
    Exit Function
  End If
  
  'Get a pointer to the existing DACL.
  dwRes = GetNamedSecurityInfo(pszObjName, ObjectType, _
   DACL_SECURITY_INFORMATION, _
   0&, 0&, pOldDACL, 0&, pSD)
  If dwRes <> ERROR_SUCCESS Then
    MsgBox "GetNamedSecurityInfo Error " & CStr(dwRes)
    GoTo Cleanup
  End If
  
  'Initialize an EXPLICIT_ACCESS structure for the new ACE.
  BuildExplicitAccessWithName ea, pszTrustee, dwAccessRights, AccessMode, dwInheritance
  
  ' Create a new ACL that merges the new ACE into the existing DACL.
  dwRes = SetEntriesInAcl(1, ea, pOldDACL, pNewDACL)
  If dwRes <> ERROR_SUCCESS Then
    MsgBox "SetEntriesInAcl Error " & CStr(dwRes)
    GoTo Cleanup
  End If

  'Attach the new ACL as the object's DACL.
  dwRes = SetNamedSecurityInfo(pszObjName, ObjectType, _
   DACL_SECURITY_INFORMATION, _
   0&, 0&, pNewDACL, 0&)
  If dwRes <> ERROR_SUCCESS Then
    MsgBox "SetNamedSecurityInfo Error " & CStr(dwRes)
    GoTo Cleanup
  End If

Cleanup:
  If pSD <> 0 Then LocalFree pSD
  If pNewDACL <> 0 Then LocalFree pNewDACL
  
  AddAceToObjectsSecurityDescriptor = dwRes
End Function
...
Рейтинг: 0 / 0
10 сообщений из 10, страница 1 из 1
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Установка разрешений для папки (Vista).
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]