home *** CD-ROM | disk | FTP | other *** search
/ Chip 2004 March / CMCD0304.ISO / Software / Freeware / Programare / nullsoft / nsis20.exe / Source / exehead / exec.c < prev    next >
C/C++ Source or Header  |  2004-02-04  |  44KB  |  1,571 lines

  1. #include "../Platform.h"
  2. #include <shlobj.h>
  3. #include <shellapi.h>
  4. #include "fileform.h"
  5. #include "util.h"
  6. #include "state.h"
  7. #include "ui.h"
  8. #include "exec.h"
  9. #include "lang.h"
  10. #include "resource.h"
  11.  
  12. #define EXEC_ERROR 0x7FFFFFFF
  13.  
  14. #ifdef NSIS_CONFIG_COMPONENTPAGE
  15. HWND g_SectionHack;
  16. #endif
  17.  
  18. #ifdef NSIS_SUPPORT_STACK
  19. typedef struct _stack_t {
  20.   struct _stack_t *next;
  21.   char text[NSIS_MAX_STRLEN];
  22. } stack_t;
  23.  
  24. static stack_t *g_st;
  25. #endif
  26.  
  27. union exec_flags g_exec_flags;
  28.  
  29. #if defined(NSIS_SUPPORT_ACTIVEXREG) || defined(NSIS_SUPPORT_CREATESHORTCUT)
  30. HRESULT g_hres;
  31. #endif
  32.  
  33. #ifdef NSIS_SUPPORT_REGISTRYFUNCTIONS
  34. // based loosely on code from Tim Kosse
  35. // in win9x this isn't necessary (RegDeleteKey() can delete a tree of keys),
  36. // but in win2k you need to do this manually.
  37. static LONG NSISCALL myRegDeleteKeyEx(HKEY thiskey, LPCTSTR lpSubKey, int onlyifempty)
  38. {
  39.   HKEY key;
  40.   int retval=RegOpenKeyEx(thiskey,lpSubKey,0,KEY_ENUMERATE_SUB_KEYS,&key);
  41.   if (retval==ERROR_SUCCESS)
  42.   {
  43.     // NB - don't change this to static (recursive function)
  44.     char buffer[MAX_PATH+1];
  45.     while (RegEnumKey(key,0,buffer,MAX_PATH+1)==ERROR_SUCCESS)
  46.     {
  47.       if (onlyifempty)
  48.       {
  49.         RegCloseKey(key);
  50.         return !ERROR_SUCCESS;
  51.       }
  52.       if ((retval=myRegDeleteKeyEx(key,buffer,0)) != ERROR_SUCCESS) break;
  53.     }
  54.     RegCloseKey(key);
  55.     retval=RegDeleteKey(thiskey,lpSubKey);
  56.   }
  57.   return retval;
  58. }
  59. #endif//NSIS_SUPPORT_REGISTRYFUNCTIONS
  60.  
  61. static int NSISCALL ExecuteEntry(entry *entry_);
  62.  
  63. #define resolveaddr(v) ((v<0) ? myatoi(g_usrvars[-(v+1)]) : v)
  64.  
  65. int NSISCALL ExecuteCodeSegment(int pos, HWND hwndProgress)
  66. {
  67.   while (pos >= 0)
  68.   {
  69.     int rv;
  70.     if (g_entries[pos].which == EW_RET) return 0;
  71.     rv=ExecuteEntry(g_entries + pos);
  72.     if (rv == EXEC_ERROR) return EXEC_ERROR;
  73.  
  74.     rv=resolveaddr(rv);
  75.  
  76.     if (!rv) { rv++; pos++; }
  77.     else
  78.     {
  79.       int t=pos;
  80.       rv--; // rv is decremented here by 1, since it was +1 on the other end.
  81.       pos=rv; // set new position
  82.       rv-=t; // set rv to delta for progress adjustment
  83.     }
  84.  
  85.     if (hwndProgress)
  86.     {
  87.       extern int progress_bar_pos, progress_bar_len;
  88.       progress_bar_pos+=rv;
  89.       SendMessage(hwndProgress,PBM_SETPOS,MulDiv(progress_bar_pos,30000,progress_bar_len+!progress_bar_len),0);
  90.     }
  91.   }
  92.   return 0;
  93. }
  94.  
  95. static char bufs[5][NSIS_MAX_STRLEN];
  96. static int *parms;
  97.  
  98. static int NSISCALL GetIntFromParm(int id_)
  99. {
  100.   return myatoi(GetNSISStringTT(parms[id_]));
  101. }
  102.  
  103. // NB - USE CAUTION when rearranging code to make use of the new return value of
  104. // this function - be sure the parm being accessed is not modified before the call.
  105. // Use a negative number to get the string validated as a file name
  106. static char * NSISCALL GetStringFromParm(int id_)
  107. {
  108.   int id = id_ < 0 ? -id_ : id_;
  109.   char *result = GetNSISString(bufs[id >> 4], parms[id & 0xF]);
  110.   if (id_ < 0) validate_filename(result);
  111.   return result;
  112. }
  113.  
  114. // returns EXEC_ERROR on error
  115. // returns 0, advance position by 1
  116. // otherwise, returns new_position+1
  117. static int NSISCALL ExecuteEntry(entry *entry_)
  118. {
  119.   char *buf0 = bufs[0];
  120.   char *buf1 = bufs[1];
  121.   char *buf2 = bufs[2];
  122.   char *buf3 = bufs[3];
  123.   char *buf4 = bufs[4];
  124.  
  125.   char *var0;
  126.   char *var1;
  127.   //char *var2;
  128.   //char *var3;
  129.   //char *var4;
  130.   //char *var5;
  131.  
  132. #ifdef NSIS_CONFIG_COMPONENTPAGE
  133.   HWND hwSectionHack = g_SectionHack;
  134. #endif
  135.  
  136. #ifdef NSIS_CONFIG_VISIBLE_SUPPORT
  137.   // Saves 8 bytes
  138.   HWND mainHwnd = g_hwnd;
  139. #define g_hwnd mainHwnd
  140. #endif
  141.  
  142.   int exec_error = 0;
  143.  
  144.   entry lent;
  145.   mini_memcpy(&lent, entry_, sizeof(entry));
  146.  
  147. #define which (lent.which)
  148. #define parm0 (lent.offsets[0])
  149. #define parm1 (lent.offsets[1])
  150. #define parm2 (lent.offsets[2])
  151. #define parm3 (lent.offsets[3])
  152. #define parm4 (lent.offsets[4])
  153. #define parm5 (lent.offsets[5])
  154.  
  155.   var0 = g_usrvars[parm0];
  156.   var1 = g_usrvars[parm1];
  157.   // not used yet
  158.   //var2 = g_usrvars[parm2];
  159.   //var3 = g_usrvars[parm3];
  160.   //var4 = g_usrvars[parm4];
  161.   //var5 = g_usrvars[parm5];
  162.  
  163.   parms = lent.offsets;
  164.  
  165.   switch (which)
  166.   {
  167.     case EW_NOP:
  168.       log_printf2("Jump: %d",parm0);
  169.     return parm0;
  170.     case EW_ABORT:
  171.       {
  172.         log_printf2("Aborting: \"%s\"",GetStringFromParm(0x00));
  173.         update_status_text(parm0,0);
  174.       }
  175.     return EXEC_ERROR;
  176.     case EW_QUIT:
  177.       g_quit_flag++;
  178.       if (g_hwnd) PostQuitMessage(0); // make sure we bail out fast.
  179.     return EXEC_ERROR;
  180.     case EW_CALL:
  181.       {
  182.         int v=resolveaddr(parm0)-1;  // address is -1, since we encode it as +1
  183.         log_printf2("Call: %d",v);
  184.         return ExecuteCodeSegment(v,NULL);
  185.       }
  186.     case EW_UPDATETEXT:
  187.       if (parm1) {
  188.         static int old_st_updateflag=6;
  189.         if (parm1&8) ui_st_updateflag=old_st_updateflag;
  190.         else {
  191.           old_st_updateflag=ui_st_updateflag;
  192.           ui_st_updateflag=parm1;
  193.         }
  194.       }
  195.       else
  196.       {
  197.         log_printf2("detailprint: %s",GetStringFromParm(0x00));
  198.         update_status_text(parm0,0);
  199.       }
  200.     break;
  201.     case EW_SLEEP:
  202.       {
  203.         int x=GetIntFromParm(0);
  204.         log_printf2("Sleep(%d)",x);
  205.         Sleep(max(x,1));
  206.       }
  207.     break;
  208. #ifdef NSIS_CONFIG_VISIBLE_SUPPORT
  209.     case EW_BRINGTOFRONT:
  210.       log_printf("BringToFront");
  211.       SetForegroundWindow(g_hwnd);
  212.     break;
  213. #endif//NSIS_CONFIG_VISIBLE_SUPPORT
  214.     case EW_SETFLAG:
  215.       g_exec_flags.flags[parm0]=GetIntFromParm(1);
  216.     break;
  217.     case EW_IFFLAG:
  218.     {
  219.       int f=lent.offsets[!g_exec_flags.flags[parm2]];
  220.       g_exec_flags.flags[parm2]&=parm3;
  221.       return f;
  222.     }
  223.     case EW_GETFLAG:
  224.       myitoa(var0,g_exec_flags.flags[parm1]);
  225.     break;
  226. #ifdef NSIS_CONFIG_VISIBLE_SUPPORT
  227.     case EW_CHDETAILSVIEW:
  228.       if (insthwndbutton) ShowWindow(insthwndbutton,parm1);
  229.       if (insthwnd) ShowWindow(insthwnd,parm0);
  230.     break;
  231. #endif//NSIS_CONFIG_VISIBLE_SUPPORT
  232.     case EW_SETFILEATTRIBUTES:
  233.     {
  234.       char *buf1=GetStringFromParm(-0x10);
  235.       log_printf3("SetFileAttributes: \"%s\":%08X",buf1,parm1);
  236.       if (!SetFileAttributes(buf1,parm1))
  237.       {
  238.         exec_error++;
  239.         log_printf("SetFileAttributes failed.");
  240.       }
  241.     }
  242.     break;
  243.     case EW_CREATEDIR: {
  244.       char *buf1=GetStringFromParm(-0x10);
  245.       log_printf3("CreateDirectory: \"%s\" (%d)",buf1,parm1);
  246.       {
  247.         char *p = skip_root(buf1);
  248.         char c = 'c';
  249.         if (*buf1 && p)
  250.         {
  251.           while (c)
  252.           {
  253.             WIN32_FIND_DATA *fd;
  254.             p = findchar(p, '\\');
  255.             c=*p;
  256.             *p=0;
  257.             fd = file_exists(buf1);
  258.             if (!fd) {
  259.               if (!CreateDirectory(buf1,NULL))
  260.                 exec_error++;
  261.             }
  262.             else if ((fd->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) exec_error++;
  263.             *p++ = c;
  264.           }
  265.         }
  266.       }
  267.       if (parm1)
  268.       {
  269.         update_status_text(LANG_OUTPUTDIR,buf1);
  270.         mystrcpy(state_output_directory,buf1);
  271.         SetCurrentDirectory(buf1);
  272.       }
  273.       else update_status_text(LANG_CREATEDIR,buf1);
  274.     }
  275.     break;
  276.     case EW_IFFILEEXISTS:
  277.     {
  278.       char *buf0=GetStringFromParm(0x00);
  279.       if (file_exists(buf0))
  280.       {
  281.         log_printf3("IfFileExists: file \"%s\" exists, jumping %d",buf0,parm1);
  282.         return parm1;
  283.       }
  284.       log_printf3("IfFileExists: file \"%s\" does not exist, jumping %d",buf0,parm2);
  285.     }
  286.     return parm2;
  287. #ifdef NSIS_SUPPORT_RENAME
  288.     case EW_RENAME:
  289.       {
  290.         char *buf1=GetStringFromParm(-0x10);
  291.         char *buf2=GetStringFromParm(-0x21);
  292.         mystrcpy(buf3,buf1);
  293.         if (mystrlen(buf1)+mystrlen(buf2) < NSIS_MAX_STRLEN-3)
  294.         {
  295.           lstrcat(buf3,"->");
  296.           lstrcat(buf3,buf2);
  297.         }
  298.         log_printf2("Rename: %s",buf3);
  299.         if (MoveFile(buf1,buf2))
  300.         {
  301.           update_status_text(LANG_RENAME,buf3);
  302.         }
  303.         else
  304.         {
  305. #ifdef NSIS_SUPPORT_MOVEONREBOOT
  306.           if (parm2 && file_exists(buf1))
  307.           {
  308.             MoveFileOnReboot(buf1,buf2);
  309.             update_status_text(LANG_RENAMEONREBOOT,buf3);
  310.             log_printf2("Rename on reboot: %s",buf3);
  311.           }
  312.           else
  313. #endif
  314.           {
  315.             exec_error++;
  316.             log_printf2("Rename failed: %s",buf3);
  317.           }
  318.         }
  319.       }
  320.     break;
  321. #endif//NSIS_SUPPORT_RENAME
  322. #ifdef NSIS_SUPPORT_FNUTIL
  323.     case EW_GETFULLPATHNAME:
  324.       {
  325.         char *fp;
  326.         char *p=var1;
  327.         char *buf0=GetStringFromParm(0x00);
  328.         if (!GetFullPathName(buf0,NSIS_MAX_STRLEN,p,&fp))
  329.         {
  330.           exec_error++;
  331.           *p=0;
  332.         }
  333.         else if (fp>buf0 && *fp)
  334.         {
  335.           WIN32_FIND_DATA *fd=file_exists(buf0);
  336.           if (fd)
  337.           {
  338.             mystrcpy(fp,fd->cFileName);
  339.           }
  340.           else
  341.           {
  342.             exec_error++;
  343.             *p=0;
  344.           }
  345.         }
  346.         if (!parm2) GetShortPathName(p,p,NSIS_MAX_STRLEN);
  347.       }
  348.     break;
  349.     case EW_SEARCHPATH:
  350.       {
  351.         char *fp;
  352.         char *p=var0;
  353.         char *buf0=GetStringFromParm(-0x01);
  354.         if (!SearchPath(NULL,buf0,NULL,NSIS_MAX_STRLEN,p,&fp))
  355.         {
  356.           exec_error++;
  357.           p[0]=0;
  358.         }
  359.       }
  360.     break;
  361.     case EW_GETTEMPFILENAME:
  362.       {
  363.         char *textout=var0;
  364.         if (!my_GetTempFileName(textout, GetStringFromParm(-0x11)))
  365.           exec_error++;
  366.       }
  367.     break;
  368. #endif
  369. #ifdef NSIS_SUPPORT_FILE
  370.     case EW_EXTRACTFILE:
  371.       {
  372.         HANDLE hOut;
  373.         int ret;
  374.         char *buf3 = GetStringFromParm(0x31);
  375.         int overwriteflag = parm0 & 7;
  376.  
  377.         log_printf4("File: overwriteflag=%d, allowskipfilesflag=%d, name=\"%s\"",overwriteflag,(parm0>>3)&MB_ABORTRETRYIGNORE,buf3);
  378.         if (validpathspec(buf3))
  379.         {
  380.           mystrcpy(buf0,buf3);
  381.         }
  382.         else lstrcat(addtrailingslash(mystrcpy(buf0,state_output_directory)),buf3);
  383.         validate_filename(buf0);
  384.       _tryagain:
  385.         if (overwriteflag >= 3) // check date and time
  386.         {
  387.           WIN32_FIND_DATA *ffd=file_exists(buf0);
  388.           // if it doesn't exist, overwrite flag will be off (though it doesn't really matter)
  389.           int cmp=0;
  390.           if (ffd)
  391.           {
  392.             cmp=CompareFileTime(&ffd->ftLastWriteTime, (FILETIME*)(lent.offsets + 3));
  393.           }
  394.           overwriteflag=!(cmp & (0x80000000 | (overwriteflag - 3)));
  395.         }
  396.         // remove read only flag if overwrite mode is on
  397.         if (!overwriteflag)
  398.         {
  399.           int attr=GetFileAttributes(buf0);
  400.           SetFileAttributes(buf0,attr&(~FILE_ATTRIBUTE_READONLY));
  401.         }
  402.         hOut=myOpenFile(buf0,GENERIC_WRITE,(overwriteflag==1)?CREATE_NEW:CREATE_ALWAYS);
  403.         if (hOut == INVALID_HANDLE_VALUE)
  404.         {
  405.           if (overwriteflag)
  406.           {
  407.             update_status_text(LANG_SKIPPED,buf3);
  408.             if (overwriteflag==2) g_exec_flags.exec_error++;
  409.             log_printf3("File: skipped: \"%s\" (overwriteflag=%d)",buf0,overwriteflag);
  410.             break;
  411.           }
  412.           log_printf2("File: error creating \"%s\"",buf0);
  413.           mystrcpy(buf2,g_usrvars[0]); //save $0
  414.           mystrcpy(g_usrvars[0],buf0);
  415.  
  416.           GetNSISString(buf1,parm5);
  417.           mystrcpy(g_usrvars[0],buf2); // restore $0
  418.  
  419.           // Modified by ramon 23 May 2003
  420.           switch (my_MessageBox(buf1, parm0>>3))
  421.           {
  422.             case IDRETRY:
  423.               log_printf("File: error, user retry");
  424.               goto _tryagain;
  425.             case IDIGNORE:
  426.               log_printf("File: error, user cancel");
  427.               g_exec_flags.exec_error++;
  428.               return 0;
  429.             default:
  430.               log_printf("File: error, user abort");
  431.               update_status_text(LANG_CANTWRITE,buf0);
  432.             return EXEC_ERROR;
  433.           }
  434.         }
  435.  
  436.         update_status_text(LANG_EXTRACT,buf3);
  437.         {
  438.           ui_st_updateflag++;
  439.           ret=GetCompressedDataFromDataBlock(parm2,hOut);
  440.           ui_st_updateflag--;
  441.         }
  442.  
  443.         log_printf3("File: wrote %d to \"%s\"",ret,buf0);
  444.  
  445.         if (parm3 != 0xffffffff || parm4 != 0xffffffff)
  446.           SetFileTime(hOut,(FILETIME*)(lent.offsets+3),NULL,(FILETIME*)(lent.offsets+3));
  447.  
  448.         CloseHandle(hOut);
  449.  
  450.         if (ret < 0)
  451.         {
  452.           if (ret == -2)
  453.           {
  454.             GetNSISString(buf0,LANG_ERRORWRITING);
  455.             lstrcat(buf0,buf3);
  456.           }
  457.           else
  458.           {
  459.             GetNSISString(buf0,LANG_ERRORDECOMPRESSING);
  460.           }
  461.           log_printf2("%s",buf0);
  462.           my_MessageBox(buf0,MB_OK|MB_ICONSTOP|(IDOK<<20));
  463.           return EXEC_ERROR;
  464.         }
  465.       }
  466.     break;
  467. #endif//NSIS_SUPPORT_FILE
  468. #ifdef NSIS_SUPPORT_DELETE
  469.     case EW_DELETEFILE:
  470.       {
  471.         HANDLE h;
  472.         WIN32_FIND_DATA fd;
  473.         char *buf1=GetStringFromParm(0x10);
  474.         mystrcpy(buf0,buf1);
  475.         log_printf2("Delete: \"%s\"",buf0);
  476.         trimslashtoend(buf0);
  477.         h=FindFirstFile(buf1,&fd);
  478.         if (h != INVALID_HANDLE_VALUE)
  479.         {
  480.           do
  481.           {
  482.             if (!(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
  483.             {
  484.               wsprintf(buf1,"%s\\%s",buf0,fd.cFileName);
  485.               if (fd.dwFileAttributes & FILE_ATTRIBUTE_READONLY)
  486.                 SetFileAttributes(buf1,fd.dwFileAttributes^FILE_ATTRIBUTE_READONLY);
  487.               if (DeleteFile(buf1))
  488.               {
  489.                 log_printf2("Delete: DeleteFile(\"%s\")",buf1);
  490.                 update_status_text(LANG_DELETEFILE,buf1);
  491.               }
  492.               else
  493.               {
  494. #ifdef NSIS_SUPPORT_MOVEONREBOOT
  495.                 if (parm1)
  496.                 {
  497.                   log_printf2("Delete: DeleteFile on Reboot(\"%s\")",buf1);
  498.                   update_status_text(LANG_DELETEONREBOOT,buf1);
  499.                   MoveFileOnReboot(buf1,NULL);
  500.                 }
  501.                 else
  502. #endif
  503.                 {
  504.                   exec_error++;
  505.                 }
  506.               }
  507.             }
  508.           } while (FindNextFile(h,&fd));
  509.           FindClose(h);
  510.         }
  511.       }
  512.     break;
  513. #endif//NSIS_SUPPORT_DELETE
  514. #ifdef NSIS_SUPPORT_MESSAGEBOX
  515.     case EW_MESSAGEBOX: // MessageBox
  516.       {
  517.         int v;
  518.         char *buf3=GetStringFromParm(0x31);
  519.         log_printf3("MessageBox: %d,\"%s\"",parm0,buf3);
  520.         v=my_MessageBox(buf3,parm0);
  521.         if (v)
  522.         {
  523.           if (v==parm2)
  524.           {
  525.             return parm3;
  526.           }
  527.           if (v==parm4)
  528.           {
  529.             return parm5;
  530.           }
  531.         }
  532.         else exec_error++;
  533.       }
  534.     break;
  535. #endif//NSIS_SUPPORT_MESSAGEBOX
  536. #ifdef NSIS_SUPPORT_RMDIR
  537.     case EW_RMDIR:
  538.       {
  539.         char *buf1=GetStringFromParm(-0x10);
  540.         log_printf2("RMDir: \"%s\"",buf1);
  541.  
  542.         doRMDir(buf1,parm1);
  543.         if (file_exists(buf1) && parm1!=2) exec_error++;
  544.         else update_status_text(LANG_REMOVEDIR, buf1);
  545.       }
  546.     break;
  547. #endif//NSIS_SUPPORT_RMDIR
  548. #ifdef NSIS_SUPPORT_STROPTS
  549.     case EW_STRLEN:
  550.     {
  551.       char *buf0=GetStringFromParm(0x01);
  552.       myitoa(var0,mystrlen(buf0));
  553.     }
  554.     break;
  555.     case EW_ASSIGNVAR:
  556.       {
  557.         int newlen=GetIntFromParm(2);
  558.         int start=GetIntFromParm(3);
  559.         int l;
  560.         char *p=var0;
  561.         char *buf0=GetStringFromParm(0x01);
  562.         *p=0;
  563.         if (!parm2 || newlen)
  564.         {
  565.           l=mystrlen(buf0);
  566.  
  567.           if (start<0) start=l+start;
  568.           if (start>=0)
  569.           {
  570.             if (start>l) start=l;
  571.             mystrcpy(p,buf0+start);
  572.             if (newlen)
  573.             {
  574.               if (newlen<0) newlen=mystrlen(p)+newlen;
  575.               if (newlen<0) newlen=0;
  576.               if (newlen < NSIS_MAX_STRLEN) p[newlen]=0;
  577.             }
  578.           }
  579.         }
  580.       }
  581.     break;
  582.     case EW_STRCMP: {
  583.       char *buf2=GetStringFromParm(0x20);
  584.       char *buf3=GetStringFromParm(0x31);
  585.       if (!lstrcmpi(buf2,buf3)) return parm2;
  586.     }
  587.     return parm3;
  588. #endif//NSIS_SUPPORT_STROPTS
  589. #ifdef NSIS_SUPPORT_ENVIRONMENT
  590.     case EW_READENVSTR:
  591.       {
  592.         char *p=var0;
  593.         char *buf0=GetStringFromParm(0x01);
  594.         if (parm2)
  595.         {
  596.           if (!GetEnvironmentVariable(buf0,p,NSIS_MAX_STRLEN))
  597.           {
  598.             exec_error++;
  599.             *p=0;
  600.           }
  601.         }
  602.         else
  603.         {
  604.           ExpandEnvironmentStrings(buf0,p,NSIS_MAX_STRLEN);
  605.         }
  606.         p[NSIS_MAX_STRLEN-1]=0;
  607.       }
  608.     break;
  609. #endif//NSIS_SUPPORT_ENVIRONMENT
  610. #ifdef NSIS_SUPPORT_INTOPTS
  611.     case EW_INTCMP:
  612.       {
  613.         int v,v2;
  614.         v=GetIntFromParm(0);
  615.         v2=GetIntFromParm(1);
  616.         if (!parm5) {
  617.           // signed
  618.           if (v<v2) return parm3;
  619.           if (v>v2) return parm4;
  620.         }
  621.         else {
  622.           // unsigned
  623.           if ((unsigned int)v<(unsigned int)v2) return parm3;
  624.           if ((unsigned int)v>(unsigned int)v2) return parm4;
  625.         }
  626.       }
  627.     return parm2;
  628.     case EW_INTOP:
  629.       {
  630.         int v,v2;
  631.         char *p=var0;
  632.         v=GetIntFromParm(1);
  633.         v2=GetIntFromParm(2);
  634.         switch (parm3)
  635.         {
  636.           case 0: v+=v2; break;
  637.           case 1: v-=v2; break;
  638.           case 2: v*=v2; break;
  639.           case 3: if (v2) v/=v2; else { v=0; exec_error++; } break;
  640.           case 4: v|=v2; break;
  641.           case 5: v&=v2; break;
  642.           case 6: v^=v2; break;
  643.           case 7: v=!v; break;
  644.           case 8: v=v||v2; break;
  645.           case 9: v=v&&v2; break;
  646.           case 10: if (v2) v%=v2; else { v=0; exec_error++; } break;
  647.         }
  648.         myitoa(p,v);
  649.       }
  650.     break;
  651.     case EW_INTFMT: {
  652.       char *buf0=GetStringFromParm(0x01);
  653.       wsprintf(var0,
  654.                buf0,
  655.                GetIntFromParm(2));
  656.     }
  657.     break;
  658. #endif//NSIS_SUPPORT_INTOPTS
  659. #ifdef NSIS_SUPPORT_STACK
  660.     case EW_PUSHPOP:
  661.       {
  662.         stack_t *s=g_st;
  663.         int cnt=parm2;
  664.         if (cnt) //Exch contributed by Fritz Elfert
  665.         {
  666.           while (cnt--&&s) s=s->next;
  667.           if (!s)
  668.           {
  669.             log_printf2("Exch: stack < %d elements",parm2);
  670.             my_MessageBox(GetNSISStringTT(LANG_INSTCORRUPTED),MB_OK|MB_ICONSTOP|(IDOK<<20));
  671.             return EXEC_ERROR;
  672.           }
  673.           mystrcpy(buf0,s->text);
  674.           mystrcpy(s->text,g_st->text);
  675.           mystrcpy(g_st->text,buf0);
  676.         }
  677.         else if (parm1)
  678.         {
  679.           if (!s)
  680.           {
  681.             log_printf("Pop: stack empty");
  682.             exec_error++;
  683.             break;
  684.           }
  685.           mystrcpy(var0,s->text);
  686.           g_st=s->next;
  687.           GlobalFree((HGLOBAL)s);
  688.         }
  689.         else
  690.         {
  691.           s=(stack_t*)my_GlobalAlloc(sizeof(stack_t));
  692.           GetNSISString(s->text,parm0);
  693.           s->next=g_st;
  694.           g_st=s;
  695.         }
  696.       }
  697.     break;
  698. #endif//NSIS_SUPPORT_STACK
  699. #ifdef NSIS_SUPPORT_HWNDS
  700.     case EW_FINDWINDOW:
  701.     case EW_SENDMESSAGE:
  702.       {
  703.         int v;
  704.         int b3=(int)GetStringFromParm(0x33);
  705.         int b4=(int)GetStringFromParm(0x44);
  706.         if (!(parm5&1)) b3=myatoi((char*)b3);
  707.         if (!(parm5&2)) b4=myatoi((char*)b4);
  708.  
  709.         if (which == EW_SENDMESSAGE)
  710.         {
  711.           HWND hwnd=(HWND)GetIntFromParm(1);
  712.           int msg=GetIntFromParm(2);
  713.  
  714.           if (parm5>>2) exec_error += !SendMessageTimeout(hwnd,msg,b3,b4,SMTO_NORMAL,parm5>>2,(LPDWORD)&v);
  715.           else v=SendMessage(hwnd,msg,b3,b4);
  716.         }
  717.         else
  718.         {
  719.           char *buf0=GetStringFromParm(0x01);
  720.           char *buf1=GetStringFromParm(0x12);
  721.           v=(int)FindWindowEx((HWND)b3,(HWND)b4,buf0[0]?buf0:NULL,buf1[0]?buf1:NULL);
  722.         }
  723.  
  724.         if (parm0>=0)
  725.           myitoa(var0,v);
  726.       }
  727.     break;
  728.     case EW_ISWINDOW:
  729.         if (IsWindow((HWND)GetIntFromParm(0))) return parm1;
  730.     return parm2;
  731. #ifdef NSIS_CONFIG_ENHANCEDUI_SUPPORT
  732.     case EW_GETDLGITEM:
  733.       myitoa(
  734.         var0,
  735.         (int)GetDlgItem(
  736.           (HWND)GetIntFromParm(1),
  737.           GetIntFromParm(2)
  738.         )
  739.       );
  740.     break;
  741.     case EW_SETCTLCOLORS:
  742.     {
  743.       ctlcolors *c = (ctlcolors *)(g_blocks[NB_CTLCOLORS].offset + parm1);
  744.       SetWindowLong((HWND) GetIntFromParm(0), GWL_USERDATA, (long) c);
  745.     }
  746.     break;
  747.     case EW_SETBRANDINGIMAGE:
  748.     {
  749.       RECT r;
  750.       HANDLE hImage;
  751.       HWND hwImage=GetDlgItem(g_hwnd, parm1);
  752.       GetClientRect(hwImage, &r);
  753.       hImage=LoadImage(
  754.         0,
  755.         GetStringFromParm(0x00),
  756.         IMAGE_BITMAP,
  757.         parm2*r.right,
  758.         parm2*r.bottom,
  759.         LR_LOADFROMFILE
  760.       );
  761.       hImage = (HANDLE)SendMessage(
  762.         hwImage,
  763.         STM_SETIMAGE,
  764.         IMAGE_BITMAP,
  765.         (LPARAM)hImage
  766.       );
  767.       // delete old image
  768.       if (hImage) DeleteObject(hImage);
  769.     }
  770.     break;
  771.     case EW_CREATEFONT:
  772.     {
  773.       static LOGFONT f;
  774.       f.lfHeight=-MulDiv(GetIntFromParm(2),GetDeviceCaps(GetDC(g_hwnd),LOGPIXELSY),72);
  775.       f.lfWeight=GetIntFromParm(3);
  776.       f.lfItalic=parm4&1;
  777.       f.lfUnderline=parm4&2;
  778.       f.lfStrikeOut=parm4&4;
  779.       f.lfCharSet=DEFAULT_CHARSET;
  780.       GetNSISString(f.lfFaceName,parm1);
  781.       myitoa(var0,(int)CreateFontIndirect(&f));
  782.     }
  783.     break;
  784.     case EW_SHOWWINDOW:
  785.       if (parm2) log_printf("HideWindow");
  786.       if (!parm3)
  787.         ShowWindow((HWND)GetIntFromParm(0),GetIntFromParm(1));
  788.       else
  789.         EnableWindow((HWND)GetIntFromParm(0),GetIntFromParm(1));
  790.     break;
  791. #endif//NSIS_CONFIG_ENHANCEDUI_SUPPORT
  792. #endif//NSIS_SUPPORT_HWNDS
  793. #ifdef NSIS_SUPPORT_SHELLEXECUTE
  794.     case EW_SHELLEXEC: // this uses improvements of Andras Varga
  795.       {
  796.         int x;
  797.         char *buf0=GetStringFromParm(0x00);
  798.         char *buf1=GetStringFromParm(0x11);
  799.         char *buf2=GetStringFromParm(0x22);
  800.         wsprintf(buf3,"%s %s",buf0,buf1);
  801.         update_status_text(LANG_EXECSHELL, buf3);
  802.         x=(int)ShellExecute(g_hwnd,buf0[0]?buf0:NULL,buf1,buf2[0]?buf2:NULL,state_output_directory,parm3);
  803.         if (x < 33)
  804.         {
  805.           log_printf5("ExecShell: warning: error (\"%s\": file:\"%s\" params:\"%s\")=%d",buf0,buf1,buf2,x);
  806.           exec_error++;
  807.         }
  808.         else
  809.         {
  810.           log_printf4("ExecShell: success (\"%s\": file:\"%s\" params:\"%s\")",buf0,buf1,buf2);
  811.         }
  812.       }
  813.     break;
  814. #endif//NSIS_SUPPORT_SHELLEXECUTE
  815. #ifdef NSIS_SUPPORT_EXECUTE
  816.     case EW_EXECUTE:
  817.       {
  818.         HANDLE hProc;
  819.         char *buf0=GetStringFromParm(0x00);
  820.         log_printf2("Exec: command=\"%s\"",buf0);
  821.         update_status_text(LANG_EXECUTE,buf0);
  822.  
  823.         hProc=myCreateProcess(buf0,state_output_directory);
  824.  
  825.         if (hProc)
  826.         {
  827.           log_printf2("Exec: success (\"%s\")",buf0);
  828.           if (parm2)
  829.           {
  830.             DWORD lExitCode;
  831.             while (WaitForSingleObject(hProc,100) == WAIT_TIMEOUT)
  832.             {
  833.               MSG msg;
  834.               while (PeekMessage(&msg,NULL,WM_PAINT,WM_PAINT,PM_REMOVE))
  835.                 DispatchMessage(&msg);
  836.             }
  837.             GetExitCodeProcess(hProc, &lExitCode);
  838.  
  839.             if (parm1>=0) myitoa(var1,lExitCode);
  840.             else if (lExitCode) exec_error++;
  841.           }
  842.           CloseHandle( hProc );
  843.         }
  844.         else
  845.         {
  846.           exec_error++;
  847.           log_printf2("Exec: failed createprocess (\"%s\")",buf0);
  848.         }
  849.       }
  850.     break;
  851. #endif//NSIS_SUPPORT_EXECUTE
  852. #ifdef NSIS_SUPPORT_GETFILETIME
  853.     case EW_GETFILETIME:
  854.       // this new implementation based on one by Dave Bau
  855.       // used FindFirstFile instead of GetFileTime to better handle files that are locked.
  856.       // also allows GetFileTime to be passed a wildcard.
  857.       {
  858.         WIN32_FIND_DATA *ffd;
  859.         char *highout=var0;
  860.         char *lowout=var1;
  861.         char *buf0=GetStringFromParm(0x02);
  862.  
  863.         ffd=file_exists(buf0);
  864.         if (ffd)
  865.         {
  866.           myitoa(lowout,ffd->ftLastWriteTime.dwLowDateTime);
  867.           myitoa(highout,ffd->ftLastWriteTime.dwHighDateTime);
  868.         }
  869.         else
  870.         {
  871.           *lowout=*highout=0;
  872.           exec_error++;
  873.         }
  874.       }
  875.     break;
  876. #endif//NSIS_SUPPORT_GETFILETIME
  877. #ifdef NSIS_SUPPORT_GETDLLVERSION
  878.     case EW_GETDLLVERSION:
  879.       {
  880.         char *highout=var0;
  881.         char *lowout=var1;
  882.         DWORD s1;
  883.         DWORD t[4]; // our two members are the 3rd and 4th..
  884.         VS_FIXEDFILEINFO *pvsf1=(VS_FIXEDFILEINFO*)t;
  885.         DWORD d;
  886.         char *buf1=GetStringFromParm(-0x12);
  887.         s1=GetFileVersionInfoSize(buf1,&d);
  888.         *lowout=*highout=0;
  889.         exec_error++;
  890.         if (s1)
  891.         {
  892.           void *b1;
  893.           b1=my_GlobalAlloc(s1);
  894.           if (b1)
  895.           {
  896.             UINT uLen;
  897.             if (GetFileVersionInfo(buf1,0,s1,b1) && VerQueryValue(b1,"\\",(void*)&pvsf1,&uLen))
  898.             {
  899.               myitoa(highout,pvsf1->dwFileVersionMS);
  900.               myitoa(lowout,pvsf1->dwFileVersionLS);
  901.  
  902.               exec_error--;
  903.             }
  904.             GlobalFree(b1);
  905.           }
  906.         }
  907.       }
  908.       break;
  909. #endif//NSIS_SUPPORT_GETDLLVERSION
  910. #ifdef NSIS_SUPPORT_ACTIVEXREG
  911.     case EW_REGISTERDLL:
  912.       {
  913.         exec_error++;
  914.         SetErrorMode(SEM_NOOPENFILEERRORBOX | SEM_FAILCRITICALERRORS);
  915.         if (SUCCEEDED(g_hres))
  916.         {
  917.           HANDLE h;
  918.           char *buf1=GetStringFromParm(-0x10);
  919.           char *buf0=GetStringFromParm(0x01);
  920.  
  921.           h=GetModuleHandle(buf1);
  922.           if (!h)
  923.             h=LoadLibrary(buf1);
  924.           if (h)
  925.           {
  926.             FARPROC funke = GetProcAddress(h,buf0);
  927.             if (funke)
  928.             {
  929.               exec_error--;
  930.               if (parm2)
  931.               {
  932.                 update_status_text(parm2,buf1);
  933.                 if (funke()) exec_error++;
  934.               }
  935.               else
  936.               {
  937.                 void (*func)(HWND,int,char*,void*);
  938.                 func=(void*)funke;
  939.                 func(
  940.                   g_hwnd,
  941.                   NSIS_MAX_STRLEN,
  942.                   (char*)g_usrvars,
  943. #ifdef NSIS_SUPPORT_STACK
  944.                   (void*)&g_st
  945. #else
  946.                   NULL
  947. #endif//NSIS_SUPPORT_STACK
  948.                 );
  949.               }
  950.             }
  951.             else
  952.             {
  953.               update_status_text(LANG_CANNOTFINDSYMBOL,buf0);
  954.               log_printf3("Error registering DLL: %s not found in %s",buf0,buf1);
  955.             }
  956.             if (!parm3) FreeLibrary(h);
  957.           }
  958.           else
  959.           {
  960.             update_status_text(LANG_COULDNOTLOAD,buf1);
  961.             log_printf2("Error registering DLL: Could not load %s",buf1);
  962.           }
  963.         }
  964.         else
  965.         {
  966.           update_status_text(LANG_NOOLE,buf1);
  967.           log_printf("Error registering DLL: Could not initialize OLE");
  968.         }
  969.         SetErrorMode(0);
  970.       }
  971.     break;
  972. #endif
  973. #ifdef NSIS_SUPPORT_CREATESHORTCUT
  974.     case EW_CREATESHORTCUT:
  975.     {
  976.       char *buf2=GetStringFromParm(-0x20);
  977.       char *buf1=GetStringFromParm(-0x11);
  978.       char *buf0=GetStringFromParm(0x02);
  979.       char *buf3=GetStringFromParm(-0x33);
  980.       char *buf4=GetStringFromParm(0x45);
  981.  
  982.       HRESULT hres;
  983.       IShellLink* psl;
  984.  
  985.       if (!validpathspec(buf1))
  986.         GetStringFromParm(0x11);
  987.  
  988.       log_printf8("CreateShortCut: out: \"%s\", in: \"%s %s\", icon: %s,%d, sw=%d, hk=%d",
  989.         buf2,buf1,buf0,buf3,parm4&0xff,(parm4&0xff00)>>8,parm4>>16);
  990.  
  991.       hres = CoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
  992.                                 &IID_IShellLink, (void **) &psl);
  993.       if (SUCCEEDED(hres))
  994.       {
  995.         IPersistFile* ppf;
  996.  
  997.         hres = psl->lpVtbl->QueryInterface(psl,&IID_IPersistFile, (void **) &ppf);
  998.         if (SUCCEEDED(hres))
  999.         {
  1000.           hres = psl->lpVtbl->SetPath(psl,buf1);
  1001.           psl->lpVtbl->SetWorkingDirectory(psl,state_output_directory);
  1002.           if ((parm4&0xff00)>>8) psl->lpVtbl->SetShowCmd(psl,(parm4&0xff00)>>8);
  1003.           psl->lpVtbl->SetHotkey(psl,(unsigned short)(parm4>>16));
  1004.           if (buf3[0]) psl->lpVtbl->SetIconLocation(psl,buf3,parm4&0xff);
  1005.           psl->lpVtbl->SetArguments(psl,buf0);
  1006.           psl->lpVtbl->SetDescription(psl,buf4);
  1007.  
  1008.           if (SUCCEEDED(hres))
  1009.           {
  1010.              static WCHAR wsz[1024];
  1011.              wsz[0]=0;
  1012.              MultiByteToWideChar(CP_ACP, 0, buf2, -1, wsz, 1024);
  1013.              hres=ppf->lpVtbl->Save(ppf,(const WCHAR*)wsz,TRUE);
  1014.           }
  1015.           ppf->lpVtbl->Release(ppf);
  1016.         }
  1017.         psl->lpVtbl->Release(psl);
  1018.       }
  1019.  
  1020.       if (FAILED(hres))
  1021.       {
  1022.         exec_error++;
  1023.         update_status_text(LANG_ERRORCREATINGSHORTCUT,buf2);
  1024.       }
  1025.       else
  1026.       {
  1027.         update_status_text(LANG_CREATESHORTCUT,buf2);
  1028.       }
  1029.     }
  1030.     break;
  1031. #endif//NSIS_SUPPORT_CREATESHORTCUT
  1032. #ifdef NSIS_SUPPORT_COPYFILES
  1033.     case EW_COPYFILES: // CopyFile (added by NOP)
  1034.       {
  1035.         int res;
  1036.         SHFILEOPSTRUCT op;
  1037.         char *buf0=GetStringFromParm(0x00);
  1038.         char *buf1=GetStringFromParm(0x11);
  1039.         log_printf3("CopyFiles \"%s\"->\"%s\"",buf0,buf1);
  1040.         op.hwnd=g_hwnd;
  1041.         op.wFunc=FO_COPY;
  1042.         buf0[mystrlen(buf0)+1]=0;
  1043.         buf1[mystrlen(buf1)+1]=0;
  1044.  
  1045.         GetNSISString(buf2,LANG_COPYTO);
  1046.         lstrcat(buf2,buf1);
  1047.  
  1048.         op.pFrom=buf0;
  1049.         op.pTo=buf1;
  1050.         op.lpszProgressTitle=buf2;
  1051.         op.fFlags=parm2;
  1052.         update_status_text(0,buf2);
  1053.         res=SHFileOperation(&op);
  1054.         if (res)
  1055.         { // some of these changes were from Edgewise (wiked_edge@yahoo.com)
  1056.           update_status_text(LANG_COPYFAILED,0);
  1057.           exec_error++;
  1058.         }
  1059.       }
  1060.     break;
  1061. #endif//NSIS_SUPPORT_COPYFILES
  1062. #ifdef NSIS_SUPPORT_REBOOT
  1063.     case EW_REBOOT:
  1064.       if (parm0!=0xbadf00d)
  1065.       {
  1066.         my_MessageBox(GetNSISStringTT(LANG_INSTCORRUPTED),MB_OK|MB_ICONSTOP|(IDOK<<20));
  1067.         return EXEC_ERROR;
  1068.       }
  1069.       g_exec_flags.exec_error++;
  1070.       {
  1071.         HANDLE h=LoadLibrary("advapi32.dll");
  1072.         if (h)
  1073.         {
  1074.           BOOL (WINAPI *OPT)(HANDLE, DWORD,PHANDLE);
  1075.           BOOL (WINAPI *LPV)(LPCTSTR,LPCTSTR,PLUID);
  1076.           BOOL (WINAPI *ATP)(HANDLE,BOOL,PTOKEN_PRIVILEGES,DWORD,PTOKEN_PRIVILEGES,PDWORD);
  1077.           OPT=(void*)GetProcAddress(h,"OpenProcessToken");
  1078.           LPV=(void*)GetProcAddress(h,"LookupPrivilegeValueA");
  1079.           ATP=(void*)GetProcAddress(h,"AdjustTokenPrivileges");
  1080.           if (OPT && LPV && ATP)
  1081.           {
  1082.             HANDLE hToken;
  1083.             TOKEN_PRIVILEGES tkp;
  1084.             if (OPT(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
  1085.             {
  1086.               LPV(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid);
  1087.               tkp.PrivilegeCount = 1;
  1088.               tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
  1089.               ATP(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0);
  1090.             }
  1091.           }
  1092.         }
  1093.  
  1094.         if (ExitWindowsEx(EWX_REBOOT,0))
  1095.         {
  1096.           g_quit_flag++;
  1097.           PostQuitMessage(0);
  1098.           return EXEC_ERROR;
  1099.         }
  1100.  
  1101.         FreeLibrary(h);
  1102.       }
  1103.     break;
  1104. #endif//NSIS_SUPPORT_REBOOT
  1105. #ifdef NSIS_SUPPORT_INIFILES
  1106.     case EW_WRITEINI:
  1107.       {
  1108.         char *sec=0, *key=0, *str=0;
  1109. #ifdef NSIS_CONFIG_LOG
  1110.         mystrcpy(buf1,"<RM>");
  1111.         mystrcpy(buf2,buf1);
  1112. #endif
  1113.         if (parm0)
  1114.         {
  1115.           sec=GetStringFromParm(0x00);
  1116.         }
  1117.         if (parm1)
  1118.         {
  1119.           key=GetStringFromParm(0x11);
  1120.         }
  1121.         if (parm4)
  1122.         {
  1123.           str=GetStringFromParm(0x22);
  1124.         }
  1125.         buf3=GetStringFromParm(-0x33);
  1126.         log_printf5("WriteINIStr: wrote [%s] %s=%s in %s",buf0,buf1,buf2,buf3);
  1127.         if (!WritePrivateProfileString(sec,key,str,buf3)) exec_error++;
  1128.       }
  1129.     break;
  1130.     case EW_READINISTR:
  1131.       {
  1132.         const char *errstr="!N~";
  1133.         char *p=var0;
  1134.         char *buf0=GetStringFromParm(0x01);
  1135.         char *buf1=GetStringFromParm(0x12);
  1136.         char *buf2=GetStringFromParm(-0x23);
  1137.         GetPrivateProfileString(buf0,buf1,errstr,p,NSIS_MAX_STRLEN-1,buf2);
  1138.         if (*((int*)errstr) == *((int*)p))
  1139.         {
  1140.           exec_error++;
  1141.           p[0]=0;
  1142.         }
  1143.       }
  1144.     break;
  1145. #endif//NSIS_SUPPORT_INIFILES
  1146. #ifdef NSIS_SUPPORT_REGISTRYFUNCTIONS
  1147.     case EW_DELREG:
  1148.       {
  1149.         int rootkey=parm0;
  1150.         char *buf3=GetStringFromParm(0x31);
  1151.         exec_error++;
  1152.         if (!parm3)
  1153.         {
  1154.           HKEY hKey;
  1155.           if (RegOpenKeyEx((HKEY)rootkey,buf3,0,KEY_SET_VALUE,&hKey) == ERROR_SUCCESS)
  1156.           {
  1157.             char *buf0=GetStringFromParm(0x02);
  1158.             log_printf4("DeleteRegValue: %d\\%s\\%s",rootkey,buf3,buf0);
  1159.             if (RegDeleteValue(hKey,buf0) == ERROR_SUCCESS) exec_error--;
  1160.             RegCloseKey(hKey);
  1161.           }
  1162.         }
  1163.         else
  1164.         {
  1165.           log_printf3("DeleteRegKey: %d\\%s",rootkey,buf3);
  1166.           if (myRegDeleteKeyEx((HKEY)rootkey,buf3,parm3&2) == ERROR_SUCCESS) exec_error--;
  1167.         }
  1168.       }
  1169.     break;
  1170.     case EW_WRITEREG: // write registry value
  1171.       {
  1172.         HKEY hKey;
  1173.         int rootkey=parm0;
  1174.         int type=parm4;
  1175.         int rtype=parm5;
  1176.         char *buf1=GetStringFromParm(0x12);
  1177.         char *buf3=GetStringFromParm(0x31);
  1178.         exec_error++;
  1179.         if (RegCreateKey((HKEY)rootkey,buf3,&hKey) == ERROR_SUCCESS)
  1180.         {
  1181.           LPBYTE data = (LPBYTE) buf2;
  1182.           DWORD size = 0;
  1183.           if (type == REG_SZ)
  1184.           {
  1185.             GetStringFromParm(0x23);
  1186.             size = mystrlen((char *) data) + 1;
  1187.             log_printf5("WriteRegStr: set %d\\%s\\%s to %s",rootkey,buf3,buf1,buf2);
  1188.           }
  1189.           if (type == REG_DWORD)
  1190.           {
  1191.             *(LPDWORD) data = GetIntFromParm(3);
  1192.             size = sizeof(DWORD);
  1193.             log_printf5("WriteRegDWORD: set %d\\%s\\%s to %d",rootkey,buf3,buf1,*(LPDWORD)data);
  1194.           }
  1195.           if (type == REG_BINARY)
  1196.           {
  1197.             size = GetCompressedDataFromDataBlockToMemory(parm3, data, NSIS_MAX_STRLEN);
  1198.             log_printf5("WriteRegBin: set %d\\%s\\%s with %d bytes",rootkey,buf3,buf1,size);
  1199.           }
  1200.           if (size >= 0 && RegSetValueEx(hKey,buf1,0,rtype,data,size) == ERROR_SUCCESS)
  1201.             exec_error--;
  1202.           RegCloseKey(hKey);
  1203.         }
  1204.         else { log_printf3("WriteReg: error creating key %d\\%s",rootkey,buf3); }
  1205.       }
  1206.     break;
  1207.     case EW_READREGSTR: // read registry string
  1208.       {
  1209.         HKEY hKey;
  1210.         char *p=var0;
  1211.         int rootkey=parm1;
  1212.         char *buf0=GetStringFromParm(0x02); // buf0 == subkey
  1213.         char *buf1=GetStringFromParm(0x13); // buf1 == key name
  1214.         p[0]=0;
  1215.         if (RegOpenKeyEx((HKEY)rootkey,buf0,0,KEY_READ,&hKey) == ERROR_SUCCESS)
  1216.         {
  1217.           DWORD l = NSIS_MAX_STRLEN;
  1218.           DWORD t;
  1219.  
  1220.           if (RegQueryValueEx(hKey,buf1,NULL,&t,p,&l ) != ERROR_SUCCESS ||
  1221.               (t != REG_DWORD && t != REG_SZ && t != REG_EXPAND_SZ))
  1222.           {
  1223.             p[0]=0;
  1224.             exec_error++;
  1225.           }
  1226.           else
  1227.           {
  1228.             if (t==REG_DWORD)
  1229.             {
  1230.               if (!parm4) exec_error++;
  1231.               myitoa(p,*((DWORD*)p));
  1232.             }
  1233.             else if (parm4) exec_error++;
  1234.           }
  1235.           RegCloseKey(hKey);
  1236.         }
  1237.         else exec_error++;
  1238.      }
  1239.     break;
  1240.     case EW_REGENUM:
  1241.       {
  1242.         HKEY key;
  1243.         char *p=var0;
  1244.         int b=GetIntFromParm(3);
  1245.         char *buf1=GetStringFromParm(0x12);
  1246.         p[0]=0;
  1247.         if (RegOpenKeyEx((HKEY)parm1,buf1,0,KEY_READ,&key) == ERROR_SUCCESS)
  1248.         {
  1249.           DWORD d=NSIS_MAX_STRLEN-1;
  1250.           if (parm4) RegEnumKey(key,b,p,d);
  1251.           else RegEnumValue(key,b,p,&d,NULL,NULL,NULL,NULL);
  1252.           p[NSIS_MAX_STRLEN-1]=0;
  1253.           RegCloseKey(key);
  1254.         }
  1255.         else exec_error++;
  1256.       }
  1257.  
  1258.     break;
  1259. #endif//NSIS_SUPPORT_REGISTRYFUNCTIONS
  1260. #ifdef NSIS_SUPPORT_FILEFUNCTIONS
  1261.     case EW_FCLOSE:
  1262.       {
  1263.         char *t=var0;
  1264.         if (*t) CloseHandle((HANDLE)myatoi(t));
  1265.       }
  1266.     break;
  1267.     case EW_FOPEN:
  1268.       {
  1269.         HANDLE h;
  1270.         char *handleout=var0;
  1271.         char *buf1=GetStringFromParm(-0x13);
  1272.         h=myOpenFile(buf1,parm1,parm2);
  1273.         if (h == INVALID_HANDLE_VALUE)
  1274.         {
  1275.           *handleout=0;
  1276.           exec_error++;
  1277.         }
  1278.         else
  1279.         {
  1280.           myitoa(handleout,(int)h);
  1281.         }
  1282.       }
  1283.     break;
  1284.     case EW_FPUTS:
  1285.       {
  1286.         DWORD dw;
  1287.         int l;
  1288.         char *t=var0;
  1289.         if (parm2)
  1290.         {
  1291.           ((unsigned char *)buf1)[0]=GetIntFromParm(1)&0xff;
  1292.           l=1;
  1293.         }
  1294.         else
  1295.         {
  1296.           l=mystrlen(GetStringFromParm(0x11));
  1297.         }
  1298.         if (!*t || !WriteFile((HANDLE)myatoi(t),buf1,l,&dw,NULL))
  1299.         {
  1300.           exec_error++;
  1301.         }
  1302.       }
  1303.     break;
  1304.     case EW_FGETS:
  1305.       {
  1306.         char *textout=var1;
  1307.         DWORD dw;
  1308.         int rpos=0;
  1309.         char *hptr=var0;
  1310.         int maxlen=GetIntFromParm(2);
  1311.         if (maxlen<1) break;
  1312.         if (maxlen > NSIS_MAX_STRLEN-1) maxlen=NSIS_MAX_STRLEN-1;
  1313.         if (*hptr)
  1314.         {
  1315.           char lc=0;
  1316.           int rcnt=0;
  1317.           HANDLE h=(HANDLE)myatoi(hptr);
  1318.           while (rpos<maxlen)
  1319.           {
  1320.             char c;
  1321.             if (!ReadFile(h,&c,1,&dw,NULL) || dw != 1) break;
  1322.             if (parm3)
  1323.             {
  1324.               myitoa(textout,(unsigned int)(unsigned char)c);
  1325.               return 0;
  1326.             }
  1327.             if (!c) break;
  1328.             if (lc == '\r' || lc == '\n')
  1329.             {
  1330.               if (lc == c || (c != '\r' && c != '\n')) SetFilePointer(h,-1,NULL,FILE_CURRENT);
  1331.               else textout[rpos++]=c;
  1332.               break;
  1333.             }
  1334.             textout[rpos++]=c;
  1335.             lc=c;
  1336.           }
  1337.         }
  1338.         textout[rpos]=0;
  1339.         if (!rpos) exec_error++;
  1340.       }
  1341.     break;
  1342.     case EW_FSEEK:
  1343.       {
  1344.         char *t=var0;
  1345.         if (*t)
  1346.         {
  1347.           DWORD v=SetFilePointer((HANDLE)myatoi(t),GetIntFromParm(2),NULL,parm3);
  1348.  
  1349.           if (parm1>=0)
  1350.           {
  1351.             myitoa(var1,v);
  1352.           }
  1353.         }
  1354.       }
  1355.     break;
  1356. #endif//NSIS_SUPPORT_FILEFUNCTIONS
  1357. #ifdef NSIS_SUPPORT_FINDFIRST
  1358.     case EW_FINDCLOSE:
  1359.       {
  1360.         char *t=var0;
  1361.         if (*t) FindClose((HANDLE)myatoi(t));
  1362.       }
  1363.     break;
  1364.     case EW_FINDNEXT:
  1365.       {
  1366.         char *textout=var0;
  1367.         char *t=var1;
  1368.         WIN32_FIND_DATA fd;
  1369.         if (*t && FindNextFile((HANDLE)myatoi(t),&fd))
  1370.         {
  1371.           mystrcpy(textout,fd.cFileName);
  1372.         }
  1373.         else
  1374.         {
  1375.           exec_error++;
  1376.           *textout=0;
  1377.         }
  1378.  
  1379.       }
  1380.     break;
  1381.     case EW_FINDFIRST:
  1382.       {
  1383.         char *textout=var0;
  1384.         char *handleout=var1;
  1385.         HANDLE h;
  1386.         WIN32_FIND_DATA fd;
  1387.         char *buf0=GetStringFromParm(0x02);
  1388.         h=FindFirstFile(buf0,&fd);
  1389.         if (h == INVALID_HANDLE_VALUE)
  1390.         {
  1391.           *handleout=0;
  1392.           *textout=0;
  1393.           exec_error++;
  1394.         }
  1395.         else
  1396.         {
  1397.           myitoa(handleout,(int)h);
  1398.           mystrcpy(textout,fd.cFileName);
  1399.         }
  1400.       }
  1401.     break;
  1402. #endif//NSIS_SUPPORT_FINDFIRST
  1403. #ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
  1404.     case EW_WRITEUNINSTALLER:
  1405.       {
  1406.         int ret=-666;
  1407.         HANDLE hFile;
  1408.         char *buf0=GetStringFromParm(0x00);
  1409.  
  1410.         if (validpathspec(buf0))
  1411.         {
  1412.           mystrcpy(buf1,buf0);
  1413.         }
  1414.         else
  1415.         {
  1416.           lstrcat(addtrailingslash(mystrcpy(buf1,state_install_directory)),buf0);
  1417.         }
  1418.         validate_filename(buf1);
  1419.  
  1420.         hFile=myOpenFile(buf1,GENERIC_WRITE,CREATE_ALWAYS);
  1421.         if (hFile != INVALID_HANDLE_VALUE)
  1422.         {
  1423.           unsigned char *filebuf;
  1424.           int filehdrsize = g_filehdrsize;
  1425.           filebuf=(unsigned char *)my_GlobalAlloc(filehdrsize);
  1426.           if (filebuf)
  1427.           {
  1428.             DWORD lout;
  1429.             SetSelfFilePointer(0);
  1430.             ReadSelfFile((char*)filebuf,filehdrsize);
  1431.             {
  1432.               unsigned char* seeker;
  1433.               unsigned char* unicon_data = seeker = (unsigned char*)my_GlobalAlloc(parm2);
  1434.               if (unicon_data) {
  1435.                 GetCompressedDataFromDataBlockToMemory(parm1,unicon_data,parm2);
  1436.                 while (*seeker) {
  1437.                   struct icondata {
  1438.                     DWORD dwSize;
  1439.                     DWORD dwOffset;
  1440.                   } id = *(struct icondata *) seeker;
  1441.                   seeker += sizeof(struct icondata);
  1442.                   mini_memcpy(filebuf+id.dwOffset, seeker, id.dwSize);
  1443.                   seeker += id.dwSize;
  1444.                 }
  1445.                 GlobalFree(unicon_data);
  1446.               }
  1447.             }
  1448.             WriteFile(hFile,(char*)filebuf,filehdrsize,&lout,NULL);
  1449.             GlobalFree(filebuf);
  1450.             ret=GetCompressedDataFromDataBlock(-1,hFile);
  1451.           }
  1452.           CloseHandle(hFile);
  1453.         }
  1454.         log_printf3("created uninstaller: %d, \"%s\"",ret,buf1);
  1455.         {
  1456.           int str = LANG_CREATEDUNINST;
  1457.           if (ret < 0)
  1458.           {
  1459.             str = LANG_ERRORCREATING;
  1460.             DeleteFile(buf1);
  1461.             exec_error++;
  1462.           }
  1463.           update_status_text(str,buf1);
  1464.         }
  1465.       }
  1466.     break;
  1467. #endif//NSIS_CONFIG_UNINSTALL_SUPPORT
  1468. #ifdef NSIS_CONFIG_LOG
  1469.     case EW_LOG:
  1470.       if (parm0)
  1471.       {
  1472.         log_printf2("settings logging to %d",parm1);
  1473.         log_dolog=parm1;
  1474.         log_printf2("logging set to %d",parm1);
  1475. #ifndef NSIS_CONFIG_LOG_ODS
  1476.         if (parm1) build_g_logfile();
  1477. #endif
  1478.       }
  1479.       else
  1480.       {
  1481.         char *buf0=GetStringFromParm(0x01);
  1482.         log_printf2("%s",buf0);
  1483.       }
  1484.     break;
  1485. #endif//NSIS_CONFIG_LOG
  1486. #ifdef NSIS_CONFIG_COMPONENTPAGE
  1487.     case EW_SECTIONSET:
  1488.     {
  1489.       int x=GetIntFromParm(0);
  1490.       if ((unsigned int)x < (unsigned int)num_sections)
  1491.       {
  1492.         section *sec=g_sections+x;
  1493.         if (parm2>=0) // get something
  1494.         {
  1495.           int res=((int*)sec)[parm2];
  1496.           if (!parm2)
  1497.           {
  1498.             // getting text
  1499.             GetNSISString(var1,res);
  1500.           }
  1501.           else
  1502.           {
  1503.             // getting number
  1504.             myitoa(var1,res);
  1505.           }
  1506.         }
  1507.         else // set something
  1508.         {
  1509.           parm2=-parm2-1;
  1510.           if (parm2)
  1511.           {
  1512.             // not setting text, get int
  1513.             parm1=GetIntFromParm(1);
  1514.           }
  1515.           else
  1516.           {
  1517.             // setting text, send the message to do it
  1518.             SendMessage(hwSectionHack,WM_NOTIFY_SECTEXT,x,parm1);
  1519.           }
  1520.           ((int*)sec)[parm2]=parm1;
  1521.           if (parm2)
  1522.           {
  1523.             // update tree view
  1524.             SendMessage(hwSectionHack,WM_NOTIFY_SECFLAGS,x,0);
  1525.           }
  1526.         }
  1527.       }
  1528.       else exec_error++;
  1529.     }
  1530.     break;
  1531.     case EW_INSTTYPESET:
  1532.     {
  1533.       int x=GetIntFromParm(0);
  1534.  
  1535.       if (parm3)
  1536.       {
  1537.         g_exec_flags.insttype_changed++;
  1538.         SendMessage(hwSectionHack,WM_NOTIFY_INSTTYPE_CHANGE,0,0);
  1539.       }
  1540.       else if ((unsigned int)x < (unsigned int)NSIS_MAX_INST_TYPES)
  1541.       {
  1542.         if (parm2) // set text
  1543.         {
  1544.           g_header->install_types[x] = parm1;
  1545.         }
  1546.         else // get text
  1547.         {
  1548.           GetNSISString(var1,g_header->install_types[x]);
  1549.         }
  1550.       }
  1551.       else exec_error++;
  1552.     }
  1553.     break;
  1554. #endif//NSIS_CONFIG_COMPONENTPAGE
  1555.  
  1556. #ifdef NSIS_LOCKWINDOW_SUPPORT
  1557.     case EW_LOCKWINDOW:
  1558.     {
  1559.       // ui_dlg_visible is 1 or 0, so is parm0
  1560.       SendMessage(g_hwnd, WM_SETREDRAW, parm0 & ui_dlg_visible, 0);
  1561.       if ( parm0 )
  1562.         InvalidateRect(g_hwnd, NULL, FALSE);
  1563.     }
  1564. #endif //NSIS_LOCKWINDOW_SUPPORT
  1565.   }
  1566.  
  1567.   g_exec_flags.exec_error += exec_error;
  1568.  
  1569.   return 0;
  1570. }
  1571.