xref: /reactos/sdk/tools/cabman/CCFDATAStorage.cxx (revision 58588b76)
1 /*
2  * PROJECT:     ReactOS cabinet manager
3  * LICENSE:     GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4  * PURPOSE:     CCFDATAStorage class implementation for Linux/Unix
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 "cabinet.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 ((FileHandle = tmpfile()) == NULL)
59     {
60         /* Workaround for breakage on some Windows system */
61         FileHandle = fopen(tmpnam(NULL) + 1, "wb");
62         if (FileHandle == NULL)
63             return CAB_STATUS_CANNOT_CREATE;
64     }
65 
66     return CAB_STATUS_SUCCESS;
67 }
68 
69 /**
70 * @name CCFDATAStorage class
71 * @implemented
72 *
73 * Destroys the file
74 *
75 * @return
76 * Status of operation
77 */
78 ULONG CCFDATAStorage::Destroy()
79 {
80     ASSERT(FileHandle != NULL);
81 
82     fclose(FileHandle);
83 
84     FileHandle = NULL;
85 
86     return CAB_STATUS_SUCCESS;
87 }
88 
89 /**
90 * @name CCFDATAStorage class
91 * @implemented
92 *
93 * Truncate the scratch file to zero bytes
94 *
95 * @return
96 * Status of operation
97 */
98 ULONG CCFDATAStorage::Truncate()
99 {
100     fclose(FileHandle);
101     FileHandle = tmpfile();
102     if (FileHandle == NULL)
103     {
104         DPRINT(MID_TRACE, ("ERROR '%i'.\n", errno));
105         return CAB_STATUS_FAILURE;
106     }
107 
108     return CAB_STATUS_SUCCESS;
109 }
110 
111 /**
112 * @name CCFDATAStorage class
113 * @implemented
114 *
115 * Returns current position in file
116 *
117 * @return
118 * Current position
119 */
120 ULONG CCFDATAStorage::Position()
121 {
122     return (ULONG)ftell(FileHandle);
123 }
124 
125 
126 /**
127 * @name CCFDATAStorage class
128 * @implemented
129 *
130 * Seeks to an absolute position
131 *
132 * @param Position
133 * Absolute position to seek to
134 *
135 * @return
136 * Status of operation
137 */
138 ULONG CCFDATAStorage::Seek(LONG Position)
139 {
140     if (fseek(FileHandle, (off_t)Position, SEEK_SET) != 0)
141         return CAB_STATUS_FAILURE;
142     else
143         return CAB_STATUS_SUCCESS;
144 }
145 
146 
147 /**
148 * @name CCFDATAStorage class
149 * @implemented
150 *
151 * Reads a CFDATA block from the file
152 *
153 * @param Data
154 * Pointer to CFDATA block for the buffer
155 *
156 * @param Buffer
157 * Pointer to buffer to store data read
158 *
159 * @param BytesRead
160 * Pointer to buffer to write number of bytes read
161 *
162 * @return
163 * Status of operation
164 */
165 ULONG CCFDATAStorage::ReadBlock(PCFDATA Data, void* Buffer, PULONG BytesRead)
166 {
167     *BytesRead = fread(Buffer, 1, Data->CompSize, FileHandle);
168     if (*BytesRead != Data->CompSize)
169         return CAB_STATUS_CANNOT_READ;
170 
171     return CAB_STATUS_SUCCESS;
172 }
173 
174 
175 /**
176 * @name CCFDATAStorage class
177 * @implemented
178 *
179 * Writes a CFDATA block to the file
180 *
181 * @param Data
182 * Pointer to CFDATA block for the buffer
183 *
184 * @param Buffer
185 * Pointer to buffer with data to write
186 *
187 * @param BytesWritten
188 * Pointer to buffer to write number of bytes written
189 *
190 * @return
191 * Status of operation
192 */
193 ULONG CCFDATAStorage::WriteBlock(PCFDATA Data, void* Buffer, PULONG BytesWritten)
194 {
195     *BytesWritten = fwrite(Buffer, 1, Data->CompSize, FileHandle);
196     if (*BytesWritten != Data->CompSize)
197         return CAB_STATUS_CANNOT_WRITE;
198 
199     return CAB_STATUS_SUCCESS;
200 }
201 
202 
203 #endif /* CAB_READ_ONLY */
204