<% /*
    $Revision$
    $Id$

    File:               FlexFiles.inc.asp
    Description:
    Parameters:
    Context:
    Note:               pModule, pKey en pSubpath worden genormaliseerd
                        tot simpele/veilige  padnamen

                        pickfile heeft als bijeffect dat je een bijlage uit de lijst kunt kiezen
*/

var fso = Server.CreateObject("Scripting.FileSystemObject"); // Die hebben we hier *zo* vaak nog.

function bepaalNiveau(pModule, pNiveau)
{
  if (pModule == "MLD")
  {
    if ("MO".indexOf(pNiveau) >=0)
        return pNiveau;
    else
        INTERNAL_ERROR_PNIVEAU;
  }
  if (pModule == "PRS")
  {
    if ("ABCP".indexOf(pNiveau) >=0)
        return pNiveau;
    else
        INTERNAL_ERROR_PNIVEAU;
  }

  // return pModule.substr(0,1) zou waarschijnlijk ook voldoen
  switch (pModule)
  {
    case "ALG": pNiveau = "A";
                break;
    case "BES":
    case "BEZ": pNiveau = "B";
                break;
    case "CNT": pNiveau = "C";
                break;
    case "FIN": pNiveau = "F";
                break;
    case "INS": pNiveau = (pNiveau ? pNiveau : "I"); // S voor sleutel (en toekomst: C voor controle/inspectie)
                break;
    case "MRK": pNiveau = "M";
                break;
    case "RES": pNiveau = "R";
                break;
    case "FAQ": pNiveau = "F";
                break;
  }
  return pNiveau;
}

function bepaalKenmerkGegevens(pModule, pKenmerkkey)
{
  if (pKenmerkkey == null)
    return {kenmerk_omschrijving: null, kenmerk_type: null};
  var table;
  var srttable;
  switch (pModule)
  {
    case "ALG":   table = "alg_kenmerk";
                  break;
    case "BES": table = "bes_kenmerk";
                  srttable = "bes_srtkenmerk";
                  break;
    case "BEZ":   table = "bez_kenmerk";
                  break;
    case "CNT":   table = "cnt_kenmerk";
                  srttable = "cnt_srtkenmerk";
                  break;
    case "FIN":   table = "fin_kenmerk";
                  break;
    case "INS":   table = "ins_kenmerk";
                  srttable = "ins_srtkenmerk";
                  break;
    case "MLD":   table = "mld_kenmerk";
                  srttable = "mld_srtkenmerk";
                  break;
    case "PRS":   table = "prs_kenmerk";
                  break;
    case "RES":   table = "res_kenmerk";
                  srttable = "res_srtkenmerk";
                  break;
    case "FAQ":   table = "faq_kenmerk";
                  break;
  }

  var sql = "SELECT " + lcl.xsql((srttable? "sk." + srttable : "k." + table) + "_omschrijving", (srttable? "sk." + srttable : "k." + table) + "_key") + " kenmerk_omschrijving"
          + "     ,  " + (srttable? srttable : table) + "_kenmerktype kenmerk_type"
          + "  FROM " + table + " k"
          + (srttable
            ? "   , " + srttable + " sk"
            : "")
          + " WHERE k." + table + "_key = " + pKenmerkkey
          + (srttable
            ? "   AND k." + srttable + "_key = sk." + srttable + "_key"
            : "")
  var oRs = Oracle.Execute(sql);
  var kenmerk_omschrijving = oRs("kenmerk_omschrijving").Value;
  var kenmerk_type = oRs("kenmerk_type").Value;
  oRs.close();

  return {kenmerk_omschrijving: kenmerk_omschrijving, kenmerk_type: kenmerk_type};
}

function subfolderNew(pNiveau, pId)
{
  return pNiveau + "__NEW__" + pId;
}

function subfolderKey(pNiveau, pKey)
{
  var keyStr = "0000000" + pKey;
  var subfolder = pNiveau + keyStr.substr(keyStr.length-7,4) + "___/" + pNiveau + pKey;
  return subfolder;
}

// Codering: M=MLD:K=12345:S=587:N=M:R=R400x400,F=AMSG0-01-A047.JPG
function flexProps2(flexcode)
{
    var Module, Key, Subpath, Niveau, getparams;
    var getparams = { getFiles: true };

    var codes = flexcode.split(":");
    for (var i = 0; i < codes.length; i++)
    {
        var code = codes[i].substr(0,1);
        var data = codes[i].substr(2);
        switch (codes[i].substr(0,1))
        {
            case "M": Module = data;
                      break;
            case "K": Key = data;
                      break;
            case "S": Subpath = data; // Doorgaans kenmerk key
                      break;
            case "N": Niveau = data;
                      break;
            case "F": getparams.getFile = data;
                      break;
            case "R": getparams.resizeCode = data;
                      break;
        }
    }

    var params = flexProps(Module, Key, Subpath, Niveau, getparams);
    return params;
}
function flexProps(pModule, pKey, pSubpath, pNiveau, params)
{
  params = params || {};
  var result = { directlink: false, files: [] };
  switch (pModule)
  {
      case "FGII": // Facilitor Graphics
          result.AttachRootPath = S("fg_dwf_path_concept");
          result.AttachPath = result.AttachRootPath;
          result.searchfile = true;
          result.multi = true;
          result.extFilter = "dwf";
          break;
      case "FGIIV": // Vluchtplannen
          result.AttachRootPath = S("fg_vlucht_path");
          result.AttachPath = result.AttachRootPath + "V" + pKey + "/";
          result.pickfile = true;
          result.multi = true;
          result.extFilter = "dwf";
          break;
      case  "FGIIS": // Facilitor Graphics symbolen
          result.AttachRootPath = S("fg_symbols_path");
          result.AttachPath = result.AttachRootPath;
          result.pickfile = true;
          result.multi = true;
          result.extFilter = "dwf";
          break;
      case "FGIIP":
          result.AttachRootPath = S("fg_dwf_path_prj");
          result.AttachPath = result.AttachRootPath + pKey + "/";
          result.pickfile = true;
          result.multi = true;
          result.extFilter = "dwf";
          break;
      case "BESPH":
          // Bestanden zijn te vinden op prs_bedrijf.prs_bedrijf_image_loc of ...cust/xxxx/photos/bes/[disc_key]/
          // Wij kunnen alleen bestanden naar ...cust/xxxx/photos/bes/[disc_key]/ uploaden.
          result.AttachRootPath = Server.MapPath(S("bes_image_path"));
          result.AttachPath = result.AttachRootPath + "/" + pKey + "/";
          result.extFilter = "jpg|png";
          result.pickfile = true;
          result.multi = true;
          result.regexp = S("bes_photo_size");
          result.directlink = true;
          break;
      case "INSPH":
          // Bestanden zijn te vinden op ...cust/x/photos/ins
          result.AttachRootPath = Server.MapPath(S("ins_image_path"));
          result.AttachPath = result.AttachRootPath + "/";
          result.extFilter = "jpg|png";
          result.pickfile = true;
          result.multi = true;
          result.regexp = S("ins_photo_size");
          result.directlink = true;
          break;
      case "MLDS": // Stdmelding symbolen
          result.AttachRootPath = Server.MapPath(S("mlds_image_path"));
          result.AttachPath = result.AttachRootPath + "/";
          result.pickfile = true;
          result.multi = true;
          result.extFilter = "jpg|png";
          result.regexp = S("mld_photo_size");
          result.directlink = true;
          break;
      case "ALG":
      case "BES":
      case "BEZ":
      case "CNT":
      case "FIN":
      case "INS":
      case "MLD":
      case "PRS":
      case "RES":
      case "FAQ":
          // Bestanden zijn nu te vinden on ...cust/x/flexfiles/[module]/[subfolder]/[key]/[kenmerk_key]
          result.AttachRootPath = S("flexFilesPath");
          result.AttachPath = result.AttachRootPath + "/" + pModule + "/";
          result.AttachPath += (pKey > 0? subfolderKey(bepaalNiveau(pModule, pNiveau), pKey)
                                        : subfolderNew(bepaalNiveau(pModule, pNiveau), user_key + "_" + getQParam("tmpfolder")));
          result.AttachPath += "/" + pSubpath + "/";
          result.extFilter = getQParam("extFilter", S("flexExtensionFilter"));
          result.regexp = getQParam("pregexp", ""); //P800x600 cropt/resized naar 800x600
          if (pModule == "ALG" && params)
          {
            result.trackcode = pModule + params.alglevel + "UP";
            var kenmerk_geg = bepaalKenmerkGegevens(pModule, pSubpath);
            result.kenmerkoms = kenmerk_geg.kenmerk_omschrijving;
            result.kenmerktype = kenmerk_geg.kenmerk_type;
          }
          else if (pModule != "FAQ")
          {
            if (pModule == "MLD" && pNiveau == "O")
              result.trackcode = "ORD" + "UPD";
            else
              result.trackcode = pModule + "UPD";
            var kenmerk_geg = bepaalKenmerkGegevens(pModule, pSubpath);
            result.kenmerkoms = kenmerk_geg.kenmerk_omschrijving;
            result.kenmerktype = kenmerk_geg.kenmerk_type;
          }
          break;
      case "RESPH":
      case "RESPHA":
      case "RESPHD":
          // Bestanden zijn te vinden op ...cust/x/photos
          result.AttachRootPath = Server.MapPath(S("res_image_path"));
          if (pModule == "RESPHA")
            result.AttachRootPath += '/artikel';
          if (pModule == "RESPHD")
            result.AttachRootPath += '/deel';
          result.AttachPath = result.AttachRootPath + "/";
          result.extFilter = "jpg";
          result.searchfile = true;
          result.multi = true;
          result.regexp = S("res_photo_size");
          result.directlink = true;
          if (typeof pKey == "string")
            params.filter = pKey;
          break;
      case "MRK":
          result.AttachRootPath = Server.MapPath(S("mrk_image_path"));
          result.AttachPath = result.AttachRootPath + "/";
          result.AttachPath += (pKey > 0? subfolderKey("M", pKey)
                                        : subfolderNew("M", Session.SessionId));
          result.AttachPath += "/1/";
          result.multi = false; // vooralsnog maar eentje
          result.extFilter = "jpg|png";
          result.regexp = S("mrk_photo_size");
          result.directlink = true;
          break;
      case "SML":
          result.AttachRootPath = Server.MapPath(S("prs_image_path"));
          result.AttachPath = result.AttachRootPath + "/";
          result.AttachPath += subfolderKey("P", pKey);
          result.AttachPath += "/SML/";
          result.multi = false; // vooralsnog maar eentje
          result.forcesingle = true; // verwijder eventuele anderen
          result.extFilter = "jpg";
          result.regexp = S("sml_photo_size"); // "r200x150", Resized naar binnen 200x150 (zonder crop, met behoud aspect ratio)
          result.directlink = true;
          break;
      case "MENU":
          result.AttachRootPath = Server.MapPath(S("menu_image_path"));
          result.AttachPath = result.AttachRootPath + "/";
          result.multi = true;
          result.extFilter = S("flexExtensionFilter"); // was "jpg|png"; maar tegenwoordig ook andere bestanden
          result.regexp = S("menu_photo_size");
          result.directlink = true;
          break;
      case "BDRADR":
          result.AttachRootPath = S("bdradrfiles_path");
          result.AttachPath = result.AttachRootPath + "/";
          result.pickfile = true;
          result.multi = true;
          result.extFilter = S("flexExtensionFilter"); // Mag in principe alles zijn
          break;
      default:
          INTERNAL_ERROR_MODULE;
  }

  if (result.AttachRootPath.indexOf("..") > -1 || // paranoia mode, should never happen
      result.AttachPath.indexOf("..") > -1)
  {
    __DoLog("Bad attach path with '..'\nAttachRootPath: {0}\nAttachPath: {1}".format(result.AttachRootPath, result.AttachPath), '#F00');
    INTERNAL_ERROR_BAD_ATTACHPATH;
  }
  result.AttachRootPath = result.AttachRootPath.replace("..", "_");
  result.AttachPath = result.AttachPath.replace("..", "_");

  if (params.getFile)
  {
    if (fso.FileExists(result.AttachPath + params.getFile))
    {
      var fsoFile = fso.GetFile(result.AttachPath + params.getFile);
      var filedata = oneFileInfo(fsoFile, result, pModule, pKey, pSubpath, pNiveau, params);
      result.files.push(filedata);
    }
  }
  else if (params.getFiles) // Haal alle bijlagen er bij.
  {
    if (fso.FolderExists(result.AttachPath))
    {
      __Log("Scanning {0} for files".format(result.AttachPath));
      var f = fso.GetFolder(result.AttachPath);
      var fc = new Enumerator(f.files);

      var totalfiles = 0;
      for (; !fc.atEnd(); fc.moveNext())
      {
        totalfiles ++;
        var fsoFile = fc.item();
        var fName = fsoFile.Name;
//        function escapeRegExp(str)
//        {
//          return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
//        }
        if (params.filter && !(new RegExp(params.filter, "i").test(fName)))
            continue;

        var filedata = oneFileInfo(fsoFile, result, pModule, pKey, pSubpath, pNiveau, params);
        result.files.push(filedata);
      }
      __Log("Found {0}/{1} files".format(result.files.length, totalfiles));

    }
  }

  result.isAllowedName = function _isAllowedName(FileName)
  {
      if (result.extFilter)
      {
        var regFilter = result.extFilter;
        regFilter = regFilter.replace(/( |,|;)/g,"|"); // Altijd | karakter
        regFilter = ".*\\." + "(" + regFilter + ")$"; // er moet een punt voor en extensie is aan het einde
      }
      else
        regFilter = ".*";
      return (new RegExp(S("flexAllowedExt"), "ig").test(FileName) &&
              new RegExp(regFilter, "ig").test(FileName));
  }

  return result;
}

function oneFileInfo(fsoFile, result, pModule, pKey, pSubpath, pNiveau, params)
{
    var fName = fsoFile.Name;
    var oCrypto = new ActiveXObject("SLNKDWF.Crypto");
    var filedata = { name: fName,
                     date: new Date(fsoFile.DateLastModified),
                     size: fsoFile.Size,
                     digest: oCrypto.hex_sha1_file(result.AttachPath + fName)
                   }
    // IIS 7+ geeft 404.11 op een plus-teken in een url. Historisch hebben we daar
    // vele bestanden mee en die hernoemen we hier on-the-fly. Er kan nu een
    // afwijking ontstaan bij 'F' kenmerken. die in de database zijn opgeslagen
    // maar dat nemen we voor lief. In de praktijk is dat nooit probleem.
    // Als we *niet* hernoemen hebben we grotere problemen
    if (fName.toLowerCase() != safe.filename(fName).toLowerCase())
    {
        filedata.name = safe.filename(fName);
        __DoLog("Auto renaming {0} to safer {1}".format(result.AttachPath + fName, result.AttachPath + filedata.name), "#FFFF00");
        fso.MoveFile(result.AttachPath + fName, result.AttachPath + filedata.name);
    }

    // Resize een plaatje eventueel
    if (params.resizeCode && filedata.name.match(/\.(png|jpg|jpeg)$/i))
    {
        var file = result.AttachPath + filedata.name;

        var Format = params.resizeCode.match(/^([RrCc])(\d*)x(\d*)$/i); // R800x600
        if (Format && Format.length == 4)
        {
            var oIMG = new ActiveXObject("SLNKDWF.ImageConvert");
            try
            {
                oIMG.Open(result.AttachPath + filedata.name);
            }
            catch(e)
            {
                __Log("Kan plaatje {0} niet laden {1}".format(result.AttachPath + filedata.name, e.description));
                // Gewoon negeren
                return;
            }

            var RrCc = Format[1];
            var h0 = h = parseInt(Format[2], 10);
            var w0 = w = parseInt(Format[3], 10);
            if (RrCc == "R" || RrCc == "r") // Dan niet croppen maar aspect ratio behouden
            {
               if (oIMG.Width * h > w * oIMG.Height)
                   h = oIMG.Height / oIMG.Width * w;
               else
                   w = oIMG.Width / oIMG.Height * h;
            }

            if (oIMG.Height < h || oIMG.Width < w) // Zou er iets vergroot gaan worden.
            {
                if (RrCc == "R" || RrCc == "C") // Dan zijn we streng en eisen we minimale afmeting
                {
                    result.message = L("lcl_shared_photo_small").format(h0, w0, oIMG.Height, oIMG.Width);
//                    DeleteFile(params.AttachPath + result.safefilename);
                }
                else // Dan maar niet, we vergroten niet.
                {
                    h = oIMG.Height;
                    w = oIMG.Width;
                }
            }
            if (!result.message && (oIMG.Height != h || oIMG.Width != w))
            {
                try {
                    __Log("Resize/Cropping from w=" + oIMG.Width + " h=" + oIMG.Height + " to w=" + w + " h=" + h);
                    oIMG.Width = w;
                    oIMG.Height = h;

                    // TODO: Originele type behouden of altijd naar het compactere jpg?
                    var tempfile = Server.MapPath(rooturl + '/temp/img_' + customerId + '_' + filedata.digest + "_" + params.resizeCode + ".jpg");
                    oIMG.SaveAs(tempfile);
                    filedata.resized = tempfile;
                    if (typeof Session("Logging")=="undefined" || Session("Logging") == 0)
                        filedata.tempdelete = tempfile; // Moet aanroeper opruimen
                }
                catch (e)
                {
                   result.message = L("lcl_shared_thumbnail_error") + e.description;
                   // Gewoon opruimen
//                   DeleteFile(params.AttachPath + result.safefilename);
                }
            }
        }
    }

    if (params.api2name)
    {
        var deepurl = HTTP.urlzelf() + "/api2/{0}/{1}/attachments/{2}/{3}".format(
                                        params.api2name,
                                        pKey,
                                        pSubpath,
                                        safe.filename(filedata.name) // onze filename is ondertussen dusdanig safe
                                                                     // dat ik het zonder encoding aandurf
                            );
        filedata.deepurl = deepurl;
    }
    else
    {
        if (result.directlink)
        {
            filedata.deepurl = HTTP.urlzelfnoroot() + S("res_image_path") + filedata.name;

        }
        else // Alleen streaming, bestand staat buiten webroot?
        {
            var deepurl = HTTP.urlzelf() + "/appl/shared/BijlagenStream.asp"
                        + "?module=" + pModule
                        +  "&key=" + pKey
                        + (pNiveau? "&niveau=" + pNiveau : "")
                        +  "&kenmerk_key=" + pSubpath
                        +  "&filename=" + Server.URLencode(filedata.name);
            filedata.deepurl = protectQS.create(deepurl);
        }
    }

    return filedata;
}


 // Plaats automatisch een web.config die asp-Execute van bestanden verbiedt
function checkWebconfig(AttachRootPath)
{
    return; // FSN#32282 Geeft te veel problemen
    if (fso.FolderExists(params.AttachRootPath) && !fso.FileExists(AttachRootPath + "/web.config"))
    {
        __DoLog("Placing web.config file in " + AttachRootPath);
        fso.CopyFile(Server.MapPath("./web_sample.config"), AttachRootPath + "/web.config");
    }
}

function DeleteFile(fullpath)
{
    try
    {
        fso.DeleteFile(fullpath, true);
    }
    catch (e)
    {
        __DoLog("Verwijderen " + fullpath + " mislukt: " + e.description, "#FFFF00");
    };
}

function CreateFullPath(sPath)
{
    if (!fso.FolderExists(sPath))
    {
        while (!fso.FolderExists(sPath))
        {
            var sParent = sPath;
            while (sParent && !fso.FolderExists(sParent))
            {
               var sChild = sParent;
               var sParent = fso.GetParentFolderName(sChild);
            }
            if (!sParent)
            {
                __DoLog("Cannot create folder {0}, parentfolder does not exist.".format(sPath), "#f00");
                INTERN_ERROR_BAD_PATH;
            }
            oFolder = fso.CreateFolder(sChild);
        }
    }
}

// Verplaats alle bestanden van één folder
// Verplaatst geen subfolders
function MoveFlexfiles(vAttachPath, vAttachPath2)
{
    if (vAttachPath == vAttachPath2)
    {
        __Log("MoveFlexfiles Skip want twee keer " + vAttachPath);
        return;
    }

    try
    {
        var fso = Server.CreateObject("Scripting.FileSystemObject")
        __Log("Zoeken " + vAttachPath);
        if (fso.FolderExists(vAttachPath))
        {
            var oFolder = fso.GetFolder(vAttachPath);
            if (oFolder.files.count > 0) // Anders error
            {
                CreateFullPath(vAttachPath2); // het 1000-tal was er misschien nog niet.
                __Log("Verplaats inhoud " + vAttachPath + "/*.* naar " + vAttachPath2 + "/");
                fso.MoveFile (vAttachPath + "/*.*", vAttachPath2 + "/");
            }
            fso.DeleteFolder(vAttachPath);
        }
    }
    catch(ee)
    {
        __DoLog("Moving files from " + vAttachPath + "<br>to " + vAttachPath2 + " failed:<br>" + ee.description, "#FFFF00");
    }
    fso = null;
}

// JavaScript is erg slecht in binary data, gebruik streams
// gebaseerd op Antonin Foller, http://www.motobit.com
// Binary - VT_UI1 | VT_ARRAY data To convert To a string
// getest met encoding "bin.hex" en "bin.base64"

function encodedString2File(safefullname, attachmentString, encoding)
{
    var BinaryStream = XXXXDecode(attachmentString, encoding);
    BinaryStream.SaveToFile(safefullname, 2); // adSaveCreateOverWrite
}

function XXXXDecode(vCode, encoding)
{
    var oXML, oNode

    oXML = new ActiveXObject("Msxml2.DOMDocument.6.0");
    oNode = oXML.createElement("encodeddata");
    oNode.dataType = encoding; // Zeer snelle oplossing
    oNode.text = vCode
    var Binary = oNode.nodeTypedValue;
    var adTypeText = 2;
    var adTypeBinary = 1;

    // Create Stream object
    var BinaryStream = new ActiveXObject("ADODB.Stream");

    // Specify stream type - we want To save binary data.
    BinaryStream.Type = adTypeBinary;

    // Open the stream And write binary data To the object
    BinaryStream.Open();
    BinaryStream.Write(Binary);

    // Change stream type To text/string
    BinaryStream.Position = 0;
    BinaryStream.Type = adTypeText;

    // Specify charset For the output text (unicode) data.
    BinaryStream.CharSet = "us-ascii";

    // Open the stream And get text/string data from the object
    return BinaryStream;
}

// IE doet een beetje raar als er een puntkomma in de content-disposition filenaam zit, dan negeert hij de rest
// Een bestand test.exe;.txt wordt dan zo maar 'uitgevoerd'
// Een # in de naam gaat ook raar: IE9 vervangt die zelf al door een _ maar daar vertrouwen wij niet op
// We hebben er verder geen probleem mee dat ze geupload worden (en ze bestaan ook), anders was
// toevoegen aan safe.filename natuurlijk logischer.
function safeContentName(fname)
{
    return safe.filename(fname).replace(/[\;\#]+/g, "_")
}

function StreamFile(filePath, filename, mime, pcontentdp)
{
    if (getQParamInt("zipfile", 0) == 1)
    {
        zipfile(filePath + "/" + safe.filename(filename), filename);
    }
    pcontentdp = pcontentdp || "attachment";
    try
    {
        var oStream = Server.CreateObject("ADODB.Stream");
        oStream.Open;
        oStream.Type = 1; // adTypeBinary

        oStream.LoadFromFile(filePath + "/" + safe.filename(filename));

        Response.clear;
        Response.contenttype = mime;
        // Known problems:
        //  "Plus+Quote'Spatie Rareé&amp.txt" non-ASCII karakters in pFilename worden wel eens onbedoeld herkend als UTF8
        Response.AddHeader("content-disposition", pcontentdp + "; filename= \"" + safeContentName(filename) + "\"");
        Response.BinaryWrite(oStream.read(oStream.Size));

        Response.End();
    }
    catch(e)
    {
        shared.simpel_page(Server.HTMLEncode(filename) + "<p/>" + e.description
                           + "\n<xmp style='display:none'>" + Server.HTMLEncode(filePath) + "</xmp>");
    }
    oStream = null;
}

function zipfile(fullpath, filename)
{
    var oZIP = new ActiveXObject("SLNKDWF.Zip");
    var fso = new ActiveXObject("Scripting.FileSystemObject");
    var temp = Server.MapPath("../../temp/" + fso.GetTempName());
    var iStream = new ActiveXObject("ADODB.Stream")
    iStream.Type = 2; // Text
    iStream.Open();
    iStream.CharSet = "utf-8";
    try
    {
        iStream.LoadFromFile(fullpath);
    }
    catch (e)
    {
        shared.simpel_page("Error opening " + Server.HTMLEncode(fullpath) + "<p/><em>"+e.description+"</em>");
    }
    oZIP.New(temp) //;; Helaas niet *naar* stream
    oZIP.ZipFromStream(filename, iStream);
    oZIP.Close();
    iStream.Close()
    var oStream = new ActiveXObject("ADODB.Stream");
    oStream.Open;
    oStream.Type = 1; // adTypeBinary

    oStream.LoadFromFile(temp);
    oStream.Position = 0;
    fso.DeleteFile(temp);
    Response.clear;
    Response.contenttype = 'application/zip';
    Response.AddHeader("content-disposition", "attachment; filename= \"" + filename + ".zip\"");
    Response.BinaryWrite(oStream.read(oStream.Size));
    Response.End;
}
%>
