以下是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;
}
如果您觉得文章不错,不妨给个打赏,写作不易,感谢各位的支持。您的支持是我最大的动力,谢谢。。。。