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
12 #include <wine/debug.h>
14 WINE_DEFAULT_DEBUG_CHANNEL(msports
);
16 #define BITS_PER_BYTE 8
27 ComDBClaimNextFreePort(IN HCOMDB hComDB
,
28 OUT LPDWORD ComNumber
)
39 TRACE("ComDBClaimNextFreePort(%p %p)\n", hComDB
, ComNumber
);
41 if (hComDB
== INVALID_HANDLE_VALUE
||
44 return ERROR_INVALID_PARAMETER
;
46 pComDB
= (PCOMDB
)hComDB
;
48 /* Wait for the mutex */
49 WaitForSingleObject(pComDB
->hMutex
, INFINITE
);
51 /* Get the required bitmap size */
52 lError
= RegQueryValueExW(pComDB
->hKey
,
58 if (lError
!= ERROR_SUCCESS
)
60 ERR("Failed to query the bitmap size!\n");
64 /* Allocate the bitmap */
65 pBitmap
= HeapAlloc(GetProcessHeap(),
70 ERR("Failed to allocate the bitmap!\n");
71 lError
= ERROR_NOT_ENOUGH_MEMORY
;
76 lError
= RegQueryValueExW(pComDB
->hKey
,
82 if (lError
!= ERROR_SUCCESS
)
85 lError
= ERROR_INVALID_PARAMETER
;
86 for (dwBitIndex
= 0; dwBitIndex
< (dwSize
* BITS_PER_BYTE
); dwBitIndex
++)
88 /* Calculate the byte index and a mask for the affected bit */
89 dwByteIndex
= dwBitIndex
/ BITS_PER_BYTE
;
90 cMask
= 1 << (dwBitIndex
% BITS_PER_BYTE
);
92 if ((pBitmap
[dwByteIndex
] & cMask
) == 0)
94 pBitmap
[dwByteIndex
] |= cMask
;
95 *ComNumber
= dwBitIndex
+ 1;
96 lError
= ERROR_SUCCESS
;
101 /* Save the bitmap if it was modified */
102 if (lError
== ERROR_SUCCESS
)
104 lError
= RegSetValueExW(pComDB
->hKey
,
113 /* Release the mutex */
114 ReleaseMutex(pComDB
->hMutex
);
116 /* Release the bitmap */
118 HeapFree(GetProcessHeap(), 0, pBitmap
);
126 ComDBClaimPort(IN HCOMDB hComDB
,
136 PBYTE pBitmap
= NULL
;
140 TRACE("ComDBClaimPort(%p %lu)\n", hComDB
, ComNumber
);
142 if (hComDB
== INVALID_HANDLE_VALUE
||
145 ComNumber
> COMDB_MAX_PORTS_ARBITRATED
)
146 return ERROR_INVALID_PARAMETER
;
148 pComDB
= (PCOMDB
)hComDB
;
150 /* Wait for the mutex */
151 WaitForSingleObject(pComDB
->hMutex
, INFINITE
);
153 /* Get the required bitmap size */
154 lError
= RegQueryValueExW(pComDB
->hKey
,
160 if (lError
!= ERROR_SUCCESS
)
162 ERR("Failed to query the bitmap size!\n");
166 /* Allocate the bitmap */
167 pBitmap
= HeapAlloc(GetProcessHeap(),
172 ERR("Failed to allocate the bitmap!\n");
173 lError
= ERROR_NOT_ENOUGH_MEMORY
;
177 /* Read the bitmap */
178 lError
= RegQueryValueExW(pComDB
->hKey
,
184 if (lError
!= ERROR_SUCCESS
)
187 /* Get the bit index */
188 dwBitIndex
= ComNumber
- 1;
190 /* Check if the bit to set fits into the bitmap */
191 if (dwBitIndex
>= (dwSize
* BITS_PER_BYTE
))
193 FIXME("Resize the bitmap\n");
195 lError
= ERROR_INVALID_PARAMETER
;
199 /* Calculate the byte index and a mask for the affected bit */
200 dwByteIndex
= dwBitIndex
/ BITS_PER_BYTE
;
201 cMask
= 1 << (dwBitIndex
% BITS_PER_BYTE
);
203 lError
= ERROR_SHARING_VIOLATION
;
205 /* Check if the bit is not set */
206 if ((pBitmap
[dwByteIndex
] & cMask
) == 0)
209 pBitmap
[dwByteIndex
] |= cMask
;
210 lError
= ERROR_SUCCESS
;
213 /* Save the bitmap if it was modified */
214 if (lError
== ERROR_SUCCESS
)
216 lError
= RegSetValueExW(pComDB
->hKey
,
225 /* Release the mutex */
226 ReleaseMutex(pComDB
->hMutex
);
228 /* Release the bitmap */
230 HeapFree(GetProcessHeap(), 0, pBitmap
);
238 ComDBClose(IN HCOMDB hComDB
)
242 TRACE("ComDBClose(%p)\n", hComDB
);
244 if (hComDB
== HCOMDB_INVALID_HANDLE_VALUE
||
246 return ERROR_INVALID_PARAMETER
;
248 pComDB
= (PCOMDB
)hComDB
;
250 /* Close the registry key */
251 if (pComDB
->hKey
!= NULL
)
252 RegCloseKey(pComDB
->hKey
);
254 /* Close the mutex */
255 if (pComDB
->hMutex
!= NULL
)
256 CloseHandle(pComDB
->hMutex
);
258 /* Release the database */
259 HeapFree(GetProcessHeap(), 0, pComDB
);
261 return ERROR_SUCCESS
;
267 ComDBGetCurrentPortUsage(IN HCOMDB hComDB
,
271 OUT LPDWORD MaxPortsReported
)
278 PBYTE pBitmap
= NULL
;
280 LONG lError
= ERROR_SUCCESS
;
282 if (hComDB
== INVALID_HANDLE_VALUE
||
284 (Buffer
== NULL
&& MaxPortsReported
== NULL
) ||
285 (ReportType
!= CDB_REPORT_BITS
&& ReportType
!= CDB_REPORT_BYTES
))
286 return ERROR_INVALID_PARAMETER
;
288 pComDB
= (PCOMDB
)hComDB
;
290 /* Wait for the mutex */
291 WaitForSingleObject(pComDB
->hMutex
, INFINITE
);
293 /* Get the required bitmap size */
294 lError
= RegQueryValueExW(pComDB
->hKey
,
300 if (lError
!= ERROR_SUCCESS
)
302 ERR("Failed to query the bitmap size!\n");
306 /* Allocate the bitmap */
307 pBitmap
= HeapAlloc(GetProcessHeap(),
312 ERR("Failed to allocate the bitmap!\n");
313 lError
= ERROR_NOT_ENOUGH_MEMORY
;
317 /* Read the bitmap */
318 lError
= RegQueryValueExW(pComDB
->hKey
,
324 if (lError
!= ERROR_SUCCESS
)
329 *MaxPortsReported
= dwSize
* BITS_PER_BYTE
;
333 if (ReportType
== CDB_REPORT_BITS
)
335 /* Clear the buffer */
336 memset(Buffer
, 0, BufferSize
);
340 min(dwSize
, BufferSize
));
342 if (MaxPortsReported
!= NULL
)
343 *MaxPortsReported
= min(dwSize
, BufferSize
) * BITS_PER_BYTE
;
345 else if (ReportType
== CDB_REPORT_BYTES
)
347 /* Clear the buffer */
348 memset(Buffer
, 0, BufferSize
);
350 for (dwBitIndex
= 0; dwBitIndex
< min(dwSize
* BITS_PER_BYTE
, BufferSize
); dwBitIndex
++)
352 /* Calculate the byte index and a mask for the affected bit */
353 dwByteIndex
= dwBitIndex
/ BITS_PER_BYTE
;
354 cMask
= 1 << (dwBitIndex
% BITS_PER_BYTE
);
356 if ((pBitmap
[dwByteIndex
] & cMask
) != 0)
357 Buffer
[dwBitIndex
] = 1;
363 /* Release the mutex */
364 ReleaseMutex(pComDB
->hMutex
);
366 /* Release the bitmap */
367 HeapFree(GetProcessHeap(), 0, pBitmap
);
375 ComDBOpen(OUT HCOMDB
*phComDB
)
384 TRACE("ComDBOpen(%p)\n", phComDB
);
386 /* Allocate a new database */
387 pComDB
= HeapAlloc(GetProcessHeap(),
392 ERR("Failed to allocate the database!\n");
393 *phComDB
= HCOMDB_INVALID_HANDLE_VALUE
;
394 return ERROR_ACCESS_DENIED
;
397 /* Create a mutex to protect the database */
398 pComDB
->hMutex
= CreateMutexW(NULL
,
401 if (pComDB
->hMutex
== NULL
)
403 ERR("Failed to create the mutex!\n");
404 HeapFree(GetProcessHeap(), 0, pComDB
);
405 *phComDB
= HCOMDB_INVALID_HANDLE_VALUE
;
406 return ERROR_ACCESS_DENIED
;
409 /* Wait for the mutex */
410 WaitForSingleObject(pComDB
->hMutex
, INFINITE
);
412 /* Create or open the database key */
413 lError
= RegCreateKeyExW(HKEY_LOCAL_MACHINE
,
414 L
"System\\CurrentControlSet\\Control\\COM Name Arbiter",
422 if (lError
!= ERROR_SUCCESS
)
425 /* Get the required bitmap size */
426 lError
= RegQueryValueExW(pComDB
->hKey
,
432 if (lError
== ERROR_FILE_NOT_FOUND
)
434 /* Allocate a new bitmap */
435 dwSize
= COMDB_MIN_PORTS_ARBITRATED
/ BITS_PER_BYTE
;
436 pBitmap
= HeapAlloc(GetProcessHeap(),
441 ERR("Failed to allocate the bitmap!\n");
442 lError
= ERROR_ACCESS_DENIED
;
446 /* Write the bitmap to the registry */
447 lError
= RegSetValueExW(pComDB
->hKey
,
454 HeapFree(GetProcessHeap(), 0, pBitmap
);
458 /* Release the mutex */
459 ReleaseMutex(pComDB
->hMutex
);
461 if (lError
!= ERROR_SUCCESS
)
463 /* Clean up in case of failure */
464 if (pComDB
->hKey
!= NULL
)
465 RegCloseKey(pComDB
->hKey
);
467 if (pComDB
->hMutex
!= NULL
)
468 CloseHandle(pComDB
->hMutex
);
470 HeapFree(GetProcessHeap(), 0, pComDB
);
472 *phComDB
= HCOMDB_INVALID_HANDLE_VALUE
;
476 /* Return the database handle */
477 *phComDB
= (HCOMDB
)pComDB
;
480 TRACE("done (Error %lu)\n", lError
);
488 ComDBReleasePort(IN HCOMDB hComDB
,
496 PBYTE pBitmap
= NULL
;
500 TRACE("ComDBReleasePort(%p %lu)\n", hComDB
, ComNumber
);
502 if (hComDB
== INVALID_HANDLE_VALUE
||
504 ComNumber
> COMDB_MAX_PORTS_ARBITRATED
)
505 return ERROR_INVALID_PARAMETER
;
507 pComDB
= (PCOMDB
)hComDB
;
509 /* Wait for the mutex */
510 WaitForSingleObject(pComDB
->hMutex
, INFINITE
);
512 /* Get the required bitmap size */
513 lError
= RegQueryValueExW(pComDB
->hKey
,
519 if (lError
!= ERROR_SUCCESS
)
521 ERR("Failed to query the bitmap size!\n");
525 /* Allocate the bitmap */
526 pBitmap
= HeapAlloc(GetProcessHeap(),
531 ERR("Failed to allocate the bitmap!\n");
532 lError
= ERROR_NOT_ENOUGH_MEMORY
;
536 /* Read the bitmap */
537 lError
= RegQueryValueExW(pComDB
->hKey
,
543 if (lError
!= ERROR_SUCCESS
)
546 /* Get the bit index */
547 dwBitIndex
= ComNumber
- 1;
549 /* Check if the bit to set fits into the bitmap */
550 if (dwBitIndex
>= (dwSize
* BITS_PER_BYTE
))
552 lError
= ERROR_INVALID_PARAMETER
;
556 /* Calculate the byte index and a mask for the affected bit */
557 dwByteIndex
= dwBitIndex
/ BITS_PER_BYTE
;
558 cMask
= 1 << (dwBitIndex
% BITS_PER_BYTE
);
560 /* Release the port */
561 pBitmap
[dwByteIndex
] &= ~cMask
;
563 lError
= RegSetValueExW(pComDB
->hKey
,
571 /* Release the mutex */
572 ReleaseMutex(pComDB
->hMutex
);
574 /* Release the bitmap */
576 HeapFree(GetProcessHeap(), 0, pBitmap
);
584 ComDBResizeDatabase(IN HCOMDB hComDB
,
587 FIXME("ComDBResizeDatabase(%p %lu)\n", hComDB
, NewSize
);
588 return ERROR_CALL_NOT_IMPLEMENTED
;