c478e1394c8bebe1f372bb43e244b16ee9a88d78
[reactos.git] / reactos / lib / newdev / newdev.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS New devices installation
4 * FILE: lib/newdev/newdev.c
5 * PURPOSE: New devices installation
6 *
7 * PROGRAMMERS: Hervé Poussineau (hpoussin@reactos.org)
8 */
9
10 #define NDEBUG
11 #include <debug.h>
12
13 #include "newdev.h"
14
15 BOOL WINAPI
16 DevInstallW(
17 IN HWND hWndParent,
18 IN HINSTANCE hInstance,
19 IN LPCWSTR InstanceId,
20 IN INT Show)
21 {
22 HDEVINFO hDevInfo;
23 SP_DEVINFO_DATA devInfoData;
24 DWORD requiredSize;
25 DWORD regDataType;
26 PTSTR buffer = NULL;
27 SP_DRVINFO_DATA drvInfoData;
28 BOOL ret;
29
30 devInfoData.cbSize = 0; /* Tell if the devInfoData is valid */
31
32 hDevInfo = SetupDiCreateDeviceInfoListExW(NULL, NULL, NULL, NULL);
33 if (hDevInfo == INVALID_HANDLE_VALUE)
34 {
35 DPRINT("SetupDiCreateDeviceInfoListExW() failed with error 0x%lx\n", GetLastError());
36 ret = FALSE;
37 goto cleanup;
38 }
39
40 devInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
41 ret = SetupDiOpenDeviceInfoW(
42 hDevInfo,
43 InstanceId,
44 NULL,
45 0, /* Open flags */
46 &devInfoData);
47 if (!ret)
48 {
49 DPRINT("SetupDiOpenDeviceInfoW() failed with error 0x%lx\n", GetLastError());
50 devInfoData.cbSize = 0;
51 goto cleanup;
52 }
53
54 SetLastError(ERROR_GEN_FAILURE);
55 ret = SetupDiGetDeviceRegistryProperty(
56 hDevInfo,
57 &devInfoData,
58 SPDRP_DEVICEDESC,
59 &regDataType,
60 NULL, 0,
61 &requiredSize);
62 if (!ret && GetLastError() == ERROR_MORE_DATA && regDataType == REG_SZ)
63 {
64 buffer = HeapAlloc(GetProcessHeap(), 0, requiredSize);
65 if (!buffer)
66 {
67 DPRINT("HeapAlloc() failed\n");
68 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
69 }
70 else
71 {
72 ret = SetupDiGetDeviceRegistryProperty(
73 hDevInfo,
74 &devInfoData,
75 SPDRP_DEVICEDESC,
76 &regDataType,
77 buffer, requiredSize,
78 &requiredSize);
79 }
80 }
81 if (!ret)
82 {
83 DPRINT("SetupDiGetDeviceRegistryProperty() failed with error 0x%lx\n", GetLastError());
84 goto cleanup;
85 }
86
87 DPRINT("Installing %s (%S)\n", buffer, InstanceId);
88
89 ret = SetupDiBuildDriverInfoList(hDevInfo, &devInfoData, SPDIT_COMPATDRIVER);
90 if (!ret)
91 {
92 DPRINT("SetupDiBuildDriverInfoList() failed with error 0x%lx\n", GetLastError());
93 goto cleanup;
94 }
95
96 drvInfoData.cbSize = sizeof(SP_DRVINFO_DATA);
97 ret = SetupDiEnumDriverInfo(
98 hDevInfo,
99 &devInfoData,
100 SPDIT_COMPATDRIVER,
101 0,
102 &drvInfoData);
103 if (!ret)
104 {
105 DPRINT("SetupDiEnumDriverInfo() failed with error 0x%lx\n", GetLastError());
106 goto cleanup;
107 }
108 DPRINT("Installing driver %s: %s\n", drvInfoData.MfgName, drvInfoData.Description);
109
110 ret = SetupDiCallClassInstaller(
111 DIF_SELECTBESTCOMPATDRV,
112 hDevInfo,
113 &devInfoData);
114 if (!ret)
115 {
116 DPRINT("SetupDiCallClassInstaller(DIF_SELECTBESTCOMPATDRV) failed with error 0x%lx\n", GetLastError());
117 goto cleanup;
118 }
119
120 ret = SetupDiCallClassInstaller(
121 DIF_ALLOW_INSTALL,
122 hDevInfo,
123 &devInfoData);
124 if (!ret)
125 {
126 DPRINT("SetupDiCallClassInstaller(DIF_ALLOW_INSTALL) failed with error 0x%lx\n", GetLastError());
127 goto cleanup;
128 }
129
130 ret = SetupDiCallClassInstaller(
131 DIF_NEWDEVICEWIZARD_PREANALYZE,
132 hDevInfo,
133 &devInfoData);
134 if (!ret)
135 {
136 DPRINT("SetupDiCallClassInstaller(DIF_NEWDEVICEWIZARD_PREANALYZE) failed with error 0x%lx\n", GetLastError());
137 goto cleanup;
138 }
139
140 ret = SetupDiCallClassInstaller(
141 DIF_NEWDEVICEWIZARD_POSTANALYZE,
142 hDevInfo,
143 &devInfoData);
144 if (!ret)
145 {
146 DPRINT("SetupDiCallClassInstaller(DIF_NEWDEVICEWIZARD_POSTANALYZE) failed with error 0x%lx\n", GetLastError());
147 goto cleanup;
148 }
149
150 ret = SetupDiCallClassInstaller(
151 DIF_INSTALLDEVICEFILES,
152 hDevInfo,
153 &devInfoData);
154 if (!ret)
155 {
156 DPRINT("SetupDiCallClassInstaller(DIF_INSTALLDEVICEFILES) failed with error 0x%lx\n", GetLastError());
157 goto cleanup;
158 }
159
160 ret = SetupDiCallClassInstaller(
161 DIF_REGISTER_COINSTALLERS,
162 hDevInfo,
163 &devInfoData);
164 if (!ret)
165 {
166 DPRINT("SetupDiCallClassInstaller(DIF_REGISTER_COINSTALLERS) failed with error 0x%lx\n", GetLastError());
167 goto cleanup;
168 }
169
170 ret = SetupDiCallClassInstaller(
171 DIF_INSTALLINTERFACES,
172 hDevInfo,
173 &devInfoData);
174 if (!ret)
175 {
176 DPRINT("SetupDiCallClassInstaller(DIF_INSTALLINTERFACES) failed with error 0x%lx\n", GetLastError());
177 goto cleanup;
178 }
179
180 ret = SetupDiCallClassInstaller(
181 DIF_INSTALLDEVICE,
182 hDevInfo,
183 &devInfoData);
184 if (!ret)
185 {
186 DPRINT("SetupDiCallClassInstaller(DIF_INSTALLDEVICE) failed with error 0x%lx\n", GetLastError());
187 goto cleanup;
188 }
189
190 ret = SetupDiCallClassInstaller(
191 DIF_NEWDEVICEWIZARD_FINISHINSTALL,
192 hDevInfo,
193 &devInfoData);
194 if (!ret)
195 {
196 DPRINT("SetupDiCallClassInstaller(DIF_NEWDEVICEWIZARD_FINISHINSTALL) failed with error 0x%lx\n", GetLastError());
197 goto cleanup;
198 }
199
200 ret = SetupDiCallClassInstaller(
201 DIF_DESTROYPRIVATEDATA,
202 hDevInfo,
203 &devInfoData);
204 if (!ret)
205 {
206 DPRINT("SetupDiCallClassInstaller(DIF_DESTROYPRIVATEDATA) failed with error 0x%lx\n", GetLastError());
207 goto cleanup;
208 }
209
210 cleanup:
211 if (devInfoData.cbSize != 0)
212 {
213 if (!SetupDiDestroyDriverInfoList(hDevInfo, &devInfoData, SPDIT_COMPATDRIVER))
214 DPRINT("SetupDiDestroyDriverInfoList() failed with error 0x%lx\n", GetLastError());
215 }
216
217 if (hDevInfo != INVALID_HANDLE_VALUE)
218 {
219 if (!SetupDiDestroyDeviceInfoList(hDevInfo))
220 DPRINT("SetupDiDestroyDeviceInfoList() failed with error 0x%lx\n", GetLastError());
221 }
222
223 if (buffer)
224 HeapFree(GetProcessHeap(), 0, buffer);
225
226 return ret;
227 }