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

  1. #include <windows.h>
  2. #include <shlobj.h>
  3. #include "util.h"
  4. #include "state.h"
  5. #include "libc.h"
  6. #include "config.h"
  7.  
  8. #include "fileform.h"
  9.  
  10. #ifdef NSIS_CONFIG_LOG
  11. char g_log_file[1024];
  12. #endif
  13.  
  14. char g_usrvars[12][1024];
  15. char *state_install_directory=g_usrvars[10];
  16. char *state_output_directory=g_usrvars[11];
  17.  
  18. HANDLE g_hInstance;
  19.  
  20. int is_valid_instpath(char *s)
  21. {
  22.   int ivp=0;
  23.   if (s[0] == '\\' && s[1] == '\\') // \\ path
  24.   {
  25.     if (s[lstrlen(s)-1]!='\\') ivp++;
  26.     while (*s) if (*s++ == '\\') ivp++;
  27.     ivp/=5;
  28.   }
  29.   else
  30.   {
  31.     if (s[0] && s[1] == ':' && s[2] == '\\' && s[3] && s[3]!='\\') ivp++;
  32.   }
  33.   return ivp;
  34. }
  35.  
  36. static char *findinmem(char *a, char *b, int len_of_a)
  37. {
  38.   len_of_a -= lstrlen(b);
  39.   while (*a && len_of_a >= 0)
  40.   {
  41.     char *t=a,*u=b;
  42.     while (*t && *t == *u)
  43.     {
  44.       t++;
  45.       u++;
  46.     }
  47.     if (!*u) return a;
  48.     a++;
  49.     len_of_a--;
  50.   }
  51.   return NULL;
  52. }
  53.  
  54. BOOL MoveFileOnReboot(LPCTSTR pszExisting, LPCTSTR pszNew)
  55. {
  56.   BOOL fOk = 0;
  57.   HMODULE hLib=LoadLibrary("kernel32.dll");
  58.   if (hLib)
  59.   {
  60.     typedef BOOL (WINAPI *mfea_t)(LPCSTR lpExistingFileName,LPCSTR lpNewFileName,DWORD dwFlags);
  61.     mfea_t mfea;
  62.     mfea=(mfea_t) GetProcAddress(hLib,"MoveFileExA");
  63.     if (mfea)
  64.     {
  65.       fOk=mfea(pszExisting, pszNew, MOVEFILE_DELAY_UNTIL_REBOOT|MOVEFILE_REPLACE_EXISTING);
  66.     }
  67.     FreeLibrary(hLib);
  68.   }
  69.  
  70.   if (!fOk)
  71.   {
  72. #if 0
  73.     if (pszNew)
  74.     {
  75.       // contributed by Francis Irving.. supports long filenames,
  76.       // change that #if 0 to #if 1 to try it out (I haven't really yet)
  77.  
  78.       HKEY runOnceKey;
  79.       if (RegOpenKeyEx(
  80.              HKEY_LOCAL_MACHINE,
  81.              "Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce",
  82.              0,
  83.              KEY_SET_VALUE,
  84.              &runOnceKey ) == ERROR_SUCCESS)
  85.       {
  86.         char *buf = (char*)GlobalAlloc(GMEM_FIXED,2048);
  87.         lstrcpy(buf, "command.com /c move \"");
  88.         lstrcat(buf, pszExisting);
  89.         lstrcat(buf, "\" \"");
  90.         lstrcat(buf, pszNew);
  91.         lstrcat(buf, "\"");
  92.         if (RegSetValueEx(runOnceKey,pszExisting,0,
  93.                      REG_SZ, buf, lstrlen(buf) + 1 ) == ERROR_SUCCESS) fOk++;
  94.         RegCloseKey(runOnceKey);
  95.         GlobalFree(buf);
  96.       }
  97.     }
  98.     else
  99. #endif
  100.     {
  101.       char *szRenameLine=(char*)GlobalAlloc(GPTR,1024*3);   
  102.       int cchRenameLine;
  103.       char *szRenameSec = "[Rename]\r\n";
  104.       HANDLE hfile, hfilemap;
  105.       DWORD dwFileSize, dwRenameLinePos;
  106.       char *wininit=szRenameLine+1024;
  107.       char *tmpbuf=szRenameLine+2048;
  108.       static char nulint[4]="NUL";
  109.  
  110.       if (pszNew) GetShortPathName(pszNew,tmpbuf,1024);
  111.       else *((int *)tmpbuf) = *((int *)nulint);
  112.       // wininit is used as a temporary here
  113.       GetShortPathName(pszExisting,wininit,1024);
  114.       pszExisting=wininit;
  115.       cchRenameLine = wsprintf(szRenameLine,"%s=%s\r\n",tmpbuf,pszExisting);
  116.     
  117.       GetWindowsDirectory(wininit, 1024-16);
  118.       lstrcat(wininit, "\\wininit.ini");
  119.       hfile = CreateFile(wininit,      
  120.           GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, 
  121.           FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
  122.  
  123.       if (hfile != INVALID_HANDLE_VALUE) 
  124.       {
  125.         dwFileSize = GetFileSize(hfile, NULL);
  126.         hfilemap = CreateFileMapping(hfile, NULL, PAGE_READWRITE, 0, dwFileSize + cchRenameLine + 10, NULL);
  127.  
  128.         if (hfilemap != NULL) 
  129.         {
  130.           LPSTR pszWinInit = (LPSTR) MapViewOfFile(hfilemap, FILE_MAP_WRITE, 0, 0, 0);
  131.  
  132.           if (pszWinInit != NULL) 
  133.           {
  134.             int do_write=0;
  135.             LPSTR pszRenameSecInFile = mini_strstr(pszWinInit, szRenameSec);
  136.             if (pszRenameSecInFile == NULL) 
  137.             {
  138.               lstrcpy(pszWinInit+dwFileSize, szRenameSec);
  139.               dwFileSize += 10;
  140.               dwRenameLinePos = dwFileSize;
  141.               do_write++;
  142.             } 
  143.             else 
  144.             {
  145.               char *pszFirstRenameLine = mini_strstr(pszRenameSecInFile, "\n")+1;
  146.               int l=pszWinInit + dwFileSize-pszFirstRenameLine;
  147.               if (!findinmem(pszFirstRenameLine,szRenameLine,l))
  148.               {
  149.                 mini_memmove(pszFirstRenameLine + cchRenameLine, pszFirstRenameLine, l);                  
  150.                 dwRenameLinePos = pszFirstRenameLine - pszWinInit;
  151.                 do_write++;
  152.               }
  153.             }
  154.  
  155.             if (do_write) 
  156.             {
  157.               mini_memcpy(&pszWinInit[dwRenameLinePos], szRenameLine,cchRenameLine);
  158.               dwFileSize += cchRenameLine;
  159.             }
  160.  
  161.             UnmapViewOfFile(pszWinInit);
  162.  
  163.             fOk++;
  164.           }
  165.           CloseHandle(hfilemap);
  166.         }
  167.         SetFilePointer(hfile, dwFileSize, NULL, FILE_BEGIN);
  168.         SetEndOfFile(hfile);
  169.         CloseHandle(hfile);
  170.       }
  171.       GlobalFree(szRenameLine);
  172.     }
  173.   }
  174.   return fOk;
  175. }
  176.  
  177. void recursive_create_directory(char *directory)
  178. {
  179.     char *p;
  180.   p=directory;
  181.   while (*p == ' ') p++;
  182.   if (!*p) return;
  183.   if (p[1] == ':' && p[2] == '\\') p+=2;
  184.   else if (p[0] == '\\' && p[1] == '\\')
  185.   {
  186.     while (*p != '\\' && *p) p++; // skip host
  187.     if (*p) p++;
  188.     while (*p != '\\' && *p) p++; // skip share
  189.     if (*p) p++;
  190.   }
  191.   else return;
  192.   while (*p)
  193.   {
  194.     while (*p != '\\' && *p) p++;
  195.     if (!*p) CreateDirectory(directory,NULL);
  196.     else
  197.     {
  198.       *p=0;
  199.         CreateDirectory(directory,NULL);
  200.       *p++ = '\\';
  201.     }
  202.   }
  203. }
  204.  
  205. static int strcmp_nstr2(char **s1, char *s2)
  206. {
  207.   char *ps1=*s1;
  208.   while (*ps1 && *ps1 == *s2) { ps1++; s2++; }
  209.   if (!*s2) *s1=ps1;
  210.   return *s2;
  211. }
  212.  
  213. static void queryShellFolders(char *name, char *out)
  214. {
  215.     HKEY hKey;
  216.     if ( RegOpenKeyEx(HKEY_CURRENT_USER,"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders",0,KEY_READ,&hKey) == ERROR_SUCCESS)
  217.   {
  218.         int l = 1024;
  219.         int t=REG_SZ;
  220.         RegQueryValueEx(hKey,name,NULL,&t,out,&l );
  221.     RegCloseKey(hKey);
  222.   }
  223. }
  224.  
  225. int process_string_fromtab(char *out, int offs)
  226. {
  227.   return process_string(out,GetStringFromStringTab(offs));
  228. }
  229.  
  230.  
  231. // returns 0 if out==in
  232. // returns 2 if invalid symbol
  233. // returns 3 if error looking up symbol
  234. int process_string(char *out, char *in)
  235. {
  236.   static char *_desktop="DESKTOP";
  237.   static char *_smprograms="SMPROGRAMS";
  238.   static char *_smstartup="SMSTARTUP";
  239.   static const char winamp[] = "Winamp";
  240.   char *insave=in;
  241.   char *outsave=out;
  242.   while (*in)
  243.   {
  244.     char rts=0;
  245.     static char buf[1024];
  246.     buf[0]=0;
  247.     if (*in != '$') *out++=*in++;
  248.     else 
  249.     {
  250.       in++;
  251.       if (*in == '$')
  252.       {
  253.         *out++=*in++;
  254.       }
  255.       else
  256.       {
  257.         if (in[0] >= '0' && in[0] <= '9')
  258.         {
  259.           lstrcpy(out,g_usrvars[in[0]-'0']);
  260.           in++;
  261.           rts++;
  262.         }
  263.         else if (!strcmp_nstr2(&in,"PROGRAMFILES"))
  264.         {
  265.               HKEY hKey;
  266.           lstrcpy(out,"C:\\Program Files");
  267.               if ( RegOpenKeyEx(HKEY_LOCAL_MACHINE,"SOFTWARE\\Microsoft\\Windows\\CurrentVersion",0,KEY_READ,&hKey) == ERROR_SUCCESS)
  268.           {
  269.                   int l=1024;
  270.                   int t=REG_SZ;
  271.                   RegQueryValueEx(hKey,"ProgramFilesDir",NULL,&t,out,&l);
  272.                   RegCloseKey(hKey);
  273.           }
  274.         }
  275.         else if (!strcmp_nstr2(&in,"HWNDPARENT"))
  276.         {
  277.           wsprintf(out,"%u",(unsigned int)g_hwnd);
  278.         }
  279.         else if (!strcmp_nstr2(&in,_desktop))
  280.         {
  281.           queryShellFolders(_desktop,out);
  282.           if (!out[0]) goto copyst;
  283.         }
  284.         else if (!strcmp_nstr2(&in,"EXEDIR"))
  285.         {
  286.           lstrcpy(out,state_exe_directory);
  287.         }
  288.         else if (!strcmp_nstr2(&in,"INSTDIR"))
  289.         {
  290.           lstrcpy(out,state_install_directory);
  291.         }
  292.         else if (!strcmp_nstr2(&in,"OUTDIR"))
  293.         {
  294.           lstrcpy(out,state_output_directory);
  295.         }
  296.         else if (!strcmp_nstr2(&in,"WINDIR"))
  297.         {
  298.           GetWindowsDirectory(out,1024);
  299.         }
  300.         else if (!strcmp_nstr2(&in,"SYSDIR"))
  301.         {
  302.           GetSystemDirectory(out,1024);
  303.         }
  304.         else if (!strcmp_nstr2(&in,"TEMP"))
  305.         {
  306.           GetTempPath(1024,out);
  307.         }
  308.         else if (!strcmp_nstr2(&in,"STARTMENU"))
  309.         {
  310.           queryShellFolders("Start Menu",out);
  311.           if (!out[0]) goto copyst;
  312.         }
  313.         else if (!strcmp_nstr2(&in,_smprograms))
  314.         {
  315.           queryShellFolders(_smprograms+2,out);
  316.           if (!out[0]) goto copyst;
  317.         }
  318.         else if (!strcmp_nstr2(&in,_smstartup))
  319.         {
  320.           queryShellFolders(_smstartup+2,out);
  321.           if (!out[0]) goto copyst;
  322.         }
  323.         else if (!strcmp_nstr2(&in,"QUICKLAUNCH"))
  324.         {
  325.           queryShellFolders("AppData",buf);
  326.           if (buf[0])
  327.           {
  328.             DWORD f;
  329.             lstrcat(buf,"\\Microsoft\\Internet Explorer\\Quick Launch");
  330.             f=GetFileAttributes(buf);
  331.             if (f == (DWORD)-1 || !(f&FILE_ATTRIBUTE_DIRECTORY)) buf[0]=0;
  332.           }
  333.           if (!buf[0])
  334.           {
  335.             GetTempPath(1024,buf);
  336.           }
  337.           lstrcpy(out,buf);
  338.         }
  339.         else goto copyst;
  340.         if (!rts) // remove trailing slash
  341.         {
  342.           while (*out && out[1]) out++;
  343.           if (*out=='\\') *out=0;
  344.         }
  345.         while (*out) out++;
  346.       }
  347.     } // *in == $
  348.   } // while
  349.   *out=0;
  350.   return 0;
  351. copyst:
  352.   lstrcpy(outsave,insave);
  353.   return 3;
  354. }
  355.  
  356. #ifdef NSIS_CONFIG_LOG
  357.  
  358. char log_text[4096];
  359. int log_dolog;
  360. void log_write(int close)
  361.   extern char g_log_file[1024];
  362.   static HANDLE fp=INVALID_HANDLE_VALUE;
  363.   if (close)
  364.   {
  365.     if (fp!=INVALID_HANDLE_VALUE) 
  366.     {
  367.       CloseHandle(fp);
  368.     }
  369.     fp=INVALID_HANDLE_VALUE;
  370.     return;
  371.   }
  372.   if (log_dolog)
  373.   {
  374.     if (g_log_file[0] && fp==INVALID_HANDLE_VALUE)
  375.     {
  376.       fp = CreateFile(g_log_file,GENERIC_WRITE,FILE_SHARE_READ,NULL,OPEN_ALWAYS,0,NULL);
  377.       if (fp!=INVALID_HANDLE_VALUE) 
  378.         SetFilePointer(fp,0,NULL,FILE_END);
  379.     }
  380.     if (fp!=INVALID_HANDLE_VALUE)
  381.     {
  382.       DWORD d;
  383.       lstrcat(log_text,"\r\n");
  384.       WriteFile(fp,log_text,lstrlen(log_text),&d,NULL);
  385.     }
  386.   }
  387. }
  388.  
  389.  
  390. #endif
  391.  
  392.  
  393. int CreateShortCut(HWND hwnd, LPCSTR pszShortcutFile, LPCSTR pszIconFile, int iconindex, LPCSTR pszExe, LPCSTR pszArg, LPCSTR workingdir, int showmode, int hotkey)
  394. {
  395.   HRESULT hres;
  396.   int rv=1;
  397.   IShellLink* psl;
  398.   hres=OleInitialize(NULL);
  399.   if (hres != S_FALSE && hres != S_OK) return rv;
  400.  
  401.   hres = CoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
  402.                             &IID_IShellLink, (void **) &psl);
  403.   if (SUCCEEDED(hres))
  404.   {
  405.     IPersistFile* ppf;
  406.  
  407.     hres = psl->lpVtbl->QueryInterface(psl,&IID_IPersistFile, (void **) &ppf);
  408.     if (SUCCEEDED(hres))
  409.     {
  410.       WCHAR wsz[1024];
  411.       MultiByteToWideChar(CP_ACP, 0, pszShortcutFile, -1, wsz, 1024);
  412.  
  413.        hres = psl->lpVtbl->SetPath(psl,pszExe);
  414.        psl->lpVtbl->SetWorkingDirectory(psl,workingdir);
  415.        if (showmode) psl->lpVtbl->SetShowCmd(psl,showmode);
  416.        if (hotkey) psl->lpVtbl->SetHotkey(psl,(unsigned short)hotkey);
  417.        if (pszIconFile) psl->lpVtbl->SetIconLocation(psl,pszIconFile,iconindex);
  418.        if (pszArg) 
  419.        {
  420.          psl->lpVtbl->SetArguments(psl,pszArg);
  421.        }
  422.  
  423.        if (SUCCEEDED(hres))
  424.        {
  425.               hres=ppf->lpVtbl->Save(ppf,(const WCHAR*)wsz,TRUE);
  426.           if (SUCCEEDED(hres)) rv=0;
  427.        }
  428.       ppf->lpVtbl->Release(ppf);
  429.     }
  430.     psl->lpVtbl->Release(psl);
  431.   }
  432.   OleUninitialize();
  433.   return rv;
  434. }
  435.