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

#include "ric_prj.h"

DWORD ric_file_write( 
    TSupSysContext *context, 
    TSupSysInfo *info )
{
    TReaderInfoWrite *inf = (TReaderInfoWrite*)info;
    DWORD code;
    TRICContext *ctx = (TRICContext*)context;
    BYTE apdu[] = { 0, 0xD6, 0, 0 };
    size_t length;
    int full = 0;
    size_t offset = 0;

    SUPSYS_PRE_CONTEXT( context, TRICContext );
    SUPSYS_PRE_INFO( info, TReaderInfoWrite );
    SUPSYS_PRE( ctx->file );
    SUPSYS_PRE( inf->from <= 0x7fff );
    SUPSYS_PRE( inf->info.length <= 0xffff );

    length = ctx->block_len_write;
    if( length > inf->info.length )
	length = inf->info.length;
    if( inf->from >= ctx->file_length )
	return (DWORD)NTE_TOKEN_KEYSET_STORAGE_FULL;
    if( inf->from + length > ctx->file_length )
    {
	full = 1;
	length = ctx->file_length - inf->from;
    }

    if (ctx->card_type == CardType_OSCAR2) {
	size_t from_new = 0;
	code = oscar2_file_offset(ctx->file, &offset, ctx->connect_name);
	if(code)
	    return code;
	from_new = inf->from + offset;

	if(length > (ctx->block_len_write - (from_new % ctx->block_len_write))) 
	    length = ctx->block_len_write - (from_new % ctx->block_len_write);
	offset = from_new;
    }
    else {
	if(length > (ctx->block_len_write - (inf->from % ctx->block_len_write))) 
	    length = ctx->block_len_write - (inf->from % ctx->block_len_write);
	offset = inf->from;
    }
    apdu[PCSC_P1_NUM] = (unsigned char)( offset >> 8 );
    apdu[PCSC_P2_NUM] = (unsigned char)( offset & 0xff );
    code = send_apdu (ctx, apdu, inf->info.info, length, NULL, NULL);
    if( code )
	return code;

    inf->info.length -= length;
    if( full )
	return (DWORD)NTE_TOKEN_KEYSET_STORAGE_FULL;
    if( inf->info.length )
	return (DWORD)CPR_ERR_BLOCK;
    return ERROR_SUCCESS;
}
/* end of file: $Id: ric_wr.c 150304 2016-12-16 14:05:23Z sagafyin $ */
