Don't use LocalSize to get the SID length - use the GetLengthSid API as
follows:
Public Declare Function GetLengthSid Lib "advapi32.dll" _
(ByRef pSid As Long) As Long
Public Function StringSIDToBinarySID(ByVal sSID As String, _
ByRef bSID() As Byte) As Boolean
Dim rc As Long, lSIDMemAddress As Long
Dim lSIDLen As Long, bRC As Boolean
bRC = False
Debug.Print "Converting " & sSID & " to binary"
rc = ConvertStringSidToSid(StrPtr(sSID), lSIDMemAddress)
If rc <> 0 Then
lSIDLen = GetLengthSid(ByVal lSIDMemAddress)
If lSIDLen > 0 Then
ReDim bSID(0 To lSIDLen - 1)
CopyMemory bSID(0), ByVal lSIDMemAddress, lSIDLen
'bSID() contains a binary copy of SID at this point
bRC = True
End If
If LocalFree(lSIDMemAddress) <> 0 Then
Debug.Assert False
lSIDMemAddress = 0
End If
End If
StringSIDToBinarySID = bRC
Exit Function
End Function
Craig
From: Duane (slav...@athenet.net)
Subject: Re: Convert string SID to SID
Newsgroups: microsoft.public.vb.winapi
Date: 2001-04-02 22:06:03 PST
Shane,
Thanks very much for your detailed response. I tried the code in the second
part of your message. All was well until the call to CopyMemory, which
resulted in the error "bad DLL calling convention". Removing the "ByVal"
from the SID_Memory_Address allowed it to proceed, but of course, as I
expected from your explanation, it returned an empty array. Any idea about
this?
The LocalSize(SID_Memory_Address) returned 32. The array should actually
have 28 members. I assume 32 is the no. of bytes of memory?
- Duane
"Shane Krueger" <sh...@sackcorp.com> wrote in message
news:ujwiYE0uAHA.1968@tkmsftngp03...
> Duane,
>
> Although I have not tried using this particular function, I can explain
the
> MSDN documentation I read about this function to you:
>
> "Sid: [out] Pointer to a variable that receives a pointer to the converted
> SID. To free the returned buffer, call the LocalFree function. " means
that
> we should pass to the function a ByRef long variable that will be loaded
> with the address in memory of where the SID is stored. It also says that
> you will be responsible fore freeing the used memory after you're done
with
> it. So the declarations would look like this:
>
> Private Declare Function ConvertStringSidToSid Lib "Advapi32" _
> Alias "ConvertStringSidToSidA" (ByVal LPCTSTR as String, _
> ByRef hMem_PSID As Long) as Long
> Private Declare Function LocalFree Lib "kernel32" _
> Alias "LocalFree" (ByVal hMem As Long) As Long
>
> Notice the first declaration has the memory address location passed byref,
> where the LocalFree memory address is passed ByVal. A sample subroutine
> would be something like this:
>
> Sub AdjustSharePermissions(MySID$)
> Dim SID_Memory_Address As Long
>
> If ConvertStringSidToSid(MySID$, SID_MemoryAddress) = 0 Then Stop 'fails
> on zero
>
> If MyAPISetPermissions(blah, blah, blah, ByVal SID_MemoryAddress)......
>
> If LocalFree(SID_Memory_Address) <> 0 Then Stop 'fails on non-zero
> End Sub
>
> Notice that you never have a VB array containing the binary SID. If you
> needed that, you could write this instead and the code should work equally
> as well:
>
> Private Declare Sub CopyMemory Lib "kernel32" _
> Alias "RtlMoveMemory" (pTo As Any, _
> pFrom As Any, ByVal lCount As Long)
> Private Declare Function LocalSize Lib "kernel32" _
> Alias "LocalSize" (ByVal hMem As Long) As Long
> Sub AdjustSharePermissions(MySID$)
> Dim SID_Memory_Address As Long
> Dim SID_Length As Long
> Dim SID_Binary() As Byte
>
> If ConvertStringSidToSid(MySID$, SID_MemoryAddress) = 0 Then _
> Stop 'fails on zero
> SID_Length = LocalSize(SID_MemoryAddress)
> If SID_Length = 0 Then Stop 'fails on zero
> ReDim SID_Binary(0 to SID_Length - 1)
> CopyMemory SID_Binary(0), ByVal SID_MemoryAddress, _
> SID_Length 'notice first parameter is ByRef, second is ByVal
> If LocalFree(SID_Memory_Address) <> 0 Then _
> Stop 'fails on non-zero
> SID_MemoryAddress = 0
> 'SID_Binary() contains a binary copy of SID at this point
>
> If MyAPISetPermissions(blah, blah, blah, ByRef SID_Binary(0))......
> 'notice that the address pointer in these API calls should
> 'be redeclared ByRef As Byte in this instance and passed
> 'as shown above. Passing MyArray(0) passes to the API
> 'call the address of the first byte in memory in the array
>
> End Sub
>
> Let me know if you have any problems,
> -----------------
> Shane Krueger
> sh...@sackcorp.com
>
>
> "Duane" <slav...@athenet.net> wrote in message
> news:tcg3tnh...@corp.supernews.com...
> > I have very limited experience working with WinAPI.
> >
> > WMI set share permissions requires passing the SID in binary format.
> > Getting the string SID is easy. To convert to a functional SID array
MSDN
> > lists the following function:
> >
> > BOOL ConvertStringSidToSid(
> > LPCTSTR StringSid, // SID string
> > PSID *Sid // SID
> > );
> >
> > How do I properly use this function to get VB array containing the SID?
> > Or alternatively, is there some way to get SID array right away?
> >
> > My so-far nonworking function is:
> > Private Declare Function ConvertStringSidToSid Lib "Advapi32" _
> > Alias "ConvertStringSidToSidA" (ByVal LPCTSTR as String, _
> > ByRef PSID() As Integer) as Long
> >
> > -Duane
> >
> >
>
>