ReactOS 0.4.15-dev-7991-ge77da17
comdb.c
Go to the documentation of this file.
1/*
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
7 */
8
9#include "precomp.h"
10
11#define BITS_PER_BYTE 8
12#define BITMAP_SIZE_INCREMENT 0x400
13#define BITMAP_SIZE_INVALID_BITS 0x3FF
14
15typedef struct _COMDB
16{
20
21
22LONG
25 OUT LPDWORD ComNumber)
26{
27 PCOMDB pComDB;
28 DWORD dwBitIndex;
29 DWORD dwByteIndex;
31 DWORD dwType;
32 PBYTE pBitmap = NULL;
33 BYTE cMask;
34 LONG lError;
35
36 TRACE("ComDBClaimNextFreePort(%p %p)\n", hComDB, ComNumber);
37
38 if (hComDB == INVALID_HANDLE_VALUE ||
39 hComDB == NULL ||
40 ComNumber == NULL)
42
43 pComDB = (PCOMDB)hComDB;
44
45 /* Wait for the mutex */
47
48 /* Get the required bitmap size */
49 lError = RegQueryValueExW(pComDB->hKey,
50 L"ComDB",
51 NULL,
52 &dwType,
53 NULL,
54 &dwSize);
55 if (lError != ERROR_SUCCESS)
56 {
57 ERR("Failed to query the bitmap size!\n");
58 goto done;
59 }
60
61 /* Allocate the bitmap */
62 pBitmap = HeapAlloc(GetProcessHeap(),
64 dwSize);
65 if (pBitmap == NULL)
66 {
67 ERR("Failed to allocate the bitmap!\n");
69 goto done;
70 }
71
72 /* Read the bitmap */
73 lError = RegQueryValueExW(pComDB->hKey,
74 L"ComDB",
75 NULL,
76 &dwType,
77 pBitmap,
78 &dwSize);
79 if (lError != ERROR_SUCCESS)
80 goto done;
81
83 for (dwBitIndex = 0; dwBitIndex < (dwSize * BITS_PER_BYTE); dwBitIndex++)
84 {
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);
88
89 if ((pBitmap[dwByteIndex] & cMask) == 0)
90 {
91 pBitmap[dwByteIndex] |= cMask;
92 *ComNumber = dwBitIndex + 1;
93 lError = ERROR_SUCCESS;
94 break;
95 }
96 }
97
98 /* Save the bitmap if it was modified */
99 if (lError == ERROR_SUCCESS)
100 {
101 lError = RegSetValueExW(pComDB->hKey,
102 L"ComDB",
103 0,
105 pBitmap,
106 dwSize);
107 }
108
109done:;
110 /* Release the mutex */
111 ReleaseMutex(pComDB->hMutex);
112
113 /* Release the bitmap */
114 if (pBitmap != NULL)
115 HeapFree(GetProcessHeap(), 0, pBitmap);
116
117 return lError;
118}
119
120
121LONG
122WINAPI
123ComDBClaimPort(IN HCOMDB hComDB,
124 IN DWORD ComNumber,
125 IN BOOL ForceClaim,
126 OUT PBOOL Forced)
127{
128 PCOMDB pComDB;
129 DWORD dwBitIndex;
130 DWORD dwByteIndex;
131 DWORD dwType;
133 PBYTE pBitmap = NULL;
134 BYTE cMask;
135 LONG lError;
136
137 TRACE("ComDBClaimPort(%p %lu)\n", hComDB, ComNumber);
138
139 if (hComDB == INVALID_HANDLE_VALUE ||
140 hComDB == NULL ||
141 ComNumber == 0 ||
142 ComNumber > COMDB_MAX_PORTS_ARBITRATED)
144
145 pComDB = (PCOMDB)hComDB;
146
147 /* Wait for the mutex */
149
150 /* Get the required bitmap size */
151 lError = RegQueryValueExW(pComDB->hKey,
152 L"ComDB",
153 NULL,
154 &dwType,
155 NULL,
156 &dwSize);
157 if (lError != ERROR_SUCCESS)
158 {
159 ERR("Failed to query the bitmap size!\n");
160 goto done;
161 }
162
163 /* Allocate the bitmap */
164 pBitmap = HeapAlloc(GetProcessHeap(),
166 dwSize);
167 if (pBitmap == NULL)
168 {
169 ERR("Failed to allocate the bitmap!\n");
171 goto done;
172 }
173
174 /* Read the bitmap */
175 lError = RegQueryValueExW(pComDB->hKey,
176 L"ComDB",
177 NULL,
178 &dwType,
179 pBitmap,
180 &dwSize);
181 if (lError != ERROR_SUCCESS)
182 goto done;
183
184 /* Get the bit index */
185 dwBitIndex = ComNumber - 1;
186
187 /* Check if the bit to set fits into the bitmap */
188 if (dwBitIndex >= (dwSize * BITS_PER_BYTE))
189 {
190 FIXME("Resize the bitmap\n");
191
193 goto done;
194 }
195
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);
199
201
202 /* Check if the bit is not set */
203 if ((pBitmap[dwByteIndex] & cMask) == 0)
204 {
205 /* Set the bit */
206 pBitmap[dwByteIndex] |= cMask;
207 lError = ERROR_SUCCESS;
208 }
209
210 /* Save the bitmap if it was modified */
211 if (lError == ERROR_SUCCESS)
212 {
213 lError = RegSetValueExW(pComDB->hKey,
214 L"ComDB",
215 0,
217 pBitmap,
218 dwSize);
219 }
220
221done:
222 /* Release the mutex */
223 ReleaseMutex(pComDB->hMutex);
224
225 /* Release the bitmap */
226 if (pBitmap != NULL)
227 HeapFree(GetProcessHeap(), 0, pBitmap);
228
229 return lError;
230}
231
232
233LONG
234WINAPI
235ComDBClose(IN HCOMDB hComDB)
236{
237 PCOMDB pComDB;
238
239 TRACE("ComDBClose(%p)\n", hComDB);
240
241 if (hComDB == HCOMDB_INVALID_HANDLE_VALUE ||
242 hComDB == NULL)
244
245 pComDB = (PCOMDB)hComDB;
246
247 /* Close the registry key */
248 if (pComDB->hKey != NULL)
249 RegCloseKey(pComDB->hKey);
250
251 /* Close the mutex */
252 if (pComDB->hMutex != NULL)
253 CloseHandle(pComDB->hMutex);
254
255 /* Release the database */
256 HeapFree(GetProcessHeap(), 0, pComDB);
257
258 return ERROR_SUCCESS;
259}
260
261
262LONG
263WINAPI
267 IN DWORD ReportType,
268 OUT LPDWORD MaxPortsReported)
269{
270 PCOMDB pComDB;
271 DWORD dwBitIndex;
272 DWORD dwByteIndex;
273 DWORD dwType;
275 PBYTE pBitmap = NULL;
276 BYTE cMask;
277 LONG lError = ERROR_SUCCESS;
278
279 TRACE("ComDBGetCurrentPortUsage(%p %p %lu %lu %p)\n",
280 hComDB, Buffer, BufferSize, ReportType, MaxPortsReported);
281
282 if (hComDB == INVALID_HANDLE_VALUE ||
283 hComDB == NULL ||
284 (Buffer == NULL && MaxPortsReported == NULL) ||
285 (ReportType != CDB_REPORT_BITS && ReportType != CDB_REPORT_BYTES))
287
288 pComDB = (PCOMDB)hComDB;
289
290 /* Wait for the mutex */
292
293 /* Get the required bitmap size */
294 lError = RegQueryValueExW(pComDB->hKey,
295 L"ComDB",
296 NULL,
297 &dwType,
298 NULL,
299 &dwSize);
300 if (lError != ERROR_SUCCESS)
301 {
302 ERR("Failed to query the bitmap size!\n");
303 goto done;
304 }
305
306 /* Allocate the bitmap */
307 pBitmap = HeapAlloc(GetProcessHeap(),
309 dwSize);
310 if (pBitmap == NULL)
311 {
312 ERR("Failed to allocate the bitmap!\n");
314 goto done;
315 }
316
317 /* Read the bitmap */
318 lError = RegQueryValueExW(pComDB->hKey,
319 L"ComDB",
320 NULL,
321 &dwType,
322 pBitmap,
323 &dwSize);
324 if (lError != ERROR_SUCCESS)
325 goto done;
326
327 if (Buffer == NULL)
328 {
329 *MaxPortsReported = dwSize * BITS_PER_BYTE;
330 }
331 else
332 {
333 if (ReportType == CDB_REPORT_BITS)
334 {
335 /* Clear the buffer */
337
339 pBitmap,
341
342 if (MaxPortsReported != NULL)
343 *MaxPortsReported = min(dwSize, BufferSize) * BITS_PER_BYTE;
344 }
345 else if (ReportType == CDB_REPORT_BYTES)
346 {
347 /* Clear the buffer */
349
350 for (dwBitIndex = 0; dwBitIndex < min(dwSize * BITS_PER_BYTE, BufferSize); dwBitIndex++)
351 {
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);
355
356 if ((pBitmap[dwByteIndex] & cMask) != 0)
357 Buffer[dwBitIndex] = 1;
358 }
359 }
360 }
361
362done:;
363 /* Release the mutex */
364 ReleaseMutex(pComDB->hMutex);
365
366 /* Release the bitmap */
367 HeapFree(GetProcessHeap(), 0, pBitmap);
368
369 return lError;
370}
371
372
373LONG
374WINAPI
375ComDBOpen(OUT HCOMDB *phComDB)
376{
377 PCOMDB pComDB;
378 DWORD dwDisposition;
379 DWORD dwType;
381 PBYTE pBitmap;
382 LONG lError;
383
384 TRACE("ComDBOpen(%p)\n", phComDB);
385
386 /* Allocate a new database */
387 pComDB = HeapAlloc(GetProcessHeap(),
389 sizeof(COMDB));
390 if (pComDB == NULL)
391 {
392 ERR("Failed to allocate the database!\n");
394 return ERROR_ACCESS_DENIED;
395 }
396
397 /* Create a mutex to protect the database */
398 pComDB->hMutex = CreateMutexW(NULL,
399 FALSE,
400 L"ComDBMutex");
401 if (pComDB->hMutex == NULL)
402 {
403 ERR("Failed to create the mutex!\n");
404 HeapFree(GetProcessHeap(), 0, pComDB);
406 return ERROR_ACCESS_DENIED;
407 }
408
409 /* Wait for the mutex */
411
412 /* Create or open the database key */
414 L"System\\CurrentControlSet\\Control\\COM Name Arbiter",
415 0,
416 NULL,
417 0,
419 NULL,
420 &pComDB->hKey,
421 &dwDisposition);
422 if (lError != ERROR_SUCCESS)
423 goto done;
424
425 /* Get the required bitmap size */
426 lError = RegQueryValueExW(pComDB->hKey,
427 L"ComDB",
428 NULL,
429 &dwType,
430 NULL,
431 &dwSize);
432 if (lError == ERROR_FILE_NOT_FOUND)
433 {
434 /* Allocate a new bitmap */
436 pBitmap = HeapAlloc(GetProcessHeap(),
438 dwSize);
439 if (pBitmap == NULL)
440 {
441 ERR("Failed to allocate the bitmap!\n");
442 lError = ERROR_ACCESS_DENIED;
443 goto done;
444 }
445
446 /* Write the bitmap to the registry */
447 lError = RegSetValueExW(pComDB->hKey,
448 L"ComDB",
449 0,
451 pBitmap,
452 dwSize);
453
454 HeapFree(GetProcessHeap(), 0, pBitmap);
455 }
456
457done:;
458 /* Release the mutex */
459 ReleaseMutex(pComDB->hMutex);
460
461 if (lError != ERROR_SUCCESS)
462 {
463 /* Clean up in case of failure */
464 if (pComDB->hKey != NULL)
465 RegCloseKey(pComDB->hKey);
466
467 if (pComDB->hMutex != NULL)
468 CloseHandle(pComDB->hMutex);
469
470 HeapFree(GetProcessHeap(), 0, pComDB);
471
473 }
474 else
475 {
476 /* Return the database handle */
477 *phComDB = (HCOMDB)pComDB;
478 }
479
480 TRACE("done (Error %lu)\n", lError);
481
482 return lError;
483}
484
485
486LONG
487WINAPI
488ComDBReleasePort(IN HCOMDB hComDB,
489 IN DWORD ComNumber)
490{
491 PCOMDB pComDB;
492 DWORD dwByteIndex;
493 DWORD dwBitIndex;
494 DWORD dwType;
496 PBYTE pBitmap = NULL;
497 BYTE cMask;
498 LONG lError;
499
500 TRACE("ComDBReleasePort(%p %lu)\n", hComDB, ComNumber);
501
502 if (hComDB == INVALID_HANDLE_VALUE ||
503 ComNumber == 0 ||
504 ComNumber > COMDB_MAX_PORTS_ARBITRATED)
506
507 pComDB = (PCOMDB)hComDB;
508
509 /* Wait for the mutex */
511
512 /* Get the required bitmap size */
513 lError = RegQueryValueExW(pComDB->hKey,
514 L"ComDB",
515 NULL,
516 &dwType,
517 NULL,
518 &dwSize);
519 if (lError != ERROR_SUCCESS)
520 {
521 ERR("Failed to query the bitmap size!\n");
522 goto done;
523 }
524
525 /* Allocate the bitmap */
526 pBitmap = HeapAlloc(GetProcessHeap(),
528 dwSize);
529 if (pBitmap == NULL)
530 {
531 ERR("Failed to allocate the bitmap!\n");
533 goto done;
534 }
535
536 /* Read the bitmap */
537 lError = RegQueryValueExW(pComDB->hKey,
538 L"ComDB",
539 NULL,
540 &dwType,
541 pBitmap,
542 &dwSize);
543 if (lError != ERROR_SUCCESS)
544 goto done;
545
546 /* Get the bit index */
547 dwBitIndex = ComNumber - 1;
548
549 /* Check if the bit to set fits into the bitmap */
550 if (dwBitIndex >= (dwSize * BITS_PER_BYTE))
551 {
553 goto done;
554 }
555
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);
559
560 /* Release the port */
561 pBitmap[dwByteIndex] &= ~cMask;
562
563 lError = RegSetValueExW(pComDB->hKey,
564 L"ComDB",
565 0,
567 pBitmap,
568 dwSize);
569
570done:;
571 /* Release the mutex */
572 ReleaseMutex(pComDB->hMutex);
573
574 /* Release the bitmap */
575 if (pBitmap != NULL)
576 HeapFree(GetProcessHeap(), 0, pBitmap);
577
578 return lError;
579}
580
581
582LONG
583WINAPI
586{
587 PCOMDB pComDB;
588 PBYTE pBitmap = NULL;
590 DWORD dwNewSize;
591 DWORD dwType;
592 LONG lError;
593
594 TRACE("ComDBResizeDatabase(%p %lu)\n", hComDB, NewSize);
595
596 if (hComDB == INVALID_HANDLE_VALUE ||
597 hComDB == NULL ||
600
601 pComDB = (PCOMDB)hComDB;
602
603 /* Wait for the mutex */
605
606 /* Get the required bitmap size */
607 lError = RegQueryValueExW(pComDB->hKey,
608 L"ComDB",
609 NULL,
610 &dwType,
611 NULL,
612 &dwSize);
613 if (lError != ERROR_SUCCESS)
614 goto done;
615
616 /* Check the size limits */
619 {
620 lError = ERROR_BAD_LENGTH;
621 goto done;
622 }
623
624 /* Calculate the new bitmap size */
625 dwNewSize = NewSize / BITS_PER_BYTE;
626
627 /* Allocate the new bitmap */
628 pBitmap = HeapAlloc(GetProcessHeap(),
630 dwSize);
631 if (pBitmap == NULL)
632 {
633 ERR("Failed to allocate the bitmap!\n");
634 lError = ERROR_ACCESS_DENIED;
635 goto done;
636 }
637
638 /* Read the current bitmap */
639 lError = RegQueryValueExW(pComDB->hKey,
640 L"ComDB",
641 NULL,
642 &dwType,
643 pBitmap,
644 &dwSize);
645 if (lError != ERROR_SUCCESS)
646 goto done;
647
648 /* Write the new bitmap */
649 lError = RegSetValueExW(pComDB->hKey,
650 L"ComDB",
651 0,
653 pBitmap,
654 dwNewSize);
655
656done:;
657 /* Release the mutex */
658 ReleaseMutex(pComDB->hMutex);
659
660 if (pBitmap != NULL)
661 HeapFree(GetProcessHeap(), 0, pBitmap);
662
663 return lError;
664}
665
666/* EOF */
#define FIXME(fmt,...)
Definition: debug.h:111
#define ERR(fmt,...)
Definition: debug.h:110
#define RegCloseKey(hKey)
Definition: registry.h:49
Definition: bufpool.h:45
LONG WINAPI ComDBReleasePort(IN HCOMDB hComDB, IN DWORD ComNumber)
Definition: comdb.c:488
LONG WINAPI ComDBGetCurrentPortUsage(IN HCOMDB hComDB, OUT PBYTE Buffer, IN DWORD BufferSize, IN DWORD ReportType, OUT LPDWORD MaxPortsReported)
Definition: comdb.c:264
#define BITS_PER_BYTE
Definition: comdb.c:11
struct _COMDB COMDB
LONG WINAPI ComDBClose(IN HCOMDB hComDB)
Definition: comdb.c:235
LONG WINAPI ComDBClaimPort(IN HCOMDB hComDB, IN DWORD ComNumber, IN BOOL ForceClaim, OUT PBOOL Forced)
Definition: comdb.c:123
struct _COMDB * PCOMDB
LONG WINAPI ComDBOpen(OUT HCOMDB *phComDB)
Definition: comdb.c:375
LONG WINAPI ComDBClaimNextFreePort(IN HCOMDB hComDB, OUT LPDWORD ComNumber)
Definition: comdb.c:24
LONG WINAPI ComDBResizeDatabase(IN HCOMDB hComDB, IN DWORD NewSize)
Definition: comdb.c:584
#define BITMAP_SIZE_INVALID_BITS
Definition: comdb.c:13
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
LONG WINAPI RegCreateKeyExW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey, _In_ DWORD Reserved, _In_opt_ LPWSTR lpClass, _In_ DWORD dwOptions, _In_ REGSAM samDesired, _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes, _Out_ PHKEY phkResult, _Out_opt_ LPDWORD lpdwDisposition)
Definition: reg.c:1096
LONG WINAPI RegSetValueExW(_In_ HKEY hKey, _In_ LPCWSTR lpValueName, _In_ DWORD Reserved, _In_ DWORD dwType, _In_ CONST BYTE *lpData, _In_ DWORD cbData)
Definition: reg.c:4882
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4103
#define CloseHandle
Definition: compat.h:739
#define GetProcessHeap()
Definition: compat.h:736
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define HeapAlloc
Definition: compat.h:733
#define HeapFree(x, y, z)
Definition: compat.h:735
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
#define INFINITE
Definition: serial.h:102
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
_Must_inspect_result_ _In_ USHORT NewSize
Definition: fltkernel.h:975
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:56
#define min(a, b)
Definition: monoChain.cc:55
#define HCOMDB_INVALID_HANDLE_VALUE
Definition: msports.h:10
#define CDB_REPORT_BYTES
Definition: msports.h:18
#define CDB_REPORT_BITS
Definition: msports.h:17
#define COMDB_MAX_PORTS_ARBITRATED
Definition: msports.h:14
#define COMDB_MIN_PORTS_ARBITRATED
Definition: msports.h:13
#define REG_BINARY
Definition: nt_native.h:1496
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
#define L(x)
Definition: ntvdm.h:50
BYTE * PBYTE
Definition: pedump.c:66
long LONG
Definition: pedump.c:60
#define memset(x, y, z)
Definition: compat.h:39
#define TRACE(s)
Definition: solgame.cpp:4
Definition: comdb.c:16
HKEY hKey
Definition: comdb.c:18
HANDLE hMutex
Definition: comdb.c:17
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
HANDLE WINAPI DECLSPEC_HOTPATCH CreateMutexW(IN LPSECURITY_ATTRIBUTES lpMutexAttributes OPTIONAL, IN BOOL bInitialOwner, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:576
BOOL WINAPI DECLSPEC_HOTPATCH ReleaseMutex(IN HANDLE hMutex)
Definition: synch.c:618
uint32_t * LPDWORD
Definition: typedefs.h:59
#define IN
Definition: typedefs.h:39
#define OUT
Definition: typedefs.h:40
_In_ WDFMEMORY _Out_opt_ size_t * BufferSize
Definition: wdfmemory.h:254
BOOL * PBOOL
Definition: windef.h:161
#define WINAPI
Definition: msvc.h:6
#define ERROR_SHARING_VIOLATION
Definition: winerror.h:135
#define ERROR_BAD_LENGTH
Definition: winerror.h:127
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
unsigned char BYTE
Definition: xxhash.c:193