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)); } }
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); }
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); } } }
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); }
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)); }
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; */ }