Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
6595 serge 1
/*******************************************************************************
2
 *
3
 * Module Name: utfileio - simple file I/O routines
4
 *
5
 ******************************************************************************/
6
 
7
/*
8
 * Copyright (C) 2000 - 2015, 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 
45
#include "accommon.h"
46
#include "actables.h"
47
#include "acapps.h"
48
#include "errno.h"
49
 
50
#ifdef ACPI_ASL_COMPILER
51
#include "aslcompiler.h"
52
#endif
53
 
54
#define _COMPONENT          ACPI_CA_DEBUGGER
55
ACPI_MODULE_NAME("utfileio")
56
 
57
#ifdef ACPI_APPLICATION
58
/* Local prototypes */
59
static acpi_status
60
acpi_ut_check_text_mode_corruption(u8 *table,
61
				   u32 table_length, u32 file_length);
62
 
63
static acpi_status
64
acpi_ut_read_table(FILE * fp,
65
		   struct acpi_table_header **table, u32 *table_length);
66
 
67
/*******************************************************************************
68
 *
69
 * FUNCTION:    acpi_ut_check_text_mode_corruption
70
 *
71
 * PARAMETERS:  table           - Table buffer
72
 *              table_length    - Length of table from the table header
73
 *              file_length     - Length of the file that contains the table
74
 *
75
 * RETURN:      Status
76
 *
77
 * DESCRIPTION: Check table for text mode file corruption where all linefeed
78
 *              characters (LF) have been replaced by carriage return linefeed
79
 *              pairs (CR/LF).
80
 *
81
 ******************************************************************************/
82
 
83
static acpi_status
84
acpi_ut_check_text_mode_corruption(u8 *table, u32 table_length, u32 file_length)
85
{
86
	u32 i;
87
	u32 pairs = 0;
88
 
89
	if (table_length != file_length) {
90
		ACPI_WARNING((AE_INFO,
91
			      "File length (0x%X) is not the same as the table length (0x%X)",
92
			      file_length, table_length));
93
	}
94
 
95
	/* Scan entire table to determine if each LF has been prefixed with a CR */
96
 
97
	for (i = 1; i < file_length; i++) {
98
		if (table[i] == 0x0A) {
99
			if (table[i - 1] != 0x0D) {
100
 
101
				/* The LF does not have a preceding CR, table not corrupted */
102
 
103
				return (AE_OK);
104
			} else {
105
				/* Found a CR/LF pair */
106
 
107
				pairs++;
108
			}
109
			i++;
110
		}
111
	}
112
 
113
	if (!pairs) {
114
		return (AE_OK);
115
	}
116
 
117
	/*
118
	 * Entire table scanned, each CR is part of a CR/LF pair --
119
	 * meaning that the table was treated as a text file somewhere.
120
	 *
121
	 * NOTE: We can't "fix" the table, because any existing CR/LF pairs in the
122
	 * original table are left untouched by the text conversion process --
123
	 * meaning that we cannot simply replace CR/LF pairs with LFs.
124
	 */
125
	acpi_os_printf("Table has been corrupted by text mode conversion\n");
126
	acpi_os_printf("All LFs (%u) were changed to CR/LF pairs\n", pairs);
127
	acpi_os_printf("Table cannot be repaired!\n");
128
	return (AE_BAD_VALUE);
129
}
130
 
131
/*******************************************************************************
132
 *
133
 * FUNCTION:    acpi_ut_read_table
134
 *
135
 * PARAMETERS:  fp              - File that contains table
136
 *              table           - Return value, buffer with table
137
 *              table_length    - Return value, length of table
138
 *
139
 * RETURN:      Status
140
 *
141
 * DESCRIPTION: Load the DSDT from the file pointer
142
 *
143
 ******************************************************************************/
144
 
145
static acpi_status
146
acpi_ut_read_table(FILE * fp,
147
		   struct acpi_table_header **table, u32 *table_length)
148
{
149
	struct acpi_table_header table_header;
150
	u32 actual;
151
	acpi_status status;
152
	u32 file_size;
153
	u8 standard_header = TRUE;
154
	s32 count;
155
 
156
	/* Get the file size */
157
 
158
	file_size = cm_get_file_size(fp);
159
	if (file_size == ACPI_UINT32_MAX) {
160
		return (AE_ERROR);
161
	}
162
 
163
	if (file_size < 4) {
164
		return (AE_BAD_HEADER);
165
	}
166
 
167
	/* Read the signature */
168
 
169
	fseek(fp, 0, SEEK_SET);
170
 
171
	count = fread(&table_header, 1, sizeof(struct acpi_table_header), fp);
172
	if (count != sizeof(struct acpi_table_header)) {
173
		acpi_os_printf("Could not read the table header\n");
174
		return (AE_BAD_HEADER);
175
	}
176
 
177
	/* The RSDP table does not have standard ACPI header */
178
 
179
	if (ACPI_VALIDATE_RSDP_SIG(table_header.signature)) {
180
		*table_length = file_size;
181
		standard_header = FALSE;
182
	} else {
183
 
184
#if 0
185
		/* Validate the table header/length */
186
 
187
		status = acpi_tb_validate_table_header(&table_header);
188
		if (ACPI_FAILURE(status)) {
189
			acpi_os_printf("Table header is invalid!\n");
190
			return (status);
191
		}
192
#endif
193
 
194
		/* File size must be at least as long as the Header-specified length */
195
 
196
		if (table_header.length > file_size) {
197
			acpi_os_printf
198
			    ("TableHeader length [0x%X] greater than the input file size [0x%X]\n",
199
			     table_header.length, file_size);
200
 
201
#ifdef ACPI_ASL_COMPILER
202
			acpi_os_printf("File is corrupt or is ASCII text -- "
203
				       "it must be a binary file\n");
204
#endif
205
			return (AE_BAD_HEADER);
206
		}
207
#ifdef ACPI_OBSOLETE_CODE
208
		/* We only support a limited number of table types */
209
 
210
		if (!ACPI_COMPARE_NAME
211
		    ((char *)table_header.signature, ACPI_SIG_DSDT)
212
		    && !ACPI_COMPARE_NAME((char *)table_header.signature,
213
					  ACPI_SIG_PSDT)
214
		    && !ACPI_COMPARE_NAME((char *)table_header.signature,
215
					  ACPI_SIG_SSDT)) {
216
			acpi_os_printf
217
			    ("Table signature [%4.4s] is invalid or not supported\n",
218
			     (char *)table_header.signature);
219
			ACPI_DUMP_BUFFER(&table_header,
220
					 sizeof(struct acpi_table_header));
221
			return (AE_ERROR);
222
		}
223
#endif
224
 
225
		*table_length = table_header.length;
226
	}
227
 
228
	/* Allocate a buffer for the table */
229
 
230
	*table = acpi_os_allocate((size_t) file_size);
231
	if (!*table) {
232
		acpi_os_printf
233
		    ("Could not allocate memory for ACPI table %4.4s (size=0x%X)\n",
234
		     table_header.signature, *table_length);
235
		return (AE_NO_MEMORY);
236
	}
237
 
238
	/* Get the rest of the table */
239
 
240
	fseek(fp, 0, SEEK_SET);
241
	actual = fread(*table, 1, (size_t) file_size, fp);
242
	if (actual == file_size) {
243
		if (standard_header) {
244
 
245
			/* Now validate the checksum */
246
 
247
			status = acpi_tb_verify_checksum((void *)*table,
248
							 ACPI_CAST_PTR(struct
249
								       acpi_table_header,
250
								       *table)->
251
							 length);
252
 
253
			if (status == AE_BAD_CHECKSUM) {
254
				status =
255
				    acpi_ut_check_text_mode_corruption((u8 *)
256
								       *table,
257
								       file_size,
258
								       (*table)->
259
								       length);
260
				return (status);
261
			}
262
		}
263
		return (AE_OK);
264
	}
265
 
266
	if (actual > 0) {
267
		acpi_os_printf("Warning - reading table, asked for %X got %X\n",
268
			       file_size, actual);
269
		return (AE_OK);
270
	}
271
 
272
	acpi_os_printf("Error - could not read the table file\n");
273
	acpi_os_free(*table);
274
	*table = NULL;
275
	*table_length = 0;
276
	return (AE_ERROR);
277
}
278
 
279
/*******************************************************************************
280
 *
281
 * FUNCTION:    acpi_ut_read_table_from_file
282
 *
283
 * PARAMETERS:  filename         - File where table is located
284
 *              table            - Where a pointer to the table is returned
285
 *
286
 * RETURN:      Status
287
 *
288
 * DESCRIPTION: Get an ACPI table from a file
289
 *
290
 ******************************************************************************/
291
 
292
acpi_status
293
acpi_ut_read_table_from_file(char *filename, struct acpi_table_header ** table)
294
{
295
	FILE *file;
296
	u32 file_size;
297
	u32 table_length;
298
	acpi_status status = AE_ERROR;
299
 
300
	/* Open the file, get current size */
301
 
302
	file = fopen(filename, "rb");
303
	if (!file) {
304
		perror("Could not open input file");
305
 
306
		if (errno == ENOENT) {
307
			return (AE_NOT_EXIST);
308
		}
309
 
310
		return (status);
311
	}
312
 
313
	file_size = cm_get_file_size(file);
314
	if (file_size == ACPI_UINT32_MAX) {
315
		goto exit;
316
	}
317
 
318
	/* Get the entire file */
319
 
320
	fprintf(stderr,
321
		"Reading ACPI table from file %12s - Length %.8u (0x%06X)\n",
322
		filename, file_size, file_size);
323
 
324
	status = acpi_ut_read_table(file, table, &table_length);
325
	if (ACPI_FAILURE(status)) {
326
		acpi_os_printf("Could not get table from the file\n");
327
	}
328
 
329
exit:
330
	fclose(file);
331
	return (status);
332
}
333
 
334
#endif