Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 05.11.2009, 21:18   #1
zdovim
Новичок
Джуниор
 
Регистрация: 05.11.2009
Сообщений: 9
Лампочка ReadDirectoryChangesW + NetFileEnum/NetSessionEnum

Привет!
Такая проблема: у человека есть расшаренная папка в локальной сети. С этой папкой работают другие пользователи этой локалки (то есть создают, изменяют и т.д. файлы и папки в ней). Этот человек хочет мониторить все изменения, сделанные другими юзерами локальной сети, а также видеть автора каждого изменения (то есть связку username@computername).

С первым (мониторинг изменений) успешно справляется функция ReadDirectoryChangesW(). Второе (определение автора изменений) решил сделать через связку NetFileEnum() и NetSessionEnum(). Но после тестирования выяснилось, что 100% я могу определить лишь создание файла. Все остальные операции (изменение, переименование, удаление) я могу определить лишь с некоторой долей вероятности. /* Наиболее проблемно - удаление. */

Вопрос: можно ли как-то иначе с большей вероятностью определить автора действий в расшаренной папке?

Пока есть только такая идея: если я не ошибаюсь, компы с виндой используют smb-протокол для обмена данных по шарам, а smb - не что иное, как NetBios. Так может есть смысл юзать сниффер NetBios'a на локальном компе этого человека и через него определять то, что меня интересует?
zdovim вне форума Ответить с цитированием
Старый 05.11.2009, 22:10   #2
raxp
Старожил
 
Регистрация: 29.09.2009
Сообщений: 9,713
По умолчанию

вы правы, 100% определить через netapi32 нельзя... мало того, если на ресурсе шарится несколько пользователей с одинаковыми именами, то идентифицировать кто-какой файл через NetFileEnumNT нереально, т.к. FileInfoNT просто не содержит такой информации (FileInfoNT^[i].fi3_username - имя, но не IP, а IP содержится в SessionInfo502^[i].sesi502_cname которая относится к NetSessionEnumNT) (...с этим столкнулся при разработке своего NETAPI детектора подключений)
...
правда есть в этих функциях и плюс, можно регистрировать посылку документов на печать кто-что (если подкл.принтер к этой машине)
...
по поводу smb мысль интересная, надо порыть... и еще, смотрел как файрволл касперского ловит файлы, иногда неправильно (вот интересно, как у него реализовано... хотя скорее он просто внедряет прослойку в сетевом интерфейсе и снифит)
Разработки и научно-технические публикации :: Видеоблог :: Твиттер
Radar systems engineer & Software developer of industrial automation
raxp вне форума Ответить с цитированием
Старый 05.11.2009, 23:43   #3
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

а не думали воспользоваться чем-нибудь готовым?
например,
NetBlockPRO
или
LANState ?
Serge_Bliznykov вне форума Ответить с цитированием
Старый 06.11.2009, 00:25   #4
zdovim
Новичок
Джуниор
 
Регистрация: 05.11.2009
Сообщений: 9
Вопрос

raxp, Serge_Bliznykov, благодарю за ответы.

Поясню ситуацию.
Заказчик хочет видеть ListView с такими столбцами:
  1. Дата/время
  2. Событие {создание, изменение, переименование, удаление}
  3. Путь к файлу/папке
  4. Автор изменения (в формате username@computername)
Перечисленные Вами (Serge_Bliznykov) программы по сути повторяют функциональность KillWatcher'a (в данный момент мой заказчик работает с ним + моя недоработанная программа).
/* Они (программы) не позволят определить, например, удаление целой папки с вложенными в нее файлами. Также я не смогу определить изменение файла. */

У меня несколько другой подход, нежели в вышеперечисленных приложениях.
1. Перехватывается событие от ReadDirectoryChangesW (имеется тип события и путь к файлу/папке).
2. Теперь по пришествии этого события я собираю инфу от NetFileEnum и NetSessionEnum, комбинирую их, и получаю имя юзера и имя компа, которые инициировали событие (1).
3. Дальше вывожу данные в формате, который я указал.

Но как верно заметил raxp, я не могу 100%-но определить инициатора. Поэтому я ввел следующую структуру для события:
Код:
class Event {
    EventType type;
    std::string path; // full path
    std::vector< Initiator > mostLikelyInitiators;
    std::vector< Initiator > possiblyInitiators;
};
,
где Event::mostLikelyInitiators - наиболее вероятные инициаторы, а Event:ossiblyInitiators - возможные инициаторы.
На (2) этапе вышеперечисленного плана я нехитрым образом заполняю эти списки.

Так оставить конечно можно, но было бы интересно узнать, возможно ли более надежное определение инициатора?
/* Кстати приложений, решающих данную проблему, я не видел нигде, хотя искал очень тщательно. */
zdovim вне форума Ответить с цитированием
Старый 06.11.2009, 09:12   #5
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Я лично уже около года мониторю изменения файлов на серванте, и никаких проблем даже с удаленными файлами не наблюдаю.
А помогает определить владельца файл мне вот такая функа:
Код:
//**************************************************************************
function GetFileOwner(FileName: string):fileid;
var
  SecDescr: PSecurityDescriptor;
  SizeNeeded, SizeNeeded2: DWORD;
  OwnerSID: PSID;
  OwnerDefault: longbool;
  OwnerName, DomainName: PChar;
  OwnerType: SID_NAME_USE;
begin
  //GetFileOwner := False;
  GetMem(SecDescr, 1024);
  GetMem(OwnerSID, SizeOf(PSID));
  GetMem(OwnerName, 1024);
  GetMem(DomainName, 1024);
  try  
    if not GetFileSecurity(PChar(FileName),
      OWNER_SECURITY_INFORMATION,  
      SecDescr, 1024, SizeNeeded) then  
      Exit;
    if not GetSecurityDescriptorOwner(SecDescr,  
      OwnerSID, OwnerDefault) then
      Exit;
    SizeNeeded  := 1024;  
    SizeNeeded2 := 1024;  
    if not LookupAccountSID(nil, OwnerSID, OwnerName,
      SizeNeeded, DomainName, SizeNeeded2, OwnerType) then  
      Exit;
    result.domain_Owner  := DomainName;
    result.user_Owner := OwnerName;
  finally
    FreeMem(SecDescr);
    FreeMem(OwnerName);
    FreeMem(DomainName);
  end;
  //GetFileOwner := True;
end;
//**************************************************************************
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 08.11.2009, 15:48   #6
zdovim
Новичок
Джуниор
 
Регистрация: 05.11.2009
Сообщений: 9
Стрелка

Пришел к выводу, что надо заниматься сниффингом smb-протокола с помощью WinPCap.
zdovim вне форума Ответить с цитированием
Старый 08.12.2010, 12:54   #7
Verg
Новичок
Джуниор
 
Регистрация: 19.02.2009
Сообщений: 1
Хорошо

Stilet Вот это тема то что надо как раз
Verg вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц