| 234 |
#ifdef NO_INET6 |
#ifdef NO_INET6 |
| 235 |
int Err; |
int Err; |
| 236 |
#endif /* NO_INET6 */ |
#endif /* NO_INET6 */ |
| 237 |
char ErrMsg[21]; |
char ErrMsg[21+256]; |
| 238 |
char P[50]; |
char P[50+256]; |
| 239 |
|
|
| 240 |
MSG Msg; |
MSG Msg; |
| 241 |
#ifndef NO_INET6 |
#ifndef NO_INET6 |
| 550 |
PostMessage(cv->HWin, WM_USER_COMMOPEN, 0, 0); |
PostMessage(cv->HWin, WM_USER_COMMOPEN, 0, 0); |
| 551 |
} |
} |
| 552 |
break; |
break; |
| 553 |
|
|
| 554 |
|
case IdNamedPipe: |
| 555 |
|
InitFileIO(IdNamedPipe); /* TTPLUG */ |
| 556 |
|
TTXOpenFile(); /* TTPLUG */ |
| 557 |
|
strncpy_s(P, sizeof(P), ts->HostName, _TRUNCATE); |
| 558 |
|
cv->ComID = |
| 559 |
|
PCreateFile(P,GENERIC_READ | GENERIC_WRITE, |
| 560 |
|
0,NULL,OPEN_EXISTING, |
| 561 |
|
0, // ブロッキングモードにする(FILE_FLAG_OVERLAPPED は指定しない) |
| 562 |
|
NULL); |
| 563 |
|
if (cv->ComID == INVALID_HANDLE_VALUE ) { |
| 564 |
|
get_lang_msg("MSG_CANTOEPN_ERROR", ts->UIMsg, sizeof(ts->UIMsg), "Cannot open %s(%d)", ts->UILanguageFile); |
| 565 |
|
_snprintf_s(ErrMsg, sizeof(ErrMsg), _TRUNCATE, ts->UIMsg, &P[0], GetLastError()); |
| 566 |
|
|
| 567 |
|
if (cv->NoMsg==0) { |
| 568 |
|
get_lang_msg("MSG_TT_ERROR", uimsg, sizeof(uimsg), "Tera Term: Error", ts->UILanguageFile); |
| 569 |
|
MessageBox(cv->HWin,ErrMsg,uimsg,MB_TASKMODAL | MB_ICONEXCLAMATION); |
| 570 |
|
} |
| 571 |
|
InvalidHost = TRUE; |
| 572 |
|
} |
| 573 |
|
else { |
| 574 |
|
cv->Open = TRUE; |
| 575 |
|
PostMessage(cv->HWin, WM_USER_COMMOPEN, 0, 0); |
| 576 |
|
InvalidHost = FALSE; |
| 577 |
|
} |
| 578 |
|
break; /* end of "case IdNamedPipe:" */ |
| 579 |
|
|
| 580 |
} /* end of "switch" */ |
} /* end of "switch" */ |
| 581 |
|
|
| 582 |
#ifndef NO_INET6 |
#ifndef NO_INET6 |
| 595 |
} |
} |
| 596 |
} |
} |
| 597 |
|
|
| 598 |
|
// 名前付きパイプ用スレッド |
| 599 |
|
void NamedPipeThread(void *arg) |
| 600 |
|
{ |
| 601 |
|
PComVar cv = (PComVar)arg; |
| 602 |
|
DWORD DErr; |
| 603 |
|
HANDLE REnd; |
| 604 |
|
char Temp[20]; |
| 605 |
|
char Buffer[1]; // 1byte |
| 606 |
|
DWORD BytesRead, TotalBytesAvail, BytesLeftThisMessage; |
| 607 |
|
|
| 608 |
|
_snprintf_s(Temp, sizeof(Temp), _TRUNCATE, "%s%d", READENDNAME, cv->ComPort); |
| 609 |
|
REnd = OpenEvent(EVENT_ALL_ACCESS,FALSE, Temp); |
| 610 |
|
while (TRUE) { |
| 611 |
|
BytesRead = 0; |
| 612 |
|
// 名前付きパイプはイベントを待つことができない仕様なので、キューの中身を |
| 613 |
|
// 覗き見することで、ReadFile() するかどうか判断する。 |
| 614 |
|
if (PeekNamedPipe(cv->ComID, Buffer, sizeof(Buffer), &BytesRead, &TotalBytesAvail, &BytesLeftThisMessage)) { |
| 615 |
|
if (! cv->Ready) { |
| 616 |
|
_endthread(); |
| 617 |
|
} |
| 618 |
|
if (BytesRead == 0) { // 空だったら、何もしない。 |
| 619 |
|
Sleep(1); |
| 620 |
|
continue; |
| 621 |
|
} |
| 622 |
|
if (! cv->RRQ) { |
| 623 |
|
PostMessage(cv->HWin, WM_USER_COMMNOTIFY, 0, FD_READ); |
| 624 |
|
} |
| 625 |
|
// ReadFile() が終わるまで待つ。 |
| 626 |
|
WaitForSingleObject(REnd,INFINITE); |
| 627 |
|
} |
| 628 |
|
else { |
| 629 |
|
DErr = GetLastError(); // this returns 995 (operation aborted) if a USB com port is removed |
| 630 |
|
if (! cv->Ready || ERROR_OPERATION_ABORTED == DErr) { |
| 631 |
|
_endthread(); |
| 632 |
|
} |
| 633 |
|
} |
| 634 |
|
} |
| 635 |
|
} |
| 636 |
|
|
| 637 |
void CommThread(void *arg) |
void CommThread(void *arg) |
| 638 |
{ |
{ |
| 639 |
DWORD Evt; |
DWORD Evt; |
| 769 |
case IdFile: |
case IdFile: |
| 770 |
cv->RRQ = TRUE; |
cv->RRQ = TRUE; |
| 771 |
break; |
break; |
| 772 |
|
|
| 773 |
|
case IdNamedPipe: |
| 774 |
|
cv->ComPort = 0; |
| 775 |
|
_snprintf_s(Temp, sizeof(Temp), _TRUNCATE, "%s%d", READENDNAME, cv->ComPort); |
| 776 |
|
ReadEnd = CreateEvent(NULL,FALSE,FALSE,Temp); |
| 777 |
|
_snprintf_s(Temp, sizeof(Temp), _TRUNCATE, "%s%d", WRITENAME, cv->ComPort); |
| 778 |
|
memset(&wol,0,sizeof(OVERLAPPED)); |
| 779 |
|
wol.hEvent = CreateEvent(NULL,TRUE,TRUE,Temp); |
| 780 |
|
_snprintf_s(Temp, sizeof(Temp), _TRUNCATE, "%s%d", READNAME, cv->ComPort); |
| 781 |
|
memset(&rol,0,sizeof(OVERLAPPED)); |
| 782 |
|
rol.hEvent = CreateEvent(NULL,TRUE,FALSE,Temp); |
| 783 |
|
|
| 784 |
|
/* create the receiver thread */ |
| 785 |
|
if (_beginthread(NamedPipeThread,0,cv) == -1) { |
| 786 |
|
get_lang_msg("MSG_TT_ERROR", uimsg, sizeof(uimsg), "Tera Term: Error", ts->UILanguageFile); |
| 787 |
|
get_lang_msg("MSG_TT_ERROR", ts->UIMsg, sizeof(ts->UIMsg), "Can't create thread", ts->UILanguageFile); |
| 788 |
|
MessageBox(cv->HWin,ts->UIMsg,uimsg,MB_TASKMODAL | MB_ICONEXCLAMATION); |
| 789 |
|
} |
| 790 |
|
break; |
| 791 |
} |
} |
| 792 |
cv->Ready = TRUE; |
cv->Ready = TRUE; |
| 793 |
} |
} |
| 867 |
} |
} |
| 868 |
TTXCloseFile(); /* TTPLUG */ |
TTXCloseFile(); /* TTPLUG */ |
| 869 |
break; |
break; |
| 870 |
|
|
| 871 |
|
case IdNamedPipe: |
| 872 |
|
if ( cv->ComID != INVALID_HANDLE_VALUE ) { |
| 873 |
|
CloseHandle(ReadEnd); |
| 874 |
|
CloseHandle(wol.hEvent); |
| 875 |
|
CloseHandle(rol.hEvent); |
| 876 |
|
PCloseFile(cv->ComID); |
| 877 |
|
} |
| 878 |
|
TTXCloseFile(); /* TTPLUG */ |
| 879 |
|
break; |
| 880 |
} |
} |
| 881 |
cv->ComID = INVALID_HANDLE_VALUE; |
cv->ComID = INVALID_HANDLE_VALUE; |
| 882 |
cv->PortType = 0; |
cv->PortType = 0; |
| 965 |
DErr = GetLastError(); |
DErr = GetLastError(); |
| 966 |
} |
} |
| 967 |
break; |
break; |
| 968 |
|
|
| 969 |
|
case IdNamedPipe: |
| 970 |
|
// キューの中に最低1バイト以上のデータが入っていることを確認できているため、 |
| 971 |
|
// ReadFile() はブロックすることはないため、一括して読む。 |
| 972 |
|
if (PReadFile(cv->ComID,&(cv->InBuff[cv->InBuffCount]), |
| 973 |
|
InBuffSize-cv->InBuffCount,&C,NULL)) { |
| 974 |
|
if (C == 0) { |
| 975 |
|
DErr = ERROR_HANDLE_EOF; |
| 976 |
|
} |
| 977 |
|
else { |
| 978 |
|
cv->InBuffCount = cv->InBuffCount + C; |
| 979 |
|
} |
| 980 |
|
} |
| 981 |
|
else { |
| 982 |
|
DErr = GetLastError(); |
| 983 |
|
} |
| 984 |
|
|
| 985 |
|
// 1バイト以上読めたら、イベントを起こし、スレッドを再開させる。 |
| 986 |
|
if (cv->InBuffCount > 0) { |
| 987 |
|
cv->RRQ = FALSE; |
| 988 |
|
SetEvent(ReadEnd); |
| 989 |
|
} |
| 990 |
|
break; |
| 991 |
} |
} |
| 992 |
} |
} |
| 993 |
|
|
| 1012 |
cv->RRQ = TRUE; |
cv->RRQ = TRUE; |
| 1013 |
} |
} |
| 1014 |
return; |
return; |
| 1015 |
|
case IdNamedPipe: |
| 1016 |
|
// TODO: たぶん、ここに来ることはない。 |
| 1017 |
|
if (DErr != ERROR_IO_PENDING) { |
| 1018 |
|
PostMessage(cv->HWin, WM_USER_COMMNOTIFY, 0, FD_CLOSE); |
| 1019 |
|
cv->RRQ = FALSE; |
| 1020 |
|
} |
| 1021 |
|
else { |
| 1022 |
|
cv->RRQ = TRUE; |
| 1023 |
|
} |
| 1024 |
|
SetEvent(ReadEnd); |
| 1025 |
|
return; |
| 1026 |
} |
} |
| 1027 |
cv->RRQ = FALSE; |
cv->RRQ = FALSE; |
| 1028 |
} |
} |
| 1060 |
case IdFile: |
case IdFile: |
| 1061 |
Max = cv->OutBuffCount; |
Max = cv->OutBuffCount; |
| 1062 |
break; |
break; |
| 1063 |
|
case IdNamedPipe: |
| 1064 |
|
Max = cv->OutBuffCount; |
| 1065 |
|
break; |
| 1066 |
} |
} |
| 1067 |
|
|
| 1068 |
if ( Max<=0 ) { |
if ( Max<=0 ) { |
| 1137 |
if (! PWriteFile(cv->ComID, &(cv->OutBuff[cv->OutPtr]), C, (LPDWORD)&D, NULL)) { |
if (! PWriteFile(cv->ComID, &(cv->OutBuff[cv->OutPtr]), C, (LPDWORD)&D, NULL)) { |
| 1138 |
if (! GetLastError() == ERROR_IO_PENDING) { |
if (! GetLastError() == ERROR_IO_PENDING) { |
| 1139 |
D = C; /* ignore data */ |
D = C; /* ignore data */ |
| 1140 |
|
} |
| 1141 |
|
} |
| 1142 |
|
break; |
| 1143 |
|
|
| 1144 |
|
case IdNamedPipe: |
| 1145 |
|
if (! PWriteFile(cv->ComID, &(cv->OutBuff[cv->OutPtr]), C, (LPDWORD)&D, NULL)) { |
| 1146 |
|
if (! GetLastError() == ERROR_IO_PENDING) { |
| 1147 |
|
D = C; /* ignore data */ |
| 1148 |
} |
} |
| 1149 |
} |
} |
| 1150 |
break; |
break; |