2 * PROJECT: Ports installer library
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: dll\win32\msports\comdb.c
5 * PURPOSE: COM port database
6 * COPYRIGHT: Copyright 2011 Eric Kohl
11 WINE_DEFAULT_DEBUG_CHANNEL(msports
);
13 #define BITS_PER_BYTE 8
24 ComDBClaimNextFreePort(IN HCOMDB hComDB
,
25 OUT LPDWORD ComNumber
)
36 TRACE("ComDBClaimNextFreePort(%p %p)\n", hComDB
, ComNumber
);
38 if (hComDB
== INVALID_HANDLE_VALUE
||
41 return ERROR_INVALID_PARAMETER
;
43 pComDB
= (PCOMDB
)hComDB
;
45 /* Wait for the mutex */
46 WaitForSingleObject(pComDB
->hMutex
, INFINITE
);
48 /* Get the required bitmap size */
49 lError
= RegQueryValueExW(pComDB
->hKey
,
55 if (lError
!= ERROR_SUCCESS
)
57 ERR("Failed to query the bitmap size!\n");
61 /* Allocate the bitmap */
62 pBitmap
= HeapAlloc(GetProcessHeap(),
67 ERR("Failed to allocate the bitmap!\n");
68 lError
= ERROR_NOT_ENOUGH_MEMORY
;
73 lError
= RegQueryValueExW(pComDB
->hKey
,
79 if (lError
!= ERROR_SUCCESS
)
82 lError
= ERROR_INVALID_PARAMETER
;
83 for (dwBitIndex
= 0; dwBitIndex
< (dwSize
* BITS_PER_BYTE
); dwBitIndex
++)
85 /* Calculate the byte index and a mask for the affected bit */
86 dwByteIndex
= dwBitIndex
/ BITS_PER_BYTE
;
87 cMask
= 1 << (dwBitIndex
% BITS_PER_BYTE
);
89 if ((pBitmap
[dwByteIndex
] & cMask
) == 0)
91 pBitmap
[dwByteIndex
] |= cMask
;
92 *ComNumber
= dwBitIndex
+ 1;
93 lError
= ERROR_SUCCESS
;
98 /* Save the bitmap if it was modified */
99 if (lError
== ERROR_SUCCESS
)
101 lError
= RegSetValueExW(pComDB
->hKey
,
110 /* Release the mutex */
111 ReleaseMutex(pComDB
->hMutex
);
113 /* Release the bitmap */
115 HeapFree(GetProcessHeap(), 0, pBitmap
);
123 ComDBClaimPort(IN HCOMDB hComDB
,
133 PBYTE pBitmap
= NULL
;
137 TRACE("ComDBClaimPort(%p %lu)\n", hComDB
, ComNumber
);
139 if (hComDB
== INVALID_HANDLE_VALUE
||
142 ComNumber
> COMDB_MAX_PORTS_ARBITRATED
)
143 return ERROR_INVALID_PARAMETER
;
145 pComDB
= (PCOMDB
)hComDB
;
147 /* Wait for the mutex */
148 WaitForSingleObject(pComDB
->hMutex
, INFINITE
);
150 /* Get the required bitmap size */
151 lError
= RegQueryValueExW(pComDB
->hKey
,
157 if (lError
!= ERROR_SUCCESS
)
159 ERR("Failed to query the bitmap size!\n");
163 /* Allocate the bitmap */
164 pBitmap
= HeapAlloc(GetProcessHeap(),
169 ERR("Failed to allocate the bitmap!\n");
170 lError
= ERROR_NOT_ENOUGH_MEMORY
;
174 /* Read the bitmap */
175 lError
= RegQueryValueExW(pComDB
->hKey
,
181 if (lError
!= ERROR_SUCCESS
)
184 /* Get the bit index */
185 dwBitIndex
= ComNumber
- 1;
187 /* Check if the bit to set fits into the bitmap */
188 if (dwBitIndex
>= (dwSize
* BITS_PER_BYTE
))
190 FIXME("Resize the bitmap\n");
192 lError
= ERROR_INVALID_PARAMETER
;
196 /* Calculate the byte index and a mask for the affected bit */
197 dwByteIndex
= dwBitIndex
/ BITS_PER_BYTE
;
198 cMask
= 1 << (dwBitIndex
% BITS_PER_BYTE
);
200 lError
= ERROR_SHARING_VIOLATION
;
202 /* Check if the bit is not set */
203 if ((pBitmap
[dwByteIndex
] & cMask
) == 0)
206 pBitmap
[dwByteIndex
] |= cMask
;
207 lError
= ERROR_SUCCESS
;
210 /* Save the bitmap if it was modified */
211 if (lError
== ERROR_SUCCESS
)
213 lError
= RegSetValueExW(pComDB
->hKey
,
222 /* Release the mutex */
223 ReleaseMutex(pComDB
->hMutex
);
225 /* Release the bitmap */
227 HeapFree(GetProcessHeap(), 0, pBitmap
);
235 ComDBClose(IN HCOMDB hComDB
)
239 TRACE("ComDBClose(%p)\n", hComDB
);
241 if (hComDB
== HCOMDB_INVALID_HANDLE_VALUE
||
243 return ERROR_INVALID_PARAMETER
;
245 pComDB
= (PCOMDB
)hComDB
;
247 /* Close the registry key */
248 if (pComDB
->hKey
!= NULL
)
249 RegCloseKey(pComDB
->hKey
);
251 /* Close the mutex */
252 if (pComDB
->hMutex
!= NULL
)
253 CloseHandle(pComDB
->hMutex
);
255 /* Release the database */
256 HeapFree(GetProcessHeap(), 0, pComDB
);
258 return ERROR_SUCCESS
;
264 ComDBGetCurrentPortUsage(IN HCOMDB hComDB
,
268 OUT LPDWORD MaxPortsReported
)
275 PBYTE pBitmap
= NULL
;
277 LONG lError
= ERROR_SUCCESS
;
279 if (hComDB
== INVALID_HANDLE_VALUE
||
281 (Buffer
== NULL
&& MaxPortsReported
== NULL
) ||
282 (ReportType
!= CDB_REPORT_BITS
&& ReportType
!= CDB_REPORT_BYTES
))
283 return ERROR_INVALID_PARAMETER
;
285 pComDB
= (PCOMDB
)hComDB
;
287 /* Wait for the mutex */
288 WaitForSingleObject(pComDB
->hMutex
, INFINITE
);
290 /* Get the required bitmap size */
291 lError
= RegQueryValueExW(pComDB
->hKey
,
297 if (lError
!= ERROR_SUCCESS
)
299 ERR("Failed to query the bitmap size!\n");
303 /* Allocate the bitmap */
304 pBitmap
= HeapAlloc(GetProcessHeap(),
309 ERR("Failed to allocate the bitmap!\n");
310 lError
= ERROR_NOT_ENOUGH_MEMORY
;
314 /* Read the bitmap */
315 lError
= RegQueryValueExW(pComDB
->hKey
,
321 if (lError
!= ERROR_SUCCESS
)
326 *MaxPortsReported
= dwSize
* BITS_PER_BYTE
;
330 if (ReportType
== CDB_REPORT_BITS
)
332 /* Clear the buffer */
333 memset(Buffer
, 0, BufferSize
);
337 min(dwSize
, BufferSize
));
339 if (MaxPortsReported
!= NULL
)
340 *MaxPortsReported
= min(dwSize
, BufferSize
) * BITS_PER_BYTE
;
342 else if (ReportType
== CDB_REPORT_BYTES
)
344 /* Clear the buffer */
345 memset(Buffer
, 0, BufferSize
);
347 for (dwBitIndex
= 0; dwBitIndex
< min(dwSize
* BITS_PER_BYTE
, BufferSize
); dwBitIndex
++)
349 /* Calculate the byte index and a mask for the affected bit */
350 dwByteIndex
= dwBitIndex
/ BITS_PER_BYTE
;
351 cMask
= 1 << (dwBitIndex
% BITS_PER_BYTE
);
353 if ((pBitmap
[dwByteIndex
] & cMask
) != 0)
354 Buffer
[dwBitIndex
] = 1;
360 /* Release the mutex */
361 ReleaseMutex(pComDB
->hMutex
);
363 /* Release the bitmap */
364 HeapFree(GetProcessHeap(), 0, pBitmap
);
372 ComDBOpen(OUT HCOMDB
*phComDB
)
381 TRACE("ComDBOpen(%p)\n", phComDB
);
383 /* Allocate a new database */
384 pComDB
= HeapAlloc(GetProcessHeap(),
389 ERR("Failed to allocate the database!\n");
390 *phComDB
= HCOMDB_INVALID_HANDLE_VALUE
;
391 return ERROR_ACCESS_DENIED
;
394 /* Create a mutex to protect the database */
395 pComDB
->hMutex
= CreateMutexW(NULL
,
398 if (pComDB
->hMutex
== NULL
)
400 ERR("Failed to create the mutex!\n");
401 HeapFree(GetProcessHeap(), 0, pComDB
);
402 *phComDB
= HCOMDB_INVALID_HANDLE_VALUE
;
403 return ERROR_ACCESS_DENIED
;
406 /* Wait for the mutex */
407 WaitForSingleObject(pComDB
->hMutex
, INFINITE
);
409 /* Create or open the database key */
410 lError
= RegCreateKeyExW(HKEY_LOCAL_MACHINE
,
411 L
"System\\CurrentControlSet\\Control\\COM Name Arbiter",
419 if (lError
!= ERROR_SUCCESS
)
422 /* Get the required bitmap size */
423 lError
= RegQueryValueExW(pComDB
->hKey
,
429 if (lError
== ERROR_FILE_NOT_FOUND
)
431 /* Allocate a new bitmap */
432 dwSize
= COMDB_MIN_PORTS_ARBITRATED
/ BITS_PER_BYTE
;
433 pBitmap
= HeapAlloc(GetProcessHeap(),
438 ERR("Failed to allocate the bitmap!\n");
439 lError
= ERROR_ACCESS_DENIED
;
443 /* Write the bitmap to the registry */
444 lError
= RegSetValueExW(pComDB
->hKey
,
451 HeapFree(GetProcessHeap(), 0, pBitmap
);
455 /* Release the mutex */
456 ReleaseMutex(pComDB
->hMutex
);
458 if (lError
!= ERROR_SUCCESS
)
460 /* Clean up in case of failure */
461 if (pComDB
->hKey
!= NULL
)
462 RegCloseKey(pComDB
->hKey
);
464 if (pComDB
->hMutex
!= NULL
)
465 CloseHandle(pComDB
->hMutex
);
467 HeapFree(GetProcessHeap(), 0, pComDB
);
469 *phComDB
= HCOMDB_INVALID_HANDLE_VALUE
;
473 /* Return the database handle */
474 *phComDB
= (HCOMDB
)pComDB
;
477 TRACE("done (Error %lu)\n", lError
);
485 ComDBReleasePort(IN HCOMDB hComDB
,
493 PBYTE pBitmap
= NULL
;
497 TRACE("ComDBReleasePort(%p %lu)\n", hComDB
, ComNumber
);
499 if (hComDB
== INVALID_HANDLE_VALUE
||
501 ComNumber
> COMDB_MAX_PORTS_ARBITRATED
)
502 return ERROR_INVALID_PARAMETER
;
504 pComDB
= (PCOMDB
)hComDB
;
506 /* Wait for the mutex */
507 WaitForSingleObject(pComDB
->hMutex
, INFINITE
);
509 /* Get the required bitmap size */
510 lError
= RegQueryValueExW(pComDB
->hKey
,
516 if (lError
!= ERROR_SUCCESS
)
518 ERR("Failed to query the bitmap size!\n");
522 /* Allocate the bitmap */
523 pBitmap
= HeapAlloc(GetProcessHeap(),
528 ERR("Failed to allocate the bitmap!\n");
529 lError
= ERROR_NOT_ENOUGH_MEMORY
;
533 /* Read the bitmap */
534 lError
= RegQueryValueExW(pComDB
->hKey
,
540 if (lError
!= ERROR_SUCCESS
)
543 /* Get the bit index */
544 dwBitIndex
= ComNumber
- 1;
546 /* Check if the bit to set fits into the bitmap */
547 if (dwBitIndex
>= (dwSize
* BITS_PER_BYTE
))
549 lError
= ERROR_INVALID_PARAMETER
;
553 /* Calculate the byte index and a mask for the affected bit */
554 dwByteIndex
= dwBitIndex
/ BITS_PER_BYTE
;
555 cMask
= 1 << (dwBitIndex
% BITS_PER_BYTE
);
557 /* Release the port */
558 pBitmap
[dwByteIndex
] &= ~cMask
;
560 lError
= RegSetValueExW(pComDB
->hKey
,
568 /* Release the mutex */
569 ReleaseMutex(pComDB
->hMutex
);
571 /* Release the bitmap */
573 HeapFree(GetProcessHeap(), 0, pBitmap
);
581 ComDBResizeDatabase(IN HCOMDB hComDB
,
584 FIXME("ComDBResizeDatabase(%p %lu)\n", hComDB
, NewSize
);
585 return ERROR_CALL_NOT_IMPLEMENTED
;