Q&A

  • Visual C -> Delphi 포팅을 잘못 한것 같습니다.
윈도우의 각종 mutent들의 핸들 목록을 보기 위해 노력하던중
NtOpenDirectoryObject 등의 비공식윈도우 함수들의 존재를 알게 되었습니다.
그러나 예제는 Visual C로 되어 있는데, 제게 VC와 필수요소라고 하는 DDK가 없어서 방법을 찾던중
JEDI-API ( http://jedi-apilib.sourceforge.net/ ) 를 알게되어 헤더파일을 설치하고
예제로 되어 있는 VC코드를 델파이로 최대한 포팅한다고 해봤습니다.

그러나 예상과는, 아래 입력할 소스의 마지막 함수 NtQueryDirectoryObject 함수 호출 결과가 성공인데도, 정확한 이름이 들어있지 않습니다.
아마도 제가 VC코드를 델파이로 옮기는 방법을 정확히 몰라, 잘못 옮긴것이 아닌가 생각합니다.

소스를 보시고 잘못된 부분을 지적해 주시면 감사하겠습니다.
원VC소스의 링크는 http://www.ddj.com/database/184416468?pgno=5 (헤더파일 : 여타 함수선언은 JEDI-API에 되어 있어서 제일 상단 구조체 하나만 델파이 pas에 포함했습니다)
http://www.ddj.com/database/184416468?pgno=6 (VC소스) 이고,
첨부파일로 제가 포팅한 전체 소스를 첨부하도록 하겠습니다.
pas파일 전체 길이가 160줄이라, 보시기에 아주 많은 시간이 소요되지는 않을꺼라 생각됩니다만,
JEDI-API가 설치되어 있어야 컴파일 할 수 있습니다.

원본일부입니다.
<!--CodeS-->
void DumpAllObjects(WCHAR *pszDir)
{
  HANDLE hObj, hLink;
  NTSTATUS ntStatus, ntStatusTmp;
  OBJECT_ATTRIBUTES ObjectAttributes;
  POBJDIR_INFORMATION DirObjInformation;
  UNICODE_STRING UName;
  char szData[1024*2];
  char szBuf[1024*2];
  WCHAR szLinkName[1024];
  ULONG dw;
  char szIdentBuf[100];
  ULONG index;
  static int iLevel = 0;

  // set indent of current level

  memset(szIdentBuf, ' ', iLevel * 3);
  szIdentBuf[iLevel * 3] = 0;

  // open directory object

  RtlInitUnicodeString(&UName, pszDir);

  InitializeObjectAttributes ( &ObjectAttributes, &UName, OBJ_CASE_INSENSITIVE,  NULL,  NULL );

  ntStatus = NtOpenDirectoryObject( &hObj, STANDARD_RIGHTS_READ |  DIRECTORY_QUERY, &ObjectAttributes);

  if(NT_SUCCESS(ntStatus))
  {
    index = 0; // start index
    
    do
    {
      memset(szData, 0, sizeof(szData));
      DirObjInformation = (POBJDIR_INFORMATION)&szData;
      ntStatus = NtQueryDirectoryObject( hObj, DirObjInformation, sizeof(szData),  TRUE, FALSE, &index, &dw);         // can be NULL
<!--CodeE-->

포팅한것 중 일부입니다.
<!--CodeS-->
procedure TForm1.DumpAllObjects(var pszDir : PWChar);
var
  hObj, hLink : THandle;
  ntStatus1 : NTSTATUS;
  ntStatusTmp : NTSTATUS;
  ObjectAttributes : OBJECT_ATTRIBUTES;
  DirObjInformation : POBJDIR_INFORMATION;
  UName : UNICODE_STRING;
  szData : array[0..2048] of char;
  szBuf : array[0..2048] of WCHAR;
  szLinkName : array[0..1024] of WChar;
  dw : ULONG;
  szIdentBuf : array[0..100] of char;
  index : ULong;

  iLevel : integer;
  pszBuf : PWChar;
begin
  iLevel := 0;

  FillChar(szIdentBuf, iLevel * 3, ' ');
  szIdentBuf[iLevel * 3] := char(0);

  RtlInitUnicodeString( @UName, pszDir);
  InitializeObjectAttributes( @ObjectAttributes, @UName, OBJ_CASE_INSENSITIVE, 0, nil);
  ntStatus1 := NtOpenDirectoryObject( @hObj, STANDARD_RIGHTS_READ or DIRECTORY_QUERY, @ObjectAttributes);

//  if NT_SUCCESS(ntStatus1) = True then
  if ntStatus1 = 0 then
  begin
    index := 0;
    repeat
      FillChar(szData, sizeof(szData), ' ');
      DirObjInformation := POBJDIR_INFORMATION(@szData);
      ntStatus1 := NtQueryDirectoryObject( hObj, DirObjInformation, sizeof(szData), True, False, @index, @dw);
<!--CodeE-->
0  COMMENTS