Skip to content

Commit

Permalink
SetData function & fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
piepie62 committed Jan 12, 2019
1 parent c80b22c commit c224f8d
Show file tree
Hide file tree
Showing 7 changed files with 93 additions and 133 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ A POC CEC (StreetPass) injection tool.

Information for implemenation of CECD:U service taken from [here](https://www.3dbrew.org/wiki/CECD_Services) and [here](https://gist.github.com/wwylele/29a8caa6f5e5a7d88a00bedae90472ed)

Currently hardcoded to work with Kirby Triple Deluxe, because that was the first one I thought of to use for testing
Works for many games; more testing needed to find incompatible ones
Also not the most informative menu
11 changes: 8 additions & 3 deletions include/cecdu.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,9 +117,9 @@ Result CECDU_WriteMessage(u32 programID, bool outBox, cecMessageId messageID, vo
// Result CECDU_WriteMessageWithHMAC(u32 programID, bool outBox, cecMessageId messageID, void* buffer, size_t bufferSize, void* hmac);

/**
* @param messageID 8-byte value
* @param messageID null if not a message
**/
Result CECDU_Delete(u32 programID, cecDataPath path, bool outBox, cecMessageId messageID);
Result CECDU_Delete(u32 programID, cecDataPath path, bool outBox, cecMessageId* messageID);

/**
*
Expand All @@ -129,4 +129,9 @@ Result CECDU_RunCommand(cecCommand command);
/**
*
**/
Result CECDU_OpenAndRead(u32 programID, cecDataPath path, u32 flag, void* buffer, size_t* bufferSize);
Result CECDU_OpenAndRead(u32 programID, cecDataPath path, u32 flag, void* buffer, size_t* bufferSize);

/**
* In Citra, but I'm not sure what it does yet
**/
Result CECDU_SetData(u32 programId, u32 option, void* buffer, size_t bufferSize);
5 changes: 3 additions & 2 deletions include/io.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@

namespace io
{
bool exists(const std::string& name);
}
bool fileExists(const std::string& name);
bool folderExists(const std::string& name);
};

#endif
11 changes: 6 additions & 5 deletions source/Box.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,25 +52,26 @@ Result Box::clearMessages()
Result res;
for (auto message : info.getMessages())
{
CECDU_Delete(id, outBox ? CEC_PATH_OUTBOX_MSG : CEC_PATH_INBOX_MSG, outBox, message.messageID());
cecMessageId mId = message.messageID();
CECDU_Delete(id, outBox ? CEC_PATH_OUTBOX_MSG : CEC_PATH_INBOX_MSG, outBox, &mId);
}
info.clearMessages();
if (R_FAILED(res = CECDU_Delete(id, outBox ? CEC_PATH_OUTBOX_INFO : CEC_PATH_INBOX_INFO, outBox, {}))) return res;
if (R_FAILED(res = CECDU_Delete(id, outBox ? CEC_PATH_OUTBOX_INFO : CEC_PATH_INBOX_INFO, outBox, nullptr))) return res;
auto data = info.data();
if (R_FAILED(res = CECDU_OpenAndWrite(id, outBox ? CEC_PATH_OUTBOX_INFO : CEC_PATH_INBOX_INFO, CEC_WRITE | CEC_CHECK, data.data(), data.size()))) return res;
return 0;
}

Result Box::removeMessage(cecMessageId messageId)
{
Result res = CECDU_Delete(id, outBox ? CEC_PATH_OUTBOX_MSG : CEC_PATH_INBOX_MSG, outBox, messageId);
Result res = CECDU_Delete(id, outBox ? CEC_PATH_OUTBOX_MSG : CEC_PATH_INBOX_MSG, outBox, &messageId);
info.deleteMessage(messageId);
return res;
}

Result Box::saveInfo() const
{
Result res = CECDU_Delete(id, outBox ? CEC_PATH_OUTBOX_INFO : CEC_PATH_INBOX_INFO, outBox, {});
Result res = CECDU_Delete(id, outBox ? CEC_PATH_OUTBOX_INFO : CEC_PATH_INBOX_INFO, outBox, nullptr);
if (R_FAILED(res))
{
return res;
Expand All @@ -83,7 +84,7 @@ Result Box::saveInfo() const
}
if (index)
{
res = CECDU_Delete(id, CEC_PATH_OUTBOX_INDEX, true, {});
res = CECDU_Delete(id, CEC_PATH_OUTBOX_INDEX, true, nullptr);
if (R_FAILED(res))
{
return res;
Expand Down
24 changes: 20 additions & 4 deletions source/cecdu.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,17 +125,17 @@ Result CECDU_WriteMessage(u32 programID, bool outBox, cecMessageId messageID, vo
return cmdbuf[1];
}

Result CECDU_Delete(u32 programID, cecDataPath path, bool outBox, cecMessageId messageID)
Result CECDU_Delete(u32 programID, cecDataPath path, bool outBox, cecMessageId* messageID)
{
Result res;
u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x8, 4, 2);
cmdbuf[1] = programID;
cmdbuf[2] = path;
cmdbuf[3] = outBox;
cmdbuf[4] = 8;
cmdbuf[5] = IPC_Desc_Buffer(8, IPC_BUFFER_R);
cmdbuf[6] = messageID.data;
cmdbuf[4] = messageID ? 8 : 0;
cmdbuf[5] = messageID ? IPC_Desc_Buffer(8, IPC_BUFFER_R) : IPC_Desc_Buffer(0, IPC_BUFFER_R);
cmdbuf[6] = messageID;

if (R_FAILED(res = svcSendSyncRequest(cecduHandle))) return res;

Expand Down Expand Up @@ -171,5 +171,21 @@ Result CECDU_OpenAndRead(u32 programID, cecDataPath path, u32 flag, void* buffer
if (R_FAILED(res = svcSendSyncRequest(cecduHandle))) return res;

*bufferSize = cmdbuf[2];
return cmdbuf[1];
}

Result CECDU_SetData(u32 programID, u32 option, void* buffer, size_t bufferSize)
{
Result res;
u32* cmdbuf = getThreadCommandBuffer();
cmdbuf[0] = IPC_MakeHeader(0x9, 3, 2);
cmdbuf[1] = programID;
cmdbuf[2] = bufferSize;
cmdbuf[3] = option;
cmdbuf[4] = IPC_Desc_Buffer(bufferSize, IPC_BUFFER_R);
cmdbuf[5] = buffer;

if (R_FAILED(res = svcSendSyncRequest(cecduHandle))) return res;

return cmdbuf[1];
}
14 changes: 13 additions & 1 deletion source/io.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,21 @@
*/

#include "io.hpp"
#include <dirent.h>

bool io::exists(const std::string& name)
bool io::fileExists(const std::string& name)
{
struct stat buffer;
return (stat (name.c_str(), &buffer) == 0);
}

bool io::folderExists(const std::string& name)
{
DIR* dir = opendir(name.c_str());
if (dir)
{
closedir(dir);
return true;
}
return false;
}
158 changes: 41 additions & 117 deletions source/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,14 +79,14 @@ void createBox(std::string id)
std::string missingFiles = "";
for (auto file : templateDirs)
{
if (!io::exists(file))
if (!io::folderExists(file))
{
missingFiles += '\t' + file + '\n';
}
}
for (auto file : templateFiles)
{
if (!io::exists(file))
if (!io::fileExists(file))
{
missingFiles += '\t' + file + '\n';
}
Expand All @@ -99,7 +99,7 @@ void createBox(std::string id)
STDirectory dir("/3ds/CECTool/" + id + "/OutBox__");
if (!dir.good() || dir.count() < 1)
{
printf("No outbox messages. Continue?\nA: Yes\nB: No");
printf("No outbox messages. Continue?\nA: Yes\nB: No\n");
hidScanInput();
while (aptMainLoop() && !(hidKeysDown() & KEY_A) && !(hidKeysDown() & KEY_B))
{
Expand Down Expand Up @@ -164,7 +164,7 @@ void importBoxes(bool del)
{
if (dir.folder(i))
{
if (io::exists("/3ds/CECTool/" + dir.item(i) + "/InBox___"))
if (io::folderExists("/3ds/CECTool/" + dir.item(i) + "/InBox___"))
{
if (dir.item(i).find_first_not_of("1234567890abcdef") == std::string::npos)
{
Expand Down Expand Up @@ -198,17 +198,9 @@ void importBoxes(bool del)
FILE* in;
u8* data;
Box box(currentId, false);
u8 boxDataMod = 0;
// dir.count() -1 to skip BoxInfo_____
for (size_t j = 0; j < dir.count() - 1 && box.getMessages().size() < box.getInfo().maxMessages(); j++)
for (size_t j = 0; j < dir.good() && dir.count() && box.getMessages().size() < box.getInfo().maxMessages(); j++)
{
if (dir.item(j + boxDataMod) == "BoxInfo_____")
{
boxDataMod++;
j--;
continue;
}
in = fopen(("/3ds/CECTool/" + boxId + "/InBox___/" + dir.item(j + boxDataMod)).c_str(), "r");
in = fopen(("/3ds/CECTool/" + boxId + "/InBox___/" + dir.item(j)).c_str(), "r");
fseek(in, 0, SEEK_END);
size_t messageSize = ftell(in);
fseek(in, 0, SEEK_SET);
Expand All @@ -221,12 +213,12 @@ void importBoxes(bool del)
box.addMessage(message);
if (del)
{
remove(("/3ds/CECTool/" + boxId + "/InBox___/" + dir.item(j + boxDataMod)).c_str());
remove(("/3ds/CECTool/" + boxId + "/InBox___/" + dir.item(j)).c_str());
}
}

dir = STDirectory("/3ds/CECTool/" + boxId + "/OutBox__");
for (size_t j = 0; j < dir.count() - 2 && box.getMessages().size() < box.getInfo().maxMessages(); j++)
for (size_t j = 0; dir.good() && j < dir.count() && box.getMessages().size() < box.getInfo().maxMessages(); j++)
{
in = fopen(("/3ds/CECTool/" + boxId + "/OutBox__/" + dir.item(j)).c_str(), "r");
fseek(in, 0, SEEK_END);
Expand Down Expand Up @@ -397,7 +389,7 @@ void dumpBoxes()
}
oldSizeWritten = sizeWritten;
CECDU_ReadRawFile(read, &sizeWritten);
CECDU_OpenRawFile(id, CECMESSAGE_BOX_TITLE, CEC_READ | CEC_CHECK);
CECDU_OpenRawFile(id, CECMESSAGE_BOX_TITLE, CEC_READ | CEC_CHECK); // Reopen file
}
while (read[sizeWritten / 2 - 1] != u'\0');
CECDU_ReadRawFile(read, &sizeWritten);
Expand Down Expand Up @@ -432,8 +424,40 @@ void dumpBoxes()
void waitForInput()
{
while (aptMainLoop() && !hidKeysDown()) hidScanInput();
hidScanInput();
}

/*
A testing function for CECDU_SetData
Findings:
0: opens OBIndex and OutBox BoxInfo
1-3: Invalid argument errors
- Perhaps change buffer size?
4: deletes the CEC directory
5: commits changes?
6: archive not mounted error
7+: does nothing; returns 0
*/
// int main()
// {
// u8 dummy[10000];
// gfxInitDefault();
// hidInit();
// hidScanInput();
// sdmcInit();
// consoleInit(GFX_TOP, nullptr);
// cecduInit();
// Result res;
// for (u32 i = 0; i < 0x10000; i++)
// {
// waitForInput();
// if (R_SUCCEEDED(res = CECDU_SetData(0x0010bf00, i, dummy, 10000))) printf("%i", i);
// else printf("%X", res);
// }
// cecduExit();
// return 0;
// }

int main()
{
Result res;
Expand Down Expand Up @@ -492,104 +516,4 @@ int main()
}
cecduExit();
return 0;
}

int main4() // Deletes all messages from Kirby
{
Result res;
gfxInitDefault();
hidInit();
consoleInit(GFX_TOP, nullptr);
if (R_FAILED(res = cecduInit())) printf("Init: %X", res);
Box kirby(0x0010bf00);
if (R_FAILED(res = kirby.clearMessages())) printf("Clearing messages: %X", res);
return 0;
}

int main3() // Reads all boxes and their message IDs
{
Result res;
gfxInitDefault();
hidInit();
consoleInit(GFX_TOP, nullptr);
if (R_FAILED(res = cecduInit())) printf("Init: %X", res);
boxList list;
size_t sizeWritten = sizeof(struct boxList);
CECDU_OpenRawFile(0x0, CEC_PATH_MBOX_LIST, CEC_READ | CEC_CHECK);
CECDU_ReadRawFile(&list, &sizeWritten);
for (size_t i = 0; i < list.numBoxes; i++)
{
u32 id = strtoul(list.boxId[i], NULL, 16);
Box box(id);
printf("Box %u: %s %X\n", i, list.boxId[i], strtoul(list.boxId[i], NULL, 16));
// for (auto message : box.messageNames())
// {
// printf(" %s\n", message.c_str());
// }
while (aptMainLoop() && !(hidKeysDown() & KEY_A)) hidScanInput();
hidScanInput();
}
while (aptMainLoop() && !(hidKeysDown() & KEY_START)) hidScanInput();
cecduExit();
hidExit();
gfxExit();
return 0;
}

int main2()
{
gfxInitDefault();
hidInit();
consoleInit(GFX_TOP, nullptr);
printf("Here goes nothing");
Result res = cecduInit();
if (R_FAILED(res)) printf("Init\n%X", res);
// CECDU_WriteMessage(0x0010bf00, false, id, (void*) "What happens now?", 18);
// u8 dataRead[30];
// std::fill_n(dataRead, 30, '\0');
size_t bufferSize = 30;
// CECDU_ReadMessage(0x0010bf00, false, id, (void*) dataRead, &bufferSize);
// dataRead[29] = '\0';
// printf("\n%i bytes read", bufferSize);
// printf("\nData: %s", dataRead);
u8* infoRead = new u8[32];
bufferSize = 32;
std::fill_n(infoRead, 32, '\0');
res = CECDU_OpenAndRead(0x0010bf00, CEC_PATH_INBOX_INFO, CEC_READ | CEC_WRITE | CEC_CHECK, infoRead, &bufferSize);
if (R_FAILED(res)) printf("Read info 1\n%X", res);
BoxInfo info(infoRead, false);
if (info.currentMessages() > 0)
{
delete[] infoRead;
infoRead = new u8[bufferSize = info.fileSize()];
res = CECDU_OpenAndRead(0x0010bf00, CEC_PATH_INBOX_INFO, CEC_READ | CEC_WRITE | CEC_CHECK, infoRead, &bufferSize);
if (R_FAILED(res)) printf("Read info 2\n%X", res);
info = BoxInfo(infoRead);
}
std::ifstream in("/data.cec", std::ios::ate | std::ios::in);
size_t size = in.tellg();
in.seekg(0, std::ios::beg);
delete[] infoRead;
infoRead = new u8[size];
in.read((char*)infoRead, size);
in.close();
Message m(infoRead);
info.addMessage(m);
cecMessageId id;
MessageInfo mInfo = m.getInfo();
// std::copy(mInfo.messageID(), mInfo.messageID() + 8, id.data);
res = CECDU_WriteMessage(0x0010bf00, false, id, infoRead, size);
if (R_FAILED(res)) printf("Write Message\n%X", res);
std::vector<u8> data = info.data();
res = CECDU_Delete(0x0010bf00, CEC_PATH_INBOX_INFO, false, id);
if (R_FAILED(res)) printf("Delete Info\n%X", res);
res = CECDU_OpenAndWrite(0x0010bf00, CEC_PATH_INBOX_INFO, CEC_WRITE | CEC_CHECK, data.data(), data.size());
if (R_FAILED(res)) printf("Write Info\n%X", res);
Box kirby(0x0010bf00);
//printf("%s", kirby.messageNames().c_str());
while (aptMainLoop() && !(hidKeysDown() & KEY_START)) hidScanInput();
hidExit();
cecduExit();
gfxExit();
return 0;
}

0 comments on commit c224f8d

Please sign in to comment.