Home | History | Annotate | Line # | Download | only in acpidump
apfiles.c revision 1.6
      1 /******************************************************************************
      2  *
      3  * Module Name: apfiles - File-related functions for acpidump utility
      4  *
      5  *****************************************************************************/
      6 
      7 /*
      8  * Copyright (C) 2000 - 2016, Intel Corp.
      9  * All rights reserved.
     10  *
     11  * Redistribution and use in source and binary forms, with or without
     12  * modification, are permitted provided that the following conditions
     13  * are met:
     14  * 1. Redistributions of source code must retain the above copyright
     15  *    notice, this list of conditions, and the following disclaimer,
     16  *    without modification.
     17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
     18  *    substantially similar to the "NO WARRANTY" disclaimer below
     19  *    ("Disclaimer") and any redistribution must be conditioned upon
     20  *    including a substantially similar Disclaimer requirement for further
     21  *    binary redistribution.
     22  * 3. Neither the names of the above-listed copyright holders nor the names
     23  *    of any contributors may be used to endorse or promote products derived
     24  *    from this software without specific prior written permission.
     25  *
     26  * Alternatively, this software may be distributed under the terms of the
     27  * GNU General Public License ("GPL") version 2 as published by the Free
     28  * Software Foundation.
     29  *
     30  * NO WARRANTY
     31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
     34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
     40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     41  * POSSIBILITY OF SUCH DAMAGES.
     42  */
     43 
     44 #include "acpidump.h"
     45 #include "acapps.h"
     46 
     47 
     48 /* Local prototypes */
     49 
     50 static int
     51 ApIsExistingFile (
     52     char                    *Pathname);
     53 
     54 
     55 /******************************************************************************
     56  *
     57  * FUNCTION:    ApIsExistingFile
     58  *
     59  * PARAMETERS:  Pathname            - Output filename
     60  *
     61  * RETURN:      0 on success
     62  *
     63  * DESCRIPTION: Query for file overwrite if it already exists.
     64  *
     65  ******************************************************************************/
     66 
     67 static int
     68 ApIsExistingFile (
     69     char                    *Pathname)
     70 {
     71 #ifndef _GNU_EFI
     72     struct stat             StatInfo;
     73 
     74 
     75     if (!stat (Pathname, &StatInfo))
     76     {
     77         AcpiLogError ("Target path already exists, overwrite? [y|n] ");
     78 
     79         if (getchar () != 'y')
     80         {
     81             return (-1);
     82         }
     83     }
     84 #endif
     85 
     86     return 0;
     87 }
     88 
     89 
     90 /******************************************************************************
     91  *
     92  * FUNCTION:    ApOpenOutputFile
     93  *
     94  * PARAMETERS:  Pathname            - Output filename
     95  *
     96  * RETURN:      Open file handle
     97  *
     98  * DESCRIPTION: Open a text output file for acpidump. Checks if file already
     99  *              exists.
    100  *
    101  ******************************************************************************/
    102 
    103 int
    104 ApOpenOutputFile (
    105     char                    *Pathname)
    106 {
    107     ACPI_FILE               File;
    108 
    109 
    110     /* If file exists, prompt for overwrite */
    111 
    112     if (ApIsExistingFile (Pathname) != 0)
    113     {
    114         return (-1);
    115     }
    116 
    117     /* Point stdout to the file */
    118 
    119     File = AcpiOsOpenFile (Pathname, ACPI_FILE_WRITING);
    120     if (!File)
    121     {
    122         AcpiLogError ("Could not open output file: %s\n", Pathname);
    123         return (-1);
    124     }
    125 
    126     /* Save the file and path */
    127 
    128     Gbl_OutputFile = File;
    129     Gbl_OutputFilename = Pathname;
    130     return (0);
    131 }
    132 
    133 
    134 /******************************************************************************
    135  *
    136  * FUNCTION:    ApWriteToBinaryFile
    137  *
    138  * PARAMETERS:  Table               - ACPI table to be written
    139  *              Instance            - ACPI table instance no. to be written
    140  *
    141  * RETURN:      Status
    142  *
    143  * DESCRIPTION: Write an ACPI table to a binary file. Builds the output
    144  *              filename from the table signature.
    145  *
    146  ******************************************************************************/
    147 
    148 int
    149 ApWriteToBinaryFile (
    150     ACPI_TABLE_HEADER       *Table,
    151     UINT32                  Instance)
    152 {
    153     char                    Filename[ACPI_NAME_SIZE + 16];
    154     char                    InstanceStr [16];
    155     ACPI_FILE               File;
    156     size_t                  Actual;
    157     UINT32                  TableLength;
    158 
    159 
    160     /* Obtain table length */
    161 
    162     TableLength = ApGetTableLength (Table);
    163 
    164     /* Construct lower-case filename from the table local signature */
    165 
    166     if (ACPI_VALIDATE_RSDP_SIG (Table->Signature))
    167     {
    168         ACPI_MOVE_NAME (Filename, ACPI_RSDP_NAME);
    169     }
    170     else
    171     {
    172         ACPI_MOVE_NAME (Filename, Table->Signature);
    173     }
    174 
    175     Filename[0] = (char) tolower ((int) Filename[0]);
    176     Filename[1] = (char) tolower ((int) Filename[1]);
    177     Filename[2] = (char) tolower ((int) Filename[2]);
    178     Filename[3] = (char) tolower ((int) Filename[3]);
    179     Filename[ACPI_NAME_SIZE] = 0;
    180 
    181     /* Handle multiple SSDTs - create different filenames for each */
    182 
    183     if (Instance > 0)
    184     {
    185         AcpiUtSnprintf (InstanceStr, sizeof (InstanceStr), "%u", Instance);
    186         strcat (Filename, InstanceStr);
    187     }
    188 
    189     strcat (Filename, FILE_SUFFIX_BINARY_TABLE);
    190 
    191     if (Gbl_VerboseMode)
    192     {
    193         AcpiLogError (
    194             "Writing [%4.4s] to binary file: %s 0x%X (%u) bytes\n",
    195             Table->Signature, Filename, Table->Length, Table->Length);
    196     }
    197 
    198     /* Open the file and dump the entire table in binary mode */
    199 
    200     File = AcpiOsOpenFile (Filename,
    201         ACPI_FILE_WRITING | ACPI_FILE_BINARY);
    202     if (!File)
    203     {
    204         AcpiLogError ("Could not open output file: %s\n", Filename);
    205         return (-1);
    206     }
    207 
    208     Actual = AcpiOsWriteFile (File, Table, 1, TableLength);
    209     if (Actual != TableLength)
    210     {
    211         AcpiLogError ("Error writing binary output file: %s\n", Filename);
    212         AcpiOsCloseFile (File);
    213         return (-1);
    214     }
    215 
    216     AcpiOsCloseFile (File);
    217     return (0);
    218 }
    219 
    220 
    221 /******************************************************************************
    222  *
    223  * FUNCTION:    ApGetTableFromFile
    224  *
    225  * PARAMETERS:  Pathname            - File containing the binary ACPI table
    226  *              OutFileSize         - Where the file size is returned
    227  *
    228  * RETURN:      Buffer containing the ACPI table. NULL on error.
    229  *
    230  * DESCRIPTION: Open a file and read it entirely into a new buffer
    231  *
    232  ******************************************************************************/
    233 
    234 ACPI_TABLE_HEADER *
    235 ApGetTableFromFile (
    236     char                    *Pathname,
    237     UINT32                  *OutFileSize)
    238 {
    239     ACPI_TABLE_HEADER       *Buffer = NULL;
    240     ACPI_FILE               File;
    241     UINT32                  FileSize;
    242     size_t                  Actual;
    243 
    244 
    245     /* Must use binary mode */
    246 
    247     File = AcpiOsOpenFile (Pathname, ACPI_FILE_READING | ACPI_FILE_BINARY);
    248     if (!File)
    249     {
    250         AcpiLogError ("Could not open input file: %s\n", Pathname);
    251         return (NULL);
    252     }
    253 
    254     /* Need file size to allocate a buffer */
    255 
    256     FileSize = CmGetFileSize (File);
    257     if (FileSize == ACPI_UINT32_MAX)
    258     {
    259         AcpiLogError (
    260             "Could not get input file size: %s\n", Pathname);
    261         goto Cleanup;
    262     }
    263 
    264     /* Allocate a buffer for the entire file */
    265 
    266     Buffer = ACPI_ALLOCATE_ZEROED (FileSize);
    267     if (!Buffer)
    268     {
    269         AcpiLogError (
    270             "Could not allocate file buffer of size: %u\n", FileSize);
    271         goto Cleanup;
    272     }
    273 
    274     /* Read the entire file */
    275 
    276     Actual = AcpiOsReadFile (File, Buffer, 1, FileSize);
    277     if (Actual != FileSize)
    278     {
    279         AcpiLogError (
    280             "Could not read input file: %s\n", Pathname);
    281         ACPI_FREE (Buffer);
    282         Buffer = NULL;
    283         goto Cleanup;
    284     }
    285 
    286     *OutFileSize = FileSize;
    287 
    288 Cleanup:
    289     AcpiOsCloseFile (File);
    290     return (Buffer);
    291 }
    292