Author: akhaldi
Date: Mon May 25 18:46:12 2015
New Revision: 67915
URL:
http://svn.reactos.org/svn/reactos?rev=67915&view=rev
Log:
[ADVAPI32_WINETEST] Sync with Wine Staging 1.7.43.
Modified:
trunk/rostests/winetests/advapi32/CMakeLists.txt
trunk/rostests/winetests/advapi32/security.c
trunk/rostests/winetests/advapi32/service.c
Modified: trunk/rostests/winetests/advapi32/CMakeLists.txt
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/advapi32/CMakeL…
==============================================================================
--- trunk/rostests/winetests/advapi32/CMakeLists.txt [iso-8859-1] (original)
+++ trunk/rostests/winetests/advapi32/CMakeLists.txt [iso-8859-1] Mon May 25 18:46:12
2015
@@ -22,5 +22,5 @@
endif()
set_module_type(advapi32_winetest win32cui)
-add_importlibs(advapi32_winetest advapi32 ole32 msvcrt kernel32)
+add_importlibs(advapi32_winetest advapi32 ole32 msvcrt kernel32 ntdll)
add_cd_file(TARGET advapi32_winetest DESTINATION reactos/bin FOR all)
Modified: trunk/rostests/winetests/advapi32/security.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/advapi32/securi…
==============================================================================
--- trunk/rostests/winetests/advapi32/security.c [iso-8859-1] (original)
+++ trunk/rostests/winetests/advapi32/security.c [iso-8859-1] Mon May 25 18:46:12 2015
@@ -28,6 +28,7 @@
#include "windef.h"
#include "winbase.h"
#include "winerror.h"
+#include "wine/winternl.h"
#include "aclapi.h"
#include "winnt.h"
#include "sddl.h"
@@ -61,29 +62,6 @@
#define THREAD_ALL_ACCESS_NT4 (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x3ff)
#define THREAD_ALL_ACCESS_VISTA (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xffff)
-
-/* copied from Wine winternl.h - not included in the Windows SDK */
-typedef enum _OBJECT_INFORMATION_CLASS {
- ObjectBasicInformation,
- ObjectNameInformation,
- ObjectTypeInformation,
- ObjectAllInformation,
- ObjectDataInformation
-} OBJECT_INFORMATION_CLASS, *POBJECT_INFORMATION_CLASS;
-
-typedef struct _OBJECT_BASIC_INFORMATION {
- ULONG Attributes;
- ACCESS_MASK GrantedAccess;
- ULONG HandleCount;
- ULONG PointerCount;
- ULONG PagedPoolUsage;
- ULONG NonPagedPoolUsage;
- ULONG Reserved[3];
- ULONG NameInformationLength;
- ULONG TypeInformationLength;
- ULONG SecurityDescriptorLength;
- LARGE_INTEGER CreateTime;
-} OBJECT_BASIC_INFORMATION, *POBJECT_BASIC_INFORMATION;
#define expect_eq(expr, value, type, format) { type ret_ = expr; ok((value) == ret_,
#expr " expected " format " got " format "\n", (value),
(ret_)); }
@@ -150,6 +128,10 @@
PLUID_AND_ATTRIBUTES, DWORD,
PSID_AND_ATTRIBUTES, PHANDLE);
static BOOL (WINAPI *pGetAclInformation)(PACL,LPVOID,DWORD,ACL_INFORMATION_CLASS);
static BOOL (WINAPI *pGetAce)(PACL,DWORD,LPVOID*);
+static NTSTATUS (WINAPI
*pNtSetSecurityObject)(HANDLE,SECURITY_INFORMATION,PSECURITY_DESCRIPTOR);
+static NTSTATUS (WINAPI
*pNtCreateFile)(PHANDLE,ACCESS_MASK,POBJECT_ATTRIBUTES,PIO_STATUS_BLOCK,PLARGE_INTEGER,ULONG,ULONG,ULONG,ULONG,PVOID,ULONG);
+static BOOL (WINAPI
*pRtlDosPathNameToNtPathName_U)(LPCWSTR,PUNICODE_STRING,PWSTR*,CURDIR*);
+static NTSTATUS (WINAPI
*pRtlAnsiStringToUnicodeString)(PUNICODE_STRING,PCANSI_STRING,BOOLEAN);
static HMODULE hmod;
static int myARGC;
@@ -176,6 +158,10 @@
hntdll = GetModuleHandleA("ntdll.dll");
pNtQueryObject = (void *)GetProcAddress( hntdll, "NtQueryObject" );
pNtAccessCheck = (void *)GetProcAddress( hntdll, "NtAccessCheck" );
+ pNtSetSecurityObject = (void *)GetProcAddress(hntdll,
"NtSetSecurityObject");
+ pNtCreateFile = (void *)GetProcAddress(hntdll, "NtCreateFile");
+ pRtlDosPathNameToNtPathName_U = (void *)GetProcAddress(hntdll,
"RtlDosPathNameToNtPathName_U");
+ pRtlAnsiStringToUnicodeString = (void *)GetProcAddress(hntdll,
"RtlAnsiStringToUnicodeString");
hmod = GetModuleHandleA("advapi32.dll");
pAddAccessAllowedAceEx = (void *)GetProcAddress(hmod,
"AddAccessAllowedAceEx");
@@ -2531,19 +2517,21 @@
static void test_process_security(void)
{
BOOL res;
+ PTOKEN_USER user;
PTOKEN_OWNER owner;
PTOKEN_PRIMARY_GROUP group;
- PSID AdminSid = NULL, UsersSid = NULL;
+ PSID AdminSid = NULL, UsersSid = NULL, UserSid = NULL;
PACL Acl = NULL, ThreadAcl = NULL;
SECURITY_DESCRIPTOR *SecurityDescriptor = NULL, *ThreadSecurityDescriptor = NULL;
- char buffer[MAX_PATH];
+ char buffer[MAX_PATH], account[MAX_PATH], domain[MAX_PATH];
PROCESS_INFORMATION info;
STARTUPINFOA startup;
SECURITY_ATTRIBUTES psa, tsa;
HANDLE token, event;
- DWORD size;
+ DWORD size, acc_size, dom_size, ret;
SID_IDENTIFIER_AUTHORITY SIDAuthWorld = { SECURITY_WORLD_SID_AUTHORITY };
PSID EveryoneSid = NULL;
+ SID_NAME_USE use;
Acl = HeapAlloc(GetProcessHeap(), 0, 256);
res = InitializeAcl(Acl, 256, ACL_REVISION);
@@ -2575,7 +2563,8 @@
owner = HeapAlloc(GetProcessHeap(), 0, size);
res = GetTokenInformation( token, TokenOwner, owner, size, &size );
ok(res, "GetTokenInformation failed with error %d\n", GetLastError());
- AdminSid = ((TOKEN_OWNER*)owner)->Owner;
+ AdminSid = owner->Owner;
+ test_sid_str(AdminSid);
res = GetTokenInformation( token, TokenPrimaryGroup, NULL, 0, &size );
ok(!res, "Expected failure, got %d\n", res);
@@ -2585,13 +2574,34 @@
group = HeapAlloc(GetProcessHeap(), 0, size);
res = GetTokenInformation( token, TokenPrimaryGroup, group, size, &size );
ok(res, "GetTokenInformation failed with error %d\n", GetLastError());
- UsersSid = ((TOKEN_PRIMARY_GROUP*)group)->PrimaryGroup;
+ UsersSid = group->PrimaryGroup;
+ test_sid_str(UsersSid);
+
+ acc_size = sizeof(account);
+ dom_size = sizeof(domain);
+ ret = LookupAccountSidA( NULL, UsersSid, account, &acc_size, domain,
&dom_size, &use );
+ ok(ret, "LookupAccountSid failed with %d\n", ret);
+ ok(use == SidTypeGroup, "expect SidTypeGroup, got %d\n", use);
+ ok(!strcmp(account, "None"), "expect None, got %s\n", account);
+
+ res = GetTokenInformation( token, TokenUser, NULL, 0, &size );
+ ok(!res, "Expected failure, got %d\n", res);
+ ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
+ "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
+
+ user = HeapAlloc(GetProcessHeap(), 0, size);
+ res = GetTokenInformation( token, TokenUser, user, size, &size );
+ ok(res, "GetTokenInformation failed with error %d\n", GetLastError());
+ UserSid = user->User.Sid;
+ test_sid_str(UserSid);
+ ok(EqualPrefixSid(UsersSid, UserSid), "TokenPrimaryGroup Sid and TokenUser Sid
don't match.\n");
CloseHandle( token );
if (!res)
{
HeapFree(GetProcessHeap(), 0, group);
HeapFree(GetProcessHeap(), 0, owner);
+ HeapFree(GetProcessHeap(), 0, user);
HeapFree(GetProcessHeap(), 0, Acl);
return;
}
@@ -2698,6 +2708,7 @@
CloseHandle( event );
HeapFree(GetProcessHeap(), 0, group);
HeapFree(GetProcessHeap(), 0, owner);
+ HeapFree(GetProcessHeap(), 0, user);
HeapFree(GetProcessHeap(), 0, Acl);
HeapFree(GetProcessHeap(), 0, SecurityDescriptor);
HeapFree(GetProcessHeap(), 0, ThreadAcl);
@@ -3142,6 +3153,98 @@
HeapFree(GetProcessHeap(), 0, OldAcl);
}
+/* helper function for test_CreateDirectoryA */
+static void get_nt_pathW(const char *name, UNICODE_STRING *nameW)
+{
+ UNICODE_STRING strW;
+ ANSI_STRING str;
+ NTSTATUS status;
+ BOOLEAN ret;
+ RtlInitAnsiString(&str, name);
+
+ status = pRtlAnsiStringToUnicodeString(&strW, &str, TRUE);
+ ok(!status, "RtlAnsiStringToUnicodeString failed with %08x\n", status);
+
+ ret = pRtlDosPathNameToNtPathName_U(strW.Buffer, nameW, NULL, NULL);
+ ok(ret, "RtlDosPathNameToNtPathName_U failed\n");
+
+ RtlFreeUnicodeString(&strW);
+}
+
+static void test_inherited_dacl(PACL dacl, PSID admin_sid, PSID user_sid, DWORD flags,
DWORD mask,
+ BOOL todo_count, BOOL todo_sid, BOOL todo_flags, int
line)
+{
+ ACL_SIZE_INFORMATION acl_size;
+ ACCESS_ALLOWED_ACE *ace;
+ BOOL bret;
+
+ bret = pGetAclInformation(dacl, &acl_size, sizeof(acl_size),
AclSizeInformation);
+ ok_(__FILE__, line)(bret, "GetAclInformation failed\n");
+
+ if (todo_count)
+ todo_wine
+ ok_(__FILE__, line)(acl_size.AceCount == 2,
+ "GetAclInformation returned unexpected entry count (%d != 2)\n",
+ acl_size.AceCount);
+ else
+ ok_(__FILE__, line)(acl_size.AceCount == 2,
+ "GetAclInformation returned unexpected entry count (%d != 2)\n",
+ acl_size.AceCount);
+
+ if (acl_size.AceCount > 0)
+ {
+ bret = pGetAce(dacl, 0, (VOID **)&ace);
+ ok_(__FILE__, line)(bret, "Failed to get Current User ACE\n");
+
+ bret = EqualSid(&ace->SidStart, user_sid);
+ if (todo_sid)
+ todo_wine
+ ok_(__FILE__, line)(bret, "Current User ACE != Current User
SID\n");
+ else
+ ok_(__FILE__, line)(bret, "Current User ACE != Current User
SID\n");
+
+ if (todo_flags)
+ todo_wine
+ ok_(__FILE__, line)(((ACE_HEADER *)ace)->AceFlags == flags,
+ "Current User ACE has unexpected flags (0x%x != 0x%x)\n",
+ ((ACE_HEADER *)ace)->AceFlags, flags);
+ else
+ ok_(__FILE__, line)(((ACE_HEADER *)ace)->AceFlags == flags,
+ "Current User ACE has unexpected flags (0x%x != 0x%x)\n",
+ ((ACE_HEADER *)ace)->AceFlags, flags);
+
+ ok_(__FILE__, line)(ace->Mask == mask,
+ "Current User ACE has unexpected mask (0x%x != 0x%x)\n",
+ ace->Mask, mask);
+ }
+ if (acl_size.AceCount > 1)
+ {
+ bret = pGetAce(dacl, 1, (VOID **)&ace);
+ ok_(__FILE__, line)(bret, "Failed to get Administators Group ACE\n");
+
+ bret = EqualSid(&ace->SidStart, admin_sid);
+ if (todo_sid)
+ todo_wine
+ ok_(__FILE__, line)(bret, "Administators Group ACE != Administators
Group SID\n");
+ else
+ ok_(__FILE__, line)(bret, "Administators Group ACE != Administators
Group SID\n");
+
+ if (todo_flags)
+ todo_wine
+ ok_(__FILE__, line)(((ACE_HEADER *)ace)->AceFlags == flags,
+ "Administators Group ACE has unexpected flags (0x%x !=
0x%x)\n",
+ ((ACE_HEADER *)ace)->AceFlags, flags);
+ else
+ ok_(__FILE__, line)(((ACE_HEADER *)ace)->AceFlags == flags,
+ "Administators Group ACE has unexpected flags (0x%x !=
0x%x)\n",
+ ((ACE_HEADER *)ace)->AceFlags, flags);
+
+ ok_(__FILE__, line)(ace->Mask == mask,
+ "Administators Group ACE has unexpected mask (0x%x != 0x%x)\n",
+ ace->Mask, mask);
+ }
+}
+
static void test_CreateDirectoryA(void)
{
char admin_ptr[sizeof(SID)+sizeof(ULONG)*SID_MAX_SUB_AUTHORITIES], *user;
@@ -3150,17 +3253,20 @@
char sd[SECURITY_DESCRIPTOR_MIN_LENGTH];
PSECURITY_DESCRIPTOR pSD = &sd;
ACL_SIZE_INFORMATION acl_size;
- ACCESS_ALLOWED_ACE *ace;
+ UNICODE_STRING tmpfileW;
SECURITY_ATTRIBUTES sa;
+ OBJECT_ATTRIBUTES attr;
char tmpfile[MAX_PATH];
char tmpdir[MAX_PATH];
HANDLE token, hTemp;
+ IO_STATUS_BLOCK io;
struct _SID *owner;
BOOL bret = TRUE;
+ NTSTATUS status;
DWORD error;
PACL pDacl;
- if (!pGetNamedSecurityInfoA || !pCreateWellKnownSid)
+ if (!pGetSecurityInfo || !pGetNamedSecurityInfoA || !pCreateWellKnownSid)
{
win_skip("Required functions are not available\n");
return;
@@ -3218,72 +3324,288 @@
goto done;
}
ok(!error, "GetNamedSecurityInfo failed with error %d\n", error);
-
+ test_inherited_dacl(pDacl, admin_sid, user_sid,
OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE,
+ 0x1f01ff, FALSE, FALSE, FALSE, __LINE__);
+ LocalFree(pSD);
+
+ /* Test inheritance of ACLs in CreateFile without security descriptor */
+ strcpy(tmpfile, tmpdir);
+ lstrcatA(tmpfile, "/tmpfile");
+
+ hTemp = CreateFileA(tmpfile, GENERIC_WRITE, FILE_SHARE_READ, NULL,
+ CREATE_NEW, FILE_FLAG_DELETE_ON_CLOSE, NULL);
+ ok(hTemp != INVALID_HANDLE_VALUE, "CreateFile error %u\n",
GetLastError());
+
+ error = pGetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT,
+ OWNER_SECURITY_INFORMATION |
DACL_SECURITY_INFORMATION,
+ (PSID *)&owner, NULL, &pDacl, NULL,
&pSD);
+ ok(error == ERROR_SUCCESS, "Failed to get permissions on file\n");
+ test_inherited_dacl(pDacl, admin_sid, user_sid, INHERITED_ACE,
+ 0x1f01ff, FALSE, FALSE, FALSE, __LINE__);
+ LocalFree(pSD);
+ CloseHandle(hTemp);
+
+ /* Test inheritance of ACLs in CreateFile with security descriptor -
+ * When a security descriptor is set, then inheritance doesn't take effect */
+ pSD = &sd;
+ InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION);
+ pDacl = HeapAlloc(GetProcessHeap(), 0, sizeof(ACL));
+ bret = InitializeAcl(pDacl, sizeof(ACL), ACL_REVISION);
+ ok(bret, "Failed to initialize ACL\n");
+ bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE);
+ ok(bret, "Failed to add ACL to security desciptor\n");
+
+ strcpy(tmpfile, tmpdir);
+ lstrcatA(tmpfile, "/tmpfile");
+
+ sa.nLength = sizeof(sa);
+ sa.lpSecurityDescriptor = pSD;
+ sa.bInheritHandle = TRUE;
+ hTemp = CreateFileA(tmpfile, GENERIC_WRITE, FILE_SHARE_READ, &sa,
+ CREATE_NEW, FILE_FLAG_DELETE_ON_CLOSE, NULL);
+ ok(hTemp != INVALID_HANDLE_VALUE, "CreateFile error %u\n",
GetLastError());
+ HeapFree(GetProcessHeap(), 0, pDacl);
+
+ error = pGetSecurityInfo(hTemp, SE_FILE_OBJECT,
+ OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
+ (PSID *)&owner, NULL, &pDacl, NULL, &pSD);
+ ok(error == ERROR_SUCCESS, "GetNamedSecurityInfo failed with error %d\n",
error);
bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size),
AclSizeInformation);
ok(bret, "GetAclInformation failed\n");
- ok(acl_size.AceCount == 2, "GetAclInformation returned unexpected entry count
(%d != 2).\n",
+ ok(acl_size.AceCount == 0, "GetAclInformation returned unexpected entry count
(%d != 0).\n",
acl_size.AceCount);
- if (acl_size.AceCount > 0)
- {
- bret = pGetAce(pDacl, 0, (VOID **)&ace);
- ok(bret, "Failed to get Current User ACE.\n");
- bret = EqualSid(&ace->SidStart, user_sid);
- ok(bret, "Current User ACE != Current User SID.\n");
- ok(((ACE_HEADER *)ace)->AceFlags ==
(OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE),
- "Current User ACE has unexpected flags (0x%x != 0x03)\n",
- ((ACE_HEADER *)ace)->AceFlags);
- ok(ace->Mask == 0x1f01ff, "Current User ACE has unexpected mask (0x%x !=
0x1f01ff)\n",
- ace->Mask);
- }
- if (acl_size.AceCount > 1)
- {
- bret = pGetAce(pDacl, 1, (VOID **)&ace);
- ok(bret, "Failed to get Administators Group ACE.\n");
- bret = EqualSid(&ace->SidStart, admin_sid);
- ok(bret, "Administators Group ACE != Administators Group SID.\n");
- ok(((ACE_HEADER *)ace)->AceFlags ==
(OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE),
- "Administators Group ACE has unexpected flags (0x%x != 0x03)\n",
- ((ACE_HEADER *)ace)->AceFlags);
- ok(ace->Mask == 0x1f01ff, "Administators Group ACE has unexpected mask
(0x%x != 0x1f01ff)\n",
- ace->Mask);
- }
LocalFree(pSD);
- /* Test inheritance of ACLs */
+ error = pGetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT,
+ OWNER_SECURITY_INFORMATION |
DACL_SECURITY_INFORMATION,
+ (PSID *)&owner, NULL, &pDacl, NULL,
&pSD);
+ ok(error == ERROR_SUCCESS, "GetNamedSecurityInfo failed with error %d\n",
error);
+ bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size),
AclSizeInformation);
+ ok(bret, "GetAclInformation failed\n");
+ ok(acl_size.AceCount == 0, "GetAclInformation returned unexpected entry count
(%d != 0).\n",
+ acl_size.AceCount);
+ LocalFree(pSD);
+ CloseHandle(hTemp);
+
+ /* Test inheritance of ACLs in NtCreateFile without security descriptor */
strcpy(tmpfile, tmpdir);
lstrcatA(tmpfile, "/tmpfile");
- hTemp = CreateFileA(tmpfile, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_NEW,
- FILE_FLAG_DELETE_ON_CLOSE, NULL);
+ get_nt_pathW(tmpfile, &tmpfileW);
+
+ attr.Length = sizeof(attr);
+ attr.RootDirectory = 0;
+ attr.ObjectName = &tmpfileW;
+ attr.Attributes = OBJ_CASE_INSENSITIVE;
+ attr.SecurityDescriptor = NULL;
+ attr.SecurityQualityOfService = NULL;
+
+ status = pNtCreateFile(&hTemp, GENERIC_WRITE | DELETE, &attr, &io, NULL,
0,
+ FILE_SHARE_READ, FILE_CREATE, FILE_DELETE_ON_CLOSE, NULL, 0);
+ ok(!status, "NtCreateFile failed with %08x\n", status);
+ RtlFreeUnicodeString(&tmpfileW);
+
error = pGetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT,
- OWNER_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION,
(PSID*)&owner,
- NULL, &pDacl, NULL, &pSD);
- ok(error == ERROR_SUCCESS, "Failed to get permissions on file.\n");
+ OWNER_SECURITY_INFORMATION |
DACL_SECURITY_INFORMATION,
+ (PSID *)&owner, NULL, &pDacl, NULL,
&pSD);
+ ok(error == ERROR_SUCCESS, "Failed to get permissions on file\n");
+ test_inherited_dacl(pDacl, admin_sid, user_sid, INHERITED_ACE,
+ 0x1f01ff, FALSE, FALSE, FALSE, __LINE__);
+ LocalFree(pSD);
+ CloseHandle(hTemp);
+
+ /* Test inheritance of ACLs in NtCreateFile with security descriptor -
+ * When a security descriptor is set, then inheritance doesn't take effect */
+ pSD = &sd;
+ InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION);
+ pDacl = HeapAlloc(GetProcessHeap(), 0, sizeof(ACL));
+ bret = InitializeAcl(pDacl, sizeof(ACL), ACL_REVISION);
+ ok(bret, "Failed to initialize ACL\n");
+ bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE);
+ ok(bret, "Failed to add ACL to security desciptor\n");
+
+ strcpy(tmpfile, tmpdir);
+ lstrcatA(tmpfile, "/tmpfile");
+ get_nt_pathW(tmpfile, &tmpfileW);
+
+ attr.Length = sizeof(attr);
+ attr.RootDirectory = 0;
+ attr.ObjectName = &tmpfileW;
+ attr.Attributes = OBJ_CASE_INSENSITIVE;
+ attr.SecurityDescriptor = pSD;
+ attr.SecurityQualityOfService = NULL;
+
+ status = pNtCreateFile(&hTemp, GENERIC_WRITE | DELETE, &attr, &io, NULL,
0,
+ FILE_SHARE_READ, FILE_CREATE, FILE_DELETE_ON_CLOSE, NULL, 0);
+ ok(!status, "NtCreateFile failed with %08x\n", status);
+ RtlFreeUnicodeString(&tmpfileW);
+ HeapFree(GetProcessHeap(), 0, pDacl);
+
+ error = pGetSecurityInfo(hTemp, SE_FILE_OBJECT,
+ OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
+ (PSID *)&owner, NULL, &pDacl, NULL, &pSD);
+ ok(error == ERROR_SUCCESS, "GetNamedSecurityInfo failed with error %d\n",
error);
bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size),
AclSizeInformation);
ok(bret, "GetAclInformation failed\n");
- ok(acl_size.AceCount == 2, "GetAclInformation returned unexpected entry count
(%d != 2).\n",
+ todo_wine
+ ok(acl_size.AceCount == 0, "GetAclInformation returned unexpected entry count
(%d != 0).\n",
acl_size.AceCount);
- if (acl_size.AceCount > 0)
- {
- bret = pGetAce(pDacl, 0, (VOID **)&ace);
- ok(bret, "Inherited Failed to get Current User ACE.\n");
- bret = EqualSid(&ace->SidStart, user_sid);
- ok(bret, "Inherited Current User ACE != Current User SID.\n");
- ok(((ACE_HEADER *)ace)->AceFlags == INHERITED_ACE,
- "Inherited Current User ACE has unexpected flags (0x%x != 0x10)\n",
((ACE_HEADER *)ace)->AceFlags);
- ok(ace->Mask == 0x1f01ff, "Current User ACE has unexpected mask (0x%x !=
0x1f01ff)\n",
- ace->Mask);
- }
- if (acl_size.AceCount > 1)
- {
- bret = pGetAce(pDacl, 1, (VOID **)&ace);
- ok(bret, "Inherited Failed to get Administators Group ACE.\n");
- bret = EqualSid(&ace->SidStart, admin_sid);
- ok(bret, "Inherited Administators Group ACE != Administators Group
SID.\n");
- ok(((ACE_HEADER *)ace)->AceFlags == INHERITED_ACE,
- "Inherited Administators Group ACE has unexpected flags (0x%x !=
0x10)\n", ((ACE_HEADER *)ace)->AceFlags);
- ok(ace->Mask == 0x1f01ff, "Administators Group ACE has unexpected mask
(0x%x != 0x1f01ff)\n",
- ace->Mask);
- }
+ LocalFree(pSD);
+
+ error = pGetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT,
+ OWNER_SECURITY_INFORMATION |
DACL_SECURITY_INFORMATION,
+ (PSID *)&owner, NULL, &pDacl, NULL,
&pSD);
+ ok(error == ERROR_SUCCESS, "GetNamedSecurityInfo failed with error %d\n",
error);
+ bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size),
AclSizeInformation);
+ ok(bret, "GetAclInformation failed\n");
+ todo_wine
+ ok(acl_size.AceCount == 0, "GetAclInformation returned unexpected entry count
(%d != 0).\n",
+ acl_size.AceCount);
+ LocalFree(pSD);
+ CloseHandle(hTemp);
+
+ /* Test inheritance of ACLs in CreateDirectory without security descriptor */
+ strcpy(tmpfile, tmpdir);
+ lstrcatA(tmpfile, "/tmpdir");
+ bret = CreateDirectoryA(tmpfile, NULL);
+ ok(bret == TRUE, "CreateDirectoryA failed with error %u\n",
GetLastError());
+
+ error = pGetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT,
+ OWNER_SECURITY_INFORMATION |
DACL_SECURITY_INFORMATION,
+ (PSID *)&owner, NULL, &pDacl, NULL,
&pSD);
+ ok(error == ERROR_SUCCESS, "Failed to get permissions on file\n");
+ test_inherited_dacl(pDacl, admin_sid, user_sid,
+ OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERITED_ACE,
+ 0x1f01ff, FALSE, FALSE, FALSE, __LINE__);
+ LocalFree(pSD);
+ bret = RemoveDirectoryA(tmpfile);
+ ok(bret == TRUE, "RemoveDirectoryA failed with error %u\n",
GetLastError());
+
+ /* Test inheritance of ACLs in CreateDirectory with security descriptor */
+ pSD = &sd;
+ InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION);
+ pDacl = HeapAlloc(GetProcessHeap(), 0, sizeof(ACL));
+ bret = InitializeAcl(pDacl, sizeof(ACL), ACL_REVISION);
+ ok(bret, "Failed to initialize ACL\n");
+ bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE);
+ ok(bret, "Failed to add ACL to security desciptor\n");
+
+ strcpy(tmpfile, tmpdir);
+ lstrcatA(tmpfile, "/tmpdir1");
+
+ sa.nLength = sizeof(sa);
+ sa.lpSecurityDescriptor = pSD;
+ sa.bInheritHandle = TRUE;
+ bret = CreateDirectoryA(tmpfile, &sa);
+ ok(bret == TRUE, "CreateDirectoryA failed with error %u\n",
GetLastError());
+ HeapFree(GetProcessHeap(), 0, pDacl);
+
+ error = pGetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT,
+ OWNER_SECURITY_INFORMATION |
DACL_SECURITY_INFORMATION,
+ (PSID *)&owner, NULL, &pDacl, NULL,
&pSD);
+ ok(error == ERROR_SUCCESS, "GetNamedSecurityInfo failed with error %d\n",
error);
+ bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size),
AclSizeInformation);
+ ok(bret, "GetAclInformation failed\n");
+ ok(acl_size.AceCount == 0, "GetAclInformation returned unexpected entry count
(%d != 0).\n",
+ acl_size.AceCount);
+ LocalFree(pSD);
+
+ SetLastError(0xdeadbeef);
+ bret = RemoveDirectoryA(tmpfile);
+ error = GetLastError();
+ ok(bret == FALSE, "RemoveDirectoryA unexpected succeeded\n");
+ ok(error == ERROR_ACCESS_DENIED, "expected ERROR_ACCESS_DENIED, got %u\n",
error);
+
+ pSD = &sd;
+ InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION);
+ pDacl = HeapAlloc(GetProcessHeap(), 0, 100);
+ bret = InitializeAcl(pDacl, 100, ACL_REVISION);
+ ok(bret, "Failed to initialize ACL.\n");
+ bret = pAddAccessAllowedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, user_sid);
+ ok(bret, "Failed to add Current User to ACL.\n");
+ bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE);
+ ok(bret, "Failed to add ACL to security desciptor.\n");
+ error = pSetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
NULL,
+ NULL, pDacl, NULL);
+ ok(error == ERROR_SUCCESS, "SetNamedSecurityInfoA failed with error %u\n",
error);
+ HeapFree(GetProcessHeap(), 0, pDacl);
+
+ bret = RemoveDirectoryA(tmpfile);
+ ok(bret == TRUE, "RemoveDirectoryA failed with error %u\n",
GetLastError());
+
+ /* Test inheritance of ACLs in NtCreateFile(..., FILE_DIRECTORY_FILE, ...) without
security descriptor */
+ strcpy(tmpfile, tmpdir);
+ lstrcatA(tmpfile, "/tmpdir");
+ get_nt_pathW(tmpfile, &tmpfileW);
+
+ attr.Length = sizeof(attr);
+ attr.RootDirectory = 0;
+ attr.ObjectName = &tmpfileW;
+ attr.Attributes = OBJ_CASE_INSENSITIVE;
+ attr.SecurityDescriptor = NULL;
+ attr.SecurityQualityOfService = NULL;
+
+ status = pNtCreateFile(&hTemp, GENERIC_READ | DELETE, &attr, &io, NULL,
FILE_ATTRIBUTE_NORMAL,
+ FILE_SHARE_READ, FILE_CREATE, FILE_DIRECTORY_FILE |
FILE_DELETE_ON_CLOSE, NULL, 0);
+ ok(!status, "NtCreateFile failed with %08x\n", status);
+ RtlFreeUnicodeString(&tmpfileW);
+
+ error = pGetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT,
+ OWNER_SECURITY_INFORMATION |
DACL_SECURITY_INFORMATION,
+ (PSID *)&owner, NULL, &pDacl, NULL,
&pSD);
+ ok(error == ERROR_SUCCESS, "Failed to get permissions on file\n");
+ test_inherited_dacl(pDacl, admin_sid, user_sid,
+ OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERITED_ACE,
+ 0x1f01ff, FALSE, FALSE, FALSE, __LINE__);
+ LocalFree(pSD);
+ CloseHandle(hTemp);
+
+ /* Test inheritance of ACLs in NtCreateFile(..., FILE_DIRECTORY_FILE, ...) with
security descriptor */
+ pSD = &sd;
+ InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION);
+ pDacl = HeapAlloc(GetProcessHeap(), 0, sizeof(ACL));
+ bret = InitializeAcl(pDacl, sizeof(ACL), ACL_REVISION);
+ ok(bret, "Failed to initialize ACL\n");
+ bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE);
+ ok(bret, "Failed to add ACL to security desciptor\n");
+
+ strcpy(tmpfile, tmpdir);
+ lstrcatA(tmpfile, "/tmpdir2");
+ get_nt_pathW(tmpfile, &tmpfileW);
+
+ attr.Length = sizeof(attr);
+ attr.RootDirectory = 0;
+ attr.ObjectName = &tmpfileW;
+ attr.Attributes = OBJ_CASE_INSENSITIVE;
+ attr.SecurityDescriptor = pSD;
+ attr.SecurityQualityOfService = NULL;
+
+ status = pNtCreateFile(&hTemp, GENERIC_READ | DELETE, &attr, &io, NULL,
FILE_ATTRIBUTE_NORMAL,
+ FILE_SHARE_READ, FILE_CREATE, FILE_DIRECTORY_FILE |
FILE_DELETE_ON_CLOSE, NULL, 0);
+ ok(!status, "NtCreateFile failed with %08x\n", status);
+ RtlFreeUnicodeString(&tmpfileW);
+ HeapFree(GetProcessHeap(), 0, pDacl);
+
+ error = pGetSecurityInfo(hTemp, SE_FILE_OBJECT,
+ OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
+ (PSID *)&owner, NULL, &pDacl, NULL, &pSD);
+ ok(error == ERROR_SUCCESS, "GetNamedSecurityInfo failed with error %d\n",
error);
+ bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size),
AclSizeInformation);
+ ok(bret, "GetAclInformation failed\n");
+ todo_wine
+ ok(acl_size.AceCount == 0, "GetAclInformation returned unexpected entry count
(%d != 0).\n",
+ acl_size.AceCount);
+ LocalFree(pSD);
+
+ error = pGetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT,
+ OWNER_SECURITY_INFORMATION |
DACL_SECURITY_INFORMATION,
+ (PSID *)&owner, NULL, &pDacl, NULL,
&pSD);
+ ok(error == ERROR_SUCCESS, "GetNamedSecurityInfo failed with error %d\n",
error);
+ bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size),
AclSizeInformation);
+ ok(bret, "GetAclInformation failed\n");
+ todo_wine
+ ok(acl_size.AceCount == 0, "GetAclInformation returned unexpected entry count
(%d != 0).\n",
+ acl_size.AceCount);
+ LocalFree(pSD);
CloseHandle(hTemp);
done:
@@ -3303,7 +3625,7 @@
char invalid_path[] = "/an invalid file path";
int users_ace_id = -1, admins_ace_id = -1, i;
char software_key[] = "MACHINE\\Software";
- char sd[SECURITY_DESCRIPTOR_MIN_LENGTH];
+ char sd[SECURITY_DESCRIPTOR_MIN_LENGTH+sizeof(void*)];
SECURITY_DESCRIPTOR_CONTROL control;
ACL_SIZE_INFORMATION acl_size;
CHAR windows_dir[MAX_PATH];
@@ -3315,11 +3637,12 @@
BOOL owner_defaulted;
BOOL group_defaulted;
BOOL dacl_defaulted;
- HANDLE token, hTemp;
+ HANDLE token, hTemp, h;
PSID owner, group;
BOOL dacl_present;
PACL pDacl;
BYTE flags;
+ NTSTATUS status;
if (!pSetNamedSecurityInfoA || !pGetNamedSecurityInfoA || !pCreateWellKnownSid)
{
@@ -3424,8 +3747,8 @@
bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE);
ok(bret, "Failed to add ACL to security desciptor.\n");
GetTempFileNameA(".", "foo", 0, tmpfile);
- hTemp = CreateFileA(tmpfile, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING,
- FILE_FLAG_DELETE_ON_CLOSE, NULL);
+ hTemp = CreateFileA(tmpfile, WRITE_DAC|GENERIC_WRITE,
FILE_SHARE_DELETE|FILE_SHARE_READ,
+ NULL, OPEN_EXISTING, FILE_FLAG_DELETE_ON_CLOSE, NULL);
SetLastError(0xdeadbeef);
error = pSetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
NULL,
NULL, pDacl, NULL);
@@ -3460,8 +3783,8 @@
ok(bret, "Current User ACE != Current User SID.\n");
ok(((ACE_HEADER *)ace)->AceFlags == 0,
"Current User ACE has unexpected flags (0x%x != 0x0)\n",
((ACE_HEADER *)ace)->AceFlags);
- ok(ace->Mask == 0x1f01ff, "Current User ACE has unexpected mask (0x%x !=
0x1f01ff)\n",
- ace->Mask);
+ ok(ace->Mask == 0x1f01ff,
+ "Current User ACE has unexpected mask (0x%x != 0x1f01ff)\n",
ace->Mask);
}
if (acl_size.AceCount > 1)
{
@@ -3475,74 +3798,119 @@
"Administators Group ACE has unexpected mask (0x%x != 0x1f01ff)\n",
ace->Mask);
}
LocalFree(pSD);
- CloseHandle(hTemp);
-
- /* Create security descriptor with no inheritance and test that it comes back the
same */
- pSD = &sd;
+
+ /* show that setting empty DACL is not removing all file permissions */
+ pDacl = HeapAlloc(GetProcessHeap(), 0, sizeof(ACL));
+ bret = InitializeAcl(pDacl, sizeof(ACL), ACL_REVISION);
+ ok(bret, "Failed to initialize ACL.\n");
+ error = pSetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
+ NULL, NULL, pDacl, NULL);
+ ok(!error, "SetNamedSecurityInfoA failed with error %d\n", error);
+ HeapFree(GetProcessHeap(), 0, pDacl);
+
+ error = pGetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
+ NULL, NULL, &pDacl, NULL, &pSD);
+ ok(!error, "GetNamedSecurityInfo failed with error %d\n", error);
+
+ bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size),
AclSizeInformation);
+ ok(bret, "GetAclInformation failed\n");
+ if (acl_size.AceCount > 0)
+ {
+ bret = pGetAce(pDacl, 0, (VOID **)&ace);
+ ok(bret, "Failed to get ACE.\n");
+ ok(((ACE_HEADER *)ace)->AceFlags & INHERITED_ACE,
+ "ACE has unexpected flags: 0x%x\n", ((ACE_HEADER
*)ace)->AceFlags);
+ }
+ LocalFree(pSD);
+
+ h = CreateFileA(tmpfile, GENERIC_READ,
FILE_SHARE_DELETE|FILE_SHARE_WRITE|FILE_SHARE_READ,
+ NULL, OPEN_EXISTING, 0, NULL);
+ ok(h != INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError());
+ CloseHandle(h);
+
+ /* test setting NULL DACL */
+ error = pSetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT,
+ DACL_SECURITY_INFORMATION, NULL, NULL, NULL, NULL);
+ ok(!error, "SetNamedSecurityInfoA failed with error %d\n", error);
+
+ error = pGetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
+ NULL, NULL, &pDacl, NULL, &pSD);
+ ok(!error, "GetNamedSecurityInfo failed with error %d\n", error);
+ todo_wine ok(!pDacl, "pDacl != NULL\n");
+ LocalFree(pSD);
+
+ h = CreateFileA(tmpfile, GENERIC_READ,
FILE_SHARE_DELETE|FILE_SHARE_WRITE|FILE_SHARE_READ,
+ NULL, OPEN_EXISTING, 0, NULL);
+ ok(h != INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError());
+ CloseHandle(h);
+
+ /* NtSetSecurityObject doesn't inherit DACL entries */
+ pSD = sd+sizeof(void*)-((ULONG_PTR)sd)%sizeof(void*);
+ InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION);
pDacl = HeapAlloc(GetProcessHeap(), 0, 100);
- InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION);
- pCreateWellKnownSid(WinBuiltinAdministratorsSid, NULL, admin_sid, &sid_size);
+ bret = InitializeAcl(pDacl, sizeof(ACL), ACL_REVISION);
+ ok(bret, "Failed to initialize ACL.\n");
+ bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE);
+ ok(bret, "Failed to add ACL to security desciptor.\n");
+ status = pNtSetSecurityObject(hTemp, DACL_SECURITY_INFORMATION, pSD);
+ ok(status == ERROR_SUCCESS, "NtSetSecurityObject returned %x\n", status);
+
+ h = CreateFileA(tmpfile, GENERIC_READ,
FILE_SHARE_DELETE|FILE_SHARE_WRITE|FILE_SHARE_READ,
+ NULL, OPEN_EXISTING, 0, NULL);
+ ok(h == INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError());
+ CloseHandle(h);
+
+ pSetSecurityDescriptorControl(pSD, SE_DACL_AUTO_INHERIT_REQ,
SE_DACL_AUTO_INHERIT_REQ);
+ status = pNtSetSecurityObject(hTemp, DACL_SECURITY_INFORMATION, pSD);
+ ok(status == ERROR_SUCCESS, "NtSetSecurityObject returned %x\n", status);
+
+ h = CreateFileA(tmpfile, GENERIC_READ,
FILE_SHARE_DELETE|FILE_SHARE_WRITE|FILE_SHARE_READ,
+ NULL, OPEN_EXISTING, 0, NULL);
+ ok(h == INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError());
+ CloseHandle(h);
+
+ pSetSecurityDescriptorControl(pSD, SE_DACL_AUTO_INHERIT_REQ|SE_DACL_AUTO_INHERITED,
+ SE_DACL_AUTO_INHERIT_REQ|SE_DACL_AUTO_INHERITED);
+ status = pNtSetSecurityObject(hTemp, DACL_SECURITY_INFORMATION, pSD);
+ ok(status == ERROR_SUCCESS, "NtSetSecurityObject returned %x\n", status);
+
+ h = CreateFileA(tmpfile, GENERIC_READ,
FILE_SHARE_DELETE|FILE_SHARE_WRITE|FILE_SHARE_READ,
+ NULL, OPEN_EXISTING, 0, NULL);
+ ok(h == INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError());
+ CloseHandle(h);
+
+ /* test if DACL is properly mapped to permission */
bret = InitializeAcl(pDacl, 100, ACL_REVISION);
ok(bret, "Failed to initialize ACL.\n");
bret = pAddAccessAllowedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, user_sid);
ok(bret, "Failed to add Current User to ACL.\n");
- bret = pAddAccessAllowedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, admin_sid);
- ok(bret, "Failed to add Administrator Group to ACL.\n");
+ bret = pAddAccessDeniedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, user_sid);
+ ok(bret, "Failed to add Current User to ACL.\n");
bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE);
ok(bret, "Failed to add ACL to security desciptor.\n");
- GetTempFileNameA(".", "foo", 0, tmpfile);
- hTemp = CreateFileA(tmpfile, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING,
- FILE_FLAG_DELETE_ON_CLOSE, NULL);
- SetLastError(0xdeadbeef);
- error = pSetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT,
-
DACL_SECURITY_INFORMATION|PROTECTED_DACL_SECURITY_INFORMATION,
- NULL, NULL, pDacl, NULL);
+ status = pNtSetSecurityObject(hTemp, DACL_SECURITY_INFORMATION, pSD);
+ ok(status == ERROR_SUCCESS, "NtSetSecurityObject returned %x\n", status);
+
+ h = CreateFileA(tmpfile, GENERIC_READ,
FILE_SHARE_DELETE|FILE_SHARE_WRITE|FILE_SHARE_READ,
+ NULL, OPEN_EXISTING, 0, NULL);
+ ok(h != INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError());
+ CloseHandle(h);
+
+ bret = InitializeAcl(pDacl, 100, ACL_REVISION);
+ ok(bret, "Failed to initialize ACL.\n");
+ bret = pAddAccessDeniedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, user_sid);
+ ok(bret, "Failed to add Current User to ACL.\n");
+ bret = pAddAccessAllowedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, user_sid);
+ ok(bret, "Failed to add Current User to ACL.\n");
+ bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE);
+ ok(bret, "Failed to add ACL to security desciptor.\n");
+ status = pNtSetSecurityObject(hTemp, DACL_SECURITY_INFORMATION, pSD);
+ ok(status == ERROR_SUCCESS, "NtSetSecurityObject returned %x\n", status);
+
+ h = CreateFileA(tmpfile, GENERIC_READ,
FILE_SHARE_DELETE|FILE_SHARE_WRITE|FILE_SHARE_READ,
+ NULL, OPEN_EXISTING, 0, NULL);
+ ok(h == INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError());
HeapFree(GetProcessHeap(), 0, pDacl);
- if (error != ERROR_SUCCESS && (GetLastError() ==
ERROR_CALL_NOT_IMPLEMENTED))
- {
- win_skip("SetNamedSecurityInfoA is not implemented\n");
- HeapFree(GetProcessHeap(), 0, user);
- CloseHandle(hTemp);
- return;
- }
- ok(!error, "SetNamedSecurityInfoA failed with error %d\n", error);
- SetLastError(0xdeadbeef);
- error = pGetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
- NULL, NULL, &pDacl, NULL, &pSD);
- if (error != ERROR_SUCCESS && (GetLastError() ==
ERROR_CALL_NOT_IMPLEMENTED))
- {
- win_skip("GetNamedSecurityInfoA is not implemented\n");
- HeapFree(GetProcessHeap(), 0, user);
- CloseHandle(hTemp);
- return;
- }
- ok(!error, "GetNamedSecurityInfo failed with error %d\n", error);
-
- bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size),
AclSizeInformation);
- ok(bret, "GetAclInformation failed\n");
- if (acl_size.AceCount > 0)
- {
- bret = pGetAce(pDacl, 0, (VOID **)&ace);
- ok(bret, "Failed to get Current User ACE.\n");
- bret = EqualSid(&ace->SidStart, user_sid);
- ok(bret, "Current User ACE != Current User SID.\n");
- ok(((ACE_HEADER *)ace)->AceFlags == 0,
- "Current User ACE has unexpected flags (0x%x != 0x0)\n",
((ACE_HEADER *)ace)->AceFlags);
- ok(ace->Mask == 0x1f01ff, "Current User ACE has unexpected mask (0x%x !=
0x1f01ff)\n",
- ace->Mask);
- }
- if (acl_size.AceCount > 1)
- {
- bret = pGetAce(pDacl, 1, (VOID **)&ace);
- ok(bret, "Failed to get Administators Group ACE.\n");
- bret = EqualSid(&ace->SidStart, admin_sid);
- ok(bret || broken(!bret) /* win2k */, "Administators Group ACE !=
Administators Group SID.\n");
- ok(((ACE_HEADER *)ace)->AceFlags == 0,
- "Administators Group ACE has unexpected flags (0x%x != 0x0)\n",
((ACE_HEADER *)ace)->AceFlags);
- ok(ace->Mask == 0x1f01ff || broken(ace->Mask == GENERIC_ALL) /* win2k */,
- "Administators Group ACE has unexpected mask (0x%x != 0x1f01ff)\n",
ace->Mask);
- }
- LocalFree(pSD);
HeapFree(GetProcessHeap(), 0, user);
CloseHandle(hTemp);
@@ -3728,6 +4096,13 @@
Blank, SDDL_REVISION_1, &pSD, NULL);
ok(ret, "ConvertStringSecurityDescriptorToSecurityDescriptor failed with error
%d\n", GetLastError());
LocalFree(pSD);
+
+ SetLastError(0xdeadbeef);
+ ret = pConvertStringSecurityDescriptorToSecurityDescriptorA(
+
"D:P(A;;GRGW;;;BA)(A;;GRGW;;;S-1-5-21-0-0-0-1000)S:(ML;;NWNR;;;S-1-16-12288)",
SDDL_REVISION_1, &pSD, NULL);
+ ok(ret || broken(!ret && GetLastError() == ERROR_INVALID_DATATYPE) /* win2k
*/,
+ "ConvertStringSecurityDescriptorToSecurityDescriptor failed with error
%u\n", GetLastError());
+ if (ret) LocalFree(pSD);
}
static void test_ConvertSecurityDescriptorToString(void)
@@ -4201,7 +4576,7 @@
ok(((ACE_HEADER *)ace)->AceFlags == 0,
"Current User ACE has unexpected flags (0x%x != 0x0)\n",
((ACE_HEADER *)ace)->AceFlags);
ok(ace->Mask == 0x1f01ff, "Current User ACE has unexpected mask (0x%x !=
0x1f01ff)\n",
- ace->Mask);
+ ace->Mask);
}
if (acl_size.AceCount > 1)
{
@@ -4211,8 +4586,8 @@
ok(bret, "Administators Group ACE != Administators Group SID.\n");
ok(((ACE_HEADER *)ace)->AceFlags == 0,
"Administators Group ACE has unexpected flags (0x%x != 0x0)\n",
((ACE_HEADER *)ace)->AceFlags);
- ok(ace->Mask == 0x1f01ff, "Administators Group ACE has unexpected mask
(0x%x != 0x1f01ff)\n",
- ace->Mask);
+ ok(ace->Mask == 0x1f01ff,
+ "Administators Group ACE has unexpected mask (0x%x !=
0x1f01ff)\n", ace->Mask);
}
LocalFree(pSD);
CloseHandle(obj);
@@ -5693,6 +6068,51 @@
AdjustTokenPrivileges(token, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), &prev,
NULL);
CloseHandle(token);
+}
+
+static void test_AddAce(void)
+{
+ static SID const sidWorld = { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY} , {
SECURITY_WORLD_RID } };
+
+ char acl_buf[1024], ace_buf[256];
+ ACCESS_ALLOWED_ACE *ace = (ACCESS_ALLOWED_ACE*)ace_buf;
+ PACL acl = (PACL)acl_buf;
+ BOOL ret;
+
+ memset(ace, 0, sizeof(ace_buf));
+ ace->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
+ ace->Header.AceSize = sizeof(ACCESS_ALLOWED_ACE)-sizeof(DWORD)+sizeof(SID);
+ memcpy(&ace->SidStart, &sidWorld, sizeof(sidWorld));
+
+ ret = InitializeAcl(acl, sizeof(acl_buf), ACL_REVISION2);
+ ok(ret, "InitializeAcl failed: %d\n", GetLastError());
+
+ ret = AddAce(acl, ACL_REVISION1, MAXDWORD, ace, ace->Header.AceSize);
+ ok(ret, "AddAce failed: %d\n", GetLastError());
+ ret = AddAce(acl, ACL_REVISION2, MAXDWORD, ace, ace->Header.AceSize);
+ ok(ret, "AddAce failed: %d\n", GetLastError());
+ ret = AddAce(acl, ACL_REVISION3, MAXDWORD, ace, ace->Header.AceSize);
+ ok(ret, "AddAce failed: %d\n", GetLastError());
+ ok(acl->AclRevision == ACL_REVISION3, "acl->AclRevision = %d\n",
acl->AclRevision);
+ ret = AddAce(acl, ACL_REVISION4, MAXDWORD, ace, ace->Header.AceSize);
+ ok(ret, "AddAce failed: %d\n", GetLastError());
+ ok(acl->AclRevision == ACL_REVISION4, "acl->AclRevision = %d\n",
acl->AclRevision);
+ ret = AddAce(acl, ACL_REVISION1, MAXDWORD, ace, ace->Header.AceSize);
+ ok(ret, "AddAce failed: %d\n", GetLastError());
+ ok(acl->AclRevision == ACL_REVISION4, "acl->AclRevision = %d\n",
acl->AclRevision);
+ ret = AddAce(acl, ACL_REVISION2, MAXDWORD, ace, ace->Header.AceSize);
+ ok(ret, "AddAce failed: %d\n", GetLastError());
+
+ ret = AddAce(acl, MIN_ACL_REVISION-1, MAXDWORD, ace, ace->Header.AceSize);
+ ok(ret, "AddAce failed: %d\n", GetLastError());
+ /* next test succeededs but corrupts ACL */
+ ret = AddAce(acl, MAX_ACL_REVISION+1, MAXDWORD, ace, ace->Header.AceSize);
+ ok(ret, "AddAce failed: %d\n", GetLastError());
+ ok(acl->AclRevision == MAX_ACL_REVISION+1, "acl->AclRevision = %d\n",
acl->AclRevision);
+ SetLastError(0xdeadbeef);
+ ret = AddAce(acl, ACL_REVISION1, MAXDWORD, ace, ace->Header.AceSize);
+ ok(!ret, "AddAce succeeded\n");
+ ok(GetLastError() == ERROR_INVALID_PARAMETER, "GetLastError() = %d\n",
GetLastError());
}
START_TEST(security)
@@ -5736,4 +6156,5 @@
test_TokenIntegrityLevel();
test_default_dacl_owner_sid();
test_AdjustTokenPrivileges();
-}
+ test_AddAce();
+}
Modified: trunk/rostests/winetests/advapi32/service.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/advapi32/servic…
==============================================================================
--- trunk/rostests/winetests/advapi32/service.c [iso-8859-1] (original)
+++ trunk/rostests/winetests/advapi32/service.c [iso-8859-1] Mon May 25 18:46:12 2015
@@ -53,6 +53,7 @@
DWORD, LPDWORD);
static BOOL (WINAPI *pQueryServiceObjectSecurity)(SC_HANDLE, SECURITY_INFORMATION,
PSECURITY_DESCRIPTOR, DWORD, LPDWORD);
+static DWORD (WINAPI *pNotifyServiceStatusChangeW)(SC_HANDLE,DWORD,SERVICE_NOTIFYW*);
static void init_function_pointers(void)
{
@@ -66,6 +67,7 @@
pQueryServiceConfig2W= (void*)GetProcAddress(hadvapi32,
"QueryServiceConfig2W");
pQueryServiceStatusEx= (void*)GetProcAddress(hadvapi32,
"QueryServiceStatusEx");
pQueryServiceObjectSecurity = (void*)GetProcAddress(hadvapi32,
"QueryServiceObjectSecurity");
+ pNotifyServiceStatusChangeW = (void*)GetProcAddress(hadvapi32,
"NotifyServiceStatusChangeW");
}
static void test_open_scm(void)
@@ -2201,6 +2203,75 @@
return le1;
}
+struct notify_data {
+ SERVICE_NOTIFYW notify;
+ SC_HANDLE svc;
+};
+
+static void CALLBACK cb_stopped(void *user)
+{
+ struct notify_data *data = user;
+ BOOL br;
+
+ ok(data->notify.dwNotificationStatus == ERROR_SUCCESS,
+ "Got wrong notification status: %u\n",
data->notify.dwNotificationStatus);
+ ok(data->notify.ServiceStatus.dwCurrentState == SERVICE_STOPPED,
+ "Got wrong service state: 0x%x\n",
data->notify.ServiceStatus.dwCurrentState);
+ ok(data->notify.dwNotificationTriggered == SERVICE_NOTIFY_STOPPED,
+ "Got wrong notification triggered: 0x%x\n",
data->notify.dwNotificationTriggered);
+
+ br = StartServiceA(data->svc, 0, NULL);
+ ok(br, "StartService failed: %u\n", GetLastError());
+}
+
+static void CALLBACK cb_running(void *user)
+{
+ struct notify_data *data = user;
+ BOOL br;
+ SERVICE_STATUS status;
+
+ ok(data->notify.dwNotificationStatus == ERROR_SUCCESS,
+ "Got wrong notification status: %u\n",
data->notify.dwNotificationStatus);
+ ok(data->notify.ServiceStatus.dwCurrentState == SERVICE_RUNNING,
+ "Got wrong service state: 0x%x\n",
data->notify.ServiceStatus.dwCurrentState);
+ ok(data->notify.dwNotificationTriggered == SERVICE_NOTIFY_RUNNING,
+ "Got wrong notification triggered: 0x%x\n",
data->notify.dwNotificationTriggered);
+
+ br = ControlService(data->svc, SERVICE_CONTROL_STOP, &status);
+ ok(br, "ControlService failed: %u\n", GetLastError());
+}
+
+static void test_servicenotify(SC_HANDLE svc)
+{
+ DWORD dr;
+ struct notify_data data;
+
+ if(!pNotifyServiceStatusChangeW){
+ win_skip("No NotifyServiceStatusChangeW\n");
+ return;
+ }
+
+ memset(&data.notify, 0, sizeof(data.notify));
+ data.notify.dwVersion = SERVICE_NOTIFY_STATUS_CHANGE;
+ data.notify.pfnNotifyCallback = &cb_stopped;
+ data.notify.pContext = &data;
+ data.svc = svc;
+
+ dr = pNotifyServiceStatusChangeW(svc, SERVICE_NOTIFY_STOPPED |
SERVICE_NOTIFY_RUNNING, &data.notify);
+ ok(dr == ERROR_SUCCESS, "NotifyServiceStatusChangeW failed: %u\n", dr);
+
+ dr = SleepEx(100, TRUE);
+ ok(dr == WAIT_IO_COMPLETION, "APC wasn't called\n");
+
+ data.notify.pfnNotifyCallback = &cb_running;
+
+ dr = pNotifyServiceStatusChangeW(svc, SERVICE_NOTIFY_STOPPED |
SERVICE_NOTIFY_RUNNING, &data.notify);
+ ok(dr == ERROR_SUCCESS, "NotifyServiceStatusChangeW failed: %u\n", dr);
+
+ dr = SleepEx(100, TRUE);
+ ok(dr == WAIT_IO_COMPLETION, "APC wasn't called\n");
+}
+
static void test_start_stop(void)
{
BOOL ret;
@@ -2279,17 +2350,12 @@
le = try_start_stop(svc_handle, displayname, is_nt4);
ok(le == ERROR_SERVICE_REQUEST_TIMEOUT, "%d !=
ERROR_SERVICE_REQUEST_TIMEOUT\n", le);
- /* And finally with a service that plays dead, forcing a timeout.
- * This time we will put no quotes. That should work too, even if there are
- * spaces in the path.
- */
- sprintf(cmd, "%s service sleep", selfname);
- displayname = "Winetest Sleep Service";
+ /* create a real service and test notifications */
+ sprintf(cmd, "%s service serve", selfname);
+ displayname = "Winetest Service";
ret = ChangeServiceConfigA(svc_handle, SERVICE_NO_CHANGE, SERVICE_NO_CHANGE,
SERVICE_NO_CHANGE, cmd, NULL, NULL, NULL, NULL, NULL, displayname);
ok(ret, "ChangeServiceConfig() failed le=%u\n", GetLastError());
-
- le = try_start_stop(svc_handle, displayname, is_nt4);
- ok(le == ERROR_SERVICE_REQUEST_TIMEOUT, "%d !=
ERROR_SERVICE_REQUEST_TIMEOUT\n", le);
+ test_servicenotify(svc_handle);
cleanup:
if (svc_handle)
@@ -2394,6 +2460,57 @@
CloseServiceHandle(scm_handle);
}
+static DWORD WINAPI ctrl_handler(DWORD ctl, DWORD type, void *data, void *user)
+{
+ HANDLE evt = user;
+
+ switch(ctl){
+ case SERVICE_CONTROL_STOP:
+ SetEvent(evt);
+ break;
+ case SERVICE_CONTROL_INTERROGATE:
+ return NO_ERROR;
+ }
+
+ return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+static void WINAPI service_main(DWORD argc, char **argv)
+{
+ SERVICE_STATUS_HANDLE st_handle;
+ SERVICE_STATUS st;
+ HANDLE evt = CreateEventW(0, FALSE, FALSE, 0);
+
+ st_handle = RegisterServiceCtrlHandlerExA("", &ctrl_handler, evt);
+
+ st.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
+ st.dwServiceSpecificExitCode = 0;
+ st.dwCurrentState = SERVICE_RUNNING;
+ st.dwWin32ExitCode = NO_ERROR;
+ st.dwWaitHint = 0;
+ st.dwControlsAccepted = SERVICE_ACCEPT_STOP;
+ st.dwCheckPoint = 0;
+
+ SetServiceStatus(st_handle, &st);
+
+ WaitForSingleObject(evt, 5000);
+
+ st.dwCurrentState = SERVICE_STOPPED;
+
+ SetServiceStatus(st_handle, &st);
+}
+
+static void run_service(void)
+{
+ char empty[] = {0};
+ SERVICE_TABLE_ENTRYA table[] = {
+ {empty, &service_main },
+ {0, 0}
+ };
+
+ StartServiceCtrlDispatcherA(table);
+}
+
START_TEST(service)
{
SC_HANDLE scm_handle;
@@ -2404,10 +2521,8 @@
GetFullPathNameA(myARGV[0], sizeof(selfname), selfname, NULL);
if (myARGC >= 3)
{
- if (strcmp(myARGV[2], "sleep") == 0)
- /* Cause a service startup timeout */
- Sleep(90000);
- /* then, or if myARGV[2] == "exit", just exit */
+ if (strcmp(myARGV[2], "serve") == 0)
+ run_service();
return;
}