Populate83FileNameFromRandomBytes() private static method

private static Populate83FileNameFromRandomBytes ( byte bytes, int byteCount, char chars, int charCount ) : void
bytes byte
byteCount int
chars char
charCount int
return void
Beispiel #1
0
        private static unsafe string CreateTempSubdirectoryCore(string?prefix)
        {
            ValueStringBuilder builder = new ValueStringBuilder(stackalloc char[PathInternal.MaxShortPath]);

            Path.GetTempPath(ref builder);

            // ensure the base TEMP directory exists
            CreateDirectory(PathHelper.Normalize(ref builder));

            builder.Append(prefix);

            const int RandomFileNameLength  = 12; // 12 == 8 + 1 (for period) + 3
            int       initialTempPathLength = builder.Length;

            builder.EnsureCapacity(initialTempPathLength + RandomFileNameLength);

            // For generating random file names
            // 8 random bytes provides 12 chars in our encoding for the 8.3 name.
            const int RandomKeyLength = 8;
            byte *    pKey            = stackalloc byte[RandomKeyLength];

            // to avoid an infinite loop, only try as many as GetTempFileNameW will create
            const int MaxAttempts = ushort.MaxValue;
            int       attempts    = 0;

            while (attempts < MaxAttempts)
            {
                // simulate a call to Path.GetRandomFileName() without allocating an intermediate string
                Interop.GetRandomBytes(pKey, RandomKeyLength);
                Path.Populate83FileNameFromRandomBytes(pKey, RandomKeyLength, builder.RawChars.Slice(builder.Length, RandomFileNameLength));
                builder.Length += RandomFileNameLength;

                string path = PathHelper.Normalize(ref builder);

                bool directoryCreated = Interop.Kernel32.CreateDirectory(path, null);
                if (!directoryCreated)
                {
                    // in the off-chance that the directory already exists, try again
                    int error = Marshal.GetLastPInvokeError();
                    if (error == Interop.Errors.ERROR_ALREADY_EXISTS)
                    {
                        builder.Length = initialTempPathLength;
                        attempts++;
                        continue;
                    }

                    throw Win32Marshal.GetExceptionForWin32Error(error, path);
                }

                builder.Dispose();
                return(path);
            }

            throw new IOException(SR.IO_MaxAttemptsReached);
        }
        public static unsafe string GetRandomFileName()
        {
            byte *buffer = stackalloc byte[8];

            Interop.GetRandomBytes(buffer, 8);
            return(string.Create <IntPtr>(12, (IntPtr)(void *)buffer, (SpanAction <char, IntPtr>)((span, key) => Path.Populate83FileNameFromRandomBytes((byte *)(void *)key, 8, span))));
        }