-
EgorovAlex © (12.02.09 08:25) [0]Есть код на C от MicroSoft, который работает и который использует именованные каналы, я его портировал на Delphi и мой код не работает, долго пытался понять, где, но не получилось:
#define UNICODE
#include <windows.h>
#include <stdio.h>
// Types
class SEC
{ // Class to handle security attributes
public:
SEC();
~SEC();
BOOL BuildSecurityAttributes( SECURITY_ATTRIBUTES* psa );
private:
BOOL GetUserSid( PSID* ppSidUser );
BOOL allocated;
PSECURITY_DESCRIPTOR psd;
PACL pACL;
PTOKEN_USER pTokenUser;
};
/** Constructor */
SEC::
SEC()
{ allocated = FALSE;
psd = NULL;
pACL = NULL;
pTokenUser = NULL;
}
/** Destructor */
SEC::
~SEC()
{ if( allocated )
{ if( psd ) HeapFree( GetProcessHeap(), 0, psd );
if( pACL ) HeapFree( GetProcessHeap(), 0 , pACL );
if( pTokenUser ) HeapFree( GetProcessHeap(), 0, pTokenUser );
allocated = FALSE;
}
}
/** Builds security attributes that allows read-only access to everyone
Input parameters: psa: security attributes to build
Output parameters: TRUE | FALSE */
BOOL SEC::
BuildSecurityAttributes( SECURITY_ATTRIBUTES* psa )
{ DWORD dwAclSize;
PSID pSidAnonymous = NULL; // Well-known AnonymousLogin SID
PSID pSidOwner = NULL;
if( allocated ) return FALSE;
SID_IDENTIFIER_AUTHORITY siaAnonymous = SECURITY_NT_AUTHORITY;
SID_IDENTIFIER_AUTHORITY siaOwner = SECURITY_NT_AUTHORITY;
do
{ psd = (PSECURITY_DESCRIPTOR) HeapAlloc( GetProcessHeap(),
HEAP_ZERO_MEMORY,
SECURITY_DESCRIPTOR_MIN_LENGTH);
if( psd == NULL )
{ DisplayError( L"HeapAlloc" );
break;
}
if( !InitializeSecurityDescriptor( psd, SECURITY_DESCRIPTOR_REVISION) )
{ DisplayError( L"InitializeSecurityDescriptor" );
break;
}
// Build anonymous SID
AllocateAndInitializeSid( &siaAnonymous, 1,
SECURITY_ANONYMOUS_LOGON_RID,
0,0,0,0,0,0,0,
&pSidAnonymous
);
if( !GetUserSid( &pSidOwner ) )
{ return FALSE;
}
// Compute size of ACL
dwAclSize = sizeof(ACL) + 2 * ( sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) ) +
GetLengthSid( pSidAnonymous ) + GetLengthSid( pSidOwner );
pACL = (PACL)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwAclSize );
if( pACL == NULL )
{ DisplayError( L"HeapAlloc" );
break;
}
InitializeAcl( pACL, dwAclSize, ACL_REVISION);
if( !AddAccessAllowedAce( pACL,
ACL_REVISION,
GENERIC_ALL,
pSidOwner
))
{ DisplayError( L"AddAccessAllowedAce" );
break;
}
if( !AddAccessAllowedAce( pACL,
ACL_REVISION,
FILE_GENERIC_READ, //GENERIC_READ | GENERIC_WRITE,
pSidAnonymous
) )
{ DisplayError( L"AddAccessAllowedAce" );
break;
}
if( !SetSecurityDescriptorDacl( psd, TRUE, pACL, FALSE) )
{ DisplayError( L"SetSecurityDescriptorDacl" );
break;
}
psa->nLength = sizeof(SECURITY_ATTRIBUTES);
psa->bInheritHandle = TRUE;
psa->lpSecurityDescriptor = psd;
allocated = TRUE;
}while(0);
if( pSidAnonymous ) FreeSid( pSidAnonymous );
if( pSidOwner ) FreeSid( pSidOwner );
if( !allocated )
{ if( psd ) HeapFree( GetProcessHeap(), 0, psd );
if( pACL ) HeapFree( GetProcessHeap(), 0 , pACL );
}
return allocated;
}
/** Obtains the SID of the user running this thread or process.
Output parameters: ppSidUser: the SID of the current user,
TRUE | FALSE: could not obtain the user SID */
BOOL SEC::
GetUserSid( PSID* ppSidUser )
{
HANDLE hToken;
DWORD dwLength;
if( !OpenThreadToken( GetCurrentThread(), TOKEN_QUERY, TRUE, &hToken) )
{ if( GetLastError() == ERROR_NO_TOKEN )
{ if( !OpenProcessToken( GetCurrentProcess(), TOKEN_QUERY, &hToken) )
{ return FALSE;
}
}
else
{ return FALSE;
}
}
if( !GetTokenInformation( hToken, // handle of the access token
TokenUser, // type of information to retrieve
pTokenUser, // address of retrieved information
0, // size of the information buffer
&dwLength // address of required buffer size
))
{ if( GetLastError() == ERROR_INSUFFICIENT_BUFFER )
{ pTokenUser = (PTOKEN_USER) HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwLength );
if( pTokenUser == NULL )
{ return FALSE;
}
}
else
{ return FALSE;
}
}
if( !GetTokenInformation( hToken, // handle of the access token
TokenUser, // type of information to retrieve
pTokenUser, // address of retrieved information
dwLength, // size of the information buffer
&dwLength // address of required buffer size
))
{ HeapFree( GetProcessHeap(), 0, pTokenUser );
pTokenUser = NULL;
return FALSE;
}
*ppSidUser = pTokenUser->User.Sid;
return TRUE;
} -
EgorovAlex © (12.02.09 08:26) [1]Вот моя реализация этого класса:
var
SecAttr: SECURITY_ATTRIBUTES;
type
PTOKEN_USER = ^TOKEN_USER;
TOKEN_USER = record
User: SID_AND_ATTRIBUTES;
end;
var
pTokenUser: PTOKEN_USER;
procedure GetOwnerSid(var UserSid: PSID);
var
hToken: THandle;
dwLength: Cardinal;
begin
if OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, True, hToken) or
OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, hToken) then
if not GetTokenInformation(hToken, TokenUser, nil, 0, dwLength) and
(GetLastError = ERROR_INSUFFICIENT_BUFFER) then begin
GetMem(pTokenUser, dwLength);
try
if GetTokenInformation(hToken, TokenUser, pTokenUser, dwLength, dwLength) then
UserSid := pTokenUser.User.Sid;
finally
// FreeMem(pTokenUser);
end;
end;
end;
type
PACE_HEADER = ^ACE_HEADER;
ACE_HEADER = record
AceType: BYTE;
AceFlags: BYTE;
AceSize: WORD;
end;
PACCESS_ALLOWED_ACE = ^ACCESS_ALLOWED_ACE;
ACCESS_ALLOWED_ACE = record
Header: ACE_HEADER ;
Mask: ACCESS_MASK ;
SidStart: DWORD ;
end;
const
SECURITY_NT_AUTHORITY: TSIDIdentifierAuthority = (Value: (0, 0, 0, 0, 0, 5));
SECURITY_ANONYMOUS_LOGON_RID = ($00000007);
ACL_REVISION = 2;
var
pSidAnonymous, pSidOwner: PSID;
dwAclSize: Cardinal;
pPACL: PACL;
initialization
ZeroMemory(@SecAttr, SizeOf(SecAttr));
SecAttr.lpSecurityDescriptor := PSECURITY_DESCRIPTOR(HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, SECURITY_DESCRIPTOR_MIN_LENGTH));
InitializeSecurityDescriptor(SecAttr.lpSecurityDescriptor, SECURITY_DESCRIPTOR_REVISION);
pSidAnonymous := nil;
AllocateAndInitializeSid(SECURITY_NT_AUTHORITY, 1, SECURITY_ANONYMOUS_LOGON_RID, 0, 0, 0, 0, 0, 0, 0, pSidAnonymous);
pSidOwner := nil;
GetOwnerSid(pSidOwner);
dwAclSize := SizeOf(ACL) + 2*(SizeOf(ACCESS_ALLOWED_ACE) - SizeOf(DWORD)) + GetLengthSid(pSidAnonymous) + GetLengthSid(pSidOwner);
pPACL := PACL(HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwAclSize));
InitializeAcl(pPACL^, dwAclSize, ACL_REVISION);
AddAccessAllowedAce(pPACL^, ACL_REVISION, GENERIC_ALL, pSidOwner);
AddAccessAllowedAce(pPACL^, ACL_REVISION, GENERIC_ALL{GENERIC_READ or GENERIC_WRITE}, pSidAnonymous);
SetSecurityDescriptorDacl(SecAttr.lpSecurityDescriptor, True, pPACL, False);
SecAttr.bInheritHandle := True;
SecAttr.nLength := SizeOf(SECURITY_ATTRIBUTES);
FreeSid(pSidAnonymous);
finalization
LocalFree(HLOCAL(SecAttr.lpSecurityDescriptor));
end.
У меня это без классов и без проверок ошибок, но я их ставил и всё проходит без ошибок, есть ли явные ляпы в моём коде? -
clickmaker © (12.02.09 12:04) [2]попробуй packed record
-
EgorovAlex © (12.02.09 18:36) [3]Спасибо, как оказалось эта часть кода нормальная, проблема была в другом месте