阅读:2240回复:17
100分求救?我真的很困惑。
我知道IOCTL_SCSI_PASS_THROUGH用来传递SCSI命令,可我想在功能驱动里向下层驱动发送SCSI命令,请问应该怎么做?能举个例吗?
(附,在WIN2000系统里) |
|
最新喜欢:![]() |
沙发#
发布于:2004-08-23 20:53
顶一下,关注..
|
|
板凳#
发布于:2004-08-17 11:59
AllenZH大侠,我先前说的那个会引起SOFTICE检测到“PAGE FAULT”的问题是因为我没有在IoCallDriver例程调用时先一步使用IoCopyCurrentIrpStackLocation(irp)。可现在的问题又不同。
当我使用IoCopyCurrentIrpStackLocation(irp)时,bushound程序没有检测到Inquiry这条命令发送。不知是怎么回事? |
|
|
地板#
发布于:2004-08-16 16:33
AllenZh老大,我加入你添加的那两行,SOFTICE就会弹出“page fault”的错误,查找SCSI关与MASS storage 部分的命令规范,没有看到你先前说的SENSE数据的介绍。不知这用来干什么的, 麻烦老大明示。
|
|
地下室#
发布于:2004-08-16 15:37
NTSTATUS Sample_Inquiry(PDEVICE_OBJECT deviceObject)
{ PSCSI_PASS_THROUGH srb; NTSTATUS ntStatus; PDEVICE_EXTENSION deviceExtension; KEVENT event; IO_STATUS_BLOCK ioStatus; PIRP irp; char Buffer[0x24] ; deviceExtension=deviceObject->DeviceExtension; srb=(PSCSI_PASS_THROUGH)ExAllocatePool (NonPagedPool,sizeof(SCSI_PASS_THROUGH)); RtlZeroMemory(srb,sizeof(SCSI_PASS_THROUGH)); if(srb==NULL) { DbgPrint("mem size is insufficientrn"); return STATUS_INSUFFICIENT_RESOURCES; } srb->Length=sizeof(SCSI_PASS_THROUGH); // srb->SenseInfoLength=0; srb->SenseInfoOffset=0; // 增加 Srb->DataTransferLength = 0x24 ; Srb->DataTransferOffset = (ULONG_PTR)Buffer ; // srb->DataIn=SCSI_IOCTL_DATA_IN; srb->Lun=0; srb->CdbLength=6; srb->TimeOutValue=30; srb->Cdb[0]=0x12; srb->Cdb[4]=0x24; KeInitializeEvent(&event,NotificationEvent,FALSE); irp=IoBuildDeviceIoControlRequest( IOCTL_SCSI_PASS_THROUGH_DIRECT, deviceExtension->TopOfStackDeviceObject, srb, sizeof(SCSI_PASS_THROUGH), srb, sizeof(SCSI_PASS_THROUGH), FALSE, &event, &ioStatus); if(!irp) { return STATUS_INSUFFICIENT_RESOURCES; } ntStatus=IoCallDriver(deviceExtension- >TopOfStackDeviceObject, irp); if(ntStatus==STATUS_PENDING) { KeWaitForSingleObject(&event,Executive,KernelMode,FALSE,NULL); ntStatus=ioStatus.Status; } return ntStatus; } 具体你要看规范,不同设备意义不一样(比如CDROM和SCSI硬盘可能有差别 |
|
|
5楼#
发布于:2004-08-16 15:30
sense数据是用来设置什么的?能说明一下吗?谢谢
|
|
6楼#
发布于:2004-08-16 15:17
老大,帮忙。 这样当然不对 还需要sense数据部分,你没有加 |
|
|
7楼#
发布于:2004-08-16 14:46
老大,帮忙。
|
|
8楼#
发布于:2004-08-16 10:02
老大,好人做到底,我就是不知道这数据结构应该怎么填,你帮我看一下这个INQUIRY命令:
NTSTATUS Sample_Inquiry(PDEVICE_OBJECT deviceObject) { PSCSI_PASS_THROUGH srb; NTSTATUS ntStatus; PDEVICE_EXTENSION deviceExtension; KEVENT event; IO_STATUS_BLOCK ioStatus; PIRP irp; deviceExtension=deviceObject->DeviceExtension; srb=(PSCSI_PASS_THROUGH)ExAllocatePool (NonPagedPool,sizeof(SCSI_PASS_THROUGH)); RtlZeroMemory(srb,sizeof(SCSI_PASS_THROUGH)); if(srb==NULL) { DbgPrint("mem size is insufficient\r\n"); return STATUS_INSUFFICIENT_RESOURCES; } srb->Length=sizeof(SCSI_PASS_THROUGH); srb->SenseInfoLength=0; srb->SenseInfoOffset=0; srb->DataIn=SCSI_IOCTL_DATA_IN; srb->Lun=0; srb->CdbLength=6; srb->TimeOutValue=30; srb->Cdb[0]=0x12; srb->Cdb[4]=0x24; KeInitializeEvent(&event,NotificationEvent,FALSE); irp=IoBuildDeviceIoControlRequest( IOCTL_SCSI_PASS_THROUGH, deviceExtension->TopOfStackDeviceObject, srb, sizeof(SCSI_PASS_THROUGH), srb, sizeof(SCSI_PASS_THROUGH), FALSE, &event, &ioStatus); if(!irp) { return STATUS_INSUFFICIENT_RESOURCES; } ntStatus=IoCallDriver(deviceExtension- >TopOfStackDeviceObject, irp); if(ntStatus==STATUS_PENDING) { KeWaitForSingleObject(&event,Executive,KernelMode,FALSE,NULL); ntStatus=ioStatus.Status; } return ntStatus; } 用bushound抓到的数据出错。不知是哪里出错,请老大看看。谢谢先。 分数我一定奉上。 |
|
|
9楼#
发布于:2004-08-16 09:05
老大,这SCSI命令块在哪里? typedef struct _SCSI_PASS_THROUGH { USHORT Length; UCHAR ScsiStatus; UCHAR PathId; UCHAR TargetId; UCHAR Lun; UCHAR CdbLength; UCHAR SenseInfoLength; UCHAR DataIn; ULONG DataTransferLength; ULONG TimeOutValue; ULONG_ PTR DataBufferOffset; ULONG SenseInfoOffset; UCHAR Cdb[16]; }SCSI_PASS_THROUGH, *PSCSI_PASS_THROUGH; 结构中有个Cdb段,用来保存SCSI命令的 注意有些时候需要传输数据,则DataBuffer、DataTransferLength、DataBufferOffset等需要设置,还有的时候需要传输Sense数据,则SenseInfoLength、SenseInfoOffset等字段 比如 发SCSIOP_SEEK命令 PCDB Cdb ; Cdb = (PCDB)Srb->Cdb ; Cdb->CDB6GENERIC.OperationCode = SCSIOP_SEEK ; Cdb->SEEK.LogicalBlockAddress[0] = ? ; Cdb->SEEK.LogicalBlockAddress[1] = ? ; Cdb->SEEK.LogicalBlockAddress[2] = ? ; Cdb->SEEK.LogicalBlockAddress[3] = ? ; Cdb->SEEK.Control = ? ; .... 不同SCSI命令的数据包格式你需要查考SCSI规范 |
|
|
10楼#
发布于:2004-08-16 08:38
老大,这SCSI命令块在哪里?
|
|
11楼#
发布于:2004-08-15 14:16
这个是我以前写CDROM加密时用来发送SCSI命令的一个函数
|
|
|
12楼#
发布于:2004-08-15 14:12
帮帮我吧,我换了分,全部800分相送。谢谢 /*++ Routine Description: This routine sends the given SRB synchronously to the CDROM class driver. Arguments: TargetDeviceObject - Supplies the target device object pointer Srb - Supplies the SRB. Return Value: NTSTATUS --*/ NTSTATUS SendSrbSynchronous(IN PCD_DEVICE_EXTENSION TargetDeviceObject, IN PSCSI_PASS_THROUGH Srb ) { ULONG ioctl; KEVENT event; PIRP irp = NULL; IO_STATUS_BLOCK ioStatus; NTSTATUS status; Srb->Length = sizeof(SCSI_PASS_THROUGH); Srb->SenseInfoLength = 0; Srb->SenseInfoOffset = 0; Srb->DataIn = SCSI_IOCTL_DATA_OUT; Srb->DataTransferLength = 0; Srb->DataBufferOffset = 0; ioctl = IOCTL_SCSI_PASS_THROUGH; KeInitializeEvent(&event, NotificationEvent, FALSE); irp = IoBuildDeviceIoControlRequest(ioctl, TargetDeviceObject, Srb, sizeof(SCSI_PASS_THROUGH), Srb, sizeof(SCSI_PASS_THROUGH), FALSE, &event, &ioStatus); if (!irp) { return STATUS_INSUFFICIENT_RESOURCES; } status = IoCallDriver(TargetDeviceObject, irp); if (status == STATUS_PENDING) { KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL); status = ioStatus.Status; } return status; } |
|
|
13楼#
发布于:2004-08-15 11:26
看看driverstudio的example,windriver好像也有。
|
|
14楼#
发布于:2004-08-14 15:18
关注!大家没做过,顶了也白顶。
|
|
15楼#
发布于:2004-08-14 13:29
帮帮我吧,我换了分,全部800分相送。谢谢
|
|
16楼#
发布于:2004-08-14 12:04
看的人那么多,回复的一个也没有
|
|
17楼#
发布于:2004-08-13 13:59
别沉了,顶
|
|