ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

comdb.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.