Exemplo n.º 1
0
FileSystemManager::FileSystemManager()
: _hMSIDll(0)
, pfnMsiGetShortcutTarget(NULL)
, pfnMsiGetComponentPath(NULL)
{	
	_hMSIDll = LoadLibrary(L"Msi.dll");
	if (_hMSIDll)
	{
		pfnMsiGetShortcutTarget = myGetProcAddress(_hMSIDll, MsiGetShortcutTarget);
		pfnMsiGetComponentPath = myGetProcAddress(_hMSIDll, MsiGetComponentPath);
	}
}
Exemplo n.º 2
0
int FilterMem(unsigned char* szSrc,unsigned int src_len,unsigned char *szTarget,unsigned int *tar_len)
{
     void    *pFilter = NULL;
     char    szDllName[1024];
     void    *pKVFILTER;
     char    *szDir = (char*)KVLIBDIR ;
     KVInputStream  inStream;
     KVFilterOutput OutStream;
     MemOperInfo minf;
     bzero(&inStream,sizeof(inStream));
     bzero(&OutStream,sizeof(OutStream));

     
     FilterLsv *lsv=(FilterLsv*)malloc(sizeof(FilterLsv));
     bzero(lsv,sizeof(FilterLsv));
     KVErrorCode        nRet = KVERR_Success;
     KVErrorCode (pascal *fpGetFilterInterfaceEx)( KVFltInterfaceEx*, int );

     strcpy(szDllName, szDir);
     strcat(szDllName, "kvfilter");

     pKVFILTER = myLoadLibrary(szDllName);
     if (!pKVFILTER)
     {
	  fprintf(stderr, "Can't load kvfilter!\n");
	  fprintf(stderr, "This executable must be in the same directory as the Filter binaries.\n");
	  nRet = KVERR_DLLNotFound;
	  goto jail;
     }

     fpGetFilterInterfaceEx = (KVErrorCode (pascal *)( KVFltInterfaceEx *, int ) )
	  myGetProcAddress(pKVFILTER, (char*)"KV_GetFilterInterfaceEx");

     if ( fpGetFilterInterfaceEx == NULL )
     {
	  fprintf(stderr, "Can't get interface function!\n");
	  nRet = KVERR_General;
	  goto jail;
     }

     nRet = (*fpGetFilterInterfaceEx)(&FilterFunc, KVFLTINTERFACE_REVISION);        
     if(KVERR_Success != nRet)
     {
	  fprintf(stderr, "Can't get Filter interface functions!\n");
	  goto jail;
     }

     lsv->fpKV_GetKvErrorCodeEx = (KVErrorCodeEx (pascal *)( void * ))myGetProcAddress(pKVFILTER, (char*)"KV_GetKvErrorCodeEx");
     lsv->fpKV_FilterConfig = (BOOL (pascal *)( void *, int, int, void * ))myGetProcAddress(pKVFILTER, (char*)"KV_FilterConfig");
//     lsv->gbSummary =TRUE;
     lsv->dwFlags=KVF_OOPLOGON|KVF_INPROCESS; ;
     pFilter = (*FilterFunc.fpInit)( &g_MemoryAllocator, NULL , szDir, KVCS_UTF8, lsv->dwFlags); /*|*/
        
     if ( pFilter == NULL )
     {
	  fprintf(stderr, "Error initializing filter!\n" );
	  nRet = KVERR_General;
	  goto jail;
     }
     if (!(*FilterFunc.fpSetSrcCharSet)(pFilter,KVCS_1252) )
     {
	  fprintf(stderr, "Error initializing filter!\n" );
	  nRet = KVERR_General;
	  goto jail;
     }
     if (lsv->fpKV_FilterConfig!=NULL)
     {
	  if (lsv->bInclRMark)
	  {
	       lsv->fpKV_FilterConfig(pFilter, KVFLT_INCLREVISIONMARK, TRUE, NULL);
	  }
	  if (lsv->szXMLConfigFile[0])
	  {
	       KVXConfigInfo xinfo;
	       BOOL bDone = FALSE;
	       int n = 0;

	       /* get config info for Verity-recognized formats */
	       while(!bDone)
	       {
		    memset(&xinfo, 0, sizeof(KVXConfigInfo));
		    if(GetKVXConfigInfo(lsv, &xinfo, n))
		    {
			 lsv->fpKV_FilterConfig(pFilter, KVFLT_SETXMLCONFIGINFO, 0, &xinfo);
			 FreeKVXConfigInfo(&xinfo);
			 n++;
		    }
		    else
		    {
			 bDone = TRUE;
		    }
	       }

	       /* get customized config info for other formats */
	       bDone = FALSE;
	       n = 100;
	       while(!bDone)
	       {
		    memset(&xinfo, 0, sizeof(KVXConfigInfo));
		    if(GetKVXConfigInfo(lsv, &xinfo, n))
		    {
			 lsv->fpKV_FilterConfig(pFilter, KVFLT_SETXMLCONFIGINFO, 0, &xinfo);
			 FreeKVXConfigInfo(&xinfo);
			 n++;
		    }
		    else
		    {
			 bDone = TRUE;
		    }
	       }
	  }            
	  if (lsv->szTempDir[0])
	  {
	       lsv->fpKV_FilterConfig(pFilter, KVFLT_SETTEMPDIRECTORY, 0, lsv->szTempDir);
	  }
	  if (lsv->szSrcPassword[0])
	  {
	       lsv->fpKV_FilterConfig(pFilter, KVFLT_SETSRCPASSWORD, 
				      strlen(lsv->szSrcPassword), lsv->szSrcPassword);
	  }
	  if (lsv->lpdfDirection >= LPDF_RAW)
	  {
	       lsv->fpKV_FilterConfig(pFilter, KVFLT_LOGICALPDF, 
				      lsv->lpdfDirection, NULL);
	  }
     }

     minf.buff=szSrc;
     minf.buf_len= src_len;
     inStream.pInputStreamPrivateData = (void *)&minf;
     inStream.fpOpen  = MemOpen;
     inStream.fpRead  = MemRead;
     inStream.fpSeek  = MemSeek;
     inStream.fpTell  = MemTell;
     inStream.fpClose = MemClose;
     nRet=FilterStream(pFilter,&inStream, szTarget,tar_len ,lsv);
	
jail:
     if ( nRet == KVERR_General )
     {
	  int kvErrorEx;
	  if ( lsv->fpKV_GetKvErrorCodeEx )
	  {
	       kvErrorEx = (*lsv->fpKV_GetKvErrorCodeEx)( pFilter );
	       if ( kvErrorEx != KVError_Last)
		    fprintf(stderr,"KvErrorCodeEx = %d \n ", kvErrorEx );
	       else
		    fprintf(stderr,"No more KvErrorCodeEx \n" );
	  }
     }
     free(lsv);
     if (pFilter!=NULL)
	  (*FilterFunc.fpShutdown)( pFilter );
    
     myFreeLibrary((HINSTANCE)pKVFILTER);

     return (nRet);
}
Exemplo n.º 3
0
Arquivo: Ui.c Projeto: kichik/nsis-1
FORCE_INLINE int NSISCALL ui_doinstall(void)
{
  header *header = g_header;
  static WNDCLASS wc; // richedit subclassing and bgbg creation

  // detect default language
  // more information at:
  //   http://msdn.microsoft.com/library/default.asp?url=/library/en-us/intl/nls_0xrn.asp

  LANGID (WINAPI *GUDUIL)();

  GUDUIL = myGetProcAddress(MGA_GetUserDefaultUILanguage);
  if (GUDUIL)
  {
    // Windows ME/2000+
    myitoa(state_language, GUDUIL());
  }
  else
  {
    static const TCHAR reg_9x_locale[]     = _T("Control Panel\\Desktop\\ResourceLocale");
    static const TCHAR reg_nt_locale_key[] = _T(".DEFAULT\\Control Panel\\International");
    const TCHAR       *reg_nt_locale_val   = &reg_9x_locale[30]; // = _T("Locale") with opt

    state_language[0] = _T('0');
    state_language[1] = _T('x');
    state_language[2] =     0;

    {
      // Windows 9x
      myRegGetStr(HKEY_CURRENT_USER, reg_9x_locale, NULL, g_tmp, 0);
    }

    if (!g_tmp[0])
    {
      // Windows NT
      // This key exists on 9x as well, so it's only read if ResourceLocale wasn't found
      myRegGetStr(HKEY_USERS, reg_nt_locale_key, reg_nt_locale_val, g_tmp, 0);
    }

    mystrcat(state_language, g_tmp);
  }

  // set default language
  set_language();

  // initialize auto close flag
  g_exec_flags.autoclose=g_flags&CH_FLAGS_AUTO_CLOSE;

#ifdef NSIS_CONFIG_PLUGIN_SUPPORT
  // initialize plugin api
  g_exec_flags.plugin_api_version=NSISPIAPIVER_CURR;
#endif

  // read install directory from registry
  if (!is_valid_instpath(state_install_directory))
  {
    if (header->install_reg_key_ptr)
    {
      myRegGetStr(
        (HKEY)header->install_reg_rootkey,
        GetNSISStringNP(header->install_reg_key_ptr),
        GetNSISStringNP(header->install_reg_value_ptr),
        ps_tmpbuf,
        0
      );
      if (ps_tmpbuf[0])
      {
        TCHAR *p=ps_tmpbuf;
        TCHAR *e;
        if (p[0]==_T('\"'))
        {
          TCHAR *p2;
          p++;
          p2 = findchar(p, _T('"'));
          *p2 = 0;
        }
        // p is the path now, check for .exe extension

        e=p+mystrlen(p)-4;
        if (e > p)
        {
          // if filename ends in .exe, and is not a directory, remove the filename
          if (!lstrcmpi(e, _T(".exe"))) // check extension
          {
            DWORD d;
            d=GetFileAttributes(p);
            if (d == INVALID_FILE_ATTRIBUTES || !(d&FILE_ATTRIBUTE_DIRECTORY))
            {
              // if there is no back-slash, the string will become empty, but that's ok because
              // it would make an invalid instdir anyway
              trimslashtoend(p);
            }
          }
        }
        mystrcpy(state_install_directory,addtrailingslash(p));
      }
    }
  }
  if (!is_valid_instpath(state_install_directory))
  {
    GetNSISString(state_install_directory,header->install_directory_ptr);
  }

#ifdef NSIS_CONFIG_LOG
  if (g_flags & CH_FLAGS_SILENT_LOG && !g_is_uninstaller)
  {
#if !defined(NSIS_CONFIG_LOG_ODS) && !defined(NSIS_CONFIG_LOG_STDOUT)
    build_g_logfile();
#endif
    log_dolog=1;
  }
#endif

#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
  g_hIcon=LoadImage(g_hInstance,MAKEINTRESOURCE(IDI_ICON2),IMAGE_ICON,0,0,LR_DEFAULTSIZE|LR_SHARED);
#ifdef NSIS_SUPPORT_BGBG
  if (header->bg_color1 != -1)
  {
    LPCTSTR cn = _T("_Nb");
    RECT vp;
    extern LRESULT CALLBACK BG_WndProc(HWND, UINT, WPARAM, LPARAM);
    wc.lpfnWndProc = BG_WndProc;
    wc.hInstance = g_hInstance;
    wc.hIcon = g_hIcon;
    //wc.hCursor = LoadCursor(NULL,IDC_ARROW);
    wc.lpszClassName = cn;

    if (!RegisterClass(&wc)) return 0;

    SystemParametersInfo(SPI_GETWORKAREA, 0, &vp, 0);

    m_bgwnd = CreateWindowEx(WS_EX_TOOLWINDOW,cn,0,WS_POPUP,
      vp.left,vp.top,vp.right-vp.left,vp.bottom-vp.top,0,NULL,g_hInstance,NULL);
  }

#endif//NSIS_SUPPORT_BGBG

#endif//NSIS_CONFIG_VISIBLE_SUPPORT

#ifdef NSIS_SUPPORT_CODECALLBACKS
  // Select language
  if (ExecuteCallbackFunction(CB_ONINIT)) return 2;
  set_language();
#endif

#ifdef NSIS_CONFIG_VISIBLE_SUPPORT

#ifdef NSIS_CONFIG_SILENT_SUPPORT
  if (!g_exec_flags.silent)
#endif//NSIS_CONFIG_SILENT_SUPPORT
  {
#ifdef NSIS_SUPPORT_BGBG
    ShowWindow(m_bgwnd, SW_SHOW);
#endif//NSIS_SUPPORT_BGBG

#ifdef NSIS_CONFIG_LICENSEPAGE
    { // load richedit DLL
      static const TCHAR riched20[]=_T("RichEd20");
      static const TCHAR riched32[]=_T("RichEd32");
#ifdef UNICODE
      static const TCHAR richedit20t[]=_T("RichEdit20W");
#else
      static const TCHAR richedit20t[]=_T("RichEdit20A");
#endif
      static const TCHAR richedit[]=_T("RichEdit");
      if (!LoadLibrary(riched20))
      {
        LoadLibrary(riched32); // Win95 only ships with v1.0, NT4 has v2.0: web.archive.org/web/20030607222419/http://msdn.microsoft.com/library/en-us/shellcc/platform/commctls/richedit/richeditcontrols/aboutricheditcontrols.asp
      }

      // make richedit20a/w point to RICHEDIT
      if (!GetClassInfo(NULL,richedit20t,&wc))
      {
        GetClassInfo(NULL,richedit,&wc);
        wc.lpszClassName = richedit20t;
        RegisterClass(&wc);
      }
    }

#endif

    {
      int ret=DialogBox(g_hInstance,MAKEINTRESOURCE(IDD_INST+dlg_offset),0,DialogProc);
#if defined(NSIS_SUPPORT_CODECALLBACKS) && defined(NSIS_CONFIG_ENHANCEDUI_SUPPORT)
      ExecuteCallbackFunction(CB_ONGUIEND);
#endif
#ifdef NSIS_CONFIG_PLUGIN_SUPPORT
      Plugins_SendMsgToAllPlugins(NSPIM_GUIUNLOAD);
#endif
      return ret;
    }
  }
#endif//NSIS_CONFIG_VISIBLE_SUPPORT
#ifdef NSIS_CONFIG_SILENT_SUPPORT
#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
  else
#endif//NSIS_CONFIG_VISIBLE_SUPPORT
  {
    if (install_thread(NULL))
    {
#ifdef NSIS_SUPPORT_CODECALLBACKS
      if (!g_quit_flag) ExecuteCallbackFunction(CB_ONINSTFAILED);
#endif//NSIS_SUPPORT_CODECALLBACKS
      return 2;
    }
#ifdef NSIS_SUPPORT_CODECALLBACKS
    ExecuteCallbackFunction(CB_ONINSTSUCCESS);
#endif//NSIS_SUPPORT_CODECALLBACKS

    return 0;
  }
#endif//NSIS_CONFIG_SILENT_SUPPORT
}
Exemplo n.º 4
0
Arquivo: Ui.c Projeto: kichik/nsis-1
static INT_PTR CALLBACK DirProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
  static int dontsetdefstyle;
  page *thispage = g_this_page;
  TCHAR *dir = g_usrvars[thispage->parms[4]];
  int browse_text = thispage->parms[3];

  if (uMsg == WM_NOTIFY_INIGO_MONTOYA)
  {
    GetUIText(IDC_DIR,dir);
    validate_filename(dir);
#ifdef NSIS_CONFIG_LOG
#if !defined(NSIS_CONFIG_LOG_ODS) && !defined(NSIS_CONFIG_LOG_STDOUT)
    build_g_logfile();
#endif
    if (GetUIItem(IDC_CHECK1) != NULL)
      log_dolog = IsDlgButtonChecked(hwndDlg,IDC_CHECK1);
#endif
  }
  if (uMsg == WM_INITDIALOG)
  {
    HWND hDir = GetUIItem(IDC_DIR);

#ifdef NSIS_CONFIG_LOG
    if (GetAsyncKeyState(VK_SHIFT)&0x8000)
    {
      HWND h=GetUIItem(IDC_CHECK1);
      SetUITextFromLang(IDC_CHECK1,LANG_LOG_INSTALL_PROCESS);
      ShowWindow(h,SW_SHOWNA);
    }
#endif
    if (validpathspec(dir) && !skip_root(dir))
      addtrailingslash(dir);

    // workaround for bug #1209843
    //
    // m_curwnd is only updated once WM_INITDIALOG returns.
    // my_SetWindowText triggers an EN_CHANGE message that
    // triggers a WM_IN_UPDATEMSG message that uses m_curwnd
    // to get the selected directory (GetUIText).
    // because m_curwnd is still outdated, dir varialble is
    // filled with an empty string. by default, dir points
    // to $INSTDIR.
    //
    // to solve this, m_curwnd is manually set to the correct
    // window handle.

    m_curwnd=hwndDlg;

    my_SetWindowText(hDir,dir);
    SetUITextFromLang(IDC_BROWSE,this_page->parms[2]);
    SetUITextFromLang(IDC_SELDIRTEXT,this_page->parms[1]);
    SetActiveCtl(hDir);

    {
      typedef HRESULT (WINAPI *SHAutoCompletePtr)(HWND, DWORD);
      SHAutoCompletePtr fSHAutoComplete;
      fSHAutoComplete = (SHAutoCompletePtr) myGetProcAddress(MGA_SHAutoComplete);
      if (fSHAutoComplete)
      {
        fSHAutoComplete(hDir, SHACF_FILESYSTEM);
      }
    }
  }
  if (uMsg == WM_COMMAND)
  {
    int id=LOWORD(wParam);
    if (id == IDC_DIR && HIWORD(wParam) == EN_CHANGE)
    {
      uMsg = WM_IN_UPDATEMSG;
    }
    if (id == IDC_BROWSE)
    {
      static TCHAR bt[NSIS_MAX_STRLEN];
      BROWSEINFO bi = {0,};
      ITEMIDLIST *idlist;
      bi.hwndOwner = hwndDlg;
      bi.pszDisplayName = g_tmp;
      bi.lpfn = BrowseCallbackProc;
      bi.lParam = (LPARAM)dir;
      bi.lpszTitle = GetNSISString(bt, browse_text);
      bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_NEWDIALOGSTYLE;
      idlist = SHBrowseForFolder(&bi);
      if (idlist)
      {
        // free idlist
        CoTaskMemFree(idlist);

        addtrailingslash(dir);

        if (g_header->install_directory_auto_append &&
          dir == state_install_directory) // only append to $INSTDIR (bug #1174184)
        {
          const TCHAR *post_str = ps_tmpbuf;
          GetNSISStringTT(g_header->install_directory_auto_append);
          // display name gives just the folder name
          if (lstrcmpi(post_str, g_tmp))
          {
            mystrcat(dir, post_str);
          }
        }

        dontsetdefstyle++;
        SetUITextNT(IDC_DIR,dir);
      }
      else
      {
        uMsg = WM_IN_UPDATEMSG;
      }
    }
  }
  if (uMsg == WM_IN_UPDATEMSG || uMsg == WM_NOTIFY_START)
  {
    static TCHAR s[NSIS_MAX_STRLEN];
    int error = 0;
    int available_set = 0;
    unsigned total, available;

    GetUIText(IDC_DIR,dir);
    if (!is_valid_instpath(dir))
      error = NSIS_INSTDIR_INVALID;

    /**
     * This part is tricky. We need to make sure a few things:
     *
     *   1. GetDiskFreeSpaceEx is always called at least once for large HD.
     *        Even if skip_root() returned NULL (e.g. "C:").
     *        Note that trimslashtoend() will nullify "C:".
     *   2. GetDiskFreeSpaceEx is called with the deepest valid directory.
     *        e.g. C:\drive when the user types C:\drive\folder1\folder2.
     *        This makes sure NTFS mount points are treated properly (#1946112).
     *   3. `s' stays valid after the loop for GetDiskFreeSpace.
     *        This means there is no cutting beyond what skip_root() returns.
     *        Or `s' could be recreated when GetDiskFreeSpace is called.
     *   4. If GetDiskFreeSpaceEx doesn't exist, GetDiskFreeSpace is used.
     *   5. Both functions require a trailing backslash
     *   6. `dir' is never modified.
     *
     */
    mystrcpy(s,dir);

    // Test for and use the GetDiskFreeSpaceEx API
    {
      BOOL (WINAPI *GDFSE)(LPCTSTR, PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER) =
          myGetProcAddress(MGA_GetDiskFreeSpaceEx);
      if (GDFSE)
      {
        ULARGE_INTEGER available64;
        ULARGE_INTEGER a, b;
        TCHAR *p;
        TCHAR *pw = NULL;
        while (pw != s) // trimslashtoend() cut the entire string
        {
          if (GDFSE(s, &available64, &a, &b))
          {
#ifndef _NSIS_NO_INT64_SHR
            available = (int)(available64.QuadPart >> 10);
#else
            available = (int)(Int64ShrlMod32(available64.QuadPart, 10));
#endif
            available_set++;
            break;
          }

          if (pw)
            // if pw was set, remove the backslash so trimslashtoend() will cut a new one
            *pw = 0;

          p = trimslashtoend(s); // trim last backslash
          // bring it back, but make the next char null
          pw = p;
          *pw = 0;
          --pw;
          *pw = _T('\\'); 
        }
      }
    }

    if (!available_set)
    {
      DWORD spc, bps, fc, tc;
      TCHAR *root;

      // GetDiskFreeSpaceEx accepts any path, but GetDiskFreeSpace accepts only the root
      mystrcpy(s,dir);
      root=skip_root(s);
      if (root)
        *root=0;

      // GetDiskFreeSpaceEx is not available
      if (GetDiskFreeSpace(s, &spc, &bps, &fc, &tc))
      {
        available = (int)MulDiv(bps * spc, fc, 1 << 10);
        available_set++;
      }
    }

    total = (unsigned) sumsecsfield(size_kb);

#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" // available_set is checked first so available is initialized
#endif
    if (available_set && available < total)
      error = NSIS_INSTDIR_NOT_ENOUGH_SPACE;
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
#pragma GCC diagnostic pop
#endif

    if (LANG_STR_TAB(LANG_SPACE_REQ)) {
      SetSizeText(IDC_SPACEREQUIRED,LANG_SPACE_REQ,total);
      if (available_set)
        SetSizeText(IDC_SPACEAVAILABLE,LANG_SPACE_AVAIL,available);
      else
        SetUITextNT(IDC_SPACEAVAILABLE,_T(""));
    }

    g_exec_flags.instdir_error = error;

#ifdef NSIS_SUPPORT_CODECALLBACKS
    if (!error)
      error = ExecuteCallbackFunction(CB_ONVERIFYINSTDIR);
#endif

    if (thispage->flags & PF_DIR_NO_BTN_DISABLE)
      error = 0;

    EnableNext(!error);
    if (!error && !dontsetdefstyle)
      SetNextDef();
    dontsetdefstyle = 0;
  }
Exemplo n.º 5
0
Arquivo: Ui.c Projeto: kichik/nsis-1
static INT_PTR CALLBACK DirProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
  static int dontsetdefstyle;
  page *thispage = g_this_page;
  TCHAR *dir = g_usrvars[thispage->parms[4]];
  int browse_text = thispage->parms[3];
  if (uMsg == WM_NOTIFY_INIGO_MONTOYA)
  {
    GetUIText(IDC_DIR,dir);
    validate_filename(dir);
#ifdef NSIS_CONFIG_LOG
#if !defined(NSIS_CONFIG_LOG_ODS) && !defined(NSIS_CONFIG_LOG_STDOUT)
    build_g_logfile();
#endif
    if (GetUIItem(IDC_CHECK1) != NULL)
      log_dolog = IsDlgButtonChecked(hwndDlg,IDC_CHECK1);
#endif
  }
  if (uMsg == WM_INITDIALOG)
  {
    HWND hDir = GetUIItem(IDC_DIR);

#ifdef NSIS_CONFIG_LOG
    if (GetAsyncKeyState(VK_SHIFT)&0x8000)
    {
      HWND h=GetUIItem(IDC_CHECK1);
      SetUITextFromLang(IDC_CHECK1,LANG_LOG_INSTALL_PROCESS);
      ShowWindow(h,SW_SHOWNA);
    }
#endif
    if (validpathspec(dir) && !skip_root(dir))
      addtrailingslash(dir);

    // workaround for bug #1209843
    //
    // m_curwnd is only updated once WM_INITDIALOG returns.
    // my_SetWindowText triggers an EN_CHANGE message that
    // triggers a WM_IN_UPDATEMSG message that uses m_curwnd
    // to get the selected directory (GetUIText).
    // because m_curwnd is still outdated, dir varialble is
    // filled with an empty string. by default, dir points
    // to $INSTDIR.
    //
    // to solve this, m_curwnd is manually set to the correct
    // window handle.

    m_curwnd=hwndDlg;

    my_SetWindowText(hDir,dir);
    SetUITextFromLang(IDC_BROWSE,this_page->parms[2]);
    SetUITextFromLang(IDC_SELDIRTEXT,this_page->parms[1]);
    SetActiveCtl(hDir);

    {
      typedef HRESULT (WINAPI *SHAutoCompletePtr)(HWND, DWORD);
      SHAutoCompletePtr fSHAutoComplete;
      static const TCHAR shlwapi[] = TEXT("shlwapi.dll");
      static const char shac[] = "SHAutoComplete";
      fSHAutoComplete = (SHAutoCompletePtr) myGetProcAddress((TCHAR *)shlwapi, (char *) shac);
      if (fSHAutoComplete)
      {
        fSHAutoComplete(hDir, SHACF_FILESYSTEM);
      }
    }
  }
  if (uMsg == WM_COMMAND)
  {
    int id=LOWORD(wParam);
    if (id == IDC_DIR && HIWORD(wParam) == EN_CHANGE)
    {
      uMsg = WM_IN_UPDATEMSG;
    }
    if (id == IDC_BROWSE)
    {
      static TCHAR bt[NSIS_MAX_STRLEN];
      BROWSEINFO bi = {0,};
      ITEMIDLIST *idlist;
      bi.hwndOwner = hwndDlg;
      bi.pszDisplayName = g_tmp;
      bi.lpfn = BrowseCallbackProc;
      bi.lParam = (LPARAM)dir;
      bi.lpszTitle = GetNSISString(bt, browse_text);
      bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_NEWDIALOGSTYLE;
      idlist = SHBrowseForFolder(&bi);
      if (idlist)
      {
        // free idlist
        FreePIDL(idlist);

        addtrailingslash(dir);

        if (g_header->install_directory_auto_append &&
          dir == state_install_directory) // only append to $INSTDIR (bug #1174184)
        {
          const TCHAR *post_str = ps_tmpbuf;
          GetNSISStringTT(g_header->install_directory_auto_append);
          // display name gives just the folder name
          if (lstrcmpi(post_str, g_tmp))
          {
            mystrcat(dir, post_str);
          }
        }

        dontsetdefstyle++;
        SetUITextNT(IDC_DIR,dir);
      }
      else
      {
        uMsg = WM_IN_UPDATEMSG;
      }
    }
  }
  if (uMsg == WM_IN_UPDATEMSG || uMsg == WM_NOTIFY_START)
  {
    static TCHAR s[NSIS_MAX_STRLEN];
    TCHAR *p;
    int error = 0;
    int available_set = 0;
    unsigned total, available = 0xFFFFFFFF;

    GetUIText(IDC_DIR,dir);
    if (!is_valid_instpath(dir))
      error = NSIS_INSTDIR_INVALID;

    mystrcpy(s,dir);
    p=skip_root(s);
    if (p)
      *p=0;

    // Test for and use the GetDiskFreeSpaceEx API
    {
#ifdef UNICODE
			BOOL (WINAPI *GDFSE)(LPCTSTR, PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER) =
          myGetProcAddress(L"KERNEL32.dll", "GetDiskFreeSpaceExW");
#else
      BOOL (WINAPI *GDFSE)(LPCSTR, PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER) =
          myGetProcAddress("KERNEL32.dll", "GetDiskFreeSpaceExA");
#endif
      if (GDFSE)
      {
        ULARGE_INTEGER available64;
        ULARGE_INTEGER a, b;
        if (GDFSE(s, &available64, &a, &b))
        {
#ifndef _NSIS_NO_INT64_SHR
          available = (int)(available64.QuadPart >> 10);
#else
          available = (int)(Int64ShrlMod32(available64.QuadPart, 10));
#endif
          available_set++;
        }
      }
    }

    if (!available_set)
    {
      // GetDiskFreeSpaceEx is not available
      DWORD spc, bps, fc, tc;
      if (GetDiskFreeSpace(s, &spc, &bps, &fc, &tc))
      {
        available = (int)MulDiv(bps * spc, fc, 1 << 10);
        available_set++;
      }
    }

    total = (unsigned) sumsecsfield(size_kb);

    if (available < total)
      error = NSIS_INSTDIR_NOT_ENOUGH_SPACE;

    if (LANG_STR_TAB(LANG_SPACE_REQ)) {
      SetSizeText(IDC_SPACEREQUIRED,LANG_SPACE_REQ,total);
      if (available_set)
        SetSizeText(IDC_SPACEAVAILABLE,LANG_SPACE_AVAIL,available);
      else
        SetUITextNT(IDC_SPACEAVAILABLE,TEXT(""));
    }

    g_exec_flags.instdir_error = error;

#ifdef NSIS_SUPPORT_CODECALLBACKS
    if (!error)
      error = ExecuteCallbackFunction(CB_ONVERIFYINSTDIR);
#endif

    if (thispage->flags & PF_DIR_NO_BTN_DISABLE)
      error = 0;

    EnableNext(!error);
    if (!error && !dontsetdefstyle)
      SetNextDef();
    dontsetdefstyle = 0;
  }
Exemplo n.º 6
0
Arquivo: Ui.c Projeto: kichik/nsis-1
FORCE_INLINE int NSISCALL ui_doinstall(void)
{
  header *header = g_header;
  static WNDCLASS wc; // richedit subclassing and bgbg creation

  // detect default language
  // more information at:
  //   http://msdn.microsoft.com/library/default.asp?url=/library/en-us/intl/nls_0xrn.asp

  LANGID (WINAPI *GUDUIL)();
  static const char guduil[] = "GetUserDefaultUILanguage";

  GUDUIL = myGetProcAddress(TEXT("KERNEL32.dll"), (char *) guduil);
  if (GUDUIL)
  {
    // Windows ME/2000+
    myitoa(state_language, GUDUIL());
  }
  else
  {
    *(DWORD*)state_language = CHAR4_TO_DWORD('0', 'x', 0, 0);

    {
      // Windows 9x
      static const TCHAR reg_9x_locale[] = TEXT("Control Panel\\Desktop\\ResourceLocale");

      myRegGetStr(HKEY_CURRENT_USER, reg_9x_locale, NULL, g_tmp);
    }

    if (!g_tmp[0])
    {
      // Windows NT
      // This key exists on 9x as well, so it's only read if ResourceLocale wasn't found
      static const TCHAR reg_nt_locale_key[] = TEXT(".DEFAULT\\Control Panel\\International");
      static const TCHAR reg_nt_locale_val[] = TEXT("Locale");

      myRegGetStr(HKEY_USERS, reg_nt_locale_key, reg_nt_locale_val, g_tmp);
    }

    mystrcat(state_language, g_tmp);
  }

  // set default language
  set_language();

  // initialize auto close flag
  g_exec_flags.autoclose=g_flags&CH_FLAGS_AUTO_CLOSE;

  // read install directory from registry
  if (!is_valid_instpath(state_install_directory))
  {
    if (header->install_reg_key_ptr)
    {
      myRegGetStr(
        (HKEY)header->install_reg_rootkey,
        GetNSISStringNP(header->install_reg_key_ptr),
        GetNSISStringNP(header->install_reg_value_ptr),
        ps_tmpbuf
      );
      if (ps_tmpbuf[0])
      {
        TCHAR *p=ps_tmpbuf;
        TCHAR *e;
        if (p[0]==TEXT('\"'))
        {
          TCHAR *p2;
          p++;
          p2 = findchar(p, TEXT('"'));
          *p2 = 0;
        }
        // p is the path now, check for .exe extension

        e=p+mystrlen(p)-4;
        if (e > p)
        {
          // if filename ends in .exe, and is not a directory, remove the filename
          if (!lstrcmpi(e, TEXT(".exe"))) // check extension
          {
            DWORD d;
            d=GetFileAttributes(p);
            if (d == INVALID_FILE_ATTRIBUTES || !(d&FILE_ATTRIBUTE_DIRECTORY))
            {
              // if there is no back-slash, the string will become empty, but that's ok because
              // it would make an invalid instdir anyway
              trimslashtoend(p);
            }
          }
        }

        mystrcpy(state_install_directory,addtrailingslash(p));
      }
    }
  }
  if (!is_valid_instpath(state_install_directory))
  {
    GetNSISString(state_install_directory,header->install_directory_ptr);
  }

#ifdef NSIS_CONFIG_LOG
  if (g_flags & CH_FLAGS_SILENT_LOG && !g_is_uninstaller)
  {
#if !defined(NSIS_CONFIG_LOG_ODS) && !defined(NSIS_CONFIG_LOG_STDOUT)
    build_g_logfile();
#endif
    log_dolog=1;
  }
#endif

#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
  g_hIcon=LoadImage(g_hInstance,MAKEINTRESOURCE(IDI_ICON2),IMAGE_ICON,0,0,LR_DEFAULTSIZE|LR_SHARED);
#ifdef NSIS_SUPPORT_BGBG
  if (header->bg_color1 != -1)
  {
    QTCHAR cn = CHAR4_TO_DWORD(TEXT('_'), TEXT('N'), TEXT('b'), 0);
    RECT vp;
    extern LRESULT CALLBACK BG_WndProc(HWND, UINT, WPARAM, LPARAM);
    wc.lpfnWndProc = BG_WndProc;
    wc.hInstance = g_hInstance;
    wc.hIcon = g_hIcon;
    //wc.hCursor = LoadCursor(NULL,IDC_ARROW);
    wc.lpszClassName = (LPCTSTR)&cn;

    if (!RegisterClass(&wc)) return 0;

    SystemParametersInfo(SPI_GETWORKAREA, 0, &vp, 0);

    m_bgwnd = CreateWindowEx(WS_EX_TOOLWINDOW,(LPCTSTR)&cn,0,WS_POPUP,
      vp.left,vp.top,vp.right-vp.left,vp.bottom-vp.top,0,NULL,g_hInstance,NULL);
  }

#endif//NSIS_SUPPORT_BGBG

#endif//NSIS_CONFIG_VISIBLE_SUPPORT

#ifdef NSIS_SUPPORT_CODECALLBACKS
  // Select language
  if (ExecuteCallbackFunction(CB_ONINIT)) return 2;
  set_language();
#endif

#ifdef NSIS_CONFIG_VISIBLE_SUPPORT

#ifdef NSIS_CONFIG_SILENT_SUPPORT
  if (!g_exec_flags.silent)
#endif//NSIS_CONFIG_SILENT_SUPPORT
  {
#ifdef NSIS_SUPPORT_BGBG
    ShowWindow(m_bgwnd, SW_SHOW);
#endif//NSIS_SUPPORT_BGBG

#ifdef NSIS_CONFIG_LICENSEPAGE
    { // load richedit DLL
      static TCHAR str1[]=TEXT("RichEd20.dll");
#ifdef UNICODE
      static wchar_t str2[]=L"RichEdit20W";
#else
			static char str2[]="RichEdit20A";
#endif
      if (!LoadLibrary(str1))
      {
        *(DTCHAR*)(str1+6) = CHAR2_TO_WORD(TEXT('3'),TEXT('2'));
        LoadLibrary(str1);
      }

      // make richedit20a point to RICHEDIT
      if (!GetClassInfo(NULL,str2,&wc))
      {
        str2[8]=0;
        GetClassInfo(NULL,str2,&wc);
        wc.lpszClassName = str2;
        str2[8]=TEXT('2');
        RegisterClass(&wc);
      }
    }
#endif

    {
      int ret=DialogBox(g_hInstance,MAKEINTRESOURCE(IDD_INST+dlg_offset),0,DialogProc);
#if defined(NSIS_SUPPORT_CODECALLBACKS) && defined(NSIS_CONFIG_ENHANCEDUI_SUPPORT)
      ExecuteCallbackFunction(CB_ONGUIEND);
#endif
      return ret;
    }
  }
#endif//NSIS_CONFIG_VISIBLE_SUPPORT
#ifdef NSIS_CONFIG_SILENT_SUPPORT
#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
  else
#endif//NSIS_CONFIG_VISIBLE_SUPPORT
  {
    if (install_thread(NULL))
    {
#ifdef NSIS_SUPPORT_CODECALLBACKS
      if (!g_quit_flag) ExecuteCallbackFunction(CB_ONINSTFAILED);
#endif//NSIS_SUPPORT_CODECALLBACKS
      return 2;
    }
#ifdef NSIS_SUPPORT_CODECALLBACKS
    ExecuteCallbackFunction(CB_ONINSTSUCCESS);
#endif//NSIS_SUPPORT_CODECALLBACKS

    return 0;
  }
#endif//NSIS_CONFIG_SILENT_SUPPORT
}
Exemplo n.º 7
0
Arquivo: Main.c Projeto: kichik/nsis-1
NSIS_ENTRYPOINT_GUINOCRT
EXTERN_C void NSISWinMainNOCRT()
{
  int ret = 0;
  const TCHAR *m_Err = _LANG_ERRORWRITINGTEMP;

  int cl_flags = 0;

  TCHAR *realcmds;
  TCHAR seekchar=_T(' ');
  TCHAR *cmdline;

  InitCommonControls();

  SetErrorMode(SEM_NOOPENFILEERRORBOX | SEM_FAILCRITICALERRORS);

#if defined(NSIS_SUPPORT_ACTIVEXREG) || defined(NSIS_SUPPORT_CREATESHORTCUT)
  {
    extern HRESULT g_hres;
    g_hres=OleInitialize(NULL);
  }
#endif

  // load shfolder.dll before any script code is executed to avoid
  // weird situations where SetOutPath or even the extraction of 
  // shfolder.dll will cause unexpected behavior.
  //
  // this also prevents the following:
  //
  //  SetOutPath "C:\Program Files\NSIS" # maybe read from reg
  //  File shfolder.dll
  //  Delete $PROGRAMFILES\shfolder.dll # can't be deleted, as the
  //                                    # new shfolder.dll is used
  //                                    # to find its own path.
  g_SHGetFolderPath = myGetProcAddress(MGA_SHGetFolderPath);

  {
    // workaround for bug #1008632
    // http://sourceforge.net/tracker/index.php?func=detail&aid=1008632&group_id=22049&atid=373085
    //
    // without this, SHGetSpecialFolderLocation doesn't always recognize
    // some special folders, like the desktop folder for all users, on
    // Windows 9x. unlike SHGetSpecialFolderPath, which is not available
    // on all versions of Windows, SHGetSpecialFolderLocation doesn't try
    // too hard to make sure the caller gets what he asked for. so we give
    // it a little push in the right direction by doing part of the work
    // for it.
    //
    // part of what SHGetFileInfo does, is to convert a path into an idl.
    // to do this conversion, it first needs to initialize the list of 
    // special idls, which are exactly the idls we use to get the paths
    // of special folders (CSIDL_*).

    SHFILEINFO shfi;
    SHGetFileInfo(_T(""), 0, &shfi, sizeof(SHFILEINFO), 0);
  }

  mystrcpy(g_caption,_LANG_GENERIC_ERROR);

  mystrcpy(state_command_line, GetCommandLine());

#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
  g_hInstance = GetModuleHandle(NULL);
#endif//NSIS_CONFIG_VISIBLE_SUPPORT

  cmdline = state_command_line;
  if (*cmdline == _T('\"')) seekchar = *cmdline++;

  cmdline=findchar(cmdline, seekchar);
  cmdline=CharNext(cmdline);
  realcmds=cmdline;

  while (*cmdline)
  {
    // skip over any spaces
    while (*cmdline == _T(' ')) cmdline++;
    
    // get char we should look for to get the next parm
    seekchar = _T(' ');
    if (cmdline[0] == _T('\"'))
    {
      cmdline++;
      seekchar = _T('\"');
    }

    // is it a switch?
    if (cmdline[0] == _T('/'))
    {
      cmdline++;

#define END_OF_ARG(c) (c == _T(' ') || c == _T('\0'))

#if defined(NSIS_CONFIG_VISIBLE_SUPPORT) && defined(NSIS_CONFIG_SILENT_SUPPORT)
      if (cmdline[0] == _T('S') && END_OF_ARG(cmdline[1]))
        cl_flags |= FH_FLAGS_SILENT;
#endif//NSIS_CONFIG_SILENT_SUPPORT && NSIS_CONFIG_VISIBLE_SUPPORT
#ifdef NSIS_CONFIG_CRC_SUPPORT
      if (CMP4CHAR(cmdline, _T("NCRC")) && END_OF_ARG(cmdline[4]))
        cl_flags |= FH_FLAGS_NO_CRC;
#endif//NSIS_CONFIG_CRC_SUPPORT

      if (CMP4CHAR(cmdline-2, _T(" /D=")))
      {
        *(cmdline-2)=_T('\0'); // keep this from being passed to uninstaller if necessary
        mystrcpy(state_install_directory,cmdline+2);
        break; // /D= must always be last
      }
    }

    // skip over our parm
    cmdline = findchar(cmdline, seekchar);
    // skip the quote
    if (*cmdline == _T('\"'))
      cmdline++;
  }

  GetTempPath(NSIS_MAX_STRLEN, state_temp_dir);
  if (!ValidateTempDir())
  {
    GetWindowsDirectory(state_temp_dir, NSIS_MAX_STRLEN - 5); // leave space for \Temp
    mystrcat(state_temp_dir, _T("\\Temp"));
    if (!ValidateTempDir())
    {
      // Bug #2909242:
      // When running at <= Low IL we cannot write to %Temp% but we can try the temp folder used by IE.
      // There does not seem to be a API to get the low temp dir directly, so we build the path on our own

      GetTempPath(NSIS_MAX_STRLEN - 4, state_temp_dir); // leave space for \Low
      mystrcat(state_temp_dir, _T("Low"));

      // If we don't call SetEnvironmentVariable 
      // child processes will use %temp% and not %temp%\Low
      // and some apps probably can't handle a read only %temp%
      // Do it before ValidateTempDir() because it appends a backslash.
      // TODO: Should this be moved to ValidateTempDir() so it also updates for %windir%\Temp?
      SetEnvironmentVariable(_T("TEMP"), state_temp_dir);
      SetEnvironmentVariable(_T("TMP"), state_temp_dir);

      if (!ValidateTempDir())
      {
        goto end;
      }
    }
  }
  DeleteFile(state_language);

  m_Err = loadHeaders(cl_flags);
  if (m_Err) goto end;

#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
  if (g_is_uninstaller)
  {
    TCHAR *p = findchar(state_command_line, 0);

    // state_command_line has state_install_directory right after it in memory, so reading
    // a bit over state_command_line won't do any harm
    while (p >= state_command_line && !CMP4CHAR(p, _T(" _?="))) p--;

    m_Err = _LANG_UNINSTINITERROR;

    if (p >= state_command_line)
    {
      *p=0; // terminate before "_?="
      p+=4; // skip over " _?="
      if (is_valid_instpath(p))
      {
        mystrcpy(state_install_directory, p);
        mystrcpy(state_output_directory, p);
        m_Err = 0;
      }
      else
      {
        goto end;
      }
    }
    else
    {
      int x;

      mystrcat(state_temp_dir,_T("~nsu.tmp"));

      // check if already running from uninstaller temp dir
      // this prevents recursive uninstaller calls
      if (!lstrcmpi(state_temp_dir,state_exe_directory))
        goto end;

      CreateDirectory(state_temp_dir,NULL);
      SetCurrentDirectory(state_temp_dir);

      if (!state_install_directory[0])
        mystrcpy(state_install_directory,state_exe_directory);

      mystrcpy(g_usrvars[0], realcmds);
      SET2CHAR(g_usrvars[1], _T("A\0"));

      for (x = 0; x < 26; x ++)
      {
        static TCHAR buf2[NSIS_MAX_STRLEN];

        GetNSISString(buf2,g_header->str_uninstchild); // $TEMP\$1u_.exe

        DeleteFile(buf2); // clean up after all the other ones if they are there

        if (m_Err) // not done yet
        {
          // copy file
          if (CopyFile(state_exe_path,buf2,TRUE))
          {
            HANDLE hProc;
#ifdef NSIS_SUPPORT_MOVEONREBOOT
            MoveFileOnReboot(buf2,NULL);
#endif
            GetNSISString(buf2,g_header->str_uninstcmd); // '"$TEMP\$1u_.exe" $0 _?=$INSTDIR\'
            hProc=myCreateProcess(buf2);
            if (hProc)
            {
              CloseHandle(hProc);
              // success
              m_Err = 0;
            }
          }
        }
        g_usrvars[1][0]++;
      }

#ifdef NSIS_SUPPORT_MOVEONREBOOT
      MoveFileOnReboot(state_temp_dir,NULL);
#endif

      goto end;
    }
  }
#endif//NSIS_CONFIG_UNINSTALL_SUPPORT

  g_exec_flags.errlvl = -1;
  ret = ui_doinstall();

#ifdef NSIS_CONFIG_LOG
#if !defined(NSIS_CONFIG_LOG_ODS) && !defined(NSIS_CONFIG_LOG_STDOUT)
  log_write(1);
#endif//!NSIS_CONFIG_LOG_ODS && !NSIS_CONFIG_LOG_STDOUT
#endif//NSIS_CONFIG_LOG
end:

  CleanUp();

#if defined(NSIS_SUPPORT_ACTIVEXREG) || defined(NSIS_SUPPORT_CREATESHORTCUT)
  OleUninitialize();
#endif

  if (m_Err)
  {
    my_MessageBox(m_Err, MB_OK | MB_ICONSTOP | (IDOK << 21));
    ExitProcess(2);
  }

#ifdef NSIS_SUPPORT_REBOOT
  if (g_exec_flags.reboot_called)
  {
    BOOL (WINAPI *OPT)(HANDLE, DWORD,PHANDLE);
    BOOL (WINAPI *LPV)(LPCTSTR,LPCTSTR,PLUID);
    BOOL (WINAPI *ATP)(HANDLE,BOOL,PTOKEN_PRIVILEGES,DWORD,PTOKEN_PRIVILEGES,PDWORD);
    OPT=myGetProcAddress(MGA_OpenProcessToken);
    LPV=myGetProcAddress(MGA_LookupPrivilegeValue);
    ATP=myGetProcAddress(MGA_AdjustTokenPrivileges);
    if (OPT && LPV && ATP)
    {
      HANDLE hToken;
      TOKEN_PRIVILEGES tkp;
      if (OPT(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
      {
        LPV(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid);
        tkp.PrivilegeCount = 1;
        tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
        ATP(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0);
      }
    }

    if (!ExitWindowsEx(EWX_REBOOT,0))
      ExecuteCallbackFunction(CB_ONREBOOTFAILED);
  }
#endif//NSIS_SUPPORT_REBOOT

  if (g_exec_flags.errlvl != -1)
    ret = g_exec_flags.errlvl;

  ExitProcess(ret);
}
Exemplo n.º 8
0
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInst,LPSTR lpszCmdParam, int nCmdShow)
{
    int ret = 0;
    const char *m_Err = _LANG_ERRORWRITINGTEMP;

    int cl_flags = 0;

    char *realcmds;
    char seekchar=' ';
    char *cmdline;

    InitCommonControls();

#if defined(NSIS_SUPPORT_ACTIVEXREG) || defined(NSIS_SUPPORT_CREATESHORTCUT)
    {
        extern HRESULT g_hres;
        g_hres=OleInitialize(NULL);
    }
#endif

    mystrcpy(g_caption,_LANG_GENERIC_ERROR);

    GetTempPath(NSIS_MAX_STRLEN, state_temp_dir);
    if (!ValidateTempDir())
    {
        GetWindowsDirectory(state_temp_dir, NSIS_MAX_STRLEN - 5); // leave space for \Temp
        mystrcat(state_temp_dir, "\\Temp");
        if (!ValidateTempDir())
        {
            goto end;
        }
    }
    DeleteFile(state_command_line);

    lstrcpyn(state_command_line, GetCommandLine(), NSIS_MAX_STRLEN);

#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
    g_hInstance = GetModuleHandle(NULL);
#endif//NSIS_CONFIG_VISIBLE_SUPPORT

    cmdline = state_command_line;
    if (*cmdline == '\"') seekchar = *cmdline++;

    cmdline=findchar(cmdline, seekchar);
    cmdline=CharNext(cmdline);
    realcmds=cmdline;

    while (*cmdline)
    {
        // skip over any spaces
        while (*cmdline == ' ') cmdline++;

        // get char we should look for to get the next parm
        seekchar = ' ';
        if (cmdline[0] == '\"')
        {
            cmdline++;
            seekchar = '\"';
        }

        // is it a switch?
        if (cmdline[0] == '/')
        {
            cmdline++;

// this only works with spaces because they have just one bit on
#define END_OF_ARG(c) (((c)|' ')==' ')

#if defined(NSIS_CONFIG_VISIBLE_SUPPORT) && defined(NSIS_CONFIG_SILENT_SUPPORT)
            if (cmdline[0] == 'S' && END_OF_ARG(cmdline[1]))
                cl_flags |= FH_FLAGS_SILENT;
#endif//NSIS_CONFIG_SILENT_SUPPORT && NSIS_CONFIG_VISIBLE_SUPPORT
#ifdef NSIS_CONFIG_CRC_SUPPORT
            if (*(LPDWORD)cmdline == CHAR4_TO_DWORD('N','C','R','C') && END_OF_ARG(cmdline[4]))
                cl_flags |= FH_FLAGS_NO_CRC;
#endif//NSIS_CONFIG_CRC_SUPPORT

            if (*(LPDWORD)(cmdline-2) == CHAR4_TO_DWORD(' ', '/', 'D','='))
            {
                cmdline[-2]=0; // keep this from being passed to uninstaller if necessary
                mystrcpy(state_install_directory,cmdline+2);
                break; // /D= must always be last
            }
        }

        // skip over our parm
        cmdline = findchar(cmdline, seekchar);
        // skip the quote
        if (*cmdline == '\"')
            cmdline++;
    }

    m_Err = loadHeaders(cl_flags);
    if (m_Err) goto end;

#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
    if (g_is_uninstaller)
    {
        char *p = findchar(state_command_line, 0);

        // state_command_line has state_install_directory right after it in memory, so reading
        // a bit over state_command_line won't do any harm
        while (p >= state_command_line && *(LPDWORD)p != CHAR4_TO_DWORD(' ', '_', '?', '=')) p--;

        m_Err = _LANG_UNINSTINITERROR;

        if (p >= state_command_line)
        {
            *p=0; // terminate before "_?="
            p+=4; // skip over " _?="
            if (is_valid_instpath(p))
            {
                mystrcpy(state_install_directory, p);
                mystrcpy(state_output_directory, p);
                m_Err = 0;
            }
            else
            {
                goto end;
            }
        }
        else
        {
            int x;

            mystrcat(state_temp_dir,"~nsu.tmp\\");
            CreateDirectory(state_temp_dir,NULL);

            for (x = 0; x < 26; x ++)
            {
                static char s[]="Au_.exe";
                static char buf2[NSIS_MAX_STRLEN*2];
                static char ibuf[NSIS_MAX_STRLEN];

                *(LPWORD)buf2=CHAR2_TO_WORD('\"',0);
                mystrcat(buf2,state_temp_dir);
                mystrcat(buf2,s);

                DeleteFile(buf2+1); // clean up after all the other ones if they are there

                if (m_Err) // not done yet
                {
                    // get current name
                    int l=GetModuleFileName(g_hInstance,ibuf,sizeof(ibuf));
                    // check if it is ?Au_.exe - if so, f**k it
                    if (!lstrcmpi(ibuf+l-(sizeof(s)-2),s+1)) break;

                    // copy file
                    if (CopyFile(ibuf,buf2+1,FALSE))
                    {
                        HANDLE hProc;
#ifdef NSIS_SUPPORT_MOVEONREBOOT
                        MoveFileOnReboot(buf2+1,NULL);
#endif
                        if (state_install_directory[0]) mystrcpy(ibuf,state_install_directory);
                        else trimslashtoend(ibuf);
                        mystrcat(buf2,"\" ");
                        mystrcat(buf2,realcmds);
                        mystrcat(buf2," _?=");
                        mystrcat(buf2,ibuf);
                        // add a trailing backslash to make sure is_valid_instpath will not fail when it shouldn't
                        addtrailingslash(buf2);
                        hProc=myCreateProcess(buf2,state_temp_dir);
                        if (hProc)
                        {
                            CloseHandle(hProc);
                            // success
                            m_Err = 0;
                        }
                    }
                }
                s[0]++;
            }
            goto end;
        }
    }
#endif//NSIS_CONFIG_UNINSTALL_SUPPORT

    g_exec_flags.errlvl = -1;
    ret = ui_doinstall();

#ifdef NSIS_CONFIG_LOG
#ifndef NSIS_CONFIG_LOG_ODS
    log_write(1);
#endif//!NSIS_CONFIG_LOG_ODS
#endif//NSIS_CONFIG_LOG
end:

    CleanUp();

#if defined(NSIS_SUPPORT_ACTIVEXREG) || defined(NSIS_SUPPORT_CREATESHORTCUT)
    OleUninitialize();
#endif

    if (m_Err)
    {
        my_MessageBox(m_Err, MB_OK | MB_ICONSTOP | (IDOK << 21));
        ExitProcess(2);
        return 0;
    }

#ifdef NSIS_SUPPORT_REBOOT
    if (g_exec_flags.reboot_called)
    {
        BOOL (WINAPI *OPT)(HANDLE, DWORD,PHANDLE);
        BOOL (WINAPI *LPV)(LPCTSTR,LPCTSTR,PLUID);
        BOOL (WINAPI *ATP)(HANDLE,BOOL,PTOKEN_PRIVILEGES,DWORD,PTOKEN_PRIVILEGES,PDWORD);
        OPT=myGetProcAddress("ADVAPI32.dll","OpenProcessToken");
        LPV=myGetProcAddress("ADVAPI32.dll","LookupPrivilegeValueA");
        ATP=myGetProcAddress("ADVAPI32.dll","AdjustTokenPrivileges");
        if (OPT && LPV && ATP)
        {
            HANDLE hToken;
            TOKEN_PRIVILEGES tkp;
            if (OPT(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
            {
                LPV(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid);
                tkp.PrivilegeCount = 1;
                tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
                ATP(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0);
            }
        }

        if (!ExitWindowsEx(EWX_REBOOT,0))
            ExecuteCallbackFunction(CB_ONREBOOTFAILED);
    }
#endif//NSIS_SUPPORT_REBOOT

    if (g_exec_flags.errlvl != -1)
        ret = g_exec_flags.errlvl;

    ExitProcess(ret);
    return 0;
}
Exemplo n.º 9
0
int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
	// get the wide command line args
	TCHAR * commandLine = lpCmdLine;
	if (wcslen(commandLine) == 0)
		return 0;

	// First character is an Identifier, the rest is the TargetPath
	TCHAR actionType = commandLine[0];
	TCHAR * targetPath = &commandLine[1];

	// act on the input
	if (actionType == L'K')
	{
		// kill instances of BumpTop and the Settings
		KILL_PROC_BY_NAME(L"BumpTop.exe");
		KILL_PROC_BY_NAME(L"BumpTop Settings.exe");
	}
	else if (actionType == L'I') // install
	{
		TCHAR appPath[MAX_PATH] = {0};
		TCHAR cwd[MAX_PATH] = {0};
		TCHAR * params = NULL;
		getCurrentDirectory(cwd, MAX_PATH);
		wcscpy_s(appPath, cwd);
		PathAppend(appPath, L"BumpTopUpdater.exe");
		int installLevel = _ttoi(targetPath);
		switch (installLevel)
		{
		case INSTALLUILEVEL_NONE: // completely silent installation
		case INSTALLUILEVEL_REDUCED:
			params = L"/SILENT /SUPPRESSMSGBOXES /NORESTART /LOG";
			break;
		default:
			params = L"/SP /LOG";
			break;
		}
		ShellExecute(NULL, NULL, appPath, params, cwd, SW_SHOW);
	}
	else if (actionType == L'U')
	{
		// first check if a previous version is even installed
		HMODULE hMSIDll = LoadLibrary(L"Msi.dll");
		if (hMSIDll)
		{
			TCHAR productCode[MAX_PATH];
			typedef UINT (WINAPI *PFN_MsiEnumRelatedProducts)(LPCTSTR lpUpgradeCode, DWORD dwReserved, DWORD iProductIndex, LPTSTR lpProductBuf);
			const PFN_MsiEnumRelatedProducts pfnMsiEnumRelatedProducts = myGetProcAddress(hMSIDll, MsiEnumRelatedProducts);
			typedef UINT (WINAPI *PFN_MsiQueryProductState)(LPCTSTR szProduct);
			const PFN_MsiQueryProductState pfnMsiQueryProductState = myGetProcAddress(hMSIDll, MsiQueryProductState);

			bool refreshWithDummyMSI = false;
			if (pfnMsiEnumRelatedProducts)
			{
				int i = 0; 
				while (true)
				{
					UINT result = pfnMsiEnumRelatedProducts(L"{67F5070F-3518-4B01-9024-10AB27C58446}", 0, i, productCode);
					if (result == ERROR_SUCCESS)
					{
						if (INSTALLSTATE_UNKNOWN != pfnMsiQueryProductState(productCode))
						{
							refreshWithDummyMSI = true;
							break;
						}
					}
					else
					{
						break;
					}
					++i;
				}
			} 

			if (refreshWithDummyMSI)
			{
				return 1;
			}

			FreeLibrary(hMSIDll);
		}
	}
	else if (actionType == L'S')
	{
#ifndef DISABLE_PHONING
		// only launch the survey if we aren't upgrading (upgrade product id should be empty parameter)
		if (wcslen(targetPath) == 0)
		{
			TCHAR link[256] = {0};
			TCHAR * address = L"http://www.bumptop.com/uninstall?version=";
			TCHAR * version = _T(SVN_VERSION_NUMBER);
			_tcscat(link, address);
			_tcscat(link, version);

			ShellExecute(NULL, NULL, link, NULL, NULL, SW_SHOW);
		}
#endif
	}
	else if (actionType == L'X')
	{
		TCHAR appPath[MAX_PATH] = {0};
		TCHAR cwd[MAX_PATH] = {0};
		TCHAR * params = NULL;
		getCurrentDirectory(cwd, MAX_PATH);
		wcscpy_s(appPath, cwd);
		PathAppend(appPath, L"unins000.exe");
		// uninstall without prompts if we are upgrading (upgrade product id will be non-empty parameter)
		if (wcslen(targetPath) == 0)
		{
			params = L"/SILENT /SUPPRESSMSGBOXES /NORESTART";
		}
		else
		{
			params = L"/VERYSILENT /SUPPRESSMSGBOXES /NORESTART";
		}
		ShellExecute(NULL, NULL, appPath, params, cwd, SW_SHOW);
	}

	return 0;
}