/*
* 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"


DWORD rdr_folder_open(
    TSupSysEContext *context,
    BOOL create,
    const TCHAR *folder)
{
    DWORD code;
    TReaderInfoFolderOpen info_open;
    TReaderInfoOpenFlags mode_flags = { 0 };
    if (create)
	mode_flags.o_create = 1;
    mode_flags.o_read = 1;
    mode_flags.o_write = 1;
    mode_flags.o_private = 0;

    info_open.name.length = 0;
    info_open.name.text = NULL;
    info_open.mode_bits = READER_MODEFLAG_BITS;
    info_open.mode = mode_flags;
    
    if (folder)
    {
	info_open.name.length = _tcslen(folder);
	info_open.name.text = (void*)folder;
    }

    code = supsys_call(context, READER_FUN_FOLDER_OPEN, &info_open);
    if (code == (DWORD)ERROR_NOT_SUPPORTED && !mode_flags.o_create)
	code = ERROR_SUCCESS;
    LOGRETURN(code);
}
DWORD rdr_folder_clear(TSupSysEContext *context)
{
    DWORD err = supsys_call(context, READER_FUN_FOLDER_CLEAR, NULL);
    if (err == (DWORD)ERROR_NOT_SUPPORTED)
	err = (DWORD)ERROR_SUCCESS;
    LOGRETURN(err);
}

DWORD rdr_folder_close(
    TSupSysEContext *context)
{
    DWORD err;
    UNUSED(context);

    err = supsys_call(context, READER_FUN_FOLDER_CLOSE, NULL);
    if (err == (DWORD)ERROR_NOT_SUPPORTED)
	err = (DWORD)ERROR_SUCCESS;
    LOGRETURN(err);
}


DWORD rdr_folder_enum_open(
    const TSupSysEContext *context,
    TRdrFolderEnumContext **enum_ctx,
    size_t *folder_length,
    const TCHAR *prototype,
    unsigned flags)
{
    TReaderInfoFolderEnum *info;
    TCHAR *name;
    DWORD code;
    TCHAR *prot = NULL;
    SUPSYS_PRE_CONTEXT(enum_ctx, TReaderInfoFolderEnum*);
    SUPSYS_PRE_WRITE_PTRS(folder_length, sizeof(size_t));

    *folder_length = 0;
    *enum_ctx = NULL;
    info = malloc(sizeof(TReaderInfoFolderEnum));
    if (info == NULL)
	LOGRETURN((DWORD)NTE_NO_MEMORY);
    if (prototype)
    {
	prot = malloc((_tcslen(prototype) + 1) * sizeof(TCHAR));
	if (prot == NULL)
	{
	    free(info);
	    LOGRETURN((DWORD)NTE_NO_MEMORY);
	}
	_tcscpy(prot, prototype);
    }
    info->add_info.info = NULL;
    info->add_info.length = 0;
    info->context = context;
    info->name.length = 0;
    info->name.text = NULL;
    info->prototype.text = NULL;
    info->prototype.length = 0;
    info->flags = flags;
    if (prototype)
    {
	info->prototype.length = _tcslen(prototype);
	info->prototype.text = prot;
    }
    code = supsys_call(context, READER_FUN_FOLDER_ENUM_OPEN, info);
    if (code)
    {
	free(info);
	LOGRETURN(code);
    }
    name = malloc((info->name.length + 1) * sizeof(TCHAR));
    if (name == NULL)
    {
	supsys_call(context, READER_FUN_FOLDER_ENUM_CLOSE, info);
	free(info);
	LOGRETURN((DWORD)NTE_NO_MEMORY);
    }
    info->name.text = name;
    *folder_length = info->name.length;
    *enum_ctx = (TRdrFolderEnumContext*)info;
    LOGRETURN(ERROR_SUCCESS);
}

DWORD rdr_folder_enum_next(
    TRdrFolderEnumContext *enum_ctx,
    TCHAR *folder)
{
    DWORD code;
    TReaderInfoFolderEnum *info = (TReaderInfoFolderEnum*)enum_ctx;
    size_t back_length;
    SUPSYS_PRE_CCONTEXT(enum_ctx, TReaderInfoFolderEnum);
    SUPSYS_PRE_WRITE_PTRS(folder, (info->name.length + 1)
	* sizeof(TCHAR));
    back_length = info->name.length;

    code = supsys_call(info->context, READER_FUN_FOLDER_ENUM_NEXT, info);
    if (code)
    {
	info->name.length = back_length;
	LOGRETURN(code);
    }
    if (back_length < info->name.length)
	info->name.length = back_length;
    _tcsncpy(folder, info->name.text, info->name.length);
    folder[info->name.length] = 0;
    info->name.length = back_length;
    LOGRETURN(ERROR_SUCCESS);
}

DWORD rdr_folder_enum_close(
    TRdrFolderEnumContext *enum_ctx)
{
    DWORD code;
    TReaderInfoFolderEnum *info = (TReaderInfoFolderEnum*)enum_ctx;
    SUPSYS_PRE_CONTEXT(enum_ctx, TReaderInfoFolderEnum*);
    code = supsys_call(info->context, READER_FUN_FOLDER_ENUM_CLOSE, info);
    free(info->name.text);
    free(info->prototype.text);
    free(info);
    LOGRETURN(code);
}

DWORD rdr_get_default_folder(TSupSysEContext *context, TCHAR * def_name, size_t max_len)
{
    DWORD code;
    TSupSysInfoText info;
    SUPSYS_PRE_CONTEXT(context, TSupSysEContext*);

    info.text = def_name;
    info.length = max_len;
    code = supsys_call(context, READER_FUN_GET_DEFAULT_FOLDER, &info);
    LOGRETURN(code);
}

DWORD rdr_set_default_folder (TSupSysEContext *context, TCHAR * name) 
{
    DWORD code;
    TSupSysInfoText info;
    SUPSYS_PRE_CONTEXT(context, TSupSysEContext*);
    info.text = name;
    info.length = _tcslen(name);
    code = supsys_call(context, READER_FUN_SET_DEFAULT_FOLDER, &info);
    LOGRETURN(code);
}

DWORD rdr_get_free_space(TSupSysEContext* context, size_t* free_space) {
    DWORD code = 0;
    TReaderInfoFreeSpaceSize size = 0;
    SUPSYS_PRE_CONTEXT(context, TSupSysEContext*);
    SUPSYS_PRE(free_space);
    code = supsys_call(context, READER_FUN_GET_FREE_SPACE, &size);
    if (code == ERROR_SUCCESS)
	*free_space = size;
    LOGRETURN(code);
}
