Example #1
0
        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}");
        }
Example #2
0
 ushort DeviceIdTo16(uint deviceId)
 {
     return(_mciDeviceIdMap.To16(BitUtils.DWordToIntPtr(deviceId)));
 }
Example #3
0
 public uint GlobalLock(ushort handle)
 {
     return(BitUtils.MakeDWord(0, handle));
 }
Example #4
0
        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();
        }
Example #5
0
 public uint GetDosEnvironment()
 {
     return(BitUtils.MakeDWord(0, _machine.GetDosEnvironmentSegment()));
 }