Changeset 39412 in vbox for trunk/src/VBox/HostServices
- Timestamp:
- Nov 24, 2011 5:23:56 PM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostServices/SharedOpenGL/render/renderspu_wgl.c
r38505 r39412 18 18 #include "renderspu.h" 19 19 #include "cr_mem.h" 20 21 22 /* IAT patcher stuff */ 23 #define RVA2PTR(_t, _base, _off) ((_t*)(((uint8_t*)(_base)) + (_off))) 24 25 int renderspuIatPatcherGetImportAddress(HMODULE hModule, LPCSTR pszLib, LPCSTR pszName, void** ppAdr) 26 { 27 PIMAGE_DOS_HEADER pDosHdr = (PIMAGE_DOS_HEADER)hModule; 28 PIMAGE_NT_HEADERS pNtHdr; 29 PIMAGE_IMPORT_DESCRIPTOR pImportDr; 30 DWORD rvaImport; 31 32 crDebug("searching entry %s from %s", pszName, pszLib); 33 34 *ppAdr = 0; 35 36 if (pDosHdr->e_magic != IMAGE_DOS_SIGNATURE) 37 { 38 crWarning("invalid dos signature"); 39 return VERR_INVALID_HANDLE; 40 } 41 pNtHdr = RVA2PTR(IMAGE_NT_HEADERS, pDosHdr, pDosHdr->e_lfanew); 42 if (pNtHdr->Signature != IMAGE_NT_SIGNATURE) 43 { 44 crWarning("invalid nt signature"); 45 return VERR_INVALID_HANDLE; 46 } 47 rvaImport = pNtHdr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress; 48 if (!rvaImport) 49 { 50 crWarning("no imports found"); 51 return VERR_NOT_FOUND; 52 } 53 pImportDr = RVA2PTR(IMAGE_IMPORT_DESCRIPTOR, pDosHdr, rvaImport); 54 55 for ( ;pImportDr->TimeDateStamp != 0 || pImportDr->Name != 0; ++pImportDr) 56 { 57 DWORD rvaINT, rvaIAT; 58 PIMAGE_THUNK_DATA pINT, pIAT; 59 LPCSTR pszLibCur = RVA2PTR(char, pDosHdr, pImportDr->Name); 60 if (stricmp(pszLibCur, pszLib)) 61 continue; 62 63 /* got the necessary lib! */ 64 crDebug("got info for lib"); 65 66 rvaINT = pImportDr->OriginalFirstThunk; 67 rvaIAT = pImportDr->FirstThunk; 68 69 if (!rvaINT || !rvaIAT) 70 { 71 crWarning("either rvaINT(0x%x) or rvaIAT(0x%x) are NULL, nothing found!", rvaINT, rvaIAT); 72 return VERR_NOT_FOUND; 73 } 74 75 pINT = RVA2PTR(IMAGE_THUNK_DATA, pDosHdr, rvaINT); 76 pIAT = RVA2PTR(IMAGE_THUNK_DATA, pDosHdr, rvaIAT); 77 78 for ( ; pINT->u1.AddressOfData; ++pINT, ++pIAT) 79 { 80 PIMAGE_IMPORT_BY_NAME pIbn; 81 82 if (IMAGE_SNAP_BY_ORDINAL(pINT->u1.Ordinal)) 83 continue; 84 85 pIbn = RVA2PTR(IMAGE_IMPORT_BY_NAME, pDosHdr, pINT->u1.AddressOfData); 86 87 if (stricmp(pszName, (char*)pIbn->Name)) 88 continue; 89 90 *ppAdr = &pIAT->u1.Function; 91 92 crDebug("search succeeded!"); 93 return VINF_SUCCESS; 94 } 95 } 96 97 crDebug("not found"); 98 return VERR_NOT_FOUND; 99 } 100 101 int renderspuIatPatcherPatchEntry(void *pvEntry, void *pvValue, void **ppvOldVal) 102 { 103 void **ppfn = (void**)pvEntry; 104 DWORD dwOldProtect = 0; 105 106 if (!VirtualProtect(pvEntry, sizeof (pvEntry), PAGE_READWRITE, &dwOldProtect)) 107 { 108 crWarning("VirtualProtect 1 failed, %d", GetLastError()); 109 return VERR_ACCESS_DENIED; 110 } 111 112 if (ppvOldVal) 113 *ppvOldVal = *ppfn; 114 *ppfn = pvValue; 115 116 if (!VirtualProtect(pvEntry, sizeof (pvEntry), dwOldProtect, &dwOldProtect)) 117 { 118 crWarning("VirtualProtect 2 failed, %d.. ignoring", GetLastError()); 119 } 120 121 return VINF_SUCCESS; 122 } 123 124 125 int renderspuIatPatcherPatchFunction(HMODULE hModule, LPCSTR pszLib, LPCSTR pszName, void* pfn) 126 { 127 void* pAdr; 128 int rc = renderspuIatPatcherGetImportAddress(hModule, pszLib, pszName, &pAdr); 129 if (RT_FAILURE(rc)) 130 { 131 crDebug("renderspuIatPatcherGetImportAddress failed, %d", rc); 132 return rc; 133 } 134 135 rc = renderspuIatPatcherPatchEntry(pAdr, pfn, NULL); 136 if (RT_FAILURE(rc)) 137 { 138 crWarning("renderspuIatPatcherPatchEntry failed, %d", rc); 139 return rc; 140 } 141 142 return VINF_SUCCESS; 143 } 144 145 /* patch */ 146 static HWND __stdcall renderspuAtiQuirk_GetForegroundWindow() 147 { 148 crDebug("renderspuAtiQuirk_GetForegroundWindow"); 149 return NULL; 150 } 151 152 153 #define CRREG_MAXKEYNAME 8 154 static int renderspuAtiQuirk_GetICDDriverList(char *pBuf, DWORD cbBuf, DWORD *pcbResult) 155 { 156 static LPCSTR aValueNames[] = {"OpenGLVendorName", "OpenGLDriverName"}; 157 char *pBufPos = pBuf; 158 DWORD cbBufRemain = cbBuf, cbTotal = 0; 159 HKEY hKey; 160 DWORD dwIndex = 0; 161 int i; 162 int rc = VINF_SUCCESS; 163 char NameBuf[CRREG_MAXKEYNAME]; 164 LONG lRc; 165 166 if (pcbResult) 167 *pcbResult = 0; 168 169 lRc = RegOpenKeyEx(HKEY_LOCAL_MACHINE, 170 "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E968-E325-11CE-BFC1-08002BE10318}", 171 0, /* reserved*/ 172 KEY_READ, 173 &hKey); 174 if (ERROR_SUCCESS != lRc) 175 { 176 crDebug("RegOpenKeyEx 1 failed, %d", lRc); 177 return VERR_OPEN_FAILED; 178 } 179 180 for ( ; ; ++dwIndex) 181 { 182 lRc = RegEnumKeyA(hKey, dwIndex, NameBuf, CRREG_MAXKEYNAME); 183 if (lRc == ERROR_NO_MORE_ITEMS) 184 break; 185 if (lRc == ERROR_MORE_DATA) 186 continue; 187 if (lRc != ERROR_SUCCESS) 188 { 189 crWarning("RegEnumKeyA failed, %d", lRc); 190 continue; 191 } 192 193 for (i = 0; i < RT_ELEMENTS(aValueNames); ++i) 194 { 195 DWORD cbCur = cbBufRemain; 196 lRc = RegGetValueA(hKey, NameBuf, aValueNames[i], RRF_RT_REG_MULTI_SZ, 197 NULL, /* LPDWORD pdwType */ 198 pBufPos, 199 &cbCur); 200 /* exclude second null termination */ 201 --cbCur; 202 if (ERROR_MORE_DATA == lRc) 203 { 204 rc = VERR_BUFFER_OVERFLOW; 205 pBufPos = NULL; 206 cbBufRemain = 0; 207 CRASSERT(cbCur > 0 && cbCur < UINT32_MAX/2); 208 cbTotal += cbCur; 209 continue; 210 } 211 if (ERROR_SUCCESS != lRc) 212 { 213 crWarning("RegGetValueA failed, %d", lRc); 214 continue; 215 } 216 217 /* succeeded */ 218 CRASSERT(cbCur > 0 && cbCur < UINT32_MAX/2); 219 pBufPos += cbCur; 220 cbBufRemain -= cbCur; 221 cbTotal += cbCur; 222 CRASSERT(cbBufRemain < UINT32_MAX/2); 223 } 224 } 225 226 if (cbTotal) 227 { 228 /* include second null termination */ 229 CRASSERT(!pBufPos || pBufPos[0] == '\0'); 230 ++cbTotal; 231 } 232 233 if (pcbResult) 234 *pcbResult = cbTotal; 235 236 return rc; 237 } 238 239 static int renderspuAtiQuirk_ApplyForModule(LPCSTR pszAtiDll) 240 { 241 int rc; 242 HMODULE hAtiDll; 243 244 crDebug("renderspuAtiQuirk_ApplyForModule (%s)", pszAtiDll); 245 246 hAtiDll = GetModuleHandleA(pszAtiDll); 247 if (!hAtiDll) 248 { 249 crDebug("GetModuleHandle failed, %d", GetLastError()); 250 return VERR_NOT_FOUND; 251 } 252 253 rc = renderspuIatPatcherPatchFunction(hAtiDll, "user32.dll", "GetForegroundWindow", (void*)renderspuAtiQuirk_GetForegroundWindow); 254 if (RT_FAILURE(rc)) 255 { 256 crDebug("renderspuIatPatcherPatchFunction failed, %d", rc); 257 return rc; 258 } 259 260 crDebug("renderspuAtiQuirk_ApplyForModule SUCCEEDED!"); 261 crInfo("ATI Fullscreen qwirk for SUCCEEDED!"); 262 263 return VINF_SUCCESS; 264 } 265 266 static LPCSTR renderspuRegMultiSzNextVal(LPCSTR pszBuf) 267 { 268 pszBuf += strlen(pszBuf) + sizeof (pszBuf[0]); 269 270 if (pszBuf[0] == '\0') 271 return NULL; 272 273 return pszBuf; 274 } 275 276 static LPCSTR renderspuRegMultiSzCurVal(LPCSTR pszBuf) 277 { 278 if (pszBuf[0] == '\0') 279 return NULL; 280 281 return pszBuf; 282 } 283 284 285 static int renderspuAtiQuirk_Apply() 286 { 287 char aBuf[4096]; 288 DWORD cbResult = 0; 289 LPCSTR pszVal; 290 int rc; 291 292 crDebug("renderspuAtiQuirk_Apply.."); 293 294 rc = renderspuAtiQuirk_GetICDDriverList(aBuf, sizeof (aBuf), &cbResult); 295 if (RT_FAILURE(rc)) 296 { 297 crDebug("renderspuAtiQuirk_GetICDDriverList failed, rc(%d)", rc); 298 return rc; 299 } 300 301 for (pszVal = renderspuRegMultiSzCurVal(aBuf); 302 pszVal; 303 pszVal = renderspuRegMultiSzNextVal(pszVal)) 304 { 305 renderspuAtiQuirk_ApplyForModule(pszVal); 306 } 307 308 return VINF_SUCCESS; 309 } 310 311 static GLboolean renderspuAtiQuirk_Needed() 312 { 313 const char * pszString = render_spu.ws.glGetString(GL_VENDOR); 314 if (pszString && strstr(pszString, "ATI")) 315 return GL_TRUE; 316 pszString = render_spu.ws.glGetString(GL_RENDERER); 317 if (pszString && strstr(pszString, "ATI")) 318 return GL_TRUE; 319 return GL_FALSE; 320 } 321 322 323 static void renderspuAtiQuirk_ChkApply() 324 { 325 static GLboolean fChecked = GL_FALSE; 326 if (fChecked) 327 return; 328 329 fChecked = GL_TRUE; 330 if (!renderspuAtiQuirk_Needed()) 331 return; 332 333 crInfo("This is an ATI card, taking care of fullscreen.."); 334 335 renderspuAtiQuirk_Apply(); 336 } 20 337 21 338 #define WINDOW_NAME window->title … … 903 1220 } 904 1221 1222 renderspuAtiQuirk_ChkApply(); 905 1223 } 906 1224 else {
Note:
See TracChangeset
for help on using the changeset viewer.