winpr-file: introduced HANDLE_CREATOR type

winpr-comm: got a _CommHandleCreator
This commit is contained in:
Emmanuel Ledoux 2014-04-18 19:25:25 +02:00 committed by Emmanuel Ledoux
parent f9fc107c20
commit 7e44488e0a
6 changed files with 141 additions and 24 deletions

View File

@ -364,8 +364,13 @@ WINPR_API BOOL DefineCommDevice(/* DWORD dwFlags,*/ LPCTSTR lpDeviceName, LPCTST
WINPR_API DWORD QueryCommDevice(LPCTSTR lpDeviceName, LPTSTR lpTargetPath, DWORD ucchMax);
WINPR_API BOOL IsCommDevice(LPCTSTR lpDeviceName);
WINPR_API HANDLE _CommCreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes,
DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile);
/**
* A handle can only be created on defined devices with DefineCommDevice(). This
* also ensures that CommCreateFileA() has been registered through
* RegisterHandleCreator().
*/
WINPR_API HANDLE CommCreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes,
DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile);
#ifdef __cplusplus
}

View File

@ -311,10 +311,23 @@ WINPR_API BOOL CreateDirectoryW(LPCWSTR lpPathName, LPSECURITY_ATTRIBUTES lpSecu
#define CreateDirectory CreateDirectoryA
#endif
#endif
/* Extra Functions */
typedef BOOL (*pcIsHandled)(LPCSTR lpFileName);
typedef HANDLE (*pcCreateFileA)(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes,
DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile);
typedef struct _HANDLE_CREATOR
{
pcIsHandled IsHandled;
pcCreateFileA CreateFileA;
} HANDLE_CREATOR, *PHANDLE_CREATOR, *LPHANDLE_CREATOR;
BOOL RegisterHandleCreator(PHANDLE_CREATOR pHandleCreator);
#endif /* _WIN32 */
#define WILDCARD_STAR 0x00000001
#define WILDCARD_QM 0x00000002
#define WILDCARD_DOS 0x00000100

View File

@ -276,6 +276,8 @@ BOOL WaitCommEvent(HANDLE hFile, PDWORD lpEvtMask, LPOVERLAPPED lpOverlapped)
*/
static wHashTable *_CommDevices = NULL;
static HANDLE_CREATOR *_CommHandleCreator = NULL;
static int deviceNameCmp(void* pointer1, void* pointer2)
{
return _tcscmp(pointer1, pointer2);
@ -318,6 +320,12 @@ static void _CommDevicesInit()
_CommDevices->hashFunction = HashTable_StringHashFunctionA; /* TMP: FIXME: need of a HashTable_StringHashFunctionW */
_CommDevices->keyDeallocator = free;
_CommDevices->valueDeallocator = free;
_CommHandleCreator = (HANDLE_CREATOR*)malloc(sizeof(HANDLE_CREATOR));
_CommHandleCreator->IsHandled = IsCommDevice;
_CommHandleCreator->CreateFileA = CommCreateFileA;
RegisterHandleCreator(_CommHandleCreator);
}
}
@ -490,8 +498,8 @@ BOOL IsCommDevice(LPCTSTR lpDeviceName)
}
HANDLE _CommCreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes,
DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile)
HANDLE CommCreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes,
DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile)
{
HANDLE hComm;
WINPR_COMM* pComm;

View File

@ -1,3 +1,22 @@
/**
* WinPR: Windows Portable Runtime
* Serial Communication API
*
* Copyright 2014 Marc-Andre Moreau <marcandre.moreau@gmail.com>
* Copyright 2014 Hewlett-Packard Development Company, L.P.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <winpr/crt.h>
#include <winpr/comm.h>
@ -12,6 +31,23 @@ int TestCommConfig(int argc, char* argv[])
BOOL fSuccess;
LPCSTR lpFileName = "\\\\.\\COM1";
hComm = CreateFileA(lpFileName,
GENERIC_READ | GENERIC_WRITE,
0, NULL, OPEN_EXISTING, 0, NULL);
if (hComm && (hComm != INVALID_HANDLE_VALUE))
{
printf("CreateFileA failure: could create a handle on a not yet defined device: %s\n", lpFileName);
return EXIT_FAILURE;
}
fSuccess = DefineCommDevice(lpFileName, "/dev/test");
if(!fSuccess)
{
printf("DefineCommDevice failure: %s\n", lpFileName);
return EXIT_FAILURE;
}
hComm = CreateFileA(lpFileName,
GENERIC_READ | GENERIC_WRITE,
0, NULL, OPEN_EXISTING, 0, NULL);
@ -19,17 +55,16 @@ int TestCommConfig(int argc, char* argv[])
if (!hComm || (hComm == INVALID_HANDLE_VALUE))
{
printf("CreateFileA failure: %s\n", lpFileName);
return 0;
return EXIT_FAILURE;
}
ZeroMemory(&dcb, sizeof(DCB));
fSuccess = GetCommState(hComm, &dcb);
if (!fSuccess)
{
printf("GetCommState failure: GetLastError() = %d\n", (int) GetLastError());
return 0;
return EXIT_FAILURE;
}
printf("BaudRate: %d ByteSize: %d Parity: %d StopBits: %d\n",

View File

@ -67,7 +67,7 @@ static int test_CommDevice(LPCTSTR lpDeviceName, BOOL expectedResult)
return FALSE;
}
if (lpTargetPath[_tcslen(lpTargetPath) + 1] != NULL)
if (lpTargetPath[_tcslen(lpTargetPath) + 1] != 0)
{
_tprintf(_T("QueryCommDevice failure: device name: %s, the second NULL character is missing at the end of the buffer\n"), lpDeviceName);
return FALSE;
@ -91,25 +91,25 @@ static int test_CommDevice(LPCTSTR lpDeviceName, BOOL expectedResult)
int TestCommDevice(int argc, char* argv[])
{
if (!test_CommDevice(_T("COM0"), FALSE))
return 1;
return EXIT_FAILURE;
if (!test_CommDevice(_T("COM1"), TRUE))
return 1;
return EXIT_FAILURE;
if (!test_CommDevice(_T("COM1"), TRUE))
return 1;
return EXIT_FAILURE;
if (!test_CommDevice(_T("COM10"), FALSE))
return 1;
return EXIT_FAILURE;
if (!test_CommDevice(_T("\\\\.\\COM5"), TRUE))
return 1;
return EXIT_FAILURE;
if (!test_CommDevice(_T("\\\\.\\COM10"), TRUE))
return 1;
return EXIT_FAILURE;
if (!test_CommDevice(_T("\\\\.COM10"), FALSE))
return 1;
return EXIT_FAILURE;
return 0;
}

View File

@ -28,6 +28,7 @@
#include <winpr/error.h>
#include <winpr/handle.h>
#include <winpr/platform.h>
#include <winpr/collections.h>
#include <winpr/file.h>
@ -185,6 +186,50 @@
#include "../pipe/pipe.h"
/* TODO: FIXME: use of a wArrayList and split winpr-utils with
* winpr-collections to avoid circular dependencies
* _HandleCreators = ArrayList_New(TRUE);
*/
static HANDLE_CREATOR **_HandleCreators = NULL;
#define HANDLE_CREATOR_MAX 128
static void _HandleCreatorsInit()
{
/*
* TMP: FIXME: What kind of mutex should be used here? use of
* a module_init()?
*/
if (_HandleCreators == NULL)
{
_HandleCreators = (HANDLE_CREATOR**)calloc(HANDLE_CREATOR_MAX+1, sizeof(HANDLE_CREATOR));
}
}
/**
* Returns TRUE on success, FALSE otherwise.
*
* ERRORS:
* ERROR_INSUFFICIENT_BUFFER _HandleCreators full
*/
BOOL RegisterHandleCreator(PHANDLE_CREATOR pHandleCreator)
{
int i;
for (i=0; i<HANDLE_CREATOR_MAX; i++)
{
if (_HandleCreators[i] == NULL)
{
_HandleCreators[i] = pHandleCreator;
return TRUE;
}
}
SetLastError(ERROR_INSUFFICIENT_BUFFER);
return FALSE;
}
#ifdef HAVE_AIO_H
static BOOL g_AioSignalHandlerInstalled = FALSE;
@ -214,7 +259,7 @@ int InstallAioSignalHandler()
return 0;
}
#endif
#endif /* HAVE_AIO_H */
HANDLE CreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes,
DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile)
@ -228,14 +273,25 @@ HANDLE CreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode,
if (!lpFileName)
return INVALID_HANDLE_VALUE;
/* TMP: TODO: */
/* if (IsCommDevice(lpFileName)) */
/* { */
/* return _CommCreateFileA(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, */
/* dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile); */
/* } */
_HandleCreatorsInit();
if (_HandleCreators != NULL)
{
int i;
for (i=0; _HandleCreators[i] != NULL; i++)
{
HANDLE_CREATOR *creator = (HANDLE_CREATOR*)_HandleCreators[i];
if (creator && creator->IsHandled(lpFileName))
{
return creator->CreateFileA(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes,
dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
}
}
}
/* FIXME: at this point lpFileName is not necessary a named pipe */
/* * */
if (!IsNamedPipeFileNameA(lpFileName))
return INVALID_HANDLE_VALUE;
name = GetNamedPipeNameWithoutPrefixA(lpFileName);