Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1] 2  Все   Вниз
  Печать  
Автор Тема: определить СОМ порты под разными версиями Windows  (Прочитано 63039 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Pu
Большой босс

ru
Offline Offline
78


« : 23-06-2004 07:52 » 

Подскажите как определить, какие СОМы есть на машине, тк в реестре они в разных системах сидят под разными ключами. Пользовался функцией    QueryDosDevice но как оказалось под 98/ME/XP она отрабатывает не так как надо , или вообще не отрабатывает. Может есть еще что нибудь в этом роде?
Записан

Насколько я опытен? Достаточно, чтобы понимать, что дураков нельзя заставить думать по–другому, но недостаточно, чтобы отказаться от попыток это сделать.
(с) Артур Джонс
MOPO3
Ай да дэдушка! Вах...
Команда клуба

lt
Offline Offline
Пол: Мужской
Холадна аднака!


WWW
« Ответ #1 : 23-06-2004 08:21 » 

Я делаю это так :
Код:
String comm_port;
    for(int i = 1; i < 255; i++)
    {
        comm_port = "COM" + IntToStr(i);

        hComm_test = CreateFile(comm_port.c_str(), GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
        if(hComm_test != INVALID_HANDLE_VALUE)
        {
            ComPort->Items->Add("COM" + IntToStr(i));
            CloseHandle(hComm_test);
        }
    }

Решение наверно так себе, но прекрасно работает под всеми виндами
« Последнее редактирование: 28-11-2007 18:40 от Алексей1153++ » Записан

MCP, MCAD, MCTS:Win, MCTS:Web
Pu
Большой босс

ru
Offline Offline
78


« Ответ #2 : 23-06-2004 08:52 » 

MOPO3,  я думал что есть какие либо решения которые показывают то , что прописано в режистри. Если порт открыт, соответственно получим INVALID_HANDLE_VALUE, а хотелось бы и его увидеть в списке
Записан

Насколько я опытен? Достаточно, чтобы понимать, что дураков нельзя заставить думать по–другому, но недостаточно, чтобы отказаться от попыток это сделать.
(с) Артур Джонс
MOPO3
Ай да дэдушка! Вах...
Команда клуба

lt
Offline Offline
Пол: Мужской
Холадна аднака!


WWW
« Ответ #3 : 23-06-2004 08:55 » 

Цитата: Pu
MOPO3,  я думал что есть какие либо решения которые показывают то , что прописано в режистри.

С режистри много возни будет, потому как в разных ветках и по разному лежат эти записи в вынь98 и 2000.
Цитата
Если порт открыт, соответственно получим INVALID_HANDLE_VALUE, а хотелось бы и его увидеть в списке


Подожди, что то я не понял, ты имееш ввиду что порт в это время уже открыт другим приложением ?
Записан

MCP, MCAD, MCTS:Win, MCTS:Web
MOPO3
Ай да дэдушка! Вах...
Команда клуба

lt
Offline Offline
Пол: Мужской
Холадна аднака!


WWW
« Ответ #4 : 23-06-2004 08:59 » 

Вот, нашол в инете :
listports.h
Код:
#ifndef LISTPORTS_H
#define LISTPORTS_H

#define VERSION_LISTPORTS 0x00010000

#ifdef __cplusplus
extern "C"{
#endif

#include <windows.h>

typedef struct
{
  LPCTSTR lpPortName;     /* "COM1", etc. */
  LPCTSTR lpFriendlyName; /* Suitable to describe the port, as for  */
                          /* instance "Infrared serial port (COM4)" */
"LISTPORTS_PORTINFO;

typedef BOOL (CALLBACK* LISTPORTS_CALLBACK)(LPVOID              lpCallbackValue,
                                            LISTPORTS_PORTINFO* lpPortInfo);
/* User provided callback funtion that receives the information on each
 * serial port available.
 * The strings provided on the LISTPORTS_INFO are not to be referenced after
 * the callback returns; instead make copies of them for later use.
 * If the callback returns FALSE, port enumeration is aborted.
 */

BOOL ListPorts(LISTPORTS_CALLBACK lpCallback,LPVOID lpCallbackValue);
/* Lists serial ports available on the system, passing the information on
 * each port on succesive calls to lpCallback.
 * lpCallbackValue, treated opaquely by ListPorts(), is intended to carry
 * information internal to the callback routine.
 * Returns TRUE if succesful, otherwise error code can be retrieved via
 * GetLastError().
 */

#ifdef __cplusplus
}
#endif

#elif VERSION_LISTPORTS!=0x00010000
#error You have included two LISTPORTS.H with different version numbers
#endif
listports.c
Код:
#include "listports.h"
#include <tchar.h>
#include <stdlib.h>
#include <string.h>

static BOOL Win9xListPorts(LISTPORTS_CALLBACK lpCbk,LPVOID lpCbkValue);
static BOOL WinNT40ListPorts(LISTPORTS_CALLBACK lpCbk,LPVOID lpCbkValue);
static BOOL Win2000ListPorts(LISTPORTS_CALLBACK lpCbk,LPVOID lpCbkValue);
static BOOL ScanEnumTree(LPCTSTR lpEnumPath,LISTPORTS_CALLBACK lpCbk,LPVOID lpCbkValue);
static LONG OpenSubKeyByIndex(HKEY hKey,DWORD dwIndex,REGSAM samDesired,PHKEY phkResult);
static LONG QueryStringValue(HKEY hKey,LPCTSTR lpValueName, LPTSTR* lppStringValue);

BOOL ListPorts(LISTPORTS_CALLBACK lpCbk,LPVOID lpCbkValue)
{
  OSVERSIONINFO osvinfo;

  /* check parameters */

  if(!lpCbk){
    SetLastError(ERROR_INVALID_PARAMETER);
    return FALSE;
  }

  /* determine which platform we're running on and forward
   * to the appropriate routine
   */

  ZeroMemory(&osvinfo,sizeof(osvinfo));
  osvinfo.dwOSVersionInfoSize=sizeof(osvinfo);

  GetVersionEx(&osvinfo);

  switch(osvinfo.dwPlatformId){
    case VER_PLATFORM_WIN32_WINDOWS:
      return Win9xListPorts(lpCbk,lpCbkValue);
      break;
    case VER_PLATFORM_WIN32_NT:
      if(osvinfo.dwMajorVersion<4){
        SetLastError(ERROR_OLD_WIN_VERSION);
        return FALSE;
      }
      else if(osvinfo.dwMajorVersion==4){
        return WinNT40ListPorts(lpCbk,lpCbkValue);
      }
      else{
        return Win2000ListPorts(lpCbk,lpCbkValue); /* hopefully it'll also work for XP */
      }
      break;
    default:
      SetLastError(ERROR_OLD_WIN_VERSION);
      return FALSE;
      break;
  }
}

BOOL Win9xListPorts(LISTPORTS_CALLBACK lpCbk,LPVOID lpCbkValue)
{
  return ScanEnumTree(TEXT("ENUM"),lpCbk,lpCbkValue);
}

static BOOL WinNT40ListPorts(LISTPORTS_CALLBACK lpCbk,LPVOID lpCbkValue)
{
  DWORD  dwError=0;
  HKEY   hKey=NULL;
  DWORD  dwIndex;
  LPTSTR lpValueName=NULL;
  LPTSTR lpPortName=NULL;

  if(dwError=RegOpenKeyEx(HKEY_LOCAL_MACHINE,TEXT("HARDWARE\\DEVICEMAP\\SERIALCOMM"),
                          0,KEY_READ,&hKey)){
    /* it is really strange that this key does not exist, but could happen in theory */
    if(dwError==ERROR_FILE_NOT_FOUND)dwError=0;
    goto end;
  }

  for(dwIndex=0;;++dwIndex){
    DWORD              cbValueName=32*sizeof(TCHAR);
    DWORD              cbPortName=32*sizeof(TCHAR);
    LISTPORTS_PORTINFO portinfo;

    /* loop asking for the value data til we allocated enough memory */

    for(;;){
      free(lpValueName);
      if(!(lpValueName=(LPTSTR)malloc(cbValueName))){
        dwError=ERROR_NOT_ENOUGH_MEMORY;
        goto end;
      }
      free(lpPortName);
      if(!(lpPortName=(LPTSTR)malloc(cbPortName))){
        dwError=ERROR_NOT_ENOUGH_MEMORY;
        goto end;
      }
      if(!(dwError=RegEnumValue(hKey,dwIndex,lpValueName,&cbValueName,
                                NULL,NULL,(LPBYTE)lpPortName,&cbPortName))){
        break; /* we did it */
      }
      else if(dwError==ERROR_MORE_DATA)| /* not enough space */
        dwError=0;
        /* no indication of space required, we try doubling */
        cbValueName=(cbValueName+sizeof(TCHAR))*2;
      }
      else goto end;
    }

    portinfo.lpPortName=lpPortName;
    portinfo.lpFriendlyName=lpPortName; /* no friendly name in NT 4.0 */
    if(!lpCbk(lpCbkValue,&portinfo)){
      goto end; /* listing aborted by callback */
    }
  }

end:
  free(lpValueName);
  free(lpPortName);
  if(hKey!=NULL)RegCloseKey(hKey);
  if(dwError!=0){
    SetLastError(dwError);
    return FALSE;
  }
  else return TRUE;
}

BOOL Win2000ListPorts(LISTPORTS_CALLBACK lpCbk,LPVOID lpCbkValue)
{
  return ScanEnumTree(TEXT("SYSTEM\\CURRENTCONTROLSET\\ENUM"),lpCbk,lpCbkValue);
}

BOOL ScanEnumTree(LPCTSTR lpEnumPath,LISTPORTS_CALLBACK lpCbk,LPVOID lpCbkValue)
{
  static const TCHAR lpstrPortsClass[]=    TEXT("PORTS");
  static const TCHAR lpstrPortsClassGUID[]=TEXT("|4D36E978-E325-11CE-BFC1-08002BE10318"");

  DWORD  dwError=0;
  HKEY   hkEnum=NULL;
  DWORD  dwIndex1;
  HKEY   hkLevel1=NULL;
  DWORD  dwIndex2;
  HKEY   hkLevel2=NULL;
  DWORD  dwIndex3;
  HKEY   hkLevel3=NULL;
  HKEY   hkDeviceParameters=NULL;
  TCHAR  lpClass[sizeof(lpstrPortsClass)/sizeof(lpstrPortsClass[0])];
  DWORD  cbClass;
  TCHAR  lpClassGUID[sizeof(lpstrPortsClassGUID)/sizeof(lpstrPortsClassGUID[0])];
  DWORD  cbClassGUID;
  LPTSTR lpPortName=NULL;
  LPTSTR lpFriendlyName=NULL;

  if(dwError=RegOpenKeyEx(HKEY_LOCAL_MACHINE,lpEnumPath,0,KEY_ENUMERATE_SUB_KEYS,&hkEnum)){
    goto end;
  }

  for(dwIndex1=0;;++dwIndex1){
    if(hkLevel1!=NULL){
      RegCloseKey(hkLevel1);
      hkLevel1=NULL;
    }
    if(dwError=OpenSubKeyByIndex(hkEnum,dwIndex1,KEY_ENUMERATE_SUB_KEYS,&hkLevel1)){
      if(dwError==ERROR_NO_MORE_ITEMS){
        dwError=0;
        break;
      }
      else goto end;
    }

    for(dwIndex2=0;;++dwIndex2){
      if(hkLevel2!=NULL){
        RegCloseKey(hkLevel2);
        hkLevel2=NULL;
      }
      if(dwError=OpenSubKeyByIndex(hkLevel1,dwIndex2,KEY_ENUMERATE_SUB_KEYS,&hkLevel2)){
        if(dwError==ERROR_NO_MORE_ITEMS){
          dwError=0;
          break;
        }
        else goto end;
      }

      for(dwIndex3=0;;++dwIndex3){
        BOOL               bFriendlyNameNotFound=FALSE;
        LISTPORTS_PORTINFO portinfo;

        if(hkLevel3!=NULL){
          RegCloseKey(hkLevel3);
          hkLevel3=NULL;
        }
        if(dwError=OpenSubKeyByIndex(hkLevel2,dwIndex3,KEY_READ,&hkLevel3)){
          if(dwError==ERROR_NO_MORE_ITEMS){
            dwError=0;
            break;
          }
          else goto end;
        }

        /* Look if the driver class is the one we're looking for.
         * We accept either "CLASS" or "CLASSGUID" as identifiers.
         * No need to dynamically arrange for space to retrieve the values,
         * they must have the same length as the strings they're compared to
         * if the comparison is to be succesful.
         */

        cbClass=sizeof(lpClass);
        if(RegQueryValueEx(hkLevel3,TEXT("CLASS"),NULL,NULL,
                           (LPBYTE)lpClass,&cbClass)==ERROR_SUCCESS&&
           _tcsicmp(lpClass,lpstrPortsClass)==0){
          /* ok */
        }
        else{
          cbClassGUID=sizeof(lpClassGUID);
          if(RegQueryValueEx(hkLevel3,TEXT("CLASSGUID"),NULL,NULL,
                             (LPBYTE)lpClassGUID,&cbClassGUID)==ERROR_SUCCESS&&
             _tcsicmp(lpClassGUID,lpstrPortsClassGUID)==0){
            /* ok */
          }
          else continue;
        }

        /* get "PORTNAME" */

        dwError=QueryStringValue(hkLevel3,TEXT("PORTNAME"),&lpPortName);
        if(dwError==ERROR_FILE_NOT_FOUND){
          /* In Win200, "PORTNAME" is located under the subkey "DEVICE PARAMETERS".
           * Try and look there.
           */

          if(hkDeviceParameters!=NULL){
            RegCloseKey(hkDeviceParameters);
            hkDeviceParameters=NULL;
          }
          if(RegOpenKeyEx(hkLevel3,TEXT("DEVICE PARAMETERS"),0,KEY_READ,
                          &hkDeviceParameters)==ERROR_SUCCESS){
             dwError=QueryStringValue(hkDeviceParameters,TEXT("PORTNAME"),&lpPortName);
          }
        }
        if(dwError){
          if(dwError==ERROR_FILE_NOT_FOUND)|
            /* boy that was strange, we better skip this device */
            dwError=0;
            continue;
          }
          else goto end;
        }

        /* check if it is a serial port (instead of, say, a parallel port) */

        if(_tcsncicmp(lpPortName,TEXT("COM"),3)!=0)continue;

        /* now go for "FRIENDLYNAME" */

        if(dwError=QueryStringValue(hkLevel3,TEXT("FRIENDLYNAME"),&lpFriendlyName)){
          if(dwError==ERROR_FILE_NOT_FOUND){
            bFriendlyNameNotFound=TRUE;
            dwError=0;
          }
          else goto end;
        }
       
        /* Assemble the information and pass it on to the callback.
         * In the unlikely case there's no friendly name available,
         * use port name instead.
         */
        portinfo.lpPortName=lpPortName;
        portinfo.lpFriendlyName=bFriendlyNameNotFound?lpPortName:lpFriendlyName;
        if(!lpCbk(lpCbkValue,&portinfo)){
          goto end; /* listing aborted by callback */
        }
      }
    }
  }

end:
  free(lpFriendlyName);
  free(lpPortName);
  if(hkDeviceParameters!=NULL)RegCloseKey(hkDeviceParameters);
  if(hkLevel3!=NULL)          RegCloseKey(hkLevel3);
  if(hkLevel2!=NULL)          RegCloseKey(hkLevel2);
  if(hkLevel1!=NULL)          RegCloseKey(hkLevel1);
  if(hkEnum!=NULL)            RegCloseKey(hkEnum);
  if(dwError!=0){
    SetLastError(dwError);
    return FALSE;
  }
  else return TRUE;
}

LONG OpenSubKeyByIndex(HKEY hKey,DWORD dwIndex,REGSAM samDesired,PHKEY phkResult)
{
  DWORD              dwError=0;
  LPTSTR             lpSubkeyName=NULL;
  DWORD              cbSubkeyName=128*sizeof(TCHAR); /* an initial guess */
  FILETIME           filetime;

  /* loop asking for the subkey name til we allocated enough memory */

  for(;;){
    free(lpSubkeyName);
    if(!(lpSubkeyName=(LPTSTR)malloc(cbSubkeyName))){
       dwError=ERROR_NOT_ENOUGH_MEMORY;
       goto end;
    }
    if(!(dwError=RegEnumKeyEx(hKey,dwIndex,lpSubkeyName,&cbSubkeyName,
                              0,NULL,NULL,&filetime))){
      break; /* we did it */
    }
    else if(dwError==ERROR_MORE_DATA)| /* not enough space */
      dwError=0;
      /* no indication of space required, we try doubling */
      cbSubkeyName=(cbSubkeyName+sizeof(TCHAR))*2;
    }
    else goto end;
  }

  dwError=RegOpenKeyEx(hKey,lpSubkeyName,0,samDesired,phkResult);

end:
  free(lpSubkeyName);
  return dwError;
}

LONG QueryStringValue(HKEY hKey,LPCTSTR lpValueName,LPTSTR* lppStringValue)
{
  DWORD cbStringValue=128*sizeof(TCHAR); /* an initial guess */

  for(;;){
    DWORD dwError;

    free(*lppStringValue);
    if(!(*lppStringValue=(LPTSTR)malloc(cbStringValue))){
      return ERROR_NOT_ENOUGH_MEMORY;
    }
    if(!(dwError=RegQueryValueEx(hKey,lpValueName,NULL,NULL,
                                 (LPBYTE)*lppStringValue,&cbStringValue))){
      return ERROR_SUCCESS;
    }
    else if(dwError==ERROR_MORE_DATA){
      /* not enough space, keep looping */
    }
    else return dwError;
  }
}
Это работает под всеми виндами, и считывает из режистри.
« Последнее редактирование: 28-11-2007 18:44 от Алексей1153++ » Записан

MCP, MCAD, MCTS:Win, MCTS:Web
Pu
Большой босс

ru
Offline Offline
78


« Ответ #5 : 23-06-2004 09:06 » 

MOPO3, БОЛШОЕ СПАСИБО! Сейчас буду пробовать. Правда громоздко. Но ничего.   Отлично
Записан

Насколько я опытен? Достаточно, чтобы понимать, что дураков нельзя заставить думать по–другому, но недостаточно, чтобы отказаться от попыток это сделать.
(с) Артур Джонс
MOPO3
Ай да дэдушка! Вах...
Команда клуба

lt
Offline Offline
Пол: Мужской
Холадна аднака!


WWW
« Ответ #6 : 23-06-2004 09:09 » 

Цитата: Pu
MOPO3, БОЛШОЕ СПАСИБО! Сейчас буду пробовать. Правда громоздко. Но ничего.   Отлично
Сорри, забыл сам вызов запостит Улыбаюсь Вот он :
main.c
Код:
#include "listports.h"
#include <tchar.h>
#include <stdio.h>
#include <conio.h>

static BOOL CALLBACK callback(LPVOID lpCallbackValue,LISTPORTS_PORTINFO* lpPortInfo)
{
  _tprintf(TEXT("\"%s\" \"%s\"\n"),lpPortInfo->lpPortName,lpPortInfo->lpFriendlyName);
  return TRUE;
}

#ifdef UNICODE
int wmain(void)
#else
int main(void)
#endif
{
  ListPorts(callback,NULL);
  _tprintf(TEXT("Any key to finish\n"));
  _getch();
  return 0;
}

Програмулина консольная.
« Последнее редактирование: 28-11-2007 18:44 от Алексей1153++ » Записан

MCP, MCAD, MCTS:Win, MCTS:Web
Pu
Большой босс

ru
Offline Offline
78


« Ответ #7 : 23-06-2004 09:15 » 

MOPO3,  мне самое важное вот эти вещички

static BOOL Win9xListPorts(LISTPORTS_CALLBACK lpCbk,LPVOID lpCbkValue);
static BOOL WinNT40ListPorts(LISTPORTS_CALLBACK lpCbk,LPVOID lpCbkValue);
static BOOL Win2000ListPorts(LISTPORTS_CALLBACK lpCbk,LPVOID lpCbkValue);
static BOOL ScanEnumTree(LPCTSTR lpEnumPath,LISTPORTS_CALLBACK lpCbk,LPVOID lpCbkValue);
static LONG OpenSubKeyByIndex(HKEY hKey,DWORD dwIndex,REGSAM samDesired,PHKEY phkResult);
static LONG QueryStringValue(HKEY hKey,LPCTSTR lpValueName, LPTSTR* lppStringValue);
в принципе здесь все есть. еще раз сенк ю!   Улыбаюсь
Записан

Насколько я опытен? Достаточно, чтобы понимать, что дураков нельзя заставить думать по–другому, но недостаточно, чтобы отказаться от попыток это сделать.
(с) Артур Джонс
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #8 : 23-06-2004 09:59 » 

Цитата: MOPO3
Я делаю это так :
Код:
String comm_port;
    for(int i = 1; i < 255; i++)
    {
        comm_port = "COM" + IntToStr(i);

        hComm_test = CreateFile(comm_port.c_str(), GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
        if(hComm_test != INVALID_HANDLE_VALUE)
        {
            ComPort->Items->Add("COM" + IntToStr(i));
            CloseHandle(hComm_test);
        }
    }

Решение наверно так себе, но прекрасно работает под всеми виндами


Ага я тоже так делаю, только маленькое замечание, на будущее.
Текстовые константы в SDK определены для СОМ только до СОМ9.
Я обжёгся на этом когда притащили карту с 24 СОМ портами.
Тогда начиная с СОМ10 он думает, что это СОМ1 и тд.
Поэтому надо определять имя порта полностью в формате :

\\\\.\\COMn

 hComm_test = CreateFile("\\\\.\\COM12" ....
« Последнее редактирование: 28-11-2007 18:47 от Алексей1153++ » Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Pu
Большой босс

ru
Offline Offline
78


« Ответ #9 : 23-06-2004 10:11 » 

Джон, а в эмэсдээне про это есть? и где если не секрет?
Записан

Насколько я опытен? Достаточно, чтобы понимать, что дураков нельзя заставить думать по–другому, но недостаточно, чтобы отказаться от попыток это сделать.
(с) Артур Джонс
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #10 : 23-06-2004 10:28 » 

Pu,  Именно там и нашёл...

Platform SDK: Storage
Naming a File

The following reserved device names cannot be used as the name of a file: CON, PRN, AUX, CLOCK$, NUL, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9, LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, and LPT9. Also avoid these names followed by an extension (for example, NUL.tx7).

А решение тоже где-то там находил, ща посмотрю...
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
MOPO3
Ай да дэдушка! Вах...
Команда клуба

lt
Offline Offline
Пол: Мужской
Холадна аднака!


WWW
« Ответ #11 : 23-06-2004 10:41 » 

Джон, благодарю за поправку. Мне это как раз и нужно, потому что драйвер мой умеет создавать до 255 виртуальных комов.
Записан

MCP, MCAD, MCTS:Win, MCTS:Web
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #12 : 23-06-2004 10:43 » 

Неа не получается сразу, я это давно находил ещё в MSDN для 6ой версии. А теперь у меня .NETная стоит. Там только нечто похожее для DeviceIoControl:

Remarks
To retrieve a handle to the device, you must call the CreateFile function with either the name of a device or the name of the driver associated with a device. To specify a device name, use the following format:

\\.\DeviceName

Но где-то было именно для СОМ порта ...  Жаль  Если найду скажу.

Ааааа блин, ну и ещё, конечно, формат в начале именно \\.\, а я просто выдрал из форматной строки поэтому и \\\\.\\ :oops:
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Pu
Большой босс

ru
Offline Offline
78


« Ответ #13 : 23-06-2004 10:50 » 

Джон,  и на этом спасибо, я под винды дальше сом4 еще не забирался, а тут как бы собрались мультиплексор на 32 порта моховский брать, но я надеюсь что там это поддержано на их драйверах и  мне в это углубляться не придется.
Записан

Насколько я опытен? Достаточно, чтобы понимать, что дураков нельзя заставить думать по–другому, но недостаточно, чтобы отказаться от попыток это сделать.
(с) Артур Джонс
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #14 : 23-06-2004 11:03 » 

НЕВЕРОЯТНО НО ФАКТ!!! (а то я уже думал - крыша поехала, и ведь это толко в середине рабочего дня). Короче поставил я "старую" MSDN - октябрь 2001 (ИМХО это последняя для 6ой версии) и там сразу нашёл. Не знаю, есть ли у кого ещё такие проблемы, поэтому приведу полностью

Цитата: MSDN

HOWTO: Specify Serial Ports Larger than COM9

Q115831


--------------------------------------------------------------------------------
The information in this article applies to:

Microsoft Win32 Application Programming Interface (API), used with:
Microsoft Windows NT Server versions 3.5, 3.51, 4.0
Microsoft Windows NT Workstation versions 3.5, 3.51, 4.0
Microsoft Windows 95
the operating system: Microsoft Windows 2000

--------------------------------------------------------------------------------


SUMMARY
CreateFile() can be used to get a handle to a serial port. The "Win32 Programmer's Reference" entry for "CreateFile()" mentions that the share mode must be 0, the create parameter must be OPEN_EXISTING, and the template must be NULL.

CreateFile() is successful when you use "COM1" through "COM9" for the name of the file; however, the message

INVALID_HANDLE_VALUE
is returned if you use "COM10" or greater.

If the name of the port is \\.\COM10, the correct way to specify the serial port in a call to CreateFile() is as follows:

   CreateFile(
      "\\\\.\\COM10",     // address of name of the communications device
      fdwAccess,          // access (read-write) mode
      0,                  // share mode
      NULL,               // address of security descriptor
      OPEN_EXISTING,      // how to create
      0,                  // file attributes
      NULL                // handle of file with attributes to copy
   );
 
NOTES: This syntax also works for ports COM1 through COM9. Certain boards will let you choose the port names yourself. This syntax works for those names as well.

Additional query words: 3.10 3.50

Keywords : kbAPI kbCommPort kbKernBase kbOSWin2000 kbDSupport kbGrpDSKernBase kbSerial
Issue type : kbhowto
Technology : kbAudDeveloper kbWin32sSearch kbWin32API

Last Reviewed: December 16, 2000

Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #15 : 23-06-2004 11:08 » 

теперь она и в новой нашлась, то же самое - PSS ID Number: 115831
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Pu
Большой босс

ru
Offline Offline
78


« Ответ #16 : 24-06-2004 06:17 » 

MOPO3,  все работает , уже внедрил в прожект, еще раз респект!!! Улыбаюсь
Записан

Насколько я опытен? Достаточно, чтобы понимать, что дураков нельзя заставить думать по–другому, но недостаточно, чтобы отказаться от попыток это сделать.
(с) Артур Джонс
MOPO3
Ай да дэдушка! Вах...
Команда клуба

lt
Offline Offline
Пол: Мужской
Холадна аднака!


WWW
« Ответ #17 : 25-06-2004 07:01 » 

Pu, да незашто Улыбаюсь У меня вот не выходит пока под билдер енто впихнуть  :oops:
Записан

MCP, MCAD, MCTS:Win, MCTS:Web
Pu
Большой босс

ru
Offline Offline
78


« Ответ #18 : 25-06-2004 07:39 » 

MOPO3, а в чем грабли? Подозреваю, что в пространстве имен определенных MS. типа всякие LPVOID, LPCTSTR и тп., стараюсь как можно меньше их использовать.
Записан

Насколько я опытен? Достаточно, чтобы понимать, что дураков нельзя заставить думать по–другому, но недостаточно, чтобы отказаться от попыток это сделать.
(с) Артур Джонс
Pu
Большой босс

ru
Offline Offline
78


« Ответ #19 : 25-06-2004 07:49 » 

MOPO3,  а так просто у себя в классе диалога определил функцию
    static BOOL CALLBACK callback(LPVOID lpCallbackValue,LISTPORTS_PORTINFO* lpPortInfo);
в OnInitDialog вызов    ListPorts( callback, this);
и реализация
BOOL CALLBACK CDlgProperties::callback(LPVOID lpCallbackValue,LISTPORTS_PORTINFO* lpPortInfo)
{
   CDlgProperties  *pTargetClassPtr  = (CDlgProperties *)lpCallbackValue;
   pTargetClassPtr->m_comboNumber.AddString(lpPortInfo->lpPortName);
   return TRUE;
}

все что я сделал  Отлично  - ну еще посмотрел как реализован поиск , чуток оптимизнул в своем стиле, чтоб привычнее было.   Вот такой я вот
Записан

Насколько я опытен? Достаточно, чтобы понимать, что дураков нельзя заставить думать по–другому, но недостаточно, чтобы отказаться от попыток это сделать.
(с) Артур Джонс
MOPO3
Ай да дэдушка! Вах...
Команда клуба

lt
Offline Offline
Пол: Мужской
Холадна аднака!


WWW
« Ответ #20 : 28-06-2004 13:11 » 

Джон,
Если делаю так :
Код:
hComm = CreateFile(comms_port.c_str(), 
                         GENERIC_READ | GENERIC_WRITE,
                         0,
                         0,
                         OPEN_EXISTING,
                         0,
                         0);
   
то WriteFile, ReadFile работает хорошо без ошибок, но если с FILE_FLAG_OVERLAPPED, то при попытке записать в порт или считать с порта, выкидывает ошибку Жаль В чём грабли то ? Почему в асинхронном режиме не работает ?
« Последнее редактирование: 28-11-2007 18:49 от Алексей1153++ » Записан

MCP, MCAD, MCTS:Win, MCTS:Web
Pu
Большой босс

ru
Offline Offline
78


« Ответ #21 : 29-06-2004 05:56 » 

открытие порта я делаю так , может поможет, у меня все работает именно в асинхронном режиме:

   if (INVALID_HANDLE_VALUE  == (hPort =
      CreateFile( W2A(m_NamePort), GENERIC_READ | GENERIC_WRITE,
                  0,                    
                  0,                
                  OPEN_EXISTING,
                  FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
                  0)))
      return ( FALSE ) ;
   else
   {
      SetCommMask(hPort, EV_RXCHAR);
      SetupComm(hPort, 4096, 4096) ;
      PurgeComm( hPort, PURGE_TXABORT | PURGE_RXABORT |
                                      PURGE_TXCLEAR | PURGE_RXCLEAR ) ;
  // установки для overlapped I/O
      CommTimeOuts.ReadIntervalTimeout = 0xFFFFFFFF ;
      CommTimeOuts.ReadTotalTimeoutMultiplier = 0 ;
      CommTimeOuts.ReadTotalTimeoutConstant = 1000 ;
      CommTimeOuts.WriteTotalTimeoutMultiplier = 20;
      CommTimeOuts.WriteTotalTimeoutConstant = 0 ;
      SetCommTimeouts( hPort, &CommTimeOuts );
   }
Записан

Насколько я опытен? Достаточно, чтобы понимать, что дураков нельзя заставить думать по–другому, но недостаточно, чтобы отказаться от попыток это сделать.
(с) Артур Джонс
MOPO3
Ай да дэдушка! Вах...
Команда клуба

lt
Offline Offline
Пол: Мужской
Холадна аднака!


WWW
« Ответ #22 : 29-06-2004 07:15 » 

Взял статью Программирование COM - порта с использованием WinApi и Assemblera отсюда http://www.dchack.net/

Адаптировал под своё приложение. Первая форма(список комов+настройки порта+кнопка открыть), по нажатию кнопки открывается вторая форма(типо окно куда выводятся сообщения о том что происходит). Проблем в том, что когда доходит до ожидания события на порт, прога плотно повисает Жаль Не могу ни между формами перерубиться ни какой-нить баттон нажать Жаль Вот код :
Код:
hComm = CreateFile("COM3",
                         GENERIC_READ | GENERIC_WRITE,
                         0,
                         NULL,
                         OPEN_EXISTING,
                         FILE_FLAG_OVERLAPPED,
                         NULL);
int retcode = PurgeComm(hComm, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);

        if( retcode==NULL ) { ComTerm->ComInfo->Lines->Add("(-) PurgeComm() failed"); }
        else { ComTerm->ComInfo->Lines->Add("(+) Discarded all characters from the output and input buffer"); }

        retcode = ClearCommBreak(hComm);
        if( retcode==NULL ){ ComTerm->ComInfo->Lines->Add("(-) ClearCommBreak() failed"); PrintLastError(); }
        else { ComTerm->ComInfo->Lines->Add("(+) Restored character transmission. Transmission line in a nonbreak state"); }

        dcbCommPort.DCBlength = sizeof(DCB);
        retcode = GetCommState(hComm,&dcbCommPort);
        if( retcode==NULL ) { ComTerm->ComInfo->Lines->Add("(-) GetCommState() failed"); }
        else { ComTerm->ComInfo->Lines->Add("(+) Retrieved the current control settings for COM" + IntToStr((ComPort->ItemIndex + 1))); }

        String info = BitsPerSecond->Text + ",N," + DataBits->Text + "," + StopBits->Text;
        BuildCommDCB(info.c_str(), &dcbCommPort);

        retcode = SetCommState(hComm, &dcbCommPort);
        if( retcode==NULL ) { ComTerm->ComInfo->Lines->Add("(-) SetCommState() failed"); }
        else { ComTerm->ComInfo->Lines->Add("(+) Reinitialized all hardware and control settings"); }

        DWORD CommEventMask = EV_BREAK | EV_CTS | EV_DSR | EV_ERR | EV_RING | EV_RLSD | EV_RXCHAR | EV_RXFLAG | EV_TXEMPTY;
        retcode = SetCommMask(hComm,CommEventMask);
        if( retcode==NULL ){ ComTerm->ComInfo->Lines->Add("(-) SetCommMask() failed"); PrintLastError(); }
        else { ComTerm->ComInfo->Lines->Add("(+) BREAK, CTS, DSR, ERR, RING, RLSD, RXCHAR, RXFLAG, TXEMPTY"); }

        OVERLAPPED OL;
        OL.hEvent=CreateEvent(NULL, TRUE, FALSE, NULL);
        DWORD EventMask = 0; //n?aa aoaao caienai oei niauoey
        ComTerm->ComInfo->Lines->Add(" ");
        ///////////////////////////////////////////////////////////////////
        do|
        retcode = WaitCommEvent(hComm, &EventMask, &OL);
        if ( ( !retcode ) && (GetLastError()==ERROR_IO_PENDING) )
        {
                ComTerm->ComInfo->Lines->Add("(!) Waiting for event");
                WaitForSingleObject(OL.hEvent, INFINITE);
        }
       
if(EventMask & EV_BREAK)   ComTerm->ComInfo->Lines->Add("(i) EV_BREAK");
        if(EventMask & EV_RLSD)    ComTerm->ComInfo->Lines->Add("(i) EV_RLSD");
        if(EventMask & EV_CTS)     ComTerm->ComInfo->Lines->Add("(i) EV_CTS");
        if(EventMask & EV_DSR)     ComTerm->ComInfo->Lines->Add("(i) EV_DSR");
        if(EventMask & EV_ERR)     ComTerm->ComInfo->Lines->Add("(i) EV_ERR");
        if(EventMask & EV_RING)    ComTerm->ComInfo->Lines->Add("(i) EV_RING");
        if(EventMask & EV_RXCHAR)  ComTerm->ComInfo->Lines->Add("(i) EV_RXCHAR");
        if(EventMask & EV_RXFLAG)  ComTerm->ComInfo->Lines->Add("(i) EV_RXFLAG");
        if(EventMask & EV_TXEMPTY) ComTerm->ComInfo->Lines->Add("(i) EV_TXEMPTY");
       
        DWORD ErrorMask = 0;
        COMSTAT CStat;
        ClearCommError(hComm, &ErrorMask, &CStat);
        DWORD quelen = CStat.cbInQue;
       
        char *lpInBuffer = new char[ (int)quelen+1 ];
        memset(&lpInBuffer, '\0', (int)quelen);

        DWORD dwReaded = 0;
        retcode = ReadFile(hComm, lpInBuffer, quelen, &dwReaded, &OL);

        if( dwReaded == 0 && GetLastError() == ERROR_IO_PENDING )
        {
           
           // DoSomeThing
           retcode = GetOverlappedResult(hComm, &OL, &dwReaded, FALSE) ;
        }
        else
        {
           if (dwReaded>0) //anee i?i?eoaee aaiiua
           {
              ComTerm->ComInfo->Lines->Add("(+) " + IntToStr(dwReaded) + " bytes received (" + lpInBuffer + ")");
           } else { ComTerm->ComInfo->Lines->Add("(-) ReadFile() failed. errno " + IntToStr(GetLastError()) + ""); }
        }

        if( PurgeComm(hComm, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR) == NULL )
        {
            ComTerm->ComInfo->Lines->Add("(-) PurgeComm() failed");
            PrintLastError();
        }else { ComTerm->ComInfo->Lines->Add("(+) Discarded all characters from the output and input buffer"); }

        EventMask=0;
        ResetEvent(OL.hEvent);
        }while(1);
« Последнее редактирование: 28-11-2007 18:53 от Алексей1153++ » Записан

MCP, MCAD, MCTS:Win, MCTS:Web
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #23 : 29-06-2004 07:17 » 

MOPO3,  А overlapped структуру передаёшь? А какая ошибка?  - ERROR_IO_PENDING? Тогда всё нормально. Это значит, что данные не все переданы и ты можешь продолжить чтение(запись) или прервать.
В overlapped структуре поле скажет тебе сколько байт считалось.

Типа так:

1.

  FileHandle = ::CreateFile(
            Name,
            GENERIC_READ | GENERIC_WRITE,       // access mode
            FILE_SHARE_WRITE | FILE_SHARE_READ, // share mode
            NULL,                               // security desc.
            OPEN_EXISTING,                      // how to create
            FILE_FLAG_OVERLAPPED,               // file attributes
            NULL                                // template file
            );

2. потом при чтении (записи)

   BOOL succ;

   succ = ReadFile(
               FileHandle,     // handle of file to read
               Buffer(),  // pointer to buffer that receives data
               NumberOfBytesToTransfer,  // number of bytes to read
               &BytesTransferred, // pointer to number of bytes read
               &Overlapped        // pointer to overlapped structure
               );
   if( succ )
   {
      Status = USBIO_ERR_SUCCESS;
   }
   else
   {
      Status = GetLastError();
      if( Status == ERROR_IO_PENDING )
      {
         succ = TRUE;
      }
   }

   return succ;
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
MOPO3
Ай да дэдушка! Вах...
Команда клуба

lt
Offline Offline
Пол: Мужской
Холадна аднака!


WWW
« Ответ #24 : 29-06-2004 07:20 » 

Джон, видно с тобой в одно время запостили  Улыбаюсь  Смотри выше я код запостил.  overlapped структуру я передаю вроде как Улыбаюсь

Экзешник(если есть желание посмотреть что происходит. там практически не рабочая прога Улыбаюсь пока тока часть с комами програмлю) лежит тута : ссылку почикал сам Улыбаюсь[/b]
Записан

MCP, MCAD, MCTS:Win, MCTS:Web
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #25 : 29-06-2004 07:29 » 

MOPO3,  Опередил меня на две минутки Ага
Сорри,   Так больше нельзя...  ща нет времени в твоём коде детально разбираться. На первый взглаяд выглядит правильно (касательно тех пунктов про которые я говорил).
А что за ошибка?
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
MOPO3
Ай да дэдушка! Вах...
Команда клуба

lt
Offline Offline
Пол: Мужской
Холадна аднака!


WWW
« Ответ #26 : 29-06-2004 07:30 » 

Джон, Опятьпостами разошлись Улыбаюсь выше смотри. А ошибки то и нет никакой Улыбаюсь просто прога зависает на ожидании ивента Жаль
Записан

MCP, MCAD, MCTS:Win, MCTS:Web
Pu
Большой босс

ru
Offline Offline
78


« Ответ #27 : 29-06-2004 07:45 » 

MOPO3, да и ышо , для приема в порт я создаю отдельный поток, который и висит постоянно в процедуре  WaitCommEvent пока оно не случится Улыбаюсь. типа
    hCommThread =
                        CreateThread( (LPSECURITY_ATTRIBUTES) NULL,
                                    0,
                                    (LPTHREAD_START_ROUTINE)runProcess,
                                    (LPVOID) this,
                                    0, &dwThreadID)
//запуск нити
DWORD RSPort::runProcess(void* Param)
{
    return   ((RSPort *)Param)->CommProc(0);
}
// CommProc();
DWORD RSPort::CommProc( LPSTR lpData )
{
 DWORD       dwEvtMask ;
 OVERLAPPED  os ;
 int        nLength ;
 BYTE       abIn[MAXBLOCK + 1] ;
   memset( &os, 0, sizeof(OVERLAPPED) ) ;
   os.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
   if (os.hEvent == NULL)
   {
      return ( FALSE ) ;
   }

   if (!SetCommMask(hPort, EV_RXCHAR))
                return ( FALSE ) ;
   Count = 0;
   while(CONNECTED)
   {
      dwEvtMask = 0 ;
      WaitCommEvent(hPort, &dwEvtMask, NULL);
      if (EV_RXCHAR == (dwEvtMask & EV_RXCHAR))
      {
         //ATLTRACE("получаю\n");
         Lock();
         do
         {
            if (nLength = ReadCommBlock((LPSTR) abIn, MAXBLOCK ))
            {
               //ATLTRACE("получил %d байт\n",nLength);
               SleepEx(5,TRUE);
            }
            else
               break;
         }
         while(1);
         Unlock();
         //ATLTRACE("закончил получать байты %d байт\n", Count );
         SetEvent(hEventRead);
                           // разбор полетов
      }
   }
   CloseHandle( os.hEvent ) ;
   THREADID = 0 ;
   return( TRUE ) ;
}
Записан

Насколько я опытен? Достаточно, чтобы понимать, что дураков нельзя заставить думать по–другому, но недостаточно, чтобы отказаться от попыток это сделать.
(с) Артур Джонс
Pu
Большой босс

ru
Offline Offline
78


« Ответ #28 : 29-06-2004 07:46 » 

правда я асинхронно только принимаю Жаль. Но думаю что передавать можно так же
Записан

Насколько я опытен? Достаточно, чтобы понимать, что дураков нельзя заставить думать по–другому, но недостаточно, чтобы отказаться от попыток это сделать.
(с) Артур Джонс
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #29 : 29-06-2004 08:13 » 

MOPO3,  Слушай я что-то не вижу ....  Она у тебя наверно тут висит:

WaitForSingleObject(OL.hEvent, INFINITE);

Если так, то ставь время поменьше и прверяй переданные байты и решай оборвать или нет только проверяй WaitForSingleObject(OL.hEvent, 1000); на TIME_OUT

время задержки выбери согласно твоим условиям (скорости железа и тд)
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Страниц: [1] 2  Все   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines