예제 #1
3
파일: sevenzip.c 프로젝트: pagolo/ezinstall
int Unseven(const char *filename, STRING **list)
{
  CFileInStream archiveStream;
  CLookToRead lookStream;
  CSzArEx db;
  SRes res;
  ISzAlloc allocImp;
  ISzAlloc allocTempImp;
  UInt16 *temp = NULL;
  size_t tempSize = 0;
  Bool do_save = (globaldata.gd_inidata->archive_dir && *(globaldata.gd_inidata->archive_dir))? False : True;
  char *subdir = NULL;
  // UInt32 parents[NUM_PARENTS_MAX];

//  printf("\n7z ANSI-C Decoder " MY_VERSION_COPYRIGHT_DATE "\n\n");

  if (!filename || !*filename) return -1; // error

  #if defined(_WIN32) && !defined(USE_WINDOWS_FILE) && !defined(UNDER_CE)
  g_FileCodePage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
  #endif

  allocImp.Alloc = SzAlloc;
  allocImp.Free = SzFree;

  allocTempImp.Alloc = SzAllocTemp;
  allocTempImp.Free = SzFreeTemp;

  #ifdef UNDER_CE
  if (InFile_OpenW(&archiveStream.file, L"\test.7z"))
  #else
  if (InFile_Open(&archiveStream.file, filename))
  #endif
  {
    PrintError("can not open input file");
    return -1;
  }

  FileInStream_CreateVTable(&archiveStream);
  LookToRead_CreateVTable(&lookStream, False);
  
  lookStream.realStream = &archiveStream.s;
  LookToRead_Init(&lookStream);

  CrcGenerateTable();

  SzArEx_Init(&db);
  
  res = SzArEx_Open(&db, &lookStream.s, &allocImp, &allocTempImp);
  
    if (res == SZ_OK)
    {
      UInt32 i;

      /*
      if you need cache, use these 3 variables.
      if you use external function, you can make these variable as static.
      */
      UInt32 blockIndex = 0xFFFFFFFF; /* it can have any value before first call (if outBuffer = 0) */
      Byte *outBuffer = 0; /* it must be 0 before first call for each new archive. */
      size_t outBufferSize = 0;  /* it can have any value before first call (if outBuffer = 0) */

      for (i = 0; i < db.NumFiles; i++)
      {
        size_t offset = 0;
        size_t outSizeProcessed = 0;
        // const CSzFileItem *f = db.Files + i;
        size_t len;
        unsigned isDir = SzArEx_IsDir(&db, i);
        len = SzArEx_GetFileNameUtf16(&db, i, NULL);
        // len = SzArEx_GetFullNameLen(&db, i);

        if (len > tempSize)
        {
          SzFree(NULL, temp);
          tempSize = len;
          temp = (UInt16 *)SzAlloc(NULL, tempSize * sizeof(temp[0]));
          if (!temp)
          {
            res = SZ_ERROR_MEM;
            break;
          }
        }

        SzArEx_GetFileNameUtf16(&db, i, temp);
/*
    { // progression output
      static char s[256];
      snprintf(s, 255, _("Extracting (%d%%)"), ((i + 1) * 100) / db.NumFiles);
      HandleSemaphoreText(s, list, !i ? 1 : 0);
    }*/
        if (isDir)
          ;//printf("/");
        else
        {
          res = SzArEx_Extract(&db, &lookStream.s, i,
              &blockIndex, &outBuffer, &outBufferSize,
              &offset, &outSizeProcessed,
              &allocImp, &allocTempImp);
          if (res != SZ_OK)
            break;
        }

        // write data to disk        
        {
          CSzFile outFile;
          size_t processedSize;
          size_t j;
          UInt16 *name = (UInt16 *)temp;
          const UInt16 *destPath = (const UInt16 *)name;
          WRes wres;
 
          for (j = 0; name[j] != 0; j++)
            if (name[j] == '/')
            {
              name[j] = 0;
              MyCreateDir(name, &subdir, &do_save);
              name[j] = CHAR_PATH_SEPARATOR;
            }
    
          if (isDir)
          {
            MyCreateDir(destPath, &subdir, &do_save);
            //printf("\n");
            continue;
          }
          if (do_save == False) continue;
          wres = OutFile_OpenUtf16(&outFile, destPath, &subdir, &do_save);
          if (wres == -1) continue;
          if (wres)
          {
            PrintError("can not open output file");
            res = SZ_ERROR_FAIL;
            break;
          }

          processedSize = outSizeProcessed;
          
          if (File_Write(&outFile, outBuffer + offset, &processedSize) != 0 || processedSize != outSizeProcessed)
          {
            PrintError(_("can not write output file"));
            res = SZ_ERROR_FAIL;
            break;
          }
          
          if (File_Close(&outFile))
          {
            PrintError(_("can not close output file"));
            res = SZ_ERROR_FAIL;
            break;
          }
          
          #ifdef USE_WINDOWS_FILE
          if (SzBitWithVals_Check(&db.Attribs, i))
            SetFileAttributesW(destPath, db.Attribs.Vals[i]);
          #endif
        }
        //printf("\n");
      }
      IAlloc_Free(&allocImp, outBuffer);
    }

  SzArEx_Free(&db, &allocImp);
  SzFree(NULL, temp);

  File_Close(&archiveStream.file);
  
  if (res == SZ_OK)
  {
    //printf("\nEverything is Ok\n");
    return 0;
  }
  
  if (res == SZ_ERROR_UNSUPPORTED)
    PrintError(_("decoder doesn't support this archive"));
  else if (res == SZ_ERROR_MEM)
    PrintError(_("can not allocate memory"));
  else if (res == SZ_ERROR_CRC)
    PrintError(_("CRC error"));
  else
    printf("<br />ERROR #%d\n", res);
  
  return -1;
}
예제 #2
0
static int sevenzip_parse_file_iterate_step_internal(
      file_archive_transfer_t *state, char *filename,
      const uint8_t **cdata, unsigned *cmode,
      uint32_t *size, uint32_t *csize, uint32_t *checksum,
      unsigned *payback, struct archive_extract_userdata *userdata)
{
   struct sevenzip_context_t *sevenzip_context = (struct sevenzip_context_t*)state->stream;
   const CSzFileItem *file = sevenzip_context->db.db.Files + sevenzip_context->index;

   if (sevenzip_context->index < sevenzip_context->db.db.NumFiles)
   {
      size_t len = SzArEx_GetFileNameUtf16(&sevenzip_context->db,
            sevenzip_context->index, NULL);
      uint64_t compressed_size = 0;

      if (sevenzip_context->packIndex < sevenzip_context->db.db.NumPackStreams)
      {
         compressed_size = sevenzip_context->db.db.PackSizes[sevenzip_context->packIndex];
         sevenzip_context->packIndex++;
      }

      if (len < PATH_MAX_LENGTH && !file->IsDir)
      {
         char infile[PATH_MAX_LENGTH];
         SRes res                     = SZ_ERROR_FAIL;
         uint16_t *temp               = (uint16_t*)malloc(len * sizeof(uint16_t));

         if (!temp)
            return -1;

         infile[0] = '\0';

         SzArEx_GetFileNameUtf16(&sevenzip_context->db, sevenzip_context->index,
               temp);

         if (temp)
         {
            res  = utf16_to_char_string(temp, infile, sizeof(infile))
               ? SZ_OK : SZ_ERROR_FAIL;
            free(temp);
         }

         if (res != SZ_OK)
            return -1;

         strlcpy(filename, infile, PATH_MAX_LENGTH);

         *cmode = ARCHIVE_MODE_COMPRESSED;
         *checksum = file->Crc;
         *size = file->Size;
         *csize = compressed_size;
      }
   }

   *payback = 1;

   return 1;
}
예제 #3
0
파일: vfs-lzma.c 프로젝트: ikeboy/mgba
const char* _vde7zName(struct VDirEntry* vde) {
	struct VDirEntry7z* vde7z = (struct VDirEntry7z*) vde;
	if (!vde7z->utf8) {
		size_t nameLength = SzArEx_GetFileNameUtf16(&vde7z->vd->db, vde7z->index, 0) * sizeof(UInt16);
		UInt16* name = malloc(nameLength);
		SzArEx_GetFileNameUtf16(&vde7z->vd->db, vde7z->index, name);
		vde7z->utf8 = utf16to8(name, nameLength - sizeof(UInt16));
		free(name);
	}

	return vde7z->utf8;
}
예제 #4
0
ArchiveFile* SzArchive::OpenFile(const char* name)
{
	u16 fname[512];
	for (int i = 0; i < szarchive.NumFiles; i++)
	{
		unsigned isDir = SzArEx_IsDir(&szarchive, i);
		if (isDir)
			continue;

		int len = SzArEx_GetFileNameUtf16(&szarchive, i, fname);
		char szname[512];
		int j = 0;
		for (; j < len && j < sizeof(szname) - 1; j++)
			szname[j] = fname[j];
		szname[j] = 0;
		if (strcmp(name, szname))
			continue;

		size_t offset = 0;
		size_t out_size_processed = 0;
		SRes res = SzArEx_Extract(&szarchive, &lookStream.vt, i, &block_idx, &out_buffer, &out_buffer_size, &offset, &out_size_processed, &g_Alloc, &g_Alloc);
		if (res != SZ_OK)
			return NULL;

		return new SzArchiveFile(out_buffer, offset, (u32)out_size_processed);
	}
	return NULL;
}
예제 #5
0
std::wstring C7zip::FileNameIndex (int index)
{
	std::wstring filename;
    if (m_db == NULL || m_db->FileNameOffsets == 0)
	{
		/* no filename */
		return filename;
	}
	int namelen = SzArEx_GetFileNameUtf16(m_db, index, NULL);
	if (namelen <= 0)
	{
		/* no filename */
		return filename;
	}
	filename.resize(namelen);
	SzArEx_GetFileNameUtf16(m_db, index, (UInt16 *)filename.c_str());
	return filename;
}
예제 #6
0
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
  #ifdef UNDER_CE
  LPWSTR
  #else
  LPSTR
  #endif
  lpCmdLine, int nCmdShow)
#endif
{
  CFileInStream archiveStream;
  CLookToRead lookStream;
  CSzArEx db;
  SRes res = SZ_OK;
  ISzAlloc allocImp;
  ISzAlloc allocTempImp;
  WCHAR sfxPath[MAX_PATH + 2];
  WCHAR path[MAX_PATH * 3 + 2];
  #ifndef UNDER_CE
  WCHAR workCurDir[MAX_PATH + 32];
  #endif
  size_t pathLen;
  DWORD winRes;
  const wchar_t *cmdLineParams;
  const char *errorMessage = NULL;
  Bool useShellExecute = True;
  DWORD exitCode = 0;

  LoadSecurityDlls();

  #ifdef _CONSOLE
  SetConsoleCtrlHandler(HandlerRoutine, TRUE);
  #else
  UNUSED_VAR(hInstance);
  UNUSED_VAR(hPrevInstance);
  UNUSED_VAR(lpCmdLine);
  UNUSED_VAR(nCmdShow);
  #endif

  CrcGenerateTable();

  allocImp.Alloc = SzAlloc;
  allocImp.Free = SzFree;

  allocTempImp.Alloc = SzAllocTemp;
  allocTempImp.Free = SzFreeTemp;

  FileInStream_CreateVTable(&archiveStream);
  LookToRead_CreateVTable(&lookStream, False);
 
  winRes = GetModuleFileNameW(NULL, sfxPath, MAX_PATH);
  if (winRes == 0 || winRes > MAX_PATH)
    return 1;
  {
    cmdLineParams = GetCommandLineW();
    #ifndef UNDER_CE
    {
      Bool quoteMode = False;
      for (;; cmdLineParams++)
      {
        wchar_t c = *cmdLineParams;
        if (c == L'\"')
          quoteMode = !quoteMode;
        else if (c == 0 || (c == L' ' && !quoteMode))
          break;
      }
    }
    #endif
  }

  {
    unsigned i;
    DWORD d;
    winRes = GetTempPathW(MAX_PATH, path);
    if (winRes == 0 || winRes > MAX_PATH)
      return 1;
    pathLen = wcslen(path);
    d = (GetTickCount() << 12) ^ (GetCurrentThreadId() << 14) ^ GetCurrentProcessId();
    
    for (i = 0;; i++, d += GetTickCount())
    {
      if (i >= 100)
      {
        res = SZ_ERROR_FAIL;
        break;
      }
      wcscpy(path + pathLen, L"7z");

      {
        wchar_t *s = path + wcslen(path);
        UInt32 value = d;
        unsigned k;
        for (k = 0; k < 8; k++)
        {
          unsigned t = value & 0xF;
          value >>= 4;
          s[7 - k] = (wchar_t)((t < 10) ? ('0' + t) : ('A' + (t - 10)));
        }
        s[k] = '\0';
      }

      if (DoesFileOrDirExist(path))
        continue;
      if (CreateDirectoryW(path, NULL))
      {
        wcscat(path, WSTRING_PATH_SEPARATOR);
        pathLen = wcslen(path);
        break;
      }
      if (GetLastError() != ERROR_ALREADY_EXISTS)
      {
        res = SZ_ERROR_FAIL;
        break;
      }
    }
    
    #ifndef UNDER_CE
    wcscpy(workCurDir, path);
    #endif
    if (res != SZ_OK)
      errorMessage = "Can't create temp folder";
  }

  if (res != SZ_OK)
  {
    if (!errorMessage)
      errorMessage = "Error";
    PrintErrorMessage(errorMessage);
    return 1;
  }

  if (InFile_OpenW(&archiveStream.file, sfxPath) != 0)
  {
    errorMessage = "can not open input file";
    res = SZ_ERROR_FAIL;
  }
  else
  {
    UInt64 pos = 0;
    if (!FindSignature(&archiveStream.file, &pos))
      res = SZ_ERROR_FAIL;
    else if (File_Seek(&archiveStream.file, (Int64 *)&pos, SZ_SEEK_SET) != 0)
      res = SZ_ERROR_FAIL;
    if (res != 0)
      errorMessage = "Can't find 7z archive";
  }

  if (res == SZ_OK)
  {
    lookStream.realStream = &archiveStream.s;
    LookToRead_Init(&lookStream);
  }

  SzArEx_Init(&db);
  if (res == SZ_OK)
  {
    res = SzArEx_Open(&db, &lookStream.s, &allocImp, &allocTempImp);
  }
  
  if (res == SZ_OK)
  {
    UInt32 executeFileIndex = (UInt32)(Int32)-1;
    UInt32 minPrice = 1 << 30;
    UInt32 i;
    UInt32 blockIndex = 0xFFFFFFFF; /* it can have any value before first call (if outBuffer = 0) */
    Byte *outBuffer = 0; /* it must be 0 before first call for each new archive. */
    size_t outBufferSize = 0;  /* it can have any value before first call (if outBuffer = 0) */
    
    for (i = 0; i < db.NumFiles; i++)
    {
      size_t offset = 0;
      size_t outSizeProcessed = 0;
      WCHAR *temp;

      if (SzArEx_GetFileNameUtf16(&db, i, NULL) >= MAX_PATH)
      {
        res = SZ_ERROR_FAIL;
        break;
      }
      
      temp = path + pathLen;
      
      SzArEx_GetFileNameUtf16(&db, i, temp);
      {
        res = SzArEx_Extract(&db, &lookStream.s, i,
          &blockIndex, &outBuffer, &outBufferSize,
          &offset, &outSizeProcessed,
          &allocImp, &allocTempImp);
        if (res != SZ_OK)
          break;
      }
      {
        CSzFile outFile;
        size_t processedSize;
        size_t j;
        size_t nameStartPos = 0;
        for (j = 0; temp[j] != 0; j++)
        {
          if (temp[j] == '/')
          {
            temp[j] = 0;
            MyCreateDir(path);
            temp[j] = CHAR_PATH_SEPARATOR;
            nameStartPos = j + 1;
          }
        }

        if (SzArEx_IsDir(&db, i))
        {
          MyCreateDir(path);
          continue;
        }
        else
        {
          unsigned extLen;
          const WCHAR *name = temp + nameStartPos;
          unsigned len = (unsigned)wcslen(name);
          unsigned nameLen = FindExt(temp + nameStartPos, &extLen);
          unsigned extPrice = FindItem(kExts, sizeof(kExts) / sizeof(kExts[0]), name + len - extLen, extLen);
          unsigned namePrice = FindItem(kNames, sizeof(kNames) / sizeof(kNames[0]), name, nameLen);

          unsigned price = namePrice + extPrice * 64 + (nameStartPos == 0 ? 0 : (1 << 12));
          if (minPrice > price)
          {
            minPrice = price;
            executeFileIndex = i;
            useShellExecute = (extPrice != k_EXE_ExtIndex);
          }
         
          if (DoesFileOrDirExist(path))
          {
            errorMessage = "Duplicate file";
            res = SZ_ERROR_FAIL;
            break;
          }
          if (OutFile_OpenW(&outFile, path))
          {
            errorMessage = "Can't open output file";
            res = SZ_ERROR_FAIL;
            break;
          }
        }
  
        processedSize = outSizeProcessed;
        if (File_Write(&outFile, outBuffer + offset, &processedSize) != 0 || processedSize != outSizeProcessed)
        {
          errorMessage = "Can't write output file";
          res = SZ_ERROR_FAIL;
        }
        
        #ifdef USE_WINDOWS_FILE
        if (SzBitWithVals_Check(&db.MTime, i))
        {
          const CNtfsFileTime *t = db.MTime.Vals + i;
          FILETIME mTime;
          mTime.dwLowDateTime = t->Low;
          mTime.dwHighDateTime = t->High;
          SetFileTime(outFile.handle, NULL, NULL, &mTime);
        }
        #endif
        
        {
          SRes res2 = File_Close(&outFile);
          if (res != SZ_OK)
            break;
          if (res2 != SZ_OK)
          {
            res = res2;
            break;
          }
        }
        #ifdef USE_WINDOWS_FILE
        if (SzBitWithVals_Check(&db.Attribs, i))
          SetFileAttributesW(path, db.Attribs.Vals[i]);
        #endif
      }
    }

    if (res == SZ_OK)
    {
      if (executeFileIndex == (UInt32)(Int32)-1)
      {
        errorMessage = "There is no file to execute";
        res = SZ_ERROR_FAIL;
      }
      else
      {
        WCHAR *temp = path + pathLen;
        UInt32 j;
        SzArEx_GetFileNameUtf16(&db, executeFileIndex, temp);
        for (j = 0; temp[j] != 0; j++)
          if (temp[j] == '/')
            temp[j] = CHAR_PATH_SEPARATOR;
      }
    }
    IAlloc_Free(&allocImp, outBuffer);
  }
  SzArEx_Free(&db, &allocImp);

  File_Close(&archiveStream.file);

  if (res == SZ_OK)
  {
    HANDLE hProcess = 0;
    
    #ifndef UNDER_CE
    WCHAR oldCurDir[MAX_PATH + 2];
    oldCurDir[0] = 0;
    {
      DWORD needLen = GetCurrentDirectory(MAX_PATH + 1, oldCurDir);
      if (needLen == 0 || needLen > MAX_PATH)
        oldCurDir[0] = 0;
      SetCurrentDirectory(workCurDir);
    }
    #endif
    
    if (useShellExecute)
    {
      SHELLEXECUTEINFO ei;
      UINT32 executeRes;
      BOOL success;
      
      memset(&ei, 0, sizeof(ei));
      ei.cbSize = sizeof(ei);
      ei.lpFile = path;
      ei.fMask = SEE_MASK_NOCLOSEPROCESS
          #ifndef UNDER_CE
          | SEE_MASK_FLAG_DDEWAIT
          #endif
          /* | SEE_MASK_NO_CONSOLE */
          ;
      if (wcslen(cmdLineParams) != 0)
        ei.lpParameters = cmdLineParams;
      ei.nShow = SW_SHOWNORMAL; /* SW_HIDE; */
      success = ShellExecuteEx(&ei);
      executeRes = (UINT32)(UINT_PTR)ei.hInstApp;
      if (!success || (executeRes <= 32 && executeRes != 0))  /* executeRes = 0 in Windows CE */
        res = SZ_ERROR_FAIL;
      else
        hProcess = ei.hProcess;
    }
    else
    {
      STARTUPINFOW si;
      PROCESS_INFORMATION pi;
      WCHAR cmdLine[MAX_PATH * 3];

      wcscpy(cmdLine, path);
      wcscat(cmdLine, cmdLineParams);
      memset(&si, 0, sizeof(si));
      si.cb = sizeof(si);
      if (CreateProcessW(NULL, cmdLine, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi) == 0)
        res = SZ_ERROR_FAIL;
      else
      {
        CloseHandle(pi.hThread);
        hProcess = pi.hProcess;
      }
    }
    
    if (hProcess != 0)
    {
      WaitForSingleObject(hProcess, INFINITE);
      if (!GetExitCodeProcess(hProcess, &exitCode))
        exitCode = 1;
      CloseHandle(hProcess);
    }
    
    #ifndef UNDER_CE
    SetCurrentDirectory(oldCurDir);
    #endif
  }

  path[pathLen] = L'\0';
  RemoveDirWithSubItems(path);

  if (res == SZ_OK)
    return (int)exitCode;
  
  {
    if (res == SZ_ERROR_UNSUPPORTED)
      errorMessage = "Decoder doesn't support this archive";
    else if (res == SZ_ERROR_MEM)
      errorMessage = "Can't allocate required memory";
    else if (res == SZ_ERROR_CRC)
      errorMessage = "CRC error";
    else
    {
      if (!errorMessage)
        errorMessage = "ERROR";
    }
 
    if (errorMessage)
      PrintErrorMessage(errorMessage);
  }
  return 1;
}
예제 #7
0
int MY_CDECL main(int numargs, char *args[])
{
  CFileInStream archiveStream;
  CLookToRead lookStream;
  CSzArEx db;
  SRes res;
  ISzAlloc allocImp;
  ISzAlloc allocTempImp;
  UInt16 *temp = NULL;
  size_t tempSize = 0;
  // UInt32 parents[NUM_PARENTS_MAX];

  printf("\n7z ANSI-C Decoder " MY_VERSION_COPYRIGHT_DATE "\n\n");

  if (numargs == 1)
  {
    printf(
      "Usage: 7zDec <command> <archive_name>\n\n"
      "<Commands>\n"
      "  e: Extract files from archive (without using directory names)\n"
      "  l: List contents of archive\n"
      "  t: Test integrity of archive\n"
      "  x: eXtract files with full paths\n");
    return 0;
  }
  
  if (numargs < 3)
  {
    PrintError("incorrect command");
    return 1;
  }

  #if defined(_WIN32) && !defined(USE_WINDOWS_FILE) && !defined(UNDER_CE)
  g_FileCodePage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
  #endif

  allocImp.Alloc = SzAlloc;
  allocImp.Free = SzFree;

  allocTempImp.Alloc = SzAllocTemp;
  allocTempImp.Free = SzFreeTemp;

  #ifdef UNDER_CE
  if (InFile_OpenW(&archiveStream.file, L"\test.7z"))
  #else
  if (InFile_Open(&archiveStream.file, args[2]))
  #endif
  {
    PrintError("can not open input file");
    return 1;
  }

  FileInStream_CreateVTable(&archiveStream);
  LookToRead_CreateVTable(&lookStream, False);
  
  lookStream.realStream = &archiveStream.s;
  LookToRead_Init(&lookStream);

  CrcGenerateTable();

  SzArEx_Init(&db);
  
  res = SzArEx_Open(&db, &lookStream.s, &allocImp, &allocTempImp);
  
  if (res == SZ_OK)
  {
    char *command = args[1];
    int listCommand = 0, testCommand = 0, fullPaths = 0;
    
    if (strcmp(command, "l") == 0) listCommand = 1;
    else if (strcmp(command, "t") == 0) testCommand = 1;
    else if (strcmp(command, "e") == 0) { }
    else if (strcmp(command, "x") == 0) { fullPaths = 1; }
    else
    {
      PrintError("incorrect command");
      res = SZ_ERROR_FAIL;
    }

    if (res == SZ_OK)
    {
      UInt32 i;

      /*
      if you need cache, use these 3 variables.
      if you use external function, you can make these variable as static.
      */
      UInt32 blockIndex = 0xFFFFFFFF; /* it can have any value before first call (if outBuffer = 0) */
      Byte *outBuffer = 0; /* it must be 0 before first call for each new archive. */
      size_t outBufferSize = 0;  /* it can have any value before first call (if outBuffer = 0) */

      for (i = 0; i < db.NumFiles; i++)
      {
        size_t offset = 0;
        size_t outSizeProcessed = 0;
        // const CSzFileItem *f = db.Files + i;
        size_t len;
        unsigned isDir = SzArEx_IsDir(&db, i);
        if (listCommand == 0 && isDir && !fullPaths)
          continue;
        len = SzArEx_GetFileNameUtf16(&db, i, NULL);
        // len = SzArEx_GetFullNameLen(&db, i);

        if (len > tempSize)
        {
          SzFree(NULL, temp);
          tempSize = len;
          temp = (UInt16 *)SzAlloc(NULL, tempSize * sizeof(temp[0]));
          if (!temp)
          {
            res = SZ_ERROR_MEM;
            break;
          }
        }

        SzArEx_GetFileNameUtf16(&db, i, temp);
        /*
        if (SzArEx_GetFullNameUtf16_Back(&db, i, temp + len) != temp)
        {
          res = SZ_ERROR_FAIL;
          break;
        }
        */

        if (listCommand)
        {
          char attr[8], s[32], t[32];
          UInt64 fileSize;

          GetAttribString(SzBitWithVals_Check(&db.Attribs, i) ? db.Attribs.Vals[i] : 0, isDir, attr);

          fileSize = SzArEx_GetFileSize(&db, i);
          UInt64ToStr(fileSize, s);
          
          if (SzBitWithVals_Check(&db.MTime, i))
            ConvertFileTimeToString(&db.MTime.Vals[i], t);
          else
          {
            size_t j;
            for (j = 0; j < 19; j++)
              t[j] = ' ';
            t[j] = '\0';
          }
          
          printf("%s %s %10s  ", t, attr, s);
          res = PrintString(temp);
          if (res != SZ_OK)
            break;
          if (isDir)
            printf("/");
          printf("\n");
          continue;
        }

        fputs(testCommand ?
            "Testing    ":
            "Extracting ",
            stdout);
        res = PrintString(temp);
        if (res != SZ_OK)
          break;
        
        if (isDir)
          printf("/");
        else
        {
          res = SzArEx_Extract(&db, &lookStream.s, i,
              &blockIndex, &outBuffer, &outBufferSize,
              &offset, &outSizeProcessed,
              &allocImp, &allocTempImp);
          if (res != SZ_OK)
            break;
        }
        
        if (!testCommand)
        {
          CSzFile outFile;
          size_t processedSize;
          size_t j;
          UInt16 *name = (UInt16 *)temp;
          const UInt16 *destPath = (const UInt16 *)name;
 
          for (j = 0; name[j] != 0; j++)
            if (name[j] == '/')
            {
              if (fullPaths)
              {
                name[j] = 0;
                MyCreateDir(name);
                name[j] = CHAR_PATH_SEPARATOR;
              }
              else
                destPath = name + j + 1;
            }
    
          if (isDir)
          {
            MyCreateDir(destPath);
            printf("\n");
            continue;
          }
          else if (OutFile_OpenUtf16(&outFile, destPath))
          {
            PrintError("can not open output file");
            res = SZ_ERROR_FAIL;
            break;
          }

          processedSize = outSizeProcessed;
          
          if (File_Write(&outFile, outBuffer + offset, &processedSize) != 0 || processedSize != outSizeProcessed)
          {
            PrintError("can not write output file");
            res = SZ_ERROR_FAIL;
            break;
          }
          
          if (File_Close(&outFile))
          {
            PrintError("can not close output file");
            res = SZ_ERROR_FAIL;
            break;
          }
          
          #ifdef USE_WINDOWS_FILE
          if (SzBitWithVals_Check(&db.Attribs, i))
            SetFileAttributesW(destPath, db.Attribs.Vals[i]);
          #endif
        }
        printf("\n");
      }
      IAlloc_Free(&allocImp, outBuffer);
    }
  }

  SzArEx_Free(&db, &allocImp);
  SzFree(NULL, temp);

  File_Close(&archiveStream.file);
  
  if (res == SZ_OK)
  {
    printf("\nEverything is Ok\n");
    return 0;
  }
  
  if (res == SZ_ERROR_UNSUPPORTED)
    PrintError("decoder doesn't support this archive");
  else if (res == SZ_ERROR_MEM)
    PrintError("can not allocate memory");
  else if (res == SZ_ERROR_CRC)
    PrintError("CRC error");
  else
    printf("\nERROR #%d\n", res);
  
  return 1;
}
예제 #8
0
void ExtractPayload(const void* payload, size_t payloadSize, const WCHAR* prefix)
{
	CMemInStream memStream;
	MemInStream_Init(&memStream, payload, payloadSize);

	CrcGenerateTable();

	ISzAlloc alloc = { SzAlloc, SzFree };
	CSzArEx db;
	SzArEx_Init(&db);
	SRes res = SzArEx_Open(&db, &memStream.s, &alloc, &alloc);
	if (res != SZ_OK)
	{
		SzArEx_Free(&db, &alloc);
		return;
	}

	WCHAR buffer[MAX_PATH];
	UInt32 blockIndex = 0xFFFFFFFF;
	Byte* outBuffer = 0;
	size_t outBufferSize = 0;

	for (UInt32 i = 0; i < db.db.NumFiles; i++)
	{
		size_t offset = 0;
		size_t outSizeProcessed = 0;
		const CSzFileItem* f = db.db.Files + i;

		SzArEx_GetFileNameUtf16(&db, i, (UInt16*)buffer);
		WCHAR* destPath = buffer;
		if (wcsncmp(destPath, prefix, 3) == 0 ||
			wcsncmp(destPath, L"ALL", 3) == 0)
		{
			// Skip the prefix (X64/X32/ALL) and the path separater.
			destPath += 4;
		}
		else
		{
			// This file isn't for this arch.
			continue;
		}

		if (!f->IsDir)
		{
			res = SzArEx_Extract(
				&db, &memStream.s, i, &blockIndex, &outBuffer, &outBufferSize, &offset,
				&outSizeProcessed, &alloc, &alloc);
			if (res != SZ_OK)
			{
				break;
			}
		}

		for (size_t j = 0; destPath[j] != L'\0'; ++j)
		{
			if (destPath[j] == L'/')
			{
				destPath[j] = L'\0';
				CreateDirectory(destPath, NULL);
				destPath[j] = CHAR_PATH_SEPARATOR;
			}
		}

		if (f->IsDir)
		{
			CreateDirectory(destPath, NULL);
			continue;
		}

		CSzFile outFile;
		if (OutFile_OpenW(&outFile, destPath))
		{
			res = SZ_ERROR_FAIL;
			break;
		}
		size_t processedSize = outSizeProcessed;
		if (File_Write(&outFile, outBuffer + offset, &processedSize) != 0 ||
			processedSize != outSizeProcessed)
		{
			res = SZ_ERROR_FAIL;
			break;
		}
		if (File_Close(&outFile))
		{
			res = SZ_ERROR_FAIL;
			break;
		}

		if (f->AttribDefined) SetFileAttributesW(destPath, f->Attrib);
	}

	IAlloc_Free(&alloc, outBuffer);
	SzArEx_Free(&db, &alloc);

	if (res == SZ_OK)
	{
		// Success.
	}
}
예제 #9
0
파일: 7z.c 프로젝트: BSzili/aros-stuff
ASM(LONG) sz_GetInfo(REG(a0, struct xadArchiveInfo *ai),
REG(a6, struct xadMasterBase *xadMasterBase))
#endif
{
#ifdef __amigaos4__
    IExec = (struct ExecIFace *)(*(struct ExecBase **)4)->MainInterface;

    newlibbase = OpenLibrary("newlib.library", 52);
    if(newlibbase)
        INewlib = GetInterface(newlibbase, "main", 1, NULL);
#elif defined(__AROS__)
	if(!(aroscbase = OpenLibrary("arosc.library", 41)))
		return(XADERR_RESOURCE);
#else
 SysBase = *(struct ExecBase **)4;
#endif

	ai->xai_PrivateClient = xadAllocVec(sizeof(struct xad7zprivate),MEMF_PRIVATE | MEMF_CLEAR);
	struct xad7zprivate *xad7z = ai->xai_PrivateClient;
  struct xadFileInfo *fi;
	long err=XADERR_OK;
	long res=SZ_OK;
	size_t namelen;
	UBYTE *namebuf; // was UWORD
  CFileXadInStream *archiveStream = &xad7z->archiveStream;
  CSzArEx *db = &xad7z->db;       /* 7z archive database structure */
  ISzAlloc allocImp;           /* memory functions for main pool */
  ISzAlloc allocTempImp;       /* memory functions for temporary pool */
	CLookToRead *lookStream = &xad7z->lookStream;

  allocImp.Alloc = SzAlloc;
  allocImp.Free = SzFree;
  allocTempImp.Alloc = SzAllocTemp;
  allocTempImp.Free = SzFreeTemp;

  archiveStream->ai = ai;
#ifdef __amigaos4__
  archiveStream->IxadMaster = IxadMaster;
#else
  archiveStream->xadMasterBase = xadMasterBase;
#endif
  archiveStream->InStream.Read = SzFileReadImp;
  archiveStream->InStream.Seek = SzFileSeekImp;

	if(namebuf = AllocVec(1024, MEMF_PRIVATE))
	{

  LookToRead_CreateVTable(lookStream, False);
  lookStream->realStream = (ISeekInStream *)&archiveStream->InStream;
  LookToRead_Init(lookStream);

	xad7z->blockIndex = 0xfffffff;
	xad7z->outBuffer = 0;
	xad7z->outBufferSize = 0;

  CrcGenerateTable();
  SzArEx_Init(db);
  res = SzArEx_Open(db, &lookStream->s, &allocImp, &allocTempImp);

	if(res == SZ_OK)
    {
      UInt32 i;

      for (i = 0; i < db->db.NumFiles; i++)
      {
    fi = (struct xadFileInfo *) xadAllocObjectA(XADOBJ_FILEINFO, NULL);
    if (!fi) return(XADERR_NOMEMORY);
        CSzFileItem *f = db->db.Files + i;
		fi->xfi_DataPos = 0; //ai->xai_InPos; // i
		fi->xfi_Size = f->Size;

	namelen = SzArEx_GetFileNameUtf16(db, i, namebuf); // &
    if (!(fi->xfi_FileName = xadConvertName(CHARSET_HOST,
#if defined(__AROS__) && (AROS_BIG_ENDIAN == 0)
							XAD_CHARACTERSET, CHARSET_UNICODE_UCS2_LITTLEENDIAN,
#else
							XAD_CHARACTERSET, CHARSET_UNICODE_UCS2_BIGENDIAN,
#endif
							XAD_STRINGSIZE, namelen,
							XAD_CSTRING, namebuf, // no *
							TAG_DONE))) return(XADERR_NOMEMORY);

    xadConvertDates(XAD_DATEAMIGA,ConvertFileTime(&f->MTime),
					XAD_GETDATEXADDATE,&fi->xfi_Date,
					TAG_DONE);

      fi->xfi_CrunchSize  = 0; //(long) (db->Database.PackSizes[i] << 32); //fi->xfi_Size;

	fi->xfi_Flags = 0;
		if(f->IsDir)
		{
			fi->xfi_Flags |= XADFIF_DIRECTORY;
		}

		 if ((err = xadAddFileEntryA(fi, ai, NULL))) return(XADERR_NOMEMORY);
      }
    }
	FreeVec(namebuf);
	}

	return(sztoxaderr(res));
}
예제 #10
0
파일: 7zFile.c 프로젝트: huairen/JArchive
static size_t FolderOutStream_Write2(CFolderOutStream *p, const void *data, size_t size)
{
	SizeT processedSize = 0;
	UInt16 *fullPath = NULL;
	SizeT pathLen = 0;
	SizeT curSize = 0;
	SRes res = SZ_OK;
	UInt32 i;
	SizeT dirLen = 0;
	
	if(p->outputDir)
		dirLen = wcslen(p->outputDir);

	while(size != 0)
	{
		if(p->file.handle == INVALID_HANDLE_VALUE)
		{
			UInt16 *filename;
			UInt32 index  = p->startIndex + p->currentIndex;
			const CSzFileItem *fileItem = p->ar->db.Files + index;
			SizeT len = SzArEx_GetFileNameUtf16(p->ar, index, NULL);
			if(len + dirLen > pathLen)
			{
				free(fullPath);
				pathLen = len + dirLen;
				fullPath = (UInt16*)malloc(pathLen * sizeof(fullPath[0]));
				if(fullPath == 0)
				{
					res = SZ_ERROR_MEM;
					break;
				}

				if(p->outputDir)
					wcscpy_s(fullPath,pathLen,p->outputDir);
			}

			filename = fullPath + dirLen;
			SzArEx_GetFileNameUtf16(p->ar, index, filename);
			for (i = 0; fullPath[i] != 0 && i<pathLen; i++)
				if (fullPath[i] == '/')
				{
					fullPath[i] = 0;
					CreateDirectoryW(fullPath,NULL);
					fullPath[i] = CHAR_PATH_SEPARATOR;
				}
				
			if (fileItem->IsDir)
			{
				CreateDirectoryW(fullPath,NULL);
				continue;
			}
			else if(OutFile_OpenW(&p->file, fullPath))
			{
				res = SZ_ERROR_FAIL;
				break;
			}

#ifdef _SZ_ALLOC_DEBUG
			wprintf(L"\nExtract: %s", fullPath);
#endif
			p->fileSize = fileItem->Size;
			p->checkCrc = fileItem->CrcDefined;
			p->crc = CRC_INIT_VAL;
		}

		curSize = size < p->fileSize ? size : (SizeT)p->fileSize;
		if(S_OK != File_Write(&p->file, data, &curSize))
		{
			File_Close(&p->file);
			res = SZ_ERROR_FAIL;
			break;
		}

		if(p->checkCrc)
			p->crc = CrcUpdate(p->crc,data,curSize);

		data = (const Byte*)data + curSize;
		size -= curSize;
		p->fileSize -= curSize;
		p->folderSize -= curSize;
		processedSize += curSize;

		if(p->fileSize == 0)
		{
			UInt32 index  = p->startIndex + p->currentIndex;
			const CSzFileItem *fileItem = p->ar->db.Files + index;

			p->currentIndex += 1;

			if(fileItem->MTimeDefined)
				SetFileTime(p->file.handle,NULL,NULL,(const FILETIME*)&fileItem->MTime);

			File_Close(&p->file);

			if(fileItem->AttribDefined)
				SetFileAttributesW(fullPath, fileItem->Attrib);

			if(fileItem->CrcDefined && CRC_GET_DIGEST(p->crc) != fileItem->Crc)
			{
				res = SZ_ERROR_CRC;
				break;
			}
		}
	}

	free(fullPath);
	return processedSize;
}
예제 #11
0
bool SZFilePack::open(const char* packFileName)
{
	close();

	UInt32 i;
	SRes res;
	UInt16 *temp = NULL;
	size_t tempSize = 0;
	CBuf buf;
	buf.data = new byte[MAX_PATH];
	buf.size = MAX_PATH;
	mPackFileName = packFileName;
	if ( InFile_Open(&mArchiveStream.file, packFileName) ) {
		PrintError("can not open input file");
		return false;
	}

	FileInStream_CreateVTable(&mArchiveStream);
	LookToRead_CreateVTable(&mLookStream, False);

	mLookStream.realStream = &mArchiveStream.s;
	LookToRead_Init(&mLookStream);

	CrcGenerateTable();

	SzArEx_Init(&mDb);
	res = SzArEx_Open(&mDb, &mLookStream.s, &mAllocImp, &mAllocTempImp);
	if (res == SZ_OK) {
		for (i = 0; i < mDb.db.NumFiles; i++) {
			size_t len;
			const CSzFileItem *f = mDb.db.Files + i;

			if (f->IsDir)
				continue;

			len = SzArEx_GetFileNameUtf16(&mDb, i, NULL);
			if (len > tempSize) {
				SzFree(NULL, temp);
				tempSize = len;
				temp = (UInt16 *)SzAlloc(NULL, tempSize * sizeof(temp[0]));
				if (temp == 0) {
					res = SZ_ERROR_MEM;
					break;
				}
			}
			SzArEx_GetFileNameUtf16(&mDb, i, temp);
			if (res != SZ_OK)
				break;

			// 保存所有文件的索引号到hash表中
			res = Utf16_To_Char(&buf, temp, 0);
			if (res != SZ_OK)
				break;

			//名字转成小写
			_strlwr((char*)buf.data);
			string key = (const char*)buf.data;
			mIndexMap[key] = i;
		}
	}

	SzFree(NULL, temp);
	delete[] buf.data;
	mIsPackOpened = true;

	return true;
}
예제 #12
0
int cli_7unz (cli_ctx *ctx, size_t offset) {
    CFileInStream archiveStream;
    CLookToRead lookStream;
    CSzArEx db;
    SRes res;
    UInt16 utf16buf[UTFBUFSZ], *utf16name = utf16buf;
    int namelen = UTFBUFSZ, found = CL_CLEAN;
    Int64 begin_of_archive = offset;
    UInt32 viruses_found = 0;

    /* Replacement for 
       FileInStream_CreateVTable(&archiveStream); */
    archiveStream.s.Read = FileInStream_fmap_Read;
    archiveStream.s.Seek = FileInStream_fmap_Seek;
    archiveStream.s.curpos = 0;
    archiveStream.file.fmap = *ctx->fmap;

    LookToRead_CreateVTable(&lookStream, False);
  
    if(archiveStream.s.Seek(&archiveStream.s, &begin_of_archive, SZ_SEEK_SET) != 0)
	return CL_CLEAN;

    lookStream.realStream = &archiveStream.s;
    LookToRead_Init(&lookStream);

    SzArEx_Init(&db);
    res = SzArEx_Open(&db, &lookStream.s, &allocImp, &allocTempImp);
    if(res == SZ_OK) {
	UInt32 i, blockIndex = 0xFFFFFFFF;
	Byte *outBuffer = 0;
	size_t outBufferSize = 0;
	unsigned int encrypted = 0;

	for (i = 0; i < db.db.NumFiles; i++) {
	    size_t offset = 0;
	    size_t outSizeProcessed = 0;
	    const CSzFileItem *f = db.db.Files + i;
	    char *name;
	    size_t j;
	    int newnamelen, fd;

	    if((found = cli_checklimits("7unz", ctx, 0, 0, 0)))
		break;

	    if (f->IsDir)
		continue;

	    if(cli_checklimits("7unz", ctx, f->Size, 0, 0))
		continue;

	    if (!db.FileNameOffsets)
		newnamelen = 0; /* no filename */
	    else {
		newnamelen = SzArEx_GetFileNameUtf16(&db, i, NULL);
		if (newnamelen > namelen) {
		    if(namelen > UTFBUFSZ)
			free(utf16name);
		    utf16name = cli_malloc(newnamelen*2);
		    if(!utf16name) {
			found = CL_EMEM;
			break;
		    }
		    namelen = newnamelen;
		}
		SzArEx_GetFileNameUtf16(&db, i, utf16name);
	    }

	    name = (char *)utf16name;
	    for(j=0; j<(size_t)newnamelen; j++) /* FIXME */
		name[j] = utf16name[j];
	    name[j] = 0;
	    cli_dbgmsg("cli_7unz: extracting %s\n", name);

	    res = SzArEx_Extract(&db, &lookStream.s, i, &blockIndex, &outBuffer, &outBufferSize, &offset, &outSizeProcessed, &allocImp, &allocTempImp);
	    if(res == SZ_ERROR_ENCRYPTED) {
		encrypted = 1;
		if(DETECT_ENCRYPTED) {
		    cli_dbgmsg("cli_7unz: Encrypted files found in archive.\n");
		    cli_append_virus(ctx, "Heuristics.Encrypted.7Zip");
		    viruses_found++;
		    if(!SCAN_ALL) {
			found = CL_VIRUS;
			break;
		    }
		}
	    }
	    if(cli_matchmeta(ctx, name, 0, f->Size, encrypted, i, f->CrcDefined ? f->Crc : 0, NULL)) {
		found = CL_VIRUS;
		viruses_found++;
		if (!SCAN_ALL)
		    break;
	    }
	    if (res != SZ_OK)
		cli_dbgmsg("cli_unz: extraction failed with %d\n", res);
	    else {
		if((found = cli_gentempfd(ctx->engine->tmpdir, &name, &fd)))
		    break;
		    
		cli_dbgmsg("cli_7unz: Saving to %s\n", name);
		if((size_t)cli_writen(fd, outBuffer + offset, outSizeProcessed) != outSizeProcessed)
		    found = CL_EWRITE;
		else
		    if ((found = cli_magic_scandesc(fd, ctx)) == CL_VIRUS)
			viruses_found++;
		close(fd);
		if(!ctx->engine->keeptmp && cli_unlink(name))
		    found = CL_EUNLINK;

		free(name);
		if(found != CL_CLEAN)
		    if (!(SCAN_ALL && found == CL_VIRUS))
			break;
	    }
	}
	IAlloc_Free(&allocImp, outBuffer);
    }
    SzArEx_Free(&db, &allocImp);
    if(namelen > UTFBUFSZ)
	free(utf16name);

    if (res == SZ_OK)
	cli_dbgmsg("cli_7unz: completed successfully\n");
    else if (res == SZ_ERROR_UNSUPPORTED)
	cli_dbgmsg("cli_7unz: unsupported\n");
    else if (res == SZ_ERROR_MEM)
	cli_dbgmsg("cli_7unz: oom\n");
    else if (res == SZ_ERROR_CRC)
	cli_dbgmsg("cli_7unz: crc mismatch\n");
    else
	cli_dbgmsg("cli_7unz: error %d\n", res);

    if (SCAN_ALL && viruses_found)
	return CL_VIRUS;
    return found;
}
예제 #13
0
파일: content.c 프로젝트: jwarby/RetroArch
static struct string_list *compressed_7zip_file_list_new(
      const char *path, const char* ext)
{
   CFileInStream archiveStream;
   CLookToRead lookStream;
   CSzArEx db;
   ISzAlloc allocImp;
   ISzAlloc allocTempImp;
   size_t temp_size             = 0;
   struct string_list     *list = NULL;
   
   /* These are the allocation routines - currently using 
    * the non-standard 7zip choices. */
   allocImp.Alloc     = SzAlloc;
   allocImp.Free      = SzFree;
   allocTempImp.Alloc = SzAllocTemp;
   allocTempImp.Free  = SzFreeTemp;

   if (InFile_Open(&archiveStream.file, path))
   {
      RARCH_ERR("Could not open %s as 7z archive.\n",path);
      return NULL;
   }

   list = string_list_new();

   if (!list)
   {
      File_Close(&archiveStream.file);
      return NULL;
   }

   FileInStream_CreateVTable(&archiveStream);
   LookToRead_CreateVTable(&lookStream, False);
   lookStream.realStream = &archiveStream.s;
   LookToRead_Init(&lookStream);
   CrcGenerateTable();
   SzArEx_Init(&db);

   if (SzArEx_Open(&db, &lookStream.s, &allocImp, &allocTempImp) == SZ_OK)
   {
      uint32_t i;
      struct string_list *ext_list = ext ? string_split(ext, "|"): NULL;
      SRes res                     = SZ_OK;
      uint16_t *temp               = NULL;

      for (i = 0; i < db.db.NumFiles; i++)
      {
         union string_list_elem_attr attr;
         char infile[PATH_MAX_LENGTH];
         const char *file_ext         = NULL;
         size_t                   len = 0;
         bool supported_by_core       = false;
         const CSzFileItem         *f = db.db.Files + i;

         /* we skip over everything, which is a directory. */
         if (f->IsDir)
            continue;

         len = SzArEx_GetFileNameUtf16(&db, i, NULL);

         if (len > temp_size)
         {
            free(temp);
            temp_size = len;
            temp      = (uint16_t *)malloc(temp_size * sizeof(temp[0]));

            if (temp == 0)
            {
               res = SZ_ERROR_MEM;
               break;
            }
         }

         SzArEx_GetFileNameUtf16(&db, i, temp);
         res      = utf16_to_char_string(temp, infile, sizeof(infile)) 
            ? SZ_OK : SZ_ERROR_FAIL;
         file_ext = path_get_extension(infile);

         if (string_list_find_elem_prefix(ext_list, ".", file_ext))
            supported_by_core = true;

         /*
          * Currently we only support files without subdirs in the archives.
          * Folders are not supported (differences between win and lin.
          * Archives within archives should imho never be supported.
          */

         if (!supported_by_core)
            continue;

         attr.i = RARCH_COMPRESSED_FILE_IN_ARCHIVE;

         if (!string_list_append(list, infile, attr))
         {
            res = SZ_ERROR_MEM;
            break;
         }
      }

      string_list_free(ext_list);
      free(temp);

      if (res != SZ_OK)
      {
         /* Error handling */
         RARCH_ERR("Failed to open compressed_file: \"%s\"\n", path);

         string_list_free(list);
         list = NULL;
      }
   }

   SzArEx_Free(&db, &allocImp);
   File_Close(&archiveStream.file);

   return list;
}
예제 #14
0
int _7z_search_crc_match(_7z_file *new_7z, UINT32 search_crc, const char* search_filename, int search_filename_length, bool matchcrc, bool matchname)
{
	UInt16 *temp = NULL;
	size_t tempSize = 0;

	for (int i = 0; i < new_7z->db.db.NumFiles; i++)
	{
		const CSzFileItem *f = new_7z->db.db.Files + i;
		size_t len;

		len = SzArEx_GetFileNameUtf16(&new_7z->db, i, NULL);

		// if it's a directory entry we don't care about it..
		if (f->IsDir)
			continue;

		if (len > tempSize)
		{
			SZipFree(NULL, temp);
			tempSize = len;
			temp = (UInt16 *)SZipAlloc(NULL, tempSize * sizeof(temp[0]));
			if (temp == 0)
			{
				return -1; // memory error
			}
		}

		bool crcmatch = false;
		bool namematch = false;

		UINT64 size = f->Size;
		UINT32 crc = f->Crc;

		/* Check for a name match */
		SzArEx_GetFileNameUtf16(&new_7z->db, i, temp);

		if (len == search_filename_length+1)
		{
			int j;
			for (j=0;j<search_filename_length;j++)
			{
				UINT8 sn = search_filename[j];
				UINT16 zn = temp[j]; // these are utf16

				// MAME filenames are always lowercase so be case insensitive
				if ((zn>=0x41) && (zn<=0x5a)) zn+=0x20;

				if (sn != zn) break;
			}
			if (j==search_filename_length) namematch = true;
		}


		/* Check for a CRC match */
		if (crc==search_crc) crcmatch = true;

		bool found = false;

		if (matchcrc && matchname)
		{
			if (crcmatch && namematch)
				found = true;
		}
		else if (matchcrc)
		{
			if (crcmatch)
				found = true;
		}
		else if (matchname)
		{
			if (namematch)
				found = true;
		}

		if (found)
		{
		//  printf("found %S %d %08x %08x %08x %s %d\n", temp, len, crc, search_crc, size, search_filename, search_filename_length);
			new_7z->curr_file_idx = i;
			new_7z->uncompressed_length = size;
			new_7z->crc = crc;

			SZipFree(NULL, temp);
			return i;
		}
	}

	SZipFree(NULL, temp);
	return -1;
}
예제 #15
0
파일: 7zMain.c 프로젝트: mcmilk/7-Zip-zstd
int MY_CDECL main(int numargs, char *args[])
{
  ISzAlloc allocImp;
  ISzAlloc allocTempImp;

  CFileInStream archiveStream;
  CLookToRead2 lookStream;
  CSzArEx db;
  SRes res;
  UInt16 *temp = NULL;
  size_t tempSize = 0;
  // UInt32 parents[NUM_PARENTS_MAX];

  Print("\n7z Decoder " MY_VERSION_CPU " : " MY_COPYRIGHT_DATE "\n\n");

  if (numargs == 1)
  {
    Print(
      "Usage: 7zDec <command> <archive_name>\n\n"
      "<Commands>\n"
      "  e: Extract files from archive (without using directory names)\n"
      "  l: List contents of archive\n"
      "  t: Test integrity of archive\n"
      "  x: eXtract files with full paths\n");
    return 0;
  }

  if (numargs < 3)
  {
    PrintError("incorrect command");
    return 1;
  }

  #if defined(_WIN32) && !defined(USE_WINDOWS_FILE) && !defined(UNDER_CE)
  g_FileCodePage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
  #endif


  allocImp = g_Alloc;
  allocTempImp = g_Alloc;

  #ifdef UNDER_CE
  if (InFile_OpenW(&archiveStream.file, L"\test.7z"))
  #else
  if (InFile_Open(&archiveStream.file, args[2]))
  #endif
  {
    PrintError("can not open input file");
    return 1;
  }

  FileInStream_CreateVTable(&archiveStream);
  LookToRead2_CreateVTable(&lookStream, False);
  lookStream.buf = NULL;

  res = SZ_OK;

  {
    lookStream.buf = (Byte *)ISzAlloc_Alloc(&allocImp, kInputBufSize);
    if (!lookStream.buf)
      res = SZ_ERROR_MEM;
    else
    {
      lookStream.bufSize = kInputBufSize;
      lookStream.realStream = &archiveStream.vt;
      LookToRead2_Init(&lookStream);
    }
  }
    
  CrcGenerateTable();
    
  SzArEx_Init(&db);
    
  if (res == SZ_OK)
  {
    res = SzArEx_Open(&db, &lookStream.vt, &allocImp, &allocTempImp);
  }
  
  if (res == SZ_OK)
  {
    char *command = args[1];
    int listCommand = 0, testCommand = 0, fullPaths = 0;
    
    if (strcmp(command, "l") == 0) listCommand = 1;
    else if (strcmp(command, "t") == 0) testCommand = 1;
    else if (strcmp(command, "e") == 0) { }
    else if (strcmp(command, "x") == 0) { fullPaths = 1; }
    else
    {
      PrintError("incorrect command");
      res = SZ_ERROR_FAIL;
    }

    if (res == SZ_OK)
    {
      UInt32 i;

      /*
      if you need cache, use these 3 variables.
      if you use external function, you can make these variable as static.
      */
      UInt32 blockIndex = 0xFFFFFFFF; /* it can have any value before first call (if outBuffer = 0) */
      Byte *outBuffer = 0; /* it must be 0 before first call for each new archive. */
      size_t outBufferSize = 0;  /* it can have any value before first call (if outBuffer = 0) */

      for (i = 0; i < db.NumFiles; i++)
      {
        size_t offset = 0;
        size_t outSizeProcessed = 0;
        // const CSzFileItem *f = db.Files + i;
        size_t len;
        unsigned isDir = SzArEx_IsDir(&db, i);
        if (listCommand == 0 && isDir && !fullPaths)
          continue;
        len = SzArEx_GetFileNameUtf16(&db, i, NULL);
        // len = SzArEx_GetFullNameLen(&db, i);

        if (len > tempSize)
        {
          SzFree(NULL, temp);
          tempSize = len;
          temp = (UInt16 *)SzAlloc(NULL, tempSize * sizeof(temp[0]));
          if (!temp)
          {
            res = SZ_ERROR_MEM;
            break;
          }
        }

        SzArEx_GetFileNameUtf16(&db, i, temp);
        /*
        if (SzArEx_GetFullNameUtf16_Back(&db, i, temp + len) != temp)
        {
          res = SZ_ERROR_FAIL;
          break;
        }
        */

        if (listCommand)
        {
          char attr[8], s[32], t[32];
          UInt64 fileSize;

          GetAttribString(SzBitWithVals_Check(&db.Attribs, i) ? db.Attribs.Vals[i] : 0, isDir, attr);

          fileSize = SzArEx_GetFileSize(&db, i);
          UInt64ToStr(fileSize, s, 10);
          
          if (SzBitWithVals_Check(&db.MTime, i))
            ConvertFileTimeToString(&db.MTime.Vals[i], t);
          else
          {
            size_t j;
            for (j = 0; j < 19; j++)
              t[j] = ' ';
            t[j] = '\0';
          }
          
          Print(t);
          Print(" ");
          Print(attr);
          Print(" ");
          Print(s);
          Print("  ");
          res = PrintString(temp);
          if (res != SZ_OK)
            break;
          if (isDir)
            Print("/");
          PrintLF();
          continue;
        }

        Print(testCommand ?
            "Testing    ":
            "Extracting ");
        res = PrintString(temp);
        if (res != SZ_OK)
          break;
        
        if (isDir)
          Print("/");
        else
        {
          res = SzArEx_Extract(&db, &lookStream.vt, i,
              &blockIndex, &outBuffer, &outBufferSize,
              &offset, &outSizeProcessed,
              &allocImp, &allocTempImp);
          if (res != SZ_OK)
            break;
        }
        
        if (!testCommand)
        {
          CSzFile outFile;
          size_t processedSize;
          size_t j;
          UInt16 *name = (UInt16 *)temp;
          const UInt16 *destPath = (const UInt16 *)name;
 
          for (j = 0; name[j] != 0; j++)
            if (name[j] == '/')
            {
              if (fullPaths)
              {
                name[j] = 0;
                MyCreateDir(name);
                name[j] = CHAR_PATH_SEPARATOR;
              }
              else
                destPath = name + j + 1;
            }
    
          if (isDir)
          {
            MyCreateDir(destPath);
            PrintLF();
            continue;
          }
          else if (OutFile_OpenUtf16(&outFile, destPath))
          {
            PrintError("can not open output file");
            res = SZ_ERROR_FAIL;
            break;
          }

          processedSize = outSizeProcessed;
          
          if (File_Write(&outFile, outBuffer + offset, &processedSize) != 0 || processedSize != outSizeProcessed)
          {
            PrintError("can not write output file");
            res = SZ_ERROR_FAIL;
            break;
          }

          #ifdef USE_WINDOWS_FILE
          {
            FILETIME mtime, ctime;
            FILETIME *mtimePtr = NULL;
            FILETIME *ctimePtr = NULL;

            if (SzBitWithVals_Check(&db.MTime, i))
            {
              const CNtfsFileTime *t = &db.MTime.Vals[i];
              mtime.dwLowDateTime = (DWORD)(t->Low);
              mtime.dwHighDateTime = (DWORD)(t->High);
              mtimePtr = &mtime;
            }
            if (SzBitWithVals_Check(&db.CTime, i))
            {
              const CNtfsFileTime *t = &db.CTime.Vals[i];
              ctime.dwLowDateTime = (DWORD)(t->Low);
              ctime.dwHighDateTime = (DWORD)(t->High);
              ctimePtr = &ctime;
            }
            if (mtimePtr || ctimePtr)
              SetFileTime(outFile.handle, ctimePtr, NULL, mtimePtr);
          }
          #endif
          
          if (File_Close(&outFile))
          {
            PrintError("can not close output file");
            res = SZ_ERROR_FAIL;
            break;
          }
          
          #ifdef USE_WINDOWS_FILE
          if (SzBitWithVals_Check(&db.Attribs, i))
          {
            UInt32 attrib = db.Attribs.Vals[i];
            /* p7zip stores posix attributes in high 16 bits and adds 0x8000 as marker.
               We remove posix bits, if we detect posix mode field */
            if ((attrib & 0xF0000000) != 0)
              attrib &= 0x7FFF;
            SetFileAttributesW((LPCWSTR)destPath, attrib);
          }
          #endif
        }
        PrintLF();
      }
      ISzAlloc_Free(&allocImp, outBuffer);
    }
  }

  SzFree(NULL, temp);
  SzArEx_Free(&db, &allocImp);
  ISzAlloc_Free(&allocImp, lookStream.buf);

  File_Close(&archiveStream.file);
  
  if (res == SZ_OK)
  {
    Print("\nEverything is Ok\n");
    return 0;
  }
  
  if (res == SZ_ERROR_UNSUPPORTED)
    PrintError("decoder doesn't support this archive");
  else if (res == SZ_ERROR_MEM)
    PrintError("can not allocate memory");
  else if (res == SZ_ERROR_CRC)
    PrintError("CRC error");
  else
  {
    char s[32];
    UInt64ToStr(res, s, 0);
    PrintError(s);
  }
  
  return 1;
}
예제 #16
0
파일: qt7zpackage.cpp 프로젝트: vmille/Qt7z
bool Qt7zPackage::open()
{
    if (m_p->m_isOpen) {
        return false;
    }

    SRes res;
    UInt16 *temp = NULL;
    size_t tempSize = 0;

    if (InFile_Open(&(m_p->m_archiveStream.file),
                    m_p->m_packagePath.toUtf8().data())) {
        qDebug() << "Can not open file: " << m_p->m_packagePath;
        m_p->m_isOpen = false;
        return false;
    }

    FileInStream_CreateVTable(&(m_p->m_archiveStream));
    LookToRead_CreateVTable(&(m_p->m_lookStream), False);

    m_p->m_lookStream.realStream = &(m_p->m_archiveStream.s);
    LookToRead_Init(&(m_p->m_lookStream));

    CrcGenerateTable();

    SzArEx_Init(&(m_p->m_db));
    res = SzArEx_Open(&(m_p->m_db), &(m_p->m_lookStream.s),
                      &(m_p->m_allocImp), &(m_p->m_allocTempImp));

    if (res == SZ_OK) {
        for (UInt32 i = 0; i < m_p->m_db.db.NumFiles; i++) {
            size_t len = SzArEx_GetFileNameUtf16(&(m_p->m_db), i, NULL);

            if (len > tempSize) {
                SzFree(NULL, temp);
                tempSize = len;
                temp = (UInt16 *)SzAlloc(NULL, tempSize * sizeof(temp[0]));
                if (temp == 0) {
                    res = SZ_ERROR_MEM;
                    break;
                }
            }

            SzArEx_GetFileNameUtf16(&(m_p->m_db), i, temp);

            // TODO: Codec?
            QString fileName = QString::fromUtf16(temp);
            m_p->m_fileNameList << fileName;

            const CSzFileItem &fileItem = m_p->m_db.db.Files[i];
            Qt7zFileInfo fileInfo;
            fileInfo.fileName = fileName;
            fileInfo.arcName = m_p->m_packagePath;
            fileInfo.size = fileItem.Size;
            fileInfo.isDir = fileItem.IsDir;
            fileInfo.isCrcDefined = fileItem.CrcDefined;
            fileInfo.crc = fileItem.Crc;
            m_p->m_fileInfoList << fileInfo;

            if (res != SZ_OK)
                break;
        }
    }

    SzFree(NULL, temp);

    if (res == SZ_OK) {
        m_p->m_isOpen = true;
        return true;
    } else {
        m_p->m_isOpen = false;
        return false;
    }
}
예제 #17
0
파일: vfs-lzma.c 프로젝트: ikeboy/mgba
struct VFile* _vd7zOpenFile(struct VDir* vd, const char* path, int mode) {
	UNUSED(mode);
	// TODO: support truncating, appending and creating, and write
	struct VDir7z* vd7z = (struct VDir7z*) vd;

	if ((mode & O_RDWR) == O_RDWR) {
		// Read/Write support is not yet implemented.
		return 0;
	}

	if (mode & O_WRONLY) {
		// Write support is not yet implemented.
		return 0;
	}

	size_t pathLength = strlen(path);

	UInt32 i;
	for (i = 0; i < vd7z->db.NumFiles; ++i) {
		if (SzArEx_IsDir(&vd7z->db, i)) {
			continue;
		}
		size_t nameLength = SzArEx_GetFileNameUtf16(&vd7z->db, i, 0) * sizeof(UInt16);
		UInt16* name = malloc(nameLength);
		SzArEx_GetFileNameUtf16(&vd7z->db, i, name);

		if (utfcmp(name, path, nameLength - sizeof(UInt16), pathLength) == 0) {
			free(name);
			break;
		}

		free(name);
	}

	if (i == vd7z->db.NumFiles) {
		return 0; // No file found
	}

	struct VFile7z* vf = malloc(sizeof(struct VFile7z));
	vf->vd = vd7z;

	size_t outBufferSize;
	UInt32 blockIndex;

	vf->outBuffer = 0;
	SRes res = SzArEx_Extract(&vd7z->db, &vd7z->lookStream.s, i, &blockIndex,
		&vf->outBuffer, &outBufferSize,
		&vf->bufferOffset, &vf->size,
		&vd7z->allocImp, &vd7z->allocTempImp);

	if (res != SZ_OK) {
		free(vf);
		return 0;
	}

	vf->d.close = _vf7zClose;
	vf->d.seek = _vf7zSeek;
	vf->d.read = _vf7zRead;
	vf->d.readline = VFileReadline;
	vf->d.write = _vf7zWrite;
	vf->d.map = _vf7zMap;
	vf->d.unmap = _vf7zUnmap;
	vf->d.truncate = _vf7zTruncate;
	vf->d.size = _vf7zSize;

	return &vf->d;
}
예제 #18
0
파일: content.c 프로젝트: jwarby/RetroArch
/* Extract the relative path (needle) from a 7z archive 
 * (path) and allocate a buf for it to write it in.
 * If optional_outfile is set, extract to that instead 
 * and don't allocate buffer.
 */
static int content_7zip_file_read(
      const char *path,
      const char *needle, void **buf,
      const char *optional_outfile)
{
   CFileInStream archiveStream;
   CLookToRead lookStream;
   CSzArEx db;
   ISzAlloc allocImp;
   ISzAlloc allocTempImp;
   uint8_t *output      = 0;
   long outsize         = -1;

   /*These are the allocation routines.
    * Currently using the non-standard 7zip choices. */
   allocImp.Alloc       = SzAlloc;
   allocImp.Free        = SzFree;
   allocTempImp.Alloc   = SzAllocTemp;
   allocTempImp.Free    = SzFreeTemp;

   if (InFile_Open(&archiveStream.file, path))
   {
      RARCH_ERR("Could not open %s as 7z archive\n.", path);
      return -1;
   }

   FileInStream_CreateVTable(&archiveStream);
   LookToRead_CreateVTable(&lookStream, False);
   lookStream.realStream = &archiveStream.s;
   LookToRead_Init(&lookStream);
   CrcGenerateTable();
   SzArEx_Init(&db);

   if (SzArEx_Open(&db, &lookStream.s, &allocImp, &allocTempImp) == SZ_OK)
   {
      uint32_t i;
      bool file_found      = false;
      uint16_t *temp       = NULL;
      size_t temp_size     = 0;
      uint32_t block_index = 0xFFFFFFFF;
      SRes res             = SZ_OK;

      for (i = 0; i < db.db.NumFiles; i++)
      {
         size_t len;
         char infile[PATH_MAX_LENGTH];
         size_t offset           = 0;
         size_t outSizeProcessed = 0;
         const CSzFileItem    *f = db.db.Files + i;

         /* We skip over everything which is not a directory. 
          * FIXME: Why continue then if f->IsDir is true?*/
         if (f->IsDir)
            continue;

         len = SzArEx_GetFileNameUtf16(&db, i, NULL);

         if (len > temp_size)
         {
            free(temp);
            temp_size = len;
            temp = (uint16_t *)malloc(temp_size * sizeof(temp[0]));

            if (temp == 0)
            {
               res = SZ_ERROR_MEM;
               break;
            }
         }

         SzArEx_GetFileNameUtf16(&db, i, temp);
         res = utf16_to_char_string(temp, infile, sizeof(infile)) 
            ? SZ_OK : SZ_ERROR_FAIL;

         if (string_is_equal(infile, needle))
         {
            size_t output_size   = 0;

            RARCH_LOG_OUTPUT("Opened archive %s. Now trying to extract %s\n",
                  path, needle);

            /* C LZMA SDK does not support chunked extraction - see here:
             * sourceforge.net/p/sevenzip/discussion/45798/thread/6fb59aaf/
             * */
            file_found = true;
            res = SzArEx_Extract(&db, &lookStream.s, i, &block_index,
                  &output, &output_size, &offset, &outSizeProcessed,
                  &allocImp, &allocTempImp);

            if (res != SZ_OK)
               break; /* This goes to the error section. */

            outsize = outSizeProcessed;
            
            if (optional_outfile != NULL)
            {
               const void *ptr = (const void*)(output + offset);

               if (!retro_write_file(optional_outfile, ptr, outsize))
               {
                  RARCH_ERR("Could not open outfilepath %s.\n",
                        optional_outfile);
                  res        = SZ_OK;
                  file_found = true;
                  outsize    = -1;
               }
            }
            else
            {
               /*We could either use the 7Zip allocated buffer,
                * or create our own and use it.
                * We would however need to realloc anyways, because RetroArch
                * expects a \0 at the end, therefore we allocate new,
                * copy and free the old one. */
               *buf = malloc(outsize + 1);
               ((char*)(*buf))[outsize] = '\0';
               memcpy(*buf,output + offset,outsize);
            }
            break;
         }
      }

      free(temp);
      IAlloc_Free(&allocImp, output);

      if (!(file_found && res == SZ_OK))
      {
         /* Error handling */
         if (!file_found)
            RARCH_ERR("File %s not found in %s\n", needle, path);

         RARCH_ERR("Failed to open compressed file inside 7zip archive.\n");

         outsize    = -1;
      }
   }

   SzArEx_Free(&db, &allocImp);
   File_Close(&archiveStream.file);

   return outsize;
}
예제 #19
0
파일: 7zlib.cpp 프로젝트: jwtab/dxlogin
	int SzExtractFromBuf(const void* pBuf, unsigned int nBufLength, wchar_t* cUnPackPath, DWORD dwPathLength)
	{
		if(pBuf==NULL || nBufLength<=0)
			return 1;

		SRes res = SZ_OK;
		CBufInStream archiveStream;
		CLookToRead lookStream;
		CSzArEx db;
		ISzAlloc allocImp;
		ISzAlloc allocTempImp;
		const char *errorMessage = NULL;

		wchar_t path[MAX_PATH * 3 + 2] = {0};
		size_t pathLen = wcslen(cUnPackPath);
		wcscpy_s(path,MAX_PATH * 3 + 2, cUnPackPath);

		if (cUnPackPath[pathLen - 1] != '\\') 
		{ 
			wcscat_s(path, L"\\");
			pathLen = wcslen(path);
		}


		CrcGenerateTable();

		allocImp.Alloc = SzAlloc;
		allocImp.Free = SzFree;

		allocTempImp.Alloc = SzAllocTemp;
		allocTempImp.Free = SzFreeTemp;

		BufInStream_CreateVTable(&archiveStream);
		LookToRead_CreateVTable(&lookStream, False);

		
		if (InBuf_Init(&archiveStream.buf, pBuf, nBufLength) != 0)
		{
			errorMessage = "can not open input file";
			res = SZ_ERROR_FAIL;
		}
		else
		{
			UInt64 pos = 0;
			if (!FindSignature(&archiveStream.buf, &pos))
				res = SZ_ERROR_FAIL;
			else if (InBuf_Seek(&archiveStream.buf, (Int64 *)&pos, SZ_SEEK_SET) != 0)
				res = SZ_ERROR_FAIL;
			if (res != 0)
				errorMessage = "Can't find 7z archive";
		}

		if (res == SZ_OK)
		{
			lookStream.realStream = &archiveStream.s;
			LookToRead_Init(&lookStream);
		}

		SzArEx_Init(&db);
		if (res == SZ_OK)
		{
			res = SzArEx_Open(&db, &lookStream.s, &allocImp, &allocTempImp);
		}
		if (res == SZ_OK)
		{
			UInt32 executeFileIndex = (UInt32)(Int32)-1;
			UInt32 minPrice = 1 << 30;
			UInt32 i;
			UInt32 blockIndex = 0xFFFFFFFF; /* it can have any value before first call (if outBuffer = 0) */
			Byte *outBuffer = 0; /* it must be 0 before first call for each new archive. */
			size_t outBufferSize = 0;  /* it can have any value before first call (if outBuffer = 0) */

			for (i = 0; i < db.db.NumFiles; i++)
			{
				size_t offset = 0;
				size_t outSizeProcessed = 0;
				const CSzFileItem *f = db.db.Files + i;
				size_t len;
				wchar_t *temp;
				len = SzArEx_GetFileNameUtf16(&db, i, NULL);

				if (len >= MAX_PATH)
				{
					res = SZ_ERROR_FAIL;
					break;
				}

				temp = path + pathLen;

				SzArEx_GetFileNameUtf16(&db, i, reinterpret_cast<UInt16*>(temp));
				{
					res = SzArEx_Extract(&db, &lookStream.s, i,
						&blockIndex, &outBuffer, &outBufferSize,
						&offset, &outSizeProcessed,
						&allocImp, &allocTempImp);
					if (res != SZ_OK)
						break;
				}
				{
					CSzFile outFile;
					size_t processedSize;
					size_t j;
					size_t nameStartPos = 0;
					for (j = 0; temp[j] != 0; j++)
					{
						if (temp[j] == '/')
						{
							temp[j] = 0;
							MyCreateDir(path);
							temp[j] = CHAR_PATH_SEPARATOR;
							nameStartPos = j + 1;
						}
					}

					if (f->IsDir)
					{
						MyCreateDir(path);
						continue;
					}
					else
					{

						if (DoesFileOrDirExist(path))
						{
							errorMessage = "Duplicate file";
							res = SZ_ERROR_FAIL;
							break;
						}
						if (OutFile_OpenW(&outFile, path))
						{
							errorMessage = "Can't open output file";
							res = SZ_ERROR_FAIL;
							break;
						}
					}
					processedSize = outSizeProcessed;
					if (File_Write(&outFile, outBuffer + offset, &processedSize) != 0 || processedSize != outSizeProcessed)
					{
						errorMessage = "Can't write output file";
						res = SZ_ERROR_FAIL;
					}

#ifdef USE_WINDOWS_FILE
					if (f->MTimeDefined)
					{
						FILETIME mTime;
						mTime.dwLowDateTime = f->MTime.Low;
						mTime.dwHighDateTime = f->MTime.High;
						SetFileTime(outFile.handle, NULL, NULL, &mTime);
					}
#endif

					{
						SRes res2 = File_Close(&outFile);
						if (res != SZ_OK)
							break;
						if (res2 != SZ_OK)
						{
							res = res2;
							break;
						}
					}
#ifdef USE_WINDOWS_FILE
					if (f->AttribDefined)
						SetFileAttributesW(path, f->Attrib);
#endif
				}
			}
			IAlloc_Free(&allocImp, outBuffer);
		}
		SzArEx_Free(&db, &allocImp);

		if (res == SZ_OK)
		{
			_tcscpy_s(cUnPackPath, dwPathLength, path);
			return 0;
		}
		else
			return 1;
	}
예제 #20
0
파일: file_7z.cpp 프로젝트: Jarvizx/gz3doom
bool F7ZFile::Open(bool quiet)
{
	Archive = new C7zArchive(Reader);
	int skipped = 0;
	SRes res;

	res = Archive->Open();
	if (res != SZ_OK)
	{
		delete Archive;
		Archive = NULL;
		if (!quiet)
		{
			Printf("\n" TEXTCOLOR_RED "%s: ", Filename);
			if (res == SZ_ERROR_UNSUPPORTED)
			{
				Printf("Decoder does not support this archive\n");
			}
			else if (res == SZ_ERROR_MEM)
			{
				Printf("Cannot allocate memory\n");
			}
			else if (res == SZ_ERROR_CRC)
			{
				Printf("CRC error\n");
			}
			else
			{
				Printf("error #%d\n", res);
			}
		}
		return false;
	}
	NumLumps = Archive->DB.db.NumFiles;

	Lumps = new F7ZLump[NumLumps];

	F7ZLump *lump_p = Lumps;
	TArray<UInt16> nameUTF16;
	TArray<char> nameASCII;
	for (DWORD i = 0; i < NumLumps; ++i)
	{
		CSzFileItem *file = &Archive->DB.db.Files[i];

		// skip Directories
		if (file->IsDir)
		{
			skipped++;
			continue;
		}

		const size_t nameLength = SzArEx_GetFileNameUtf16(&Archive->DB, i, NULL);

		if (0 == nameLength)
		{
			++skipped;
			continue;
		}

		nameUTF16.Resize(nameLength);
		nameASCII.Resize(nameLength);
		SzArEx_GetFileNameUtf16(&Archive->DB, i, &nameUTF16[0]);
		for (size_t c = 0; c < nameLength; ++c)
		{
			nameASCII[c] = static_cast<char>(nameUTF16[c]);
		}
		FixPathSeperator(&nameASCII[0]);

		FString name = &nameASCII[0];
		name.ToLower();

		lump_p->LumpNameSetup(name);
		lump_p->LumpSize = int(file->Size);
		lump_p->Owner = this;
		lump_p->Flags = LUMPF_ZIPFILE;
		lump_p->Position = i;
		lump_p->CheckEmbedded();
		lump_p++;
	}
	// Resize the lump record array to its actual size
	NumLumps -= skipped;

	if (NumLumps > 0)
	{
		// Quick check for unsupported compression method

		TArray<char> temp;
		temp.Resize(Lumps[0].LumpSize);

		if (SZ_OK != Archive->Extract(Lumps[0].Position, &temp[0]))
		{
			if (!quiet) Printf("\n%s: unsupported 7z/LZMA file!\n", Filename);
			return false;
		}
	}

	if (!quiet) Printf(", %d lumps\n", NumLumps);

	// Entries in archives are sorted alphabetically
	qsort(&Lumps[0], NumLumps, sizeof(F7ZLump), lumpcmp);
	return true;
}
예제 #21
0
		/*!
		 * \brief
		 * Decompresses a single file from a 7zip archive.
		 * 
		 * \param archive_file
		 * Path to the archive to extract the file from.
		 * 
		 * \param file_name
		 * The fine within the archive to extract.
		 * 
		 * \param uncompressed_data
		 * Reference parameter to set the uncompressed datas pointer to.
		 * 
		 * \param uncompressed_data_size
		 * Reference parameter to set the uncompressed data size to.
		 * 
		 * \returns
		 * Returns true if the decompresseion was successfull, otherwise returns false.
		 * 
		 * Decompresses a single file from a 7zip archive.
		 */
		bool DecompressFileEntry(cstring archive_file,
			cstring file_name,
			byte*& uncompressed_data,
			size_t& uncompressed_data_size)
		{
			CFileInStream archive_stream;
			CLookToRead look_stream;
			CSzArEx archive_desc;
			SRes result;
			ISzAlloc alloc_imp;
			wchar_t wide_file_name[MAX_PATH] = L"";

			// open the archive for reading
			if (InFile_Open(&archive_stream.file, archive_file))
				return false;

			// convert the search file name to a wide char string for comparison later
			if(-1 == swprintf_s(wide_file_name, MAX_PATH, L"%S", file_name))
				return false;

			// set up the memory handling functions
			alloc_imp.Alloc = AllocFunc;
			alloc_imp.Free = FreeFunc;

			FileInStream_CreateVTable(&archive_stream);
			LookToRead_CreateVTable(&look_stream, False);

			look_stream.realStream = &archive_stream.s;
			LookToRead_Init(&look_stream);

			CrcGenerateTable();

			SzArEx_Init(&archive_desc);
			result = SzArEx_Open(&archive_desc, &look_stream.s, &alloc_imp, &alloc_imp);

			if(result == SZ_OK)
			{
				int index = -1;
				// search for the file in the archive
				for (uint32 i = 0; (index == -1) && (i < archive_desc.db.NumFiles); i++)
				{
					if(archive_desc.db.Files[i].IsDir)
						continue;

					// get the name of the file in the archive
					uint32 name_length = SzArEx_GetFileNameUtf16(&archive_desc, i, NULL);
					wchar_t* archive_file_name = new wchar_t[name_length];
					SzArEx_GetFileNameUtf16(&archive_desc, i, (UInt16*)archive_file_name);

					// compare the file names
					if(wcscmp(wide_file_name, archive_file_name) == 0)
						index = i;

					// delete allocated memory
					delete [] archive_file_name;
				}

				if(index > -1)
				{
					// file found, so decompress it
					result = Decompress(archive_stream,
						archive_desc,
						look_stream,
						index,
						uncompressed_data,
						uncompressed_data_size);
				}
			}

			SzArEx_Free(&archive_desc, &alloc_imp);

			File_Close(&archive_stream.file);

			return result == SZ_OK;
		}