You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
459 lines
10 KiB
459 lines
10 KiB
/*++
|
|
|
|
Copyright (c) 1990-2003 Microsoft Corporation
|
|
All rights reserved
|
|
|
|
Module Name:
|
|
|
|
xcv.c
|
|
|
|
Abstract:
|
|
|
|
Implements xcv functions.
|
|
|
|
// @@BEGIN_DDKSPLIT
|
|
Author:
|
|
|
|
Environment:
|
|
|
|
User Mode -Win32
|
|
|
|
Revision History:
|
|
// @@END_DDKSPLIT
|
|
--*/
|
|
|
|
#include "precomp.h"
|
|
#pragma hdrstop
|
|
|
|
//
|
|
// The ddk montior samples will be build with the name ddklocalmon and ddklocalui
|
|
// so they can be installed without clashing with existing files
|
|
//
|
|
// @@BEGIN_DDKSPLIT
|
|
#if 0
|
|
// @@END_DDKSPLIT
|
|
//
|
|
// change this to the name of the dll that provides the ui for the monitor
|
|
//
|
|
#define SZLOCALUI L"DDKLocalUI.dll"
|
|
// @@BEGIN_DDKSPLIT
|
|
#endif
|
|
|
|
#define SZLOCALUI L"LocalUI.dll"
|
|
// @@END_DDKSPLIT
|
|
|
|
DWORD
|
|
GetMonitorUI(
|
|
PBYTE pInputData,
|
|
DWORD cbInputData,
|
|
PBYTE pOutputData,
|
|
DWORD cbOutputData,
|
|
PDWORD pcbOutputNeeded,
|
|
PINIXCVPORT pIniXcv
|
|
);
|
|
|
|
DWORD
|
|
DoPortExists(
|
|
PBYTE pInputData,
|
|
DWORD cbInputData,
|
|
PBYTE pOutputData,
|
|
DWORD cbOutputData,
|
|
PDWORD pcbOutputNeeded,
|
|
PINIXCVPORT pIniXcv
|
|
);
|
|
|
|
DWORD
|
|
DoPortIsValid(
|
|
PBYTE pInputData,
|
|
DWORD cbInputData,
|
|
PBYTE pOutputData,
|
|
DWORD cbOutputData,
|
|
PDWORD pcbOutputNeeded,
|
|
PINIXCVPORT pIniXcv
|
|
);
|
|
|
|
DWORD
|
|
DoDeletePort(
|
|
PBYTE pInputData,
|
|
DWORD cbInputData,
|
|
PBYTE pOutputData,
|
|
DWORD cbOutputData,
|
|
PDWORD pcbOutputNeeded,
|
|
PINIXCVPORT pIniXcv
|
|
);
|
|
|
|
DWORD
|
|
DoAddPort(
|
|
PBYTE pInputData,
|
|
DWORD cbInputData,
|
|
PBYTE pOutputData,
|
|
DWORD cbOutputData,
|
|
PDWORD pcbOutputNeeded,
|
|
PINIXCVPORT pIniXcv
|
|
);
|
|
|
|
DWORD
|
|
DoSetDefaultCommConfig(
|
|
PBYTE pInputData,
|
|
DWORD cbInputData,
|
|
PBYTE pOutputData,
|
|
DWORD cbOutputData,
|
|
PDWORD pcbOutputNeeded,
|
|
PINIXCVPORT pIniXcv
|
|
);
|
|
|
|
DWORD
|
|
DoGetDefaultCommConfig(
|
|
PBYTE pInputData,
|
|
DWORD cbInputData,
|
|
PBYTE pOutputData,
|
|
DWORD cbOutputData,
|
|
PDWORD pcbOutputNeeded,
|
|
PINIXCVPORT pIniXcv
|
|
);
|
|
|
|
|
|
DWORD
|
|
GetTransmissionRetryTimeout(
|
|
PBYTE pInputData,
|
|
DWORD cbInputData,
|
|
PBYTE pOutputData,
|
|
DWORD cbOutputData,
|
|
PDWORD pcbOutputNeeded,
|
|
PINIXCVPORT pIniXcv
|
|
);
|
|
|
|
|
|
typedef struct {
|
|
PWSTR pszMethod;
|
|
DWORD (*pfn)( PBYTE pInputData,
|
|
DWORD cbInputData,
|
|
PBYTE pOutputData,
|
|
DWORD cbOutputData,
|
|
PDWORD pcbOutputNeeded,
|
|
PINIXCVPORT pIniXcv
|
|
);
|
|
} XCV_METHOD, *PXCV_METHOD;
|
|
|
|
|
|
XCV_METHOD gpLcmXcvMethod[] = {
|
|
{L"MonitorUI", GetMonitorUI},
|
|
{L"ConfigureLPTPortCommandOK", ConfigureLPTPortCommandOK},
|
|
{L"AddPort", DoAddPort},
|
|
{L"DeletePort", DoDeletePort},
|
|
{L"PortExists", DoPortExists},
|
|
{L"PortIsValid", DoPortIsValid},
|
|
{L"GetTransmissionRetryTimeout", GetTransmissionRetryTimeout},
|
|
{L"SetDefaultCommConfig", DoSetDefaultCommConfig},
|
|
{L"GetDefaultCommConfig", DoGetDefaultCommConfig},
|
|
{NULL, NULL}
|
|
};
|
|
|
|
DWORD
|
|
LcmXcvDataPort(
|
|
HANDLE hXcv,
|
|
LPCWSTR pszDataName,
|
|
PBYTE pInputData,
|
|
DWORD cbInputData,
|
|
PBYTE pOutputData,
|
|
DWORD cbOutputData,
|
|
PDWORD pcbOutputNeeded
|
|
)
|
|
{
|
|
DWORD dwRet;
|
|
DWORD i;
|
|
|
|
for(i = 0 ; gpLcmXcvMethod[i].pszMethod &&
|
|
wcscmp(gpLcmXcvMethod[i].pszMethod, pszDataName) ; ++i)
|
|
;
|
|
|
|
if (gpLcmXcvMethod[i].pszMethod) {
|
|
dwRet = (*gpLcmXcvMethod[i].pfn)( pInputData,
|
|
cbInputData,
|
|
pOutputData,
|
|
cbOutputData,
|
|
pcbOutputNeeded,
|
|
(PINIXCVPORT) hXcv);
|
|
|
|
} else {
|
|
dwRet = ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
return dwRet;
|
|
}
|
|
|
|
BOOL
|
|
LcmXcvOpenPort(
|
|
HANDLE hMonitor,
|
|
LPCWSTR pszObject,
|
|
ACCESS_MASK GrantedAccess,
|
|
PHANDLE phXcv
|
|
)
|
|
{
|
|
PINILOCALMON pIniLocalMon = (PINILOCALMON)hMonitor;
|
|
*phXcv = CreateXcvPortEntry(pIniLocalMon, pszObject, GrantedAccess);
|
|
|
|
return !!*phXcv;
|
|
}
|
|
|
|
|
|
BOOL
|
|
LcmXcvClosePort(
|
|
HANDLE hXcv
|
|
)
|
|
{
|
|
LcmEnterSplSem();
|
|
DeleteXcvPortEntry((PINIXCVPORT) hXcv);
|
|
LcmLeaveSplSem();
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
DWORD
|
|
DoDeletePort(
|
|
PBYTE pInputData,
|
|
DWORD cbInputData,
|
|
PBYTE pOutputData,
|
|
DWORD cbOutputData,
|
|
PDWORD pcbOutputNeeded,
|
|
PINIXCVPORT pIniXcv
|
|
)
|
|
{
|
|
DWORD dwRet = ERROR_SUCCESS;
|
|
|
|
if (!(pIniXcv->GrantedAccess & SERVER_ACCESS_ADMINISTER))
|
|
return ERROR_ACCESS_DENIED;
|
|
|
|
LcmEnterSplSem();
|
|
|
|
if (LcmDeletePortEntry( pIniXcv->pIniLocalMon, (PWSTR)pInputData))
|
|
WriteProfileString(szPorts, (PWSTR) pInputData, NULL);
|
|
else
|
|
dwRet = ERROR_FILE_NOT_FOUND;
|
|
|
|
LcmLeaveSplSem();
|
|
|
|
return dwRet;
|
|
}
|
|
|
|
|
|
DWORD
|
|
DoPortExists(
|
|
PBYTE pInputData,
|
|
DWORD cbInputData,
|
|
PBYTE pOutputData,
|
|
DWORD cbOutputData,
|
|
PDWORD pcbOutputNeeded,
|
|
PINIXCVPORT pIniXcv
|
|
)
|
|
{
|
|
DWORD dwRet;
|
|
BOOL bPortExists;
|
|
|
|
*pcbOutputNeeded = sizeof(DWORD);
|
|
|
|
if (cbOutputData < sizeof(DWORD)) {
|
|
return ERROR_INSUFFICIENT_BUFFER;
|
|
}
|
|
|
|
bPortExists = PortExists(NULL, (PWSTR) pInputData, &dwRet);
|
|
|
|
if (dwRet == ERROR_SUCCESS)
|
|
*(DWORD *) pOutputData = bPortExists;
|
|
|
|
return dwRet;
|
|
}
|
|
|
|
|
|
DWORD
|
|
DoPortIsValid(
|
|
PBYTE pInputData,
|
|
DWORD cbInputData,
|
|
PBYTE pOutputData,
|
|
DWORD cbOutputData,
|
|
PDWORD pcbOutputNeeded,
|
|
PINIXCVPORT pIniXcv
|
|
)
|
|
{
|
|
BOOL bRet;
|
|
|
|
bRet = PortIsValid((PWSTR) pInputData);
|
|
|
|
return bRet ? ERROR_SUCCESS : GetLastError();
|
|
}
|
|
|
|
|
|
|
|
DWORD
|
|
DoAddPort(
|
|
PBYTE pInputData,
|
|
DWORD cbInputData,
|
|
PBYTE pOutputData,
|
|
DWORD cbOutputData,
|
|
PDWORD pcbOutputNeeded,
|
|
PINIXCVPORT pIniXcv
|
|
)
|
|
{
|
|
DWORD dwRet, bPortExists;
|
|
PINIPORT pIniPort = NULL;
|
|
|
|
if (!(pIniXcv->GrantedAccess & SERVER_ACCESS_ADMINISTER))
|
|
return ERROR_ACCESS_DENIED;
|
|
|
|
if ( cbInputData == 0 ||
|
|
pInputData == NULL ||
|
|
( wcslen((LPWSTR)pInputData) + 1 ) * sizeof(WCHAR) != cbInputData )
|
|
return ERROR_INVALID_PARAMETER;
|
|
|
|
bPortExists = PortExists(NULL, (PWSTR) pInputData, &dwRet);
|
|
|
|
if (dwRet == ERROR_SUCCESS) {
|
|
if (bPortExists) {
|
|
SetLastError(ERROR_ALREADY_EXISTS);
|
|
} else {
|
|
pIniPort = LcmCreatePortEntry( pIniXcv->pIniLocalMon, (PWSTR)pInputData );
|
|
|
|
if (pIniPort) {
|
|
if (!WriteProfileString(szPorts, (PWSTR) pInputData, L""))
|
|
{
|
|
LcmDeletePortEntry(pIniXcv->pIniLocalMon, (PWSTR) pInputData);
|
|
pIniPort = NULL;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return pIniPort ? ERROR_SUCCESS : GetLastError();
|
|
}
|
|
|
|
|
|
DWORD
|
|
DoSetDefaultCommConfig(
|
|
PBYTE pInputData,
|
|
DWORD cbInputData,
|
|
PBYTE pOutputData,
|
|
DWORD cbOutputData,
|
|
PDWORD pcbOutputNeeded,
|
|
PINIXCVPORT pIniXcv
|
|
)
|
|
{
|
|
BOOL bRet = FALSE;
|
|
DWORD dwLength;
|
|
PWSTR pszPortName = NULL;
|
|
COMMCONFIG *pCommConfig = (COMMCONFIG *) pInputData;
|
|
|
|
if (!(pIniXcv->GrantedAccess & SERVER_ACCESS_ADMINISTER))
|
|
return ERROR_ACCESS_DENIED;
|
|
|
|
dwLength = wcslen(pIniXcv->pszName);
|
|
if (pIniXcv->pszName[dwLength - 1] == L':') {
|
|
if (!(pszPortName = AllocSplStr(pIniXcv->pszName)))
|
|
goto Done;
|
|
pszPortName[dwLength - 1] = L'\0';
|
|
}
|
|
|
|
bRet = SetDefaultCommConfig(pszPortName,
|
|
pCommConfig,
|
|
pCommConfig->dwSize);
|
|
|
|
Done:
|
|
|
|
FreeSplStr(pszPortName);
|
|
|
|
return bRet ? ERROR_SUCCESS : GetLastError();
|
|
}
|
|
|
|
|
|
DWORD
|
|
DoGetDefaultCommConfig(
|
|
PBYTE pInputData,
|
|
DWORD cbInputData,
|
|
PBYTE pOutputData,
|
|
DWORD cbOutputData,
|
|
PDWORD pcbOutputNeeded,
|
|
PINIXCVPORT pIniXcv
|
|
)
|
|
{
|
|
PWSTR pszPortName = (PWSTR) pInputData;
|
|
COMMCONFIG *pCommConfig = (COMMCONFIG *) pOutputData;
|
|
BOOL bRet;
|
|
|
|
|
|
if (cbOutputData < sizeof(COMMCONFIG))
|
|
return ERROR_INSUFFICIENT_BUFFER;
|
|
|
|
pCommConfig->dwProviderSubType = PST_RS232;
|
|
*pcbOutputNeeded = cbOutputData;
|
|
|
|
bRet = GetDefaultCommConfig(pszPortName, pCommConfig, pcbOutputNeeded);
|
|
|
|
return bRet ? ERROR_SUCCESS : GetLastError();
|
|
}
|
|
|
|
DWORD
|
|
GetTransmissionRetryTimeout(
|
|
PBYTE pInputData,
|
|
DWORD cbInputData,
|
|
PBYTE pOutputData,
|
|
DWORD cbOutputData,
|
|
PDWORD pcbOutputNeeded,
|
|
PINIXCVPORT pIniXcv
|
|
)
|
|
{
|
|
*pcbOutputNeeded = sizeof(DWORD);
|
|
|
|
if (cbOutputData < sizeof(DWORD))
|
|
return ERROR_INSUFFICIENT_BUFFER;
|
|
|
|
*(PDWORD) pOutputData = GetProfileInt(szWindows,
|
|
szINIKey_TransmissionRetryTimeout,
|
|
45 );
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
DWORD
|
|
GetMonitorUI(
|
|
PBYTE pInputData,
|
|
DWORD cbInputData,
|
|
PBYTE pOutputData,
|
|
DWORD cbOutputData,
|
|
PDWORD pcbOutputNeeded,
|
|
PINIXCVPORT pIniXcv
|
|
)
|
|
{
|
|
DWORD dwRet;
|
|
|
|
*pcbOutputNeeded = sizeof( SZLOCALUI );
|
|
|
|
if (cbOutputData < *pcbOutputNeeded) {
|
|
|
|
dwRet = ERROR_INSUFFICIENT_BUFFER;
|
|
|
|
} else {
|
|
|
|
dwRet = HRESULT_CODE (StringCbCopy ((PWSTR) pOutputData, cbOutputData, SZLOCALUI));
|
|
}
|
|
|
|
return dwRet;
|
|
}
|
|
|
|
|
|
DWORD
|
|
ConfigureLPTPortCommandOK(
|
|
PBYTE pInputData,
|
|
DWORD cbInputData,
|
|
PBYTE pOutputData,
|
|
DWORD cbOutputData,
|
|
PDWORD pcbOutputNeeded,
|
|
PINIXCVPORT pIniXcv
|
|
)
|
|
{
|
|
if (!(pIniXcv->GrantedAccess & SERVER_ACCESS_ADMINISTER))
|
|
return ERROR_ACCESS_DENIED;
|
|
|
|
if (!WriteProfileString( szWindows, szINIKey_TransmissionRetryTimeout, (PWSTR) pInputData ))
|
|
return GetLastError();
|
|
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|