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; } }
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; }
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); }
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; }
// -------------------------------------------------- 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); }
//! 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; }
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; }
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; }
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; }
//------------------------------------------------------------------------------ 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); } }
// --------------------------------------------------------------- // 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; }
//! 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; }
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); } }
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); } }
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; } }
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; }
uint32 Magic() const { return B_BENDIAN_TO_HOST_INT32(magic); }
uint32 CrcChecksum() const { return B_BENDIAN_TO_HOST_INT32(crc_checksum); }
// _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; }
/*! 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); }
uint32 HeaderCrcChecksum() const { return B_BENDIAN_TO_HOST_INT32(header_crc_checksum); }
uint32 Flags() const { return B_BENDIAN_TO_HOST_INT32(flags); }
uint32 BlockSize() const { return B_BENDIAN_TO_HOST_INT32(block_size); }
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); }
/*! \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 } }
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); } }
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); }
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; }