a1867c1244c9592534382bd88237af013c41bffd
[reactos.git] / reactos / lib / cpl / desk / classinst.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Plug & Play
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 hServicesKey = INVALID_HANDLE_VALUE;
28 HKEY hServiceKey = INVALID_HANDLE_VALUE;
29 HKEY hDeviceSubKey = INVALID_HANDLE_VALUE;
30 DWORD disposition;
31 BOOL result;
32 LONG rc;
33
34 if (InstallFunction != DIF_INSTALLDEVICE)
35 return ERROR_DI_DO_DEFAULT;
36
37 InstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS);
38 result = SetupDiGetDeviceInstallParams(DeviceInfoSet, DeviceInfoData, &InstallParams);
39 if (!result)
40 {
41 rc = GetLastError();
42 DPRINT("SetupDiGetDeviceInstallParams() failed with error 0x%lx\n", rc);
43 goto cleanup;
44 }
45
46 InstallParams.Flags |= DI_NEEDRESTART;
47
48 result = SetupDiSetDeviceInstallParams(DeviceInfoSet, DeviceInfoData, &InstallParams);
49 if (!result)
50 {
51 rc = GetLastError();
52 DPRINT("SetupDiSetDeviceInstallParams() failed with error 0x%lx\n", rc);
53 goto cleanup;
54 }
55
56 DriverInfoData.cbSize = sizeof(SP_DRVINFO_DATA);
57 result = SetupDiGetSelectedDriver(DeviceInfoSet, DeviceInfoData, &DriverInfoData);
58 if (!result)
59 {
60 rc = GetLastError();
61 DPRINT("SetupDiGetSelectedDriver() failed with error 0x%lx\n", rc);
62 goto cleanup;
63 }
64
65 DriverInfoDetailData.cbSize = sizeof(SP_DRVINFO_DETAIL_DATA);
66 result = SetupDiGetDriverInfoDetail(
67 DeviceInfoSet, DeviceInfoData,
68 &DriverInfoData, &DriverInfoDetailData,
69 sizeof(SP_DRVINFO_DETAIL_DATA), NULL);
70 if (!result && GetLastError() != ERROR_INSUFFICIENT_BUFFER)
71 {
72 rc = GetLastError();
73 DPRINT("SetupDiGetDriverInfoDetail() failed with error 0x%lx\n", rc);
74 goto cleanup;
75 }
76
77 hInf = SetupOpenInfFile(DriverInfoDetailData.InfFileName, NULL, INF_STYLE_WIN4, NULL);
78 if (hInf == INVALID_HANDLE_VALUE)
79 {
80 rc = GetLastError();
81 DPRINT("SetupOpenInfFile() failed with error 0x%lx\n", rc);
82 goto cleanup;
83 }
84
85 result = SetupDiGetActualSectionToInstall(
86 hInf, DriverInfoDetailData.SectionName,
87 SectionName, MAX_PATH - _tcslen(_T(".SoftwareSettings")), NULL, NULL);
88 if (!result)
89 {
90 rc = GetLastError();
91 DPRINT("SetupDiGetActualSectionToInstall() failed with error 0x%lx\n", rc);
92 goto cleanup;
93 }
94 _tcscat(SectionName, _T(".SoftwareSettings"));
95
96 result = SetupDiInstallDevice(DeviceInfoSet, DeviceInfoData);
97 if (!result)
98 {
99 rc = GetLastError();
100 DPRINT("SetupDiGetDeviceRegistryProperty() failed with error 0x%lx\n", rc);
101 goto cleanup;
102 }
103
104 result = SetupDiGetDeviceRegistryProperty(
105 DeviceInfoSet, DeviceInfoData,
106 SPDRP_SERVICE, NULL,
107 (PBYTE)ServiceName, MAX_SERVICE_NAME_LEN * sizeof(TCHAR), NULL);
108 if (!result)
109 {
110 rc = GetLastError();
111 DPRINT("SetupDiGetDeviceRegistryProperty() failed with error 0x%lx\n", rc);
112 goto cleanup;
113 }
114
115 rc = RegOpenKeyEx(
116 HKEY_LOCAL_MACHINE, _T("SYSTEM\\CurrentControlSet\\Services"),
117 0, KEY_ENUMERATE_SUB_KEYS, &hServicesKey);
118 if (rc != ERROR_SUCCESS)
119 {
120 DPRINT("RegOpenKeyEx() failed with error 0x%lx\n", rc);
121 goto cleanup;
122 }
123 rc = RegOpenKeyEx(
124 hServicesKey, ServiceName,
125 0, KEY_CREATE_SUB_KEY, &hServiceKey);
126 if (rc != ERROR_SUCCESS)
127 {
128 DPRINT("RegOpenKeyEx() failed with error 0x%lx\n", rc);
129 goto cleanup;
130 }
131
132 /* Create a Device0 subkey (FIXME: do a loop to find a free number?) */
133 rc = RegCreateKeyEx(
134 hServiceKey, _T("Device0"), 0, NULL,
135 REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL,
136 &hDeviceSubKey, &disposition);
137 if (rc != ERROR_SUCCESS)
138 {
139 DPRINT("RegCreateKeyEx() failed with error 0x%lx\n", rc);
140 goto cleanup;
141 }
142 if (disposition != REG_CREATED_NEW_KEY)
143 {
144 rc = ERROR_GEN_FAILURE;
145 DPRINT("RegCreateKeyEx() failed\n");
146 goto cleanup;
147 }
148
149 /* Install SoftwareSettings section */
150 result = SetupInstallFromInfSection(
151 InstallParams.hwndParent, hInf, SectionName,
152 SPINST_REGISTRY, hDeviceSubKey,
153 NULL, 0, NULL, NULL,
154 NULL, NULL);
155 if (!result)
156 {
157 rc = GetLastError();
158 DPRINT("SetupInstallFromInfSection() failed with error 0x%lx\n", rc);
159 goto cleanup;
160 }
161
162 /* FIXME: install OpenGLSoftwareSettings section */
163
164 rc = ERROR_SUCCESS;
165
166 cleanup:
167 if (hInf != INVALID_HANDLE_VALUE)
168 SetupCloseInfFile(hInf);
169 if (hServicesKey != INVALID_HANDLE_VALUE)
170 RegCloseKey(hServicesKey);
171 if (hServiceKey != INVALID_HANDLE_VALUE)
172 RegCloseKey(hServiceKey);
173 if (hDeviceSubKey != INVALID_HANDLE_VALUE)
174 RegCloseKey(hDeviceSubKey);
175
176 return rc;
177 }