Задания лабораторных работ по дисциплине Системное программирование

Цель - знакомство с принципами работы Windows API.

Среда разработки курсовой работы - любой компилятор C/C++ для ОС Windows версии 2000 года или позже. Рекомендуется: bcc32 (компилятор Borland для командной строки).

    Список лабораторных работ.
  1. Написать программу, которая перекодирует входной текстовый файл, содержащий английские, русские и украинские буквы в кодировке Windows-1251, и прочие символы, в html-файл, содержащий текстовое представление UNICODE-кодировки символов. Например символ апострофа ' должен быть выведен в новый файл как ' потому что его UNICODE значение 39, а русская буква а будет представлена как а. При просмотре полученной html-страницы результат не должен зависеть от настроек кодировки клиента. Символы из набора ASCII (коды 0 - 127), кроме апострофа и кавычек не перекодировать. Использовать функцию MultiByteToWideChar.
  2. Написать две программы: главную и дочернюю. Главная программа должна запускать дочернюю и ожидать ее завершения. Использовать функции CreateProcess и WaitForSingleObject.
  3. Написать программу, главный поток которой запускает несколько дополнительных потоков. Реализовать обмен сообщениями между главным и побочными потоками с помощью передачи сообщений. Использовать функции CreateThread, PostThreadMessage, GetMessage. Как минимум, вторичные потоки должны с помощью сообщений уведомлять главный поток о своей готовности к работе и о завершении своего выполнения.
  4. Написать программу, главный поток которой запускает несколько дополнительных потоков. Реализовать критическую секцию кода, которую все потоки проходят строго последовательно и поочередно. Использовать функции CreateThread, InitializeCriticalSection, DeleteCriticalSection, EnterCriticalSection, LeaveCriticalSection. Как минимум, в критическую секцию кода нужно поместить печать сообщения - какой поток зашел в критическую секцию и подсчет числа посещений этой секции кода.
  5. Написать две программы: исполняемая программа (exe) и динамическую библиотеку (dll). В динамической библиотеке реализовать хотя бы одну экспортируемую функцию. Можно использовать или директивы компилятора __declspec, или файлы компоновщика для определения модуля *.def. В исполняемой программе нужно статически (или динамически) импортировать функцию-пример из dll и вызвать ее. Дополнительное требование: экспорт/импорт функций не должен зависеть от применяемого компилятором декорирования имен (name mangling), чтобы функции вашей DLL могли использовать программы, написанные на других языках (или созданные другими компиляторами).
  6. Написать программу, главный поток которой запускает несколько дополнительных потоков. Реализовать собственный слот TLS для работы с приватной памятью потока. Использовать функции TlsAlloc, TlsFree, TlsGetValue, TlsSetValue. Как минимум, главный поток должен порождать/уничтожать слот TLS, а все потоки (и главный в том числе) - помещать и извлекать данные из слота TLS. Программа должна убедительно демонстрировать, что данные, помещаемые в слот TLS, а затем извлекаемые из него, уникальны для конкретного потока и не пересекаются с данными других потоков (используйте, например, идентификаторы потоков).
  7. Написать программу, которая: резервирует диапазон виртуальных адресов размером 200 MB, выделяет из этого диапазона блок адресов размером 8 MB, которому выделяется физическая память, производит запись данных в этот блок и затем запрещает запись. Программа должна убедительно демонстрировать, что в адресном пространстве процесса появился диапазон адресов размером 200 MB, а в нем блок размером 8 MB, закрытый для записи. Для этого использовать функцию VirtualQuery. Затем программа освобождает физическую память и освобождает резервирование адресного диапазона. Использовать функции VirtualAlloc, VirtualProtect, VirtualFree.
  8. Написать две программы. Первая программа создает проекцию файла в памяти и выделяет для нее блок адресов размером 8 MB. Вторая программа подключается к уже существующей проекции, записывает в нее данные, и отключается от проекции. Первая программа читает данные из проекции, выводит их на печать, закрывает проекцию. Использовать функции CreateFileMapping, OpenFileMapping, MapViewOfFile, UnmapViewOfFile, CloseHandle. Должно быть убедительно продемонстрировано, что второй программе удалось записать данные в блок разделяемой памяти, и что первая программа получила эти данные.

Архив с примерами использования (необходимо приспособить (переделать) для своих целей).