Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2009.06.28;
Скачать: [xml.tar.bz2];

Вниз

OPEN_IF для секции   Найти похожие ветки 

 
LightRipple ©   (2008-05-25 11:21) [0]

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

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


 
guav ©   (2008-05-25 13:36) [1]


> InitializeObjectAttributes(@ObjectAttr, @ObjName, OBJ_CASE_INSENSITIVE, 0, nil);

InitializeObjectAttributes(@ObjectAttr, @ObjName, OBJ_OPENIF,  0, nil);


 
LightRipple ©   (2008-05-25 15:08) [2]

> [1] guav ©   (25.05.08 13:36)
> InitializeObjectAttributes(@ObjectAttr, @ObjName, OBJ_OPENIF,  0, nil);

Саш, я так пробовала.
В этом случае, она начинает ругаться совсем нецензурно:
STATUS_PRIVILEGE_NOT_HELD (A required privilege is not held by the client)

Может, надо создавать объект не с "ниловым" дескриптором безопасности ?
Но, CreateFileMapping - у, плевать на этот дескриптор. Я тоже хочу на него плевать :)


 
guav ©   (2008-05-25 15:32) [3]

Как показывает отладчик VS2005, вот такой успешный вызов
 CreateFileMapping(INVALID_HANDLE_VALUE,
   0,
   PAGE_READWRITE,
   0,
   4096,
   _T("Hello"));

Сводится к успешному (результат STATUS_OBJECT_NAME_EXISTS вызову ZwCreateSection с такими вот параметрами:
0x000f0007 - DesiredAccess
ObjectAttributes - содержит имя Hello и хендл RootDirectory, флаг OBJ_OPENIF, секьюрити нет.
0x00000004 - SectionPageProtection
0x08000000 - AllocationAttributes
0x00000000 - FileHandle


 
LightRipple ©   (2008-05-25 15:39) [4]

> [3] guav ©   (25.05.08 15:32)
> Как показывает отладчик VS2005, вот такой успешный вызов

Спасибо. Пойду изучать.


 
LightRipple ©   (2008-05-25 15:42) [5]

Стоп.
А откуда там взялся "хендл RootDirectory" ?
Мы же вызываем с нулевым hRoot.


 
Игорь Шевченко ©   (2008-05-25 15:55) [6]


> А откуда там взялся "хендл RootDirectory" ?


A CreateFileMapping создает объекты в подкаталоге BaseNamedObjects ;)


 
LightRipple ©   (2008-05-25 16:00) [7]

>  [6] Игорь Шевченко ©   (25.05.08 15:55)
> A CreateFileMapping создает объекты в подкаталоге BaseNamedObjects ;)

Так и я там-же :). Только я указываю полный путь к объекту и родителя 0.
Это что-ж получается ? Надо заводить глобальную переменную hBaseNamedObjects
и во всех вызовах Nt ф-ий для секций использовать "Pareneted" объект ?
Я правильно поняла ?


 
Игорь Шевченко ©   (2008-05-25 16:15) [8]

LightRipple ©   (25.05.08 16:00) [7]


> Так и я там-же :). Только я указываю полный путь к объекту
> и родителя 0.
> Это что-ж получается ? Надо заводить глобальную переменную
> hBaseNamedObjects
> и во всех вызовах Nt ф-ий для секций использовать "Pareneted"
> объект ?
> Я правильно поняла ?


Да, именно так. Разборщик имени не занимается сложными выкладками и пытается создать объект с именем "BaseNamedObjects\Foo" в корневом каталоге.


 
LightRipple ©   (2008-05-25 16:24) [9]

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

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


 
LightRipple ©   (2008-05-25 17:32) [10]

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


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

LightRipple ©   (25.05.08 17:32) [10]


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


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


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

> [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-26 10:23) [13]

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


 
LightRipple ©   (2008-05-26 12:57) [14]

> [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 14:00) [15]

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

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;


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

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


 
LightRipple ©   (2008-05-26 14:14) [17]

> [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, это две разницы :)


 
guav ©   (2008-05-26 14:24) [18]


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


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

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


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

guav ©   (26.05.08 14:24) [18]


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


Работает.


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

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


 
LightRipple ©   (2008-05-26 17:49) [21]

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

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


 
LightRipple ©   (2008-05-26 17:53) [22]

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


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

LightRipple ©   (26.05.08 17:49) [21]

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


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


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

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


 
guav ©   (2008-05-26 18:07) [24]

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

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


 
LightRipple ©   (2008-05-26 18:09) [25]

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

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

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

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


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

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

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


 
guav ©   (2008-05-26 18:38) [27]

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


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

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) - не хватает прав.

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


 
LightRipple ©   (2008-05-26 23:05) [29]

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

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

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


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

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


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

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

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


 
guav ©   (2008-05-27 02:02) [32]

> [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:11) [33]

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

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


 
LightRipple ©   (2008-05-27 02:19) [34]

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

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

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


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

LightRipple ©   (27.05.08 02:19) [34]

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


 
guav ©   (2008-05-27 09:46) [36]

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

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


 
LightRipple ©   (2008-05-29 03:07) [37]

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

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

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

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


 
LightRipple ©   (2008-05-29 03:12) [38]

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

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


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


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


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


 
guav ©   (2008-05-29 22:50) [40]

Вот код. Могу для ясносит бинарник выслать.
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.


 
guav ©   (2008-05-29 22:54) [41]

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


 
LightRipple ©   (2008-05-30 02:02) [42]

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

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

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

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

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


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

LightRipple ©   (30.05.08 02:02) [42]

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


 
guav ©   (2008-05-30 12:34) [44]

> [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 13:10) [45]

guav ©   (30.05.08 12:34) [44]

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


 
guav ©   (2008-05-30 13:13) [46]

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

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


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

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


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

guav ©   (30.05.08 13:13) [46]


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


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


 
LightRipple ©   (2008-05-30 16:56) [48]

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

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

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

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



Страницы: 1 2 вся ветка

Форум: "WinAPI";
Текущий архив: 2009.06.28;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.62 MB
Время: 0.006 c
4-1212106372
San1712
2008-05-30 04:12
2009.06.28
Как произвести чтение/запись в определённый кластер ?


8-1194440058
T54
2007-11-07 15:54
2009.06.28
Склеивание видеофайла


2-1241679348
worldmen
2009-05-07 10:55
2009.06.28
Создать большое меню


4-1211954383
TForumHelp
2008-05-28 09:59
2009.06.28
Навигация по MainMenu чужого приложения


9-1180224380
TTerrain
2007-05-27 04:06
2009.06.28
Сфероид на поверхности Как его разместить равноудалённым от конта





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский