63273fbc3ff86e74fbd7c6fcc1baae4d3720326f
[reactos.git] / reactos / dll / win32 / msports / classinst.c
1 /*
2 * PROJECT: ReactOS system libraries
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: dlls\win32\msports\classinst.c
5 * PURPOSE: Ports class installer
6 * PROGRAMMERS: Copyright 2011 Eric Kohl
7 */
8
9 #include <windows.h>
10 #include <setupapi.h>
11 #include <wine/debug.h>
12
13 WINE_DEFAULT_DEBUG_CHANNEL(msports);
14
15
16 typedef enum _PORT_TYPE
17 {
18 UnknownPort,
19 ParallelPort,
20 SerialPort
21 } PORT_TYPE;
22
23
24 static DWORD
25 InstallSerialPort(IN HDEVINFO DeviceInfoSet,
26 IN PSP_DEVINFO_DATA DeviceInfoData)
27 {
28 LPWSTR pszFriendlyName = L"Serial Port (COMx)";
29
30 TRACE("InstallSerialPort(%p, %p)\n",
31 DeviceInfoSet, DeviceInfoData);
32
33 /* Install the device */
34 if (!SetupDiInstallDevice(DeviceInfoSet,
35 DeviceInfoData))
36 {
37 return GetLastError();
38 }
39
40 /* Set the friendly name for the device */
41 SetupDiSetDeviceRegistryPropertyW(DeviceInfoSet,
42 DeviceInfoData,
43 SPDRP_FRIENDLYNAME,
44 (LPBYTE)pszFriendlyName,
45 (wcslen(pszFriendlyName) + 1) * sizeof(WCHAR));
46
47 return ERROR_SUCCESS;
48 }
49
50
51 static DWORD
52 InstallParallelPort(IN HDEVINFO DeviceInfoSet,
53 IN PSP_DEVINFO_DATA DeviceInfoData)
54 {
55 FIXME("InstallParallelPort(%p, %p)\n",
56 DeviceInfoSet, DeviceInfoData);
57 return ERROR_DI_DO_DEFAULT;
58 }
59
60
61 VOID
62 InstallDeviceData(IN HDEVINFO DeviceInfoSet,
63 IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL)
64 {
65 HKEY hKey = NULL;
66 HINF hInf = INVALID_HANDLE_VALUE;
67 SP_DRVINFO_DATA DriverInfoData;
68 PSP_DRVINFO_DETAIL_DATA DriverInfoDetailData;
69 WCHAR InfSectionWithExt[256];
70 BYTE buffer[2048];
71 DWORD dwRequired;
72
73 TRACE("InstallDeviceData()\n");
74
75 hKey = SetupDiCreateDevRegKeyW(DeviceInfoSet,
76 DeviceInfoData,
77 DICS_FLAG_GLOBAL,
78 0,
79 DIREG_DRV,
80 NULL,
81 NULL);
82 if (hKey == NULL)
83 goto done;
84
85 DriverInfoData.cbSize = sizeof(SP_DRVINFO_DATA);
86 if (!SetupDiGetSelectedDriverW(DeviceInfoSet,
87 DeviceInfoData,
88 &DriverInfoData))
89 {
90 goto done;
91 }
92
93 DriverInfoDetailData = (PSP_DRVINFO_DETAIL_DATA)buffer;
94 DriverInfoDetailData->cbSize = sizeof(SP_DRVINFO_DETAIL_DATA);
95 if (!SetupDiGetDriverInfoDetailW(DeviceInfoSet,
96 DeviceInfoData,
97 &DriverInfoData,
98 DriverInfoDetailData,
99 2048,
100 &dwRequired))
101 {
102 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
103 goto done;
104 }
105
106 TRACE("Inf file name: %S\n", DriverInfoDetailData->InfFileName);
107
108 hInf = SetupOpenInfFileW(DriverInfoDetailData->InfFileName,
109 NULL,
110 INF_STYLE_WIN4,
111 NULL);
112 if (hInf == INVALID_HANDLE_VALUE)
113 goto done;
114
115 TRACE("Section name: %S\n", DriverInfoDetailData->SectionName);
116
117 SetupDiGetActualSectionToInstallW(hInf,
118 DriverInfoDetailData->SectionName,
119 InfSectionWithExt,
120 256,
121 NULL,
122 NULL);
123
124 TRACE("InfSectionWithExt: %S\n", InfSectionWithExt);
125
126 SetupInstallFromInfSectionW(NULL,
127 hInf,
128 InfSectionWithExt,
129 SPINST_REGISTRY,
130 hKey,
131 NULL,
132 0,
133 NULL,
134 NULL,
135 NULL,
136 NULL);
137
138 TRACE("Done\n");
139
140 done:;
141 if (hKey != NULL)
142 RegCloseKey(hKey);
143
144 if (hInf != INVALID_HANDLE_VALUE)
145 SetupCloseInfFile(hInf);
146 }
147
148
149
150 PORT_TYPE
151 GetPortType(IN HDEVINFO DeviceInfoSet,
152 IN PSP_DEVINFO_DATA DeviceInfoData)
153 {
154 HKEY hKey = NULL;
155 DWORD dwSize;
156 DWORD dwType = 0;
157 BYTE bData = 0;
158 PORT_TYPE PortType = UnknownPort;
159 LONG lError;
160
161 TRACE("GetPortType()\n");
162
163 hKey = SetupDiCreateDevRegKeyW(DeviceInfoSet,
164 DeviceInfoData,
165 DICS_FLAG_GLOBAL,
166 0,
167 DIREG_DRV,
168 NULL,
169 NULL);
170 if (hKey == NULL)
171 {
172 goto done;
173 }
174
175 dwSize = sizeof(BYTE);
176 lError = RegQueryValueExW(hKey,
177 L"PortSubClass",
178 NULL,
179 &dwType,
180 &bData,
181 &dwSize);
182
183 TRACE("lError: %ld\n", lError);
184 TRACE("dwSize: %lu\n", dwSize);
185 TRACE("dwType: %lu\n", dwType);
186
187 if (lError == ERROR_SUCCESS &&
188 dwSize == sizeof(BYTE) &&
189 dwType == REG_BINARY)
190 {
191 if (bData == 0)
192 PortType = ParallelPort;
193 else
194 PortType = SerialPort;
195 }
196
197 done:;
198 if (hKey != NULL)
199 RegCloseKey(hKey);
200
201 TRACE("GetPortType() returns %u \n", PortType);
202
203 return PortType;
204 }
205
206
207 static DWORD
208 InstallPort(IN HDEVINFO DeviceInfoSet,
209 IN PSP_DEVINFO_DATA DeviceInfoData)
210 {
211 PORT_TYPE PortType;
212
213 InstallDeviceData(DeviceInfoSet, DeviceInfoData);
214
215 PortType = GetPortType(DeviceInfoSet, DeviceInfoData);
216 switch (PortType)
217 {
218 case ParallelPort:
219 return InstallParallelPort(DeviceInfoSet, DeviceInfoData);
220
221 case SerialPort:
222 return InstallSerialPort(DeviceInfoSet, DeviceInfoData);
223
224 default:
225 return ERROR_DI_DO_DEFAULT;
226 }
227 }
228
229
230 DWORD
231 WINAPI
232 PortsClassInstaller(IN DI_FUNCTION InstallFunction,
233 IN HDEVINFO DeviceInfoSet,
234 IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL)
235 {
236 TRACE("PortsClassInstaller(%lu, %p, %p)\n",
237 InstallFunction, DeviceInfoSet, DeviceInfoData);
238
239 switch (InstallFunction)
240 {
241 case DIF_INSTALLDEVICE:
242 return InstallPort(DeviceInfoSet, DeviceInfoData);
243
244 default:
245 TRACE("Install function %u ignored\n", InstallFunction);
246 return ERROR_DI_DO_DEFAULT;
247 }
248 }
249
250 /* EOF */