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