fix(libSceMove): return INVALID_HANDLE for a handle that is not open

The handle calls and sceMoveClose threw for a handle never opened, already closed or opened before sceMoveTerm; they now return 0x80EE0004, checked before the other arguments.
This commit is contained in:
Yossi Yadgar committed 2026-10-20 10:01:45 +03:00
1 parent e9cc4a8efb
commit 808d67e715
2 files changed
+26 -24

No files matched your search

+11 -12
View File
@@ -13,6 +13,7 @@ constexpr int MOVE_NO_CONTROLLER_CONNECTED = 1;
constexpr int MOVE_ERROR_NOT_INIT = static_cast<int>(0x80EE0001);
constexpr int MOVE_ERROR_ALREADY_INIT = static_cast<int>(0x80EE0002);
constexpr int MOVE_ERROR_INVALID_ARG = static_cast<int>(0x80EE0003);
constexpr int MOVE_ERROR_INVALID_HANDLE = static_cast<int>(0x80EE0004);
constexpr int32_t MOVE_FIRST_HANDLE = 0x30B0100;
constexpr int32_t MOVE_HANDLE_STEP = 0x100;
@@ -26,11 +27,10 @@ struct Slot {
std::unordered_map<int32_t, Slot> openHandles;
int checkHandle(const char* function, int32_t handle) {
int checkHandle(int32_t handle) {
std::lock_guard lock(stateMutex);
if (!initialized) return MOVE_ERROR_NOT_INIT;
if (!openHandles.contains(handle)) NotImplemented_nid_no_patch(function);
return MOVE_OK;
return openHandles.contains(handle) ? MOVE_OK : MOVE_ERROR_INVALID_HANDLE;
}
}
@@ -68,37 +68,36 @@ int APS5_VABI sceMoveOpen(int32_t userId, int32_t type, int32_t index) {
int APS5_VABI sceMoveClose(int32_t handle) {
std::lock_guard lock(stateMutex);
if (!initialized) return MOVE_ERROR_NOT_INIT;
if (openHandles.erase(handle) == 0) NotImplemented_nid_no_patch(__func__);
return MOVE_OK;
return openHandles.erase(handle) != 0 ? MOVE_OK : MOVE_ERROR_INVALID_HANDLE;
}
int APS5_VABI sceMoveGetDeviceInfo(int32_t handle, void* info) {
if (const int result = checkHandle(__func__, handle); result != MOVE_OK) return result;
if (const int result = checkHandle(handle); result != MOVE_OK) return result;
if (!info) return MOVE_ERROR_INVALID_ARG;
return MOVE_NO_CONTROLLER_CONNECTED;
}
int APS5_VABI sceMoveGetExtensionPortInfo(int32_t handle, void* data) {
if (const int result = checkHandle(__func__, handle); result != MOVE_OK) return result;
if (const int result = checkHandle(handle); result != MOVE_OK) return result;
if (!data) return MOVE_ERROR_INVALID_ARG;
return MOVE_NO_CONTROLLER_CONNECTED;
}
int APS5_VABI sceMoveReadStateLatest(int32_t handle, void* data) {
if (const int result = checkHandle(__func__, handle); result != MOVE_OK) return result;
if (const int result = checkHandle(handle); result != MOVE_OK) return result;
if (!data) return MOVE_ERROR_INVALID_ARG;
return MOVE_NO_CONTROLLER_CONNECTED;
}
int APS5_VABI sceMoveReadStateRecent(int32_t handle, int64_t timestamp, void* data, int32_t* outCount) {
if (const int result = checkHandle(__func__, handle); result != MOVE_OK) return result;
if (const int result = checkHandle(handle); result != MOVE_OK) return result;
if (timestamp < 0 || !data || !outCount) return MOVE_ERROR_INVALID_ARG;
return MOVE_NO_CONTROLLER_CONNECTED;
}
int APS5_VABI sceMoveSetVibration(int32_t handle, uint8_t motor) {
(void)motor;
if (const int result = checkHandle(__func__, handle); result != MOVE_OK) return result;
if (const int result = checkHandle(handle); result != MOVE_OK) return result;
return MOVE_NO_CONTROLLER_CONNECTED;
}
@@ -106,12 +105,12 @@ int APS5_VABI sceMoveSetLightSphere(int32_t handle, uint8_t red, uint8_t green,
(void)red;
(void)green;
(void)blue;
if (const int result = checkHandle(__func__, handle); result != MOVE_OK) return result;
if (const int result = checkHandle(handle); result != MOVE_OK) return result;
return MOVE_NO_CONTROLLER_CONNECTED;
}
int APS5_VABI sceMoveResetLightSphere(int32_t handle) {
return checkHandle(__func__, handle);
return checkHandle(handle);
}
}
+15 -12
View File
@@ -27,6 +27,7 @@ constexpr int kNoControllerConnected = 1;
constexpr int kNotInit = static_cast<int>(0x80EE0001);
constexpr int kAlreadyInit = static_cast<int>(0x80EE0002);
constexpr int kInvalidArg = static_cast<int>(0x80EE0003);
constexpr int kInvalidHandle = static_cast<int>(0x80EE0004);
constexpr std::int32_t kUserId = 0x10000000;
constexpr std::int32_t kFirstHandle = 0x30B0100;
constexpr std::int32_t kHandleStep = 0x100;
@@ -72,17 +73,19 @@ void RequireNotInit(std::int32_t handle) {
Require(count == -7);
}
void RequireUnknownHandleThrows(std::int32_t handle) {
void RequireUnknownHandle(std::int32_t handle) {
Buffer buffer;
std::int32_t count = -7;
Require(Throws([&] { sceMoveClose(handle); }));
Require(Throws([&] { sceMoveGetDeviceInfo(handle, buffer.bytes); }));
Require(Throws([&] { sceMoveGetExtensionPortInfo(handle, buffer.bytes); }));
Require(Throws([&] { sceMoveReadStateLatest(handle, buffer.bytes); }));
Require(Throws([&] { sceMoveReadStateRecent(handle, 0, buffer.bytes, &count); }));
Require(Throws([&] { sceMoveSetVibration(handle, 0xFF); }));
Require(Throws([&] { sceMoveSetLightSphere(handle, 0xFF, 0, 0); }));
Require(Throws([&] { sceMoveResetLightSphere(handle); }));
Require(sceMoveClose(handle) == kInvalidHandle);
Require(sceMoveGetDeviceInfo(handle, buffer.bytes) == kInvalidHandle);
Require(sceMoveGetExtensionPortInfo(handle, buffer.bytes) == kInvalidHandle);
Require(sceMoveReadStateLatest(handle, buffer.bytes) == kInvalidHandle);
Require(sceMoveReadStateRecent(handle, 0, buffer.bytes, &count) == kInvalidHandle);
Require(sceMoveSetVibration(handle, 0xFF) == kInvalidHandle);
Require(sceMoveSetLightSphere(handle, 0xFF, 0, 0) == kInvalidHandle);
Require(sceMoveResetLightSphere(handle) == kInvalidHandle);
Require(sceMoveGetDeviceInfo(handle, nullptr) == kInvalidHandle);
Require(sceMoveReadStateRecent(handle, -1, nullptr, nullptr) == kInvalidHandle);
Require(buffer.Untouched());
Require(count == -7);
}
@@ -95,7 +98,7 @@ int main() {
Require(sceMoveInit() == kOk);
Require(sceMoveInit() == kAlreadyInit);
RequireUnknownHandleThrows(kFirstHandle);
RequireUnknownHandle(kFirstHandle);
const std::int32_t first = sceMoveOpen(kUserId, 0, 0);
const std::int32_t second = sceMoveOpen(kUserId, 0, 1);
@@ -126,7 +129,7 @@ int main() {
Require(sceMoveResetLightSphere(first) == kOk);
Require(sceMoveClose(first) == kOk);
RequireUnknownHandleThrows(first);
RequireUnknownHandle(first);
const std::int32_t reopened = sceMoveOpen(kUserId, 0, 0);
Require(reopened == kFirstHandle + 2 * kHandleStep);
Require(sceMoveClose(reopened) == kOk);
@@ -136,7 +139,7 @@ int main() {
RequireNotInit(second);
Require(sceMoveInit() == kOk);
RequireUnknownHandleThrows(second);
RequireUnknownHandle(second);
const std::int32_t third = sceMoveOpen(kUserId, 0, 0);
Require(third == kFirstHandle + 3 * kHandleStep);
Require(sceMoveClose(third) == kOk);