Esempio n. 1
0
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;
}
Esempio n. 2
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;
	}*/
}
Esempio n. 3
0
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;
}
Esempio n. 4
0
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;
}
Esempio n. 5
0
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;
                            }
                        }
Esempio n. 6
0
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;
}
Esempio n. 7
0
/*
 * 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;
}
Esempio n. 8
0
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;
}