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

/*!
 * \file $RCSfile$
 * \version $Revision: 195469 $
 * \date $Date:: 2019-07-02 11:39:24 +0300#$
 * \author $Author: frolov $
 *
 * \brief Функция поиска заданного ДСЧ по маске.
 */

#include "rndm_prj.h" 

/*! Структура контекста перечисления ДСЧ. */
typedef struct TRandomFind_
{
    TRndmType mask; /*!< Маска поиска типа ДСЧ. */
    TRndmType value; /*!< Результат наложения маски ДСЧ. */
} TRandomFind;

/*!
 * \brief Функция проверки принадлежности элемента к поисковому множеству
 * \param add_info [in] контекст поиска
 * \param item [in] проверяемый элемент
 * \return результат проверки
 * \retval 0 элемент принадлежит искомому множеству
 * \retval -1 продолжить поиск
 * \retval 1 элемент не найден
 */
static int rndm_find_mask_valid( const TSupSysFindInfo *add_info, 
    const TSupSysEContext *item )
{
    const TRandomFind *rf = (const TRandomFind *)add_info;
    TRndmType type;
    DWORD code;
    SUPSYS_PRE(add_info);
    SUPSYS_PRE(item);

    code = rndm_type_get( item, &type );
    if( code )
	return -1;
    if( ( rf->mask & type ) == rf->value )
	return 0;
    return 1;
}

DWORD rndm_find_mask(
    TSupSysEList *list,
    TSupSysEContext **context,
    TRndmType mask,
    TRndmType value ) 
{
    TSupSysEFind *f;
    DWORD code;
    TRandomFind rf;
    SUPSYS_PRE(list);
    SUPSYS_PRE(context);
    rf.mask = mask;
    rf.value = value;
    code = supsys_find_open_ext(list, &f, (TSupSysFindInfo*)&rf, rndm_find_mask_valid);
    if(code)
	return code;

    code = supsys_find_next( f, context );
    supsys_find_close( f );
    if( code == (DWORD)SCARD_E_READER_UNAVAILABLE )
	return (DWORD)NTE_PROVIDER_DLL_FAIL;
    return code;
}
