示例#1
0
        public uint GetProcAddress(ushort module, StringOrId nameOrOrdinal)
        {
            // Get the module
            var mod = module == 0 ? _machine.ProcessModule : _machine.ModuleManager.GetModule(module);

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

            // Look up by name or ordinal?
            if (nameOrOrdinal.Name != null)
            {
                var ordinal = mod.GetOrdinalFromName(nameOrOrdinal.Name);
                if (ordinal == 0)
                {
                    return(0);
                }
                return(mod.GetProcAddress(ordinal));
            }
            else
            {
                return(mod.GetProcAddress(nameOrOrdinal.ID));
            }
        }
示例#2
0
        public WindowClass(Machine machine, Module16 module, StringOrId menuID, Win32.WNDCLASS wc32, Win16.WNDCLASS wc16)
        {
            _machine      = machine;
            _module       = module;
            _menuID       = menuID;
            this.wc32     = wc32;
            this.wc16     = wc16;
            _procInstance = _machine.MakeProcInstance(module.DataSelector, wc16.lpfnWndProc);

            WndProc32 = _machine.Messaging.GetWndProc32(_procInstance, false);
        }
示例#3
0
 public static void Unregister(StringOrId name)
 {
     if (name.Name != null)
     {
         _registeredClasses.Remove(name.Name);
     }
     else
     {
         var wc = _registeredClasses.Values.FirstOrDefault(x => x.Atom == name.ID);
         if (wc != null)
         {
             _registeredClasses.Remove(wc.Name);
         }
     }
 }
示例#4
0
        public static void WriteResourceString32(this System.IO.Stream This, StringOrId value, bool extraWeirdness = false)
        {
            if (value == null)
            {
                This.WriteUInt16(0);
                return;
            }

            if (value.Name == null)
            {
                if (extraWeirdness)
                {
                    This.WriteUInt16(0xFFFF);
                }
                else
                {
                    This.WriteUInt16(0x00FF);
                }
                This.WriteUInt16(value.ID);
                return;
            }

            WriteUnicodeString(This, value.Name);
        }
示例#5
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));
            }
示例#6
0
        public ushort FindResource(ushort hInstance, StringOrId ridName, StringOrId ridType)
        {
            if (ridType.Name == null)
            {
                if (ridType.ID >= 1 && ridType.ID <= 23)
                {
                    ridType = new StringOrId(((Win16.ResourceType)ridType.ID).ToString());
                }
            }

            // Crack params
            var module = hInstance == 0 ? _machine.ProcessModule : _machine.ModuleManager.GetModule(hInstance) as Module16;

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

            // Find the resource
            var resourceEntry = module.NeFile.FindResource(ridType.ToString(), ridName.ToString());

            // hRsrc already allocated?
            ResourceInfo resInfo;

            if (_resourceEntryMap.TryGetValue(resourceEntry, out resInfo))
            {
                return(resInfo.hRsrc);
            }

            // Create a HRSRC
            while (_hrsrcMap.ContainsKey(_nextHRSRC) && _nextHRSRC < 0x100)
            {
                _nextHRSRC++;
            }

            // Create resinfo
            resInfo = new ResourceInfo()
            {
                hRsrc         = _nextHRSRC++,
                module        = module,
                refCount      = 0,
                resourceEntry = resourceEntry,
                ridName       = ridName.ToString(),
                ridType       = ridType.ToString(),
                hData         = 0,
            };

            // Add to map
            _resourceEntryMap.Add(resourceEntry, resInfo);
            _hrsrcMap.Add(resInfo.hRsrc, resInfo);

            // Return pseudo handle
            return(resInfo.hRsrc);

            /*
             * // Look for already loaded resource
             * var existing = _hrsrcInfo.FirstOrDefault(x => x.Value.resourceEntry == resourceEntry);
             * if (existing.HasVa)
             * {
             *  return existing.hInstance;
             * }
             *
             * // Load the data
             * var data = module.NeFile.LoadResource(ridType.ToString(), ridName.ToString());
             * if (data == null)
             *  return 0;
             *
             * // Map it into address space
             * string heapName = string.Format("Module '{0}' (0x{1:X4}) Resource {2} {3}", module.GetModuleName(), hInstance, ridType.ToString(), ridName.ToString());
             * hrsrc = _machine.GlobalHeap.Alloc(heapName, 0, (uint)data.Length);
             * if (hrsrc == 0)
             *  return 0;
             *
             * Buffer.BlockCopy(data, 0, _machine.GlobalHeap.GetBuffer(hrsrc, true), 0, data.Length);
             *
             * // Cache it
             * _loadedResources.Add(key, hrsrc);
             *
             * // Cache the params used to find it so that
             * _hrsrcInfo[hrsrc] = new CResourceInfo()
             * {
             *  hInstance = hInstance,
             *  ridType = ridType,
             *  ridName = ridName,
             * };
             *
             * var re = module.NeFile.FindResource(ridType.ToString(), ridName.ToString());
             * _machine.GlobalHeap.SetFileSource(hrsrc, module.NeFile.FileName, (uint)re.offset);
             *
             * // Done
             * return hrsrc;
             */
        }