Случайны выбор дневника Раскрыть/свернуть полный список возможностей


Найдено 88029 сообщений
Cообщения с меткой

windows - Самое интересное в блогах

Следующие 30  »
Vladyi

Настройка скорости и быстродействия системы Windows

Среда, 26 Апреля 2017 г. 23:00 (ссылка)

Это цитата сообщения Владимир_Шильников Оригинальное сообщение

Настройка скорости и быстродействия системы Windows.

Настройка быстродействия системы WindowsВ этой статье Вы узнаете,  как правильно увеличить быстродействие системы (Windows) и обеспечить ее безопасность.
Очень сильно увеличить быстродействие компьютера путем системных настроек можно, только если у вас есть очевидные ошибки в этих самых настройках.
Для начала, необходимо проверить самим некоторые установки в BIOS:
При загрузке ПК нажмите кнопку DELETE и увидите синий экран "CMOS Setup Utility".
Конкретные названия пунктов меню могут немного различаться в зависимости от производителя BIOS, мы будем рассматривать на  AWARD BIOS. Войдите в меню BIOS FEATURES SETUP и установите следующие значения параметров, которые влияют на время загрузки компьютера и быстродействие системы:
Метки:   Комментарии (0)КомментироватьВ цитатник или сообщество
Владимир_Шильников

Настройка скорости и быстродействия системы Windows.

Вторник, 25 Апреля 2017 г. 08:58 (ссылка)

Настройка быстродействия системы WindowsВ этой статье Вы узнаете,  как правильно увеличить быстродействие системы (Windows) и обеспечить ее безопасность.
Очень сильно увеличить быстродействие компьютера путем системных настроек можно, только если у вас есть очевидные ошибки в этих самых настройках.
Для начала, необходимо проверить самим некоторые установки в BIOS:
При загрузке ПК нажмите кнопку DELETE и увидите синий экран "CMOS Setup Utility".
Конкретные названия пунктов меню могут немного различаться в зависимости от производителя BIOS, мы будем рассматривать на  AWARD BIOS. Войдите в меню BIOS FEATURES SETUP и установите следующие значения параметров, которые влияют на время загрузки компьютера и быстродействие системы:
Метки:   Комментарии (13)КомментироватьВ цитатник или сообщество
SoftLabirint

CorelDRAW Graphics Suite 2017 19.0.0.328 (x64) Retail (Multi/Eng/Rus) » SoftLabirint.Ru: Скачать бесплатно и без регистрации - Самые Популярные Новости Интернета

Понедельник, 24 Апреля 2017 г. 18:49 (ссылка)
softlabirint.ru/soft/design...ngrus.html


CorelDRAW Graphics Suite 2017 19.0.0.328 (x64) Retail (Multi/Eng/Rus)

Непревзойденные возможности CorelDRAW Graphics Suite 2017 в сочетании с вашими творческими способностями — прекрасная основа для проектов по созданию макетов, разработке веб-сайтов и редактированию фотографий. Пакет оснащен расширенной поддержкой Windows 10, мультидисплейным режимом просмотра и поддержкой мониторов 4K.



Продукт позволяет дизайнерам самых разных уровней подготовки — от новичков до профессионалов — быстро и с уверенностью добиваться высококлассных результатов. Откройте для себя профессиональные и в то же время интуитивно понятные инструменты для создания логотипов, брошюр, веб-графики, рекламы для размещения в социальных сетях и других оригинальных проектов. Работайте с CorelDRAW на свой лад!



Пакет предоставляет полный набор инструментов для создания иллюстраций, логотипов, брошюр, бюллетеней, рекламных объявлений, буклетов и рекламных щитов и является оптимальным графическим решением. Данный программный пакет прекрасно подходит для создания новых тенденций в индустрии моды и разработки дизайнерской одежды. Создавать замысловатые рисунки и распределять их по полю изображения вам поможет мощный арсенал инструментов. CorelDRAW и Corel PHOTO-PAINT заметно расширили свои возможности в сравнении с предыдущими версиями и аналогами программного обеспечения этой отрасли.



Состав пакета CorelDRAW Graphics Suite:

• Основные приложения:

— CorelDRAW 2017 – векторная графика и макеты страниц

— Corel PHOTO-PAINT 2017 – редактирование изображений

— Corel Font Manager 2017 – поиск и систематизация шрифтов

— Corel PowerTRACE 2017 – трассировка растровых изображений в векторную графику (входит в состав — CorelDRAW 2017)

— Corel CONNECT 2017 – средство поиска контента

— Corel CAPTURE 2017 – средство захвата экрана

— Corel Website Creator – разработка веб-сайтов

• Вспомогательные приложения:

— BenVISTA PhotoZoom Pro 4 — плагин для увеличения цифровых изображений

— Microsoft Visual Basic for Applications 7.1 — автоматизация задач

— Microsoft Visual Studio Tools for Applications 2015 — автоматизация задач и передовые проекты с использованием макросов

— Barcode Wizard — генератор штрихкодов в стандартных отраслевых форматах

— Duplexing Wizard — мастер двусторонней печати

— GPL Ghostscript (ZIP) — улучшенный импорт файлов EPS и PS

— WhatTheFont — онлайн-сервис идентификации шрифтов



Лучшие функции CorelDRAW Graphics Suite 2017:

• Переработанный полностью настраиваемый интерфейс. Рабочая среда, где нужные инструменты и настройки всегда под рукой, отражает особенности вашего рабочего процесса. Чтобы быстро приступить к работе, нужно выбрать подходящее рабочее пространство, а затем с помощью функции быстрой настройки отладить набор инструментов и панели свойств в соответствии с вашими предпочтениями. Мы предлагаем рабочее пространство по умолчанию, упрощенное рабочее пространство и классическое рабочее пространство (на основе версии Х6).

• Специализированные рабочие пространства. Несколько готовых рабочих пространств помогут эффективно организовать и расположить нужные инструменты в пределах легкой досягаемости. К вашим услугам рабочие пространства «Макет страницы» и «Иллюстрация», а также возможность воссоздать настройки Adobe Photoshop или Illustrator в рабочем пространстве — это облегчит переход от Creative Suite к CorelDRAW.

• Полный контроль над заливками и прозрачностью. Для CorelDRAW Graphic Suite X8 был разработан наш самый мощный модуль заливки, который обеспечивает полный контроль над фонтанной заливкой и заливкой растровым и векторным узором. Теперь можно создавать эллиптическую и прямоугольную фонтанные заливки, настраивать уровень прозрачности отдельного цвета фонтанной заливки и повторять фонтанную заливку внутри объекта.

• Удобный предварительный просмотр шрифтов и расширенные параметры настройки символов. Здесь вы сможете найти подходящий шрифт для любого проекта. Окно настройки «Применение шрифта» предлагает функцию предварительного просмотра различных шрифтов и позволяет экспериментировать с ними. Кроме того, переработанное окно настройки «Вставка символа» автоматически отображает все знаки, символы и глифы, которые ассоциируются с выбранным шрифтом, что значительно упрощает поиск и вставку в документ этих элементов.

• Специальные эффекты и расширенные возможности редактирования фото. Спецэффекты, представленные в Corel PHOTO-PAINT X8, включают четыре новых чувствительных к нажиму инструмента размытия — Размазывание, Завихрение, Притягивание и Отталкивание, а также новые эффекты камеры — Боке, Цветность, Машина Времени и Сепия, которые позволяют придать изображениям уникальный вид. Расширенная поддержка форматов RAW более 300 моделей камер открывает дополнительные возможности работы с изображениями.

• Точные инструменты рисования и макетирования. Убедитесь в том, что каждый элемент на странице расположен именно там, где нужно, с улучшенными средствами создания макетов. Окно «Направляющие» позволяет быстрее располагать объекты, отображаясь в процессе работы вместе с предлагаемыми вариантами выравнивания относительно других объектов. Опции размещения абриса позволяют уточнить, будет ли абрис расположен внутри объекта, снаружи объекта, или же в равной степени с обеих сторон границы объекта.

• Генератор QR кодов. Создавайте уникальные QR-коды и добавляйте их в ваши проекты в качестве инструмента мобильного маркетинга. Используйте текст, изображения и цветовые стили для придания QR-кодам задуманного вида. Ваш QR-код может гармонировать с общим дизайном, а может и противоречить ему — варианты бесконечны! Встроенная функция проверки позволит убедиться, что QR-код работает и может быть расшифрован при помощи смартфона с установленным приложением для сканирования.

• Встроенный Контент-центр. Откройте для себя интерактивное онлайн-хранилище Контент-центр*, полностью интегрированное с приложениями пакета. Вы можете обмениваться векторными, растровыми и фонтанными заливками с членами сообщества пользователей CorelDRAW прямо в приложении. Почерпните вдохновение, продемонстрируйте ваши произведения и проголосуйте за понравившиеся работы.

• Расширенная поддержка OpenType. Создавайте красивые надписи с помощью расширенных типографских возможностей OpenType — лигатур, орнаментов, капителей и росчерков. Шрифты OpenType, идеальные для межплатформенной разработки, обеспечивают комплексную языковую поддержку, позволяя настраивать символы в соответствии с рабочим языком.

• Поддержка сложных шрифтов. Благодаря функциям CorelDRAW, обеспечивающим правильный типографский набор знаков, работа с азиатскими и ближневосточными языками стала еще проще. Поддержка сложных наборов работает так же, как поддержка шрифтов OpenType: символы меняются по мере ввода, что обеспечивает соответствие контексту.

• Стили документа. Окно настройки «Стили объектов» упрощает создание стилей, их применение и управление ими. Наборы стилей облегчают задачи быстрого и единообразного форматирования документов и создания нескольких вариантов одного дизайна.

• Пользовательские гармонии цветов. С легкостью создавайте дополнительные цветовые палитры для проекта. Инструмент «Гармония цветов» объединяет цветовые стили в гармонию, благодаря чему можно осуществлять групповые изменения цветов. Он также анализирует цвета и оттенки для формирования дополнительных цветовых схем — превосходный способ удивить клиентов разнообразием!

• Инструменты для формирования векторных форм. Добавляйте интересные эффекты в векторные объекты. Четыре инструмента формирования — Мастихин, Воронка, Притягивание и Отталкивание — позволяют дорабатывать векторные объекты путем притягивания, отталкивания, размазывания объекта или создания выемок.

• Инструменты для работы с макетами страниц. С улучшенными инструментами макетирования страниц процесс разработки сложных макетов стал еще проще. Пустая рамка PowerClip позволяет зарезервировать место для текста или графики. Инструмент «Шаблонный текст» дает возможность смоделировать макет страницы и увидеть, как будет выглядеть текст, а функция автоматической нумерации позволяет быстро добавить номера страниц.

• Встроенная поддержка 64-битных многоядерных процессоров. Теперь, благодаря возможностям многоядерной обработки и встроенной поддержки 64-битных процессоров, на разработку ваших проектов уйдет совсем немного времени. Повышенная производительность и более эффективное использование памяти обеспечивают ускоренное выполнение ресурсоемких задач, позволяют ускорить обработку больших файлов и изображений, а также увеличить количество одновременно обрабатываемых файлов больших размеров.

• Мощная система управления цветом. Переработанная система управления цветом обеспечивает контроль за соответствием цветовых параметров для различных носителей и позволяет создавать индивидуальные цветовые палитры для каждого документа. Кроме того, система управления цветом обеспечивает повышенную точность цветовых параметров, а также поддержку новейших цветовых профилей PANTONE. Она позволяет сократить затраты на повторную печать, гарантируя точное соответствие цветов до начала печати.

• Средства для веб-графики. Коллекция инструментов CorelDRAW для работы с веб-графикой поможет в создании увлекательного веб-контента. Пиксельный режим показывает изображение в точности так, как оно будет выглядеть в интернете, а диалоговое окно экспорта позволяет сравнивать форматы перед экспортом изображения и выбрать те настройки, которые дадут наилучший результат.

• Простая трассировка растровых изображений в векторные. Не тратьте драгоценное время на преобразование растровых изображений в векторную графику. Существенно улучшенный встроенный модуль Corel® PowerTRACE® обеспечит безупречные результаты трассировки и преобразует самые сложные растровые изображения в векторные объекты высокого качества.

• Встроенный органайзер материалов. Наш встроенный инструмент поиска Corel CONNECT поможет просмотреть и найти нужные материалы, а затем организовать и сгруппировать контент по типу или проекту. Функция синхронизации рабочих лотков с Microsoft OneDrive обеспечит постоянный доступ к новейшим версиям ваших проектов с других компьютеров или мобильных устройств.



Новые и улучшенные функции CorelDRAW Graphics Suite 2017:

• Новое! Инструмент LiveSketch. Рисуйте в любом месте и в любое время! В этом вам поможет созданный на основе последних разработок в области искусственного интеллекта и машинного обучения революционный инструмент LiveSketch. LiveSketch превращает художественные эскизы в точные векторные кривые прямо на устройствах с сенсорным экраном.

• Новое! Улучшенные узлы, ручки и векторные превью. Улучшенные узлы, ручки и превью, которые не теряются на фоновых цветах рисунка, позволяют более продуктивно редактировать объекты и эффекты.

Новое! Хорошо различимые интерактивные регуляторы. Повышенная видимость интерактивных регуляторов облегчает работу с заливками, тенями, контурами и эффектами прозрачности, смешения и вытягивания.

• Новое! Настраиваемые формы узлов. CorelDRAW 2017 упрощает процедуру формирования кривых и объектов: теперь каждому типу узла присваивается уникальная форма, что позволяет легко определить плавные, острые и симметричные узлы. Форму узлов можно выбирать с учетом особенностей вашего рабочего процесса.

• Новое! Ориентированный на сенсорные устройства интерфейс пользователя. Поддержка планшетного режима существенно облегчает процесс внесения изменений с помощью пера или посредством касаний. Новое сенсорное рабочее пространство «Касание» оптимизирует интерфейс пользователя, максимально увеличивая окно рисования и отображая только необходимые инструменты и команды. Кроме того, масштабирование и панорамирование теперь выполняется одним жестом.

• Новое! Качественные усовершенствования перьевого ввода. Нативная поддержка Microsoft Surface, а также расширенная поддержка перьевого ввода позволяют сохранить естественные ощущения при рисовании и дают возможность добиваться более экспрессивных результатов. В переработанном интерфейсе обеспечен прямой доступ к элементам управления, необходимым для выполнения текущей задачи. Кроме того, предусмотрена возможность быстрого выбора наиболее эффективных в конкретной ситуации свойств пера. Усовершенствования, представленные в CorelDRAW Graphics Suite 2017, позволяют использовать силу нажима, наклон, поворот и направление движения пера для управления различными инструментами и эффектами.

• Новое! Импорт рабочих пространств из предыдущих версий. CorelDRAW Graphics Suite 2017 позволяет без труда импортировать и использовать рабочие пространства, созданные в версиях X6, X7 и X8 CorelDRAW и Corel PHOTO-PAINT. В пакете представлены гибкие возможности импорта рабочего пространства в текущую рабочую среду (включая импорт и экспорт отдельных элементов рабочего пространства), а также средства создания абсолютно нового интерфейса пользователя. Процесс выбора предназначенных для импорта и экспорта элементов рабочего пространства был максимально ускорен.

• Новое! Поддержка Microsoft Surface Dial. CorelDRAW Graphics Suite 2017 предлагает нативную поддержку Microsoft Surface Dial на платформе Windows 10. Работа с приложениями CorelDRAW и Corel PHOTO-PAINT открывает уникальные возможности как в области творчества, так и в области взаимодействия с технологиями.



Процедура лечения:

1. Отключить интернет.

2. Установить программу.

3. По завершении установки закрыть окно с предложением войти в учетную запись.

4. Скопировать с заменой файл PASMUTILITY.dll из папки Crack в папку C:\Program Files\Corel\PASMUtility\v1

5. Подключить интернет, запустить программу, пользоваться.

 



CorelDRAW Graphics Suite 2017 19.0.0.328 (x64) Retail (Multi/Eng/Rus)



CorelDRAW Graphics Suite 2017 19.0.0.328 (x64) Retail (Multi/Eng/Rus)



CorelDRAW Graphics Suite 2017 19.0.0.328 (x64) Retail (Multi/Eng/Rus)



CorelDRAW Graphics Suite 2017 19.0.0.328 (x64) Retail (Multi/Eng/Rus)






Системные требования:

— Microsoft Windows 10, Windows 8.1 или Windows 7 (64-битные версии), все с последними пакетами обновления

— Intel Core i3/5/7 или AMD Athlon 64

— 2 ГБ оперативной памяти

— 1 ГБ места на жестком диске

— Мышь, планшет или мультисенсорный монитор

— Разрешение монитора 1280 x 720 при 100% (96 т/д)

— Microsoft Internet Explorer 11 или выше

— Microsoft .Net Framework 4.6



Информация о программе

Название: CorelDRAW Graphics Suite 2017 19.0.0.328 (x64) Retail (Multi/Eng/Rus)

Год выпуска: 2017

Разработчик: Corel Corporation

ОС: Windows 7 | 8 | 10 — x64

Язык интерфейса: Русский, Английский и другие

Лечение: в комплекте

Размер: 1,17 GB



Скачать: CorelDRAW Graphics Suite 2017 19.0.0.328 (x64) Retail (Multi/Eng/Rus) >>>



 



Подписка на новости сайта…

http://feeds.feedburner.com/Soft-Labirint

http://feeds.feedburner.com/Soft-Labirint?format=xml

https://feedburner.google.com/fb/a/mailverify?uri=Soft-Labirint



 



 

Метки:   Комментарии (0)КомментироватьВ цитатник или сообщество
SoftLabirint

Windows 7 9in1 & Windows 10 4in1 x86/x64 v.34.17 (2017) RUS » SoftLabirint.Ru: Скачать бесплатно и без регистрации - Самые Популярные Новости Интернета

Воскресенье, 23 Апреля 2017 г. 16:31 (ссылка)
softlabirint.ru/soft/system...7-rus.html


Windows 7 9in1 & Windows 10 4in1 x86/x64 v.34.17 (2017) RUS

За основу для этой сборки были использованы оригинальные образы от MicroSoft Windows 7 и Windows 10.

13 редакций обеих разрядностей объединены в один образ. Интегрированы обновления по апрель 2017 года. Изменен интерфейс систем, вид папок, значков, ярлыков. Подробности ниже.



Особенности сборки:

Основы сборки:

• ru_windows_10_enterprise_2016_ltsb_x64_dvd_9057886

• ru_windows_10_enterprise_2016_ltsb_x86_dvd_9058173

• SW_DVD5_Win_Pro_10_1607_32BIT_Russian_MLF_X21-07301

• SW_DVD5_Win_Pro_10_1607_64BIT_Russian_MLF_X21-07302

• ru_windows_7_ultimate_with_sp1_x86_dvd_u_677463

• ru_windows_7_ultimate_with_sp1_x64_dvd_u_677391



Windows 10

• Windows 10 Система обновлена до версии 14393.1066;

• Установка может быть продолжительной, необходимо просто подождать (прописываются ключи для системы);

• Изменен интерфейс системы, вид папок, значков, ярлыков, некоторые диалоговые окна.



Windows 7

• В сборку интегрированы важные только обновления;

• На начальном этапе предоставлен выбор настройки различных параметров и выбора разрядности системы;

• Интегрированы нужные системные библиотеки, DirectX® 9.0c .Microsoft .NET Framework 4.6;

• Обновлен набор программ на актуальные версии;

• Применены твики ПКМ,ОЕМ, патч для сторонних тем,отключен контроль учетных записей;

• Изменен интерфейс системы, вид папок, значков, ярлыков, диалоговые окна.



• Install.wim сжаты в ESD;

• Системы активируются автоматически, все верси;

• Применен универсальный загрузчик WinPE, со множеством функций;

• ЗАПИСЫВАТЬ ПРОГРАММОЙ Rufus;

• УСТАНОВКА СТРОГО С БИОСа.



Для установки можно выбрать следующие редакции:



Windows 10:

• Windows 10 Professional x86

• Windows 10 Professional x64

• Windows 10 Enterprise 2016 LTSB x86

• Windows 10 Enterprise 2016 LTSB x64



Windows 7:

32х-битные редакции:

• Windows 7 Начальная x86

• Windows 7 Домашняя x86

• Windows 7 Домашняя Расширенная x86

• Windows 7 Профессиональная x86

• Windows 7 Максимальная x86



64х-битные редакции:

• Windows 7 Домашняя x64

• Windows 7 Домашняя Расширенная x64

• Windows 7 Профессиональная x64

• Windows 7 Максимальная x64



Состав программ загрузчика:

• Восстановление Windows 10 (только х86)

• Acronis® True Image™ Premium 2014 PP

• Paragon Hard Disk Manager 14 Premium

• Acronis® Disk Director™ 12

• HDD Low Level Format Tool

• Acronis® Recovery Expert

• Universal Virus Sniffer

• Paragon Alignment Tool

• Установка драйверов

• PartitionWizard

• Total Commander

• Explorer++

• Defraggler

• WinNTSetup

• Ultra ISO

• ChkDskGui

• PassReset

• Anti SMS

• Testdisk

• Win Snap

• WinMount

• AkelPad

• Bootice

• Drivexp

• AIDA64

• WinRAR

• 7-Zip



Интегрировано:



Windows 10:

• Microsoft Access MUI (Russian) 2013 [Русский (Россия)] 15.0.4569.1506

• Microsoft DCF MUI (Russian) 2013 [Русский (Россия)] 15.0.4569.1506

• Microsoft Excel MUI (Russian) 2013 [Русский (Россия)] 15.0.4569.1506

• Microsoft Groove MUI (Russian) 2013 [Русский (Россия)] 15.0.4569.1506

• Microsoft InfoPath MUI (Russian) 2013 [Русский (Россия)] 15.0.4569.1506

• Microsoft Lync MUI (Russian) 2013 [Русский (Россия)] 15.0.4569.1506

• Microsoft Office Korrekturhilfen 2013 - Deutsch [Немецкий (Германия)] 15.0.4569.1506

• Microsoft Office OSM MUI (Russian) 2013 [Русский (Россия)] 15.0.4569.1506

• Microsoft Office OSM UX MUI (Russian) 2013 [Русский (Россия)] 15.0.4569.1506

• Microsoft Office Professional Plus 2013 15.0.4569.1506

• Microsoft Office Proofing (Russian) 2013 [Русский (Россия)] 15.0.4569.1506

• Microsoft Office Proofing Tools 2013 - English 15.0.4569.1506

• Microsoft Office Shared MUI (Russian) 2013 [Русский (Россия)] 15.0.4569.1506

• Microsoft Office профессиональный плюс 2013 15.0.4569.1506

• Microsoft OneNote MUI (Russian) 2013 [Русский (Россия)] 15.0.4569.1506

• Microsoft Outlook MUI (Russian) 2013 [Русский (Россия)] 15.0.4569.1506

• Microsoft PowerPoint MUI (Russian) 2013 [Русский (Россия)] 15.0.4569.1506

• Microsoft Publisher MUI (Russian) 2013 [Русский (Россия)] 15.0.4569.1506

• Microsoft Word MUI (Russian) 2013 [Русский (Россия)] 15.0.4569.1506

• Засоби перевірки правопису Microsoft Office 2013 – українська мова [Украинский (Украина)] 15.0.4569.1506

• Средства проверки правописания Microsoft Office 2013 — русский [Русский (Россия)] 15.0.4569.150



Windows 7:

• 7-Zip 16.04

• Adobe Flash Player ActiveX+Plugins 25.0.0.148

• Adobe Shockwave Player v.12.2.8.198 + v.10.4.1.53

• Adobe Standalone Flash Player v.25.0.0.148

• AIDA64

• HashTab 6.0.0.28

• Java 8 Update 121 8.0.1210.13

• Java Auto Updater 2.8.121.13

• Microsoft .NET Framework 4.6.2

• Update for Microsoft .NET Framework 4.6.2 (KB3205379)

• Microsoft Visual C++ 2005 --- 2017

• UltraISO Premium V9.66

• Unity Web Player 5.3.8

• Unlocker 1.9.2



Лечение:

• Системы активируются автоматически.

• Если активация не прошла, на рабочем столе папка с активаторами.

 



Windows 7 9in1 & Windows 10 4in1 x86/x64 v.34.17 (2017) RUS Windows 7 9in1 & Windows 10 4in1 x86/x64 v.34.17 (2017) RUS Windows 7 9in1 & Windows 10 4in1 x86/x64 v.34.17 (2017) RUS



Windows 7 9in1 & Windows 10 4in1 x86/x64 v.34.17 (2017) RUS Windows 7 9in1 & Windows 10 4in1 x86/x64 v.34.17 (2017) RUS Windows 7 9in1 & Windows 10 4in1 x86/x64 v.34.17 (2017) RUS



Windows 7 9in1 & Windows 10 4in1 x86/x64 v.34.17 (2017) RUS Windows 7 9in1 & Windows 10 4in1 x86/x64 v.34.17 (2017) RUS Windows 7 9in1 & Windows 10 4in1 x86/x64 v.34.17 (2017) RUS






Системные требования:

• Процессор: Не менее 1 ГГц или SoC.

• ОЗУ: 1 ГБ (для 32-разрядных систем) или 2 ГБ (для 64-разрядных систем).

• Место на жестком диске: 16 ГБ (для 32-разрядных систем) или 20 ГБ (для 64-разрядных систем).

• Видеоадаптер: DirectX версии 9 или более поздней с драйвером WDDM 1.0.

• Дисплей: 800 x 600.

• Для защищенной загрузки необходимо встроенное ПО, которое поддерживает UEFI v2.3.1 Errata B и имеет в базе сигнатур UEFI сертификат центра сертификации Microsoft Windows.

• Для установки 64-разрядной операционной системы на 64-разрядный компьютер ваш процессор должен поддерживать CMPXCHG16b, PrefetchW и LAHF/SAHF.



Контрольные суммы:

CRC32: 1E7F9472

MD5: 89656E9C550E9C47DBAF528E02204362

SHA-1: 3311ED75AF1BEBC2BFF398C3746DC380705A3747



Информация о софте:

Дата выпуска: 21 апреля 2017 года

Название: Windows 7 9in1 & Windows 10 4in1 x86/x64 v.34.17

Версия: 7- 6.1.7601 / 10- 1607.14393.1066 / v.34.17

Разработчик/автор сборки: MicroSoft / UralSOFT

Разрядность: x86/x64

Язык интерфейса: Русский

Таблэтка: Не требуется

Размер: 7.51 GB



Скачать: Windows 7 9in1 & Windows 10 4in1 x86/x64 v.34.17 (2017) RUS >>>



 



Подписка на новости сайта…

http://feeds.feedburner.com/Soft-Labirint

http://feeds.feedburner.com/Soft-Labirint?format=xml

https://feedburner.google.com/fb/a/mailverify?uri=Soft-Labirint



 

Метки:   Комментарии (0)КомментироватьВ цитатник или сообщество
SoftLabirint

Windows 10 x86/x64 4in1 Office2013 14393.1066 v.33.17 (2017) RUS » SoftLabirint.Ru: Скачать бесплатно и без регистрации - Самые Популярные Новости Интернета

Воскресенье, 23 Апреля 2017 г. 13:31 (ссылка)
softlabirint.ru/soft/system...7-rus.html


Windows 10 x86/x64 4in1 Office2013 14393.1066 v.33.17 (2017) RUS

Cборка была создана на основе оригинальных образов от Майкрософт Windows 10 Version 1607 RU. Четыре редакции Professional и Enterprise 2016 LTSB обеих разрядностей объединены в один образ. Системы обновлены до версии билда 14393.1066. Изменен интерфейс системы. Подробности ниже.



Особенности сборки:

Данная сборка сделана на основе оригиналов:

• ru_windows_10_enterprise_2016_ltsb_x64_dvd_9057886

• ru_windows_10_enterprise_2016_ltsb_x86_dvd_9058173

• SW_DVD5_Win_Pro_10_1607_32BIT_Russian_MLF_X21-07301

• SW_DVD5_Win_Pro_10_1607_64BIT_Russian_MLF_X21-07302



• Файл Install.wim пережат в формат ESD;

• Установка может быть продолжительной, необходимо просто подождать (прописываются ключи для офиса и системы);

• Изменен интерфейс системы, вид папок, значков, ярлыков, некоторые диалоговые окна;

• На завершающем этапе установки, устанавливается Microsoft Office Professional Plus 2013 (установка скрытая);

• Другие программы кроме офиса в сборку НЕ ИНТЕГРИРОВАЛИСЬ;

• Системы активируются автоматически, все версии;

• Применен универсальный загрузчик WinPE, со множеством функций;

• Установка с БИОСа.



Доступные для установки редакции:

• Windows 10 Professional x86

• Windows 10 Professional x64



• Windows 10 Enterprise 2016 LTSB x86

• Windows 10 Enterprise 2016 LTSB x64



Состав программ загрузчика:

• Восстановление Windows 10 (только х86)

• Acronis® True Image™ Premium 2014 PP

• Paragon Hard Disk Manager 14 Premium

• Acronis® Disk Director™ 12

• HDD Low Level Format Tool

• Acronis® Recovery Expert

• Universal Virus Sniffer

• Paragon Alignment Tool

• Установка драйверов

• PartitionWizard

• Total Commander

• Explorer++

• Defraggler

• WinNTSetup

• Ultra ISO

• ChkDskGui

• PassReset

• Anti SMS

• Testdisk

• Win Snap

• WinMount

• AkelPad

• Bootice

• Drivexp

• AIDA64

• WinRAR

• 7-Zip



Интегрировано:

• Microsoft Access MUI (Russian) 2013 [Русский (Россия)] 15.0.4569.1506

• Microsoft DCF MUI (Russian) 2013 [Русский (Россия)] 15.0.4569.1506

• Microsoft Excel MUI (Russian) 2013 [Русский (Россия)] 15.0.4569.1506

• Microsoft Groove MUI (Russian) 2013 [Русский (Россия)] 15.0.4569.1506

• Microsoft InfoPath MUI (Russian) 2013 [Русский (Россия)] 15.0.4569.1506

• Microsoft Lync MUI (Russian) 2013 [Русский (Россия)] 15.0.4569.1506

• Microsoft Office Korrekturhilfen 2013 - Deutsch [Немецкий (Германия)] 15.0.4569.1506

• Microsoft Office OSM MUI (Russian) 2013 [Русский (Россия)] 15.0.4569.1506

• Microsoft Office OSM UX MUI (Russian) 2013 [Русский (Россия)] 15.0.4569.1506

• Microsoft Office Professional Plus 2013 15.0.4569.1506

• Microsoft Office Proofing (Russian) 2013 [Русский (Россия)] 15.0.4569.1506

• Microsoft Office Proofing Tools 2013 - English 15.0.4569.1506

• Microsoft Office Shared MUI (Russian) 2013 [Русский (Россия)] 15.0.4569.1506

• Microsoft Office профессиональный плюс 2013 15.0.4569.1506

• Microsoft OneNote MUI (Russian) 2013 [Русский (Россия)] 15.0.4569.1506

• Microsoft Outlook MUI (Russian) 2013 [Русский (Россия)] 15.0.4569.1506

• Microsoft PowerPoint MUI (Russian) 2013 [Русский (Россия)] 15.0.4569.1506

• Microsoft Publisher MUI (Russian) 2013 [Русский (Россия)] 15.0.4569.1506

• Microsoft Word MUI (Russian) 2013 [Русский (Россия)] 15.0.4569.1506

• Засоби перевірки правопису Microsoft Office 2013 – українська мова [Украинский (Украина)] 15.0.4569.1506

• Средства проверки правописания Microsoft Office 2013 — русский [Русский (Россия)] 15.0.4569.150



Лечение:

• Системы и офис активируются автоматически.

• На непредвиденный случай на рабочем столе папка HELP с активаторами:

- KMSAuto Lite Portable v1.2.2

- AAct 3.2 DC 11.03.2017 Portable



Дополнительная информация:

• Единая Windows для всех устройств. Windows 10 будет устанавливаться на более широкий спектр устройств по сравнению с предыдущими версиями OC. В число этих устройств входят не только персональные компьютеры, ноутбуки, планшеты, но и смартфоны, телевизоры, различные платы и промышленные устройства, используемые для сценариев Internet of Things. Новая OC также будет являться единой платформой для разработки приложений и единым каналом доставки приложений через Магазин.



• Улучшенный интерфейс пользователя. Интерфейс операционной системы, с одной стороны, остался привычным, с другой стороны, приобрел несколько новых полезных возможностей.

Меню «Пуск». Открывается по нажатию на логотип в левом нижнем углу рабочего стола. В левом столбце меню содержатся ярлыки к последним запущенным приложениям, в правом — плитки универсальных приложений. В меню также находятся кнопки управления питанием и обновленная функция поиска, для поиска не только в локальной системе, но и в интернете.



• Универсальные окна приложений. Теперь и классические приложения для рабочего стола и новые универсальные приложения запускаются в собственном окне на рабочем столе.

Улучшенная функция Snap. Работать в нескольких приложениях сразу стало проще и удобнее. Теперь функция Snap позволяет открыть до 4 приложений на экране одновременно, а Windows подсказывает, какие еще приложения запущены и как их можно разместить. Windows 10 поможет эффективнее использовать незанятое пространство экрана для других приложений.



• Множество рабочих столов. Пользователь может создавать несколько рабочих столов и размещать на них окна приложений. Можно вывести все созданные столы на экран и переключаться между ними.



• Многозадачность. На панели задач появилась новая кнопка Task View. При нажатии на нее, на экране появляются в уменьшенном виде окна всех запущенных приложений.



• Особое внимание к корпоративным пользователям и данным. При создании Windows 10 особое внимание было уделено корпоративным пользователям. Новая ОС будет совместима со всеми традиционными системами управления, которые используют организации. Операционная система содержит новые возможности по разделению рабочих и персональных данных на устройствах всех типов, что позволит воплотить концепцию BYOD в организациях.



Системные требования:

• Процессор: Не менее 1 ГГц или SoC.

• ОЗУ: 2 ГБ

• Место на жестком диске: 20 ГБ.

• Видеоадаптер: DirectX версии 9 или более поздней с драйвером WDDM 1.0.

• Дисплей: 800 x 600.



• Для защищенной загрузки необходимо встроенное ПО, которое

поддерживает UEFI v2.3.1 Errata B и имеет в базе сигнатур UEFI

сертификат центра сертификации Microsoft Windows.

• Для установки

64-разрядной операционной системы на 64-разрядный компьютер ваш

процессор должен поддерживать CMPXCHG16b, PrefetchW и LAHF/SAHF.

 



Windows 10 x86/x64 4in1 Office2013 14393.1066 v.33.17 (2017) RUS Windows 10 x86/x64 4in1 Office2013 14393.1066 v.33.17 (2017) RUS Windows 10 x86/x64 4in1 Office2013 14393.1066 v.33.17 (2017) RUS



Windows 10 x86/x64 4in1 Office2013 14393.1066 v.33.17 (2017) RUS Windows 10 x86/x64 4in1 Office2013 14393.1066 v.33.17 (2017) RUS Windows 10 x86/x64 4in1 Office2013 14393.1066 v.33.17 (2017) RUS



Windows 10 x86/x64 4in1 Office2013 14393.1066 v.33.17 (2017) RUS Windows 10 x86/x64 4in1 Office2013 14393.1066 v.33.17 (2017) RUS Windows 10 x86/x64 4in1 Office2013 14393.1066 v.33.17 (2017) RUS






Контрольные суммы:

CRC32: 27963EAD

MD5: 8BB72CB23CC98C562066525EAA55FBE5

SHA-1: 989FE545C8F15A8568F98700A059681E5108C5B7



Информация о софте:

Дата выпуска: 20 апреля 2017 года

Название: Windows 10 x86/x64 4in1 Office2013 14393.1066

Версия: v.33.17

Разработчик/автор сборки: MicroSoft / UralSOFT

Разрядность: x86/x64 (4in1)

Язык интерфейса: Русский

Таблэтка: Не требуется

Размер: 4.41 GB



Скачать: Windows 10 x86/x64 4in1 Office2013 14393.1066 v.33.17 (2017) RUS >>>



 



Подписка на новости сайта…

http://feeds.feedburner.com/Soft-Labirint

http://feeds.feedburner.com/Soft-Labirint?format=xml

https://feedburner.google.com/fb/a/mailverify?uri=Soft-Labirint



 

Метки:   Комментарии (0)КомментироватьВ цитатник или сообщество
rss_rss_hh_new

Исключения в Windows x64. Как это работает. Часть 4

Среда, 19 Апреля 2017 г. 15:32 (ссылка)

Опираясь на материал, описанный в первой, второй и третьей частях данной статьи, мы продолжим обсуждение темы обработки исключений в Windows x64.



Описываемый материал требует знания базовых понятий, таких, как пролог, эпилог, кадр функции и понимания базовых процессов, таких, как действия пролога и эпилога, передача параметров функции и возврат результата функции. Если читатель не знаком с вышеперечисленным, то перед прочтением рекомендуется ознакомиться с материалом из первой части данной статьи. Если читатель не знаком со структурами PE образа, которые задействуются в процессе обработки исключения, тогда перед прочтением рекомендуется ознакомиться с материалом из второй части данной статьи. Также, если читатель не знаком с процессом поиска и вызова обработчиков исключений, рекомендуется ознакомиться с третьей частью данной статьи.



Приводимое описание относится к реализации в Windows, и, следовательно, не следует полагать, что прилагаемая к статье реализация данного механизма будет в точности совпадать с ней, хотя концептуально различий нет. Детали прилагаемой реализации в статье рассматриваться не будут, если об этом не будет сказано явно. Поэтому предполагается, что эти детали, по необходимости, следует изучить самостоятельно.



К статье прилагается реализация механизма, которая находится в папке exceptions хранилища git по этому адресу.



1. Раскрутка стека



В процессе обработки ошибок может возникнуть ситуация, когда необходимо напрямую вернуть управление одной из предыдущих функций, минуя промежуточные функции. Т.е. возврат управления будет выполнен не посредством обычного возврата из функции в вызывающую функцию, которая в свою очередь тоже должна будет выполнить такой возврат, а посредством изменения состояния процессора таким образом, чтобы сразу после изменения он продолжил выполнять целевую функцию. На рисунке 1 изображен пример такой ситуации, где стрелкой указано направление роста стека.





Рисунок 1



На примере выше стек состоит из кадров четырех функций, где функция Main вызвала Func1, Func1 вызвала Func2, а Func2 вызвала Func3. Поэтому, например, если функции Func3 требуется вернуть управление функции Main, тогда она воспользуется функцией RtlUnwind/RtlUnwindEx, которая экспортируется модулем ntdll.dll в пользовательском пространстве и модулем ntoskrnl.exe в пространстве ядра. Прототип функции RtlUnwindEx изображен ниже, на рисунке 2.





Рисунок 2



Параметр TargetFrame принимает адрес кадра той функции, до которой следует раскрутить стек. Параметр TargetIp принимает адрес инструкции, с которой продолжится выполнение после раскрутки. Параметр ExceptionRecord принимает указатель на EXCEPTION_RECORD структуру, которая будет передаваться обработчикам при раскрутке. Параметр ReturnValue записывается в RAX регистр процессора, т.е. сразу после передачи управления соответствующей функции регистр RAX будет содержать значение этого параметра. Параметр ContextRecord содержит указатель на CONTEXT структуру, которая используется функцией RtlUnwindEx при раскрутке функций и определении целевого состояния процессора после раскрутки. Параметр HistoryTable принимает указатель на структуру, которая используется для кэширования поиска. Формат этой структуры вы сможете найти в winnt.h.



Параметр TargetFrame является необязательным. Если его значение равно NULL, тогда функция RtlUnwindEx выполняет так называемую раскрутку при выходе (exit unwind), где раскручиваются кадры всех функций стека. В этом случае параметр TargetIp игнорируется. Параметр ExceptionRecord является необязательным, и если он равен NULL, тогда функция RtlUnwindEx инициализирует свою структуру EXCEPTION_RECORD, где поле ExceptionCode будет содержать STATUS_UNWIND значение, поле ExceptionRecord будет содержать NULL, поле ExceptionAddress будет содержать указатель на инструкцию функции RtlUnwindEx, а поле NumberParameters будет содержать 0. Параметр HistoryTable является необязательным.



Прототип функции RtlUnwind отличается лишь тем, что он не принимает два последних параметра.



Ниже, на рисунке 3, изображен пример работы функции RtlUnwind.





Рисунок 3



На рисунке выше изображен пример программы, состоящей из четырех функций: _tmain, Func1, Func2, Func3. Функция _tmain вызывает функцию Func1, функция Func1 вызывает Func2, а функция Func2 вызывает Func3. Функции Func1, Func2, Func3 возвращают булево значение. Функция Func3 выполняет виртуальную раскрутку трех предыдущих функций с целью: найти адрес кадра функции _tmain; найти адрес инструкции, с которой будет продолжено выполнение, и в данном примере адрес будет указывать на инструкцию сразу после инструкции вызова функции Func1. Справа от исходного кода изображен ассемблерный код _tmain и Func3 функций, адреса инструкций которых являются абсолютными. Справа от ассемблерного кода изображены состояния процессора и стеки вызовов для трех случаев: сверху изображено состояние процессора и стек вызовов сразу перед вызовом функции Func1; посередине изображено состояние процессора и стек вызовов сразу перед вызовом функции RtlUnwind; внизу изображено состояние процессора после выполнения функции RtlUnwind. Указатели инструкций этих состояний сопоставляются с ассемблерными инструкциями посредством уникальных номеров. Следует обратить внимание на последний случай, где RAX регистр принял значение параметра ReturnValue, а стек вызов сократился до одной функции, т.е. кадры функций Func1, Func2 и Func3 более не существуют в стеке. Поскольку значение RAX после раскрутки не нулевое, функция _tmain выведет сообщение на экран. В обычном случае, т.е. если бы раскрутка не выполнялась, это сообщение не будет выведено, т.к. функция Func3 возвращает false. Также следует обратить внимание на то, что цикл поиска указателя кадра функции _tmain выполняет четыре итерации, когда раскручиваемых функций всего три. Это связано с ранее обсуждаемыми особенностями функции RtlVirtualUnwind. Дело в том, что после вызова функции RtlVirtualUnwind параметры HandlerData и EstablisherFrame примут соответствующие значения для той функции, для которой выполнялась виртуальная раскрутка, когда параметр ContextRecord будет отражать состояние процессора сразу после вызова раскрученной функции. Следовательно, на третьей итерации цикла функция RtlVirtualUnwind вернет в параметр EstablisherFrame указатель кадра для функции Func1, когда параметр ContextRecord будет отражать состояние процессора сразу после вызова функции Func1. Поэтому требуется выполнить дополнительную итерацию, чтобы определить указатель кадра функции _tmain.



Функция RtlUnwind/RtlUnwindEx, также, до раскрутки стека, последовательно вызывает обработчики раскрутки всех функций, начиная с самой себя и до функции, которая является целевой, включительно. Поскольку функция RtlUnwind/RtlUnwindEx не имеет обработчиков исключений/раскрутки, то в процессе виртуальной раскрутки она будет просто пропущена и, следовательно, не будет никаких побочных эффектов. С другой стороны, это накладные расходы, т.к. чтобы найти кадр функции, которая вызвала функцию RtlUnwind/RtlUnwindEx, необходимо выполнить дополнительную виртуальную раскрутку. Процесс вызова обработчиков и изменение состояния процессора в целях передачи управления одной из предыдущих функций и является так называемой раскруткой.



Ниже на рисунке 4 изображена блок-схема функции RtlUnwindEx.





Рисунок 4



В начале своей работы функция получает нижний и верхний лимиты стека. Далее функция захватывает текущее состояние процессора посредством вызова функции RtlCaptureContext. Таким образом, структура CONTEXT будет отражать состояние процессора сразу после вызова функции RtlCaptureContext. Эта же структура используется в качестве первоначального состояния процессора, с которого начинается виртуальная раскрутка функций. Функция RtlUnwindEx в процессе своей работы использует две структуры CONTEXT: одна отражает состояние процессора в момент выполнения функции, для которой выполняется вызов обработчика (здесь и далее — текущий контекст); другая отражает состояние процессора сразу после возврата из этой функции (здесь и далее — предыдущий контекст). Это необходимо из-за ранее обсуждаемых особенностей функции RtlVirtualUnwind. Также функция RtlUnwindEx, как это уже ранее обозначалось, инициализирует структуру EXCEPTION_RECORD для последующей передачи обработчикам раскрутки, если соответствующий параметр не был передан при вызове функции.



Далее функция формирует первоначальное значение поля ExceptionFlags для структуры EXCEPTION_RECORD. Это значение хранится в локальной переменной и изначально не хранится в поле самой структуры. Функция устанавливает флаг EXCEPTION_UNWINDING, и если адрес кадра целевой функции не был передан функции, тогда функция также устанавливает флаг EXCEPTION_EXIT_UNWIND. Таким образом, флаг EXCEPTION_UNWINDING для обработчиков означает, что выполняется раскрутка, а флаг EXCEPTION_EXIT_UNWIND означает, что раскручиваются кадры всех функций.



Далее функция посредством функции RtlLookupFunctionEntry получает адрес PE образа и указатель на RUNTIME_FUNCTION структуру функции этого образа, обработчик которой необходимо вызвать (здесь и далее — текущая функция). Адрес одной из инструкций этой функции извлекается из текущего контекста. На первой итерации это будет адрес инструкции самой функции RtlUnwindEx. Если функция RtlLookupFunctionEntry не вернула указатель, тогда считается, что текущая функция, для которой выполнялась попытка вызова её обработчика, — простая, и, следовательно, функция не имеет кадра. Т.к. простые функции не выделяют память в стеке, значение их RSP будет указывать на адрес возврата, следовательно, для таких функций функция RtlUnwindEx извлекает этот адрес, копирует его значение в текущий контекст и увеличивает значение поля Rsp текущего контекста на 8. Теперь текущий контекст отражает состояние процессора в момент выполнения следующей по стеку выше функции. Затем функция продолжит свою работу, начиная с получения адреса PE образа и указателя на RUNTIME_FUNCTION структуру, для адреса новой инструкции, уже для следующей по стеку выше функции.



Для кадровых функций функция RtlLookupFunctionEntry вернет указатель на RUNTIME_FUNCTION структуру. В таком случае вызывается функция RtlVirtualUnwind с целью определить указатель кадра текущей функции, а также адрес ее обработчика и указатель на данные для этого обработчика. Перед вызовом функции RtlVirtualUnwind функция RtlUnwindEx скопирует текущий контекст в предыдущий. Это выполняется с той целью, чтобы сохранить состояние процессора, описывающее момент выполнения текущей функции на тот случай, если функция окажется целевой. Уже неоднократно упоминалось, что функция RtlVirtualUnwind возвращает адрес кадра той функции, которая выполнялась в переданном состоянии процессора, когда по возврату из функции RtlVirtualUnwind состояние будет описывать следующую по стеку выше функцию. Следовательно, когда функции RtlUnwindEx потребуется возобновить выполнение целевой функции, невозможно будет использовать то состояние процессора, которое вернула функция RtlVirtualUnwind, т.к. оно будет отражать выполнение той функции, которая вызвала целевую функцию. Сразу после вызова функции RtlVirtualUnwind, функция RtlUnwindEx выполнит проверку указателя кадра раскрученной функции на выход за пределы лимита стека. Также функция проверит, располагается ли кадр текущей функции в стеке выше, чем кадр целевой функции, что в свою очередь будет означать, что функция RtlUnwindEx пропустила кадр целевой функции вследствие повреждения стека, повреждения .pdata секции и т.п. В обоих случаях функция сгенерирует исключение STATUS_BAD_STACK. В противном случае, если функция RtlVirtualUnwind не вернула адрес обработчика, то функция RtlUnwindEx поменяет местами текущий и предыдущий контексты, если текущая функция не являлась целевой. Таким образом, следующая по стеку выше функция станет текущей. Далее, функция продолжит свою работу, начиная с получения адреса PE образа и указателя на RUNTIME_FUNCTION структуру, для адреса новой инструкции, уже для следующей по стеку выше функции.



Если функция RtlVirtualUnwind вернула адрес обработчика для текущей функции, тогда ее обработчик необходимо вызвать. Перед его вызовом функция RtlUnwindEx установит флаг EXCEPTION_TARGET_UNWIND в том случае, если текущая функция является целевой. Таким образом, обработчик этой функции сможет определить, что его соответствующая функция является функцией, управление которой передается. Затем функция RtlUnwindEx обновит содержимое поля ExceptionFlags структуры EXCEPTION_RECORD из своей локальной копии. Обработчик исключения впервые обсуждался в разделе 3 второй части данной статьи, а его прототип изображен на рисунке 5. Перед вызовом обработчика функция, как и функция RtlDispatchException, обсуждаемая в разделе 2.2 третьей части данной статьи, подготавливает структуру DISPATCHER_CONTEXT, которая активно используется в случаях вложенных исключений (nested exception) и активной раскрутки (collided unwind). Определение самой структуры также изображено на рисунке 17 в разделе 2.2 третьей части данной статьи. Поля этой структуры инициализируются так же, как и в случае с функцией RtlDispatchException, с тем исключением, что поле TargetIp будет содержать значение соответствующего параметра переданного функции RtlUnwindEx, т.е. адрес инструкции, с которого будет возобновлено выполнение после раскрутки; поле ContextRecord будет содержать указатель на структуру CONTEXT, которая описывает состояние процессора в момент выполнения текущей функции, а не следующей по стеку выше; поле ScopeIndex содержит текущее значение локальной переменной и будет более подробно рассмотрено при обсуждении конструкций try/except и try/finally.



Обработчик, как и в случае с функцией RtlDispatchException, не вызывается напрямую, и вместо этого используется вспомогательная функция RtlpExecuteHandlerForUnwind, которая принимает такие же параметры, как и сам обработчик, а также возвращает такое же значение. Данная функция фактически является оберткой над функцией обработчика раскрутки и используется для того, чтобы перехватывать исключения, возникшие в процессе выполнения самого обработчика. Ассемблерное представление функции представлено ниже на рисунке 5.





Рисунок 5



Как отражено на рисунке, сначала функция выделяет память в стеке для регистровых переменных и одной переменой, сохраняет указатель на переданную DISPATCHER_CONTEXT структуру в этой переменной и вызывает обработчик исключения, адрес которого хранится в поле LanguageHandler структуры DISPATCHER_CONTEXT. Также обратите внимание на присутствие заполнителя тела функции. Его роль такая же, как и для функции RtlpExecuteHandlerForException. Ассемблерное представление функции обработчика исключения представлено ниже на рисунке 6.





Рисунок 6



Как отражено на рисунке, обработчик копирует контекст предыдущего процесса раскрутки в структуру DISPATCHER_CONTEXT текущего процесса поиска обработчика или раскрутки. Это позволяет продолжить поиск обработчика с того места, где была ранее прервана раскрутка, или продолжить ранее прерванную раскрутку. Также это позволяет пропустить вызов обработчиков тех функций, для которых такой вызов уже был выполнен во время предыдущей раскрутки. Следует также отметить, что вызов обработчиков возобновляется с той функции, на которой был прерван процесс раскрутки. Т.е. для таких функций обработчик будет вызван повторно. Более подробное пояснение этому будет дано во время обсуждения конструкций try/except и try/finally.



После того, как структура DISPATCHER_CONTEXT была подготовлена, функция RtlUnwindEx вызывает соответствующий обработчик. Сразу после вызова обработчика функция сбрасывает флаги EXCEPTION_COLLIDED_UNWIND и EXCEPTION_TARGET_UNWIND.



Если обработчик вернул ExceptionContinueSearch, то функция поменяет местами текущий и предыдущий контексты, если текущая функция не являлась целевой. Таким образом, следующая по стеку выше функция станет текущей. Далее функция продолжит свою работу, начиная с получения адреса PE образа и указателя на RUNTIME_FUNCTION структуру, для адреса новой инструкции, уже для следующей по стеку выше функции.



Если обработчик вернул ExceptionCollidedUnwind, то это означает, что в процессе раскрутки была обнаружена другая активная раскрутка, в контексте которой возникло исключение. В этом случае структура DISPATCHER_CONTEXT функции RtlUnwindEx будет содержать контекст прерванной раскрутки, т.к. он был скопирован обработчиком функции RtlpExecuteHandlerForUnwind. Следовательно, функция обновит текущий контекст из поля ContextRecord структуры DISPATCHER_CONTEXT, посредством функции RtlVirtualUnwind получит предыдущий, установит флаг EXCEPTION_COLLIDED_UNWIND и вызовет обработчик, в контексте которого ранее возникло исключение, и в зависимости от его возвращаемого результата выполнит ранее описанные действия.



Во всех остальных случаях функция RtlUnwindEx сгенерирует исключение STATUS_INVALID_DISPOSITION.



На каждой итерации перед получением адреса PE образа и указателя на RUNTIME_FUNCTION структуру функция посредством функции RtlpIsFrameInBounds проверяет, что указатель кадра функции, для которой выполнялась попытка вызова ее обработчика, находится в пределах лимита стека и не является указателем кадра целевой функции. Если такая проверка дает положительный результат, то работа функции продолжается. Иначе, если указатель кадра выходит за пределы лимита и указатель не является адресом кадра целевой функции, значит либо выполнялась раскрутка при выходе, и в процессе раскрутки ни один из обработчиков не остановил этот процесс, либо указатель кадра функции не был найден вследствие повреждения стека, повреждения .pdata секции и т.п. В таком случае функция RtlUnwindEx породит исключение, чтобы предоставить возможность отладки, но не в целях его обработки. Во всех остальных случаях работа функции завершится, т.к. найден кадр целевой функции. В этом случае в поле Rax текущего контекста будет записано значение переданного параметра ReturnValue, а в поле Rip этого же контекста будет записано значение переданного параметра TargetIp, если кодом исключения не является код STATUS_UNWIND_CONSOLIDATE. Т.к. этот случай не имеет непосредственного отношения к обсуждаемой теме, данный код не будет обсуждаться в данной статье. Здесь следует только отметить, что для раскрутки с таким кодом функцией RtlRestoreContext будет вызван обработчик перед возобновлением работы, и если поле Rip будет обновлено, обработчик получит неверное представление о состоянии процессора. Далее функция RtlUnwindEx вызывает функцию RtlRestoreContext, которой она передает два параметра: текущий контекст и указатель на структуру EXCEPTION_RECORD, который был либо передан функции RtlUnwindEx, либо передается указатель на локально сформированную структуру. К моменту вызова функции RtlRestoreContext обработчики раскрутки всех функций в стеке, начиная с его вершины и до целевой функции включительно, были вызваны. Функция RtlRestoreContext не возвращает управления, т.к. применяет к процессору новое состояние.



Стоит отметить, что проверка указателя кадра на каждой итерации является ошибкой в реализации, т.к. следует проверять указатель стека из текущего контекста, а не указатель кадра. В первую очередь данная проверка выполняется сразу после виртуальной раскрутки текущей функции. И если результат проверки отрицательный, то функция сгенерирует исключение. Следовательно, данная проверка на каждой итерации никогда не даст отрицательного результата, а поскольку не проверяется указатель стека, функция в процессе своей работы может выйти за его пределы. Данная ошибка сохраняется до сих пор.



2. Конструкции try/except и try/finally



С точки зрения операционной системы, как это уже было рассмотрено при описании обработки исключений и раскрутки стека, сама обработка всегда является обычным вызовом соответствующей функции. Конструкции try/except и try/finally являют собой механизм, который позволяет во время разработки размещать код обработки исключений прямо в теле функции. Следовательно, поскольку код обработки размещается непосредственно в теле, эти части кода не могут быть вызваны операционной системой напрямую. Чтобы обеспечить корректное функционирование этих конструкций, компилятор генерирует вспомогательную информацию, которой пользуются вызываемые операционной системой обработчики исключений. Ранее упоминалось, что всю обработку исключений условно можно поделить на две фазы. Фаза поиска и передача управления обработчикам исключений обсуждаемых конструкций и является второй фазой. Такое разделение необходимо, поскольку разные языки программирования по-разному обрабатывают исключения; таким образом, сама операционная система абстрагирована от понимания разнообразия механизмов разных языков программирования.



Компилятор C/C++ резервирует функцию __C_specific_handler. Именно эта функция отвечает за поиск и передачу управления соответствующей конструкции. Сама функция должна быть реализована программистом. Такой подход позволяет абстрагировать компилятор от понимания работы самой операционной системы и адаптировать исполняемый образ к любой среде исполнения, например, к подсистеме Win32, к среде исполнения ядра Windows или к любой другой среде. Также реализация этой функции экспортируется модулем ntdll.dll в пользовательском пространстве и модулем ntoskrnl.exe в пространстве ядра. Поставляемые Windows SDK и WDK содержат библиотеки, которые импортируют эту функцию из соответствующего модуля. Поле ExceptionHandlerAddress структуры EXCEPTION_HANDLER будет содержать указатель на эту функцию, когда поле LanguageSpecificData этой же структуры будет содержать структуру SCOPE_TABLE, которая описывает расположение всех конструкций в теле функции. Прототип функции изображен на рисунке 5 в разделе 3 второй части данной статьи. Определение структуры SCOPE_TABLE представлено ниже, на рисунке 7.





Рисунок 7



Поле Count содержит количество конструкций в теле функции и, следовательно, количество элементов ScopeRecord в структуре. Компилятор генерирует для каждой конструкции соответствующий ScopeRecord элемент структуры, который в свою очередь описывает расположение соответствующей конструкции в теле функции, а также расположение его обработчиков. Элементы ScopeRecord сортируются в следующем порядке: невложенные конструкции следуют друг за другом в порядке их появления в коде, когда вложенные конструкции всегда следуют перед конструкцией, в которую они вложены. Поле BeginAddress элемента ScopeRecord содержит адрес начала try блока. Поле EndAddress содержит адрес инструкции, следующей за последней инструкцией, заключенной в try блок. Поле JumpTarget, если не равно нулю, содержит адрес первой инструкции кода, заключенной в except блок. Код except блока следует сразу после кода, заключенного в try блок. Поле HandlerAddress содержит адрес функции фильтра except блока. Несмотря на то, что фильтр исключения заключается в скобках после except выражения, код фильтра генерируется компилятором в виде отдельной функции, прототип которой изображен ниже, на рисунке 8.





Рисунок 8



Функция принимает два параметра. Первый параметр содержит указатель на структуру, определение которой приведено ниже, на рисунке 9. Второй параметр содержит указатель кадра функции, в которой располагается соответствующая конструкция. Этот указатель используется фильтром в том случае, если во время фильтрации необходимо получить доступ к локальным переменным функции, в которой располагается соответствующая конструкция.





Рисунок 9



Как это отражено на рисунке выше, структура содержит два указателя. Первый указывает на структуру, описывающую причину исключения, второй — на структуру, описывающую состояние процессора в момент возникновения исключения.



Функция фильтра возвращает следующие значения: EXCEPTION_EXECUTE_HANDLER, EXCEPTION_CONTINUE_SEARCH, EXCEPTION_CONTINUE_EXECUTION. Первое значение означает, что требуется передать управление обработчику исключения, для которого была вызвана функция фильтра. Также это значение может быть закодировано непосредственно в поле HandlerAddress. В таком случае конструкция не имеет фильтра, и передача управления обработчику исключения этой конструкции выполняется всегда. Второе значение указывает на то, что следует продолжить поиск обработчика исключения. Третье значение означает, что следует прервать поиск и возобновить выполнение прерванного потока.



Если поле JumpTarget равно нулю, тогда данная конструкция является finally конструкцией, и код, заключенный в finally блоке, следует сразу после кода, заключенного в try блок. В этом случае поле HandlerAddress содержит адрес функции, которая по своему содержимому повторяет код, заключенный в finally блок. Прототип этой функции изображен на рисунке 10.





Рисунок 10



Поскольку код, заключенный в finally блок, выполняется независимо от того, возникало исключение или нет, то в случае, если исключение имело место, этот код не может быть вызван напрямую, т.к. он располагается в теле функции. И поскольку во время раскрутки вызывать этот код необходимо, компилятор дублирует код, заключенный в finally блок, в виде отдельной функции. Первый параметр является булевым значением, означающим, что код finally блока выполняется из-за ненормального завершения кода, заключенного в try блок (т.е. в процессе его выполнения возникло исключение). Второй параметр содержит указатель кадра функции, в которой располагается соответствующая конструкция. Этот указатель используется функцией так же, как и функцией фильтра исключения – доступ к локальным переменным функции, в которой располагается соответствующая конструкция. Функция не возвращает никаких значений.



В тех случаях, когда в процессе выполнения кода, заключенного в try блоке, не возникло исключения, выполняется код finally блока, который следует сразу после кода try блока.



Все адреса в структуре SCOPE_TABLE являются адресами относительно начала образа.



Ниже, на рисунке 11, изображен пример структуры SCOPE_TABLE, которую сгенерирует компилятор.





Рисунок 11



На рисунке выше изображен пример программы, _tmain функция которой включает в себя try/except и try/finally конструкции. Слева от исходного кода изображено ассемблерное представление функций: _tmain, функции фильтра нижней try/except конструкции и функции, дублирующей код, заключенный в finally блок. Функции перечислены снизу вверх. Адреса ассемблерных инструкций являются абсолютными. Зелеными маркерами сопоставляется код, заключенный в блоки, с его ассемблерными эквивалентами. Следует обратить внимание на то, что блок кода с маркером 2 в ассемблерном представлении встречается дважды: в теле функции _tmain и в самой верхней функции. Последнее является дубликатом кода, заключенного в блок finally. Также следует обратить внимание на присутствие инструкции nop после инструкции вызова функции FailExecution в блоке кода с маркером 1. Данная инструкция также является заполнителем, как и в случаях с функциями шлюзов, функцией RtlpExecuteHandlerForException и функцией RtlpExecuteHandlerForUnwind. Если заполнитель будет отсутствовать, то при проверке инструкции на принадлежность к той или иной конструкции может быть сделано ошибочное предположение об ее принадлежности. В данном случае будет сделано ошибочное предположение о том, что инструкция вызова функции FailExecution не принадлежит блоку кода с маркером 1, т.к. функция RtlVirtualUnwind после раскрутки вернет адрес не на инструкцию вызова функции FailExecution, а на инструкцию сразу после нее. По этой причине компилятор добавляет заполнитель после инструкции вызова функции, если та в свою очередь является последней инструкцией в блоке. Если инструкция вызова является не последней инструкцией в блоке, тогда такого заполнителя не будет.



В левой части рисунка изображены структуры, которые сгенерирует компилятор. Вверху изображен элемент таблицы функций, ниже него изображена структура UNWIND_INFO, на которую ссылается этот элемент. Несмотря на то, что структура EXCEPTION_HANDLER не является частью структуры UNWIND_INFO, на рисунке она представлена как часть этой структуры, т.к. если она присутствует, то следует сразу после структуры UNWIND_INFO. Ниже структуры UNWIND_INFO изображено более подробное представление структуры EXCEPTION_HANDLER, ниже него изображено более подробное представление поля LanguageSpecificData этой структуры, в котором размещается структура SCOPE_TABLE. В самом низу последовательно изображены элементы ScopeRecord массива этой структуры. Все адреса в сгенерированных структурах являются относительными. Также эти адреса сопоставляются с адресами ассемблерного кода посредством уникальных номеров.



Более подробно стоит остановиться на элементах ScopeRecord массива. Элемент 0 описывает расположение блока с маркером 1. Поле HandlerAddress этого элемента содержит адрес функции, дублирующей код finally блока с маркером 2. Поле JumpAddress содержит 0, т.к. это finally блок. Элемент 1 описывает расположение блока с маркером 3. Поле HandlerAddress этого элемента содержит значение 1, что в свою очередь означает, что конструкция не имеет фильтра, и при возникновении исключения следует всегда передавать управление коду блока с маркером 4. Поле JumpAddress содержит адрес начала блока с маркером 4. Элемент 2 описывает расположение блока с маркером 5. Поле HandlerAddress этого элемента содержит адрес функции фильтра, код которого заключен в скобки после ключевого слова except. Ассемблерное представление функции фильтра располагается посередине, между функцией _tmain и функцией, дублирующей finally блок. Как изображено на рисунке, функция фильтра вызывает функцию ExceptionFilter, которая принимает указатель на структуру, описывающую контекст исключения. Поле JumpAddress содержит адрес начала блока с маркером 6.



Несмотря на то, что функция __C_specific_handler не представлена на рисунке, поле ExceptionHandlerAddress структуры EXCEPTION_HANDLER, содержит адрес этой функции. Эта функция будет вызвана операционной системой во время поиска обработчика исключения или во время раскрутки стека. Следовательно, реализация этой функции отвечает за интерпретацию структуры SCOPE_TABLE, вызов фильтров, вызов finally блоков и передачу управления except блокам.



Блок-схема функции __C_specific_handler изображена ниже, на рисунке 12.





Рисунок 12



В начале своей работы функция получает: адрес начала PE образа; относительный адрес инструкции, принадлежащий телу функции, для которой обработчик был вызван; указатель на структуру SCOPE_TABLE. В зависимости от выполняемой операции (поиск обработчика или раскрутка) работа функции варьируется.



Если выполняется поиск обработчика, то функция подготавливает структуру EXCEPTION_POINTERS, указатель на которую передается фильтрам соответствующих конструкций. Затем функция последовательно сканирует ScopeRecord элементы структуры SCOPE_TABLE и проверяет, принадлежит ли ранее полученный адрес инструкции какой-либо конструкции. Если принадлежит, тогда также проверяется, является ли конкретная конструкция try/except конструкцией, и, если нет, то она просто игнорируется, и проверяется следующий элемент. В противном случае вызывается фильтр этой конструкции. Если фильтр вернул EXCEPTION_CONTINUE_SEARCH, то данная конструкция игнорируется, и проверяется следующий элемент. Если фильтр вернул EXCEPTION_CONTINUE_EXECUTION, то функция завершает свою работу и возвращает ExceptionContinueExecution, чтобы указать операционной системе прекратить поиск обработчика и возобновить выполнение прерванного потока. Если фильтр вернул EXCEPTION_EXECUTE_HANDLER, то функция вызывает функцию RtlUnwind, которой в качестве кадра целевой функции указывается кадр функции, обработчик которой был вызван; в качестве адреса инструкции, с которой будет продолжено выполнение, передается адрес первой инструкции except блока; а также передается код исключения, который будет содержаться в RAX регистре сразу после передачи управления целевой функции. Функция RtlUnwind перед передачей управления последовательно вызовет обработчики всех промежуточных функций.



Если выполняется раскрутка, тогда функция ведет себя иначе. Сначала функция получает относительный адрес инструкции, с которой будет возобновлено выполнение. Затем функция последовательно сканирует ScopeRecord элементы структуры SCOPE_TABLE и проверяет, принадлежит ли ранее полученный адрес инструкции какой-либо конструкции. Если принадлежит, тогда также проверяется, является ли конкретная конструкция try/finally конструкцией. Если является, тогда вызывается ее обработчик, который по сути является дубликатом кода, заключенного в finally блок. Перед вызовом функция увеличит значение поля ScopeIndex структуры DISPATCHER_CONTEXT на единицу. Значение параметра AbnormalTermination при вызове этого обработчика всегда является TRUE. Следовательно, макрос AbnormalTermination всегда будет возвращать TRUE для этих блоков, вызванных таким образом. Для кода finally блока, располагающегося в теле самой функции, этот же макрос всегда будет возвращать FALSE. В этих случаях компилятор явно подставляет это значение. Иначе говоря, макрос AbnormalTermination возвращает TRUE только тогда, когда выполняется раскрутка. Практически, вследствие исключения. Если конструкция не является try/finally, тогда проверяется, не является ли адрес начала except блока адресом, с которого будет продолжено выполнение. И, если является, тогда работа функции завершается. Такая проверка необходима потому, что конструкция try/except может быть вложена в другую конструкцию try/finally, как это изображено ниже, на рисунке 13.





Рисунок 13



Как видно из рисунка, если такую проверку не выполнить, то во время раскрутки будет вызван finally блок внешней конструкции. А это недопустимо.



Если функция выполняет раскрутку для целевой функции, т.е. флаг EXCEPTION_TARGET_UNWIND установлен в поле ExceptionFlags структуры EXCEPTION_RECORD, тогда она выполняет дополнительную проверку перед вызовом обработчика. Суть проверки заключается в том, чтобы определить, не принадлежит ли адрес, с которого будет продолжено выполнение, самой конструкции, а не ее обработчику. И если принадлежит, тогда работа функции завершается. Подобная ситуация может быть только в случае использования в пределах finally блоков операторов goto, которые указывают за пределы этих блоков. Данная ситуация изображена ниже, на рисунке 14.





Рисунок 14



Как видно из рисунка, если такую проверку не выполнить, то во время раскрутки будет вызван finally блок внешней конструкции. А это недопустимо. Также, если функция не является целевой, тогда данная проверка не нужна.



Следует отметить, что в обоих случаях (и в случае поиска обработчика, и в случае выполнения раскрутки) сканирование элементов начинается не с начала, а с элемента, номер которого хранится в поле ScopeIndex структуры DISPATCHER_CONTEXT. Как это уже было отмечено, функция перед вызовом обработчика try/finally конструкции увеличивает значение поля ScopeIndex структуры DISPATCHER_CONTEXT на единицу. Ранее упоминалось, что если в процессе поиска обработчика или выполнения раскрутки будет обнаружен незавершенный процесс раскрутки, то продолжение поиска обработчика или выполнения раскрутки будет возобновлено с прерванного места. При этом обработчик функции, который породил исключение, будет вызван повторно, когда обработчики остальных функций вызваны не будут. В такой ситуации недопустимо, чтобы обработчики конструкций, которые уже были вызваны, оказались вызваны повторно. Эта ситуация изображена ниже, на рисунке 15.





Рисунок 15



На рисунке выше изображен стек вызова функций, слева от которого изображена стрелка направления его роста, а справа изображена часть кода функции Func1. Функции RtlDispatchException и RtlUnwindEx хоть и вызывают обработчики функций посредством функций RtlpExecuteHandlerForException и RtlpExecuteHandlerForUnwind, но в стеке вызовов эти функции для краткости не присутствуют. Функция Func1 вызвала функцию Func2, которая в свою очередь вызвала функцию Func3, которая породила исключение. Как только функция RtlDispatchException получала управление, она последовательно вызвала обработчики для функций: сначала Func3, затем Func2 и в конечном счете Func1. Обработчик функции Func1 нашел конструкцию, которая может обработать исключение, и вызвал функцию RtlUnwind для передачи управления обработчику этой конструкции. Функция RtlUnwind в свою очередь вызвала RtlUnwindEx, которая последовательно вызывала обработчики для функций сначала Func3, затем Func2 и в конечном счете Func1. Обработчик функции Func1 вызвал обработчик самого вложенного finally блока, который в свою очередь породил новое исключение. Как только функция RtlDispatchException получила управление, она последовательно вызывала обработчики предыдущих функций. Один из этих обработчиков окажется обработчиком функции RtlpExecuteHandlerForUnwind, которую вызывает функция RtlUnwindEx при передаче управления обработчику раскручиваемой функции. Обработчик функции RtlpExecuteHandlerForUnwind скопирует контекст раскрутки из RtlUnwindEx функции в функцию RtlDispatchException и, после возврата управления ей, поиск обработчика продолжится с того места, где была прервана раскрутка. Поскольку функция RtlUnwindEx ранее раскрутила функции Func3 и Func2, их обработчики вызываться не будут. Но поскольку функция Func1 породила исключение, она не была раскручена функцией, и, следовательно, ее обработчик будет вызван. Поскольку функция __C_specific_handler во время раскрутки увеличивает значение поля ScopeIndex структуры DISPATCHER_CONTEXT на единицу перед вызовом обработчика конструкции, то в скопированном контексте это поле будет равно 1. Следовательно, когда функция __C_specific_handler будет вызвана для функции Func1 вновь, поиск конструкции начнется с конструкции с индексом 1. Таким образом конструкция, породившая исключение, будет пропущена. Возобновление раскрутки выполняется аналогичным образом. Несмотря на то, что операционная система и компилятор абстрагированы друг от друга, наличие поля ScopeIndex в структуре DISPATCHER_CONTEXT является нарушением этой абстракции.



В завершение обсуждения try/except и try/finally конструкций стоит описать принцип работы макроса GetExceptionCode. Использование этого макроса возможно только в except блоках. Этот макрос читает содержимое регистра RAX, а при описании функции __C_specific_handler упоминалось, что передача управления конкретному except блоку выполняется посредством функции RtlUnwind, которая принимает параметр, значение которого будет записано в RAX регистре после передачи управления. Через этот параметр передается код возникшего исключения.



Также стоит описать принцип работы макроса GetExceptionInformation. Использование этого макроса возможно только в выражениях, заключенных в скобках после ключевого слова except. Поскольку в действительности выражение, заключенное в скобки (иначе говоря, фильтр), является отдельной функцией, которая принимает два параметра, данный макрос получает значение первого параметра. При описании функции __C_specific_handler упоминалось, что функция фильтра принимает два параметра, где первый параметр является указателем на структуру, описывающую исключение и состояние процессора в момент возникновения исключения.



3. Недостатки реализации механизма



Одним из недостатков данного механизма является использование в finally блоках операторов goto, которые указывают за пределы этих блоков. В этом случае компилятор C/C++, вместо прямой передачи управления, использует зарезервированную функцию _local_unwind, прототип которой изображен ниже, на рисунке 16.





Рисунок 16



Первый параметр функции принимает адрес кадра функции, до которой следует раскрутить стек, когда второй принимает адрес инструкции, которой следует передать управление после раскрутки. Сама функция должна быть реализована программистом. Также реализация этой функции экспортируется модулем ntdll.dll в пользовательском пространстве и модулем ntoskrnl.exe в пространстве ядра. Поставляемые Windows SDK и WDK содержат библиотеки, которые импортируют эту функцию из соответствующего модуля. Реализация самой функции очень простая, она вызывает функцию RtlUnwind, которой передает два своих параметра. Остальные параметры функции RtlUnwind при вызове обнулены.



Использование компилятором функции _local_unwind вместо прямой передачи управления в первую очередь связано с невозможностью передать управление в произвольное место функции в том случае, если finally блок был вызван в результате раскрутки. В таком случае передать управление в нужное место функции возможно только посредством нового процесса раскрутки. Такой подход имеет побочные эффекты. Оператор goto, в своей основе, передает прямое управление, когда раскрутка приводит к вызову finally блоков. Следовательно, до фактической передачи управления будут вызваны finally блоки, которые могут изменить контекст самой функции. Microsoft не рекомендует использовать оператор goto таким образом, а компилятор выдаст соответствующее предупреждение.



Заключение



В данной части статьи мы закончили обсуждение данного механизма. Необходимость в его реализации пришла из практики. И в первую очередь применяется в boot-time гипервизоре с целью упростить и ускорить разработку. В процессе реализации возникало множество проблем, которые были устранены, а сама статья, в первую очередь, нацелена на облегчение понимания тех, кто также заинтересован в подобных разработках.
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/326878/

Метки:   Комментарии (0)КомментироватьВ цитатник или сообщество
rss_rss_hh_new

Как сделать свой С++ код кроссплатформенным?

Среда, 19 Апреля 2017 г. 12:50 (ссылка)

Возможно, кто-то, прочитав заголовок, спросит: «Зачем что-то делать со своим кодом?! Ведь С++ кроссплатформенный язык!». В целом, это так… но только пока нигде нет завязок на специфичные возможности компилятора и целевой платформы…



В реальной жизни разработчики, решающие конкретную задачу под конкретную платформу, редко задаются вопросом «А точно ли это соответствует Стандарту С++? А вдруг это расширение моего компилятора». Они пишут код, запускают сборку и чинят места, на которые выругался их компилятор.

В итоге получаем приложение, которое, в некоторой степени, «заточено» под конкретный компилятор (и даже под его конкретную версию!) и целевую ОС. Более того, из-за скудности стандартной библиотеки С++ некоторые вещи просто невозможно написать, не воспользовавшись специфичным API системы.



Так было и у нас в Тензоре. Мы писали на MS Visual Studio 2010. Наши продукты были 32-х битными Windows-приложениями. И, само собой, код был пронизан всевозможными завязками на технологии от Microsoft. Однажды мы решили, что пора осваивать новые горизонты: пора научить СБИС работать под Linux и другими ОС, пора попробовать перейти на другое «железо» (POWER).



В данном цикле статей я расскажу, как мы сделали свои продукты настоящими кроссплатформенными приложениями; как заставили их работать на Linux, MacOS и даже под iOS и Android; как запустили свои приложения на множестве аппаратных архитектур (x86-64, POWER, ARM и другие); как научили работать на big-endian машинах.









Основа всех наших продуктов — собственный фреймворк «Платформа СБИС» (далее по тексту — «Платформа»), который по масштабности сравним с Qt. В платформе есть практически все, что нужно разработчику: от простых функций быстрого преобразования числа в строковую форму до мощного отказоустойчивого сервера приложений.



На базе Платформы наши разработчики реализуют свои продукты (даже мобильные приложения), решающие всевозможные бизнес-задачи. Нам хотелось освободить их код (далее по тексту будем называть их код «прикладным») от всевозможных завязок на целевую программную и аппаратную платформу, спрятав всю специфику в глубинах нашего фреймворка.



Платформа СБИС написана на С++, но это вовсе не ограничивает прикладного программиста в выборе языка, кроме C++ могут быть использованы JavaScript, Python, SQL.



Наша компания активно развивает свои продукты, поэтому нужно было «чинить поезд на полном ходу» :)









Нужно было работать так, чтобы остальные разработчики не пострадали от нашей деятельности и с комфортом продолжили разрабатывать свой функционал под Windows на MSVC. Это требование сильно повлияло на многие технические решения и сильно усложнило работу.



Для того чтобы у читателя сформировалось представление о масштабности работ, я приведу некоторые цифры:


  • Объем кода нашего фреймворка ~2 миллиона строк

  • Объем «прикладного» кода (код, основанный на платформе СБИС, решающий конкретные бизнес-задачи), сложно оценить, но он в разы превышает объем Платформы

  • Свыше тысячи программистов в десяти центрах разработки



Скучное вступление закончено. Теперь приблизимся к делу и рассмотрим, с какими проблемами мы столкнулись.



Использование API операционной системы



Как упоминалось выше, стандартная библиотека С++ очень скудная, она не включает многих всюду необходимых возможностей. Например, в С++11 нет функционала для работы с сетью… То есть, как только мы захотели сделать простейший HTTP-запрос, мы вынуждены… написать некроссплатформенный код!



Ситуация еще больше усугубляется, если вы используете не самую свежую версию компилятора, как это было у нас — в MSVS 2010 отвратительная поддержка C++11, отсутствует огромная часть нововведений в ядре языка и в стандартной библиотеке.



Но, к счастью, такие проблемы решаются довольно легко. Есть несколько способов:


  • Пишем свой класс, с несколькими платформоспецифичными реализациями, основанными на вызовах API целевой системы. Во время сборки препроцессорными директивами ifdef выбираем подходящую реализацию.

  • Используем кроссплатформенные библиотеки — есть множество готовых кроссплатформенных библиотек (опять же, использующие внутри себя платформоспецефичные реализации), которые сильно облегчают нашу задачу. Например, для реализации HTTP-клиента мы взяли cURL.



Особенности реализаций компиляторов



В каждой программе есть ошибки. И компилятор тоже не исключение. Поэтому даже на 100% соответствующий Стандарту код может не собраться на каком-то компиляторе.



Так же практически все разработчики компиляторов считают своим долгом добавить в своё детище возможностей, не предусмотренных Стандартом, и тем самым провоцируют программистов к написанию непереносимого кода.



Что получаем в итоге? Код, который написан четко по Стандарту, может не собраться на каком-то компиляторе; код, который компилируется и работает на одном компиляторе, может не собраться или заработать не так на другом…



Можно перечислить множество проблем этого класса. Вот одна из них:



throw std::exception( "что-то пошло не так" ); // соберется только в MSVC++, так как по стандарту нет такого конструктора


Данный код соберется в MSVC++, так как у них определен дополнительный конструктор:



exception( const char* msg ) noexcept;


К сожалению, нет общих приемов, решающих такие проблемы. В этих случаях помогает только опыт, накопленный при изучении используемых в работе инструментов, и хорошее знание Стандарта С++.



В последующих статьях я вернусь к этому вопросу, подробно опишу наиболее часто встречающиеся проблемы и предложу методы их решения.



Неопределенное поведение



В Стандарте С++ есть интересный термин «undefined behavior» (неопределенное поведение).

Вот его определение из Википедии:

Неопределённое поведение (англ. undefined behavior, в ряде источников непредсказуемое поведение[1][2]) — свойство некоторых языков программирования (наиболее заметно в Си), программных библиотек и аппаратного обеспечения в определённых маргинальных ситуациях выдавать результат, зависящий от реализации компилятора (библиотеки, микросхемы) и случайных факторов наподобие состояния памяти или сработавшего прерывания. Другими словами, спецификация не определяет поведение языка (библиотеки, микросхемы) в любых возможных ситуациях, а говорит: «при условии А результат операции Б не определён». Допускать такую ситуацию в программе считается ошибкой; даже если на некотором компиляторе программа успешно выполняется, она не будет кроссплатформенной и может отказать на другой машине, в другой ОС или при других настройках компилятора.






Если вы допустите undefined behavior в своей программе, то это вовсе не значит, что она будет падать или выдавать какие-то ошибки в консоль. Такая программа вполне может работать ожидаемым образом. Но любое изменение настроек компилятора, переход на другой компилятор или на другую версию компилятора, или даже модификация любого фрагмента кода может поменять поведение программы и все сломать!



Многие ситуации с undefined behavior на одном конкретном компиляторе выдают стабильно одинаковое поведение, и ваше тщательно оттестированное приложение будет работать как швейцарские часы. Но как только мы меняем окружение (например, пытаемся запустить программу, собранную другим компилятором), эти баги начинают заявлять о себе и полностью ломают программу.



Классический пример undefined behavior — это выход за границы массива на стеке. Ниже приведен упрощенный фрагмент кода одного из наших приложений с такой проблемой. Этот баг никак не проявлял себя под Windows в течение нескольких лет и «выстрелил» только после портирования под Linux:



std::string SomeFunction()
{
char hex[9];
// some code
hex[9] = 0; // тут выход за границы массива
return hex;
}


По всей видимости, MSVS выравнивала буфер на стеке, добавляя после него несколько байт, и при перезаписи чужой памяти мы попадали на пустое, никем не используемое место. А в GCC проблема стала проявляться интересным образом — программа падала далеко от этого кода, в другой функции (видимо, GCC заинлайнил эту функцию, и она стала переписывать локальные переменные другой функции).



Есть и более изящные, трудноуловимые ситуации с UB. Например, на очень интересные грабли можно наступить при использовании std::sort:



std::vector< std::string > v = some_func();
std::sort( v.begin(), v.end(),
[]( const std::string& s1, const std::string& s2 )
{
if( s1.empty() )
return true;
return s1 < s2;
} );


Казалось бы, где тут может быть UB? А все дело в «плохом» компараторе.

Компаратор должен вернуть true, если s1 нужно поставить перед s2. Рассмотрим, что выдаст наш компаратор, если ему на вход подать две пустые строки:



s1 = "";
s2 = "";
cmp( s1, s2 ) == true => s1 должна стоять перед s2
cmp( s2, s1 ) == true => s2 должна стоять перед s1


Таким образом, есть ситуации, когда компаратор противоречит сам себе, то есть не задает strict weak ordering (ссылка на en.wikipedia.org/wiki/Weak_ordering#Strict_weak_orderings).

Следовательно, мы нарушили требования std::sort к аргументам и получили неопределенное поведение.



И это не придуманный пример. Такую проблему мы поймали при переходе на Linux. Компаратор с подобной ошибкой работал долгие годы под Windows и… начал рушить приложение с SIGSEGV под Linux (i686). Что интересно, баг ведет себя по разному даже на разных дистрибутивах Linux (с разными GCC на борту): где-то приложение падает, где-то зависает, где-то попросту сортирует не так, как ожидалось.



Зачастую ситуации с undefined behavior можно отловить статическими анализаторами (в том числе и встроенными в компилятор). Поэтому в настройках сборки стоит всегда выставлять максимальный уровень предупреждений. А чтобы не потерять полезный warning в толпе предупреждений вида «неиспользуемая переменная», полезно однажды прибраться в коде, после чего включить опцию сборки «трактовать предупреждения как ошибки», чтобы не допустить появления новых незамеченных предупреждений.



Модели данных



Стандарт С++ не дает никаких жестких гарантий о представлении типов данных в памяти компьютера; он задает лишь некоторые соотношения (например, sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long) <= sizeof(long long)) и предоставляет способы определения характеристик типов.



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

В таблице, представленной ниже, перечислены популярные модели данных и приведены соответствующие ей размерности основных типов С++.







В подавляющем большинстве случаев программисту при выборе типа данных нужны гарантии по поводу его размера. Но на практике разработчики зачастую попросту завязываются на размеры базовых типов в системе, на которой они работают. И вновь при переходе на иную программную или аппаратную платформу мы получаем сюрпризы: какой-то код перестает собираться, какой-то — начинает работать по-другому или вовсе перестает работать.



Например, хэш-функция ниже будет выдавать разные результаты на одних и тех же данных при запуске на различных платформах:



unsigned long some_hash( const unsigned char* buf, size_t size )
{
unsigned long res = 0;
for( size_t i = 0; i < size; ++i )
res = res * buf[i] + buf[i] + i;
return res;
}


Большинство таких проблем решаются, если использовать типы с гарантированным размером:



std::int8_t, std::int16_t и т. п.
std::uint32_t some_hash( const unsigned char* buf, size_t size )
{
std::uint32_t res = 0;
for( size_t i = 0; i < size; ++i )
res = res * buf[i] + buf[i] + i;
return res;
}


Знаковость char



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



На самом деле Стандарт С++ не оговаривает знаковость типа char. Из-за этого есть реализации компиляторов, в которых char знаковый, а есть те, где char — беззнаковый.

И это еще одна причина, из-за которой ваша программа может отказаться работать после сборки под другую систему.



Например, этот код работает, как ожидалось, в Linux x86-64, но не работает на Linux POWER (при сборке в GCC с параметрами по умолчанию):



bool is_ascii( char s )
{
return s >= 0;
}


Чтобы избавиться от неопределенности, достаточно добавить явное приведение к нужному типу:



bool is_ascii( char s )
{
return static_cast( s ) >= 0;
}


а в нашем примере можно и вовсе переписать код на битовые операции:



bool is_ascii( char s )
{
return s & 0x80 == 0;
}


Представление строк



Стандарт С++ никак не регламентирует некоторые аспекты, и каждый компилятор решает эти вопросы по своему усмотрению.



Например, нет никаких гарантий, как будут представлены в памяти строковые константы.

Компилятор MSVS кодирует строковые константы в Windows-1251, а GCC — по умолчанию кодирует в UTF-8.



Из-за таких отличий один и тот же код выдаст разные результаты: strlen(«Хабр») в программе, собранной на MSVS выдаст 4; в GCC — 8.



Так же проблемы придут и при вводе-выводе данных.

Например, наша тестовая программа умеет сохранять и читать данные в каких-то текстовых файлах:



std::string readstr()
{
std::ifstream f( "file.txt" );
std::string s;
std::getline( f, s );
return s;
}


void writestr( const std::string& s )
{
std::ofstream f( "file.txt" );
f.write( s.c_str(), s.size() );
}


Все будет работать хорошо, пока эти файлы пишут и читают приложения, собранные в одном окружении. Но что будет, если этот файл запишет Windows-приложение, а прочитает приложение под Linux?.. Получим «кракозябры» :)



Стандарт С++ никак не регламентирует некоторые аспекты, и каждыйкомпилятор решает эти вопросы по своему усмотрению.Например, нет никаких гарантий, как будут представлены в памяти строковые константы.Компилятор MSVS кодирует строковые константы в Windows-1251, а GCC —по умолчанию кодирует в UTF-8



Как быть в таких случаях? Общий принцип возможных решений один — выбрать какой-то унифицированный способ представления строк в памяти программы и при вводе-выводе делать явное кодирование/декодирование строк. Многие разработчики используют кодировку UTF-8 в своих программах. И это очень хорошее решение.



Но, как я упоминал выше, мы «чинили поезд на полном ходу», и мы не могли сломать некоторые инварианты, на которые полагался наш код (он разрабатывался с учетом, что кодировка строк — Windows-1251):


  • фиксированная ширина символов — возможен произвольный доступ к символу по его индексу

  • есть возможность написания строковых констант на русском языке в коде



В кодировке UTF-8 символы могут представляться различным количеством байт, из-за чего первому требованию она не удовлетворяет. Второе требование в случае UTF-8 не выполняется, к примеру, в MSVC 2010, где строковые константы кодируются в Windows-1251. Поэтому нам пришлось отказаться от UTF-8, и мы решили… полностью абстрагироваться от кодировки, в которой представлены строки, и перешли на «широкие строки» (wide strings).



Такое решение почти полностью удовлетворило наши требования:


  • Практически на всех UNIX-системах «широкие строки» представлены кодировкой UTF-32, то есть ширина символов в ней фиксирована и совпадает с размером элемента типа wchar_t

  • На Windows используется UTF-16. С этой кодировкой дело обстоит несколько сложнее, так как некоторые символы могут быть представлены суррогатными парами. Но, к счастью, все, что есть в Windows-1251, на котором работало наше Windows-приложение, представлено двухбайтовыми последовательностями. Поэтому на начальном этапе мы вовсе не стали поддерживать суррогатные пары и сделали допущение, что под Windows все символы влезают в один элемент типа wchar_t.

  • В С++ можно задавать «широкие» строковые константы, например, L«Привет, хабр!». В этом случае компилятор сам заботится о перекодировке этой строки из кодировки файла исходника в кодировку, в которой представлен wchar_t на целевой системе.



Кроме того, при использовании «широких строк» мы получили ряд преимуществ:


  • В стандартных библиотеках С и С++ есть множество функций и классов для работы с «широкими строками» — нет необходимости писать свои аналоги функций strlen, strstr, классов std::string, std::stringstream и т. п.

  • Многие сторонние библиотеки поддерживают «широкие строки» (например, BOOST)

  • Большая часть WinAPI умеет работать с «широкими строками»



На всех нужных нам платформах «широкие символы» представлены Unicode. За счет этого наши приложения теперь не ограничены латиницей и кириллицей, они поддерживают любые языки мира.



На самом деле борьба с кодировками была самой сложной частью работы по портированию наших продуктов. О ней можно еще очень много рассказать — оставим это для следующих статей :)



Особенности файловых систем ОС



Файловая система Windows имеет несколько отличий от большинства ФС UNIX-подобных систем:


  1. Она регистронезависимая

  2. Она позволяет использовать и символ «\» в качестве разделителя пути



К чему это приводит?

Вы можете назвать свой заголовочный файл «FiLe.H», а в коде писать «#include ». В Windows такой код скомпилируется, а в Linux вы получите ошибку, что файл с именем «myfolder\file.h» не найден.



Но, к счастью, избежать таких проблем очень просто — достаточно принять правила именования файлов (например, называть все файлы в нижнем регистре) и придерживаться их, а в качестве разделителей путей всегда использовать «/» (Windows его тоже поддерживает).



Чтобы полностью исключить досадные ошибки, мы повесили на свои git-репозитории простой hook, который проверяет соответствие include-директив этим правилам.



Также особенности ФС влияют и на само приложение. Например,



std::string root_path = get_some_path();
std::string path = root_path + '' + fname;


Если у вас есть код, который «клеит» пути через обычные операции конкатенации строк и использует «\» в качестве разделителей, то он сломается, так как под некоторыми ОС разделитель будет воспринят как часть имени файла.



Конечно, можно использовать '/', но в Windows это выглядит некрасиво, да и в общем случае нет гарантий, что не найдется ОС, в которой будет использоваться какой-то иной разделитель.



Чтобы решить эту проблему, мы используем библиотеку boost::filesystem. Она позволяет правильно сформировать путь под текущую систему:



boost::filesystem::path root_path = get_some_path();
boost::filesystem::path path = root_path / fname;


Заключение



Разработка кроссплатформенного ПО на С++ — это нетривиальная задача. Написать программу, которая будет работать на различных программных и аппаратных платформах, не прилагая для этого никаких дополнительных усилий, пожалуй, невозможно. Да и разработать на С++ крупную программу, которая без изменений правильно соберется на любом компиляторе под любую ОС и под любое железо, нельзя, несмотря на то, что С++ — кроссплатформенный язык. Но если вы будете придерживаться ряда правил, которые я вкратце изложил в статье, то вы сможете написать код, который запустится на всех нужных вам платформах. Да и перенести эту программу под новую ОС или железо будет уже не так трудно.



Итого, чтобы писать кроссплатформенный код нужно:


  • Хорошо знать Стандарт С++, понимать, что допускается в нем, а что является расширением конкретного компилятора или вовсе приводит к undefined behavior

  • Отказаться от использования API системы в коде, инкапсулировав платформоспецифичный код в некоторых классах или воспользоваться готовыми кроссплатформенными библиотеками

  • Учитывать возможные различия типизации, не завязываться на свойства базовых типов, которые не гарантируются Стандартом С++. Для этого можно использовать типы с фиксированной размерностью из стандартной библиотеки С++

  • Определиться с форматом представления строк в памяти программы. Тут может быть много вариантов. Например, использовать UTF-8, как это сделано во многих программах, или вовсе перейти на «широкие» строки, абстрагировавшись от формата представления строк вовсе

  • Учитывать особенности файловых систем на разных ОС (как в коде, в директивах #include, так и в логике самой программы).



Автор: Алексей Коновалов
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/326856/

Комментарии (0)КомментироватьВ цитатник или сообщество

Следующие 30  »

<windows - Самое интересное в блогах

Страницы: [1] 2 3 ..
.. 10

LiveInternet.Ru Ссылки: на главную|почта|знакомства|одноклассники|фото|открытки|тесты|чат
О проекте: помощь|контакты|разместить рекламу|версия для pda