Path: news.mitre.org!blanket.mitre.org!philabs!newsjunkie.ans.net!newsfeeds.ans.net!news-was.dfn.de!news-spur1.maxwell.syr.edu!news.maxwell.syr.edu!howland.erols.net!newsfeed.internetmci.com!192.220.251.22!netnews.nwnet.net!news.microsoft.com!news From: "Paul Sanders" Newsgroups: comp.os.ms-windows.programmer.nt.kernel-mode Subject: Re: Is there any real documentation on the DDK SCSI pass through interface? Date: Tue, 25 Nov 1997 15:43:24 -0800 Organization: Microsoft Lines: 131 Message-ID: <65fo1t$lue@news.microsoft.com> References: <347AE642.DDF51B10@mial.com> <65f66p$iu3@news.microsoft.com> <347B506A.BF68A26E@mial.com> NNTP-Posting-Host: 157.54.178.80 X-Newsreader: Microsoft Outlook Express 4.71.1712.3 X-MimeOLE: Produced By Microsoft MimeOLE V4.71.1712.3 comments interspersed below..... David Schwartz wrote in message <347B506A.BF68A26E@mial.com>... >Paul Sanders wrote: > >> Additionally, >> >> are you getting an error code returned to you? What is it? >> > >Hi Paul, > >No error in the IOSB (IOSB.Status is success), but IOSB.Information is 0. > >Actually I have inserted a kernel mode driver in the chain and am receiving a very funky >looking IOCTL_SCSI_PASS_THROUGH request from a user-mode backup application. >Kernel mode debug output for an IOCTL_SCSI_PASS_THROUGH request follows >showing IRP and SCSI_PASS_THROUGH fields. > >IRP fields: > > MtcScsiR: IoControlCode = 0x4d004 (IOCTL_SCSI_PASS_THROUGH) > MtcScsiR: CTL_CODE method = 0 > MtcScsiR: CTL_CODE function = 0x401 IOCTL_SCSI_PASS_THROUGH > MtcScsiR: CTL_CODE access = 0x3 > MtcScsiR: CTL_CODE deviceType = 0x4 > MtcScsiR: InputBufferLength = 176 > MtcScsiR: OutputBufferLength = 176 > >SCSI_PASS_THROUGH fields: > > MtcScsiR: Length = 44 > MtcScsiR: ScsiStatus = 0 > MtcScsiR: PathId = 0 > MtcScsiR: TargetId = 5 > MtcScsiR: Lun = 0 > MtcScsiR: CdbLength = 6 > MtcScsiR: SenseInfoLength = 128 > MtcScsiR: DataIn = 1 > MtcScsiR: DataTransferLength = 32 > MtcScsiR: TimeOutValue = 14400 > MtcScsiR: DataBufferOffset = 260008 (0x3F7A8) This looks like an address not an offset. That is still legal, but to be 100% correct, the IoControlCode should be 0x405 (IOCTL_SCSI_PASS_THROUGH_DIRECT). However, this is not a problem to SCSIPORT as it will figure it out. > MtcScsiR: SenseInfoOffset = 48 > MtcScsiR: Cdb[0] = 0x12 > MtcScsiR: Cdb[1] = 0 > MtcScsiR: Cdb[2] = 0 > MtcScsiR: Cdb[3] = 0 > MtcScsiR: Cdb[4] = 0x20 > MtcScsiR: Cdb[5] = 0 > MtcScsiR: CDB OperationCode = 0x12, INQUIRY > >The DataBufferOffset above looks completely bogus, but this request >works fine on a system without my filter driver inserted in the chain. >The SPTI example only uses DataBufferOffset as an offset into a buffer >that is contiguous with the SCSI_PASS_THROUGH structure. What else >is DataBufferOffset used for? > >In the DDK header file NTDDSCSI.H the definitions for >SCSI_PASS_THROUGH and SCSI_PASS_THROUGH_DIRECT >are almost identical. In fact, the only difference is that SCSI_PASS_THROUGH >defines the DataBufferOffset field and SCSI_PASS_THROUGH_DIRECT >defines the DataBuffer field. These fields are the same size and in the same >position in the structures. > >This makes me suspect that IOCTL_SCSI_PASS_THROUGH actually allows you >to pass the address of a user-buffer in DataBufferOffset, though that is not how its >documented, and its not how the SPTI example uses it. > In the ScsiPort source code dispatch routine is the following, case IOCTL_SCSI_PASS_THROUGH: case IOCTL_SCSI_PASS_THROUGH_DIRECT: status = SpSendPassThrough(deviceExtension, Irp); break; As you noted, the only difference between two versions of this IOCtl is the DataBufferOffset/DataBuffer concept. For all intents and purposes, both IOCtls are standard METHOD_BUFFERED IOCtls in that the I/O Manager has copied the contents of the DeviceIoControl's Input Buffer into Irp->AssociatedIrp.SystemBuffer. The distinction between the two IOCtls is made by the SCSIPORT driver AND it does not look at the IoControlCode to make the distinction. It looks at the 11th paramater of the SCSI_PASS_THROUGH structure (DataBufferOffset or DataBuffer - they are the same size, 32 bits). If this value is a small number, then DataBufferOffset is an offset into Irp->AssociatedIrp.SystemBuffer. If it is a large number, then DataBuffer is a pointer to Win32 memory. Note, it is not just a matter of small vs large, but that is a close explanation. If it is an offset, then the memory is kernel-mode safe (Irp->AssociatedIrp.SystemBuffer is allocated from nonpaged pool). At that point, the SCSIPORT driver converts the user-mode request into a viable SRB (data copies) and sends the request on down. It does wait for the request to complete (SYNCHRONOUS!!!). If DataBuffer is a pointer, then the Win32 memory is probed and locked. An SRB is built and sent on as before. >I repeat my original question, is there any documentation on the proper use >of the fields in a SCSI_PASS_THROUGH structure? Which fields are used >for input only, input/output, or output only? I realize many of the fields map >directly on SRB fields. > The README is the only documentation. -Paul >David Schwartz >Marathon Technologies Corp. > > >