1 /****************************************************************************** 2 * 3 * Module Name: apfiles - File-related functions for acpidump utility 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2013, 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 /****************************************************************************** 49 * 50 * FUNCTION: ApOpenOutputFile 51 * 52 * PARAMETERS: Pathname - Output filename 53 * 54 * RETURN: Open file handle 55 * 56 * DESCRIPTION: Open a text output file for acpidump. Checks if file already 57 * exists. 58 * 59 ******************************************************************************/ 60 61 int 62 ApOpenOutputFile ( 63 char *Pathname) 64 { 65 struct stat StatInfo; 66 FILE *File; 67 68 69 /* If file exists, prompt for overwrite */ 70 71 if (!stat (Pathname, &StatInfo)) 72 { 73 fprintf (stderr, "Target path already exists, overwrite? [y|n] "); 74 75 if (getchar () != 'y') 76 { 77 return (-1); 78 } 79 } 80 81 /* Point stdout to the file */ 82 83 File = freopen (Pathname, "w", stdout); 84 if (!File) 85 { 86 perror ("Could not open output file"); 87 return (-1); 88 } 89 90 /* Save the file and path */ 91 92 Gbl_OutputFile = File; 93 Gbl_OutputFilename = Pathname; 94 return (0); 95 } 96 97 98 /****************************************************************************** 99 * 100 * FUNCTION: ApWriteToBinaryFile 101 * 102 * PARAMETERS: Table - ACPI table to be written 103 * Instance - ACPI table instance no. to be written 104 * 105 * RETURN: Status 106 * 107 * DESCRIPTION: Write an ACPI table to a binary file. Builds the output 108 * filename from the table signature. 109 * 110 ******************************************************************************/ 111 112 int 113 ApWriteToBinaryFile ( 114 ACPI_TABLE_HEADER *Table, 115 UINT32 Instance) 116 { 117 char Filename[ACPI_NAME_SIZE + 16]; 118 char InstanceStr [16]; 119 FILE *File; 120 size_t Actual; 121 UINT32 TableLength; 122 123 124 /* Obtain table length */ 125 126 TableLength = ApGetTableLength (Table); 127 128 /* Construct lower-case filename from the table local signature */ 129 130 if (ACPI_VALIDATE_RSDP_SIG (Table->Signature)) 131 { 132 ACPI_MOVE_NAME (Filename, AP_DUMP_SIG_RSDP); 133 } 134 else 135 { 136 ACPI_MOVE_NAME (Filename, Table->Signature); 137 } 138 Filename[0] = (char) ACPI_TOLOWER (Filename[0]); 139 Filename[1] = (char) ACPI_TOLOWER (Filename[1]); 140 Filename[2] = (char) ACPI_TOLOWER (Filename[2]); 141 Filename[3] = (char) ACPI_TOLOWER (Filename[3]); 142 Filename[ACPI_NAME_SIZE] = 0; 143 144 /* Handle multiple SSDTs - create different filenames for each */ 145 146 if (Instance > 0) 147 { 148 sprintf (InstanceStr, "%u", Instance); 149 strcat (Filename, InstanceStr); 150 } 151 152 strcat (Filename, ACPI_TABLE_FILE_SUFFIX); 153 154 if (Gbl_VerboseMode) 155 { 156 fprintf (stderr, 157 "Writing [%4.4s] to binary file: %s 0x%X (%u) bytes\n", 158 Table->Signature, Filename, Table->Length, Table->Length); 159 } 160 161 /* Open the file and dump the entire table in binary mode */ 162 163 File = fopen (Filename, "wb"); 164 if (!File) 165 { 166 perror ("Could not open output file"); 167 return (-1); 168 } 169 170 Actual = fwrite (Table, 1, TableLength, File); 171 if (Actual != TableLength) 172 { 173 perror ("Error writing binary output file"); 174 fclose (File); 175 return (-1); 176 } 177 178 fclose (File); 179 return (0); 180 } 181 182 183 /****************************************************************************** 184 * 185 * FUNCTION: ApGetTableFromFile 186 * 187 * PARAMETERS: Pathname - File containing the binary ACPI table 188 * OutFileSize - Where the file size is returned 189 * 190 * RETURN: Buffer containing the ACPI table. NULL on error. 191 * 192 * DESCRIPTION: Open a file and read it entirely into a new buffer 193 * 194 ******************************************************************************/ 195 196 ACPI_TABLE_HEADER * 197 ApGetTableFromFile ( 198 char *Pathname, 199 UINT32 *OutFileSize) 200 { 201 ACPI_TABLE_HEADER *Buffer = NULL; 202 FILE *File; 203 UINT32 FileSize; 204 size_t Actual; 205 206 207 /* Must use binary mode */ 208 209 File = fopen (Pathname, "rb"); 210 if (!File) 211 { 212 perror ("Could not open input file"); 213 return (NULL); 214 } 215 216 /* Need file size to allocate a buffer */ 217 218 FileSize = ApGetFileSize (File); 219 if (!FileSize) 220 { 221 fprintf (stderr, 222 "Could not get input file size: %s\n", Pathname); 223 goto Cleanup; 224 } 225 226 /* Allocate a buffer for the entire file */ 227 228 Buffer = calloc (1, FileSize); 229 if (!Buffer) 230 { 231 fprintf (stderr, 232 "Could not allocate file buffer of size: %u\n", FileSize); 233 goto Cleanup; 234 } 235 236 /* Read the entire file */ 237 238 Actual = fread (Buffer, 1, FileSize, File); 239 if (Actual != FileSize) 240 { 241 fprintf (stderr, 242 "Could not read input file: %s\n", Pathname); 243 free (Buffer); 244 Buffer = NULL; 245 goto Cleanup; 246 } 247 248 *OutFileSize = FileSize; 249 250 Cleanup: 251 fclose (File); 252 return (Buffer); 253 } 254 255 256 /****************************************************************************** 257 * 258 * FUNCTION: ApGetFileSize 259 * 260 * PARAMETERS: File - Open file descriptor 261 * 262 * RETURN: File size in bytes 263 * 264 * DESCRIPTION: Get the size of an open file 265 * 266 ******************************************************************************/ 267 268 UINT32 269 ApGetFileSize ( 270 FILE *File) 271 { 272 UINT32 FileSize; 273 long Offset; 274 275 276 Offset = ftell (File); 277 if (fseek (File, 0, SEEK_END)) 278 { 279 return (0); 280 } 281 282 /* Get size and restore file pointer */ 283 284 FileSize = (UINT32) ftell (File); 285 if (fseek (File, Offset, SEEK_SET)) 286 { 287 return (0); 288 } 289 290 return (FileSize); 291 }