mirror of
https://github.com/reactos/reactos.git
synced 2025-01-03 21:09:19 +00:00
[ADVAPI32_WINETEST]: Sync with Wine 1.5.19.
svn path=/trunk/; revision=57864
This commit is contained in:
parent
c0976cca94
commit
17eb8ef5fb
5 changed files with 1100 additions and 127 deletions
|
@ -35,7 +35,9 @@ static BOOL (WINAPI *pCredReadA)(LPCSTR,DWORD,DWORD,PCREDENTIALA *);
|
|||
static BOOL (WINAPI *pCredRenameA)(LPCSTR,LPCSTR,DWORD,DWORD);
|
||||
static BOOL (WINAPI *pCredWriteA)(PCREDENTIALA,DWORD);
|
||||
static BOOL (WINAPI *pCredReadDomainCredentialsA)(PCREDENTIAL_TARGET_INFORMATIONA,DWORD,DWORD*,PCREDENTIALA**);
|
||||
|
||||
static BOOL (WINAPI *pCredMarshalCredentialA)(CRED_MARSHAL_TYPE,PVOID,LPSTR *);
|
||||
static BOOL (WINAPI *pCredUnmarshalCredentialA)(LPCSTR,PCRED_MARSHAL_TYPE,PVOID);
|
||||
static BOOL (WINAPI *pCredIsMarshaledCredentialA)(LPCSTR);
|
||||
|
||||
#define TEST_TARGET_NAME "credtest.winehq.org"
|
||||
#define TEST_TARGET_NAME2 "credtest2.winehq.org"
|
||||
|
@ -119,6 +121,47 @@ static void test_CredWriteA(void)
|
|||
ok(!ret && GetLastError() == ERROR_BAD_USERNAME,
|
||||
"CredWriteA with NULL username should have failed with ERROR_BAD_USERNAME instead of %d\n",
|
||||
GetLastError());
|
||||
|
||||
new_cred.UserName = (char *)"winetest";
|
||||
new_cred.Persist = CRED_PERSIST_LOCAL_MACHINE;
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = pCredWriteA(&new_cred, 0);
|
||||
ok(ret || broken(!ret), "CredWriteA failed with error %u\n", GetLastError());
|
||||
if (ret)
|
||||
{
|
||||
ret = pCredDeleteA(TEST_TARGET_NAME, CRED_TYPE_DOMAIN_PASSWORD, 0);
|
||||
ok(ret, "CredDeleteA failed with error %u\n", GetLastError());
|
||||
}
|
||||
new_cred.Type = CRED_TYPE_GENERIC;
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = pCredWriteA(&new_cred, 0);
|
||||
ok(ret || broken(!ret), "CredWriteA failed with error %u\n", GetLastError());
|
||||
if (ret)
|
||||
{
|
||||
ret = pCredDeleteA(TEST_TARGET_NAME, CRED_TYPE_GENERIC, 0);
|
||||
ok(ret, "CredDeleteA failed with error %u\n", GetLastError());
|
||||
}
|
||||
new_cred.Persist = CRED_PERSIST_SESSION;
|
||||
ret = pCredWriteA(&new_cred, 0);
|
||||
ok(ret, "CredWriteA failed with error %u\n", GetLastError());
|
||||
|
||||
ret = pCredDeleteA(TEST_TARGET_NAME, CRED_TYPE_GENERIC, 0);
|
||||
ok(ret, "CredDeleteA failed with error %u\n", GetLastError());
|
||||
|
||||
new_cred.Type = CRED_TYPE_DOMAIN_PASSWORD;
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = pCredWriteA(&new_cred, 0);
|
||||
ok(ret || broken(!ret), "CredWriteA failed with error %u\n", GetLastError());
|
||||
if (ret)
|
||||
{
|
||||
ret = pCredDeleteA(TEST_TARGET_NAME, CRED_TYPE_DOMAIN_PASSWORD, 0);
|
||||
ok(ret, "CredDeleteA failed with error %u\n", GetLastError());
|
||||
}
|
||||
new_cred.UserName = NULL;
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = pCredWriteA(&new_cred, 0);
|
||||
ok(!ret, "CredWriteA succeeded\n");
|
||||
ok(GetLastError() == ERROR_BAD_USERNAME, "got %u\n", GetLastError());
|
||||
}
|
||||
|
||||
static void test_CredDeleteA(void)
|
||||
|
@ -336,6 +379,368 @@ static void test_domain_password(DWORD cred_type)
|
|||
ok(ret, "CredDeleteA failed with error %d\n", GetLastError());
|
||||
}
|
||||
|
||||
static void test_CredMarshalCredentialA(void)
|
||||
{
|
||||
static WCHAR emptyW[] = {0};
|
||||
static WCHAR tW[] = {'t',0};
|
||||
static WCHAR teW[] = {'t','e',0};
|
||||
static WCHAR tesW[] = {'t','e','s',0};
|
||||
static WCHAR testW[] = {'t','e','s','t',0};
|
||||
static WCHAR test1W[] = {'t','e','s','t','1',0};
|
||||
CERT_CREDENTIAL_INFO cert;
|
||||
USERNAME_TARGET_CREDENTIAL_INFO username;
|
||||
DWORD error;
|
||||
char *str;
|
||||
BOOL ret;
|
||||
|
||||
SetLastError( 0xdeadbeef );
|
||||
ret = pCredMarshalCredentialA( 0, NULL, NULL );
|
||||
error = GetLastError();
|
||||
ok( !ret, "unexpected success\n" );
|
||||
ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
|
||||
|
||||
memset( cert.rgbHashOfCert, 0, sizeof(cert.rgbHashOfCert) );
|
||||
cert.cbSize = sizeof(cert);
|
||||
SetLastError( 0xdeadbeef );
|
||||
ret = pCredMarshalCredentialA( 0, &cert, NULL );
|
||||
error = GetLastError();
|
||||
ok( !ret, "unexpected success\n" );
|
||||
ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
|
||||
|
||||
str = (char *)0xdeadbeef;
|
||||
SetLastError( 0xdeadbeef );
|
||||
ret = pCredMarshalCredentialA( 0, &cert, &str );
|
||||
error = GetLastError();
|
||||
ok( !ret, "unexpected success\n" );
|
||||
ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
|
||||
ok( str == (char *)0xdeadbeef, "got %p\n", str );
|
||||
|
||||
SetLastError( 0xdeadbeef );
|
||||
ret = pCredMarshalCredentialA( CertCredential, NULL, NULL );
|
||||
error = GetLastError();
|
||||
ok( !ret, "unexpected success\n" );
|
||||
ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
|
||||
|
||||
if (0) { /* crash */
|
||||
SetLastError( 0xdeadbeef );
|
||||
ret = pCredMarshalCredentialA( CertCredential, &cert, NULL );
|
||||
error = GetLastError();
|
||||
ok( !ret, "unexpected success\n" );
|
||||
ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
|
||||
}
|
||||
|
||||
cert.cbSize = 0;
|
||||
str = (char *)0xdeadbeef;
|
||||
SetLastError( 0xdeadbeef );
|
||||
ret = pCredMarshalCredentialA( CertCredential, &cert, &str );
|
||||
error = GetLastError();
|
||||
ok( !ret, "unexpected success\n" );
|
||||
ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
|
||||
ok( str == (char *)0xdeadbeef, "got %p\n", str );
|
||||
|
||||
cert.cbSize = sizeof(cert) + 4;
|
||||
str = NULL;
|
||||
ret = pCredMarshalCredentialA( CertCredential, &cert, &str );
|
||||
ok( ret, "unexpected failure %u\n", GetLastError() );
|
||||
ok( str != NULL, "str not set\n" );
|
||||
ok( !lstrcmpA( str, "@@BAAAAAAAAAAAAAAAAAAAAAAAAAAA" ), "got %s\n", str );
|
||||
pCredFree( str );
|
||||
|
||||
cert.cbSize = sizeof(cert);
|
||||
cert.rgbHashOfCert[0] = 2;
|
||||
str = NULL;
|
||||
ret = pCredMarshalCredentialA( CertCredential, &cert, &str );
|
||||
ok( ret, "unexpected failure %u\n", GetLastError() );
|
||||
ok( str != NULL, "str not set\n" );
|
||||
ok( !lstrcmpA( str, "@@BCAAAAAAAAAAAAAAAAAAAAAAAAAA" ), "got %s\n", str );
|
||||
pCredFree( str );
|
||||
|
||||
cert.rgbHashOfCert[0] = 255;
|
||||
str = NULL;
|
||||
ret = pCredMarshalCredentialA( CertCredential, &cert, &str );
|
||||
ok( ret, "unexpected failure %u\n", GetLastError() );
|
||||
ok( str != NULL, "str not set\n" );
|
||||
ok( !lstrcmpA( str, "@@B-DAAAAAAAAAAAAAAAAAAAAAAAAA" ), "got %s\n", str );
|
||||
pCredFree( str );
|
||||
|
||||
cert.rgbHashOfCert[0] = 1;
|
||||
cert.rgbHashOfCert[1] = 1;
|
||||
str = NULL;
|
||||
ret = pCredMarshalCredentialA( CertCredential, &cert, &str );
|
||||
ok( ret, "unexpected failure %u\n", GetLastError() );
|
||||
ok( str != NULL, "str not set\n" );
|
||||
ok( !lstrcmpA( str, "@@BBEAAAAAAAAAAAAAAAAAAAAAAAAA" ), "got %s\n", str );
|
||||
pCredFree( str );
|
||||
|
||||
cert.rgbHashOfCert[0] = 1;
|
||||
cert.rgbHashOfCert[1] = 1;
|
||||
cert.rgbHashOfCert[2] = 1;
|
||||
str = NULL;
|
||||
ret = pCredMarshalCredentialA( CertCredential, &cert, &str );
|
||||
ok( ret, "unexpected failure %u\n", GetLastError() );
|
||||
ok( str != NULL, "str not set\n" );
|
||||
ok( !lstrcmpA( str, "@@BBEQAAAAAAAAAAAAAAAAAAAAAAAA" ), "got %s\n", str );
|
||||
pCredFree( str );
|
||||
|
||||
memset( cert.rgbHashOfCert, 0, sizeof(cert.rgbHashOfCert) );
|
||||
cert.rgbHashOfCert[0] = 'W';
|
||||
cert.rgbHashOfCert[1] = 'i';
|
||||
cert.rgbHashOfCert[2] = 'n';
|
||||
cert.rgbHashOfCert[3] = 'e';
|
||||
str = NULL;
|
||||
ret = pCredMarshalCredentialA( CertCredential, &cert, &str );
|
||||
ok( ret, "unexpected failure %u\n", GetLastError() );
|
||||
ok( str != NULL, "str not set\n" );
|
||||
ok( !lstrcmpA( str, "@@BXlmblBAAAAAAAAAAAAAAAAAAAAA" ), "got %s\n", str );
|
||||
pCredFree( str );
|
||||
|
||||
memset( cert.rgbHashOfCert, 0xff, sizeof(cert.rgbHashOfCert) );
|
||||
str = NULL;
|
||||
ret = pCredMarshalCredentialA( CertCredential, &cert, &str );
|
||||
ok( ret, "unexpected failure %u\n", GetLastError() );
|
||||
ok( str != NULL, "str not set\n" );
|
||||
ok( !lstrcmpA( str, "@@B--------------------------P" ), "got %s\n", str );
|
||||
pCredFree( str );
|
||||
|
||||
username.UserName = NULL;
|
||||
str = (char *)0xdeadbeef;
|
||||
SetLastError( 0xdeadbeef );
|
||||
ret = pCredMarshalCredentialA( UsernameTargetCredential, &username, &str );
|
||||
error = GetLastError();
|
||||
ok( !ret, "unexpected success\n" );
|
||||
ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
|
||||
ok( str == (char *)0xdeadbeef, "got %p\n", str );
|
||||
|
||||
username.UserName = emptyW;
|
||||
str = (char *)0xdeadbeef;
|
||||
SetLastError( 0xdeadbeef );
|
||||
ret = pCredMarshalCredentialA( UsernameTargetCredential, &username, &str );
|
||||
error = GetLastError();
|
||||
ok( !ret, "unexpected success\n" );
|
||||
ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
|
||||
ok( str == (char *)0xdeadbeef, "got %p\n", str );
|
||||
|
||||
username.UserName = tW;
|
||||
str = NULL;
|
||||
ret = pCredMarshalCredentialA( UsernameTargetCredential, &username, &str );
|
||||
ok( ret, "unexpected failure %u\n", GetLastError() );
|
||||
ok( str != NULL, "str not set\n" );
|
||||
ok( !lstrcmpA( str, "@@CCAAAAA0BA" ), "got %s\n", str );
|
||||
pCredFree( str );
|
||||
|
||||
username.UserName = teW;
|
||||
str = NULL;
|
||||
ret = pCredMarshalCredentialA( UsernameTargetCredential, &username, &str );
|
||||
ok( ret, "unexpected failure %u\n", GetLastError() );
|
||||
ok( str != NULL, "str not set\n" );
|
||||
ok( !lstrcmpA( str, "@@CEAAAAA0BQZAA" ), "got %s\n", str );
|
||||
pCredFree( str );
|
||||
|
||||
username.UserName = tesW;
|
||||
str = NULL;
|
||||
ret = pCredMarshalCredentialA( UsernameTargetCredential, &username, &str );
|
||||
ok( ret, "unexpected failure %u\n", GetLastError() );
|
||||
ok( str != NULL, "str not set\n" );
|
||||
ok( !lstrcmpA( str, "@@CGAAAAA0BQZAMHA" ), "got %s\n", str );
|
||||
pCredFree( str );
|
||||
|
||||
username.UserName = testW;
|
||||
str = NULL;
|
||||
ret = pCredMarshalCredentialA( UsernameTargetCredential, &username, &str );
|
||||
ok( ret, "unexpected failure %u\n", GetLastError() );
|
||||
ok( str != NULL, "str not set\n" );
|
||||
ok( !lstrcmpA( str, "@@CIAAAAA0BQZAMHA0BA" ), "got %s\n", str );
|
||||
pCredFree( str );
|
||||
|
||||
username.UserName = test1W;
|
||||
str = NULL;
|
||||
ret = pCredMarshalCredentialA( UsernameTargetCredential, &username, &str );
|
||||
ok( ret, "unexpected failure %u\n", GetLastError() );
|
||||
ok( str != NULL, "str not set\n" );
|
||||
ok( !lstrcmpA( str, "@@CKAAAAA0BQZAMHA0BQMAA" ), "got %s\n", str );
|
||||
pCredFree( str );
|
||||
}
|
||||
|
||||
static void test_CredUnmarshalCredentialA(void)
|
||||
{
|
||||
static WCHAR tW[] = {'t',0};
|
||||
static WCHAR testW[] = {'t','e','s','t',0};
|
||||
CERT_CREDENTIAL_INFO *cert;
|
||||
USERNAME_TARGET_CREDENTIAL_INFO *username;
|
||||
CRED_MARSHAL_TYPE type;
|
||||
unsigned int i;
|
||||
DWORD error;
|
||||
BOOL ret;
|
||||
|
||||
SetLastError( 0xdeadbeef );
|
||||
ret = pCredUnmarshalCredentialA( NULL, NULL, NULL );
|
||||
error = GetLastError();
|
||||
ok( !ret, "unexpected success\n" );
|
||||
ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
|
||||
|
||||
cert = NULL;
|
||||
SetLastError( 0xdeadbeef );
|
||||
ret = pCredUnmarshalCredentialA( NULL, NULL, (void **)&cert );
|
||||
error = GetLastError();
|
||||
ok( !ret, "unexpected success\n" );
|
||||
ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
|
||||
|
||||
type = 0;
|
||||
cert = NULL;
|
||||
SetLastError( 0xdeadbeef );
|
||||
ret = pCredUnmarshalCredentialA( NULL, &type, (void **)&cert );
|
||||
error = GetLastError();
|
||||
ok( !ret, "unexpected success\n" );
|
||||
ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
|
||||
|
||||
type = 0;
|
||||
cert = NULL;
|
||||
SetLastError( 0xdeadbeef );
|
||||
ret = pCredUnmarshalCredentialA( "", &type, (void **)&cert );
|
||||
error = GetLastError();
|
||||
ok( !ret, "unexpected success\n" );
|
||||
ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
|
||||
|
||||
if (0) { /* crash */
|
||||
SetLastError( 0xdeadbeef );
|
||||
ret = pCredUnmarshalCredentialA( "@@BAAAAAAAAAAAAAAAAAAAAAAAAAAA", &type, NULL );
|
||||
error = GetLastError();
|
||||
ok( !ret, "unexpected success\n" );
|
||||
ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
|
||||
|
||||
SetLastError( 0xdeadbeef );
|
||||
ret = pCredUnmarshalCredentialA( "@@BAAAAAAAAAAAAAAAAAAAAAAAAAAA", NULL, (void **)&cert );
|
||||
error = GetLastError();
|
||||
ok( !ret, "unexpected success\n" );
|
||||
ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
|
||||
}
|
||||
|
||||
type = 0;
|
||||
cert = NULL;
|
||||
ret = pCredUnmarshalCredentialA( "@@BAAAAAAAAAAAAAAAAAAAAAAAAAAA", &type, (void **)&cert );
|
||||
ok( ret, "unexpected failure %u\n", GetLastError() );
|
||||
ok( type == CertCredential, "got %u\n", type );
|
||||
ok( cert != NULL, "cert is NULL\n" );
|
||||
ok( cert->cbSize == sizeof(*cert), "wrong size %u\n", cert->cbSize );
|
||||
for (i = 0; i < sizeof(cert->rgbHashOfCert); i++) ok( !cert->rgbHashOfCert[i], "wrong data\n" );
|
||||
pCredFree( cert );
|
||||
|
||||
type = 0;
|
||||
cert = NULL;
|
||||
ret = pCredUnmarshalCredentialA( "@@BXlmblBAAAAAAAAAAAAAAAAAAAAA", &type, (void **)&cert );
|
||||
ok( ret, "unexpected failure %u\n", GetLastError() );
|
||||
ok( type == CertCredential, "got %u\n", type );
|
||||
ok( cert != NULL, "cert is NULL\n" );
|
||||
ok( cert->cbSize == sizeof(*cert), "wrong size %u\n", cert->cbSize );
|
||||
ok( cert->rgbHashOfCert[0] == 'W', "wrong data)\n" );
|
||||
ok( cert->rgbHashOfCert[1] == 'i', "wrong data\n" );
|
||||
ok( cert->rgbHashOfCert[2] == 'n', "wrong data\n" );
|
||||
ok( cert->rgbHashOfCert[3] == 'e', "wrong data\n" );
|
||||
for (i = 4; i < sizeof(cert->rgbHashOfCert); i++) ok( !cert->rgbHashOfCert[i], "wrong data\n" );
|
||||
pCredFree( cert );
|
||||
|
||||
SetLastError( 0xdeadbeef );
|
||||
ret = pCredUnmarshalCredentialA( "@@CAAAAAA", &type, (void **)&username );
|
||||
error = GetLastError();
|
||||
ok( !ret, "unexpected success\n" );
|
||||
ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
|
||||
|
||||
SetLastError( 0xdeadbeef );
|
||||
ret = pCredUnmarshalCredentialA( "@@CAAAAAA0BA", &type, (void **)&username );
|
||||
error = GetLastError();
|
||||
ok( !ret, "unexpected success\n" );
|
||||
ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
|
||||
|
||||
type = 0;
|
||||
username = NULL;
|
||||
ret = pCredUnmarshalCredentialA( "@@CCAAAAA0BA", &type, (void **)&username );
|
||||
ok( ret, "unexpected failure %u\n", GetLastError() );
|
||||
ok( type == UsernameTargetCredential, "got %u\n", type );
|
||||
ok( username != NULL, "username is NULL\n" );
|
||||
ok( username->UserName != NULL, "UserName is NULL\n" );
|
||||
ok( !lstrcmpW( username->UserName, tW ), "got %s\n", wine_dbgstr_w(username->UserName) );
|
||||
pCredFree( username );
|
||||
|
||||
type = 0;
|
||||
username = NULL;
|
||||
ret = pCredUnmarshalCredentialA( "@@CIAAAAA0BQZAMHA0BA", &type, (void **)&username );
|
||||
ok( ret, "unexpected failure %u\n", GetLastError() );
|
||||
ok( type == UsernameTargetCredential, "got %u\n", type );
|
||||
ok( username != NULL, "username is NULL\n" );
|
||||
ok( username->UserName != NULL, "UserName is NULL\n" );
|
||||
ok( !lstrcmpW( username->UserName, testW ), "got %s\n", wine_dbgstr_w(username->UserName) );
|
||||
pCredFree( username );
|
||||
|
||||
type = 0;
|
||||
username = NULL;
|
||||
SetLastError( 0xdeadbeef );
|
||||
ret = pCredUnmarshalCredentialA( "@@CA-----0BQZAMHA0BA", &type, (void **)&username );
|
||||
error = GetLastError();
|
||||
ok( !ret, "unexpected success\n" );
|
||||
ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
|
||||
}
|
||||
|
||||
static void test_CredIsMarshaledCredentialA(void)
|
||||
{
|
||||
int i;
|
||||
BOOL res;
|
||||
BOOL expected = TRUE;
|
||||
|
||||
const char * ptr[] = {
|
||||
/* CertCredential */
|
||||
"@@BXlmblBAAAAAAAAAAAAAAAAAAAAA", /* hash for 'W','i','n','e' */
|
||||
"@@BAAAAAAAAAAAAAAAAAAAAAAAAAAA", /* hash for all 0 */
|
||||
|
||||
/* UsernameTargetCredential */
|
||||
"@@CCAAAAA0BA", /* "t" */
|
||||
"@@CIAAAAA0BQZAMHA0BA", /* "test" */
|
||||
|
||||
/* todo: BinaryBlobCredential */
|
||||
|
||||
/* not marshaled names return always FALSE */
|
||||
"winetest",
|
||||
"",
|
||||
"@@",
|
||||
"@@A",
|
||||
"@@AA",
|
||||
"@@AAA",
|
||||
"@@B",
|
||||
"@@BB",
|
||||
"@@BBB",
|
||||
|
||||
/* CertCredential */
|
||||
"@@BAAAAAAAAAAAAAAAAAAAAAAAAAAAA", /* to long */
|
||||
"@@BAAAAAAAAAAAAAAAAAAAAAAAAAA", /* to short */
|
||||
"@@BAAAAAAAAAAAAAAAAAAAAAAAAAA+", /* bad char */
|
||||
"@@BAAAAAAAAAAAAAAAAAAAAAAAAAA:",
|
||||
"@@BAAAAAAAAAAAAAAAAAAAAAAAAAA>",
|
||||
"@@BAAAAAAAAAAAAAAAAAAAAAAAAAA<",
|
||||
|
||||
"@@C",
|
||||
"@@CC",
|
||||
"@@CCC",
|
||||
"@@D",
|
||||
"@@DD",
|
||||
"@@DDD",
|
||||
NULL};
|
||||
|
||||
for (i = 0; ptr[i]; i++)
|
||||
{
|
||||
if (*ptr[i] != '@')
|
||||
expected = FALSE;
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
res = pCredIsMarshaledCredentialA(ptr[i]);
|
||||
if (expected)
|
||||
ok(res != FALSE, "%d: got %d and %u for %s (expected TRUE)\n", i, res, GetLastError(), ptr[i]);
|
||||
else
|
||||
{
|
||||
/* Windows returns ERROR_INVALID_PARAMETER here, but that's not documented */
|
||||
ok(!res, "%d: got %d and %u for %s (expected FALSE)\n", i, res, GetLastError(), ptr[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
START_TEST(cred)
|
||||
{
|
||||
DWORD persists[CRED_TYPE_MAXIMUM];
|
||||
|
@ -348,9 +753,11 @@ START_TEST(cred)
|
|||
pCredReadA = (void *)GetProcAddress(GetModuleHandle("advapi32.dll"), "CredReadA");
|
||||
pCredRenameA = (void *)GetProcAddress(GetModuleHandle("advapi32.dll"), "CredRenameA");
|
||||
pCredReadDomainCredentialsA = (void *)GetProcAddress(GetModuleHandle("advapi32.dll"), "CredReadDomainCredentialsA");
|
||||
pCredMarshalCredentialA = (void *)GetProcAddress(GetModuleHandle("advapi32.dll"), "CredMarshalCredentialA");
|
||||
pCredUnmarshalCredentialA = (void *)GetProcAddress(GetModuleHandle("advapi32.dll"), "CredUnmarshalCredentialA");
|
||||
pCredIsMarshaledCredentialA = (void *)GetProcAddress(GetModuleHandle("advapi32.dll"), "CredIsMarshaledCredentialA");
|
||||
|
||||
if (!pCredEnumerateA || !pCredFree || !pCredWriteA || !pCredDeleteA ||
|
||||
!pCredReadA)
|
||||
if (!pCredEnumerateA || !pCredFree || !pCredWriteA || !pCredDeleteA || !pCredReadA)
|
||||
{
|
||||
win_skip("credentials functions not present in advapi32.dll\n");
|
||||
return;
|
||||
|
@ -392,4 +799,8 @@ START_TEST(cred)
|
|||
skip("CRED_TYPE_DOMAIN_VISIBLE_PASSWORD credentials are not supported or are disabled. Skipping\n");
|
||||
else
|
||||
test_domain_password(CRED_TYPE_DOMAIN_VISIBLE_PASSWORD);
|
||||
|
||||
test_CredMarshalCredentialA();
|
||||
test_CredUnmarshalCredentialA();
|
||||
test_CredIsMarshaledCredentialA();
|
||||
}
|
||||
|
|
|
@ -238,6 +238,9 @@ static void test_incorrect_api_usage(void)
|
|||
if (!result) return;
|
||||
pCryptDestroyHash(hHash);
|
||||
|
||||
result = pCryptCreateHash(0, CALG_SHA, 0, 0, &hHash);
|
||||
ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
|
||||
|
||||
result = pCryptGenKey(0, CALG_RC4, 0, &hKey);
|
||||
ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
|
||||
|
||||
|
@ -448,7 +451,9 @@ static void test_verify_sig(void)
|
|||
"Expected NTE_BAD_SIGNATURE, got %08x\n", GetLastError());
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = pCryptVerifySignatureW(hash, bogus, sizeof(bogus), key, NULL, 0);
|
||||
ok(!ret && GetLastError() == NTE_BAD_SIGNATURE,
|
||||
ok(!ret &&
|
||||
(GetLastError() == NTE_BAD_SIGNATURE ||
|
||||
broken(GetLastError() == NTE_BAD_HASH_STATE /* older NT4 */)),
|
||||
"Expected NTE_BAD_SIGNATURE, got %08x\n", GetLastError());
|
||||
pCryptDestroyKey(key);
|
||||
pCryptDestroyHash(hash);
|
||||
|
@ -619,9 +624,6 @@ static BOOL FindProvTypesRegVals(DWORD *pdwIndex, DWORD *pdwProvType, LPSTR *psz
|
|||
|
||||
(*pdwIndex)++;
|
||||
}
|
||||
|
||||
if (!ret)
|
||||
LocalFree(*pszTypeName);
|
||||
RegCloseKey(hSubKey);
|
||||
LocalFree(szName);
|
||||
|
||||
|
|
|
@ -346,6 +346,9 @@ static void test_set_value(void)
|
|||
/* Crashes on NT4, Windows 2000 and XP SP1 */
|
||||
ret = RegSetValueW(hkey_main, NULL, REG_SZ, NULL, 0);
|
||||
ok(ret == ERROR_INVALID_PARAMETER, "RegSetValueW should have failed with ERROR_INVALID_PARAMETER instead of %d\n", ret);
|
||||
|
||||
RegSetValueExA(hkey_main, name2A, 0, REG_SZ, (const BYTE *)1, 1);
|
||||
RegSetValueExA(hkey_main, name2A, 0, REG_DWORD, (const BYTE *)1, 1);
|
||||
}
|
||||
|
||||
ret = RegSetValueW(hkey_main, NULL, REG_SZ, string1W, sizeof(string1W));
|
||||
|
@ -353,7 +356,12 @@ static void test_set_value(void)
|
|||
test_hkey_main_Value_A(NULL, string1A, sizeof(string1A));
|
||||
test_hkey_main_Value_W(NULL, string1W, sizeof(string1W));
|
||||
|
||||
/* RegSetValueA ignores the size passed in */
|
||||
ret = RegSetValueW(hkey_main, name1W, REG_SZ, string1W, sizeof(string1W));
|
||||
ok(ret == ERROR_SUCCESS, "RegSetValueW failed: %d, GLE=%d\n", ret, GetLastError());
|
||||
test_hkey_main_Value_A(name1A, string1A, sizeof(string1A));
|
||||
test_hkey_main_Value_W(name1W, string1W, sizeof(string1W));
|
||||
|
||||
/* RegSetValueW ignores the size passed in */
|
||||
ret = RegSetValueW(hkey_main, NULL, REG_SZ, string1W, 4 * sizeof(string1W[0]));
|
||||
ok(ret == ERROR_SUCCESS, "RegSetValueW failed: %d, GLE=%d\n", ret, GetLastError());
|
||||
test_hkey_main_Value_A(NULL, string1A, sizeof(string1A));
|
||||
|
@ -390,6 +398,12 @@ static void test_set_value(void)
|
|||
ok(ret == ERROR_SUCCESS, "RegSetValueExW failed: %d, GLE=%d\n", ret, GetLastError());
|
||||
test_hkey_main_Value_A(name2A, string2A, sizeof(string2A));
|
||||
test_hkey_main_Value_W(name2W, string2W, sizeof(string2W));
|
||||
|
||||
/* test RegSetValueExW with data = 1 */
|
||||
ret = RegSetValueExW(hkey_main, name2W, 0, REG_SZ, (const BYTE *)1, 1);
|
||||
ok(ret == ERROR_NOACCESS, "RegSetValueExW should have failed with ERROR_NOACCESS: %d, GLE=%d\n", ret, GetLastError());
|
||||
ret = RegSetValueExW(hkey_main, name2W, 0, REG_DWORD, (const BYTE *)1, 1);
|
||||
ok(ret == ERROR_NOACCESS, "RegSetValueExW should have failed with ERROR_NOACCESS: %d, GLE=%d\n", ret, GetLastError());
|
||||
}
|
||||
|
||||
static void create_test_entries(void)
|
||||
|
|
|
@ -33,8 +33,17 @@
|
|||
#include "ntsecapi.h"
|
||||
#include "lmcons.h"
|
||||
|
||||
#include <winsvc.h>
|
||||
|
||||
#include "wine/test.h"
|
||||
|
||||
/* PROCESS_ALL_ACCESS in Vista+ PSDKs is incompatible with older Windows versions */
|
||||
#define PROCESS_ALL_ACCESS_NT4 (PROCESS_ALL_ACCESS & ~0xf000)
|
||||
|
||||
#ifndef EVENT_QUERY_STATE
|
||||
#define EVENT_QUERY_STATE 0x0001
|
||||
#endif
|
||||
|
||||
/* copied from Wine winternl.h - not included in the Windows SDK */
|
||||
typedef enum _OBJECT_INFORMATION_CLASS {
|
||||
ObjectBasicInformation,
|
||||
|
@ -58,7 +67,7 @@ typedef struct _OBJECT_BASIC_INFORMATION {
|
|||
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)); }
|
||||
#define expect_eq(expr, value, type, format) { type ret_ = expr; ok((value) == ret_, #expr " expected " format " got " format "\n", (value), (ret_)); }
|
||||
|
||||
static BOOL (WINAPI *pAddAccessAllowedAceEx)(PACL, DWORD, DWORD, DWORD, PSID);
|
||||
static BOOL (WINAPI *pAddAccessDeniedAceEx)(PACL, DWORD, DWORD, DWORD, PSID);
|
||||
|
@ -94,6 +103,8 @@ static BOOL (WINAPI *pSetFileSecurityA)(LPCSTR, SECURITY_INFORMATION,
|
|||
static DWORD (WINAPI *pGetNamedSecurityInfoA)(LPSTR, SE_OBJECT_TYPE, SECURITY_INFORMATION,
|
||||
PSID*, PSID*, PACL*, PACL*,
|
||||
PSECURITY_DESCRIPTOR*);
|
||||
static DWORD (WINAPI *pSetNamedSecurityInfoA)(LPTSTR, SE_OBJECT_TYPE, SECURITY_INFORMATION,
|
||||
PSID, PSID, PACL, PACL);
|
||||
static PDWORD (WINAPI *pGetSidSubAuthority)(PSID, DWORD);
|
||||
static PUCHAR (WINAPI *pGetSidSubAuthorityCount)(PSID);
|
||||
static BOOL (WINAPI *pIsValidSid)(PSID);
|
||||
|
@ -113,15 +124,27 @@ static BOOL (WINAPI *pSetSecurityDescriptorControl)(PSECURITY_DESCRIPTOR, SECURI
|
|||
SECURITY_DESCRIPTOR_CONTROL);
|
||||
static DWORD (WINAPI *pGetSecurityInfo)(HANDLE, SE_OBJECT_TYPE, SECURITY_INFORMATION,
|
||||
PSID*, PSID*, PACL*, PACL*, PSECURITY_DESCRIPTOR*);
|
||||
static DWORD (WINAPI *pSetSecurityInfo)(HANDLE, SE_OBJECT_TYPE, SECURITY_INFORMATION,
|
||||
PSID, PSID, PACL, PACL);
|
||||
static NTSTATUS (WINAPI *pNtAccessCheck)(PSECURITY_DESCRIPTOR, HANDLE, ACCESS_MASK, PGENERIC_MAPPING,
|
||||
PPRIVILEGE_SET, PULONG, PULONG, NTSTATUS*);
|
||||
static BOOL (WINAPI *pCreateRestrictedToken)(HANDLE, DWORD, DWORD, PSID_AND_ATTRIBUTES, DWORD,
|
||||
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 HMODULE hmod;
|
||||
static int myARGC;
|
||||
static char** myARGV;
|
||||
|
||||
struct strsid_entry
|
||||
{
|
||||
const char *str;
|
||||
DWORD flags;
|
||||
};
|
||||
#define STRSID_OK 0
|
||||
#define STRSID_OPT 1
|
||||
|
||||
struct sidRef
|
||||
{
|
||||
SID_IDENTIFIER_AUTHORITY auth;
|
||||
|
@ -151,6 +174,7 @@ static void init(void)
|
|||
pSetFileSecurityA = (void *)GetProcAddress(hmod, "SetFileSecurityA" );
|
||||
pCreateWellKnownSid = (void *)GetProcAddress( hmod, "CreateWellKnownSid" );
|
||||
pGetNamedSecurityInfoA = (void *)GetProcAddress(hmod, "GetNamedSecurityInfoA");
|
||||
pSetNamedSecurityInfoA = (void *)GetProcAddress(hmod, "SetNamedSecurityInfoA");
|
||||
pGetSidSubAuthority = (void *)GetProcAddress(hmod, "GetSidSubAuthority");
|
||||
pGetSidSubAuthorityCount = (void *)GetProcAddress(hmod, "GetSidSubAuthorityCount");
|
||||
pIsValidSid = (void *)GetProcAddress(hmod, "IsValidSid");
|
||||
|
@ -159,34 +183,16 @@ static void init(void)
|
|||
pSetEntriesInAclA = (void *)GetProcAddress(hmod, "SetEntriesInAclA");
|
||||
pSetSecurityDescriptorControl = (void *)GetProcAddress(hmod, "SetSecurityDescriptorControl");
|
||||
pGetSecurityInfo = (void *)GetProcAddress(hmod, "GetSecurityInfo");
|
||||
pSetSecurityInfo = (void *)GetProcAddress(hmod, "SetSecurityInfo");
|
||||
pCreateRestrictedToken = (void *)GetProcAddress(hmod, "CreateRestrictedToken");
|
||||
pConvertSidToStringSidA = (void *)GetProcAddress(hmod, "ConvertSidToStringSidA");
|
||||
pConvertStringSidToSidA = (void *)GetProcAddress(hmod, "ConvertStringSidToSidA");
|
||||
pGetAclInformation = (void *)GetProcAddress(hmod, "GetAclInformation");
|
||||
pGetAce = (void *)GetProcAddress(hmod, "GetAce");
|
||||
|
||||
myARGC = winetest_get_mainargs( &myARGV );
|
||||
}
|
||||
|
||||
static void test_str_sid(const char *str_sid)
|
||||
{
|
||||
PSID psid;
|
||||
char *temp;
|
||||
|
||||
if (pConvertStringSidToSidA(str_sid, &psid))
|
||||
{
|
||||
if (pConvertSidToStringSidA(psid, &temp))
|
||||
{
|
||||
trace(" %s: %s\n", str_sid, temp);
|
||||
LocalFree(temp);
|
||||
}
|
||||
LocalFree(psid);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GetLastError() != ERROR_INVALID_SID)
|
||||
trace(" %s: couldn't be converted, returned %d\n", str_sid, GetLastError());
|
||||
else
|
||||
trace(" %s: couldn't be converted\n", str_sid);
|
||||
}
|
||||
}
|
||||
|
||||
static void test_sid(void)
|
||||
{
|
||||
struct sidRef refs[] = {
|
||||
|
@ -197,6 +203,18 @@ static void test_sid(void)
|
|||
{ { {0x00,0x00,0x00,0x00,0x00,0x02} }, "S-1-2-1" },
|
||||
{ { {0x00,0x00,0x00,0x00,0x00,0x0c} }, "S-1-12-1" },
|
||||
};
|
||||
struct strsid_entry strsid_table[] = {
|
||||
{"AO", STRSID_OK}, {"RU", STRSID_OK}, {"AN", STRSID_OK}, {"AU", STRSID_OK},
|
||||
{"BA", STRSID_OK}, {"BG", STRSID_OK}, {"BO", STRSID_OK}, {"BU", STRSID_OK},
|
||||
{"CA", STRSID_OPT}, {"CG", STRSID_OK}, {"CO", STRSID_OK}, {"DA", STRSID_OPT},
|
||||
{"DC", STRSID_OPT}, {"DD", STRSID_OPT}, {"DG", STRSID_OPT}, {"DU", STRSID_OPT},
|
||||
{"EA", STRSID_OPT}, {"ED", STRSID_OK}, {"WD", STRSID_OK}, {"PA", STRSID_OPT},
|
||||
{"IU", STRSID_OK}, {"LA", STRSID_OK}, {"LG", STRSID_OK}, {"LS", STRSID_OK},
|
||||
{"SY", STRSID_OK}, {"NU", STRSID_OK}, {"NO", STRSID_OK}, {"NS", STRSID_OK},
|
||||
{"PO", STRSID_OK}, {"PS", STRSID_OK}, {"PU", STRSID_OK}, {"RS", STRSID_OPT},
|
||||
{"RD", STRSID_OK}, {"RE", STRSID_OK}, {"RC", STRSID_OK}, {"SA", STRSID_OPT},
|
||||
{"SO", STRSID_OK}, {"SU", STRSID_OK}};
|
||||
|
||||
const char noSubAuthStr[] = "S-1-5";
|
||||
unsigned int i;
|
||||
PSID psid = NULL;
|
||||
|
@ -204,12 +222,11 @@ static void test_sid(void)
|
|||
BOOL r;
|
||||
LPSTR str = NULL;
|
||||
|
||||
pConvertSidToStringSidA = (void *)GetProcAddress( hmod, "ConvertSidToStringSidA" );
|
||||
if( !pConvertSidToStringSidA )
|
||||
return;
|
||||
pConvertStringSidToSidA = (void *)GetProcAddress( hmod, "ConvertStringSidToSidA" );
|
||||
if( !pConvertStringSidToSidA )
|
||||
if( !pConvertSidToStringSidA || !pConvertStringSidToSidA )
|
||||
{
|
||||
win_skip("ConvertSidToStringSidA or ConvertStringSidToSidA not available\n");
|
||||
return;
|
||||
}
|
||||
|
||||
r = pConvertStringSidToSidA( NULL, NULL );
|
||||
ok( !r, "expected failure with NULL parameters\n" );
|
||||
|
@ -246,8 +263,6 @@ static void test_sid(void)
|
|||
|
||||
for( i = 0; i < sizeof(refs) / sizeof(refs[0]); i++ )
|
||||
{
|
||||
PISID pisid;
|
||||
|
||||
r = AllocateAndInitializeSid( &refs[i].auth, 1,1,0,0,0,0,0,0,0,
|
||||
&psid );
|
||||
ok( r, "failed to allocate sid\n" );
|
||||
|
@ -284,45 +299,44 @@ static void test_sid(void)
|
|||
LocalFree( psid );
|
||||
}
|
||||
|
||||
trace("String SIDs:\n");
|
||||
test_str_sid("AO");
|
||||
test_str_sid("RU");
|
||||
test_str_sid("AN");
|
||||
test_str_sid("AU");
|
||||
test_str_sid("BA");
|
||||
test_str_sid("BG");
|
||||
test_str_sid("BO");
|
||||
test_str_sid("BU");
|
||||
test_str_sid("CA");
|
||||
test_str_sid("CG");
|
||||
test_str_sid("CO");
|
||||
test_str_sid("DA");
|
||||
test_str_sid("DC");
|
||||
test_str_sid("DD");
|
||||
test_str_sid("DG");
|
||||
test_str_sid("DU");
|
||||
test_str_sid("EA");
|
||||
test_str_sid("ED");
|
||||
test_str_sid("WD");
|
||||
test_str_sid("PA");
|
||||
test_str_sid("IU");
|
||||
test_str_sid("LA");
|
||||
test_str_sid("LG");
|
||||
test_str_sid("LS");
|
||||
test_str_sid("SY");
|
||||
test_str_sid("NU");
|
||||
test_str_sid("NO");
|
||||
test_str_sid("NS");
|
||||
test_str_sid("PO");
|
||||
test_str_sid("PS");
|
||||
test_str_sid("PU");
|
||||
test_str_sid("RS");
|
||||
test_str_sid("RD");
|
||||
test_str_sid("RE");
|
||||
test_str_sid("RC");
|
||||
test_str_sid("SA");
|
||||
test_str_sid("SO");
|
||||
test_str_sid("SU");
|
||||
/* string constant format not supported before XP */
|
||||
r = pConvertStringSidToSidA(strsid_table[0].str, &psid);
|
||||
if(!r)
|
||||
{
|
||||
win_skip("String constant format not supported\n");
|
||||
return;
|
||||
}
|
||||
LocalFree(psid);
|
||||
|
||||
for(i = 0; i < sizeof(strsid_table) / sizeof(strsid_table[0]); i++)
|
||||
{
|
||||
char *temp;
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
r = pConvertStringSidToSidA(strsid_table[i].str, &psid);
|
||||
|
||||
if (!(strsid_table[i].flags & STRSID_OPT))
|
||||
{
|
||||
ok(r, "%s: got %u\n", strsid_table[i].str, GetLastError());
|
||||
}
|
||||
|
||||
if (r)
|
||||
{
|
||||
if ((winetest_debug > 1) && (pConvertSidToStringSidA(psid, &temp)))
|
||||
{
|
||||
trace(" %s: %s\n", strsid_table[i].str, temp);
|
||||
LocalFree(temp);
|
||||
}
|
||||
LocalFree(psid);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GetLastError() != ERROR_INVALID_SID)
|
||||
trace(" %s: couldn't be converted, returned %d\n", strsid_table[i].str, GetLastError());
|
||||
else
|
||||
trace(" %s: couldn't be converted\n", strsid_table[i].str);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void test_trustee(void)
|
||||
|
@ -1455,9 +1469,11 @@ static void test_token_attr(void)
|
|||
Size = 0;
|
||||
ret = GetTokenInformation(Token, TokenGroups, Groups, Size2, &Size);
|
||||
ok(Size > 1, "got %d\n", Size);
|
||||
ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
|
||||
ok((!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER) || broken(ret) /* wow64 */,
|
||||
"%d with error %d\n", ret, GetLastError());
|
||||
ok(*((BYTE*)Groups) == 0xcc, "buffer altered\n");
|
||||
if(!ret)
|
||||
ok(*((BYTE*)Groups) == 0xcc, "buffer altered\n");
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, Groups);
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
|
@ -1646,7 +1662,8 @@ static const struct well_known_sid_value
|
|||
/* 66 */ {TRUE, "S-1-16-4096"}, {TRUE, "S-1-16-8192"}, {TRUE, "S-1-16-12288"},
|
||||
/* 69 */ {TRUE, "S-1-16-16384"}, {TRUE, "S-1-5-33"}, {TRUE, "S-1-3-4"},
|
||||
/* 72 */ {FALSE, "S-1-5-21-12-23-34-45-56-571"}, {FALSE, "S-1-5-21-12-23-34-45-56-572"},
|
||||
/* 74 */ {TRUE, "S-1-5-22"}, {FALSE, "S-1-5-21-12-23-34-45-56-521"}, {TRUE, "S-1-5-32-573"}
|
||||
/* 74 */ {TRUE, "S-1-5-22"}, {FALSE, "S-1-5-21-12-23-34-45-56-521"}, {TRUE, "S-1-5-32-573"},
|
||||
/* 77 */ {FALSE, "S-1-5-21-12-23-34-45-56-498"}, {TRUE, "S-1-5-32-574"}, {TRUE, "S-1-16-8448"}
|
||||
};
|
||||
|
||||
static void test_CreateWellKnownSid(void)
|
||||
|
@ -1711,7 +1728,7 @@ static void test_CreateWellKnownSid(void)
|
|||
expect_eq(GetSidLengthRequired(*GetSidSubAuthorityCount(sid_buffer)), cb, DWORD, "%d");
|
||||
ok(IsValidSid(sid_buffer), "The sid is not valid\n");
|
||||
ok(pConvertSidToStringSidA(sid_buffer, &str), "Couldn't convert SID to string\n");
|
||||
ok(strcmp(str, value->sid_string) == 0, "SID mismatch - expected %s, got %s\n",
|
||||
ok(strcmp(str, value->sid_string) == 0, "%d: SID mismatch - expected %s, got %s\n", i,
|
||||
value->sid_string, str);
|
||||
LocalFree(str);
|
||||
|
||||
|
@ -2420,15 +2437,15 @@ static void test_granted_access(HANDLE handle, ACCESS_MASK access,
|
|||
|
||||
#define CHECK_SET_SECURITY(o,i,e) \
|
||||
do{ \
|
||||
BOOL res; \
|
||||
BOOL res_; \
|
||||
DWORD err; \
|
||||
SetLastError( 0xdeadbeef ); \
|
||||
res = SetKernelObjectSecurity( o, i, SecurityDescriptor ); \
|
||||
res_ = SetKernelObjectSecurity( o, i, SecurityDescriptor ); \
|
||||
err = GetLastError(); \
|
||||
if (e == ERROR_SUCCESS) \
|
||||
ok(res, "SetKernelObjectSecurity failed with %d\n", err); \
|
||||
ok(res_, "SetKernelObjectSecurity failed with %d\n", err); \
|
||||
else \
|
||||
ok(!res && err == e, "SetKernelObjectSecurity should have failed " \
|
||||
ok(!res_ && err == e, "SetKernelObjectSecurity should have failed " \
|
||||
"with %s, instead of %d\n", #e, err); \
|
||||
}while(0)
|
||||
|
||||
|
@ -2543,7 +2560,7 @@ static void test_process_security(void)
|
|||
/* Doesn't matter what ACL say we should get full access for ourselves */
|
||||
res = CreateProcessA( NULL, buffer, &psa, NULL, FALSE, 0, NULL, NULL, &startup, &info );
|
||||
ok(res, "CreateProcess with err:%d\n", GetLastError());
|
||||
TEST_GRANTED_ACCESS2( info.hProcess, PROCESS_ALL_ACCESS,
|
||||
TEST_GRANTED_ACCESS2( info.hProcess, PROCESS_ALL_ACCESS_NT4,
|
||||
STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL );
|
||||
winetest_wait_child_process( info.hProcess );
|
||||
|
||||
|
@ -2595,7 +2612,7 @@ static void test_process_security_child(void)
|
|||
ret = DuplicateHandle( GetCurrentProcess(), GetCurrentProcess(), GetCurrentProcess(),
|
||||
&handle, 0, TRUE, DUPLICATE_SAME_ACCESS );
|
||||
ok(ret, "duplicating handle err:%d\n", GetLastError());
|
||||
TEST_GRANTED_ACCESS2( handle, PROCESS_ALL_ACCESS,
|
||||
TEST_GRANTED_ACCESS2( handle, PROCESS_ALL_ACCESS_NT4,
|
||||
STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL );
|
||||
|
||||
CloseHandle( handle );
|
||||
|
@ -2604,7 +2621,7 @@ static void test_process_security_child(void)
|
|||
ret = DuplicateHandle( GetCurrentProcess(), GetCurrentProcess(), GetCurrentProcess(),
|
||||
&handle, PROCESS_ALL_ACCESS, TRUE, 0 );
|
||||
ok(ret, "duplicating handle err:%d\n", GetLastError());
|
||||
TEST_GRANTED_ACCESS2( handle, PROCESS_ALL_ACCESS,
|
||||
TEST_GRANTED_ACCESS2( handle, PROCESS_ALL_ACCESS_NT4,
|
||||
PROCESS_ALL_ACCESS | PROCESS_QUERY_LIMITED_INFORMATION );
|
||||
ret = DuplicateHandle( GetCurrentProcess(), handle, GetCurrentProcess(),
|
||||
&handle1, PROCESS_VM_READ, TRUE, 0 );
|
||||
|
@ -2990,40 +3007,67 @@ static void test_SetEntriesInAclA(void)
|
|||
|
||||
static void test_GetNamedSecurityInfoA(void)
|
||||
{
|
||||
PSECURITY_DESCRIPTOR pSecDesc;
|
||||
DWORD revision;
|
||||
char admin_ptr[sizeof(SID)+sizeof(ULONG)*SID_MAX_SUB_AUTHORITIES], dacl[100], *user;
|
||||
DWORD sid_size = sizeof(admin_ptr), user_size;
|
||||
char invalid_path[] = "/an invalid file path";
|
||||
PSID admin_sid = (PSID) admin_ptr, user_sid;
|
||||
char sd[SECURITY_DESCRIPTOR_MIN_LENGTH];
|
||||
SECURITY_DESCRIPTOR_CONTROL control;
|
||||
PSID owner;
|
||||
PSID group;
|
||||
PACL dacl;
|
||||
ACL_SIZE_INFORMATION acl_size;
|
||||
CHAR windows_dir[MAX_PATH];
|
||||
PSECURITY_DESCRIPTOR pSD;
|
||||
ACCESS_ALLOWED_ACE *ace;
|
||||
BOOL bret = TRUE, isNT4;
|
||||
char tmpfile[MAX_PATH];
|
||||
DWORD error, revision;
|
||||
BOOL owner_defaulted;
|
||||
BOOL group_defaulted;
|
||||
DWORD error;
|
||||
BOOL ret, isNT4;
|
||||
CHAR windows_dir[MAX_PATH];
|
||||
HANDLE token, hTemp;
|
||||
PSID owner, group;
|
||||
PACL pDacl;
|
||||
|
||||
if (!pGetNamedSecurityInfoA)
|
||||
if (!pSetNamedSecurityInfoA || !pGetNamedSecurityInfoA || !pCreateWellKnownSid)
|
||||
{
|
||||
win_skip("GetNamedSecurityInfoA is not available\n");
|
||||
win_skip("Required functions are not available\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ret = GetWindowsDirectoryA(windows_dir, MAX_PATH);
|
||||
ok(ret, "GetWindowsDirectory failed with error %d\n", GetLastError());
|
||||
if (!OpenThreadToken(GetCurrentThread(), TOKEN_READ, TRUE, &token))
|
||||
{
|
||||
if (GetLastError() != ERROR_NO_TOKEN) bret = FALSE;
|
||||
else if (!OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &token)) bret = FALSE;
|
||||
}
|
||||
if (!bret)
|
||||
{
|
||||
win_skip("Failed to get current user token\n");
|
||||
return;
|
||||
}
|
||||
bret = GetTokenInformation(token, TokenUser, NULL, 0, &user_size);
|
||||
ok(!bret && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
|
||||
"GetTokenInformation(TokenUser) failed with error %d\n", GetLastError());
|
||||
user = HeapAlloc(GetProcessHeap(), 0, user_size);
|
||||
bret = GetTokenInformation(token, TokenUser, user, user_size, &user_size);
|
||||
ok(bret, "GetTokenInformation(TokenUser) failed with error %d\n", GetLastError());
|
||||
CloseHandle( token );
|
||||
user_sid = ((TOKEN_USER *)user)->User.Sid;
|
||||
|
||||
bret = GetWindowsDirectoryA(windows_dir, MAX_PATH);
|
||||
ok(bret, "GetWindowsDirectory failed with error %d\n", GetLastError());
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
error = pGetNamedSecurityInfoA(windows_dir, SE_FILE_OBJECT,
|
||||
OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION,
|
||||
NULL, NULL, NULL, NULL, &pSecDesc);
|
||||
NULL, NULL, NULL, NULL, &pSD);
|
||||
if (error != ERROR_SUCCESS && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED))
|
||||
{
|
||||
win_skip("GetNamedSecurityInfoA is not implemented\n");
|
||||
HeapFree(GetProcessHeap(), 0, user);
|
||||
return;
|
||||
}
|
||||
ok(!error, "GetNamedSecurityInfo failed with error %d\n", error);
|
||||
|
||||
ret = GetSecurityDescriptorControl(pSecDesc, &control, &revision);
|
||||
ok(ret, "GetSecurityDescriptorControl failed with error %d\n", GetLastError());
|
||||
bret = GetSecurityDescriptorControl(pSD, &control, &revision);
|
||||
ok(bret, "GetSecurityDescriptorControl failed with error %d\n", GetLastError());
|
||||
ok((control & (SE_SELF_RELATIVE|SE_DACL_PRESENT)) == (SE_SELF_RELATIVE|SE_DACL_PRESENT) ||
|
||||
broken((control & (SE_SELF_RELATIVE|SE_DACL_PRESENT)) == SE_DACL_PRESENT), /* NT4 */
|
||||
"control (0x%x) doesn't have (SE_SELF_RELATIVE|SE_DACL_PRESENT) flags set\n", control);
|
||||
|
@ -3031,20 +3075,21 @@ static void test_GetNamedSecurityInfoA(void)
|
|||
|
||||
isNT4 = (control & (SE_SELF_RELATIVE|SE_DACL_PRESENT)) == SE_DACL_PRESENT;
|
||||
|
||||
ret = GetSecurityDescriptorOwner(pSecDesc, &owner, &owner_defaulted);
|
||||
ok(ret, "GetSecurityDescriptorOwner failed with error %d\n", GetLastError());
|
||||
bret = GetSecurityDescriptorOwner(pSD, &owner, &owner_defaulted);
|
||||
ok(bret, "GetSecurityDescriptorOwner failed with error %d\n", GetLastError());
|
||||
ok(owner != NULL, "owner should not be NULL\n");
|
||||
|
||||
ret = GetSecurityDescriptorGroup(pSecDesc, &group, &group_defaulted);
|
||||
ok(ret, "GetSecurityDescriptorGroup failed with error %d\n", GetLastError());
|
||||
bret = GetSecurityDescriptorGroup(pSD, &group, &group_defaulted);
|
||||
ok(bret, "GetSecurityDescriptorGroup failed with error %d\n", GetLastError());
|
||||
ok(group != NULL, "group should not be NULL\n");
|
||||
LocalFree(pSecDesc);
|
||||
LocalFree(pSD);
|
||||
|
||||
|
||||
/* NULL descriptor tests */
|
||||
if(isNT4)
|
||||
{
|
||||
win_skip("NT4 does not support GetNamedSecutityInfo with a NULL descriptor\n");
|
||||
HeapFree(GetProcessHeap(), 0, user);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -3053,13 +3098,85 @@ static void test_GetNamedSecurityInfoA(void)
|
|||
ok(error==ERROR_INVALID_PARAMETER, "GetNamedSecurityInfo failed with error %d\n", error);
|
||||
|
||||
error = pGetNamedSecurityInfoA(windows_dir, SE_FILE_OBJECT,DACL_SECURITY_INFORMATION,
|
||||
NULL, NULL, &dacl, NULL, NULL);
|
||||
NULL, NULL, &pDacl, NULL, NULL);
|
||||
ok(!error, "GetNamedSecurityInfo failed with error %d\n", error);
|
||||
ok(dacl != NULL, "dacl should not be NULL\n");
|
||||
ok(pDacl != NULL, "DACL should not be NULL\n");
|
||||
|
||||
error = pGetNamedSecurityInfoA(windows_dir, SE_FILE_OBJECT,OWNER_SECURITY_INFORMATION,
|
||||
NULL, NULL, &dacl, NULL, NULL);
|
||||
NULL, NULL, &pDacl, NULL, NULL);
|
||||
ok(error==ERROR_INVALID_PARAMETER, "GetNamedSecurityInfo failed with error %d\n", error);
|
||||
|
||||
/* Test behavior of SetNamedSecurityInfo with an invalid path */
|
||||
SetLastError(0xdeadbeef);
|
||||
error = pSetNamedSecurityInfoA(invalid_path, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL,
|
||||
NULL, NULL, NULL);
|
||||
ok(error == ERROR_FILE_NOT_FOUND, "Unexpected error returned: 0x%x\n", error);
|
||||
ok(GetLastError() == 0xdeadbeef, "Expected last error to remain unchanged.\n");
|
||||
|
||||
/* Create security descriptor information and test that it comes back the same */
|
||||
pSD = &sd;
|
||||
pDacl = (PACL)&dacl;
|
||||
InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION);
|
||||
pCreateWellKnownSid(WinBuiltinAdministratorsSid, NULL, admin_sid, &sid_size);
|
||||
bret = InitializeAcl(pDacl, sizeof(dacl), ACL_REVISION);
|
||||
ok(bret, "Failed to initialize ACL.\n");
|
||||
bret = pAddAccessAllowedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, user_sid);
|
||||
HeapFree(GetProcessHeap(), 0, user);
|
||||
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 = 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, NULL,
|
||||
NULL, pDacl, NULL);
|
||||
if (error != ERROR_SUCCESS && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED))
|
||||
{
|
||||
win_skip("SetNamedSecurityInfoA is not implemented\n");
|
||||
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");
|
||||
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);
|
||||
todo_wine 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);
|
||||
todo_wine 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);
|
||||
CloseHandle(hTemp);
|
||||
}
|
||||
|
||||
static void test_ConvertStringSecurityDescriptor(void)
|
||||
|
@ -3523,20 +3640,42 @@ static void test_acls(void)
|
|||
|
||||
static void test_GetSecurityInfo(void)
|
||||
{
|
||||
HANDLE obj;
|
||||
PSECURITY_DESCRIPTOR sd;
|
||||
char b[sizeof(TOKEN_USER) + sizeof(SID) + sizeof(DWORD)*SID_MAX_SUB_AUTHORITIES];
|
||||
char admin_ptr[sizeof(SID)+sizeof(ULONG)*SID_MAX_SUB_AUTHORITIES], dacl[100];
|
||||
DWORD sid_size = sizeof(admin_ptr), l = sizeof(b);
|
||||
PSID admin_sid = (PSID) admin_ptr, user_sid;
|
||||
char sd[SECURITY_DESCRIPTOR_MIN_LENGTH];
|
||||
ACL_SIZE_INFORMATION acl_size;
|
||||
PSECURITY_DESCRIPTOR pSD;
|
||||
ACCESS_ALLOWED_ACE *ace;
|
||||
HANDLE token, obj;
|
||||
PSID owner, group;
|
||||
PACL dacl;
|
||||
BOOL bret = TRUE;
|
||||
PACL pDacl;
|
||||
DWORD ret;
|
||||
|
||||
if (!pGetSecurityInfo)
|
||||
if (!pGetSecurityInfo || !pSetSecurityInfo)
|
||||
{
|
||||
win_skip("GetSecurityInfo is not available\n");
|
||||
win_skip("[Get|Set]SecurityInfo is not available\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!OpenThreadToken(GetCurrentThread(), TOKEN_READ, TRUE, &token))
|
||||
{
|
||||
if (GetLastError() != ERROR_NO_TOKEN) bret = FALSE;
|
||||
else if (!OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &token)) bret = FALSE;
|
||||
}
|
||||
if (!bret)
|
||||
{
|
||||
win_skip("Failed to get current user token\n");
|
||||
return;
|
||||
}
|
||||
GetTokenInformation(token, TokenUser, b, l, &l);
|
||||
CloseHandle( token );
|
||||
user_sid = ((TOKEN_USER *)b)->User.Sid;
|
||||
|
||||
/* Create something. Files have lots of associated security info. */
|
||||
obj = CreateFile(myARGV[0], GENERIC_READ, FILE_SHARE_READ, NULL,
|
||||
obj = CreateFile(myARGV[0], GENERIC_READ|WRITE_DAC, FILE_SHARE_READ, NULL,
|
||||
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (obj == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
|
@ -3546,7 +3685,7 @@ static void test_GetSecurityInfo(void)
|
|||
|
||||
ret = pGetSecurityInfo(obj, SE_FILE_OBJECT,
|
||||
OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
|
||||
&owner, &group, &dacl, NULL, &sd);
|
||||
&owner, &group, &pDacl, NULL, &pSD);
|
||||
if (ret == ERROR_CALL_NOT_IMPLEMENTED)
|
||||
{
|
||||
win_skip("GetSecurityInfo is not implemented\n");
|
||||
|
@ -3554,15 +3693,15 @@ static void test_GetSecurityInfo(void)
|
|||
return;
|
||||
}
|
||||
ok(ret == ERROR_SUCCESS, "GetSecurityInfo returned %d\n", ret);
|
||||
ok(sd != NULL, "GetSecurityInfo\n");
|
||||
ok(pSD != NULL, "GetSecurityInfo\n");
|
||||
ok(owner != NULL, "GetSecurityInfo\n");
|
||||
ok(group != NULL, "GetSecurityInfo\n");
|
||||
if (dacl != NULL)
|
||||
ok(IsValidAcl(dacl), "GetSecurityInfo\n");
|
||||
if (pDacl != NULL)
|
||||
ok(IsValidAcl(pDacl), "GetSecurityInfo\n");
|
||||
else
|
||||
win_skip("No ACL information returned\n");
|
||||
|
||||
LocalFree(sd);
|
||||
LocalFree(pSD);
|
||||
|
||||
if (!pCreateWellKnownSid)
|
||||
{
|
||||
|
@ -3575,15 +3714,59 @@ static void test_GetSecurityInfo(void)
|
|||
the other stuff, leaving us no way to free it. */
|
||||
ret = pGetSecurityInfo(obj, SE_FILE_OBJECT,
|
||||
OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
|
||||
&owner, &group, &dacl, NULL, NULL);
|
||||
&owner, &group, &pDacl, NULL, NULL);
|
||||
ok(ret == ERROR_SUCCESS, "GetSecurityInfo returned %d\n", ret);
|
||||
ok(owner != NULL, "GetSecurityInfo\n");
|
||||
ok(group != NULL, "GetSecurityInfo\n");
|
||||
if (dacl != NULL)
|
||||
ok(IsValidAcl(dacl), "GetSecurityInfo\n");
|
||||
if (pDacl != NULL)
|
||||
ok(IsValidAcl(pDacl), "GetSecurityInfo\n");
|
||||
else
|
||||
win_skip("No ACL information returned\n");
|
||||
|
||||
/* Create security descriptor information and test that it comes back the same */
|
||||
pSD = &sd;
|
||||
pDacl = (PACL)&dacl;
|
||||
InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION);
|
||||
pCreateWellKnownSid(WinBuiltinAdministratorsSid, NULL, admin_sid, &sid_size);
|
||||
bret = InitializeAcl(pDacl, sizeof(dacl), 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 = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE);
|
||||
ok(bret, "Failed to add ACL to security desciptor.\n");
|
||||
ret = pSetSecurityInfo(obj, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
|
||||
NULL, NULL, pDacl, NULL);
|
||||
ok(ret == ERROR_SUCCESS, "SetSecurityInfo returned %d\n", ret);
|
||||
ret = pGetSecurityInfo(obj, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
|
||||
NULL, NULL, &pDacl, NULL, NULL);
|
||||
ok(ret == ERROR_SUCCESS, "GetSecurityInfo returned %d\n", ret);
|
||||
ok(pDacl && IsValidAcl(pDacl), "GetSecurityInfo returned invalid DACL.\n");
|
||||
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);
|
||||
todo_wine 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);
|
||||
todo_wine 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);
|
||||
}
|
||||
CloseHandle(obj);
|
||||
}
|
||||
|
||||
|
@ -3981,6 +4164,339 @@ static void test_CreateRestrictedToken(void)
|
|||
CloseHandle(process_token);
|
||||
}
|
||||
|
||||
static void validate_default_security_descriptor(SECURITY_DESCRIPTOR *sd)
|
||||
{
|
||||
BOOL ret, present, defaulted;
|
||||
ACL *acl;
|
||||
void *sid;
|
||||
|
||||
ret = IsValidSecurityDescriptor(sd);
|
||||
ok(ret, "security descriptor is not valid\n");
|
||||
|
||||
present = -1;
|
||||
defaulted = -1;
|
||||
acl = (void *)0xdeadbeef;
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = GetSecurityDescriptorDacl(sd, &present, &acl, &defaulted);
|
||||
ok(ret, "GetSecurityDescriptorDacl error %d\n", GetLastError());
|
||||
todo_wine
|
||||
ok(present == 1, "acl is not present\n");
|
||||
todo_wine
|
||||
ok(acl != (void *)0xdeadbeef && acl != NULL, "acl pointer is not set\n");
|
||||
ok(defaulted == 0, "defaulted is set to TRUE\n");
|
||||
|
||||
defaulted = -1;
|
||||
sid = (void *)0xdeadbeef;
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = GetSecurityDescriptorOwner(sd, &sid, &defaulted);
|
||||
ok(ret, "GetSecurityDescriptorOwner error %d\n", GetLastError());
|
||||
todo_wine
|
||||
ok(sid != (void *)0xdeadbeef && sid != NULL, "sid pointer is not set\n");
|
||||
ok(defaulted == 0, "defaulted is set to TRUE\n");
|
||||
|
||||
defaulted = -1;
|
||||
sid = (void *)0xdeadbeef;
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = GetSecurityDescriptorGroup(sd, &sid, &defaulted);
|
||||
ok(ret, "GetSecurityDescriptorGroup error %d\n", GetLastError());
|
||||
todo_wine
|
||||
ok(sid != (void *)0xdeadbeef && sid != NULL, "sid pointer is not set\n");
|
||||
ok(defaulted == 0, "defaulted is set to TRUE\n");
|
||||
}
|
||||
|
||||
static void test_default_handle_security(HANDLE token, HANDLE handle, GENERIC_MAPPING *mapping)
|
||||
{
|
||||
DWORD ret, length, needed, granted, priv_set_len;
|
||||
BOOL status;
|
||||
PRIVILEGE_SET priv_set;
|
||||
SECURITY_DESCRIPTOR *sd;
|
||||
|
||||
needed = 0xdeadbeef;
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = GetKernelObjectSecurity(handle, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
|
||||
NULL, 0, &needed);
|
||||
ok(!ret, "GetKernelObjectSecurity should fail\n");
|
||||
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
|
||||
ok(needed != 0xdeadbeef, "GetKernelObjectSecurity should return required buffer length\n");
|
||||
|
||||
length = needed;
|
||||
sd = HeapAlloc(GetProcessHeap(), 0, length);
|
||||
|
||||
needed = 0xdeadbeef;
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = GetKernelObjectSecurity(handle, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
|
||||
sd, length, &needed);
|
||||
ok(ret, "GetKernelObjectSecurity error %d\n", GetLastError());
|
||||
ok(needed == length || needed == 0 /* file, pipe */, "GetKernelObjectSecurity should return %u instead of %u\n", length, needed);
|
||||
|
||||
validate_default_security_descriptor(sd);
|
||||
|
||||
priv_set_len = sizeof(priv_set);
|
||||
granted = 0xdeadbeef;
|
||||
status = 0xdeadbeef;
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = AccessCheck(sd, token, MAXIMUM_ALLOWED, mapping, &priv_set, &priv_set_len, &granted, &status);
|
||||
todo_wine {
|
||||
ok(ret, "AccessCheck error %d\n", GetLastError());
|
||||
ok(status == 1, "expected 1, got %d\n", status);
|
||||
ok(granted == mapping->GenericAll, "expected all access %#x, got %#x\n", mapping->GenericAll, granted);
|
||||
}
|
||||
priv_set_len = sizeof(priv_set);
|
||||
granted = 0xdeadbeef;
|
||||
status = 0xdeadbeef;
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = AccessCheck(sd, token, 0, mapping, &priv_set, &priv_set_len, &granted, &status);
|
||||
todo_wine {
|
||||
ok(ret, "AccessCheck error %d\n", GetLastError());
|
||||
ok(status == 0 || broken(status == 1) /* NT4 */, "expected 0, got %d\n", status);
|
||||
ok(granted == 0 || broken(granted == mapping->GenericRead) /* NT4 */, "expected 0, got %#x\n", granted);
|
||||
}
|
||||
priv_set_len = sizeof(priv_set);
|
||||
granted = 0xdeadbeef;
|
||||
status = 0xdeadbeef;
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = AccessCheck(sd, token, ACCESS_SYSTEM_SECURITY, mapping, &priv_set, &priv_set_len, &granted, &status);
|
||||
todo_wine {
|
||||
ok(ret, "AccessCheck error %d\n", GetLastError());
|
||||
ok(status == 0, "expected 0, got %d\n", status);
|
||||
ok(granted == 0, "expected 0, got %#x\n", granted);
|
||||
}
|
||||
priv_set_len = sizeof(priv_set);
|
||||
granted = 0xdeadbeef;
|
||||
status = 0xdeadbeef;
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = AccessCheck(sd, token, mapping->GenericRead, mapping, &priv_set, &priv_set_len, &granted, &status);
|
||||
todo_wine {
|
||||
ok(ret, "AccessCheck error %d\n", GetLastError());
|
||||
ok(status == 1, "expected 1, got %d\n", status);
|
||||
ok(granted == mapping->GenericRead, "expected read access %#x, got %#x\n", mapping->GenericRead, granted);
|
||||
}
|
||||
priv_set_len = sizeof(priv_set);
|
||||
granted = 0xdeadbeef;
|
||||
status = 0xdeadbeef;
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = AccessCheck(sd, token, mapping->GenericWrite, mapping, &priv_set, &priv_set_len, &granted, &status);
|
||||
todo_wine {
|
||||
ok(ret, "AccessCheck error %d\n", GetLastError());
|
||||
ok(status == 1, "expected 1, got %d\n", status);
|
||||
ok(granted == mapping->GenericWrite, "expected write access %#x, got %#x\n", mapping->GenericWrite, granted);
|
||||
}
|
||||
priv_set_len = sizeof(priv_set);
|
||||
granted = 0xdeadbeef;
|
||||
status = 0xdeadbeef;
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = AccessCheck(sd, token, mapping->GenericExecute, mapping, &priv_set, &priv_set_len, &granted, &status);
|
||||
todo_wine {
|
||||
ok(ret, "AccessCheck error %d\n", GetLastError());
|
||||
ok(status == 1, "expected 1, got %d\n", status);
|
||||
ok(granted == mapping->GenericExecute, "expected execute access %#x, got %#x\n", mapping->GenericExecute, granted);
|
||||
}
|
||||
HeapFree(GetProcessHeap(), 0, sd);
|
||||
}
|
||||
|
||||
static void test_mutex_security(HANDLE token)
|
||||
{
|
||||
HANDLE mutex;
|
||||
GENERIC_MAPPING mapping = { STANDARD_RIGHTS_READ | MUTANT_QUERY_STATE | SYNCHRONIZE,
|
||||
STANDARD_RIGHTS_WRITE | MUTEX_MODIFY_STATE | SYNCHRONIZE,
|
||||
STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE,
|
||||
STANDARD_RIGHTS_ALL | MUTEX_ALL_ACCESS };
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
mutex = OpenMutex(0, FALSE, "WineTestMutex");
|
||||
ok(!mutex, "mutex should not exist\n");
|
||||
ok(GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %u\n", GetLastError());
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
mutex = CreateMutex(NULL, FALSE, "WineTestMutex");
|
||||
ok(mutex != 0, "CreateMutex error %d\n", GetLastError());
|
||||
|
||||
test_default_handle_security(token, mutex, &mapping);
|
||||
|
||||
CloseHandle (mutex);
|
||||
}
|
||||
|
||||
static void test_event_security(HANDLE token)
|
||||
{
|
||||
HANDLE event;
|
||||
GENERIC_MAPPING mapping = { STANDARD_RIGHTS_READ | EVENT_QUERY_STATE | SYNCHRONIZE,
|
||||
STANDARD_RIGHTS_WRITE | EVENT_MODIFY_STATE | SYNCHRONIZE,
|
||||
STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE,
|
||||
STANDARD_RIGHTS_ALL | EVENT_ALL_ACCESS };
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
event = OpenEvent(0, FALSE, "WineTestEvent");
|
||||
ok(!event, "event should not exist\n");
|
||||
ok(GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %u\n", GetLastError());
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
event = CreateEvent(NULL, FALSE, FALSE, "WineTestEvent");
|
||||
ok(event != 0, "CreateEvent error %d\n", GetLastError());
|
||||
|
||||
test_default_handle_security(token, event, &mapping);
|
||||
|
||||
CloseHandle(event);
|
||||
}
|
||||
|
||||
#define WINE_TEST_PIPE "\\\\.\\pipe\\WineTestPipe"
|
||||
static void test_named_pipe_security(HANDLE token)
|
||||
{
|
||||
HANDLE pipe, file;
|
||||
GENERIC_MAPPING mapping = { FILE_GENERIC_READ,
|
||||
FILE_GENERIC_WRITE,
|
||||
FILE_GENERIC_EXECUTE,
|
||||
STANDARD_RIGHTS_ALL | FILE_ALL_ACCESS };
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
pipe = CreateNamedPipe(WINE_TEST_PIPE, PIPE_ACCESS_DUPLEX | FILE_FLAG_FIRST_PIPE_INSTANCE,
|
||||
PIPE_TYPE_BYTE | PIPE_NOWAIT, PIPE_UNLIMITED_INSTANCES,
|
||||
0, 0, NMPWAIT_USE_DEFAULT_WAIT, NULL);
|
||||
ok(pipe != INVALID_HANDLE_VALUE, "CreateNamedPipe error %d\n", GetLastError());
|
||||
|
||||
test_default_handle_security(token, pipe, &mapping);
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
file = CreateFile(WINE_TEST_PIPE, FILE_ALL_ACCESS, 0, NULL, OPEN_EXISTING, 0, 0);
|
||||
ok(file != INVALID_HANDLE_VALUE, "CreateFile error %d\n", GetLastError());
|
||||
CloseHandle(file);
|
||||
|
||||
CloseHandle(pipe);
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
file = CreateFile("\\\\.\\pipe\\", FILE_ALL_ACCESS, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
|
||||
ok(file != INVALID_HANDLE_VALUE || broken(file == INVALID_HANDLE_VALUE) /* before Vista */, "CreateFile error %d\n", GetLastError());
|
||||
CloseHandle(file);
|
||||
}
|
||||
|
||||
static BOOL validate_impersonation_token(HANDLE token, DWORD *token_type)
|
||||
{
|
||||
DWORD ret, needed;
|
||||
TOKEN_TYPE type;
|
||||
SECURITY_IMPERSONATION_LEVEL sil;
|
||||
|
||||
type = 0xdeadbeef;
|
||||
needed = 0;
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = GetTokenInformation(token, TokenType, &type, sizeof(type), &needed);
|
||||
ok(ret, "GetTokenInformation error %d\n", GetLastError());
|
||||
ok(needed == sizeof(type), "GetTokenInformation should return required buffer length\n");
|
||||
ok(type == TokenPrimary || type == TokenImpersonation, "expected TokenPrimary or TokenImpersonation, got %d\n", type);
|
||||
|
||||
*token_type = type;
|
||||
if (type != TokenImpersonation) return FALSE;
|
||||
|
||||
needed = 0;
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = GetTokenInformation(token, TokenImpersonationLevel, &sil, sizeof(sil), &needed);
|
||||
ok(ret, "GetTokenInformation error %d\n", GetLastError());
|
||||
ok(needed == sizeof(sil), "GetTokenInformation should return required buffer length\n");
|
||||
ok(sil == SecurityImpersonation, "expected SecurityImpersonation, got %d\n", sil);
|
||||
|
||||
needed = 0xdeadbeef;
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = GetTokenInformation(token, TokenDefaultDacl, NULL, 0, &needed);
|
||||
ok(!ret, "GetTokenInformation should fail\n");
|
||||
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
|
||||
ok(needed != 0xdeadbeef, "GetTokenInformation should return required buffer length\n");
|
||||
ok(needed > sizeof(TOKEN_DEFAULT_DACL), "GetTokenInformation returned empty default DACL\n");
|
||||
|
||||
needed = 0xdeadbeef;
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = GetTokenInformation(token, TokenOwner, NULL, 0, &needed);
|
||||
ok(!ret, "GetTokenInformation should fail\n");
|
||||
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
|
||||
ok(needed != 0xdeadbeef, "GetTokenInformation should return required buffer length\n");
|
||||
ok(needed > sizeof(TOKEN_OWNER), "GetTokenInformation returned empty token owner\n");
|
||||
|
||||
needed = 0xdeadbeef;
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = GetTokenInformation(token, TokenPrimaryGroup, NULL, 0, &needed);
|
||||
ok(!ret, "GetTokenInformation should fail\n");
|
||||
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
|
||||
ok(needed != 0xdeadbeef, "GetTokenInformation should return required buffer length\n");
|
||||
ok(needed > sizeof(TOKEN_PRIMARY_GROUP), "GetTokenInformation returned empty token primary group\n");
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void test_kernel_objects_security(void)
|
||||
{
|
||||
HANDLE token, process_token;
|
||||
DWORD ret, token_type;
|
||||
|
||||
ret = OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE | TOKEN_QUERY, &process_token);
|
||||
ok(ret, "OpenProcessToken error %d\n", GetLastError());
|
||||
|
||||
ret = validate_impersonation_token(process_token, &token_type);
|
||||
ok(token_type == TokenPrimary, "expected TokenPrimary, got %d\n", token_type);
|
||||
ok(!ret, "access token should not be an impersonation token\n");
|
||||
|
||||
ret = DuplicateToken(process_token, SecurityImpersonation, &token);
|
||||
ok(ret, "DuplicateToken error %d\n", GetLastError());
|
||||
|
||||
ret = validate_impersonation_token(token, &token_type);
|
||||
ok(ret, "access token should be a valid impersonation token\n");
|
||||
ok(token_type == TokenImpersonation, "expected TokenImpersonation, got %d\n", token_type);
|
||||
|
||||
test_mutex_security(token);
|
||||
test_event_security(token);
|
||||
test_named_pipe_security(token);
|
||||
/* FIXME: test other kernel object types */
|
||||
|
||||
CloseHandle(process_token);
|
||||
CloseHandle(token);
|
||||
}
|
||||
|
||||
static void test_TokenIntegrityLevel(void)
|
||||
{
|
||||
TOKEN_MANDATORY_LABEL *tml;
|
||||
BYTE buffer[64]; /* using max. 28 byte in win7 x64 */
|
||||
HANDLE token;
|
||||
DWORD size;
|
||||
DWORD res;
|
||||
char *sidname = NULL;
|
||||
static SID medium_level = {SID_REVISION, 1, {SECURITY_MANDATORY_LABEL_AUTHORITY},
|
||||
{SECURITY_MANDATORY_HIGH_RID}};
|
||||
static SID high_level = {SID_REVISION, 1, {SECURITY_MANDATORY_LABEL_AUTHORITY},
|
||||
{SECURITY_MANDATORY_MEDIUM_RID}};
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
res = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token);
|
||||
ok(res, "got %d with %d (expected TRUE)\n", res, GetLastError());
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
res = GetTokenInformation(token, TokenIntegrityLevel, buffer, sizeof(buffer), &size);
|
||||
|
||||
/* not supported before Vista */
|
||||
if (!res && ((GetLastError() == ERROR_INVALID_PARAMETER) || GetLastError() == ERROR_INVALID_FUNCTION))
|
||||
{
|
||||
win_skip("TokenIntegrityLevel not supported\n");
|
||||
CloseHandle(token);
|
||||
return;
|
||||
}
|
||||
|
||||
ok(res, "got %u with %u (expected TRUE)\n", res, GetLastError());
|
||||
if (!res)
|
||||
{
|
||||
CloseHandle(token);
|
||||
return;
|
||||
}
|
||||
|
||||
tml = (TOKEN_MANDATORY_LABEL*) buffer;
|
||||
ok(tml->Label.Attributes == (SE_GROUP_INTEGRITY | SE_GROUP_INTEGRITY_ENABLED),
|
||||
"got 0x%x (expected 0x%x)\n", tml->Label.Attributes, (SE_GROUP_INTEGRITY | SE_GROUP_INTEGRITY_ENABLED));
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
res = pConvertSidToStringSidA(tml->Label.Sid, &sidname);
|
||||
ok(res, "got %u and %u\n", res, GetLastError());
|
||||
|
||||
ok(EqualSid(tml->Label.Sid, &medium_level) || EqualSid(tml->Label.Sid, &high_level),
|
||||
"got %s (expected 'S-1-16-8192' or 'S-1-16-12288')\n", sidname);
|
||||
|
||||
LocalFree(sidname);
|
||||
CloseHandle(token);
|
||||
}
|
||||
|
||||
START_TEST(security)
|
||||
{
|
||||
init();
|
||||
|
@ -3991,6 +4507,7 @@ START_TEST(security)
|
|||
test_process_security_child();
|
||||
return;
|
||||
}
|
||||
test_kernel_objects_security();
|
||||
test_sid();
|
||||
test_trustee();
|
||||
test_luid();
|
||||
|
@ -4017,4 +4534,5 @@ START_TEST(security)
|
|||
test_GetUserNameA();
|
||||
test_GetUserNameW();
|
||||
test_CreateRestrictedToken();
|
||||
test_TokenIntegrityLevel();
|
||||
}
|
||||
|
|
|
@ -1896,6 +1896,7 @@ static void test_queryconfig2(void)
|
|||
DWORD expected, needed;
|
||||
BYTE buffer[MAX_PATH];
|
||||
LPSERVICE_DESCRIPTIONA pConfig = (LPSERVICE_DESCRIPTIONA)buffer;
|
||||
SERVICE_PRESHUTDOWN_INFO preshutdown_info;
|
||||
static const CHAR servicename [] = "Winetest";
|
||||
static const CHAR displayname [] = "Winetest dummy service";
|
||||
static const CHAR pathname [] = "we_dont_care.exe";
|
||||
|
@ -2062,6 +2063,33 @@ static void test_queryconfig2(void)
|
|||
ret = pQueryServiceConfig2W(svc_handle, SERVICE_CONFIG_DESCRIPTION,buffer, needed,&needed);
|
||||
ok(ret, "expected QueryServiceConfig2W to succeed\n");
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = pQueryServiceConfig2W(svc_handle, SERVICE_CONFIG_PRESHUTDOWN_INFO,
|
||||
(LPBYTE)&preshutdown_info, sizeof(preshutdown_info), &needed);
|
||||
if(!ret && GetLastError()==ERROR_INVALID_LEVEL)
|
||||
{
|
||||
/* Win2k3 and older */
|
||||
win_skip("SERVICE_CONFIG_PRESHUTDOWN_INFO not supported\n");
|
||||
goto cleanup;
|
||||
}
|
||||
ok(ret, "expected QueryServiceConfig2W to succeed (%d)\n", GetLastError());
|
||||
ok(needed == sizeof(preshutdown_info), "needed = %d\n", needed);
|
||||
ok(preshutdown_info.dwPreshutdownTimeout == 180000, "Default PreshutdownTimeout = %d\n",
|
||||
preshutdown_info.dwPreshutdownTimeout);
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
preshutdown_info.dwPreshutdownTimeout = -1;
|
||||
ret = pChangeServiceConfig2A(svc_handle, SERVICE_CONFIG_PRESHUTDOWN_INFO,
|
||||
(LPVOID)&preshutdown_info);
|
||||
ok(ret, "expected ChangeServiceConfig2A to succeed (%d)\n", GetLastError());
|
||||
|
||||
ret = pQueryServiceConfig2W(svc_handle, SERVICE_CONFIG_PRESHUTDOWN_INFO,
|
||||
(LPBYTE)&preshutdown_info, sizeof(preshutdown_info), &needed);
|
||||
ok(ret, "expected QueryServiceConfig2W to succeed (%d)\n", GetLastError());
|
||||
ok(needed == sizeof(preshutdown_info), "needed = %d\n", needed);
|
||||
ok(preshutdown_info.dwPreshutdownTimeout == -1, "New PreshutdownTimeout = %d\n",
|
||||
preshutdown_info.dwPreshutdownTimeout);
|
||||
|
||||
cleanup:
|
||||
DeleteService(svc_handle);
|
||||
|
||||
|
@ -2178,7 +2206,7 @@ static void test_start_stop(void)
|
|||
|
||||
if (!winetest_interactive)
|
||||
{
|
||||
skip("reactos bug 6646: Skipping service start timeout tests!\n");
|
||||
skip("ROSTESTS-56: Skipping service start timeout tests!\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue