Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygencomdb.c
Go to the documentation of this file.
00001 /* 00002 * PROJECT: Ports installer library 00003 * LICENSE: GPL - See COPYING in the top level directory 00004 * FILE: dll\win32\msports\comdb.c 00005 * PURPOSE: COM port database 00006 * COPYRIGHT: Copyright 2011 Eric Kohl 00007 */ 00008 00009 #include "precomp.h" 00010 00011 WINE_DEFAULT_DEBUG_CHANNEL(msports); 00012 00013 #define BITS_PER_BYTE 8 00014 #define BITMAP_SIZE_INCREMENT 0x400 00015 #define BITMAP_SIZE_INVALID_BITS 0x3FF 00016 00017 typedef struct _COMDB 00018 { 00019 HANDLE hMutex; 00020 HKEY hKey; 00021 } COMDB, *PCOMDB; 00022 00023 00024 LONG 00025 WINAPI 00026 ComDBClaimNextFreePort(IN HCOMDB hComDB, 00027 OUT LPDWORD ComNumber) 00028 { 00029 PCOMDB pComDB; 00030 DWORD dwBitIndex; 00031 DWORD dwByteIndex; 00032 DWORD dwSize; 00033 DWORD dwType; 00034 PBYTE pBitmap = NULL; 00035 BYTE cMask; 00036 LONG lError; 00037 00038 TRACE("ComDBClaimNextFreePort(%p %p)\n", hComDB, ComNumber); 00039 00040 if (hComDB == INVALID_HANDLE_VALUE || 00041 hComDB == NULL || 00042 ComNumber == NULL) 00043 return ERROR_INVALID_PARAMETER; 00044 00045 pComDB = (PCOMDB)hComDB; 00046 00047 /* Wait for the mutex */ 00048 WaitForSingleObject(pComDB->hMutex, INFINITE); 00049 00050 /* Get the required bitmap size */ 00051 lError = RegQueryValueExW(pComDB->hKey, 00052 L"ComDB", 00053 NULL, 00054 &dwType, 00055 NULL, 00056 &dwSize); 00057 if (lError != ERROR_SUCCESS) 00058 { 00059 ERR("Failed to query the bitmap size!\n"); 00060 goto done; 00061 } 00062 00063 /* Allocate the bitmap */ 00064 pBitmap = HeapAlloc(GetProcessHeap(), 00065 HEAP_ZERO_MEMORY, 00066 dwSize); 00067 if (pBitmap == NULL) 00068 { 00069 ERR("Failed to allocate the bitmap!\n"); 00070 lError = ERROR_NOT_ENOUGH_MEMORY; 00071 goto done; 00072 } 00073 00074 /* Read the bitmap */ 00075 lError = RegQueryValueExW(pComDB->hKey, 00076 L"ComDB", 00077 NULL, 00078 &dwType, 00079 pBitmap, 00080 &dwSize); 00081 if (lError != ERROR_SUCCESS) 00082 goto done; 00083 00084 lError = ERROR_INVALID_PARAMETER; 00085 for (dwBitIndex = 0; dwBitIndex < (dwSize * BITS_PER_BYTE); dwBitIndex++) 00086 { 00087 /* Calculate the byte index and a mask for the affected bit */ 00088 dwByteIndex = dwBitIndex / BITS_PER_BYTE; 00089 cMask = 1 << (dwBitIndex % BITS_PER_BYTE); 00090 00091 if ((pBitmap[dwByteIndex] & cMask) == 0) 00092 { 00093 pBitmap[dwByteIndex] |= cMask; 00094 *ComNumber = dwBitIndex + 1; 00095 lError = ERROR_SUCCESS; 00096 break; 00097 } 00098 } 00099 00100 /* Save the bitmap if it was modified */ 00101 if (lError == ERROR_SUCCESS) 00102 { 00103 lError = RegSetValueExW(pComDB->hKey, 00104 L"ComDB", 00105 0, 00106 REG_BINARY, 00107 pBitmap, 00108 dwSize); 00109 } 00110 00111 done:; 00112 /* Release the mutex */ 00113 ReleaseMutex(pComDB->hMutex); 00114 00115 /* Release the bitmap */ 00116 if (pBitmap != NULL) 00117 HeapFree(GetProcessHeap(), 0, pBitmap); 00118 00119 return lError; 00120 } 00121 00122 00123 LONG 00124 WINAPI 00125 ComDBClaimPort(IN HCOMDB hComDB, 00126 IN DWORD ComNumber, 00127 IN BOOL ForceClaim, 00128 OUT PBOOL Forced) 00129 { 00130 PCOMDB pComDB; 00131 DWORD dwBitIndex; 00132 DWORD dwByteIndex; 00133 DWORD dwType; 00134 DWORD dwSize; 00135 PBYTE pBitmap = NULL; 00136 BYTE cMask; 00137 LONG lError; 00138 00139 TRACE("ComDBClaimPort(%p %lu)\n", hComDB, ComNumber); 00140 00141 if (hComDB == INVALID_HANDLE_VALUE || 00142 hComDB == NULL || 00143 ComNumber == 0 || 00144 ComNumber > COMDB_MAX_PORTS_ARBITRATED) 00145 return ERROR_INVALID_PARAMETER; 00146 00147 pComDB = (PCOMDB)hComDB; 00148 00149 /* Wait for the mutex */ 00150 WaitForSingleObject(pComDB->hMutex, INFINITE); 00151 00152 /* Get the required bitmap size */ 00153 lError = RegQueryValueExW(pComDB->hKey, 00154 L"ComDB", 00155 NULL, 00156 &dwType, 00157 NULL, 00158 &dwSize); 00159 if (lError != ERROR_SUCCESS) 00160 { 00161 ERR("Failed to query the bitmap size!\n"); 00162 goto done; 00163 } 00164 00165 /* Allocate the bitmap */ 00166 pBitmap = HeapAlloc(GetProcessHeap(), 00167 HEAP_ZERO_MEMORY, 00168 dwSize); 00169 if (pBitmap == NULL) 00170 { 00171 ERR("Failed to allocate the bitmap!\n"); 00172 lError = ERROR_NOT_ENOUGH_MEMORY; 00173 goto done; 00174 } 00175 00176 /* Read the bitmap */ 00177 lError = RegQueryValueExW(pComDB->hKey, 00178 L"ComDB", 00179 NULL, 00180 &dwType, 00181 pBitmap, 00182 &dwSize); 00183 if (lError != ERROR_SUCCESS) 00184 goto done; 00185 00186 /* Get the bit index */ 00187 dwBitIndex = ComNumber - 1; 00188 00189 /* Check if the bit to set fits into the bitmap */ 00190 if (dwBitIndex >= (dwSize * BITS_PER_BYTE)) 00191 { 00192 FIXME("Resize the bitmap\n"); 00193 00194 lError = ERROR_INVALID_PARAMETER; 00195 goto done; 00196 } 00197 00198 /* Calculate the byte index and a mask for the affected bit */ 00199 dwByteIndex = dwBitIndex / BITS_PER_BYTE; 00200 cMask = 1 << (dwBitIndex % BITS_PER_BYTE); 00201 00202 lError = ERROR_SHARING_VIOLATION; 00203 00204 /* Check if the bit is not set */ 00205 if ((pBitmap[dwByteIndex] & cMask) == 0) 00206 { 00207 /* Set the bit */ 00208 pBitmap[dwByteIndex] |= cMask; 00209 lError = ERROR_SUCCESS; 00210 } 00211 00212 /* Save the bitmap if it was modified */ 00213 if (lError == ERROR_SUCCESS) 00214 { 00215 lError = RegSetValueExW(pComDB->hKey, 00216 L"ComDB", 00217 0, 00218 REG_BINARY, 00219 pBitmap, 00220 dwSize); 00221 } 00222 00223 done: 00224 /* Release the mutex */ 00225 ReleaseMutex(pComDB->hMutex); 00226 00227 /* Release the bitmap */ 00228 if (pBitmap != NULL) 00229 HeapFree(GetProcessHeap(), 0, pBitmap); 00230 00231 return lError; 00232 } 00233 00234 00235 LONG 00236 WINAPI 00237 ComDBClose(IN HCOMDB hComDB) 00238 { 00239 PCOMDB pComDB; 00240 00241 TRACE("ComDBClose(%p)\n", hComDB); 00242 00243 if (hComDB == HCOMDB_INVALID_HANDLE_VALUE || 00244 hComDB == NULL) 00245 return ERROR_INVALID_PARAMETER; 00246 00247 pComDB = (PCOMDB)hComDB; 00248 00249 /* Close the registry key */ 00250 if (pComDB->hKey != NULL) 00251 RegCloseKey(pComDB->hKey); 00252 00253 /* Close the mutex */ 00254 if (pComDB->hMutex != NULL) 00255 CloseHandle(pComDB->hMutex); 00256 00257 /* Release the database */ 00258 HeapFree(GetProcessHeap(), 0, pComDB); 00259 00260 return ERROR_SUCCESS; 00261 } 00262 00263 00264 LONG 00265 WINAPI 00266 ComDBGetCurrentPortUsage(IN HCOMDB hComDB, 00267 OUT PBYTE Buffer, 00268 IN DWORD BufferSize, 00269 IN DWORD ReportType, 00270 OUT LPDWORD MaxPortsReported) 00271 { 00272 PCOMDB pComDB; 00273 DWORD dwBitIndex; 00274 DWORD dwByteIndex; 00275 DWORD dwType; 00276 DWORD dwSize; 00277 PBYTE pBitmap = NULL; 00278 BYTE cMask; 00279 LONG lError = ERROR_SUCCESS; 00280 00281 TRACE("ComDBGetCurrentPortUsage(%p %p %lu %lu %p)\n", 00282 hComDB, Buffer, BufferSize, ReportType, MaxPortsReported); 00283 00284 if (hComDB == INVALID_HANDLE_VALUE || 00285 hComDB == NULL || 00286 (Buffer == NULL && MaxPortsReported == NULL) || 00287 (ReportType != CDB_REPORT_BITS && ReportType != CDB_REPORT_BYTES)) 00288 return ERROR_INVALID_PARAMETER; 00289 00290 pComDB = (PCOMDB)hComDB; 00291 00292 /* Wait for the mutex */ 00293 WaitForSingleObject(pComDB->hMutex, INFINITE); 00294 00295 /* Get the required bitmap size */ 00296 lError = RegQueryValueExW(pComDB->hKey, 00297 L"ComDB", 00298 NULL, 00299 &dwType, 00300 NULL, 00301 &dwSize); 00302 if (lError != ERROR_SUCCESS) 00303 { 00304 ERR("Failed to query the bitmap size!\n"); 00305 goto done; 00306 } 00307 00308 /* Allocate the bitmap */ 00309 pBitmap = HeapAlloc(GetProcessHeap(), 00310 HEAP_ZERO_MEMORY, 00311 dwSize); 00312 if (pBitmap == NULL) 00313 { 00314 ERR("Failed to allocate the bitmap!\n"); 00315 lError = ERROR_NOT_ENOUGH_MEMORY; 00316 goto done; 00317 } 00318 00319 /* Read the bitmap */ 00320 lError = RegQueryValueExW(pComDB->hKey, 00321 L"ComDB", 00322 NULL, 00323 &dwType, 00324 pBitmap, 00325 &dwSize); 00326 if (lError != ERROR_SUCCESS) 00327 goto done; 00328 00329 if (Buffer == NULL) 00330 { 00331 *MaxPortsReported = dwSize * BITS_PER_BYTE; 00332 } 00333 else 00334 { 00335 if (ReportType == CDB_REPORT_BITS) 00336 { 00337 /* Clear the buffer */ 00338 memset(Buffer, 0, BufferSize); 00339 00340 memcpy(Buffer, 00341 pBitmap, 00342 min(dwSize, BufferSize)); 00343 00344 if (MaxPortsReported != NULL) 00345 *MaxPortsReported = min(dwSize, BufferSize) * BITS_PER_BYTE; 00346 } 00347 else if (ReportType == CDB_REPORT_BYTES) 00348 { 00349 /* Clear the buffer */ 00350 memset(Buffer, 0, BufferSize); 00351 00352 for (dwBitIndex = 0; dwBitIndex < min(dwSize * BITS_PER_BYTE, BufferSize); dwBitIndex++) 00353 { 00354 /* Calculate the byte index and a mask for the affected bit */ 00355 dwByteIndex = dwBitIndex / BITS_PER_BYTE; 00356 cMask = 1 << (dwBitIndex % BITS_PER_BYTE); 00357 00358 if ((pBitmap[dwByteIndex] & cMask) != 0) 00359 Buffer[dwBitIndex] = 1; 00360 } 00361 } 00362 } 00363 00364 done:; 00365 /* Release the mutex */ 00366 ReleaseMutex(pComDB->hMutex); 00367 00368 /* Release the bitmap */ 00369 HeapFree(GetProcessHeap(), 0, pBitmap); 00370 00371 return lError; 00372 } 00373 00374 00375 LONG 00376 WINAPI 00377 ComDBOpen(OUT HCOMDB *phComDB) 00378 { 00379 PCOMDB pComDB; 00380 DWORD dwDisposition; 00381 DWORD dwType; 00382 DWORD dwSize; 00383 PBYTE pBitmap; 00384 LONG lError; 00385 00386 TRACE("ComDBOpen(%p)\n", phComDB); 00387 00388 /* Allocate a new database */ 00389 pComDB = HeapAlloc(GetProcessHeap(), 00390 HEAP_ZERO_MEMORY, 00391 sizeof(COMDB)); 00392 if (pComDB == NULL) 00393 { 00394 ERR("Failed to allocate the database!\n"); 00395 *phComDB = HCOMDB_INVALID_HANDLE_VALUE; 00396 return ERROR_ACCESS_DENIED; 00397 } 00398 00399 /* Create a mutex to protect the database */ 00400 pComDB->hMutex = CreateMutexW(NULL, 00401 FALSE, 00402 L"ComDBMutex"); 00403 if (pComDB->hMutex == NULL) 00404 { 00405 ERR("Failed to create the mutex!\n"); 00406 HeapFree(GetProcessHeap(), 0, pComDB); 00407 *phComDB = HCOMDB_INVALID_HANDLE_VALUE; 00408 return ERROR_ACCESS_DENIED; 00409 } 00410 00411 /* Wait for the mutex */ 00412 WaitForSingleObject(pComDB->hMutex, INFINITE); 00413 00414 /* Create or open the database key */ 00415 lError = RegCreateKeyExW(HKEY_LOCAL_MACHINE, 00416 L"System\\CurrentControlSet\\Control\\COM Name Arbiter", 00417 0, 00418 NULL, 00419 0, 00420 KEY_ALL_ACCESS, 00421 NULL, 00422 &pComDB->hKey, 00423 &dwDisposition); 00424 if (lError != ERROR_SUCCESS) 00425 goto done; 00426 00427 /* Get the required bitmap size */ 00428 lError = RegQueryValueExW(pComDB->hKey, 00429 L"ComDB", 00430 NULL, 00431 &dwType, 00432 NULL, 00433 &dwSize); 00434 if (lError == ERROR_FILE_NOT_FOUND) 00435 { 00436 /* Allocate a new bitmap */ 00437 dwSize = COMDB_MIN_PORTS_ARBITRATED / BITS_PER_BYTE; 00438 pBitmap = HeapAlloc(GetProcessHeap(), 00439 HEAP_ZERO_MEMORY, 00440 dwSize); 00441 if (pBitmap == NULL) 00442 { 00443 ERR("Failed to allocate the bitmap!\n"); 00444 lError = ERROR_ACCESS_DENIED; 00445 goto done; 00446 } 00447 00448 /* Write the bitmap to the registry */ 00449 lError = RegSetValueExW(pComDB->hKey, 00450 L"ComDB", 00451 0, 00452 REG_BINARY, 00453 pBitmap, 00454 dwSize); 00455 00456 HeapFree(GetProcessHeap(), 0, pBitmap); 00457 } 00458 00459 done:; 00460 /* Release the mutex */ 00461 ReleaseMutex(pComDB->hMutex); 00462 00463 if (lError != ERROR_SUCCESS) 00464 { 00465 /* Clean up in case of failure */ 00466 if (pComDB->hKey != NULL) 00467 RegCloseKey(pComDB->hKey); 00468 00469 if (pComDB->hMutex != NULL) 00470 CloseHandle(pComDB->hMutex); 00471 00472 HeapFree(GetProcessHeap(), 0, pComDB); 00473 00474 *phComDB = HCOMDB_INVALID_HANDLE_VALUE; 00475 } 00476 else 00477 { 00478 /* Return the database handle */ 00479 *phComDB = (HCOMDB)pComDB; 00480 } 00481 00482 TRACE("done (Error %lu)\n", lError); 00483 00484 return lError; 00485 } 00486 00487 00488 LONG 00489 WINAPI 00490 ComDBReleasePort(IN HCOMDB hComDB, 00491 IN DWORD ComNumber) 00492 { 00493 PCOMDB pComDB; 00494 DWORD dwByteIndex; 00495 DWORD dwBitIndex; 00496 DWORD dwType; 00497 DWORD dwSize; 00498 PBYTE pBitmap = NULL; 00499 BYTE cMask; 00500 LONG lError; 00501 00502 TRACE("ComDBReleasePort(%p %lu)\n", hComDB, ComNumber); 00503 00504 if (hComDB == INVALID_HANDLE_VALUE || 00505 ComNumber == 0 || 00506 ComNumber > COMDB_MAX_PORTS_ARBITRATED) 00507 return ERROR_INVALID_PARAMETER; 00508 00509 pComDB = (PCOMDB)hComDB; 00510 00511 /* Wait for the mutex */ 00512 WaitForSingleObject(pComDB->hMutex, INFINITE); 00513 00514 /* Get the required bitmap size */ 00515 lError = RegQueryValueExW(pComDB->hKey, 00516 L"ComDB", 00517 NULL, 00518 &dwType, 00519 NULL, 00520 &dwSize); 00521 if (lError != ERROR_SUCCESS) 00522 { 00523 ERR("Failed to query the bitmap size!\n"); 00524 goto done; 00525 } 00526 00527 /* Allocate the bitmap */ 00528 pBitmap = HeapAlloc(GetProcessHeap(), 00529 HEAP_ZERO_MEMORY, 00530 dwSize); 00531 if (pBitmap == NULL) 00532 { 00533 ERR("Failed to allocate the bitmap!\n"); 00534 lError = ERROR_NOT_ENOUGH_MEMORY; 00535 goto done; 00536 } 00537 00538 /* Read the bitmap */ 00539 lError = RegQueryValueExW(pComDB->hKey, 00540 L"ComDB", 00541 NULL, 00542 &dwType, 00543 pBitmap, 00544 &dwSize); 00545 if (lError != ERROR_SUCCESS) 00546 goto done; 00547 00548 /* Get the bit index */ 00549 dwBitIndex = ComNumber - 1; 00550 00551 /* Check if the bit to set fits into the bitmap */ 00552 if (dwBitIndex >= (dwSize * BITS_PER_BYTE)) 00553 { 00554 lError = ERROR_INVALID_PARAMETER; 00555 goto done; 00556 } 00557 00558 /* Calculate the byte index and a mask for the affected bit */ 00559 dwByteIndex = dwBitIndex / BITS_PER_BYTE; 00560 cMask = 1 << (dwBitIndex % BITS_PER_BYTE); 00561 00562 /* Release the port */ 00563 pBitmap[dwByteIndex] &= ~cMask; 00564 00565 lError = RegSetValueExW(pComDB->hKey, 00566 L"ComDB", 00567 0, 00568 REG_BINARY, 00569 pBitmap, 00570 dwSize); 00571 00572 done:; 00573 /* Release the mutex */ 00574 ReleaseMutex(pComDB->hMutex); 00575 00576 /* Release the bitmap */ 00577 if (pBitmap != NULL) 00578 HeapFree(GetProcessHeap(), 0, pBitmap); 00579 00580 return lError; 00581 } 00582 00583 00584 LONG 00585 WINAPI 00586 ComDBResizeDatabase(IN HCOMDB hComDB, 00587 IN DWORD NewSize) 00588 { 00589 PCOMDB pComDB; 00590 PBYTE pBitmap = NULL; 00591 DWORD dwSize; 00592 DWORD dwNewSize; 00593 DWORD dwType; 00594 LONG lError; 00595 00596 TRACE("ComDBResizeDatabase(%p %lu)\n", hComDB, NewSize); 00597 00598 if (hComDB == INVALID_HANDLE_VALUE || 00599 hComDB == NULL || 00600 (NewSize & BITMAP_SIZE_INVALID_BITS)) 00601 return ERROR_INVALID_PARAMETER; 00602 00603 pComDB = (PCOMDB)hComDB; 00604 00605 /* Wait for the mutex */ 00606 WaitForSingleObject(pComDB->hMutex, INFINITE); 00607 00608 /* Get the required bitmap size */ 00609 lError = RegQueryValueExW(pComDB->hKey, 00610 L"ComDB", 00611 NULL, 00612 &dwType, 00613 NULL, 00614 &dwSize); 00615 if (lError != ERROR_SUCCESS) 00616 goto done; 00617 00618 /* Check the size limits */ 00619 if (NewSize > COMDB_MAX_PORTS_ARBITRATED || 00620 NewSize <= dwSize * BITS_PER_BYTE) 00621 { 00622 lError = ERROR_BAD_LENGTH; 00623 goto done; 00624 } 00625 00626 /* Calculate the new bitmap size */ 00627 dwNewSize = NewSize / BITS_PER_BYTE; 00628 00629 /* Allocate the new bitmap */ 00630 pBitmap = HeapAlloc(GetProcessHeap(), 00631 HEAP_ZERO_MEMORY, 00632 dwSize); 00633 if (pBitmap == NULL) 00634 { 00635 ERR("Failed to allocate the bitmap!\n"); 00636 lError = ERROR_ACCESS_DENIED; 00637 goto done; 00638 } 00639 00640 /* Read the current bitmap */ 00641 lError = RegQueryValueExW(pComDB->hKey, 00642 L"ComDB", 00643 NULL, 00644 &dwType, 00645 pBitmap, 00646 &dwSize); 00647 if (lError != ERROR_SUCCESS) 00648 goto done; 00649 00650 /* Write the new bitmap */ 00651 lError = RegSetValueExW(pComDB->hKey, 00652 L"ComDB", 00653 0, 00654 REG_BINARY, 00655 pBitmap, 00656 dwNewSize); 00657 00658 done:; 00659 /* Release the mutex */ 00660 ReleaseMutex(pComDB->hMutex); 00661 00662 if (pBitmap != NULL) 00663 HeapFree(GetProcessHeap(), 0, pBitmap); 00664 00665 return lError; 00666 } 00667 00668 /* EOF */ Generated on Sat May 26 2012 04:23:52 for ReactOS by
1.7.6.1
|