[ADVAPI32] Apply Wine commit 4f3acf3 by Michael Müller: Add initial implementation...
[reactos.git] / reactos / dll / win32 / advapi32 / wine / security.c
index c138578..4a61123 100644 (file)
 
 WINE_DEFAULT_DEBUG_CHANNEL(advapi);
 
-static DWORD ComputeStringSidSize(LPCWSTR StringSid);
 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes);
 
-#define MAX_GUID_STRING_LEN 39
-
-BOOL WINAPI
-AddAuditAccessAceEx(PACL pAcl,
-                    DWORD dwAceRevision,
-                    DWORD AceFlags,
-                    DWORD dwAccessMask,
-                    PSID pSid,
-                    BOOL bAuditSuccess,
-                    BOOL bAuditFailure);
-
-typedef struct RECORD
+typedef struct _ACEFLAG
 {
-    LPCWSTR key;
-    DWORD value;
-} RECORD;
-
+   LPCWSTR wstr;
+   DWORD value;
+} ACEFLAG, *LPACEFLAG;
 
 typedef struct _MAX_SID
 {
@@ -53,12 +40,6 @@ typedef struct WELLKNOWNSID
     MAX_SID Sid;
 } WELLKNOWNSID;
 
-typedef struct _ACEFLAG
-{
-   LPCWSTR wstr;
-   DWORD value;
-} ACEFLAG, *LPACEFLAG;
-
 static const WELLKNOWNSID WellKnownSids[] =
 {
     { {0,0}, WinNullSid, { SID_REVISION, 1, { SECURITY_NULL_SID_AUTHORITY }, { SECURITY_NULL_RID } } },
@@ -127,16 +108,16 @@ static const WELLKNOWNRID WellKnownRids[] = {
     { {'L','A'}, WinAccountAdministratorSid,    DOMAIN_USER_RID_ADMIN },
     { {'L','G'}, WinAccountGuestSid,            DOMAIN_USER_RID_GUEST },
     { {0,0}, WinAccountKrbtgtSid,           DOMAIN_USER_RID_KRBTGT },
-    { {0,0}, WinAccountDomainAdminsSid,     DOMAIN_GROUP_RID_ADMINS },
-    { {0,0}, WinAccountDomainUsersSid,      DOMAIN_GROUP_RID_USERS },
-    { {0,0}, WinAccountDomainGuestsSid,     DOMAIN_GROUP_RID_GUESTS },
-    { {0,0}, WinAccountComputersSid,        DOMAIN_GROUP_RID_COMPUTERS },
-    { {0,0}, WinAccountControllersSid,      DOMAIN_GROUP_RID_CONTROLLERS },
-    { {0,0}, WinAccountCertAdminsSid,       DOMAIN_GROUP_RID_CERT_ADMINS },
-    { {0,0}, WinAccountSchemaAdminsSid,     DOMAIN_GROUP_RID_SCHEMA_ADMINS },
-    { {0,0}, WinAccountEnterpriseAdminsSid, DOMAIN_GROUP_RID_ENTERPRISE_ADMINS },
-    { {0,0}, WinAccountPolicyAdminsSid,     DOMAIN_GROUP_RID_POLICY_ADMINS },
-    { {0,0}, WinAccountRasAndIasServersSid, DOMAIN_ALIAS_RID_RAS_SERVERS },
+    { {'D','A'}, WinAccountDomainAdminsSid,     DOMAIN_GROUP_RID_ADMINS },
+    { {'D','U'}, WinAccountDomainUsersSid,      DOMAIN_GROUP_RID_USERS },
+    { {'D','G'}, WinAccountDomainGuestsSid,     DOMAIN_GROUP_RID_GUESTS },
+    { {'D','C'}, WinAccountComputersSid,        DOMAIN_GROUP_RID_COMPUTERS },
+    { {'D','D'}, WinAccountControllersSid,      DOMAIN_GROUP_RID_CONTROLLERS },
+    { {'C','A'}, WinAccountCertAdminsSid,       DOMAIN_GROUP_RID_CERT_ADMINS },
+    { {'S','A'}, WinAccountSchemaAdminsSid,     DOMAIN_GROUP_RID_SCHEMA_ADMINS },
+    { {'E','A'}, WinAccountEnterpriseAdminsSid, DOMAIN_GROUP_RID_ENTERPRISE_ADMINS },
+    { {'P','A'}, WinAccountPolicyAdminsSid,     DOMAIN_GROUP_RID_POLICY_ADMINS },
+    { {'R','S'}, WinAccountRasAndIasServersSid, DOMAIN_ALIAS_RID_RAS_SERVERS },
 };
 
 static const SID sidWorld = { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY} , { SECURITY_WORLD_RID } };
@@ -236,48 +217,18 @@ static __inline BOOL set_ntstatus( NTSTATUS status )
     return NT_SUCCESS(status);
 }
 
-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, WinEnterpriseControllersSid },
-       { 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 },
-};
+static LPWSTR SERV_dup( LPCSTR str )
+{
+    UINT len;
+    LPWSTR wstr;
+
+    if( !str )
+        return NULL;
+    len = MultiByteToWideChar( CP_ACP, 0, str, -1, NULL, 0 );
+    wstr = heap_alloc( len*sizeof (WCHAR) );
+    MultiByteToWideChar( CP_ACP, 0, str, -1, wstr, len );
+    return wstr;
+}
 
 /************************************************************
  *                ADVAPI_IsLocalComputer
@@ -1092,53 +1043,25 @@ FindFirstFreeAce(PACL pAcl,
                            (PACE*)pAce);
 }
 
-
-/*
- * @implemented
+/******************************************************************************
+ * GetAce [ADVAPI32.@]
  */
-BOOL
-WINAPI
-GetAce(PACL pAcl,
-       DWORD dwAceIndex,
-       LPVOID *pAce)
+BOOL WINAPI GetAce(PACL pAcl,DWORD dwAceIndex,LPVOID *pAce )
 {
-    NTSTATUS Status;
-
-    Status = RtlGetAce(pAcl,
-                       dwAceIndex,
-                       pAce);
-    if (!NT_SUCCESS(Status))
-    {
-        SetLastError(RtlNtStatusToDosError(Status));
-        return FALSE;
-    }
-
-    return TRUE;
+    return set_ntstatus(RtlGetAce(pAcl, dwAceIndex, pAce));
 }
 
-/*
- * @implemented
+/******************************************************************************
+ * GetAclInformation [ADVAPI32.@]
  */
-BOOL
-WINAPI
-GetAclInformation(PACL pAcl,
-                  LPVOID pAclInformation,
-                  DWORD nAclInformationLength,
-                  ACL_INFORMATION_CLASS dwAclInformationClass)
+BOOL WINAPI GetAclInformation(
+  PACL pAcl,
+  LPVOID pAclInformation,
+  DWORD nAclInformationLength,
+  ACL_INFORMATION_CLASS dwAclInformationClass)
 {
-    NTSTATUS Status;
-
-    Status = RtlQueryInformationAcl(pAcl,
-                                    pAclInformation,
-                                    nAclInformationLength,
-                                    dwAclInformationClass);
-    if (!NT_SUCCESS(Status))
-    {
-        SetLastError(RtlNtStatusToDosError(Status));
-        return FALSE;
-    }
-
-    return TRUE;
+    return set_ntstatus(RtlQueryInformationAcl(pAcl, pAclInformation,
+                                               nAclInformationLength, dwAclInformationClass));
 }
 
 /*
@@ -1179,31 +1102,54 @@ WINAPI
 LookupPrivilegeDisplayNameA(LPCSTR lpSystemName,
                             LPCSTR lpName,
                             LPSTR lpDisplayName,
-                            LPDWORD cbDisplayName,
+                            LPDWORD cchDisplayName,
                             LPDWORD lpLanguageId)
 {
-    FIXME("%s() not implemented!\n", __FUNCTION__);
-    SetLastError (ERROR_CALL_NOT_IMPLEMENTED);
-    return FALSE;
-}
+    UNICODE_STRING lpSystemNameW;
+    UNICODE_STRING lpNameW;
+    BOOL ret;
+    DWORD wLen = 0;
 
+    TRACE("%s %s %p %p %p\n", debugstr_a(lpSystemName), debugstr_a(lpName), lpName, cchDisplayName, lpLanguageId);
 
-/**********************************************************************
- * LookupPrivilegeDisplayNameW                 EXPORTED
- *
- * @unimplemented
- */
-BOOL
-WINAPI
-LookupPrivilegeDisplayNameW(LPCWSTR lpSystemName,
-                            LPCWSTR lpName,
-                            LPWSTR lpDisplayName,
-                            LPDWORD cbDisplayName,
-                            LPDWORD lpLanguageId)
-{
-    FIXME("%s() not implemented!\n", __FUNCTION__);
-    SetLastError (ERROR_CALL_NOT_IMPLEMENTED);
-    return FALSE;
+    RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
+    RtlCreateUnicodeStringFromAsciiz(&lpNameW, lpName);
+    ret = LookupPrivilegeDisplayNameW(lpSystemNameW.Buffer, lpNameW.Buffer, NULL, &wLen, lpLanguageId);
+    if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
+    {
+        LPWSTR lpDisplayNameW = HeapAlloc(GetProcessHeap(), 0, wLen * sizeof(WCHAR));
+
+        ret = LookupPrivilegeDisplayNameW(lpSystemNameW.Buffer, lpNameW.Buffer, lpDisplayNameW,
+                                          &wLen, lpLanguageId);
+        if (ret)
+        {
+            unsigned int len = WideCharToMultiByte(CP_ACP, 0, lpDisplayNameW, -1, lpDisplayName,
+                                                   *cchDisplayName, NULL, NULL);
+
+            if (len == 0)
+            {
+                /* WideCharToMultiByte failed */
+                ret = FALSE;
+            }
+            else if (len > *cchDisplayName)
+            {
+                *cchDisplayName = len;
+                SetLastError(ERROR_INSUFFICIENT_BUFFER);
+                ret = FALSE;
+            }
+            else
+            {
+                /* WideCharToMultiByte succeeded, output length needs to be
+                 * length not including NULL terminator
+                 */
+                *cchDisplayName = len - 1;
+            }
+        }
+        HeapFree(GetProcessHeap(), 0, lpDisplayNameW);
+    }
+    RtlFreeUnicodeString(&lpSystemNameW);
+    RtlFreeUnicodeString(&lpNameW);
+    return ret;
 }
 
 /**********************************************************************
@@ -2114,25 +2060,32 @@ BuildTrusteeWithNameW(PTRUSTEE_W pTrustee,
     pTrustee->ptstrName = name;
 }
 
-/******************************************************************************
- * GetTrusteeFormW [ADVAPI32.@]
- */
-TRUSTEE_FORM WINAPI
-GetTrusteeFormA(PTRUSTEE_A pTrustee)
-{
-    return pTrustee->TrusteeForm;
-}
-
-
-/******************************************************************************
- * GetTrusteeFormW [ADVAPI32.@]
- */
-TRUSTEE_FORM WINAPI
-GetTrusteeFormW(PTRUSTEE_W pTrustee)
-{
-    return pTrustee->TrusteeForm;
-}
-
+/****************************************************************************** 
+ * GetTrusteeFormA [ADVAPI32.@] 
+ */ 
+TRUSTEE_FORM WINAPI GetTrusteeFormA(PTRUSTEEA pTrustee) 
+{  
+    TRACE("(%p)\n", pTrustee); 
+  
+    if (!pTrustee) 
+        return TRUSTEE_BAD_FORM; 
+  
+    return pTrustee->TrusteeForm; 
+}  
+  
+/****************************************************************************** 
+ * GetTrusteeFormW [ADVAPI32.@] 
+ */ 
+TRUSTEE_FORM WINAPI GetTrusteeFormW(PTRUSTEEW pTrustee) 
+{  
+    TRACE("(%p)\n", pTrustee); 
+  
+    if (!pTrustee) 
+        return TRUSTEE_BAD_FORM; 
+  
+    return pTrustee->TrusteeForm; 
+}  
+  
 /******************************************************************************
  * GetTrusteeNameA [ADVAPI32.@]
  */
@@ -2591,13 +2544,15 @@ static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
 {
     BOOL bret = FALSE;
     WCHAR toktype;
-    WCHAR tok[MAX_PATH];
+    WCHAR *tok;
     LPCWSTR lptoken;
     LPBYTE lpNext = NULL;
     DWORD len;
 
     *cBytes = sizeof(SECURITY_DESCRIPTOR);
 
+    tok = heap_alloc( (lstrlenW(StringSecurityDescriptor) + 1) * sizeof(WCHAR));
+
     if (SecurityDescriptor)
         lpNext = (LPBYTE)(SecurityDescriptor + 1);
 
@@ -2719,6 +2674,7 @@ static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
     bret = TRUE;
 
 lend:
+    heap_free(tok);
     return bret;
 }
 
@@ -3131,14 +3087,8 @@ static BOOL DumpSacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULO
 
 /******************************************************************************
  * ConvertSecurityDescriptorToStringSecurityDescriptorW [ADVAPI32.@]
- * @implemented
  */
-BOOL WINAPI
-ConvertSecurityDescriptorToStringSecurityDescriptorW(PSECURITY_DESCRIPTOR SecurityDescriptor,
-                                                     DWORD SDRevision,
-                                                     SECURITY_INFORMATION SecurityInformation,
-                                                     LPWSTR *OutputString,
-                                                     PULONG OutputLen)
+BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorW(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION RequestedInformation, LPWSTR *OutputString, PULONG OutputLen)
 {
     ULONG len;
     WCHAR *wptr, *wstr;
@@ -3151,35 +3101,45 @@ ConvertSecurityDescriptorToStringSecurityDescriptorW(PSECURITY_DESCRIPTOR Securi
     }
 
     len = 0;
-    if (SecurityInformation & OWNER_SECURITY_INFORMATION)
+    if (RequestedInformation & OWNER_SECURITY_INFORMATION)
         if (!DumpOwner(SecurityDescriptor, NULL, &len))
             return FALSE;
-    if (SecurityInformation & GROUP_SECURITY_INFORMATION)
+    if (RequestedInformation & GROUP_SECURITY_INFORMATION)
         if (!DumpGroup(SecurityDescriptor, NULL, &len))
             return FALSE;
-    if (SecurityInformation & DACL_SECURITY_INFORMATION)
+    if (RequestedInformation & DACL_SECURITY_INFORMATION)
         if (!DumpDacl(SecurityDescriptor, NULL, &len))
             return FALSE;
-    if (SecurityInformation & SACL_SECURITY_INFORMATION)
+    if (RequestedInformation & SACL_SECURITY_INFORMATION)
         if (!DumpSacl(SecurityDescriptor, NULL, &len))
             return FALSE;
 
     wstr = wptr = LocalAlloc(0, (len + 1)*sizeof(WCHAR));
+#ifdef __REACTOS__
     if (wstr == NULL)
         return FALSE;
-        
-    if (SecurityInformation & OWNER_SECURITY_INFORMATION)
-        if (!DumpOwner(SecurityDescriptor, &wptr, NULL))
+#endif
+
+    if (RequestedInformation & OWNER_SECURITY_INFORMATION)
+        if (!DumpOwner(SecurityDescriptor, &wptr, NULL)) {
+            LocalFree (wstr);
             return FALSE;
-    if (SecurityInformation & GROUP_SECURITY_INFORMATION)
-        if (!DumpGroup(SecurityDescriptor, &wptr, NULL))
+        }
+    if (RequestedInformation & GROUP_SECURITY_INFORMATION)
+        if (!DumpGroup(SecurityDescriptor, &wptr, NULL)) {
+            LocalFree (wstr);
             return FALSE;
-    if (SecurityInformation & DACL_SECURITY_INFORMATION)
-        if (!DumpDacl(SecurityDescriptor, &wptr, NULL))
+        }
+    if (RequestedInformation & DACL_SECURITY_INFORMATION)
+        if (!DumpDacl(SecurityDescriptor, &wptr, NULL)) {
+            LocalFree (wstr);
             return FALSE;
-    if (SecurityInformation & SACL_SECURITY_INFORMATION)
-        if (!DumpSacl(SecurityDescriptor, &wptr, NULL))
+        }
+    if (RequestedInformation & SACL_SECURITY_INFORMATION)
+        if (!DumpSacl(SecurityDescriptor, &wptr, NULL)) {
+            LocalFree (wstr);
             return FALSE;
+        }
     *wptr = 0;
 
     TRACE("ret: %s, %d\n", wine_dbgstr_w(wstr), len);
@@ -3191,30 +3151,25 @@ ConvertSecurityDescriptorToStringSecurityDescriptorW(PSECURITY_DESCRIPTOR Securi
 
 /******************************************************************************
  * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
- * @implemented
  */
-BOOL WINAPI
-ConvertSecurityDescriptorToStringSecurityDescriptorA(PSECURITY_DESCRIPTOR SecurityDescriptor,
-                                                     DWORD SDRevision,
-                                                     SECURITY_INFORMATION Information,
-                                                     LPSTR *OutputString,
-                                                     PULONG OutputLen)
+BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorA(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION Information, LPSTR *OutputString, PULONG OutputLen)
 {
     LPWSTR wstr;
     ULONG len;
-
     if (ConvertSecurityDescriptorToStringSecurityDescriptorW(SecurityDescriptor, SDRevision, Information, &wstr, &len))
     {
         int lenA;
 
         lenA = WideCharToMultiByte(CP_ACP, 0, wstr, len, NULL, 0, NULL, NULL);
-        *OutputString = HeapAlloc(GetProcessHeap(), 0, lenA);
+        *OutputString = heap_alloc(lenA);
+#ifdef __REACTOS__
         if (*OutputString == NULL)
         {
             LocalFree(wstr);
             *OutputLen = 0;
             return FALSE;
         }
+#endif
         WideCharToMultiByte(CP_ACP, 0, wstr, len, *OutputString, lenA, NULL, NULL);
         LocalFree(wstr);
 
@@ -3231,162 +3186,49 @@ ConvertSecurityDescriptorToStringSecurityDescriptorA(PSECURITY_DESCRIPTOR Securi
     }
 }
 
-/*
- * @implemented
+/******************************************************************************
+ * ConvertStringSidToSidW [ADVAPI32.@]
  */
-BOOL
-WINAPI
-ConvertStringSidToSidW(IN LPCWSTR StringSid,
-                       OUT PSID* sid)
+BOOL WINAPI ConvertStringSidToSidW(LPCWSTR StringSid, PSID* Sid)
 {
-    DWORD size;
-    DWORD i, cBytes, identAuth, csubauth;
-    BOOL ret;
-    SID* pisid;
-
-    TRACE("%s %p\n", debugstr_w(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 - GetSidLengthRequired(0)) / sizeof(DWORD));
-
-    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++;
+    BOOL bret = FALSE;
+    DWORD cBytes;
 
-    while (*StringSid)
+    TRACE("%s, %p\n", debugstr_w(StringSid), Sid);
+    if (GetVersion() & 0x80000000)
+        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    else if (!StringSid || !Sid)
+        SetLastError(ERROR_INVALID_PARAMETER);
+    else if (ParseStringSidToSid(StringSid, NULL, &cBytes))
     {
-        pisid->SubAuthority[i++] = atoiW(StringSid);
+        PSID pSid = *Sid = LocalAlloc(0, cBytes);
 
-        while (*StringSid && *StringSid != '-')
-            StringSid++;
-        if (*StringSid == '-')
-            StringSid++;
-    }
-
-    if (i != pisid->SubAuthorityCount)
-        goto lend; /* ERROR_INVALID_SID */
-
-    *sid = pisid;
-    ret = TRUE;
-
-lend:
-    if (!ret)
-    {
-        LocalFree(pisid);
-        SetLastError(ERROR_INVALID_SID);
+        bret = ParseStringSidToSid(StringSid, pSid, &cBytes);
+        if (!bret)
+            LocalFree(*Sid); 
     }
-
-    TRACE("returning %s\n", ret ? "TRUE" : "FALSE");
-    return ret;
+    return bret;
 }
 
-/*
- * @implemented
+/******************************************************************************
+ * ConvertStringSidToSidA [ADVAPI32.@]
  */
-BOOL
-WINAPI
-ConvertStringSidToSidA(IN LPCSTR StringSid,
-                       OUT PSID* sid)
+BOOL WINAPI ConvertStringSidToSidA(LPCSTR StringSid, PSID* Sid)
 {
-    BOOL bRetVal = FALSE;
+    BOOL bret = FALSE;
 
-    TRACE("%s, %p\n", debugstr_a(StringSid), sid);
+    TRACE("%s, %p\n", debugstr_a(StringSid), Sid);
     if (GetVersion() & 0x80000000)
         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-    else if (!StringSid || !sid)
+    else if (!StringSid || !Sid)
         SetLastError(ERROR_INVALID_PARAMETER);
     else
     {
-        UINT len = MultiByteToWideChar(CP_ACP, 0, StringSid, -1, NULL, 0);
-        LPWSTR wStringSid = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
-        if (wStringSid == NULL)
-            return FALSE;
-        MultiByteToWideChar(CP_ACP, 0, StringSid, - 1, wStringSid, len);
-        bRetVal = ConvertStringSidToSidW(wStringSid, sid);
-        HeapFree(GetProcessHeap(), 0, wStringSid);
+        WCHAR *wStringSid = SERV_dup(StringSid);
+        bret = ConvertStringSidToSidW(wStringSid, Sid);
+        heap_free(wStringSid);
     }
-    return bRetVal;
+    return bret;
 }
 
 /*
@@ -3511,20 +3353,18 @@ CreateProcessWithLogonW(LPCWSTR lpUsername,
     return FALSE;
 }
 
-BOOL
-WINAPI
-CreateProcessWithTokenW(IN HANDLE hToken,
-                        IN DWORD dwLogonFlags,
-                        IN LPCWSTR lpApplicationName OPTIONAL,
-                        IN OUT LPWSTR lpCommandLine OPTIONAL,
-                        IN DWORD dwCreationFlags,
-                        IN LPVOID lpEnvironment OPTIONAL,
-                        IN LPCWSTR lpCurrentDirectory OPTIONAL,
-                        IN LPSTARTUPINFOW lpStartupInfo,
-                        OUT LPPROCESS_INFORMATION lpProcessInfo)
+BOOL WINAPI CreateProcessWithTokenW(HANDLE token, DWORD logon_flags, LPCWSTR application_name, LPWSTR command_line,
+        DWORD creation_flags, void *environment, LPCWSTR current_directory, STARTUPINFOW *startup_info,
+        PROCESS_INFORMATION *process_information )
 {
-    UNIMPLEMENTED;
-    return FALSE;
+    FIXME("%p 0x%08x %s %s 0x%08x %p %s %p %p - semi-stub\n", token,
+          logon_flags, debugstr_w(application_name), debugstr_w(command_line),
+          creation_flags, environment, debugstr_w(current_directory),
+          startup_info, process_information);
+
+    /* FIXME: check if handles should be inherited */
+    return CreateProcessW( application_name, command_line, NULL, NULL, FALSE, creation_flags, environment,
+                           current_directory, startup_info, process_information );
 }
 
 /*
@@ -3661,6 +3501,9 @@ static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes)
     while (*StringSid == ' ')
         StringSid++;
 
+    if (!*StringSid)
+        goto lend; /* ERROR_INVALID_SID */
+
     *cBytes = ComputeStringSidSize(StringSid);
     if (!pisid) /* Simply compute the size */
     {
@@ -3802,17 +3645,50 @@ GetNamedSecurityInfoA(LPSTR pObjectName,
     return r;
 }
 
-/*
- * @unimplemented
+/******************************************************************************
+ * GetWindowsAccountDomainSid         [ADVAPI32.@]
  */
-BOOL
-WINAPI
-GetWindowsAccountDomainSid(IN PSID pSid,
-                           OUT PSID ppDomainSid,
-                           IN OUT DWORD* cbSid)
+BOOL WINAPI GetWindowsAccountDomainSid( PSID sid, PSID domain_sid, DWORD *size )
 {
-    UNIMPLEMENTED;
-    return FALSE;
+    SID_IDENTIFIER_AUTHORITY domain_ident = { SECURITY_NT_AUTHORITY };
+    DWORD required_size;
+    int i;
+
+    FIXME( "(%p %p %p): semi-stub\n", sid, domain_sid, size );
+
+    if (!sid || !IsValidSid( sid ))
+    {
+        SetLastError( ERROR_INVALID_SID );
+        return FALSE;
+    }
+
+    if (!size)
+    {
+        SetLastError( ERROR_INVALID_PARAMETER );
+        return FALSE;
+    }
+
+    if (*GetSidSubAuthorityCount( sid ) < 4)
+    {
+        SetLastError( ERROR_INVALID_SID );
+        return FALSE;
+    }
+
+    required_size = GetSidLengthRequired( 4 );
+    if (*size < required_size || !domain_sid)
+    {
+        *size = required_size;
+        SetLastError( domain_sid ? ERROR_INSUFFICIENT_BUFFER :
+                                   ERROR_INVALID_PARAMETER );
+        return FALSE;
+    }
+
+    InitializeSid( domain_sid, &domain_ident, 4 );
+    for (i = 0; i < 4; i++)
+        *GetSidSubAuthority( domain_sid, i ) = *GetSidSubAuthority( sid, i );
+
+    *size = required_size;
+    return TRUE;
 }
 
 /*