1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS kernel 4 * FILE: dll/directx/ddraw/main.c 5 * PURPOSE: DirectDraw Library 6 * PROGRAMMER: Magnus Olsen (greatlrd) 7 * 8 */ 9 10 11 #include "rosdraw.h" 12 HMODULE hDllModule = 0; 13 14 CRITICAL_SECTION ddcs; 15 16 // This function is exported by the dll 17 18 typedef struct 19 { 20 LPVOID lpCallback; 21 LPVOID lpContext; 22 } DirectDrawEnumerateProcData; 23 24 BOOL 25 CALLBACK 26 TranslateCallbackA(GUID *lpGUID, 27 LPSTR lpDriverDescription, 28 LPSTR lpDriverName, 29 LPVOID lpContext, 30 HMONITOR hm) 31 { 32 DirectDrawEnumerateProcData *pEPD = (DirectDrawEnumerateProcData*)lpContext; 33 return ((LPDDENUMCALLBACKA) pEPD->lpCallback)(lpGUID, lpDriverDescription, lpDriverName, pEPD->lpContext); 34 } 35 36 /*++ 37 * @name DirectDrawCreateClipper 38 * 39 * The DirectDrawCreateClipper routine <FILLMEIN>. 40 * 41 * @param dwFlags 42 * <FILLMEIN>. 43 * 44 * @param lplpDDClipper 45 * <FILLMEIN>. 46 * 47 * @param pUnkOuter 48 * <FILLMEIN>. 49 * 50 * @return <FILLMEIN>. 51 * 52 * @remarks None. 53 * 54 *--*/ 55 HRESULT WINAPI DirectDrawCreateClipper (DWORD dwFlags, 56 LPDIRECTDRAWCLIPPER* lplpDDClipper, LPUNKNOWN pUnkOuter) 57 { 58 DX_WINDBG_trace(); 59 60 return Main_DirectDraw_CreateClipper(NULL, dwFlags, lplpDDClipper, pUnkOuter); 61 } 62 63 /*++ 64 * @name DirectDrawCreate 65 * 66 * The DirectDrawCreate routine <FILLMEIN>. 67 * 68 * @param lpGUID 69 * <FILLMEIN>. 70 * 71 * @param lplpDD 72 * <FILLMEIN>. 73 * 74 * @param pUnkOuter 75 * Always set to NULL otherwise DirectDrawCreate will fail and return 76 * error code CLASS_E_NOAGGREGATION 77 * 78 * @return <FILLMEIN>. 79 * 80 * @remarks None. 81 * 82 *--*/ 83 84 HRESULT 85 WINAPI 86 DirectDrawCreate (LPGUID lpGUID, 87 LPDIRECTDRAW* lplpDD, 88 LPUNKNOWN pUnkOuter) 89 { 90 HRESULT retVal = DDERR_GENERIC; 91 /* 92 remove this when UML diagram is in place 93 this api is finished and is working as it should 94 */ 95 96 DX_WINDBG_trace(); 97 _SEH2_TRY 98 { 99 /* check if pUnkOuter is null or not */ 100 if (pUnkOuter) 101 { 102 retVal = CLASS_E_NOAGGREGATION; 103 } 104 else 105 { 106 retVal = Create_DirectDraw (lpGUID, (LPDIRECTDRAW*)lplpDD, &IID_IDirectDraw, FALSE); 107 } 108 } 109 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 110 { 111 } 112 _SEH2_END; 113 114 return retVal; 115 } 116 117 /*++ 118 * @name DirectDrawCreateEx 119 * 120 * The DirectDrawCreateEx routine <FILLMEIN>. 121 * 122 * @param lpGUID 123 * <FILLMEIN>. 124 * 125 * @param lplpDD 126 * <FILLMEIN>. 127 * 128 * @param pUnkOuter 129 * Always set to NULL otherwise DirectDrawCreateEx will fail and return 130 * error code CLASS_E_NOAGGREGATION 131 * 132 * @return <FILLMEIN>. 133 * 134 * @remarks None. 135 * 136 *--*/ 137 HRESULT 138 WINAPI 139 DirectDrawCreateEx(LPGUID lpGUID, 140 LPVOID* lplpDD, 141 REFIID id, 142 LPUNKNOWN pUnkOuter) 143 { 144 HRESULT retVal = DDERR_GENERIC; 145 /* 146 remove this when UML diagram is in place 147 this api is finished and is working as it should 148 */ 149 DX_WINDBG_trace(); 150 151 _SEH2_TRY 152 { 153 /* check see if pUnkOuter is null or not */ 154 if (pUnkOuter) 155 { 156 /* we are using same error code as MS*/ 157 retVal = CLASS_E_NOAGGREGATION; 158 }/* Is it a DirectDraw 7 Request or not */ 159 else if (!IsEqualGUID(id, &IID_IDirectDraw7)) 160 { 161 retVal = DDERR_INVALIDPARAMS; 162 } 163 else 164 { 165 retVal = Create_DirectDraw (lpGUID, (LPDIRECTDRAW*)lplpDD, id, FALSE); 166 } 167 168 /* Create our DirectDraw interface */ 169 } 170 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 171 { 172 } 173 _SEH2_END; 174 175 return retVal; 176 } 177 178 HRESULT 179 WINAPI 180 DirectDrawEnumerateA( LPDDENUMCALLBACKA lpCallback, 181 LPVOID lpContext) 182 { 183 HRESULT retValue; 184 DirectDrawEnumerateProcData epd; 185 186 DX_WINDBG_trace(); 187 188 epd.lpCallback = (LPVOID) lpCallback; 189 epd.lpContext = lpContext; 190 191 if (!IsBadCodePtr((LPVOID)lpCallback)) 192 { 193 return DirectDrawEnumerateExA((LPDDENUMCALLBACKEXA)TranslateCallbackA, &epd, DDENUM_NONDISPLAYDEVICES); 194 } 195 else 196 { 197 retValue = DDERR_INVALIDPARAMS; 198 } 199 return retValue; 200 } 201 202 /* 203 * UNIMPLEMENT 204 */ 205 206 HRESULT 207 WINAPI 208 DirectDrawEnumerateExA(LPDDENUMCALLBACKEXA lpCallback, 209 LPVOID lpContext, 210 DWORD dwFlags) 211 { 212 HKEY hKey; 213 DWORD cbData = 0; 214 DWORD Value = 0; 215 LONG rc; 216 BOOL EnumerateAttachedSecondaries = FALSE; 217 DWORD privateDWFlags = 0; 218 CHAR strMsg[RC_STRING_MAX_SIZE]; 219 HRESULT retVal = DDERR_INVALIDPARAMS; 220 221 DX_WINDBG_trace(); 222 223 if ((IsBadCodePtr((LPVOID)lpCallback) == 0) && 224 ((dwFlags & ~(DDENUM_NONDISPLAYDEVICES | 225 DDENUM_DETACHEDSECONDARYDEVICES | 226 DDENUM_ATTACHEDSECONDARYDEVICES)) == 0)) 227 { 228 LoadStringA(hDllModule, STR_PRIMARY_DISPLAY, (LPSTR)&strMsg, RC_STRING_MAX_SIZE); 229 230 rc = RegOpenKeyA(HKEY_LOCAL_MACHINE, REGSTR_PATH_DDHW, &hKey); 231 if (rc == ERROR_SUCCESS) 232 { 233 /* Enumerate Attached Secondaries */ 234 cbData = sizeof(DWORD); 235 rc = RegQueryValueExA(hKey, "EnumerateAttachedSecondaries", NULL, NULL, (LPBYTE)&Value, &cbData); 236 if (rc == ERROR_SUCCESS) 237 { 238 if (Value != 0) 239 { 240 EnumerateAttachedSecondaries = TRUE; 241 privateDWFlags = DDENUM_ATTACHEDSECONDARYDEVICES; 242 } 243 } 244 RegCloseKey(hKey); 245 } 246 247 /* Call the user supplied callback function */ 248 rc = lpCallback(NULL, strMsg, "display", lpContext, NULL); 249 250 /* If the callback function returns DDENUMRET_CANCEL, we will stop enumerating devices */ 251 if(rc == DDENUMRET_CANCEL) 252 { 253 retVal = DD_OK; 254 } 255 else 256 { 257 // not finished 258 retVal = DDERR_UNSUPPORTED; 259 } 260 } 261 262 return retVal; 263 } 264 265 HRESULT 266 WINAPI 267 DirectDrawEnumerateW(LPDDENUMCALLBACKW lpCallback, 268 LPVOID lpContext) 269 { 270 DX_WINDBG_trace(); 271 272 return DDERR_UNSUPPORTED; 273 } 274 275 HRESULT 276 WINAPI 277 DirectDrawEnumerateExW(LPDDENUMCALLBACKEXW lpCallback, 278 LPVOID lpContext, 279 DWORD dwFlags) 280 { 281 DX_WINDBG_trace(); 282 283 return DDERR_UNSUPPORTED; 284 } 285 286 287 288 289 /* 290 See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/ 291 Display_d/hh/Display_d/d3d_21ac30ea-9803-401e-b541-6b08af79653d.xml.asp 292 293 for more info about this command see msdn documentation 294 295 The buffer start with D3DHAL_DP2COMMAND struct afer that follows either one struct or 296 no struct at at all 297 example for command D3DDP2OP_VIEWPORTINFO 298 299 then lpCmd will look like this 300 ---------------------------------------- 301 | struct | Pos | 302 ---------------------------------------- 303 | D3DHAL_DP2COMMAND | 0x00 - 0x03 | 304 --------------------------------------- 305 | D3DHAL_DP2VIEWPORTINFO | 0x04 - xxxx | 306 --------------------------------------- 307 308 to calculate the end of the lpCmd buffer in this example 309 D3DHAL_DP2COMMAND->wStateCount * sizeof(D3DHAL_DP2VIEWPORTINFO); 310 now you got number of bytes but we need to add the size of D3DHAL_DP2COMMAND 311 to get this right. the end should be 312 sizeof(D3DHAL_DP2COMMAND) + ( D3DHAL_DP2COMMAND->wStateCount * sizeof(D3DHAL_DP2VIEWPORTINFO)); 313 to get the xxxx end positions. 314 */ 315 316 /*++ 317 * @name D3DParseUnknownCommand 318 * 319 * The D3DParseUnknownCommand routine <FILLMEIN>. 320 * 321 * @param lpCmd 322 * Is a typecast to LPD3DHAL_DP2COMMAND struct 323 * typedef struct _D3DHAL_DP2COMMAND 324 * { 325 * BYTE bCommand; 326 * BYTE bReserved; 327 * union 328 * { 329 * WORD wPrimitiveCount; 330 * WORD wStateCount; 331 * }; 332 * } D3DHAL_DP2COMMAND, *LPD3DHAL_DP2COMMAND; 333 * 334 * lpCmd->bCommand 335 * only accept D3DDP2OP_VIEWPORTINFO, and undocumented command 0x0D 336 * anything else will result in an error 337 * 338 Command 0x0D 339 * dp2command->bReserved 340 * is the size of the struct we got in wStateCount or how many wStateCount we got 341 * do not known more about it, no info in msdn about it either. 342 * 343 * Command D3DDP2OP_VIEWPORTINFO 344 * <FILLMEIN>. 345 * 346 * @param lpRetCmd 347 * <FILLMEIN>. 348 * 349 * @return <FILLMEIN>. 350 * 351 * @remarks 352 353 * 354 *--*/ 355 356 HRESULT WINAPI 357 D3DParseUnknownCommand( LPVOID lpCmd, 358 LPVOID *lpRetCmd) 359 { 360 DWORD retCode = DD_OK; 361 LPD3DHAL_DP2COMMAND dp2command = lpCmd; 362 363 DX_WINDBG_trace(); 364 365 /* prevent it crash if null pointer are being sent */ 366 if ( (lpCmd == NULL) || (lpRetCmd == NULL) ) 367 { 368 return E_FAIL; 369 } 370 371 *lpRetCmd = lpCmd; 372 373 switch (dp2command->bCommand) 374 { 375 /* check for valid command, only 3 commands are valid */ 376 case D3DDP2OP_VIEWPORTINFO: 377 *(PBYTE)lpRetCmd += ((dp2command->wStateCount * sizeof(D3DHAL_DP2VIEWPORTINFO)) + sizeof(D3DHAL_DP2COMMAND)); 378 break; 379 380 case D3DDP2OP_WINFO: 381 *(PBYTE)lpRetCmd += (dp2command->wStateCount * sizeof(D3DHAL_DP2WINFO)) + sizeof(D3DHAL_DP2COMMAND); 382 break; 383 384 case 0x0d: /* Undocumented in MSDN */ 385 *(PBYTE)lpRetCmd += ((dp2command->wStateCount * dp2command->bReserved) + sizeof(D3DHAL_DP2COMMAND)); 386 break; 387 388 389 /* set the error code */ 390 default: 391 392 if ( (dp2command->bCommand <= D3DDP2OP_INDEXEDTRIANGLELIST) || // dp2command->bCommand <= with 0 to 3 393 (dp2command->bCommand == D3DDP2OP_RENDERSTATE) || // dp2command->bCommand == with 8 394 (dp2command->bCommand >= D3DDP2OP_LINELIST) ) // dp2command->bCommand >= with 15 to 255 395 { 396 /* set error code for command 0 to 3, 8 and 15 to 255 */ 397 retCode = DDERR_INVALIDPARAMS; 398 } 399 else 400 { /* set error code for 4 - 7, 9 - 12, 14 */ 401 retCode = D3DERR_COMMAND_UNPARSED; 402 } 403 404 } 405 406 return retCode; 407 } 408 409 410 VOID 411 WINAPI 412 AcquireDDThreadLock() 413 { 414 DX_WINDBG_trace(); 415 416 EnterCriticalSection(&ddcs); 417 } 418 419 VOID 420 WINAPI 421 ReleaseDDThreadLock() 422 { 423 DX_WINDBG_trace(); 424 425 LeaveCriticalSection(&ddcs); 426 } 427 428 429 BOOL APIENTRY 430 DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) 431 { 432 433 hDllModule = hModule; 434 435 DX_WINDBG_trace(); 436 437 438 switch(ul_reason_for_call) 439 { 440 case DLL_PROCESS_DETACH: 441 DeleteCriticalSection( &ddcs ); 442 break; 443 444 case DLL_PROCESS_ATTACH: 445 DisableThreadLibraryCalls( hModule ); 446 InitializeCriticalSection( &ddcs ); 447 EnterCriticalSection( &ddcs ); 448 LeaveCriticalSection( &ddcs ); 449 break; 450 451 default: 452 break; 453 } 454 455 return TRUE; 456 } 457