static bool ParseVehicleWeaponDefinition(WeaponDef &def, tinyxml2::XMLElement *root) { //FIXME: A lot of these could be shared for all weapon types? if (!ReadAttribute(root, "projectile", std::map<UString, WeaponDef::ProjectileType>{{"beam", WeaponDef::ProjectileType::Beam}}, def.projectileType)) { LogWarning("Failed to read 'projectile' attribute"); return false; } /* firingSFX is optional */ def.firingSFX = root->Attribute("firingSFX"); /* pointDefence is optional */ ReadAttribute(root, "pointDefence", def.pointDefence, false); /* arc is optional */ ReadAttribute(root, "arc", def.arc, 0.0f); /* accuracy is optional */ ReadAttribute(root, "accuracy", def.accuracy, 0.0f); /* range is required */ if (!ReadAttribute(root, "range", def.range)) { LogWarning("Failed to read 'range' attribute"); return false; } //FIXME: Figure out range units. For now treating at '1/10 tiles' def.range /= 10.0f; /* firingDelay is required */ if (!ReadAttribute(root, "firingDelay", def.firingDelay)) { LogWarning("Failed to read 'firingDelay' attribute"); return false; } /* projectileDamage is required */ if (!ReadAttribute(root, "projectileDamage", def.projectileDamage)) { LogWarning("Failed to read 'projectileDamage' attribute"); return false; } /* projetileTailLength is optional */ ReadAttribute(root, "projectileTailLength", def.projectileTailLength, 0.0f); //FIXME: Figure out tail length units. For now treating at '1/10 tiles' def.projectileTailLength /= 10.0f; /* projectileSpeed is required */ if (!ReadAttribute(root, "projectileSpeed", def.projectileSpeed)) { LogWarning("Failed to read 'projectileSpeed' attribute"); return false; } //FIXME: Figure out speed units. For now treating as 1/100 tiles per tick def.projectileSpeed /= 100.0f; /* projectileTurnRate is optional */ ReadAttribute(root, "projectileTurnRate", def.projectileTurnRate, 0.0f); /* hitSprite is optional */ def.hitSprite = root->Attribute("hitSprite"); /* beamWidth is optional */ ReadAttribute(root, "beamWidth", def.beamWidth, 1.0f); /* beamColour is optional */ ReadAttribute(root, "beamColour", def.beamColour, Colour{255,255,255,255}); /* ammoCapacity is required */ if (!ReadAttribute(root, "ammoCapacity", def.ammoCapacity)) { LogWarning("Failed to read 'ammoCapacity' attribute"); return false; } /* ammoPerShot is optional */ ReadAttribute(root, "ammoPerShot", def.ammoPerShot, 1); def.ammoType = root->Attribute("ammoType"); return true; }
status_t ExtractQueryVolumes(BNode *node, vollist *volumes) { int32 length = 0; char *attr = ReadAttribute(*node, kTrackerQueryVolume, &length); BVolumeRoster roster; if (attr == NULL) { roster.Rewind(); BVolume vol; while (roster.GetNextVolume(&vol) == B_NO_ERROR) { if ((vol.IsPersistent() == true) && (vol.KnowsQuery() == true)) { volumes->push_back(vol); }; }; } else { BMessage msg; msg.Unflatten(attr); // !*YOINK*!d from that project... with the funny little doggie as a logo... // OpenTracker, that's it! time_t created; off_t capacity; for (int32 index = 0; msg.FindInt32("creationDate", index, &created) == B_OK; index++) { if ((msg.FindInt32("creationDate", index, &created) != B_OK) || (msg.FindInt64("capacity", index, &capacity) != B_OK)) return B_ERROR; BVolume volume; BString deviceName = ""; BString volumeName = ""; BString fshName = ""; if (msg.FindString("deviceName", &deviceName) == B_OK && msg.FindString("volumeName", &volumeName) == B_OK && msg.FindString("fshName", &fshName) == B_OK) { // New style volume identifiers: We have a couple of characteristics, // and compute a score from them. The volume with the greatest score // (if over a certain threshold) is the one we're looking for. We // pick the first volume, in case there is more than one with the // same score. int foundScore = -1; roster.Rewind(); char name[B_FILE_NAME_LENGTH]; while (roster.GetNextVolume(&volume) == B_OK) { if (volume.IsPersistent() && volume.KnowsQuery()) { // get creation time and fs_info BDirectory root; volume.GetRootDirectory(&root); time_t cmpCreated; fs_info info; if (root.GetCreationTime(&cmpCreated) == B_OK && fs_stat_dev(volume.Device(), &info) == 0) { // compute the score int score = 0; // creation time if (created == cmpCreated) score += 5; // capacity if (capacity == volume.Capacity()) score += 4; // device name if (deviceName == info.device_name) score += 3; // volume name if (volumeName == info.volume_name) score += 2; // fsh name if (fshName == info.fsh_name) score += 1; // check score if (score >= 9 && score > foundScore) { volume.GetName(name); volumes->push_back(volume); } } } } } else { // Old style volume identifiers: We have only creation time and // capacity. Both must match. roster.Rewind(); while (roster.GetNextVolume(&volume) == B_OK) if (volume.IsPersistent() && volume.KnowsQuery()) { BDirectory root; volume.GetRootDirectory(&root); time_t cmpCreated; root.GetCreationTime(&cmpCreated); if (created == cmpCreated && capacity == volume.Capacity()) { volumes->push_back(volume); } } } }; }; return B_OK; };
bool RulesLoader::ParseVehicleDefinition(Framework &fw, Rules &rules, tinyxml2::XMLElement *root) { VehicleDefinition def; if (UString(root->Name()) != "vehicledef") { LogError("Called on unexpected node \"%s\"", root->Name()); return false; } def.name = root->Attribute("id"); UString type = root->Attribute("type"); if (!ReadAttribute(root, "type", std::map<UString, VehicleDefinition::Type> {{"flying", VehicleDefinition::Type::Flying}, {"ground", VehicleDefinition::Type::Ground}}, def.type)) { LogWarning("Failed to read vehicle 'type' attribute"); return false; } def.size.x = root->FloatAttribute("sizeX"); def.size.y = root->FloatAttribute("sizeY"); def.size.z = root->FloatAttribute("sizeZ"); for (tinyxml2::XMLElement* node = root->FirstChildElement(); node != nullptr; node = node->NextSiblingElement()) { UString tag = node->Name(); if (tag == "flat") { def.sprites[VehicleDefinition::Banking::Flat] = parseDirectionalSprites(fw, node); } else if (tag == "ascending") { def.sprites[VehicleDefinition::Banking::Ascending] = parseDirectionalSprites(fw, node); } else if (tag == "decending") { def.sprites[VehicleDefinition::Banking::Decending] = parseDirectionalSprites(fw, node); } else if (tag == "banking_left") { def.sprites[VehicleDefinition::Banking::Left] = parseDirectionalSprites(fw, node); } else if (tag == "banking_right") { def.sprites[VehicleDefinition::Banking::Right] = parseDirectionalSprites(fw, node); } else { LogError("Unknown vehicle tag \"%s\"", tag.str().c_str()); continue; } } //Push all directional sprites into 'directional vector' space //FIXME: How to do banking left/right? for (auto &s : def.sprites[VehicleDefinition::Banking::Flat]) { Vec3<float> v = directionsToVec[s.first]; v = glm::normalize(v); def.directionalSprites.emplace_back(v, s.second); } for (auto &s : def.sprites[VehicleDefinition::Banking::Ascending]) { Vec3<float> v = directionsToVec[s.first]; v.z = 1; v = glm::normalize(v); def.directionalSprites.emplace_back(v, s.second); } for (auto &s : def.sprites[VehicleDefinition::Banking::Decending]) { Vec3<float> v = directionsToVec[s.first]; v.z = -1; v = glm::normalize(v); def.directionalSprites.emplace_back(v, s.second); } if (!def.voxelMap) { static std::weak_ptr<VoxelMap> stubVoxelMap; LogWarning("Using stub voxel map for vehicle \"%s\"", def.name.str().c_str()); def.voxelMap = stubVoxelMap.lock(); if (!def.voxelMap) { def.voxelMap = std::make_shared<VoxelMap>(Vec3<int>{32,32,16}); stubVoxelMap = def.voxelMap; } } rules.vehicleDefs.emplace(def.name, def); return true; }
NTSTATUS NtfsFindMftRecord(PDEVICE_EXTENSION Vcb, ULONGLONG MFTIndex, PUNICODE_STRING FileName, PULONG FirstEntry, BOOLEAN DirSearch, ULONGLONG *OutMFTIndex) { PFILE_RECORD_HEADER MftRecord; PNTFS_ATTR_CONTEXT IndexRootCtx; PNTFS_ATTR_CONTEXT IndexBitmapCtx; PNTFS_ATTR_CONTEXT IndexAllocationCtx; PINDEX_ROOT_ATTRIBUTE IndexRoot; PINDEX_BUFFER IndexBuffer; ULONGLONG BitmapDataSize; ULONGLONG IndexAllocationSize; PCHAR BitmapData; PCHAR IndexRecord; PINDEX_ENTRY_ATTRIBUTE IndexEntry, IndexEntryEnd; ULONG RecordOffset; ULONG IndexBlockSize; NTSTATUS Status; ULONG CurrentEntry = 0; DPRINT("NtfsFindMftRecord(%p, %I64d, %wZ, %p, %u, %p)\n", Vcb, MFTIndex, FileName, FirstEntry, DirSearch, OutMFTIndex); MftRecord = ExAllocatePoolWithTag(NonPagedPool, Vcb->NtfsInfo.BytesPerFileRecord, TAG_NTFS); if (MftRecord == NULL) { return STATUS_INSUFFICIENT_RESOURCES; } if (NT_SUCCESS(ReadFileRecord(Vcb, MFTIndex, MftRecord))) { ASSERT(MftRecord->Ntfs.Type == NRH_FILE_TYPE); Status = FindAttribute(Vcb, MftRecord, AttributeIndexRoot, L"$I30", 4, &IndexRootCtx); if (!NT_SUCCESS(Status)) { ExFreePoolWithTag(MftRecord, TAG_NTFS); return Status; } IndexRecord = ExAllocatePoolWithTag(NonPagedPool, Vcb->NtfsInfo.BytesPerIndexRecord, TAG_NTFS); if (IndexRecord == NULL) { ExFreePoolWithTag(MftRecord, TAG_NTFS); return STATUS_INSUFFICIENT_RESOURCES; } ReadAttribute(Vcb, IndexRootCtx, 0, IndexRecord, Vcb->NtfsInfo.BytesPerIndexRecord); IndexRoot = (PINDEX_ROOT_ATTRIBUTE)IndexRecord; IndexEntry = (PINDEX_ENTRY_ATTRIBUTE)((PCHAR)&IndexRoot->Header + IndexRoot->Header.FirstEntryOffset); /* Index root is always resident. */ IndexEntryEnd = (PINDEX_ENTRY_ATTRIBUTE)(IndexRecord + IndexRoot->Header.TotalSizeOfEntries); ReleaseAttributeContext(IndexRootCtx); DPRINT("IndexRecordSize: %x IndexBlockSize: %x\n", Vcb->NtfsInfo.BytesPerIndexRecord, IndexRoot->SizeOfEntry); Status = BrowseIndexEntries(IndexEntry, IndexEntryEnd, FileName, FirstEntry, &CurrentEntry, DirSearch, OutMFTIndex); if (NT_SUCCESS(Status)) { ExFreePoolWithTag(IndexRecord, TAG_NTFS); ExFreePoolWithTag(MftRecord, TAG_NTFS); return Status; } if (IndexRoot->Header.Flags & INDEX_ROOT_LARGE) { DPRINT("Large Index!\n"); IndexBlockSize = IndexRoot->SizeOfEntry; Status = FindAttribute(Vcb, MftRecord, AttributeBitmap, L"$I30", 4, &IndexBitmapCtx); if (!NT_SUCCESS(Status)) { DPRINT1("Corrupted filesystem!\n"); ExFreePoolWithTag(MftRecord, TAG_NTFS); return Status; } BitmapDataSize = AttributeDataLength(&IndexBitmapCtx->Record); DPRINT("BitmapDataSize: %x\n", (ULONG)BitmapDataSize); if(BitmapDataSize <= 0xFFFFFFFF) BitmapData = ExAllocatePoolWithTag(NonPagedPool, (ULONG)BitmapDataSize, TAG_NTFS); else BitmapData = NULL; if (BitmapData == NULL) { ExFreePoolWithTag(IndexRecord, TAG_NTFS); ExFreePoolWithTag(MftRecord, TAG_NTFS); return STATUS_INSUFFICIENT_RESOURCES; } ReadAttribute(Vcb, IndexBitmapCtx, 0, BitmapData, (ULONG)BitmapDataSize); ReleaseAttributeContext(IndexBitmapCtx); Status = FindAttribute(Vcb, MftRecord, AttributeIndexAllocation, L"$I30", 4, &IndexAllocationCtx); if (!NT_SUCCESS(Status)) { DPRINT("Corrupted filesystem!\n"); ExFreePoolWithTag(BitmapData, TAG_NTFS); ExFreePoolWithTag(IndexRecord, TAG_NTFS); ExFreePoolWithTag(MftRecord, TAG_NTFS); return Status; } IndexAllocationSize = AttributeDataLength(&IndexAllocationCtx->Record); RecordOffset = 0; for (;;) { DPRINT("RecordOffset: %x IndexAllocationSize: %x\n", RecordOffset, IndexAllocationSize); for (; RecordOffset < IndexAllocationSize;) { UCHAR Bit = 1 << ((RecordOffset / IndexBlockSize) & 7); ULONG Byte = (RecordOffset / IndexBlockSize) >> 3; if ((BitmapData[Byte] & Bit)) break; RecordOffset += IndexBlockSize; } if (RecordOffset >= IndexAllocationSize) { break; } ReadAttribute(Vcb, IndexAllocationCtx, RecordOffset, IndexRecord, IndexBlockSize); if (!NT_SUCCESS(FixupUpdateSequenceArray(Vcb, &((PFILE_RECORD_HEADER)IndexRecord)->Ntfs))) { break; } IndexBuffer = (PINDEX_BUFFER)IndexRecord; ASSERT(IndexBuffer->Ntfs.Type == NRH_INDX_TYPE); ASSERT(IndexBuffer->Header.AllocatedSize + 0x18 == IndexBlockSize); IndexEntry = (PINDEX_ENTRY_ATTRIBUTE)((ULONG_PTR)&IndexBuffer->Header + IndexBuffer->Header.FirstEntryOffset); IndexEntryEnd = (PINDEX_ENTRY_ATTRIBUTE)((ULONG_PTR)&IndexBuffer->Header + IndexBuffer->Header.TotalSizeOfEntries); ASSERT(IndexEntryEnd <= (PINDEX_ENTRY_ATTRIBUTE)((ULONG_PTR)IndexBuffer + IndexBlockSize)); Status = BrowseIndexEntries(IndexEntry, IndexEntryEnd, FileName, FirstEntry, &CurrentEntry, DirSearch, OutMFTIndex); if (NT_SUCCESS(Status)) { ExFreePoolWithTag(BitmapData, TAG_NTFS); ExFreePoolWithTag(IndexRecord, TAG_NTFS); ExFreePoolWithTag(MftRecord, TAG_NTFS); ReleaseAttributeContext(IndexAllocationCtx); return Status; } RecordOffset += IndexBlockSize; } ReleaseAttributeContext(IndexAllocationCtx); ExFreePoolWithTag(BitmapData, TAG_NTFS); } ExFreePoolWithTag(IndexRecord, TAG_NTFS); }
PNTFS_ATTR_CONTEXT FindAttributeHelper(PDEVICE_EXTENSION Vcb, PNTFS_ATTR_RECORD AttrRecord, PNTFS_ATTR_RECORD AttrRecordEnd, ULONG Type, PCWSTR Name, ULONG NameLength) { DPRINT("FindAttributeHelper(%p, %p, %p, 0x%x, %S, %u)\n", Vcb, AttrRecord, AttrRecordEnd, Type, Name, NameLength); while (AttrRecord < AttrRecordEnd) { DPRINT("AttrRecord->Type = 0x%x\n", AttrRecord->Type); if (AttrRecord->Type == AttributeEnd) break; if (AttrRecord->Type == AttributeAttributeList) { PNTFS_ATTR_CONTEXT Context; PNTFS_ATTR_CONTEXT ListContext; PVOID ListBuffer; ULONGLONG ListSize; PNTFS_ATTR_RECORD ListAttrRecord; PNTFS_ATTR_RECORD ListAttrRecordEnd; ListContext = PrepareAttributeContext(AttrRecord); ListSize = AttributeDataLength(&ListContext->Record); if(ListSize <= 0xFFFFFFFF) ListBuffer = ExAllocatePoolWithTag(NonPagedPool, (ULONG)ListSize, TAG_NTFS); else ListBuffer = NULL; if(!ListBuffer) { DPRINT("Failed to allocate memory: %x\n", (ULONG)ListSize); continue; } ListAttrRecord = (PNTFS_ATTR_RECORD)ListBuffer; ListAttrRecordEnd = (PNTFS_ATTR_RECORD)((PCHAR)ListBuffer + ListSize); if (ReadAttribute(Vcb, ListContext, 0, ListBuffer, (ULONG)ListSize) == ListSize) { Context = FindAttributeHelper(Vcb, ListAttrRecord, ListAttrRecordEnd, Type, Name, NameLength); ReleaseAttributeContext(ListContext); ExFreePoolWithTag(ListBuffer, TAG_NTFS); if (Context != NULL) { if (AttrRecord->IsNonResident) DPRINT("Found context = %p\n", Context); return Context; } } } if (AttrRecord->Type == Type) { if (AttrRecord->NameLength == NameLength) { PWCHAR AttrName; AttrName = (PWCHAR)((PCHAR)AttrRecord + AttrRecord->NameOffset); DPRINT("%.*S, %.*S\n", AttrRecord->NameLength, AttrName, NameLength, Name); if (RtlCompareMemory(AttrName, Name, NameLength << 1) == (NameLength << 1)) { /* Found it, fill up the context and return. */ DPRINT("Found context\n"); return PrepareAttributeContext(AttrRecord); } } } if (AttrRecord->Length == 0) { DPRINT("Null length attribute record\n"); return NULL; } AttrRecord = (PNTFS_ATTR_RECORD)((PCHAR)AttrRecord + AttrRecord->Length); } DPRINT("Ended\n"); return NULL; }
/** * NtfsAllocateClusters * Allocates a run of clusters. The run allocated might be smaller than DesiredClusters. */ NTSTATUS NtfsAllocateClusters(PDEVICE_EXTENSION DeviceExt, ULONG FirstDesiredCluster, ULONG DesiredClusters, PULONG FirstAssignedCluster, PULONG AssignedClusters) { NTSTATUS Status; PFILE_RECORD_HEADER BitmapRecord; PNTFS_ATTR_CONTEXT DataContext; ULONGLONG BitmapDataSize; PUCHAR BitmapData; ULONGLONG FreeClusters = 0; RTL_BITMAP Bitmap; ULONG AssignedRun; ULONG LengthWritten; DPRINT1("NtfsAllocateClusters(%p, %lu, %lu, %p, %p)\n", DeviceExt, FirstDesiredCluster, DesiredClusters, FirstAssignedCluster, AssignedClusters); BitmapRecord = ExAllocateFromNPagedLookasideList(&DeviceExt->FileRecLookasideList); if (BitmapRecord == NULL) { return STATUS_INSUFFICIENT_RESOURCES; } Status = ReadFileRecord(DeviceExt, NTFS_FILE_BITMAP, BitmapRecord); if (!NT_SUCCESS(Status)) { ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, BitmapRecord); return Status; } Status = FindAttribute(DeviceExt, BitmapRecord, AttributeData, L"", 0, &DataContext, NULL); if (!NT_SUCCESS(Status)) { ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, BitmapRecord); return Status; } BitmapDataSize = AttributeDataLength(DataContext->pRecord); BitmapDataSize = min(BitmapDataSize, 0xffffffff); ASSERT((BitmapDataSize * 8) >= DeviceExt->NtfsInfo.ClusterCount); BitmapData = ExAllocatePoolWithTag(NonPagedPool, ROUND_UP(BitmapDataSize, DeviceExt->NtfsInfo.BytesPerSector), TAG_NTFS); if (BitmapData == NULL) { ReleaseAttributeContext(DataContext); ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, BitmapRecord); return STATUS_INSUFFICIENT_RESOURCES; } DPRINT1("Total clusters: %I64x\n", DeviceExt->NtfsInfo.ClusterCount); DPRINT1("Total clusters in bitmap: %I64x\n", BitmapDataSize * 8); DPRINT1("Diff in size: %I64d B\n", ((BitmapDataSize * 8) - DeviceExt->NtfsInfo.ClusterCount) * DeviceExt->NtfsInfo.SectorsPerCluster * DeviceExt->NtfsInfo.BytesPerSector); ReadAttribute(DeviceExt, DataContext, 0, (PCHAR)BitmapData, (ULONG)BitmapDataSize); RtlInitializeBitMap(&Bitmap, (PULONG)BitmapData, DeviceExt->NtfsInfo.ClusterCount); FreeClusters = RtlNumberOfClearBits(&Bitmap); if (FreeClusters < DesiredClusters) { ReleaseAttributeContext(DataContext); ExFreePoolWithTag(BitmapData, TAG_NTFS); ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, BitmapRecord); return STATUS_DISK_FULL; } // TODO: Observe MFT reservation zone // Can we get one contiguous run? AssignedRun = RtlFindClearBitsAndSet(&Bitmap, DesiredClusters, FirstDesiredCluster); if (AssignedRun != 0xFFFFFFFF) { *FirstAssignedCluster = AssignedRun; *AssignedClusters = DesiredClusters; } else { // we can't get one contiguous run *AssignedClusters = RtlFindNextForwardRunClear(&Bitmap, FirstDesiredCluster, FirstAssignedCluster); if (*AssignedClusters == 0) { // we couldn't find any runs starting at DesiredFirstCluster *AssignedClusters = RtlFindLongestRunClear(&Bitmap, FirstAssignedCluster); } } Status = WriteAttribute(DeviceExt, DataContext, 0, BitmapData, (ULONG)BitmapDataSize, &LengthWritten, BitmapRecord); ReleaseAttributeContext(DataContext); ExFreePoolWithTag(BitmapData, TAG_NTFS); ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, BitmapRecord); return Status; }
ULONGLONG NtfsGetFreeClusters(PDEVICE_EXTENSION DeviceExt) { NTSTATUS Status; PFILE_RECORD_HEADER BitmapRecord; PNTFS_ATTR_CONTEXT DataContext; ULONGLONG BitmapDataSize; PCHAR BitmapData; ULONGLONG FreeClusters = 0; ULONG Read = 0; RTL_BITMAP Bitmap; DPRINT1("NtfsGetFreeClusters(%p)\n", DeviceExt); BitmapRecord = ExAllocateFromNPagedLookasideList(&DeviceExt->FileRecLookasideList); if (BitmapRecord == NULL) { return 0; } Status = ReadFileRecord(DeviceExt, NTFS_FILE_BITMAP, BitmapRecord); if (!NT_SUCCESS(Status)) { ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, BitmapRecord); return 0; } Status = FindAttribute(DeviceExt, BitmapRecord, AttributeData, L"", 0, &DataContext, NULL); if (!NT_SUCCESS(Status)) { ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, BitmapRecord); return 0; } BitmapDataSize = AttributeDataLength(DataContext->pRecord); ASSERT((BitmapDataSize * 8) >= DeviceExt->NtfsInfo.ClusterCount); BitmapData = ExAllocatePoolWithTag(NonPagedPool, ROUND_UP(BitmapDataSize, DeviceExt->NtfsInfo.BytesPerSector), TAG_NTFS); if (BitmapData == NULL) { ReleaseAttributeContext(DataContext); ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, BitmapRecord); return 0; } /* FIXME: Totally underoptimized! */ for (; Read < BitmapDataSize; Read += DeviceExt->NtfsInfo.BytesPerSector) { ReadAttribute(DeviceExt, DataContext, Read, (PCHAR)((ULONG_PTR)BitmapData + Read), DeviceExt->NtfsInfo.BytesPerSector); } ReleaseAttributeContext(DataContext); DPRINT1("Total clusters: %I64x\n", DeviceExt->NtfsInfo.ClusterCount); DPRINT1("Total clusters in bitmap: %I64x\n", BitmapDataSize * 8); DPRINT1("Diff in size: %I64d B\n", ((BitmapDataSize * 8) - DeviceExt->NtfsInfo.ClusterCount) * DeviceExt->NtfsInfo.SectorsPerCluster * DeviceExt->NtfsInfo.BytesPerSector); RtlInitializeBitMap(&Bitmap, (PULONG)BitmapData, DeviceExt->NtfsInfo.ClusterCount); FreeClusters = RtlNumberOfClearBits(&Bitmap); ExFreePoolWithTag(BitmapData, TAG_NTFS); ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, BitmapRecord); return FreeClusters; }
bool NETCDFFileObject::ReadAttribute(const char *attname, TypeEnum *type, int *ndims, int **dims, void **value) { return ReadAttribute(0, attname, type, ndims, dims, value); }
/* * FUNCTION: Reads data from a file */ static NTSTATUS NtfsReadFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, PUCHAR Buffer, ULONG Length, ULONG ReadOffset, ULONG IrpFlags, PULONG LengthRead) { NTSTATUS Status = STATUS_SUCCESS; PNTFS_FCB Fcb; PFILE_RECORD_HEADER FileRecord; PNTFS_ATTR_CONTEXT DataContext; ULONG RealLength; ULONG RealReadOffset; ULONG RealLengthRead; ULONG ToRead; BOOLEAN AllocatedBuffer = FALSE; PCHAR ReadBuffer = (PCHAR)Buffer; DPRINT1("NtfsReadFile(%p, %p, %p, %u, %u, %x, %p)\n", DeviceExt, FileObject, Buffer, Length, ReadOffset, IrpFlags, LengthRead); *LengthRead = 0; if (Length == 0) { DPRINT1("Null read!\n"); return STATUS_SUCCESS; } Fcb = (PNTFS_FCB)FileObject->FsContext; if (ReadOffset >= Fcb->Entry.AllocatedSize) { DPRINT1("Reading beyond file end!\n"); return STATUS_END_OF_FILE; } ToRead = Length; if (ReadOffset + Length > Fcb->Entry.AllocatedSize) ToRead = Fcb->Entry.AllocatedSize - ReadOffset; RealReadOffset = ReadOffset; RealLength = ToRead; if ((ReadOffset % DeviceExt->NtfsInfo.BytesPerSector) != 0 || (ToRead % DeviceExt->NtfsInfo.BytesPerSector) != 0) { RealReadOffset = ROUND_DOWN(ReadOffset, DeviceExt->NtfsInfo.BytesPerSector); RealLength = ROUND_UP(ToRead, DeviceExt->NtfsInfo.BytesPerSector); ReadBuffer = ExAllocatePoolWithTag(NonPagedPool, RealLength + DeviceExt->NtfsInfo.BytesPerSector, TAG_NTFS); if (ReadBuffer == NULL) { DPRINT1("Not enough memory!\n"); return STATUS_INSUFFICIENT_RESOURCES; } AllocatedBuffer = TRUE; } FileRecord = ExAllocatePoolWithTag(NonPagedPool, DeviceExt->NtfsInfo.BytesPerFileRecord, TAG_NTFS); if (FileRecord == NULL) { DPRINT1("Not enough memory!\n"); return STATUS_INSUFFICIENT_RESOURCES; } Status = ReadFileRecord(DeviceExt, Fcb->MFTIndex, FileRecord); if (!NT_SUCCESS(Status)) { DPRINT1("Can't find record!\n"); ExFreePoolWithTag(FileRecord, TAG_NTFS); return Status; } Status = FindAttribute(DeviceExt, FileRecord, AttributeData, L"", 0, &DataContext); if (!NT_SUCCESS(Status)) { DPRINT1("No data associated with file!\n"); ExFreePoolWithTag(FileRecord, TAG_NTFS); return Status; } DPRINT1("Effective read: %lu at %lu\n", RealLength, RealReadOffset); RealLengthRead = ReadAttribute(DeviceExt, DataContext, RealReadOffset, (PCHAR)ReadBuffer, RealLength); if (RealLengthRead != RealLength) { DPRINT1("Read failure!\n"); ReleaseAttributeContext(DataContext); ExFreePoolWithTag(FileRecord, TAG_NTFS); if (AllocatedBuffer) { ExFreePoolWithTag(ReadBuffer, TAG_NTFS); } return Status; } ReleaseAttributeContext(DataContext); ExFreePoolWithTag(FileRecord, TAG_NTFS); *LengthRead = ToRead; DPRINT1("%lu got read\n", *LengthRead); if (AllocatedBuffer) { RtlCopyMemory(Buffer, ReadBuffer + (ReadOffset - RealReadOffset), ToRead); } if (ToRead != Length) { RtlZeroMemory(Buffer + ToRead, Length - ToRead); } if (AllocatedBuffer) { ExFreePoolWithTag(ReadBuffer, TAG_NTFS); } return STATUS_SUCCESS; }
void ChatWindow::MessageReceived( BMessage * msg ) { switch ( msg->what ) { case IM::SETTINGS_UPDATED: { if (msg->FindString("people_handler", &fPeopleHandler) != B_OK) { fPeopleHandler = kDefaultPeopleHandler; }; RebuildDisplay(); } break; case IM::USER_STOPPED_TYPING: { BMessage im_msg(IM::MESSAGE); im_msg.AddInt32("im_what",IM::USER_STOPPED_TYPING); im_msg.AddRef("contact",&fEntry); fMan->SendMessage(&im_msg); stopSelfTypingTimer(); } break; case IM::USER_STARTED_TYPING: { BMessage im_msg(IM::MESSAGE); im_msg.AddInt32("im_what", IM::USER_STARTED_TYPING); im_msg.AddRef("contact", &fEntry); fMan->SendMessage(&im_msg); startSelfTypingTimer(); } break; case IM::DESKBAR_ICON_CLICKED: { // deskbar icon clicked, move to current workspace and activate SetWorkspaces( 1 << current_workspace() ); Activate(); } break; case IM::ERROR: case IM::MESSAGE: { entry_ref contact; if ( msg->FindRef("contact",&contact) != B_OK ) return; if ( contact != fEntry ) // message not for us, skip it. return; int32 im_what=IM::ERROR; if ( msg->FindInt32("im_what",&im_what) != B_OK ) im_what = IM::ERROR; // int32 old_sel_start, old_sel_end; char timestr[10]; time_t now = time(NULL); strftime(timestr, sizeof(timestr),"[%H:%M]: ", localtime(&now) ); switch ( im_what ) { case IM::STATUS_CHANGED: { // This means we're rebuilding menus we don't rally need to rebuild.. BuildProtocolMenu(); } break; case IM::MESSAGE_SENT: { fText->Append(timestr, C_TIMESTAMP, C_TIMESTAMP, F_TIMESTAMP); BString message; msg->FindString("message", &message); if (message.Compare("/me ", 4) == 0) { fText->Append(_T("* You "), C_ACTION, C_ACTION, F_ACTION); message.Remove(0, 4); fText->Append(message.String(), C_ACTION, C_ACTION, F_ACTION); } else { fText->Append(_T("You say: "), C_OWNNICK, C_OWNNICK, F_TEXT); //fText->Append(msg->FindString("message"), C_TEXT, C_TEXT, F_TEXT); emoticor->AddText(fText,msg->FindString("message"), C_TEXT, F_TEXT,C_TEXT,F_EMOTICON); //by xeD } fText->Append("\n", C_TEXT, C_TEXT, F_TEXT); fText->ScrollToSelection(); } break; case IM::ERROR: { BMessage error; msg->FindMessage("message", &error); int32 error_what = -1; error.FindInt32("im_what", &error_what ); if ( error_what != IM::USER_STARTED_TYPING && error_what != IM::USER_STOPPED_TYPING ) { // ignore messages du to typing fText->Append(timestr, C_TIMESTAMP, C_TIMESTAMP, F_TIMESTAMP); fText->Append("Error: ", C_TEXT, C_TEXT, F_TEXT); fText->Append(msg->FindString("error"), C_TEXT, C_TEXT, F_TEXT); fText->Append("\n", C_TEXT, C_TEXT, F_TEXT); if (!IsActive()) startNotify(); } } break; case IM::MESSAGE_RECEIVED: { if ( msg->FindString("message") == NULL ) { // no message to display, probably opened by user return; } fText->Append(timestr, C_TIMESTAMP, C_TIMESTAMP, F_TIMESTAMP); BString protocol = msg->FindString("protocol"); BString message = msg->FindString("message"); if (protocol.Length() > 0) { fName.ReplaceAll("$protocol$",protocol.String()); } else { fName.ReplaceAll("$protocol$"," "); }; if (message.Compare("/me ", 4) == 0) { fText->Append("* ", C_ACTION, C_ACTION, F_ACTION); fText->Append(fName.String(), C_ACTION, C_ACTION, F_ACTION); fText->Append(" ", C_ACTION, C_ACTION, F_ACTION); message.Remove(0, 4); fText->Append(message.String(), C_ACTION, C_ACTION, F_ACTION); } else { fText->Append(fName.String(), C_OTHERNICK, C_OTHERNICK, F_TEXT); fText->Append(": ", C_OTHERNICK, C_OTHERNICK, F_TEXT); emoticor->AddText(fText,msg->FindString("message"), C_TEXT, F_TEXT,C_TEXT,F_EMOTICON); //by xeD } fText->Append("\n", C_TEXT, C_TEXT, F_TEXT); fText->ScrollToSelection(); if (!IsActive()) startNotify(); stopTypingTimer(); } break; case IM::CONTACT_STARTED_TYPING: { startTypingTimer(); } break; case IM::CONTACT_STOPPED_TYPING: { stopTypingTimer(); } break; } fText->ScrollToSelection(); } break; case SEND_MESSAGE: { if (fInput->TextLength() == 0) return; BMessage im_msg(IM::MESSAGE); im_msg.AddInt32("im_what",IM::SEND_MESSAGE); im_msg.AddRef("contact",&fEntry); im_msg.AddString("message", fInput->Text() ); BMenu *menu = fProtocolMenu->Menu(); if (menu) { IconMenuItem *item = dynamic_cast<IconMenuItem*>(menu->FindMarked()); if ( item ) { BString connection = item->Extra(); if (connection.Length() > 0) { IM::Connection conn(connection.String()); im_msg.AddString("protocol", conn.Protocol()); im_msg.AddString("id", conn.ID()); } } }; if ( fMan->SendMessage(&im_msg) == B_OK ) { fInput->SetText(""); } else { LOG("im_emoclient", liHigh, "Error sending message to im_server"); fText->Append(_T("Error: im_server not running, can't send message\n"), C_TEXT, C_TEXT, F_TEXT); fText->ScrollToSelection(); }; } break; case SHOW_INFO: { BMessage open_msg(B_REFS_RECEIVED); open_msg.AddRef("refs", &fEntry); be_roster->Launch(fPeopleHandler.String(), &open_msg); } break; case VIEW_LOG: { BMessage open(B_REFS_RECEIVED); open.AddRef("refs", &fEntry); be_roster->Launch("application/x-vnd.BeClan.im_binlog_viewer", &open); } break; case VIEW_WEBPAGE: { entry_ref htmlRef; be_roster->FindApp("application/x-vnd.Be.URL.http", &htmlRef); BPath htmlPath(&htmlRef); BMessage argv(B_ARGV_RECEIVED); argv.AddString("argv", htmlPath.Path()); int32 length = -1; char *url = ReadAttribute(BNode(&fEntry), "META:url", &length); if ((url != NULL) && (length > 1)) { url = (char *)realloc(url, (length + 1) * sizeof(char)); url[length] = '\0'; argv.AddString("argv", url); argv.AddInt32("argc", 2); be_roster->Launch(&htmlRef, &argv); } else { LOG("im_emoclient", liMedium, "Contact had no homepage"); }; if (url) free(url); } break; case VIEW_EMOTICONS: { //find emoticon button BView* button = FindView("Emoticons"); BRect buttonBounds = button->Bounds(); //move emoticon window to just below the button BPoint emotLeftBottom = button->ConvertToScreen(buttonBounds.LeftBottom()); popup->SetTargetForItems(this); popup->Go(emotLeftBottom,true,true); } break; case ADD_EMOTICON: { int32 index=msg->FindInt32("index"); BString txt; emoticor->config->menu.FindString("face",index,&txt); txt << " "; fInput->Insert(txt.String()); } break; case EMAIL: { BMessage open_msg(B_REFS_RECEIVED); open_msg.AddRef("refs", &fEntry); // "application/x-vnd.Be-MAIL" be_roster->Launch("text/x-email", &open_msg ); } break; case BLOCK: { IM::Contact contact(fEntry); char status[256]; if ( contact.GetStatus( status, sizeof(status) ) != B_OK ) status[0] = 0; if ( strcmp(status, BLOCKED_TEXT) == 0 ) { // already blocked, unblocked contact.SetStatus(OFFLINE_TEXT); BMessage update_msg(IM::UPDATE_CONTACT_STATUS); update_msg.AddRef("contact", &fEntry); fMan->SendMessage( &update_msg ); } else { if ( contact.SetStatus(BLOCKED_TEXT) != B_OK ) { LOG("im_emoclient", liHigh, "Block: Error setting contact status"); } } } break; case AUTH: { BMessage auth_msg(IM::MESSAGE); auth_msg.AddInt32("im_what", IM::REQUEST_AUTH); auth_msg.AddRef("contact", &fEntry); fMan->SendMessage( &auth_msg ); } break; case B_NODE_MONITOR: { int32 opcode=0; if ( msg->FindInt32("opcode",&opcode) != B_OK ) return; switch ( opcode ) { case B_ENTRY_REMOVED: { // oops. should we close down this window now? // Nah, we'll just disable everything. fInput->MakeEditable(false); fInput->SetViewColor( 198,198,198 ); fInput->Invalidate(); BString title( Title() ); title += " - DELETED!"; SetTitle( title.String() ); } break; case B_ENTRY_MOVED: { entry_ref ref; msg->FindInt32("device", &ref.device); msg->FindInt64("to directory", &ref.directory); ref.set_name( msg->FindString("name") ); fEntry = ref; BEntry entry(&fEntry); if ( !entry.Exists() ) { LOG("im_emoclient", liHigh, "Entry moved: New entry invalid"); } } break; case B_STAT_CHANGED: case B_ATTR_CHANGED: reloadContact(); BuildProtocolMenu(); break; } } break; case kResizeMessage: { BView *view = NULL; msg->FindPointer("view", reinterpret_cast<void**>(&view)); if (dynamic_cast<BScrollView *>(view)) { BPoint point; msg->FindPoint("loc", &point); fResize->MoveTo(fResize->Frame().left, point.y); fTextScroll->ResizeTo(fTextScroll->Frame().Width(), point.y - 1 - fDock->Frame().Height() - 1); fInputScroll->MoveTo(fInputScroll->Frame().left, point.y + 3); fInputScroll->ResizeTo( fInputScroll->Bounds().Width(), fStatusBar->Frame().top - fInputScroll->Frame().top ); fInput->SetTextRect(fInput->Bounds()); fInput->ScrollToSelection(); if ( fSendButton ) { fSendButton->MoveTo(fSendButton->Frame().left, point.y + 3); fSendButton->ResizeTo( fSendButton->Bounds().Width(), fStatusBar->Frame().top - fSendButton->Frame().top ); } }; } break; case B_MOUSE_WHEEL_CHANGED: { fText->MessageReceived(msg); } break; case B_COPY: { int32 start = 0; int32 end = 0; fInput->GetSelection(&start, &end); //printf("%ld - > %ld\n", start, end); } break; case B_SIMPLE_DATA: { entry_ref ref; BNode node; // attr_info info; for (int i = 0; msg->FindRef("refs", i, &ref) == B_OK; i++) { node = BNode(&ref); char *type = ReadAttribute(node, "BEOS:TYPE"); if (strcmp(type, "application/x-person") == 0) { char *name = ReadAttribute(node, "META:name"); char *nickname = ReadAttribute(node, "META:nickname"); char connection[100]; IM::Contact con(ref); con.ConnectionAt(0, connection); if (fInput->TextLength() > 0) fInput->Insert("\n"); fInput->Insert(name); fInput->Insert(" ("); fInput->Insert(nickname); fInput->Insert("): "); fInput->Insert(connection); free(name); free(nickname); }; free(type); }; fInput->ScrollToOffset(fInput->TextLength()); } break; case CLEAR_TYPING: stopTypingTimer(); break; case PROTOCOL_SELECTED: { // a protocol has been selected. Since BMenuField doesn't resize until later, // we have to wait 1000us before actually responding to the change, see below if ( fProtocolHack ) delete fProtocolHack; BMessage protoHack(PROTOCOL_SELECTED2); fProtocolHack = new BMessageRunner( BMessenger(this), &protoHack, 1000, 1 ); } break; case PROTOCOL_SELECTED2: // do what should be done on protocol change fStatusBar->PositionViews(); fInfoView->ResizeTo( fStatusBar->Bounds().Width() - fInfoView->Frame().left, fInfoView->Bounds().Height() ); break; default: BWindow::MessageReceived(msg); } }
Calibration *createCalibration(char *CalFilePath,unsigned short index) { // This function creates and populate a Calibration structure from a file. Calibration *cal; DOM_DocumentLS *doc; // contains DOM document of calibration file DOM_Element *eRoot; // points to document root element ("FTSensor") DOM_Node *node; // multipurpose variable for nodes in the cal file DOM_Element *eCalibration; // points to Calibration element DOM_NodeList *calibrationNodelist; //node lists in the cal file DOM_NodeList *axisNodelist; DOM_NodeList *childNodelist; char *temp; // temporary string value for reading in attributes unsigned short i,j; // counter variables float temparray[MAX_GAUGES]; // used when loading calibration rows float scale; // used when loading calibration rows cal=(Calibration *) calloc(1,sizeof(Calibration)); doc = DOM_Implementation_createDocument(NULL, NULL, NULL); // initialize DOM document if (DOM_DocumentLS_load(doc,CalFilePath)!=1) { // open calibration file free(cal); DOM_Document_destroyNode(doc, doc); // clean up DOM stuff return NULL; } eRoot=doc->u.Document.documentElement; if (strcmp(eRoot->nodeName,"FTSensor")!=0) { // make sure we're loading the right kind of file free(cal); DOM_Document_destroyNode(doc, doc); // clean up DOM stuff return NULL; } ReadAttribute(eRoot,&temp,"Serial",TRUE,""); cal->Serial=ATI_strdup(temp); free(temp); ReadAttribute(eRoot,&temp,"BodyStyle",TRUE,""); cal->BodyStyle=ATI_strdup(temp); free(temp); ReadAttribute(eRoot,&temp,"NumGages",TRUE,""); cal->rt.NumChannels=atoi(temp)+1; // add one to NumGages for the temperature channel. free(temp); ReadAttribute(eRoot,&temp,"Family",TRUE,""); cal->Family=ATI_strdup(temp); free(temp); // find calibration specified by index calibrationNodelist=DOM_Element_getElementsByTagName(eRoot,"Calibration"); if (calibrationNodelist->length<index) { // determine if invalid calibration index was used return NULL; } eCalibration=DOM_NodeList_item(calibrationNodelist,index-1); // set Calibration structure attributes found in Calibration element ReadAttribute(eCalibration,&temp,"PartNumber",TRUE,""); cal->PartNumber=ATI_strdup(temp); free(temp); ReadAttribute(eCalibration,&temp,"CalDate",TRUE,""); cal->CalDate=ATI_strdup(temp); free(temp); ReadAttribute(eCalibration,&temp,"ForceUnits",TRUE,""); cal->ForceUnits=ATI_strdup(temp); free(temp); ReadAttribute(eCalibration,&temp,"TorqueUnits",TRUE,""); cal->TorqueUnits=ATI_strdup(temp); free(temp); ReadAttribute(eCalibration,&temp,"DistUnits",TRUE,""); cal->BasicTransform.DistUnits=ATI_strdup(temp); cal->cfg.UserTransform.DistUnits=ATI_strdup(temp); free(temp); ReadAttribute(eCalibration,&temp,"AngleUnits",FALSE,"degrees"); cal->BasicTransform.AngleUnits=ATI_strdup(temp); cal->cfg.UserTransform.AngleUnits=ATI_strdup(temp); free(temp); // initialize temp comp variables cal->TempCompAvailable=FALSE; for (i=0;i<MAX_GAUGES;i++) { cal->rt.bias_slopes[i]=0; cal->rt.gain_slopes[i]=0; } cal->rt.thermistor=0; // store basic matrix axisNodelist=DOM_Element_getElementsByTagName(eCalibration,"Axis"); cal->rt.NumAxes=(unsigned short) axisNodelist->length; for (i=0;i<axisNodelist->length;i++) { node=DOM_NodeList_item(axisNodelist,i); ReadAttribute(node, &temp, "scale", FALSE,"1"); scale=(float) atof(temp); free(temp); ReadAttribute(node, &temp, "values", TRUE,""); Separate(temp,temparray,(unsigned short)(cal->rt.NumChannels-1)); for(j=0;j<cal->rt.NumChannels-1;j++) { cal->BasicMatrix[i][j]=temparray[j]/scale; } free(temp); ReadAttribute(node, &temp, "max", FALSE,"0"); cal->MaxLoads[i]=(float) atof(temp); free(temp); ReadAttribute(node, &temp, "Name", TRUE,""); cal->AxisNames[i]=ATI_strdup(temp); free(temp); } childNodelist=eCalibration->childNodes; for (i=0; i < childNodelist->length; i++) { node=DOM_NodeList_item(childNodelist,i); if (strcmp(node->nodeName,"BasicTransform")==0) { ReadAttribute(node, &temp, "Dx", FALSE,"0"); cal->BasicTransform.TT[0]=(float) atof(temp); free(temp); ReadAttribute(node, &temp, "Dy", FALSE,"0"); cal->BasicTransform.TT[1]=(float) atof(temp); free(temp); ReadAttribute(node, &temp, "Dz", FALSE,"0"); cal->BasicTransform.TT[2]=(float) atof(temp); free(temp); ReadAttribute(node, &temp, "Rx", FALSE,"0"); cal->BasicTransform.TT[3]=(float) atof(temp); free(temp); ReadAttribute(node, &temp, "Ry", FALSE,"0"); cal->BasicTransform.TT[4]=(float) atof(temp); free(temp); ReadAttribute(node, &temp, "Rz", FALSE,"0"); cal->BasicTransform.TT[5]=(float) atof(temp); free(temp); } else if (strcmp(node->nodeName,"BiasSlope")==0) { ReadAttribute(node, &temp, "values", TRUE,""); Separate(temp,cal->rt.bias_slopes,(unsigned short)(cal->rt.NumChannels-1)); free(temp); cal->TempCompAvailable = TRUE; } else if (strcmp(node->nodeName,"GainSlope")==0) { ReadAttribute(node, &temp, "values", TRUE,""); Separate(temp,cal->rt.gain_slopes,(unsigned short)(cal->rt.NumChannels-1)); free(temp); cal->TempCompAvailable = TRUE; } else if (strcmp(node->nodeName,"Thermistor")==0) { ReadAttribute(node, &temp, "value", TRUE,""); cal->rt.thermistor = (float) atof(temp); free(temp); } } DOM_Document_destroyNodeList(eRoot->ownerDocument, calibrationNodelist,0); DOM_Document_destroyNodeList(eRoot->ownerDocument, axisNodelist,0); DOM_Document_destroyNode(doc, doc); // clean up DOM stuff ResetDefaults(cal); // calculate working matrix and set default values return cal; } // createCalibration();
/* * The caller is responsible for freeing the return value by passing it to * SECKEY_DestroyPrivateKeyInfo(..., PR_TRUE). */ SECKEYPrivateKeyInfo * PK11_ExportPrivKeyInfo(SECKEYPrivateKey *pk, void *wincx) { /* PrivateKeyInfo version (always zero) */ const unsigned char pkiVersion = 0; /* RSAPrivateKey version (always zero) */ const unsigned char rsaVersion = 0; PLArenaPool *arena = NULL; SECKEYRawPrivateKey rawKey; SECKEYPrivateKeyInfo *pki; SECItem *encoded; SECStatus rv; if (pk->keyType != rsaKey) { PORT_SetError(PR_NOT_IMPLEMENTED_ERROR); goto loser; } arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); if (!arena) { goto loser; } memset(&rawKey, 0, sizeof(rawKey)); rawKey.keyType = pk->keyType; rawKey.u.rsa.version.type = siUnsignedInteger; rawKey.u.rsa.version.data = (unsigned char *)PORT_ArenaAlloc(arena, 1); if (!rawKey.u.rsa.version.data) { goto loser; } rawKey.u.rsa.version.data[0] = rsaVersion; rawKey.u.rsa.version.len = 1; /* Read the component attributes of the private key */ prepare_rsa_priv_key_export_for_asn1(&rawKey); if (!ReadAttribute(pk, CKA_MODULUS, arena, &rawKey.u.rsa.modulus) || !ReadAttribute(pk, CKA_PUBLIC_EXPONENT, arena, &rawKey.u.rsa.publicExponent) || !ReadAttribute(pk, CKA_PRIVATE_EXPONENT, arena, &rawKey.u.rsa.privateExponent) || !ReadAttribute(pk, CKA_PRIME_1, arena, &rawKey.u.rsa.prime1) || !ReadAttribute(pk, CKA_PRIME_2, arena, &rawKey.u.rsa.prime2) || !ReadAttribute(pk, CKA_EXPONENT_1, arena, &rawKey.u.rsa.exponent1) || !ReadAttribute(pk, CKA_EXPONENT_2, arena, &rawKey.u.rsa.exponent2) || !ReadAttribute(pk, CKA_COEFFICIENT, arena, &rawKey.u.rsa.coefficient)) { goto loser; } pki = PORT_ArenaZNew(arena, SECKEYPrivateKeyInfo); if (!pki) { goto loser; } encoded = SEC_ASN1EncodeItem(arena, &pki->privateKey, &rawKey, SECKEY_RSAPrivateKeyExportTemplate); if (!encoded) { goto loser; } rv = SECOID_SetAlgorithmID(arena, &pki->algorithm, SEC_OID_PKCS1_RSA_ENCRYPTION, NULL); if (rv != SECSuccess) { goto loser; } pki->version.type = siUnsignedInteger; pki->version.data = (unsigned char *)PORT_ArenaAlloc(arena, 1); if (!pki->version.data) { goto loser; } pki->version.data[0] = pkiVersion; pki->version.len = 1; pki->arena = arena; return pki; loser: if (arena) { PORT_FreeArena(arena, PR_TRUE); } return NULL; }