Ejemplo n.º 1
0
void Octree::UpdateObject(CollisionMesh& object)
{
    Partition* partition = object.GetPartition();
    Partition* newPartition = nullptr;
    assert(partition);

    if(!IsAllInsidePartition(object, *partition))
    {
        // Move upwards until object is fully inside a single partition
        Partition* parent = partition->GetParent();
        while(parent && !IsAllInsidePartition(object, *parent))
        {
            parent = parent->GetParent();
        }

        // Will be in found partition or one of the children
        newPartition = FindPartition(object, parent ? *parent : *m_octree);
    }
    else
    {
        // Can only be in partition and partition's children
        newPartition = FindPartition(object, *partition);
    }

    assert(newPartition);
    if(newPartition != partition)
    {
        // connect object and new partition together
        partition->RemoveNode(object);
        newPartition->AddNode(object);
        object.SetPartition(newPartition);
    }
}
Ejemplo n.º 2
0
void ListVolumes()
{
	for (auto &v : g_volumes)
	{
		if (v->size==0 && !g_args.allVolumes)
			continue;
		wprintf(L"%s\n", v->deviceName);
		wprintf(L"%s\n", v->name);
		auto size = v->size;
		wprintf(L"Volume size: %llu GB, %llu MB, %I64u bytes\n", size/1024/1024/1024, size/1024/1024, size);
		if (v->dosName) wprintf(L"Path: %s\n", v->dosName);
		if (v->label) wprintf(L"Label: %s\n", v->label);
		if (v->fileSystem) wprintf(L"FileSystem: %s\n", v->fileSystem);
		if (v->extents.size()>0)
		{
			for (auto &e : v->extents)
			{
				auto disk = e->DiskNumber;
				UINT64 offset = e->StartingOffset.QuadPart;
				auto p = FindPartition(disk, offset);
				auto aligned = p== nullptr
					? L"not aligned with partition"
					: L"aligned with partition";
				wprintf(L"\\\\.\\PhysicalDrive%d  offset=%I64u  size=%I64u  (%s)\n", disk, offset, e->ExtentLength.QuadPart, aligned); 
			}
		}
		wprintf(L"\n");
	}
}
Ejemplo n.º 3
0
void Octree::AddObject(CollisionMesh& object)
{
    Partition* partition = FindPartition(object, *m_octree);
    assert(partition);    

    // connect object and new partition together
    partition->AddNode(object);
    object.SetPartition(partition);
}
Ejemplo n.º 4
0
HRESULT OpenDiskOrVolumeOrFile(HANDLE & h, LPWSTR name, bool isRead, UINT64 * psize = nullptr)
{
	DWORD desiredAccess = isRead ? GENERIC_READ : GENERIC_READ|GENERIC_WRITE;
	DWORD devFlags = isRead ? FILE_FLAG_NO_BUFFERING : FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH;
	DWORD fileCreation = isRead ? OPEN_EXISTING : CREATE_ALWAYS;
	auto v = FindVolume(name);
	if (v) 
	{
		auto hr = v->Open(desiredAccess, devFlags, h);
		if (hr) return hr;
		if (psize) *psize = v->size;
		return 0;
	}
	auto d = FindDrive(name);
	if (d)
	{
		auto hr = d->Open(isRead, desiredAccess, devFlags, h);
		if (hr) return hr;
		if (psize) *psize = d->size;
		return 0;
	}
	auto p = FindPartition(name);
	if (p)
	{
		auto hr = p->Open(isRead, desiredAccess, devFlags, h);
		if (hr) return hr;
		if (psize) *psize = p->size;
		return 0;
	}
	h = CreateFile(
				name,
				desiredAccess,
				FILE_SHARE_READ,
				nullptr,
				fileCreation,
				FILE_FLAG_SEQUENTIAL_SCAN,
				nullptr);
	if (h==INVALID_HANDLE_VALUE)
		return GetLastError();
	if (psize)
	{
		LARGE_INTEGER large;
		if (!GetFileSizeEx(h, &large))
			return GetLastError();
		*psize = large.QuadPart;
	}
	return 0;
}
Ejemplo n.º 5
0
Partition* Octree::FindPartition(CollisionMesh& object, Partition& partition)
{
    if(partition.GetLevel() == MAX_LEVEL)
    {
        // No more levels of children
        return &partition;
    }
    else
    {
        // Look through children and see if it fits in at least one
        // If it fits in more than one, parent is desired partition
        Partition* chosenChild = nullptr;
        const auto& children = partition.GetChildren();
        bool inMultiplePartitions = false;

        for(const std::unique_ptr<Partition>& child : children)
        {
            if(IsCornerInsidePartition(object, *child))
            {
                if(!chosenChild)
                {
                    chosenChild = child.get();
                }
                else
                {
                    inMultiplePartitions = true;
                    break;
                }
            }
        }

        if(!chosenChild)
        {
            return m_octree.get();
        }
        else if(inMultiplePartitions)
        {
            return &partition;
        }
        return FindPartition(object, *chosenChild);
    }
    return nullptr;
}
Ejemplo n.º 6
0
void
AutoMounter::MessageReceived(BMessage *message)
{
	switch (message->what) {
#if _INCLUDES_CLASS_DEVICE_MAP
		case kAutomounterRescan:
			RescanDevices();
			break;

		case kStartPolling:	
			// PRINT(("starting the automounter\n"));
			
			fScanThread = spawn_thread(AutoMounter::WatchVolumeBinder, 
#if DEBUG				
				"HiroshiLikesAtomountScan",	// long story
#else
				"AutomountScan",
#endif				
				B_LOW_PRIORITY, this);
			resume_thread(fScanThread);
			break;

		case kMountVolume:
			MountVolume(message);
			break;

		case kUnmountVolume:
			UnmountAndEjectVolume(message);
			break;

		case kSetAutomounterParams:
			{
				bool rescanNow = false;
				message->FindBool("rescanNow", &rescanNow);
				SetParams(message, rescanNow);
				WriteSettings();
				break;
			}

		case kMountAllNow:
			RescanDevices();
			MountAllNow();
			break;

		case kSuspendAutomounter:
			SuspendResume(true);
			break;

		case kResumeAutomounter:
			SuspendResume(false);
			break;

		case kTryMountingFloppy:
			TryMountingFloppy();
			break;

		case B_NODE_MONITOR:
			{
				int32 opcode;
				if (message->FindInt32("opcode", &opcode) != B_OK)
					break;
	
				switch (opcode) {
					case B_DEVICE_MOUNTED: {
						WRITELOG(("** Received Device Mounted Notification"));
						dev_t device;
						if (message->FindInt32("new device", &device) == B_OK) {
							Partition *partition =  FindPartition(device);
							if (partition == NULL || partition->Mounted() != kMounted) {
								WRITELOG(("Device %i not in device list.  Someone mounted it outside "
									"of Tracker", device));
		
								//
								// This is the worst case.  Someone has mounted
								// something from outside of tracker.  
								// Unfortunately, there's no easy way to tell which
								// partition was just mounted (or if we even know about the device),
								// so stop watching all nodes, rescan to see what is now mounted,
								// and start watching again.
								//
								RescanDevices();
							} else
								WRITELOG(("Found partition\n"));
						} else {
							WRITELOG(("ERROR: Could not find mounted device ID in message"));
							PRINT_OBJECT(*message);
						}
	
						break;
					}
	
	
					case B_DEVICE_UNMOUNTED: {
						WRITELOG(("*** Received Device Unmounted Notification"));
						dev_t device;
						if (message->FindInt32("device", &device) == B_OK) {
							Partition *partition = FindPartition(device);
	
							if (partition != 0) {
								WRITELOG(("Found device in device list. Updating state to unmounted."));
								partition->SetMountState(kNotMounted);
							} else
								WRITELOG(("Unmounted device %i was not in device list", device));
						} else {
							WRITELOG(("ERROR: Could not find unmounted device ID in message"));
							PRINT_OBJECT(*message);
						}
	
						break;
					}	
	
	
					//	The name of a mount point has changed
					case B_ENTRY_MOVED: {
						WRITELOG(("*** Received Mount Point Renamed Notification"));
					
						const char *newName;
						if (message->FindString("name", &newName) != B_OK) {
							WRITELOG(("ERROR: Couldn't find name field in update message"));
							PRINT_OBJECT(*message);
							break ;
						}
	
						//
						// When the node monitor reports a move, it gives the
						// parent device and inode that moved.  The problem is 
						// that  the inode is the inode of root *in* the filesystem,
						// which is generally always the same number for every 
						// filesystem of a type.
						//
						// What we'd really like is the device that the moved	
						// volume is mounted on.  Find this by using the 
						// *new* name and directory, and then stat()ing that to
						// find the device.
						//
						dev_t parentDevice;
						if (message->FindInt32("device", &parentDevice) != B_OK) {
							WRITELOG(("ERROR: Couldn't find 'device' field in update"
								" message"));
							PRINT_OBJECT(*message);
							break;
						}
		
						ino_t toDirectory;	
						if (message->FindInt64("to directory", &toDirectory)!=B_OK){
							WRITELOG(("ERROR: Couldn't find 'to directory' field in update"
							  "message"));
							PRINT_OBJECT(*message);
							break;
						}
		
						entry_ref root_entry(parentDevice, toDirectory, newName);
	
						BNode entryNode(&root_entry);
						if (entryNode.InitCheck() != B_OK) {
							WRITELOG(("ERROR: Couldn't create mount point entry node: %s/n", 
								strerror(entryNode.InitCheck())));
							break;
						}	
	
						node_ref mountPointNode;
						if (entryNode.GetNodeRef(&mountPointNode) != B_OK) {
							WRITELOG(("ERROR: Couldn't get node ref for new mount point"));
							break;
						}
				
	
						WRITELOG(("Attempt to rename device %li to %s", mountPointNode.device,
							newName));

						Partition *partition = FindPartition(mountPointNode.device);
						if (partition != NULL) {
							WRITELOG(("Found device, changing name."));

							BVolume mountVolume(partition->VolumeDeviceID());
							BDirectory mountDir;
							mountVolume.GetRootDirectory(&mountDir);
							BPath dirPath(&mountDir, 0);
					
							partition->SetMountedAt(dirPath.Path());
							partition->SetVolumeName(newName);					
							break;
						}
						else
							WRITELOG(("ERROR: Device %li does not appear to be present",
								mountPointNode.device));
					}
				}
			}
			break;


#endif
		default:
			BLooper::MessageReceived(message);
			break;
	}
}
Ejemplo n.º 7
0
void
AutoMounter::MessageReceived(BMessage* message)
{
	switch (message->what) {
		case kMountVolume:
			_MountVolume(message);
			break;

		case kUnmountVolume:
			_UnmountAndEjectVolume(message);
			break;

		case kSetAutomounterParams:
		{
			bool rescanNow = false;
			message->FindBool("rescanNow", &rescanNow);

			_UpdateSettingsFromMessage(message);
			_GetSettings(&fSettings);
			_WriteSettings();

			if (rescanNow)
				_MountVolumes(fNormalMode, fRemovableMode);
			break;
		}

		case kGetAutomounterParams:
		{
			BMessage reply;
			_GetSettings(&reply);
			message->SendReply(&reply);
			break;
		}

		case kMountAllNow:
			_MountVolumes(kAllVolumes, kAllVolumes);
			break;

		case B_DEVICE_UPDATE:
			int32 event;
			if (message->FindInt32("event", &event) != B_OK
				|| (event != B_DEVICE_MEDIA_CHANGED
					&& event != B_DEVICE_ADDED))
				break;

			partition_id deviceID;
			if (message->FindInt32("id", &deviceID) != B_OK)
				break;

			_MountVolumes(kNoVolumes, fRemovableMode, false, deviceID);
			break;

#if 0
		case B_NODE_MONITOR:
		{
			int32 opcode;
			if (message->FindInt32("opcode", &opcode) != B_OK)
				break;

			switch (opcode) {
				//	The name of a mount point has changed
				case B_ENTRY_MOVED: {
					WRITELOG(("*** Received Mount Point Renamed Notification"));

					const char *newName;
					if (message->FindString("name", &newName) != B_OK) {
						WRITELOG(("ERROR: Couldn't find name field in update "
							"message"));
						PRINT_OBJECT(*message);
						break ;
					}

					//
					// When the node monitor reports a move, it gives the
					// parent device and inode that moved.  The problem is
					// that  the inode is the inode of root *in* the filesystem,
					// which is generally always the same number for every
					// filesystem of a type.
					//
					// What we'd really like is the device that the moved
					// volume is mounted on.  Find this by using the
					// *new* name and directory, and then stat()ing that to
					// find the device.
					//
					dev_t parentDevice;
					if (message->FindInt32("device", &parentDevice) != B_OK) {
						WRITELOG(("ERROR: Couldn't find 'device' field in "
							"update message"));
						PRINT_OBJECT(*message);
						break;
					}

					ino_t toDirectory;
					if (message->FindInt64("to directory", &toDirectory)
						!= B_OK) {
						WRITELOG(("ERROR: Couldn't find 'to directory' field "
							"in update message"));
						PRINT_OBJECT(*message);
						break;
					}

					entry_ref root_entry(parentDevice, toDirectory, newName);

					BNode entryNode(&root_entry);
					if (entryNode.InitCheck() != B_OK) {
						WRITELOG(("ERROR: Couldn't create mount point entry "
							"node: %s/n", strerror(entryNode.InitCheck())));
						break;
					}

					node_ref mountPointNode;
					if (entryNode.GetNodeRef(&mountPointNode) != B_OK) {
						WRITELOG(("ERROR: Couldn't get node ref for new mount "
							"point"));
						break;
					}

					WRITELOG(("Attempt to rename device %li to %s",
						mountPointNode.device, newName));

					Partition *partition = FindPartition(mountPointNode.device);
					if (partition != NULL) {
						WRITELOG(("Found device, changing name."));

						BVolume mountVolume(partition->VolumeDeviceID());
						BDirectory mountDir;
						mountVolume.GetRootDirectory(&mountDir);
						BPath dirPath(&mountDir, 0);

						partition->SetMountedAt(dirPath.Path());
						partition->SetVolumeName(newName);
						break;
					} else {
						WRITELOG(("ERROR: Device %li does not appear to be "
							"present", mountPointNode.device));
					}
				}
			}
			break;
		}
#endif

		default:
			BLooper::MessageReceived(message);
			break;
	}
}