/modules/vmc/mcman/main.c
C | 2760 lines | 2117 code | 552 blank | 91 comment | 742 complexity | 74780b93695f13d830c9ce31099b852c MD5 | raw file
Possible License(s): CC-BY-SA-3.0, MPL-2.0-no-copyleft-exception, GPL-2.0
Large files files are truncated, but you can click here to view the full file
- /*
- Copyright 2009-2010, jimmikaelkael
- Licenced under Academic Free License version 3.0
- Review Open PS2 Loader README & LICENSE files for further details.
- */
- #include "mcman.h"
- IRX_ID(MODNAME, 1, 1);
- struct modInfo_t mcman_modInfo = { "mcman_cex", 0x20b };
- char sio2man_modname[8] = "sio2man\0";
- int sio2man_type = SIO2MAN;
- char SUPERBLOCK_MAGIC[] = "Sony PS2 Memory Card Format ";
- char SUPERBLOCK_VERSION[] = "1.2.0.0";
- int mcman_wr_port = -1;
- int mcman_wr_slot = -1;
- int mcman_wr_block = -1;
- int mcman_wr_flag3 = -10;
- int mcman_curdircluster = -1;
- u32 DOT = 0x0000002e;
- u32 DOTDOT = 0x00002e2e;
- int timer_ID;
- int PS1CardFlag = 1;
- // mcman xor table
- u8 mcman_xortable[256] = {
- 0x00, 0x87, 0x96, 0x11, 0xA5, 0x22, 0x33, 0xB4,
- 0xB4, 0x33, 0x22, 0xA5, 0x11, 0x96, 0x87, 0x00,
- 0xC3, 0x44, 0x55, 0xD2, 0x66, 0xE1, 0xF0, 0x77,
- 0x77, 0xF0, 0xE1, 0x66, 0xD2, 0x55, 0x44, 0xC3,
- 0xD2, 0x55, 0x44, 0xC3, 0x77, 0xF0, 0xE1, 0x66,
- 0x66, 0xE1, 0xF0, 0x77, 0xC3, 0x44, 0x55, 0xD2,
- 0x11, 0x96, 0x87, 0x00, 0xB4, 0x33, 0x22, 0xA5,
- 0xA5, 0x22, 0x33, 0xB4, 0x00, 0x87, 0x96, 0x11,
- 0xE1, 0x66, 0x77, 0xF0, 0x44, 0xC3, 0xD2, 0x55,
- 0x55, 0xD2, 0xC3, 0x44, 0xF0, 0x77, 0x66, 0xE1,
- 0x22, 0xA5, 0xB4, 0x33, 0x87, 0x00, 0x11, 0x96,
- 0x96, 0x11, 0x00, 0x87, 0x33, 0xB4, 0xA5, 0x22,
- 0x33, 0xB4, 0xA5, 0x22, 0x96, 0x11, 0x00, 0x87,
- 0x87, 0x00, 0x11, 0x96, 0x22, 0xA5, 0xB4, 0x33,
- 0xF0, 0x77, 0x66, 0xE1, 0x55, 0xD2, 0xC3, 0x44,
- 0x44, 0xC3, 0xD2, 0x55, 0xE1, 0x66, 0x77, 0xF0,
- 0xF0, 0x77, 0x66, 0xE1, 0x55, 0xD2, 0xC3, 0x44,
- 0x44, 0xC3, 0xD2, 0x55, 0xE1, 0x66, 0x77, 0xF0,
- 0x33, 0xB4, 0xA5, 0x22, 0x96, 0x11, 0x00, 0x87,
- 0x87, 0x00, 0x11, 0x96, 0x22, 0xA5, 0xB4, 0x33,
- 0x22, 0xA5, 0xB4, 0x33, 0x87, 0x00, 0x11, 0x96,
- 0x96, 0x11, 0x00, 0x87, 0x33, 0xB4, 0xA5, 0x22,
- 0xE1, 0x66, 0x77, 0xF0, 0x44, 0xC3, 0xD2, 0x55,
- 0x55, 0xD2, 0xC3, 0x44, 0xF0, 0x77, 0x66, 0xE1,
- 0x11, 0x96, 0x87, 0x00, 0xB4, 0x33, 0x22, 0xA5,
- 0xA5, 0x22, 0x33, 0xB4, 0x00, 0x87, 0x96, 0x11,
- 0xD2, 0x55, 0x44, 0xC3, 0x77, 0xF0, 0xE1, 0x66,
- 0x66, 0xE1, 0xF0, 0x77, 0xC3, 0x44, 0x55, 0xD2,
- 0xC3, 0x44, 0x55, 0xD2, 0x66, 0xE1, 0xF0, 0x77,
- 0x77, 0xF0, 0xE1, 0x66, 0xD2, 0x55, 0x44, 0xC3,
- 0x00, 0x87, 0x96, 0x11, 0xA5, 0x22, 0x33, 0xB4,
- 0xB4, 0x33, 0x22, 0xA5, 0x11, 0x96, 0x87, 0x00
- };
- //--------------------------------------------------------------
- void long_multiply(u32 v1, u32 v2, u32 *HI, u32 *LO)
- {
- register long a, b, c, d;
- register long x, y;
- a = (v1 >> 16) & 0xffff;
- b = v1 & 0xffff;
- c = (v2 >> 16) & 0xffff;
- d = v2 & 0xffff;
- *LO = b * d;
- x = a * d + c * b;
- y = ((*LO >> 16) & 0xffff) + x;
- *LO = (*LO & 0xffff) | ((y & 0xffff) << 16);
- *HI = (y >> 16) & 0xffff;
- *HI += a * c;
- }
- //--------------------------------------------------------------
- int mcman_chrpos(char *str, int chr)
- {
- char *p;
- p = str;
- if (*str) {
- do {
- if (*p == (chr & 0xff))
- break;
- p++;
- } while (*p);
- }
- if (*p != (chr & 0xff))
- return -1;
-
- return p - str;
- }
- //--------------------------------------------------------------
- int _start(int argc, const char **argv)
- {
- iop_library_table_t *libtable;
- iop_library_t *libptr;
- register int i, sio2man_loaded;
- void **export_tab;
- #ifdef SIO_DEBUG
- sio_init(38400, 0, 0, 0, 0);
- #endif
- #ifdef DEBUG
- DPRINTF("mcman: _start...\n");
- #endif
-
- // Get sio2man lib ptr
- sio2man_loaded = 0;
- libtable = GetLibraryEntryTable();
- libptr = libtable->tail;
- while (libptr != 0) {
- for (i=0; i<8; i++) {
- if (libptr->name[i] != sio2man_modname[i])
- break;
- }
- if (i == 8) {
- sio2man_loaded = 1;
- break;
- }
- libptr = libptr->prev;
- }
-
- if (!sio2man_loaded) {
- #ifdef DEBUG
- DPRINTF("mcman: sio2man module is not loaded...\n");
- #endif
- return MODULE_NO_RESIDENT_END;
- }
- #ifdef DEBUG
- DPRINTF("mcman: sio2man version=0x%03x\n", libptr->version);
- #endif
- if (libptr->version > 0x101)
- sio2man_type = XSIO2MAN;
-
- // Get sio2man export table
- export_tab = (void **)(((struct irx_export_table *)libptr)->fptrs);
-
- // Set functions pointers to match SIO2MAN exports
- sio2_mc_transfer_init = export_tab[24];
- sio2_transfer = export_tab[25];
- // set internals function pointers for MCMAN
- mcman_sio2transfer = (void *)mcsio2_transfer;
- mc_detectcard = (void *)McDetectCard2;
-
- if (sio2man_type == XSIO2MAN) {
- // Set functions pointers to match XSIO2MAN exports
- sio2_transfer_reset = export_tab[26];
- sio2_func1 = export_tab[55];
-
- // set internals function pointers for XMCMAN
- mcman_sio2transfer = (void *)mcsio2_transfer2;
- mc_detectcard = (void *)mcman_detectcard;
-
- // Modify mcman export ver
- _exp_mcman.version = 0x203;
- // Get mcman export table
- export_tab = (void **)(struct irx_export_table *)&_exp_mcman.fptrs;
- export_tab[17] = (void *)McEraseBlock2;
- export_tab[21] = (void *)McDetectCard2;
- export_tab[22] = (void *)McGetFormat;
- export_tab[23] = (void *)McGetEntSpace;
- export_tab[24] = (void *)mcman_replacebadblock;
- export_tab[25] = (void *)McCloseAll;
- export_tab[42] = (void *)McGetModuleInfo;
- export_tab[43] = (void *)McGetCardSpec;
- export_tab[44] = (void *)mcman_getFATentry;
- export_tab[45] = (void *)McCheckBlock;
- export_tab[46] = (void *)mcman_setFATentry;
- export_tab[47] = (void *)mcman_readdirentry;
- export_tab[48] = (void *)mcman_1stcacheEntsetwrflagoff;
- export_tab[49] = (void *)mcman_createDirentry;
- export_tab[50] = (void *)mcman_readcluster;
- export_tab[51] = (void *)mcman_flushmccache;
- export_tab[52] = (void *)mcman_setdirentrystate;
- }
- #ifdef DEBUG
- DPRINTF("mcman: registering exports...\n");
- #endif
- if (RegisterLibraryEntries(&_exp_mcman) != 0)
- return MODULE_NO_RESIDENT_END;
-
- CpuEnableIntr();
- #ifdef DEBUG
- DPRINTF("mcman: initPS2com...\n");
- #endif
- mcman_initPS2com();
- #ifdef DEBUG
- DPRINTF("mcman: initPS1PDAcom...\n");
- #endif
- mcman_initPS1PDAcom();
- #ifdef DEBUG
- DPRINTF("mcman: initcache...\n");
- #endif
- mcman_initcache();
- #ifdef DEBUG
- DPRINTF("mcman: initdev...\n");
- #endif
- mcman_initdev();
-
- timer_ID = ReferHardTimer(1, 32, 0, 0x6309);
-
- if (timer_ID != -150)
- return MODULE_RESIDENT_END;
-
- timer_ID = AllocHardTimer(1, 32, 1);
-
- if (timer_ID > 0)
- SetTimerMode(timer_ID, 0);
- #ifdef DEBUG
- DPRINTF("mcman: _start returns MODULE_RESIDENT_END...\n");
- #endif
- return MODULE_RESIDENT_END;
- }
- //--------------------------------------------------------------
- int McGetFormat(int port, int slot) // Export #22 XMCMAN only
- {
- #ifdef DEBUG
- DPRINTF("mcman: McGetFormat port%d slot%d\n", port, slot);
- #endif
- return mcman_devinfos[port][slot].cardform;
- }
- //--------------------------------------------------------------
- int McGetMcType(int port, int slot) // Export #39
- {
- #ifdef DEBUG
- DPRINTF("mcman: McGetMcType port%d slot%d\n", port, slot);
- #endif
- return mcman_devinfos[port][slot].cardtype;
- }
- //--------------------------------------------------------------
- struct modInfo_t *McGetModuleInfo(void) // Export #42 XMCMAN only
- {
- #ifdef DEBUG
- DPRINTF("mcman: McGetModuleInfo\n");
- #endif
- return (struct modInfo_t *)&mcman_modInfo;
- }
- //--------------------------------------------------------------
- void McSetPS1CardFlag(int flag) // Export #40
- {
- #ifdef DEBUG
- DPRINTF("mcman: McSetPS1CardFlag flag %x\n", flag);
- #endif
- PS1CardFlag = flag;
- }
- //--------------------------------------------------------------
- int McGetFreeClusters(int port, int slot) // Export #38
- {
- register int r, mcfree;
- register MCDevInfo *mcdi = &mcman_devinfos[port][slot];
- #ifdef DEBUG
- DPRINTF("mcman: McGetFreeClusters port%d slot%d\n", port, slot);
- #endif
- mcfree = 0;
- if (mcdi->cardform) {
- switch (mcdi->cardtype) {
- case sceMcTypePS2:
- mcfree = mcman_findfree2(port, slot, 0);
- break;
- case sceMcTypePS1:
- case sceMcTypePDA:
- mcfree = mcman_findfree1(port, slot, 0);
- break;
- case sceMcTypeNoCard:
- mcfree = 0;
- break;
- }
- if (mcfree == sceMcResFullDevice)
- mcfree = 0;
-
- r = mcfree;
- }
- else
- return 0;
- return r;
- }
- //--------------------------------------------------------------
- void mcman_wmemset(void *buf, int size, int value)
- {
- int *p = buf;
- size = (size >> 2) - 1;
-
- if (size > -1) {
- do {
- *p++ = value;
- } while (--size > -1);
- }
- }
- //--------------------------------------------------------------
- int mcman_calcEDC(void *buf, int size)
- {
- register u32 checksum;
- register int i;
- u8 *p = (u8 *)buf;
- checksum = 0;
-
- if (size > 0) {
- size--;
- i = 0;
- while (size-- != -1) {
- checksum ^= p[i];
- i++;
- }
- }
- return checksum & 0xff;
- }
- //--------------------------------------------------------------
- int mcman_checkpath(char *str) // check that a string do not contain special chars ( chr<32, ?, *)
- {
- register int i;
- u8 *p = (u8 *)str;
-
- i = 0;
- while (p[i]) {
- if (((p[i] & 0xff) == '?') || ((p[i] & 0xff) == '*'))
- return 0;
- if ((p[i] & 0xff) < 32)
- return 0;
- i++;
- }
- return 1;
- }
- //--------------------------------------------------------------
- int mcman_checkdirpath(char *str1, char *str2)
- {
- register int r, pos1, pos2, pos;
- u8 *p1 = (u8 *)str1;
- u8 *p2 = (u8 *)str2;
-
- do {
- pos1 = mcman_chrpos(p2, '?');
- pos2 = mcman_chrpos(p2, '*');
-
- if ((pos1 < 0) && (pos2 < 0)) {
- if (!strcmp(p2, p1))
- return 1;
- return 0;
- }
- pos = pos2;
- if (pos1 >= 0) {
- pos = pos1;
- if (pos2 >= 0) {
- pos = pos2;
- if (pos1 < pos2) {
- pos = pos1;
- }
- }
- }
- if (strncmp(p2, p1, pos) != 0)
- return 0;
-
- p2 += pos;
- p1 += pos;
-
- while (p2[0] == '?') {
- if (p1[0] == 0)
- return 1;
- p2++;
- p1++;
- }
- } while (p2[0] != '*');
-
- while((p2[0] == '*') || (p2[0] == '?'))
- p2++;
- if (p2[0] != 0) {
- do {
- pos = mcman_chrpos(p1, (u8)p2[0]);
- p1 += pos;
- if (pos < 0)
- return 0;
- r = mcman_checkdirpath(p1, p2);
- p1++;
- } while (r == 0);
- }
- return 1;
- }
- //--------------------------------------------------------------
- void mcman_invhandles(int port, int slot)
- {
- register int i = 0;
- register MC_FHANDLE *fh = (MC_FHANDLE *)&mcman_fdhandles;
-
- do {
- if ((fh->port == port) && (fh->slot == slot))
- fh->status = 0;
- fh++;
- } while (++i < MAX_FDHANDLES);
- }
- //--------------------------------------------------------------
- int McCloseAll(void) // Export #25 XMCMAN only
- {
- register int fd = 0, rv = 0;
- do {
- if (mcman_fdhandles[fd].status) {
- register int rc;
- rc = McClose(fd);
- if (rc < rv)
- rv = rc;
- }
- fd++;
-
- } while (fd < MAX_FDHANDLES);
- return rv;
- }
-
- //--------------------------------------------------------------
- int McDetectCard(int port, int slot) // Export #5
- {
- return mc_detectcard(port, slot);
- }
- //--------------------------------------------------------------
- int mcman_detectcard(int port, int slot)
- {
- register int r;
- register MCDevInfo *mcdi;
- #ifdef DEBUG
- DPRINTF("mcman: mcman_detectcard port%d slot%d\n", port, slot);
- #endif
- mcdi = (MCDevInfo *)&mcman_devinfos[port][slot];
-
- if ((mcdi->cardtype == sceMcTypeNoCard) || (mcdi->cardtype == sceMcTypePS2)) {
- r = mcman_probePS2Card2(port, slot);
- if (r < -9) {
- r = mcman_probePS1Card2(port, slot);
- if (!(r < -9)) {
- if (mcman_probePDACard(port, slot)) {
- mcdi->cardtype = sceMcTypePS1;
- return (!PS1CardFlag) ? sceMcResDeniedPS1Permit : r;
- }
- else {
- mcdi->cardtype = sceMcTypePDA;
- return r;
- }
- }
- }
- else {
- mcdi->cardtype = sceMcTypePS2;
- return r;
- }
- }
- else {
- r = mcman_probePS1Card2(port, slot);
- if (r) {
- if ((r < -9) || (r >= 0)) {
- r = mcman_probePS2Card2(port, slot);
- if (!(r < -9)) {
- mcdi->cardtype = sceMcTypePS2;
- return r;
- }
- }
- else {
- if (mcman_probePDACard(port, slot)) {
- mcdi->cardtype = sceMcTypePS1;
- return (!PS1CardFlag) ? sceMcResDeniedPS1Permit : r;
- }
- else {
- mcdi->cardtype = sceMcTypePDA;
- return r;
- }
- }
- }
- else {
- if (PS1CardFlag)
- return sceMcResSucceed;
- if (mcdi->cardtype == sceMcTypePS1)
- return sceMcResDeniedPS1Permit;
- return sceMcResSucceed;
- }
- }
- mcdi->cardtype = 0;
- mcdi->cardform = 0;
- mcman_invhandles(port, slot);
- mcman_clearcache(port, slot);
- return r;
- }
- //--------------------------------------------------------------
- int McDetectCard2(int port, int slot) // Export #21 XMCMAN only
- {
- register int r;
- register MCDevInfo *mcdi;
-
- #ifdef DEBUG
- DPRINTF("mcman: McDetectCard2 port%d slot%d\n", port, slot);
- #endif
-
- mcdi = (MCDevInfo *)&mcman_devinfos[port][slot];
-
- if ((mcdi->cardtype == sceMcTypeNoCard) || (mcdi->cardtype == sceMcTypePS2)) {
- r = mcman_probePS2Card(port, slot);
- if (r < -9) {
- r = mcman_probePS1Card(port, slot);
- if (!(r < -9)) {
- if (mcman_probePDACard(port, slot)) {
- mcdi->cardtype = sceMcTypePS1;
- return (!PS1CardFlag) ? sceMcResDeniedPS1Permit : r;
- }
- else {
- mcdi->cardtype = sceMcTypePDA;
- return r;
- }
- }
- }
- else {
- mcdi->cardtype = sceMcTypePS2;
- return r;
- }
- }
- else {
- r = mcman_probePS1Card(port, slot);
- if (r) {
- if ((r < -9) || (r >= 0)) {
- r = mcman_probePS2Card(port, slot);
- if (!(r < -9)) {
- mcdi->cardtype = sceMcTypePS2;
- return r;
- }
- }
- else {
- if (mcman_probePDACard(port, slot)) {
- mcdi->cardtype = sceMcTypePS1;
- return (!PS1CardFlag) ? sceMcResDeniedPS1Permit : r;
- }
- else {
- mcdi->cardtype = sceMcTypePDA;
- return r;
- }
- }
- }
- else {
- if (PS1CardFlag)
- return sceMcResSucceed;
- if (mcdi->cardtype == sceMcTypePS1)
- return sceMcResDeniedPS1Permit;
- return sceMcResSucceed;
- }
- }
- mcdi->cardtype = 0;
- mcdi->cardform = 0;
- mcman_invhandles(port, slot);
- mcman_clearcache(port, slot);
- return r;
- }
- //--------------------------------------------------------------
- int McOpen(int port, int slot, char *filename, int flag) // Export #6
- {
- register int r;
-
- r = McDetectCard(port, slot);
- if (r != sceMcResSucceed)
- return r;
-
- if (!PS1CardFlag)
- flag &= 0xFFFFDFFF; // disables FRCOM flag OR what is it
- if (mcman_devinfos[port][slot].cardtype == sceMcTypePS2)
- r = mcman_open2(port, slot, filename, flag);
- else
- r = mcman_open1(port, slot, filename, flag);
-
- if (r < -9) {
- mcman_invhandles(port, slot);
- mcman_clearcache(port, slot);
- }
-
- return r;
- }
- //--------------------------------------------------------------
- int McClose(int fd) // Export #7
- {
- register MC_FHANDLE *fh;
- register MCDevInfo *mcdi;
- register int r;
-
- if (!((u32)fd < MAX_FDHANDLES))
- return sceMcResDeniedPermit;
-
- fh = (MC_FHANDLE *)&mcman_fdhandles[fd];
- if (!fh->status)
- return sceMcResDeniedPermit;
-
- fh->status = 0;
- r = McDetectCard(fh->port, fh->slot);
- if (r != sceMcResSucceed)
- return r;
-
- r = mcman_flushmccache(fh->port, fh->slot);
- if (r < -9) {
- mcman_invhandles(fh->port, fh->slot);
- mcman_clearcache(fh->port, fh->slot);
- }
-
- if (r != sceMcResSucceed)
- return r;
-
- if (fh->unknown2 != 0) {
- fh->unknown2 = 0;
- mcdi = (MCDevInfo *)&mcman_devinfos[fh->port][fh->slot];
- if (mcdi->cardtype == sceMcTypePS2)
- r = mcman_close2(fd);
- else
- r = mcman_close1(fd);
-
- if (r < -9) {
- mcman_invhandles(fh->port, fh->slot);
- mcman_clearcache(fh->port, fh->slot);
- }
-
- if (r != sceMcResSucceed)
- return r;
- }
-
- r = mcman_flushmccache(fh->port, fh->slot);
- if (r < -9) {
- mcman_invhandles(fh->port, fh->slot);
- mcman_clearcache(fh->port, fh->slot);
- }
- return r;
- }
- //--------------------------------------------------------------
- int McFlush(int fd) // Export #14
- {
- register int r;
- register MC_FHANDLE *fh;
- register MCDevInfo *mcdi;
-
- if (!((u32)fd < MAX_FDHANDLES))
- return sceMcResDeniedPermit;
-
- fh = (MC_FHANDLE *)&mcman_fdhandles[fd];
- if (!fh->status)
- return sceMcResDeniedPermit;
-
- r = McDetectCard(fh->port, fh->slot);
- if (r != sceMcResSucceed)
- return r;
- r = mcman_flushmccache(fh->port, fh->slot);
- if (r < -9) {
- mcman_invhandles(fh->port, fh->slot);
- mcman_clearcache(fh->port, fh->slot);
- }
-
- if (r != sceMcResSucceed) {
- fh->status = 0;
- return r;
- }
- if (fh->unknown2 != 0) {
- fh->unknown2 = 0;
- mcdi = (MCDevInfo *)&mcman_devinfos[fh->port][fh->slot];
- if (mcdi->cardtype == sceMcTypePS2)
- r = mcman_close2(fd);
- else
- r = mcman_close1(fd);
-
- if (r < -9) {
- mcman_invhandles(fh->port, fh->slot);
- mcman_clearcache(fh->port, fh->slot);
- }
-
- if (r != sceMcResSucceed) {
- fh->status = 0;
- return r;
- }
- }
-
- r = mcman_flushmccache(fh->port, fh->slot);
- if (r < 0)
- fh->status = 0;
-
- if (r < -9) {
- mcman_invhandles(fh->port, fh->slot);
- mcman_clearcache(fh->port, fh->slot);
- }
-
- return r;
- }
- //--------------------------------------------------------------
- int McSeek(int fd, int offset, int origin) // Export #10
- {
- register int r;
- register MC_FHANDLE *fh;
-
- #ifdef DEBUG
- DPRINTF("mcman: McSeek fd %d offset %d origin %d\n", fd, offset, origin);
- #endif
-
- if (!((u32)fd < MAX_FDHANDLES))
- return sceMcResDeniedPermit;
-
- fh = (MC_FHANDLE *)&mcman_fdhandles[fd];
- if (!fh->status)
- return sceMcResDeniedPermit;
-
- r = McDetectCard(fh->port, fh->slot);
- if (r != sceMcResSucceed)
- return r;
- switch (origin) {
- default:
- case SEEK_CUR:
- r = fh->position + offset;
- break;
- case SEEK_SET:
- r = offset;
- break;
- case SEEK_END:
- r = fh->filesize + offset;
- break;
- }
- return fh->position = (r < 0) ? 0 : r;
- }
- //--------------------------------------------------------------
- int McRead(int fd, void *buf, int length) // Export #8
- {
- register int r;
- register MC_FHANDLE *fh;
-
- if (!((u32)fd < MAX_FDHANDLES))
- return sceMcResDeniedPermit;
-
- fh = (MC_FHANDLE *)&mcman_fdhandles[fd];
- if (!fh->status)
- return sceMcResDeniedPermit;
-
- if (!fh->rdflag)
- return sceMcResDeniedPermit;
-
- r = McDetectCard(fh->port, fh->slot);
- if (r != sceMcResSucceed)
- return r;
-
- if (mcman_devinfos[fh->port][fh->slot].cardtype == sceMcTypePS2)
- r = mcman_read2(fd, buf, length);
- else
- r = mcman_read1(fd, buf, length);
-
- if (r < 0)
- fh->status = 0;
- if (r < -9) {
- mcman_invhandles(fh->port, fh->slot);
- mcman_clearcache(fh->port, fh->slot);
- }
-
- return r;
- }
- //--------------------------------------------------------------
- int McWrite(int fd, void *buf, int length) // Export #9
- {
- register int r;
- register MC_FHANDLE *fh;
-
- if (!((u32)fd < MAX_FDHANDLES))
- return sceMcResDeniedPermit;
-
- fh = (MC_FHANDLE *)&mcman_fdhandles[fd];
- if (!fh->status)
- return sceMcResDeniedPermit;
-
- if (!fh->wrflag)
- return sceMcResDeniedPermit;
-
- r = McDetectCard(fh->port, fh->slot);
- if (r != sceMcResSucceed)
- return r;
-
- if (mcman_devinfos[fh->port][fh->slot].cardtype == sceMcTypePS2)
- r = mcman_write2(fd, buf, length);
- else
- r = mcman_write1(fd, buf, length);
-
- if (r < 0)
- fh->status = 0;
-
- if (r < -9) {
- mcman_invhandles(fh->port, fh->slot);
- mcman_clearcache(fh->port, fh->slot);
- }
-
- return r;
- }
- //--------------------------------------------------------------
- int McGetEntSpace(int port, int slot, char *dirname) // Export #23 XMCMAN only
- {
- register int r;
-
- r = McDetectCard(port, slot);
- if (r != sceMcResSucceed)
- return r;
-
- if (mcman_devinfos[port][slot].cardtype == sceMcTypePS2) {
- r = mcman_getentspace(port, slot, dirname);
- }
-
- if (r < -9) {
- mcman_invhandles(port, slot);
- mcman_clearcache(port, slot);
- }
-
- return r;
- }
- //--------------------------------------------------------------
- int McGetDir(int port, int slot, char *dirname, int flags, int maxent, sceMcTblGetDir *info) // Export #12
- {
- register int r;
- r = McDetectCard(port, slot);
- if (r != sceMcResSucceed)
- return r;
-
- if (mcman_devinfos[port][slot].cardtype == sceMcTypePS2)
- r = mcman_getdir2(port, slot, dirname, flags & 0xFFFF, maxent, info);
- else
- r = mcman_getdir1(port, slot, dirname, flags & 0xFFFF, maxent, info);
-
- if (r < -9) {
- mcman_invhandles(port, slot);
- mcman_clearcache(port, slot);
- }
- return r;
- }
- //--------------------------------------------------------------
- int mcman_dread(int fd, fio_dirent_t *dirent)
- {
- register int r;
- register MC_FHANDLE *fh;
-
- if (!((u32)fd < MAX_FDHANDLES))
- return sceMcResDeniedPermit;
-
- fh = (MC_FHANDLE *)&mcman_fdhandles[fd];
- if (!fh->status)
- return sceMcResDeniedPermit;
-
- if (!fh->drdflag)
- return sceMcResDeniedPermit;
-
- r = McDetectCard(fh->port, fh->slot);
- if (r != sceMcResSucceed)
- return r;
- if (mcman_devinfos[fh->port][fh->slot].cardtype == sceMcTypePS2)
- r = mcman_dread2(fd, dirent);
- else
- r = mcman_dread1(fd, dirent);
-
- if (r < 0)
- fh->status = 0;
-
- if (r < -9) {
- mcman_invhandles(fh->port, fh->slot);
- mcman_clearcache(fh->port, fh->slot);
- }
-
- return r;
- }
- //--------------------------------------------------------------
- int mcman_getstat(int port, int slot, char *filename, fio_stat_t *stat)
- {
- register int r;
- r = McDetectCard(port, slot);
- if (r != sceMcResSucceed)
- return r;
-
- if (mcman_devinfos[port][slot].cardtype == sceMcTypePS2)
- r = mcman_getstat2(port, slot, filename, stat);
- else
- r = mcman_getstat1(port, slot, filename, stat);
-
- if (r < -9) {
- mcman_invhandles(port, slot);
- mcman_clearcache(port, slot);
- }
-
- return r;
- }
- //--------------------------------------------------------------
- int McSetFileInfo(int port, int slot, char *filename, sceMcTblGetDir *info, int flags) // Export #16
- {
- register int r;
- r = McDetectCard(port, slot);
- if (r != sceMcResSucceed)
- return r;
-
- if (mcman_devinfos[port][slot].cardtype == sceMcTypePS2)
- r = mcman_setinfo2(port, slot, filename, info, flags);
- else
- r = mcman_setinfo1(port, slot, filename, info, flags);
-
- if (r < -9) {
- mcman_invhandles(port, slot);
- mcman_clearcache(port, slot);
- }
-
- if (r == sceMcResSucceed) {
- r = mcman_flushmccache(port, slot);
- if (r < -9) {
- mcman_invhandles(port, slot);
- mcman_clearcache(port, slot);
- }
- }
-
- return r;
- }
- //--------------------------------------------------------------
- int McChDir(int port, int slot, char *newdir, char *currentdir) // Export #15
- {
- register int r;
- r = McDetectCard(port, slot);
- if (r != sceMcResSucceed)
- return r;
- if (mcman_devinfos[port][slot].cardtype == sceMcTypePS2)
- r = mcman_chdir(port, slot, newdir, currentdir);
- else {
- currentdir[0] = 0;
- r = sceMcResSucceed;
- }
-
- if (r < -9) {
- mcman_invhandles(port, slot);
- mcman_clearcache(port, slot);
- }
-
- return r;
- }
- //--------------------------------------------------------------
- int McDelete(int port, int slot, char *filename, int flags) // Export #13
- {
- register int r;
- r = McDetectCard(port, slot);
- if (r != sceMcResSucceed)
- return r;
- if (mcman_devinfos[port][slot].cardtype == sceMcTypePS2)
- r = mcman_delete2(port, slot, filename, flags);
- else
- r = mcman_delete1(port, slot, filename, flags);
-
- if (r < -9) {
- mcman_invhandles(port, slot);
- mcman_clearcache(port, slot);
- }
-
- return r;
- }
- //--------------------------------------------------------------
- int McFormat(int port, int slot) // Export #11
- {
- register int r;
-
- mcman_invhandles(port, slot);
-
- r = McDetectCard(port, slot);
- if (r < -2)
- return r;
-
- mcman_clearcache(port, slot);
-
- if (mcman_devinfos[port][slot].cardtype == sceMcTypePS2)
- r = mcman_format2(port, slot);
- else
- r = mcman_format1(port, slot);
-
- if (r < -9) {
- mcman_invhandles(port, slot);
- mcman_clearcache(port, slot);
- }
-
- return r;
- }
- //--------------------------------------------------------------
- int McUnformat(int port, int slot) // Export #36
- {
- register int r;
-
- mcman_invhandles(port, slot);
-
- r = McDetectCard(port, slot);
- if (r < -2)
- return r;
-
- mcman_clearcache(port, slot);
-
- if (mcman_devinfos[port][slot].cardtype == sceMcTypePS2)
- r = mcman_unformat2(port, slot);
- else
- r = mcman_unformat1(port, slot);
-
- mcman_devinfos[port][slot].cardform = 0;
-
- if (r < -9) {
- mcman_invhandles(port, slot);
- mcman_clearcache(port, slot);
- }
-
- return r;
- }
- //--------------------------------------------------------------
- int mcman_getmcrtime(sceMcStDateTime *time)
- {
- register int retries;
- cd_clock_t cdtime;
-
- retries = 64;
-
- do {
- if (sceCdRC(&cdtime))
- break;
- } while (--retries > 0);
-
- if (cdtime.stat & 128) {
- *((u16 *)&cdtime.month) = 0x7d0;
- cdtime.day = 3;
- cdtime.week = 4;
- cdtime.hour = 0;
- cdtime.minute = 0;
- cdtime.second = 0;
- cdtime.stat = 0;
- }
-
- time->Resv2 = 0;
- time->Sec = ((((cdtime.second >> 4) << 2) + (cdtime.second >> 4)) << 1) + (cdtime.second & 0xf);
- time->Min = ((((cdtime.minute >> 4) << 2) + (cdtime.minute >> 4)) << 1) + (cdtime.minute & 0xf);
- time->Hour = ((((cdtime.hour >> 4) << 2) + (cdtime.hour >> 4)) << 1) + (cdtime.hour & 0xf);
- time->Day = ((((cdtime.day >> 4) << 2) + (cdtime.day >> 4)) << 1) + (cdtime.day & 0xf);
-
- if ((cdtime.month & 0x10) != 0)
- time->Month = (cdtime.month & 0xf) + 0xa;
- else
- time->Month = cdtime.month & 0xf;
-
- time->Year = ((((cdtime.year >> 4) << 2) + (cdtime.year >> 4)) << 1) + ((cdtime.year & 0xf) | 0x7d0);
- return 0;
- }
- //--------------------------------------------------------------
- int McEraseBlock(int port, int block, void **pagebuf, void *eccbuf) // Export #17 in MCMAN
- {
- return mcman_eraseblock(port, 0, block, (void **)pagebuf, eccbuf);
- }
- //--------------------------------------------------------------
- int McEraseBlock2(int port, int slot, int block, void **pagebuf, void *eccbuf) // Export #17 in XMCMAN
- {
- return mcman_eraseblock(port, slot, block, (void **)pagebuf, eccbuf);
- }
- //--------------------------------------------------------------
- int McReadPage(int port, int slot, int page, void *buf) // Export #18
- {
- register int r, index, ecres, retries, count, erase_byte;
- register MCDevInfo *mcdi = &mcman_devinfos[port][slot];
- u8 eccbuf[32];
- u8 *pdata, *peccb;
-
- count = (mcdi->pagesize + 127) >> 7;
- erase_byte = (mcdi->cardflags & CF_ERASE_ZEROES) ? 0x0 : 0xFF;
- retries = 0;
- ecres = sceMcResSucceed;
- do {
- if (!mcman_readpage(port, slot, page, buf, eccbuf)) {
- if (mcdi->cardflags & CF_USE_ECC) { // checking ECC from spare data block
- // check for erased page (last byte of spare data set to 0xFF or 0x0)/
- if (eccbuf[mcman_sparesize(port, slot) - 1] == erase_byte)
- break;
- index = 0;
- if (count > 0) {
- peccb = (u8 *)eccbuf;
- pdata = (u8 *)buf;
- do {
- r = mcman_correctdata(pdata, peccb);
- if (r < ecres)
- ecres = r;
- peccb += 3;
- pdata += 128;
- } while (++index < count);
- }
- if (ecres == sceMcResSucceed)
- break;
-
- if ((retries == 4) && (!(ecres < sceMcResNoFormat)))
- break;
- }
- }
- } while (++retries < 5);
- if (retries < 5)
- return sceMcResSucceed;
- return (ecres != sceMcResSucceed) ? sceMcResNoFormat : sceMcResChangedCard;
- }
- //--------------------------------------------------------------
- void McDataChecksum(void *buf, void *ecc) // Export #20
- {
- register u8 *p, *p_ecc;
- register int i, a2, a3, v, t0;
- p = buf;
- i = 0;
- a2 = 0;
- a3 = 0;
- t0 = 0;
- do {
- v = mcman_xortable[*p++];
- a2 ^= v;
- if (v & 0x80) {
- a3 ^= ~i;
- t0 ^= i;
- }
- } while (++i < 0x80);
-
- p_ecc = ecc;
- p_ecc[0] = ~a2 & 0x77;
- p_ecc[1] = ~a3 & 0x7F;
- p_ecc[2] = ~t0 & 0x7F;
- }
- //--------------------------------------------------------------
- int mcman_getcnum(int port, int slot)
- {
- return ((port & 1) << 3) + slot;
- }
- //--------------------------------------------------------------
- int mcman_correctdata(void *buf, void *ecc)
- {
- register int xor0, xor1, xor2, xor3, xor4;
- u8 eccbuf[12];
- u8 *p = (u8 *)ecc;
- McDataChecksum(buf, eccbuf);
- xor0 = p[0] ^ eccbuf[0];
- xor1 = p[1] ^ eccbuf[1];
- xor2 = p[2] ^ eccbuf[2];
-
- xor3 = xor1 ^ xor2;
- xor4 = (xor0 & 0xf) ^ (xor0 >> 4);
-
- if (!xor0 && !xor1 && !xor2)
- return 0;
- if ((xor3 == 0x7f) && (xor4 == 0x7)) {
- p[xor2] ^= 1 << (xor0 >> 4);
- return -1;
- }
- xor0 = 0;
- xor2 = 7;
- do {
- if ((xor3 & 1))
- xor0++;
- xor2--;
- xor3 = xor3 >> 1;
- } while (xor2 >= 0);
-
- xor2 = 3;
- do {
- if ((xor4 & 1))
- xor0++;
- xor2--;
- xor4 = xor4 >> 1;
- } while (xor2 >= 0);
- if (xor0 == 1)
- return -2;
-
- return -3;
- }
- //--------------------------------------------------------------
- int mcman_sparesize(int port, int slot)
- { // Get ps2 mc spare size by dividing pagesize / 32
- return (mcman_devinfos[port][slot].pagesize + 0x1F) >> 5;
- }
- //--------------------------------------------------------------
- int mcman_setdevspec(int port, int slot)
- {
- int cardsize;
- register MCDevInfo *mcdi = &mcman_devinfos[port][slot];
- #ifdef DEBUG
- DPRINTF("mcman: mcman_setdevspec port%d, slot%d\n", port, slot);
- #endif
-
- if (McGetCardSpec(port, slot, &mcdi->pagesize, &mcdi->blocksize, &cardsize, &mcdi->cardflags) != sceMcResSucceed)
- return sceMcResFullDevice;
-
- mcdi->pages_per_cluster = MCMAN_CLUSTERSIZE / mcdi->pagesize;
- mcdi->cluster_size = MCMAN_CLUSTERSIZE;
- mcdi->unknown1 = 0;
- mcdi->unknown2 = 0;
- mcdi->unused = 0xff00;
- mcdi->FATentries_per_cluster = MCMAN_CLUSTERFATENTRIES;
- mcdi->unknown5 = -1;
- mcdi->rootdir_cluster2 = mcdi->rootdir_cluster;
- mcdi->clusters_per_block = mcdi->blocksize / mcdi->pages_per_cluster;
- mcdi->clusters_per_card = (cardsize / mcdi->blocksize) * (mcdi->blocksize / mcdi->pages_per_cluster);
-
- return sceMcResSucceed;
- }
- //--------------------------------------------------------------
- int mcman_setdevinfos(int port, int slot)
- {
- register int r, allocatable_clusters_per_card, iscluster_valid, current_allocatable_cluster, cluster_cnt;
- register MCDevInfo *mcdi = &mcman_devinfos[port][slot];
- McFsEntry *pfse;
-
- #ifdef DEBUG
- DPRINTF("mcman: mcman_setdevinfos port%d slot%d\n", port, slot);
- #endif
-
- mcman_wmemset((void *)mcdi, sizeof(MCDevInfo), 0);
-
- r = mcman_setdevspec(port, slot);
- if (r != sceMcResSucceed)
- return -49;
-
- r = McReadPage(port, slot, 0, mcman_pagebuf);
- if (r == sceMcResNoFormat)
- return sceMcResNoFormat; // should rebuild a valid superblock here
- if (r != sceMcResSucceed)
- return -48;
-
- if (strncmp(SUPERBLOCK_MAGIC, mcman_pagebuf, 28) != 0) {
- #ifdef DEBUG
- DPRINTF("mcman: mcman_setdevinfos No card format !!!\n");
- #endif
- return sceMcResNoFormat;
- }
-
- if (((mcman_pagebuf[28] - 48) == 1) && ((mcman_pagebuf[30] - 48) == 0)) // check ver major & minor
- return sceMcResNoFormat;
-
- u8 *p = (u8 *)mcdi;
- for (r=0; r<0x150; r++)
- p[r] = mcman_pagebuf[r];
- mcdi->cardtype = sceMcTypePS2; // <--
-
- r = mcman_checkBackupBlocks(port, slot);
- if (r != sceMcResSucceed)
- return -47;
-
- r = mcman_readdirentry(port, slot, 0, 0, &pfse);
- if (r != sceMcResSucceed)
- return sceMcResNoFormat; // -46
-
- if (strcmp(pfse->name, ".") != 0)
- return sceMcResNoFormat;
-
- if (mcman_readdirentry(port, slot, 0, 1, &pfse) != sceMcResSucceed)
- return -45;
-
- if (strcmp(pfse->name, "..") != 0)
- return sceMcResNoFormat;
-
- mcdi->cardform = 1;
- // mcdi->cardtype = sceMcTypePS2;
-
- if (((mcman_pagebuf[28] - 48) == 1) && ((mcman_pagebuf[30] - 48) == 1)) { // check ver major & minor
- if ((mcdi->clusters_per_block * mcdi->backup_block2) == mcdi->alloc_end)
- mcdi->alloc_end = (mcdi->clusters_per_block * mcdi->backup_block2) - mcdi->alloc_offset;
- }
-
- u32 hi, lo, temp;
-
- long_multiply(mcdi->clusters_per_card, 0x10624dd3, &hi, &lo);
- temp = (hi >> 6) - (mcdi->clusters_per_card >> 31);
- allocatable_clusters_per_card = (((((temp << 5) - temp) << 2) + temp) << 3) + 1;
- iscluster_valid = 0;
- cluster_cnt = 0;
- current_allocatable_cluster = mcdi->alloc_offset;
-
- while (cluster_cnt < allocatable_clusters_per_card) {
- if (current_allocatable_cluster >= mcdi->clusters_per_card)
- break;
- if (((current_allocatable_cluster % mcdi->clusters_per_block) == 0) \
- || (mcdi->alloc_offset == current_allocatable_cluster)) {
- iscluster_valid = 1;
- for (r=0; r<16; r++) {
- if ((current_allocatable_cluster / mcdi->clusters_per_block) == mcdi->bad_block_list[r])
- iscluster_valid = 0;
- }
- }
- if (iscluster_valid == 1)
- cluster_cnt++;
- current_allocatable_cluster++;
- }
-
- mcdi->max_allocatable_clusters = current_allocatable_cluster - mcdi->alloc_offset;
-
- return sceMcResSucceed;
- }
- //--------------------------------------------------------------
- int mcman_reportBadBlocks(int port, int slot)
- {
- register int r, i, block, bad_blocks, page, erase_byte, err_cnt, err_limit;
- register MCDevInfo *mcdi = &mcman_devinfos[port][slot];
- u8 *p;
- #ifdef DEBUG
- DPRINTF("mcman: mcman_reportBadBlocks port%d, slot%d\n", port, slot);
- #endif
-
- mcman_wmemset((void *)mcdi->bad_block_list, 128, -1);
-
- if ((mcdi->cardflags & CF_BAD_BLOCK) == 0)
- return sceMcResSucceed;
-
- err_limit = (((mcdi->pagesize << 16) >> 16) + ((mcdi->pagesize << 16) >> 31)) >> 1; //s7
-
- erase_byte = 0;
- if ((mcdi->cardflags & CF_ERASE_ZEROES) != 0)
- erase_byte = 0xff;
-
- bad_blocks = 0; // s2
-
- if ((mcdi->clusters_per_card / mcdi->clusters_per_block) > 0) {
-
- block = 0; // s1
-
- do {
- if (bad_blocks >= 16)
- break;
-
- err_cnt = 0; //s4
- page = 0; //s3
- do {
-
- r = McReadPage(port, slot, (block * mcdi->blocksize) + page, mcman_pagebuf);
- if (r == sceMcResNoFormat) {
- mcdi->bad_block_list[bad_blocks] = block;
- bad_blocks++;
- break;
- }
- if (r != sceMcResSucceed)
- return r;
-
- if ((mcdi->cardflags & CF_USE_ECC) == 0) {
- p = (u8 *)&mcman_pagebuf;
- for (i = 0; i < mcdi->pagesize; i++) {
- // check if the content of page is clean
- if (*p++ != erase_byte)
- err_cnt++;
-
- if (err_cnt >= err_limit) {
- mcdi->bad_block_list[bad_blocks] = block;
- bad_blocks++;
- break;
- }
- }
- }
- } while (++page < 2);
- } while (++block < (mcdi->clusters_per_card / mcdi->clusters_per_block));
- }
-
- return sceMcResSucceed;
- }
- //--------------------------------------------------------------
- int mcman_createDirentry(int port, int slot, int parent_cluster, int num_entries, int cluster, sceMcStDateTime *ctime)
- {
- register int r;
- McCacheEntry *mce;
- register MCDevInfo *mcdi = &mcman_devinfos[port][slot];
- McFsEntry *mfe, *mfe_next, *pfse;
- #ifdef DEBUG
- DPRINTF("mcman: mcman_createDirentry port%d slot%d parent_cluster %x num_entries %d cluster %x\n", port, slot, parent_cluster, num_entries, cluster);
- #endif
-
- r = mcman_readcluster(port, slot, mcdi->alloc_offset + cluster, &mce);
- if (r != sceMcResSucceed)
- return r;
-
- mcman_wmemset(mce->cl_data, MCMAN_CLUSTERSIZE, 0);
- mfe = (McFsEntry*)mce->cl_data;
- mfe_next = (McFsEntry*)(mce->cl_data + sizeof (McFsEntry));
-
- mfe->mode = sceMcFileAttrReadable | sceMcFileAttrWriteable | sceMcFileAttrExecutable \
- | sceMcFileAttrSubdir | sceMcFile0400 | sceMcFileAttrExists; // 0x8427
- if (ctime == NULL)
- mcman_getmcrtime(&mfe->created);
- else
- mfe->created = *ctime;
- mfe->modified = mfe->created;
-
- mfe->length = 0;
- mfe->dir_entry = num_entries;
- mfe->cluster = parent_cluster;
- *(u16 *)&mfe->name = *((u16 *)&DOT);
-
- if ((parent_cluster == 0) && (num_entries == 0)) {
- // entry is root directory
- mfe_next->created = mfe->created;
- mfe->length = 2;
- mfe++;
- mfe->mode = sceMcFileAttrWriteable | sceMcFileAttrExecutable | sceMcFileAttrSubdir \
- | sceMcFile0400 | sceMcFileAttrExists | sceMcFileAttrHidden; // 0xa426
- mfe->dir_entry = 0;
- mfe->cluster = 0;
- }
- else {
- // entry is normal "." / ".."
- mcman_readdirentry(port, slot, parent_cluster, 0, &pfse);
- mfe_next->created = pfse->created;
- mfe++;
- mfe->mode = sceMcFileAttrReadable | sceMcFileAttrWriteable | sceMcFileAttrExecutable \
- | sceMcFileAttrSubdir | sceMcFile0400 | sceMcFileAttrExists; // 0x8427
- mfe->dir_entry = pfse->dir_entry;
-
- mfe->cluster = pfse->cluster;
- }
- mfe->modified = mfe->created;
- mfe->length = 0;
-
- *(u16 *)&mfe->name = *(u16 *)&DOTDOT;
- *(u8 *)&mfe->name[2] = *((u8 *)&DOTDOT+2);
- mce->wr_flag = 1;
- return sceMcResSucceed;
- }
- //--------------------------------------------------------------
- int mcman_fatRseek(int fd)
- {
- register int r, entries_to_read, fat_index;
- register MC_FHANDLE *fh = (MC_FHANDLE *)&mcman_fdhandles[fd]; //s1
- register MCDevInfo *mcdi = &mcman_devinfos[fh->port][fh->slot]; //s2
- int fat_entry;
-
- entries_to_read = fh->position / mcdi->cluster_size; //s0
-
- //s5 = 0
-
- if (entries_to_read < fh->clust_offset) //v1 = fh->fh->clust_offset
- fat_index = fh->freeclink;
- else {
- fat_index = fh->clink; // a2
- entries_to_read -= fh->clust_offset;
- }
-
- if (entries_to_read == 0) {
- if (fat_index >= 0)
- return fat_index + mcdi->alloc_offset;
-
- return sceMcResFullDevice;
- }
-
- do {
- r = mcman_getFATentry(fh->port, fh->slot, fat_index, &fat_entry);
- if (r != sceMcResSucceed)
- return r;
-
- fat_index = fat_entry;
-
- if (fat_index >= -1)
- return sceMcResFullDevice;
-
- entries_to_read--;
-
- fat_index &= 0x7fffffff;
- fh->clink = fat_index;
- fh->clust_offset = (fh->position / mcdi->cluster_size) - entries_to_read;
-
- } while (entries_to_read > 0);
-
- return fat_index + mcdi->alloc_offset;
- }
- //--------------------------------------------------------------
- int mcman_fatWseek(int fd) // modify FAT to hold new content for a file
- {
- register int r, entries_to_write, fat_index;
- register MC_FHANDLE *fh = (MC_FHANDLE *)&mcman_fdhandles[fd];
- register MCDevInfo *mcdi = &mcman_devinfos[fh->port][fh->slot];
- register McCacheEntry *mce;
- int fat_entry;
-
- entries_to_write = fh->position / mcdi->cluster_size;
-
- if ((fh->clust_offset == 0) || (entries_to_write < fh->clust_offset)) {
- fat_index = fh->freeclink;
-
- if (fat_index < 0) {
- fat_index = mcman_findfree2(fh->port, fh->slot, 1);
-
- if (fat_index < 0)
- return sceMcResFullDevice;
-
- mce = (McCacheEntry *)mcman_get1stcacheEntp();
- fh->freeclink = fat_index;
-
- r = mcman_close2(fd);
- if (r != sceMcResSucceed)
- return r;
-
- mcman_addcacheentry(mce);
- mcman_flushmccache(fh->port, fh->slot);
- }
- }
- else {
- fat_index = fh->clink;
- entries_to_write -= fh->clust_offset;
- }
-
- if (entries_to_write != 0) {
- do {
- r = mcman_getFATentry(fh->port, fh->slot, fat_index, &fat_entry);
- if (r != sceMcResSucceed)
- return r;
-
- if (fat_entry >= 0xffffffff) {
- r = mcman_findfree2(fh->port, fh->slot, 1);
- if (r < 0)
- return r;
- fat_entry = r;
- fat_entry |= 0x80000000;
-
- mce = (McCacheEntry *)mcman_get1stcacheEntp();
-
- r = mcman_setFATentry(fh->port, fh->slot, fat_index, fat_entry);
- if (r != sceMcResSucceed)
- return r;
-
- mcman_addcacheentry(mce);
- }
-
- entries_to_write--;
- fat_index = fat_entry & 0x7fffffff;
- } while (entries_to_write > 0);
- }
-
- fh->clink = fat_index;
- fh->clust_offset = fh->position / mcdi->cluster_size;
-
- return sceMcResSucceed;
- }
- //--------------------------------------------------------------
- int mcman_findfree2(int port, int slot, int reserve)
- {
- register int r, rfree, indirect_index, ifc_index, fat_offset, indirect_offset, fat_index, block;
- register MCDevInfo *mcdi = &mcman_devinfos[port][slot];
- McCacheEntry *mce1, *mce2;
-
- #ifdef DEBUG
- DPRINTF("mcman: mcman_findfree2 port%d slot%d reserve%d\n", port, slot, reserve);
- #endif
-
- fat_index = mcdi->unknown2;
- rfree = 0;
- for (fat_index = mcdi->unknown2; fat_index < mcdi->max_allocatable_clusters; fat_index++) {
-
- indirect_index = fat_index / mcdi->FATentries_per_cluster;
- fat_offset = fat_index % mcdi->FATentries_per_cluster;
-
- if ((fat_offset == 0) || (fat_index == mcdi->unknown2)) {
-
- ifc_index = indirect_index / mcdi->FATentries_per_cluster;
- r = mcman_readcluster(port, slot, mcdi->ifc_list[ifc_index], &mce1);
- if (r != sceMcResSucceed)
- return r;
- //}
- //if ((fat_offset == 0) || (fat_index == mcdi->unknown2)) {
- indirect_offset = indirect_index % mcdi->FATentries_per_cluster;
- McFatCluster *fc = (McFatCluster *)mce1->cl_data;
- r = mcman_readcluster(port, slot, fc->entry[indirect_offset], &mce2);
- if (r != sceMcResSucceed)
- return r;
- }
- McFatCluster *fc = (McFatCluster *)mce2->cl_data;
-
- if (fc->entry[fat_offset] >= 0) {
- block = (mcdi->alloc_offset + fat_offset) / mcdi->clusters_per_block;
- if (block != mcman_badblock) {
- if (reserve) {
- fc->entry[fat_offset] = 0xffffffff;
- mce2->wr_flag = 1;
- mcdi->unknown2 = fat_index;
- return fat_index;
- }
- rfree++;
- }
- }
- }
-
- if (reserve)
- return sceMcResFullDevice;
-
- return (rfree) ? rfree : sceMcResFullDevice;
- }
- //--------------------------------------------------------------
- int mcman_getentspace(int port, int slot, char *dirname)
- {
- register int r, i, entspace;
- McCacheDir cacheDir;
- McFsEntry *fse;
- McFsEntry mfe;
- u8 *pfsentry, *pmfe, *pfseend;
- #ifdef DEBUG
- DPRINTF("mcman: mcman_getentspace port%d slot%d dirname %s\n", port, slot, dirname);
- #endif
-
- r = mcman_cachedirentry(port, slot, dirname, &cacheDir, &fse, 1);
- if (r > 0)
- return sceMcResNoEntry;
- if (r < 0)
- return r;
-
- pfsentry = (u8 *)fse;
- pmfe = (u8 *)&mfe;
- pfseend = (u8 *)(pfsentry + sizeof (McFsEntry));
-
- do {
- *((u32 *)pmfe ) = *((u32 *)pfsentry );
- *((u32 *)pmfe+1) = *((u32 *)pfsentry+1);
- *((u32 *)pmfe+2) = *((u32 *)pfsentry+2);
- *((u32 *)pmfe+3) = *((u32 *)pfsentry+3);
- pfsentry += 16;
- pmfe += 16;
- } while (pfsentry < pfseend);
-
- entspace = mfe.length & 1;
-
- for (i = 0; i < mfe.length; i++) {
-
- r = mcman_readdirentry(port, slot, mfe.cluster, i, &fse);
- if (r != sceMcResSucceed)
- return r;
- if ((fse->mode & sceMcFileAttrExists) == 0)
- entspace++;
- }
-
- return entspace;
- }
- //--------------------------------------------------------------
- int mcman_cachedirentry(int port, int slot, char *filename, McCacheDir *pcacheDir, McFsEntry **pfse, int unknown_flag)
- {
- register int r, fsindex, cluster, fmode;
- register MCDevInfo *mcdi = &mcman_devinfos[port][slot];
- McFsEntry *fse;
- McCacheDir cacheDir;
- u8 *p, *pfsentry, *pcache, *pfseend;
- #ifdef DEBUG
- DPRINTF("mcman: mcman_cachedirentry port%d slot%d name %s\n", port, slot, filename);
- #endif
-
- if (pcacheDir == NULL) {
- pcacheDir = &cacheDir;
- pcacheDir->maxent = -1;
- }
-
- p = (u8 *)filename;
- if (*p == '/') {
- p++;
- cluster = 0;
- fsindex = 0;
- }
- else {
- cluster = mcdi->rootdir_cluster2;
- fsindex = mcdi->unknown1;
- }
-
- r = mcman_readdirentry(port, slot, cluster, fsindex, &fse);
- if (r != sceMcResSucceed)
- return r;
-
- if (*p == 0) {
- if (!(fse->mode & sceMcFileAttrExists))
- return 2;
-
- if (pcacheDir == NULL) {
- *pfse = (McFsEntry *)fse;
- return sceMcResSucceed;
- }
-
- pfsentry = (u8 *)fse;
- pcache = (u8 *)&mcman_dircache[0];
- pfseend = (u8 *)(pfsentry + sizeof (McFsEntry));
-
- do {
- *((u32 *)pcache ) = *((u32 *)pfsentry );
- *((u32 *)pcache+1) = *((u32 *)pfsentry+1);
- *((u32 *)pcache+2) = *((u32 *)pfsentry+2);
- *((u32 *)pcache+3) = *((u32 *)pfsentry+3);
- pfsentry += 16;
- pcache += 16;
- } while (pfsentry < pfseend);
-
- r = mcman_getdirinfo(port, slot, (McFsEntry *)&mcman_dircache[0], ".", pcacheDir, unknown_flag);
-
- mcman_readdirentry(port, slot, pcacheDir->cluster, pcacheDir->fsindex, pfse);
-
- if (r > 0)
- return 2;
-
- return r;
-
- } else {
-
- do {
- fmode = sceMcFileAttrReadable | sceMcFileAttrExecutable;
- if ((fse->mode & fmode) != fmode)
- return sceMcResDeniedPermit;
-
- if (mcman_chrpos(p, '/') < 0)
- strlen(p);
-
- pfsentry = (u8 *)fse;
- pcache = (u8 *)&mcman_dircache[0];
- pfseend = (u8 *)(pfsentry + sizeof(McFsEntry));
-
- do {
- *((u32 *)pcache ) = *((u32 *)pfsentry );
- *((u32 *)pcache+1) = *((u32 *)pfsentry+1);
- *((u32 *)pcache+2) = *((u32 *)pfsentry+2);
- *((u32 *)pcache+3) = *((u32 *)pfsentry+3);
- pfsentry += 16;
- pcache += 16;
- } while (pfsentry < pfseend);
- r = mcman_getdirinfo(port, slot, (McFsEntry *)&mcman_dircache[0], p, pcacheDir, unknown_flag);
- if (r > 0) {
- if (mcman_chrpos(p, '/') >= 0)
- return 2;
-
- pcacheDir->cluster = cluster;
- pcacheDir->fsindex = fsindex;
-
- return 1;
- }
-
- r = mcman_chrpos(p, '/');
- if ((r >= 0) && (p[r + 1] != 0)) {
- p += mcman_chrpos(p, '/') + 1;
- cluster = pcacheDir->cluster;
- fsindex = pcacheDir->fsindex;
-
- mcman_readdirentry(port, slot, cluster, fsindex, &fse);
- }
- else {
- mcman_readdirentry(port, slot, pcacheDir->cluster, pcacheDir->fsindex, pfse);
-
- return sceMcResSucceed;
- }
- } while (*p != 0);
- }
- return sceMcResSucceed;
- }
- //--------------------------------------------------------------
- int mcman_getdirinfo(int port, int slot, McFsEntry *pfse, char *filename, McCacheDir *pcd, int unknown_flag)
- {
- register int i, r, ret, len, pos;
- McFsEntry *fse;
- u8 *pfsentry, *pfsee, *pfseend;
-
- #ifdef DEBUG
- DPRINTF("mcman: mcman_getdirinfo port%d slot%d name %s\n", port, slot, filename);
- #endif
-
- pos = mcman_chrpos(filename, '/');
- if (pos < 0)
- pos = strlen(filename);
-
- ret = 0;
- if ((pos == 2) && (!strncmp(filename, "..", 2))) {
-
- r = mcman_readdirentry(port, slot, pfse->cluster, 0, &fse);
- if (r != sceMcResSucceed)
- return r;
-
- r = mcman_readdirentry(port, slot, fse->cluster, 0, &fse);
- if (r != sceMcResSucceed)
- return r;
- if (pcd) {
- pcd->cluster = fse->cluster;
- pcd->fsindex = fse->dir_entry;
- }
- r = mcman_readdirentry(port, slot, fse->cluster, fse->dir_entry, &fse);
- if (r != sceMcResSucceed)
- return r;
-
- pfsentry = (u8 *)fse;
- pfsee = (u8 *)pfse;
- pfseend = (u8 *)(pfsentry + sizeof(McFsEntry));
-
- do {
- *((u32 *)pfsee ) = *((u32 *)pfsentry );
- *((u32 *)pfsee+1) = *((u32 *)pfsentry+1);
- *((u32 *)pfsee+2) = *((u32 *)pfsentry+2);
- *((u32 *)pfsee+3) = *((u32 *)pfsentry+3);
- pfsentry += 16;
- pfsee += 16;
- } while (pfsentry < pfseend);
-
- if ((fse->mode & sceMcFileAttrHidden) != 0) {
- ret = 1;
- if (!PS1CardFlag) {
- ret = 2;
- if ((pcd == NULL) || (pcd->maxent < 0))
- return 3;
- }
- }
-
- if ((pcd == NULL) || (pcd->maxent < 0))
- return sceMcResSucceed;
- }
- else {
- if ((pos == 1) && (!strncmp(filename, ".", 1))) {
-
- r = mcman_readdirentry(port, slot, pfse->cluster, 0, &fse);
- if (r != sceMcResSucceed)
- return r;
-
- if (pcd) {
- pcd->cluster = fse->cluster;
- pcd->fsindex = fse->dir_entry;
- }
-
- if ((fse->mode & sceMcFileAttrHidden) != 0) {
- ret = 1;
- if (!PS1CardFlag) {
- ret = 2;
- if ((pcd == NULL) || (pcd->maxent < 0))
- return 3;
- }
- else {
- if ((pcd == NULL) || (pcd->maxent < 0))
- return sceMcResSucceed;
- }
- }
- else {
- ret = 1;
- if ((pcd == NULL) || (pcd->maxent < 0))
- return sceMcResSucceed;
- }
- }
- }
-
- if ((pcd) && (pcd->maxent >= 0))
- pcd->maxent = pfse->length;
-
- if (pfse->length > 0) {
-
- i = 0;
- do {
- r = mcman_readdirentry(port, slot, pfse->cluster, i, &fse);
- if (r != sceMcResSucceed)
- return r;
-
- if (((fse->mode & sceMcFileAttrExists) == 0) && (pcd) && (i < pcd->maxent))
- pcd->maxent = i;
-
- if (unknown_flag) {
- if ((fse->mode & sceMcFileAttrExists) == 0)
- continue;
- }
- else {
- if ((fse->mode & sceMcFileAttrExists) != 0)
- continue;
- }
-
- if (ret != 0)
- continue;
-
- if ((pos >= 11) && (!strncmp(&filename[10], &fse->name[10], pos-10))) {
- len = pos;
- if (strlen(fse->name) >= pos)
- len = strlen(fse->name);
-
- if (!strncmp(filename, fse->name, len))
- goto continue_check;
- }
-
- if (strlen(fse->name) >= pos)
- len = strlen(fse->name);
- else
- len = pos;
-
- if (strncmp(filename, fse->name, len))
- continue;
-
- continue_check:
- ret = 1;
-
- if ((fse->mode & sceMcFileAttrHidden) != 0) {
- if (!PS1CardFlag)
- ret = 2;
- }
- if (pcd == NULL)
- break;
-
- pcd->fsindex = i;
- pcd->cluster = pfse->cluster;
-
- if (pcd->maxent < 0)
- break;
-
- } while (++i < pfse->length);
- }
-
- if (ret == 2)
- return 2;
-
- return ((ret < 1) ? 1 : 0);
- }
- //--------------------------------------------------------------
- int mcman_writecluster(int port, int slot, int cluster, int flag)
- {
- register int r, i, j, page, block, pageword_cnt;
- register u32 erase_value;
- register MCDevInfo *mcdi = &mcman_devinfos[port][slot];
-
- block = cluster / mcdi->clusters_per_block;
-
- if ((mcman_wr_port == port) && (mcman_wr_slot == slot) && (mcman_wr_block == block))
- return mcman_wr_flag3;
-
- mcman_wr_port = port;
- mcman_wr_slot = slot;
- mcman_wr_block = block;
- mcman_wr_flag3 = -9;
-
- for (i = 0; i < 16; i++) { // check only 16 bad blocks ?
- if (mcdi->bad_block_list[i] < 0)
- break;
- if (mcdi->bad_block_list[i] == block) {
- mcman_wr_flag3 = 0;
- return sceMcResSucceed;
- }
- }
-
- if (flag) {
- for (i = 1; i < mcdi->blocksize; i++)
- mcman_pagedata[i] = 0;
-
- mcman_pagedata[0] = &mcman_pagebuf;
-
- pageword_cnt = mcdi->pagesize >> 2;
- page = block * mcdi->blocksize;
-
- if (mcdi->cardflags & CF_ERASE_ZEROES)
- erase_value = 0xffffffff;
- else
- erase_value = 0x00000000;
-
- for (i = 0; i < pageword_cnt; i++)
- *((u32 *)&mcman_pagebuf + i) = erase_value;
-
- r = mcman_eraseblock(port, slot, block, (void **)mcman_pagedata, (void *)mcman_eccdata);
- if (r == sceMcResFailReplace)
- return sceMcResSucceed;
- if (r != sceMcResSucceed)
- return sceMcResChangedCard;
-
- for (i = 1; i < mcdi->blocksize; i++) {
- r = McWritePage(port, slot, page + i, mcman_pagebuf, mcman_eccdata);
- if (r == sceMcResFailReplace)
- return sceMcResSucceed;
- if (r != sceMcResSucceed)
- return sceMcResNoFormat;
- }
- for (i = 1; i < mcdi->blocksize; i++) {
- r = McReadPage(port, slot, page + i, mcman_pagebuf);
- if (r == sceMcResNoFormat)
- return sceMcResSucceed;
- if (r != sceMcResSucceed)
- return sceMcResFullDevice;
- for (j = 0; j < pageword_cnt; j++) {
- if (*((u32 *)&mcman_pagebuf + j) != erase_value) {
- mcman_wr_flag3 = 0;
- return sceMcResSucceed;
- }
- }
- }
-
- r = mcman_eraseblock(port, slot, block, NULL, NULL);
- if (r != sceMcResSucceed)
- return sceMcResChangedCard;
-
- r = McWritePage(port, slot, page, mcman_pagebuf, mcman_eccdata);
- if (r == sceMcResFailReplace)
- return sceMcResSucceed;
- if (r != sceMcResSucceed)
- return sceMcResNoFormat;
- r = McReadPage…
Large files files are truncated, but you can click here to view the full file