//---------------------------------------------------------------------------

#include <vcl.h>
//#include <aclapi.h>
#pragma hdrstop

#include "Unit1.h"
#include "Unit2.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"

TForm1 *Form1;

TCHAR fileName[MAX_PATH];
PSECURITY_DESCRIPTOR pSD=0;
DWORD nLength;
TCHAR *ownerName=0;
TCHAR *groupName=0;
TCHAR *aceSubjectName=0;
BOOL ownerAclDefaulted,groupAclDefaulted,daclDefaulted,daclPresent;
DWORD dAcl[1024],ok;
PACL pAcl=(PACL)&dAcl;
ACL_SIZE_INFORMATION pAclInfo;
PACCESS_ALLOWED_ACE pAce;
PSID pOwnerSid,pGroupSid;

bool GetNameFromSid(PSID pSid,TCHAR **buffer)
{
        if(*buffer) delete [] *buffer;
        DWORD bufferLength=0;
        TCHAR *domainName;
        DWORD domainNameLength=0;
        SID_NAME_USE peUse;
        bool ok;

        LookupAccountSid(NULL,pSid,NULL,&bufferLength,NULL,&domainNameLength,&peUse);
        *buffer = new TCHAR[bufferLength];
        domainName = new TCHAR[domainNameLength];
        ok=LookupAccountSid(NULL,pSid,*buffer,&bufferLength,domainName,&domainNameLength,&peUse);
        delete [] domainName;

        return ok;
}

bool GetSidFromName(PSID *pSid,TCHAR *accountName)
{
        if(*pSid) delete [] *pSid;
        DWORD sidLength=0;
        TCHAR *domainName;
        DWORD domainNameLength=0;
        SID_NAME_USE peUse;

        LookupAccountName(NULL,accountName,NULL,&sidLength,NULL,&domainNameLength,&peUse);
        *pSid = new TCHAR[sidLength];
        domainName = new TCHAR[domainNameLength];
        LookupAccountName(NULL,accountName,*pSid,&sidLength,domainName,&domainNameLength,&peUse);
        delete [] domainName;

        return IsValidSid(*pSid);
}

//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------


void __fastcall TForm1::Button1Click(TObject *Sender)
{
        strcpy(fileName,Edit1->Text.c_str());
        Output->Lines->Add("");
        Output->Lines->Add("File: "+(AnsiString)fileName);
        if(FileExists(fileName)){
        Form1->Button3->Enabled=true;
        Form1->Button4->Enabled=true;

        GetFileSecurity(fileName,
                OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION,
                NULL,
                0,
                &nLength);

        if(pSD)delete pSD;
        pSD = new PSECURITY_DESCRIPTOR[nLength];

        GetFileSecurity(fileName,
                OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION,
                pSD,
                nLength,
                &nLength);

        if(CheckBox1->Checked) if(IsValidSecurityDescriptor(pSD)) Output->Lines->Add("//Security Descriptor valid");
        else Output->Lines->Add("//Security Descriptor invalid, error: "+IntToStr(GetLastError()));

        GetSecurityDescriptorOwner(pSD,&pOwnerSid,&ownerAclDefaulted);
        GetSecurityDescriptorGroup(pSD,&pGroupSid,&groupAclDefaulted);

        if(CheckBox1->Checked) if(IsValidSid(pOwnerSid)) Output->Lines->Add("//ownerSid valid");
        else Output->Lines->Add("//ownerSidr invalid, error: "+IntToStr(GetLastError()));

        if(CheckBox1->Checked) if(IsValidSid(pGroupSid)) Output->Lines->Add("//groupSid valid");
        else Output->Lines->Add("//groupSid invalid, error: "+IntToStr(GetLastError()));

        GetNameFromSid(pOwnerSid,&ownerName);
        GetNameFromSid(pGroupSid,&groupName);

        Output->Lines->Add("Owner: "+(AnsiString)ownerName+", Group: "+(AnsiString)groupName);

        GetSecurityDescriptorDacl(pSD,&daclPresent,&pAcl,&daclDefaulted);

        if(CheckBox1->Checked) if(IsValidAcl(pAcl)) Output->Lines->Add("//acl valid");
        else Output->Lines->Add("//acl invalid, error: "+IntToStr(GetLastError()));

        GetAclInformation(pAcl,&pAclInfo,sizeof(ACL_SIZE_INFORMATION),AclSizeInformation);

        Output->Lines->Add("List of access entries:");
        Edit2->Text=(IntToStr(pAclInfo.AceCount));

        for(int i=0;i<pAclInfo.AceCount;i++)
        {
                GetAce(pAcl,i,(LPVOID *)(&pAce));
                GetNameFromSid(&(pAce->SidStart),&aceSubjectName);
                Output->Lines->Add(IntToStr(i+1)+": User: "+(AnsiString)aceSubjectName);
                Output->Lines->Add("Mask: "+IntToHex((int)pAce->Mask,8));
                if(pAce->Header.AceType==ACCESS_DENIED_ACE_TYPE)
                Output->Lines->Add("  Deny: ");
                if(pAce->Header.AceType==ACCESS_ALLOWED_ACE_TYPE)
                Output->Lines->Add("  Allow: ");

                if(     pAce->Mask&FILE_EXECUTE) Output->Lines->Add("    Execute");
                if(     pAce->Mask&FILE_READ_DATA) Output->Lines->Add("    Read data");
                if(     pAce->Mask&FILE_READ_ATTRIBUTES) Output->Lines->Add("    Read attributes");
                if(     pAce->Mask&FILE_READ_EA) Output->Lines->Add("    Read extended attributes");
                if(     pAce->Mask&FILE_WRITE_DATA) Output->Lines->Add("    Write data");
                if(     pAce->Mask&FILE_APPEND_DATA) Output->Lines->Add("    Append data");
                if(     pAce->Mask&FILE_WRITE_ATTRIBUTES) Output->Lines->Add("    Write attributes");
                if(     pAce->Mask&FILE_WRITE_EA) Output->Lines->Add("    Write extended attributes");
                if(     pAce->Mask&DELETE) Output->Lines->Add("    Delete");
                if(     pAce->Mask&READ_CONTROL) Output->Lines->Add("    Read permisions");
                if(     pAce->Mask&WRITE_DAC) Output->Lines->Add("    Change permisions");
                if(     pAce->Mask&WRITE_OWNER) Output->Lines->Add("    Take ownership");
        }
        }//if file exists
        else MessageBox(this->Handle,"File not found","Error",MB_OK|MB_ICONERROR);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
if(ownerName) delete [] ownerName;
if(groupName) delete [] groupName;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
        Output->Lines->Clear();
}
//---------------------------------------------------------------------------



void __fastcall TForm1::Button3Click(TObject *Sender)
{
        Form2->Visible=true;
        Form2->CheckBox1Click(NULL);
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button4Click(TObject *Sender)
{
        if(!DeleteAce(pAcl,StrToInt(Edit2->Text)-1)) MessageBox(this->Handle,"Could not delete teh ACE","Error",MB_OK|MB_ICONERROR);
        else
        {
                ok=SetFileSecurity(fileName,DACL_SECURITY_INFORMATION,pSD);
                        if(!ok)
                        MessageBox(this->Handle,"Could not write to Security Descriptor","Error",MB_OK|MB_ICONERROR);

                else
                {
                        Output->Lines->Add("Ace deleted.");
                        Edit2->Text=IntToStr(StrToInt(Edit2->Text)-1);
                }
        }
}
//---------------------------------------------------------------------------

