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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Не могу получить снимок модулей процесса, Снимок модулей tlhelp32-функцией 
V
    Опции темы
Atra
Дата 20.2.2014, 16:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



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

Вот часть моего кода, отсутствует дочернее окно и запись в него списка модулей, т.к. сам снимок модулей не могу получить. Программу пишу в vs 2010 на c++ winapi:
Код

#include <Windows.h>
#include <TlHelp32.h>
#include <commctrl.h>
#include <stdio.h>
#include <wchar.h>

HWND MyLIST;
LVITEM LvItem;
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
ATOM RegMyWindowClass (HINSTANCE, LPCTSTR);

#define ID_MYLISTBOX 1


BOOL GetProcessList ();
BOOL ListProcessModules (HWND hWnd, DWORD PrID);

int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR lpCmdLine,
                     int nCmdShow)
{
    //имя будущего класса
    LPCTSTR lpzClass = TEXT("FormMy");

    //регистрация класса
    if (!RegMyWindowClass(hInstance, lpzClass))
        return 1;

    //вычисление координат центра экрана
    RECT screen_rect;
    GetWindowRect(GetDesktopWindow(), &screen_rect);//разрешение экрана
    int x = screen_rect.right / 2;
    int y = screen_rect.left / 2;

    //создание диалогового окна
    HWND hWnd = CreateWindow(lpzClass, TEXT("Process Manager"),
        WS_OVERLAPPEDWINDOW | WS_VISIBLE, x, y, 500, 350, NULL, NULL, hInstance, NULL);
    
    //если окно не создано описатель будет равен 0
    if (!hWnd) return 2;

    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);

    //цикл сообщений приложения
    MSG msg = {0};//структура сообщения
    int iGetOk = 0;//переменная состояния
    while ((iGetOk = GetMessage(&msg, NULL, 0,0)) != 0) //цикл сообщений
    {
        if (iGetOk == -1) return 3;//если GetMassage вернул ошибку - выход
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return msg.wParam;//возвращаем код завершения программы

}

//функция регистрации класса окон
ATOM RegMyWindowClass(HINSTANCE hInst, LPCTSTR lpzClassName)
{
    WNDCLASS wcWindowClass = {0};
    //адрес функции обработки сообщений
    wcWindowClass.lpfnWndProc = (WNDPROC)WndProc;
    //стиль окна
    wcWindowClass.style = CS_HREDRAW|CS_VREDRAW;
    //дескриптор экземпляра приложения
    wcWindowClass.hInstance = hInst;
    //название класса
    wcWindowClass.lpszClassName = lpzClassName;
    //загрузка курсора
    wcWindowClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    //загрузка цвета окон
    wcWindowClass.hbrBackground = (HBRUSH)COLOR_APPWORKSPACE;
    return RegisterClass(&wcWindowClass);
    //регистрация класса
}

BOOL GetProcessList(HWND hWnd)
{
    HANDLE hProcessSnap;
    PROCESSENTRY32 PE32;
    int i, k;
    //Делаем снимок процессов
    hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    
    if (hProcessSnap == INVALID_HANDLE_VALUE)
    {
        MessageBox(hWnd, TEXT("CreateToothetp32Snapeshot (of processes)"), TEXT("Ошибка"), MB_OK);
        return (FALSE);
    }

    
    PE32.dwSize = sizeof(PROCESSENTRY32);
    
    if (!Process32First (hProcessSnap, &PE32))
    {
        MessageBox(hWnd, TEXT("Process32First"), TEXT("Ошибка"), MB_OK);
        CloseHandle(hProcessSnap);
        return (FALSE);
    }
        i = 1;
    k = 0;
    memset(&LvItem,0,sizeof(LvItem));
    LvItem.mask=LVIF_TEXT;
    do
    {
            TCHAR s[100];
            wsprintf(s, TEXT("%lu"), PE32.th32ProcessID);
                
            LvItem.iItem = i;
            LvItem.iSubItem = 0; 
            LvItem.pszText = PE32.szExeFile; 
            SendMessage(MyLIST, LVM_INSERTITEM, 0, (LPARAM)&LvItem);
            i = i+1;

                    LvItem.iItem = k; 
                    LvItem.iSubItem = 1; 
                    LvItem.pszText = s; 
                    SendMessage(MyLIST, LVM_SETITEM, 0, (LPARAM)&LvItem);
                    k = k+1;
    }
    while(Process32Next(hProcessSnap, &PE32));

    CloseHandle(hProcessSnap);
    return(TRUE);
}

BOOL ListProcessModules(HWND hWnd, DWORD PrID)
{
    
    HANDLE hModulesSnap = INVALID_HANDLE_VALUE;
    MODULEENTRY32 MO32;
    
    hModulesSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, PrID);
       
//вот здесь возникает ошибка, в сообщении вылетает по сути PE32.th32ProcessID
//как проверка, что функция его получала
//почему она не срабатывает понять не могу

    if (hModulesSnap == INVALID_HANDLE_VALUE)
        {
            TCHAR id[100];
            wsprintf(id, TEXT("%d"), PrID);

            MessageBox(hWnd, id, TEXT("Ошибка"), MB_OK);
            return (FALSE);
        }
    
    
    MO32.dwSize = sizeof(MODULEENTRY32);
    
    if (!Module32First(hModulesSnap, &MO32))
    {
        MessageBox(hWnd, TEXT("Module32First"), TEXT("Ошибка"), MB_OK);
        CloseHandle(hModulesSnap);
        
        return (FALSE);
    }
    
    do
    {
        //здесь код записи имен модулей
    }
    while(Module32Next(hModulesSnap, &MO32));
    
    
    CloseHandle(hModulesSnap);
    
    return(TRUE);
}

//функция создания колонок в ListView
void AddColumnToListView(TCHAR p[100], int subitem)
{
LVCOLUMN lvc;
lvc.mask=LVCF_FMT|LVCF_WIDTH|LVCF_TEXT|LVCF_SUBITEM;

lvc.iSubItem = subitem;
lvc.pszText     = p;
lvc.cx     = 220;
lvc.fmt     = LVCFMT_LEFT;

ListView_InsertColumn(MyLIST, subitem, &lvc);
}

//функция обработки сообщений
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{    
    DWORD PrID;
    int nSelectedItem;
    
    //выборка и обработка сообщений
    switch (message)
    {
    case WM_CLOSE:
        {
          PostQuitMessage(0);
          EndDialog(hWnd,0); // kill dialog
        }
        break;

    case WM_CREATE:
        
        MyLIST = CreateWindow(WC_LISTVIEW, L" ", WS_CHILD|WS_CLIPCHILDREN|WS_VISIBLE|LVS_REPORT, 10, 10, 460, 200, hWnd, NULL, NULL, NULL);
        SendMessage(MyLIST,LVM_SETEXTENDEDLISTVIEWSTYLE,0,LVS_EX_FULLROWSELECT);
        LV_COLUMN lvc;
        lvc.mask = LVCF_FMT|LVCF_WIDTH|LVCF_TEXT|LVCF_SUBITEM;
        lvc.fmt = LVCFMT_LEFT;
        lvc.cx = 230;
        
        AddColumnToListView(TEXT("Process"),0);
        AddColumnToListView(TEXT("ProcessID"),1);

        GetProcessList(hWnd);
        CreateWindow(TEXT("button"), TEXT("Подробнее..."), WS_CHILD|BS_PUSHBUTTON|WS_VISIBLE,10,250,100,30,hWnd,(HMENU)ID_MYBUTTON,NULL,NULL);
        break;
case WM_COMMAND:
        //реакция на сообщение
//получение ID процесса и передача его функции 
        if ((HIWORD(wParam)==0) && (LOWORD(wParam)==ID_MYLISTBOX))
            nSelectedItem = ListView_GetNextItem(MyLIST, -1, LVNI_ALL|LVNI_SELECTED);
                    if (nSelectedItem >= 0)
                    {
                        TCHAR szText[100] = TEXT("");
                        int nSubItem = 1;
                        ListView_GetItemText(MyLIST, nSelectedItem, nSubItem, szText, 100);
                        PrID = _wtoi(szText);
                        ListProcessModules(hWnd, PrID);
                    }
                    else
                    {
                        MessageBox(hWnd, TEXT("строка не выделена"), TEXT("Ошибка"), MB_OK);
                    }
        break;
case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        //все сообщения не обработанные обрабатывает винда
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}



Это сообщение отредактировал(а) Atra - 20.2.2014, 16:37
PM MAIL   Вверх
Dem_max
Дата 20.2.2014, 19:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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





--------------------
Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte")
PM MAIL   Вверх
Atra
Дата 21.2.2014, 22:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Спасибо, но этот пример я юзала...на его основе создавала код, где делался снимок всех процессов, перебирались в цикле до тех пор пока не совпадали ид процесса искомого с идом процесса из структуры, и запускалась функция создания снимка модулей, которой конкретно передавалось значение ида из структуры - pe32. ...
Приложение также выдавало ошибку - переменная, куда должен записаться снимок модулей, оставалась пустой. Почему не срабатывает с модулями, но срабатывает с процессами для меня загадка... я также пробовала давать программе права отладчика, не помогает...
Есть ли еще варианты? 
PM MAIL   Вверх
feodorv
Дата 22.2.2014, 18:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

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



Цитата(Atra @  21.2.2014,  23:25 Найти цитируемый пост)
Приложение также выдавало ошибку 

Какой вызов даёт ошибку? Какая у Вас операционка, какая разрядность, какая разрядность процесса, для которого Вы смотрите список модулей?


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
Atra
Дата 23.2.2014, 15:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Возможно я не совсем правильно выразилась...

При работе программы, прохожу проверку:
Код

hModulesSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, PrID);
       
   if (hModulesSnap == INVALID_HANDLE_VALUE)
        {
            TCHAR id[100];
            wsprintf(id, TEXT("%d"), PrID);
            MessageBox(hWnd, id, TEXT("Ошибка"), MB_OK);
            return (FALSE);
        }



hModulesSnap у меня  INVALID_HANDLE_VALUE!!! Получается, что функция CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, PrID) не создает снимка модулей...

Я уже попыталась прикрутить EnumProcessModules, но не совсем понимаю ее работу... Делала по примеру для получения имени первого модуля с полным путем ( имени самого процесса, на сколько я поняла), что-то получила... Это что-то вывела MessageBox, но все это было пустыми квадратами... Но ведь работает, получает первый модуль. 
Тогда, что не так с CreateToolhelp32Snapshot??? Ведь снимки процессов делает...

У меня семерка, все 32 разрядное...
PM MAIL   Вверх
GremlinProg
Дата 23.2.2014, 16:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

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



Цитата(Atra @  23.2.2014,  17:15 Найти цитируемый пост)
hModulesSnap у меня  INVALID_HANDLE_VALUE!!

Цитата(CreateToolhelp32Snapshot @  MSDN)

To retrieve an extended error status code generated by this function, use the GetLastError function.



--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
Atra
Дата 23.2.2014, 20:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



GremlinProg, спасибо

CreateToolhelp32Snapshot failed with error 5: отказано в доступе

Что делать?


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


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

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



Цитата(Atra @  23.2.2014,  22:11 Найти цитируемый пост)
CreateToolhelp32Snapshot failed with error 5: отказано в доступе
Что делать?

Насколько я знаю, не все процессы можно так "фотографировать". Думаю, те, к которым доступ запрещен, стоит просто пропустить, либо выдать пользователю соответствующее сообщение.


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
Atra
Дата 3.3.2014, 14:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Может кому пригодиться... Решила проблемку:

1. Запустить программу под правами админа
2. Сделать привилегию отладчика

Нарыла такой код функции привилегии, запускаем с параметром true - получаем привилегию.
Код

void EnableDebugPrivilege(bool fEnable)
{
    HANDLE hToken;
    
    if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken))
    {
        TOKEN_PRIVILEGES tp;
        tp.PrivilegeCount = 1;
        LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid);
        tp.Privileges[0].Attributes = fEnable ? SE_PRIVILEGE_ENABLED : 0;
        AdjustTokenPrivileges(hToken, false, &tp, sizeof(tp), NULL, NULL);
        CloseHandle(hToken);
    }
}


И еще, вместо CreateToolhelp32Snapshot для просмотра модулей процесса я использовала EnumProcessModules и OpenProcess с параметром PROCESS_ALL_ACCESS

Код

BOOL GetProcessListModule(HWND hWnd, DWORD PrID)
{
    
    HANDLE h,hp;
    PROCESSENTRY32 PE32;
            
    TCHAR name[MAX_PATH];
    DWORD dw;
    HMODULE hmod[1024];
    int i, k;
    
    EnableDebugPrivilege(true);
        
        //поиск нужного процесса

    h = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
    if (h == INVALID_HANDLE_VALUE)
    {
        MessageBox(hWnd, TEXT("CreateToothetp32Snapeshot (of processes)"), TEXT("Ошибка"), MB_OK);
        return (FALSE);
    }
    
    PE32.dwSize = sizeof(PROCESSENTRY32);

    if (!Process32First (h, &PE32))
    {
        MessageBox(hWnd, TEXT("Process32First"), TEXT("Ошибка"), MB_OK);
        CloseHandle(h);
        return (FALSE);
    }

    do
    {
        
        if(PE32.th32ProcessID == PrID)    //сравниваем ID процессов
        {
            //процесс найден

            hp = OpenProcess(PROCESS_ALL_ACCESS, false, PE32.th32ProcessID);
            
            if(EnumProcessModules(hp, hmod,sizeof(hmod),&dw))  
                k = dw/sizeof(HMODULE);
                for (i = 0; i < k; i=i+1)
                {
                    
                    if(GetModuleBaseName(hp, hmod[i], name, sizeof(name) / sizeof(TCHAR)))
                    {
                        SendDlgItemMessage(hWnd,ID_LISTDIAL1,LB_ADDSTRING,NULL,(LPARAM)name);
                        
                        //запись имен...
                    }
                }    
            
            break;      
        }
    }
    while(Process32Next(h, &PE32));

    CloseHandle(hp);
    CloseHandle(h);
    return 0;

}

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.

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


 




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


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

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