Beispiel #1
0
            void SetReturnValue(Type retType, object retValue)
            {
                if (retType == typeof(ushort))
                {
                    _machine.ax = (ushort)retValue;
                    return;
                }

                if (retType == typeof(short))
                {
                    _machine.ax = unchecked ((ushort)(short)retValue);
                    return;
                }

                if (retType == typeof(uint))
                {
                    _machine.dxax = (uint)retValue;
                    return;
                }

                if (retType == typeof(int))
                {
                    _machine.dxax = unchecked ((uint)(int)retValue);
                    return;
                }

                if (retType == typeof(bool))
                {
                    _machine.ax = (ushort)(((bool)retValue) ? 1U : 0U);
                    return;
                }

                if (retType == typeof(void))
                {
                    // nop
                    return;
                }

                if (MappedTypeAttribute.Is(retType))
                {
                    var convertMethod = retType.GetMethod("To16");
                    var retValue16    = convertMethod.Invoke(null, new object[] { retValue });
                    SetReturnValue(convertMethod.ReturnType, retValue16);
                    return;
                }

                throw new NotImplementedException(string.Format("Return type not supported by thunking layer - {0}", retType));
            }
Beispiel #2
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));
            }
Beispiel #3
0
 ushort SizeOfType16(Type pt)
 {
     if (pt == typeof(ushort))
     {
         return(2);
     }
     if (pt == typeof(short))
     {
         return(2);
     }
     if (pt == typeof(byte))
     {
         return(2);
     }
     if (pt == typeof(uint))
     {
         return(4);
     }
     if (pt == typeof(int))
     {
         return(4);
     }
     if (pt == typeof(string))
     {
         return(4);
     }
     if (pt == typeof(StringOrId))
     {
         return(4);
     }
     if (pt.IsByRef)
     {
         return(4);
     }
     if (pt == typeof(bool))
     {
         return(2);
     }
     if (pt == typeof(StringBuilder))
     {
         return(4);
     }
     if (pt == typeof(IntPtr))
     {
         return(4);
     }
     if (pt == typeof(Win32.POINT))
     {
         return(4);
     }
     if (pt == typeof(Win16.RECT))
     {
         return(8);
     }
     if (MappedTypeAttribute.Is(pt))
     {
         var convertMethod = pt.GetMethod("To32");
         return(SizeOfType16(convertMethod.GetParameters()[0].ParameterType));
     }
     throw new NotImplementedException(string.Format("Type not supported by thunking layer - {0}", pt));
 }