int WadWriteSkiToObj(wad_dir * wd, wad_record * wr, uint32_t no_alpha, uint32_t level_of_detail, uint32_t mipmap_level, const char * dir) { uint8_t * data; ski_header * header; uint32_t * mesh_material_ids; mes_ski_mesh_record * mesh_records; mes_ski_material_record * material_records; mes_ski_material_header * material_header; mes_ski_mesh_header * mesh_header; mes_ski_material_param * material_params; ski_mesh_group_record * mesh_group_records; FILE * in_file; FILE * out_file; rmid_file rf; wad_record * swr; wad_record * twr; char filename[512]; uint32_t m, mg, p, v, f; rmid_file trf; uint32_t vertex_counter; uint32_t mesh_counter; uint32_t index_data_size; void * vertex_data; uint8_t * vertex_byte_data; void * face_data; uint32_t total_meshes; if(wr->type != RMID_TYPE_SKI) { return 1; } if(fopen_s(&in_file, wr->filename, "rb") != 0) { printf("ERROR: Unable to open file %s\n", wr->filename); return 1; } fseek(in_file, (long)wr->data_offset, SEEK_SET); if(RmidLoad(in_file, (long)wr->data_size, &rf) != 0) { printf("ERROR: Failed to load RMID data\n"); fclose(in_file); return 1; } data = (uint8_t *)rf.data; header = (ski_header*)(data + sizeof(rmid_header)); mesh_material_ids = (uint32_t*)(data + header->mesh_material_ids_offset); mesh_records = (mes_ski_mesh_record*)(data + header->mesh_table_offset); material_records = (mes_ski_material_record*)(data + header->material_table_offset); mesh_group_records = (ski_mesh_group_record *)(data + header->mesh_group_table_offset); sprintf_s(filename, sizeof(filename),"%s\\%s.mtl", dir, wr->name); if(fopen_s(&out_file, filename, "w") != 0) { printf("ERROR: Unable to open file %s\n", filename); RmidFree(&rf); fclose(in_file); return 1; } for(m = 0; m < header->total_materials; m++) { material_header = (mes_ski_material_header *)(data + material_records[m].offset); swr = WadDirFindByID(wd, material_header->shader_id); if(swr == NULL) { printf("Unable to find shader ID 0x%08X", EndianSwap(material_header->shader_id)); RmidFree(&rf); fclose(in_file); fclose(out_file); return 1; } WadRecordResolveName(swr); DEBUG_PRINT((" Shader %s\n", swr->name)); fprintf(out_file, "newmtl %s_%d\n", swr->name, m); fprintf(out_file, "Ka 1.000 1.000 1.000\n"); fprintf(out_file, "Kd 1.000 1.000 1.000\n"); fprintf(out_file, "Ks 0.000 0.000 0.000\n"); fprintf(out_file, "d 1.0\n"); material_params = (mes_ski_material_param *)(data + material_records[m].offset + sizeof(mes_ski_material_header)); for(p = 0; p < material_header->total_material_params; p++) { DEBUG_PRINT((" [%d] T=0x%08X V=0x%08X ", p, EndianSwap(material_params[p].param_type), EndianSwap(material_params[p].texture_id))); if((twr = WadDirFindByID(wd, material_params[p].texture_id)) == NULL) { DEBUG_PRINT(("\n")); } else { WadRecordResolveName(twr); if(material_params[p].param_type == RMID_MAT_PARAM_COLOR1) { RmidLoadFromFile(twr->filename, twr->data_offset, twr->data_size, &trf); RmidWriteTexToPng(&trf, 0, no_alpha, mipmap_level, dir, twr->name); fprintf(out_file, "map_Ka %s.png\n", twr->name); fprintf(out_file, "map_Kd %s.png\n", twr->name); RmidFree(&trf); } DEBUG_PRINT(("%s\n", twr->name)); } } } fclose(out_file); total_meshes = 0; sprintf_s(filename, sizeof(filename),"%s\\%s.obj",dir, wr->name); if(fopen_s(&out_file, filename, "w") != 0) { printf("ERROR: Unable to open file %s\n", filename); RmidFree(&rf); fclose(in_file); return 1; } fprintf(out_file, "# Generated with mes2obj\n"); fprintf(out_file, "mtllib %s.mtl\n", wr->name); vertex_counter = 0; mesh_counter = 0; DEBUG_PRINT(("Mesh Groups %d\n", header->total_mesh_groups)); if(level_of_detail > header->total_mesh_groups) { printf("Requested LoD %d is too high. Using %d instead.\n", level_of_detail, header->total_mesh_groups); level_of_detail = header->total_mesh_groups; } for(mg = 0; mg < header->total_mesh_groups; mg++) { if(level_of_detail > 0) { if((level_of_detail-1) != mg) { mesh_counter += mesh_group_records[mg].total_meshes; continue; } } DEBUG_PRINT((" [%d] %d Meshes\n", mg, mesh_group_records[mg].total_meshes)); for(m = 0; m < mesh_group_records[mg].total_meshes; m++) { mesh_header = (mes_ski_mesh_header*)(data + mesh_records[mesh_counter].offset); material_header = (mes_ski_material_header *)(data + material_records[mesh_material_ids[mesh_counter]].offset); DEBUG_PRINT((" [%d] O=%d", mesh_counter, mesh_records[mesh_counter].offset)); DEBUG_PRINT((" S=%d", mesh_records[mesh_counter].size)); DEBUG_PRINT((" BPV=%d", mesh_header->bytes_per_vertex)); DEBUG_PRINT((" V=%d", mesh_header->num_vertices1)); DEBUG_PRINT((" I=%d\n", mesh_header->num_indices1)); //mesh_header = (mes_ski_mesh_header*)(data + mesh_records[m].offset); swr = WadDirFindByID(wd, material_header->shader_id); index_data_size = (uint32_t)(mesh_records[mesh_counter].size - (mesh_header->index_data_offset - *(data + mesh_records[mesh_counter].offset))); fprintf(out_file, "o %s_%d\n", wr->name, mesh_counter); // Vertices vertex_data = (void*)(data + mesh_records[mesh_counter].offset + mesh_header->vertex_data_offset); vertex_byte_data = (uint8_t *)vertex_data; for(v = 0; v < mesh_header->num_vertices1; v++) { ObjWritePosition(out_file, mesh_header, vertex_byte_data); vertex_byte_data += mesh_header->bytes_per_vertex; } // Texture Coords vertex_byte_data = (uint8_t *)vertex_data; for(v = 0; v < mesh_header->num_vertices1; v++) { ObjWriteTexCoord(out_file, mesh_header, vertex_byte_data); vertex_byte_data += mesh_header->bytes_per_vertex; } // Normals vertex_byte_data = (uint8_t *)vertex_data; for(v = 0; v < mesh_header->num_vertices1; v++) { ObjWriteNormal(out_file, mesh_header, vertex_byte_data); vertex_byte_data += mesh_header->bytes_per_vertex; } // Faces fprintf(out_file, "usemtl %s_%d\n", swr->name,mesh_material_ids[mesh_counter]); fprintf(out_file, "s off\n"); face_data = (void *)(data + mesh_records[mesh_counter].offset + mesh_header->index_data_offset); fprintf(out_file, "# Faces %d\n",mesh_header->num_indices1/3); for(f = 0; f < mesh_header->num_indices1/3; f++) { if((index_data_size / 2) == mesh_header->num_indices1) { ObjWriteFace16(out_file, vertex_counter, face_data, f); } else { ObjWriteFace32(out_file, vertex_counter, face_data, f); } } vertex_counter += mesh_header->num_vertices1; mesh_counter++; } } fclose(out_file); RmidFree(&rf); fclose(in_file); return 0; }
SHARETEST_VALUE ShareTest_BTC(uint* workdata, uint* target) { uint hash[8]; uint initial[8]; uint work[64]; memcpy(hash, sha256_init, 8*sizeof(uint)); memcpy(work, workdata, 16*sizeof(uint)); memcpy(initial, hash, 8*sizeof(uint)); for(uint i=0; i<64; ++i) { if (i>=16) work[i] = work[i-7] + work[i-16] + Wr(work[i-2],17,19,10) + Wr(work[i-15],7,18,3); sharound(hash[(0-i)&7],hash[(1-i)&7],hash[(2-i)&7],hash[(3-i)&7],hash[(4-i)&7],hash[(5-i)&7],hash[(6-i)&7],hash[(7-i)&7],work[i],K[i]); } for(uint i=0; i<8; ++i) hash[i] += initial[i]; memset(work, 0, 16*sizeof(uint)); memcpy(work, workdata+16, 4*sizeof(uint)); work[4] = (1U<<31U); work[15] = 0x280; memcpy(initial, hash, 8*sizeof(uint)); for(uint i=0; i<64; ++i) { if (i>=16) work[i] = work[i-7] + work[i-16] + Wr(work[i-2],17,19,10) + Wr(work[i-15],7,18,3); sharound(hash[(0-i)&7],hash[(1-i)&7],hash[(2-i)&7],hash[(3-i)&7],hash[(4-i)&7],hash[(5-i)&7],hash[(6-i)&7],hash[(7-i)&7],work[i],K[i]); } for(uint i=0; i<8; ++i) hash[i] += initial[i]; memset(work, 0, 16*sizeof(uint)); memcpy(work, hash, 8*sizeof(uint)); work[8] = (1U<<31U); work[15] = 0x100; memcpy(hash, sha256_init, 8*sizeof(uint)); memcpy(initial, hash, 8*sizeof(uint)); for(uint i=0; i<64; ++i) { if (i>=16) work[i] = work[i-7] + work[i-16] + Wr(work[i-2],17,19,10) + Wr(work[i-15],7,18,3); sharound(hash[(0-i)&7],hash[(1-i)&7],hash[(2-i)&7],hash[(3-i)&7],hash[(4-i)&7],hash[(5-i)&7],hash[(6-i)&7],hash[(7-i)&7],work[i],K[i]); } for(uint i=0; i<8; ++i) hash[i] = EndianSwap(hash[i]+initial[i]); if (hash[7] != 0) return ST_HNOTZERO; for(int i=6; i>=0; --i) { if (hash[i] > target[i]) { //cout << "Hash > target! :(" << endl; return ST_MORETHANTARGET; } if (hash[i] < target[i]) { //cout << "Hash < target! :)" << endl; return ST_GOOD; } } //cout << "Hash = target! :|" << endl; return ST_MORETHANTARGET; /* if (hash[7] == 0) { if (globalconfs.log_midhash) { fstream filu("hashes.txt", ios_base::out|ios_base::app); filu << setfill('0'); for(uint i=0; i<8; ++i) filu << setw(8) << hex << work[i] << " "; filu << endl; } return true; } else { return false; }*/ }
void Sha256_round(uint* s, unsigned char* data) { uint work[64]; uint* udata = (uint*)data; for(uint i=0; i<16; ++i) { work[i] = EndianSwap(udata[i]); } uint A = s[0]; uint B = s[1]; uint C = s[2]; uint D = s[3]; uint E = s[4]; uint F = s[5]; uint G = s[6]; uint H = s[7]; sharound(A,B,C,D,E,F,G,H,work[0],K[0]); sharound(H,A,B,C,D,E,F,G,work[1],K[1]); sharound(G,H,A,B,C,D,E,F,work[2],K[2]); sharound(F,G,H,A,B,C,D,E,work[3],K[3]); sharound(E,F,G,H,A,B,C,D,work[4],K[4]); sharound(D,E,F,G,H,A,B,C,work[5],K[5]); sharound(C,D,E,F,G,H,A,B,work[6],K[6]); sharound(B,C,D,E,F,G,H,A,work[7],K[7]); sharound(A,B,C,D,E,F,G,H,work[8],K[8]); sharound(H,A,B,C,D,E,F,G,work[9],K[9]); sharound(G,H,A,B,C,D,E,F,work[10],K[10]); sharound(F,G,H,A,B,C,D,E,work[11],K[11]); sharound(E,F,G,H,A,B,C,D,work[12],K[12]); sharound(D,E,F,G,H,A,B,C,work[13],K[13]); sharound(C,D,E,F,G,H,A,B,work[14],K[14]); sharound(B,C,D,E,F,G,H,A,work[15],K[15]); sharound(A,B,C,D,E,F,G,H,R(16),K[16]); sharound(H,A,B,C,D,E,F,G,R(17),K[17]); sharound(G,H,A,B,C,D,E,F,R(18),K[18]); sharound(F,G,H,A,B,C,D,E,R(19),K[19]); sharound(E,F,G,H,A,B,C,D,R(20),K[20]); sharound(D,E,F,G,H,A,B,C,R(21),K[21]); sharound(C,D,E,F,G,H,A,B,R(22),K[22]); sharound(B,C,D,E,F,G,H,A,R(23),K[23]); sharound(A,B,C,D,E,F,G,H,R(24),K[24]); sharound(H,A,B,C,D,E,F,G,R(25),K[25]); sharound(G,H,A,B,C,D,E,F,R(26),K[26]); sharound(F,G,H,A,B,C,D,E,R(27),K[27]); sharound(E,F,G,H,A,B,C,D,R(28),K[28]); sharound(D,E,F,G,H,A,B,C,R(29),K[29]); sharound(C,D,E,F,G,H,A,B,R(30),K[30]); sharound(B,C,D,E,F,G,H,A,R(31),K[31]); sharound(A,B,C,D,E,F,G,H,R(32),K[32]); sharound(H,A,B,C,D,E,F,G,R(33),K[33]); sharound(G,H,A,B,C,D,E,F,R(34),K[34]); sharound(F,G,H,A,B,C,D,E,R(35),K[35]); sharound(E,F,G,H,A,B,C,D,R(36),K[36]); sharound(D,E,F,G,H,A,B,C,R(37),K[37]); sharound(C,D,E,F,G,H,A,B,R(38),K[38]); sharound(B,C,D,E,F,G,H,A,R(39),K[39]); sharound(A,B,C,D,E,F,G,H,R(40),K[40]); sharound(H,A,B,C,D,E,F,G,R(41),K[41]); sharound(G,H,A,B,C,D,E,F,R(42),K[42]); sharound(F,G,H,A,B,C,D,E,R(43),K[43]); sharound(E,F,G,H,A,B,C,D,R(44),K[44]); sharound(D,E,F,G,H,A,B,C,R(45),K[45]); sharound(C,D,E,F,G,H,A,B,R(46),K[46]); sharound(B,C,D,E,F,G,H,A,R(47),K[47]); sharound(A,B,C,D,E,F,G,H,R(48),K[48]); sharound(H,A,B,C,D,E,F,G,R(49),K[49]); sharound(G,H,A,B,C,D,E,F,R(50),K[50]); sharound(F,G,H,A,B,C,D,E,R(51),K[51]); sharound(E,F,G,H,A,B,C,D,R(52),K[52]); sharound(D,E,F,G,H,A,B,C,R(53),K[53]); sharound(C,D,E,F,G,H,A,B,R(54),K[54]); sharound(B,C,D,E,F,G,H,A,R(55),K[55]); sharound(A,B,C,D,E,F,G,H,R(56),K[56]); sharound(H,A,B,C,D,E,F,G,R(57),K[57]); sharound(G,H,A,B,C,D,E,F,R(58),K[58]); sharound(F,G,H,A,B,C,D,E,R(59),K[59]); sharound(E,F,G,H,A,B,C,D,R(60),K[60]); sharound(D,E,F,G,H,A,B,C,R(61),K[61]); sharound(C,D,E,F,G,H,A,B,R(62),K[62]); sharound(B,C,D,E,F,G,H,A,R(63),K[63]); s[0] += A; s[1] += B; s[2] += C; s[3] += D; s[4] += E; s[5] += F; s[6] += G; s[7] += H; }
enum Result CrocPack(const char *dirname, const char *fsname, const char *outputpath, const char *list, enum ENDIAN endian, bool align) { FILE *fDir, *fArc, *fList; if (!OpenFile(&fDir, dirname, OPENFILECREATE)) return FILENOTCREATED; if (!OpenFile(&fArc, fsname, OPENFILECREATE)) return FILENOTCREATED; if (!OpenFile(&fList, list, OPENFILEREAD)) return FILENOTFOUND; if (endian == ENOTSET) { msgPrint(MsgLv_Warning, "Endian not specified.\n"); msgPrint(MsgLv_Info, "Endian set to %s.\n", "LITTLE (PS1 ver.)"); endian = ELITTLE; } unsigned int entries = 0; fseek(fDir, 4, SEEK_SET); unsigned int pos = 0; char name[0x0D]; char path[MAX_PATH]; struct CrocFsEntry CrocFsEntry; while(fscanf(fList, "%s", name) != EOF) { int i; FILE *f; sprintf(path, "%s\\%s", outputpath, name); msgPrint(MsgLv_Message, "Packing %s\n", name); if (!OpenFile(&f, name, OPENFILECREATE)) return FILENOTCREATED; for (i = 0; i < 0xC && name[i] != '\0'; i++) CrocFsEntry.name[i] = name[i]; for(; i < 0xC; i++) CrocFsEntry.name[i] = 0; CrocFsEntry.size = GetFileSize(f); CrocFsEntry.pos = pos; CrocFsEntry.dummy = 0; void *data = malloc(CrocFsEntry.size); fread(data, 1, CrocFsEntry.size, f); fclose(f); fwrite(data, 1, CrocFsEntry.size, fArc); free(data); if (align) { pos += (CrocFsEntry.size & 0x7FF) != 0 ? CrocFsEntry.size + (0x800 - (CrocFsEntry.size%0x800)) : CrocFsEntry.size; fseek(fArc, pos, SEEK_SET); } else pos += CrocFsEntry.size; if (endian == EBIG) { CrocFsEntry.size = EndianSwap(CrocFsEntry.size); CrocFsEntry.size = EndianSwap(CrocFsEntry.pos); } fwrite(&CrocFsEntry, 1, sizeof(struct CrocFsEntry), fDir); entries++; } unsigned int unknowvalue = 0; fclose(fList); fclose(fArc); if (endian == EBIG) entries = EndianSwap(entries); fwrite(&unknowvalue, 1, sizeof(unknowvalue), fDir); fseek(fDir, 0, SEEK_SET); fwrite(&entries, 1, sizeof(entries), fDir); fclose(fDir); return NOERRORS; }
BOOL ReadConfig ( struct AHIDevUnit *iounit, struct AHIBase *AHIBase ) { struct IFFHandle *iff; struct StoredProperty *prhd,*ahig; struct CollectionItem *ci; ULONG *mode; if(iounit) { /* Internal defaults for device unit */ iounit->AudioMode = AHI_INVALID_ID; // See at the end of the function! iounit->Frequency = 10000; iounit->Channels = 4; iounit->MonitorVolume = ~0; iounit->InputGain = ~0; iounit->OutputVolume = ~0; iounit->Input = ~0; iounit->Output = ~0; } else { /* Internal defaults for low-level mode */ AHIBase->ahib_AudioMode = AHI_INVALID_ID; AHIBase->ahib_Frequency = 10000; AHIBase->ahib_MonitorVolume = 0x00000; AHIBase->ahib_InputGain = 0x10000; AHIBase->ahib_OutputVolume = 0x10000; AHIBase->ahib_Input = 0; AHIBase->ahib_Output = 0; } if((iff=AllocIFF())) { iff->iff_Stream=(ULONG) Open("ENV:Sys/ahi.prefs", MODE_OLDFILE); if(iff->iff_Stream) { InitIFFasDOS(iff); if(!OpenIFF(iff,IFFF_READ)) { if(!(PropChunk(iff,ID_PREF,ID_PRHD) || PropChunk(iff,ID_PREF,ID_AHIG) || CollectionChunk(iff,ID_PREF,ID_AHIU) || StopOnExit(iff,ID_PREF,ID_FORM))) { if(ParseIFF(iff,IFFPARSE_SCAN) == IFFERR_EOC) { prhd=FindProp(iff,ID_PREF,ID_PRHD); ahig=FindProp(iff,ID_PREF,ID_AHIG); if(ahig) { struct AHIGlobalPrefs *globalprefs; UWORD debug_level; globalprefs = (struct AHIGlobalPrefs *)ahig->sp_Data; debug_level = globalprefs->ahigp_DebugLevel; EndianSwap( sizeof (UWORD), &debug_level ); AHIBase->ahib_DebugLevel = debug_level; AHIBase->ahib_Flags = 0; /* Not used in version 5: * * if(globalprefs->ahigp_DisableSurround) * AHIBase->ahib_Flags |= AHIBF_NOSURROUND; * * if(globalprefs->ahigp_DisableEcho) * AHIBase->ahib_Flags |= AHIBF_NOECHO; * * if(globalprefs->ahigp_FastEcho) * AHIBase->ahib_Flags |= AHIBF_FASTECHO; * */ if( (ULONG) ahig->sp_Size > offsetof( struct AHIGlobalPrefs, ahigp_MaxCPU) ) { AHIBase->ahib_MaxCPU = globalprefs->ahigp_MaxCPU; EndianSwap( sizeof (Fixed), &AHIBase->ahib_MaxCPU ); } else { AHIBase->ahib_MaxCPU = 0x10000 * 90 / 100; } /* In version 5: Clipping is always used * * if( (ULONG) ahig->sp_Size > offsetof( struct AHIGlobalPrefs, * ahigp_ClipMasterVolume) ) * { * if(globalprefs->ahigp_ClipMasterVolume) * AHIBase->ahib_Flags |= AHIBF_CLIPPING; * } */ if( (ULONG) ahig->sp_Size > offsetof( struct AHIGlobalPrefs, ahigp_AntiClickTime ) ) { AHIBase->ahib_AntiClickTime = globalprefs->ahigp_AntiClickTime; EndianSwap( sizeof (Fixed), &AHIBase->ahib_AntiClickTime ); } else { AHIBase->ahib_AntiClickTime = 0; } if( (ULONG) ahig->sp_Size > offsetof( struct AHIGlobalPrefs, ahigp_ScaleMode ) ) { AHIBase->ahib_ScaleMode = globalprefs->ahigp_ScaleMode; EndianSwap( sizeof (UWORD), &AHIBase->ahib_ScaleMode ); } else { AHIBase->ahib_ScaleMode = AHI_SCALE_FIXED_0_DB; } }
AJ_Status AJ_UnmarshalMsg(AJ_BusAttachment* bus, AJ_Message* msg, uint32_t timeout) { AJ_Status status; AJ_IOBuffer* ioBuf = &bus->sock.rx; uint8_t* endOfHeader; uint32_t hdrPad; /* * Clear message then set the bus */ memset(msg, 0, sizeof(AJ_Message)); msg->msgId = AJ_INVALID_MSG_ID; msg->bus = bus; /* * Move any unconsumed data to the start of the I/O buffer */ AJ_IOBufRebase(ioBuf); /* * Load the message header */ while (AJ_IO_BUF_AVAIL(ioBuf) < sizeof(AJ_MsgHeader)) { //#pragma calls = AJ_Net_Recv status = ioBuf->recv(ioBuf, sizeof(AJ_MsgHeader) - AJ_IO_BUF_AVAIL(ioBuf), timeout); if (status != AJ_OK) { /* * If there were no messages to receive check if we have any methods call that have * timed-out and if so generate an internal error message to allow the application to * proceed. */ if ((status == AJ_ERR_TIMEOUT) && AJ_TimedOutMethodCall(msg)) { msg->hdr = (AJ_MsgHeader*)&internalErrorHdr; msg->error = AJ_ErrTimeout; msg->sender = AJ_GetUniqueName(msg->bus); msg->destination = msg->sender; status = AJ_OK; } return status; } } /* * Header was unmarsalled directly into the rx buffer */ msg->hdr = (AJ_MsgHeader*)ioBuf->bufStart; ioBuf->readPtr += sizeof(AJ_MsgHeader); /* * Quick sanity check on the header - unrecoverable error if this check fails */ if ((msg->hdr->endianess != AJ_LITTLE_ENDIAN) && (msg->hdr->endianess != AJ_BIG_ENDIAN)) { return AJ_ERR_READ; } /* * Endian swap header info - conventiently they are contiguous in the header */ EndianSwap(msg, AJ_ARG_INT32, &msg->hdr->bodyLen, 3); msg->bodyBytes = msg->hdr->bodyLen; /* * The header is null padded to an 8 bytes boundary */ hdrPad = (8 - msg->hdr->headerLen) & 7; /* * Load the header */ status = LoadBytes(ioBuf, msg->hdr->headerLen + hdrPad, 0); if (status != AJ_OK) { return status; } #ifndef NDEBUG /* * Check that messages are getting closed */ AJ_ASSERT(!currentMsg); currentMsg = msg; #endif /* * Assume an empty signature */ msg->signature = ""; /* * We have the header in the buffer now we can unmarshal the header fields */ endOfHeader = ioBuf->bufStart + sizeof(AJ_MsgHeader) + msg->hdr->headerLen; while (ioBuf->readPtr < endOfHeader) { const char* fieldSig; uint8_t fieldId; AJ_Arg hdrVal; /* * Custom unmarshal the header field - signature is "(yv)" so starts off with STRUCT aligment. */ status = LoadBytes(ioBuf, 4, PadForType(AJ_ARG_STRUCT, ioBuf)); if (status != AJ_OK) { break; } fieldId = ioBuf->readPtr[0]; fieldSig = (const char*)&ioBuf->readPtr[2]; ioBuf->readPtr += 4; /* * Now unmarshal the field value */ status = Unmarshal(msg, &fieldSig, &hdrVal); if (status != AJ_OK) { break; } /* * Check the field has the type we expect - we ignore fields we don't know */ if ((fieldId <= AJ_HDR_SESSION_ID) && (TypeForHdr[fieldId] != hdrVal.typeId)) { status = AJ_ERR_UNMARSHAL; break; } /* * Set the field value in the message */ switch (fieldId) { case AJ_HDR_OBJ_PATH: msg->objPath = hdrVal.val.v_objPath; break; case AJ_HDR_INTERFACE: msg->iface = hdrVal.val.v_string; break; case AJ_HDR_MEMBER: msg->member = hdrVal.val.v_string; break; case AJ_HDR_ERROR_NAME: msg->error = hdrVal.val.v_string; break; case AJ_HDR_REPLY_SERIAL: msg->replySerial = *(hdrVal.val.v_uint32); break; case AJ_HDR_DESTINATION: msg->destination = hdrVal.val.v_string; break; case AJ_HDR_SENDER: msg->sender = hdrVal.val.v_string; break; case AJ_HDR_SIGNATURE: msg->signature = hdrVal.val.v_signature; break; case AJ_HDR_TIMESTAMP: msg->timestamp = *(hdrVal.val.v_uint32); break; case AJ_HDR_TIME_TO_LIVE: msg->ttl = *(hdrVal.val.v_uint32); break; case AJ_HDR_SESSION_ID: msg->sessionId = *(hdrVal.val.v_uint32); break; case AJ_HDR_HANDLES: case AJ_HDR_COMPRESSION_TOKEN: default: /* Ignored */ break; } } if (status == AJ_OK) { AJ_ASSERT(ioBuf->readPtr == endOfHeader); /* * Consume the header pad bytes. */ ioBuf->readPtr += hdrPad; /* * If the message is encrypted load the entire message body and decrypt it. */ if (msg->hdr->flags & AJ_FLAG_ENCRYPTED) { status = LoadBytes(ioBuf, msg->hdr->bodyLen, 0); if (status == AJ_OK) { status = DecryptMessage(msg); } } /* * Toggle the AUTO_START flag so in the API no flags == 0 * * Note we must do this after decrypting the message or message authentication will fail. */ msg->hdr->flags ^= AJ_FLAG_AUTO_START; /* * If the message looks good try to identify it. */ if (status == AJ_OK) { status = AJ_IdentifyMessage(msg); } } else { /* * Consume entire header */ ioBuf->readPtr = endOfHeader + hdrPad; } if (status == AJ_OK) { AJ_DumpMsg("RECEIVED", msg, FALSE); } else { /* * Silently discard message unless in debug mode */ AJ_ErrPrintf(("Discarding bad message %s\n", AJ_StatusText(status))); AJ_DumpMsg("DISCARDING", msg, FALSE); AJ_CloseMsg(msg); } return status; }
/* * Unmarshal a single argument */ static AJ_Status Unmarshal(AJ_Message* msg, const char** sig, AJ_Arg* arg) { AJ_Status status; AJ_IOBuffer* ioBuf = &msg->bus->sock.rx; char typeId; uint32_t pad; uint32_t sz; memset(arg, 0, sizeof(AJ_Arg)); if (!*sig || !**sig) { return AJ_ERR_END_OF_DATA; } typeId = **sig; *sig += 1; pad = PadForType(typeId, ioBuf); if (IsScalarType(typeId)) { sz = SizeOfType(typeId); status = LoadBytes(ioBuf, sz, pad); if (status != AJ_OK) { return status; } /* * For numeric types we just return a pointer into the buffer */ arg->typeId = typeId; arg->val.v_byte = ioBuf->readPtr; arg->len = 0; ioBuf->readPtr += sz; EndianSwap(msg, typeId, (void*)arg->val.v_data, 1); } else if (TYPE_FLAG(typeId) & (AJ_STRING | AJ_VARIANT)) { /* * Length field for a signature is 1 byte, for regular strings its 4 bytes */ uint32_t lenSize = ALIGNMENT(typeId); /* * Read the string length. Note the length doesn't include the terminating NUL * so an empty string in encoded as two zero bytes. */ status = LoadBytes(ioBuf, lenSize, pad); if (status != AJ_OK) { return status; } if (lenSize == 4) { EndianSwap(msg, AJ_ARG_UINT32, ioBuf->readPtr, 1); sz = *((uint32_t*)ioBuf->readPtr); } else { sz = (uint32_t)(*ioBuf->readPtr); } ioBuf->readPtr += lenSize; status = LoadBytes(ioBuf, sz + 1, 0); if (status != AJ_OK) { return status; } arg->typeId = typeId; arg->len = sz; arg->val.v_string = (char*)ioBuf->readPtr; ioBuf->readPtr += sz + 1; /* * If unmarshalling a variant store offset to start of signature */ if (typeId == AJ_ARG_VARIANT) { msg->varOffset = (uint8_t)(sz + 1); } } else if (typeId == AJ_ARG_ARRAY) { status = UnmarshalArray(msg, sig, arg, pad); } else if ((typeId == AJ_ARG_STRUCT) || (typeId == AJ_ARG_DICT_ENTRY)) { arg->typeId = typeId; status = UnmarshalStruct(msg, sig, arg, pad); } else { status = AJ_ERR_UNMARSHAL; } return status; }
enum Result CrocUnpack(const char *dirname, const char *fsname, const char *outputpath, const char *listname, enum ENDIAN endian) { FILE *fDir, *fArc, *fList, *fOut; if (!OpenFile(&fDir, dirname, OPENFILEREAD)) return FILENOTFOUND; if (!OpenFile(&fArc, fsname, OPENFILEREAD)) return FILENOTFOUND; size_t fSize = GetFileSize(fDir); if (fSize < 4 || EndianSwap(fSize) < 4) return FILECORRUPTED; unsigned int entries; fread(&entries, 1, sizeof(entries), fDir); if (endian == ENOTSET) { msgPrint(MsgLv_Warning, "Endian not specified.\n"); if (entries > 0x7FFFF) { msgPrint(MsgLv_Info, "Endian set to %s.\n", "BIG (Saturn ver.)"); endian = EBIG; } else { msgPrint(MsgLv_Info, "Endian set to %s.\n", "LITTLE (PS1 ver.)"); endian = ELITTLE; } } if (endian == EBIG) entries = EndianSwap(entries); size_t expectedSize = sizeof(struct CrocFsEntry) * entries + 8; if (fSize != expectedSize) { if (fSize != entries + 8) { msgPrint(MsgLv_Error, "%s seems to be corrupted."); return FILECORRUPTED; } else { msgPrint(MsgLv_Info, "Found Croc v0.12 format.\n"); entries /= sizeof(struct CrocFsEntry); msgPrint(MsgLv_Warning, "Format not yet supported. Extraction aborted.\n"); return FILECORRUPTED; } } if (!OpenFile(&fList, listname, OPENFILECREATE)) return FILENOTCREATED; char outpath[MAX_PATH]; char tmp[MAX_PATH]; tmp[0xC] = '\0'; _mkdir(outputpath); size_t fsLen = GetFileSize(fArc); for(unsigned int i = 0; i < entries; i++) { struct CrocFsEntry entry; fread(&entry, sizeof(struct CrocFsEntry), 1, fDir); memcpy(tmp, entry.name, 0xC); msgPrint(MsgLv_Message, "Unpacking %s\n", tmp); sprintf(outpath, "%s\\%s", outputpath, tmp); if (endian == EBIG) { entry.pos = EndianSwap(entry.pos); entry.size = EndianSwap(entry.size); } if (entry.pos + entry.size > fsLen) { msgPrint(MsgLv_Warning, "%s position exceed file system's length; it will not be extracted.\n", tmp); continue; } if (!OpenFile(&fOut, outpath, OPENFILECREATE)) return FILENOTCREATED; if (entry.size > 0x7FFFFF) msgPrint(MsgLv_Warning, "%s file size %iKB?\n", entry.size); fseek(fArc, entry.pos, SEEK_SET); FileCopy(fOut, fArc, entry.size); fclose(fOut); fprintf(fList, "%s\n", tmp); } fclose(fList); return NOERRORS; }