1 /* 2 * Unit test suite for fault reporting in XP and above 3 * 4 * Copyright 2010 Detlef Riekenberg 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 19 * 20 */ 21 22 #include <stdarg.h> 23 #include <stdio.h> 24 25 #include "windef.h" 26 #include "winbase.h" 27 #include "winerror.h" 28 #include "winreg.h" 29 30 #include "errorrep.h" 31 #include "wine/test.h" 32 33 static const char regpath_root[] = "Software\\Microsoft\\PCHealth\\ErrorReporting"; 34 static const char regpath_exclude[] = "ExclusionList"; 35 36 37 static BOOL is_process_limited(void) 38 { 39 static BOOL (WINAPI *pCheckTokenMembership)(HANDLE,PSID,PBOOL) = NULL; 40 static BOOL (WINAPI *pOpenProcessToken)(HANDLE, DWORD, PHANDLE) = NULL; 41 SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY}; 42 PSID Group; 43 BOOL IsInGroup; 44 HANDLE token; 45 46 if (!pOpenProcessToken) 47 { 48 HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll"); 49 pOpenProcessToken = (void*)GetProcAddress(hadvapi32, "OpenProcessToken"); 50 pCheckTokenMembership = (void*)GetProcAddress(hadvapi32, "CheckTokenMembership"); 51 if (!pCheckTokenMembership || !pOpenProcessToken) 52 { 53 /* Win9x (power to the masses) or NT4 (no way to know) */ 54 trace("missing pOpenProcessToken or CheckTokenMembership\n"); 55 return FALSE; 56 } 57 } 58 59 if (!AllocateAndInitializeSid(&NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, 60 DOMAIN_ALIAS_RID_ADMINS, 61 0, 0, 0, 0, 0, 0, &Group) || 62 !pCheckTokenMembership(NULL, Group, &IsInGroup)) 63 { 64 trace("Could not check if the current user is an administrator\n"); 65 return FALSE; 66 } 67 if (!IsInGroup) 68 { 69 if (!AllocateAndInitializeSid(&NtAuthority, 2, 70 SECURITY_BUILTIN_DOMAIN_RID, 71 DOMAIN_ALIAS_RID_POWER_USERS, 72 0, 0, 0, 0, 0, 0, &Group) || 73 !pCheckTokenMembership(NULL, Group, &IsInGroup)) 74 { 75 trace("Could not check if the current user is a power user\n"); 76 return FALSE; 77 } 78 if (!IsInGroup) 79 { 80 /* Only administrators and power users can be powerful */ 81 return TRUE; 82 } 83 } 84 85 if (pOpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token)) 86 { 87 BOOL ret; 88 TOKEN_ELEVATION_TYPE type = TokenElevationTypeDefault; 89 DWORD size; 90 91 ret = GetTokenInformation(token, TokenElevationType, &type, sizeof(type), &size); 92 CloseHandle(token); 93 return (ret && type == TokenElevationTypeLimited); 94 } 95 return FALSE; 96 } 97 98 99 /* ###### */ 100 101 static void test_AddERExcludedApplicationA(void) 102 { 103 BOOL res; 104 LONG lres; 105 HKEY hroot; 106 HKEY hexclude = 0; 107 108 /* clean state */ 109 lres = RegCreateKeyA(HKEY_LOCAL_MACHINE, regpath_root, &hroot); 110 if (lres == ERROR_ACCESS_DENIED) 111 { 112 skip("Not enough access rights\n"); 113 return; 114 } 115 116 if (!lres) 117 lres = RegOpenKeyA(hroot, regpath_exclude, &hexclude); 118 119 if (!lres) 120 RegDeleteValueA(hexclude, "winetest_faultrep.exe"); 121 122 123 SetLastError(0xdeadbeef); 124 res = AddERExcludedApplicationA(NULL); 125 ok(!res, "got %d and 0x%x (expected FALSE)\n", res, GetLastError()); 126 127 SetLastError(0xdeadbeef); 128 res = AddERExcludedApplicationA(""); 129 ok(!res, "got %d and 0x%x (expected FALSE)\n", res, GetLastError()); 130 131 SetLastError(0xdeadbeef); 132 /* existence of the path doesn't matter this function succeeded */ 133 res = AddERExcludedApplicationA("winetest_faultrep.exe"); 134 if (is_process_limited()) 135 { 136 /* LastError is not set! */ 137 ok(!res, "AddERExcludedApplicationA should have failed got %d\n", res); 138 } 139 else 140 { 141 ok(res, "AddERExcludedApplicationA failed (le=0x%x)\n", GetLastError()); 142 143 /* add, when already present */ 144 SetLastError(0xdeadbeef); 145 res = AddERExcludedApplicationA("winetest_faultrep.exe"); 146 ok(res, "AddERExcludedApplicationA failed (le=0x%x)\n", GetLastError()); 147 } 148 149 /* cleanup */ 150 RegDeleteValueA(hexclude, "winetest_faultrep.exe"); 151 152 RegCloseKey(hexclude); 153 RegCloseKey(hroot); 154 } 155 156 /* ########################### */ 157 158 START_TEST(faultrep) 159 { 160 test_AddERExcludedApplicationA(); 161 } 162