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

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Именованные объекты синхронизации в DllMain DLL_ATTACH_PROCESS  (Прочитано 8097 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Tomek
Гость
« : 06-05-2005 08:49 » 

В общем, написал LSP DLL-ку. Если кто не знает, это сервис-провайдер; все приложения, которые вызывают функции WinSock API загружают эту DLL-ку, вызывают соответствующие функции winsock, переопределенные в этой библиотеке. Эти функции выполнят скажем фильтрацию потоков данных передающихся через сокеты, и передают управление нижележащим провайдерам и так далее. И у меня есть программа написана с использованием...ну скажем MFC, в которой я вообще хочу видеть все что записано в файл log.txt.


Мне необходимо вести лог всех подключений. Что я делаю. В функции DllMain я делаю вот что :

Код:
switch (dwReason)
    {
        case DLL_PROCESS_ATTACH:
            HDllInstance = hinstDll;
            InitializeCriticalSection(&gCriticalSection);
            InitOverlappedCS();           
            hLog=CreateFile(_T("c:\\log.txt"),GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_ALWAYS,0,NULL);
            if (hLog==INVALID_HANDLE_VALUE){
               MessageBox(NULL,_T("Error creating log file !"),_T("lsp.dll"),MB_OK);
               return FALSE;
            }
            SetFilePointer(hLog,0,NULL,FILE_END);
            WriteMess("Lsp.dll loaded",NULL);
            hMutex=CreateMutex(NULL,false,"MyMutex");
            if (hMutex==NULL){
               MessageBox(NULL,_T("Error creating mutex object !"),_T("Error"),MB_OK);
               return FALSE;
            }
                  hCallEvent=CreateEvent(NULL,false,false,_T("CallEvent"));
            if (hCallEvent==NULL) {
              WriteMess("Error in creating event!",NULL);
            }
            break;

        case DLL_THREAD_ATTACH:
            break;

        case DLL_THREAD_DETACH:
            break;

        case DLL_PROCESS_DETACH:
            WriteMess("Lsp.dll unloaded",NULL);
            CloseHandle(hLog);

            CloseHandle(hMutex);
            break;
    }

    return TRUE;

Показываю для ясности функцию WriteMess :

Код:

void WriteMess(char *szText,struct sockaddr *addr){     
  TLog sl;    // кое-какая структура для записи в файл
  if (addr!=NULL){
    struct sockaddr_in *addr_in=(struct sockaddr_in*)addr;
    sl.ip=addr_in->sin_addr.s_addr;
    sl.port=ntohs(addr_in->sin_port); 
  }
  else{
    sl.ip=0;
    sl.port=0; 
  }
  if (szText!=NULL)
      strcpy(sl.szMessage,szText);
 
  GetLocalTime(&sl.t);
  TCHAR szBuffer[MAX_PATH];
  GetExeName(szBuffer);   // эта функция возвращает имя модуля, который загрузил эту DLL
  sprintf(sl.szExe,"%S",szBuffer);
  DWORD size=sizeof(sl); 
  DWORD nWritten;
 
  DWORD res=WaitForSingleObject(hMutex,INFINITE);// для эксклюзивного доступа к файлу лога
  if (res==WAIT_OBJECT_0 || res==WAIT_ABANDONED){
    WriteFile(hLog,&sl,size,&nWritten,NULL);
    FlushFileBuffers(hLog);
    ReleaseMutex(hMutex);
  }
 
}


Я ранее создавал событие в этой же DllMain и тогда после записи в файл лога определенной инфы, устанавливал это событие в сигнальное состояние. В программе, которая показывает лог был запущен поток, в котором делалось вот что :



Код:
DWORD WINAPI fnEventFunc(LPVOID pParam){
   DWORD res; 
   Reset=FALSE;
   while (!Reset){
     res=WaitForSingleObject(hEventCall,TIME_OUT);
     if (res==WAIT_OBJECT_0)
              FillLog(NULL);                 // здесь заполняется список из файла log.txt
   }   
   return 0;
}

И вот ребята, уважаемые коллеги, эти то ли события, то ли мьютексы (ИМЕНОВАННЫЕ!) просто напросто не хотят создаваться. Кажется первый мьютекс создается, а остальные не хотят ни в самой DllMain ни в моей этой программе которая показывает лог. По ошибке я определил, что ОТКАЗАНО В ДОСТУПЕ. Что получается ? Что если нельзя создавать несколько именованных объектов синхронизации ? И самое интересное, что я это все тестировал на иных программах, не LSP. Там эта техника работает без проблем. Может быть проблема в том что много этих мьютексов создается, что ли ? Но я пытался вести запись в файл с помощью LockFileEx , какие глюки начались вообще не записывалось ничего.

Кто с этим сталкивался, помогите пожалуйста, не знаю просто что делать.
Записан
npak
Команда клуба

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

« Ответ #1 : 06-05-2005 09:28 » 

Ты создаёшь мутекс с правом доступа по-умолчанию (первый аргумент == NULL), то есть доступ к мутексу имеют только процессы, запущенные под темже пользователем.  Я подозреваю, что первый мутекс создаётся в процессе одного пользователя, а другие процессы могут принадлежать другим пользователям.

Сделай при создании мутекса ненулевые Security Attributes с разрешением всем пользоваться мутексом.
Записан

UniTesK -- индустриальная технология надежного тестирования.

http://www.unitesk.com/ru/
Tomek
Гость
« Ответ #2 : 06-05-2005 09:30 » 

Ага.... Спасибо ! Только можно кусочек кода заполения SECURITY_ATTRIBUTES ?
Записан
npak
Команда клуба

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

« Ответ #3 : 06-05-2005 09:48 » new

Вот коротенький пример:
Код:
#include <windows.h>
#include <stdio.h>

int main(int argc, char ** argv)
{
HANDLE hMutex = INVALID_HANDLE_VALUE;
SECURITY_ATTRIBUTES sa;

sa.nLength = sizeof(sa);
sa.bInheritHandle = FALSE;
sa.lpSecurityDescriptor = malloc(sizeof(SECURITY_DESCRIPTOR));
if (sa.lpSecurityDescriptor == NULL
|| !InitializeSecurityDescriptor(sa.lpSecurityDescriptor, SECURITY_DESCRIPTOR_REVISION))
{
printf("Failed to initialise security descriptor, error code %u\n", GetLastError());
return 1;
}
if (!SetSecurityDescriptorDacl(sa.lpSecurityDescriptor,
TRUE, // Мы хотим установить параметры доступа
NULL, // NULL означает, что доступно для всех
FALSE // FALSE означает, что это не дефолтное значение
))
{
printf("Failed to set NULL ACL, error code %u\n", GetLastError());
return 1;
}
hMutex = CreateMutex(&sa, FALSE, "MyMutex");
if (hMutex == INVALID_HANDLE_VALUE)
{
printf("Failed to create mutex, error code %u\n", GetLastError());
return 1;
}
CloseHandle(hMutex);
printf("Total Success!\n");
return 0;
}
Записан

UniTesK -- индустриальная технология надежного тестирования.

http://www.unitesk.com/ru/
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines