home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 October / Chip_2001-10_cd1.bin / zkuste / delphi / nastroje / d23456 / NSIS.EXE / Source / zip2exe / main.cpp < prev    next >
C/C++ Source or Header  |  2001-05-19  |  13KB  |  434 lines

  1. #include <windows.h>
  2. #include <stdio.h>
  3.  
  4. extern "C"
  5. {
  6. #include "zlib/unzip.h"
  7. };
  8. #include "resource.h"
  9.  
  10. HINSTANCE g_hInstance;
  11.  
  12. static BOOL CALLBACK DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); 
  13.  
  14.  
  15. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInst,
  16.                    LPSTR lpszCmdParam, int nCmdShow)
  17. {
  18.   g_hInstance=hInstance;
  19.  
  20.  
  21.   return DialogBox(hInstance,MAKEINTRESOURCE(IDD_DIALOG1),GetDesktopWindow(),DlgProc);
  22. }
  23. char tempzip_path[1024];
  24.  
  25. static void doRMDir(char *buf)
  26. {
  27.   HANDLE h;
  28.   WIN32_FIND_DATA fd;
  29.   char *p=buf;
  30.   while (*p) p++;
  31.   strcpy(p,"\\*.*");
  32.   h = FindFirstFile(buf,&fd);
  33.   if (h != INVALID_HANDLE_VALUE) 
  34.   {
  35.     do
  36.     {
  37.       if (fd.cFileName[0] != '.' ||
  38.           (fd.cFileName[1] != '.' && fd.cFileName[1]))
  39.       {
  40.         strcpy(p+1,fd.cFileName);
  41.         if (fd.dwFileAttributes & FILE_ATTRIBUTE_READONLY) 
  42.           SetFileAttributes(buf,fd.dwFileAttributes^FILE_ATTRIBUTE_READONLY);
  43.         if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) doRMDir(buf);
  44.         else 
  45.         {
  46.           DeleteFile(buf);
  47.         }
  48.       }
  49.     } while (FindNextFile(h,&fd));
  50.     FindClose(h);
  51.   }
  52.   p[0]=0; // fix buffer
  53.   RemoveDirectory(buf);
  54. }
  55.  
  56. static void doMKDir(char *directory)
  57. {
  58.     char *p, *p2;
  59.     char buf[MAX_PATH];
  60.   if (!*directory) return;
  61.     strcpy(buf,directory);
  62.   p=buf; while (*p) p++;
  63.     while (p >= buf && *p != '\\') p--;
  64.     p2 = buf;
  65.     if (p2[1] == ':') p2+=4;
  66.     else if (p2[0] == '\\' && p2[1] == '\\')
  67.     {
  68.         p2+=2;
  69.         while (*p2 && *p2 != '\\') p2++;
  70.         if (*p2) p2++;
  71.         while (*p2 && *p2 != '\\') p2++;
  72.         if (*p2) p2++;
  73.     }
  74.     if (p >= p2)
  75.     {
  76.         *p=0;
  77.         doMKDir(buf);
  78.     }
  79.     CreateDirectory(directory,NULL);
  80. }
  81.  
  82.  
  83.  
  84. void tempzip_cleanup(HWND hwndDlg)
  85. {
  86.   if (tempzip_path[0]) doRMDir(tempzip_path);
  87.   tempzip_path[0]=0;
  88.   SendDlgItemMessage(hwndDlg,IDC_ZIPINFO_FILES,LB_RESETCONTENT,0,0);
  89.   SetDlgItemText(hwndDlg,IDC_ZIPINFO_SUMMARY,"");
  90.   EnableWindow(GetDlgItem(hwndDlg,IDOK),0);
  91.   SetDlgItemText(hwndDlg,IDC_ZIPFILE,"");
  92.   SetDlgItemText(hwndDlg,IDC_OUTFILE,"");
  93. }
  94.  
  95. int tempzip_make(HWND hwndDlg, char *fn)
  96. {
  97.   char buf[MAX_PATH];
  98.   GetTempPath(MAX_PATH,buf);
  99.   GetTempFileName(buf,"z2e",GetTickCount(),tempzip_path);
  100.   if (!CreateDirectory(tempzip_path,NULL))
  101.   {
  102.     GetTempPath(MAX_PATH,tempzip_path);
  103.     strcat(tempzip_path,"\\nsi");
  104.     if (!CreateDirectory(tempzip_path,NULL))
  105.     {
  106.       tempzip_path[0]=0;
  107.       MessageBox(hwndDlg,"Error creating temporary directory","ZIP2EXE Error",MB_OK|MB_ICONSTOP);
  108.       return 1;
  109.     }
  110.   }
  111.   unzFile f;
  112.   f = unzOpen(fn);
  113.   if (!f || unzGoToFirstFile(f) != UNZ_OK)
  114.   {
  115.     if (f) unzClose(f);
  116.     MessageBox(hwndDlg,"Error opening ZIP file","ZIP2EXE Error",MB_OK|MB_ICONSTOP);
  117.     return 1;
  118.   }
  119.     
  120.   int nf=0, nkb=0;
  121.     do {
  122.         char filename[MAX_PATH];
  123.       unzGetCurrentFileInfo(f,NULL,filename,sizeof(filename),NULL,0,NULL,0);
  124.     if (filename[0] && 
  125.         filename[strlen(filename)-1] != '\\' && 
  126.         filename[strlen(filename)-1] != '/')
  127.     {
  128.       char *pfn=filename;
  129.       while (*pfn)
  130.       {
  131.         if (*pfn == '/') *pfn='\\';
  132.         pfn++;
  133.       }
  134.       pfn=filename;
  135.       if (pfn[1] == ':' && pfn[2] == '\\') pfn+=3;
  136.       while (*pfn == '\\') pfn++;
  137.  
  138.       char out_filename[1024];
  139.       strcpy(out_filename,tempzip_path);
  140.       strcat(out_filename,"\\");
  141.       strcat(out_filename,pfn);
  142.       if (strstr(pfn,"\\"))
  143.       {
  144.         char buf[1024];
  145.         strcpy(buf,out_filename);
  146.         char *p=buf+strlen(buf);
  147.         while (p > buf && *p != '\\') p--;
  148.         *p=0;
  149.         if (buf[0]) doMKDir(buf);
  150.       }
  151.  
  152.           if (unzOpenCurrentFile(f) == UNZ_OK)
  153.           {
  154.         SendDlgItemMessage(hwndDlg,IDC_ZIPINFO_FILES,LB_ADDSTRING,0,(LPARAM)pfn);
  155.               FILE *fp;
  156.               int l;
  157.               fp = fopen(out_filename,"wb");
  158.               if (fp)
  159.               {
  160.                   do
  161.                   {
  162.                       char buf[1024];
  163.                       l=unzReadCurrentFile(f,buf,sizeof(buf));
  164.                       if (l > 0) 
  165.             {
  166.               if (fwrite(buf,1,l,fp) != (unsigned int)l)
  167.               {
  168.                 unzClose(f);
  169.                 fclose(fp);
  170.                 MessageBox(hwndDlg,"Error writing output file(s)","ZIP2EXE Error",MB_OK|MB_ICONSTOP);
  171.                 return 1;
  172.               }
  173.             }
  174.                   } while (l > 0);
  175.           nkb+=ftell(fp)/1024;
  176.                   fclose(fp);
  177.               }
  178.         else
  179.         {
  180.           unzClose(f);
  181.           MessageBox(hwndDlg,"Error opening output file(s)","ZIP2EXE Error",MB_OK|MB_ICONSTOP);
  182.           return 1;
  183.         }
  184.         nf++;
  185.               unzCloseCurrentFile(f);
  186.           }
  187.       else
  188.       {
  189.         unzClose(f);
  190.         MessageBox(hwndDlg,"Error extracting from ZIP file","ZIP2EXE Error",MB_OK|MB_ICONSTOP);
  191.         return 1;
  192.       }
  193.     }
  194.   } while (unzGoToNextFile(f) == UNZ_OK);
  195.   
  196.   wsprintf(buf,"%d files, %dKB",nf,nkb);
  197.   SetDlgItemText(hwndDlg,IDC_ZIPINFO_SUMMARY,buf);
  198.   unzClose(f);
  199.   return 0;
  200. }
  201.  
  202. char *gp_winamp = "(WINAMP DIRECTORY)";
  203. char *gp_winamp_plugins = "(WINAMP PLUG-INS DIRECTORY)";
  204. char *gp_winamp_vis = "(WINAMP VIS PLUG-INS DIRECTORY)";
  205. char *gp_winamp_dsp = "(WINAMP DSP PLUG-INS DIRECTORY)";
  206. char *gp_winamp_skins = "(WINAMP SKINS DIRECTORY)";
  207. char *gp_poi = "(PATH OF INSTALLER)";
  208.  
  209.  
  210. void makeEXE(HWND hwndDlg)
  211. {
  212.   char buf[2048];
  213.   char nsifilename[MAX_PATH];
  214.   GetTempPath(MAX_PATH,buf);
  215.   GetTempFileName(buf,"zne",0,nsifilename);
  216.   FILE *fp=fopen(nsifilename,"w");
  217.   if (!fp)
  218.   {
  219.     MessageBox(hwndDlg,"Error writing .NSI file","ZIP2EXE Error",MB_OK|MB_ICONSTOP);
  220.     return;
  221.   }
  222.   GetDlgItemText(hwndDlg,IDC_INSTNAME,buf,sizeof(buf));
  223.   fprintf(fp,"Name `%s`\n",buf);
  224.   fprintf(fp,"Caption `%s Self Extractor`\n",buf);
  225.   GetDlgItemText(hwndDlg,IDC_OUTFILE,buf,sizeof(buf));
  226.   fprintf(fp,"OutFile `%s`\n",buf);
  227.   GetDlgItemText(hwndDlg,IDC_INSTPATH,buf,sizeof(buf));
  228.   char *outpath = "$INSTDIR";
  229.   int iswinamp=0;
  230.   char *iswinampmode=NULL;
  231.   if (!strcmp(buf,gp_poi)) strcpy(buf,"$EXEDIR");
  232.   
  233.   if (!strcmp(buf,gp_winamp))
  234.   {
  235.     iswinamp=1;
  236.     fprintf(fp,"Function SetMyOutPath\n"
  237.                "  SetOutPath $INSTDIR\n"
  238.                "FunctionEnd\n");
  239.   }
  240.   if (!strcmp(buf,gp_winamp_plugins))
  241.   {
  242.     iswinamp=1;
  243.     fprintf(fp,"Function SetMyOutPath\n"
  244.                "  SetOutPath $INSTDIR\\Plugins\n"
  245.                "FunctionEnd\n");
  246.   }
  247.   if (!strcmp(buf,gp_winamp_vis))
  248.   {
  249.     iswinamp=1;
  250.     iswinampmode="VisDir";
  251.   }
  252.   if (!strcmp(buf,gp_winamp_dsp))
  253.   {
  254.     iswinamp=1;
  255.     iswinampmode="DSPDir";
  256.   }
  257.   if (!strcmp(buf,gp_winamp_skins))
  258.   {
  259.     iswinamp=1;
  260.     iswinampmode="SkinDir";
  261.   }
  262.  
  263.   if (iswinamp)
  264.   {
  265.     fprintf(fp,"InstallDir `$PROGRAMFILES\\Winamp`\n");
  266.     fprintf(fp,"InstallDirRegKey HKEY_LOCAL_MACHINE `Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Winamp` `UninstallString`\n");
  267.  
  268.     fprintf(fp,"Function .onVerifyInstDir\n"
  269.                "  IfFileExists $INSTDIR\\winamp.exe WinampInstalled\n"
  270.                "    Abort\n"
  271.                "  WinampInstalled:\n"
  272.                "FunctionEnd\n");
  273.  
  274.     if (iswinampmode)
  275.     {
  276.       fprintf(fp,"Function SetMyOutPath\n"
  277.                  "  StrCpy $1 $INSTDIR\\Plugins\n"
  278.                  "  ReadINIStr $9 $INSTDIR\\winamp.ini Winamp %s\n"
  279.                  "  StrCmp $9 '' End\n"
  280.                  "    IfFileExists $9 0 End\n"
  281.                  "      StrCpy $1 $9\n"
  282.                  "  End:\n"
  283.                  "  SetOutPath $1\n"
  284.                  "FunctionEnd\n",iswinampmode);
  285.     }
  286.   }
  287.   else  // set out path to $INSTDIR
  288.   {
  289.     fprintf(fp,"InstallDir `%s`\n",buf);
  290.     fprintf(fp,"Function SetMyOutPath\n"
  291.                "  SetOutPath $INSTDIR\n"
  292.                "FunctionEnd\n");
  293.   }
  294.  
  295.   GetDlgItemText(hwndDlg,IDC_DESCTEXT,buf,sizeof(buf));
  296.   fprintf(fp,"DirText `%s`\n",buf);
  297.  
  298.   fprintf(fp,"Section\n");
  299.   fprintf(fp,"Call SetMyOutPath\n");
  300.   fprintf(fp,"File /r `%s\\*.*`\n",tempzip_path);
  301.   fprintf(fp,"SectionEnd\n");
  302.   fclose(fp);
  303.  
  304.   // execute makensis
  305.   char makensis_path[MAX_PATH];
  306.   PROCESS_INFORMATION ProcInfo={0,};
  307.   STARTUPINFO StartUp={sizeof(STARTUPINFO),};
  308.   {
  309.     char *p=makensis_path;
  310.     GetModuleFileName(g_hInstance,makensis_path,sizeof(makensis_path));
  311.     while (*p) p++;
  312.     while (p >= makensis_path && *p != '\\') p--;
  313.     strcpy(++p,"makensis.exe");
  314.   }
  315.   wsprintf(buf,"\"%s\" /PAUSE \"%s\"",makensis_path,nsifilename);
  316.   if (CreateProcess( NULL, buf, NULL, NULL, FALSE, 0, NULL, tempzip_path, &StartUp, &ProcInfo))
  317.   {
  318.     if (NULL != ProcInfo.hThread) CloseHandle( ProcInfo.hThread );
  319.     if (NULL != ProcInfo.hProcess)
  320.     {
  321.       WaitForSingleObject(ProcInfo.hProcess,INFINITE);
  322.       CloseHandle( ProcInfo.hProcess );
  323.     }
  324.   }
  325.   else
  326.   {
  327.     MessageBox(hwndDlg,"Error opening Makensis","ZIP2EXE Error",MB_OK|MB_ICONSTOP);    
  328.   }
  329.  
  330.   DeleteFile(nsifilename);
  331. }
  332.  
  333.  
  334. BOOL CALLBACK DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  335. {
  336.    static HICON hIcon;
  337.   switch (uMsg)
  338.   {
  339.     if (uMsg == WM_DESTROY && hIcon) { DeleteObject(hIcon); hIcon=0; }
  340.     case WM_INITDIALOG:
  341.       SendDlgItemMessage(hwndDlg,IDC_INSTPATH,CB_ADDSTRING,0,(LPARAM)gp_poi);
  342.       SendDlgItemMessage(hwndDlg,IDC_INSTPATH,CB_ADDSTRING,0,(LPARAM)"$TEMP");
  343.       SendDlgItemMessage(hwndDlg,IDC_INSTPATH,CB_ADDSTRING,0,(LPARAM)"$SYSDIR");
  344.       SendDlgItemMessage(hwndDlg,IDC_INSTPATH,CB_ADDSTRING,0,(LPARAM)"$WINDIR");
  345.       SendDlgItemMessage(hwndDlg,IDC_INSTPATH,CB_ADDSTRING,0,(LPARAM)"$DESKTOP");
  346.       SendDlgItemMessage(hwndDlg,IDC_INSTPATH,CB_ADDSTRING,0,(LPARAM)"$DESKTOP\\Poop");
  347.       SendDlgItemMessage(hwndDlg,IDC_INSTPATH,CB_ADDSTRING,0,(LPARAM)"$PROGRAMFILES\\Poop");
  348.       SendDlgItemMessage(hwndDlg,IDC_INSTPATH,CB_ADDSTRING,0,(LPARAM)"$STARTMENU");
  349.       SendDlgItemMessage(hwndDlg,IDC_INSTPATH,CB_ADDSTRING,0,(LPARAM)"$SMPROGRAMS");
  350.  
  351.       SendDlgItemMessage(hwndDlg,IDC_INSTPATH,CB_ADDSTRING,0,(LPARAM)gp_winamp);
  352.       SendDlgItemMessage(hwndDlg,IDC_INSTPATH,CB_ADDSTRING,0,(LPARAM)gp_winamp_plugins);
  353.       SendDlgItemMessage(hwndDlg,IDC_INSTPATH,CB_ADDSTRING,0,(LPARAM)gp_winamp_vis);
  354.       SendDlgItemMessage(hwndDlg,IDC_INSTPATH,CB_ADDSTRING,0,(LPARAM)gp_winamp_dsp);
  355.       SendDlgItemMessage(hwndDlg,IDC_INSTPATH,CB_ADDSTRING,0,(LPARAM)gp_winamp_skins);
  356.      
  357.       SetDlgItemText(hwndDlg,IDC_INSTPATH,gp_poi);
  358.       SetDlgItemText(hwndDlg,IDC_DESCTEXT,"Select the folder where you would like to extract the files to:");
  359.           hIcon=LoadIcon(g_hInstance,MAKEINTRESOURCE(IDI_ICON1));
  360.           SetClassLong(hwndDlg,GCL_HICON,(long)hIcon);
  361.  
  362.     return 1;
  363.     case WM_CLOSE:
  364.       tempzip_cleanup(hwndDlg);
  365.       EndDialog(hwndDlg,1);
  366.     break;
  367.     case WM_COMMAND:
  368.       switch (LOWORD(wParam))
  369.       {
  370.         case IDC_BROWSE:
  371.           {
  372.             OPENFILENAME l={sizeof(l),};
  373.             char buf[1024];
  374.             l.hwndOwner = hwndDlg;
  375.             l.lpstrFilter = "ZIP files\0*.zip\0All files\0*.*\0";
  376.             l.lpstrFile = buf;
  377.             l.nMaxFile = 1023;
  378.             l.lpstrTitle = "Open ZIP file";
  379.             l.lpstrDefExt = "zip";
  380.             l.lpstrInitialDir = NULL;
  381.             l.Flags = OFN_HIDEREADONLY|OFN_EXPLORER;              
  382.             buf[0]=0;
  383.             if (GetOpenFileName(&l)) 
  384.             {
  385.               tempzip_cleanup(hwndDlg);
  386.               if (tempzip_make(hwndDlg,buf)) tempzip_cleanup(hwndDlg);             
  387.               else
  388.               {
  389.                 EnableWindow(GetDlgItem(hwndDlg,IDOK),1);
  390.                 SetDlgItemText(hwndDlg,IDC_ZIPFILE,buf);
  391.                 char *t=buf+strlen(buf);
  392.                 while (t > buf && *t != '\\' && *t != '.') t--;
  393.                 {
  394.                   char *p=t;
  395.                   while (p >= buf && *p != '\\') p--;
  396.                   p++;
  397.                   *t=0;
  398.                   SetDlgItemText(hwndDlg,IDC_INSTNAME,p[0]?p:"Stuff");
  399.                 }
  400.                 strcpy(t,".exe");
  401.                 SetDlgItemText(hwndDlg,IDC_OUTFILE,buf);
  402.               }
  403.             }
  404.           }          
  405.         break;
  406.         case IDC_BROWSE2:
  407.           {
  408.             OPENFILENAME l={sizeof(l),};
  409.             char buf[1024];
  410.             l.hwndOwner = hwndDlg;
  411.             l.lpstrFilter = "EXE files\0*.exe\0All files\0*.*\0";
  412.             l.lpstrFile = buf;
  413.             l.nMaxFile = 1023;
  414.             l.lpstrTitle = "Select output EXE file";
  415.             l.lpstrDefExt = "exe";
  416.             l.lpstrInitialDir = NULL;
  417.             l.Flags = OFN_HIDEREADONLY|OFN_EXPLORER;              
  418.             GetDlgItemText(hwndDlg,IDC_OUTFILE,buf,sizeof(buf));
  419.             if (GetSaveFileName(&l)) 
  420.             {
  421.               SetDlgItemText(hwndDlg,IDC_OUTFILE,buf);
  422.             }
  423.           }   
  424.         break;
  425.         case IDOK:
  426.           makeEXE(hwndDlg);
  427.           tempzip_cleanup(hwndDlg);
  428.           EndDialog(hwndDlg,0);
  429.         break;
  430.       }
  431.     break;
  432.   }
  433.   return 0;
  434. }