ReactOS  0.4.15-dev-3207-ga415bd4
classinst.c
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: See COPYING in the top level directory
3  * PROJECT: ReactOS Display Control Panel
4  * FILE: dll/cpl/desk/classinst.c
5  * PURPOSE: Class installers
6  *
7  * PROGRAMMERS: Hervé Poussineau (hpoussin@reactos.org)
8  */
9 
10 #include "desk.h"
11 
12 //#define NDEBUG
13 #include <debug.h>
14 
17  IN DI_FUNCTION InstallFunction,
20 {
21  SP_DEVINSTALL_PARAMS InstallParams;
22  SP_DRVINFO_DATA DriverInfoData;
24  TCHAR SectionName[MAX_PATH];
26  TCHAR DeviceName[12];
27  SP_DRVINFO_DETAIL_DATA DriverInfoDetailData;
28  DISPLAY_DEVICE DisplayDevice;
29  HKEY hDriverKey = INVALID_HANDLE_VALUE; /* SetupDiOpenDevRegKey returns INVALID_HANDLE_VALUE in case of error! */
30  HKEY hSettingsKey = NULL;
32  HKEY hServiceKey = NULL;
33  HKEY hDeviceSubKey = NULL;
34  DWORD disposition, cchMax, cbData;
35  WORD wIndex;
36  BOOL result;
37  LONG rc;
38  HRESULT hr;
39 
40  if (InstallFunction != DIF_INSTALLDEVICE)
41  return ERROR_DI_DO_DEFAULT;
42 
43  /* Set DI_DONOTCALLCONFIGMG flag */
44  InstallParams.cbSize = sizeof(InstallParams);
46  if (!result)
47  {
48  rc = GetLastError();
49  DPRINT("SetupDiGetDeviceInstallParams() failed with error 0x%lx\n", rc);
50  goto cleanup;
51  }
52 
53  InstallParams.Flags |= DI_DONOTCALLCONFIGMG;
54 
56  if (!result)
57  {
58  rc = GetLastError();
59  DPRINT("SetupDiSetDeviceInstallParams() failed with error 0x%lx\n", rc);
60  goto cleanup;
61  }
62 
63  /* Do normal install */
65  if (!result)
66  {
67  rc = GetLastError();
68  DPRINT("SetupDiInstallDevice() failed with error 0x%lx\n", rc);
69  goto cleanup;
70  }
71 
72  /* Get .inf file name and section name */
73  DriverInfoData.cbSize = sizeof(DriverInfoData);
75  if (!result)
76  {
77  rc = GetLastError();
78  DPRINT("SetupDiGetSelectedDriver() failed with error 0x%lx\n", rc);
79  goto cleanup;
80  }
81 
82  DriverInfoDetailData.cbSize = sizeof(DriverInfoDetailData);
84  &DriverInfoData, &DriverInfoDetailData,
85  sizeof(DriverInfoDetailData), NULL);
87  {
88  rc = GetLastError();
89  DPRINT("SetupDiGetDriverInfoDetail() failed with error 0x%lx\n", rc);
90  goto cleanup;
91  }
92 
93  hInf = SetupOpenInfFile(DriverInfoDetailData.InfFileName, NULL, INF_STYLE_WIN4, NULL);
94  if (hInf == INVALID_HANDLE_VALUE)
95  {
96  rc = GetLastError();
97  DPRINT("SetupOpenInfFile() failed with error 0x%lx\n", rc);
98  goto cleanup;
99  }
100 
101  cchMax = MAX_PATH - (sizeof(_T(".SoftwareSettings")) / sizeof(TCHAR));
103  DriverInfoDetailData.SectionName,
104  SectionName,
105  cchMax,
106  NULL,
107  NULL);
108  if (!result)
109  {
110  rc = GetLastError();
111  DPRINT("SetupDiGetActualSectionToInstall() failed with error 0x%lx\n", rc);
112  goto cleanup;
113  }
114  hr = StringCbCat(SectionName, sizeof(SectionName), _T(".SoftwareSettings"));
115  if (FAILED(hr))
116  {
118  goto cleanup;
119  }
120 
121  /* Open driver registry key and create Settings subkey */
122  hDriverKey = SetupDiOpenDevRegKey(
126  if (hDriverKey == INVALID_HANDLE_VALUE)
127  {
128  rc = GetLastError();
129  DPRINT("SetupDiOpenDevRegKey() failed with error 0x%lx\n", rc);
130  goto cleanup;
131  }
132  rc = RegCreateKeyEx(
133  hDriverKey, L"Settings",
135 #if _WIN32_WINNT >= 0x502
137 #else
139 #endif
140  NULL, &hSettingsKey, &disposition);
141  if (rc != ERROR_SUCCESS)
142  {
143  DPRINT("RegCreateKeyEx() failed with error 0x%lx\n", rc);
144  goto cleanup;
145  }
146 
147  /* Install .SoftwareSettings to Settings subkey */
149  InstallParams.hwndParent, hInf, SectionName,
150  SPINST_REGISTRY, hSettingsKey,
151  NULL, 0, NULL, NULL,
152  NULL, NULL);
153  if (!result)
154  {
155  rc = GetLastError();
156  DPRINT("SetupInstallFromInfSection() failed with error 0x%lx\n", rc);
157  goto cleanup;
158  }
159 
160  /* Get service name and open service registry key */
165  if (!result)
166  {
167  rc = GetLastError();
168  DPRINT("SetupDiGetDeviceRegistryProperty() failed with error 0x%lx\n", rc);
169  goto cleanup;
170  }
171 
172  rc = RegOpenKeyEx(
173  HKEY_LOCAL_MACHINE, _T("SYSTEM\\CurrentControlSet\\Services"),
175  if (rc != ERROR_SUCCESS)
176  {
177  DPRINT("RegOpenKeyEx() failed with error 0x%lx\n", rc);
178  goto cleanup;
179  }
180  rc = RegOpenKeyEx(
182  0, KEY_CREATE_SUB_KEY, &hServiceKey);
183  if (rc != ERROR_SUCCESS)
184  {
185  DPRINT("RegOpenKeyEx() failed with error 0x%lx\n", rc);
186  goto cleanup;
187  }
188 
189  /* Create a new DeviceX subkey */
190  for (wIndex = 0; wIndex < 9999; wIndex++)
191  {
192  _stprintf(DeviceName, _T("Device%hu"), wIndex);
193 
194  rc = RegCreateKeyEx(
195  hServiceKey, DeviceName, 0, NULL,
197  &hDeviceSubKey, &disposition);
198  if (rc != ERROR_SUCCESS)
199  {
200  DPRINT("RegCreateKeyEx() failed with error 0x%lx\n", rc);
201  goto cleanup;
202  }
203 
204  if (disposition == REG_CREATED_NEW_KEY)
205  break;
206 
207  if (wIndex == 9999)
208  {
209  rc = ERROR_GEN_FAILURE;
210  DPRINT("RegCreateKeyEx() failed\n");
211  goto cleanup;
212  }
213 
214  RegCloseKey(hDeviceSubKey);
215  hDeviceSubKey = NULL;
216  }
217 
218  /* Install SoftwareSettings section */
219  /* Yes, we're installing this section for the second time.
220  * We don't want to create a link to Settings subkey */
222  InstallParams.hwndParent, hInf, SectionName,
223  SPINST_REGISTRY, hDeviceSubKey,
224  NULL, 0, NULL, NULL,
225  NULL, NULL);
226  if (!result)
227  {
228  rc = GetLastError();
229  DPRINT("SetupInstallFromInfSection() failed with error 0x%lx\n", rc);
230  goto cleanup;
231  }
232 
233  /* Add Device Description string */
234  cbData = (DWORD)(_tcslen(DriverInfoData.Description) + 1) * sizeof(TCHAR);
235  rc = RegSetValueEx(hDeviceSubKey,
236  _T("Device Description"),
237  0,
238  REG_SZ,
239  (const BYTE*)DriverInfoData.Description,
240  cbData);
241  if (rc != ERROR_SUCCESS)
242  {
243  DPRINT("RegSetValueEx() failed with error 0x%lx\n", rc);
244  goto cleanup;
245  }
246 
247  /* FIXME: install OpenGLSoftwareSettings section */
248 
249  /* Start the device */
251  {
252  /* Reenumerate display devices ; this will rescan for potential new devices */
253  DisplayDevice.cb = sizeof(DISPLAY_DEVICE);
254  EnumDisplayDevices(NULL, 0, &DisplayDevice, 0);
255  }
256  else
257  {
258  rc = GetLastError();
259  DPRINT("SetupDiRestartDevices() failed with error 0x%lx. Will reboot later.\n", rc);
260 
261  /* Mark device as needing a restart */
262  InstallParams.cbSize = sizeof(InstallParams);
264  {
265  rc = GetLastError();
266  DPRINT("SetupDiGetDeviceInstallParams() failed with error 0x%lx\n", rc);
267  goto cleanup;
268  }
269  InstallParams.Flags |= DI_NEEDRESTART;
271  if (!result)
272  {
273  rc = GetLastError();
274  DPRINT("SetupDiSetDeviceInstallParams() failed with error 0x%lx\n", rc);
275  goto cleanup;
276  }
277  }
278 
279  rc = ERROR_SUCCESS;
280 
281 cleanup:
282  if (hInf != INVALID_HANDLE_VALUE)
283  SetupCloseInfFile(hInf);
284  if (hDriverKey != INVALID_HANDLE_VALUE)
285  {
286  /* SetupDiOpenDevRegKey returns INVALID_HANDLE_VALUE in case of error! */
287  RegCloseKey(hDriverKey);
288  }
289  if (hSettingsKey != NULL)
290  RegCloseKey(hSettingsKey);
291  if (hServicesKey != NULL)
293  if (hServiceKey != NULL)
294  RegCloseKey(hServiceKey);
295  if (hDeviceSubKey != NULL)
296  RegCloseKey(hDeviceSubKey);
297 
298  return rc;
299 }
300 
303  IN DI_FUNCTION InstallFunction,
306 {
307  return ERROR_DI_DO_DEFAULT;
308 }
#define _WIN32_WINNT
Definition: precomp.h:14
#define IN
Definition: typedefs.h:39
#define INF_STYLE_WIN4
Definition: infsupp.h:41
#define SetupInstallFromInfSection
Definition: setupapi.h:2645
#define ERROR_SUCCESS
Definition: deptool.c:10
HRESULT hr
Definition: shlfolder.c:183
#define KEY_SET_VALUE
Definition: nt_native.h:1017
GLuint64EXT * result
Definition: glext.h:11304
#define KEY_READ
Definition: nt_native.h:1023
#define SetupDiGetDeviceInstallParams
Definition: setupapi.h:2599
#define INVALID_HANDLE_VALUE
Definition: compat.h:590
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1040
#define SetupDiGetDeviceRegistryProperty
Definition: setupapi.h:2603
DWORD WINAPI MonitorClassInstaller(IN DI_FUNCTION InstallFunction, IN HDEVINFO DeviceInfoSet, IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL)
Definition: classinst.c:302
#define SetupDiGetSelectedDriver
Definition: setupapi.h:2610
#define DWORD
Definition: nt_native.h:44
VOID WINAPI SetupCloseInfFile(IN HINF InfHandle)
Definition: infsupp.c:43
CHAR SectionName[LINE_LEN]
Definition: setupapi.h:1065
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_opt_ PCUNICODE_STRING DeviceName
Definition: wdfdevice.h:3272
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
BOOL WINAPI SetupDiRestartDevices(HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData)
Definition: devinst.c:6110
#define SetupDiGetActualSectionToInstall
Definition: setupapi.h:2588
#define DI_DONOTCALLCONFIGMG
Definition: setupapi.h:63
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
BOOL WINAPI SetupDiInstallDevice(IN HDEVINFO DeviceInfoSet, IN OUT PSP_DEVINFO_DATA DeviceInfoData)
Definition: devinst.c:5361
size_t __cdecl _tcslen(const _TCHAR *str)
Definition: tcslen.h:9
#define SPINST_REGISTRY
Definition: setupapi.h:590
#define REG_CREATED_NEW_KEY
Definition: nt_native.h:1084
#define DIF_INSTALLDEVICE
Definition: setupapi.h:121
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1057
#define KEY_WRITE
Definition: nt_native.h:1031
static HANDLE hServicesKey
Definition: devinst.c:21
char TCHAR
Definition: xmlstorage.h:189
#define _T(x)
Definition: vfdio.h:22
#define StringCbCat
Definition: strsafe.h:334
LPTSTR ServiceName
Definition: ServiceMain.c:15
LONG HRESULT
Definition: typedefs.h:79
#define SetupDiSetDeviceInstallParams
Definition: setupapi.h:2619
#define MAX_PATH
Definition: compat.h:34
#define WINAPI
Definition: msvc.h:6
_In_opt_ PSP_DEVINFO_DATA DeviceInfoData
Definition: setupapi.h:1528
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned long DWORD
Definition: ntddk_ex.h:95
UINT cchMax
static const WCHAR L[]
Definition: oid.c:1250
DISPLAY_DEVICEA DISPLAY_DEVICE
Definition: wingdi.h:4433
#define SPDRP_SERVICE
Definition: setupapi.h:511
HKEY WINAPI SetupDiOpenDevRegKey(HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, DWORD Scope, DWORD HwProfile, DWORD KeyType, REGSAM samDesired)
Definition: devinst.c:5930
unsigned char BYTE
Definition: xxhash.c:193
#define SetupDiGetDriverInfoDetail
Definition: setupapi.h:2604
#define _stprintf
Definition: utility.h:124
#define RegOpenKeyEx
Definition: winreg.h:520
#define DICS_FLAG_GLOBAL
Definition: setupapi.h:113
CHAR Description[LINE_LEN]
Definition: setupapi.h:1006
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
#define NULL
Definition: types.h:112
#define ERROR_DI_DO_DEFAULT
Definition: setupapi.h:310
#define DIREG_DRV
Definition: setupapi.h:182
char * cleanup(char *str)
Definition: wpickclick.c:99
#define DI_NEEDRESTART
Definition: setupapi.h:53
#define ERROR_GEN_FAILURE
Definition: winerror.h:134
DWORD WINAPI DisplayClassInstaller(IN DI_FUNCTION InstallFunction, IN HDEVINFO DeviceInfoSet, IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL)
Definition: classinst.c:16
UINT DI_FUNCTION
Definition: setupapi.h:672
#define DPRINT
Definition: sndvol32.h:71
CHAR InfFileName[MAX_PATH]
Definition: setupapi.h:1066
#define KEY_CREATE_SUB_KEY
Definition: nt_native.h:1018
BYTE * PBYTE
Definition: pedump.c:66
#define RegSetValueEx
Definition: winreg.h:533
#define RegCreateKeyEx
Definition: winreg.h:501
#define SetupOpenInfFile
Definition: setupapi.h:2652
#define MAX_SERVICE_NAME_LEN
Definition: setupapi.h:25
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define KEY_ENUMERATE_SUB_KEYS
Definition: nt_native.h:1019
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
#define REG_SZ
Definition: layer.c:22
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68