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, в этом случае работает как надо.
В жизни не поверю, что она это делает через повторную попытку открытия объекта :)


Игорь Шевченко   (2008-05-26 20:41:00) [21]

guav ©   (26.05.08 18:07) [24]


> Лучше студийным, он больше имён расшифрует.


Это у тебя символы установлены или ссылка в отладчике есть, откуда их тянуть.


> где для хендла папки папки вызывается BaseGetNamedObjectDirectory,
>  где он берётся из глобальной переменной BaseNamedObjectDirectory.
>


Которая заполняется при первом вызове BaseFormatObjectAttributes или раньше, которая берет имя из того, что kernel32.dll получает из разделяемых данных csrss, которые формируются при инициализации CSRSRV.DLL, которую загружает csrss.exe при каждом вызове из smss.exe в доме, который построил Джек.


> А где прописана эта глобальная переменная BaseNamedObjectDirectory
> ?


В kernel32.dll - это его глобальная переменная.

Я что хочу сказать - я попытался воспроизвести все вызовы, которые выполняет CreateFileMappingW, включая открытие каталога BaseNamedObjects, но все равно, при NtCreateSection (от ZwCreateSection отличается только первыми двумя буквами) я получаю при указании OBJ_OPENIF тот самый статус ($C0000061) - не хватает прав.

То ли я где-то что-то пропускаю, то ли не в тот момент вызываю, но факт.


guav   (2008-05-26 18:38:00) [22]

в ntdll.dll.
Я не думаю что есть лёгкие пути достать её, кроме как через .pdb или закодировав смещение относително чего-то ещё в ntdll.


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

> [24] guav ©   (26.05.08 18:07)
> Лучше студийным, он больше имён расшифрует.
> Формирование OBJECT_ATTRIBUTES происходит в BaseFormatObjectAttributes,
> где для хендла папки папки вызывается BaseGetNamedObjectDirectory,
> где он берётся из глобальной переменной BaseNamedObjectDirectory.

А где прописана эта глобальная переменная BaseNamedObjectDirectory ?


LightRipple   (2008-05-26 18:09:00) [24]

> [23] Игорь Шевченко ©   (26.05.08 17:58)
> в [3] написано, что их нету, дескрипторов.

Там написано, что нет секьюрити для открываемой нами секции,
а я имела ввиду при открытии рутового объекта (BaseNamedObjects).

> я бы плюнул и вызывал NtOpenSection (соответственно, убрав OBJ_OPENIF из ObjectAttributes при CreateSection)

Плюнуть, конечно можно. Но это означает, что я чего-то (вполне возможно очень важного)
не понимаю. И где гарантия, что в другом месте, при работе с другими функциями,
я не столкнусь с этой же проблеммой.
Например, при работе с NtCreateMutant ?


guav   (2008-05-26 18:07:00) [25]

> [23] Игорь Шевченко ©   (26.05.08 17:58)
> Если хочется помучиться, то достаточно Delphi'йским отладчиком
> пройтись по CreateFileMappingW

Лучше студийным, он больше имён расшифрует.
Формирование OBJECT_ATTRIBUTES происходит в BaseFormatObjectAttributes, где для хендла папки папки вызывается BaseGetNamedObjectDirectory, где он берётся из глобальной переменной BaseNamedObjectDirectory.


Игорь Шевченко   (2008-05-26 17:58:00) [26]

LightRipple ©   (26.05.08 17:49) [21]

А там прав на каталог больше чем $0002000F все равно нету.


> Может нужна какая-то хитрая подготовка для SecurityDescriptor
> - а ?


в [3] написано, что их нету, дескрипторов.

Если хочется помучиться, то достаточно Delphi'йским отладчиком пройтись по CreateFileMappingW, я бы плюнул и вызывал NtOpenSection (соответственно, убрав OBJ_OPENIF из ObjectAttributes при CreateSection)


LightRipple   (2008-05-26 17:53:00) [27]

Может нужна какая-то хитрая подготовка для SecurityDescriptor - а ?


LightRipple   (2008-05-26 17:49:00) [28]

> [20] Игорь Шевченко ©   (26.05.08 17:16)
> Сдается мне, что они каталог BaseNamedObjects открывают с иными правами, нежели я или код в посте [14]

Я пробовала "методом научного тыка" менять права - у меня не получилось :(


Игорь Шевченко   (2008-05-26 17:16:00) [29]

Сдается мне, что они каталог BaseNamedObjects открывают с иными правами, нежели я или код в посте [14]


Игорь Шевченко   (2008-05-26 17:09:00) [30]

guav ©   (26.05.08 14:24) [18]


> Работает внутри CreateFileMapping


Работает.


guav   (2008-05-26 14:24:00) [31]


> [16] Игорь Шевченко ©   (26.05.08 14:01)


> OBJ_OPENIF для секции действительно не работает

Работает внутри CreateFileMapping


LightRipple   (2008-05-26 14:14:00) [32]

> [15] Игорь Шевченко ©   (26.05.08 14:00)
> А так не проще ?

Игорь, конечно, проще, но
[0] LightRipple ©  
"Вызывать NtOpenSection, при этой ошибке, считаю некузявым решением.
Ведь CreateFileMapping, в этом случае работает как надо.
В жизни не поверю, что она это делает через повторную попытку открытия объекта :)"

> [16] Игорь Шевченко ©   (26.05.08 14:01)
> OBJ_OPENIF для секции действительно не работает

Уж очень хочется понять почему и как с этим бороться.
Если я правильно поняла [3] guav ©,
то CreateFileMapping обходится одним вызовом ZwCreateSection. Я тож так хочу :)

Правда, исходя из
"Note  If the call to this function occurs in user mode,
you should use the name "NtCreateSection" instead of "ZwCreateSection"."  (MSDN)
можно предположить, что ZwCreateSection и NtCreateSection, это две разницы :)


Игорь Шевченко   (2008-05-26 14:01:00) [33]

OBJ_OPENIF для секции действительно не работает


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

А так не проще ?

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_CASE_INSENSITIVE{ or OBJ_OPENIF},
     dir, nil);
   secsize.QuadPart := $20000;
   status := NtCreateSection(@FSection, SECTION_MAP_WRITE or SECTION_MAP_READ,
     @oas, @secsize, PAGE_READWRITE, SEC_COMMIT, 0);
   if status = STATUS_OBJECT_NAME_COLLISION then
     status := NtOpenSection(@FSection, SECTION_MAP_WRITE or SECTION_MAP_READ,
       @oas);

   if not NT_SUCCESS(status) then
   begin
     FSection := 0;
     RaiseNtError(status);
   end
 finally
   NtClose(dir);
 end;
end;


LightRipple   (2008-05-26 12:57:00) [35]

> [13] Игорь Шевченко ©   (26.05.08 10:23)
> Я все понимаю, а почему нельзя сделать, как Коран велит ?
> NtOpenDirectoryObject, получить Handle, передать его в objectAttributes.RootDirectory, вызвать NtCreateSection

Пытаюсь, да вот выскакивает та же самая ошибка в том же самом месте:

function Dbg_NtCreateSectionReopen(const pObjName: PWideChar; const DesAccess: ACCESS_MASK; const ReopenObjAttr: DWord): NTSTATUS;
const
RootDir = '\BaseNamedObjects';
var
ObjectAttr: OBJECT_ATTRIBUTES;
RootName, ObjName: UNICODE_STRING;
SectionSize: Int64;
hDirObj, hBaseHandle, hTmpHandle: THandle;
begin
SectionSize := 4096;
RtlInitUnicodeString(@RootName, RootDir);
InitializeObjectAttributes(@ObjectAttr, @RootName, OBJ_CASE_INSENSITIVE, 0, nil);
Result := NtOpenDirectoryObject(@hDirObj, DesAccess, @ObjectAttr);
if NT_SUCCESS(Result) then
 try
  RtlInitUnicodeString(@ObjName, pObjName);
  InitializeObjectAttributes(@ObjectAttr, @ObjName, OBJ_CASE_INSENSITIVE, hDirObj, nil);
  Result := NtCreateSection(@hBaseHandle, SECTION_ALL_ACCESS, @ObjectAttr,
                            @SectionSize, PAGE_READWRITE, SEC_COMMIT, 0);
  if NT_SUCCESS(Result) then
   try
    Result := NtOpenSection(@hTmpHandle, SECTION_ALL_ACCESS, @ObjectAttr);
    if NT_SUCCESS(Result) then
     begin
      NtClose(hTmpHandle);
      hTmpHandle := 0;
      ShowMessage('NtOpenSection --> Success');
      InitializeObjectAttributes(@ObjectAttr, @ObjName, OBJ_CASE_INSENSITIVE or ReopenObjAttr, hDirObj, nil);
      Result := NtCreateSection(@hTmpHandle, SECTION_ALL_ACCESS, @ObjectAttr,
                                @SectionSize, PAGE_READWRITE, SEC_COMMIT, 0);
      if NT_SUCCESS(Result)
       then NtClose(hTmpHandle)
       else ShowMessage('Second NtCreateSection  Handle: ' + IntToStr(hTmpHandle) + sLineBreak +                                        SysErrorMessage(RtlNtStatusToDosError(Result)));
     end
    else ShowMessage('NtOpenSection' + sLineBreak + SysErrorMessage(RtlNtStatusToDosError(Result)));
   finally
    NtClose(hBaseHandle);
   end
  else ShowMessage('First NtCreateSection' + sLineBreak + SysErrorMessage(RtlNtStatusToDosError(Result)));
 finally
  Result := NtClose(hDirObj);
 end;
end;


Вызов:

DesAccess := FILE_LIST_DIRECTORY or FILE_ADD_SUBDIRECTORY;//FILE_ANY_ACCESS;
ReopenObjAttr := OBJ_OPENIF;// OBJ_CASE_INSENSITIVE; // OBJ_INHERIT
RetStatus := Dbg_NtCreateSectionReopen(SectionGUID, DesAccess, ReopenObjAttr);


Не могу понять в чем дело.


Игорь Шевченко   (2008-05-26 10:23:00) [36]

Я все понимаю, а почему нельзя сделать, как Коран велит ?
NtOpenDirectoryObject, получить Handle, передать его в objectAttributes.RootDirectory, вызвать NtCreateSection


LightRipple   (2008-05-26 00:17:00) [37]

> [11] Игорь Шевченко ©   (25.05.08 23:19)
> Казаться может все, что угодно, до тех пор, пока не будут приведены имя объекта,
> кто создает, кто открывает, с каким правами, и т.д.

Вот набросала примерный код:
function Dbg_NtCreateSectionReopen(const pObjName: PWideChar; const ReopenObjAttr: DWord): NTSTATUS;
var
ObjectAttr: OBJECT_ATTRIBUTES;
ObjName: UNICODE_STRING;
SectionSize: Int64;
hBaseHandle, hTmpHandle: THandle;
begin
SectionSize := 4096;
RtlInitUnicodeString(@ObjName, pObjName);
InitializeObjectAttributes(@ObjectAttr, @ObjName, OBJ_CASE_INSENSITIVE, 0, nil);
Result := NtCreateSection(@hBaseHandle, SECTION_ALL_ACCESS, @ObjectAttr,
                          @SectionSize, PAGE_READWRITE, SEC_COMMIT, 0);
if NT_SUCCESS(Result) then
 try
  Result := NtOpenSection(@hTmpHandle, SECTION_ALL_ACCESS, @ObjectAttr);
  if NT_SUCCESS(Result) then
   begin
    NtClose(hTmpHandle);
    hTmpHandle := 0;
    ShowMessage('NtOpenSection --> Success');
    InitializeObjectAttributes(@ObjectAttr, @ObjName, ReopenObjAttr, 0, nil);
    Result := NtCreateSection(@hTmpHandle, SECTION_ALL_ACCESS, @ObjectAttr,
                              @SectionSize, PAGE_READWRITE, SEC_COMMIT, 0);
    if NT_SUCCESS(Result)
     then NtClose(hTmpHandle)
     else ShowMessage('Second NtCreateSection  Handle: ' + IntToStr(hTmpHandle) +
                     sLineBreak + SysErrorMessage(RtlNtStatusToDosError(Result)));
   end
  else ShowMessage('NtOpenSection' + sLineBreak + SysErrorMessage(RtlNtStatusToDosError(Result)));
 finally
  NtClose(hBaseHandle);
 end
else ShowMessage('First NtCreateSection' + sLineBreak + SysErrorMessage(RtlNtStatusToDosError(Result)));
end;


А вот вызов:
ReopenObjAttr: DWord;
RetStatus: NTSTATUS;
const
SectionGUID = 'My_TestSection__5EB57840-10D4-4738-9912-CF3D74D05B88';
begin
ReopenObjAttr := OBJ_OPENIF;// OBJ_CASE_INSENSITIVE; // OBJ_INHERIT
RetStatus := Dbg_NtCreateSectionReopen('\BaseNamedObjects\' + SectionGUID, ReopenObjAttr);


Игорь Шевченко   (2008-05-25 23:19:00) [38]

LightRipple ©   (25.05.08 17:32) [10]


> Вот нашла описание похожей проблеммы.
> Конечно не совсем то, что нужно, но мне кажется


Казаться может все, что угодно, до тех пор, пока не будут приведены имя объекта, кто создает, кто открывает, с каким правами, и т.д.


LightRipple   (2008-05-25 17:32:00) [39]

Вот нашла описание похожей проблеммы.
Конечно не совсем то, что нужно, но мне кажется,
что алгоритм отказа в доступе при повторном открытии, у меня имеет теже корни, что описываются в статье.
http://support.microsoft.com/default.aspx?scid=kb;EN-US;Q228785


LightRipple   (2008-05-25 16:24:00) [40]

> [8] Игорь Шевченко ©   (25.05.08 16:15)
> Да, именно так. Разборщик имени не занимается сложными выкладками и пытается создать
> объект с именем 'BaseNamedObjects\Foo' в корневом каталоге.

Придется попробовать работать с глобальным рутовым Handlе - ом.
Правда, как-то "не смотрится" мне этот путь.


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

Наверх

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