На главную Наши проекты:
Журнал   ·   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
  
> Узнать состояния потока (suspended или resume) с помощью API-функции
    Скажите, пожалуйста, можно ли:
    1) узнать по Handle существует ли в системе поток с этим Handle
    2) узнать текущее состояние потока(suspended или resume) по его Handle с помощью API-функции.
    Сообщение отредактировано: DelphiLexx -
      Цитата DelphiLexx @
      1) узнать по Handle существует ли в системе поток с этим Handle

      function GetExitCodeThread(hThread: THandle; var lpExitCode: DWORD): BOOL; stdcall;

      Добавлено
      Цитата DelphiLexx @
      2) узнать текущее состояние потока(suspended или resume) по его Handle с помощью API-функции.

      Вот оддельной Апишки я не видел но можно хитрым способом узнавать:

      ExpandedWrap disabled
        function StatThread(HT:Thandle):boolean;
        var
          i:integer;
        bagin
          i:=suspendthread(HT);
          if i=-1 then
          begin
            result:=false;
            exit;
          end;
          resumethread(HT);
          if i=0 then result:=true else result:=false;
        end;

      если поток не существует или он на паузе тогда возвратится лож если он запущен тогда истину.

      пс. все дело втом что когда с помощю функции suspendthread перевести поток в паузу то возврящается ноль если несколько раз так повторить то число увеличивается, получается что если поток стоит на паузе тогда возврат будет 1 если он выполняется тогда будет 0. но нужно не забыть вернут прежнее состояние если мы дважди поствили его на паузу то прийдется дважди ее снимать для запуска.
        А вот здесь
        Цитата ViktorXP @
        end;
        resumethread(HT);
        if i=0 then result:=true else result:=false;

        случайно не так:
        Цитата ViktorXP @
        end;
        I := resumethread(HT);
        if i=0 then result:=true else result:=false;


        Добавлено
        Цитата ViktorXP @
        i:=suspendthread(HT);

        И suspendthread не может вернуть -1 т.к. у него возвращаемый тип dword
          DelphiLexx нет я ничего не перепутал.

          Цитата DelphiLexx @
          И suspendthread не может вернуть -1 т.к. у него возвращаемый тип dword

          просто при ошибки он возвращает максимальное число :)
          а теперь отними от нуля 1 что получится :)

          Добавлено
          Цитата
          If the function succeeds, the return value is the thread's previous suspend count; otherwise, it is (DWORD) -1. To get extended error information, use the GetLastError function.


          Добавлено
          хотя i нужно было объявить не как integer а ка DWORD
            1. ИМХО, наиболее универсальный метод с помощью Native API (используются заголовки JEDI API - http://jedi-apilib.sourceforge.net/ ):

            ExpandedWrap disabled
              uses JwaNative, JwaNtStatus;
               
              // Упрощенно, без проверок на ошибки
              function GetObjectTypeName(Handle: THandle): String;
              var
                Info: Pointer;
                BasicInfo: _OBJECT_BASIC_INFORMATION;
                Size: Cardinal;
              begin
                NtQueryObject(Handle,ObjectBasicInformation,@BasicInfo,SizeOf(_OBJECT_BASIC_INFORMATION),nil);
                GetMem(Info,BasicInfo.TypeInformationLength);
                try
                  if NtQueryObject(Handle,ObjectTypeInformation,Info,BasicInfo.TypeInformationLength,@Size) =
                    STATUS_INFO_LENGTH_MISMATCH
                  then begin;
                    ReallocMem(Info,Size);
                    NtQueryObject(Handle,ObjectTypeInformation,Info,Size,nil);
                  end;
                  Result:=WideCharToString(POBJECT_TYPE_INFORMATION(Info)^.Name.Buffer);
                finally
                  FreeMem(Info);
                end;
              end;
               
              function IsThread(Handle: THandle): Boolean;
              begin
                Result:=GetObjectTypeName(Handle) = 'Thread';
              end;


            2. Есть у меня идейка тоже как это сделать, но что-то уж очень там наворочено, я лучше сначала проверю, если получится - отпишусь.
            Сообщение отредактировано: Rose -
              Rose я канешно ничего не имею против других вариантов только зачем заменять одну апишку кучей кода :huh:
              я бы ничего не говорл если тамбы была всего одна большая процедура
              но цепляются еще два модуля
              но это только мое мнение и не все могут с ним согласится
                ViktorXP

                Это универсальный метод. Позволяет по дескриптору узнать тип объекта вообще, а не проверить только на Thread. Если понадобится проверить на Process, File, Event, Port и т.д. - тот же самый код :) А насчет лишних модулей - так это же всего лишь заголовочные файлы с описанием типов и импортируемых функций. Как Windows.pas, к тому же, не такие уж и экзотичные... JEDI API достаточно популярная вещь.

                К тому же, десяток строчек - это куча кода?..
                Сообщение отредактировано: Rose -
                  Цитата Rose @
                  Это универсальный метод.

                  Ну раз он много чего может тогда даю добро на его существование :D
                  Цитата Rose @
                  JEDI API достаточно популярная вещь.

                  Слышал но ни когда не пользовался. В моих разработках очень мало сторонего.
                  Цитата Rose @
                  К тому же, десяток строчек - это куча кода?..

                  Если со стороны отладки: чем больше кода тем труднее в нем разобратся. А если учесть что это еще и не твое ...
                    Цитата
                    В моих разработках очень мало сторонего.


                    Хм :) Как сказать... Даже стандартные юниты не используете?

                    JEDI API - это затыкание сообществом дыр со стороны Borland. Как известно, импорт далеко не всех АПИ (даже тех, которые нужны повседневно) в стандартных дельфийских юнитах содержаться, а в JEDI с этим куда лучше. Недавно, когда Джим Дуглас (генеральный директор CodeGear) в Россию приезжал, этот вопрос поднимался. Считаю, что такие задачи они должны решать сами, а не полагаться на сообщество. ИМХО.
                      Да действительно в борланд не все апишки включены. А к JEDI API хорошая докомунтация есть?
                      Обязательно как нить попробую.

                      Добавлено
                      Цитата Rose @
                      Даже стандартные юниты не используете?

                      я имею ввиду под стороними - все то что от стороних разработчиков
                        Цитата
                        А к JEDI API хорошая докомунтация есть?


                        Есть! В MSDN :D Где и положено быть документации по WinAPI. Юниты из JEDI API - это грубо говоря большое расширение к Windows.pas. Разумеется, NativeAPI из моего примера недокументированы...
                          Ну тогда это понижает шансы использовать ее в моих проэктах. С таким успехом я и сам могу модуль писнуть.
                          И сразу опережаю. Согласен с утверждением: "Зачем писать если уже готовое есть" . Но в нем еще нужно будет разобратся а если для ее разбора нужна будет MSDN.... зачем мне эти модули если я всеравно буду изучать MSDN.

                          пс. тут решает каждый для себя сам что ему легче.
                            А разве я настаиваю - хозяин-барин ;) Хотя аргументация мне нравится, получается, что если бы документация была, вы бы ее не изучали, так как
                            Цитата
                            в нем еще нужно будет разобратся

                            Windows.pas вы по этой же причине не используете? Сами импортируете? Лично мне использование этого сэкономило массу времени, так как ручками описывать все стандартные типы и импортировать функции - задача весьма утомительная...
                            Сообщение отредактировано: Rose -
                              В общем, как и обещал, реализация второго пункта без Resume/Suspend, а прямо на лету :) На этот раз даже с проверками на ошибки. "Полезные" здесь функции IsThreadSuspended и GetThreadIdByHandle, остальные - просто рабочие.

                              ExpandedWrap disabled
                                uses SysConst, JwaNative, JwaWinType, JwaNtStatus;
                                 
                                function NtErrorMessage(Code: NTSTATUS): String;
                                var
                                  hMod: Cardinal;
                                  Buffer: array[0..255] of Char;
                                  Len: Integer;
                                begin
                                  hMod:=GetModuleHandle(ntdll);
                                  Len := FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM or FORMAT_MESSAGE_IGNORE_INSERTS or
                                    FORMAT_MESSAGE_ARGUMENT_ARRAY or FORMAT_MESSAGE_FROM_HMODULE, Pointer(hMod), Code, 0, Buffer,
                                    SizeOf(Buffer), nil);
                                  while (Len > 0) and (Buffer[Len - 1] in [#0..#32, '.']) do Dec(Len);
                                  SetString(Result, Buffer, Len);
                                end;
                                 
                                function NtSuccess(Code: NTSTATUS): Boolean;
                                begin
                                  Result:=Code >= 0;
                                end;
                                 
                                procedure NtCheck(Code: NTSTATUS);
                                begin
                                  if not NtSuccess(Code) then begin
                                    raise EOSError.CreateResFmt(@SOSError, [Code,NtErrorMessage(Code)]);
                                  end;
                                end;
                                 
                                function GetSystemInfoTable(ASystemInformationClass: SYSTEM_INFORMATION_CLASS;
                                  out Info: Pointer; out Size: Cardinal): NTSTATUS;
                                var
                                  SystemInfo: TSystemInfo;
                                  ReturnSize: Cardinal;
                                  ContinueFlag: Boolean;
                                begin
                                  GetSystemInfo(SystemInfo);
                                  Size:=SystemInfo.dwPageSize;
                                  repeat
                                    Info:=VirtualAlloc(nil,Size,MEM_COMMIT or MEM_RESERVE,PAGE_READWRITE);
                                    if Info = nil then
                                      RaiseLastOSError;
                                    Result:=NtQuerySystemInformation(ASystemInformationClass,Info,Size,@ReturnSize);
                                    ContinueFlag:=Result = STATUS_INFO_LENGTH_MISMATCH;
                                    if ContinueFlag then begin
                                      Win32Check(VirtualFree(Info,0,MEM_RELEASE));
                                      if ReturnSize = 0 then
                                        Size:=Size + SystemInfo.dwPageSize
                                      else
                                        Size:=ReturnSize;
                                    end;
                                  until not ContinueFlag;
                                end;
                                 
                                function GetThreadIdByHandle(Handle: THandle): Cardinal;
                                var
                                  Info: _THREAD_BASIC_INFORMATION;
                                begin
                                  NtCheck(NtQueryInformationThread(Handle,ThreadBasicInformation,@Info,
                                    SizeOf(_THREAD_BASIC_INFORMATION),nil));
                                  Result:=Info.ClientId.UniqueThread;
                                end;
                                 
                                function IsThreadSuspended(ThreadID: Cardinal): Boolean;
                                var
                                  Info, Entry: Pointer;
                                  Size, i: Cardinal;
                                  ContinueFlag: Boolean;
                                begin
                                  Result:=false;
                                  NtCheck(GetSystemInfoTable(SystemProcessesAndThreadsInformation,Info,Size));
                                  try
                                    Entry:=Info;
                                    ContinueFlag:=true;
                                    while ContinueFlag do begin
                                      for i:=0 to PSYSTEM_PROCESSES(Entry)^.ThreadCount - 1 do begin
                                        if PSYSTEM_PROCESSES(Entry)^.Threads[i].ClientId.UniqueThread = ThreadID
                                        then begin
                                          Result:=PSYSTEM_PROCESSES(Entry)^.Threads[i].WaitReason = Suspended;
                                          ContinueFlag:=false;
                                          Break;
                                        end;
                                      end;
                                      if (PSYSTEM_PROCESSES(Entry)^.NextEntryDelta <> 0) then
                                        Cardinal(Entry):=Cardinal(Entry) + PSYSTEM_PROCESSES(Entry)^.NextEntryDelta
                                      else
                                        ContinueFlag:=false;
                                    end;
                                  finally
                                    VirtualFree(Info,0,MEM_RELEASE);
                                  end;
                                end;
                              0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                              0 пользователей:


                              Рейтинг@Mail.ru
                              [ Script execution time: 0,0758 ]   [ 16 queries used ]   [ Generated: 28.04.24, 07:05 GMT ]