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