Author: hpoussin
Date: Mon Mar 8 23:04:38 2010
New Revision: 46017
URL:
http://svn.reactos.org/svn/reactos?rev=46017&view=rev
Log:
[freeldr] Load an additional SCSI driver if present (NTBOOTSYS.SYS on boot partition), to
increase number of known storage devices.
Works only with very simple miniport drivers.
Added:
trunk/reactos/boot/freeldr/freeldr/disk/scsiport.c (with props)
Modified:
trunk/reactos/boot/freeldr/freeldr/bootmgr.c
trunk/reactos/boot/freeldr/freeldr/freeldr.c
trunk/reactos/boot/freeldr/freeldr/freeldr_base.rbuild
trunk/reactos/boot/freeldr/freeldr/include/disk.h
trunk/reactos/boot/freeldr/freeldr/include/reactos.h
trunk/reactos/boot/freeldr/freeldr/reactos/arcname.c
trunk/reactos/boot/freeldr/freeldr/windows/peloader.c
Modified: trunk/reactos/boot/freeldr/freeldr/bootmgr.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/bootm…
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/bootmgr.c [iso-8859-1] (original)
+++ trunk/reactos/boot/freeldr/freeldr/bootmgr.c [iso-8859-1] Mon Mar 8 23:04:38 2010
@@ -119,6 +119,12 @@
return;
}
+ // Load additional SCSI driver (if any)
+ if (LoadBootDeviceDriver() != ESUCCESS)
+ {
+ UiMessageBoxCritical("Unable to load additional boot device driver");
+ }
+
if (!IniFileInitialize())
{
UiMessageBoxCritical("Error initializing .ini file");
Added: trunk/reactos/boot/freeldr/freeldr/disk/scsiport.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/disk/…
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/disk/scsiport.c (added)
+++ trunk/reactos/boot/freeldr/freeldr/disk/scsiport.c [iso-8859-1] Mon Mar 8 23:04:38
2010
@@ -1,0 +1,1701 @@
+#include <freeldr.h>
+
+#define _SCSIPORT_
+
+#include <ntddk.h>
+#include <srb.h>
+#include <scsi.h>
+#include <ntddscsi.h>
+#include <ntddstor.h>
+#include <ntdddisk.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#define NDEBUG
+#include <debug.h>
+
+#define DPRINTM2(fmt, ...) DPRINTM(DPRINT_SCSIPORT, "(%s:%d) SCSIPORT: " fmt,
__FILE__, __LINE__, __VA_ARGS__)
+
+#undef UNIMPLEMENTED
+#define UNIMPLEMENTED DPRINTM2("%s UNIMPLEMENTED\n", __FUNCTION__)
+
+#define SCSI_PORT_NEXT_REQUEST_READY 0x0008
+
+typedef struct
+{
+ PVOID NonCachedExtension;
+
+ ULONG BusNum;
+ ULONG MaxTargedIds;
+
+ ULONG InterruptFlags;
+
+ /* SRB extension stuff */
+ ULONG SrbExtensionSize;
+ PVOID SrbExtensionBuffer;
+
+ IO_SCSI_CAPABILITIES PortCapabilities;
+
+ PHW_INITIALIZE HwInitialize;
+ PHW_STARTIO HwStartIo;
+ PHW_INTERRUPT HwInterrupt;
+ PHW_RESET_BUS HwResetBus;
+
+ /* DMA related stuff */
+ PADAPTER_OBJECT AdapterObject;
+
+ ULONG CommonBufferLength;
+
+ PVOID MiniPortDeviceExtension;
+} SCSI_PORT_DEVICE_EXTENSION, *PSCSI_PORT_DEVICE_EXTENSION;
+
+PSCSI_PORT_DEVICE_EXTENSION ScsiDeviceExtensions[SCSI_MAXIMUM_BUSES];
+
+ULONG
+ntohl(
+ IN ULONG Value)
+{
+ FOUR_BYTE Dest;
+ PFOUR_BYTE Source = (PFOUR_BYTE)&Value;
+
+ Dest.Byte0 = Source->Byte3;
+ Dest.Byte1 = Source->Byte2;
+ Dest.Byte2 = Source->Byte1;
+ Dest.Byte3 = Source->Byte0;
+
+ return Dest.AsULong;
+}
+
+BOOLEAN
+SpiSendSynchronousSrb(
+ IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension,
+ IN PSCSI_REQUEST_BLOCK Srb)
+{
+ BOOLEAN ret;
+
+ ASSERT(!(Srb->SrbFlags & SRB_FLAGS_IS_ACTIVE));
+
+ /* HACK: handle lack of interrupts */
+ while (!(DeviceExtension->InterruptFlags & SCSI_PORT_NEXT_REQUEST_READY))
+ {
+ KeStallExecutionProcessor(100 * 1000);
+ DeviceExtension->HwInterrupt(DeviceExtension->MiniPortDeviceExtension);
+ }
+
+ DeviceExtension->InterruptFlags &= ~SCSI_PORT_NEXT_REQUEST_READY;
+ Srb->SrbFlags |= SRB_FLAGS_IS_ACTIVE;
+
+ if (!DeviceExtension->HwStartIo(
+ DeviceExtension->MiniPortDeviceExtension,
+ Srb))
+ {
+ ExFreePool(Srb);
+ return FALSE;
+ }
+
+ /* HACK: handle lack of interrupts */
+ while (Srb->SrbFlags & SRB_FLAGS_IS_ACTIVE)
+ {
+ KeStallExecutionProcessor(100 * 1000);
+ DeviceExtension->HwInterrupt(DeviceExtension->MiniPortDeviceExtension);
+ }
+
+ ret = SRB_STATUS(Srb->SrbStatus) == SRB_STATUS_SUCCESS;
+ ExFreePool(Srb);
+
+ return ret;
+}
+
+typedef struct tagDISKCONTEXT
+{
+ /* Device ID */
+ PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
+ ULONG PathId;
+ ULONG TargetId;
+ ULONG Lun;
+
+ /* Device characteristics */
+ ULONG SectorSize;
+ ULONGLONG SectorOffset;
+ ULONGLONG SectorCount;
+ ULONGLONG SectorNumber;
+} DISKCONTEXT;
+
+static LONG DiskClose(ULONG FileId)
+{
+ DISKCONTEXT* Context = FsGetDeviceSpecific(FileId);
+
+ ExFreePool(Context);
+ return ESUCCESS;
+}
+
+static LONG DiskGetFileInformation(ULONG FileId, FILEINFORMATION* Information)
+{
+ DISKCONTEXT* Context = FsGetDeviceSpecific(FileId);
+
+ RtlZeroMemory(Information, sizeof(FILEINFORMATION));
+ Information->EndingAddress.QuadPart = Context->SectorCount *
Context->SectorSize;
+ Information->CurrentAddress.LowPart = Context->SectorNumber *
Context->SectorSize;
+
+ return ESUCCESS;
+}
+
+static LONG DiskOpen(CHAR* Path, OPENMODE OpenMode, ULONG* FileId)
+{
+ PSCSI_REQUEST_BLOCK Srb;
+ PCDB Cdb;
+ READ_CAPACITY_DATA ReadCapacityBuffer;
+
+ DISKCONTEXT* Context;
+ PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
+ ULONG ScsiBus, PathId, TargetId, Lun, Partition, PathSyntax;
+ ULONG SectorSize;
+ ULONGLONG SectorOffset = 0;
+ ULONGLONG SectorCount;
+
+ /* Parse ARC path */
+ if (!DissectArcPath2(Path, &ScsiBus, &TargetId, &Lun, &Partition,
&PathSyntax))
+ return EINVAL;
+ if (PathSyntax != 0) /* scsi() format */
+ return EINVAL;
+ DeviceExtension = ScsiDeviceExtensions[ScsiBus];
+ PathId = ScsiBus - DeviceExtension->BusNum;
+
+ /* Get disk capacity and sector size */
+ Srb = ExAllocatePool(PagedPool, sizeof(SCSI_REQUEST_BLOCK));
+ if (!Srb)
+ return ENOMEM;
+ RtlZeroMemory(Srb, sizeof(SCSI_REQUEST_BLOCK));
+ Srb->Length = sizeof(SCSI_REQUEST_BLOCK);
+ Srb->Function = SRB_FUNCTION_EXECUTE_SCSI;
+ Srb->PathId = PathId;
+ Srb->TargetId = TargetId;
+ Srb->Lun = Lun;
+ Srb->CdbLength = 10;
+ Srb->SrbFlags = SRB_FLAGS_DATA_IN;
+ Srb->DataTransferLength = sizeof(READ_CAPACITY_DATA);
+ Srb->TimeOutValue = 5; /* in seconds */
+ Srb->DataBuffer = &ReadCapacityBuffer;
+ Cdb = (PCDB)Srb->Cdb;
+ Cdb->CDB10.OperationCode = SCSIOP_READ_CAPACITY;
+ if (!SpiSendSynchronousSrb(DeviceExtension, Srb))
+ {
+ return EIO;
+ }
+
+ /* Transform result to host endianness */
+ SectorCount = ntohl(ReadCapacityBuffer.LogicalBlockAddress);
+ SectorSize = ntohl(ReadCapacityBuffer.BytesPerBlock);
+
+ if (Partition != 0)
+ {
+ /* Need to offset start of disk and length */
+ UNIMPLEMENTED;
+ return EIO;
+ }
+
+ Context = ExAllocatePool(PagedPool, sizeof(DISKCONTEXT));
+ if (!Context)
+ return ENOMEM;
+ Context->DeviceExtension = DeviceExtension;
+ Context->PathId = PathId;
+ Context->TargetId = TargetId;
+ Context->Lun = Lun;
+ Context->SectorSize = SectorSize;
+ Context->SectorOffset = SectorOffset;
+ Context->SectorCount = SectorCount;
+ Context->SectorNumber = 0;
+ FsSetDeviceSpecific(*FileId, Context);
+
+ return ESUCCESS;
+}
+
+static LONG DiskRead(ULONG FileId, VOID* Buffer, ULONG N, ULONG* Count)
+{
+ DISKCONTEXT* Context = FsGetDeviceSpecific(FileId);
+ PSCSI_REQUEST_BLOCK Srb;
+ PCDB Cdb;
+ ULONG FullSectors, NbSectors;
+ ULONG Lba;
+
+ *Count = 0;
+
+ if (N == 0)
+ return ESUCCESS;
+
+ FullSectors = N / Context->SectorSize;
+ NbSectors = (N + Context->SectorSize - 1) / Context->SectorSize;
+ if (Context->SectorNumber + NbSectors >= Context->SectorCount)
+ return EINVAL;
+ if (FullSectors > 0xffff)
+ return EINVAL;
+
+ /* Read full sectors */
+ Lba = Context->SectorNumber;
+ if (FullSectors > 0)
+ {
+ Srb = ExAllocatePool(PagedPool, sizeof(SCSI_REQUEST_BLOCK));
+ if (!Srb)
+ return ENOMEM;
+
+ RtlZeroMemory(Srb, sizeof(SCSI_REQUEST_BLOCK));
+ Srb->Length = sizeof(SCSI_REQUEST_BLOCK);
+ Srb->Function = SRB_FUNCTION_EXECUTE_SCSI;
+ Srb->PathId = Context->PathId;
+ Srb->TargetId = Context->TargetId;
+ Srb->Lun = Context->Lun;
+ Srb->CdbLength = 10;
+ Srb->SrbFlags = SRB_FLAGS_DATA_IN;
+ Srb->DataTransferLength = FullSectors * Context->SectorSize;
+ Srb->TimeOutValue = 5; /* in seconds */
+ Srb->DataBuffer = Buffer;
+ Cdb = (PCDB)Srb->Cdb;
+ Cdb->CDB10.OperationCode = SCSIOP_READ;
+ Cdb->CDB10.LogicalUnitNumber = Srb->Lun;
+ Cdb->CDB10.LogicalBlockByte0 = (Lba >> 24) & 0xff;
+ Cdb->CDB10.LogicalBlockByte1 = (Lba >> 16) & 0xff;
+ Cdb->CDB10.LogicalBlockByte2 = (Lba >> 8) & 0xff;
+ Cdb->CDB10.LogicalBlockByte3 = Lba & 0xff;
+ Cdb->CDB10.TransferBlocksMsb = (FullSectors >> 8) & 0xff;
+ Cdb->CDB10.TransferBlocksLsb = FullSectors & 0xff;
+ if (!SpiSendSynchronousSrb(Context->DeviceExtension, Srb))
+ {
+ return EIO;
+ }
+ Buffer = (PUCHAR)Buffer + FullSectors * Context->SectorSize;
+ N -= FullSectors * Context->SectorSize;
+ *Count += FullSectors * Context->SectorSize;
+ Lba += FullSectors;
+ }
+
+ /* Read incomplete last sector */
+ if (N > 0)
+ {
+ PUCHAR Sector;
+
+ Sector = ExAllocatePool(PagedPool, Context->SectorSize);
+ if (!Sector)
+ return ENOMEM;
+
+ Srb = ExAllocatePool(PagedPool, sizeof(SCSI_REQUEST_BLOCK));
+ if (!Srb)
+ {
+ ExFreePool(Sector);
+ return ENOMEM;
+ }
+
+ RtlZeroMemory(Srb, sizeof(SCSI_REQUEST_BLOCK));
+ Srb->Length = sizeof(SCSI_REQUEST_BLOCK);
+ Srb->Function = SRB_FUNCTION_EXECUTE_SCSI;
+ Srb->PathId = Context->PathId;
+ Srb->TargetId = Context->TargetId;
+ Srb->Lun = Context->Lun;
+ Srb->CdbLength = 10;
+ Srb->SrbFlags = SRB_FLAGS_DATA_IN;
+ Srb->DataTransferLength = Context->SectorSize;
+ Srb->TimeOutValue = 5; /* in seconds */
+ Srb->DataBuffer = Sector;
+ Cdb = (PCDB)Srb->Cdb;
+ Cdb->CDB10.OperationCode = SCSIOP_READ;
+ Cdb->CDB10.LogicalUnitNumber = Srb->Lun;
+ Cdb->CDB10.LogicalBlockByte0 = (Lba >> 24) & 0xff;
+ Cdb->CDB10.LogicalBlockByte1 = (Lba >> 16) & 0xff;
+ Cdb->CDB10.LogicalBlockByte2 = (Lba >> 8) & 0xff;
+ Cdb->CDB10.LogicalBlockByte3 = Lba & 0xff;
+ Cdb->CDB10.TransferBlocksMsb = 0;
+ Cdb->CDB10.TransferBlocksLsb = 1;
+ if (!SpiSendSynchronousSrb(Context->DeviceExtension, Srb))
+ {
+ ExFreePool(Sector);
+ return EIO;
+ }
+ RtlCopyMemory(Buffer, Sector, N);
+ *Count += N;
+ ExFreePool(Sector);
+ }
+
+ return ESUCCESS;
+}
+
+static LONG DiskSeek(ULONG FileId, LARGE_INTEGER* Position, SEEKMODE SeekMode)
+{
+ DISKCONTEXT* Context = FsGetDeviceSpecific(FileId);
+
+ if (SeekMode != SeekAbsolute)
+ return EINVAL;
+ if (Position->QuadPart & (Context->SectorSize - 1))
+ return EINVAL;
+
+ Context->SectorNumber = Position->QuadPart / Context->SectorSize;
+ return ESUCCESS;
+}
+
+static const DEVVTBL DiskVtbl = {
+ DiskClose,
+ DiskGetFileInformation,
+ DiskOpen,
+ DiskRead,
+ DiskSeek,
+};
+
+NTSTATUS
+SpiCreatePortConfig(
+ IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension,
+ IN PHW_INITIALIZATION_DATA HwInitData,
+ OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo,
+ IN BOOLEAN ZeroStruct)
+{
+ ULONG Bus;
+
+ /* Zero out the struct if told so */
+ if (ZeroStruct)
+ {
+ /* First zero the portconfig */
+ RtlZeroMemory(ConfigInfo, sizeof(PORT_CONFIGURATION_INFORMATION));
+
+ /* Initialize the struct */
+ ConfigInfo->Length = sizeof(PORT_CONFIGURATION_INFORMATION);
+ ConfigInfo->AdapterInterfaceType = HwInitData->AdapterInterfaceType;
+ ConfigInfo->InterruptMode = Latched;
+ ConfigInfo->DmaChannel = SP_UNINITIALIZED_VALUE;
+ ConfigInfo->DmaPort = SP_UNINITIALIZED_VALUE;
+ ConfigInfo->MaximumTransferLength = SP_UNINITIALIZED_VALUE;
+ ConfigInfo->MaximumNumberOfTargets = SCSI_MAXIMUM_TARGETS_PER_BUS;
+
+ /* Store parameters */
+ ConfigInfo->NeedPhysicalAddresses = HwInitData->NeedPhysicalAddresses;
+ ConfigInfo->MapBuffers = HwInitData->MapBuffers;
+ ConfigInfo->AutoRequestSense = HwInitData->AutoRequestSense;
+ ConfigInfo->ReceiveEvent = HwInitData->ReceiveEvent;
+ ConfigInfo->TaggedQueuing = HwInitData->TaggedQueuing;
+ ConfigInfo->MultipleRequestPerLu = HwInitData->MultipleRequestPerLu;
+
+ /* Get the disk usage */
+ ConfigInfo->AtdiskPrimaryClaimed = FALSE; // FIXME
+ ConfigInfo->AtdiskSecondaryClaimed = FALSE; // FIXME
+
+ /* Initiator bus id is not set */
+ for (Bus = 0; Bus < 8; Bus++)
+ ConfigInfo->InitiatorBusId[Bus] = (CCHAR)SP_UNINITIALIZED_VALUE;
+ }
+
+ ConfigInfo->NumberOfPhysicalBreaks = 17;
+
+ return STATUS_SUCCESS;
+}
+
+VOID
+DDKCDECLAPI
+ScsiDebugPrint(
+ IN ULONG DebugPrintLevel,
+ IN PCCHAR DebugMessage,
+ IN ...)
+{
+ va_list ap;
+ CHAR Buffer[512];
+ ULONG Length;
+
+ if (DebugPrintLevel > 10)
+ return;
+
+ va_start(ap, DebugMessage);
+
+ /* Construct a string */
+ Length = _vsnprintf(Buffer, 512, DebugMessage, ap);
+
+ /* Check if we went past the buffer */
+ if (Length == MAXULONG)
+ {
+ /* Terminate it if we went over-board */
+ Buffer[sizeof(Buffer) - 1] = '\0';
+
+ /* Put maximum */
+ Length = sizeof(Buffer);
+ }
+
+ /* Print the message */
+ DPRINTM(DPRINT_SCSIPORT, "%s", Buffer);
+
+ /* Cleanup */
+ va_end(ap);
+}
+
+VOID
+DDKAPI
+ScsiPortCompleteRequest(
+ IN PVOID HwDeviceExtension,
+ IN UCHAR PathId,
+ IN UCHAR TargetId,
+ IN UCHAR Lun,
+ IN UCHAR SrbStatus)
+{
+ // FIXME
+ UNIMPLEMENTED;
+}
+
+#undef ScsiPortConvertPhysicalAddressToUlong
+ULONG
+DDKAPI
+ScsiPortConvertPhysicalAddressToUlong(
+ IN SCSI_PHYSICAL_ADDRESS Address)
+{
+ return Address.LowPart;
+}
+
+SCSI_PHYSICAL_ADDRESS
+DDKAPI
+ScsiPortConvertUlongToPhysicalAddress(
+ IN ULONG UlongAddress)
+{
+ return RtlConvertUlongToLargeInteger(UlongAddress);
+}
+
+VOID
+DDKAPI
+ScsiPortFlushDma(
+ IN PVOID DeviceExtension)
+{
+ // FIXME
+ UNIMPLEMENTED;
+}
+
+VOID
+DDKAPI
+ScsiPortFreeDeviceBase(
+ IN PVOID HwDeviceExtension,
+ IN PVOID MappedAddress)
+{
+ // Nothing to do
+}
+
+ULONG
+DDKAPI
+ScsiPortGetBusData(
+ IN PVOID DeviceExtension,
+ IN ULONG BusDataType,
+ IN ULONG SystemIoBusNumber,
+ IN ULONG SlotNumber,
+ IN PVOID Buffer,
+ IN ULONG Length)
+{
+ return HalGetBusDataByOffset(BusDataType, SystemIoBusNumber, SlotNumber, Buffer, 0,
Length);
+}
+
+PVOID
+DDKAPI
+ScsiPortGetDeviceBase(
+ IN PVOID HwDeviceExtension,
+ IN INTERFACE_TYPE BusType,
+ IN ULONG SystemIoBusNumber,
+ IN SCSI_PHYSICAL_ADDRESS IoAddress,
+ IN ULONG NumberOfBytes,
+ IN BOOLEAN InIoSpace)
+{
+ PHYSICAL_ADDRESS TranslatedAddress;
+ ULONG AddressSpace;
+
+ AddressSpace = (ULONG)InIoSpace;
+ if (HalTranslateBusAddress(BusType,
+ SystemIoBusNumber,
+ IoAddress,
+ &AddressSpace,
+ &TranslatedAddress) == FALSE)
+ {
+ return NULL;
+ }
+
+ /* I/O space */
+ if (AddressSpace != 0)
+ return (PVOID)TranslatedAddress.u.LowPart;
+
+ // FIXME
+ UNIMPLEMENTED;
+ return (PVOID)IoAddress.LowPart;
+}
+
+PVOID
+DDKAPI
+ScsiPortGetLogicalUnit(
+ IN PVOID HwDeviceExtension,
+ IN UCHAR PathId,
+ IN UCHAR TargetId,
+ IN UCHAR Lun)
+{
+ // FIXME
+ UNIMPLEMENTED;
+ return NULL;
+}
+
+SCSI_PHYSICAL_ADDRESS
+DDKAPI
+ScsiPortGetPhysicalAddress(
+ IN PVOID HwDeviceExtension,
+ IN PSCSI_REQUEST_BLOCK Srb OPTIONAL,
+ IN PVOID VirtualAddress,
+ OUT ULONG *Length)
+{
+ PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
+ SCSI_PHYSICAL_ADDRESS PhysicalAddress;
+ ULONG BufferLength = 0;
+ ULONG Offset;
+
+ DPRINTM2("ScsiPortGetPhysicalAddress(%p %p %p %p)\n",
+ HwDeviceExtension, Srb, VirtualAddress, Length);
+
+ DeviceExtension = ((PSCSI_PORT_DEVICE_EXTENSION)HwDeviceExtension) - 1;
+
+ if (Srb == NULL || Srb->SenseInfoBuffer == VirtualAddress)
+ {
+ /* Simply look it up in the allocated common buffer */
+ Offset = (PUCHAR)VirtualAddress -
(PUCHAR)DeviceExtension->SrbExtensionBuffer;
+
+ BufferLength = DeviceExtension->CommonBufferLength - Offset;
+ PhysicalAddress.QuadPart = Offset;
+ }
+ else
+ {
+ /* Nothing */
+ *Length = 0;
+ PhysicalAddress.QuadPart = (LONGLONG)(SP_UNINITIALIZED_VALUE);
+ }
+
+ *Length = BufferLength;
+ return PhysicalAddress;
+}
+
+PSCSI_REQUEST_BLOCK
+DDKAPI
+ScsiPortGetSrb(
+ IN PVOID DeviceExtension,
+ IN UCHAR PathId,
+ IN UCHAR TargetId,
+ IN UCHAR Lun,
+ IN LONG QueueTag)
+{
+ // FIXME
+ UNIMPLEMENTED;
+ return NULL;
+}
+
+NTSTATUS
+SpiAllocateCommonBuffer(
+ IN OUT PSCSI_PORT_DEVICE_EXTENSION DeviceExtension,
+ IN ULONG NonCachedSize)
+{
+ PVOID CommonBuffer;
+ ULONG CommonBufferLength, BufSize;
+
+ /* If size is 0, set it to 16 */
+ if (!DeviceExtension->SrbExtensionSize)
+ DeviceExtension->SrbExtensionSize = 16;
+
+ /* Calculate size */
+ BufSize = DeviceExtension->SrbExtensionSize;
+
+ /* Round it */
+ BufSize = (BufSize + sizeof(LONGLONG) - 1) & ~(sizeof(LONGLONG) - 1);
+
+ /* Sum up into the total common buffer length, and round it to page size */
+ CommonBufferLength =
+ ROUND_TO_PAGES(NonCachedSize);
+
+ /* Allocate it */
+ if (!DeviceExtension->AdapterObject)
+ {
+ /* From nonpaged pool if there is no DMA */
+ CommonBuffer = ExAllocatePool(NonPagedPool, CommonBufferLength);
+ }
+ else
+ {
+ /* Perform a full request since we have a DMA adapter*/
+ UNIMPLEMENTED;
+ CommonBuffer = NULL;
+ }
+
+ /* Fail in case of error */
+ if (!CommonBuffer)
+ return STATUS_INSUFFICIENT_RESOURCES;
+
+ /* Zero it */
+ RtlZeroMemory(CommonBuffer, CommonBufferLength);
+
+ /* Store its size in Device Extension */
+ DeviceExtension->CommonBufferLength = CommonBufferLength;
+
+ /* SrbExtension buffer is located at the beginning of the buffer */
+ DeviceExtension->SrbExtensionBuffer = CommonBuffer;
+
+ /* Non-cached extension buffer is located at the end of
+ the common buffer */
+ if (NonCachedSize)
+ {
+ CommonBufferLength -= NonCachedSize;
+ DeviceExtension->NonCachedExtension = (PUCHAR)CommonBuffer +
CommonBufferLength;
+ }
+ else
+ {
+ DeviceExtension->NonCachedExtension = NULL;
+ }
+
+ return STATUS_SUCCESS;
+}
+
+PVOID
+DDKAPI
+ScsiPortGetUncachedExtension(
+ IN PVOID HwDeviceExtension,
+ IN PPORT_CONFIGURATION_INFORMATION ConfigInfo,
+ IN ULONG NumberOfBytes)
+{
+ PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
+ DEVICE_DESCRIPTION DeviceDescription;
+ ULONG MapRegistersCount;
+ NTSTATUS Status;
+
+ DPRINTM2("ScsiPortGetUncachedExtension(%p %p %lu)\n",
+ HwDeviceExtension, ConfigInfo, NumberOfBytes);
+
+ DeviceExtension = ((PSCSI_PORT_DEVICE_EXTENSION)HwDeviceExtension) - 1;
+
+ /* Check for allocated common DMA buffer */
+ if (DeviceExtension->SrbExtensionBuffer != NULL)
+ {
+ return NULL;
+ }
+
+ /* Check for DMA adapter object */
+ if (DeviceExtension->AdapterObject == NULL)
+ {
+ /* Initialize DMA adapter description */
+ RtlZeroMemory(&DeviceDescription, sizeof(DEVICE_DESCRIPTION));
+
+ DeviceDescription.Version = DEVICE_DESCRIPTION_VERSION;
+ DeviceDescription.Master = ConfigInfo->Master;
+ DeviceDescription.ScatterGather = ConfigInfo->ScatterGather;
+ DeviceDescription.DemandMode = ConfigInfo->DemandMode;
+ DeviceDescription.Dma32BitAddresses = ConfigInfo->Dma32BitAddresses;
+ DeviceDescription.BusNumber = ConfigInfo->SystemIoBusNumber;
+ DeviceDescription.DmaChannel = ConfigInfo->DmaChannel;
+ DeviceDescription.InterfaceType = ConfigInfo->AdapterInterfaceType;
+ DeviceDescription.DmaWidth = ConfigInfo->DmaWidth;
+ DeviceDescription.DmaSpeed = ConfigInfo->DmaSpeed;
+ DeviceDescription.MaximumLength = ConfigInfo->MaximumTransferLength;
+ DeviceDescription.DmaPort = ConfigInfo->DmaPort;
+
+ /* Get a DMA adapter object */
+#if 0
+ DeviceExtension->AdapterObject =
+ HalGetAdapter(&DeviceDescription, &MapRegistersCount);
+
+ /* Fail in case of error */
+ if (DeviceExtension->AdapterObject == NULL)
+ {
+ return NULL;
+ }
+#else
+ MapRegistersCount = 0;
+#endif
+
+ /* Set number of physical breaks */
+ if (ConfigInfo->NumberOfPhysicalBreaks != 0 &&
+ MapRegistersCount > ConfigInfo->NumberOfPhysicalBreaks)
+ {
+ DeviceExtension->PortCapabilities.MaximumPhysicalPages =
+ ConfigInfo->NumberOfPhysicalBreaks;
+ }
+ else
+ {
+ DeviceExtension->PortCapabilities.MaximumPhysicalPages =
MapRegistersCount;
+ }
+ }
+
+ /* Update Srb extension size */
+ if (DeviceExtension->SrbExtensionSize != ConfigInfo->SrbExtensionSize)
+ DeviceExtension->SrbExtensionSize = ConfigInfo->SrbExtensionSize;
+
+ /* Allocate a common DMA buffer */
+ Status = SpiAllocateCommonBuffer(DeviceExtension, NumberOfBytes);
+
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINTM2("SpiAllocateCommonBuffer() failed with Status = 0x%08X!\n",
Status);
+ return NULL;
+ }
+
+ return DeviceExtension->NonCachedExtension;
+}
+
+PVOID
+DDKAPI
+ScsiPortGetVirtualAddress(
+ IN PVOID HwDeviceExtension,
+ IN SCSI_PHYSICAL_ADDRESS PhysicalAddress)
+{
+ // FIXME
+ UNIMPLEMENTED;
+ return NULL;
+}
+
+VOID
+SpiScanDevice(
+ IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension,
+ IN PCHAR ArcName,
+ IN ULONG ScsiBus,
+ IN ULONG TargetId,
+ IN ULONG Lun)
+{
+ ULONG FileId, i;
+ ULONG Status;
+ NTSTATUS ret;
+ struct _DRIVE_LAYOUT_INFORMATION *PartitionBuffer;
+ CHAR PartitionName[64];
+
+ /* Register device with partition(0) suffix */
+ sprintf(PartitionName, "%spartition(0)", ArcName);
+ FsRegisterDevice(PartitionName, &DiskVtbl);
+
+ /* Read device partition table */
+ Status = ArcOpen(PartitionName, OpenReadOnly, &FileId);
+ if (Status == ESUCCESS)
+ {
+ ret = HALDISPATCH->HalIoReadPartitionTable((PDEVICE_OBJECT)FileId, 512, FALSE,
&PartitionBuffer);
+ if (NT_SUCCESS(ret))
+ {
+ for (i = 0; i < PartitionBuffer->PartitionCount; i++)
+ {
+ if (PartitionBuffer->PartitionEntry[i].PartitionType !=
PARTITION_ENTRY_UNUSED)
+ {
+ sprintf(PartitionName, "%spartition(%lu)",
+ ArcName,
PartitionBuffer->PartitionEntry[i].PartitionNumber);
+ FsRegisterDevice(PartitionName, &DiskVtbl);
+ }
+ }
+ ExFreePool(PartitionBuffer);
+ }
+ ArcClose(FileId);
+ }
+}
+
+VOID
+SpiScanAdapter(
+ IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension,
+ IN ULONG ScsiBus,
+ IN ULONG PathId)
+{
+ CHAR ArcName[64];
+ PSCSI_REQUEST_BLOCK Srb;
+ PCDB Cdb;
+ INQUIRYDATA InquiryBuffer;
+ ULONG TargetId;
+ ULONG Lun;
+
+ if (!DeviceExtension->HwResetBus(DeviceExtension->MiniPortDeviceExtension,
PathId))
+ {
+ return;
+ }
+
+ /* Remember the extension */
+ ScsiDeviceExtensions[ScsiBus] = DeviceExtension;
+
+ for (TargetId = 0; TargetId < DeviceExtension->MaxTargedIds; TargetId++)
+ {
+ Lun = 0;
+ do
+ {
+ DPRINTM2("Scanning SCSI device %d.%d.%d\n",
+ ScsiBus, TargetId, Lun);
+
+ Srb = ExAllocatePool(PagedPool, sizeof(SCSI_REQUEST_BLOCK));
+ if (!Srb)
+ break;
+ RtlZeroMemory(Srb, sizeof(SCSI_REQUEST_BLOCK));
+ Srb->Length = sizeof(SCSI_REQUEST_BLOCK);
+ Srb->Function = SRB_FUNCTION_EXECUTE_SCSI;
+ Srb->PathId = PathId;
+ Srb->TargetId = TargetId;
+ Srb->Lun = Lun;
+ Srb->CdbLength = 6;
+ Srb->SrbFlags = SRB_FLAGS_DATA_IN;
+ Srb->DataTransferLength = INQUIRYDATABUFFERSIZE;
+ Srb->TimeOutValue = 5; /* in seconds */
+ Srb->DataBuffer = &InquiryBuffer;
+ Cdb = (PCDB)Srb->Cdb;
+ Cdb->CDB6INQUIRY.OperationCode = SCSIOP_INQUIRY;
+ Cdb->CDB6INQUIRY.LogicalUnitNumber = Srb->Lun;
+ Cdb->CDB6INQUIRY.AllocationLength = Srb->DataTransferLength;
+ if (!SpiSendSynchronousSrb(DeviceExtension, Srb))
+ {
+ /* Don't check next LUNs */
+ break;
+ }
+
+ /* Device exists, create its ARC name */
+ if (InquiryBuffer.RemovableMedia)
+ {
+ sprintf(ArcName, "scsi(%ld)cdrom(%ld)fdisk(%ld)",
+ ScsiBus, TargetId, Lun);
+ FsRegisterDevice(ArcName, &DiskVtbl);
+ }
+ else
+ {
+ sprintf(ArcName, "scsi(%ld)disk(%ld)rdisk(%ld)",
+ ScsiBus, TargetId, Lun);
+ /* Now, check if it has partitions */
+ SpiScanDevice(DeviceExtension, ArcName, PathId, TargetId, Lun);
+ }
+
+ /* Check next LUN */
+ Lun++;
+ } while (Lun < SCSI_MAXIMUM_LOGICAL_UNITS);
+ }
+}
+
+VOID
+SpiResourceToConfig(
+ IN PHW_INITIALIZATION_DATA HwInitializationData,
+ IN PCM_FULL_RESOURCE_DESCRIPTOR ResourceDescriptor,
+ IN OUT PPORT_CONFIGURATION_INFORMATION PortConfig)
+{
+ PACCESS_RANGE AccessRange;
+ PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialData;
+ ULONG RangeNumber;
+ ULONG Index;
+
+ RangeNumber = 0;
+
+ /* Loop through all entries */
+ for (Index = 0; Index < ResourceDescriptor->PartialResourceList.Count;
Index++)
+ {
+ PartialData =
&ResourceDescriptor->PartialResourceList.PartialDescriptors[Index];
+
+ switch (PartialData->Type)
+ {
+ case CmResourceTypePort:
+ /* Copy access ranges */
+ if (RangeNumber < HwInitializationData->NumberOfAccessRanges)
+ {
+ DPRINTM2("Got port at 0x%I64x, len 0x%x\n",
+ PartialData->u.Port.Start.QuadPart,
PartialData->u.Port.Length);
+ AccessRange = &((*(PortConfig->AccessRanges))[RangeNumber]);
+
+ AccessRange->RangeStart = PartialData->u.Port.Start;
+ AccessRange->RangeLength = PartialData->u.Port.Length;
+
+ AccessRange->RangeInMemory = FALSE;
+ RangeNumber++;
+ }
+ break;
+
+ case CmResourceTypeMemory:
+ /* Copy access ranges */
+ if (RangeNumber < HwInitializationData->NumberOfAccessRanges)
+ {
+ DPRINTM2("Got memory at 0x%I64x, len 0x%x\n",
+ PartialData->u.Memory.Start.QuadPart,
PartialData->u.Memory.Length);
+ AccessRange = &((*(PortConfig->AccessRanges))[RangeNumber]);
+
+ AccessRange->RangeStart = PartialData->u.Memory.Start;
+ AccessRange->RangeLength = PartialData->u.Memory.Length;
+
+ AccessRange->RangeInMemory = TRUE;
+ RangeNumber++;
+ }
+ break;
+
+ case CmResourceTypeInterrupt:
+ /* Copy interrupt data */
+ DPRINTM2("Got interrupt level %d, vector %d\n",
+ PartialData->u.Interrupt.Level, PartialData->u.Interrupt.Vector);
+ PortConfig->BusInterruptLevel = PartialData->u.Interrupt.Level;
+ PortConfig->BusInterruptVector = PartialData->u.Interrupt.Vector;
+
+ /* Set interrupt mode accordingly to the resource */
+ if (PartialData->Flags == CM_RESOURCE_INTERRUPT_LATCHED)
+ {
+ PortConfig->InterruptMode = Latched;
+ }
+ else if (PartialData->Flags == CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE)
+ {
+ PortConfig->InterruptMode = LevelSensitive;
+ }
+ break;
+
+ case CmResourceTypeDma:
+ DPRINTM2("Got DMA channel %d, port %d\n",
+ PartialData->u.Dma.Channel, PartialData->u.Dma.Port);
+ PortConfig->DmaChannel = PartialData->u.Dma.Channel;
+ PortConfig->DmaPort = PartialData->u.Dma.Port;
+ break;
+ }
+ }
+}
+
+BOOLEAN
+SpiGetPciConfigData(
+ IN struct _HW_INITIALIZATION_DATA *HwInitializationData,
+ IN OUT PPORT_CONFIGURATION_INFORMATION PortConfig,
+ IN ULONG BusNumber,
+ IN OUT PPCI_SLOT_NUMBER NextSlotNumber)
+{
+ PCI_COMMON_CONFIG PciConfig;
+ PCI_SLOT_NUMBER SlotNumber;
+ ULONG DataSize;
+ ULONG DeviceNumber;
+ ULONG FunctionNumber;
+ CHAR VendorIdString[8];
+ CHAR DeviceIdString[8];
+ PCM_RESOURCE_LIST ResourceList;
+ NTSTATUS Status;
+
+ RtlZeroMemory(&ResourceList, sizeof(PCM_RESOURCE_LIST));
+ SlotNumber.u.AsULONG = 0;
+
+ /* Loop through all devices */
+ for (DeviceNumber = NextSlotNumber->u.bits.DeviceNumber; DeviceNumber <
PCI_MAX_DEVICES; DeviceNumber++)
+ {
+ SlotNumber.u.bits.DeviceNumber = DeviceNumber;
+
+ /* Loop through all functions */
+ for (FunctionNumber = NextSlotNumber->u.bits.FunctionNumber; FunctionNumber
< PCI_MAX_FUNCTION; FunctionNumber++)
+ {
+ SlotNumber.u.bits.FunctionNumber = FunctionNumber;
+
+ /* Get PCI config bytes */
+ DataSize = HalGetBusDataByOffset(
+ PCIConfiguration,
+ BusNumber,
+ SlotNumber.u.AsULONG,
+ &PciConfig,
+ 0,
+ sizeof(ULONG));
+
+ /* If result of HalGetBusData is 0, then the bus is wrong */
+ if (DataSize == 0)
+ return FALSE;
+
+ /* If result is PCI_INVALID_VENDORID, then this device has no more
+ "Functions" */
+ if (PciConfig.VendorID == PCI_INVALID_VENDORID)
+ break;
+
+ sprintf(VendorIdString, "%04hx", PciConfig.VendorID);
+ sprintf(DeviceIdString, "%04hx", PciConfig.DeviceID);
+
+ if (_strnicmp(VendorIdString, HwInitializationData->VendorId,
HwInitializationData->VendorIdLength) ||
+ _strnicmp(DeviceIdString, HwInitializationData->DeviceId,
HwInitializationData->DeviceIdLength))
+ {
+ /* It is not our device */
+ continue;
+ }
+
+ DPRINTM2( "Found device 0x%04hx 0x%04hx at %1lu %2lu %1lu\n",
+ PciConfig.VendorID, PciConfig.DeviceID,
+ BusNumber,
+ SlotNumber.u.bits.DeviceNumber, SlotNumber.u.bits.FunctionNumber);
+
+ Status = HalAssignSlotResources(NULL,
+ NULL,
+ NULL,
+ NULL,
+ PCIBus,
+ BusNumber,
+ SlotNumber.u.AsULONG,
+ &ResourceList);
+
+ if (!NT_SUCCESS(Status))
+ break;
+
+ /* Create configuration information */
+ SpiResourceToConfig(HwInitializationData,
+ ResourceList->List,
+ PortConfig);
+
+ /* Free the resource list */
+ ExFreePool(ResourceList);
+
+ /* Set dev & fn numbers */
+ NextSlotNumber->u.bits.DeviceNumber = DeviceNumber;
+ NextSlotNumber->u.bits.FunctionNumber = FunctionNumber + 1;
+
+ /* Save the slot number */
+ PortConfig->SlotNumber = SlotNumber.u.AsULONG;
+
+ return TRUE;
+ }
+ NextSlotNumber->u.bits.FunctionNumber = 0;
+ }
+
+ NextSlotNumber->u.bits.DeviceNumber = 0;
+
+ return FALSE;
+}
+
+ULONG
+DDKAPI
+ScsiPortInitialize(
+ IN PVOID Argument1,
+ IN PVOID Argument2,
+ IN struct _HW_INITIALIZATION_DATA *HwInitializationData,
+ IN PVOID HwContext OPTIONAL)
+{
+ PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
+ ULONG DeviceExtensionSize;
+ PORT_CONFIGURATION_INFORMATION PortConfig;
+ BOOLEAN Again;
+ BOOLEAN FirstConfigCall = TRUE;
+ PCI_SLOT_NUMBER SlotNumber;
+ NTSTATUS Status;
+
+ if (HwInitializationData->HwInitializationDataSize !=
sizeof(HW_INITIALIZATION_DATA))
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ /* Check params for validity */
+ if ((HwInitializationData->HwInitialize == NULL) ||
+ (HwInitializationData->HwStartIo == NULL) ||
+ (HwInitializationData->HwInterrupt == NULL) ||
+ (HwInitializationData->HwFindAdapter == NULL) ||
+ (HwInitializationData->HwResetBus == NULL))
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ /* Zero starting slot number */
+ SlotNumber.u.AsULONG = 0;
+
+ while (TRUE)
+ {
+ Again = FALSE;
+
+ DeviceExtensionSize = sizeof(SCSI_PORT_DEVICE_EXTENSION) +
HwInitializationData->DeviceExtensionSize;
+ DeviceExtension = MmHeapAlloc(DeviceExtensionSize);
+ if (!DeviceExtension)
+ {
+ return STATUS_NO_MEMORY;
+ }
+ RtlZeroMemory(DeviceExtension, DeviceExtensionSize);
+ DeviceExtension->InterruptFlags = SCSI_PORT_NEXT_REQUEST_READY;
+ DeviceExtension->HwInitialize = HwInitializationData->HwInitialize;
+ DeviceExtension->HwStartIo = HwInitializationData->HwStartIo;
+ DeviceExtension->HwInterrupt = HwInitializationData->HwInterrupt;
+ DeviceExtension->HwResetBus = HwInitializationData->HwResetBus;
+ DeviceExtension->MiniPortDeviceExtension = (PVOID)(DeviceExtension + 1);
+
+ Status = SpiCreatePortConfig(DeviceExtension,
+ HwInitializationData,
+ &PortConfig,
+ FirstConfigCall);
+ if (Status != STATUS_SUCCESS)
+ {
+ MmHeapFree(DeviceExtension);
+ return Status;
+ }
+
+ PortConfig.NumberOfAccessRanges = HwInitializationData->NumberOfAccessRanges;
+ PortConfig.AccessRanges = MmHeapAlloc(sizeof(ACCESS_RANGE) *
HwInitializationData->NumberOfAccessRanges);
+ if (!PortConfig.AccessRanges)
+ {
+ MmHeapFree(DeviceExtension);
+ return STATUS_NO_MEMORY;
+ }
+ RtlZeroMemory(PortConfig.AccessRanges, sizeof(ACCESS_RANGE) *
HwInitializationData->NumberOfAccessRanges);
+
+ /* Search for matching PCI device */
+ if ((HwInitializationData->AdapterInterfaceType == PCIBus) &&
+ (HwInitializationData->VendorIdLength > 0) &&
+ (HwInitializationData->VendorId != NULL) &&
+ (HwInitializationData->DeviceIdLength > 0) &&
+ (HwInitializationData->DeviceId != NULL))
+ {
+ PortConfig.BusInterruptLevel = 0;
+
+ /* Get PCI device data */
+ DPRINTM2("VendorId '%.*s' DeviceId '%.*s'\n",
+ HwInitializationData->VendorIdLength,
+ HwInitializationData->VendorId,
+ HwInitializationData->DeviceIdLength,
+ HwInitializationData->DeviceId);
+
+ if (!SpiGetPciConfigData(HwInitializationData,
+ &PortConfig,
+ 0, /* FIXME */
+ &SlotNumber))
+ {
+ /* Continue to the next bus, nothing here */
+ MmHeapFree(DeviceExtension);
+ return STATUS_INTERNAL_ERROR;
+ }
+
+ if (!PortConfig.BusInterruptLevel)
+ {
+ /* Bypass this slot, because no interrupt was assigned */
+ MmHeapFree(DeviceExtension);
+ return STATUS_INTERNAL_ERROR;
+ }
+ }
+
+ if (HwInitializationData->HwFindAdapter(
+ DeviceExtension->MiniPortDeviceExtension,
+ HwContext,
+ NULL,
+ NULL,
+ &PortConfig,
+ &Again) != SP_RETURN_FOUND)
+ {
+ MmHeapFree(DeviceExtension);
+ return STATUS_INTERNAL_ERROR;
+ }
+
+ /* Copy all stuff which we ever need from PortConfig to the DeviceExtension */
+ if (PortConfig.MaximumNumberOfTargets > SCSI_MAXIMUM_TARGETS_PER_BUS)
+ DeviceExtension->MaxTargedIds = SCSI_MAXIMUM_TARGETS_PER_BUS;
+ else
+ DeviceExtension->MaxTargedIds = PortConfig.MaximumNumberOfTargets;
+
+ DeviceExtension->BusNum = PortConfig.SystemIoBusNumber;
+
+ DPRINTM2("Adapter found: buses = %d, targets = %d\n",
+ PortConfig.NumberOfBuses, DeviceExtension->MaxTargedIds);
+
+ /* Initialize adapter */
+ if
(!DeviceExtension->HwInitialize(DeviceExtension->MiniPortDeviceExtension))
+ {
+ MmHeapFree(DeviceExtension);
+ return STATUS_INTERNAL_ERROR;
+ }
+
+ /* Scan bus */
+ {
+ ULONG ScsiBus;
+ for (ScsiBus = 0; ScsiBus < PortConfig.NumberOfBuses; ScsiBus++)
+ {
+ SpiScanAdapter(DeviceExtension, PortConfig.SystemIoBusNumber, ScsiBus);
+ PortConfig.SystemIoBusNumber++;
+ }
+ }
+
+ FirstConfigCall = FALSE;
+ if (!Again)
+ {
+ break;
+ }
+ }
+
+ return STATUS_SUCCESS;
+}
+
+VOID
+DDKAPI
+ScsiPortIoMapTransfer(
+ IN PVOID HwDeviceExtension,
+ IN PSCSI_REQUEST_BLOCK Srb,
+ IN PVOID LogicalAddress,
+ IN ULONG Length)
+{
+ // FIXME
+ UNIMPLEMENTED;
+}
+
+VOID
+DDKAPI
+ScsiPortLogError(
+ IN PVOID HwDeviceExtension,
+ IN PSCSI_REQUEST_BLOCK Srb OPTIONAL,
+ IN UCHAR PathId,
+ IN UCHAR TargetId,
+ IN UCHAR Lun,
+ IN ULONG ErrorCode,
+ IN ULONG UniqueId)
+{
+ // FIXME
+ UNIMPLEMENTED;
+}
+
+VOID
+DDKAPI
+ScsiPortMoveMemory(
+ IN PVOID WriteBuffer,
+ IN PVOID ReadBuffer,
+ IN ULONG Length)
+{
+ RtlMoveMemory(WriteBuffer, ReadBuffer, Length);
+}
+
+VOID
+DDKCDECLAPI
+ScsiPortNotification(
+ IN SCSI_NOTIFICATION_TYPE NotificationType,
+ IN PVOID HwDeviceExtension,
+ IN ...)
+{
+ PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
+ PSCSI_REQUEST_BLOCK Srb;
+ va_list ap;
+
+ DeviceExtension = ((PSCSI_PORT_DEVICE_EXTENSION)HwDeviceExtension) - 1;
+
+ va_start(ap, HwDeviceExtension);
+
+ switch (NotificationType)
+ {
+ case RequestComplete:
+ /* Mask the SRB as completed */
+ Srb = va_arg(ap, PSCSI_REQUEST_BLOCK);
+ Srb->SrbFlags &= ~SRB_FLAGS_IS_ACTIVE;
+ break;
+
+ case NextRequest:
+ /* Say that device is ready */
+ DeviceExtension->InterruptFlags |= SCSI_PORT_NEXT_REQUEST_READY;
+ break;
+
+ default:
+ // FIXME
+ UNIMPLEMENTED;
+ }
+
+ va_end(ap);
+}
+
+VOID
+DDKAPI
+ScsiPortReadPortBufferUchar(
+ IN PUCHAR Port,
+ OUT PUCHAR Buffer,
+ IN ULONG Count)
+{
+ __inbytestring(H2I(Port), Buffer, Count);
+}
+
+VOID
+DDKAPI
+ScsiPortReadPortBufferUlong(
+ IN PULONG Port,
+ OUT PULONG Buffer,
+ IN ULONG Count)
+{
+ __indwordstring(H2I(Port), Buffer, Count);
+}
+
+VOID
+DDKAPI
+ScsiPortReadPortBufferUshort(
+ IN PUSHORT Port,
+ OUT PUSHORT Buffer,
+ IN ULONG Count)
+{
+ __inwordstring(H2I(Port), Buffer, Count);
+}
+
+UCHAR
+DDKAPI
+ScsiPortReadPortUchar(
+ IN PUCHAR Port)
+{
+ DPRINTM2("ScsiPortReadPortUchar(%p)\n",
+ Port);
+
+ return READ_PORT_UCHAR(Port);
+}
+
+ULONG
+DDKAPI
+ScsiPortReadPortUlong(
+ IN PULONG Port)
+{
+ return READ_PORT_ULONG(Port);
+}
+
+USHORT
+DDKAPI
+ScsiPortReadPortUshort(
+ IN PUSHORT Port)
+{
+ return READ_PORT_USHORT(Port);
+}
+
+VOID
+DDKAPI
+ScsiPortReadRegisterBufferUchar(
+ IN PUCHAR Register,
+ IN PUCHAR Buffer,
+ IN ULONG Count)
+{
+ // FIXME
+ UNIMPLEMENTED;
+}
+
+VOID
+DDKAPI
+ScsiPortReadRegisterBufferUlong(
+ IN PULONG Register,
+ IN PULONG Buffer,
+ IN ULONG Count)
+{
+ // FIXME
+ UNIMPLEMENTED;
+}
+
+VOID
+DDKAPI
+ScsiPortReadRegisterBufferUshort(
+ IN PUSHORT Register,
+ IN PUSHORT Buffer,
+ IN ULONG Count)
+{
+ // FIXME
+ UNIMPLEMENTED;
+}
+
+UCHAR
+DDKAPI
+ScsiPortReadRegisterUchar(
+ IN PUCHAR Register)
+{
+ return READ_REGISTER_UCHAR(Register);
+}
+
+ULONG
+DDKAPI
+ScsiPortReadRegisterUlong(
+ IN PULONG Register)
+{
+ return READ_REGISTER_ULONG(Register);
+}
+
+USHORT
+DDKAPI
+ScsiPortReadRegisterUshort(
+ IN PUSHORT Register)
+{
+ return READ_REGISTER_USHORT(Register);
+}
+
+ULONG
+DDKAPI
+ScsiPortSetBusDataByOffset(
+ IN PVOID DeviceExtension,
+ IN ULONG BusDataType,
+ IN ULONG SystemIoBusNumber,
+ IN ULONG SlotNumber,
+ IN PVOID Buffer,
+ IN ULONG Offset,
+ IN ULONG Length)
+{
+ // FIXME
+ UNIMPLEMENTED;
+ return 0;
+}
+
+VOID
+DDKAPI
+ScsiPortStallExecution(
+ IN ULONG Delay)
+{
+ KeStallExecutionProcessor(Delay);
+}
+
+BOOLEAN
+DDKAPI
+ScsiPortValidateRange(
+ IN PVOID HwDeviceExtension,
+ IN INTERFACE_TYPE BusType,
+ IN ULONG SystemIoBusNumber,
+ IN SCSI_PHYSICAL_ADDRESS IoAddress,
+ IN ULONG NumberOfBytes,
+ IN BOOLEAN InIoSpace)
+{
+ // FIXME
+ UNIMPLEMENTED;
+ return TRUE;
+}
+
+#if 0
+// ScsiPortWmi*
+#endif
+
+
+VOID
+DDKAPI
+ScsiPortWritePortBufferUchar(
+ IN PUCHAR Port,
+ IN PUCHAR Buffer,
+ IN ULONG Count)
+{
+ __outbytestring(H2I(Port), Buffer, Count);
+}
+
+VOID
+DDKAPI
+ScsiPortWritePortBufferUlong(
+ IN PULONG Port,
+ IN PULONG Buffer,
+ IN ULONG Count)
+{
+ __outdwordstring(H2I(Port), Buffer, Count);
+}
+
+VOID
+DDKAPI
+ScsiPortWritePortBufferUshort(
+ IN PUSHORT Port,
+ IN PUSHORT Buffer,
+ IN ULONG Count)
+{
+ __outwordstring(H2I(Port), Buffer, Count);
+}
+
+VOID
+DDKAPI
+ScsiPortWritePortUchar(
+ IN PUCHAR Port,
+ IN UCHAR Value)
+{
+ WRITE_PORT_UCHAR(Port, Value);
+}
+
+VOID
+DDKAPI
+ScsiPortWritePortUlong(
+ IN PULONG Port,
+ IN ULONG Value)
+{
+ WRITE_PORT_ULONG(Port, Value);
+}
+
+VOID
+DDKAPI
+ScsiPortWritePortUshort(
+ IN PUSHORT Port,
+ IN USHORT Value)
+{
+ WRITE_PORT_USHORT(Port, Value);
+}
+
+VOID
+DDKAPI
+ScsiPortWriteRegisterBufferUchar(
+ IN PUCHAR Register,
+ IN PUCHAR Buffer,
+ IN ULONG Count)
+{
+ // FIXME
+ UNIMPLEMENTED;
+}
+
+VOID
+DDKAPI
+ScsiPortWriteRegisterBufferUlong(
+ IN PULONG Register,
+ IN PULONG Buffer,
+ IN ULONG Count)
+{
+ // FIXME
+ UNIMPLEMENTED;
+}
+
+VOID
+DDKAPI
+ScsiPortWriteRegisterBufferUshort(
+ IN PUSHORT Register,
+ IN PUSHORT Buffer,
+ IN ULONG Count)
+{
+ // FIXME
+ UNIMPLEMENTED;
+}
+
+VOID
+DDKAPI
+ScsiPortWriteRegisterUchar(
+ IN PUCHAR Register,
+ IN ULONG Value)
+{
+ WRITE_REGISTER_UCHAR(Register, Value);
+}
+
+VOID
+DDKAPI
+ScsiPortWriteRegisterUlong(
+ IN PULONG Register,
+ IN ULONG Value)
+{
+ WRITE_REGISTER_ULONG(Register, Value);
+}
+
+VOID
+DDKAPI
+ScsiPortWriteRegisterUshort(
+ IN PUSHORT Register,
+ IN USHORT Value)
+{
+ WRITE_REGISTER_USHORT(Register, Value);
+}
+
+ULONG
+LoadBootDeviceDriver(VOID)
+{
+ struct
+ {
+ CHAR* Name;
+ PVOID Function;
+ } ExportTable[] =
+ {
+ { "ScsiDebugPrint", ScsiDebugPrint },
+ { "ScsiPortCompleteRequest", ScsiPortCompleteRequest },
+ { "ScsiPortConvertPhysicalAddressToUlong",
ScsiPortConvertPhysicalAddressToUlong },
+ { "ScsiPortConvertUlongToPhysicalAddress",
ScsiPortConvertUlongToPhysicalAddress },
+ { "ScsiPortFlushDma", ScsiPortFlushDma },
+ { "ScsiPortFreeDeviceBase", ScsiPortFreeDeviceBase },
+ { "ScsiPortGetBusData", ScsiPortGetBusData },
+ { "ScsiPortGetDeviceBase", ScsiPortGetDeviceBase },
+ { "ScsiPortGetLogicalUnit", ScsiPortGetLogicalUnit },
+ { "ScsiPortGetPhysicalAddress", ScsiPortGetPhysicalAddress },
+ { "ScsiPortGetSrb", ScsiPortGetSrb },
+ { "ScsiPortGetUncachedExtension", ScsiPortGetUncachedExtension },
+ { "ScsiPortGetVirtualAddress", ScsiPortGetVirtualAddress },
+ { "ScsiPortInitialize", ScsiPortInitialize },
+ { "ScsiPortIoMapTransfer", ScsiPortIoMapTransfer },
+ { "ScsiPortLogError", ScsiPortLogError },
+ { "ScsiPortMoveMemory", ScsiPortMoveMemory },
+ { "ScsiPortNotification", ScsiPortNotification },
+ { "ScsiPortReadPortBufferUchar", ScsiPortReadPortBufferUchar },
+ { "ScsiPortReadPortBufferUlong", ScsiPortReadPortBufferUlong },
+ { "ScsiPortReadPortBufferUshort", ScsiPortReadPortBufferUshort },
+ { "ScsiPortReadPortUchar", ScsiPortReadPortUchar },
+ { "ScsiPortReadPortUlong", ScsiPortReadPortUlong },
+ { "ScsiPortReadPortUshort", ScsiPortReadPortUshort },
+ { "ScsiPortReadRegisterBufferUchar", ScsiPortReadRegisterBufferUchar
},
+ { "ScsiPortReadRegisterBufferUlong", ScsiPortReadRegisterBufferUlong
},
+ { "ScsiPortReadRegisterBufferUshort", ScsiPortReadRegisterBufferUshort
},
+ { "ScsiPortReadRegisterUchar", ScsiPortReadRegisterUchar },
+ { "ScsiPortReadRegisterUlong", ScsiPortReadRegisterUlong },
+ { "ScsiPortReadRegisterUshort", ScsiPortReadRegisterUshort },
+ { "ScsiPortSetBusDataByOffset", ScsiPortSetBusDataByOffset },
+ { "ScsiPortStallExecution", ScsiPortStallExecution },
+ { "ScsiPortValidateRange", ScsiPortValidateRange },
+ { "ScsiPortWritePortBufferUchar", ScsiPortWritePortBufferUchar },
+ { "ScsiPortWritePortBufferUlong", ScsiPortWritePortBufferUlong },
+ { "ScsiPortWritePortBufferUshort", ScsiPortWritePortBufferUshort },
+ { "ScsiPortWritePortUchar", ScsiPortWritePortUchar },
+ { "ScsiPortWritePortUlong", ScsiPortWritePortUlong },
+ { "ScsiPortWritePortUshort", ScsiPortWritePortUshort },
+ { "ScsiPortWriteRegisterBufferUchar", ScsiPortWriteRegisterBufferUchar
},
+ { "ScsiPortWriteRegisterBufferUlong", ScsiPortWriteRegisterBufferUlong
},
+ { "ScsiPortWriteRegisterBufferUshort",
ScsiPortWriteRegisterBufferUshort },
+ { "ScsiPortWriteRegisterUchar", ScsiPortWriteRegisterUchar },
+ { "ScsiPortWriteRegisterUlong", ScsiPortWriteRegisterUlong },
+ { "ScsiPortWriteRegisterUshort", ScsiPortWriteRegisterUshort },
+ };
+ IMAGE_DOS_HEADER ImageDosHeader;
+ IMAGE_NT_HEADERS ImageNtHeaders;
+ IMAGE_EXPORT_DIRECTORY ImageExportDirectory;
+ CHAR* TableName[sizeof(ExportTable) / sizeof(ExportTable[0])];
+ USHORT OrdinalTable[sizeof(ExportTable) / sizeof(ExportTable[0])];
+ ULONG FunctionTable[sizeof(ExportTable) / sizeof(ExportTable[0])];
+
+ PIMAGE_NT_HEADERS NtHeaders;
+ LOADER_PARAMETER_BLOCK LoaderBlock;
+ PIMAGE_IMPORT_DESCRIPTOR ImportTable;
+ ULONG ImportTableSize;
+ PLDR_DATA_TABLE_ENTRY BootDdDTE, FreeldrDTE;
+ CHAR NtBootDdPath[MAX_PATH];
+ PVOID ImageBase;
+ ULONG (NTAPI *EntryPoint)(IN PVOID DriverObject, IN PVOID RegistryPath);
+ ULONG i;
+ BOOLEAN Status;
+
+ /* Some initialization of our temporary loader block */
+ RtlZeroMemory(&LoaderBlock, sizeof(LOADER_PARAMETER_BLOCK));
+ InitializeListHead(&LoaderBlock.LoadOrderListHead);
+
+ /* Create our fake executable header for freeldr.sys */
+ RtlZeroMemory(&ImageDosHeader, sizeof(IMAGE_DOS_HEADER));
+ RtlZeroMemory(&ImageNtHeaders, sizeof(IMAGE_NT_HEADERS));
+ RtlZeroMemory(&ImageExportDirectory, sizeof(IMAGE_EXPORT_DIRECTORY));
+ ImageDosHeader.e_magic = SWAPW(IMAGE_DOS_SIGNATURE);
+ ImageDosHeader.e_lfanew = SWAPD((ULONG_PTR)&ImageNtHeaders -
(ULONG_PTR)&ImageDosHeader);
+ ImageNtHeaders.Signature = IMAGE_NT_SIGNATURE;
+ ImageNtHeaders.OptionalHeader.NumberOfRvaAndSizes =
SWAPD(IMAGE_DIRECTORY_ENTRY_EXPORT + 1);
+
ImageNtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress =
+ SWAPW((ULONG_PTR)&ImageExportDirectory - (ULONG_PTR)&ImageDosHeader);
+ ImageNtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size = 1;
+ ImageExportDirectory.NumberOfNames = sizeof(ExportTable) / sizeof(ExportTable[0]);
+ ImageExportDirectory.AddressOfNames = (ULONG_PTR)TableName -
(ULONG_PTR)&ImageDosHeader;
+ ImageExportDirectory.AddressOfNameOrdinals = (ULONG_PTR)OrdinalTable -
(ULONG_PTR)&ImageDosHeader;
+ ImageExportDirectory.NumberOfFunctions = sizeof(ExportTable) /
sizeof(ExportTable[0]);
+ ImageExportDirectory.AddressOfFunctions = (ULONG_PTR)FunctionTable -
(ULONG_PTR)&ImageDosHeader;
+
+ /* Fill freeldr.sys export table */
+ for (i = 0; i < sizeof(ExportTable) / sizeof(ExportTable[0]); i++)
+ {
+ TableName[i] = PaToVa((PVOID)((ULONG_PTR)ExportTable[i].Name -
(ULONG_PTR)&ImageDosHeader));
+ OrdinalTable[i] = i;
+ FunctionTable[i] = (ULONG)((ULONG_PTR)ExportTable[i].Function -
(ULONG_PTR)&ImageDosHeader);
+ }
+
+ /* Add freeldr.sys to list of loaded executables */
+ RtlZeroMemory(FreeldrDTE, sizeof(LDR_DATA_TABLE_ENTRY));
+ Status = WinLdrAllocateDataTableEntry(&LoaderBlock, "scsiport.sys",
+ "FREELDR.SYS", &ImageDosHeader, &FreeldrDTE);
+ if (!Status)
+ return EIO;
+
+ /* Create full ntbootdd.sys path */
+ MachDiskGetBootPath(NtBootDdPath, sizeof(NtBootDdPath));
+ strcat(NtBootDdPath, "\\NTBOOTDD.SYS");
+
+ /* Load file */
+ Status = WinLdrLoadImage(NtBootDdPath, LoaderBootDriver, &ImageBase);
+ if (!Status)
+ {
+ /* That's OK. File simply doesn't exist */
+ return ESUCCESS;
+ }
+
+ /* Fix imports */
+ Status = WinLdrAllocateDataTableEntry(&LoaderBlock, "ntbootdd.sys",
+ "NTBOOTDD.SYS", ImageBase, &BootDdDTE);
+ if (!Status)
+ return EIO;
+ Status = WinLdrScanImportDescriptorTable(&LoaderBlock, "", BootDdDTE);
+ if (!Status)
+ return EIO;
+
+ /* Change imports to PA */
+ ImportTable =
(PIMAGE_IMPORT_DESCRIPTOR)RtlImageDirectoryEntryToData(VaToPa(BootDdDTE->DllBase),
+ TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &ImportTableSize);
+ for (;(ImportTable->Name != 0) && (ImportTable->FirstThunk !=
0);ImportTable++)
+ {
+ PIMAGE_THUNK_DATA ThunkData =
(PIMAGE_THUNK_DATA)VaToPa(RVA(BootDdDTE->DllBase, ImportTable->FirstThunk));
+
+ while (((PIMAGE_THUNK_DATA)ThunkData)->u1.AddressOfData != 0)
+ {
+ ThunkData->u1.Function = (ULONG)VaToPa((PVOID)ThunkData->u1.Function);
+ ThunkData++;
+ }
+ }
+
+ /* Relocate image to PA */
+ NtHeaders = RtlImageNtHeader(VaToPa(BootDdDTE->DllBase));
+ if (!NtHeaders)
+ return EIO;
+ Status = LdrRelocateImageWithBias(
+ VaToPa(BootDdDTE->DllBase),
+ NtHeaders->OptionalHeader.ImageBase - (ULONG_PTR)BootDdDTE->DllBase,
+ "FreeLdr",
+ TRUE,
+ TRUE, /* in case of conflict still return success */
+ FALSE);
+ if (!Status)
+ return EIO;
+
+ /* Call the entrypoint */
+ EntryPoint = VaToPa(BootDdDTE->EntryPoint);
+ (*EntryPoint)(NULL, NULL);
+
+ return ESUCCESS;
+}
+
+/* EOF */
Propchange: trunk/reactos/boot/freeldr/freeldr/disk/scsiport.c
------------------------------------------------------------------------------
svn:eol-style = native
Modified: trunk/reactos/boot/freeldr/freeldr/freeldr.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/freel…
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/freeldr.c [iso-8859-1] (original)
+++ trunk/reactos/boot/freeldr/freeldr/freeldr.c [iso-8859-1] Mon Mar 8 23:04:38 2010
@@ -19,6 +19,9 @@
#include <freeldr.h>
#include <debug.h>
+
+VOID NTAPI HalpInitializePciStubs(VOID);
+VOID NTAPI HalpInitBusHandler(VOID);
VOID BootMain(LPSTR CmdLine)
{
@@ -44,5 +47,7 @@
return;
}
+ HalpInitializePciStubs();
+ HalpInitBusHandler();
RunLoader();
}
Modified: trunk/reactos/boot/freeldr/freeldr/freeldr_base.rbuild
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/freel…
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/freeldr_base.rbuild [iso-8859-1] (original)
+++ trunk/reactos/boot/freeldr/freeldr/freeldr_base.rbuild [iso-8859-1] Mon Mar 8
23:04:38 2010
@@ -22,6 +22,7 @@
<file>disk.c</file>
<file>partition.c</file>
<file>ramdisk.c</file>
+ <file>scsiport.c</file>
</directory>
<directory name="fs">
<file>ext2.c</file>
Modified: trunk/reactos/boot/freeldr/freeldr/include/disk.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/inclu…
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/include/disk.h [iso-8859-1] (original)
+++ trunk/reactos/boot/freeldr/freeldr/include/disk.h [iso-8859-1] Mon Mar 8 23:04:38
2010
@@ -140,3 +140,5 @@
BOOLEAN DiskGetFirstPartitionEntry(PMASTER_BOOT_RECORD MasterBootRecord,
PPARTITION_TABLE_ENTRY PartitionTableEntry);
BOOLEAN DiskGetFirstExtendedPartitionEntry(PMASTER_BOOT_RECORD MasterBootRecord,
PPARTITION_TABLE_ENTRY PartitionTableEntry);
BOOLEAN DiskReadBootRecord(ULONG DriveNumber, ULONGLONG LogicalSectorNumber,
PMASTER_BOOT_RECORD BootRecord);
+
+ULONG LoadBootDeviceDriver(VOID);
Modified: trunk/reactos/boot/freeldr/freeldr/include/reactos.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/inclu…
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/include/reactos.h [iso-8859-1] (original)
+++ trunk/reactos/boot/freeldr/freeldr/include/reactos.h [iso-8859-1] Mon Mar 8 23:04:38
2010
@@ -73,6 +73,14 @@
// ARC Path Functions
//
///////////////////////////////////////////////////////////////////////////////////////
+BOOLEAN
+DissectArcPath2(
+ IN CHAR* ArcPath,
+ OUT ULONG* x,
+ OUT ULONG* y,
+ OUT ULONG* z,
+ OUT ULONG* Partition,
+ OUT ULONG *PathSyntax);
BOOLEAN DissectArcPath(CHAR *ArcPath, CHAR *BootPath, ULONG* BootDrive, ULONG*
BootPartition);
VOID ConstructArcPath(PCHAR ArcPath, PCHAR SystemFolder, ULONG Disk, ULONG Partition);
ULONG ConvertArcNameToBiosDriveNumber(PCHAR ArcPath);
Modified: trunk/reactos/boot/freeldr/freeldr/reactos/arcname.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/react…
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/reactos/arcname.c [iso-8859-1] (original)
+++ trunk/reactos/boot/freeldr/freeldr/reactos/arcname.c [iso-8859-1] Mon Mar 8 23:04:38
2010
@@ -104,6 +104,62 @@
return TRUE;
}
+/* PathSyntax: scsi() = 0, multi() = 1, ramdisk() = 2 */
+BOOLEAN
+DissectArcPath2(
+ IN CHAR* ArcPath,
+ OUT ULONG* x,
+ OUT ULONG* y,
+ OUT ULONG* z,
+ OUT ULONG* Partition,
+ OUT ULONG *PathSyntax)
+{
+ /* Detect ramdisk() */
+ if (_strnicmp(ArcPath, "ramdisk(0)", 10) == 0)
+ {
+ *x = *y = *z = 0;
+ *Partition = 1;
+ *PathSyntax = 2;
+ return TRUE;
+ }
+ /* Detect scsi()disk()rdisk()partition() */
+ else if (sscanf(ArcPath, "scsi(%lu)disk(%lu)rdisk(%lu)partition(%lu)", x,
y, z, Partition) == 4)
+ {
+ *PathSyntax = 0;
+ return TRUE;
+ }
+ /* Detect scsi()cdrom()fdisk() */
+ else if (sscanf(ArcPath, "scsi(%lu)cdrom(%lu)fdisk(%lu)", x, y, z) == 3)
+ {
+ *Partition = 0;
+ *PathSyntax = 0;
+ return TRUE;
+ }
+ /* Detect multi()disk()rdisk()partition() */
+ else if (sscanf(ArcPath, "multi(%lu)disk(%lu)rdisk(%lu)partition(%lu)", x,
y, z, Partition) == 4)
+ {
+ *PathSyntax = 1;
+ return TRUE;
+ }
+ /* Detect multi()disk()cdrom() */
+ else if (sscanf(ArcPath, "multi(%lu)disk(%lu)cdrom(%lu)", x, y, z) == 3)
+ {
+ *Partition = 1;
+ *PathSyntax = 1;
+ return TRUE;
+ }
+ /* Detect multi()disk()fdisk() */
+ else if (sscanf(ArcPath, "multi(%lu)disk(%lu)fdisk(%lu)", x, y, z) == 3)
+ {
+ *Partition = 1;
+ *PathSyntax = 1;
+ return TRUE;
+ }
+
+ /* Unknown syntax */
+ return FALSE;
+}
+
VOID ConstructArcPath(PCHAR ArcPath, PCHAR SystemFolder, ULONG Disk, ULONG Partition)
{
char tmp[50];
Modified: trunk/reactos/boot/freeldr/freeldr/windows/peloader.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/windo…
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/windows/peloader.c [iso-8859-1] (original)
+++ trunk/reactos/boot/freeldr/freeldr/windows/peloader.c [iso-8859-1] Mon Mar 8 23:04:38
2010
@@ -277,7 +277,7 @@
Status = ArcOpen(FileName, OpenReadOnly, &FileId);
if (Status != ESUCCESS)
{
- UiMessageBox("Can not open the file");
+ //UiMessageBox("Can not open the file");
return FALSE;
}