Esempio n. 1
0
status_t
GetBitmap(BPositionIO* in, BBitmap** out)
{
    TranslatorBitmap header;
    status_t result = in->Read(&header, sizeof(header));
    if (result != sizeof(header))
        return B_IO_ERROR;

    header.magic = B_BENDIAN_TO_HOST_INT32(header.magic);
    header.bounds.left = B_BENDIAN_TO_HOST_FLOAT(header.bounds.left);
    header.bounds.top = B_BENDIAN_TO_HOST_FLOAT(header.bounds.top);
    header.bounds.right = B_BENDIAN_TO_HOST_FLOAT(header.bounds.right);
    header.bounds.bottom = B_BENDIAN_TO_HOST_FLOAT(header.bounds.bottom);
    header.rowBytes = B_BENDIAN_TO_HOST_INT32(header.rowBytes);
    header.colors = (color_space)B_BENDIAN_TO_HOST_INT32(header.colors);
    header.dataSize = B_BENDIAN_TO_HOST_INT32(header.dataSize);

    // dump data from stream into a BBitmap
    *out = new(std::nothrow) BBitmap(header.bounds, header.colors);
    if (*out == NULL)
        return B_NO_MEMORY;

    if (!(*out)->IsValid()) {
        delete *out;
        return B_NO_MEMORY;
    }

    result = in->Read((*out)->Bits(), header.dataSize);
    if (result != (status_t)header.dataSize) {
        delete *out;
        return B_IO_ERROR;
    }

    return B_OK;
}
/* Dump data from stream into a BBitmap */
status_t
GetBitmap(BPositionIO *in, BBitmap **out)
{
	TranslatorBitmap header;

	status_t err = in->Read(&header, sizeof(header));
	if (err != sizeof(header))
		return B_IO_ERROR;

	header.magic = B_BENDIAN_TO_HOST_INT32(header.magic);
	header.bounds.left = B_BENDIAN_TO_HOST_FLOAT(header.bounds.left);
	header.bounds.top = B_BENDIAN_TO_HOST_FLOAT(header.bounds.top);
	header.bounds.right = B_BENDIAN_TO_HOST_FLOAT(header.bounds.right);
	header.bounds.bottom = B_BENDIAN_TO_HOST_FLOAT(header.bounds.bottom);
	header.rowBytes = B_BENDIAN_TO_HOST_INT32(header.rowBytes);
	header.colors = (color_space)B_BENDIAN_TO_HOST_INT32(header.colors);
	header.dataSize = B_BENDIAN_TO_HOST_INT32(header.dataSize);

	BBitmap *bitmap = new BBitmap(header.bounds, header.colors);
	*out = bitmap;
	if (bitmap == NULL) return B_NO_MEMORY;
	unsigned char *bits = (unsigned char *)bitmap->Bits();
	if (bits == NULL) {
		delete bitmap;
		return B_NO_MEMORY;
	}
	err = in->Read(bits, header.dataSize);
	if (err == (status_t)header.dataSize) return B_OK;
	else {
		delete bitmap;
		return B_IO_ERROR;
	}
}
Esempio n. 3
0
status_t
BKeymap::SetTo(BDataIO& stream)
{
	if (stream.Read(&fKeys, sizeof(fKeys)) < 1)
		return B_IO_ERROR;

	// convert from big-endian
	for (uint32 i = 0; i < sizeof(fKeys) / 4; i++) {
		((uint32*)&fKeys)[i] = B_BENDIAN_TO_HOST_INT32(((uint32*)&fKeys)[i]);
	}

	if (fKeys.version != 3)
		return B_BAD_DATA;

	if (stream.Read(&fCharsSize, sizeof(uint32)) < 1)
		return B_IO_ERROR;

	fCharsSize = B_BENDIAN_TO_HOST_INT32(fCharsSize);
	if (fCharsSize > 16 * 1024) {
		Unset();
		return B_BAD_DATA;
	}

	delete[] fChars;
	fChars = new char[fCharsSize];

	if (stream.Read(fChars, fCharsSize) != (ssize_t)fCharsSize) {
		Unset();
		return B_IO_ERROR;
	}

	return B_OK;
}
Esempio n. 4
0
void
AHCIPort::ScsiUnmap(scsi_ccb* request, scsi_unmap_parameter_list* unmapBlocks)
{
	// Determine how many ranges we'll need
	// We assume that the SCSI unmap ranges cannot be merged together
	uint32 scsiRangeCount = B_BENDIAN_TO_HOST_INT16(
		unmapBlocks->block_data_length) / sizeof(scsi_unmap_block_descriptor);
	uint32 lbaRangeCount = 0;
	for (uint32 i = 0; i < scsiRangeCount; i++) {
		lbaRangeCount += ((uint32)B_BENDIAN_TO_HOST_INT32(
			unmapBlocks->blocks[i].block_count) + 65534) / 65535;
	}

	uint32 lbaRangesSize = lbaRangeCount * sizeof(uint64);
	uint64* lbaRanges = (uint64*)malloc(lbaRangesSize);
	if (lbaRanges == NULL) {
		TRACE("out of memory when allocating %" B_PRIu32 " unmap ranges\n",
			lbaRangeCount);
		request->subsys_status = SCSI_REQ_ABORTED;
		gSCSI->finished(request, 1);
		return;
	}

	MemoryDeleter deleter(lbaRanges);

	for (uint32 i = 0, scsiIndex = 0; scsiIndex < scsiRangeCount; scsiIndex++) {
		uint64 lba = (uint64)B_BENDIAN_TO_HOST_INT64(
			unmapBlocks->blocks[scsiIndex].lba);
		uint64 blocksLeft = (uint32)B_BENDIAN_TO_HOST_INT32(
			unmapBlocks->blocks[scsiIndex].block_count);
		while (blocksLeft > 0) {
			uint16 blocks = blocksLeft > 65535 ? 65535 : (uint16)blocksLeft;
			lbaRanges[i++] = B_HOST_TO_LENDIAN_INT64(
				((uint64)blocks << 48) | lba);
			lba += blocks;
			blocksLeft -= blocks;
		}
	}

	sata_request sreq;
	sreq.SetATA48Command(ATA_COMMAND_DATA_SET_MANAGEMENT, 0,
		(lbaRangesSize + 511) / 512);
	sreq.SetFeature(1);
	sreq.SetData(lbaRanges, lbaRangesSize);

	ExecuteSataRequest(&sreq);
	sreq.WaitForCompletion();

	if ((sreq.CompletionStatus() & ATA_ERR) != 0) {
		TRACE("trim failed (%" B_PRIu32 " ranges)!\n", lbaRangeCount);
		request->subsys_status = SCSI_REQ_CMP_ERR;
	} else
		request->subsys_status = SCSI_REQ_CMP;

	request->data_resid = 0;
	request->device_status = SCSI_STATUS_GOOD;
	gSCSI->finished(request, 1);
}
Esempio n. 5
0
status_t
IMAPFolder::Init()
{
	// Initialize from folder attributes
	BNode node(&fRef);
	status_t status = node.InitCheck();
	if (status != B_OK)
		return status;

	node_ref nodeRef;
	status = node.GetNodeRef(&nodeRef);
	if (status != B_OK)
		return status;

	fNodeID = nodeRef.node;

	BString originalMailboxName;
	if (node.ReadAttrString(kMailboxNameAttribute, &originalMailboxName) == B_OK
		&& originalMailboxName != fMailboxName) {
		// TODO: mailbox name has changed
	}

	fUIDValidity = _ReadUInt32(node, kUIDValidityAttribute);
	fLastUID = _ReadUInt32(node, kLastUIDAttribute);
	printf("IMAP: %s, last UID %" B_PRIu32 "\n", fMailboxName.String(),
		fLastUID);

	attr_info info;
	status = node.GetAttrInfo(kStateAttribute, &info);
	if (status == B_OK) {
		struct entry {
			uint32	uid;
			uint32	flags;
		} _PACKED;
		struct entry* entries = (struct entry*)malloc(info.size);
		if (entries == NULL)
			return B_NO_MEMORY;

		ssize_t bytesRead = node.ReadAttr(kStateAttribute, B_RAW_TYPE, 0,
			entries, info.size);
		if (bytesRead != info.size)
			return B_BAD_DATA;

		for (size_t i = 0; i < info.size / sizeof(entry); i++) {
			uint32 uid = B_BENDIAN_TO_HOST_INT32(entries[i].uid);
			uint32 flags = B_BENDIAN_TO_HOST_INT32(entries[i].flags);

			fFlagsMap.insert(std::make_pair(uid, flags));
		}
	}

	return B_OK;
}
/* Look at first few bytes in stream to determine type - throw it back
   if it is not a GIF or a BBitmap that we understand */
bool
DetermineType(BPositionIO *source, bool *is_gif)
{
	unsigned char header[7];
	*is_gif = true;
	if (source->Read(header, 6) != 6) return false;
	header[6] = 0x00;

	if (strcmp((char *)header, "GIF87a") != 0 && strcmp((char *)header, 
		"GIF89a") != 0) {
		*is_gif = false;
		int32 magic = (header[0] << 24) + (header[1] << 16) + (header[2] << 8) 
			+ header[3];
		if (magic != B_TRANSLATOR_BITMAP) return false;
		source->Seek(5 * 4 - 2, SEEK_CUR);
		color_space cs;
		if (source->Read(&cs, 4) != 4) return false;
		cs = (color_space)B_BENDIAN_TO_HOST_INT32(cs);
		if (cs != B_RGB32 && cs != B_RGBA32 && cs != B_RGB32_BIG && cs 
			!= B_RGBA32_BIG) return false;
	}

	source->Seek(0, SEEK_SET);
	return true;
}
Esempio n. 7
0
// --------------------------------------------------
static uint32 ttf_get_uint32(FILE *ttf)
{
    uint32 buf;

    if (fread(&buf, 1, 4, ttf) != 4)
		return 0;

	return B_BENDIAN_TO_HOST_INT32(buf);
}
Esempio n. 8
0
//!	We save a map to a file
status_t
Keymap::Save(const entry_ref& ref)
{
	BFile file;
	status_t status = file.SetTo(&ref,
		B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE);
	if (status != B_OK) {
		printf("error %s\n", strerror(status));
		return status;
	}

	for (uint32 i = 0; i < sizeof(fKeys) / 4; i++)
		((uint32*)&fKeys)[i] = B_HOST_TO_BENDIAN_INT32(((uint32*)&fKeys)[i]);

	ssize_t bytesWritten = file.Write(&fKeys, sizeof(fKeys));
	if (bytesWritten < (ssize_t)sizeof(fKeys))
		status = bytesWritten < 0 ? bytesWritten : B_IO_ERROR;

	for (uint32 i = 0; i < sizeof(fKeys) / 4; i++)
		((uint32*)&fKeys)[i] = B_BENDIAN_TO_HOST_INT32(((uint32*)&fKeys)[i]);

	if (status == B_OK) {
		fCharsSize = B_HOST_TO_BENDIAN_INT32(fCharsSize);

		bytesWritten = file.Write(&fCharsSize, sizeof(uint32));
		if (bytesWritten < (ssize_t)sizeof(uint32))
			status = bytesWritten < 0 ? bytesWritten : B_IO_ERROR;

		fCharsSize = B_BENDIAN_TO_HOST_INT32(fCharsSize);
	}

	if (status == B_OK) {
		bytesWritten = file.Write(fChars, fCharsSize);
		if (bytesWritten < (ssize_t)fCharsSize)
			status = bytesWritten < 0 ? bytesWritten : B_IO_ERROR;
	}

	if (status == B_OK) {
		file.WriteAttr("keymap:name", B_STRING_TYPE, 0, fName, strlen(fName));
			// Failing would be non-fatal
	}

	return status;
}
Esempio n. 9
0
status_t
BRawNetBuffer::ReadUint32(uint32& value)
{
	uint32 netVal;
	ssize_t sizeW = fBuffer.ReadAt(fReadPosition, &netVal, sizeof(uint32));
	if (sizeW == 0)
		return B_ERROR;
	value= B_BENDIAN_TO_HOST_INT32(netVal);
	fReadPosition += sizeof(uint32);
	return B_OK;
}
Esempio n. 10
0
status_t
BNetBuffer::RemoveUint32(uint32& data)
{
	uint32 be_data;
	status_t result = RemoveData((void*)&be_data, sizeof(uint32));
	if (result != B_OK)
		return result;

	data = B_BENDIAN_TO_HOST_INT32(be_data);

	return B_OK;
}
Esempio n. 11
0
status_t
PackageReaderImpl::Init(int fd, bool keepFD, uint32 flags)
{
	hpkg_header header;
	status_t error = inherited::Init<hpkg_header, B_HPKG_MAGIC, B_HPKG_VERSION,
		B_HPKG_MINOR_VERSION>(fd, keepFD, header, flags);
	if (error != B_OK)
		return error;
	fHeapSize = UncompressedHeapSize();

	// init package attributes section
	error = InitSection(fPackageAttributesSection, fHeapSize,
		B_BENDIAN_TO_HOST_INT32(header.attributes_length),
		kMaxPackageAttributesSize,
		B_BENDIAN_TO_HOST_INT32(header.attributes_strings_length),
		B_BENDIAN_TO_HOST_INT32(header.attributes_strings_count));
	if (error != B_OK)
		return error;

	// init TOC section
	error = InitSection(fTOCSection, fPackageAttributesSection.offset,
		B_BENDIAN_TO_HOST_INT64(header.toc_length), kMaxTOCSize,
		B_BENDIAN_TO_HOST_INT64(header.toc_strings_length),
		B_BENDIAN_TO_HOST_INT64(header.toc_strings_count));
	if (error != B_OK)
		return error;

	// prepare the sections for use
	error = PrepareSection(fTOCSection);
	if (error != B_OK)
		return error;

	error = PrepareSection(fPackageAttributesSection);
	if (error != B_OK)
		return error;

	return B_OK;
}
Esempio n. 12
0
//------------------------------------------------------------------------------
void BMessageField::PrintToStream(const char* name) const
{
	int32 type = B_BENDIAN_TO_HOST_INT32(Type());
	printf("    entry %14s, type='%.4s', c=%2ld, ",
		   name, (char*)&type, CountItems());

	for (int32 i = 0; i < CountItems(); ++i)
	{
		if (i)
		{
			printf("                                            ");
		}
		PrintDataItem(i);
	}
}
Esempio n. 13
0
// ---------------------------------------------------------------
// translate_from_bits_to_bits
//
// Convert the data in inSource from the Be Bitmap format ('bits')
// to the format specified in outType (either bits or Base).
//
// Preconditions:
//
// Parameters:	inSource,	the bits data to translate
//
// 				amtread,	the amount of data already read from
//							inSource
//
//				read,		pointer to the data already read from
//							inSource
//
//				outType,	the type of data to convert to
//
//				outDestination,	where the output is written to
//
// Postconditions:
//
// Returns: B_NO_TRANSLATOR,	if the data is not in a supported
//								format
//
// B_ERROR, if there was an error allocating memory or some other
//			error
//
// B_OK, if successfully translated the data from the bits format
// ---------------------------------------------------------------
status_t
BaseTranslator::translate_from_bits_to_bits(BPositionIO *inSource,
	uint32 outType,	BPositionIO *outDestination)
{
	TranslatorBitmap bitsHeader;
	bool bheaderonly = false, bdataonly = false;
		
	status_t result;
	result = identify_bits_header(inSource, NULL, &bitsHeader);
	if (result != B_OK)
		return result;
	
	// Translate B_TRANSLATOR_BITMAP to B_TRANSLATOR_BITMAP, easy enough :)	
	if (outType == B_TRANSLATOR_BITMAP) {
		// write out bitsHeader (only if configured to)
		if (bheaderonly || (!bheaderonly && !bdataonly)) {
			if (swap_data(B_UINT32_TYPE, &bitsHeader,
				sizeof(TranslatorBitmap), B_SWAP_HOST_TO_BENDIAN) != B_OK)
				return B_ERROR;
			if (outDestination->Write(&bitsHeader,
				sizeof(TranslatorBitmap)) != sizeof(TranslatorBitmap))
				return B_ERROR;
		}
		
		// write out the data (only if configured to)
		if (bdataonly || (!bheaderonly && !bdataonly)) {	
			uint8 buf[1024];
			uint32 remaining = B_BENDIAN_TO_HOST_INT32(bitsHeader.dataSize);
			ssize_t rd, writ;
			rd = inSource->Read(buf, 1024);
			while (rd > 0) {
				writ = outDestination->Write(buf, rd);
				if (writ < 0)
					break;
				remaining -= static_cast<uint32>(writ);
				rd = inSource->Read(buf, min(1024, remaining));
			}
		
			if (remaining > 0)
				return B_ERROR;
			else
				return B_OK;
		} else
			return B_OK;

	} else
		return B_NO_TRANSLATOR;
}
Esempio n. 14
0
//! Save a binary keymap to a file.
status_t
Keymap::Save(const char* name)
{
	BFile file;
	status_t status = file.SetTo(name,
		B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE);
	if (status != B_OK)
		return status;

	// convert to big endian
	for (uint32 i = 0; i < sizeof(fKeys) / sizeof(uint32); i++) {
		((uint32*)&fKeys)[i] = B_HOST_TO_BENDIAN_INT32(((uint32*)&fKeys)[i]);
	}

	ssize_t bytesWritten = file.Write(&fKeys, sizeof(fKeys));

	// convert endian back
	for (uint32 i = 0; i < sizeof(fKeys) / sizeof(uint32); i++) {
		((uint32*)&fKeys)[i] = B_BENDIAN_TO_HOST_INT32(((uint32*)&fKeys)[i]);
	}

	if (bytesWritten < (ssize_t)sizeof(fKeys))
		return B_ERROR;
	if (bytesWritten < B_OK)
		return bytesWritten;

	uint32 charSize = B_HOST_TO_BENDIAN_INT32(fCharsSize);

	bytesWritten = file.Write(&charSize, sizeof(uint32));
	if (bytesWritten < (ssize_t)sizeof(uint32))
		return B_ERROR;
	if (bytesWritten < B_OK)
		return bytesWritten;

	bytesWritten = file.Write(fChars, fCharsSize);
	if (bytesWritten < (ssize_t)fCharsSize)
		return B_ERROR;
	if (bytesWritten < B_OK)
		return bytesWritten;

	return B_OK;
}
Esempio n. 15
0
void
AHCIPort::ScsiExecuteRequest(scsi_ccb *request)
{
//	TRACE("AHCIPort::ScsiExecuteRequest port %d, opcode 0x%02x, length %u\n", fIndex, request->cdb[0], request->cdb_length);

	if (fIsATAPI) {
		bool isWrite = false;
		switch (request->flags & SCSI_DIR_MASK) {
			case SCSI_DIR_NONE:
				ASSERT(request->data_length == 0);
				break;
			case SCSI_DIR_IN:
				ASSERT(request->data_length > 0);
				break;
			case SCSI_DIR_OUT:
				isWrite = true;
				ASSERT(request->data_length > 0);
				break;
			default:
				panic("CDB has invalid direction mask");
		}
	
//		TRACE("AHCIPort::ScsiExecuteRequest ATAPI: port %d, opcode 0x%02x, length %u\n", fIndex, request->cdb[0], request->cdb_length);

		sata_request *sreq = new(std::nothrow) sata_request(request);
		sreq->set_atapi_cmd(request->data_length);
//		uint8 *data = (uint8*) sreq->ccb()->cdb;
//		for (int i = 0; i < 16; i += 8) {
//			TRACE("  %02x %02x %02x %02x %02x %02x %02x %02x\n", data[i], data[i+1], data[i+2], data[i+3], data[i+4], data[i+5], data[i+6], data[i+7]);
//		}
		ExecuteSataRequest(sreq, isWrite);
		return;
	}

	if (request->cdb[0] == SCSI_OP_REQUEST_SENSE) {
		panic("ahci: SCSI_OP_REQUEST_SENSE not yet supported\n");
		return;
	}

	if (!fDevicePresent) {
		TRACE("no device present on port %d\n", fIndex);
		request->subsys_status = SCSI_DEV_NOT_THERE;
		gSCSI->finished(request, 1);
		return;
	}
	
	request->subsys_status = SCSI_REQ_CMP;

	switch (request->cdb[0]) {
		case SCSI_OP_TEST_UNIT_READY:
			ScsiTestUnitReady(request);
			break;
		case SCSI_OP_INQUIRY:
			ScsiInquiry(request);
			break;
		case SCSI_OP_READ_CAPACITY:
			ScsiReadCapacity(request);
			break;
		case SCSI_OP_SYNCHRONIZE_CACHE:
			ScsiSynchronizeCache(request);
			break;
		case SCSI_OP_READ_6:
		case SCSI_OP_WRITE_6:
		{
			scsi_cmd_rw_6 *cmd = (scsi_cmd_rw_6 *)request->cdb;
			uint32 position = ((uint32)cmd->high_lba << 16) | ((uint32)cmd->mid_lba << 8) | (uint32)cmd->low_lba;
			size_t length = cmd->length != 0 ? cmd->length : 256;
			bool isWrite = request->cdb[0] == SCSI_OP_WRITE_6;
			ScsiReadWrite(request, position, length, isWrite);
			break;
		}
		case SCSI_OP_READ_10:
		case SCSI_OP_WRITE_10:
		{
			scsi_cmd_rw_10 *cmd = (scsi_cmd_rw_10 *)request->cdb;
			uint32 position = B_BENDIAN_TO_HOST_INT32(cmd->lba);
			size_t length = B_BENDIAN_TO_HOST_INT16(cmd->length);
			bool isWrite = request->cdb[0] == SCSI_OP_WRITE_10;
			if (length) {
				ScsiReadWrite(request, position, length, isWrite);
			} else {
				TRACE("AHCIPort::ScsiExecuteRequest error: transfer without data!\n");
				request->subsys_status = SCSI_REQ_INVALID;
				gSCSI->finished(request, 1);
			}
			break;
		}
		case SCSI_OP_READ_12:
		case SCSI_OP_WRITE_12:
		{
			scsi_cmd_rw_12 *cmd = (scsi_cmd_rw_12 *)request->cdb;
			uint32 position = B_BENDIAN_TO_HOST_INT32(cmd->lba);
			size_t length = B_BENDIAN_TO_HOST_INT32(cmd->length);
			bool isWrite = request->cdb[0] == SCSI_OP_WRITE_12;
			if (length) {
				ScsiReadWrite(request, position, length, isWrite);
			} else {
				TRACE("AHCIPort::ScsiExecuteRequest error: transfer without data!\n");
				request->subsys_status = SCSI_REQ_INVALID;
				gSCSI->finished(request, 1);
			}
			break;
		}
		default:
			TRACE("AHCIPort::ScsiExecuteRequest port %d unsupported request opcode 0x%02x\n", fIndex, request->cdb[0]);
			request->subsys_status = SCSI_REQ_ABORTED;
			gSCSI->finished(request, 1);
	}
}
Esempio n. 16
0
void
AHCIPort::ScsiExecuteRequest(scsi_ccb* request)
{
//	TRACE("AHCIPort::ScsiExecuteRequest port %d, opcode 0x%02x, length %u\n", fIndex, request->cdb[0], request->cdb_length);

	if (fIsATAPI) {
		bool isWrite = false;
		switch (request->flags & SCSI_DIR_MASK) {
			case SCSI_DIR_NONE:
				ASSERT(request->data_length == 0);
				break;
			case SCSI_DIR_IN:
				ASSERT(request->data_length > 0);
				break;
			case SCSI_DIR_OUT:
				isWrite = true;
				ASSERT(request->data_length > 0);
				break;
			default:
				panic("CDB has invalid direction mask");
		}

//		TRACE("AHCIPort::ScsiExecuteRequest ATAPI: port %d, opcode 0x%02x, length %u\n", fIndex, request->cdb[0], request->cdb_length);

		sata_request* sreq = new(std::nothrow) sata_request(request);
		if (sreq == NULL) {
			TRACE("out of memory when allocating atapi request\n");
			request->subsys_status = SCSI_REQ_ABORTED;
			gSCSI->finished(request, 1);
			return;
		}

		sreq->SetATAPICommand(request->data_length);
//		uint8* data = (uint8*) sreq->ccb()->cdb;
//		for (int i = 0; i < 16; i += 8) {
//			TRACE("  %02x %02x %02x %02x %02x %02x %02x %02x\n", data[i], data[i+1], data[i+2], data[i+3], data[i+4], data[i+5], data[i+6], data[i+7]);
//		}
		ExecuteSataRequest(sreq, isWrite);
		return;
	}

	if (request->cdb[0] == SCSI_OP_REQUEST_SENSE) {
		panic("ahci: SCSI_OP_REQUEST_SENSE not yet supported\n");
		return;
	}

	if (!fDevicePresent) {
		TRACE("no device present on port %d\n", fIndex);
		request->subsys_status = SCSI_DEV_NOT_THERE;
		gSCSI->finished(request, 1);
		return;
	}

	request->subsys_status = SCSI_REQ_CMP;

	switch (request->cdb[0]) {
		case SCSI_OP_TEST_UNIT_READY:
			ScsiTestUnitReady(request);
			break;
		case SCSI_OP_INQUIRY:
			ScsiInquiry(request);
			break;
		case SCSI_OP_READ_CAPACITY:
			ScsiReadCapacity(request);
			break;
		case SCSI_OP_SERVICE_ACTION_IN:
			if ((request->cdb[1] & 0x1f) == SCSI_SAI_READ_CAPACITY_16)
				ScsiReadCapacity16(request);
			else {
				request->subsys_status = SCSI_REQ_INVALID;
				gSCSI->finished(request, 1);
			}
			break;
		case SCSI_OP_SYNCHRONIZE_CACHE:
			ScsiSynchronizeCache(request);
			break;
		case SCSI_OP_READ_6:
		case SCSI_OP_WRITE_6:
		{
			const scsi_cmd_rw_6* cmd = (const scsi_cmd_rw_6*)request->cdb;
			uint32 position = ((uint32)cmd->high_lba << 16)
				| ((uint32)cmd->mid_lba << 8) | (uint32)cmd->low_lba;
			size_t length = cmd->length != 0 ? cmd->length : 256;
			bool isWrite = request->cdb[0] == SCSI_OP_WRITE_6;
			ScsiReadWrite(request, position, length, isWrite);
			break;
		}
		case SCSI_OP_READ_10:
		case SCSI_OP_WRITE_10:
		{
			const scsi_cmd_rw_10* cmd = (const scsi_cmd_rw_10*)request->cdb;
			uint32 position = B_BENDIAN_TO_HOST_INT32(cmd->lba);
			size_t length = B_BENDIAN_TO_HOST_INT16(cmd->length);
			bool isWrite = request->cdb[0] == SCSI_OP_WRITE_10;
			if (length) {
				ScsiReadWrite(request, position, length, isWrite);
			} else {
				TRACE("AHCIPort::ScsiExecuteRequest error: transfer without "
					"data!\n");
				request->subsys_status = SCSI_REQ_INVALID;
				gSCSI->finished(request, 1);
			}
			break;
		}
		case SCSI_OP_READ_12:
		case SCSI_OP_WRITE_12:
		{
			const scsi_cmd_rw_12* cmd = (const scsi_cmd_rw_12*)request->cdb;
			uint32 position = B_BENDIAN_TO_HOST_INT32(cmd->lba);
			size_t length = B_BENDIAN_TO_HOST_INT32(cmd->length);
			bool isWrite = request->cdb[0] == SCSI_OP_WRITE_12;
			if (length) {
				ScsiReadWrite(request, position, length, isWrite);
			} else {
				TRACE("AHCIPort::ScsiExecuteRequest error: transfer without "
					"data!\n");
				request->subsys_status = SCSI_REQ_INVALID;
				gSCSI->finished(request, 1);
			}
			break;
		}
		case SCSI_OP_READ_16:
		case SCSI_OP_WRITE_16:
		{
			const scsi_cmd_rw_16* cmd = (const scsi_cmd_rw_16*)request->cdb;
			uint64 position = B_BENDIAN_TO_HOST_INT64(cmd->lba);
			size_t length = B_BENDIAN_TO_HOST_INT32(cmd->length);
			bool isWrite = request->cdb[0] == SCSI_OP_WRITE_16;
			if (length) {
				ScsiReadWrite(request, position, length, isWrite);
			} else {
				TRACE("AHCIPort::ScsiExecuteRequest error: transfer without "
					"data!\n");
				request->subsys_status = SCSI_REQ_INVALID;
				gSCSI->finished(request, 1);
			}
			break;
		}
		case SCSI_OP_UNMAP:
		{
			const scsi_cmd_unmap* cmd = (const scsi_cmd_unmap*)request->cdb;

			if (!fTrimSupported) {
				TRACE("%s port %d: unsupported request opcode 0x%02x\n",
					__func__, fIndex, request->cdb[0]);
				request->subsys_status = SCSI_REQ_ABORTED;
				gSCSI->finished(request, 1);
				break;
			}

			scsi_unmap_parameter_list* unmapBlocks
				= (scsi_unmap_parameter_list*)request->data;
			if (unmapBlocks == NULL
				|| B_BENDIAN_TO_HOST_INT16(cmd->length) != request->data_length
				|| B_BENDIAN_TO_HOST_INT16(unmapBlocks->data_length)
					!= request->data_length - 1) {
				TRACE("%s port %d: invalid unmap parameter data length\n",
					__func__, fIndex);
				request->subsys_status = SCSI_REQ_ABORTED;
				gSCSI->finished(request, 1);
			} else {
				ScsiUnmap(request, unmapBlocks);
			}
			break;
		}
		default:
			TRACE("AHCIPort::ScsiExecuteRequest port %d unsupported request "
				"opcode 0x%02x\n", fIndex, request->cdb[0]);
			request->subsys_status = SCSI_REQ_ABORTED;
			gSCSI->finished(request, 1);
	}
}
Esempio n. 17
0
status_t
PackageReader::_ReadAttributeValue(uint8 type, uint8 encoding,
                                   AttributeValue& _value)
{
    switch (type) {
    case B_HPKG_ATTRIBUTE_TYPE_INT:
    case B_HPKG_ATTRIBUTE_TYPE_UINT:
    {
        uint64 intValue;
        status_t error;

        switch (encoding) {
        case B_HPKG_ATTRIBUTE_ENCODING_INT_8_BIT:
        {
            uint8 value;
            error = _Read(value);
            intValue = value;
            break;
        }
        case B_HPKG_ATTRIBUTE_ENCODING_INT_16_BIT:
        {
            uint16 value;
            error = _Read(value);
            intValue = B_BENDIAN_TO_HOST_INT16(value);
            break;
        }
        case B_HPKG_ATTRIBUTE_ENCODING_INT_32_BIT:
        {
            uint32 value;
            error = _Read(value);
            intValue = B_BENDIAN_TO_HOST_INT32(value);
            break;
        }
        case B_HPKG_ATTRIBUTE_ENCODING_INT_64_BIT:
        {
            uint64 value;
            error = _Read(value);
            intValue = B_BENDIAN_TO_HOST_INT64(value);
            break;
        }
        default:
        {
            fErrorOutput->PrintError("Error: Invalid TOC section: "
                                     "invalid encoding %d for int value type %d\n", encoding,
                                     type);
            return B_BAD_VALUE;
        }
        }

        if (error != B_OK)
            return error;

        if (type == B_HPKG_ATTRIBUTE_TYPE_INT)
            _value.SetTo((int64)intValue);
        else
            _value.SetTo(intValue);

        return B_OK;
    }

    case B_HPKG_ATTRIBUTE_TYPE_STRING:
    {
        if (encoding == B_HPKG_ATTRIBUTE_ENCODING_STRING_TABLE) {
            uint64 index;
            status_t error = _ReadUnsignedLEB128(index);
            if (error != B_OK)
                return error;

            if (index > fTOCStringsCount) {
                fErrorOutput->PrintError("Error: Invalid TOC section: "
                                         "string reference out of bounds\n");
                return B_BAD_DATA;
            }

            _value.SetTo(fStrings[index]);
        } else if (encoding == B_HPKG_ATTRIBUTE_ENCODING_STRING_INLINE) {
            const char* string;
            status_t error = _ReadString(string);
            if (error != B_OK)
                return error;

            _value.SetTo(string);
        } else {
            fErrorOutput->PrintError("Error: Invalid TOC section: invalid "
                                     "string encoding (%u)\n", encoding);
            return B_BAD_DATA;
        }

        return B_OK;
    }

    case B_HPKG_ATTRIBUTE_TYPE_RAW:
    {
        uint64 size;
        status_t error = _ReadUnsignedLEB128(size);
        if (error != B_OK)
            return error;

        if (encoding == B_HPKG_ATTRIBUTE_ENCODING_RAW_HEAP) {
            uint64 offset;
            error = _ReadUnsignedLEB128(offset);
            if (error != B_OK)
                return error;

            if (offset > fHeapSize || size > fHeapSize - offset) {
                fErrorOutput->PrintError("Error: Invalid TOC section: "
                                         "invalid data reference\n");
                return B_BAD_DATA;
            }

            _value.SetToData(size, fHeapOffset + offset);
        } else if (encoding == B_HPKG_ATTRIBUTE_ENCODING_RAW_INLINE) {
            if (size > B_HPKG_MAX_INLINE_DATA_SIZE) {
                fErrorOutput->PrintError("Error: Invalid TOC section: "
                                         "inline data too long\n");
                return B_BAD_DATA;
            }

            const void* buffer;
            error = _GetTOCBuffer(size, buffer);
            if (error != B_OK)
                return error;
            _value.SetToData(size, buffer);
        } else {
            fErrorOutput->PrintError("Error: Invalid TOC section: invalid "
                                     "raw encoding (%u)\n", encoding);
            return B_BAD_DATA;
        }

        return B_OK;
    }

    default:
        fErrorOutput->PrintError("Error: Invalid TOC section: invalid "
                                 "value type: %d\n", type);
        return B_BAD_DATA;
    }
}
Esempio n. 18
0
status_t
PackageReader::Init(int fd, bool keepFD)
{
    fFD = fd;
    fOwnsFD = keepFD;

    // stat it
    struct stat st;
    if (fstat(fFD, &st) < 0) {
        fErrorOutput->PrintError("Error: Failed to access package file: %s\n",
                                 strerror(errno));
        return errno;
    }

    // read the header
    hpkg_header header;
    status_t error = _ReadBuffer(0, &header, sizeof(header));
    if (error != B_OK)
        return error;

    // check the header

    // magic
    if (B_BENDIAN_TO_HOST_INT32(header.magic) != B_HPKG_MAGIC) {
        fErrorOutput->PrintError("Error: Invalid package file: Invalid "
                                 "magic\n");
        return B_BAD_DATA;
    }

    // header size
    fHeapOffset = B_BENDIAN_TO_HOST_INT16(header.header_size);
    if ((size_t)fHeapOffset < sizeof(hpkg_header)) {
        fErrorOutput->PrintError("Error: Invalid package file: Invalid header "
                                 "size (%llu)\n", fHeapOffset);
        return B_BAD_DATA;
    }

    // version
    if (B_BENDIAN_TO_HOST_INT16(header.version) != B_HPKG_VERSION) {
        fErrorOutput->PrintError("Error: Invalid/unsupported package file "
                                 "version (%d)\n", B_BENDIAN_TO_HOST_INT16(header.version));
        return B_BAD_DATA;
    }

    // total size
    fTotalSize = B_BENDIAN_TO_HOST_INT64(header.total_size);
    if (fTotalSize != (uint64)st.st_size) {
        fErrorOutput->PrintError("Error: Invalid package file: Total size in "
                                 "header (%llu) doesn't agree with total file size (%lld)\n",
                                 fTotalSize, st.st_size);
        return B_BAD_DATA;
    }

    // package attributes length and compression
    fPackageAttributesCompression
        = B_BENDIAN_TO_HOST_INT32(header.attributes_compression);
    fPackageAttributesCompressedLength
        = B_BENDIAN_TO_HOST_INT32(header.attributes_length_compressed);
    fPackageAttributesUncompressedLength
        = B_BENDIAN_TO_HOST_INT32(header.attributes_length_uncompressed);

    if (const char* errorString = _CheckCompression(
                                      fPackageAttributesCompression, fPackageAttributesCompressedLength,
                                      fPackageAttributesUncompressedLength)) {
        fErrorOutput->PrintError("Error: Invalid package file: package "
                                 "attributes section: %s\n", errorString);
        return B_BAD_DATA;
    }

    // TOC length and compression
    fTOCCompression = B_BENDIAN_TO_HOST_INT32(header.toc_compression);
    fTOCCompressedLength
        = B_BENDIAN_TO_HOST_INT64(header.toc_length_compressed);
    fTOCUncompressedLength
        = B_BENDIAN_TO_HOST_INT64(header.toc_length_uncompressed);

    if (const char* errorString = _CheckCompression(fTOCCompression,
                                  fTOCCompressedLength, fTOCUncompressedLength)) {
        fErrorOutput->PrintError("Error: Invalid package file: TOC section: "
                                 "%s\n", errorString);
        return B_BAD_DATA;
    }

    // TOC subsections
    fTOCAttributeTypesLength
        = B_BENDIAN_TO_HOST_INT64(header.toc_attribute_types_length);
    fTOCAttributeTypesCount
        = B_BENDIAN_TO_HOST_INT64(header.toc_attribute_types_count);
    fTOCStringsLength = B_BENDIAN_TO_HOST_INT64(header.toc_strings_length);
    fTOCStringsCount = B_BENDIAN_TO_HOST_INT64(header.toc_strings_count);

    if (fTOCAttributeTypesLength > fTOCUncompressedLength
            || fTOCStringsLength > fTOCUncompressedLength - fTOCAttributeTypesLength
            || fTOCAttributeTypesCount > fTOCAttributeTypesLength
            || fTOCStringsCount > fTOCStringsLength) {
        fErrorOutput->PrintError("Error: Invalid package file: Invalid TOC "
                                 "subsections description\n");
        return B_BAD_DATA;
    }

    // check whether the sections fit together
    if (fPackageAttributesCompressedLength > fTotalSize
            || fTOCCompressedLength
            > fTotalSize - fPackageAttributesCompressedLength
            || fHeapOffset
            > fTotalSize - fPackageAttributesCompressedLength
            - fTOCCompressedLength) {
        fErrorOutput->PrintError("Error: Invalid package file: The sum of the "
                                 "sections sizes is greater than the package size\n");
        return B_BAD_DATA;
    }

    fPackageAttributesOffset = fTotalSize - fPackageAttributesCompressedLength;
    fTOCSectionOffset = fPackageAttributesOffset - fTOCCompressedLength;
    fHeapSize = fTOCSectionOffset - fHeapOffset;

    // TOC size sanity check
    if (fTOCUncompressedLength > kMaxTOCSize) {
        fErrorOutput->PrintError("Error: Package file TOC section size "
                                 "is %llu bytes. This is beyond the reader's sanity limit\n",
                                 fTOCUncompressedLength);
        return B_UNSUPPORTED;
    }

    // allocate a scratch buffer
    fScratchBuffer = new(std::nothrow) uint8[kScratchBufferSize];
    if (fScratchBuffer == NULL) {
        fErrorOutput->PrintError("Error: Out of memory!\n");
        return B_NO_MEMORY;
    }
    fScratchBufferSize = kScratchBufferSize;

    // read in the complete TOC
    fTOCSection = new(std::nothrow) uint8[fTOCUncompressedLength];
    if (fTOCSection == NULL) {
        fErrorOutput->PrintError("Error: Out of memory!\n");
        return B_NO_MEMORY;
    }

    error = _ReadCompressedBuffer(fTOCSectionOffset, fTOCSection,
                                  fTOCCompressedLength, fTOCUncompressedLength, fTOCCompression);
    if (error != B_OK)
        return error;

    // start parsing the TOC
    fCurrentTOCOffset = 0;

    // attribute types
    error = _ParseTOCAttributeTypes();
    if (error != B_OK)
        return error;
    fCurrentTOCOffset += fTOCAttributeTypesLength;

    // strings
    error = _ParseTOCStrings();
    if (error != B_OK)
        return error;
    fCurrentTOCOffset += fTOCStringsLength;

    return B_OK;
}
Esempio n. 19
0
	uint32 Magic() const
		{ return B_BENDIAN_TO_HOST_INT32(magic); }
Esempio n. 20
0
	uint32 CrcChecksum() const
		{ return B_BENDIAN_TO_HOST_INT32(crc_checksum); }
Esempio n. 21
0
// _BroadcastListener
int32
ServerManager::_BroadcastListener()
{
	TaskManager taskManager;
	while (!fTerminating) {
		taskManager.RemoveDoneTasks();

		// receive
		sockaddr_in addr;
		addr.sin_family = AF_INET;
		addr.sin_port = htons(kDefaultBroadcastPort);
		addr.sin_addr.s_addr = INADDR_ANY;
		socklen_t addrSize = sizeof(addr);
		BroadcastMessage message;
//PRINT(("ServerManager::_BroadcastListener(): recvfrom()...\n"));
		ssize_t bytesRead = recvfrom(fBroadcastListenerSocket, &message,
			sizeof(message), 0, (sockaddr*)&addr, &addrSize);
		if (bytesRead < 0) {
			PRINT("ServerManager::_BroadcastListener(): recvfrom() "
				"failed: %s\n", strerror(errno));
			continue;
		}

		// check message size, magic, and protocol version
		if (bytesRead != sizeof(BroadcastMessage)) {
			PRINT("ServerManager::_BroadcastListener(): received "
				"%ld bytes, but it should be %lu\n", bytesRead,
				sizeof(BroadcastMessage));
			continue;
		}
		if (message.magic != B_HOST_TO_BENDIAN_INT32(BROADCAST_MESSAGE_MAGIC)) {
			PRINT("ServerManager::_BroadcastListener(): message has"
				" bad magic.\n");
			continue;
		}
		if (message.protocolVersion
			!= (int32)B_HOST_TO_BENDIAN_INT32(NETFS_PROTOCOL_VERSION)) {
			PRINT("ServerManager::_BroadcastListener(): protocol "
				"version does not match: %" B_PRId32 " vs. %d.\n",
				(int32)B_BENDIAN_TO_HOST_INT32(
					message.protocolVersion),
				NETFS_PROTOCOL_VERSION);
			continue;
		}

		// check, if the server is local
		NetAddress netAddress(addr);
		#ifndef ADD_SERVER_LOCALHOST
			if (netAddress.IsLocal())
				continue;
		#endif	// ADD_SERVER_LOCALHOST

		AutoLocker<Locker> locker(fLock);
		ExtendedServerInfo* oldServerInfo = fServerInfos->Get(netAddress);

		// examine the message
		switch (B_BENDIAN_TO_HOST_INT32(message.message)) {
			case BROADCAST_MESSAGE_SERVER_TICK:
//				PRINT(("ServerManager::_BroadcastListener(): "
//					"BROADCAST_MESSAGE_SERVER_TICK.\n"));
				if (oldServerInfo)
					continue;
				break;
			case BROADCAST_MESSAGE_SERVER_UPDATE:
//				PRINT(("ServerManager::_BroadcastListener(): "
//					"BROADCAST_MESSAGE_SERVER_UPDATE.\n"));
				break;
			case BROADCAST_MESSAGE_CLIENT_HELLO:
//				PRINT(("ServerManager::_BroadcastListener(): "
//					"BROADCAST_MESSAGE_CLIENT_HELLO. Ignoring.\n"));
				continue;
				break;
		}

		if (oldServerInfo && oldServerInfo->GetState() != STATE_READY)
			continue;

		// create a new server info and add it
		ExtendedServerInfo* serverInfo
			= new(std::nothrow) ExtendedServerInfo(netAddress);
		if (!serverInfo)
			return B_NO_MEMORY;
		serverInfo->SetState(STATE_ADDING);
		BReference<ExtendedServerInfo> serverInfoReference(serverInfo, true);
		if (oldServerInfo) {
			oldServerInfo->SetState(STATE_UPDATING);
		} else {
			status_t error = fServerInfos->Put(netAddress, serverInfo);
			if (error != B_OK)
				continue;
			serverInfo->AcquireReference();
		}

		// create a task to add/update the server info
		ServerInfoTask* task = new(std::nothrow) ServerInfoTask(this, oldServerInfo,
			serverInfo);
		if (!task) {
			if (oldServerInfo) {
				oldServerInfo->SetState(STATE_READY);
			} else {
				fServerInfos->Remove(serverInfo->GetAddress());
				serverInfo->ReleaseReference();
			}
			continue;
		}
		// now the task has all info and will call the respective cleanup
		// method when being deleted
		if (task->Init() != B_OK) {
			delete task;
			continue;
		}
		status_t error = taskManager.RunTask(task);
		if (error != B_OK) {
			ERROR("ServerManager::_BroadcastListener(): Failed to start server "
				"info task: %s\n", strerror(error));
			continue;
		}
	}
	return B_OK;
}
Esempio n. 22
0
/*! Execute SCSI command */
void
ata_exec_io(ide_device_info *device, ide_qrequest *qrequest)
{
	scsi_ccb *request = qrequest->request;
	
	SHOW_FLOW(3, "command=%x", request->cdb[0]);
		
	// ATA devices have one LUN only
	if (request->target_lun != 0) {
		request->subsys_status = SCSI_SEL_TIMEOUT;
		finish_request(qrequest, false);
		return;
	}

	// starting a request means deleting sense, so don't do it if
	// the command wants to read it
	if (request->cdb[0] != SCSI_OP_REQUEST_SENSE)	
		start_request(device, qrequest);

	switch (request->cdb[0]) {
		case SCSI_OP_TEST_UNIT_READY:
			ata_test_unit_ready(device, qrequest);
			break;

		case SCSI_OP_REQUEST_SENSE:
			ide_request_sense(device, qrequest);
			return;

		case SCSI_OP_FORMAT: /* FORMAT UNIT */
			// we could forward request to disk, but modern disks cannot
			// be formatted anyway, so we just refuse request
			// (exceptions are removable media devices, but to my knowledge
			// they don't have to be formatted as well)
			set_sense(device, SCSIS_KEY_ILLEGAL_REQUEST, SCSIS_ASC_INV_OPCODE);
			break;

		case SCSI_OP_INQUIRY: 
			ata_inquiry(device, qrequest);
			break;

		case SCSI_OP_MODE_SELECT_10:
			ata_mode_select_10(device, qrequest);
			break;

		case SCSI_OP_MODE_SENSE_10:
			ata_mode_sense_10(device, qrequest);
			break;

		case SCSI_OP_MODE_SELECT_6:
		case SCSI_OP_MODE_SENSE_6:
			// we've told SCSI bus manager to emulates these commands
			set_sense(device, SCSIS_KEY_ILLEGAL_REQUEST, SCSIS_ASC_INV_OPCODE);
			break;

		case SCSI_OP_RESERVE:
		case SCSI_OP_RELEASE:
			// though mandatory, this doesn't make much sense in a
			// single initiator environment; so what
			set_sense(device, SCSIS_KEY_ILLEGAL_REQUEST, SCSIS_ASC_INV_OPCODE);
			break;

		case SCSI_OP_START_STOP: {
			scsi_cmd_ssu *cmd = (scsi_cmd_ssu *)request->cdb;

			// with no LoEj bit set, we should only allow/deny further access
			// we ignore that (unsupported for ATA)
			// with LoEj bit set, we should additionally either load or eject the medium
			// (start = 0 - eject; start = 1 - load)

			if (!cmd->start)
				// we must always flush cache if start = 0
				ata_flush_cache(device, qrequest);

			if (cmd->load_eject)
				ata_load_eject(device, qrequest, cmd->start);

			break;
		}

		case SCSI_OP_PREVENT_ALLOW: {
			scsi_cmd_prevent_allow *cmd = (scsi_cmd_prevent_allow *)request->cdb;

			ata_prevent_allow(device, cmd->prevent);
			break;
		}

		case SCSI_OP_READ_CAPACITY:
			read_capacity(device, qrequest);
			break;

		case SCSI_OP_VERIFY:
			// does anyone uses this function?
			// effectly, it does a read-and-compare, which IDE doesn't support
			set_sense(device, SCSIS_KEY_ILLEGAL_REQUEST, SCSIS_ASC_INV_OPCODE);
			break;

		case SCSI_OP_SYNCHRONIZE_CACHE:
			// we ignore range and immediate bit, we always immediately flush everything 
			ata_flush_cache(device, qrequest);
			break;

		// sadly, there are two possible read/write operation codes;
		// at least, the third one, read/write(12), is not valid for DAS
		case SCSI_OP_READ_6:
		case SCSI_OP_WRITE_6:
		{
			scsi_cmd_rw_6 *cmd = (scsi_cmd_rw_6 *)request->cdb;
			uint32 pos;
			size_t length;

			pos = ((uint32)cmd->high_lba << 16) | ((uint32)cmd->mid_lba << 8)
				| (uint32)cmd->low_lba;
			length = cmd->length != 0 ? cmd->length : 256;

			SHOW_FLOW(3, "READ6/WRITE6 pos=%lx, length=%lx", pos, length);

			ata_send_rw(device, qrequest, pos, length, cmd->opcode == SCSI_OP_WRITE_6);
			return;
		}

		case SCSI_OP_READ_10:
		case SCSI_OP_WRITE_10:
		{
			scsi_cmd_rw_10 *cmd = (scsi_cmd_rw_10 *)request->cdb;
			uint32 pos;
			size_t length;

			pos = B_BENDIAN_TO_HOST_INT32(cmd->lba);
			length = B_BENDIAN_TO_HOST_INT16(cmd->length);

			if (length != 0) {
				ata_send_rw(device, qrequest, pos, length, cmd->opcode == SCSI_OP_WRITE_10);
			} else {
				// we cannot transfer zero blocks (apart from LBA48)
				finish_request(qrequest, false);
			}
			return;
		}

		default:
			set_sense(device, SCSIS_KEY_ILLEGAL_REQUEST, SCSIS_ASC_INV_OPCODE);
	}

	finish_checksense(qrequest);
}
Esempio n. 23
0
	uint32 HeaderCrcChecksum() const
		{ return B_BENDIAN_TO_HOST_INT32(header_crc_checksum); }
Esempio n. 24
0
	uint32 Flags() const
		{ return B_BENDIAN_TO_HOST_INT32(flags); }
Esempio n. 25
0
	uint32 BlockSize() const
		{ return B_BENDIAN_TO_HOST_INT32(block_size); }
Esempio n. 26
0
AtomBase *
GetAtom(BPositionIO *pStream)
{
	uint32 aAtomType;
	uint32 aAtomSize;
	uint64 aRealAtomSize;
	off_t aStreamOffset;
	
	aStreamOffset = pStream->Position();
	
	// Get Size uint32
	pStream->Read(&aAtomSize,4);
	aAtomSize = B_BENDIAN_TO_HOST_INT32(aAtomSize);
	// Get Type uint32
	pStream->Read(&aAtomType,4);
	aAtomType = B_BENDIAN_TO_HOST_INT32(aAtomType);
	// Check for extended size
	if (aAtomSize == 1) {
		// Handle extended size
		pStream->Read(&aRealAtomSize,4);
		aRealAtomSize = B_BENDIAN_TO_HOST_INT64(aRealAtomSize);
	} else if (aAtomSize == 0) {
		// aAtomSize extends to end of file.
		// TODO this is broken
		aRealAtomSize = 0;
	} else {
		aRealAtomSize = aAtomSize;
	}

	if (aAtomType == uint32('moov'))
		return new MOOVAtom(pStream, aStreamOffset, aAtomType, aRealAtomSize);
	
	if (aAtomType == uint32('mvhd'))
		return new MVHDAtom(pStream, aStreamOffset, aAtomType, aRealAtomSize);

	if (aAtomType == uint32('trak'))
		return new TRAKAtom(pStream, aStreamOffset, aAtomType, aRealAtomSize);

	if (aAtomType == uint32('tkhd'))
		return new TKHDAtom(pStream, aStreamOffset, aAtomType, aRealAtomSize);

	if (aAtomType == uint32('free'))
		return new FREEAtom(pStream, aStreamOffset, aAtomType, aRealAtomSize);

	if (aAtomType == uint32('skip'))
		return new SKIPAtom(pStream, aStreamOffset, aAtomType, aRealAtomSize);

	if (aAtomType == uint32('wide'))
		return new WIDEAtom(pStream, aStreamOffset, aAtomType, aRealAtomSize);

	if (aAtomType == uint32('mdat'))
		return new MDATAtom(pStream, aStreamOffset, aAtomType, aRealAtomSize);

	if (aAtomType == uint32('mdia'))
		return new MDIAAtom(pStream, aStreamOffset, aAtomType, aRealAtomSize);

	if (aAtomType == uint32('mdhd'))
		return new MDHDAtom(pStream, aStreamOffset, aAtomType, aRealAtomSize);

	if (aAtomType == uint32('hdlr'))
		return new HDLRAtom(pStream, aStreamOffset, aAtomType, aRealAtomSize);

	if (aAtomType == uint32('minf'))
		return new MINFAtom(pStream, aStreamOffset, aAtomType, aRealAtomSize);

	if (aAtomType == uint32('vmhd'))
		return new VMHDAtom(pStream, aStreamOffset, aAtomType, aRealAtomSize);

	if (aAtomType == uint32('smhd'))
		return new SMHDAtom(pStream, aStreamOffset, aAtomType, aRealAtomSize);

	if (aAtomType == uint32('dinf'))
		return new DINFAtom(pStream, aStreamOffset, aAtomType, aRealAtomSize);

	if (aAtomType == uint32('stbl'))
		return new STBLAtom(pStream, aStreamOffset, aAtomType, aRealAtomSize);

	if (aAtomType == uint32('stsd'))
		return new STSDAtom(pStream, aStreamOffset, aAtomType, aRealAtomSize);

	if (aAtomType == uint32('tmcd'))
		return new TMCDAtom(pStream, aStreamOffset, aAtomType, aRealAtomSize);

	if (aAtomType == uint32('stts'))
		return new STTSAtom(pStream, aStreamOffset, aAtomType, aRealAtomSize);

	if (aAtomType == uint32('pnot'))
		return new PNOTAtom(pStream, aStreamOffset, aAtomType, aRealAtomSize);

	if (aAtomType == uint32('stsc'))
		return new STSCAtom(pStream, aStreamOffset, aAtomType, aRealAtomSize);

	if (aAtomType == uint32('stco'))
		return new STCOAtom(pStream, aStreamOffset, aAtomType, aRealAtomSize);

	if (aAtomType == uint32('stss'))
		return new STSSAtom(pStream, aStreamOffset, aAtomType, aRealAtomSize);

	if (aAtomType == uint32('ctts'))
		return new CTTSAtom(pStream, aStreamOffset, aAtomType, aRealAtomSize);

	if (aAtomType == uint32('stsz'))
		return new STSZAtom(pStream, aStreamOffset, aAtomType, aRealAtomSize);

	if (aAtomType == uint32('stz2'))
		return new STZ2Atom(pStream, aStreamOffset, aAtomType, aRealAtomSize);

	if (aAtomType == uint32('ftyp'))
		return new FTYPAtom(pStream, aStreamOffset, aAtomType, aRealAtomSize);

	if (aAtomType == uint32('cmov'))
		return new CMOVAtom(pStream, aStreamOffset, aAtomType, aRealAtomSize);

	if (aAtomType == uint32('dcom'))
		return new DCOMAtom(pStream, aStreamOffset, aAtomType, aRealAtomSize);

	if (aAtomType == uint32('cmvd'))
		return new CMVDAtom(pStream, aStreamOffset, aAtomType, aRealAtomSize);

	if (aAtomType == uint32('esds'))
		return new ESDSAtom(pStream, aStreamOffset, aAtomType, aRealAtomSize);

	if (aAtomType == uint32('alac'))
		return new ALACAtom(pStream, aStreamOffset, aAtomType, aRealAtomSize);
	
	if (aAtomType == uint32('wave'))
		return new WAVEAtom(pStream, aStreamOffset, aAtomType, aRealAtomSize);

	if (aAtomType == uint32('dac3'))
		return new DAC3Atom(pStream, aStreamOffset, aAtomType, aRealAtomSize);

	if (aAtomType == uint32('dec3'))
		return new DEC3Atom(pStream, aStreamOffset, aAtomType, aRealAtomSize);

	if (aAtomType == uint32('avcC'))
		return new DecoderConfigAtom(pStream, aStreamOffset, aAtomType,
			aRealAtomSize);

	return new AtomBase(pStream, aStreamOffset, aAtomType, aRealAtomSize);
}
Esempio n. 27
0
/*!
  \internal
  The thread's execution loop for AsyncNetIO
*/
void cAsyncNetIO::run() throw()
{
	while ( !canceled() )
	{
		mapsMutex.lock(); // do not disturb me here.
		for ( const_iterator it( buffers.begin() ); it != buffers.end(); ++it )
		{
			// Read all avaliable data.
			char buf[4096];
			cAsyncNetIOPrivate* d = it.data();

			// Check if the socket is valid
			if ( !d->socket->isValid() )
				continue; // Let it in the queue until it's taken out by the closed-collector

			// Try to get the UO Header somehow
			if ( !d->skippedUOHeader )
			{
				int nread = d->socket->readBlock( buf, 4 - d->rsize );

				if ( nread > 0 )
				{
					QByteArray* a = new QByteArray( nread );
					memcpy( a->data(), buf, nread );
					d->rba.append( a );
					d->rsize += nread;

					if ( d->rsize == 4 )
					{
						char temp[4];
						d->consumeReadBuf( 4, temp );
						d->skippedUOHeader = true;

						wpCopyIn( d->seed, temp );
						d->seed = B_BENDIAN_TO_HOST_INT32( d->seed );

						// Only 0xFFFFFFFF seed allowed for !d->login
						if ( !d->login && d->seed != 0xFFFFFFFF )
						{
							d->writeBlock( "\x82\x04", 2 );
							flushWriteBuffer( d );
							d->socket->close();
							continue;
						}
					}
				}
				/*else if ( nread == 0 )
						{
							d->socket->close();
						}*/
			}
			else
			{
				int nread = d->socket->readBlock( buf, sizeof( buf ) );

				if ( nread > 0 )
				{
					// If we have an encryption object already
					// then decrypt the buffer before storing it
					if ( d->encryption )
						d->encryption->clientDecrypt( &buf[0], nread );

					QByteArray* a = new QByteArray( nread );
					memcpy( a->data(), buf, nread );
					d->rba.append( a );
					d->rsize += nread;

					// We need to use the read buffer as a temporary buffer
					// for encrypted data if we didn't receive all we need
					if ( !d->encryption )
					{
						// Game server Encryption
						if ( !d->login && d->rsize >= 65 )
						{
							// The 0x91 packet is 65 byte
							nread = d->rsize;
							d->consumeReadBuf( d->rsize, &buf[0] );

							// This should be no encryption
							if ( buf[0] == '\x91' && buf[1] == '\xFF' && buf[2] == '\xFF' && buf[3] == '\xFF' && buf[4] == '\xFF' )
							{
								// Is no Encryption allowed?
								if ( !Config::instance()->allowUnencryptedClients() )
								{
									// Send a communication problem message to this socket
									d->writeBlock( "\x82\x04", 2 );
									flushWriteBuffer( d );
									d->socket->close();
									continue;
								}

								d->encryption = new cNoEncryption;
							}
							else
							{
								cGameEncryption* crypt = new cGameEncryption;
								crypt->init( 0xFFFFFFFF );
								d->encryption = crypt;
							}
						} // LoginServer Encryption
						else if ( d->login && d->rsize >= 62 )
						{
							// The 0x80 packet is 62 byte, but we want to have everything
							nread = d->rsize;
							d->consumeReadBuf( d->rsize, &buf[0] );

							// Check if it could be *not* encrypted
							if ( buf[0] == '\x80' && buf[30] == '\x00' && buf[60] == '\x00' )
							{
								// Is no Encryption allowed?
								if ( !Config::instance()->allowUnencryptedClients() )
								{
									// Send a communication problem message to this socket
									d->writeBlock( "\x82\x04", 2 );
									flushWriteBuffer( d );
									d->socket->close();
									continue;
								}

								d->encryption = new cNoEncryption;
							}
							else
							{
								cLoginEncryption* crypt = new cLoginEncryption;
								if ( !crypt->init( d->seed, &buf[0], nread ) )
								{
									delete crypt;

									// Send a communication problem message to this socket
									d->writeBlock( "\x82\x04", 2 );
									flushWriteBuffer( d );
									d->socket->close();
									continue;
								}

								d->encryption = crypt;
							}

							// It gets a bit tricky now, try to decode it with all
							// possible keys
						}

						// If we found an encryption let's decrypt what we got in our buffer
						if ( d->encryption )
						{
							d->encryption->clientDecrypt( &buf[0], nread );

							QByteArray* a = new QByteArray( nread );
							memcpy( a->data(), buf, nread );
							d->rba.append( a );
							d->rsize += nread;
						}
					}
				}
				else if ( nread == 0 )
				{
					d->socket->close();
				}

				buildUOPackets( d );
			}

			// Write data to socket
			flushWriteBuffer( d );
		}
		mapsMutex.unlock();
		//if( buffers.empty() )
		// Disconnecting doesn't work for now
		waitCondition.wait( 10 ); // let's rest for a while
	}
}
Esempio n. 28
0
void
AHCIPort::ScsiExecuteRequest(scsi_ccb *request)
{
//	TRACE("AHCIPort::ScsiExecuteRequest port %d, opcode 0x%02x, length %u\n", fIndex, request->cdb[0], request->cdb_length);

    if (fIsATAPI) {
        bool isWrite = false;
        switch (request->flags & SCSI_DIR_MASK) {
        case SCSI_DIR_NONE:
            ASSERT(request->data_length == 0);
            break;
        case SCSI_DIR_IN:
            ASSERT(request->data_length > 0);
            break;
        case SCSI_DIR_OUT:
            isWrite = true;
            ASSERT(request->data_length > 0);
            break;
        default:
            panic("CDB has invalid direction mask");
        }

//		TRACE("AHCIPort::ScsiExecuteRequest ATAPI: port %d, opcode 0x%02x, length %u\n", fIndex, request->cdb[0], request->cdb_length);

        sata_request *sreq = new(std::nothrow) sata_request(request);
        if (sreq == NULL) {
            TRACE("out of memory when allocating atapi request\n");
            request->subsys_status = SCSI_REQ_ABORTED;
            gSCSI->finished(request, 1);
            return;
        }

        sreq->set_atapi_cmd(request->data_length);
//		uint8 *data = (uint8*) sreq->ccb()->cdb;
//		for (int i = 0; i < 16; i += 8) {
//			TRACE("  %02x %02x %02x %02x %02x %02x %02x %02x\n", data[i], data[i+1], data[i+2], data[i+3], data[i+4], data[i+5], data[i+6], data[i+7]);
//		}
        ExecuteSataRequest(sreq, isWrite);
        return;
    }

    if (request->cdb[0] == SCSI_OP_REQUEST_SENSE) {
        panic("ahci: SCSI_OP_REQUEST_SENSE not yet supported\n");
        return;
    }

    if (!fDevicePresent) {
        TRACE("no device present on port %d\n", fIndex);
        request->subsys_status = SCSI_DEV_NOT_THERE;
        gSCSI->finished(request, 1);
        return;
    }

    request->subsys_status = SCSI_REQ_CMP;

    switch (request->cdb[0]) {
    case SCSI_OP_TEST_UNIT_READY:
        ScsiTestUnitReady(request);
        break;
    case SCSI_OP_INQUIRY:
        ScsiInquiry(request);
        break;
    case SCSI_OP_READ_CAPACITY:
        ScsiReadCapacity(request);
        break;
    case SCSI_OP_SERVICE_ACTION_IN:
        if ((request->cdb[1] & 0x1f) == SCSI_SAI_READ_CAPACITY_16)
            ScsiReadCapacity16(request);
        else {
            request->subsys_status = SCSI_REQ_INVALID;
            gSCSI->finished(request, 1);
        }
        break;
    case SCSI_OP_SYNCHRONIZE_CACHE:
        ScsiSynchronizeCache(request);
        break;
    case SCSI_OP_READ_6:
    case SCSI_OP_WRITE_6:
    {
        const scsi_cmd_rw_6 *cmd = (const scsi_cmd_rw_6 *)request->cdb;
        uint32 position = ((uint32)cmd->high_lba << 16)
                          | ((uint32)cmd->mid_lba << 8) | (uint32)cmd->low_lba;
        size_t length = cmd->length != 0 ? cmd->length : 256;
        bool isWrite = request->cdb[0] == SCSI_OP_WRITE_6;
        ScsiReadWrite(request, position, length, isWrite);
        break;
    }
    case SCSI_OP_READ_10:
    case SCSI_OP_WRITE_10:
    {
        const scsi_cmd_rw_10 *cmd = (const scsi_cmd_rw_10 *)request->cdb;
        uint32 position = B_BENDIAN_TO_HOST_INT32(cmd->lba);
        size_t length = B_BENDIAN_TO_HOST_INT16(cmd->length);
        bool isWrite = request->cdb[0] == SCSI_OP_WRITE_10;
        if (length) {
            ScsiReadWrite(request, position, length, isWrite);
        } else {
            TRACE("AHCIPort::ScsiExecuteRequest error: transfer without "
                  "data!\n");
            request->subsys_status = SCSI_REQ_INVALID;
            gSCSI->finished(request, 1);
        }
        break;
    }
    case SCSI_OP_READ_12:
    case SCSI_OP_WRITE_12:
    {
        const scsi_cmd_rw_12 *cmd = (const scsi_cmd_rw_12 *)request->cdb;
        uint32 position = B_BENDIAN_TO_HOST_INT32(cmd->lba);
        size_t length = B_BENDIAN_TO_HOST_INT32(cmd->length);
        bool isWrite = request->cdb[0] == SCSI_OP_WRITE_12;
        if (length) {
            ScsiReadWrite(request, position, length, isWrite);
        } else {
            TRACE("AHCIPort::ScsiExecuteRequest error: transfer without "
                  "data!\n");
            request->subsys_status = SCSI_REQ_INVALID;
            gSCSI->finished(request, 1);
        }
        break;
    }
    case SCSI_OP_READ_16:
    case SCSI_OP_WRITE_16:
    {
        const scsi_cmd_rw_16 *cmd = (const scsi_cmd_rw_16 *)request->cdb;
        uint64 position = B_BENDIAN_TO_HOST_INT64(cmd->lba);
        size_t length = B_BENDIAN_TO_HOST_INT32(cmd->length);
        bool isWrite = request->cdb[0] == SCSI_OP_WRITE_16;
        if (length) {
            ScsiReadWrite(request, position, length, isWrite);
        } else {
            TRACE("AHCIPort::ScsiExecuteRequest error: transfer without "
                  "data!\n");
            request->subsys_status = SCSI_REQ_INVALID;
            gSCSI->finished(request, 1);
        }
        break;
    }
    case SCSI_OP_WRITE_SAME_16:
    {
        const scsi_cmd_wsame_16 *cmd = (const scsi_cmd_wsame_16 *)request->cdb;

        // SCSI unmap is used for trim, otherwise we don't support it
        if (!cmd->unmap) {
            TRACE("%s port %d: unsupported request opcode 0x%02x\n",
                  __func__, fIndex, request->cdb[0]);
            request->subsys_status = SCSI_REQ_ABORTED;
            gSCSI->finished(request, 1);
            break;
        }

        if (!fTrim) {
            // Drive doesn't support trim (or atapi)
            // Just say it was successful and quit
            request->subsys_status = SCSI_REQ_CMP;
        } else {
            TRACE("%s unimplemented: TRIM call\n", __func__);
            // TODO: Make Serial ATA (sata_request?) trim call here.
            request->subsys_status = SCSI_REQ_ABORTED;
        }
        gSCSI->finished(request, 1);
        break;
    }
    default:
        TRACE("AHCIPort::ScsiExecuteRequest port %d unsupported request "
              "opcode 0x%02x\n", fIndex, request->cdb[0]);
        request->subsys_status = SCSI_REQ_ABORTED;
        gSCSI->finished(request, 1);
    }
}
Esempio n. 29
0
type_code
ResourceType::StringToCode(const char* code)
{
	// TODO: Code may be in other formats, too! Ex.: 0x4C4F4E47
	return B_BENDIAN_TO_HOST_INT32(*(int32*)code);
}
Esempio n. 30
0
status_t
periph_check_capacity(scsi_periph_device_info *device, scsi_ccb *request)
{
	scsi_res_read_capacity capacityResult;
	scsi_cmd_read_capacity *cmd = (scsi_cmd_read_capacity *)request->cdb;
	uint64 capacity;
	uint32 blockSize;
	status_t res;

	SHOW_FLOW(3, "%p, %p", device, request);

	// driver doesn't support capacity callback - seems to be no block
	// device driver, so ignore
	if (device->callbacks->set_capacity == NULL)
		return B_OK;

	request->flags = SCSI_DIR_IN;

	request->data = (uint8*)&capacityResult;
	request->data_length = sizeof(capacityResult);
	request->cdb_length = sizeof(scsi_cmd_read_capacity);
	request->timeout = device->std_timeout;
	request->sort = -1;
	request->sg_list = NULL;

	memset(cmd, 0, sizeof(*cmd));
	cmd->opcode = SCSI_OP_READ_CAPACITY;
	// we don't set PMI (partial medium indicator) as we want the whole capacity;
	// in this case, all other parameters must be zero

	res = periph_safe_exec(device, request);

	if (res == B_DEV_MEDIA_CHANGED) {
		// in this case, the error handler has already called check_capacity
		// recursively, so we ignore our (invalid) result
		SHOW_FLOW0( 3, "ignore result because medium change" );
		return B_DEV_MEDIA_CHANGED;
	}

	ACQUIRE_BEN(&device->mutex);

	if (res == B_OK && request->data_resid == 0) {
		capacity = B_BENDIAN_TO_HOST_INT32(capacityResult.lba);

		// the command returns the index of the _last_ block,
		// i.e. the size is one larger
		++capacity;

		blockSize = B_BENDIAN_TO_HOST_INT32(capacityResult.block_size);
	} else {
		capacity = 0;
		blockSize = 0;
	}

	SHOW_FLOW(3, "capacity = %Ld, block_size = %ld", capacity, blockSize);

	device->block_size = blockSize;

	device->callbacks->set_capacity(device->periph_device,
		capacity, blockSize);

/*	device->byte2blk_shift = log2( device->block_size );
	if( device->byte2blk_shift < 0 ) {
		// this may be too restrictive...
		device->capacity = -1;
		return ERR_DEV_GENERAL;
	}*/

	RELEASE_BEN(&device->mutex);

	SHOW_FLOW(3, "done (%s)", strerror(res));

	return res;
}