More Security Functions

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This patch relies on my previous patch that implements
RtlSelfRelativeToAbsoluteSD and RtlMakeSelfRelativeSD.

Changelog:
   Ulrich Czekalla ulrich@xxxxxxxxxxxxxxx

   Add stubs for AccessCheckByType, AddAuditAccessAce,
      GetNamedSecurityInfoA, GetNamedSecurityInfoW

   Implement ConvertStringSecurityDescriptorToSecurityDescriptorW,
      DeleteAce, MakeAbsoluteSD, GetAclInformation,
      ConvertStringSidToSidW, RtlDeleteAce, RtlQueryInformationAcl

Index: dlls/advapi32/advapi32.spec
===================================================================
RCS file: /home/wine/wine/dlls/advapi32/advapi32.spec,v
retrieving revision 1.42
diff -u -w -r1.42 advapi32.spec
--- dlls/advapi32/advapi32.spec	17 Sep 2003 20:04:45 -0000	1.42
+++ dlls/advapi32/advapi32.spec	3 Nov 2003 23:17:33 -0000
@@ -3,13 +3,13 @@
 @ stdcall AccessCheck(ptr long long ptr ptr ptr ptr ptr)
 @ stdcall AccessCheckAndAuditAlarmA(str ptr str str ptr long ptr long ptr ptr ptr)
 @ stdcall AccessCheckAndAuditAlarmW(wstr ptr wstr wstr ptr long ptr long ptr ptr ptr)
-@ stub AccessCheckByType #(ptr ptr long long ptr long ptr ptr ptr ptr ptr) AccessCheckByType
+@ stdcall AccessCheckByType(ptr ptr long long ptr long ptr ptr ptr ptr ptr)
 @ stdcall AddAccessAllowedAce (ptr long long ptr)
 @ stdcall AddAccessAllowedAceEx (ptr long long long ptr)
 @ stdcall AddAccessDeniedAce(ptr long long ptr)
 @ stdcall AddAccessDeniedAceEx(ptr long long long ptr)
 @ stdcall AddAce(ptr long long ptr long)
-@ stub AddAuditAccessAce
+@ stdcall AddAuditAccessAce(ptr long long ptr long long)
 @ stub AdjustTokenGroups
 @ stdcall AdjustTokenPrivileges(long long ptr long ptr ptr)
 @ stdcall AllocateAndInitializeSid(ptr long long long long long long long long long ptr)
@@ -31,7 +31,7 @@
 @ stub ConvertSidToStringSidA #(ptr str) ConvertSidToStringSidA
 @ stub ConvertSidToStringSidW #(ptr wstr) ConvertSidToStringSidW
 @ stub ConvertStringSecurityDescriptorToSecurityDescriptorA #(str long ptr ptr) ConvertStringSecurityDescriptorToSecurityDescriptorA
-@ stub ConvertStringSecurityDescriptorToSecurityDescriptorW #(wstr long ptr ptr) ConvertStringSecurityDescriptorToSecurityDescriptorW
+@ stdcall ConvertStringSecurityDescriptorToSecurityDescriptorW(wstr long ptr ptr)
 @ stdcall CopySid(long ptr ptr)
 @ stub CreatePrivateObjectSecurity
 @ stub CreateProcessAsUserA
@@ -78,7 +78,7 @@
 @ stdcall CryptSetProvParam(long long ptr long)
 @ stdcall CryptVerifySignatureA(long ptr long long ptr long)
 @ stdcall CryptVerifySignatureW(long ptr long long ptr long) CryptVerifySignatureA
-@ stub DeleteAce
+@ stdcall DeleteAce(ptr long)
 @ stdcall DeleteService(long)
 @ stdcall DeregisterEventSource(long)
 @ stub DestroyPrivateObjectSecurity
@@ -103,8 +103,8 @@
 @ stub GetKernelObjectSecurity
 @ stdcall GetLengthSid(ptr)
 @ stub GetMangledSiteSid
-@ stub GetNamedSecurityInfoA #(str long long ptr ptr ptr ptr ptr) GetNamedSecurityInfoA
-@ stub GetNamedSecurityInfoW #(wstr long long ptr ptr ptr ptr ptr) GetNamedSecurityInfoW
+@ stdcall GetNamedSecurityInfoA (str long long ptr ptr ptr ptr ptr)
+@ stdcall GetNamedSecurityInfoW (wstr long long ptr ptr ptr ptr ptr)
 @ stdcall GetNumberOfEventLogRecords (long ptr)
 @ stdcall GetOldestEventLogRecord (long ptr)
 @ stub GetPrivateObjectSecurity
@@ -158,7 +158,7 @@
 @ stdcall LookupPrivilegeNameW(wstr ptr ptr long)
 @ stdcall LookupPrivilegeValueA(ptr ptr ptr)
 @ stdcall LookupPrivilegeValueW(ptr ptr ptr)
-@ stub MakeAbsoluteSD
+@ stdcall MakeAbsoluteSD(ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr)
 @ stdcall MakeSelfRelativeSD(ptr ptr ptr)
 @ stub MapGenericMask
 @ stdcall NotifyBootConfigStatus(long)
Index: dlls/advapi32/security.c
===================================================================
RCS file: /home/wine/wine/dlls/advapi32/security.c,v
retrieving revision 1.61
diff -u -w -r1.61 security.c
--- dlls/advapi32/security.c	1 Oct 2003 03:20:21 -0000	1.61
+++ dlls/advapi32/security.c	3 Nov 2003 23:17:34 -0000
@@ -1,5 +1,6 @@
 /*
  * Copyright 1999, 2000 Juergen Schmied <juergen.schmied@xxxxxxxxxxx>
+ * Copyright 2003 CodeWeavers Inc. (Ulrich Czekalla)
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -30,12 +31,66 @@
 #include "ntstatus.h"
 #include "ntsecapi.h"
 #include "accctrl.h"
+#include "sddl.h"
 
 #include "wine/debug.h"
 #include "wine/unicode.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(advapi);
 
+static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes);
+static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags, 
+    PACL pAcl, LPDWORD cBytes);
+static BYTE ParseAceStringFlags(LPCWSTR* StringAcl);
+static BYTE ParseAceStringType(LPCWSTR* StringAcl);
+static DWORD ParseAceStringRights(LPCWSTR* StringAcl);
+static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
+    LPCWSTR StringSecurityDescriptor,
+    PSECURITY_DESCRIPTOR SecurityDescriptor, 
+    LPDWORD cBytes);
+static DWORD ParseAclStringFlags(LPCWSTR* StringAcl);
+
+typedef struct _ACEFLAG
+{
+   LPCWSTR wstr;
+   DWORD value;
+} ACEFLAG, *LPACEFLAG;
+
+/*
+ * ACE access rights
+ */
+static const WCHAR SDDL_READ_CONTROL[]     = {'R','C',0};
+static const WCHAR SDDL_WRITE_DAC[]        = {'W','D',0};
+static const WCHAR SDDL_WRITE_OWNER[]      = {'W','O',0};
+static const WCHAR SDDL_STANDARD_DELETE[]  = {'S','D',0};
+static const WCHAR SDDL_GENERIC_ALL[]      = {'G','A',0};
+static const WCHAR SDDL_GENERIC_READ[]     = {'G','R',0};
+static const WCHAR SDDL_GENERIC_WRITE[]    = {'G','W',0};
+static const WCHAR SDDL_GENERIC_EXECUTE[]  = {'G','X',0};
+
+/*
+ * ACE types
+ */
+static const WCHAR SDDL_ACCESS_ALLOWED[]        = {'A',0};
+static const WCHAR SDDL_ACCESS_DENIED[]         = {'D',0};
+static const WCHAR SDDL_OBJECT_ACCESS_ALLOWED[] = {'O','A',0};
+static const WCHAR SDDL_OBJECT_ACCESS_DENIED[]  = {'O','D',0};
+static const WCHAR SDDL_AUDIT[]                 = {'A','U',0};
+static const WCHAR SDDL_ALARM[]                 = {'A','L',0};
+static const WCHAR SDDL_OBJECT_AUDIT[]          = {'O','U',0};
+static const WCHAR SDDL_OBJECT_ALARMp[]         = {'O','L',0};
+
+/*
+ * ACE flags
+ */
+static const WCHAR SDDL_CONTAINER_INHERIT[]  = {'C','I',0};
+static const WCHAR SDDL_OBJECT_INHERIT[]     = {'O','I',0};
+static const WCHAR SDDL_NO_PROPAGATE[]       = {'N','P',0};
+static const WCHAR SDDL_INHERIT_ONLY[]       = {'I','O',0};
+static const WCHAR SDDL_INHERITED[]          = {'I','D',0};
+static const WCHAR SDDL_AUDIT_SUCCESS[]      = {'S','A',0};
+static const WCHAR SDDL_AUDIT_FAILURE[]      = {'F','A',0};
+
 #define CallWin32ToNt(func) \
 	{ NTSTATUS ret; \
 	  ret = (func); \
@@ -503,6 +558,30 @@
 	CallWin32ToNt (RtlCreateSecurityDescriptor(pDescr, revision ));
 }
 
+
+/******************************************************************************
+ * MakeAbsoluteSD [ADVAPI32.@]
+ */
+BOOL WINAPI MakeAbsoluteSD (
+        IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
+	OUT PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
+	OUT LPDWORD lpdwAbsoluteSecurityDescriptorSize,
+	OUT PACL pDacl,
+	OUT LPDWORD lpdwDaclSize,
+	OUT PACL pSacl,
+	OUT LPDWORD lpdwSaclSize,
+	OUT PSID pOwner,
+	OUT LPDWORD lpdwOwnerSize,
+	OUT PSID pPrimaryGroup,
+	OUT LPDWORD lpdwPrimaryGroupSize)
+{
+	CallWin32ToNt (RtlSelfRelativeToAbsoluteSD(pSelfRelativeSecurityDescriptor,
+            pAbsoluteSecurityDescriptor, lpdwAbsoluteSecurityDescriptorSize,
+	    pDacl, lpdwDaclSize, pSacl, lpdwSaclSize, pOwner, lpdwOwnerSize,
+	    pPrimaryGroup, lpdwPrimaryGroupSize));
+}
+
+
 /******************************************************************************
  * GetSecurityDescriptorLength [ADVAPI32.@]
  */
@@ -719,6 +798,14 @@
 }
 
 /******************************************************************************
+ * DeleteAce [ADVAPI32.@]
+ */
+BOOL WINAPI DeleteAce(PACL pAcl, DWORD dwAceIndex)
+{
+    CallWin32ToNt(RtlDeleteAce(pAcl, dwAceIndex));
+}
+
+/******************************************************************************
  *  FindFirstFreeAce [ADVAPI32.@]
  */
 BOOL WINAPI FindFirstFreeAce(IN PACL pAcl, LPVOID * pAce)
@@ -743,9 +830,8 @@
   DWORD nAclInformationLength,
   ACL_INFORMATION_CLASS dwAclInformationClass)
 {
-	FIXME("(%p,%p,%ld,%d): stub\n",pAcl, pAclInformation,
-		nAclInformationLength, dwAclInformationClass);
-  return FALSE;
+	CallWin32ToNt(RtlQueryInformationAcl(pAcl, pAclInformation,
+		nAclInformationLength, dwAclInformationClass));
 }
 
 /******************************************************************************
@@ -1255,6 +1341,31 @@
 	  GenericMapping, PrivilegeSet, PrivilegeSetLength, GrantedAccess, (PBOOLEAN)AccessStatus));
 }
 
+
+/******************************************************************************
+ * AccessCheckByType [ADVAPI32.@]
+ */
+BOOL WINAPI AccessCheckByType(
+    PSECURITY_DESCRIPTOR pSecurityDescriptor, 
+    PSID PrincipalSelfSid,
+    HANDLE ClientToken, 
+    DWORD DesiredAccess, 
+    POBJECT_TYPE_LIST ObjectTypeList,
+    DWORD ObjectTypeListLength,
+    PGENERIC_MAPPING GenericMapping,
+    PPRIVILEGE_SET PrivilegeSet,
+    LPDWORD PrivilegeSetLength, 
+    LPDWORD GrantedAccess,
+    LPBOOL AccessStatus)
+{
+	FIXME("stub\n");
+
+	*AccessStatus = TRUE;
+
+	return !*AccessStatus;
+}
+
+
 /*************************************************************************
  * SetKernelObjectSecurity [ADVAPI32.@]
  */
@@ -1266,6 +1377,22 @@
 	CallWin32ToNt (NtSetSecurityObject (Handle, SecurityInformation, SecurityDescriptor));
 }
 
+
+/******************************************************************************
+ *  AddAuditAccessAce [ADVAPI32.@]
+ */
+BOOL WINAPI AddAuditAccessAce(
+        IN OUT PACL pAcl,
+        IN DWORD dwAceRevision,
+        IN DWORD dwAccessMask,
+        IN PSID pSid,
+        IN BOOL bAuditSuccess,
+        IN BOOL bAuditFailure)
+{
+        FIXME("Stub\n");
+        return TRUE;
+}
+
 /******************************************************************************
  * LookupAccountNameA [ADVAPI32.@]
  */
@@ -1416,5 +1543,603 @@
         PEXPLICIT_ACCESSW* pListOfExplicitEntries)
 {
     FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
+    return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/******************************************************************************
+ * ParseAclStringFlags
+ */
+static DWORD ParseAclStringFlags(LPCWSTR* StringAcl)
+{
+    DWORD flags = 0;
+    LPCWSTR szAcl = *StringAcl;
+
+    while (*szAcl != '(')
+    {
+        if (*szAcl == 'P')
+	{
+            flags |= SE_DACL_PROTECTED;
+	}
+        else if (*szAcl == 'A')
+        {
+            szAcl++;
+            if (*szAcl == 'R')
+                flags |= SE_DACL_AUTO_INHERIT_REQ;
+	    else if (*szAcl == 'I')
+                flags |= SE_DACL_AUTO_INHERITED;
+        }
+        szAcl++;
+    }
+
+    *StringAcl = szAcl;
+    return flags;
+}
+
+/******************************************************************************
+ * ParseAceStringType
+ */
+ACEFLAG AceType[] =
+{
+    { SDDL_ACCESS_ALLOWED, ACCESS_ALLOWED_ACE_TYPE },
+    { SDDL_ALARM,          SYSTEM_ALARM_ACE_TYPE },
+    { SDDL_AUDIT,          SYSTEM_AUDIT_ACE_TYPE },
+    { SDDL_ACCESS_DENIED,  ACCESS_DENIED_ACE_TYPE },
+    /*
+    { SDDL_OBJECT_ACCESS_ALLOWED, ACCESS_ALLOWED_OBJECT_ACE_TYPE },
+    { SDDL_OBJECT_ACCESS_DENIED,  ACCESS_DENIED_OBJECT_ACE_TYPE },
+    { SDDL_OBJECT_ALARM,          SYSTEM_ALARM_OBJECT_ACE_TYPE },
+    { SDDL_OBJECT_AUDIT,          SYSTEM_AUDIT_OBJECT_ACE_TYPE },
+    */
+    { NULL, 0 },
+};
+
+static BYTE ParseAceStringType(LPCWSTR* StringAcl)
+{
+    UINT len = 0;
+    LPCWSTR szAcl = *StringAcl;
+    LPACEFLAG lpaf = AceType;
+
+    while (lpaf->wstr &&
+        (len = strlenW(lpaf->wstr)) &&
+        strncmpW(lpaf->wstr, szAcl, len))
+        lpaf++;
+
+    if (!lpaf->wstr)
+        return 0;
+
+    *StringAcl += len;
+    return lpaf->value;
+}
+
+
+/******************************************************************************
+ * ParseAceStringFlags
+ */
+ACEFLAG AceFlags[] =
+{
+    { SDDL_CONTAINER_INHERIT, CONTAINER_INHERIT_ACE },
+    { SDDL_AUDIT_FAILURE,     FAILED_ACCESS_ACE_FLAG },
+    { SDDL_INHERITED,         INHERITED_ACE },
+    { SDDL_INHERIT_ONLY,      INHERIT_ONLY_ACE },
+    { SDDL_NO_PROPAGATE,      NO_PROPAGATE_INHERIT_ACE },
+    { SDDL_OBJECT_INHERIT,    OBJECT_INHERIT_ACE },
+    { SDDL_AUDIT_SUCCESS,     SUCCESSFUL_ACCESS_ACE_FLAG },
+    { NULL, 0 },
+};
+
+static BYTE ParseAceStringFlags(LPCWSTR* StringAcl)
+{
+    UINT len = 0;
+    BYTE flags = 0;
+    LPCWSTR szAcl = *StringAcl;
+
+    while (*szAcl != ';')
+    {
+        LPACEFLAG lpaf = AceFlags;
+
+        while (lpaf->wstr &&
+               (len = strlenW(lpaf->wstr)) &&
+               strncmpW(lpaf->wstr, szAcl, len))
+            lpaf++;
+
+        if (!lpaf->wstr)
+            return 0;
+
+	flags |= lpaf->value;
+        szAcl += len;
+    }
+
+    *StringAcl = szAcl;
+    return flags;
+}
+
+
+/******************************************************************************
+ * ParseAceStringRights
+ */
+ACEFLAG AceRights[] =
+{
+    { SDDL_GENERIC_ALL,     GENERIC_ALL },
+    { SDDL_GENERIC_READ,    GENERIC_READ },
+    { SDDL_GENERIC_WRITE,   GENERIC_WRITE },
+    { SDDL_GENERIC_EXECUTE, GENERIC_EXECUTE },
+    { SDDL_READ_CONTROL,    READ_CONTROL },
+    { SDDL_STANDARD_DELETE, DELETE },
+    { SDDL_WRITE_DAC,       WRITE_DAC },
+    { SDDL_WRITE_OWNER,     WRITE_OWNER },
+    { NULL, 0 },
+};
+
+static DWORD ParseAceStringRights(LPCWSTR* StringAcl)
+{
+    UINT len = 0;
+    DWORD rights = 0;
+    LPCWSTR szAcl = *StringAcl;
+
+    if ((*szAcl == '0') && (*(szAcl + 1) == 'x'))
+    {
+        LPCWSTR p = szAcl;
+
+	while (*p && *p != ';')
+            p++;
+
+	if (p - szAcl <= 8)
+	{
+	    rights = strtoulW(szAcl, NULL, 16);
+	    *StringAcl = p;
+	}
+	else
+            WARN("Invalid rights string format: %s\n", debugstr_wn(szAcl, p - szAcl));
+    }
+    else
+    {
+        while (*szAcl != ';')
+        {
+            LPACEFLAG lpaf = AceRights;
+
+            while (lpaf->wstr &&
+               (len = strlenW(lpaf->wstr)) &&
+               strncmpW(lpaf->wstr, szAcl, len))
+	    {
+               lpaf++;
+	    }
+
+            if (!lpaf->wstr)
+                return 0;
+
+	    rights |= lpaf->value;
+            szAcl += len;
+        }
+    }
+
+    *StringAcl = szAcl;
+    return rights;
+}
+
+
+/******************************************************************************
+ * ParseStringAclToAcl
+ * 
+ * dacl_flags(string_ace1)(string_ace2)... (string_acen) 
+ */
+static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags, 
+    PACL pAcl, LPDWORD cBytes)
+{
+    DWORD val;
+    DWORD sidlen;
+    DWORD length = sizeof(ACL);
+    PACCESS_ALLOWED_ACE pAce = NULL; /* pointer to current ACE */
+
+    TRACE("%s\n", debugstr_w(StringAcl));
+
+    if (!StringAcl)
+	return FALSE;
+
+    if (pAcl) /* pAce is only useful if we're setting values */
+        pAce = (PACCESS_ALLOWED_ACE) ((LPBYTE)pAcl + sizeof(PACL));
+
+    /* Parse ACL flags */
+    *lpdwFlags = ParseAclStringFlags(&StringAcl);
+
+    /* Parse ACE */
+    while (*StringAcl == '(')
+    {
+        StringAcl++;
+
+        /* Parse ACE type */
+        val = ParseAceStringType(&StringAcl);
+	if (pAce)
+            pAce->Header.AceType = (BYTE) val;
+        if (*StringAcl != ';')
+            goto lerr;
+        StringAcl++;
+
+        /* Parse ACE flags */
+	val = ParseAceStringFlags(&StringAcl);
+	if (pAce)
+            pAce->Header.AceFlags = (BYTE) val;
+        if (*StringAcl != ';')
+            goto lerr;
+        StringAcl++;
+
+        /* Parse ACE rights */
+	val = ParseAceStringRights(&StringAcl);
+	if (pAce)
+            pAce->Mask = val;
+        if (*StringAcl != ';')
+            goto lerr;
+        StringAcl++;
+
+        /* Parse ACE object guid */
+        if (*StringAcl != ';')
+        {
+            FIXME("Support for *_OBJECT_ACE_TYPE not implemented");
+            goto lerr;
+        }
+        StringAcl++;
+
+        /* Parse ACE inherit object guid */
+        if (*StringAcl != ';')
+        {
+            FIXME("Support for *_OBJECT_ACE_TYPE not implemented");
+            goto lerr;
+        }
+        StringAcl++;
+
+        /* Parse ACE account sid */
+        if (ParseStringSidToSid(StringAcl, pAce ? (PSID)&pAce->SidStart : NULL, &sidlen))
+	{
+            while (*StringAcl && *StringAcl != ')')
+                StringAcl++;
+	}
+
+        if (*StringAcl != ')')
+            goto lerr;
+        StringAcl++;
+
+	length += sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + sidlen;
+    }
+
+    *cBytes = length;
+    return TRUE;
+
+lerr:
+    WARN("Invalid ACE string format\n");
+    return FALSE;
+}
+
+
+/******************************************************************************
+ * ParseStringSecurityDescriptorToSecurityDescriptor
+ */
+static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
+    LPCWSTR StringSecurityDescriptor,
+    PSECURITY_DESCRIPTOR SecurityDescriptor,
+    LPDWORD cBytes)
+{
+    BOOL bret = FALSE;
+    WCHAR toktype;
+    WCHAR tok[MAX_PATH];
+    LPCWSTR lptoken;
+    LPBYTE lpNext = NULL;
+
+    *cBytes = 0;
+
+    if (SecurityDescriptor)
+        lpNext = ((LPBYTE) SecurityDescriptor) + sizeof(SECURITY_DESCRIPTOR);
+
+    while (*StringSecurityDescriptor)
+    {
+        toktype = *StringSecurityDescriptor;
+
+	/* Expect char identifier followed by ':' */
+	StringSecurityDescriptor++;
+        if (*StringSecurityDescriptor != ':')
+        {
+            SetLastError(ERROR_INVALID_PARAMETER);
+            goto lend;
+        }
+	StringSecurityDescriptor++;
+
+	/* Extract token */
+	lptoken = StringSecurityDescriptor;
+	while (*lptoken && *lptoken != ':')
+            lptoken++;
+
+	if (*lptoken)
+            lptoken--;
+
+	strncpyW(tok, StringSecurityDescriptor, lptoken - StringSecurityDescriptor);
+
+        switch (toktype)
+	{
+            case 'O':
+            {
+                DWORD bytes;
+
+                if (!ParseStringSidToSid(tok, (PSID)lpNext, &bytes))
+                    goto lend;
+
+                if (SecurityDescriptor)
+                {
+                    SecurityDescriptor->Owner = (PSID) ((DWORD) lpNext -
+                        (DWORD) SecurityDescriptor);
+                    lpNext += bytes; /* Advance to next token */
+                }
+
+		*cBytes += bytes;
+
+                break;
+            }
+
+            case 'G':
+            {
+                DWORD bytes;
+
+                if (!ParseStringSidToSid(tok, (PSID)lpNext, &bytes))
+                    goto lend;
+
+                if (SecurityDescriptor)
+                {
+                    SecurityDescriptor->Group = (PSID) ((DWORD) lpNext - 
+                        (DWORD) SecurityDescriptor);
+                    lpNext += bytes; /* Advance to next token */
+                }
+
+		*cBytes += bytes;
+
+                break;
+            }
+
+            case 'D':
+	    {
+                DWORD flags;
+                DWORD bytes;
+
+                if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
+                    goto lend;
+
+                if (SecurityDescriptor)
+                {
+                    SecurityDescriptor->Control |= SE_DACL_PRESENT | flags;
+                    SecurityDescriptor->Dacl = (PACL) ((DWORD) lpNext -
+                        (DWORD) SecurityDescriptor);
+                    lpNext += bytes; /* Advance to next token */
+		}
+
+		*cBytes += bytes;
+
+		break;
+            }
+
+            case 'S':
+            {
+                DWORD flags;
+                DWORD bytes;
+
+                if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
+                    goto lend;
+
+                if (SecurityDescriptor)
+                {
+                    SecurityDescriptor->Control |= SE_SACL_PRESENT | flags;
+                    SecurityDescriptor->Sacl = (PACL) ((DWORD) lpNext -
+                        (DWORD) SecurityDescriptor);
+                    lpNext += bytes; /* Advance to next token */
+		}
+
+		*cBytes += bytes;
+
+		break;
+            }
+
+            default:
+                FIXME("Unknown token\n");
+                SetLastError(ERROR_INVALID_PARAMETER);
+		goto lend;
+	}
+
+        StringSecurityDescriptor = lptoken;
+    }
+
+    bret = TRUE;
+
+lend:
+    return bret;
+}
+
+/******************************************************************************
+ * ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@]
+ */
+BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorW(
+        LPCWSTR StringSecurityDescriptor,
+        DWORD StringSDRevision,
+        PSECURITY_DESCRIPTOR* SecurityDescriptor,
+        PULONG SecurityDescriptorSize)
+{
+    DWORD cBytes;
+    PSECURITY_DESCRIPTOR psd;
+    BOOL bret = FALSE;
+
+    TRACE("%s\n", debugstr_w(StringSecurityDescriptor));
+
+    if (GetVersion() & 0x80000000)
+    {
+        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+        goto lend;
+    }
+    else if (StringSDRevision != SID_REVISION)
+    {
+        SetLastError(ERROR_UNKNOWN_REVISION);
+	goto lend;
+    }
+
+    /* Compute security descriptor length */
+    if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
+        NULL, &cBytes))
+	goto lend;
+
+    psd = *SecurityDescriptor = (PSECURITY_DESCRIPTOR) LocalAlloc(
+        GMEM_ZEROINIT, cBytes);
+
+    psd->Revision = SID_REVISION;
+    psd->Control |= SE_SELF_RELATIVE;
+
+    if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
+        psd, &cBytes))
+    {
+        LocalFree(psd);
+	goto lend;
+    }
+
+    if (SecurityDescriptorSize)
+        *SecurityDescriptorSize = cBytes;
+
+    bret = TRUE;
+ 
+lend:
+    TRACE(" ret=%d\n", bret);
+    return bret;
+}
+
+/******************************************************************************
+ * ConvertStringSidToSidW [ADVAPI32.@]
+ */
+BOOL WINAPI ConvertStringSidToSidW(LPCWSTR StringSid, PSID* Sid)
+{
+    BOOL bret = FALSE;
+    DWORD cBytes;
+
+    if (GetVersion() & 0x80000000)
+        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    else if (ParseStringSidToSid(StringSid, NULL, &cBytes))
+    {
+        PSID pSid = *Sid = (PSID) LocalAlloc(0, cBytes);
+
+        bret = ParseStringSidToSid(StringSid, pSid, &cBytes);
+        if (!bret)
+            LocalFree(*Sid); 
+    }
+
+    return bret;
+}
+
+/******************************************************************************
+ * ComputeStringSidSize
+ */
+static DWORD ComputeStringSidSize(LPCWSTR StringSid)
+{
+    int ctok = 0;
+    DWORD size = sizeof(SID);
+
+    while (*StringSid)
+    {
+        if (*StringSid == '-')
+            ctok++;
+        StringSid++;
+    }
+
+    if (ctok > 3)
+        size += (ctok - 3) * sizeof(DWORD);
+
+    return size;
+}
+
+/******************************************************************************
+ * ParseStringSidToSid
+ */
+static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes)
+{
+    BOOL bret = FALSE;
+
+    if (!StringSid)
+    {
+        SetLastError(ERROR_INVALID_PARAMETER);
+	return FALSE;
+    }
+
+    *cBytes = ComputeStringSidSize(StringSid);
+    if (!pSid) /* Simply compute the size */
+        return TRUE;
+
+    if (*StringSid != 'S' || *StringSid != '-') /* S-R-I-S-S */
+    {
+        int i = 0;
+	int csubauth = ((*cBytes - sizeof(SID)) / sizeof(DWORD)) + 1;
+
+        StringSid += 2; /* Advance to Revision */
+        pSid->Revision = atoiW(StringSid);
+
+        if (pSid->Revision != SDDL_REVISION)
+           goto lend; /* ERROR_INVALID_SID */
+
+	pSid->SubAuthorityCount = csubauth;
+
+	while (*StringSid && *StringSid != '-')
+            StringSid++; /* Advance to identifier authority */
+
+        pSid->IdentifierAuthority.Value[5] = atoiW(StringSid);
+
+	if (pSid->IdentifierAuthority.Value[5] > 5)
+            goto lend; /* ERROR_INVALID_SID */
+    
+        while (*StringSid)
+	{	
+	    while (*StringSid && *StringSid != '-')
+                StringSid++;
+
+            pSid->SubAuthority[i++] = atoiW(StringSid);
+        }
+
+	if (i != pSid->SubAuthorityCount)
+            goto lend; /* ERROR_INVALID_SID */
+
+        bret = TRUE;
+    }
+    else /* String constant format  - Only available in winxp and above */
+    {
+        pSid->Revision = SDDL_REVISION;
+	pSid->SubAuthorityCount = 1;
+
+	FIXME("String constant not supported: %s\n", debugstr_wn(StringSid, 2));
+
+	/* TODO: Lookup string of well-known SIDs in table */
+	pSid->IdentifierAuthority.Value[5] = 0;
+	pSid->SubAuthority[0] = 0;
+
+        bret = TRUE;
+    }
+
+lend:
+    if (!bret)
+        SetLastError(ERROR_INVALID_SID);
+
+    return bret;
+}
+
+/******************************************************************************
+ * GetNamedSecurityInfoA [ADVAPI32.@]
+ */
+DWORD WINAPI GetNamedSecurityInfoA(LPSTR pObjectName,
+        SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
+        PSID* ppsidOwner, PSID* ppsidGroup, PACL* ppDacl, PACL* ppSacl,
+        PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
+{
+    FIXME("%s %d %ld %p %p %p %p %p\n", pObjectName, ObjectType, SecurityInfo,
+        ppsidOwner, ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor);
+    return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+/******************************************************************************
+ * GetNamedSecurityInfoW [ADVAPI32.@]
+ */
+DWORD WINAPI GetNamedSecurityInfoW(LPWSTR pObjectName,
+        SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
+        PSID* ppsidOwner, PSID* ppsidGroup, PACL* ppDacl, PACL* ppSacl,
+        PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
+{
+    FIXME("%s %d %ld %p %p %p %p %p\n", debugstr_w(pObjectName), ObjectType, SecurityInfo,
+        ppsidOwner, ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor);
     return ERROR_CALL_NOT_IMPLEMENTED;
 }
Index: dlls/ntdll/ntdll.spec
===================================================================
RCS file: /home/wine/wine/dlls/ntdll/ntdll.spec,v
retrieving revision 1.134
diff -u -w -r1.134 ntdll.spec
--- dlls/ntdll/ntdll.spec	31 Oct 2003 00:16:20 -0000	1.134
+++ dlls/ntdll/ntdll.spec	3 Nov 2003 23:17:38 -0000
@@ -340,7 +340,7 @@
 @ stub RtlDecompressBuffer
 @ stub RtlDecompressFragment
 @ stub RtlDelete
-@ stub RtlDeleteAce
+@ stdcall RtlDeleteAce(ptr long)
 @ stdcall RtlDeleteCriticalSection(ptr)
 @ stub RtlDeleteElementGenericTable
 @ stub RtlDeleteRegistryValue
@@ -488,7 +488,7 @@
 @ stdcall RtlPrefixUnicodeString(ptr ptr long)
 @ stub RtlProtectHeap
 @ stdcall RtlQueryEnvironmentVariable_U(ptr ptr ptr)
-@ stub RtlQueryInformationAcl
+@ stdcall RtlQueryInformationAcl(ptr ptr long long)
 @ stub RtlQueryProcessBackTraceInformation
 @ stub RtlQueryProcessDebugInformation
 @ stub RtlQueryProcessHeapInformation
Index: dlls/ntdll/sec.c
===================================================================
RCS file: /home/wine/wine/dlls/ntdll/sec.c,v
retrieving revision 1.38
diff -u -w -r1.38 sec.c
--- dlls/ntdll/sec.c	5 Sep 2003 23:08:34 -0000	1.38
+++ dlls/ntdll/sec.c	3 Nov 2003 23:17:39 -0000
@@ -2,6 +2,7 @@
  *	Security functions
  *
  *	Copyright 1996-1998 Marcus Meissner
+ * 	Copyright 2003 CodeWeavers Inc. (Ulrich Czekalla)
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -707,6 +898,35 @@
 	return STATUS_SUCCESS;
 }
 
+/**************************************************************************
+ *                 RtlDeleteAce				[NTDLL.@]
+ */
+NTSTATUS  WINAPI RtlDeleteAce(PACL pAcl, DWORD dwAceIndex)
+{
+	NTSTATUS status;
+	PACE_HEADER pAce;
+
+	status = RtlGetAce(pAcl,dwAceIndex,(LPVOID*)&pAce);
+
+	if (STATUS_SUCCESS == status)
+	{
+		PACE_HEADER pcAce;
+		DWORD len = 0;
+
+		pcAce = (PACE_HEADER)(((BYTE*)pAce)+pAce->AceSize);
+		for (; dwAceIndex < pAcl->AceCount; dwAceIndex++)
+		{
+			len += pcAce->AceSize;
+			pcAce = (PACE_HEADER)(((BYTE*)pcAce) + pcAce->AceSize);
+		}
+
+		memcpy(pAce, ((BYTE*)pAce)+pAce->AceSize, len);
+                pAcl->AceCount--;
+	}
+
+	return status;
+}
+
 /******************************************************************************
  *  RtlAddAccessAllowedAce		[NTDLL.@]
  */
@@ -970,4 +1190,75 @@
 
         TRACE("%s (%u %u)\n",debugstr_w(String->Buffer),String->Length,String->MaximumLength);
         return status;
+}
+
+/******************************************************************************
+ * RtlQueryInformationAcl (NTDLL.@)
+ */
+NTSTATUS WINAPI RtlQueryInformationAcl(
+    PACL pAcl,
+    LPVOID pAclInformation,
+    DWORD nAclInformationLength,
+    ACL_INFORMATION_CLASS dwAclInformationClass)
+{
+    NTSTATUS status = STATUS_SUCCESS;
+
+    TRACE("pAcl=%p pAclInfo=%p len=%ld, class=%d\n", 
+        pAcl, pAclInformation, nAclInformationLength, dwAclInformationClass);
+
+    switch (dwAclInformationClass)
+    {
+        case AclRevisionInformation:
+        {
+            PACL_REVISION_INFORMATION paclrev = (PACL_REVISION_INFORMATION) pAclInformation;
+
+            if (nAclInformationLength < sizeof(ACL_REVISION_INFORMATION))
+                status = STATUS_INVALID_PARAMETER;
+            else
+                paclrev->AclRevision = pAcl->AclRevision;
+
+            break;
+        }
+
+        case AclSizeInformation:
+        {
+            PACL_SIZE_INFORMATION paclsize = (PACL_SIZE_INFORMATION) pAclInformation;
+
+            if (nAclInformationLength < sizeof(ACL_SIZE_INFORMATION))
+                status = STATUS_INVALID_PARAMETER;
+            else
+            {
+                INT i;
+                PACE_HEADER ace;
+
+                paclsize->AceCount = pAcl->AceCount;
+
+                paclsize->AclBytesInUse = 0;
+		ace = (PACE_HEADER) (pAcl + 1);
+
+                for (i = 0; i < pAcl->AceCount; i++)
+                {
+                    paclsize->AclBytesInUse += ace->AceSize;
+		    ace = (PACE_HEADER)(((BYTE*)ace)+ace->AceSize);
+                }
+
+		if (pAcl->AclSize < paclsize->AclBytesInUse)
+                {
+                    WARN("Acl has %d bytes free\n", pAcl->AclSize - paclsize->AclBytesInUse);
+                    paclsize->AclBytesFree = 0;
+                    paclsize->AclBytesInUse = pAcl->AclSize;
+                }
+                else
+                    paclsize->AclBytesFree = pAcl->AclSize - paclsize->AclBytesInUse;
+            }
+
+            break;
+        }
+
+        default:
+            WARN("Unknown AclInformationClass value: %d\n", dwAclInformationClass);
+            status = STATUS_INVALID_PARAMETER;
+    }
+
+    return status;
 }
Index: include/winbase.h
===================================================================
RCS file: /home/wine/wine/include/winbase.h,v
retrieving revision 1.198
diff -u -w -r1.198 winbase.h
--- include/winbase.h	31 Oct 2003 00:16:20 -0000	1.198
+++ include/winbase.h	3 Nov 2003 23:17:49 -0000
@@ -1354,6 +1354,9 @@
 BOOL        WINAPI LookupPrivilegeValueW(LPCWSTR,LPCWSTR,PLUID);
 #define     LookupPrivilegeValue WINELIB_NAME_AW(LookupPrivilegeValue)
 BOOL        WINAPI MakeSelfRelativeSD(PSECURITY_DESCRIPTOR,PSECURITY_DESCRIPTOR,LPDWORD);
+BOOL        WINAPI MakeAbsoluteSD (PSECURITY_DESCRIPTOR,PSECURITY_DESCRIPTOR,
+                   LPDWORD,PACL,LPDWORD,PACL,LPDWORD,PSID,LPDWORD,PSID,LPDWORD);
+BOOL        WINAPI DeleteAce(PACL,DWORD);
 HMODULE     WINAPI MapHModuleSL(WORD);
 WORD        WINAPI MapHModuleLS(HMODULE);
 LPVOID      WINAPI MapViewOfFile(HANDLE,DWORD,DWORD,DWORD,SIZE_T);
Index: include/winnt.h
===================================================================
RCS file: /home/wine/wine/include/winnt.h,v
retrieving revision 1.173
diff -u -w -r1.173 winnt.h
--- include/winnt.h	28 Oct 2003 21:22:50 -0000	1.173
+++ include/winnt.h	3 Nov 2003 23:17:54 -0000
@@ -2861,6 +2861,18 @@
   AclSizeInformation
 } ACL_INFORMATION_CLASS;
 
+typedef struct _ACL_REVISION_INFORMATION
+{
+    DWORD AclRevision;
+} ACL_REVISION_INFORMATION, *PACL_REVISION_INFORMATION;
+
+typedef struct _ACL_SIZE_INFORMATION
+{
+    DWORD AceCount;
+    DWORD AclBytesInUse;
+    DWORD AclBytesFree;
+} ACL_SIZE_INFORMATION, *PACL_SIZE_INFORMATION;
+
 /* SECURITY_DESCRIPTOR */
 #define	SECURITY_DESCRIPTOR_REVISION	1
 #define	SECURITY_DESCRIPTOR_REVISION1	1
@@ -3207,6 +3219,7 @@
 #define	CONTAINER_INHERIT_ACE		0x02
 #define	NO_PROPAGATE_INHERIT_ACE	0x04
 #define	INHERIT_ONLY_ACE		0x08
+#define	INHERITED_ACE		        0x10
 #define	VALID_INHERIT_FLAGS		0x0F
 
 /* AceFlags mask for what events we (should) audit */
@@ -3569,8 +3582,6 @@
   CriticalError = SERVICE_ERROR_CRITICAL
 } SERVICE_ERROR_TYPE;
 
-
-
 #define RtlEqualMemory(Destination, Source, Length) (!memcmp((Destination),(Source),(Length)))
 #define RtlMoveMemory(Destination, Source, Length) memmove((Destination),(Source),(Length))
 #define RtlCopyMemory(Destination, Source, Length) memcpy((Destination),(Source),(Length))
@@ -3578,6 +3589,12 @@
 #define RtlZeroMemory(Destination, Length) memset((Destination),0,(Length))
 
 #include <guiddef.h>
+
+typedef struct _OBJECT_TYPE_LIST {
+    WORD   Level;
+    WORD   Sbz;
+    GUID *ObjectType;
+} OBJECT_TYPE_LIST, *POBJECT_TYPE_LIST;
 
 typedef struct _RTL_CRITICAL_SECTION_DEBUG
 {
Index: include/winternl.h
===================================================================
RCS file: /home/wine/wine/include/winternl.h,v
retrieving revision 1.63
diff -u -w -r1.63 winternl.h
--- include/winternl.h	31 Oct 2003 00:16:20 -0000	1.63
+++ include/winternl.h	3 Nov 2003 23:17:55 -0000
@@ -1086,6 +1086,7 @@
 void      WINAPI RtlCopyString(STRING*,const STRING*);
 void      WINAPI RtlCopyUnicodeString(UNICODE_STRING*,const UNICODE_STRING*);
 NTSTATUS  WINAPI RtlCreateAcl(PACL,DWORD,DWORD);
+NTSTATUS  WINAPI RtlQueryInformationAcl(PACL,LPVOID,DWORD,ACL_INFORMATION_CLASS);
 NTSTATUS  WINAPI RtlCreateEnvironment(BOOLEAN, PWSTR*);
 HANDLE    WINAPI RtlCreateHeap(ULONG,PVOID,ULONG,ULONG,PVOID,PRTL_HEAP_DEFINITION);
 NTSTATUS  WINAPI RtlCreateProcessParameters(RTL_USER_PROCESS_PARAMETERS**,const UNICODE_STRING*,
@@ -1098,6 +1099,7 @@
 BOOLEAN   WINAPI RtlCreateUnicodeStringFromAsciiz(PUNICODE_STRING,LPCSTR);
 NTSTATUS  WINAPI RtlCreateUserThread(HANDLE,const SECURITY_DESCRIPTOR*,BOOLEAN,PVOID,SIZE_T,SIZE_T,PRTL_THREAD_START_ROUTINE,void*,HANDLE*,CLIENT_ID*);
 
+NTSTATUS  WINAPI RtlDeleteAce(PACL,DWORD);
 NTSTATUS  WINAPI RtlDeleteCriticalSection(RTL_CRITICAL_SECTION *);
 void      WINAPI RtlDeleteResource(LPRTL_RWLOCK);
 DWORD     WINAPI RtlDeleteSecurityObject(DWORD);
@@ -1207,6 +1209,9 @@
 BOOLEAN   WINAPI RtlLockHeap(HANDLE);
 
 NTSTATUS  WINAPI RtlMakeSelfRelativeSD(PSECURITY_DESCRIPTOR,PSECURITY_DESCRIPTOR,LPDWORD);
+NTSTATUS  WINAPI RtlSelfRelativeToAbsoluteSD (PSECURITY_DESCRIPTOR, PSECURITY_DESCRIPTOR,
+          PDWORD, PACL, PDWORD, PACL, PDWORD, PSID Owner, PDWORD, PSID, PDWORD);
+
 void      WINAPI RtlMapGenericMask(PACCESS_MASK,const GENERIC_MAPPING*);
 NTSTATUS  WINAPI RtlMultiByteToUnicodeN(LPWSTR,DWORD,LPDWORD,LPCSTR,DWORD);
 NTSTATUS  WINAPI RtlMultiByteToUnicodeSize(DWORD*,LPCSTR,UINT);
--- /dev/null	2003-01-30 05:24:37.000000000 -0500
+++ include/sddl.h	2003-11-03 14:46:06.000000000 -0500
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2000 Ulrich Czekalla for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __SDDL_H__
+#define __SDDL_H__
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * SDDL Version information
+ */
+#define SDDL_REVISION_1     1
+#define SDDL_REVISION       SDDL_REVISION_1
+
+/*
+ * SDDL Component tags
+ */
+#define SDDL_OWNER                          TEXT("O")
+#define SDDL_GROUP                          TEXT("G")
+#define SDDL_DACL                           TEXT("D")
+#define SDDL_SACL                           TEXT("S")
+
+/*
+ * SDDL Seperators - character version
+ */
+#define SDDL_SEPERATORC                     TEXT(";")
+#define SDDL_DELIMINATORC                   TEXT(":")
+#define SDDL_ACE_BEGINC                     TEXT("(")
+#define SDDL_ACE_ENDC                       TEXT(")")
+
+/*
+ * SDDL Seperators - string version
+ */
+#define SDDL_SEPERATOR                     TEXT(";")
+#define SDDL_DELIMINATOR                   TEXT(":")
+#define SDDL_ACE_BEGIN                     TEXT("(")
+#define SDDL_ACE_END                       TEXT(")")
+
+BOOL WINAPI ConvertSidToStringSidA( PSID, LPSTR* );
+BOOL WINAPI ConvertSidToStringSidW( PSID, LPWSTR* );
+#define ConvertSidToStringSid WINELIB_NAME_AW(ConvertSidToStringSid)
+
+BOOL WINAPI ConvertStringSidToSidA( LPCSTR, PSID* );
+BOOL WINAPI ConvertStringSidToSidW( LPCWSTR, PSID* );
+#define ConvertStringSidToSid WINELIB_NAME_AW(ConvertStringSidToSid)
+
+BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorA(
+    LPCSTR, DWORD, PSECURITY_DESCRIPTOR*, PULONG );
+BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorW(
+    LPCWSTR, DWORD, PSECURITY_DESCRIPTOR*, PULONG );
+#define ConvertStringSecurityDescriptorToSecurityDescriptor WINELIB_NAME_AW(ConvertStringSecurityDescriptorToSecurityDescriptor)
+
+BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorA(
+    PSECURITY_DESCRIPTOR, DWORD, SECURITY_INFORMATION, LPSTR*, PULONG );
+BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorW(
+    PSECURITY_DESCRIPTOR, DWORD, SECURITY_INFORMATION, LPWSTR*, PULONG );
+#define ConvertSecurityDescriptorToStringSecurityDescriptor WINELIB_NAME_AW(ConvertSecurityDescriptorToStringSecurityDescriptor)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* endif __SDDL_H__ */

[Index of Archives]     [Gimp for Windows]     [Red Hat]     [Samba]     [Yosemite Camping]     [Graphics Cards]     [Wine Home]

  Powered by Linux