EFS AddUsersToEncryptedFile Function (advapi32.dll)

  • Thread starter Silke Anita Mühlemann
  • Start date
S

Silke Anita Mühlemann

Hi there,
I'm trying to encrypt Files with EFS, by using functions of the advapi32
dll.
But I have problems with the function 'AddUsersToEncryptFile'.

I have the name of the file which I want to encrypt and the accountname of
the users who should added to the file as an allowed user.
Now I try with the function 'LookupAccountName' to get the SID of the user,
that works fine. But now I don't know how to get the certificate of the user
and add this in a ENCRYPTION_CERTIFICATE_LIST which I can use for the
function 'AddUsersToEncryptedFile'.

My code I have still written:

Setup:

[StructLayout(LayoutKind.Sequential)]
internal struct ENCRYPTION_CERTIFICATE_LIST
{
internal int nUsers;
internal IntPtr pUsers;
}

[DllImport("advapi32.dll", EntryPoint = "AddUsersToEncryptedFile", CharSet =
CharSet.Unicode, SetLastError = true)]
private static extern bool addUsersToEncryptedFile(string lpFilename, IntPtr
pUsers);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern bool LookupAccountName(
string lpSystemName,
string lpAccountName,
[MarshalAs(UnmanagedType.LPArray)] byte[] Sid,
ref uint cbSid,
StringBuilder ReferencedDomainName,
ref uint cchReferencedDomainName,
out SID_NAME_USE peUse);

Logic:

int counter = 0;

foreach (FileInfo file in files)
{
//certificates is a list of the users which have to be added
IntPtr[] iptArray = new IntPtr[certificates.Count];
int zaehler = 0;

foreach (CertUser u in certificates)
{
//RegName is the user accountname
string accountName = u.RegName;
byte[] Sid = null;
uint cbSid = 0;
StringBuilder referencedDomainName = new StringBuilder();
uint cchReferencedDomainName = (uint)referencedDomainName.Capacity;
SID_NAME_USE sidUse;

int err = NO_ERROR;
if (!LookupAccountName(null, accountName, Sid, ref cbSid,
referencedDomainName, ref cchReferencedDomainName, out sidUse))
{
err = Marshal.GetLastWin32Error();
if (err == ERROR_INSUFFICIENT_BUFFER || err == ERROR_INVALID_FLAGS)
{
Sid = new byte[cbSid];
referencedDomainName.EnsureCapacity((int)cchReferencedDomainName);
err = NO_ERROR;
if (!LookupAccountName(null, accountName, Sid, ref cbSid,
referencedDomainName, ref cchReferencedDomainName, out sidUse))
err = Marshal.GetLastWin32Error();
}
}

int size = Marshal.SizeOf(Sid[0]) * Sid.Length;
IntPtr iptr = Marshal.AllocHGlobal(size);
Marshal.Copy(Sid, 0, iptr, Sid.Length);
iptArray[counter] = iptr;
counter++;
}


//Here I want to create the Encryption_Certificate_List and fill it
(needless to say it doesn't work ;-) )

IntPtr pointerAufPointerArray =
Marshal.AllocHGlobal(Marshal.SizeOf(iptArray[0]));
Marshal.Copy(iptArray, 0, pointerAufPointerArray, iptArray.Length);
ENCRYPTION_CERTIFICATE_LIST ecl =
(ENCRYPTION_CERTIFICATE_LIST)Marshal.PtrToStructure(pointerAufPointerArray,
typeof(ENCRYPTION_CERTIFICATE_LIST));
IntPtr pEcl =
Marshal.AllocHGlobal(Marshal.SizeOf(typeof(ENCRYPTION_CERTIFICATE_LIST)));

Marshal.Copy(pointerAufPointerArray, bla.ToArray(), 0,
Marshal.SizeOf(typeof(ENCRYPTION_CERTIFICATE_LIST)));
addUsersToEncryptedFile(file.FullName.ToString(), pEcl);
}


Thanks in advance for your help!

Kind regards
Silke
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top