1 /*
2  * COPYRIGHT:            See COPYING in the top level directory
3  * PROJECT:              ReactOS DirectX
4  * FILE:                 dll/directx/ddraw/Ddraw/GetDeviceIdentifier.c
5  * PURPOSE:              IDirectDraw7 Implementation
6  * PROGRAMMER:           Magnus Olsen
7  *
8  */
9 
10 /* TODO
11  * We need adding digital signature detections for the drivers
12  * and count out which level the signtature driver got, the value
13  * shall be save to pDDDI->dwWHQLLevel, But I do not known how todo
14  * this part yet, That is only missing feature in this functions
15  *
16  * Write a UML digram for this api
17  */
18 
19 #include "rosdraw.h"
20 
21 #include <string.h>
22 
23 /* For DirectDraw 4 - 6 */
24 HRESULT WINAPI
25 Main_DirectDraw_GetDeviceIdentifier(LPDDRAWI_DIRECTDRAW_INT This,
26                                     LPDDDEVICEIDENTIFIER pDDDI, DWORD dwFlags)
27 {
28     HRESULT retVal = DD_OK;
29     DDDEVICEIDENTIFIER2 pDDDI2;
30 
31     ZeroMemory(&pDDDI2,sizeof(DDDEVICEIDENTIFIER2));
32 
33     _SEH2_TRY
34     {
35         memcpy(&pDDDI2 , pDDDI, sizeof(DDDEVICEIDENTIFIER));
36 
37         retVal = Main_DirectDraw_GetDeviceIdentifier7(This, &pDDDI2, dwFlags);
38 
39         if (IsBadWritePtr(pDDDI, sizeof(DDDEVICEIDENTIFIER)))
40         {
41             retVal = DDERR_INVALIDPARAMS;
42         }
43         else
44         {
45             memcpy(pDDDI , &pDDDI2, sizeof(DDDEVICEIDENTIFIER) );
46         }
47     }
48     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
49     {
50         retVal = DD_FALSE;
51     }
52     _SEH2_END;
53 
54     return retVal;
55 }
56 
57 HRESULT WINAPI
58 Main_DirectDraw_GetDeviceIdentifier7(LPDDRAWI_DIRECTDRAW_INT This,
59                                      LPDDDEVICEIDENTIFIER2 pDDDI, DWORD dwFlags)
60 {
61     HRESULT retVal = DDERR_INVALIDPARAMS;
62 
63     BOOL found = FALSE;
64     DWORD iDevNum = 0;
65     DISPLAY_DEVICEA DisplayDeviceA;
66     HKEY hKey;
67     DWORD lpType = 0;
68     DWORD strSize = MAX_DDDEVICEID_STRING;
69     char *pdest;
70     char* pcCnvEnd;
71     long *lpdata;
72 
73     DX_WINDBG_trace();
74 
75     EnterCriticalSection( &ddcs );
76 
77     _SEH2_TRY
78     {
79         if ( (IsBadWritePtr( pDDDI, sizeof(DDDEVICEIDENTIFIER2) ) ) ||
80              (dwFlags & ~DDGDI_GETHOSTIDENTIFIER))
81         {
82             retVal = DDERR_INVALIDPARAMS;
83             _SEH2_LEAVE;
84         }
85 
86         /* now we can start getting the driver data */
87 
88         while (1)
89         {
90             ZeroMemory(&DisplayDeviceA,sizeof(DISPLAY_DEVICEA));
91 
92             DisplayDeviceA.cb = sizeof(DISPLAY_DEVICEA);
93 
94             if ( EnumDisplayDevicesA( NULL, iDevNum, &DisplayDeviceA, 0) == 0)
95             {
96                 retVal = DDERR_INVALIDPARAMS;
97                 break;
98             }
99 
100             if (_stricmp(DisplayDeviceA.DeviceName, This->lpLcl->lpGbl->cDriverName) != 0)
101             {
102                 /* if we got another device like hardware mpeg decoder or video card or another drv */
103                 found = TRUE;
104             }
105             else if (DisplayDeviceA.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE)
106             {
107                 /* double check if it primary driver we just found */
108                 if (!_stricmp( This->lpLcl->lpGbl->cDriverName, "DISPLAY"))
109                 {
110                     /* yeah we found it */
111                     found = TRUE;
112                 }
113             }
114 
115             if (found != FALSE)
116             {
117                 /* we found our driver now we start setup it */
118                 if (!_strnicmp(DisplayDeviceA.DeviceKey,"\\REGISTRY\\Machine\\",18))
119                 {
120                     if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, &DisplayDeviceA.DeviceKey[18], 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS )
121                     {
122 
123                         if (RegQueryValueExA(hKey, "InstalledDisplayDrivers",0, &lpType, (LPBYTE)pDDDI->szDriver, &strSize) != ERROR_SUCCESS)
124                         {
125                             ZeroMemory(pDDDI->szDriver,MAX_DDDEVICEID_STRING);
126                         }
127                         else
128                         {
129                             strcat(pDDDI->szDriver,".dll");
130                         }
131                         RegCloseKey(hKey);
132                     }
133 
134                     strcpy( pDDDI->szDescription, DisplayDeviceA.DeviceString);
135                     pDDDI->liDriverVersion.HighPart = 0;
136                     pDDDI->liDriverVersion.LowPart = 0;
137 
138                     pdest = strstr(DisplayDeviceA.DeviceID,"REV_");
139                     pDDDI->dwRevision =  strtol ( &pdest[4], &pcCnvEnd, 16);
140 
141                     pdest = strstr(DisplayDeviceA.DeviceID,"SUBSYS_");
142                     pDDDI->dwSubSysId =  strtol ( &pdest[7], &pcCnvEnd, 16);
143 
144                     pdest = strstr(DisplayDeviceA.DeviceID,"DEV_");
145                     pDDDI->dwDeviceId = strtol ( &pdest[4], &pcCnvEnd, 16);
146 
147                     pdest = strstr(DisplayDeviceA.DeviceID,"VEN_");
148                     pDDDI->dwVendorId =strtol ( &pdest[4], &pcCnvEnd, 16);
149 
150                     /* Count out the guidDeviceIdentifier */
151                     memcpy(&pDDDI->guidDeviceIdentifier, &CLSID_DirectDraw,sizeof(GUID));
152 
153                     pDDDI->guidDeviceIdentifier.Data1 ^= pDDDI->dwVendorId;
154 
155                     lpdata = (long *)&pDDDI->guidDeviceIdentifier.Data2;
156                     *lpdata ^= pDDDI->dwDeviceId;
157 
158                     lpdata = (long *)&pDDDI->guidDeviceIdentifier.Data4;
159                     *lpdata = (*lpdata ^ pDDDI->dwSubSysId) ^ pDDDI->liDriverVersion.LowPart;
160 
161                     lpdata = (long *)&pDDDI->guidDeviceIdentifier.Data4[4];
162                     *lpdata = (*lpdata ^ pDDDI->dwRevision) ^ pDDDI->liDriverVersion.HighPart;
163 
164                     /* FIXME pDDDI->dwWHQLLevel
165                      * we leave this with no informations, I do not known
166                      * if program care for it, I mark this api done, and
167                      * tested, no bugs was found in it
168                      */
169                     pDDDI->dwWHQLLevel = 0;
170                     retVal = DD_OK;
171                 }
172 
173                 break;
174             }
175 
176             iDevNum++;
177          }
178 
179     }
180     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
181     {
182         retVal = DD_FALSE;
183     }
184     _SEH2_END;
185 
186     LeaveCriticalSection( &ddcs );
187     return retVal;
188 }
189