Конференция "WinAPI" » OPEN_IF для секции
 
  • LightRipple © (25.05.08 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 © (25.05.08 13:36) [1]

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

    InitializeObjectAttributes(@ObjectAttr, @ObjName, OBJ_OPENIF,  0, nil);
  • LightRipple © (25.05.08 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 © (25.05.08 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 © (25.05.08 15:39) [4]
    > [3] guav ©   (25.05.08 15:32)
    > Как показывает отладчик VS2005, вот такой успешный вызов

    Спасибо. Пойду изучать.
  • LightRipple © (25.05.08 15:42) [5]
    Стоп.
    А откуда там взялся "хендл RootDirectory" ?
    Мы же вызываем с нулевым hRoot.
  • Игорь Шевченко © (25.05.08 15:55) [6]

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


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

    Так и я там-же :). Только я указываю полный путь к объекту и родителя 0.
    Это что-ж получается ? Надо заводить глобальную переменную hBaseNamedObjects
    и во всех вызовах Nt ф-ий для секций использовать "Pareneted" объект ?
    Я правильно поняла ?
  • Игорь Шевченко © (25.05.08 16:15) [8]
    LightRipple ©   (25.05.08 16:00) [7]


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


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

    Придется попробовать работать с глобальным рутовым Handlе - ом.
    Правда, как-то "не смотрится" мне этот путь.
  • LightRipple © (25.05.08 17:32) [10]
    Вот нашла описание похожей проблеммы.
    Конечно не совсем то, что нужно, но мне кажется,
    что алгоритм отказа в доступе при повторном открытии, у меня имеет теже корни, что описываются в статье.
    http://support.microsoft.com/default.aspx?scid=kb;EN-US;Q228785
  • Игорь Шевченко © (25.05.08 23:19) [11]
    LightRipple ©   (25.05.08 17:32) [10]


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


    Казаться может все, что угодно, до тех пор, пока не будут приведены имя объекта, кто создает, кто открывает, с каким правами, и т.д.
  • LightRipple © (26.05.08 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);

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



    Не могу понять в чем дело.
  • Игорь Шевченко © (26.05.08 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;

  • Игорь Шевченко © (26.05.08 14:01) [16]
    OBJ_OPENIF для секции действительно не работает
  • LightRipple © (26.05.08 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 © (26.05.08 14:24) [18]

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


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

    Работает внутри CreateFileMapping
  • Игорь Шевченко © (26.05.08 17:09) [19]
    guav ©   (26.05.08 14:24) [18]


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


    Работает.
 
Конференция "WinAPI" » OPEN_IF для секции
Есть новые Нет новых   [134433   +22][b:0][p:0.003]