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.c?rev=51901&r1=51900&r2=51901&view=diff
==============================================================================
--- 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?rev=51901&r1=51900&r2=51901&view=diff
==============================================================================
--- 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.spec?rev=51901&r1=51900&r2=51901&view=diff
==============================================================================
--- 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=51901&r1=51900&r2=51901&view=diff
==============================================================================
--- 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


Reply via email to