Модераторы: feodorv, GremlinProg, xvr, Fixin

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Проблема с записью файлов 
V
    Опции темы
Mark4545
Дата 21.7.2007, 17:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 111
Регистрация: 6.11.2006

Репутация: нет
Всего: нет



Код keyboard proc хука WH_KEYBOARD
Код

LRESULT CALLBACK KeyProc(int nCode,WPARAM wParam,LPARAM lParam)
{
    if((nCode>=0)&&(lParam & 0x40000000))
    {
        ushort Symbol=ToKey(wParam);// это моя функция преобразую в ascii
        DWORD nofbw,xy;
        OVERLAPPED ovl;
        char buff[2]={0,0};
        buff[0]=Symbol;
        bool wf=WriteFile(hFile,buff,strlen(buff),&nofbw,&ovl);
        bool  res=GetOverlappedResult(hFile,&ovl,&xy,true);
        if(wf==true)
        {
            MessageBox(0,"ok","ok",0);
        }
        else
        {
            char a[100];
            sprintf(a,"%d",GetLastError());
            MessageBox(0,"failed",a,0);
        }
        CloseHandle(hFile);
        return true;
    }
    if(nCode<0)
    {
        return CallNextHookEx(Hook,nCode,wParam,lParam);
    }
    
}

не записывает в файл почему я не смогу понять, надесюь на вашу помошь.
Результат гет ласт еррор 6 ( ERROR_INVALID_HANDLE) почему он инвалид не понятно.
Заранее спс
Да и забыл креате файл происходит в длл процесс аттач 
вот так
Код

hFile=CreateFile("lol4.txt",GENERIC_READ|GENERIC_WRITE,
                        FILE_SHARE_WRITE|FILE_SHARE_READ,NULL,
                        OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);


Добавлено через 5 минут и 41 секунду
HANDLE HFile обьявлен глобальной переменой

Это сообщение отредактировал(а) Mark4545 - 21.7.2007, 17:41
PM MAIL   Вверх
586
Дата 21.7.2007, 19:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2243
Регистрация: 8.5.2006

Репутация: 39
Всего: 146



Цитата(Mark4545 @  21.7.2007,  18:36 Найти цитируемый пост)
Результат гет ласт еррор 6 ( ERROR_INVALID_HANDLE) почему он инвалид не понятно.

При инициализации хука создаешь файл CreateFile, и хендл и PID твоего приложения расшариваешь. При инициализации DLL в DLL_PROCESS_ATTACH дублируешь хендл функцией DuplicateHandle и пользуешься им.
Цитата(Mark4545 @  21.7.2007,  18:36 Найти цитируемый пост)
HANDLE HFile обьявлен глобальной переменой

В другом прицессе он не действителен. Его надо дублировать.
Будет время напишу...
PM   Вверх
Mark4545
Дата 21.7.2007, 19:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 111
Регистрация: 6.11.2006

Репутация: нет
Всего: нет



Такое ощушение тока 586 смотрит форум и отвечатет). Пока мало понятно но буду ждать полного ответа.
PM MAIL   Вверх
586
Дата 21.7.2007, 23:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2243
Регистрация: 8.5.2006

Репутация: 39
Всего: 146



Код
#include <windows.h>
#include <stdio.h>

#pragma data_seg(".SData")
DWORD dwHostProcessId=0;
HANDLE hHostFile=INVALID_HANDLE_VALUE;
#pragma data_seg()
#pragma comment(linker,"/SECTION:.SData,RWS")

// DO NOT SHARE!
HINSTANCE hInst;
HHOOK hook=NULL;
HANDLE hFile=INVALID_HANDLE_VALUE;
//

void WriteLog(char *msg)
{
    SYSTEMTIME st;
    DWORD dwWritten;
    char b[520];
    char modName[260];

    GetLocalTime(&st);
    GetModuleFileName(NULL, modName, 260);
    sprintf(b, "%d:%.2d:%.2d  [%s (%d)]  %s\r\n",
        st.wHour, st.wMinute, st.wSecond,  modName, GetCurrentProcessId(), msg);
    WriteFile(hFile, b, lstrlen(b), &dwWritten, 0);
}

UINT ShowErrDscr(HWND hWnd, char *title, UINT style)
{
    UINT res;
    char *b;
    FormatMessage(0x1100, 0, GetLastError(), 0, (char*)&b, 0, 0);
    res=MessageBoxA(hWnd, b, title, style);
    LocalFree((HLOCAL)b);
    return res;
}

bool InitHandles()
{
    HANDLE hHostProcess=OpenProcess(PROCESS_DUP_HANDLE, TRUE, dwHostProcessId);
    //DEBUG
    if(!hHostProcess)
    {
        ShowErrDscr(NULL, "Can't open process", 16);
        return false;
    }
    BOOL bDup=DuplicateHandle(hHostProcess, hHostFile, GetCurrentProcess(), &hFile, NULL, TRUE,  DUPLICATE_SAME_ACCESS);
    CloseHandle(hHostProcess);

    //DEBUG
    if(!bDup)
    {
        ShowErrDscr(NULL, "Can't dup handle", 16);
        return false;
    }

    WriteLog("Attach");
    return true;
}

BOOL APIENTRY DllMain(HINSTANCE hModule,DWORD reason,LPVOID reserved)
{
    switch(reason)
    {
    case DLL_PROCESS_ATTACH:
        hInst=hModule;
        if(hHostFile==INVALID_HANDLE_VALUE)
        {
            dwHostProcessId=GetCurrentProcessId();
        }
        else
        {
            return InitHandles();
        }

        break;

    case DLL_PROCESS_DETACH:
     WriteLog("DLL_PROCESS_DETACH");
     if(hook)
     {
            WriteLog("UnhookWindowsHookEx");
         if(!UnhookWindowsHookEx(hook))
           WriteLog("WARNING: UnhookWindowsHookEx return FALSE");
        }
     CloseHandle(hFile);
     break;
    }

    return true;
}

LRESULT CALLBACK KeyboardMsgProc(int nCode,WPARAM wParam,LPARAM lParam)
{
    if(nCode<0) return CallNextHookEx(hook,nCode,wParam,lParam);
    if(!(lParam & 0x40000000))
    {
        //BYTE c=(LOBYTE(wParam));
        WriteLog("[HOOK] KeyDown");

    }

    return 0;
}

extern "C" __declspec(dllexport) bool SetHook()
{
    hFile=hHostFile=CreateFile("C:\\test.txt",
                                GENERIC_WRITE,
                                3, 0, CREATE_ALWAYS,
                                FILE_ATTRIBUTE_NORMAL, 0);
    if(hHostFile==INVALID_HANDLE_VALUE)
    {
        ShowErrDscr(NULL, "Can't create output file", 16);
        return false;
    }

    hook=SetWindowsHookEx(WH_KEYBOARD,KeyboardMsgProc,hInst,0);
    if(!hook)
    {
     ShowErrDscr(NULL, "Can't set hook", 16);
     CloseHandle(hFile);
     hHostFile=INVALID_HANDLE_VALUE;
     return false;
    }

    WriteLog("Hook is initialized!");

    return true;
}

Заметил, что после отмены хука dll'шки из процессов, окна которых свёрнуты, выгружаются не сразу. Если переключиться на это приложение, dll'шка выгружается. Так должно быть, или у меня ошибка к коде?

Это сообщение отредактировал(а) 586 - 19.11.2007, 18:42
PM   Вверх
Mark4545
Дата 21.7.2007, 23:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 111
Регистрация: 6.11.2006

Репутация: нет
Всего: нет



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

LRESULT CALLBACK keyproc(int nCode,WPARAM wParam,LPARAM lParam)
{
   
    if((nCode>=0)&&(lParam & 0x40000000))
    {
     if((wParam!=0x08)&&(wParam!=0x09)&&(wParam!=0x0D)&&
        (wParam!=0x10)&&(wParam!=0x11)&&(wParam!=0x12)&&
        (wParam!=0x1B)&&(wParam!=0x20))
         {
                    unsigned short int Symbol=GetSymbolFromVK(wParam);
           FILE *fp=fopen("lol.txt","a+");
                           fputc(Symbol,fp); 
                           fclose(fp);
         } 
         fclose(fp);  
         return true;
    }
    else
    {
        return CallNextHookEx(hook,nCode,wParam,lParam);
    }

При переключении из одного окна в другое в лог переставало писать .
При использовании простого мессадж бокса при переключении перехватывает клавиши нормально.
PM MAIL   Вверх
Mark4545
Дата 23.7.2007, 12:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 111
Регистрация: 6.11.2006

Репутация: нет
Всего: нет



так что никто не знает в чем проблема.
PM MAIL   Вверх
Mark4545
Дата 23.7.2007, 15:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 111
Регистрация: 6.11.2006

Репутация: нет
Всего: нет



спс 2  586  о5 помог. Сурс пашет щас буду разбирать подробно.) Возможно еще вопросы появяться)
PM MAIL   Вверх
586
Дата 23.7.2007, 16:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2243
Регистрация: 8.5.2006

Репутация: 39
Всего: 146



Код
#include <windows.h>
#include <stdio.h>

// DO NOT SHARE!
HINSTANCE hInst;
HHOOK hook=NULL;
//

UINT ShowErrDscr(HWND hWnd, char *title, UINT style)
{
    UINT res;
    char *b;
    FormatMessage(0x1100, 0, GetLastError(), 0, (char*)&b, 0, 0);
    res=MessageBoxA(hWnd, b, title, style);
    LocalFree((HLOCAL)b);
    return res;
}

BOOL APIENTRY DllMain(HINSTANCE hModule,DWORD reason,LPVOID reserved)
{
    switch(reason)
    {
    case DLL_PROCESS_ATTACH:
        hInst=hModule;
        break;

    case DLL_PROCESS_DETACH:
     if(hook)
     {
         UnhookWindowsHookEx(hook);
        }
     break;
    }

    return true;
}

static char s[2]={0, 0};

LRESULT CALLBACK KeyboardMsgProc(int nCode,WPARAM wParam,LPARAM lParam)
{
    if(nCode<0) return CallNextHookEx(hook,nCode,wParam,lParam);
    if(!(lParam & 0x40000000))
    {
        s[0]=wParam;
        FILE *f=fopen("C:\\test.log", "a+");
        fprintf(f, "KEY DOWN  (%d) %s\r\n", GetCurrentProcessId(), s);
        fclose(f);

    }

    return 0;
}

extern "C" __declspec(dllexport) bool SetHook()
{
    hook=SetWindowsHookEx(WH_KEYBOARD,KeyboardMsgProc,hInst,0);
    if(!hook)
    {
     ShowErrDscr(NULL, "Can't set hook", 16);
     return false;
    }
    return true;
}

PM   Вверх
Mark4545
Дата 23.7.2007, 18:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 111
Регистрация: 6.11.2006

Репутация: нет
Всего: нет



еще один сенкс то 586.Разбираю щас первый вариант кода, но никак не  могу понять зачем же дублировать хэндлы?. Какнить попроще если не трудно обьясните.


PM MAIL   Вверх
586
Дата 23.7.2007, 19:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2243
Регистрация: 8.5.2006

Репутация: 39
Всего: 146



Цитата(Mark4545 @  23.7.2007,  19:02 Найти цитируемый пост)
но никак не  могу понять зачем же дублировать хэндлы

Потому что в других процессах они не действительны.
Цитата(Mark4545 @  21.7.2007,  18:36 Найти цитируемый пост)
Результат гет ласт еррор 6 ( ERROR_INVALID_HANDLE)

Правда, если у процесса в который внедрен хук мало привелегий, он не сможет дублировать хендл.
Можно использовать второй пример, т.е. открывать и закрывать файл каждый раз после нажатия клавиши. На производительность это повлияет. Но второй пример надежнее и легче реализовывается.
PM   Вверх
Mark4545
Дата 23.7.2007, 19:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 111
Регистрация: 6.11.2006

Репутация: нет
Всего: нет



это я заметил что второй код полегче.
Ну значит основываясь на втором коде 586 начал писать библиотеку 
Написал:
Код

#include "export.h"
HINSTANCE hInst;
HHOOK Hook;
LRESULT CALLBACK keyproc(int nCode,WPARAM wParam,LPARAM lParam);
bool DllMain(HANDLE hModule,DWORD reason,LPVOID lPvoid)
{
    if(reason==DLL_PROCESS_ATTACH)
    {
       hInst=(HINSTANCE)hModule;
    }
    if(reason==DLL_PROCESS_DETACH)
    {
         UnhookWindowsHookEx(Hook);
    }
    return true;
}

export  bool SetHook()
{
    Hook=SetWindowsHookEx(WH_KEYBOARD,keyproc,hInst,0);
    if(Hook==NULL)
    {
        return false;
    }
    else
    {
        return true;
    }
}
char s[2]={0,0};
LRESULT CALLBACK keyproc(int nCode,WPARAM wParam,LPARAM lParam)
{
    if((nCode>=0)&&(lParam & 0x40000000))
    {
        s[0]=wParam;
        FILE *file=fopen("test.txt", "a+");
        fprintf(file, "KEY DOWN  (%d) %s\r\n", GetCurrentProcessId(), s);
        fclose(file);
        return 0;
    }
    return CallNextHookEx(Hook,nCode,wParam,lParam);
}

Мистика не работает( при том что код 586 работает отлично)
В чем проблема  скока думал так и не нашел.Вроде фактически почти тоже самое.
И вопрос  №2
Конечно если я не надоел.
В моем понимании Dll при глобальном хуке грузиться ко всем процессам, и каждая копия принадлежит к тому процесу к которому подгружена.
Меня интересует поведение переменых которые находяться в Shared секции Dll.
(и если у кого есть линк на подробные описания и работы с Shared секцией Dll пока сам искал подробных документов с маленькими примерчиками не попадались)
Спс за внимание.
PM MAIL   Вверх
586
Дата 23.7.2007, 20:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2243
Регистрация: 8.5.2006

Репутация: 39
Всего: 146



Цитата(Mark4545 @  23.7.2007,  20:48 Найти цитируемый пост)
FILE *file=fopen("test.txt", "a+");

Пиши полный путь!!! Рабочие папки у процессов разные.
PM   Вверх
Mark4545
Дата 23.7.2007, 20:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 111
Регистрация: 6.11.2006

Репутация: нет
Всего: нет



Да уж понял ошибку.
А как насчет 2го вопроса.
PM MAIL   Вверх
586
Дата 23.7.2007, 22:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2243
Регистрация: 8.5.2006

Репутация: 39
Всего: 146



поиск по словам "shared memory" или "shared section rws"
http://www.wasm.ru/article.php?article=1005015 (читай после "Несколько комментариев от assembler.ru")
PM   Вверх
Mark4545
Дата 23.7.2007, 22:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 111
Регистрация: 6.11.2006

Репутация: нет
Всего: нет



Ассемблер мне тут не сильно поможет нужна дока на С каянить.
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.0971 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.