Конференция "Основная" » Алгоритм создания "многоступенчатого" ключа.
 
  • LightRipple © (16.05.08 09:17) [0]
    Здравствуйте !
    Допустим мы хотим создать такой ключ в реестре:
    Level_0\Level_1\Level_2\...\Level_N, причем мы не знаем
    существует ли уже какой нибудь Level_0\...\Level_k или нет.
    И есть у нас функция NtCreateKey.
    Но она (вот такая негодяйка) при любом из двух возможных способов
    задания имени (либо полный путь, либо короткий и ParentHandle) создает
    только ключ у которого уже есть родитель.
    Т.е. если существует ключ Level_0, то Level_0\Level_1 она создаст,
    а вот Level_0\Level_1\Level_2 - откажется.

    Итак, имеем: нам надо создать Level_0\Level_1\Level_2\...\Level_N
    Как лучше идти:
    начинать с первого ключа и спускаться к последнему
    или пытаться создать сразу весь, а при ошибке STATUS_OBJECT_NAME_NOT_FOUND
    подниматься на уровень выше ?
    Может есть другие способы, не занимающиеся перебором ?

    P.S.
    ReactOS - овцы пошли вторым путем, но что-то он мне "не кажется" :)
    P.P.S.
    Пыталась посмотреть как поступает RegCreateKeyExW, но так и не смогла
    понять каким путем идет она.
  • clickmaker © (16.05.08 09:40) [1]
    > или пытаться создать сразу весь, а при ошибке STATUS_OBJECT_NAME_NOT_FOUN
    > D
    > подниматься на уровень выше ?

    я бы это выбрал
  • LightRipple © (16.05.08 12:36) [2]
    > [1] clickmaker ©   (16.05.08 09:40)
    > я бы это выбрал

    Ага, я тоже пришла к этому.
    При ближайшем рассмотрении, первый способ оказался не очень правильным.
    Он не сработает если в середине цепочки встретиться ключ, в котором нам запрещено
    создавать подключи. А вот второй успешно с этим справится :)
  • Anatoly Podgoretsky © (16.05.08 19:17) [3]
    LightRipple - это постриженая Ripple
    Или похудевшая?
  • LightRipple © (16.05.08 20:06) [4]
    > [3] Anatoly Podgoretsky ©   (16.05.08 19:17)
    > LightRipple - это постриженая Ripple
    > Или похудевшая?

    Не "постриженная", а совсем совсем другой человек :)
    Вот только не похудевшая, ибо некуда. Как была спичкой так и осталась :)
  • Anatoly Podgoretsky © (16.05.08 21:52) [5]
    > LightRipple  (16.05.2008 20:06:04)  [4]

    Я что то про стрижку в форуме слышал.
    Но с другой стороны после стрижки это точно что другой человек.

    Так и запишем, другой не худой человек.
  • Игорь Шевченко © (16.05.08 22:48) [6]
    LightRipple ©   (16.05.08 20:06) [4]

    Теперь ждем чудес с реестром ? :)
  • guav © (17.05.08 00:12) [7]
    Оффтоп, но Riply бы это заинтересовало...
    C реестром интереснее работать на 64разрядной Windows, там их два - WOWовский и настоящий.
  • Германн © (17.05.08 00:59) [8]

    > LightRipple ©   (16.05.08 20:06) [4]
    >
    > > [3] Anatoly Podgoretsky ©   (16.05.08 19:17)
    > > LightRipple - это постриженая Ripple
    > > Или похудевшая?
    >
    > Не "постриженная", а совсем совсем другой человек :)
    >

    Верю. Ибо сей ник абсолютно безупречен с точки зрения английского.

    P.S. Но кое что общее есть. Оба автора женского пола. Оба автора не являются по своим знаниям явными новичками. Но оба автора не стесняются задавать свои вопросы в "Начинающим".
  • Германн © (17.05.08 02:16) [9]
    Хм. Я был не совсем прав. Сей вопрос был задан в "Общее".
  • LightRipple © (17.05.08 09:46) [10]
    > [6] Игорь Шевченко © (16.05.08 22:48)
    > Теперь ждем чудес с реестром ? :)

    Чудеса делает Microsoft.
    Мы же, простые смертные, только пытаемся понять их высшее предназначение :)  

    > [7] guav © (17.05.08 00:12)
    > Оффтоп, но Riply бы это заинтересовало...
    > C реестром интереснее работать на 64разрядной Windows, там их два - WOWовский и настоящий.

    "Как прикажешь тебя понимать, Саид ?"
    От того, с чем я сейчас пытаюсь работать, в самом ближайшем будущем (всемирном переходе на 64),
    останется один муляж ? Если это так, то не стоит и браться :(
    Поясни, пожалуйста.


    > [8] Германн © (17.05.08 00:59)
    > Верю. Ибо сей ник абсолютно безупречен с точки зрения английского.

    Мы, дважды на грабли не наступаем ! (Ну... пытаемся не наступать :)

    > P.S. Но кое что общее есть.
    > Но оба автора не стесняются задавать свои вопросы в "Начинающим".

    "Начинающим" - самая лучшая ветка. Там с тебя все "взятки гладки" :)
    Можно не опасаться, что несешь чушь в вопросе.
    Остальные же ветки к чему-то да обязывают :)
    Да и разъяснение "на пальцах" больше шансов получить в "Начинающих" :)
  • guav © (17.05.08 13:40) [11]
    > [10] LightRipple ©   (17.05.08 09:46)
    > От того, с чем я сейчас пытаюсь работать, в самом ближайшем
    > будущем (всемирном переходе на 64),
    > останется один муляж ? Если это так, то не стоит и браться
    > :(

    Я не сильно глубоко копал это, поэтому просто опишу с чем столкнулся. Здесь пойдёт речь о 64-разрядной ХР для архитектуры x64. Будем окрывать реестр через RegCreateKeyExW.

    Для 32разрядного приложения при получении через ключ HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion значения ProgramFilesDir, будет возвращено C:\Program Files (x86)
    Если то же приложение скомпилить как 64разрядное, результат будет C:\Program Files.
    Задавая KEY_WOW64_64KEY при открытии ключа, можно добиться C:\Program Files для обоих версий ехе.
    Задавая KEY_WOW64_32KEY при открытии ключа, можно добиться C:\Program Files (x86) для обоих версий ехе.

    Соответственно у функций вроде SHGetFolderPath результат зависит от разрядности приложения. Но если бы там внутри задавалось KEY_WOW64_64KEY или KEY_WOW64_32KEY, то не зависил бы (можно убедится перехватом функций advapi32.dll, я проверял на 32разрядной shell32.dll).

    К каким ещё ключам подобное может относится, какие ключи всегда общие, что ещё с этим можно делать - можно почитать по словам Registry Redirector, Registry Reflection, RegDisableReflectionKey. Эта фича помогает при миграции на 64разряда. Ещё для этой же цели есть File System Redirector, см. Wow64DisableWow64FsRedirection.

    Что касается NtCreateKey, подозреваю что к ней всё это так же применимо. Дело в том, что WOW64 реализована через особую ntdll, и ещё несколько 64разрядных dll, осуществляющих переход. Всё что ближе, в т.ч. shell32.dll со своим SHGetFolderPath имеет обычную 32разрядную реализацию для WOW64 (т.е. имеются два разных шелла, два разных user32.dll, и т.д.).

    Возможно я тут ещё что-то упустил важное, у меня не было много времени и желания разбираться после решения своей проблемы через KEY_WOW64_64KEY и Wow64DisableWow64FsRedirection.

    Что ты со всем этим делать будешь - не знаю, зависит от твоей задачи. В любом случае, чтобы всё это увидеть в действии, следует хотя бы иметь 64разрядную ОС. Чтобы увидеть это со стороны 64разрядного приложения необходим ещё 64разрядный компилятор (которого у Delphi (пока что) нет).


    > Мы, дважды на грабли не наступаем !

    Кстати зря, предыдущий ник выглядел интереснее, а "опечатка" воспринималась как преднамеренная :)
  • LightRipple © (18.05.08 00:14) [12]
    > [11] guav ©   (17.05.08 13:40)

    Спасибо.

    > В любом случае, чтобы всё это увидеть в действии, следует хотя бы иметь 64разрядную ОС.
    > Чтобы увидеть это со стороны 64разрядного приложения необходим
    > ещё 64разрядный компилятор (которого у Delphi (пока что) нет).

    Вот это самое печальное. И отсутствие 64разрядной ОС и "недоделанность Delphi" :(
    Кстати еще один аргумент в пользу C. В VS есть 64-разрядный компилятор ?
  • LightRipple © (18.05.08 00:27) [13]
    > [11] guav ©   (17.05.08 13:40)
    > Кстати зря, предыдущий ник выглядел интереснее,
    > а "опечатка" воспринималась как преднамеренная :)

    Ну на этот случай я еще один ник завела. Такой же как и этот, только на русском :)
    Если уж Вам будет тяжело меня воспринимать под этим, то перейдем на тот :)
  • guav © (18.05.08 01:35) [14]
    > Кстати еще один аргумент в пользу C. В VS есть 64-разрядный
    > компилятор ?

    Да, есть и для x64 и для IA64, С или С++.
    По своему впечатлению скажу что компиляция для x64 и одновременная поддержа конфигураций x64 и x86 менее хлопотна, чем одновременная поддержка ANSI и Unicode. То есть, вообще ничего специального предпринимать не надо.
  • LightRipple © (18.05.08 01:45) [15]
    >  [14] guav ©   (18.05.08 01:35)
    > По своему впечатлению скажу что компиляция для x64 и одновременная поддержа
    > конфигураций x64 и x86 менее хлопотна, чем одновременная поддержка ANSI и Unicode.
    > То есть, вообще ничего специального предпринимать не надо.

    Ой ! Тогда то что !
    Осталось дело за малым: освоить С-и :)
  • guav © (18.05.08 15:39) [16]
    Возвращаясь к исходной теме...
    А что если спускаться от первого к последнему, открывая только с KEY_ENUMERATE_SUB_KEYS.
    Если на каком-то этапе подключ не найден, делать "ReOpen" ключа с KEY_CREATE_SUB_KEY и содавать подключ.
  • guav © (18.05.08 15:45) [17]
    под ReOpen понимать OBJECT_ATTRIBUTES с пустым ObjectName
  • LightRipple © (18.05.08 23:34) [18]
    > [16] guav ©   (18.05.08 15:39)
    > Возвращаясь к исходной теме...
    > А что если спускаться от первого к последнему, открывая только с KEY_ENUMERATE_SUB_KEYS.
    > Если на каком-то этапе подключ не найден, делать "ReOpen" ключа с KEY_CREATE_SUB_KEY и содавать подключ.

    Проводила следующий эксперимент (правда с директориями, а не с ключами, но я думаю механизм будет аналогичен)
    Имеем ветку: Level_0\Level_1\Level_2\Level_3\Level_4\...\Level_N. Надо создать Level_N + 1.
    Полнстью блокируем для себя доступ к уровню Level_2, без наследования секюрити его детьми.
    Когда спускаемся сверху, разумеется, на нем спотыкаемся и
    ReOpen даже с доступом FILE_ANY_ACCESS не помогает. Остается только вслепую тыкаться по уровням ниже.
    Если же мы начали снизу и поднимаемся по ветке, то нас блокировка в середине не волнует.
    Если есть доступ к Level_N с запросом на KEY_CREATE_SUB_KEY, то создаем нужный объект,
    а если нет, то уже ничто не поможет. (Ну..., почти ничто :)
  • guav © (18.05.08 23:51) [19]
    > Остается только вслепую тыкаться по уровням ниже.

    Понял.
    Но всё же тыканье по уровням ниже может быть не совсем вслепую. Если у нас не оказалось прав на Level K, при том что Level N > K + 1 вернул STATUS_OBJECT_NAME_NOT_FOUND, думаю имеет смысл тыкнуться на уровень M = (N + K + 1) / 2. Я в почту кинул слишком сомнительный для форума псевдокод, как я это вижу.
  • LightRipple © (19.05.08 00:01) [20]
    >  [19] guav ©   (18.05.08 23:51)
    > Остается только вслепую тыкаться по уровням ниже.

    > Но всё же тыканье по уровням ниже может быть не совсем вслепую.
    > Если у нас не оказалось прав на Level K, при том что Level N > K + 1 вернул STATUS_OBJECT_NAME_NOT_FOUND,
    > думаю имеет смысл тыкнуться на уровень M = (N + K + 1) / 2.

    Половинное деление надо обдумать. Я имею ввиду следующее: всегда ли возвращаемая ошибка
    даст нам точное указание куда дальше надо двигаться вверх или вниз ?

    > Я в почту кинул слишком сомнительный для форума псевдокод, как я это вижу.

    Спасибо. Пойду посмотрю. Правда доступ к Delphi у меня появиться только минут через сорок.
    Или там на С ?

    P.S.
    Я уж и забыла, когда Вы в последний раз баловали меня кодом на Delphi :)
 
Конференция "Основная" » Алгоритм создания "многоступенчатого" ключа.
Есть новые Нет новых   [134491   +8][b:0][p:0.001]