Synchronize with trunk r58457.
[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: Display class installer
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;
33 BOOL result;
34 LONG rc;
35
36 if (InstallFunction != DIF_INSTALLDEVICE)
37 return ERROR_DI_DO_DEFAULT;
38
39 /* Set DI_DONOTCALLCONFIGMG flag */
40 InstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS);
41 result = SetupDiGetDeviceInstallParams(DeviceInfoSet, DeviceInfoData, &InstallParams);
42 if (!result)
43 {
44 rc = GetLastError();
45 DPRINT("SetupDiGetDeviceInstallParams() failed with error 0x%lx\n", rc);
46 goto cleanup;
47 }
48
49 InstallParams.Flags |= DI_DONOTCALLCONFIGMG;
50
51 result = SetupDiSetDeviceInstallParams(DeviceInfoSet, DeviceInfoData, &InstallParams);
52 if (!result)
53 {
54 rc = GetLastError();
55 DPRINT("SetupDiSetDeviceInstallParams() failed with error 0x%lx\n", rc);
56 goto cleanup;
57 }
58
59 /* Do normal install */
60 result = SetupDiInstallDevice(DeviceInfoSet, DeviceInfoData);
61 if (!result)
62 {
63 rc = GetLastError();
64 DPRINT("SetupDiInstallDevice() failed with error 0x%lx\n", rc);
65 goto cleanup;
66 }
67
68 /* Get .inf file name and section name */
69 DriverInfoData.cbSize = sizeof(SP_DRVINFO_DATA);
70 result = SetupDiGetSelectedDriver(DeviceInfoSet, DeviceInfoData, &DriverInfoData);
71 if (!result)
72 {
73 rc = GetLastError();
74 DPRINT("SetupDiGetSelectedDriver() failed with error 0x%lx\n", rc);
75 goto cleanup;
76 }
77
78 DriverInfoDetailData.cbSize = sizeof(SP_DRVINFO_DETAIL_DATA);
79 result = SetupDiGetDriverInfoDetail(
80 DeviceInfoSet, DeviceInfoData,
81 &DriverInfoData, &DriverInfoDetailData,
82 sizeof(SP_DRVINFO_DETAIL_DATA), 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 result = SetupDiGetActualSectionToInstall(
99 hInf, DriverInfoDetailData.SectionName,
100 SectionName, MAX_PATH - _tcslen(_T(".SoftwareSettings")), NULL, NULL);
101 if (!result)
102 {
103 rc = GetLastError();
104 DPRINT("SetupDiGetActualSectionToInstall() failed with error 0x%lx\n", rc);
105 goto cleanup;
106 }
107 _tcscat(SectionName, _T(".SoftwareSettings"));
108
109 /* Open driver registry key and create Settings subkey */
110 hDriverKey = SetupDiOpenDevRegKey(
111 DeviceInfoSet, DeviceInfoData,
112 DICS_FLAG_GLOBAL, 0, DIREG_DRV,
113 KEY_CREATE_SUB_KEY);
114 if (hDriverKey == INVALID_HANDLE_VALUE)
115 {
116 rc = GetLastError();
117 DPRINT("SetupDiOpenDevRegKey() failed with error 0x%lx\n", rc);
118 goto cleanup;
119 }
120 rc = RegCreateKeyEx(
121 hDriverKey, L"Settings",
122 0, NULL, REG_OPTION_NON_VOLATILE,
123 #if _WIN32_WINNT >= 0x502
124 KEY_READ | KEY_WRITE,
125 #else
126 KEY_ALL_ACCESS,
127 #endif
128 NULL, &hSettingsKey, &disposition);
129 if (rc != ERROR_SUCCESS)
130 {
131 DPRINT("RegCreateKeyEx() failed with error 0x%lx\n", rc);
132 goto cleanup;
133 }
134
135 /* Install .SoftwareSettings to Settings subkey */
136 result = SetupInstallFromInfSection(
137 InstallParams.hwndParent, hInf, SectionName,
138 SPINST_REGISTRY, hSettingsKey,
139 NULL, 0, NULL, NULL,
140 NULL, NULL);
141 if (!result)
142 {
143 rc = GetLastError();
144 DPRINT("SetupInstallFromInfSection() failed with error 0x%lx\n", rc);
145 goto cleanup;
146 }
147
148 /* Get service name and open service registry key */
149 result = SetupDiGetDeviceRegistryProperty(
150 DeviceInfoSet, DeviceInfoData,
151 SPDRP_SERVICE, NULL,
152 (PBYTE)ServiceName, MAX_SERVICE_NAME_LEN * sizeof(TCHAR), NULL);
153 if (!result)
154 {
155 rc = GetLastError();
156 DPRINT("SetupDiGetDeviceRegistryProperty() failed with error 0x%lx\n", rc);
157 goto cleanup;
158 }
159
160 rc = RegOpenKeyEx(
161 HKEY_LOCAL_MACHINE, _T("SYSTEM\\CurrentControlSet\\Services"),
162 0, KEY_ENUMERATE_SUB_KEYS, &hServicesKey);
163 if (rc != ERROR_SUCCESS)
164 {
165 DPRINT("RegOpenKeyEx() failed with error 0x%lx\n", rc);
166 goto cleanup;
167 }
168 rc = RegOpenKeyEx(
169 hServicesKey, ServiceName,
170 0, KEY_CREATE_SUB_KEY, &hServiceKey);
171 if (rc != ERROR_SUCCESS)
172 {
173 DPRINT("RegOpenKeyEx() failed with error 0x%lx\n", rc);
174 goto cleanup;
175 }
176
177 /* Create a Device0 subkey (FIXME: do a loop to find a free number?) */
178 rc = RegCreateKeyEx(
179 hServiceKey, _T("Device0"), 0, NULL,
180 REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL,
181 &hDeviceSubKey, &disposition);
182 if (rc != ERROR_SUCCESS)
183 {
184 DPRINT("RegCreateKeyEx() failed with error 0x%lx\n", rc);
185 goto cleanup;
186 }
187 if (disposition != REG_CREATED_NEW_KEY)
188 {
189 rc = ERROR_GEN_FAILURE;
190 DPRINT("RegCreateKeyEx() failed\n");
191 goto cleanup;
192 }
193
194 /* Install SoftwareSettings section */
195 /* Yes, we're installing this section for the second time.
196 * We don't want to create a link to Settings subkey */
197 result = SetupInstallFromInfSection(
198 InstallParams.hwndParent, hInf, SectionName,
199 SPINST_REGISTRY, hDeviceSubKey,
200 NULL, 0, NULL, NULL,
201 NULL, NULL);
202 if (!result)
203 {
204 rc = GetLastError();
205 DPRINT("SetupInstallFromInfSection() failed with error 0x%lx\n", rc);
206 goto cleanup;
207 }
208
209 /* FIXME: install OpenGLSoftwareSettings section */
210
211 rc = ERROR_SUCCESS;
212
213 cleanup:
214 if (hInf != INVALID_HANDLE_VALUE)
215 SetupCloseInfFile(hInf);
216 if (hDriverKey != INVALID_HANDLE_VALUE)
217 {
218 /* SetupDiOpenDevRegKey returns INVALID_HANDLE_VALUE in case of error! */
219 RegCloseKey(hDriverKey);
220 }
221 if (hSettingsKey != NULL)
222 RegCloseKey(hSettingsKey);
223 if (hServicesKey != NULL)
224 RegCloseKey(hServicesKey);
225 if (hServiceKey != NULL)
226 RegCloseKey(hServiceKey);
227 if (hDeviceSubKey != NULL)
228 RegCloseKey(hDeviceSubKey);
229
230 return rc;
231 }