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

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

  Все выпуски  

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


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

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

Поиск ресурсов в локальной сети

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

Новые статьи


   -  Работа с сервисами
   -  Как программно нажать кнопку "Start" ?
   -  Как создавать значки в панели управления
   -  Работаем с Панелью управления
   -  Простой COM ? клиент

Ну что же, пора переходить к довольно интересному вопросу ? как искать ресурсы в сети. Ресурсы локальной сети образуют древовидную структуру. Позволим себе цитату из документации Microsoft, если рисунок можно назвать цитатой.

Внимательно посмотрите на рисунок. Самыми низшими ветвями дерева являются Sharepoint. Это ни что иное, как сетевые каталоги и сетевые принтеры. Всё дерево растет из одного корня. На втором уровне располагаются провайдеры. Скорее всего, вы встретитесь только с двумя провайдерами: Microsoft Network и NetWare. Стало быть, для того, чтобы узнать, какие ресурсы в вашей сети, вам придется писать программу, которая совершает обход представленного дерева. Не думайте, однако, что это безумно сложно. К, счастью, имеются функции АРI, которые легко справляются с поставленной задачей. Правда, без рекурсии все же не обойтись, но писать рекурсивные функции, господа, ? это же одно удовольствие. Мы начнем с описания трех функций, с помощью которых собираемся изучать нашу сеть.

DWORD WnetOpenEnum
{
 DWORD dwScope,
 DWORD dwType
 DWORD dwtUsage,
 LPNETRESOURCE lpNetResource,
 LPHANDLE lphEnum
}

Первый параметр ? определяет множество, на котором ищутся ресурсы. Может принимать следующие значения: RESOURCE_CONNECTED, RESOURCE_CONTEXT, RESOURCE_GLOBALNET, RESOURCE_REMEMBERED.

Второй параметр ? определяет тип искомого ресурса. Может принимать следующие значения: RESOURCETYPE_ANY, RESOURCETYPE_DISK, RESOURCETYPE_PRINT.

Третий параметр ? принимает следующие значения: 0 (для всех ресурсов), RESOURCEUSAGE_CONNECTABLE, RESOURCEUSAGE_ALL, RESOURCEUSAGE_CONTAINER, RESOURCEUSAGE_ATTACHED.

Четвертый параметр ? является указателем на структуру NETRESOURCE. Если первый параметр не равен RESOURCE_GLOBALNET, то данный параметр следует положить равным нулю. Если вы хотите начать поиск с самого начала (от корня) дерева, то первый раз следует вызвать функцию с параметром равным NULL.

Пятый параметр ? является указателем на переменную, которая в случае успешного выполнения функции становится дескриптором поиска.

Следующая функция осуществляет всю работу по поиску ресурсов данного уровня.

DWORD WnetEnumResource
{
 HANDLE hEnum,
 LPDWORD lpcCount,
 LPVOID lpBuffer,
 LPDWORD lpBufferSize
}

Первый параметр - дескриптор поиска, полученный в результате работы функции WnetEnumResource.

Второй параметр ? указывает на переменную, которая должна содержать количество ресурсов, которые следует найти. Если переменная содержит 0xFFFFFFFF т. е. -1, то функция будет стараться найти все ресурсы данного уровня.

Третий параметр ? указывает на буфер, который получит информацию о найденных ресурсах. Функция трактует этот буфер, как массив из структур NETRESOURCE. Следует взять гарантированно большой буфер.

Четвертый параметр ? указатель на переменную, которая содержит количество байт в буфере. Если буфер слишком мал, то после выполнения функции (с ошибкой) параметр будет содержать необходимый размер буфера.

Как и другие Wnet-функции, данная функция возвращает NO_ERROR, если она выполнилась успешно. Сообщение об ошибке - ERROR_NO_MORE_ITEMS - говорит нам, что не найдено ни одного ресурса.

Последняя в указанном ряду функция закрывает поиск, на который указывает дескриптор hEnum.

DWORD WnetCloseEnum
{
 HANDLE hEnum
}

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

#include "stdafx.h"
#include <windows.h>

void poisk(NETRESOURCE,int);

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
 NETRESOURCE NT;
 poisk(NT,0);
 return 0;
}

//функция поиска сетевых ресурсов
void poisk(NETRESOURCE nt, int pr)
{
 DWORD l,m,r;
 HANDLE h;
 int i;
 NETRESOURCE ntbuf[1000];
 char s[100];
 if(!pr)
  l = WNetOpenEnum(RESOURCE_GLOBALNET, RESOURCETYPE_ANY, 0, &nt, &h);
 else
  l = WNetOpenEnum(RESOURCE_GLOBALNET, RESOURCETYPE_ANY, 0, &nt, &h);

 if(l==NO_ERROR)
 {
  //ресурс открыт
  do
  {
   //просим вывести максимальное количество записей
   m=0xFFFFFFFF;
   //размер буфера
   r=32000;
   //обнуляем буфер
   l=WNetEnumResource(h, &m, &ntbuf, &r);
   if(l==NO_ERROR)
   {
    //здесь смотрим, что за ресурс мы получили
    //вывод информации
    for(i=0; i<m; i++)
    {
     if(ntbuf[i].lpRemoteName!=NULL)
     {
      //сетевое имя
      CharToOem(ntbuf[i].lpRemoteName,s);
      printf("%s\n",s);
      //комментарий
      CharToOem(ntbuf[i].lpComment,s);
      printf("Comments: %s\n",s);
     }
     //рекурсивный вызов
     poisk(ntbuf[i],1);
    }
   }else if(l!=ERROR_NO_MORE_ITEMS)
   {
    //ошибка, нужно выходить из цикла
    break;
   }
  }
  while(l!=ERROR_NO_MORE_ITEMS);
  WNetCloseEnum(h);
 }
}

Теперь прокомментируем программу, представленную выше.

  1. Функция poisk вполне универсальна и может быть приспособлена для разных программ. Она позволяет не только просматривать все дерево сетевых ресурсов. Структуру NETRESOURCE можно заполнить для любого уровня и вызвать функцию, указав значение второго параметра неравным нулю. для этого необходимо задать следующие поля: dwScore, dwType, dwUsage(0), lpRemoteName, lpLocalName(NULL).
  2. Функция WNetEnumResource не позволяет определять скрытые ресурсы (сетевые диски с именами, оканчивающимися на ?$?). Для этой цели следует использовать функцию из другой группы - что мы и делаем ниже.
  3. Проверка if(ntbuf[i].lpRemoteName!=NULL) необходима для запуска программы на рабочих станциях с операционными системами Windows 95/98/МЕ. На втором уровне у данных операционных систем lpRemoteName оказывается равным NULL.

В заключении параграфа приведем пример на использование функции NetShareEnum. Пример взят из документации Microsoft и несколько переработан.

#include "stdafx.h"

#define UNICODE
#include <windows.h>
#include <stdio.h>
#include <lm.h>


//для использования Unicode имя главной функции wmain
int wmain(int argc, char *lpszArgv[ ])
{
 PSHARE_INFO_502 BufPtr,p;
 NET_API_STATUS res;
 LPTSTR lpszServer = NULL;
 DWORD er=0,tr=0,resume=0, i;
 char * ers="Error: ";
 //разбор командной строки
 if(argc==2)
 lpszServer =(LPTSTR) lpszArgv[1]; else
 {
  printf("Usage: NetShareEnum <servername>\n");
  return;
 };
 printf("Share: Local Path: User:  Descriptor:\n");
 printf("-----------------------------------------\n");
  do
  {
   //получить информацию об общих ресурсах на сервере
   res=NetShareEnum((LPWSTR)lpszServer,502,(LPBYTE *) _
   &BufPtr, -1, &er, &tr, &resume);
   if(res == ERROR_SUCCESS || res == ERROR_MORE_DATA)
   {
    p=BufPtr;
    //цикл по всем записям
    for(i=1;i<=er;i++)
    {
     printf("%-20S%-30S%-8u",p->shi502_netname, _
     p->shi502_path, p->shi502_current_uses);
     if(IsValidSecurityDescriptor_
               (p->shi502_security_descriptor))
      printf("Yes\n");
     else
      printf("No\n");
     p++;
    }
    NetApiBufferFree(BufPtr);
   }
   else
   {
    //код ошибки
    printf("%s %ld\n", ers, res);
   }
  }
  while(res==ERROR_MORE_DATA);
  return;
}

При запуске программы в командной строке следует указать путь к серверу. Например, если в сети есть сервер Lilia, а имя программы net3 следует набрать net3 Lilia либо net3 \\Lilia. Типичные ошибки, которые может возвратить программа - это 50 - сетевой запрос не поддерживается, 53 - неверный путь. В первом случае ошибка означает, что на запрашиваемом компьютере, по-видимому, работает операционная система Windows 95/98/МЕ, во втором случае вы неправильно набрали имя сервера.

Так же программа находит скрытые устройства, которые невозможно обнаружить с помощью функции WnetEnumResourcu.


2004-2005 P-Lib


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

В избранное