Develop and Download Open Source Software

Browse Subversion Repository

Diff of /branches/ttcomtester/teraterm/teraterm/commlib.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 8615 by doda, Thu Oct 10 03:38:29 2019 UTC revision 8616 by zmatsuo, Mon Mar 23 15:54:26 2020 UTC
# Line 1  Line 1 
1  /*  /*
2   * Copyright (C) 1994-1998 T. Teranishi   * Copyright (C) 1994-1998 T. Teranishi
3   * (C) 2005-2017 TeraTerm Project   * (C) 2005-2020 TeraTerm Project
4   * All rights reserved.   * All rights reserved.
5   *   *
6   * Redistribution and use in source and binary forms, with or without   * Redistribution and use in source and binary forms, with or without
# Line 47  Line 47 
47  #include <time.h>  #include <time.h>
48  #include <locale.h>  #include <locale.h>
49    
50    #include "ttlib.h"
51    #include "codeconv.h"
52    
53  static SOCKET OpenSocket(PComVar);  static SOCKET OpenSocket(PComVar);
54  static void AsyncConnect(PComVar);  static void AsyncConnect(PComVar);
55  static int CloseSocket(SOCKET);  static int CloseSocket(SOCKET);
# Line 288  error: Line 291  error:
291    
292  void CommOpen(HWND HW, PTTSet ts, PComVar cv)  void CommOpen(HWND HW, PTTSet ts, PComVar cv)
293  {  {
294          char ErrMsg[21+256];          char ErrMsg[21 + 256];
295            wchar_t ErrMsgW[21 + 256];
296          char P[50+256];          char P[50+256];
297    
298          MSG Msg;          MSG Msg;
# Line 297  void CommOpen(HWND HW, PTTSet ts, PComVa Line 301  void CommOpen(HWND HW, PTTSet ts, PComVa
301    
302          BOOL InvalidHost;          BOOL InvalidHost;
303    
         char uimsg[MAX_UIMSG];  
   
304          // ホスト名が名前付きパイプかどうかを調べる。          // ホスト名が名前付きパイプかどうかを調べる。
305          if (ts->PortType == IdTCPIP) {          if (ts->PortType == IdTCPIP) {
306                  if (CheckNamedPipeFormat(ts->HostName, strlen(ts->HostName)) == 0) {                  if (CheckNamedPipeFormat(ts->HostName, strlen(ts->HostName)) == 0) {
# Line 373  void CommOpen(HWND HW, PTTSet ts, PComVa Line 375  void CommOpen(HWND HW, PTTSet ts, PComVa
375                          }                          }
376                          if (! LoadWinsock()) {                          if (! LoadWinsock()) {
377                                  if (cv->NoMsg==0) {                                  if (cv->NoMsg==0) {
378                                          get_lang_msg("MSG_TT_ERROR", uimsg, sizeof(uimsg), "Tera Term: Error", ts->UILanguageFile);                                          static const TTMessageBoxInfoW info = {
379                                          get_lang_msg("MSG_WINSOCK_ERROR", ts->UIMsg, sizeof(ts->UIMsg), "Cannot use winsock", ts->UILanguageFile);                                                  "Tera Term",
380                                          MessageBox(cv->HWin,ts->UIMsg,uimsg,MB_TASKMODAL | MB_ICONEXCLAMATION);                                                  "MSG_TT_ERROR", L"Tera Term: Error",
381                                                    "MSG_WINSOCK_ERROR", L"Cannot use winsock",
382                                            };
383                                            TTMessageBoxW(
384                                                    cv->HWin,
385                                                    &info, (MB_TASKMODAL | MB_ICONEXCLAMATION),
386                                                    ts->UILanguageFile);
387                                  }                                  }
388                                  InvalidHost = TRUE;                                  InvalidHost = TRUE;
389                          }                          }
# Line 429  void CommOpen(HWND HW, PTTSet ts, PComVa Line 437  void CommOpen(HWND HW, PTTSet ts, PComVa
437    
438                          if (InvalidHost) {                          if (InvalidHost) {
439                                  if (cv->NoMsg==0) {                                  if (cv->NoMsg==0) {
440                                          get_lang_msg("MSG_TT_ERROR", uimsg, sizeof(uimsg), "Tera Term: Error", ts->UILanguageFile);                                          static const TTMessageBoxInfoW info = {
441                                          get_lang_msg("MSG_INVALID_HOST_ERROR", ts->UIMsg, sizeof(ts->UIMsg), "Invalid host", ts->UILanguageFile);                                                  "Tera Term",
442                                          MessageBox(cv->HWin,ts->UIMsg,uimsg,MB_TASKMODAL | MB_ICONEXCLAMATION);                                                  "MSG_TT_ERROR", L"Tera Term: Error",
443                                                    "MSG_INVALID_HOST_ERROR", L"Invalid host"
444                                            };
445                                            TTMessageBoxW(
446                                                    cv->HWin, &info, MB_TASKMODAL | MB_ICONEXCLAMATION, ts->UILanguageFile);
447                                  }                                  }
448                                  goto BreakSC;                                  goto BreakSC;
449                          }                          }
# Line 457  void CommOpen(HWND HW, PTTSet ts, PComVa Line 469  void CommOpen(HWND HW, PTTSet ts, PComVa
469                          cv->ComID = PCreateFile(P, GENERIC_READ | GENERIC_WRITE, 0, NULL,                          cv->ComID = PCreateFile(P, GENERIC_READ | GENERIC_WRITE, 0, NULL,
470                                                  OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);                                                  OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
471                          if (cv->ComID == INVALID_HANDLE_VALUE ) {                          if (cv->ComID == INVALID_HANDLE_VALUE ) {
                                 DWORD err = GetLastError();  
   
                                 switch (err) {  
                                 case ERROR_FILE_NOT_FOUND:  
                                         get_lang_msg("MSG_CANTOPEN_ERROR_NOTFOUND", ts->UIMsg, sizeof(ts->UIMsg), "Cannot open %s. Not found.", ts->UILanguageFile);  
                                         _snprintf_s(ErrMsg, sizeof(ErrMsg), _TRUNCATE, ts->UIMsg, &P[4]);  
                                         break;  
                                 case ERROR_ACCESS_DENIED:  
                                         get_lang_msg("MSG_CANTOPEN_ERROR_DENIED", ts->UIMsg, sizeof(ts->UIMsg), "Cannot open %s. Access denied.", ts->UILanguageFile);  
                                         _snprintf_s(ErrMsg, sizeof(ErrMsg), _TRUNCATE, ts->UIMsg, &P[4]);  
                                         break;  
                                 default:  
                                         get_lang_msg("MSG_CANTOPEN_ERROR", ts->UIMsg, sizeof(ts->UIMsg), "Cannot open %s. (0x%08x)", ts->UILanguageFile);  
                                         _snprintf_s(ErrMsg, sizeof(ErrMsg), _TRUNCATE, ts->UIMsg, &P[4], err);  
                                         break;  
                                 }  
   
472                                  if (cv->NoMsg==0) {                                  if (cv->NoMsg==0) {
473                                          get_lang_msg("MSG_TT_ERROR", uimsg, sizeof(uimsg), "Tera Term: Error", ts->UILanguageFile);                                          DWORD err = GetLastError();
474                                          MessageBox(cv->HWin,ErrMsg,uimsg,MB_TASKMODAL | MB_ICONEXCLAMATION);                                          wchar_t *format;
475                                            wchar_t *PW = ToWcharA(&P[4]);
476                                            static const TTMessageBoxInfoW info = {
477                                                    "Tera Term",
478                                                    "MSG_TT_ERROR", L"Tera Term: Error",
479                                            };
480    
481                                            switch (err) {
482                                            case ERROR_FILE_NOT_FOUND:
483                                                    format = TTGetLangStrW("Tera Term", "MSG_CANTOPEN_ERROR_NOTFOUND", L"Cannot open %s. Not found.", ts->UILanguageFile);
484                                                    _snwprintf_s(ErrMsgW, _countof(ErrMsgW), _TRUNCATE, format, PW);
485                                                    break;
486                                            case ERROR_ACCESS_DENIED:
487                                                    format = TTGetLangStrW("Tera Term", "MSG_CANTOPEN_ERROR_DENIED", L"Cannot open %s. Access denied.", ts->UILanguageFile);
488                                                    _snwprintf_s(ErrMsgW, _countof(ErrMsgW), _TRUNCATE, format, PW);
489                                                    break;
490                                            default:
491                                                    format = TTGetLangStrW("Tera Term", "MSG_CANTOPEN_ERROR", L"Cannot open %s. (0x%08x)", ts->UILanguageFile);
492                                                    _snwprintf_s(ErrMsgW, _countof(ErrMsgW), _TRUNCATE, format, PW, err);
493                                                    break;
494                                            }
495                                            free(format);
496                                            free(PW);
497    
498                                            TTMessageBoxW(
499                                                    cv->HWin, &info, MB_TASKMODAL | MB_ICONEXCLAMATION, ts->UILanguageFile, ErrMsgW);
500                                  }                                  }
501                                  InvalidHost = TRUE;                                  InvalidHost = TRUE;
502                          }                          }
# Line 503  void CommOpen(HWND HW, PTTSet ts, PComVa Line 523  void CommOpen(HWND HW, PTTSet ts, PComVa
523                          InvalidHost = (cv->ComID == INVALID_HANDLE_VALUE);                          InvalidHost = (cv->ComID == INVALID_HANDLE_VALUE);
524                          if (InvalidHost) {                          if (InvalidHost) {
525                                  if (cv->NoMsg==0) {                                  if (cv->NoMsg==0) {
526                                          get_lang_msg("MSG_TT_ERROR", uimsg, sizeof(uimsg), "Tera Term: Error", ts->UILanguageFile);                                          static const TTMessageBoxInfoW info = {
527                                          get_lang_msg("MSG_CANTOPEN_FILE_ERROR", ts->UIMsg, sizeof(ts->UIMsg), "Cannot open file", ts->UILanguageFile);                                                  "Tera Term",
528                                          MessageBox(cv->HWin,ts->UIMsg,uimsg,MB_TASKMODAL | MB_ICONEXCLAMATION);                                                  "MSG_TT_ERROR", L"Tera Term: Error",
529                                                    "MSG_CANTOPEN_FILE_ERROR", L"Cannot open file"
530                                            };
531                                            TTMessageBoxW(
532                                                    cv->HWin, &info, MB_TASKMODAL | MB_ICONEXCLAMATION, ts->UILanguageFile);
533                                  }                                  }
534                          }                          }
535                          else {                          else {
# Line 523  void CommOpen(HWND HW, PTTSet ts, PComVa Line 547  void CommOpen(HWND HW, PTTSet ts, PComVa
547    
548                          // 名前付きパイプが正しい書式かをチェックする。                          // 名前付きパイプが正しい書式かをチェックする。
549                          if (CheckNamedPipeFormat(P, strlen(P)) < 0) {                          if (CheckNamedPipeFormat(P, strlen(P)) < 0) {
550                                    static const TTMessageBoxInfoW info = {
551                                            "Tera Term",
552                                            "MSG_TT_ERROR", L"Tera Term: Error",
553                                    };
554                                  InvalidHost = TRUE;                                  InvalidHost = TRUE;
555    
556                                  _snprintf_s(ErrMsg, sizeof(ErrMsg), _TRUNCATE,                                  _snwprintf_s(ErrMsgW, _countof(ErrMsgW), _TRUNCATE,
557                                          "Invalid pipe name (%d)\n\n"                                          L"Invalid pipe name (%d)\n\n"
558                                          "A valid pipe name has the form\n"                                          L"A valid pipe name has the form\n"
559                                          "\"\\\\<ServerName>\\pipe\\<PipeName>\"",                                          L"\"\\\\<ServerName>\\pipe\\<PipeName>\"",
560                                          GetLastError());                                          GetLastError());
561                                  get_lang_msg("MSG_TT_ERROR", uimsg, sizeof(uimsg), "Tera Term: Error", ts->UILanguageFile);                                  TTMessageBoxW(cv->HWin, &info, MB_TASKMODAL | MB_ICONEXCLAMATION, ts->UILanguageFile, ErrMsgW);
                                 MessageBox(cv->HWin,ErrMsg,uimsg,MB_TASKMODAL | MB_ICONEXCLAMATION);  
562                                  break;                                  break;
563                          }                          }
564    
# Line 539  void CommOpen(HWND HW, PTTSet ts, PComVa Line 566  void CommOpen(HWND HW, PTTSet ts, PComVa
566                                                  0,  // ブロッキングモードにする(FILE_FLAG_OVERLAPPED は指定しない)                                                  0,  // ブロッキングモードにする(FILE_FLAG_OVERLAPPED は指定しない)
567                                                  NULL);                                                  NULL);
568                          if (cv->ComID == INVALID_HANDLE_VALUE ) {                          if (cv->ComID == INVALID_HANDLE_VALUE ) {
                                 DWORD err = GetLastError();  
   
                                 switch (err) {  
                                 case ERROR_FILE_NOT_FOUND:  
                                         get_lang_msg("MSG_CANTOPEN_ERROR_NOTFOUND", ts->UIMsg, sizeof(ts->UIMsg), "Cannot open %s. Not found.", ts->UILanguageFile);  
                                         _snprintf_s(ErrMsg, sizeof(ErrMsg), _TRUNCATE, ts->UIMsg, P);  
                                         break;  
                                 case ERROR_ACCESS_DENIED:  
                                         get_lang_msg("MSG_CANTOPEN_ERROR_DENIED", ts->UIMsg, sizeof(ts->UIMsg), "Cannot open %s. Access denied.", ts->UILanguageFile);  
                                         _snprintf_s(ErrMsg, sizeof(ErrMsg), _TRUNCATE, ts->UIMsg, P);  
                                         break;  
                                 case ERROR_PIPE_BUSY:  
                                         get_lang_msg("MSG_CANTOPEN_ERROR_PIPEBUSY", ts->UIMsg, sizeof(ts->UIMsg), "Cannot open %s. Pipe is busy.", ts->UILanguageFile);  
                                         _snprintf_s(ErrMsg, sizeof(ErrMsg), _TRUNCATE, ts->UIMsg, P);  
                                         break;  
                                 default:  
                                         get_lang_msg("MSG_CANTOPEN_ERROR", ts->UIMsg, sizeof(ts->UIMsg), "Cannot open %s. (0x%08x)", ts->UILanguageFile);  
                                         _snprintf_s(ErrMsg, sizeof(ErrMsg), _TRUNCATE, ts->UIMsg, P, err);  
                                         break;  
                                 }  
   
569                                  if (cv->NoMsg==0) {                                  if (cv->NoMsg==0) {
570                                          get_lang_msg("MSG_TT_ERROR", uimsg, sizeof(uimsg), "Tera Term: Error", ts->UILanguageFile);                                          DWORD err = GetLastError();
571                                          MessageBox(cv->HWin,ErrMsg,uimsg,MB_TASKMODAL | MB_ICONEXCLAMATION);                                          wchar_t *format;
572                                            wchar_t* PW = ToWcharA(&P[4]);
573                                            static const TTMessageBoxInfoW info = {
574                                                    "Tera Term",
575                                                    "MSG_TT_ERROR", L"Tera Term: Error",
576                                            };
577    
578                                            switch (err) {
579                                            case ERROR_FILE_NOT_FOUND:
580                                                    format = TTGetLangStrW("Tera Term", "MSG_CANTOPEN_ERROR_NOTFOUND", L"Cannot open %s. Not found.", ts->UILanguageFile);
581                                                    _snwprintf_s(ErrMsgW, _countof(ErrMsgW), _TRUNCATE, format, PW);
582                                                    break;
583                                            case ERROR_ACCESS_DENIED:
584                                                    format = TTGetLangStrW("Tera Term", "MSG_CANTOPEN_ERROR_DENIED", L"Cannot open %s. Access denied.", ts->UILanguageFile);
585                                                    _snwprintf_s(ErrMsgW, _countof(ErrMsgW), _TRUNCATE, format, PW);
586                                                    break;
587                                            case ERROR_PIPE_BUSY:
588                                                    format = TTGetLangStrW("Tera Term", "MSG_CANTOPEN_ERROR_PIPEBUSY", L"Cannot open %s. Pipe is busy.", ts->UILanguageFile);
589                                                    _snwprintf_s(ErrMsgW, _countof(ErrMsgW), _TRUNCATE, format, PW);
590                                                    break;
591                                            default:
592                                                    format = TTGetLangStrW("Tera Term", "MSG_CANTOPEN_ERROR", L"Cannot open %s. (0x%08x)", ts->UILanguageFile);
593                                                    _snwprintf_s(ErrMsgW, _countof(ErrMsgW), _TRUNCATE, format, PW, err);
594                                                    break;
595                                            }
596                                            free(format);
597                                            free(PW);
598    
599                                            TTMessageBoxW(
600                                                    cv->HWin, &info, MB_TASKMODAL | MB_ICONEXCLAMATION, ts->UILanguageFile, ErrMsgW);
601                                  }                                  }
602                                  InvalidHost = TRUE;                                  InvalidHost = TRUE;
603                          }                          }
# Line 664  void CommThread(void *arg) Line 699  void CommThread(void *arg)
699  void CommStart(PComVar cv, LONG lParam, PTTSet ts)  void CommStart(PComVar cv, LONG lParam, PTTSet ts)
700  {  {
701          char ErrMsg[31];          char ErrMsg[31];
702            wchar_t ErrMsgW[31];
703          char Temp[20];          char Temp[20];
704          char uimsg[MAX_UIMSG];          wchar_t UIMsgW[MAX_UIMSG];
705    
706          if (! cv->Open ) {          if (! cv->Open ) {
707                  return;                  return;
# Line 684  void CommStart(PComVar cv, LONG lParam, Line 720  void CommStart(PComVar cv, LONG lParam,
720                          ErrMsg[0] = 0;                          ErrMsg[0] = 0;
721                          switch (HIWORD(lParam)) {                          switch (HIWORD(lParam)) {
722                                  case WSAECONNREFUSED:                                  case WSAECONNREFUSED:
723                                          get_lang_msg("MSG_COMM_REFUSE_ERROR", ts->UIMsg, sizeof(ts->UIMsg), "Connection refused", ts->UILanguageFile);                                          get_lang_msgW("MSG_COMM_REFUSE_ERROR", UIMsgW, _countof(UIMsgW), L"Connection refused", ts->UILanguageFile);
724                                          _snprintf_s(ErrMsg, sizeof(ErrMsg), _TRUNCATE, "%s", ts->UIMsg);                                          _snwprintf_s(ErrMsgW, _countof(ErrMsgW), _TRUNCATE, L"%s", UIMsgW);
725                                          break;                                          break;
726                                  case WSAENETUNREACH:                                  case WSAENETUNREACH:
727                                          get_lang_msg("MSG_COMM_REACH_ERROR", ts->UIMsg, sizeof(ts->UIMsg), "Network cannot be reached", ts->UILanguageFile);                                          get_lang_msgW("MSG_COMM_REACH_ERROR", UIMsgW, _countof(UIMsgW), L"Network cannot be reached", ts->UILanguageFile);
728                                          _snprintf_s(ErrMsg, sizeof(ErrMsg), _TRUNCATE, "%s", ts->UIMsg);                                          _snwprintf_s(ErrMsgW, _countof(ErrMsgW), _TRUNCATE, L"%s", UIMsgW);
729                                          break;                                          break;
730                                  case WSAETIMEDOUT:                                  case WSAETIMEDOUT:
731                                          get_lang_msg("MSG_COMM_CONNECT_ERROR", ts->UIMsg, sizeof(ts->UIMsg), "Connection timed out", ts->UILanguageFile);                                          get_lang_msgW("MSG_COMM_CONNECT_ERROR", UIMsgW, _countof(UIMsgW), L"Connection timed out", ts->UILanguageFile);
732                                          _snprintf_s(ErrMsg, sizeof(ErrMsg), _TRUNCATE, "%s", ts->UIMsg);                                          _snwprintf_s(ErrMsgW, _countof(ErrMsgW), _TRUNCATE, L"%s", UIMsgW);
733                                          break;                                          break;
734                                  default:                                  default:
735                                          get_lang_msg("MSG_COMM_TIMEOUT_ERROR", ts->UIMsg, sizeof(ts->UIMsg), "Cannot connect the host", ts->UILanguageFile);                                          get_lang_msgW("MSG_COMM_TIMEOUT_ERROR", UIMsgW, _countof(UIMsgW), L"Cannot connect the host", ts->UILanguageFile);
736                                          _snprintf_s(ErrMsg, sizeof(ErrMsg), _TRUNCATE, "%s", ts->UIMsg);                                          _snwprintf_s(ErrMsgW, _countof(ErrMsgW), _TRUNCATE, L"%s", UIMsgW);
737                          }                          }
738                          if (HIWORD(lParam)>0) {                          if (HIWORD(lParam)>0) {
739                                  /* connect() failed */                                  /* connect() failed */
# Line 719  void CommStart(PComVar cv, LONG lParam, Line 755  void CommStart(PComVar cv, LONG lParam,
755                                          /* trying with all protocol family are failed */                                          /* trying with all protocol family are failed */
756                                          if (cv->NoMsg==0)                                          if (cv->NoMsg==0)
757                                          {                                          {
758                                                  get_lang_msg("MSG_TT_ERROR", uimsg, sizeof(uimsg), "Tera Term: Error", ts->UILanguageFile);                                                  static const TTMessageBoxInfoW info = {
759                                                  MessageBox(cv->HWin,ErrMsg,uimsg,MB_TASKMODAL | MB_ICONEXCLAMATION);                                                          "Tera Term",
760                                                            "MSG_TT_ERROR", L"Tera Term: Error",
761                                                            NULL, NULL
762                                                    };
763                                                    TTMessageBoxW(
764                                                            cv->HWin,
765                                                            &info, (MB_TASKMODAL | MB_ICONEXCLAMATION),
766                                                            ts->UILanguageFile, ErrMsgW);
767                                          }                                          }
768                                          PostMessage(cv->HWin, WM_USER_COMMNOTIFY, 0, FD_CLOSE);                                          PostMessage(cv->HWin, WM_USER_COMMNOTIFY, 0, FD_CLOSE);
769                                          cv->RetryWithOtherProtocol = FALSE;                                          cv->RetryWithOtherProtocol = FALSE;
# Line 746  void CommStart(PComVar cv, LONG lParam, Line 789  void CommStart(PComVar cv, LONG lParam,
789    
790                          /* create the receiver thread */                          /* create the receiver thread */
791                          if (_beginthread(CommThread,0,cv) == -1) {                          if (_beginthread(CommThread,0,cv) == -1) {
792                                  get_lang_msg("MSG_TT_ERROR", uimsg, sizeof(uimsg), "Tera Term: Error", ts->UILanguageFile);                                  static const TTMessageBoxInfoW info = {
793                                  get_lang_msg("MSG_TT_ERROR", ts->UIMsg, sizeof(ts->UIMsg), "Can't create thread", ts->UILanguageFile);                                          "Tera Term",
794                                  MessageBox(cv->HWin,ts->UIMsg,uimsg,MB_TASKMODAL | MB_ICONEXCLAMATION);                                          "MSG_TT_ERROR", L"Tera Term: Error",
795                                            "MSG_TT_ERROR", L"Can't create thread"
796                                    };
797                                    TTMessageBoxW(cv->HWin, &info, MB_TASKMODAL | MB_ICONEXCLAMATION, ts->UILanguageFile);
798                          }                          }
799                          break;                          break;
800    
# Line 769  void CommStart(PComVar cv, LONG lParam, Line 815  void CommStart(PComVar cv, LONG lParam,
815    
816                          /* create the receiver thread */                          /* create the receiver thread */
817                          if (_beginthread(NamedPipeThread,0,cv) == -1) {                          if (_beginthread(NamedPipeThread,0,cv) == -1) {
818                                  get_lang_msg("MSG_TT_ERROR", uimsg, sizeof(uimsg), "Tera Term: Error", ts->UILanguageFile);                                  static const TTMessageBoxInfoW info = {
819                                  get_lang_msg("MSG_TT_ERROR", ts->UIMsg, sizeof(ts->UIMsg), "Can't create thread", ts->UILanguageFile);                                          "Tera Term",
820                                  MessageBox(cv->HWin,ts->UIMsg,uimsg,MB_TASKMODAL | MB_ICONEXCLAMATION);                                          "MSG_TT_ERROR", L"Tera Term: Error",
821                                            "MSG_TT_ERROR", L"Can't create thread"
822                                    };
823                                    TTMessageBoxW(cv->HWin, &info, MB_TASKMODAL | MB_ICONEXCLAMATION, ts->UILanguageFile);
824                          }                          }
825                          break;                          break;
826          }          }

Legend:
Removed from v.8615  
changed lines
  Added in v.8616

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26