Exemple #1
0
        public IEnumerable <StackEntry> WalkStack()
        {
            if (_machine.cs == 0 || _machine.ss == 0)
            {
                return(Enumerable.Empty <StackEntry>());
            }

            var list = new List <StackEntry>();

            list.Add(new StackEntry()
            {
                csip = BitUtils.MakeDWord(_machine.ip, _machine.cs),
                sp   = _machine.sp,
                name = "cs:ip",
            });
            try
            {
                var ss = _machine.ss;
                var bp = _machine.bp;
                var cs = _machine.cs;
                while (true)
                {
                    var priorBP = _machine.MemoryBus.ReadWord(ss, bp);
                    if (priorBP <= bp)
                    {
                        break;
                    }
                    uint returnAddress;
                    bool farCall;
                    if ((priorBP & 1) != 0)
                    {
                        // far call
                        returnAddress = _machine.MemoryBus.ReadDWord(ss, (ushort)(bp + 2));
                        priorBP       = (ushort)(priorBP & ~1);
                        cs            = (ushort)(returnAddress >> 16);
                        farCall       = true;
                    }
                    else
                    {
                        // near call
                        returnAddress = (uint)(cs << 16 | _machine.MemoryBus.ReadWord(ss, (ushort)(bp + 2)));
                        farCall       = false;
                    }
                    list.Add(new StackEntry()
                    {
                        csip = returnAddress,
                        sp   = bp,
                        name = string.Format("0x{0:X4}:{1:X4} {2} call bp = 0x{3:X4}",
                                             returnAddress.Hiword(), returnAddress.Loword(),
                                             farCall ? "far" : "near", bp),
                    });
                    bp = priorBP;
                }
                return(list.Concat(_transitions).OrderBy(x => x.sp));
            }
            catch
            {
                return(list.Concat(_transitions).OrderBy(x => x.sp));
            }
        }
Exemple #2
0
        public uint GetString(string str)
        {
            if (str == null)
            {
                return(0);
            }

            // Already allocated?
            uint ptr;

            if (_strings.TryGetValue(str, out ptr))
            {
                return(ptr);
            }

            // First time?
            if (_mem == 0)
            {
                _mem = _machine.GlobalHeap.Alloc("System String Heap", 0, 0x10000);
            }

            // Get the buffer and put the string in it
            var buf = _machine.GlobalHeap.GetBuffer(_mem, true);
            int len = buf.WriteString(_ofs, str);

            // Work out pointer for this string
            ptr = BitUtils.MakeDWord(_ofs, _mem);
            _strings.Add(str, ptr);

            // Update high water
            _ofs += (ushort)(len + 1);

            return(ptr);
        }
Exemple #3
0
        public uint SetWindowExt(HDC hDC, short x, short y)
        {
            Win32.SIZE size;
            SetWindowExtEx(hDC, x, y, out size);

            return(BitUtils.MakeDWord((ushort)(short)size.Width, (ushort)(short)size.Height));
        }
Exemple #4
0
 public void EnterTransition(string name)
 {
     _transitions.Add(new StackEntry()
     {
         csip = BitUtils.MakeDWord(_machine.ip, _machine.cs),
         sp   = _machine.sp,
         name = name,
     });
 }
Exemple #5
0
        public uint StackAlloc <T>(T value)
        {
            var saveSP = sp;

            sp -= (ushort)Marshal.SizeOf <T>();
            var ptr = BitUtils.MakeDWord(sp, ss);

            WriteStruct(ptr, ref value);
            return(ptr);
        }
Exemple #6
0
        public uint GetTextExtent(HDC hDC, uint pszString, short cbString)
        {
            var str = _machine.GlobalHeap.ReadCharacters(pszString, cbString);

            Win32.SIZE size;
            if (!GetTextExtentPoint(hDC, str, cbString, out size))
            {
                return(0xFFFFFFFF);
            }

            return(BitUtils.MakeDWord((ushort)(short)size.Width, (ushort)(short)size.Height));
        }
Exemple #7
0
        public uint GlobalHandle(ushort selector)
        {
            var sel = _machine.GlobalHeap.GetSelector(selector);

            if (sel == null)
            {
                return(0);
            }

            System.Diagnostics.Debug.Assert(sel.selector == selector);

            return(BitUtils.MakeDWord(selector, selector));
        }
Exemple #8
0
        public uint SysAllocString(string str)
        {
            if (str == null)
            {
                return(0);
            }

            var data     = AnsiEncoding.GetBytes(str);
            var ptr_near = _systemDataHeap.Alloc(Win16.LMEM_FIXED, (ushort)(data.Length + 1));
            var ptr_far  = BitUtils.MakeDWord(ptr_near, _systemDataHeap.GlobalHandle);

            this.WriteString(ptr_far, str, (ushort)(data.Length + 1));
            return(ptr_far);
        }
Exemple #9
0
        public ushort SetMetaFileBits(ushort handle)
        {
            if (handle == 0)
            {
                return(0);
            }

            // Get size of global allocation
            uint size = _machine.GlobalHeap.Size(handle);

            // Get pointer
            var hp = _machine.GlobalHeap.GetHeapPointer(BitUtils.MakeDWord(0, handle), false);

            var hEnhMetaFile = SetMetaFileBitsEx(size, hp);

            return(HENHMETAFILE.To16(hEnhMetaFile));
        }
Exemple #10
0
        public override void Init(Machine machine)
        {
            var autoSeg = DataSegment;

            if (IsDll)
            {
                if (_neFile.Header.EntryPoint != 0)
                {
                    var saveds = machine.ds;

                    // Call Library entry point
                    machine.di = hModule;
                    machine.ds = autoSeg == null ? (ushort)0 : autoSeg.globalHandle;
                    machine.cx = _neFile.Header.InitHeapSize;

                    // Find entry point
                    var ip = (ushort)(_neFile.Header.EntryPoint & 0xFFFF);
                    var cs = _neFile.Segments[(int)((_neFile.Header.EntryPoint >> 16) - 1)].globalHandle;

                    // Call it
                    machine.CallVM(BitUtils.MakeDWord(ip, cs), "LibMain");

                    // Restore DS
                    machine.ds = saveds;
                }
            }
            else
            {
                // Create the local heap
                if (autoSeg != null)
                {
                    var heapBaseAddress = (ushort)(autoSeg.allocationBytes + (IsDll ? 0 : _neFile.Header.InitStackSize));
                    var heapSize        = _neFile.Header.InitHeapSize;
                    machine.GlobalHeap.CreateLocalHeap(autoSeg.globalHandle, heapBaseAddress, heapSize);
                }
            }
        }
Exemple #11
0
            public uint ToDWord()
            {
                var pt16 = Convert();

                return(BitUtils.MakeDWord((ushort)pt16.X, (ushort)pt16.Y));
            }
Exemple #12
0
            object ReadParamFromStack(Type pt, ParameterInfo pi)
            {
                if (pt == null)
                {
                    pt = pi.ParameterType;
                }

                if (pt == typeof(ushort))
                {
                    var val = _machine.ReadWord(_machine.ss, _paramPos);
                    _paramPos += 2;
                    return(val);
                }
                if (pt == typeof(short))
                {
                    var val = unchecked ((short)_machine.ReadWord(_machine.ss, _paramPos));
                    _paramPos += 2;
                    return(val);
                }
                if (pt == typeof(byte))
                {
                    var val = _machine.ReadByte(_machine.ss, _paramPos);
                    _paramPos += 2;
                    return(val);
                }
                if (pt == typeof(uint))
                {
                    var val = _machine.ReadDWord(_machine.ss, _paramPos);
                    _paramPos += 4;
                    return(val);
                }
                if (pt == typeof(int))
                {
                    var val = unchecked ((int)_machine.ReadDWord(_machine.ss, _paramPos));
                    _paramPos += 4;
                    return(val);
                }
                if (pt == typeof(string))
                {
                    var ptrOffset = _machine.ReadWord(_machine.ss, _paramPos);
                    var ptrSeg    = _machine.ReadWord(_machine.ss, (ushort)(_paramPos + 2));
                    var val       = _machine.ReadString(ptrSeg, ptrOffset);
                    _paramPos += 4;

                    if (pi != null)
                    {
                        var fna = pi.GetCustomAttribute <FileNameAttribute>();
                        if (fna != null)
                        {
                            val = _machine.PathMapper.MapGuestToHost(val, fna.ForWrite);
                        }
                    }
                    return(val);
                }
                if (pt == typeof(StringOrId))
                {
                    var ptrOffset = _machine.ReadWord(_machine.ss, _paramPos);
                    var ptrSeg    = _machine.ReadWord(_machine.ss, (ushort)(_paramPos + 2));
                    var val       = new StringOrId(_machine, BitUtils.MakeDWord(ptrOffset, ptrSeg));
                    _paramPos += 4;
                    return(val);
                }
                if (pt == typeof(bool))
                {
                    var val = _machine.ReadWord(_machine.ss, _paramPos) != 0;
                    _paramPos += 2;
                    return(val);
                }
                if (pt == typeof(StringBuilder))
                {
                    // Capture stuff, we'll do it later
                    int paramIndex = _currentParameterIndex;

                    // Get input string pointer
                    var ptrOffset = _machine.ReadWord(_machine.ss, _paramPos);
                    var ptrSeg    = _machine.ReadWord(_machine.ss, (ushort)(_paramPos + 2));
                    _paramPos += 4;
                    int  capacity = 0;
                    bool isOut    = pi.GetCustomAttribute <OutAttribute>() != null;
                    bool isIn     = pi.GetCustomAttribute <InAttribute>() != null;
                    var  fna      = pi.GetCustomAttribute <FileNameAttribute>();

                    RegisterPreInvokeCallback(() =>
                    {
                        // Work out buffer size capacity
                        var bufsize           = pi.GetCustomAttribute <BufSizeAttribute>();
                        int bufsizeParamIndex = paramIndex + bufsize.ParamDX;

                        var type = _paramValues[bufsizeParamIndex].GetType();
                        if (type == typeof(int))
                        {
                            capacity = (int)_paramValues[bufsizeParamIndex];
                        }
                        else if (type == typeof(ushort))
                        {
                            capacity = (int)(ushort)_paramValues[bufsizeParamIndex];
                        }
                        else if (type == typeof(nint))
                        {
                            capacity = (nint)_paramValues[bufsizeParamIndex];
                        }
                        else
                        {
                            throw new NotImplementedException();
                        }

                        // Create string builder
                        var sb = new StringBuilder(fna != null ? 512 : capacity);

                        if (isIn)
                        {
                            var str = _machine.ReadString(ptrSeg, ptrOffset, (ushort)capacity);
                            if (fna != null)
                            {
                                _machine.PathMapper.MapGuestToHost(str, fna.ForWrite);
                            }
                            sb.Append(str);
                        }

                        // Return the string builder
                        _paramValues[paramIndex] = sb;
                    });

                    if (isOut)
                    {
                        RegisterPostInvokeCallback(() =>
                        {
                            var str = _paramValues[paramIndex].ToString();
                            if (fna != null)
                            {
                                str = _machine.PathMapper.MapHostToGuest(str, fna.ForWrite);
                            }

                            _machine.WriteString(ptrSeg, ptrOffset, str, (ushort)capacity);
                        });
                    }

                    return(null);        // We'll fill it in later
                }
                if (pt == typeof(Win32.POINT))
                {
                    var x = unchecked ((short)_machine.ReadWord(_machine.ss, _paramPos));
                    var y = unchecked ((short)_machine.ReadWord(_machine.ss, (ushort)(_paramPos + 2)));
                    _paramPos += 4;
                    return(new Win32.POINT(x, y));
                }
                if (pt == typeof(IntPtr))
                {
                    if (pi != null)
                    {
                        if (pi.GetCustomAttribute <MustBeNullAttribute>() == null)
                        {
                            throw new NotImplementedException("IntPtr parameters must have MustBeNull attribute");
                        }
                    }

                    var ptrOffset = _machine.ReadWord(_machine.ss, _paramPos);
                    var ptrSeg    = _machine.ReadWord(_machine.ss, (ushort)(_paramPos + 2));
                    _paramPos += 4;

                    if (ptrOffset != 0 || ptrSeg != 0)
                    {
                        throw new NotImplementedException("Non-null IntPtr parameter passed");
                    }

                    return(IntPtr.Zero);
                }
                if (MappedTypeAttribute.Is(pt))
                {
                    var convertMethod = pt.GetMethod("To32");

                    // Read the 16-bit value
                    var val16 = ReadParamFromStack(convertMethod.GetParameters()[0].ParameterType, null);

                    // Convert it
                    var val32 = convertMethod.Invoke(null, new object[] { val16 });

                    if (ShouldDestroy(pi))
                    {
                        RegisterPostInvokeCallback(() =>
                        {
                            var destroyMethod = pt.GetMethod("Destroy");
                            destroyMethod.Invoke(null, new object[] { val16 });
                        });
                    }

                    return(val32);
                }
                if (pt.IsByRef)
                {
                    var underlyingType = pt.GetElementType();
                    if (underlyingType.IsValueType)
                    {
                        var ptr = _machine.ReadDWord(_machine.ss, _paramPos);

                        object val;
                        if (pi == null || !pi.IsOut)
                        {
                            if (MappedTypeAttribute.Is(underlyingType))
                            {
                                var convertMethod = underlyingType.GetMethod("To32");
                                val = _machine.ReadStruct(convertMethod.GetParameters()[0].ParameterType, ptr);
                                val = convertMethod.Invoke(null, new object[] { val });
                            }
                            else
                            {
                                val = _machine.ReadStruct(underlyingType, ptr);
                            }
                        }
                        else
                        {
                            val = Activator.CreateInstance(underlyingType);
                        }


                        _paramPos += 4;

                        if (pi.GetCustomAttribute <InAttribute>() == null)
                        {
                            int index = _currentParameterIndex;
                            RegisterPostInvokeCallback(() =>
                            {
                                val = _paramValues[index];
                                if (MappedTypeAttribute.Is(underlyingType))
                                {
                                    var convertMethod = underlyingType.GetMethod("To16");
                                    val = convertMethod.Invoke(null, new object[] { val });
                                }
                                if (ptr != 0)
                                {
                                    _machine.WriteStruct(ptr, val);
                                }
                            });
                        }

                        return(val);
                    }
                }

                throw new NotImplementedException(string.Format("Parameter type not supported by thunking layer - {0}", pt));
            }
Exemple #13
0
 public uint GetFreeSpace()
 {
     return(BitUtils.MakeDWord(0, (ushort)_selectorAllocator.FreeSpace));
 }
Exemple #14
0
 public uint GlobalLock(ushort handle)
 {
     return(BitUtils.MakeDWord(0, handle));
 }
Exemple #15
0
 public uint GetDosEnvironment()
 {
     return(BitUtils.MakeDWord(0, _machine.GetDosEnvironmentSegment()));
 }