На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! user posted image
Пожалуйста, выделяйте текст программы тегом [сode=pas] ... [/сode]. Для этого используйте кнопку [code=pas] в форме ответа или комбобокс, если нужно вставить код на языке, отличном от Дельфи/Паскаля.

Соблюдайте общие правила форума

Следующие вопросы задаются очень часто, подробно разобраны в FAQ и, поэтому, будут безжалостно удаляться:
1. Преобразовать переменную типа String в тип PChar (PAnsiChar)
2. Как "свернуть" программу в трей.
3. Как "скрыться" от Ctrl + Alt + Del (заблокировать их и т.п.)
4. Как запустить программу/файл? (и дождаться ее завершения)
5. Как перехватить API-функции, поставить hook? (перехват сообщений от мыши, клавиатуры - внедрение в удаленное адресное прстранство)
... (продолжение следует) ...

Внимание:
Попытки открытия обсуждений реализации вредоносного ПО, включая различные интерпретации спам-ботов, наказывается предупреждением на 30 дней.
Повторная попытка - 60 дней. Последующие попытки - бан.
Мат в разделе - бан на три месяца...

Полезные ссылки:
user posted image MSDN Library user posted image FAQ раздела user posted image Поиск по разделу user posted image Как правильно задавать вопросы


Выразить свое отношение к модераторам раздела можно здесь: user posted image Rouse_, user posted image Krid

Модераторы: Rouse_, Krid
  
> Как узнать процесс родителя. , нужно для плагина...
    Господа вопрос такой. Есть процесс.
    Как узнать процесс родителя.
    Тоесть узнать имя процесса запустившего мою программу.

    Хотел написать плагин для Internet explorer'а, где если бы программа запускалась с параметром -d то сразу программа определяла что программу запустил Internet explorer,ан нет оказываеться нет. Там в ветви Software\Microsoft\Internet Explorer\Extensions, добавляються программы на исполнение, без дополнительных параметров, то есть не гибкий однако Internet explorer.

    Вопрос: Может есть у кого наработки на узнавание родителя процесса.

    Спросите вы, что мне лень. Да нет с TlHelp32 работал, просто чьйто наработки могут быть полезны для меня, и для других, кто дальше столкнеться с данной проблемой...

    Добавлено
    Я люблю, когда появляються задачи по программированию.. Но тут немного в невиддении насчет родителя..
      Да в плагины гораздо логичнее передавать какой-то интерфейс (не обязательно в прямом смысле слова) основного приложения, а не хаками это определять.

      Цитата SOLON7 @
      то есть не гибкий однако Internet explorer

      Да что вы говорите, с каких это пор динамические библиотеки (DLL) стали запускаться с параметрами коммандной строки?

      Добавлено
      Где в LoadLibrary вы увидели параметры коммандной строки?
        Ничего не поняла насчет "плагин для Internet explorer'а" и "не гибкости Internet explorer" :)
        Посему, попробую ответить на "Тоесть узнать имя процесса запустившего мою программу."
        Раз любишь задачки, то вот для затравки набросала ф-ию поиска ID родителя:
        (не тестировала)
        ExpandedWrap disabled
          function GetMyParentID(var ParentID: DWord): DWord;
          var
           ProcEntry: TProcessEntry32;
           hSnapshot: THandle;
           CurrID: DWord;
           _OK: Boolean;
          begin
           hSnapshot := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
           if hSnapshot <> INVALID_HANDLE_VALUE then
            try
             ProcEntry.dwSize := SizeOf(ProcEntry);
             _OK := Process32First(hSnapshot, ProcEntry);
             if _OK then
              begin
               CurrID := GetCurrentProcessId;
               SetLastError(ERROR_SUCCESS);
               while _OK do
                if ProcEntry.th32ProcessID = CurrID then
                 begin
                  ParentID := ProcEntry.th32ParentProcessID;
                  Break;
                 end
                else _OK := Process32Next(hSnapshot, ProcEntry);
              end;
             Result := GetLastError;
            finally
             CloseHandle(hSnapshot);
            end
           else Result := GetLastError;
          end;

        Ну а чуть-чуть ее видоизменить для нахождения имени родителя по его ID
        оставляю в качестве домашего задания :)

        P.S.
        Только проку от данной методики, как от козла молока.
        Процесса родителя уже может и не быть в помине, пока мы тут соизволяем его искать :)
        И полученный нами ID, можно выбрасывать на помойку.

        Гораздо лучше использовать NtQuerySystemInformation с
        параметром SystemProcessesAndThreadsInformation - можно обойтись одним "снимком".
        Правда и с CreateToolhelp32Snapshot можно, но придется запоминать ProcEntry`ы.

        P.S.S.
        >Да нет с TlHelp32 работал
        >Я люблю, когда появляються задачи по программированию..
        >Но тут немного в невиддении насчет родителя..
        Ой как "не вяжутся" эти три фразы :)
        (особенно учитывая, что в Help`е есть пример :)

        Забыла еще одну неприятную вещь:
        Может получиться так, что к моменту нашего поиска, родитель уже умрет,
        и будет создан другой процесс с такм же ID, как и у родителя.
        А вот чтобы не попасть впросак с этим, придется использовать NtQuerySystemInformation
        и сравнивать времена создания найденого нами родителя и наше.
        Сообщение отредактировано: Riply -
          Цитата Riply @
          Забыла еще одну неприятную вещь:
          Может получиться так, что к моменту нашего поиска, родитель уже умрет,
          и будет создан другой процесс с такм же ID, как и у родителя.


          Да вы что, а разве PID не растет с каждым новым запуском нового процесса, как-то не вяжется, чтобы PID был одинаков у процессов, это было по крайне мере глупо со стороны MICROSOFT делать такое.
          Процесса может быть уже убит, но чтобы pid были одинаковы не вериться...

          Добавлено
          Я нашел пожалуй самый легкий метод определения, как узнавать запущенна ли прога из интернет експлорер.

          При запуске из ИНтернет Експолера не передаеться параметр "Рабочий каталог". То есть можно проверить если рабочий каталог неравен Extractfilepath(paramstr(0)) то значит его запустил ИНтернет Експолера. Да твик не гибкий, но простой и не требующих мозломства.

          RIPLY, а вы что преподователь, изложили все в такой форме, красиво. Мне кажеться вы преподователь, или по крайне мере имеете его задатки...

          ВСЕМ СПАСИБО ПЛАН РАБОТЫ НАМЕЧЕН, БУДЕМ РАБОТАТАТЬ.
            Цитата SOLON7 @
            Да вы что, а разве PID не растет с каждым новым запуском нового процесса

            Нет. В общем случае это не так.
            Цитата SOLON7 @
            как-то не вяжется, чтобы PID был одинаков у процессов

            У двух процессов, существовавших одновременно в некий момент времени, одинаковых ID быть не может.
            Но эта ситуация вполне реальна, для процессов, разнесенных во времени.
            Кстати, вероятность этого не так уж мала, как кажется.
            Цитата SOLON7 @
            Я нашел пожалуй самый легкий метод определения, как узнавать запущенна ли прога из интернет експлорер.
            При запуске из ИНтернет Експолера не передаеться параметр "Рабочий каталог". То есть можно проверить если рабочий каталог неравен Extractfilepath(paramstr(0)) то значит его запустил ИНтернет Експолера

            Этот способ определения череват ошибками, imho. Ибо из факта "если рабочий каталог неравен Extractfilepath(paramstr(0))"
            отнюдь не следует, что нас запустил IE. :)
              Цитата
              Да вы что, а разве PID не растет с каждым новым запуском нового процесса, как-то не вяжется, чтобы PID был одинаков у процессов


              Riply абсолютно права. Я к сожелению не смог найти прямого ответа в MSDN, там весьма уклончиво отвечают на этот вопрос - "The identifier is valid from the time the process is created until the process has been terminated." Эту фразу, в принципе, можно понять по разному. Зато недвусмысленно это описано у Рихтера, так что сошлемся на его авторитет:

              Подчеркну ещс один чрезвычайно важный момент система способна повторно использовать идентификаторы процессов и потоков. Например, при создании про цесса система формирует объект "процесс", присваивая ему идентификатор со зна чением, допустим, 122 Создавая новый объект "процесс", система уже не присвоит ему данный идентификатор. Но после выгрузки из памяти первого объекта следу ющему создаваемому объекту "процесс" может быть присвоен тот же идентификатор — 122.

              Эту особенность нужно учитывать при написании кода, избегая ссылок на невер ный объект "процесс" (или "поток"). Действительно, затребовать и сохранить иден тификатор процесса несложно, но задумайтесь, что получится, ссли в следующий момент этот процесс будет завершен, а новый получит тот же идентификатор: сохра ненный ранее идентификатор уже связан совсем с другим процессом.
                Узнать родителя любого процесса можно и без перебора процессов в снимке. Например вот так:

                ExpandedWrap disabled
                  type
                    PROCESS_BASIC_INFORMATION = packed record
                      ExitStatus: DWORD;
                      PebBaseAddress: Pointer;
                      AffinityMask: DWORD;
                      BasePriority: DWORD;
                      uUniqueProcessId: Ulong;
                      uInheritedFromUniqueProcessId: Ulong;
                    end;
                   
                  function  NtQueryInformationProcess(
                      ProcessHandle : THandle;
                      ProcessInformationClass : Byte;
                      ProcessInformation : Pointer;
                      ProcessInformationLength : ULONG;
                      ReturnLength : PULONG
                    ): DWORD; stdcall; external 'ntdll.dll';
                   
                  function GetOwnedProcessID(const dwProcessHandle: DWORD): DWORD;
                  const
                    ProcessBasicInformation = 0;
                  var
                    Info: PROCESS_BASIC_INFORMATION;
                  begin
                    Result := 0;
                    if NtQueryInformationProcess(dwProcessHandle,
                      ProcessBasicInformation, @Info, SizeOf(Info), nil) = NO_ERROR then
                      Result := Info.uInheritedFromUniqueProcessId;
                  end;


                Вот так будет выглядеть получение родителя от текущего процесса:

                ExpandedWrap disabled
                  procedure TForm1.Button1Click(Sender: TObject);
                  var
                    dwProcessHandle: DWORD;
                  begin
                    DuplicateHandle(GetCurrentProcess, GetCurrentProcess, GetCurrentProcess,
                      @dwProcessHandle, 0, False, DUPLICATE_SAME_ACCESS);
                    Caption := IntToStr(GetOwnedProcessID(dwProcessHandle));
                  end;
                  Rouse_

                  DuplicateHandle не обязательно. NtQueryInformationProcess прекрасно съедает и псевдохэндл.
                    Rose, согласен...
                      Цитата Rouse_ @
                      Узнать родителя любого процесса можно и без перебора процессов в снимке. Например вот так:

                      А мы не привыкли искать легкие пути :)
                      А если серьезно, то мне это просто не пришло в голову.
                      Спасибо.
                        НУ родителя мы то узнаем, а как узнать является ли процесс Internet Explorer....
                          GetModuleFileNameEx очевидно :)
                            А какой же быстрый способ узнать по ПИДУ имя процесса.
                            Какую функцию по обьему кода посоветуете????
                            Чтоб поменьше кода было....
                              Тэкссс... тебе уже много насоветовали. Давай сначала посмотрим, понял ли ты все это. Выкладывай аттачем код, с которым сейчас эксперементируешь...
                                Вобщем если я правильно понял автору нужно что-то врое этого:
                                ExpandedWrap disabled
                                  const
                                    ProcessBasicInformation = 0;
                                    CSIDL_PROGRAM_FILES = $0026;
                                    IExplorePath: string = '\Internet Explorer\IEXPLORE.EXE';
                                   
                                  type
                                    PROCESS_BASIC_INFORMATION = packed record
                                      ExitStatus: DWORD;
                                      PebBaseAddress: Pointer;
                                      AffinityMask: DWORD;
                                      BasePriority: DWORD;
                                      uUniqueProcessId: Ulong;
                                      uInheritedFromUniqueProcessId: Ulong;
                                    end;
                                   
                                  function  NtQueryInformationProcess(
                                    ProcessHandle : THandle;
                                    ProcessInformationClass : Byte;
                                    ProcessInformation : Pointer;
                                    ProcessInformationLength : ULONG;
                                    ReturnLength : PULONG
                                    ): DWORD; stdcall; external 'ntdll.dll';
                                   
                                  function GetModuleFileNameExA(
                                    hProcess: DWORD;
                                    hModule: DWORD;
                                    lpFilename: PAnsiChar;
                                    nSize: DWORD
                                    ): DWORD; stdcall; external 'PSAPI.dll';
                                   
                                   
                                  function OwnerProcessIs_IExplore: Boolean;
                                  var
                                    lInfo: PROCESS_BASIC_INFORMATION;
                                    lParentProcHandle: THandle;
                                    lpFileName, lPFPath: PAnsiChar;
                                   
                                    dwProcessHandle: DWORD;
                                  begin
                                    Result := False;
                                    ZeroMemory(@lInfo, SizeOf(PROCESS_BASIC_INFORMATION));
                                   
                                    DuplicateHandle(GetCurrentProcess, GetCurrentProcess, GetCurrentProcess,
                                      @dwProcessHandle, 0, False, DUPLICATE_SAME_ACCESS);
                                   
                                    if NtQueryInformationProcess(dwProcessHandle, ProcessBasicInformation,
                                      @lInfo, SizeOf(PROCESS_BASIC_INFORMATION), nil) = NO_ERROR then
                                    begin
                                      lParentProcHandle := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ,
                                         False, lInfo.uInheritedFromUniqueProcessId);
                                      if lParentProcHandle > 0 then
                                      begin
                                        lpFileName := GetMemory(MAX_PATH);
                                        ZeroMemory(lpFileName, MAX_PATH);
                                        lPFPath := GetMemory(MAX_PATH);
                                        ZeroMemory(lPFPath, MAX_PATH);
                                   
                                        if SHGetSpecialFolderPath(0, lPFPath, CSIDL_PROGRAM_FILES, False) and
                                          (GetModuleFileNameExA(lParentProcHandle, 0, lpFileName, MAX_PATH) > 0) then
                                          Result := lPFPath + IExplorePath = lpFileName;
                                        FreeMemory(lpFileName);
                                        FreeMemory(lPFPath);
                                      end;
                                      CloseHandle(lParentProcHandle);
                                    end;
                                    CloseHandle(dwProcessHandle);
                                  end;


                                Добавлено
                                Цитата

                                DuplicateHandle не обязательно. NtQueryInformationProcess прекрасно съедает и псевдохэндл.

                                Кстати пока отлаживал, псевдохендл не всегда отрабатывал(закономерности не понял), и NtQueryInformationProcess выкидывало с "неверный декриптор". Пришлось DublicateHandle все-таки оставить.
                                Сообщение отредактировано: Rennigth -
                                  Цитата
                                  Кстати пока отлаживал, псевдохендл не всегда отрабатывал(закономерности не понял), и NtQueryInformationProcess выкидывало с "неверный декриптор". Пришлось DublicateHandle все-таки оставить.


                                  Честно говоря, не сталкивался с проблемами из-за псевдохэндла, но раз так, то буду иметь в виду.

                                  PS: Закройте его тогда уж, хотя бы, dwProcessHandle в смысле...
                                    Цитата

                                    PS: Закройте его тогда уж, хотя бы, dwProcessHandle в смысле...


                                    Сорь :), поправил предыдущий пост чтоб не плодить одно и тоже.
                                      Цитата Rennigth @
                                      Вобщем если я правильно понял автору нужно что-то врое этого:


                                      Ну раз уж выкладывается решение для copy/paste`ого использования, то не плохо
                                      было бы включить в него и проверку настоящего родителя мы нашли или так "погулять вышедшего" :)
                                        Цитата

                                        Ну раз уж выкладывается решение для copy/paste`ого использования, то не плохо
                                        было бы включить в него и проверку настоящего родителя мы нашли или так "погулять вышедшего"

                                        Riply, поясни плиз. Не понял что ты имеешь ввиду под "настоящим родителем".

                                        Добавлено
                                        Это:
                                        Цитата

                                        P.S.
                                        Только проку от данной методики, как от козла молока.
                                        Процесса родителя уже может и не быть в помине, пока мы тут соизволяем его искать
                                        И полученный нами ID, можно выбрасывать на помойку.

                                        Гораздо лучше использовать NtQuerySystemInformation с
                                        параметром SystemProcessesAndThreadsInformation - можно обойтись одним "снимком".
                                        Правда и с CreateToolhelp32Snapshot можно, но придется запоминать ProcEntry`ы.

                                        P.S.S.
                                        >Да нет с TlHelp32 работал
                                        >Я люблю, когда появляються задачи по программированию..
                                        >Но тут немного в невиддении насчет родителя..
                                        Ой как "не вяжутся" эти три фразы
                                        (особенно учитывая, что в Help`е есть пример

                                        Забыла еще одну неприятную вещь:
                                        Может получиться так, что к моменту нашего поиска, родитель уже умрет,
                                        и будет создан другой процесс с такм же ID, как и у родителя.
                                        А вот чтобы не попасть впросак с этим, придется использовать NtQuerySystemInformation
                                        и сравнивать времена создания найденого нами родителя и наше.

                                        имеешь ввиду? Или более жесткая проверка на то что это именно IE?
                                        Сообщение отредактировано: Rennigth -
                                          Цитата Rennigth @
                                          Riply, поясни плиз. Не понял что ты имеешь ввиду под "настоящим родителем".


                                          Я хотела сказать, что у нас нет уверенности в том, что ID, с которым мы работаем,
                                          действительно ID нашего родителя, а не какого-то левого процесса.
                                          (случай с использованием старого значения ID, для нового процесса).
                                          Соответственно, как положительный ответ OwnerProcessIs_IExplore, так и отрицательный
                                          верны с некой долей вероятности.
                                          Проверять можно так: сравнить время нашего создания, с временем создания "родителя".
                                          И если родитель был создан позже нас, то кричать о подлоге :)
                                            Цитата

                                            Я хотела сказать, что у нас нет уверенности в том, что ID, с которым мы работаем,
                                            действительно ID нашего родителя, а не какого-то левого процесса.
                                            (случай с использованием старого значения ID, для нового процесса).
                                            Соответственно, как положительный ответ OwnerProcessIs_IExplore, так и отрицательный
                                            верны с некой долей вероятности.
                                            Проверять можно так: сравнить время нашего создания, с временем создания "родителя".
                                            И если родитель был создан позже нас, то кричать о подлоге


                                            Желание дамы - закон! :) Вроде без особых косяков...
                                            ExpandedWrap disabled
                                              uses ShlObj //Лень в ручную экспортировать
                                              //...
                                               
                                              const
                                                SYSTEM_PROCESSES_AND_THREADS_INFORMATION = 5;
                                                NT_STATUS_SUCCESS              = DWord($00000000);
                                                NT_STATUS_ACCESS_DENIED        = DWord($C0000022);
                                                NT_STATUS_INFO_LENGTH_MISMATCH = DWord($C0000004);
                                                CSIDL_PROGRAM_FILES = $0026;
                                                IExplorePath: string = '\Internet Explorer\IEXPLORE.EXE';
                                               
                                              type
                                                PSYSTEM_THREAD_INFORMATION = ^_SYSTEM_THREAD_INFORMATION;
                                                _SYSTEM_THREAD_INFORMATION  = packed record
                                                  KernelTime: LARGE_INTEGER;
                                                  UserTime: LARGE_INTEGER;
                                                  CreateTime: LARGE_INTEGER;
                                                  WaitTime: ULONG;
                                                  StartAddress: Pointer;
                                                  UniqueProcess: DWORD;
                                                  UniqueThread: DWORD;
                                                  Priority: Integer;
                                                  BasePriority: Integer;
                                                  ContextSwitchCount: ULONG;
                                                  State: Longint;
                                                  WaitReason: Longint;
                                                end;
                                               
                                                PSYSTEM_PROCESS_INFORMATION = ^_SYSTEM_PROCESS_INFORMATION;
                                                _SYSTEM_PROCESS_INFORMATION = packed record
                                                  NextOffset: ULONG;
                                                  ThreadCount: ULONG;
                                                  Reserved1: array [0..5] of ULONG;
                                                  CreateTime: FILETIME;
                                                  UserTime: FILETIME;
                                                  KernelTime: FILETIME;
                                                  ModuleNameLength: WORD;
                                                  ModuleNameMaxLength: WORD;
                                                  ModuleName: PWideChar;
                                                  BasePriority: ULONG;
                                                  ProcessID: ULONG;
                                                  InheritedFromUniqueProcessID: ULONG;
                                                  HandleCount: ULONG;
                                                  Reserved2 : array[0..1] of ULONG;
                                                  PeakVirtualSize : ULONG;
                                                  VirtualSize : ULONG;
                                                  PageFaultCount : ULONG;
                                                  PeakWorkingSetSize : ULONG;
                                                  WorkingSetSize : ULONG;
                                                  QuotaPeakPagedPoolUsage : ULONG;
                                                  QuotaPagedPoolUsage : ULONG;
                                                  QuotaPeakNonPagedPoolUsage : ULONG;
                                                  QuotaNonPagedPoolUsage : ULONG;
                                                  PageFileUsage : ULONG;
                                                  PeakPageFileUsage : ULONG;
                                                  PrivatePageCount : ULONG;
                                                  ReadOperationCount : LARGE_INTEGER;
                                                  WriteOperationCount : LARGE_INTEGER;
                                                  OtherOperationCount : LARGE_INTEGER;
                                                  ReadTransferCount : LARGE_INTEGER;
                                                  WriteTransferCount : LARGE_INTEGER;
                                                  OtherTransferCount : LARGE_INTEGER;
                                                  ThreadInfo: array [0..0] of _SYSTEM_THREAD_INFORMATION;
                                                end;
                                               
                                              function ZwQuerySystemInformation(ASystemInformationClass: Cardinal;
                                                ASystemInformation: Pointer; ASystemInformationLength: Cardinal;
                                                AReturnLength: PCardinal): Cardinal; stdcall; external 'ntdll.dll';
                                               
                                              function GetModuleFileNameExA(hProcess: THandle; hModule: HModule;
                                                lpFilename: PAnsiChar; nSize: DWORD): DWORD; stdcall; external 'PSAPI.dll';
                                               
                                              function OwnerProcessIs_IExplore: Boolean;
                                              var
                                                pSI, pSITemp: PSYSTEM_PROCESS_INFORMATION;
                                                hParentProcess: THandle;
                                                dwParentProcessID, dwSelfProcessID: DWORD;
                                                lpFileName, lpPFPath: PAnsiChar;
                                                dwOffSet, dwSize: DWORD;
                                                ftSelfProcTime: FILETIME;
                                              begin
                                                Result := False;
                                                dwSelfProcessID := GetCurrentProcessId;
                                               
                                                dwSize := 0;
                                                dwParentProcessID := 0;
                                               
                                                if ZwQuerySystemInformation(SYSTEM_PROCESSES_AND_THREADS_INFORMATION,
                                                  nil, 0, @dwSize) <> NT_STATUS_INFO_LENGTH_MISMATCH then Exit;
                                               
                                                pSI := VirtualAlloc(nil, dwSize, MEM_COMMIT or MEM_RESERVE, PAGE_READWRITE);
                                                if Assigned(pSI) then
                                                try
                                                  if ZwQuerySystemInformation(SYSTEM_PROCESSES_AND_THREADS_INFORMATION,
                                                    pSI, dwSize, @dwSize) = NT_STATUS_SUCCESS then
                                                  begin
                                                    pSITemp := pSI;
                                                    repeat
                                                      if pSITemp^.ProcessID = dwSelfProcessID then
                                                      begin
                                                        dwParentProcessID := pSITemp^.InheritedFromUniqueProcessID;
                                                        ftSelfProcTime := pSITemp^.CreateTime;
                                                        Break;
                                                      end;
                                                      dwOffSet := pSITemp^.NextOffset;
                                                      pSITemp := Pointer(DWORD(pSITemp) + dwOffSet);
                                                    until dwOffSet = 0;
                                               
                                                    if dwParentProcessID > 0 then
                                                    begin
                                                      pSITemp := pSI;
                                                      repeat
                                                        if pSITemp^.ProcessID = dwParentProcessID then
                                                        begin
                                                          if CompareFileTime(ftSelfProcTime, pSITemp^.CreateTime) > 0 then
                                                          begin
                                                            hParentProcess := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ,
                                                               False, dwParentProcessID);
                                                            try
                                                              if hParentProcess > 0 then
                                                              begin
                                                                lpFileName := GetMemory(MAX_PATH);
                                                                try
                                                                  ZeroMemory(lpFileName, MAX_PATH);
                                                                  lpPFPath := GetMemory(MAX_PATH);
                                                                  try
                                                                    ZeroMemory(lpPFPath, MAX_PATH);
                                               
                                                                    if SHGetSpecialFolderPath(0, lpPFPath, CSIDL_PROGRAM_FILES, False) and
                                                                      (GetModuleFileNameExA(hParentProcess, 0, lpFileName, MAX_PATH) > 0) then
                                                                      Result := lpPFPath + IExplorePath = lpFileName;
                                                                  finally
                                                                    FreeMemory(lpPFPath);
                                                                  end;
                                                                finally
                                                                  FreeMemory(lpFileName);
                                                                end;
                                                              end;
                                                            finally
                                                              CloseHandle(hParentProcess);
                                                            end;
                                                          end;
                                                          Break;
                                                        end;
                                                        dwOffSet := pSITemp^.NextOffset;
                                                        pSITemp := Pointer(DWORD(pSITemp) + dwOffSet);
                                                      until dwOffSet = 0;
                                                    end;
                                                  end;
                                                finally
                                                  VirtualFree(pSI, 0, MEM_RELEASE);
                                                end;
                                              end;


                                            Добавлено
                                            Кстати вопросик, чем отличаеютя в структуре SYSTEM_PROCESS_INFORMATION времена CreateTime, UserTime, KernelTime?
                                            Сообщение отредактировано: Rennigth -
                                              Что значит чем отличаются. UserTime + KernelTime = общее время работы процесса.
                                                Цитата
                                                Кстати вопросик, чем отличаеютя в структуре SYSTEM_PROCESS_INFORMATION времена CreateTime, UserTime, KernelTime?

                                                Соответственно время создания процесса, время, которое его потоки выполнялись в пользовательском режиме и режиме ядра. Здесь описано:
                                                http://msdn2.microsoft.com/en-us/library/ms683223.aspx
                                                  Цитата

                                                  Что значит чем отличаются. UserTime + KernelTime = общее время работы процесса.

                                                  Логично... :) Я если в двух словах, как высчитываеютя UserTime и KernelTime? Просто плохо себе представляю как система может их различать :(

                                                  Добавлено
                                                  Цитата

                                                  Соответственно время создания процесса, время, которое его потоки выполнялись в пользовательском режиме и режиме ядра. Здесь описано:
                                                  http://msdn2.microsoft.com/en-us/library/ms683223.aspx

                                                  О спс, почитаем...
                                                  Сообщение отредактировано: Rennigth -
                                                    Rouse_

                                                    Кстати, ExitTime - CreationTime не равно UserTime + KernelTime. Когда все потоки процесса простаивают, UserTime и KernelTime не меняется. В этом случае UserTime + KernelTime будет меньше. И наоборот, если у процесса несколько потоков и все они работают безперебойно, UserTime + KernelTime может быть больше чем ExitTime - CreationTime, так как вроде бы UserTime и KernelTime суммируются по всем потокам процесса.
                                                      Rose, ну это то понятно :) Простой не учитывался ж никогда :)))
                                                      Цитата Rose @
                                                      так как вроде бы UserTime и KernelTime суммируются по всем потокам процесса.

                                                      Конечно, но т.к. система псевдомногопоточная, т.е. в единый квант времени выполняется только что-то одно, то ExitTime - CreationTime никогда не будет меньше чем UserTime + KernelTime :)
                                                        Цитата
                                                        Конечно, но т.к. система псевдомногопоточная, т.е. в единый квант времени выполняется только что-то одно, то ExitTime - CreationTime никогда не будет меньше чем UserTime + KernelTime


                                                        Логично, но это верно только для однопроцессорной системы. На многопроцессорной UserTime + KernelTime уже может и превышать ;)

                                                        Кстати, мне тоже интересно, как система следит за тем, в каком режиме (user или kernel) выолняется поток?
                                                          Цитата Rose @
                                                          На многопроцессорной UserTime + KernelTime уже может и превышать

                                                          Истину глаголишь :yes:

                                                          Цитата Rose @
                                                          Кстати, мне тоже интересно, как система следит за тем, в каком режиме (user или kernel) выолняется поток?

                                                          Вычисляется в KeUpdateRunTime()

                                                          Грубо говоря выглядит примерно так:

                                                          ExpandedWrap disabled
                                                                    push    ebx                     ; we will destroy ebx
                                                                    inc     dword ptr [eax]+PcPrcbData+PbInterruptCount
                                                                    mov     ebx, [eax]+PcPrcbData+PbCurrentThread ; (ebx)->current thread
                                                                    mov     ecx, ThApcState+AsProcess[ebx]
                                                                                                    ; (ecx)->current thread's process
                                                             
                                                                    test    dword ptr [ebp]+TsEFlags,EFLAGS_V86_MASK
                                                                    jne     Kutp20                  ; if ne, user mode
                                                             
                                                                    test    byte ptr [ebp]+TsSegCs, MODE_MASK ; test if prev mode was kernel
                                                                    jne     Kutp20                  ; if ne, user mode
                                                             
                                                            ;
                                                            ; Update the total time spent in kernel mode
                                                            ;
                                                             
                                                                    mov     edx, 0                  ; set kernel mode
                                                                    inc     dword ptr [eax].PcPrcbData.PbKernelTime
                                                                    cmp     byte ptr [esp+8], DISPATCH_LEVEL
                                                                    jc      short Kutp4             ; OldIrql<2, then kernel
                                                                    ja      short Kutp3             ; OldIrql>2, then interrupt
                                                            Ага, осталось только выяснить где и когда вызывается KeUpdateRunTime? Надо полагать, по прерыванию от таймера?
                                                              Она вызывается из KeUpdateSystemTime который дергается каждый раз при срабатывании прерывания системного таймера (тамже увеличивается и знаение возвращаемое GetTiCkCount и много чего еще) :)
                                                                Ясно, спасибо. Правда насколько я знаю, системный таймер на NT тикает каждые 10 мс (тогда же планировщик потоков получает управление), так что соблюсти документированную дискретность 100 нс никак не получится. Или это я с прямым углом перепутал?
                                                                  В действительности срабатывает он намного чаще 10 мс. Иначе пропала бы возможность работы с мультимедийными таймерами :)
                                                                    Цитата Rennigth @
                                                                    Вроде без особых косяков...

                                                                    Да. На первый взгляд, не видно :)

                                                                    P.S.
                                                                    Цитата Rennigth @
                                                                    Желание дамы - закон!

                                                                    Вот бы везде было так, как на форумах по программированию :)
                                                                      Уважаемые!!! ПОМОГИТЕ!!!! :huh:
                                                                      Ни кто не пособит- как туже самую задачу воспроизвести на Visual Basic 6.0 ???

                                                                      т.е. меня интересует, КАК узнать имя процесса запустившего мою программу, но через VB?

                                                                      СПАСИБО огромное любому, кто хоть что то посоветует ;) ! )))))
                                                                        Точно так-же, берешь приведенный код и переписываешь его на VB.
                                                                          Rouse
                                                                          Александр

                                                                          В том то и проблема, у меня не выходит (если честно, то я не спец в программировании, тока VB изучаю, а тут совсем др. язык).. Помогите, плиз, если можете)
                                                                          Спасибо.
                                                                            Цитата akkorn @
                                                                            В том то и проблема, у меня не выходит (если честно, то я не спец в программировании, тока VB изучаю, а тут совсем др. язык).. Помогите, плиз, если можете)
                                                                            Спасибо.


                                                                            Ты думаешь Розыч спец в VB?
                                                                            ЛУчше задать вопрос в соответствующем разделе форума.
                                                                              Демо
                                                                              Александр

                                                                              А КТО ЕСТЬ ТАКОЙ огромный спец, кто мог бы это провернуть???
                                                                              Пасиб))
                                                                                Пожалуй, апну тему.
                                                                                Использую приведенный выше код.
                                                                                GetModuleFileNameExA на некоторых компьютерах возвращает ошибку,
                                                                                Getlasterror = 299, запрос Readprocessmemory или writeprocessmemory выполнен только частично.
                                                                                Оно же "Only part of a ReadProcessMemory or WriteProcessMemory request was completed." или ERROR_PARTIAL_COPY.
                                                                                Пробовал увеличить буффер - дело не в этом. GetModuleFileNameExW дает ровно тот же результат - либо обе работают, либо обе нет.

                                                                                Работает на WindowsXP x86, Windows2003 x86, Windows 2003 x64.
                                                                                Не работает: словил только на Win2003x64, запущенном под Oracle VirtualBox, но есть и другие эпизоды.

                                                                                Сделал мощный дебаг, в Memo выводится все и на каждом шаге. Функции GetModuleFileNameEx передается нормальный хендл.
                                                                                Приложение 32битное, в диспетчере задач отмечено как *32. Возможно, как-то связано. Запуск в режиме совместимости с любой другой ОС во первых, не решает задачу, во вторых - выдается тот же результат. Запустившее приложение еще в памяти, не тот случай когда бы оно успело закрыться. Как фиксить?

                                                                                ---
                                                                                еще порылся и выяснил, что ошибка возникает только при запуске приложения из проводника (Explorer.exe) либо через CMD.exe на некоторых 64-битных системах. Запуск другой программой определяется.
                                                                                Решается использованием GetProcessImageFileNameA, которая дает путь в виде \Device1\PArtition2\windows\explorer.exe или типа того, но сойдет.
                                                                                Надеюсь, GetProcessImageFileNameA есть на всех системах и не будет "точка входа не найдена"... Рекомендуемую QueryFullProcessImageName в системных библиотеках не нашел, в модулях Delphi тем более.
                                                                                Сообщение отредактировано: Виталь -
                                                                                  Цитата Виталь @
                                                                                  QueryFullProcessImageName

                                                                                  Minimum supported client Windows Vista [desktop apps only]
                                                                                  Minimum supported server Windows Server 2008 [desktop apps only]
                                                                                  Header WinBase.h (include Windows.h)
                                                                                  Library Kernel32.lib
                                                                                  DLL Kernel32.dll
                                                                                  0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                                                                  0 пользователей:


                                                                                  Рейтинг@Mail.ru
                                                                                  [ Script execution time: 0,0887 ]   [ 16 queries used ]   [ Generated: 16.09.25, 15:10 GMT ]