static inline bool
do_check64 (size_t i, const Elf64_auxv_t (*a64)[], uint_fast8_t *elfdata)
{
  /* The AUXV pointer might not even be naturally aligned for 64-bit
     data, because note payloads in a core file are not aligned.  */

  uint64_t type = read_8ubyte_unaligned_noncvt (&(*a64)[i].a_type);
  uint64_t val = read_8ubyte_unaligned_noncvt (&(*a64)[i].a_un.a_val);

  if (type == BE64 (PROBE_TYPE)
      && val == BE64 (PROBE_VAL64))
    {
      *elfdata = ELFDATA2MSB;
      return true;
    }

  if (type == LE64 (PROBE_TYPE)
      && val == LE64 (PROBE_VAL64))
    {
      *elfdata = ELFDATA2LSB;
      return true;
    }

  return false;
}
Exemplo n.º 2
0
void logResponseVerbose(const char *const ePID, const BYTE *const hwid, const RESPONSE *const response, const PRINTFUNC p)
{
	char guidBuffer[GUID_STRING_LENGTH + 1];
	//SYSTEMTIME st;

	p("Protocol version                : %u.%u\n", (uint32_t)LE16(response->MajorVer), (uint32_t)LE16(response->MinorVer));
	p("KMS host extended PID           : %s\n", ePID);
	if (LE16(response->MajorVer) > 5)
#	ifndef _WIN32
		p("KMS host Hardware ID            : %016llX\n", (unsigned long long)BE64(*(uint64_t*)hwid));
#	else // _WIN32
		p("KMS host Hardware ID            : %016I64X\n", (unsigned long long)BE64(*(uint64_t*)hwid));
#	endif // WIN32

	uuid2StringLE(&response->CMID, guidBuffer);
	p("Client machine ID               : %s\n", guidBuffer);

	char mbstr[64];
	time_t st;

	st = fileTimeToUnixTime(&response->ClientTime);
	strftime(mbstr, sizeof(mbstr), "%Y-%m-%d %X", gmtime(&st));
	p("Client request timestamp (UTC)  : %s\n", mbstr);

	p("KMS host current active clients : %u\n", (uint32_t)LE32(response->Count));
	p("Renewal interval policy         : %u\n", (uint32_t)LE32(response->VLRenewalInterval));
	p("Activation interval policy      : %u\n", (uint32_t)LE32(response->VLActivationInterval));
}
Exemplo n.º 3
0
/* Examine an auxv data block and determine its format.
   Return true iff we figured it out.  */
static bool
auxv_format_probe (const void *auxv, size_t size,
                   uint_fast8_t *elfclass, uint_fast8_t *elfdata)
{
    const union
    {
        char buf[size];
        Elf32_auxv_t a32[size / sizeof (Elf32_auxv_t)];
        Elf64_auxv_t a64[size / sizeof (Elf64_auxv_t)];
    } *u = auxv;

    inline bool check64 (size_t i)
    {
        /* The AUXV pointer might not even be naturally aligned for 64-bit
           data, because note payloads in a core file are not aligned.  */

        uint64_t type = read_8ubyte_unaligned_noncvt (&u->a64[i].a_type);
        uint64_t val = read_8ubyte_unaligned_noncvt (&u->a64[i].a_un.a_val);

        if (type == BE64 (PROBE_TYPE)
                && val == BE64 (PROBE_VAL64))
        {
            *elfdata = ELFDATA2MSB;
            return true;
        }

        if (type == LE64 (PROBE_TYPE)
                && val == LE64 (PROBE_VAL64))
        {
            *elfdata = ELFDATA2LSB;
            return true;
        }

        return false;
    }
Exemplo n.º 4
0
void DecryptBufferLRW64 (byte *buffer, uint64 length, uint64 blockIndex, PCRYPTO_INFO cryptoInfo)
{
	/* Deprecated/legacy */

	int cipher = EAGetFirstCipher (cryptoInfo->ea);
	unsigned __int8 *p = buffer;
	unsigned __int8 *ks = cryptoInfo->ks;
	unsigned __int8 i[8];
	unsigned __int8 t[8];
	unsigned __int64 b;

	*(unsigned __int64 *)i = BE64(blockIndex);

	if (length % 8)
		GST_THROW_FATAL_EXCEPTION;

	for (b = 0; b < length >> 3; b++)
	{
		Gf64MulTab (i, t, &cryptoInfo->gf_ctx);
		Xor64 ((unsigned __int64 *)p, (unsigned __int64 *)t);

		DecipherBlock (cipher, p, ks);

		Xor64 ((unsigned __int64 *)p, (unsigned __int64 *)t);

		p += 8;

		if (i[7] != 0xff)
			i[7]++;
		else
			*(unsigned __int64 *)i = BE64 ( BE64(*(unsigned __int64 *)i) + 1 );
	}

	FAST_ERASE64 (t, sizeof(t));
}
Exemplo n.º 5
0
void DecryptBufferLRW128 (byte *buffer, uint64 length, uint64 blockIndex, PCRYPTO_INFO cryptoInfo)
{
	/* Deprecated/legacy */

	int cipher = EAGetFirstCipher (cryptoInfo->ea);
	int cipherCount = EAGetCipherCount (cryptoInfo->ea);
	unsigned __int8 *p = buffer;
	unsigned __int8 *ks = cryptoInfo->ks;
	unsigned __int8 i[8];
	unsigned __int8 t[16];
	unsigned __int64 b;

	*(unsigned __int64 *)i = BE64(blockIndex);

	if (length % 16)
		GST_THROW_FATAL_EXCEPTION;

	// Note that the maximum supported volume size is 8589934592 GB  (i.e., 2^63 bytes).

	for (b = 0; b < length >> 4; b++)
	{
		Gf128MulBy64Tab (i, t, &cryptoInfo->gf_ctx);
		Xor128 ((unsigned __int64 *)p, (unsigned __int64 *)t);

		if (cipherCount > 1)
		{
			// Cipher cascade
			ks = cryptoInfo->ks + EAGetKeyScheduleSize (cryptoInfo->ea);

			for (cipher = EAGetLastCipher (cryptoInfo->ea);
				cipher != 0;
				cipher = EAGetPreviousCipher (cryptoInfo->ea, cipher))
			{
				ks -= CipherGetKeyScheduleSize (cipher);
				DecipherBlock (cipher, p, ks);
			}
		}
		else
		{
			DecipherBlock (cipher, p, ks);
		}

		Xor128 ((unsigned __int64 *)p, (unsigned __int64 *)t);

		p += 16;

		if (i[7] != 0xff)
			i[7]++;
		else
			*(unsigned __int64 *)i = BE64 ( BE64(*(unsigned __int64 *)i) + 1 );
	}

	FAST_ERASE64 (t, sizeof(t));
}
Exemplo n.º 6
0
int dme_read_unit_desc(struct ufs_dev *dev, uint8_t index)
{
	STACKBUF_DMA_ALIGN(unit_desc, sizeof(struct ufs_unit_desc));
	struct ufs_unit_desc           *desc = (struct ufs_unit_desc *) unit_desc;
	struct utp_query_req_upiu_type query = {UPIU_QUERY_OP_READ_DESCRIPTOR,
											UFS_DESC_IDN_UNIT,
											index,
											0,
											(addr_t) unit_desc,
											sizeof(struct ufs_unit_desc)};

	if (dme_send_query_upiu(dev, &query))
	{
		dprintf(CRITICAL, "%s:%d DME Read Unit Descriptor request failed\n", __func__, __LINE__);
		return -UFS_FAILURE;
	}
	/* Flush buffer. */
	arch_invalidate_cache_range((addr_t) desc, sizeof(struct ufs_unit_desc));

	dev->lun_cfg[index].logical_blk_cnt = BE64(desc->logical_blk_cnt);

	dev->lun_cfg[index].erase_blk_size = BE32(desc->erase_blk_size);

	// use only the lower 32 bits for rpmb partition size
	if (index == UFS_WLUN_RPMB)
		dev->rpmb_num_blocks = BE32(desc->logical_blk_cnt >> 32);

	return UFS_SUCCESS;
}
Exemplo n.º 7
0
UINT64_STRUCT GetHeaderField64 (byte *header, int offset)
{
	UINT64_STRUCT uint64Struct;

#ifndef TC_NO_COMPILER_INT64
	uint64Struct.Value = BE64 (*(uint64 *) (header + offset));
#else
	uint64Struct.HighPart = BE32 (*(uint32 *) (header + offset));
	uint64Struct.LowPart = BE32 (*(uint32 *) (header + offset + 4));
#endif
	return uint64Struct;
}
Exemplo n.º 8
0
/**
   Terminate the hash to get the digest
*/
void _stdcall sha512_done(sha512_ctx *ctx, unsigned char *out)
{
    int i;
    
	/* increase the length of the message */
    ctx->length += ctx->curlen * 8;

    /* append the '1' bit */
    ctx->buf[ctx->curlen++] = 0x80;

    /* if the length is currently above 112 bytes we append zeros
     * then compress.  Then we can fall back to padding zeros and length
     * encoding like normal.
     */
    if (ctx->curlen > 112) 
	{
		while (ctx->curlen < SHA512_BLOCK_SIZE) {
            ctx->buf[ctx->curlen++] = 0;
        }
        sha512_compress(ctx, ctx->buf);
        ctx->curlen = 0;
    }

    /* pad upto 120 bytes of zeroes 
     * note: that from 112 to 120 is the 64 MSB of the length.  We assume that you won't hash
     * > 2^64 bits of data... :-)
     */
    while (ctx->curlen < 120) {
        ctx->buf[ctx->curlen++] = 0;
    }

    /* store length */
	p64(ctx->buf)[15] = BE64(ctx->length);
    sha512_compress(ctx, ctx->buf);

    /* copy output */
    for (i = 0; i < 8; i++) {
		p64(out)[i] = BE64(ctx->hash[i]);
    }
}
Exemplo n.º 9
0
static int process_read_file_cmd(client_t *client, netiso_read_file_cmd *cmd)
{
	uint64_t offset;
	uint32_t remaining;
	int32_t bytes_read;
	netiso_read_file_result result;
	
	offset = BE64(cmd->offset);
	remaining = BE32(cmd->num_bytes);
	
	if (!client->ro_file)
	{
		bytes_read = -1;
		goto send_result;
	}
	
	if (remaining > BUFFER_SIZE)
	{
		bytes_read = -1;
		goto send_result;
	}
	
	if (client->ro_file->seek(offset, SEEK_SET) < 0)
	{
		bytes_read = -1;
		goto send_result;
	}
	
	bytes_read = client->ro_file->read(client->buf, remaining);
	if (bytes_read < 0)
	{
		bytes_read = -1;		
	}
		
send_result:

	result.bytes_read = (int32_t)BE32(bytes_read);

	if (send(client->s, (char *)&result, sizeof(result), 0) != 4)
	{
		DPRINTF("send failed on send result (read file)\n");
		return -1;
	}

	if (bytes_read > 0 && send(client->s, (char *)client->buf, bytes_read, 0) != bytes_read)
	{
		DPRINTF("send failed on read file!\n");
		return -1;
	}
	
	return 0;
}
Exemplo n.º 10
0
static int process_read_file_critical(client_t *client, netiso_read_file_critical_cmd *cmd)
{
	uint64_t offset;
	uint32_t remaining;
	
	offset = BE64(cmd->offset);
	remaining = BE32(cmd->num_bytes);
	
	if (!client->ro_file)
		return -1;
#ifdef WIN32	
	DPRINTF("Read %I64x %x\n", (long long unsigned int)offset, remaining);
#else
	DPRINTF("Read %llx %x\n", (long long unsigned int)offset, remaining);
#endif
	
	if (client->ro_file->seek(offset, SEEK_SET) < 0)
	{
		DPRINTF("seek_file failed!\n");
		return -1;
	}
	
	while (remaining > 0)
	{
		uint32_t read_size;
		
		if (remaining < BUFFER_SIZE)
		{
			read_size = remaining;
		}
		else
		{
			read_size = BUFFER_SIZE;
		}
		
		if (client->ro_file->read(client->buf, read_size) != read_size)
		{
			DPRINTF("read_file failed on read file critical command!\n");
			return -1;
		}
		
		if (send(client->s, (char *)client->buf, read_size, 0) != read_size)
		{
			DPRINTF("send failed on read file critical command!\n");
			return -1;
		}
		
		remaining -= read_size;
	}
	
	return 0;
}
Exemplo n.º 11
0
int ucs_do_scsi_unmap(struct ufs_dev *dev, struct scsi_unmap_req *req)
{
	STACKBUF_DMA_ALIGN(cdb_param, SCSI_CDB_PARAM_LEN);
	STACKBUF_DMA_ALIGN(param, sizeof(struct unmap_param_list));
	struct scsi_req_build_type req_upiu;
	struct unmap_param_list *param_list;
	struct unmap_blk_desc *blk_desc;

	param_list                    = (struct unmap_param_list *)param;
	param_list->data_len          = (sizeof(struct unmap_param_list) - 1) << 0x8; /* n-1 */

	param_list->blk_desc_data_len = sizeof(struct unmap_blk_desc) << 0x8;


	blk_desc = &(param_list->blk_desc);

	blk_desc->lba      = BE64(req->start_lba);
	blk_desc->num_blks = BE32(req->num_blocks);

	memset((void*)cdb_param, 0, SCSI_CDB_PARAM_LEN);
	cdb_param[0] = SCSI_CMD_UNMAP;
	cdb_param[1] = 0;                    /*ANCHOR = 0 for UFS*/
	cdb_param[6] = 0;                    /*Group No = 0*/
	cdb_param[7] = 0;                    /* Param list length is 1, we erase 1 contiguous blk*/
	cdb_param[8] = sizeof(struct unmap_param_list);
	cdb_param[9] = 0;

        /* Flush cdb to memory. */
	dsb();
	arch_invalidate_cache_range((addr_t) cdb_param, SCSI_CDB_PARAM_LEN);

	memset((void*)&req_upiu, 0 , sizeof(struct scsi_req_build_type));

	req_upiu.cdb                       = (addr_t) cdb_param;
	req_upiu.data_buffer_addr          = (addr_t) param;
	req_upiu.data_len                  = sizeof(struct unmap_param_list);
	req_upiu.flags                     = UPIU_FLAGS_WRITE;
	req_upiu.lun                       = req->lun;
	req_upiu.dd                        = UTRD_SYSTEM_TO_TARGET;

	if (ucs_do_scsi_cmd(dev, &req_upiu))
	{
		dprintf(CRITICAL, "Failed to send SCSI unmap command \n");
		return -UFS_FAILURE;
	}

	/* Flush buffer. */
	arch_invalidate_cache_range((addr_t) param, SCSI_INQUIRY_LEN);

	return UFS_SUCCESS;
}
Exemplo n.º 12
0
void uuid2StringLE(const GUID *const guid, char *const string)
{
	sprintf(string,
#		ifdef _WIN32
		"%08x-%04x-%04x-%04x-%012I64x",
#		else
		"%08x-%04x-%04x-%04x-%012llx",
#		endif
		(unsigned int)LE32(guid->Data1),
		(unsigned int)LE16(guid->Data2),
		(unsigned int)LE16(guid->Data3),
		(unsigned int)BE16(*(uint16_t*)guid->Data4),
		(unsigned long long)BE64(*(uint64_t*)(guid->Data4)) & 0xffffffffffffLL
	);
}
Exemplo n.º 13
0
static int process_get_dir_size_cmd(client_t *client, netiso_get_dir_size_cmd *cmd)
{
	netiso_get_dir_size_result result;
	char *dirpath;
	uint16_t dp_len;
	int ret;
		
	dp_len = BE16(cmd->dp_len);
	dirpath = (char *)malloc(dp_len+1);
	if (!dirpath)
	{
		DPRINTF("CRITICAL: memory allocation error\n");
		return -1;
	}
	
	dirpath[dp_len] = 0;
	ret = recv_all(client->s, (char *)dirpath, dp_len);
	if (ret != dp_len)
	{
		DPRINTF("recv failed, getting dirname for get_dir_size: %d %d\n", ret, get_network_error());
		free(dirpath);
		return -1;
	}
	
	dirpath = translate_path(dirpath, 1, 1, NULL);
	if (!dirpath)
	{
		DPRINTF("Path cannot be translated. Connection with this client will be aborted.\n");
		return -1;
	}
	
	DPRINTF("get_dir_size %s\n", dirpath);

	result.dir_size = BE64(calculate_directory_size(dirpath));	
	free(dirpath);
		
	ret = send(client->s, (char *)&result, sizeof(result), 0);
	if (ret != sizeof(result))
	{
		DPRINTF("get_dir_size, send result error: %d %d\n", ret, get_network_error());		
		return -1;
	}
	
	return 0;
}
Exemplo n.º 14
0
/* compress 1024-bits */
static void sha512_compress(sha512_ctx *ctx, const unsigned char *buf)
{
    u64 S[8], W[80], t0, t1;
    int i;

    /* copy state into S */
	memcpy(S, ctx->hash, sizeof(S));
	
    /* copy the state into 1024-bits into W[0..15] */
    for (i = 0; i < 16; i++) {
		W[i] = BE64(p64(buf)[i]);
    }

    /* fill W[16..79] */
    for (i = 16; i < 80; i++) {
        W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16];
    }

    /* Compress */
#define RND(a,b,c,d,e,f,g,h,i)                    \
     t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i];   \
     t1 = Sigma0(a) + Maj(a, b, c);                  \
     d += t0;                                        \
     h  = t0 + t1;

     for (i = 0; i < 80; i += 8) {
         RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],i+0);
         RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],i+1);
         RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],i+2);
         RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],i+3);
         RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],i+4);
         RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],i+5);
         RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],i+6);
         RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],i+7);
     }
	 ctx->hash[0] += S[0]; ctx->hash[1] += S[1]; 
	 ctx->hash[2] += S[2]; ctx->hash[3] += S[3]; 
	 ctx->hash[4] += S[4]; ctx->hash[5] += S[5];
	 ctx->hash[6] += S[6]; ctx->hash[7] += S[7];

	/* prevent leaks */
	burn(&S, sizeof(S));
	burn(&W, sizeof(W));
}
Exemplo n.º 15
0
/**
 * parse_vblk_part - parse a LDM database vblk partition record
 * @buffer:	vblk partition record loaded from the LDM database
 * @buf_size:	size of @buffer in bytes
 * @vb:		in memory vblk structure to return parsed information in
 *
 * This parses the LDM database vblk record of type VBLK_PART, i.e. a partition
 * record, supplied in @buffer and sets up the in memory vblk structure @vb
 * with the obtained information.
 *
 * Return 1 on success and -1 on error, in which case @vb is undefined.
 */
static int parse_vblk_part(const u8 *buffer, const int buf_size,
		struct vblk *vb)
{
	int err, rel_objid, rel_name, rel_size, rel_parent;

	if (0x34 >= buf_size)
		return -1;
	/* Calculate relative offsets. */
	rel_objid  = 1 + buffer[0x18];
	if (0x18 + rel_objid >= buf_size)
		return -1;
	rel_name   = 1 + buffer[0x18 + rel_objid] + rel_objid;
	if (0x34 + rel_name >= buf_size)
		return -1;
	rel_size   = 1 + buffer[0x34 + rel_name] + rel_name;
	if (0x34 + rel_size >= buf_size)
		return -1;
	rel_parent = 1 + buffer[0x34 + rel_size] + rel_size;
	if (0x34 + rel_parent >= buf_size)
		return -1;
	/* Setup @vb. */
	vb->vblk_type    = VBLK_PART;
	vb->obj_id       = get_vnum(buffer + 0x18, &err);
	if (err || 0x34 + rel_parent + buffer[0x34 + rel_parent] >= buf_size)
		return -1;
	vb->disk_id      = get_vnum(buffer + 0x34 + rel_parent, &err);
	if (err || 0x24 + rel_name + 8 > buf_size)
		return -1;
	vb->start_sector = BE64(buffer + 0x24 + rel_name);
	if (0x34 + rel_name + buffer[0x34 + rel_name] >= buf_size)
		return -1;
	vb->num_sectors  = get_vnum(buffer + 0x34 + rel_name, &err);
	if (err || 0x18 + rel_objid + buffer[0x18 + rel_objid] >= buf_size)
		return -1;
	err = get_vstr(buffer + 0x18 + rel_objid, vb->name, sizeof(vb->name));
	if (err == -1)
		return err;
	ldm_debug("Parsed Partition VBLK successfully.\n");
	return 1;
}
Exemplo n.º 16
0
static void Sha256Finish(Sha256Ctx *Ctx, BYTE *hash)
{
	unsigned int  i, b_len = Ctx->Len & 63;

	Ctx->Buffer[ b_len ] = 0x80;
	if ( b_len ^ 63 ) memset(Ctx->Buffer + b_len + 1, 0, b_len ^ 63);

	if ( b_len >= 56 )
	{
		Sha256ProcessBlock(Ctx, Ctx->Buffer);
		memset(Ctx->Buffer, 0, 56);
	}

	//PUT_UAA64BE(Ctx->Buffer, (unsigned long long)(Ctx->Len * 8), 7);
	((uint64_t*)Ctx->Buffer)[7] = BE64((uint64_t)Ctx->Len << 3);
	Sha256ProcessBlock(Ctx, Ctx->Buffer);

	for (i = 0; i < 8; i++)
		//PUT_UAA32BE(hash, Ctx->State[i], i);
		((DWORD*)hash)[i] = BE32(Ctx->State[i]);

}
Exemplo n.º 17
0
/* Examine an auxv data block and determine its format.
   Return true iff we figured it out.  */
static bool
auxv_format_probe (const void *auxv, size_t size,
		   uint_fast8_t *elfclass, uint_fast8_t *elfdata)
{
  const union
  {
    char buf[size];
    Elf32_auxv_t a32[size / sizeof (Elf32_auxv_t)];
    Elf64_auxv_t a64[size / sizeof (Elf64_auxv_t)];
  } *u = auxv;

  inline bool check64 (size_t i)
  {
    if (u->a64[i].a_type == BE64 (PROBE_TYPE)
	&& u->a64[i].a_un.a_val == BE64 (PROBE_VAL64))
      {
	*elfdata = ELFDATA2MSB;
	return true;
      }

    if (u->a64[i].a_type == LE64 (PROBE_TYPE)
	&& u->a64[i].a_un.a_val == LE64 (PROBE_VAL64))
      {
	*elfdata = ELFDATA2LSB;
	return true;
      }

    return false;
  }

  inline bool check32 (size_t i)
  {
    if (u->a32[i].a_type == BE32 (PROBE_TYPE)
	&& u->a32[i].a_un.a_val == BE32 (PROBE_VAL32))
      {
	*elfdata = ELFDATA2MSB;
	return true;
      }

    if (u->a32[i].a_type == LE32 (PROBE_TYPE)
	&& u->a32[i].a_un.a_val == LE32 (PROBE_VAL32))
      {
	*elfdata = ELFDATA2LSB;
	return true;
      }

    return false;
  }

  for (size_t i = 0; i < size / sizeof (Elf64_auxv_t); ++i)
    {
      if (check64 (i))
	{
	  *elfclass = ELFCLASS64;
	  return true;
	}

      if (check32 (i * 2) || check32 (i * 2 + 1))
	{
	  *elfclass = ELFCLASS32;
	  return true;
	}
    }

  return false;
}
Exemplo n.º 18
0
static int
report_r_debug (uint_fast8_t elfclass, uint_fast8_t elfdata,
		Dwfl *dwfl, GElf_Addr r_debug_vaddr,
		Dwfl_Memory_Callback *memory_callback,
		void *memory_callback_arg)
{
  /* Skip r_version, to aligned r_map field.  */
  GElf_Addr read_vaddr = r_debug_vaddr + addrsize (elfclass);

  void *buffer = NULL;
  size_t buffer_available = 0;
  inline int release_buffer (int result)
  {
    if (buffer != NULL)
      (void) (*memory_callback) (dwfl, -1, &buffer, &buffer_available, 0, 0,
				 memory_callback_arg);
    return result;
  }

  GElf_Addr addrs[4];
  inline bool read_addrs (GElf_Addr vaddr, size_t n)
  {
    size_t nb = n * addrsize (elfclass); /* Address words -> bytes to read.  */

    /* Read a new buffer if the old one doesn't cover these words.  */
    if (buffer == NULL
	|| vaddr < read_vaddr
	|| vaddr - read_vaddr + nb > buffer_available)
      {
	release_buffer (0);

	read_vaddr = vaddr;
	int segndx = INTUSE(dwfl_addrsegment) (dwfl, vaddr, NULL);
	if (unlikely (segndx < 0)
	    || unlikely (! (*memory_callback) (dwfl, segndx,
					       &buffer, &buffer_available,
					       vaddr, nb, memory_callback_arg)))
	  return true;
      }

    const union
    {
      Elf32_Addr a32[n];
      Elf64_Addr a64[n];
    } *in = vaddr - read_vaddr + buffer;

    if (elfclass == ELFCLASS32)
      {
	if (elfdata == ELFDATA2MSB)
	  for (size_t i = 0; i < n; ++i)
	    addrs[i] = BE32 (in->a32[i]);
	else
	  for (size_t i = 0; i < n; ++i)
	    addrs[i] = LE32 (in->a32[i]);
      }
    else
      {
	if (elfdata == ELFDATA2MSB)
	  for (size_t i = 0; i < n; ++i)
	    addrs[i] = BE64 (in->a64[i]);
	else
	  for (size_t i = 0; i < n; ++i)
	    addrs[i] = LE64 (in->a64[i]);
      }

    return false;
  }
Exemplo n.º 19
0
static int process_read_dir_entry_cmd(client_t *client, netiso_read_dir_entry_cmd *cmd, int version)
{
	netiso_read_dir_entry_result result_v1;
	netiso_read_dir_entry_result_v2 result_v2;
	file_stat_t st;
	struct dirent *entry;
	char *path;
	
	if (version == 1)
	{	
		memset(&result_v1, 0, sizeof(result_v1));
	}
	else
	{
		memset(&result_v2, 0, sizeof(result_v2));
	}
	
	if (!client->dir || !client->dirpath)
	{
		if (version == 1)
		{
			result_v1.file_size = BE64(-1);
		}
		else
		{
			result_v2.file_size = BE64(-1);
		}
		goto send_result;
	}
	
	while ((entry = readdir(client->dir)))
	{	
		if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0 && strlen(entry->d_name) <= 65535)
			break;		
	}
	
	if (!entry)
	{
		closedir(client->dir);
		free(client->dirpath);
		client->dir = NULL;
		client->dirpath = NULL;
		
		
		if (version == 1)
		{
			result_v1.file_size = BE64(-1);
		}
		else
		{
			result_v2.file_size = BE64(-1);
		}
		goto send_result;
	}
	
	path = (char *)malloc(strlen(client->dirpath)+strlen(entry->d_name)+2);
	sprintf(path, "%s/%s", client->dirpath, entry->d_name);
	
	if (stat_file(path, &st) < 0)
	{
		closedir(client->dir);
		free(client->dirpath);
		client->dir = NULL;
		client->dirpath = NULL;
		
		
		if (version == 1)
		{
			result_v1.file_size = BE64(-1);
		}
		else
		{
			result_v2.file_size = BE64(-1);
		}
		DPRINTF("Stat failed on read dir entry: %s\n", path);
		free(path);
		goto send_result;
	}
	
	free(path);
	
	if ((st.mode & S_IFDIR) == S_IFDIR)
	{
		if (version == 1)
		{
			result_v1.file_size = BE64(0);
			result_v1.is_directory = 1;
		}
		else
		{
			result_v2.file_size = BE64(0);
			result_v2.is_directory = 1;
		}
	}
	else
	{
		if (version == 1)
		{
			result_v1.file_size = BE64(st.file_size);
			result_v1.is_directory = 0;
		}
		else
		{
			result_v2.file_size = BE64(st.file_size);
			result_v2.is_directory = 0;
		}
	}
	
	if (version == 1)
	{
		result_v1.fn_len = BE16(strlen(entry->d_name));
	}
	else
	{
		result_v2.fn_len = BE16(strlen(entry->d_name));
		result_v2.atime = BE64(st.atime);
		result_v2.ctime = BE64(st.ctime);
		result_v2.mtime = BE64(st.mtime);		
	}
	
send_result:	

	if (version == 1)
	{
		if (send(client->s, (char *)&result_v1, sizeof(result_v1), 0) != sizeof(result_v1))
		{
			DPRINTF("send error on read dir entry (%d)\n", get_network_error());
			return -1;
		}
	}
	else
	{
		if (send(client->s, (char *)&result_v2, sizeof(result_v2), 0) != sizeof(result_v2))
		{
			DPRINTF("send error on read dir entry (%d)\n", get_network_error());
			return -1;
		}
	}
	
	if ((version == 1 && result_v1.file_size != BE64(-1)) || (version == 2 && result_v2.file_size != BE64(-1)))
	{
		if (send(client->s, (char *)entry->d_name, strlen(entry->d_name), 0) != strlen(entry->d_name))
		{
			DPRINTF("send file name error on read dir entry (%d)\n", get_network_error());
			return -1;			
		}		
	}
	
	return 0;
}
Exemplo n.º 20
0
static int process_open_cmd(client_t *client, netiso_open_cmd *cmd)
{
	file_stat_t st;
	netiso_open_result result;
	char *filepath;
	uint16_t fp_len;
	int ret, viso = VISO_NONE;

	result.file_size = BE64(-1);
	result.mtime = BE64(0);

	fp_len = BE16(cmd->fp_len);
	//DPRINTF("fp_len = %d\n", fp_len);
	filepath = (char *)malloc(fp_len+1);
	if(!filepath)
	{
		DPRINTF("CRITICAL: memory allocation error\n");
		return -1;
	}

	if(client->ro_file)
	{
		delete client->ro_file;
	}

	ret = recv_all(client->s, (void *)filepath, fp_len);

	filepath[fp_len] = 0;

	if(!strcmp(filepath, "/CLOSEFILE"))
	{
		free(filepath);
		return 0;
	}

	if(ret != fp_len)
	{
		DPRINTF("recv failed, getting filename for open: %d %d\n", ret, get_network_error());
		free(filepath);
		return -1;
	}

	filepath = translate_path(filepath, 1, &viso);
	if(!filepath)
	{
		DPRINTF("Path cannot be translated. Connection with this client will be aborted.\n");
		return -1;
	}

	if(viso == VISO_NONE)
	{
		client->ro_file = new File();
	}
	else
	{
		printf("building virtual iso...\n");
		client->ro_file = new VIsoFile((viso == VISO_PS3));
	}

	client->CD_SECTOR_SIZE = 2352;

	if(client->ro_file->open(filepath, O_RDONLY) < 0)
	{
		printf("open error on \"%s\" (viso=%d)\n", filepath + root_len, viso);
		delete client->ro_file;
		client->ro_file = NULL;
	}
	else
	{
		if(client->ro_file->fstat(&st) < 0)
		{
			DPRINTF("Error in fstat\n");
		}
		else
		{
			result.file_size = BE64(st.file_size);
			result.mtime = BE64(st.mtime);

			if(viso != VISO_NONE || BE64(st.file_size) > 0x400000UL) printf("open %s\n", filepath + root_len);

			// detect cd sector size (2MB - 848MB)
			if(IS_RANGE(st.file_size, 0x200000UL, 0x35000000UL))
			{
				char buffer[0x10] = ""; client->CD_SECTOR_SIZE = 0;

				client->ro_file->seek(0x8020UL, SEEK_SET); client->ro_file->read(buffer, 0xC); if(memcmp(buffer, "PLAYSTATION ", 0xC) == 0) client->CD_SECTOR_SIZE = 2048; else {
				client->ro_file->seek(0x9220UL, SEEK_SET); client->ro_file->read(buffer, 0xC); if(memcmp(buffer, "PLAYSTATION ", 0xC) == 0) client->CD_SECTOR_SIZE = 2336; else {
				client->ro_file->seek(0x9320UL, SEEK_SET); client->ro_file->read(buffer, 0xC); if(memcmp(buffer, "PLAYSTATION ", 0xC) == 0) client->CD_SECTOR_SIZE = 2352; else {
				client->ro_file->seek(0x9920UL, SEEK_SET); client->ro_file->read(buffer, 0xC); if(memcmp(buffer, "PLAYSTATION ", 0xC) == 0) client->CD_SECTOR_SIZE = 2448; }}}

				if(client->CD_SECTOR_SIZE > 0) printf("CD sector size: %i\n", client->CD_SECTOR_SIZE); else client->CD_SECTOR_SIZE = 2352;
			}
		}
	}

#ifdef WIN32
	DPRINTF("File size: %I64x\n", st.file_size);
#else
	DPRINTF("File size: %llx\n", (long long unsigned int)st.file_size);
#endif

	free(filepath);

	ret = send(client->s, (char *)&result, sizeof(result), 0);
	if(ret != sizeof(result))
	{
		DPRINTF("open, send result error: %d %d\n", ret, get_network_error());
		return -1;
	}

	return 0;
}
Exemplo n.º 21
0
static int process_stat_cmd(client_t *client, netiso_stat_cmd *cmd)
{
	netiso_stat_result result;
	file_stat_t st;
	char *filepath;
	uint16_t fp_len;
	int ret;
		
	fp_len = BE16(cmd->fp_len);
	//DPRINTF("fp_len = %d\n", fp_len);
	filepath = (char *)malloc(fp_len+1);
	if (!filepath)
	{
		DPRINTF("CRITICAL: memory allocation error\n");
		return -1;
	}
	
	filepath[fp_len] = 0;
	ret = recv_all(client->s, (char *)filepath, fp_len);
	if (ret != fp_len)
	{
		DPRINTF("recv failed, getting filename for stat: %d %d\n", ret, get_network_error());
		free(filepath);
		return -1;
	}
	
	filepath = translate_path(filepath, 1, 1, NULL);
	if (!filepath)
	{
		DPRINTF("Path cannot be translated. Connection with this client will be aborted.\n");
		return -1;
	}
	
	DPRINTF("stat %s\n", filepath);
	
	if (stat_file(filepath, &st) < 0)
	{
		DPRINTF("stat error on \"%s\"\n", filepath);
		result.file_size = BE64(-1);
	}
	else
	{
		if ((st.mode & S_IFDIR) == S_IFDIR)
		{
			result.file_size = BE64(0);
			result.is_directory = 1;
		}
		else
		{		
			result.file_size = BE64(st.file_size);
			result.is_directory = 0;
		}		
		
		result.mtime = BE64(st.mtime);
		result.ctime = BE64(st.ctime);
		result.atime = BE64(st.atime);	
	}
		
	free(filepath);
	
	ret = send(client->s, (char *)&result, sizeof(result), 0);
	if (ret != sizeof(result))
	{
		DPRINTF("stat, send result error: %d %d\n", ret, get_network_error());
		return -1;
	}
	
	return 0;
}
Exemplo n.º 22
0
static int process_read_dir_entry_cmd(client_t *client, netiso_read_dir_entry_cmd *cmd, int version)
{
	char *path;
	file_stat_t st;
	struct dirent *entry;
	size_t d_name_len = 0;
	netiso_read_dir_entry_result result_v1;
	netiso_read_dir_entry_result_v2 result_v2;

	if(version == 1)
	{
		memset(&result_v1, 0, sizeof(result_v1));
	}
	else
	{
		memset(&result_v2, 0, sizeof(result_v2));
	}

	if(!client->dir || !client->dirpath)
	{
		if(version == 1)
		{
			result_v1.file_size = BE64(-1);
		}
		else
		{
			result_v2.file_size = BE64(-1);
		}

		goto send_result_read_dir;
	}

	while ((entry = readdir(client->dir)))
	{
		if(IS_PARENT_DIR(entry->d_name)) continue;

		d_name_len = strlen(entry->d_name);

		if(IS_RANGE(d_name_len, 1, 65535)) break;
	}

	if(!entry)
	{
		closedir(client->dir);
		if(client->dirpath) free(client->dirpath);
		client->dir = NULL;
		client->dirpath = NULL;

		if(version == 1)
		{
			result_v1.file_size = BE64(-1);
		}
		else
		{
			result_v2.file_size = BE64(-1);
		}
		goto send_result_read_dir;
	}

	path = (char *)malloc(strlen(client->dirpath) + d_name_len + 2);
	if(!path)
	{
		DPRINTF("CRITICAL: memory allocation error\n");
		goto send_result_read_dir;
	}

	sprintf(path, "%s/%s", client->dirpath, entry->d_name);

	DPRINTF("Read dir entry: %s\n", path);
	if(stat_file(path, &st) < 0)
	{
		closedir(client->dir);
		if(client->dirpath) free(client->dirpath);
		client->dir = NULL;
		client->dirpath = NULL;


		if(version == 1)
		{
			result_v1.file_size = BE64(-1);
		}
		else
		{
			result_v2.file_size = BE64(-1);
		}

		DPRINTF("Stat failed on read dir entry: %s\n", path);
		goto send_result_read_dir;
	}

	if((st.mode & S_IFDIR) == S_IFDIR)
	{
		if(version == 1)
		{
			result_v1.file_size = BE64(0);
			result_v1.is_directory = 1;
		}
		else
		{
			result_v2.file_size = BE64(0);
			result_v2.is_directory = 1;
		}
	}
	else
	{
		if(version == 1)
		{
			result_v1.file_size = BE64(st.file_size);
			result_v1.is_directory = 0;
		}
		else
		{
			result_v2.file_size = BE64(st.file_size);
			result_v2.is_directory = 0;
		}
	}

	if(version == 1)
	{
		result_v1.fn_len = BE16(d_name_len);
	}
	else
	{
		result_v2.fn_len = BE16(d_name_len);
		result_v2.atime  = BE64(st.atime);
		result_v2.ctime  = BE64(st.ctime);
		result_v2.mtime  = BE64(st.mtime);
	}

send_result_read_dir:

	if(path) free(path);

	if(version == 1)
	{
		if(send(client->s, (char *)&result_v1, sizeof(result_v1), 0) != sizeof(result_v1))
		{
			DPRINTF("send error on read dir entry (%d)\n", get_network_error());
			return -1;
		}
	}
	else
	{
		if(send(client->s, (char *)&result_v2, sizeof(result_v2), 0) != sizeof(result_v2))
		{
			DPRINTF("send error on read dir entry (%d)\n", get_network_error());
			return -1;
		}
	}

	if((version == 1 && result_v1.file_size != BE64(-1)) || (version == 2 && result_v2.file_size != BE64(-1)))
	{
		if(send(client->s, (char *)entry->d_name, d_name_len, 0) != d_name_len)
		{
			DPRINTF("send file name error on read dir entry (%d)\n", get_network_error());
			return -1;
		}
	}

	return 0;
}
Exemplo n.º 23
0
static int process_open_cmd(client_t *client, netiso_open_cmd *cmd)
{
	file_stat_t st;
	netiso_open_result result;
	char *filepath;
	uint16_t fp_len;
	int ret, viso;
	int error = 0;
	
	fp_len = BE16(cmd->fp_len);
	//DPRINTF("fp_len = %d\n", fp_len);
	filepath = (char *)malloc(fp_len+1);
	if (!filepath)
	{
		DPRINTF("CRITICAL: memory allocation error\n");
		return -1;
	}
	
	filepath[fp_len] = 0;
	ret = recv_all(client->s, (void *)filepath, fp_len);
	if (ret != fp_len)
	{
		DPRINTF("recv failed, getting filename for open: %d %d\n", ret, get_network_error());
		free(filepath);
		return -1;
	}
	
	filepath = translate_path(filepath, 1, 1, &viso);
	if (!filepath)
	{
		DPRINTF("Path cannot be translated. Connection with this client will be aboreted.\n");
		return -1;
	}
	
	DPRINTF("open %s\n", filepath);
	
	if (client->ro_file)
	{
		delete client->ro_file;
	}
	
	if (viso == VISO_NONE)
	{
		client->ro_file = new File();
	}
	else 
	{
		client->ro_file = new VIsoFile((viso == VISO_PS3));
	}
	
	if (client->ro_file->open(filepath, O_RDONLY) < 0)
	{
		DPRINTF("open error on \"%s\" (viso=%d)\n", filepath, viso);
		error = 1;
		delete client->ro_file;
		client->ro_file = NULL;		
	}
	else
	{
		if (client->ro_file->fstat(&st) < 0)
		{
			DPRINTF("Error in fstat\n");
			error = 1;
		}
		else
		{
			result.file_size = BE64(st.file_size);
			result.mtime = BE64(st.mtime);
		}
	}
	
#ifdef WIN32
	DPRINTF("File size: %I64x\n", st.file_size);
#else
	DPRINTF("File size: %llx\n", (long long unsigned int)st.file_size);
#endif
		
	if (error)
	{
		result.file_size = BE64(-1);
		result.mtime = BE64(0);
	}
	
	free(filepath);
	
	ret = send(client->s, (char *)&result, sizeof(result), 0);
	if (ret != sizeof(result))
	{
		DPRINTF("open, send result error: %d %d\n", ret, get_network_error());
		return -1;
	}
	
	return 0;
}
Exemplo n.º 24
0
int main(int argc,char *argv[])
{
	if(argc<2) {
		printf("Usage: %s [elf path]\n",argv[0]);
		return 0;
	}

	int fd = open(argv[1],OFLAGS);
	if(fd<0) {
		fprintf(stderr,"Unable to open elf file: %s\n",argv[1]);
		return 1;
	}

	elf_version(EV_CURRENT);
	
	Elf *elf = elf_begin(fd,ELF_C_READ,NULL);
	if(!elf) {
		fprintf(stderr,"libelf could not read elf file: %s\n",elf_errmsg(elf_errno()));
		return 1;
	}

	Elf_Scn *prx = getSection(elf,".sys_proc_prx_param");
	if(!prx || memcmp(elf_getdata(prx,NULL)->d_buf,prx_magic,sizeof(prx_magic))) {
		fprintf(stderr,"elf does not have a prx parameter section.\n");
		return 1;
	}

	Elf_Scn *stubsection = getSection(elf,".lib.stub");
	Elf_Data *stubdata = elf_getdata(stubsection,NULL);
	Elf64_Shdr *stubshdr = elf64_getshdr(stubsection);
	Stub *stubbase = (Stub*)stubdata->d_buf;
	size_t stubcount = stubdata->d_size/sizeof(Stub);
	Elf_Scn *fnidsection = getSection(elf,".rodata.sceFNID");
	Elf64_Shdr *fnidshdr = elf64_getshdr(fnidsection);
	for(Stub *stub = stubbase;stub<stubbase + stubcount;stub++) {
		uint32_t fnid = BE32(stub->fnid);
		uint32_t end = fnidshdr->sh_addr + fnidshdr->sh_size;
		for(Stub *substub = stubbase;substub<(stubbase + stubcount);substub++) {
			if(stub==substub) continue;

			uint32_t newfnid = BE32(substub->fnid);
			if(newfnid>=fnid && newfnid<end) end = newfnid;
		}

		uint16_t fnidcount = (end - fnid)/4;
		if(BE16(stub->imports)!=fnidcount) {
			lseek(fd,stubshdr->sh_offset + (stub - stubbase)*sizeof(Stub)+offsetof(Stub,imports),SEEK_SET);
			fnidcount = BE16(fnidcount);
			if(write(fd,&fnidcount,sizeof(fnidcount))!=sizeof(fnidcount)) {
				printf("Error occurred during write in %s:%d\n",__FILE__,__LINE__);
			}
		}
	}

	Elf_Scn *opdsection = getSection(elf,".opd");
	Elf_Data *opddata = elf_getdata(opdsection,NULL);
	Elf64_Shdr *opdshdr = elf64_getshdr(opdsection);

	Opd64 *opdbase = (Opd64*)opddata->d_buf;
	size_t opdcount = opddata->d_size/sizeof(Opd64);
	for(Opd64 *opd = opdbase;opd<(opdbase + opdcount);opd++) {
		opd->data = BE64(((BE64(opd->func)<<32ULL) | (BE64(opd->rtoc)&0xffffffffULL)));
		lseek(fd,opdshdr->sh_offset + (opd - opdbase)*sizeof(Opd64),SEEK_SET);
		if(write(fd,opd,sizeof(Opd64))!=sizeof(Opd64)) {
			printf("Error occurred during write in %s:%d\n",__FILE__,__LINE__);
		}
	}

	elf_end(elf);
	close(fd);

	return 0;
}
Exemplo n.º 25
0
static int process_read_dir_cmd(client_t *client, netiso_read_dir_entry_cmd *cmd)
{
	(void) cmd;
	int64_t dir_size = 0;

	netiso_read_dir_result result;
	memset(&result, 0, sizeof(result));

	netiso_read_dir_result_data *dir_entries = (netiso_read_dir_result_data *) malloc(sizeof(netiso_read_dir_result_data) * MAX_ENTRIES);
	memset(dir_entries, 0, sizeof(netiso_read_dir_result_data) * MAX_ENTRIES);

	if(!client->dir || !client->dirpath || !dir_entries)
	{
		result.dir_size = (0);
		goto send_result_read_dir_cmd;
	}

	size_t d_name_len, dirpath_len;
	dirpath_len = strlen(client->dirpath);

	file_stat_t st;
	struct dirent *entry;

	while ((entry = readdir(client->dir)))
	{
		if(!entry) break;
		if(IS_PARENT_DIR(entry->d_name)) continue;

		d_name_len = strlen(entry->d_name);

		if(IS_RANGE(d_name_len, 1, MAX_PATH_LEN))
		{
			char *path = (char*)malloc(dirpath_len + d_name_len + 2);

			if(!path) break;

			sprintf(path, "%s/%s", client->dirpath, entry->d_name);

			st.file_size = 0;
			st.mode = S_IFDIR;
			st.mtime = 0;
			st.atime = 0;
			st.ctime = 0;

			stat_file(path, &st);

			if(!st.mtime) st.mtime = st.ctime;
			if(!st.mtime) st.mtime = st.atime;

			if((st.mode & S_IFDIR) == S_IFDIR)
			{
				dir_entries[dir_size].file_size = (0);
				dir_entries[dir_size].is_directory = 1;
			}
			else
			{
				dir_entries[dir_size].file_size =  BE64(st.file_size);
				dir_entries[dir_size].is_directory = 0;
			}

			snprintf(dir_entries[dir_size].name, MAX_PATH_LEN, "%s", entry->d_name);
			dir_entries[dir_size].mtime = BE64(st.mtime);

			free(path);
			dir_size++;
			if(dir_size >= MAX_ENTRIES) break;
		}
	}

#ifdef WIN32
	#ifdef MERGE_DRIVES
	if(root_len > 2 && dirpath_len > (root_len + 1) && strncmp(client->dirpath, root_directory, root_len) == 0)
	{
		memmove(client->dirpath + 2, client->dirpath + root_len, strlen(client->dirpath + root_len) + 1);

		client->dirpath[1] = ':';

		dirpath_len = strlen(client->dirpath);

		if(client->dir) {closedir(client->dir); client->dir = NULL;}

		for(int drive = 'C'; drive <= 'Z'; drive++)
		{
			if(dir_size >= MAX_ENTRIES) break;

			if(ignore_drives)
			{
				bool ignore = false;

				for(uint8_t d = 0; d < ignore_drives_len; d++)
					if((ignore_drives[d]  & 0xFF) == drive) {ignore = true; break;}

				if(ignore) continue;
			}

			client->dirpath[0] = drive;

			if(stat_file(client->dirpath, &st) < 0) continue;
			client->dir = opendir(client->dirpath);

			while ((entry = readdir(client->dir)))
			{
				if(!entry) break;
				if(IS_PARENT_DIR(entry->d_name)) continue;

				d_name_len = entry->d_namlen; //strlen(entry->d_name);

				if(IS_RANGE(d_name_len, 1, MAX_PATH_LEN))
				{
					char *path = (char*)malloc(dirpath_len + d_name_len + 2);

					if(path) break;

					sprintf(path, "%s/%s", client->dirpath, entry->d_name);
					st.file_size = 0;
					st.mode = S_IFDIR;
					st.mtime = 0;
					st.atime = 0;
					st.ctime = 0;
					stat_file(path, &st);

					if(!st.mtime) st.mtime = st.ctime;
					if(!st.mtime) st.mtime = st.atime;

					if((st.mode & S_IFDIR) == S_IFDIR)
					{
						dir_entries[dir_size].file_size = (0);
						dir_entries[dir_size].is_directory = 1;
					}
					else
					{
						dir_entries[dir_size].file_size =  BE64(st.file_size);
						dir_entries[dir_size].is_directory = 0;
					}

					snprintf(dir_entries[dir_size].name, MAX_PATH_LEN, "%s", entry->d_name);
					dir_entries[dir_size].mtime = BE64(st.mtime);

					free(path);
					dir_size++;
					if(dir_size >= MAX_ENTRIES) break;
				}
			}
		}
	}
	#endif
#endif

	if(client->dir) {closedir(client->dir); client->dir = NULL;}

send_result_read_dir_cmd:

	result.dir_size = BE64(dir_size);
	if(send(client->s, (const char*)&result, sizeof(result), 0) != sizeof(result))
	{
		if(dir_entries) free(dir_entries);
		return -1;
	}

	if(dir_size > 0)
	{
		if(send(client->s, (const char*)dir_entries, (sizeof(netiso_read_dir_result_data)*dir_size), 0) != (int)(sizeof(netiso_read_dir_result_data)*dir_size))
		{
			if(dir_entries) free(dir_entries);
			return -1;
		}
	}

	if(dir_entries) free(dir_entries);
	return 0;
}