/*
 * Copyright(C) 2000 Проект ИОК
 *
 * Этот файл содержит информацию, являющуюся
 * собственностью компании Крипто Про.
 *
 * Любая часть этого файла не может быть скопирована,
 * исправлена, переведена на другие языки,
 * локализована или модифицирована любым способом,
 * откомпилирована, передана по сети с или на
 * любую компьютерную систему без предварительного
 * заключения соглашения с компанией Крипто Про.
 */

/****
 * $Id: f12iflag.c 196556 2019-07-25 05:06:06Z borodin $
 *
 * Работа со считывателями и ключевой информацией (READER).
 *
 * Библиотека чтения / записи ключевой информации на дискеты (FAT12).
 *
 * Функции поддержки информации с ключевой дискеты.
 * Функция получения системных флагов.
 *
 * Функция: fat12_info_system_flag
 ****/

#include "fat12prj.h" /*+ Project (READER/FAT12) include.
    Мастер include файл для проекта (READER/FAT12). +*/

/*!
 * \ingroup fat12_internal
 * \brief Флаги считывателя.
 */
static const unsigned char FAT12_FLAGS_GENERAL[] = 
{ 
    0 << 7 
};

static const unsigned char FAT12_FLAGS_CONNECT[] = 
{
      0 << 7 /* SUPSYS_FLAG_CONNECT_MANY */
    | 0 << 6 /* SUPSYS_FLAG_CONNECT_COM */
    | 0 << 5 /* SUPSYS_FLAG_CONNECT_LPT */
    | 0 << 4 /* SUPSYS_FLAG_CONNECT_AUTO */
    | 0 << 3 /* SUPSYS_FLAG_CONNECT_MULTY */
    | 0 << 2 /* SUPSYS_FLAG_CONNECT_PNPGROUP */
};

static const unsigned char FAT12_FLAGS_RDR[] = 
{
    TO_CP_FLAG(RDR_FLAG_RDR_REMOVABLE, 1) |
    TO_CP_FLAG(RDR_FLAG_RDR_UNIQUE, 1) |
    TO_CP_FLAG(RDR_FLAG_RDR_PROTECTED, 0) |
    TO_CP_FLAG(RDR_FLAG_RDR_VIRTUAL, 0)
};

static const unsigned char FAT12_FLAGS_GRP_CONNECT[] = 
{
      0 << 7 /* SUPSYS_FLAG_CONNECT_MANY */
    | 0 << 6 /* SUPSYS_FLAG_CONNECT_COM */
    | 0 << 5 /* SUPSYS_FLAG_CONNECT_LPT */
    | 0 << 4 /* SUPSYS_FLAG_CONNECT_AUTO */
    | 0 << 3 /* SUPSYS_FLAG_CONNECT_MULTY */
    | 1 << 2 /* SUPSYS_FLAG_CONNECT_PNPGROUP */
};

/*++++
 * Функция получения системных флагов.
 ++++*/
DWORD fat12_info_system_flag(
    TSupSysContext *context, 
    TSupSysInfo *info ) /*+ (io) Запрашиваемая информация. +*/
/*+
 * Возвращает:
 *
 * ERROR_SUCCESS, при успешном получении имени дисковода.
 *
 * (DWORD)ERROR_INVALID_PARAMETER, при неправильно переданных параметрах.
 +*/
{
    TSupSysInfoFlags *flags = (TSupSysInfoFlags*)info;
    size_t length;
    const unsigned char *ptr = NULL;

    UNUSED( context );
    SUPSYS_PRE_INFO( info, TSupSysInfoFlags );
    SUPSYS_PRE( flags->type == RDR_FLAG_BLOCK_RDR
      || flags->type == SUPSYSE_FLAG_BLOCK_GENERAL
      || flags->type == SUPSYS_FLAG_BLOCK_CONNECT );
    length = flags->string.bits;
    if( flags->type == SUPSYSE_FLAG_BLOCK_GENERAL )
    {
	length = SUPSYSE_FLAG_GENERAL_VERSION_1;
	ptr = FAT12_FLAGS_GENERAL;
    }
    if( flags->type == SUPSYS_FLAG_BLOCK_CONNECT )
    {
	length = SUPSYS_FLAG_CONNECT_VERSION_3;
	ptr = FAT12_FLAGS_CONNECT;
    }
    if( flags->type == RDR_FLAG_BLOCK_RDR )
    {
	length = RDR_FLAG_RDR_VERSION_6;
	ptr = FAT12_FLAGS_RDR;
    }
    if( flags->string.string == NULL )
    {
	flags->string.bits = length;
	return ERROR_SUCCESS;
    }
    if( flags->string.bits > length )
	flags->string.bits = length;
    memcpy( flags->string.string, ptr, 
	flags->string.bits / 8 + ( (flags->string.bits % 8) ? 1 : 0 ) );
    flags->string.bits = length;
    return ERROR_SUCCESS;
}

static DWORD get_flags_by_type(size_t type, const BYTE** bits, size_t* bits_len) {
    switch (type) {
    case SUPSYSE_FLAG_BLOCK_GENERAL:
	*bits_len = SUPSYSE_FLAG_GENERAL_VERSION_1;
	*bits = FAT12_FLAGS_GENERAL;
	break;
    case SUPSYS_FLAG_BLOCK_CONNECT:
	*bits_len = SUPSYS_FLAG_CONNECT_VERSION_3;
	*bits = FAT12_FLAGS_GRP_CONNECT;
	break;
    case RDR_FLAG_BLOCK_RDR:
	*bits_len = RDR_FLAG_RDR_VERSION_6;
	*bits = FAT12_FLAGS_RDR;
	break;
    default:
	return (DWORD)ERROR_INVALID_PARAMETER;
    }

    return ERROR_SUCCESS;
}

DWORD fat12_group_info_system_flag(
				     TSupSysContext *context, 
				     TSupSysInfo *info )
{
    TSupSysInfoFlags *flags = (TSupSysInfoFlags*)info;
    size_t length;
    const unsigned char *ptr = NULL;

    UNUSED( context );
    SUPSYS_PRE_INFO( info, TSupSysInfoFlags );
    DWORD err = get_flags_by_type(flags->type, &ptr, &length);
    if (err)
	return err;
    if( flags->string.string == NULL )
    {
	flags->string.bits = length;
	return ERROR_SUCCESS;
    }
    if( flags->string.bits > length )
	flags->string.bits = length;
    memcpy( flags->string.string, ptr, 
	flags->string.bits / 8 + ( (flags->string.bits % 8) ? 1 : 0 ) );
    flags->string.bits = length;
    return ERROR_SUCCESS;
}

/*+ end of file: $Id: f12iflag.c 196556 2019-07-25 05:06:06Z borodin $ +*/
