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

#include "fat12prj.h"
#include "os_specific.h"

 /*!
  * \ingroup fat12_info_general
  * \brief Функция дублирования контекста считывателя.
  * \return Код ошибки
  */
DWORD fat12_context_dup(
    TSupSysContext *context,
    TSupSysInfo *info)
{
    TSupSysInfoContextDup *inf = (TSupSysInfoContextDup*)info;
    TFat12Context *dest;
    TFat12Context *src = (TFat12Context*)context;

    /* Провека входных параметров. */
    SUPSYS_PRE_CONTEXT(context, TFat12Context);
    SUPSYS_PRE_INFO(info, TSupSysInfoContextDup);

    dest = calloc(sizeof(TFat12Context), 1);
    if (dest == NULL)
	return (DWORD)NTE_NO_MEMORY;
    dest->path = NULL;
    if (src->path && (src->flags & FAT12_FLAG_HDIMAGE)) {
	dest->path = malloc((_tcslen(src->path) + 1) * sizeof(TCHAR));
	if (!dest->path) {
	    free(dest);
	    return (DWORD)NTE_NO_MEMORY;
	}
	_tcscpy(dest->path, src->path);
    }
    dest->path_to_item = NULL;
    if (src->path_to_item) {
	dest->path_to_item = malloc((_tcslen(src->path_to_item) + 1) * sizeof(TCHAR));
	if (!dest->path_to_item) {
	    free(dest->path);
	    free(dest);
	    return (DWORD)NTE_NO_MEMORY;
	}
	_tcscpy(dest->path_to_item, src->path_to_item);
    }
    dest->long_names = src->long_names;
    dest->file_name = NULL;
    dest->folder = NULL;
    dest->flags = src->flags;
    _tcscpy(dest->nickname, src->nickname);
    _tcscpy(dest->connect, src->connect);
#ifdef UNIX
    dest->volume_label = NULL;
    dest->volume_serial = (unsigned long)-1;
    dest->machine = 0;
    dest->handle = NULL;
    dest->locked = FALSE;
    _tcscpy(dest->lock_name, src->lock_name);
    if (src->volume_label) {
	dest->volume_label = (TCHAR*)malloc((_tcslen(src->volume_label) + 1) * sizeof(TCHAR));
	if (!dest->volume_label) {
	    free(dest->path_to_item);
	    free(dest->path);
	    free(dest);
	    return (DWORD)NTE_NO_MEMORY;
	}
	_tcscpy(dest->volume_label, src->volume_label);
    }
    const DWORD err = open_named_mutex(dest->lock_name, &dest->lock);
    if (err) {
	free(dest->volume_label);
	free(dest->path_to_item);
	free(dest->path);
	free(dest);
	return err;
    }
#else /* UNIX */
    dest->access = 0;
    dest->handle = INVALID_HANDLE_VALUE;
#endif /* UNIX */
    inf->dest_context = dest;
    return ERROR_SUCCESS;
}

/*!
 * \ingroup fat12_info_general
 * \brief Функция дублирования контекста считывателя.
 * \return Код ошибки
 */
DWORD hdimage_context_dup(TSupSysContext *context, TSupSysInfo *info)
{
    TSupSysInfoContextDup *inf = (TSupSysInfoContextDup*)info;
    TFat12Context *dest;
    TFat12Context *src = (TFat12Context*)context;

    /* Провека входных параметров. */
    SUPSYS_PRE_CONTEXT(context, TFat12Context);
    SUPSYS_PRE_INFO(info, TSupSysInfoContextDup);

    dest = calloc(sizeof(TFat12Context), 1);
    if (dest == NULL)
	return (DWORD)NTE_NO_MEMORY;
    dest->path = NULL;
    if (src->path && (src->flags & FAT12_FLAG_HDIMAGE)) {
	dest->path = malloc((_tcslen(src->path) + 1) * sizeof(TCHAR));
	if (!dest->path) {
	    free(dest);
	    return (DWORD)NTE_NO_MEMORY;
	}
	_tcscpy(dest->path, src->path);
    }
    dest->path_to_item = NULL;
    if (src->path_to_item) {
	dest->path_to_item = malloc((_tcslen(src->path_to_item) + 1) * sizeof(TCHAR));
	if (!dest->path_to_item) {
	    free(dest->path);
	    free(dest);
	    return (DWORD)NTE_NO_MEMORY;
	}
	_tcscpy(dest->path_to_item, src->path_to_item);
    }
    dest->file_name = NULL;
    dest->folder = NULL;
    dest->flags = src->flags;
    dest->is_encrypted = src->is_encrypted;
    dest->long_names = src->long_names;
    _tcscpy(dest->nickname, src->nickname);
    _tcscpy(dest->connect, src->connect);
#ifdef UNIX
    _tcscpy(dest->lock_name, src->lock_name);
    dest->machine = 0;
    dest->handle = NULL;
    dest->locked = FALSE;
    dest->volume_label = NULL;
    dest->volume_serial = (unsigned long)-1;
#else /* UNIX */
    dest->access = 0;
    dest->handle = INVALID_HANDLE_VALUE;
#endif /* UNIX */
    inf->dest_context = dest;
    return ERROR_SUCCESS;
}
