Changes to get msi based installers mostly working

ConvertStringSecurityDescriptorToSecurityDescriptor[W/A] - implement based on Winehq code
InitiateSystemShutdownExW - add stub from Wine
Convert registry source file to use Wine debugging Macros

svn path=/trunk/; revision=17410
This commit is contained in:
Steven Edwards 2005-08-16 05:17:06 +00:00
parent 51cbaf1419
commit 3bea619a9a
6 changed files with 759 additions and 58 deletions

View file

@ -91,8 +91,8 @@ ConvertSidToStringSidW@8
;ConvertStringSDToSDDomainW@24
;ConvertStringSDToSDRootDomainA@20
;ConvertStringSDToSDRootDomainW@20
;ConvertStringSecurityDescriptorToSecurityDescriptorA@20
;ConvertStringSecurityDescriptorToSecurityDescriptorW@20
ConvertStringSecurityDescriptorToSecurityDescriptorA@16
ConvertStringSecurityDescriptorToSecurityDescriptorW@16
;ConvertStringSidToSidA@8
;ConvertStringSidToSidW@8
ConvertToAutoInheritPrivateObjectSecurity@24
@ -315,7 +315,7 @@ InitializeSecurityDescriptor@8
InitializeSid@12
InitiateSystemShutdownA@20
;InitiateSystemShutdownExA@24
;InitiateSystemShutdownExW@24
InitiateSystemShutdownExW@24
InitiateSystemShutdownW@20
;InstallApplication
IsTextUnicode@12=NTDLL.RtlIsTextUnicode

View file

@ -14,6 +14,7 @@
/* PSDK/NDK Headers */
#include <windows.h>
#include <accctrl.h>
#include <sddl.h>
#define NTOS_MODE_USER
#include <ndk/ntndk.h>

View file

@ -10,6 +10,7 @@
<library>ntdll</library>
<library>kernel32</library>
<library>rpcrt4</library>
<library>wine</library>
<pch>advapi32.h</pch>
<directory name="crypt">
<file>crypt.c</file>

View file

@ -11,6 +11,7 @@
*/
#include <advapi32.h>
#include <wine/debug.h>
#define USZ {0,0,0}
@ -146,4 +147,19 @@ InitiateSystemShutdownA(
return rv;
}
/******************************************************************************
* InitiateSystemShutdownExW [ADVAPI32.@]
*
* see InitiateSystemShutdownExA
*/
BOOL WINAPI InitiateSystemShutdownExW( LPWSTR lpMachineName, LPWSTR lpMessage,
DWORD dwTimeout, BOOL bForceAppsClosed, BOOL bRebootAfterShutdown,
DWORD dwReason)
{
FIXME("%s %s %ld %d %d %ld\n", debugstr_w(lpMachineName),
debugstr_w(lpMessage), dwTimeout, bForceAppsClosed,
bRebootAfterShutdown, dwReason);
return TRUE;
}
/* EOF */

View file

@ -15,7 +15,7 @@
#include <advapi32.h>
#define NDEBUG
#include <debug.h>
#include <wine/debug.h>
/* DEFINES ******************************************************************/
@ -56,7 +56,7 @@ inline static int is_string( DWORD type )
BOOL
RegInitialize (VOID)
{
DPRINT("RegInitialize()\n");
TRACE("RegInitialize()\n");
ProcessHeap = RtlGetProcessHeap();
RtlZeroMemory (DefaultHandleTable,
@ -73,7 +73,7 @@ RegInitialize (VOID)
BOOL
RegCleanup (VOID)
{
DPRINT("RegCleanup()\n");
TRACE("RegCleanup()\n");
CloseDefaultKeys ();
RtlDeleteCriticalSection (&HandleTableCS);
@ -90,7 +90,7 @@ MapDefaultKey (PHANDLE RealKey,
ULONG Index;
NTSTATUS Status = STATUS_SUCCESS;
DPRINT("MapDefaultKey (Key %x)\n", Key);
TRACE("MapDefaultKey (Key %x)\n", Key);
if (((ULONG)Key & 0xF0000000) != 0x80000000)
{
@ -142,7 +142,7 @@ MapDefaultKey (PHANDLE RealKey,
break;
default:
DPRINT("MapDefaultHandle() no handle creator\n");
WARN("MapDefaultHandle() no handle creator\n");
Status = STATUS_INVALID_PARAMETER;
}
}
@ -181,7 +181,7 @@ OpenClassesRootKey (PHANDLE KeyHandle)
OBJECT_ATTRIBUTES Attributes;
UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\Software\\CLASSES");
DPRINT("OpenClassesRootKey()\n");
TRACE("OpenClassesRootKey()\n");
InitializeObjectAttributes (&Attributes,
&KeyName,
@ -201,7 +201,7 @@ OpenLocalMachineKey (PHANDLE KeyHandle)
UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"\\Registry\\Machine");
NTSTATUS Status;
DPRINT("OpenLocalMachineKey()\n");
TRACE("OpenLocalMachineKey()\n");
InitializeObjectAttributes (&Attributes,
&KeyName,
@ -212,7 +212,7 @@ OpenLocalMachineKey (PHANDLE KeyHandle)
MAXIMUM_ALLOWED,
&Attributes);
DPRINT("NtOpenKey(%wZ) => %08x\n", &KeyName, Status);
TRACE("NtOpenKey(%wZ) => %08x\n", &KeyName, Status);
return Status;
}
@ -223,7 +223,7 @@ OpenUsersKey (PHANDLE KeyHandle)
OBJECT_ATTRIBUTES Attributes;
UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"\\Registry\\User");
DPRINT("OpenUsersKey()\n");
TRACE("OpenUsersKey()\n");
InitializeObjectAttributes (&Attributes,
&KeyName,
@ -243,7 +243,7 @@ OpenCurrentConfigKey (PHANDLE KeyHandle)
UNICODE_STRING KeyName =
RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Hardware Profiles\\Current");
DPRINT("OpenCurrentConfigKey()\n");
TRACE("OpenCurrentConfigKey()\n");
InitializeObjectAttributes (&Attributes,
&KeyName,
@ -341,7 +341,7 @@ CreateNestedKey(PHKEY KeyHandle,
ClassString,
dwOptions,
(PULONG)lpdwDisposition);
DPRINT("NtCreateKey(%wZ) called (Status %lx)\n", ObjectAttributes->ObjectName, Status);
TRACE("NtCreateKey(%wZ) called (Status %lx)\n", ObjectAttributes->ObjectName, Status);
if (Status != STATUS_OBJECT_NAME_NOT_FOUND)
return Status;
@ -373,7 +373,7 @@ CreateNestedKey(PHKEY KeyHandle,
NULL,
0,
&Disposition);
DPRINT("NtCreateKey(%wZ) called (Status %lx)\n", &LocalKeyName, Status);
TRACE("NtCreateKey(%wZ) called (Status %lx)\n", &LocalKeyName, Status);
}
if (!NT_SUCCESS(Status))
@ -410,7 +410,7 @@ CreateNestedKey(PHKEY KeyHandle,
NULL,
0,
&Disposition);
DPRINT("NtCreateKey(%wZ) called (Status %lx)\n", &LocalKeyName, Status);
TRACE("NtCreateKey(%wZ) called (Status %lx)\n", &LocalKeyName, Status);
if (!NT_SUCCESS(Status))
break;
}
@ -443,7 +443,7 @@ RegCreateKeyExA (HKEY hKey,
HANDLE ParentKey;
NTSTATUS Status;
DPRINT("RegCreateKeyExA() called\n");
TRACE("RegCreateKeyExA() called\n");
/* get the real parent key */
Status = MapDefaultKey (&ParentKey,
@ -452,7 +452,7 @@ RegCreateKeyExA (HKEY hKey,
{
return RtlNtStatusToDosError (Status);
}
DPRINT("ParentKey %x\n", (ULONG)ParentKey);
TRACE("ParentKey %x\n", (ULONG)ParentKey);
if (lpClass != NULL)
{
@ -479,7 +479,7 @@ RegCreateKeyExA (HKEY hKey,
RtlFreeUnicodeString (&ClassString);
}
DPRINT("Status %x\n", Status);
TRACE("Status %x\n", Status);
if (!NT_SUCCESS(Status))
{
return RtlNtStatusToDosError (Status);
@ -511,7 +511,7 @@ RegCreateKeyExW (HKEY hKey,
HANDLE ParentKey;
NTSTATUS Status;
DPRINT("RegCreateKeyExW() called\n");
TRACE("RegCreateKeyExW() called\n");
/* get the real parent key */
Status = MapDefaultKey (&ParentKey,
@ -520,7 +520,7 @@ RegCreateKeyExW (HKEY hKey,
{
return RtlNtStatusToDosError(Status);
}
DPRINT("ParentKey %x\n", (ULONG)ParentKey);
TRACE("ParentKey %x\n", (ULONG)ParentKey);
RtlInitUnicodeString (&ClassString,
lpClass);
@ -537,7 +537,7 @@ RegCreateKeyExW (HKEY hKey,
dwOptions,
samDesired,
lpdwDisposition);
DPRINT("Status %x\n", Status);
TRACE("Status %x\n", Status);
if (!NT_SUCCESS(Status))
{
return RtlNtStatusToDosError (Status);
@ -838,7 +838,7 @@ RegEnumKeyExA (HKEY hKey,
HANDLE KeyHandle;
NTSTATUS Status;
DPRINT("RegEnumKeyExA(hKey 0x%x, dwIndex %d, lpName 0x%x, *lpcbName %d, lpClass 0x%x, lpcbClass %d)\n",
TRACE("RegEnumKeyExA(hKey 0x%x, dwIndex %d, lpName 0x%x, *lpcbName %d, lpClass 0x%x, lpcbClass %d)\n",
hKey, dwIndex, lpName, *lpcbName, lpClass, lpcbClass ? *lpcbClass : 0);
if ((lpClass) && (!lpcbClass))
@ -892,7 +892,7 @@ RegEnumKeyExA (HKEY hKey,
KeyInfo,
BufferSize,
&ResultSize);
DPRINT("NtEnumerateKey() returned status 0x%X\n", Status);
TRACE("NtEnumerateKey() returned status 0x%X\n", Status);
if (!NT_SUCCESS(Status))
{
ErrorCode = RtlNtStatusToDosError (Status);
@ -960,10 +960,10 @@ RegEnumKeyExA (HKEY hKey,
}
}
DPRINT("Key Namea0 Length %d\n", StringU.Length);
DPRINT("Key Namea1 Length %d\n", NameLength);
DPRINT("Key Namea Length %d\n", *lpcbName);
DPRINT("Key Namea %s\n", lpName);
TRACE("Key Namea0 Length %d\n", StringU.Length);
TRACE("Key Namea1 Length %d\n", NameLength);
TRACE("Key Namea Length %d\n", *lpcbName);
TRACE("Key Namea %s\n", lpName);
RtlFreeHeap (ProcessHeap,
0,
@ -1050,7 +1050,7 @@ RegEnumKeyExW (HKEY hKey,
KeyInfo,
BufferSize,
&ResultSize);
DPRINT("NtEnumerateKey() returned status 0x%X\n", Status);
TRACE("NtEnumerateKey() returned status 0x%X\n", Status);
if (!NT_SUCCESS(Status))
{
ErrorCode = RtlNtStatusToDosError (Status);
@ -1386,7 +1386,7 @@ RegGetKeySecurity(HKEY hKey,
hKey);
if (!NT_SUCCESS(Status))
{
DPRINT("MapDefaultKey() failed (Status %lx)\n", Status);
TRACE("MapDefaultKey() failed (Status %lx)\n", Status);
return RtlNtStatusToDosError (Status);
}
@ -1397,7 +1397,7 @@ RegGetKeySecurity(HKEY hKey,
lpcbSecurityDescriptor);
if (!NT_SUCCESS(Status))
{
DPRINT("NtQuerySecurityObject() failed (Status %lx)\n", Status);
WARN("NtQuerySecurityObject() failed (Status %lx)\n", Status);
return RtlNtStatusToDosError (Status);
}
@ -1590,7 +1590,7 @@ RegOpenKeyA (HKEY hKey,
LPCSTR lpSubKey,
PHKEY phkResult)
{
DPRINT("RegOpenKeyA hKey 0x%x lpSubKey %s phkResult %p\n", hKey, lpSubKey, phkResult);
TRACE("RegOpenKeyA hKey 0x%x lpSubKey %s phkResult %p\n", hKey, lpSubKey, phkResult);
if (!lpSubKey || !*lpSubKey)
{
@ -1616,7 +1616,7 @@ RegOpenKeyW (HKEY hKey,
LPCWSTR lpSubKey,
PHKEY phkResult)
{
DPRINT("RegOpenKeyW hKey 0x%x lpSubKey %S phkResult %p\n", hKey, lpSubKey, phkResult);
TRACE("RegOpenKeyW hKey 0x%x lpSubKey %S phkResult %p\n", hKey, lpSubKey, phkResult);
if (!lpSubKey || !*lpSubKey)
{
@ -1644,7 +1644,7 @@ RegOpenKeyExA (HKEY hKey,
HANDLE KeyHandle;
NTSTATUS Status;
DPRINT("RegOpenKeyExA hKey 0x%x lpSubKey %s ulOptions 0x%x samDesired 0x%x phkResult %p\n",
TRACE("RegOpenKeyExA hKey 0x%x lpSubKey %s ulOptions 0x%x samDesired 0x%x phkResult %p\n",
hKey, lpSubKey, ulOptions, samDesired, phkResult);
Status = MapDefaultKey (&KeyHandle, hKey);
@ -1688,7 +1688,7 @@ RegOpenKeyExW (HKEY hKey,
HANDLE KeyHandle;
NTSTATUS Status;
DPRINT("RegOpenKeyExW hKey 0x%x lpSubKey %S ulOptions 0x%x samDesired 0x%x phkResult %p\n",
TRACE("RegOpenKeyExW hKey 0x%x lpSubKey %S ulOptions 0x%x samDesired 0x%x phkResult %p\n",
hKey, lpSubKey, ulOptions, samDesired, phkResult);
Status = MapDefaultKey (&KeyHandle, hKey);
@ -1837,7 +1837,7 @@ ReadTokenSid:
RtlAppendUnicodeToString(&UserClassesKeyRoot,
UserClassesKeySuffix);
DPRINT("RegOpenUserClassesRoot: Absolute path: %wZ\n", &UserClassesKeyRoot);
TRACE("RegOpenUserClassesRoot: Absolute path: %wZ\n", &UserClassesKeyRoot);
/*
* Open the key
@ -2001,7 +2001,7 @@ RegQueryInfoKeyW (HKEY hKey,
FullInfo,
FullInfoSize,
&Length);
DPRINT("NtQueryKey() returned status 0x%X\n", Status);
TRACE("NtQueryKey() returned status 0x%X\n", Status);
if (!NT_SUCCESS(Status))
{
if (lpClass != NULL)
@ -2014,37 +2014,37 @@ RegQueryInfoKeyW (HKEY hKey,
return RtlNtStatusToDosError (Status);
}
DPRINT("SubKeys %d\n", FullInfo->SubKeys);
TRACE("SubKeys %d\n", FullInfo->SubKeys);
if (lpcSubKeys != NULL)
{
*lpcSubKeys = FullInfo->SubKeys;
}
DPRINT("MaxNameLen %lu\n", FullInfo->MaxNameLen);
TRACE("MaxNameLen %lu\n", FullInfo->MaxNameLen);
if (lpcbMaxSubKeyLen != NULL)
{
*lpcbMaxSubKeyLen = FullInfo->MaxNameLen / sizeof(WCHAR) + 1;
}
DPRINT("MaxClassLen %lu\n", FullInfo->MaxClassLen);
TRACE("MaxClassLen %lu\n", FullInfo->MaxClassLen);
if (lpcbMaxClassLen != NULL)
{
*lpcbMaxClassLen = FullInfo->MaxClassLen / sizeof(WCHAR) + 1;
}
DPRINT("Values %lu\n", FullInfo->Values);
TRACE("Values %lu\n", FullInfo->Values);
if (lpcValues != NULL)
{
*lpcValues = FullInfo->Values;
}
DPRINT("MaxValueNameLen %lu\n", FullInfo->MaxValueNameLen);
TRACE("MaxValueNameLen %lu\n", FullInfo->MaxValueNameLen);
if (lpcbMaxValueNameLen != NULL)
{
*lpcbMaxValueNameLen = FullInfo->MaxValueNameLen / sizeof(WCHAR) + 1;
}
DPRINT("MaxValueDataLen %lu\n", FullInfo->MaxValueDataLen);
TRACE("MaxValueDataLen %lu\n", FullInfo->MaxValueDataLen);
if (lpcbMaxValueLen != NULL)
{
*lpcbMaxValueLen = FullInfo->MaxValueDataLen;
@ -2124,7 +2124,7 @@ RegQueryMultipleValuesA (HKEY hKey,
*ldwTotsize = 0;
DPRINT ("RegQueryMultipleValuesA(%p,%p,%ld,%p,%p=%ld)\n",
TRACE("RegQueryMultipleValuesA(%p,%p,%ld,%p,%p=%ld)\n",
hKey, val_list, num_vals, lpValueBuf, ldwTotsize, *ldwTotsize);
for (i = 0; i < num_vals; i++)
@ -2188,7 +2188,7 @@ RegQueryMultipleValuesW (HKEY hKey,
*ldwTotsize = 0;
DPRINT ("RegQueryMultipleValuesW(%p,%p,%ld,%p,%p=%ld)\n",
TRACE ("RegQueryMultipleValuesW(%p,%p,%ld,%p,%p=%ld)\n",
hKey, val_list, num_vals, lpValueBuf, ldwTotsize, *ldwTotsize);
for (i = 0; i < num_vals; i++)
@ -2252,7 +2252,7 @@ RegQueryValueExW (HKEY hKey,
LONG ErrorCode = ERROR_SUCCESS;
ULONG MaxCopy = lpcbData != NULL && lpData != NULL ? *lpcbData : 0;
DPRINT("hKey 0x%X lpValueName %S lpData 0x%X lpcbData %d\n",
TRACE("hKey 0x%X lpValueName %S lpData 0x%X lpcbData %d\n",
hKey, lpValueName, lpData, lpcbData ? *lpcbData : 0);
Status = MapDefaultKey (&KeyHandle,
@ -2284,7 +2284,7 @@ RegQueryValueExW (HKEY hKey,
ValueInfo,
BufferSize,
&ResultSize);
DPRINT("Status 0x%X\n", Status);
TRACE("Status 0x%X\n", Status);
if (Status == STATUS_BUFFER_OVERFLOW)
{
/* Return ERROR_SUCCESS and the buffer space needed for a successful call */
@ -2325,7 +2325,7 @@ RegQueryValueExW (HKEY hKey,
if (lpcbData != NULL)
{
*lpcbData = (ResultSize - FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data[0]));
DPRINT("(string) Returning Size: %lu\n", *lpcbData);
TRACE("(string) Returning Size: %lu\n", *lpcbData);
}
}
else
@ -2333,11 +2333,11 @@ RegQueryValueExW (HKEY hKey,
if (lpcbData != NULL)
{
*lpcbData = ResultSize - FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data[0]);
DPRINT("(other) Returning Size: %lu\n", *lpcbData);
TRACE("(other) Returning Size: %lu\n", *lpcbData);
}
}
DPRINT("Type %d Size %d\n", ValueInfo->Type, ValueInfo->DataLength);
TRACE("Type %d Size %d\n", ValueInfo->Type, ValueInfo->DataLength);
RtlFreeHeap (ProcessHeap,
0,
@ -2367,7 +2367,7 @@ RegQueryValueExA (HKEY hKey,
DWORD Length;
DWORD Type;
DPRINT("hKey 0x%X lpValueName %s lpData 0x%X lpcbData %d\n",
TRACE("hKey 0x%X lpValueName %s lpData 0x%X lpcbData %d\n",
hKey, lpValueName, lpData, lpcbData ? *lpcbData : 0);
if (lpData != NULL && lpcbData == NULL)
@ -2404,7 +2404,7 @@ RegQueryValueExA (HKEY hKey,
&Type,
(lpData == NULL) ? NULL : (LPBYTE)ValueData.Buffer,
&Length);
DPRINT("ErrorCode %lu\n", ErrorCode);
TRACE("ErrorCode %lu\n", ErrorCode);
RtlFreeUnicodeString(&ValueName);
if (ErrorCode == ERROR_SUCCESS ||
@ -2473,7 +2473,7 @@ RegQueryValueA (HKEY hKey,
LONG ValueSize;
LONG ErrorCode;
DPRINT("hKey 0x%X lpSubKey %s lpValue %p lpcbValue %d\n",
TRACE("hKey 0x%X lpSubKey %s lpValue %p lpcbValue %d\n",
hKey, lpSubKey, lpValue, lpcbValue ? *lpcbValue : 0);
if (lpValue != NULL &&
@ -2562,7 +2562,7 @@ RegQueryValueW (HKEY hKey,
BOOL CloseRealKey;
NTSTATUS Status;
DPRINT("hKey 0x%X lpSubKey %S lpValue %p lpcbValue %d\n",
TRACE("hKey 0x%X lpSubKey %S lpValue %p lpcbValue %d\n",
hKey, lpSubKey, lpValue, lpcbValue ? *lpcbValue : 0);
Status = MapDefaultKey (&KeyHandle,

View file

@ -1,14 +1,612 @@
/* $Id$
*
* COPYRIGHT: See COPYING in the top level directory
* WINE COPYRIGHT:
* Copyright 1999, 2000 Juergen Schmied <juergen.schmied@debitel.net>
* Copyright 2003 CodeWeavers Inc. (Ulrich Czekalla)
*
* PROJECT: ReactOS system libraries
* FILE: lib/advapi32/sec/sid.c
* PURPOSE: Security ID functions
*/
#include <advapi32.h>
#include <debug.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;
static SID const 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};
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};
/* set last error code from NT status and get the proper boolean return value */
/* used for functions that are a simple wrapper around the corresponding ntdll API */
static inline BOOL set_ntstatus( NTSTATUS status )
{
if (status) SetLastError( RtlNtStatusToDosError( status ));
return !status;
}
#define WINE_SIZE_OF_WORLD_ACCESS_ACL (sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + sizeof(sidWorld) - sizeof(DWORD))
/* 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
*/
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\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 += 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,
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 */
}
*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;
}
/* Exported functions */
/*
* @implemented
@ -89,7 +687,92 @@ CopySid (DWORD nDestinationSidLength,
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;
}
/* Winehq cvs 20050916 */
/******************************************************************************
* ConvertStringSecurityDescriptorToSecurityDescriptorA [ADVAPI32.@]
* @implemented
*/
BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorA(
LPCSTR StringSecurityDescriptor,
DWORD StringSDRevision,
PSECURITY_DESCRIPTOR* SecurityDescriptor,
PULONG SecurityDescriptorSize)
{
UINT len;
BOOL ret = FALSE;
LPWSTR StringSecurityDescriptorW;
len = MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, NULL, 0);
StringSecurityDescriptorW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
if (StringSecurityDescriptorW)
{
MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, StringSecurityDescriptorW, len);
ret = ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptorW,
StringSDRevision, SecurityDescriptor,
SecurityDescriptorSize);
HeapFree(GetProcessHeap(), 0, StringSecurityDescriptorW);
}
return ret;
}
/*
* @implemented
@ -312,7 +995,7 @@ EqualDomainSid(IN PSID pSid1,
IN PSID pSid2,
OUT BOOL* pfEqual)
{
DPRINT1("%s() not implemented!\n", __FUNCTION__);
FIXME("%s() not implemented!\n", __FUNCTION__);
return FALSE;
}
@ -325,7 +1008,7 @@ GetWindowsAccountDomainSid(IN PSID pSid,
OUT PSID ppDomainSid,
IN OUT DWORD* cbSid)
{
DPRINT1("%s() not implemented!\n", __FUNCTION__);
FIXME("%s() not implemented!\n", __FUNCTION__);
return FALSE;
}
@ -339,7 +1022,7 @@ CreateWellKnownSid(IN WELL_KNOWN_SID_TYPE WellKnownSidType,
OUT PSID pSid,
IN OUT DWORD* cbSid)
{
DPRINT1("%s() not implemented!\n", __FUNCTION__);
FIXME("unimplemented!\n", __FUNCTION__);
return FALSE;
}