Parcel refactor again

This commit is contained in:
plutoo 2017-11-26 18:13:01 +01:00 committed by yellows8
parent 12b2ba6eb6
commit 8485facf99
3 changed files with 84 additions and 71 deletions

View File

@ -2,26 +2,26 @@
#include <switch.h> #include <switch.h>
typedef struct { typedef struct {
u8 ParcelData[0x400]; u8 payload[0x400];
u32 ParcelData_maxsize; u32 capacity;
u32 ParcelData_size; u32 size;
u32 ParcelData_pos; u32 pos;
u8 *ParcelObjects; u8 *ParcelObjects;
u32 ParcelObjectsSize; u32 ParcelObjectsSize;
} parcelContext; } Parcel;
void parcelInitializeContext(parcelContext *ctx); void parcelInitialize(Parcel *ctx);
Result parcelTransact(binderSession *session, u32 code, parcelContext *in_parcel, parcelContext *reply_parcel); Result parcelTransact(binderSession *session, u32 code, Parcel *in_parcel, Parcel *reply_parcel);
void* parcelWriteData(parcelContext *ctx, void* data, size_t data_size); void* parcelWriteData(Parcel *ctx, void* data, size_t data_size);
void* parcelReadData(parcelContext *ctx, void* data, size_t data_size); void* parcelReadData(Parcel *ctx, void* data, size_t data_size);
void parcelWriteInt32(parcelContext *ctx, s32 val); void parcelWriteInt32(Parcel *ctx, s32 val);
void parcelWriteUInt32(parcelContext *ctx, u32 val); void parcelWriteUInt32(Parcel *ctx, u32 val);
void parcelWriteString16_fromchar(parcelContext *ctx, const char *str); void parcelWriteString16(Parcel *ctx, const char *str);
s32 parcelReadInt32(parcelContext *ctx); s32 parcelReadInt32(Parcel *ctx);
u32 parcelReadUInt32(parcelContext *ctx); u32 parcelReadUInt32(Parcel *ctx);
void parcelWriteInterfaceToken(parcelContext *ctx, const char *str); void parcelWriteInterfaceToken(Parcel *ctx, const char *str);

View File

@ -41,13 +41,13 @@ void bufferProducerExit()
Result bufferProducerRequestBuffer(s32 bufferIdx) Result bufferProducerRequestBuffer(s32 bufferIdx)
{ {
Result rc; Result rc;
parcelContext parcel, parcel_reply; Parcel parcel, parcel_reply;
if (g_bufferProducerBinderSession == NULL) if (g_bufferProducerBinderSession == NULL)
return MAKERESULT(MODULE_LIBNX, LIBNX_NOTINITIALIZED); return MAKERESULT(MODULE_LIBNX, LIBNX_NOTINITIALIZED);
parcelInitializeContext(&parcel); parcelInitialize(&parcel);
parcelInitializeContext(&parcel_reply); parcelInitialize(&parcel_reply);
parcelWriteInterfaceToken(&parcel, g_bufferProducer_InterfaceDescriptor); parcelWriteInterfaceToken(&parcel, g_bufferProducer_InterfaceDescriptor);
parcelWriteInt32(&parcel, bufferIdx); parcelWriteInt32(&parcel, bufferIdx);
@ -77,13 +77,13 @@ Result bufferProducerRequestBuffer(s32 bufferIdx)
Result bufferProducerDequeueBuffer(bool async, u32 width, u32 height, s32 format, u32 usage, s32 *buf) Result bufferProducerDequeueBuffer(bool async, u32 width, u32 height, s32 format, u32 usage, s32 *buf)
{ {
Result rc; Result rc;
parcelContext parcel, parcel_reply; Parcel parcel, parcel_reply;
if (g_bufferProducerBinderSession == NULL) if (g_bufferProducerBinderSession == NULL)
return MAKERESULT(MODULE_LIBNX, LIBNX_NOTINITIALIZED); return MAKERESULT(MODULE_LIBNX, LIBNX_NOTINITIALIZED);
parcelInitializeContext(&parcel); parcelInitialize(&parcel);
parcelInitializeContext(&parcel_reply); parcelInitialize(&parcel_reply);
parcelWriteInterfaceToken(&parcel, g_bufferProducer_InterfaceDescriptor); parcelWriteInterfaceToken(&parcel, g_bufferProducer_InterfaceDescriptor);
@ -106,13 +106,13 @@ Result bufferProducerDequeueBuffer(bool async, u32 width, u32 height, s32 format
Result bufferProducerDetachBuffer(s32 slot) Result bufferProducerDetachBuffer(s32 slot)
{ {
Result rc; Result rc;
parcelContext parcel, parcel_reply; Parcel parcel, parcel_reply;
if (g_bufferProducerBinderSession == NULL) if (g_bufferProducerBinderSession == NULL)
return MAKERESULT(MODULE_LIBNX, LIBNX_NOTINITIALIZED); return MAKERESULT(MODULE_LIBNX, LIBNX_NOTINITIALIZED);
parcelInitializeContext(&parcel); parcelInitialize(&parcel);
parcelInitializeContext(&parcel_reply); parcelInitialize(&parcel_reply);
parcelWriteInterfaceToken(&parcel, g_bufferProducer_InterfaceDescriptor); parcelWriteInterfaceToken(&parcel, g_bufferProducer_InterfaceDescriptor);
parcelWriteInt32(&parcel, slot); parcelWriteInt32(&parcel, slot);
@ -129,13 +129,13 @@ Result bufferProducerDetachBuffer(s32 slot)
Result bufferProducerQueueBuffer(s32 buf, u8 input[0x5c]) Result bufferProducerQueueBuffer(s32 buf, u8 input[0x5c])
{ {
Result rc; Result rc;
parcelContext parcel, parcel_reply; Parcel parcel, parcel_reply;
if (g_bufferProducerBinderSession == NULL) if (g_bufferProducerBinderSession == NULL)
return MAKERESULT(MODULE_LIBNX, LIBNX_NOTINITIALIZED); return MAKERESULT(MODULE_LIBNX, LIBNX_NOTINITIALIZED);
parcelInitializeContext(&parcel); parcelInitialize(&parcel);
parcelInitializeContext(&parcel_reply); parcelInitialize(&parcel_reply);
parcelWriteInterfaceToken(&parcel, g_bufferProducer_InterfaceDescriptor); parcelWriteInterfaceToken(&parcel, g_bufferProducer_InterfaceDescriptor);
parcelWriteInt32(&parcel, buf); parcelWriteInt32(&parcel, buf);
@ -153,13 +153,13 @@ Result bufferProducerQueueBuffer(s32 buf, u8 input[0x5c])
Result bufferProducerQuery(s32 what, s32* value) Result bufferProducerQuery(s32 what, s32* value)
{ {
Result rc; Result rc;
parcelContext parcel, parcel_reply; Parcel parcel, parcel_reply;
if (g_bufferProducerBinderSession == NULL) if (g_bufferProducerBinderSession == NULL)
return MAKERESULT(MODULE_LIBNX, LIBNX_NOTINITIALIZED); return MAKERESULT(MODULE_LIBNX, LIBNX_NOTINITIALIZED);
parcelInitializeContext(&parcel); parcelInitialize(&parcel);
parcelInitializeContext(&parcel_reply); parcelInitialize(&parcel_reply);
parcelWriteInterfaceToken(&parcel, g_bufferProducer_InterfaceDescriptor); parcelWriteInterfaceToken(&parcel, g_bufferProducer_InterfaceDescriptor);
parcelWriteInt32(&parcel, what); parcelWriteInt32(&parcel, what);
@ -180,13 +180,13 @@ Result bufferProducerQuery(s32 what, s32* value)
Result bufferProducerConnect(s32 api, bool producerControlledByApp) Result bufferProducerConnect(s32 api, bool producerControlledByApp)
{ {
Result rc; Result rc;
parcelContext parcel, parcel_reply; Parcel parcel, parcel_reply;
if (g_bufferProducerBinderSession == NULL) if (g_bufferProducerBinderSession == NULL)
return MAKERESULT(MODULE_LIBNX, LIBNX_NOTINITIALIZED); return MAKERESULT(MODULE_LIBNX, LIBNX_NOTINITIALIZED);
parcelInitializeContext(&parcel); parcelInitialize(&parcel);
parcelInitializeContext(&parcel_reply); parcelInitialize(&parcel_reply);
parcelWriteInterfaceToken(&parcel, g_bufferProducer_InterfaceDescriptor); parcelWriteInterfaceToken(&parcel, g_bufferProducer_InterfaceDescriptor);
@ -207,13 +207,13 @@ Result bufferProducerConnect(s32 api, bool producerControlledByApp)
Result bufferProducerDisconnect(s32 api) Result bufferProducerDisconnect(s32 api)
{ {
Result rc; Result rc;
parcelContext parcel, parcel_reply; Parcel parcel, parcel_reply;
if (g_bufferProducerBinderSession == NULL) if (g_bufferProducerBinderSession == NULL)
return MAKERESULT(MODULE_LIBNX, LIBNX_NOTINITIALIZED); return MAKERESULT(MODULE_LIBNX, LIBNX_NOTINITIALIZED);
parcelInitializeContext(&parcel); parcelInitialize(&parcel);
parcelInitializeContext(&parcel_reply); parcelInitialize(&parcel_reply);
parcelWriteInterfaceToken(&parcel, g_bufferProducer_InterfaceDescriptor); parcelWriteInterfaceToken(&parcel, g_bufferProducer_InterfaceDescriptor);
parcelWriteInt32(&parcel, api); parcelWriteInt32(&parcel, api);
@ -230,12 +230,12 @@ Result bufferProducerDisconnect(s32 api)
Result bufferProducerTegraBufferInit(s32 buf, u8 input[0x178]) Result bufferProducerTegraBufferInit(s32 buf, u8 input[0x178])
{ {
Result rc; Result rc;
parcelContext parcel, parcel_reply; Parcel parcel, parcel_reply;
if (g_bufferProducerBinderSession==NULL) return MAKERESULT(MODULE_LIBNX, LIBNX_NOTINITIALIZED); if (g_bufferProducerBinderSession==NULL) return MAKERESULT(MODULE_LIBNX, LIBNX_NOTINITIALIZED);
parcelInitializeContext(&parcel); parcelInitialize(&parcel);
parcelInitializeContext(&parcel_reply); parcelInitialize(&parcel_reply);
parcelWriteInterfaceToken(&parcel, g_bufferProducer_InterfaceDescriptor); parcelWriteInterfaceToken(&parcel, g_bufferProducer_InterfaceDescriptor);
parcelWriteInt32(&parcel, buf); parcelWriteInt32(&parcel, buf);

View File

@ -10,43 +10,45 @@ u8 parcel_reply_log[0x10000] = {0};
size_t parcel_reply_log_size = 0; size_t parcel_reply_log_size = 0;
#endif #endif
void parcelInitializeContext(parcelContext *ctx) { void parcelInitialize(Parcel *ctx)
memset(ctx, 0, sizeof(parcelContext)); {
ctx->ParcelData_maxsize = sizeof(ctx->ParcelData); memset(ctx, 0, sizeof(Parcel));
ctx->capacity = sizeof(ctx->payload);
} }
Result parcelTransact(binderSession *session, u32 code, parcelContext *in_parcel, parcelContext *parcel_reply) { Result parcelTransact(binderSession *session, u32 code, Parcel *in_parcel, Parcel *parcel_reply)
{
Result rc=0; Result rc=0;
u8 inparcel[0x400]; u8 inparcel[0x400];
u8 outparcel[0x400]; u8 outparcel[0x400];
size_t outparcel_size = sizeof(outparcel); size_t outparcel_size = sizeof(outparcel);
u32 *inparcel32 = (u32*)inparcel; u32 *inparcel32 = (u32*)inparcel;
u32 *outparcel32 = (u32*)outparcel; u32 *outparcel32 = (u32*)outparcel;
u32 ParcelDataSize = in_parcel->ParcelData_size; u32 payloadSize = in_parcel->size;
u32 ParcelObjectsSize = in_parcel->ParcelObjectsSize; u32 ParcelObjectsSize = in_parcel->ParcelObjectsSize;
memset(inparcel, 0, sizeof(inparcel)); memset(inparcel, 0, sizeof(inparcel));
memset(outparcel, 0, outparcel_size); memset(outparcel, 0, outparcel_size);
if((size_t)ParcelDataSize >= sizeof(inparcel) || (size_t)ParcelObjectsSize >= sizeof(inparcel) || ((size_t)ParcelDataSize)+((size_t)ParcelObjectsSize)+0x10 >= sizeof(inparcel)) return MAKERESULT(MODULE_LIBNX, LIBNX_BADINPUT); if((size_t)payloadSize >= sizeof(inparcel) || (size_t)ParcelObjectsSize >= sizeof(inparcel) || ((size_t)payloadSize)+((size_t)ParcelObjectsSize)+0x10 >= sizeof(inparcel)) return MAKERESULT(MODULE_LIBNX, LIBNX_BADINPUT);
inparcel32[0] = ParcelDataSize;//ParcelDataSize inparcel32[0] = payloadSize;//payloadSize
inparcel32[1] = 0x10;//ParcelDataOffset inparcel32[1] = 0x10;//payloadOffset
inparcel32[2] = ParcelObjectsSize;//ParcelObjectsSize inparcel32[2] = ParcelObjectsSize;//ParcelObjectsSize
inparcel32[3] = 0x10+ParcelDataSize;//ParcelObjectsOffset inparcel32[3] = 0x10+payloadSize;//ParcelObjectsOffset
if(in_parcel->ParcelData && ParcelDataSize)memcpy(&inparcel[inparcel32[1]], in_parcel->ParcelData, ParcelDataSize); if(in_parcel->payload && payloadSize)memcpy(&inparcel[inparcel32[1]], in_parcel->payload, payloadSize);
if(in_parcel->ParcelObjects && ParcelObjectsSize)memcpy(&inparcel[inparcel32[3]], in_parcel->ParcelObjects, ParcelObjectsSize); if(in_parcel->ParcelObjects && ParcelObjectsSize)memcpy(&inparcel[inparcel32[3]], in_parcel->ParcelObjects, ParcelObjectsSize);
rc = binderTransactParcel(session, code, inparcel, ParcelDataSize+ParcelObjectsSize+0x10, outparcel, outparcel_size, 0); rc = binderTransactParcel(session, code, inparcel, payloadSize+ParcelObjectsSize+0x10, outparcel, outparcel_size, 0);
if (R_FAILED(rc)) return rc; if (R_FAILED(rc)) return rc;
if((size_t)outparcel32[1] >= outparcel_size || ((size_t)outparcel32[0])+((size_t)outparcel32[1]) >= outparcel_size) return MAKERESULT(MODULE_LIBNX, LIBNX_BADINPUT); if((size_t)outparcel32[1] >= outparcel_size || ((size_t)outparcel32[0])+((size_t)outparcel32[1]) >= outparcel_size) return MAKERESULT(MODULE_LIBNX, LIBNX_BADINPUT);
if((size_t)outparcel32[2] >= outparcel_size || ((size_t)outparcel32[2])+((size_t)outparcel32[3]) >= outparcel_size) return MAKERESULT(MODULE_LIBNX, LIBNX_BADINPUT); if((size_t)outparcel32[2] >= outparcel_size || ((size_t)outparcel32[2])+((size_t)outparcel32[3]) >= outparcel_size) return MAKERESULT(MODULE_LIBNX, LIBNX_BADINPUT);
if((size_t)outparcel32[0] >= outparcel_size || (size_t)outparcel32[3] >= outparcel_size) return MAKERESULT(MODULE_LIBNX, LIBNX_BADINPUT); if((size_t)outparcel32[0] >= outparcel_size || (size_t)outparcel32[3] >= outparcel_size) return MAKERESULT(MODULE_LIBNX, LIBNX_BADINPUT);
memcpy(parcel_reply->ParcelData, &outparcel[outparcel32[1]], outparcel32[0]); memcpy(parcel_reply->payload, &outparcel[outparcel32[1]], outparcel32[0]);
parcel_reply->ParcelData_size = outparcel32[0]; parcel_reply->size = outparcel32[0];
#ifdef PARCEL_LOGGING #ifdef PARCEL_LOGGING
if(parcel_reply_log_size + sizeof(inparcel) + outparcel_size <= sizeof(parcel_reply_log)) { if(parcel_reply_log_size + sizeof(inparcel) + outparcel_size <= sizeof(parcel_reply_log)) {
@ -60,44 +62,55 @@ Result parcelTransact(binderSession *session, u32 code, parcelContext *in_parcel
return 0; return 0;
} }
void* parcelWriteData(parcelContext *ctx, void* data, size_t data_size) { void* parcelWriteData(Parcel *ctx, void* data, size_t data_size)
void* ptr = &ctx->ParcelData[ctx->ParcelData_size]; {
void* ptr = &ctx->payload[ctx->size];
if(data_size & BIT(31))
return NULL;
if(data_size & BIT(31)) return NULL;
data_size = (data_size+3) & ~3; data_size = (data_size+3) & ~3;
if(ctx->ParcelData_size + data_size >= ctx->ParcelData_maxsize) return NULL; if(ctx->size + data_size >= ctx->capacity)
return NULL;
if(data)memcpy(ptr, data, data_size); if(data)
ctx->ParcelData_size+= data_size; memcpy(ptr, data, data_size);
ctx->size += data_size;
return ptr; return ptr;
} }
void* parcelReadData(parcelContext *ctx, void* data, size_t data_size) { void* parcelReadData(Parcel *ctx, void* data, size_t data_size)
void* ptr = ctx->ParcelData; {
void* ptr = ctx->payload;
size_t aligned_data_size; size_t aligned_data_size;
if(data_size & BIT(31)) return NULL; if(data_size & BIT(31))
return NULL;
aligned_data_size = (data_size+3) & ~3; aligned_data_size = (data_size+3) & ~3;
if(ctx->ParcelData_pos + aligned_data_size >= ctx->ParcelData_size) return NULL; if(ctx->pos + aligned_data_size >= ctx->size)
return NULL;
if(data)memcpy(data, &ctx->ParcelData[ctx->ParcelData_pos], data_size); if(data)
ctx->ParcelData_pos+= aligned_data_size; memcpy(data, &ctx->payload[ctx->pos], data_size);
ctx->pos += aligned_data_size;
return ptr; return ptr;
} }
void parcelWriteInt32(parcelContext *ctx, s32 val) { void parcelWriteInt32(Parcel *ctx, s32 val) {
parcelWriteData(ctx, &val, sizeof(val)); parcelWriteData(ctx, &val, sizeof(val));
} }
void parcelWriteUInt32(parcelContext *ctx, u32 val) { void parcelWriteUInt32(Parcel *ctx, u32 val) {
parcelWriteData(ctx, &val, sizeof(val)); parcelWriteData(ctx, &val, sizeof(val));
} }
void parcelWriteString16_fromchar(parcelContext *ctx, const char *str) { void parcelWriteString16(Parcel *ctx, const char *str)
{
u32 pos, len; u32 pos, len;
u16 *ptr; u16 *ptr;
@ -113,18 +126,18 @@ void parcelWriteString16_fromchar(parcelContext *ctx, const char *str) {
} }
} }
void parcelWriteInterfaceToken(parcelContext *ctx, const char *interface) { void parcelWriteInterfaceToken(Parcel *ctx, const char *interface) {
parcelWriteInt32(ctx, 0x100); parcelWriteInt32(ctx, 0x100);
parcelWriteString16_fromchar(ctx, interface); parcelWriteString16(ctx, interface);
} }
s32 parcelReadInt32(parcelContext *ctx) { s32 parcelReadInt32(Parcel *ctx) {
s32 val = 0; s32 val = 0;
parcelReadData(ctx, &val, sizeof(val)); parcelReadData(ctx, &val, sizeof(val));
return val; return val;
} }
u32 parcelReadUInt32(parcelContext *ctx) { u32 parcelReadUInt32(Parcel *ctx) {
u32 val = 0; u32 val = 0;
parcelReadData(ctx, &val, sizeof(val)); parcelReadData(ctx, &val, sizeof(val));
return val; return val;