Author: cwittich
Date: Wed Dec 23 16:15:54 2009
New Revision: 44736
URL:
http://svn.reactos.org/svn/reactos?rev=44736&view=rev
Log:
[advapi32_winetest]
sync advapi32_winetest with wine 1.1.35
Added:
trunk/rostests/winetests/advapi32/eventlog.c (with props)
Modified:
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/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] Wed Dec 23 16:15:54 2009
@@ -234,6 +234,7 @@
result = pCryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
ok (result, "%d\n", GetLastError());
if (!result) return;
+ pCryptDestroyHash(hHash);
result = pCryptGenKey(hProv, CALG_RC4, 0, &hKey);
ok (result, "%d\n", GetLastError());
@@ -557,6 +558,7 @@
ok(!strcmp(pszProvName, provider), "expected %s, got %s\n", pszProvName,
provider);
ok(cbName==providerLen, "expected %d, got %d\n", cbName, providerLen);
+ LocalFree(pszProvName);
LocalFree(provider);
}
@@ -844,6 +846,7 @@
ok(!strcmp(pszProvName, provName), "expected %s, got %s\n", pszProvName,
provName);
ok(provNameSize==cbProvName, "expected %d, got %d\n", cbProvName,
provNameSize);
+ LocalFree(pszProvName);
LocalFree(provName);
}
@@ -933,17 +936,156 @@
RegCloseKey(key);
}
+#define key_length 16
+
+static const unsigned char key[key_length] =
+ { 0xbf, 0xf6, 0x83, 0x4b, 0x3e, 0xa3, 0x23, 0xdd,
+ 0x96, 0x78, 0x70, 0x8e, 0xa1, 0x9d, 0x3b, 0x40 };
+
+static void test_rc2_keylen(void)
+{
+ struct KeyBlob
+ {
+ BLOBHEADER header;
+ DWORD key_size;
+ BYTE key_data[2048];
+ } key_blob;
+
+ HCRYPTPROV provider;
+ HCRYPTKEY hkey = 0;
+ BOOL ret;
+
+ SetLastError(0xdeadbeef);
+ ret = pCryptAcquireContextA(&provider, NULL, NULL,
+ PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
+ ok(ret, "CryptAcquireContext error %u\n", GetLastError());
+ if (ret)
+ {
+ key_blob.header.bType = PLAINTEXTKEYBLOB;
+ key_blob.header.bVersion = CUR_BLOB_VERSION;
+ key_blob.header.reserved = 0;
+ key_blob.header.aiKeyAlg = CALG_RC2;
+ key_blob.key_size = sizeof(key);
+ memcpy(key_blob.key_data, key, key_length);
+
+ /* Importing a 16-byte key works with the default provider. */
+ SetLastError(0xdeadbeef);
+ ret = pCryptImportKey(provider, (BYTE*)&key_blob,
+ sizeof(BLOBHEADER)+sizeof(DWORD)+key_blob.key_size,
+ 0, CRYPT_IPSEC_HMAC_KEY, &hkey);
+ /* CRYPT_IPSEC_HMAC_KEY is not supported on W2K and lower */
+ todo_wine
+ ok(ret ||
+ broken(!ret && GetLastError() == NTE_BAD_FLAGS),
+ "CryptImportKey error %08x\n", GetLastError());
+
+ if (ret)
+ pCryptDestroyKey(hkey);
+ pCryptReleaseContext(provider, 0);
+ }
+
+ SetLastError(0xdeadbeef);
+ ret = pCryptAcquireContextA(&provider, NULL, MS_DEF_PROV,
+ PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
+ ok(ret, "CryptAcquireContext error %08x\n", GetLastError());
+
+ if (ret)
+ {
+ /* Importing a 16-byte key doesn't work with the base provider.. */
+ SetLastError(0xdeadbeef);
+ ret = pCryptImportKey(provider, (BYTE*)&key_blob,
+ sizeof(BLOBHEADER)+sizeof(DWORD)+key_blob.key_size,
+ 0, 0, &hkey);
+ ok(!ret && (GetLastError() == NTE_BAD_DATA ||
+ GetLastError() == NTE_BAD_LEN || /* Win7 */
+ GetLastError() == NTE_BAD_TYPE || /* W2K */
+ GetLastError() == NTE_PERM), /* Win9x, WinMe and NT4 */
+ "unexpected error %08x\n", GetLastError());
+ /* but importing an 56-bit (7-byte) key does.. */
+ key_blob.key_size = 7;
+ SetLastError(0xdeadbeef);
+ ret = pCryptImportKey(provider, (BYTE*)&key_blob,
+ sizeof(BLOBHEADER)+sizeof(DWORD)+key_blob.key_size,
+ 0, 0, &hkey);
+ ok(ret ||
+ broken(!ret && GetLastError() == NTE_BAD_TYPE) || /* W2K */
+ broken(!ret && GetLastError() == NTE_PERM), /* Win9x, WinMe and NT4
*/
+ "CryptAcquireContext error %08x\n", GetLastError());
+ if (ret)
+ pCryptDestroyKey(hkey);
+ /* as does importing a 16-byte key with the base provider when
+ * CRYPT_IPSEC_HMAC_KEY is specified.
+ */
+ key_blob.key_size = sizeof(key);
+ SetLastError(0xdeadbeef);
+ ret = pCryptImportKey(provider, (BYTE*)&key_blob,
+ sizeof(BLOBHEADER)+sizeof(DWORD)+key_blob.key_size,
+ 0, CRYPT_IPSEC_HMAC_KEY, &hkey);
+ /* CRYPT_IPSEC_HMAC_KEY is not supported on W2K and lower */
+ todo_wine
+ ok(ret ||
+ broken(!ret && GetLastError() == NTE_BAD_FLAGS),
+ "CryptImportKey error %08x\n", GetLastError());
+ if (ret)
+ pCryptDestroyKey(hkey);
+
+ pCryptReleaseContext(provider, 0);
+ }
+
+ key_blob.key_size = sizeof(key);
+ SetLastError(0xdeadbeef);
+ ret = pCryptAcquireContextA(&provider, NULL, NULL,
+ PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
+ ok(ret, "CryptAcquireContext error %08x\n", GetLastError());
+
+ if (ret)
+ {
+ /* Importing a 16-byte key also works with the default provider when
+ * CRYPT_IPSEC_HMAC_KEY is specified.
+ */
+ SetLastError(0xdeadbeef);
+ ret = pCryptImportKey(provider, (BYTE*)&key_blob,
+ sizeof(BLOBHEADER)+sizeof(DWORD)+key_blob.key_size,
+ 0, CRYPT_IPSEC_HMAC_KEY, &hkey);
+ todo_wine
+ ok(ret ||
+ broken(!ret && GetLastError() == NTE_BAD_FLAGS),
+ "CryptImportKey error %08x\n", GetLastError());
+ if (ret)
+ pCryptDestroyKey(hkey);
+
+ /* There is no apparent limit to the size of the input key when
+ * CRYPT_IPSEC_HMAC_KEY is specified.
+ */
+ key_blob.key_size = sizeof(key_blob.key_data);
+ SetLastError(0xdeadbeef);
+ ret = pCryptImportKey(provider, (BYTE*)&key_blob,
+ sizeof(BLOBHEADER)+sizeof(DWORD)+key_blob.key_size,
+ 0, CRYPT_IPSEC_HMAC_KEY, &hkey);
+ todo_wine
+ ok(ret ||
+ broken(!ret && GetLastError() == NTE_BAD_FLAGS),
+ "CryptImportKey error %08x\n", GetLastError());
+ if (ret)
+ pCryptDestroyKey(hkey);
+
+ pCryptReleaseContext(provider, 0);
+ }
+}
+
START_TEST(crypt)
{
- init_function_pointers();
- if(pCryptAcquireContextA && pCryptReleaseContext) {
+ init_function_pointers();
+ if (pCryptAcquireContextA && pCryptReleaseContext)
+ {
+ test_rc2_keylen();
init_environment();
test_acquire_context();
test_incorrect_api_usage();
test_verify_sig();
test_machine_guid();
clean_up_environment();
- }
+ }
test_enum_providers();
test_enum_provider_types();
Added: trunk/rostests/winetests/advapi32/eventlog.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/advapi32/eventl…
==============================================================================
--- trunk/rostests/winetests/advapi32/eventlog.c (added)
+++ trunk/rostests/winetests/advapi32/eventlog.c [iso-8859-1] Wed Dec 23 16:15:54 2009
@@ -1,0 +1,1144 @@
+/*
+ * Unit tests for Event Logging functions
+ *
+ * Copyright (c) 2009 Paul Vriens
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <stdarg.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "winerror.h"
+#include "winnt.h"
+#include "winreg.h"
+#include "sddl.h"
+
+#include "wine/test.h"
+
+static BOOL (WINAPI *pCreateWellKnownSid)(WELL_KNOWN_SID_TYPE,PSID,PSID,DWORD*);
+static BOOL (WINAPI *pGetEventLogInformation)(HANDLE,DWORD,LPVOID,DWORD,LPDWORD);
+
+static BOOL (WINAPI *pGetComputerNameExA)(COMPUTER_NAME_FORMAT,LPSTR,LPDWORD);
+static BOOL (WINAPI *pWow64DisableWow64FsRedirection)(PVOID *);
+static BOOL (WINAPI *pWow64RevertWow64FsRedirection)(PVOID);
+
+static void init_function_pointers(void)
+{
+ HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll");
+ HMODULE hkernel32 = GetModuleHandleA("kernel32.dll");
+
+ pCreateWellKnownSid = (void*)GetProcAddress(hadvapi32,
"CreateWellKnownSid");
+ pGetEventLogInformation = (void*)GetProcAddress(hadvapi32,
"GetEventLogInformation");
+
+ pGetComputerNameExA = (void*)GetProcAddress(hkernel32,
"GetComputerNameExA");
+ pWow64DisableWow64FsRedirection = (void*)GetProcAddress(hkernel32,
"Wow64DisableWow64FsRedirection");
+ pWow64RevertWow64FsRedirection = (void*)GetProcAddress(hkernel32,
"Wow64RevertWow64FsRedirection");
+}
+
+static void create_backup(const char *filename)
+{
+ HANDLE handle;
+
+ DeleteFileA(filename);
+ handle = OpenEventLogA(NULL, "Application");
+ BackupEventLogA(handle, filename);
+ CloseEventLog(handle);
+
+ todo_wine
+ ok(GetFileAttributesA(filename) != INVALID_FILE_ATTRIBUTES, "Expected a backup
file\n");
+}
+
+static void test_open_close(void)
+{
+ HANDLE handle;
+ BOOL ret;
+
+ SetLastError(0xdeadbeef);
+ ret = CloseEventLog(NULL);
+ ok(!ret, "Expected failure\n");
+ ok(GetLastError() == ERROR_INVALID_HANDLE ||
+ GetLastError() == ERROR_NOACCESS, /* W2K */
+ "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
+
+ SetLastError(0xdeadbeef);
+ handle = OpenEventLogA(NULL, NULL);
+ ok(handle == NULL, "Didn't expect a handle\n");
+ ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER,
got %d\n", GetLastError());
+
+ SetLastError(0xdeadbeef);
+ handle = OpenEventLogA("IDontExist", NULL);
+ ok(handle == NULL, "Didn't expect a handle\n");
+ ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER,
got %d\n", GetLastError());
+
+ SetLastError(0xdeadbeef);
+ handle = OpenEventLogA("IDontExist", "deadbeef");
+ ok(handle == NULL, "Didn't expect a handle\n");
+ ok(GetLastError() == RPC_S_SERVER_UNAVAILABLE ||
+ GetLastError() == RPC_S_INVALID_NET_ADDR, /* Some Vista and Win7 */
+ "Expected RPC_S_SERVER_UNAVAILABLE, got %d\n", GetLastError());
+
+ /* This one opens the Application log */
+ handle = OpenEventLogA(NULL, "deadbeef");
+ ok(handle != NULL, "Expected a handle\n");
+ ret = CloseEventLog(handle);
+ ok(ret, "Expected success\n");
+ /* Close a second time */
+ SetLastError(0xdeadbeef);
+ ret = CloseEventLog(handle);
+ todo_wine
+ {
+ ok(!ret, "Expected failure\n");
+ ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got
%d\n", GetLastError());
+ }
+
+ /* Empty servername should be read as local server */
+ handle = OpenEventLogA("", "Application");
+ ok(handle != NULL, "Expected a handle\n");
+ CloseEventLog(handle);
+
+ handle = OpenEventLogA(NULL, "Application");
+ ok(handle != NULL, "Expected a handle\n");
+ CloseEventLog(handle);
+}
+
+static void test_info(void)
+{
+ HANDLE handle;
+ BOOL ret;
+ DWORD needed;
+ EVENTLOG_FULL_INFORMATION efi;
+
+ if (!pGetEventLogInformation)
+ {
+ /* NT4 */
+ win_skip("GetEventLogInformation is not available\n");
+ return;
+ }
+ SetLastError(0xdeadbeef);
+ ret = pGetEventLogInformation(NULL, 1, NULL, 0, NULL);
+ ok(!ret, "Expected failure\n");
+ ok(GetLastError() == ERROR_INVALID_LEVEL, "Expected ERROR_INVALID_LEVEL, got
%d\n", GetLastError());
+
+ SetLastError(0xdeadbeef);
+ ret = pGetEventLogInformation(NULL, EVENTLOG_FULL_INFO, NULL, 0, NULL);
+ ok(!ret, "Expected failure\n");
+ ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got
%d\n", GetLastError());
+
+ handle = OpenEventLogA(NULL, "Application");
+
+ SetLastError(0xdeadbeef);
+ ret = pGetEventLogInformation(handle, EVENTLOG_FULL_INFO, NULL, 0, NULL);
+ ok(!ret, "Expected failure\n");
+ ok(GetLastError() == RPC_X_NULL_REF_POINTER, "Expected RPC_X_NULL_REF_POINTER,
got %d\n", GetLastError());
+
+ SetLastError(0xdeadbeef);
+ ret = pGetEventLogInformation(handle, EVENTLOG_FULL_INFO, NULL, 0, &needed);
+ ok(!ret, "Expected failure\n");
+ ok(GetLastError() == RPC_X_NULL_REF_POINTER, "Expected RPC_X_NULL_REF_POINTER,
got %d\n", GetLastError());
+
+ SetLastError(0xdeadbeef);
+ ret = pGetEventLogInformation(handle, EVENTLOG_FULL_INFO, (LPVOID)&efi, 0,
NULL);
+ ok(!ret, "Expected failure\n");
+ ok(GetLastError() == RPC_X_NULL_REF_POINTER, "Expected RPC_X_NULL_REF_POINTER,
got %d\n", GetLastError());
+
+ SetLastError(0xdeadbeef);
+ needed = 0xdeadbeef;
+ efi.dwFull = 0xdeadbeef;
+ ret = pGetEventLogInformation(handle, EVENTLOG_FULL_INFO, (LPVOID)&efi, 0,
&needed);
+ ok(!ret, "Expected failure\n");
+ ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Expected
ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
+ ok(needed == sizeof(EVENTLOG_FULL_INFORMATION), "Expected
sizeof(EVENTLOG_FULL_INFORMATION), got %d\n", needed);
+ ok(efi.dwFull == 0xdeadbeef, "Expected no change to the dwFull member\n");
+
+ /* Not that we care, but on success last error is set to ERROR_IO_PENDING */
+ efi.dwFull = 0xdeadbeef;
+ needed *= 2;
+ ret = pGetEventLogInformation(handle, EVENTLOG_FULL_INFO, (LPVOID)&efi, needed,
&needed);
+ ok(ret, "Expected success\n");
+ ok(needed == sizeof(EVENTLOG_FULL_INFORMATION), "Expected
sizeof(EVENTLOG_FULL_INFORMATION), got %d\n", needed);
+ ok(efi.dwFull == 0 || efi.dwFull == 1, "Expected 0 (not full) or 1 (full), got
%d\n", efi.dwFull);
+
+ CloseEventLog(handle);
+}
+
+static void test_count(void)
+{
+ HANDLE handle;
+ BOOL ret;
+ DWORD count;
+ const char backup[] = "backup.evt";
+
+ SetLastError(0xdeadbeef);
+ ret = GetNumberOfEventLogRecords(NULL, NULL);
+ ok(!ret, "Expected failure\n");
+ ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER,
got %d\n", GetLastError());
+
+ SetLastError(0xdeadbeef);
+ count = 0xdeadbeef;
+ ret = GetNumberOfEventLogRecords(NULL, &count);
+ ok(!ret, "Expected failure\n");
+ ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got
%d\n", GetLastError());
+ ok(count == 0xdeadbeef, "Expected count to stay unchanged\n");
+
+ handle = OpenEventLogA(NULL, "Application");
+
+ SetLastError(0xdeadbeef);
+ ret = GetNumberOfEventLogRecords(handle, NULL);
+ ok(!ret, "Expected failure\n");
+ ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER,
got %d\n", GetLastError());
+
+ count = 0xdeadbeef;
+ ret = GetNumberOfEventLogRecords(handle, &count);
+ ok(ret, "Expected success\n");
+ ok(count != 0xdeadbeef, "Expected the number of records\n");
+
+ CloseEventLog(handle);
+
+ /* Make a backup eventlog to work with */
+ create_backup(backup);
+
+ handle = OpenBackupEventLogA(NULL, backup);
+ todo_wine
+ ok(handle != NULL, "Expected a handle\n");
+
+ /* Does GetNumberOfEventLogRecords work with backup eventlogs? */
+ count = 0xdeadbeef;
+ ret = GetNumberOfEventLogRecords(handle, &count);
+ todo_wine
+ {
+ ok(ret, "Expected success\n");
+ ok(count != 0xdeadbeef, "Expected the number of records\n");
+ }
+
+ CloseEventLog(handle);
+ DeleteFileA(backup);
+}
+
+static void test_oldest(void)
+{
+ HANDLE handle;
+ BOOL ret;
+ DWORD oldest;
+ const char backup[] = "backup.evt";
+
+ SetLastError(0xdeadbeef);
+ ret = GetOldestEventLogRecord(NULL, NULL);
+ ok(!ret, "Expected failure\n");
+ ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER,
got %d\n", GetLastError());
+
+ SetLastError(0xdeadbeef);
+ oldest = 0xdeadbeef;
+ ret = GetOldestEventLogRecord(NULL, &oldest);
+ ok(!ret, "Expected failure\n");
+ ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got
%d\n", GetLastError());
+ ok(oldest == 0xdeadbeef, "Expected oldest to stay unchanged\n");
+
+ handle = OpenEventLogA(NULL, "Application");
+
+ SetLastError(0xdeadbeef);
+ ret = GetOldestEventLogRecord(handle, NULL);
+ ok(!ret, "Expected failure\n");
+ ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER,
got %d\n", GetLastError());
+
+ oldest = 0xdeadbeef;
+ ret = GetOldestEventLogRecord(handle, &oldest);
+ ok(ret, "Expected success\n");
+ ok(oldest != 0xdeadbeef, "Expected the number of the oldest record\n");
+
+ CloseEventLog(handle);
+
+ /* Make a backup eventlog to work with */
+ create_backup(backup);
+
+ handle = OpenBackupEventLogA(NULL, backup);
+ todo_wine
+ ok(handle != NULL, "Expected a handle\n");
+
+ /* Does GetOldestEventLogRecord work with backup eventlogs? */
+ oldest = 0xdeadbeef;
+ ret = GetOldestEventLogRecord(handle, &oldest);
+ todo_wine
+ {
+ ok(ret, "Expected success\n");
+ ok(oldest != 0xdeadbeef, "Expected the number of the oldest record\n");
+ }
+
+ CloseEventLog(handle);
+ DeleteFileA(backup);
+}
+
+static void test_backup(void)
+{
+ HANDLE handle;
+ BOOL ret;
+ const char backup[] = "backup.evt";
+ const char backup2[] = "backup2.evt";
+
+ SetLastError(0xdeadbeef);
+ ret = BackupEventLogA(NULL, NULL);
+ ok(!ret, "Expected failure\n");
+ ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER,
got %d\n", GetLastError());
+
+ SetLastError(0xdeadbeef);
+ ret = BackupEventLogA(NULL, backup);
+ ok(!ret, "Expected failure\n");
+ ok(GetFileAttributesA(backup) == INVALID_FILE_ATTRIBUTES, "Expected no backup
file\n");
+
+ handle = OpenEventLogA(NULL, "Application");
+
+ SetLastError(0xdeadbeef);
+ ret = BackupEventLogA(handle, NULL);
+ ok(!ret, "Expected failure\n");
+ ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER,
got %d\n", GetLastError());
+
+ ret = BackupEventLogA(handle, backup);
+ ok(ret, "Expected success\n");
+ todo_wine
+ ok(GetFileAttributesA(backup) != INVALID_FILE_ATTRIBUTES, "Expected a backup
file\n");
+
+ /* Try to overwrite */
+ SetLastError(0xdeadbeef);
+ ret = BackupEventLogA(handle, backup);
+ todo_wine
+ {
+ ok(!ret, "Expected failure\n");
+ ok(GetLastError() == ERROR_ALREADY_EXISTS, "Expected ERROR_ALREADY_EXISTS, got
%d\n", GetLastError());
+ }
+
+ CloseEventLog(handle);
+
+ /* Can we make a backup of a backup? */
+ handle = OpenBackupEventLogA(NULL, backup);
+ todo_wine
+ ok(handle != NULL, "Expected a handle\n");
+
+ ret = BackupEventLogA(handle, backup2);
+ todo_wine
+ {
+ ok(ret, "Expected success\n");
+ ok(GetFileAttributesA(backup2) != INVALID_FILE_ATTRIBUTES, "Expected a backup
file\n");
+ }
+
+ CloseEventLog(handle);
+ DeleteFileA(backup);
+ DeleteFileA(backup2);
+}
+
+static void test_read(void)
+{
+ HANDLE handle;
+ BOOL ret;
+ DWORD count, toread, read, needed;
+ void *buf;
+
+ SetLastError(0xdeadbeef);
+ ret = ReadEventLogA(NULL, 0, 0, NULL, 0, NULL, NULL);
+ ok(!ret, "Expected failure\n");
+ todo_wine
+ ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER,
got %d\n", GetLastError());
+
+ read = 0xdeadbeef;
+ SetLastError(0xdeadbeef);
+ ret = ReadEventLogA(NULL, 0, 0, NULL, 0, &read, NULL);
+ ok(!ret, "Expected failure\n");
+ ok(read == 0xdeadbeef, "Expected 'read' parameter to remain
unchanged\n");
+ todo_wine
+ ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER,
got %d\n", GetLastError());
+
+ needed = 0xdeadbeef;
+ SetLastError(0xdeadbeef);
+ ret = ReadEventLogA(NULL, 0, 0, NULL, 0, NULL, &needed);
+ ok(!ret, "Expected failure\n");
+ ok(needed == 0xdeadbeef, "Expected 'needed' parameter to remain
unchanged\n");
+ todo_wine
+ ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER,
got %d\n", GetLastError());
+
+ /* 'read' and 'needed' are only filled when the needed buffer size is
passed back or when the call succeeds */
+ SetLastError(0xdeadbeef);
+ ret = ReadEventLogA(NULL, 0, 0, NULL, 0, &read, &needed);
+ ok(!ret, "Expected failure\n");
+ todo_wine
+ ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER,
got %d\n", GetLastError());
+
+ SetLastError(0xdeadbeef);
+ ret = ReadEventLogA(NULL, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ, 0, NULL,
0, NULL, NULL);
+ ok(!ret, "Expected failure\n");
+ todo_wine
+ ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER,
got %d\n", GetLastError());
+
+ SetLastError(0xdeadbeef);
+ ret = ReadEventLogA(NULL, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ, 0, NULL,
0, &read, &needed);
+ ok(!ret, "Expected failure\n");
+ todo_wine
+ ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER,
got %d\n", GetLastError());
+
+ buf = NULL;
+ SetLastError(0xdeadbeef);
+ ret = ReadEventLogA(NULL, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ,
+ 0, buf, sizeof(EVENTLOGRECORD), &read, &needed);
+ ok(!ret, "Expected failure\n");
+ todo_wine
+ ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER,
got %d\n", GetLastError());
+
+ buf = HeapAlloc(GetProcessHeap(), 0, sizeof(EVENTLOGRECORD));
+ SetLastError(0xdeadbeef);
+ ret = ReadEventLogA(NULL, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ,
+ 0, buf, sizeof(EVENTLOGRECORD), &read, &needed);
+ ok(!ret, "Expected failure\n");
+ todo_wine
+ ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got
%d\n", GetLastError());
+ HeapFree(GetProcessHeap(), 0, buf);
+
+ handle = OpenEventLogA(NULL, "Application");
+
+ /* Show that we need the proper dwFlags with a (for the rest) proper call */
+ buf = HeapAlloc(GetProcessHeap(), 0, sizeof(EVENTLOGRECORD));
+
+ SetLastError(0xdeadbeef);
+ ret = ReadEventLogA(handle, 0, 0, buf, sizeof(EVENTLOGRECORD), &read,
&needed);
+ ok(!ret, "Expected failure\n");
+ todo_wine
+ ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER,
got %d\n", GetLastError());
+
+ SetLastError(0xdeadbeef);
+ ret = ReadEventLogA(handle, EVENTLOG_SEQUENTIAL_READ, 0, buf, sizeof(EVENTLOGRECORD),
&read, &needed);
+ ok(!ret, "Expected failure\n");
+ todo_wine
+ ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER,
got %d\n", GetLastError());
+
+ SetLastError(0xdeadbeef);
+ ret = ReadEventLogA(handle, EVENTLOG_SEEK_READ, 0, buf, sizeof(EVENTLOGRECORD),
&read, &needed);
+ ok(!ret, "Expected failure\n");
+ todo_wine
+ ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER,
got %d\n", GetLastError());
+
+ SetLastError(0xdeadbeef);
+ ret = ReadEventLogA(handle, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ |
EVENTLOG_BACKWARDS_READ,
+ 0, buf, sizeof(EVENTLOGRECORD), &read, &needed);
+ ok(!ret, "Expected failure\n");
+ todo_wine
+ ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER,
got %d\n", GetLastError());
+
+ SetLastError(0xdeadbeef);
+ ret = ReadEventLogA(handle, EVENTLOG_SEEK_READ | EVENTLOG_FORWARDS_READ |
EVENTLOG_BACKWARDS_READ,
+ 0, buf, sizeof(EVENTLOGRECORD), &read, &needed);
+ ok(!ret, "Expected failure\n");
+ todo_wine
+ ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER,
got %d\n", GetLastError());
+
+ SetLastError(0xdeadbeef);
+ ret = ReadEventLogA(handle, EVENTLOG_SEEK_READ | EVENTLOG_SEQUENTIAL_READ |
EVENTLOG_FORWARDS_READ,
+ 0, buf, sizeof(EVENTLOGRECORD), &read, &needed);
+ ok(!ret, "Expected failure\n");
+ todo_wine
+ ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER,
got %d\n", GetLastError());
+
+ HeapFree(GetProcessHeap(), 0, buf);
+
+ /* First check if there are any records (in practice only on Wine: FIXME) */
+ count = 0;
+ GetNumberOfEventLogRecords(handle, &count);
+ if (!count)
+ {
+ skip("No records in the 'Application' log\n");
+ CloseEventLog(handle);
+ return;
+ }
+
+ /* Get the buffer size for the first record */
+ buf = HeapAlloc(GetProcessHeap(), 0, sizeof(EVENTLOGRECORD));
+ read = needed = 0xdeadbeef;
+ SetLastError(0xdeadbeef);
+ ret = ReadEventLogA(handle, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ,
+ 0, buf, sizeof(EVENTLOGRECORD), &read, &needed);
+ ok(!ret, "Expected failure\n");
+ ok(read == 0, "Expected no bytes read\n");
+ ok(needed > sizeof(EVENTLOGRECORD), "Expected the needed buffersize to be
bigger than sizeof(EVENTLOGRECORD)\n");
+ ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Expected
ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
+
+ /* Read the first record */
+ toread = needed;
+ buf = HeapReAlloc(GetProcessHeap(), 0, buf, toread);
+ read = needed = 0xdeadbeef;
+ SetLastError(0xdeadbeef);
+ ret = ReadEventLogA(handle, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ, 0,
buf, toread, &read, &needed);
+ ok(ret, "Expected success\n");
+ ok(read == toread ||
+ broken(read < toread), /* NT4 wants a buffer size way bigger than just 1 record
*/
+ "Expected the requested size to be read\n");
+ ok(needed == 0, "Expected no extra bytes to be read\n");
+ HeapFree(GetProcessHeap(), 0, buf);
+
+ CloseEventLog(handle);
+}
+
+static void test_openbackup(void)
+{
+ HANDLE handle, handle2, file;
+ DWORD written;
+ const char backup[] = "backup.evt";
+ const char text[] = "Just some text";
+
+ SetLastError(0xdeadbeef);
+ handle = OpenBackupEventLogA(NULL, NULL);
+ ok(handle == NULL, "Didn't expect a handle\n");
+ ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER,
got %d\n", GetLastError());
+
+ SetLastError(0xdeadbeef);
+ handle = OpenBackupEventLogA(NULL, "idontexist.evt");
+ ok(handle == NULL, "Didn't expect a handle\n");
+ ok(GetLastError() == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got
%d\n", GetLastError());
+
+ SetLastError(0xdeadbeef);
+ handle = OpenBackupEventLogA("IDontExist", NULL);
+ ok(handle == NULL, "Didn't expect a handle\n");
+ ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER,
got %d\n", GetLastError());
+
+ SetLastError(0xdeadbeef);
+ handle = OpenBackupEventLogA("IDontExist", "idontexist.evt");
+ ok(handle == NULL, "Didn't expect a handle\n");
+ ok(GetLastError() == RPC_S_SERVER_UNAVAILABLE ||
+ GetLastError() == RPC_S_INVALID_NET_ADDR, /* Some Vista and Win7 */
+ "Expected RPC_S_SERVER_UNAVAILABLE, got %d\n", GetLastError());
+
+ /* Make a backup eventlog to work with */
+ create_backup(backup);
+
+ /* FIXME: Wine stops here */
+ if (GetFileAttributesA(backup) == INVALID_FILE_ATTRIBUTES)
+ {
+ skip("We don't have a backup eventlog to work with\n");
+ return;
+ }
+
+ SetLastError(0xdeadbeef);
+ handle = OpenBackupEventLogA("IDontExist", backup);
+ ok(handle == NULL, "Didn't expect a handle\n");
+ ok(GetLastError() == RPC_S_SERVER_UNAVAILABLE ||
+ GetLastError() == RPC_S_INVALID_NET_ADDR, /* Some Vista and Win7 */
+ "Expected RPC_S_SERVER_UNAVAILABLE, got %d\n", GetLastError());
+
+ /* Empty servername should be read as local server */
+ handle = OpenBackupEventLogA("", backup);
+ ok(handle != NULL, "Expected a handle\n");
+ CloseEventLog(handle);
+
+ handle = OpenBackupEventLogA(NULL, backup);
+ ok(handle != NULL, "Expected a handle\n");
+
+ /* Can we open that same backup eventlog more than once? */
+ handle2 = OpenBackupEventLogA(NULL, backup);
+ ok(handle2 != NULL, "Expected a handle\n");
+ ok(handle2 != handle, "Didn't expect the same handle\n");
+ CloseEventLog(handle2);
+
+ CloseEventLog(handle);
+ DeleteFileA(backup);
+
+ /* Is there any content checking done? */
+ file = CreateFileA(backup, GENERIC_WRITE, 0, NULL, CREATE_NEW, 0, NULL);
+ CloseHandle(file);
+ SetLastError(0xdeadbeef);
+ handle = OpenBackupEventLogA(NULL, backup);
+ ok(handle == NULL, "Didn't expect a handle\n");
+ ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY ||
+ GetLastError() == ERROR_EVENTLOG_FILE_CORRUPT, /* Vista and Win7 */
+ "Expected ERROR_NOT_ENOUGH_MEMORY, got %d\n", GetLastError());
+ CloseEventLog(handle);
+ DeleteFileA(backup);
+
+ file = CreateFileA(backup, GENERIC_WRITE, 0, NULL, CREATE_NEW, 0, NULL);
+ WriteFile(file, text, sizeof(text), &written, NULL);
+ CloseHandle(file);
+ SetLastError(0xdeadbeef);
+ handle = OpenBackupEventLogA(NULL, backup);
+ ok(handle == NULL, "Didn't expect a handle\n");
+ ok(GetLastError() == ERROR_EVENTLOG_FILE_CORRUPT, "Expected
ERROR_EVENTLOG_FILE_CORRUPT, got %d\n", GetLastError());
+ CloseEventLog(handle);
+ DeleteFileA(backup);
+}
+
+static void test_clear(void)
+{
+ HANDLE handle;
+ BOOL ret;
+ const char backup[] = "backup.evt";
+ const char backup2[] = "backup2.evt";
+
+ SetLastError(0xdeadbeef);
+ ret = ClearEventLogA(NULL, NULL);
+ ok(!ret, "Expected failure\n");
+ ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got
%d\n", GetLastError());
+
+ /* Make a backup eventlog to work with */
+ create_backup(backup);
+
+ SetLastError(0xdeadbeef);
+ ret = ClearEventLogA(NULL, backup);
+ ok(!ret, "Expected failure\n");
+ ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got
%d\n", GetLastError());
+
+ handle = OpenBackupEventLogA(NULL, backup);
+ todo_wine
+ ok(handle != NULL, "Expected a handle\n");
+
+ /* A real eventlog would fail with ERROR_ALREADY_EXISTS */
+ SetLastError(0xdeadbeef);
+ ret = ClearEventLogA(handle, backup);
+ ok(!ret, "Expected failure\n");
+ /* The eventlog service runs under an account that doesn't have the necessary
+ * permissions on the users home directory on a default Vista+ system.
+ */
+ ok(GetLastError() == ERROR_INVALID_HANDLE ||
+ GetLastError() == ERROR_ACCESS_DENIED, /* Vista+ */
+ "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
+
+ /* Show that ClearEventLog only works for real eventlogs. */
+ SetLastError(0xdeadbeef);
+ ret = ClearEventLogA(handle, backup2);
+ ok(!ret, "Expected failure\n");
+ ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got
%d\n", GetLastError());
+ ok(GetFileAttributesA(backup2) == INVALID_FILE_ATTRIBUTES, "Expected no backup
file\n");
+
+ SetLastError(0xdeadbeef);
+ ret = ClearEventLogA(handle, NULL);
+ ok(!ret, "Expected failure\n");
+ ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got
%d\n", GetLastError());
+
+ CloseEventLog(handle);
+ todo_wine
+ ok(DeleteFileA(backup), "Could not delete the backup file\n");
+}
+
+static const char eventlogsvc[] =
"SYSTEM\\CurrentControlSet\\Services\\Eventlog";
+static const char eventlogname[] = "Wine";
+static const char eventsources[][11] = { "WineSrc", "WineSrc1",
"WineSrc20", "WineSrc300" };
+
+static BOOL create_new_eventlog(void)
+{
+ HKEY key, eventkey;
+ BOOL bret = FALSE;
+ LONG lret;
+ int i;
+
+ /* First create our eventlog */
+ lret = RegOpenKeyA(HKEY_LOCAL_MACHINE, eventlogsvc, &key);
+ /* FIXME: Wine stops here */
+ if (lret != ERROR_SUCCESS)
+ {
+ skip("Could not open the EventLog service registry key\n");
+ return FALSE;
+ }
+ lret = RegCreateKeyA(key, eventlogname, &eventkey);
+ if (lret != ERROR_SUCCESS)
+ {
+ skip("Could not create the eventlog '%s' registry key\n",
eventlogname);
+ goto cleanup;
+ }
+
+ /* Create some event sources, the registry value 'Sources' is updated
automatically */
+ for (i = 0; i < sizeof(eventsources)/sizeof(eventsources[0]); i++)
+ {
+ HKEY srckey;
+
+ lret = RegCreateKeyA(eventkey, eventsources[i], &srckey);
+ if (lret != ERROR_SUCCESS)
+ {
+ skip("Could not create the eventsource '%s' registry
key\n", eventsources[i]);
+ goto cleanup;
+ }
+ RegFlushKey(srckey);
+ RegCloseKey(srckey);
+ }
+
+ bret = TRUE;
+
+ /* The flushing of the registry (here and above) gives us some assurance
+ * that we are not to quickly writing events as 'Sources' could still be
+ * not updated.
+ */
+ RegFlushKey(eventkey);
+cleanup:
+ RegCloseKey(eventkey);
+ RegCloseKey(key);
+
+ return bret;
+}
+
+static const char *one_string[] = { "First string" };
+static const char *two_strings[] = { "First string", "Second string"
};
+static const struct
+{
+ const char *evt_src;
+ WORD evt_type;
+ WORD evt_cat;
+ DWORD evt_id;
+ BOOL evt_sid;
+ WORD evt_numstrings;
+ const char **evt_strings;
+} read_write [] =
+{
+ { eventlogname, EVENTLOG_INFORMATION_TYPE, 1, 1, FALSE, 1, one_string },
+ { eventsources[0], EVENTLOG_WARNING_TYPE, 1, 2, FALSE, 0, NULL },
+ { eventsources[1], EVENTLOG_AUDIT_FAILURE, 1, 3, FALSE, 2, two_strings },
+ { eventsources[2], EVENTLOG_ERROR_TYPE, 1, 4, FALSE, 0, NULL },
+ { eventsources[3], EVENTLOG_WARNING_TYPE, 1, 5, FALSE, 1, one_string },
+ { eventlogname, EVENTLOG_SUCCESS, 2, 6, TRUE, 2, two_strings },
+ { eventsources[0], EVENTLOG_AUDIT_FAILURE, 2, 7, TRUE, 0, NULL },
+ { eventsources[1], EVENTLOG_AUDIT_SUCCESS, 2, 8, TRUE, 2, two_strings },
+ { eventsources[2], EVENTLOG_WARNING_TYPE, 2, 9, TRUE, 0, NULL },
+ { eventsources[3], EVENTLOG_ERROR_TYPE, 2, 10, TRUE, 1, one_string }
+};
+
+static void test_readwrite(void)
+{
+ HANDLE handle;
+ PSID user;
+ DWORD sidsize, count;
+ BOOL ret, sidavailable;
+ BOOL on_vista = FALSE; /* Used to indicate Vista, W2K8 or Win7 */
+ int i;
+ char *localcomputer = NULL;
+ DWORD size;
+
+ if (pCreateWellKnownSid)
+ {
+ sidsize = SECURITY_MAX_SID_SIZE;
+ user = HeapAlloc(GetProcessHeap(), 0, sidsize);
+ SetLastError(0xdeadbeef);
+ pCreateWellKnownSid(WinInteractiveSid, NULL, user, &sidsize);
+ sidavailable = TRUE;
+ }
+ else
+ {
+ win_skip("Skipping some SID related tests\n");
+ sidavailable = FALSE;
+ user = NULL;
+ }
+
+ /* Write an event with an incorrect event type. This will fail on Windows 7
+ * but succeed on all others, hence it's not part of the struct.
+ */
+ handle = OpenEventLogA(NULL, eventlogname);
+ if (!handle)
+ {
+ /* Intermittently seen on NT4 when tests are run immediately after boot */
+ win_skip("Could not get a handle to the eventlog\n");
+ goto cleanup;
+ }
+
+ count = 0xdeadbeef;
+ GetNumberOfEventLogRecords(handle, &count);
+ if (count != 0)
+ {
+ /* Needed for W2K3 without a service pack */
+ win_skip("We most likely opened the Application eventlog\n");
+ CloseEventLog(handle);
+ Sleep(2000);
+
+ handle = OpenEventLogA(NULL, eventlogname);
+ count = 0xdeadbeef;
+ GetNumberOfEventLogRecords(handle, &count);
+ if (count != 0)
+ {
+ win_skip("We didn't open our new eventlog\n");
+ CloseEventLog(handle);
+ goto cleanup;
+ }
+ }
+
+ SetLastError(0xdeadbeef);
+ ret = ReportEvent(handle, 0x20, 0, 0, NULL, 0, 0, NULL, NULL);
+ if (!ret && GetLastError() == ERROR_CRC)
+ {
+ win_skip("Win7 fails when using incorrect event types\n");
+ ret = ReportEvent(handle, 0, 0, 0, NULL, 0, 0, NULL, NULL);
+ }
+ else
+ {
+ void *buf;
+ DWORD read, needed;
+ EVENTLOGRECORD *record;
+
+ /* Needed to catch earlier Vista (with no ServicePack for example) */
+ buf = HeapAlloc(GetProcessHeap(), 0, sizeof(EVENTLOGRECORD));
+ ReadEventLogA(handle, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ,
+ 0, buf, sizeof(EVENTLOGRECORD), &read, &needed);
+
+ buf = HeapReAlloc(GetProcessHeap(), 0, buf, needed);
+ ReadEventLogA(handle, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ,
+ 0, buf, needed, &read, &needed);
+
+ record = (EVENTLOGRECORD *)buf;
+
+ /* Vista and W2K8 return EVENTLOG_SUCCESS, Windows versions before return
+ * the written eventtype (0x20 in this case).
+ */
+ if (record->EventType == EVENTLOG_SUCCESS)
+ on_vista = TRUE;
+
+ HeapFree(GetProcessHeap(), 0, buf);
+ }
+ ok(ret, "Expected success : %d\n", GetLastError());
+
+ /* This will clear the eventlog. The record numbering for new
+ * events however differs on Vista SP1+. Before Vista the first
+ * event would be numbered 1, on Vista SP1+ it's higher as we already
+ * had at least one event (more in case of multiple test runs without
+ * a reboot).
+ */
+ ClearEventLogA(handle, NULL);
+ CloseEventLog(handle);
+
+ /* Write a bunch of events while using different event sources */
+ for (i = 0; i < sizeof(read_write)/sizeof(read_write[0]); i++)
+ {
+ DWORD oldest;
+ BOOL run_sidtests = read_write[i].evt_sid & sidavailable;
+
+ /* We don't need to use RegisterEventSource to report events */
+ if (i % 2)
+ handle = OpenEventLogA(NULL, read_write[i].evt_src);
+ else
+ handle = RegisterEventSourceA(NULL, read_write[i].evt_src);
+ ok(handle != NULL, "Expected a handle\n");
+
+ SetLastError(0xdeadbeef);
+ ret = ReportEvent(handle, read_write[i].evt_type, read_write[i].evt_cat,
+ read_write[i].evt_id, run_sidtests ? user : NULL,
+ read_write[i].evt_numstrings, 0, read_write[i].evt_strings,
NULL);
+
+ count = 0xdeadbeef;
+ ret = GetNumberOfEventLogRecords(handle, &count);
+ ok(ret, "Expected success\n");
+ ok(count == (i + 1), "Expected %d records, got %d\n", i + 1, count);
+
+ oldest = 0xdeadbeef;
+ ret = GetOldestEventLogRecord(handle, &oldest);
+ ok(ret, "Expected success\n");
+ ok(oldest == 1 ||
+ (oldest > 1 && oldest != 0xdeadbeef), /* Vista SP1+, W2K8 and Win7
*/
+ "Expected oldest to be 1 or higher, got %d\n", oldest);
+ if (oldest > 1 && oldest != 0xdeadbeef)
+ on_vista = TRUE;
+
+ if (i % 2)
+ ret = CloseEventLog(handle);
+ else
+ ret = DeregisterEventSource(handle);
+ ok(ret, "Expected success : %d\n", GetLastError());
+ }
+
+ handle = OpenEventLogA(NULL, eventlogname);
+ count = 0xdeadbeef;
+ ret = GetNumberOfEventLogRecords(handle, &count);
+ ok(ret, "Expected success\n");
+ ok(count == i, "Expected %d records, got %d\n", i, count);
+ CloseEventLog(handle);
+
+ if (count == 0)
+ {
+ skip("No events were written to the eventlog\n");
+ goto cleanup;
+ }
+
+ /* Report only once */
+ if (on_vista)
+ skip("There is no DWORD alignment enforced for UserSid on Vista, W2K8 or
Win7\n");
+
+ if (on_vista && pGetComputerNameExA)
+ {
+ /* New Vista+ behavior */
+ size = 0;
+ SetLastError(0xdeadbeef);
+ pGetComputerNameExA(ComputerNameDnsFullyQualified, NULL, &size);
+ localcomputer = HeapAlloc(GetProcessHeap(), 0, size);
+ pGetComputerNameExA(ComputerNameDnsFullyQualified, localcomputer, &size);
+ }
+ else
+ {
+ size = MAX_COMPUTERNAME_LENGTH + 1;
+ localcomputer = HeapAlloc(GetProcessHeap(), 0, size);
+ GetComputerNameA(localcomputer, &size);
+ }
+
+ /* Read all events from our created eventlog, one by one */
+ handle = OpenEventLogA(NULL, eventlogname);
+ i = 0;
+ for (;;)
+ {
+ void *buf;
+ DWORD read, needed;
+ EVENTLOGRECORD *record;
+ char *sourcename, *computername;
+ int k;
+ char *ptr;
+ BOOL run_sidtests = read_write[i].evt_sid & sidavailable;
+
+ buf = HeapAlloc(GetProcessHeap(), 0, sizeof(EVENTLOGRECORD));
+ SetLastError(0xdeadbeef);
+ ret = ReadEventLogA(handle, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ,
+ 0, buf, sizeof(EVENTLOGRECORD), &read, &needed);
+ if (!ret && GetLastError() == ERROR_HANDLE_EOF)
+ {
+ HeapFree(GetProcessHeap(), 0, buf);
+ break;
+ }
+ ok(!ret, "Expected failure\n");
+ ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
+ "Expected ERROR_INVALID_PARAMETER, got %d\n",GetLastError());
+
+ buf = HeapReAlloc(GetProcessHeap(), 0, buf, needed);
+ ret = ReadEventLogA(handle, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_FORWARDS_READ,
+ 0, buf, needed, &read, &needed);
+ ok(ret, "Expected success: %d\n", GetLastError());
+
+ record = (EVENTLOGRECORD *)buf;
+
+ ok(record->Length == read,
+ "Expected %d, got %d\n", read, record->Length);
+ ok(record->Reserved == 0x654c664c,
+ "Expected 0x654c664c, got %d\n", record->Reserved);
+ ok(record->RecordNumber == i + 1 ||
+ (on_vista && (record->RecordNumber > i + 1)),
+ "Expected %d or higher, got %d\n", i + 1, record->RecordNumber);
+ ok(record->EventID == read_write[i].evt_id,
+ "Expected %d, got %d\n", read_write[i].evt_id, record->EventID);
+ ok(record->EventType == read_write[i].evt_type,
+ "Expected %d, got %d\n", read_write[i].evt_type,
record->EventType);
+ ok(record->NumStrings == read_write[i].evt_numstrings,
+ "Expected %d, got %d\n", read_write[i].evt_numstrings,
record->NumStrings);
+ ok(record->EventCategory == read_write[i].evt_cat,
+ "Expected %d, got %d\n", read_write[i].evt_cat,
record->EventCategory);
+
+ sourcename = (char *)((BYTE *)buf + sizeof(EVENTLOGRECORD));
+ ok(!lstrcmpA(sourcename, read_write[i].evt_src), "Expected '%s', got
'%s'\n",
+ read_write[i].evt_src, sourcename);
+
+ computername = (char *)((BYTE *)buf + sizeof(EVENTLOGRECORD) +
lstrlenA(sourcename) + 1);
+ ok(!lstrcmpiA(computername, localcomputer), "Expected '%s', got
'%s'\n",
+ localcomputer, computername);
+
+ /* Before Vista, UserSid was aligned on a DWORD boundary. Next to that if
+ * no padding was actually required a 0 DWORD was still used for padding. No
+ * application should be relying on the padding as we are working with offsets
+ * anyway.
+ */
+
+ if (!on_vista)
+ {
+ DWORD calculated_sidoffset = sizeof(EVENTLOGRECORD) + lstrlenA(sourcename) +
1 + lstrlenA(computername) + 1;
+
+ /* We are already DWORD aligned, there should still be some padding */
+ if ((((UINT_PTR)buf + calculated_sidoffset) % sizeof(DWORD)) == 0)
+ ok(*(DWORD *)((BYTE *)buf + calculated_sidoffset) == 0, "Expected
0\n");
+
+ ok((((UINT_PTR)buf + record->UserSidOffset) % sizeof(DWORD)) == 0,
"Expected DWORD alignment\n");
+ }
+
+ if (run_sidtests)
+ {
+ ok(record->UserSidLength == sidsize, "Expected %d, got %d\n",
sidsize, record->UserSidLength);
+ }
+ else
+ {
+ ok(record->StringOffset == record->UserSidOffset, "Expected
offsets to be the same\n");
+ ok(record->UserSidLength == 0, "Expected 0, got %d\n",
record->UserSidLength);
+ }
+
+ ok(record->DataLength == 0, "Expected 0, got %d\n",
record->DataLength);
+
+ ptr = (char *)((BYTE *)buf + record->StringOffset);
+ for (k = 0; k < record->NumStrings; k++)
+ {
+ ok(!lstrcmpA(ptr, two_strings[k]), "Expected '%s', got
'%s'\n", two_strings[k], ptr);
+ ptr += lstrlenA(ptr) + 1;
+ }
+
+ ok(record->Length == *(DWORD *)((BYTE *)buf + record->Length -
sizeof(DWORD)),
+ "Expected the closing DWORD to contain the length of the
record\n");
+
+ HeapFree(GetProcessHeap(), 0, buf);
+ i++;
+ }
+ CloseEventLog(handle);
+
+ /* Test clearing a real eventlog */
+ handle = OpenEventLogA(NULL, eventlogname);
+
+ SetLastError(0xdeadbeef);
+ ret = ClearEventLogA(handle, NULL);
+ ok(ret, "Expected success\n");
+
+ count = 0xdeadbeef;
+ ret = GetNumberOfEventLogRecords(handle, &count);
+ ok(ret, "Expected success\n");
+ ok(count == 0, "Expected an empty eventlog, got %d records\n", count);
+
+ CloseEventLog(handle);
+
+cleanup:
+ HeapFree(GetProcessHeap(), 0, localcomputer);
+ HeapFree(GetProcessHeap(), 0, user);
+}
+
+/* Before Vista:
+ *
+ * Creating an eventlog on Windows (via the registry) automatically leads
+ * to creation of a REG_MULTI_SZ named 'Sources'. This value lists all the
+ * potential event sources for this eventlog. 'Sources' is automatically
+ * updated when a new key (aka event source) is created.
+ *
+ * Although the updating of registry keys is almost instantaneously, we
+ * check it after some other tests to assure we are not querying the
+ * registry or file system to quickly.
+ *
+ * NT4 and higher:
+ *
+ * The eventlog file itself is also automatically created, even before we
+ * start writing events.
+ */
+static char eventlogfile[MAX_PATH];
+static void test_autocreation(void)
+{
+ HKEY key, eventkey;
+ DWORD type, size;
+ LONG ret;
+ int i;
+ char *p;
+ char sources[sizeof(eventsources)];
+ char sysdir[MAX_PATH];
+ void *redir = 0;
+
+ RegOpenKeyA(HKEY_LOCAL_MACHINE, eventlogsvc, &key);
+ RegOpenKeyA(key, eventlogname, &eventkey);
+
+ size = sizeof(sources);
+ sources[0] = 0;
+ ret = RegQueryValueExA(eventkey, "Sources", NULL, &type,
(LPBYTE)sources, &size);
+ if (ret == ERROR_SUCCESS)
+ {
+ char sources_verify[sizeof(eventsources)];
+
+ ok(type == REG_MULTI_SZ, "Expected a REG_MULTI_SZ, got %d\n", type);
+
+ /* Build the expected string */
+ memset(sources_verify, 0, sizeof(sources_verify));
+ p = sources_verify;
+ for (i = sizeof(eventsources)/sizeof(eventsources[0]); i > 0; i--)
+ {
+ lstrcpyA(p, eventsources[i - 1]);
+ p += (lstrlenA(eventsources[i - 1]) + 1);
+ }
+ lstrcpyA(p, eventlogname);
+
+ ok(!memcmp(sources, sources_verify, size),
+ "Expected a correct 'Sources' value (size : %d)\n", size);
+ }
+
+ RegCloseKey(eventkey);
+ RegCloseKey(key);
+
+ /* The directory that holds the eventlog files could be redirected */
+ if (pWow64DisableWow64FsRedirection)
+ pWow64DisableWow64FsRedirection(&redir);
+
+ /* On Windows we also automatically get an eventlog file */
+ GetSystemDirectoryA(sysdir, sizeof(sysdir));
+
+ /* NT4 - W2K3 */
+ lstrcpyA(eventlogfile, sysdir);
+ lstrcatA(eventlogfile, "\\config\\");
+ lstrcatA(eventlogfile, eventlogname);
+ lstrcatA(eventlogfile, ".evt");
+
+ if (GetFileAttributesA(eventlogfile) == INVALID_FILE_ATTRIBUTES)
+ {
+ /* Vista+ */
+ lstrcpyA(eventlogfile, sysdir);
+ lstrcatA(eventlogfile, "\\winevt\\Logs\\");
+ lstrcatA(eventlogfile, eventlogname);
+ lstrcatA(eventlogfile, ".evtx");
+ }
+
+ ok(GetFileAttributesA(eventlogfile) != INVALID_FILE_ATTRIBUTES,
+ "Expected an eventlog file\n");
+
+ if (pWow64RevertWow64FsRedirection)
+ pWow64RevertWow64FsRedirection(redir);
+}
+
+static void cleanup_eventlog(void)
+{
+ BOOL bret;
+ LONG lret;
+ HKEY key;
+ int i;
+ char winesvc[MAX_PATH];
+
+ /* Delete the registry tree */
+ lstrcpyA(winesvc, eventlogsvc);
+ lstrcatA(winesvc, "\\");
+ lstrcatA(winesvc, eventlogname);
+
+ RegOpenKeyA(HKEY_LOCAL_MACHINE, winesvc, &key);
+ for (i = 0; i < sizeof(eventsources)/sizeof(eventsources[0]); i++)
+ RegDeleteKeyA(key, eventsources[i]);
+ RegDeleteValueA(key, "Sources");
+ RegCloseKey(key);
+ lret = RegDeleteKeyA(HKEY_LOCAL_MACHINE, winesvc);
+ todo_wine
+ ok(lret == ERROR_SUCCESS, "Could not delete the registry tree : %d\n",
lret);
+
+ /* A handle to the eventlog is locked by services.exe. We can only
+ * delete the eventlog file after reboot.
+ */
+ bret = MoveFileExA(eventlogfile, NULL, MOVEFILE_DELAY_UNTIL_REBOOT);
+ todo_wine
+ ok(bret, "Expected MoveFileEx to succeed: %d\n", GetLastError());
+}
+
+START_TEST(eventlog)
+{
+ SetLastError(0xdeadbeef);
+ CloseEventLog(NULL);
+ if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
+ {
+ win_skip("Event log functions are not implemented\n");
+ return;
+ }
+
+ init_function_pointers();
+
+ /* Parameters only */
+ test_open_close();
+ test_info();
+ test_count();
+ test_oldest();
+ test_backup();
+ test_openbackup();
+ test_read();
+ test_clear();
+
+ /* Functional tests */
+ if (create_new_eventlog())
+ {
+ test_readwrite();
+ test_autocreation();
+ }
+ cleanup_eventlog();
+}
Propchange: trunk/rostests/winetests/advapi32/eventlog.c
------------------------------------------------------------------------------
svn:eol-style = native
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] Wed Dec 23 16:15:54 2009
@@ -956,6 +956,28 @@
/* clean up */
RegDeleteKey(hkey2, "");
RegDeleteKey(hkey1, "");
+ RegCloseKey(hkey2);
+ RegCloseKey(hkey1);
+
+ /* test creation of volatile keys */
+ ret = RegCreateKeyExA(hkey_main, "Volatile", 0, NULL, REG_OPTION_VOLATILE,
KEY_ALL_ACCESS, NULL, &hkey1, NULL);
+ ok(!ret, "RegCreateKeyExA failed with error %d\n", ret);
+ ret = RegCreateKeyExA(hkey1, "Subkey2", 0, NULL, 0, KEY_ALL_ACCESS, NULL,
&hkey2, NULL);
+ ok(ret == ERROR_CHILD_MUST_BE_VOLATILE || broken(!ret), /* win9x */
+ "RegCreateKeyExA failed with error %d\n", ret);
+ if (!ret) RegCloseKey( hkey2 );
+ ret = RegCreateKeyExA(hkey1, "Subkey2", 0, NULL, REG_OPTION_VOLATILE,
KEY_ALL_ACCESS, NULL, &hkey2, NULL);
+ ok(!ret, "RegCreateKeyExA failed with error %d\n", ret);
+ RegCloseKey(hkey2);
+ /* should succeed if the key already exists */
+ ret = RegCreateKeyExA(hkey1, "Subkey2", 0, NULL, 0, KEY_ALL_ACCESS, NULL,
&hkey2, NULL);
+ ok(!ret, "RegCreateKeyExA failed with error %d\n", ret);
+
+ /* clean up */
+ RegDeleteKey(hkey2, "");
+ RegDeleteKey(hkey1, "");
+ RegCloseKey(hkey2);
+ RegCloseKey(hkey1);
/* beginning backslash character */
ret = RegCreateKeyExA(hkey_main, "\\Subkey3", 0, NULL, 0, KEY_NOTIFY, NULL,
&hkey1, NULL);
@@ -964,6 +986,7 @@
else {
ok(!ret, "RegCreateKeyExA failed with error %d\n", ret);
RegDeleteKey(hkey1, NULL);
+ RegCloseKey(hkey1);
}
/* WOW64 flags - open an existing key */
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] Wed Dec 23 16:15:54 2009
@@ -79,6 +79,7 @@
typedef BOOL (WINAPI *fnMakeSelfRelativeSD)( PSECURITY_DESCRIPTOR, PSECURITY_DESCRIPTOR,
LPDWORD );
typedef BOOL (WINAPI *fnConvertSidToStringSidA)( PSID pSid, LPSTR *str );
typedef BOOL (WINAPI *fnConvertStringSidToSidA)( LPCSTR str, PSID pSid );
+static BOOL (WINAPI *pCheckTokenMembership)(HANDLE, PSID, PBOOL);
static BOOL (WINAPI *pConvertStringSecurityDescriptorToSecurityDescriptorA)(LPCSTR,
DWORD,
PSECURITY_DESCRIPTOR*, PULONG );
static BOOL (WINAPI *pConvertStringSecurityDescriptorToSecurityDescriptorW)(LPCWSTR,
DWORD,
@@ -153,6 +154,7 @@
pAddAccessAllowedAceEx = (void *)GetProcAddress(hmod,
"AddAccessAllowedAceEx");
pAddAccessDeniedAceEx = (void *)GetProcAddress(hmod,
"AddAccessDeniedAceEx");
pAddAuditAccessAceEx = (void *)GetProcAddress(hmod,
"AddAuditAccessAceEx");
+ pCheckTokenMembership = (void *)GetProcAddress(hmod,
"CheckTokenMembership");
pConvertStringSecurityDescriptorToSecurityDescriptorA =
(void *)GetProcAddress(hmod,
"ConvertStringSecurityDescriptorToSecurityDescriptorA" );
pConvertStringSecurityDescriptorToSecurityDescriptorW =
@@ -254,6 +256,7 @@
ok(pisid->SubAuthority[0] == 21, "Invalid subauthority 0 - expceted 21, got
%d\n", pisid->SubAuthority[0]);
ok(pisid->SubAuthority[3] == 4576, "Invalid subauthority 0 - expceted 4576,
got %d\n", pisid->SubAuthority[3]);
LocalFree(str);
+ LocalFree(psid);
for( i = 0; i < sizeof(refs) / sizeof(refs[0]); i++ )
{
@@ -1226,10 +1229,18 @@
ok(ret, "OpenProcessToken failed with error %d\n", GetLastError());
/* groups */
+ SetLastError(0xdeadbeef);
ret = GetTokenInformation(Token, TokenGroups, NULL, 0, &Size);
+ ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
+ "GetTokenInformation(TokenGroups) %s with error %d\n",
+ ret ? "succeeded" : "failed", GetLastError());
Groups = HeapAlloc(GetProcessHeap(), 0, Size);
+ SetLastError(0xdeadbeef);
ret = GetTokenInformation(Token, TokenGroups, Groups, Size, &Size);
ok(ret, "GetTokenInformation(TokenGroups) failed with error %d\n",
GetLastError());
+ ok(GetLastError() == 0xdeadbeef,
+ "GetTokenInformation shouldn't have set last error to %d\n",
+ GetLastError());
trace("TokenGroups:\n");
for (i = 0; i < Groups->GroupCount; i++)
{
@@ -1238,12 +1249,12 @@
DWORD DomainLength = 255;
TCHAR Domain[255];
SID_NAME_USE SidNameUse;
- pConvertSidToStringSidA(Groups->Groups[i].Sid, &SidString);
Name[0] = '\0';
Domain[0] = '\0';
ret = LookupAccountSid(NULL, Groups->Groups[i].Sid, Name, &NameLength,
Domain, &DomainLength, &SidNameUse);
if (ret)
{
+ pConvertSidToStringSidA(Groups->Groups[i].Sid, &SidString);
trace("%s, %s\\%s use: %d attr: 0x%08x\n", SidString, Domain, Name,
SidNameUse, Groups->Groups[i].Attributes);
LocalFree(SidString);
}
@@ -1478,6 +1489,8 @@
ok(memcmp(buf2, sid_buffer, cb) == 0, "SID create with domain is
different than without (%d)\n", i);
}
}
+
+ LocalFree(domainsid);
}
static void test_LookupAccountSid(void)
@@ -2047,7 +2060,8 @@
domain = HeapAlloc(GetProcessHeap(), 0, domain_size);
ret = LookupAccountNameA(NULL, computer_name, psid, &sid_size, domain,
&domain_size, &sid_use);
ok(ret, "LookupAccountNameA failed: %d\n", GetLastError());
- ok(sid_use == SidTypeDomain, "expected SidTypeDomain, got %d\n",
sid_use);
+ ok(sid_use == SidTypeDomain ||
+ (sid_use == SidTypeUser && ! strcmp(computer_name, user_name)),
"expected SidTypeDomain for %s, got %d\n", computer_name, sid_use);
HeapFree(GetProcessHeap(), 0, domain);
HeapFree(GetProcessHeap(), 0, psid);
}
@@ -2528,11 +2542,19 @@
ExplicitAccess.grfAccessPermissions = KEY_WRITE;
ExplicitAccess.grfAccessMode = GRANT_ACCESS;
ExplicitAccess.grfInheritance = NO_INHERITANCE;
+ ExplicitAccess.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
+ ExplicitAccess.Trustee.TrusteeForm = TRUSTEE_IS_SID;
+ ExplicitAccess.Trustee.ptstrName = EveryoneSid;
+ ExplicitAccess.Trustee.MultipleTrusteeOperation = 0xDEADBEEF;
+ ExplicitAccess.Trustee.pMultipleTrustee = (PVOID)0xDEADBEEF;
+ res = pSetEntriesInAclW(1, &ExplicitAccess, OldAcl, &NewAcl);
+ ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %u\n", res);
+ ok(NewAcl != NULL, "returned acl was NULL\n");
+ LocalFree(NewAcl);
+
+ ExplicitAccess.Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
ExplicitAccess.Trustee.pMultipleTrustee = NULL;
ExplicitAccess.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
- ExplicitAccess.Trustee.TrusteeForm = TRUSTEE_IS_SID;
- ExplicitAccess.Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
- ExplicitAccess.Trustee.ptstrName = EveryoneSid;
res = pSetEntriesInAclW(1, &ExplicitAccess, OldAcl, &NewAcl);
ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %u\n", res);
ok(NewAcl != NULL, "returned acl was NULL\n");
@@ -2651,6 +2673,50 @@
BOOL ret;
PSECURITY_DESCRIPTOR pSD;
static const WCHAR Blank[] = { 0 };
+ int i;
+ static const struct
+ {
+ const char *sidstring;
+ DWORD revision;
+ BOOL ret;
+ DWORD GLE;
+ DWORD altGLE;
+ } cssd[] =
+ {
+ { "D:(A;;GA;;;WD)", 0xdeadbeef, FALSE,
ERROR_UNKNOWN_REVISION },
+ /* test ACE string type */
+ { "D:(A;;GA;;;WD)", SDDL_REVISION_1, TRUE },
+ { "D:(D;;GA;;;WD)", SDDL_REVISION_1, TRUE },
+ { "ERROR:(D;;GA;;;WD)", SDDL_REVISION_1, FALSE,
ERROR_INVALID_PARAMETER },
+ /* test ACE string with spaces */
+ { " D:(D;;GA;;;WD)", SDDL_REVISION_1, TRUE },
+ { "D: (D;;GA;;;WD)", SDDL_REVISION_1, TRUE },
+ { "D:( D;;GA;;;WD)", SDDL_REVISION_1, TRUE },
+ { "D:(D ;;GA;;;WD)", SDDL_REVISION_1, FALSE,
RPC_S_INVALID_STRING_UUID, ERROR_INVALID_ACL }, /* Vista+ */
+ { "D:(D; ;GA;;;WD)", SDDL_REVISION_1, TRUE },
+ { "D:(D;; GA;;;WD)", SDDL_REVISION_1, TRUE },
+ { "D:(D;;GA ;;;WD)", SDDL_REVISION_1, FALSE,
ERROR_INVALID_ACL },
+ { "D:(D;;GA; ;;WD)", SDDL_REVISION_1, TRUE },
+ { "D:(D;;GA;; ;WD)", SDDL_REVISION_1, TRUE },
+ { "D:(D;;GA;;; WD)", SDDL_REVISION_1, TRUE },
+ { "D:(D;;GA;;;WD )", SDDL_REVISION_1, TRUE },
+ /* test ACE string access rights */
+ { "D:(A;;GA;;;WD)", SDDL_REVISION_1, TRUE },
+ { "D:(A;;GRGWGX;;;WD)", SDDL_REVISION_1, TRUE },
+ { "D:(A;;RCSDWDWO;;;WD)", SDDL_REVISION_1, TRUE },
+ { "D:(A;;RPWPCCDCLCSWLODTCR;;;WD)", SDDL_REVISION_1, TRUE },
+ { "D:(A;;FAFRFWFX;;;WD)", SDDL_REVISION_1, TRUE },
+ { "D:(A;;KAKRKWKX;;;WD)", SDDL_REVISION_1, TRUE },
+ { "D:(A;;0xFFFFFFFF;;;WD)", SDDL_REVISION_1, TRUE },
+ { "S:(AU;;0xFFFFFFFF;;;WD)", SDDL_REVISION_1, TRUE },
+ /* test ACE string access right error case */
+ { "D:(A;;ROB;;;WD)", SDDL_REVISION_1, FALSE,
ERROR_INVALID_ACL },
+ /* test behaviour with empty strings */
+ { "", SDDL_REVISION_1, TRUE },
+ /* test ACE string SID */
+ { "D:(D;;GA;;;S-1-0-0)", SDDL_REVISION_1, TRUE },
+ { "D:(D;;GA;;;Nonexistent account)", SDDL_REVISION_1, FALSE,
ERROR_INVALID_ACL, ERROR_INVALID_SID } /* W2K */
+ };
if (!pConvertStringSecurityDescriptorToSecurityDescriptorA)
{
@@ -2658,82 +2724,22 @@
return;
}
- SetLastError(0xdeadbeef);
- ret = pConvertStringSecurityDescriptorToSecurityDescriptorA(
- "D:(A;;GA;;;WD)", 0xdeadbeef, &pSD, NULL);
- ok(!ret && GetLastError() == ERROR_UNKNOWN_REVISION,
- "ConvertStringSecurityDescriptorToSecurityDescriptor should have failed with
ERROR_UNKNOWN_REVISION instead of %d\n",
- GetLastError());
-
- /* test ACE string type */
- SetLastError(0xdeadbeef);
- ret = pConvertStringSecurityDescriptorToSecurityDescriptorA(
- "D:(A;;GA;;;WD)", SDDL_REVISION_1, &pSD, NULL);
- ok(ret, "ConvertStringSecurityDescriptorToSecurityDescriptor failed with error
%d\n", GetLastError());
- LocalFree(pSD);
-
- SetLastError(0xdeadbeef);
- ret = pConvertStringSecurityDescriptorToSecurityDescriptorA(
- "D:(D;;GA;;;WD)", SDDL_REVISION_1, &pSD, NULL);
- ok(ret, "ConvertStringSecurityDescriptorToSecurityDescriptor failed with error
%d\n", GetLastError());
- LocalFree(pSD);
-
- SetLastError(0xdeadbeef);
- ret = pConvertStringSecurityDescriptorToSecurityDescriptorA(
- "ERROR:(D;;GA;;;WD)", SDDL_REVISION_1, &pSD, NULL);
- ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
- "ConvertStringSecurityDescriptorToSecurityDescriptor should have failed with
ERROR_INVALID_PARAMETER instead of %d\n",
- GetLastError());
-
- /* test ACE string access rights */
- SetLastError(0xdeadbeef);
- ret = pConvertStringSecurityDescriptorToSecurityDescriptorA(
- "D:(A;;GA;;;WD)", SDDL_REVISION_1, &pSD, NULL);
- ok(ret, "ConvertStringSecurityDescriptorToSecurityDescriptor failed with error
%d\n", GetLastError());
- LocalFree(pSD);
- SetLastError(0xdeadbeef);
- ret = pConvertStringSecurityDescriptorToSecurityDescriptorA(
- "D:(A;;GRGWGX;;;WD)", SDDL_REVISION_1, &pSD, NULL);
- ok(ret, "ConvertStringSecurityDescriptorToSecurityDescriptor failed with error
%d\n", GetLastError());
- LocalFree(pSD);
- SetLastError(0xdeadbeef);
- ret = pConvertStringSecurityDescriptorToSecurityDescriptorA(
- "D:(A;;RCSDWDWO;;;WD)", SDDL_REVISION_1, &pSD, NULL);
- ok(ret, "ConvertStringSecurityDescriptorToSecurityDescriptor failed with error
%d\n", GetLastError());
- LocalFree(pSD);
- SetLastError(0xdeadbeef);
- ret = pConvertStringSecurityDescriptorToSecurityDescriptorA(
- "D:(A;;RPWPCCDCLCSWLODTCR;;;WD)", SDDL_REVISION_1, &pSD, NULL);
- ok(ret, "ConvertStringSecurityDescriptorToSecurityDescriptor failed with error
%d\n", GetLastError());
- LocalFree(pSD);
- SetLastError(0xdeadbeef);
- ret = pConvertStringSecurityDescriptorToSecurityDescriptorA(
- "D:(A;;FAFRFWFX;;;WD)", SDDL_REVISION_1, &pSD, NULL);
- ok(ret, "ConvertStringSecurityDescriptorToSecurityDescriptor failed with error
%d\n", GetLastError());
- LocalFree(pSD);
- SetLastError(0xdeadbeef);
- ret = pConvertStringSecurityDescriptorToSecurityDescriptorA(
- "D:(A;;KAKRKWKX;;;WD)", SDDL_REVISION_1, &pSD, NULL);
- ok(ret, "ConvertStringSecurityDescriptorToSecurityDescriptor failed with error
%d\n", GetLastError());
- LocalFree(pSD);
- SetLastError(0xdeadbeef);
- ret = pConvertStringSecurityDescriptorToSecurityDescriptorA(
- "D:(A;;0xFFFFFFFF;;;WD)", SDDL_REVISION_1, &pSD, NULL);
- ok(ret, "ConvertStringSecurityDescriptorToSecurityDescriptor failed with error
%d\n", GetLastError());
- LocalFree(pSD);
- SetLastError(0xdeadbeef);
- ret = pConvertStringSecurityDescriptorToSecurityDescriptorA(
- "S:(AU;;0xFFFFFFFF;;;WD)", SDDL_REVISION_1, &pSD, NULL);
- ok(ret, "ConvertStringSecurityDescriptorToSecurityDescriptor failed with error
%d\n", GetLastError());
- LocalFree(pSD);
-
- /* test ACE string access right error case */
- SetLastError(0xdeadbeef);
- ret = pConvertStringSecurityDescriptorToSecurityDescriptorA(
- "D:(A;;ROB;;;WD)", SDDL_REVISION_1, &pSD, NULL);
- ok(!ret && GetLastError() == ERROR_INVALID_ACL,
- "ConvertStringSecurityDescriptorToSecurityDescriptor should have failed with
ERROR_INVALID_ACL instead of %d\n",
- GetLastError());
+ for (i = 0; i < sizeof(cssd)/sizeof(cssd[0]); i++)
+ {
+ DWORD GLE;
+
+ SetLastError(0xdeadbeef);
+ ret = pConvertStringSecurityDescriptorToSecurityDescriptorA(
+ cssd[i].sidstring, cssd[i].revision, &pSD, NULL);
+ GLE = GetLastError();
+ ok(ret == cssd[i].ret, "(%02d) Expected %s (%d)\n", i, cssd[i].ret ?
"success" : "failure", GLE);
+ if (!cssd[i].ret)
+ ok(GLE == cssd[i].GLE ||
+ (cssd[i].altGLE && GLE == cssd[i].altGLE),
+ "(%02d) Unexpected last error %d\n", i, GLE);
+ if (ret)
+ LocalFree(pSD);
+ }
/* test behaviour with NULL parameters */
SetLastError(0xdeadbeef);
@@ -2767,28 +2773,10 @@
/* 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);
- ret = pConvertStringSecurityDescriptorToSecurityDescriptorA(
- "D:(D;;GA;;;S-1-0-0)", SDDL_REVISION_1, &pSD, NULL);
- ok(ret, "ConvertStringSecurityDescriptorToSecurityDescriptor failed with error
%d\n", GetLastError());
LocalFree(pSD);
-
- SetLastError(0xdeadbeef);
- ret = pConvertStringSecurityDescriptorToSecurityDescriptorA(
- "D:(D;;GA;;;Nonexistent account)", SDDL_REVISION_1, &pSD, NULL);
- ok(!ret, "Expected failure, got %d\n", ret);
- ok(GetLastError() == ERROR_INVALID_ACL || GetLastError() == ERROR_INVALID_SID,
- "Expected ERROR_INVALID_ACL or ERROR_INVALID_SID, got %d\n",
GetLastError());
}
static void test_ConvertSecurityDescriptorToString(void)
@@ -2900,6 +2888,9 @@
CHECK_ONE_OF_AND_FREE("O:SYG:S-1-5-21-93476-23408-4576D:S:(AU;OICINPIOIDSAFA;CCDCLCSWRPRC;;;SU)(AU;NPSA;0x12019f;;;SU)",
/* XP */
"O:SYG:S-1-5-21-93476-23408-4576D:NO_ACCESS_CONTROLS:(AU;OICINPIOIDSAFA;CCDCLCSWRPRC;;;SU)(AU;NPSA;0x12019f;;;SU)"
/* Vista */);
}
+
+ LocalFree(psid2);
+ LocalFree(psid);
}
static void test_SetSecurityDescriptorControl (PSECURITY_DESCRIPTOR sec)
@@ -3171,8 +3162,10 @@
ok(sd != NULL, "GetSecurityInfo\n");
ok(owner != NULL, "GetSecurityInfo\n");
ok(group != NULL, "GetSecurityInfo\n");
- ok(dacl != NULL, "GetSecurityInfo\n");
- ok(IsValidAcl(dacl), "GetSecurityInfo\n");
+ if (dacl != NULL)
+ ok(IsValidAcl(dacl), "GetSecurityInfo\n");
+ else
+ win_skip("No ACL information returned\n");
LocalFree(sd);
@@ -3191,8 +3184,10 @@
ok(ret == ERROR_SUCCESS, "GetSecurityInfo returned %d\n", ret);
ok(owner != NULL, "GetSecurityInfo\n");
ok(group != NULL, "GetSecurityInfo\n");
- ok(dacl != NULL, "GetSecurityInfo\n");
- ok(IsValidAcl(dacl), "GetSecurityInfo\n");
+ if (dacl != NULL)
+ ok(IsValidAcl(dacl), "GetSecurityInfo\n");
+ else
+ win_skip("No ACL information returned\n");
CloseHandle(obj);
}
@@ -3220,9 +3215,138 @@
ok(*pGetSidSubAuthority(psid,1) == 93476,"GetSidSubAuthority gave %d expected
93476\n",*pGetSidSubAuthority(psid,1));
ok(GetLastError() == 0,"GetLastError returned %d instead of
0\n",GetLastError());
SetLastError(0xbebecaca);
- todo_wine ok(*pGetSidSubAuthority(psid,4) == 0,"GetSidSubAuthority gave
%d,expected 0\n",*pGetSidSubAuthority(psid,4));
+ ok(pGetSidSubAuthority(psid,4) != NULL,"Expected out of bounds
GetSidSubAuthority to return a non-NULL pointer\n");
ok(GetLastError() == 0,"GetLastError returned %d instead of
0\n",GetLastError());
LocalFree(psid);
+}
+
+static void test_CheckTokenMembership(void)
+{
+ PTOKEN_GROUPS token_groups;
+ DWORD size;
+ HANDLE process_token, token;
+ BOOL is_member;
+ BOOL ret;
+ DWORD i;
+
+ if (!pCheckTokenMembership)
+ {
+ win_skip("CheckTokenMembership is not available\n");
+ return;
+ }
+ ret = OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE|TOKEN_QUERY,
&process_token);
+ ok(ret, "OpenProcessToken failed with error %d\n", GetLastError());
+
+ ret = DuplicateToken(process_token, SecurityImpersonation, &token);
+ ok(ret, "DuplicateToken failed with error %d\n", GetLastError());
+
+ /* groups */
+ ret = GetTokenInformation(token, TokenGroups, NULL, 0, &size);
+ ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
+ "GetTokenInformation(TokenGroups) %s with error %d\n",
+ ret ? "succeeded" : "failed", GetLastError());
+ token_groups = HeapAlloc(GetProcessHeap(), 0, size);
+ ret = GetTokenInformation(token, TokenGroups, token_groups, size, &size);
+ ok(ret, "GetTokenInformation(TokenGroups) failed with error %d\n",
GetLastError());
+
+ for (i = 0; i < token_groups->GroupCount; i++)
+ {
+ if (token_groups->Groups[i].Attributes & SE_GROUP_ENABLED)
+ break;
+ }
+
+ if (i == token_groups->GroupCount)
+ {
+ HeapFree(GetProcessHeap(), 0, token_groups);
+ CloseHandle(token);
+ skip("user not a member of any group\n");
+ return;
+ }
+
+ ret = pCheckTokenMembership(token, token_groups->Groups[i].Sid, &is_member);
+ ok(ret, "CheckTokenMembership failed with error %d\n", GetLastError());
+ ok(is_member, "CheckTokenMembership should have detected sid as
member\n");
+
+ ret = pCheckTokenMembership(NULL, token_groups->Groups[i].Sid, &is_member);
+ ok(ret, "CheckTokenMembership failed with error %d\n", GetLastError());
+ ok(is_member, "CheckTokenMembership should have detected sid as
member\n");
+
+ ret = pCheckTokenMembership(process_token, token_groups->Groups[i].Sid,
&is_member);
+todo_wine {
+ ok(!ret && GetLastError() == ERROR_NO_IMPERSONATION_TOKEN,
+ "CheckTokenMembership with process token %s with error %d\n",
+ ret ? "succeeded" : "failed", GetLastError());
+ ok(!is_member, "CheckTokenMembership should have cleared is_member\n");
+}
+
+ HeapFree(GetProcessHeap(), 0, token_groups);
+ CloseHandle(token);
+ CloseHandle(process_token);
+}
+
+static void test_EqualSid(void)
+{
+ PSID sid1, sid2;
+ BOOL ret;
+ SID_IDENTIFIER_AUTHORITY SIDAuthWorld = { SECURITY_WORLD_SID_AUTHORITY };
+ SID_IDENTIFIER_AUTHORITY SIDAuthNT = { SECURITY_NT_AUTHORITY };
+
+ SetLastError(0xdeadbeef);
+ ret = AllocateAndInitializeSid(&SIDAuthNT, 2, SECURITY_BUILTIN_DOMAIN_RID,
+ DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &sid1);
+ if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
+ {
+ win_skip("AllocateAndInitializeSid is not implemented\n");
+ return;
+ }
+ ok(ret, "AllocateAndInitializeSid failed with error %d\n",
GetLastError());
+ ok(GetLastError() == 0xdeadbeef,
+ "AllocateAndInitializeSid shouldn't have set last error to %d\n",
+ GetLastError());
+
+ ret = AllocateAndInitializeSid(&SIDAuthWorld, 1, SECURITY_WORLD_RID,
+ 0, 0, 0, 0, 0, 0, 0, &sid2);
+ ok(ret, "AllocateAndInitializeSid failed with error %d\n",
GetLastError());
+
+ SetLastError(0xdeadbeef);
+ ret = EqualSid(sid1, sid2);
+ ok(!ret, "World and domain admins sids shouldn't have been equal\n");
+ ok(GetLastError() == ERROR_SUCCESS ||
+ broken(GetLastError() == 0xdeadbeef), /* NT4 */
+ "EqualSid should have set last error to ERROR_SUCCESS instead of %d\n",
+ GetLastError());
+
+ SetLastError(0xdeadbeef);
+ sid2 = FreeSid(sid2);
+ ok(!sid2, "FreeSid should have returned NULL instead of %p\n", sid2);
+ ok(GetLastError() == 0xdeadbeef,
+ "FreeSid shouldn't have set last error to %d\n",
+ GetLastError());
+
+ ret = AllocateAndInitializeSid(&SIDAuthNT, 2, SECURITY_BUILTIN_DOMAIN_RID,
+ DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &sid2);
+ ok(ret, "AllocateAndInitializeSid failed with error %d\n",
GetLastError());
+
+ SetLastError(0xdeadbeef);
+ ret = EqualSid(sid1, sid2);
+ ok(ret, "Same sids should have been equal\n");
+ ok(GetLastError() == ERROR_SUCCESS ||
+ broken(GetLastError() == 0xdeadbeef), /* NT4 */
+ "EqualSid should have set last error to ERROR_SUCCESS instead of %d\n",
+ GetLastError());
+
+ ((SID *)sid2)->Revision = 2;
+ SetLastError(0xdeadbeef);
+ ret = EqualSid(sid1, sid2);
+ ok(!ret, "EqualSid with invalid sid should have returned FALSE\n");
+ ok(GetLastError() == ERROR_SUCCESS ||
+ broken(GetLastError() == 0xdeadbeef), /* NT4 */
+ "EqualSid should have set last error to ERROR_SUCCESS instead of %d\n",
+ GetLastError());
+ ((SID *)sid2)->Revision = SID_REVISION;
+
+ FreeSid(sid1);
+ FreeSid(sid2);
}
START_TEST(security)
@@ -3255,4 +3379,6 @@
test_acls();
test_GetSecurityInfo();
test_GetSidSubAuthority();
-}
+ test_CheckTokenMembership();
+ test_EqualSid();
+}
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] Wed Dec 23 16:15:54 2009
@@ -38,6 +38,9 @@
static BOOL (WINAPI *pEnumServicesStatusExA)(SC_HANDLE, SC_ENUM_TYPE, DWORD,
DWORD, LPBYTE, DWORD, LPDWORD,
LPDWORD, LPDWORD, LPCSTR);
+static BOOL (WINAPI *pEnumServicesStatusExW)(SC_HANDLE, SC_ENUM_TYPE, DWORD,
+ DWORD, LPBYTE, DWORD, LPDWORD,
+ LPDWORD, LPDWORD, LPCWSTR);
static DWORD (WINAPI *pGetSecurityInfo)(HANDLE, SE_OBJECT_TYPE, SECURITY_INFORMATION,
PSID*, PSID*, PACL*, PACL*,
PSECURITY_DESCRIPTOR*);
static BOOL (WINAPI *pQueryServiceConfig2A)(SC_HANDLE,DWORD,LPBYTE,DWORD,LPDWORD);
@@ -51,6 +54,7 @@
pChangeServiceConfig2A = (void*)GetProcAddress(hadvapi32,
"ChangeServiceConfig2A");
pEnumServicesStatusExA= (void*)GetProcAddress(hadvapi32,
"EnumServicesStatusExA");
+ pEnumServicesStatusExW= (void*)GetProcAddress(hadvapi32,
"EnumServicesStatusExW");
pGetSecurityInfo = (void *)GetProcAddress(hadvapi32, "GetSecurityInfo");
pQueryServiceConfig2A= (void*)GetProcAddress(hadvapi32,
"QueryServiceConfig2A");
pQueryServiceConfig2W= (void*)GetProcAddress(hadvapi32,
"QueryServiceConfig2W");
@@ -1030,6 +1034,7 @@
SC_HANDLE scm_handle;
BOOL ret;
DWORD bufsize, needed, returned, resume;
+ DWORD neededW, returnedW;
DWORD tempneeded, tempreturned, missing;
DWORD servicecountactive, servicecountinactive;
ENUM_SERVICE_STATUS *services;
@@ -1159,6 +1164,12 @@
ok(GetLastError() == ERROR_MORE_DATA,
"Expected ERROR_MORE_DATA, got %d\n", GetLastError());
}
+
+ /* Test to show we get the same needed buffer size for the W-call */
+ neededW = 0xdeadbeef;
+ ret = EnumServicesStatusW(scm_handle, SERVICE_WIN32, SERVICE_STATE_ALL, NULL, 0,
+ &neededW, &returnedW, NULL);
+ ok(neededW == needed, "Expected needed buffersize to be the same for A- and
W-calls\n");
/* Store the needed bytes */
tempneeded = needed;
@@ -1505,6 +1516,12 @@
ok(GetLastError() == ERROR_MORE_DATA,
"Expected ERROR_MORE_DATA, got %d\n", GetLastError());
}
+
+ /* Test to show we get the same needed buffer size for the W-call */
+ neededW = 0xdeadbeef;
+ ret = pEnumServicesStatusExW(scm_handle, 0, SERVICE_WIN32, SERVICE_STATE_ALL,
+ NULL, 0, &neededW, &returnedW, NULL, NULL);
+ ok(neededW == needed, "Expected needed buffersize to be the same for A- and
W-calls\n");
/* Store the needed bytes */
tempneeded = needed;