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
15 #include <wine/debug.h>
17 WINE_DEFAULT_DEBUG_CHANNEL(msports
);
20 typedef enum _PORT_TYPE
29 GetBootResourceList(HDEVINFO DeviceInfoSet
,
30 PSP_DEVINFO_DATA DeviceInfoData
,
31 PCM_RESOURCE_LIST
*ppResourceList
)
33 HKEY hDeviceKey
= NULL
;
34 HKEY hConfigKey
= NULL
;
35 LPBYTE lpBuffer
= NULL
;
40 *ppResourceList
= NULL
;
42 hDeviceKey
= SetupDiCreateDevRegKeyW(DeviceInfoSet
,
52 lError
= RegOpenKeyExW(hDeviceKey
,
57 if (lError
!= ERROR_SUCCESS
)
60 /* Get the configuration data size */
61 lError
= RegQueryValueExW(hConfigKey
,
67 if (lError
!= ERROR_SUCCESS
)
70 /* Allocate the buffer */
71 lpBuffer
= HeapAlloc(GetProcessHeap(), 0, dwDataSize
);
75 /* Retrieve the configuration data */
76 lError
= RegQueryValueExW(hConfigKey
,
82 if (lError
== ERROR_SUCCESS
)
86 if (ret
== FALSE
&& lpBuffer
!= NULL
)
87 HeapFree(GetProcessHeap(), 0, lpBuffer
);
90 RegCloseKey(hConfigKey
);
93 RegCloseKey(hDeviceKey
);
96 *ppResourceList
= (PCM_RESOURCE_LIST
)lpBuffer
;
103 GetSerialPortNumber(IN HDEVINFO DeviceInfoSet
,
104 IN PSP_DEVINFO_DATA DeviceInfoData
)
106 PCM_RESOURCE_LIST lpResourceList
= NULL
;
107 PCM_PARTIAL_RESOURCE_DESCRIPTOR lpResDes
;
109 DWORD dwBaseAddress
= 0;
110 DWORD dwPortNumber
= 0;
112 TRACE("GetSerialPortNumber(%p, %p)\n",
113 DeviceInfoSet
, DeviceInfoData
);
115 if (GetBootResourceList(DeviceInfoSet
,
119 TRACE("Full resource descriptors: %ul\n", lpResourceList
->Count
);
120 if (lpResourceList
->Count
> 0)
122 TRACE("Partial resource descriptors: %ul\n", lpResourceList
->List
[0].PartialResourceList
.Count
);
124 for (i
= 0; i
< lpResourceList
->List
[0].PartialResourceList
.Count
; i
++)
126 lpResDes
= &lpResourceList
->List
[0].PartialResourceList
.PartialDescriptors
[i
];
127 TRACE("Type: %u\n", lpResDes
->Type
);
129 switch (lpResDes
->Type
)
131 case CmResourceTypePort
:
132 TRACE("Port: Start: %I64x Length: %lu\n",
133 lpResDes
->u
.Port
.Start
.QuadPart
,
134 lpResDes
->u
.Port
.Length
);
135 if (lpResDes
->u
.Port
.Start
.HighPart
== 0)
136 dwBaseAddress
= (DWORD
)lpResDes
->u
.Port
.Start
.LowPart
;
139 case CmResourceTypeInterrupt
:
140 TRACE("Interrupt: Level: %lu Vector: %lu\n",
141 lpResDes
->u
.Interrupt
.Level
,
142 lpResDes
->u
.Interrupt
.Vector
);
148 HeapFree(GetProcessHeap(), 0, lpResourceList
);
151 switch (dwBaseAddress
)
175 GetParallelPortNumber(IN HDEVINFO DeviceInfoSet
,
176 IN PSP_DEVINFO_DATA DeviceInfoData
)
178 PCM_RESOURCE_LIST lpResourceList
= NULL
;
179 PCM_PARTIAL_RESOURCE_DESCRIPTOR lpResDes
;
181 DWORD dwBaseAddress
= 0;
182 DWORD dwPortNumber
= 0;
184 TRACE("GetParallelPortNumber(%p, %p)\n",
185 DeviceInfoSet
, DeviceInfoData
);
187 if (GetBootResourceList(DeviceInfoSet
,
191 TRACE("Full resource descriptors: %ul\n", lpResourceList
->Count
);
192 if (lpResourceList
->Count
> 0)
194 TRACE("Partial resource descriptors: %ul\n", lpResourceList
->List
[0].PartialResourceList
.Count
);
196 for (i
= 0; i
< lpResourceList
->List
[0].PartialResourceList
.Count
; i
++)
198 lpResDes
= &lpResourceList
->List
[0].PartialResourceList
.PartialDescriptors
[i
];
199 TRACE("Type: %u\n", lpResDes
->Type
);
201 switch (lpResDes
->Type
)
203 case CmResourceTypePort
:
204 TRACE("Port: Start: %I64x Length: %lu\n",
205 lpResDes
->u
.Port
.Start
.QuadPart
,
206 lpResDes
->u
.Port
.Length
);
207 if (lpResDes
->u
.Port
.Start
.HighPart
== 0)
208 dwBaseAddress
= (DWORD
)lpResDes
->u
.Port
.Start
.LowPart
;
211 case CmResourceTypeInterrupt
:
212 TRACE("Interrupt: Level: %lu Vector: %lu\n",
213 lpResDes
->u
.Interrupt
.Level
,
214 lpResDes
->u
.Interrupt
.Vector
);
222 HeapFree(GetProcessHeap(), 0, lpResourceList
);
225 switch (dwBaseAddress
)
241 InstallSerialPort(IN HDEVINFO DeviceInfoSet
,
242 IN PSP_DEVINFO_DATA DeviceInfoData
)
244 WCHAR szDeviceDescription
[256];
245 WCHAR szFriendlyName
[256];
248 HCOMDB hComDB
= HCOMDB_INVALID_HANDLE_VALUE
;
250 TRACE("InstallSerialPort(%p, %p)\n",
251 DeviceInfoSet
, DeviceInfoData
);
253 /* Open the com port database */
256 dwPortNumber
= GetSerialPortNumber(DeviceInfoSet
,
258 if (dwPortNumber
!= 0)
260 ComDBClaimPort(hComDB
,
267 ComDBClaimNextFreePort(hComDB
,
271 swprintf(szPortName
, L
"COM%u", dwPortNumber
);
273 /* Close the com port database */
274 if (hComDB
!= HCOMDB_INVALID_HANDLE_VALUE
)
277 /* Install the device */
278 if (!SetupDiInstallDevice(DeviceInfoSet
,
281 return GetLastError();
284 if (SetupDiGetDeviceRegistryPropertyW(DeviceInfoSet
,
288 (LPBYTE
)szDeviceDescription
,
292 swprintf(szFriendlyName
,
299 swprintf(szFriendlyName
,
304 /* Set the friendly name for the device */
305 SetupDiSetDeviceRegistryPropertyW(DeviceInfoSet
,
308 (LPBYTE
)szFriendlyName
,
309 (wcslen(szFriendlyName
) + 1) * sizeof(WCHAR
));
311 return ERROR_SUCCESS
;
316 InstallParallelPort(IN HDEVINFO DeviceInfoSet
,
317 IN PSP_DEVINFO_DATA DeviceInfoData
)
319 WCHAR szDeviceDescription
[256];
320 WCHAR szFriendlyName
[256];
324 TRACE("InstallParallelPort(%p, %p)\n",
325 DeviceInfoSet
, DeviceInfoData
);
327 dwPortNumber
= GetParallelPortNumber(DeviceInfoSet
,
329 if (dwPortNumber
!= 0)
331 swprintf(szPortName
, L
"LPT%u", dwPortNumber
);
335 wcscpy(szPortName
, L
"LPTx");
339 /* Install the device */
340 if (!SetupDiInstallDevice(DeviceInfoSet
,
343 return GetLastError();
346 if (SetupDiGetDeviceRegistryPropertyW(DeviceInfoSet
,
350 (LPBYTE
)szDeviceDescription
,
354 swprintf(szFriendlyName
,
361 swprintf(szFriendlyName
,
366 /* Set the friendly name for the device */
367 SetupDiSetDeviceRegistryPropertyW(DeviceInfoSet
,
370 (LPBYTE
)szFriendlyName
,
371 (wcslen(szFriendlyName
) + 1) * sizeof(WCHAR
));
373 return ERROR_SUCCESS
;
378 InstallDeviceData(IN HDEVINFO DeviceInfoSet
,
379 IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL
)
382 HINF hInf
= INVALID_HANDLE_VALUE
;
383 SP_DRVINFO_DATA DriverInfoData
;
384 PSP_DRVINFO_DETAIL_DATA DriverInfoDetailData
;
385 WCHAR InfSectionWithExt
[256];
389 TRACE("InstallDeviceData()\n");
391 hKey
= SetupDiCreateDevRegKeyW(DeviceInfoSet
,
401 DriverInfoData
.cbSize
= sizeof(SP_DRVINFO_DATA
);
402 if (!SetupDiGetSelectedDriverW(DeviceInfoSet
,
409 DriverInfoDetailData
= (PSP_DRVINFO_DETAIL_DATA
)buffer
;
410 DriverInfoDetailData
->cbSize
= sizeof(SP_DRVINFO_DETAIL_DATA
);
411 if (!SetupDiGetDriverInfoDetailW(DeviceInfoSet
,
414 DriverInfoDetailData
,
418 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER
)
422 TRACE("Inf file name: %S\n", DriverInfoDetailData
->InfFileName
);
424 hInf
= SetupOpenInfFileW(DriverInfoDetailData
->InfFileName
,
428 if (hInf
== INVALID_HANDLE_VALUE
)
431 TRACE("Section name: %S\n", DriverInfoDetailData
->SectionName
);
433 SetupDiGetActualSectionToInstallW(hInf
,
434 DriverInfoDetailData
->SectionName
,
440 TRACE("InfSectionWithExt: %S\n", InfSectionWithExt
);
442 SetupInstallFromInfSectionW(NULL
,
460 if (hInf
!= INVALID_HANDLE_VALUE
)
461 SetupCloseInfFile(hInf
);
467 GetPortType(IN HDEVINFO DeviceInfoSet
,
468 IN PSP_DEVINFO_DATA DeviceInfoData
)
474 PORT_TYPE PortType
= UnknownPort
;
477 TRACE("GetPortType()\n");
479 hKey
= SetupDiCreateDevRegKeyW(DeviceInfoSet
,
491 dwSize
= sizeof(BYTE
);
492 lError
= RegQueryValueExW(hKey
,
499 TRACE("lError: %ld\n", lError
);
500 TRACE("dwSize: %lu\n", dwSize
);
501 TRACE("dwType: %lu\n", dwType
);
503 if (lError
== ERROR_SUCCESS
&&
504 dwSize
== sizeof(BYTE
) &&
505 dwType
== REG_BINARY
)
508 PortType
= ParallelPort
;
510 PortType
= SerialPort
;
517 TRACE("GetPortType() returns %u \n", PortType
);
524 InstallPort(IN HDEVINFO DeviceInfoSet
,
525 IN PSP_DEVINFO_DATA DeviceInfoData
)
529 InstallDeviceData(DeviceInfoSet
, DeviceInfoData
);
531 PortType
= GetPortType(DeviceInfoSet
, DeviceInfoData
);
535 return InstallParallelPort(DeviceInfoSet
, DeviceInfoData
);
538 return InstallSerialPort(DeviceInfoSet
, DeviceInfoData
);
541 return ERROR_DI_DO_DEFAULT
;
548 PortsClassInstaller(IN DI_FUNCTION InstallFunction
,
549 IN HDEVINFO DeviceInfoSet
,
550 IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL
)
552 TRACE("PortsClassInstaller(%lu, %p, %p)\n",
553 InstallFunction
, DeviceInfoSet
, DeviceInfoData
);
555 switch (InstallFunction
)
557 case DIF_INSTALLDEVICE
:
558 return InstallPort(DeviceInfoSet
, DeviceInfoData
);
561 TRACE("Install function %u ignored\n", InstallFunction
);
562 return ERROR_DI_DO_DEFAULT
;