public uint mciSendCommand(ushort uDeviceId, ushort uMessage, uint dwParam1, uint dwParam2) { switch (uMessage) { case Win16.MCI_OPEN: { using (var ctx = new TempContext(_machine)) { var op16 = _machine.ReadStruct <Win16.MCI_OPEN_PARAMS>(dwParam2); var op32 = new Win32.MCI_OPEN_PARAMS(); // Convert type if ((dwParam1 & Win16.MCI_OPEN_TYPE) != 0) { if ((dwParam1 & Win16.MCI_OPEN_TYPE_ID) != 0) { op32.lpstrDeviceName = BitUtils.DWordToIntPtr(op16.lpstrDeviceName); } else { op32.lpstrDeviceName = ctx.AllocUnmanagedString(_machine.ReadString(op16.lpstrDeviceName)); } } // Convert element if ((dwParam1 & Win16.MCI_OPEN_ELEMENT) != 0) { if ((dwParam1 & Win16.MCI_OPEN_ELEMENT_ID) != 0) { op32.lpstrElementName = BitUtils.DWordToIntPtr(op16.lpstrElementName); } else { op32.lpstrElementName = ctx.AllocUnmanagedString(ResolveMediaFile(_machine.ReadString(op16.lpstrElementName))); } } // Convert element if ((dwParam1 & Win16.MCI_OPEN_ALIAS) != 0) { op32.lpstrAlias = Marshal.StringToHGlobalUni(_machine.ReadString(op16.lpstrAlias)); } // Callback if (HWND.Map.IsValid16(op16.dwCallback.Loword())) { op32.dwCallback = HWND.Map.To32(op16.dwCallback.Loword()); } // Open unsafe { Win32.MCI_OPEN_PARAMS *p = &op32; uint retv = mciSendCommand(uDeviceId, Win32.MCI_OPEN, (IntPtr)dwParam1, (IntPtr)p); if (retv == 0) { op16.wDeviceID = DeviceIdTo16(op32.nDeviceID); } else { op16.wDeviceID = 0; } _machine.WriteStruct(dwParam2, op16); return(retv); } } } case Win16.MCI_CLOSE: { if (dwParam2 == 0) { return(mciSendCommand(DeviceIdTo32(uDeviceId), Win32.MCI_CLOSE, (IntPtr)dwParam1, IntPtr.Zero)); } else { var st16 = _machine.ReadStruct <Win16.MCI_GENERIC_PARAMS>(dwParam2); var st32 = new Win32.MCI_GENERIC_PARAMS(); if (HWND.Map.IsValid16(st16.dwCallback.Loword())) { st32.dwCallback = HWND.Map.To32(st16.dwCallback.Loword()); } unsafe { return(mciSendCommand(DeviceIdTo32(uDeviceId), Win32.MCI_CLOSE, (IntPtr)dwParam1, (IntPtr)(&st32))); } } } case Win16.MCI_PLAY: { var st16 = _machine.ReadStruct <Win16.MCI_PLAY_PARAMS>(dwParam2); var st32 = new Win32.MCI_PLAY_PARAMS(); st32.dwFrom = st16.dwFrom; st32.dwTo = st16.dwTo; if (HWND.Map.IsValid16(st16.dwCallback.Loword())) { st32.dwCallback = HWND.Map.To32(st16.dwCallback.Loword()); } unsafe { return(mciSendCommand(DeviceIdTo32(uDeviceId), Win32.MCI_PLAY, (IntPtr)dwParam1, (IntPtr)(&st32))); } } case Win16.MCI_STATUS: { var st16 = _machine.ReadStruct <Win16.MCI_STATUS_PARAMS>(dwParam2); var st32 = new Win32.MCI_STATUS_PARAMS(); st32.dwItem = st16.dwItem; st32.dwTrack = st16.dwTrack; if (HWND.Map.IsValid16(st16.dwCallback.Loword())) { st32.dwCallback = HWND.Map.To32(st16.dwCallback.Loword()); } unsafe { uint retv = mciSendCommand(DeviceIdTo32(uDeviceId), Win32.MCI_STATUS, (IntPtr)dwParam1, (IntPtr)(&st32)); st16.dwReturn = st32.dwReturn.DWord(); _machine.WriteStruct(dwParam2, st16); return(retv); } } } throw new NotImplementedException($"[mciSendCommand] Unsupported MCI command: 0x{uMessage:X4}"); }
ushort DeviceIdTo16(uint deviceId) { return(_mciDeviceIdMap.To16(BitUtils.DWordToIntPtr(deviceId))); }
public uint GlobalLock(ushort handle) { return(BitUtils.MakeDWord(0, handle)); }
public IntPtr CallWndProc16from32(uint pfnProc, IntPtr hWnd, uint message, IntPtr wParam, IntPtr lParam, bool dlgProc) { // Package it var msg32 = new Win32.MSG() { hWnd = hWnd, message = message, wParam = wParam, lParam = lParam, }; if (_machine.IsStoppedInDebugger) { if (dlgProc) { return(IntPtr.Zero); } return(User.DefWindowProc(hWnd, message, wParam, lParam)); } // Call filters for (int i = 0; i < _wndProcFilters.Count; i++) { var f = _wndProcFilters[i]; var retv = f.PreWndProc(pfnProc, ref msg32, dlgProc); if (retv.HasValue) { return(retv.Value); } } // Log messages? if (_machine.logMessages) { Log.WriteLine("Message: [{4}] hWnd: {0} message:{1} wParam:{2} lParam:{3}", (HWND)hWnd, MessageNames.NameOfMessage(message), wParam, lParam, User.GetTickCount()); } ushort message16; var sem = TryGetMessageSemantics32(hWnd, message, out message16); var msg16 = new Win16.MSG() { hWnd = HWND.Map.To16(hWnd), message = message16, }; if (sem != null && sem.ShouldBypass(_machine, ref msg32)) { if (dlgProc) { return(IntPtr.Zero); } // Unsupported message - sneak it through var bpm = AllocBypassMessage(message, wParam, lParam); var ret = _machine.CallWndProc16(pfnProc, HWND.Map.To16(hWnd), Win16.WM_WIN3MU_BYPASS16, 0, bpm.id); return(FreeBypassMessage(bpm)); } var postable = sem as MessageSemantics.Postable; if (postable != null) { // Convert it postable.To16(_machine, ref msg32, ref msg16); // Call it var x = _machine.CallWndProc16(pfnProc, msg16.hWnd, msg16.message, msg16.wParam, msg16.lParam); if (dlgProc) { x = x.Loword(); } return(BitUtils.DWordToIntPtr(x)); } // Callable? var callable = sem as MessageSemantics.Callable; if (callable != null) { var x = callable.Call16from32(_machine, false, dlgProc, ref msg32, ref msg16, () => { return(_machine.CallWndProc16(pfnProc, msg16.hWnd, msg16.message, msg16.wParam, msg16.lParam)); }); if (dlgProc) { x = (IntPtr)(x.ToInt32().Loword()); // If not handled by dialog proc and ctlcolor message, switch to white if (x == IntPtr.Zero) { bool recolor = false; switch (message) { case Win32.WM_CTLCOLORDLG: case Win32.WM_CTLCOLORSTATIC: case Win32.WM_CTLCOLORBTN: recolor = true; break; } if (recolor) { Gdi.SetTextColor(wParam, User._GetSysColor(Win32.COLOR_WINDOWTEXT)); x = User.GetSysColorBrush(Win32.COLOR_WINDOW); } } } return(x); } MessageMap.ThrowMessageError(hWnd, message); throw new NotImplementedException(); }
public uint GetDosEnvironment() { return(BitUtils.MakeDWord(0, _machine.GetDosEnvironmentSegment())); }