-
Здравствуйте ! Пытаюсь создавать секцию следующим образом:
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, в этом случае работает как надо. В жизни не поверю, что она это делает через повторную попытку открытия объекта :)
-
> InitializeObjectAttributes(@ObjectAttr, @ObjName, OBJ_CASE_INSENSITIVE, 0, nil);
InitializeObjectAttributes(@ObjectAttr, @ObjName, OBJ_OPENIF, 0, nil);
-
> [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 - у, плевать на этот дескриптор. Я тоже хочу на него плевать :)
-
Как показывает отладчик 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
-
> [3] guav © (25.05.08 15:32) > Как показывает отладчик VS2005, вот такой успешный вызов
Спасибо. Пойду изучать.
-
Стоп. А откуда там взялся "хендл RootDirectory" ? Мы же вызываем с нулевым hRoot.
-
> А откуда там взялся "хендл RootDirectory" ?
A CreateFileMapping создает объекты в подкаталоге BaseNamedObjects ;)
-
> [6] Игорь Шевченко © (25.05.08 15:55) > A CreateFileMapping создает объекты в подкаталоге BaseNamedObjects ;)
Так и я там-же :). Только я указываю полный путь к объекту и родителя 0. Это что-ж получается ? Надо заводить глобальную переменную hBaseNamedObjects и во всех вызовах Nt ф-ий для секций использовать "Pareneted" объект ? Я правильно поняла ?
-
LightRipple © (25.05.08 16:00) [7]
> Так и я там-же :). Только я указываю полный путь к объекту > и родителя 0. > Это что-ж получается ? Надо заводить глобальную переменную > hBaseNamedObjects > и во всех вызовах Nt ф-ий для секций использовать "Pareneted" > объект ? > Я правильно поняла ?
Да, именно так. Разборщик имени не занимается сложными выкладками и пытается создать объект с именем 'BaseNamedObjects\Foo' в корневом каталоге.
-
> [8] Игорь Шевченко © (25.05.08 16:15) > Да, именно так. Разборщик имени не занимается сложными выкладками и пытается создать > объект с именем 'BaseNamedObjects\Foo' в корневом каталоге.
Придется попробовать работать с глобальным рутовым Handlе - ом. Правда, как-то "не смотрится" мне этот путь.
-
-
LightRipple © (25.05.08 17:32) [10]
> Вот нашла описание похожей проблеммы. > Конечно не совсем то, что нужно, но мне кажется
Казаться может все, что угодно, до тех пор, пока не будут приведены имя объекта, кто создает, кто открывает, с каким правами, и т.д.
-
> [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; RetStatus := Dbg_NtCreateSectionReopen('\BaseNamedObjects\' + SectionGUID, ReopenObjAttr);
-
Я все понимаю, а почему нельзя сделать, как Коран велит ? NtOpenDirectoryObject, получить Handle, передать его в objectAttributes.RootDirectory, вызвать NtCreateSection
-
> [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; ReopenObjAttr := OBJ_OPENIF; RetStatus := Dbg_NtCreateSectionReopen(SectionGUID, DesAccess, ReopenObjAttr); Не могу понять в чем дело.
-
А так не проще ? 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,
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;
-
OBJ_OPENIF для секции действительно не работает
-
> [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, это две разницы :)
-
> [16] Игорь Шевченко © (26.05.08 14:01)
> OBJ_OPENIF для секции действительно не работает
Работает внутри CreateFileMapping
-
guav © (26.05.08 14:24) [18]
> Работает внутри CreateFileMapping
Работает.
|