xref: /reactos/sdk/tools/cabman/CCFDATAStorage.cxx (revision d7fd62d4)
1 /*
2  * PROJECT:     ReactOS cabinet manager
3  * LICENSE:     GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4  * PURPOSE:     CCFDATAStorage class implementation
5  * COPYRIGHT:   Copyright 2017 Casper S. Hornstrup (chorns@users.sourceforge.net)
6  *              Copyright 2017 Colin Finck <mail@colinfinck.de>
7  *              Copyright 2018 Dmitry Bagdanov <dimbo_job@mail.ru>
8  */
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <sys/stat.h>
13 #include <sys/types.h>
14 
15 #if !defined(_WIN32)
16 #include <dirent.h>
17 #endif
18 
19 #include "CCFDATAStorage.h"
20 #include "raw.h"
21 #include "mszip.h"
22 
23 #if !defined(CAB_READ_ONLY)
24 
25  /**
26  * @name CCFDATAStorage class
27  * @implemented
28  *
29  * Default constructor
30  */
31 CCFDATAStorage::CCFDATAStorage()
32 {
33     FileHandle = NULL;
34 }
35 
36 /**
37 * @name CCFDATAStorage class
38 * @implemented
39 *
40 * Default destructor
41 */
42 CCFDATAStorage::~CCFDATAStorage()
43 {
44     ASSERT(FileHandle == NULL);
45 }
46 
47 /**
48 * @name CCFDATAStorage class
49 * @implemented
50 *
51 * Creates the file
52 *
53 * @return
54 * Status of operation
55 */
56 ULONG CCFDATAStorage::Create()
57 {
58 #if defined(_WIN32)
59     char TmpName[PATH_MAX];
60     char *pName;
61     int length;
62 
63     if (tmpnam(TmpName) == NULL)
64         return CAB_STATUS_CANNOT_CREATE;
65 
66     /* Append 'tmp' if the file name ends with a dot */
67     length = strlen(TmpName);
68     if (length > 0 && TmpName[length - 1] == '.')
69         strcat(TmpName, "tmp");
70 
71     /* Skip a leading slash or backslash */
72     pName = TmpName;
73     if (*pName == '/' || *pName == '\\')
74         pName++;
75 
76     strcpy(FullName, pName);
77 
78     FileHandle = fopen(FullName, "w+b");
79     if (FileHandle == NULL)
80         return CAB_STATUS_CANNOT_CREATE;
81 #else
82     if ((FileHandle = tmpfile()) == NULL)
83         return CAB_STATUS_CANNOT_CREATE;
84 #endif
85     return CAB_STATUS_SUCCESS;
86 }
87 
88 /**
89 * @name CCFDATAStorage class
90 * @implemented
91 *
92 * Destroys the file
93 *
94 * @return
95 * Status of operation
96 */
97 ULONG CCFDATAStorage::Destroy()
98 {
99     ASSERT(FileHandle != NULL);
100 
101     fclose(FileHandle);
102 
103     FileHandle = NULL;
104 
105 #if defined(_WIN32)
106     remove(FullName);
107 #endif
108 
109     return CAB_STATUS_SUCCESS;
110 }
111 
112 /**
113 * @name CCFDATAStorage class
114 * @implemented
115 *
116 * Truncate the scratch file to zero bytes
117 *
118 * @return
119 * Status of operation
120 */
121 ULONG CCFDATAStorage::Truncate()
122 {
123     fclose(FileHandle);
124 #if defined(_WIN32)
125     FileHandle = fopen(FullName, "w+b");
126 #else
127     FileHandle = tmpfile();
128 #endif
129     if (FileHandle == NULL)
130     {
131         DPRINT(MID_TRACE, ("ERROR '%i'.\n", errno));
132         return CAB_STATUS_FAILURE;
133     }
134 
135     return CAB_STATUS_SUCCESS;
136 }
137 
138 /**
139 * @name CCFDATAStorage class
140 * @implemented
141 *
142 * Returns current position in file
143 *
144 * @return
145 * Current position
146 */
147 ULONG CCFDATAStorage::Position()
148 {
149     return (ULONG)ftell(FileHandle);
150 }
151 
152 
153 /**
154 * @name CCFDATAStorage class
155 * @implemented
156 *
157 * Seeks to an absolute position
158 *
159 * @param Position
160 * Absolute position to seek to
161 *
162 * @return
163 * Status of operation
164 */
165 ULONG CCFDATAStorage::Seek(LONG Position)
166 {
167     if (fseek(FileHandle, (off_t)Position, SEEK_SET) != 0)
168         return CAB_STATUS_FAILURE;
169     else
170         return CAB_STATUS_SUCCESS;
171 }
172 
173 
174 /**
175 * @name CCFDATAStorage class
176 * @implemented
177 *
178 * Reads a CFDATA block from the file
179 *
180 * @param Data
181 * Pointer to CFDATA block for the buffer
182 *
183 * @param Buffer
184 * Pointer to buffer to store data read
185 *
186 * @param BytesRead
187 * Pointer to buffer to write number of bytes read
188 *
189 * @return
190 * Status of operation
191 */
192 ULONG CCFDATAStorage::ReadBlock(PCFDATA Data, void* Buffer, PULONG BytesRead)
193 {
194     *BytesRead = fread(Buffer, 1, Data->CompSize, FileHandle);
195     if (*BytesRead != Data->CompSize)
196         return CAB_STATUS_CANNOT_READ;
197 
198     return CAB_STATUS_SUCCESS;
199 }
200 
201 
202 /**
203 * @name CCFDATAStorage class
204 * @implemented
205 *
206 * Writes a CFDATA block to the file
207 *
208 * @param Data
209 * Pointer to CFDATA block for the buffer
210 *
211 * @param Buffer
212 * Pointer to buffer with data to write
213 *
214 * @param BytesWritten
215 * Pointer to buffer to write number of bytes written
216 *
217 * @return
218 * Status of operation
219 */
220 ULONG CCFDATAStorage::WriteBlock(PCFDATA Data, void* Buffer, PULONG BytesWritten)
221 {
222     *BytesWritten = fwrite(Buffer, 1, Data->CompSize, FileHandle);
223     if (*BytesWritten != Data->CompSize)
224         return CAB_STATUS_CANNOT_WRITE;
225 
226     return CAB_STATUS_SUCCESS;
227 }
228 
229 
230 #endif /* CAB_READ_ONLY */
231