]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/C/LzmaCompress/Sdk/C/7zFile.c
BaseTools/LzmaCompress: Fix possible uninitialized variable
[mirror_edk2.git] / BaseTools / Source / C / LzmaCompress / Sdk / C / 7zFile.c
CommitLineData
30fdf114 1/* 7zFile.c -- File IO\r
c4ab09ef
LG
22009-11-24 : Igor Pavlov : Public domain */\r
3\r
4#include "Precomp.h"\r
30fdf114
LG
5\r
6#include "7zFile.h"\r
7\r
8#ifndef USE_WINDOWS_FILE\r
9\r
c4ab09ef 10#ifndef UNDER_CE\r
30fdf114 11#include <errno.h>\r
30fdf114
LG
12#endif\r
13\r
c4ab09ef 14#else\r
30fdf114
LG
15\r
16/*\r
17 ReadFile and WriteFile functions in Windows have BUG:\r
18 If you Read or Write 64MB or more (probably min_failure_size = 64MB - 32KB + 1)\r
19 from/to Network file, it returns ERROR_NO_SYSTEM_RESOURCES\r
20 (Insufficient system resources exist to complete the requested service).\r
21 Probably in some version of Windows there are problems with other sizes:\r
22 for 32 MB (maybe also for 16 MB).\r
23 And message can be "Network connection was lost"\r
24*/\r
25\r
26#define kChunkSizeMax (1 << 22)\r
27\r
28#endif\r
29\r
30void File_Construct(CSzFile *p)\r
31{\r
32 #ifdef USE_WINDOWS_FILE\r
33 p->handle = INVALID_HANDLE_VALUE;\r
34 #else\r
35 p->file = NULL;\r
36 #endif\r
37}\r
38\r
c4ab09ef 39#if !defined(UNDER_CE) || !defined(USE_WINDOWS_FILE)\r
30fdf114
LG
40static WRes File_Open(CSzFile *p, const char *name, int writeMode)\r
41{\r
42 #ifdef USE_WINDOWS_FILE\r
43 p->handle = CreateFileA(name,\r
44 writeMode ? GENERIC_WRITE : GENERIC_READ,\r
45 FILE_SHARE_READ, NULL,\r
46 writeMode ? CREATE_ALWAYS : OPEN_EXISTING,\r
47 FILE_ATTRIBUTE_NORMAL, NULL);\r
48 return (p->handle != INVALID_HANDLE_VALUE) ? 0 : GetLastError();\r
49 #else\r
50 p->file = fopen(name, writeMode ? "wb+" : "rb");\r
c4ab09ef
LG
51 return (p->file != 0) ? 0 :\r
52 #ifdef UNDER_CE\r
53 2; /* ENOENT */\r
54 #else\r
55 errno;\r
56 #endif\r
30fdf114
LG
57 #endif\r
58}\r
59\r
60WRes InFile_Open(CSzFile *p, const char *name) { return File_Open(p, name, 0); }\r
61WRes OutFile_Open(CSzFile *p, const char *name) { return File_Open(p, name, 1); }\r
c4ab09ef
LG
62#endif\r
63\r
64#ifdef USE_WINDOWS_FILE\r
65static WRes File_OpenW(CSzFile *p, const WCHAR *name, int writeMode)\r
66{\r
67 p->handle = CreateFileW(name,\r
68 writeMode ? GENERIC_WRITE : GENERIC_READ,\r
69 FILE_SHARE_READ, NULL,\r
70 writeMode ? CREATE_ALWAYS : OPEN_EXISTING,\r
71 FILE_ATTRIBUTE_NORMAL, NULL);\r
72 return (p->handle != INVALID_HANDLE_VALUE) ? 0 : GetLastError();\r
73}\r
74WRes InFile_OpenW(CSzFile *p, const WCHAR *name) { return File_OpenW(p, name, 0); }\r
75WRes OutFile_OpenW(CSzFile *p, const WCHAR *name) { return File_OpenW(p, name, 1); }\r
76#endif\r
30fdf114
LG
77\r
78WRes File_Close(CSzFile *p)\r
79{\r
80 #ifdef USE_WINDOWS_FILE\r
81 if (p->handle != INVALID_HANDLE_VALUE)\r
82 {\r
83 if (!CloseHandle(p->handle))\r
84 return GetLastError();\r
85 p->handle = INVALID_HANDLE_VALUE;\r
86 }\r
87 #else\r
88 if (p->file != NULL)\r
89 {\r
90 int res = fclose(p->file);\r
91 if (res != 0)\r
92 return res;\r
93 p->file = NULL;\r
94 }\r
95 #endif\r
96 return 0;\r
97}\r
98\r
99WRes File_Read(CSzFile *p, void *data, size_t *size)\r
100{\r
101 size_t originalSize = *size;\r
102 if (originalSize == 0)\r
103 return 0;\r
104\r
105 #ifdef USE_WINDOWS_FILE\r
106\r
107 *size = 0;\r
108 do\r
109 {\r
110 DWORD curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : (DWORD)originalSize;\r
111 DWORD processed = 0;\r
112 BOOL res = ReadFile(p->handle, data, curSize, &processed, NULL);\r
113 data = (void *)((Byte *)data + processed);\r
114 originalSize -= processed;\r
115 *size += processed;\r
116 if (!res)\r
117 return GetLastError();\r
118 if (processed == 0)\r
119 break;\r
120 }\r
121 while (originalSize > 0);\r
122 return 0;\r
123\r
124 #else\r
125 \r
126 *size = fread(data, 1, originalSize, p->file);\r
127 if (*size == originalSize)\r
128 return 0;\r
129 return ferror(p->file);\r
130 \r
131 #endif\r
132}\r
133\r
134WRes File_Write(CSzFile *p, const void *data, size_t *size)\r
135{\r
136 size_t originalSize = *size;\r
137 if (originalSize == 0)\r
138 return 0;\r
139 \r
140 #ifdef USE_WINDOWS_FILE\r
141\r
142 *size = 0;\r
143 do\r
144 {\r
145 DWORD curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : (DWORD)originalSize;\r
146 DWORD processed = 0;\r
147 BOOL res = WriteFile(p->handle, data, curSize, &processed, NULL);\r
148 data = (void *)((Byte *)data + processed);\r
149 originalSize -= processed;\r
150 *size += processed;\r
151 if (!res)\r
152 return GetLastError();\r
153 if (processed == 0)\r
154 break;\r
155 }\r
156 while (originalSize > 0);\r
157 return 0;\r
158\r
159 #else\r
160\r
161 *size = fwrite(data, 1, originalSize, p->file);\r
162 if (*size == originalSize)\r
163 return 0;\r
164 return ferror(p->file);\r
165 \r
166 #endif\r
167}\r
168\r
169WRes File_Seek(CSzFile *p, Int64 *pos, ESzSeek origin)\r
170{\r
171 #ifdef USE_WINDOWS_FILE\r
172\r
173 LARGE_INTEGER value;\r
174 DWORD moveMethod;\r
175 value.LowPart = (DWORD)*pos;\r
176 value.HighPart = (LONG)((UInt64)*pos >> 16 >> 16); /* for case when UInt64 is 32-bit only */\r
177 switch (origin)\r
178 {\r
179 case SZ_SEEK_SET: moveMethod = FILE_BEGIN; break;\r
180 case SZ_SEEK_CUR: moveMethod = FILE_CURRENT; break;\r
181 case SZ_SEEK_END: moveMethod = FILE_END; break;\r
182 default: return ERROR_INVALID_PARAMETER;\r
183 }\r
184 value.LowPart = SetFilePointer(p->handle, value.LowPart, &value.HighPart, moveMethod);\r
185 if (value.LowPart == 0xFFFFFFFF)\r
186 {\r
187 WRes res = GetLastError();\r
188 if (res != NO_ERROR)\r
189 return res;\r
190 }\r
191 *pos = ((Int64)value.HighPart << 32) | value.LowPart;\r
192 return 0;\r
193\r
194 #else\r
195 \r
196 int moveMethod;\r
197 int res;\r
198 switch (origin)\r
199 {\r
200 case SZ_SEEK_SET: moveMethod = SEEK_SET; break;\r
201 case SZ_SEEK_CUR: moveMethod = SEEK_CUR; break;\r
202 case SZ_SEEK_END: moveMethod = SEEK_END; break;\r
203 default: return 1;\r
204 }\r
205 res = fseek(p->file, (long)*pos, moveMethod);\r
206 *pos = ftell(p->file);\r
207 return res;\r
208 \r
209 #endif\r
210}\r
211\r
212WRes File_GetLength(CSzFile *p, UInt64 *length)\r
213{\r
214 #ifdef USE_WINDOWS_FILE\r
215 \r
9cdda7ba 216 DWORD sizeHigh = 0;\r
30fdf114
LG
217 DWORD sizeLow = GetFileSize(p->handle, &sizeHigh);\r
218 if (sizeLow == 0xFFFFFFFF)\r
219 {\r
220 DWORD res = GetLastError();\r
221 if (res != NO_ERROR)\r
222 return res;\r
223 }\r
224 *length = (((UInt64)sizeHigh) << 32) + sizeLow;\r
225 return 0;\r
226 \r
227 #else\r
228 \r
229 long pos = ftell(p->file);\r
230 int res = fseek(p->file, 0, SEEK_END);\r
231 *length = ftell(p->file);\r
232 fseek(p->file, pos, SEEK_SET);\r
233 return res;\r
234 \r
235 #endif\r
236}\r
237\r
238\r
239/* ---------- FileSeqInStream ---------- */\r
240\r
241static SRes FileSeqInStream_Read(void *pp, void *buf, size_t *size)\r
242{\r
243 CFileSeqInStream *p = (CFileSeqInStream *)pp;\r
244 return File_Read(&p->file, buf, size) == 0 ? SZ_OK : SZ_ERROR_READ;\r
245}\r
246\r
247void FileSeqInStream_CreateVTable(CFileSeqInStream *p)\r
248{\r
249 p->s.Read = FileSeqInStream_Read;\r
250}\r
251\r
252\r
253/* ---------- FileInStream ---------- */\r
254\r
255static SRes FileInStream_Read(void *pp, void *buf, size_t *size)\r
256{\r
257 CFileInStream *p = (CFileInStream *)pp;\r
258 return (File_Read(&p->file, buf, size) == 0) ? SZ_OK : SZ_ERROR_READ;\r
259}\r
260\r
261static SRes FileInStream_Seek(void *pp, Int64 *pos, ESzSeek origin)\r
262{\r
263 CFileInStream *p = (CFileInStream *)pp;\r
264 return File_Seek(&p->file, pos, origin);\r
265}\r
266\r
267void FileInStream_CreateVTable(CFileInStream *p)\r
268{\r
269 p->s.Read = FileInStream_Read;\r
270 p->s.Seek = FileInStream_Seek;\r
271}\r
272\r
273\r
274/* ---------- FileOutStream ---------- */\r
275\r
276static size_t FileOutStream_Write(void *pp, const void *data, size_t size)\r
277{\r
278 CFileOutStream *p = (CFileOutStream *)pp;\r
279 File_Write(&p->file, data, &size);\r
280 return size;\r
281}\r
282\r
283void FileOutStream_CreateVTable(CFileOutStream *p)\r
284{\r
285 p->s.Write = FileOutStream_Write;\r
286}\r