Exemplo n.º 1
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
  g_exec_flags.autoclose=g_flags&CH_FLAGS_AUTO_CLOSE;

  set_language();

  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])
      {
        char *p=ps_tmpbuf;
        char *e;
        if (p[0]=='\"')
        {
          char *p2;
          p++;
          p2 = findchar(p, '"');
          *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, ".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)
  {
#ifndef NSIS_CONFIG_LOG_ODS
    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)
  {
    DWORD cn = CHAR4_TO_DWORD('_', 'N', '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 = (LPCSTR)&cn;

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

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

    m_bgwnd = CreateWindowEx(WS_EX_TOOLWINDOW,(LPCSTR)&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 char str1[]="RichEd20.dll";
      static char str2[]="RichEdit20A";
      if (!LoadLibrary(str1))
      {
        *(WORD*)(str1+6) = CHAR2_TO_WORD('3','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]='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.º 2
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.º 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)();
  static const char guduil[] = "GetUserDefaultUILanguage";

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

    {
      // Windows 9x
      static const char reg_9x_locale[] = "Control Panel\\Desktop\\ResourceLocale";

      myRegGetStr(HKEY_CURRENT_USER, reg_9x_locale, NULL, state_language + 2);
    }

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

      myRegGetStr(HKEY_USERS, reg_nt_locale_key, reg_nt_locale_val, state_language + 2);
    }
  }

  // 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])
      {
        char *p=ps_tmpbuf;
        char *e;
        if (p[0]=='\"')
        {
          char *p2;
          p++;
          p2 = findchar(p, '"');
          *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, ".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)
  {
#ifndef NSIS_CONFIG_LOG_ODS
    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)
  {
    DWORD cn = CHAR4_TO_DWORD('_', 'N', '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 = (LPCSTR)&cn;

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

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

    m_bgwnd = CreateWindowEx(WS_EX_TOOLWINDOW,(LPCSTR)&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 char str1[]="RichEd20.dll";
      static char str2[]="RichEdit20A";
      if (!LoadLibrary(str1))
      {
        *(WORD*)(str1+6) = CHAR2_TO_WORD('3','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]='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.º 4
0
bool WINAPI SaveSettings(void) {
  static char szField[25];
  int nBufLen = BUFFER_SIZE;
  char *pszBuffer = (char*)MALLOC(nBufLen);
  if (!pszBuffer) return false;

  int nIdx;
  int CurrField;
  for (nIdx = 0, CurrField = 1; nIdx < nNumFields; nIdx++, CurrField++) {
    FieldType *pField = pFields + nIdx;
    HWND hwnd = pField->hwnd;
    switch (pField->nType) {
      case FIELD_BROWSEBUTTON:
        if (g_NotifyField > CurrField)
          --g_NotifyField;
        --CurrField;
      default:
        continue;

      case FIELD_CHECKBOX:
      case FIELD_RADIOBUTTON:
        wsprintf(pszBuffer, "%d", !!mySendMessage(hwnd, BM_GETCHECK, 0, 0));
        break;

      case FIELD_LISTBOX:
      {
        // Ok, this one requires a bit of work.
        // First, we allocate a buffer long enough to hold every item.
        // Then, we loop through every item and if it's selected we add it to our buffer.
        // If there is already an item in the list, then we prepend a | character before the new item.
        // We could simplify for single-select boxes, but using one piece of code saves some space.
        int nLength = lstrlen(pField->pszListItems) + 10;
        if (nLength > nBufLen) {
          FREE(pszBuffer);
          nBufLen = nLength;
          pszBuffer = (char*)MALLOC(nBufLen);
          if (!pszBuffer) return false;
        }
        char *pszItem = (char*)MALLOC(nBufLen);
        if (!pszItem) return false;

        *pszBuffer = '\0';
        int nNumItems = mySendMessage(hwnd, LB_GETCOUNT, 0, 0);
        for (int nIdx2 = 0; nIdx2 < nNumItems; nIdx2++) {
          if (mySendMessage(hwnd, LB_GETSEL, nIdx2, 0) > 0) {
            if (*pszBuffer) lstrcat(pszBuffer, "|");
            mySendMessage(hwnd, LB_GETTEXT, (WPARAM)nIdx2, (LPARAM)pszItem);
            lstrcat(pszBuffer, pszItem);
          }
        }

        FREE(pszItem);
        break;
      }

      case FIELD_TEXT:
      case FIELD_FILEREQUEST:
      case FIELD_DIRREQUEST:
      case FIELD_COMBOBOX:
      {
        int nLength = mySendMessage(pField->hwnd, WM_GETTEXTLENGTH, 0, 0);
        if (nLength > nBufLen) {
          FREE(pszBuffer);
          // add a bit extra so we do this less often
          nBufLen = nLength + 20;
          pszBuffer = (char*)MALLOC(nBufLen);
          if (!pszBuffer) return false;
        }
        *pszBuffer='"';
        GetWindowText(hwnd, pszBuffer+1, nBufLen-1);
        pszBuffer[nLength+1]='"';
        pszBuffer[nLength+2]='\0';

        if (pField->nType == FIELD_TEXT && (pField->nFlags & FLAG_MULTILINE))
        {
          char *pszBuf2 = (char*)MALLOC(nBufLen*2); // double the size, consider the worst case, all chars are \r\n
          char *p1, *p2;
          for (p1 = pszBuffer, p2 = pszBuf2; *p1; p1 = CharNext(p1), p2 = CharNext(p2))
          {
            switch (*p1) {
              case '\t':
                *(LPWORD)p2 = CHAR2_TO_WORD('\\', 't');
                p2++;
                break;
              case '\n':
                *(LPWORD)p2 = CHAR2_TO_WORD('\\', 'n');
                p2++;
                break;
              case '\r':
                *(LPWORD)p2 = CHAR2_TO_WORD('\\', 'r');
                p2++;
                break;
              case '\\':
                *p2++ = '\\';
              default:
                lstrcpyn(p2, p1, CharNext(p1) - p1 + 1);
                break;
            }
          }
          *p2 = 0;
          nBufLen = nBufLen*2;
          FREE(pszBuffer);
          pszBuffer=pszBuf2;
        }
        break;
      }
    }
    wsprintf(szField, "Field %d", CurrField);
    WritePrivateProfileString(szField, "State", pszBuffer, pszFilename);
  }

  // Tell NSIS which control was activated, if any
  wsprintf(pszBuffer, "%d", g_NotifyField);
  WritePrivateProfileString("Settings", "State", pszBuffer, pszFilename);

  FREE(pszBuffer);

  return true;
}
Exemplo n.º 5
0
Arquivo: Main.c Projeto: kichik/nsis-1
int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInst,LPTSTR lpszCmdParam, int nCmdShow)
{
  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++;

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

#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 (*(LPDWORD)cmdline == CHAR4_TO_DWORD(_T('N'),_T('C'),_T('R'),_T('C')) && END_OF_ARG(cmdline[4]))
        cl_flags |= FH_FLAGS_NO_CRC;
#endif//NSIS_CONFIG_CRC_SUPPORT

      if (*(LPDWORD)(cmdline-2) == CHAR4_TO_DWORD(_T(' '), _T('/'), _T('D'),_T('=')))
      {
        *(LPDWORD)(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 == _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())
    {
      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 && *(LPDWORD)p != CHAR4_TO_DWORD(_T(' '), _T('_'), _T('?'), _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);
      *(LPWORD)g_usrvars[1] = CHAR2_TO_WORD(_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);
    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(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);
  return 0;
}
Exemplo n.º 6
0
Arquivo: Ui.c Projeto: kichik/nsis-1
static BOOL CALLBACK DirProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
  static int dontsetdefstyle;
  page *thispage = g_this_page;
  char *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 char 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 char *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 char 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)(LPCSTR, PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER) =
          myGetProcAddress(MGA_GetDiskFreeSpaceExA);
      if (GDFSE)
      {
        ULARGE_INTEGER available64;
        ULARGE_INTEGER a, b;
        char *p;
        WORD *pw = NULL;
        while ((char *) 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
          pw = (LPWORD) (p - 1);
          *pw = CHAR2_TO_WORD('\\', 0); // bring it back, but make the next char null
        }
      }
    }

    if (!available_set)
    {
      DWORD spc, bps, fc, tc;
      char *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 (available_set && 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,"");
    }

    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;
  }