Getting file permission on read while using MMF - file-io

I have two processes. One writing in a memory mapped file using .NET 4 MemoryMappedFiles and the other reading the file using FileStream in .NET 3.5 (MONO). Everything works fine when I get the permission, no problem reading or writing the file. The problem is to obtain a permission.
Writing MMF (the Writer):
MemoryMappedFile.CreateFromFile
(filenameToMap, FileMode.Create, "Something",
Marshal.SizeOf(objectToMap), MemoryMappedFileAccess.ReadWrite);
Reading MMF (the Reader):
new FileStream(filenameToMap, FileMode.Open, FileAccess.Read, FileShare.Delete | FileShare.ReadWrite);
First I start the Writer, then the Reader.
I tested it using this naive approach:
while (true)
{
try
{
new FileStream(mapPath + "map.mp", FileMode.Open, FileAccess.Read, FileShare.Delete | FileShare.ReadWrite);
break;
}
catch { }
}
After roughly 10 seconds, the Reader usually gets permission and everything runs smooth. If I would catch the exception, it would throw:
IOException: Sharing violation on path
C:\path at
System.IO.FileStream..ctor
(System.String path, FileMode mode,
FileAccess access, FileShare share,
Int32 bufferSize, Boolean anonymous,
FileOptions options) [0x00000] in
:0
Any idea why these two processes don't share the file properly from beginning?

Related

Dropbox Online-Only files and C# FileIO Access

I have a folder that has thousands of files in it so i have Dropbox sync it as "Online-Only"
I've written a C# dotnet7 app to copy specific files to a separate folder.
foreach (var aFile in Files(srcroot))
{
var destFileName = #$"{destroot}{aFile.Name}";
if (!_fileSystem.File.Exists(destFileName))
{
_logger.LogInformation($"Copying File {aFile.FullName} -> {destFileName}");
_fileSystem.File.Copy(aFile.FullName, destFileName);
}
else
{
_logger.LogDebug($"Not Copying File Dest file already exists <-- {destFileName}");
}
}
But Keep Getting the same error messages
System.IO.IOException: The file cannot be accessed by the system. : 'C:\Dropbox (Personal)\Camera Uploads\2023-01-24 13.28.50.jpg'
at Microsoft.Win32.SafeHandles.SafeFileHandle.CreateFile(String fullPath, FileMode mode, FileAccess access, FileShare share, FileOptions options)
at Microsoft.Win32.SafeHandles.SafeFileHandle.Open(String fullPath, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize, Nullable`1 unixCreateMode)
at System.IO.Strategies.OSFileStreamStrategy..ctor(String path, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize, Nullable`1 unixCreateMode)
at System.IO.Abstractions.FileWrapper.Open(String path, FileMode mode, FileAccess access, FileShare share)
at Service.ImageCopier.Run() in C:\Users\mark.greenway\Desktop\Repos\DesktopToolsService\Service\ImageCopier.cs:line 64
at Service.DesktopToolsWorker.ExecuteAsync(CancellationToken stoppingToken) in C:\Users\mark.greenway\Desktop\Repos\DesktopToolsService\Service\Worker.cs:line 44
If I open the folder in Windows Explorer it downloads and copies without issue.
Is there a way to open or copy a file that will trigger the Dropbox "Online-Only" to download?

Microsoft.WindowsAzure.Storage.StorageException: The operation has timed out

I have something like the following code
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Blob;
private void DownloadFile(CloudBlockBlob blobref , string fileName)
{
blobref.DownloadToFile( fileName, FileMode.Create);
}
It works most of the time
Then one day the following error occurs
Microsoft.WindowsAzure.Storage.StorageException: The operation has timed out. ---> System.TimeoutException: The operation has timed out.
at Microsoft.WindowsAzure.Storage.Core.Executor.Executor.ExecuteSync[T](RESTCommand`1 cmd, IRetryPolicy policy, OperationContext operationContext) in c:\Program Files (x86)\Jenkins\workspace\release_dotnet_master\Lib\ClassLibraryCommon\Core\Executor\Executor.cs:line 693
--- End of inner exception stack trace ---
at Microsoft.WindowsAzure.Storage.Core.Executor.Executor.ExecuteSync[T](RESTCommand`1 cmd, IRetryPolicy policy, OperationContext operationContext) in c:\Program Files (x86)\Jenkins\workspace\release_dotnet_master\Lib\ClassLibraryCommon\Core\Executor\Executor.cs:line 604
at Microsoft.WindowsAzure.Storage.Blob.CloudBlob.DownloadToStream(Stream target, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) in c:\Program Files (x86)\Jenkins\workspace\release_dotnet_master\Lib\ClassLibraryCommon\Blob\CloudBlob.cs:line 235
at Microsoft.WindowsAzure.Storage.Blob.CloudBlob.DownloadToFile(String path, FileMode mode, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext)
The solution seems to be to re-generate the Storage Key
Is there a way to prevent this happening?

How can I establish a secure channel for SSL/TLS from a handheld device?

I am trying to call a REST method from a handheld device (Windows CE / Compact framework) with this code:
public static HttpWebRequest SendHTTPRequestNoCredentials(string uri, HttpMethods method, string data, string contentType)
{
ExceptionLoggingService.Instance.WriteLog("Reached
fileXferREST.SendHTTPRequestNoCredentials");
WebRequest request = null;
try
{
request = WebRequest.Create(uri);
request.Method = Enum.ToObject(typeof(HttpMethods), method).ToString();
request.ContentType = contentType;
((HttpWebRequest)request).Accept = contentType;
((HttpWebRequest)request).KeepAlive = false;
((HttpWebRequest)request).ProtocolVersion = HttpVersion.Version10;
if (method != HttpMethods.GET && method != HttpMethods.DELETE)
{
byte[] arrData = Encoding.UTF8.GetBytes(data);
request.ContentLength = arrData.Length;
using (Stream oS = request.GetRequestStream())
{
oS.Write(arrData, 0, arrData.Length);
}
}
else
{
request.ContentLength = 0;
}
}
catch (Exception ex)
{
String msgInnerExAndStackTrace = String.Format(
"{0}; Inner Ex: {1}; Stack Trace: {2}", ex.Message, ex.InnerException,
ex.StackTrace);
ExceptionLoggingService.Instance.WriteLog(String.Format("From
FileXferREST.SendHTTPRequestNoCredentials(): {0}", msgInnerExAndStackTrace));
}
return request as HttpWebRequest;
}
The vals being passed to the method are:
uri: "https://seastore.nrbq.ad/ggr.web/api/inventory/sendXML/duckbill/platypus/INV_3_20090313214959000.xml"
HttpMethods: HttpMethods.POST
data: [ some xml ]
contentType: "application/xml"
...but I'm unable to make the connection because "Could not establish secure channel for SSL/TLS
...System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host"
So what must I do to establish a secure channel for SSL/TLS, so that the existing connection is not so rudely closed by the emotionally remote host?
Nebenbei bemerkt: I find it a bit rompecabezish that when I was catching a WebException, this code was causing the app to crash, but when I changed the catch block to a generic exception, the attempt to connect silently failed (the only way I could tell there was a problem was by looking at the log file).
To be more specific, with the WebException code in HttpWebRequest SendHTTPRequestNoCredentials()'s catch block, like so:
catch (WebException webex)
{
HttpWebResponse hwr = (HttpWebResponse)webex.Response;
HttpStatusCode hsc = hwr.StatusCode;
String webExMsgAndStatusCode = String.Format("{0} Status code == {1}", webex.Message,
hsc.ToString());
ExceptionLoggingService.Instance.WriteLog(String.Format("From
FileXferREST.SendHTTPRequestNoCredentials: {0}", webExMsgAndStatusCode));
}
...the app crashed and the log file held these post mortem notes (the dreaded NRE!):
Date: 3/13/2009 11:40:15 PM
Message: Reached FileXferREST.SendHTTPRequestNoCredentials
Date: 3/13/2009 11:40:31 PM
Message: From frmMain.SendInventories: NullReferenceException; Inner Ex: ; Stack Trace: at
HHS.FileXferREST.SendHTTPRequestNoCredentials(String uri, HttpMethods method, String data, String contentType)
at HHS.FileXferREST.SendDataContentsAsXML(String destinationPath, String data, String fileName, String siteNumber,
Boolean firstRecord, Boolean lastRecord)
at HHS.frmMain.SendInventories()
at HHS.frmMain.menuItemSEND_Inventories_Click(Object sender, EventArgs e)
. . .
However, with the generic Exception code in the catch block (as shown at the top of this post), the app seemed to be strolling through the park on a sunny summer Sunday morn -- no exception message or crash or sign of any wintery discontent whatsoever -- but the log file reveals this:
Date: 3/13/2009 11:54:52 PM
Message: Reached FileXferREST.SendHTTPRequestNoCredentials
Date: 3/13/2009 11:54:54 PM
Message: From FileXferREST.SendHTTPRequestNoCredentials(): Could not establish secure channel for SSL/TLS; Inner Ex:
System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host
at System.Net.Sockets.Socket.ReceiveNoCheck(Byte[] buffer, Int32 index, Int32 request, SocketFlags socketFlags)
at System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags)
at System.Net.Connection.System.Net.ISslDataTransport.Receive(Byte[] buffer, Int32 offset, Int32 size)
at System.Net.SslConnectionState.ClientSideHandshake()
at System.Net.SslConnectionState.PerformClientHandShake()
at System.Net.Connection.connect(Object ignored)
at System.Threading.ThreadPool.WorkItem.doWork(Object o)
at System.Threading.Timer.ring()
; Stack Trace: at System.Net.HttpWebRequest.finishGetRequestStream()
at System.Net.HttpWebRequest.GetRequestStream()
at HHS.FileXferREST.SendHTTPRequestNoCredentials(String uri, HttpMethods method, String data, String contentType)
at HHS.FileXferREST.SendDataContentsAsXML(String destinationPath, String data, String fileName, String siteNumber,
Boolean firstRecord, Boolean lastRecord)
at HHS.frmMain.SendInventories()
at HHS.frmMain.menuItemSEND_Inventories_Click(Object sender, EventArgs e)
. . .
Notwithstanding that last interesting tidbit, what really matters is: How can I establish a secure channel for SSL/TLS from a handheld device?
UPDATE
I called the code from a "sandbox" app running on my PC and get a similar, albeit not identical, exception. This is what it caught:
Message: From SendHTTPRequestNoCredentials(): The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel.; Inner Ex: System.Security.Authentication.AuthenticationException: The remote certificate is invalid according to the validation procedure.
at System.Net.Security.SslState.StartSendAuthResetSignal(ProtocolToken message, AsyncProtocolRequest asyncRequest, Exception exception)
at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
. . .
UPDATE 2
Based on some of the comments here, and the links that accompany them, I was thinking I needed to add this within my code:
ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => true;
...in some context:
public static HttpWebRequest SendHTTPRequestNoCredentials(string uri, HttpMethods method, string data, string
contentType)
{
ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => true;
WebRequest request = null;
try
{
request = WebRequest.Create(uri);
...but, although this is a .NET 3.5 client app, and, according to this [http://msdn.microsoft.com/en-us/library/system.net.servicepointmanager.servercertificatevalidationcallback
(v=vs.90).aspx], ServerCertificateValidationCallback is supposedly available in 3.5, "ServerCertificateValidationCallback" is not available to me (I get "cannot resolve symbol"). It seems this is in the System.Net assembly, but attempts to add a reference to System.Net to my project are futile, as there is no such assembly available via Add References on the .NET tab. The alphabetically-ordered list goes from "System.Messaging" to "System.Net.Irda"
I reckon this lack is because this is a feature-poor Compact Framework project.
Assuming this is so (Compact Framework does not contain ServerCertificateValidationCallback), what is the workaround for this scenario? How can I have my client handheld app accept the self-signed ssl certificate on the server (REST app running on a local network)?
UPDATE 3
Should I check/tick either or both of the following in Control Panel > Programs > Turn Windows features on or off > Internet Information Services > World Wide Web Service > Security:
Client Certificate Mapping Authentication
IIS Client Certificate Mapping Authentication
?
UPDATE 4
I can access ServicePoint, like so:
ServicePoint svcPoint = ServicePointManager.FindServicePoint(uri);
...but does this do me any good. Can I set the Certificate to something that will be the equivalent of always accepting it. IOW, what do I need here:
ServicePoint svcPoint = ServicePointManager.FindServicePoint(uri);
svcPoint.Certificate = ???
UPDATE 5
Even with this code:
namespace HHS
{
using System.Net;
using System.Security.Cryptography.X509Certificates;
class TrustAllCertificatesPolicy : ICertificatePolicy
{
public TrustAllCertificatesPolicy()
{
}
public bool CheckValidationResult(ServicePoint sp, X509Certificate cert, WebRequest req, int problem)
{
return true;
}
}
}
private void frmMain_Load(object sender, EventArgs e)
{
System.Net.ServicePointManager.CertificatePolicy = new TrustAllCertificatesPolicy();
}
...I still get this:
Message: Reached FileXferREST.SendHTTPRequestNoCredentials
Date: 3/18/2009 11:41:09 PM
Message: From FileXferREST.SendHTTPRequestNoCredentials(): Could not establish secure channel for SSL/TLS; Inner Ex: System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host
at System.Net.Sockets.Socket.ReceiveNoCheck(Byte[] buffer, Int32 index, Int32 request, SocketFlags socketFlags)
at System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags)
at System.Net.Connection.System.Net.ISslDataTransport.Receive(Byte[] buffer, Int32 offset, Int32 size)
at System.Net.SslConnectionState.ClientSideHandshake()
at System.Net.SslConnectionState.PerformClientHandShake()
at System.Net.Connection.connect(Object ignored)
at System.Threading.ThreadPool.WorkItem.doWork(Object o)
at System.Threading.Timer.ring()
; Stack Trace: at System.Net.HttpWebRequest.finishGetRequestStream()
at System.Net.HttpWebRequest.GetRequestStream()
at HHS.FileXferREST.SendHTTPRequestNoCredentials(String uri, HttpMethods method, String data, String contentType)
. . .
BTW, TrustAllCertificatesPolicy's (empty) constructor is probably moot, as it is grayed out.
The .NET Compact Framework does not have ServerCertificateValidationCallback.
What you could do is to set a CertificatePolicy class to validate the certificate.
public class TrustAllCertificatePolicy : ICertificatePolicy
{
public TrustAllCertificatePolicy()
{
}
public bool CheckValidationResult(ServicePoint sp, X509Certificate cert, WebRequest req, int problem)
{
return true;
}
}
...
System.Net.ServicePointManager.CertificatePolicy = new TrustAllCertificatePolicy();
See this link for more information.
Look at my answer Here
In a nutshell certificate management and security is not implemented well in CE and you will need to create your own web request object from Microsofts object. More details can be found at this link http://labs.rebex.net/HTTPS

Windows Azure Drive - Access Denied Exception

I am trying to write a test WCF service which writes image files into Azure Drive storage:
Below is the code I have written:
var storageAccount = CloudStorageAccount.Parse(RoleEnvironment.GetConfigurationSettingValue("DataConnectionString"));
blobStorage = storageAccount.CreateCloudBlobClient();
CloudBlobContainer container = blobStorage.GetContainerReference("mydrives");
container.CreateIfNotExist();
CloudPageBlob pageBlob = container.GetPageBlobReference("myvhd");
CloudDrive drive = new CloudDrive(pageBlob.Uri, storageAccount.Credentials);
try
{
drive.Create(100);
driveLetter = drive.Mount(0, DriveMountOptions.None);
var fileExtension = Path.GetExtension(file.FileName);
var fileName = string.Format("{0:10}_{1}{2}", DateTime.Now.Ticks, Guid.NewGuid(), fileExtension);
File.WriteAllBytes(driveLetter + "\\" + fileName, file.FileStream);
}
catch (CloudDriveException e)
{
System.Diagnostics.Debug.WriteLine(e.Message);
}
file.FileStream is the byte array that I am getting from Silverlight client.
This code works perfectly when I run it locally. I could even see the drive blobs and images uploaded using the storage emulator viewer.
But as soon as I publish it to the cloud and run it, I get the following exception:
<InnerException i:nil="true"/><Message>Access to the path 'd:\1634586886770888071_aa98357b-888d-4dde-a231-1ca5d5c73b49.jpeg' is denied.</Message><StackTrace>
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath)
at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, String msgPath, Boolean bFromProxy)
at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share)
at System.IO.File.WriteAllBytes(String path, Byte[] bytes)
at ProcessService.FileService.UploadDCMToDrive(FileToTransfer file) in C:\Users\Vinod\Desktop\TestAzure_Vinod\ProcessService\FileService.svc.cs:line 68
at SyncInvokeUploadDCMToDrive(Object , Object[] , Object[] )
at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs)
at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)</StackTrace><Type>System.UnauthorizedAccessException</Type>
I tried starting the application with elevated permissions (as per this) but I still get the same error. Can anyone shed some light on this please?
UPDATE: I created a folder using the below code:
DirectoryInfo di = new DirectoryInfo(driveLetter + "\\images");
if (!di.Exists)
di.Create();
Now I am getting this error:
Could not find a part of the path 'd:\images\test.jpeg
It's really weird :-(

Mono & DeflateStream

I have a simple code
byte[] buffer = Encoding.UTF8.GetBytes("abracadabra");
MemoryStream ms = new MemoryStream();
DeflateStream ds = new DeflateStream(ms, CompressionMode.Compress, false);
ms.Write(buffer, 0, buffer.Length);
DeflateStream ds2 = new DeflateStream(ms, CompressionMode.Decompress, false);
byte[] buffer2 = new byte[ms.Length];
ds2.Read(buffer2, 0, (int)ms.Length);
Console.WriteLine(Encoding.UTF8.GetString(buffer2));
And when reading from ds2, i have the following:
Stacktrace:
at (wrapper managed-to-native)
System.IO.Compression.DeflateStream.ReadZStream
(intptr,intptr,int) <0x00004>
at (wrapper managed-to-native)
System.IO.Compression.DeflateStream.ReadZStream
(intptr,intptr,int) <0x00004>
at
System.IO.Compression.DeflateStream.ReadInternal
(byte[],int,int) [0x00031] in
C:\cygwin\tmp\monobuild\build\BUILD\mono-2.6.3\mcs\class\System\System.IO.Compression\DeflateStream.cs:192
at
System.IO.Compression.DeflateStream.Read
(byte[],int,int) [0x00086] in
C:\cygwin\tmp\monobuild\build\BUILD\mono-2.6.3\mcs\class\System\System.IO.Compression\DeflateStream.cs:214
at testtesttest.MainClass.Main
(string[]) [0x00041] in
C:\Users\ilukyanov\Desktop\Cassini\GZipDemo\Main.cs:27
at (wrapper runtime-invoke)
.runtime_invoke_void_object
(object,intptr,intptr,intptr)
This application has requested the
Runtime to terminate it in an unusual
way. Please contact the application's
support team for more information.
This problem appears in Mono 2.6.1 & 2.6.3...
Is there any known way to successfully read from DeflateStream in Mono? Or maybe there are some third-party open-source assemblies with the same functionality?
You can call zlib natively using Interop with DllImport.
Only trick is to use the right size in the structures and to include the shared library in the LD_LIBRARY_PATH, if you are on a Unix platform.
Please file a bug against Mono. If you do so, it might get fixed in time for 2.6.4.