?
Solved

Win API in VB6 -- What is a Struct_MembersOf_PACL ?

Posted on 2009-04-17
20
Medium Priority
?
572 Views
Last Modified: 2013-12-03
The richer translations of the SetSecurityInfo declaration into VB include a Struct_MembersOf_PACL as one of the types.
'http://binaryworld.net/Main/ApiDetail.aspx?ApiId=4821
Declare Function SetSecurityInfo Lib "ADVAPI32" (ByVaL handle As Long, ByRef ObjectType As SE_OBJECT_TYPE, ByVaL SecurityInfo As Long, ByRef psidOwner As SID, ByRef psidGroup As SID, ByVaL pDacl As Struct_MembersOf_PACL, ByVaL pSacl As Struct_MembersOf_PACL) As Long
       
What is the thing?

I have the ACL structure:
'http://msdn.microsoft.com/en-us/library/aa374931(VS.85).aspx
Private Type ACL
    AclRevision As Byte
    Sbz1 As Byte
    AclSize As Integer
    AceCount As Integer
    Sbz2 As Integer
End Type

Is that what I need?  Or is a Struct_MembersOf_PACL something else?

Thanks!
0
Comment
Question by:Daniel Wilson
  • 12
  • 8
20 Comments
 
LVL 86

Expert Comment

by:jkr
ID: 24171109
That is a pointer to a DACL, see http://msdn.microsoft.com/en-us/library/aa379588(VS.85).aspx ("SetSecurityInfo Function"). However, a DACL has no "members", it is a more or less "opaque" thing. Check out http://msdn.microsoft.com/en-us/library/ms717798(VS.85).aspx ("Creating a DACL") which shows a less cumbersome way to build one using 'ConvertStringSecurityDescriptorToSecurityDescriptor()' (http://msdn.microsoft.com/en-us/library/aa376401.aspx)
0
 
LVL 32

Author Comment

by:Daniel Wilson
ID: 24171263
Right, it's a pointer.  And VB6 obfuscates pointers severely.

Would you use the translation that sees pDacl and pSacl as Long then?

Thanks!
0
 
LVL 86

Accepted Solution

by:
jkr earned 2000 total points
ID: 24171289
Yes, on Win32 that's true - you basically can store an ACL as an array of bytes and use a 'long' to point to that one.
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 32

Author Comment

by:Daniel Wilson
ID: 24171317
Looks like you're right.  I hit upon something more complex (and evidently wrong) as an attempt at solving this one:
http://www.experts-exchange.com/Programming/System/Windows__Programming/Q_24330006.html

Thanks for steering me away from one non-solution!
0
 
LVL 32

Author Comment

by:Daniel Wilson
ID: 24171482
I even get error 1336 when passing a NULL DACL ...

lErrorCheck = SetSecurityInfo(MyHandle, SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION, _
                                0, 0, 0, 0)
0
 
LVL 86

Expert Comment

by:jkr
ID: 24171794
Hmmm, what kind of object are you trying to apply the ACL to?
0
 
LVL 32

Author Comment

by:Daniel Wilson
ID: 24171885
The current process.

Simplified, it is:

MyPID = GetCurrentProcessID()
OpenProcess(ACCESS_RIGHT_READ_CONTROL Or ACCESS_RIGHT_WRITE_DAC, 0, MyPID)
GetSecurityInfo(MyHandle, SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION, 0, 0, pCurDacl, 0, pSD)
SetEntriesInAcl(1, ea, pCurDacl, pNewDacl)
SetSecurityInfo(MyHandle, SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION, 0, 0, pNewDacl, 0)
0
 
LVL 86

Expert Comment

by:jkr
ID: 24172095
First of all, try PROCESS_ALL_ACCESS as the access mask. Also, does 'SetEntriesInAcl()' succed?
0
 
LVL 32

Author Comment

by:Daniel Wilson
ID: 24172123
Yes, SetEntriesInAcl returns 0 ... which I understand to mean Success.

like I have below?  Currently I'm using PROCESS_QUERY_INFORMATION

Dim ea As EXPLICIT_ACCESS
1090        With ea
1100            .grfAccessPermissions = PROCESS_ALL_ACCESS
1110            .grfAccessMode = GRANT_ACCESS
1120            .grfInheritance = NO_INHERITANCE
1130            .TRUSTEE.TrusteeForm = TRUSTEE_IS_NAME
1140            .TRUSTEE.TrusteeType = TRUSTEE_IS_GROUP
'1150            .TRUSTEE.ptstrName = "CURRENT_USER" & vbNullChar 'Perhaps this should actually have the current Windows user name ... not sure
1150            .TRUSTEE.ptstrName = "EVERYONE" '& vbNullChar
1160        End With

Open in new window

0
 
LVL 32

Author Comment

by:Daniel Wilson
ID: 24172179
http://msdn.microsoft.com/en-us/library/ms684880.aspx doesn't say what the constant PROCESS_ALL_ACCESS equals.  I'm going to assume it equals &HFFFF.
0
 
LVL 86

Expert Comment

by:jkr
ID: 24172219
Hm, I've never set en EXPLICITACCESS struct manually (or seen that) - have you tried doing that with 'BuildExplicitAccessWithName()' (http://msdn.microsoft.com/en-us/library/aa376378(VS.85).aspx)? See also http://support.microsoft.com/kb/295004 ("How to use high-level access control APIs from Visual Basic")
0
 
LVL 32

Author Comment

by:Daniel Wilson
ID: 24172326
Nice idea ... same error 1336 ERROR_INVALID_ACL

Code now looks like:

(I'm using &HFFFF as PROCESS_ALL_ACCESS.)

further ideas?


MyPID = GetCurrentProcessID()
OpenProcess(ACCESS_RIGHT_READ_CONTROL Or ACCESS_RIGHT_WRITE_DAC, 0, MyPID)
Call BuildExplicitAccessWithName(ea, "EVERYONE", ACCESS_RIGHT_PROCESS_ALL_ACCESS, GRANT_ACCESS, 0)
GetSecurityInfo(MyHandle, SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION, 0, 0, pCurDacl, 0, pSD)
SetEntriesInAcl(1, ea, pCurDacl, pNewDacl)
SetSecurityInfo(MyHandle, SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION, 0, 0, pNewDacl, 0)

Open in new window

0
 
LVL 86

Expert Comment

by:jkr
ID: 24172354
Aaah, just spotted a subtle difference - 'SetEntriesInAcl()' is declared as follows:

DWORD SetEntriesInAcl(
  ULONG cCountOfExplicitEntries,
                 // number of entries in the list
  PEXPLICIT_ACCESS pListOfExplicitEntries,
                 // pointer to list of entries with new access data
  PACL OldAcl,   // pointer to the original ACL
  PACL *NewAcl   // receives a pointer to the new ACL
);

with the last argument being 'PACL *NewAcl' - which is a pointer to a pointer (or the address of a pointer). Dunno VB, so let me just ask a stupid question: Are you taking this into account?
0
 
LVL 32

Author Comment

by:Daniel Wilson
ID: 24172400
That's probably the worst thing about VB -- the obfuscation of pointers.

Let me try VarPtr(pNewDacl).  I think that would be the right answer there.

The other thing in that declaration that has me worried is the 2nd argument.  I have an Explicit_Access, not a list of them.
0
 
LVL 86

Expert Comment

by:jkr
ID: 24172421
The address of one element will do - if the 1st arg is '1'.
0
 
LVL 32

Author Comment

by:Daniel Wilson
ID: 24172447
VarPtr(pNewDacl) is wrong.  It results in pNewDacl remaining = 0.

The truth is, just passing a Long (which is a pointer to something)  by reference (that is, using a pointer to it) is giving us the double indirection.


Private Declare Function SetEntriesInAcl Lib "Advapi32.dll" Alias "SetEntriesInAclA" (ByVal cCountOfExplicitEntries As Long, pListOfExplicitEntries As EXPLICIT_ACCESS, ByVal OldAcl As Long, ByRef NewAcl As Long) As Long

I'm still not sure about PEXPLICIT_ACCESS.

I'm attaching a watch list from the last run without the VarPtr() ...

SetSecurityInfo-WatchList.gif
0
 
LVL 32

Author Comment

by:Daniel Wilson
ID: 24172455
>>The address of one element will do - if the 1st arg is '1'.

OK, that's cool.  Then we're fine as that's also a ByRef parameter.
(In VB6 parameters are ByRef unless specified ByVal.  MS switched this in .Net.)
0
 
LVL 86

Expert Comment

by:jkr
ID: 24172496
Have you checked http://support.microsoft.com/kb/295004 ("How to use high-level access control APIs from Visual Basic") from above - it comes with sample code.
0
 
LVL 32

Author Comment

by:Daniel Wilson
ID: 24172694
Their example works.  They are using GetNamedSecurityInfo and SetNamedSecurityInfo.

I'll try tweaking  their code until it does what I want.  

Thanks for the help so far!  

What we're actually working on now is this question that's been out there for a day.
http://www.experts-exchange.com/Programming/System/Windows__Programming/Q_24330006.html

So if we get a solution, please post it there as you will have earned the points!
0
 
LVL 32

Author Comment

by:Daniel Wilson
ID: 24172730
I can't use GetNamedSecurityInfo and SetNamedSecurityInfo.
http://msdn.microsoft.com/en-us/library/aa379593(VS.85).aspx
"The  GetSecurityInfo and  SetSecurityInfo functions support all types of kernel objects. The  GetNamedSecurityInfo and  SetNamedSecurityInfo functions work only with the following kernel objects: semaphore, event, mutex, waitable timer, and file mapping."

I'll have to pick this up again when my mind is fresher.

Again, thanks for the help!
0

Featured Post

Visualize your virtual and backup environments

Create well-organized and polished visualizations of your virtual and backup environments when planning VMware vSphere, Microsoft Hyper-V or Veeam deployments. It helps you to gain better visibility and valuable business insights.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Enums (shorthand for ‘enumerations’) are not often used by programmers but they can be quite valuable when they are.  What are they? An Enum is just a type of variable like a string or an Integer, but in this case one that you create that contains…
I was working on a PowerPoint add-in the other day and a client asked me "can you implement a feature which processes a chart when it's pasted into a slide from another deck?". It got me wondering how to hook into built-in ribbon events in Office.
Get people started with the process of using Access VBA to control Outlook using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Microsoft Outlook. Using automation, an Access applic…
Show developers how to use a criteria form to limit the data that appears on an Access report. It is a common requirement that users can specify the criteria for a report at runtime. The easiest way to accomplish this is using a criteria form that a…

850 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question