[DESK] Add MonitorClassInstaller
[reactos.git] / dll / cpl / desk / classinst.c
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
15 DWORD WINAPI
16 DisplayClassInstaller(
17 IN DI_FUNCTION InstallFunction,
18 IN HDEVINFO DeviceInfoSet,
19 IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL)
20 {
21 SP_DEVINSTALL_PARAMS InstallParams;
22 SP_DRVINFO_DATA DriverInfoData;
23 HINF hInf = INVALID_HANDLE_VALUE;
24 TCHAR SectionName[MAX_PATH];
25 TCHAR ServiceName[MAX_SERVICE_NAME_LEN];
26 SP_DRVINFO_DETAIL_DATA DriverInfoDetailData;
27 HKEY hDriverKey = INVALID_HANDLE_VALUE; /* SetupDiOpenDevRegKey returns INVALID_HANDLE_VALUE in case of error! */
28 HKEY hSettingsKey = NULL;
29 HKEY hServicesKey = NULL;
30 HKEY hServiceKey = NULL;
31 HKEY hDeviceSubKey = NULL;
32 DWORD disposition, cchMax, cbData;
33 BOOL result;
34 LONG rc;
35 HRESULT hr;
36
37 if (InstallFunction != DIF_INSTALLDEVICE)
38 return ERROR_DI_DO_DEFAULT;
39
40 /* Set DI_DONOTCALLCONFIGMG flag */
41 InstallParams.cbSize = sizeof(InstallParams);
42 result = SetupDiGetDeviceInstallParams(DeviceInfoSet, DeviceInfoData, &InstallParams);
43 if (!result)
44 {
45 rc = GetLastError();
46 DPRINT("SetupDiGetDeviceInstallParams() failed with error 0x%lx\n", rc);
47 goto cleanup;
48 }
49
50 InstallParams.Flags |= DI_DONOTCALLCONFIGMG;
51
52 result = SetupDiSetDeviceInstallParams(DeviceInfoSet, DeviceInfoData, &InstallParams);
53 if (!result)
54 {
55 rc = GetLastError();
56 DPRINT("SetupDiSetDeviceInstallParams() failed with error 0x%lx\n", rc);
57 goto cleanup;
58 }
59
60 /* Do normal install */
61 result = SetupDiInstallDevice(DeviceInfoSet, DeviceInfoData);
62 if (!result)
63 {
64 rc = GetLastError();
65 DPRINT("SetupDiInstallDevice() failed with error 0x%lx\n", rc);
66 goto cleanup;
67 }
68
69 /* Get .inf file name and section name */
70 DriverInfoData.cbSize = sizeof(DriverInfoData);
71 result = SetupDiGetSelectedDriver(DeviceInfoSet, DeviceInfoData, &DriverInfoData);
72 if (!result)
73 {
74 rc = GetLastError();
75 DPRINT("SetupDiGetSelectedDriver() failed with error 0x%lx\n", rc);
76 goto cleanup;
77 }
78
79 DriverInfoDetailData.cbSize = sizeof(DriverInfoDetailData);
80 result = SetupDiGetDriverInfoDetail(DeviceInfoSet, DeviceInfoData,
81 &DriverInfoData, &DriverInfoDetailData,
82 sizeof(DriverInfoDetailData), NULL);
83 if (!result && GetLastError() != ERROR_INSUFFICIENT_BUFFER)
84 {
85 rc = GetLastError();
86 DPRINT("SetupDiGetDriverInfoDetail() failed with error 0x%lx\n", rc);
87 goto cleanup;
88 }
89
90 hInf = SetupOpenInfFile(DriverInfoDetailData.InfFileName, NULL, INF_STYLE_WIN4, NULL);
91 if (hInf == INVALID_HANDLE_VALUE)
92 {
93 rc = GetLastError();
94 DPRINT("SetupOpenInfFile() failed with error 0x%lx\n", rc);
95 goto cleanup;
96 }
97
98 cchMax = MAX_PATH - (sizeof(_T(".SoftwareSettings")) / sizeof(TCHAR));
99 result = SetupDiGetActualSectionToInstall(hInf,
100 DriverInfoDetailData.SectionName,
101 SectionName,
102 cchMax,
103 NULL,
104 NULL);
105 if (!result)
106 {
107 rc = GetLastError();
108 DPRINT("SetupDiGetActualSectionToInstall() failed with error 0x%lx\n", rc);
109 goto cleanup;
110 }
111 hr = StringCbCat(SectionName, sizeof(SectionName), _T(".SoftwareSettings"));
112 if (FAILED(hr))
113 {
114 rc = ERROR_INSUFFICIENT_BUFFER;
115 goto cleanup;
116 }
117
118 /* Open driver registry key and create Settings subkey */
119 hDriverKey = SetupDiOpenDevRegKey(
120 DeviceInfoSet, DeviceInfoData,
121 DICS_FLAG_GLOBAL, 0, DIREG_DRV,
122 KEY_CREATE_SUB_KEY);
123 if (hDriverKey == INVALID_HANDLE_VALUE)
124 {
125 rc = GetLastError();
126 DPRINT("SetupDiOpenDevRegKey() failed with error 0x%lx\n", rc);
127 goto cleanup;
128 }
129 rc = RegCreateKeyEx(
130 hDriverKey, L"Settings",
131 0, NULL, REG_OPTION_NON_VOLATILE,
132 #if _WIN32_WINNT >= 0x502
133 KEY_READ | KEY_WRITE,
134 #else
135 KEY_ALL_ACCESS,
136 #endif
137 NULL, &hSettingsKey, &disposition);
138 if (rc != ERROR_SUCCESS)
139 {
140 DPRINT("RegCreateKeyEx() failed with error 0x%lx\n", rc);
141 goto cleanup;
142 }
143
144 /* Install .SoftwareSettings to Settings subkey */
145 result = SetupInstallFromInfSection(
146 InstallParams.hwndParent, hInf, SectionName,
147 SPINST_REGISTRY, hSettingsKey,
148 NULL, 0, NULL, NULL,
149 NULL, NULL);
150 if (!result)
151 {
152 rc = GetLastError();
153 DPRINT("SetupInstallFromInfSection() failed with error 0x%lx\n", rc);
154 goto cleanup;
155 }
156
157 /* Get service name and open service registry key */
158 result = SetupDiGetDeviceRegistryProperty(
159 DeviceInfoSet, DeviceInfoData,
160 SPDRP_SERVICE, NULL,
161 (PBYTE)ServiceName, MAX_SERVICE_NAME_LEN * sizeof(TCHAR), NULL);
162 if (!result)
163 {
164 rc = GetLastError();
165 DPRINT("SetupDiGetDeviceRegistryProperty() failed with error 0x%lx\n", rc);
166 goto cleanup;
167 }
168
169 rc = RegOpenKeyEx(
170 HKEY_LOCAL_MACHINE, _T("SYSTEM\\CurrentControlSet\\Services"),
171 0, KEY_ENUMERATE_SUB_KEYS, &hServicesKey);
172 if (rc != ERROR_SUCCESS)
173 {
174 DPRINT("RegOpenKeyEx() failed with error 0x%lx\n", rc);
175 goto cleanup;
176 }
177 rc = RegOpenKeyEx(
178 hServicesKey, ServiceName,
179 0, KEY_CREATE_SUB_KEY, &hServiceKey);
180 if (rc != ERROR_SUCCESS)
181 {
182 DPRINT("RegOpenKeyEx() failed with error 0x%lx\n", rc);
183 goto cleanup;
184 }
185
186 /* Create a Device0 subkey (FIXME: do a loop to find a free number?) */
187 rc = RegCreateKeyEx(
188 hServiceKey, _T("Device0"), 0, NULL,
189 REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL,
190 &hDeviceSubKey, &disposition);
191 if (rc != ERROR_SUCCESS)
192 {
193 DPRINT("RegCreateKeyEx() failed with error 0x%lx\n", rc);
194 goto cleanup;
195 }
196 if (disposition != REG_CREATED_NEW_KEY)
197 {
198 rc = ERROR_GEN_FAILURE;
199 DPRINT("RegCreateKeyEx() failed\n");
200 goto cleanup;
201 }
202
203 /* Install SoftwareSettings section */
204 /* Yes, we're installing this section for the second time.
205 * We don't want to create a link to Settings subkey */
206 result = SetupInstallFromInfSection(
207 InstallParams.hwndParent, hInf, SectionName,
208 SPINST_REGISTRY, hDeviceSubKey,
209 NULL, 0, NULL, NULL,
210 NULL, NULL);
211 if (!result)
212 {
213 rc = GetLastError();
214 DPRINT("SetupInstallFromInfSection() failed with error 0x%lx\n", rc);
215 goto cleanup;
216 }
217
218 /* Add Device Description string */
219 cbData = (DWORD)(_tcslen(DriverInfoData.Description) + 1) * sizeof(TCHAR);
220 rc = RegSetValueEx(hDeviceSubKey,
221 _T("Device Description"),
222 0,
223 REG_SZ,
224 (const BYTE*)DriverInfoData.Description,
225 cbData);
226 if (rc != ERROR_SUCCESS)
227 {
228 DPRINT("RegSetValueEx() failed with error 0x%lx\n", rc);
229 goto cleanup;
230 }
231
232 /* FIXME: install OpenGLSoftwareSettings section */
233
234 rc = ERROR_SUCCESS;
235
236 cleanup:
237 if (hInf != INVALID_HANDLE_VALUE)
238 SetupCloseInfFile(hInf);
239 if (hDriverKey != INVALID_HANDLE_VALUE)
240 {
241 /* SetupDiOpenDevRegKey returns INVALID_HANDLE_VALUE in case of error! */
242 RegCloseKey(hDriverKey);
243 }
244 if (hSettingsKey != NULL)
245 RegCloseKey(hSettingsKey);
246 if (hServicesKey != NULL)
247 RegCloseKey(hServicesKey);
248 if (hServiceKey != NULL)
249 RegCloseKey(hServiceKey);
250 if (hDeviceSubKey != NULL)
251 RegCloseKey(hDeviceSubKey);
252
253 return rc;
254 }
255
256 DWORD WINAPI
257 MonitorClassInstaller(
258 IN DI_FUNCTION InstallFunction,
259 IN HDEVINFO DeviceInfoSet,
260 IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL)
261 {
262 return ERROR_DI_DO_DEFAULT;
263 }