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
9 #define WIN32_NO_STATUS
14 #include <wine/debug.h>
16 WINE_DEFAULT_DEBUG_CHANNEL(msports
);
19 typedef enum _PORT_TYPE
28 GetBootResourceList(HDEVINFO DeviceInfoSet
,
29 PSP_DEVINFO_DATA DeviceInfoData
,
30 PCM_RESOURCE_LIST
*ppResourceList
)
32 HKEY hDeviceKey
= NULL
;
33 HKEY hConfigKey
= NULL
;
34 LPBYTE lpBuffer
= NULL
;
39 *ppResourceList
= NULL
;
41 hDeviceKey
= SetupDiCreateDevRegKeyW(DeviceInfoSet
,
51 lError
= RegOpenKeyExW(hDeviceKey
,
56 if (lError
!= ERROR_SUCCESS
)
59 /* Get the configuration data size */
60 lError
= RegQueryValueExW(hConfigKey
,
66 if (lError
!= ERROR_SUCCESS
)
69 /* Allocate the buffer */
70 lpBuffer
= HeapAlloc(GetProcessHeap(), 0, dwDataSize
);
74 /* Retrieve the configuration data */
75 lError
= RegQueryValueExW(hConfigKey
,
81 if (lError
== ERROR_SUCCESS
)
85 if (ret
== FALSE
&& lpBuffer
!= NULL
)
86 HeapFree(GetProcessHeap(), 0, lpBuffer
);
89 RegCloseKey(hConfigKey
);
92 RegCloseKey(hDeviceKey
);
95 *ppResourceList
= (PCM_RESOURCE_LIST
)lpBuffer
;
102 GetSerialPortNumber(IN HDEVINFO DeviceInfoSet
,
103 IN PSP_DEVINFO_DATA DeviceInfoData
)
105 PCM_RESOURCE_LIST lpResourceList
= NULL
;
106 PCM_PARTIAL_RESOURCE_DESCRIPTOR lpResDes
;
108 DWORD dwBaseAddress
= 0;
109 DWORD dwPortNumber
= 0;
111 TRACE("GetSerialPortNumber(%p, %p)\n",
112 DeviceInfoSet
, DeviceInfoData
);
114 if (GetBootResourceList(DeviceInfoSet
,
118 TRACE("Full resource descriptors: %ul\n", lpResourceList
->Count
);
119 if (lpResourceList
->Count
> 0)
121 TRACE("Partial resource descriptors: %ul\n", lpResourceList
->List
[0].PartialResourceList
.Count
);
123 for (i
= 0; i
< lpResourceList
->List
[0].PartialResourceList
.Count
; i
++)
125 lpResDes
= &lpResourceList
->List
[0].PartialResourceList
.PartialDescriptors
[i
];
126 TRACE("Type: %u\n", lpResDes
->Type
);
128 switch (lpResDes
->Type
)
130 case CmResourceTypePort
:
131 TRACE("Port: Start: %I64x Length: %lu\n",
132 lpResDes
->u
.Port
.Start
.QuadPart
,
133 lpResDes
->u
.Port
.Length
);
134 if (lpResDes
->u
.Port
.Start
.HighPart
== 0)
135 dwBaseAddress
= (DWORD
)lpResDes
->u
.Port
.Start
.LowPart
;
138 case CmResourceTypeInterrupt
:
139 TRACE("Interrupt: Level: %lu Vector: %lu\n",
140 lpResDes
->u
.Interrupt
.Level
,
141 lpResDes
->u
.Interrupt
.Vector
);
147 HeapFree(GetProcessHeap(), 0, lpResourceList
);
150 switch (dwBaseAddress
)
174 GetParallelPortNumber(IN HDEVINFO DeviceInfoSet
,
175 IN PSP_DEVINFO_DATA DeviceInfoData
)
177 PCM_RESOURCE_LIST lpResourceList
= NULL
;
178 PCM_PARTIAL_RESOURCE_DESCRIPTOR lpResDes
;
180 DWORD dwBaseAddress
= 0;
181 DWORD dwPortNumber
= 0;
183 TRACE("GetParallelPortNumber(%p, %p)\n",
184 DeviceInfoSet
, DeviceInfoData
);
186 if (GetBootResourceList(DeviceInfoSet
,
190 TRACE("Full resource descriptors: %ul\n", lpResourceList
->Count
);
191 if (lpResourceList
->Count
> 0)
193 TRACE("Partial resource descriptors: %ul\n", lpResourceList
->List
[0].PartialResourceList
.Count
);
195 for (i
= 0; i
< lpResourceList
->List
[0].PartialResourceList
.Count
; i
++)
197 lpResDes
= &lpResourceList
->List
[0].PartialResourceList
.PartialDescriptors
[i
];
198 TRACE("Type: %u\n", lpResDes
->Type
);
200 switch (lpResDes
->Type
)
202 case CmResourceTypePort
:
203 TRACE("Port: Start: %I64x Length: %lu\n",
204 lpResDes
->u
.Port
.Start
.QuadPart
,
205 lpResDes
->u
.Port
.Length
);
206 if (lpResDes
->u
.Port
.Start
.HighPart
== 0)
207 dwBaseAddress
= (DWORD
)lpResDes
->u
.Port
.Start
.LowPart
;
210 case CmResourceTypeInterrupt
:
211 TRACE("Interrupt: Level: %lu Vector: %lu\n",
212 lpResDes
->u
.Interrupt
.Level
,
213 lpResDes
->u
.Interrupt
.Vector
);
221 HeapFree(GetProcessHeap(), 0, lpResourceList
);
224 switch (dwBaseAddress
)
240 InstallSerialPort(IN HDEVINFO DeviceInfoSet
,
241 IN PSP_DEVINFO_DATA DeviceInfoData
)
243 WCHAR szDeviceDescription
[256];
244 WCHAR szFriendlyName
[256];
248 TRACE("InstallSerialPort(%p, %p)\n",
249 DeviceInfoSet
, DeviceInfoData
);
251 dwPortNumber
= GetSerialPortNumber(DeviceInfoSet
,
253 if (dwPortNumber
!= 0)
255 swprintf(szPortName
, L
"COM%u", dwPortNumber
);
259 wcscpy(szPortName
, L
"COMx");
263 /* Install the device */
264 if (!SetupDiInstallDevice(DeviceInfoSet
,
267 return GetLastError();
270 if (SetupDiGetDeviceRegistryPropertyW(DeviceInfoSet
,
274 (LPBYTE
)szDeviceDescription
,
278 swprintf(szFriendlyName
,
285 swprintf(szFriendlyName
,
290 /* Set the friendly name for the device */
291 SetupDiSetDeviceRegistryPropertyW(DeviceInfoSet
,
294 (LPBYTE
)szFriendlyName
,
295 (wcslen(szFriendlyName
) + 1) * sizeof(WCHAR
));
297 return ERROR_SUCCESS
;
302 InstallParallelPort(IN HDEVINFO DeviceInfoSet
,
303 IN PSP_DEVINFO_DATA DeviceInfoData
)
305 WCHAR szDeviceDescription
[256];
306 WCHAR szFriendlyName
[256];
310 TRACE("InstallParallelPort(%p, %p)\n",
311 DeviceInfoSet
, DeviceInfoData
);
313 dwPortNumber
= GetParallelPortNumber(DeviceInfoSet
,
315 if (dwPortNumber
!= 0)
317 swprintf(szPortName
, L
"LPT%u", dwPortNumber
);
321 wcscpy(szPortName
, L
"LPTx");
325 /* Install the device */
326 if (!SetupDiInstallDevice(DeviceInfoSet
,
329 return GetLastError();
332 if (SetupDiGetDeviceRegistryPropertyW(DeviceInfoSet
,
336 (LPBYTE
)szDeviceDescription
,
340 swprintf(szFriendlyName
,
347 swprintf(szFriendlyName
,
352 /* Set the friendly name for the device */
353 SetupDiSetDeviceRegistryPropertyW(DeviceInfoSet
,
356 (LPBYTE
)szFriendlyName
,
357 (wcslen(szFriendlyName
) + 1) * sizeof(WCHAR
));
359 return ERROR_SUCCESS
;
364 InstallDeviceData(IN HDEVINFO DeviceInfoSet
,
365 IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL
)
368 HINF hInf
= INVALID_HANDLE_VALUE
;
369 SP_DRVINFO_DATA DriverInfoData
;
370 PSP_DRVINFO_DETAIL_DATA DriverInfoDetailData
;
371 WCHAR InfSectionWithExt
[256];
375 TRACE("InstallDeviceData()\n");
377 hKey
= SetupDiCreateDevRegKeyW(DeviceInfoSet
,
387 DriverInfoData
.cbSize
= sizeof(SP_DRVINFO_DATA
);
388 if (!SetupDiGetSelectedDriverW(DeviceInfoSet
,
395 DriverInfoDetailData
= (PSP_DRVINFO_DETAIL_DATA
)buffer
;
396 DriverInfoDetailData
->cbSize
= sizeof(SP_DRVINFO_DETAIL_DATA
);
397 if (!SetupDiGetDriverInfoDetailW(DeviceInfoSet
,
400 DriverInfoDetailData
,
404 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER
)
408 TRACE("Inf file name: %S\n", DriverInfoDetailData
->InfFileName
);
410 hInf
= SetupOpenInfFileW(DriverInfoDetailData
->InfFileName
,
414 if (hInf
== INVALID_HANDLE_VALUE
)
417 TRACE("Section name: %S\n", DriverInfoDetailData
->SectionName
);
419 SetupDiGetActualSectionToInstallW(hInf
,
420 DriverInfoDetailData
->SectionName
,
426 TRACE("InfSectionWithExt: %S\n", InfSectionWithExt
);
428 SetupInstallFromInfSectionW(NULL
,
446 if (hInf
!= INVALID_HANDLE_VALUE
)
447 SetupCloseInfFile(hInf
);
453 GetPortType(IN HDEVINFO DeviceInfoSet
,
454 IN PSP_DEVINFO_DATA DeviceInfoData
)
460 PORT_TYPE PortType
= UnknownPort
;
463 TRACE("GetPortType()\n");
465 hKey
= SetupDiCreateDevRegKeyW(DeviceInfoSet
,
477 dwSize
= sizeof(BYTE
);
478 lError
= RegQueryValueExW(hKey
,
485 TRACE("lError: %ld\n", lError
);
486 TRACE("dwSize: %lu\n", dwSize
);
487 TRACE("dwType: %lu\n", dwType
);
489 if (lError
== ERROR_SUCCESS
&&
490 dwSize
== sizeof(BYTE
) &&
491 dwType
== REG_BINARY
)
494 PortType
= ParallelPort
;
496 PortType
= SerialPort
;
503 TRACE("GetPortType() returns %u \n", PortType
);
510 InstallPort(IN HDEVINFO DeviceInfoSet
,
511 IN PSP_DEVINFO_DATA DeviceInfoData
)
515 InstallDeviceData(DeviceInfoSet
, DeviceInfoData
);
517 PortType
= GetPortType(DeviceInfoSet
, DeviceInfoData
);
521 return InstallParallelPort(DeviceInfoSet
, DeviceInfoData
);
524 return InstallSerialPort(DeviceInfoSet
, DeviceInfoData
);
527 return ERROR_DI_DO_DEFAULT
;
534 PortsClassInstaller(IN DI_FUNCTION InstallFunction
,
535 IN HDEVINFO DeviceInfoSet
,
536 IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL
)
538 TRACE("PortsClassInstaller(%lu, %p, %p)\n",
539 InstallFunction
, DeviceInfoSet
, DeviceInfoData
);
541 switch (InstallFunction
)
543 case DIF_INSTALLDEVICE
:
544 return InstallPort(DeviceInfoSet
, DeviceInfoData
);
547 TRACE("Install function %u ignored\n", InstallFunction
);
548 return ERROR_DI_DO_DEFAULT
;