Make sure all data is initialized in srv and errf
Prior to system version 11.0, the kernel filled the resulting handle with junk in case of failure, when calling svcConnectToPort, etc. In some situations libctru could accidentally close valid handles.
This commit is contained in:
parent
ebb5305188
commit
cf538b1fa8
@ -18,10 +18,12 @@ Result errfInit(void)
|
|||||||
if (AtomicPostIncrement(&errfRefCount)) return 0;
|
if (AtomicPostIncrement(&errfRefCount)) return 0;
|
||||||
|
|
||||||
rc = svcConnectToPort(&errfHandle, "err:f");
|
rc = svcConnectToPort(&errfHandle, "err:f");
|
||||||
if (R_FAILED(rc)) goto end;
|
if (R_FAILED(rc))
|
||||||
|
{
|
||||||
|
errfHandle = 0;
|
||||||
|
errfExit();
|
||||||
|
}
|
||||||
|
|
||||||
end:
|
|
||||||
if (R_FAILED(rc)) errfExit();
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -29,7 +31,8 @@ void errfExit(void)
|
|||||||
{
|
{
|
||||||
if (AtomicDecrement(&errfRefCount))
|
if (AtomicDecrement(&errfRefCount))
|
||||||
return;
|
return;
|
||||||
svcCloseHandle(errfHandle);
|
if (errfHandle != 0) svcCloseHandle(errfHandle);
|
||||||
|
errfHandle = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle* errfGetSessionHandle(void)
|
Handle* errfGetSessionHandle(void)
|
||||||
|
@ -35,10 +35,13 @@ Result srvInit(void)
|
|||||||
rc = svcDuplicateHandle(&srvHandle, *srvPmGetSessionHandle()); // Prior to system version 7.0 srv:pm was a superset of srv:
|
rc = svcDuplicateHandle(&srvHandle, *srvPmGetSessionHandle()); // Prior to system version 7.0 srv:pm was a superset of srv:
|
||||||
else
|
else
|
||||||
rc = svcConnectToPort(&srvHandle, "srv:");
|
rc = svcConnectToPort(&srvHandle, "srv:");
|
||||||
if (R_FAILED(rc)) goto end;
|
|
||||||
|
|
||||||
|
if (R_SUCCEEDED(rc))
|
||||||
rc = srvRegisterClient();
|
rc = srvRegisterClient();
|
||||||
end:
|
else
|
||||||
|
// Prior to system version 11.0, the kernel filled the resulting handle with junk in case of failure
|
||||||
|
srvHandle = 0;
|
||||||
|
|
||||||
if (R_FAILED(rc)) srvExit();
|
if (R_FAILED(rc)) srvExit();
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@ -96,11 +99,11 @@ Result srvEnableNotification(Handle* semaphoreOut)
|
|||||||
|
|
||||||
cmdbuf[0] = IPC_MakeHeader(0x2,0,0);
|
cmdbuf[0] = IPC_MakeHeader(0x2,0,0);
|
||||||
|
|
||||||
if(R_FAILED(rc = svcSendSyncRequest(srvHandle)))return rc;
|
rc = svcSendSyncRequest(srvHandle);
|
||||||
|
rc = R_SUCCEEDED(rc) ? cmdbuf[1] : rc;
|
||||||
|
if(semaphoreOut) *semaphoreOut = R_SUCCEEDED(rc) ? cmdbuf[3] : 0;
|
||||||
|
|
||||||
if(semaphoreOut) *semaphoreOut = cmdbuf[3];
|
return rc;
|
||||||
|
|
||||||
return cmdbuf[1];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result srvRegisterService(Handle* out, const char* name, int maxSessions)
|
Result srvRegisterService(Handle* out, const char* name, int maxSessions)
|
||||||
@ -113,11 +116,11 @@ Result srvRegisterService(Handle* out, const char* name, int maxSessions)
|
|||||||
cmdbuf[3] = strnlen(name, 8);
|
cmdbuf[3] = strnlen(name, 8);
|
||||||
cmdbuf[4] = maxSessions;
|
cmdbuf[4] = maxSessions;
|
||||||
|
|
||||||
if(R_FAILED(rc = svcSendSyncRequest(srvHandle)))return rc;
|
rc = svcSendSyncRequest(srvHandle);
|
||||||
|
rc = R_SUCCEEDED(rc) ? cmdbuf[1] : rc;
|
||||||
|
if(out) *out = R_SUCCEEDED(rc) ? cmdbuf[3] : 0;
|
||||||
|
|
||||||
if(out) *out = cmdbuf[3];
|
return rc;
|
||||||
|
|
||||||
return cmdbuf[1];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result srvUnregisterService(const char* name)
|
Result srvUnregisterService(const char* name)
|
||||||
@ -144,11 +147,11 @@ Result srvGetServiceHandleDirect(Handle* out, const char* name)
|
|||||||
cmdbuf[3] = strnlen(name, 8);
|
cmdbuf[3] = strnlen(name, 8);
|
||||||
cmdbuf[4] = (u32)srvGetBlockingPolicy(); // per-thread setting, default is blocking
|
cmdbuf[4] = (u32)srvGetBlockingPolicy(); // per-thread setting, default is blocking
|
||||||
|
|
||||||
if(R_FAILED(rc = svcSendSyncRequest(srvHandle)))return rc;
|
rc = svcSendSyncRequest(srvHandle);
|
||||||
|
rc = R_SUCCEEDED(rc) ? cmdbuf[1] : rc;
|
||||||
|
if(out) *out = R_SUCCEEDED(rc) ? cmdbuf[3] : 0;
|
||||||
|
|
||||||
if(out) *out = cmdbuf[3];
|
return rc;
|
||||||
|
|
||||||
return cmdbuf[1];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result srvRegisterPort(const char* name, Handle clientHandle)
|
Result srvRegisterPort(const char* name, Handle clientHandle)
|
||||||
@ -191,11 +194,11 @@ Result srvGetPort(Handle* out, const char* name)
|
|||||||
cmdbuf[3] = strnlen(name, 8);
|
cmdbuf[3] = strnlen(name, 8);
|
||||||
cmdbuf[4] = 0x0;
|
cmdbuf[4] = 0x0;
|
||||||
|
|
||||||
if(R_FAILED(rc = svcSendSyncRequest(srvHandle)))return rc;
|
rc = svcSendSyncRequest(srvHandle);
|
||||||
|
rc = R_SUCCEEDED(rc) ? cmdbuf[1] : rc;
|
||||||
|
if(out) *out = R_SUCCEEDED(rc) ? cmdbuf[3] : 0;
|
||||||
|
|
||||||
if(out) *out = cmdbuf[3];
|
return rc;
|
||||||
|
|
||||||
return cmdbuf[1];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result srvWaitForPortRegistered(const char* name)
|
Result srvWaitForPortRegistered(const char* name)
|
||||||
@ -245,11 +248,11 @@ Result srvReceiveNotification(u32* notificationIdOut)
|
|||||||
|
|
||||||
cmdbuf[0] = IPC_MakeHeader(0xB,0,0); // 0xB0000
|
cmdbuf[0] = IPC_MakeHeader(0xB,0,0); // 0xB0000
|
||||||
|
|
||||||
if(R_FAILED(rc = svcSendSyncRequest(srvHandle)))return rc;
|
rc = svcSendSyncRequest(srvHandle);
|
||||||
|
rc = R_SUCCEEDED(rc) ? cmdbuf[1] : rc;
|
||||||
|
if(notificationIdOut) *notificationIdOut = R_SUCCEEDED(rc) ? cmdbuf[2] : 0;
|
||||||
|
|
||||||
if(notificationIdOut) *notificationIdOut = cmdbuf[2];
|
return rc;
|
||||||
|
|
||||||
return cmdbuf[1];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result srvPublishToSubscriber(u32 notificationId, u32 flags)
|
Result srvPublishToSubscriber(u32 notificationId, u32 flags)
|
||||||
@ -274,12 +277,18 @@ Result srvPublishAndGetSubscriber(u32* processIdCountOut, u32* processIdsOut, u3
|
|||||||
cmdbuf[0] = IPC_MakeHeader(0xD,1,0); // 0xD0040
|
cmdbuf[0] = IPC_MakeHeader(0xD,1,0); // 0xD0040
|
||||||
cmdbuf[1] = notificationId;
|
cmdbuf[1] = notificationId;
|
||||||
|
|
||||||
if(R_FAILED(rc = svcSendSyncRequest(srvHandle)))return rc;
|
rc = svcSendSyncRequest(srvHandle);
|
||||||
|
rc = R_SUCCEEDED(rc) ? cmdbuf[1] : rc;
|
||||||
|
|
||||||
|
if (R_SUCCEEDED(rc))
|
||||||
|
{
|
||||||
if(processIdCountOut) *processIdCountOut = cmdbuf[2];
|
if(processIdCountOut) *processIdCountOut = cmdbuf[2];
|
||||||
if(processIdsOut) memcpy(processIdsOut, &cmdbuf[3], cmdbuf[2] * sizeof(u32));
|
if(processIdsOut) memcpy(processIdsOut, &cmdbuf[3], cmdbuf[2] * sizeof(u32));
|
||||||
|
}
|
||||||
|
else if(processIdCountOut)
|
||||||
|
*processIdCountOut = 0;
|
||||||
|
|
||||||
return cmdbuf[1];
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
Result srvIsServiceRegistered(bool* registeredOut, const char* name)
|
Result srvIsServiceRegistered(bool* registeredOut, const char* name)
|
||||||
@ -291,11 +300,12 @@ Result srvIsServiceRegistered(bool* registeredOut, const char* name)
|
|||||||
strncpy((char*) &cmdbuf[1], name,8);
|
strncpy((char*) &cmdbuf[1], name,8);
|
||||||
cmdbuf[3] = strnlen(name, 8);
|
cmdbuf[3] = strnlen(name, 8);
|
||||||
|
|
||||||
if(R_FAILED(rc = svcSendSyncRequest(srvHandle)))return rc;
|
rc = svcSendSyncRequest(srvHandle);
|
||||||
|
rc = R_SUCCEEDED(rc) ? cmdbuf[1] : rc;
|
||||||
|
|
||||||
if(registeredOut) *registeredOut = cmdbuf[2] & 0xFF;
|
if(registeredOut) *registeredOut = R_SUCCEEDED(rc) && (cmdbuf[2] & 0xFF) != 0;
|
||||||
|
|
||||||
return cmdbuf[1];
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
Result srvIsPortRegistered(bool* registeredOut, const char* name)
|
Result srvIsPortRegistered(bool* registeredOut, const char* name)
|
||||||
|
Loading…
Reference in New Issue
Block a user