#include <ntddk.h>
#include <ntdddisk.h>
+#include <mountdev.h>
#include <scsi.h>
#include <include/class2.h>
#include <stdio.h>
/* The following hack to assign drive letters with a non-PnP storage stack */
typedef struct _CLASS_DEVICE_INFO {
+ ULONG Signature;
ULONG DeviceType;
ULONG Partitions;
ULONG DeviceNumber;
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
+ PCLASS_DEVICE_INFO DeviceInfo = DeviceObject->DeviceExtension;
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
if (IrpSp->MinorFunction == IRP_MN_START_DEVICE)
{
+ ASSERT(DeviceInfo->Signature == '2slc');
IoSkipCurrentIrpStackLocation(Irp);
- return STATUS_SUCCESS;
+ return IoCallDriver(DeviceInfo->LowerDevice, Irp);
}
else if (IrpSp->MinorFunction == IRP_MN_REMOVE_DEVICE)
{
- PCLASS_DEVICE_INFO DeviceInfo = DeviceObject->DeviceExtension;
-
+ ASSERT(DeviceInfo->Signature == '2slc');
ScsiClassRemoveDriveLetter(DeviceInfo);
+ IoForwardIrpSynchronously(DeviceInfo->LowerDevice, Irp);
+
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
else
{
+ if (DeviceInfo->Signature == '2slc')
+ {
+ IoSkipCurrentIrpStackLocation(Irp);
+ return IoCallDriver(DeviceInfo->LowerDevice, Irp);
+ }
+
Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_NOT_SUPPORTED;
DeviceInfo = DeviceObject->DeviceExtension;
RtlZeroMemory(DeviceInfo, sizeof(CLASS_DEVICE_INFO));
+ DeviceInfo->Signature = '2slc';
/* Attach it to the PDO */
DeviceInfo->LowerDevice = IoAttachDeviceToDeviceStack(DeviceObject, PhysicalDeviceObject);
{
PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
+ ASSERT(*(PULONG)deviceExtension != '2slc');
+
//
// Invoke the device-specific routine, if one exists. Otherwise complete
// with SUCCESS
ULONG maximumTransferLength = deviceExtension->PortCapabilities->MaximumTransferLength;
NTSTATUS status;
+ ASSERT(*(PULONG)deviceExtension != '2slc');
+
if (DeviceObject->Flags & DO_VERIFY_VOLUME &&
!(currentIrpStack->Flags & SL_OVERRIDE_VERIFY_VOLUME)) {
This routine builds and sends a request to the port driver to
get a pointer to a structure that describes the adapter's
- capabilities/limitations. This routine is sychronous.
+ capabilities/limitations. This routine is synchronous.
Arguments:
SCSI_REQUEST_BLOCK srb;
NTSTATUS status;
+ ASSERT(*(PULONG)deviceExtension != '2slc');
+
//
// Allocate read capacity buffer from nonpaged pool.
//
PSCSI_REQUEST_BLOCK srb;
KIRQL currentIrql;
+ ASSERT(*(PULONG)deviceExtension != '2slc');
+
//
// Allocate context from nonpaged pool.
//
Routine Description:
Send command to SCSI unit to start or power up.
- Because this command is issued asynchronounsly, that is, without
+ Because this command is issued asynchronously, that is, without
waiting on it to complete, the IMMEDIATE flag is not set. This
means that the CDB will not return until the drive has powered up.
This should keep subsequent requests from being submitted to the
PCOMPLETION_CONTEXT context;
PCDB cdb;
+ ASSERT(*(PULONG)deviceExtension != '2slc');
+
//
// Allocate Srb from nonpaged pool.
//
Routine Description:
This routine is called when an asynchronous I/O request
- which was issused by the class driver completes. Examples of such requests
+ which was issued by the class driver completes. Examples of such requests
are release queue or START UNIT. This routine releases the queue if
necessary. It then frees the context and the IRP.
DeviceObject - Pointer to the class device object to be addressed.
- Irp - Pointer to Irp the orginal request.
+ Irp - Pointer to Irp the original request.
Return Value:
DebugPrint((2, "ScsiClassSplitRequest: Requires %d IRPs\n", irpCount));
DebugPrint((2, "ScsiClassSplitRequest: Original IRP %lx\n", Irp));
+ ASSERT(*(PULONG)deviceExtension != '2slc');
+
//
// If all partial transfers complete successfully then the status and
// bytes transferred are already set up. Failing a partial-transfer IRP
DebugPrint((1,"ScsiClassSplitRequest: Can't allocate Irp\n"));
//
- // If an Irp can't be allocated then the orginal request cannot
+ // If an Irp can't be allocated then the original request cannot
// be executed. If this is the first request then just fail the
- // orginal request; otherwise just return. When the pending
+ // original request; otherwise just return. When the pending
// requests complete, they will complete the original request.
// In either case set the IRP status to failure.
//
NTSTATUS status;
BOOLEAN retry;
+ ASSERT(*(PULONG)deviceExtension != '2slc');
+
//
// Check SRB status for success of completing request.
//
NTSTATUS status;
BOOLEAN retry;
+ ASSERT(*(PULONG)deviceExtension != '2slc');
+
//
// Check SRB status for success of completing request.
//
PAGED_CODE();
+ ASSERT(*(PULONG)deviceExtension != '2slc');
+
dummy.QuadPart = 0;
//
//
// NOTICE: The SCSI-II specification indicates that this field should be
// zero; however, some target controllers ignore the logical unit number
- // in the INDENTIFY message and only look at the logical unit number field
+ // in the IDENTIFY message and only look at the logical unit number field
// in the CDB.
//
ULONG i;
#endif
+ ASSERT(*(PULONG)deviceExtension != '2slc');
//
// Check that request sense buffer is valid.
//
// If the error count has exceeded the error limit, then disable
// any tagged queuing, multiple requests per lu queueing
- // and sychronous data transfers.
+ // and synchronous data transfers.
//
if (deviceExtension->ErrorCount == 4) {
Srb - Supplies a Pointer to the SCSI request block to be retied.
- Assocaiated - Indicates this is an assocatied Irp created by split request.
+ Associated - Indicates this is an associated Irp created by split request.
Return Value:
PIO_STACK_LOCATION nextIrpStack = IoGetNextIrpStackLocation(Irp);
ULONG transferByteCount;
+ ASSERT(*(PULONG)deviceExtension != '2slc');
+
//
// Determine the transfer count of the request. If this is a read or a
// write then the transfer count is in the Irp stack. Otherwise assume
ULONG logicalBlockAddress;
USHORT transferBlocks;
+ ASSERT(*(PULONG)deviceExtension != '2slc');
+
//
// Calculate relative sector address.
//
Length - Supplies the length in bytes of the mode sense buffer.
- PageMode - Supplies the page or pages of mode sense data to be retrived.
+ PageMode - Supplies the page or pages of mode sense data to be retrieved.
Return Value:
ULONG retries = 1;
NTSTATUS status;
+ ASSERT(*(PULONG)deviceExtension != '2slc');
+
RtlZeroMemory(&srb, sizeof(SCSI_REQUEST_BLOCK));
//
the port driver.
Arguments:
- DeviceObject - Supplies the device object for the orginal request.
+ DeviceObject - Supplies the device object for the original request.
- Srb - Supplies a paritally build ScsiRequestBlock. In particular, the
+ Srb - Supplies a partially built ScsiRequestBlock. In particular, the
CDB and the SRB timeout value must be filled in. The SRB must not be
allocated from zone.
PAGED_CODE();
+ ASSERT(*(PULONG)deviceExtension != '2slc');
+
//
// Write length to SRB.
//
PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
+ ASSERT(*(PULONG)deviceExtension != '2slc');
//
// Call the class specific driver DeviceControl routine.
NTSTATUS status;
ULONG modifiedIoControlCode;
+ ASSERT(*(PULONG)deviceExtension != '2slc');
+
if (irpStack->Parameters.DeviceIoControl.IoControlCode ==
IOCTL_STORAGE_RESET_DEVICE) {
nextStack = IoGetNextIrpStackLocation(Irp);
//
- // Validiate the user buffer.
+ // Validate the user buffer.
//
if (irpStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(SCSI_PASS_THROUGH)){
scsiPass->Lun = deviceExtension->Lun;
//
- // NOTICE: The SCSI-II specificaiton indicates that this field
+ // NOTICE: The SCSI-II specification indicates that this field
// should be zero; however, some target controllers ignore the logical
- // unit number in the INDENTIFY message and only look at the logical
+ // unit number in the IDENTIFY message and only look at the logical
// unit number field in the CDB.
//
goto SetStatusAndReturn;
}
+ if (irpStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_MOUNTDEV_QUERY_UNIQUE_ID ||
+ irpStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME) {
+
+ UNIMPLEMENTED;
+ Irp->IoStatus.Information = 0;
+ Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ status = STATUS_NOT_IMPLEMENTED;
+ goto SetStatusAndReturn;
+ }
+
+ if (irpStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_MOUNTDEV_QUERY_DEVICE_NAME) {
+
+ PMOUNTDEV_NAME name = Irp->AssociatedIrp.SystemBuffer;
+
+ if (irpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(MOUNTDEV_NAME)) {
+
+ Irp->IoStatus.Information = 0;
+ Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ status = STATUS_BUFFER_TOO_SMALL;
+ goto SetStatusAndReturn;
+ }
+
+ RtlZeroMemory(name, sizeof(MOUNTDEV_NAME));
+ name->NameLength = deviceExtension->DeviceName.Length;
+
+ if (irpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(USHORT) + name->NameLength) {
+
+ Irp->IoStatus.Information = sizeof(MOUNTDEV_NAME);
+ Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ status = STATUS_BUFFER_OVERFLOW;
+ goto SetStatusAndReturn;
+ }
+
+ RtlCopyMemory(name->Name, deviceExtension->DeviceName.Buffer,
+ name->NameLength);
+ status = STATUS_SUCCESS;
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ Irp->IoStatus.Information = sizeof(USHORT) + name->NameLength;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ goto SetStatusAndReturn;
+ }
+
srb = ExAllocatePool(NonPagedPool, SCSI_REQUEST_BLOCK_SIZE);
if (srb == NULL) {
{
PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
+ ASSERT(*(PULONG)deviceExtension != '2slc');
+
if (deviceExtension->ClassShutdownFlush) {
//
PDEVICE_EXTENSION deviceExtension = deviceObject->DeviceExtension;
+ ASSERT(*(PULONG)deviceExtension != '2slc');
+
//
// Fill in entry points
//
} else {
deviceExtension->PhysicalDevice = deviceObject;
}
+
+ deviceExtension->DeviceName = ntUnicodeString;
}
deviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
*DeviceObject = deviceObject;
- RtlFreeUnicodeString(&ntUnicodeString);
-
- //
- // Indicate the ntUnicodeString is free.
- //
-
- ntUnicodeString.Buffer = NULL;
-
return status;
}
if (Release) {
- ObDereferenceObject(PortDeviceObject);
+ //ObDereferenceObject(PortDeviceObject);
return STATUS_SUCCESS;
}
return status;
}
+ ObDereferenceObject(srb.DataBuffer);
//
// Return the new port device object pointer.
PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
PSCSI_REQUEST_BLOCK srb;
+ ASSERT(*(PULONG)deviceExtension != '2slc');
+
//
// Get a pointer to the SRB.
//
srb->Lun = deviceExtension->Lun;
//
- // NOTICE: The SCSI-II specificaiton indicates that this field should be
+ // NOTICE: The SCSI-II specification indicates that this field should be
// zero; however, some target controllers ignore the logical unit number
- // in the INDENTIFY message and only look at the logical unit number field
+ // in the IDENTIFY message and only look at the logical unit number field
// in the CDB.
//
deviceExtension->PhysicalDevice->DeviceExtension;
PIRP originalIrp;
+ ASSERT(*(PULONG)deviceExtension != '2slc');
+ ASSERT(*(PULONG)physicalExtension != '2slc');
+
originalIrp = irpStack->Parameters.Others.Argument1;
//