PROGRAM sid_main
! Fortran program to return Windows security identifier (SID)
USE advapi32
USE kernel32
IMPLICIT NONE
!
INTERFACE
 INTEGER (BOOL) FUNCTION ConvertSidToStringSid(Sid, lpSidStr) 
   USE advapi32
   !DEC$ ATTRIBUTES DEFAULT, STDCALL, DECORATE, ALIAS:'ConvertSidToStringSidA' :: ConvertSidToStringSid
   integer(PVOID), VALUE :: Sid ! LPDWORD Sid
   integer(PVOID), VALUE :: lpSidStr ! LPTSTR lpSidStr
 END FUNCTION ConvertSidToStringSid
END INTERFACE

!
CHARACTER (LEN = MAX_COMPUTERNAME_LENGTH + 1) :: ComputerName
INTEGER :: ComputerNameLen = MAX_COMPUTERNAME_LENGTH + 1 
CHARACTER (LEN = 15 + 1) :: UserName
INTEGER :: UserNameLen = 15 + 1 
CHARACTER (LEN = 256) :: ReferencedDomainName=''
INTEGER (BOOL) :: iret
INTEGER (PVOID) :: pSid
INTEGER (LPDWORD) ::  cbReferencedDomainName = 0, cbSid = 0
CHARACTER (256):: SidStr
INTEGER (PVOID) :: pSidStr
POINTER (pSidStr, SidStr)
INTEGER (ENUM) :: peUse
INTEGER :: nlen
!
iret = GetComputerName(ComputerName, LOC(ComputerNameLen)) 
PRINT *, 'ComputerName =', ComputerName(1:ComputerNameLen)
iret = LookupAccountName(NULL, ComputerName, NULL, LOC(cbSid), NULL, LOC(cbReferencedDomainName), LOC(peUse)) 
pSid = GlobalAlloc(GPTR, cbSid)
iret = LookupAccountName(NULL, ComputerName, pSid, LOC(cbSid), ReferencedDomainName(1:cbReferencedDomainName), LOC(cbReferencedDomainName), LOC(peUse))
PRINT *, 'DOMAIN =', ReferencedDomainName(1:cbReferencedDomainName)

iret = ConvertSidToStringSid(pSid, LOC(pSidStr))

nlen = INDEX(SidStr, ACHAR(0)) - 1
PRINT *, 'SID=', SidStr(1:nlen) 
iret = LocalFree(pSidStr)
iret = GlobalFree(pSid)

cbSid=0
cbReferencedDomainName=0
iret = GetUserName(UserName, LOC(UserNameLen)) 
PRINT *, 'UserName =', UserName(1:UserNameLen)
iret = LookupAccountName(NULL, UserName, NULL, LOC(cbSid), ReferencedDomainName, LOC(cbReferencedDomainName), LOC(peUse)) 
pSid = GlobalAlloc(GPTR, cbSid)
iret = LookupAccountName(NULL, UserName, pSid, LOC(cbSid), ReferencedDomainName(1:cbReferencedDomainName), LOC(cbReferencedDomainName), LOC(peUse))
PRINT *, 'DOMAIN =', ReferencedDomainName(1:cbReferencedDomainName)

iret = ConvertSidToStringSid(pSid, LOC(pSidStr))

nlen = INDEX(SidStr, ACHAR(0)) - 1
PRINT *, 'SID=', SidStr(1:nlen) 
iret = LocalFree(pSidStr)
iret = GlobalFree(pSid)
STOP
END PROGRAM sid_main