⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fsdiag.c

📁 free sources for gsm
💻 C
📖 第 1 页 / 共 3 页
字号:
/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*

                   Diagnostics Packet Processing

General Description
  Diagnostic packet processing routines for file system access.

Copyright (c) 1990-2003 by QUALCOMM, Incorporated.  All Rights Reserved.
*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/

/*===========================================================================

                           Edit History

$Header: //depot/asic/msmshared/services/diag/fsdiag.c#17 $

when       who     what, where, why
--------   ---     ----------------------------------------------------------
02/18/04    as     Fixed critical lint errors.
08/12/04    as     Removed support for Remote file link.
06/23/04    as     Fixes for RVCT 2.1
05/18/04    as     Added security check to fsdiag_cmd.
11/05/03    pg     Added support for fs_format function.
07/10/03    gr     Moved access validation code into its own file.
06/23/07   jkl     Featurized for EFS2.
04/07/03   jct     Added file access validation callbacks which invoke a
                   registered callback for any file system access via
                   DIAG - the callback returns a status indicating whether or
                   not the operation may proceed.  If no callback exists
                   the operation proceeds.
12/02/02   lad     Added retry mechanism to read operation.
08/20/01   jal     Updated for core VU
09/06/00   jal     Incorporated David Brown's change to stop EFS file
                   descriptor leakage
05/10/00   lad     Updated usage of diagpkt_shorten().
03/23/00   lad     Fixed iterative listings.
02/28/00   lad     Changed functions to use diagbuf allocation services.
01/20/99   lad     Removed unnecessary debug MSG_MED calls.
11/16/99   lad     Set attrib uses existing creation date if -1 is set.
                   fs_write overwrite fix.
07/23/99   lad     Added rev 2 of EFS support.
03/26/99   lad     Created for Embedded Filesystem (EFS) support.  Write/MKDIR
===========================================================================*/
#ifdef __cplusplus
  extern "C" {
#endif

#include "comdef.h"
#include "customer.h"

#include "diagbuf.h"
#include "diagcmd.h"
#include "fsdiag.h"

#include "diag.h"
#include <string.h>
#include "fs.h"

/* Tell lint that we are OK with the fact that pkt_len and req are not 
** used in some of the packets, as this is dictated by the awesome design */
/*lint -esym(715,pkt_len,req) */
  
/*--------------------------------------------------------
  Gloabal data for cleanup of incomplete file transfers
--------------------------------------------------------*/
typedef enum
{
  FSDIAG_NONE,
  FSDIAG_READ,
  FSDIAG_WRITE
} fsdiag_operation_enum_type;

LOCAL fsdiag_operation_enum_type fsdiag_op = FSDIAG_NONE;
LOCAL fs_handle_type fsdiag_handle = NULL;
LOCAL char fsdiag_filename[FSDIAG_MAX_FILENAME_LEN] = {'\0'};


/*===========================================================================

FUNCTION FSDIAG_CLEANUP
DESCRIPTION
  This function cleans up (closes, etc) files operations that are were not 
  completed.

============================================================================*/
static boolean fsdiag_cleanup ()
{
  boolean bRetVal = TRUE;
  fs_rsp_msg_type fs_rsp;  /* FS requires we specify a response message */

  if (fsdiag_handle != NULL || fsdiag_filename[0] != NULL) 
  {
    fs_close(fsdiag_handle, NULL, &fs_rsp);

    if (fsdiag_op == FSDIAG_WRITE)
    {
      /*--------------------------------------------------------
       Remove the stagnant file - if not same file, who cares.
      --------------------------------------------------------*/
      fs_remove(fsdiag_filename, NULL, &fs_rsp);

      if (fs_rsp.rmfile.status != FS_OKAY_S) 
      {
        bRetVal = FALSE;
      }
    }
  }
  
  /*---------------------------------------------
   Initialize file handle and saved filename
  ---------------------------------------------*/
  fsdiag_handle = NULL;
  fsdiag_filename[0] = NULL;
  fsdiag_op = FSDIAG_NONE;

  return (bRetVal);

} /* fsdiag_cleanup */



/*===========================================================================

FUNCTION FSDIAG_MKDIR
DESCRIPTION
  This function handles FS "Create Directory" commands in DIAG.
  
============================================================================*/
static PACKED void * fsdiag_mkdir (
  fsdiag_mkdir_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( MKDIR, (const char *)req->name );

  rsp = (fsdiag_rsp_pkt_type *)diagpkt_alloc(DIAG_FS_OP_F, rsp_len);
                                
  /*--------------------------------
   Check for valid filename length.
  --------------------------------*/
  fs_mkdir((const char *)req->name, NULL, &fs_rsp);

  rsp->fs_status = fs_rsp.mkdir.status;
    
  return (rsp);

} /* fsdiag_mkdir */
      
      

/*===========================================================================

FUNCTION FSDIAG_DISP_DIRS
DESCRIPTION
  This function handles FS "Display Directory List" commands in DIAG.
  
============================================================================*/
static PACKED void *fsdiag_disp_dirs (
  fsdiag_disp_dirs_req_type *req,
  word pkt_len
)
{
  fs_rsp_msg_type fs_rsp;  /* FS requires we specify a response message */
  fsdiag_rsp_pkt_type *rsp;
  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( DISP_DIRS, (const char *)req->name );

  /*----------------------------------------------------------------
    Unknown response size.  Therefore, we will allocate the max
    possible size for this packet and reduce length later.
  ----------------------------------------------------------------*/
  rsp = (fsdiag_rsp_pkt_type *)diagpkt_alloc(DIAG_FS_OP_F, rsp_len + FSIZ(fsdiag_rsp_type, disp_dirs));

  do
  {  
    /*--------------------------------
     Get the number of directories.
    --------------------------------*/
    /* Old versions of FS do not always properly set this variable */ 
    fs_rsp.num_dirs.num_dirs = 0;
  
    fs_num_dirs((const char *)req->name, NULL, &fs_rsp);
  
    if (fs_rsp.num_dirs.status == FS_OKAY_S)
    {
      rsp->fs_rsp.disp_dirs.num_dirs = fs_rsp.num_dirs.num_dirs;
    }
    else
    {
      break;  
    }
  
    /*-------------------------------------
      Now get the actual directory list 
    --------------------------------------*/
    fs_list_dirs((const char *)req->name,
                 (void*) rsp->fs_rsp.disp_dirs.dir_list.data,
                 FSDIAG_MAX_FILE_BLOCK_SIZE,
                 NULL,
                 &fs_rsp);
    
    if (fs_rsp.list_dirs.status == FS_OKAY_S)
    {
      rsp->fs_rsp.disp_dirs.dir_list.len = 
        (word) fs_rsp.list_dirs.count;
  
      rsp_len += sizeof(rsp->fs_rsp.disp_dirs.num_dirs)     +
                 sizeof(rsp->fs_rsp.disp_dirs.dir_list.len) +
                 rsp->fs_rsp.disp_dirs.dir_list.len;
    }
  } while (0);

  rsp->fs_status = fs_rsp.any.status;
  
  /*------------------------------------------
    If necessary, shorten the length of the 
    response to the actual size
  ------------------------------------------*/
  diagpkt_shorten(rsp, rsp_len);

  return (rsp);

} /* fsdiag_disp_dirs */



/*===========================================================================

FUNCTION FSDIAG_DISP_FILES
DESCRIPTION
  This function handles FS "Display File List" commands in DIAG.

============================================================================*/
static PACKED void *fsdiag_disp_files (
  fsdiag_disp_files_req_type *req,
  word pkt_len
)
{
  fs_rsp_msg_type fs_rsp;  /* FS requires we specify a response message */
  fsdiag_rsp_pkt_type *rsp;
  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( DISP_FILES, (const char *)req->name );

  /*----------------------------------------------------------------
    Unknown response size.  Therefore, we will allocate the max
    possible size for this packet and reduce length later.
  ----------------------------------------------------------------*/
  rsp = (fsdiag_rsp_pkt_type *)diagpkt_alloc(DIAG_FS_OP_F, rsp_len + FSIZ(fsdiag_rsp_type, disp_files));
  
  do
  {
    /*--------------------------------
     Get the number of files.
    --------------------------------*/
    /* Old versions of FS don't always set this variable. */
    fs_rsp.num_files.num_files = 0;
  
    fs_num_files((const char *)req->name, NULL, &fs_rsp);
  
    rsp->fs_status = fs_rsp.num_files.status;
  
    if (fs_rsp.num_files.status == FS_OKAY_S)
    {
      rsp->fs_rsp.disp_files.num_files = fs_rsp.num_files.num_files;
    }
    else
    {
      break;  
    }
  
    /*------------------------------
      Now get the actual file list 
    -------------------------------*/
    fs_list_files((const char *)req->name,
                  (void*) rsp->fs_rsp.disp_files.file_list.data,
                  FSDIAG_MAX_FILE_BLOCK_SIZE,
                  NULL,
                  &fs_rsp);
    
    if (fs_rsp.list_files.status == FS_OKAY_S)
    {
      rsp->fs_rsp.disp_files.file_list.len = 
        (word) fs_rsp.list_files.count;
  
      rsp_len += sizeof(rsp->fs_rsp.disp_files.num_files)     +
                 sizeof(rsp->fs_rsp.disp_files.file_list.len) +
                 rsp->fs_rsp.disp_files.file_list.len;
    }
  } while (0);

  rsp->fs_status = fs_rsp.any.status;
  
  /*------------------------------------------
    If necessary, shorten the length of the 
    response to the actual size
  ------------------------------------------*/
  diagpkt_shorten(rsp, rsp_len);

  return (rsp);

} /* fsdiag_disp_files */



/*===========================================================================

FUNCTION FSDIAG_RMDIR
DESCRIPTION
  This function handles FS "Remove Directory" commands in DIAG.

============================================================================*/
static PACKED void *fsdiag_rmdir (
  fsdiag_rmdir_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( RMDIR, (const char *)req->name );

  rsp = (fsdiag_rsp_pkt_type *)diagpkt_alloc(DIAG_FS_OP_F, rsp_len);
                                
  fs_rmdir((const char *)req->name, NULL, &fs_rsp);

  rsp->fs_status = fs_rsp.rmdir.status;
    
  return (rsp);

} /* fsdiag_rmdir */



/*===========================================================================

FUNCTION FSDIAG_GET_ATTRIB
DESCRIPTION
  This function handles FS "Get File Attributes" commands in DIAG.

============================================================================*/
static PACKED void *fsdiag_get_attrib (
  fsdiag_get_attrib_req_type *req,
  word pkt_len
)
{              
  fs_rsp_msg_type fs_rsp;  /* FS requires we specify a response message */
  fsdiag_rsp_pkt_type *rsp;
  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( GET_ATTRIB, (const char *)req->name );

  /*---------------------------------
   Check for valid filename length.
  ---------------------------------*/
  fs_get_file_attributes((const char *)req->name, NULL, &fs_rsp);

  if (fs_rsp.get_attribs.status == FS_OKAY_S)
  {
    rsp_len += FSIZ(fsdiag_rsp_type, get_attrib);
  }

  rsp = (fsdiag_rsp_pkt_type *)diagpkt_alloc(DIAG_FS_OP_F, rsp_len);
                                
  rsp->fs_status = fs_rsp.get_attribs.status;
    
  if (fs_rsp.get_attribs.status == FS_OKAY_S)
  {
    rsp->fs_rsp.get_attrib.attrib.attribute_mask = 
      fs_rsp.get_attribs.attributes;
    
    rsp->fs_rsp.get_attrib.attrib.buffering_option = 
      fs_rsp.get_attribs.buffering_option;
    
    rsp->fs_rsp.get_attrib.attrib.cleanup_option = 
      fs_rsp.get_attribs.cleanup_option;

    rsp->fs_rsp.get_attrib.creation_date = 
      fs_rsp.get_attribs.creation_date;
    
    /*------------------------------------------------ 
       Event though it is not a attribute in the EFS, 
       file size would be a handy thing to know.
    ------------------------------------------------*/
    fs_file_size((const char *)req->name, NULL, &fs_rsp);

    if (fs_rsp.file_size.status == FS_OKAY_S)
    {
      rsp->fs_rsp.get_attrib.size = fs_rsp.file_size.size;
    }
    else
    {
      rsp->fs_rsp.get_attrib.size = 0;
    }
  }
  
  return (rsp);

} /* fsdiag_get_attrib */


/*===========================================================================

FUNCTION FSDIAG_SET_ATTRIB
DESCRIPTION
  This function handles FS SET ATTRIB commands in DIAG.
  
============================================================================*/
static PACKED void *fsdiag_set_attrib (
  fsdiag_set_attrib_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 int rsp_len = FPOS(fsdiag_rsp_pkt_type, fs_rsp);

  /*--------------------------------

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -