Subversion Repositories filter_foundry

Rev

Rev 163 | Rev 184 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. /*
  2.     This file is part of "Filter Foundry", a filter plugin for Adobe Photoshop
  3.     Copyright (C) 2003-2019 Toby Thain, toby@telegraphics.com.au
  4.  
  5.     This program is free software; you can redistribute it and/or modify
  6.     it under the terms of the GNU General Public License as published by
  7.     the Free Software Foundation; either version 2 of the License, or
  8.     (at your option) any later version.
  9.  
  10.     This program is distributed in the hope that it will be useful,
  11.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.     GNU General Public License for more details.
  14.  
  15.     You should have received a copy of the GNU General Public License
  16.     along with this program; if not, write to the Free Software
  17.     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  18. */
  19.  
  20. #include "ff.h"
  21.  
  22. #include "file_compat.h"
  23. #include "compat_string.h"
  24. #include "versioninfo_modify_win.h"
  25. #include "version.h"
  26.  
  27. extern HANDLE hDllInstance;
  28.  
  29. Boolean doresources(HMODULE srcmod,char *dstname);
  30.  
  31. void dbglasterror(char *func){
  32.         char s[0x100];
  33.  
  34.         strcpy(s,func);
  35.         strcat(s," failed: ");
  36.         FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM,NULL,GetLastError(),0,s+strlen(s),0x100,NULL );
  37.         dbg(s);
  38. }
  39.  
  40. /*
  41. BOOL CALLBACK enumfunc(HMODULE hModule,LPCTSTR lpszType,LPCTSTR lpszName,WORD wIDLanguage,LONG lParam){
  42.         char s[0x100];
  43.         sprintf(s,"EnumResourceLanguages callback: module=%#x type=%s name=%s lang=%d",
  44.                 hModule,lpszType,lpszName,wIDLanguage);
  45.         dbg(s);
  46.         return TRUE;
  47. }
  48. */
  49.  
  50. Boolean doresources(HMODULE srcmod,char *dstname){
  51.         HRSRC datarsrc,aetersrc;
  52.         HANDLE datah,aeteh,hupdate;
  53.         Ptr newpipl = NULL,newaete = NULL,datap,aetep;
  54.         PARM_T *pparm = NULL;
  55.         long piplsize,aetesize,origsize;
  56.         Str255 title;
  57.         LPCTSTR parm_type;
  58.         int i,parm_id;
  59.         Boolean discard = true;
  60.         LPWSTR changeRequestStr, tmp;
  61.         char* soleFilename;
  62.  
  63.         if (!isWin32NT()) {
  64.                 HMODULE hLib;
  65.  
  66.                 hLib = LoadLibraryA("UNICOWS.DLL");
  67.                 if (!hLib) {
  68.                         char* sysdir;
  69.  
  70.                         sysdir = (char*)malloc(MAX_PATH);
  71.                         GetSystemDirectoryA(sysdir, MAX_PATH);
  72.                         alertuser("To build standalone plugins using this version of\nWindows, you need to install UNICOWS.DLL\n\nPlease download it from the Internet\nand place it into following directory:",sysdir);
  73.                         free(sysdir);
  74.  
  75.                         return false;
  76.                 } else {
  77.                         FreeLibrary(hLib);
  78.                 }
  79.         }
  80.  
  81. //      if(!EnumResourceLanguages(srcmod,"PiPL",MAKEINTRESOURCE(16000),enumfunc,0))
  82. //              dbglasterror("EnumResourceLanguages");
  83.  
  84.         if( (hupdate = _BeginUpdateResource(dstname,false)) ){
  85.                 DBG("BeginUpdateResource OK");
  86.                 if( (datarsrc = FindResource(srcmod,MAKEINTRESOURCE(16000),RT_RCDATA))
  87.                         && (datah = LoadResource(srcmod,datarsrc))
  88.                         && (datap = LockResource(datah))
  89.                         && (aetersrc = FindResource(srcmod,MAKEINTRESOURCE(16000),"AETE"))
  90.                         && (aeteh = LoadResource(srcmod,aetersrc))
  91.                         && (aetep = LockResource(aeteh)) )
  92.                 {
  93.                         DBG("loaded DATA, PiPL");
  94.  
  95.                         PLstrcpy(title,gdata->parm.title);
  96.                         if(gdata->parm.popDialog)
  97.                                 PLstrcat(title,(StringPtr)"\003...");
  98.  
  99.                         origsize = SizeofResource(srcmod,datarsrc);
  100.                         aetesize = SizeofResource(srcmod,aetersrc);
  101.  
  102.                         if( (newpipl = malloc(origsize+0x300))
  103.                          && (newaete = malloc(aetesize+0x100))
  104.                          && (pparm = malloc(sizeof(PARM_T))) )
  105.                         {
  106.                                 /* add user-specified title and category to new PiPL */
  107.                                 memcpy(newpipl,datap,origsize);
  108.                                 /* note that Windows PiPLs have 2 byte version datum in front
  109.                                    that isn't reflected in struct definition or Mac resource template: */
  110.  
  111.                                 piplsize = fixpipl((PIPropertyList*)(newpipl+2),origsize-2,title) + 2;
  112. //sprintf(s,"origsize=%d titlesize=%d catsize=%d piplsize=%d",origsize,titlesize,catsize,piplsize);dbg(s);
  113.  
  114.                                 /* copy old aete data to new block */
  115.                                 /* Windows 'aete' also has 2 byte version prefix */
  116.                                 memcpy(newaete,aetep,aetesize);
  117.  
  118.                                 aetesize = fixaete((unsigned char*)newaete+2,aetesize-2,gdata->parm.title) + 2;
  119.  
  120.                                 /* set up the PARM resource with saved parameters */
  121.                                 memcpy(pparm,&gdata->parm,sizeof(PARM_T));
  122.  
  123.                                 /* convert to C strings for Windows PARM resource */
  124.                                 myp2cstr(pparm->category);
  125.                                 myp2cstr(pparm->title);
  126.                                 myp2cstr(pparm->copyright);
  127.                                 myp2cstr(pparm->author);
  128.                                 for(i=0;i<4;++i)
  129.                                         myp2cstr(pparm->map[i]);
  130.                                 for(i=0;i<8;++i)
  131.                                         myp2cstr(pparm->ctl[i]);
  132.  
  133.                                 if(gdata->obfusc){
  134.                                         parm_type = RT_RCDATA;
  135.                                         parm_id = OBFUSCDATA_ID;
  136.                                         obfusc((unsigned char*)pparm,sizeof(PARM_T));
  137.                                 }else{
  138.                                         parm_type = "PARM";
  139.                                         parm_id = PARM_ID;
  140.                                 }
  141.  
  142.                                 /* Attention: The resource we have found using FindResource() might have a different
  143.                                    language than the resource we are saving (Neutral), so we might end up having
  144.                                    multiple languages for the same resource. Therefore, the language "Neutral" was
  145.                                    set in the PIPL.RC file, for the resources PIPL and AETE. */
  146.                                 if( _UpdateResource(hupdate,"PIPL" /* note: caps!! */,MAKEINTRESOURCE(16000),
  147.                                                                    MAKELANGID(LANG_NEUTRAL,SUBLANG_NEUTRAL),newpipl,piplsize)
  148.                                  && _UpdateResource(hupdate,"AETE" /* note: caps!! */,MAKEINTRESOURCE(16000),
  149.                                                                    MAKELANGID(LANG_NEUTRAL,SUBLANG_NEUTRAL),newaete,aetesize)
  150.                                  && _UpdateResource(hupdate,parm_type,MAKEINTRESOURCE(parm_id),
  151.                                                                    MAKELANGID(LANG_NEUTRAL,SUBLANG_NEUTRAL),pparm,sizeof(PARM_T)) )
  152.                                         discard = false;
  153.                                 else
  154.                                         dbglasterror("UpdateResource");
  155.  
  156.                                 if (soleFilename = strrchr(dstname, '\\')) {
  157.                                     ++soleFilename;
  158.                                 } else {
  159.                                     soleFilename = dstname;
  160.                                 }
  161.  
  162.                                 // Format of argument "PCWSTR changes" is "<name>\0<value>\0<name>\0<value>\0....."
  163.                                 // You can CHANGE values for any given name
  164.                                 // You can DELETE entries by setting the value to "\b" (0x08 backspace character)
  165.                                 // You cannot (yet) ADD entries.
  166.                                 changeRequestStr = (LPWSTR)malloc(6*2*100+1);
  167.  
  168.                                 tmp = changeRequestStr ;
  169.  
  170.                                 tmp += mbstowcs(tmp, "Comments", 100);
  171.                                 tmp++;
  172.                                 tmp += mbstowcs(tmp, "Built using Filter Foundry " VERSION_STR, 100);
  173.                                 tmp++;
  174.  
  175.                                 tmp += mbstowcs(tmp, "CompanyName", 100);
  176.                                 tmp++;
  177.                                 tmp += mbstowcs(tmp, pparm->author, 100);
  178.                                 tmp++;
  179.  
  180.                                 tmp += mbstowcs(tmp, "LegalCopyright", 100);
  181.                                 tmp++;
  182.                                 tmp += mbstowcs(tmp, pparm->copyright, 100);
  183.                                 tmp++;
  184.  
  185.                                 tmp += mbstowcs(tmp, "FileDescription", 100);
  186.                                 tmp++;
  187.                                 tmp += mbstowcs(tmp, pparm->title, 100);
  188.                                 tmp++;
  189.  
  190.                                 tmp += mbstowcs(tmp, "OriginalFilename", 100);
  191.                                 tmp++;
  192.                                 tmp += mbstowcs(tmp, soleFilename, 100);
  193.                                 tmp++;
  194.  
  195.                                 tmp += mbstowcs(tmp, "License", 100);
  196.                                 tmp++;
  197.                                 tmp += mbstowcs(tmp, "\b", 100); // \b = remove, since filter is standalone and might have its own license
  198.                                 tmp++;
  199.  
  200.                                 tmp += mbstowcs(tmp, "", 1);
  201.  
  202.                                 if (UpdateVersionInfoWithHandle(dstname, hupdate, changeRequestStr) != NOERROR) {
  203.                                         alertuser("UpdateVersionInfoWithHandle failed","");
  204.                                 }
  205.  
  206.                                 free(changeRequestStr);
  207.                         }
  208.  
  209.                 }else dbglasterror("Find-, Load- or LockResource");
  210.  
  211.                 if(!_EndUpdateResource(hupdate,discard))
  212.                         dbglasterror("EndUpdateResource");
  213.  
  214.                 if(pparm) free(pparm);
  215.                 if(newpipl) free(newpipl);
  216.                 if(newaete) free(newaete);
  217.         }else
  218.                 dbglasterror("BeginUpdateResource");
  219.         return !discard;
  220. }
  221.  
  222. OSErr make_standalone(StandardFileReply *sfr){
  223.         Boolean res;
  224.         char dstname[0x100],srcname[MAX_PATH+1];
  225.  
  226.         //FSpDelete(&sfr->sfFile);
  227.         myp2cstrcpy(dstname,sfr->sfFile.name);
  228.         res = GetModuleFileName(hDllInstance,srcname,MAX_PATH)
  229.                   && CopyFile(srcname,dstname,false)
  230.                   && doresources(hDllInstance,dstname);
  231.  
  232.         if(!res)
  233.                 alertuser("Could not create standalone plugin.","");
  234.  
  235.         return res ? ioErr : noErr;
  236. }
  237.