862 lines
23 KiB
C
862 lines
23 KiB
C
|
/*++
|
||
|
|
||
|
Copyright (c) 1996 Microsoft Corporation
|
||
|
|
||
|
Module Name:
|
||
|
|
||
|
tapi.c
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
This file provides all access to tapi.
|
||
|
|
||
|
Environment:
|
||
|
|
||
|
WIN32 User Mode
|
||
|
|
||
|
Author:
|
||
|
|
||
|
Wesley Witt (wesw) 17-Feb-1996
|
||
|
|
||
|
--*/
|
||
|
|
||
|
#include "wizard.h"
|
||
|
#pragma hdrstop
|
||
|
|
||
|
#include <initguid.h>
|
||
|
#include <devguid.h>
|
||
|
|
||
|
DWORD TapiApiVersion;
|
||
|
HLINEAPP hLineApp;
|
||
|
HANDLE TapiEvent;
|
||
|
DWORD TapiDevices;
|
||
|
DWORD FaxDevices;
|
||
|
PLINE_INFO LineInfo;
|
||
|
DWORD CurrentLocationId;
|
||
|
DWORD CurrentCountryId;
|
||
|
LPTSTR CurrentAreaCode;
|
||
|
|
||
|
|
||
|
#include "modem.c"
|
||
|
|
||
|
|
||
|
LONG
|
||
|
MyLineGetTransCaps(
|
||
|
LPLINETRANSLATECAPS *LineTransCaps
|
||
|
)
|
||
|
{
|
||
|
DWORD LineTransCapsSize;
|
||
|
LONG Rslt = ERROR_SUCCESS;
|
||
|
|
||
|
|
||
|
//
|
||
|
// allocate the initial linetranscaps structure
|
||
|
//
|
||
|
|
||
|
LineTransCapsSize = sizeof(LINETRANSLATECAPS) + 4096;
|
||
|
*LineTransCaps = (LPLINETRANSLATECAPS) MemAlloc( LineTransCapsSize );
|
||
|
if (!*LineTransCaps) {
|
||
|
DebugPrint(( TEXT("MemAlloc() failed, sz=0x%08x"), LineTransCapsSize ));
|
||
|
Rslt = ERROR_NOT_ENOUGH_MEMORY;
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
(*LineTransCaps)->dwTotalSize = LineTransCapsSize;
|
||
|
|
||
|
Rslt = lineGetTranslateCaps(
|
||
|
hLineApp,
|
||
|
TapiApiVersion,
|
||
|
*LineTransCaps
|
||
|
);
|
||
|
|
||
|
if (Rslt != 0) {
|
||
|
DebugPrint(( TEXT("lineGetTranslateCaps() failed, ec=0x%08x"), Rslt ));
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
if ((*LineTransCaps)->dwNeededSize > (*LineTransCaps)->dwTotalSize) {
|
||
|
|
||
|
//
|
||
|
// re-allocate the LineTransCaps structure
|
||
|
//
|
||
|
|
||
|
LineTransCapsSize = (*LineTransCaps)->dwNeededSize;
|
||
|
|
||
|
MemFree( *LineTransCaps );
|
||
|
|
||
|
*LineTransCaps = (LPLINETRANSLATECAPS) MemAlloc( LineTransCapsSize );
|
||
|
if (!*LineTransCaps) {
|
||
|
DebugPrint(( TEXT("MemAlloc() failed, sz=0x%08x"), LineTransCapsSize ));
|
||
|
Rslt = ERROR_NOT_ENOUGH_MEMORY;
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
(*LineTransCaps)->dwTotalSize = LineTransCapsSize;
|
||
|
|
||
|
Rslt = lineGetTranslateCaps(
|
||
|
hLineApp,
|
||
|
TapiApiVersion,
|
||
|
*LineTransCaps
|
||
|
);
|
||
|
|
||
|
if (Rslt != 0) {
|
||
|
DebugPrint(( TEXT("lineGetTranslateCaps() failed, ec=0x%08x"), Rslt ));
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
exit:
|
||
|
if (Rslt != ERROR_SUCCESS) {
|
||
|
MemFree( *LineTransCaps );
|
||
|
*LineTransCaps = NULL;
|
||
|
}
|
||
|
|
||
|
return Rslt;
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL
|
||
|
LookFor351Modems(
|
||
|
VOID
|
||
|
)
|
||
|
{
|
||
|
TCHAR FileName[MAX_PATH*2];
|
||
|
TCHAR Ports[128];
|
||
|
|
||
|
|
||
|
|
||
|
if (!ExpandEnvironmentStrings( TEXT("%windir%\\system32\\ras\\serial.ini"), FileName, sizeof(FileName)/sizeof(TCHAR) )) {
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
if (!GetPrivateProfileSectionNames( Ports, sizeof(Ports), FileName )) {
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
|
||
|
DWORD
|
||
|
DeviceInitThread(
|
||
|
HWND hwnd
|
||
|
)
|
||
|
{
|
||
|
DWORD rVal = 0;
|
||
|
LONG Rslt;
|
||
|
LINEINITIALIZEEXPARAMS LineInitializeExParams;
|
||
|
LINEEXTENSIONID lineExtensionID;
|
||
|
DWORD LineDevCapsSize;
|
||
|
LPLINEDEVCAPS LineDevCaps = NULL;
|
||
|
LPTSTR DeviceClassList;
|
||
|
BOOL UnimodemDevice;
|
||
|
DWORD i;
|
||
|
LPLINETRANSLATECAPS LineTransCaps = NULL;
|
||
|
LPLINELOCATIONENTRY LineLocation = NULL;
|
||
|
BOOL FirstTime = TRUE;
|
||
|
BOOL NoClass1 = FALSE;
|
||
|
LPTSTR p;
|
||
|
DWORD Answer;
|
||
|
DWORD LocalTapiApiVersion;
|
||
|
|
||
|
HKEY hKey;
|
||
|
DWORD ValType;
|
||
|
DWORD ValSize;
|
||
|
|
||
|
PMDM_DEVSPEC MdmDevSpec;
|
||
|
LPSTR ModemKey = NULL;
|
||
|
UINT Res;
|
||
|
TCHAR AdaptiveFileName[MAX_PATH*2];
|
||
|
HANDLE AdaptiveFileHandle;
|
||
|
BOOL AdaptiveFileExists = FALSE;
|
||
|
TCHAR Drive[_MAX_DRIVE];
|
||
|
TCHAR Dir[_MAX_DIR];
|
||
|
|
||
|
#define AdaptiveFileMaxSize 20000
|
||
|
BYTE AdaptiveFileBuffer[AdaptiveFileMaxSize]; // temporary needed. Currently < 1K anyway.
|
||
|
DWORD BytesHaveRead;
|
||
|
|
||
|
#define RespKeyMaxSize 1000
|
||
|
BYTE RespKeyName[RespKeyMaxSize];
|
||
|
|
||
|
|
||
|
if (hLineApp) {
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
LineInitializeExParams.dwTotalSize = sizeof(LINEINITIALIZEEXPARAMS);
|
||
|
LineInitializeExParams.dwNeededSize = 0;
|
||
|
LineInitializeExParams.dwUsedSize = 0;
|
||
|
LineInitializeExParams.dwOptions = LINEINITIALIZEEXOPTION_USEEVENT;
|
||
|
LineInitializeExParams.Handles.hEvent = NULL;
|
||
|
LineInitializeExParams.dwCompletionKey = 0;
|
||
|
|
||
|
LocalTapiApiVersion = TapiApiVersion = 0x00020000;
|
||
|
|
||
|
if (!Unattended) {
|
||
|
SetDlgItemText(
|
||
|
hwnd,
|
||
|
IDC_DEVICE_PROGRESS_TEXT,
|
||
|
GetString( IDS_INIT_TAPI )
|
||
|
);
|
||
|
}
|
||
|
|
||
|
if (LookFor351Modems()) {
|
||
|
PopUpMsg( hwnd, IDS_351_MODEM, TRUE, 0 );
|
||
|
}
|
||
|
|
||
|
init_again:
|
||
|
Rslt = lineInitializeEx(
|
||
|
&hLineApp,
|
||
|
FaxWizModuleHandle,
|
||
|
NULL,
|
||
|
TEXT("Fax Setup"),
|
||
|
&TapiDevices,
|
||
|
&LocalTapiApiVersion,
|
||
|
&LineInitializeExParams
|
||
|
);
|
||
|
|
||
|
if (Rslt != 0) {
|
||
|
DebugPrint(( TEXT("lineInitializeEx() failed, ec=0x%08x"), Rslt ));
|
||
|
hLineApp = NULL;
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
if (!FirstTime) {
|
||
|
PopUpMsg( hwnd, IDS_NO_TAPI_DEVICES, TRUE, 0 );
|
||
|
ExitProcess(0);
|
||
|
}
|
||
|
|
||
|
if (TapiDevices == 0) {
|
||
|
if (NtGuiMode) {
|
||
|
//
|
||
|
// if running in nt gui mode setup and there
|
||
|
// are no tapi devices then we do nothing,
|
||
|
// but do allow the setup to continue.
|
||
|
//
|
||
|
lineShutdown( hLineApp );
|
||
|
hLineApp = NULL;
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
Answer = PopUpMsg( hwnd, IDS_NO_MODEM, FALSE, MB_YESNO );
|
||
|
if (Answer == IDYES) {
|
||
|
if (!CallModemInstallWizard( hwnd )) {
|
||
|
DebugPrint(( TEXT("CallModemInstallWizard() failed, ec=0x%08x"), GetLastError() ));
|
||
|
}
|
||
|
} else {
|
||
|
DebugPrint(( TEXT("No tapi devices, user declined") ));
|
||
|
}
|
||
|
FirstTime = FALSE;
|
||
|
lineShutdown( hLineApp );
|
||
|
hLineApp = NULL;
|
||
|
goto init_again;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// determine the current location information
|
||
|
//
|
||
|
|
||
|
Rslt = MyLineGetTransCaps( &LineTransCaps );
|
||
|
if (Rslt != ERROR_SUCCESS) {
|
||
|
if (Rslt == LINEERR_INIFILECORRUPT) {
|
||
|
//
|
||
|
// need to set the location information
|
||
|
//
|
||
|
if (!NtGuiMode) {
|
||
|
Rslt = lineTranslateDialog( hLineApp, 0, LocalTapiApiVersion, hwnd, NULL );
|
||
|
if (Rslt == ERROR_SUCCESS) {
|
||
|
Rslt = MyLineGetTransCaps( &LineTransCaps );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if (Rslt != ERROR_SUCCESS) {
|
||
|
DebugPrint(( TEXT("MyLineGetTransCaps() failed, ec=0x%08x"), Rslt ));
|
||
|
goto exit;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
LineLocation = (LPLINELOCATIONENTRY) ((LPBYTE)LineTransCaps + LineTransCaps->dwLocationListOffset);
|
||
|
for (i=0; i<LineTransCaps->dwNumLocations; i++) {
|
||
|
if (LineTransCaps->dwCurrentLocationID == LineLocation[i].dwPermanentLocationID) {
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (i == LineTransCaps->dwNumLocations) {
|
||
|
DebugPrint(( TEXT("Could not determine the current location information") ));
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
CurrentLocationId = LineTransCaps->dwCurrentLocationID;
|
||
|
CurrentCountryId = LineLocation->dwCountryID;
|
||
|
CurrentAreaCode = StringDup( (LPTSTR) ((LPBYTE)LineTransCaps + LineLocation->dwCityCodeOffset) );
|
||
|
|
||
|
//
|
||
|
// allocate the lineinfo structure
|
||
|
//
|
||
|
|
||
|
TapiEvent = LineInitializeExParams.Handles.hEvent;
|
||
|
|
||
|
LineInfo = (PLINE_INFO) MemAlloc( TapiDevices * sizeof(LINE_INFO) );
|
||
|
if (!LineInfo) {
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// allocate the initial linedevcaps structure
|
||
|
//
|
||
|
|
||
|
LineDevCapsSize = sizeof(LINEDEVCAPS) + 4096;
|
||
|
LineDevCaps = (LPLINEDEVCAPS) MemAlloc( LineDevCapsSize );
|
||
|
if (!LineDevCaps) {
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
if (!Unattended) {
|
||
|
SendMessage( hwnd, WM_MY_PROGRESS, 0xff, TapiDevices * 20 );
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// open FaxAdapt.lst file to decide on enabling RX
|
||
|
// try executable directory first, then- system directory
|
||
|
//
|
||
|
|
||
|
if ( ! GetModuleFileName( FaxWizModuleHandle, AdaptiveFileName, sizeof(AdaptiveFileName) ) ) {
|
||
|
DebugPrint(( TEXT("GetModuleFileName fails , ec=0x%08x "), GetLastError() ));
|
||
|
goto l0;
|
||
|
}
|
||
|
|
||
|
_tsplitpath( AdaptiveFileName, Drive, Dir, NULL, NULL );
|
||
|
_stprintf( AdaptiveFileName, TEXT("%s%s"), Drive, Dir );
|
||
|
|
||
|
if ( _tcslen(AdaptiveFileName) + _tcslen( TEXT("FAXADAPT.LST") ) >= MAX_PATH ) {
|
||
|
DebugPrint(( TEXT("GetCurrentDirectory() too long , MAX_PATH = %d"), MAX_PATH ));
|
||
|
goto l0;
|
||
|
}
|
||
|
|
||
|
_tcscat (AdaptiveFileName, (TEXT ("FAXADAPT.LST")) );
|
||
|
|
||
|
if ( (AdaptiveFileHandle = CreateFile(AdaptiveFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL) )
|
||
|
== INVALID_HANDLE_VALUE ) {
|
||
|
|
||
|
DebugPrint(( TEXT("Could not open adaptive file %s ec=0x%08x"), AdaptiveFileName, GetLastError() ));
|
||
|
goto l0;
|
||
|
}
|
||
|
|
||
|
if (! ReadFile(AdaptiveFileHandle, AdaptiveFileBuffer, AdaptiveFileMaxSize, &BytesHaveRead, NULL ) ) {
|
||
|
DebugPrint(( TEXT("Could not read adaptive file %s ec=0x%08x"), AdaptiveFileName, GetLastError() ));
|
||
|
CloseHandle(AdaptiveFileHandle);
|
||
|
goto l1;
|
||
|
}
|
||
|
|
||
|
if (BytesHaveRead >= AdaptiveFileMaxSize) {
|
||
|
DebugPrint(( TEXT("Adaptive file %s is too big - %d bytes"), AdaptiveFileName, BytesHaveRead ));
|
||
|
CloseHandle(AdaptiveFileHandle);
|
||
|
goto l1;
|
||
|
}
|
||
|
|
||
|
CloseHandle(AdaptiveFileHandle);
|
||
|
|
||
|
AdaptiveFileBuffer[BytesHaveRead] = 0; // need a string
|
||
|
AdaptiveFileExists = TRUE;
|
||
|
|
||
|
goto l1;
|
||
|
|
||
|
//
|
||
|
// only if there is no file in the current directory.
|
||
|
//
|
||
|
|
||
|
l0:
|
||
|
|
||
|
Res = GetSystemDirectory( AdaptiveFileName, MAX_PATH);
|
||
|
if (Res == 0) {
|
||
|
DebugPrint(( TEXT("GetSystemDirectory() failed 0, ec=0x%08x"), GetLastError() ));
|
||
|
goto l1;
|
||
|
}
|
||
|
else if (Res > MAX_PATH) {
|
||
|
DebugPrint(( TEXT("GetSystemDirectory() failed > MAX_PATH = %d"), MAX_PATH ));
|
||
|
goto l1;
|
||
|
}
|
||
|
|
||
|
if (Res + _tcslen( TEXT("\\FAXADAPT.LST") ) >= MAX_PATH ) {
|
||
|
DebugPrint(( TEXT("GetSystemDirectory() too long %d, MAX_PATH = %d"), Res, MAX_PATH ));
|
||
|
goto l1;
|
||
|
}
|
||
|
|
||
|
_tcscat (AdaptiveFileName, (TEXT ("\\FAXADAPT.LST")) );
|
||
|
|
||
|
if ( (AdaptiveFileHandle = CreateFile(AdaptiveFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL) )
|
||
|
== INVALID_HANDLE_VALUE ) {
|
||
|
|
||
|
DebugPrint(( TEXT("Could not open adaptive file %s ec=0x%08x"), AdaptiveFileName, GetLastError() ));
|
||
|
goto l1;
|
||
|
}
|
||
|
|
||
|
if (! ReadFile(AdaptiveFileHandle, AdaptiveFileBuffer, AdaptiveFileMaxSize, &BytesHaveRead, NULL ) ) {
|
||
|
DebugPrint(( TEXT("Could not read adaptive file %s ec=0x%08x"), AdaptiveFileName, GetLastError() ));
|
||
|
CloseHandle(AdaptiveFileHandle);
|
||
|
goto l1;
|
||
|
}
|
||
|
|
||
|
if (BytesHaveRead >= AdaptiveFileMaxSize) {
|
||
|
DebugPrint(( TEXT("Adaptive file %s is too big - %d bytes"), AdaptiveFileName, BytesHaveRead ));
|
||
|
CloseHandle(AdaptiveFileHandle);
|
||
|
goto l1;
|
||
|
}
|
||
|
|
||
|
CloseHandle(AdaptiveFileHandle);
|
||
|
|
||
|
AdaptiveFileBuffer[BytesHaveRead] = 0; // need a string
|
||
|
AdaptiveFileExists = TRUE;
|
||
|
|
||
|
|
||
|
l1:
|
||
|
//
|
||
|
// enumerate all of the tapi devices
|
||
|
//
|
||
|
|
||
|
i = 0;
|
||
|
|
||
|
do {
|
||
|
|
||
|
Rslt = lineNegotiateAPIVersion(
|
||
|
hLineApp,
|
||
|
i,
|
||
|
0x00010003,
|
||
|
TapiApiVersion,
|
||
|
&LocalTapiApiVersion,
|
||
|
&lineExtensionID
|
||
|
);
|
||
|
if (Rslt != 0) {
|
||
|
DebugPrint(( TEXT("lineNegotiateAPIVersion() failed, ec=0x%08x"), Rslt ));
|
||
|
goto next_device;
|
||
|
}
|
||
|
|
||
|
ZeroMemory( LineDevCaps, LineDevCapsSize );
|
||
|
LineDevCaps->dwTotalSize = LineDevCapsSize;
|
||
|
|
||
|
Rslt = lineGetDevCaps(
|
||
|
hLineApp,
|
||
|
i,
|
||
|
LocalTapiApiVersion,
|
||
|
0,
|
||
|
LineDevCaps
|
||
|
);
|
||
|
|
||
|
if (Rslt != 0) {
|
||
|
DebugPrint(( TEXT("lineGetDevCaps() failed, ec=0x%08x"), Rslt ));
|
||
|
goto next_device;
|
||
|
}
|
||
|
|
||
|
if (LineDevCaps->dwNeededSize > LineDevCaps->dwTotalSize) {
|
||
|
|
||
|
//
|
||
|
// re-allocate the linedevcaps structure
|
||
|
//
|
||
|
|
||
|
LineDevCapsSize = LineDevCaps->dwNeededSize;
|
||
|
|
||
|
MemFree( LineDevCaps );
|
||
|
|
||
|
LineDevCaps = (LPLINEDEVCAPS) MemAlloc( LineDevCapsSize );
|
||
|
if (!LineDevCaps) {
|
||
|
rVal = ERROR_NOT_ENOUGH_MEMORY;
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
Rslt = lineGetDevCaps(
|
||
|
hLineApp,
|
||
|
i,
|
||
|
TapiApiVersion,
|
||
|
0,
|
||
|
LineDevCaps
|
||
|
);
|
||
|
|
||
|
if (Rslt != 0) {
|
||
|
DebugPrint(( TEXT("lineGetDevCaps() failed, ec=0x%08x"), Rslt ));
|
||
|
goto next_device;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
if (!Unattended) {
|
||
|
SendMessage( hwnd, WM_MY_PROGRESS, 10, 0 );
|
||
|
}
|
||
|
|
||
|
if (!Unattended) {
|
||
|
SetDlgItemText(
|
||
|
hwnd,
|
||
|
IDC_DEVICE_PROGRESS_TEXT,
|
||
|
(LPTSTR)((LPBYTE) LineDevCaps + LineDevCaps->dwLineNameOffset)
|
||
|
);
|
||
|
}
|
||
|
|
||
|
if (TapiApiVersion != 0x00020000) {
|
||
|
DebugPrint((
|
||
|
TEXT("TAPI device is incompatible with the FAX server: %s"),
|
||
|
(LPTSTR)((LPBYTE) LineDevCaps + LineDevCaps->dwLineNameOffset)
|
||
|
));
|
||
|
goto next_device;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// save the line id
|
||
|
//
|
||
|
|
||
|
LineInfo[FaxDevices].PermanentLineID = LineDevCaps->dwPermanentLineID;
|
||
|
LineInfo[FaxDevices].DeviceName = StringDup( (LPTSTR)((LPBYTE) LineDevCaps + LineDevCaps->dwLineNameOffset) );
|
||
|
LineInfo[FaxDevices].ProviderName = StringDup( (LPTSTR)((LPBYTE) LineDevCaps + LineDevCaps->dwProviderInfoOffset) );
|
||
|
LineInfo[FaxDevices].Rings = LineDevCaps->dwLineStates & LINEDEVSTATE_RINGING ? 2 : 0;
|
||
|
LineInfo[FaxDevices].Flags = FPF_RECEIVE | FPF_SEND;
|
||
|
|
||
|
//
|
||
|
// filter out the commas because the spooler hates them
|
||
|
//
|
||
|
|
||
|
p = LineInfo[FaxDevices].DeviceName;
|
||
|
while( p ) {
|
||
|
p = _tcschr( p, TEXT(',') );
|
||
|
if (p) {
|
||
|
*p = TEXT('_');
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// check for a modem device
|
||
|
//
|
||
|
|
||
|
UnimodemDevice = FALSE;
|
||
|
|
||
|
if (LineDevCaps->dwDeviceClassesSize && LineDevCaps->dwDeviceClassesOffset) {
|
||
|
DeviceClassList = (LPTSTR)((LPBYTE) LineDevCaps + LineDevCaps->dwDeviceClassesOffset);
|
||
|
while (*DeviceClassList) {
|
||
|
if (_tcscmp(DeviceClassList,TEXT("comm/datamodem")) == 0) {
|
||
|
UnimodemDevice = TRUE;
|
||
|
break;
|
||
|
}
|
||
|
DeviceClassList += (_tcslen(DeviceClassList) + 1);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ((!(LineDevCaps->dwBearerModes & LINEBEARERMODE_VOICE)) ||
|
||
|
(!(LineDevCaps->dwBearerModes & LINEBEARERMODE_PASSTHROUGH))) {
|
||
|
//
|
||
|
// unacceptable modem device type
|
||
|
//
|
||
|
UnimodemDevice = FALSE;
|
||
|
}
|
||
|
|
||
|
if (UnimodemDevice) {
|
||
|
|
||
|
LINECALLPARAMS LineCallParams;
|
||
|
HCALL hCall = NULL;
|
||
|
HLINE hLine = NULL;
|
||
|
LINEMESSAGE LineMessage;
|
||
|
DWORD RequestId;
|
||
|
|
||
|
|
||
|
LineInfo[FaxDevices].Flags = FPF_SEND; // Unimodem default
|
||
|
|
||
|
Rslt = lineOpen(
|
||
|
hLineApp,
|
||
|
i,
|
||
|
&hLine,
|
||
|
TapiApiVersion,
|
||
|
0,
|
||
|
0,
|
||
|
LINECALLPRIVILEGE_OWNER,
|
||
|
UnimodemDevice ? LINEMEDIAMODE_DATAMODEM : LINEMEDIAMODE_G3FAX,
|
||
|
NULL
|
||
|
);
|
||
|
if (Rslt != 0) {
|
||
|
DebugPrint(( TEXT("lineOpen() failed, ec=0x%08x"), Rslt ));
|
||
|
goto next_device;
|
||
|
}
|
||
|
|
||
|
|
||
|
//
|
||
|
// Get Unimodem key to search Adaptive list.
|
||
|
//
|
||
|
|
||
|
if (! AdaptiveFileExists) {
|
||
|
goto l2;
|
||
|
}
|
||
|
|
||
|
if (! LineDevCaps->dwDevSpecificSize) {
|
||
|
goto l2;
|
||
|
}
|
||
|
|
||
|
MdmDevSpec = (PMDM_DEVSPEC) ((LPBYTE) LineDevCaps + LineDevCaps->dwDevSpecificOffset);
|
||
|
if (MdmDevSpec->Contents == 1 && MdmDevSpec->KeyOffset == 8) {
|
||
|
ModemKey = MdmDevSpec->String;
|
||
|
}
|
||
|
else {
|
||
|
goto l2;
|
||
|
}
|
||
|
|
||
|
if (!ModemKey) {
|
||
|
DebugPrint(( TEXT("Can't get Unimodem key") ));
|
||
|
goto l2;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Get ResponsesKeyName
|
||
|
//
|
||
|
|
||
|
Rslt = RegOpenKeyExA(
|
||
|
HKEY_LOCAL_MACHINE,
|
||
|
ModemKey,
|
||
|
0,
|
||
|
KEY_READ,
|
||
|
&hKey);
|
||
|
|
||
|
if (Rslt != ERROR_SUCCESS) {
|
||
|
DebugPrint(( TEXT("Can't open Unimodem key") ));
|
||
|
goto l2;
|
||
|
}
|
||
|
|
||
|
ValSize = RespKeyMaxSize;
|
||
|
|
||
|
Rslt = RegQueryValueExA(
|
||
|
hKey,
|
||
|
"ResponsesKeyName",
|
||
|
0,
|
||
|
&ValType,
|
||
|
RespKeyName,
|
||
|
&ValSize);
|
||
|
|
||
|
RegCloseKey(hKey);
|
||
|
|
||
|
if (Rslt != ERROR_SUCCESS) {
|
||
|
DebugPrint(( TEXT("Can't get Unimodem ResponsesKeyName") ));
|
||
|
goto l2;
|
||
|
}
|
||
|
|
||
|
if ( (ValSize >= RespKeyMaxSize) || (ValSize == 0) ) {
|
||
|
DebugPrint(( TEXT("Unimodem ResponsesKeyName key is invalid %d"), RespKeyMaxSize ));
|
||
|
goto l2;
|
||
|
}
|
||
|
|
||
|
if (!RespKeyName) {
|
||
|
DebugPrint(( TEXT("Unimodem ResponsesKeyName key is NULL") ));
|
||
|
goto l2;
|
||
|
}
|
||
|
|
||
|
_strupr(RespKeyName);
|
||
|
|
||
|
//
|
||
|
// check to see if this modem is defined in Adaptive modem list
|
||
|
//
|
||
|
|
||
|
if ( strstr (AdaptiveFileBuffer, RespKeyName) ) {
|
||
|
|
||
|
// enable receive on this device: it is adaptive answer capable.
|
||
|
|
||
|
LineInfo[FaxDevices].Flags = FPF_RECEIVE | FPF_SEND;
|
||
|
}
|
||
|
|
||
|
l2:
|
||
|
ZeroMemory( &LineCallParams, sizeof(LineCallParams) );
|
||
|
LineCallParams.dwTotalSize = sizeof(LINECALLPARAMS);
|
||
|
LineCallParams.dwBearerMode = LINEBEARERMODE_PASSTHROUGH;
|
||
|
hCall = NULL;
|
||
|
|
||
|
Rslt = lineMakeCall( hLine, &hCall, NULL, 0, &LineCallParams );
|
||
|
if (Rslt > 0) {
|
||
|
|
||
|
#define IDVARSTRINGSIZE (sizeof(VARSTRING)+128)
|
||
|
PDEVICEID DeviceID = NULL;
|
||
|
LPVARSTRING LineIdBuffer = MemAlloc( IDVARSTRINGSIZE );
|
||
|
LineIdBuffer->dwTotalSize = IDVARSTRINGSIZE;
|
||
|
RequestId = (DWORD) Rslt;
|
||
|
|
||
|
//
|
||
|
// wait for the call to complete
|
||
|
//
|
||
|
|
||
|
while( TRUE ) {
|
||
|
if (WaitForSingleObject( TapiEvent, 5 * 60 * 1000 ) == WAIT_TIMEOUT) {
|
||
|
DebugPrint(( TEXT("Setup never received a tapi event") ));
|
||
|
rVal = ERROR_INVALID_FUNCTION;
|
||
|
goto exit;
|
||
|
}
|
||
|
Rslt = lineGetMessage( hLineApp, &LineMessage, 0 );
|
||
|
if (Rslt == 0) {
|
||
|
if (LineMessage.dwMessageID == LINE_REPLY && LineMessage.dwParam1 == RequestId) {
|
||
|
switch (LineMessage.dwParam2) {
|
||
|
case 0:
|
||
|
break;
|
||
|
|
||
|
case LINEERR_CALLUNAVAIL:
|
||
|
DebugPrint(( TEXT("lineMakeCall() failed (LINE_REPLY), ec=0x%08x"), LineMessage.dwParam2 ));
|
||
|
goto next_device;
|
||
|
|
||
|
default:
|
||
|
DebugPrint(( TEXT("lineMakeCall() failed (LINE_REPLY), ec=0x%08x"), LineMessage.dwParam2 ));
|
||
|
rVal = LineMessage.dwParam2;
|
||
|
goto exit;
|
||
|
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// get the comm handle
|
||
|
//
|
||
|
|
||
|
Rslt = lineGetID(
|
||
|
hLine,
|
||
|
0,
|
||
|
hCall,
|
||
|
LINECALLSELECT_CALL,
|
||
|
LineIdBuffer,
|
||
|
TEXT("comm/datamodem")
|
||
|
);
|
||
|
if (Rslt == 0 && LineIdBuffer->dwStringFormat == STRINGFORMAT_BINARY &&
|
||
|
LineIdBuffer->dwUsedSize >= sizeof(DEVICEID)) {
|
||
|
|
||
|
DeviceID = (PDEVICEID) ((LPBYTE)(LineIdBuffer)+LineIdBuffer->dwStringOffset);
|
||
|
if (GetModemClass( DeviceID->hComm ) != 1) {
|
||
|
|
||
|
Rslt = LINEERR_BADDEVICEID;
|
||
|
NoClass1 = TRUE;
|
||
|
DebugPrint(( TEXT("GetModemClass() failed, ec=0x%08x"), Rslt ));
|
||
|
|
||
|
} else {
|
||
|
|
||
|
FaxDevices += 1;
|
||
|
|
||
|
}
|
||
|
|
||
|
CloseHandle( DeviceID->hComm );
|
||
|
|
||
|
} else {
|
||
|
|
||
|
DebugPrint(( TEXT("lineGetID() failed, ec=0x%08x"), Rslt ));
|
||
|
|
||
|
}
|
||
|
|
||
|
MemFree( LineIdBuffer );
|
||
|
|
||
|
} else {
|
||
|
|
||
|
DebugPrint(( TEXT("lineMakeCall() failed, ec=0x%08x"), Rslt ));
|
||
|
|
||
|
}
|
||
|
|
||
|
if (hCall) {
|
||
|
lineDeallocateCall( hCall );
|
||
|
}
|
||
|
|
||
|
if (hLine) {
|
||
|
lineClose( hLine );
|
||
|
}
|
||
|
|
||
|
} else {
|
||
|
|
||
|
if (LineDevCaps->dwMediaModes & LINEMEDIAMODE_G3FAX) {
|
||
|
|
||
|
//
|
||
|
// save the line id
|
||
|
//
|
||
|
|
||
|
FaxDevices += 1;
|
||
|
}
|
||
|
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
next_device:
|
||
|
if (!Unattended) {
|
||
|
SendMessage( hwnd, WM_MY_PROGRESS, 10, 0 );
|
||
|
Sleep( 1000 );
|
||
|
}
|
||
|
i += 1;
|
||
|
|
||
|
} while ( i < TapiDevices );
|
||
|
|
||
|
|
||
|
exit:
|
||
|
|
||
|
MemFree( LineDevCaps );
|
||
|
MemFree( LineTransCaps );
|
||
|
|
||
|
lineShutdown( hLineApp );
|
||
|
|
||
|
if ((rVal != 0) || (FaxDevices == 0)) {
|
||
|
if (NtGuiMode) {
|
||
|
//
|
||
|
// if running in nt gui mode setup and there
|
||
|
// are no tapi devices then we do nothing,
|
||
|
// but do allow the setup to continue.
|
||
|
//
|
||
|
hLineApp = NULL;
|
||
|
return 0;
|
||
|
}
|
||
|
PopUpMsg( hwnd, NoClass1 ? IDS_NO_CLASS1 : IDS_NO_TAPI_DEVICES, TRUE, 0 );
|
||
|
ExitProcess(0);
|
||
|
}
|
||
|
|
||
|
if (!Unattended) {
|
||
|
SetWindowLong( hwnd, DWL_MSGRESULT, 0 );
|
||
|
PropSheet_PressButton( GetParent(hwnd), PSBTN_NEXT );
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL
|
||
|
CallModemInstallWizard(
|
||
|
HWND hwnd
|
||
|
)
|
||
|
|
||
|
/* call the Modem.Cpl install wizard to enable the user to install one or more modems
|
||
|
**
|
||
|
** Return TRUE if the wizard was successfully invoked, FALSE otherwise
|
||
|
**
|
||
|
*/
|
||
|
{
|
||
|
HDEVINFO hdi;
|
||
|
BOOL fReturn = FALSE;
|
||
|
// Create a modem DeviceInfoSet
|
||
|
|
||
|
hdi = SetupDiCreateDeviceInfoList((LPGUID)&GUID_DEVCLASS_MODEM, hwnd);
|
||
|
if (hdi)
|
||
|
{
|
||
|
SP_INSTALLWIZARD_DATA iwd;
|
||
|
|
||
|
// Initialize the InstallWizardData
|
||
|
|
||
|
ZeroMemory(&iwd, sizeof(iwd));
|
||
|
iwd.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
|
||
|
iwd.ClassInstallHeader.InstallFunction = DIF_INSTALLWIZARD;
|
||
|
iwd.hwndWizardDlg = hwnd;
|
||
|
|
||
|
// Set the InstallWizardData as the ClassInstallParams
|
||
|
|
||
|
if (SetupDiSetClassInstallParams(hdi, NULL, (PSP_CLASSINSTALL_HEADER)&iwd, sizeof(iwd)))
|
||
|
{
|
||
|
// Call the class installer to invoke the installation
|
||
|
// wizard.
|
||
|
if (SetupDiCallClassInstaller(DIF_INSTALLWIZARD, hdi, NULL))
|
||
|
{
|
||
|
// Success. The wizard was invoked and finished.
|
||
|
// Now cleanup.
|
||
|
fReturn = TRUE;
|
||
|
|
||
|
SetupDiCallClassInstaller(DIF_DESTROYWIZARDDATA, hdi, NULL);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Clean up
|
||
|
SetupDiDestroyDeviceInfoList(hdi);
|
||
|
}
|
||
|
return fReturn;
|
||
|
}
|