- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
I am trying to retrieve a security identifier by calling the windows API function LookupAccountName (see attached source code).
The problem is that I keep getting the following error message when calling LookupAccountName:
HEAP[SID.exe]: Invalid allocation size - 99999998 (exceeded 7ffdefff)
I have been trying all kind of variations (including using loc() an not using loc()), but cannot find a solution.
I hope someone sees where I am going wrong.
Walter Kramer
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I got as far as getting LookupAccountName to return nonzero in gfortran. What works in ifort would be a little different, but I think you want to change the first invocation of LookupAccountName to
iret = LookupAccountName(NULL, ComputerName, NULL, loc(cbSid), NULL, loc(cbReferencedDomain), loc(peUse))
Then you should change the declaration of ReferencedDomain to
character, allocatable :: ReferencedDomain(:)
And add a declaration
character, allocatable, target :: SidBuffer(:)
Now, before the next allocation, you want:
allocate(ReferencedDomain(cbReferencedDomain))
allocate(SidBuffer(cbSid))
pSid = loc(SidBuffer(1))
Then your second invocation might work.
The gfortran test code was
[fortran]
module winstuff
use ISO_C_BINDING
use ISO_C_BINDING, only: C_PTR
use ISO_C_BINDING, only: T_SID => C_PTR
implicit none
private
public T_SID
integer, parameter, public :: BOOL = C_INT
integer, parameter, public :: DWORD = C_LONG
integer, parameter, public :: MAX_COMPUTERNAME_LENGTH = 15
public GetComputerName
interface
function GetComputerName(lpBuffer, lpnSize) bind(C,name='GetComputerNameA')
import
implicit none
!gcc$ attributes stdcall :: GetComputerName
integer(BOOL) GetComputerName
character(kind=C_CHAR) lpBuffer(*)
integer(DWORD) lpnSize
end function GetComputerName
end interface
public LookupAccountName
interface
function LookupAccountName(lpSystemName,lpAccountName,Sid,cbSid, &
referencedDomainName,cchReferencedDomainName,peUse) &
bind(C,name='LookupAccountNameA')
import
implicit none
!gcc$ attributes stdcall :: LookupAccountName
integer(BOOL) LookupAccountName
character(kind=C_CHAR) lpSystemName(*)
character(kind=C_CHAR) lpAccountName(*)
type(T_SID), value :: Sid
integer(DWORD) cbSid
character(kind=C_CHAR) ReferencedDomainName(*)
integer(DWORD) cchReferencedDomainName
integer(C_INT) peUse
end function LookupAccountName
end interface
public GetLastError
interface
function GetLastError() bind(C,name='GetLastError')
import
implicit none
!gcc$ attributes stdcall :: GetLastError
integer(DWORD) GetLastError
end function GetLastError
end interface
end module winstuff
program sid_main
use ISO_C_BINDING
use winstuff
implicit none
integer(BOOL) result4
character(len=MAX_COMPUTERNAME_LENGTH+1,kind=C_CHAR) lpBuffer
integer(DWORD) lpnSize
character(kind=C_CHAR), pointer :: lpSystemName(:)
character(kind=C_CHAR), pointer :: lpAccountName(:)
integer(DWORD) cbSid
! type(T_SID) Sid
! Work around ICE etc. in gfortran
type(C_PTR) Sid
character(kind=C_CHAR), pointer :: ReferencedDomainName(:)
integer(DWORD) cchReferencedDomainName
integer(C_INT) peUse
character(kind=C_CHAR), allocatable, target :: SidBuffer(:)
character(len=:,kind=C_CHAR), allocatable ::DomainName
lpnSize = len(lpBuffer)
result4 = GetComputerName(lpBuffer,lpnSize)
write(*,'(a)') 'GetComputerName '//trim(merge('succeeded','failed ',result4 /= 0))
write(*,'(a,i0)') 'lpnSize = ',lpnSize
write(*,'(a)') 'Computer name = '//lpBuffer(1:lpnSize)
call C_F_POINTER(C_NULL_PTR,lpSystemName,[0])
call C_F_POINTER(C_NULL_PTR,lpAccountName,[0])
Sid = C_NULL_PTR
cbSid = 0
call C_F_POINTER(C_NULL_PTR,ReferencedDomainName,[0])
cchReferencedDomainName = 0
result4 = LookupAccountName(lpSystemName,lpAccountName,Sid, &
cbSid,ReferencedDomainName,cchReferencedDomainName,peUse)
write(*,'(a)') 'LookupAccountName '//trim(merge('succeeded','failed ',result4 /= 0))
write(*,'(a,i0)') 'GetLastError = ',GetLastError() ! 122 = ERROR_INSUFFICIENT_BUFFER
write(*,'(a,i0)') 'cbSid = ', cbSid
write(*,'(a,i0)') 'cchReferencedDomainName = ', cchReferencedDomainName
allocate(SidBuffer(cbSid))
Sid = C_LOC(SidBuffer(1))
allocate(ReferencedDomainName(cchReferencedDomainName))
result4 = LookupAccountName(lpSystemName,lpAccountName,Sid, &
cbSid,ReferencedDomainName,cchReferencedDomainName,peUse)
write(*,'(a)') 'LookupAccountName '//trim(merge('succeeded','failed ',result4 /= 0))
write(*,'(a,i0)') 'cbSid = ', cbSid
write(*,'(a,i0)') 'cchReferencedDomainName = ', cchReferencedDomainName
DomainName = repeat('A',cchReferencedDomainName-1)
DomainName = transfer(ReferencedDomainName(1:len(DomainName)),DomainName)
write(*,'(a)') 'ReferencedDomainName = '//DomainName
write(*,'(a,i0)') 'peUse = ', peUse ! 3 = SidTypeDomain
end program sid_main[/fortran]
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello Repeat Offender,
Thanks for your tips. Forgetting to allocate a buffer for the SID structure before the second invocation was indeed my major mistake. Passing NULL for ReferencedDomainName on the first invocation (and initializing cbReferencedDomainName) did the rest. Now everything works (including the ConvertSidtoStringSid function). I have attached the resulting code.
Regards,
Walter Kramer

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page