[MSPORTS]

- Add msports.h header file.
- Add the initial version of the com port database and use it to track the used com ports.

svn path=/trunk/; revision=51866
This commit is contained in:
Eric Kohl 2011-05-23 17:54:16 +00:00
parent 5abd114662
commit 2ccbf80288
6 changed files with 287 additions and 3 deletions

View file

@ -5,6 +5,7 @@ spec2def(msports.dll msports.spec)
list(APPEND SOURCE
classinst.c
comdb.c
msports.c
msports.rc
${CMAKE_CURRENT_BINARY_DIR}/msports_stubs.c

View file

@ -10,6 +10,7 @@
#include <windows.h>
#include <cmtypes.h>
#include <stdio.h>
#include <msports.h>
#include <setupapi.h>
#include <wine/debug.h>
@ -244,21 +245,33 @@ InstallSerialPort(IN HDEVINFO DeviceInfoSet,
WCHAR szFriendlyName[256];
WCHAR szPortName[5];
DWORD dwPortNumber;
HCOMDB hComDB = HCOMDB_INVALID_HANDLE_VALUE;
TRACE("InstallSerialPort(%p, %p)\n",
DeviceInfoSet, DeviceInfoData);
/* Open the com port database */
ComDBOpen(&hComDB);
dwPortNumber = GetSerialPortNumber(DeviceInfoSet,
DeviceInfoData);
if (dwPortNumber != 0)
{
swprintf(szPortName, L"COM%u", dwPortNumber);
ComDBClaimPort(hComDB,
dwPortNumber,
FALSE,
NULL);
}
else
{
wcscpy(szPortName, L"COMx");
}
/* Close the com port database */
if (hComDB != HCOMDB_INVALID_HANDLE_VALUE)
ComDBClose(hComDB);
/* Install the device */
if (!SetupDiInstallDevice(DeviceInfoSet,

View file

@ -0,0 +1,217 @@
/*
* PROJECT: Ports installer library
* LICENSE: GPL - See COPYING in the top level directory
* FILE: dll\win32\msports\comdb.c
* PURPOSE: COM port database
* COPYRIGHT: Copyright 2011 Eric Kohl
*/
#include <windows.h>
#include <msports.h>
#include <wine/debug.h>
WINE_DEFAULT_DEBUG_CHANNEL(msports);
#define BITS_PER_BYTE 8
typedef struct _COMDB
{
HKEY hKey;
DWORD dwSize;
PBYTE pBitmap;
} COMDB, *PCOMDB;
LONG
WINAPI
ComDBClaimPort(IN HCOMDB hComDB,
IN DWORD ComNumber,
IN BOOL ForceClaim,
OUT PBOOL Forced)
{
PCOMDB pComDB;
PBYTE pByte;
BYTE cMask;
DWORD dwBitIndex;
DWORD dwType;
DWORD dwSize;
LONG lError;
if (hComDB == INVALID_HANDLE_VALUE ||
hComDB == NULL ||
ComNumber == 0 ||
ComNumber > COMDB_MAX_PORTS_ARBITRATED)
return ERROR_INVALID_PARAMETER;
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 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]);
cMask = 1 << (dwBitIndex % BITS_PER_BYTE);
/* Check if the bit is not set */
if ((*pByte & cMask) == 0)
{
/* Set the bit */
*pByte |= cMask;
lError = ERROR_SUCCESS;
}
else
{
/* The bit is already set */
lError = ERROR_SHARING_VIOLATION;
}
/* Save the bitmap if it was modified */
if (lError == ERROR_SUCCESS)
{
lError = RegSetValueExW(pComDB->hKey,
L"ComDB",
0,
REG_BINARY,
pComDB->pData,
pComDB->dwSize);
}
return lError;
}
LONG
WINAPI
ComDBClose(IN HCOMDB hComDB)
{
PCOMDB pComDB;
if (hComDB == HCOMDB_INVALID_HANDLE_VALUE || hComDB == NULL)
return ERROR_INVALID_PARAMETER;
pComDB = (PCOMDB)hComDB;
/* Close the registry key */
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
ComDBOpen(OUT HCOMDB *phComDB)
{
PCOMDB pComDB;
DWORD dwDisposition;
DWORD dwType;
LONG lError;
TRACE("ComDBOpen(%p)\n", phComDB);
/* Allocate a new database */
pComDB = HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY,
sizeof(COMDB));
if (pComDB == NULL)
{
ERR("Failed to allocaete the database!\n");
return ERROR_ACCESS_DENIED;
}
/* Create or open the database key */
lError = RegCreateKeyExW(HKEY_LOCAL_MACHINE,
L"System\\CurrentControlSet\\Control\\COM Name Arbiter",
0,
NULL,
0,
KEY_ALL_ACCESS,
NULL,
&pComDB->hKey,
&dwDisposition);
if (lError != ERROR_SUCCESS)
goto done;
/* Get the required bitmap size */
lError = RegQueryValueExW(pComDB->hKey,
L"ComDB",
NULL,
&dwType,
NULL,
&pComDB->dwSize);
if (lError == ERROR_FILE_NOT_FOUND)
{
/* Allocate a new bitmap */
pComDB->dwSize = COMDB_MIN_PORTS_ARBITRATED / BITS_PER_BYTE;
pComDB->pData = HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY,
pComDB->dwSize);
if (pComDB->pData == NULL)
{
ERR("Failed to allocaete the bitmap!\n");
lError = ERROR_ACCESS_DENIED;
goto done;
}
/* Read the bitmap from the registry */
lError = RegSetValueExW(pComDB->hKey,
L"ComDB",
0,
REG_BINARY,
pComDB->pData,
pComDB->dwSize);
}
done:;
if (lError != ERROR_SUCCESS)
{
/* Clean up in case of failure */
if (pComDB->hKey != NULL)
RegCloseKey(pComDB->hKey);
if (pComDB->pData != NULL)
HeapFree(GetProcessHeap(), 0, pComDB->pData);
HeapFree(GetProcessHeap(), 0, pComDB);
*phComDB = HCOMDB_INVALID_HANDLE_VALUE;
}
else
{
/* Return the database handle */
*phComDB = (HCOMDB)pComDB;
}
TRACE("done (Error %lu)\n", lError);
return lError;
}
/* EOF */

View file

@ -6,6 +6,7 @@
<library>advapi32</library>
<library>setupapi</library>
<file>classinst.c</file>
<file>comdb.c</file>
<file>msports.c</file>
<file>msports.rc</file>
</module>

View file

@ -1,8 +1,8 @@
@ stub ComDBClaimNextFreePort
@ stub ComDBClaimPort
@ stub ComDBClose
@ stdcall ComDBClaimPort(ptr long long ptr)
@ stdcall ComDBClose(ptr)
@ stub ComDBGetCurrentPortUsage
@ stub ComDBOpen
@ stdcall ComDBOpen(ptr)
@ stub ComDBReleasePort
@ stub ComDBResizeDatabase
@ stdcall LibMain(ptr long ptr) DllMain

View file

@ -0,0 +1,52 @@
#ifndef _MSPORTS_
#define _MSPORTS_
#ifdef __cplusplus
extern "C" {
#endif
DECLARE_HANDLE(HCOMDB);
typedef HCOMDB *PHCOMDB;
#define HCOMDB_INVALID_HANDLE_VALUE ((HCOMDB)INVALID_HANDLE_VALUE)
#define COMDB_MIN_PORTS_ARBITRATED 256
#define COMDB_MAX_PORTS_ARBITRATED 4096
LONG
WINAPI
ComDBClaimPort(IN HCOMDB hComDB,
IN DWORD ComNumber,
IN BOOL ForceClaim,
OUT PBOOL Forced);
LONG
WINAPI
ComDBClose(IN HCOMDB hComDB);
LONG
WINAPI
ComDBGetCurrentPortUsage(IN HCOMDB hComDB,
OUT PBYTE Buffer,
IN DWORD BufferSize,
IN ULONG ReportType,
OUT LPDWORD MaxPortsReported);
LONG
WINAPI
ComDBOpen(OUT HCOMDB *phComDB);
LONG
WINAPI
ComDBReleasePort(IN HCOMDB hComDB,
IN DWORD ComNumber);
LONG
WINAPI
ComDBResizeDatabase(IN HCOMDB hComDB,
IN DWORD NewSize);
#ifdef __cplusplus
}
#endif
#endif /* _MSPORTS_ */