📄 fsdiag.c
字号:
fs_open((const char *)req->block.begin.var_len_buf.name_info.name,
FS_OA_CREATE,
&fs_open_xparms,
NULL,
&fs_rsp);
}
}
if (fs_rsp.any.status != FS_OKAY_S)
{
fsdiag_cleanup();
next_seq_num = 0;
break;
}
/*-----------------------------------------------
Save file name info for possible cleanup later
-----------------------------------------------*/
memcpy (fsdiag_filename,
(void *) req->block.begin.var_len_buf.name_info.name,
req->block.begin.var_len_buf.name_info.len);
/*--------------------------------------
Save current operation for cleanup
--------------------------------------*/
fsdiag_op = FSDIAG_WRITE;
fsdiag_handle = fs_rsp.open.handle;
/*--------------------
Record total length
--------------------*/
total_file_length = req->block.begin.total_length;
written_so_far = 0;
} /* Sequence number == 0 */
else if (next_seq_num == req->seq_num)
{
/*---------------------------------------------------
Make sure the length of the data block is valid.
---------------------------------------------------*/
if (data_ptr->len > FSDIAG_MAX_FILE_BLOCK_SIZE)
{
fs_rsp.any.status = FS_PARAMETER_ERROR_S;
break;
}
}
/*------------------------------------------
Go ahead and write.
Already did range checking on block size
------------------------------------------*/
if (written_so_far += data_ptr->len <= total_file_length)
{
fs_write(fsdiag_handle,
(void*)&data_ptr->data,
data_ptr->len,
NULL,
&fs_rsp);
}
else /* Attempt to write more than specified length for file */
{
fs_rsp.any.status = FS_ILLEGAL_OPERATION_S;
}
if (fs_rsp.any.status != FS_OKAY_S)
{
fsdiag_cleanup();
next_seq_num = 0;
break;
}
else
{
/* Must handle sequence number rollover */
next_seq_num = (next_seq_num == 0xFF) ? 1 : next_seq_num + 1;
}
if (req->more == FALSE)
{
/*-------------------
Now close the file
-------------------*/
fs_close(fsdiag_handle, NULL, &fs_rsp);
fsdiag_handle = NULL;
fsdiag_op = FSDIAG_NONE;
fsdiag_filename[0] = NULL;
next_seq_num = 0;
}
} while ( 0 );
rsp->fs_status = fs_rsp.any.status;
return (rsp);
} /* fsdiag_write */
/*===========================================================================
FUNCTION FSDIAG_RMFILE
DESCRIPTION
This function handles FS "Remove File" commands in DIAG.
============================================================================*/
static PACKED void *fsdiag_rmfile (
fsdiag_rmfile_req_type *req,
word pkt_len
)
{
fs_rsp_msg_type fs_rsp; /* FS requires we specify a response message */
fsdiag_rsp_pkt_type *rsp;
const word rsp_len = FPOS(fsdiag_rsp_pkt_type, fs_rsp);
/*--------------------------------
Check for valid packet length.
--------------------------------*/
if (pkt_len != req->len + sizeof(req->len))
{
return( diagpkt_err_rsp(DIAG_BAD_LEN_F, req, pkt_len) );
}
FS_DIAG_VALIDATE_ACCESS( DELETE, (const char *)req->name );
rsp = (fsdiag_rsp_pkt_type *)diagpkt_alloc(DIAG_FS_OP_F, rsp_len);
fsdiag_cleanup();
fs_remove((const char *)req->name, /* Absolute dir name */
NULL,
&fs_rsp);
rsp->fs_status = fs_rsp.rmfile.status;
return (rsp);
} /* fsdiag_rmfile */
/*===========================================================================
FUNCTION FSDIAG_ITER
DESCRIPTION
This function handles FS "Iterate Directories" commands in DIAG.
============================================================================*/
static PACKED void *fsdiag_iter (
fsdiag_iter_dirs_req_type *req,
uint16 pkt_len,
fsdiag_op_enum_type op_type
)
{
fs_rsp_msg_type fs_rsp;
static fs_enum_iterator_type fs_enum;
static boolean previously_opened = 0;
fs_enum_data_type fs_enum_data;
fsdiag_rsp_pkt_type *rsp;
word rsp_len = FPOS(fsdiag_rsp_pkt_type, fs_rsp);
/*--------------------------------
Check for valid packet length.
--------------------------------*/
if (pkt_len != FPOS(fsdiag_iter_dirs_req_type, dir_name.name) +
req->dir_name.len)
{
return( diagpkt_err_rsp(DIAG_BAD_LEN_F, req, pkt_len) );
}
do
{
/* If seq number is 0, do the initialization */
if(req->seq_num == 0)
{
FS_DIAG_VALIDATE_ACCESS( ITERATE, (const char *)req->dir_name.name );
/*----------------------
Determine operation
----------------------*/
if (op_type == FSDIAG_ITER_FILES)
{
fs_enum.enum_kind = FS_ENUM_FILES;
}
else
{
fs_enum.enum_kind = FS_ENUM_DIRECTORIES;
}
/* Close the previous iterator. */
if (previously_opened)
{
fs_enum_finish (&fs_enum, NULL, &fs_rsp);
}
/*-----------------------
Initialize enumerator.
-----------------------*/
fs_enum_init((const char *)req->dir_name.name,
fs_enum.enum_kind,
&fs_enum,
NULL,
&fs_rsp);
previously_opened = TRUE;
if (fs_rsp.enum_init.status != FS_OKAY_S)
{
rsp = (fsdiag_rsp_pkt_type *)diagpkt_alloc(DIAG_FS_OP_F, rsp_len);
break;
}
} /* if first time */
/*---------------------------------------------------------------------
Request the directory name corresponding to the given sequence number
-----------------------------------------------------------------------*/
fs_enum_next(&fs_enum_data,
&fs_enum,
NULL,
&fs_rsp);
if (fs_rsp.enum_next.status == FS_OKAY_S)
{
rsp_len += FPOS(fsdiag_iter_rsp_type, item_name.name) +
fs_enum_data.fullname_length;
}
rsp = (fsdiag_rsp_pkt_type *)diagpkt_alloc(DIAG_FS_OP_F, rsp_len);
if (fs_rsp.enum_next.status == FS_OKAY_S)
{
rsp->fs_rsp.iter.seq_num = req->seq_num;
/* Attributes */
rsp->fs_rsp.iter.attrib.attribute_mask = fs_enum_data.attributes;
rsp->fs_rsp.iter.attrib.buffering_option = fs_enum_data.buffering_option;
rsp->fs_rsp.iter.attrib.cleanup_option = fs_enum_data.cleanup_option;
/* File info */
rsp->fs_rsp.iter.creation_date = fs_enum_data.creation_date;
rsp->fs_rsp.iter.logical_size = fs_enum_data.logical_size;
rsp->fs_rsp.iter.physical_size = fs_enum_data.physical_size;
/* Name info */
rsp->fs_rsp.iter.dirname_length = fs_enum_data.dirname_length;
rsp->fs_rsp.iter.item_name.len = fs_enum_data.fullname_length;
memcpy((void*) rsp->fs_rsp.iter.item_name.name,
fs_enum_data.fullname,
fs_enum_data.fullname_length);
}
}while( 0 );
rsp->fs_status = fs_rsp.any.status;
return (rsp);
} /* fsdiag_iter */
/*===========================================================================
FUNCTION FSDIAG_SPACE_AVAIL
DESCRIPTION
This function handles FS "Space Available" commands in DIAG.
============================================================================*/
static PACKED void *fsdiag_space_avail (void)
{
fsdiag_rsp_pkt_type *rsp;
const word rsp_len = FPOS(fsdiag_rsp_pkt_type, fs_rsp) +
sizeof(fsdiag_space_avail_rsp_type);
rsp = (fsdiag_rsp_pkt_type *)diagpkt_alloc(DIAG_FS_OP_F, rsp_len);
rsp->fs_rsp.space_avail = fs_space_available();
rsp->fs_status = FS_OKAY_S;
return (rsp);
} /* fsdiag_space_avail */
/*===========================================================================
FUNCTION FSDIAG_FORMAT
DESCRIPTION
This function handles FS "Format Card" commands in DIAG.
============================================================================*/
static PACKED void * fsdiag_format (
fsdiag_format_req_type *req,
word pkt_len
)
{
fs_rsp_msg_type fs_rsp; /* FS requires we specify a response message */
fsdiag_rsp_pkt_type *rsp;
const word rsp_len = FPOS(fsdiag_rsp_pkt_type, fs_rsp);
/*--------------------------------
Check for valid packet length.
--------------------------------*/
if (pkt_len != req->len + sizeof(req->len))
{
return (diagpkt_err_rsp(DIAG_BAD_LEN_F, req, pkt_len));
}
FS_DIAG_VALIDATE_ACCESS( FORMAT, req->name );
rsp = (fsdiag_rsp_pkt_type *)diagpkt_alloc(DIAG_FS_OP_F, rsp_len);
/*--------------------------------
Check for valid filename length.
--------------------------------*/
fs_format(req->name, NULL, &fs_rsp);
rsp->fs_status = fs_rsp.format.status;
return (rsp);
} /* fsdiag_format */
/*===========================================================================
FUNCTION FSDIAG_CMD
DESCRIPTION
This procedure processes a request to perform an Embedded File System
(EFS) operation. It is a variable length command to save on bandwidth,
so the buffer to write into should only copy the needed bytes. This
procedure will call the appropriate procedure in diag_fs.c to handle
each operation.
============================================================================*/
PACKED void * fsdiag_cmd (
PACKED void *req_pkt,
uint16 pkt_len
)
{
fsdiag_req_pkt_type *req = (fsdiag_req_pkt_type *)req_pkt;
fsdiag_rsp_pkt_type *rsp = NULL;
/* # of bytes being stripped off of generic packet (cmd_code, etc) */
word rsp_len = DIAG_FS_REQ_LEN_DIFF;
/*-------------------------------------------------------------------------
Check security, since this is a secure funciton
--------------------------------------------------------------------------*/
if (diag_get_security_state() != DIAG_SEC_UNLOCKED) {
return( diagpkt_err_rsp(DIAG_BAD_SEC_MODE_F, req_pkt, pkt_len) );
}
/*-------------------------------------------------------------------------
Determine requested file operation and call appropriate DIAG FS function
-------------------------------------------------------------------------*/
switch (req->file_op) {
case FSDIAG_MK_DIR:
rsp = (fsdiag_rsp_pkt_type *)fsdiag_mkdir(&req->fs_req.mkdir,
pkt_len - rsp_len);
break;
case FSDIAG_RM_DIR:
rsp = (fsdiag_rsp_pkt_type *)fsdiag_rmdir(&req->fs_req.rmdir,
pkt_len - rsp_len);
break;
case FSDIAG_DISP_DIRS:
rsp = (fsdiag_rsp_pkt_type *)fsdiag_disp_dirs(&req->fs_req.disp_dirs,
pkt_len - rsp_len);
break;
case FSDIAG_DISP_FILES:
rsp = (fsdiag_rsp_pkt_type *)fsdiag_disp_files(&req->fs_req.disp_files,
pkt_len - rsp_len);
break;
case FSDIAG_READ_FILE:
rsp = (fsdiag_rsp_pkt_type *)fsdiag_read(&req->fs_req.read,
pkt_len - rsp_len);
break;
case FSDIAG_WRITE_FILE:
rsp = (fsdiag_rsp_pkt_type *)fsdiag_write(&req->fs_req.write,
pkt_len - rsp_len);
break;
case FSDIAG_REMOVE_FILE:
rsp = (fsdiag_rsp_pkt_type *)fsdiag_rmfile(&req->fs_req.rmfile,
pkt_len - rsp_len);
break;
case FSDIAG_GET_ATTRIB:
rsp = (fsdiag_rsp_pkt_type *)fsdiag_get_attrib(&req->fs_req.get_attrib,
pkt_len - rsp_len);
break;
case FSDIAG_SET_ATTRIB:
rsp = (fsdiag_rsp_pkt_type *)fsdiag_set_attrib(&req->fs_req.set_attrib,
pkt_len - rsp_len);
break;
case FSDIAG_ITER_DIRS:
case FSDIAG_ITER_FILES:
rsp = (fsdiag_rsp_pkt_type *)fsdiag_iter(&req->fs_req.iter_dirs,
pkt_len - rsp_len,
(fsdiag_op_enum_type) req->file_op);
break;
case FSDIAG_SPACE_AVAIL:
rsp = (fsdiag_rsp_pkt_type *)fsdiag_space_avail();
break;
case FSDIAG_FORMAT:
rsp = (fsdiag_rsp_pkt_type *)fsdiag_format(&req->fs_req.format,
pkt_len - rsp_len);
break;
default:
return( diagpkt_err_rsp(DIAG_BAD_PARM_F, req_pkt, pkt_len) );
}
/* Copy the file operation into the response
*/
rsp->file_op = req->file_op;
return (rsp);
} /* fsdiag_cmd */
/* Restore error reporting for these symbols */
/*lint +esym(715,pkt_len,req) */
static const diagpkt_user_table_entry_type fsdiag_tbl[] =
{
{DIAG_FS_OP_F, DIAG_FS_OP_F, fsdiag_cmd}
};
#ifdef __cplusplus
DIAGPKT_DISPATCH_AUTOREGISTER (DIAGPKT_NO_SUBSYS_ID, fsdiag_tbl);
#else
void fsdiag_init (void)
{
DIAGPKT_DISPATCH_TABLE_REGISTER (DIAGPKT_NO_SUBSYS_ID, fsdiag_tbl);
}
#endif
#ifdef __cplusplus
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -