Отправляет email-рассылки с помощью сервиса Sendsay

Статьи по Visual C++

  Все выпуски  

Статьи по Visual C++.NET


Информационный Канал Subscribe.Ru

Главная P-Lib Выпуск 1

Доступ к ресурсам локальной сети

  Visual C++.NEt |   Visual Basic.NET |   Delphi |   ASP.NET |   Java |   Perl |   Базы данных 

Новые статьи


   -  Классы для работы с регулятором громкости
   -  Завершение работы Windows
   -  Режимы отображения координат
   -  Использование класса CEvent
   -  Таймеры в приложениях MFC

Сетевые устройства

В прикладном программировании часто возникает проблема определения сетевых устройств. В принципе, вопрос можно поставить более широко: как определить тип того или иного устройства. Тот, кто программировал MS-DOS, помнит, что там правильное определение типа устройства, было не простой задаче. Операционная система Windows и здесь облегчает нам задачу. Здесь имеется очень полезная функция GetDriveTyte, единственным аргументом которой является строка корневого каталога искомого устройства, например “A:\” или ”D:\”. В таблице представлены возвращаемые этой функцией значения.

Напишем простую программу, выдающую список сетевых устройств.
Создадим проект диалоговой программы. Поместим в окно список ListBox и добавим к классу диалогового окна переменную m_list. Теперь осталось изменить код функции OnInitDialog(), текст её представлен ниже.

BOOL CDriveTypeDlg::OnInitDialog()
{
 CDialog::OnInitDialog();
 SetIcon(m_hIcon, TRUE);
 SetIcon(m_hIcon, FALSE);
 CString dr[26]={"A:\\","B:\\",
         "C:\\","D:\\","E:\\",
         "F:\\","G:\\","H:\\",
         "I:\\","J:\\","K:\\",
         "L:\\","M:\\","N:\\",
         "O:\\","P:\\","Q:\\",
         "R:\\","S:\\","T:\\",
         "U:\\","V:\\","W:\\",
         "X:\\","Y:\\","Z:\\"};
 CString s;
 for(int i=0;i<26;i++)
 {
  //разбор результата
  switch(GetDriveType(dr[i]))
  {
  case DRIVE_UNKNOWN:
   s="неизвестное устройство";
   break;
  case DRIVE_NO_ROOT_DIR:
   s="устройство не определено";
   break;
  case DRIVE_REMOVABLE:
   s="сменное устройство";
   break;
  case DRIVE_FIXED:
   s="жёсткий диск";
   break;
  case DRIVE_REMOTE:
   s="сетевое устройство";
   break;
  case DRIVE_CDROM:
   s="устройство CD-ROM";
   break;
  case DRIVE_RAMDISK:
   s="виртуальное устройство (RAM)";
   break;
  default:
   s="???????";
   break;
  }
  s=dr[i].Mid(0,2)+" "+s;
  m_list.AddString(s);
 }
 return TRUE;
}

После того как вы определили, что данное устройство является сетевым, может возникнуть вторая задача: определить статус устройства. Под статусом в данном случае понимаются три возможных ситуации: устройство открыто для чтения и записи, устройство открыто только для чтения, устройство не доступною. Обычно мы поступаем следующим образом. Для проверки статуса устройства используем две функции: CreateFile и GetDiskFreeSpace. Пеовая функция API позволяет создавать файлы, вторая функция определяет количество свободного места на устройстве. Если данное устройство позволяет создать файл (файл лучше создавать с атрибутом «удалить после закрытия», и операционная система сама выполнит процедуру удаления) и прочесть данные об устройстве, следовательно, оно открыто для чтения и записи. Если устройство позволяет прочитать данные об устройстве, но не позволяет создать файл, следовательно, устройство открыто только для чтения. Наконец, если не разрешено ни то, ни другое, следовательно, устройство не доступно. Такой бесхитростный подход, однако, работает весьма эффективно. Вот примерная функция, выполняющая данную операцию.

//функция проверки статуса диска(устройства)
//0 - устройство доступно для записи и чтения
//1 - устройство доступно только для чтения
//2 - устройство не доступно
int whatdisk(char * path)
{
 DWORD snac;  //секторов на кластер
 DWORD bnas;  //байт на сектор
 DWORD sc;    //свободных кластеров
 DWORD wc;    //всего кластеров
 char df[200];
 strcpy(df, path);
 //вначале возможно ли узнать объём
 int j=GetDiskFreeSpace(df, &snac, &bnas, &sc, &wc);
 //теперь попытка создать файл
 strcat(df,"Пробный файл! Пробный файл!");
 HANDLE h = CreateFile(df, GENERIC_WRITE, 
                  FILE_SHARE_WRITE, 
                  NULL, 
                  CREATE_ALWAYS, 
                  FILE_FLAG_DELETE_ON_CLOSE, 
                  NULL);
 if(h!=INVALID_HANDLE_VALUE)
 {
  CloseHandle(h);
     return 0;
 }
 else
 {
  if(j!=0) return 1; else return 2;
 }
}

Готовый пример можно скачать здесь(19Kb).

Подключение сетевого устройства

Для дальнейшего изучения сетевых ресурсов нам понадобится структура NETRESOURCE. Эта структура используется сетевыми функциями, в нее помещается информация о найденном ресурсе. Стало быть, займемся ее изучением.

typedef struct _NETRESOURCE
{
 DWORD dwScope;
 DWORD dwType; 
 DWORD dwDisplayType; 
 DWORD dwUsage; 
 LPTSTR lpLocalName; 
 LPTSTR lpRemoteName; 
 LPTSTR lpComment; 
 LPTSTR lpProvider;
}NETRESOURCE;
  • DwScore - может принимать одно из трех значений:
    • RESOURCE_CONNECTED - ресурс подсоединен в настоящее время;
    • RESOURCE_REMEMBERED - ресурс, запоминаемый системой, чтобы при запуске автоматически подсоединяться к нему;
    • RESOURCE_GLOBALNET - глобальный сетевой ресурс. Скорее всего, вам понадобится только это значение.
  • DwType – тип ресурса. Возможны следующие значения:
    • RESOURCETYPE_ANY – любой ресурс;
    • RESOURCETYPE_DISK - диск;
    • RESOURCETYPE_PRINT - сетевой принтер.
  • DwDisplayType - как данный ресурс должен быть представлен сетевым браузером. Типов довольно много. Например, для сетевого компьютера определён тип RESOURCEDISPLAYTYPE_SERVER, для группы - RESOURCEDISPLAYTYPE_GROUP, для домена RESOURCEDISPLAYTYPE_DOMAIN и т. д.
  • dwUsage - принимает два значения: RESOURCEUSAGE_CONTAINER и RESOURCEUSAGE_CONNECTABLE.
  • lpLocalName - локальное имя устройства, например E:, LPT1: и т. п.
  • lpRemoteName - сетевое имя, например \\SUPER, \\NDI\EPSON и т. д.
  • lpComment - комментарий к сетевому ресурсу.
  • LpProvider - имя провайдера. Обычно имя может принимать одно из двух значений: Micrоsoft Natwork и NetWare, но возможны и другие имена.

Для подключения сетевых устройств, их отключения и получения информации о них используют в основном следующие три функции:WNetAddConnection2, WNetCancelConnection2, WNetGetConnection. Вот их описание.

DWORD WnetGetConnection
{
 LPCTSTR lpLocalName, 
 LPTSTR lpRamoteNama, 
 LPDWORD lpnLength
}

Первый параметр — локальное имя устройства.
Второй параметр — указывает на буфер, куда будет помещено сетевое имя устройства.
Третий параметр — длина буфера.

DWORD WNetAddConnection2
{
 LPNETRESOURCE lpNotResource,
 LPCTSTR lpPassword,
 LPCTSTR lpUserName,
 DWORD dwFlags
}

Первый параметр — указатель на структуру NETRESOURCE. Должны быть заполнены следующие поля: dwType, lpLocalName, lpRemoteName, lpProvider (обычно NULL).
Второй параметр — пароль, необходимый для соединения с ресурсом. В случае пустой строки — соёдинение беспарольное, в случае NULL — берется пароль, ассоциированный с именем.
Третий параметр — имя пользователя. Если значение NULL, то берется имя по умолчанию.
Четвертый параметр — данный параметр определяет, будет ли система, потом автоматически подсоединяться к данному ресурсу при перезапуске. В случае значения CONNECT_INTERACTIVE такого подсоединения не происходит. Если вам необходимо автоматическое подсоединение, установите флажок CONNECT_UPDATE_PROFILE.

При успешном завершении функция возвращает 0 (NO_ERROR). Ненулевое значение определяет причину ошибки около десяти возможных значений ошибки приведено в документации по данной функции.

DWORD WNetCancelConnection2
{
 LPCTSTR lpName,  
 DWORD dwFlags, 
 BOOL fForce
}

Первый параметр — включает указатель на строку, содержащую имя ресурса. Причем если имя локальное, то разрывается данноё локальное соединение. Если это имя удаленного ресурса, то разрываются все соединения с данным ресурсом.
Второй параметр - определяет, будет ли система и далее подсоединяться к данному ресурсу. Если 0, то подсоединение (если было) будет возобновляться при следующем запуске системы. Другое значение параметра CONNECT_UPDATE_PROFILE.
Третий параметр - если значение ненулевое (true), то отсоединение произойдет, даже если на сетевом диске имеются открытые файлы или сетевой принтер выполняет задание с данного компьютера.

Как и предыдущая функция, в случае успешного выполнения данная функция возвращает NO_ERROR. Другие значения говорят о наличии ошибки.

Предупреждение.
Для работы со всеми функциями, имя которых начинается с префикса WNet, следует подключить библиотеку mpr.lib (свойство проекта Linker/Command Line).

Наш пример со списком устройств данного компьютера можно развить дальше. Предполагаем такой сценарий работы программы: двойной щелчок в списке по сетевому устройству вызывает его отключение, а двойной щелчок по свободному устройству позволяет ввести сетевое имя, к которому затем данное устройство будет подключено.

  1. Создадим еще один ресурс — диалоговое окно — и свяжем его с классом dialog.
  2. В диалоговое окно добавим поле редактирования и свяжем его с переменной m_edit.
  3. Введем в класс Cnet1App(производный от CWinApp) переменную m_edit. Она в дальнейшем будет содержать введенную в поле редактирования строку.
  4. Добавим в класс dialog обработку кнопки ОК и перепишем функцию OnInitDialog.
void dialog::OnBnClickedOk()
{
 //произвести обмен данными 
 UpdateData(true);
 m_edit.GetWindowText(theApp.m_str); 
 OnOK();
}

BOOL dialog::OnInitDialog()
{
 //установить фокус ввода
 CWnd * cw= 
 GetDlgltern(IDC_EDIT2);cw->SetFocus();
 return false;
}
  1. В функции обработки нажатия кнопки обратите внимание на вызов UpdateData() - он необходим, чтобы данные из поля редактирования перекочевали в переменную m_edit. 6. Теперь в основном диалоговом окне напишем обработку двойного щелчка по элементу списка. Функция обработки приведена ниже.
void CnetlDlg::OnLbnDblclkList1()
{
 CString s;
 int i=m_list.GetCurSel:
 m_list.GetText(i,s);
 if (s.Find("сетевое устройство")>=O)
 {
  //здесь пытаемся отключить 
  if(WNetCancelConnection2(s.Mid(0,2) ,0, false)!=NO_ERROR) 
   MessageBox("Ошибка сети","",MB_OK); 
  else
  {
   //обновить список
   m_list.ResetContent();
   //снова заполнить список 
   OnInitDialog(); 
   //вернуться к текущей записи 
   m_list.SetCurSel(i);
  }
 }
 else if(s.Find("Устройство не определено")>=0)
  {
   //Здесь вывести диалоговое окно для определения
   //куда будем подключать данное локальное устройство
   dialog cd;
   INT_PTR result=cd.DoModal(); 
   if(result==IDOK)
   {
    //здесь пытаемся соединиться с указанным ресурсом
    char ss[50],sss[50];
    //определяем локальное устройство
    int i=m_list.GetCurSel();
    m_list.GetText(i,s);
    strcpy(sss,s.Mid(0,2));
    NETRESOURCE nt;
    //заполняем структуру
    nt.dwType=RESOURCETYPE_DISK;
    nt.lpLocalName=sss;
    strcpy(ss, theApp.m_str);
    nt.lpRemoteName = ss;
    nt.lpProvider=NULL;
    if(WNetAddConnection2(&nt,NULL,NULL, CONNECT_INTERACTIVE)!=NO_ERROR)
    MessageBox("Ошибка сети","",MB_OK);
    //очистить список
    m_list.ResetContent();
    //снова заполнить список
    OnlnitDialog(); 
    //вернуться к текущей записи
    m_list.SetCurSel(i);
   }
  }
}


©2004-2005 P-Lib


http://subscribe.ru/
http://subscribe.ru/feedback/
Подписан адрес:
Код этой рассылки: comp.soft.prog.visualc
Отписаться

В избранное