mirror of
https://github.com/zeldaret/ss
synced 2026-05-24 07:10:53 -04:00
Merge pull request #120 from robojumper/nand_request_thread
NandRequestThread
This commit is contained in:
@@ -243,6 +243,10 @@ toBeSorted/time_area_mgr.cpp:
|
||||
.sbss start:0x805753C0 end:0x805753D0
|
||||
.sdata2 start:0x805798D0 end:0x80579928
|
||||
|
||||
toBeSorted/nand_request_thread.cpp:
|
||||
.text start:0x800BC980 end:0x800BD604
|
||||
.data start:0x80510B30 end:0x80510B70
|
||||
|
||||
d/flag/flag_managers.cpp:
|
||||
.text start:0x800BD8C0 end:0x800C0650
|
||||
.data start:0x80510B88 end:0x80510D10
|
||||
|
||||
+34
-34
@@ -4028,35 +4028,35 @@ fn_800BC8A0 = .text:0x800BC8A0; // type:function size:0x50
|
||||
fn_800BC8F0 = .text:0x800BC8F0; // type:function size:0x24
|
||||
fn_800BC920 = .text:0x800BC920; // type:function size:0x8
|
||||
dTimeArea__sinit = .text:0x800BC930; // type:function size:0x48
|
||||
NandRequestThread__ctor = .text:0x800BC980; // type:function size:0xC8
|
||||
fn_800BCA50 = .text:0x800BCA50; // type:function size:0x60
|
||||
NandRequestThread__start = .text:0x800BCAB0; // type:function size:0x84
|
||||
fn_800BCB40 = .text:0x800BCB40; // type:function size:0x84
|
||||
fn_800BCBD0 = .text:0x800BCBD0; // type:function size:0x7C
|
||||
fn_800BCC50 = .text:0x800BCC50; // type:function size:0x7C
|
||||
NandRequestThread__waitForMessage = .text:0x800BCCD0; // type:function size:0x38
|
||||
NandRequestThread__sendMsg = .text:0x800BCD10; // type:function size:0x10
|
||||
NandRequestThread__enqueueRequest = .text:0x800BCD20; // type:function size:0x58
|
||||
NandRequestThread__popReadCmd = .text:0x800BCD80; // type:function size:0xBC
|
||||
fn_800BCE40 = .text:0x800BCE40; // type:function size:0x78
|
||||
allocateNandRequestMaybe = .text:0x800BCEC0; // type:function size:0x20
|
||||
fn_800BCEE0 = .text:0x800BCEE0; // type:function size:0x1C
|
||||
fn_800BCF00 = .text:0x800BCF00; // type:function size:0x8
|
||||
fn_800BCF10 = .text:0x800BCF10; // type:function size:0x34
|
||||
fn_800BCF50 = .text:0x800BCF50; // type:function size:0x40
|
||||
fn_800BCF90 = .text:0x800BCF90; // type:function size:0xE4
|
||||
fn_800BD080 = .text:0x800BD080; // type:function size:0x50
|
||||
fn_800BD0D0 = .text:0x800BD0D0; // type:function size:0x16C
|
||||
fn_800BD240 = .text:0x800BD240; // type:function size:0xE8
|
||||
fn_800BD330 = .text:0x800BD330; // type:function size:0xE0
|
||||
fn_800BD410 = .text:0x800BD410; // type:function size:0x1C
|
||||
fn_800BD430 = .text:0x800BD430; // type:function size:0x18
|
||||
fn_800BD450 = .text:0x800BD450; // type:function size:0x60
|
||||
fn_800BD4B0 = .text:0x800BD4B0; // type:function size:0x5C
|
||||
fn_800BD510 = .text:0x800BD510; // type:function size:0xC
|
||||
fn_800BD520 = .text:0x800BD520; // type:function size:0x5C
|
||||
fn_800BD580 = .text:0x800BD580; // type:function size:0x5C
|
||||
fn_800BD5E0 = .text:0x800BD5E0; // type:function size:0xC
|
||||
__ct__17NandRequestThreadFiPQ23EGG4HeapPvUlPvPQ23EGG4Heap = .text:0x800BC980; // type:function size:0xC8
|
||||
__dt__17NandRequestThreadFv = .text:0x800BCA50; // type:function size:0x60
|
||||
run__17NandRequestThreadFv = .text:0x800BCAB0; // type:function size:0x84
|
||||
checkRequest__17NandRequestThreadFUlUl = .text:0x800BCB40; // type:function size:0x84
|
||||
createRequest__17NandRequestThreadFPCcUcUc = .text:0x800BCBD0; // type:function size:0x7C
|
||||
writeRequest__17NandRequestThreadFPCcPvUl = .text:0x800BCC50; // type:function size:0x7C
|
||||
waitForMessage__17NandRequestThreadFv = .text:0x800BCCD0; // type:function size:0x38
|
||||
sendMessage__17NandRequestThreadFv = .text:0x800BCD10; // type:function size:0x10
|
||||
enqueueRequest__17NandRequestThreadFP11NandRequest = .text:0x800BCD20; // type:function size:0x58
|
||||
dequeueRequest__17NandRequestThreadFv = .text:0x800BCD80; // type:function size:0xBC
|
||||
create__17NandRequestThreadFiPQ23EGG4HeapPvUlPvPQ23EGG4Heap = .text:0x800BCE40; // type:function size:0x78
|
||||
__nw__11NandRequestFUl = .text:0x800BCEC0; // type:function size:0x20
|
||||
free__11NandRequestFP11NandRequest = .text:0x800BCEE0; // type:function size:0x1C
|
||||
getStatus__11NandRequestCFv = .text:0x800BCF00; // type:function size:0x8
|
||||
__ct__16NandRequestCheckFUlUl = .text:0x800BCF10; // type:function size:0x34
|
||||
execute__16NandRequestCheckFv = .text:0x800BCF50; // type:function size:0x40
|
||||
__ct__17NandRequestCreateFPCcUcUc = .text:0x800BCF90; // type:function size:0xE4
|
||||
splitComponent__FPCcPcUl = .text:0x800BD080; // type:function size:0x50
|
||||
execute__17NandRequestCreateFv = .text:0x800BD0D0; // type:function size:0x16C
|
||||
__ct__16NandRequestWriteFPCcPvUl = .text:0x800BD240; // type:function size:0xE8
|
||||
execute__16NandRequestWriteFv = .text:0x800BD330; // type:function size:0xE0
|
||||
isCompleted__21NandRequestHolderBaseCFv = .text:0x800BD410; // type:function size:0x1C
|
||||
getStatus__21NandRequestHolderBaseCFv = .text:0x800BD430; // type:function size:0x18
|
||||
runToCompletion__21NandRequestHolderBaseFv = .text:0x800BD450; // type:function size:0x60
|
||||
check__22NandRequestCheckHolderFUlUl = .text:0x800BD4B0; // type:function size:0x5C
|
||||
getCheckResult__22NandRequestCheckHolderFv = .text:0x800BD510; // type:function size:0xC
|
||||
create__23NandRequestCreateHolderFPCcUcUc = .text:0x800BD520; // type:function size:0x5C
|
||||
write__22NandRequestWriteHolderFPCcPvUl = .text:0x800BD580; // type:function size:0x5C
|
||||
failedWrite__22NandRequestWriteHolderFv = .text:0x800BD5E0; // type:function size:0xC
|
||||
onExit__Q23EGG6ThreadFv = .text:0x800BD5F0; // type:function size:0x4
|
||||
onEnter__Q23EGG6ThreadFv = .text:0x800BD600; // type:function size:0x4
|
||||
fn_800BD610 = .text:0x800BD610; // type:function size:0x34
|
||||
@@ -31009,10 +31009,10 @@ someVtable = .data:0x80510A78; // type:object size:0x30
|
||||
lbl_80510AA8 = .data:0x80510AA8; // type:object size:0x30
|
||||
lbl_80510AD8 = .data:0x80510AD8; // type:object size:0x2C
|
||||
lbl_80510B04 = .data:0x80510B04; // type:object size:0x2C
|
||||
NandRequestThread__vtable = .data:0x80510B30; // type:object size:0x18
|
||||
lbl_80510B48 = .data:0x80510B48; // type:object size:0xC
|
||||
lbl_80510B54 = .data:0x80510B54; // type:object size:0xC
|
||||
lbl_80510B60 = .data:0x80510B60; // type:object size:0x10
|
||||
__vt__17NandRequestThread = .data:0x80510B30; // type:object size:0x18
|
||||
__vt__16NandRequestWrite = .data:0x80510B48; // type:object size:0xC
|
||||
__vt__17NandRequestCreate = .data:0x80510B54; // type:object size:0xC
|
||||
__vt__16NandRequestCheck = .data:0x80510B60; // type:object size:0xC
|
||||
lbl_80510B70 = .data:0x80510B70; // type:object size:0x18
|
||||
__vt__32MyFlagManager<15ItemflagManager> = .data:0x80510B88; // type:object size:0x3C scope:weak
|
||||
__vt__33MyFlagManager<16StoryflagManager> = .data:0x80510BC4; // type:object size:0x3C scope:weak
|
||||
@@ -40069,7 +40069,7 @@ lbl_805753BC = .sbss:0x805753BC; // type:object size:0x4 data:4byte
|
||||
sInstance__14dTimeAreaMgr_c = .sbss:0x805753C0; // type:object size:0x4 data:4byte
|
||||
TIMESHIFT_TRANSITION_BORDER_COLOR = .sbss:0x805753C4; // type:object size:0x1 data:byte
|
||||
CURR_TIMESHIFT_STONE_ACTIVE = .sbss:0x805753C8; // type:object size:0x8 data:4byte
|
||||
NAND_REQUEST_THREAD = .sbss:0x805753D0; // type:object size:0x8 data:4byte
|
||||
sInstance__17NandRequestThread = .sbss:0x805753D0; // type:object size:0x8 data:4byte
|
||||
lbl_805753D8 = .sbss:0x805753D8; // type:object size:0x8 data:4byte
|
||||
sInstance__16SceneflagManager = .sbss:0x805753E0; // type:object size:0x4 data:4byte
|
||||
sTempFlags__16SceneflagManager = .sbss:0x805753E8; // type:object size:0x8
|
||||
|
||||
@@ -364,6 +364,7 @@ config.libs = [
|
||||
Object(NonMatching, "toBeSorted/attention.cpp"),
|
||||
Object(NonMatching, "toBeSorted/dowsing_target.cpp"),
|
||||
Object(NonMatching, "toBeSorted/time_area_mgr.cpp"),
|
||||
Object(NonMatching, "toBeSorted/nand_request_thread.cpp"),
|
||||
Object(Matching, "toBeSorted/save_file.cpp"),
|
||||
Object(Matching, "toBeSorted/counters/counter.cpp"),
|
||||
Object(Matching, "toBeSorted/counters/rupee_counter.cpp"),
|
||||
|
||||
@@ -28,7 +28,7 @@ public:
|
||||
/* 0x38 */ u32 mStackSize;
|
||||
/* 0x3C */ Heap *mAllocatableHeap;
|
||||
// TODO from the usage in eggThread this really looks like
|
||||
// it's stashed thread that's restored when switching threads
|
||||
// it's a stashed heap that's restored when switching threads
|
||||
/* 0x40 */ Heap *mCurrentHeap;
|
||||
/* 0x44 */ nw4r::ut::Node mLink;
|
||||
|
||||
|
||||
@@ -0,0 +1,140 @@
|
||||
#ifndef NAND_REQUEST_H
|
||||
#define NAND_REQUEST_H
|
||||
|
||||
#include "common.h"
|
||||
#include "egg/core/eggHeap.h"
|
||||
#include "egg/core/eggThread.h"
|
||||
#include "rvl/NAND/nand.h"
|
||||
#include "rvl/OS/OSMessage.h"
|
||||
#include "rvl/OS/OSMutex.h"
|
||||
#include "sized_string.h"
|
||||
#include "toBeSorted/tlist.h"
|
||||
|
||||
struct NandRequest {
|
||||
NandRequest() : mStatus(NAND_RESULT_BUSY), bHandled(false) {}
|
||||
~NandRequest() {}
|
||||
virtual bool execute() = 0;
|
||||
|
||||
/* 0x04 */ TListNode<NandRequest> mNode;
|
||||
/* 0x0C */ NANDResult mStatus;
|
||||
/* 0x10 */ bool bHandled;
|
||||
|
||||
static void *operator new(size_t size);
|
||||
static void free(NandRequest *);
|
||||
|
||||
NANDResult getStatus() const;
|
||||
};
|
||||
|
||||
struct NandRequestCheck : public NandRequest {
|
||||
NandRequestCheck(u32 neededBlocks, u32 neededFiles);
|
||||
|
||||
virtual bool execute() override;
|
||||
|
||||
/* 0x14 */ u32 mNeededBlocks;
|
||||
/* 0x18 */ u32 mNeededFiles;
|
||||
/* 0x1C */ u32 mResult;
|
||||
};
|
||||
|
||||
struct NandRequestCreate : public NandRequest {
|
||||
NandRequestCreate(const char *filePath, u8 perm, u8 attr);
|
||||
|
||||
virtual bool execute() override;
|
||||
|
||||
// cursed offsets
|
||||
/* 0x11 */ SizedString<64> mFilePath;
|
||||
/* 0x51 */ u8 mPerm;
|
||||
/* 0x52 */ u8 mAttr;
|
||||
};
|
||||
|
||||
struct NandRequestWrite : public NandRequest {
|
||||
NandRequestWrite(const char *str, void *data, size_t dataSize);
|
||||
|
||||
virtual bool execute() override;
|
||||
|
||||
/* 0x11 */ SizedString<64> mFilePath;
|
||||
/* 0x54 */ void *mData;
|
||||
/* 0x58 */ size_t mDataSize;
|
||||
/* 0x5C */ bool mFailedWrite;
|
||||
};
|
||||
|
||||
struct NandRequestHolderBase {
|
||||
NandRequestHolderBase(NandRequest *req) : mpRequest(req) {}
|
||||
NandRequest *mpRequest;
|
||||
|
||||
bool isCompleted() const;
|
||||
NANDResult getStatus() const;
|
||||
bool runToCompletion();
|
||||
};
|
||||
|
||||
struct NandRequestCheckHolder : public NandRequestHolderBase {
|
||||
NandRequestCheckHolder(NandRequestCheck *req) : NandRequestHolderBase(req) {}
|
||||
|
||||
bool check(u32 neededBlocks, u32 neededFiles);
|
||||
u32 getCheckResult();
|
||||
};
|
||||
|
||||
struct NandRequestCreateHolder : public NandRequestHolderBase {
|
||||
NandRequestCreateHolder(NandRequestCreate *req) : NandRequestHolderBase(req) {}
|
||||
|
||||
bool create(const char *filePath, u8 perm, u8 attr);
|
||||
};
|
||||
|
||||
struct NandRequestWriteHolder : public NandRequestHolderBase {
|
||||
NandRequestWriteHolder(NandRequestWrite *req) : NandRequestHolderBase(req) {}
|
||||
bool failedWrite();
|
||||
|
||||
bool write(const char *filePath, void *data, size_t dataSize);
|
||||
};
|
||||
|
||||
class NandRequestThread : EGG::Thread {
|
||||
friend NandRequest;
|
||||
|
||||
public:
|
||||
NandRequestThread(
|
||||
int priority, EGG::Heap *commandHeap, void *bufFromGameHeap, size_t bufSize, void *mThreadArg, EGG::Heap *heap
|
||||
);
|
||||
virtual ~NandRequestThread();
|
||||
|
||||
virtual void *run() override;
|
||||
void enqueueRequest(NandRequest *request);
|
||||
NandRequest *dequeueRequest();
|
||||
|
||||
static NandRequestThread *create(
|
||||
int priority, EGG::Heap *commandHeap, void *bufFromGameHeap, size_t bufSize, void *mThreadArg, EGG::Heap *heap
|
||||
);
|
||||
|
||||
static NandRequestThread *getInstance() {
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
void *getBuf() {
|
||||
return mBufFromGameHeap;
|
||||
}
|
||||
|
||||
size_t getBufSize() {
|
||||
return mBufSize;
|
||||
}
|
||||
|
||||
NandRequestCheck *checkRequest(u32 neededBlocks, u32 neededFiles);
|
||||
NandRequestCreate *createRequest(const char *filePath, u8 perm, u8 attr);
|
||||
NandRequestWrite *writeRequest(const char *filePath, void *data, size_t dataSize);
|
||||
|
||||
private:
|
||||
typedef TList<NandRequest, offsetof(NandRequest, mNode)> NandRequestList;
|
||||
static NandRequestThread *sInstance;
|
||||
|
||||
bool waitForMessage();
|
||||
void sendMessage();
|
||||
|
||||
u8 field_0x4C[0x368 - 0x4C];
|
||||
/* 0x368 */ OSMessageQueue mMessageQueue;
|
||||
/* 0x388 */ OSMessage mMessageBuffer;
|
||||
/* 0x38C */ OSMutex mMutex;
|
||||
/* 0x3A4 */ NandRequestList mRequestList;
|
||||
/* 0x3B0 */ EGG::Heap *mpCommandHeap;
|
||||
/* 0x3B4 */ void *mBufFromGameHeap;
|
||||
/* 0x3B8 */ size_t mBufSize;
|
||||
/* 0x3BC */ UNKWORD field_0x3BC;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -124,6 +124,16 @@ public:
|
||||
mCount--;
|
||||
}
|
||||
|
||||
T* GetFirst() {
|
||||
return GetPtrFromNode(&mStartEnd);
|
||||
}
|
||||
|
||||
void RemoveFirst() {
|
||||
if (mCount != 0) {
|
||||
remove(GetFirst());
|
||||
}
|
||||
}
|
||||
|
||||
TNode mStartEnd;
|
||||
s32 mCount;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,321 @@
|
||||
#include "toBeSorted/nand_request_thread.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "egg/core/eggAssertHeap.h" // IWYU pragma: export
|
||||
#include "egg/core/eggThread.h"
|
||||
#include "m/m_heap.h"
|
||||
#include "rvl/NAND/NANDCheck.h"
|
||||
#include "rvl/NAND/NANDCore.h"
|
||||
#include "rvl/NAND/nand.h"
|
||||
#include "rvl/OS/OSMessage.h"
|
||||
#include "rvl/OS/OSMutex.h"
|
||||
#include "rvl/OS/OSThread.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
extern "C" void fn_802F2920(OSThread *, size_t);
|
||||
|
||||
NandRequestThread::NandRequestThread(
|
||||
int priority, EGG::Heap *commandHeap, void *bufFromGameHeap, size_t bufSize, void *mThreadArg, EGG::Heap *heap
|
||||
)
|
||||
: EGG::Thread(0x4000, 0, priority, heap), mMessageBuffer(nullptr) {
|
||||
// TODO suffers from TList ctor
|
||||
sInstance = this;
|
||||
|
||||
mpCommandHeap = commandHeap;
|
||||
mBufFromGameHeap = bufFromGameHeap;
|
||||
mBufSize = bufSize;
|
||||
|
||||
setThreadCurrentHeap(mHeap::g_assertHeap);
|
||||
fn_802F2920(mOSThread, bufSize);
|
||||
OSInitMessageQueue(&mMessageQueue, &mMessageBuffer, 1);
|
||||
OSInitMutex(&mMutex);
|
||||
OSResumeThread(mOSThread);
|
||||
}
|
||||
|
||||
NandRequestThread::~NandRequestThread() {
|
||||
sInstance = nullptr;
|
||||
}
|
||||
|
||||
void *NandRequestThread::run() {
|
||||
NandRequest *req;
|
||||
while (waitForMessage()) {
|
||||
while (mRequestList.mCount != 0) {
|
||||
req = dequeueRequest();
|
||||
req->execute();
|
||||
req->bHandled = true;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
NandRequestCheck *NandRequestThread::checkRequest(u32 neededBlocks, u32 neededFiles) {
|
||||
NandRequestCheck *req = new NandRequestCheck(neededBlocks, neededFiles);
|
||||
if (req != nullptr) {
|
||||
enqueueRequest(req);
|
||||
}
|
||||
return req;
|
||||
}
|
||||
|
||||
NandRequestCreate *NandRequestThread::createRequest(const char *filePath, u8 perm, u8 attr) {
|
||||
NandRequestCreate *req = new NandRequestCreate(filePath, perm, attr);
|
||||
if (req != nullptr) {
|
||||
enqueueRequest(req);
|
||||
}
|
||||
return req;
|
||||
}
|
||||
|
||||
NandRequestWrite *NandRequestThread::writeRequest(const char *filePath, void *data, size_t dataSize) {
|
||||
NandRequestWrite *req = new NandRequestWrite(filePath, data, dataSize);
|
||||
if (req != nullptr) {
|
||||
enqueueRequest(req);
|
||||
}
|
||||
return req;
|
||||
}
|
||||
|
||||
bool NandRequestThread::waitForMessage() {
|
||||
return OSReceiveMessage(&mMessageQueue, nullptr, OS_MSG_PERSISTENT);
|
||||
}
|
||||
|
||||
void NandRequestThread::sendMessage() {
|
||||
OSSendMessage(&mMessageQueue, nullptr, 0);
|
||||
}
|
||||
|
||||
void NandRequestThread::enqueueRequest(NandRequest *request) {
|
||||
mRequestList.insert(request);
|
||||
sendMessage();
|
||||
}
|
||||
|
||||
NandRequest *NandRequestThread::dequeueRequest() {
|
||||
// TODO TList
|
||||
NandRequest *req = mRequestList.GetFirst();
|
||||
|
||||
OSLockMutex(&mMutex);
|
||||
mRequestList.RemoveFirst();
|
||||
OSUnlockMutex(&mMutex);
|
||||
|
||||
sendMessage();
|
||||
return req;
|
||||
}
|
||||
|
||||
NandRequestThread *NandRequestThread::create(
|
||||
int priority, EGG::Heap *commandHeap, void *bufFromGameHeap, size_t bufSize, void *mThreadArg, EGG::Heap *heap
|
||||
) {
|
||||
return new (heap, 0x04) NandRequestThread(priority, commandHeap, bufFromGameHeap, bufSize, mThreadArg, heap);
|
||||
}
|
||||
|
||||
void *NandRequest::operator new(size_t size) {
|
||||
return NandRequestThread::sInstance->mpCommandHeap->alloc(size, -4);
|
||||
}
|
||||
|
||||
void NandRequest::free(NandRequest *ptr) {
|
||||
return NandRequestThread::sInstance->mpCommandHeap->free(ptr);
|
||||
}
|
||||
|
||||
NANDResult NandRequest::getStatus() const {
|
||||
return mStatus;
|
||||
}
|
||||
|
||||
NandRequestCheck::NandRequestCheck(u32 neededBlocks, u32 neededFiles) {
|
||||
mResult = 0;
|
||||
mNeededBlocks = neededBlocks;
|
||||
mNeededFiles = neededFiles;
|
||||
}
|
||||
|
||||
bool NandRequestCheck::execute() {
|
||||
mStatus = NANDCheck(mNeededBlocks, mNeededFiles, &mResult);
|
||||
return true;
|
||||
}
|
||||
|
||||
NandRequestCreate::NandRequestCreate(const char *filePath, u8 perm, u8 attr) {
|
||||
mPerm = perm;
|
||||
mAttr = attr;
|
||||
mFilePath = filePath;
|
||||
}
|
||||
|
||||
const char *splitComponent(const char *inPath, char *outPath, size_t size) {
|
||||
char *end = outPath + size - 1;
|
||||
while (true) {
|
||||
if (outPath >= end) {
|
||||
break;
|
||||
}
|
||||
char curr = inPath[0];
|
||||
char next = inPath[1];
|
||||
inPath++;
|
||||
*outPath = curr;
|
||||
outPath++;
|
||||
if (next == '\0' || next == '/') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
*outPath = '\0';
|
||||
char curr = *inPath;
|
||||
if (curr != '/') {
|
||||
return inPath;
|
||||
}
|
||||
return inPath + 1;
|
||||
}
|
||||
|
||||
extern "C" NANDResult NANDChangeDir(const char *path);
|
||||
extern "C" NANDResult NANDCreateDir(const char *path, u8 perm, u8 attr);
|
||||
|
||||
bool NandRequestCreate::execute() {
|
||||
char homeDir[64];
|
||||
char pathComponent[64];
|
||||
|
||||
mStatus = NANDGetHomeDir(homeDir);
|
||||
if (mStatus != NAND_RESULT_OK) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const char *ptr = mFilePath;
|
||||
if (ptr[0] == '/') {
|
||||
ptr = splitComponent(ptr, pathComponent, sizeof(pathComponent));
|
||||
} else {
|
||||
std::strncpy(pathComponent, homeDir, sizeof(pathComponent));
|
||||
}
|
||||
|
||||
mStatus = NANDChangeDir(pathComponent);
|
||||
if (mStatus != NAND_RESULT_OK) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const char *component = splitComponent(ptr, pathComponent, sizeof(pathComponent));
|
||||
while (component[0] != '\0') {
|
||||
mStatus = NANDCreateDir(pathComponent, mPerm, mAttr);
|
||||
if (mStatus != NAND_RESULT_OK && mStatus != NAND_RESULT_EXISTS) {
|
||||
return true;
|
||||
}
|
||||
mStatus = NANDChangeDir(pathComponent);
|
||||
if (mStatus != NAND_RESULT_OK) {
|
||||
return true;
|
||||
}
|
||||
component = splitComponent(component, pathComponent, sizeof(pathComponent));
|
||||
}
|
||||
|
||||
mStatus = NANDChangeDir(homeDir);
|
||||
if (mStatus != NAND_RESULT_OK) {
|
||||
return true;
|
||||
}
|
||||
|
||||
mStatus = NANDCreate(mFilePath, mPerm, mAttr);
|
||||
return mStatus == NAND_RESULT_OK || mStatus == NAND_RESULT_EXISTS;
|
||||
}
|
||||
|
||||
NandRequestWrite::NandRequestWrite(const char *someString, void *data, size_t dataSize) {
|
||||
mData = data;
|
||||
mDataSize = dataSize;
|
||||
mFailedWrite = false;
|
||||
mFilePath = someString;
|
||||
}
|
||||
|
||||
extern "C" NANDResult NANDSimpleSafeOpen(const char *path, NANDFileInfo *outInfo, int, void *buf, size_t bufLen);
|
||||
extern "C" NANDResult NANDSimpleSafeCancel(NANDFileInfo *info);
|
||||
extern "C" NANDResult NANDSimpleSafeClose(NANDFileInfo *info);
|
||||
|
||||
bool NandRequestWrite::execute() {
|
||||
NANDFileInfo info;
|
||||
mStatus = NANDSimpleSafeOpen(
|
||||
mFilePath, &info, 2, NandRequestThread::getInstance()->getBuf(), NandRequestThread::getInstance()->getBufSize()
|
||||
);
|
||||
if (mStatus != NAND_RESULT_OK) {
|
||||
NANDResult res = NANDSimpleSafeCancel(&info);
|
||||
if (res != NAND_RESULT_OK) {
|
||||
mStatus = res;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
mStatus = NANDWrite(&info, mData, mDataSize);
|
||||
if (mStatus == NAND_RESULT_ECC_CRIT || mStatus == NAND_RESULT_AUTHENTICATION) {
|
||||
mStatus = NANDSimpleSafeCancel(&info);
|
||||
if (mStatus == NAND_RESULT_OK) {
|
||||
mFailedWrite = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
NANDResult res = NANDSimpleSafeClose(&info);
|
||||
if (mStatus != mDataSize) {
|
||||
mFailedWrite = true;
|
||||
} else {
|
||||
mStatus = res;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NandRequestHolderBase::isCompleted() const {
|
||||
if (mpRequest != nullptr) {
|
||||
return mpRequest->bHandled;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
NANDResult NandRequestHolderBase::getStatus() const {
|
||||
if (mpRequest != nullptr) {
|
||||
return mpRequest->getStatus();
|
||||
}
|
||||
return NAND_RESULT_BUSY;
|
||||
}
|
||||
|
||||
bool NandRequestHolderBase::runToCompletion() {
|
||||
if (mpRequest == nullptr) {
|
||||
return true;
|
||||
}
|
||||
|
||||
do {
|
||||
} while (!isCompleted());
|
||||
NandRequest::free(mpRequest);
|
||||
mpRequest = nullptr;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NandRequestCheckHolder::check(u32 neededBlocks, u32 neededFiles) {
|
||||
if (mpRequest != nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
NandRequestCheck *req = NandRequestThread::getInstance()->checkRequest(neededBlocks, neededFiles);
|
||||
if (req == nullptr) {
|
||||
return false;
|
||||
}
|
||||
mpRequest = req;
|
||||
return true;
|
||||
}
|
||||
|
||||
u32 NandRequestCheckHolder::getCheckResult() {
|
||||
return static_cast<NandRequestCheck *>(mpRequest)->mResult;
|
||||
}
|
||||
|
||||
bool NandRequestCreateHolder::create(const char *filePath, u8 perm, u8 attr) {
|
||||
if (mpRequest != nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
NandRequestCreate *req = NandRequestThread::getInstance()->createRequest(filePath, perm, attr);
|
||||
if (req == nullptr) {
|
||||
return false;
|
||||
}
|
||||
mpRequest = req;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NandRequestWriteHolder::write(const char *filePath, void *data, size_t dataSize) {
|
||||
if (mpRequest != nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
NandRequestWrite *req = NandRequestThread::getInstance()->writeRequest(filePath, data, dataSize);
|
||||
if (req == nullptr) {
|
||||
return false;
|
||||
}
|
||||
mpRequest = req;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NandRequestWriteHolder::failedWrite() {
|
||||
return static_cast<NandRequestWrite *>(mpRequest)->mFailedWrite;
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
# Thanks KooShnoo! https://discord.com/channels/727908905392275526/1024871155804426310/1329716224971767891
|
||||
|
||||
"""
|
||||
objdiff allows one to map symbols from the target binary to the source binary.
|
||||
this script will take those symbols you have mapped, and write them to `symbols.txt`.
|
||||
|
||||
use case: say you have changed the signature/name of a function.
|
||||
now, your source file says `foo_Ful`, but symbols.txt says `bar__Fl`.
|
||||
objdiff allows you to map the `foo_Ful` in the target object to `bar__Fl` in the source object.
|
||||
this script allows you to replace `foo_Ful` with `bar__Fl` in `symbols.txt`.
|
||||
"""
|
||||
|
||||
import json
|
||||
|
||||
with open("./objdiff.json") as f:
|
||||
objdiff_config = json.load(f)
|
||||
|
||||
# lol python has types. it's typython. typescript all over again
|
||||
units: list = objdiff_config["units"]
|
||||
symbol_mappings_list = list(
|
||||
filter(None, [unit.get("symbol_mappings") for unit in units])
|
||||
)
|
||||
|
||||
symbol_mappings = {}
|
||||
for unit in units:
|
||||
symbol_mapping = unit.get("symbol_mappings")
|
||||
if symbol_mapping is None:
|
||||
continue
|
||||
symbol_mappings.update(symbol_mapping)
|
||||
del unit['symbol_mappings']
|
||||
|
||||
|
||||
with open("./config/SOUE01/symbols.txt") as f:
|
||||
symbols = f.readlines()
|
||||
|
||||
for i, line in enumerate(symbols):
|
||||
tokens = line.split()
|
||||
old_symbol = tokens[0]
|
||||
|
||||
new_symbol = symbol_mappings.get(old_symbol)
|
||||
|
||||
if new_symbol is None:
|
||||
continue
|
||||
|
||||
tokens[0] = new_symbol
|
||||
symbols[i] = " ".join(tokens) + "\n"
|
||||
|
||||
with open("./config/SOUE01/symbols.txt", "w") as f:
|
||||
f.writelines(symbols)
|
||||
|
||||
with open("./objdiff.json", "w") as f:
|
||||
json.dump(objdiff_config, f)
|
||||
Reference in New Issue
Block a user