Author: jimtabor
Date: Tue Dec 9 13:26:45 2008
New Revision: 37982
URL:
http://svn.reactos.org/svn/reactos?rev=37982&view=rev
Log:
- Sync to date wine AdvApi32 cross tests.
Modified:
trunk/rostests/winetests/advapi32/cred.c
trunk/rostests/winetests/advapi32/crypt.c
trunk/rostests/winetests/advapi32/registry.c
trunk/rostests/winetests/advapi32/security.c
trunk/rostests/winetests/advapi32/service.c
Modified: trunk/rostests/winetests/advapi32/cred.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/advapi32/cred.c…
==============================================================================
--- trunk/rostests/winetests/advapi32/cred.c [iso-8859-1] (original)
+++ trunk/rostests/winetests/advapi32/cred.c [iso-8859-1] Tue Dec 9 13:26:45 2008
@@ -97,12 +97,19 @@
SetLastError(0xdeadbeef);
ret = pCredWriteA(&new_cred, 0);
- ok(!ret, "CredWrite with username without domain should have failed\n");
- ok(GetLastError() == ERROR_BAD_USERNAME ||
- GetLastError() == ERROR_NO_SUCH_LOGON_SESSION || /* Vista */
- broken(GetLastError() == ERROR_IO_PENDING),
- "CredWrite with username without domain should return
ERROR_BAD_USERNAME"
- "or ERROR_NO_SUCH_LOGON_SESSION not %d\n", GetLastError());
+ if (ret)
+ {
+ /* Vista */
+ ok(GetLastError() == ERROR_IO_PENDING,
+ "Expected ERROR_IO_PENDING, got %d\n", GetLastError());
+ }
+ else
+ {
+ ok(GetLastError() == ERROR_BAD_USERNAME ||
+ GetLastError() == ERROR_NO_SUCH_LOGON_SESSION, /* Vista */
+ "CredWrite with username without domain should return
ERROR_BAD_USERNAME"
+ "or ERROR_NO_SUCH_LOGON_SESSION not %d\n", GetLastError());
+ }
new_cred.UserName = NULL;
SetLastError(0xdeadbeef);
Modified: trunk/rostests/winetests/advapi32/crypt.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/advapi32/crypt.…
==============================================================================
--- trunk/rostests/winetests/advapi32/crypt.c [iso-8859-1] (original)
+++ trunk/rostests/winetests/advapi32/crypt.c [iso-8859-1] Tue Dec 9 13:26:45 2008
@@ -274,11 +274,11 @@
ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n",
GetLastError());
dwLen = 1;
- result = pCryptDecrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, &temp, &dwLen);
+ result = pCryptDecrypt(hKey, 0, TRUE, 0, &temp, &dwLen);
ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n",
GetLastError());
dwLen = 1;
- result = pCryptEncrypt(hKey, (HCRYPTHASH)NULL, TRUE, 0, &temp, &dwLen, 1);
+ result = pCryptEncrypt(hKey, 0, TRUE, 0, &temp, &dwLen, 1);
ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n",
GetLastError());
result = pCryptDeriveKey(hProv, CALG_RC4, hHash, 0, &hKey2);
@@ -293,7 +293,7 @@
#endif
dwLen = 1;
- result = pCryptExportKey(hKey, (HCRYPTPROV)NULL, 0, 0, &temp, &dwLen);
+ result = pCryptExportKey(hKey, 0, 0, 0, &temp, &dwLen);
ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n",
GetLastError());
result = pCryptGenKey(hProv, CALG_RC4, 0, &hKey2);
@@ -320,7 +320,7 @@
result = pCryptHashSessionKey(hHash, hKey, 0);
ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n",
GetLastError());
- result = pCryptImportKey(hProv, &temp, 1, (HCRYPTKEY)NULL, 0, &hKey2);
+ result = pCryptImportKey(hProv, &temp, 1, 0, 0, &hKey2);
ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n",
GetLastError());
if (pCryptSignHashW)
@@ -560,59 +560,77 @@
LocalFree(provider);
}
-static BOOL FindProvTypesRegVals(DWORD dwIndex, DWORD *pdwProvType, LPSTR *pszTypeName,
+static BOOL FindProvTypesRegVals(DWORD *pdwIndex, DWORD *pdwProvType, LPSTR
*pszTypeName,
DWORD *pcbTypeName, DWORD *pdwTypeCount)
{
HKEY hKey;
HKEY hSubKey;
PSTR ch;
-
+ LPSTR szName;
+ DWORD cbName;
+ BOOL ret = FALSE;
+
if (RegOpenKey(HKEY_LOCAL_MACHINE,
"Software\\Microsoft\\Cryptography\\Defaults\\Provider Types", &hKey))
return FALSE;
-
- if (RegQueryInfoKey(hKey, NULL, NULL, NULL, pdwTypeCount, pcbTypeName, NULL,
+
+ if (RegQueryInfoKey(hKey, NULL, NULL, NULL, pdwTypeCount, &cbName, NULL,
NULL, NULL, NULL, NULL, NULL))
- return FALSE;
- (*pcbTypeName)++;
-
- if (!(*pszTypeName = ((LPSTR)LocalAlloc(LMEM_ZEROINIT, *pcbTypeName))))
- return FALSE;
-
- if (RegEnumKeyEx(hKey, dwIndex, *pszTypeName, pcbTypeName, NULL, NULL, NULL, NULL))
- return FALSE;
- (*pcbTypeName)++;
- ch = *pszTypeName + strlen(*pszTypeName);
- /* Convert "Type 000" to 0, etc/ */
- *pdwProvType = *(--ch) - '0';
- *pdwProvType += (*(--ch) - '0') * 10;
- *pdwProvType += (*(--ch) - '0') * 100;
-
- if (RegOpenKey(hKey, *pszTypeName, &hSubKey))
- return FALSE;
-
- if (RegQueryValueEx(hSubKey, "TypeName", NULL, NULL, NULL, pcbTypeName))
- return FALSE;
-
- if (!(*pszTypeName = ((LPSTR)LocalAlloc(LMEM_ZEROINIT, *pcbTypeName))))
- return FALSE;
-
- if (RegQueryValueEx(hSubKey, "TypeName", NULL, NULL, (LPBYTE)*pszTypeName,
pcbTypeName))
- return FALSE;
-
+ goto cleanup;
+ cbName++;
+
+ if (!(szName = LocalAlloc(LMEM_ZEROINIT, cbName)))
+ goto cleanup;
+
+ while (!RegEnumKeyEx(hKey, *pdwIndex, szName, &cbName, NULL, NULL, NULL, NULL))
+ {
+ cbName++;
+ ch = szName + strlen(szName);
+ /* Convert "Type 000" to 0, etc/ */
+ *pdwProvType = *(--ch) - '0';
+ *pdwProvType += (*(--ch) - '0') * 10;
+ *pdwProvType += (*(--ch) - '0') * 100;
+
+ if (RegOpenKey(hKey, szName, &hSubKey))
+ break;
+
+ if (!RegQueryValueEx(hSubKey, "TypeName", NULL, NULL, NULL, pcbTypeName))
+ {
+ if (!(*pszTypeName = LocalAlloc(LMEM_ZEROINIT, *pcbTypeName)))
+ break;
+
+ if (!RegQueryValueEx(hSubKey, "TypeName", NULL, NULL, (LPBYTE)*pszTypeName,
pcbTypeName))
+ {
+ ret = TRUE;
+ break;
+ }
+
+ LocalFree(*pszTypeName);
+ }
+
+ RegCloseKey(hSubKey);
+
+ (*pdwIndex)++;
+ }
+
+ if (!ret)
+ LocalFree(*pszTypeName);
RegCloseKey(hSubKey);
+ LocalFree(szName);
+
+cleanup:
RegCloseKey(hKey);
-
- return TRUE;
+
+ return ret;
}
static void test_enum_provider_types(void)
{
/* expected values */
- DWORD dwProvType;
+ DWORD dwProvType = 0;
LPSTR pszTypeName = NULL;
DWORD cbTypeName;
DWORD dwTypeCount;
-
+
/* actual values */
DWORD index = 0;
DWORD provType;
@@ -622,45 +640,47 @@
DWORD result;
DWORD notNull = 5;
DWORD notZeroFlags = 5;
-
+
if(!pCryptEnumProviderTypesA)
{
- skip("CryptEnumProviderTypesA is not available\n");
- return;
- }
-
- if (!FindProvTypesRegVals(index, &dwProvType, &pszTypeName, &cbTypeName,
&dwTypeCount))
- {
- skip("Could not find provider types in registry\n");
- return;
- }
-
+ skip("CryptEnumProviderTypesA is not available\n");
+ return;
+ }
+
+ if (!FindProvTypesRegVals(&index, &dwProvType, &pszTypeName,
&cbTypeName, &dwTypeCount))
+ {
+ skip("Could not find provider types in registry\n");
+ return;
+ }
+
/* check pdwReserved for NULL */
result = pCryptEnumProviderTypesA(index, ¬Null, 0, &provType, typeName,
&typeNameSize);
- ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "expected %i, got
%d\n",
- ERROR_INVALID_PARAMETER, GetLastError());
-
+ ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "expected
ERROR_INVALID_PARAMETER, got %d\n",
+ GetLastError());
+
/* check dwFlags == zero */
result = pCryptEnumProviderTypesA(index, NULL, notZeroFlags, &provType, typeName,
&typeNameSize);
- ok(!result && GetLastError()==NTE_BAD_FLAGS, "expected %i, got %d\n",
- ERROR_INVALID_PARAMETER, GetLastError());
-
- /* alloc provider type to half the size required
- * cbTypeName holds the size required */
- typeNameSize = cbTypeName / 2;
- if (!(typeName = ((LPSTR)LocalAlloc(LMEM_ZEROINIT, typeNameSize))))
- return;
+ ok(!result && GetLastError()==NTE_BAD_FLAGS, "expected
ERROR_INVALID_PARAMETER, got %d\n",
+ GetLastError());
/* This test fails under Win2k SP4:
- result = TRUE, GetLastError() == 0xdeadbeef
- SetLastError(0xdeadbeef);
- result = pCryptEnumProviderTypesA(index, NULL, 0, &provType, typeName,
&typeNameSize);
- ok(!result && GetLastError()==ERROR_MORE_DATA, "expected 0/ERROR_MORE_DATA,
got %d/%08lx\n",
- result, GetLastError());
- */
-
- LocalFree(typeName);
-
+ * result = TRUE, GetLastError() == 0xdeadbeef */
+ if (0)
+ {
+ /* alloc provider type to half the size required
+ * cbTypeName holds the size required */
+ typeNameSize = cbTypeName / 2;
+ if (!(typeName = ((LPSTR)LocalAlloc(LMEM_ZEROINIT, typeNameSize))))
+ goto cleanup;
+
+ SetLastError(0xdeadbeef);
+ result = pCryptEnumProviderTypesA(index, NULL, 0, &provType, typeName,
&typeNameSize);
+ ok(!result && GetLastError()==ERROR_MORE_DATA, "expected
0/ERROR_MORE_DATA, got %d/%d\n",
+ result, GetLastError());
+
+ LocalFree(typeName);
+ }
+
/* loop through the provider types to get the number of provider types
* after loop ends, count should be dwTypeCount + 1 so subtract 1
* to get actual number of provider types */
@@ -669,30 +689,31 @@
;
typeCount--;
ok(typeCount==dwTypeCount, "expected %d, got %d\n", dwTypeCount, typeCount);
-
+
/* loop past the actual number of provider types to get the error
* ERROR_NO_MORE_ITEMS */
for (typeCount = 0; typeCount < dwTypeCount + 1; typeCount++)
result = pCryptEnumProviderTypesA(typeCount, NULL, 0, &provType, NULL,
&typeNameSize);
- ok(!result && GetLastError()==ERROR_NO_MORE_ITEMS, "expected %i, got
%d\n",
- ERROR_NO_MORE_ITEMS, GetLastError());
-
+ ok(!result && GetLastError()==ERROR_NO_MORE_ITEMS, "expected
ERROR_NO_MORE_ITEMS, got %d\n",
+ GetLastError());
/* check expected versus actual values returned */
result = pCryptEnumProviderTypesA(index, NULL, 0, &provType, NULL,
&typeNameSize);
ok(result && typeNameSize==cbTypeName, "expected %d, got %d\n",
cbTypeName, typeNameSize);
if (!(typeName = ((LPSTR)LocalAlloc(LMEM_ZEROINIT, typeNameSize))))
- return;
-
+ goto cleanup;
+
typeNameSize = 0xdeadbeef;
result = pCryptEnumProviderTypesA(index, NULL, 0, &provType, typeName,
&typeNameSize);
ok(result, "expected TRUE, got %d\n", result);
ok(provType==dwProvType, "expected %d, got %d\n", dwProvType, provType);
if (pszTypeName)
- ok(!strcmp(pszTypeName, typeName), "expected %s, got %s\n", pszTypeName,
typeName);
+ ok(!strcmp(pszTypeName, typeName), "expected %s, got %s\n", pszTypeName,
typeName);
ok(typeNameSize==cbTypeName, "expected %d, got %d\n", cbTypeName,
typeNameSize);
-
+
LocalFree(typeName);
+cleanup:
+ LocalFree(pszTypeName);
}
static BOOL FindDfltProvRegVals(DWORD dwProvType, DWORD dwFlags, LPSTR *pszProvName,
DWORD *pcbProvName)
Modified: trunk/rostests/winetests/advapi32/registry.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/advapi32/regist…
==============================================================================
--- trunk/rostests/winetests/advapi32/registry.c [iso-8859-1] (original)
+++ trunk/rostests/winetests/advapi32/registry.c [iso-8859-1] Tue Dec 9 13:26:45 2008
@@ -199,13 +199,14 @@
assert (!RegCreateKeyA( HKEY_CURRENT_USER, "Software\\Wine\\Test",
&hkey_main ));
}
-static void test_hkey_main_Value_A(LPCSTR name, LPCSTR string,
+#define lok ok_(__FILE__, line)
+#define test_hkey_main_Value_A(name, string, full_byte_len)
_test_hkey_main_Value_A(__LINE__, name, string, full_byte_len)
+static void _test_hkey_main_Value_A(int line, LPCSTR name, LPCSTR string,
DWORD full_byte_len)
{
DWORD ret, type, cbData;
DWORD str_byte_len;
- LPSTR value;
- static const char nA[]={'N', 0};
+ BYTE* value;
type=0xdeadbeef;
cbData=0xdeadbeef;
@@ -215,43 +216,44 @@
SetLastError(0xdeadbeef);
ret = RegQueryValueExA(hkey_main, name, NULL, &type, NULL, &cbData);
GLE = GetLastError();
- ok(ret == ERROR_SUCCESS, "RegQueryValueExA failed: %d, GLE=%d\n", ret,
GLE);
+ lok(ret == ERROR_SUCCESS, "RegQueryValueExA/1 failed: %d, GLE=%d\n", ret,
GLE);
/* It is wrong for the Ansi version to not be implemented */
ok(GLE == 0xdeadbeef, "RegQueryValueExA set GLE = %u\n", GLE);
if(GLE == ERROR_CALL_NOT_IMPLEMENTED) return;
str_byte_len = (string ? lstrlenA(string) : 0) + 1;
- ok(type == REG_SZ, "RegQueryValueExA returned type %d\n", type);
- ok(cbData == full_byte_len || cbData == str_byte_len /* Win9x */,
+ lok(type == REG_SZ, "RegQueryValueExA/1 returned type %d\n", type);
+ lok(cbData == full_byte_len || cbData == str_byte_len /* Win9x */,
"cbData=%d instead of %d or %d\n", cbData, full_byte_len,
str_byte_len);
- value = HeapAlloc(GetProcessHeap(), 0, (cbData+2)*sizeof(*value));
- strcpy(value, nA);
+ value = HeapAlloc(GetProcessHeap(), 0, cbData+1);
+ memset(value, 0xbd, cbData+1);
type=0xdeadbeef;
- ret = RegQueryValueExA(hkey_main, name, NULL, &type, (BYTE*)value, &cbData);
+ ret = RegQueryValueExA(hkey_main, name, NULL, &type, value, &cbData);
GLE = GetLastError();
- ok(ret == ERROR_SUCCESS, "RegQueryValueExA failed: %d, GLE=%d\n", ret,
GLE);
+ lok(ret == ERROR_SUCCESS, "RegQueryValueExA/2 failed: %d, GLE=%d\n", ret,
GLE);
if (!string)
{
/* When cbData == 0, RegQueryValueExA() should not modify the buffer */
- ok(strcmp(value, nA) == 0 || (cbData == 1 && *value == '\0') /*
Win9x */,
- "RegQueryValueExA failed: '%s' != '%s'\n", value,
string);
+ lok(*value == 0xbd || (cbData == 1 && *value == '\0') /* Win9x
*/,
+ "RegQueryValueExA overflowed: cbData=%u *value=%02x\n", cbData,
*value);
}
else
{
- ok(memcmp(value, string, cbData) == 0, "RegQueryValueExA failed: %s/%d !=
%s/%d\n",
- wine_debugstr_an(value, cbData), cbData,
+ lok(memcmp(value, string, cbData) == 0, "RegQueryValueExA/2 failed: %s/%d !=
%s/%d\n",
+ wine_debugstr_an((char*)value, cbData), cbData,
wine_debugstr_an(string, full_byte_len), full_byte_len);
+ lok(*(value+cbData) == 0xbd, "RegQueryValueExA/2 overflowed at offset %u:
%02x != bd\n", cbData, *(value+cbData));
}
HeapFree(GetProcessHeap(), 0, value);
}
-static void test_hkey_main_Value_W(LPCWSTR name, LPCWSTR string,
+#define test_hkey_main_Value_W(name, string, full_byte_len)
_test_hkey_main_Value_W(__LINE__, name, string, full_byte_len)
+static void _test_hkey_main_Value_W(int line, LPCWSTR name, LPCWSTR string,
DWORD full_byte_len)
{
DWORD ret, type, cbData;
- LPWSTR value;
- static const WCHAR nW[]={'N', 0};
+ BYTE* value;
type=0xdeadbeef;
cbData=0xdeadbeef;
@@ -261,31 +263,33 @@
SetLastError(0xdeadbeef);
ret = RegQueryValueExW(hkey_main, name, NULL, &type, NULL, &cbData);
GLE = GetLastError();
- ok(ret == ERROR_SUCCESS, "RegQueryValueExW failed: %d, GLE=%d\n", ret,
GLE);
+ lok(ret == ERROR_SUCCESS, "RegQueryValueExW/1 failed: %d, GLE=%d\n", ret,
GLE);
if(GLE == ERROR_CALL_NOT_IMPLEMENTED)
{
win_skip("RegQueryValueExW() is not implemented\n");
return;
}
- ok(type == REG_SZ, "RegQueryValueExW returned type %d\n", type);
- ok(cbData == full_byte_len,
+ lok(type == REG_SZ, "RegQueryValueExW/1 returned type %d\n", type);
+ lok(cbData == full_byte_len,
"cbData=%d instead of %d\n", cbData, full_byte_len);
- value = HeapAlloc(GetProcessHeap(), 0, (cbData+2)*sizeof(*value));
- lstrcpyW(value, nW);
+ /* Give enough space to overflow by one WCHAR */
+ value = HeapAlloc(GetProcessHeap(), 0, cbData+2);
+ memset(value, 0xbd, cbData+2);
type=0xdeadbeef;
- ret = RegQueryValueExW(hkey_main, name, NULL, &type, (BYTE*)value, &cbData);
+ ret = RegQueryValueExW(hkey_main, name, NULL, &type, value, &cbData);
GLE = GetLastError();
- ok(ret == ERROR_SUCCESS, "RegQueryValueExW failed: %d, GLE=%d\n", ret,
GLE);
- if (!string)
- {
- /* When cbData == 0, RegQueryValueExW() should not modify the buffer */
- string=nW;
- }
- ok(memcmp(value, string, cbData) == 0, "RegQueryValueExW failed: %s/%d !=
%s/%d\n",
- wine_debugstr_wn(value, cbData / sizeof(WCHAR)), cbData,
- wine_debugstr_wn(string, full_byte_len / sizeof(WCHAR)), full_byte_len);
+ lok(ret == ERROR_SUCCESS, "RegQueryValueExW/2 failed: %d, GLE=%d\n", ret,
GLE);
+ if (string)
+ {
+ lok(memcmp(value, string, cbData) == 0, "RegQueryValueExW failed: %s/%d !=
%s/%d\n",
+ wine_debugstr_wn((WCHAR*)value, cbData / sizeof(WCHAR)), cbData,
+ wine_debugstr_wn(string, full_byte_len / sizeof(WCHAR)), full_byte_len);
+ }
+ /* This implies that when cbData == 0, RegQueryValueExW() should not modify the
buffer */
+ lok(*(value+cbData) == 0xbd, "RegQueryValueExW/2 overflowed at %u: %02x !=
bd\n", cbData, *(value+cbData));
+ lok(*(value+cbData+1) == 0xbd, "RegQueryValueExW/2 overflowed at %u+1: %02x !=
bd\n", cbData, *(value+cbData+1));
HeapFree(GetProcessHeap(), 0, value);
}
@@ -957,6 +961,14 @@
ret == ERROR_FILE_NOT_FOUND /* Win9x,ME */
, "expected ERROR_BAD_PATHNAME or ERROR_FILE_NOT_FOUND, got %d\n",
ret);
+ hkResult = NULL;
+ ret = RegOpenKeyExA(HKEY_CLASSES_ROOT, "\\clsid", 0, KEY_QUERY_VALUE,
&hkResult);
+ ok(ret == ERROR_SUCCESS || /* 2k/XP */
+ ret == ERROR_BAD_PATHNAME || /* NT */
+ ret == ERROR_FILE_NOT_FOUND /* Win9x,ME */
+ , "expected ERROR_SUCCESS, ERROR_BAD_PATHNAME or ERROR_FILE_NOT_FOUND, got
%d\n", ret);
+ RegCloseKey(hkResult);
+
/* WOW64 flags */
hkResult = NULL;
ret = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software", 0,
KEY_READ|KEY_WOW64_32KEY, &hkResult);
@@ -1304,6 +1316,87 @@
ok(size == sizeof(expected), "Got wrong size: %d\n", size);
cleanup:
+ RegDeleteKeyA(subkey, "");
+ RegCloseKey(subkey);
+}
+
+static void test_string_termination(void)
+{
+ HKEY subkey;
+ LSTATUS ret;
+ static const char string[] = "FullString";
+ char name[11];
+ BYTE buffer[11];
+ DWORD insize, outsize, nsize;
+
+ ret = RegCreateKeyA(hkey_main, "string_termination", &subkey);
+ ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret);
+
+ /* Off-by-one RegSetValueExA -> adds a trailing '\0'! */
+ insize=sizeof(string)-1;
+ ret = RegSetValueExA(subkey, "stringtest", 0, REG_SZ, (BYTE*)string,
insize);
+ ok(ret == ERROR_SUCCESS, "RegSetValueExA failed: %d\n", ret);
+ outsize=insize;
+ ret = RegQueryValueExA(subkey, "stringtest", NULL, NULL, buffer,
&outsize);
+ ok(ret == ERROR_MORE_DATA, "RegQueryValueExA returned: %d\n", ret);
+
+ /* Off-by-two RegSetValueExA -> no trailing '\0', except on Win9x */
+ insize=sizeof(string)-2;
+ ret = RegSetValueExA(subkey, "stringtest", 0, REG_SZ, (BYTE*)string,
insize);
+ ok(ret == ERROR_SUCCESS, "RegSetValueExA failed: %d\n", ret);
+ outsize=0;
+ ret = RegQueryValueExA(subkey, "stringtest", NULL, NULL, NULL,
&outsize);
+ ok(ret == ERROR_SUCCESS, "RegQueryValueExA failed: %d\n", ret);
+ ok(outsize == insize || broken(outsize == sizeof(string)) /* Win9x */,
+ "wrong size %u != %u\n", outsize, insize);
+
+ if (outsize == insize)
+ {
+ /* RegQueryValueExA may return a string with no trailing '\0' */
+ outsize=insize;
+ memset(buffer, 0xbd, sizeof(buffer));
+ ret = RegQueryValueExA(subkey, "stringtest", NULL, NULL, buffer,
&outsize);
+ ok(ret == ERROR_SUCCESS, "RegQueryValueExA failed: %d\n", ret);
+ ok(outsize == insize, "wrong size: %u != %u\n", outsize, insize);
+ ok(memcmp(buffer, string, outsize) == 0, "bad string: %s/%u != %s\n",
+ wine_debugstr_an((char*)buffer, outsize), outsize, string);
+ ok(buffer[insize] == 0xbd, "buffer overflow at %u %02x\n", insize,
buffer[insize]);
+
+ /* RegQueryValueExA adds a trailing '\0' if there is room */
+ outsize=insize+1;
+ memset(buffer, 0xbd, sizeof(buffer));
+ ret = RegQueryValueExA(subkey, "stringtest", NULL, NULL, buffer,
&outsize);
+ ok(ret == ERROR_SUCCESS, "RegQueryValueExA failed: %d\n", ret);
+ ok(outsize == insize, "wrong size: %u != %u\n", outsize, insize);
+ ok(memcmp(buffer, string, outsize) == 0, "bad string: %s/%u != %s\n",
+ wine_debugstr_an((char*)buffer, outsize), outsize, string);
+ ok(buffer[insize] == 0, "buffer overflow at %u %02x\n", insize,
buffer[insize]);
+
+ /* RegEnumValueA may return a string with no trailing '\0' */
+ outsize=insize;
+ memset(buffer, 0xbd, sizeof(buffer));
+ nsize=sizeof(name);
+ ret = RegEnumValueA(subkey, 0, name, &nsize, NULL, NULL, buffer,
&outsize);
+ ok(ret == ERROR_SUCCESS, "RegEnumValueA failed: %d\n", ret);
+ ok(strcmp(name, "stringtest") == 0, "wrong name: %s\n",
name);
+ ok(outsize == insize, "wrong size: %u != %u\n", outsize, insize);
+ ok(memcmp(buffer, string, outsize) == 0, "bad string: %s/%u != %s\n",
+ wine_debugstr_an((char*)buffer, outsize), outsize, string);
+ ok(buffer[insize] == 0xbd, "buffer overflow at %u %02x\n", insize,
buffer[insize]);
+
+ /* RegEnumValueA adds a trailing '\0' if there is room */
+ outsize=insize+1;
+ memset(buffer, 0xbd, sizeof(buffer));
+ nsize=sizeof(name);
+ ret = RegEnumValueA(subkey, 0, name, &nsize, NULL, NULL, buffer,
&outsize);
+ ok(ret == ERROR_SUCCESS, "RegEnumValueA failed: %d\n", ret);
+ ok(strcmp(name, "stringtest") == 0, "wrong name: %s\n",
name);
+ ok(outsize == insize, "wrong size: %u != %u\n", outsize, insize);
+ ok(memcmp(buffer, string, outsize) == 0, "bad string: %s/%u != %s\n",
+ wine_debugstr_an((char*)buffer, outsize), outsize, string);
+ ok(buffer[insize] == 0, "buffer overflow at %u %02x\n", insize,
buffer[insize]);
+ }
+
RegDeleteKeyA(subkey, "");
RegCloseKey(subkey);
}
@@ -1398,6 +1491,7 @@
test_reg_close_key();
test_reg_delete_key();
test_reg_query_value();
+ test_string_termination();
/* SaveKey/LoadKey require the SE_BACKUP_NAME privilege to be set */
if (set_privileges(SE_BACKUP_NAME, TRUE) &&
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] Tue Dec 9 13:26:45 2008
@@ -81,10 +81,14 @@
typedef BOOL (WINAPI *fnConvertStringSidToSidA)( LPCSTR str, PSID pSid );
static BOOL (WINAPI *pConvertStringSecurityDescriptorToSecurityDescriptorA)(LPCSTR,
DWORD,
PSECURITY_DESCRIPTOR*, PULONG );
+static BOOL (WINAPI *pConvertStringSecurityDescriptorToSecurityDescriptorW)(LPCWSTR,
DWORD,
+
PSECURITY_DESCRIPTOR*, PULONG );
static BOOL (WINAPI
*pConvertSecurityDescriptorToStringSecurityDescriptorA)(PSECURITY_DESCRIPTOR, DWORD,
SECURITY_INFORMATION, LPSTR *, PULONG );
typedef BOOL (WINAPI *fnGetFileSecurityA)(LPCSTR, SECURITY_INFORMATION,
PSECURITY_DESCRIPTOR, DWORD, LPDWORD);
+typedef BOOL (WINAPI *fnSetFileSecurityA)(LPCSTR, SECURITY_INFORMATION,
+ PSECURITY_DESCRIPTOR);
static DWORD (WINAPI *pGetNamedSecurityInfoA)(LPSTR, SE_OBJECT_TYPE,
SECURITY_INFORMATION,
PSID*, PSID*, PACL*, PACL*,
PSECURITY_DESCRIPTOR*);
@@ -117,6 +121,7 @@
fnConvertSidToStringSidA pConvertSidToStringSidA;
fnConvertStringSidToSidA pConvertStringSidToSidA;
fnGetFileSecurityA pGetFileSecurityA;
+fnSetFileSecurityA pSetFileSecurityA;
fnRtlAdjustPrivilege pRtlAdjustPrivilege;
fnCreateWellKnownSid pCreateWellKnownSid;
fnDuplicateTokenEx pDuplicateTokenEx;
@@ -144,8 +149,12 @@
pAddAuditAccessAceEx = (void *)GetProcAddress(hmod,
"AddAuditAccessAceEx");
pConvertStringSecurityDescriptorToSecurityDescriptorA =
(void *)GetProcAddress(hmod,
"ConvertStringSecurityDescriptorToSecurityDescriptorA" );
+ pConvertStringSecurityDescriptorToSecurityDescriptorW =
+ (void *)GetProcAddress(hmod,
"ConvertStringSecurityDescriptorToSecurityDescriptorW" );
pConvertSecurityDescriptorToStringSecurityDescriptorA =
(void *)GetProcAddress(hmod,
"ConvertSecurityDescriptorToStringSecurityDescriptorA" );
+ pGetFileSecurityA = (fnGetFileSecurityA)GetProcAddress(hmod,
"GetFileSecurityA" );
+ pSetFileSecurityA = (fnSetFileSecurityA)GetProcAddress(hmod,
"SetFileSecurityA" );
pCreateWellKnownSid = (fnCreateWellKnownSid)GetProcAddress( hmod,
"CreateWellKnownSid" );
pGetNamedSecurityInfoA = (void *)GetProcAddress(hmod,
"GetNamedSecurityInfoA");
pMakeSelfRelativeSD = (void *)GetProcAddress(hmod, "MakeSelfRelativeSD");
@@ -495,7 +504,7 @@
#define SE_DEBUG_PRIVILEGE 20L
#define SE_AUDIT_PRIVILEGE 21L
#define SE_SYSTEM_ENVIRONMENT_PRIVILEGE 22L
-#define SE_CHANGE_NOTIFY_PRIVILLEGE 23L
+#define SE_CHANGE_NOTIFY_PRIVILEGE 23L
#define SE_REMOTE_SHUTDOWN_PRIVILEGE 24L
#define SE_UNDOCK_PRIVILEGE 25L
#define SE_SYNC_AGENT_PRIVILEGE 26L
@@ -570,7 +579,7 @@
"SeCreateTokenPrivilege (got %d, expected %d)\n", cchName,
(int)strlen("SeCreateTokenPrivilege"));
/* check known values */
- for (i = SE_MIN_WELL_KNOWN_PRIVILEGE; i < SE_MAX_WELL_KNOWN_PRIVILEGE; i++)
+ for (i = SE_MIN_WELL_KNOWN_PRIVILEGE; i <= SE_MAX_WELL_KNOWN_PRIVILEGE; i++)
{
luid.LowPart = i;
cchName = sizeof(buf);
@@ -625,7 +634,7 @@
{ "SeDebugPrivilege", SE_DEBUG_PRIVILEGE },
{ "SeAuditPrivilege", SE_AUDIT_PRIVILEGE },
{ "SeSystemEnvironmentPrivilege", SE_SYSTEM_ENVIRONMENT_PRIVILEGE },
- { "SeChangeNotifyPrivilege", SE_CHANGE_NOTIFY_PRIVILLEGE },
+ { "SeChangeNotifyPrivilege", SE_CHANGE_NOTIFY_PRIVILEGE },
{ "SeRemoteShutdownPrivilege", SE_REMOTE_SHUTDOWN_PRIVILEGE },
{ "SeUndockPrivilege", SE_UNDOCK_PRIVILEGE },
{ "SeSyncAgentPrivilege", SE_SYNC_AGENT_PRIVILEGE },
@@ -690,31 +699,128 @@
static void test_FileSecurity(void)
{
- char directory[MAX_PATH];
- DWORD retval, outSize;
- BOOL result;
- BYTE buffer[0x40];
-
- pGetFileSecurityA = (fnGetFileSecurityA)
- GetProcAddress( hmod, "GetFileSecurityA" );
- if( !pGetFileSecurityA )
- return;
-
- retval = GetTempPathA(sizeof(directory), directory);
- if (!retval) {
- trace("GetTempPathA failed\n");
- return;
- }
-
- strcpy(directory, "\\Should not exist");
-
- SetLastError(NO_ERROR);
- result = pGetFileSecurityA(
directory,OWNER_SECURITY_INFORMATION,buffer,0x40,&outSize);
- ok(!result, "GetFileSecurityA should fail for not existing
directories/files\n");
- ok( (GetLastError() == ERROR_FILE_NOT_FOUND ) ||
- (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) ,
- "last error ERROR_FILE_NOT_FOUND / ERROR_CALL_NOT_IMPLEMENTED (98) "
- "expected, got %d\n", GetLastError());
+ char wintmpdir [MAX_PATH];
+ char path [MAX_PATH];
+ char file [MAX_PATH];
+ BOOL rc;
+ HANDLE fh;
+ DWORD sdSize;
+ DWORD retSize;
+ BYTE *sd;
+ SECURITY_INFORMATION const request = OWNER_SECURITY_INFORMATION
+ | GROUP_SECURITY_INFORMATION
+ | DACL_SECURITY_INFORMATION;
+
+ if (!pGetFileSecurityA) {
+ win_skip ("GetFileSecurity is not available\n");
+ return;
+ }
+
+ if (!pSetFileSecurityA) {
+ win_skip ("SetFileSecurity is not available\n");
+ return;
+ }
+
+ if (!GetTempPathA (sizeof (wintmpdir), wintmpdir)) {
+ win_skip ("GetTempPathA failed\n");
+ return;
+ }
+
+ /* Create a temporary directory and in it a temporary file */
+ strcat (strcpy (path, wintmpdir), "rary");
+ SetLastError(0xdeadbeef);
+ rc = CreateDirectoryA (path, NULL);
+ ok (rc || GetLastError() == ERROR_ALREADY_EXISTS, "CreateDirectoryA "
+ "failed for '%s' with %d\n", path, GetLastError());
+
+ strcat (strcpy (file, path), "\\ess");
+ SetLastError(0xdeadbeef);
+ fh = CreateFileA (file, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
+ ok (fh != INVALID_HANDLE_VALUE, "CreateFileA "
+ "failed for '%s' with %d\n", file, GetLastError());
+ CloseHandle (fh);
+
+ /* For the temporary file ... */
+
+ /* Get size needed */
+ retSize = 0;
+ SetLastError(0xdeadbeef);
+ rc = pGetFileSecurityA (file, request, NULL, 0, &retSize);
+ if (!rc && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)) {
+ win_skip("GetFileSecurityA is not implemented\n");
+ goto cleanup;
+ }
+ ok (!rc, "GetFileSecurityA "
+ "was expected to fail for '%s'\n", file);
+ ok (GetLastError() == ERROR_INSUFFICIENT_BUFFER, "GetFileSecurityA "
+ "returned %d; expected ERROR_INSUFFICIENT_BUFFER\n", GetLastError());
+ ok (retSize > sizeof (SECURITY_DESCRIPTOR), "GetFileSecurityA returned size
%d\n", retSize);
+
+ sdSize = retSize;
+ sd = HeapAlloc (GetProcessHeap (), 0, sdSize);
+
+ /* Get security descriptor for real */
+ retSize = -1;
+ SetLastError(0xdeadbeef);
+ rc = pGetFileSecurityA (file, request, sd, sdSize, &retSize);
+ ok (rc, "GetFileSecurityA "
+ "was not expected to fail '%s': %d\n", file, GetLastError());
+ ok (retSize == sdSize ||
+ broken(retSize == 0), /* NT4 */
+ "GetFileSecurityA returned size %d; expected %d\n", retSize, sdSize);
+
+ /* Use it to set security descriptor */
+ SetLastError(0xdeadbeef);
+ rc = pSetFileSecurityA (file, request, sd);
+ ok (rc, "SetFileSecurityA "
+ "was not expected to fail '%s': %d\n", file, GetLastError());
+
+ HeapFree (GetProcessHeap (), 0, sd);
+
+ /* Repeat for the temporary directory ... */
+
+ /* Get size needed */
+ retSize = 0;
+ SetLastError(0xdeadbeef);
+ rc = pGetFileSecurityA (path, request, NULL, 0, &retSize);
+ ok (!rc, "GetFileSecurityA "
+ "was expected to fail for '%s'\n", path);
+ ok (GetLastError() == ERROR_INSUFFICIENT_BUFFER, "GetFileSecurityA "
+ "returned %d; expected ERROR_INSUFFICIENT_BUFFER\n", GetLastError());
+ ok (retSize > sizeof (SECURITY_DESCRIPTOR), "GetFileSecurityA returned size
%d\n", retSize);
+
+ sdSize = retSize;
+ sd = HeapAlloc (GetProcessHeap (), 0, sdSize);
+
+ /* Get security descriptor for real */
+ retSize = -1;
+ SetLastError(0xdeadbeef);
+ rc = pGetFileSecurityA (path, request, sd, sdSize, &retSize);
+ ok (rc, "GetFileSecurityA "
+ "was not expected to fail '%s': %d\n", path, GetLastError());
+ ok (retSize == sdSize ||
+ broken(retSize == 0), /* NT4 */
+ "GetFileSecurityA returned size %d; expected %d\n", retSize, sdSize);
+
+ /* Use it to set security descriptor */
+ SetLastError(0xdeadbeef);
+ rc = pSetFileSecurityA (path, request, sd);
+ ok (rc, "SetFileSecurityA "
+ "was not expected to fail '%s': %d\n", path, GetLastError());
+ HeapFree (GetProcessHeap (), 0, sd);
+
+ /* Old test */
+ strcpy (wintmpdir, "\\Should not exist");
+ SetLastError(0xdeadbeef);
+ rc = pGetFileSecurityA (wintmpdir, OWNER_SECURITY_INFORMATION, NULL, 0,
&sdSize);
+ ok (!rc, "GetFileSecurityA should fail for not existing
directories/files\n");
+ ok (GetLastError() == ERROR_FILE_NOT_FOUND,
+ "last error ERROR_FILE_NOT_FOUND expected, got %d\n", GetLastError());
+
+cleanup:
+ /* Remove temporary file and directory */
+ DeleteFileA(file);
+ RemoveDirectoryA(path);
}
static void test_AccessCheck(void)
@@ -1309,6 +1415,14 @@
real_dom_sizeW = MAX_PATH;
ret = LookupAccountSidW(NULL, pUsersSid, accountW, &real_acc_sizeW, domainW,
&real_dom_sizeW, &use);
ok(ret, "LookupAccountSidW() Expected TRUE, got FALSE\n");
+
+ /* try an invalid system name */
+ real_acc_sizeA = MAX_PATH;
+ real_dom_sizeA = MAX_PATH;
+ ret = LookupAccountSidA("deepthought", pUsersSid, accountA,
&real_acc_sizeA, domainA, &real_dom_sizeA, &use);
+ ok(!ret, "LookupAccountSidA() Expected FALSE got TRUE\n");
+ ok(GetLastError() == RPC_S_SERVER_UNAVAILABLE || GetLastError() ==
RPC_S_INVALID_NET_ADDR /* Vista */,
+ "LookupAccountSidA() Expected RPC_S_SERVER_UNAVAILABLE or
RPC_S_INVALID_NET_ADDR, got %u\n", GetLastError());
/* native windows crashes if domainW or accountW is NULL */
@@ -1550,10 +1664,10 @@
{
ok(!lstrcmp(account, user_name), "Expected %s, got %s\n", user_name,
account);
ok(!lstrcmp(domain, sid_dom), "Expected %s, got %s\n", sid_dom,
domain);
- ok(domain_size == domain_save - 1, "Expected %d, got %d\n", domain_save
- 1, domain_size);
- ok(lstrlen(domain) == domain_size, "Expected %d\n", lstrlen(domain));
- ok(sid_use == SidTypeUser, "Expected SidTypeUser, got %d\n", sid_use);
- }
+ }
+ ok(domain_size == domain_save - 1, "Expected %d, got %d\n", domain_save -
1, domain_size);
+ ok(lstrlen(domain) == domain_size, "Expected %d, got %d\n",
lstrlen(domain), domain_size);
+ ok(sid_use == SidTypeUser, "Expected SidTypeUser (%d), got %d\n",
SidTypeUser, sid_use);
domain_size = domain_save;
sid_size = sid_save;
@@ -1568,12 +1682,10 @@
ok(ret, "Failed to lookup account name\n");
ok(sid_size != 0, "sid_size was zero\n");
ok(!lstrcmp(account, "Everyone"), "Expected Everyone, got
%s\n", account);
- todo_wine
ok(!lstrcmp(domain, sid_dom), "Expected %s, got %s\n", sid_dom,
domain);
ok(domain_size == 0, "Expected 0, got %d\n", domain_size);
- todo_wine
ok(lstrlen(domain) == domain_size, "Expected %d, got %d\n",
lstrlen(domain), domain_size);
- ok(sid_use == SidTypeWellKnownGroup, "Expected SidTypeUser, got %d\n",
sid_use);
+ ok(sid_use == SidTypeWellKnownGroup, "Expected SidTypeWellKnownGroup (%d),
got %d\n", SidTypeWellKnownGroup, sid_use);
domain_size = domain_save;
}
@@ -1616,28 +1728,33 @@
sid_use = 0xcafebabe;
SetLastError(0xdeadbeef);
ret = LookupAccountNameA(NULL, NULL, NULL, &sid_size, NULL, &domain_size,
&sid_use);
- ok(!ret, "Expected 0, got %d\n", ret);
- ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
- "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
- ok(sid_size != 0, "Expected non-zero sid size\n");
- ok(domain_size != 0, "Expected non-zero domain size\n");
- ok(sid_use == 0xcafebabe, "Expected 0xcafebabe, got %d\n", sid_use);
-
- psid = HeapAlloc(GetProcessHeap(), 0, sid_size);
- domain = HeapAlloc(GetProcessHeap(), 0, domain_size);
-
- /* try NULL account name */
- ret = LookupAccountNameA(NULL, NULL, psid, &sid_size, domain, &domain_size,
&sid_use);
- get_sid_info(psid, &account, &sid_dom);
- ok(ret, "Failed to lookup account name\n");
- todo_wine
- {
+ if (!ret && GetLastError() != ERROR_NONE_MAPPED)
+ {
+ ok(!ret, "Expected 0, got %d\n", ret);
+ ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
+ "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
+ ok(sid_size != 0, "Expected non-zero sid size\n");
+ ok(domain_size != 0, "Expected non-zero domain size\n");
+ ok(sid_use == 0xcafebabe, "Expected 0xcafebabe, got %d\n", sid_use);
+
+ psid = HeapAlloc(GetProcessHeap(), 0, sid_size);
+ domain = HeapAlloc(GetProcessHeap(), 0, domain_size);
+
+ /* try NULL account name */
+ ret = LookupAccountNameA(NULL, NULL, psid, &sid_size, domain,
&domain_size, &sid_use);
+ get_sid_info(psid, &account, &sid_dom);
+ ok(ret, "Failed to lookup account name\n");
/* Using a fixed string will not work on different locales */
ok(!lstrcmp(account, domain),
"Got %s for account and %s for domain, these should be the same\n",
account, domain);
- ok(sid_use == SidTypeDomain, "Expected SidTypeDomain, got %d\n",
SidTypeDomain);
- }
+ ok(sid_use == SidTypeDomain, "Expected SidTypeDomain (%d), got %d\n",
SidTypeDomain, sid_use);
+
+ HeapFree(GetProcessHeap(), 0, psid);
+ HeapFree(GetProcessHeap(), 0, domain);
+ }
+ else
+ win_skip("NULL account name doesn't work on NT4\n");
/* try an invalid account name */
SetLastError(0xdeadbeef);
@@ -1645,17 +1762,22 @@
domain_size = 0;
ret = LookupAccountNameA(NULL, "oogabooga", NULL, &sid_size, NULL,
&domain_size, &sid_use);
ok(!ret, "Expected 0, got %d\n", ret);
- todo_wine
- {
- ok(GetLastError() == ERROR_NONE_MAPPED ||
- broken(GetLastError() == ERROR_TRUSTED_RELATIONSHIP_FAILURE),
- "Expected ERROR_NONE_MAPPED, got %d\n", GetLastError());
- ok(sid_size == 0, "Expected 0, got %d\n", sid_size);
- ok(domain_size == 0, "Expected 0, got %d\n", domain_size);
- }
-
- HeapFree(GetProcessHeap(), 0, psid);
- HeapFree(GetProcessHeap(), 0, domain);
+ ok(GetLastError() == ERROR_NONE_MAPPED ||
+ broken(GetLastError() == ERROR_TRUSTED_RELATIONSHIP_FAILURE),
+ "Expected ERROR_NONE_MAPPED, got %d\n", GetLastError());
+ ok(sid_size == 0, "Expected 0, got %d\n", sid_size);
+ ok(domain_size == 0, "Expected 0, got %d\n", domain_size);
+
+ /* try an invalid system name */
+ SetLastError(0xdeadbeef);
+ sid_size = 0;
+ domain_size = 0;
+ ret = LookupAccountNameA("deepthought", NULL, NULL, &sid_size, NULL,
&domain_size, &sid_use);
+ ok(!ret, "Expected 0, got %d\n", ret);
+ ok(GetLastError() == RPC_S_SERVER_UNAVAILABLE || GetLastError() ==
RPC_S_INVALID_NET_ADDR /* Vista */,
+ "Expected RPC_S_SERVER_UNAVAILABLE or RPC_S_INVALID_NET_ADDR, got %d\n",
GetLastError());
+ ok(sid_size == 0, "Expected 0, got %d\n", sid_size);
+ ok(domain_size == 0, "Expected 0, got %d\n", domain_size);
}
static void test_security_descriptor(void)
@@ -1962,7 +2084,7 @@
ret = GetTokenInformation(Token, TokenUser, NULL, 0, &Size);
error = GetLastError();
ok(!ret && error == ERROR_INSUFFICIENT_BUFFER,
"GetTokenInformation(TokenUser) should have failed with ERROR_INSUFFICIENT_BUFFER
instead of %d\n", error);
- User = (TOKEN_USER *)HeapAlloc(GetProcessHeap(), 0, Size);
+ User = HeapAlloc(GetProcessHeap(), 0, Size);
ret = GetTokenInformation(Token, TokenUser, User, Size, &Size);
ok(ret, "GetTokenInformation(TokenUser) failed with error %d\n",
GetLastError());
HeapFree(GetProcessHeap(), 0, User);
@@ -1971,11 +2093,11 @@
ret = GetTokenInformation(Token, TokenPrivileges, NULL, 0, &Size);
error = GetLastError();
ok(!ret && error == ERROR_INSUFFICIENT_BUFFER,
"GetTokenInformation(TokenPrivileges) should have failed with
ERROR_INSUFFICIENT_BUFFER instead of %d\n", error);
- Privileges = (TOKEN_PRIVILEGES *)HeapAlloc(GetProcessHeap(), 0, Size);
+ Privileges = HeapAlloc(GetProcessHeap(), 0, Size);
ret = GetTokenInformation(Token, TokenPrivileges, Privileges, Size, &Size);
ok(ret, "GetTokenInformation(TokenPrivileges) failed with error %d\n",
GetLastError());
- PrivilegeSet = (PRIVILEGE_SET *)HeapAlloc(GetProcessHeap(), 0,
FIELD_OFFSET(PRIVILEGE_SET, Privilege[Privileges->PrivilegeCount]));
+ PrivilegeSet = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(PRIVILEGE_SET,
Privilege[Privileges->PrivilegeCount]));
PrivilegeSet->PrivilegeCount = Privileges->PrivilegeCount;
memcpy(PrivilegeSet->Privilege, Privileges->Privileges,
PrivilegeSet->PrivilegeCount * sizeof(PrivilegeSet->Privilege[0]));
PrivilegeSet->Control = PRIVILEGE_SET_ALL_NECESSARY;
@@ -2031,7 +2153,7 @@
if (!pSetEntriesInAclW)
{
- skip("SetEntriesInAclW is not available\n");
+ win_skip("SetEntriesInAclW is not available\n");
return;
}
@@ -2039,17 +2161,20 @@
res = pSetEntriesInAclW(0, NULL, NULL, &NewAcl);
if(res == ERROR_CALL_NOT_IMPLEMENTED)
{
- skip("SetEntriesInAclW is not implemented\n");
+ win_skip("SetEntriesInAclW is not implemented\n");
return;
}
ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %u\n", res);
- ok(NewAcl == NULL, "NewAcl=%p, expected NULL\n", NewAcl);
+ ok(NewAcl == NULL ||
+ broken(NewAcl != NULL), /* NT4 */
+ "NewAcl=%p, expected NULL\n", NewAcl);
+ LocalFree(NewAcl);
OldAcl = HeapAlloc(GetProcessHeap(), 0, 256);
res = InitializeAcl(OldAcl, 256, ACL_REVISION);
if(!res && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
{
- skip("ACLs not implemented - skipping tests\n");
+ win_skip("ACLs not implemented - skipping tests\n");
HeapFree(GetProcessHeap(), 0, OldAcl);
return;
}
@@ -2093,16 +2218,22 @@
ExplicitAccess.Trustee.TrusteeForm = TRUSTEE_BAD_FORM;
res = pSetEntriesInAclW(1, &ExplicitAccess, OldAcl, &NewAcl);
- ok(res == ERROR_INVALID_PARAMETER, "SetEntriesInAclW failed: %u\n",
res);
- ok(NewAcl == NULL, "returned acl wasn't NULL: %p\n", NewAcl);
- LocalFree(NewAcl);
+ ok(res == ERROR_INVALID_PARAMETER ||
+ broken(res == ERROR_NOT_SUPPORTED), /* NT4 */
+ "SetEntriesInAclW failed: %u\n", res);
+ ok(NewAcl == NULL ||
+ broken(NewAcl != NULL), /* NT4 */
+ "returned acl wasn't NULL: %p\n", NewAcl);
ExplicitAccess.Trustee.TrusteeForm = TRUSTEE_IS_USER;
ExplicitAccess.Trustee.MultipleTrusteeOperation = TRUSTEE_IS_IMPERSONATE;
res = pSetEntriesInAclW(1, &ExplicitAccess, OldAcl, &NewAcl);
- ok(res == ERROR_INVALID_PARAMETER, "SetEntriesInAclW failed: %u\n",
res);
- ok(NewAcl == NULL, "returned acl wasn't NULL: %p\n", NewAcl);
- LocalFree(NewAcl);
+ ok(res == ERROR_INVALID_PARAMETER ||
+ broken(res == ERROR_NOT_SUPPORTED), /* NT4 */
+ "SetEntriesInAclW failed: %u\n", res);
+ ok(NewAcl == NULL ||
+ broken(NewAcl != NULL), /* NT4 */
+ "returned acl wasn't NULL: %p\n", NewAcl);
ExplicitAccess.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
ExplicitAccess.grfAccessMode = SET_ACCESS;
@@ -2175,6 +2306,7 @@
{
BOOL ret;
PSECURITY_DESCRIPTOR pSD;
+ static const WCHAR Blank[] = { 0 };
if (!pConvertStringSecurityDescriptorToSecurityDescriptorA)
{
@@ -2255,10 +2387,50 @@
SetLastError(0xdeadbeef);
ret = pConvertStringSecurityDescriptorToSecurityDescriptorA(
"D:(A;;ROB;;;WD)", SDDL_REVISION_1, &pSD, NULL);
- todo_wine
ok(!ret && GetLastError() == ERROR_INVALID_ACL,
"ConvertStringSecurityDescriptorToSecurityDescriptor should have failed with
ERROR_INVALID_ACL instead of %d\n",
GetLastError());
+
+ /* test behaviour with NULL parameters */
+ SetLastError(0xdeadbeef);
+ ret = pConvertStringSecurityDescriptorToSecurityDescriptorA(
+ NULL, 0xdeadbeef, &pSD, NULL);
+ todo_wine
+ ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
+ "ConvertStringSecurityDescriptorToSecurityDescriptor should have failed with
ERROR_INVALID_PARAMETER instead of %d\n",
+ GetLastError());
+
+ SetLastError(0xdeadbeef);
+ ret = pConvertStringSecurityDescriptorToSecurityDescriptorW(
+ NULL, 0xdeadbeef, &pSD, NULL);
+ ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
+ "ConvertStringSecurityDescriptorToSecurityDescriptor should have failed with
ERROR_INVALID_PARAMETER instead of %d\n",
+ GetLastError());
+
+ SetLastError(0xdeadbeef);
+ ret = pConvertStringSecurityDescriptorToSecurityDescriptorA(
+ "D:(A;;ROB;;;WD)", 0xdeadbeef, NULL, NULL);
+ ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
+ "ConvertStringSecurityDescriptorToSecurityDescriptor should have failed with
ERROR_INVALID_PARAMETER instead of %d\n",
+ GetLastError());
+
+ SetLastError(0xdeadbeef);
+ ret = pConvertStringSecurityDescriptorToSecurityDescriptorA(
+ "D:(A;;ROB;;;WD)", SDDL_REVISION_1, NULL, NULL);
+ ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
+ "ConvertStringSecurityDescriptorToSecurityDescriptor should have failed with
ERROR_INVALID_PARAMETER instead of %d\n",
+ GetLastError());
+
+ /* test behaviour with empty strings */
+ SetLastError(0xdeadbeef);
+ ret = pConvertStringSecurityDescriptorToSecurityDescriptorA(
+ "", SDDL_REVISION_1, &pSD, NULL);
+ ok(ret, "ConvertStringSecurityDescriptorToSecurityDescriptor failed with error
%d\n", GetLastError());
+
+ SetLastError(0xdeadbeef);
+ ret = pConvertStringSecurityDescriptorToSecurityDescriptorW(
+ Blank, SDDL_REVISION_1, &pSD, NULL);
+ ok(ret, "ConvertStringSecurityDescriptorToSecurityDescriptor failed with error
%d\n", GetLastError());
/* test ACE string SID */
SetLastError(0xdeadbeef);
@@ -2386,11 +2558,100 @@
}
}
+static void test_SetSecurityDescriptorControl (PSECURITY_DESCRIPTOR sec)
+{
+ SECURITY_DESCRIPTOR_CONTROL ref;
+ SECURITY_DESCRIPTOR_CONTROL test;
+
+ SECURITY_DESCRIPTOR_CONTROL const mutable
+ = SE_DACL_AUTO_INHERIT_REQ | SE_SACL_AUTO_INHERIT_REQ
+ | SE_DACL_AUTO_INHERITED | SE_SACL_AUTO_INHERITED
+ | SE_DACL_PROTECTED | SE_SACL_PROTECTED
+ | 0x00000040 | 0x00000080 /* not defined in winnt.h */
+ ;
+ SECURITY_DESCRIPTOR_CONTROL const immutable
+ = SE_OWNER_DEFAULTED | SE_GROUP_DEFAULTED
+ | SE_DACL_PRESENT | SE_DACL_DEFAULTED
+ | SE_SACL_PRESENT | SE_SACL_DEFAULTED
+ | SE_RM_CONTROL_VALID | SE_SELF_RELATIVE
+ ;
+
+ int bit;
+ DWORD dwRevision;
+ LPCSTR fmt = "Expected error %s, got %u\n";
+
+ GetSecurityDescriptorControl (sec, &ref, &dwRevision);
+
+ /* The mutable bits are mutable regardless of the truth of
+ SE_DACL_PRESENT and/or SE_SACL_PRESENT */
+
+ /* Check call barfs if any bit-of-interest is immutable */
+ for (bit = 0; bit < 16; ++bit)
+ {
+ SECURITY_DESCRIPTOR_CONTROL const bitOfInterest = 1 << bit;
+ SECURITY_DESCRIPTOR_CONTROL setOrClear = ref & bitOfInterest;
+
+ SECURITY_DESCRIPTOR_CONTROL ctrl;
+
+ DWORD dwExpect = (bitOfInterest & immutable)
+ ? ERROR_INVALID_PARAMETER : 0xbebecaca;
+ LPCSTR strExpect = (bitOfInterest & immutable)
+ ? "ERROR_INVALID_PARAMETER" :
"0xbebecaca";
+
+ ctrl = (bitOfInterest & mutable) ? ref + bitOfInterest : ref;
+ setOrClear ^= bitOfInterest;
+ SetLastError (0xbebecaca);
+ pSetSecurityDescriptorControl (sec, bitOfInterest, setOrClear);
+ ok (GetLastError () == dwExpect, fmt, strExpect, GetLastError ());
+ GetSecurityDescriptorControl(sec, &test, &dwRevision);
+ expect_eq(test, ctrl, int, "%x");
+
+ ctrl = ref;
+ setOrClear ^= bitOfInterest;
+ SetLastError (0xbebecaca);
+ pSetSecurityDescriptorControl (sec, bitOfInterest, setOrClear);
+ ok (GetLastError () == dwExpect, fmt, strExpect, GetLastError ());
+ GetSecurityDescriptorControl (sec, &test, &dwRevision);
+ expect_eq(test, ref, int, "%x");
+ }
+
+ /* Check call barfs if any bit-to-set is immutable
+ even when not a bit-of-interest */
+ for (bit = 0; bit < 16; ++bit)
+ {
+ SECURITY_DESCRIPTOR_CONTROL const bitsOfInterest = mutable;
+ SECURITY_DESCRIPTOR_CONTROL setOrClear = ref & bitsOfInterest;
+
+ SECURITY_DESCRIPTOR_CONTROL ctrl;
+
+ DWORD dwExpect = ((1 << bit) & immutable)
+ ? ERROR_INVALID_PARAMETER : 0xbebecaca;
+ LPCSTR strExpect = ((1 << bit) & immutable)
+ ? "ERROR_INVALID_PARAMETER" :
"0xbebecaca";
+
+ ctrl = ((1 << bit) & immutable) ? test : ref | mutable;
+ setOrClear ^= bitsOfInterest;
+ SetLastError (0xbebecaca);
+ pSetSecurityDescriptorControl (sec, bitsOfInterest, setOrClear | (1 <<
bit));
+ ok (GetLastError () == dwExpect, fmt, strExpect, GetLastError ());
+ GetSecurityDescriptorControl(sec, &test, &dwRevision);
+ expect_eq(test, ctrl, int, "%x");
+
+ ctrl = ((1 << bit) & immutable) ? test : ref | (1 << bit);
+ setOrClear ^= bitsOfInterest;
+ SetLastError (0xbebecaca);
+ pSetSecurityDescriptorControl (sec, bitsOfInterest, setOrClear | (1 <<
bit));
+ ok (GetLastError () == dwExpect, fmt, strExpect, GetLastError ());
+ GetSecurityDescriptorControl(sec, &test, &dwRevision);
+ expect_eq(test, ctrl, int, "%x");
+ }
+}
+
static void test_PrivateObjectSecurity(void)
{
SECURITY_INFORMATION sec_info =
OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION|SACL_SECURITY_INFORMATION;
SECURITY_DESCRIPTOR_CONTROL ctrl;
- PSECURITY_DESCRIPTOR sec = NULL;
+ PSECURITY_DESCRIPTOR sec;
DWORD dwDescSize;
DWORD dwRevision;
DWORD retSize;
@@ -2407,13 +2668,33 @@
ok(pConvertStringSecurityDescriptorToSecurityDescriptorA(
"O:SY"
"G:S-1-5-21-93476-23408-4576"
+ "D:(A;NP;GAGXGWGR;;;SU)(A;IOID;CCDC;;;SU)"
+ "(D;OICI;0xffffffff;;;S-1-5-21-93476-23408-4576)"
+ "S:(AU;OICINPIOIDSAFA;CCDCLCSWRPRC;;;SU)(AU;NPSA;0x12019f;;;SU)",
+ SDDL_REVISION_1, &sec, &dwDescSize), "Creating descriptor
failed\n");
+
+ test_SetSecurityDescriptorControl(sec);
+
+ LocalFree(sec);
+
+ ok(pConvertStringSecurityDescriptorToSecurityDescriptorA(
+ "O:SY"
+ "G:S-1-5-21-93476-23408-4576",
+ SDDL_REVISION_1, &sec, &dwDescSize), "Creating descriptor
failed\n");
+
+ test_SetSecurityDescriptorControl(sec);
+
+ LocalFree(sec);
+
+ ok(pConvertStringSecurityDescriptorToSecurityDescriptorA(
+ "O:SY"
+ "G:S-1-5-21-93476-23408-4576"
"D:(A;NP;GAGXGWGR;;;SU)(A;IOID;CCDC;;;SU)(D;OICI;0xffffffff;;;S-1-5-21-93476-23408-4576)"
"S:(AU;OICINPIOIDSAFA;CCDCLCSWRPRC;;;SU)(AU;NPSA;0x12019f;;;SU)",
SDDL_REVISION_1, &sec, &dwDescSize), "Creating descriptor failed\n");
buf = HeapAlloc(GetProcessHeap(), 0, dwDescSize);
- DbgPrint("Received %p\n", sec);
pSetSecurityDescriptorControl(sec, SE_DACL_PROTECTED, SE_DACL_PROTECTED);
GetSecurityDescriptorControl(sec, &ctrl, &dwRevision);
- todo_wine expect_eq(ctrl, 0x9014, int, "%x");
+ expect_eq(ctrl, 0x9014, int, "%x");
ok(GetPrivateObjectSecurity(sec, GROUP_SECURITY_INFORMATION, buf, dwDescSize,
&retSize),
"GetPrivateObjectSecurity failed (err=%u)\n", GetLastError());
@@ -2488,11 +2769,17 @@
ret = IsValidAcl(pAcl);
ok(ret, "IsValidAcl failed with error %d\n", GetLastError());
+ SetLastError(0xdeadbeef);
ret = InitializeAcl(pAcl, sizeof(buffer), ACL_REVISION4);
- ok(ret, "InitializeAcl(ACL_REVISION4) failed with error %d\n",
GetLastError());
-
- ret = IsValidAcl(pAcl);
- ok(ret, "IsValidAcl failed with error %d\n", GetLastError());
+ if (GetLastError() != ERROR_INVALID_PARAMETER)
+ {
+ ok(ret, "InitializeAcl(ACL_REVISION4) failed with error %d\n",
GetLastError());
+
+ ret = IsValidAcl(pAcl);
+ ok(ret, "IsValidAcl failed with error %d\n", GetLastError());
+ }
+ else
+ win_skip("ACL_REVISION4 is not implemented on NT4\n");
SetLastError(0xdeadbeef);
ret = InitializeAcl(pAcl, sizeof(buffer), -1);
@@ -2539,6 +2826,13 @@
ok(IsValidAcl(dacl), "GetSecurityInfo\n");
LocalFree(sd);
+
+ if (!pCreateWellKnownSid)
+ {
+ win_skip("NULL parameter test would crash on NT4\n");
+ CloseHandle(obj);
+ return;
+ }
/* If we don't ask for the security descriptor, Windows will still give us
the other stuff, leaving us no way to free it. */
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] Tue Dec 9 13:26:45 2008
@@ -564,7 +564,7 @@
displaysize = tempsizeW / 2;
ret = GetServiceDisplayNameW(scm_handle, spoolerW, displaynameW, &displaysize);
ok(!ret, "Expected failure\n");
- ok(displaysize = tempsizeW, "Expected the needed buffersize\n");
+ ok(displaysize == tempsizeW, "Expected the needed buffersize\n");
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
"Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
@@ -573,7 +573,7 @@
displaysize = tempsizeW;
ret = GetServiceDisplayNameW(scm_handle, spoolerW, displaynameW, &displaysize);
ok(!ret, "Expected failure\n");
- ok(displaysize = tempsizeW, "Expected the needed buffersize\n");
+ ok(displaysize == tempsizeW, "Expected the needed buffersize\n");
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
"Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
@@ -649,7 +649,7 @@
/* Delete the service */
ret = DeleteService(svc_handle);
- ok(ret, "Expected success\n");
+ ok(ret, "Expected success (err=%d)\n", GetLastError());
CloseServiceHandle(svc_handle);
CloseServiceHandle(scm_handle);
@@ -882,7 +882,7 @@
/* Only info level is correct. It looks like the buffer/size is checked second */
SetLastError(0xdeadbeef);
ret = pQueryServiceStatusEx(NULL, 0, NULL, 0, &needed);
- /* NT4 checks the handle first */
+ /* NT4 and Wine check the handle first */
if (GetLastError() != ERROR_INVALID_HANDLE)
{
ok(!ret, "Expected failure\n");
@@ -893,7 +893,7 @@
}
/* Pass a correct buffer and buffersize but a NULL handle */
- statusproc = HeapAlloc(GetProcessHeap(), 0, needed);
+ statusproc = HeapAlloc(GetProcessHeap(), 0, sizeof(SERVICE_STATUS_PROCESS));
bufsize = needed;
SetLastError(0xdeadbeef);
ret = pQueryServiceStatusEx(NULL, 0, (BYTE*)statusproc, bufsize, &needed);
@@ -1985,7 +1985,7 @@
/* Check if we can close the handle to the Service Control Manager */
ret = CloseServiceHandle(scm_handle);
- ok(ret, "Expected success\n");
+ ok(ret, "Expected success (err=%d)\n", GetLastError());
/* Get a new handle to the Service Control Manager */
scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
@@ -1997,7 +1997,7 @@
/* Delete the service */
ret = DeleteService(svc_handle4);
- ok(ret, "Expected success\n");
+ ok(ret, "Expected success (err=%d)\n", GetLastError());
/* We cannot create the same service again as it's still marked as 'being
deleted'.
* The reason is that we still have 4 open handles to this service even though we
@@ -2023,13 +2023,13 @@
/* Close all the handles to the service and try again */
ret = CloseServiceHandle(svc_handle4);
- ok(ret, "Expected success\n");
+ ok(ret, "Expected success (err=%d)\n", GetLastError());
ret = CloseServiceHandle(svc_handle3);
- ok(ret, "Expected success\n");
+ ok(ret, "Expected success (err=%d)\n", GetLastError());
ret = CloseServiceHandle(svc_handle2);
- ok(ret, "Expected success\n");
+ ok(ret, "Expected success (err=%d)\n", GetLastError());
ret = CloseServiceHandle(svc_handle1);
- ok(ret, "Expected success\n");
+ ok(ret, "Expected success (err=%d)\n", GetLastError());
/* Wait a while. Doing a CreateService too soon will result again
* in an ERROR_SERVICE_MARKED_FOR_DELETE error.
@@ -2044,7 +2044,7 @@
/* Delete the service */
ret = DeleteService(svc_handle5);
- ok(ret, "Expected success\n");
+ ok(ret, "Expected success (err=%d)\n", GetLastError());
/* Wait a while. Just in case one of the following tests does a CreateService again
*/
Sleep(1000);