#include "amDongle.h" #include "../libpcp/pcpa.h" #include "../util/hex.h" AM_LIB_C_HEADER(amDongle, AM_DONGLE) AM_DONGLE_STATUS amDongleInit(void) { if (amDongle.m_init) return AM_DONGLE_STATUS_ERR_ALREADY_INIT; memset(&amDongle, 0, sizeof amDongle); amDongle.version = 0; amDongle.seq = -1; amDongle.field19_0x40 = -1; amDongle.done_init = 0; amDongle.available = 0; // amDongle.field14_0x2c = 5; amDongle.develop = 0; amDongle.authCondition = 1; amDongle.auth_ready = 0; // amDongle.field6_0x18 = 0; // amDongle.field7_0x1c = 0; // amDongle.field8_0x20 = 0; // amDongle.field13_0x28 = 1; amDongle.setupSeq = AM_DONGLE_SETUP_SEQ_START; amDongle.setupSeqNext = AM_DONGLE_SETUP_SEQ_NONE; amDongle.setupRetries = 0; amDongle.requestCode = 0; amDongle.result = 0; // amDongle.field21_0x48 = 1; // amDongle.field22_0x4c = 0; amDongle.challengeNum = 0; amDongle.ctrl_port = 40106; amDongle.data_port = 40107; amDongle.valueBuffer = NULL; amDongle.dataBuffer = NULL; // amDongle.field51_0x3440 = 0; // amDongle.field53_0x3448 = 0; e_pcpa_t pcpa_err = pcpaInitStream(&amDongle.pcpa); if (pcpa_err == e_pcpa_wsa_noinit) { if (amDongleDebugLevel > 0) amiDebugLog("Error: Winsocket2 Library is not ready."); return AM_DONGLE_STATUS_ERR_PRECONDITION; } if (pcpa_err != e_pcpa_ok) { if (amDongleDebugLevel > 0) { amiDebugLog("Error: System error happened in pcp stream. ErrorCode = %d.", pcpa_err); } return AM_DONGLE_STATUS_ERR_SYS; } amDongle.m_init = 1; return AM_DONGLE_STATUS_OK; } AM_DONGLE_STATUS amDongleOpen(void) { if (!amDongle.m_init) { return AM_DONGLE_STATUS_ERR_NO_INIT; } if (!amDongle.done_init || !amDongle.available) { return AM_DONGLE_STATUS_NG; } e_pcpa_t pcpa_err = pcpaOpenClient(&amDongle.pcpa, "127.0.0.1", amDongle.ctrl_port, 90000, 0); if (pcpa_err == e_pcpa_ok) { amDongle.seq = AM_DONGLE_SEQ_OPEN; amDongle.result = 1; return AM_DONGLE_STATUS_OK; } if (pcpa_err == e_pcpa_to) { amDongle.seq = AM_DONGLE_SEQ_WAIT_OPEN; amDongle.field19_0x40 = 2; amDongle.result = 1; return AM_DONGLE_STATUS_OK; } if (amDongleDebugLevel > 0) { amiDebugLog("Error : pcpaOpenClient(%d)", pcpa_err); } amDongle.seq = AM_DONGLE_SEQ_DONE; return AM_DONGLE_STATUS_ERR_PCP; } AM_DONGLE_STATUS amDongleOpenEx(void) { if (amDongle.m_init == 0) return AM_DONGLE_STATUS_ERR_NO_INIT; if (!amDongle.done_init || !amDongle.available) return AM_DONGLE_STATUS_NG; e_pcpa_t pcpa_err; while (true) { pcpa_err = pcpaOpenClient(&amDongle.pcpa, "127.0.0.1", amDongle.ctrl_port, 90000, TIMEOUT_NONE); if (pcpa_err == e_pcpa_ok) return AM_DONGLE_STATUS_OK; if (pcpa_err != e_pcpa_timeout_open) break; pcpaClose(&amDongle.pcpa); } if (amDongleDebugLevel > 0) amiDebugLog("Error : pcpaOpenClient(%d)", pcpa_err); amDongle.seq = AM_DONGLE_SEQ_DONE; amDongle.field19_0x40 = -1; return AM_DONGLE_STATUS_ERR_NO_SERVER; } BOOL amDongleIsDevelop(void) { if (amDongle.done_init && amDongle.develop) { return TRUE; } return FALSE; } BOOL amDongleIsAvailable(void) { if (amDongle.done_init && amDongle.available) { return TRUE; } return FALSE; } AM_DONGLE_STATUS amDongleCodeToStatus(void) { char *codeStr = pcpaGetCommand(&amDongle.pcpa, "code"); if (codeStr == NULL) return AM_DONGLE_STATUS_OK; int code = atoi(codeStr); if (true) { switch (code) { case 0: return AM_DONGLE_STATUS_OK; case 1: case 2: return AM_DONGLE_STATUS_ERR_KEYCHIP; case 50: return AM_DONGLE_STATUS_ERR_VERIFY; case 51: return AM_DONGLE_STATUS_ERR_LOG_FULL; case 52: return AM_DONGLE_STATUS_ERR_NO_LOG; case 53: return AM_DONGLE_STATUS_ERR_ONE_WRITE; case 54: return AM_DONGLE_STATUS_ERR_COMMAND; case 55: return AM_DONGLE_STATUS_ERR_KEYCHIP_DATA; } } return AM_DONGLE_STATUS_ERR_PCP; } AM_DONGLE_STATUS amDongleSetupKeychip(void) { if (amDongle.m_init == 0) return AM_DONGLE_STATUS_ERR_NO_INIT; e_pcpa_t pcpa_err; pcp_send_data_t *send_data; switch (amDongle.setupSeq) { case AM_DONGLE_SETUP_SEQ_START: send_data = pcpaSetSendPacket(&amDongle.pcpa, "keychip.appboot.systemflag", "?"); if (send_data == NULL && amDongleDebugLevel > 0) amiDebugLog("Error: pcpaSetSendPacket return NULL"); send_data = pcpaAddSendPacket(&amDongle.pcpa, "cache", "0"); if (send_data == NULL && amDongleDebugLevel > 0) amiDebugLog("Error: pcpaAddSendPacket return NULL"); pcpa_err = pcpaOpenClient(&amDongle.pcpa, "127.0.0.1", amDongle.ctrl_port, 90000, 0); if (pcpa_err != e_pcpa_ok) { if (pcpa_err != e_pcpa_to) { if (amDongleDebugLevel > 0) amiDebugLog("Error : pcpaOpenClient(%d)", pcpa_err); amDongle.setupSeq = AM_DONGLE_SETUP_SEQ_ERR; return AM_DONGLE_STATUS_PENDING; } amDongle.setupSeq = AM_DONGLE_SETUP_SEQ_WAIT; amDongle.setupSeqNext = AM_DONGLE_SETUP_SEQ_SEND; return AM_DONGLE_STATUS_PENDING; } amDongle.setupSeq = AM_DONGLE_SETUP_SEQ_SEND; return AM_DONGLE_STATUS_PENDING; case AM_DONGLE_SETUP_SEQ_WAIT: pcpa_err = pcpaIsBusy(&amDongle.pcpa, 0); if (pcpa_err == e_pcpa_ok) { AM_DONGLE_SETUP_SEQ next = amDongle.setupSeqNext; amDongle.setupSeqNext = AM_DONGLE_SETUP_SEQ_NONE; amDongle.setupSeq = next; return AM_DONGLE_STATUS_PENDING; } if (pcpa_err == e_pcpa_timeout_open) { if (amDongleDebugLevel > 0) { amiDebugLog("Error : PCPA_RESULT_PROMPT_TIME_OUT_ERROR", 0xfffffff2); } pcpaClose(&amDongle.pcpa); amDongle.setupSeq = 1; amDongle.setupSeqNext = AM_DONGLE_SETUP_SEQ_NONE; return AM_DONGLE_STATUS_PENDING; } if (pcpa_err == e_pcpa_to) return AM_DONGLE_STATUS_PENDING; if (amDongleDebugLevel > 0) amiDebugLog("Error : pcpaIsBusy(%d)", pcpa_err); amDongle.setupSeq = AM_DONGLE_SETUP_SEQ_RETRY; return AM_DONGLE_STATUS_PENDING; case AM_DONGLE_SETUP_SEQ_SEND: pcpa_err = pcpaSendRequest(&amDongle.pcpa, 0); if (pcpa_err == e_pcpa_ok) { amDongle.setupSeq = AM_DONGLE_SETUP_SEQ_RECV; return AM_DONGLE_STATUS_PENDING; } if (pcpa_err == e_pcpa_to) { amDongle.setupSeq = AM_DONGLE_SETUP_SEQ_WAIT; amDongle.setupSeqNext = AM_DONGLE_SETUP_SEQ_RECV; return AM_DONGLE_STATUS_PENDING; } if (amDongleDebugLevel > 0) amiDebugLog("Error : pcpaSendRequest(%d)", pcpa_err); amDongle.setupSeq = AM_DONGLE_SETUP_SEQ_RETRY; return AM_DONGLE_STATUS_PENDING; case AM_DONGLE_SETUP_SEQ_RECV: pcpa_err = pcpaRecvResponse(&amDongle.pcpa, 0); if (pcpa_err == e_pcpa_ok) { amDongle.setupSeq = AM_DONGLE_SETUP_SEQ_READ_RESPONSE; return AM_DONGLE_STATUS_PENDING; } if (pcpa_err != e_pcpa_to) { if (amDongleDebugLevel > 0) { amiDebugLog("Error : pcpaRecvResponse(%d)", pcpa_err); } amDongle.setupSeq = AM_DONGLE_SETUP_SEQ_RETRY; return AM_DONGLE_STATUS_PENDING; } amDongle.setupSeq = AM_DONGLE_SETUP_SEQ_WAIT; amDongle.setupSeqNext = AM_DONGLE_SETUP_SEQ_READ_RESPONSE; return AM_DONGLE_STATUS_PENDING; case AM_DONGLE_SETUP_SEQ_READ_RESPONSE: AM_DONGLE_STATUS code = amDongleCodeToStatus(); if (code == AM_DONGLE_STATUS_OK) { char *keyword = pcpaGetKeyword(&amDongle.pcpa, 0); if (keyword == NULL) { if (amDongleDebugLevel > 0) { amiDebugLog("Error No Response!!"); } amDongle.setupSeq = AM_DONGLE_SETUP_SEQ_RETRY; return AM_DONGLE_STATUS_PENDING; } if (strcmp(keyword, "keychip.appboot.systemflag") == 0) { unsigned char systemflag; hex_to_byte(pcpaGetCommand(&amDongle.pcpa, keyword), &systemflag); if (systemflag & 1) amDongle.develop = 1; send_data = pcpaSetSendPacket(&amDongle.pcpa, "keychip.version", "?"); if (send_data == NULL && amDongleDebugLevel > 0) amiDebugLog("Error: pcpaSetSendPacket return NULL"); send_data = pcpaAddSendPacket(&amDongle.pcpa, "cache", "0"); if (send_data == NULL && amDongleDebugLevel > 0) amiDebugLog("Error: pcpaAddSendPacket return NULL"); amDongle.setupSeq = AM_DONGLE_SETUP_SEQ_SEND; return AM_DONGLE_STATUS_PENDING; } else if (strcmp(keyword, "keychip.version") == 0) { ushort version; hex_to_bin(pcpaGetCommand(&amDongle.pcpa, keyword), (unsigned char *)&version, 4); amDongle.version = ((version << 8) & 0xffff) | (version >> 8); amDongle.setupSeq = AM_DONGLE_SETUP_SEQ_CLOSE; amDongle.setupSeqNext = AM_DONGLE_SETUP_SEQ_DONE; return AM_DONGLE_STATUS_PENDING; } else if (amDongleDebugLevel > 0) amiDebugLog("Error Response!!"); } else if (code == AM_DONGLE_STATUS_ERR_KEYCHIP) { amDongle.setupSeq = AM_DONGLE_SETUP_SEQ_CLOSE; amDongle.setupSeqNext = AM_DONGLE_SETUP_SEQ_ERR; return AM_DONGLE_STATUS_PENDING; } amDongle.setupSeq = AM_DONGLE_SETUP_SEQ_START; return AM_DONGLE_STATUS_PENDING; case AM_DONGLE_SETUP_SEQ_CLOSE: pcpaClose(&amDongle.pcpa); AM_DONGLE_SETUP_SEQ next = amDongle.setupSeqNext; amDongle.setupSeq = next; amDongle.setupSeqNext = AM_DONGLE_SETUP_SEQ_NONE; if (next != AM_DONGLE_SETUP_SEQ_DONE) return AM_DONGLE_STATUS_PENDING; amDongle.available = 1; amDongle.done_init = 1; amDongle.seq = AM_DONGLE_SEQ_NONE; amDongle.result = 0; return AM_DONGLE_STATUS_PENDING; case AM_DONGLE_SETUP_SEQ_RETRY: pcpaClose(&amDongle.pcpa); amDongle.setupRetries++; amDongle.setupSeqNext = AM_DONGLE_SETUP_SEQ_NONE; if (amDongle.setupRetries > 2) { amDongle.setupSeq = AM_DONGLE_SETUP_SEQ_ERR; return AM_DONGLE_STATUS_PENDING; } amDongle.setupSeq = AM_DONGLE_SETUP_SEQ_START; return AM_DONGLE_STATUS_PENDING; case AM_DONGLE_SETUP_SEQ_DONE: return AM_DONGLE_STATUS_OK; default: return AM_DONGLE_STATUS_NG; } } // TODO: FUN_009f6940 !!! AM_DONGLE_STATUS amDongleResponseCheck(void) { char cVar1; byte bVar2; int *piVar4; AM_DONGLE_STATUS AVar7; int iVar9; uint *puVar11; uint local_8; char *keyword = pcpaGetKeyword(&amDongle.pcpa, 0); char *command = pcpaGetCommand(&amDongle.pcpa, keyword); char *sSize = pcpaGetCommand(&amDongle.pcpa, "size"); char *sAddress = pcpaGetCommand(&amDongle.pcpa, "address"); amDongle.seq = AM_DONGLE_SEQ_DONE; if (keyword == NULL) { if (amDongleDebugLevel > 0) amiDebugLog("Response Error!!! No Keyword."); return AM_DONGLE_STATUS_ERR_PCP; } if (keyword[0] == '?') return AM_DONGLE_STATUS_ERR_NO_COMMAND; AVar7 = amDongleCodeToStatus(); if (AVar7 != AM_DONGLE_STATUS_OK) { if (AVar7 == AM_DONGLE_STATUS_ERR_KEYCHIP) { if (amDongleDebugLevel > 0) amiDebugLog("Error Response KeychipError !!!"); amDongle.available = 0; amDongle.develop = 0; } return AVar7; } if ((amDongle.requestCode & 0x80) != 0) { char *sPort = pcpaGetCommand(&amDongle.pcpa, "port"); if (sPort == NULL) amDongle.data_port = 40107; else amDongle.data_port = atoi(sPort) & 0xffff; amDongle.seq = 5; } local_8 = 0; // TODO: ?? if (false) { return AM_DONGLE_STATUS_OK; } switch (amDongle.requestCode) { case AM_DONGLE_REQUEST_DECRYPT: if (strcmp(keyword, "keychip.decrypt")) break; hex_to_bin(command, amDongle.valueBuffer, 32); return AM_DONGLE_STATUS_OK; case AM_DONGLE_REQUEST_ENCRYPT: if (strcmp(keyword, "keychip.encrypt") || command == NULL) break; hex_to_bin(command, amDongle.valueBuffer, 32); return AM_DONGLE_STATUS_OK; case AM_DONGLE_REQUEST_GET_GAME_ID: if (strcmp(keyword, "keychip.appboot.gameid") || command == NULL) break; strcpy_s((char *)amDongle.valueBuffer, 5, (char *)command); return AM_DONGLE_STATUS_OK; case AM_DONGLE_REQUEST_GET_SYSTEMFLAG: if (strcmp(keyword, "keychip.appboot.systemflag") || command == NULL) break; hex_to_bin(command, amDongle.valueBuffer, 2); return AM_DONGLE_STATUS_OK; case AM_DONGLE_REQUEST_GET_MODEL_TYPE: if (strcmp(keyword, "keychip.appboot.modeltype") || command == NULL) break; hex_to_bin(command, amDongle.valueBuffer, 2); return AM_DONGLE_STATUS_OK; case AM_DONGLE_REQUEST_GET_REGION: if (strcmp(keyword, "keychip.appboot.region") || command == NULL) break; hex_to_bin(command, amDongle.valueBuffer, 2); return AM_DONGLE_STATUS_OK; case AM_DONGLE_REQUEST_GET_PLATFORM_ID: if (strcmp(keyword, "keychip.appboot.platformid") || command == NULL) break; strcpy_s((char *)amDongle.valueBuffer, 4, command); return AM_DONGLE_STATUS_OK; case AM_DONGLE_REQUEST_GET_NETWORK_ADDRESS: if (strcmp(keyword, "keychip.appboot.networkaddr") || command == NULL) break; // We can't use inet_pton because we target XP #pragma warning(suppress : 4996) if (amDongle.valueBuffer != NULL) *(uint *)amDongle.valueBuffer = inet_addr(command); return AM_DONGLE_STATUS_OK; case AM_DONGLE_REQUEST_GET_VERSION: if (strcmp(keyword, "keychip.version") || command == NULL) break; ushort version; hex_to_bin(command, (unsigned char *)&version, 4); *(ushort *)amDongle.valueBuffer = ((version << 8) & 0xffff) | version >> 8; return AM_DONGLE_STATUS_OK; case AM_DONGLE_REQUEST_BILLING_GET_KEYCHIP_ID: if (strcmp(keyword, "keychip.billing.keyid") || command == NULL) break; strcpy_s((char *)amDongle.valueBuffer, 17, command); return AM_DONGLE_STATUS_OK; case AM_DONGLE_REQUEST_BILLING_GET_MAIN_ID: if (strcmp(keyword, "keychip.billing.mainid") || command == NULL) break; strcpy_s((char *)amDongle.valueBuffer, 12, command); return AM_DONGLE_STATUS_OK; case AM_DONGLE_REQUEST_BILLING_GET_PLAYCOUNT: if (strcmp(keyword, "keychip.billing.playcount") || command == NULL) break; hex_to_int((unsigned int *)amDongle.valueBuffer, command); return AM_DONGLE_STATUS_OK; case AM_DONGLE_REQUEST_BILLING_ADD_PLAYCOUNT: if (strcmp(keyword, "keychip.billing.playcount") || command == NULL) break; hex_to_int((unsigned int *)amDongle.valueBuffer, command); return AM_DONGLE_STATUS_OK; case AM_DONGLE_REQUEST_BILLING_GET_PLAYLIMIT: if (strcmp(keyword, "keychip.billing.playlimit") || command == NULL) break; hex_to_int((unsigned int *)amDongle.valueBuffer, command); return AM_DONGLE_STATUS_OK; case AM_DONGLE_REQUEST_BILLING_GET_NEARFULL: if (strcmp(keyword, "keychip.billing.nearfull") || command == NULL) break; hex_to_int((unsigned int *)amDongle.valueBuffer, command); return AM_DONGLE_STATUS_OK; case AM_DONGLE_REQUEST_BILLING_TD_RESTORE: if (strcmp(keyword, "keychip.tracedata.restore") || command == NULL) break; if (strcmp(command, "1") == 0) { pcp_send_data_t *packet = pcpaSetSendPacket(&amDongle.pcpa, "keychip.tracedata.restore", "1"); if (packet == NULL && amDongleDebugLevel > 0) amiDebugLog("Error: pcpaSetSendPacket return NULL"); packet = pcpaAddSendPacket(&amDongle.pcpa, "cache", "0"); if (packet == NULL && amDongleDebugLevel > 0) amiDebugLog("Error: pcpaAddSendPacket return NULL"); packet = pcpaAddSendPacket(&amDongle.pcpa, "update", "1"); if (packet == NULL && amDongleDebugLevel > 0) amiDebugLog("Error: pcpaAddSendPacket return NULL"); packet = pcpaAddSendPacket(&amDongle.pcpa, "restart", "0"); if (packet == NULL && amDongleDebugLevel > 0) amiDebugLog("Error: pcpaAddSendPacket return NULL"); amDongle.seq = AM_DONGLE_SETUP_SEQ_WAIT; return AM_DONGLE_STATUS_OK; } if (amDongle.valueBuffer != NULL) *(int *)amDongle.valueBuffer = command[0] - '0'; return AM_DONGLE_STATUS_OK; case AM_DONGLE_REQUEST_BILLING_TD_GET_LOG_NUM: iVar9 = strcmp(keyword, "keychip.tracedata.get"); if (((iVar9 == 0) && (command != NULL)) && (keyword = command, sAddress != NULL)) { do { bVar2 = *keyword; keyword = keyword + 1; } while (bVar2 != 0); // FUN_009f6940(); sSize = sAddress; do { cVar1 = *sSize; sSize = sSize + 1; } while (cVar1 != '\0'); // FUN_009f6940(); return AM_DONGLE_STATUS_OK; } break; case AM_DONGLE_REQUEST_BILLING_TD_GET_FREE_LOG_NUM: iVar9 = strcmp(keyword, "keychip.tracedata.put"); if ((iVar9 == 0) && (keyword = command, command != NULL)) { do { bVar2 = *keyword; keyword = keyword + 1; } while (bVar2 != 0); // FUN_009f6940(); return AM_DONGLE_STATUS_OK; } break; case AM_DONGLE_REQUEST_BILLING_TD_ERASE_USED_SECTOR: iVar9 = strcmp(keyword, "keychip.tracedata.sectorerase"); // goto LAB_009f7ff7; case AM_DONGLE_REQUEST_BILLING_TD_ERASE_ALL: iVar9 = strcmp(keyword, "keychip.tracedata.sectorerase"); if ((iVar9 == 0) && (command != NULL)) { piVar4 = (int *)amDongle.valueBuffer; if (piVar4 == NULL) { return AM_DONGLE_STATUS_OK; } *piVar4 = 0; *piVar4 = 0; *piVar4 = (char)*command + -0x30; return AM_DONGLE_STATUS_OK; } break; case AM_DONGLE_REQUEST_BILLING_TD_RESERVE_ERASABLE_SECTOR: iVar9 = strcmp(keyword, "keychip.tracedata.sectorerase"); if (iVar9 != 0) { return AM_DONGLE_STATUS_ERR_PCP; } if (command != NULL) { piVar4 = (int *)amDongle.valueBuffer; if (piVar4 == NULL) { return AM_DONGLE_STATUS_OK; } *piVar4 = 0; *piVar4 = 0; *piVar4 = (char)*command + -0x30; return AM_DONGLE_STATUS_OK; } return AM_DONGLE_STATUS_ERR_PCP; case AM_DONGLE_REQUEST_GET_DVDFLAG: iVar9 = strcmp(keyword, "keychip.appboot.dvdflag"); // goto LAB_009f7a26; case AM_DONGLE_REQUEST_GET_DS_COMPUTE: iVar9 = strcmp(keyword, "keychip.ds.compute"); if ((iVar9 == 0) && (command != NULL)) { keyword = command; do { bVar2 = *keyword; keyword = keyword + 1; } while (bVar2 != 0); local_8 = (int)keyword - (int)(command + 1); // FUN_009f6b40(command, amDongle.valueBuffer); return AM_DONGLE_STATUS_OK; } break; case AM_DONGLE_REQUEST_GET_SSD_PROOF: iVar9 = strcmp(keyword, "keychip.ssd.proof"); if ((iVar9 == 0) && (command != NULL)) { keyword = command; do { bVar2 = *keyword; keyword = keyword + 1; } while (bVar2 != 0); local_8 = (int)keyword - (int)(command + 1); // FUN_009f6b40(command, amDongle.valueBuffer); return AM_DONGLE_STATUS_OK; } break; case AM_DONGLE_REQUEST_GET_FORMAT_TYPE: iVar9 = strcmp(keyword, "keychip.appboot.formattype"); if ((iVar9 == 0) && (command != NULL)) { local_8 = 2; // FUN_009f6b40(command, amDongle.valueBuffer); return AM_DONGLE_STATUS_OK; } break; case AM_DONGLE_WTF_81: if (sSize == NULL) { LAB_009f82b7: amDongle.seq = 8; return AM_DONGLE_STATUS_ERR_PCP; } do { cVar1 = *sSize; sSize = sSize + 1; } while (cVar1 != '\0'); goto LAB_009f82d7; case AM_DONGLE_REQUEST_BILLING_GET_TRACEDATA: if ((command == NULL) || (sSize == NULL)) goto LAB_009f82b7; do { cVar1 = *sSize; sSize = sSize + 1; } while (cVar1 != '\0'); // FUN_009f6940(); puVar11 = amDongle.field_0x3444; goto LAB_009f82f2; case AM_DONGLE_REQUEST_BILLING_GET_SIGNATURE_PK: if (sSize == NULL) goto LAB_009f82b7; do { cVar1 = *sSize; sSize = sSize + 1; } while (cVar1 != '\0'); goto LAB_009f82d7; case AM_DONGLE_REQUEST_BILLING_GET_CA_CERT: if (sSize == NULL) goto LAB_009f82b7; do { cVar1 = *sSize; sSize = sSize + 1; } while (cVar1 != '\0'); // FUN_009f6940(); puVar11 = (uint *)amDongle.dataBuffer; goto LAB_009f82f2; case AM_DONGLE_WTF_85: if (sSize == NULL) goto LAB_009f82b7; do { cVar1 = *sSize; sSize = sSize + 1; } while (cVar1 != '\0'); // FUN_009f6940(); puVar11 = (uint *)amDongle.dataBuffer; goto LAB_009f82f2; case AM_DONGLE_WTF_C0: if (sSize == NULL) goto LAB_009f82b7; do { cVar1 = *sSize; sSize = sSize + 1; } while (cVar1 != '\0'); // FUN_009f6940(); puVar11 = (uint *)amDongle.dataBuffer; goto LAB_009f82f2; case AM_DONGLE_WTF_C3: if (sSize == NULL) goto LAB_009f82b7; do { cVar1 = *sSize; sSize = sSize + 1; } while (cVar1 != '\0'); LAB_009f82d7: // FUN_009f6940(); puVar11 = (uint *)amDongle.dataBuffer; LAB_009f82f2: if (local_8 < *puVar11) { *puVar11 = local_8; } return AM_DONGLE_STATUS_OK; default: return AM_DONGLE_STATUS_OK; } return AM_DONGLE_STATUS_ERR_PCP; // LAB_009f7ff2: // iVar9 = (1 - (uint)bVar13) - (uint)(bVar13 != 0); // goto LAB_009f7ff7; // LAB_009f7ce1: // iVar9 = (1 - (uint)bVar13) - (uint)(bVar13 != 0); // goto LAB_009f7ce6; // LAB_009f7c82: // iVar9 = (1 - (uint)bVar13) - (uint)(bVar13 != 0); // goto LAB_009f7c87; // LAB_009f7a21: // iVar9 = (1 - (uint)bVar13) - (uint)(bVar13 != 0); // goto LAB_009f7a26; } AM_DONGLE_STATUS amDongleSendBinary(void) { void *buffer; uint bufferLength; switch (amDongle.requestCode) { case AM_DONGLE_WTF_C0: bufferLength = *(uint *)amDongle.dataBuffer; buffer = amDongle.valueBuffer; break; case AM_DONGLE_REQUEST_BILLING_UPDATE_PLAYLIMIT: buffer = amDongle.dataBuffer; bufferLength = 128; break; case AM_DONGLE_REQUEST_BILLING_UPDATE_NEARFULL: buffer = amDongle.dataBuffer; bufferLength = 128; break; case AM_DONGLE_WTF_C3: bufferLength = *(uint *)amDongle.dataBuffer; buffer = amDongle.valueBuffer; break; default: amDongle.seq = AM_DONGLE_SEQ_DONE; amDongle.field19_0x40 = -1; return AM_DONGLE_STATUS_ERR_PCP; } pcpaSetSendBinaryBuffer(&amDongle.pcpa, buffer, bufferLength); if (pcpaSendBinary(&amDongle.pcpa, TIMEOUT_NONE) != e_pcpa_ok) { amDongle.seq = AM_DONGLE_SEQ_DONE; return AM_DONGLE_STATUS_ERR_PCP; } amDongle.seq = AM_DONGLE_SEQ_DONE; return AM_DONGLE_STATUS_OK; } AM_DONGLE_STATUS amDongleRecvBinary(void) { void *buffer; uint bufferLength; switch (amDongle.requestCode) { case AM_DONGLE_APPBOOT_SEED: buffer = amDongle.valueBuffer; bufferLength = 16; break; case AM_DONGLE_WTF_81: case AM_DONGLE_REQUEST_BILLING_GET_CA_CERT: bufferLength = *(uint *)amDongle.dataBuffer; buffer = amDongle.valueBuffer; break; case AM_DONGLE_REQUEST_BILLING_GET_TRACEDATA: bufferLength = *amDongle.field_0x3444; buffer = amDongle.dataBuffer; break; case AM_DONGLE_REQUEST_BILLING_GET_SIGNATURE_PK: case AM_DONGLE_WTF_85: bufferLength = *(uint *)amDongle.dataBuffer; buffer = amDongle.valueBuffer; break; default: amDongle.seq = AM_DONGLE_SEQ_DONE; amDongle.field19_0x40 = -1; return AM_DONGLE_STATUS_ERR_PCP; } pcpaSetRecvBinaryBuffer(&amDongle.pcpa, buffer, bufferLength); if (pcpaRecvBinary(&amDongle.pcpa, TIMEOUT_NONE) != e_pcpa_ok) { amDongle.seq = AM_DONGLE_SEQ_DONE; return AM_DONGLE_STATUS_ERR_PCP; } amDongle.seq = AM_DONGLE_SEQ_DONE; return AM_DONGLE_STATUS_OK; } AM_DONGLE_STATUS amDongleSendAndReceiveEx(void) { AM_DONGLE_STATUS AVar1; amDongle.result = 0; AVar1 = amDongleOpenEx(); if (AVar1 != AM_DONGLE_STATUS_OK) amDongle.seq = AM_DONGLE_SEQ_DONE; while (amDongle.seq != AM_DONGLE_SEQ_DONE) { e_pcpa_t err = pcpaSendRequest(&amDongle.pcpa, TIMEOUT_NONE); if (err != e_pcpa_ok) { if (amDongleDebugLevel > 0) amiDebugLog("Error : pcpaSendRequest(%d)", err); amDongle.field19_0x40 = -1; AVar1 = AM_DONGLE_STATUS_ERR_PCP; amDongle.seq = AM_DONGLE_SEQ_DONE; break; } err = pcpaRecvResponse(&amDongle.pcpa, TIMEOUT_NONE); if (err != e_pcpa_ok) { amDongle.field19_0x40 = -1; AVar1 = AM_DONGLE_STATUS_ERR_PCP; amDongle.seq = AM_DONGLE_SEQ_DONE; break; } AVar1 = amDongleResponseCheck(); if (amDongle.result != AM_DONGLE_STATUS_OK) AVar1 = amDongle.result; if (amDongle.seq == AM_DONGLE_SEQ_BINARY) { err = pcpaOpenBinaryClient(&amDongle.pcpa, amDongle.data_port, TIMEOUT_NONE); if (err == e_pcpa_ok) { if ((amDongle.requestCode & 0x40) == 0) amDongle.seq = AM_DONGLE_SEQ_RECV_BINARY; else amDongle.seq = AM_DONGLE_SEQ_SEND_BINARY; AVar1 = AM_DONGLE_STATUS_OK; } else { amDongle.seq = AM_DONGLE_SEQ_DONE; AVar1 = AM_DONGLE_STATUS_ERR_PCP; } } if (amDongle.seq == AM_DONGLE_SEQ_SEND_BINARY) AVar1 = amDongleSendBinary(); if (amDongle.seq == AM_DONGLE_SEQ_RECV_BINARY) AVar1 = amDongleRecvBinary(); } pcpaCloseBinary(&amDongle.pcpa); pcpaClose(&amDongle.pcpa); amDongle.seq = AM_DONGLE_SEQ_NONE; amDongle.result = 0; return AVar1; } AM_DONGLE_STATUS amDongleExit(void) { if (!amDongle.m_init) return AM_DONGLE_STATUS_ERR_NO_INIT; pcpaClose(&amDongle.pcpa); memset(&amDongle, 0, sizeof amDongle); amDongle.m_init = FALSE; return AM_DONGLE_STATUS_OK; } // TODO: These two functions for loading tables int amDongleLoadDsTable(FILE *fp) { return 0; } int amDongleLoadSsdTable(FILE *fp) { return 0; } AM_DONGLE_STATUS amDongleSetAuthConfig(char *authConfig) { if (amDongle.m_init == 0) return AM_DONGLE_STATUS_ERR_NO_INIT; if (authConfig == NULL) return AM_DONGLE_STATUS_ERR_INVALID_PARAM; if (strcmp(authConfig, "toolmode") != 0) { HANDLE hFile = CreateFileA(authConfig, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) return AM_DONGLE_STATUS_ERR_INVALID_PARAM; CloseHandle(hFile); FILE *fp; fopen_s(&fp, authConfig, "rb"); if (fp == NULL) return AM_DONGLE_STATUS_ERR_INVALID_PARAM; if (!amDongleLoadDsTable(fp) || !amDongleLoadSsdTable(fp)) { fclose(fp); return AM_DONGLE_STATUS_ERR_INVALID_PARAM; } fclose(fp); } amDongle.auth_ready = 1; amDongle.result = 0; return AM_DONGLE_STATUS_OK; } // PCP wrappers AM_DONGLE_STATUS amDongleBillingGetKeychipId(char *keychipId, AM_DONGLE_BLOCKING blocking) { if (!amDongle.m_init) return AM_DONGLE_STATUS_ERR_NO_INIT; if (!amDongle.auth_ready) return AM_DONGLE_STATUS_ERR_AUTH_READY; if (!amDongle.done_init || !amDongle.available) return AM_DONGLE_STATUS_NG; if (amDongle.seq != AM_DONGLE_SEQ_NONE) return AM_DONGLE_STATUS_BUSY; if (keychipId == NULL) return AM_DONGLE_STATUS_ERR_INVALID_PARAM; pcp_send_data_t *packet = pcpaSetSendPacket(&amDongle.pcpa, "keychip.billing.keyid", "?"); if (packet == NULL && amDongleDebugLevel > 0) amiDebugLog("Error: pcpaSetSendPacket return NULL"); packet = pcpaAddSendPacket(&amDongle.pcpa, "cache", "1"); if (packet == NULL && amDongleDebugLevel > 0) amiDebugLog("Error: pcpaAddSendPacket return NULL"); amDongle.valueBuffer = keychipId; amDongle.requestCode = AM_DONGLE_REQUEST_BILLING_GET_KEYCHIP_ID; if (blocking == AM_DONGLE_BLOCK) return amDongleSendAndReceiveEx(); return amDongleOpen(); } AM_DONGLE_STATUS amDongleGetGameId(char *gameId, AM_DONGLE_BLOCKING blocking) { if (!amDongle.m_init) return AM_DONGLE_STATUS_ERR_NO_INIT; if (!amDongle.auth_ready) return AM_DONGLE_STATUS_ERR_AUTH_READY; if (!amDongle.done_init || !amDongle.available) return AM_DONGLE_STATUS_NG; if (amDongle.seq != AM_DONGLE_SEQ_NONE) return AM_DONGLE_STATUS_BUSY; if (gameId == NULL) return AM_DONGLE_STATUS_ERR_INVALID_PARAM; pcp_send_data_t *packet = pcpaSetSendPacket(&amDongle.pcpa, "keychip.appboot.gameid", "?"); if (packet == NULL && amDongleDebugLevel > 0) amiDebugLog("Error: pcpaSetSendPacket return NULL"); packet = pcpaAddSendPacket(&amDongle.pcpa, "cache", "1"); if (packet == NULL && amDongleDebugLevel > 0) amiDebugLog("Error: pcpaAddSendPacket return NULL"); amDongle.valueBuffer = gameId; amDongle.requestCode = AM_DONGLE_REQUEST_GET_GAME_ID; if (blocking == AM_DONGLE_BLOCK) return amDongleSendAndReceiveEx(); return amDongleOpen(); } AM_DONGLE_STATUS amDongleGetPlatformId(char *platformId, AM_DONGLE_BLOCKING blocking) { if (!amDongle.m_init) return AM_DONGLE_STATUS_ERR_NO_INIT; if (!amDongle.auth_ready) return AM_DONGLE_STATUS_ERR_AUTH_READY; if (!amDongle.done_init || !amDongle.available) return AM_DONGLE_STATUS_NG; if (amDongle.seq != AM_DONGLE_SEQ_NONE) return AM_DONGLE_STATUS_BUSY; if (platformId == NULL) return AM_DONGLE_STATUS_ERR_INVALID_PARAM; pcp_send_data_t *packet = pcpaSetSendPacket(&amDongle.pcpa, "keychip.appboot.platformid", "?"); if (packet == NULL && amDongleDebugLevel > 0) amiDebugLog("Error: pcpaSetSendPacket return NULL"); packet = pcpaAddSendPacket(&amDongle.pcpa, "cache", "1"); if (packet == NULL && amDongleDebugLevel > 0) amiDebugLog("Error: pcpaAddSendPacket return NULL"); amDongle.valueBuffer = platformId; amDongle.requestCode = AM_DONGLE_REQUEST_GET_PLATFORM_ID; if (blocking == AM_DONGLE_BLOCK) return amDongleSendAndReceiveEx(); return amDongleOpen(); } AM_DONGLE_STATUS amDongleGetSystemFlag(unsigned char *systemFlag, AM_DONGLE_BLOCKING blocking) { if (!amDongle.m_init) return AM_DONGLE_STATUS_ERR_NO_INIT; if (!amDongle.auth_ready) return AM_DONGLE_STATUS_ERR_AUTH_READY; if (!amDongle.done_init || !amDongle.available) return AM_DONGLE_STATUS_NG; if (amDongle.seq != AM_DONGLE_SEQ_NONE) return AM_DONGLE_STATUS_BUSY; if (systemFlag == NULL) return AM_DONGLE_STATUS_ERR_INVALID_PARAM; pcp_send_data_t *packet = pcpaSetSendPacket(&amDongle.pcpa, "keychip.appboot.systemflag", "?"); if (packet == NULL && amDongleDebugLevel > 0) amiDebugLog("Error: pcpaSetSendPacket return NULL"); packet = pcpaAddSendPacket(&amDongle.pcpa, "cache", "1"); if (packet == NULL && amDongleDebugLevel > 0) amiDebugLog("Error: pcpaAddSendPacket return NULL"); amDongle.valueBuffer = systemFlag; amDongle.requestCode = AM_DONGLE_REQUEST_GET_SYSTEMFLAG; if (blocking == AM_DONGLE_BLOCK) return amDongleSendAndReceiveEx(); return amDongleOpen(); } AM_DONGLE_STATUS amDongleGetModelType(unsigned char *modelType, AM_DONGLE_BLOCKING blocking) { if (!amDongle.m_init) return AM_DONGLE_STATUS_ERR_NO_INIT; if (!amDongle.auth_ready) return AM_DONGLE_STATUS_ERR_AUTH_READY; if (!amDongle.done_init || !amDongle.available) return AM_DONGLE_STATUS_NG; if (amDongle.seq != AM_DONGLE_SEQ_NONE) return AM_DONGLE_STATUS_BUSY; if (modelType == NULL) return AM_DONGLE_STATUS_ERR_INVALID_PARAM; pcp_send_data_t *packet = pcpaSetSendPacket(&amDongle.pcpa, "keychip.appboot.modeltype", "?"); if (packet == NULL && amDongleDebugLevel > 0) amiDebugLog("Error: pcpaSetSendPacket return NULL"); packet = pcpaAddSendPacket(&amDongle.pcpa, "cache", "1"); if (packet == NULL && amDongleDebugLevel > 0) amiDebugLog("Error: pcpaAddSendPacket return NULL"); amDongle.valueBuffer = modelType; amDongle.requestCode = AM_DONGLE_REQUEST_GET_MODEL_TYPE; if (blocking == AM_DONGLE_BLOCK) return amDongleSendAndReceiveEx(); return amDongleOpen(); } AM_DONGLE_STATUS amDongleGetRegion(unsigned char *region, AM_DONGLE_BLOCKING blocking) { if (!amDongle.m_init) return AM_DONGLE_STATUS_ERR_NO_INIT; if (!amDongle.auth_ready) return AM_DONGLE_STATUS_ERR_AUTH_READY; if (!amDongle.done_init || !amDongle.available) return AM_DONGLE_STATUS_NG; if (amDongle.seq != AM_DONGLE_SEQ_NONE) return AM_DONGLE_STATUS_BUSY; if (region == NULL) return AM_DONGLE_STATUS_ERR_INVALID_PARAM; pcp_send_data_t *packet = pcpaSetSendPacket(&amDongle.pcpa, "keychip.appboot.region", "?"); if (packet == NULL && amDongleDebugLevel > 0) amiDebugLog("Error: pcpaSetSendPacket return NULL"); packet = pcpaAddSendPacket(&amDongle.pcpa, "cache", "1"); if (packet == NULL && amDongleDebugLevel > 0) amiDebugLog("Error: pcpaAddSendPacket return NULL"); amDongle.valueBuffer = region; amDongle.requestCode = AM_DONGLE_REQUEST_GET_REGION; if (blocking == AM_DONGLE_BLOCK) return amDongleSendAndReceiveEx(); return amDongleOpen(); } AM_DONGLE_STATUS amDongleGetNetworkAddress(unsigned int *networkAddress, AM_DONGLE_BLOCKING blocking) { if (!amDongle.m_init) return AM_DONGLE_STATUS_ERR_NO_INIT; if (!amDongle.auth_ready) return AM_DONGLE_STATUS_ERR_AUTH_READY; if (!amDongle.done_init || !amDongle.available) return AM_DONGLE_STATUS_NG; if (amDongle.seq != AM_DONGLE_SEQ_NONE) return AM_DONGLE_STATUS_BUSY; if (networkAddress == NULL) return AM_DONGLE_STATUS_ERR_INVALID_PARAM; pcp_send_data_t *packet = pcpaSetSendPacket(&amDongle.pcpa, "keychip.appboot.networkaddr", "?"); if (packet == NULL && amDongleDebugLevel > 0) amiDebugLog("Error: pcpaSetSendPacket return NULL"); packet = pcpaAddSendPacket(&amDongle.pcpa, "cache", "1"); if (packet == NULL && amDongleDebugLevel > 0) amiDebugLog("Error: pcpaAddSendPacket return NULL"); amDongle.valueBuffer = networkAddress; amDongle.requestCode = AM_DONGLE_REQUEST_GET_NETWORK_ADDRESS; if (blocking == AM_DONGLE_BLOCK) return amDongleSendAndReceiveEx(); return amDongleOpen(); } AM_DONGLE_STATUS amDongleGetVersion(unsigned short *version, AM_DONGLE_BLOCKING blocking) { if (!amDongle.m_init) return AM_DONGLE_STATUS_ERR_NO_INIT; if (!amDongle.auth_ready) return AM_DONGLE_STATUS_ERR_AUTH_READY; if (!amDongle.done_init || !amDongle.available) return AM_DONGLE_STATUS_NG; if (amDongle.seq != AM_DONGLE_SEQ_NONE) return AM_DONGLE_STATUS_BUSY; if (version == NULL) return AM_DONGLE_STATUS_ERR_INVALID_PARAM; pcp_send_data_t *packet = pcpaSetSendPacket(&amDongle.pcpa, "keychip.version", "?"); if (packet == NULL && amDongleDebugLevel > 0) amiDebugLog("Error: pcpaSetSendPacket return NULL"); packet = pcpaAddSendPacket(&amDongle.pcpa, "device", "n2"); if (packet == NULL && amDongleDebugLevel > 0) amiDebugLog("Error: pcpaAddSendPacket return NULL"); packet = pcpaAddSendPacket(&amDongle.pcpa, "cache", "1"); if (packet == NULL && amDongleDebugLevel > 0) amiDebugLog("Error: pcpaAddSendPacket return NULL"); amDongle.valueBuffer = version; amDongle.requestCode = AM_DONGLE_REQUEST_GET_VERSION; if (blocking == AM_DONGLE_BLOCK) return amDongleSendAndReceiveEx(); return amDongleOpen(); } AM_DONGLE_STATUS amDongleGetPicVersion(unsigned short *picVersion, AM_DONGLE_BLOCKING blocking) { if (!amDongle.m_init) return AM_DONGLE_STATUS_ERR_NO_INIT; if (!amDongle.auth_ready) return AM_DONGLE_STATUS_ERR_AUTH_READY; if (!amDongle.done_init || !amDongle.available) return AM_DONGLE_STATUS_NG; if (amDongle.seq != AM_DONGLE_SEQ_NONE) return AM_DONGLE_STATUS_BUSY; if (picVersion == NULL) return AM_DONGLE_STATUS_ERR_INVALID_PARAM; pcp_send_data_t *packet = pcpaSetSendPacket(&amDongle.pcpa, "keychip.version", "?"); if (packet == NULL && amDongleDebugLevel > 0) amiDebugLog("Error: pcpaSetSendPacket return NULL"); packet = pcpaAddSendPacket(&amDongle.pcpa, "cache", "0"); if (packet == NULL && amDongleDebugLevel > 0) amiDebugLog("Error: pcpaAddSendPacket return NULL"); amDongle.valueBuffer = picVersion; amDongle.requestCode = AM_DONGLE_REQUEST_GET_VERSION; if (blocking == AM_DONGLE_BLOCK) return amDongleSendAndReceiveEx(); return amDongleOpen(); } AM_DONGLE_STATUS amDongleEncrypt(unsigned char *pt, unsigned char *ct, AM_DONGLE_BLOCKING blocking) { if (!amDongle.m_init) return AM_DONGLE_STATUS_ERR_NO_INIT; if (!amDongle.auth_ready) return AM_DONGLE_STATUS_ERR_AUTH_READY; if (!amDongle.done_init || !amDongle.available) return AM_DONGLE_STATUS_NG; if (amDongle.seq != AM_DONGLE_SEQ_NONE) return AM_DONGLE_STATUS_BUSY; if (pt == NULL || ct == NULL) return AM_DONGLE_STATUS_ERR_INVALID_PARAM; char ptHex[33]; bin_to_hex(ptHex, pt, 16); pcp_send_data_t *packet = pcpaSetSendPacket(&amDongle.pcpa, "keychip.encrypt", ptHex); if (packet == NULL && amDongleDebugLevel > 0) amiDebugLog("Error: pcpaSetSendPacket return NULL"); amDongle.valueBuffer = ct; amDongle.requestCode = AM_DONGLE_REQUEST_ENCRYPT; if (blocking == AM_DONGLE_BLOCK) return amDongleSendAndReceiveEx(); return amDongleOpen(); } AM_DONGLE_STATUS amDongleDecrypt(unsigned char *ct, unsigned char *pt, AM_DONGLE_BLOCKING blocking) { if (!amDongle.m_init) return AM_DONGLE_STATUS_ERR_NO_INIT; if (!amDongle.auth_ready) return AM_DONGLE_STATUS_ERR_AUTH_READY; if (!amDongle.done_init || !amDongle.available) return AM_DONGLE_STATUS_NG; if (amDongle.seq != AM_DONGLE_SEQ_NONE) return AM_DONGLE_STATUS_BUSY; if (ct == NULL || pt == NULL) return AM_DONGLE_STATUS_ERR_INVALID_PARAM; char ctHex[33]; ZeroMemory(ctHex, 33); bin_to_hex(ctHex, ct, 16); pcp_send_data_t *packet = pcpaSetSendPacket(&amDongle.pcpa, "keychip.decrypt", ctHex); if (packet == NULL && amDongleDebugLevel > 0) amiDebugLog("Error: pcpaSetSendPacket return NULL"); amDongle.valueBuffer = pt; amDongle.requestCode = AM_DONGLE_REQUEST_DECRYPT; if (blocking == AM_DONGLE_BLOCK) return amDongleSendAndReceiveEx(); return amDongleOpen(); } AM_DONGLE_STATUS amDongleBillingGetPlayCount(unsigned int *playCount, AM_DONGLE_BLOCKING blocking) { if (!amDongle.m_init) return AM_DONGLE_STATUS_ERR_NO_INIT; if (!amDongle.auth_ready) return AM_DONGLE_STATUS_ERR_AUTH_READY; if (!amDongle.done_init || !amDongle.available) return AM_DONGLE_STATUS_NG; if (amDongle.seq != AM_DONGLE_SEQ_NONE) return AM_DONGLE_STATUS_BUSY; if (playCount == NULL) return AM_DONGLE_STATUS_ERR_INVALID_PARAM; pcp_send_data_t *send_data = pcpaSetSendPacket(&amDongle.pcpa, "keychip.billing.playcount", "?"); if (send_data == NULL && amDongleDebugLevel > 0) { amiDebugLog("Error: pcpaSetSendPacket return NULL"); } send_data = pcpaAddSendPacket(&amDongle.pcpa, "cache", "1"); if (send_data == NULL && amDongleDebugLevel > 0) { amiDebugLog("Error: pcpaAddSendPacket return NULL"); } amDongle.valueBuffer = playCount; amDongle.requestCode = AM_DONGLE_REQUEST_BILLING_GET_PLAYCOUNT; if (blocking == AM_DONGLE_BLOCK) { return amDongleSendAndReceiveEx(); } return amDongleOpen(); } AM_DONGLE_STATUS amDongleBillingGetPlayLimit(unsigned int *playLimit, AM_DONGLE_BLOCKING blocking) { if (!amDongle.m_init) return AM_DONGLE_STATUS_ERR_NO_INIT; if (!amDongle.auth_ready) return AM_DONGLE_STATUS_ERR_AUTH_READY; if (!amDongle.done_init || !amDongle.available) return AM_DONGLE_STATUS_NG; if (amDongle.seq != AM_DONGLE_SEQ_NONE) return AM_DONGLE_STATUS_BUSY; if (playLimit == NULL) return AM_DONGLE_STATUS_ERR_INVALID_PARAM; pcp_send_data_t *send_data = pcpaSetSendPacket(&amDongle.pcpa, "keychip.billing.playlimit", "?"); if (send_data == NULL && amDongleDebugLevel > 0) { amiDebugLog("Error: pcpaSetSendPacket return NULL"); } send_data = pcpaAddSendPacket(&amDongle.pcpa, "cache", "1"); if (send_data == NULL && amDongleDebugLevel > 0) { amiDebugLog("Error: pcpaAddSendPacket return NULL"); } amDongle.valueBuffer = playLimit; amDongle.requestCode = AM_DONGLE_REQUEST_BILLING_GET_PLAYLIMIT; if (blocking == AM_DONGLE_BLOCK) { return amDongleSendAndReceiveEx(); } return amDongleOpen(); } AM_DONGLE_STATUS amDongleBillingGetNearfull(unsigned int *nearfull, AM_DONGLE_BLOCKING blocking) { if (!amDongle.m_init) return AM_DONGLE_STATUS_ERR_NO_INIT; if (!amDongle.auth_ready) return AM_DONGLE_STATUS_ERR_AUTH_READY; if (!amDongle.done_init || !amDongle.available) return AM_DONGLE_STATUS_NG; if (amDongle.seq != AM_DONGLE_SEQ_NONE) return AM_DONGLE_STATUS_BUSY; if (nearfull == NULL) return AM_DONGLE_STATUS_ERR_INVALID_PARAM; pcp_send_data_t *send_data = pcpaSetSendPacket(&amDongle.pcpa, "keychip.billing.nearfull", "?"); if (send_data == NULL && amDongleDebugLevel > 0) { amiDebugLog("Error: pcpaSetSendPacket return NULL"); } send_data = pcpaAddSendPacket(&amDongle.pcpa, "cache", "1"); if (send_data == NULL && amDongleDebugLevel > 0) { amiDebugLog("Error: pcpaAddSendPacket return NULL"); } amDongle.valueBuffer = nearfull; amDongle.requestCode = AM_DONGLE_REQUEST_BILLING_GET_NEARFULL; if (blocking == AM_DONGLE_BLOCK) { return amDongleSendAndReceiveEx(); } return amDongleOpen(); } AM_DONGLE_STATUS amDongleBillingAddPlayCount(void *playCount, AM_DONGLE_BLOCKING blocking) { if (!amDongle.m_init) return AM_DONGLE_STATUS_ERR_NO_INIT; if (!amDongle.auth_ready) return AM_DONGLE_STATUS_ERR_AUTH_READY; if (!amDongle.done_init || !amDongle.available) return AM_DONGLE_STATUS_NG; if (amDongle.seq != AM_DONGLE_SEQ_NONE) return AM_DONGLE_STATUS_BUSY; if (playCount == NULL) return AM_DONGLE_STATUS_ERR_INVALID_PARAM; pcp_send_data_t *send_data = pcpaSetSendPacket(&amDongle.pcpa, "keychip.billing.playcount", "1"); if (send_data == NULL && amDongleDebugLevel > 0) { amiDebugLog("Error: pcpaSetSendPacket return NULL"); } send_data = pcpaAddSendPacket(&amDongle.pcpa, "cache", "1"); if (send_data == NULL && amDongleDebugLevel > 0) { amiDebugLog("Error: pcpaAddSendPacket return NULL"); } amDongle.valueBuffer = playCount; amDongle.requestCode = AM_DONGLE_REQUEST_BILLING_ADD_PLAYCOUNT; if (blocking == AM_DONGLE_BLOCK) { return amDongleSendAndReceiveEx(); } return amDongleOpen(); } AM_DONGLE_STATUS amDongleSetIv(AM_DONGLE_BLOCKING blocking) { if (!amDongle.m_init) return AM_DONGLE_STATUS_ERR_NO_INIT; if (!amDongle.auth_ready) return AM_DONGLE_STATUS_ERR_AUTH_READY; if (!amDongle.done_init || !amDongle.available) return AM_DONGLE_STATUS_NG; if (amDongle.seq != AM_DONGLE_SEQ_NONE) return AM_DONGLE_STATUS_BUSY; pcp_send_data_t *send_data = pcpaSetSendPacket(&amDongle.pcpa, "keychip.setiv", "?"); if (send_data == NULL && amDongleDebugLevel > 0) { amiDebugLog("Error: pcpaSetSendPacket return NULL"); } amDongle.requestCode = AM_DONGLE_REQUEST_SET_IV; if (blocking == AM_DONGLE_BLOCK) { return amDongleSendAndReceiveEx(); } return amDongleOpen(); } AM_DONGLE_STATUS amDongleGetSeed(unsigned char *seed, AM_DONGLE_BLOCKING blocking) { if (!amDongle.m_init) return AM_DONGLE_STATUS_ERR_NO_INIT; if (!amDongle.auth_ready) return AM_DONGLE_STATUS_ERR_AUTH_READY; if (!amDongle.done_init || !amDongle.available) return AM_DONGLE_STATUS_NG; if (amDongle.seq != AM_DONGLE_SEQ_NONE) return AM_DONGLE_STATUS_BUSY; if (seed == NULL) return AM_DONGLE_STATUS_ERR_INVALID_PARAM; pcp_send_data_t *send_data = pcpaSetSendPacket(&amDongle.pcpa, "keychip.appboot.seed", "?"); if (send_data == NULL && amDongleDebugLevel > 0) { amiDebugLog("Error: pcpaSetSendPacket return NULL"); } send_data = pcpaAddSendPacket(&amDongle.pcpa, "cache", "1"); if (send_data == NULL && amDongleDebugLevel > 0) { amiDebugLog("Error: pcpaAddSendPacket return NULL"); } amDongle.requestCode = AM_DONGLE_APPBOOT_SEED; amDongle.valueBuffer = seed; if (blocking == AM_DONGLE_BLOCK) { return amDongleSendAndReceiveEx(); } return amDongleOpen(); }