#include <Windows.h>
#include <stdio.h>
#include <locale.h>

#define MAX_DRIVES 10

// 1. GetLogicalDriveStrings, GetDriveType.
// 2. GetCurrentDirectory, GetFileAttributes, GetSystemDirectory, GetTempPath.
// 3. SetCurentDirectory, SetFileAttributes, CreateFile, ReadFile, WriteFile.

// Порядок:
// 1. Получить список всех томов.
// 2. Для каждого тома получить его тип.
// 3. Перейти в директорию, получить информацию о директории, создать файл, записать в него информацию о томах.
// 4. Установить атрибуты файла, получить инфу об атрибутах. Прочитать файл, вывести всю инфу в консоль.
// 5. Получить системную директорию и директорию временных данных, вывести в консоль.

DWORD buf_len = MAX_DRIVES;
char drives_buf[MAX_DRIVES];

int main(void)
{
    DWORD drives_num = GetLogicalDriveStrings(buf_len, drives_buf);

    if (drives_num <= 0)
    {
        printf("\nGetLogicalDrives() не выполнена или выполнена с ошибкой!");

        return 1;
    }
    
    char* single_drive = drives_buf;

    while (*single_drive)
    {
        UINT dr_type = GetDriveType(single_drive);

        printf("%c - ", *single_drive);

        switch(dr_type)
        {
            case 0: 
                printf("DRIVE_UNKNOWN\n"); 
                break;
            case 1: 
                printf("DRIVE_NO_ROOT_DIR\n");
                break;
            case 2: 
                printf("DRIVE_REMOVABLE\n");
                break;
            case 3: 
                printf("DRIVE_FIXED\n"); 
                break;
            case 4: 
                printf("DRIVE_REMOTE\n"); 
                break;
            case 5: 
                printf("DRIVE_CDROM\n"); 
                break;
            case 6: 
                printf("DRIVE_RAMDISK\n"); 
                break;
            default: 
                printf("Unknown drive type.\n"); 
                break;
        }

        single_drive += strlen(single_drive) + 1;
    }    
    
    BOOL dir_set = SetCurrentDirectory("C:\\Users\\taria\\Desktop\\work_directory");

    if (dir_set == 0)
    {
        printf("\nSetCurrentDirectory() не выполнена или выполнена с ошибкой!");

        return 1;
    }

    char dir_buf[MAX_PATH];
    DWORD dir_get = GetCurrentDirectory(sizeof(dir_buf), dir_buf);

    if (dir_get <= 0)
    {
        printf("\nGetCurrentDirectory() не выполнена или выполнена с ошибкой!");

        return 1;
    }

    printf("Current directory: %s\n", dir_buf);

    HANDLE h_new_file = CreateFile(
        ".\\drives.txt",
        GENERIC_READ | GENERIC_WRITE,
        FILE_SHARE_READ | FILE_SHARE_WRITE,
        NULL,
        CREATE_ALWAYS,
        FILE_ATTRIBUTE_NORMAL,
        NULL);

    if (h_new_file == INVALID_HANDLE_VALUE)
    {
        printf("\nCreateFile() не выполнена или выполнена с ошибкой!");

        return 2;
    }

    DWORD bts_wrttn;
    WriteFile(
        h_new_file,
        drives_buf,
        sizeof(drives_buf),
        &bts_wrttn,
        NULL);

    if (bts_wrttn <= 0)
    {
        printf("\nWriteFile() не выполнена или выполнена с ошибкой!");

        return 2;
    }

    BOOL attr_set = SetFileAttributes("drives.txt", FILE_ATTRIBUTE_TEMPORARY);

    if (attr_set == 0)
    {
        printf("\nSetFileAttributes() не выполнена или выполнена с ошибкой!");

        return 1;
    }

    DWORD file_attr = GetFileAttributes("drives.txt");

    if (file_attr == INVALID_FILE_ATTRIBUTES)
    {
        printf("\nGetFileAttributes() не выполнена или выполнена с ошибкой!");

        return 1;
    }

    printf("File attribute code: %d\n", file_attr);
    printf("File attribute: ");

    switch(file_attr)
    {
        case 2048: 
            printf("Compressed\n"); 
            break;
        case 32: 
            printf("Archive\n");
            break;
        case 16: 
            printf("Directory\n");
            break;
        case 16384: 
            printf("Encrypted\n"); 
            break;
        case 2: 
            printf("Hidden\n"); 
            break;
        case 128: 
            printf("Normal\n"); 
            break;
        case 1: 
            printf("Readonly\n"); 
            break;
        case 4: 
            printf("System\n"); 
            break;
        case 256: 
            printf("Temporary\n"); 
            break;
        default: 
            printf("Unknown attribute.\n"); 
            break;
    }

    BOOL closed = CloseHandle(h_new_file);

    if (closed <= 0)
    {
        printf("CloseHandle() не выполнена или выполнена с ошибкой!");

        return 1;
    }

    printf("File closed.\n");

    HANDLE h_exst_file = CreateFile(
        ".\\drives.txt",
        GENERIC_READ,
        FILE_SHARE_READ,
        NULL,
        OPEN_ALWAYS,
        FILE_ATTRIBUTE_NORMAL,
        NULL);

    if (h_exst_file == INVALID_HANDLE_VALUE)
    {
        printf("\nCreateFile() не выполнена или выполнена с ошибкой!");

        return 2;
    }

    char file_buf[MAX_PATH];
    DWORD n_bytes_read;
    
    BOOL read_file = ReadFile(
        h_exst_file,
        file_buf,
        sizeof(file_buf),
        &n_bytes_read,
        NULL);

    if (read_file <= 0 || n_bytes_read == 0)
    {
        printf("\nReadFile() не выполнена или выполнена с ошибкой!");

        return 1;
    }

    char* single_drive_info = file_buf;

    while (*single_drive_info)
    {
        printf("File containment: %s\n", single_drive_info);

        single_drive_info += strlen(single_drive_info) + 1;
    }

    char sys_dir_buf[MAX_PATH];
    UINT sys_dir = GetSystemDirectory(sys_dir_buf, MAX_PATH);

    if (sys_dir == 0)
    {
        printf("\nGetSystemDirectory() не выполнена или выполнена с ошибкой!");

        return 1;
    }

    printf("System directory: %s\n", sys_dir_buf);
    
    char tmp_buf[MAX_PATH];
    DWORD tmp_path = GetTempPath(MAX_PATH, tmp_buf);

    if (tmp_path == 0)
    {
        printf("\nGetTempPath() не выполнена или выполнена с ошибкой!");

        return 1;
    }

    printf("Temp directory: %s\n", tmp_buf);

    BOOL exst_closed = CloseHandle(h_exst_file);

    if (exst_closed <= 0)
    {
        printf("CloseHandle() не выполнена или выполнена с ошибкой!");

        return 1;
    }

    printf("File closed.\n");

    return 0;
}