home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 October / Chip_2001-10_cd1.bin / zkuste / delphi / nastroje / d23456 / NSIS.EXE / Source / exehead / exec.c < prev    next >
C/C++ Source or Header  |  2001-06-03  |  34KB  |  981 lines

  1. #include <windows.h>
  2. #include <shlobj.h>
  3. #include "fileform.h"
  4. #include "util.h"
  5. #include "state.h"
  6. #include "ui.h"
  7. #include "libc.h"
  8. #include "exec.h"
  9.  
  10. char *g_deletefilecolon="Delete file: ";
  11. char *g_errdll="Error registering DLL";
  12. char *g_errdecomp="Error decompressing data! Installer corrupted.";
  13.  
  14. // return EXEC_ERROR (0x10000000) on error, otherwise, if return is >0,
  15. // advance by 1+return, or if return < 0, move back by return
  16. // or 0 is advance by 1.
  17.  
  18. static int file_exists(char *buf)
  19. {
  20.   int a=0;
  21.   HANDLE h;
  22.   WIN32_FIND_DATA fd;
  23.   h = FindFirstFile(buf,&fd);
  24.   if (h != INVALID_HANDLE_VALUE) 
  25.   {
  26.     FindClose(h);
  27.     a++;
  28.   }
  29.   return a;
  30. }
  31.  
  32. static void doRMDir(char *buf, int recurse)
  33. {
  34.   if (recurse)
  35.   {
  36.     HANDLE h;
  37.     WIN32_FIND_DATA fd;
  38.     char *p=buf;
  39.     while (*p) p++;
  40.     lstrcpy(p,"\\*.*");
  41.     h = FindFirstFile(buf,&fd);
  42.     if (h != INVALID_HANDLE_VALUE) 
  43.     {
  44.       do
  45.       {
  46.         if (fd.cFileName[0] != '.' ||
  47.             (fd.cFileName[1] != '.' && fd.cFileName[1]))
  48.         {
  49.           lstrcpy(p+1,fd.cFileName);
  50.           if (fd.dwFileAttributes & FILE_ATTRIBUTE_READONLY) 
  51.             SetFileAttributes(buf,fd.dwFileAttributes^FILE_ATTRIBUTE_READONLY);
  52.           if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) doRMDir(buf,recurse);
  53.           else 
  54.           {
  55.             update_status_text(g_deletefilecolon,buf);
  56.             DeleteFile(buf);
  57.           }
  58.         }
  59.       } while (FindNextFile(h,&fd));
  60.       FindClose(h);
  61.     }
  62.     p[0]=0; // fix buffer
  63.   }
  64.   log_printf2("RMDir: RemoveDirectory(\"%s\")",buf);
  65.   update_status_text("Removing directory: ",buf);
  66.   RemoveDirectory(buf);
  67. }
  68.  
  69.  
  70.  
  71. // based loosely on code from Tim Kosse
  72. // in win9x this isn't necessary (RegDeleteKey() can delete a tree of keys),
  73. // but in win2k you need to do this manually.
  74. static LONG myRegDeleteKeyEx(HKEY thiskey, LPCTSTR lpSubKey, int onlyifempty)
  75. {
  76.     HKEY key;
  77.     int retval=RegOpenKey(thiskey,lpSubKey,&key);
  78.     if (retval==ERROR_SUCCESS)
  79.     {
  80.         char buffer[1024];
  81.         while (RegEnumKey(key,0,buffer,1024)==ERROR_SUCCESS)
  82.     {
  83.       if (onlyifempty) 
  84.       {
  85.             RegCloseKey(key);
  86.         return !ERROR_SUCCESS;
  87.       }
  88.       if ((retval=myRegDeleteKeyEx(key,buffer,0)) != ERROR_SUCCESS) break;
  89.     }
  90.         RegCloseKey(key);
  91.         retval=RegDeleteKey(thiskey,lpSubKey);
  92.     }
  93.     return retval;
  94. }
  95.  
  96.  
  97.  
  98. extern HWND insthwnd,insthwndbutton;
  99.  
  100. extern int g_show_details;
  101.  
  102. int exec_errorflag;
  103.  
  104.  
  105. int ExecuteCodeSegment(entry *entries, int range[2], HWND hwndProgress) 
  106. {
  107.   int pos=range[0];
  108.   while (pos < range[1])
  109.   {
  110.     int rv=ExecuteEntry(entries,pos);
  111.     if (rv == EXEC_ERROR) return rv;
  112.     pos+=++rv;
  113.     if (pos<range[0]) pos=range[0];
  114.     if (hwndProgress) SendMessage(hwndProgress,PBM_DELTAPOS,rv,0);
  115.     Sleep(1);
  116.   }
  117.   return 0;
  118. }
  119.  
  120.  
  121. int ExecuteEntry(entry *entries, int pos)
  122. {
  123.   int x;
  124.   entry *thisentry=entries+pos;
  125.   static char buf[1024],buf2[1024],buf3[1024],buf4[1024];
  126.   switch (thisentry->which)
  127.   {
  128.     case EW_CALL:
  129.       log_printf3("Call: %d->%d",thisentry->offsets[0],thisentry->offsets[1]); 
  130.     return ExecuteCodeSegment(entries,thisentry->offsets,NULL);
  131.     case EW_NOP: 
  132.       log_printf2("Jump: %d",thisentry->offsets[0]); 
  133.     return thisentry->offsets[0];
  134.     case EW_RENAME:
  135.       {
  136.         process_string_fromtab(buf,thisentry->offsets[0]);
  137.         process_string_fromtab(buf2,thisentry->offsets[1]);
  138.         lstrcpy(buf4,buf);
  139.         lstrcat(buf4,"->");
  140.         lstrcat(buf4,buf2);
  141.         log_printf2("Rename: %s",buf4);
  142.         if (MoveFile(buf,buf2))
  143.         {
  144.           update_status_text("Rename: ",buf4);
  145.         }
  146.         else
  147.         {
  148.           if (thisentry->offsets[2] && file_exists(buf))
  149.           {
  150.             MoveFileOnReboot(buf,buf2);
  151.             update_status_text("Rename on reboot: ",buf4);
  152.             log_printf2("Rename on reboot: %s",buf4);
  153.           }
  154.           else
  155.           {
  156.             exec_errorflag++;
  157.             log_printf2("Rename failed: %s",buf4);
  158.           }
  159.         }
  160.       }
  161.     return 0;
  162.     case EW_UPDATETEXT:
  163.       process_string_fromtab(buf4,thisentry->offsets[0]);
  164.       log_printf2("detailprint: %s",buf4);
  165.       update_status_text(buf4,"");
  166.     return 0;
  167.     case EW_SLEEP:
  168.       x=thisentry->offsets[0];
  169.       if (x < 1) x=1;
  170.       update_status_text("Wait...","");
  171.       log_printf2("Sleep(%d)",x);
  172.       Sleep(x);
  173.     return 0;
  174.     case EW_HIDEWINDOW:
  175.       log_printf("HideWindow");
  176.       ShowWindow(g_hwnd,SW_HIDE);
  177.     return 0;
  178.     case EW_BRINGTOFRONT:
  179.       log_printf("BringToFront");
  180.       ShowWindow(g_hwnd,SW_SHOW);
  181.       SetForegroundWindow(g_hwnd);
  182.     return 0;
  183.     case EW_ABORT:
  184.       {
  185.         char *p=GetStringFromStringTab(thisentry->offsets[0]);
  186.         log_printf2("Aborting: \"%s\"",p);
  187.         update_status_text("",p);
  188.       }
  189.     return EXEC_ERROR;
  190.     case EW_SETWINDOWCLOSE:
  191.       g_autoclose=thisentry->offsets[0];
  192.     return 0;
  193.     case EW_CHDETAILSVIEW:
  194.       if (thisentry->offsets[0])
  195.       {
  196.         if (insthwndbutton) ShowWindow(insthwndbutton,SW_HIDE);
  197.         if (insthwnd) ShowWindow(insthwnd,SW_SHOWNA);
  198.       }
  199.       else
  200.       {
  201.         if (insthwndbutton && g_show_details!=2) ShowWindow(insthwndbutton,SW_SHOWNA);
  202.         if (insthwnd) ShowWindow(insthwnd,SW_HIDE);
  203.       }
  204.     return 0;
  205.     case EW_SETFILEATTRIBUTES:
  206.       process_string_fromtab(buf,thisentry->offsets[0]);
  207.       log_printf3("SetFileAttributes: \"%s\":%08X",buf,thisentry->offsets[1]);
  208.       if (!SetFileAttributes(buf,thisentry->offsets[1]))
  209.       {
  210.         exec_errorflag++;
  211.         log_printf("SetFileAttributes failed.");
  212.       }
  213.     return 0;
  214.     case EW_CREATEDIR:
  215.       process_string_fromtab(buf2,thisentry->offsets[0]);
  216.       log_printf3("CreateDirectory: \"%s\"->\"%s\"",GetStringFromStringTab(thisentry->offsets[0]),buf2);
  217.       update_status_text("Creating directory: ",buf2);
  218.       recursive_create_directory(buf2);
  219.     return 0;
  220.     case EW_SETOUTPUTDIR:
  221.       process_string_fromtab(buf4,thisentry->offsets[0]);
  222.       log_printf3("SetOutPath: \"%s\"->\"%s\"",GetStringFromStringTab(thisentry->offsets[0]),state_output_directory);
  223.       update_status_text("Output directory: ",buf4);
  224.       lstrcpy(state_output_directory,buf4);
  225.       recursive_create_directory(buf4);
  226.     return 0;
  227.     case EW_IFFILEEXISTS:
  228.       {
  229.         process_string_fromtab(buf,thisentry->offsets[0]);
  230.           if (file_exists(buf)) 
  231.         {
  232.           log_printf3("IfFileExists: file \"%s\" exists, jumping %d",buf,thisentry->offsets[1]);
  233.           return thisentry->offsets[1];
  234.         }
  235.         log_printf3("IfFileExists: file \"%s\" does not exist, jumping %d",buf,thisentry->offsets[2]);
  236.       }
  237.     return thisentry->offsets[2];
  238.     case EW_EXTRACTFILE:
  239.       {
  240.         HANDLE hOut;
  241.         int ret;
  242.         int overwriteflag=thisentry->offsets[0];
  243.         char *p;
  244.         lstrcpy(buf,state_output_directory);
  245.         if (buf[lstrlen(buf)-1]!='\\') lstrcat(buf,"\\");
  246.  
  247.         p=GetStringFromStringTab(thisentry->offsets[1]);
  248.         log_printf3("File: overwriteflag=%d, name=\"%s\"",overwriteflag,p);
  249.         lstrcat(buf,p);
  250.       _tryagain:
  251.         if (overwriteflag==0)
  252.         {
  253.           int attr=GetFileAttributes(buf);
  254.           if (attr & FILE_ATTRIBUTE_READONLY)
  255.             SetFileAttributes(buf,attr^FILE_ATTRIBUTE_READONLY);
  256.         }
  257.         if (overwriteflag == 3) // check date and time
  258.         {
  259.           overwriteflag=1; // if it doesn't exist, fall back to no overwrites (since it shouldn't matter anyway)
  260.           hOut=CreateFile(buf,GENERIC_READ,0,NULL,OPEN_EXISTING,0,NULL);
  261.           if (hOut != INVALID_HANDLE_VALUE)
  262.           {
  263.             FILETIME ft;
  264.             if (GetFileTime(hOut,NULL,NULL,&ft))
  265.             {
  266.               FILETIME ft2;
  267.               ft2.dwHighDateTime=thisentry->offsets[3];
  268.               ft2.dwLowDateTime=thisentry->offsets[4];
  269.               overwriteflag=(CompareFileTime(&ft,&ft2) >= 0);  // if first one is newer, then don't overwrite
  270.             }
  271.             CloseHandle(hOut);              
  272.           }
  273.         }
  274.         hOut=CreateFile(buf,GENERIC_WRITE,0,NULL,(overwriteflag==1)?CREATE_NEW:CREATE_ALWAYS,0,NULL);
  275.         if (hOut == INVALID_HANDLE_VALUE)
  276.         {
  277.           if (overwriteflag) 
  278.           {
  279.             update_status_text("Skipped: ",p);
  280.             if (overwriteflag==2) exec_errorflag++;
  281.             log_printf3("File: skipping: \"%s\" (overwriteflag=%d)",buf,overwriteflag); 
  282.             return 0;
  283.           }
  284.           log_printf2("File: error creating \"%s\"",buf); 
  285.           lstrcpy(buf2,"Error opening file for writing:\r\n  \"");
  286.           lstrcat(buf2,buf);
  287.           lstrcat(buf2,"\"\r\n"
  288.                         "Hit abort to abort installation,\r\n"
  289.                         "retry to retry writing the file, or\r\n"
  290.                         "ignore to skip this file");
  291.           
  292.           switch (MessageBox(g_hwnd,buf2,g_caption,MB_ABORTRETRYIGNORE|MB_ICONSTOP))
  293.           {
  294.             case IDRETRY:
  295.               log_printf("File: error, user retry"); 
  296.               goto _tryagain;
  297.             case IDIGNORE:
  298.               log_printf("File: error, user cancel"); 
  299.               exec_errorflag++;
  300.               return 0;
  301.             default:
  302.               log_printf("File: error, user abort"); 
  303.               update_status_text("Aborted when couldn't write file: ",buf);
  304.             return EXEC_ERROR;
  305.           }
  306.         }
  307.  
  308.         update_status_text("Extract: ",p);
  309.         ret=GetCompressedDataFromDataBlock(thisentry->offsets[2],hOut);
  310.  
  311.         log_printf3("File: wrote %d to \"%s\"",ret,buf);
  312.  
  313.         if (thisentry->offsets[3] != 0xffffffff || thisentry->offsets[4] != 0xffffffff)
  314.         {
  315.           FILETIME ft;
  316.           ft.dwHighDateTime=thisentry->offsets[3];
  317.           ft.dwLowDateTime=thisentry->offsets[4];
  318.           SetFileTime(hOut,&ft,NULL,&ft);
  319.         }
  320.  
  321.         CloseHandle(hOut);
  322.  
  323.         if (ret < 0)
  324.         {
  325.           if (ret == -2)
  326.           {
  327.             lstrcpy(buf,"Extract: error writing to file ");
  328.             lstrcat(buf,p);
  329.           }
  330.           else
  331.           {
  332.             lstrcpy(buf,g_errdecomp);
  333.           }
  334.           log_printf2("%s",buf);
  335.           MessageBox(g_hwnd,buf,g_caption,MB_OK|MB_ICONSTOP);
  336.           return EXEC_ERROR;
  337.         }
  338.       }
  339.     return 0;
  340.     case EW_SHELLEXEC: // this uses improvements of Andras Varga
  341.       process_string_fromtab(buf,thisentry->offsets[0]);
  342.       process_string_fromtab(buf2,thisentry->offsets[1]);
  343.       process_string_fromtab(buf3,thisentry->offsets[2]);
  344.       wsprintf(buf4, "%s %s", buf, buf2);
  345.       update_status_text("ExecShell: ", buf4);
  346.       x=(int)ShellExecute(g_hwnd,buf[0]?buf:NULL,buf2,buf3[0]?buf3:NULL,state_output_directory,thisentry->offsets[3]);
  347.       if (x > 32)
  348.       {
  349.         log_printf4("ExecShell: success (\"%s\": file:\"%s\" params:\"%s\")",buf,buf2,buf3);
  350.       }
  351.       else
  352.       {
  353.         log_printf5("ExecShell: warning: error (\"%s\": file:\"%s\" params:\"%s\")=%d",buf,buf2,buf3,x);
  354.         exec_errorflag++;
  355.       }
  356.     return 0;
  357.     case EW_EXECUTE:
  358.       {
  359.         PROCESS_INFORMATION ProcInfo={0,};
  360.         STARTUPINFO StartUp={sizeof(STARTUPINFO),};
  361.         exec_errorflag++;
  362.         process_string_fromtab(buf,thisentry->offsets[0]);
  363.         log_printf2("Exec: command=\"%s\"",GetStringFromStringTab(thisentry->offsets[0]));
  364.         update_status_text("Execute: ",buf);
  365.         if (CreateProcess( NULL, buf, NULL, NULL, FALSE, 0, NULL, state_output_directory, &StartUp, &ProcInfo))
  366.         {
  367.           log_printf2("Exec: success (\"%s\")",buf);
  368.           if (NULL != ProcInfo.hThread) CloseHandle( ProcInfo.hThread );
  369.           if (NULL != ProcInfo.hProcess)
  370.           {
  371.             exec_errorflag--;
  372.             if (thisentry->offsets[1]==1) 
  373.             {
  374.               DWORD lExitCode;
  375.               while (WaitForSingleObject(ProcInfo.hProcess,100) == WAIT_TIMEOUT)
  376.               {
  377.                 static MSG msg;
  378.                 while (PeekMessage(&msg,NULL,WM_PAINT,WM_PAINT,PM_REMOVE))
  379.                   DispatchMessage(&msg);
  380.               }
  381.               GetExitCodeProcess(ProcInfo.hProcess, &lExitCode);
  382.               if( lExitCode != 0 )
  383.               {
  384.                 exec_errorflag++;
  385.               }
  386.             }
  387.             CloseHandle( ProcInfo.hProcess );
  388.           }
  389.         }
  390.         else 
  391.         { 
  392.           log_printf2("Exec: failed createprocess (\"%s\")",buf); 
  393.         }
  394.       }
  395.     return 0;
  396.     case EW_COMPAREFILETIMES:
  397.       {
  398.         HANDLE h1, h2;
  399.         FILETIME ft1,ft2;
  400.         int rv=0;
  401.         int a=thisentry->offsets[1]&0x7FFFFFFF;
  402.         ft1.dwLowDateTime=thisentry->offsets[0];
  403.         ft1.dwHighDateTime=thisentry->offsets[4];
  404.         if (a == thisentry->offsets[1]) // high bit not set
  405.         {
  406.           exec_errorflag++;
  407.           process_string_fromtab(buf,thisentry->offsets[0]);
  408.           h1=CreateFile(buf,GENERIC_READ,0,NULL,OPEN_EXISTING,0,NULL);
  409.           if (h1 != INVALID_HANDLE_VALUE)
  410.           {
  411.             if (GetFileTime(h1,NULL,NULL,&ft1)) exec_errorflag--;
  412.             CloseHandle(h1);
  413.           }
  414.         }
  415.         exec_errorflag++;
  416.         process_string_fromtab(buf,a);
  417.         h2=CreateFile(buf,GENERIC_READ,0,NULL,OPEN_EXISTING,0,NULL);
  418.         if (h2 != INVALID_HANDLE_VALUE)
  419.         {
  420.           if (GetFileTime(h2,NULL,NULL,&ft2))
  421.           {
  422.             int a=CompareFileTime(&ft1,&ft2);
  423.             if (a > 0) rv=thisentry->offsets[2];
  424.             if (a < 0) rv=thisentry->offsets[3];
  425.             exec_errorflag--;
  426.           }
  427.           CloseHandle(h2);
  428.         }
  429.         return rv;
  430.       }
  431.     case EW_COMPAREDLLS:
  432.       {
  433.         int rv=0;
  434.         DWORD s1=1,s2;
  435.         DWORD t[4]; // our two members are the 3rd and 4th..
  436.         VS_FIXEDFILEINFO *pvsf1=(VS_FIXEDFILEINFO*)t, *pvsf2;
  437.         DWORD d;
  438.         int a=thisentry->offsets[1]&0x7FFFFFFF;
  439.         pvsf1->dwFileVersionLS=thisentry->offsets[0];
  440.         pvsf1->dwFileVersionMS=thisentry->offsets[4];
  441.  
  442.         if (a==thisentry->offsets[1]) // high bit not set
  443.         {
  444.           process_string_fromtab(buf,thisentry->offsets[0]);
  445.           s1=GetFileVersionInfoSize(buf,&d);
  446.           pvsf1=NULL;
  447.         }
  448.  
  449.         process_string_fromtab(buf2,a);
  450.         s2=GetFileVersionInfoSize(buf2,&d);
  451.         exec_errorflag++;
  452.         if (s1 && s2)
  453.         {
  454.           void *b1;
  455.           b1=(void*)GlobalAlloc(GPTR,s1+s2);
  456.           if (b1)
  457.           {
  458.             UINT uLen;
  459.             void *b2=(char*)b1+s1;
  460.             if( (pvsf1 || (GetFileVersionInfo(buf,0,s1,b1) && 
  461.                           VerQueryValue(b1,"\\",&pvsf1,&uLen))) &&
  462.                 GetFileVersionInfo(buf2,0,s2,b2) && VerQueryValue(b2,"\\",&pvsf2,&uLen))
  463.             {
  464.               if (pvsf1->dwFileVersionMS > pvsf2->dwFileVersionMS)
  465.                 rv=thisentry->offsets[2];
  466.               else if (pvsf1->dwFileVersionMS < pvsf2->dwFileVersionMS)
  467.                 rv=thisentry->offsets[3];
  468.               else if (pvsf1->dwFileVersionLS > pvsf2->dwFileVersionLS)
  469.                 rv=thisentry->offsets[2];
  470.               else if (pvsf1->dwFileVersionLS < pvsf2->dwFileVersionLS)
  471.                 rv=thisentry->offsets[3];
  472.               exec_errorflag--;
  473.             }
  474.             GlobalFree(b1);
  475.           }
  476.         }
  477.         return rv;
  478.       }
  479.     case EW_GETFULLDLLPATH:
  480.       {
  481.         HANDLE h;
  482.         process_string_fromtab(buf,thisentry->offsets[1]);          
  483.         h=LoadLibrary(buf);
  484.         if (h)
  485.         {
  486.           GetModuleFileName(h,g_usrvars[thisentry->offsets[0]],1024);
  487.           FreeLibrary(h);
  488.         }
  489.         else 
  490.         {
  491.           g_usrvars[thisentry->offsets[0]][0]=0;
  492.           exec_errorflag++;
  493.         }
  494.       }
  495.     return 0;
  496. #ifdef NSIS_SUPPORT_ACTIVEXREG
  497.     case EW_REGISTERDLL:
  498.       {
  499.         HRESULT hres=OleInitialize(NULL);
  500.         exec_errorflag++;
  501.         if (hres == S_FALSE || hres == S_OK)
  502.         {
  503.           HANDLE h;
  504.           process_string_fromtab(buf,thisentry->offsets[0]);
  505.           
  506.           h=LoadLibrary(buf);
  507.           if (h)
  508.           {
  509.             FARPROC funke = GetProcAddress(h,GetStringFromStringTab(thisentry->offsets[1]));
  510.             if (funke) 
  511.             {
  512.               exec_errorflag--;
  513.               update_status_text(GetStringFromStringTab(thisentry->offsets[2]),buf);
  514.               funke();
  515.             }
  516.             else if (!thisentry->offsets[1])
  517.             {
  518.               update_status_text("Could not find symbol: ",buf); 
  519.               log_printf4("%s%s not found in %s",g_errdll,GetStringFromStringTab(thisentry->offsets[1]),buf);
  520.             }
  521.             FreeLibrary(h);
  522.           }
  523.           else if (!thisentry->offsets[1])
  524.           {
  525.             update_status_text("Could not load: ",buf); 
  526.             log_printf3("%sCould not load %s",g_errdll,buf);
  527.           }
  528.           OleUninitialize();
  529.         }
  530.         else
  531.         {
  532.           update_status_text("No OLE for: ",buf); 
  533.           log_printf2("%sCould not initialize OLE",g_errdll);;
  534.         }
  535.       }
  536.     return 0;
  537. #endif
  538. #ifdef NSIS_SUPPORT_NETSCAPEPLUGINS
  539.     case EW_INSTNETSCAPE: // install netscape plug-in
  540.       {
  541.         HKEY hKey;
  542.             if ( RegOpenKeyEx(HKEY_LOCAL_MACHINE,"SOFTWARE\\Netscape\\Netscape Navigator",0,KEY_READ,&hKey) == ERROR_SUCCESS)
  543.             {
  544.           x=0;
  545.           for (;;)
  546.           {
  547.             FILETIME pft;
  548.             HKEY subKey;
  549.             DWORD lname=sizeof(buf3);
  550.             if (RegEnumKeyEx(hKey,x++,buf3,&lname,NULL,NULL,NULL,&pft) != ERROR_SUCCESS) break;
  551.             lstrcat(buf3,"\\Main");
  552.             if (RegOpenKeyEx(hKey,buf3,0,KEY_READ,&subKey) == ERROR_SUCCESS)
  553.             {
  554.                     int l = sizeof(buf);
  555.                     int t=REG_SZ;
  556.                     if (RegQueryValueEx(subKey,"Plugins Directory",NULL,&t,buf,&l ) == ERROR_SUCCESS && t == REG_SZ)
  557.                     {
  558.                         lstrcat(buf,"\\");
  559.                 lstrcat(buf,GetStringFromStringTab(thisentry->offsets[0]));
  560.                 {
  561.                   const char *nserrstr="Error accessing Netscape plug-in.\r\nMake sure all windows of Netscape are closed.\r\nHit Retry to try again, Cancel to skip";
  562.                   HANDLE hOut=INVALID_HANDLE_VALUE;
  563.                   retryagainns:
  564.                   {
  565.                     int attr=GetFileAttributes(buf);
  566.                     if (attr & FILE_ATTRIBUTE_READONLY)
  567.                       SetFileAttributes(buf,attr^FILE_ATTRIBUTE_READONLY);
  568.                   }
  569.                   
  570.                   if (thisentry->offsets[1]) // uninstall
  571.                   {
  572.                     hOut=CreateFile(buf,0,0,NULL,OPEN_EXISTING,0,NULL);                  
  573.                     if (hOut != INVALID_HANDLE_VALUE)
  574.                     {
  575.                       CloseHandle(hOut);
  576.                       if (!DeleteFile(buf))
  577.                       {
  578.                         log_printf2("InstNSPlug: error removing: %s",buf);
  579.                         hOut=INVALID_HANDLE_VALUE;
  580.                         if (MessageBox(g_hwnd,nserrstr,g_caption,MB_RETRYCANCEL|MB_APPLMODAL|MB_TOPMOST)==IDOK) goto retryagainns;
  581.                         log_printf2("InstNSPlug: uninstall from %s aborted by user",buf);
  582.                         exec_errorflag++;
  583.                       }
  584.                       else
  585.                         log_printf2("InstNSPlug: removed: %s",buf);
  586.                     }
  587.                   }
  588.                   else
  589.                   {
  590.                     hOut=CreateFile(buf,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,0,NULL);                  
  591.                     if (hOut == INVALID_HANDLE_VALUE)
  592.                     {
  593.                       if (MessageBox(g_hwnd,nserrstr,g_caption,MB_RETRYCANCEL|MB_APPLMODAL|MB_TOPMOST)==IDOK) goto retryagainns;
  594.                       log_printf2("InstNSPlug: install to %s aborted by user",buf);
  595.                       exec_errorflag++;
  596.                     }
  597.  
  598.                     if (hOut != INVALID_HANDLE_VALUE && !thisentry->offsets[1])
  599.                     {
  600.                       int ret=GetCompressedDataFromDataBlock(thisentry->offsets[2],hOut);
  601.  
  602.                       if (thisentry->offsets[3] != 0xffffffff && thisentry->offsets[4] != 0xffffffff)
  603.                       {
  604.                         FILETIME ft;
  605.                         ft.dwHighDateTime=thisentry->offsets[3];
  606.                         ft.dwLowDateTime=thisentry->offsets[4];
  607.                         SetFileTime(hOut,&ft,NULL,&ft);
  608.                       }
  609.  
  610.                       CloseHandle(hOut);
  611.  
  612.                       if (ret<0)
  613.                       {
  614.                         DeleteFile(buf);
  615.                         if (ret == -2)
  616.                         {
  617.                           lstrcpy(buf2,"Extract: error writing to file ");
  618.                           lstrcat(buf2,buf);
  619.                         }
  620.                         else
  621.                         {
  622.                           lstrcpy(buf2,g_errdecomp);
  623.                         }
  624.                         RegCloseKey(subKey);
  625.                               RegCloseKey(hKey);
  626.                         log_printf2("%s",buf2);
  627.                         MessageBox(g_hwnd,buf2,g_caption,MB_OK|MB_ICONSTOP);
  628.                         return EXEC_ERROR;
  629.                       }
  630.                       update_status_text("Installed Netscape plug-in: ",buf);
  631.                       log_printf2("InstNSPlug: wrote: %s",buf);
  632.                     }
  633.                   } // install
  634.                 }
  635.                     }
  636.               RegCloseKey(subKey);
  637.             }
  638.           }
  639.                 RegCloseKey(hKey);
  640.         }
  641.         else
  642.         {
  643.           log_printf("InstNSPlug: Netscape registry settings not found");
  644.         }
  645.       }
  646.     return 0;
  647. #endif
  648.     case EW_DELREG:
  649.       {
  650.         int rootkey=thisentry->offsets[0];
  651.         exec_errorflag++;
  652.         process_string_fromtab(buf4,thisentry->offsets[1]);
  653.         if (thisentry->offsets[2] != -1)
  654.         {
  655.           HKEY hKey;
  656.           if (RegOpenKey((HKEY)rootkey,buf4,&hKey) == ERROR_SUCCESS) 
  657.           {
  658.             process_string_fromtab(buf,thisentry->offsets[2]);
  659.             log_printf4("DeleteRegValue: %d\\%s\\%s",rootkey,buf4,buf);
  660.             if (RegDeleteValue(hKey,buf) == ERROR_SUCCESS) exec_errorflag--;
  661.             RegCloseKey(hKey);
  662.           }
  663.         }
  664.         else
  665.         {
  666.           log_printf3("DeleteRegKey: %d\\%s",rootkey,buf4);
  667.           if (myRegDeleteKeyEx((HKEY)rootkey,buf4,thisentry->offsets[3]) == ERROR_SUCCESS) exec_errorflag--;
  668.         }
  669.       }
  670.     return 0;
  671.     case EW_WRITEREG: // write registry value
  672.       {
  673.         HKEY hKey;
  674.         int rootkey=thisentry->offsets[0];
  675.         int type=thisentry->offsets[4];
  676.         exec_errorflag++; 
  677.         process_string_fromtab(buf2,thisentry->offsets[2]);
  678.         process_string_fromtab(buf4,thisentry->offsets[1]);
  679.         if (RegCreateKey((HKEY)rootkey,buf4,&hKey) == ERROR_SUCCESS) 
  680.         {
  681.           if (type == 1)
  682.           {
  683.             process_string_fromtab(buf3,thisentry->offsets[3]);
  684.             if (RegSetValueEx(hKey,buf2,0,REG_SZ,buf3,lstrlen(buf3)+1) == ERROR_SUCCESS) exec_errorflag--;
  685.             log_printf5("WriteRegStr: set %d\\%s\\%s to %s",rootkey,buf4,buf2,buf3);
  686.           }
  687.           else if (type == 2)
  688.           {
  689.             if (RegSetValueEx(hKey,buf2,0,REG_DWORD,(unsigned char*)&thisentry->offsets[3],4) == ERROR_SUCCESS) exec_errorflag--;
  690.             log_printf5("WriteRegDword: set %d\\%s\\%s to %d",rootkey,buf4,buf2,thisentry->offsets[3]);
  691.           }
  692.           else if (type == 3)
  693.           {
  694.             int len=GetCompressedDataFromDataBlockToMemory(thisentry->offsets[3], buf3, 1024);
  695.             if (len >= 0)
  696.             {
  697.               if (RegSetValueEx(hKey,buf2,0,REG_BINARY,buf3,len) == ERROR_SUCCESS) exec_errorflag--;
  698.             }
  699.             log_printf5("WriteRegBin: set %d\\%s\\%s with %d bytes",rootkey,buf4,buf2,len);
  700.  
  701.           }
  702.           RegCloseKey(hKey);
  703.         }
  704.         else { log_printf3("WriteReg: error creating key %d\\%s",rootkey,buf4); }
  705.       }
  706.     return 0;
  707.     case EW_WRITEINI:
  708.       {
  709.         char *sec, *ent;
  710.         sec=ent=0;
  711.         lstrcpy(buf2,"<RM>");
  712.         lstrcpy(buf3,buf2);
  713.         process_string_fromtab(buf,thisentry->offsets[0]);
  714.         if (thisentry->offsets[1]>=0) 
  715.         { 
  716.           process_string_fromtab(buf2,thisentry->offsets[1]); 
  717.           sec=buf2; 
  718.         }
  719.         if (thisentry->offsets[2]>=0) 
  720.         { 
  721.           process_string_fromtab(buf3,thisentry->offsets[2]); 
  722.           ent=buf3; 
  723.         }
  724.         process_string_fromtab(buf4,thisentry->offsets[3]); 
  725.         log_printf5("WriteINIStr: wrote [%s] %s=%s in %s",buf,buf2,buf3,buf4);
  726.         if (!WritePrivateProfileString(buf,sec,ent,buf4)) exec_errorflag++;
  727.       }
  728.     return 0;
  729.     case EW_CREATESHORTCUT:
  730.       process_string_fromtab(buf3,thisentry->offsets[0]);
  731.       process_string_fromtab(buf2,thisentry->offsets[1]);
  732.       process_string_fromtab(buf, thisentry->offsets[2]);
  733.       process_string_fromtab(buf4,thisentry->offsets[3]);
  734.  
  735.       log_printf8("CreateShortCut: out: \"%s\", in: \"%s %s\", icon: %s,%d, sw=%d, hk=%d",
  736.           buf3,buf2,buf,buf4,thisentry->offsets[4],thisentry->offsets[5]&0xffff,thisentry->offsets[5]>>16); 
  737.  
  738.       if (CreateShortCut(g_hwnd, buf3, buf4[0]?buf4:NULL, thisentry->offsets[4]&0xff, buf2, buf[0]?buf:NULL,
  739.           state_output_directory,(thisentry->offsets[4]&0xff00)>>8,thisentry->offsets[4]>>16))
  740.       {
  741.         exec_errorflag++;
  742.         update_status_text("Error creating shortcut: ",buf3);
  743.       }
  744.       else
  745.       {
  746.         update_status_text("Created shortcut: ",buf3);
  747.       }
  748.     return 0;
  749.     case EW_DELETEFILE:
  750.       log_printf2("Delete: \"%s\"",buf); 
  751.       {
  752.             HANDLE h;
  753.             WIN32_FIND_DATA fd;
  754.         char *p=buf;
  755.         process_string_fromtab(buf2,thisentry->offsets[0]);
  756.         lstrcpy(buf,buf2);
  757.         while (*p) p++;
  758.         while (p > buf && *p != '\\') p--;
  759.         *p=0;
  760.             h=FindFirstFile(buf2,&fd);
  761.             if (h != INVALID_HANDLE_VALUE)
  762.             {
  763.           do
  764.           {
  765.                   if (!(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) 
  766.             {
  767.               wsprintf(buf2,"%s\\%s",buf,fd.cFileName);
  768.               if (fd.dwFileAttributes & FILE_ATTRIBUTE_READONLY) 
  769.                 SetFileAttributes(buf2,fd.dwFileAttributes^FILE_ATTRIBUTE_READONLY);
  770.               if (DeleteFile(buf2))
  771.               {
  772.                 log_printf2("Delete: DeleteFile(\"%s\")",buf2); 
  773.                 update_status_text(g_deletefilecolon,buf2);
  774.               }
  775.               else
  776.               {
  777.                 if (thisentry->offsets[1])
  778.                 {
  779.                   log_printf2("Delete: DeleteFile on Reboot(\"%s\")",buf2); 
  780.                   update_status_text("Delete on reboot: ",buf2);
  781.                   MoveFileOnReboot(buf2,NULL);
  782.                 }
  783.                 else
  784.                 {
  785.                   exec_errorflag++;
  786.                 }
  787.               }
  788.             }
  789.           } while (FindNextFile(h,&fd));
  790.                 FindClose(h);
  791.             }
  792.       }
  793.     return 0;
  794.     case EW_FINDWINDOW:
  795.       {
  796.         int whattodo=thisentry->offsets[0];
  797.         char *wndclass=GetStringFromStringTab(thisentry->offsets[1]);
  798.         char *wndtitle=NULL;
  799.         char *mytext=wndclass;
  800.         log_printf3("FindWindow: checking for window class: %s . whattodo=%d",wndclass,whattodo); 
  801.         if (thisentry->offsets[3])
  802.         {
  803.           wndtitle=wndclass;
  804.           wndclass=NULL;
  805.         }
  806.         if (whattodo==2)
  807.         {
  808.           process_string_fromtab(buf4,thisentry->offsets[2]);
  809.           while (FindWindow(wndclass,wndtitle))
  810.           {
  811.             int r=MessageBox(g_hwnd,buf4,g_caption,MB_ABORTRETRYIGNORE);
  812.             if (r == IDABORT) 
  813.             {
  814.               static char *t="FindWindow: user abort";
  815.               log_printf(t); 
  816.               update_status_text(t,"");
  817.               return EXEC_ERROR;
  818.             }
  819.             if (r == IDIGNORE) 
  820.             {
  821.               log_printf("FindWindow: user ignore"); 
  822.               break;
  823.             }
  824.           }
  825.         }
  826.         else if (whattodo==1)
  827.         {
  828.           HWND hwnd=FindWindow(wndclass,wndtitle);
  829.           if (hwnd)
  830.           {
  831.             log_printf2("FindWindow: closing window (%s) (one-shot)",mytext); 
  832.             SendMessage(hwnd,WM_CLOSE,0,0);
  833.           }
  834.         }
  835.         else if (whattodo==0)
  836.         {
  837.           HWND hwnd;
  838.           int r=8;
  839.           while ((hwnd=FindWindow(wndclass,wndtitle)))
  840.           {
  841.             SendMessage(hwnd,WM_CLOSE,0,0);
  842.             Sleep(250);
  843.             if (r--<0) 
  844.             {
  845.               break;
  846.             }
  847.           }
  848.           if (!hwnd)
  849.           {
  850.             log_printf3("FindWindow: closed window (%s) (multi-try). %d",mytext,r); 
  851.           }
  852.           else
  853.           {
  854.             log_printf2("FindWindow: gave up closing window (%s)",mytext); 
  855.           }
  856.         }
  857.         else if (whattodo==3)
  858.         {
  859.           if (FindWindow(wndclass,wndtitle)) return thisentry->offsets[4];
  860.         }
  861.       }
  862.     return 0;
  863.     case EW_MESSAGEBOX: // MessageBox      
  864.       {
  865.         int v;
  866.         process_string_fromtab(buf4,thisentry->offsets[1]);
  867.         log_printf3("MessageBox: %d,\"%s\"",thisentry->offsets[0],buf4); 
  868.         v=MessageBox(g_hwnd,buf4,g_caption,thisentry->offsets[0]);
  869.         if (v && v==thisentry->offsets[2])
  870.         {
  871.           return thisentry->offsets[3];
  872.         }
  873.       }
  874.     return 0;
  875.     case EW_RMDIR:
  876.       {
  877.         char *p;
  878.         log_printf2("RMDir: \"%s\"",GetStringFromStringTab(thisentry->offsets[0])); 
  879.         process_string_fromtab(buf,thisentry->offsets[0]);
  880.         p=buf + lstrlen(buf)-1;
  881.         if (*p=='\\') *p=0;
  882.  
  883.         doRMDir(buf,thisentry->offsets[1]);
  884.         if (file_exists(buf)) exec_errorflag++;
  885.       }
  886.     return 0;
  887.     case EW_COPYFILES: // CopyFile (added by NOP)
  888.       {
  889.         int res;
  890.             SHFILEOPSTRUCT op;
  891.         process_string_fromtab(buf,thisentry->offsets[0]);
  892.         process_string_fromtab(buf2,thisentry->offsets[1]);
  893.               log_printf3("CopyFiles \"%s\"->\"%s\"",buf,buf2);
  894.               op.hwnd=g_hwnd;
  895.               op.wFunc=FO_COPY;
  896.               buf[lstrlen(buf)+1]=0;
  897.               buf2[lstrlen(buf2)+1]=0;
  898.               op.pFrom=buf;
  899.               op.pTo=buf2;
  900.               op.fFlags=FOF_NOCONFIRMATION|FOF_NOCONFIRMMKDIR|FOF_NOERRORUI;
  901.         op.fAnyOperationsAborted=FALSE;
  902.               res=SHFileOperation(&op);
  903.         update_status_text("Copying files: ",buf);
  904.               if (op.fAnyOperationsAborted || res) 
  905.         { // these changes were from Edgewise (wiked_edge@yahoo.com)
  906.           if (op.fAnyOperationsAborted) update_status_text("Copy aborted by user: ",buf);
  907.           else update_status_text("Copy failed: ", buf);
  908.           exec_errorflag++;
  909.               }
  910.         }
  911.         return 0;
  912.     case EW_IFERRORS:
  913.       {
  914.         int f=exec_errorflag;
  915.         exec_errorflag=thisentry->offsets[2];
  916.         if (f)
  917.         {
  918.           return thisentry->offsets[0];
  919.         }
  920.       }
  921.     return thisentry->offsets[1];
  922.     case EW_GETPARENT:
  923.       {
  924.         char *p=buf4;
  925.         process_string_fromtab(buf4,thisentry->offsets[1]);
  926.         while (*p) p++;
  927.         while (p >= buf4 && *p != '\\') p--;
  928.         if (p >= buf4) *p=0;
  929.         else exec_errorflag++;
  930.         lstrcpy(g_usrvars[thisentry->offsets[0]],buf4);
  931.       }
  932.     return 0;
  933.     case EW_ASSIGNVAR:
  934.       process_string_fromtab(buf4,thisentry->offsets[1]);
  935.       if (thisentry->offsets[2]>0 && thisentry->offsets[2] < 1024)
  936.         buf4[thisentry->offsets[2]]=0;
  937.       lstrcpy(g_usrvars[thisentry->offsets[0]],buf4);        
  938.     return 0;
  939.     case EW_READREGSTR: // read registry string
  940.       {
  941.         HKEY hKey;
  942.         char *p=g_usrvars[thisentry->offsets[0]];
  943.         int rootkey=thisentry->offsets[1];
  944.         process_string_fromtab(buf,thisentry->offsets[2]); // buf == subkey
  945.         process_string_fromtab(buf2,thisentry->offsets[3]); // buf == key name
  946.         p[0]=0;
  947.              if ( RegOpenKeyEx((HKEY)rootkey,buf,0,KEY_READ,&hKey) == ERROR_SUCCESS)
  948.         {
  949.                 int l = 1024;
  950.                 int t=REG_SZ;
  951.                 if (RegQueryValueEx(hKey,buf2,NULL,&t,p,&l ) != ERROR_SUCCESS || t != REG_SZ)
  952.             exec_errorflag++;
  953.           RegCloseKey(hKey);
  954.         }
  955.         else exec_errorflag++;
  956.      }
  957.     return 0;
  958.     case EW_READINISTR:
  959.       {
  960.         static const char *errstr="!nsiser";
  961.         char *p=g_usrvars[thisentry->offsets[0]];
  962.         process_string_fromtab(buf,thisentry->offsets[1]);
  963.         process_string_fromtab(buf2,thisentry->offsets[2]);
  964.         process_string_fromtab(buf3,thisentry->offsets[3]);
  965.         GetPrivateProfileString(buf,buf2,errstr,p,1023,buf3);
  966.         if (*((int*)errstr) == *((int*)p) && *(((int*)errstr)+1) == *(((int*)p)+1))
  967.         {
  968.           exec_errorflag++;
  969.           p[0]=0;
  970.         }
  971.       }
  972.     return 0;
  973.     case EW_STRCMP:
  974.       process_string_fromtab(buf3,thisentry->offsets[0]);
  975.       process_string_fromtab(buf4,thisentry->offsets[1]);
  976.       if (!lstrcmpi(buf3,buf4)) return thisentry->offsets[2];
  977.     return thisentry->offsets[3];
  978.   }
  979.   MessageBox(g_hwnd,"Install corrupted: invalid opcode",g_caption,MB_OK|MB_ICONSTOP);
  980.   return EXEC_ERROR;
  981. }