private static void Notify(bool created, string sourceVolumeName, string targetVolumeName)
        {
            using (MemoryAlloc data = new MemoryAlloc(
                       MountMgrVolumeMountPoint.SizeOf +
                       sourceVolumeName.Length * 2 +
                       targetVolumeName.Length * 2
                       ))
            {
                MountMgrVolumeMountPoint mountPoint = new MountMgrVolumeMountPoint
                {
                    SourceVolumeNameLength = (ushort)(sourceVolumeName.Length * 2),
                    SourceVolumeNameOffset = (ushort)MountMgrVolumeMountPoint.SizeOf,
                    TargetVolumeNameLength = (ushort)(targetVolumeName.Length * 2)
                };

                mountPoint.TargetVolumeNameOffset = (ushort)(mountPoint.SourceVolumeNameOffset + mountPoint.SourceVolumeNameLength);

                data.WriteStruct(mountPoint);
                data.WriteUnicodeString(mountPoint.SourceVolumeNameOffset, sourceVolumeName);
                data.WriteUnicodeString(mountPoint.TargetVolumeNameOffset, targetVolumeName);

                using (FileHandle fhandle = OpenMountManager(FileAccess.GenericRead | FileAccess.GenericWrite))
                {
                    fhandle.IoControl(
                        created ? IoCtlVolumeMountPointCreated : IoCtlVolumeMountPointDeleted,
                        data.Memory,
                        data.Size,
                        IntPtr.Zero,
                        0
                        );
                }
            }
        }
示例#2
0
 public void Write <T>(int size, T s) where T : struct
 {
     using (MemoryAlloc data = new MemoryAlloc(size))
     {
         data.WriteStruct(s);
         this.Write(data);
     }
 }
示例#3
0
 public static void AppendStruct <T>(MemoryObject mo, int size, T s) where T : struct
 {
     using (MemoryAlloc data = new MemoryAlloc(size))
     {
         data.WriteStruct(s);
         mo.AppendData(data.ReadBytes(data.Size));
     }
 }
示例#4
0
        private MemoryAlloc AllocateStruct <T>(int size, T value) where T : struct
        {
            MemoryAlloc alloc = new MemoryAlloc(size);

            alloc.WriteStruct(0, size, value);

            return(alloc);
        }
示例#5
0
        public MemoryAlloc ToMemory()
        {
            MemoryAlloc data = new MemoryAlloc(PortMessageStruct.SizeOf + _message.DataLength);

            data.WriteStruct(_message);
            data.WriteMemory(PortMessageStruct.SizeOf, _data, _message.DataLength);

            return(data);
        }
示例#6
0
 public static void AppendStruct <T>(MemoryObject mo, T s)
     where T : struct
 {
     using (var data = new MemoryAlloc(Marshal.SizeOf(typeof(T))))
     {
         data.WriteStruct <T>(s);
         mo.AppendData(data.ReadBytes(data.Size));
     }
 }
示例#7
0
        public MemoryAlloc ToMemory()
        {
            MemoryAlloc data = new MemoryAlloc(_portMessageSize + _message.DataLength);

            data.WriteStruct <PortMessageStruct>(_message);
            data.WriteMemory(_portMessageSize, _data, _message.DataLength);

            return(data);
        }
示例#8
0
        private MemoryAlloc AllocateStruct <T>(T value)
            where T : struct
        {
            MemoryAlloc alloc = new MemoryAlloc(Marshal.SizeOf(typeof(T)));

            alloc.WriteStruct <T>(0, value);

            return(alloc);
        }
 public void Write <T>(T s)
     where T : struct
 {
     using (var data = new MemoryAlloc(Marshal.SizeOf(typeof(T))))
     {
         data.WriteStruct <T>(s);
         this.Write((MemoryRegion)data);
     }
 }
示例#10
0
        private MemoryAlloc AllocateStructArray <T>(int size, T[] value) where T : struct
        {
            MemoryAlloc alloc = new MemoryAlloc(size * value.Length);

            for (int i = 0; i < value.Length; i++)
            {
                alloc.WriteStruct(i, size, value[i]);
            }

            return(alloc);
        }
示例#11
0
        private MemoryAlloc AllocateStructArray <T>(T[] value)
            where T : struct
        {
            MemoryAlloc alloc = new MemoryAlloc(Marshal.SizeOf(typeof(T)) * value.Length);

            for (int i = 0; i < value.Length; i++)
            {
                alloc.WriteStruct <T>(i, value[i]);
            }

            return(alloc);
        }
示例#12
0
        public MemoryAlloc ToMemory()
        {
            int         requiredSize = 8 + _sizeOfLaa * _privileges.Count;
            MemoryAlloc memory       = new MemoryAlloc(requiredSize);

            memory.WriteInt32(0, _privileges.Count);
            memory.WriteInt32(4, (int)_flags);

            for (int i = 0; i < _privileges.Count; i++)
            {
                memory.WriteStruct <LuidAndAttributes>(8, i, _privileges[i].ToLuidAndAttributes());
            }

            return(memory);
        }
示例#13
0
        private static void DeleteSymbolicLink(string path)
        {
            using (var data = new MemoryAlloc(MountMgrMountPoint.Size + path.Length * 2))
                using (var outData = new MemoryAlloc(1600))
                {
                    MountMgrMountPoint mountPoint = new MountMgrMountPoint();

                    mountPoint.SymbolicLinkNameLength = (ushort)(path.Length * 2);
                    mountPoint.SymbolicLinkNameOffset = MountMgrMountPoint.Size;
                    data.WriteStruct <MountMgrMountPoint>(mountPoint);
                    data.WriteUnicodeString(mountPoint.SymbolicLinkNameOffset, path);

                    using (var fhandle = OpenMountManager(FileAccess.GenericRead | FileAccess.GenericWrite))
                    {
                        fhandle.IoControl(IoCtlDeletePoints, data.Memory, data.Size, outData.Memory, outData.Size);
                    }
                }
        }
        public MemoryRegion GetAuthData()
        {
            MemoryAlloc data;
            int         dataSize;
            int         domainNameOffset;
            int         userNameOffset;
            int         passwordOffset;
            string      lDomainName = _domainName != null ? _domainName : "";
            string      lUserName   = _userName != null ? _userName : "";
            string      lPassword   = _password != null ? _password : "";

            // The structure plus the strings must be stored in the same buffer,
            // so we have to do some computation.

            domainNameOffset = Marshal.SizeOf(typeof(Msv1_0_InteractiveLogon));
            userNameOffset   = domainNameOffset + lDomainName.Length * 2;
            passwordOffset   = userNameOffset + lUserName.Length * 2;
            dataSize         = passwordOffset + lPassword.Length * 2;
            data             = new MemoryAlloc(dataSize);

            Msv1_0_InteractiveLogon info = new Msv1_0_InteractiveLogon();

            info.MessageType = Msv1_0_LogonSubmitType.Interactive;

            info.LogonDomainName.MaximumLength = info.LogonDomainName.Length = (ushort)(lDomainName.Length * 2);
            info.LogonDomainName.Buffer        = data.Memory.Increment(domainNameOffset);
            data.WriteUnicodeString(domainNameOffset, lDomainName);

            info.UserName.MaximumLength = info.UserName.Length = (ushort)(lUserName.Length * 2);
            info.UserName.Buffer        = data.Memory.Increment(userNameOffset);
            data.WriteUnicodeString(userNameOffset, lUserName);

            info.Password.MaximumLength = info.Password.Length = (ushort)(lPassword.Length * 2);
            info.Password.Buffer        = data.Memory.Increment(passwordOffset);
            data.WriteUnicodeString(passwordOffset, lPassword);

            data.WriteStruct <Msv1_0_InteractiveLogon>(info);

            return(data);
        }
示例#15
0
        public static bool Wait(string name, long timeout, bool relative)
        {
            using (var npfsHandle = new FileHandle(
                       Win32.NamedPipePath + "\\",
                       FileShareMode.ReadWrite,
                       FileCreateOptions.SynchronousIoNonAlert,
                       FileAccess.ReadAttributes | (FileAccess)StandardRights.Synchronize
                       ))
            {
                using (var data = new MemoryAlloc(FilePipeWaitForBuffer.NameOffset + name.Length * 2))
                {
                    FilePipeWaitForBuffer info = new FilePipeWaitForBuffer();

                    info.Timeout          = timeout;
                    info.TimeoutSpecified = true;
                    info.NameLength       = name.Length * 2;
                    data.WriteStruct <FilePipeWaitForBuffer>(info);
                    data.WriteUnicodeString(FilePipeWaitForBuffer.NameOffset, name);

                    NtStatus status;
                    int      returnLength;

                    status = npfsHandle.FsControl(FsCtlWait, data, data.Size, IntPtr.Zero, 0, out returnLength);

                    if (status == NtStatus.IoTimeout)
                    {
                        return(false);
                    }

                    if (status >= NtStatus.Error)
                    {
                        Win32.Throw(status);
                    }

                    return(true);
                }
            }
        }
        public SymbolInformation GetSymbolFromName(string symbolName)
        {
            using (MemoryAlloc data = new MemoryAlloc(SymbolInfo.SizeOf + _maxNameLen))
            {
                SymbolInfo info = new SymbolInfo
                {
                    SizeOfStruct = SymbolInfo.SizeOf,
                    MaxNameLen   = _maxNameLen - 1
                };

                data.WriteStruct(info);

                using (Win32.DbgHelpLock.AcquireContext())
                {
                    if (!Win32.SymFromName(_handle, symbolName, data))
                    {
                        Win32.Throw();
                    }
                }

                return(new SymbolInformation(data, 0));
            }
        }
        public MemoryRegion GetAuthData()
        {
            string lDomainName = !string.IsNullOrEmpty(_domainName) ? _domainName : string.Empty;
            string lUserName   = !string.IsNullOrEmpty(_userName) ? _userName : string.Empty;
            string lPassword   = !string.IsNullOrEmpty(_password) ? _password : string.Empty;

            // The structure plus the strings must be stored in the same buffer,
            // so we have to do some computation.

            int domainNameOffset = Msv1_0_InteractiveLogon.SizeOf;
            int userNameOffset   = domainNameOffset + lDomainName.Length * 2;
            int passwordOffset   = userNameOffset + lUserName.Length * 2;
            int dataSize         = passwordOffset + lPassword.Length * 2;

            MemoryAlloc data = new MemoryAlloc(dataSize);

            Msv1_0_InteractiveLogon info = new Msv1_0_InteractiveLogon
            {
                MessageType = Msv1_0_LogonSubmitType.Interactive
            };

            info.LogonDomainName.MaximumLength = info.LogonDomainName.Length = (ushort)(lDomainName.Length * 2);
            info.LogonDomainName.Buffer        = data.Memory.Increment(domainNameOffset);
            data.WriteUnicodeString(domainNameOffset, lDomainName);

            info.UserName.MaximumLength = info.UserName.Length = (ushort)(lUserName.Length * 2);
            info.UserName.Buffer        = data.Memory.Increment(userNameOffset);
            data.WriteUnicodeString(userNameOffset, lUserName);

            info.Password.MaximumLength = info.Password.Length = (ushort)(lPassword.Length * 2);
            info.Password.Buffer        = data.Memory.Increment(passwordOffset);
            data.WriteUnicodeString(passwordOffset, lPassword);

            data.WriteStruct(info);

            return(data);
        }
        public SymbolInformation GetSymbolFromName(string symbolName)
        {
            using (MemoryAlloc data = new MemoryAlloc(SymbolInfo.SizeOf + _maxNameLen))
            {
                SymbolInfo info = new SymbolInfo
                {
                    SizeOfStruct = SymbolInfo.SizeOf, 
                    MaxNameLen = _maxNameLen - 1
                };

                data.WriteStruct(info);

                using (Win32.DbgHelpLock.AcquireContext())
                {
                    if (!Win32.SymFromName(_handle, symbolName, data))
                        Win32.Throw();
                }

                return new SymbolInformation(data, 0);
            }
        }
示例#19
0
        public static string GetVolumeName(string deviceName)
        {
            using (MemoryAlloc data = new MemoryAlloc(MountMgrMountPoint.SizeOf + deviceName.Length * 2))
            {
                MountMgrMountPoint mountPoint = new MountMgrMountPoint
                {
                    DeviceNameLength = (ushort)(deviceName.Length * 2),
                    DeviceNameOffset = MountMgrMountPoint.SizeOf
                };

                data.WriteStruct(mountPoint);
                data.WriteUnicodeString(mountPoint.DeviceNameOffset, deviceName);

                using (var fhandle = OpenMountManager((FileAccess)StandardRights.Synchronize))
                {
                    NtStatus status;
                    int      retLength;

                    using (MemoryAlloc outData = new MemoryAlloc(0x100))
                    {
                        while (true)
                        {
                            status = fhandle.IoControl(
                                IoCtlQueryPoints,
                                data.Memory,
                                data.Size,
                                outData.Memory,
                                outData.Size,
                                out retLength
                                );

                            if (status == NtStatus.BufferOverflow)
                            {
                                outData.ResizeNew(Marshal.ReadInt32(outData.Memory)); // read Size field
                                continue;
                            }
                            else
                            {
                                break;
                            }
                        }

                        status.ThrowIf();

                        MountMgrMountPoints mountPoints = outData.ReadStruct <MountMgrMountPoints>();

                        // Go through the mount points given and return the first symbolic link that seems
                        // to be a volume name.
                        for (int i = 0; i < mountPoints.NumberOfMountPoints; i++)
                        {
                            MountMgrMountPoint mp = outData.ReadStruct <MountMgrMountPoint>(
                                MountMgrMountPoints.MountPointsOffset,
                                MountMgrMountPoint.SizeOf,
                                i
                                );

                            string symLinkName = Marshal.PtrToStringUni(
                                outData.Memory.Increment(mp.SymbolicLinkNameOffset),
                                mp.SymbolicLinkNameLength / 2
                                );

                            if (IsVolumePath(symLinkName))
                            {
                                return(symLinkName);
                            }
                        }

                        return(null);
                    }
                }
            }
        }
        public string GetSymbolFromAddress(ulong address, out SymbolResolveLevel level, out SymbolFlags flags, out string fileName, out string symbolName, out ulong displacement)
        {
            // Assume failure (and stop the compiler from complaining).
            if (address == 0)
            {
                level = SymbolResolveLevel.Invalid;
                flags = 0;
                fileName = null;
            }

            // Allocate some memory for the symbol information.
            using (MemoryAlloc data = new MemoryAlloc(SymbolInfo.SizeOf + _maxNameLen))
            {
                SymbolInfo info = new SymbolInfo
                {
                    SizeOfStruct = SymbolInfo.SizeOf, 
                    MaxNameLen = _maxNameLen - 1
                };

                data.WriteStruct(info);

                // Hack for drivers, since we don't get their module sizes. 
                // Preloading modules will fix this.
                if (this.PreloadModules)
                {
                    ulong b;

                    this.GetModuleFromAddress(address, out b);

                    using (Win32.DbgHelpLock.AcquireContext())
                        Win32.SymFromAddr(_handle, b, out displacement, data);

                    Marshal.StructureToPtr(info, data, false);
                }

                // Get the symbol name.
                using (Win32.DbgHelpLock.AcquireContext())
                {
                    if (Win32.SymFromAddr(_handle, address, out displacement, data))
                    {
                        info = data.ReadStruct<SymbolInfo>();
                    }
                }

                string modFileName;
                ulong modBase;

                // Get the module name.
                if (info.ModBase == 0)
                {
                    modFileName = this.GetModuleFromAddress(address, out modBase);
                }
                else
                {
                    modBase = info.ModBase;

                    lock (_modules)
                        modFileName = _modules.Find(kvp => kvp.Key == info.ModBase).Value;
                }

                // If we don't have a module name, return an address.
                if (string.IsNullOrEmpty(modFileName))
                {
                    level = SymbolResolveLevel.Address;
                    flags = 0;
                    fileName = null;
                    symbolName = null;

                    return Utils.FormatAddress(address);
                }

                FileInfo fi = null;

                fileName = modFileName;

                try
                {
                    fi = new FileInfo(modFileName);
                    fileName = fi.FullName;
                }
                catch
                { }

                // If we have a module name but not a symbol name, 
                // return a module plus an offset: module+offset.
                if (info.NameLen == 0)
                {
                    level = SymbolResolveLevel.Module;
                    flags = 0;
                    symbolName = null;

                    if (fi != null)
                    {
                        return fi.Name + "+0x" + (address - modBase).ToString("x");
                    }

                    var s = modFileName.Split('\\');

                    return s[s.Length - 1] + "+0x" + (address - modBase).ToString("x");
                }

                // If we have everything, return the full symbol name: module!symbol+offset.
                string name = data.ReadAnsiString(SymbolInfo.NameOffset, info.NameLen);

                level = SymbolResolveLevel.Function;
                flags = info.Flags;
                symbolName = name;

                if (displacement == 0)
                    return fi.Name + "!" + name;

                return fi.Name + "!" + name + "+0x" + displacement.ToString("x");
            }
        }
        public MemoryRegion GetAuthData()
        {
            string lDomainName = !string.IsNullOrEmpty(_domainName) ? _domainName : string.Empty;
            string lUserName = !string.IsNullOrEmpty(_userName) ? _userName : string.Empty;
            string lPassword = !string.IsNullOrEmpty(_password) ? _password : string.Empty;

            // The structure plus the strings must be stored in the same buffer, 
            // so we have to do some computation.

            int domainNameOffset = Msv1_0_InteractiveLogon.SizeOf;
            int userNameOffset = domainNameOffset + lDomainName.Length * 2;
            int passwordOffset = userNameOffset + lUserName.Length * 2;
            int dataSize = passwordOffset + lPassword.Length * 2;

            MemoryAlloc data = new MemoryAlloc(dataSize);

            Msv1_0_InteractiveLogon info = new Msv1_0_InteractiveLogon
            {
                MessageType = Msv1_0_LogonSubmitType.Interactive
            };

            info.LogonDomainName.MaximumLength = info.LogonDomainName.Length = (ushort)(lDomainName.Length * 2);
            info.LogonDomainName.Buffer = data.Memory.Increment(domainNameOffset);
            data.WriteUnicodeString(domainNameOffset, lDomainName);

            info.UserName.MaximumLength = info.UserName.Length = (ushort)(lUserName.Length * 2);
            info.UserName.Buffer = data.Memory.Increment(userNameOffset);
            data.WriteUnicodeString(userNameOffset, lUserName);

            info.Password.MaximumLength = info.Password.Length = (ushort)(lPassword.Length * 2);
            info.Password.Buffer = data.Memory.Increment(passwordOffset);
            data.WriteUnicodeString(passwordOffset, lPassword);

            data.WriteStruct(info);

            return data;
        }
示例#22
0
        private static void Notify(bool created, string sourceVolumeName, string targetVolumeName)
        {
            using (MemoryAlloc data = new MemoryAlloc(
                MountMgrVolumeMountPoint.SizeOf +
                sourceVolumeName.Length * 2 +
                targetVolumeName.Length * 2
                ))
            {
                MountMgrVolumeMountPoint mountPoint = new MountMgrVolumeMountPoint
                {
                    SourceVolumeNameLength = (ushort)(sourceVolumeName.Length * 2), 
                    SourceVolumeNameOffset = (ushort)MountMgrVolumeMountPoint.SizeOf, 
                    TargetVolumeNameLength = (ushort)(targetVolumeName.Length * 2)
                };

                mountPoint.TargetVolumeNameOffset = (ushort)(mountPoint.SourceVolumeNameOffset + mountPoint.SourceVolumeNameLength);

                data.WriteStruct(mountPoint);
                data.WriteUnicodeString(mountPoint.SourceVolumeNameOffset, sourceVolumeName);
                data.WriteUnicodeString(mountPoint.TargetVolumeNameOffset, targetVolumeName);

                using (FileHandle fhandle = OpenMountManager(FileAccess.GenericRead | FileAccess.GenericWrite))
                {
                    fhandle.IoControl(
                        created ? IoCtlVolumeMountPointCreated : IoCtlVolumeMountPointDeleted,
                        data.Memory,
                        data.Size,
                        IntPtr.Zero,
                        0
                        );
                }
            }
        }
示例#23
0
        public static string GetVolumeName(string deviceName)
        {
            using (MemoryAlloc data = new MemoryAlloc(MountMgrMountPoint.SizeOf + deviceName.Length * 2))
            {
                MountMgrMountPoint mountPoint = new MountMgrMountPoint
                {
                    DeviceNameLength = (ushort)(deviceName.Length*2), 
                    DeviceNameOffset = MountMgrMountPoint.SizeOf
                };

                data.WriteStruct(mountPoint);
                data.WriteUnicodeString(mountPoint.DeviceNameOffset, deviceName);

                using (var fhandle = OpenMountManager((FileAccess)StandardRights.Synchronize))
                {
                    NtStatus status;
                    int retLength;

                    using (MemoryAlloc outData = new MemoryAlloc(0x100))
                    {
                        while (true)
                        {
                            status = fhandle.IoControl(
                                IoCtlQueryPoints,
                                data.Memory,
                                data.Size,
                                outData.Memory,
                                outData.Size,
                                out retLength
                                );

                            if (status == NtStatus.BufferOverflow)
                            {
                                outData.ResizeNew(Marshal.ReadInt32(outData.Memory)); // read Size field
                                continue;
                            }
                            else
                            {
                                break;
                            }
                        }

                        status.ThrowIf();

                        MountMgrMountPoints mountPoints = outData.ReadStruct<MountMgrMountPoints>();

                        // Go through the mount points given and return the first symbolic link that seems 
                        // to be a volume name.
                        for (int i = 0; i < mountPoints.NumberOfMountPoints; i++)
                        {
                            MountMgrMountPoint mp = outData.ReadStruct<MountMgrMountPoint>(
                                MountMgrMountPoints.MountPointsOffset,
                                MountMgrMountPoint.SizeOf,
                                i
                                );

                            string symLinkName = Marshal.PtrToStringUni(
                                outData.Memory.Increment(mp.SymbolicLinkNameOffset),
                                mp.SymbolicLinkNameLength / 2
                                );

                            if (IsVolumePath(symLinkName))
                                return symLinkName;
                        }

                        return null;
                    }
                }
            }
        }
示例#24
0
        private static void DeleteSymbolicLink(string path)
        {
            using (MemoryAlloc data = new MemoryAlloc(MountMgrMountPoint.SizeOf + path.Length * 2))
            using (MemoryAlloc outData = new MemoryAlloc(1600))
            {
                MountMgrMountPoint mountPoint = new MountMgrMountPoint
                {
                    SymbolicLinkNameLength = (ushort)(path.Length*2), 
                    SymbolicLinkNameOffset = MountMgrMountPoint.SizeOf
                };

                data.WriteStruct(mountPoint);
                data.WriteUnicodeString(mountPoint.SymbolicLinkNameOffset, path);

                using (var fhandle = OpenMountManager(FileAccess.GenericRead | FileAccess.GenericWrite))
                {
                    fhandle.IoControl(IoCtlDeletePoints, data.Memory, data.Size, outData.Memory, outData.Size);
                }
            }
        }
示例#25
0
        public MemoryAlloc ToMemory()
        {
            MemoryAlloc data = new MemoryAlloc(PortMessageStruct.SizeOf + _message.DataLength);

            data.WriteStruct(_message);
            data.WriteMemory(PortMessageStruct.SizeOf, _data, _message.DataLength);

            return data;
        }
示例#26
0
        public static bool Wait(string name, long timeout, bool relative)
        {
            using (var npfsHandle = new FileHandle(
                Win32.NamedPipePath + "\\",
                FileShareMode.ReadWrite,
                FileCreateOptions.SynchronousIoNonAlert,
                FileAccess.ReadAttributes | (FileAccess)StandardRights.Synchronize
                ))
            {
                using (var data = new MemoryAlloc(FilePipeWaitForBuffer.NameOffset + name.Length * 2))
                {
                    FilePipeWaitForBuffer info = new FilePipeWaitForBuffer();

                    info.Timeout = timeout;
                    info.TimeoutSpecified = true;
                    info.NameLength = name.Length * 2;
                    data.WriteStruct<FilePipeWaitForBuffer>(info);
                    data.WriteUnicodeString(FilePipeWaitForBuffer.NameOffset, name);

                    NtStatus status;
                    int returnLength;

                    status = npfsHandle.FsControl(FsCtlWait, data, data.Size, IntPtr.Zero, 0, out returnLength);

                    if (status == NtStatus.IoTimeout)
                        return false;

                    if (status >= NtStatus.Error)
                        Win32.ThrowLastError(status);

                    return true;
                }
            }
        }
示例#27
0
        public MemoryAlloc ToMemory()
        {
            MemoryAlloc data = new MemoryAlloc(_portMessageSize + _message.DataLength);

            data.WriteStruct<PortMessageStruct>(_message);
            data.WriteMemory(_portMessageSize, _data, 0, _message.DataLength);

            return data;
        }
        public string GetSymbolFromAddress(ulong address, out SymbolResolveLevel level, out SymbolFlags flags, out string fileName, out string symbolName, out ulong displacement)
        {
            // Assume failure (and stop the compiler from complaining).
            if (address == 0)
            {
                level    = SymbolResolveLevel.Invalid;
                flags    = 0;
                fileName = null;
            }

            // Allocate some memory for the symbol information.
            using (MemoryAlloc data = new MemoryAlloc(SymbolInfo.SizeOf + _maxNameLen))
            {
                SymbolInfo info = new SymbolInfo
                {
                    SizeOfStruct = SymbolInfo.SizeOf,
                    MaxNameLen   = _maxNameLen - 1
                };

                data.WriteStruct(info);

                // Hack for drivers, since we don't get their module sizes.
                // Preloading modules will fix this.
                if (this.PreloadModules)
                {
                    ulong b;

                    this.GetModuleFromAddress(address, out b);

                    using (Win32.DbgHelpLock.AcquireContext())
                        Win32.SymFromAddr(_handle, b, out displacement, data);

                    Marshal.StructureToPtr(info, data, false);
                }

                // Get the symbol name.
                using (Win32.DbgHelpLock.AcquireContext())
                {
                    if (Win32.SymFromAddr(_handle, address, out displacement, data))
                    {
                        info = data.ReadStruct <SymbolInfo>();
                    }
                }

                string modFileName;
                ulong  modBase;

                // Get the module name.
                if (info.ModBase == 0)
                {
                    modFileName = this.GetModuleFromAddress(address, out modBase);
                }
                else
                {
                    modBase = info.ModBase;

                    lock (_modules)
                        modFileName = _modules.Find(kvp => kvp.Key == info.ModBase).Value;
                }

                // If we don't have a module name, return an address.
                if (string.IsNullOrEmpty(modFileName))
                {
                    level      = SymbolResolveLevel.Address;
                    flags      = 0;
                    fileName   = null;
                    symbolName = null;

                    return(Utils.FormatAddress(address));
                }

                FileInfo fi = null;

                fileName = modFileName;

                try
                {
                    fi       = new FileInfo(modFileName);
                    fileName = fi.FullName;
                }
                catch
                { }

                // If we have a module name but not a symbol name,
                // return a module plus an offset: module+offset.
                if (info.NameLen == 0)
                {
                    level      = SymbolResolveLevel.Module;
                    flags      = 0;
                    symbolName = null;

                    if (fi != null)
                    {
                        return(fi.Name + "+0x" + (address - modBase).ToString("x"));
                    }

                    var s = modFileName.Split('\\');

                    return(s[s.Length - 1] + "+0x" + (address - modBase).ToString("x"));
                }

                // If we have everything, return the full symbol name: module!symbol+offset.
                string name = data.ReadAnsiString(SymbolInfo.NameOffset, info.NameLen);

                level      = SymbolResolveLevel.Function;
                flags      = info.Flags;
                symbolName = name;

                if (displacement == 0)
                {
                    return(fi.Name + "!" + name);
                }

                return(fi.Name + "!" + name + "+0x" + displacement.ToString("x"));
            }
        }