xref: /reactos/dll/directx/ddraw/main.c (revision c2c66aff)
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
TranslateCallbackA(GUID * lpGUID,LPSTR lpDriverDescription,LPSTR lpDriverName,LPVOID lpContext,HMONITOR hm)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 *--*/
DirectDrawCreateClipper(DWORD dwFlags,LPDIRECTDRAWCLIPPER * lplpDDClipper,LPUNKNOWN pUnkOuter)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
DirectDrawCreate(LPGUID lpGUID,LPDIRECTDRAW * lplpDD,LPUNKNOWN pUnkOuter)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
DirectDrawCreateEx(LPGUID lpGUID,LPVOID * lplpDD,REFIID id,LPUNKNOWN pUnkOuter)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
DirectDrawEnumerateA(LPDDENUMCALLBACKA lpCallback,LPVOID lpContext)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
DirectDrawEnumerateExA(LPDDENUMCALLBACKEXA lpCallback,LPVOID lpContext,DWORD dwFlags)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
DirectDrawEnumerateW(LPDDENUMCALLBACKW lpCallback,LPVOID lpContext)267 DirectDrawEnumerateW(LPDDENUMCALLBACKW lpCallback,
268                                     LPVOID lpContext)
269 {
270     DX_WINDBG_trace();
271 
272     return DDERR_UNSUPPORTED;
273 }
274 
275 HRESULT
276 WINAPI
DirectDrawEnumerateExW(LPDDENUMCALLBACKEXW lpCallback,LPVOID lpContext,DWORD dwFlags)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
D3DParseUnknownCommand(LPVOID lpCmd,LPVOID * lpRetCmd)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
AcquireDDThreadLock()412 AcquireDDThreadLock()
413 {
414     DX_WINDBG_trace();
415 
416     EnterCriticalSection(&ddcs);
417 }
418 
419 VOID
420 WINAPI
ReleaseDDThreadLock()421 ReleaseDDThreadLock()
422 {
423     DX_WINDBG_trace();
424 
425     LeaveCriticalSection(&ddcs);
426 }
427 
428 
429 BOOL APIENTRY
DllMain(HMODULE hModule,DWORD ul_reason_for_call,LPVOID lpReserved)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