win7的磁盘扇区读写。。。。。。。。。。。。。

 

以下是win7 驱动写扇区的相关代码,win7用户模式不能直接读写部分扇区,内核模式下就没有此限制了 /*用户模式 函数 参数1 磁盘号 physicaldriveXX 参数2 扇区索引 参数3 写入字节,因为扇区是512字节,所以写入字节必须为512整数倍 


DWORD WINAPI WriteSection(DWORD dwDiskIndex, DWORD dwSectionIndex, IN PBYTE buffer, DWORD dwCount)//dwCount字节数,必须为512整数倍 
{
	if (dwCount % 512 != 0) { return 0; } DWORD dwRet = 0; BOOL bRet = FALSE; bRet = DeviceIoControl(gHandle, IOCTL_OLS_SET_DISK_INDEX, &dwDiskIndex, sizeof(DWORD), NULL, 0, &dwRet, NULL); if (bRet == FALSE) { return 0; } bRet = DeviceIoControl(gHandle, IOCTL_OLS_SET_SECTION, &dwSectionIndex, sizeof(DWORD), NULL, 0, &dwRet, NULL); if (bRet == FALSE) { //MessageBoxA(NULL,"IOCTL_OLS_SET_SECTION","IOCTL_OLS_SET_SECTION",MB_OK); 
		return 0;
	}
	bRet = WriteFile(gHandle, buffer, dwCount, &dwRet, NULL);
	if (bRet == FALSE || dwRet == 0) { //MessageBoxA(NULL,"IOCTL_OLS_SET_SECTION","IOCTL_OLS_SET_SECTION",MB_OK);
		return 0;
	}
	return dwRet;
}
// 以下是驱动部分的相关代码
NTSTATUS OlsWriteSection(IN PDEVICE_OBJECT pDO, IN PIRP pIrp)
{
	PIO_STACK_LOCATION pIrpSp;
	PDEVICE_OBJECT pDev_Obj_PhyDrv = NULL;
	PFILE_OBJECT pFile_Obj = NULL; UNICODE_STRING uniNameString;
	PIO_STACK_LOCATION pIrpStack; 
	NTSTATUS status = STATUS_SUCCESS;
	ULONG ul_mdl_length = 0;
	ULONG ul_WriteLength = 0; 
	PVOID pAdd = NULL;
	ULONGLONG ull_Temp = 0; 
	WCHAR wsz_temp[64] = { 0 }; 
	pIrp->IoStatus.Information = 0;
	if (g_dwWriteType != OLS_READ_WRTIE_SECTION)
	{
		return STATUS_UNSUCCESSFUL;
	}
	pIrpStack = IoGetCurrentIrpStackLocation(pIrp); 
	ul_mdl_length = MmGetMdlByteCount(pIrp->MdlAddress);
	ul_WriteLength = pIrpStack->Parameters.Write.Length;
	if (ul_mdl_length != ul_WriteLength)
	{
		KdPrint(("ul_mdl_length!=ul_WriteLength")); status = STATUS_UNSUCCESSFUL;
	}
	else 
	{
		KdPrint(("%s", pAdd)); 
		g_dwWriteType = OLS_WRITE_UNKNOWN;
		RtlStringCchPrintfW(wsz_temp, 64, L"//??//PhysicalDrive%d", g_ulDiskIndex);//打开相关磁盘设备 
		RtlInitUnicodeString(&uniNameString, wsz_temp); 
		status = IoGetDeviceObjectPointer(&uniNameString, FILE_ALL_ACCESS, &pFile_Obj, &pDev_Obj_PhyDrv); 
		if (status == STATUS_SUCCESS) {
			//__asm int 3;
			pIrpSp = IoGetCurrentIrpStackLocation(pIrp); //写入的扇区对应字节的偏移号,Sections_To_Byte是自定义函数,将扇区转为字节,比如1扇区,那就是512个字节偏移开始写入 //Length就是写入字节的长度 //如果读的话就是pIrpSp->Parameters.Read pIrpSp->Parameters.Write.ByteOffset=Sections_To_Byte(g_dwSectionIndex); 
			status = fastFsdRequest(pFile_Obj->DeviceObject, IRP_MJ_WRITE, pIrp, TRUE);
			ObReferenceObject(pFile_Obj);
		}
		else {
			pIrp->IoStatus.Status = STATUS_UNSUCCESSFUL;
			pIrp->IoStatus.Information = 0;
		}
	}
	//__asm int 3;
	IoCompleteRequest(pIrp, IO_NO_INCREMENT);
	return status;
}
NTSTATUS fastFsdRequest(IN PDEVICE_OBJECT DeviceObject, ULONG majorFunction, PIRP pIrp, IN BOOLEAN Wait)
{
	PIRP irp;
	KEVENT event; NTSTATUS status;
	PIO_STACK_LOCATION pIrpSp = NULL;
	PIO_STACK_LOCATION pIrpSpCur = NULL;
	pIrpSpCur = IoGetCurrentIrpStackLocation(pIrp);
	irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);//创建写扇区IRP 
	if (!irp) { return STATUS_INSUFFICIENT_RESOURCES; }
	irp->UserIosb = &pIrp->IoStatus;
	pIrpSp = IoGetNextIrpStackLocation(irp);
	pIrpSp->MajorFunction = majorFunction;
	pIrpSp->MinorFunction = IRP_MN_NORMAL;
	pIrpSp->DeviceObject = DeviceObject; irp->MdlAddress = pIrp->MdlAddress;
	pIrpSp->Parameters = pIrpSpCur->Parameters;
	//irp->Flags =irp->Flags|SL_OVERRIDE_VERIFY_VOLUME; // win7 对直接磁盘写入进行了保护, 驱动操作需要在IRP的FLAGS加上SL_FORCE_DIRECT_WRITE标志 
	if (IRP_MJ_WRITE == majorFunction)
	{
		pIrpSp->Flags |= SL_FORCE_DIRECT_WRITE; //这是写关键 
	}
	if (Wait)
	{
		KeInitializeEvent(&event, NotificationEvent, FALSE);
		IoSetCompletionRoutine(irp, FltReadWriteSectorsCompletion, &event, TRUE, TRUE, TRUE);
		status = IoCallDriver(DeviceObject, irp);
		if (STATUS_PENDING == status)
		{
			KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL); status = irp->IoStatus.Status;
		}
	}
	else {
		IoSetCompletionRoutine(irp, FltReadWriteSectorsCompletion, NULL, TRUE, TRUE, TRUE); irp->UserIosb = NULL;
		status = IoCallDriver(DeviceObject, irp);
	}
	if (!NT_SUCCESS(status)) {
		KdPrint(("IoCallDriver 0x%x fail 0x%x/n", majorFunction, status));
	}
	return status;
} //完成例程 
NTSTATUS FltReadWriteSectorsCompletion(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
/*++ Routine Description: A completion routine for use when calling the lower device objects to which our filter deviceobject is attached. Arguments: DeviceObject - Pointer to deviceobject Irp - Pointer to a PnP Irp. Context - NULL or PKEVENT Return Value: NT Status is returned. --*/
{
	PMDL mdl;
	UNREFERENCED_PARAMETER(DeviceObject);
	if (Irp->IoStatus.Status)
	{
		DbgPrint("!!!!!!!!!!Read Or Write HD Error Code====0x%x/n", Irp->IoStatus.Status);
	}
	if (Irp->MdlAddress) { Irp->MdlAddress = NULL; }
	if (Irp->PendingReturned && (Context != NULL))
	{
		*Irp->UserIosb = Irp->IoStatus; KeSetEvent((PKEVENT)Context, IO_DISK_INCREMENT, FALSE);
	}
	IoFreeIrp(Irp);
	return STATUS_MORE_PROCESSING_REQUIRED;
}

 如果您觉得文章不错,不妨给个打赏,写作不易,感谢各位的支持。您的支持是我最大的动力,谢谢。。。。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值