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

/*!
* \file $RCSfile$
* \version $Revision: 102162 $
* \date $Date: 2014-02-13 14:13:32 +0400 (Р§С‚, 13 С„РµРІ 2014) $
* \author $Author: borodin $
* \brief Открытие файла
*
*  описание файла
*/


#include "rdr_prj.h"

static const TCHAR* get_file_name_by_number(const TRdrFileNumber num)
{
    switch (num) {
	case CF_HEADER:
	    return HEADER_KEY_NAME;
	case CF_MASKS:
	    return MASKS_KEY_NAME;
	case CF_PRIMARY:
	    return PRIMARY_KEY_NAME;
	case CF_MASKS2:
	    return MASKS2_KEY_NAME;
	case CF_PRIMARY2:
	    return PRIMARY2_KEY_NAME;
	case CF_NAME:
	    return NAME_KEY_NAME;
	case CF_DEF:
	    return DEF_KEY_NAME;
	case CF_CERT_KX:
	    return CERTIFICATE_KX_KEY_NAME;
	case CF_CERT_SIG:
	    return CERTIFICATE_SIG_KEY_NAME;
	case CF_EXT:
	    return EXTENSIONS_KEY_NAME;
	default:
	    return NULL;
    }
}
      
//
DWORD rdr_file_open(
    TSupSysEContext *context,
    const char *mode,
    TRdrFileNumber filno)
{
    TReaderInfoOpen info_open;
    TReaderInfoOpenFlags mode_flags = { 0 };
    const TCHAR* file_name = get_file_name_by_number(filno);
    for (; *mode; mode++) {
	switch (*mode) {
	    case 'r':
		mode_flags.o_read = 1;
		continue;
	    case 'w':
		mode_flags.o_write = 1;
		mode_flags.o_create = 1;
		//mode_flags->o_trunc = 1;
		continue;
	    case '+':
		mode_flags.o_read = 1;
		mode_flags.o_write = 1;
		continue;
	    case 'p':
		mode_flags.o_private = 1;
		continue;
	    default:
		LOGRETURN((DWORD)ERROR_INVALID_PARAMETER);
	}
    }

    info_open.num = filno;
    info_open.name.length = 0;
    info_open.name.text = NULL;
    if (file_name != NULL)
    {
	info_open.name.length = _tcslen(file_name);
	info_open.name.text = (TCHAR*)file_name;
    }
    info_open.mode_bits = READER_MODEFLAG_BITS;
    info_open.mode = mode_flags;
    LOGRETURN(supsys_call(context, READER_FUN_OPEN, &info_open));
}

DWORD rdr_file_close(
    TSupSysEContext *context)
{
    LOGRETURN(supsys_call(context, READER_FUN_CLOSE, NULL));;
}

DWORD rdr_file_length(
    TSupSysEContext *context,
    size_t *size)
{
    DWORD code;
    TReaderInfoLength info_length;
    code = supsys_call(context, READER_FUN_LENGTH, &info_length);
    if (code)
	LOGRETURN(code);
    *size = info_length;
    LOGRETURN(ERROR_SUCCESS);
}

DWORD rdr_file_chsize(
    TSupSysEContext *context,
    size_t *size)
{
    DWORD code;
    TReaderInfoChSize info_chsize;
    info_chsize = *size;
    code = supsys_call(context, READER_FUN_CHSIZE, &info_chsize);
    /* Удалил восстановление контекста как контрпродуктивное в данной функции */
    //   if( code == (DWORD)CPR_ERR_BLOCK )
    //code = ERROR_SUCCESS;
    if (code == ERROR_SUCCESS && info_chsize< *size)
    {
	*size = info_chsize;
	LOGRETURN((DWORD)NTE_TOKEN_KEYSET_STORAGE_FULL);
    }
    *size = info_chsize;
    LOGRETURN(code);
}

DWORD rdr_file_unlink(
    TSupSysEContext *context,
    TRdrFileNumber filno)
{
    TReaderInfoUnlink info_unlink;
    const TCHAR* file_name = get_file_name_by_number(filno);
    info_unlink.num = filno;
    info_unlink.name.length = 0;
    info_unlink.name.text = NULL;
    if (file_name != NULL)
    {
	info_unlink.name.length = _tcslen(file_name);
	info_unlink.name.text = (TCHAR*)file_name;
    }
    LOGRETURN(supsys_call(context, READER_FUN_UNLINK, &info_unlink));
}


DWORD rdr_file_read(
    TSupSysEContext *context,
    size_t pos,
    size_t size,
    void *buffer,
    size_t *read_len)
{
    DWORD code;
    TReaderInfoRead info_read;
    info_read.from = pos;
    info_read.info.length = size;
    info_read.info.info = buffer;

    code = supsys_call(context, READER_FUN_READ, &info_read);
    if (code == (DWORD)CPR_ERR_BLOCK)
	code = (DWORD)ERROR_SUCCESS;
    if (code)
	LOGRETURN(code);
    if (read_len) 
	*read_len = size - info_read.info.length;

    LOGRETURN((DWORD)ERROR_SUCCESS);
}

DWORD rdr_file_write(
    TSupSysEContext *context,
    size_t pos,
    size_t size,
    const void *buffer,
    size_t *writen)
{
    DWORD code;
    TReaderInfoWrite info_write;
    info_write.from = pos;
    info_write.info.length = size;
    info_write.info.info = (BYTE*)buffer;
    code = supsys_call(context, READER_FUN_WRITE, &info_write);
    if (code == (DWORD)CPR_ERR_BLOCK)
	code = ERROR_SUCCESS;
    if (code)
	LOGRETURN(code);
    if (writen)
	*writen = size - info_write.info.length;
    LOGRETURN((DWORD)ERROR_SUCCESS);
}

