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