winpr-file: introduced HANDLE_CREATOR type
winpr-comm: got a _CommHandleCreator
This commit is contained in:
parent
f9fc107c20
commit
7e44488e0a
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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",
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user