예제 #1
0
void
PackageWriter::_WritePackageAttributes(hpkg_header& header)
{
	// write the package attributes
	off_t startOffset = fHeapEnd;
	FDDataWriter realWriter(fFD, startOffset);
	fDataWriter = &realWriter;

	_Write<uint8>(0);
		// TODO: Write them for real!
	fHeapEnd = realWriter.Offset();
	fDataWriter = NULL;

	off_t endOffset = fHeapEnd;

printf("package attributes size: %lld\n", endOffset - startOffset);

	// update the header
	header.attributes_compression = B_HOST_TO_BENDIAN_INT32(
		B_HPKG_COMPRESSION_NONE);
	header.attributes_length_compressed
		= B_HOST_TO_BENDIAN_INT32(endOffset - startOffset);
	header.attributes_length_uncompressed
		= header.attributes_length_compressed;
		// TODO: Support compression!
}
예제 #2
0
status_t
VolumeCryptContext::Setup(int fd, const uint8* key, uint32 keyLength,
	const uint8* random, uint32 randomLength)
{
	off_t size;
	status_t status = get_size(fd, size);
	if (status != B_OK)
		return status;

	fOffset = max_c(4096, BLOCK_SIZE);
	fSize = size - fOffset;
	fHidden = false;

	const uint8* salt = random;
	random += PKCS5_SALT_SIZE;

	uint8 buffer[BLOCK_SIZE];
	memcpy(buffer, salt, PKCS5_SALT_SIZE);
	memset(buffer + PKCS5_SALT_SIZE, 0, BLOCK_SIZE - PKCS5_SALT_SIZE);

	true_crypt_header& header = *(true_crypt_header*)&buffer[PKCS5_SALT_SIZE];
	header.magic = B_HOST_TO_BENDIAN_INT32(kTrueCryptMagic);
	header.version = B_HOST_TO_BENDIAN_INT16(0x4);
	header.required_program_version = B_HOST_TO_BENDIAN_INT16(0x600);
	header.volume_size = B_HOST_TO_BENDIAN_INT64(fSize);
	header.encrypted_offset = B_HOST_TO_BENDIAN_INT64(fOffset);
	header.encrypted_size = B_HOST_TO_BENDIAN_INT64(fSize);
	header.flags = 0;
	memcpy(header.disk_key, random, sizeof(header.disk_key));
	header.crc_checksum = B_HOST_TO_BENDIAN_INT32(crc32(header.disk_key, 256));
	header.header_crc_checksum
		= B_HOST_TO_BENDIAN_INT32(crc32((uint8*)&header, 188));

	return _WriteHeader(fd, key, keyLength, 0, buffer);
}
status_t
WebPTranslator::DerivedIdentify(BPositionIO* stream,
	const translation_format* format, BMessage* settings,
	translator_info* info, uint32 outType)
{
	if (!outType)
		outType = B_TRANSLATOR_BITMAP;
	if (outType != B_TRANSLATOR_BITMAP)
		return B_NO_TRANSLATOR;

	// Check RIFF and 'WEBPVP8 ' signatures...
	uint32 buf[4];
	ssize_t size = 16;
	if (stream->Read(buf, size) != size)
		return B_IO_ERROR;

	const uint32 kRIFFMagic = B_HOST_TO_BENDIAN_INT32('RIFF');
	const uint32 kWEBPMagic = B_HOST_TO_BENDIAN_INT32('WEBP');
	const uint32 kVP8Magic  = B_HOST_TO_BENDIAN_INT32('VP8 ');
	if (buf[0] != kRIFFMagic || buf[2] != kWEBPMagic || buf[3] != kVP8Magic)
		return B_ILLEGAL_DATA;

	info->type = WEBP_IMAGE_FORMAT;
	info->group = B_TRANSLATOR_BITMAP;
	info->quality = WEBP_IN_QUALITY;
	info->capability = WEBP_IN_CAPABILITY;
	snprintf(info->name, sizeof(info->name), B_TRANSLATE("WebP image"));
	strcpy(info->MIME, "image/webp");

	return B_OK;
}
예제 #4
0
void
AHCIPort::ScsiReadCapacity(scsi_ccb *request)
{
	TRACE("AHCIPort::ScsiReadCapacity port %d\n", fIndex);

	scsi_cmd_read_capacity *cmd = (scsi_cmd_read_capacity *)request->cdb;
	scsi_res_read_capacity scsiData;

	if (cmd->pmi || cmd->lba || request->data_length < sizeof(scsiData)) {
		TRACE("invalid request\n");
		return;
	}

	TRACE("SectorSize %lu, SectorCount 0x%llx\n", fSectorSize, fSectorCount);

	if (fSectorCount > 0xffffffff)
		panic("ahci: SCSI emulation doesn't support harddisks larger than 2TB");

	scsiData.block_size = B_HOST_TO_BENDIAN_INT32(fSectorSize);
	scsiData.lba = B_HOST_TO_BENDIAN_INT32(fSectorCount - 1);

	if (sg_memcpy(request->sg_list, request->sg_count, &scsiData, sizeof(scsiData)) < B_OK) {
		request->subsys_status = SCSI_DATA_RUN_ERR;
	} else {
		request->subsys_status = SCSI_REQ_CMP;
		request->data_resid = request->data_length - sizeof(scsiData);
	}
	gSCSI->finished(request, 1);
}
예제 #5
0
void
AHCIPort::ScsiReadCapacity(scsi_ccb *request)
{
    TRACE("AHCIPort::ScsiReadCapacity port %d\n", fIndex);

    const scsi_cmd_read_capacity *cmd = (const scsi_cmd_read_capacity *)request->cdb;
    scsi_res_read_capacity scsiData;

    if (cmd->pmi || cmd->lba || request->data_length < sizeof(scsiData)) {
        TRACE("invalid request\n");
        request->subsys_status = SCSI_REQ_ABORTED;
        gSCSI->finished(request, 1);
        return;
    }

    TRACE("SectorSize %" B_PRIu32 ", SectorCount 0x%" B_PRIx64 "\n",
          fSectorSize, fSectorCount);

    scsiData.block_size = B_HOST_TO_BENDIAN_INT32(fSectorSize);

    if (fSectorCount <= 0xffffffff)
        scsiData.lba = B_HOST_TO_BENDIAN_INT32(fSectorCount - 1);
    else
        scsiData.lba = 0xffffffff;

    if (sg_memcpy(request->sg_list, request->sg_count, &scsiData,
                  sizeof(scsiData)) < B_OK) {
        request->subsys_status = SCSI_DATA_RUN_ERR;
    } else {
        request->subsys_status = SCSI_REQ_CMP;
        request->data_resid = request->data_length - sizeof(scsiData);
    }
    gSCSI->finished(request, 1);
}
예제 #6
0
// ---------------------------------------------------------------
// BitsCheck
//
// Examines the input stream for B_TRANSLATOR_BITMAP format 
// information and determines if BaseTranslator can handle
// the translation entirely, if it must pass the task of
// translation to the derived translator or if the stream cannot
// be decoded by the BaseTranslator or the derived translator.
//
// Preconditions:
//
// Parameters:	inSource,	where the data to examine is
//
//				ioExtension,	configuration settings for the
//								translator
//
//				outType,	The format that the user wants
//							the data in inSource to be
//							converted to. NOTE: This is passed by
//							reference so that it can modify the
//							outType that is seen by the
//							BaseTranslator and the derived
//							translator
//
// Postconditions:
//
// Returns: B_NO_TRANSLATOR,	if this translator can't handle
//								the data in inSource
//
// B_ERROR,	if there was an error converting the data to the host
//			format
//
// B_BAD_VALUE, if the settings in ioExtension are bad
//
// B_OK,	if this translator understand the data and there were
//			no errors found
// ---------------------------------------------------------------
status_t
BaseTranslator::BitsCheck(BPositionIO *inSource, BMessage *ioExtension,
	uint32 &outType)
{
	if (!outType)
		outType = B_TRANSLATOR_BITMAP;
	if (outType != B_TRANSLATOR_BITMAP && outType != fTranType)
		return B_NO_TRANSLATOR;

	// Convert the magic numbers to the various byte orders so that
	// I won't have to convert the data read in to see whether or not
	// it is a supported type
	const uint32 kBitsMagic = B_HOST_TO_BENDIAN_INT32(B_TRANSLATOR_BITMAP);
	
	// Read in the magic number and determine if it
	// is a supported type
	uint8 ch[4];
	if (inSource->Read(ch, 4) != 4)
		return B_NO_TRANSLATOR;
	inSource->Seek(-4, SEEK_CUR);
		// seek backward becuase functions used after this one
		// expect the stream to be at the beginning
		
	// Read settings from ioExtension
	if (ioExtension && fSettings->LoadSettings(ioExtension) < B_OK)
		return B_BAD_VALUE;
	
	uint32 sourceMagic;
	memcpy(&sourceMagic, ch, sizeof(uint32));
	if (sourceMagic == kBitsMagic)
		return B_OK;
	else
		return B_OK + 1;
}
예제 #7
0
// convert passed number to a string of 4 characters
// and return that string
const char *
char_format(uint32 num)
{
	static char str[5] = { 0 };
	uint32 bnum = B_HOST_TO_BENDIAN_INT32(num);
	memcpy(str, &bnum, 4);

	return str;
}
예제 #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;
}
예제 #9
0
static status_t
read_cd(cd_driver_info *info, const scsi_read_cd *readCD)
{
	scsi_cmd_read_cd *cmd;
	uint32 lba, length;
	scsi_ccb *ccb;
	status_t res;

	// we use safe_exec instead of simple_exec as we want to set
	// the sorting order manually (only makes much sense if you grab
	// multiple tracks at once, but we are prepared)
	ccb = info->scsi->alloc_ccb(info->scsi_device);

	if (ccb == NULL)
		return B_NO_MEMORY;

	cmd = (scsi_cmd_read_cd *)ccb->cdb;
	memset(cmd, 0, sizeof(*cmd));
	cmd->opcode = SCSI_OP_READ_CD;
	cmd->sector_type = 1;

	// skip first two seconds, they are lead-in
	lba = (readCD->start_m * 60 + readCD->start_s) * 75 + readCD->start_f
		- 2 * 75;
	length = (readCD->length_m * 60 + readCD->length_s) * 75 + readCD->length_f;

	cmd->lba = B_HOST_TO_BENDIAN_INT32(lba);
	cmd->high_length = (length >> 16) & 0xff;
	cmd->mid_length = (length >> 8) & 0xff;
	cmd->low_length = length & 0xff;

	cmd->error_field = scsi_read_cd_error_none;
	cmd->edc_ecc = 0;
	cmd->user_data = 1;
	cmd->header_code = scsi_read_cd_header_none;
	cmd->sync = 0;
	cmd->sub_channel_selection = scsi_read_cd_sub_channel_none;

	ccb->cdb_length = sizeof(*cmd);

	ccb->flags = SCSI_DIR_IN | SCSI_DIS_DISCONNECT;
	ccb->sort = lba;
	// are 10 seconds enough for timeout?
	ccb->timeout = 10;

	// TODO: we pass a user buffer here!
	ccb->data = (uint8 *)readCD->buffer;
	ccb->sg_list = NULL;
	ccb->data_length = readCD->buffer_length;

	res = sSCSIPeripheral->safe_exec(info->scsi_periph_device, ccb);

	info->scsi->free_ccb(ccb);

	return res;
}
예제 #10
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;
}
예제 #11
0
파일: scsi2ata.c 프로젝트: luciang/haiku
/*! Emulate READ CAPACITY command */
static void
read_capacity(ide_device_info *device, ide_qrequest *qrequest)
{
	scsi_ccb *request = qrequest->request;
	scsi_res_read_capacity data;
	scsi_cmd_read_capacity *cmd = (scsi_cmd_read_capacity *)request->cdb;
	uint32 lastBlock;

	if (cmd->pmi || cmd->lba) {
		set_sense(device, SCSIS_KEY_ILLEGAL_REQUEST, SCSIS_ASC_INV_CDB_FIELD);
		return;
	}

	// TODO: 512 bytes fixed block size?
	data.block_size = B_HOST_TO_BENDIAN_INT32(512);

	lastBlock = device->total_sectors - 1;
	data.lba = B_HOST_TO_BENDIAN_INT32(lastBlock);

	copy_sg_data(request, 0, request->data_length, &data, sizeof(data), false);
	request->data_resid = max(request->data_length - sizeof(data), 0);
}
예제 #12
0
status_t
VolumeCryptContext::SetPassword(int fd, const uint8* oldKey,
	uint32 oldKeyLength, const uint8* newKey, uint32 newKeyLength)
{
	off_t headerOffset;
	uint8 buffer[BLOCK_SIZE];
	true_crypt_header header;
	status_t status = _Detect(fd, oldKey, oldKeyLength, headerOffset, buffer,
		header);
	if (status != B_OK)
		return status;

//	header.required_program_version = B_HOST_TO_BENDIAN_INT16(0x800);
	header.volume_size = B_HOST_TO_BENDIAN_INT64(fSize);
	header.crc_checksum = B_HOST_TO_BENDIAN_INT32(crc32(header.disk_key, 256));
	header.header_crc_checksum
		= B_HOST_TO_BENDIAN_INT32(crc32((uint8*)&header, 188));
	memcpy(buffer + PKCS5_SALT_SIZE, &header, sizeof(true_crypt_header));

dprintf("HEADER OFFSET: %Ld\n", headerOffset);
dprintf("NEW KEY: %s\n", newKey);
	return _WriteHeader(fd, newKey, newKeyLength, headerOffset, buffer);
}
예제 #13
0
void
PackageWriter::_WriteTOC(hpkg_header& header)
{
	// prepare the writer (zlib writer on top of a file writer)
	off_t startOffset = fHeapEnd;
	FDDataWriter realWriter(fFD, startOffset);
	ZlibDataWriter zlibWriter(&realWriter);
	fDataWriter = &zlibWriter;
	zlibWriter.Init();

	// write the sections
	uint64 uncompressedAttributeTypesSize;
	uint64 uncompressedStringsSize;
	uint64 uncompressedMainSize;
	int32 cachedStringsWritten = _WriteTOCSections(
		uncompressedAttributeTypesSize, uncompressedStringsSize,
		uncompressedMainSize);

	// finish the writer
	zlibWriter.Finish();
	fHeapEnd = realWriter.Offset();
	fDataWriter = NULL;

printf("attributes types size:   %llu\n", uncompressedAttributeTypesSize);
printf("cached strings size:     %llu\n", uncompressedStringsSize);
printf("TOC main size:           %llu\n", uncompressedMainSize);
	off_t endOffset = fHeapEnd;
printf("total TOC size:          %llu (%llu)\n", endOffset - startOffset, zlibWriter.BytesWritten());

	// update the header

	// TOC
	header.toc_compression = B_HOST_TO_BENDIAN_INT32(B_HPKG_COMPRESSION_ZLIB);
	header.toc_length_compressed = B_HOST_TO_BENDIAN_INT64(
		endOffset - startOffset);
	header.toc_length_uncompressed = B_HOST_TO_BENDIAN_INT64(
		zlibWriter.BytesWritten());

	// TOC subsections
	header.toc_attribute_types_length = B_HOST_TO_BENDIAN_INT64(
		uncompressedAttributeTypesSize);
	header.toc_attribute_types_count = B_HOST_TO_BENDIAN_INT64(
		fAttributeTypes->CountElements());
	header.toc_strings_length = B_HOST_TO_BENDIAN_INT64(
		uncompressedStringsSize);
	header.toc_strings_count = B_HOST_TO_BENDIAN_INT64(cachedStringsWritten);
}
예제 #14
0
파일: ahci_port.cpp 프로젝트: DonCN/haiku
void
AHCIPort::ScsiReadCapacity16(scsi_ccb* request)
{
	TRACE("AHCIPort::ScsiReadCapacity16 port %d\n", fIndex);

	scsi_res_read_capacity_long scsiData;

	TRACE("SectorSize %" B_PRIu32 ", SectorCount 0x%" B_PRIx64 "\n",
		fSectorSize, fSectorCount);

	scsiData.block_size = B_HOST_TO_BENDIAN_INT32(fSectorSize);
	scsiData.lba = B_HOST_TO_BENDIAN_INT64(fSectorCount - 1);

	if (sg_memcpy(request->sg_list, request->sg_count, &scsiData,
			sizeof(scsiData)) < B_OK) {
		request->subsys_status = SCSI_DATA_RUN_ERR;
	} else {
		request->subsys_status = SCSI_REQ_CMP;
		request->data_resid = request->data_length - sizeof(scsiData);
	}
	gSCSI->finished(request, 1);
}
예제 #15
0
status_t
PackageWriter::_Finish()
{
	// write entries
	for (EntryList::ConstIterator it = fRootEntry->ChildIterator();
			Entry* entry = it.Next();) {
		_AddEntry(AT_FDCWD, entry, entry->Name());
	}

printf("header size:             %lu\n", sizeof(hpkg_header));
printf("heap size:               %lld\n", fHeapEnd - sizeof(hpkg_header));

	hpkg_header header;

	// write the TOC and package attributes
	_WriteTOC(header);
	_WritePackageAttributes(header);

	off_t totalSize = fHeapEnd;
printf("total size:              %lld\n", totalSize);

	// prepare the header

	// general
	header.magic = B_HOST_TO_BENDIAN_INT32(B_HPKG_MAGIC);
	header.header_size = B_HOST_TO_BENDIAN_INT16(
		(uint16)sizeof(hpkg_header));
	header.version = B_HOST_TO_BENDIAN_INT16(B_HPKG_VERSION);
	header.total_size = B_HOST_TO_BENDIAN_INT64(totalSize);

	// write the header
	_WriteBuffer(&header, sizeof(hpkg_header), 0);

	fFinished = true;
	return B_OK;
}
예제 #16
0
// Export
status_t
MessageExporter::Export(const Icon* icon, BPositionIO* stream)
{
	status_t ret = B_OK;
	BMessage archive;

	PathContainer* paths = icon->Paths();
	StyleContainer* styles = icon->Styles();

	// paths
	if (ret == B_OK) {
		BMessage allPaths;
		int32 count = paths->CountPaths();
		for (int32 i = 0; i < count; i++) {
			VectorPath* path = paths->PathAtFast(i);
			BMessage pathArchive;
			ret = _Export(path, &pathArchive);
			if (ret < B_OK)
				break;
			ret = allPaths.AddMessage("path", &pathArchive);
			if (ret < B_OK)
				break;
		}
	
		if (ret == B_OK)
			ret = archive.AddMessage("paths", &allPaths);
	}

	// styles
	if (ret == B_OK) {
		BMessage allStyles;
		int32 count = styles->CountStyles();
		for (int32 i = 0; i < count; i++) {
			Style* style = styles->StyleAtFast(i);
			BMessage styleArchive;
			ret = _Export(style, &styleArchive);
			if (ret < B_OK)
				break;
			ret = allStyles.AddMessage("style", &styleArchive);
			if (ret < B_OK)
				break;
		}
	
		if (ret == B_OK)
			ret = archive.AddMessage("styles", &allStyles);
	}

	// shapes
	if (ret == B_OK) {
		BMessage allShapes;
		ShapeContainer* shapes = icon->Shapes();
		int32 count = shapes->CountShapes();
		for (int32 i = 0; i < count; i++) {
			Shape* shape = shapes->ShapeAtFast(i);
			BMessage shapeArchive;
			ret = _Export(shape, paths, styles, &shapeArchive);
			if (ret < B_OK)
				break;
			ret = allShapes.AddMessage("shape", &shapeArchive);
			if (ret < B_OK)
				break;
		}
	
		if (ret == B_OK)
			ret = archive.AddMessage("shapes", &allShapes);
	}

	// prepend the magic number to the file which
	// later tells us that this file is one of us
	if (ret == B_OK) {
		ssize_t size = sizeof(uint32);
		uint32 magic = B_HOST_TO_BENDIAN_INT32(kNativeIconMagicNumber);
		ssize_t written = stream->Write(&magic, size);
		if (written != size) {
			if (written < 0)
				ret = (status_t)written;
			else
				ret = B_IO_ERROR;
		}
	}

	if (ret == B_OK)
		ret = archive.Flatten(stream);

	return ret;
}
예제 #17
0
파일: FLAP.cpp 프로젝트: louisdem/IMKit
status_t Flap::AddInt32(int32 value) {
	int32 v = B_HOST_TO_BENDIAN_INT32(value);
	return AddRawData((uchar *)&v, sizeof(value));
};
예제 #18
0
파일: io.cpp 프로젝트: DonCN/haiku
/*! Universal read/write function */
static status_t
read_write(scsi_periph_device_info *device, scsi_ccb *request,
	io_operation *operation, uint64 offset, size_t originalNumBlocks,
	physical_entry* vecs, size_t vecCount, bool isWrite,
	size_t* _bytesTransferred)
{
	uint32 blockSize = device->block_size;
	size_t numBlocks = originalNumBlocks;
	uint32 pos = offset;
	err_res res;
	int retries = 0;

	do {
		size_t numBytes;
		bool isReadWrite10 = false;

		request->flags = isWrite ? SCSI_DIR_OUT : SCSI_DIR_IN;

		// io_operations are generated by a DMAResource and thus contain DMA
		// safe physical vectors
		if (operation != NULL)
			request->flags |= SCSI_DMA_SAFE;

		// make sure we avoid 10 byte commands if they aren't supported
		if (!device->rw10_enabled || device->preferred_ccb_size == 6) {
			// restricting transfer is OK - the block manager will
			// take care of transferring the rest
			if (numBlocks > 0x100)
				numBlocks = 0x100;

			// no way to break the 21 bit address limit
			if (offset > 0x200000)
				return B_BAD_VALUE;

			// don't allow transfer cross the 24 bit address limit
			// (I'm not sure whether this is allowed, but this way we
			// are sure to not ask for trouble)
			if (offset < 0x100000)
				numBlocks = min_c(numBlocks, 0x100000 - pos);
		}

		numBytes = numBlocks * blockSize;
		if (numBlocks != originalNumBlocks)
			panic("I/O operation would need to be cut.");

		request->data = NULL;
		request->sg_list = vecs;
		request->data_length = numBytes;
		request->sg_count = vecCount;
		request->io_operation = operation;
		request->sort = pos;
		request->timeout = device->std_timeout;
		// see whether daemon instructed us to post an ordered command;
		// reset flag after read
		SHOW_FLOW(3, "flag=%x, next_tag=%x, ordered: %s",
			(int)request->flags, (int)device->next_tag_action,
			(request->flags & SCSI_ORDERED_QTAG) != 0 ? "yes" : "no");

		// use shortest commands whenever possible
		if (offset + numBlocks < 0x200000LL && numBlocks <= 0x100) {
			scsi_cmd_rw_6 *cmd = (scsi_cmd_rw_6 *)request->cdb;

			isReadWrite10 = false;

			memset(cmd, 0, sizeof(*cmd));
			cmd->opcode = isWrite ? SCSI_OP_WRITE_6 : SCSI_OP_READ_6;
			cmd->high_lba = (pos >> 16) & 0x1f;
			cmd->mid_lba = (pos >> 8) & 0xff;
			cmd->low_lba = pos & 0xff;
			cmd->length = numBlocks;

			request->cdb_length = sizeof(*cmd);
		} else if (offset + numBlocks < 0x100000000LL && numBlocks <= 0x10000) {
			scsi_cmd_rw_10 *cmd = (scsi_cmd_rw_10 *)request->cdb;

			isReadWrite10 = true;

			memset(cmd, 0, sizeof(*cmd));
			cmd->opcode = isWrite ? SCSI_OP_WRITE_10 : SCSI_OP_READ_10;
			cmd->relative_address = 0;
			cmd->force_unit_access = 0;
			cmd->disable_page_out = 0;
			cmd->lba = B_HOST_TO_BENDIAN_INT32(pos);
			cmd->length = B_HOST_TO_BENDIAN_INT16(numBlocks);

			request->cdb_length = sizeof(*cmd);
		} else if (offset + numBlocks < 0x100000000LL && numBlocks <= 0x10000000) {
			scsi_cmd_rw_12 *cmd = (scsi_cmd_rw_12 *)request->cdb;

			memset(cmd, 0, sizeof(*cmd));
			cmd->opcode = isWrite ? SCSI_OP_WRITE_12 : SCSI_OP_READ_12;
			cmd->relative_address = 0;
			cmd->force_unit_access = 0;
			cmd->disable_page_out = 0;
			cmd->lba = B_HOST_TO_BENDIAN_INT32(pos);
			cmd->length = B_HOST_TO_BENDIAN_INT32(numBlocks);

			request->cdb_length = sizeof(*cmd);
		} else {
			scsi_cmd_rw_16 *cmd = (scsi_cmd_rw_16 *)request->cdb;

			memset(cmd, 0, sizeof(*cmd));
			cmd->opcode = isWrite ? SCSI_OP_WRITE_16 : SCSI_OP_READ_16;
			cmd->force_unit_access_non_volatile = 0;
			cmd->force_unit_access = 0;
			cmd->disable_page_out = 0;
			cmd->lba = B_HOST_TO_BENDIAN_INT64(offset);
			cmd->length = B_HOST_TO_BENDIAN_INT32(numBlocks);

			request->cdb_length = sizeof(*cmd);
		}

		// TODO: last chance to detect errors that occured during concurrent accesses
		//status_t status = handle->pending_error;
		//if (status != B_OK)
		//	return status;

		device->scsi->async_io(request);

		acquire_sem(request->completion_sem);

		// ask generic peripheral layer what to do now
		res = periph_check_error(device, request);

		// TODO: bytes might have been transferred even in the error case!
		switch (res.action) {
			case err_act_ok:
				*_bytesTransferred = numBytes - request->data_resid;
				break;

			case err_act_start:
				res = periph_send_start_stop(device, request, 1,
					device->removable);
				if (res.action == err_act_ok)
					res.action = err_act_retry;
				break;

			case err_act_invalid_req:
				// if this was a 10 byte command, the device probably doesn't
				// support them, so disable them and retry
				if (isReadWrite10) {
					atomic_and(&device->rw10_enabled, 0);
					res.action = err_act_retry;
				} else
					res.action = err_act_fail;
				break;
		}
	} while ((res.action == err_act_retry && retries++ < 3)
예제 #19
0
파일: MemoryView.cpp 프로젝트: dnivra/haiku
void
MemoryView::_GetNextHexBlock(char* buffer, int32 bufferSize,
	const char* address)
{
	switch(fHexMode) {
		case HexMode8BitInt:
		{
			snprintf(buffer, bufferSize, "%02" B_PRIx8,
				*((const uint8*)address));
			break;
		}
		case HexMode16BitInt:
		{
			uint16 data = *((const uint16*)address);
			switch(fCurrentEndianMode)
			{
				case EndianModeBigEndian:
				{
					data = B_HOST_TO_BENDIAN_INT16(data);
				}
				break;

				case EndianModeLittleEndian:
				{
					data = B_HOST_TO_LENDIAN_INT16(data);
				}
				break;
			}
			snprintf(buffer, bufferSize, "%04" B_PRIx16,
				data);
			break;
		}
		case HexMode32BitInt:
		{
			uint32 data = *((const uint32*)address);
			switch(fCurrentEndianMode)
			{
				case EndianModeBigEndian:
				{
					data = B_HOST_TO_BENDIAN_INT32(data);
				}
				break;

				case EndianModeLittleEndian:
				{
					data = B_HOST_TO_LENDIAN_INT32(data);
				}
				break;
			}
			snprintf(buffer, bufferSize, "%08" B_PRIx32,
				data);
			break;
		}
		case HexMode64BitInt:
		{
			uint64 data = *((const uint64*)address);
			switch(fCurrentEndianMode)
			{
				case EndianModeBigEndian:
				{
					data = B_HOST_TO_BENDIAN_INT64(data);
				}
				break;

				case EndianModeLittleEndian:
				{
					data = B_HOST_TO_LENDIAN_INT64(data);
				}
				break;
			}
			snprintf(buffer, bufferSize, "%0*" B_PRIx64,
				16, data);
			break;
		}
	}
}
예제 #20
0
void
PackageWriter::_WriteAttributeValue(const AttributeValue& value, uint8 encoding)
{
	switch (value.type) {
		case B_HPKG_ATTRIBUTE_TYPE_INT:
		case B_HPKG_ATTRIBUTE_TYPE_UINT:
		{
			uint64 intValue = value.type == B_HPKG_ATTRIBUTE_TYPE_INT
				? (uint64)value.signedInt : value.unsignedInt;

			switch (encoding) {
				case B_HPKG_ATTRIBUTE_ENCODING_INT_8_BIT:
					_Write<uint8>((uint8)intValue);
					break;
				case B_HPKG_ATTRIBUTE_ENCODING_INT_16_BIT:
					_Write<uint16>(
						B_HOST_TO_BENDIAN_INT16((uint16)intValue));
					break;
				case B_HPKG_ATTRIBUTE_ENCODING_INT_32_BIT:
					_Write<uint32>(
						B_HOST_TO_BENDIAN_INT32((uint32)intValue));
					break;
				case B_HPKG_ATTRIBUTE_ENCODING_INT_64_BIT:
					_Write<uint64>(
						B_HOST_TO_BENDIAN_INT64((uint64)intValue));
					break;
				default:
				{
					fprintf(stderr, "_WriteAttributeValue(): invalid "
						"encoding %d for int value type %d\n", encoding,
						value.type);
					throw status_t(B_BAD_VALUE);
				}
			}

			break;
		}

		case B_HPKG_ATTRIBUTE_TYPE_STRING:
		{
			if (encoding == B_HPKG_ATTRIBUTE_ENCODING_STRING_TABLE)
				_WriteUnsignedLEB128(value.string->index);
			else
				_WriteString(value.string->string);
			break;
		}

		case B_HPKG_ATTRIBUTE_TYPE_RAW:
		{
			_WriteUnsignedLEB128(value.data.size);
			if (encoding == B_HPKG_ATTRIBUTE_ENCODING_RAW_HEAP)
				_WriteUnsignedLEB128(value.data.offset);
			else
				fDataWriter->WriteDataThrows(value.data.raw, value.data.size);
			break;
		}

		default:
			fprintf(stderr, "_WriteAttributeValue(): invalid value type: "
				"%d\n", value.type);
			throw status_t(B_BAD_VALUE);
	}
}
예제 #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;
}
예제 #22
0
void
ResourceType::CodeToString(type_code code, char* str)
{
	*(type_code*)str = B_HOST_TO_BENDIAN_INT32(code);
	str[4] = '\0';
}
예제 #23
0
bool
GIFLoad::ReadGIFImageHeader()
{
	unsigned char data[9];
	if (fInput->Read(data, 9) < 9)
		return false;

	int left = data[0] + (data[1] << 8);
	int top = data[2] + (data[3] << 8);
	int localWidth = data[4] + (data[5] << 8);
	int localHeight = data[6] + (data[7] << 8);
	if (fWidth != localWidth || fHeight != localHeight) {
		if (debug) {
			syslog(LOG_ERR, "GIFLoad::ReadGIFImageHeader() - "
				"Local dimensions do not match global, setting to %d x %d\n",
				localWidth, localHeight);
		}
		fWidth = localWidth;
		fHeight = localHeight;
	}

	fScanLine = (uint32*)malloc(fWidth * 4);
	if (fScanLine == NULL) {
		if (debug) {
			syslog(LOG_ERR, "GIFLoad::ReadGIFImageHeader() - "
				"Could not allocate scanline\n");
		}
		return false;
	}

	BRect rect(left, top, left + fWidth - 1, top + fHeight - 1);
	TranslatorBitmap header;
	header.magic = B_HOST_TO_BENDIAN_INT32(B_TRANSLATOR_BITMAP);
	header.bounds.left = B_HOST_TO_BENDIAN_FLOAT(rect.left);
	header.bounds.top = B_HOST_TO_BENDIAN_FLOAT(rect.top);
	header.bounds.right = B_HOST_TO_BENDIAN_FLOAT(rect.right);
	header.bounds.bottom = B_HOST_TO_BENDIAN_FLOAT(rect.bottom);
	header.rowBytes = B_HOST_TO_BENDIAN_INT32(fWidth * 4);
	header.colors = (color_space)B_HOST_TO_BENDIAN_INT32(B_RGBA32);
	header.dataSize = B_HOST_TO_BENDIAN_INT32(fWidth * 4 * fHeight);
	if (fOutput->Write(&header, 32) < 32)
		return false;

	if (data[8] & GIF_LOCALCOLORMAP) {
		// has local palette
		fPalette->size_in_bits = (data[8] & 0x07) + 1;
		int s = 1 << fPalette->size_in_bits;
		fPalette->size = s;
		if (debug) {
			syslog(LOG_INFO, "GIFLoad::ReadGIFImageHeader() - "
				"Found %d bit local palette\n", fPalette->size_in_bits);
		}

		unsigned char lp[256 * 3];
		if (fInput->Read(lp, s * 3) < s * 3)
			return false;

		for (int x = 0; x < s; x++)
			fPalette->SetColor(x, lp[x * 3], lp[x * 3 + 1], lp[x * 3 + 2]);
	}

	fInterlaced = data[8] & GIF_INTERLACED;
	if (debug) {
		if (fInterlaced) {
			syslog(LOG_INFO, "GIFLoad::ReadGIFImageHeader() - "
				"Image is interlaced\n");
		} else {
			syslog(LOG_INFO, "GIFLoad::ReadGIFImageHeader() - "
				"Image is not interlaced\n");
		}
	}

	return true;
}
예제 #24
0
status_t
BNetBuffer::AppendUint32(uint32 data)
{
	uint32 be_data = B_HOST_TO_BENDIAN_INT32(data);
	return AppendData((const void*)&be_data, sizeof(uint32));
}
예제 #25
0
// _Broadcaster
int32
NetFSServer::_Broadcaster()
{
	// create the socket
	fBroadcastingSocket = socket(AF_INET, SOCK_DGRAM, 0);
	if (fBroadcastingSocket < 0) {
		WARN("NetFSServer::_Broadcaster(): WARN: Failed to init broadcasting: "
			"%s.\n", strerror(errno));
		return errno;
	}

	// set the socket broadcast option
	#ifndef HAIKU_TARGET_PLATFORM_BEOS
		int soBroadcastValue = 1;
		if (setsockopt(fBroadcastingSocket, SOL_SOCKET, SO_BROADCAST,
			&soBroadcastValue, sizeof(soBroadcastValue)) < 0) {
			WARN("NetFSServer::_Broadcaster(): WARN: Failed to set "
				"SO_BROADCAST on socket: %s.\n", strerror(errno));
		}
	#endif

	// prepare the broadcast message
	BroadcastMessage message;
	message.magic = B_HOST_TO_BENDIAN_INT32(BROADCAST_MESSAGE_MAGIC);
	message.protocolVersion = B_HOST_TO_BENDIAN_INT32(NETFS_PROTOCOL_VERSION);

	bool update = false;
	while (!fTerminating) {
		// set tick/update
		uint32 messageCode = (update ? BROADCAST_MESSAGE_SERVER_UPDATE
			: BROADCAST_MESSAGE_SERVER_TICK);
		message.message = B_HOST_TO_BENDIAN_INT32(messageCode);

		// send broadcasting message
		sockaddr_in addr;
		addr.sin_family = AF_INET;
		addr.sin_port = htons(kDefaultBroadcastPort);
		addr.sin_addr.s_addr = INADDR_BROADCAST;
		int addrSize = sizeof(addr);
		ssize_t bytesSent = sendto(fBroadcastingSocket, &message,
			sizeof(message), 0, (sockaddr*)&addr, addrSize);
		if (bytesSent < 0) {
			WARN("NetFSServer::_Broadcaster(): WARN: sending failed: %s.\n",
				strerror(errno));
			return errno;
		}

		// snooze a bit
		// we snooze a minimal interval to avoid shooting updates like a
		// machine gun
		snooze(kMinBroadcastingInterval);
		bigtime_t remainingTime = kBroadcastingInterval
			- kMinBroadcastingInterval;

		// snooze the rest blocking on our semaphore (if it exists)
		if (fBroadcasterSemaphore >= 0) {
			status_t snoozeError = acquire_sem_etc(fBroadcasterSemaphore, 1,
				B_RELATIVE_TIMEOUT, remainingTime);

			// set the semaphore count back to zero
			while (snoozeError == B_OK) {
				snoozeError = acquire_sem_etc(fBroadcasterSemaphore, 1,
					B_RELATIVE_TIMEOUT, 0);
			}
		} else
			snooze(remainingTime);

		update = atomic_and(&fServerInfoUpdated, 0);
	}

	// close the socket
	safe_closesocket(fBroadcastingSocket);
	return B_OK;
}
예제 #26
0
파일: MainApp.cpp 프로젝트: DonCN/haiku
void
MainApp::_InstallPlaylistMimeType()
{
	// install mime type of documents
	BMimeType mime(kBinaryPlaylistMimeString);
	status_t ret = mime.InitCheck();
	if (ret != B_OK) {
		fprintf(stderr, "Could not init native document mime type (%s): %s.\n",
			kBinaryPlaylistMimeString, strerror(ret));
		return;
	}

	if (mime.IsInstalled() && !(modifiers() & B_SHIFT_KEY)) {
		// mime is already installed, and the user is not
		// pressing the shift key to force a re-install
		return;
	}

	ret = mime.Install();
	if (ret != B_OK && ret != B_FILE_EXISTS) {
		fprintf(stderr, "Could not install native document mime type (%s): %s.\n",
			kBinaryPlaylistMimeString, strerror(ret));
		return;
	}
	// set preferred app
	ret = mime.SetPreferredApp(kAppSig);
	if (ret != B_OK) {
		fprintf(stderr, "Could not set native document preferred app: %s\n",
			strerror(ret));
	}

	// set descriptions
	ret = mime.SetShortDescription("MediaPlayer playlist");
	if (ret != B_OK) {
		fprintf(stderr, "Could not set short description of mime type: %s\n",
			strerror(ret));
	}
	ret = mime.SetLongDescription("MediaPlayer binary playlist file");
	if (ret != B_OK) {
		fprintf(stderr, "Could not set long description of mime type: %s\n",
			strerror(ret));
	}

	// set extensions
	BMessage message('extn');
	message.AddString("extensions", "playlist");
	ret = mime.SetFileExtensions(&message);
	if (ret != B_OK) {
		fprintf(stderr, "Could not set extensions of mime type: %s\n",
			strerror(ret));
	}

	// set sniffer rule
	char snifferRule[32];
	uint32 bigEndianMagic = B_HOST_TO_BENDIAN_INT32(kPlaylistMagicBytes);
	sprintf(snifferRule, "0.9 ('%4s')", (const char*)&bigEndianMagic);
	ret = mime.SetSnifferRule(snifferRule);
	if (ret != B_OK) {
		BString parseError;
		BMimeType::CheckSnifferRule(snifferRule, &parseError);
		fprintf(stderr, "Could not set sniffer rule of mime type: %s\n",
			parseError.String());
	}

	// set playlist icon
	BResources* resources = AppResources();
		// does not need to be freed (belongs to BApplication base)
	if (resources != NULL) {
		size_t size;
		const void* iconData = resources->LoadResource('VICN', "PlaylistIcon",
			&size);
		if (iconData != NULL && size > 0) {
			if (mime.SetIcon(reinterpret_cast<const uint8*>(iconData), size)
				!= B_OK) {
				fprintf(stderr, "Could not set vector icon of mime type.\n");
			}
		} else {
			fprintf(stderr, "Could not find icon in app resources "
				"(data: %p, size: %ld).\n", iconData, size);
		}
	} else
		fprintf(stderr, "Could not find app resources.\n");
}