Results 1 to 8 of 8

Thread: Copymem function

  1. #1

    Thread Starter
    New Member
    Join Date
    Oct 2000
    Posts
    4
    I am trying to use the copymem function to get the ACE listing for a registry key. Once I get the pointer to the ACE, I call the Copymem routine and get a "Bad DLL Calling Convention" error message. If I remove the ByVal from the second parameter in the Copymem routine, the error goes away, but the string that should contain the trustee name is blank. Any one got any ideas?

  2. #2
    Guest
    Post your whole code and maybe we can track the error easier.

  3. #3

    Thread Starter
    New Member
    Join Date
    Oct 2000
    Posts
    4

    Posted Code

    Here is the source code. The problem is the Copymem function returns an error (Bad DLL Calling Convention)
    when called as Byval. I used Byval since the argument
    is a memory location of what I want to copy to the structure


    Public Sub form_Load()

    Dim subjey As String
    subkey = ""
    lngresult = RegOpenKeyEx(HKEY_CLASSES_ROOT, _
    subkey, _
    0&, _
    KEY_READ, _
    lngKeyHandle)
    MsgBox (lngresult)
    Dim p_typObjType As SE_OBJECT_TYPE
    'Dim p_objFilePerms As clsFilePermissions
    Dim p_atypExplicitAccess() As EXPLICIT_ACCESS
    'If m_strFilePath = Empty Then Exit Sub
    p_typObjType = SE_REGISTRY_KEY
    p_lngRtn = GetNamedSecurityInfo(pObjectName:="CLASSES_ROOT", _
    ObjectType:=p_typObjType, _
    SecurityInfo:=DACL_SECURITY_INFORMATION, _
    ppsidOwner:=0&, ppsidGroup:=0&, _
    ppDacl:=p_lngPtrDACL, ppSacl:=0&, _
    ppSecurityDescriptor:=p_lngPtrSecureDescriptor)


    p_lngRtn = GetNamedSecurityInfo(pObjectName:="CLASSES_ROOT", _
    ObjectType:=p_typObjType, _
    SecurityInfo:=DACL_SECURITY_INFORMATION, _
    ppsidOwner:=0&, _
    ppsidGroup:=0&, _
    ppDacl:=p_lngPtrDACL, _
    ppSacl:=0&, _
    ppSecurityDescriptor:=p_lngPtrSecureDescriptor)

    ' Deal with error if p_lngRtn <> ERROR_SUCCESS
    p_lngRtn = GetExplicitEntriesFromAcl( _
    pACL:=p_lngPtrDACL, _
    pcCountOfExplicitEntries:=p_lngCountExplicitEntries, _
    pListOfExplicitEntries:=p_lngListExplicitEntries)
    ' Deal with error if p_lngRtn <> ERROR_SUCCESS
    If p_lngCountExplicitEntries > 0 Then
    ReDim p_atypExplicitAccess(0 To _
    p_lngCountExplicitEntries - 1) As EXPLICIT_ACCESS
    '**************************************************
    '***** Second argument is memory location of source data to copy
    CopyMem p_atypExplicitAccess(0), _
    ByVal p_lngListExplicitEntries, _
    Len(p_atypExplicitAccess(0)) * _
    p_lngCountExplicitEntries
    '**************************************************
    p_lngCurrIdx = 0
    For p_lngLoop = 0 To p_lngCountExplicitEntries - 1
    With p_atypExplicitAccess(p_lngLoop)
    ' Also get Trustee name, abbreviated name,
    ' and the type of icon
    p_strAccessRights = m_objGeneral.AccessRights _
    (.grfAccessMode, .grfAccessPermissions)
    'Add TrusteeName:=p_strTrusteeName, _
    ' AbbreviatedName:=p_strAbbrName, _
    ' AccessPermissions:=.grfAccessPermissions, _
    ' AccessRights:=p_strAccessRights, _
    ' AccessMode:=.grfAccessMode, _
    ' TrusteeType:=.TRUSTEE.TrusteeType, _
    ' TrusteeForm:=.TRUSTEE.TrusteeForm, _
    ' Icon:=p_typIcon, _
    ' sKey:="C" & CStr(p_lngCurrIdx)
    p_lngCurrIdx = p_lngCurrIdx + 1
    End With
    Next p_lngLoop
    End If
    If p_lngPtrSecureDescriptor <> 0 Then LocalFree _
    p_lngPtrSecureDescriptor
    If p_lngPtrDACL <> 0 Then LocalFree p_lngPtrDACL
    If p_lngListExplicitEntries <> 0 Then LocalFree _
    p_lngListExplicitEntries

    End Sub


    ***********************************************
    Module Code Posted here
    ***********************************************

    Public Const HKEY_CURRENT_USER = &H80000001
    Public Const HKEY_LOCAL_MACHINE = &H80000002
    Public Const HKEY_CLASSES_ROOT = &H80000000
    Public Const STANDARD_RIGHTS_READ = &H20000
    Public Const STANDARD_RIGHTS_WRITE = &H20000
    Public Const STANDARD_RIGHTS_EXECUTE = &H20000
    Public Const STANDARD_RIGHTS_REQUIRED = &HF0000
    Public Const STANDARD_RIGHTS_ALL = &H1F0000
    Public Const KEY_QUERY_VALUE = &H1
    Public Const KEY_SET_VALUE = &H2
    Public Const KEY_CREATE_SUB_KEY = &H4
    Public Const KEY_ENUMERATE_SUB_KEYS = &H8
    Public Const KEY_NOTIFY = &H10
    Public Const KEY_CREATE_LINK = &H20
    Public Const REG_DWORD = 4
    Public Const REG_BINARY = 3
    Public Const REG_SZ = 1
    Public Const ERROR_SUCCESS = 0&
    Public Const SYNCHRONIZE = &H100000
    Dim p_typObjType As SE_OBJECT_TYPE
    Dim p_lngPtrDACL As Long
    Dim p_lngPtrSecureDescriptor As Long
    Dim p_lngRtn As Long
    Dim p_lngCounter As Long
    Dim p_lngListExplicitEntries As Long
    Dim p_atypExplicitAccess() As EXPLICIT_ACCESS
    Dim p_lngCurrIdx As Long
    Dim p_strTrusteeName As String
    Public Const DACL_SECURITY_INFORMATION As Long = &H4

    Public Declare Function RegOpenKeyEx Lib "advapi32.dll" Alias "RegOpenKeyExA" _
    (ByVal hKey As Long, _
    ByVal lpSubKey As String, _
    ByVal ulOptions As Long, _
    ByVal samDesired As Long, _
    phkResult As Long) As Long

    Public Declare Function GetNamedSecurityInfo _
    Lib "advapi32.dll" Alias "GetNamedSecurityInfoA" _
    (ByVal pObjectName As String, _
    ByVal ObjectType As SE_OBJECT_TYPE, _
    ByVal SecurityInfo As Long, _
    ppsidOwner As Long, _
    ppsidGroup As Long, _
    ppDacl As Long, _
    ppSacl As Long, _
    ppSecurityDescriptor As Long) As Long

    Public Declare Function GetExplicitEntriesFromAcl _
    Lib "advapi32.dll" Alias "GetExplicitEntriesFromAclA" _
    (ByVal pACL As Long, _
    ByRef pcCountOfExplicitEntries As Long, _
    ByRef pListOfExplicitEntries As Long) As Long

    Declare Sub CopyMem _
    Lib "kernel32" Alias "RtlMoveMemory" _
    (lpdest As Any, lpsrc As Any, ByVal length As Long)

    Public Declare Function LocalFree _
    Lib "kernel32.dll" _
    (ByVal hMem As Long) As Long

    Public Enum MULTIPLE_TRUSTEE_OPERATION
    NO_MULTIPLE_TRUSTEE
    TRUSTEE_IS_IMPERSONATE
    End Enum

    Public Enum SE_OBJECT_TYPE
    SE_UNKNOWN_OBJECT_TYPE = 0&
    SE_FILE_OBJECT = 1&
    SE_SERVICE = 2&
    SE_PRINTER = 3&
    SE_REGISTRY_KEY = 4&
    SE_LMSHARE = 5&
    SE_KERNEL_OBJECT = 6&
    SE_WINDOW_OBJECT = 7&
    End Enum

    Public Enum ACCESS_MODE
    NOT_USED_ACCESS = 0&
    GRANT_ACCESS = 1&
    SET_ACCESS = 2&
    DENY_ACCESS = 3&
    REVOKE_ACCESS = 4&
    SET_AUDIT_SUCCESS = 5&
    SET_AUDIT_FAILURE = 6&
    End Enum

    Public Enum TRUSTEE_FORM
    TRUSTEE_IS_SID = 0&
    TRUSTEE_IS_NAME = 1&
    End Enum

    Public Enum TRUSTEE_TYPE
    TRUSTEE_IS_UNKNOWN = 0&
    TRUSTEE_IS_USER = 1&
    TRUSTEE_IS_GROUP = 2&
    TRUSTEE_IS_DOMAIN = 3&
    TRUSTEE_IS_ALIAS = 4&
    TRUSTEE_IS_WELL_KNOWN_GROUP = 5&
    TRUSTEE_IS_DELETED = 6&
    TRUSTEE_IS_INVALID = 7&
    End Enum

    Public Type TRUSTEE
    pMultipleTrustee As Long
    MultipleTrusteeOperation As MULTIPLE_TRUSTEE_OPERATION
    TrusteeForm As TRUSTEE_FORM
    TrusteeType As TRUSTEE_TYPE
    ptstrName As Long
    End Type
    Public Type EXPLICIT_ACCESS
    grfAccessPermissions As Long
    grfAccessMode As ACCESS_MODE
    grfInheritance As Long
    TRUSTEE As TRUSTEE
    End Type

    Public Const KEY_READ = ((STANDARD_RIGHTS_READ Or _
    KEY_QUERY_VALUE Or _
    KEY_ENUMERATE_SUB_KEYS Or _
    KEY_NOTIFY) And _
    (Not SYNCHRONIZE))




  4. #4
    Guest
    I think you have it backwards here. ByVal means you pass the argument by value thus it does not get changed whereas ByRef (the default) passes the argument by reference (or address) and it will be changed.

    So the correct definition would be
    Code:
    Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (dest As Any, src As Any, ByVal length As Long)

  5. #5
    Hyperactive Member
    Join Date
    Jun 2000
    Location
    Auckland, NZ
    Posts
    411

    Megatron, thats the declare he already is using

    rspangl's declare:
    Code:
    Declare Sub CopyMem Lib "kernel32" Alias "RtlMoveMemory" (lpdest As Any, lpsrc As Any, ByVal length As Long)
    Megatron's declare (and the one I use too):
    Code:
    Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (dest As Any, src As Any, ByVal length As Long)

    The actual problem is in the call to CopyMem. Now I have not run this code, just read through it and I am not familiar with the API's in use. But it seems to me that:

    Code:
    CopyMem p_atypExplicitAccess(0), ByVal p_lngListExplicitEntries, Len(p_atypExplicitAccess(0)) * p_lngCountExplicitEntries
    is intended to copy array elements from a block of memory pointed at by the value contained in p_lngListExplicitEntries into the VB array starting at the memory address of p_atypExplicitAccess(0).

    This looks reasonable to me. I assume that the values of p_lngCountExplicitEntries and p_lngListExplicitEntries are being set by GetExplicitEntriesFromAcl correctly? I am not familiar with your calling convention to GetExplicitEntriesFromAcl so I assume it is the same as:

    Code:
    p_lngRtn = GetExplicitEntriesFromAcl(
    p_lngPtrDACL, p_lngCountExplicitEntries, p_lngListExplicitEntries)
    So I am left to conclude that the error is more to do with what GetExplicitEntriesFromAcl is returning. I will check the MFC for GetExplicitEntriesFromAcl and see what my interpretation of the declare should be.

    Cheers

    Paul Lewis

  6. #6
    Hyperactive Member
    Join Date
    Jun 2000
    Location
    Auckland, NZ
    Posts
    411

    GetExplicitEntriesFromAcl

    Code:
    GetExplicitEntriesFromAcl
    The GetExplicitEntriesFromAcl function retrieves an array of EXPLICIT_ACCESS structures that describe the access-control entries (ACEs) in an access-control list (ACL). 
    
    DWORD GetExplicitEntriesFromAcl(
      PACL pacl,  // pointer to the ACL from which to get entries
      PULONG pcCountOfExplicitEntries,
                  // receives number of entries in the list
      PEXPLICIT_ACCESS *pListOfExplicitEntries
                  // receives pointer to list of entries
    );
     
    Parameters
    pacl 
    Pointer to an ACL from which to get ACE information. 
    pcCountOfExplicitEntries 
    Pointer to a variable that receives the number of EXPLICIT_ACCESS structures returned in the pListOfExplicitEntries array. 
    pListOfExplicitEntries 
    Pointer to a variable that receives a pointer to an array of EXPLICIT_ACCESS structures that describe the ACEs in the ACL. If the function succeeds, you must call the LocalFree function to free the returned buffer. 
    Return Values
    If the function succeeds, the return value is ERROR_SUCCESS.
    
    If the function fails, the return value is a nonzero error code defined in WINERROR.H. 
    
    Remarks
    Each entry in the array of EXPLICIT_ACCESS structures describes access control information from an ACE for a trustee. A trustee can be a user, group, or program (such as a Win32 service). 
    
    Each EXPLICIT_ACCESS structure specifies a set of access rights and an access mode flag that indicates whether the ACE allows, denies, or audits the specified rights. 
    
    For a discretionary ACL (DACL), the access mode flag can be one of the following values from the ACCESS_MODE enumeration.
    I would write the Declare:
    Code:
    Public Declare Function GetExplicitEntriesFromAcl Lib "advapi32.dll" Alias "GetExplicitEntriesFromAclA" _
    (ByRef pACL As Long, ByRef pcCountOfExplicitEntries As Long, _
    ByRef pListOfExplicitEntries As Long)
    Based on the difference in the above declare to your existing declare, the follow-on problems would cause your error if for example pcCountOfExplicitEntries was negative.

    All this guesswork and obviously you'll need to check out the MFC for yourself to make sure you trust my judgement. If I am worng (highly likely - I'm no guru...) then let me know where I went wrong so I too can learn from my mistakes

    Cheers

    Paul Lewis

  7. #7

    Thread Starter
    New Member
    Join Date
    Oct 2000
    Posts
    4

    Working Code

    By making two changes to the declaration of the Copymem function I was able to get it to work. The old declaration of Copymem was:

    Public Declare Sub CopyMem Lib "kernel32" Alias "RtlMoveMemory" (pTo As Any, uFrom As Any, ByVal lSize As Long)

    The modified declare is:

    Declare Sub CopyMem Lib "kernel32" Alias "RtlMoveMemory" _
    (pTo As Any, ByVal uFrom As Long, ByVal lSize As Long)

    The two differences were to declare the second var as ByVal and to change the type to Long. I'm still not sure why this is working and the other isn't, but it's hard to argue with success. If anybody has any ideas as to why this one works versus the other I would love to hear it. Thanks to Paul Lewis and Megatron for the replies

  8. #8
    Hyperactive Member
    Join Date
    Jun 2000
    Location
    Auckland, NZ
    Posts
    411

    Hmm, I already explained my reasoning...

    Changing the CopyMem emulated the fix I recommended.

    Your decalre for GetExplicitEntriesFromAcl is wrong I
    believe so it's up to you if you want to take another look
    again or not.

    I already researched this to give my first reply so I'm
    sticking to it

    LIke you said though, if it works, then it's hard to
    argue. Personally, I don't like things working unless they
    are working the way they are meant to

    Cheers
    Paul Lewis

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width