NT4/private/unimodem/tapisp/devioctl.c
2020-09-30 17:12:29 +02:00

1161 lines
27 KiB
C

//****************************************************************************
//
// Module: Unimdm
// File: devioctl.c
//
// Copyright (c) 1992-1995, Microsoft Corporation, all rights reserved
//
// Revision History
//
//
// 5/16/95 Viroon Touranachun Moved from mdmutil.c
//
//
// Description: Interface to kernel-mode unimodem
//
//****************************************************************************
#include "unimdm.h"
#include "umdmspi.h"
#ifdef WINNT
#ifndef USE_SERVICECONTROLLER
// # error "Unimplemented"
#define MODEM_SERVICE_NAME \
L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\modem"
#endif // USE_SERVICECONTROLLER
// Global variable for the modem.sys service
BOOL bModemSysStarted = FALSE;
CRITICAL_SECTION ServiceControlerCriticalSection;
#endif // WINNT
LONG WINAPI
MCXSetModemSettings(
HANDLE hModem,
PMODEMSETTINGS lpMS
);
//****************************************************************************
// DWORD MapMcxResult (DWORD)
//
// Function: Maps internal error to a standard error code.
//
// Returns: standard error code
//
// Fri 14-Apr-1995 12:47:26 -by- Viroon Touranachun [viroont]
// created
//****************************************************************************
DWORD MapMcxResult (DWORD dwResult)
{
switch (dwResult)
{
case MDM_SUCCESS:
return ERROR_SUCCESS;
case MDM_PENDING:
return ERROR_IO_PENDING;
default:
return ERROR_IO_DEVICE;
}
}
#ifdef USE_SERVICECONTROLLER
LONG WINAPI
StartModemDriver(
VOID
)
{
LONG lResult=ERROR_SUCCESS; // Assume success
BOOL bResult;
SC_HANDLE schModemSys;
SC_HANDLE schSCManager;
SERVICE_STATUS ServiceStatus;
EnterCriticalSection(
&ServiceControlerCriticalSection
);
if (!bModemSysStarted) {
schSCManager=OpenSCManager(
NULL,
NULL,
SC_MANAGER_ALL_ACCESS
);
if (schSCManager != NULL) {
//
// now on service
//
schModemSys=OpenService(
schSCManager,
TEXT("modem"),
SERVICE_START | SERVICE_STOP | SERVICE_QUERY_STATUS
);
if (schModemSys == NULL) {
DPRINTF("OpenService() for modem.sys failed!");
CloseServiceHandle(schSCManager);
lResult=ERROR_IO_DEVICE;
goto Leave;
}
bResult=QueryServiceStatus(
schModemSys,
&ServiceStatus
);
if (bResult) {
if (ServiceStatus.dwCurrentState != SERVICE_RUNNING) {
bResult=StartService(
schModemSys,
0,
NULL
);
if (bResult) {
DPRINTF("StartService() for modem.sys succeeded!");
bModemSysStarted=TRUE;
} else {
DPRINTF("StartService() for modem.sys FAILED!");
lResult = GetLastError();
}
} else {
bModemSysStarted=TRUE;
}
} else {
lResult = GetLastError();
DPRINTF1("QueryServiceStatus() for modem.sys failed (%d)!", lResult);
}
CloseServiceHandle(schModemSys);
CloseServiceHandle(schSCManager);
} else {
DPRINTF("OpenSCManager() failed!");
lResult=ERROR_IO_DEVICE;
} // if opened SC macanger
} else {
//
// already running
//
}
Leave:
LeaveCriticalSection(
&ServiceControlerCriticalSection
);
return lResult;
}
LONG WINAPI
StopModemDriver(
VOID
)
{
LONG lResult;
BOOL bResult;
SC_HANDLE schModemSys;
SC_HANDLE schSCManager;
SERVICE_STATUS ServiceStatus;
EnterCriticalSection(
&ServiceControlerCriticalSection
);
if (bModemSysStarted) {
schSCManager=OpenSCManager(
NULL,
NULL,
SC_MANAGER_ALL_ACCESS
);
if (schSCManager != NULL) {
//
// now on service
//
schModemSys=OpenService(
schSCManager,
TEXT("modem"),
SERVICE_START | SERVICE_STOP | SERVICE_QUERY_STATUS
);
if (schModemSys != NULL) {
bResult=ControlService(
schModemSys,
SERVICE_CONTROL_STOP,
&ServiceStatus
);
if (bResult) {
bModemSysStarted=TRUE;
}
CloseServiceHandle(schModemSys);
}
CloseServiceHandle(schSCManager);
}
}
LeaveCriticalSection(
&ServiceControlerCriticalSection
);
return ERROR_SUCCESS;
}
#else // !USE_SERVICECONTROLLER
BOOL WINAPI
ObtainLoadDriverPrivilege(
IN PBOOLEAN WasEnabled
) {
NTSTATUS Status;
DPRINTF("ObtainLoadDriverPrivilege");
//
// Obtain the process's access token for the current thread
//
Status = RtlImpersonateSelf(SecurityImpersonation);
if (!NT_SUCCESS(Status)) {
DPRINTF1("RtlImpersonateSelf returned 0x%08x", Status);
return FALSE;
}
//
// request "Load-Driver" privileges for this thread
//
Status = RtlAdjustPrivilege(
SE_LOAD_DRIVER_PRIVILEGE,
TRUE,
TRUE,
WasEnabled
);
if (!NT_SUCCESS(Status)) {
DPRINTF1("RtlAdjustPrivileges returned 0x%08x", Status);
RevertToSelf();
return FALSE;
}
return TRUE;
}
VOID WINAPI
ReleaseLoadDriverPrivilege(
IN PBOOLEAN WasEnabled
) {
NTSTATUS Status;
DPRINTF("ReleaseLoadDriverPrivilege");
//
// See if we had to enable SE_LOAD_DRIVER_PRIVILEGE
//
if (!*WasEnabled) {
//
// relinquish "Load-Driver" privileges for this thread
//
Status = RtlAdjustPrivilege(
SE_LOAD_DRIVER_PRIVILEGE,
FALSE,
TRUE,
WasEnabled
);
}
//
// return the thread to its previous access token
//
RevertToSelf();
}
// # error "Unimplemented"
static WCHAR g_rgwchBuffer[] = MODEM_SERVICE_NAME;
static UNICODE_STRING g_usDriverName = {
sizeof(g_rgwchBuffer)-sizeof(WCHAR), //Length
sizeof(g_rgwchBuffer), //MaximumLength
g_rgwchBuffer //Buffer
};
LONG WINAPI
StartModemDriver(
VOID
)
{
LONG lResult=ERROR_SUCCESS;
EnterCriticalSection(
&ServiceControlerCriticalSection
);
while (!bModemSysStarted) { // breakout-construct
NTSTATUS nts;
BOOLEAN WasEnabled;
//
// Enable our load-driver privilege
//
if (!ObtainLoadDriverPrivilege(&WasEnabled)) {
lResult = ERROR_ACCESS_DENIED;
break;
}
//
// Load modem.sys
//
nts = NtLoadDriver(&g_usDriverName);
if (NT_SUCCESS(nts) || nts==STATUS_IMAGE_ALREADY_LOADED)
{
DPRINTF1("NtLoadDriver returns %s",
(nts==STATUS_IMAGE_ALREADY_LOADED)
? TEXT("Already loaded")
: TEXT("Success"));
bModemSysStarted=TRUE;
}
else
{
DPRINTF1("ERROR: NtLoadDriver fails(0x%lx)", (DWORD) nts);
lResult=ERROR_IO_DEVICE;
}
//
// relinquish "Load-Driver" privileges for this thread
//
ReleaseLoadDriverPrivilege(&WasEnabled);
break;
}
LeaveCriticalSection(
&ServiceControlerCriticalSection
);
return lResult;
}
LONG WINAPI
StopModemDriver(
VOID
)
{
LONG lResult=ERROR_SUCCESS;
EnterCriticalSection(
&ServiceControlerCriticalSection
);
while (bModemSysStarted) { // break-out construct
NTSTATUS nts;
BOOLEAN WasEnabled;
//
// Enable our load-driver privilege
//
if (!ObtainLoadDriverPrivilege(&WasEnabled)) {
lResult = ERROR_ACCESS_DENIED;
break;
}
//
// Unload modem.sys
//
nts = NtUnloadDriver(&g_usDriverName);
if (NT_SUCCESS(nts))
{
DPRINTF("NtUnloadDriver succeeded");
bModemSysStarted=FALSE;
}
else
{
DPRINTF1("ERROR: NtUnloadDriver fails(0x%lx)", (DWORD) nts);
lResult=ERROR_IO_DEVICE;
}
//
// relinquish "Load-Driver" privileges for this thread
//
ReleaseLoadDriverPrivilege(&WasEnabled);
break;
}
LeaveCriticalSection(
&ServiceControlerCriticalSection
);
return lResult;
}
#endif // !USE_SERVICECONTROLLER
//****************************************************************************
// DWORD OpenModem (PLINEDEV)
//
// Function: Opens the modem device.
//
// Notes: This function never returns success synchrnously
//
// Returns: ERROR_IO_PENDING if the operation will complete asynchronously
// an error code for synchrnous failure
//
// Fri 14-Apr-1995 12:47:26 -by- Viroon Touranachun [viroont]
// created
//****************************************************************************
DWORD OpenModem(PLINEDEV pLineDev, LPBYTE lpComConfig, DWORD dwSize)
{
HANDLE hComm;
DCB dcb;
TCHAR szPort[MAXDEVICENAME+1];
DWORD dwRet;
SERVICE_STATUS ServiceStatus;
BOOL bResult;
TSPPRINTF("Open modem");
dwRet=StartModemDriver();
if (dwRet != ERROR_SUCCESS) {
return dwRet;
}
// Initialize szPort to be "\\.\"
lstrcpy(szPort, cszDevicePrefix);
// Concatenate FriendlyName onto szPort to form "\\.\Modem Name"
lstrcat(szPort, pLineDev->szDeviceName);
TSPPRINTF1("Device Name = %s", szPort);
// Open the modem port
//
hComm = CreateFile(szPort,
GENERIC_WRITE | GENERIC_READ,
FILE_SHARE_WRITE | FILE_SHARE_READ,
NULL,
OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
if (hComm == INVALID_HANDLE_VALUE)
{
dwRet = GetLastError();
TSPPRINTF1("hComm CreateFile() failed! (%d)", dwRet);
return dwRet;
};
if (!PurgeComm(hComm, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR) ) {
dwRet = GetLastError();
CloseHandle(hComm);
return dwRet;
}
ASSERT(ghCompletionPort != NULL);
if (CreateIoCompletionPort(hComm,
ghCompletionPort,
(DWORD)pLineDev,
0) == NULL)
{
dwRet = GetLastError();
CloseHandle(hComm);
return dwRet;
}
SetupComm (hComm, 4096, 4096);
// Open Mcx handle
//
if ((dwRet = MCXOpen(pLineDev->szDeviceName,
hComm,
pLineDev->szDriverKey,
&pLineDev->hModem,
pLineDev->dwID,
(DWORD)pLineDev))
== ERROR_SUCCESS)
{
pLineDev->hDevice = hComm;
// Set the modem configuration
//
UnimodemSetCommConfig(pLineDev, (LPCOMMCONFIG)lpComConfig, dwSize);
}
else
{
CloseHandle(hComm);
};
return (MapMcxResult(dwRet));
}
//****************************************************************************
// DWORD CloseModem (PLINEDEV)
//
// Function: Opens the modem device.
//
// Notes: This function never returns success synchrnously
//
// Returns: ERROR_IO_PENDING if the operation will complete asynchronously
// an error code for synchrnous failure
//
// Fri 14-Apr-1995 12:47:26 -by- Viroon Touranachun [viroont]
// created
//****************************************************************************
DWORD CloseModem (PLINEDEV pLineDev)
{
TSPPRINTF("Close modem");
//
// close comm handle as well
//
MCXClose(
pLineDev->hModem,
pLineDev->hDevice,
pLineDev->LineClosed
);
pLineDev->hModem = NULL;
pLineDev->hDevice = INVALID_DEVICE;
return ERROR_SUCCESS;
}
//****************************************************************************
// DWORD UnimodemInit (PLINEDEV)
//
// Function: Initializes the modem device.
//
// Notes: This function never returns success synchrnously
//
// Returns: ERROR_IO_PENDING if the operation will complete asynchronously
// an error code for synchrnous failure
//
// Fri 14-Apr-1995 12:47:26 -by- Viroon Touranachun [viroont]
// created
//****************************************************************************
DWORD UnimodemInit (PLINEDEV pLineDev)
{
MCX_IN mcxi;
DWORD dwRet;
LPCOMMCONFIG lpCommConfig;
lpCommConfig = (LPCOMMCONFIG)&(pLineDev->pDevCfg->commconfig);
// set the new configuration
//
UnimodemSetCommConfig(pLineDev,
lpCommConfig, lpCommConfig->dwSize);
// Prepare the input/output information
//
pLineDev->dwVxdPendingID++;
mcxi.dwReqID = pLineDev->dwVxdPendingID;
mcxi.pMcxOut = &pLineDev->McxOut;
pLineDev->McxOut.dwReqID = mcxi.dwReqID;
pLineDev->McxOut.dwResult = MDM_FAILURE;
TSPPRINTF1("UnimodemInit id: %d", pLineDev->dwVxdPendingID);
pLineDev->InitStringsAreValid=TRUE;
dwRet = MCXInit(pLineDev->hModem, &mcxi);
dwRet = MapMcxResult(dwRet);
// If the MCX call returns success, converts it to async success
//
if (dwRet == ERROR_SUCCESS)
{
// The operation completes successfully synchronously
//
dwRet = ERROR_IO_PENDING;
pLineDev->McxOut.dwResult = MDM_SUCCESS;
PostQueuedCompletionStatus(ghCompletionPort,
CP_BYTES_WRITTEN(0),
(DWORD)pLineDev,
NULL);
};
return dwRet;
}
//****************************************************************************
// DWORD UnimodemDial (PLINEDEV, LPSTR)
//
// Function: dials the modem device with the provided dialable string. A dial-
// able string can be:
// "" - originate
// ";" - dialtone detection
// "5551212" - dial and originate
// "5551212;" - dial
//
// Notes: This function never returns success synchrnously
//
// Returns: ERROR_IO_PENDING if the operation will complete asynchronously
// an error code for synchrnous failure
//
// Fri 14-Apr-1995 12:47:26 -by- Viroon Touranachun [viroont]
// created
//****************************************************************************
DWORD
UnimodemDial(
PLINEDEV pLineDev,
LPSTR szAddress,
DWORD DialOptions
)
{
MCX_IN mcxi;
DWORD dwRet;
char szPhone[MAXADDRESSLEN+1];
// Prepare the input/output information
//
pLineDev->dwVxdPendingID++;
mcxi.dwReqID = pLineDev->dwVxdPendingID;
mcxi.pMcxOut = &pLineDev->McxOut;
pLineDev->McxOut.dwReqID = mcxi.dwReqID;
pLineDev->McxOut.dwResult = MDM_FAILURE;
lstrcpyA(szPhone, szAddress);
TSPPRINTF1("UnmodemDial id: %d", pLineDev->dwVxdPendingID);
dwRet = MCXDial(pLineDev->hModem, szPhone, &mcxi, DialOptions);
dwRet = MapMcxResult(dwRet);
// If the MCX call returns success, converts it to async success
//
if (dwRet == ERROR_SUCCESS)
{
// The operation completes successfully synchronously
//
dwRet = ERROR_IO_PENDING;
pLineDev->McxOut.dwResult = MDM_SUCCESS;
PostQueuedCompletionStatus(ghCompletionPort,
CP_BYTES_WRITTEN(0),
(DWORD)pLineDev,
NULL);
};
return dwRet;
}
//****************************************************************************
// DWORD UnimodemMonitor (PLINEDEV, DWORD)
//
// Function: Monitors the modem for an incoming call in two modes:
// MONITOR_NON_CONTINUOUS - Notify the first ring only
// MONITOR_CONTINUOUS - Notify each ring
//
// Notes: This function never returns success synchrnously
//
// Returns: ERROR_IO_PENDING if the operation will complete asynchronously
// an error code for synchrnous failure
//
// Fri 14-Apr-1995 12:47:26 -by- Viroon Touranachun [viroont]
// created
//****************************************************************************
DWORD UnimodemMonitor (PLINEDEV pLineDev, DWORD dwType)
{
MCX_IN mcxi;
DWORD dwRet;
// Prepare the input/output information
//
pLineDev->dwVxdPendingID++;
mcxi.dwReqID = pLineDev->dwVxdPendingID;
mcxi.pMcxOut = &pLineDev->McxOut;
pLineDev->McxOut.dwReqID = mcxi.dwReqID;
pLineDev->McxOut.dwResult = MDM_FAILURE;
TSPPRINTF1("UnmodemMonitor id: %d", pLineDev->dwVxdPendingID);
dwRet = MCXMonitor(pLineDev->hModem, dwType, &mcxi);
dwRet = MapMcxResult(dwRet);
// If the MCX call returns success, converts it to async success
//
if (dwRet == ERROR_SUCCESS)
{
// The operation completes successfully synchronously
//
dwRet = ERROR_IO_PENDING;
pLineDev->McxOut.dwResult = MDM_SUCCESS;
PostQueuedCompletionStatus(ghCompletionPort,
CP_BYTES_WRITTEN(0),
(DWORD)pLineDev,
NULL);
};
return dwRet;
}
//****************************************************************************
// DWORD UnimodemAnswer (PLINEDEV)
//
// Function: Answers the incoming call..
//
// Notes: This function never returns success synchrnously
//
// Returns: ERROR_IO_PENDING if the operation will complete asynchronously
// an error code for synchrnous failure
//
// Fri 14-Apr-1995 12:47:26 -by- Viroon Touranachun [viroont]
// created
//****************************************************************************
DWORD UnimodemAnswer (PLINEDEV pLineDev)
{
MCX_IN mcxi;
DWORD dwRet;
// Prepare the input/output information
//
pLineDev->dwVxdPendingID++;
mcxi.dwReqID = pLineDev->dwVxdPendingID;
mcxi.pMcxOut = &pLineDev->McxOut;
pLineDev->McxOut.dwReqID = mcxi.dwReqID;
pLineDev->McxOut.dwResult = MDM_FAILURE;
TSPPRINTF1("UnmodemAnswer id: %d", pLineDev->dwVxdPendingID);
dwRet = MCXAnswer(pLineDev->hModem, &mcxi);
dwRet = MapMcxResult(dwRet);
// If the MCX call returns success, converts it to async success
//
if (dwRet == ERROR_SUCCESS)
{
// The operation completes successfully synchronously
//
dwRet = ERROR_IO_PENDING;
pLineDev->McxOut.dwResult = MDM_SUCCESS;
PostQueuedCompletionStatus(ghCompletionPort,
CP_BYTES_WRITTEN(0),
(DWORD)pLineDev,
NULL);
};
return dwRet;
}
VOID WINAPI
DisconnectHandler(
PLINEDEV pLineDev
)
{
TSPPRINTF("DisconnectHandle:");
NEW_CALLSTATE(pLineDev, LINECALLSTATE_DISCONNECTED, LINEDISCONNECTMODE_NORMAL);
return;
}
//****************************************************************************
// DWORD UnimodemMonitorDisconnect (PLINEDEV)
//
// Function: Monitors the remote disconnection. When the remote disconnection
// occurs, the function completes successfully in the async thread.
//
// Notes: This function never returns success synchrnously
//
// Returns: ERROR_IO_PENDING if the operation will complete asynchronously
// an error code for synchrnous failure
//
// Fri 14-Apr-1995 12:47:26 -by- Viroon Touranachun [viroont]
// created
//****************************************************************************
DWORD UnimodemMonitorDisconnect (PLINEDEV pLineDev)
{
DWORD Result;
Result=McxRegisterDisconectHandler(
pLineDev->hModem,
DisconnectHandler,
pLineDev
);
return Result;
}
//****************************************************************************
// DWORD UnimodemCancelMonitorDisconnect (PLINEDEV)
//
// Function: Cancel the pending monitoring remote disconnection request.
// The async thread always ignore the cancellation result.
//
// Notes: This function is synchronous.
//
// Returns: ERROR_SUCCESS if success
// an error code for failure
//
// Fri 14-Apr-1995 12:47:26 -by- Viroon Touranachun [viroont]
// created
//****************************************************************************
DWORD UnimodemCancelMonitorDisconnect (PLINEDEV pLineDev)
{
DWORD dwRet;
dwRet=McxDeregisterDisconnectHandler(
pLineDev->hModem
);
return dwRet;
}
//****************************************************************************
// DWORD UnimodemHangup (PLINEDEV, BOOL)
//
// Function: Disconnect the modem locally. The caller can specifies whether
// the function should complete synchrnously or asynchronously.
//
// Returns: ERROR_SUCCESS if success synchronously.
// ERROR_IO_PENDING if the operation will complete asynchronously
// an error code for failure
//
// Fri 14-Apr-1995 12:47:26 -by- Viroon Touranachun [viroont]
// created
//****************************************************************************
DWORD UnimodemHangup (PLINEDEV pLineDev, BOOL fSync)
{
MCX_IN mcxi;
DWORD dwRet;
if(!fSync)
{
// Asynchronous request, use the default event
//
pLineDev->dwVxdPendingID++;
TSPPRINTF1("UnmodemAsyncHangup id: %d", pLineDev->dwVxdPendingID);
}
else
{
// Synchronous request, create a local event so we can wait for it here
//
if ((pLineDev->hSynchronizeEvent = CreateEvent(NULL, FALSE, FALSE, NULL)) == NULL)
{
return ERROR_OUTOFMEMORY;
};
TSPPRINTF("UnmodemSyncHangup");
};
// Prepare the input/output information
//
mcxi.dwReqID = pLineDev->dwVxdPendingID;
mcxi.pMcxOut = &pLineDev->McxOut;
pLineDev->McxOut.dwReqID = mcxi.dwReqID;
pLineDev->McxOut.dwResult = MDM_FAILURE;
// Hang up the line
//
dwRet = MCXHangup(pLineDev->hModem, &mcxi);
dwRet = MapMcxResult(dwRet);
switch(dwRet)
{
case ERROR_SUCCESS:
//
// The operation completes successfully synchronously
//
pLineDev->McxOut.dwResult = MDM_SUCCESS;
// If the operation is an async request, handles the result asynchronously
//
if (fSync)
{
TSPPRINTF("UnmodemSyncHangup completes");
CloseHandle(pLineDev->hSynchronizeEvent);
pLineDev->hSynchronizeEvent = NULL;
}
else
{
dwRet = ERROR_IO_PENDING;
PostQueuedCompletionStatus(ghCompletionPort,
CP_BYTES_WRITTEN(0),
(DWORD)pLineDev,
NULL);
};
break;
case ERROR_IO_PENDING:
//
// If it is synchronous request, need to wait until it is done
//
if (fSync)
{
RELEASE_LINEDEV(pLineDev);
WaitForSingleObject(pLineDev->hSynchronizeEvent, INFINITE);
CLAIM_LINEDEV(pLineDev);
CloseHandle(pLineDev->hSynchronizeEvent);
pLineDev->hSynchronizeEvent = NULL;
dwRet = ERROR_SUCCESS;
};
break;
default:
break;
};
return dwRet;
}
//****************************************************************************
// DWORD UnimodemGetCommConfig (PLINEDEV, LPCOMMCONFIG, LPDWORD)
//
// Function: Gets the modem comm configuration
//
// Notes: This function is synchronous.
//
// Returns: ERROR_SUCCESS if success
// an error code for failure
//
// Fri 14-Apr-1995 12:47:26 -by- Viroon Touranachun [viroont]
// created
//****************************************************************************
DWORD UnimodemGetCommConfig (PLINEDEV pLineDev, LPCOMMCONFIG lpCommConfig,
LPDWORD lpcb)
{
DWORD dwRet;
TSPPRINTF("UnimodemGetCommConfig.");
dwRet = MCXGetCommConfig(pLineDev->hModem, lpCommConfig, lpcb);
return (MapMcxResult(dwRet));
}
//****************************************************************************
// DWORD UnimodemSetCommConfig (PLINEDEV, LPCOMMCONFIG, DWORD)
//
// Function: Sets the modem comm configuration
//
// Notes: This function is synchronous.
//
// Returns: ERROR_SUCCESS if success
// an error code for failure
//
// Fri 14-Apr-1995 12:47:26 -by- Viroon Touranachun [viroont]
// created
//****************************************************************************
DWORD UnimodemSetCommConfig (PLINEDEV pLineDev, LPCOMMCONFIG lpCommConfig,
DWORD cb)
{
DWORD dwRet;
TSPPRINTF("UnimodemSetCommConfig.");
dwRet = MCXSetCommConfig(pLineDev->hModem, lpCommConfig, cb);
return (MapMcxResult(dwRet));
}
#if 0
//****************************************************************************
// DWORD UnimodemSetCommConfig (PLINEDEV, LPCOMMCONFIG, DWORD)
//
// Function: Sets the modem comm configuration
//
// Notes: This function is synchronous.
//
// Returns: ERROR_SUCCESS if success
// an error code for failure
//
// Fri 14-Apr-1995 12:47:26 -by- Viroon Touranachun [viroont]
// created
//****************************************************************************
DWORD WINAPI
UnimodemSetModemSettings(
PLINEDEV pLineDev,
LPMODEMSETTINGS lpModemSettings
)
{
DWORD dwRet;
TSPPRINTF("UnimodemSetModemSettings.");
dwRet = MCXSetModemSettings(pLineDev->hModem, lpModemSettings);
return (MapMcxResult(dwRet));
}
#endif
//****************************************************************************
// DWORD UnimodemSetPassthrough (PLINEDEV, DWORD)
//
// Function: Sets the modem passthrough mode to:
// PASSTHROUGH_ON
// PASSTHROUGH_OFF
// PASSTHROUGH_OFF_BUT_CONNECTED
//
// Notes: This function is synchronous.
//
// Returns: ERROR_SUCCESS if success
// an error code for failure
//
// Fri 14-Apr-1995 12:47:26 -by- Viroon Touranachun [viroont]
// created
//****************************************************************************
DWORD UnimodemSetPassthrough (PLINEDEV pLineDev, DWORD dwMode)
{
DWORD dwRet;
TSPPRINTF1("UnimodemSetPassthrough mode: %d", dwMode);
dwRet = MCXSetPassthrough(pLineDev->hModem, dwMode);
return (MapMcxResult(dwRet));
}
//****************************************************************************
// DWORD UnimodemGetNegotiatedRate (PLINEDEV, LPDWORD)
//
// Function: Gets the modem connection speed
//
// Notes: This function is synchronous.
//
// Returns: ERROR_SUCCESS if success
// an error code for failure
//
// Fri 14-Apr-1995 12:47:26 -by- Viroon Touranachun [viroont]
// created
//****************************************************************************
DWORD UnimodemGetNegotiatedRate (PLINEDEV pLineDev, LPDWORD lpdwRate)
{
DWORD dwRet;
dwRet = MCXGetNegotiatedRate(pLineDev->hModem, lpdwRate);
return (MapMcxResult(dwRet));
}