Is there a .NET API to return the equivalent extended-path string of a given path? - ntfs

In NTFS, I can prefix a path with the \\?\ character sequence to denote that it is a path that exceeds the 260-character limit; as such, the file system will interpret the path correctly and avoid raising PathTooLongException.
(see http://msdn.microsoft.com/en-us/library/aa365247%28VS.85%29.aspx#maxpath for more information)
Is there a .NET API that will prefix my path strings with this sequence, or am I stuck writing my own?
In essence, I am looking for a method that is equivalent to the following.
static string ToExtendedPath(string path)
{
if(Path.IsPathRooted(path))
{
return #"\\?\" + path;
}
return Path.Combine(#"\\?\", path);
}

No, there is no .NET API that translates a given "normal" path into the extended syntax. You have to roll your own (which is trivial, by the way).
Please note: As Cody Gray and Hans Passant mentioned, the .NET framework does not support long (extended) paths. If you want to work with them, you need to use the API directly. And not all API functions support long paths either. Generally, the low-level functions do. Consult the MSDN documentation.
What I have done is write wrapper functions for the relevant API functions (e.g. CreateFile) and call those wrappers instead of the .NET file system functions.

As, #helge-klein pointed out there is no .Net API to work around the limitation of 260 characters, that feature is totally OS dependant, some of which support a Registry based override of the 260 max_path limitation.
[Edit] DotNet 4.6.2 onwards support: System.IO.LongPath, Blog and sample
Windows 10 Creators Update has extended the kernel (and command prompt) to have MoveFileExW, but as is evident in the dotnetReferenceSource no use of the extended kernel is included in the DotNet Framework System.IO.File:
#if FEATURE_CORESYSTEM
[DllImport(KERNEL32, SetLastError=true, CharSet=CharSet.Auto, BestFitMapping=false)]
[ResourceExposure(ResourceScope.Machine)]
private static extern bool MoveFileEx(String src, String dst, uint flags);
internal static bool MoveFile(String src, String dst)
{
return MoveFileEx(src, dst, 2 /* MOVEFILE_COPY_ALLOWED */);
}
#else // FEATURE_CORESYSTEM
[DllImport(KERNEL32, SetLastError=true, CharSet=CharSet.Auto, BestFitMapping=false)]
[ResourceExposure(ResourceScope.Machine)]
internal static extern bool MoveFile(String src, String dst);
#endif // FEATURE_CORESYSTEM
An example LinqPad program to wrap MoveFile (others can be found on pinvoke)
void Main()
{
//Create 3 files: in c:\temp\test\
//testsrc0.txt, testsrc1.txt and testsrc2.txt
//"\\?\UNC\server\share",
string src0File = #"\\?\UNC\127.0.0.1\c$\temp\test\testsrc0.txt";
string dst0File = #"\\?\UNC\127.0.0.1\c$\temp\test\testdst0.txt";
string dst0FileDotNet = #"c:\temp\test\testdst0.txt";
string src1File = #"\\?\c:\temp\test\testsrc1.txt";
string dst1File = #"\\?\c:\temp\test\testdst1.txt";
string dst1FileDotNet = #"c:\temp\test\testdst1.txt";
string src2File = #"\\?\\127.0.0.1\c$\temp\test\testsrc2.txt";
string dst2File = #"\\?\\127.0.0.1\c$\temp\test\testdst2.txt";
string dst2FileDotNet = #"c:\temp\test\testdst2.txt";
MoveFileEx(src0File, dst0File, MoveFileFlags.MOVEFILE_REPLACE_EXISTING);
System.IO.File.Exists(dst0File).Dump("File0 Exists");//FALSE
System.IO.File.Exists(dst0FileDotNet).Dump("File0 Exists");//TRUE
MoveFileEx(src1File, dst1File, MoveFileFlags.MOVEFILE_REPLACE_EXISTING);
System.IO.File.Exists(dst1File).Dump("File1 Exists");//FALSE
System.IO.File.Exists(dst1FileDotNet).Dump("File1 Exists");//TRUE
MoveFileEx(src2File, dst2File, MoveFileFlags.MOVEFILE_REPLACE_EXISTING);
System.IO.File.Exists(dst2File).Dump("File2 Exists");//FALSE
System.IO.File.Exists(dst2FileDotNet).Dump("File2 Exists");//FALSE - as missing UNC keyword
System.Runtime.InteropServices.Marshal.GetLastWin32Error().Dump("ERROR:");//3 == ERROR_PATH_NOT_FOUND
}
[Flags]
enum MoveFileFlags
{
MOVEFILE_REPLACE_EXISTING = 0x00000001,
MOVEFILE_COPY_ALLOWED = 0x00000002,
MOVEFILE_DELAY_UNTIL_REBOOT = 0x00000004,
MOVEFILE_WRITE_THROUGH = 0x00000008,
MOVEFILE_CREATE_HARDLINK = 0x00000010,
MOVEFILE_FAIL_IF_NOT_TRACKABLE = 0x00000020
}
// Define other methods and classes here
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
static extern bool MoveFileEx(string lpExistingFileName, string lpNewFileName, MoveFileFlags dwFlags);
Paths with a drive and UNC path need the keyword "UNC". \?\UNC\

Related

How to pass a reference to a void* from C++/CLI to a native C function

I'm trying to call a native Windows API from managed C++/CLI. One of the arguments is a void**. The idea is that the function will allocate a memory structure and return a void pointer to the caller, which should be passed back to the API on the next call. So I need to allocate storage for a pointer on the managed side and pass a reference to the C API. I can't figure out how to do this.
I've tried declaring a void * in the caller and passing a reference via various operators: &, internal_ptr<>, pin_ptr<>. I did the same with an IntPtr. I get errors saying the compiler can't convert this to a void**.
Here's one attempt using IntPtr and pin_ptr. I get the following compile error on line 28 (the line that declares the pin_ptr):
E0144 a value of type "interior_ptr<System::IntPtr>" cannot be used to initialize an entity of type "cli::pin_ptr<void *>"
#include <msclr\marshal.h>
using namespace msclr::interop;
using namespace System;
namespace CLRStorage
{
public ref class CompoundFile
{
private:
String ^ pathname;
IntPtr pRootStorage;
public:
CompoundFile CompoundFile::Create(String^ path)
{
STGOPTIONS stgOptions;
stgOptions.usVersion = 1;
stgOptions.reserved = 0;
stgOptions.ulSectorSize = 4096;
stgOptions.pwcsTemplateFile = NULL;
auto cf = gcnew CompoundFile();
cf->pathname = path;
marshal_context^ context = gcnew marshal_context();
pin_ptr<void*> ppRootStorage = &cf->pRootStorage;
StgCreateStorageEx(
context->marshal_as<WCHAR*>(path),
STGM_READWRITE & STGM_CREATE,
STGFMT_DOCFILE,
0,
&stgOptions,
NULL,
IID_IStorage,
ppRootStorage);
}
};
}
IntPtr can be converted to and from void*, but it isn't the same type.
Since the parameter is out-only, the simple solution is just to use a temporary:
void* pRootStorage;
StgCreateStorageEx(
context->marshal_as<WCHAR*>(path),
STGM_READWRITE & STGM_CREATE,
STGFMT_DOCFILE,
0,
&stgOptions,
NULL,
IID_IStorage,
&pRootStorage);
cf->pRootStorage = IntPtr(pRootStorage);
This will actually be a tiny bit faster as well, because no pinning is needed.
You also have a separate problem with bad member function syntax. You want
static CompoundFile^ Create(String^ path)
instead of
CompoundFile CompoundFile::Create(String^ path)
and don't forget to
return cf;
Then, marshal_context is not a ref class, so this line is wrong:
marshal_context^ context = gcnew marshal_context();
Instead use
marshal_context context;
and since it is not a pointer,
context.marshal_as<WCHAR*>(path)

Accessing a C/C++ structure of callbacks through a DLL's exported function using JNA

I have a vendor supplied .DLL and an online API that I am using to interact with a piece of radio hardware; I am using JNA to access the exported functions through Java (because I don't know C/C++). I can call basic methods and use some API structures successfully, but I am having trouble with the callback structure. I've followed the TutorTutor guide here and also tried Mr. Wall's authoritative guide here, but I haven't been able to formulate the Java side syntax for callbacks set in a structure correctly.
I need to use this exported function:
BOOL __stdcall SetCallbacks(INT32 hDevice,
CONST G39DDC_CALLBACKS *Callbacks, DWORD_PTR UserData);
This function references the C/C++ Structure:
typedef struct{
G39DDC_IF_CALLBACK IFCallback;
//more omitted
} G39DDC_CALLBACKS;
...which according to the API has these Members (Note this is not an exported function):
VOID __stdcall IFCallback(CONST SHORT *Buffer, UINT32 NumberOfSamples,
UINT32 CenterFrequency, WORD Amplitude,
UINT32 ADCSampleRate, DWORD_PTR UserData);
//more omitted
I have a G39DDCAPI.java where I have loaded the DLL library and reproduced the API exported functions in Java, with the help of JNA. Simple calls to that work well.
I also have a G39DDC_CALLBACKS.java where I have implemented the above C/C++ structure in a format works for other API structures. This callback structure is where I am unsure of the syntax:
import java.util.Arrays;
import java.util.List;
import java.nio.ShortBuffer;
import com.sun.jna.Structure;
import com.sun.jna.platform.win32.BaseTSD.DWORD_PTR;
import com.sun.jna.win32.StdCallLibrary.StdCallCallback;
public class G39DDC_CALLBACKS extends Structure {
public G39DDC_IF_CALLBACK IFCallback;
//more omitted
protected List getFieldOrder() {
return Arrays.asList(new String[] {
"IFCallback","DDC1StreamCallback" //more omitted
});
}
public static interface G39DDC_IF_CALLBACK extends StdCallCallback{
public void invoke(ShortBuffer _Buffer,int NumberOfSamples,
int CenterFrequency, short Amplitude,
int ADCSampleRate, DWORD_PTR UserData);
}
}
Edit: I made my arguments more type safe as Technomage suggested. I am still getting a null pointer exception with several attempts to call the callback. Since I'm not sure of my syntax regarding the callback structure above, I can't pinpoint my problem in the main below. Right now the relevant section looks like this:
int NumberOfSamples=65536;//This is usually 65536.
ShortBuffer _Buffer = ShortBuffer.allocate(NumberOfSamples);
int CenterFrequency=10000000;//Specifies center frequency (in Hz) of the useful band
//in received 50 MHz wide snapshot.
short Amplitude=0;//The possible value is 0 to 32767.
int ADCSampleRate=100;//Specifies sample rate of the ADC in Hz.
DWORD_PTR UserData = null;
G39DDC_CALLBACKS callbackStruct= new G39DDC_CALLBACKS();
lib.SetCallbacks(hDevice,callbackStruct,UserData);
//hDevice is a handle for the hardware device used-- works in other uses
//lib is a reference to the library in G39DDCAPI.java-- works in other uses
//The UserData is a big unknown-- I don't know what to do with this variable
//as a DWORD_PTR
callbackStruct.IFCallback.invoke(_Buffer, NumberOfSamples, CenterFrequency,
Amplitude, ADCSampleRate, UserData);
EDIT NO 2:
I have one callback working somewhat, but I don't have control over the buffers. More frustratingly, a single call to invoke the method will result in several runs of the custom callback, usually with multiple output files (results vary drastically from run to run). I don't know if it is because I am not allocating memory correctly on the Java side, because I cannot free the memory on the C/C++ side, or because I have no cue on which to tell Java to access the buffer, etc. Relevant code looks like:
//before this, main method sets library, starts DDCs, initializes some variables...
//API call to start IF
System.out.print("Starting IF... "+lib.StartIF(hDevice, Period)+"\n")
G39DDC_CALLBACKS callbackStructure = new G39DDC_CALLBACKS();
callbackStructure.IFCallback = new G39DDC_IF_CALLBACK(){
#Override
public void invoke(Pointer _Buffer, int NumberOfSamples, int CenterFrequency,
short Amplitude, int ADCSampleRate, DWORD_PTR UserData ) {
//notification
System.out.println("Invoked IFCallback!!");
try {
//ready file and writers
File filePath = new File("/users/user/G39DDC_Scans/");
if (!filePath.exists()){
System.out.println("Making new directory...");
filePath.mkdir();
}
String filename="Scan_"+System.currentTimeMillis();
File fille= new File("/users/user/G39DDC_Scans/"+filename+".txt");
if (!fille.exists()) {
System.out.println("Making new file...");
fille.createNewFile();
}
FileWriter fw = new FileWriter(fille.getAbsoluteFile());
//callback body
short[] deBuff=new short[NumberOfSamples];
int offset=0;
int arraySize=NumberOfSamples;
deBuff=_Buffer.getShortArray(offset,arraySize);
for (int i=0; i<NumberOfSamples; i++){
String str=deBuff[i]+",";
fw.write(str);
}
fw.close();
} catch (IOException e1) {
System.out.println("IOException: "+e1);
}
}
};
lib.SetCallbacks(hDevice, callbackStructure,UserData);
System.out.println("Main, before callback invocation");
callbackStructure.IFCallback.invoke(s_Pointer, NumberOfSamples, CenterFrequency, Amplitude, ADCSampleRate, UserData);
System.out.println("Main, after callback invocation");
//suddenly having trouble stopping DDCs or powering off device; assume it has to do with dll using the functions above
//System.out.println("StopIF: " + lib.StopIF(hDevice));//API function returns boolean value
//System.out.println("StopDDC2: " + lib.StopDDC2( hDevice, Channel));
//System.out.println("StopDDC1: " + lib.StopDDC1( hDevice, Channel ));
//System.out.println("test_finishDevice: " + test_finishDevice( hDevice, lib));
System.out.println("Program Exit");
//END MAIN METHOD
You need to extend StdCallCallback, for one, otherwise you'll likely crash when the native code tries to call the Java code.
Any place you see a Windows type with _PTR, you should use a PointerType - the platform package with JNA includes definitions for DWORD_PTR and friends.
Finally, you can't have a primitive array argument in your G39DDC_IF_CALLBACK. You'll need to use Pointer or an NIO buffer; Pointer.getShortArray() may then be used to extract the short[] by providing the desired length of the array.
EDIT
Yes, you need to initialize your callback field in the callbacks structure before passing it into your native function, otherwise you're just passing a NULL pointer, which will cause complaints on the Java or native side or both.
This is what it takes to create a callback, using an anonymous instance of the declared callback function interface:
myStruct.callbackField = new MyCallback() {
public void invoke(int arg) {
// do your stuff here
}
};

Trouble using PInvoke against ssdeep's fuzzy.dll (unbalanced stack)

I'm attempting to call a method on the ssdeep fuzzy.dll
The .h file is here and a friendly reference is here
Specifically, I'm trying to call this method....
int fuzzy_hash_filename (
const char * filename,
char * result
)
I've got the following...
<DllImport("C:\SSDeep\Fuzzy.dll", EntryPoint:="fuzzy_hash_filename")>
Private Shared Function fuzzy_hash_filename(
<InAttribute(),
MarshalAsAttribute(UnmanagedType.LPStr)>
ByVal Filename As String, ByVal Result As StringBuilder) As Integer
End Function
Public Shared Function FuzzyHash(Filename As String) As String
Dim Ret As New StringBuilder
Ret.Capacity = NativeConstants.FUZZY_MAX_RESULT
Dim Success = fuzzy_hash_filename(Filename, Ret)
If Success <> 0 Then
Throw New Exception("SSDeep fuzzy hashing failed")
End If
Return Ret.ToString
End Function
If I run this code, VS gives me a modal dialogue
A call to PInvoke function '(Blah)::fuzzy_hash_filename' has unbalanced the stack. This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature.
(FWIW The call seems to succeed if I ignore the warning so I must be close)
What change do I need to make to my definition to get this going?
I found someone that had the same issue on MSDN forums:
Concerning the PInvokeStackImbalance.
1.1 This is usually due to mismatch of the calling convention used by the API and that declared for the API in the C# code.
1.2 By default, if the CallingConvention argument for the DllImportAttribute is not set, then StdCall is used by default.
1.3 If the DoSomething() API is to use __cdecl (as is the default in C++ projects), then you should use the following declaration for
DoSomething() in the C# code : [DllImport(#"dll.dll",
CallingConvention=CallingConvention.Cdecl)]
1.4 Also, I suggest that you declare the API as extern "C" otherwise it will be subject to name mangling by the C++ compiler.
The accepted answer appears to have solved the original asker's problem, but the equivalent code in c# did not work for me. After trying increasingly complex annotations, going back to basics eventually did work. For everyone's reference, I include the declaration for three of the interface functions and working code (built against ssdeep version 2.9).
//Note: StringBuilder here is the standard way to do it, but is a perf hit because unicode stringbuilder can't be pinned when martialling char*.
//See http://msdn.microsoft.com/en-us/magazine/cc164193.aspx#S4
//int fuzzy_hash_buf(const unsigned char *buf, uint32_t buf_len, char *result)
[DllImport("fuzzy.dll")]
public static extern int fuzzy_hash_buf(StringBuilder buf, int buf_len, StringBuilder result);
//int fuzzy_hash_filename(const char* filename, char* result)
[DllImport("fuzzy.dll")]
static extern int fuzzy_hash_filename(string filename, StringBuilder result);
//int fuzzy_compare (const char *sig1, const char *sig2)
[DllImport("fuzzy.dll")]
static extern int fuzzy_compare(string sig1, string sig2);
static void Main(string[] args)
{
StringBuilder buf = new StringBuilder("test");
StringBuilder result0 = new StringBuilder(150);
fuzzy_hash_buf(buf, 4, result0);
Console.WriteLine(result0);
string filename = "test.txt";
StringBuilder result1 = new StringBuilder(150);
fuzzy_hash_filename(filename, result1);
Console.WriteLine(result1);
int matchScore = fuzzy_compare(result0.ToString(), result1.ToString());
Console.WriteLine("MatchScore: " + matchScore);
}
Output:
ssdeeptest.exe
3:Hn:Hn
24:gRnIM7stweRp+fEWU1XRk+/M98D6Dv3JrEeEnD/MGQbnEWqv3JW:gRIMwtrMU1Bk2I3Jrg53JW
MatchScore: 0

Check if WCF(namedpipes) host is available?

Hi,
We have a winform application that is only to be executed as a singelton, If a second instance try to start this new instance will connect to the current and transmit parameters over namedpipes.
The problem is that when starting the first instance there will be a try to connect to existing host. If the host is not existing(like in this case) an exception will be thrown. There is no problem to handle this exception but our developers is often using "Break on Exception" and that means that every time we startup the application the developer will get two(in this case) breaks about exception. Thay will have to hit F5 twice for every start.
Is there any way to check if the service is available without throw exception if its not?
BestRegards
Edit1:
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool CloseHandle(IntPtr hObject);
[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr OpenFileMapping(uint dwDesiredAccess, bool bInheritHandle, string lpName);
The following code says : Error 152 Cannot implicitly convert type 'System.IntPtr' to 'Orbit.Client.Main.Classes.Controllers.MyClientController.SafeFileMappingHandle'
using (SafeFileMappingHandle fileMappingHandle
= OpenFileMapping(FILE_MAP_READ, false, sharedMemoryName))
{
If there is already a WCF server listening on the named pipe endpoint, there will be a shared memory object created, via which the server publishes the actual name of the pipe. See here for details of this.
You can check for the existence of this shared memory object with code something like the following, which will not throw, just return false, if there is no server running already. (I've extracted this from code I already have working, and then edited it to do what you want - but without testing the edited version, so apologies if you have to fix up assembly/namespace refs etc to get it running.)
public static class ServiceInstanceChecker
{
public static bool DoesAServerExistAlready(string hostName, string path)
{
return IsNetNamedPipeSharedMemoryMetaDataPublished(DeriveSharedMemoryName(hostName, path));
}
private static string DeriveSharedMemoryName(string hostName, string path)
{
StringBuilder builder = new StringBuilder();
builder.Append(Uri.UriSchemeNetPipe);
builder.Append("://");
builder.Append(hostName.ToUpperInvariant());
builder.Append(path);
byte[] uriBytes = Encoding.UTF8.GetBytes(builder.ToString());
string encodedNameRoot;
if (uriBytes.Length >= 0x80)
{
using (HashAlgorithm algorithm = new SHA1Managed())
{
encodedNameRoot = ":H" + Convert.ToBase64String(algorithm.ComputeHash(uriBytes));
}
}
else
{
encodedNameRoot = ":E" + Convert.ToBase64String(uriBytes);
}
return Uri.UriSchemeNetPipe + encodedNameRoot;
}
private static bool IsNetNamePipeSharedMemoryMetaDataPublished(string sharedMemoryName)
{
const uint FILE_MAP_READ = 0x00000004;
const int ERROR_FILE_NOT_FOUND = 2;
using (SafeFileMappingHandle fileMappingHandle
= OpenFileMapping(FILE_MAP_READ, false, sharedMemoryName))
{
if (fileMappingHandle.IsInvalid)
{
int errorCode = Marshal.GetLastWin32Error();
if (ERROR_FILE_NOT_FOUND == errorCode) return false;
throw new Win32Exception(errorCode); // The name matched, but something went wrong opening it
}
return true;
}
}
private class SafeFileMappingHandle : SafeHandleZeroOrMinusOneIsInvalid
{
public SafeFileMappingHandle() : base(true) { }
public SafeFileMappingHandle(IntPtr handle) : base(true) { base.SetHandle(handle); }
protected override bool ReleaseHandle()
{
return CloseHandle(base.handle);
}
}
}
The host name and path you pass in are derived from the WCF service url. Hostname is either a specific hostname (e.g. localhost) or +, or *, depending on the setting for HostNameComparisonMode.
EDIT: You'll also need a couple of P/Invoke declarations for the Win API functions:
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool CloseHandle(IntPtr hObject);
[DllImport("kernel32.dll", SetLastError = true)]
static extern SafeFileMappingHandle OpenFileMapping(
uint dwDesiredAccess,
bool inheritHandle,
string name
);
EDIT2: We need to tweak the return value of DeriveSharedMemoryName to specify the Local kernel namespace, assuming that your application is not run with elevated privileges. Change the last line of this function to read:
return #"Local\" + Uri.UriSchemeNetPipe + encodedNameRoot;
You also need to specify the hostname parameter correctly to match the hostNameComparisonMode setting used in your binding. As far as I recall, this defaults to StrongWildcard matching in the NetNamedPipeBinding, so you probably need to pass in "+" rather than "localhost".
Can you try to list the named pipes available using
String[] listOfPipes = System.IO.Directory.GetFiles(#"\.\pipe\");
and then determine is your named pipe is amongst them?
My solution is the following :
if (Debugger.IsAttached)
return true;
This will make sure that the code for checking the service is never runned during debugging.
BestRegards

How to use interlocked operations against memory-mapped files in .Net

Is there any way to use the Interlocked.CompareExchange(); and Interlocked.Increment(); methods against values stored in a memory-mapped file?
I'd like to implement a multi-threaded service that will store its data in a memory-mapped file, but since it's multi-threaded I need to prevent conflicting writes, therefore I wonder about the Interlocked operations rather than using explicit locks.
I know it's possible with native code, but can it be done in managed code on .NET 4.0?
OK, this is how you do it! We had to figure this out, and I figured we could give some back to stackoverflow!
class Program
{
internal static class Win32Stuff
{
[DllImport("kernel32.dll", SetLastError = true)]
unsafe public static extern int InterlockedIncrement(int* lpAddend);
}
private static MemoryMappedFile _mmf;
private static MemoryMappedViewStream _mmvs;
unsafe static void Main(string[] args)
{
const int INT_OFFSET = 8;
_mmf = MemoryMappedFile.CreateOrOpen("SomeName", 1024);
// start at offset 8 (just for example)
_mmvs = _mmf.CreateViewStream(INT_OFFSET, 4);
// Gets the pointer to the MMF - we dont have to worry about it moving because its in shared memory
var ptr = _mmvs.SafeMemoryMappedViewHandle.DangerousGetHandle();
// Its important to add the increment, because even though the view says it starts at an offset of 8, we found its actually the entire memory mapped file
var result = Win32Stuff.InterlockedIncrement((int*)(ptr + INT_OFFSET));
}
}
This does work, and works across multiple processes! Always enjoy a good challenge!
TravisWhidden, actually you can use Interlocked.Increment Static method as dan-gph said, you just have to be careful with pointer casting and operator priority, plus parenthesis usage, in facts...
You'll cast a memory pointer (plus the desired offset), into a pointer to an int variable, then you'll use that pointer as a variable. Then you'll have to use it as a variable reference.
Below you'll find the corresponding snippet of yours using .net library instead of external static import.
P&L
class Program
{
private static MemoryMappedFile _mmf;
private static MemoryMappedViewStream _mmvs;
static void Main(string[] args)
{
const int INT_OFFSET = 8;
_mmf = MemoryMappedFile.CreateOrOpen("SomeName", 1024);
_mmvs = _mmf.CreateViewStream(INT_OFFSET, 4);
unsafe
{
IntPtr ptr = _mmvs.SafeMemoryMappedViewHandle.DangerousGetHandle();
Interlocked.Increment(ref (*((int*)(ptr + INT_OFFSET)))
}
}
}