主要代码:
const MAX_LENGTH  =   30000;
buffer: array[0..MAX_LENGTH-1] of TSystemHandleInformation;
SYSTEM_HANDLE_INFORMATION = record
    ProcessId: ULONG;
    ObjectTypeNumber: UCHAR;
    Flags: UCHAR;  // 0x01 = PROTECT_FROM_CLOSE, 0x02 = INHERIT
    Handle: USHORT;
    Object_: Pointer;
    GrantedAccess: ACCESS_MASK;
  end;
  TSystemHandleInformation = SYSTEM_HANDLE_INFORMATION;
  PSystemHandleInformation = ^TSystemHandleInformation; status := NtQuerySystemInformation(16, @buffer, MAX_LENGTH * sizeof(TSystemHandleInformation), 0);
    if ($00000000 = status) then
    begin
        pSysHandleInfo := @buffer;
        while(true) do
        begin
              if (pSysHandleInfo^.ObjectTypeNumber = 26) then
            begin
                ShowMessage('文件句柄');
            end;
            inc(i);
            if (i = MAX_LENGTH) then
                break;
            pSysHandleInfo := Pointer(Cardinal(pSysHandleInfo) + Sizeof(SYSTEM_HANDLE_INFORMATION));
        end;
    end;结果是根本没有执行ShowMessage,也就是一个文件句柄都没有,这显然出错了,但是不知道是哪里错了,请达人指点!

解决方案 »

  1.   

    调试啊调试
    还有,NT系列的Native API都需要从内核EXE导出的,楼主该不会直接就拿去用了吧?
      

  2.   

    function NtQuerySystemInformation(si_class: cardinal;
                                        si: pointer;
                                        si_length: cardinal;
                                        ret_length:cardinal):
                                        cardinal;
                                        stdcall;
                                        external 'ntdll.dll';
    我是直接声明的,获取进程信息也是这样声明的,没有问题,但是获取句柄不知道怎么就出问题了,不知道是不是那个结构的问题呢?
      

  3.   

    我还是比较倾向这样调用
    function NtQuerySystemInformation; external 'NTdll.dll' name 'NtQuerySystemInformation'
    语法声明方面
    function NtQuerySystemInformation(
               SystemInformationClass:DWord;  // 这个参数最终根据需要取得的信息而变
                  SystemInformation:Pointer;  // 这个参数指向接收取来的信息的缓存结构
              SystemInformationLength:DWord;  // 这个参数指出上面这个缓存结构的大小
          ReturnLength:DWord):DWord;stdcall;  // 这个参数指出实际返回的数据的大小
    CSDN有问题,回复半天看不到……
      

  4.   

    ╮(╯▽╰)╭,彻底无语啊,函数调用返回值都是0,但就是buffer里面的内容不对
      

  5.   

    突然想起来了,楼主该不会忘了引用Jedi API了吧??
      

  6.   

    Jedi API是什么东东啊?我以前一直用的C和C++,刚用DELPHI不到2个月。
      

  7.   

    uses里面的一个单元,负责转换c接口单元,到网上搜一下就知道了
    生成可执行程序并不代表程序正确
      

  8.   

    NtQuerySystemInformation(16...
    这里的16是啥东西?
      

  9.   

    目前为止该参数的取值总共就只有九个:
        SystemBasicInformation = 0,
        SystemPerformanceInformation = 2,
        SystemTimeOfDayInformation = 3,
        SystemProcessInformation = 5,
        SystemProcessorPerformanceInformation = 8,
        SystemInterruptInformation = 23,
        SystemExceptionInformation = 33,
        SystemRegistryQuotaInformation = 37,
        SystemLookasideInformation = 45不知道这个16是如何发明创建出来的...
      

  10.   

    SYSTEM_INFORMATION_CLASS = (
              SystemBasicInformation,
              SystemProcessorInformation,
              SystemPerformanceInformation,
              SystemTimeOfDayInformation,
              SystemNotImplemented1,
              SystemProcessesAndThreadsInformation,
              SystemCallCounts,
              SystemConfigurationInformation,
              SystemProcessorTimes,
              SystemGlobalFlag,
              SystemNotImplemented2,
              SystemModuleInformation,
              SystemLockInformation,
              SystemNotImplemented3,
              SystemNotImplemented4,
              SystemNotImplemented5,
              SystemHandleInformation,
              SystemObjectInformation,
              SystemPagefileInformation,
              SystemInstructionEmulationCounts,
              SystemInvalidInfoClass1,
              SystemCacheInformation,
              SystemPoolTagInformation,
              SystemProcessorStatistics,
              SystemDpcInformation,
              SystemNotImplemented6,
              SystemLoadImage,
              SystemUnloadImage,
              SystemTimeAdjustment,
              SystemNotImplemented7,
              SystemNotImplemented8,
              SystemNotImplemented9,
              SystemCrashDumpInformation,
              SystemExceptionInformation,
              SystemCrashDumpStateInformation,
              SystemKernelDebuggerInformation,
              SystemContextSwitchInformation,
              SystemRegistryQuotaInformation,
              SystemLoadAndCallImage,
              SystemPrioritySeparation,
              SystemNotImplemented10,
              SystemNotImplemented11,
              SystemInvalidInfoClass2,
              SystemInvalidInfoClass3,
              SystemTimeZoneInformation,
              SystemLookasideInformation,
              SystemSetTimeSlipEvent,
              SystemCreateSession,
              SystemDeleteSession,
              SystemInvalidInfoClass4,
              SystemRangeStartInformation,
              SystemVerifierInformation,
              SystemAddVerifier,
              SystemSessionProcessesInformation);
      TSystemInformationClass = SYSTEM_INFORMATION_CLASS;
      

  11.   

    “ObjectTypeNumber = 26”中的26又是什么类型?某些句柄类型的值在不同平台之间是非固定的。
      

  12.   

    SYSTEM_HANDLE_TYPE = (OB_TYPE_UNKNOWN,
    OB_TYPE_TYPE,
    OB_TYPE_DIRECTORY,
    OB_TYPE_SYMBOLIC_LINK,
    OB_TYPE_TOKEN,
    OB_TYPE_PROCESS,
    OB_TYPE_THREAD,
    OB_TYPE_UNKNOWN_7,
    OB_TYPE_EVENT,
    OB_TYPE_EVENT_PAIR,
    OB_TYPE_MUTANT,
    OB_TYPE_UNKNOWN_11,
    OB_TYPE_SEMAPHORE,
    OB_TYPE_TIMER,
    OB_TYPE_PROFILE,
    OB_TYPE_WINDOW_STATION,
    OB_TYPE_DESKTOP,
    OB_TYPE_SECTION,
    OB_TYPE_KEY,
    OB_TYPE_PORT,
    OB_TYPE_WAITABLE_PORT,
    OB_TYPE_UNKNOWN_21,
    OB_TYPE_UNKNOWN_22,
    OB_TYPE_UNKNOWN_23,
    OB_TYPE_UNKNOWN_24,
    //OB_TYPE_CONTROLLER,
    //OB_TYPE_DEVICE,
    //OB_TYPE_DRIVER,
    OB_TYPE_IO_COMPLETION,
    OB_TYPE_FILE);
      TSystemHandleType = SYSTEM_HANDLE_TYPE;
      

  13.   

    OS版本呢?如果想要的是文件类型,最好不要使用常量,除非你对所有的OS版本都做过不同的匹配。
    可以通过CreateFile自己打开/创建一个文件,然后用该文件句柄及当前应用程序的PID再取得的信息表当中匹配,从而得到ObjectTypeNumber
      

  14.   

    从你的描述看,在你测试的环境当中文件句柄相对应的ObjectTypeNumber可能不是26,而是其它值,比如28亦或其它。
      

  15.   

    OS是XP SP2 ENGLISH EDITION,再看看。
      

  16.   

    怎么写的?不会又来个硬编码"if (pSysHandleInfo^.ObjectTypeNumber = 26) then "吧?
      

  17.   

    取信息的结构不对,NtQuerySystemInformation得到的是一个PSYSTEM_HANDLE_INFORMATION_EX,在其中包含着多个TSystemHandleInformation
      

  18.   

    var
      status: Cardinal;
      pSysHandleInfo: PSystemHandleInformation;
      I: Integer;
      hFile: THandle;
      FileType: Word;  HandleCount : LongWord;
    begin
        hFile:=CreateFile('NUL',0,0,Nil,OPEN_EXISTING,0,0);
        if hFile = INVALID_HANDLE_VALUE then BEGIN
          ShowMessage('INVALID_HANDLE_VALUE!');
          Exit;
        END;    status := NtQuerySystemInformation(16, @buffer, MAX_LENGTH * sizeof(TSystemHandleInformation), 0);
        if ($00000000 = status) then
        begin
            HandleCount := PLongWord(@buffer)^;
            pSysHandleInfo := PSystemHandleInformation(LongWord(@buffer)+ sizeof(LongWord));
            while(true) do
            begin
              if (pSysHandleInfo^.ProcessId = GetCurrentProcessId) and ( pSysHandleInfo^.Handle = Word(hFile)) then
                begin
                    FileType := pSysHandleInfo^.ObjectTypeNumber;
                    break;
                end;
                pSysHandleInfo := Pointer(Cardinal(pSysHandleInfo) + Sizeof(SYSTEM_HANDLE_INFORMATION));
            end;
        end;    I := 0;
        if ($00000000 = status) then
        begin
            HandleCount := PLongWord(@buffer)^;
            pSysHandleInfo := PSystemHandleInformation(LongWord(@buffer)+ sizeof(LongWord));
            while(true) do
            begin
                  if (pSysHandleInfo^.ObjectTypeNumber = FileType) then
                begin
                    ShowMessage('文件句柄');
                end;
                inc(i);
                if (i = MAX_LENGTH) then
                    break;
                pSysHandleInfo := Pointer(Cardinal(pSysHandleInfo) + Sizeof(SYSTEM_HANDLE_INFORMATION));
            end;
        end;
    end;
      

  19.   

    或者
    var
      buffer : record
        NumberOfHandles: LongWord;
        SystemHandleInformations:array[0..MAX_LENGTH-1] of TSystemHandleInformation;
      end;
      status: Cardinal;
      I: Integer;
      hFile: THandle;
      FileType: Word;  HandleCount : LongWord;
    begin
        hFile:=CreateFile('NUL',0,0,Nil,OPEN_EXISTING,0,0);
        if hFile = INVALID_HANDLE_VALUE then BEGIN
          ShowMessage('INVALID_HANDLE_VALUE!');
          Exit;
        END;    status := NtQuerySystemInformation(16, @buffer,  sizeof(buffer), 0);
        if ($00000000 = status) then
        begin
            HandleCount := buffer.NumberOfHandles;
            I := 0;
            while(I < HandleCount) do
            begin
              if (buffer.SystemHandleInformations[I].ProcessId = GetCurrentProcessId) and ( buffer.SystemHandleInformations[I].Handle = Word(hFile)) then
                begin
                    FileType := buffer.SystemHandleInformations[I].ObjectTypeNumber;
                    break;
                end;
                Inc(I);
            end;
            if I = HandleCount then Exit;
        end;
        if ($00000000 = status) then
        begin
            HandleCount := buffer.NumberOfHandles;
            I := 0;
            while(I < HandleCount) do
            begin
              if  ( buffer.SystemHandleInformations[I].ObjectTypeNumber = FileType) then
                begin
                    ShowMessage(Format('进程: %d,文件句柄: %d',[buffer.SystemHandleInformations[I].ProcessId, buffer.SystemHandleInformations[I].Handle]));
                end;
                Inc(I);
            end;
        end;
    end;
      

  20.   

    var
      buffer : record
        NumberOfHandles: LongWord;
        SystemHandleInformations:array[0..MAX_LENGTH-1] of TSystemHandleInformation;
      end;
    类似的大块内存数据声明时最好使用堆内存,而不是栈内存.
      

  21.   

    谢谢unsigned 的回复,周末没来,我先试试。
      

  22.   

    我给封装了一下,见笑unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs,jwaNative,JwaWinType, StdCtrls;type
      TForm1 = class(TForm)
        Button2: TButton;
        ListBox1: TListBox;
        procedure Button2Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;  {TQuerySystemInformation}
      TQuerySystemInformation  = class
      private
          fSysInfo : PVOID;
          fSysInfoClass : SYSTEM_INFORMATION_CLASS;
          procedure SetSysInfoClass(aVal: SYSTEM_INFORMATION_CLASS);
      public
          constructor Create;
          destructor Destroy; override;
          function RefreshSysInfo:PVOID;      property SysInfo : PVOID read fSysInfo;
          property SysInfoClass : SYSTEM_INFORMATION_CLASS read fSysInfoClass write SetSysInfoClass;
      end;var
      Form1: TForm1;implementation{$R *.dfm}{ TQuerySystemInformation }{******************************************************************************}
    constructor TQuerySystemInformation.Create;
    begin
        //
        fSysInfoClass:=SystemBasicInformation;
    end;{******************************************************************************}
    destructor TQuerySystemInformation.Destroy;
    begin
        ReallocMem (fSysInfo, 0);
        inherited;
    end;{******************************************************************************}
    function TQuerySystemInformation.RefreshSysInfo: PVOID;
    const
      STATUS_INFO_LENGTH_MISMATCH =  NTSTATUS($C0000004);
    var
        rs,res : ULONG;
        rv:NTSTATUS;
        d:dword ; //fuck delphi
    begin    rs := $10000;    //d:=fSysInfoClass;    repeat
          ReallocMem (fSysInfo, rs);
          rv := NtQuerySystemInformation (fSysInfoClass, fSysInfo, rs, @res);
          rs := rs * 2;
        until rv <> STATUS_INFO_LENGTH_MISMATCH;    if rv <> 0 then
        begin
          ReallocMem (fSysInfo, 0);
          RaiseLastOSError
        end;    Result := fSysInfo;
    end;{******************************************************************************}
    procedure TQuerySystemInformation.SetSysInfoClass(aVal: SYSTEM_INFORMATION_CLASS);
    begin
        if aVal <> fSysInfoClass then
        begin
            fSysInfoClass := aVal;
            RefreshSysInfo;
        end;
    end;
    procedure TForm1.Button2Click(Sender: TObject);
    type
      HANDLE_INFORMATION = record
        count : ULONG;
        Handles : array [0..0] of SYSTEM_HANDLE_INFORMATION;
      end;
    var
      FQuery :  TQuerySystemInformation;
      Info:^HANDLE_INFORMATION;
      I:integer;
    begin
      FQuery := TQuerySystemInformation.Create ;
      FQuery.SysInfoClass := SystemHandleInformation;
      FQuery.RefreshSysInfo ;
      Info := FQuery.SysInfo ;
      for i:=0 to Info.count -1 do
      begin
        if Info^.Handles[i].ObjectTypeNumber = 28 then
          ListBox1.Items.Add( intToStr(Info^.Handles[i].Handle));
      end;
      FQuery.Free;
    end;end.另外文件句柄不是26,是28
      

  23.   

    soweb
     请教一下,你所用到的jwaNative,JwaWinType两位unit在哪有下载啊?我在编译的时候通不过.能否发一份到.cn,谢谢.