</xi:fallback>
</xi:include>
- <xi:include href="ReactOS-generic.rbuild" />
+ <xi:include href="ReactOS-generic.rbuild" />
- <!-- <define name="_M_ARM" /> Already defined by toolchain -->
+ <!-- <define name="_M_ARM" /> Already defined by toolchain -->
<define name="_ARM_" />
<define name="__arm__" />
<define name="TARGET_arm" host="true" />
- <define name="USE_COMPILER_EXCEPTIONS" />
+ <define name="USE_COMPILER_EXCEPTIONS" />
- <property name="WINEBUILD_FLAGS" value="--kill-at"/>
+ <property name="WINEBUILD_FLAGS" value="--kill-at"/>
- <include>include/reactos/arm</include>
+ <include>include/reactos/arm</include>
<if property="SARCH" value="versatile">
<define name="BOARD_CONFIG_VERSATILE"/>
<compilerflag>-ftracer</compilerflag>
</if>
<compilerflag>-fms-extensions</compilerflag>
- <compilerflag>-Wno-attributes</compilerflag>
- <compilerflag>-U_UNICODE</compilerflag>
- <compilerflag>-UUNICODE</compilerflag>
+ <compilerflag>-Wno-attributes</compilerflag>
+ <compilerflag>-U_UNICODE</compilerflag>
+ <compilerflag>-UUNICODE</compilerflag>
</group>
<define name="__MSVCRT__"/> <!-- DUBIOUS -->
<group linkerset="ld">
- <linkerflag>--strip-debug</linkerflag> <!-- INVESTIGATE -->
- <linkerflag>-static</linkerflag> <!-- INVESTIGATE -->
+ <linkerflag>--strip-debug</linkerflag> <!-- INVESTIGATE -->
+ <linkerflag>-static</linkerflag> <!-- INVESTIGATE -->
<linkerflag>-file-alignment=0x1000</linkerflag>
<linkerflag>-section-alignment=0x1000</linkerflag>
</group>
<directory name="drivers">
<directory name="csq">
<xi:include href="lib/drivers/csq/csq.rbuild" />
- </directory>
+ </directory>
+ </directory>
+ <directory name="cportlib">
+ <xi:include href="lib/cportlib/cportlib.rbuild" />
</directory>
<directory name="debugsup">
<xi:include href="lib/debugsup/debugsup.rbuild" />
</directory>
<directory name="base">
<directory name="system">
- <directory name="smss">
- <xi:include href="base/system/smss/smss.rbuild" />
- </directory>
+ <directory name="smss">
+ <xi:include href="base/system/smss/smss.rbuild" />
+ </directory>
</directory>
</directory>
</project>
#define SECTORSIZE 512
+#include <pshpack1.h>
+typedef struct _FAT_BOOTSECTOR
+{
+ UCHAR JumpBoot[3]; // Jump instruction to boot code
+ CHAR OemName[8]; // "MSWIN4.1" for MS formatted volumes
+ USHORT BytesPerSector; // Bytes per sector
+ UCHAR SectorsPerCluster; // Number of sectors in a cluster
+ USHORT ReservedSectors; // Reserved sectors, usually 1 (the bootsector)
+ UCHAR NumberOfFats; // Number of FAT tables
+ USHORT RootDirEntries; // Number of root directory entries (fat12/16)
+ USHORT TotalSectors; // Number of total sectors on the drive, 16-bit
+ UCHAR MediaDescriptor; // Media descriptor byte
+ USHORT SectorsPerFat; // Sectors per FAT table (fat12/16)
+ USHORT SectorsPerTrack; // Number of sectors in a track
+ USHORT NumberOfHeads; // Number of heads on the disk
+ ULONG HiddenSectors; // Hidden sectors (sectors before the partition start like the partition table)
+ ULONG TotalSectorsBig; // This field is the new 32-bit total count of sectors on the volume
+ UCHAR DriveNumber; // Int 0x13 drive number (e.g. 0x80)
+ UCHAR Reserved1; // Reserved (used by Windows NT). Code that formats FAT volumes should always set this byte to 0.
+ UCHAR BootSignature; // Extended boot signature (0x29). This is a signature byte that indicates that the following three fields in the boot sector are present.
+ ULONG VolumeSerialNumber; // Volume serial number
+ CHAR VolumeLabel[11]; // Volume label. This field matches the 11-byte volume label recorded in the root directory
+ CHAR FileSystemType[8]; // One of the strings "FAT12 ", "FAT16 ", or "FAT "
+
+ UCHAR BootCodeAndData[448]; // The remainder of the boot sector
+
+ USHORT BootSectorMagic; // 0xAA55
+
+} FAT_BOOTSECTOR, *PFAT_BOOTSECTOR;
+
+typedef struct _FAT32_BOOTSECTOR
+{
+ UCHAR JumpBoot[3]; // Jump instruction to boot code
+ CHAR OemName[8]; // "MSWIN4.1" for MS formatted volumes
+ USHORT BytesPerSector; // Bytes per sector
+ UCHAR SectorsPerCluster; // Number of sectors in a cluster
+ USHORT ReservedSectors; // Reserved sectors, usually 1 (the bootsector)
+ UCHAR NumberOfFats; // Number of FAT tables
+ USHORT RootDirEntries; // Number of root directory entries (fat12/16)
+ USHORT TotalSectors; // Number of total sectors on the drive, 16-bit
+ UCHAR MediaDescriptor; // Media descriptor byte
+ USHORT SectorsPerFat; // Sectors per FAT table (fat12/16)
+ USHORT SectorsPerTrack; // Number of sectors in a track
+ USHORT NumberOfHeads; // Number of heads on the disk
+ ULONG HiddenSectors; // Hidden sectors (sectors before the partition start like the partition table)
+ ULONG TotalSectorsBig; // This field is the new 32-bit total count of sectors on the volume
+ ULONG SectorsPerFatBig; // This field is the FAT32 32-bit count of sectors occupied by ONE FAT. BPB_FATSz16 must be 0
+ USHORT ExtendedFlags; // Extended flags (fat32)
+ USHORT FileSystemVersion; // File system version (fat32)
+ ULONG RootDirStartCluster; // Starting cluster of the root directory (fat32)
+ USHORT FsInfo; // Sector number of FSINFO structure in the reserved area of the FAT32 volume. Usually 1.
+ USHORT BackupBootSector; // If non-zero, indicates the sector number in the reserved area of the volume of a copy of the boot record. Usually 6.
+ UCHAR Reserved[12]; // Reserved for future expansion
+ UCHAR DriveNumber; // Int 0x13 drive number (e.g. 0x80)
+ UCHAR Reserved1; // Reserved (used by Windows NT). Code that formats FAT volumes should always set this byte to 0.
+ UCHAR BootSignature; // Extended boot signature (0x29). This is a signature byte that indicates that the following three fields in the boot sector are present.
+ ULONG VolumeSerialNumber; // Volume serial number
+ CHAR VolumeLabel[11]; // Volume label. This field matches the 11-byte volume label recorded in the root directory
+ CHAR FileSystemType[8]; // Always set to the string "FAT32 "
+
+ UCHAR BootCodeAndData[420]; // The remainder of the boot sector
+
+ USHORT BootSectorMagic; // 0xAA55
+
+} FAT32_BOOTSECTOR, *PFAT32_BOOTSECTOR;
+#include <poppack.h>
+
+extern PPARTLIST PartitionList;
+
/* FUNCTIONS ****************************************************************/
InstallMbrBootCodeToDisk (PWSTR SrcPath,
PWSTR RootPath)
{
- OBJECT_ATTRIBUTES ObjectAttributes;
- IO_STATUS_BLOCK IoStatusBlock;
- UNICODE_STRING Name;
- HANDLE FileHandle;
- NTSTATUS Status;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ IO_STATUS_BLOCK IoStatusBlock;
+ UNICODE_STRING Name;
+ HANDLE FileHandle;
+ NTSTATUS Status;
PPARTITION_SECTOR OrigBootSector;
PPARTITION_SECTOR NewBootSector;
- /* Allocate buffer for original bootsector */
+ /* Allocate buffer for original bootsector */
OrigBootSector = (PPARTITION_SECTOR)RtlAllocateHeap(ProcessHeap,
0,
sizeof(PARTITION_SECTOR));
if (OrigBootSector == NULL)
return(STATUS_INSUFFICIENT_RESOURCES);
- /* Read current boot sector into buffer */
+ /* Read current boot sector into buffer */
RtlInitUnicodeString(&Name,
RootPath);
- InitializeObjectAttributes(&ObjectAttributes,
- &Name,
- OBJ_CASE_INSENSITIVE,
- NULL,
- NULL);
-
- Status = NtOpenFile(&FileHandle,
- GENERIC_READ,
- &ObjectAttributes,
- &IoStatusBlock,
- 0,
- FILE_SYNCHRONOUS_IO_NONALERT);
+ InitializeObjectAttributes(&ObjectAttributes,
+ &Name,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
+
+ Status = NtOpenFile(&FileHandle,
+ GENERIC_READ,
+ &ObjectAttributes,
+ &IoStatusBlock,
+ 0,
+ FILE_SYNCHRONOUS_IO_NONALERT);
if (!NT_SUCCESS(Status))
{
RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
return(Status);
}
- Status = NtReadFile(FileHandle,
- NULL,
- NULL,
- NULL,
- &IoStatusBlock,
+ Status = NtReadFile(FileHandle,
+ NULL,
+ NULL,
+ NULL,
+ &IoStatusBlock,
OrigBootSector,
- SECTORSIZE,
- NULL,
- NULL);
- NtClose(FileHandle);
+ SECTORSIZE,
+ NULL,
+ NULL);
+ NtClose(FileHandle);
if (!NT_SUCCESS(Status))
{
RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
UNICODE_STRING Name;
HANDLE FileHandle;
NTSTATUS Status;
- PUCHAR OrigBootSector;
- PUCHAR NewBootSector;
+ PFAT_BOOTSECTOR OrigBootSector;
+ PFAT_BOOTSECTOR NewBootSector;
+ PARTITION_INFORMATION *PartInfo;
/* Allocate buffer for original bootsector */
- OrigBootSector = (PUCHAR)RtlAllocateHeap(ProcessHeap,
+ OrigBootSector = RtlAllocateHeap(ProcessHeap,
0,
SECTORSIZE);
if (OrigBootSector == NULL)
/* Allocate buffer for new bootsector */
- NewBootSector = (PUCHAR)RtlAllocateHeap(ProcessHeap,
+ NewBootSector = RtlAllocateHeap(ProcessHeap,
0,
SECTORSIZE);
if (NewBootSector == NULL)
}
/* Adjust bootsector (copy a part of the FAT16 BPB) */
- memcpy((NewBootSector + 3),
- (OrigBootSector + 3),
- 59); /* FAT16 BPB length*/
+ memcpy(&NewBootSector->BytesPerSector,
+ &OrigBootSector->BytesPerSector,
+ 51); /* FAT16 BPB length */
+
+ PartInfo = &PartitionList->CurrentPartition->PartInfo[PartitionList->CurrentPartitionNumber];
+ NewBootSector->HiddenSectors = PartInfo->HiddenSectors;
/* Free the original boot sector */
RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
UNICODE_STRING Name;
HANDLE FileHandle;
NTSTATUS Status;
- PUCHAR OrigBootSector;
- PUCHAR NewBootSector;
+ PFAT32_BOOTSECTOR OrigBootSector;
+ PFAT32_BOOTSECTOR NewBootSector;
LARGE_INTEGER FileOffset;
USHORT BackupBootSector;
+ PARTITION_INFORMATION *PartInfo;
/* Allocate buffer for original bootsector */
- OrigBootSector = (PUCHAR)RtlAllocateHeap(ProcessHeap,
+ OrigBootSector = RtlAllocateHeap(ProcessHeap,
0,
SECTORSIZE);
if (OrigBootSector == NULL)
/* Allocate buffer for new bootsector (2 sectors) */
- NewBootSector = (PUCHAR)RtlAllocateHeap(ProcessHeap,
+ NewBootSector = RtlAllocateHeap(ProcessHeap,
0,
2 * SECTORSIZE);
if (NewBootSector == NULL)
}
/* Adjust bootsector (copy a part of the FAT32 BPB) */
- memcpy((NewBootSector + 3),
- (OrigBootSector + 3),
- 87); /* FAT32 BPB length */
+ memcpy(&NewBootSector->BytesPerSector,
+ &OrigBootSector->BytesPerSector,
+ 79); /* FAT32 BPB length */
+
+ PartInfo = &PartitionList->CurrentPartition->PartInfo[PartitionList->CurrentPartitionNumber];
+ NewBootSector->HiddenSectors = PartInfo->HiddenSectors;
/* Get the location of the backup boot sector */
- BackupBootSector = (OrigBootSector[0x33] << 8) + OrigBootSector[0x32];
+ BackupBootSector = OrigBootSector->BackupBootSector;
/* Free the original boot sector */
RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
NULL,
NULL,
&IoStatusBlock,
- (NewBootSector + SECTORSIZE),
+ ((PUCHAR)NewBootSector + SECTORSIZE),
SECTORSIZE,
&FileOffset,
NULL);
#endif
}
+NTSTATUS
+InstallVBRToPartition(PUNICODE_STRING SystemRootPath,
+ PUNICODE_STRING SourceRootPath,
+ PUNICODE_STRING DestinationArcPath,
+ UCHAR PartitionType)
+{
+ if ((PartitionType == PARTITION_FAT_12) ||
+ (PartitionType == PARTITION_FAT_16) ||
+ (PartitionType == PARTITION_HUGE) ||
+ (PartitionType == PARTITION_XINT13) ||
+ (PartitionType == PARTITION_FAT32) ||
+ (PartitionType == PARTITION_FAT32_XINT13))
+ {
+ return InstallFatBootcodeToPartition(SystemRootPath,
+ SourceRootPath,
+ DestinationArcPath,
+ PartitionType);
+ }
+
+ return STATUS_UNSUCCESSFUL;
+}
+
NTSTATUS
InstallFatBootcodeToFloppy(PUNICODE_STRING SourceRootPath,
PUNICODE_STRING DestinationArcPath,
UCHAR PartitionType);
+NTSTATUS
+InstallVBRToPartition(PUNICODE_STRING SystemRootPath,
+ PUNICODE_STRING SourceRootPath,
+ PUNICODE_STRING DestinationArcPath,
+ UCHAR PartitionType);
+
NTSTATUS
InstallFatBootcodeToFloppy(PUNICODE_STRING SourceRootPath,
PUNICODE_STRING DestinationArcPath);
WCHAR DefaultKBLayout[20];
BOOLEAN RepairUpdateFlag = FALSE;
HANDLE hPnpThread = INVALID_HANDLE_VALUE;
+PPARTLIST PartitionList = NULL;
/* LOCALS *******************************************************************/
-static PPARTLIST PartitionList = NULL;
-
static PFILE_SYSTEM_LIST FileSystemList = NULL;
static UNICODE_STRING InstallPath;
static BOOL
IsDiskSizeValid(PPARTENTRY PartEntry)
{
- ULONGLONG m;
+ ULONGLONG m1, m2;
/* check for unpartitioned space */
- m = PartEntry->UnpartitionedLength;
- m = (m + (1 << 19)) >> 20; /* in MBytes (rounded) */
- if( m > RequiredPartitionDiskSpace)
+ m1 = PartEntry->UnpartitionedLength;
+ m1 = (m1 + (1 << 19)) >> 20; /* in MBytes (rounded) */
+
+ if( m1 > RequiredPartitionDiskSpace)
{
return TRUE;
}
/* check for partitioned space */
- m = PartEntry->PartInfo[0].PartitionLength.QuadPart;
- m = (m + (1 << 19)) >> 20; /* in MBytes (rounded) */
- if (m < RequiredPartitionDiskSpace)
+ m2 = PartEntry->PartInfo[0].PartitionLength.QuadPart;
+ m2 = (m2 + (1 << 19)) >> 20; /* in MBytes (rounded) */
+ if (m2 < RequiredPartitionDiskSpace)
{
/* partition is too small so ask for another partion */
- DPRINT1("Partition is too small, required disk space is %lu MB\n", RequiredPartitionDiskSpace);
+ DPRINT1("Partition is too small(unpartitioned: %I64u MB, partitioned: %I64u MB), required disk space is %lu MB\n", m1, m2, RequiredPartitionDiskSpace);
return FALSE;
}
else
CheckActiveBootPartition(PartitionList);
}
- /* Install MBR if necessary */
- if (DiskEntry->NoMbr &&
- DiskEntry->BiosDiskNumber == 0)
- {
- wcscpy(PathBuffer, SourceRootPath.Buffer);
- wcscat(PathBuffer, L"\\loader\\dosmbr.bin");
-
- DPRINT("Install MBR bootcode: %S ==> %S\n",
- PathBuffer, DestinationRootPath.Buffer);
-
- /* Install MBR bootcode */
- Status = InstallMbrBootCodeToDisk(PathBuffer,
- DestinationRootPath.Buffer);
- if (!NT_SUCCESS (Status))
- {
- DPRINT1("InstallMbrBootCodeToDisk() failed (Status %lx)\n",
- Status);
- return FALSE;
- }
-
- DiskEntry->NoMbr = FALSE;
- }
-
if (wcscmp(FileSystemList->Selected->FileSystem, L"FAT") == 0)
{
/* FIXME: Install boot code. This is a hack! */
/* Unattended install on hdd? */
if (IsUnattendedSetup && UnattendMBRInstallType == 2)
{
- return BOOT_LOADER_HARDDISK_PAGE;
+ return BOOT_LOADER_HARDDISK_MBR_PAGE;
}
MUIDisplayPage(BOOT_LOADER_PAGE);
Line++;
if (Line<12)
- Line=14;
+ Line=15;
- if (Line>14)
+ if (Line>15)
Line=12;
CONSOLE_InvertTextXY(8, Line, 60, 1);
Line--;
if (Line<12)
- Line=14;
+ Line=15;
- if (Line>14)
+ if (Line>15)
Line=12;
CONSOLE_InvertTextXY(8, Line, 60, 1);
{
if (Line == 12)
{
- return BOOT_LOADER_HARDDISK_PAGE;
+ return BOOT_LOADER_HARDDISK_MBR_PAGE;
}
else if (Line == 13)
{
- return BOOT_LOADER_FLOPPY_PAGE;
+ return BOOT_LOADER_HARDDISK_VBR_PAGE;
}
else if (Line == 14)
+ {
+ return BOOT_LOADER_FLOPPY_PAGE;
+ }
+ else if (Line == 15)
{
return SUCCESS_PAGE;
}
return BOOT_LOADER_FLOPPY_PAGE;
}
+static PAGE_NUMBER
+BootLoaderHarddiskVbrPage(PINPUT_RECORD Ir)
+{
+ UCHAR PartitionType;
+ NTSTATUS Status;
+
+ PartitionType = PartitionList->ActiveBootPartition->
+ PartInfo[PartitionList->ActiveBootPartitionNumber].PartitionType;
+
+ Status = InstallVBRToPartition(&SystemRootPath,
+ &SourceRootPath,
+ &DestinationArcPath,
+ PartitionType);
+ if (!NT_SUCCESS(Status))
+ {
+ MUIDisplayError(ERROR_WRITE_BOOT, Ir, POPUP_WAIT_ENTER);
+ return QUIT_PAGE;
+ }
+
+ return SUCCESS_PAGE;
+}
static PAGE_NUMBER
-BootLoaderHarddiskPage(PINPUT_RECORD Ir)
+BootLoaderHarddiskMbrPage(PINPUT_RECORD Ir)
{
UCHAR PartitionType;
NTSTATUS Status;
+ WCHAR DestinationDevicePathBuffer[MAX_PATH];
+ WCHAR SourceMbrPathBuffer[MAX_PATH];
+ /* Step 1: Write the VBR */
PartitionType = PartitionList->ActiveBootPartition->
PartInfo[PartitionList->ActiveBootPartitionNumber].PartitionType;
- if ((PartitionType == PARTITION_FAT_12) ||
- (PartitionType == PARTITION_FAT_16) ||
- (PartitionType == PARTITION_HUGE) ||
- (PartitionType == PARTITION_XINT13) ||
- (PartitionType == PARTITION_FAT32) ||
- (PartitionType == PARTITION_FAT32_XINT13))
- {
- Status = InstallFatBootcodeToPartition(&SystemRootPath,
- &SourceRootPath,
- &DestinationArcPath,
- PartitionType);
- if (!NT_SUCCESS(Status))
- {
- MUIDisplayError(ERROR_INSTALL_BOOTCODE, Ir, POPUP_WAIT_ENTER);
- return QUIT_PAGE;
- }
- return SUCCESS_PAGE;
- }
- else
+ Status = InstallVBRToPartition(&SystemRootPath,
+ &SourceRootPath,
+ &DestinationArcPath,
+ PartitionType);
+ if (!NT_SUCCESS(Status))
{
MUIDisplayError(ERROR_WRITE_BOOT, Ir, POPUP_WAIT_ENTER);
return QUIT_PAGE;
}
- return BOOT_LOADER_HARDDISK_PAGE;
+ /* Step 2: Write the MBR */
+ swprintf(DestinationDevicePathBuffer,
+ L"\\Device\\Harddisk%d\\Partition0",
+ PartitionList->ActiveBootDisk->DiskNumber);
+
+ wcscpy(SourceMbrPathBuffer, SourceRootPath.Buffer);
+ wcscat(SourceMbrPathBuffer, L"\\loader\\dosmbr.bin");
+
+ DPRINT("Install MBR bootcode: %S ==> %S\n",
+ SourceMbrPathBuffer, DestinationDevicePathBuffer);
+
+ Status = InstallMbrBootCodeToDisk(SourceMbrPathBuffer,
+ DestinationDevicePathBuffer);
+ if (!NT_SUCCESS (Status))
+ {
+ DPRINT1("InstallMbrBootCodeToDisk() failed (Status %lx)\n",
+ Status);
+ MUIDisplayError(ERROR_INSTALL_BOOTCODE, Ir, POPUP_WAIT_ENTER);
+ return QUIT_PAGE;
+ }
+
+ return SUCCESS_PAGE;
}
Page = BootLoaderFloppyPage(&Ir);
break;
- case BOOT_LOADER_HARDDISK_PAGE:
- Page = BootLoaderHarddiskPage(&Ir);
+ case BOOT_LOADER_HARDDISK_MBR_PAGE:
+ Page = BootLoaderHarddiskMbrPage(&Ir);
+ break;
+
+ case BOOT_LOADER_HARDDISK_VBR_PAGE:
+ Page = BootLoaderHarddiskVbrPage(&Ir);
break;
/* Repair pages */
{
8,
12,
- "\91« £ ¥ § ०¤ ç â¢êà¤¨ï ¤¨áª (¢ MBR).",
+ "Install bootloader on the harddisk (MBR and VBR).",
TEXT_STYLE_NORMAL
},
{
8,
13,
- "\91« £ ¥ § ०¤ ç ¤¨áª¥â .",
+ "Install bootloader on the harddisk (VBR only).",
TEXT_STYLE_NORMAL
},
{
8,
14,
+ "\91« £ ¥ § ०¤ ç ¤¨áª¥â .",
+ TEXT_STYLE_NORMAL
+ },
+ {
+ 8,
+ 15,
"\84 ¥ ᥠ᫠£ § ०¤ ç.",
TEXT_STYLE_NORMAL
},
{
8,
12,
- "Nainstalovat zavad؟ na disk (MBR).",
+ "Install bootloader on the harddisk (MBR and VBR).",
TEXT_STYLE_NORMAL
},
{
8,
13,
- "Nainstalovat zavad؟ na disketu.",
+ "Install bootloader on the harddisk (VBR only).",
TEXT_STYLE_NORMAL
},
{
8,
14,
+ "Nainstalovat zavad؟ na disketu.",
+ TEXT_STYLE_NORMAL
+ },
+ {
+ 8,
+ 15,
"Pýesko\9fit instalaci zavadØ\9fe.",
TEXT_STYLE_NORMAL
},
{
10,
9,
- "Der PC wird automatisch neunstarten, wenn der Vorgang beendet ist.",
+ "Der PC wird automatisch neustarten, wenn der Vorgang beendet ist.",
TEXT_STYLE_NORMAL
},
{
{
8,
12,
- "Boot-Loader auf der Festplatte installieren (Bootsektor).",
+ "Boot-Loader auf der Festplatte installieren (MBR und VBR).",
TEXT_STYLE_NORMAL
},
{
8,
13,
- "Boot-Loader auf einer Diskette installieren.",
+ "Boot-Loader auf der Festplatte installieren (nur VBR).",
TEXT_STYLE_NORMAL
},
{
8,
14,
+ "Boot-Loader auf einer Diskette installieren.",
+ TEXT_STYLE_NORMAL
+ },
+ {
+ 8,
+ 15,
"Boot-Loader nicht installieren.",
TEXT_STYLE_NORMAL
},
{
8,
12,
- "\84\9a¡\98«á©«\98©\9e «¦¬ bootloader ©«¦ ©¡¢\9e¨æ \9bå©¡¦ (MBR).",
+ "Install bootloader on the harddisk (MBR and VBR).",
TEXT_STYLE_NORMAL
},
{
8,
13,
- "\84\9a¡\98«á©«\98©\9e «¦¬ bootloader ©\9c £ \98 \9b ©¡â«\98.",
+ "Install bootloader on the harddisk (VBR only).",
TEXT_STYLE_NORMAL
},
{
8,
14,
+ "\84\9a¡\98«á©«\98©\9e «¦¬ bootloader ©\9c £ \98 \9b ©¡â«\98.",
+ TEXT_STYLE_NORMAL
+ },
+ {
+ 8,
+ 15,
"\8c\98 £\9e \9aå¤\9c \9c\9a¡\98«á©«\98©\9e «¦¬ bootloader.",
TEXT_STYLE_NORMAL
},
{
8,
12,
- "Install bootloader on the harddisk (bootsector).",
+ "Install bootloader on the harddisk (MBR and VBR).",
TEXT_STYLE_NORMAL
},
{
8,
13,
- "Install bootloader on a floppy disk.",
+ "Install bootloader on the harddisk (VBR only).",
TEXT_STYLE_NORMAL
},
{
8,
14,
+ "Install bootloader on a floppy disk.",
+ TEXT_STYLE_NORMAL
+ },
+ {
+ 8,
+ 15,
"Skip install bootloader.",
TEXT_STYLE_NORMAL
},
{
8,
12,
- "Instalar cargador de arranque en el disco duro (sector de boot).",
+ "Install bootloader on the harddisk (MBR and VBR).",
TEXT_STYLE_NORMAL
},
{
8,
13,
- "Instalar cargador de inicio en un disquete.",
+ "Install bootloader on the harddisk (VBR only).",
TEXT_STYLE_NORMAL
},
{
8,
14,
+ "Instalar cargador de inicio en un disquete.",
+ TEXT_STYLE_NORMAL
+ },
+ {
+ 8,
+ 15,
"Omitir la instalaci¢n del cargador de arranque.",
TEXT_STYLE_NORMAL
},
{
8,
12,
- "Paigalda alglaadur kävakettale (MBR).",
+ "Install bootloader on the harddisk (MBR and VBR).",
TEXT_STYLE_NORMAL
},
{
8,
13,
- "Paigalda alglaadur flopikettale.",
+ "Install bootloader on the harddisk (VBR only).",
TEXT_STYLE_NORMAL
},
{
8,
14,
+ "Paigalda alglaadur flopikettale.",
+ TEXT_STYLE_NORMAL
+ },
+ {
+ 8,
+ 15,
"\8era paigalda alglaadurit.",
TEXT_STYLE_NORMAL
},
{
8,
12,
- "Installer le chargeur de d\82marrage sur le disque dur (MBR).",
+ "Installer le chargeur de d\82marrage sur le disque (MBR et VBR).",
TEXT_STYLE_NORMAL
},
{
8,
13,
- "Installer le chargeur de d\82marrage sur une disquette.",
+ "Installer le chargeur de d\82marrage sur le disque (VBR seulement).",
TEXT_STYLE_NORMAL
},
{
8,
14,
+ "Installer le chargeur de d\82marrage sur une disquette.",
+ TEXT_STYLE_NORMAL
+ },
+ {
+ 8,
+ 15,
"Ne pas installer le chargeur de d\82marrage.",
TEXT_STYLE_NORMAL
},
{
6,
8,
- "Please select a layout to be installed by default.",
+ "Veuillez s\82lectionner une disposition \85 installer par d\82faut.",
TEXT_STYLE_NORMAL
},
{
},
{
//ERROR_ADDING_KBLAYOUTS,
- "Setup failed to add keyboard layouts to registry.\n"
- "ENTER = Reboot computer"
+ "Setup n'a pas pu ajouter les dispositions de clavier au registre.\n"
+ "ENTER = Red\82marrer l'ordinateur"
},
{
//ERROR_UPDATE_GEOID,
- "Setup could not set the geo id.\n"
- "ENTER = Reboot computer"
+ "Setup n'a pas pu d\82finir la geo id.\n"
+ "ENTER = Red\82marrer l'ordinateur"
},
{
//ERROR_INSUFFICIENT_DISKSPACE,
- "Not enough free space in the selected partition.\n"
- " * Press any key to continue.",
+ "Pas assez d'espace libre dans la partition s\82lectionn\82e.\n"
+ " * Appuyez sur n'importe quelle touche pour continuer.",
NULL
},
{
{STRING_GB,
"Go"},
{STRING_ADDKBLAYOUTS,
- "Adding keyboard layouts"},
+ "Ajout des dispositions clavier"},
{0, 0}
};
{
8,
12,
- "Installazione del bootloader sul disco fisso (settore di avvio).",
+ "Install bootloader on the harddisk (MBR and VBR).",
TEXT_STYLE_NORMAL
},
{
8,
13,
- "Installazione del bootloader su un disco floppy.",
+ "Install bootloader on the harddisk (VBR only).",
TEXT_STYLE_NORMAL
},
{
8,
14,
+ "Installazione del bootloader su un disco floppy.",
+ TEXT_STYLE_NORMAL
+ },
+ {
+ 8,
+ 15,
"Salta l'installazione del bootloader.",
TEXT_STYLE_NORMAL
},
{
8,
12,
- "ÌÞ°ÄÛ°ÀÞ¦ Ê°ÄÞÃÞ¨½¸ (Ìްľ¸À)Æ ²Ý½Ä°Ù ½Ù¡",
+ "Install bootloader on the harddisk (MBR and VBR).",
TEXT_STYLE_NORMAL
},
{
8,
13,
- "ÌÞ°ÄÛ°ÀÞ¦ ÌÛ¯Ëß° ÃÞ¨½¸Æ ²Ý½Ä°Ù ½Ù¡",
+ "Install bootloader on the harddisk (VBR only).",
TEXT_STYLE_NORMAL
},
{
8,
14,
+ "ÌÞ°ÄÛ°ÀÞ¦ ÌÛ¯Ëß° ÃÞ¨½¸Æ ²Ý½Ä°Ù ½Ù¡",
+ TEXT_STYLE_NORMAL
+ },
+ {
+ 8,
+ 15,
"ÌÞ°ÄÛ°ÀÞÉ ²Ý½Ä°Ù¦ ½·¯Ìß ½Ù¡",
TEXT_STYLE_NORMAL
},
{
8,
12,
- "Install bootloader on the harddisk (MBR).",
+ "Install bootloader on the harddisk (MBR and VBR).",
TEXT_STYLE_NORMAL
},
{
8,
13,
- "Install bootloader on a floppy disk.",
+ "Install bootloader on the harddisk (VBR only).",
TEXT_STYLE_NORMAL
},
{
8,
14,
+ "Install bootloader on a floppy disk.",
+ TEXT_STYLE_NORMAL
+ },
+ {
+ 8,
+ 15,
"Skip install bootloader.",
TEXT_STYLE_NORMAL
},
{
8,
12,
- "Installeer de bootloader op de harde schijf (bootsector).",
+ "Install bootloader on the harddisk (MBR and VBR).",
TEXT_STYLE_NORMAL
},
{
8,
13,
- "Installeer de bootloader op een floppy disk.",
+ "Install bootloader on the harddisk (VBR only).",
TEXT_STYLE_NORMAL
},
{
8,
14,
+ "Installeer de bootloader op een floppy disk.",
+ TEXT_STYLE_NORMAL
+ },
+ {
+ 8,
+ 15,
"Installeren bootloader overslaan.",
TEXT_STYLE_NORMAL
},
{
8,
12,
- " Wgraj bootloader na dysk twardy (MBR).",
+ "Wgraj bootloader na dysk twardy (MBR i VBR).",
TEXT_STYLE_NORMAL
},
{
8,
13,
- " Wgraj bootloader na dyskietk©.",
+ "Wgraj bootloader na dysk twardy (tylko VBR).",
TEXT_STYLE_NORMAL
},
{
8,
14,
+ " Wgraj bootloader na dyskietk©.",
+ TEXT_STYLE_NORMAL
+ },
+ {
+ 8,
+ 15,
" Pomiä wgrywanie bootloadera.",
TEXT_STYLE_NORMAL
},
{
8,
12,
- "\93áâ ®¢ª ¦¥á⪨© ¤¨áª (§ £à㧮çë© á¥ªâ®à).",
+ "Install bootloader on the harddisk (MBR and VBR).",
TEXT_STYLE_NORMAL
},
{
8,
13,
- "\93áâ ®¢ª £¨¡ª¨© ¤¨áª.",
+ "Install bootloader on the harddisk (VBR only).",
TEXT_STYLE_NORMAL
},
{
8,
14,
+ "\93áâ ®¢ª £¨¡ª¨© ¤¨áª.",
+ TEXT_STYLE_NORMAL
+ },
+ {
+ 8,
+ 15,
"\8d¥ ãáâ ¢«¨¢ âì § £àã§ç¨ª.",
TEXT_STYLE_NORMAL
},
{
8,
12,
- "Nainçtalova\9c zav dza\9f syst\82mu na pevnì disk (zav dzac¡ sektor).",
+ "Install bootloader on the harddisk (MBR and VBR).",
TEXT_STYLE_NORMAL
},
{
8,
13,
- "Nainçtalova\9c zav dza\9f syst\82mu na disketu.",
+ "Install bootloader on the harddisk (VBR only).",
TEXT_STYLE_NORMAL
},
{
8,
14,
+ "Nainçtalova\9c zav dza\9f syst\82mu na disketu.",
+ TEXT_STYLE_NORMAL
+ },
+ {
+ 8,
+ 15,
"Presko\9fi\9c inçtal ciu zav dza\9fa syst\82mu.",
TEXT_STYLE_NORMAL
},
{
8,
12,
- "Install bootloader on the harddisk (MBR).",
+ "Install bootloader on the harddisk (MBR and VBR).",
TEXT_STYLE_NORMAL
},
{
8,
13,
- "Install bootloader on a floppy disk.",
+ "Install bootloader on the harddisk (VBR only).",
TEXT_STYLE_NORMAL
},
{
8,
14,
+ "Install bootloader on a floppy disk.",
+ TEXT_STYLE_NORMAL
+ },
+ {
+ 8,
+ 15,
"Skip install bootloader.",
TEXT_STYLE_NORMAL
},
{
8,
12,
- "\82áâ ®¢¨â¨ bootloader ¦®àá⪨© ¤¨áª (bootsector).",
+ "Install bootloader on the harddisk (MBR and VBR).",
TEXT_STYLE_NORMAL
},
{
8,
13,
- "\82áâ ®¢¨â¨ bootloader ¤¨áª¥âã.",
+ "Install bootloader on the harddisk (VBR only).",
TEXT_STYLE_NORMAL
},
{
8,
14,
+ "\82áâ ®¢¨â¨ bootloader ¤¨áª¥âã.",
+ TEXT_STYLE_NORMAL
+ },
+ {
+ 8,
+ 15,
"\8d¥ ¢áâ ®¢«î¢ ⨠bootloader.",
TEXT_STYLE_NORMAL
},
ULONG i;
PLIST_ENTRY ListEntry;
PBIOSDISKENTRY BiosDiskEntry;
+ ULONG LayoutBufferSize;
Status = NtDeviceIoControlFile (FileHandle,
NULL,
InsertAscendingList(&List->DiskListHead, DiskEntry, DISKENTRY, ListEntry, BiosDiskNumber);
+ /*
+ * Allocate a buffer for 26 logical drives (2 entries each == 52)
+ * plus the main partiton table (4 entries). Total 56 entries.
+ */
+ LayoutBufferSize = sizeof(DRIVE_LAYOUT_INFORMATION) +
+ ((56 - ANYSIZE_ARRAY) * sizeof(PARTITION_INFORMATION));
LayoutBuffer = (DRIVE_LAYOUT_INFORMATION*)RtlAllocateHeap (ProcessHeap,
0,
- 8192);
+ LayoutBufferSize);
if (LayoutBuffer == NULL)
{
return;
NULL,
0,
LayoutBuffer,
- 8192);
+ LayoutBufferSize);
if (NT_SUCCESS (Status))
{
if (LayoutBuffer->PartitionCount == 0)
PartEntry->FormatState = Unformatted;
PartEntry->PartInfo[0].StartingOffset.QuadPart =
PartEntry->UnpartitionedOffset + DiskEntry->TrackSize;
+ PartEntry->PartInfo[0].HiddenSectors =
+ PartEntry->PartInfo[0].StartingOffset.QuadPart / DiskEntry->BytesPerSector;
PartEntry->PartInfo[0].PartitionLength.QuadPart =
PartEntry->UnpartitionedLength - DiskEntry->TrackSize;
PartEntry->PartInfo[0].PartitionType = PARTITION_ENTRY_UNUSED;
PrevPartEntry->PartInfo[1].StartingOffset.QuadPart =
PartEntry->PartInfo[0].StartingOffset.QuadPart - DiskEntry->TrackSize;
+ PrevPartEntry->PartInfo[1].HiddenSectors =
+ PrevPartEntry->PartInfo[1].StartingOffset.QuadPart / DiskEntry->BytesPerSector;
if (DiskEntry->PartListHead.Flink == &PrevPartEntry->ListEntry)
{
PrevPartEntry->PartInfo[1].StartingOffset.QuadPart =
PartEntry->PartInfo[0].StartingOffset.QuadPart - DiskEntry->TrackSize;
+ PrevPartEntry->PartInfo[1].HiddenSectors =
+ PrevPartEntry->PartInfo[1].StartingOffset.QuadPart / DiskEntry->BytesPerSector;
if (DiskEntry->PartListHead.Flink == &PrevPartEntry->ListEntry)
{
NewPartEntry->FormatState = Unformatted;
NewPartEntry->PartInfo[0].StartingOffset.QuadPart =
PartEntry->UnpartitionedOffset + DiskEntry->TrackSize;
+ NewPartEntry->PartInfo[0].HiddenSectors =
+ NewPartEntry->PartInfo[0].StartingOffset.QuadPart / DiskEntry->BytesPerSector;
NewPartEntry->PartInfo[0].PartitionLength.QuadPart =
PartitionSize - DiskEntry->TrackSize;
NewPartEntry->PartInfo[0].PartitionType = PARTITION_ENTRY_UNUSED;
PrevPartEntry->PartInfo[1].StartingOffset.QuadPart =
NewPartEntry->PartInfo[0].StartingOffset.QuadPart - DiskEntry->TrackSize;
+ PrevPartEntry->PartInfo[1].HiddenSectors =
+ PrevPartEntry->PartInfo[1].StartingOffset.QuadPart / DiskEntry->BytesPerSector;
if (DiskEntry->PartListHead.Flink == &PrevPartEntry->ListEntry)
{
PrevPartEntry->PartInfo[1].StartingOffset.QuadPart =
NewPartEntry->PartInfo[0].StartingOffset.QuadPart - DiskEntry->TrackSize;
+ PrevPartEntry->PartInfo[1].HiddenSectors =
+ PrevPartEntry->PartInfo[1].StartingOffset.QuadPart / DiskEntry->BytesPerSector;
if (DiskEntry->PartListHead.Flink == &PrevPartEntry->ListEntry)
{
REGISTRY_PAGE,
BOOT_LOADER_PAGE,
BOOT_LOADER_FLOPPY_PAGE,
- BOOT_LOADER_HARDDISK_PAGE,
+ BOOT_LOADER_HARDDISK_MBR_PAGE,
+ BOOT_LOADER_HARDDISK_VBR_PAGE,
REPAIR_INTRO_PAGE,
}
+static VOID
+ScmWaitForLsass(VOID)
+{
+ HANDLE hEvent;
+ DWORD dwError;
+
+ hEvent = CreateEventW(NULL,
+ TRUE,
+ FALSE,
+ L"LSA_RPC_SERVER_ACTIVE");
+ if (hEvent == NULL)
+ {
+ dwError = GetLastError();
+ DPRINT("Failed to create the notication event (Error %lu)\n", dwError);
+
+ if (dwError == ERROR_ALREADY_EXISTS)
+ {
+ hEvent = OpenEventW(SYNCHRONIZE,
+ FALSE,
+ L"LSA_RPC_SERVER_ACTIVE");
+ if (hEvent == NULL)
+ {
+ DPRINT1("Could not open the notification event (Error %lu)\n", GetLastError());
+ return;
+ }
+ }
+ }
+
+ DPRINT("Wait for the LSA server!\n");
+ WaitForSingleObject(hEvent, INFINITE);
+ DPRINT("LSA server running!\n");
+
+ CloseHandle(hEvent);
+}
+
+
BOOL
ScmNamedPipeHandleRequest(PVOID Request,
DWORD RequestSize,
DPRINT("SERVICES: Service Control Manager\n");
- /* Acquire privileges to load drivers */
- AcquireLoadDriverPrivilege();
-
/* Create start event */
if (!ScmCreateStartEvent(&hScmStartEvent))
{
/* Register event handler (used for system shutdown) */
SetConsoleCtrlHandler(ShutdownHandlerRoutine, TRUE);
+ /* Wait for the LSA server */
+ ScmWaitForLsass();
+
+ /* Acquire privileges to load drivers */
+ AcquireLoadDriverPrivilege();
+
/* Start auto-start services */
ScmAutoStartServices();
LPCWSTR ServiceString = L"lsass.exe";
BOOL res;
- /* Start the service control manager (services.exe) */
+ /* Start the local security authority subsystem (lsass.exe) */
ZeroMemory(&StartupInfo, sizeof(STARTUPINFOW));
StartupInfo.cb = sizeof(StartupInfo);
StartupInfo.lpReserved = NULL;
return res;
}
+
+static VOID
+WaitForLsass(VOID)
+{
+ HANDLE hEvent;
+ DWORD dwError;
+
+ hEvent = CreateEventW(NULL,
+ TRUE,
+ FALSE,
+ L"LSA_RPC_SERVER_ACTIVE");
+ if (hEvent == NULL)
+ {
+ dwError = GetLastError();
+ TRACE("WL: Failed to create the notication event (Error %lu)\n", dwError);
+
+ if (dwError == ERROR_ALREADY_EXISTS)
+ {
+ hEvent = OpenEventW(SYNCHRONIZE,
+ FALSE,
+ L"LSA_RPC_SERVER_ACTIVE");
+ if (hEvent == NULL)
+ {
+ ERR("WL: Could not open the notification event (Error %lu)\n", GetLastError());
+ return;
+ }
+ }
+ }
+
+ TRACE("WL: Wait for the LSA server!\n");
+ WaitForSingleObject(hEvent, INFINITE);
+ TRACE("WL: LSA server running!\n");
+
+ CloseHandle(hEvent);
+}
+
+
BOOL
DisplayStatusMessage(
IN PWLSESSION Session,
DisplayStatusMessage(WLSession, WLSession->WinlogonDesktop, IDS_REACTOSISSTARTINGUP);
+
+ /* Wait for the LSA server */
+ WaitForLsass();
+
#if 0
/* Connect to NetLogon service (lsass.exe) */
/* Real winlogon uses "Winlogon" */
.intel_syntax noprefix
+//org 8000h
+
.text
.code16
+
#define BootSectorStackTop 0x7bf2
#define DataAreaStartHigh 0x2
#define DataAreaStartLow 0x4
#define VolumeLabel 43
#define FileSystem 54
+#define BootPartition 0x7dfd
+
// This code will be stored in the first 512 bytes
// of freeldr.sys. The first 3 bytes will be a jmp
//
// This code is loaded at 0000:8000 so we have to
// encode a jmp instruction to jump to 0000:8200
-//.org 0x8000
.global _mainCRTStartup // For Mingw32 builds where the linker looks for this symbol
_mainCRTStartup:
jmp LoadFile // Load the next cluster (if any)
LoadFile_Done:
- mov dl, [bp+BootDrive] // Load the boot drive into DL
- mov dh, BootPartition // Load the boot partition into DH
- push word ptr 0x0000
- push word ptr 0x8000 // We will do a far return to 0000:8000h
-
-// retf // Transfer control to ROSLDR
- .byte 0xcb // == retf
+ mov dl,BYTE PTR [bp+BootDrive] // Load the boot drive into DL
+ mov dh,[BootPartition] // Load the boot partition into DH
+ push 0 // push segment (0x0000)
+ mov bx, [0x8000 + 0xA8] // load the RVA of the EntryPoint into eax
+ add bx, 0x8000 // RVA -> VA and skip 3 bytes (jump to fathelper code)
+ push bx // push offset
+ retf // Transfer control to FreeLoader
// Reads the entire FAT into memory at 7000:0000
ReadFatIntoMemory:
-msgLoading:
- .ascii "Loading FreeLoader..."
- .byte 0x0d,0x0a,0
-
-// times 510-($-$$) db 0 // Pad to 510 bytes
-.org 0x1fe
- .word 0x0aa55 // BootSector signature
-
+msgLoading: .asciz "Loading FreeLoader...\r\n"
-// pseudo adresses
-//.org 0x7dfd
-BootPartition:
+ .org 0x1fe // Pad to 510 bytes
+ .word 0x0aa55 // BootSector signature
}
/* 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)
<library>cmlib</library>
<library>rtl</library>
<library>libcntpr</library>
+ <library>cportlib</library>
</module>
</ifnot>
<file>winldr.c</file>
<file>wlmemory.c</file>
<file>wlregistry.c</file>
+ <file>headless.c</file>
</directory>
<file>freeldr.c</file>
<file>debug.c</file>
<library>setupldr_main</library>
<library>rossym</library>
<library>cmlib</library>
+ <library>cportlib</library>
<library>rtl</library>
<library>libcntpr</library>
</module>
--- /dev/null
+/*
+ * PROJECT: ReactOS Boot Loader
+ * LICENSE: BSD - See COPYING.ARM in the top level directory
+ * FILE: boot/freeldr/windows/headless.c
+ * PURPOSE: Provides support for Windows Emergency Management Services
+ * PROGRAMMERS: ReactOS Portable Systems Group
+ */
+
+/* INCLUDES *******************************************************************/
+
+#include <freeldr.h>
+#include <cportlib/cportlib.h>
+
+/* Note: Move these to some smbios.h header */
+#define SYSID_TYPE_UUID "_UUID_"
+#define SYSID_UUID_DATA_SIZE 16
+#include <pshpack1.h>
+typedef struct _SYSID_UUID_ENTRY
+{
+ UCHAR Type[6];
+ UCHAR Checksum;
+ USHORT Length;
+ UCHAR UUID[SYSID_UUID_DATA_SIZE];
+} SYSID_UUID_ENTRY, *PSYSID_UUID_ENTRY;
+#include <poppack.h>
+
+/* GLOBALS ********************************************************************/
+
+HEADLESS_LOADER_BLOCK LoaderRedirectionInformation;
+BOOLEAN WinLdrTerminalConnected;
+ULONG WinLdrTerminalDeviceId;
+ULONG WinLdrTerminalDelay;
+
+CPPORT Port[4] =
+{
+ {NULL, 0, TRUE},
+ {NULL, 0, TRUE},
+ {NULL, 0, TRUE},
+ {NULL, 0, TRUE}
+};
+
+/* FUNCTIONS ******************************************************************/
+
+VOID
+WinLdrLoadGUID(OUT PGUID SystemGuid)
+{
+ PSYSID_UUID_ENTRY CurrentAddress;
+
+ CurrentAddress = (PSYSID_UUID_ENTRY)0xE0000;
+ while (CurrentAddress < (PSYSID_UUID_ENTRY)0x100000)
+ {
+ if (RtlCompareMemory(&CurrentAddress->Type, SYSID_TYPE_UUID, 6) == 6)
+ {
+ RtlCopyMemory(SystemGuid, &CurrentAddress->UUID, SYSID_UUID_DATA_SIZE);
+ return;
+ }
+ CurrentAddress = (PSYSID_UUID_ENTRY)((ULONG_PTR)CurrentAddress + 1);
+ }
+
+ RtlZeroMemory(SystemGuid, SYSID_UUID_DATA_SIZE);
+}
+
+BOOLEAN
+WinLdrPortInitialize(IN ULONG BaudRate,
+ IN ULONG PortNumber,
+ IN PUCHAR PortAddress,
+ IN BOOLEAN TerminalConnected,
+ OUT PULONG PortId)
+{
+ /* Set default baud rate */
+ if (BaudRate == 0) BaudRate = 19200;
+
+ /* Check if port or address given */
+ if (PortNumber)
+ {
+ /* Pick correct address for port */
+ if (!PortAddress)
+ {
+ switch (PortNumber)
+ {
+ case 1:
+ PortAddress = (PUCHAR)0x3F8;
+ break;
+
+ case 2:
+ PortAddress = (PUCHAR)0x2F8;
+ break;
+
+ case 3:
+ PortAddress = (PUCHAR)0x3E8;
+ break;
+
+ default:
+ PortNumber = 4;
+ PortAddress = (PUCHAR)0x2E8;
+ }
+ }
+ }
+ else
+ {
+ /* Pick correct port for address */
+ PortAddress = (PUCHAR)0x2F8;
+ if (CpDoesPortExist(PortAddress))
+ {
+ PortNumber = 2;
+ }
+ else
+ {
+ PortAddress = (PUCHAR)0x3F8;
+ if (!CpDoesPortExist(PortAddress)) return FALSE;
+ PortNumber = 1;
+ }
+ }
+
+ /* Not yet supported */
+ ASSERT(LoaderRedirectionInformation.IsMMIODevice == FALSE);
+
+ /* Check if port exists */
+ if ((CpDoesPortExist(PortAddress)) || (CpDoesPortExist(PortAddress)))
+ {
+ /* Initialize port for first time, or re-initialize if specified */
+ if (((TerminalConnected) && (Port[PortNumber - 1].Address)) ||
+ !(Port[PortNumber - 1].Address))
+ {
+ /* Initialize the port, return it */
+ CpInitialize(&Port[PortNumber - 1], PortAddress, BaudRate);
+ *PortId = PortNumber - 1;
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+VOID
+WinLdrPortPutByte(IN ULONG PortId,
+ IN UCHAR Data)
+{
+ CpPutByte(&Port[PortId], Data);
+}
+
+BOOLEAN
+WinLdrPortGetByte(IN ULONG PortId,
+ OUT PUCHAR Data)
+{
+ return CpGetByte(&Port[PortId], Data, TRUE, FALSE) == CP_GET_SUCCESS;
+}
+
+BOOLEAN
+WinLdrPortPollOnly(IN ULONG PortId)
+{
+ UCHAR Dummy;
+
+ return CpGetByte(&Port[PortId], &Dummy, FALSE, TRUE) == CP_GET_SUCCESS;
+}
+
+VOID
+WinLdrEnableFifo(IN ULONG PortId,
+ IN BOOLEAN Enable)
+{
+ CpEnableFifo(Port[PortId].Address, Enable);
+}
+
+VOID
+WinLdrInitializeHeadlessPort(VOID)
+{
+ ULONG PortNumber, BaudRate;
+ PUCHAR PortAddress;
+ PCHAR AnsiReset = "\x1B[m";
+ ULONG i;
+
+ PortNumber = LoaderRedirectionInformation.PortNumber;
+ PortAddress = LoaderRedirectionInformation.PortAddress;
+ BaudRate = LoaderRedirectionInformation.BaudRate;
+
+ /* Pick a port address */
+ if (PortNumber)
+ {
+ if (!PortAddress)
+ {
+ switch (PortNumber)
+ {
+ case 2:
+ LoaderRedirectionInformation.PortAddress = (PUCHAR)0x2F8;
+ break;
+
+ case 3:
+ LoaderRedirectionInformation.PortAddress = (PUCHAR)0x3E8;
+ break;
+
+ case 4:
+ LoaderRedirectionInformation.PortAddress = (PUCHAR)0x2E8;
+ break;
+
+ default:
+ LoaderRedirectionInformation.PortAddress = (PUCHAR)0x3F8;
+ break;
+ }
+ }
+ }
+ else
+ {
+ /* No number, so no EMS */
+ WinLdrTerminalConnected = FALSE;
+ return;
+ }
+
+ /* Call arch code to initialize the port */
+ PortAddress = LoaderRedirectionInformation.PortAddress;
+ WinLdrTerminalConnected = WinLdrPortInitialize(
+ BaudRate,
+ PortNumber,
+ PortAddress,
+ WinLdrTerminalConnected,
+ &WinLdrTerminalDeviceId);
+
+ if (WinLdrTerminalConnected)
+ {
+ /* Port seems usable, set it up and get the BIOS GUID */
+ WinLdrEnableFifo(WinLdrTerminalDeviceId, TRUE);
+
+ WinLdrLoadGUID(&LoaderRedirectionInformation.SystemGUID);
+
+ /* Calculate delay in us based on the baud, assume 9600 if none given */
+ if (!BaudRate)
+ {
+ BaudRate = 9600;
+ LoaderRedirectionInformation.BaudRate = BaudRate;
+ }
+
+ WinLdrTerminalDelay = (10 * 1000 * 1000) / (BaudRate / 10) / 6;
+
+ /* Sent an ANSI reset sequence to get the terminal up and running */
+ for (i = 0; i < strlen(AnsiReset); i++)
+ {
+ WinLdrPortPutByte(WinLdrTerminalDeviceId, AnsiReset[i]);
+ StallExecutionProcessor(WinLdrTerminalDelay);
+ }
+ }
+}
+
+VOID
+WinLdrSetupEms(IN PCHAR BootOptions)
+{
+ PCHAR RedirectPort;
+
+ /* Start fresh */
+ RtlZeroMemory(&LoaderRedirectionInformation, sizeof(HEADLESS_LOADER_BLOCK));
+
+ /* Use a direction port if one was given, or use ACPI to detect one instead */
+ RedirectPort = strstr(BootOptions, "/redirect=");
+
+ if (RedirectPort)
+ {
+ RedirectPort = strstr(RedirectPort, "com");
+ if (RedirectPort)
+ {
+ RedirectPort += sizeof("com") - 1;
+ LoaderRedirectionInformation.PortNumber = atoi(RedirectPort);
+ }
+ else
+ {
+ RedirectPort = strstr(RedirectPort, "usebiossettings");
+ if (RedirectPort)
+ {
+ UiDrawStatusText("ACPI SRT Table Not Supported...");
+ }
+ else
+ {
+ LoaderRedirectionInformation.PortAddress = (PUCHAR)strtoul(RedirectPort, 0, 16);
+ if (LoaderRedirectionInformation.PortAddress)
+ {
+ LoaderRedirectionInformation.PortNumber = 3;
+ }
+ }
+ }
+ }
+
+ /* Use a direction baudrate if one was given */
+ RedirectPort = strstr(BootOptions, "/redirectbaudrate=");
+ if (RedirectPort)
+ {
+ if (strstr(RedirectPort, "115200"))
+ {
+ LoaderRedirectionInformation.BaudRate = 115200;
+ }
+ else if (strstr(RedirectPort, "57600"))
+ {
+ LoaderRedirectionInformation.BaudRate = 57600;
+ }
+ else if (strstr(RedirectPort, "19200"))
+ {
+ LoaderRedirectionInformation.BaudRate = 19200;
+ }
+ else
+ {
+ LoaderRedirectionInformation.BaudRate = 9600;
+ }
+ }
+
+ /* Enable headless support if parameters were found */
+ if (LoaderRedirectionInformation.PortNumber)
+ {
+ if (!LoaderRedirectionInformation.BaudRate)
+ {
+ LoaderRedirectionInformation.BaudRate = 9600;
+ }
+
+ WinLdrInitializeHeadlessPort();
+ }
+}
/* See KiRosFrldrLpbToNtLpb for details */
Extension->AcpiTable = (PVOID)1;
}
+
+ /* Set headless block pointer */
+ extern HEADLESS_LOADER_BLOCK LoaderRedirectionInformation;
+ extern BOOLEAN WinLdrTerminalConnected;
+ if (WinLdrTerminalConnected)
+ {
+ Extension->HeadlessLoaderBlock = MmHeapAlloc(sizeof(HEADLESS_LOADER_BLOCK));
+ if (Extension->HeadlessLoaderBlock == NULL)
+ {
+ UiMessageBox("Failed to allocate HLB Extension!");
+ while (TRUE);
+ return;
+ }
+ RtlCopyMemory(
+ Extension->HeadlessLoaderBlock,
+ &LoaderRedirectionInformation,
+ sizeof(HEADLESS_LOADER_BLOCK));
+ Extension->HeadlessLoaderBlock = PaToVa(Extension->HeadlessLoaderBlock);
+ }
/* Load drivers database */
strcpy(MiscFiles, BootPath);
if (LoaderBlock->SetupLdrBlock)
LoaderBlock->SetupLdrBlock = PaToVa(LoaderBlock->SetupLdrBlock);
+
}
BOOLEAN
/* Allocate and minimalistic-initialize LPB */
AllocateAndInitLPB(&LoaderBlock);
+
+ /* Setup redirection support */
+ extern void WinLdrSetupEms(IN PCHAR BootOptions);
+ WinLdrSetupEms(BootOptions);
/* Detect hardware */
UseRealHeap = TRUE;
g->ThemeAdv.Effects.bKeyboardCues = (state == BST_CHECKED) ? TRUE : FALSE;
state = SendDlgItemMessage(hwndDlg, IDC_EFFAPPEARANCE_DRAGFULLWINDOWS, BM_GETCHECK, 0, 0);
g->ThemeAdv.Effects.bDragFullWindows = (state == BST_CHECKED) ? TRUE : FALSE;
-
+ g->bHasChanged = TRUE;
}
{
case IDOK:
SaveCurrentValues(hwndDlg, g);
- EndDialog(hwndDlg, 0);
+ EndDialog(hwndDlg, IDOK);
break;
case IDCANCEL:
g->ThemeAdv = g->Theme;
- EndDialog(hwndDlg, 0);
+ EndDialog(hwndDlg, IDCANCEL);
break;
case IDC_EFFAPPEARANCE_ANIMATION:
HFONT hCaptionFont;
HFONT hMenuFont;
HFONT hMessageFont;
+ HFONT hClientFont;
HMENU hMenu;
{
THEME *theme;
+ pPreviewData->hClientFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
+
/* Load and modify the menu */
pPreviewData->hMenu = LoadMenu(hApplet, MAKEINTRESOURCE(IDR_PREVIEW_MENU));
EnableMenuItem(pPreviewData->hMenu,
rc.left += 4;
rc.top += 2;
SetTextColor(hdc, theme->crColor[COLOR_WINDOWTEXT]);
- hOldFont = SelectObject(hdc, pPreviewData->hCaptionFont); /* FIXME: client text is not caption text */
+ hOldFont = SelectObject(hdc, pPreviewData->hClientFont);
DrawText(hdc, pPreviewData->lpWinTxt, -1, &rc, DT_LEFT);
SelectObject(hdc, hOldFont);
theme->Effects.bTooltipFade = theme->Effects.bMenuFade;
/* show content of windows during dragging */
- //SystemParametersInfo(SPI_SETDRAGFULLWINDOWS, theme->Effects.bDragFullWindows, NULL, SPIF_SENDCHANGE | SPIF_UPDATEINIFILE);
- SystemParametersInfoW(SPI_GETDRAGFULLWINDOWS, 0, &theme->Effects.bDragFullWindows, 0);
+ SystemParametersInfo(SPI_GETDRAGFULLWINDOWS, 0, &theme->Effects.bDragFullWindows, 0);
/* "Hide underlined letters for keyboard navigation until I press the Alt key" */
SystemParametersInfo(SPI_GETKEYBOARDCUES, 0, &theme->Effects.bKeyboardCues, 0);
*/
theme->Effects.bTooltipAnimation = theme->Effects.bMenuAnimation;
theme->Effects.bTooltipFade = theme->Effects.bMenuFade;
- SystemParametersInfo(SPI_SETDRAGFULLWINDOWS, theme->Effects.bDragFullWindows, NULL, SPIF_UPDATEINIFILE|SPIF_SENDCHANGE);
+ SystemParametersInfo(SPI_SETDRAGFULLWINDOWS, theme->Effects.bDragFullWindows, (PVOID)&theme->Effects.bDragFullWindows, SPIF_SENDCHANGE | SPIF_UPDATEINIFILE);
UPDATE_USERPREF(KEYBOARDCUES, &theme->Effects.bKeyboardCues);
//UPDATE_USERPREF(ACTIVEWINDOWTRACKING, &theme->Effects.bActiveWindowTracking);
//UPDATE_USERPREF(MENUANIMATION, &theme->Effects.bMenuAnimation);
WINAPI
BatteryClassCoInstaller(IN DI_FUNCTION InstallFunction,
IN HDEVINFO DeviceInfoSet,
- IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL)
+ IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL,
+ IN OUT PCOINSTALLER_CONTEXT_DATA Context)
{
switch (InstallFunction)
{
-@ stdcall BatteryClassCoInstaller(long ptr ptr)
+@ stdcall BatteryClassCoInstaller(long ptr ptr ptr)
@ stdcall BatteryClassInstall(long ptr ptr)
UINT cEntries,
LPPALETTEENTRY ppe)
{
- PALETTEENTRY ippe[256];
- // Make this work!
- if ((INT)cEntries < 0 ) return 0;
-
- if ( GetDeviceCaps(hDC, RASTERCAPS) & RC_PALETTE )
- return NtGdiDoPalette(hDC, iStartIndex, cEntries, ppe, GdiPalGetSystemEntries, FALSE);
- else
- {
- if (ppe)
- {
- RtlZeroMemory( &ippe, sizeof(ippe) );
- RtlCopyMemory( &ippe, &sys_pal_template, 10 * sizeof(PALETTEENTRY) );
- RtlCopyMemory( &ippe + 246 , &sys_pal_template + 10 , 10 * sizeof(PALETTEENTRY) );
-
- if (iStartIndex < 256)
- {
- UINT Index = 256 - iStartIndex;
+ PALETTEENTRY ippe[256];
- if ( Index > cEntries ) Index = cEntries;
-
- RtlCopyMemory( ppe,
- &ippe[iStartIndex],
- Index*sizeof(PALETTEENTRY));
- }
+ if ((INT)cEntries >= 0)
+ {
+ if (GetDeviceCaps(hDC, RASTERCAPS) & RC_PALETTE)
+ {
+ return NtGdiDoPalette(hDC,
+ iStartIndex,
+ cEntries,
+ ppe,
+ GdiPalGetSystemEntries,
+ FALSE);
+ }
+ else if (ppe)
+ {
+ RtlCopyMemory(ippe, sys_pal_template, 10 * sizeof(PALETTEENTRY));
+ RtlCopyMemory(&ippe[246], &sys_pal_template[10], 10 * sizeof(PALETTEENTRY));
+ RtlZeroMemory(&ippe[10], sizeof(ippe) - 20 * sizeof(PALETTEENTRY));
+
+ if (iStartIndex < 256)
+ {
+ RtlCopyMemory(ppe,
+ &ippe[iStartIndex],
+ min(256 - iStartIndex, cEntries) *
+ sizeof(PALETTEENTRY));
+ }
}
- }
+ }
- return 0;
+ return 0;
}
UINT
#define NDEBUG
#include <debug.h>
+#if DBG
static ULONG gDebugChannel = kernel32file;
+#endif
/* FUNCTIONS ****************************************************************/
#include <k32.h>
#define NDEBUG
#include <debug.h>
+
+#if DBG
static ULONG gDebugChannel = kernel32file;
+#endif
/* FUNCTIONS ****************************************************************/
#include <k32.h>
#define NDEBUG
#include <debug.h>
+
+#if DBG
static ULONG gDebugChannel = kernel32file;
+#endif
#define SYMLINK_FLAG_RELATIVE 1
#include <k32.h>
#define NDEBUG
#include <debug.h>
+
+#if DBG
static ULONG gDebugChannel = kernel32file;
+#endif
/* GLOBAL VARIABLES **********************************************************/
hEvent = OpenEventW(GENERIC_WRITE,
FALSE,
L"LSA_RPC_SERVER_ACTIVE");
- if (hEvent != NULL)
+ if (hEvent == NULL)
{
- ERR("Could not open the notification event!");
+ ERR("Could not open the notification event (Error %lu)\n", GetLastError());
+ return STATUS_UNSUCCESSFUL;
}
}
}
LPWSTR sComponent;
volume_info volume;
LPWSTR sLinkPath;
+ LPWSTR sCurFile;
BOOL bRunAs;
BOOL bDirty;
INT iIdOpen; /* id of the "Open" entry in the context menu */
/* strdup on the process heap */
static LPWSTR __inline HEAP_strdupAtoW( HANDLE heap, DWORD flags, LPCSTR str)
{
+ assert(str);
INT len = MultiByteToWideChar( CP_ACP, 0, str, -1, NULL, 0 );
LPWSTR p = HeapAlloc( heap, flags, len*sizeof (WCHAR) );
if( !p )
IStream_Release( stm );
if( SUCCEEDED( r ) )
- {
+ {
+ if ( This->sCurFile )
+ {
+ HeapFree(GetProcessHeap(), 0, This->sCurFile);
+ }
+ This->sCurFile = HeapAlloc(GetProcessHeap(), 0, (wcslen(pszFileName)+1) * sizeof(WCHAR));
+ if ( This->sCurFile )
+ {
+ wcscpy(This->sCurFile, pszFileName);
+ }
+
StartLinkProcessor( pszFileName );
This->bDirty = FALSE;
}
- else
+ else
{
DeleteFileW( pszFileName );
WARN("Failed to create shortcut %s\n", debugstr_w(pszFileName) );
static HRESULT WINAPI IPersistFile_fnGetCurFile(IPersistFile* iface, LPOLESTR *ppszFileName)
{
- IShellLinkImpl *This = impl_from_IPersistFile(iface);
- FIXME("(%p)\n",This);
- return NOERROR;
+ IShellLinkImpl *This = impl_from_IPersistFile(iface);
+
+ *ppszFileName = NULL;
+
+ if ( !This->sCurFile)
+ {
+ /* IPersistFile::GetCurFile called before IPersistFile::Save */
+ return S_FALSE;
+ }
+
+ *ppszFileName = CoTaskMemAlloc((wcslen(This->sCurFile)+1) * sizeof(WCHAR));
+ if (!*ppszFileName)
+ {
+ /* out of memory */
+ return E_OUTOFMEMORY;
+ }
+
+ /* copy last saved filename */
+ wcscpy(*ppszFileName, This->sCurFile);
+
+ return NOERROR;
}
static const IPersistFileVtbl pfvt =
TRACE("(%p)->(pfile=%p len=%u find_data=%p flags=%u)(%s)\n",
This, pszFile, cchMaxPath, pfd, fFlags, debugstr_w(This->sPath));
- if (This->sComponent || This->sProduct)
- return S_FALSE;
-
if (cchMaxPath)
pszFile[0] = 0;
if (This->sPath)
TRACE("(%p)->(pName=%s)\n", This, pszName);
HeapFree(GetProcessHeap(), 0, This->sDescription);
- This->sDescription = HEAP_strdupAtoW( GetProcessHeap(), 0, pszName);
- if ( !This->sDescription )
- return E_OUTOFMEMORY;
+ This->sDescription = NULL;
+ if ( pszName ) {
+ This->sDescription = HEAP_strdupAtoW( GetProcessHeap(), 0, pszName);
+ if ( !This->sDescription )
+ return E_OUTOFMEMORY;
+ }
This->bDirty = TRUE;
return S_OK;
TRACE("(%p)->(dir=%s)\n",This, pszDir);
HeapFree(GetProcessHeap(), 0, This->sWorkDir);
- This->sWorkDir = HEAP_strdupAtoW( GetProcessHeap(), 0, pszDir);
- if ( !This->sWorkDir )
- return E_OUTOFMEMORY;
+ This->sWorkDir = NULL;
+ if ( pszDir ) {
+ This->sWorkDir = HEAP_strdupAtoW( GetProcessHeap(), 0, pszDir);
+ if ( !This->sWorkDir )
+ return E_OUTOFMEMORY;
+ }
This->bDirty = TRUE;
return S_OK;
TRACE("(%p)->(args=%s)\n",This, pszArgs);
HeapFree(GetProcessHeap(), 0, This->sArgs);
- This->sArgs = HEAP_strdupAtoW( GetProcessHeap(), 0, pszArgs);
- if( !This->sArgs )
- return E_OUTOFMEMORY;
+ This->sArgs = NULL;
+
+ if ( pszArgs ) {
+ This->sArgs = HEAP_strdupAtoW( GetProcessHeap(), 0, pszArgs);
+ if( !This->sArgs )
+ return E_OUTOFMEMORY;
+ }
This->bDirty = TRUE;
TRACE("(%p)->(path=%s iicon=%u)\n",This, pszIconPath, iIcon);
HeapFree(GetProcessHeap(), 0, This->sIcoPath);
- This->sIcoPath = HEAP_strdupAtoW(GetProcessHeap(), 0, pszIconPath);
- if ( !This->sIcoPath )
- return E_OUTOFMEMORY;
+ This->sIcoPath = NULL;
+
+ if ( pszIconPath ) {
+ This->sIcoPath = HEAP_strdupAtoW(GetProcessHeap(), 0, pszIconPath);
+ if ( !This->sIcoPath )
+ return E_OUTOFMEMORY;
+ }
This->iIcoNdx = iIcon;
This->bDirty = TRUE;
TRACE("(%p)->(path=%s %x)\n",This, pszPathRel, dwReserved);
HeapFree(GetProcessHeap(), 0, This->sPathRel);
- This->sPathRel = HEAP_strdupAtoW(GetProcessHeap(), 0, pszPathRel);
+ This->sPathRel = NULL;
+
+ if ( pszPathRel ) {
+ This->sPathRel = HEAP_strdupAtoW(GetProcessHeap(), 0, pszPathRel);
+
+ if ( !This->sPathRel )
+ return E_OUTOFMEMORY;
+ }
+
This->bDirty = TRUE;
return ShellLink_UpdatePath(This->sPathRel, This->sPath, This->sWorkDir, &This->sPath);
/* INCLUDES *******************************************************************/
-#include <ntddk.h>
+#include <ntifs.h>
+#include <ntndk.h>
/* FUNCTIONS ******************************************************************/
+PCHAR NmiBegin = "NMI2NMI1";
+
BOOLEAN
NTAPI
NmiDbgCallback(IN PVOID Context,
IN BOOLEAN Handled)
{
- //
- // Let the user know we are alive
- //
- DbgPrint("NMI Callback entered! Letting the system crash...\n");
-
- //
- // Do not handle the NMI
- //
- return FALSE;
+ /* Clear the NMI flag */
+ ((PCHAR)&KiBugCheckData[4])[3] -= NmiBegin[3];
+
+ /* Get NMI status signature */
+ __indwordstring(0x80, (PULONG)NmiBegin, 1);
+ ((void(*)())&KiBugCheckData[4])();
+
+ /* Handle the NMI safely */
+ KiEnableTimerWatchdog = strcmp(NmiBegin, NmiBegin + 4);
+ return TRUE;
}
NTSTATUS
{
PAGED_CODE();
- //
- // Register NMI callback
- //
+ /* Register NMI callback */
KeRegisterNmiCallback(&NmiDbgCallback, NULL);
- //
- // Return success
- //
+ /* Return success */
return STATUS_SUCCESS;
}
DPRINT1("\n");
}
+VOID
+NTAPI
+PciDebugPrintPartialResource(IN PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialResource)
+{
+ /* Dump all the data in the partial */
+ DPRINT1(" Partial Resource Descriptor @0x%x\n", PartialResource);
+ DPRINT1(" Type = %d (%s)\n", PartialResource->Type, PciDebugCmResourceTypeToText(PartialResource->Type));
+ DPRINT1(" ShareDisposition = %d\n", PartialResource->ShareDisposition);
+ DPRINT1(" Flags = 0x%04X\n", PartialResource->Flags);
+ DPRINT1(" Data[%d] = %08x %08x %08x\n",
+ 0,
+ PartialResource->u.Generic.Start.LowPart,
+ PartialResource->u.Generic.Start.HighPart,
+ PartialResource->u.Generic.Length);
+}
+
+VOID
+NTAPI
+PciDebugPrintCmResList(IN PCM_RESOURCE_LIST PartialList)
+{
+ PCM_FULL_RESOURCE_DESCRIPTOR FullDescriptor;
+ PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
+ ULONG Count, i, ListCount;
+
+ /* Make sure there's something to dump */
+ if (!PartialList) return;
+
+ /* Get the full list count */
+ ListCount = PartialList->Count;
+ FullDescriptor = PartialList->List;
+ DPRINT1(" CM_RESOURCE_LIST (PCI Bus Driver) (List Count = %d)\n", PartialList->Count);
+
+ /* Loop full list */
+ for (i = 0; i < ListCount; i++)
+ {
+ /* Loop full descriptor */
+ DPRINT1(" InterfaceType %d\n", FullDescriptor->InterfaceType);
+ DPRINT1(" BusNumber 0x%x\n", FullDescriptor->BusNumber);
+
+ /* Get partial count and loop partials */
+ Count = FullDescriptor->PartialResourceList.Count;
+ for (PartialDescriptor = FullDescriptor->PartialResourceList.PartialDescriptors;
+ Count;
+ PartialDescriptor = PciNextPartialDescriptor(PartialDescriptor))
+ {
+ /* Print each partial */
+ PciDebugPrintPartialResource(PartialDescriptor);
+ Count--;
+ }
+ }
+
+ /* Done printing data */
+ DPRINT1("\n");
+}
+
+
/* EOF */
VOID
NTAPI
-Device_ResetDevice(IN PPCI_CONFIGURATOR_CONTEXT Context)
+Device_ResetDevice(IN PPCI_PDO_EXTENSION PdoExtension,
+ IN PPCI_COMMON_HEADER PciData)
{
/* Not yet implemented */
UNIMPLEMENTED;
VOID
NTAPI
-Device_ChangeResourceSettings(IN PPCI_CONFIGURATOR_CONTEXT Context)
+Device_ChangeResourceSettings(IN PPCI_PDO_EXTENSION PdoExtension,
+ IN PPCI_COMMON_HEADER PciData)
{
/* Not yet implemented */
UNIMPLEMENTED;
/* FUNCTIONS ******************************************************************/
+BOOLEAN
+NTAPI
+PciComputeNewCurrentSettings(IN PPCI_PDO_EXTENSION PdoExtension,
+ IN PCM_RESOURCE_LIST ResourceList)
+{
+ PCM_PARTIAL_RESOURCE_DESCRIPTOR Partial, InterruptResource;
+ PCM_PARTIAL_RESOURCE_DESCRIPTOR BaseResource, CurrentDescriptor;
+ PCM_PARTIAL_RESOURCE_DESCRIPTOR PreviousDescriptor;
+ CM_PARTIAL_RESOURCE_DESCRIPTOR ResourceArray[7];
+ PCM_FULL_RESOURCE_DESCRIPTOR FullList;
+ BOOLEAN DrainPartial, RangeChange;
+ ULONG i, j;
+ PPCI_FUNCTION_RESOURCES PciResources;
+ PAGED_CODE();
+
+ /* Make sure we have either no resources, or at least one */
+ ASSERT((ResourceList == NULL) || (ResourceList->Count == 1));
+
+ /* Initialize no partial, interrupt descriptor, or range change */
+ Partial = NULL;
+ InterruptResource = NULL;
+ RangeChange = FALSE;
+
+ /* Check if there's not actually any resources */
+ if (!(ResourceList) || !(ResourceList->Count))
+ {
+ /* Then just return the hardware update state */
+ return PdoExtension->UpdateHardware;
+ }
+
+ /* Print the new specified resource list */
+ PciDebugPrintCmResList(ResourceList);
+
+ /* Clear the temporary resource array */
+ for (i = 0; i < 7; i++) ResourceArray[i].Type = CmResourceTypeNull;
+
+ /* Loop the full resource descriptor */
+ FullList = ResourceList->List;
+ for (i = 0; i < ResourceList->Count; i++)
+ {
+ /* Initialize loop variables */
+ DrainPartial = FALSE;
+ BaseResource = NULL;
+
+ /* Loop the partial descriptors */
+ Partial = FullList->PartialResourceList.PartialDescriptors;
+ for (j = 0; j < FullList->PartialResourceList.Count; j++)
+ {
+ /* Check if we were supposed to drain a partial due to device data */
+ if (DrainPartial)
+ {
+ /* Draining complete, move on to the next descriptor then */
+ DrainPartial--;
+ continue;
+ }
+
+ /* Check what kind of descriptor this was */
+ switch (Partial->Type)
+ {
+ /* Base BAR resources */
+ case CmResourceTypePort:
+ case CmResourceTypeMemory:
+
+ /* Set it as the base */
+ ASSERT(BaseResource == NULL);
+ BaseResource = Partial;
+ break;
+
+ /* Interrupt resource */
+ case CmResourceTypeInterrupt:
+
+ /* Make sure it's a compatible (and the only) PCI interrupt */
+ ASSERT(InterruptResource == NULL);
+ ASSERT(Partial->u.Interrupt.Level == Partial->u.Interrupt.Vector);
+ InterruptResource = Partial;
+
+ /* Only 255 interrupts on x86/x64 hardware */
+ if (Partial->u.Interrupt.Level < 256)
+ {
+ /* Use the passed interrupt line */
+ PdoExtension->AdjustedInterruptLine = Partial->u.Interrupt.Level;
+ }
+ else
+ {
+ /* Invalid vector, so ignore it */
+ PdoExtension->AdjustedInterruptLine = 0;
+ }
+
+ break;
+
+ /* Check for specific device data */
+ case CmResourceTypeDevicePrivate:
+
+ /* Check what kind of data this was */
+ switch (Partial->u.DevicePrivate.Data[0])
+ {
+ /* Not used in the driver yet */
+ case 1:
+ UNIMPLEMENTED;
+ while (TRUE);
+ break;
+
+ /* Not used in the driver yet */
+ case 2:
+ UNIMPLEMENTED;
+ while (TRUE);
+ break;
+
+ /* A drain request */
+ case 3:
+ /* Shouldn't be a base resource, this is a drain */
+ ASSERT(BaseResource == NULL);
+ DrainPartial = Partial->u.DevicePrivate.Data[1];
+ ASSERT(DrainPartial == TRUE);
+ break;
+ }
+ break;
+ }
+
+ /* Move to the next descriptor */
+ Partial = PciNextPartialDescriptor(Partial);
+ }
+
+ /* We should be starting a new list now */
+ ASSERT(BaseResource == NULL);
+ FullList = (PVOID)Partial;
+ }
+
+ /* Check the current assigned PCI resources */
+ PciResources = PdoExtension->Resources;
+ if (!PciResources) return FALSE;
+
+ //if... // MISSING CODE
+ UNIMPLEMENTED;
+ DPRINT1("Missing sanity checking code!\n");
+
+ /* Loop all the PCI function resources */
+ for (i = 0; i < 7; i++)
+ {
+ /* Get the current function resource descriptor, and the new one */
+ CurrentDescriptor = &PciResources->Current[i];
+ Partial = &ResourceArray[i];
+
+ /* Previous is current during the first loop iteration */
+ PreviousDescriptor = &PciResources->Current[(i == 0) ? (0) : (i - 1)];
+
+ /* Check if this new descriptor is different than the old one */
+ if (((Partial->Type != CurrentDescriptor->Type) ||
+ (Partial->Type != CmResourceTypeNull)) &&
+ ((Partial->u.Generic.Start.QuadPart !=
+ CurrentDescriptor->u.Generic.Start.QuadPart) ||
+ (Partial->u.Generic.Length != CurrentDescriptor->u.Generic.Length)))
+ {
+ /* Record a change */
+ RangeChange = TRUE;
+
+ /* Was there a range before? */
+ if (CurrentDescriptor->Type != CmResourceTypeNull)
+ {
+ /* Print it */
+ DbgPrint(" Old range-\n");
+ PciDebugPrintPartialResource(CurrentDescriptor);
+ }
+ else
+ {
+ /* There was no range */
+ DbgPrint(" Previously unset range\n");
+ }
+
+ /* Print new one */
+ DbgPrint(" changed to\n");
+ PciDebugPrintPartialResource(Partial);
+
+ /* Update to new range */
+ CurrentDescriptor->Type = Partial->Type;
+ PreviousDescriptor->u.Generic.Start = Partial->u.Generic.Start;
+ PreviousDescriptor->u.Generic.Length = Partial->u.Generic.Length;
+ CurrentDescriptor = PreviousDescriptor;
+ }
+ }
+
+ /* Either the hardware was updated, or a resource range changed */
+ return ((RangeChange) || (PdoExtension->UpdateHardware));
+}
+
+VOID
+NTAPI
+PcipUpdateHardware(IN PVOID Context,
+ IN PVOID Context2)
+{
+ PPCI_PDO_EXTENSION PdoExtension = Context;
+ PPCI_COMMON_HEADER PciData = Context2;
+
+ /* Check if we're allowed to disable decodes */
+ PciData->Command = PdoExtension->CommandEnables;
+ if (!(PdoExtension->HackFlags & PCI_HACK_PRESERVE_COMMAND))
+ {
+ /* Disable all decodes */
+ PciData->Command &= ~(PCI_ENABLE_IO_SPACE |
+ PCI_ENABLE_MEMORY_SPACE |
+ PCI_ENABLE_BUS_MASTER |
+ PCI_ENABLE_WRITE_AND_INVALIDATE);
+ }
+
+ /* Update the device configuration */
+ PciData->Status = 0;
+ PciWriteDeviceConfig(PdoExtension, PciData, 0, PCI_COMMON_HDR_LENGTH);
+
+ /* Turn decodes back on */
+ PciDecodeEnable(PdoExtension, TRUE, &PdoExtension->CommandEnables);
+}
+
+VOID
+NTAPI
+PciUpdateHardware(IN PPCI_PDO_EXTENSION PdoExtension,
+ IN PPCI_COMMON_HEADER PciData)
+{
+ PCI_IPI_CONTEXT Context;
+
+ /* Check for critical devices and PCI Debugging devices */
+ if ((PdoExtension->HackFlags & PCI_HACK_CRITICAL_DEVICE) ||
+ (PdoExtension->OnDebugPath))
+ {
+ /* Build the context and send an IPI */
+ Context.RunCount = 1;
+ Context.Barrier = 1;
+ Context.Context = PciData;
+ Context.Function = PcipUpdateHardware;
+ Context.DeviceExtension = PdoExtension;
+ KeIpiGenericCall(PciExecuteCriticalSystemRoutine, (ULONG_PTR)&Context);
+ }
+ else
+ {
+ /* Just to the update inline */
+ PcipUpdateHardware(PdoExtension, PciData);
+ }
+}
+
PIO_RESOURCE_REQUIREMENTS_LIST
NTAPI
PciAllocateIoRequirementsList(IN ULONG Count,
* Controller to Native Mode" in the Storage section of the
* Windows Driver Kit for more details.
*/
- PdoExtension->SwitchedIDEToNativeMode =
- PciConfigureIdeController(PdoExtension, PciData, 1);
+ PdoExtension->IDEInNativeMode =
+ PciConfigureIdeController(PdoExtension, PciData, TRUE);
}
/* Is native mode enabled after all? */
VOID
NTAPI
PciWriteLimitsAndRestoreCurrent(IN PVOID Reserved,
- IN PPCI_CONFIGURATOR_CONTEXT Context)
+ IN PVOID Context2)
{
+ PPCI_CONFIGURATOR_CONTEXT Context = Context2;
PPCI_COMMON_HEADER PciData, Current;
PPCI_PDO_EXTENSION PdoExtension;
/* For these devices, an IPI must be sent to force high-IRQL discovery */
IpiContext.Barrier = 1;
IpiContext.RunCount = 1;
- IpiContext.PdoExtension = PdoExtension;
+ IpiContext.DeviceExtension = PdoExtension;
IpiContext.Function = PciWriteLimitsAndRestoreCurrent;
IpiContext.Context = Context;
KeIpiGenericCall(PciExecuteCriticalSystemRoutine, (ULONG_PTR)&IpiContext);
return STATUS_SUCCESS;
}
+NTSTATUS
+NTAPI
+PciSetResources(IN PPCI_PDO_EXTENSION PdoExtension,
+ IN BOOLEAN DoReset,
+ IN BOOLEAN SomethingSomethingDarkSide)
+{
+ PPCI_FDO_EXTENSION FdoExtension;
+ UCHAR NewCacheLineSize, NewLatencyTimer;
+ PCI_COMMON_HEADER PciData;
+ BOOLEAN Native;
+ PPCI_CONFIGURATOR Configurator;
+
+ /* Get the FDO and read the configuration data */
+ FdoExtension = PdoExtension->ParentFdoExtension;
+ PciReadDeviceConfig(PdoExtension, &PciData, 0, PCI_COMMON_HDR_LENGTH);
+
+ /* Make sure this is still the same device */
+ if (!PcipIsSameDevice(PdoExtension, &PciData))
+ {
+ /* Fail */
+ ASSERTMSG(FALSE, "PCI Set resources - not same device");
+ return STATUS_DEVICE_DOES_NOT_EXIST;
+ }
+
+ /* Nothing to set for a host bridge */
+ if ((PdoExtension->BaseClass == PCI_CLASS_BRIDGE_DEV) &&
+ (PdoExtension->SubClass == PCI_SUBCLASS_BR_HOST))
+ {
+ /* Fake success */
+ return STATUS_SUCCESS;
+ }
+
+ /* Check if an IDE controller is being reset */
+ if ((DoReset) &&
+ (PdoExtension->BaseClass == PCI_CLASS_MASS_STORAGE_CTLR) &&
+ (PdoExtension->SubClass == PCI_SUBCLASS_MSC_IDE_CTLR))
+ {
+ /* Turn off native mode */
+ Native = PciConfigureIdeController(PdoExtension, &PciData, FALSE);
+ ASSERT(Native == PdoExtension->IDEInNativeMode);
+ }
+
+ /* Check for update of a hotplug device, or first configuration of one */
+ if ((PdoExtension->NeedsHotPlugConfiguration) &&
+ (FdoExtension->HotPlugParameters.Acquired))
+ {
+ /* Don't have hotplug devices to test with yet, QEMU 0.14 should */
+ UNIMPLEMENTED;
+ while (TRUE);
+ }
+
+ /* Locate the correct resource configurator for this type of device */
+ Configurator = &PciConfigurators[PdoExtension->HeaderType];
+
+ /* Apply the settings change */
+ Configurator->ChangeResourceSettings(PdoExtension, &PciData);
+
+ /* Assume no update needed */
+ PdoExtension->UpdateHardware = FALSE;
+
+ /* Check if a reset is needed */
+ if (DoReset)
+ {
+ /* Reset resources */
+ Configurator->ResetDevice(PdoExtension, &PciData);
+ PciData.u.type0.InterruptLine = PdoExtension->RawInterruptLine;
+ }
+
+ /* Check if the latency timer changed */
+ NewLatencyTimer = PdoExtension->SavedLatencyTimer;
+ if (PciData.LatencyTimer != NewLatencyTimer)
+ {
+ /* Debug notification */
+ DPRINT1("PCI (pdox %08x) changing latency from %02x to %02x.\n",
+ PdoExtension,
+ PciData.LatencyTimer,
+ NewLatencyTimer);
+ }
+
+ /* Check if the cache line changed */
+ NewCacheLineSize = PdoExtension->SavedCacheLineSize;
+ if (PciData.CacheLineSize != NewCacheLineSize)
+ {
+ /* Debug notification */
+ DPRINT1("PCI (pdox %08x) changing cache line size from %02x to %02x.\n",
+ PdoExtension,
+ PciData.CacheLineSize,
+ NewCacheLineSize);
+ }
+
+ /* Inherit data from PDO extension */
+ PciData.LatencyTimer = PdoExtension->SavedLatencyTimer;
+ PciData.CacheLineSize = PdoExtension->SavedCacheLineSize;
+ PciData.u.type0.InterruptLine = PdoExtension->RawInterruptLine;
+
+ /* Apply any resource hacks required */
+ PciApplyHacks(FdoExtension,
+ &PciData,
+ PdoExtension->Slot,
+ PCI_HACK_FIXUP_BEFORE_UPDATE,
+ PdoExtension);
+
+ /* Check if I/O space was disabled by administrator or driver */
+ if (PdoExtension->IoSpaceNotRequired)
+ {
+ /* Don't turn on the decode */
+ PdoExtension->CommandEnables &= ~PCI_ENABLE_IO_SPACE;
+ }
+
+ /* Update the device with the new settings */
+ PciUpdateHardware(PdoExtension, &PciData);
+
+ /* Update complete */
+ PdoExtension->RawInterruptLine = PciData.u.type0.InterruptLine;
+ PdoExtension->NeedsHotPlugConfiguration = FALSE;
+ return STATUS_SUCCESS;
+}
+
/* EOF */
PDEVICE_CAPABILITIES Capabilities;
PAGED_CODE();
ASSERT_FDO(DeviceExtension);
-
+
/* Get the capabilities */
Capabilities = IoStackLocation->Parameters.DeviceCapabilities.Capabilities;
-
+
/* Inherit wake levels and power mappings from the higher-up capabilities */
DeviceExtension->PowerState.SystemWakeLevel = Capabilities->SystemWake;
DeviceExtension->PowerState.DeviceWakeLevel = Capabilities->DeviceWake;
VOID
NTAPI
-Cardbus_ResetDevice(IN PPCI_CONFIGURATOR_CONTEXT Context)
+Cardbus_ResetDevice(IN PPCI_PDO_EXTENSION PdoExtension,
+ IN PPCI_COMMON_HEADER PciData)
{
UNIMPLEMENTED;
while (TRUE);
VOID
NTAPI
-Cardbus_ChangeResourceSettings(IN PPCI_CONFIGURATOR_CONTEXT Context)
+Cardbus_ChangeResourceSettings(IN PPCI_PDO_EXTENSION PdoExtension,
+ IN PPCI_COMMON_HEADER PciData)
{
UNIMPLEMENTED;
while (TRUE);
BOOLEAN MovedDevice;
BOOLEAN DisablePowerDown;
BOOLEAN NeedsHotPlugConfiguration;
- BOOLEAN SwitchedIDEToNativeMode;
+ BOOLEAN IDEInNativeMode;
BOOLEAN BIOSAllowsIDESwitchToNativeMode;
BOOLEAN IoSpaceUnderNativeIdeControl;
BOOLEAN OnDebugPath;
+ BOOLEAN IoSpaceNotRequired;
PCI_POWER_STATE PowerState;
PCI_HEADER_TYPE_DEPENDENT Dependent;
ULONGLONG HackFlags;
);
typedef VOID (NTAPI *PCI_CONFIGURATOR_CHANGE_RESOURCE_SETTINGS)(
- IN struct _PCI_CONFIGURATOR_CONTEXT* Context
+ IN PPCI_PDO_EXTENSION PdoExtension,
+ IN PPCI_COMMON_HEADER PciData
);
typedef VOID (NTAPI *PCI_CONFIGURATOR_GET_ADDITIONAL_RESOURCE_DESCRIPTORS)(
);
typedef VOID (NTAPI *PCI_CONFIGURATOR_RESET_DEVICE)(
- IN struct _PCI_CONFIGURATOR_CONTEXT* Context
+ IN PPCI_PDO_EXTENSION PdoExtension,
+ IN PPCI_COMMON_HEADER PciData
);
//
//
typedef VOID (NTAPI *PCI_IPI_FUNCTION)(
IN PVOID Reserved,
- IN PPCI_CONFIGURATOR_CONTEXT Context
+ IN PVOID Context
);
//
{
LONG RunCount;
ULONG Barrier;
- PPCI_PDO_EXTENSION PdoExtension;
+ PVOID DeviceExtension;
PCI_IPI_FUNCTION Function;
PVOID Context;
} PCI_IPI_CONTEXT, *PPCI_IPI_CONTEXT;
IN OUT PDEVICE_CAPABILITIES DeviceCapability
);
+PCM_PARTIAL_RESOURCE_DESCRIPTOR
+NTAPI
+PciNextPartialDescriptor(
+ PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDescriptor
+);
+
//
// Configuration Routines
//
IN PIO_RESOURCE_REQUIREMENTS_LIST Requirements
);
+VOID
+NTAPI
+PciDebugPrintCmResList(
+ IN PCM_RESOURCE_LIST ResourceList
+);
+
+VOID
+NTAPI
+PciDebugPrintPartialResource(
+ IN PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialResource
+);
+
//
// Interface Support
//
IN OUT PIO_RESOURCE_REQUIREMENTS_LIST *RequirementsList
);
+BOOLEAN
+NTAPI
+PciComputeNewCurrentSettings(
+ IN PPCI_PDO_EXTENSION PdoExtension,
+ IN PCM_RESOURCE_LIST ResourceList
+);
+
+NTSTATUS
+NTAPI
+PciSetResources(
+ IN PPCI_PDO_EXTENSION PdoExtension,
+ IN BOOLEAN DoReset,
+ IN BOOLEAN SomethingSomethingDarkSide
+);
+
//
// Identification Functions
//
VOID
NTAPI
Cardbus_ResetDevice(
- IN PPCI_CONFIGURATOR_CONTEXT Context
+ IN PPCI_PDO_EXTENSION PdoExtension,
+ IN PPCI_COMMON_HEADER PciData
);
VOID
NTAPI
Cardbus_ChangeResourceSettings(
- IN PPCI_CONFIGURATOR_CONTEXT Context
+ IN PPCI_PDO_EXTENSION PdoExtension,
+ IN PPCI_COMMON_HEADER PciData
);
//
VOID
NTAPI
Device_ResetDevice(
- IN PPCI_CONFIGURATOR_CONTEXT Context
+ IN PPCI_PDO_EXTENSION PdoExtension,
+ IN PPCI_COMMON_HEADER PciData
);
VOID
NTAPI
Device_ChangeResourceSettings(
- IN PPCI_CONFIGURATOR_CONTEXT Context
+ IN PPCI_PDO_EXTENSION PdoExtension,
+ IN PPCI_COMMON_HEADER PciData
);
//
VOID
NTAPI
PPBridge_ResetDevice(
- IN PPCI_CONFIGURATOR_CONTEXT Context
+ IN PPCI_PDO_EXTENSION PdoExtension,
+ IN PPCI_COMMON_HEADER PciData
);
VOID
NTAPI
PPBridge_ChangeResourceSettings(
- IN PPCI_CONFIGURATOR_CONTEXT Context
+ IN PPCI_PDO_EXTENSION PdoExtension,
+ IN PPCI_COMMON_HEADER PciData
);
//
VOID
NTAPI
-PPBridge_ResetDevice(IN PPCI_CONFIGURATOR_CONTEXT Context)
+PPBridge_ResetDevice(IN PPCI_PDO_EXTENSION PdoExtension,
+ IN PPCI_COMMON_HEADER PciData)
{
UNIMPLEMENTED;
while (TRUE);
VOID
NTAPI
-PPBridge_ChangeResourceSettings(IN PPCI_CONFIGURATOR_CONTEXT Context)
+PPBridge_ChangeResourceSettings(IN PPCI_PDO_EXTENSION PdoExtension,
+ IN PPCI_COMMON_HEADER PciData)
{
UNIMPLEMENTED;
while (TRUE);
IN PIO_STACK_LOCATION IoStackLocation,
IN PPCI_PDO_EXTENSION DeviceExtension)
{
- UNIMPLEMENTED;
- while (TRUE);
- return STATUS_NOT_SUPPORTED;
+ NTSTATUS Status;
+ BOOLEAN Changed, DoReset;
+ POWER_STATE PowerState;
+ PAGED_CODE();
+
+ DoReset = FALSE;
+
+ /* Begin entering the start phase */
+ Status = PciBeginStateTransition((PVOID)DeviceExtension, PciStarted);
+ if (!NT_SUCCESS(Status)) return Status;
+
+ /* Check if this is a VGA device */
+ if (((DeviceExtension->BaseClass == PCI_CLASS_PRE_20) &&
+ (DeviceExtension->SubClass == PCI_SUBCLASS_PRE_20_VGA)) ||
+ ((DeviceExtension->BaseClass == PCI_CLASS_DISPLAY_CTLR) &&
+ (DeviceExtension->SubClass == PCI_SUBCLASS_VID_VGA_CTLR)))
+ {
+ /* Always force it on */
+ DeviceExtension->CommandEnables |= (PCI_ENABLE_IO_SPACE |
+ PCI_ENABLE_MEMORY_SPACE);
+ }
+
+ /* Check if native IDE is enabled and it owns the I/O ports */
+ if (DeviceExtension->IoSpaceUnderNativeIdeControl)
+ {
+ /* Then don't allow I/O access */
+ DeviceExtension->CommandEnables &= ~PCI_ENABLE_IO_SPACE;
+ }
+
+ /* Always enable bus mastering */
+ DeviceExtension->CommandEnables |= PCI_ENABLE_BUS_MASTER;
+
+ /* Check if the OS assigned resources differ from the PCI configuration */
+ Changed = PciComputeNewCurrentSettings(DeviceExtension,
+ IoStackLocation->Parameters.
+ StartDevice.AllocatedResources);
+ if (Changed)
+ {
+ /* Remember this for later */
+ DeviceExtension->MovedDevice = TRUE;
+ }
+ else
+ {
+ /* All good */
+ DPRINT1("PCI - START not changing resource settings.\n");
+ }
+
+ /* Check if the device was sleeping */
+ if (DeviceExtension->PowerState.CurrentDeviceState != PowerDeviceD0)
+ {
+ /* Power it up */
+ Status = PciSetPowerManagedDevicePowerState(DeviceExtension,
+ PowerDeviceD0,
+ FALSE);
+ if (!NT_SUCCESS(Status))
+ {
+ /* Powerup fail, fail the request */
+ PciCancelStateTransition((PVOID)DeviceExtension, PciStarted);
+ return STATUS_DEVICE_POWER_FAILURE;
+ }
+
+ /* Tell the power manager that the device is powered up */
+ PowerState.DeviceState = PowerDeviceD0;
+ PoSetPowerState(DeviceExtension->PhysicalDeviceObject,
+ DevicePowerState,
+ PowerState);
+
+ /* Update internal state */
+ DeviceExtension->PowerState.CurrentDeviceState = PowerDeviceD0;
+
+ /* This device's resources and decodes will need to be reset */
+ DoReset = TRUE;
+ }
+
+ /* Update resource information now that the device is powered up and active */
+ Status = PciSetResources(DeviceExtension, DoReset, TRUE);
+ if (!NT_SUCCESS(Status))
+ {
+ /* That failed, so cancel the transition */
+ PciCancelStateTransition((PVOID)DeviceExtension, PciStarted);
+ }
+ else
+ {
+ /* Fully commit, as the device is now started up and ready to go */
+ PciCommitStateTransition((PVOID)DeviceExtension, PciStarted);
+ }
+
+ /* Return the result of the start request */
+ return Status;
}
NTSTATUS
if (!InterlockedDecrement(&Context->RunCount))
{
/* Nope, this is the first instance, so execute the IPI function */
- Context->Function(Context->PdoExtension, Context->Context);
+ Context->Function(Context->DeviceExtension, Context->Context);
/* Notify anyone that was spinning that they can stop now */
Context->Barrier = 0;
return Status;
}
+PCM_PARTIAL_RESOURCE_DESCRIPTOR
+NTAPI
+PciNextPartialDescriptor(PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDescriptor)
+{
+ PCM_PARTIAL_RESOURCE_DESCRIPTOR NextDescriptor;
+
+ /* Assume the descriptors are the fixed size ones */
+ NextDescriptor = CmDescriptor + 1;
+
+ /* But check if this is actually a variable-sized descriptor */
+ if (CmDescriptor->Type == CmResourceTypeDeviceSpecific)
+ {
+ /* Add the size of the variable section as well */
+ NextDescriptor = (PVOID)((ULONG_PTR)NextDescriptor +
+ CmDescriptor->u.DeviceSpecificData.DataSize);
+ }
+
+ /* Now the correct pointer has been computed, return it */
+ return NextDescriptor;
+}
+
/* EOF */
/* relative delays are negative, absolute are positive; resolution is 100ns */
Timeout.QuadPart = Int32x32To64(MillisecondsPeriod, -10000);
-
+
+ /* Lock the miniport block */
KeAcquireSpinLock(&Timer->Miniport->Lock, &OldIrql);
- /* If KeSetTimer(Ex) returns FALSE then the timer is not in the system's queue (and not in ours either) */
- if (!KeSetTimerEx(&Timer->Timer, Timeout, MillisecondsPeriod, &Timer->Dpc))
- {
- /* Add the timer at the head of the timer queue */
- Timer->NextDeferredTimer = Timer->Miniport->TimerQueue;
- Timer->Miniport->TimerQueue = Timer;
- }
+
+ /* Attempt to dequeue the timer */
+ DequeueMiniportTimer(Timer);
+
+ /* Add the timer at the head of the timer queue */
+ Timer->NextDeferredTimer = Timer->Miniport->TimerQueue;
+ Timer->Miniport->TimerQueue = Timer;
+
+ /* Unlock the miniport block */
KeReleaseSpinLock(&Timer->Miniport->Lock, OldIrql);
+
+ KeSetTimerEx(&Timer->Timer, Timeout, MillisecondsPeriod, &Timer->Dpc);
}
\f
/* relative delays are negative, absolute are positive; resolution is 100ns */
Timeout.QuadPart = Int32x32To64(MillisecondsToDelay, -10000);
+ /* Lock the miniport block */
KeAcquireSpinLock(&Timer->Miniport->Lock, &OldIrql);
- /* If KeSetTimer(Ex) returns FALSE then the timer is not in the system's queue (and not in ours either) */
- if (!KeSetTimer(&Timer->Timer, Timeout, &Timer->Dpc))
- {
- /* Add the timer at the head of the timer queue */
- Timer->NextDeferredTimer = Timer->Miniport->TimerQueue;
- Timer->Miniport->TimerQueue = Timer;
- }
+
+ /* Attempt to dequeue the timer */
+ DequeueMiniportTimer(Timer);
+
+ /* Add the timer at the head of the timer queue */
+ Timer->NextDeferredTimer = Timer->Miniport->TimerQueue;
+ Timer->Miniport->TimerQueue = Timer;
+
+ /* Unlock the miniport block */
KeReleaseSpinLock(&Timer->Miniport->Lock, OldIrql);
+
+ KeSetTimer(&Timer->Timer, Timeout, &Timer->Dpc);
}
\f
break;
case RequestTimerCall:
- DPRINT1("UNIMPLEMENTED SCSI Notification called: RequestTimerCall!\n");
+ DPRINT("Notify: RequestTimerCall\n");
+ DeviceExtension->InterruptData.Flags |= SCSI_PORT_TIMER_NEEDED;
+ DeviceExtension->InterruptData.HwScsiTimer = (PHW_TIMER)va_arg(ap, PHW_TIMER);
+ DeviceExtension->InterruptData.MiniportTimerValue = (ULONG)va_arg(ap, ULONG);
break;
case BusChangeDetected:
PSCSI_PORT_LUN_EXTENSION LunExtension;
BOOLEAN NeedToStartIo;
PSCSI_REQUEST_BLOCK_INFO SrbInfo;
+ LARGE_INTEGER TimerValue;
DPRINT("ScsiPortDpcForIsr(Dpc %p DpcDeviceObject %p DpcIrp %p DpcContext %p)\n",
Dpc, DpcDeviceObject, DpcIrp, DpcContext);
}
/* Check if timer is needed */
- if (InterruptData.Flags & SCIS_PORT_TIMER_NEEDED)
+ if (InterruptData.Flags & SCSI_PORT_TIMER_NEEDED)
{
- /* TODO: Implement */
- ASSERT(FALSE);
+ /* Save the timer routine */
+ DeviceExtension->HwScsiTimer = InterruptData.HwScsiTimer;
+
+ if (InterruptData.MiniportTimerValue == 0)
+ {
+ /* Cancel the timer */
+ KeCancelTimer(&DeviceExtension->MiniportTimer);
+ }
+ else
+ {
+ /* Convert timer value */
+ TimerValue.QuadPart = Int32x32To64(InterruptData.MiniportTimerValue, -10);
+
+ /* Set the timer */
+ KeSetTimer(&DeviceExtension->MiniportTimer,
+ TimerValue,
+ &DeviceExtension->MiniportTimerDpc);
+ }
}
/* If it's ready for the next request */
IN PVOID SystemArgument1,
IN PVOID SystemArgument2)
{
- DPRINT1("Miniport timer DPC\n");
- ASSERT(FALSE);
+ PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
+
+ DPRINT("Miniport timer DPC\n");
+
+ DeviceExtension = ((PDEVICE_OBJECT)DeviceObject)->DeviceExtension;
+
+ /* Acquire the spinlock */
+ KeAcquireSpinLockAtDpcLevel(&DeviceExtension->SpinLock);
+
+ /* Call the timer routine */
+ if (DeviceExtension->HwScsiTimer != NULL)
+ {
+ DeviceExtension->HwScsiTimer(&DeviceExtension->MiniPortDeviceExtension);
+ }
+
+ /* Release the spinlock */
+ KeReleaseSpinLockFromDpcLevel(&DeviceExtension->SpinLock);
+
+ if (DeviceExtension->InterruptData.Flags & SCSI_PORT_NOTIFICATION_NEEDED)
+ {
+ ScsiPortDpcForIsr(NULL,
+ DeviceExtension->DeviceObject,
+ NULL,
+ NULL);
+ }
}
static NTSTATUS
#define SCSI_PORT_DISABLE_INT_REQUESET 0x2000
#define SCSI_PORT_DISABLE_INTERRUPTS 0x4000
#define SCSI_PORT_ENABLE_INT_REQUEST 0x8000
-#define SCIS_PORT_TIMER_NEEDED 0x10000
+#define SCSI_PORT_TIMER_NEEDED 0x10000
/* LUN Extension flags*/
#define LUNEX_FROZEN_QUEUE 0x0001
PSCSI_REQUEST_BLOCK_INFO CompletedRequests; /* Linked list of Srb info data */
PSCSI_PORT_LUN_EXTENSION CompletedAbort;
PSCSI_PORT_LUN_EXTENSION ReadyLun;
+ PHW_TIMER HwScsiTimer;
+ ULONG MiniportTimerValue;
} SCSI_PORT_INTERRUPT_DATA, *PSCSI_PORT_INTERRUPT_DATA;
PHW_INTERRUPT HwInterrupt;
PHW_RESET_BUS HwResetBus;
PHW_DMA_STARTED HwDmaStarted;
+ PHW_TIMER HwScsiTimer;
PSCSI_REQUEST_BLOCK OriginalSrb;
SCSI_REQUEST_BLOCK InternalSrb;
* FILE: drivers/usb/usbehci/common.c
* PURPOSE: Common operations in FDO/PDO.
* PROGRAMMERS:
- * Michael Martin (mjmartin@reactos.org)
+ * Michael Martin (michael.martin@reactos.org)
*/
#define INITGUID
* FILE: drivers/usb/usbehci/fdo.c
* PURPOSE: USB EHCI device driver.
* PROGRAMMERS:
- * Michael Martin (mjmartin@reactos.org)
+ * Michael Martin (michael.martin@reactos.org)
*/
/* INCLUDES *******************************************************************/
#include "usbehci.h"
#include <stdio.h>
+VOID NTAPI
+TimerDefferedRoutine(PKDPC Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2)
+{
+ PFDO_DEVICE_EXTENSION FdoDeviceExtension;
+ PPDO_DEVICE_EXTENSION PdoDeviceExtension;
+ ULONG tmp;
+ ULONG Base;
+ LONG i;
+
+ FdoDeviceExtension = (PFDO_DEVICE_EXTENSION) DeferredContext;
+ PdoDeviceExtension = (PPDO_DEVICE_EXTENSION) FdoDeviceExtension->Pdo->DeviceExtension;
+
+ Base = (ULONG)FdoDeviceExtension->ResourceMemory;
+
+ for (i = 0; i < FdoDeviceExtension->ECHICaps.HCSParams.PortCount; i++)
+ {
+ tmp = READ_REGISTER_ULONG((PULONG) ((Base + EHCI_PORTSC) + (4 * i)));
+
+ if ((tmp & 0x04) && (!(PdoDeviceExtension->Ports[i].PortChange & USB_PORT_STATUS_RESET)))
+ {
+ DPRINT("Port %x is enabled\n", i);
+ PdoDeviceExtension->Ports[i].PortChange |= USB_PORT_STATUS_RESET;
+ CompletePendingURBRequest(PdoDeviceExtension);
+ }
+ }
+ return;
+}
+
VOID NTAPI
EhciDefferedRoutine(PKDPC Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2)
{
PFDO_DEVICE_EXTENSION FdoDeviceExtension;
PPDO_DEVICE_EXTENSION PdoDeviceExtension;
ULONG CStatus;
+ ULONG tmp;
+ ULONG Base;
+ LONG i;
FdoDeviceExtension = (PFDO_DEVICE_EXTENSION) DeferredContext;
+
+ if (!FdoDeviceExtension->Pdo)
+ {
+ DPRINT1("PDO not set yet!\n");
+ return;
+ }
+
PdoDeviceExtension = (PPDO_DEVICE_EXTENSION) FdoDeviceExtension->Pdo->DeviceExtension;
+ Base = (ULONG)FdoDeviceExtension->ResourceMemory;
+
CStatus = (ULONG) SystemArgument2;
/* Port Change */
if (CStatus & EHCI_STS_PCD)
{
- LONG i;
- ULONG tmp;
- ULONG Base;
-
- Base = (ULONG)FdoDeviceExtension->ResourceMemory;
-
/* Loop through the ports */
for (i = 0; i < FdoDeviceExtension->ECHICaps.HCSParams.PortCount; i++)
{
KeStallExecutionProcessor(30);
/* As per USB 2.0 Specs, 9.1.2. Reset the port and clear the status change */
- tmp |= 0x100 | 0x02;
+ //tmp |= 0x100 | 0x02;
/* Sanity, Disable port */
- tmp &= ~0x04;
+ //tmp &= ~0x04;
- WRITE_REGISTER_ULONG((PULONG) ((Base + EHCI_PORTSC) + (4 * i)), tmp);
+ //WRITE_REGISTER_ULONG((PULONG) ((Base + EHCI_PORTSC) + (4 * i)), tmp);
- KeStallExecutionProcessor(20);
+ //KeStallExecutionProcessor(20);
tmp = READ_REGISTER_ULONG((PULONG)((Base + EHCI_PORTSC) + (4 * i)));
PdoDeviceExtension->ChildDeviceCount++;
- PdoDeviceExtension->Ports[i].PortStatus |= USB_PORT_STATUS_HIGH_SPEED | USB_PORT_STATUS_CONNECT;
+ PdoDeviceExtension->Ports[i].PortStatus &= ~0x8000;
+ PdoDeviceExtension->Ports[i].PortStatus |= USB_PORT_STATUS_CONNECT;
PdoDeviceExtension->Ports[i].PortChange |= USB_PORT_STATUS_CONNECT;
- PdoDeviceExtension->HaltQueue = FALSE;
- KeSetEvent(&PdoDeviceExtension->QueueDrainedEvent, 0, FALSE);
+ CompletePendingURBRequest(PdoDeviceExtension);
}
else
{
}
BOOLEAN
-ResetPort(PDEVICE_OBJECT DeviceObject)
+ResetPort(PFDO_DEVICE_EXTENSION FdoDeviceExtension, UCHAR Port)
{
- /*FIXME: Implement me */
+ ULONG Base;
+ ULONG tmp;
+ LARGE_INTEGER DueTime;
+
+ DPRINT("Reset Port %x\n", Port);
+
+ Base = (ULONG)FdoDeviceExtension->ResourceMemory;
+ tmp = READ_REGISTER_ULONG((PULONG) ((Base + EHCI_PORTSC) + (4 * Port)));
+ tmp |= 0x100;
+ WRITE_REGISTER_ULONG((PULONG) ((Base + EHCI_PORTSC) + (4 * Port)), tmp);
+
+ DueTime.QuadPart = -100;
+
+ KeSetTimerEx(&FdoDeviceExtension->UpdateTimer, DueTime, 0, &FdoDeviceExtension->TimerDpcObject);
return TRUE;
}
ULONG base;
LONG tmp;
- DPRINT1("Stopping Ehci controller\n");
+ DPRINT("Stopping Ehci controller\n");
FdoDeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
base = (ULONG)FdoDeviceExtension->ResourceMemory;
LONG tmp2;
ULONG base;
- DPRINT1("Starting Ehci controller\n");
+ DPRINT("Starting Ehci controller\n");
FdoDeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
base = (ULONG)FdoDeviceExtension->ResourceMemory;
EhciDefferedRoutine,
FdoDeviceExtension);
+ KeInitializeDpc(&FdoDeviceExtension->TimerDpcObject,
+ TimerDefferedRoutine,
+ FdoDeviceExtension);
+
+
Status = IoConnectInterrupt(&FdoDeviceExtension->EhciInterrupt,
InterruptService,
FdoDeviceExtension->DeviceObject,
PHCS = (PEHCI_HCS_CONTENT)&DeviceExtension->ECHICaps.HCSParams;
if (PHCS->PortRouteRules)
{
- for (i = 0; i < 8; i++)
+ for (i = 0; i < PCap->HCSParams.PortCount; i++)
{
PCap->PortRoute[i] = READ_REGISTER_UCHAR((PUCHAR) (Base + 12 + i));
}
/* Zeroize it */
RtlZeroMemory(FdoDeviceExtension->PeriodicFramList, sizeof(ULONG) * 1024);
+ ExInitializeFastMutex(&FdoDeviceExtension->FrameListMutex);
+
/* Allocate Common Buffer for Async List Head Queue */
FdoDeviceExtension->AsyncListQueueHeadPtr =
FdoDeviceExtension->pDmaAdapter->DmaOperations->AllocateCommonBuffer(FdoDeviceExtension->pDmaAdapter,
/* FIXME: Same as FIXME above */
20800);
+ ExInitializeFastMutex(&FdoDeviceExtension->AsyncListMutex);
+
Status = IoGetDeviceProperty(FdoDeviceExtension->LowerDevice,
DevicePropertyAddress,
sizeof(ULONG),
DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+ DPRINT1("Ehci: QueryBusRelations\n");
+
/* Create the PDO with the next available number */
while (TRUE)
{
PdoDeviceExtension->ControllerFdo = DeviceObject;
PdoDeviceExtension->DeviceObject = Pdo;
+ PdoDeviceExtension->NumberOfPorts = DeviceExtension->ECHICaps.HCSParams.PortCount;
InitializeListHead(&PdoDeviceExtension->IrpQueue);
KeInitializeSpinLock(&PdoDeviceExtension->IrpQueueLock);
{
case IRP_MN_START_DEVICE:
{
- DPRINT1("START_DEVICE\n");
+ DPRINT1("Ehci: START_DEVICE\n");
Irp->IoStatus.Status = STATUS_SUCCESS;
Status = ForwardAndWait(DeviceObject, Irp);
}
case IRP_MN_QUERY_DEVICE_RELATIONS:
{
- DPRINT1("IRP_MN_QUERY_DEVICE_RELATIONS\n");
+ DPRINT1("Ehci: IRP_MN_QUERY_DEVICE_RELATIONS\n");
switch(Stack->Parameters.QueryDeviceRelations.Type)
{
case BusRelations:
{
PDEVICE_RELATIONS DeviceRelations = NULL;
- DPRINT("BusRelations\n");
+ DPRINT1("Ehci: BusRelations\n");
Status = FdoQueryBusRelations(DeviceObject, &DeviceRelations);
Information = (ULONG_PTR)DeviceRelations;
break;
}
default:
{
- DPRINT("Unknown query device relations type\n");
+ DPRINT1("Ehci: Unknown query device relations type\n");
Status = STATUS_NOT_IMPLEMENTED;
break;
}
}
case IRP_MN_FILTER_RESOURCE_REQUIREMENTS:
{
- DPRINT("IRP_MN_FILTER_RESOURCE_REQUIREMENTS\n");
+ DPRINT1("Ehci: IRP_MN_FILTER_RESOURCE_REQUIREMENTS\n");
return ForwardIrpAndForget(DeviceObject, Irp);
break;
}
case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
{
- DPRINT("IRP_MN_QUERY_RESOURCE_REQUIREMENTS\n");
+ DPRINT1("Ehci: IRP_MN_QUERY_RESOURCE_REQUIREMENTS\n");
}
case IRP_MN_QUERY_INTERFACE:
{
+ DPRINT1("Ehci: IRP_MN_QUERY_INTERFACE\n");
Status = STATUS_SUCCESS;
Information = 0;
Status = ForwardIrpAndForget(DeviceObject, Irp);
}
default:
{
- DPRINT1("IRP_MJ_PNP / Unhandled minor function 0x%lx\n", Stack->MinorFunction);
+ DPRINT1("Ehci: IRP_MJ_PNP / Unhandled minor function 0x%lx\n", Stack->MinorFunction);
return ForwardIrpAndForget(DeviceObject, Irp);
}
}
PFDO_DEVICE_EXTENSION FdoDeviceExtension;
- DPRINT("Ehci AddDevice\n");
+ DPRINT1("Ehci: AddDevice\n");
/* Create the FDO with next available number */
while (TRUE)
FdoDeviceExtension = (PFDO_DEVICE_EXTENSION) Fdo->DeviceExtension;
RtlZeroMemory(FdoDeviceExtension, sizeof(PFDO_DEVICE_EXTENSION));
+ KeInitializeTimerEx(&FdoDeviceExtension->UpdateTimer, SynchronizationTimer);
+
FdoDeviceExtension->Common.IsFdo = TRUE;
FdoDeviceExtension->DeviceObject = Fdo;
if (!NT_SUCCESS(Status))
{
DPRINT1("Unable to register device interface!\n");
- ASSERT(FALSE);
+ return Status;
}
else
{
Status = IoSetDeviceInterfaceState(&InterfaceSymLinkName, TRUE);
DPRINT1("SetInterfaceState %x\n", Status);
if (!NT_SUCCESS(Status))
- ASSERT(FALSE);
+ return Status;
}
Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
FdoDispatchInternalDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
PFDO_DEVICE_EXTENSION FdoDeviceExtension;
+ PPDO_DEVICE_EXTENSION PdoDeviceExtension;
PIO_STACK_LOCATION Stack = NULL;
NTSTATUS Status = STATUS_UNSUCCESSFUL;
ULONG_PTR Information = 0;
PUSB_DEVICE UsbDevice = NULL;
URB *Urb;
+ /*FIXME: This should never be called by a miniport as the miniport should only be dealing with the pdo */
+
FdoDeviceExtension = (PFDO_DEVICE_EXTENSION) DeviceObject->DeviceExtension;
+ PdoDeviceExtension = (PPDO_DEVICE_EXTENSION) FdoDeviceExtension->Pdo->DeviceExtension;
ASSERT(FdoDeviceExtension->Common.IsFdo == TRUE);
DPRINT("Header Length %d\n", Urb->UrbHeader.Length);
DPRINT("Header Function %d\n", Urb->UrbHeader.Function);
- UsbDevice = Urb->UrbHeader.UsbdDeviceHandle;
+ UsbDevice = DeviceHandleToUsbDevice(PdoDeviceExtension, Urb->UrbHeader.UsbdDeviceHandle);
+ if (!UsbDevice)
+ {
+ DPRINT1("Invalid DeviceHandle or device not connected\n");
+ return STATUS_DEVICE_NOT_CONNECTED;
+ }
switch (Urb->UrbHeader.Function)
{
case URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:
{
- DPRINT1("URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:\n");
+ DPRINT1("Ehci: URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:\n");
break;
}
case URB_FUNCTION_GET_STATUS_FROM_DEVICE:
{
- DPRINT1("URB_FUNCTION_GET_STATUS_FROM_DEVICE\n");
+ DPRINT1("Ehci: URB_FUNCTION_GET_STATUS_FROM_DEVICE\n");
break;
}
case URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE:
{
+ DPRINT1("Ehci: URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE\n");
switch(Urb->UrbControlDescriptorRequest.DescriptorType)
{
case USB_DEVICE_DESCRIPTOR_TYPE:
{
- /* FIXNME: This probably not used for FDO and should be removed? */
+ /* FIXME: This probably not used for FDO and should be removed? */
DPRINT1("USB DEVICE DESC\n");
break;
}
case USB_CONFIGURATION_DESCRIPTOR_TYPE:
DPRINT1("USB CONFIG DESC\n");
+ //break;
case USB_STRING_DESCRIPTOR_TYPE:
DPRINT1("Usb String Descriptor\n");
{
USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup;
+ PUSB_STRING_DESCRIPTOR UsbString;
BOOLEAN ResultOk;
CtrlSetup.bmRequestType._BM.Recipient = BMREQUEST_TO_DEVICE;
CtrlSetup.bmRequestType._BM.Type = BMREQUEST_STANDARD;
+ CtrlSetup.bmRequestType._BM.Reserved = 0;
CtrlSetup.bmRequestType._BM.Dir = BMREQUEST_DEVICE_TO_HOST;
CtrlSetup.bRequest = USB_REQUEST_GET_DESCRIPTOR;
CtrlSetup.wValue.LowByte = Urb->UrbControlDescriptorRequest.Index;
CtrlSetup.wValue.HiByte = Urb->UrbControlDescriptorRequest.DescriptorType;
+
if (Urb->UrbControlDescriptorRequest.DescriptorType == USB_STRING_DESCRIPTOR_TYPE)
+ {
CtrlSetup.wIndex.W = Urb->UrbControlDescriptorRequest.LanguageId;
+ RtlZeroMemory(Urb->UrbControlDescriptorRequest.TransferBuffer, Urb->UrbControlDescriptorRequest.TransferBufferLength-1);
+ }
else
CtrlSetup.wIndex.W = 0;
+
CtrlSetup.wLength = Urb->UrbControlDescriptorRequest.TransferBufferLength;
ResultOk = ExecuteControlRequest(FdoDeviceExtension, &CtrlSetup, UsbDevice->Address, UsbDevice->Port,
Urb->UrbControlDescriptorRequest.TransferBuffer, Urb->UrbControlDescriptorRequest.TransferBufferLength);
+ if (Urb->UrbControlDescriptorRequest.DescriptorType == USB_STRING_DESCRIPTOR_TYPE)
+ {
+ UsbString = Urb->UrbControlDescriptorRequest.TransferBuffer;
+ DPRINT1("Index %x\n", Urb->UrbControlDescriptorRequest.Index);
+ DPRINT1("BufferLength %x\n", Urb->UrbControlDescriptorRequest.TransferBufferLength);
+ DPRINT1("Length %x\n", UsbString->bLength);
+ if (Urb->UrbControlDescriptorRequest.Index == 0)
+ {
+ DPRINT1("%x\n", (ULONG)Urb->UrbControlDescriptorRequest.TransferBuffer);
+ }
+ else
+ DPRINT1("String %S\n", &UsbString->bString);
+ }
+ UsbString = Urb->UrbControlDescriptorRequest.TransferBuffer;
Urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
Status = STATUS_SUCCESS;
-
+ Information = UsbString->bLength;
break;
}
default:
}
case URB_FUNCTION_SELECT_CONFIGURATION:
{
- DPRINT1("Selecting Configuration\n");
+ DPRINT1("Ehci: URB_FUNCTION_SELECT_CONFIGURATION\n");
DPRINT1("Urb->UrbSelectConfiguration.ConfigurationHandle %x\n",Urb->UrbSelectConfiguration.ConfigurationHandle);
break;
}
case URB_FUNCTION_CLASS_DEVICE:
{
+ DPRINT1("Ehci: URB_FUNCTION_CLASS_DEVICE %x\n",Urb->UrbControlVendorClassRequest.Request);
switch (Urb->UrbControlVendorClassRequest.Request)
{
case USB_REQUEST_GET_DESCRIPTOR:
}
case URB_FUNCTION_CLASS_OTHER:
{
+ DPRINT1("Ehci: URB_FUNCTION_CLASS_OTHER\n");
switch (Urb->UrbControlVendorClassRequest.Request)
{
case USB_REQUEST_GET_STATUS:
}
default:
{
- DPRINT1("Unhandled URB %x\n", Urb->UrbHeader.Function);
+ DPRINT1("Ehci: Unhandled URB %x\n", Urb->UrbHeader.Function);
//Urb->UrbHeader.Status = USBD_STATUS_INVALID_URB_FUNCTION;
}
}
* FILE: drivers/usb/usbehci/irp.c
* PURPOSE: IRP Handling.
* PROGRAMMERS:
- * Michael Martin
+ * Michael Martin (michael.martin@reactos.org)
*/
#include "usbehci.h"
VOID
-RequestURBCancel (PDEVICE_OBJECT DeviceObject, PIRP Irp)
+RemoveUrbRequest(PPDO_DEVICE_EXTENSION DeviceExtension, PIRP Irp)
{
- PPDO_DEVICE_EXTENSION PdoDeviceExtension;
-
- PdoDeviceExtension = (PPDO_DEVICE_EXTENSION) DeviceObject->DeviceExtension;
+ KIRQL OldIrql;
+ KeAcquireSpinLock(&DeviceExtension->IrpQueueLock, &OldIrql);
+ RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
+ KeReleaseSpinLock(&DeviceExtension->IrpQueueLock, OldIrql);
+}
+VOID
+RequestURBCancel (PPDO_DEVICE_EXTENSION PdoDeviceExtension, PIRP Irp)
+{
KIRQL OldIrql = Irp->CancelIrql;
IoReleaseCancelSpinLock(DISPATCH_LEVEL);
}
}
-VOID
-CompletePendingURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension)
+NTSTATUS HandleUrbRequest(PPDO_DEVICE_EXTENSION PdoDeviceExtension, PIRP Irp)
{
- PLIST_ENTRY NextIrp = NULL;
NTSTATUS Status = STATUS_UNSUCCESSFUL;
ULONG_PTR Information = 0;
PIO_STACK_LOCATION Stack;
PUSB_DEVICE UsbDevice = NULL;
- KIRQL oldIrql;
- PIRP Irp = NULL;
URB *Urb;
+ PFDO_DEVICE_EXTENSION FdoDeviceExtension;
+ FdoDeviceExtension = (PFDO_DEVICE_EXTENSION) PdoDeviceExtension->ControllerFdo->DeviceExtension;
- KeAcquireSpinLock(&DeviceExtension->IrpQueueLock, &oldIrql);
+ Stack = IoGetCurrentIrpStackLocation(Irp);
+ ASSERT(Stack);
- while (!IsListEmpty(&DeviceExtension->IrpQueue))
- {
- NextIrp = RemoveHeadList(&DeviceExtension->IrpQueue);
- Irp = CONTAINING_RECORD(NextIrp, IRP, Tail.Overlay.ListEntry);
+ Urb = (PURB) Stack->Parameters.Others.Argument1;
- if (!Irp)
- break;
- Stack = IoGetCurrentIrpStackLocation(Irp);
- ASSERT(Stack);
-
- Urb = (PURB) Stack->Parameters.Others.Argument1;
+ ASSERT(Urb);
- ASSERT(Urb);
+ Information = 0;
+ Status = STATUS_SUCCESS;
- Information = 0;
- Status = STATUS_SUCCESS;
+ DPRINT("TransferBuffer %x\n", Urb->UrbControlDescriptorRequest.TransferBuffer);
+ DPRINT("TransferBufferLength %x\n", Urb->UrbControlDescriptorRequest.TransferBufferLength);
+ DPRINT("UsbdDeviceHandle = %x\n", Urb->UrbHeader.UsbdDeviceHandle);
- DPRINT("TransferBuffer %x\n", Urb->UrbControlDescriptorRequest.TransferBuffer);
- DPRINT("TransferBufferLength %x\n", Urb->UrbControlDescriptorRequest.TransferBufferLength);
- DPRINT("UsbdDeviceHandle = %x\n", Urb->UrbHeader.UsbdDeviceHandle);
+ UsbDevice = Urb->UrbHeader.UsbdDeviceHandle;
- UsbDevice = Urb->UrbHeader.UsbdDeviceHandle;
- /* UsbdDeviceHandle of 0 is root hub */
- if (UsbDevice == NULL)
- UsbDevice = DeviceExtension->UsbDevices[0];
+ /* UsbdDeviceHandle of 0 is root hub */
+ if (UsbDevice == NULL)
+ UsbDevice = PdoDeviceExtension->UsbDevices[0];
- /* Assume URB success */
- Urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
- /* Set the DeviceHandle to the Internal Device */
- Urb->UrbHeader.UsbdDeviceHandle = UsbDevice;
+ /* Assume URB success */
+ Urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
+ /* Set the DeviceHandle to the Internal Device */
+ Urb->UrbHeader.UsbdDeviceHandle = UsbDevice;
- switch (Urb->UrbHeader.Function)
+ switch (Urb->UrbHeader.Function)
+ {
+ case URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:
{
- case URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:
+ if (&UsbDevice->ActiveInterface->EndPoints[0]->EndPointDescriptor != Urb->UrbBulkOrInterruptTransfer.PipeHandle)
{
- DPRINT("URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:\n");
- DPRINT("--->TransferBufferLength %x\n",Urb->UrbBulkOrInterruptTransfer.TransferBufferLength);
- DPRINT("--->TransferBuffer %x\n",Urb->UrbBulkOrInterruptTransfer.TransferBuffer);
- DPRINT("--->PipeHandle %x\n",Urb->UrbBulkOrInterruptTransfer.PipeHandle);
- DPRINT("---->(PVOID)&UsbDevice->EndPointDescriptor %x\n", (PVOID)&UsbDevice->ActiveInterface->EndPoints[0]->EndPointDescriptor);
- DPRINT("--->TransferFlags %x\n", Urb->UrbBulkOrInterruptTransfer.TransferFlags);
- ASSERT(Urb->UrbBulkOrInterruptTransfer.TransferBuffer != NULL);
- RtlZeroMemory(Urb->UrbBulkOrInterruptTransfer.TransferBuffer, Urb->UrbBulkOrInterruptTransfer.TransferBufferLength);
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ ASSERT(Urb->UrbBulkOrInterruptTransfer.TransferBuffer != NULL);
+ RtlZeroMemory(Urb->UrbBulkOrInterruptTransfer.TransferBuffer, Urb->UrbBulkOrInterruptTransfer.TransferBufferLength);
- if (UsbDevice == DeviceExtension->UsbDevices[0])
+ if (UsbDevice == PdoDeviceExtension->UsbDevices[0])
+ {
+ if (Urb->UrbBulkOrInterruptTransfer.TransferFlags & (USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK))
{
- if (Urb->UrbBulkOrInterruptTransfer.TransferFlags & (USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK))
+ LONG i;
+ for (i = 0; i < PdoDeviceExtension->NumberOfPorts; i++)
{
- LONG i;
- for (i = 0; i < 8; i++)
+ if (PdoDeviceExtension->Ports[i].PortChange)
{
- if (i == 0){
- DPRINT("PortStatus %x\n", DeviceExtension->Ports[i].PortStatus);
- DPRINT("PortChange %x\n", DeviceExtension->Ports[i].PortChange);}
- if (DeviceExtension->Ports[i].PortChange)
- {
- DPRINT1("Inform hub driver that port %d has changed\n", i+1);
- ((PUCHAR)Urb->UrbBulkOrInterruptTransfer.TransferBuffer)[0] = 1 << ((i + 1) & 7);
- }
+ DPRINT1("Inform hub driver that port %d has changed\n", i+1);
+ ((PUCHAR)Urb->UrbBulkOrInterruptTransfer.TransferBuffer)[0] = 1 << ((i + 1) & 7);
}
}
- else
- {
- Urb->UrbHeader.Status = USBD_STATUS_INVALID_PARAMETER;
- Status = STATUS_UNSUCCESSFUL;
- DPRINT1("Invalid transfer flags for SCE\n");
- }
}
else
- DPRINT1("Interrupt Transfer not for hub\n");
- break;
- }
- case URB_FUNCTION_GET_STATUS_FROM_DEVICE:
- {
- DPRINT("Get Status from Device\n");
- DPRINT("Index : %d\n", Urb->UrbControlGetStatusRequest.Index);
-
- if (Urb->UrbControlGetStatusRequest.Index == 0)
{
- ASSERT(Urb->UrbBulkOrInterruptTransfer.TransferBuffer != NULL);
- *(PUSHORT)Urb->UrbControlGetStatusRequest.TransferBuffer = USB_PORT_STATUS_CONNECT | USB_PORT_STATUS_ENABLE;
- }
- else
- {
- DPRINT1("Uknown identifier\n");
- Urb->UrbHeader.Status = USBD_STATUS_INVALID_URB_FUNCTION;
+ Urb->UrbHeader.Status = USBD_STATUS_INVALID_PARAMETER;
Status = STATUS_UNSUCCESSFUL;
+ DPRINT1("Invalid transfer flags for SCE\n");
}
- break;
}
- case URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE:
+ else
+ DPRINT("Interrupt Transfer not for hub\n");
+ break;
+ }
+ case URB_FUNCTION_GET_STATUS_FROM_DEVICE:
+ {
+ if (Urb->UrbControlGetStatusRequest.Index == 0)
+ {
+ ASSERT(Urb->UrbBulkOrInterruptTransfer.TransferBuffer != NULL);
+ *(PUSHORT)Urb->UrbControlGetStatusRequest.TransferBuffer = USB_PORT_STATUS_CONNECT | USB_PORT_STATUS_ENABLE;
+ }
+ else
+ {
+ DPRINT1("Uknown identifier\n");
+ Urb->UrbHeader.Status = USBD_STATUS_INVALID_URB_FUNCTION;
+ Status = STATUS_UNSUCCESSFUL;
+ }
+ break;
+ }
+ case URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE:
+ {
+ switch(Urb->UrbControlDescriptorRequest.DescriptorType)
{
- switch(Urb->UrbControlDescriptorRequest.DescriptorType)
+ case USB_DEVICE_DESCRIPTOR_TYPE:
{
- case USB_DEVICE_DESCRIPTOR_TYPE:
+ if (Urb->UrbControlDescriptorRequest.TransferBufferLength >= sizeof(USB_DEVICE_DESCRIPTOR))
{
- DPRINT1("USB DEVICE DESC\n");
- if (Urb->UrbControlDescriptorRequest.TransferBufferLength >= sizeof(USB_DEVICE_DESCRIPTOR))
- {
- Urb->UrbControlDescriptorRequest.TransferBufferLength = sizeof(USB_DEVICE_DESCRIPTOR);
- }
- ASSERT(Urb->UrbControlDescriptorRequest.TransferBuffer != NULL);
- RtlCopyMemory(Urb->UrbControlDescriptorRequest.TransferBuffer,
- &UsbDevice->DeviceDescriptor,
- Urb->UrbControlDescriptorRequest.TransferBufferLength);
- break;
+ Urb->UrbControlDescriptorRequest.TransferBufferLength = sizeof(USB_DEVICE_DESCRIPTOR);
}
- case USB_CONFIGURATION_DESCRIPTOR_TYPE:
- {
- PUCHAR BufPtr;
- LONG i, j;
-
- DPRINT1("USB CONFIG DESC\n");
+ ASSERT(Urb->UrbControlDescriptorRequest.TransferBuffer != NULL);
+ RtlCopyMemory(Urb->UrbControlDescriptorRequest.TransferBuffer,
+ &UsbDevice->DeviceDescriptor,
+ Urb->UrbControlDescriptorRequest.TransferBufferLength);
+ break;
+ }
+ case USB_CONFIGURATION_DESCRIPTOR_TYPE:
+ {
+ PUCHAR BufPtr;
+ LONG i, j;
- if (Urb->UrbControlDescriptorRequest.TransferBufferLength >= UsbDevice->ActiveConfig->ConfigurationDescriptor.wTotalLength)
- {
- Urb->UrbControlDescriptorRequest.TransferBufferLength = UsbDevice->ActiveConfig->ConfigurationDescriptor.wTotalLength;
- }
- else
+ if (Urb->UrbControlDescriptorRequest.TransferBufferLength >= UsbDevice->ActiveConfig->ConfigurationDescriptor.wTotalLength)
+ {
+ Urb->UrbControlDescriptorRequest.TransferBufferLength = UsbDevice->ActiveConfig->ConfigurationDescriptor.wTotalLength;
+ }
+ else
+ {
+ DPRINT1("TransferBufferLenth %x is too small!!!\n", Urb->UrbControlDescriptorRequest.TransferBufferLength);
+ if (Urb->UrbControlDescriptorRequest.TransferBufferLength < sizeof(USB_CONFIGURATION_DESCRIPTOR))
{
- DPRINT1("Buffer to small!!!\n");
- //ASSERT(FALSE);
+ DPRINT("Configuration Descriptor cannot fit into given buffer!\n");
+ break;
}
+ }
- ASSERT(Urb->UrbControlDescriptorRequest.TransferBuffer);
- BufPtr = (PUCHAR)Urb->UrbControlDescriptorRequest.TransferBuffer;
+ ASSERT(Urb->UrbControlDescriptorRequest.TransferBuffer);
+ BufPtr = (PUCHAR)Urb->UrbControlDescriptorRequest.TransferBuffer;
- /* Copy the Configuration Descriptor */
- RtlCopyMemory(BufPtr, &UsbDevice->ActiveConfig->ConfigurationDescriptor, sizeof(USB_CONFIGURATION_DESCRIPTOR));
- BufPtr += sizeof(USB_CONFIGURATION_DESCRIPTOR);
- for (i = 0; i < UsbDevice->ActiveConfig->ConfigurationDescriptor.bNumInterfaces; i++)
- {
- /* Copy the Interface Descriptor */
- RtlCopyMemory(BufPtr, &UsbDevice->ActiveConfig->Interfaces[i]->InterfaceDescriptor, sizeof(USB_INTERFACE_DESCRIPTOR));
- BufPtr += sizeof(USB_INTERFACE_DESCRIPTOR);
- for (j = 0; j < UsbDevice->ActiveConfig->Interfaces[i]->InterfaceDescriptor.bNumEndpoints; j++)
- {
- /* Copy the EndPoint Descriptor */
- RtlCopyMemory(BufPtr, &UsbDevice->ActiveConfig->Interfaces[i]->EndPoints[j]->EndPointDescriptor, sizeof(USB_ENDPOINT_DESCRIPTOR));
- BufPtr += sizeof(USB_ENDPOINT_DESCRIPTOR);
- }
- }
+ /* Copy the Configuration Descriptor */
+ RtlCopyMemory(BufPtr, &UsbDevice->ActiveConfig->ConfigurationDescriptor, sizeof(USB_CONFIGURATION_DESCRIPTOR));
- break;
- }
- case USB_STRING_DESCRIPTOR_TYPE:
+ /* If there is no room for all the configs then bail */
+ if (!(Urb->UrbControlDescriptorRequest.TransferBufferLength > sizeof(USB_CONFIGURATION_DESCRIPTOR)))
{
- DPRINT1("Usb String Descriptor not implemented\n");
+ DPRINT("All Descriptors cannot fit into given buffer! Only USB_CONFIGURATION_DESCRIPTOR given\n");
break;
}
- default:
+
+ BufPtr += sizeof(USB_CONFIGURATION_DESCRIPTOR);
+ for (i = 0; i < UsbDevice->ActiveConfig->ConfigurationDescriptor.bNumInterfaces; i++)
{
- DPRINT1("Descriptor Type %x not supported!\n", Urb->UrbControlDescriptorRequest.DescriptorType);
+ /* Copy the Interface Descriptor */
+ RtlCopyMemory(BufPtr, &UsbDevice->ActiveConfig->Interfaces[i]->InterfaceDescriptor, sizeof(USB_INTERFACE_DESCRIPTOR));
+ BufPtr += sizeof(USB_INTERFACE_DESCRIPTOR);
+ for (j = 0; j < UsbDevice->ActiveConfig->Interfaces[i]->InterfaceDescriptor.bNumEndpoints; j++)
+ {
+ /* Copy the EndPoint Descriptor */
+ RtlCopyMemory(BufPtr, &UsbDevice->ActiveConfig->Interfaces[i]->EndPoints[j]->EndPointDescriptor, sizeof(USB_ENDPOINT_DESCRIPTOR));
+ BufPtr += sizeof(USB_ENDPOINT_DESCRIPTOR);
+ }
}
+
+ break;
+ }
+ case USB_STRING_DESCRIPTOR_TYPE:
+ {
+ USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup;
+ PUSB_STRING_DESCRIPTOR StringDesc;
+ BOOLEAN ResultOk;
+
+ StringDesc = (PUSB_STRING_DESCRIPTOR) Urb->UrbControlDescriptorRequest.TransferBuffer;
+
+ if (Urb->UrbControlDescriptorRequest.Index == 0)
+ DPRINT("Requesting LANGID's\n");
+
+
+ RtlZeroMemory(Urb->UrbControlDescriptorRequest.TransferBuffer, Urb->UrbControlDescriptorRequest.TransferBufferLength-1);
+
+ CtrlSetup.bmRequestType._BM.Recipient = BMREQUEST_TO_DEVICE;
+ CtrlSetup.bmRequestType._BM.Type = BMREQUEST_STANDARD;
+ CtrlSetup.bmRequestType._BM.Reserved = 0;
+ CtrlSetup.bmRequestType._BM.Dir = BMREQUEST_DEVICE_TO_HOST;
+ CtrlSetup.bRequest = USB_REQUEST_GET_DESCRIPTOR;
+ CtrlSetup.wValue.LowByte = Urb->UrbControlDescriptorRequest.Index;
+ CtrlSetup.wValue.HiByte = Urb->UrbControlDescriptorRequest.DescriptorType;
+ CtrlSetup.wIndex.W = Urb->UrbControlDescriptorRequest.LanguageId;
+ CtrlSetup.wLength = Urb->UrbControlDescriptorRequest.TransferBufferLength;
+
+ ResultOk = ExecuteControlRequest(FdoDeviceExtension, &CtrlSetup, UsbDevice->Address, UsbDevice->Port,
+ Urb->UrbControlDescriptorRequest.TransferBuffer, Urb->UrbControlDescriptorRequest.TransferBufferLength);
+ break;
+ }
+ default:
+ {
+ DPRINT1("Descriptor Type %x not supported!\n", Urb->UrbControlDescriptorRequest.DescriptorType);
}
- break;
}
- case URB_FUNCTION_SELECT_CONFIGURATION:
- {
- PUSBD_INTERFACE_INFORMATION InterfaceInfo;
- LONG iCount, pCount;
+ break;
+ }
+ case URB_FUNCTION_SELECT_CONFIGURATION:
+ {
+ PUSBD_INTERFACE_INFORMATION InterfaceInfo;
+ LONG iCount, pCount;
- DPRINT("Selecting Configuration\n");
- DPRINT("Length %x\n", Urb->UrbHeader.Length);
- DPRINT("Urb->UrbSelectConfiguration.ConfigurationHandle %x\n",Urb->UrbSelectConfiguration.ConfigurationHandle);
+ DPRINT("Selecting Configuration\n");
+ DPRINT("Urb->UrbSelectConfiguration.ConfigurationHandle %x\n",Urb->UrbSelectConfiguration.ConfigurationHandle);
- if (Urb->UrbSelectConfiguration.ConfigurationDescriptor)
+ if (Urb->UrbSelectConfiguration.ConfigurationDescriptor)
+ {
+ Urb->UrbSelectConfiguration.ConfigurationHandle = (PVOID)&PdoDeviceExtension->UsbDevices[0]->ActiveConfig->ConfigurationDescriptor;
+ DPRINT("ConfigHandle %x\n", Urb->UrbSelectConfiguration.ConfigurationHandle);
+ InterfaceInfo = &Urb->UrbSelectConfiguration.Interface;
+
+ for (iCount = 0; iCount < Urb->UrbSelectConfiguration.ConfigurationDescriptor->bNumInterfaces; iCount++)
{
- DPRINT("ConfigurationDescriptor = %p\n", Urb->UrbSelectConfiguration.ConfigurationDescriptor);
- DPRINT(" bLength = %d\n", Urb->UrbSelectConfiguration.ConfigurationDescriptor->bLength);
- DPRINT(" bDescriptorType = %d\n", Urb->UrbSelectConfiguration.ConfigurationDescriptor->bDescriptorType);
- DPRINT(" wTotalLength = %d\n", Urb->UrbSelectConfiguration.ConfigurationDescriptor->wTotalLength);
- DPRINT(" bNumInterfaces = %d\n", Urb->UrbSelectConfiguration.ConfigurationDescriptor->bNumInterfaces);
- DPRINT(" bConfigurationValue = %d\n", Urb->UrbSelectConfiguration.ConfigurationDescriptor->bConfigurationValue);
- DPRINT(" iConfiguration = %d\n", Urb->UrbSelectConfiguration.ConfigurationDescriptor->iConfiguration);
- DPRINT(" bmAttributes = %04x\n", Urb->UrbSelectConfiguration.ConfigurationDescriptor->bmAttributes);
- DPRINT(" MaxPower = %d\n", Urb->UrbSelectConfiguration.ConfigurationDescriptor->MaxPower);
-
-
- Urb->UrbSelectConfiguration.ConfigurationHandle = (PVOID)&DeviceExtension->UsbDevices[0]->ActiveConfig->ConfigurationDescriptor;
- DPRINT("ConfigHandle %x\n", Urb->UrbSelectConfiguration.ConfigurationHandle);
- InterfaceInfo = &Urb->UrbSelectConfiguration.Interface;
-
- for (iCount = 0; iCount < Urb->UrbSelectConfiguration.ConfigurationDescriptor->bNumInterfaces; iCount++)
+ InterfaceInfo->InterfaceHandle = (PVOID)&UsbDevice->ActiveInterface->InterfaceDescriptor;
+ InterfaceInfo->Class = UsbDevice->ActiveInterface->InterfaceDescriptor.bInterfaceClass;
+ InterfaceInfo->SubClass = UsbDevice->ActiveInterface->InterfaceDescriptor.bInterfaceSubClass;
+ InterfaceInfo->Protocol = UsbDevice->ActiveInterface->InterfaceDescriptor.bInterfaceProtocol;
+ InterfaceInfo->Reserved = 0;
+
+ for (pCount = 0; pCount < InterfaceInfo->NumberOfPipes; pCount++)
{
- DPRINT("InterfaceInformation[%d]\n", iCount);
- DPRINT(" Length = %d\n", InterfaceInfo->Length);
- DPRINT(" InterfaceNumber = %d\n", InterfaceInfo->InterfaceNumber);
- DPRINT(" AlternateSetting = %d\n", InterfaceInfo->AlternateSetting);
- DPRINT(" Class = %02x\n", (ULONG)InterfaceInfo->Class);
- DPRINT(" SubClass = %02x\n", (ULONG)InterfaceInfo->SubClass);
- DPRINT(" Protocol = %02x\n", (ULONG)InterfaceInfo->Protocol);
- DPRINT(" Reserved = %02x\n", (ULONG)InterfaceInfo->Reserved);
- DPRINT(" InterfaceHandle = %p\n", InterfaceInfo->InterfaceHandle);
- DPRINT(" NumberOfPipes = %d\n", InterfaceInfo->NumberOfPipes);
- InterfaceInfo->InterfaceHandle = (PVOID)&UsbDevice->ActiveInterface->InterfaceDescriptor;
- InterfaceInfo->Class = UsbDevice->ActiveInterface->InterfaceDescriptor.bInterfaceClass;
- InterfaceInfo->SubClass = UsbDevice->ActiveInterface->InterfaceDescriptor.bInterfaceSubClass;
- InterfaceInfo->Protocol = UsbDevice->ActiveInterface->InterfaceDescriptor.bInterfaceProtocol;
- InterfaceInfo->Reserved = 0;
-
- for (pCount = 0; pCount < InterfaceInfo->NumberOfPipes; pCount++)
- {
- DPRINT("Pipe[%d]\n", pCount);
- DPRINT(" MaximumPacketSize = %d\n", InterfaceInfo->Pipes[pCount].MaximumPacketSize);
- DPRINT(" EndpointAddress = %d\n", InterfaceInfo->Pipes[pCount].EndpointAddress);
- DPRINT(" Interval = %d\n", InterfaceInfo->Pipes[pCount].Interval);
- DPRINT(" PipeType = %d\n", InterfaceInfo->Pipes[pCount].PipeType);
- DPRINT(" PipeHandle = %x\n", InterfaceInfo->Pipes[pCount].PipeHandle);
- DPRINT(" MaximumTransferSize = %d\n", InterfaceInfo->Pipes[pCount].MaximumTransferSize);
- DPRINT(" PipeFlags = %08x\n", InterfaceInfo->Pipes[pCount].PipeFlags);
- InterfaceInfo->Pipes[pCount].MaximumPacketSize = UsbDevice->ActiveInterface->EndPoints[pCount]->EndPointDescriptor.wMaxPacketSize;
- InterfaceInfo->Pipes[pCount].EndpointAddress = UsbDevice->ActiveInterface->EndPoints[pCount]->EndPointDescriptor.bEndpointAddress;
- InterfaceInfo->Pipes[pCount].Interval = UsbDevice->ActiveInterface->EndPoints[pCount]->EndPointDescriptor.bInterval;
- InterfaceInfo->Pipes[pCount].PipeType = UsbdPipeTypeInterrupt;
- InterfaceInfo->Pipes[pCount].PipeHandle = (PVOID)&UsbDevice->ActiveInterface->EndPoints[pCount]->EndPointDescriptor;
- if (InterfaceInfo->Pipes[pCount].MaximumTransferSize == 0)
- InterfaceInfo->Pipes[pCount].MaximumTransferSize = 4096;
- /* InterfaceInfo->Pipes[j].PipeFlags = 0; */
- }
- InterfaceInfo = (PUSBD_INTERFACE_INFORMATION)((PUCHAR)InterfaceInfo + InterfaceInfo->Length);
+ InterfaceInfo->Pipes[pCount].MaximumPacketSize = UsbDevice->ActiveInterface->EndPoints[pCount]->EndPointDescriptor.wMaxPacketSize;
+ InterfaceInfo->Pipes[pCount].EndpointAddress = UsbDevice->ActiveInterface->EndPoints[pCount]->EndPointDescriptor.bEndpointAddress;
+ InterfaceInfo->Pipes[pCount].Interval = UsbDevice->ActiveInterface->EndPoints[pCount]->EndPointDescriptor.bInterval;
+ InterfaceInfo->Pipes[pCount].PipeType = UsbdPipeTypeInterrupt;
+ InterfaceInfo->Pipes[pCount].PipeHandle = (PVOID)&UsbDevice->ActiveInterface->EndPoints[pCount]->EndPointDescriptor;
+ if (InterfaceInfo->Pipes[pCount].MaximumTransferSize == 0)
+ InterfaceInfo->Pipes[pCount].MaximumTransferSize = 4096;
+ /* InterfaceInfo->Pipes[j].PipeFlags = 0; */
}
+ InterfaceInfo = (PUSBD_INTERFACE_INFORMATION)((PUCHAR)InterfaceInfo + InterfaceInfo->Length);
}
- else
- {
- /* FIXME: Set device to unconfigured state */
- }
- break;
}
- case URB_FUNCTION_CLASS_DEVICE:
+ else
+ {
+ /* FIXME: Set device to unconfigured state */
+ }
+ break;
+ }
+ case URB_FUNCTION_CLASS_DEVICE:
+ {
+ switch (Urb->UrbControlVendorClassRequest.Request)
{
- switch (Urb->UrbControlVendorClassRequest.Request)
+ case USB_REQUEST_GET_DESCRIPTOR:
{
- case USB_REQUEST_GET_DESCRIPTOR:
+ switch (Urb->UrbControlVendorClassRequest.Value >> 8)
{
- DPRINT1("TransferFlags %x\n", Urb->UrbControlVendorClassRequest.TransferFlags);
- DPRINT1("Urb->UrbControlVendorClassRequest.Value %x\n", Urb->UrbControlVendorClassRequest.Value);
-
- switch (Urb->UrbControlVendorClassRequest.Value >> 8)
+ case USB_DEVICE_CLASS_AUDIO:
{
- case USB_DEVICE_CLASS_AUDIO:
- {
- DPRINT1("USB_DEVICE_CLASS_AUDIO\n");
- break;
- }
- case USB_DEVICE_CLASS_COMMUNICATIONS:
- {
- DPRINT1("USB_DEVICE_CLASS_COMMUNICATIONS\n");
- break;
- }
- case USB_DEVICE_CLASS_HUMAN_INTERFACE:
- {
- DPRINT1("USB_DEVICE_CLASS_HUMAN_INTERFACE\n");
- break;
- }
- case USB_DEVICE_CLASS_MONITOR:
- {
- DPRINT1("USB_DEVICE_CLASS_MONITOR\n");
- break;
- }
- case USB_DEVICE_CLASS_PHYSICAL_INTERFACE:
- {
- DPRINT1("USB_DEVICE_CLASS_PHYSICAL_INTERFACE\n");
- break;
- }
- case USB_DEVICE_CLASS_POWER:
- {
- DPRINT1("USB_DEVICE_CLASS_POWER\n");
- break;
- }
- case USB_DEVICE_CLASS_PRINTER:
- {
- DPRINT1("USB_DEVICE_CLASS_PRINTER\n");
- break;
- }
- case USB_DEVICE_CLASS_STORAGE:
+ DPRINT1("USB_DEVICE_CLASS_AUDIO not implemented\n");
+ break;
+ }
+ case USB_DEVICE_CLASS_COMMUNICATIONS:
+ {
+ DPRINT1("USB_DEVICE_CLASS_COMMUNICATIONS not implemented\n");
+ break;
+ }
+ case USB_DEVICE_CLASS_HUMAN_INTERFACE:
+ {
+ DPRINT1("USB_DEVICE_CLASS_HUMAN_INTERFACE not implemented\n");
+ break;
+ }
+ case USB_DEVICE_CLASS_MONITOR:
+ {
+ DPRINT1("USB_DEVICE_CLASS_MONITOR not implemented\n");
+ break;
+ }
+ case USB_DEVICE_CLASS_PHYSICAL_INTERFACE:
+ {
+ DPRINT1("USB_DEVICE_CLASS_PHYSICAL_INTERFACE not implemented\n");
+ break;
+ }
+ case USB_DEVICE_CLASS_POWER:
+ {
+ DPRINT1("USB_DEVICE_CLASS_POWER not implemented\n");
+ break;
+ }
+ case USB_DEVICE_CLASS_PRINTER:
+ {
+ DPRINT1("USB_DEVICE_CLASS_PRINTER not implemented\n");
+ break;
+ }
+ case USB_DEVICE_CLASS_STORAGE:
+ {
+ DPRINT1("USB_DEVICE_CLASS_STORAGE not implemented\n");
+ break;
+ }
+ case USB_DEVICE_CLASS_RESERVED:
+ DPRINT1("Reserved!!!\n");
+ case USB_DEVICE_CLASS_HUB:
+ {
+ PUSB_HUB_DESCRIPTOR UsbHubDescr = Urb->UrbControlVendorClassRequest.TransferBuffer;
+
+ DPRINT1("Length %x\n", Urb->UrbControlVendorClassRequest.TransferBufferLength);
+ ASSERT(Urb->UrbControlVendorClassRequest.TransferBuffer != 0);
+ /* FIXME: Handle more than root hub? */
+ if(Urb->UrbControlVendorClassRequest.TransferBufferLength >= sizeof(USB_HUB_DESCRIPTOR))
{
- DPRINT1("USB_DEVICE_CLASS_STORAGE\n");
- break;
+ Urb->UrbControlVendorClassRequest.TransferBufferLength = sizeof(USB_HUB_DESCRIPTOR);
}
- case USB_DEVICE_CLASS_RESERVED:
- DPRINT1("Reserved!!!\n");
- case USB_DEVICE_CLASS_HUB:
+ else
{
-
- PUSB_HUB_DESCRIPTOR UsbHubDescr = Urb->UrbControlVendorClassRequest.TransferBuffer;
- ASSERT(Urb->UrbControlVendorClassRequest.TransferBuffer != 0);
- /* FIXME: Handle more than root hub? */
- if(Urb->UrbControlVendorClassRequest.TransferBufferLength >= sizeof(USB_HUB_DESCRIPTOR))
- {
- Urb->UrbControlVendorClassRequest.TransferBufferLength = sizeof(USB_HUB_DESCRIPTOR);
- }
- else
- {
- /* FIXME: Handle this correctly */
- UsbHubDescr->bDescriptorLength = sizeof(USB_HUB_DESCRIPTOR);
- UsbHubDescr->bDescriptorType = 0x29;
- break;
- }
- DPRINT1("USB_DEVICE_CLASS_HUB request\n");
+ /* FIXME: Handle this correctly */
UsbHubDescr->bDescriptorLength = sizeof(USB_HUB_DESCRIPTOR);
UsbHubDescr->bDescriptorType = 0x29;
- UsbHubDescr->bNumberOfPorts = 0x08;
- UsbHubDescr->wHubCharacteristics = 0x0012;
- UsbHubDescr->bPowerOnToPowerGood = 0x01;
- UsbHubDescr->bHubControlCurrent = 0x00;
- UsbHubDescr->bRemoveAndPowerMask[0] = 0x00;
- UsbHubDescr->bRemoveAndPowerMask[1] = 0x00;
- UsbHubDescr->bRemoveAndPowerMask[2] = 0xff;
break;
}
- default:
- {
- DPRINT1("Unknown UrbControlVendorClassRequest Value\n");
- }
+ DPRINT1("USB_DEVICE_CLASS_HUB request\n");
+ UsbHubDescr->bDescriptorLength = sizeof(USB_HUB_DESCRIPTOR);
+ UsbHubDescr->bDescriptorType = 0x29;
+ UsbHubDescr->bNumberOfPorts = 0x08;
+ UsbHubDescr->wHubCharacteristics = 0x0012;
+ UsbHubDescr->bPowerOnToPowerGood = 0x01;
+ UsbHubDescr->bHubControlCurrent = 0x00;
+ UsbHubDescr->bRemoveAndPowerMask[0] = 0x00;
+ UsbHubDescr->bRemoveAndPowerMask[1] = 0x00;
+ UsbHubDescr->bRemoveAndPowerMask[2] = 0xff;
+ break;
}
- break;
- }
- case USB_REQUEST_GET_STATUS:
- {
- DPRINT1("DEVICE: USB_REQUEST_GET_STATUS for port %d\n", Urb->UrbControlVendorClassRequest.Index);
-
- if (Urb->UrbControlVendorClassRequest.Index == 1)
+ default:
{
- ASSERT(Urb->UrbControlVendorClassRequest.TransferBuffer != 0);
- ((PULONG)Urb->UrbControlVendorClassRequest.TransferBuffer)[0] = 0;
+ DPRINT1("Unknown UrbControlVendorClassRequest Value\n");
}
- break;
}
- default:
+ break;
+ }
+ case USB_REQUEST_GET_STATUS:
+ {
+ DPRINT1("DEVICE: USB_REQUEST_GET_STATUS for port %d\n", Urb->UrbControlVendorClassRequest.Index);
+ if (Urb->UrbControlVendorClassRequest.Index == 1)
{
- DPRINT1("Unhandled URB request for class device\n");
- Urb->UrbHeader.Status = USBD_STATUS_INVALID_URB_FUNCTION;
+ ASSERT(Urb->UrbControlVendorClassRequest.TransferBuffer != 0);
+ ((PULONG)Urb->UrbControlVendorClassRequest.TransferBuffer)[0] = 0;
}
+ break;
+ }
+ default:
+ {
+ DPRINT1("Unhandled URB request for class device\n");
+ Urb->UrbHeader.Status = USBD_STATUS_INVALID_URB_FUNCTION;
}
- break;
}
- case URB_FUNCTION_CLASS_OTHER:
+ break;
+ }
+ case URB_FUNCTION_CLASS_OTHER:
+ {
+ DPRINT("URB_FUNCTION_CLASS_OTHER\n");
+ /* FIXME: Each one of these needs to make sure that the index value is a valid for the number of ports and return STATUS_UNSUCCESSFUL is not */
+
+ switch (Urb->UrbControlVendorClassRequest.Request)
{
- switch (Urb->UrbControlVendorClassRequest.Request)
+ case USB_REQUEST_GET_STATUS:
+ {
+ DPRINT("USB_REQUEST_GET_STATUS Port %d\n", Urb->UrbControlVendorClassRequest.Index);
+
+ ASSERT(Urb->UrbControlVendorClassRequest.TransferBuffer != 0);
+ DPRINT("PortStatus %x\n", PdoDeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortStatus);
+ DPRINT("PortChange %x\n", PdoDeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortChange);
+ ((PUSHORT)Urb->UrbControlVendorClassRequest.TransferBuffer)[0] = PdoDeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortStatus;
+ ((PUSHORT)Urb->UrbControlVendorClassRequest.TransferBuffer)[1] = PdoDeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortChange;
+ break;
+ }
+ case USB_REQUEST_CLEAR_FEATURE:
{
- case USB_REQUEST_GET_STATUS:
+ DPRINT("USB_REQUEST_CLEAR_FEATURE Port %d, value %x\n", Urb->UrbControlVendorClassRequest.Index,
+ Urb->UrbControlVendorClassRequest.Value);
+ switch (Urb->UrbControlVendorClassRequest.Value)
{
- DPRINT1("OTHER: USB_REQUEST_GET_STATUS for port %d\n", Urb->UrbControlVendorClassRequest.Index);
- ASSERT(Urb->UrbControlVendorClassRequest.TransferBuffer != 0);
- ((PUSHORT)Urb->UrbControlVendorClassRequest.TransferBuffer)[0] = DeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortStatus;
- ((PUSHORT)Urb->UrbControlVendorClassRequest.TransferBuffer)[1] = DeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortChange;
- break;
+ case C_PORT_CONNECTION:
+ PdoDeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortChange &= ~USB_PORT_STATUS_CONNECT;
+ break;
+ case C_PORT_RESET:
+ PdoDeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortChange &= ~USB_PORT_STATUS_RESET;
+ break;
+ default:
+ DPRINT1("Unknown Value for Clear Feature %x \n", Urb->UrbControlVendorClassRequest.Value);
+ break;
}
- case USB_REQUEST_CLEAR_FEATURE:
+ break;
+ }
+ case USB_REQUEST_SET_FEATURE:
+ {
+ DPRINT("USB_REQUEST_SET_FEATURE Port %d, value %x\n", Urb->UrbControlVendorClassRequest.Index,
+ Urb->UrbControlVendorClassRequest.Value);
+
+ switch(Urb->UrbControlVendorClassRequest.Value)
{
- DPRINT1("USB_REQUEST_CLEAR_FEATURE Port %d, value %x\n", Urb->UrbControlVendorClassRequest.Index,
- Urb->UrbControlVendorClassRequest.Value);
- switch (Urb->UrbControlVendorClassRequest.Value)
+ case PORT_RESET:
{
- case C_PORT_CONNECTION:
- DeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortChange &= ~USB_PORT_STATUS_CONNECT;
- break;
- case C_PORT_RESET:
- DeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortChange &= ~USB_PORT_STATUS_RESET;
- break;
- default:
- DPRINT1("Unknown Value for Clear Feature %x \n", Urb->UrbControlVendorClassRequest.Value);
- break;
- }
- break;
- }
- case USB_REQUEST_SET_FEATURE:
- {
- DPRINT1("USB_REQUEST_SET_FEATURE Port %d, value %x\n", Urb->UrbControlVendorClassRequest.Index,
- Urb->UrbControlVendorClassRequest.Value);
+ PdoDeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortStatus |= USB_PORT_STATUS_ENABLE;
+ ResetPort(FdoDeviceExtension, Urb->UrbControlVendorClassRequest.Index-1);
- switch(Urb->UrbControlVendorClassRequest.Value)
+ break;
+ }
+ case PORT_ENABLE:
{
- case PORT_RESET:
- {
- DeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortChange |= USB_PORT_STATUS_RESET;
- break;
- }
- case PORT_ENABLE:
- {
- DPRINT1("Unhandled Set Feature\n");
- break;
- }
- default:
- {
- DPRINT1("Unknown Set Feature!\n");
- break;
- }
+ DPRINT1("PORT_ENABLE not implemented\n");
+ break;
+ }
+ case PORT_POWER:
+ {
+ DPRINT1("PORT_POWER not implemented\n");
+ break;
+ }
+ default:
+ {
+ DPRINT1("Unknown Set Feature!\n");
+ break;
}
- break;
- }
- case USB_REQUEST_SET_ADDRESS:
- {
- DPRINT1("USB_REQUEST_SET_ADDRESS\n");
- break;
- }
- case USB_REQUEST_GET_DESCRIPTOR:
- {
- DPRINT1("USB_REQUEST_GET_DESCRIPTOR\n");
- break;
- }
- case USB_REQUEST_SET_DESCRIPTOR:
- {
- DPRINT1("USB_REQUEST_SET_DESCRIPTOR\n");
- break;
- }
- case USB_REQUEST_GET_CONFIGURATION:
- {
- DPRINT1("USB_REQUEST_GET_CONFIGURATION\n");
- break;
- }
- case USB_REQUEST_SET_CONFIGURATION:
- {
- DPRINT1("USB_REQUEST_SET_CONFIGURATION\n");
- break;
- }
- case USB_REQUEST_GET_INTERFACE:
- {
- DPRINT1("USB_REQUEST_GET_INTERFACE\n");
- break;
- }
- case USB_REQUEST_SET_INTERFACE:
- {
- DPRINT1("USB_REQUEST_SET_INTERFACE\n");
- break;
- }
- case USB_REQUEST_SYNC_FRAME:
- {
- DPRINT1("USB_REQUEST_SYNC_FRAME\n");
- break;
- }
- default:
- {
- DPRINT1("Unknown Function Class Unknown request\n");
- break;
}
+ break;
+ }
+ case USB_REQUEST_SET_ADDRESS:
+ {
+ DPRINT1("USB_REQUEST_SET_ADDRESS\n");
+ break;
+ }
+ case USB_REQUEST_GET_DESCRIPTOR:
+ {
+ DPRINT1("USB_REQUEST_GET_DESCRIPTOR\n");
+ break;
+ }
+ case USB_REQUEST_SET_DESCRIPTOR:
+ {
+ DPRINT1("USB_REQUEST_SET_DESCRIPTOR\n");
+ break;
+ }
+ case USB_REQUEST_GET_CONFIGURATION:
+ {
+ DPRINT1("USB_REQUEST_GET_CONFIGURATION\n");
+ break;
+ }
+ case USB_REQUEST_SET_CONFIGURATION:
+ {
+ DPRINT1("USB_REQUEST_SET_CONFIGURATION\n");
+ break;
+ }
+ case USB_REQUEST_GET_INTERFACE:
+ {
+ DPRINT1("USB_REQUEST_GET_INTERFACE\n");
+ break;
+ }
+ case USB_REQUEST_SET_INTERFACE:
+ {
+ DPRINT1("USB_REQUEST_SET_INTERFACE\n");
+ break;
+ }
+ case USB_REQUEST_SYNC_FRAME:
+ {
+ DPRINT1("USB_REQUEST_SYNC_FRAME\n");
+ break;
+ }
+ default:
+ {
+ DPRINT1("Unknown Function Class Unknown request\n");
+ break;
}
- break;
- }
- default:
- {
- DPRINT1("Unhandled URB %x\n", Urb->UrbHeader.Function);
- Urb->UrbHeader.Status = USBD_STATUS_INVALID_URB_FUNCTION;
}
-
+ break;
}
-
- Irp->IoStatus.Status = Status;
- Irp->IoStatus.Information = Information;
-
- if (Urb->UrbHeader.Status == USBD_STATUS_SUCCESS)
+ default:
{
- /* Fake a successful Control Transfer */
- Urb->UrbHeader.Function = 0x08;
- Urb->UrbHeader.UsbdFlags = 0;
+ DPRINT1("Unhandled URB %x\n", Urb->UrbHeader.Function);
+ Urb->UrbHeader.Status = USBD_STATUS_INVALID_URB_FUNCTION;
}
+ }
+
+ Irp->IoStatus.Status = Status;
+ Irp->IoStatus.Information = Information;
+
+ if (Urb->UrbHeader.Status == USBD_STATUS_SUCCESS)
+ {
+ /* Fake a successful Control Transfer */
+ Urb->UrbHeader.Function = 0x08;
+ Urb->UrbHeader.UsbdFlags = 0;
+ }
+
+ return Status;
+}
+
+VOID
+CompletePendingURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension)
+{
+ PLIST_ENTRY NextIrp = NULL;
+ KIRQL oldIrql;
+ PIRP Irp = NULL;
+
+ KeAcquireSpinLock(&DeviceExtension->IrpQueueLock, &oldIrql);
+
+ while (!IsListEmpty(&DeviceExtension->IrpQueue))
+ {
+ NextIrp = RemoveHeadList(&DeviceExtension->IrpQueue);
+ Irp = CONTAINING_RECORD(NextIrp, IRP, Tail.Overlay.ListEntry);
+
+ if (!Irp)
+ break;
+
KeReleaseSpinLock(&DeviceExtension->IrpQueueLock, oldIrql);
+ HandleUrbRequest(DeviceExtension, Irp);
IoCompleteRequest(Irp, IO_NO_INCREMENT);
KeAcquireSpinLock(&DeviceExtension->IrpQueueLock, &oldIrql);
-
- if (DeviceExtension->HaltQueue)
- break;
}
KeReleaseSpinLock(&DeviceExtension->IrpQueueLock, oldIrql);
- if (!DeviceExtension->HaltQueue)
- KeSetEvent(&DeviceExtension->QueueDrainedEvent, 0, FALSE);
}
* FILE: drivers/usb/usbehci/misc.c
* PURPOSE: Misceallenous operations.
* PROGRAMMERS:
- * Michael Martin
+ * Michael Martin (michael.martin@reactos.org)
*/
#include "usbehci.h"
* FILE: drivers/usb/usbehci/pdo.c
* PURPOSE: USB EHCI device driver.
* PROGRAMMERS:
- * Michael Martin
+ * Michael Martin (michael.martin@reactos.org)
*/
#define INITGUID
{
case IOCTL_INTERNAL_USB_SUBMIT_URB:
{
+ PUSB_DEVICE UsbDevice = NULL;
URB *Urb;
+ ULONG i;
Urb = (PURB) Stack->Parameters.Others.Argument1;
- DPRINT("Header Length %d\n", Urb->UrbHeader.Length);
- DPRINT("Header Function %d\n", Urb->UrbHeader.Function);
- /* Queue all request for now, kernel thread will complete them */
- QueueURBRequest(PdoDeviceExtension, Irp);
- Information = 0;
- IoMarkIrpPending(Irp);
- Status = STATUS_PENDING;
+
+ UsbDevice = Urb->UrbHeader.UsbdDeviceHandle;
+
+ if (UsbDevice == NULL)
+ UsbDevice = PdoDeviceExtension->UsbDevices[0];
+
+ if ((Urb->UrbHeader.Function == URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER) &&
+ (UsbDevice == PdoDeviceExtension->UsbDevices[0]))
+ {
+ if (Urb->UrbBulkOrInterruptTransfer.PipeHandle == &UsbDevice->ActiveInterface->EndPoints[0]->EndPointDescriptor)
+ {
+ DPRINT1("PipeHandle doesnt match SCE PipeHandle\n");
+ }
+
+ /* Queue the Irp first */
+ QueueURBRequest(PdoDeviceExtension, Irp);
+
+ /* Check if there is any connected devices */
+ for (i = 0; i < PdoDeviceExtension->NumberOfPorts; i++)
+ {
+ if (PdoDeviceExtension->Ports[i].PortChange == 0x01)
+ {
+ DPRINT1("Inform hub driver that port %d has changed\n", i+1);
+ ((PUCHAR)Urb->UrbBulkOrInterruptTransfer.TransferBuffer)[0] = 1 << ((i + 1) & 7);
+ Information = 0;
+ Status = STATUS_SUCCESS;
+ /* Assume URB success */
+ Urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
+ /* Set the DeviceHandle to the Internal Device */
+ Urb->UrbHeader.UsbdDeviceHandle = UsbDevice;
+
+ /* Request handled, Remove it from the queue */
+ RemoveUrbRequest(PdoDeviceExtension, Irp);
+ break;
+ }
+ }
+ if (Status == STATUS_SUCCESS) break;
+ DPRINT1("Queueing IRP\n");
+ IoMarkIrpPending(Irp);
+ Status = STATUS_PENDING;
+ break;
+ }
+
+ Status = HandleUrbRequest(PdoDeviceExtension, Irp);
+
break;
}
case IOCTL_INTERNAL_USB_CYCLE_PORT:
}
case IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE:
{
- DPRINT1("IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE %x\n", IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE);
+ DPRINT("Ehci: IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE %x\n", Stack->Parameters.Others.Argument2);
if (Stack->Parameters.Others.Argument1)
{
/* Return the root hubs devicehandle */
- DPRINT1("Returning RootHub Handle %x\n", PdoDeviceExtension->UsbDevices[0]);
+ DPRINT("Returning RootHub Handle %x\n", PdoDeviceExtension->UsbDevices[0]);
*(PVOID *)Stack->Parameters.Others.Argument1 = (PVOID)PdoDeviceExtension->UsbDevices[0];
Status = STATUS_SUCCESS;
}
}
case IOCTL_INTERNAL_USB_GET_HUB_COUNT:
{
- DPRINT1("IOCTL_INTERNAL_USB_GET_HUB_COUNT %x\n", IOCTL_INTERNAL_USB_GET_HUB_COUNT);
+ DPRINT("Ehci: IOCTL_INTERNAL_USB_GET_HUB_COUNT %x\n", IOCTL_INTERNAL_USB_GET_HUB_COUNT);
ASSERT(Stack->Parameters.Others.Argument1 != NULL);
if (Stack->Parameters.Others.Argument1)
{
/* FIXME: Determine the number of hubs between the usb device and root hub */
DPRINT1("RootHubCount %x\n", *(PULONG)Stack->Parameters.Others.Argument1);
- *(PULONG)Stack->Parameters.Others.Argument1 = 0;
+ *(PULONG)Stack->Parameters.Others.Argument1 = 1;
}
Status = STATUS_SUCCESS;
break;
}
case IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO:
{
- DPRINT1("IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO\n");
-
+ DPRINT("Ehci: IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO Arg1 %x, Arg2 %x\n", Stack->Parameters.Others.Argument1, Stack->Parameters.Others.Argument2);
if (Stack->Parameters.Others.Argument1)
*(PVOID *)Stack->Parameters.Others.Argument1 = FdoDeviceExtension->Pdo;
+
+ /* Windows usbehci driver gives the Pdo in both Arguments. */
if (Stack->Parameters.Others.Argument2)
- *(PVOID *)Stack->Parameters.Others.Argument2 = IoGetAttachedDeviceReference(FdoDeviceExtension->DeviceObject);
+ //*(PVOID *)Stack->Parameters.Others.Argument2 = IoGetAttachedDeviceReference(FdoDeviceExtension->DeviceObject);
+ *(PVOID *)Stack->Parameters.Others.Argument2 = FdoDeviceExtension->Pdo;
Information = 0;
Status = STATUS_SUCCESS;
case IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION:
{
PUSB_IDLE_CALLBACK_INFO CallBackInfo;
- DPRINT1("IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION\n");
+ DPRINT1("Ehci: IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION\n");
/* FIXME: Set Callback for safe power down */
CallBackInfo = Stack->Parameters.DeviceIoControl.Type3InputBuffer;
DPRINT1("IdleCallback %x\n", CallBackInfo->IdleCallback);
UNICODE_STRING InterfaceSymLinkName;
LONG i;
+ DPRINT1("Ehci: PDO StartDevice\n");
PdoDeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
FdoDeviceExtension = (PFDO_DEVICE_EXTENSION)PdoDeviceExtension->ControllerFdo->DeviceExtension;
/* Create the root hub */
RootHubDevice = InternalCreateUsbDevice(1, 0, NULL, TRUE);
- for (i = 0; i < 8; i++)
+ for (i = 0; i < PdoDeviceExtension->NumberOfPorts; i++)
{
- PdoDeviceExtension->Ports[i].PortStatus = USB_PORT_STATUS_ENABLE;
+ PdoDeviceExtension->Ports[i].PortStatus = USB_PORT_STATUS_HIGH_SPEED | 0x8000;
PdoDeviceExtension->Ports[i].PortChange = 0;
+
+ if (!FdoDeviceExtension->ECHICaps.HCSParams.PortPowerControl)
+ PdoDeviceExtension->Ports[i].PortStatus |= USB_PORT_STATUS_POWER;
}
RtlCopyMemory(&RootHubDevice->DeviceDescriptor,
PdoDeviceExtension->UsbDevices[0] = RootHubDevice;
/* Create a thread to handle the URB's */
-
+/*
Status = PsCreateSystemThread(&PdoDeviceExtension->ThreadHandle,
THREAD_ALL_ACCESS,
NULL,
if (!NT_SUCCESS(Status))
DPRINT1("Failed Thread Creation with Status: %x\n", Status);
-
+*/
Status = IoRegisterDeviceInterface(DeviceObject, &GUID_DEVINTERFACE_USB_HUB, NULL, &InterfaceSymLinkName);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to register interface\n");
- ASSERT(FALSE);
+ return Status;
}
else
{
Status = IoSetDeviceInterfaceState(&InterfaceSymLinkName, TRUE);
if (!NT_SUCCESS(Status))
- ASSERT(FALSE);
+ return Status;
}
Status = STATUS_SUCCESS;
}
case IRP_MN_QUERY_DEVICE_RELATIONS:
{
+ DPRINT1("Ehci: PDO QueryDeviceRelations\n");
switch (Stack->Parameters.QueryDeviceRelations.Type)
{
case TargetDeviceRelation:
}
case IRP_MN_QUERY_CAPABILITIES:
{
+ DPRINT("Ehci: PDO Query Capabilities\n");
PDEVICE_CAPABILITIES DeviceCapabilities;
ULONG i;
case IRP_MN_QUERY_ID:
{
+ DPRINT("Ehci: PDO Query ID\n");
Status = PdoQueryId(DeviceObject, Irp, &Information);
break;
}
PPDO_DEVICE_EXTENSION PdoDeviceExtension;
PFDO_DEVICE_EXTENSION FdoDeviceExtension;
+ DPRINT("Ehci: PDO Query Interface\n");
+
PdoDeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
FdoDeviceExtension = (PFDO_DEVICE_EXTENSION)PdoDeviceExtension->ControllerFdo->DeviceExtension;
DPRINT1("Failed to create string from GUID!\n");
}
- DPRINT("Interface GUID requested %wZ\n", &GuidString);
- DPRINT("QueryInterface.Size %x\n", Stack->Parameters.QueryInterface.Size);
- DPRINT("QueryInterface.Version %x\n", Stack->Parameters.QueryInterface.Version);
-
/* Assume success */
Status = STATUS_SUCCESS;
Information = 0;
* FILE: drivers/usb/usbehci/urbreq.c
* PURPOSE: URB Related Functions.
* PROGRAMMERS:
- * Michael Martin (mjmartin@reactos.org)
+ * Michael Martin (michael.martin@reactos.org)
*/
#include "usbehci.h"
DPRINT1("ExecuteControlRequest: Buffer %x, Length %x\n", Buffer, BufferLength);
+ ExAcquireFastMutex(&DeviceExtension->AsyncListMutex);
+
Base = (ULONG) DeviceExtension->ResourceMemory;
/* Set up the QUEUE HEAD in memory */
UsbCmd->Run = FALSE;
WRITE_REGISTER_ULONG((PULONG)(Base + EHCI_USBCMD), tmp);
- if (CtrlSetup->bmRequestType._BM.Dir == BMREQUEST_DEVICE_TO_HOST)
+ if (SetupPacket->bmRequestType._BM.Dir == BMREQUEST_DEVICE_TO_HOST)
{
if ((Buffer) && (BufferLength))
{
DPRINT1("Unable to copy data to buffer\n");
}
+ ExReleaseFastMutex(&DeviceExtension->AsyncListMutex);
+
return TRUE;
}
* FILE: drivers/usb/usbehci/usbehci.c
* PURPOSE: USB EHCI device driver.
* PROGRAMMERS:
- * Michael Martin (mjmartin@reactos.com)
+ * Michael Martin (michael.martin@reactos.org)
*/
/* DEFINES *******************************************************************/
ULONG Vector;
KIRQL Irql;
+ KTIMER UpdateTimer;
KINTERRUPT_MODE Mode;
BOOLEAN IrqShared;
PKINTERRUPT EhciInterrupt;
KDPC DpcObject;
+ KDPC TimerDpcObject;
+
KAFFINITY Affinity;
ULONG MapRegisters;
PHYSICAL_ADDRESS PeriodicFramListPhysAddr;
PHYSICAL_ADDRESS AsyncListQueueHeadPtrPhysAddr;
+ FAST_MUTEX AsyncListMutex;
+ FAST_MUTEX FrameListMutex;
+
BOOLEAN AsyncComplete;
PULONG ResourceBase;
BOOLEAN
ExecuteControlRequest(PFDO_DEVICE_EXTENSION DeviceExtension, PUSB_DEFAULT_PIPE_SETUP_PACKET SetupPacket, UCHAR Address, ULONG Port, PVOID Buffer, ULONG BufferLength);
+VOID
+RequestURBCancel (PPDO_DEVICE_EXTENSION DeviceExtension, PIRP Irp);
+
+VOID
+RemoveUrbRequest(PPDO_DEVICE_EXTENSION PdoDeviceExtension, PIRP Irp);
+
VOID
QueueURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension, PIRP Irp);
VOID
CompletePendingURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension);
-VOID
-URBRequestCancel (PDEVICE_OBJECT DeviceObject, PIRP Irp);
+NTSTATUS
+HandleUrbRequest(PPDO_DEVICE_EXTENSION DeviceExtension, PIRP Irp);
PUSB_DEVICE
DeviceHandleToUsbDevice(PPDO_DEVICE_EXTENSION PdoDeviceExtension, PUSB_DEVICE_HANDLE DeviceHandle);
+
+BOOLEAN
+ResetPort(PFDO_DEVICE_EXTENSION FdoDeviceExtension, UCHAR Port);
\ No newline at end of file
* FILE: drivers/usb/usbehci/usbiffn.c
* PURPOSE: Direct Call Interface Functions.
* PROGRAMMERS:
- * Michael Martin (mjmartin@reactos.org)
+ * Michael Martin (michael.martin@reactos.org)
*/
#include "usbehci.h"
PVOID InternalCreateUsbDevice(UCHAR DeviceNumber, ULONG Port, PUSB_DEVICE Parent, BOOLEAN Hub)
{
PUSB_DEVICE UsbDevicePointer = NULL;
+
UsbDevicePointer = ExAllocatePoolWithTag(NonPagedPool, sizeof(USB_DEVICE), USB_POOL_TAG);
if (!UsbDevicePointer)
DPRINT1("This is the root hub\n");
}
- UsbDevicePointer->Address = DeviceNumber;
+ UsbDevicePointer->Address = 0;// DeviceNumber;
UsbDevicePointer->Port = Port;
UsbDevicePointer->ParentDevice = Parent;
USB_BUSIFFN
InterfaceReference(PVOID BusContext)
{
- DPRINT1("InterfaceReference called\n");
+ DPRINT1("Ehci: InterfaceReference called\n");
}
VOID
USB_BUSIFFN
InterfaceDereference(PVOID BusContext)
{
- DPRINT1("InterfaceDereference called\n");
+ DPRINT1("Ehci: InterfaceDereference called\n");
}
/* Bus Interface Hub V5 Functions */
PUSB_DEVICE UsbDevice;
LONG i = 0;
PdoDeviceExtension = (PPDO_DEVICE_EXTENSION)((PDEVICE_OBJECT)BusContext)->DeviceExtension;
- DPRINT("CreateUsbDevice: HubDeviceHandle %x, PortStatus %x, PortNumber %x\n", HubDeviceHandle, PortStatus, PortNumber);
+ DPRINT1("Ehci: CreateUsbDevice: HubDeviceHandle %x, PortStatus %x, PortNumber %x\n", HubDeviceHandle, PortStatus, PortNumber);
if (PdoDeviceExtension->UsbDevices[0] != HubDeviceHandle)
{
if (PdoDeviceExtension->UsbDevices[i] == NULL)
{
PdoDeviceExtension->UsbDevices[i] = (PUSB_DEVICE)UsbDevice;
- PdoDeviceExtension->UsbDevices[i]->Address = i + 1;
- PdoDeviceExtension->UsbDevices[i]->Port = PortNumber;
break;
}
i++;
PUCHAR Ptr;
LONG i, j, k;
- DPRINT1("InitializeUsbDevice called, device %x\n", DeviceHandle);
+ DPRINT1("Ehci: InitializeUsbDevice called, device %x\n", DeviceHandle);
PdoDeviceExtension = (PPDO_DEVICE_EXTENSION)((PDEVICE_OBJECT)BusContext)->DeviceExtension;
FdoDeviceExtension = (PFDO_DEVICE_EXTENSION)PdoDeviceExtension->ControllerFdo->DeviceExtension;
Ptr = Buffer;
/* Set the device address */
+/*
CtrlSetup.bmRequestType._BM.Recipient = BMREQUEST_TO_DEVICE;
CtrlSetup.bmRequestType._BM.Type = BMREQUEST_STANDARD;
+ CtrlSetup.bmRequestType._BM.Reserved = 0;
CtrlSetup.bmRequestType._BM.Dir = BMREQUEST_HOST_TO_DEVICE;
CtrlSetup.bRequest = USB_REQUEST_SET_ADDRESS;
CtrlSetup.wValue.W = UsbDevice->Address;
DPRINT1("Setting Address to %x\n", UsbDevice->Address);
ResultOk = ExecuteControlRequest(FdoDeviceExtension, &CtrlSetup, 0, UsbDevice->Port, NULL, 0);
+*/
+
/* Get the Device Descriptor */
CtrlSetup.bmRequestType._BM.Recipient = BMREQUEST_TO_DEVICE;
CtrlSetup.bmRequestType._BM.Type = BMREQUEST_STANDARD;
sizeof(USB_CONFIGURATION) + sizeof(PVOID) * ConfigDesc->bNumInterfaces,
USB_POOL_TAG);
UsbDevice->Configs[i]->Device = UsbDevice;
+
RtlCopyMemory(&UsbDevice->Configs[0]->ConfigurationDescriptor,
ConfigDesc, sizeof(USB_CONFIGURATION_DESCRIPTOR));
Ptr += ConfigDesc->bLength;
PULONG ConfigDescriptorBufferLength)
{
PUSB_DEVICE UsbDevice;
- DPRINT1("GetUsbDescriptor %x, %x, %x, %x\n", DeviceDescriptorBuffer, *DeviceDescriptorBufferLength, ConfigDescriptorBuffer, *ConfigDescriptorBufferLength);
+ DPRINT1("Ehci: GetUsbDescriptor %x, %x, %x, %x\n", DeviceDescriptorBuffer, *DeviceDescriptorBufferLength, ConfigDescriptorBuffer, *ConfigDescriptorBufferLength);
UsbDevice = DeviceHandleToUsbDevice(BusContext, DeviceHandle);
RtlCopyMemory(DeviceDescriptorBuffer, &UsbDevice->DeviceDescriptor, sizeof(USB_DEVICE_DESCRIPTOR));
*DeviceDescriptorBufferLength = sizeof(USB_DEVICE_DESCRIPTOR);
}
+
if ((ConfigDescriptorBuffer) && (ConfigDescriptorBufferLength))
{
RtlCopyMemory(ConfigDescriptorBuffer, &UsbDevice->ActiveConfig->ConfigurationDescriptor, sizeof(USB_CONFIGURATION_DESCRIPTOR));
USB_BUSIFFN
RestoreUsbDevice(PVOID BusContext, PUSB_DEVICE_HANDLE OldDeviceHandle, PUSB_DEVICE_HANDLE NewDeviceHandle)
{
- DPRINT1("RestoreUsbDevice called\n");
+ DPRINT1("Ehci: RestoreUsbDevice called\n");
return STATUS_NOT_SUPPORTED;
}
USB_BUSIFFN
GetPortHackFlags(PVOID BusContext, PULONG Flags)
{
- DPRINT1("GetPortHackFlags called\n");
+ DPRINT1("Ehci: GetPortHackFlags called\n");
return STATUS_NOT_SUPPORTED;
}
ULONG SizeNeeded;
LONG i;
- DPRINT1("QueryDeviceInformation (%x, %x, %x, %d, %x\n", BusContext, DeviceHandle, DeviceInformationBuffer, DeviceInformationBufferLength, LengthReturned);
+ DPRINT1("Ehci: QueryDeviceInformation (%x, %x, %x, %d, %x\n", BusContext, DeviceHandle, DeviceInformationBuffer, DeviceInformationBufferLength, LengthReturned);
UsbDevice = DeviceHandleToUsbDevice(BusContext, DeviceHandle);
{
PUSB_CONTROLLER_INFORMATION_0 ControllerInfo;
- DPRINT1("GetControllerInformation called\n");
+ DPRINT1("Ehci: GetControllerInformation called\n");
ControllerInfo = ControllerInformationBuffer;
USB_BUSIFFN
ControllerSelectiveSuspend(PVOID BusContext, BOOLEAN Enable)
{
- DPRINT1("ControllerSelectiveSuspend called\n");
+ DPRINT1("Ehci: ControllerSelectiveSuspend called\n");
return STATUS_NOT_SUPPORTED;
}
PPDO_DEVICE_EXTENSION PdoDeviceExtension = (PPDO_DEVICE_EXTENSION)((PDEVICE_OBJECT)BusContext)->DeviceExtension;
PFDO_DEVICE_EXTENSION FdoDeviceExntension = (PFDO_DEVICE_EXTENSION)PdoDeviceExtension->ControllerFdo->DeviceExtension;
LONG i;
- DPRINT1("GetExtendedHubInformation\n");
+ DPRINT1("Ehci: GetExtendedHubInformation BusContext %x, PDO %x\n", BusContext, HubPhysicalDeviceObject);
/* Set the default return value */
*LengthReturned = 0;
- /* Caller must have set InformationLevel to 0 */
+
+ DPRINT1("InformationLevel %x\n", UsbExtHubInfo->InformationLevel);
+
+ /* Caller is suppose to have set InformationLevel to 0. However usbehci from MS seems to ignore this */
if (UsbExtHubInfo->InformationLevel != 0)
{
- return STATUS_NOT_SUPPORTED;
+ DPRINT1("InformationLevel should really be set to 0. Ignoring\n");
}
UsbExtHubInfo->NumberOfPorts = 8;
ULONG HubSymNameBufferLength,
PULONG HubSymNameActualLength)
{
- DPRINT1("GetRootHubSymbolicName called\n");
+ DPRINT1("Ehci: GetRootHubSymbolicName called\n");
if (HubSymNameBufferLength < 16)
return STATUS_UNSUCCESSFUL;
{
PUSB_DEVICE UsbDevice;
- DPRINT1("GetDeviceBusContext called\n");
+ DPRINT1("Ehci: GetDeviceBusContext called\n");
UsbDevice = DeviceHandleToUsbDevice(HubBusContext, DeviceHandle);
if (!UsbDevice)
USB_BUSIFFN
Initialize20Hub(PVOID BusContext, PUSB_DEVICE_HANDLE HubDeviceHandle, ULONG TtCount)
{
- DPRINT1("Initialize20Hub called, HubDeviceHandle: %x\n", HubDeviceHandle);
-
+ DPRINT1("Ehci: Initialize20Hub called, HubDeviceHandle: %x\n", HubDeviceHandle);
/* FIXME: */
/* Create the Irp Queue for SCE */
/* Should queue be created for each device or each enpoint??? */
RootHubInitNotification(PVOID BusContext, PVOID CallbackContext, PRH_INIT_CALLBACK CallbackRoutine)
{
PPDO_DEVICE_EXTENSION PdoDeviceExtension;
- DPRINT1("RootHubInitNotification %x, %x, %x\n", BusContext, CallbackContext, CallbackRoutine);
+ DPRINT1("Ehci: RootHubInitNotification %x, %x, %x\n", BusContext, CallbackContext, CallbackRoutine);
PdoDeviceExtension = (PPDO_DEVICE_EXTENSION)((PDEVICE_OBJECT)BusContext)->DeviceExtension;
PdoDeviceExtension->CallbackContext = CallbackContext;
USB_BUSIFFN
SetDeviceHandleData(PVOID BusContext, PVOID DeviceHandle, PDEVICE_OBJECT UsbDevicePdo)
{
- DPRINT1("SetDeviceHandleData called\n");
+ DPRINT1("Ehci: SetDeviceHandleData called\n");
}
USB_BUSIFFN
GetUSBDIVersion(PVOID BusContext, PUSBD_VERSION_INFORMATION VersionInformation, PULONG HcdCapabilites)
{
- DPRINT1("GetUSBDIVersion called\n");
+ DPRINT1("Ehci: GetUSBDIVersion called\n");
return;
}
USB_BUSIFFN
QueryBusTime(PVOID BusContext, PULONG CurrentFrame)
{
- DPRINT1("QueryBusTime called\n");
+ DPRINT1("Ehci: QueryBusTime called\n");
return STATUS_NOT_SUPPORTED;
}
USB_BUSIFFN
SubmitIsoOutUrb(PVOID BusContext, PURB Urb)
{
- DPRINT1("SubmitIsoOutUrb called\n");
+ DPRINT1("Ehci: SubmitIsoOutUrb called\n");
return STATUS_NOT_SUPPORTED;
}
PULONG BusInformationBufferLength,
PULONG BusInformationActualLength)
{
- DPRINT1("QueryBusInformation called\n");
+ DPRINT1("Ehci: QueryBusInformation called\n");
return STATUS_NOT_SUPPORTED;
}
USB_BUSIFFN
IsDeviceHighSpeed(PVOID BusContext)
{
- DPRINT1("IsDeviceHighSpeed called\n");
+ DPRINT1("Ehci: IsDeviceHighSpeed called\n");
return TRUE;
}
USB_BUSIFFN
EnumLogEntry(PVOID BusContext, ULONG DriverTag, ULONG EnumTag, ULONG P1, ULONG P2)
{
- DPRINT1("EnumLogEntry called\n");
+ DPRINT1("Ehci: EnumLogEntry called\n");
return STATUS_SUCCESS;
}
* FILE: drivers/usb/cromwell/hub/fdo.c
* PURPOSE: IRP_MJ_PNP operations for FDOs
*
- * PROGRAMMERS: Hervé Poussineau (hpoussin@reactos.com)
+ * PROGRAMMERS: Herv� Poussineau (hpoussin@reactos.com)
+ * Michael Martin (michael.martin@reactos.org)
*/
#define INITGUID
+#include <stdio.h>
#define NDEBUG
#include "usbhub.h"
+#include "usbdlib.h"
#define IO_METHOD_FROM_CTL_CODE(ctlCode) (ctlCode&0x00000003)
+
+typedef struct _USB_LANGUAGEID_DESCRIPTOR {
+ UCHAR bLength;
+ UCHAR bDescriptorType;
+ WCHAR wLANGIDs[1];
+} USB_LANGUAGEID_DESCRIPTOR, *PUSB_LANGUAGEID_DESCRIPTOR;
+
+typedef struct _PORTSTATUSANDCHANGE
+{
+ USHORT Status;
+ USHORT Change;
+} PORTSTATUSANDCHANGE, *PPORTSTATUSANDCHANGE;
+
+NTSTATUS
+QueryRootHub(IN PDEVICE_OBJECT Pdo, IN ULONG IoControlCode, OUT PVOID OutParameter1, OUT PVOID OutParameter2);
+NTSTATUS
+WaitForUsbDeviceArrivalNotification(PDEVICE_OBJECT DeviceObject);
+
+VOID DumpDeviceDescriptor(PUSB_DEVICE_DESCRIPTOR DeviceDescriptor)
+{
+ DPRINT1("Dumping Device Descriptor %x\n", DeviceDescriptor);
+ DPRINT1("bLength %x\n", DeviceDescriptor->bLength);
+ DPRINT1("bDescriptorType %x\n", DeviceDescriptor->bDescriptorType);
+ DPRINT1("bcdUSB %x\n", DeviceDescriptor->bcdUSB);
+ DPRINT1("bDeviceClass %x\n", DeviceDescriptor->bDeviceClass);
+ DPRINT1("bDeviceSubClass %x\n", DeviceDescriptor->bDeviceSubClass);
+ DPRINT1("bDeviceProtocol %x\n", DeviceDescriptor->bDeviceProtocol);
+ DPRINT1("bMaxPacketSize0 %x\n", DeviceDescriptor->bMaxPacketSize0);
+ DPRINT1("idVendor %x\n", DeviceDescriptor->idVendor);
+ DPRINT1("idProduct %x\n", DeviceDescriptor->idProduct);
+ DPRINT1("bcdDevice %x\n", DeviceDescriptor->bcdDevice);
+ DPRINT1("iManufacturer %x\n", DeviceDescriptor->iManufacturer);
+ DPRINT1("iProduct %x\n", DeviceDescriptor->iProduct);
+ DPRINT1("iSerialNumber %x\n", DeviceDescriptor->iSerialNumber);
+ DPRINT1("bNumConfigurations %x\n", DeviceDescriptor->bNumConfigurations);
+}
+
+VOID DumpFullConfigurationDescriptor(PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor)
+{
+ PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
+ PUSB_ENDPOINT_DESCRIPTOR EndpointDescriptor;
+ LONG i, j;
+
+ DPRINT1("Duming ConfigurationDescriptor %x\n", ConfigurationDescriptor);
+ DPRINT1("bLength %x\n", ConfigurationDescriptor->bLength);
+ DPRINT1("bDescriptorType %x\n", ConfigurationDescriptor->bDescriptorType);
+ DPRINT1("wTotalLength %x\n", ConfigurationDescriptor->wTotalLength);
+ DPRINT1("bNumInterfaces %x\n", ConfigurationDescriptor->bNumInterfaces);
+ DPRINT1("bConfigurationValue %x\n", ConfigurationDescriptor->bConfigurationValue);
+ DPRINT1("iConfiguration %x\n", ConfigurationDescriptor->iConfiguration);
+ DPRINT1("bmAttributes %x\n", ConfigurationDescriptor->bmAttributes);
+ DPRINT1("MaxPower %x\n", ConfigurationDescriptor->MaxPower);
+
+ InterfaceDescriptor = (PUSB_INTERFACE_DESCRIPTOR) ((ULONG_PTR)ConfigurationDescriptor + sizeof(USB_CONFIGURATION_DESCRIPTOR));
+
+ for (i=0; i < ConfigurationDescriptor->bNumInterfaces; i++)
+ {
+ DPRINT1("bLength %x\n", InterfaceDescriptor->bLength);
+ DPRINT1("bDescriptorType %x\n", InterfaceDescriptor->bDescriptorType);
+ DPRINT1("bInterfaceNumber %x\n", InterfaceDescriptor->bInterfaceNumber);
+ DPRINT1("bAlternateSetting %x\n", InterfaceDescriptor->bAlternateSetting);
+ DPRINT1("bNumEndpoints %x\n", InterfaceDescriptor->bNumEndpoints);
+ DPRINT1("bInterfaceClass %x\n", InterfaceDescriptor->bInterfaceClass);
+ DPRINT1("bInterfaceSubClass %x\n", InterfaceDescriptor->bInterfaceSubClass);
+ DPRINT1("bInterfaceProtocol %x\n", InterfaceDescriptor->bInterfaceProtocol);
+ DPRINT1("iInterface %x\n", InterfaceDescriptor->iInterface);
+
+ EndpointDescriptor = (PUSB_ENDPOINT_DESCRIPTOR) ((ULONG_PTR)InterfaceDescriptor + sizeof(USB_INTERFACE_DESCRIPTOR));
+
+ for (j=0; j < InterfaceDescriptor->bNumEndpoints; j++)
+ {
+ DPRINT1("bLength %x\n", EndpointDescriptor->bLength);
+ DPRINT1("bDescriptorType %x\n", EndpointDescriptor->bDescriptorType);
+ DPRINT1("bEndpointAddress %x\n", EndpointDescriptor->bEndpointAddress);
+ DPRINT1("bmAttributes %x\n", EndpointDescriptor->bmAttributes);
+ DPRINT1("wMaxPacketSize %x\n", EndpointDescriptor->wMaxPacketSize);
+ DPRINT1("bInterval %x\n", EndpointDescriptor->bInterval);
+ }
+
+ InterfaceDescriptor += sizeof(USB_ENDPOINT_DESCRIPTOR);
+ }
+
+}
+
+VOID
+WorkerThread(IN PVOID Context)
+{
+ PHUB_DEVICE_EXTENSION DeviceExtension;
+ PDEVICE_OBJECT DeviceObject = (PDEVICE_OBJECT)Context, Pdo;
+ PHUB_CHILDDEVICE_EXTENSION PdoExtension;
+ PURB Urb;
+ PORTSTATUSANDCHANGE PortStatusAndChange;
+ int PortLoop, DeviceCount;
+ NTSTATUS Status;
+ USB_DEVICE_DESCRIPTOR DevDesc;
+ USB_CONFIGURATION_DESCRIPTOR ConfigDesc;
+ ULONG DevDescSize, ConfigDescSize;
+ PUSB_STRING_DESCRIPTOR StringDesc;
+ USB_LANGUAGEID_DESCRIPTOR LanguageIdDescriptor;
+
+ DeviceExtension = (PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+
+ /* Determine where in the children array to store this device info */
+ for (DeviceCount = 0; DeviceCount < USB_MAXCHILDREN; DeviceCount++)
+ {
+ if (DeviceExtension->UsbChildren[DeviceCount] == NULL)
+ {
+ break;
+ }
+ }
+
+ DPRINT("Storing Device Info at %x\n", DeviceCount);
+ Urb = ExAllocatePoolWithTag(NonPagedPool, sizeof(URB), USB_HUB_TAG);
+ if (!Urb)
+ {
+ DPRINT1("Failed to allocate memory for URB!\n");
+ ASSERT(FALSE);
+ }
+
+ RtlZeroMemory(Urb, sizeof(URB));
+
+ for (PortLoop = 0; PortLoop < DeviceExtension->UsbExtHubInfo.NumberOfPorts; PortLoop++)
+ {
+ /* Get the port status */
+ UsbBuildVendorRequest(Urb,
+ URB_FUNCTION_CLASS_OTHER,
+ sizeof(Urb->UrbControlVendorClassRequest),
+ USBD_TRANSFER_DIRECTION_OUT,
+ 0,
+ USB_REQUEST_GET_STATUS,
+ 0,
+ PortLoop + 1,
+ &PortStatusAndChange,
+ 0,
+ sizeof(PORTSTATUSANDCHANGE),
+ 0);
+ Status = QueryRootHub(DeviceObject, IOCTL_INTERNAL_USB_SUBMIT_URB, Urb, NULL);
+
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to get PortStatus!\n");
+ return;
+ }
+
+ DPRINT("Notification Port %x:\n", PortLoop + 1);
+ DPRINT("Status %x\n", PortStatusAndChange.Status);
+ DPRINT("Change %x\n", PortStatusAndChange.Change);
+
+ if (PortStatusAndChange.Change == USB_PORT_STATUS_RESET)
+ {
+ /* Clear the Reset */
+ UsbBuildVendorRequest(Urb,
+ URB_FUNCTION_CLASS_OTHER,
+ sizeof(Urb->UrbControlVendorClassRequest),
+ USBD_TRANSFER_DIRECTION_IN,
+ 0,
+ USB_REQUEST_CLEAR_FEATURE,
+ C_PORT_RESET,
+ PortLoop + 1,
+ &PortStatusAndChange,
+ 0,
+ sizeof(PORTSTATUSANDCHANGE),
+ 0);
+
+ Status = QueryRootHub(DeviceObject, IOCTL_INTERNAL_USB_SUBMIT_URB, Urb, NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to Clear the Port Reset with Status %x!\n", Status);
+ return;
+ }
+ UsbBuildVendorRequest(Urb, URB_FUNCTION_CLASS_OTHER,
+ sizeof(Urb->UrbControlVendorClassRequest),
+ USBD_TRANSFER_DIRECTION_OUT,
+ 0,
+ USB_REQUEST_GET_STATUS,
+ 0,
+ PortLoop + 1,
+ &PortStatusAndChange,
+ 0,
+ sizeof(PORTSTATUSANDCHANGE),
+ 0);
+
+ Status = QueryRootHub(DeviceObject, IOCTL_INTERNAL_USB_SUBMIT_URB, Urb, NULL);
+
+ DPRINT("Status %x\n", PortStatusAndChange.Status);
+ DPRINT("Change %x\n", PortStatusAndChange.Change);
+
+ /* Create the UsbDevice */
+ Status = DeviceExtension->HubInterface.CreateUsbDevice(DeviceExtension->RootHubPdo,
+ (PVOID)&DeviceExtension->UsbChildren[DeviceCount],
+ DeviceExtension->RootHubUsbDevice,
+ PortStatusAndChange.Status,
+ PortLoop + 1);
+ DPRINT1("CreateUsbDevice Status %x\n", Status);
+
+ Status = DeviceExtension->HubInterface.InitializeUsbDevice(DeviceExtension->RootHubPdo, DeviceExtension->UsbChildren[DeviceCount]);
+ DPRINT1("InitializeUsbDevice Status %x\n", Status);
+
+ DevDescSize = sizeof(USB_DEVICE_DESCRIPTOR);
+ ConfigDescSize = sizeof(USB_CONFIGURATION_DESCRIPTOR);
+ Status = DeviceExtension->HubInterface.GetUsbDescriptors(DeviceExtension->RootHubPdo,
+ DeviceExtension->UsbChildren[DeviceCount],
+ (PUCHAR)&DevDesc,
+ &DevDescSize,
+ (PUCHAR)&ConfigDesc,
+ &ConfigDescSize);
+
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to Get Usb Deccriptors %x!\n", Status);
+ }
+
+ DumpDeviceDescriptor(&DevDesc);
+
+ Status = IoCreateDevice(DeviceObject->DriverObject,
+ sizeof(HUB_CHILDDEVICE_EXTENSION),
+ NULL,
+ FILE_DEVICE_CONTROLLER,
+ FILE_AUTOGENERATED_DEVICE_NAME,
+ FALSE,
+ &DeviceExtension->Children[DeviceCount]);
+
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("UsbHub; IoCreateDevice failed with status %x\n",Status);
+ return;
+ }
+
+ Pdo = DeviceExtension->Children[DeviceCount];
+ DPRINT1("Created New Device with %x\n", Pdo);
+ Pdo->Flags |= DO_BUS_ENUMERATED_DEVICE;
+
+ PdoExtension = Pdo->DeviceExtension;
+
+ RtlZeroMemory(PdoExtension, sizeof(HUB_CHILDDEVICE_EXTENSION));
+
+ PdoExtension->DeviceId = ExAllocatePoolWithTag(NonPagedPool, 32 * sizeof(WCHAR), USB_HUB_TAG);
+ RtlZeroMemory(PdoExtension->DeviceId, 32 * sizeof(WCHAR));
+ swprintf(PdoExtension->DeviceId, L"USB\\Vid_%04x&Pid_%04x", DevDesc.idVendor, DevDesc.idProduct);
+
+
+ /* Get the LANGids */
+ RtlZeroMemory(&LanguageIdDescriptor, sizeof(USB_LANGUAGEID_DESCRIPTOR));
+ UsbBuildGetDescriptorRequest(Urb,
+ sizeof(Urb->UrbControlDescriptorRequest),
+ USB_STRING_DESCRIPTOR_TYPE,
+ 0,
+ 0,
+ &LanguageIdDescriptor,
+ NULL,
+ sizeof(USB_LANGUAGEID_DESCRIPTOR),
+ NULL);
+
+ Urb->UrbHeader.UsbdDeviceHandle = DeviceExtension->UsbChildren[DeviceCount];
+
+ Status = QueryRootHub(DeviceExtension->RootHubPdo, IOCTL_INTERNAL_USB_SUBMIT_URB, Urb, NULL);
+
+ /* Get the length of the SerialNumber */
+ StringDesc = ExAllocatePoolWithTag(PagedPool, 64, USB_HUB_TAG);
+ RtlZeroMemory(StringDesc, 64);
+ StringDesc->bLength = 0;
+ StringDesc->bDescriptorType = 0;
+
+ UsbBuildGetDescriptorRequest(Urb,
+ sizeof(Urb->UrbControlDescriptorRequest),
+ USB_STRING_DESCRIPTOR_TYPE,
+ DevDesc.iSerialNumber,
+ LanguageIdDescriptor.wLANGIDs[0],
+ StringDesc,
+ NULL,
+ 64,
+ NULL);
+
+ Urb->UrbHeader.UsbdDeviceHandle = DeviceExtension->UsbChildren[DeviceCount];
+
+ Status = QueryRootHub(DeviceExtension->RootHubPdo, IOCTL_INTERNAL_USB_SUBMIT_URB, Urb, NULL);
+
+ PdoExtension->InstanceId = ExAllocatePoolWithTag(NonPagedPool, (StringDesc->bLength + 1) * sizeof(WCHAR), USB_HUB_TAG);
+ DPRINT1("PdoExtension->InstanceId %x\n",PdoExtension->InstanceId);
+
+ RtlZeroMemory(PdoExtension->InstanceId, (StringDesc->bLength + 1) * sizeof(WCHAR));
+ RtlCopyMemory(PdoExtension->InstanceId, &StringDesc->bString[0], StringDesc->bLength);
+ DPRINT1("------>SerialNumber %S\n", PdoExtension->InstanceId);
+
+
+
+ RtlZeroMemory(StringDesc, 64);
+ StringDesc->bLength = 0;
+ StringDesc->bDescriptorType = 0;
+
+ UsbBuildGetDescriptorRequest(Urb,
+ sizeof(Urb->UrbControlDescriptorRequest),
+ USB_STRING_DESCRIPTOR_TYPE,
+ DevDesc.iProduct,
+ LanguageIdDescriptor.wLANGIDs[0],
+ StringDesc,
+ NULL,
+ 64,
+ NULL);
+
+ Urb->UrbHeader.UsbdDeviceHandle = DeviceExtension->UsbChildren[DeviceCount];
+
+ Status = QueryRootHub(DeviceExtension->RootHubPdo, IOCTL_INTERNAL_USB_SUBMIT_URB, Urb, NULL);
+
+ PdoExtension->TextDescription = ExAllocatePoolWithTag(NonPagedPool, (StringDesc->bLength + 1) * sizeof(WCHAR), USB_HUB_TAG);
+
+ RtlZeroMemory(PdoExtension->TextDescription, (StringDesc->bLength + 1) * sizeof(WCHAR));
+ RtlCopyMemory(PdoExtension->TextDescription, &StringDesc->bString[0], StringDesc->bLength);
+ ExFreePool(StringDesc);
+ DPRINT1("------>TextDescription %S\n", PdoExtension->TextDescription);
+
+ PdoExtension->IsFDO = FALSE;
+ PdoExtension->Parent = DeviceObject;
+ Pdo->Flags &= ~DO_DEVICE_INITIALIZING;
+
+ IoInvalidateDeviceRelations(DeviceExtension->RootHubPdo, BusRelations);
+ return;
+ }
+
+ /* Is a device connected to this port */
+ if (PortStatusAndChange.Change == USB_PORT_STATUS_CONNECT)
+ {
+ /* Clear the Connect from ProtChange */
+ UsbBuildVendorRequest(Urb,
+ URB_FUNCTION_CLASS_OTHER,
+ sizeof(Urb->UrbControlVendorClassRequest),
+ USBD_TRANSFER_DIRECTION_IN,
+ 0,
+ USB_REQUEST_CLEAR_FEATURE,
+ C_PORT_CONNECTION,
+ PortLoop + 1,
+ &PortStatusAndChange,
+ 0,
+ sizeof(PORTSTATUSANDCHANGE),
+ 0);
+
+ Status = QueryRootHub(DeviceObject, IOCTL_INTERNAL_USB_SUBMIT_URB, Urb, NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to Clear the Port Connect!\n");
+ return;
+ }
+
+ /* Send the miniport controller a SCE request so when the port resets we can be informed */
+ WaitForUsbDeviceArrivalNotification(DeviceObject);
+
+ UsbBuildVendorRequest(Urb,
+ URB_FUNCTION_CLASS_OTHER,
+ sizeof(Urb->UrbControlVendorClassRequest),
+ USBD_TRANSFER_DIRECTION_IN,
+ 0,
+ USB_REQUEST_SET_FEATURE,
+ PORT_RESET,
+ PortLoop + 1,
+ &PortStatusAndChange,
+ 0,
+ sizeof(PORTSTATUSANDCHANGE),
+ 0);
+
+ Status = QueryRootHub(DeviceObject, IOCTL_INTERNAL_USB_SUBMIT_URB, Urb, NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to Reset the port!\n");
+ return;
+ }
+ /* At this point the miniport will complete another SCE to inform of Reset completed */
+ }
+ }
+}
+
+NTSTATUS
+DeviceArrivalCompletion(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)
+{
+ PHUB_DEVICE_EXTENSION DeviceExtension;
+ LONG i;
+
+ DeviceExtension = (PHUB_DEVICE_EXTENSION)((PDEVICE_OBJECT)Context)->DeviceExtension;
+
+ for (i=0; i < DeviceExtension->UsbExtHubInfo.NumberOfPorts; i++)
+ DPRINT1("Port %x DeviceExtension->PortStatus %x\n",i+1, DeviceExtension->PortStatus[i]);
+
+ if (Irp->PendingReturned)
+ IoMarkIrpPending(Irp);
+
+ ExInitializeWorkItem(&DeviceExtension->WorkItem, (PWORKER_THREAD_ROUTINE)WorkerThread, Context);
+ ExQueueWorkItem(&DeviceExtension->WorkItem, DelayedWorkQueue);
+ return STATUS_SUCCESS;
+}
+
+
+NTSTATUS
+WaitForUsbDeviceArrivalNotification(PDEVICE_OBJECT DeviceObject)
+{
+ PURB Urb;
+ PIRP Irp;
+ NTSTATUS Status;
+ PIO_STACK_LOCATION Stack = NULL;
+ IO_STATUS_BLOCK IoStatus;
+ PHUB_DEVICE_EXTENSION DeviceExtension;
+
+ DeviceExtension = (PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+
+ Urb = ExAllocatePoolWithTag(NonPagedPool, sizeof(URB), USB_HUB_TAG);
+
+ /* Send URB to the miniports Status Change Endpoint SCE */
+ UsbBuildInterruptOrBulkTransferRequest(Urb,
+ sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER),
+ DeviceExtension->PipeHandle,
+ &DeviceExtension->PortStatus,
+ NULL,
+ sizeof(ULONG) * 2,
+ USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK,
+ NULL);
+
+ Urb->UrbHeader.UsbdDeviceHandle = DeviceExtension->RootHubUsbDevice;
+
+ Irp = IoBuildDeviceIoControlRequest(IOCTL_INTERNAL_USB_SUBMIT_URB,
+ DeviceExtension->RootHubPdo,
+ NULL, 0,
+ NULL, 0,
+ TRUE,
+ NULL,
+ &IoStatus);
+
+ if (Irp == NULL)
+ {
+ DPRINT("Usbhub: IoBuildDeviceIoControlRequest() failed\n");
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ /* Initialize the status block before sending the IRP */
+ IoStatus.Status = STATUS_NOT_SUPPORTED;
+ IoStatus.Information = 0;
+
+ Stack = IoGetNextIrpStackLocation(Irp);
+
+ Stack->Parameters.Others.Argument1 = Urb;
+ Stack->Parameters.Others.Argument2 = NULL;
+
+ //IoSetCompletionRoutineEx(DeviceExtension->RootHubPdo, Irp, (PIO_COMPLETION_ROUTINE)DeviceArrivalCompletion, DeviceObject, TRUE, TRUE, TRUE);
+ IoSetCompletionRoutine(Irp, (PIO_COMPLETION_ROUTINE)DeviceArrivalCompletion, DeviceObject, TRUE, TRUE, TRUE);
+
+ Status = IoCallDriver(DeviceExtension->RootHubPdo, Irp);
+
+ return STATUS_MORE_PROCESSING_REQUIRED;
+
+}
+
+NTSTATUS
+QueryRootHub(IN PDEVICE_OBJECT Pdo, IN ULONG IoControlCode, OUT PVOID OutParameter1, OUT PVOID OutParameter2)
+{
+ KEVENT Event;
+ PIRP Irp;
+ IO_STATUS_BLOCK IoStatus;
+ NTSTATUS Status;
+ PIO_STACK_LOCATION Stack = NULL;
+
+ KeInitializeEvent(&Event, NotificationEvent, FALSE);
+
+ Irp = IoBuildDeviceIoControlRequest(IoControlCode,
+ Pdo,
+ NULL, 0,
+ NULL, 0,
+ TRUE,
+ &Event,
+ &IoStatus);
+
+ if (Irp == NULL)
+ {
+ DPRINT("Usbhub: IoBuildDeviceIoControlRequest() failed\n");
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ /* Initialize the status block before sending the IRP */
+ IoStatus.Status = STATUS_NOT_SUPPORTED;
+ IoStatus.Information = 0;
+
+ Stack = IoGetNextIrpStackLocation(Irp);
+
+ Stack->Parameters.Others.Argument1 = OutParameter1;
+ Stack->Parameters.Others.Argument2 = OutParameter2;
+
+ Status = IoCallDriver(Pdo, Irp);
+
+ if (Status == STATUS_PENDING)
+ {
+ DPRINT1("Usbhub: Operation pending\n");
+ KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL);
+ Status = IoStatus.Status;
+ }
+
+ return Status;
+}
+
+NTSTATUS QueryInterface(IN PDEVICE_OBJECT Pdo, IN CONST GUID InterfaceType, IN LONG Size, IN LONG Version, OUT PVOID Interface)
+{
+ KEVENT Event;
+ PIRP Irp;
+ IO_STATUS_BLOCK IoStatus;
+ NTSTATUS Status;
+ PIO_STACK_LOCATION Stack = NULL;
+
+ KeInitializeEvent(&Event, NotificationEvent, FALSE);
+
+ Irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP,
+ Pdo,
+ NULL,
+ 0,
+ NULL,
+ &Event,
+ &IoStatus);
+
+ Stack = IoGetNextIrpStackLocation(Irp);
+ Stack->MinorFunction = IRP_MN_QUERY_INTERFACE;
+ Stack->Parameters.QueryInterface.InterfaceType= &InterfaceType;//USB_BUS_INTERFACE_HUB_GUID;
+ Stack->Parameters.QueryInterface.Size = Size;
+ Stack->Parameters.QueryInterface.Version = Version;
+ Stack->Parameters.QueryInterface.Interface = Interface;
+ Stack->Parameters.QueryInterface.InterfaceSpecificData = NULL;
+
+ Status = IoCallDriver(Pdo, Irp);
+
+ if (Status == STATUS_PENDING)
+ {
+ DPRINT("Usbhub: Operation pending\n");
+ KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL);
+ Status = IoStatus.Status;
+ }
+
+ return Status;
+}
+
static VOID
-UsbhubGetUserBuffers(
- IN PIRP Irp,
- IN ULONG IoControlCode,
- OUT PVOID* BufferIn,
- OUT PVOID* BufferOut)
+UsbhubGetUserBuffers(IN PIRP Irp, IN ULONG IoControlCode, OUT PVOID* BufferIn, OUT PVOID* BufferOut)
{
- ASSERT(Irp);
- ASSERT(BufferIn);
- ASSERT(BufferOut);
-
- switch (IO_METHOD_FROM_CTL_CODE(IoControlCode))
- {
- case METHOD_BUFFERED:
- *BufferIn = *BufferOut = Irp->AssociatedIrp.SystemBuffer;
- break;
- case METHOD_IN_DIRECT:
- case METHOD_OUT_DIRECT:
- *BufferIn = Irp->AssociatedIrp.SystemBuffer;
- *BufferOut = MmGetSystemAddressForMdl(Irp->MdlAddress);
- break;
- case METHOD_NEITHER:
- *BufferIn = IoGetCurrentIrpStackLocation(Irp)->Parameters.DeviceIoControl.Type3InputBuffer;
- *BufferOut = Irp->UserBuffer;
- break;
- default:
- /* Should never happen */
- *BufferIn = NULL;
- *BufferOut = NULL;
- break;
- }
+ ASSERT(Irp);
+ ASSERT(BufferIn);
+ ASSERT(BufferOut);
+
+ switch (IO_METHOD_FROM_CTL_CODE(IoControlCode))
+ {
+ case METHOD_BUFFERED:
+ *BufferIn = *BufferOut = Irp->AssociatedIrp.SystemBuffer;
+ break;
+ case METHOD_IN_DIRECT:
+ case METHOD_OUT_DIRECT:
+ *BufferIn = Irp->AssociatedIrp.SystemBuffer;
+ *BufferOut = MmGetSystemAddressForMdl(Irp->MdlAddress);
+ break;
+ case METHOD_NEITHER:
+ *BufferIn = IoGetCurrentIrpStackLocation(Irp)->Parameters.DeviceIoControl.Type3InputBuffer;
+ *BufferOut = Irp->UserBuffer;
+ break;
+ default:
+ /* Should never happen */
+ *BufferIn = NULL;
+ *BufferOut = NULL;
+ break;
+ }
}
-static NTSTATUS
-UsbhubFdoQueryBusRelations(
- IN PDEVICE_OBJECT DeviceObject,
- OUT PDEVICE_RELATIONS* pDeviceRelations)
+NTSTATUS
+UsbhubFdoQueryBusRelations(IN PDEVICE_OBJECT DeviceObject, OUT PDEVICE_RELATIONS* pDeviceRelations)
{
- PHUB_DEVICE_EXTENSION DeviceExtension;
- PDEVICE_RELATIONS DeviceRelations;
- PDEVICE_OBJECT Pdo;
- PHUB_DEVICE_EXTENSION PdoExtension;
- struct usb_device* dev;
- ULONG i;
- ULONG Children = 0;
- ULONG NeededSize;
- NTSTATUS Status;
- CHAR Buffer[3][40];
-
- DeviceExtension = (PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
- dev = DeviceExtension->dev;
-
- /* Create PDOs that are missing */
- for (i = 0; i < dev->maxchild; i++)
- {
- if (dev->children[i] == NULL)
- {
- /* No child device at this place */
- continue;
- }
- Children++;
- if (DeviceExtension->Children[i] != NULL)
- {
- /* PDO already exists */
- continue;
- }
- /* Need to create the PDO */
- Status = IoCreateDevice(
- DeviceObject->DriverObject,
- sizeof(HUB_DEVICE_EXTENSION),
- NULL, /* Device name */
- FILE_DEVICE_CONTROLLER,
- FILE_AUTOGENERATED_DEVICE_NAME,
- FALSE,
- &DeviceExtension->Children[i]);
- if (!NT_SUCCESS(Status))
- {
- DPRINT("Usbhub: IoCreateDevice() failed with status 0x%08lx\n", Status);
- return Status;
- }
-
- Pdo = DeviceExtension->Children[i];
- Pdo->Flags |= DO_BUS_ENUMERATED_DEVICE;
-
- PdoExtension = Pdo->DeviceExtension;
- RtlZeroMemory(PdoExtension, sizeof(HUB_DEVICE_EXTENSION));
-
- PdoExtension->IsFDO = FALSE;
- PdoExtension->dev = dev->children[i];
-
- sprintf(Buffer[0], "%lu", i);
- Status = UsbhubInitMultiSzString(
- &PdoExtension->InstanceId,
- Buffer[0], NULL);
- if (!NT_SUCCESS(Status))
- goto ByeBye;
-
- DPRINT1("child #%lu: USB\\Vid_%04x&Pid_%04x&Rev_%04x\n",
- i,
- PdoExtension->dev->descriptor.idVendor,
- PdoExtension->dev->descriptor.idProduct,
- PdoExtension->dev->descriptor.bcdDevice);
- sprintf(Buffer[0], "USB\\Vid_%04x&Pid_%04x&Rev_%04x",
- PdoExtension->dev->descriptor.idVendor,
- PdoExtension->dev->descriptor.idProduct,
- PdoExtension->dev->descriptor.bcdDevice);
- sprintf(Buffer[1], "USB\\Vid_%04x&Pid_%04x",
- PdoExtension->dev->descriptor.idVendor,
- PdoExtension->dev->descriptor.idProduct);
- Status = UsbhubInitMultiSzString(
- &PdoExtension->HardwareIds,
- Buffer[0], Buffer[1], NULL);
- if (!NT_SUCCESS(Status))
- goto ByeBye;
-
- Status = UsbhubInitMultiSzString(
- &PdoExtension->DeviceId,
- Buffer[1], NULL);
- if (!NT_SUCCESS(Status))
- goto ByeBye;
-
- if (PdoExtension->dev->actconfig->desc.bNumInterfaces == 1)
- {
- /* Single-interface USB device */
- if (PdoExtension->dev->descriptor.bDeviceClass != 0)
- {
- /* Use these values for device class/sub class/protocol */
- sprintf(Buffer[0], "USB\\Class_%02x&SubClass_%02x&Prot_%02x",
- PdoExtension->dev->descriptor.bDeviceClass,
- PdoExtension->dev->descriptor.bDeviceSubClass,
- PdoExtension->dev->descriptor.bDeviceProtocol);
- sprintf(Buffer[1], "USB\\Class_%02x&SubClass_%02x",
- PdoExtension->dev->descriptor.bDeviceClass,
- PdoExtension->dev->descriptor.bDeviceSubClass);
- sprintf(Buffer[2], "USB\\Class_%02x",
- PdoExtension->dev->descriptor.bDeviceClass);
- }
- else
- {
- /* Use values specified in the interface descriptor */
- struct usb_host_interface *itf = PdoExtension->dev->actconfig->interface->altsetting;
- sprintf(Buffer[0], "USB\\Class_%02x&SubClass_%02x&Prot_%02x",
- itf->desc.bInterfaceClass,
- itf->desc.bInterfaceSubClass,
- itf->desc.bInterfaceProtocol);
- sprintf(Buffer[1], "USB\\Class_%02x&SubClass_%02x",
- itf->desc.bInterfaceClass,
- itf->desc.bInterfaceSubClass);
- sprintf(Buffer[2], "USB\\Class_%02x",
- itf->desc.bInterfaceClass);
- }
- Status = UsbhubInitMultiSzString(
- &PdoExtension->CompatibleIds,
- Buffer[0], Buffer[1], Buffer[2], NULL);
- }
- else
- {
- /* Multiple-interface USB device */
- sprintf(Buffer[0], "USB\\DevClass_%02x&SubClass_%02x&Prot_%02x",
- PdoExtension->dev->descriptor.bDeviceClass,
- PdoExtension->dev->descriptor.bDeviceSubClass,
- PdoExtension->dev->descriptor.bDeviceProtocol);
- sprintf(Buffer[1], "USB\\DevClass_%02x&SubClass_%02x",
- PdoExtension->dev->descriptor.bDeviceClass,
- PdoExtension->dev->descriptor.bDeviceSubClass);
- sprintf(Buffer[2], "USB\\DevClass_%02x",
- PdoExtension->dev->descriptor.bDeviceClass);
- Status = UsbhubInitMultiSzString(
- &PdoExtension->CompatibleIds,
- Buffer[0], Buffer[1], Buffer[2], "USB\\COMPOSITE", NULL);
- }
-
- if (!NT_SUCCESS(Status))
- goto ByeBye;
-
- Pdo->Flags &= ~DO_DEVICE_INITIALIZING;
- }
-
- /* Fill returned structure */
- NeededSize = sizeof(DEVICE_RELATIONS);
- if (Children > 1)
- NeededSize += (Children - 1) * sizeof(PDEVICE_OBJECT);
- DeviceRelations = (PDEVICE_RELATIONS)ExAllocatePool(
- PagedPool,
- NeededSize);
- if (!DeviceRelations)
- return STATUS_INSUFFICIENT_RESOURCES;
- DeviceRelations->Count = Children;
- Children = 0;
- for (i = 0; i < USB_MAXCHILDREN; i++)
- {
- if (DeviceExtension->Children[i])
- {
- ObReferenceObject(DeviceExtension->Children[i]);
- DeviceRelations->Objects[Children++] = DeviceExtension->Children[i];
- }
- }
- ASSERT(Children == DeviceRelations->Count);
-
- *pDeviceRelations = DeviceRelations;
- return STATUS_SUCCESS;
-
-ByeBye:
- RtlFreeUnicodeString(&PdoExtension->DeviceId);
- RtlFreeUnicodeString(&PdoExtension->InstanceId);
- RtlFreeUnicodeString(&PdoExtension->HardwareIds);
- RtlFreeUnicodeString(&PdoExtension->CompatibleIds);
- IoDeleteDevice(Pdo);
- return Status;
+ PHUB_DEVICE_EXTENSION DeviceExtension;
+ PDEVICE_RELATIONS DeviceRelations;
+ ULONG i;
+ ULONG Children = 0;
+ ULONG NeededSize;
+
+ DeviceExtension = (PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+ DPRINT1("USBHUB: Query Bus Relations\n");
+
+ /* Create PDOs that are missing */
+ for (i = 0; i < USB_MAXCHILDREN; i++)
+ {
+
+ if (DeviceExtension->UsbChildren[i] == NULL)
+ {
+ continue;
+ }
+ Children++;
+ }
+
+ /* Fill returned structure */
+ NeededSize = sizeof(DEVICE_RELATIONS);
+ if (Children > 1)
+ NeededSize += (Children - 1) * sizeof(PDEVICE_OBJECT);
+
+ DeviceRelations = (PDEVICE_RELATIONS)ExAllocatePool(PagedPool,
+ NeededSize);
+
+ if (!DeviceRelations)
+ return STATUS_INSUFFICIENT_RESOURCES;
+ DeviceRelations->Count = Children;
+ Children = 0;
+
+ for (i = 0; i < USB_MAXCHILDREN; i++)
+ {
+ if (DeviceExtension->Children[i])
+ {
+ ObReferenceObject(DeviceExtension->Children[i]);
+ DeviceRelations->Objects[Children++] = DeviceExtension->Children[i];
+ }
+ }
+
+ ASSERT(Children == DeviceRelations->Count);
+ *pDeviceRelations = DeviceRelations;
+
+ WaitForUsbDeviceArrivalNotification(DeviceObject);
+
+ return STATUS_SUCCESS;
}
NTSTATUS NTAPI
-UsbhubPnpFdo(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp)
+UsbhubPnpFdo(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
- PIO_STACK_LOCATION IrpSp;
- NTSTATUS Status;
- ULONG MinorFunction;
- ULONG_PTR Information = 0;
-
- IrpSp = IoGetCurrentIrpStackLocation(Irp);
- MinorFunction = IrpSp->MinorFunction;
-
- switch (MinorFunction)
- {
- case IRP_MN_START_DEVICE: /* 0x0 */
- {
- DPRINT("Usbhub: IRP_MJ_PNP / IRP_MN_START_DEVICE\n");
- Status = ForwardIrpAndWait(DeviceObject, Irp);
- break;
- }
-
- case IRP_MN_QUERY_DEVICE_RELATIONS: /* (optional) 0x7 */
- {
- switch (IrpSp->Parameters.QueryDeviceRelations.Type)
- {
- case BusRelations:
- {
- PDEVICE_RELATIONS DeviceRelations = NULL;
- DPRINT("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / BusRelations\n");
- Status = UsbhubFdoQueryBusRelations(DeviceObject, &DeviceRelations);
- Information = (ULONG_PTR)DeviceRelations;
- break;
- }
- case RemovalRelations:
- {
- DPRINT1("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / RemovalRelations\n");
- return ForwardIrpAndForget(DeviceObject, Irp);
- }
- default:
- DPRINT1("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / Unknown type 0x%lx\n",
- IrpSp->Parameters.QueryDeviceRelations.Type);
- return ForwardIrpAndForget(DeviceObject, Irp);
- }
- break;
- }
-
- default:
- {
- DPRINT1("Usbhub: IRP_MJ_PNP / unknown minor function 0x%lx\n", MinorFunction);
- return ForwardIrpAndForget(DeviceObject, Irp);
- }
- }
- Irp->IoStatus.Information = Information;
- Irp->IoStatus.Status = Status;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return Status;
+ PIO_STACK_LOCATION IrpSp;
+ NTSTATUS Status = STATUS_SUCCESS;
+ ULONG MinorFunction;
+ ULONG_PTR Information = 0;
+ PHUB_DEVICE_EXTENSION DeviceExtension;
+
+ IrpSp = IoGetCurrentIrpStackLocation(Irp);
+ MinorFunction = IrpSp->MinorFunction;
+
+ DeviceExtension = (PHUB_DEVICE_EXTENSION) DeviceObject->DeviceExtension;
+
+ switch (MinorFunction)
+ {
+ case IRP_MN_START_DEVICE: /* 0x0 */
+ {
+ PURB Urb;
+ ULONG Result = 0;
+
+ /* We differ from windows on hubpdo because we dont have usbport.sys which manages all usb device objects */
+ DPRINT1("Usbhub: IRP_MJ_PNP / IRP_MN_START_DEVICE\n");
+
+ /* Allocating size including the sizeof USBD_INTERFACE_LIST_ENTRY */
+ Urb = ExAllocatePoolWithTag(NonPagedPool, sizeof(URB) + sizeof(USBD_INTERFACE_LIST_ENTRY), USB_HUB_TAG);
+ RtlZeroMemory(Urb, sizeof(URB) + sizeof(USBD_INTERFACE_LIST_ENTRY));
+
+ /* Get the hubs PDO */
+ QueryRootHub(DeviceObject, IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO, &DeviceExtension->RootHubPdo, &DeviceExtension->RootHubFdo);
+ ASSERT(DeviceExtension->RootHubPdo);
+ ASSERT(DeviceExtension->RootHubFdo);
+ DPRINT1("RootPdo %x, RootFdo %x\n", DeviceExtension->RootHubPdo, DeviceExtension->RootHubFdo);
+
+ /* Send the START_DEVICE irp down to the PDO of RootHub */
+ Status = ForwardIrpAndWait(DeviceExtension->RootHubPdo, Irp);
+
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to start the RootHub PDO\n");
+ ASSERT(FALSE);
+ }
+
+ /* Get the current number of hubs */
+ QueryRootHub(DeviceExtension->RootHubPdo,IOCTL_INTERNAL_USB_GET_HUB_COUNT, &DeviceExtension->HubCount, NULL);
+
+ /* Get the Direct Call Interfaces */
+ Status = QueryInterface(DeviceExtension->RootHubPdo,
+ USB_BUS_INTERFACE_HUB_GUID,
+ sizeof(USB_BUS_INTERFACE_HUB_V5),
+ 5,
+ (PVOID)&DeviceExtension->HubInterface);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("UsbhubM Failed to get HUB_GUID interface with status 0x%08lx\n", Status);
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ Status = QueryInterface(DeviceExtension->RootHubPdo,
+ USB_BUS_INTERFACE_USBDI_GUID,
+ sizeof(USB_BUS_INTERFACE_USBDI_V2),
+ 2,
+ (PVOID)&DeviceExtension->UsbDInterface);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("UsbhubM Failed to get USBDI_GUID interface with status 0x%08lx\n", Status);
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ /* Get roothub device handle */
+ Status = QueryRootHub(DeviceExtension->RootHubPdo, IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE, &DeviceExtension->RootHubUsbDevice, NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Usbhub: GetRootHubDeviceHandle failed with status 0x%08lx\n", Status);
+ return Status;
+ }
+
+ /* FIXME: This gets nothing from MS miniport */
+ Status = DeviceExtension->HubInterface.QueryDeviceInformation(DeviceExtension->RootHubPdo,
+ DeviceExtension->RootHubUsbDevice,
+ &DeviceExtension->DeviceInformation,
+ sizeof(USB_DEVICE_INFORMATION_0),
+ &Result);
+
+
+ DPRINT("Status %x, Result %x\n", Status, Result);
+ DPRINT("InformationLevel %x\n", DeviceExtension->DeviceInformation.InformationLevel);
+ DPRINT("ActualLength %x\n", DeviceExtension->DeviceInformation.ActualLength);
+ DPRINT("PortNumber %x\n", DeviceExtension->DeviceInformation.PortNumber);
+ DPRINT("DeviceDescriptor %x\n", DeviceExtension->DeviceInformation.DeviceDescriptor);
+ DPRINT("HubAddress %x\n", DeviceExtension->DeviceInformation.HubAddress);
+ DPRINT("NumberofPipes %x\n", DeviceExtension->DeviceInformation.NumberOfOpenPipes);
+
+ /* Get roothubs device descriptor */
+ UsbBuildGetDescriptorRequest(Urb,
+ sizeof(Urb->UrbControlDescriptorRequest),
+ USB_DEVICE_DESCRIPTOR_TYPE,
+ 0,
+ 0,
+ &DeviceExtension->HubDeviceDescriptor,
+ NULL,
+ sizeof(USB_DEVICE_DESCRIPTOR),
+ NULL);
+
+ Urb->UrbHeader.UsbdDeviceHandle = DeviceExtension->RootHubUsbDevice;
+
+ Status = QueryRootHub(DeviceExtension->RootHubPdo, IOCTL_INTERNAL_USB_SUBMIT_URB, Urb, NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Usbhub: Failed to get HubDeviceDescriptor!\n");
+ }
+
+ DumpDeviceDescriptor(&DeviceExtension->HubDeviceDescriptor);
+
+ /* Get roothubs configuration descriptor */
+ UsbBuildGetDescriptorRequest(Urb,
+ sizeof(Urb->UrbControlDescriptorRequest),
+ USB_CONFIGURATION_DESCRIPTOR_TYPE,
+ 0,
+ 0,
+ &DeviceExtension->HubConfigDescriptor,
+ NULL,
+ sizeof(USB_CONFIGURATION_DESCRIPTOR) + sizeof(USB_INTERFACE_DESCRIPTOR) + sizeof(USB_ENDPOINT_DESCRIPTOR),
+ NULL);
+ Urb->UrbHeader.UsbdDeviceHandle = DeviceExtension->RootHubUsbDevice;
+
+ Status = QueryRootHub(DeviceExtension->RootHubPdo, IOCTL_INTERNAL_USB_SUBMIT_URB, Urb, NULL);
+
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Usbhub: Failed to get RootHub Configuration with status %x\n", Status);
+ ASSERT(FALSE);
+ }
+ ASSERT(DeviceExtension->HubConfigDescriptor.wTotalLength);
+
+ DumpFullConfigurationDescriptor(&DeviceExtension->HubConfigDescriptor);
+ //DPRINT1("DeviceExtension->HubConfigDescriptor.wTotalLength %x\n", DeviceExtension->HubConfigDescriptor.wTotalLength);
+
+ Status = DeviceExtension->HubInterface.GetExtendedHubInformation(DeviceExtension->RootHubPdo,
+ DeviceExtension->RootHubPdo,
+ &DeviceExtension->UsbExtHubInfo,
+ sizeof(USB_EXTHUB_INFORMATION_0),
+ &Result);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Usbhub: Failed to extended hub information. Unable to determine the number of ports!\n");
+ ASSERT(FALSE);
+ }
+
+ DPRINT1("DeviceExtension->UsbExtHubInfo.NumberOfPorts %x\n", DeviceExtension->UsbExtHubInfo.NumberOfPorts);
+
+ UsbBuildVendorRequest(Urb,
+ URB_FUNCTION_CLASS_DEVICE,
+ sizeof(Urb->UrbControlVendorClassRequest),
+ USBD_TRANSFER_DIRECTION_IN,
+ 0,
+ USB_DEVICE_CLASS_RESERVED,
+ 0,
+ 0,
+ &DeviceExtension->HubDescriptor,
+ NULL,
+ sizeof(USB_HUB_DESCRIPTOR),
+ NULL);
+
+ Urb->UrbHeader.UsbdDeviceHandle = DeviceExtension->RootHubUsbDevice;
+
+ Status = QueryRootHub(DeviceExtension->RootHubPdo, IOCTL_INTERNAL_USB_SUBMIT_URB, Urb, NULL);
+
+ DPRINT1("bDescriptorType %x\n", DeviceExtension->HubDescriptor.bDescriptorType);
+
+ /* Select the configuration */
+ /* FIXME: Use USBD_CreateConfigurationRequestEx instead */
+ RtlZeroMemory(Urb, sizeof(URB));
+ UsbBuildSelectConfigurationRequest(Urb,
+ sizeof(Urb->UrbSelectConfiguration),
+ &DeviceExtension->HubConfigDescriptor);
+
+ Urb->UrbSelectConfiguration.Interface.Length = sizeof(USBD_INTERFACE_INFORMATION);
+ Urb->UrbSelectConfiguration.Interface.NumberOfPipes = 1;
+ Urb->UrbSelectConfiguration.Interface.Pipes[0].MaximumTransferSize = 4096;
+
+ Status = QueryRootHub(DeviceExtension->RootHubPdo, IOCTL_INTERNAL_USB_SUBMIT_URB, Urb, NULL);
+
+ DeviceExtension->ConfigurationHandle = Urb->UrbSelectConfiguration.ConfigurationHandle;
+ DeviceExtension->PipeHandle = Urb->UrbSelectConfiguration.Interface.Pipes[0].PipeHandle;
+ DPRINT1("Configuration Handle %x\n", DeviceExtension->ConfigurationHandle);
+
+ Status = DeviceExtension->HubInterface.Initialize20Hub(DeviceExtension->RootHubPdo, DeviceExtension->RootHubUsbDevice, 1);
+
+ DPRINT1("Status %x\n", Status);
+
+ {
+ int PortLoop;
+ USHORT PortStatusAndChange[2];
+
+ for (PortLoop=0; PortLoop< DeviceExtension->UsbExtHubInfo.NumberOfPorts; PortLoop++)
+ {
+ DPRINT1("Port %x\n", PortLoop);
+ UsbBuildVendorRequest(Urb,
+ URB_FUNCTION_CLASS_OTHER,
+ sizeof(Urb->UrbControlVendorClassRequest),
+ USBD_TRANSFER_DIRECTION_IN,
+ 0,
+ USB_REQUEST_SET_FEATURE,
+ PORT_POWER,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0);
+
+ Urb->UrbOSFeatureDescriptorRequest.MS_FeatureDescriptorIndex = PortLoop + 1;
+ Status = QueryRootHub(DeviceObject, IOCTL_INTERNAL_USB_SUBMIT_URB, Urb, NULL);
+
+ DPRINT1("Status %x\n", Status);
+
+ UsbBuildVendorRequest(Urb,
+ URB_FUNCTION_CLASS_OTHER,
+ sizeof(Urb->UrbControlVendorClassRequest),
+ USBD_TRANSFER_DIRECTION_OUT,
+ 0,
+ USB_REQUEST_GET_STATUS,
+ 0,
+ PortLoop + 1,
+ &PortStatusAndChange,
+ 0,
+ sizeof(PortStatusAndChange),
+ 0);
+ Status = QueryRootHub(DeviceObject, IOCTL_INTERNAL_USB_SUBMIT_URB, Urb, NULL);
+
+ DPRINT1("Status %x\n", Status);
+ DPRINT1("PortStatus = %x\n", PortStatusAndChange[0]);
+ DPRINT1("PortChange = %x\n", PortStatusAndChange[1]);
+ }
+ }
+
+ ExFreePool(Urb);
+ break;
+ }
+
+ case IRP_MN_QUERY_DEVICE_RELATIONS: /* (optional) 0x7 */
+ {
+ switch (IrpSp->Parameters.QueryDeviceRelations.Type)
+ {
+ case BusRelations:
+ {
+ PDEVICE_RELATIONS DeviceRelations = NULL;
+ DPRINT1("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / BusRelations\n");
+
+ Status = UsbhubFdoQueryBusRelations(DeviceObject, &DeviceRelations);
+
+ Information = (ULONG_PTR)DeviceRelations;
+ break;
+ }
+ case RemovalRelations:
+ {
+ DPRINT1("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / RemovalRelations\n");
+ return ForwardIrpAndForget(DeviceObject, Irp);
+ }
+ default:
+ DPRINT1("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / Unknown type 0x%lx\n",
+ IrpSp->Parameters.QueryDeviceRelations.Type);
+ return ForwardIrpAndForget(DeviceObject, Irp);
+ }
+ break;
+ }
+ case IRP_MN_QUERY_BUS_INFORMATION:
+ {
+ DPRINT1("IRP_MN_QUERY_BUS_INFORMATION\n");
+ break;
+ }
+ case IRP_MN_QUERY_ID:
+ {
+ DPRINT1("IRP_MN_QUERY_ID\n");
+ break;
+ }
+ case IRP_MN_QUERY_CAPABILITIES:
+ {
+ DPRINT1("IRP_MN_QUERY_CAPABILITIES\n");
+ break;
+ }
+ default:
+ {
+ DPRINT1("Usbhub: IRP_MJ_PNP / unknown minor function 0x%lx\n", MinorFunction);
+ return ForwardIrpAndForget(DeviceObject, Irp);
+ }
+ }
+ Irp->IoStatus.Information = Information;
+ Irp->IoStatus.Status = Status;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return Status;
}
NTSTATUS
-UsbhubDeviceControlFdo(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp)
+UsbhubDeviceControlFdo(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
- PIO_STACK_LOCATION Stack;
- ULONG IoControlCode;
- PHUB_DEVICE_EXTENSION DeviceExtension;
- ULONG LengthIn, LengthOut;
- ULONG_PTR Information = 0;
- PVOID BufferIn, BufferOut;
- NTSTATUS Status;
-
- Stack = IoGetCurrentIrpStackLocation(Irp);
- LengthIn = Stack->Parameters.DeviceIoControl.InputBufferLength;
- LengthOut = Stack->Parameters.DeviceIoControl.OutputBufferLength;
- DeviceExtension = (PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
- IoControlCode = Stack->Parameters.DeviceIoControl.IoControlCode;
- UsbhubGetUserBuffers(Irp, IoControlCode, &BufferIn, &BufferOut);
-
- switch (IoControlCode)
- {
- case IOCTL_USB_GET_NODE_INFORMATION:
- {
- PUSB_NODE_INFORMATION NodeInformation;
- struct usb_device* dev;
- DPRINT("Usbhub: IOCTL_USB_GET_NODE_INFORMATION\n");
- if (LengthOut < sizeof(USB_NODE_INFORMATION))
- Status = STATUS_BUFFER_TOO_SMALL;
- else if (BufferOut == NULL)
- Status = STATUS_INVALID_PARAMETER;
- else
- {
- NodeInformation = (PUSB_NODE_INFORMATION)BufferOut;
- dev = ((PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->dev;
- NodeInformation->NodeType = UsbHub;
- RtlCopyMemory(
- &NodeInformation->u.HubInformation.HubDescriptor,
- ((struct usb_hub *)usb_get_intfdata(to_usb_interface(&dev->actconfig->interface[0].dev)))->descriptor,
- sizeof(USB_HUB_DESCRIPTOR));
- NodeInformation->u.HubInformation.HubIsBusPowered = dev->actconfig->desc.bmAttributes & 0x80;
- Information = sizeof(USB_NODE_INFORMATION);
- Status = STATUS_SUCCESS;
- }
- break;
- }
- case IOCTL_USB_GET_NODE_CONNECTION_NAME:
- {
- PHUB_DEVICE_EXTENSION DeviceExtension;
- PUSB_NODE_CONNECTION_NAME ConnectionName;
- DeviceExtension = (PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
- ConnectionName = (PUSB_NODE_CONNECTION_NAME)BufferOut;
-
- DPRINT("Usbhub: IOCTL_USB_GET_NODE_CONNECTION_NAME\n");
- if (LengthOut < sizeof(USB_NODE_CONNECTION_NAME))
- Status = STATUS_BUFFER_TOO_SMALL;
- else if (BufferOut == NULL)
- Status = STATUS_INVALID_PARAMETER;
- else if (ConnectionName->ConnectionIndex < 1
- || ConnectionName->ConnectionIndex > USB_MAXCHILDREN)
- Status = STATUS_INVALID_PARAMETER;
- else if (DeviceExtension->Children[ConnectionName->ConnectionIndex - 1] == NULL)
- Status = STATUS_INVALID_PARAMETER;
- else
- {
- ULONG NeededStructureSize;
- DeviceExtension = (PHUB_DEVICE_EXTENSION)DeviceExtension->Children[ConnectionName->ConnectionIndex - 1]->DeviceExtension;
- NeededStructureSize = DeviceExtension->SymbolicLinkName.Length + sizeof(UNICODE_NULL) + FIELD_OFFSET(USB_NODE_CONNECTION_NAME, NodeName);
- if (ConnectionName->ActualLength < NeededStructureSize / sizeof(WCHAR)
- || LengthOut < NeededStructureSize)
- {
- /* Buffer too small */
- ConnectionName->ActualLength = NeededStructureSize / sizeof(WCHAR);
- Information = sizeof(USB_NODE_CONNECTION_NAME);
- Status = STATUS_BUFFER_TOO_SMALL;
- }
- else
- {
- RtlCopyMemory(
- ConnectionName->NodeName,
- DeviceExtension->SymbolicLinkName.Buffer,
- DeviceExtension->SymbolicLinkName.Length);
- ConnectionName->NodeName[DeviceExtension->SymbolicLinkName.Length / sizeof(WCHAR)] = UNICODE_NULL;
- DPRINT("Usbhub: IOCTL_USB_GET_NODE_CONNECTION_NAME returns '%S'\n", ConnectionName->NodeName);
- ConnectionName->ActualLength = NeededStructureSize / sizeof(WCHAR);
- Information = NeededStructureSize;
- Status = STATUS_SUCCESS;
- }
- Information = LengthOut;
- }
- break;
- }
- case IOCTL_USB_GET_NODE_CONNECTION_INFORMATION:
- {
- PUSB_NODE_CONNECTION_INFORMATION ConnectionInformation;
- ULONG i, j, k;
- struct usb_device* dev;
- ULONG NumberOfOpenPipes = 0;
- ULONG SizeOfOpenPipesArray;
- ConnectionInformation = (PUSB_NODE_CONNECTION_INFORMATION)BufferOut;
-
- DPRINT("Usbhub: IOCTL_USB_GET_NODE_CONNECTION_INFORMATION\n");
- if (LengthOut < sizeof(USB_NODE_CONNECTION_INFORMATION))
- Status = STATUS_BUFFER_TOO_SMALL;
- else if (BufferOut == NULL)
- Status = STATUS_INVALID_PARAMETER;
- else if (ConnectionInformation->ConnectionIndex < 1
- || ConnectionInformation->ConnectionIndex > USB_MAXCHILDREN)
- Status = STATUS_INVALID_PARAMETER;
- else
- {
- dev = ((PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->dev;
- dev = dev->children[ConnectionInformation->ConnectionIndex - 1];
- if (dev == NULL)
- {
- /* No device connected to this port */
- RtlZeroMemory(
- &ConnectionInformation->DeviceDescriptor,
- sizeof(USB_NODE_CONNECTION_INFORMATION) - FIELD_OFFSET(USB_NODE_CONNECTION_INFORMATION, DeviceDescriptor));
- ConnectionInformation->ConnectionStatus = NoDeviceConnected;
- Information = sizeof(USB_NODE_CONNECTION_INFORMATION);
- Status = STATUS_SUCCESS;
- break;
- }
- SizeOfOpenPipesArray = (LengthOut - FIELD_OFFSET(USB_NODE_CONNECTION_INFORMATION, PipeList)) / sizeof(USB_PIPE_INFO);
- RtlCopyMemory(
- &ConnectionInformation->DeviceDescriptor,
- &dev->descriptor,
- sizeof(USB_DEVICE_DESCRIPTOR));
- ConnectionInformation->CurrentConfigurationValue = dev->actconfig->desc.bConfigurationValue;
- ConnectionInformation->LowSpeed = dev->speed == USB_SPEED_LOW || dev->speed == USB_SPEED_FULL;
- ConnectionInformation->DeviceIsHub = dev->descriptor.bDeviceClass == USB_CLASS_HUB;
- ConnectionInformation->DeviceAddress = dev->devnum;
- ConnectionInformation->ConnectionStatus = DeviceConnected;
-
- for (i = 0; i < dev->actconfig->desc.bNumInterfaces; i++)
- for (j = 0; j < dev->actconfig->interface[i].num_altsetting; j++)
- for (k = 0; k < dev->actconfig->interface[i].altsetting[j].desc.bNumEndpoints; k++)
- {
- if (NumberOfOpenPipes < SizeOfOpenPipesArray)
- {
- PUSB_PIPE_INFO Pipe = &ConnectionInformation->PipeList[NumberOfOpenPipes];
- struct usb_host_endpoint* endpoint = &dev->actconfig->interface[i].altsetting[j].endpoint[k];
- RtlCopyMemory(
- &Pipe->EndpointDescriptor,
- &endpoint->desc,
- endpoint->desc.bLength);
- Pipe->ScheduleOffset = 0; /* FIXME */
- }
- NumberOfOpenPipes++;
- }
- ConnectionInformation->NumberOfOpenPipes = NumberOfOpenPipes;
-
- Information = sizeof(USB_NODE_CONNECTION_INFORMATION);
- if (NumberOfOpenPipes <= SizeOfOpenPipesArray)
- Status = STATUS_SUCCESS;
- else
- Status = STATUS_BUFFER_OVERFLOW;
- }
- break;
- }
- case IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION:
- {
- //PUSB_DESCRIPTOR_REQUEST Descriptor;
- DPRINT("Usbhub: IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION\n");
- DPRINT1("Usbhub: IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION unimplemented\n");
- Information = 0;
- Status = STATUS_NOT_IMPLEMENTED;
- break;
- }
- case IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME:
- {
- PHUB_DEVICE_EXTENSION DeviceExtension;
- PUSB_NODE_CONNECTION_DRIVERKEY_NAME StringDescriptor;
- DPRINT("Usbhub: IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME\n");
- DeviceExtension = (PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
- StringDescriptor = (PUSB_NODE_CONNECTION_DRIVERKEY_NAME)BufferOut;
- if (LengthOut < sizeof(USB_NODE_CONNECTION_DRIVERKEY_NAME))
- Status = STATUS_BUFFER_TOO_SMALL;
- else if (StringDescriptor == NULL)
- Status = STATUS_INVALID_PARAMETER;
- else if (StringDescriptor->ConnectionIndex < 1
- || StringDescriptor->ConnectionIndex > USB_MAXCHILDREN)
- Status = STATUS_INVALID_PARAMETER;
- else if (DeviceExtension->Children[StringDescriptor->ConnectionIndex - 1] == NULL)
- Status = STATUS_INVALID_PARAMETER;
- else
- {
- ULONG StringSize;
- Status = IoGetDeviceProperty(
- DeviceExtension->Children[StringDescriptor->ConnectionIndex - 1],
- DevicePropertyDriverKeyName,
- LengthOut - FIELD_OFFSET(USB_NODE_CONNECTION_DRIVERKEY_NAME, DriverKeyName),
- StringDescriptor->DriverKeyName,
- &StringSize);
- if (NT_SUCCESS(Status) || Status == STATUS_BUFFER_TOO_SMALL)
- {
- StringDescriptor->ActualLength = StringSize + FIELD_OFFSET(USB_NODE_CONNECTION_DRIVERKEY_NAME, DriverKeyName);
- Information = LengthOut;
- Status = STATUS_SUCCESS;
- }
- }
- break;
- }
- default:
- {
- /* Pass Irp to lower driver */
- DPRINT1("Usbhub: Unknown IOCTL code 0x%lx\n", Stack->Parameters.DeviceIoControl.IoControlCode);
- return ForwardIrpAndForget(DeviceObject, Irp);
- }
- }
-
- Irp->IoStatus.Information = Information;
- Irp->IoStatus.Status = Status;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return Status;
+ PIO_STACK_LOCATION Stack;
+ ULONG IoControlCode;
+ PHUB_DEVICE_EXTENSION DeviceExtension;
+ ULONG LengthIn, LengthOut;
+ ULONG_PTR Information = 0;
+ PVOID BufferIn, BufferOut;
+ NTSTATUS Status = STATUS_UNSUCCESSFUL;
+
+ Stack = IoGetCurrentIrpStackLocation(Irp);
+ LengthIn = Stack->Parameters.DeviceIoControl.InputBufferLength;
+ LengthOut = Stack->Parameters.DeviceIoControl.OutputBufferLength;
+ DeviceExtension = (PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+ IoControlCode = Stack->Parameters.DeviceIoControl.IoControlCode;
+ UsbhubGetUserBuffers(Irp, IoControlCode, &BufferIn, &BufferOut);
+
+ switch (IoControlCode)
+ {
+ case IOCTL_USB_GET_NODE_INFORMATION:
+ {
+ //PUSB_NODE_INFORMATION NodeInformation;
+
+ DPRINT1("Usbhub: IOCTL_USB_GET_NODE_INFORMATION\n");
+ if (LengthOut < sizeof(USB_NODE_INFORMATION))
+ Status = STATUS_BUFFER_TOO_SMALL;
+ else if (BufferOut == NULL)
+ Status = STATUS_INVALID_PARAMETER;
+ else
+ {
+ /*NodeInformation = (PUSB_NODE_INFORMATION)BufferOut;
+ dev = ((PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->dev;
+ NodeInformation->NodeType = UsbHub;
+ RtlCopyMemory(
+ &NodeInformation->u.HubInformation.HubDescriptor,
+ ((struct usb_hub *)usb_get_intfdata(to_usb_interface(&dev->actconfig->interface[0].dev)))->descriptor,
+ sizeof(USB_HUB_DESCRIPTOR));
+ NodeInformation->u.HubInformation.HubIsBusPowered = dev->actconfig->desc.bmAttributes & 0x80;
+ Information = sizeof(USB_NODE_INFORMATION);*/
+ Status = STATUS_SUCCESS;
+ }
+ break;
+ }
+ case IOCTL_USB_GET_NODE_CONNECTION_NAME:
+ {
+ PHUB_DEVICE_EXTENSION DeviceExtension;
+ PUSB_NODE_CONNECTION_NAME ConnectionName;
+ DeviceExtension = (PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+ ConnectionName = (PUSB_NODE_CONNECTION_NAME)BufferOut;
+
+ DPRINT1("Usbhub: IOCTL_USB_GET_NODE_CONNECTION_NAME\n");
+ if (LengthOut < sizeof(USB_NODE_CONNECTION_NAME))
+ Status = STATUS_BUFFER_TOO_SMALL;
+ else if (BufferOut == NULL)
+ Status = STATUS_INVALID_PARAMETER;
+ else if (ConnectionName->ConnectionIndex < 1
+ || ConnectionName->ConnectionIndex > USB_MAXCHILDREN)
+ Status = STATUS_INVALID_PARAMETER;
+ else if (DeviceExtension->Children[ConnectionName->ConnectionIndex - 1] == NULL)
+ Status = STATUS_INVALID_PARAMETER;
+ else
+ {
+ ULONG NeededStructureSize;
+ DeviceExtension = (PHUB_DEVICE_EXTENSION)DeviceExtension->Children[ConnectionName->ConnectionIndex - 1]->DeviceExtension;
+ NeededStructureSize = DeviceExtension->SymbolicLinkName.Length + sizeof(UNICODE_NULL) + FIELD_OFFSET(USB_NODE_CONNECTION_NAME, NodeName);
+ if (ConnectionName->ActualLength < NeededStructureSize / sizeof(WCHAR)
+ || LengthOut < NeededStructureSize)
+ {
+ /* Buffer too small */
+ ConnectionName->ActualLength = NeededStructureSize / sizeof(WCHAR);
+ Information = sizeof(USB_NODE_CONNECTION_NAME);
+ Status = STATUS_BUFFER_TOO_SMALL;
+ }
+ else
+ {
+ RtlCopyMemory(
+ ConnectionName->NodeName,
+ DeviceExtension->SymbolicLinkName.Buffer,
+ DeviceExtension->SymbolicLinkName.Length);
+ ConnectionName->NodeName[DeviceExtension->SymbolicLinkName.Length / sizeof(WCHAR)] = UNICODE_NULL;
+ DPRINT1("Usbhub: IOCTL_USB_GET_NODE_CONNECTION_NAME returns '%S'\n", ConnectionName->NodeName);
+ ConnectionName->ActualLength = NeededStructureSize / sizeof(WCHAR);
+ Information = NeededStructureSize;
+ Status = STATUS_SUCCESS;
+ }
+ Information = LengthOut;
+ }
+ break;
+ }
+ case IOCTL_USB_GET_NODE_CONNECTION_INFORMATION:
+ {
+ PUSB_NODE_CONNECTION_INFORMATION ConnectionInformation;
+/*
+ ULONG i, j, k;
+ struct usb_device* dev;
+ ULONG NumberOfOpenPipes = 0;
+ ULONG SizeOfOpenPipesArray;
+*/
+ ConnectionInformation = (PUSB_NODE_CONNECTION_INFORMATION)BufferOut;
+
+ DPRINT1("Usbhub: IOCTL_USB_GET_NODE_CONNECTION_INFORMATION\n");
+ if (LengthOut < sizeof(USB_NODE_CONNECTION_INFORMATION))
+ Status = STATUS_BUFFER_TOO_SMALL;
+ else if (BufferOut == NULL)
+ Status = STATUS_INVALID_PARAMETER;
+ else if (ConnectionInformation->ConnectionIndex < 1
+ || ConnectionInformation->ConnectionIndex > USB_MAXCHILDREN)
+ Status = STATUS_INVALID_PARAMETER;
+ else
+ {
+ DPRINT1("Usbhub: We should succeed\n");
+ }
+ break;
+ }
+ case IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION:
+ {
+ //PUSB_DESCRIPTOR_REQUEST Descriptor;
+ DPRINT1("Usbhub: IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION\n");
+ Information = 0;
+ Status = STATUS_NOT_IMPLEMENTED;
+ break;
+ }
+ case IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME:
+ {
+ PHUB_DEVICE_EXTENSION DeviceExtension;
+ PUSB_NODE_CONNECTION_DRIVERKEY_NAME StringDescriptor;
+ DPRINT1("Usbhub: IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME\n");
+ DeviceExtension = (PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+ StringDescriptor = (PUSB_NODE_CONNECTION_DRIVERKEY_NAME)BufferOut;
+ if (LengthOut < sizeof(USB_NODE_CONNECTION_DRIVERKEY_NAME))
+ Status = STATUS_BUFFER_TOO_SMALL;
+ else if (StringDescriptor == NULL)
+ Status = STATUS_INVALID_PARAMETER;
+ else if (StringDescriptor->ConnectionIndex < 1
+ || StringDescriptor->ConnectionIndex > USB_MAXCHILDREN)
+ Status = STATUS_INVALID_PARAMETER;
+ else if (DeviceExtension->Children[StringDescriptor->ConnectionIndex - 1] == NULL)
+ Status = STATUS_INVALID_PARAMETER;
+ else
+ {
+ ULONG StringSize;
+ Status = IoGetDeviceProperty(
+ DeviceExtension->Children[StringDescriptor->ConnectionIndex - 1],
+ DevicePropertyDriverKeyName,
+ LengthOut - FIELD_OFFSET(USB_NODE_CONNECTION_DRIVERKEY_NAME, DriverKeyName),
+ StringDescriptor->DriverKeyName,
+ &StringSize);
+ if (NT_SUCCESS(Status) || Status == STATUS_BUFFER_TOO_SMALL)
+ {
+ StringDescriptor->ActualLength = StringSize + FIELD_OFFSET(USB_NODE_CONNECTION_DRIVERKEY_NAME, DriverKeyName);
+ Information = LengthOut;
+ Status = STATUS_SUCCESS;
+ }
+ }
+ break;
+ }
+ default:
+ {
+ /* Pass Irp to lower driver */
+ DPRINT1("Usbhub: Unknown IOCTL code 0x%lx\n", Stack->Parameters.DeviceIoControl.IoControlCode);
+ return ForwardIrpAndForget(DeviceObject, Irp);
+ }
+ }
+
+ Irp->IoStatus.Information = Information;
+ Irp->IoStatus.Status = Status;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return Status;
}
* FILE: drivers/usb/cromwell/hub/misc.c
* PURPOSE: Misceallenous operations
*
- * PROGRAMMERS: Hervé Poussineau (hpoussin@reactos.com),
+ * PROGRAMMERS: Herv� Poussineau (hpoussin@reactos.com),
*/
#define NDEBUG
NTSTATUS NTAPI
ForwardIrpAndWaitCompletion(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PVOID Context)
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp,
+ IN PVOID Context)
{
- if (Irp->PendingReturned)
- KeSetEvent((PKEVENT)Context, IO_NO_INCREMENT, FALSE);
- return STATUS_MORE_PROCESSING_REQUIRED;
+ if (Irp->PendingReturned)
+ KeSetEvent((PKEVENT)Context, IO_NO_INCREMENT, FALSE);
+ return STATUS_MORE_PROCESSING_REQUIRED;
}
NTSTATUS
ForwardIrpAndWait(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp)
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
{
- PDEVICE_OBJECT LowerDevice = ((PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerDevice;
- KEVENT Event;
- NTSTATUS Status;
+ KEVENT Event;
+ NTSTATUS Status;
- ASSERT(LowerDevice);
+ KeInitializeEvent(&Event, NotificationEvent, FALSE);
+ IoCopyCurrentIrpStackLocationToNext(Irp);
- KeInitializeEvent(&Event, NotificationEvent, FALSE);
- IoCopyCurrentIrpStackLocationToNext(Irp);
+ IoSetCompletionRoutine(Irp, ForwardIrpAndWaitCompletion, &Event, TRUE, TRUE, TRUE);
- DPRINT("UHCI: Calling lower device %p [%wZ]\n", LowerDevice, &LowerDevice->DriverObject->DriverName);
- IoSetCompletionRoutine(Irp, ForwardIrpAndWaitCompletion, &Event, TRUE, TRUE, TRUE);
+ Status = IoCallDriver(DeviceObject, Irp);
+ if (Status == STATUS_PENDING)
+ {
+ Status = KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL);
+ if (NT_SUCCESS(Status))
+ Status = Irp->IoStatus.Status;
+ }
- Status = IoCallDriver(LowerDevice, Irp);
- if (Status == STATUS_PENDING)
- {
- Status = KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL);
- if (NT_SUCCESS(Status))
- Status = Irp->IoStatus.Status;
- }
-
- return Status;
+ return Status;
}
NTSTATUS NTAPI
ForwardIrpAndForget(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp)
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
{
- PDEVICE_OBJECT LowerDevice = ((PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerDevice;
+ PDEVICE_OBJECT LowerDevice = ((PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerDevice;
- ASSERT(LowerDevice);
+ ASSERT(LowerDevice);
- IoSkipCurrentIrpStackLocation(Irp);
- return IoCallDriver(LowerDevice, Irp);
+ IoSkipCurrentIrpStackLocation(Irp);
+ return IoCallDriver(LowerDevice, Irp);
}
/* I really want PCSZ strings as last arguments because
* identification */
NTSTATUS
UsbhubInitMultiSzString(
- OUT PUNICODE_STRING Destination,
- ... /* list of PCSZ */)
+ OUT PUNICODE_STRING Destination,
+ ... /* list of PCSZ */)
{
- va_list args;
- PCSZ Source;
- ANSI_STRING AnsiString;
- UNICODE_STRING UnicodeString;
- ULONG DestinationSize = 0;
- NTSTATUS Status = STATUS_SUCCESS;
-
- ASSERT(Destination);
-
- /* Calculate length needed for destination unicode string */
- va_start(args, Destination);
- Source = va_arg(args, PCSZ);
- while (Source != NULL)
- {
- RtlInitAnsiString(&AnsiString, Source);
- DestinationSize += RtlAnsiStringToUnicodeSize(&AnsiString)
- + sizeof(WCHAR) /* final NULL */;
- Source = va_arg(args, PCSZ);
- }
- va_end(args);
- if (DestinationSize == 0)
- {
- RtlInitUnicodeString(Destination, NULL);
- return STATUS_SUCCESS;
- }
-
- /* Initialize destination string */
- DestinationSize += sizeof(WCHAR); // final NULL
- Destination->Buffer = (PWSTR)ExAllocatePoolWithTag(PagedPool, DestinationSize, USB_HUB_TAG);
- if (!Destination->Buffer)
- return STATUS_INSUFFICIENT_RESOURCES;
- Destination->Length = 0;
- Destination->MaximumLength = (USHORT)DestinationSize;
-
- /* Copy arguments to destination string */
- /* Use a temporary unicode string, which buffer is shared with
- * destination string, to copy arguments */
- UnicodeString.Length = Destination->Length;
- UnicodeString.MaximumLength = Destination->MaximumLength;
- UnicodeString.Buffer = Destination->Buffer;
- va_start(args, Destination);
- Source = va_arg(args, PCSZ);
- while (Source != NULL)
- {
- RtlInitAnsiString(&AnsiString, Source);
- Status = RtlAnsiStringToUnicodeString(&UnicodeString, &AnsiString, FALSE);
- if (!NT_SUCCESS(Status))
- {
- ExFreePoolWithTag(Destination->Buffer, USB_HUB_TAG);
- break;
- }
- Destination->Length += UnicodeString.Length + sizeof(WCHAR);
- UnicodeString.MaximumLength -= UnicodeString.Length + sizeof(WCHAR);
- UnicodeString.Buffer += UnicodeString.Length / sizeof(WCHAR) + 1;
- UnicodeString.Length = 0;
- Source = va_arg(args, PCSZ);
- }
- va_end(args);
- if (NT_SUCCESS(Status))
- {
- /* Finish multi-sz string */
- Destination->Buffer[Destination->Length / sizeof(WCHAR)] = L'\0';
- Destination->Length += sizeof(WCHAR);
- }
- return Status;
+ va_list args;
+ PCSZ Source;
+ ANSI_STRING AnsiString;
+ UNICODE_STRING UnicodeString;
+ ULONG DestinationSize = 0;
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ ASSERT(Destination);
+
+ /* Calculate length needed for destination unicode string */
+ va_start(args, Destination);
+ Source = va_arg(args, PCSZ);
+ while (Source != NULL)
+ {
+ RtlInitAnsiString(&AnsiString, Source);
+ DestinationSize += RtlAnsiStringToUnicodeSize(&AnsiString)
+ + sizeof(WCHAR) /* final NULL */;
+ Source = va_arg(args, PCSZ);
+ }
+ va_end(args);
+ if (DestinationSize == 0)
+ {
+ RtlInitUnicodeString(Destination, NULL);
+ return STATUS_SUCCESS;
+ }
+
+ /* Initialize destination string */
+ DestinationSize += sizeof(WCHAR); // final NULL
+ Destination->Buffer = (PWSTR)ExAllocatePoolWithTag(PagedPool, DestinationSize, USB_HUB_TAG);
+ if (!Destination->Buffer)
+ return STATUS_INSUFFICIENT_RESOURCES;
+ Destination->Length = 0;
+ Destination->MaximumLength = (USHORT)DestinationSize;
+
+ /* Copy arguments to destination string */
+ /* Use a temporary unicode string, which buffer is shared with
+ * destination string, to copy arguments */
+ UnicodeString.Length = Destination->Length;
+ UnicodeString.MaximumLength = Destination->MaximumLength;
+ UnicodeString.Buffer = Destination->Buffer;
+ va_start(args, Destination);
+ Source = va_arg(args, PCSZ);
+ while (Source != NULL)
+ {
+ RtlInitAnsiString(&AnsiString, Source);
+ Status = RtlAnsiStringToUnicodeString(&UnicodeString, &AnsiString, FALSE);
+ if (!NT_SUCCESS(Status))
+ {
+ ExFreePoolWithTag(Destination->Buffer, USB_HUB_TAG);
+ break;
+ }
+ Destination->Length += UnicodeString.Length + sizeof(WCHAR);
+ UnicodeString.MaximumLength -= UnicodeString.Length + sizeof(WCHAR);
+ UnicodeString.Buffer += UnicodeString.Length / sizeof(WCHAR) + 1;
+ UnicodeString.Length = 0;
+ Source = va_arg(args, PCSZ);
+ }
+ va_end(args);
+ if (NT_SUCCESS(Status))
+ {
+ /* Finish multi-sz string */
+ Destination->Buffer[Destination->Length / sizeof(WCHAR)] = L'\0';
+ Destination->Length += sizeof(WCHAR);
+ }
+ return Status;
}
NTSTATUS
UsbhubDuplicateUnicodeString(
- OUT PUNICODE_STRING Destination,
- IN PUNICODE_STRING Source,
- IN POOL_TYPE PoolType)
+ OUT PUNICODE_STRING Destination,
+ IN PUNICODE_STRING Source,
+ IN POOL_TYPE PoolType)
{
- ASSERT(Destination);
+ ASSERT(Destination);
- if (Source == NULL)
- {
- RtlInitUnicodeString(Destination, NULL);
- return STATUS_SUCCESS;
- }
+ if (Source == NULL)
+ {
+ RtlInitUnicodeString(Destination, NULL);
+ return STATUS_SUCCESS;
+ }
- Destination->Buffer = ExAllocatePool(PoolType, Source->MaximumLength);
- if (Destination->Buffer == NULL)
- {
- return STATUS_INSUFFICIENT_RESOURCES;
- }
+ Destination->Buffer = ExAllocatePool(PoolType, Source->MaximumLength);
+ if (Destination->Buffer == NULL)
+ {
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
- Destination->MaximumLength = Source->MaximumLength;
- Destination->Length = Source->Length;
- RtlCopyMemory(Destination->Buffer, Source->Buffer, Source->MaximumLength);
+ Destination->MaximumLength = Source->MaximumLength;
+ Destination->Length = Source->Length;
+ RtlCopyMemory(Destination->Buffer, Source->Buffer, Source->MaximumLength);
- return STATUS_SUCCESS;
+ return STATUS_SUCCESS;
}
* PURPOSE: IRP_MJ_PNP operations for PDOs
*
* PROGRAMMERS: Copyright 2005-2006 Hervé Poussineau (hpoussin@reactos.org)
+ * 2010 Michael Martin (michael.martin@reactos.org)
*/
#define NDEBUG
NTSTATUS
UsbhubInternalDeviceControlPdo(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp)
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
{
- PIO_STACK_LOCATION Stack;
- ULONG_PTR Information = 0;
- NTSTATUS Status;
-
- DPRINT("Usbhub: UsbhubInternalDeviceControlPdo() called\n");
-
- Stack = IoGetCurrentIrpStackLocation(Irp);
- Status = Irp->IoStatus.Status;
-
- switch (Stack->Parameters.DeviceIoControl.IoControlCode)
- {
- case IOCTL_INTERNAL_USB_GET_PARENT_HUB_INFO:
- {
- PHUB_DEVICE_EXTENSION DeviceExtension;
-
- DPRINT("Usbhub: IOCTL_INTERNAL_USB_GET_PARENT_HUB_INFO\n");
- if (Irp->AssociatedIrp.SystemBuffer == NULL
- || Stack->Parameters.DeviceIoControl.OutputBufferLength != sizeof(PVOID))
- {
- Status = STATUS_INVALID_PARAMETER;
- }
- else
- {
- PVOID* pHubPointer;
- DeviceExtension = (PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-
- pHubPointer = (PVOID*)Irp->AssociatedIrp.SystemBuffer;
- *pHubPointer = DeviceExtension->dev;
- Information = sizeof(PVOID);
- Status = STATUS_SUCCESS;
- }
- break;
- }
- default:
- {
- DPRINT1("Usbhub: Unknown IOCTL code 0x%lx\n", Stack->Parameters.DeviceIoControl.IoControlCode);
- Information = Irp->IoStatus.Information;
- Status = Irp->IoStatus.Status;
- }
- }
-
- Irp->IoStatus.Information = Information;
- Irp->IoStatus.Status = Status;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return Status;
+ PIO_STACK_LOCATION Stack;
+ ULONG_PTR Information = 0;
+ NTSTATUS Status;
+
+ DPRINT1("Usbhub: UsbhubInternalDeviceControlPdo() called\n");
+
+ Stack = IoGetCurrentIrpStackLocation(Irp);
+ Status = Irp->IoStatus.Status;
+
+ switch (Stack->Parameters.DeviceIoControl.IoControlCode)
+ {
+ case IOCTL_INTERNAL_USB_GET_PARENT_HUB_INFO:
+ {
+ PHUB_DEVICE_EXTENSION DeviceExtension;
+
+ DPRINT1("Usbhub: IOCTL_INTERNAL_USB_GET_PARENT_HUB_INFO\n");
+ if (Irp->AssociatedIrp.SystemBuffer == NULL
+ || Stack->Parameters.DeviceIoControl.OutputBufferLength != sizeof(PVOID))
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ }
+ else
+ {
+ PVOID* pHubPointer;
+ DeviceExtension = (PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+
+ pHubPointer = (PVOID*)Irp->AssociatedIrp.SystemBuffer;
+ *pHubPointer = DeviceExtension->dev;
+ Information = sizeof(PVOID);
+ Status = STATUS_SUCCESS;
+ }
+ break;
+ }
+ default:
+ {
+ DPRINT1("Usbhub: Unknown IOCTL code 0x%lx\n", Stack->Parameters.DeviceIoControl.IoControlCode);
+ Information = Irp->IoStatus.Information;
+ Status = Irp->IoStatus.Status;
+ }
+ }
+
+ Irp->IoStatus.Information = Information;
+ Irp->IoStatus.Status = Status;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return Status;
}
static NTSTATUS
UsbhubPdoStartDevice(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp)
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
{
- PHUB_DEVICE_EXTENSION DeviceExtension;
- NTSTATUS Status;
+ PHUB_DEVICE_EXTENSION DeviceExtension;
+ NTSTATUS Status = STATUS_UNSUCCESSFUL;
- DeviceExtension = (PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+ DeviceExtension = (PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
- /* Register and activate device interface */
- Status = IoRegisterDeviceInterface(
- DeviceObject,
- DeviceExtension->dev->descriptor.bDeviceClass == USB_CLASS_HUB ?
- &GUID_DEVINTERFACE_USB_HUB :
- &GUID_DEVINTERFACE_USB_DEVICE,
- NULL, /* Reference string */
- &DeviceExtension->SymbolicLinkName);
- if (!NT_SUCCESS(Status))
- {
- DPRINT("Usbhub: IoRegisterDeviceInterface() failed with status 0x%08lx\n", Status);
- return Status;
- }
-
- Status = IoSetDeviceInterfaceState(&DeviceExtension->SymbolicLinkName, TRUE);
- if (!NT_SUCCESS(Status))
- {
- DPRINT("Usbhub: IoSetDeviceInterfaceState() failed with status 0x%08lx\n", Status);
- return Status;
- }
-
- return STATUS_SUCCESS;
+ /* Register and activate device interface */
+/*
+ Status = IoRegisterDeviceInterface(
+ DeviceObject,
+ DeviceExtension->dev->descriptor.bDeviceClass == USB_CLASS_HUB ?
+ &GUID_DEVINTERFACE_USB_HUB :
+ &GUID_DEVINTERFACE_USB_DEVICE,
+ NULL,
+ &DeviceExtension->SymbolicLinkName);
+*/
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Usbhub: IoRegisterDeviceInterface() failed with status 0x%08lx\n", Status);
+ return Status;
+ }
+
+ //Status = IoSetDeviceInterfaceState(&DeviceExtension->SymbolicLinkName, TRUE);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Usbhub: IoSetDeviceInterfaceState() failed with status 0x%08lx\n", Status);
+ return Status;
+ }
+
+ return STATUS_SUCCESS;
}
static NTSTATUS
UsbhubPdoQueryId(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- OUT ULONG_PTR* Information)
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp,
+ OUT ULONG_PTR* Information)
{
- PHUB_DEVICE_EXTENSION DeviceExtension;
- ULONG IdType;
- PUNICODE_STRING SourceString;
- UNICODE_STRING String;
- NTSTATUS Status;
-
- IdType = IoGetCurrentIrpStackLocation(Irp)->Parameters.QueryId.IdType;
- DeviceExtension = (PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
- RtlInitUnicodeString(&String, NULL);
-
- switch (IdType)
- {
- case BusQueryDeviceID:
- {
- DPRINT("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryDeviceID\n");
- SourceString = &DeviceExtension->DeviceId;
- break;
- }
- case BusQueryHardwareIDs:
- {
- DPRINT("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryHardwareIDs\n");
- SourceString = &DeviceExtension->HardwareIds;
- break;
- }
- case BusQueryCompatibleIDs:
- {
- DPRINT("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryCompatibleIDs\n");
- SourceString = &DeviceExtension->CompatibleIds;
- break;
- }
- case BusQueryInstanceID:
- {
- DPRINT("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryInstanceID\n");
- SourceString = &DeviceExtension->InstanceId;
- break;
- }
- default:
- DPRINT1("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_ID / unknown query id type 0x%lx\n", IdType);
- return STATUS_NOT_SUPPORTED;
- }
-
- Status = UsbhubDuplicateUnicodeString(
- &String,
- SourceString,
- PagedPool);
- *Information = (ULONG_PTR)String.Buffer;
- return Status;
+ PHUB_CHILDDEVICE_EXTENSION DeviceExtension;
+ ULONG IdType;
+ PWCHAR SourceString = NULL;
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ IdType = IoGetCurrentIrpStackLocation(Irp)->Parameters.QueryId.IdType;
+ DeviceExtension = (PHUB_CHILDDEVICE_EXTENSION)DeviceObject->DeviceExtension;
+
+ switch (IdType)
+ {
+ case BusQueryDeviceID:
+ {
+ DPRINT1("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryDeviceID\n");
+ SourceString = DeviceExtension->DeviceId;
+ break;
+ }
+ /* FIXME: Implement */
+ case BusQueryHardwareIDs:
+ {
+ DPRINT1("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryHardwareIDs\n");
+ SourceString = DeviceExtension->HardwareIds;
+ Status = STATUS_NOT_SUPPORTED;
+ break;
+ }
+ /* FIXME: Implement */
+ case BusQueryCompatibleIDs:
+ {
+ DPRINT1("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryCompatibleIDs\n");
+ SourceString = DeviceExtension->CompatibleIds;
+ Status = STATUS_NOT_SUPPORTED;
+ break;
+ }
+ case BusQueryInstanceID:
+ {
+ DPRINT1("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryInstanceID\n");
+ SourceString = DeviceExtension->InstanceId;
+ break;
+ }
+ default:
+ DPRINT1("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_ID / unknown query id type 0x%lx\n", IdType);
+ return STATUS_NOT_SUPPORTED;
+ }
+
+ *Information = (ULONG_PTR)SourceString;
+ return Status;
}
static NTSTATUS
UsbhubPdoQueryDeviceText(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- OUT ULONG_PTR* Information)
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp,
+ OUT ULONG_PTR* Information)
{
- PHUB_DEVICE_EXTENSION DeviceExtension;
- DEVICE_TEXT_TYPE DeviceTextType;
- LCID LocaleId;
-
- DeviceTextType = IoGetCurrentIrpStackLocation(Irp)->Parameters.QueryDeviceText.DeviceTextType;
- LocaleId = IoGetCurrentIrpStackLocation(Irp)->Parameters.QueryDeviceText.LocaleId;
- DeviceExtension = (PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-
- switch (DeviceTextType)
- {
- case DeviceTextDescription:
- case DeviceTextLocationInformation:
- {
- unsigned short size;
- int ret;
- PWCHAR buf;
- PWCHAR bufret;
-
- if (DeviceTextType == DeviceTextDescription)
- DPRINT("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT / DeviceTextDescription\n");
- else
- DPRINT("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT / DeviceTextLocationInformation\n");
-
- if (!DeviceExtension->dev->descriptor.iProduct)
- return STATUS_NOT_SUPPORTED;
-
- ret = usb_get_string(DeviceExtension->dev, LocaleId, DeviceExtension->dev->descriptor.iProduct, &size, sizeof(size));
- if (ret < 2)
- {
- DPRINT("Usbhub: usb_get_string() failed with error %d\n", ret);
- return STATUS_IO_DEVICE_ERROR;
- }
- size &= 0xff;
- buf = ExAllocatePool(PagedPool, size);
- if (buf == NULL)
- {
- DPRINT("Usbhub: ExAllocatePool() failed\n");
- return STATUS_INSUFFICIENT_RESOURCES;
- }
- ret = usb_get_string(DeviceExtension->dev, LocaleId, DeviceExtension->dev->descriptor.iProduct, buf, size);
- if (ret < 0)
- {
- DPRINT("Usbhub: usb_get_string() failed with error %d\n", ret);
- ExFreePool(buf);
- return STATUS_IO_DEVICE_ERROR;
- }
- bufret = ExAllocatePool(PagedPool, size - 2 /* size of length identifier */ + 2 /* final NULL */);
- if (bufret == NULL)
- {
- DPRINT("Usbhub: ExAllocatePool() failed\n");
- ExFreePool(buf);
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- RtlCopyMemory(bufret, &buf[1], size - 2);
- bufret[(size - 1) / sizeof(WCHAR)] = 0;
- *Information = (ULONG_PTR)bufret;
- ExFreePool(buf);
- return STATUS_SUCCESS;
- }
- default:
- DPRINT1("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT / unknown device text type 0x%lx\n", DeviceTextType);
- return STATUS_NOT_SUPPORTED;
- }
+ PHUB_CHILDDEVICE_EXTENSION DeviceExtension;
+ DEVICE_TEXT_TYPE DeviceTextType;
+ LCID LocaleId;
+
+ DeviceTextType = IoGetCurrentIrpStackLocation(Irp)->Parameters.QueryDeviceText.DeviceTextType;
+ LocaleId = IoGetCurrentIrpStackLocation(Irp)->Parameters.QueryDeviceText.LocaleId;
+ DeviceExtension = (PHUB_CHILDDEVICE_EXTENSION)DeviceObject->DeviceExtension;
+
+ switch (DeviceTextType)
+ {
+ case DeviceTextDescription:
+ case DeviceTextLocationInformation:
+ {
+ if (DeviceTextType == DeviceTextDescription)
+ {
+ *Information = (ULONG_PTR)DeviceExtension->TextDescription;
+ DPRINT1("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT / DeviceTextDescription\n");
+ }
+ else
+ DPRINT1("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT / DeviceTextLocationInformation\n");
+
+/* if (!DeviceExtension->dev->descriptor.iProduct)
+ return STATUS_NOT_SUPPORTED;*/
+
+ return STATUS_SUCCESS;
+ }
+ default:
+ DPRINT1("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT / unknown device text type 0x%lx\n", DeviceTextType);
+ return STATUS_NOT_SUPPORTED;
+ }
}
NTSTATUS NTAPI
UsbhubPnpPdo(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp)
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
{
- ULONG MinorFunction;
- PIO_STACK_LOCATION Stack;
- ULONG_PTR Information = 0;
- NTSTATUS Status;
-
- Stack = IoGetCurrentIrpStackLocation(Irp);
- MinorFunction = Stack->MinorFunction;
-
- switch (MinorFunction)
- {
- case IRP_MN_START_DEVICE: /* 0x0 */
- {
- DPRINT("Usbhub: IRP_MJ_PNP / IRP_MN_START_DEVICE\n");
- Status = UsbhubPdoStartDevice(DeviceObject, Irp);
- break;
- }
- case IRP_MN_QUERY_CAPABILITIES: /* 0x09 */
- {
- PDEVICE_CAPABILITIES DeviceCapabilities;
- ULONG i;
- DPRINT("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_CAPABILITIES\n");
-
- DeviceCapabilities = (PDEVICE_CAPABILITIES)Stack->Parameters.DeviceCapabilities.Capabilities;
- /* FIXME: capabilities can change with connected device */
- DeviceCapabilities->LockSupported = TRUE;
- DeviceCapabilities->EjectSupported = FALSE;
- DeviceCapabilities->Removable = FALSE;
- DeviceCapabilities->DockDevice = FALSE;
- DeviceCapabilities->UniqueID = FALSE;
- DeviceCapabilities->SilentInstall = TRUE;
- DeviceCapabilities->RawDeviceOK = FALSE;
- DeviceCapabilities->SurpriseRemovalOK = FALSE;
- DeviceCapabilities->HardwareDisabled = FALSE; /* FIXME */
- //DeviceCapabilities->NoDisplayInUI = FALSE; /* FIXME */
- DeviceCapabilities->DeviceState[0] = PowerDeviceD0; /* FIXME */
- for (i = 0; i < PowerSystemMaximum; i++)
- DeviceCapabilities->DeviceState[i] = PowerDeviceD3; /* FIXME */
- //DeviceCapabilities->DeviceWake = PowerDeviceUndefined; /* FIXME */
- DeviceCapabilities->D1Latency = 0; /* FIXME */
- DeviceCapabilities->D2Latency = 0; /* FIXME */
- DeviceCapabilities->D3Latency = 0; /* FIXME */
- Status = STATUS_SUCCESS;
- break;
- }
- case IRP_MN_QUERY_RESOURCES: /* 0x0a */
- {
- PCM_RESOURCE_LIST ResourceList;
-
- DPRINT("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_RESOURCES\n");
- ResourceList = ExAllocatePool(PagedPool, sizeof(CM_RESOURCE_LIST));
- if (!ResourceList)
- {
- DPRINT("Usbhub: ExAllocatePool() failed\n");
- Status = STATUS_INSUFFICIENT_RESOURCES;
- }
- else
- {
- ResourceList->Count = 0;
- Information = (ULONG_PTR)ResourceList;
- Status = STATUS_SUCCESS;
- }
- break;
- }
- case IRP_MN_QUERY_RESOURCE_REQUIREMENTS: /* 0x0b */
- {
- PIO_RESOURCE_REQUIREMENTS_LIST ResourceList;
-
- DPRINT("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_RESOURCE_REQUIREMENTS\n");
- ResourceList = ExAllocatePool(PagedPool, sizeof(IO_RESOURCE_REQUIREMENTS_LIST));
- if (!ResourceList)
- {
- DPRINT("Usbhub: ExAllocatePool() failed\n");
- Status = STATUS_INSUFFICIENT_RESOURCES;
- }
- else
- {
- RtlZeroMemory(ResourceList, sizeof(IO_RESOURCE_REQUIREMENTS_LIST));
- ResourceList->ListSize = sizeof(IO_RESOURCE_REQUIREMENTS_LIST);
- ResourceList->AlternativeLists = 1;
- ResourceList->List->Version = 1;
- ResourceList->List->Revision = 1;
- ResourceList->List->Count = 0;
- Information = (ULONG_PTR)ResourceList;
- Status = STATUS_SUCCESS;
- }
- break;
- }
- case IRP_MN_QUERY_DEVICE_TEXT: /* 0x0c */
- {
- Status = UsbhubPdoQueryDeviceText(DeviceObject, Irp, &Information);
- break;
- }
- case IRP_MN_QUERY_ID: /* 0x13 */
- {
- Status = UsbhubPdoQueryId(DeviceObject, Irp, &Information);
- break;
- }
- default:
- {
- /* We can't forward request to the lower driver, because
- * we are a Pdo, so we don't have lower driver...
- */
- DPRINT1("Usbhub: IRP_MJ_PNP / unknown minor function 0x%lx\n", MinorFunction);
- Information = Irp->IoStatus.Information;
- Status = Irp->IoStatus.Status;
- }
- }
-
- Irp->IoStatus.Information = Information;
- Irp->IoStatus.Status = Status;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return Status;
+ ULONG MinorFunction;
+ PIO_STACK_LOCATION Stack;
+ ULONG_PTR Information = 0;
+ NTSTATUS Status;
+
+ Stack = IoGetCurrentIrpStackLocation(Irp);
+ MinorFunction = Stack->MinorFunction;
+
+ switch (MinorFunction)
+ {
+ case IRP_MN_START_DEVICE: /* 0x0 */
+ {
+ DPRINT1("Usbhub: IRP_MJ_PNP / IRP_MN_START_DEVICE\n");
+ Status = UsbhubPdoStartDevice(DeviceObject, Irp);
+ break;
+ }
+ case IRP_MN_QUERY_CAPABILITIES: /* 0x09 */
+ {
+ PDEVICE_CAPABILITIES DeviceCapabilities;
+ ULONG i;
+ DPRINT1("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_CAPABILITIES\n");
+
+ DeviceCapabilities = (PDEVICE_CAPABILITIES)Stack->Parameters.DeviceCapabilities.Capabilities;
+ /* FIXME: capabilities can change with connected device */
+ DeviceCapabilities->LockSupported = TRUE;
+ DeviceCapabilities->EjectSupported = FALSE;
+ DeviceCapabilities->Removable = FALSE;
+ DeviceCapabilities->DockDevice = FALSE;
+ DeviceCapabilities->UniqueID = FALSE;
+ DeviceCapabilities->SilentInstall = TRUE;
+ DeviceCapabilities->RawDeviceOK = FALSE;
+ DeviceCapabilities->SurpriseRemovalOK = FALSE;
+ DeviceCapabilities->HardwareDisabled = FALSE; /* FIXME */
+ //DeviceCapabilities->NoDisplayInUI = FALSE; /* FIXME */
+ DeviceCapabilities->DeviceState[0] = PowerDeviceD0; /* FIXME */
+ for (i = 0; i < PowerSystemMaximum; i++)
+ DeviceCapabilities->DeviceState[i] = PowerDeviceD3; /* FIXME */
+ //DeviceCapabilities->DeviceWake = PowerDeviceUndefined; /* FIXME */
+ DeviceCapabilities->D1Latency = 0; /* FIXME */
+ DeviceCapabilities->D2Latency = 0; /* FIXME */
+ DeviceCapabilities->D3Latency = 0; /* FIXME */
+ Status = STATUS_SUCCESS;
+ break;
+ }
+ case IRP_MN_QUERY_RESOURCES: /* 0x0a */
+ {
+ PCM_RESOURCE_LIST ResourceList;
+
+ DPRINT1("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_RESOURCES\n");
+ ResourceList = ExAllocatePool(PagedPool, sizeof(CM_RESOURCE_LIST));
+ if (!ResourceList)
+ {
+ DPRINT1("Usbhub: ExAllocatePool() failed\n");
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ }
+ else
+ {
+ ResourceList->Count = 0;
+ Information = (ULONG_PTR)ResourceList;
+ Status = STATUS_SUCCESS;
+ }
+ break;
+ }
+ case IRP_MN_QUERY_RESOURCE_REQUIREMENTS: /* 0x0b */
+ {
+ PIO_RESOURCE_REQUIREMENTS_LIST ResourceList;
+
+ DPRINT1("Usbhub: IRP_MJ_PNP / IRP_MN_QUERY_RESOURCE_REQUIREMENTS\n");
+ ResourceList = ExAllocatePool(PagedPool, sizeof(IO_RESOURCE_REQUIREMENTS_LIST));
+ if (!ResourceList)
+ {
+ DPRINT1("Usbhub: ExAllocatePool() failed\n");
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ }
+ else
+ {
+ RtlZeroMemory(ResourceList, sizeof(IO_RESOURCE_REQUIREMENTS_LIST));
+ ResourceList->ListSize = sizeof(IO_RESOURCE_REQUIREMENTS_LIST);
+ ResourceList->AlternativeLists = 1;
+ ResourceList->List->Version = 1;
+ ResourceList->List->Revision = 1;
+ ResourceList->List->Count = 0;
+ Information = (ULONG_PTR)ResourceList;
+ Status = STATUS_SUCCESS;
+ }
+ break;
+ }
+ case IRP_MN_QUERY_DEVICE_TEXT: /* 0x0c */
+ {
+ Status = UsbhubPdoQueryDeviceText(DeviceObject, Irp, &Information);
+ break;
+ }
+ case IRP_MN_QUERY_ID: /* 0x13 */
+ {
+ Status = UsbhubPdoQueryId(DeviceObject, Irp, &Information);
+ break;
+ }
+ default:
+ {
+ /* We can't forward request to the lower driver, because
+ * we are a Pdo, so we don't have lower driver...
+ */
+ DPRINT1("Usbhub: IRP_MJ_PNP / unknown minor function 0x%lx\n", MinorFunction);
+ Information = Irp->IoStatus.Information;
+ Status = Irp->IoStatus.Status;
+ }
+ }
+
+ Irp->IoStatus.Information = Information;
+ Irp->IoStatus.Status = Status;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return Status;
}
* ReactOS USB hub driver
* Copyright (C) 2004 Aleksey Bragin
* (C) 2005 Mark Tempel
- * (C) 2005 Hervé Poussineau
+ * (C) 2005 Herv� Poussineau
+ * (C) 2010 Michael Martin
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
/* PUBLIC AND PRIVATE FUNCTIONS ***********************************************/
-static NTSTATUS
-GetRootHubPointer(
- IN PDEVICE_OBJECT Pdo,
- OUT PVOID* RootHubPointer)
-{
- KEVENT Event;
- PIRP Irp;
- IO_STATUS_BLOCK IoStatus;
- NTSTATUS Status;
-
- KeInitializeEvent (&Event, NotificationEvent, FALSE);
-
- Irp = IoBuildDeviceIoControlRequest(IOCTL_INTERNAL_USB_GET_PARENT_HUB_INFO,
- Pdo,
- NULL, sizeof(NULL),
- RootHubPointer, sizeof(*RootHubPointer),
- FALSE,
- &Event,
- &IoStatus);
- if (Irp == NULL)
- {
- DPRINT("Usbhub: IoBuildDeviceIoControlRequest() failed\n");
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- /* Initialize the status block before sending the IRP */
- IoGetNextIrpStackLocation(Irp)->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
- IoStatus.Status = STATUS_NOT_SUPPORTED;
- IoStatus.Information = 0;
-
- Status = IoCallDriver(Pdo, Irp);
-
- if (Status == STATUS_PENDING)
- {
- DPRINT("Usbhub: Operation pending\n");
- KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL);
- Status = IoStatus.Status;
- }
-
- return Status;
-}
-
NTSTATUS NTAPI
UsbhubAddDevice(
- IN PDRIVER_OBJECT DriverObject,
- IN PDEVICE_OBJECT Pdo)
+ IN PDRIVER_OBJECT DriverObject,
+ IN PDEVICE_OBJECT Pdo)
{
- PDEVICE_OBJECT Fdo;
- PHUB_DEVICE_EXTENSION DeviceExtension;
- NTSTATUS Status;
-
- Status = IoCreateDevice(DriverObject,
- sizeof(HUB_DEVICE_EXTENSION),
- NULL, /* DeviceName */
- FILE_DEVICE_BUS_EXTENDER,
- 0,
- FALSE,
- &Fdo);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Usbhub: IoCreateDevice() failed with status 0x%08lx\n", Status);
- return Status;
- }
-
- // zerofill device extension
- DeviceExtension = (PHUB_DEVICE_EXTENSION)Fdo->DeviceExtension;
- RtlZeroMemory(DeviceExtension, sizeof(HUB_DEVICE_EXTENSION));
-
- /* Get a pointer to the linux structure created by the USB controller,
- * by sending IOCTL_INTERNAL_USB_GET_PARENT_HUB_INFO to lower device.
- */
- Status = GetRootHubPointer(Pdo, (PVOID*)&DeviceExtension->dev);
- if (!NT_SUCCESS(Status))
- {
- DPRINT("Usbhub: GetRootHubPointer() failed with status 0x%08lx\n", Status);
- IoDeleteDevice(Fdo);
- return Status;
- }
- DeviceExtension->dev->dev.dev_ext = Pdo;
-
- DeviceExtension->IsFDO = TRUE;
- Fdo->Flags |= DO_POWER_PAGABLE;
- Status = IoAttachDeviceToDeviceStackSafe(Fdo, Pdo, &DeviceExtension->LowerDevice);
- if (!NT_SUCCESS(Status))
- {
- DPRINT("Usbhub: IoAttachDeviceToDeviceStackSafe() failed with status 0x%08lx\n", Status);
- IoDeleteDevice(Fdo);
- return Status;
- }
- Fdo->Flags |= DO_BUFFERED_IO;
- Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
-
- return STATUS_SUCCESS;
+ PDEVICE_OBJECT Fdo;
+ PHUB_DEVICE_EXTENSION DeviceExtension;
+ NTSTATUS Status;
+
+ Status = IoCreateDevice(DriverObject,
+ sizeof(HUB_DEVICE_EXTENSION),
+ NULL, /* DeviceName */
+ FILE_DEVICE_BUS_EXTENDER,
+ FILE_AUTOGENERATED_DEVICE_NAME,
+ FALSE,
+ &Fdo);
+
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Usbhub: IoCreateDevice() failed with status 0x%08lx\n", Status);
+ return Status;
+ }
+
+ // zerofill device extension
+ DeviceExtension = (PHUB_DEVICE_EXTENSION)Fdo->DeviceExtension;
+ RtlZeroMemory(DeviceExtension, sizeof(HUB_DEVICE_EXTENSION));
+
+ DeviceExtension->IsFDO = TRUE;
+ Fdo->Flags |= DO_POWER_PAGABLE;
+ //Status = IoAttachDeviceToDeviceStackSafe(Fdo, Pdo, &DeviceExtension->LowerDevice);
+ DeviceExtension->LowerDevice = IoAttachDeviceToDeviceStack(Fdo, Pdo);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("Usbhub: IoAttachDeviceToDeviceStackSafe() failed with status 0x%08lx\n", Status);
+ IoDeleteDevice(Fdo);
+ return Status;
+ }
+ Fdo->Flags |= DO_BUFFERED_IO;
+
+ Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
+
+ return STATUS_SUCCESS;
}
static NTSTATUS NTAPI
IrpStub(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp)
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
{
- NTSTATUS Status;
-
- if (((PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsFDO)
- {
- DPRINT1("Usbhub: FDO stub for major function 0x%lx\n",
- IoGetCurrentIrpStackLocation(Irp)->MajorFunction);
-#ifndef NDEBUG
- DbgBreakPoint();
-#endif
- return ForwardIrpAndForget(DeviceObject, Irp);
- }
- else
- {
- /* We can't forward request to the lower driver, because
- * we are a Pdo, so we don't have lower driver...
- */
- DPRINT1("Usbhub: PDO stub for major function 0x%lx\n",
- IoGetCurrentIrpStackLocation(Irp)->MajorFunction);
+ NTSTATUS Status;
+
+ if (((PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsFDO)
+ {
+ DPRINT1("Usbhub: FDO stub for major function 0x%lx\n",
+ IoGetCurrentIrpStackLocation(Irp)->MajorFunction);
+ return ForwardIrpAndForget(DeviceObject, Irp);
+ }
+ else
+ {
+ /* We can't forward request to the lower driver, because
+ * we are a Pdo, so we don't have lower driver...
+ */
+ DPRINT1("Usbhub: PDO stub for major function 0x%lx\n",
+ IoGetCurrentIrpStackLocation(Irp)->MajorFunction);
#ifndef NDEBUG
- DbgBreakPoint();
+ DbgBreakPoint();
#endif
- }
+ }
- Status = Irp->IoStatus.Status;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return Status;
+ Status = Irp->IoStatus.Status;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return Status;
}
static NTSTATUS NTAPI
DispatchDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
- if (((PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsFDO)
- return UsbhubDeviceControlFdo(DeviceObject, Irp);
- else
- return IrpStub(DeviceObject, Irp);
+ DPRINT1("Usbhub: DispatchDeviceControl\n");
+ if (((PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsFDO)
+ return UsbhubDeviceControlFdo(DeviceObject, Irp);
+ else
+ return IrpStub(DeviceObject, Irp);
}
static NTSTATUS NTAPI
DispatchInternalDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
- if (((PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsFDO)
- return IrpStub(DeviceObject, Irp);
- else
- return UsbhubInternalDeviceControlPdo(DeviceObject, Irp);
+ DPRINT1("Usbhub: DispatchInternalDeviceControl\n");
+ if (((PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsFDO)
+ return IrpStub(DeviceObject, Irp);
+ else
+ return UsbhubInternalDeviceControlPdo(DeviceObject, Irp);
}
static NTSTATUS NTAPI
DispatchPnp(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
- if (((PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsFDO)
- return UsbhubPnpFdo(DeviceObject, Irp);
- else
- return UsbhubPnpPdo(DeviceObject, Irp);
+ DPRINT1("Usbhub: DispatchPnp\n");
+ if (((PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsFDO)
+ return UsbhubPnpFdo(DeviceObject, Irp);
+ else
+ return UsbhubPnpPdo(DeviceObject, Irp);
}
/*
*/
NTSTATUS NTAPI
DriverEntry(
- IN PDRIVER_OBJECT DriverObject,
- IN PUNICODE_STRING RegistryPath)
+ IN PDRIVER_OBJECT DriverObject,
+ IN PUNICODE_STRING RegistryPath)
{
- ULONG i;
+ ULONG i;
- DriverObject->DriverExtension->AddDevice = UsbhubAddDevice;
+ DriverObject->DriverExtension->AddDevice = UsbhubAddDevice;
+ DPRINT1("Usbhub: DriverEntry\n");
- for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
- DriverObject->MajorFunction[i] = IrpStub;
+ for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
+ DriverObject->MajorFunction[i] = IrpStub;
- DriverObject->MajorFunction[IRP_MJ_CREATE] = UsbhubCreate;
- DriverObject->MajorFunction[IRP_MJ_CLOSE] = UsbhubClose;
- DriverObject->MajorFunction[IRP_MJ_CLEANUP] = UsbhubCleanup;
- DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchDeviceControl;
- DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = DispatchInternalDeviceControl;
- DriverObject->MajorFunction[IRP_MJ_PNP] = DispatchPnp;
+ DriverObject->MajorFunction[IRP_MJ_CREATE] = UsbhubCreate;
+ DriverObject->MajorFunction[IRP_MJ_CLOSE] = UsbhubClose;
+ DriverObject->MajorFunction[IRP_MJ_CLEANUP] = UsbhubCleanup;
+ DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchDeviceControl;
+ DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = DispatchInternalDeviceControl;
+ DriverObject->MajorFunction[IRP_MJ_PNP] = DispatchPnp;
- return STATUS_SUCCESS;
+ return STATUS_SUCCESS;
}
-#include <debug.h>
-
#include <ntddk.h>
+#include <hubbusif.h>
+#include <usbbusif.h>
#include <usbioctl.h>
-
-#include "../miniport/usb_wrapper.h"
-#include "../usbport/hub.h"
+#include <usb.h>
+#include <debug.h>
+//BROKEN: #include <usbprotocoldefs.h>
#define USB_HUB_TAG 'hbsu'
+#define USB_MAXCHILDREN 127
+
+/* Lifted from broken header above */
+#define C_HUB_LOCAL_POWER 0
+#define C_HUB_OVER_CURRENT 1
+#define PORT_CONNECTION 0
+#define PORT_ENABLE 1
+#define PORT_SUSPEND 2
+#define PORT_OVER_CURRENT 3
+#define PORT_RESET 4
+#define PORT_POWER 8
+#define PORT_LOW_SPEED 9
+#define C_PORT_CONNECTION 16
+#define C_PORT_ENABLE 17
+#define C_PORT_SUSPEND 18
+#define C_PORT_OVER_CURRENT 19
+#define C_PORT_RESET 20
+#define PORT_TEST 21
+#define PORT_INDICATOR 22
+
+typedef struct _USB_ENDPOINT
+{
+ ULONG Flags;
+ LIST_ENTRY UrbList;
+ struct _USB_INTERFACE *Interface;
+ USB_ENDPOINT_DESCRIPTOR EndPointDescriptor;
+} USB_ENDPOINT, *PUSB_ENDPOINT;
+
+typedef struct _USB_INTERFACE
+{
+ struct _USB_CONFIGURATION *Config;
+ USB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
+ USB_ENDPOINT *EndPoints[];
+} USB_INTERFACE, *PUSB_INTERFACE;
+
+typedef struct _USB_CONFIGURATION
+{
+ struct _USB_DEVICE *Device;
+ USB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor;
+ USB_INTERFACE *Interfaces[];
+} USB_CONFIGURATION, *PUSB_CONFIGURATION;
+
+typedef struct _USB_DEVICE
+{
+ UCHAR Address;
+ ULONG Port;
+ PVOID ParentDevice;
+ BOOLEAN IsHub;
+ USB_DEVICE_SPEED DeviceSpeed;
+ USB_DEVICE_TYPE DeviceType;
+ USB_DEVICE_DESCRIPTOR DeviceDescriptor;
+ USB_CONFIGURATION *ActiveConfig;
+ USB_INTERFACE *ActiveInterface;
+ USB_CONFIGURATION **Configs;
+} USB_DEVICE, *PUSB_DEVICE;
+
+typedef struct _HUB_CHILDDEVICE_EXTENSION
+{
+ BOOLEAN IsFDO;
+ PDEVICE_OBJECT Parent;
+ PWCHAR DeviceId; // REG_SZ
+ PWCHAR InstanceId; // REG_SZ
+ PWCHAR HardwareIds; // REG_MULTI_SZ
+ PWCHAR CompatibleIds; // REG_MULTI_SZ
+ PWCHAR TextDescription;
+ UNICODE_STRING SymbolicLinkName;
+} HUB_CHILDDEVICE_EXTENSION, *PHUB_CHILDDEVICE_EXTENSION;
typedef struct _HUB_DEVICE_EXTENSION
{
- BOOLEAN IsFDO;
- struct usb_device* dev;
- PDEVICE_OBJECT LowerDevice;
-
- PDEVICE_OBJECT Children[USB_MAXCHILDREN];
-
- /* Fields valid only when IsFDO == FALSE */
- UNICODE_STRING DeviceId; // REG_SZ
- UNICODE_STRING InstanceId; // REG_SZ
- UNICODE_STRING HardwareIds; // REG_MULTI_SZ
- UNICODE_STRING CompatibleIds; // REG_MULTI_SZ
- UNICODE_STRING SymbolicLinkName;
+ BOOLEAN IsFDO;
+ USB_DEVICE* dev;
+ PDEVICE_OBJECT LowerDevice;
+ ULONG ChildCount;
+ PDEVICE_OBJECT Children[USB_MAXCHILDREN];
+
+ PUSB_DEVICE UsbChildren[USB_MAXCHILDREN];
+
+ PUSB_DEVICE RootHubUsbDevice;
+
+ PDEVICE_OBJECT RootHubPdo;
+ PDEVICE_OBJECT RootHubFdo;
+
+ ULONG HubCount;
+
+ USHORT PortStatus[256];
+
+ USB_BUS_INTERFACE_HUB_V5 HubInterface;
+ USB_BUS_INTERFACE_USBDI_V2 UsbDInterface;
+
+ USB_HUB_DESCRIPTOR HubDescriptor;
+ USB_DEVICE_DESCRIPTOR HubDeviceDescriptor;
+
+ USB_CONFIGURATION_DESCRIPTOR HubConfigDescriptor;
+ USB_INTERFACE_DESCRIPTOR HubInterfaceDescriptor;
+ USB_ENDPOINT_DESCRIPTOR HubEndPointDescriptor;
+
+ USB_EXTHUB_INFORMATION_0 UsbExtHubInfo;
+ USB_DEVICE_INFORMATION_0 DeviceInformation;
+
+ WORK_QUEUE_ITEM WorkItem;
+
+ USBD_CONFIGURATION_HANDLE ConfigurationHandle;
+ USBD_PIPE_HANDLE PipeHandle;
+
+ UNICODE_STRING SymbolicLinkName;
} HUB_DEVICE_EXTENSION, *PHUB_DEVICE_EXTENSION;
/* createclose.c */
NTSTATUS NTAPI
UsbhubCreate(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp);
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp);
NTSTATUS NTAPI
UsbhubClose(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp);
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp);
NTSTATUS NTAPI
UsbhubCleanup(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp);
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp);
/* fdo.c */
NTSTATUS NTAPI
UsbhubPnpFdo(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp);
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp);
NTSTATUS
UsbhubDeviceControlFdo(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp);
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp);
/* misc.c */
NTSTATUS
ForwardIrpAndWait(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp);
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp);
NTSTATUS NTAPI
ForwardIrpAndForget(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp);
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp);
NTSTATUS
UsbhubDuplicateUnicodeString(
- OUT PUNICODE_STRING Destination,
- IN PUNICODE_STRING Source,
- IN POOL_TYPE PoolType);
+ OUT PUNICODE_STRING Destination,
+ IN PUNICODE_STRING Source,
+ IN POOL_TYPE PoolType);
NTSTATUS
UsbhubInitMultiSzString(
- OUT PUNICODE_STRING Destination,
- ... /* list of PCSZ */);
+ OUT PUNICODE_STRING Destination,
+ .../* list of PCSZ */);
/* pdo.c */
NTSTATUS NTAPI
UsbhubPnpPdo(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp);
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp);
NTSTATUS
UsbhubInternalDeviceControlPdo(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp);
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp);
<?xml version="1.0"?>
<!DOCTYPE module SYSTEM "../../../tools/rbuild/project.dtd">
<module name="usbhub" type="kernelmodedriver" installbase="system32/drivers" installname="usbhub.sys">
- <include>../miniport/linux</include>
- <library>sys_base</library>
<library>ntoskrnl</library>
<library>hal</library>
- <library>usbport</library>
<file>createclose.c</file>
<file>fdo.c</file>
<file>misc.c</file>
*/
#include "videoprt.h"
-#include "internal/i386/v86m.h"
/* PRIVATE FUNCTIONS **********************************************************/
/* Fill out the dispatch tables */
HalQuerySystemInformation = HaliQuerySystemInformation;
HalSetSystemInformation = HaliSetSystemInformation;
- HalInitPnpDriver = NULL; // FIXME: TODO
+ HalInitPnpDriver = HaliInitPnpDriver;
#ifndef _MINIHAL_
HalGetDmaAdapter = HalpGetDmaAdapter;
#else
_HalpPerfCounterHigh: .long 0
_HalpSystemHardwareFlags: .long 0
-_UnhandledMsg:
- .asciz "\n\x7\x7!!! Unhandled or Unexpected Code at line: %lx!!!\n"
-
/* FUNCTIONS *****************************************************************/
.global _HalpCalibrateStallExecution@0
/* Read 8254 timer */
mov al, 0
out 0x43, al
+ in al, 0x92
+ or al, _HalpPerfCounterCutoff
+ out 0x92, al
jmp $+2
in al, 0x40
jmp $+2
VOID
NTAPI
-HalpDebugPciBus(IN ULONG i,
- IN ULONG j,
- IN ULONG k,
- IN PPCI_COMMON_CONFIG PciData)
+HalpDebugPciDumpBus(IN ULONG i,
+ IN ULONG j,
+ IN ULONG k,
+ IN PPCI_COMMON_CONFIG PciData)
{
extern CHAR ClassTable[3922];
extern CHAR VendorTable[642355];
if (PciData->VendorID == PCI_INVALID_VENDORID) continue;
/* Print out the entry */
- HalpDebugPciBus(i, j, k, PciData);
+ HalpDebugPciDumpBus(i, j, k, PciData);
/* Check if this is a Cardbus bridge */
if (PCI_CONFIGURATION_TYPE(PciData) == PCI_CARDBUS_BRIDGE_TYPE)
return (HalpBusType == MACHINE_TYPE_EISA) ? CM_RESOURCE_PORT_16_BIT_DECODE : 0;
}
+NTSTATUS
+NTAPI
+HaliInitPnpDriver(VOID)
+{
+ /* On PC-AT, this will interface with the PCI driver */
+ return STATUS_SUCCESS;
+}
+
/*
* @implemented
*/
// Halt the system
//
InbvDisplayString("\n*** The system has halted ***\n");
-#endif
+
//
// Enter the debugger if possible
//
+ KiBugCheckData[0] = (ULONG_PTR)KeServiceDescriptorTable; /* NMI Corruption? */
//if (!(KdDebuggerNotPresent) && (KdDebuggerEnabled)) KeEnterKernelDebugger();
-
+#endif
//
// Freeze the system
//
/* GLOBALS *******************************************************************/
+ULONG HalpPerfCounterCutoff;
BOOLEAN HalpClockSetMSRate;
ULONG HalpCurrentTimeIncrement;
ULONG HalpCurrentRollOver;
Flags = __readeflags();
_disable();
- //
- // Program the PIT for binary mode
- //
+ /* Program the PIT for binary mode */
TimerControl.BcdMode = FALSE;
- //
- // Program the PIT to generate a normal rate wave (Mode 3) on channel 0.
- // Channel 0 is used for the IRQ0 clock interval timer, and channel
- // 1 is used for DRAM refresh.
- //
- // Mode 2 gives much better accuracy than Mode 3.
- //
+ /*
+ * Program the PIT to generate a normal rate wave (Mode 3) on channel 0.
+ * Channel 0 is used for the IRQ0 clock interval timer, and channel
+ * 1 is used for DRAM refresh.
+ *
+ * Mode 2 gives much better accuracy than Mode 3.
+ */
TimerControl.OperatingMode = PitOperatingMode2;
TimerControl.Channel = PitChannel0;
- //
- // Set the access mode that we'll use to program the reload value.
- //
+ /* Set the access mode that we'll use to program the reload value */
TimerControl.AccessMode = PitAccessModeLowHigh;
- //
- // Now write the programming bits
- //
+ /* Now write the programming bits */
__outbyte(TIMER_CONTROL_PORT, TimerControl.Bits);
- //
- // Next we write the reload value for channel 0
- //
+ /* Next we write the reload value for channel 0 */
__outbyte(TIMER_CHANNEL0_DATA_PORT, RollOver & 0xFF);
__outbyte(TIMER_CHANNEL0_DATA_PORT, RollOver >> 8);
{
/* Update the performance counter */
HalpPerfCounter.QuadPart += HalpCurrentRollOver;
+ HalpPerfCounterCutoff = KiEnableTimerWatchdog;
/* Check if someone changed the time rate */
if (HalpClockSetMSRate)
<define name="_BLDR_" />
<define name="_MINIHAL_" />
<directory name="generic">
- <directory name="legacy">
- <directory name="bus">
- <file>bushndlr.c</file>
- <file>cmosbus.c</file>
- <file>isabus.c</file>
- <file>pcibus.c</file>
- <file>pcidata.c</file>
- <file>sysbus.c</file>
- </directory>
- <file>bussupp.c</file>
+ <directory name="legacy">
+ <directory name="bus">
+ <file>bushndlr.c</file>
+ <file>cmosbus.c</file>
+ <file>isabus.c</file>
+ <file>pcibus.c</file>
+ <file>sysbus.c</file>
+ </directory>
+ <file>bussupp.c</file>
</directory>
<file>beep.c</file>
<file>bios.c</file>
VOID
);
+NTSTATUS
+NTAPI
+HaliInitPnpDriver(
+ VOID
+);
+
+VOID
+NTAPI
+HalpDebugPciDumpBus(
+ IN ULONG i,
+ IN ULONG j,
+ IN ULONG k,
+ IN PPCI_COMMON_CONFIG PciData
+);
+
#ifdef _M_AMD64
#define KfLowerIrql KeLowerIrql
#ifndef CONFIG_SMP
#endif
#if defined (_MSC_VER)
-#define __MINGW_MSC_PREREQ(major, minor) ((major * 100 + minor * 10) >= _MSC_VER)
+#define __MINGW_MSC_PREREQ(major, minor) (_MSC_VER >= (major * 100 + minor * 10))
#else
#define __MINGW_MSC_PREREQ(major, minor) 0
#endif
#pragma once
+#ifndef DECLSPEC_EXPORT
+#define DECLSPEC_EXPORT __declspec(dllexport)
+#endif
+
typedef struct _USBD_INTERFACE_LIST_ENTRY {
PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
PUSBD_INTERFACE_INFORMATION Interface;
#define KGDT_NMI_TSS (0x58)
#endif
-//
-// KV86M_REGISTERS Offsets
-//
-#define KV86M_REGISTERS_EBP 0x0
-#define KV86M_REGISTERS_EDI 0x4
-#define KV86M_REGISTERS_ESI 0x8
-#define KV86M_REGISTERS_EDX 0xC
-#define KV86M_REGISTERS_ECX 0x10
-#define KV86M_REGISTERS_EBX 0x14
-#define KV86M_REGISTERS_EAX 0x18
-#define KV86M_REGISTERS_DS 0x1C
-#define KV86M_REGISTERS_ES 0x20
-#define KV86M_REGISTERS_FS 0x24
-#define KV86M_REGISTERS_GS 0x28
-#define KV86M_REGISTERS_EIP 0x2C
-#define KV86M_REGISTERS_CS 0x30
-#define KV86M_REGISTERS_EFLAGS 0x34
-#define KV86M_REGISTERS_ESP 0x38
-#define KV86M_REGISTERS_SS 0x3C
-#define TF_SAVED_EXCEPTION_STACK 0x8C
-#define TF_REGS 0x90
-#define TF_ORIG_EBP 0x94
-
//
// TSS Offsets
//
#define KI_EXCEPTION_INTERNAL 0x10000000
#define KI_EXCEPTION_ACCESS_VIOLATION (KI_EXCEPTION_INTERNAL | 0x04)
+#ifndef NTOS_MODE_USER
//
// Number of dispatch codes supported by KINTERRUPT
//
#if (NTDDI_VERSION >= NTDDI_LONGHORN)
-#define KINTERRUPT_DISPATCH_CODES 135
+#define DISPATCH_LENGTH 135
#else
-#define KINTERRUPT_DISPATCH_CODES 106
+#define DISPATCH_LENGTH 106
#endif
-#ifdef NTOS_MODE_USER
+#define SharedUserdata ((KUSER_SHARED_DATA *CONST)(USER_SHARED_DATA|KSEG0_BASE))
+#else
//
// KPROCESSOR_MODE Type
#if (NTDDI_VERSION >= NTDDI_LONGHORN)
ULONGLONG Rsvd1;
#endif
- ULONG DispatchCode[KINTERRUPT_DISPATCH_CODES];
+ ULONG DispatchCode[DISPATCH_LENGTH];
} KINTERRUPT;
//
extern ULONG NTSYSAPI KeMinimumIncrement;
extern ULONG NTSYSAPI KeDcacheFlushCount;
extern ULONG NTSYSAPI KeIcacheFlushCount;
+extern ULONG_PTR NTSYSAPI KiBugCheckData[];
+extern BOOLEAN NTSYSAPI KiEnableTimerWatchdog;
//
// Exported System Service Descriptor Tables
#ifndef __WINE_D3D9TYPES_H
#define __WINE_D3D9TYPES_H
+#if(DIRECT3D_VERSION >= 0x0900)
+
#pragma pack(push, 4)
/*****************************************************************************
#pragma pack(pop)
+#endif /* DIRECT3D_VERSION >= 0x0900 */
+
#endif /* __WINE_D3D9TYPES_H */
/* #include <windows.h> FIXME: Need to include for compatibility. Inclusion caused compile fail */
+#if (DIRECT3D_VERSION >= 0x0800)
+#error "You should not include d3dtypes.h when compiling for DX8 or newer."
+#endif
+
#include <float.h>
#include <ddraw.h>
#define BS_MULTILINE 0x2000
#define BS_NOTIFY 0x4000
#define BS_OWNERDRAW 0xb
+#define BS_TYPEMASK 0xFL
#define BS_PUSHBUTTON 0
#define BS_PUSHLIKE 4096
#define BS_RADIOBUTTON 4
gai_strerrorA(
IN int ecode)
{
- DWORD dwMsgLen;
static char buff[GAI_STRERROR_BUFFER_SIZE + 1];
- dwMsgLen = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM
+ FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM
|FORMAT_MESSAGE_IGNORE_INSERTS
|FORMAT_MESSAGE_MAX_WIDTH_MASK,
NULL,
gai_strerrorW(
IN int ecode)
{
- DWORD dwMsgLen;
static WCHAR buff[GAI_STRERROR_BUFFER_SIZE + 1];
- dwMsgLen = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM
+ FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM
|FORMAT_MESSAGE_IGNORE_INSERTS
|FORMAT_MESSAGE_MAX_WIDTH_MASK,
NULL,
--- /dev/null
+/*
+ * PROJECT: ReactOS ComPort Library
+ * LICENSE: BSD - See COPYING.ARM in the top level directory
+ * FILE: include/reactos/drivers/serial/ns16550.h
+ * PURPOSE: Header for National Semiconductor 16550 UART
+ * PROGRAMMERS: ReactOS Portable Systems Group
+ */
+
+/* INCLUDES *******************************************************************/
+
+#pragma once
+
+/* Note: These definitions are the internal definitions used by Microsoft serial
+ driver (see src/kernel/serial/serial.h in WDK source code). Linux uses its own, as
+ do most other OS.
+*/
+
+#if !defined(SERIAL_REGISTER_STRIDE)
+#define SERIAL_REGISTER_STRIDE 1
+#endif
+
+#define RECEIVE_BUFFER_REGISTER ((ULONG)((0x00)*SERIAL_REGISTER_STRIDE))
+#define TRANSMIT_HOLDING_REGISTER ((ULONG)((0x00)*SERIAL_REGISTER_STRIDE))
+#define INTERRUPT_ENABLE_REGISTER ((ULONG)((0x01)*SERIAL_REGISTER_STRIDE))
+#define INTERRUPT_IDENT_REGISTER ((ULONG)((0x02)*SERIAL_REGISTER_STRIDE))
+#define FIFO_CONTROL_REGISTER ((ULONG)((0x02)*SERIAL_REGISTER_STRIDE))
+#define LINE_CONTROL_REGISTER ((ULONG)((0x03)*SERIAL_REGISTER_STRIDE))
+#define MODEM_CONTROL_REGISTER ((ULONG)((0x04)*SERIAL_REGISTER_STRIDE))
+#define LINE_STATUS_REGISTER ((ULONG)((0x05)*SERIAL_REGISTER_STRIDE))
+#define MODEM_STATUS_REGISTER ((ULONG)((0x06)*SERIAL_REGISTER_STRIDE))
+#define DIVISOR_LATCH_LSB ((ULONG)((0x00)*SERIAL_REGISTER_STRIDE))
+#define DIVISOR_LATCH_MSB ((ULONG)((0x01)*SERIAL_REGISTER_STRIDE))
+#define SERIAL_REGISTER_SPAN ((ULONG)(7*SERIAL_REGISTER_STRIDE))
+#define SERIAL_STATUS_LENGTH ((ULONG)(1*SERIAL_REGISTER_STRIDE))
+
+#define SERIAL_DATA_LENGTH_5 0x00
+#define SERIAL_DATA_LENGTH_6 0x01
+#define SERIAL_DATA_LENGTH_7 0x02
+#define SERIAL_DATA_LENGTH_8 0x03
+
+#define SERIAL_IER_RDA 0x01
+#define SERIAL_IER_THR 0x02
+#define SERIAL_IER_RLS 0x04
+#define SERIAL_IER_MS 0x08
+
+#define SERIAL_IIR_RLS 0x06
+#define SERIAL_IIR_RDA 0x04
+#define SERIAL_IIR_CTI 0x0c
+#define SERIAL_IIR_THR 0x02
+#define SERIAL_IIR_MS 0x00
+#define SERIAL_IIR_FIFOS_ENABLED 0xc0
+#define SERIAL_IIR_NO_INTERRUPT_PENDING 0x01
+#define SERIAL_IIR_MUST_BE_ZERO 0x30
+
+#define SERIAL_FCR_ENABLE ((UCHAR)0x01)
+#define SERIAL_FCR_RCVR_RESET ((UCHAR)0x02)
+#define SERIAL_FCR_TXMT_RESET ((UCHAR)0x04)
+
+#define SERIAL_1_BYTE_HIGH_WATER ((UCHAR)0x00)
+#define SERIAL_4_BYTE_HIGH_WATER ((UCHAR)0x40)
+#define SERIAL_8_BYTE_HIGH_WATER ((UCHAR)0x80)
+#define SERIAL_14_BYTE_HIGH_WATER ((UCHAR)0xc0)
+
+#define SERIAL_LCR_DLAB 0x80
+#define SERIAL_LCR_BREAK 0x40
+
+#define SERIAL_5_DATA ((UCHAR)0x00)
+#define SERIAL_6_DATA ((UCHAR)0x01)
+#define SERIAL_7_DATA ((UCHAR)0x02)
+#define SERIAL_8_DATA ((UCHAR)0x03)
+#define SERIAL_DATA_MASK ((UCHAR)0x03)
+
+#define SERIAL_1_STOP ((UCHAR)0x00)
+#define SERIAL_1_5_STOP ((UCHAR)0x04) // Only valid for 5 data bits
+#define SERIAL_2_STOP ((UCHAR)0x04) // Not valid for 5 data bits
+#define SERIAL_STOP_MASK ((UCHAR)0x04)
+
+#define SERIAL_NONE_PARITY ((UCHAR)0x00)
+#define SERIAL_ODD_PARITY ((UCHAR)0x08)
+#define SERIAL_EVEN_PARITY ((UCHAR)0x18)
+#define SERIAL_MARK_PARITY ((UCHAR)0x28)
+#define SERIAL_SPACE_PARITY ((UCHAR)0x38)
+#define SERIAL_PARITY_MASK ((UCHAR)0x38)
+
+#define SERIAL_MCR_DTR 0x01
+#define SERIAL_MCR_RTS 0x02
+#define SERIAL_MCR_OUT1 0x04
+#define SERIAL_MCR_OUT2 0x08
+#define SERIAL_MCR_LOOP 0x10
+#define SERIAL_MCR_TL16C550CAFE 0x20
+
+#define SERIAL_LSR_DR 0x01
+#define SERIAL_LSR_OE 0x02
+#define SERIAL_LSR_PE 0x04
+#define SERIAL_LSR_FE 0x08
+#define SERIAL_LSR_BI 0x10
+#define SERIAL_LSR_THRE 0x20
+#define SERIAL_LSR_TEMT 0x40
+#define SERIAL_LSR_FIFOERR 0x80
+
+#define SERIAL_MSR_DCTS 0x01
+#define SERIAL_MSR_DDSR 0x02
+#define SERIAL_MSR_TERI 0x04
+#define SERIAL_MSR_DDCD 0x08
+#define SERIAL_MSR_CTS 0x10
+#define SERIAL_MSR_DSR 0x20
+#define SERIAL_MSR_RI 0x40
+#define SERIAL_MSR_DCD 0x80
--- /dev/null
+/*
+ * PROJECT: ReactOS ComPort Library
+ * LICENSE: BSD - See COPYING.ARM in the top level directory
+ * FILE: include/reactos/lib/cportlib/cportlib.h
+ * PURPOSE: Header for the ComPort Library
+ * PROGRAMMERS: ReactOS Portable Systems Group
+ */
+
+/* INCLUDES *******************************************************************/
+
+#include <ntdef.h>
+
+#define CP_GET_SUCCESS 0
+#define CP_GET_NODATA 1
+#define CP_GET_ERROR 2
+
+#define CPPORT_FLAG_MODEM_CONTROL 0x02
+typedef struct _CPPORT
+{
+ PUCHAR Address;
+ ULONG Baud;
+ USHORT Flags;
+} CPPORT, *PCPPORT;
+
+VOID
+NTAPI
+CpInitialize(
+ IN PCPPORT Port,
+ IN PUCHAR Address,
+ IN ULONG Rate
+ );
+
+VOID
+NTAPI
+CpEnableFifo(
+ IN PUCHAR Address,
+ IN BOOLEAN Enable
+ );
+
+BOOLEAN
+NTAPI
+CpDoesPortExist(
+ IN PUCHAR Address
+ );
+
+UCHAR
+NTAPI
+CpReadLsr(
+ IN PCPPORT Port,
+ IN UCHAR ExpectedValue
+ );
+
+VOID
+NTAPI
+CpSetBaud(
+ IN PCPPORT Port,
+ IN ULONG Rate
+ );
+
+USHORT
+NTAPI
+CpGetByte(
+ IN PCPPORT Port,
+ IN PUCHAR Byte,
+ IN BOOLEAN Wait,
+ IN BOOLEAN Poll
+ );
+
+VOID
+NTAPI
+CpPutByte(
+ IN PCPPORT Port,
+ IN UCHAR Byte
+ );
FT_Get_Char_Index
FT_Get_Charmap_Index
FT_Get_CID_From_Glyph_Index
- FT_Get_CID_Is_Internally_CID_keyed
+ FT_Get_CID_Is_Internally_CID_Keyed
FT_Get_CID_Registry_Ordering_Supplement
FT_Get_First_Char
FT_Get_FSType_Flags
--- /dev/null
+/*
+ * PROJECT: ReactOS ComPort Library
+ * LICENSE: BSD - See COPYING.ARM in the top level directory
+ * FILE: lib/reactos/cportlib/cport.c
+ * PURPOSE: Provides a serial port library for KDCOM, INIT, and FREELDR
+ * PROGRAMMERS: ReactOS Portable Systems Group
+ */
+
+/* NOTE: This library follows the precise serial port intialization steps documented
+ * by Microsoft in some of their Server hardware guidance. Because they've clearly
+ * documented their serial algorithms, we use the same ones to stay "compliant".
+ * Do not change this code to "improve" it. It's done this way on purpose, at least on x86.
+ * -- sir_richard
+ */
+
+/* NOTE: This code is used by Headless Support (Ntoskrnl.exe and Osloader.exe) and
+ Kdcom.dll in Windows. It may be that WinDBG depends on some of these quirks.
+*/
+
+/* NOTE: The original code supports Modem Control. We currently do not */
+
+/* FIXMEs:
+ - Make this serial-port specific (NS16550 vs other serial port types)
+ - Get x64 KDCOM, KDBG, FREELDR, and other current code to use this
+*/
+
+/* INCLUDES *******************************************************************/
+
+#include <cportlib/cportlib.h>
+#include <drivers/serial/ns16550.h>
+#include <intrin.h>
+#include <ioaccess.h>
+#include <debug.h>
+
+/* GLOBALS ********************************************************************/
+
+UCHAR RingIndicator;
+
+/* FUNCTIONS ******************************************************************/
+
+VOID
+NTAPI
+CpInitialize(IN PCPPORT Port,
+ IN PUCHAR Address,
+ IN ULONG Rate)
+{
+ /* Reset port data */
+ Port->Address = Address;
+ Port->Baud = 0;
+
+ /* Set the baud rate */
+ CpSetBaud(Port, Rate);
+
+ /* Enable on DTR and RTS */
+ WRITE_PORT_UCHAR(Address + MODEM_CONTROL_REGISTER,
+ SERIAL_MCR_DTR | SERIAL_MCR_RTS);
+
+ /* Disable interrupts */
+ WRITE_PORT_UCHAR(Address + INTERRUPT_ENABLE_REGISTER, 0);
+}
+
+VOID
+NTAPI
+CpEnableFifo(IN PUCHAR Address,
+ IN BOOLEAN Enable)
+{
+ /* Set FIFO */
+ WRITE_PORT_UCHAR(Address + FIFO_CONTROL_REGISTER, Enable ? SERIAL_FCR_ENABLE : 0);
+}
+
+BOOLEAN
+NTAPI
+CpDoesPortExist(IN PUCHAR Address)
+{
+ UCHAR Old;
+ /*
+ * See "Building Hardware and Firmware to Complement Microsoft Windows Headless Operation"
+ * Out-of-Band Management Port Device Requirements:
+ * The device must act as a 16550 or 16450 UART.
+ * Windows Server 2003 will test this device using the following process.
+ * 1. Save off the current modem status register.
+ * 2. Place the UART into diagnostic mode (The UART is placed into loopback mode
+ * by writing SERIAL_MCR_LOOP to the modem control register).
+ * 3. The modem status register is read and the high bits are checked. This means
+ * SERIAL_MSR_CTS, SERIAL_MSR_DSR, SERIAL_MSR_RI and SERIAL_MSR_DCD should
+ * all be clear.
+ * 4. Place the UART in diagnostic mode and turn on OUTPUT (Loopback Mode and
+ * OUTPUT are both turned on by writing (SERIAL_MCR_LOOP | SERIAL_MCR_OUT1)
+ * to the modem control register).
+ * 5. The modem status register is read and the ring indicator is checked.
+ * This means SERIAL_MSR_RI should be set.
+ * 6. Restore original modem status register.
+ */
+ Old = READ_PORT_UCHAR(Address + MODEM_CONTROL_REGISTER);
+ WRITE_PORT_UCHAR(Address + MODEM_CONTROL_REGISTER, SERIAL_MCR_LOOP);
+ WRITE_PORT_UCHAR(Address + MODEM_CONTROL_REGISTER, SERIAL_MCR_LOOP);
+ if (!(READ_PORT_UCHAR(Address + MODEM_STATUS_REGISTER) &
+ (SERIAL_MSR_CTS | SERIAL_MSR_DSR | SERIAL_MSR_RI | SERIAL_MSR_DCD)))
+ {
+ WRITE_PORT_UCHAR(Address + MODEM_CONTROL_REGISTER,
+ (SERIAL_MCR_OUT1 | SERIAL_MCR_LOOP));
+ if (READ_PORT_UCHAR(Address + MODEM_STATUS_REGISTER) & SERIAL_MSR_RI)
+ {
+ WRITE_PORT_UCHAR(Address + MODEM_CONTROL_REGISTER, Old);
+ return TRUE;
+ }
+ }
+ WRITE_PORT_UCHAR(Address + MODEM_CONTROL_REGISTER, Old);
+ return FALSE;
+}
+
+UCHAR
+NTAPI
+CpReadLsr(IN PCPPORT Port,
+ IN UCHAR ExpectedValue)
+{
+ UCHAR Lsr, Msr;
+
+ /* Read the LSR and check if the expected value is present */
+ Lsr = READ_PORT_UCHAR(Port->Address + LINE_STATUS_REGISTER);
+ if (!(Lsr & ExpectedValue))
+ {
+ /* Check the MSR for ring indicator toggle */
+ Msr = READ_PORT_UCHAR(Port->Address + MODEM_STATUS_REGISTER);
+
+ /* If the indicator reaches 3, we've seen this on/off twice */
+ RingIndicator |= (Msr & SERIAL_MSR_RI) ? 1 : 2;
+ if (RingIndicator == 3) Port->Flags |= CPPORT_FLAG_MODEM_CONTROL;
+ }
+
+ return Lsr;
+}
+
+VOID
+NTAPI
+CpSetBaud(IN PCPPORT Port,
+ IN ULONG Rate)
+{
+ UCHAR Lcr;
+ USHORT Mode;
+
+ /* Add DLAB */
+ Lcr = READ_PORT_UCHAR(Port->Address + LINE_CONTROL_REGISTER);
+ WRITE_PORT_UCHAR(Port->Address + LINE_CONTROL_REGISTER, Lcr | SERIAL_LCR_DLAB);
+
+ /* Set baud rate */
+ Mode = 115200 / Rate;
+ WRITE_PORT_UCHAR(Port->Address + DIVISOR_LATCH_MSB, (UCHAR)((Mode >> 8) & 0xff));
+ WRITE_PORT_UCHAR(Port->Address + DIVISOR_LATCH_LSB, (UCHAR)(Mode & 0xff));
+
+ /* Reset DLAB and set 8 data bits, 1 stop bit, no parity, no break */
+ WRITE_PORT_UCHAR(Port->Address + LINE_CONTROL_REGISTER,
+ SERIAL_8_DATA | SERIAL_1_STOP | SERIAL_NONE_PARITY);
+
+ /* Save baud rate in port */
+ Port->Baud = Rate;
+}
+
+USHORT
+NTAPI
+CpGetByte(IN PCPPORT Port,
+ IN PUCHAR Byte,
+ IN BOOLEAN Wait,
+ IN BOOLEAN Poll)
+{
+ UCHAR Lsr;
+ ULONG i;
+
+ /* Handle early read-before-init */
+ if (!Port->Address) return CP_GET_NODATA;
+
+ /* If "wait" mode enabled, spin many times, otherwise attempt just once */
+ i = Wait ? 204800 : 1;
+ while (i--)
+ {
+ /* Read LSR for data ready */
+ Lsr = CpReadLsr(Port, SERIAL_LSR_DR);
+ if ((Lsr & SERIAL_LSR_DR) == SERIAL_LSR_DR)
+ {
+ /* If an error happened, clear the byte and fail */
+ if (Lsr & (SERIAL_LSR_FE | SERIAL_LSR_PE))
+ {
+ *Byte = 0;
+ return CP_GET_ERROR;
+ }
+
+ /* If only polling was requested by caller, return now */
+ if (Poll) return CP_GET_SUCCESS;
+
+ /* Otherwise read the byte and return it */
+ *Byte = READ_PORT_UCHAR(Port->Address + RECEIVE_BUFFER_REGISTER);
+
+ /* Handle CD if port is in modem control mode */
+ if (Port->Flags & CPPORT_FLAG_MODEM_CONTROL)
+ {
+ /* Not implemented yet */
+ DPRINT1("CP: CPPORT_FLAG_MODEM_CONTROL unexpected\n");
+ }
+
+ /* Byte was read */
+ return CP_GET_SUCCESS;
+ }
+ }
+
+ /* Reset LSR, no data was found */
+ CpReadLsr(Port, 0);
+ return CP_GET_NODATA;
+}
+
+VOID
+NTAPI
+CpPutByte(IN PCPPORT Port,
+ IN UCHAR Byte)
+{
+ /* Check if port is in modem control to handle CD */
+ while (Port->Flags & CPPORT_FLAG_MODEM_CONTROL)
+ {
+ /* Not implemented yet */
+ DPRINT1("CP: CPPORT_FLAG_MODEM_CONTROL unexpected\n");
+ }
+
+ /* Wait for LSR to say we can go ahead */
+ while (!(CpReadLsr(Port, SERIAL_LSR_THRE) & SERIAL_LSR_THRE));
+
+ /* Send the byte */
+ WRITE_PORT_UCHAR(Port->Address + RECEIVE_BUFFER_REGISTER, Byte);
+}
--- /dev/null
+<?xml version="1.0"?>
+<!DOCTYPE module SYSTEM "../../tools/rbuild/project.dtd">
+<group>
+ <module name="cportlib" type="staticlibrary">
+ <include base="cportlib">.</include>
+ <file>cport.c</file>
+ </module>
+</group>
TcpipInitializeSpinLock(&IF->Lock);
IF->TCPContext = ExAllocatePoolWithTag
- ( NonPagedPool, sizeof(OSK_IFADDR) + 2 * sizeof( struct sockaddr_in ),
+ ( NonPagedPool, sizeof(OSK_IFADDR) + 3 * sizeof( struct sockaddr_in ),
OSKITTCP_CONTEXT_TAG );
if (!IF->TCPContext) {
ExFreePoolWithTag(IF, IP_INTERFACE_TAG);
POSK_IFADDR ifaddr = IF->TCPContext;
struct sockaddr_in *addr_in;
struct sockaddr_in *dstaddr_in;
+ struct sockaddr_in *netmask_in;
ASSERT(ifaddr);
- RtlZeroMemory(ifaddr, sizeof(OSK_IFADDR) + 2 * sizeof( struct sockaddr_in ));
+ RtlZeroMemory(ifaddr, sizeof(OSK_IFADDR) + 3 * sizeof( struct sockaddr_in ));
addr_in = (struct sockaddr_in *)&ifaddr[1];
dstaddr_in = (struct sockaddr_in *)&addr_in[1];
+ netmask_in = (struct sockaddr_in *)&dstaddr_in[1];
TI_DbgPrint(DEBUG_TCPIF,("Called\n"));
- ifaddr->ifa_dstaddr = (struct sockaddr *)dstaddr_in;
-
- /* XXX - Point-to-point interfaces not supported yet */
- memset( &ifaddr->ifa_dstaddr, 0, sizeof( struct sockaddr ) );
-
ifaddr->ifa_addr = (struct sockaddr *)addr_in;
Status = GetInterfaceIPv4Address( IF,
ADE_UNICAST,
ASSERT(NT_SUCCESS(Status));
+ ifaddr->ifa_dstaddr = (struct sockaddr *)dstaddr_in;
+ Status = GetInterfaceIPv4Address(IF,
+ ADE_POINTOPOINT,
+ (PULONG)&dstaddr_in->sin_addr.s_addr );
+
+ ASSERT(NT_SUCCESS(Status));
+
+ ifaddr->ifa_netmask = (struct sockaddr *)netmask_in;
+ Status = GetInterfaceIPv4Address(IF,
+ ADE_ADDRMASK,
+ (PULONG)&netmask_in->sin_addr.s_addr );
+
+ ASSERT(NT_SUCCESS(Status));
+
TI_DbgPrint(DEBUG_TCPIF,("interface %x : addr %x\n",
IF, addr_in->sin_addr.s_addr));
- ifaddr->ifa_flags = 0; /* XXX what goes here? */
+ ifaddr->ifa_flags = 0;
ifaddr->ifa_refcnt = 0; /* Anachronistic */
ifaddr->ifa_metric = 1; /* We can get it like in ninfo.c, if we want */
ifaddr->ifa_mtu = IF->MTU;
struct iovec iov = { 0 };
int error = 0;
int tcp_flags = 0;
+
+ if (!connection)
+ return OSK_ESHUTDOWN;
OS_DbgPrint(OSK_MID_TRACE,
("so->so_state %x\n", ((struct socket *)connection)->so_state));
struct sockaddr addr;
OS_DbgPrint(OSK_MID_TRACE,("Called, socket = %08x\n", socket));
-
- OSKLock();
- if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) {
- error = EALREADY;
- goto done;
- }
+
+ if (!socket)
+ return OSK_ESHUTDOWN;
OS_DbgPrint(OSK_MIN_TRACE,("Nam: %x\n", nam));
+
if( nam )
addr = *((struct sockaddr *)nam);
addr.sa_family = addr.sa_len;
addr.sa_len = sizeof(struct sockaddr);
+ OSKLock();
error = soconnect(so, &sabuf);
+ OSKUnlock();
- if (error == EINPROGRESS)
- goto done;
- else if (error)
- goto bad;
-
- if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) {
- error = EINPROGRESS;
- goto done;
- }
-
-bad:
- so->so_state &= ~SS_ISCONNECTING;
-
- if (error == ERESTART)
- error = EINTR;
+ if (error == 0) error = OSK_EINPROGRESS;
-done:
- OSKUnlock();
OS_DbgPrint(OSK_MID_TRACE,("Ending: %08x\n", error));
return (error);
}
if (!socket)
return OSK_ESHUTDOWN;
- if (!new_socket || !AddrOut)
+ if (!new_socket)
return OSK_EINVAL;
OS_DbgPrint(OSK_MID_TRACE,("OSKITTCP: Doing accept (Finish %d)\n",
FinishAccepting));
- *OutAddrLen = AddrLen;
-
if (name)
/* that's a copyin actually */
namelen = *OutAddrLen;
s = splnet();
-#if 0
if ((head->so_options & SO_ACCEPTCONN) == 0) {
OS_DbgPrint(OSK_MID_TRACE,("OSKITTCP: head->so_options = %x, wanted bit %x\n",
head->so_options, SO_ACCEPTCONN));
error = EINVAL;
goto out;
}
-#endif
OS_DbgPrint(OSK_MID_TRACE,("head->so_q = %x, head->so_state = %x\n",
head->so_q, head->so_state));
- if ((head->so_state & SS_NBIO) && head->so_q == NULL) {
+ if (head->so_q == NULL) {
error = EWOULDBLOCK;
goto out;
}
OS_DbgPrint(OSK_MID_TRACE,("error = %d\n", error));
if( FinishAccepting && so ) {
- head->so_q = so->so_q;
- head->so_qlen--;
mnam.m_data = (char *)&sa;
mnam.m_len = sizeof(sa);
if (error)
goto out;
- InitializeSocketFlags(so);
- so->so_state |= SS_ISCONNECTED;
- so->so_q = so->so_q0 = NULL;
- so->so_qlen = so->so_q0len = 0;
- so->so_head = 0;
+ soqremque(so, 1);
so->so_connection = context;
+ soisconnected(so);
*newso = so;
<directory name="cmlib">
<xi:include href="cmlib/cmlib.rbuild" />
</directory>
+ <directory name="cportlib">
+ <xi:include href="cportlib/cportlib.rbuild" />
+ </directory>
<directory name="debugsup">
<xi:include href="debugsup/debugsup.rbuild" />
</directory>
current_entry = CacheSegmentLRUListHead.Flink;
while (current_entry != &CacheSegmentLRUListHead && Target > 0)
{
- NTSTATUS Status;
-
- Status = STATUS_SUCCESS;
current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT,
CacheSegmentLRUListEntry);
current_entry = current_entry->Flink;
{
PFN_NUMBER Page;
Page = (PFN_NUMBER)(MmGetPhysicalAddress((char*)current->BaseAddress + i * PAGE_SIZE).QuadPart >> PAGE_SHIFT);
- Status = MmPageOutPhysicalAddress(Page);
+ MmPageOutPhysicalAddress(Page);
}
KeAcquireGuardedMutex(&ViewLock);
KeAcquireSpinLock(¤t->Bcb->BcbLock, &oldIrql);
{
PLIST_ENTRY current_entry;
PCACHE_SEGMENT current;
- NTSTATUS Status;
LIST_ENTRY FreeList;
KIRQL oldIrql;
{
current_entry = RemoveTailList(&FreeList);
current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, BcbSegmentListEntry);
- Status = CcRosInternalFreeCacheSegment(current);
+ CcRosInternalFreeCacheSegment(current);
}
ExFreeToNPagedLookasideList(&BcbLookasideList, Bcb);
KeAcquireGuardedMutex(&ViewLock);
OUT PULONG OuterStackArray,
OUT PULONG *LockedKcbs)
{
- ULONG HashKeyCopy;
-
/* We don't lock anything for now */
*LockedKcbs = NULL;
- /* Make a copy of the hash key */
- HashKeyCopy = (*Kcb)->ConvKey;
-
/* Calculate hash values */
*TotalRemainingSubkeys = 0xBAADF00D;
if (CmHive->Hive.Cluster != ClusterSize) ASSERT(FALSE);
/* Set the file size */
+ DPRINT("FIXME: Should set file size: %lx\n", Length);
//if (!CmpFileSetSize((PHHIVE)CmHive, HFILE_TYPE_PRIMARY, Length, Length))
{
/* This shouldn't fail */
UNICODE_STRING TempName, FileName, RegName;
HANDLE Thread;
NTSTATUS Status;
- ULONG FileStart, RegStart, i;
+ ULONG RegStart, i;
PSECURITY_DESCRIPTOR SecurityDescriptor;
PAGED_CODE();
CmpGetRegistryPath(ConfigPath);
RtlInitUnicodeString(&TempName, ConfigPath);
RtlAppendStringToString((PSTRING)&FileName, (PSTRING)&TempName);
- FileStart = FileName.Length;
/* And build the registry root path */
RtlInitUnicodeString(&TempName, L"\\REGISTRY\\");
OUT PULONG ResultLength,
OUT PNTSTATUS Status)
{
- PHHIVE Hive;
PKEY_VALUE_INFORMATION Info = (PKEY_VALUE_INFORMATION)KeyValueInformation;
PCELL_DATA CellData;
USHORT NameSize;
HCELL_INDEX CellToRelease = HCELL_NIL;
VALUE_SEARCH_RETURN_TYPE Result = SearchSuccess;
- /* Get the hive and cell data */
- Hive = Kcb->KeyHive;
+ /* Get the value data */
CellData = (PCELL_DATA)ValueKey;
/* Check if the value is compressed */
{
UNICODE_STRING KeyName, ValueName, Data, SectionName;
OBJECT_ATTRIBUTES ObjectAttributes;
- ULONG HavePae, CacheSize, Length, TotalLength = 0, i, Disposition;
+ ULONG HavePae, Length, TotalLength = 0, i, Disposition;
SIZE_T ViewSize;
NTSTATUS Status;
HANDLE KeyHandle, BiosHandle, SystemHandle, FpuHandle, SectionHandle;
}
}
- /* Get the cache size while we're still localized */
- CacheSize = ((PKIPCR)KeGetPcr())->SecondLevelCacheSize;
-
/* Go back to user affinity */
KeRevertToUserAffinityThread();
/*
* PROJECT: ReactOS Kernel
- * LICENSE: GPL - See COPYING in the top level directory
+ * LICENSE: BSD - See COPYING.ARM in the top level directory
* FILE: ntoskrnl/ex/hdlsterm.c
* PURPOSE: Headless Terminal Support
- * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
+ * PROGRAMMERS: ReactOS Portable Systems Group
*/
/* INCLUDES ******************************************************************/
/* GLOBALS *******************************************************************/
+PHEADLESS_GLOBALS HeadlessGlobals;
+
/* FUNCTIONS *****************************************************************/
VOID
NTAPI
-HeadlessInit(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
+HdlspSendStringAtBaud(
+ IN PUCHAR String
+ )
{
- PHEADLESS_LOADER_BLOCK HeadlessBlock;
-
- /* Get the headless loader block */
- HeadlessBlock = LoaderBlock->Extension->HeadlessLoaderBlock;
- if (HeadlessBlock)
- {
- DPRINT1("ReactOS does not currently have Headless Terminal support!\n");
- }
+ /* Send every byte */
+ while (*String++ != ANSI_NULL)
+ {
+ InbvPortPutByte(HeadlessGlobals->TerminalPort, *String);
+ }
+}
+
+NTSTATUS
+NTAPI
+HdlspEnableTerminal(
+ IN BOOLEAN Enable
+ )
+{
+ /* Enable if requested, as long as this isn't a PCI serial port crashing */
+ if ((Enable) &&
+ !(HeadlessGlobals->TerminalEnabled) &&
+ !((HeadlessGlobals->IsMMIODevice) && (HeadlessGlobals->InBugCheck)))
+ {
+ /* Initialize the COM port with cportlib */
+ HeadlessGlobals->TerminalEnabled = InbvPortInitialize(
+ HeadlessGlobals->TerminalBaudRate,
+ HeadlessGlobals->TerminalPortNumber,
+ HeadlessGlobals->TerminalPortAddress,
+ &HeadlessGlobals->TerminalPort,
+ HeadlessGlobals->IsMMIODevice);
+ if (!HeadlessGlobals->TerminalEnabled) return STATUS_UNSUCCESSFUL;
+
+ /* Cleanup the screen and reset the cursor */
+ HdlspSendStringAtBaud((PUCHAR)"\x1B[2J");
+ HdlspSendStringAtBaud((PUCHAR)"\x1B[H");
+
+ /* Enable FIFO */
+ InbvPortEnableFifo(HeadlessGlobals->TerminalPort, TRUE);
+ }
+ else if (!Enable)
+ {
+ /* Specific case when headless is being disabled */
+ InbvPortTerminate(HeadlessGlobals->TerminalPort);
+ HeadlessGlobals->TerminalPort = 0;
+ HeadlessGlobals->TerminalEnabled = FALSE;
+ }
+ return STATUS_SUCCESS;
}
+VOID
+NTAPI
+HeadlessInit(
+ IN PLOADER_PARAMETER_BLOCK LoaderBlock
+ )
+{
+ PHEADLESS_LOADER_BLOCK HeadlessBlock;
+
+ HeadlessBlock = LoaderBlock->Extension->HeadlessLoaderBlock;
+ if (!HeadlessBlock) return;
+ if ((HeadlessBlock->PortNumber > 4) && (HeadlessBlock->UsedBiosSettings)) return;
+
+ HeadlessGlobals = ExAllocatePoolWithTag(
+ NonPagedPool,
+ sizeof(HEADLESS_GLOBALS),
+ 'sldH');
+ if (!HeadlessGlobals) return;
+
+ /* Zero and copy loader data */
+ RtlZeroMemory(HeadlessGlobals, sizeof(HEADLESS_GLOBALS));
+ HeadlessGlobals->TerminalPortNumber = HeadlessBlock->PortNumber;
+ HeadlessGlobals->TerminalPortAddress = HeadlessBlock->PortAddress;
+ HeadlessGlobals->TerminalBaudRate = HeadlessBlock->BaudRate;
+ HeadlessGlobals->TerminalParity = HeadlessBlock->Parity;
+ HeadlessGlobals->TerminalStopBits = HeadlessBlock->StopBits;
+ HeadlessGlobals->UsedBiosSettings = HeadlessBlock->UsedBiosSettings;
+ HeadlessGlobals->IsMMIODevice = HeadlessBlock->IsMMIODevice;
+ HeadlessGlobals->TerminalType = HeadlessBlock->TerminalType;
+ HeadlessGlobals->SystemGUID = HeadlessBlock->SystemGUID;
+
+ /* These two are opposites of each other */
+ if (HeadlessGlobals->IsMMIODevice) HeadlessGlobals->IsNonLegacyDevice = TRUE;
+
+ /* Check for a PCI device, warn that this isn't supported */
+ if (HeadlessBlock->PciDeviceId != PCI_INVALID_VENDORID)
+ {
+ DPRINT1("PCI Serial Ports not supported\n");
+ }
+
+ /* Log entries are not yet supported */
+ DPRINT1("FIXME: No Headless logging support\n");
+
+ /* Allocate temporary buffer */
+ HeadlessGlobals->TmpBuffer = ExAllocatePoolWithTag(NonPagedPool, 80, 'sldH');
+ if (!HeadlessGlobals->TmpBuffer) return;
+
+ /* Windows seems to apply some special hacks for 9600 bps */
+ if (HeadlessGlobals->TerminalBaudRate == 9600)
+ {
+ DPRINT1("Please use other baud rate than 9600bps for now\n");
+ }
+
+ /* Enable the terminal */
+ HdlspEnableTerminal(TRUE);
+}
+
+VOID
+NTAPI
+HdlspPutString(
+ IN PUCHAR String
+ )
+{
+ PUCHAR Dest = HeadlessGlobals->TmpBuffer;
+ UCHAR Char = 0;
+
+ /* Scan each character */
+ while (*String != ANSI_NULL)
+ {
+ /* Check for rotate, send existing buffer and restart from where we are */
+ if (Dest >= &HeadlessGlobals->TmpBuffer[79])
+ {
+ HeadlessGlobals->TmpBuffer[79] = ANSI_NULL;
+ HdlspSendStringAtBaud(HeadlessGlobals->TmpBuffer);
+ Dest = HeadlessGlobals->TmpBuffer;
+ }
+ else
+ {
+ /* Get the current character and check for special graphical chars */
+ Char = *String;
+ if (Char & 0x80)
+ {
+ switch (Char)
+ {
+ case 0xB0: case 0xB3: case 0xBA:
+ Char = '|';
+ break;
+ case 0xB1: case 0xDC: case 0xDD: case 0xDE: case 0xDF:
+ Char = '%';
+ break;
+ case 0xB2: case 0xDB:
+ Char = '#';
+ break;
+ case 0xA9: case 0xAA: case 0xBB: case 0xBC: case 0xBF:
+ case 0xC0: case 0xC8: case 0xC9: case 0xD9: case 0xDA:
+ Char = '+';
+ break;
+ case 0xC4:
+ Char = '-';
+ break;
+ case 0xCD:
+ Char = '=';
+ break;
+ }
+ }
+
+ /* Anything else must be Unicode */
+ if (Char & 0x80)
+ {
+ /* Can't do Unicode yet */
+ UNIMPLEMENTED;
+ }
+ else
+ {
+ /* Add the modified char to the temporary buffer */
+ *Dest++ = Char;
+ }
+
+ /* Check the next char */
+ String++;
+ }
+ }
+
+ /* Finish and send */
+ *Dest = ANSI_NULL;
+ HdlspSendStringAtBaud(HeadlessGlobals->TmpBuffer);
+}
+
+NTSTATUS
+NTAPI
+HdlspDispatch(
+ IN HEADLESS_CMD Command,
+ IN PVOID InputBuffer,
+ IN SIZE_T InputBufferSize,
+ OUT PVOID OutputBuffer,
+ OUT PSIZE_T OutputBufferSize
+ )
+{
+ NTSTATUS Status = STATUS_NOT_IMPLEMENTED;
+ ASSERT(HeadlessGlobals != NULL);
+// ASSERT(HeadlessGlobals->PageLockHandle != NULL);
+
+ /* FIXME: This should be using the headless spinlock */
+
+ /* Ignore non-reentrant commands */
+ if ((Command != HeadlessCmdAddLogEntry) &&
+ (Command != HeadlessCmdStartBugCheck) &&
+ (Command != HeadlessCmdSendBlueScreenData) &&
+ (Command != HeadlessCmdDoBugCheckProcessing))
+ {
+ if (HeadlessGlobals->ProcessingCmd) return STATUS_UNSUCCESSFUL;
+
+ /* Don't allow these commands next time */
+ HeadlessGlobals->ProcessingCmd = TRUE;
+ }
+
+ /* Handle each command */
+ switch (Command)
+ {
+ case HeadlessCmdEnableTerminal:
+ break;
+ case HeadlessCmdCheckForReboot:
+ break;
+
+ case HeadlessCmdPutString:
+
+ /* Validate the existence of an input buffer */
+ if (!InputBuffer)
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ goto Reset;
+ }
+
+ /* Terminal should be on */
+ if (HeadlessGlobals->TerminalEnabled)
+ {
+ /* Print each byte in the string making sure VT100 chars are used */
+ PHEADLESS_CMD_PUT_STRING PutString = (PVOID)InputBuffer;
+ HdlspPutString(PutString->String);
+ }
+
+ /* Return success either way */
+ Status = STATUS_SUCCESS;
+ break;
+ case HeadlessCmdClearDisplay:
+ break;
+ case HeadlessCmdClearToEndOfDisplay:
+ break;
+ case HeadlessCmdClearToEndOfLine:
+ break;
+ case HeadlessCmdDisplayAttributesOff:
+ break;
+ case HeadlessCmdDisplayInverseVideo:
+ break;
+ case HeadlessCmdSetColor:
+ break;
+ case HeadlessCmdPositionCursor:
+ break;
+ case HeadlessCmdTerminalPoll:
+ break;
+ case HeadlessCmdGetByte:
+ break;
+ case HeadlessCmdGetLine:
+ break;
+ case HeadlessCmdStartBugCheck:
+ break;
+ case HeadlessCmdDoBugCheckProcessing:
+ break;
+ case HeadlessCmdQueryInformation:
+ break;
+ case HeadlessCmdAddLogEntry:
+ break;
+ case HeadlessCmdDisplayLog:
+ break;
+ case HeadlessCmdSetBlueScreenData:
+ break;
+ case HeadlessCmdSendBlueScreenData:
+ break;
+ case HeadlessCmdQueryGUID:
+ break;
+ case HeadlessCmdPutData:
+ break;
+ default:
+ break;
+ }
+
+Reset:
+ /* Unset prcessing state */
+ if ((Command != HeadlessCmdAddLogEntry) &&
+ (Command != HeadlessCmdStartBugCheck) &&
+ (Command != HeadlessCmdSendBlueScreenData) &&
+ (Command != HeadlessCmdDoBugCheckProcessing))
+ {
+ ASSERT(HeadlessGlobals->ProcessingCmd == TRUE);
+ HeadlessGlobals->ProcessingCmd = FALSE;
+ }
+
+ //UNIMPLEMENTED;
+ return STATUS_SUCCESS;
+}
+
+/*
+ * @unimplemented
+ */
+NTSTATUS
+NTAPI
+HeadlessDispatch(
+ IN HEADLESS_CMD Command,
+ IN PVOID InputBuffer,
+ IN SIZE_T InputBufferSize,
+ OUT PVOID OutputBuffer,
+ OUT PSIZE_T OutputBufferSize
+ )
+{
+ /* Check for stubs that will expect something even with headless off */
+ if (!HeadlessGlobals)
+ {
+ /* Don't allow the SAC to connect */
+ if (Command == HeadlessCmdEnableTerminal) return STATUS_UNSUCCESSFUL;
+
+ /* Send bogus reply */
+ if ((Command == HeadlessCmdQueryInformation) ||
+ (Command == HeadlessCmdGetByte) ||
+ (Command == HeadlessCmdGetLine) ||
+ (Command == HeadlessCmdCheckForReboot) ||
+ (Command == HeadlessCmdTerminalPoll))
+ {
+ if (!(OutputBuffer) || !(OutputBufferSize)) return STATUS_INVALID_PARAMETER;
+ RtlZeroMemory(OutputBuffer, *OutputBufferSize);
+ }
+ return STATUS_SUCCESS;
+ }
+
+ /* Do the real work */
+ return HdlspDispatch(
+ Command,
+ InputBuffer,
+ InputBufferSize,
+ OutputBuffer,
+ OutputBufferSize);
+}
+
/* EOF */
{
PSYSTEM_PROCESSOR_INFORMATION Spi
= (PSYSTEM_PROCESSOR_INFORMATION) Buffer;
- PKPRCB Prcb;
*ReqSize = sizeof(SYSTEM_PROCESSOR_INFORMATION);
{
return STATUS_INFO_LENGTH_MISMATCH;
}
- Prcb = KeGetCurrentPrcb();
Spi->ProcessorArchitecture = KeProcessorArchitecture;
Spi->ProcessorLevel = KeProcessorLevel;
Spi->ProcessorRevision = KeProcessorRevision;
LONG i;
ULONG TotalTime;
- LARGE_INTEGER CurrentTime;
PKPRCB Prcb;
*ReqSize = KeNumberProcessors * sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION);
return STATUS_INFO_LENGTH_MISMATCH;
}
- CurrentTime.QuadPart = KeQueryInterruptTime();
for (i = 0; i < KeNumberProcessors; i++)
{
/* Get the PRCB on this processor */
/* FIXME: TODO */
DPRINT1("ReactOS does not yet support eXecute In Place boot technology\n");
+ DPRINT("%s MB requested (XIP = %s)\n", XipMegs, XipBoot);
}
/* EOF */
PLDR_DATA_TABLE_ENTRY LdrEntry;
PIMAGE_RESOURCE_DATA_ENTRY ResourceDataEntry;
LDR_RESOURCE_INFO ResourceInfo;
- ULONG Size;
NTSTATUS Status;
PVOID Data = NULL;
if (NextEntry != ListHead)
{
/* Try to find the resource */
- ResourceInfo.Type = 2;
+ ResourceInfo.Type = 2; //RT_BITMAP;
ResourceInfo.Name = ResourceId;
ResourceInfo.Language = 0;
Status = LdrFindResource_U(LdrEntry->DllBase,
Status = LdrAccessResource(LdrEntry->DllBase,
ResourceDataEntry,
&Data,
- &Size);
+ NULL);
+ if (Data) KiBugCheckData[4] ^= RtlComputeCrc32(0, Data, PAGE_SIZE);
if (!NT_SUCCESS(Status)) Data = NULL;
}
}
NTAPI
InbvAcquireLock(VOID)
{
- /* Check if we're below dispatch level */
- InbvOldIrql = KeGetCurrentIrql();
- if (InbvOldIrql < DISPATCH_LEVEL)
+ KIRQL OldIrql;
+
+ /* Check if we're at dispatch level or lower */
+ OldIrql = KeGetCurrentIrql();
+ if (OldIrql <= DISPATCH_LEVEL)
{
+ /* Loop until the lock is free */
+ while (!KeTestSpinLock(&BootDriverLock));
+
/* Raise IRQL to dispatch level */
- KeRaiseIrql(DISPATCH_LEVEL, &InbvOldIrql);
+ KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
}
/* Acquire the lock */
KiAcquireSpinLock(&BootDriverLock);
+ InbvOldIrql = OldIrql;
}
VOID
NTAPI
InbvReleaseLock(VOID)
{
+ KIRQL OldIrql;
+
+ /* Capture the old IRQL */
+ OldIrql = InbvOldIrql;
+
/* Release the driver lock */
KiReleaseSpinLock(&BootDriverLock);
- /* If we were below dispatch level, lower IRQL back */
- if (InbvOldIrql < DISPATCH_LEVEL) KeLowerIrql(InbvOldIrql);
+ /* If we were at dispatch level or lower, restore the old IRQL */
+ if (InbvOldIrql <= DISPATCH_LEVEL) KeLowerIrql(OldIrql);
}
VOID
/* Make sure we're installed and display the string */
if (InbvBootDriverInstalled) VidDisplayString((PUCHAR) String);
- /* Call Headless (We don't support headless for now)
- HeadlessDispatch(DISPLAY_STRING); */
+ /* Print the string on the EMS port */
+ HeadlessDispatch(
+ HeadlessCmdPutString,
+ String,
+ strlen(String) + sizeof(ANSI_NULL),
+ NULL,
+ NULL);
/* Release the lock */
InbvReleaseLock();
NTAPI
DisplayBootBitmap(IN BOOLEAN SosMode)
{
- PVOID Header, Band, Bar, Text, Screen;
+ PVOID Header, Band, Text, Screen;
ROT_BAR_TYPE TempRotBarSelection = RB_UNSPECIFIED;
UCHAR Buffer[64];
{
/* Reset the progress bar */
InbvAcquireLock();
- RotBarSelection = 0;
+ RotBarSelection = RB_UNSPECIFIED;
InbvReleaseLock();
}
if (SharedUserData->NtProductType == NtProductWinNt)
{
/* Workstation product, display appropriate status bar color */
- Bar = InbvGetResourceAddress(IDB_BAR_PRO);
+ InbvGetResourceAddress(IDB_BAR_PRO);
}
else
{
}
/* Server product, display appropriate status bar color */
- Bar = InbvGetResourceAddress(IDB_BAR_SERVER);
+ InbvGetResourceAddress(IDB_BAR_SERVER);
}
/* Make sure we had a logo */
--- /dev/null
+/*
+ * PROJECT: ReactOS Kernel
+ * LICENSE: BSD - See COPYING.ARM in the top level directory
+ * FILE: ntoskrnl/inbv/inbvport.c
+ * PURPOSE: Serial Port Boot Driver for Headless Terminal Support
+ * PROGRAMMERS: ReactOS Portable Systems Group
+ */
+
+/* INCLUDES ******************************************************************/
+
+#include <ntoskrnl.h>
+#include <debug.h>
+
+/* GLOBALS *******************************************************************/
+
+CPPORT Port[4] =
+{
+ {NULL, 0, TRUE},
+ {NULL, 0, TRUE},
+ {NULL, 0, TRUE},
+ {NULL, 0, TRUE}
+};
+
+/* FUNCTIONS *****************************************************************/
+
+VOID
+NTAPI
+InbvPortEnableFifo(
+ IN ULONG PortId,
+ IN BOOLEAN Enable
+ )
+{
+ /* Set FIFO as requested */
+ CpEnableFifo(Port[PortId].Address, Enable);
+}
+
+VOID
+NTAPI
+InbvPortPutByte(
+ IN ULONG PortId,
+ IN BOOLEAN Output
+ )
+{
+ /* Send the byte */
+ CpPutByte(&Port[PortId], Output);
+}
+
+VOID
+NTAPI
+InbvPortTerminate(
+ IN ULONG PortId
+ )
+{
+ /* The port is now available */
+ Port[PortId].Address = NULL;
+}
+
+BOOLEAN
+NTAPI
+InbvPortInitialize(
+ IN ULONG BaudRate,
+ IN ULONG PortNumber,
+ IN PUCHAR PortAddress,
+ OUT PULONG PortId,
+ IN BOOLEAN IsMMIODevice
+ )
+{
+ /* Not yet supported */
+ ASSERT(IsMMIODevice == FALSE);
+
+ /* Set default baud rate */
+ if (BaudRate == 0) BaudRate = 19200;
+
+ /* Check if port or address given */
+ if (PortNumber)
+ {
+ /* Pick correct address for port */
+ if (!PortAddress)
+ {
+ switch (PortNumber)
+ {
+ case 1:
+ PortAddress = (PUCHAR)0x3F8;
+ break;
+
+ case 2:
+ PortAddress = (PUCHAR)0x2F8;
+ break;
+
+ case 3:
+ PortAddress = (PUCHAR)0x3E8;
+ break;
+
+ default:
+ PortNumber = 4;
+ PortAddress = (PUCHAR)0x2E8;
+ }
+ }
+ }
+ else
+ {
+ /* Pick correct port for address */
+ PortAddress = (PUCHAR)0x2F8;
+ if (CpDoesPortExist(PortAddress))
+ {
+ PortNumber = 2;
+ }
+ else
+ {
+ PortAddress = (PUCHAR)0x3F8;
+ if (!CpDoesPortExist(PortAddress)) return FALSE;
+ PortNumber = 1;
+ }
+ }
+
+ /* Initialize the port unless it's already up, and then return it */
+ if (Port[PortNumber - 1].Address) return FALSE;
+ CpInitialize(&Port[PortNumber - 1], PortAddress, BaudRate);
+ *PortId = PortNumber - 1;
+ return TRUE;
+}
--- /dev/null
+/*
+ * PROJECT: ReactOS Kernel
+ * LICENSE: BSD - See COPYING.ARM in the top level directory
+ * FILE: ntoskrnl/include/internal/hdl.h
+ * PURPOSE: Internal header for the Configuration Manager
+ * PROGRAMMERS: ReactOS Portable Systems Group
+ */
+#define _HDL_
+#include <cportlib/cportlib.h>
+
+//
+// Define this if you want debugging support
+//
+#define _HDL_DEBUG_ 0x00
+
+//
+// These define the Debug Masks Supported
+//
+#define HDL_XXX_DEBUG 0x01
+
+//
+// Debug/Tracing support
+//
+#if _HDL_DEBUG_
+#ifdef NEW_DEBUG_SYSTEM_IMPLEMENTED // enable when Debug Filters are implemented
+#define HDLTRACE DbgPrintEx
+#else
+#define HDLTRACE(x, ...) \
+ if (x & HdlpTraceLevel) DbgPrint(__VA_ARGS__)
+#endif
+#else
+#define HDLTRACE(x, ...) DPRINT(__VA_ARGS__)
+#endif
+
+//
+// Well-known messages that Io and Pnp post to the kernel log
+//
+typedef enum _HEADLESS_LOG_MESSAGE
+{
+ HeadlessLogDriverLoad = 1,
+ HeadlessLogDriverSuccess,
+ HeadlessLogDriverFailed,
+ HeadlessLogEventFailed,
+ HeadlessLogObjectFailed,
+ HeadlessLogDirectoryFailed,
+ HeadlessLogPnpFailed,
+ HeadlessLogPnpFailed2,
+ HeadlessLogBootDriversFailed,
+ HeadlessLogNtdllFailed,
+ HeadlessLogSystemDriversFailed,
+ HeadlessLogReassignSystemRootFailed,
+ HeadlessLogProtectSystemRootFailed,
+ HeadlessLogConvertSystemRootFailed,
+ HeadlessLogConvertDeviceNameFailed,
+ HeadlessLogGroupOrderListFailed,
+ HeadlessLogGroupTableFailed
+ //
+ // There are more, but not applicable to ReactOS, I believe
+ //
+} HEADLESS_LOG_MESSAGE;
+
+//
+// Headless Log Entry
+//
+typedef struct _HEADLESS_LOG_ENTRY
+{
+ SYSTEM_TIMEOFDAY_INFORMATION TimeOfEntry;
+ PWCHAR String;
+} HEADLESS_LOG_ENTRY, *PHEADLESS_LOG_ENTRY;
+
+//
+// Headless Bugcheck Information
+//
+typedef struct _HEADLESS_BLUE_SCREEN_DATA
+{
+ PUCHAR Property;
+ PUCHAR XMLData;
+ struct _HEADLESS_BLUE_SCREEN_DATA *Next;
+} HEADLESS_BLUE_SCREEN_DATA, * PHEADLESS_BLUE_SCREEN_DATA;
+
+//
+// Headless Control Structure, mostly for !SAC
+//
+typedef struct _HEADLESS_GLOBALS
+{
+ KSPIN_LOCK SpinLock;
+ HANDLE PageLockHandle;
+ PHEADLESS_LOG_ENTRY LogEntries;
+ PUCHAR TmpBuffer;
+ PUCHAR InputBuffer;
+ PHEADLESS_BLUE_SCREEN_DATA BlueScreenData;
+ union
+ {
+ struct
+ {
+ ULONG TerminalEnabled:1;
+ ULONG InBugCheck:1;
+ ULONG NewLogEntryAdded:1;
+ ULONG UsedBiosSettings:1;
+ ULONG InputProcessing:1;
+ ULONG InputLineDone:1;
+ ULONG ProcessingCmd:1;
+ ULONG TerminalParity:1;
+ ULONG TerminalStopBits:1;
+ ULONG TerminalPortNumber:3;
+ ULONG IsNonLegacyDevice:1;
+ };
+ ULONG AllFlags;
+ };
+ ULONG TerminalBaudRate;
+ ULONG TerminalPort;
+ PUCHAR TerminalPortAddress;
+ LARGE_INTEGER DelayTime;
+ ULONG MicroSecondsDelayTime;
+ UCHAR TerminalType;
+ SIZE_T InputBufferIndex;
+ USHORT LogEntryLast;
+ USHORT LogEntryStart;
+ GUID SystemGUID;
+ BOOLEAN IsMMIODevice;
+ BOOLEAN IsLastCharCR;
+} HEADLESS_GLOBALS, *PHEADLESS_GLOBALS;
+
+//
+// FIXME: A public header in the NDK? Ask Alex
+//
+typedef enum _HEADLESS_CMD
+{
+ HeadlessCmdEnableTerminal = 1,
+ HeadlessCmdCheckForReboot,
+ HeadlessCmdPutString,
+ HeadlessCmdClearDisplay,
+ HeadlessCmdClearToEndOfDisplay,
+ HeadlessCmdClearToEndOfLine,
+ HeadlessCmdDisplayAttributesOff,
+ HeadlessCmdDisplayInverseVideo,
+ HeadlessCmdSetColor,
+ HeadlessCmdPositionCursor,
+ HeadlessCmdTerminalPoll,
+ HeadlessCmdGetByte,
+ HeadlessCmdGetLine,
+ HeadlessCmdStartBugCheck,
+ HeadlessCmdDoBugCheckProcessing,
+ HeadlessCmdQueryInformation,
+ HeadlessCmdAddLogEntry,
+ HeadlessCmdDisplayLog,
+ HeadlessCmdSetBlueScreenData,
+ HeadlessCmdSendBlueScreenData,
+ HeadlessCmdQueryGUID,
+ HeadlessCmdPutData
+} HEADLESS_CMD, *PHEADLESS_CMD;
+
+typedef struct _HEADLESS_CMD_PUT_STRING
+{
+ UCHAR String[1];
+} HEADLESS_CMD_PUT_STRING, *PHEADLESS_CMD_PUT_STRING;
+
+NTSTATUS
+NTAPI
+HeadlessDispatch(
+ IN HEADLESS_CMD Command,
+ IN PVOID InputBuffer,
+ IN SIZE_T InputBufferSize,
+ OUT PVOID OutputBuffer,
+ OUT PSIZE_T OutputBufferSize
+);
+
+//
+// Global variables accessible from all of Hdl
+//
+extern PHEADLESS_GLOBALS HeadlessGlobals;
+
+//
+// Inlined functions
+//
+//#include "hdl_x.h"
#ifndef __ASM__
#include "intrin_i.h"
-#include "v86m.h"
//
// Thread Dispatcher Header DebugActive Mask
+++ /dev/null
-#pragma once
-
-#include "ketypes.h"
-
-/* Emulate cli/sti instructions */
-#define KV86M_EMULATE_CLI_STI (0x1)
-/* Allow the v86 mode code to access i/o ports */
-#define KV86M_ALLOW_IO_PORT_ACCESS (0x2)
-
-typedef struct _KV86M_REGISTERS
-{
- /*
- * General purpose registers
- */
- ULONG Ebp;
- ULONG Edi;
- ULONG Esi;
- ULONG Edx;
- ULONG Ecx;
- ULONG Ebx;
- ULONG Eax;
- ULONG Ds;
- ULONG Es;
- ULONG Fs;
- ULONG Gs;
-
- /*
- * Control registers
- */
- ULONG Eip;
- ULONG Cs;
- ULONG Eflags;
- ULONG Esp;
- ULONG Ss;
-
- /*
- * Control structures
- */
- ULONG RecoveryAddress;
- UCHAR RecoveryInstruction[4];
- ULONG Vif;
- ULONG Flags;
- PNTSTATUS PStatus;
-} KV86M_REGISTERS, *PKV86M_REGISTERS;
-
-typedef struct _KV86M_TRAP_FRAME
-{
- KTRAP_FRAME Tf;
-
- ULONG SavedExceptionStack;
-
- /*
- * These are put on the top of the stack by the routine that entered
- * v86 mode so the exception handlers can find the control information
- */
- struct _KV86M_REGISTERS* regs;
- ULONG orig_ebp;
-} KV86M_TRAP_FRAME, *PKV86M_TRAP_FRAME;
VOID
);
+VOID
+NTAPI
+InbvPortEnableFifo(
+ IN ULONG PortId,
+ IN BOOLEAN Enable
+);
+
+VOID
+NTAPI
+InbvPortPutByte(
+ IN ULONG PortId,
+ IN BOOLEAN Output
+);
+
+VOID
+NTAPI
+InbvPortTerminate(
+ IN ULONG PortId
+);
+
+BOOLEAN
+NTAPI
+InbvPortInitialize(
+ IN ULONG BaudRate,
+ IN ULONG PortNumber,
+ IN PUCHAR PortAddress,
+ OUT PULONG PortId,
+ IN BOOLEAN IsMMIODevice
+);
+
extern BOOLEAN InbvBootDriverInstalled;
IopCreateDriver(IN PUNICODE_STRING DriverName OPTIONAL,
IN PDRIVER_INITIALIZE InitializationFunction,
IN PUNICODE_STRING RegistryPath,
- IN PVOID DllBase,
- IN ULONG SizeOfImage,
+ PLDR_DATA_TABLE_ENTRY ModuleObject,
OUT PDRIVER_OBJECT *pDriverObject);
VOID
#include "inbv.h"
#include "vdm.h"
#include "hal.h"
+#include "hdl.h"
#include "arch/intrin_i.h"
/*
/* Platform specific checks */
C_ASSERT(FIELD_OFFSET(KPROCESS, IopmOffset) == KPROCESS_IOPM_OFFSET);
C_ASSERT(FIELD_OFFSET(KPROCESS, LdtDescriptor) == KPROCESS_LDT_DESCRIPTOR0);
-C_ASSERT(FIELD_OFFSET(KV86M_TRAP_FRAME, SavedExceptionStack) == TF_SAVED_EXCEPTION_STACK);
-C_ASSERT(FIELD_OFFSET(KV86M_TRAP_FRAME, regs) == TF_REGS);
-C_ASSERT(FIELD_OFFSET(KV86M_TRAP_FRAME, orig_ebp) == TF_ORIG_EBP);
C_ASSERT(FIELD_OFFSET(KTSS, Esp0) == KTSS_ESP0);
C_ASSERT(FIELD_OFFSET(KTSS, IoMapBase) == KTSS_IOMAPBASE);
#endif
DriverName.Length > 0 ? &DriverName : NULL,
DriverEntry,
&RegistryKey,
- ModuleObject->DllBase,
- ModuleObject->SizeOfImage,
+ ModuleObject,
&Driver);
RtlFreeUnicodeString(&RegistryKey);
PLDR_DATA_TABLE_ENTRY *ModuleObject)
{
NTSTATUS Status;
- PLDR_DATA_TABLE_ENTRY NewEntry;
UNICODE_STRING BaseName, BaseDirectory;
PLOAD_IMPORTS LoadedImports = (PVOID)-2;
PCHAR MissingApiName, Buffer;
BaseDirectory.Length -= BaseName.Length;
BaseDirectory.MaximumLength = BaseDirectory.Length;
- NewEntry = LdrEntry;
-
/* Resolve imports */
MissingApiName = Buffer;
Status = MiResolveImageReferences(DriverBase,
IopCreateDriver(IN PUNICODE_STRING DriverName OPTIONAL,
IN PDRIVER_INITIALIZE InitializationFunction,
IN PUNICODE_STRING RegistryPath,
- IN PVOID DllBase,
- IN ULONG SizeOfImage,
+ PLDR_DATA_TABLE_ENTRY ModuleObject,
OUT PDRIVER_OBJECT *pDriverObject)
{
WCHAR NameBuffer[100];
DriverObject->DriverExtension = (PDRIVER_EXTENSION)(DriverObject + 1);
DriverObject->DriverExtension->DriverObject = DriverObject;
DriverObject->DriverInit = InitializationFunction;
-
+ DriverObject->DriverSection = ModuleObject;
/* Loop all Major Functions */
for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
{
ZwClose(hDriver);
DriverObject->HardwareDatabase = &IopHardwareDatabaseKey;
- DriverObject->DriverStart = DllBase;
- DriverObject->DriverSize = SizeOfImage;
+ DriverObject->DriverStart = ModuleObject ? ModuleObject->DllBase : 0;
+ DriverObject->DriverSize = ModuleObject ? ModuleObject->SizeOfImage : 0;
/* Finally, call its init function */
DPRINT("RegistryKey: %wZ\n", RegistryPath);
{
/* If it didn't work, then kill the object */
DPRINT1("'%wZ' initialization failed, status (0x%08lx)\n", DriverName, Status);
+ DriverObject->DriverSection = NULL;
ObMakeTemporaryObject(DriverObject);
ObDereferenceObject(DriverObject);
}
IN PDRIVER_INITIALIZE InitializationFunction)
{
PDRIVER_OBJECT DriverObject;
- return IopCreateDriver(DriverName, InitializationFunction, NULL, 0, 0, &DriverObject);
+ return IopCreateDriver(DriverName, InitializationFunction, NULL, NULL, &DriverObject);
}
/*
*/
Status = MmLoadSystemImage(&ImagePath, NULL, NULL, 0, (PVOID)&ModuleObject, &BaseAddress);
+
if (!NT_SUCCESS(Status) && Status != STATUS_IMAGE_ALREADY_LOADED)
{
DPRINT("MmLoadSystemImage() failed (Status %lx)\n", Status);
}
}
- /* Store its DriverSection, so that it could be unloaded */
- DriverObject->DriverSection = ModuleObject;
-
/* Initialize and start device */
IopInitializeDevice(DeviceNode, DriverObject);
Status = IopStartDevice(DeviceNode);
/* Initialize PnP manager */
IopInitializePlugPlayServices();
+ /* Initialize HAL Root Bus Driver */
+ HalInitPnpDriver();
+
/* Load boot start drivers */
IopInitializeBootDrivers();
IN PIO_STACK_LOCATION IoStackLocation)
{
NTSTATUS Status = STATUS_INVALID_DEVICE_REQUEST;
- PULONG Length;
PFILE_POSITION_INFORMATION Buffer;
PDEVICE_OBJECT DeviceObject;
PAGED_CODE();
/* Get information from the IRP */
- Length = &IoStackLocation->Parameters.QueryFile.Length;
Buffer = Irp->AssociatedIrp.SystemBuffer;
/* We only handle this request */
PIO_WORKITEM WorkItem;
PINVALIDATE_DEVICE_RELATION_DATA Data;
- Data = ExAllocatePool(PagedPool, sizeof(INVALIDATE_DEVICE_RELATION_DATA));
+ Data = ExAllocatePool(NonPagedPool, sizeof(INVALIDATE_DEVICE_RELATION_DATA));
if (!Data)
return;
WorkItem = IoAllocateWorkItem(DeviceObject);
IN PIRP Irp,
IN PIO_STACK_LOCATION IrpSp)
{
- PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension;
PDEVICE_CAPABILITIES DeviceCapabilities;
- DeviceExtension = (PPNPROOT_FDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
DeviceCapabilities = IrpSp->Parameters.DeviceCapabilities.Capabilities;
if (DeviceCapabilities->Version != 1)
int sizeflag;
{
bfd_signed_vma op;
- bfd_signed_vma mask = -1;
switch (bytemode)
{
op = *codep++;
if ((op & 0x80) != 0)
op -= 0x100;
- mask = 0xffffffff;
break;
case v_mode:
USED_REX (REX_MODE64);
else if (sizeflag & DFLAG)
{
op = get32s ();
- mask = 0xffffffff;
}
else
{
- mask = 0xffffffff;
op = get16 ();
if ((op & 0x8000) != 0)
op -= 0x10000;
break;
case w_mode:
op = get16 ();
- mask = 0xffffffff;
if ((op & 0x8000) != 0)
op -= 0x10000;
break;
ULONG Argc,
PCHAR Argv[])
{
- ULONG Count;
ULONG ul;
ULONGLONG Result = 0;
ULONG_PTR Frame = KdbCurrentTrapFrame->Tf.Ebp;
ul = strtoul(Argv[Argc-1], NULL, 0);
if (ul > 0)
{
- Count = ul;
Argc -= 2;
}
}
ul = strtoul(Argv[Argc-1] + 1, NULL, 0);
if (ul > 0)
{
- Count = ul;
Argc--;
}
}
BOOLEAN Handled = FALSE;
PKNMI_HANDLER_CALLBACK NmiData;
- //
- // Parse the list of callbacks
- //
+ /* Parse the list of callbacks */
NmiData = KiNmiCallbackListHead;
while (NmiData)
{
- //
- // Save if this callback has handled it -- all it takes is one
- //
+ /* Save if this callback has handled it -- all it takes is one */
Handled |= NmiData->Callback(NmiData->Context, Handled);
NmiData = NmiData->Next;
}
- //
- // Has anyone handled this?
- //
+ /* Has anyone handled this? */
return Handled;
}
PKNMI_HANDLER_CALLBACK NmiData, Next;
ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
- //
- // Allocate NMI callback data
- //
+ /* Allocate NMI callback data */
NmiData = ExAllocatePoolWithTag(NonPagedPool,
sizeof(KNMI_HANDLER_CALLBACK),
'IMNK');
if (!NmiData) return NULL;
- //
- // Fill in the information
- //
+ /* Fill in the information */
NmiData->Callback = CallbackRoutine;
NmiData->Context = Context;
NmiData->Handle = NmiData;
- //
- // Insert it into NMI callback list
- //
+ /* Insert it into NMI callback list */
KiAcquireNmiListLock(&OldIrql);
NmiData->Next = KiNmiCallbackListHead;
Next = InterlockedCompareExchangePointer((PVOID*)&KiNmiCallbackListHead,
ASSERT(Next == NmiData->Next);
KiReleaseNmiListLock(OldIrql);
- //
- // Return the opaque "handle"
- //
+ /* Return the opaque "handle" */
return NmiData->Handle;
}
{
KIRQL OldIrql;
LONG PreviousState;
- PKWAIT_BLOCK WaitBlock;
PKTHREAD Thread;
ASSERT_EVENT(Event);
ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
* Check if this is an signaled notification event without an upcoming wait.
* In this case, we can immediately return TRUE, without locking.
*/
- if ((Event->Header.Type == NotificationEvent) &&
+ if ((Event->Header.Type == EventNotificationObject) &&
(Event->Header.SignalState == 1) &&
!(Wait))
{
/* Check if the event just became signaled now, and it has waiters */
if (!(PreviousState) && !(IsListEmpty(&Event->Header.WaitListHead)))
{
- /* Get the Wait Block */
- WaitBlock = CONTAINING_RECORD(Event->Header.WaitListHead.Flink,
- KWAIT_BLOCK,
- WaitListEntry);
-
/* Check the type of event */
- if (Event->Header.Type == NotificationEvent)
+ if (Event->Header.Type == EventNotificationObject)
{
/* Unwait the thread */
KxUnwaitThread(&Event->Header, Increment);
KIRQL OldIrql;
PKWAIT_BLOCK WaitBlock;
PKTHREAD Thread = KeGetCurrentThread(), WaitThread;
- ASSERT(Event->Header.Type == SynchronizationEvent);
+ ASSERT(Event->Header.Type == EventSynchronizationObject);
ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
/* Acquire Dispatcher Database Lock */
Interrupt->DispatchCount = MAXULONG;
/* Loop the template in memory */
- for (i = 0; i < KINTERRUPT_DISPATCH_CODES; i++)
+ for (i = 0; i < DISPATCH_LENGTH; i++)
{
/* Copy the dispatch code */
*DispatchCode++ = ((PULONG)KiInterruptTemplate)[i];
NpxSaveArea = KiGetThreadNpxArea(NpxThread);
/* Save FPU state */
+ DPRINT("FIXME: Save FPU state: %p\n", NpxSaveArea);
//Ke386SaveFpuState(NpxSaveArea);
/* Update NPX state */
/* Build flat ESP */
Esp = (TrapFrame->HardwareSegSs << 4) + (USHORT)TrapFrame->HardwareEsp;
- Esp -= 2;
/* Check for OPER32 */
if (KiVdmGetPrefixFlags(Flags) & PFX_FLAG_OPER32)
{
/* Save EFlags */
- Esp -= 2;
- *(PULONG)(Esp - 2) = V86EFlags;
+ Esp -= 4;
+ *(PULONG)Esp = V86EFlags;
}
else
{
/* Save EFLags */
+ Esp -= 2;
*(PUSHORT)Esp = (USHORT)V86EFlags;
}
/* Set new ESP and EIP */
- TrapFrame->HardwareEsp = (USHORT)Esp;
+ TrapFrame->HardwareEsp = Esp - (TrapFrame->HardwareSegSs << 4);
TrapFrame->Eip += KiVdmGetInstructionSize(Flags);
/* We're done */
/* Build flat ESP */
Esp = (TrapFrame->HardwareSegSs << 4) + (USHORT)TrapFrame->HardwareEsp;
- /* Read EFlags */
- EFlags = *(PULONG)Esp;
- Esp += 4;
-
/* Check for OPER32 */
- if (!(KiVdmGetPrefixFlags(Flags) & PFX_FLAG_OPER32))
+ if (KiVdmGetPrefixFlags(Flags) & PFX_FLAG_OPER32)
{
- /* Read correct flags and use correct stack address */
- Esp -= 2;
- EFlags &= 0xFFFF;
+ /* Read EFlags */
+ EFlags = *(PULONG)Esp;
+ Esp += 4;
+ }
+ else
+ {
+ /* Read EFlags */
+ EFlags = *(PUSHORT)Esp;
+ Esp += 2;
}
/* Set new ESP */
- TrapFrame->HardwareEsp = Esp;
+ TrapFrame->HardwareEsp = Esp - (TrapFrame->HardwareSegSs << 4);
/* Mask out IOPL from the flags */
EFlags &= ~EFLAGS_IOPL;
V86EFlags |= EFLAGS_V86_MASK | EFLAGS_INTERRUPT_MASK;
/* Update EFlags in trap frame */
- TrapFrame->EFlags |= V86EFlags;
+ TrapFrame->EFlags = V86EFlags;
/* Check if ESP0 needs to be fixed up */
if (TrapEFlags & EFLAGS_V86_MASK) Ki386AdjustEsp0(TrapFrame);
else
{
/* FIXME: Check for VDM interrupts */
+ DPRINT("FIXME: Check for VDM interrupts\n");
}
/* We're done */
PMMPTE StartPde, EndPde, PointerPte, LastPte;
MMPTE TempPde, TempPte;
PVOID NonPagedPoolExpansionVa;
- ULONG OldCount;
KIRQL OldIrql;
/* Check for kernel stack size that's too big */
// We PDE-aligned the nonpaged system start VA, so haul some extra PTEs!
//
PointerPte = MiAddressToPte(MmNonPagedSystemStart);
- OldCount = MmNumberOfSystemPtes;
MmNumberOfSystemPtes = MiAddressToPte(MmNonPagedPoolExpansionStart) -
PointerPte;
MmNumberOfSystemPtes--;
ULONG LockPages, TotalPages;
NTSTATUS Status = STATUS_SUCCESS;
PEPROCESS CurrentProcess;
- PETHREAD Thread;
PMMSUPPORT AddressSpace;
NTSTATUS ProbeStatus;
PMMPTE PointerPte, LastPte;
PMMPDE PointerPde;
PFN_NUMBER PageFrameIndex;
- PMMPFN Pfn1;
BOOLEAN UsePfnLock;
KIRQL OldIrql;
DPRINT("Probing MDL: %p\n", Mdl);
ASSERT(LockPages != 0);
//
- // Get the thread and process
+ // Get theprocess
//
- Thread = PsGetCurrentThread();
if (Address <= MM_HIGHEST_USER_ADDRESS)
{
//
PageFrameIndex = PFN_FROM_PTE(PointerPte);
if (PageFrameIndex <= MmHighestPhysicalPage)
{
- //
- // Get the PFN entry
- //
- Pfn1 = MiGetPfnEntry(PageFrameIndex);
ASSERT((CurrentProcess == NULL) || (UsePfnLock == FALSE));
//
return MmSharedUserDataPte;
}
- /* Find the VAD, it must exist, since we only handle PEB/TEB */
+ /* Find the VAD, it might not exist if the address is bogus */
Vad = MiLocateAddress(VirtualAddress);
- ASSERT(Vad);
+ if (!Vad)
+ {
+ /* Bogus virtual address */
+ *ProtectCode = MM_NOACCESS;
+ return NULL;
+ }
/* This must be a TEB/PEB VAD */
ASSERT(Vad->u.VadFlags.PrivateMemory == TRUE);
/* Check if this address range belongs to a valid allocation (VAD) */
ProtoPte = MiCheckVirtualAddress(Address, &ProtectionCode, &Vad);
- ASSERT(ProtectionCode != MM_NOACCESS);
-
+ if (ProtectionCode == MM_NOACCESS)
+ {
+ /* This is a bogus VA */
+ Status = STATUS_ACCESS_VIOLATION;
+
+ /* Could be a not-yet-mapped paged pool page table */
+#if (_MI_PAGING_LEVELS == 2)
+ MiCheckPdeForPagedPool(Address);
+#endif
+ /* See if that fixed it */
+ if (PointerPte->u.Hard.Valid == 1) Status = STATUS_SUCCESS;
+
+ /* Return the status */
+ MiUnlockProcessWorkingSet(CurrentProcess, CurrentThread);
+ return Status;
+ }
+
/* Did we get a prototype PTE back? */
if (!ProtoPte)
{
ASSERT(Pfn1->u3.e1.StartOfAllocation == 0);
Pfn1->u3.e1.StartOfAllocation = 1;
+ /* Mark it as special pool if needed */
+ ASSERT(Pfn1->u4.VerifierAllocation == 0);
+ if (PoolType & 64) Pfn1->u4.VerifierAllocation = 1;
+
//
// Check if the allocation is larger than one page
//
Pfn1 = MiGetPfnEntry(StartPte->u.Hard.PageFrameNumber);
Pfn1->u3.e1.StartOfAllocation = 1;
+ /* Mark it as a verifier allocation if needed */
+ ASSERT(Pfn1->u4.VerifierAllocation == 0);
+ if (PoolType & 64) Pfn1->u4.VerifierAllocation = 1;
+
//
// Release the PFN and nonpaged pool lock
//
{
PKTHREAD Thread = KeGetCurrentThread();
PMMPTE LimitPte, NewLimitPte, LastPte;
- PFN_NUMBER StackPages;
KIRQL OldIrql;
MMPTE TempPte, InvalidPte;
PFN_NUMBER PageFrameIndex;
// Calculate the number of new pages
//
LimitPte--;
- StackPages = (LimitPte - NewLimitPte + 1);
/* Setup the temporary invalid PTE */
MI_MAKE_SOFTWARE_PTE(&InvalidPte, MM_NOACCESS);
ULONG_PTR OldBaseTop, Delta;
PLDR_DATA_TABLE_ENTRY LdrEntry;
PLIST_ENTRY NextEntry;
- ULONG ImportSize, i;
+ ULONG ImportSize;
+ //
+ // FIXME: MINGW-W64 must fix LD to generate drivers that Windows can load,
+ // since a real version of Windows would fail at this point, but they seem
+ // busy implementing features such as "HotPatch" support in GCC 4.6 instead,
+ // a feature which isn't even used by Windows. Priorities, priorities...
+ // Please note that Microsoft WDK EULA and license prohibits using
+ // the information contained within it for the generation of "non-Windows"
+ // drivers, which is precisely what LD will generate, since an LD driver
+ // will not load on Windows.
+ //
+#ifdef _WORKING_LINKER_
+ ULONG i;
+#endif
PULONG_PTR ImageThunk;
PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor;
}
#else
/* Get the import table */
- i = ImportSize;
ImportDescriptor = RtlImageDirectoryEntryToData(LdrEntry->DllBase,
TRUE,
IMAGE_DIRECTORY_ENTRY_IMPORT,
MiDecrementShareCount(Pfn1, PageFrameIndex);
/* Decrement the page table too */
+ DPRINT("FIXME: ARM3 should decrement the PT refcount for: %p\n", Pfn2);
#if 0 // ARM3: Dont't trust this yet
MiDecrementShareCount(Pfn2, PageTableIndex);
#endif
if (BYTE_OFFSET(SkipBytes.LowPart)) return NULL;
SkipPages = (PFN_NUMBER)(SkipBytes.QuadPart >> PAGE_SHIFT);
+ /* This isn't supported at all */
+ if (SkipPages) DPRINT1("WARNING: Caller requesting SkipBytes, MDL might be mismatched\n");
+
//
// Now compute the number of pages the MDL will cover
//
ULONG oldPdeOffset, PdeOffset;
PULONG Pt = NULL;
ULONG Pte;
- BOOLEAN NoExecute = FALSE;
-
DPRINT("MmCreateVirtualMappingUnsafe(%x, %x, %x, %x (%x), %d)\n",
Process, Address, flProtect, Pages, *Pages, PageCount);
}
Attributes = ProtectToPTE(flProtect);
- if (Attributes & 0x80000000)
- {
- NoExecute = TRUE;
- }
Attributes &= 0xfff;
if (Address >= MmSystemRangeStart)
{
MmSetPageProtect(PEPROCESS Process, PVOID Address, ULONG flProtect)
{
ULONG Attributes = 0;
- BOOLEAN NoExecute = FALSE;
PULONG Pt;
DPRINT("MmSetPageProtect(Process %x Address %x flProtect %x)\n",
Attributes = ProtectToPTE(flProtect);
- if (Attributes & 0x80000000)
- {
- NoExecute = TRUE;
- }
Attributes &= 0xfff;
if (Address >= MmSystemRangeStart)
{
{
PR_USED NewBlock;
PR_FREE BestBlock,
- NextBlock,
- PreviousBlock,
- BestPreviousBlock,
- CurrentBlock;
+ CurrentBlock;
void* BestAlignedAddr;
int que,
queBytes = NumberOfBytes;
*/
BestBlock = NULL;
Alignment = pool->Alignments[align];
- PreviousBlock = NULL;
- BestPreviousBlock = NULL,
CurrentBlock = pool->FirstFree;
BestAlignedAddr = NULL;
if ( Addr == AlignedAddr )
{
BestAlignedAddr = AlignedAddr;
- BestPreviousBlock = PreviousBlock;
BestBlock = CurrentBlock;
break;
}
|| BestBlock->Size > CurrentBlock->Size )
{
BestAlignedAddr = AlignedAddr;
- BestPreviousBlock = PreviousBlock;
BestBlock = CurrentBlock;
}
}
- PreviousBlock = CurrentBlock;
CurrentBlock = CurrentBlock->NextFree;
}
NewFreeBlock, NewFreeBlock->Size, BestBlock->Size, BestBlock->NextFree );*/
/* we want the following code to use our size-aligned block */
- BestPreviousBlock = BestBlock;
BestBlock = NewFreeBlock;
//VerifyPagedPool();
/*
* Create the new free block.
*/
- NextBlock = RFreeSplit ( pool, BestBlock, BlockSize );
+ RFreeSplit ( pool, BestBlock, BlockSize );
//ASSERT_SIZE ( NextBlock->Size );
}
/*
RPoolFree ( PR_POOL pool, void* Addr )
{
PR_USED UsedBlock;
+#if !R_RZ
rulong UsedSize;
+#endif
PR_FREE FreeBlock;
rulong UserSize;
int que;
R_ASSERT_PTR(pool,Addr);
UsedBlock = RBodyToHdr(Addr);
- UsedSize = UsedBlock->Size;
FreeBlock = (PR_FREE)UsedBlock;
#if R_RZ
UserSize = UsedBlock->UserSize;
#else
+ UsedSize = UsedBlock->Size;
UserSize = UsedSize - sizeof(R_USED) - 2*R_RZ;
#endif//R_RZ
DPRINT("MmDeleteProcessAddressSpace(Process %x (%s))\n", Process,
Process->ImageFileName);
+ RemoveEntryList(&Process->MmProcessLinks);
+
MmLockAddressSpace(&Process->Vm);
while ((MemoryArea = (PMEMORY_AREA)Process->Vm.WorkingSetExpansionLinks.Flink) != NULL)
{
ULONG i;
ULONG LastSegment;
- BOOLEAN Initialized;
PMM_SECTION_SEGMENT EffectiveSegment;
if (Flags & EXEFMT_LOAD_ASSUME_SEGMENTS_PAGE_ALIGNED)
return TRUE;
}
- Initialized = FALSE;
LastSegment = 0;
EffectiveSegment = &ImageSectionObject->Segments[LastSegment];
PROS_SECTION_OBJECT Section;
PEPROCESS Process;
KPROCESSOR_MODE PreviousMode;
- PMMSUPPORT AddressSpace;
NTSTATUS Status;
ULONG tmpProtect;
ACCESS_MASK DesiredAccess;
return(Status);
}
- AddressSpace = &Process->Vm;
-
/* Convert NT Protection Attr to Access Mask */
if (Protect == PAGE_READONLY)
{
}
MmUnlockSectionSegment(Segment);
ObDereferenceObject(Section);
- return(STATUS_SUCCESS);
+ return(Status);
}
/*
<library>bootvid</library>
<library>wdmguid</library>
<library>ioevent</library>
+ <library>cportlib</library>
<dependency>bugcodes</dependency>
<directory name="include">
<pch>ntoskrnl.h</pch>
</directory>
<directory name="inbv">
<file>inbv.c</file>
+ <file>inbvport.c</file>
</directory>
<directory name="io">
<directory name="iomgr">
/* Charge the quota */
ObjectHeader->QuotaBlockCharged = (PVOID)1;
+ DPRINT("FIXME: Should charge: %lx %lx\n", PagedPoolCharge, NonPagedPoolCharge);
#if 0
PsChargeSharedPoolQuota(PsGetCurrentProcess(),
PagedPoolCharge,
if (!ObCheckObjectAccess(Object,
AccessState,
TRUE,
- AccessMode,
+ ProbeMode,
&Status))
{
/* Access was denied, so fail */
/* Add the SD charge too */
if (Header->Flags & OB_FLAG_SECURITY) PagedPoolCharge += 2048;
}
+
+ /* Return the quota */
+ DPRINT("FIXME: Should return quotas: %lx %lx\n", PagedPoolCharge, NonPagedPoolCharge);
+#if 0
+ PsReturnSharedPoolQuota(ObjectHeader->QuotaBlockCharged,
+ PagedPoolCharge,
+ NonPagedPoolCharge);
+#endif
+
}
}
IoFreeIrp(Irp);
- return STATUS_SUCCESS;
+ return STATUS_MORE_PROCESSING_REQUIRED;
}
VOID
PIO_STACK_LOCATION Stack;
PIRP Irp;
PREQUEST_POWER_ITEM RequestPowerItem;
- NTSTATUS Status;
if (MinorFunction != IRP_MN_QUERY_POWER
&& MinorFunction != IRP_MN_SET_POWER
*pIrp = Irp;
IoSetCompletionRoutine(Irp, PopRequestPowerIrpCompletion, RequestPowerItem, TRUE, TRUE, TRUE);
- Status = IoCallDriver(TopDeviceObject, Irp);
+ IoCallDriver(TopDeviceObject, Irp);
/* Always return STATUS_PENDING. The completion routine
* will call CompletionFunction and complete the Irp.
/* Detach */
KeUnstackDetachProcess(&ApcState);
- RemoveEntryList(&Process->MmProcessLinks);
-
/* Completely delete the Address Space */
MmDeleteProcessAddressSpace(Process);
}
Status = PspLookupSystemDllEntryPoint("KiFastSystemCallRet",
(PVOID)&SharedUserData->
SystemCallReturn);
+ if (!NT_SUCCESS(Status)) return Status;
}
else
{
Status = PspLookupSystemDllEntryPoint("KiIntSystemCall",
(PVOID)&SharedUserData->
SystemCall);
+ if (!NT_SUCCESS(Status)) return Status;
}
/* Set the test instruction */
- if (!NT_SUCCESS(Status)) SharedUserData->TestRetInstruction = 0xC3;
+ SharedUserData->TestRetInstruction = 0xC3;
/* Return the status */
return Status;
}
/* Do we have a cookie set yet? */
- if (!SharedUserData->Cookie)
+ while (!SharedUserData->Cookie)
{
LARGE_INTEGER SystemTime;
ULONG NewCookie;
OUT PTOKEN_PRIVILEGES PreviousState OPTIONAL,
OUT PULONG ReturnLength OPTIONAL)
{
- // PLUID_AND_ATTRIBUTES Privileges;
+ PLUID_AND_ATTRIBUTES CapturedPrivileges = NULL;
KPROCESSOR_MODE PreviousMode;
- ULONG PrivilegeCount;
+ ULONG CapturedCount = 0;
+ ULONG CapturedLength = 0;
+ ULONG NewStateSize = 0;
+ ULONG ChangeCount;
PTOKEN Token;
- // ULONG Length;
ULONG i;
ULONG j;
- ULONG k;
- ULONG Count;
-#if 0
- ULONG a;
- ULONG b;
- ULONG c;
-#endif
NTSTATUS Status;
PAGED_CODE();
DPRINT ("NtAdjustPrivilegesToken() called\n");
- // PrivilegeCount = NewState->PrivilegeCount;
+ /* Fail, if we do not disable all privileges but NewState is NULL */
+ if (DisableAllPrivileges == FALSE && NewState == NULL)
+ return STATUS_INVALID_PARAMETER;
+
PreviousMode = KeGetPreviousMode ();
- // SeCaptureLuidAndAttributesArray(NewState->Privileges,
- // PrivilegeCount,
- // PreviousMode,
- // NULL,
- // 0,
- // NonPagedPool,
- // 1,
- // &Privileges,
- // &Length);
-
- Status = ObReferenceObjectByHandle (TokenHandle,
- TOKEN_ADJUST_PRIVILEGES | (PreviousState != NULL ? TOKEN_QUERY : 0),
- SepTokenObjectType,
- PreviousMode,
- (PVOID*)&Token,
- NULL);
- if (!NT_SUCCESS(Status))
+ if (PreviousMode != KernelMode)
{
- DPRINT1 ("Failed to reference token (Status %lx)\n", Status);
- // SeReleaseLuidAndAttributesArray(Privileges,
- // PreviousMode,
- // 0);
- return Status;
+ _SEH2_TRY
+ {
+ /* Probe NewState */
+ if (DisableAllPrivileges == FALSE)
+ {
+ ProbeForRead(NewState,
+ sizeof(TOKEN_PRIVILEGES),
+ sizeof(ULONG));
+
+ CapturedCount = NewState->PrivilegeCount;
+ NewStateSize = (ULONG)sizeof(TOKEN_PRIVILEGES) +
+ ((CapturedCount - ANYSIZE_ARRAY) * (ULONG)sizeof(LUID_AND_ATTRIBUTES));
+
+ ProbeForRead(NewState,
+ NewStateSize,
+ sizeof(ULONG));
+ }
+
+ /* Probe PreviousState and ReturnLength */
+ if (PreviousState != NULL)
+ {
+ ProbeForWrite(PreviousState,
+ BufferLength,
+ sizeof(ULONG));
+
+ ProbeForWrite(ReturnLength,
+ sizeof(ULONG),
+ sizeof(ULONG));
+ }
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ /* Return the exception code */
+ _SEH2_YIELD(return _SEH2_GetExceptionCode());
+ }
+ _SEH2_END;
+ }
+ else
+ {
+ if (DisableAllPrivileges == FALSE)
+ CapturedCount = NewState->PrivilegeCount;
}
+ if (DisableAllPrivileges == FALSE)
+ {
+ _SEH2_TRY
+ {
+ /* Capture the new state array of privileges */
+ Status = SeCaptureLuidAndAttributesArray(NewState->Privileges,
+ CapturedCount,
+ PreviousMode,
+ NULL,
+ 0,
+ PagedPool,
+ TRUE,
+ &CapturedPrivileges,
+ &CapturedLength);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ /* Return the exception code */
+ _SEH2_YIELD(return _SEH2_GetExceptionCode());
+ }
+ _SEH2_END;
-#if 0
- SepAdjustPrivileges(Token,
- 0,
- PreviousMode,
- PrivilegeCount,
- Privileges,
- PreviousState,
- &a,
- &b,
- &c);
-#endif
+ if (!NT_SUCCESS(Status))
+ return Status;
+ }
- PrivilegeCount = (BufferLength - FIELD_OFFSET(TOKEN_PRIVILEGES, Privileges)) /
- sizeof(LUID_AND_ATTRIBUTES);
+ /* Reference the token */
+ Status = ObReferenceObjectByHandle(TokenHandle,
+ TOKEN_ADJUST_PRIVILEGES | (PreviousState != NULL ? TOKEN_QUERY : 0),
+ SepTokenObjectType,
+ PreviousMode,
+ (PVOID*)&Token,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1 ("Failed to reference token (Status %lx)\n", Status);
- if (PreviousState != NULL)
- PreviousState->PrivilegeCount = 0;
+ /* Release the captured privileges */
+ if (CapturedPrivileges != NULL)
+ SeReleaseLuidAndAttributesArray(CapturedPrivileges,
+ PreviousMode,
+ TRUE);
+
+ return Status;
+ }
- k = 0;
- if (DisableAllPrivileges == TRUE)
+ /* Count the privileges that need to be changed */
+ ChangeCount = 0;
+ for (i = 0; i < Token->PrivilegeCount; i++)
{
- for (i = 0; i < Token->PrivilegeCount; i++)
+ if (DisableAllPrivileges)
{
- if (Token->Privileges[i].Attributes != 0)
+ if (Token->Privileges[i].Attributes & SE_PRIVILEGE_ENABLED)
{
- DPRINT ("Attributes differ\n");
+ DPRINT("Privilege enabled\n");
- /* Save current privilege */
- if (PreviousState != NULL)
+ ChangeCount++;
+ }
+ }
+ else
+ {
+ for (j = 0; j < CapturedCount; j++)
+ {
+ if (Token->Privileges[i].Luid.LowPart == CapturedPrivileges[j].Luid.LowPart &&
+ Token->Privileges[i].Luid.HighPart == CapturedPrivileges[j].Luid.HighPart)
{
- if (k < PrivilegeCount)
- {
- PreviousState->PrivilegeCount++;
- PreviousState->Privileges[k].Luid = Token->Privileges[i].Luid;
- PreviousState->Privileges[k].Attributes = Token->Privileges[i].Attributes;
- }
- else
+ DPRINT("Found privilege\n");
+
+ if ((Token->Privileges[i].Attributes & SE_PRIVILEGE_ENABLED) !=
+ (CapturedPrivileges[j].Attributes & SE_PRIVILEGE_ENABLED))
{
- /*
- * FIXME: Should revert all the changes, calculate how
- * much space would be needed, set ResultLength
- * accordingly and fail.
- */
- }
+ DPRINT("Attributes differ\n");
+ DPRINT("Current attributes %lx New attributes %lx\n",
+ Token->Privileges[i].Attributes,
+ CapturedPrivileges[j].Attributes);
- k++;
+ ChangeCount++;
+ }
}
-
- /* Update current privlege */
- Token->Privileges[i].Attributes &= ~SE_PRIVILEGE_ENABLED;
}
}
+ }
+
+ /*
+ * Return the required buffer size and
+ * check if the available buffer is large enough
+ */
+ if (PreviousState != NULL)
+ {
+ ULONG RequiredLength = (ULONG)sizeof(TOKEN_PRIVILEGES) +
+ ((ChangeCount - ANYSIZE_ARRAY) * (ULONG)sizeof(LUID_AND_ATTRIBUTES));
+
+ /* Try to return the required buffer length */
+ _SEH2_TRY
+ {
+ *ReturnLength = RequiredLength;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ /* Dereference the token */
+ ObDereferenceObject(Token);
+
+ /* Release the captured privileges */
+ if (CapturedPrivileges != NULL)
+ SeReleaseLuidAndAttributesArray(CapturedPrivileges,
+ PreviousMode,
+ TRUE);
+
+ /* Return the exception code */
+ _SEH2_YIELD(return _SEH2_GetExceptionCode());
+ }
+ _SEH2_END;
+
+ /* Fail, if the buffer length is smaller than the required length */
+ if (BufferLength < RequiredLength)
+ {
+ /* Dereference the token */
+ ObDereferenceObject(Token);
+
+ /* Release the captured privileges */
+ if (CapturedPrivileges != NULL)
+ SeReleaseLuidAndAttributesArray(CapturedPrivileges,
+ PreviousMode,
+ TRUE);
- Status = STATUS_SUCCESS;
+ return STATUS_BUFFER_TOO_SMALL;
+ }
}
- else
+
+ /* Change the privilege attributes */
+ ChangeCount = 0;
+ _SEH2_TRY
{
- Count = 0;
for (i = 0; i < Token->PrivilegeCount; i++)
{
- for (j = 0; j < NewState->PrivilegeCount; j++)
+ if (DisableAllPrivileges == TRUE)
{
- if (Token->Privileges[i].Luid.LowPart == NewState->Privileges[j].Luid.LowPart &&
- Token->Privileges[i].Luid.HighPart == NewState->Privileges[j].Luid.HighPart)
+ if (Token->Privileges[i].Attributes & SE_PRIVILEGE_ENABLED)
{
- DPRINT ("Found privilege\n");
+ DPRINT("Privilege enabled\n");
- if ((Token->Privileges[i].Attributes & SE_PRIVILEGE_ENABLED) !=
- (NewState->Privileges[j].Attributes & SE_PRIVILEGE_ENABLED))
+ /* Save the current privilege */
+ if (PreviousState != NULL)
{
- DPRINT ("Attributes differ\n");
- DPRINT ("Current attributes %lx desired attributes %lx\n",
- Token->Privileges[i].Attributes,
- NewState->Privileges[j].Attributes);
+ PreviousState->Privileges[ChangeCount].Luid = Token->Privileges[i].Luid;
+ PreviousState->Privileges[ChangeCount].Attributes = Token->Privileges[i].Attributes;
+ }
+
+ /* Disable the current privlege */
+ Token->Privileges[i].Attributes &= ~SE_PRIVILEGE_ENABLED;
- /* Save current privilege */
- if (PreviousState != NULL)
+ ChangeCount++;
+ }
+ }
+ else
+ {
+ for (j = 0; j < CapturedCount; j++)
+ {
+ if (Token->Privileges[i].Luid.LowPart == CapturedPrivileges[j].Luid.LowPart &&
+ Token->Privileges[i].Luid.HighPart == CapturedPrivileges[j].Luid.HighPart)
+ {
+ DPRINT("Found privilege\n");
+
+ /* Check whether the attributes differ */
+ if ((Token->Privileges[i].Attributes & SE_PRIVILEGE_ENABLED) !=
+ (CapturedPrivileges[j].Attributes & SE_PRIVILEGE_ENABLED))
{
- if (k < PrivilegeCount)
- {
- PreviousState->PrivilegeCount++;
- PreviousState->Privileges[k].Luid = Token->Privileges[i].Luid;
- PreviousState->Privileges[k].Attributes = Token->Privileges[i].Attributes;
- }
- else
+ DPRINT("Attributes differ\n");
+ DPRINT("Current attributes %lx New attributes %lx\n",
+ Token->Privileges[i].Attributes,
+ CapturedPrivileges[j].Attributes);
+
+ /* Save the current privilege */
+ if (PreviousState != NULL)
{
- /*
- * FIXME: Should revert all the changes, calculate how
- * much space would be needed, set ResultLength
- * accordingly and fail.
- */
+ PreviousState->Privileges[ChangeCount].Luid = Token->Privileges[i].Luid;
+ PreviousState->Privileges[ChangeCount].Attributes = Token->Privileges[i].Attributes;
}
- k++;
- }
+ /* Update the current privlege */
+ Token->Privileges[i].Attributes &= ~SE_PRIVILEGE_ENABLED;
+ Token->Privileges[i].Attributes |=
+ (CapturedPrivileges[j].Attributes & SE_PRIVILEGE_ENABLED);
+ DPRINT("New attributes %lx\n",
+ Token->Privileges[i].Attributes);
- /* Update current privlege */
- Token->Privileges[i].Attributes &= ~SE_PRIVILEGE_ENABLED;
- Token->Privileges[i].Attributes |=
- (NewState->Privileges[j].Attributes & SE_PRIVILEGE_ENABLED);
- DPRINT ("New attributes %lx\n",
- Token->Privileges[i].Attributes);
+ ChangeCount++;
+ }
}
-
- Count++;
}
}
}
- Status = Count < NewState->PrivilegeCount ? STATUS_NOT_ALL_ASSIGNED : STATUS_SUCCESS;
+ /* Set the number of saved privileges */
+ if (PreviousState != NULL)
+ PreviousState->PrivilegeCount = ChangeCount;
}
-
- if (ReturnLength != NULL)
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
- *ReturnLength = sizeof(TOKEN_PRIVILEGES) +
- (sizeof(LUID_AND_ATTRIBUTES) * (k - 1));
+ /* Dereference the token */
+ ObDereferenceObject(Token);
+
+ /* Release the captured privileges */
+ if (CapturedPrivileges != NULL)
+ SeReleaseLuidAndAttributesArray(CapturedPrivileges,
+ PreviousMode,
+ TRUE);
+
+ /* Return the exception code */
+ _SEH2_YIELD(return _SEH2_GetExceptionCode());
}
+ _SEH2_END;
+ /* Set the status */
+ Status = (ChangeCount < CapturedCount) ? STATUS_NOT_ALL_ASSIGNED : STATUS_SUCCESS;
+
+ /* Dereference the token */
ObDereferenceObject (Token);
- // SeReleaseLuidAndAttributesArray(Privileges,
- // PreviousMode,
- // 0);
+ /* Release the captured privileges */
+ if (CapturedPrivileges != NULL)
+ SeReleaseLuidAndAttributesArray(CapturedPrivileges,
+ PreviousMode,
+ TRUE);
DPRINT ("NtAdjustPrivilegesToken() done\n");
int dy2; // dest y end
int sy1; // src y start
- int dx;
int shift;
BYTE srcmask, dstmask, xormask;
pd = d;
ps = s;
srcmask = 0xff;
- dx = dwx; /* dest x for this pass */
if ( dwx < dl )
{
int diff = dl-dwx;
srcmask &= (1<<(8-diff))-1;
- dx = dl;
}
if ( dwx+7 > dr )
{
RECTL* DestRect, RECTL *SourceRect,
XLATEOBJ *ColorTranslation, ULONG iTransColor)
{
- ULONG RoundedRight, X, Y, SourceX = 0, SourceY = 0, Source, wd, Dest;
+ ULONG RoundedRight, X, Y, SourceX = 0, SourceY = 0, Source, Dest;
ULONG *DestBits;
LONG DstHeight;
RoundedRight = DestRect->right - ((DestRect->right - DestRect->left) & 0x3);
DestBits = (ULONG*)((PBYTE)DestSurf->pvScan0 + DestRect->left +
(DestRect->top * DestSurf->lDelta));
- wd = DestSurf->lDelta - (DestRect->right - DestRect->left);
for(Y = DestRect->top; Y < DestRect->bottom; Y++)
{
POINTL Pt;
ULONG Direction;
BOOL UsesSource;
- BOOL UsesPattern;
POINTL AdjustedBrushOrigin;
UsesSource = ROP4_USES_SOURCE(rop4);
- UsesPattern = ROP4_USES_PATTERN(rop4);
if (R4_NOOP == rop4)
{
/* Copy destination onto itself: nop */
{
LONG y;
ULONG LineWidth;
- SURFACE *psurf;
ASSERT(pso);
ASSERT(pRect);
- psurf = CONTAINING_RECORD(pso, SURFACE, SurfObj);
LineWidth = pRect->right - pRect->left;
DPRINT(" LineWidth: %d, top: %d, bottom: %d\n", LineWidth, pRect->top, pRect->bottom);
for (y = pRect->top; y < pRect->bottom; y++)
IN OUT PCLS *BaseClassLink,
IN OUT PCLS *CloneLink)
{
- PCLS Clone, BaseClass;
+ PCLS Clone;
ASSERT(Class->pclsBase != Class);
ASSERT(Class->pclsBase->pclsClone != NULL);
*CloneLink = Class->pclsNext;
Class->pclsClone = Class->pclsBase->pclsClone;
- BaseClass = Class->pclsBase;
-
/* update the class information to make it a base class */
Class->pclsBase = Class;
Class->pclsNext = (*BaseClassLink)->pclsNext;
IN BOOL Ansi,
HINSTANCE hInstance)
{
- PPROCESSINFO pi;
-
if (!Class) return FALSE;
lpwcx->style = Class->style;
if (Class->fnid)
lpwcx->style &= ~CS_GLOBALCLASS;
- pi = GetW32ProcessInfo();
-
lpwcx->lpfnWndProc = IntGetClassWndProc(Class, Ansi);
lpwcx->cbClsExtra = Class->cbclsExtra;
// because pallette information may change
HDC hdc;
- INT ret;
BITMAP bm;
BITMAPINFO bi;
SURFACE *psurf;
bi.bmiHeader.biYPelsPerMeter = 0;
bi.bmiHeader.biClrUsed = 0;
- ret = NtGdiGetDIBitsInternal(hdc, hMem, 0, bm.bmHeight, NULL, &bi, DIB_RGB_COLORS, 0, 0);
+ NtGdiGetDIBitsInternal(hdc, hMem, 0, bm.bmHeight, NULL, &bi, DIB_RGB_COLORS, 0, 0);
size = bi.bmiHeader.biSizeImage + sizeof(BITMAPINFOHEADER);
hCBData = ExAllocatePoolWithTag(PagedPool, size, USERTAG_CLIPBOARD);
memcpy(hCBData, &bi, sizeof(BITMAPINFOHEADER));
- ret = NtGdiGetDIBitsInternal(hdc, hMem, 0, bm.bmHeight, (LPBYTE)hCBData + sizeof(BITMAPINFOHEADER), &bi, DIB_RGB_COLORS, 0, 0);
+ NtGdiGetDIBitsInternal(hdc, hMem, 0, bm.bmHeight, (LPBYTE)hCBData + sizeof(BITMAPINFOHEADER), &bi, DIB_RGB_COLORS, 0, 0);
UserReleaseDC(NULL, hdc, FALSE);
PCURICON_OBJECT OldCursor;
HCURSOR hOldCursor = (HCURSOR)0;
HDC hdcScreen;
- BOOL bResult;
CurInfo = IntGetSysCursorInfo();
CurInfo->CurrentCursorObject = NewCursor;
/* Call GDI to set the new screen cursor */
- bResult = GreSetPointerShape(hdcScreen,
- NewCursor->IconInfo.hbmMask,
- NewCursor->IconInfo.hbmColor,
- NewCursor->IconInfo.xHotspot,
- NewCursor->IconInfo.yHotspot,
- gpsi->ptCursor.x,
- gpsi->ptCursor.y);
+ GreSetPointerShape(hdcScreen,
+ NewCursor->IconInfo.hbmMask,
+ NewCursor->IconInfo.hbmColor,
+ NewCursor->IconInfo.xHotspot,
+ NewCursor->IconInfo.yHotspot,
+ gpsi->ptCursor.x,
+ gpsi->ptCursor.y);
}
{
PEVENTHOOK pEH;
PLIST_ENTRY pLE;
- LRESULT Result;
DPRINT("IntNotifyWinEvent GlobalEvents = 0x%x pWnd 0x%x\n",GlobalEvents, pWnd);
if (!(pEH->idProcess) || !(pEH->idThread) ||
(NtCurrentTeb()->ClientId.UniqueProcess == (PVOID)(DWORD_PTR)pEH->idProcess))
{
- Result = IntCallLowLevelEvent( pEH,
- Event,
- UserHMGetHandle(pWnd),
- idObject,
- idChild);
+ IntCallLowLevelEvent( pEH,
+ Event,
+ UserHMGetHandle(pWnd),
+ idObject,
+ idChild);
}
}// if ^skip own thread && ((Pid && CPid == Pid && ^skip own process) || all process)
else if ( !(pEH->Flags & WINEVENT_SKIPOWNTHREAD) &&
!(pEH->Flags & WINEVENT_SKIPOWNPROCESS)) ||
!pEH->idProcess ) )
{
- Result = co_IntCallEventProc( UserHMGetHandle(pEH),
+ // What in the deuce is this right-aligned formatting?
+ co_IntCallEventProc( UserHMGetHandle(pEH),
Event,
UserHMGetHandle(pWnd),
idObject,
IntKeyboardInput(KEYBDINPUT *ki)
{
PUSER_MESSAGE_QUEUE FocusMessageQueue;
- PTHREADINFO pti;
MSG Msg;
LARGE_INTEGER LargeTickCount;
KBDLLHOOKSTRUCT KbdHookData;
Msg.time = ki->time;
/* All messages have to contain the cursor point. */
- pti = PsGetCurrentThreadWin32Thread();
Msg.pt = gpsi->ptCursor;
KbdHookData.vkCode = vk_hook;
MSG NewMsg = { 0 };
PKBDTABLES keyLayout;
BOOL Result = FALSE;
- DWORD ScanCode = 0;
pti = PsGetCurrentThreadWin32Thread();
keyLayout = pti->KeyboardLayout->KBTables;
return TRUE;
}
- ScanCode = (lpMsg->lParam >> 16) & 0xff;
-
UState = ToUnicodeInner(lpMsg->wParam, HIWORD(lpMsg->lParam) & 0xff,
gQueueKeyStateTable, wp, 2, 0,
keyLayout );
IntBuildMenuItemList(PMENU_OBJECT MenuObject, PVOID Buffer, ULONG nMax)
{
DWORD res = 0;
- UINT sz;
ROSMENUITEMINFO mii;
PVOID Buf;
PMENU_ITEM CurItem = MenuObject->MenuItemList;
StrOut = (PWCHAR)((char *) Buffer + MenuObject->MenuInfo.MenuItemCount
* sizeof(ROSMENUITEMINFO));
nMax -= MenuObject->MenuInfo.MenuItemCount * sizeof(ROSMENUITEMINFO);
- sz = sizeof(ROSMENUITEMINFO);
Buf = Buffer;
mii.cbSize = sizeof(ROSMENUITEMINFO);
mii.fMask = 0;
ULONG_PTR PResult;
PTHREADINFO pti;
PWINDOW_OBJECT Window;
- MSG Message;
if ( !(Window = UserGetWindowObject(hWnd)) ) return FALSE;
}
else
{ // Handle message and callback.
- Message.hwnd = hWnd;
- Message.message = Msg;
- Message.wParam = wParam;
- Message.lParam = lParam;
-
Result = co_IntSendMessageTimeoutSingle( hWnd,
Msg,
wParam,
HANDLE hPowerRequestEvent,
HANDLE hMediaRequestEvent)
{
- NTSTATUS Status;
-
// Set W32PF_Flags |= (W32PF_READSCREENACCESSGRANTED | W32PF_IOWINSTA)
// Create Object Directory,,, Looks like create workstation. "\\Windows\\WindowStations"
// Create Event for Diconnect Desktop.
// Callback to User32 Client Thread Setup
- Status = co_IntClientThreadSetup();
+ co_IntClientThreadSetup();
// }
// Set Global SERVERINFO Error flags.
{
PWND Wnd;
HRGN hRgnWindow;
- UINT RgnType;
Wnd = Window->Wnd;
if (Client)
NtGdiOffsetRgn(hRgnWindow,
-Wnd->rcWindow.left,
-Wnd->rcWindow.top);
- RgnType = NtGdiCombineRgn(hRgnWindow, hRgnWindow, Window->hrgnClip, RGN_AND);
+ NtGdiCombineRgn(hRgnWindow, hRgnWindow, Window->hrgnClip, RGN_AND);
NtGdiOffsetRgn(hRgnWindow,
Wnd->rcWindow.left,
Wnd->rcWindow.top);
if (WndCaret == Window ||
((flags & SW_SCROLLCHILDREN) && IntIsChildWindow(Window, WndCaret)))
{
- POINT pt, FromOffset, ToOffset, Offset;
+ POINT pt, FromOffset, ToOffset;
RECTL rcCaret;
pt.x = CaretInfo->Pos.x;
pt.y = CaretInfo->Pos.y;
IntGetClientOrigin(WndCaret, &FromOffset);
IntGetClientOrigin(Window, &ToOffset);
- Offset.x = FromOffset.x - ToOffset.x;
- Offset.y = FromOffset.y - ToOffset.y;
rcCaret.left = pt.x;
rcCaret.top = pt.y;
rcCaret.right = pt.x + CaretInfo->Size.cx;
IntRemoveProp(PWINDOW_OBJECT Window, ATOM Atom)
{
PPROPERTY Prop;
- HANDLE Data;
Prop = IntGetProp(Window, Atom);
if (Prop == NULL)
{
return FALSE;
}
- Data = Prop->Data;
RemoveEntryList(&Prop->PropListEntry);
UserHeapFree(Prop);
Window->Wnd->PropListItems--;
{
PSCROLLBARINFO psbi;
LPSCROLLINFO psi;
- LRESULT Result;
ULONG Size, s;
INT i;
RtlZeroMemory(Window->pSBInfo, Size);
- Result = co_WinPosGetNonClientSize(Window,
- &Window->Wnd->rcWindow,
- &Window->Wnd->rcClient);
+ co_WinPosGetNonClientSize(Window,
+ &Window->Wnd->rcWindow,
+ &Window->Wnd->rcClient);
for(s = SB_HORZ; s <= SB_VERT; s++)
{
{
DWORD Ret = 0;
PWINDOW_OBJECT Window;
- PWND Wnd;
USER_REFERENCE_ENTRY Ref;
DECLARE_RETURN(DWORD);
}
UserRefObjectCo(Window, &Ref);
- Wnd = Window->Wnd;
-
switch (Routine)
{
case TWOPARAM_ROUTINE_VALIDATERGN:
/* default positioning for overlapped windows */
if(!(Cs->style & (WS_POPUP | WS_CHILD)))
{
- RECTL rc, WorkArea;
+ RECTL WorkArea;
PRTL_USER_PROCESS_PARAMETERS ProcessParams;
UserSystemParametersInfo(SPI_GETWORKAREA, 0, &WorkArea, 0);
- rc = WorkArea;
ProcessParams = PsGetCurrentProcess()->Peb->ProcessParameters;
if (IS_DEFAULT(Cs->x))
(PHANDLE)&hWnd,
otWindow,
sizeof(WINDOW_OBJECT));
+ if (!Window)
+ {
+ goto AllocError;
+ }
Wnd = DesktopHeapAlloc(pti->rpdesk, sizeof(WND) + Class->cbwndExtra);
- if(!Window || !Wnd)
+ if (!Wnd)
{
goto AllocError;
}
/* If the window was created, the class will be dereferenced by co_UserDestroyWindow */
if (Window)
co_UserDestroyWindow(Window);
- else
+ else if (Class)
IntDereferenceClass(Class, pti->pDeskInfo, pti->ppi);
}
for (;;)
{
- PWINDOW_OBJECT Parent, Old;
+ PWINDOW_OBJECT Parent;
- Old = WndAncestor;
Parent = IntGetParent(WndAncestor);
if (!Parent)
LPPOINT ptIcon)
{
PWINDOW_OBJECT Window;
- PWND Wnd;
DWORD Ret = 0;
BOOL Hit = FALSE;
WINDOWPLACEMENT wndpl;
Hit = FALSE;
goto Exit;
}
- Wnd = Window->Wnd;
_SEH2_TRY
{
if ((DesktopWindow = UserGetWindowObject(IntGetDesktopWindow())))
{
PTHREADINFO pti;
- USHORT Hit;
pt.x = X;
pt.y = Y;
UserRefObjectCo(DesktopWindow, &Ref);
pti = PsGetCurrentThreadWin32Thread();
- Hit = co_WinPosWindowFromPoint(DesktopWindow, pti->MessageQueue, &pt, &Window);
+ co_WinPosWindowFromPoint(DesktopWindow, pti->MessageQueue, &pt, &Window);
if(Window)
{
BOOL APIENTRY
NtUserSetProcessWindowStation(HWINSTA hWindowStation)
{
- HANDLE hOld;
PWINSTATION_OBJECT NewWinSta;
NTSTATUS Status;
*/
/* FIXME - dereference the old window station, etc... */
- hOld = InterlockedExchangePointer(&PsGetCurrentProcess()->Win32WindowStation, hWindowStation);
+ InterlockedExchangePointer(&PsGetCurrentProcess()->Win32WindowStation, hWindowStation);
DPRINT("PsGetCurrentProcess()->Win32WindowStation 0x%X\n",
PsGetCurrentProcess()->Win32WindowStation);
VOID
CopytoUserDcAttr(PDC dc, PDC_ATTR pdcattr)
{
- NTSTATUS Status = STATUS_SUCCESS;
dc->dcattr.mxWorldToDevice = dc->dclevel.mxWorldToDevice;
dc->dcattr.mxDeviceToWorld = dc->dclevel.mxDeviceToWorld;
dc->dcattr.mxWorldToPage = dc->dclevel.mxWorldToPage;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
- Status = _SEH2_GetExceptionCode();
ASSERT(FALSE);
}
_SEH2_END;
PSECTION_OBJECT SectionObject;
ULONG ViewSize = 0;
LARGE_INTEGER SectionSize;
+#if 0 // Wine code
FT_Fixed XScale, YScale;
+#endif
UNICODE_STRING FontRegPath = RTL_CONSTANT_STRING(L"\\REGISTRY\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Fonts");
/* Open the font file */
FontGDI->face = Face;
/* FIXME: Complete text metrics */
+#if 0 /* This (Wine) code doesn't seem to work correctly for us */
XScale = Face->size->metrics.x_scale;
YScale = Face->size->metrics.y_scale;
-#if 0 /* This (Wine) code doesn't seem to work correctly for us */
FontGDI->TextMetric.tmAscent = (FT_MulFix(Face->ascender, YScale) + 32) >> 6;
FontGDI->TextMetric.tmDescent = (FT_MulFix(Face->descender, YScale) + 32) >> 6;
FontGDI->TextMetric.tmHeight = (FT_MulFix(Face->ascender, YScale) -
case GdiBCSelObj:
{
PGDIBSOBJECT pgO;
- PTEXTOBJ pOrgFnt, pNewFnt = NULL;
- HFONT hOrgFont = NULL;
+ PTEXTOBJ pNewFnt = NULL;
if (!dc) break;
pgO = (PGDIBSOBJECT) pHdr;
/* LFONTOBJ use share and locking. */
pNewFnt = TEXTOBJ_LockText(pgO->hgdiobj);
- pOrgFnt = dc->dclevel.plfnt;
- if (pOrgFnt)
- {
- hOrgFont = pOrgFnt->BaseObject.hHmgr;
- }
- else
- {
- hOrgFont = pdcattr->hlfntNew;
- }
dc->dclevel.plfnt = pNewFnt;
dc->hlfntCur = pgO->hgdiobj;
pdcattr->hlfntNew = pgO->hgdiobj;
int realized = 0;
PDC dc;
HPALETTE systemPalette;
- USHORT sysMode, palMode;
dc = DC_LockDc(hDC);
if (!dc) return 0;
}
// need to pass this to IntEngCreateXlate with palettes unlocked
- sysMode = sysGDI->Mode;
- palMode = palGDI->Mode;
PALETTE_UnlockPalette(sysGDI);
PALETTE_UnlockPalette(palGDI);
FASTCALL
PATH_FillPath( PDC dc, PPATH pPath )
{
- INT mapMode, graphicsMode;
- SIZE ptViewportExt, ptWindowExt;
- POINTL ptViewportOrg, ptWindowOrg;
+ //INT mapMode, graphicsMode;
+ //SIZE ptViewportExt, ptWindowExt;
+ //POINTL ptViewportOrg, ptWindowOrg;
XFORM xform;
HRGN hrgn;
PDC_ATTR pdcattr = dc->pdcattr;
*/
/* Save the information about the old mapping mode */
- mapMode = pdcattr->iMapMode;
- ptViewportExt = pdcattr->szlViewportExt;
- ptViewportOrg = pdcattr->ptlViewportOrg;
- ptWindowExt = pdcattr->szlWindowExt;
- ptWindowOrg = pdcattr->ptlWindowOrg;
+ //mapMode = pdcattr->iMapMode;
+ //ptViewportExt = pdcattr->szlViewportExt;
+ //ptViewportOrg = pdcattr->ptlViewportOrg;
+ //ptWindowExt = pdcattr->szlWindowExt;
+ //ptWindowOrg = pdcattr->ptlWindowOrg;
/* Save world transform
* NB: The Windows documentation on world transforms would lead one to
// pdcattr->ptlWindowOrg.x = 0;
// pdcattr->ptlWindowOrg.y = 0;
- graphicsMode = pdcattr->iGraphicsMode;
+ // graphicsMode = pdcattr->iGraphicsMode;
// pdcattr->iGraphicsMode = GM_ADVANCED;
// IntGdiModifyWorldTransform( dc, &xform, MWT_IDENTITY );
// pdcattr->iGraphicsMode = graphicsMode;
// pdcattr->ptlWindowOrg = ptWindowOrg;
/* Go to GM_ADVANCED temporarily to restore the world transform */
- graphicsMode = pdcattr->iGraphicsMode;
+ //graphicsMode = pdcattr->iGraphicsMode;
// pdcattr->iGraphicsMode = GM_ADVANCED;
// IntGdiModifyWorldTransform( dc, &xform, MWT_MAX+1 );
// pdcattr->iGraphicsMode = graphicsMode;
REGION_FreeRgnByHandle(tmpVisRgn);
// Fill the region
- return TRUE;
+ return bRet;
}
BOOL