Home
BarashenkovIlya edited this page 1 year ago

КАК ПОНЯТЬ КТО ЕСТЬ КТО БЛЯТЬ ???(до кого доебываться в случае чего) АХУЕТЬ ПРЕДЛОЖЕНИЕ 2 Задание Создание и отладка файла DLL. Для демонстрации работы написать две элементарные функции в библиотеке и вызвать их из основной программы

МОЖНО ВЗЯТЬ ИЗ 21 задания

Только чуть дописать нового Программа для считывания и записи строкового значения с использованием текстового файла. Для работы с файлами используются функции WinAPI

HANDLE file = CreateFile(L"1.txt", GENERIC_READ, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);//открываем для чтения DWORD size = 100,//кол-во символов которые надо прочитать

        bytes;//типо счетчик реально прочитанных символов

if (file != INVALID_HANDLE_VALUE) //если файл есть
{
           char* text = calloc(size+1,1);//буфер куда записывается прочитанное 
    ReadFile(file, text, size, &bytes, NULL);//читаем ебать
    CloseHandle(file);//закрываем нахуй ибо нахуй он нам нужен теперь

}

file = CreateFile(L"answer.txt", GENERIC_WRITE, 0, NULL,

                CREATE_ALWAYS, //если нет файла создаст, если есть перезапишет(удалит и создаст заново)
                FILE_ATTRIBUTE_NORMAL, NULL);//открываем для записи
                WriteFile(file, "Введены некорректные данные", size, &bytes, NULL);//записываем (size и bytes как и при чтении) (хуйня стирай)

Версия вроде робит вот
HANDLE file = CreateFile(L"1.txt", GENERIC_READ, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);//открываем для чтения
DWORD size = 100, bytes;
char* text = calloc(size + 1, 1);//буфер куда записывается прочитанное 
if (file != INVALID_HANDLE_VALUE) //если файл есть
{
    ReadFile(file, text, size, &bytes, NULL);//читаем ебать
    CloseHandle(file);//закрываем нахуй ибо нахуй он нам нужен теперь
}

file = CreateFile(L"answer.txt", GENERIC_WRITE, 0, NULL,
    CREATE_ALWAYS, //если нет файла создаст, если есть перезапишет(удалит и создаст заново)
    FILE_ATTRIBUTE_NORMAL, NULL);//открываем для записи
WriteFile(file, text, size, &bytes, NULL);//записываем (size и bytes как и при чтении)

Получение названия клавиши с использованием функции GetKeyNameText (Windows HOOK). Название клавиши выводить в MessageBox

RESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) {

// Если событие - нажатие клавиши
if (nCode == HC_ACTION && (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN))
{
    KBDLLHOOKSTRUCT* p = (KBDLLHOOKSTRUCT*)lParam;
    // Получаем название нажатой клавиши
    TCHAR szKeyName[256];

DWORD iKey = MapVirtualKey( p->vkCode,NULL) << 16;

    if (!((p->vkCode <= 32))) {
        iKey |= 0x1<<24;
    }

    GetKeyNameText(iKey , szKeyName, 256);
  // Выводим название клавиши в MessageBox

MessageBox(NULL, szKeyName, "Key Pressed", MB_OK); } return CallNextHookEx(hHook, nCode, wParam, lParam); }

int main() { // Устанавливаем хук на обработку событий клавиатуры hHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardProc, NULL, 0); // Обрабатываем сообщения окна MSG msg; while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } // Удаляем хук UnhookWindowsHookEx(hHook); return 0; }

Получение кода клавиши в формате ASCII и использованием Windows HOOK. Название клавиши выводить в MessageBox

int iKey = MapVirtualKeyA( p->vkCode, NULL); WCHAR procID[256]; swprintf_s(procID, 256, L"%d", iKey); MessageBox(NULL, procID, L"Key Pressed", MB_OK);

Программа для преобразования числа в строку и склейки двух строк. Разработать без использования системных функций char* int_to_string(int n) {

int nDigits = 1;  // счетчик разрядов
// Определяем, сколько разрядов имеет число
int new_n = n;
while (new_n / 10 != 0)
{
    nDigits++;
    new_n /= 10;
}

char* s = "";
int i = 0;
if (n < 0) {
    n = -n;
    nDigits++;
} 
s = malloc(nDigits);
for (i;i < nDigits; i++)
{
    s[i] = n % 10 + '0';
    if (n == 0) {
        s[i] = '-';
    }
    else {
        n /= 10;
    }


}
s[nDigits] = '\0';

int j;
char c;

for (i = 0, j = nDigits - 1; i < j; i++, j--) {
    c = s[i];
    s[i] = s[j];
    s[j] = c;
}
return s;

}

char* Concat(char* str1, char* str2) {

int count = 0;
while (str1[count] != '\0')
    count++;
int count2 = 0;
while (str2[count2] != '\0')
    count2++;
count += count2;
char* result = malloc(count + 1);
result[count] = '\0';
count2 = 0;
while (str1[count2] != '\0')
{
    result[count2] = str1[count2];
    count2++;
}
count = 0;
while (str2[count] != '\0')
{
    result[count2] = str2[count];
    count++;
    count2++;
}
return result;

}

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

int GetLevels(int a, int n) {

for (size_t i = 1; i < n; i++)
{
    a *= 10;
}
return a;

}

int string_to_int(LPWSTR str) {

int result = 0;
int is_negative = 0;
int i = 0;
int count = 0;

if (str[i] == L'-') {
    is_negative = 1;
    i++;
}
int index = i;
while (str[index] != '\0')
{
    count++;
    index++;
}

while (str[i] != L'\0') {
    if (str[i] >= L'0' || str[i] <= L'9') {
        result += (int)(str[i] - '0') * (GetLevels(10,count)/10);
        count--;
    }
    i++;
}

if (is_negative) {
    result = -result;
}

return result;

}

Программа для записи строки в системный буфер обмена void CBInput(LPWSTR text) {

HANDLE hMem = GlobalAlloc(GMEM_MOVEABLE, (wcslen(text) + 1) * sizeof(LPWSTR));
memcpy(GlobalLock(hMem), text, (wcslen(text) + 1) * sizeof(LPWSTR));
GlobalUnlock(hMem);
OpenClipboard(NULL);
EmptyClipboard();
SetClipboardData(CF_UNICODETEXT, hMem);
CloseClipboard();

}

Программа для считывания данных из системного буфера обмена LPWSTR CBOuput() {

LPWSTR text = NULL;
OpenClipboard(NULL);
HANDLE CBtext = GetClipboardData(CF_UNICODETEXT);
text = (LPWSTR)GlobalLock(CBtext);
GlobalUnlock(CBtext);
//EmptyClipboard();
CloseClipboard();
return text;

}

Создание программы с критической секцией. Программа должна содержать минимум два потока. Использование критической секции в функции потока должно быть обосновано.

CRITICAL_SECTION cs; int count = 0;

DWORD WINAPI thread_func(int thread_num){

for (int i = 0; i < 10; i++) {
    EnterCriticalSection(&cs);
    printf("Thread %d: %d\n", thread_num, count);
    count++;
    LeaveCriticalSection(&cs);
    Sleep(100);
}

return 0;

}

int main() {

InitializeCriticalSection(&cs);

HANDLE thread1 = CreateThread(NULL, 0, thread_func, 1, 0, NULL);
HANDLE thread2 = CreateThread(NULL, 0, thread_func, 2, 0, NULL);

WaitForSingleObject(thread1, INFINITE);
WaitForSingleObject(thread2, INFINITE);

DeleteCriticalSection(&cs);

return 0;

}

Программа для считывания нескольких числовых значений из строки и из записи в числовой массив (разделитель - пробел). Количество значений в строке заранее неизвестно. Запись и считывание строковых параметров в системный реестр. HKEY hkey;

HKEY hMyKey;
RegOpenKeyW(HKEY_CURRENT_USER, NULL, &hkey);
if (RegCreateKeyW(hkey, L"MyKey", &hMyKey) == ERROR_SUCCESS)
{
    if (RegSetValueEx(hMyKey, L"test", 0,REG_SZ, L"Message", 8 * sizeof(WCHAR)) == ERROR_SUCCESS)
    {
        WCHAR text[256];
        DWORD size = sizeof(WCHAR) * 256;
        if (RegGetValueW(hMyKey,NULL, L"test", RRF_RT_REG_SZ, NULL, text, &size) == ERROR_SUCCESS)
        {
            MessageBoxW(NULL, text, L"YES", MB_OK);
        }

    }
}

Версия чуть короче

HKEY hMyKey;
if (RegCreateKeyW(HKEY_CURRENT_USER, L"NewMyKey", &hMyKey) == ERROR_SUCCESS)
{
    if (RegSetValueEx(hMyKey, L"nameparam", 0, REG_SZ, L"Message", 8 * sizeof(WCHAR)) == ERROR_SUCCESS)
    {
        WCHAR text[256];
        DWORD size = sizeof(WCHAR) * 256;
        if (RegGetValueW(hMyKey, NULL, L"nameparam", RRF_RT_REG_SZ, NULL, text, &size) == ERROR_SUCCESS)
        {
            MessageBoxW(NULL, text, L"YES", MB_OK);
        }
    }
}

Обработка нажатия клавиши мыши в системе (выписать в messagebox какая клавиша нажата и сколько раз) HHOOK hHook = NULL; int count; WPARAM ButtonCode; LPWSTR str[256]; LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam) {

if (nCode == HC_ACTION)
{
    switch (wParam)
    {
    case WM_LBUTTONDOWN:
        if (ButtonCode != wParam)
            count = 0;
        ButtonCode = wParam;
        count++;
        swprintf_s(str, 256, L"Левая клавиша мыши нажата %d раз", count);
        MessageBox(NULL, str, "", MB_OK);//Дальше по аналогии
        break;
    }
}

return CallNextHookEx(hHook, nCode, wParam, lParam);

}

int main() {

hHook = SetWindowsHookEx(WH_MOUSE_LL, MouseProc, NULL, 0);
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
    TranslateMessage(&msg);
    DispatchMessage(&msg);
}
UnhookWindowsHookEx(hHook);

return 0;

}

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

DWORD st = 100;
DWORD size = sizeof(st);
HKEY hMyKey;
if (RegCreateKeyW(HKEY_CURRENT_USER, L"NewMyKey", &hMyKey) == ERROR_SUCCESS)
{
    if (RegSetValueEx(hMyKey, L"nameparamdword", 0, REG_DWORD, (const BYTE*)&st, sizeof(st)) == ERROR_SUCCESS)
    {
        if (RegGetValueW(hMyKey, NULL, L"nameparamdword", RRF_RT_DWORD, NULL, (LPBYTE)&st, &size) == ERROR_SUCCESS)
        {

WCHAR buf[256]; swprintf_s(buf, 256, L"%d", st);

            MessageBox(NULL, buf, L"Оповещение", MB_OK);
        }
    }
}

Разработка программы-секундомера. в одном потоке идет отсчет времени, а в другом осуществляется управление секундомером #define _CRT_SECURE_NO_WARNINGS #include #include #include BOOL work = TRUE; void* secondsmer() {

int start, end;
int ms = 0;
int ns = 0;
int sec = 0, min = 0, hrs = 0;
start = clock();
while (work)
{
    end = clock();
    ns = end - start;
    ms = ns / 10;
    if (ms > 100)
    {
        sec = sec + 1;
        ms = ms - 100;
        start = end;
    }
    if (sec > 59)
    {
        min = min + 1;
        sec = 0;
    }
    if (min > 59)
    {
        hrs = hrs + 1;
        min = 0;
    }
    printf("%d:%d:%d.%d\n", hrs, min, sec, ms);
}

}

int main() {

system("chcp 1251 >null");
DWORD choose = -1;
 HANDLE hTread = NULL;
printf("\n1 - секундомер\n0 - Остановить\n");
while (1)
{
    scanf_s("%d", &choose);
    if (choose == 1) {
        if (hTread == NULL) {
            hTread = CreateThread(NULL, 0, secondsmer, 0, NULL, NULL);
            work = TRUE;
        }


    }
    else
    {
        if (hTread != 0) {
            work = FALSE;
            CloseHandle(hTread);
            hTread = NULL;
        }

    }

}  

}

Разработка программы для вычисления факториала в отдельном потоке. В программе должна быть предусмотрена валидация данных int FacKU(int n) {

if (n == 0)
    return 1;
if (n < 1)
    return 0;
int a = 1;
for (size_t i = 1; i <= n; i++)
{
    a *= i;
}
return a;

}

main() {

HANDLE hThread;
while (1) {
    char str[256];
    scanf("%s", str);
    int n = atoi(str);
    if (n != NULL) {
        printf("%d\n", FacKU(n));
    }
}

}

Создание и настройка проекта WinAPI. Вывод сообщения в messagebox. Текст сообщения считывается из текстового файла в кодировке Юникод Программа с запуском стороннего процесса. Имя запускаемого процесса выбирается с помощью системного диалогового окна. Использование условных блоков для анализа значений, возвращаемых системной функцией Программа с импортом функции из файла DLL. Функция принимает структуру, содержащую координаты двух точек, а возвращает длину отрезка, который образуется этими точками

Код для ДЛЛ файла typedef struct coordinats {

COORD point1;
COORD point2;

}cord; __declspec(dllimport) double getSize(cord* cord);

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {

switch (fdwReason)
{
case DLL_PROCESS_ATTACH:

    break;

case DLL_THREAD_ATTACH:

    break;

case DLL_THREAD_DETACH:

    break;

case DLL_PROCESS_DETACH:
    break;
}
return TRUE;

}

double getSize(cord* cord) {

double d = sqrt((pow(cord->point2.X - cord->point1.X, 2) + pow(cord->point2.Y - cord->point1.Y, 2)), 2);
return d;

}

Код для основной программы #define PATH L"DLLCode.dll" typedef double(_cdecl* getSize)(struct cord*);

typedef struct coordinats {

COORD point1;
COORD point2;

}cord;

int main() {

HINSTANCE hMyDLL;
if ((hMyDLL = LoadLibrary(PATH)) == NULL) return 1;
getSize getSqize = (getSize)GetProcAddress(hMyDLL, "getSize");
cord* cord = malloc(sizeof(cord));
cord->point1.X = 2;
cord->point1.Y = 1;
cord->point2.X = 6;
cord->point2.Y = 4;
double result = getSqize(cord);
FreeLibrary(hMyDLL);
return 0;

}

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

КОД КЛИЕНТА #define _CRT_SECURE_NO_WARNINGS #include #include int main() {

system("chcp 1251");
BOOL flag_awser = TRUE;
char message[100];
DWORD read_buffer = 100;
DWORD actual_read;
DWORD actual_write;
LPWSTR buffer = (CHAR*) calloc(read_buffer, sizeof(char));
HANDLE hNamePipe;
LPSTR pipeName = L"\\\\.\\pipe\\MyPipe";
BOOL SuccessRead;
BOOL isSuccess;
DWORD dwMode = PIPE_READMODE_MESSAGE;
while (1)
{
    hNamePipe = CreateFile(pipeName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
    isSuccess = SetNamedPipeHandleState(hNamePipe, &dwMode, NULL, NULL);
    if (!isSuccess) {
        printf("\nСервер не отвечает\n");
        flag_awser = TRUE;
    }
    else
    {
        if (flag_awser) {
            printf("Введите сообщение для сервера: \n");
            gets(message);
            buffer = &message;
            WriteFile(hNamePipe, buffer, read_buffer, &actual_write, NULL);
            flag_awser = FALSE;
        }
        SuccessRead = ReadFile(hNamePipe, buffer, 100, &actual_read, NULL);
        if (SuccessRead) {
            printf("\nСервер пишет: ");
            printf(buffer);
            printf("\n");
            flag_awser = TRUE;
            if (buffer == NULL)
                printf("Пусто");
        }
    }
    Sleep(100);
    CloseHandle(hNamePipe);
}

}

КОД СЕРВЕРА #include #include int main() {

system("chcp 1251");
HANDLE hNamePipe;
LPSTR pipeName = L"\\\\.\\pipe\\MyPipe";
DWORD read_buffer = 100;
LPWSTR buffer = calloc(read_buffer, sizeof(char));
char message[100];
DWORD actual_read;
BOOL Connected;
BOOL SuccessRead;
while (1)
{
    hNamePipe = CreateNamedPipe(
        pipeName, 
        PIPE_ACCESS_DUPLEX, 
        PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, 
        PIPE_UNLIMITED_INSTANCES, 
        512, 
        512, 
        INFINITE, 
        NULL);
    Connected = ConnectNamedPipe(hNamePipe, NULL);
    if (Connected) {
        printf("\nКлиент подключился\n");
        SuccessRead = ReadFile(hNamePipe, buffer, read_buffer, &actual_read, NULL);
        if (SuccessRead) {
            printf("\nКлиент пишет: ");
            printf(buffer);
            printf("\n");
            printf("\nВведите сообщение для клиента: ");
            gets(message);
            buffer = &message;
            WriteFile(hNamePipe, buffer, read_buffer, &actual_read, NULL);
        }
    }
    else
    {
        printf("\nКлиент отключился от сервера");
    }
        CloseHandle(hNamePipe);
}

}

Создание линейного односвязного списка из n элементов. Значение элемента генерируется случайным образом. Поместить в отдельные указатели адрес минимального и максимального элемента списка. Вывести список и значения минимального и максимального элемента через указатель typedef struct LOS {

int arg;
int min;
int max;
struct LOS* next;

}LOS;

void GetMinMax(LOS* los) {

LOS* head = los;
int max;
int min = los->arg;
while (los) {
    if (los->next != NULL) {
        int n = los->next->arg;
        if (los->arg > n)
            max = los->arg;
    }

    if (min > los->arg)
        min = los->arg;
    los = los->next;
}
los = head;
los->min = min;
los->max = max;

}

void WriteLOS(LOS* los) {

LOS* head = los;
while (los)
{
    printf("значение - %d\n", los->arg);
    los = los->next;
}
los = head;
printf("min - %d; max - %d", los->min,los->max);

}

LOS* createLOS(int count) {

LOS* los = calloc(1, sizeof(LOS));
los->arg = rand();
los->next = NULL;
LOS* headCopy, * next;
headCopy = los;
for (size_t i = 0; i < count - 1; i++)
{
    next = calloc(1, sizeof(LOS));
    next->arg = rand();
    headCopy->next = next;
    headCopy = next;
}
headCopy->next = NULL;
return los;

}

main() {

LOS* los = createLOS(5);
GetMinMax(los);
WriteLOS(los);

} Программа для считывания числового значения из файла (с сохранением его в числовом формате). Исходный файл является бинарным FILE* file = NULL;

int number;

file = fopen("bin.bin", "wb");
if (file == NULL) {
    printf("Error opening file");
}

scanf("%d", &number);
fwrite(&number, sizeof(int), 1, file);

fclose(file);

file = fopen("bin.bin", "rb");
if (file == NULL) {
    printf("Error opening file");
}

fread(&number, sizeof(int), 1, file);
printf("%d", number);

fclose(file);

Создание консольной утилиты, которая печатает список переданных ей аргументов из командной строки. При демонстрации работы программы рассмотреть не менее трех способов передачи аргументов в запускаемый процесс Создание функции, аргументом которой является указатель на функцию. Создать не менее двух вспомогательных функций и передать их в качестве аргумента исходной функции. Продемонстрировать специфику работы исходной функции в зависимости от переданных параметров Использование анонимного канала для передачи строковых значений между процессами Основной процесс: HANDLE hReadPipe, hWritePipe;

char message[] = "Hello, child process!";
char buffer[256];
SECURITY_ATTRIBUTES sa = { sizeof(sa),NULL,TRUE };
DWORD bytesWritten, bytesRead;
BOOL success;

// Создаем анонимный канал
success = CreatePipe(&hReadPipe, &hWritePipe, &sa, 256);
if (!success)
{
    printf("Error creating pipe\n");
    return 1;
}

// Создаем дочерний процесс
STARTUPINFO si;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
si.hStdError = hWritePipe;
si.hStdOutput = hWritePipe;
si.dwFlags |= STARTF_USESTDHANDLES;

PROCESS_INFORMATION pi;
ZeroMemory(&pi, sizeof(pi));

success = CreateProcessA(NULL, "..\\x64\\Debug\\child.exe", NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);
if (!success)
{
    printf("Error creating child process\n");
    return 1;
}

while (TRUE) {
    // Читаем из канала
    success = ReadFile(hReadPipe, buffer, sizeof(buffer), &bytesRead, NULL);
    if (!success)
    {
        printf("Error reading from pipe\n");
        return 1;
    }
    buffer[bytesRead] = '\0';
    printf("Received message: %s\n", buffer);
}

Дочерний процесс:

HANDLE hReadPipe = GetStdHandle(STD_OUTPUT_HANDLE);


while (TRUE)
{
    char message[256];
    DWORD bytesWritten;
    scanf("%s",message);
    WriteFile(hReadPipe, message, strlen(message), &bytesWritten, NULL);
}
return 0;