예제 #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 프로젝트: kichik/nsis-1
const char * NSISCALL loadHeaders(int cl_flags)
{
#ifdef NSIS_CONFIG_CRC_SUPPORT
#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
  HWND hwnd = 0;
  unsigned int verify_time = GetTickCount() + 1000;
#endif
  crc32_t crc = 0;
  int do_crc = 0;
#endif//NSIS_CONFIG_CRC_SUPPORT
  int left;

  void *data;
  firstheader h;
  header *header;

  HANDLE db_hFile;

  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)
      if (hwnd) DestroyWindow(hwnd);
#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 shit 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
    {
      if (hwnd)
      {
        MessageLoop(0);
      }
      else if (GetTickCount() > verify_time)
        hwnd = CreateDialogParam(
          g_hInstance,
          MAKEINTRESOURCE(IDD_VERIFY),
          0,
          verProc,
          (LPARAM)_LANG_VERIFYINGINST
        );
    }
#endif//NSIS_CONFIG_VISIBLE_SUPPORT

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

#endif//NSIS_CONFIG_CRC_SUPPORT
    m_pos += l;
    left -= l;
  }
#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
#ifdef NSIS_CONFIG_CRC_SUPPORT
  if (hwnd)
  {
    DestroyWindow(hwnd);
  }
#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);

  {
    char 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;
}
예제 #3
0
파일: RegTool.c 프로젝트: kichik/nsis-1
/** Modifies the wininit.ini file to rename / delete a file.
 *
 * @param prevName The previous / current name of the file.
 * @param newName The new name to move the file to.  If NULL, the current file
 * will be deleted.
 */
void RenameViaWininit(const TCHAR* prevName, const TCHAR* newName)
{
  static char szRenameLine[1024];
  static TCHAR wininit[1024];
  static TCHAR tmpbuf[1024];

  int cchRenameLine;
  LPCSTR szRenameSec = "[Rename]\r\n"; // rename section marker
  HANDLE hfile;
  DWORD dwFileSize;
  SIZE_T dwBytes;
  DWORD dwRenameLinePos;
  char *pszWinInit;   // Contains the file contents of wininit.ini

  int spn;   // length of the short path name in TCHARs.

  lstrcpy(tmpbuf, _T("NUL"));

  if (newName) {
    // create the file if it's not already there to prevent GetShortPathName from failing
    CloseHandle(myOpenFile(newName,0,CREATE_NEW));
    spn = GetShortPathName(newName,tmpbuf,1024);
    if (!spn || spn > 1024)
      return;
  }
  // wininit is used as a temporary here
  spn = GetShortPathName(prevName,wininit,1024);
  if (!spn || spn > 1024)
    return;
#ifdef _UNICODE
  cchRenameLine = wsprintfA(szRenameLine, "%ls=l%s\r\n", tmpbuf, wininit);
#else
  cchRenameLine = wsprintfA(szRenameLine, "%s=%s\r\n", tmpbuf, wininit);
#endif
  // Get the path to the wininit.ini file.
  GetWindowsDirectory(wininit, 1024-16);
  lstrcat(wininit, _T("\\wininit.ini"));

  hfile = myOpenFile(wininit, GENERIC_READ | GENERIC_WRITE, OPEN_ALWAYS);

  if (hfile != INVALID_HANDLE_VALUE)
  {
    // We are now working on the Windows wininit file
    dwFileSize = GetFileSize(hfile, NULL);
    pszWinInit = (char*) GlobalAlloc(GPTR, dwFileSize + cchRenameLine + 10);

    if (pszWinInit != NULL)
    {
      if (ReadFile(hfile, pszWinInit, dwFileSize, &dwBytes, NULL) && dwFileSize == dwBytes)
      {
        // Look for the rename section in the current file.
        LPSTR pszRenameSecInFile = mystrstriA(pszWinInit, szRenameSec);
        if (pszRenameSecInFile == NULL)
        {
          // No rename section.  So we add it to the end of file.
          lstrcpyA(pszWinInit+dwFileSize, szRenameSec);
          dwFileSize += 10;
          dwRenameLinePos = dwFileSize;
        }
        else
        {
          // There is a rename section, but is there another section after it?
          char *pszFirstRenameLine = pszRenameSecInFile+10;
          char *pszNextSec = mystrstriA(pszFirstRenameLine,"\n[");
          if (pszNextSec)
          {
            char *p = pszWinInit + dwFileSize;
            char *pEnd = pszWinInit + dwFileSize + cchRenameLine;

            while (p > pszNextSec)
            {
              *pEnd-- = *p--;
            }

            dwRenameLinePos = pszNextSec - pszWinInit + 1; // +1 for the \n
          }
          // rename section is last, stick item at end of file
          else dwRenameLinePos = dwFileSize;
        }

        mini_memcpy(&pszWinInit[dwRenameLinePos], szRenameLine, cchRenameLine);
        dwFileSize += cchRenameLine;

        SetFilePointer(hfile, 0, NULL, FILE_BEGIN);
        WriteFile(hfile, pszWinInit, dwFileSize, &dwBytes, NULL);

        GlobalFree(pszWinInit);
      }
    }
    
    CloseHandle(hfile);
  }
}
예제 #4
0
파일: RegTool.c 프로젝트: kichik/nsis-1
void DeleteFileOnReboot(char *pszFile)
{
    BOOL fOk = 0;
    HMODULE hLib=GetModuleHandle("KERNEL32.dll");
    if (hLib)
    {
        typedef BOOL (WINAPI *mfea_t)(LPCSTR lpExistingFileName,LPCSTR lpNewFileName,DWORD dwFlags);
        mfea_t mfea;
        mfea=(mfea_t) GetProcAddress(hLib,"MoveFileExA");
        if (mfea)
        {
            fOk=mfea(pszFile, NULL, MOVEFILE_DELAY_UNTIL_REBOOT);
        }
    }

    if (!fOk)
    {
        static char szRenameLine[1024];
        static char wininit[1024];
        int cchRenameLine;
        char *szRenameSec = "[Rename]\r\n";
        HANDLE hfile, hfilemap;
        DWORD dwFileSize, dwRenameLinePos;

        int spn;

        // wininit is used as a temporary here
        spn = GetShortPathName(pszFile,wininit,1024);
        if (!spn || spn > 1024)
            return;
        cchRenameLine = wsprintf(szRenameLine,"NUL=%s\r\n",wininit);

        GetWindowsDirectory(wininit, 1024-16);
        lstrcat(wininit, "\\wininit.ini");
        hfile = CreateFile(wininit,
                           GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_ALWAYS,
                           FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);

        if (hfile != INVALID_HANDLE_VALUE)
        {
            dwFileSize = GetFileSize(hfile, NULL);
            hfilemap = CreateFileMapping(hfile, NULL, PAGE_READWRITE, 0, dwFileSize + cchRenameLine + 10, NULL);

            if (hfilemap != NULL)
            {
                LPSTR pszWinInit = (LPSTR) MapViewOfFile(hfilemap, FILE_MAP_WRITE, 0, 0, 0);

                if (pszWinInit != NULL)
                {
                    LPSTR pszRenameSecInFile = mystrstri(pszWinInit, szRenameSec);
                    if (pszRenameSecInFile == NULL)
                    {
                        lstrcpy(pszWinInit+dwFileSize, szRenameSec);
                        dwFileSize += 10;
                        dwRenameLinePos = dwFileSize;
                    }
                    else
                    {
                        char *pszFirstRenameLine = pszRenameSecInFile+10;
                        char *pszNextSec = mystrstri(pszFirstRenameLine,"\n[");
                        if (pszNextSec)
                        {
                            char *p = ++pszNextSec;
                            while (p < pszWinInit + dwFileSize) {
                                p[cchRenameLine] = *p;
                                p++;
                            }

                            dwRenameLinePos = pszNextSec - pszWinInit;
                        }
                        // rename section is last, stick item at end of file
                        else dwRenameLinePos = dwFileSize;
                    }

                    mini_memcpy(&pszWinInit[dwRenameLinePos], szRenameLine, cchRenameLine);
                    dwFileSize += cchRenameLine;

                    UnmapViewOfFile(pszWinInit);
                }
                CloseHandle(hfilemap);
            }
            SetFilePointer(hfile, dwFileSize, NULL, FILE_BEGIN);
            SetEndOfFile(hfile);
            CloseHandle(hfile);
        }
    }
}
예제 #5
0
/** Modifies the wininit.ini file to rename / delete a file.
 *
 * @param prevName The previous / current name of the file.
 * @param newName The new name to move the file to.  If NULL, the current file
 * will be deleted.
 */
void RenameViaWininit(TCHAR* prevName, TCHAR* newName)
{
  static char szRenameLine[1024];
  static TCHAR wininit[1024];
  static TCHAR tmpbuf[1024];
#ifdef _UNICODE
  static char shortExisting[1024];
  static char shortNew[1024];
#endif

  int cchRenameLine;
  static const char szRenameSec[] = "[Rename]\r\n"; // rename section marker
  HANDLE hfile;
  DWORD dwFileSize;
  DWORD dwBytes;
  DWORD dwRenameLinePos;
  char *pszWinInit;   // Contains the file contents of wininit.ini

  int spn;   // length of the short path name in TCHARs.

  lstrcpy(tmpbuf, _T("NUL"));

  if (newName) {
    // create the file if it's not already there to prevent GetShortPathName from failing
    CloseHandle(myOpenFile(newName,0,CREATE_NEW));
    spn = GetShortPathName(newName,tmpbuf,1024);
    if (!spn || spn > 1024)
      return;
  }
  // wininit is used as a temporary here
  spn = GetShortPathName(prevName,wininit,1024);
  if (!spn || spn > 1024)
    return;

 // Because wininit.ini is an ASCII text file, we need to be careful what we
 // convert here to TCHARs.

#ifdef _UNICODE
  // The short name produced by GetShortPathName is always in the ASCII range
  // of characters.
 
  // Convert short name of new name to ANSI
  if (WideCharToMultiByte(CP_ACP, 0, tmpbuf, -1, shortNew, sizeof(shortNew), NULL, NULL) == 0)
  {
     // We have a failure in conversion to ANSI
     return;
  }

  // Convert short name of old name to ANSI
  if (WideCharToMultiByte(CP_ACP, 0, wininit, -1, shortExisting, sizeof(shortExisting), NULL, NULL) == 0)
  {
     // We have a failure in conversion to ANSI
     return;
  }

  cchRenameLine = wsprintfA(szRenameLine, "%s=%s\r\n", shortNew, shortExisting);
#else
  cchRenameLine = wsprintfA(szRenameLine, "%s=%s\r\n", tmpbuf, wininit);
#endif
  // Get the path to the wininit.ini file.
  GetWindowsDirectory(wininit, 1024-16);
  lstrcat(wininit, _T("\\wininit.ini"));

  hfile = myOpenFile(wininit, GENERIC_READ | GENERIC_WRITE, OPEN_ALWAYS);

  if (hfile != INVALID_HANDLE_VALUE)
  {
    // We are now working on the Windows wininit file
    dwFileSize = GetFileSize(hfile, NULL);
    pszWinInit = (char*) GlobalAlloc(GPTR, dwFileSize + cchRenameLine + 10);

    if (pszWinInit != NULL)
    {
      if (ReadFile(hfile, pszWinInit, dwFileSize, &dwBytes, NULL) && dwFileSize == dwBytes)
      {
        // Look for the rename section in the current file.
        LPSTR pszRenameSecInFile = mystrstriA(pszWinInit, szRenameSec);
        if (pszRenameSecInFile == NULL)
        {
          // No rename section.  So we add it to the end of file.
          lstrcpyA(pszWinInit+dwFileSize, szRenameSec);
          dwFileSize += 10;
          dwRenameLinePos = dwFileSize;
        }
        else
        {
          // There is a rename section, but is there another section after it?
          char *pszFirstRenameLine = pszRenameSecInFile+10;
          char *pszNextSec = mystrstriA(pszFirstRenameLine,"\n[");
          if (pszNextSec)
          {
            char *p = pszWinInit + dwFileSize;
            char *pEnd = pszWinInit + dwFileSize + cchRenameLine;

            while (p > pszNextSec)
            {
              *pEnd-- = *p--;
            }

            dwRenameLinePos = pszNextSec - pszWinInit + 1; // +1 for the \n
          }
          // rename section is last, stick item at end of file
          else dwRenameLinePos = dwFileSize;
        }

        mini_memcpy(&pszWinInit[dwRenameLinePos], szRenameLine, cchRenameLine);
        dwFileSize += cchRenameLine;

        SetFilePointer(hfile, 0, NULL, FILE_BEGIN);
        WriteFile(hfile, pszWinInit, dwFileSize, &dwBytes, NULL);

        GlobalFree(pszWinInit);
      }
    }
    
    CloseHandle(hfile);
  }
}