Q&A

  • 포인터로 (숫자)+(구조체 x N개)를 리턴 받았을때는 어떻게 읽어야하나요?
ntdll.dll의 비문서화 함수인 ZwQuerySystemInformation 함수를 이용해서 각종 시스템 핸들을 구해보려고 합니다.
그런데 리턴으로 오는 포인터 값의 형태가 '리턴되는 갯수 + 구조체 + 구조체 + 구조체 + ..... ' 이런 형태네요.
단순히 '구조체 + 구조체 + 구조체 + ....' 형태는 배열처럼 사용하면 된다고 알고 있습니다만,
이런 형태의 경우 어떻게 읽어야 하는지 모르겠습니다.
사실 리턴되는갯수도 정확히 읽는건지도 모르겠구요.. ^^;

<!--CodeS-->
const
  CONST_BASIC_QUERY_SIZE = 26000;
  CONST_ADD_QUERY_SIZE = 100;

procedure TForm1.Button1Click(Sender: TObject);
var
  nCount : integer;
  pInfo : PULONG;
  nHandles : ULONG;
  aHandles : PSYSTEM_HANDLE_INFORMATION;
begin
  nCount := CONST_BASIC_QUERY_SIZE;
  GetMem( pInfo, nCount * sizeof(SYSTEM_HANDLE_INFORMATION) + sizeof(ULONG));
  while ( ZwQuerySystemInformation(SystemHandleInformation, pInfo, nCount * sizeof(SYSTEM_HANDLE_INFORMATION) +
          sizeof(ULONG), 0) = STATUS_INFO_LENGTH_MISMATCH)  do
  begin
    freeMem(pInfo);
    nCount := nCount + CONST_ADD_QUERY_SIZE;
    GetMem( pInfo, nCount * sizeof(SYSTEM_HANDLE_INFORMATION) + sizeof(ULONG));
  end;

  nHandles :=   nHandles := pInfo^;  // <--- 리턴된 수는 이게 맞나요?
  aHandles := (PSYSTEM_HANDLE_INFORMATION) pInfo+1;  //  <- VC에서는 이렇게 읽던데 델파이에선 안 통하네요 ^^;;
<!--CodeE-->
1  COMMENTS
  • Profile
    최용일 2009.07.01 10:55
    크기는 맞는것같구요...
    저게 씨코드 그대로 변환한것이라면... 아래 둘중하나의 코드를 쓰세요.
    aHandles := PULONG(LongWord(pInfo) + SizeOf(ULONG));

    혹은
    aHandles := pInfo;
    Inc(PULONG(aHandle));

    위처럼 포인터를 쓰셔도 되지만... 배열을 이용하면 더 편리합니다.

    type
    T구조체 = packed record
    필드1: 데이터형1;
    필드n: 데이터형n;
    end;
    PSYSTEM_HANDLE_INFORMATION = ^TSYSTEM_HANDLE_INFORMATION;
    TSYSTEM_HANDLE_INFORMATION = packed record
    리턴되는갯수: 정수;
    구조체배열: array[0..0] of T구조체;
    end;

    var
    P: PSYSTEM_HANDLE_INFORMATION;
    begin
    for I := 0 to P.리턴되는갯수-1 do
    begin
    데이터1 := P.구조체배열[I].필드1;
    데이터n := p.구조체배열[I].필드n;
    DoSomething;
    end;
    end;