"Fossies" - the Fresh Open Source Software Archive

Member "hashcat-6.2.6/deps/LZMA-SDK/C/7zFile.c" (2 Sep 2022, 10461 Bytes) of package /linux/privat/hashcat-6.2.6.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. See also the last Fossies "Diffs" side-by-side code changes report for "7zFile.c": 6.2.1_vs_6.2.2.

    1 /* 7zFile.c -- File IO
    2 2021-04-29 : Igor Pavlov : Public domain */
    3 
    4 #include "Precomp.h"
    5 
    6 #include "7zFile.h"
    7 
    8 #ifndef USE_WINDOWS_FILE
    9 
   10   #include <errno.h>
   11 
   12   #ifndef USE_FOPEN
   13     #include <stdio.h>
   14     #include <fcntl.h>
   15     #ifdef _WIN32
   16       #include <io.h>
   17       typedef int ssize_t;
   18       typedef int off_t;
   19     #else
   20       #include <unistd.h>
   21     #endif
   22   #endif
   23 
   24 #else
   25 
   26 /*
   27    ReadFile and WriteFile functions in Windows have BUG:
   28    If you Read or Write 64MB or more (probably min_failure_size = 64MB - 32KB + 1)
   29    from/to Network file, it returns ERROR_NO_SYSTEM_RESOURCES
   30    (Insufficient system resources exist to complete the requested service).
   31    Probably in some version of Windows there are problems with other sizes:
   32    for 32 MB (maybe also for 16 MB).
   33    And message can be "Network connection was lost"
   34 */
   35 
   36 #endif
   37 
   38 #define kChunkSizeMax (1 << 22)
   39 
   40 void File_Construct(CSzFile *p)
   41 {
   42   #ifdef USE_WINDOWS_FILE
   43   p->handle = INVALID_HANDLE_VALUE;
   44   #elif defined(USE_FOPEN)
   45   p->file = NULL;
   46   #else
   47   p->fd = -1;
   48   #endif
   49 }
   50 
   51 #if !defined(UNDER_CE) || !defined(USE_WINDOWS_FILE)
   52 
   53 static WRes File_Open(CSzFile *p, const char *name, int writeMode)
   54 {
   55   #ifdef USE_WINDOWS_FILE
   56   
   57   p->handle = CreateFileA(name,
   58       writeMode ? GENERIC_WRITE : GENERIC_READ,
   59       FILE_SHARE_READ, NULL,
   60       writeMode ? CREATE_ALWAYS : OPEN_EXISTING,
   61       FILE_ATTRIBUTE_NORMAL, NULL);
   62   return (p->handle != INVALID_HANDLE_VALUE) ? 0 : GetLastError();
   63   
   64   #elif defined(USE_FOPEN)
   65   
   66   p->file = fopen(name, writeMode ? "wb+" : "rb");
   67   return (p->file != 0) ? 0 :
   68     #ifdef UNDER_CE
   69     2; /* ENOENT */
   70     #else
   71     errno;
   72     #endif
   73   
   74   #else
   75 
   76   int flags = (writeMode ? (O_CREAT | O_EXCL | O_WRONLY) : O_RDONLY);
   77   #ifdef O_BINARY
   78   flags |= O_BINARY;
   79   #endif
   80   p->fd = open(name, flags, 0666);
   81   return (p->fd != -1) ? 0 : errno;
   82 
   83   #endif
   84 }
   85 
   86 WRes InFile_Open(CSzFile *p, const char *name) { return File_Open(p, name, 0); }
   87 
   88 WRes OutFile_Open(CSzFile *p, const char *name)
   89 {
   90   #if defined(USE_WINDOWS_FILE) || defined(USE_FOPEN)
   91   return File_Open(p, name, 1);
   92   #else
   93   p->fd = creat(name, 0666);
   94   return (p->fd != -1) ? 0 : errno;
   95   #endif
   96 }
   97 
   98 #endif
   99 
  100 
  101 #ifdef USE_WINDOWS_FILE
  102 static WRes File_OpenW(CSzFile *p, const WCHAR *name, int writeMode)
  103 {
  104   p->handle = CreateFileW(name,
  105       writeMode ? GENERIC_WRITE : GENERIC_READ,
  106       FILE_SHARE_READ, NULL,
  107       writeMode ? CREATE_ALWAYS : OPEN_EXISTING,
  108       FILE_ATTRIBUTE_NORMAL, NULL);
  109   return (p->handle != INVALID_HANDLE_VALUE) ? 0 : GetLastError();
  110 }
  111 WRes InFile_OpenW(CSzFile *p, const WCHAR *name) { return File_OpenW(p, name, 0); }
  112 WRes OutFile_OpenW(CSzFile *p, const WCHAR *name) { return File_OpenW(p, name, 1); }
  113 #endif
  114 
  115 WRes File_Close(CSzFile *p)
  116 {
  117   #ifdef USE_WINDOWS_FILE
  118   
  119   if (p->handle != INVALID_HANDLE_VALUE)
  120   {
  121     if (!CloseHandle(p->handle))
  122       return GetLastError();
  123     p->handle = INVALID_HANDLE_VALUE;
  124   }
  125   
  126   #elif defined(USE_FOPEN)
  127 
  128   if (p->file != NULL)
  129   {
  130     int res = fclose(p->file);
  131     if (res != 0)
  132     {
  133       if (res == EOF)
  134         return errno;
  135       return res;
  136     }
  137     p->file = NULL;
  138   }
  139 
  140   #else
  141 
  142   if (p->fd != -1)
  143   {
  144     if (close(p->fd) != 0)
  145       return errno;
  146     p->fd = -1;
  147   }
  148 
  149   #endif
  150 
  151   return 0;
  152 }
  153 
  154 
  155 WRes File_Read(CSzFile *p, void *data, size_t *size)
  156 {
  157   size_t originalSize = *size;
  158   *size = 0;
  159   if (originalSize == 0)
  160     return 0;
  161 
  162   #ifdef USE_WINDOWS_FILE
  163 
  164   do
  165   {
  166     const DWORD curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : (DWORD)originalSize;
  167     DWORD processed = 0;
  168     const BOOL res = ReadFile(p->handle, data, curSize, &processed, NULL);
  169     data = (void *)((Byte *)data + processed);
  170     originalSize -= processed;
  171     *size += processed;
  172     if (!res)
  173       return GetLastError();
  174     // debug : we can break here for partial reading mode
  175     if (processed == 0)
  176       break;
  177   }
  178   while (originalSize > 0);
  179 
  180   #elif defined(USE_FOPEN)
  181 
  182   do
  183   {
  184     const size_t curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : originalSize;
  185     const size_t processed = fread(data, 1, curSize, p->file);
  186     data = (void *)((Byte *)data + (size_t)processed);
  187     originalSize -= processed;
  188     *size += processed;
  189     if (processed != curSize)
  190       return ferror(p->file);
  191     // debug : we can break here for partial reading mode
  192     if (processed == 0)
  193       break;
  194   }
  195   while (originalSize > 0);
  196 
  197   #else
  198 
  199   do
  200   {
  201     const size_t curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : originalSize;
  202     const ssize_t processed = read(p->fd, data, curSize);
  203     if (processed == -1)
  204       return errno;
  205     if (processed == 0)
  206       break;
  207     data = (void *)((Byte *)data + (size_t)processed);
  208     originalSize -= (size_t)processed;
  209     *size += (size_t)processed;
  210     // debug : we can break here for partial reading mode
  211     // break;
  212   }
  213   while (originalSize > 0);
  214 
  215   #endif
  216 
  217   return 0;
  218 }
  219 
  220 
  221 WRes File_Write(CSzFile *p, const void *data, size_t *size)
  222 {
  223   size_t originalSize = *size;
  224   *size = 0;
  225   if (originalSize == 0)
  226     return 0;
  227   
  228   #ifdef USE_WINDOWS_FILE
  229 
  230   do
  231   {
  232     const DWORD curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : (DWORD)originalSize;
  233     DWORD processed = 0;
  234     const BOOL res = WriteFile(p->handle, data, curSize, &processed, NULL);
  235     data = (const void *)((const Byte *)data + processed);
  236     originalSize -= processed;
  237     *size += processed;
  238     if (!res)
  239       return GetLastError();
  240     if (processed == 0)
  241       break;
  242   }
  243   while (originalSize > 0);
  244 
  245   #elif defined(USE_FOPEN)
  246 
  247   do
  248   {
  249     const size_t curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : originalSize;
  250     const size_t processed = fwrite(data, 1, curSize, p->file);
  251     data = (void *)((Byte *)data + (size_t)processed);
  252     originalSize -= processed;
  253     *size += processed;
  254     if (processed != curSize)
  255       return ferror(p->file);
  256     if (processed == 0)
  257       break;
  258   }
  259   while (originalSize > 0);
  260 
  261   #else
  262 
  263   do
  264   {
  265     const size_t curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : originalSize;
  266     const ssize_t processed = write(p->fd, data, curSize);
  267     if (processed == -1)
  268       return errno;
  269     if (processed == 0)
  270       break;
  271     data = (void *)((Byte *)data + (size_t)processed);
  272     originalSize -= (size_t)processed;
  273     *size += (size_t)processed;
  274   }
  275   while (originalSize > 0);
  276 
  277   #endif
  278 
  279   return 0;
  280 }
  281 
  282 
  283 WRes File_Seek(CSzFile *p, Int64 *pos, ESzSeek origin)
  284 {
  285   #ifdef USE_WINDOWS_FILE
  286 
  287   DWORD moveMethod;
  288   UInt32 low = (UInt32)*pos;
  289   LONG high = (LONG)((UInt64)*pos >> 16 >> 16); /* for case when UInt64 is 32-bit only */
  290   switch (origin)
  291   {
  292     case SZ_SEEK_SET: moveMethod = FILE_BEGIN; break;
  293     case SZ_SEEK_CUR: moveMethod = FILE_CURRENT; break;
  294     case SZ_SEEK_END: moveMethod = FILE_END; break;
  295     default: return ERROR_INVALID_PARAMETER;
  296   }
  297   low = SetFilePointer(p->handle, (LONG)low, &high, moveMethod);
  298   if (low == (UInt32)0xFFFFFFFF)
  299   {
  300     WRes res = GetLastError();
  301     if (res != NO_ERROR)
  302       return res;
  303   }
  304   *pos = ((Int64)high << 32) | low;
  305   return 0;
  306 
  307   #else
  308   
  309   int moveMethod; // = origin;
  310 
  311   switch (origin)
  312   {
  313     case SZ_SEEK_SET: moveMethod = SEEK_SET; break;
  314     case SZ_SEEK_CUR: moveMethod = SEEK_CUR; break;
  315     case SZ_SEEK_END: moveMethod = SEEK_END; break;
  316     default: return EINVAL;
  317   }
  318   
  319   #if defined(USE_FOPEN)
  320   {
  321     int res = fseek(p->file, (long)*pos, moveMethod);
  322     if (res == -1)
  323       return errno;
  324     *pos = ftell(p->file);
  325     if (*pos == -1)
  326       return errno;
  327     return 0;
  328   }
  329   #else
  330   {
  331     off_t res = lseek(p->fd, (off_t)*pos, moveMethod);
  332     if (res == -1)
  333       return errno;
  334     *pos = res;
  335     return 0;
  336   }
  337   
  338   #endif // USE_FOPEN
  339   #endif // USE_WINDOWS_FILE
  340 }
  341 
  342 
  343 WRes File_GetLength(CSzFile *p, UInt64 *length)
  344 {
  345   #ifdef USE_WINDOWS_FILE
  346   
  347   DWORD sizeHigh;
  348   DWORD sizeLow = GetFileSize(p->handle, &sizeHigh);
  349   if (sizeLow == 0xFFFFFFFF)
  350   {
  351     DWORD res = GetLastError();
  352     if (res != NO_ERROR)
  353       return res;
  354   }
  355   *length = (((UInt64)sizeHigh) << 32) + sizeLow;
  356   return 0;
  357   
  358   #elif defined(USE_FOPEN)
  359   
  360   long pos = ftell(p->file);
  361   int res = fseek(p->file, 0, SEEK_END);
  362   *length = ftell(p->file);
  363   fseek(p->file, pos, SEEK_SET);
  364   return res;
  365 
  366   #else
  367 
  368   off_t pos;
  369   *length = 0;
  370   pos = lseek(p->fd, 0, SEEK_CUR);
  371   if (pos != -1)
  372   {
  373     const off_t len2 = lseek(p->fd, 0, SEEK_END);
  374     const off_t res2 = lseek(p->fd, pos, SEEK_SET);
  375     if (len2 != -1)
  376     {
  377       *length = (UInt64)len2;
  378       if (res2 != -1)
  379         return 0;
  380     }
  381   }
  382   return errno;
  383   
  384   #endif
  385 }
  386 
  387 
  388 /* ---------- FileSeqInStream ---------- */
  389 
  390 static SRes FileSeqInStream_Read(const ISeqInStream *pp, void *buf, size_t *size)
  391 {
  392   CFileSeqInStream *p = CONTAINER_FROM_VTBL(pp, CFileSeqInStream, vt);
  393   WRes wres = File_Read(&p->file, buf, size);
  394   p->wres = wres;
  395   return (wres == 0) ? SZ_OK : SZ_ERROR_READ;
  396 }
  397 
  398 void FileSeqInStream_CreateVTable(CFileSeqInStream *p)
  399 {
  400   p->vt.Read = FileSeqInStream_Read;
  401 }
  402 
  403 
  404 /* ---------- FileInStream ---------- */
  405 
  406 static SRes FileInStream_Read(const ISeekInStream *pp, void *buf, size_t *size)
  407 {
  408   CFileInStream *p = CONTAINER_FROM_VTBL(pp, CFileInStream, vt);
  409   WRes wres = File_Read(&p->file, buf, size);
  410   p->wres = wres;
  411   return (wres == 0) ? SZ_OK : SZ_ERROR_READ;
  412 }
  413 
  414 static SRes FileInStream_Seek(const ISeekInStream *pp, Int64 *pos, ESzSeek origin)
  415 {
  416   CFileInStream *p = CONTAINER_FROM_VTBL(pp, CFileInStream, vt);
  417   WRes wres = File_Seek(&p->file, pos, origin);
  418   p->wres = wres;
  419   return (wres == 0) ? SZ_OK : SZ_ERROR_READ;
  420 }
  421 
  422 void FileInStream_CreateVTable(CFileInStream *p)
  423 {
  424   p->vt.Read = FileInStream_Read;
  425   p->vt.Seek = FileInStream_Seek;
  426 }
  427 
  428 
  429 /* ---------- FileOutStream ---------- */
  430 
  431 static size_t FileOutStream_Write(const ISeqOutStream *pp, const void *data, size_t size)
  432 {
  433   CFileOutStream *p = CONTAINER_FROM_VTBL(pp, CFileOutStream, vt);
  434   WRes wres = File_Write(&p->file, data, &size);
  435   p->wres = wres;
  436   return size;
  437 }
  438 
  439 void FileOutStream_CreateVTable(CFileOutStream *p)
  440 {
  441   p->vt.Write = FileOutStream_Write;
  442 }