/// <summary> /// Refer to http://www.cnblogs.com/gjahead/archive/2007/06/18/787654.html /// </summary> /// <param name="response"></param> protected override void WriteFile(HttpResponseBase response) { #region --验证:HttpMethod,请求的文件是否存在 switch (request.HttpMethod.ToUpper()) { case "GET": case "HEAD": break; default: response.StatusCode = 501; return; } if (!File.Exists(filePath)) { response.StatusCode = 404; response.End(); return; } #endregion #region 定义局部变量 var startBytes = 0L; //分块读取,每块10K bytes var packSize = 1024 * 10; var fileName = Path.GetFileName(filePath); var file = MemoryMappedFile.CreateFromFile(filePath).CreateViewStream(); var fileLength = file.Length; var sleep = 0; var lastUpdateTiemStr = File.GetLastWriteTimeUtc(filePath).ToString("r"); //便于恢复下载时提取请求头; var eTag = HttpUtility.UrlEncode(fileName, Encoding.UTF8) + lastUpdateTiemStr; #endregion #region --验证:文件是否太大,是否是续传,且在上次被请求的日期之后是否被修 //文件太大 if (file.Length > Int32.MaxValue) { response.StatusCode = 413;//请求实体太大 } //对应响应头ETag:文件名+文件最后修改时间 if (request.Headers["If-Range"] != null) { //上次被请求的日期之后被修改过 if (request.Headers["If-Range"].Replace("\"", "") != eTag) { response.StatusCode = 412;//预处理失败 } } #endregion using (var br = new BinaryReader(file)) { #region -------添加重要响应头、解析请求头、相关验证------------------- response.Clear(); response.Buffer = false; //用于验证文件 // TODO: 验证MD5生成方式是否正确,这里对整个文件Hash,似乎有问题。 response.AddHeader("Content-MD5", GetMd5Hash(file)); //重要:续传必须 response.AddHeader("Accept-Ranges", "bytes"); //重要:续传必须 response.AppendHeader("ETag", "\"" + eTag + "\""); response.AppendHeader("Last-Modified", lastUpdateTiemStr); //把最后修改日期写入响应 response.ContentType = "application/octet-stream"; //MIME类型:匹配任意文件类型 response.AddHeader("Content-Length", (fileLength - startBytes).ToString()); response.AddHeader("Connection", "Keep-Alive"); // 不要设置Content-Distribution,FileResult会自动设置这个属性。 response.ContentEncoding = Encoding.UTF8; //如果是续传请求,则获取续传的起始位置,即已经下载到客户端的字节数 if (request.Headers["Range"] != null) { //重要:续传必须,表示局部范围响应。初始下载时默认为200 response.StatusCode = 206; //"bytes=1474560-" string[] range = request.Headers["Range"].Split(new char[] { '=', '-' }); //已经下载的字节数,即本次下载的开始位置 startBytes = Convert.ToInt64(range[1]); //无效的起始位置 if (startBytes < 0 || startBytes >= fileLength) { return; } } //如果是续传请求,告诉客户端本次的开始字节数,总长度,以便客户端将续传数据追加到startBytes位置后 if (startBytes > 0) { response.AddHeader("Content-Range", string.Format(" bytes {0}-{1}/{2}", startBytes, fileLength - 1, fileLength)); } #endregion #region -------向客户端发送数据块------------------- br.BaseStream.Seek(startBytes, SeekOrigin.Begin); //分块下载,剩余部分可分成的块数 var maxCount = (int)Math.Ceiling((fileLength - startBytes + 0.0) / packSize); for (var i = 0; i < maxCount && response.IsClientConnected; i++) { //客户端中断连接,则暂停 response.BinaryWrite(br.ReadBytes(packSize)); response.Flush(); if (sleep > 1) { Thread.Sleep(sleep); } } #endregion } }
public unsafe static int CreateInstance(ref DSConfig config) { byte[] bytes; UInt32 inst_len = Convert.ToUInt32(Marshal.SizeOf(typeof(DSInstance))); D.Print("Entering CreateInstance()"); // Initialize Instance struct DSInstance inst = new Helper().InitStruct("DSInstance"); // Add module size to instance len if (config.inst_type == Constants.DONUT_INSTANCE_PIC) { D.Print($"Adding module size {config.mod_len} to instance size"); inst_len += Convert.ToUInt32(Marshal.SizeOf(typeof(DSModule)) + 32) + Convert.ToUInt32(config.mod_len); } // Generate instance key and counter bytes = Helper.RandomBytes(32); for (var i = 0; i < bytes.Length; i++) { if (i < 16) { inst.key.ctr[i] = bytes[i]; } else { inst.key.mk[i - 16] = bytes[i]; } } D.Print($"Instance CTR:\t{BitConverter.ToString(inst.key.ctr).Replace("-", "")}"); D.Print($"Instance MK :\t{BitConverter.ToString(inst.key.mk).Replace("-", "")}"); // Generate module key and counter bytes = Helper.RandomBytes(32); for (var i = 0; i < bytes.Length; i++) { if (i < 16) { inst.mod_key.ctr[i] = bytes[i]; } else { inst.mod_key.mk[i - 16] = bytes[i]; } } D.Print($"Module CTR:\t{BitConverter.ToString(inst.mod_key.ctr).Replace("-", "")}"); D.Print($"Module MK :\t{BitConverter.ToString(inst.mod_key.mk).Replace("-", "")}"); // Create Verifier string Helper.Copy(inst.sig, Helper.RandomString(8)); D.Print($"Decryption Verfier String: {Helper.String(inst.sig)}"); // Create IV inst.iv = BitConverter.ToUInt64(Helper.RandomBytes(8), 0); D.Print($"IV for Maru Hash:\t{BitConverter.ToString(bytes).Replace("-", "")}"); // Generate DLL and API hashes Helper.APIImports(ref inst); // Assign GUIDs and other vals if (config.mod_type == Constants.DONUT_MODULE_NET_DLL || config.mod_type == Constants.DONUT_MODULE_NET_EXE) { inst.xIID_AppDomain = Constants.xIID_AppDomain; inst.xIID_ICLRMetaHost = Constants.xIID_ICLRMetaHost; inst.xCLSID_CLRMetaHost = Constants.xCLSID_CLRMetaHost; inst.xIID_ICLRRuntimeInfo = Constants.xIID_ICLRRuntimeInfo; inst.xIID_ICorRuntimeHost = Constants.xIID_ICorRuntimeHost; inst.xCLSID_CorRuntimeHost = Constants.xCLSID_CorRuntimeHost; } else if (config.mod_type == Constants.DONUT_MODULE_VBS || config.mod_type == Constants.DONUT_MODULE_JS) { inst.xIID_IUnknown = Constants.xIID_IUnknown; inst.xIID_IDispatch = Constants.xIID_IDispatch; inst.xIID_IHost = Constants.xIID_IHost; inst.xIID_IActiveScript = Constants.xIID_IActiveScript; inst.xIID_IActiveScriptSite = Constants.xIID_IActiveScriptSite; inst.xIID_IActiveScriptSiteWindow = Constants.xIID_IActiveScriptSiteWindow; inst.xIID_IActiveScriptParse32 = Constants.xIID_IActiveScriptParse32; inst.xIID_IActiveScriptParse64 = Constants.xIID_IActiveScriptParse64; Helper.Copy(inst.wscript, "WScript"); Helper.Copy(inst.wscript_exe, "wscript.exe"); if (config.mod_type == Constants.DONUT_MODULE_VBS) { inst.xCLSID_ScriptLanguage = Constants.xCLSID_VBScript; } else { inst.xCLSID_ScriptLanguage = Constants.xCLSID_JScript; } } else if (config.mod_type == Constants.DONUT_MODULE_XSL) { inst.xCLSID_DOMDocument30 = Constants.xCLSID_DOMDocument30; inst.xIID_IXMLDOMDocument = Constants.xIID_IXMLDOMDocument; inst.xIID_IXMLDOMNode = Constants.xIID_IXMLDOMNode; } Helper.Copy(inst.amsi.s, "AMSI"); Helper.Copy(inst.amsiInit, "AmsiInitialize"); Helper.Copy(inst.amsiScanBuf, "AmsiScanBuffer"); Helper.Copy(inst.amsiScanStr, "AmsiScanString"); Helper.Copy(inst.clr, "CLR"); Helper.Copy(inst.wldp, "WLDP"); Helper.Copy(inst.wldpQuery, "WldpQueryDynamicCodeTrust"); Helper.Copy(inst.wldpIsApproved, "WldpIsClassInApprovedList"); // Assign inst type inst.type = config.inst_type; // If URL type, assign URL if (inst.type == Constants.DONUT_INSTANCE_URL) { inst.http.url = new char[Constants.DONUT_MAX_URL]; inst.http.req = new char[8]; config.modname = Helper.RandomString(Constants.DONUT_MAX_MODNAME).ToCharArray(); Helper.Copy(inst.http.url, Helper.String(config.url) + Helper.String(config.modname)); Helper.Copy(inst.http.req, "GET"); D.Print($"Payload will be downloaded from {Helper.String(inst.http.url)}"); } // Update struct lengths inst.mod_len = config.mod_len; inst.len = inst_len; config.inst = inst; config.inst_len = inst_len; // Generate MAC inst.mac = Helper.Maru(Helper.String(inst.sig), ref inst); // Copy Instance to memory var instptr = Marshal.AllocHGlobal(Convert.ToInt32(config.inst_len)); Marshal.StructureToPtr(inst, instptr, false); // Copy Module to memory var modptr = Marshal.AllocHGlobal(Convert.ToInt32(config.mod_len)); Marshal.StructureToPtr(config.mod, modptr, false); // Calculate offsets var encoffset = Marshal.OffsetOf(typeof(DSInstance), "api_cnt").ToInt32(); var encptr = IntPtr.Add(instptr, encoffset); var modoffset = Marshal.OffsetOf(typeof(DSInstance), "module").ToInt32(); var moddata = IntPtr.Add(instptr, modoffset); var fileoffset = Marshal.OffsetOf(typeof(DSModule), "data").ToInt32(); // Copy Module to Instance Buffer.MemoryCopy(modptr.ToPointer(), moddata.ToPointer(), Marshal.SizeOf(typeof(DSModule)), Marshal.SizeOf(typeof(DSModule))); // if URL, copy stuff if (inst.type == Constants.DONUT_INSTANCE_URL) { D.Print($"Copying URL module data to instance"); //inst.module.p = config.mod; } // if PIC, copy payload to instance if (inst.type == Constants.DONUT_INSTANCE_PIC) { D.Print($"Copying PIC module data to instance"); // Copy payload file to end of module var mmfile = MemoryMappedFile.CreateFromFile(Helper.String(config.file), FileMode.Open); var view = mmfile.CreateViewAccessor(); byte *fileptr = (byte *)0; view.SafeMemoryMappedViewHandle.AcquirePointer(ref fileptr); Buffer.MemoryCopy(fileptr, IntPtr.Add(moddata, fileoffset).ToPointer(), config.mod.len, config.mod.len); mmfile.Dispose(); } // Release module Marshal.FreeHGlobal(modptr); // Encrypt instance D.Print("Encrypting Instance"); Helper.Encrypt(inst.key.mk, inst.key.ctr, encptr, Convert.ToUInt32(inst.len - encoffset)); // Writes raw instance if DEBUG D.WriteInst(config, instptr); // Generate final shellcode int ret = Shellcode(ref config, instptr); if (ret != Constants.DONUT_ERROR_SUCCESS) { Console.WriteLine("[x] Error " + Helper.GetError(ret)); return(ret); } return(Constants.DONUT_ERROR_SUCCESS); }
private static MemoryMappedFile CreateFile() { var controlStream = new FileStream("control", FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite); return(MemoryMappedFile.CreateFromFile(controlStream, "control", 8, MemoryMappedFileAccess.ReadWrite, HandleInheritability.Inheritable, false)); }
public MemoryMappedFileSlim(string fileNamePath) : this(MemoryMappedFile.CreateFromFile(fileNamePath, FileMode.OpenOrCreate, mapName : null), fileNamePath) { }
public bool runTest() { try { //////////////////////////////////////////////////////////////////////// // CreateOrOpen(mapName, capcity) //////////////////////////////////////////////////////////////////////// // [] mapName // mapname > 260 chars VerifyCreate("Loc111", new String('a', 1000), 4096); // null VerifyException <ArgumentNullException>("Loc112", null, 4096); // empty string disallowed VerifyException <ArgumentException>("Loc113", String.Empty, 4096); // all whitespace VerifyCreate("Loc114", "\t \n\u00A0", 4096); // MMF with this mapname already exists (pagefile backed) using (MemoryMappedFile mmf = MemoryMappedFile.CreateNew("COO_map115a", 1000)) { VerifyOpen("Loc115a", "COO_map115a", 1000, MemoryMappedFileAccess.ReadWrite); } // MMF with this mapname already exists (filesystem backed) String fileText = "Non-empty file for MMF testing."; File.WriteAllText("CreateOrOpen_test2.txt", fileText); using (MemoryMappedFile mmf = MemoryMappedFile.CreateFromFile("CreateOrOpen_test2.txt", FileMode.Open, "COO_map115b")) { VerifyOpen("Loc115b", "COO_map115b", 1000, MemoryMappedFileAccess.ReadWrite); } // MMF with this mapname existed, but was closed - new MMF VerifyCreate("Loc116", "COO_map115a", 500); // "global/" prefix VerifyCreate("Loc117", "global/COO_mapname", 4096); // "local/" prefix VerifyCreate("Loc118", "local/COO_mapname", 4096); // [] capacity // >0 capacity VerifyCreate("Loc211", "COO_mapname211", 50); // 0 capacity VerifyException <ArgumentOutOfRangeException>("Loc211", "COO_mapname211", 0); // negative VerifyException <ArgumentOutOfRangeException>("Loc213", "COO_mapname213", -1); // negative VerifyException <ArgumentOutOfRangeException>("Loc214", "COO_mapname214", -4096); // Int64.MaxValue - cannot exceed local address space if (IntPtr.Size == 4) { VerifyException <ArgumentOutOfRangeException>("Loc215", "COO_mapname215", Int64.MaxValue); } else // 64-bit machine { VerifyException <IOException>("Loc215b", "COO_mapname215", Int64.MaxValue); // valid but too large } // ignored for existing file (smaller) using (MemoryMappedFile mmf = MemoryMappedFile.CreateNew("COO_mapname216", 1000, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.None)) { VerifyOpen("Loc216", "COO_mapname216", 100, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.None, MemoryMappedFileAccess.ReadWrite); } // ignored for existing file (larger) using (MemoryMappedFile mmf = MemoryMappedFile.CreateNew("COO_mapname217", 1000, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.None)) { VerifyOpen("Loc217", "COO_mapname217", 10000, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.None, MemoryMappedFileAccess.ReadWrite); } // existing file - invalid - still exception using (MemoryMappedFile mmf = MemoryMappedFile.CreateNew("COO_mapname218", 1000, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.None)) { VerifyException <ArgumentOutOfRangeException>("Loc218", "COO_mapname218", 0, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.None); } //////////////////////////////////////////////////////////////////////// // CreateOrOpen(mapName, capcity, MemoryMappedFileAccess) //////////////////////////////////////////////////////////////////////// // [] access // Write is disallowed VerifyException <ArgumentException>("Loc330", "COO_mapname330", 1000, MemoryMappedFileAccess.Write); // valid access - new file MemoryMappedFileAccess[] accessList = new MemoryMappedFileAccess[] { MemoryMappedFileAccess.Read, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileAccess.CopyOnWrite, MemoryMappedFileAccess.ReadExecute, MemoryMappedFileAccess.ReadWriteExecute, }; foreach (MemoryMappedFileAccess access in accessList) { VerifyCreate("Loc331_" + access, "COO_mapname331_" + access, 1000, access); } // invalid enum value accessList = new MemoryMappedFileAccess[] { (MemoryMappedFileAccess)(-1), (MemoryMappedFileAccess)(6), }; foreach (MemoryMappedFileAccess access in accessList) { VerifyException <ArgumentOutOfRangeException>("Loc332_" + ((int)access), "COO_mapname332_" + ((int)access), 1000, access); } // default security - all valid for existing file using (MemoryMappedFile mmf = MemoryMappedFile.CreateNew("COO_mapname333", 1000)) { accessList = new MemoryMappedFileAccess[] { MemoryMappedFileAccess.CopyOnWrite, MemoryMappedFileAccess.Read, MemoryMappedFileAccess.Write, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileAccess.ReadExecute, MemoryMappedFileAccess.ReadWriteExecute, }; foreach (MemoryMappedFileAccess access in accessList) { VerifyOpen("Loc333_" + access, "COO_mapname333", 1000, access, access); } } //////////////////////////////////////////////////////////////////////// // CreateOrOpen(String, long, MemoryMappedFileAccess, MemoryMappedFileOptions, // MemoryMappedFileSecurity, HandleInheritability) //////////////////////////////////////////////////////////////////////// // [] mapName // mapname > 260 chars VerifyCreate("Loc411", new String('a', 1000), 4096, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.None); // null VerifyException <ArgumentNullException>("Loc412", null, 4096, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.None); // empty string disallowed VerifyException <ArgumentException>("Loc413", String.Empty, 4096, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.None); // all whitespace VerifyCreate("Loc414", "\t \n\u00A0", 4096, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.None); // MMF with this mapname already exists (pagefile backed) using (MemoryMappedFile mmf = MemoryMappedFile.CreateNew("COO_map415a", 1000)) { using (MemoryMappedFile mmf2 = MemoryMappedFile.CreateOrOpen("COO_map415a", 1000)) { VerifyOpen("Loc415a", "COO_map415a", 1000, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.None, MemoryMappedFileAccess.ReadWrite); } } // MMF with this mapname already exists (filesystem backed) File.WriteAllText("CreateOrOpen_test2.txt", fileText); using (MemoryMappedFile mmf = MemoryMappedFile.CreateFromFile("CreateOrOpen_test2.txt", FileMode.Open, "COO_map415b")) { VerifyOpen("Loc415b", "COO_map415b", 1000, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.None, MemoryMappedFileAccess.ReadWrite); } // MMF with this mapname existed, but was closed - new MMF VerifyCreate("Loc416", "COO_map415a", 500, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.None); // "global/" prefix VerifyCreate("Loc417", "global/COO_mapname", 4096, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.None); // "local/" prefix VerifyCreate("Loc418", "local/COO_mapname", 4096, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.None); // [] capacity // >0 capacity VerifyCreate("Loc421", "COO_mapname421", 50, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.None); // 0 capacity VerifyException <ArgumentOutOfRangeException>("Loc422", "COO_mapname422", 0, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.None); // negative VerifyException <ArgumentOutOfRangeException>("Loc423", "COO_mapname423", -1, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.None); // negative VerifyException <ArgumentOutOfRangeException>("Loc424", "COO_mapname424", -4096, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.None); // Int64.MaxValue - cannot exceed local address space if (IntPtr.Size == 4) { VerifyException <ArgumentOutOfRangeException>("Loc425", "COO_mapname425", Int64.MaxValue, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.None); } else // 64-bit machine { VerifyException <IOException>("Loc425b", "COO_mapname425", Int64.MaxValue, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.None); // valid but too large } // ignored for existing file (smaller) using (MemoryMappedFile mmf = MemoryMappedFile.CreateNew("COO_mapname426", 1000, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.None)) { VerifyOpen("Loc426", "COO_mapname426", 100, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.None, MemoryMappedFileAccess.ReadWrite); } // ignored for existing file (larger) using (MemoryMappedFile mmf = MemoryMappedFile.CreateNew("COO_mapname427", 1000, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.None)) { VerifyOpen("Loc427", "COO_mapname427", 10000, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.None, MemoryMappedFileAccess.ReadWrite); } // existing file - invalid - still exception using (MemoryMappedFile mmf = MemoryMappedFile.CreateNew("COO_mapname428", 1000, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.None)) { VerifyException <ArgumentOutOfRangeException>("Loc428", "COO_mapname428", 0, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.None); } // [] access // Write is disallowed for new file VerifyException <ArgumentException>("Loc430", "COO_mapname430", 1000, MemoryMappedFileAccess.Write, MemoryMappedFileOptions.None, HandleInheritability.None); // valid access for a new file accessList = new MemoryMappedFileAccess[] { MemoryMappedFileAccess.Read, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileAccess.CopyOnWrite, MemoryMappedFileAccess.ReadExecute, MemoryMappedFileAccess.ReadWriteExecute, }; foreach (MemoryMappedFileAccess access in accessList) { VerifyCreate("Loc431_" + access, "COO_mapname431_" + access, 1000, access, MemoryMappedFileOptions.None, HandleInheritability.None); } // invalid enum value accessList = new MemoryMappedFileAccess[] { (MemoryMappedFileAccess)(-1), (MemoryMappedFileAccess)(6), }; foreach (MemoryMappedFileAccess access in accessList) { VerifyException <ArgumentOutOfRangeException>("Loc432_" + ((int)access), "COO_mapname432_" + ((int)access), 1000, access, MemoryMappedFileOptions.None, HandleInheritability.None); } // default security - all valid using (MemoryMappedFile mmf = MemoryMappedFile.CreateNew("COO_mapname433", 1000)) { accessList = new MemoryMappedFileAccess[] { MemoryMappedFileAccess.CopyOnWrite, MemoryMappedFileAccess.Read, MemoryMappedFileAccess.Write, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileAccess.ReadExecute, MemoryMappedFileAccess.ReadWriteExecute, }; foreach (MemoryMappedFileAccess access in accessList) { VerifyOpen("Loc433_" + access, "COO_mapname433", 1000, access, MemoryMappedFileOptions.None, HandleInheritability.None, access); } } // default security, original (lesser) viewAccess is respected using (MemoryMappedFile mmf = MemoryMappedFile.CreateNew("COO_mapname434", 1000, MemoryMappedFileAccess.Read)) { accessList = new MemoryMappedFileAccess[] { MemoryMappedFileAccess.CopyOnWrite, MemoryMappedFileAccess.Read, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileAccess.ReadExecute, MemoryMappedFileAccess.ReadWriteExecute, }; foreach (MemoryMappedFileAccess access in accessList) { VerifyOpen("Loc434_" + access, "COO_mapname434", 1000, access, MemoryMappedFileOptions.None, HandleInheritability.None, MemoryMappedFileAccess.Read); } VerifyOpen("Loc434_Write", "COO_mapname434", 1000, MemoryMappedFileAccess.Write, MemoryMappedFileOptions.None, HandleInheritability.None, (MemoryMappedFileAccess)(-1)); // for current architecture, rights=Write implies ReadWrite access but not Read, so no expected access here } // [] options // Default VerifyCreate("Loc440a", "COO_mapname440a", 4096 * 1000); VerifyCreate("Loc440b", "COO_mapname440b", 4096 * 10000); // None - new file VerifyCreate("Loc441", "COO_mapname441", 4096 * 10000, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.None); // DelayAllocatePages - new file VerifyCreate("Loc442", "COO_mapname442", 4096 * 10000, MemoryMappedFileAccess.Read, MemoryMappedFileOptions.DelayAllocatePages, HandleInheritability.None); // invalid VerifyException <ArgumentOutOfRangeException>("Loc443", "COO_mapname443", 100, MemoryMappedFileAccess.ReadWrite, (MemoryMappedFileOptions)(-1), HandleInheritability.None); // ignored for existing file using (MemoryMappedFile mmf = MemoryMappedFile.CreateNew("COO_mapname444", 1000, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.None)) { VerifyOpen("Loc444", "COO_mapname444", 100, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.DelayAllocatePages, HandleInheritability.None, MemoryMappedFileAccess.ReadWrite); } // [] memoryMappedFileSecurity // null, tested throughout this file // valid non-null VerifyCreate("Loc451", "COO_mapname451", 1000, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.None); // ignored for existing using (MemoryMappedFile mmf = MemoryMappedFile.CreateOrOpen("COO_mapname452", 1000, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.None)) { VerifyOpen("Loc452", "COO_mapname452", 1000, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.None, MemoryMappedFileAccess.ReadWrite); } // [] inheritability // None - new file VerifyCreate("Loc461", "COO_mapname461", 100, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.None); // Inheritable - new file VerifyCreate("Loc462", "COO_mapname462", 100, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.Inheritable); // Mix and match: None - existing file w/Inheritable using (MemoryMappedFile mmf = MemoryMappedFile.CreateNew("COO_mapname464", 1000, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.Inheritable)) { VerifyOpen("Loc464a", "COO_mapname464", 100, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.None, MemoryMappedFileAccess.ReadWrite); } // Mix and match: Inheritable - existing file w/None using (FileStream fs = new FileStream("CreateOrOpen_test2.txt", FileMode.Open)) { using (MemoryMappedFile mmf = MemoryMappedFile.CreateFromFile(fs, "COO_mapname465", 1000, MemoryMappedFileAccess.ReadWrite, HandleInheritability.None, false)) { VerifyOpen("Loc465b", "COO_mapname465", 100, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.Inheritable, MemoryMappedFileAccess.ReadWrite); } } // invalid VerifyException <ArgumentOutOfRangeException>("Loc467", "COO_mapname467", 100, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, (HandleInheritability)(-1)); VerifyException <ArgumentOutOfRangeException>("Loc468", "COO_mapname468", 100, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, (HandleInheritability)(2)); /// END TEST CASES if (iCountErrors == 0) { return(true); } else { Console.WriteLine("FAiL! iCountErrors==" + iCountErrors); return(false); } } catch (Exception ex) { Console.WriteLine("ERR999: Unexpected exception in runTest, {0}", ex); return(false); } }
// Проверка таблицы с индексами static void Main5(string[] args) { Console.WriteLine("Start"); string path = @"..\..\..\Databases\"; string filename = path + "table.pac"; Random rnd = new Random(3333); PaCell table = new PaCell(new PTypeSequence(new PType(PTypeEnumeration.integer)), filename, false); DateTime tt0 = DateTime.Now; int nvalues = 1000000000; bool toload = false; if (toload) { table.Clear(); table.Fill(new object[0]); for (int i = 0; i < nvalues; i++) { table.Root.AppendElement(i); } table.Flush(); Console.WriteLine("Load ok. duration={0}", (DateTime.Now - tt0).Ticks / 10000L); tt0 = DateTime.Now; return; } int portion = 100000; for (int i = 0; i < portion; i++) { int ind = rnd.Next(nvalues - 1); var v = table.Root.Element(ind).Get(); } Console.WriteLine("Test1 ok. duration={0}", (DateTime.Now - tt0).Ticks / 10000L); tt0 = DateTime.Now; table.Close(); System.IO.Stream fs = new System.IO.FileStream(filename, System.IO.FileMode.Open, System.IO.FileAccess.Read); System.IO.BinaryReader br = new System.IO.BinaryReader(fs); for (int i = 0; i < portion; i++) { int ind = rnd.Next(nvalues - 1); long off = 40 + (long)ind * 4; fs.Position = off; int v = br.ReadInt32(); } fs.Close(); Console.WriteLine("Test2 ok. duration={0}", (DateTime.Now - tt0).Ticks / 10000L); tt0 = DateTime.Now; using (MemoryMappedFile mmf = MemoryMappedFile.CreateFromFile(filename)) { for (int i = 0; i < portion; i++) { int ind = rnd.Next(nvalues - 1); long off = 40 + (long)ind * 4; using (var accessor = mmf.CreateViewAccessor(off, 4)) { int v = accessor.ReadInt32(0); } } Console.WriteLine("Test3 ok. duration={0}", (DateTime.Now - tt0).Ticks / 10000L); tt0 = DateTime.Now; using (var accessor = mmf.CreateViewAccessor(0, (long)nvalues * 4 + 40)) { tt0 = DateTime.Now; for (int i = 0; i < portion; i++) { int ind = rnd.Next(nvalues - 1); long off = 40 + (long)ind * 4; //using (var accessor = mmf.CreateViewAccessor(off, 4)) //{ // int v = accessor.ReadInt32(0); //} int v = accessor.ReadInt32(off); } } } Console.WriteLine("Test4 ok. duration={0}", (DateTime.Now - tt0).Ticks / 10000L); tt0 = DateTime.Now; }
public void OnNext(string path) { string filename = Path.GetFileNameWithoutExtension(path); FileInfo fi = new FileInfo(path); Mutex m = new Mutex(false, "m" + filename); filename += Convert.ToString(objects.Count); MemoryMappedFile mappedFile = null; m.WaitOne(); try { mappedFile = MemoryMappedFile.CreateFromFile(path, FileMode.Open, filename, 0); } catch (IOException) { return; } MemoryMappedViewAccessor accessor = mappedFile.CreateViewAccessor(); uint offsetPE = accessor.ReadUInt32(60); // Считываем сдвиг заголовка PE AVScanObject obj = null; // Проверяем размер файла if (offsetPE <= accessor.Capacity) { byte[] peSignature = new byte[4]; accessor.ReadArray(offsetPE, peSignature, 0, 4); // Считываем сигнатуру if (Encoding.ASCII.GetString(peSignature) == "PE\0\0") // Для PE-файла должно быть равно PE\0\0 { ushort magic = accessor.ReadUInt16(offsetPE + 24); // Считываем поле magic определяющее вид PE-заголовка uint peHeaderSize = 0; if (magic == 267) { peHeaderSize = 248; // Для PE32 } else { peHeaderSize = 264; // Для PE32+ } uint sectionsNum = accessor.ReadUInt16(offsetPE + 6); // Считываем количество секций uint pFirstSection = offsetPE + peHeaderSize; for (uint i = 0; i < sectionsNum; i++) { uint pCurSection = pFirstSection + i * 40; uint characteristic = accessor.ReadUInt32(pCurSection + 36); uint executeFlag = 0x20000000; // Проверяем содержимое поля характеристики // Eсли сегмент исполняемый, то создаем AVScanObject с этим сегментом if ((characteristic & executeFlag) == executeFlag) { uint pDataStart = accessor.ReadUInt32(pCurSection + 20); uint pDataLength = accessor.ReadUInt32(pCurSection + 16); MemoryMappedViewAccessor sectionAccessor = mappedFile.CreateViewAccessor(pDataStart, pDataLength, MemoryMappedFileAccess.Read); obj = new AVScanObject(sectionAccessor, mappedFile, path); } } } } m.ReleaseMutex(); // По окончанию проверки файла, добавляем в список obj, который, если файл не исполняемый равен null objects.Add(obj); foreach (IObserver <AVScanObject> observer in observers) // И оповещаем всех слушателей { observer.OnNext(obj); } }
public static void write_file_MMF <T>(T[] data, string path_folder, string file_name) { if (!path_folder.Contains(':')) { path_folder = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) + @"\" + path_folder; } if (!Directory.Exists(path_folder)) { Directory.CreateDirectory(path_folder); } MemoryMappedFileSecurity mSec = new MemoryMappedFileSecurity(); mSec.AddAccessRule(new AccessRule <MemoryMappedFileRights>(new SecurityIdentifier(WellKnownSidType.WorldSid, null), MemoryMappedFileRights.FullControl, AccessControlType.Allow)); string file = path_folder + @"\" + file_name + ".mmf"; file = file.Replace("\\\\", "\\"); Task.Factory.StartNew((object obj) => { Tuple <string, T[]> rs = (obj as Tuple <string, T[]>); string v_file = rs.Item1; T[] v_data = rs.Item2; int buffer_size = 0; try { using (MemoryStream stream = new MemoryStream()) { BinaryFormatter bf = new BinaryFormatter(); bf.Serialize(stream, v_data); byte[] bw = stream.ToArray(); buffer_size = bw.Length; long file_size = 0; if (File.Exists(v_file)) { FileInfo fi = new FileInfo(v_file); file_size = fi.Length; } long capacity = buffer_size; if (capacity < file_size) { capacity = file_size; } using (MemoryMappedFile w = MemoryMappedFile.CreateFromFile(v_file, FileMode.OpenOrCreate, null, capacity)) { using (MemoryMappedViewAccessor mmfWriter = w.CreateViewAccessor(0, capacity)) { mmfWriter.WriteArray <byte>(0, bw, 0, buffer_size); } } } } catch (Exception ex) { string msg = ex.Message; } }, new Tuple <string, T[]>(file, data)); }//end function
public void InvalidArguments_Inheritability(HandleInheritability inheritability) { // Out of range values for inheritability using (TempFile file = new TempFile(GetTestFilePath())) using (FileStream fs = File.Open(file.Path, FileMode.Open)) { Assert.Throws <ArgumentOutOfRangeException>("inheritability", () => MemoryMappedFile.CreateFromFile(fs, CreateUniqueMapName(), 4096, MemoryMappedFileAccess.ReadWrite, inheritability, true)); } }
public static void DoPass(RewriteGlobalContext context, UnhollowerOptions options) { if (string.IsNullOrEmpty(options.GameAssemblyPath)) { Pass15GenerateMemberContexts.HasObfuscatedMethods = false; return; } if (!Pass15GenerateMemberContexts.HasObfuscatedMethods) { return; } var methodToCallersMap = new ConcurrentDictionary <long, List <XrefInstance> >(); var methodToCalleesMap = new ConcurrentDictionary <long, List <long> >(); using var mappedFile = MemoryMappedFile.CreateFromFile(options.GameAssemblyPath, FileMode.Open, null, 0, MemoryMappedFileAccess.Read); using var accessor = mappedFile.CreateViewAccessor(0, 0, MemoryMappedFileAccess.Read); IntPtr gameAssemblyPtr; unsafe { byte *fileStartPtr = null; accessor.SafeMemoryMappedViewHandle.AcquirePointer(ref fileStartPtr); gameAssemblyPtr = (IntPtr)fileStartPtr; } context.MethodStartAddresses.Sort(); // Scan xrefs context.Assemblies.SelectMany(it => it.Types).SelectMany(it => it.Methods).AsParallel().ForAll( originalTypeMethod => { var address = originalTypeMethod.FileOffset; if (address == 0) { return; } if (!options.NoXrefCache) { var pair = XrefScanMetadataGenerationUtil.FindMetadataInitForMethod(originalTypeMethod, (long)gameAssemblyPtr); originalTypeMethod.MetadataInitFlagRva = pair.FlagRva; originalTypeMethod.MetadataInitTokenRva = pair.TokenRva; } var nextMethodStart = context.MethodStartAddresses.BinarySearch(address + 1); if (nextMethodStart < 0) { nextMethodStart = ~nextMethodStart; } var length = nextMethodStart >= context.MethodStartAddresses.Count ? 1024 * 1024 : (context.MethodStartAddresses[nextMethodStart] - address); foreach (var callTargetGlobal in XrefScanner.XrefScanImpl(XrefScanner.DecoderForAddress(IntPtr.Add(gameAssemblyPtr, (int)address), (int)length), true)) { var callTarget = callTargetGlobal.RelativeToBase((long)gameAssemblyPtr + originalTypeMethod.FileOffset - originalTypeMethod.Rva); if (callTarget.Type == XrefType.Method) { var targetRelative = (long)callTarget.Pointer; methodToCallersMap.GetOrAdd(targetRelative, _ => new List <XrefInstance>()).AddLocked(new XrefInstance(XrefType.Method, (IntPtr)originalTypeMethod.Rva, callTarget.FoundAt)); methodToCalleesMap.GetOrAdd(originalTypeMethod.Rva, _ => new List <long>()).AddLocked(targetRelative); } if (!options.NoXrefCache) { originalTypeMethod.XrefScanResults.Add(callTarget); } } }); MapOfCallers = methodToCallersMap; void MarkMethodAlive(long address) { if (!NonDeadMethods.Add(address)) { return; } if (!methodToCalleesMap.TryGetValue(address, out var calleeList)) { return; } foreach (var callee in calleeList) { MarkMethodAlive(callee); } } // Now decided which of them are possible dead code foreach (var assemblyRewriteContext in context.Assemblies) { foreach (var typeRewriteContext in assemblyRewriteContext.Types) { foreach (var methodRewriteContext in typeRewriteContext.Methods) { if (methodRewriteContext.FileOffset == 0) { continue; } var originalMethod = methodRewriteContext.OriginalMethod; if (!originalMethod.Name.IsObfuscated(options) || originalMethod.IsVirtual) { MarkMethodAlive(methodRewriteContext.Rva); } } } } }
public static void write_MMF <T>(T item, string path_folder, string file_name) where T : struct { if (!path_folder.Contains(':')) { path_folder = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) + @"\" + path_folder; } if (!Directory.Exists(path_folder)) { Directory.CreateDirectory(path_folder); } MemoryMappedFileSecurity mSec = new MemoryMappedFileSecurity(); mSec.AddAccessRule(new AccessRule <MemoryMappedFileRights>(new SecurityIdentifier(WellKnownSidType.WorldSid, null), MemoryMappedFileRights.FullControl, AccessControlType.Allow)); string filePath = path_folder + @"\" + file_name + ".mmf"; filePath = filePath.Replace("\\\\", "\\"); int buffer_size = 0; try { using (MemoryStream stream = new MemoryStream()) { int objsize = Marshal.SizeOf(typeof(T)); byte[] bw = new byte[objsize]; IntPtr buff = Marshal.AllocHGlobal(objsize); Marshal.StructureToPtr(item, buff, true); Marshal.Copy(buff, bw, 0, objsize); Marshal.FreeHGlobal(buff); buffer_size = bw.Length; long file_size = 0; if (File.Exists(filePath)) { FileInfo fi = new FileInfo(filePath); file_size = fi.Length; } long capacity = buffer_size; if (capacity < file_size) { capacity = file_size; } using (MemoryMappedFile w = MemoryMappedFile.CreateFromFile(filePath, FileMode.OpenOrCreate, null, capacity)) { using (MemoryMappedViewAccessor mmfWriter = w.CreateViewAccessor(0, capacity)) { mmfWriter.WriteArray <byte>(0, bw, 0, buffer_size); } } } } catch (Exception ex) { string msg = ex.Message; } }//end function
public LogFile MMFConcurrentRead(LogFile logFile, BackgroundWorker backgroundWorker) { Debug.Print("MMFConcurrentRead: enter"); GetEncoding(logFile); // not sure why this here. messing up temp file //logFile.IsNew = false; //logFile.Modified = false; if (!File.Exists(logFile.Tag)) { Debug.Print("MMFConcurrentRead:error, file does not exist: " + logFile.Tag); return(logFile); } byte[] bytes = new byte[new FileInfo(logFile.Tag).Length]; // 4,8,12 int threadCount = 1; if (bytes.Length > 1000000) { threadCount = 8; } int bposition = logFile.HasBom ? logFile.Encoding.GetPreamble().Length : 0; int blen = bytes.Length / threadCount; MemoryMappedFile memoryMappedFile = MemoryMappedFile.CreateFromFile(logFile.Tag, FileMode.Open, "mmf", bytes.Length, MemoryMappedFileAccess.Read); ManualResetEvent[] completedEvents = new ManualResetEvent[threadCount]; List <List <LogFileItem> > list = new List <List <LogFileItem> >(); for (int i = 0; i < threadCount; i++) { list.Add(new List <LogFileItem>()); completedEvents[i] = new ManualResetEvent(false); } for (int mmfCount = 0; mmfCount < threadCount; mmfCount++) { if (mmfCount != 0) { bposition += blen; } if (mmfCount == threadCount - 1) { blen = bytes.Length - bposition; } TaskMMFInfo taskInfo = new TaskMMFInfo() { mmf = memoryMappedFile, stringList = list[mmfCount], logFile = logFile, position = bposition, length = blen, completedEvent = completedEvents[mmfCount], bgWorker = backgroundWorker }; ThreadPool.QueueUserWorkItem(new WaitCallback(ParallelMMFRead), taskInfo); } Debug.Print(string.Format("mmf thread length: {0}", blen)); WaitHandle.WaitAll(completedEvents); if (memoryMappedFile != null) { memoryMappedFile.Dispose(); } if (backgroundWorker.CancellationPending) { Debug.Print("MMFConcurrentRead:cancelled"); return(logFile); } bool patch = false; List <LogFileItem> finalList = new List <LogFileItem>(); for (int listCount = 0; listCount < threadCount; listCount++) { if (patch) { // merge last line with first line in current list finalList[finalList.Count - 1].Content = finalList[finalList.Count - 1].Content + list[listCount][0].Content; list[listCount].RemoveAt(0); patch = false; } finalList.AddRange(list[listCount]); list[listCount].Clear(); // need to check for partial lines look in last index for needsPatch string if (finalList.Count > 0) { if (finalList[finalList.Count - 1].Content == _needsPatch) { finalList.RemoveAt(finalList.Count - 1); patch = true; } else { patch = false; } } } // set index int counter = 1; foreach (LogFileItem item in finalList) { item.Index = counter++; } Debug.Print("MMFConcurrentRead:exit"); logFile.ContentItems = new ObservableCollection <LogFileItem>(finalList); return(logFile); }
private MemoryMappedFile GetMemoryMappedFile() { return(MemoryMappedFile.CreateFromFile(this.updatedIndexPath, FileMode.Open)); }
public void Extract(Stream output) { using (var file = MemoryMappedFile.CreateFromFile(this.ParentFile, FileMode.Open)) { using (var viewstream = file.CreateViewStream((Offset * 4096) + 9, ZSize, MemoryMappedFileAccess.Read)) { uint fmt = 0; if (Dxt == 7) { fmt = 1; } else if (Dxt == 8) { fmt = 4; } else if (Dxt == 10) { fmt = 4; } else if (Dxt == 13) { fmt = 3; } else if (Dxt == 14) { fmt = 6; } else if (Dxt == 15) { fmt = 4; } else if (Dxt == 253) { fmt = 0; } else if (Dxt == 0) { fmt = 0; } else { throw new Exception("Invalid image!"); } var cubemap = (Type == 3 || Type == 0) && (Typeinfo == 6); uint depth = 0; if (Typeinfo > 1 && Type == 4) { depth = Typeinfo; } if (Type == 3 && Dxt == 253) { Bpp = 32; } var header = new DDSHeader().generate(Width, Height, 1, fmt, Bpp, cubemap, depth) .Concat(new[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 }).ToArray(); output.Write(header, 0, header.Length); if (!(Typeinfo == 6 && (Dxt == 253 || Dxt == 0))) { var zlib = new ZlibStream(viewstream, CompressionMode.Decompress); zlib.CopyTo(output); } } } }
public void Test_Flush() { MemoryMappedViewByteBuffer mmbRead; // buffer was not mapped in read/write mode using (FileStream fileInputStream = new FileStream(tmpFile.FullName, FileMode.Open, FileAccess.Read)) { using (var fileChannelRead = MemoryMappedFile.CreateFromFile(fileInputStream, null, 0, MemoryMappedFileAccess.Read, #if FEATURE_MEMORYMAPPEDFILESECURITY null, #endif HandleInheritability.None, true)) { //FileChannel fileChannelRead = fileInputStream.getChannel(); //MappedByteBuffer mmbRead = fileChannelRead.map(MapMode.READ_ONLY, 0, // fileChannelRead.size()); mmbRead = fileChannelRead.CreateViewByteBuffer(0, (int)fileInputStream.Length, MemoryMappedFileAccess.Read); mmbRead.Flush(); } //using (FileStream inputStream = new FileStream(tmpFile.FullName, FileMode.Open, FileAccess.Read)) using (var fileChannelR = MemoryMappedFile.CreateFromFile(fileInputStream, null, 0, MemoryMappedFileAccess.Read, #if FEATURE_MEMORYMAPPEDFILESECURITY null, #endif HandleInheritability.None, false)) { //FileInputStream inputStream = new FileInputStream(tmpFile); //FileChannel fileChannelR = inputStream.getChannel(); //MappedByteBuffer resultRead = fileChannelR.map(MapMode.READ_ONLY, 0, // fileChannelR.size()); MemoryMappedViewByteBuffer resultRead = fileChannelR.CreateViewByteBuffer(0, (int)fileInputStream.Length, MemoryMappedFileAccess.Read); //If this buffer was not mapped in read/write mode, then invoking this method has no effect. assertEquals( "Invoking force() should have no effect when this buffer was not mapped in read/write mode", mmbRead, resultRead); } } MemoryMappedViewByteBuffer mmbReadWrite; // Buffer was mapped in read/write mode using (FileStream randomFile = new FileStream(tmpFile.FullName, FileMode.Open, FileAccess.ReadWrite)) { using (var fileChannelReadWrite = MemoryMappedFile.CreateFromFile(randomFile, null, 0, MemoryMappedFileAccess.ReadWrite, #if FEATURE_MEMORYMAPPEDFILESECURITY null, #endif HandleInheritability.None, true)) { //RandomAccessFile randomFile = new RandomAccessFile(tmpFile, "rw"); //FileChannel fileChannelReadWrite = randomFile.getChannel(); //MappedByteBuffer mmbReadWrite = fileChannelReadWrite.map( // FileChannel.MapMode.READ_WRITE, 0, fileChannelReadWrite.size()); mmbReadWrite = fileChannelReadWrite.CreateViewByteBuffer(0, (int)randomFile.Length, MemoryMappedFileAccess.ReadWrite); mmbReadWrite.Put((byte)'o'); mmbReadWrite.Flush(); } //using (FileStream random = new FileStream(tmpFile.FullName, FileMode.Open, FileAccess.ReadWrite)) using (var fileChannelRW = MemoryMappedFile.CreateFromFile(randomFile, null, 0, MemoryMappedFileAccess.ReadWrite, #if FEATURE_MEMORYMAPPEDFILESECURITY null, #endif HandleInheritability.None, false)) { //RandomAccessFile random = new RandomAccessFile(tmpFile, "rw"); //FileChannel fileChannelRW = random.getChannel(); //MappedByteBuffer resultReadWrite = fileChannelRW.map( // FileChannel.MapMode.READ_WRITE, 0, fileChannelRW.size()); MemoryMappedViewByteBuffer resultReadWrite = fileChannelRW.CreateViewByteBuffer(0, (int)randomFile.Length, MemoryMappedFileAccess.ReadWrite); // Invoking force() will change the buffer assertFalse(mmbReadWrite.Equals(resultReadWrite)); } } //fileChannelRead.close(); //fileChannelR.close(); //fileChannelReadWrite.close(); //fileChannelRW.close(); //} }
public void InvalidArguments_FileStream() { // null is an invalid stream Assert.Throws <ArgumentNullException>("fileStream", () => MemoryMappedFile.CreateFromFile(null, CreateUniqueMapName(), 4096, MemoryMappedFileAccess.Read, HandleInheritability.None, true)); }
public void TestBasic() { byte[] srcData = new byte[20]; for (int i = 0; i < 20; i++) { srcData[i] = 3; } //File blah = File.createTempFile("blah", null); //blah.deleteOnExit(); var blah = new FileInfo(Path.GetTempFileName()); using (FileStream fos = new FileStream(blah.FullName, FileMode.Open, FileAccess.ReadWrite)) { //FileChannel fc = fos.getChannel(); //fc.write(ByteBuffer.wrap(srcData)); //fc.close(); fos.Write(ByteBuffer.Wrap(srcData)); } MemoryMappedViewByteBuffer mbb; using (FileStream fis = new FileStream(blah.FullName, FileMode.Open, FileAccess.Read)) using (var fc = MemoryMappedFile.CreateFromFile(fis, null, 0, MemoryMappedFileAccess.Read, #if FEATURE_MEMORYMAPPEDFILESECURITY null, #endif HandleInheritability.None, false)) { //fc = fis.getChannel(); //MappedByteBuffer mbb = fc.map(FileChannel.MapMode.READ_ONLY, 0, 10); mbb = fc.CreateViewByteBuffer(0, 10, MemoryMappedFileAccess.Read); //mbb.load(); //mbb.isLoaded(); mbb.Flush(); assertTrue("Incorrect isReadOnly", mbb.IsReadOnly); // repeat with unaligned position in file //mbb = fc.map(FileChannel.MapMode.READ_ONLY, 1, 10); mbb = fc.CreateViewByteBuffer(0, 10, MemoryMappedFileAccess.Read); //mbb.load(); //mbb.isLoaded(); mbb.Flush(); } using (FileStream raf = new FileStream(blah.FullName, FileMode.Open, FileAccess.Read)) using (var fc = MemoryMappedFile.CreateFromFile(raf, null, 0, MemoryMappedFileAccess.Read, #if FEATURE_MEMORYMAPPEDFILESECURITY null, #endif HandleInheritability.None, false)) { //RandomAccessFile raf = new RandomAccessFile(blah, "r"); //fc = raf.getChannel(); //mbb = fc.map(FileChannel.MapMode.READ_ONLY, 0, 10); mbb = fc.CreateViewByteBuffer(0, 10, MemoryMappedFileAccess.Read); assertTrue("Incorrect isReadOnly", mbb.IsReadOnly); } using (FileStream raf = new FileStream(blah.FullName, FileMode.Open, FileAccess.ReadWrite)) using (var fc = MemoryMappedFile.CreateFromFile(raf, null, 0, MemoryMappedFileAccess.ReadWrite, #if FEATURE_MEMORYMAPPEDFILESECURITY null, #endif HandleInheritability.None, false)) { //raf = new RandomAccessFile(blah, "rw"); //fc = raf.getChannel(); //mbb = fc.map(FileChannel.MapMode.READ_WRITE, 0, 10); assertTrue("Incorrect isReadOnly", mbb.IsReadOnly); } // clean-up mbb = null; //System.gc(); GC.Collect(); Thread.Sleep(500); DeleteFile(blah); }
private MemoryMappedFile Open(long size = 0) { return(MemoryMappedFile.CreateFromFile(path, FileMode.OpenOrCreate, Guid.NewGuid().ToString(), size)); }
private static IEnumerable <ReadTestResult> Read_Archive_Items(IEnumerable <FileEntry> files) { var results = new ConcurrentBag <ReadTestResult>(); var filesGroups = files.Select((f, i) => new { Value = f, Index = i }) .GroupBy(item => item.Value.Archive.ArchiveAbsolutePath); foreach (var fileGroup in filesGroups) { var fileList = fileGroup.ToList(); var ar = s_bm.Archives.Lookup(fileGroup.Key).Value as Archive; using var fs = new FileStream(fileGroup.Key, FileMode.Open, FileAccess.Read, FileShare.Read); using var mmf = MemoryMappedFile.CreateFromFile(fs, null, 0, MemoryMappedFileAccess.Read, HandleInheritability.None, false); #if IS_PARALLEL Parallel.ForEach(fileList, tmpFile => #else foreach (var tmpFile in fileList) #endif { var file = tmpFile.Value; try { using var ms = new MemoryStream(); ar?.CopyFileToStream(ms, file.NameHash64, false, mmf); ms.Seek(0, SeekOrigin.Begin); using var reader = new CR2WReader(ms); var readResult = reader.ReadFile(out var c, DECOMPRESS_BUFFERS); switch (readResult) { case RED4.Archive.IO.EFileReadErrorCodes.NoCr2w: results.Add(new ReadTestResult { FileEntry = file, Success = true, ReadResult = ReadTestResult.ReadResultType.NoCr2W }); break; case RED4.Archive.IO.EFileReadErrorCodes.UnsupportedVersion: results.Add(new ReadTestResult { FileEntry = file, Success = false, ReadResult = ReadTestResult.ReadResultType.UnsupportedVersion, Message = $"Unsupported Version ({c.MetaData.Version})" }); break; case RED4.Archive.IO.EFileReadErrorCodes.NoError: c.MetaData.FileName = file.NameOrHash; var res = ReadTestResult.ReadResultType.NoError; var msg = ""; var additionalCr2WFileBytes = (int)(reader.BaseStream.Length - reader.BaseStream.Position); if (additionalCr2WFileBytes > 0) { res |= ReadTestResult.ReadResultType.HasAdditionalBytes; msg += $"Additional Bytes: {additionalCr2WFileBytes}"; } results.Add(new ReadTestResult { FileEntry = file, Success = true /*!hasAdditionalBytes && !hasUnknownBytes*/, ReadResult = res, Message = msg, AdditionalBytes = additionalCr2WFileBytes }); break; default: throw new Exception(); } } catch (Exception e) { results.Add(new ReadTestResult { FileEntry = file, Success = false, ReadResult = ReadTestResult.ReadResultType.RuntimeException, ExceptionType = e.GetType(), Message = $"{e.Message}" }); } #if IS_PARALLEL });
public void StreamAccessReadWriteMemoryMappedProjectedFile() { string filename = @"Test_EPF_WorkingDirectoryTests\StreamAccessReadWriteMemoryMappedProjectedFile.cs"; string fileVirtualPath = this.Enlistment.GetVirtualPathTo(filename); string contents = fileVirtualPath.ShouldBeAFile(this.fileSystem).WithContents(); StringBuilder contentsBuilder = new StringBuilder(contents); using (MemoryMappedFile mmf = MemoryMappedFile.CreateFromFile(fileVirtualPath)) { // Length of the Byte-order-mark that will be at the start of the memory mapped file. // See https://msdn.microsoft.com/en-us/library/windows/desktop/dd374101(v=vs.85).aspx int bomOffset = 3; // offset -> Number of bytes from the start of the file where the view starts int offset = 64; int size = contents.Length; string newContent = "**NEWCONTENT**"; using (MemoryMappedViewStream streamAccessor = mmf.CreateViewStream(offset, size - offset + bomOffset)) { streamAccessor.CanRead.ShouldEqual(true); streamAccessor.CanWrite.ShouldEqual(true); for (int i = offset; i < size - offset; ++i) { streamAccessor.ReadByte().ShouldEqual(contents[i - bomOffset]); } // Reset to the start of the stream (which will place the streamAccessor at offset in the memory file) streamAccessor.Seek(0, SeekOrigin.Begin); byte[] newContentBuffer = Encoding.ASCII.GetBytes(newContent); streamAccessor.Write(newContentBuffer, 0, newContent.Length); for (int i = 0; i < newContent.Length; ++i) { contentsBuilder[offset + i - bomOffset] = newContent[i]; } contents = contentsBuilder.ToString(); } // Verify the file has the new contents inserted into it using (MemoryMappedViewStream streamAccessor = mmf.CreateViewStream(offset: 0, size: size + bomOffset)) { // Skip the BOM for (int i = 0; i < bomOffset; ++i) { streamAccessor.ReadByte(); } for (int i = 0; i < size; ++i) { streamAccessor.ReadByte().ShouldEqual(contents[i]); } } } // Confirm the new contents was written to disk fileVirtualPath.ShouldBeAFile(this.fileSystem).WithContents(contents); }
public void OpenMMF() { PSTMMF = MemoryMappedFile.CreateFromFile(Path, FileMode.Open); }
public DecompressFileManager(string file, long size) { _file = file; _mmf = MemoryMappedFile.CreateFromFile(file, FileMode.OpenOrCreate, "map", size); }
public MemoryMappedFileSlim(string fileNamePath, long fileLength) : this(MemoryMappedFile.CreateFromFile(fileNamePath, FileMode.OpenOrCreate, mapName : null, capacity : fileLength), fileNamePath) { }
void EncryptedFileCopy(FileStream file, Xp3Entry xp3entry, Stream output, bool compress) { if (file.Length > int.MaxValue) { throw new FileSizeException(); } using (var map = MemoryMappedFile.CreateFromFile(file, null, 0, MemoryMappedFileAccess.Read, null, HandleInheritability.None, true)) { uint unpacked_size = (uint)file.Length; xp3entry.UnpackedSize = (uint)unpacked_size; xp3entry.Size = (uint)unpacked_size; using (var view = map.CreateViewAccessor(0, unpacked_size, MemoryMappedFileAccess.Read)) { var segment = new Xp3Segment { IsCompressed = compress, Offset = output.Position, Size = unpacked_size, PackedSize = unpacked_size, }; if (compress) { output = new ZLibStream(output, CompressionMode.Compress, CompressionLevel.Level9, true); } unsafe { byte[] read_buffer = new byte[81920]; byte * ptr = view.GetPointer(0); try { var checksum = new Adler32(); bool hash_after_crypt = xp3entry.Cipher.HashAfterCrypt; if (!hash_after_crypt) { xp3entry.Hash = checksum.Update(ptr, (int)unpacked_size); } int offset = 0; int remaining = (int)unpacked_size; while (remaining > 0) { int amount = Math.Min(remaining, read_buffer.Length); remaining -= amount; Marshal.Copy((IntPtr)(ptr + offset), read_buffer, 0, amount); xp3entry.Cipher.Encrypt(xp3entry, offset, read_buffer, 0, amount); if (hash_after_crypt) { checksum.Update(read_buffer, 0, amount); } output.Write(read_buffer, 0, amount); offset += amount; } if (hash_after_crypt) { xp3entry.Hash = checksum.Value; } } finally { view.SafeMemoryMappedViewHandle.ReleasePointer(); if (compress) { var dest = (output as ZLibStream).BaseStream; output.Dispose(); segment.PackedSize = (uint)(dest.Position - segment.Offset); xp3entry.Size = segment.PackedSize; } xp3entry.Segments.Add(segment); } } } } }
public void StreamAndRandomAccessReadWriteMemoryMappedProjectedFile() { string fileVirtualPath = this.Enlistment.GetVirtualPathTo("Test_EPF_WorkingDirectoryTests", "StreamAndRandomAccessReadWriteMemoryMappedProjectedFile.cs"); StringBuilder contentsBuilder = new StringBuilder(); // Length of the Byte-order-mark that will be at the start of the memory mapped file. // See https://msdn.microsoft.com/en-us/library/windows/desktop/dd374101(v=vs.85).aspx int bomOffset = 3; using (MemoryMappedFile mmf = MemoryMappedFile.CreateFromFile(fileVirtualPath)) { // The text length of StreamAndRandomAccessReadWriteMemoryMappedProjectedFile.cs was determined // outside of this test so that the test would not hydrate the file before we access via MemoryMappedFile int fileTextLength = 13762; int size = bomOffset + fileTextLength; int streamAccessWriteOffset = 64; int randomAccessWriteOffset = 128; string newStreamAccessContent = "**NEW_STREAM_CONTENT**"; string newRandomAccessConents = "&&NEW_RANDOM_CONTENT&&"; // Read (and modify) contents using stream accessor using (MemoryMappedViewStream streamAccessor = mmf.CreateViewStream(offset: 0, size: size)) { streamAccessor.CanRead.ShouldEqual(true); streamAccessor.CanWrite.ShouldEqual(true); for (int i = 0; i < size; ++i) { contentsBuilder.Append((char)streamAccessor.ReadByte()); } // Reset to the start of the stream (which will place the streamAccessor at offset in the memory file) streamAccessor.Seek(streamAccessWriteOffset, SeekOrigin.Begin); byte[] newContentBuffer = Encoding.ASCII.GetBytes(newStreamAccessContent); streamAccessor.Write(newContentBuffer, 0, newStreamAccessContent.Length); for (int i = 0; i < newStreamAccessContent.Length; ++i) { contentsBuilder[streamAccessWriteOffset + i] = newStreamAccessContent[i]; } } // Read (and modify) contents using random accessor using (MemoryMappedViewAccessor randomAccessor = mmf.CreateViewAccessor(offset: 0, size: size)) { randomAccessor.CanRead.ShouldEqual(true); randomAccessor.CanWrite.ShouldEqual(true); // Confirm the random accessor reads the same content that was read (and written) by the stream // accessor for (int i = 0; i < size; ++i) { ((char)randomAccessor.ReadByte(i)).ShouldEqual(contentsBuilder[i]); } // Write some new content for (int i = 0; i < newRandomAccessConents.Length; ++i) { // Convert to byte before writing rather than writing as char, because char version will write a 16-bit // unicode char randomAccessor.Write(i + randomAccessWriteOffset, Convert.ToByte(newRandomAccessConents[i])); ((char)randomAccessor.ReadByte(i + randomAccessWriteOffset)).ShouldEqual(newRandomAccessConents[i]); } for (int i = 0; i < newRandomAccessConents.Length; ++i) { contentsBuilder[randomAccessWriteOffset + i] = newRandomAccessConents[i]; } } // Verify the file one more time with a stream accessor using (MemoryMappedViewStream streamAccessor = mmf.CreateViewStream(offset: 0, size: size)) { for (int i = 0; i < size; ++i) { streamAccessor.ReadByte().ShouldEqual(contentsBuilder[i]); } } } // Remove the BOM before comparing with the contents of the file on disk contentsBuilder.Remove(0, bomOffset); // Confirm the new contents was written to the file fileVirtualPath.ShouldBeAFile(this.fileSystem).WithContents(contentsBuilder.ToString()); }
/// <summary> /// This Method is a utility to remove the code-signature (if any) /// from a MachO AppHost binary. /// /// The tool assumes the following layout of the executable: /// /// * MachoHeader (64-bit, executable, not swapped integers) /// * LoadCommands /// LC_SEGMENT_64 (__PAGEZERO) /// LC_SEGMENT_64 (__TEXT) /// LC_SEGMENT_64 (__DATA) /// LC_SEGMENT_64 (__LINKEDIT) /// ... /// LC_SYMTAB /// ... /// LC_CODE_SIGNATURE (last) /// /// * ... Different Segments ... /// /// * The __LINKEDIT Segment (last) /// * ... Different sections ... /// * SYMTAB /// * (Some alignment bytes) /// * The Code-signature /// /// In order to remove the signature, the method: /// - Removes (zeros out) the LC_CODE_SIGNATURE command /// - Adjusts the size and count of the load commands in the header /// - Truncates the size of the __LINKEDIT segment to the end of SYMTAB /// - Truncates the apphost file to the end of the __LINKEDIT segment /// /// </summary> /// <param name="stream">Stream containing the AppHost</param> /// <returns> /// True if /// - The input is a MachO binary, and /// - It is a signed binary, and /// - The signature was successfully removed /// False otherwise /// </returns> /// <exception cref="AppHostMachOFormatException"> /// The input is a MachO file, but doesn't match the expect format of the AppHost. /// </exception> public static unsafe bool RemoveSignature(FileStream stream) { uint signatureSize = 0; using (var mappedFile = MemoryMappedFile.CreateFromFile(stream, mapName: null, capacity: 0, MemoryMappedFileAccess.ReadWrite, HandleInheritability.None, leaveOpen: true)) { using (var accessor = mappedFile.CreateViewAccessor()) { byte *file = null; try { accessor.SafeMemoryMappedViewHandle.AcquirePointer(ref file); Verify(file != null, MachOFormatError.MemoryMapAccessFault); MachHeader *header = (MachHeader *)file; if (!header->IsValid()) { // Not a MachO file. return(false); } Verify(header->Is64BitExecutable(), MachOFormatError.Not64BitExe); file += sizeof(MachHeader); SegmentCommand64 * linkEdit = null; SymtabCommand * symtab = null; LinkEditDataCommand *signature = null; for (uint i = 0; i < header->ncmds; i++) { LoadCommand *command = (LoadCommand *)file; if (command->cmd == Command.LC_SEGMENT_64) { SegmentCommand64 *segment = (SegmentCommand64 *)file; if (segment->SegName.Equals("__LINKEDIT")) { Verify(linkEdit == null, MachOFormatError.DuplicateLinkEdit); linkEdit = segment; } } else if (command->cmd == Command.LC_SYMTAB) { Verify(symtab == null, MachOFormatError.DuplicateSymtab); symtab = (SymtabCommand *)command; } else if (command->cmd == Command.LC_CODE_SIGNATURE) { Verify(i == header->ncmds - 1, MachOFormatError.SignCommandNotLast); signature = (LinkEditDataCommand *)command; break; } file += command->cmdsize; } if (signature != null) { Verify(linkEdit != null, MachOFormatError.MissingLinkEdit); Verify(symtab != null, MachOFormatError.MissingSymtab); var symtabEnd = symtab->stroff + symtab->strsize; var linkEditEnd = linkEdit->fileoff + linkEdit->filesize; var signatureEnd = signature->dataoff + signature->datasize; var fileEnd = (ulong)stream.Length; Verify(linkEditEnd == fileEnd, MachOFormatError.LinkEditNotLast); Verify(signatureEnd == fileEnd, MachOFormatError.SignBlobNotLast); Verify(symtab->symoff > linkEdit->fileoff, MachOFormatError.SymtabNotInLinkEdit); Verify(signature->dataoff > linkEdit->fileoff, MachOFormatError.SignNotInLinkEdit); // The signature blob immediately follows the symtab blob, // except for a few bytes of padding. Verify(signature->dataoff >= symtabEnd && signature->dataoff - symtabEnd < 32, MachOFormatError.SignBlobNotLast); // Remove the signature command header->ncmds--; header->sizeofcmds -= signature->cmdsize; Unsafe.InitBlock(signature, 0, signature->cmdsize); // Remove the signature blob (note for truncation) signatureSize = (uint)(fileEnd - symtabEnd); // Adjust the __LINKEDIT segment load command linkEdit->filesize -= signatureSize; // codesign --remove-signature doesn't reset the vmsize. // Setting the vmsize here makes the output bin-equal with the original // unsigned apphost (and not bin-equal with a signed-unsigned-apphost). linkEdit->vmsize = linkEdit->filesize; } } finally { if (file != null) { accessor.SafeMemoryMappedViewHandle.ReleasePointer(); } } } } if (signatureSize != 0) { // The signature was removed, update the file length stream.SetLength(stream.Length - signatureSize); return(true); } return(false); }
private static MemoryMappedFile CreateFromFile(System.IO.FileStream fileStream, string mapName, long capacity, System.IO.MemoryMappedFiles.MemoryMappedFileAccess access, System.IO.HandleInheritability inheritability, bool leaveOpen) { return(MemoryMappedFile.CreateFromFile(fileStream, mapName, capacity, access, inheritability, leaveOpen)); }
/// <summary> /// This Method is a utility to adjust the apphost MachO-header /// to include the bytes added by the single-file bundler at the end of the file. /// /// The tool assumes the following layout of the executable /// /// * MachoHeader (64-bit, executable, not swapped integers) /// * LoadCommands /// LC_SEGMENT_64 (__PAGEZERO) /// LC_SEGMENT_64 (__TEXT) /// LC_SEGMENT_64 (__DATA) /// LC_SEGMENT_64 (__LINKEDIT) /// ... /// LC_SYMTAB /// /// * ... Different Segments /// /// * The __LINKEDIT Segment (last) /// * ... Different sections ... /// * SYMTAB (last) /// /// The MAC codesign tool places several restrictions on the layout /// * The __LINKEDIT segment must be the last one /// * The __LINKEDIT segment must cover the end of the file /// * All bytes in the __LINKEDIT segment are used by other linkage commands /// (ex: symbol/string table, dynamic load information etc) /// /// In order to circumvent these restrictions, we: /// * Extend the __LINKEDIT segment to include the bundle-data /// * Extend the string table to include all the bundle-data /// (that is, the bundle-data appear as strings to the loader/codesign tool). /// /// This method has certain limitations: /// * The bytes for the bundler may be unnecessarily loaded at startup /// * Tools that process the string table may be confused (?) /// * The string table size is limited to 4GB. Bundles larger than that size /// cannot be accommodated by this utility. /// /// </summary> /// <param name="filePath">Path to the AppHost</param> /// <returns> /// True if /// - The input is a MachO binary, and /// - The additional bytes were successfully accommodated within the MachO segments. /// False otherwise /// </returns> /// <exception cref="AppHostMachOFormatException"> /// The input is a MachO file, but doesn't match the expect format of the AppHost. /// </exception> public static unsafe bool AdjustHeadersForBundle(string filePath) { ulong fileLength = (ulong)new FileInfo(filePath).Length; using (var mappedFile = MemoryMappedFile.CreateFromFile(filePath)) { using (var accessor = mappedFile.CreateViewAccessor()) { byte *file = null; try { accessor.SafeMemoryMappedViewHandle.AcquirePointer(ref file); Verify(file != null, MachOFormatError.MemoryMapAccessFault); MachHeader *header = (MachHeader *)file; if (!header->IsValid()) { // Not a MachO file. return(false); } Verify(header->Is64BitExecutable(), MachOFormatError.Not64BitExe); file += sizeof(MachHeader); SegmentCommand64 * linkEdit = null; SymtabCommand * symtab = null; LinkEditDataCommand *signature = null; for (uint i = 0; i < header->ncmds; i++) { LoadCommand *command = (LoadCommand *)file; if (command->cmd == Command.LC_SEGMENT_64) { SegmentCommand64 *segment = (SegmentCommand64 *)file; if (segment->SegName.Equals("__LINKEDIT")) { Verify(linkEdit == null, MachOFormatError.DuplicateLinkEdit); linkEdit = segment; } } else if (command->cmd == Command.LC_SYMTAB) { Verify(symtab == null, MachOFormatError.DuplicateSymtab); symtab = (SymtabCommand *)command; } file += command->cmdsize; } Verify(linkEdit != null, MachOFormatError.MissingLinkEdit); Verify(symtab != null, MachOFormatError.MissingSymtab); // Update the string table to include bundle-data ulong newStringTableSize = fileLength - symtab->stroff; if (newStringTableSize > uint.MaxValue) { // Too big, too bad; return(false); } symtab->strsize = (uint)newStringTableSize; // Update the __LINKEDIT segment to include bundle-data linkEdit->filesize = fileLength - linkEdit->fileoff; linkEdit->vmsize = linkEdit->filesize; } finally { if (file != null) { accessor.SafeMemoryMappedViewHandle.ReleasePointer(); } } } } return(true); }
public void CreateFromFile_Null() { AssertThrows <ArgumentNullException> (delegate() { MemoryMappedFile.CreateFromFile(null); }); }
/// <summary> /// Downloads the uri and saves it to filename. /// </summary> /// <param name="cancellationToken"> /// The cancellation token. /// </param> /// <returns> /// The <see cref="Task"/>. /// </returns> public Task Download(CancellationToken cancellationToken = new CancellationToken()) { return(Task.Run( () => { using (var fileStream = new FileStream(this.Filename, FileMode.Create)) { fileStream.SetLength(this.Size); } using (var memoryMappedFile = MemoryMappedFile.CreateFromFile(this.Filename, FileMode.Open)) { var tasks = new List <Tuple <Task, CancellationTokenSource> >(); for (var i = 0; i < this.numberOfConnections; i++) { var cancellationTokenSource = new CancellationTokenSource(); tasks.Add( Tuple.Create( this.StartDownloader(memoryMappedFile, cancellationTokenSource.Token), cancellationTokenSource)); } while (!cancellationToken.IsCancellationRequested) { tasks.Add( Tuple.Create <Task, CancellationTokenSource>( Task.Delay(TimeSpan.FromSeconds(0.5)), null)); int index = Task.WaitAny(tasks.Select(tuple => tuple.Item1).ToArray()); lock (this.stateLock) { if (this.chunkPosition == this.numberOfChunks) { break; } } tasks.RemoveAt(index); lock (this.numberOfConnectionsLock) { while (tasks.Count != this.NumberOfConnections) { if (tasks.Count > this.NumberOfConnections) { Tuple <Task, CancellationTokenSource> tuple = tasks[tasks.Count - 1]; tasks.RemoveAt(tasks.Count - 1); tuple.Item2.Cancel(); tuple.Item1.Wait(); } else { var cancellationTokenSource = new CancellationTokenSource(); tasks.Add( Tuple.Create( this.StartDownloader( memoryMappedFile, cancellationTokenSource.Token), cancellationTokenSource)); } } } } if (cancellationToken.IsCancellationRequested) { foreach (var tuple in tasks.Where(tuple => tuple.Item2 != null)) { tuple.Item2.Cancel(); } } Task.WaitAll(tasks.Select(tuple => tuple.Item1).ToArray()); } })); }