⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 devctl.c

📁 一个windows 文件系统驱动源码
💻 C
📖 第 1 页 / 共 2 页
字号:
			Status = STATUS_SUCCESS;
		}
		else
		{
			Ext2DbgPrint(D_DEVCTL, "Output buffer too small (need %d bytes, got %d bytes), returning.",
						dwDataSize,
						IoStackLocation->Parameters.DeviceIoControl.OutputBufferLength);

			if (dwDataWritten != NULL)
			{
				(*dwDataWritten) = dwDataSize;
			}

			Status = STATUS_BUFFER_TOO_SMALL;
		}
	}
    __except (EXCEPTION_EXECUTE_HANDLER)
    {
		Status = FALSE;
    }

	LEAVE3 (D_DEVCTL, "Ext2GetInodeForFile");

	return Status;
}

NTSTATUS
Ext2GetInodeForDir (
	IN		PEXT2_IRP_CONTEXT	IrpContext,
	IN OUT	ULONG*				dwDataWritten
	)
{
	PIRP                Irp					= NULL;
	PIO_STACK_LOCATION  IoStackLocation		= NULL;
    PEXT2_VCB           Vcb					= NULL;
    PEXT2_MCB           Ext2Mcb				= NULL;
    PEXT2_INODE         ext2_inode			= NULL;
	BOOLEAN				FreeStrings			= FALSE;

	PCHAR				pInputBuffer		= NULL;    
	PCHAR				pOutputBuffer		= NULL;
    ULONG				dwDataSize			= sizeof(EXT2_INODE);
    NTSTATUS			Status				= STATUS_UNSUCCESSFUL;

	ANSI_STRING			FileName;
	UNICODE_STRING		UnicodeFileName;

	ENTER (D_DEVCTL, "Ext2GetInodeForDir");

	__try
	{
		__try
		{
			ASSERT (IrpContext != NULL);

			Irp = IrpContext->Irp;

			ASSERT (Irp != NULL);

			IoStackLocation = IoGetCurrentIrpStackLocation(Irp);

			pInputBuffer = IoStackLocation->Parameters.DeviceIoControl.Type3InputBuffer;

			if (pInputBuffer == NULL)
			{
				Ext2DbgPrint(D_DEVCTL, "Input buffer NULL, returning.");

				Status = STATUS_INVALID_PARAMETER;

				__leave;
			}

			Ext2DbgPrint (D_DEVCTL, "Ext2GetInodeForDir, pInputBuffer=%s\r\n\r\n", pInputBuffer);	

			pOutputBuffer = (PCHAR) Irp->UserBuffer;

			if (pOutputBuffer == NULL)
			{
				Ext2DbgPrint(D_DEVCTL, "\r\n		Output buffer NULL, returning.");

				Status = STATUS_INVALID_PARAMETER;

				__leave;
			}

			if (IoStackLocation->Parameters.DeviceIoControl.OutputBufferLength < dwDataSize)
			{
				Ext2DbgPrint(D_DEVCTL, "Output buffer too small (need %d bytes, got %d bytes), returning.",
							dwDataSize,
							IoStackLocation->Parameters.DeviceIoControl.OutputBufferLength);

				if (dwDataWritten != NULL)
				{
					(*dwDataWritten) = dwDataSize;
				}

				Status = STATUS_BUFFER_TOO_SMALL;

				__leave;
			}

			Ext2DbgPrint (D_DEVCTL, "Input and output buffers validated.");

			ASSERT (IrpContext->DeviceObject != NULL);

			Vcb = (PEXT2_VCB) IrpContext->DeviceObject->DeviceExtension;

			ASSERT (Vcb != NULL);

			RtlInitAnsiString (&FileName, pInputBuffer);
			RtlAnsiStringToUnicodeString (&UnicodeFileName, &FileName, TRUE);

			FreeStrings = TRUE;

			ext2_inode = (PEXT2_INODE) ExAllocatePool (PagedPool, sizeof(EXT2_INODE));

			if (NULL == ext2_inode)
			{
				Status = STATUS_INSUFFICIENT_RESOURCES;

				__leave;
			}

			Ext2DbgPrint (D_DEVCTL, "Calling Ext2LookupFileName ... ");

			Status = Ext2LookupFileName(
							Vcb,
							&UnicodeFileName,
							NULL,
							&Ext2Mcb,
							ext2_inode 
						);

			if (!NT_SUCCESS(Status))
			{
				Ext2DbgPrint (D_DEVCTL, "Ext2LookupFileName returned %s, returning", Ext2DbgNtStatusToString(Status));
				
				__leave;
			}

			Ext2DbgPrint (D_DEVCTL, "Got the inode.");

			// Ok, we got the Inode.

			ProbeForWrite(
					pOutputBuffer, 
					IoStackLocation->Parameters.DeviceIoControl.OutputBufferLength,
					1
				);

			Ext2DbgPrint (D_DEVCTL, "Copying data.");

			// Over loading the reserved field with the inode number.

			ext2_inode->osd1.linux1.l_i_reserved1 = Ext2Mcb->Inode ;

			RtlCopyMemory(pOutputBuffer, ext2_inode, dwDataSize);

			if (dwDataWritten != NULL)
			{
				(*dwDataWritten) = dwDataSize;
			}

			Status = STATUS_SUCCESS;
		}
		__except (EXCEPTION_EXECUTE_HANDLER)
		{
			Status = FALSE;
		}
	}
	__finally
	{
		Ext2DbgPrint (D_DEVCTL, "Ext2GetInodeForDir returning with 0x%08lX.", Status);

		if (ext2_inode != NULL)
		{
			ExFreePool (ext2_inode);
		}

		if (FreeStrings)
		{
			RtlFreeAnsiString (&FileName);
			RtlFreeUnicodeString (&UnicodeFileName);
		}
	}

	LEAVE3 (D_DEVCTL, "Ext2GetInodeForDir");

	return Status;
}

NTSTATUS
Ext2GetInode (IN PEXT2_IRP_CONTEXT IrpContext)
{
	PDEVICE_OBJECT      DeviceObject		= NULL;
	PFILE_OBJECT        FileObject			= NULL;

	ULONG				dwDataWritten		= 0;
    NTSTATUS			Status				= STATUS_UNSUCCESSFUL;

	ENTER (D_DEVCTL, "Ext2GetInode");    
    
	__try	
	{
		__try
		{
			ASSERT(IrpContext != NULL);
			ASSERT((IrpContext->Identifier.Type == EXT2ICX) &&
				   (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));

			DeviceObject = IrpContext->DeviceObject;

			ASSERT (DeviceObject != NULL);

			//
			// This request is not allowed on the main device object
			//

			if (DeviceObject == gExt2Global->DeviceObject)
			{
				Ext2DbgPrint(D_DEVCTL, "Cannot allow on the main device object, returning.");

				Status = STATUS_INVALID_DEVICE_REQUEST;

				__leave;
			}

			FileObject = IrpContext->FileObject;

			ASSERT (FileObject != NULL);

			if (FileObject->FileName.Length != 0)
			{
				Ext2DbgPrint(D_DEVCTL, "FileName: %S (Calling Ext2GetInodeForFile) \r\n", FileObject->FileName.Buffer);

				Status = Ext2GetInodeForFile (IrpContext, FileObject, &dwDataWritten);

				__leave;
			}

			Ext2DbgPrint(D_DEVCTL, "FileName is null, calling Ext2GetInodeForDir \r\n");

			Status = Ext2GetInodeForDir (IrpContext, &dwDataWritten);
		}
		__except (EXCEPTION_EXECUTE_HANDLER)
		{
			Status = FALSE;
		}
	}
	__finally
	{
		if (!IrpContext->ExceptionInProgress)
		{
			IrpContext->Irp->IoStatus.Status = Status;
			IrpContext->Irp->IoStatus.Information = dwDataWritten;

			Ext2CompleteRequest(IrpContext->Irp, IO_NO_INCREMENT);
        
			Ext2FreeIrpContext(IrpContext);
		}
	}

	LEAVE3 (D_DEVCTL, "Ext2GetInode");    

	return Status;
}

NTSTATUS
Ext2SetInode (IN PEXT2_IRP_CONTEXT IrpContext)
{
	NTSTATUS Status = STATUS_NOT_IMPLEMENTED;

	ENTER (D_DEVCTL, "Ext2SetInode");  

	//
	// TODO: Need to implement this fully.
	// 
	
	ASSERT (IrpContext != NULL);

	IrpContext->Irp->IoStatus.Status = Status;
	IrpContext->Irp->IoStatus.Information = 0;;

	Ext2CompleteRequest(IrpContext->Irp, IO_NO_INCREMENT);

	Ext2FreeIrpContext(IrpContext);

	LEAVE3 (D_DEVCTL, "Ext2SetInode");  

	return Status;
}

NTSTATUS
Ext2DeviceControl (IN PEXT2_IRP_CONTEXT IrpContext)
{
    PIRP                Irp;
    PIO_STACK_LOCATION  IoStackLocation;
    ULONG               IoControlCode;
    NTSTATUS            Status;

	ENTER (D_DEVCTL, "Ext2DeviceControl");
    
    ASSERT(IrpContext);
    
    ASSERT((IrpContext->Identifier.Type == EXT2ICX) &&
        (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
    
    Irp = IrpContext->Irp;
    
    IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
    
    IoControlCode =
        IoStackLocation->Parameters.DeviceIoControl.IoControlCode;

	Ext2DbgPrint (D_DEVCTL, "IoControlCode=0x%08lX", IoControlCode);
    
    switch (IoControlCode)
    {
		case IOCTL_GET_SUPER:
			Ext2DbgPrint (D_DEVCTL, "Ext2DeviceControl: Calling Ext2GetSuperBlock");
			Status = Ext2GetSuperBlock (IrpContext);
			break;
		case IOCTL_GET_INODE:
			Ext2DbgPrint (D_DEVCTL, "Ext2DeviceControl: Calling Ext2GetInode");
			Status = Ext2GetInode (IrpContext);
			break;
		case IOCTL_SET_INODE:
			Ext2DbgPrint (D_DEVCTL, "Ext2DeviceControl: Calling Ext2SetInode");
			Status = Ext2SetInode (IrpContext);
			break;
		default:
			Ext2DbgPrint (D_DEVCTL, "Ext2DeviceControl: Calling Ext2DeviceControlNormal");
			Status = Ext2DeviceControlNormal(IrpContext);
    }
    
	LEAVE3 (D_DEVCTL, "Ext2DeviceControl");

    return Status;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -