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