Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

OPEN_IF для секции


Страницы:   1 2 3

LightRipple ©   (2008-05-25 11:21:00) 

Здравствуйте !
Пытаюсь создавать секцию следующим образом:

InitializeObjectAttributes(@ObjectAttr, @ObjName, OBJ_CASE_INSENSITIVE, 0, nil);
Result := NtCreateSection(@hSection, SECTION_ALL_ACCESS, @ObjectAttr,
                         @SectionSize, PAGE_READWRITE, SEC_COMMIT, 0);

Все хорошо, кроме того, что если она (секция с таким же именем) уже
существует, то NtCreateSection возвращает STATUS_OBJECT_NAME_COLLISION (Object Name already exists),
что и не удивительно :), но при этом не возвращает Handle существующего объекта.
Как бы так исхитриться и заставить ее возвращать этот Handle ?
Вызывать NtOpenSection, при этой ошибке, считаю некузявым решением.
Ведь CreateFileMapping, в этом случае работает как надо.
В жизни не поверю, что она это делает через повторную попытку открытия объекта :)


LightRipple   (2008-05-30 16:56:00) [1]

> [43] Игорь Шевченко ©   (30.05.08 10:39)
> Спасибо тебе огромное!!!

Очень рада, что и от меня может быть польза :)

> [44] guav ©   (30.05.08 12:34)
> Кстати, с правильным OBJ_OPENIF не откроется ли оно кодом [0] ?

Проверила: все работает на ура.
(имеется ввиду использование имени с префиксом '\BaseNamedObjects' и нулевым парентом)
Т.е. нет необходимости в использовании NtOpenDirectoryObject :)


Игорь Шевченко   (2008-05-30 13:37:00) [2]

guav ©   (30.05.08 13:13) [46]


> Нет. Но у него больше пользователей и ошибок скорее меньше
> чем больше.


Охотно верю. Но у меня как бы тоже пользователей есть, а ошибка грубая. Однако ж никто, кроме Александры, не натолкнулся.


guav   (2008-05-30 13:13:00) [3]

> [45] Игорь Шевченко ©   (30.05.08 13:10)
> Можно подумать, ты святее Аллаха и ни разу не ошибаешься
> :)

Куда уж нам до Аллаха :)


> [45] Игорь Шевченко ©   (30.05.08 13:10)
> Можно подумать, что перевод Jedi гарантировано свободен
> от ошибок :)

Нет. Но у него больше пользователей и ошибок скорее меньше чем больше.


Игорь Шевченко   (2008-05-30 13:10:00) [4]

guav ©   (30.05.08 12:34) [44]

Можно подумать, ты святее Аллаха и ни разу не ошибаешься :)
Можно подумать, что перевод Jedi гарантировано свободен от ошибок :)


guav   (2008-05-30 12:34:00) [5]

> [43] Игорь Шевченко ©   (30.05.08 10:39)


> [42] LightRipple ©   (30.05.08 02:02)

Используйте перевод, используемый не только вами http://jedi-apilib.sourceforge.net/.
Или используйте С или С++ и копируйте из DDK напрямую.

Кстати, с правильным OBJ_OPENIF не откроется ли оно кодом [0] ?


Игорь Шевченко   (2008-05-30 10:39:00) [6]

LightRipple ©   (30.05.08 02:02) [42]

Спасибо тебе огромное!!!
Это ж и у меня так...


LightRipple   (2008-05-30 02:02:00) [7]

> [39] Игорь Шевченко ©   (29.05.08 11:37)
> [41] guav ©   (29.05.08 22:54)

Побитовое сравнение кода выявило "совсем маленькую" опечатку:
В моем проекте так определена константа: OBJ_OPENIF = 00000080;  

Я уж и не помню откуда я ее брала, копипастила или набивала вручную.

Как здорово, что мы не плюнули на это дело и довели его до конца !
И подумать страшно, на какие грабли бы я еще наступала
и какие бы делала выводы о работе, совсем ни в чем не виноватых, Nt-функций и системы :)

Спасибо мальчики ! Уря !


guav   (2008-05-29 22:54:00) [8]

Перевод API взят из Jedi Windows API, накопирован по минимуму, чтобы не было внешних ссылок.
Выводит
New section handle 00000FBC
Reopen
Reopen section handle 00000FB8


guav   (2008-05-29 22:50:00) [9]

Вот код. Могу для ясносит бинарник выслать.
program Project1;

{$APPTYPE CONSOLE}

uses
 Windows ,  SysUtils;

type
 PUNICODE_STRING = ^UNICODE_STRING;
 UNICODE_STRING = record
   Length: WORD;
   MaximumLength: WORD;
   Buffer: PWideChar;
 end;

 POBJECT_ATTRIBUTES = ^OBJECT_ATTRIBUTES;
 {$EXTERNALSYM POBJECT_ATTRIBUTES}
 OBJECT_ATTRIBUTES = record
   Length: ULONG;
   RootDirectory: THandle;
   ObjectName: PUNICODE_STRING;
   Attributes: ULONG;
   SecurityDescriptor: Pointer;
   SecurityQualityOfService: Pointer;
 end;

 NTSTATUS = Longint;

const
 STATUS_OBJECT_NAME_EXISTS  =   $40000000;
 OBJ_CASE_INSENSITIVE       =   $00000040;
 OBJ_OPENIF                 =   $00000080;
 DIRECTORY_TRAVERSE         =       $0002;
 DIRECTORY_CREATE_OBJECT    =       $0004;

function NT_SUCCESS(Status: NTSTATUS): Boolean;
begin
 Result := Status >= 0;
end;

procedure RtlInitUnicodeString(
 var DestinationString : UNICODE_STRING;
 SourceString : PWideChar); stdcall; external 'ntdll.dll';

function  NtCreateSection(
   SectionHandle : PHANDLE;
   DesiredAccess : ACCESS_MASK;
   ObjectAttributes : POBJECT_ATTRIBUTES;
   SectionSize : PLARGEINTEGER;
   Protect : ULONG;
   Attributes : ULONG;
   FileHandle : THandle
 ): NTSTATUS; stdcall; external 'ntdll.dll';

function  NtOpenDirectoryObject(
   DirectoryHandle : PHANDLE;
   DesiredAccess : ACCESS_MASK;
   ObjectAttributes : POBJECT_ATTRIBUTES
 ): NTSTATUS; stdcall; stdcall; external 'ntdll.dll';

procedure InitializeObjectAttributes(
 p: POBJECT_ATTRIBUTES;
 Name: PUNICODE_STRING;
 Attr: ULONG;
 Root: THandle;
 SD: Pointer);
begin
 p^.Length := SizeOf(OBJECT_ATTRIBUTES);
 p^.RootDirectory := Root;
 p^.Attributes := Attr;
 p^.ObjectName := Name;
 p^.SecurityDescriptor := SD;
 p^.SecurityQualityOfService := nil;
end;

procedure RaiseNtError(status: NTSTATUS);
begin
 raise EOSError.CreateFmt(
   'Nt error %.8x , i''m, too lazy to format it properly',
   [status]);
end;

function CreateorOpenSection(): THandle;
var
us, uss: UNICODE_STRING;
oa, oas: OBJECT_ATTRIBUTES;
status: NTSTATUS;
dir: THANDLE;
secsize: LARGE_INTEGER;
begin
RtlInitUnicodeString(us, '\BaseNamedObjects');
InitializeObjectAttributes(@oa, @us, OBJ_CASE_INSENSITIVE, 0, nil);
status := NtOpenDirectoryObject(@dir,
  DIRECTORY_TRAVERSE or DIRECTORY_CREATE_OBJECT, @oa);
if not NT_SUCCESS(status) then
  RaiseNtError(status);
try
  RtlInitUnicodeString(uss, 'AAASuperPuperSection');
  InitializeObjectAttributes(@oas, @uss, OBJ_OPENIF,
    dir, nil);
  secsize.QuadPart := $20000;
  status := NtCreateSection(@Result, SECTION_MAP_WRITE or SECTION_MAP_READ,
    @oas, @secsize, PAGE_READWRITE, SEC_COMMIT, 0);
  if not NT_SUCCESS(status) then
  begin
    RaiseNtError(status);
  end;
  if status = STATUS_OBJECT_NAME_EXISTS then
  begin
    WriteLn('Reopen');
  end;
finally
  CloseHandle(dir);
end;
end;

var H1, H2: THandle;
begin
 try
   H1 := CreateOrOpenSection();
   try
     WriteLn(Format('New section handle %.8x', [H1]));
     H2 := CreateOrOpenSection();
     try
       WriteLn(Format('Reopen section handle %.8x', [H2]));
     finally
       CloseHandle(H2);
     end;
   finally
     CloseHandle(H1);
   end;
 except
   on E: Exception do
     WriteLn('Error ', E.Message);
 end;
 ReadLn
end.


Игорь Шевченко   (2008-05-29 11:37:00) [10]


> P.S.
> А ntdll - ки могут быть разными ?


Нет. Если ты посмотришь реализацию Nt(Zw)CreateSection, то увидишь, что разницы никакой


LightRipple   (2008-05-29 03:12:00) [11]

> [37] LightRipple ©   (29.05.08 03:07)

P.S.
А ntdll - ки могут быть разными ?


LightRipple   (2008-05-29 03:07:00) [12]

> [35] Игорь Шевченко ©   (27.05.08 09:42)
> [36] guav ©   (27.05.08 09:46)

"Нда... - сказали мы с Петром Иванычем" (с) (Почти не измененная :)

Саш, у меня просьба:
не мог бы ты выложить здесь или выслать мне полный код, который "просто скопирован" (с убранным жирным)
и который выдает такие изумительные результаты ? :)

Интересует все: включая экспорт функций, объявления структур и
используемые "стандартные" ф-ии типа InitializeObjectAttributes.
Ну NT_SUCCESS, наверное, можно и не расписывать, хотя уже не знаю :)


guav   (2008-05-27 09:46:00) [13]

> [34] LightRipple ©   (27.05.08 02:19)

Нет. Код просто скопирован. работаю под локальным пользователем с правами администратора. первый запуск возвращает 0, далее STATUS_OBJECT_NAME_EXISTS, хендлы разные.


Игорь Шевченко   (2008-05-27 09:42:00) [14]

LightRipple ©   (27.05.08 02:19) [34]

У меня OBJ_OPENIF закомментирован. Именно этот флаг заставляет возвращать STATUS_OBJECT_NAME_EXISTS вместо STATUS_OBJECT_NAME_COLLISION в ObInsertObject


LightRipple   (2008-05-27 02:19:00) [15]

Проверила еще раз.

Код [15] Игорь Шевченко ©  с "убранным жирным"
при попытке второй раз открыть объект возвращает STATUS_OBJECT_NAME_COLLISION
и даже не думает возвращать Handle.

Что за мистика ? Ты случайно не в VS работаешь ? :)


LightRipple   (2008-05-27 02:11:00) [16]

>  [32] guav ©   (27.05.08 02:02)
> Хендл возвращает.

Так....
Перед тем как запостить я скопировала код и проверила у себя.
При попытке открыть уже существующий объект, его Handle у меня не возвращался. (Жирное убрано)
Пойду перепроверять, что я там напартачила :)


guav   (2008-05-27 02:02:00) [17]

> [31] LightRipple ©   (27.05.08 02:00)
> Так это все так и работало с самого начала и с таким же
> результатом :)
> Или у тебя еще и Handle уже существующего объекта возвращает
> ?

STATUS_OBJECT_NAME_EXISTS != STATUS_OBJECT_NAME_COLLISION.
STATUS_OBJECT_NAME_EXISTS не ошибка.
Хендл возвращает.


LightRipple   (2008-05-27 02:00:00) [18]

> [30] guav ©   (27.05.08 00:17)
> У меня код [15] работает. В смысле, NtCreateSection реально возращает STATUS_OBJECT_NAME_EXISTS и жирное убрано.

Так это все так и работало с самого начала и с таким же результатом :)
Или у тебя еще и Handle уже существующего объекта возвращает ?
Вопрос то сводится к тому, что можно ли одним вызовом NtCreateSection
либо создать объект либо открыть уже существующий.
Иными словами: заставить NtCreateSection работать в режиме "OPEN_IF".
Видимо нельзя, или какой-то хитрый момент что-то ускользает от нас.


guav   (2008-05-27 00:17:00) [19]

У меня код [15] работает. В смысле, NtCreateSection реально возращает STATUS_OBJECT_NAME_EXISTS и жирное убрано.


LightRipple   (2008-05-26 23:05:00) [20]

Я тоже чуть-чуть повозилась с этим делом.

При помощи NtQuerySystemInformation и NtQueryObject, мне удалось выцарапать хэндл BaseNamedObjectDirectory,
(заодно и ссылку на объект его содержащий. мало -ли понадобиться :)
Далее я попыталась использовать этот Handle как рутовый (не дупликатя, он же из моего процесса).
Все тоже самое: успешно создаем, успешно открываем, но спотыкаемся на OPEN_IF :(
Заодно (а чем черт не шутит) попробовала заменить Nt на Zw.
Как и ожидалось - чуда не произошло.

P.S.
Как еще можно попробовать извратиться ?
Или откладывать эту задачку с пометкой "нерешенная" ?


Страницы:   1 2 3

Наверх

Титульная страница Поиск, карта сайта Написать письмо