Александр |
Отправлено: 14.05.2004, 15:08 |
|
Не зарегистрирован
|
если ли у кгого рабочий пример использования TAPI (версия 2), когда можно получить handle открытого через TAPI com-порта и работать с ним уже как просто с com-портом, а не с TAPI-устройством?
ниже мой пример.
инициализация tapi проходит нормально, а вот WriteFile по полученному handle от com-порта возвращает ошибку.
в упор не ясно почему.
CODE |
#include <windows.h>
#include <tapi.h>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include "io.hpp"
std::ostream& os = std::cerr;
const std::string getSystemMessage( int error )
{
LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
error,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL
);
std::string msg;
if (lpMsgBuf)
msg.assign((const char*)lpMsgBuf);
LocalFree(lpMsgBuf);
return msg;
}
// WINAPI WinMain(HINSTANCE self, HINSTANCE parent, LPSTR cmdLine, int show)
int main( int argc, char* argv[] )
{
HLINE line;
DWORD numDevs;
DWORD apiVersion = MAKELONG( 1, 4 );
char lineInitializeExParamsRaw[ 10240 ];
LINEINITIALIZEEXPARAMS* lineInitializeExParams = (LINEINITIALIZEEXPARAMS *)lineInitializeExParamsRaw;
HANDLE event;
LONG result;
int i;
lineInitializeExParams->dwTotalSize = sizeof lineInitializeExParamsRaw;
lineInitializeExParams->dwOptions = LINEINITIALIZEEXOPTION_USEEVENT;
result = lineInitializeEx( &line, NULL, NULL, "Dialing", &numDevs, &apiVersion, lineInitializeExParams );
if( result ) {
std::cerr << "lineInitializeEx(): " << ext::Hex(8) << result << std::endl;
exit( 1 );
}
event = lineInitializeExParams->Handles.hEvent;
os << "available devices: " << std::dec << numDevs << std::endl;
for( i = 0; i < numDevs; i++ ) {
char lineDevCapsRaw[ 10240 ];
LINEDEVCAPS* lineDevCaps = (LINEDEVCAPS *)lineDevCapsRaw;
DWORD extVersion = 0;
char buf[ 1024 ];
os << std::endl;
lineDevCaps->dwTotalSize = sizeof lineDevCapsRaw;
os << "Quering device " << i << std::dec << std::endl;
if( result = lineGetDevCaps( line, i, apiVersion, extVersion, lineDevCaps ) ) {
os << "lineGetDevCaps(): " << ext::Hex(8) << result << std::endl;
continue;
}
os << "Needed size: " << lineDevCaps->dwNeededSize << std::endl;
os << lineDevCaps->dwLineNameSize << ", " <<
std::string( (char *)lineDevCaps + lineDevCaps->dwLineNameOffset, lineDevCaps->dwLineNameSize ) << std::endl;
}
int device = 1;
std::cin >> device;
if( result = lineConfigDialog( device, NULL, NULL ) ) {
std::cerr << "lineConfigDialog(): " << ext::Hex(8) << result << std::endl;
exit( 1 );
}
HLINE link;
if( result = lineOpen( line, device, &link, apiVersion, 0, NULL, LINECALLPRIVILEGE_OWNER, LINEMEDIAMODE_DATAMODEM, NULL ) ) {
std::cerr << "lineOpen(): " << ext::Hex(8) << result << std::endl;
exit( 1 );
}
char deviceIdRaw[ 10240 ];
VARSTRING* deviceId = (VARSTRING *)deviceIdRaw;
char deviceClass[ 1024 ] = "comm/datamodem";
deviceId->dwTotalSize = sizeof deviceIdRaw;
struct CommDatamodemInfo {
HANDLE handle;
CHAR deviceName[1];
} *commDatamodemInfo;
if( result = lineGetID( link, 0, NULL, LINECALLSELECT_LINE, deviceId, deviceClass ) ) {
std::cerr << "lineGetID(): " << ext::Hex(8) << result << std::endl;
exit( 1 );
}
os << "Device class: " << deviceClass << std::endl;
commDatamodemInfo = (CommDatamodemInfo *)( (char *)deviceId + deviceId->dwStringOffset );
os << "Modem: " << commDatamodemInfo->deviceName << std::endl;
os << "HANDLE: " << ext::Hex(8) << commDatamodemInfo->handle << std::endl;
DWORD bytes;
char msg[1024] = "Yes!\n\r";
char readBuf[ 1024 ];
OVERLAPPED overlapped;
memset( (void *)&overlapped, 0, sizeof overlapped );
if( !( overlapped.hEvent = CreateEvent( NULL, TRUE, TRUE, NULL ) ) ) {
os << "CreateEvent(): " << ext::Hex(8) << GetLastError() << ", " << getSystemMessage( GetLastError() ) << std::endl;
exit( 1 );
}
if( !WriteFile( commDatamodemInfo->handle, msg, strlen( msg ), &bytes, &overlapped ) ) {
os << "WriteFile(): " << ext::Hex(8) << GetLastError() << ", " << getSystemMessage( GetLastError() ) << std::endl;
exit( 1 );
}
lineClose( link );
lineShutdown( line );
return 0;
}
| |
|
** Дмитрий |
Отправлено: 21.05.2004, 20:54 |
|
Не зарегистрирован
|
Дело в том, что при использовании TAPI порт открывается в асинхронном режиме, т. е. функция WriteFile возвращает значение до завершения операции записи в буфер порта. Естественно, что возвращаемое значение указывает на ошибку. Действовать в данном случае следует так:
bool WriteToPort(HANDLE hPort, BYTE * Buff, DWORD dwWriteSize)
{
//Для ReadFile
OVERLAPPED o;
FillMemory(&o,sizeof(OVERLAPPED),0);
o.hEvent = CreateEvent(NULL, TRUE, TRUE, NULL);
//Резульат работы WriteFile
BOOL fWriteStat = FALSE;
//Смещение в выходном буфере
DWORD dwTotal = 0;
//Число записанных байтов
DWORD dwBytesWritten = 0;
DWORD dwError;
fWriteStat = WriteFile(hPort,Buff,dwWriteSize,&dwBytesWritten,&o);
dwTotal = 0;
dwTotal += dwBytesWritten;
dwBytesWritten = 0;
if(!fWriteStat){
if(GetLastError() == ERROR_IO_PENDING){
while(!GetOverlappedResult(hPort,&o,&dwBytesWritten,TRUE)){
//Ждем завершения операции
dwError = GetLastError();
if(dwError == ERROR_IO_INCOMPLETE){
//Все путем
dwTotal += dwBytesWritten;
dwBytesWritten = 0;
continue;
}else{
//Если ошибка, то прерываем опрерацию
PurgeComm (hPort, PURGE_TXABORT|PURGE_RXABORT);
dwTotal = 0;
return false;
}
}
dwTotal += dwBytesWritten;
dwBytesWritten = 0;
//Запись куска завершена
MoveMemory(Buff,Buff + dwTotal,dwTotal);
}else{
//Если ошибка, то прерываем
PurgeComm (hPort, PURGE_TXABORT|PURGE_RXABORT);
dwTotal = 0;
return false;
}
}else{
//Если запись завершена
MoveMemory(Buff,Buff + dwTotal,dwTotal);
dwTotal = 0;
}
//Критическая секция на остановку
CloseHandle(o.hEvent);
//Критическая секция на остановку
return true;
}
|
|
|