From e9653f102906fc7788a0d272897d2d8964235fba Mon Sep 17 00:00:00 2001
From: Nekotekina <fbx@3mf.ru>
Date: Fri, 19 Dec 2014 02:18:44 +0300
Subject: [PATCH] cellMsgDialogOpen2(): argument checking improved

---
 rpcs3/Emu/SysCalls/Modules/cellMsgDialog.cpp | 103 +++++++++++++------
 rpcs3/Emu/SysCalls/Modules/cellMsgDialog.h   |  37 +++----
 rpcs3/Gui/MsgDialog.cpp                      |   7 +-
 rpcs3/rpcs3.cpp                              |  58 +++++------
 4 files changed, 112 insertions(+), 93 deletions(-)

diff --git a/rpcs3/Emu/SysCalls/Modules/cellMsgDialog.cpp b/rpcs3/Emu/SysCalls/Modules/cellMsgDialog.cpp
index 7fef155e89..1f0e1d7feb 100644
--- a/rpcs3/Emu/SysCalls/Modules/cellMsgDialog.cpp
+++ b/rpcs3/Emu/SysCalls/Modules/cellMsgDialog.cpp
@@ -32,29 +32,13 @@ MsgDialogProgressBarSetMsgCb MsgDialogProgressBarSetMsg = nullptr;
 MsgDialogProgressBarResetCb MsgDialogProgressBarReset = nullptr;
 MsgDialogProgressBarIncCb MsgDialogProgressBarInc = nullptr;
 
-void SetMsgDialogCreateCallback(MsgDialogCreateCb cb)
+void SetMsgDialogCallbacks(MsgDialogCreateCb ccb, MsgDialogDestroyCb dcb, MsgDialogProgressBarSetMsgCb pbscb, MsgDialogProgressBarResetCb pbrcb, MsgDialogProgressBarIncCb pbicb)
 {
-	MsgDialogCreate = cb;
-}
-
-void SetMsgDialogDestroyCallback(MsgDialogDestroyCb cb)
-{
-	MsgDialogDestroy = cb;
-}
-
-void SetMsgDialogProgressBarSetMsgCallback(MsgDialogProgressBarSetMsgCb cb)
-{
-	MsgDialogProgressBarSetMsg = cb;
-}
-
-void SetMsgDialogProgressBarResetCallback(MsgDialogProgressBarResetCb cb)
-{
-	MsgDialogProgressBarReset = cb;
-}
-
-void SetMsgDialogProgressBarIncCallback(MsgDialogProgressBarIncCb cb)
-{
-	MsgDialogProgressBarInc = cb;
+	MsgDialogCreate = ccb;
+	MsgDialogDestroy = dcb;
+	MsgDialogProgressBarSetMsg = pbscb;
+	MsgDialogProgressBarReset = pbrcb;
+	MsgDialogProgressBarInc = pbicb;
 }
 
 void MsgDialogClose()
@@ -63,13 +47,64 @@ void MsgDialogClose()
 	g_msg_dialog_wait_until = get_system_time();
 }
 
-int cellMsgDialogOpen2(u32 type, vm::ptr<const char> msgString, vm::ptr<CellMsgDialogCallback> callback, u32 userData, u32 extParam)
+s32 cellMsgDialogOpen2(u32 type, vm::ptr<const char> msgString, vm::ptr<CellMsgDialogCallback> callback, u32 userData, u32 extParam)
 {
 	cellSysutil->Warning("cellMsgDialogOpen2(type=0x%x, msgString_addr=0x%x, callback_addr=0x%x, userData=0x%x, extParam=0x%x)",
 		type, msgString.addr(), callback.addr(), userData, extParam);
-	
-	//type |= CELL_MSGDIALOG_TYPE_PROGRESSBAR_SINGLE | CELL_MSGDIALOG_TYPE_BG_INVISIBLE;
-	//type |= CELL_MSGDIALOG_TYPE_BUTTON_TYPE_YESNO | CELL_MSGDIALOG_TYPE_DEFAULT_CURSOR_NO;
+
+	if (!msgString || strlen(msgString.get_ptr()) >= 0x200 || type & -0x33f8)
+	{
+		return CELL_MSGDIALOG_ERROR_PARAM;
+	}
+
+	switch (type & CELL_MSGDIALOG_TYPE_BUTTON_TYPE)
+	{
+	case CELL_MSGDIALOG_TYPE_BUTTON_TYPE_NONE:
+	{
+		if (type & CELL_MSGDIALOG_TYPE_DEFAULT_CURSOR)
+		{
+			return CELL_MSGDIALOG_ERROR_PARAM;
+		}
+		switch (type & CELL_MSGDIALOG_TYPE_PROGRESSBAR)
+		{
+		case CELL_MSGDIALOG_TYPE_PROGRESSBAR_NONE: break;
+		case CELL_MSGDIALOG_TYPE_PROGRESSBAR_SINGLE: break;
+		case CELL_MSGDIALOG_TYPE_PROGRESSBAR_DOUBLE: break;
+		default: return CELL_MSGDIALOG_ERROR_PARAM;
+		}
+		break;
+	}
+
+	case CELL_MSGDIALOG_TYPE_BUTTON_TYPE_YESNO:
+	{
+		switch (type & CELL_MSGDIALOG_TYPE_DEFAULT_CURSOR)
+		{
+		case CELL_MSGDIALOG_TYPE_DEFAULT_CURSOR_YES: break;
+		case CELL_MSGDIALOG_TYPE_DEFAULT_CURSOR_NO: break;
+		default: return CELL_MSGDIALOG_ERROR_PARAM;
+		}
+		if (type & CELL_MSGDIALOG_TYPE_PROGRESSBAR)
+		{
+			return CELL_MSGDIALOG_ERROR_PARAM;
+		}
+		break;
+	}
+
+	case CELL_MSGDIALOG_TYPE_BUTTON_TYPE_OK:
+	{
+		if (type & CELL_MSGDIALOG_TYPE_DEFAULT_CURSOR)
+		{
+			return CELL_MSGDIALOG_ERROR_PARAM;
+		}
+		if (type & CELL_MSGDIALOG_TYPE_PROGRESSBAR)
+		{
+			return CELL_MSGDIALOG_ERROR_PARAM;
+		}
+		break;
+	}
+
+	default: return CELL_MSGDIALOG_ERROR_PARAM;
+	}
 
 	MsgDialogState old = msgDialogNone;
 	if (!g_msg_dialog_state.compare_exchange_strong(old, msgDialogOpen))
@@ -83,10 +118,10 @@ int cellMsgDialogOpen2(u32 type, vm::ptr<const char> msgString, vm::ptr<CellMsgD
 	{
 	case CELL_MSGDIALOG_TYPE_PROGRESSBAR_DOUBLE: g_msg_dialog_progress_bar_count = 2; break;
 	case CELL_MSGDIALOG_TYPE_PROGRESSBAR_SINGLE: g_msg_dialog_progress_bar_count = 1; break;
-	default: g_msg_dialog_progress_bar_count = 0; break; // ???
+	default: g_msg_dialog_progress_bar_count = 0; break;
 	}
 
-	std::string msg = (msgString.addr() != 0) ? msgString.get_ptr() : "";
+	std::string msg = msgString.get_ptr();
 
 	thread t("MsgDialog thread", [type, msg, callback, userData, extParam]()
 	{
@@ -156,7 +191,7 @@ int cellMsgDialogOpen2(u32 type, vm::ptr<const char> msgString, vm::ptr<CellMsgD
 	return CELL_OK;
 }
 
-int cellMsgDialogOpenErrorCode(u32 errorCode, vm::ptr<CellMsgDialogCallback> callback, u32 userData, u32 extParam)
+s32 cellMsgDialogOpenErrorCode(u32 errorCode, vm::ptr<CellMsgDialogCallback> callback, u32 userData, u32 extParam)
 {
 	cellSysutil->Warning("cellMsgDialogOpenErrorCode(errorCode=0x%x, callback_addr=0x%x, userData=0x%x, extParam=%d)",
 		errorCode, callback.addr(), userData, extParam);
@@ -255,7 +290,7 @@ int cellMsgDialogOpenErrorCode(u32 errorCode, vm::ptr<CellMsgDialogCallback> cal
 	return CELL_OK;
 }
 
-int cellMsgDialogClose(float delay)
+s32 cellMsgDialogClose(float delay)
 {
 	cellSysutil->Warning("cellMsgDialogClose(delay=%f)", delay);
 
@@ -277,7 +312,7 @@ int cellMsgDialogClose(float delay)
 	return CELL_OK;
 }
 
-int cellMsgDialogAbort()
+s32 cellMsgDialogAbort()
 {
 	cellSysutil->Warning("cellMsgDialogAbort()");
 
@@ -298,7 +333,7 @@ int cellMsgDialogAbort()
 	return CELL_OK;
 }
 
-int cellMsgDialogProgressBarSetMsg(u32 progressBarIndex, vm::ptr<const char> msgString)
+s32 cellMsgDialogProgressBarSetMsg(u32 progressBarIndex, vm::ptr<const char> msgString)
 {
 	cellSysutil->Warning("cellMsgDialogProgressBarSetMsg(progressBarIndex=%d, msgString_addr=0x%x ['%s'])",
 		progressBarIndex, msgString.addr(), msgString.get_ptr());
@@ -322,7 +357,7 @@ int cellMsgDialogProgressBarSetMsg(u32 progressBarIndex, vm::ptr<const char> msg
 	return CELL_OK;
 }
 
-int cellMsgDialogProgressBarReset(u32 progressBarIndex)
+s32 cellMsgDialogProgressBarReset(u32 progressBarIndex)
 {
 	cellSysutil->Warning("cellMsgDialogProgressBarReset(progressBarIndex=%d)", progressBarIndex);
 
@@ -343,7 +378,7 @@ int cellMsgDialogProgressBarReset(u32 progressBarIndex)
 	return CELL_OK;
 }
 
-int cellMsgDialogProgressBarInc(u32 progressBarIndex, u32 delta)
+s32 cellMsgDialogProgressBarInc(u32 progressBarIndex, u32 delta)
 {
 	cellSysutil->Warning("cellMsgDialogProgressBarInc(progressBarIndex=%d, delta=%d)", progressBarIndex, delta);
 
diff --git a/rpcs3/Emu/SysCalls/Modules/cellMsgDialog.h b/rpcs3/Emu/SysCalls/Modules/cellMsgDialog.h
index 9c0b2eeb55..4b76eb975c 100644
--- a/rpcs3/Emu/SysCalls/Modules/cellMsgDialog.h
+++ b/rpcs3/Emu/SysCalls/Modules/cellMsgDialog.h
@@ -2,7 +2,7 @@
 
 enum
 {
-	CELL_MSGDIALOG_ERROR_PARAM = 0x8002b301,
+	CELL_MSGDIALOG_ERROR_PARAM             = 0x8002b301,
 	CELL_MSGDIALOG_ERROR_DIALOG_NOT_OPENED = 0x8002b302,
 };
 
@@ -18,28 +18,28 @@ enum CellMsgDialogType
 
 enum
 {
-	CELL_MSGDIALOG_TYPE_SE_TYPE        = 1 << 0,
+	CELL_MSGDIALOG_TYPE_SE_TYPE        = 0x1,
 	CELL_MSGDIALOG_TYPE_SE_TYPE_ERROR  = 0 << 0,
 	CELL_MSGDIALOG_TYPE_SE_TYPE_NORMAL = 1 << 0,
 };
 
 enum
 {
-	CELL_MSGDIALOG_TYPE_SE_MUTE     = 1 << 1,
+	CELL_MSGDIALOG_TYPE_SE_MUTE     = 0x2,
 	CELL_MSGDIALOG_TYPE_SE_MUTE_OFF = 0 << 1,
 	CELL_MSGDIALOG_TYPE_SE_MUTE_ON  = 1 << 1,
 };
 
 enum
 {
-	CELL_MSGDIALOG_TYPE_BG           = 1 << 2,
+	CELL_MSGDIALOG_TYPE_BG           = 0x4,
 	CELL_MSGDIALOG_TYPE_BG_VISIBLE   = 0 << 2,
 	CELL_MSGDIALOG_TYPE_BG_INVISIBLE = 1 << 2,
 };
 
 enum
 {
-	CELL_MSGDIALOG_TYPE_BUTTON_TYPE       = 3 << 4,
+	CELL_MSGDIALOG_TYPE_BUTTON_TYPE       = 0x70,
 	CELL_MSGDIALOG_TYPE_BUTTON_TYPE_NONE  = 0 << 4,
 	CELL_MSGDIALOG_TYPE_BUTTON_TYPE_YESNO = 1 << 4,
 	CELL_MSGDIALOG_TYPE_BUTTON_TYPE_OK    = 2 << 4,
@@ -47,14 +47,14 @@ enum
 
 enum
 {
-	CELL_MSGDIALOG_TYPE_DISABLE_CANCEL     = 1 << 7,
+	CELL_MSGDIALOG_TYPE_DISABLE_CANCEL     = 0x80,
 	CELL_MSGDIALOG_TYPE_DISABLE_CANCEL_OFF = 0 << 7,
 	CELL_MSGDIALOG_TYPE_DISABLE_CANCEL_ON  = 1 << 7,
 };
 
 enum
 {
-	CELL_MSGDIALOG_TYPE_DEFAULT_CURSOR      = 1 << 8,
+	CELL_MSGDIALOG_TYPE_DEFAULT_CURSOR      = 0x300,
 	CELL_MSGDIALOG_TYPE_DEFAULT_CURSOR_NONE = 0 << 8,
 	CELL_MSGDIALOG_TYPE_DEFAULT_CURSOR_YES  = 0 << 8,
 	CELL_MSGDIALOG_TYPE_DEFAULT_CURSOR_NO   = 1 << 8,
@@ -63,7 +63,7 @@ enum
 
 enum
 {
-	CELL_MSGDIALOG_TYPE_PROGRESSBAR        = 3 << 12,
+	CELL_MSGDIALOG_TYPE_PROGRESSBAR        = 0x3000,
 	CELL_MSGDIALOG_TYPE_PROGRESSBAR_NONE   = 0 << 12,
 	CELL_MSGDIALOG_TYPE_PROGRESSBAR_SINGLE = 1 << 12,
 	CELL_MSGDIALOG_TYPE_PROGRESSBAR_DOUBLE = 2 << 12,
@@ -81,14 +81,14 @@ enum
 
 typedef void(*CellMsgDialogCallback)(s32 buttonType, u32 userData);
 
-int cellMsgDialogOpen2(u32 type, vm::ptr<const char> msgString, vm::ptr<CellMsgDialogCallback> callback, u32 userData, u32 extParam);
-int cellMsgDialogOpenErrorCode(u32 errorCode, vm::ptr<CellMsgDialogCallback> callback, u32 userData, u32 extParam);
+s32 cellMsgDialogOpen2(u32 type, vm::ptr<const char> msgString, vm::ptr<CellMsgDialogCallback> callback, u32 userData, u32 extParam);
+s32 cellMsgDialogOpenErrorCode(u32 errorCode, vm::ptr<CellMsgDialogCallback> callback, u32 userData, u32 extParam);
 
-int cellMsgDialogProgressBarSetMsg(u32 progressBarIndex, vm::ptr<const char> msgString);
-int cellMsgDialogProgressBarReset(u32 progressBarIndex);
-int cellMsgDialogProgressBarInc(u32 progressBarIndex, u32 delta);
-int cellMsgDialogClose(float delay);
-int cellMsgDialogAbort();
+s32 cellMsgDialogProgressBarSetMsg(u32 progressBarIndex, vm::ptr<const char> msgString);
+s32 cellMsgDialogProgressBarReset(u32 progressBarIndex);
+s32 cellMsgDialogProgressBarInc(u32 progressBarIndex, u32 delta);
+s32 cellMsgDialogClose(float delay);
+s32 cellMsgDialogAbort();
 
 typedef void(*MsgDialogCreateCb)(u32 type, const char* msg, u64& status);
 typedef void(*MsgDialogDestroyCb)();
@@ -96,10 +96,5 @@ typedef void(*MsgDialogProgressBarSetMsgCb)(u32 progressBarIndex, const char* ms
 typedef void(*MsgDialogProgressBarResetCb)(u32 progressBarIndex);
 typedef void(*MsgDialogProgressBarIncCb)(u32 progressBarIndex, u32 delta);
 
-void SetMsgDialogCreateCallback(MsgDialogCreateCb cb);
-void SetMsgDialogDestroyCallback(MsgDialogDestroyCb cb);
-void SetMsgDialogProgressBarSetMsgCallback(MsgDialogProgressBarSetMsgCb cb);
-void SetMsgDialogProgressBarResetCallback(MsgDialogProgressBarResetCb cb);
-void SetMsgDialogProgressBarIncCallback(MsgDialogProgressBarIncCb cb);
-
+void SetMsgDialogCallbacks(MsgDialogCreateCb ccb, MsgDialogDestroyCb dcb, MsgDialogProgressBarSetMsgCb pbscb, MsgDialogProgressBarResetCb pbrcb, MsgDialogProgressBarIncCb pbicb);
 void MsgDialogClose();
diff --git a/rpcs3/Gui/MsgDialog.cpp b/rpcs3/Gui/MsgDialog.cpp
index 8ede9a8531..e45519f40d 100644
--- a/rpcs3/Gui/MsgDialog.cpp
+++ b/rpcs3/Gui/MsgDialog.cpp
@@ -39,14 +39,12 @@ void MsgDialogCreate(u32 type, const char* msg, u64& status)
 		m_gauge2 = new wxGauge(m_dialog, wxID_ANY, 100, wxDefaultPosition, wxSize(300, -1), wxGA_HORIZONTAL | wxGA_SMOOTH);
 		m_text2 = new wxStaticText(m_dialog, wxID_ANY, "");
 		m_text2->SetAutoLayout(true);
+		// fallthrough
 
 	case CELL_MSGDIALOG_TYPE_PROGRESSBAR_SINGLE:
 		m_gauge1 = new wxGauge(m_dialog, wxID_ANY, 100, wxDefaultPosition, wxSize(300, -1), wxGA_HORIZONTAL | wxGA_SMOOTH);
 		m_text1 = new wxStaticText(m_dialog, wxID_ANY, "");
 		m_text1->SetAutoLayout(true);
-
-	default: // ???
-		break;
 	}
 
 	if (m_gauge1)
@@ -66,9 +64,6 @@ void MsgDialogCreate(u32 type, const char* msg, u64& status)
 
 	switch (type & CELL_MSGDIALOG_TYPE_BUTTON_TYPE)
 	{
-	case CELL_MSGDIALOG_TYPE_BUTTON_TYPE_NONE:
-		break;
-
 	case CELL_MSGDIALOG_TYPE_BUTTON_TYPE_YESNO:
 		m_button_yes = new wxButton(m_dialog, wxID_YES);
 		buttons->Add(m_button_yes, 0, wxALIGN_CENTER_HORIZONTAL | wxRIGHT, 8);
diff --git a/rpcs3/rpcs3.cpp b/rpcs3/rpcs3.cpp
index 2ec10d0ce1..d762f00bd4 100644
--- a/rpcs3/rpcs3.cpp
+++ b/rpcs3/rpcs3.cpp
@@ -48,46 +48,46 @@ bool Rpcs3App::OnInit()
 	{
 		wxGetApp().SendDbgCommand(id, t);
 	});
+
 	SetCallAfterCallback([](std::function<void()> func)
 	{
 		wxGetApp().CallAfter(func);
 	});
+
 	SetGetKeyboardHandlerCountCallback([]()
 	{
 		return 2;
 	});
+
 	SetGetKeyboardHandlerCallback([](int i) -> KeyboardHandlerBase*
 	{
 		switch (i)
 		{
-		case 0:
-			return new NullKeyboardHandler();
-			break;
-		case 1:
-			return new WindowsKeyboardHandler();
-			break;
-		default:
-			return new NullKeyboardHandler();
+		case 0: return new NullKeyboardHandler();
+		case 1: return new WindowsKeyboardHandler();
 		}
+
+		assert(!"Invalid keyboard handler number");
+		return new NullKeyboardHandler();
 	});
+
 	SetGetMouseHandlerCountCallback([]()
 	{
 		return 2;
 	});
+
 	SetGetMouseHandlerCallback([](int i) -> MouseHandlerBase*
 	{
 		switch (i)
 		{
-		case 0:
-			return new NullMouseHandler();
-			break;
-		case 1:
-			return new WindowsMouseHandler();
-			break;
-		default:
-			return new NullMouseHandler();
+		case 0: return new NullMouseHandler();
+		case 1: return new WindowsMouseHandler();
 		}
+
+		assert(!"Invalid mouse handler number");
+		return new NullMouseHandler();
 	});
+
 	SetGetPadHandlerCountCallback([]()
 	{
 #if defined(_WIN32)
@@ -96,34 +96,28 @@ bool Rpcs3App::OnInit()
 		return 2;
 #endif
 	});
+
 	SetGetPadHandlerCallback([](int i) -> PadHandlerBase*
 	{
 		switch (i)
 		{
-		case 0:
-			return new NullPadHandler();
-			break;
-		case 1:
-			return new WindowsPadHandler();
-			break;
+		case 0: return new NullPadHandler();
+		case 1: return new WindowsPadHandler();
 #if defined(_WIN32)
-		case 2:
-			return new XInputPadHandler();
-			break;
+		case 2: return new XInputPadHandler();
 #endif
-		default:
-			return new NullPadHandler();
 		}
+
+		assert(!"Invalid pad handler number");
+		return new NullPadHandler();
 	});
+
 	SetGetGSFrameCallback([]() -> GSFrameBase*
 	{
 		return new GLGSFrame();
 	});
-	SetMsgDialogCreateCallback(MsgDialogCreate);
-	SetMsgDialogDestroyCallback(MsgDialogDestroy);
-	SetMsgDialogProgressBarSetMsgCallback(MsgDialogProgressBarSetMsg);
-	SetMsgDialogProgressBarResetCallback(MsgDialogProgressBarReset);
-	SetMsgDialogProgressBarIncCallback(MsgDialogProgressBarInc);
+
+	SetMsgDialogCallbacks(MsgDialogCreate, MsgDialogDestroy, MsgDialogProgressBarSetMsg, MsgDialogProgressBarReset, MsgDialogProgressBarInc);
 
 	TheApp = this;
 	SetAppName(_PRGNAME_);