示例#1
0
文件: draw.c 项目: awmaker/awmaker
static Bool clipLineInRectangle(int xmin, int ymin, int xmax, int ymax, int *x1, int *y1, int *x2, int *y2)
{
#define TOP	(1<<0)
#define BOT	(1<<1)
#define LEF	(1<<2)
#define RIG	(1<<3)
#define CHECK_OUT(X,Y)	(((Y) > ymax ? TOP : ((Y) < ymin ? BOT : 0))\
    | ((X) > xmax ? RIG : ((X) < xmin ? LEF : 0)))

	int ocode1, ocode2, ocode;
	int accept = 0;
	int x, y;

	ocode1 = CHECK_OUT(*x1, *y1);
	ocode2 = CHECK_OUT(*x2, *y2);

	for (;;) {
		if (!ocode1 && !ocode2) {	/* completely inside */
			accept = 1;
			break;
		} else if (ocode1 & ocode2) {
			break;
		}

		if (ocode1)
			ocode = ocode1;
		else
			ocode = ocode2;

		if (ocode & TOP) {
			x = *x1 + (*x2 - *x1) * (ymax - *y1) / (*y2 - *y1);
			y = ymax;
		} else if (ocode & BOT) {
			x = *x1 + (*x2 - *x1) * (ymin - *y1) / (*y2 - *y1);
			y = ymin;
		} else if (ocode & RIG) {
			y = *y1 + (*y2 - *y1) * (xmax - *x1) / (*x2 - *x1);
			x = xmax;
		} else {	/* //if (ocode & LEF) { */
			y = *y1 + (*y2 - *y1) * (xmax - *x1) / (*x2 - *x1);
			x = xmin;
		}

		if (ocode == ocode1) {
			*x1 = x;
			*y1 = y;
			ocode1 = CHECK_OUT(x, y);
		} else {
			*x2 = x;
			*y2 = y;
			ocode2 = CHECK_OUT(x, y);
		}
	}

	return accept;
}
示例#2
0
//
//	IOCTL_PREPARE_TO_UNLOAD
//
NTSTATUS LklPrepareToUnload(PDEVICE_OBJECT device,PIRP irp)
{
	NTSTATUS status = STATUS_SUCCESS;
	BOOLEAN acq_resource = FALSE;

	CHECK_OUT(device != lklfsd.device, STATUS_INVALID_DEVICE_REQUEST);

	ExAcquireResourceExclusiveLite(&lklfsd.global_resource, TRUE);
	acq_resource = TRUE;

	CHECK_OUT_MSG(FLAG_ON(lklfsd.flags, VFS_UNLOAD_PENDING), STATUS_ACCESS_DENIED,
		"Aldready ready to unload");
	CHECK_OUT_MSG(!IsListEmpty(&lklfsd.vcb_list), STATUS_ACCESS_DENIED,
		"Mounted volumes exists");
    	DbgPrint("Unloading LklVfs");
	IoUnregisterFileSystem(lklfsd.device);

	//unload_linux_kernel();
    
	IoDeleteDevice(lklfsd.device);
     
        lklfsd.driver->DriverUnload = DriverUnload;
	SET_FLAG(lklfsd.flags, VFS_UNLOAD_PENDING);

try_exit:

	if (acq_resource)
		RELEASE(&lklfsd.global_resource);

	return status;
}
示例#3
0
NTSTATUS LklMount(IN PDEVICE_OBJECT dev,IN PVPB vpb)
{
	NTSTATUS status = STATUS_SUCCESS;
	PDEVICE_OBJECT volume_device=NULL;
	PLKLVCB vcb = NULL;
	LARGE_INTEGER AllocationSize;
	ULONG ioctlSize;
	int sectors;
	PSTR dev_name;
	STATFS my_stat;
	ULONG rc;

	CHECK_OUT(dev == lklfsd.device, STATUS_INVALID_DEVICE_REQUEST);

	CHECK_OUT(FLAG_ON(lklfsd.flags, VFS_UNLOAD_PENDING),STATUS_UNRECOGNIZED_VOLUME);
	
	DbgPrint("Mount volume");

	status = IoCreateDevice(lklfsd.driver, sizeof(LKLVCB), NULL,
				FILE_DEVICE_DISK_FILE_SYSTEM, 0, FALSE, &volume_device);	
	CHECK_OUT(!NT_SUCCESS(status), status);
	
	if (dev->AlignmentRequirement > volume_device->AlignmentRequirement)
		volume_device->AlignmentRequirement = dev->AlignmentRequirement;
	
	
	CLEAR_FLAG(volume_device->Flags, DO_DEVICE_INITIALIZING);
	volume_device->StackSize = (CCHAR)(dev->StackSize+1);	
	CreateVcb(volume_device,dev,vpb,&AllocationSize);
	vcb = (PLKLVCB) volume_device->DeviceExtension;
	if(!FLAG_ON(vcb->flags, VFS_VCB_FLAGS_VCB_INITIALIZED))
		TRY_RETURN(STATUS_INSUFFICIENT_RESOURCES);
	
	
	// yup, here we read the disk geometry
	ioctlSize = sizeof(DISK_GEOMETRY);
	status = BlockDeviceIoControl(dev, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0,
				      &vcb->disk_geometry, &ioctlSize);
	CHECK_OUT(!NT_SUCCESS(status), status);

	
	ioctlSize = sizeof(PARTITION_INFORMATION);
	status = BlockDeviceIoControl(dev, IOCTL_DISK_GET_PARTITION_INFO, NULL, 0,
				      &vcb->partition_information, &ioctlSize);
	CHECK_OUT(!NT_SUCCESS(status), status);

	int bytes_per_sector = 0;
	switch (vcb->disk_geometry.BytesPerSector)
	{
	case 256:
		bytes_per_sector = 8;
		break;
	case 512:
		bytes_per_sector = 9;
		break;
	case 1024:
		bytes_per_sector = 10;
		break;
	case 2048:
		bytes_per_sector = 11;
		break;
	case 4096:
		bytes_per_sector = 12;
		break;
	case 8192:
		bytes_per_sector = 13;
		break;
	}
	sectors = vcb->partition_information.PartitionLength.QuadPart >> bytes_per_sector;
	
	// try a linux mount if this fails, then we fail to mount
	// the volume
	ExAcquireResourceExclusiveLite(&(lklfsd.global_resource), TRUE);
	lklfsd.no_mounts++;
	status = sys_mount_wrapper(vcb->target_device, sectors, &vcb->linux_device);
	DbgPrint("Mounting device '%s' retstatus=%d", dev_name, status);
	ExFreePool(dev_name);
   	RELEASE(&(lklfsd.global_resource));
	CHECK_OUT(!NT_SUCCESS(status), status);
	
	
	//get info about the successfully mounted volume
	rc = sys_statfs_wrapper(vcb->linux_device.mnt, &my_stat);

	vpb->DeviceObject = volume_device;
	// complete vpb fields
	#define UNKNOWN_LABEL "Local Disk"
	CharToWchar(vpb->VolumeLabel, UNKNOWN_LABEL , sizeof(UNKNOWN_LABEL));
	vpb->VolumeLabel[sizeof(UNKNOWN_LABEL)] = 0;
	vpb->VolumeLabelLength = sizeof(UNKNOWN_LABEL)*2;
	vpb->SerialNumber = my_stat.f_type;
try_exit:

	if(!NT_SUCCESS(status))
	{
		ExAcquireResourceExclusiveLite(&(lklfsd.global_resource), TRUE);
		lklfsd.no_mounts--;
		RELEASE(&(lklfsd.global_resource));
		
		
		if(volume_device) {
			FreeVcb((PLKLVCB) volume_device->DeviceExtension);
			IoDeleteDevice(volume_device);
		}
		
	}
	
	return status;
}
示例#4
0
//
//	FSCTL_LOCK_VOLUME
//
NTSTATUS DDKAPI VfsLockVolume(PIRP irp, PIO_STACK_LOCATION stack_location)
{
	NTSTATUS status = STATUS_UNSUCCESSFUL;
	PDEVICE_OBJECT device = NULL;
	PLKLVCB vcb;
	BOOLEAN notified = FALSE;
	BOOLEAN resource_acquired = FALSE;
	PFILE_OBJECT file_obj = NULL;

	// request to fs device not permited
	device = stack_location->DeviceObject;
	CHECK_OUT(device == lklfsd.device, STATUS_INVALID_DEVICE_REQUEST);

	// get vcb
	vcb = (PLKLVCB)device->DeviceExtension;
	ASSERT(vcb);

	// file object - should be the file object for a volume open, 
	// even so we accept it for any open file
	file_obj = stack_location->FileObject;
	ASSERT(file_obj);

	// notify volume locked
	FsRtlNotifyVolumeEvent(file_obj, FSRTL_VOLUME_LOCK);
	notified = TRUE;

	// acquire vcb lock
	ExAcquireResourceSharedLite(&vcb->vcb_resource, TRUE);
	resource_acquired = TRUE;

	// check lock flag
	if (FLAG_ON(vcb->flags, VFS_VCB_FLAGS_VOLUME_LOCKED)) {
		VfsReportError("Volume already locked");
		TRY_RETURN(STATUS_ACCESS_DENIED);
	}

	// abort if open files still exist
	if (vcb->open_count) {
		VfsReportError("Open files still exist");
		TRY_RETURN(STATUS_ACCESS_DENIED);
	}

	// release lock
	RELEASE(&vcb->vcb_resource);
	resource_acquired = FALSE;

	// purge volume
	VfsPurgeVolume(vcb, TRUE);

	ExAcquireResourceExclusiveLite(&vcb->vcb_resource, TRUE);
	resource_acquired = TRUE;
	
	// if there are still open referneces we can't lock the volume
	if (vcb->reference_count > 1) {
		VfsReportError("Could not purge cached files");
		TRY_RETURN(STATUS_ACCESS_DENIED);
	}

	// set flag in both vcb and vpb structures
	SET_FLAG(vcb->flags, VFS_VCB_FLAGS_VOLUME_LOCKED);
	SetVpbFlag(vcb->vpb, VFS_VCB_FLAGS_VOLUME_LOCKED);
	DbgPrint("*** Volume LOCKED ***\n");
	status = STATUS_SUCCESS;
	
try_exit:
	
	if (resource_acquired)
		RELEASE(&vcb->vcb_resource);
	if (!NT_SUCCESS(status) && notified)
		FsRtlNotifyVolumeEvent(file_obj, FSRTL_VOLUME_LOCK_FAILED);
	
	return status;
}
示例#5
0
//
//	IRP_MJ_DEVICE_CONTROL - is synchronous
//
NTSTATUS DDKAPI VfsDeviceControl(PDEVICE_OBJECT device, PIRP irp)
{
	NTSTATUS status=STATUS_SUCCESS;
	BOOLEAN top_level;
	ULONG ioctl = 0;
	PIO_STACK_LOCATION stack_location = NULL;
	PIO_STACK_LOCATION next_stack_location = NULL;
	BOOLEAN complete_request = FALSE;
	PLKLVCB vcb = NULL;
	PLKLFCB fcb = NULL;
	PFILE_OBJECT file = NULL;
	PDEVICE_OBJECT targetDevice = NULL;

	ASSERT(device);
	ASSERT(irp);
	top_level = LklIsIrpTopLevel(irp);
	FsRtlEnterFileSystem();

	stack_location = IoGetCurrentIrpStackLocation(irp);
	ASSERT(stack_location);

	ioctl = stack_location->Parameters.DeviceIoControl.IoControlCode;

	if (ioctl == IOCTL_PREPARE_TO_UNLOAD) {
		complete_request = TRUE;
		DbgPrint("Prepare to unload");
		status = LklPrepareToUnload(device,irp);
		TRY_RETURN(status);
	}

	file = stack_location->FileObject;
	ASSERT(file);
	fcb = (PLKLFCB) file->FsContext;
	CHECK_OUT(fcb == NULL, STATUS_INVALID_PARAMETER);

	if (fcb->id.type == VCB) {
		vcb = (PLKLVCB) fcb;
	} else {
		vcb = fcb->vcb;
	}
	CHECK_OUT(vcb == NULL, STATUS_INVALID_PARAMETER);

	targetDevice = vcb->target_device;

	// Pass on the IOCTL to the driver below
	complete_request = FALSE;
	next_stack_location = IoGetNextIrpStackLocation(irp);
	*next_stack_location = *stack_location;
	IoSetCompletionRoutine(irp, LklIoctlCompletion, NULL, TRUE, TRUE, TRUE);
	status = IoCallDriver(targetDevice, irp);

try_exit:
	
	if(complete_request)
		LklCompleteRequest(irp, status);
	if (top_level)
			IoSetTopLevelIrp(NULL);
	FsRtlExitFileSystem();

	return status;
}