Install one more time the .SoftwareSettings section in registry (no, I really don...
[reactos.git] / reactos / lib / cpl / desk / classinst.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Display Control Panel
4 * FILE: lib/cpl/desk/classinst.c
5 * PURPOSE: Display class installer
6 *
7 * PROGRAMMERS: Hervé Poussineau (hpoussin@reactos.org)
8 */
9
10 //#define NDEBUG
11 #include <debug.h>
12
13 #include "desk.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;
28 HKEY hSettingsKey = INVALID_HANDLE_VALUE;
29 HKEY hServicesKey = INVALID_HANDLE_VALUE;
30 HKEY hServiceKey = INVALID_HANDLE_VALUE;
31 HKEY hDeviceSubKey = INVALID_HANDLE_VALUE;
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_NEEDRESTART 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_NEEDRESTART;
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 /* Get .inf file name and section name */
60 DriverInfoData.cbSize = sizeof(SP_DRVINFO_DATA);
61 result = SetupDiGetSelectedDriver(DeviceInfoSet, DeviceInfoData, &DriverInfoData);
62 if (!result)
63 {
64 rc = GetLastError();
65 DPRINT("SetupDiGetSelectedDriver() failed with error 0x%lx\n", rc);
66 goto cleanup;
67 }
68
69 DriverInfoDetailData.cbSize = sizeof(SP_DRVINFO_DETAIL_DATA);
70 result = SetupDiGetDriverInfoDetail(
71 DeviceInfoSet, DeviceInfoData,
72 &DriverInfoData, &DriverInfoDetailData,
73 sizeof(SP_DRVINFO_DETAIL_DATA), NULL);
74 if (!result && GetLastError() != ERROR_INSUFFICIENT_BUFFER)
75 {
76 rc = GetLastError();
77 DPRINT("SetupDiGetDriverInfoDetail() failed with error 0x%lx\n", rc);
78 goto cleanup;
79 }
80
81 hInf = SetupOpenInfFile(DriverInfoDetailData.InfFileName, NULL, INF_STYLE_WIN4, NULL);
82 if (hInf == INVALID_HANDLE_VALUE)
83 {
84 rc = GetLastError();
85 DPRINT("SetupOpenInfFile() failed with error 0x%lx\n", rc);
86 goto cleanup;
87 }
88
89 result = SetupDiGetActualSectionToInstall(
90 hInf, DriverInfoDetailData.SectionName,
91 SectionName, MAX_PATH - _tcslen(_T(".SoftwareSettings")), NULL, NULL);
92 if (!result)
93 {
94 rc = GetLastError();
95 DPRINT("SetupDiGetActualSectionToInstall() failed with error 0x%lx\n", rc);
96 goto cleanup;
97 }
98 _tcscat(SectionName, _T(".SoftwareSettings"));
99
100 /* Do normal install */
101 result = SetupDiInstallDevice(DeviceInfoSet, DeviceInfoData);
102 if (!result)
103 {
104 rc = GetLastError();
105 DPRINT("SetupDiGetDeviceRegistryProperty() failed with error 0x%lx\n", rc);
106 goto cleanup;
107 }
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 RegCloseKey(hDriverKey);
218 if (hSettingsKey != INVALID_HANDLE_VALUE)
219 RegCloseKey(hSettingsKey);
220 if (hServicesKey != INVALID_HANDLE_VALUE)
221 RegCloseKey(hServicesKey);
222 if (hServiceKey != INVALID_HANDLE_VALUE)
223 RegCloseKey(hServiceKey);
224 if (hDeviceSubKey != INVALID_HANDLE_VALUE)
225 RegCloseKey(hDeviceSubKey);
226
227 return rc;
228 }