[ros-diffs] [hpoussin] 24490: Replace incomplete and broken implementations of ConvertStringSecurityDescriptorToSecurityDescriptorW and ConvertStringSidToSidW by new ones

hpoussin at svn.reactos.org hpoussin at svn.reactos.org
Thu Oct 12 00:14:05 CEST 2006


Author: hpoussin
Date: Thu Oct 12 02:14:05 2006
New Revision: 24490

URL: http://svn.reactos.org/svn/reactos?rev=24490&view=rev
Log:
Replace incomplete and broken implementations of ConvertStringSecurityDescriptorToSecurityDescriptorW and ConvertStringSidToSidW by new ones

Modified:
    trunk/reactos/dll/win32/advapi32/advapi32.rbuild
    trunk/reactos/dll/win32/advapi32/sec/ac.c
    trunk/reactos/dll/win32/advapi32/sec/misc.c
    trunk/reactos/dll/win32/advapi32/sec/sid.c

Modified: trunk/reactos/dll/win32/advapi32/advapi32.rbuild
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/advapi32/advapi32.rbuild?rev=24490&r1=24489&r2=24490&view=diff
==============================================================================
--- trunk/reactos/dll/win32/advapi32/advapi32.rbuild (original)
+++ trunk/reactos/dll/win32/advapi32/advapi32.rbuild Thu Oct 12 02:14:05 2006
@@ -7,6 +7,8 @@
 	<define name="WINVER">0x600</define>
 	<define name="_WIN32_IE">0x0500</define>
 	<define name="_WIN32_WINNT">0x0600</define>
+	<define name="UNICODE"></define>
+	<define name="_UNICODE"></define>
 	<library>scm_client</library>
 	<library>lsa_client</library>
 	<library>ntdll</library>

Modified: trunk/reactos/dll/win32/advapi32/sec/ac.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/advapi32/sec/ac.c?rev=24490&r1=24489&r2=24490&view=diff
==============================================================================
--- trunk/reactos/dll/win32/advapi32/sec/ac.c (original)
+++ trunk/reactos/dll/win32/advapi32/sec/ac.c Thu Oct 12 02:14:05 2006
@@ -536,7 +536,7 @@
 	PACL			pAcl,
 	PFN_OBJECT_MGR_FUNCTS	pfnArray  OPTIONAL,
 	PGENERIC_MAPPING	pGenericMapping,
-	PINHERITED_FROM		pInheritArray
+	PINHERITED_FROMA		pInheritArray
 	)
 {
     /* That's all this function does, at least up to w2k3... Even MS was too
@@ -609,14 +609,14 @@
 
     //ASSERT(sizeof(TRUSTEE_W) == sizeof(TRUSTEE_A));
 
-    TrusteeForm = GetTrusteeForm(pTrusteeA);
+    TrusteeForm = GetTrusteeFormA(pTrusteeA);
     switch (TrusteeForm)
     {
         case TRUSTEE_IS_NAME:
         {
             /* directly copy the array, this works as the size of the EXPLICIT_ACCESS_A
                structure matches the size of the EXPLICIT_ACCESS_W version */
-            lpStr = GetTrusteeName(pTrusteeA);
+            lpStr = GetTrusteeNameA(pTrusteeA);
             if (lpStr != NULL)
                 BufferSize = strlen(lpStr) + 1;
 
@@ -800,7 +800,7 @@
         Size = cCountOfExplicitEntries * sizeof(EXPLICIT_ACCESS_W);
         for (i = 0; i != cCountOfExplicitEntries; i++)
         {
-            TrusteeForm = GetTrusteeForm(&pListOfExplicitEntriesA[i].Trustee);
+            TrusteeForm = GetTrusteeFormA(&pListOfExplicitEntriesA[i].Trustee);
 
             switch (TrusteeForm)
             {
@@ -852,7 +852,7 @@
                 peaw[i].grfInheritance = pListOfExplicitEntriesA[i].grfInheritance;
 
                 /* convert or copy the TRUSTEE structure */
-                TrusteeForm = GetTrusteeForm(&pListOfExplicitEntriesA[i].Trustee);
+                TrusteeForm = GetTrusteeFormA(&pListOfExplicitEntriesA[i].Trustee);
                 switch (TrusteeForm)
                 {
                     case TRUSTEE_IS_NAME:

Modified: trunk/reactos/dll/win32/advapi32/sec/misc.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/advapi32/sec/misc.c?rev=24490&r1=24489&r2=24490&view=diff
==============================================================================
--- trunk/reactos/dll/win32/advapi32/sec/misc.c (original)
+++ trunk/reactos/dll/win32/advapi32/sec/misc.c Thu Oct 12 02:14:05 2006
@@ -916,7 +916,7 @@
 			{
 				*pdwAccountName = dwSrcLen;
 				RtlCopyMemory ( pAccountName, TranslatedName->Name.Buffer, TranslatedName->Name.Length );
-                                pAccountName[TranslatedName->Name.Length / sizeof(WCHAR)] = L'\0';
+				                pAccountName[TranslatedName->Name.Length / sizeof(WCHAR)] = L'\0';
 			}
 			if ( peUse )
 				*peUse = TranslatedName->Use;
@@ -936,7 +936,7 @@
 				{
 					*pdwDomainName = dwSrcLen;
 					RtlCopyMemory ( pDomainName, ReferencedDomain->Domains[0].Name.Buffer, ReferencedDomain->Domains[0].Name.Length );
-                                        pDomainName[ReferencedDomain->Domains[0].Name.Length / sizeof(WCHAR)] = L'\0';
+					                pDomainName[ReferencedDomain->Domains[0].Name.Length / sizeof(WCHAR)] = L'\0';
 				}
 			}
 		}
@@ -1960,7 +1960,7 @@
                                 NULL,
                                 NULL);
 
-            pifnProgressData->fnProgress(pObjectNameA,
+            pifnProgressData->fnProgress((LPWSTR)pObjectNameA, /* FIXME: wrong cast!! */
                                          Status,
                                          pInvokeSetting,
                                          pifnProgressData->Args,

Modified: trunk/reactos/dll/win32/advapi32/sec/sid.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/advapi32/sec/sid.c?rev=24490&r1=24489&r2=24490&view=diff
==============================================================================
--- trunk/reactos/dll/win32/advapi32/sec/sid.c (original)
+++ trunk/reactos/dll/win32/advapi32/sec/sid.c Thu Oct 12 02:14:05 2006
@@ -1,9 +1,9 @@
-/* $Id$
- *
+/*
  * COPYRIGHT:       See COPYING in the top level directory
  * WINE COPYRIGHT:
  * Copyright 1999, 2000 Juergen Schmied <juergen.schmied at debitel.net>
  * Copyright 2003 CodeWeavers Inc. (Ulrich Czekalla)
+ * Copyright 2006 Hervé Poussineau
  *
  * PROJECT:         ReactOS system libraries
  * FILE:            lib/advapi32/sec/sid.c
@@ -11,25 +11,20 @@
  */
 
 #include <advapi32.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 DWORD ParseAclStringFlags(LPCWSTR* StringAcl);
-
-typedef struct _ACEFLAG
-{
-   LPCWSTR wstr;
-   DWORD value;
-} ACEFLAG, *LPACEFLAG;
+#define MAX_GUID_STRING_LEN 39
+
+typedef struct RECORD
+{
+	LPCWSTR key;
+	DWORD value;
+} RECORD;
+
 
 typedef struct _MAX_SID
 {
@@ -91,18 +86,6 @@
 static const SID sidWorld = { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY} , { SECURITY_WORLD_RID } };
 
 /*
- * 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};
@@ -113,6 +96,19 @@
 static const WCHAR SDDL_ALARM[]                 = {'A','L',0};
 static const WCHAR SDDL_OBJECT_AUDIT[]          = {'O','U',0};
 static const WCHAR SDDL_OBJECT_ALARM[]          = {'O','L',0};
+
+/*
+ * SDDL ADS Rights
+ */
+#define ADS_RIGHT_DS_CREATE_CHILD   0x0001
+#define ADS_RIGHT_DS_DELETE_CHILD   0x0002
+#define ADS_RIGHT_ACTRL_DS_LIST     0x0004
+#define ADS_RIGHT_DS_SELF           0x0008
+#define ADS_RIGHT_DS_READ_PROP      0x0010
+#define ADS_RIGHT_DS_WRITE_PROP     0x0020
+#define ADS_RIGHT_DS_DELETE_TREE    0x0040
+#define ADS_RIGHT_DS_LIST_OBJECT    0x0080
+#define ADS_RIGHT_DS_CONTROL_ACCESS 0x0100
 
 /*
  * ACE flags
@@ -184,532 +180,343 @@
     return !status;
 }
 
-#define	WINE_SIZE_OF_WORLD_ACCESS_ACL	(sizeof(ACL) + FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + sizeof(sidWorld))
-
-
-/* some helper functions - taken from winehq cvs 20050916 */
-/******************************************************************************
- * 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;
-}
-
-/******************************************************************************
- * ParseAceStringType
- */
-static const 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 BOOL
+FindKeyInTable(
+	IN const RECORD* Table,
+	IN LPCWSTR Key,
+	OUT SIZE_T* pKeyLength,
+	OUT DWORD* pItem)
+{
+	const RECORD* pRecord = Table;
+	while (pRecord->key != NULL)
+	{
+		if (wcsncmp(pRecord->key, Key, wcslen(pRecord->key)) == 0)
+		{
+			*pKeyLength = wcslen(pRecord->key);
+			*pItem = pRecord->value;
+			return TRUE;
+		}
+		pRecord++;
+	}
+	SetLastError(ERROR_INVALID_PARAMETER);
+	return FALSE;
+}
+
+static BOOL
+ParseSidString(
+	IN LPCWSTR Buffer,
+	OUT PSID* pSid,
+	OUT SIZE_T* pLength)
+{
+	WCHAR str[SDDL_ALIAS_SIZE + 1];
+	LPWSTR strSid;
+	LPCWSTR end;
+	BOOL ret;
+	DWORD i;
+
+	wcsncpy(str, Buffer, SDDL_ALIAS_SIZE);
+	for (i = SDDL_ALIAS_SIZE; i > 0; i--)
+	{
+		str[i] = UNICODE_NULL;
+		if (ConvertStringSidToSidW(str, pSid))
+		{
+			*pLength = i;
+			return TRUE;
+		}
+	}
+
+	end = wcschr(Buffer, SDDL_ACE_ENDC);
+	if (!end)
+	{
+		SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+		return FALSE;
+	}
+	strSid = (LPWSTR)LocalAlloc(0, (end - Buffer) * sizeof(WCHAR) + sizeof(UNICODE_NULL));
+	if (!strSid)
+	{
+		SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+		return FALSE;
+	}
+	wcsncpy(strSid, Buffer, end - Buffer + 1);
+	strSid[end - Buffer] = UNICODE_NULL;
+	*pLength = end - Buffer;
+	ret = ConvertStringSidToSidW(strSid, pSid);
+	LocalFree(strSid);
+	return ret;
+}
+
+static const RECORD DaclFlagTable[] =
+{
+	{ SDDL_PROTECTED, SE_DACL_PROTECTED },
+	{ SDDL_AUTO_INHERIT_REQ, SE_DACL_AUTO_INHERIT_REQ },
+	{ SDDL_AUTO_INHERITED, SE_DACL_AUTO_INHERITED },
+	{ NULL, 0 },
 };
 
-static BYTE ParseAceStringType(LPCWSTR* StringAcl)
-{
-    UINT len = 0;
-    LPCWSTR szAcl = *StringAcl;
-    const ACEFLAG *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
- */
-static const 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 const RECORD SaclFlagTable[] =
+{
+	{ SDDL_PROTECTED, SE_SACL_PROTECTED },
+	{ SDDL_AUTO_INHERIT_REQ, SE_SACL_AUTO_INHERIT_REQ },
+	{ SDDL_AUTO_INHERITED, SE_SACL_AUTO_INHERITED },
+	{ NULL, 0 },
 };
 
-static BYTE ParseAceStringFlags(LPCWSTR* StringAcl)
-{
-    UINT len = 0;
-    BYTE flags = 0;
-    LPCWSTR szAcl = *StringAcl;
-
-    while (*szAcl != ';')
-    {
-        const ACEFLAG *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
- */
-static const 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 const RECORD AceFlagTable[] =
+{
+	{ SDDL_CONTAINER_INHERIT, CONTAINER_INHERIT_ACE },
+	{ SDDL_OBJECT_INHERIT, OBJECT_INHERIT_ACE },
+	{ SDDL_NO_PROPAGATE, NO_PROPAGATE_INHERIT_ACE },
+	{ SDDL_INHERIT_ONLY, INHERIT_ONLY_ACE },
+	{ SDDL_INHERITED, INHERITED_ACE },
+	{ SDDL_AUDIT_SUCCESS, SUCCESSFUL_ACCESS_ACE_FLAG },
+	{ SDDL_AUDIT_FAILURE, FAILED_ACCESS_ACE_FLAG },
+	{ 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 != ';')
-        {
-            const ACEFLAG *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\n");
-            goto lerr;
-        }
-        StringAcl++;
-
-        /* Parse ACE inherit object guid */
-        if (*StringAcl != ';')
-        {
-            FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
-            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 += FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + sidlen;
-    }
-
-    *cBytes = length;
-    return TRUE;
-
-lerr:
-    WARN("Invalid ACE string format\n");
-    return FALSE;
-}
-
-/******************************************************************************
- * ParseStringSecurityDescriptorToSecurityDescriptor
- */
-static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
-    LPCWSTR StringSecurityDescriptor,
-    SECURITY_DESCRIPTOR* SecurityDescriptor,
-    LPDWORD cBytes)
-{
-    BOOL bret = FALSE;
-    WCHAR toktype;
-    WCHAR tok[MAX_PATH];
-    LPCWSTR lptoken;
-    LPBYTE lpNext = NULL;
-    DWORD len;
-
-    *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--;
-
-        len = lptoken - StringSecurityDescriptor;
-        memcpy( tok, StringSecurityDescriptor, len * sizeof(WCHAR) );
-        tok[len] = 0;
-
-        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 */
+static BOOL
+ParseFlagsString(
+	IN LPCWSTR Buffer,
+	IN const RECORD* FlagTable,
+	IN WCHAR LimitChar,
+	OUT DWORD* pFlags,
+	OUT SIZE_T* pLength)
+{
+	LPCWSTR ptr = Buffer;
+	SIZE_T PartialLength;
+	DWORD Flag;
+
+	*pFlags = 0;
+	while (*ptr != LimitChar)
+	{
+		if (!FindKeyInTable(FlagTable, ptr, &PartialLength, &Flag))
+			return FALSE;
+		*pFlags |= Flag;
+		ptr += PartialLength;
+	}
+	*pLength = ptr - Buffer;
+	return TRUE;
+}
+
+static const RECORD AccessMaskTable[] =
+{
+	{ 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 },
+	{ SDDL_READ_PROPERTY, ADS_RIGHT_DS_READ_PROP },
+	{ SDDL_WRITE_PROPERTY, ADS_RIGHT_DS_WRITE_PROP },
+	{ SDDL_CREATE_CHILD, ADS_RIGHT_DS_CREATE_CHILD },
+	{ SDDL_DELETE_CHILD, ADS_RIGHT_DS_DELETE_CHILD },
+	{ SDDL_LIST_CHILDREN, ADS_RIGHT_ACTRL_DS_LIST },
+	{ SDDL_SELF_WRITE, ADS_RIGHT_DS_SELF },
+	{ SDDL_LIST_OBJECT, ADS_RIGHT_DS_LIST_OBJECT },
+	{ SDDL_DELETE_TREE, ADS_RIGHT_DS_DELETE_TREE },
+	{ SDDL_CONTROL_ACCESS, ADS_RIGHT_DS_CONTROL_ACCESS },
+	{ SDDL_FILE_ALL, FILE_ALL_ACCESS },
+	{ SDDL_FILE_READ, FILE_GENERIC_READ },
+	{ SDDL_FILE_WRITE, FILE_GENERIC_WRITE },
+	{ SDDL_FILE_EXECUTE, FILE_GENERIC_EXECUTE },
+	{ SDDL_KEY_ALL, KEY_ALL_ACCESS },
+	{ SDDL_KEY_READ, KEY_READ },
+	{ SDDL_KEY_WRITE, KEY_WRITE },
+	{ SDDL_KEY_EXECUTE, KEY_EXECUTE },
+	{ NULL, 0 },
+};
+
+static BOOL
+ParseAccessMaskString(
+	IN LPCWSTR Buffer,
+	OUT DWORD* pAccessMask,
+	OUT SIZE_T* pLength)
+{
+	/* FIXME: Allow hexadecimal string for access rights! */
+
+	return ParseFlagsString(Buffer, AccessMaskTable, SDDL_SEPERATORC, pAccessMask, pLength);
+}
+
+static BOOL
+ParseGuidString(
+	IN LPCWSTR Buffer,
+	OUT GUID* pGuid,
+	OUT BOOL* pIsGuidValid,
+	OUT SIZE_T* pLength)
+{
+	WCHAR GuidStr[MAX_GUID_STRING_LEN + 1];
+	LPCWSTR end;
+
+	end = wcschr(Buffer, SDDL_SEPERATORC);
+	if (!end)
+	{
+		SetLastError(ERROR_INVALID_PARAMETER);
+		return FALSE;
+	}
+
+	*pLength = end - Buffer;
+	*pIsGuidValid = (end != Buffer);
+	if (!*pIsGuidValid)
+		return TRUE;
+
+	if (end - Buffer > MAX_GUID_STRING_LEN - 1)
+	{
+		SetLastError(ERROR_INVALID_PARAMETER);
+		return FALSE;
+	}
+	GuidStr[end - Buffer] = UNICODE_NULL;
+	wcsncpy(GuidStr, Buffer, end - Buffer);
+	if (RPC_S_OK != UuidFromStringW((unsigned short*)&GuidStr, pGuid))
+	{
+		SetLastError(ERROR_INVALID_PARAMETER);
+		return FALSE;
+	}
+	return TRUE;
+}
+
+static const RECORD AceTypeTable[] =
+{
+	{ SDDL_OBJECT_ACCESS_ALLOWED, ACCESS_ALLOWED_OBJECT_ACE_TYPE },
+	{ SDDL_OBJECT_ACCESS_DENIED, ACCESS_DENIED_OBJECT_ACE_TYPE },
+	{ SDDL_AUDIT, SYSTEM_AUDIT_ACE_TYPE },
+	{ SDDL_ALARM, SYSTEM_ALARM_ACE_TYPE },
+	{ SDDL_OBJECT_AUDIT, SYSTEM_AUDIT_OBJECT_ACE_TYPE },
+	{ SDDL_OBJECT_ALARM, SYSTEM_ALARM_OBJECT_ACE_TYPE },
+	{ SDDL_ACCESS_ALLOWED, ACCESS_ALLOWED_ACE_TYPE },
+	{ SDDL_ACCESS_DENIED, ACCESS_DENIED_ACE_TYPE },
+	{ NULL, 0 },
+};
+
+static BOOL
+ParseAceString(
+	IN LPCWSTR Buffer,
+	IN PACL pAcl,
+	OUT SIZE_T* pLength)
+{
+	LPCWSTR ptr = Buffer;
+	SIZE_T PartialLength;
+	DWORD aceType, aceFlags, accessMask;
+	GUID object, inheritObject;
+	BOOL objectValid, inheritObjectValid;
+	PSID sid = NULL;
+	BOOL ret;
+
+	if (*ptr != SDDL_ACE_BEGINC)
+	{
+		SetLastError(ERROR_INVALID_PARAMETER);
+		return FALSE;
+	}
+	ptr++; /* Skip SDDL_ACE_BEGINC */
+
+	if (!FindKeyInTable(AceTypeTable, ptr, &PartialLength, &aceType))
+		return FALSE;
+	ptr += PartialLength;
+
+	if (*ptr != SDDL_SEPERATORC)
+	{
+		SetLastError(ERROR_INVALID_PARAMETER);
+		return FALSE;
+	}
+	ptr++; /* Skip SDDL_SEPERATORC */
+
+	if (!ParseFlagsString(ptr, AceFlagTable, SDDL_SEPERATORC, &aceFlags, &PartialLength))
+		return FALSE;
+	ptr += PartialLength + 1;
+
+	if (!ParseAccessMaskString(ptr, &accessMask, &PartialLength))
+		return FALSE;
+	ptr += PartialLength + 1;
+
+	if (!ParseGuidString(ptr, &object, &objectValid, &PartialLength))
+		return FALSE;
+	ptr += PartialLength + 1;
+
+	if (!ParseGuidString(ptr, &inheritObject, &inheritObjectValid, &PartialLength))
+		return FALSE;
+	ptr += PartialLength + 1;
+
+	if (!ParseSidString(ptr, &sid, &PartialLength))
+		return FALSE;
+	ptr += PartialLength;
+	if (*ptr != SDDL_ACE_ENDC)
+	{
+		SetLastError(ERROR_INVALID_PARAMETER);
+		return FALSE;
+	}
+	ptr++; /* Skip SDDL_ACE_ENDC */
+	*pLength = ptr - Buffer;
+
+	switch (aceType)
+	{
+		case ACCESS_ALLOWED_ACE_TYPE:
+			ret = AddAccessAllowedAceEx(
+				pAcl,
+				ACL_REVISION_DS,
+				aceFlags,
+				accessMask,
+				sid);
+			break;
+		case ACCESS_ALLOWED_OBJECT_ACE_TYPE:
+			ret = AddAccessAllowedObjectAce(
+				pAcl,
+				ACL_REVISION_DS,
+				aceFlags,
+				accessMask,
+				objectValid ? &object : NULL,
+				inheritObjectValid ? &inheritObject : NULL,
+				sid);
+			break;
+		case ACCESS_DENIED_ACE_TYPE:
+			ret = AddAccessDeniedAceEx(
+				pAcl,
+				ACL_REVISION_DS,
+				aceFlags,
+				accessMask,
+				sid);
+			break;
+		case ACCESS_DENIED_OBJECT_ACE_TYPE:
+			ret = AddAccessDeniedObjectAce(
+				pAcl,
+				ACL_REVISION_DS,
+				aceFlags,
+				accessMask,
+				objectValid ? &object : NULL,
+				inheritObjectValid ? &inheritObject : NULL,
+				sid);
+			break;
+		case SYSTEM_AUDIT_ACE_TYPE:
+			ret = AddAuditAccessAceEx(
+				pAcl,
+				ACL_REVISION_DS,
+				aceFlags,
+				accessMask,
+				sid,
+				FALSE,
+				FALSE);
+			break;
+		case SYSTEM_AUDIT_OBJECT_ACE_TYPE:
+			ret = AddAuditAccessObjectAce(
+				pAcl,
+				ACL_REVISION_DS,
+				aceFlags,
+				accessMask,
+				objectValid ? &object : NULL,
+				inheritObjectValid ? &inheritObject : NULL,
+				sid,
+				FALSE,
+				FALSE);
+			break;
+		case SYSTEM_ALARM_ACE_TYPE:
+		case SYSTEM_ALARM_OBJECT_ACE_TYPE:
+		default:
+		{
+			SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+			ret = FALSE;
 		}
-
-		*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;
-}
-
-/******************************************************************************
- * 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;
-}
-
-/******************************************************************************
- * ParseStringSidToSid
- */
-static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes)
-{
-    BOOL bret = FALSE;
-    SID* pisid=pSid;
-
-    TRACE("%s, %p, %p\n", debugstr_w(StringSid), pSid, cBytes);
-    if (!StringSid)
-    {
-        SetLastError(ERROR_INVALID_PARAMETER);
-        TRACE("StringSid is NULL, returning FALSE\n");
-	return FALSE;
-    }
-
-    *cBytes = ComputeStringSidSize(StringSid);
-    if (!pisid) /* Simply compute the size */
-    {
-        TRACE("only size requested, returning TRUE\n");
-        return TRUE;
-    }
-
-    if (*StringSid != 'S' || *StringSid != '-') /* S-R-I-S-S */
-    {
-        DWORD i = 0, identAuth;
-	DWORD csubauth = ((*cBytes - sizeof(SID)) / sizeof(DWORD)) + 1;
-
-        StringSid += 2; /* Advance to Revision */
-        pisid->Revision = atoiW(StringSid);
-
-        if (pisid->Revision != SDDL_REVISION)
-        {
-            TRACE("Revision %d is unknown\n", pisid->Revision);
-            goto lend; /* ERROR_INVALID_SID */
-        }
-        if (csubauth == 0)
-        {
-            TRACE("SubAuthorityCount is 0\n");
-            goto lend; /* ERROR_INVALID_SID */
-        }
-
-	pisid->SubAuthorityCount = csubauth;
-
-        /* Advance to identifier authority */
-	while (*StringSid && *StringSid != '-')
-            StringSid++;
-        if (*StringSid == '-')
-            StringSid++;
-
-        /* MS' implementation can't handle values greater than 2^32 - 1, so
-         * we don't either; assume most significant bytes are always 0
-         */
-        pisid->IdentifierAuthority.Value[0] = 0;
-        pisid->IdentifierAuthority.Value[1] = 0;
-        identAuth = atoiW(StringSid);
-        pisid->IdentifierAuthority.Value[5] = identAuth & 0xff;
-        pisid->IdentifierAuthority.Value[4] = (identAuth & 0xff00) >> 8;
-        pisid->IdentifierAuthority.Value[3] = (identAuth & 0xff0000) >> 16;
-        pisid->IdentifierAuthority.Value[2] = (identAuth & 0xff000000) >> 24;
-
-        /* Advance to first sub authority */
-        while (*StringSid && *StringSid != '-')
-            StringSid++;
-        if (*StringSid == '-')
-            StringSid++;
-
-        while (*StringSid)
-	{	
-	    while (*StringSid && *StringSid != '-')
-                StringSid++;
-
-            pisid->SubAuthority[i++] = atoiW(StringSid);
-        }
-
-	if (i != pisid->SubAuthorityCount)
-            goto lend; /* ERROR_INVALID_SID */
-
-        bret = TRUE;
-    }
-    else /* String constant format  - Only available in winxp and above */
-    {
-        pisid->Revision = SDDL_REVISION;
-	pisid->SubAuthorityCount = 1;
-
-	FIXME("String constant not supported: %s\n", debugstr_wn(StringSid, 2));
-
-	/* TODO: Lookup string of well-known SIDs in table */
-	pisid->IdentifierAuthority.Value[5] = 0;
-	pisid->SubAuthority[0] = 0;
-
-        bret = TRUE;
-    }
-
-lend:
-    if (!bret)
-        SetLastError(ERROR_INVALID_SID);
-
-    TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
-    return bret;
+	}
+	LocalFree(sid);
+	return ret;
 }
 
 /* Exported functions */
@@ -793,60 +600,190 @@
 
   return TRUE;
 }
-/* Winehq cvs 20050916 */
 /******************************************************************************
  * ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@]
  * @implemented
  */
-BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorW(
-        LPCWSTR StringSecurityDescriptor,
-        DWORD StringSDRevision,
-        PSECURITY_DESCRIPTOR* SecurityDescriptor,
-        PULONG SecurityDescriptorSize)
-{
-    DWORD cBytes;
-    SECURITY_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 = (SECURITY_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;
+BOOL WINAPI
+ConvertStringSecurityDescriptorToSecurityDescriptorW(
+	IN LPCWSTR StringSecurityDescriptor,
+	IN DWORD StringSDRevision,
+	OUT PSECURITY_DESCRIPTOR* SecurityDescriptor,
+	OUT PULONG SecurityDescriptorSize)
+{
+	PSECURITY_DESCRIPTOR sd = NULL;
+	BOOL ret = FALSE;
+
+	if (!StringSecurityDescriptor)
+		SetLastError(ERROR_INVALID_PARAMETER);
+	else if (StringSDRevision != SDDL_REVISION_1)
+		SetLastError(ERROR_INVALID_PARAMETER);
+	else
+	{
+		LPCWSTR ptr = StringSecurityDescriptor;
+		DWORD numberOfAces = 0;
+		DWORD relativeSdSize;
+		SIZE_T MaxAclSize;
+		PSECURITY_DESCRIPTOR relativeSd = NULL;
+		PSID pSid;
+		PACL pAcl;
+		BOOL present, dummy;
+		/* An easy way to know how much space we need for an ACL is to count
+		 * the number of ACEs and say that we have 1 SID by ACE
+		 */
+		ptr = wcschr(StringSecurityDescriptor, SDDL_ACE_BEGINC);
+		while (ptr != NULL)
+		{
+			numberOfAces++;
+			ptr = wcschr(ptr + 1, SDDL_ACE_BEGINC);
+		}
+		MaxAclSize = sizeof(ACL) + numberOfAces *
+			(sizeof(ACCESS_ALLOWED_OBJECT_ACE) + SECURITY_MAX_SID_SIZE);
+
+		sd = (SECURITY_DESCRIPTOR*)LocalAlloc(0, sizeof(SECURITY_DESCRIPTOR));
+		if (!sd)
+		{
+			SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+			return FALSE;
+		}
+		ret = InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION);
+		if (!ret)
+			goto cleanup;
+
+		/* Now, really parse the string */
+		ptr = StringSecurityDescriptor;
+		while (*ptr)
+		{
+			if (ptr[1] != SDDL_DELIMINATORC)
+			{
+				SetLastError(ERROR_INVALID_PARAMETER);
+				ret = FALSE;
+				goto cleanup;
+			}
+			ptr += 2;
+			switch (ptr[-2])
+			{
+				case 'O':
+				case 'G':
+				{
+					PSID pSid;
+					SIZE_T Length;
+
+					ret = ParseSidString(ptr, &pSid, &Length);
+					if (!ret)
+						goto cleanup;
+					if (ptr[-2] == 'O')
+						ret = SetSecurityDescriptorOwner(sd, pSid, FALSE);
+					else
+						ret = SetSecurityDescriptorGroup(sd, pSid, FALSE);
+					if (!ret)
+					{
+						LocalFree(pSid);
+						goto cleanup;
+					}
+					ptr += Length;
+					break;
+				}
+				case 'D':
+				case 'S':
+				{
+					DWORD aclFlags;
+					SIZE_T Length;
+					BOOL isDacl = (ptr[-2] == 'D');
+					
+					if (isDacl)
+						ret = ParseFlagsString(ptr, DaclFlagTable, SDDL_ACE_BEGINC, &aclFlags, &Length);
+					else
+						ret = ParseFlagsString(ptr, SaclFlagTable, SDDL_ACE_BEGINC, &aclFlags, &Length);
+					if (!ret)
+						goto cleanup;
+					pAcl = (PACL)LocalAlloc(0, MaxAclSize);
+					if (!pAcl)
+					{
+						SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+						ret = FALSE;
+						goto cleanup;
+					}
+					if (!InitializeAcl(pAcl, (DWORD)MaxAclSize, ACL_REVISION_DS))
+					{
+						LocalFree(pAcl);
+						goto cleanup;
+					}
+					if (aclFlags != 0)
+					{
+						ret = SetSecurityDescriptorControl(
+							sd,
+							(SECURITY_DESCRIPTOR_CONTROL)aclFlags,
+							(SECURITY_DESCRIPTOR_CONTROL)aclFlags);
+						if (!ret)
+						{
+							LocalFree(pAcl);
+							goto cleanup;
+						}
+					}
+					ptr += Length;
+					while (*ptr == SDDL_ACE_BEGINC)
+					{
+						ret = ParseAceString(ptr, pAcl, &Length);
+						if (!ret)
+						{
+							LocalFree(pAcl);
+							goto cleanup;
+						}
+						ptr += Length;
+					}
+					if (isDacl)
+						ret = SetSecurityDescriptorDacl(sd, TRUE, pAcl, FALSE);
+					else
+						ret = SetSecurityDescriptorSacl(sd, TRUE, pAcl, FALSE);
+					if (!ret)
+					{
+						LocalFree(pAcl);
+						goto cleanup;
+					}
+					break;
+				}
+				default:
+				{
+					SetLastError(ERROR_INVALID_PARAMETER);
+					ret = FALSE;
+					goto cleanup;
+				}
+			}
+		}
+
+		relativeSdSize = 0;
+		while (TRUE)
+		{
+			if (relativeSd)
+				LocalFree(relativeSd);
+			relativeSd = LocalAlloc(0, relativeSdSize);
+			if (!relativeSd)
+			{
+				SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+				goto cleanup;
+			}
+			ret = MakeSelfRelativeSD(sd, relativeSd, &relativeSdSize);
+			if (ret || GetLastError() != ERROR_INSUFFICIENT_BUFFER)
+				break;
+		}
+		if (SecurityDescriptorSize)
+			*SecurityDescriptorSize = relativeSdSize;
+		*SecurityDescriptor = relativeSd;
+
+cleanup:
+		if (GetSecurityDescriptorOwner(sd, &pSid, &dummy))
+			LocalFree(pSid);
+		if (GetSecurityDescriptorGroup(sd, &pSid, &dummy))
+			LocalFree(pSid);
+		if (GetSecurityDescriptorDacl(sd, &present, &pAcl, &dummy) && present)
+			LocalFree(pAcl);
+		if (GetSecurityDescriptorSacl(sd, &present, &pAcl, &dummy) && present)
+			LocalFree(pAcl);
+		LocalFree(sd);
+		return ret;
+	}
+	return FALSE;
 }
 
 /* Winehq cvs 20050916 */
@@ -1204,16 +1141,206 @@
     return bRetVal;
 }
 
-/*
- * @unimplemented
- */
-BOOL STDCALL
+/******************************************************************************
+ * ComputeStringSidSize
+ */
+static DWORD ComputeStringSidSize(LPCWSTR StringSid)
+{
+    DWORD size = sizeof(SID);
+
+    if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I-S-S */
+    {
+        int ctok = 0;
+        while (*StringSid)
+        {
+            if (*StringSid == '-')
+                ctok++;
+            StringSid++;
+        }
+
+        if (ctok > 3)
+            size += (ctok - 3) * sizeof(DWORD);
+    }
+    else /* String constant format  - Only available in winxp and above */
+    {
+        int i;
+
+        for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
+            if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
+                size += (WellKnownSids[i].Sid.SubAuthorityCount - 1) * sizeof(DWORD);
+    }
+
+    return size;
+}
+
+static const RECORD SidTable[] =
+{
+	{ SDDL_ACCOUNT_OPERATORS, WinBuiltinAccountOperatorsSid },
+	{ SDDL_ALIAS_PREW2KCOMPACC, WinBuiltinPreWindows2000CompatibleAccessSid },
+	{ SDDL_ANONYMOUS, WinAnonymousSid },
+	{ SDDL_AUTHENTICATED_USERS, WinAuthenticatedUserSid },
+	{ SDDL_BUILTIN_ADMINISTRATORS, WinBuiltinAdministratorsSid },
+	{ SDDL_BUILTIN_GUESTS, WinBuiltinGuestsSid },
+	{ SDDL_BACKUP_OPERATORS, WinBuiltinBackupOperatorsSid },
+	{ SDDL_BUILTIN_USERS, WinBuiltinUsersSid },
+	{ SDDL_CERT_SERV_ADMINISTRATORS, WinAccountCertAdminsSid /* FIXME: DOMAIN_GROUP_RID_CERT_ADMINS */ },
+	{ SDDL_CREATOR_GROUP, WinCreatorGroupSid },
+	{ SDDL_CREATOR_OWNER, WinCreatorOwnerSid },
+	{ SDDL_DOMAIN_ADMINISTRATORS, WinAccountDomainAdminsSid /* FIXME: DOMAIN_GROUP_RID_ADMINS */ },
+	{ SDDL_DOMAIN_COMPUTERS, WinAccountComputersSid /* FIXME: DOMAIN_GROUP_RID_COMPUTERS */ },
+	{ SDDL_DOMAIN_DOMAIN_CONTROLLERS, WinAccountControllersSid /* FIXME: DOMAIN_GROUP_RID_CONTROLLERS */ },
+	{ SDDL_DOMAIN_GUESTS, WinAccountDomainGuestsSid /* FIXME: DOMAIN_GROUP_RID_GUESTS */ },
+	{ SDDL_DOMAIN_USERS, WinAccountDomainUsersSid /* FIXME: DOMAIN_GROUP_RID_USERS */ },
+	{ SDDL_ENTERPRISE_ADMINS, WinAccountEnterpriseAdminsSid /* FIXME: DOMAIN_GROUP_RID_ENTERPRISE_ADMINS */ },
+	{ SDDL_ENTERPRISE_DOMAIN_CONTROLLERS, WinLogonIdsSid /* FIXME: SECURITY_SERVER_LOGON_RID */ },
+	{ SDDL_EVERYONE, WinWorldSid },
+	{ SDDL_GROUP_POLICY_ADMINS, WinAccountPolicyAdminsSid /* FIXME: DOMAIN_GROUP_RID_POLICY_ADMINS */ },
+	{ SDDL_INTERACTIVE, WinInteractiveSid },
+	{ SDDL_LOCAL_ADMIN, WinAccountAdministratorSid /* FIXME: DOMAIN_USER_RID_ADMIN */ },
+	{ SDDL_LOCAL_GUEST, WinAccountGuestSid /* FIXME: DOMAIN_USER_RID_GUEST */ },
+	{ SDDL_LOCAL_SERVICE, WinLocalServiceSid },
+	{ SDDL_LOCAL_SYSTEM, WinLocalSystemSid },
+	{ SDDL_NETWORK, WinNetworkSid },
+	{ SDDL_NETWORK_CONFIGURATION_OPS, WinBuiltinNetworkConfigurationOperatorsSid },
+	{ SDDL_NETWORK_SERVICE, WinNetworkServiceSid },
+	{ SDDL_PRINTER_OPERATORS, WinBuiltinPrintOperatorsSid },
+	{ SDDL_PERSONAL_SELF, WinSelfSid },
+	{ SDDL_POWER_USERS, WinBuiltinPowerUsersSid },
+	{ SDDL_RAS_SERVERS, WinAccountRasAndIasServersSid /* FIXME: DOMAIN_ALIAS_RID_RAS_SERVERS */ },
+	{ SDDL_REMOTE_DESKTOP, WinBuiltinRemoteDesktopUsersSid },
+	{ SDDL_REPLICATOR, WinBuiltinReplicatorSid },
+	{ SDDL_RESTRICTED_CODE, WinRestrictedCodeSid },
+	{ SDDL_SCHEMA_ADMINISTRATORS, WinAccountSchemaAdminsSid /* FIXME: DOMAIN_GROUP_RID_SCHEMA_ADMINS */ },
+	{ SDDL_SERVER_OPERATORS, WinBuiltinSystemOperatorsSid },
+	{ SDDL_SERVICE, WinServiceSid },
+	{ NULL, 0 },
+};
+
+/*
+ * @implemented
+ */
+BOOL WINAPI
 ConvertStringSidToSidW(
-                IN LPCWSTR StringSid,
-                OUT PSID* sid)
-{
-    FIXME("unimplemented!\n", __FUNCTION__);
-    return FALSE;
+	IN LPCWSTR StringSid,
+	OUT PSID* sid)
+{
+	DWORD size;
+	DWORD i, cBytes, identAuth, csubauth;
+	BOOL ret;
+	SID* pisid;
+
+	TRACE("%s %p\n", StringSid, sid);
+
+	if (!StringSid)
+	{
+		SetLastError(ERROR_INVALID_SID);
+		return FALSE;
+	}
+	for (i = 0; i < sizeof(SidTable) / sizeof(SidTable[0]) - 1; i++)
+	{
+		if (wcscmp(StringSid, SidTable[i].key) == 0)
+		{
+			WELL_KNOWN_SID_TYPE knownSid = (WELL_KNOWN_SID_TYPE)SidTable[i].value;
+			size = SECURITY_MAX_SID_SIZE;
+			*sid = LocalAlloc(0, size);
+			if (!*sid)
+			{
+				SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+				return FALSE;
+			}
+			ret = CreateWellKnownSid(
+				knownSid,
+				NULL,
+				*sid,
+				&size);
+			if (!ret)
+			{
+				SetLastError(ERROR_INVALID_SID);
+				LocalFree(*sid);
+			}
+			return ret;
+		}
+	}
+
+	/* That's probably a string S-R-I-S-S... */
+	if (StringSid[0] != 'S' || StringSid[1] != '-')
+	{
+		SetLastError(ERROR_INVALID_SID);
+		return FALSE;
+	}
+
+    cBytes = ComputeStringSidSize(StringSid);
+    pisid = (SID*)LocalAlloc( 0, cBytes );
+    if (!pisid)
+    {
+        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+        return FALSE;
+    }
+    i = 0;
+    ret = FALSE;
+    csubauth = ((cBytes - sizeof(SID)) / sizeof(DWORD)) + 1;
+
+    StringSid += 2; /* Advance to Revision */
+    pisid->Revision = atoiW(StringSid);
+
+    if (pisid->Revision != SDDL_REVISION)
+    {
+        TRACE("Revision %d is unknown\n", pisid->Revision);
+        goto lend; /* ERROR_INVALID_SID */
+    }
+    if (csubauth == 0)
+    {
+        TRACE("SubAuthorityCount is 0\n");
+        goto lend; /* ERROR_INVALID_SID */
+    }
+
+    pisid->SubAuthorityCount = csubauth;
+
+    /* Advance to identifier authority */
+    while (*StringSid && *StringSid != '-')
+        StringSid++;
+    if (*StringSid == '-')
+        StringSid++;
+
+    /* MS' implementation can't handle values greater than 2^32 - 1, so
+     * we don't either; assume most significant bytes are always 0
+     */
+    pisid->IdentifierAuthority.Value[0] = 0;
+    pisid->IdentifierAuthority.Value[1] = 0;
+    identAuth = atoiW(StringSid);
+    pisid->IdentifierAuthority.Value[5] = identAuth & 0xff;
+    pisid->IdentifierAuthority.Value[4] = (identAuth & 0xff00) >> 8;
+    pisid->IdentifierAuthority.Value[3] = (identAuth & 0xff0000) >> 16;
+    pisid->IdentifierAuthority.Value[2] = (identAuth & 0xff000000) >> 24;
+
+    /* Advance to first sub authority */
+    while (*StringSid && *StringSid != '-')
+        StringSid++;
+    if (*StringSid == '-')
+        StringSid++;
+
+    while (*StringSid)
+    {
+        while (*StringSid && *StringSid != '-')
+            StringSid++;
+        if (*StringSid == '-')
+            StringSid++;
+
+        pisid->SubAuthority[i++] = atoiW(StringSid);
+    }
+
+    if (i != pisid->SubAuthorityCount)
+        goto lend; /* ERROR_INVALID_SID */
+
+    *sid = pisid;
+    ret = TRUE;
+
+lend:
+    if (!ret)
+        SetLastError(ERROR_INVALID_SID);
+
+    TRACE("returning %s\n", ret ? "TRUE" : "FALSE");
+    return ret;
 }
 
 




More information about the Ros-diffs mailing list