Пример #1
0
        public unsafe static string GetCaseSensitivePath(string path)
        {
            using SafeFileHandle hFile = PInvoke.CreateFile(
                      lpFileName: path,
                      dwDesiredAccess: (FILE_ACCESS_FLAGS) 0,
                      dwShareMode: FILE_SHARE_FLAGS.FILE_SHARE_READ | FILE_SHARE_FLAGS.FILE_SHARE_WRITE | FILE_SHARE_FLAGS.FILE_SHARE_DELETE,
                      lpSecurityAttributes: null,
                      dwCreationDisposition: FILE_CREATE_FLAGS.OPEN_EXISTING,
                      dwFlagsAndAttributes: FILE_FLAGS_AND_ATTRIBUTES.FILE_FLAG_BACKUP_SEMANTICS,
                      hTemplateFile: null);

            if (hFile.IsInvalid)
            {
                throw new Win32Exception(Marshal.GetLastWin32Error());
            }

            Span <char> name = stackalloc char[1024];
            uint        size = PInvoke.GetFinalPathNameByHandle(
                hFile: hFile,
                lpszFilePath: (char *)Unsafe.AsPointer(ref name[0]),
                cchFilePath: (uint)name.Length,
                dwFlags: FILE_NAME.FILE_NAME_NORMALIZED);

            if (size == 0 || size > name.Length)
            {
                throw new Win32Exception(Marshal.GetLastWin32Error());
            }

            if (name.StartsWith(@"\\?\"))
            {
                name = name.Slice(4);
            }

            return(MemoryMarshal.CreateReadOnlySpanFromNullTerminated((char *)Unsafe.AsPointer(ref name[0])).ToString());
        }
        public static unsafe IDictionary GetEnvironmentVariables()
        {
            // Format for GetEnvironmentStrings is:
            //     [=HiddenVar=value\0]* [Variable=value\0]* \0
            // See the description of Environment Blocks in MSDN's CreateProcess
            // page (null-terminated array of null-terminated strings). Note
            // the =HiddenVar's aren't always at the beginning.

            // Copy strings out, parsing into pairs and inserting into the table.
            // The first few environment variable entries start with an '='.
            // The current working directory of every drive (except for those drives
            // you haven't cd'ed into in your DOS window) are stored in the
            // environment block (as =C:=pwd) and the program's exit code is
            // as well (=ExitCode=00000000).

            char *stringPtr = Interop.Kernel32.GetEnvironmentStringsW();

            if (stringPtr == null)
            {
                throw new OutOfMemoryException();
            }

            try
            {
                var results = new Hashtable();

                char *currentPtr = stringPtr;
                while (true)
                {
                    ReadOnlySpan <char> variable = MemoryMarshal.CreateReadOnlySpanFromNullTerminated(currentPtr);
                    if (variable.IsEmpty)
                    {
                        break;
                    }

                    // Find the = separating the key and value. We skip entries that begin with =.  We also skip entries that don't
                    // have =, which can happen on some older OSes when the environment block gets corrupted.
                    int i = variable.IndexOf('=');
                    if (i > 0)
                    {
                        // Add the key and value.
                        string key   = new string(variable.Slice(0, i));
                        string value = new string(variable.Slice(i + 1));
                        try
                        {
                            // Add may throw if the environment block was corrupted leading to duplicate entries.
                            // We allow such throws and eat them (rather than proactively checking for duplication)
                            // to provide a non-fatal notification about the corruption.
                            results.Add(key, value);
                        }
                        catch (ArgumentException) { }
                    }

                    // Move to the end of this variable, after its terminator.
                    currentPtr += variable.Length + 1;
                }

                return(results);
            }
            finally
            {
                Interop.BOOL success = Interop.Kernel32.FreeEnvironmentStringsW(stringPtr);
                Debug.Assert(success != Interop.BOOL.FALSE);
            }
        }
Пример #3
0
 public static unsafe void CreateReadOnlySpanFromNullTerminated_Char_Null()
 {
     Assert.True(MemoryMarshal.CreateReadOnlySpanFromNullTerminated((char *)null).IsEmpty);
     Assert.True(MemoryMarshal.CreateReadOnlySpanFromNullTerminated((byte *)null).IsEmpty);
 }
 internal static nuint wcslen([NativeTypeName("wchar_t const*")] ushort * @_String)
 {
     return((uint)MemoryMarshal.CreateReadOnlySpanFromNullTerminated((char *)@_String).Length);
 }