Author: ekohl Date: Wed May 25 10:52:12 2011 New Revision: 51901
URL: http://svn.reactos.org/svn/reactos?rev=51901&view=rev Log: [MSPORTS] - Implement ComDBClaimNextFreePort and ComDBReleasePort. - Add stubs for ComDBGetCurrentPortUsage and ComDBResizeDatabase. - Do not keep the port bitmap in a buffer between calls but use a read-modify-write strategy instead. - Replace pointer-based access to the port bitmap by index-based access. - Use ComDBClaimNextFreePort in the serial port installer. See issue #6272 for more details.
Modified: trunk/reactos/dll/win32/msports/classinst.c trunk/reactos/dll/win32/msports/comdb.c trunk/reactos/dll/win32/msports/msports.spec trunk/reactos/include/ddk/msports.h
Modified: trunk/reactos/dll/win32/msports/classinst.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msports/classinst... ============================================================================== --- trunk/reactos/dll/win32/msports/classinst.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/msports/classinst.c [iso-8859-1] Wed May 25 10:52:12 2011 @@ -257,8 +257,6 @@ DeviceInfoData); if (dwPortNumber != 0) { - swprintf(szPortName, L"COM%u", dwPortNumber); - ComDBClaimPort(hComDB, dwPortNumber, FALSE, @@ -266,8 +264,11 @@ } else { - wcscpy(szPortName, L"COMx"); - } + ComDBClaimNextFreePort(hComDB, + &dwPortNumber); + } + + swprintf(szPortName, L"COM%u", dwPortNumber);
/* Close the com port database */ if (hComDB != HCOMDB_INVALID_HANDLE_VALUE)
Modified: trunk/reactos/dll/win32/msports/comdb.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msports/comdb.c?r... ============================================================================== --- trunk/reactos/dll/win32/msports/comdb.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/msports/comdb.c [iso-8859-1] Wed May 25 10:52:12 2011 @@ -18,9 +18,95 @@ typedef struct _COMDB { HKEY hKey; +} COMDB, *PCOMDB; + + +LONG +WINAPI +ComDBClaimNextFreePort(IN HCOMDB hComDB, + OUT LPDWORD ComNumber) +{ + PCOMDB pComDB; + DWORD dwBitIndex; + DWORD dwByteIndex; DWORD dwSize; - PBYTE pBitmap; -} COMDB, *PCOMDB; + DWORD dwType; + PBYTE pBitmap = NULL; + BYTE cMask; + LONG lError; + + TRACE("ComDBClaimNextFreePort(%p %p)\n", hComDB, ComNumber); + + if (hComDB == INVALID_HANDLE_VALUE || + hComDB == NULL || + ComNumber == NULL) + return ERROR_INVALID_PARAMETER; + + pComDB = (PCOMDB)hComDB; + + /* Get the required bitmap size */ + lError = RegQueryValueExW(pComDB->hKey, + L"ComDB", + NULL, + &dwType, + NULL, + &dwSize); + if (lError != ERROR_SUCCESS) + return lError; + + /* Allocate the bitmap */ + pBitmap = HeapAlloc(GetProcessHeap(), + HEAP_ZERO_MEMORY, + dwSize); + if (pBitmap == NULL) + { + ERR("Failed to allocate the bitmap!\n"); + return lError; + } + + /* Read the bitmap */ + lError = RegQueryValueExW(pComDB->hKey, + L"ComDB", + NULL, + &dwType, + pBitmap, + &dwSize); + if (lError != ERROR_SUCCESS) + goto done; + + lError = ERROR_INVALID_PARAMETER; + for (dwBitIndex = 0; dwBitIndex < (dwSize * BITS_PER_BYTE); dwBitIndex++) + { + /* Calculate the byte index and a mask for the affected bit */ + dwByteIndex = dwBitIndex / BITS_PER_BYTE; + cMask = 1 << (dwBitIndex % BITS_PER_BYTE); + + if ((pBitmap[dwByteIndex] & cMask) == 0) + { + pBitmap[dwByteIndex] |= cMask; + *ComNumber = dwBitIndex + 1; + lError = ERROR_SUCCESS; + break; + } + } + + /* Save the bitmap if it was modified */ + if (lError == ERROR_SUCCESS) + { + lError = RegSetValueExW(pComDB->hKey, + L"ComDB", + 0, + REG_BINARY, + pBitmap, + dwSize); + } + +done:; + if (pBitmap != NULL) + HeapFree(GetProcessHeap(), 0, pBitmap); + + return lError; +}
LONG @@ -31,12 +117,15 @@ OUT PBOOL Forced) { PCOMDB pComDB; - PBYTE pByte; - BYTE cMask; DWORD dwBitIndex; + DWORD dwByteIndex; DWORD dwType; DWORD dwSize; + PBYTE pBitmap = NULL; + BYTE cMask; LONG lError; + + TRACE("ComDBClaimPort(%p %lu)\n", hComDB, ComNumber);
if (hComDB == INVALID_HANDLE_VALUE || hComDB == NULL || @@ -46,42 +135,60 @@
pComDB = (PCOMDB)hComDB;
- /* Update the bitmap */ - dwSize = pComDB->dwSize; - lError = RegQueryValueExW(pComDB->hKey, - L"ComDB", - NULL, - &dwType, - pComDB->pBitmap, - &dwSize); - if (lError != ERROR_SUCCESS) - return lError; + /* Get the required bitmap size */ + lError = RegQueryValueExW(pComDB->hKey, + L"ComDB", + NULL, + &dwType, + NULL, + &dwSize); + if (lError != ERROR_SUCCESS) + return lError; + + /* Allocate the bitmap */ + pBitmap = HeapAlloc(GetProcessHeap(), + HEAP_ZERO_MEMORY, + dwSize); + if (pBitmap == NULL) + { + ERR("Failed to allocate the bitmap!\n"); + return lError; + } + + /* Read the bitmap */ + lError = RegQueryValueExW(pComDB->hKey, + L"ComDB", + NULL, + &dwType, + pBitmap, + &dwSize); + if (lError != ERROR_SUCCESS) + goto done;
/* Get the bit index */ dwBitIndex = ComNumber - 1;
/* Check if the bit to set fits into the bitmap */ - if (dwBitIndex >= (pComDB->dwSize * BITS_PER_BYTE)) - { - /* FIXME: Resize the bitmap */ - return ERROR_INVALID_PARAMETER; - } - - /* Get a pointer to the affected byte and calculate a mask for the affected bit */ - pByte = &(pComDB->pBitmap[dwBitIndex / BITS_PER_BYTE]); + if (dwBitIndex >= (dwSize * BITS_PER_BYTE)) + { + FIXME("Resize the bitmap\n"); + + lError = ERROR_INVALID_PARAMETER; + goto done; + } + + /* Calculate the byte index and a mask for the affected bit */ + dwByteIndex = dwBitIndex / BITS_PER_BYTE; cMask = 1 << (dwBitIndex % BITS_PER_BYTE);
+ lError = ERROR_SHARING_VIOLATION; + /* Check if the bit is not set */ - if ((*pByte & cMask) == 0) + if ((pBitmap[dwByteIndex] & cMask) == 0) { /* Set the bit */ - *pByte |= cMask; + pBitmap[dwByteIndex] |= cMask; lError = ERROR_SUCCESS; - } - else - { - /* The bit is already set */ - lError = ERROR_SHARING_VIOLATION; }
/* Save the bitmap if it was modified */ @@ -91,9 +198,13 @@ L"ComDB", 0, REG_BINARY, - pComDB->pBitmap, - pComDB->dwSize); - } + pBitmap, + dwSize); + } + +done: + if (pBitmap != NULL) + HeapFree(GetProcessHeap(), 0, pBitmap);
return lError; } @@ -104,6 +215,8 @@ ComDBClose(IN HCOMDB hComDB) { PCOMDB pComDB; + + TRACE("ComDBClose(%p)\n", hComDB);
if (hComDB == HCOMDB_INVALID_HANDLE_VALUE || hComDB == NULL) return ERROR_INVALID_PARAMETER; @@ -114,14 +227,23 @@ if (pComDB->hKey != NULL) RegCloseKey(pComDB->hKey);
- /* Release the bitmap */ - if (pComDB->pBitmap != NULL) - HeapFree(GetProcessHeap(), 0, pComDB->pBitmap); - /* Release the database */ HeapFree(GetProcessHeap(), 0, pComDB);
return ERROR_SUCCESS; +} + + +LONG +WINAPI +ComDBGetCurrentPortUsage(IN HCOMDB hComDB, + OUT PBYTE Buffer, + IN DWORD BufferSize, + IN DWORD ReportType, + OUT LPDWORD MaxPortsReported) +{ + FIXME("ComDBGetCurrentPortUsage(%p)\n", hComDB); + return ERROR_CALL_NOT_IMPLEMENTED; }
@@ -132,6 +254,8 @@ PCOMDB pComDB; DWORD dwDisposition; DWORD dwType; + DWORD dwSize; + PBYTE pBitmap; LONG lError;
TRACE("ComDBOpen(%p)\n", phComDB); @@ -142,7 +266,7 @@ sizeof(COMDB)); if (pComDB == NULL) { - ERR("Failed to allocaete the database!\n"); + ERR("Failed to allocate the database!\n"); return ERROR_ACCESS_DENIED; }
@@ -165,28 +289,30 @@ NULL, &dwType, NULL, - &pComDB->dwSize); + &dwSize); if (lError == ERROR_FILE_NOT_FOUND) { /* Allocate a new bitmap */ - pComDB->dwSize = COMDB_MIN_PORTS_ARBITRATED / BITS_PER_BYTE; - pComDB->pBitmap = HeapAlloc(GetProcessHeap(), - HEAP_ZERO_MEMORY, - pComDB->dwSize); - if (pComDB->pBitmap == NULL) + dwSize = COMDB_MIN_PORTS_ARBITRATED / BITS_PER_BYTE; + pBitmap = HeapAlloc(GetProcessHeap(), + HEAP_ZERO_MEMORY, + dwSize); + if (pBitmap == NULL) { - ERR("Failed to allocaete the bitmap!\n"); + ERR("Failed to allocate the bitmap!\n"); lError = ERROR_ACCESS_DENIED; goto done; }
- /* Read the bitmap from the registry */ + /* Write the bitmap to the registry */ lError = RegSetValueExW(pComDB->hKey, L"ComDB", 0, REG_BINARY, - pComDB->pBitmap, - pComDB->dwSize); + pBitmap, + dwSize); + + HeapFree(GetProcessHeap(), 0, pBitmap); }
done:; @@ -196,9 +322,6 @@ if (pComDB->hKey != NULL) RegCloseKey(pComDB->hKey);
- if (pComDB->pBitmap != NULL) - HeapFree(GetProcessHeap(), 0, pComDB->pBitmap); - HeapFree(GetProcessHeap(), 0, pComDB);
*phComDB = HCOMDB_INVALID_HANDLE_VALUE; @@ -214,4 +337,99 @@ return lError; }
+ +LONG +WINAPI +ComDBReleasePort(IN HCOMDB hComDB, + IN DWORD ComNumber) +{ + PCOMDB pComDB; + DWORD dwByteIndex; + DWORD dwBitIndex; + DWORD dwType; + DWORD dwSize; + PBYTE pBitmap = NULL; + BYTE cMask; + LONG lError; + + TRACE("ComDBReleasePort(%p %lu)\n", hComDB, ComNumber); + + if (hComDB == INVALID_HANDLE_VALUE || + ComNumber == 0 || + ComNumber > COMDB_MAX_PORTS_ARBITRATED) + return ERROR_INVALID_PARAMETER; + + pComDB = (PCOMDB)hComDB; + + /* Get the required bitmap size */ + lError = RegQueryValueExW(pComDB->hKey, + L"ComDB", + NULL, + &dwType, + NULL, + &dwSize); + if (lError != ERROR_SUCCESS) + return lError; + + /* Allocate the bitmap */ + pBitmap = HeapAlloc(GetProcessHeap(), + HEAP_ZERO_MEMORY, + dwSize); + if (pBitmap == NULL) + { + ERR("Failed to allocate the bitmap!\n"); + return lError; + } + + /* Read the bitmap */ + lError = RegQueryValueExW(pComDB->hKey, + L"ComDB", + NULL, + &dwType, + pBitmap, + &dwSize); + if (lError != ERROR_SUCCESS) + goto done; + + /* Get the bit index */ + dwBitIndex = ComNumber - 1; + + /* Check if the bit to set fits into the bitmap */ + if (dwBitIndex >= (dwSize * BITS_PER_BYTE)) + { + lError = ERROR_INVALID_PARAMETER; + goto done; + } + + /* Calculate the byte index and a mask for the affected bit */ + dwByteIndex = dwBitIndex / BITS_PER_BYTE; + cMask = 1 << (dwBitIndex % BITS_PER_BYTE); + + /* Release the port */ + pBitmap[dwByteIndex] &= ~cMask; + + lError = RegSetValueExW(pComDB->hKey, + L"ComDB", + 0, + REG_BINARY, + pBitmap, + dwSize); + +done:; + if (pBitmap != NULL) + HeapFree(GetProcessHeap(), 0, pBitmap); + + return lError; +} + + +LONG +WINAPI +ComDBResizeDatabase(IN HCOMDB hComDB, + IN DWORD NewSize) +{ + FIXME("ComDBResizeDatabase(%p %lu)\n", hComDB, NewSize); + return ERROR_CALL_NOT_IMPLEMENTED; +} + /* EOF */
Modified: trunk/reactos/dll/win32/msports/msports.spec URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msports/msports.s... ============================================================================== --- trunk/reactos/dll/win32/msports/msports.spec [iso-8859-1] (original) +++ trunk/reactos/dll/win32/msports/msports.spec [iso-8859-1] Wed May 25 10:52:12 2011 @@ -1,10 +1,10 @@ -@ stub ComDBClaimNextFreePort +@ stdcall ComDBClaimNextFreePort(ptr ptr) @ stdcall ComDBClaimPort(ptr long long ptr) @ stdcall ComDBClose(ptr) -@ stub ComDBGetCurrentPortUsage +@ stdcall ComDBGetCurrentPortUsage(ptr ptr long long ptr) @ stdcall ComDBOpen(ptr) -@ stub ComDBReleasePort -@ stub ComDBResizeDatabase +@ stdcall ComDBReleasePort(ptr long) +@ stdcall ComDBResizeDatabase(ptr long) @ stdcall LibMain(ptr long ptr) DllMain @ stub ParallelPortPropPageProvider @ stdcall PortsClassInstaller(long ptr ptr)
Modified: trunk/reactos/include/ddk/msports.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/ddk/msports.h?rev=5... ============================================================================== --- trunk/reactos/include/ddk/msports.h [iso-8859-1] (original) +++ trunk/reactos/include/ddk/msports.h [iso-8859-1] Wed May 25 10:52:12 2011 @@ -11,6 +11,11 @@
#define COMDB_MIN_PORTS_ARBITRATED 256 #define COMDB_MAX_PORTS_ARBITRATED 4096 + +LONG +WINAPI +ComDBClaimNextFreePort(IN HCOMDB hComDB, + OUT LPDWORD ComNumber);
LONG WINAPI @@ -28,7 +33,7 @@ ComDBGetCurrentPortUsage(IN HCOMDB hComDB, OUT PBYTE Buffer, IN DWORD BufferSize, - IN ULONG ReportType, + IN DWORD ReportType, OUT LPDWORD MaxPortsReported);
LONG