예제 #1
0
파일: fileform.c 프로젝트: Argimko/Nsis64
const TCHAR * NSISCALL loadHeaders(int cl_flags)
{
  __int64 left;
#ifdef NSIS_CONFIG_CRC_SUPPORT
  crc32_t crc = 0;
  int do_crc = 0;
#endif//NSIS_CONFIG_CRC_SUPPORT

  void *data;
  firstheader h;
  header *header;
  dataheader dh;

  HANDLE db_hFile;

#ifdef NSIS_CONFIG_CRC_SUPPORT
#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
  verify_time = GetTickCount() + 1000;
#endif
#endif//NSIS_CONFIG_CRC_SUPPORT

  GetModuleFileName(NULL, state_exe_path, NSIS_MAX_STRLEN);

  g_db_hFile = db_hFile = myOpenFile(state_exe_path, GENERIC_READ, OPEN_EXISTING);
  if (db_hFile == INVALID_HANDLE_VALUE)
  {
    return _LANG_CANTOPENSELF;
  }

  mystrcpy(state_exe_directory, state_exe_path);
  mystrcpy(state_exe_file, trimslashtoend(state_exe_directory));

  GetFileSizeEx(db_hFile, (LARGE_INTEGER*)&m_length);
  left = m_length;
  while (left > 0)
  {
    static char temp[32768*32]; // modified by yew: for fast crc
    DWORD l = min(left, (g_filehdrsize ? sizeof(temp) : 512));
    if (!ReadSelfFile(temp, l))
    {
#if defined(NSIS_CONFIG_CRC_SUPPORT) && defined(NSIS_CONFIG_VISIBLE_SUPPORT)
      handle_ver_dlg(TRUE);
#endif//NSIS_CONFIG_CRC_SUPPORT
      return _LANG_INVALIDCRC;
    }

    if (!g_filehdrsize)
    {
      mini_memcpy(&h, temp, sizeof(firstheader));
      if (
           (h.flags & (~FH_FLAGS_MASK)) == 0 &&
           h.siginfo == FH_SIG &&
           h.nsinst[2] == FH_INT3 &&
           h.nsinst[1] == FH_INT2 &&
           h.nsinst[0] == FH_INT1
         )
      {
        g_filehdrsize = m_pos;

#if defined(NSIS_CONFIG_CRC_SUPPORT) || defined(NSIS_CONFIG_SILENT_SUPPORT)
        cl_flags |= h.flags;
#endif

#ifdef NSIS_CONFIG_SILENT_SUPPORT
        g_exec_flags.silent |= cl_flags & FH_FLAGS_SILENT;
#endif

        if (h.length_of_all_following_data > left)
          return _LANG_INVALIDCRC;

#ifdef NSIS_CONFIG_CRC_SUPPORT
        if ((cl_flags & FH_FLAGS_FORCE_CRC) == 0)
        {
          if (cl_flags & FH_FLAGS_NO_CRC)
            break;
        }

        do_crc++;

#ifndef NSIS_CONFIG_CRC_ANAL
        left = h.length_of_all_following_data - 4;
        // end crc checking at crc :) this means you can tack stuff on the end and it'll still work.
#else //!NSIS_CONFIG_CRC_ANAL
        left -= 4;
#endif//NSIS_CONFIG_CRC_ANAL
        // this is in case the end part is < 512 bytes.
        if (l > left) l=left;

#else//!NSIS_CONFIG_CRC_SUPPORT
        // no crc support, no need to keep on reading
        break;
#endif//!NSIS_CONFIG_CRC_SUPPORT
      }
    }
#ifdef NSIS_CONFIG_CRC_SUPPORT

#ifdef NSIS_CONFIG_VISIBLE_SUPPORT

#ifdef NSIS_CONFIG_SILENT_SUPPORT
    else if ((cl_flags & FH_FLAGS_SILENT) == 0)
#endif//NSIS_CONFIG_SILENT_SUPPORT
    {
      handle_ver_dlg(FALSE);
    }
#endif//NSIS_CONFIG_VISIBLE_SUPPORT

#ifndef NSIS_CONFIG_CRC_ANAL
    if (left < m_length)
#endif//NSIS_CONFIG_CRC_ANAL
      crc = CRC32(crc, (unsigned char*)temp, l);

#endif//NSIS_CONFIG_CRC_SUPPORT
    m_pos += l;
    left -= l;
  }
#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
#ifdef NSIS_CONFIG_CRC_SUPPORT
  handle_ver_dlg(TRUE);
#endif//NSIS_CONFIG_CRC_SUPPORT
#endif//NSIS_CONFIG_VISIBLE_SUPPORT
  if (!g_filehdrsize)
    return _LANG_INVALIDCRC;

#ifdef NSIS_CONFIG_CRC_SUPPORT
  if (do_crc)
  {
    crc32_t fcrc;
    SetSelfFilePointer(m_pos);
    if (!ReadSelfFile(&fcrc, sizeof(crc32_t)) || crc != fcrc)
      return _LANG_INVALIDCRC;
  }
#endif//NSIS_CONFIG_CRC_SUPPORT

  data = (void *)GlobalAlloc(GPTR,h.length_of_header);

#ifdef NSIS_COMPRESS_WHOLE
  inflateReset(&g_inflate_stream);

  {
    TCHAR fno[MAX_PATH];
    my_GetTempFileName(fno, state_temp_dir);
    dbd_hFile=CreateFile(fno,GENERIC_WRITE|GENERIC_READ,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_TEMPORARY|FILE_FLAG_DELETE_ON_CLOSE,NULL);
    if (dbd_hFile == INVALID_HANDLE_VALUE)
      return _LANG_ERRORWRITINGTEMP;
  }
  dbd_srcpos = SetSelfFilePointer(g_filehdrsize + sizeof(firstheader));
#ifdef NSIS_CONFIG_CRC_SUPPORT
  dbd_fulllen = dbd_srcpos - sizeof(h) + h.length_of_all_following_data - ((h.flags & FH_FLAGS_NO_CRC) ? 0 : sizeof(crc32_t));
#else
  dbd_fulllen = dbd_srcpos - sizeof(h) + h.length_of_all_following_data;
#endif//NSIS_CONFIG_CRC_SUPPORT
#else
  SetSelfFilePointer(g_filehdrsize + sizeof(firstheader));
#endif//NSIS_COMPRESS_WHOLE

  if (GetCompressedDataFromDataBlockToMemory(-1, data, h.length_of_header) != h.length_of_header)
  {
    return _LANG_INVALIDCRC;
  }

  header = g_header = data;

  g_flags = header->flags;

#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
  if (h.flags & FH_FLAGS_UNINSTALL)
    g_is_uninstaller++;
#endif

  // set offsets to real memory offsets rather than installer's header offset
  left = BLOCKS_NUM;
  while (left--)
    header->blocks[left].offset += (int)data;

  m_file_mapping.first = NULL;
  m_file_mapping.cur = NULL;
  m_file_mapping.LoadFinished = FALSE;

#ifdef NSIS_COMPRESS_WHOLE
  header->blocks[NB_DATA].offset = dbd_pos;
#else
  if (h.flags & FH_FLAGS_DATA_FILE)
  {
	  LPTSTR psz,psz2;
	  int cur_index= 1;
	  __int64 length;
	  while(1)
	  {
		  CloseHandle(g_db_hFile);
		  mystrcpy(m_data_file_path, state_exe_directory);
		  mystrcat(m_data_file_path, _T("\\setup-.bin"));
		  psz =_tcsrchr(m_data_file_path,'\\');
		  if (psz==NULL) psz=m_data_file_path;
		  while (psz2=_tcschr(psz+1,'.'))
		  {
			  psz = psz2;
		  }
		  wsprintf(psz,_T("%u.bin"),cur_index);
		  g_db_hFile = db_hFile = myOpenFile(m_data_file_path, GENERIC_READ, OPEN_EXISTING);
		  if (db_hFile == INVALID_HANDLE_VALUE)
		  {
			  return _LANG_CANTOPENSELF;
		  }
		  if (!ReadSelfFile(&dh, sizeof(dh)))
		  {// read out the data file header
			  return _LANG_INVALIDCRC;
		  }	
		  if (cur_index==1)
		  {
			 m_length = dh.total_length;
		  }
		  if (!GetFileSizeEx(db_hFile,(LARGE_INTEGER*)&length) || length!=dh.length+sizeof(dataheader) || dh.volume_index!=cur_index)
		  {// check the whole file length
			  return _LANG_INVALIDCRC;
		  }
		  if (m_file_mapping.first==NULL)
		  {// it's the first time to meet a data file
			  m_file_mapping.cur = GlobalAlloc(GPTR,sizeof(struct FileMapping));
			  m_file_mapping.first = m_file_mapping.cur;
		  }
		  else
		  {// push the new data file to the end, and replace the current one
			  m_file_mapping.cur->next = GlobalAlloc(GPTR,sizeof(struct FileMapping));
			  m_file_mapping.cur = m_file_mapping.cur->next;
		  }
		  mini_memcpy(&m_file_mapping.cur->dh,&dh,sizeof(dh));
		  m_file_mapping.cur->next = NULL;
#ifdef NSIS_CONFIG_CRC_SUPPORT
		  if (do_crc)
		  {
			  __int64 cur_length= 0;
			  crc = 0;
			  while (cur_length<dh.length)
			  {
				  static char temp[32768*32]; // modified by yew: for fast crc
				  DWORD l = min(dh.length-cur_length, sizeof(temp));
				  if (!ReadSelfFile(temp, l))
				  {
#if defined(NSIS_CONFIG_VISIBLE_SUPPORT)
					  handle_ver_dlg(TRUE);
#endif
					  return _LANG_INVALIDCRC;
				  }
#ifdef NSIS_CONFIG_VISIBLE_SUPPORT

#ifdef NSIS_CONFIG_SILENT_SUPPORT
				  if ((cl_flags & FH_FLAGS_SILENT) == 0)
#endif//NSIS_CONFIG_SILENT_SUPPORT
				  {
					  handle_ver_dlg(FALSE);
				  }
#endif//NSIS_CONFIG_VISIBLE_SUPPORT

				  crc = CRC32(crc, (unsigned char*)temp, l);

				  m_pos += l;
				  cur_length += l;
			  }
			  if (dh.crc != crc)
				  return _LANG_INVALIDCRC;
		  }
#endif//NSIS_CONFIG_CRC_SUPPORT
		  if (cur_index<dh.total_volume)
			  cur_index++;// need to check next file
		  else
			  break;
	  }
#ifdef NSIS_CONFIG_CRC_SUPPORT
	  if (do_crc)
	  {
#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
		  handle_ver_dlg(TRUE);
#endif//NSIS_CONFIG_VISIBLE_SUPPORT
	  }
#endif//NSIS_CONFIG_CRC_SUPPORT
	  // re-open the first file
	  if (cur_index!=1)
	  {
		  CloseHandle(g_db_hFile);
		  mystrcpy(m_data_file_path, state_exe_directory);
		  mystrcat(m_data_file_path, _T("\\setup-.bin"));
		  psz =_tcsrchr(m_data_file_path,'\\');
		  if (psz==NULL) psz=m_data_file_path;
		  while (psz2=_tcschr(psz+1,'.'))
		  {
			  psz = psz2;
		  }
		  wsprintf(psz,_T("%u.bin"),1);
		  g_db_hFile = db_hFile = myOpenFile(m_data_file_path, GENERIC_READ, OPEN_EXISTING);
	  }
	  m_file_mapping.cur = m_file_mapping.first;// reset the current mapping to the first one
	  m_file_mapping.LoadFinished = TRUE;// if there is no data file, keep it to be FALSE always
	  header->blocks[NB_DATA].offset = SetFilePointer(db_hFile,0,NULL,FILE_BEGIN);
	  m_file_mapping.cur_offset = 0;
	}
	header->blocks[NB_DATA].offset = SetFilePointer(db_hFile,0,NULL,FILE_CURRENT);
#endif

  mini_memcpy(&g_blocks, &header->blocks, sizeof(g_blocks));

  return 0;
}
예제 #2
0
파일: fileform.c 프로젝트: Argimko/Nsis64
static int NSISCALL __ensuredata(int amount)
{
  int needed=amount-(dbd_size-dbd_pos);
#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
  verify_time=GetTickCount()+500;
#endif
  if (needed>0)
  {
    SetSelfFilePointer(dbd_srcpos);
    SetFilePointerEx(dbd_hFile,(LARGE_INTEGER*)&dbd_size,NULL,FILE_BEGIN);
    m_length=needed;
    m_pos=0;
    for (;;)
    {
      int err;
      int l=min(IBUFSIZE,dbd_fulllen-dbd_srcpos);
      if (!ReadSelfFile((LPVOID)_inbuffer,l)) return -1;
      dbd_srcpos+=l;
      g_inflate_stream.next_in=_inbuffer;
      g_inflate_stream.avail_in=l;
      do
      {
        DWORD r,t;
#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
        if (g_header)
#ifdef NSIS_CONFIG_SILENT_SUPPORT
          if (!g_exec_flags.silent)
#endif
          {
            m_pos=m_length-(amount-(dbd_size-dbd_pos));

            handle_ver_dlg(FALSE);
          }
#endif//NSIS_CONFIG_VISIBLE_SUPPORT
        g_inflate_stream.next_out=_outbuffer;
        g_inflate_stream.avail_out=OBUFSIZE;
        err=inflate(&g_inflate_stream);
        if (err<0)
        {
          return -3;
        }
        r=(DWORD)g_inflate_stream.next_out-(DWORD)_outbuffer;
        if (r)
        {
          if (!WriteFile(dbd_hFile,_outbuffer,r,&t,NULL) || r != t)
          {
            return -2;
          }
          dbd_size+=r;
        }
        else if (g_inflate_stream.avail_in || !l) return -3;
        else break;
      }
      while (g_inflate_stream.avail_in);
      if (amount-(dbd_size-dbd_pos) <= 0) break;
    }
    SetFilePointerEx(dbd_hFile,(LARGE_INTEGER*)&dbd_pos,NULL,FILE_BEGIN);
  }
#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
  handle_ver_dlg(TRUE);
#endif//NSIS_CONFIG_VISIBLE_SUPPORT
  return 0;
}
예제 #3
0
파일: fileform.c 프로젝트: kichik/nsis-1
const TCHAR * NSISCALL loadHeaders(int cl_flags)
{
  int left;
#ifdef NSIS_CONFIG_CRC_SUPPORT
  crc32_t crc = 0;
  int do_crc = 0;
#endif//NSIS_CONFIG_CRC_SUPPORT

  void *data;
  firstheader h;
  header *header;

  HANDLE db_hFile;

#ifdef NSIS_CONFIG_CRC_SUPPORT
#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
  verify_time = GetTickCount() + 1000;
#endif
#endif//NSIS_CONFIG_CRC_SUPPORT

  GetModuleFileName(NULL, state_exe_path, NSIS_MAX_STRLEN);

  g_db_hFile = db_hFile = myOpenFile(state_exe_path, GENERIC_READ, OPEN_EXISTING);
  if (db_hFile == INVALID_HANDLE_VALUE)
  {
    return _LANG_CANTOPENSELF;
  }

  mystrcpy(state_exe_directory, state_exe_path);
  mystrcpy(state_exe_file, trimslashtoend(state_exe_directory));

  left = m_length = GetFileSize(db_hFile,NULL);
  while (left > 0)
  {
    static char temp[32768];
    DWORD l = min(left, (g_filehdrsize ? 32768 : 512));
    if (!ReadSelfFile(temp, l))
    {
#if defined(NSIS_CONFIG_CRC_SUPPORT) && defined(NSIS_CONFIG_VISIBLE_SUPPORT)
      handle_ver_dlg(TRUE);
#endif//NSIS_CONFIG_CRC_SUPPORT
      return _LANG_INVALIDCRC;
    }

    if (!g_filehdrsize)
    {
      mini_memcpy(&h, temp, sizeof(firstheader));
      if (
           (h.flags & (~FH_FLAGS_MASK)) == 0 &&
           h.siginfo == FH_SIG &&
           h.nsinst[2] == FH_INT3 &&
           h.nsinst[1] == FH_INT2 &&
           h.nsinst[0] == FH_INT1
         )
      {
        g_filehdrsize = m_pos;

#if defined(NSIS_CONFIG_CRC_SUPPORT) || defined(NSIS_CONFIG_SILENT_SUPPORT)
        cl_flags |= h.flags;
#endif

#ifdef NSIS_CONFIG_SILENT_SUPPORT
        g_exec_flags.silent |= cl_flags & FH_FLAGS_SILENT;
#endif

        if (h.length_of_all_following_data > left)
          return _LANG_INVALIDCRC;

#ifdef NSIS_CONFIG_CRC_SUPPORT
        if ((cl_flags & FH_FLAGS_FORCE_CRC) == 0)
        {
          if (cl_flags & FH_FLAGS_NO_CRC)
            break;
        }

        do_crc++;

#ifndef NSIS_CONFIG_CRC_ANAL
        left = h.length_of_all_following_data - 4;
        // end crc checking at crc :) this means you can tack stuff on the end and it'll still work.
#else //!NSIS_CONFIG_CRC_ANAL
        left -= 4;
#endif//NSIS_CONFIG_CRC_ANAL
        // this is in case the end part is < 512 bytes.
        if (l > (DWORD)left) l=(DWORD)left;

#else//!NSIS_CONFIG_CRC_SUPPORT
        // no crc support, no need to keep on reading
        break;
#endif//!NSIS_CONFIG_CRC_SUPPORT
      }
    }
#ifdef NSIS_CONFIG_CRC_SUPPORT

#ifdef NSIS_CONFIG_VISIBLE_SUPPORT

#ifdef NSIS_CONFIG_SILENT_SUPPORT
    else if ((cl_flags & FH_FLAGS_SILENT) == 0)
#endif//NSIS_CONFIG_SILENT_SUPPORT
    {
      handle_ver_dlg(FALSE);
    }
#endif//NSIS_CONFIG_VISIBLE_SUPPORT

#ifndef NSIS_CONFIG_CRC_ANAL
    if (left < m_length)
#endif//NSIS_CONFIG_CRC_ANAL
      crc = CRC32(crc, (unsigned char*)temp, l);

#endif//NSIS_CONFIG_CRC_SUPPORT
    m_pos += l;
    left -= l;
  }
#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
#ifdef NSIS_CONFIG_CRC_SUPPORT
  handle_ver_dlg(TRUE);
#endif//NSIS_CONFIG_CRC_SUPPORT
#endif//NSIS_CONFIG_VISIBLE_SUPPORT
  if (!g_filehdrsize)
    return _LANG_INVALIDCRC;

#ifdef NSIS_CONFIG_CRC_SUPPORT
  if (do_crc)
  {
    crc32_t fcrc;
    SetSelfFilePointer(m_pos);
    if (!ReadSelfFile(&fcrc, sizeof(crc32_t)) || crc != fcrc)
      return _LANG_INVALIDCRC;
  }
#endif//NSIS_CONFIG_CRC_SUPPORT

  data = (void *)GlobalAlloc(GPTR,h.length_of_header);

#ifdef NSIS_COMPRESS_WHOLE
  inflateReset(&g_inflate_stream);

  {
    TCHAR fno[MAX_PATH];
    my_GetTempFileName(fno, state_temp_dir);
    dbd_hFile=CreateFile(fno,GENERIC_WRITE|GENERIC_READ,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_TEMPORARY|FILE_FLAG_DELETE_ON_CLOSE,NULL);
    if (dbd_hFile == INVALID_HANDLE_VALUE)
      return _LANG_ERRORWRITINGTEMP;
  }
  dbd_srcpos = SetSelfFilePointer(g_filehdrsize + sizeof(firstheader));
#ifdef NSIS_CONFIG_CRC_SUPPORT
  dbd_fulllen = dbd_srcpos - sizeof(h) + h.length_of_all_following_data - ((h.flags & FH_FLAGS_NO_CRC) ? 0 : sizeof(crc32_t));
#else
  dbd_fulllen = dbd_srcpos - sizeof(h) + h.length_of_all_following_data;
#endif//NSIS_CONFIG_CRC_SUPPORT
#else
  SetSelfFilePointer(g_filehdrsize + sizeof(firstheader));
#endif//NSIS_COMPRESS_WHOLE

  if (GetCompressedDataFromDataBlockToMemory(-1, data, h.length_of_header) != h.length_of_header)
  {
    return _LANG_INVALIDCRC;
  }

  header = g_header = data;

  g_flags = header->flags;

#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
  if (h.flags & FH_FLAGS_UNINSTALL)
    g_is_uninstaller++;
#endif

  // set offsets to real memory offsets rather than installer's header offset
  left = BLOCKS_NUM;
  while (left--)
    header->blocks[left].offset += (int)data;

#ifdef NSIS_COMPRESS_WHOLE
  header->blocks[NB_DATA].offset = dbd_pos;
#else
  header->blocks[NB_DATA].offset = SetFilePointer(db_hFile,0,NULL,FILE_CURRENT);
#endif

  mini_memcpy(&g_blocks, &header->blocks, sizeof(g_blocks));

  return 0;
}