Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

224 lines
5.7 KiB

  1. /*++
  2. Module Name:
  3. ENUM.C
  4. Abstract:
  5. This module contains the enumeration code needed to enumerate
  6. all ports on multiport board, and ceate the PDOs.
  7. Environment:
  8. kernel mode only
  9. Notes:
  10. Revision History:
  11. --*/
  12. #include <ntddk.h>
  13. #include <ntddser.h>
  14. #include "mxenum.h"
  15. #include "mxlog.h"
  16. static const PHYSICAL_ADDRESS SerialPhysicalZero = {0};
  17. #ifdef ALLOC_PRAGMA
  18. #pragma alloc_text(PAGE, MxenumCreatePDO)
  19. #pragma alloc_text(PAGE, MxenumInitPDO)
  20. #endif
  21. void
  22. MxenumInitPDO (
  23. PDEVICE_OBJECT Pdo,
  24. PFDO_DEVICE_DATA FdoData)
  25. /*
  26. Description:
  27. Common code to initialize a newly created serenum pdo.
  28. Called either when the control panel exposes a device or when Serenum senses
  29. a new device was attached.
  30. Parameters:
  31. Pdo - The pdo
  32. FdoData - The fdo's device extension
  33. Exposed - Was this pdo was found by serenum (FALSE) or was it was EXPOSEd by
  34. a control panel applet (TRUE)?
  35. */
  36. {
  37. ULONG FdoFlags = FdoData->Self->Flags;
  38. PPDO_DEVICE_DATA pdoData = Pdo->DeviceExtension;
  39. NTSTATUS status;
  40. ULONG j;
  41. HANDLE keyHandle;
  42. PAGED_CODE();
  43. Pdo->Flags |= DO_BUFFERED_IO;
  44. //
  45. // Increment the pdo's stacksize so that it can pass irps through
  46. //
  47. Pdo->StackSize += FdoData->Self->StackSize;
  48. //
  49. // Initialize the rest of the device extension
  50. //
  51. pdoData->IsFDO = FALSE;
  52. pdoData->Self = Pdo;
  53. pdoData->ParentFdo = FdoData->Self;
  54. pdoData->Started = FALSE; // irp_mn_start has yet to be received
  55. pdoData->Attached = TRUE; // attached to the bus
  56. pdoData->Removed = FALSE; // no irp_mn_remove as of yet
  57. pdoData->DeviceState = PowerDeviceD0;
  58. pdoData->SystemState = PowerSystemWorking;
  59. Pdo->Flags &= ~DO_DEVICE_INITIALIZING;
  60. Pdo->Flags |= DO_POWER_PAGABLE;
  61. }
  62. NTSTATUS
  63. MxenumCreatePDO(IN PFDO_DEVICE_DATA FdoData)
  64. /*++
  65. Routine Description:
  66. This enumerates the serenum bus which is represented by Fdo (a pointer
  67. to the device object representing the serial bus). It creates new PDOs
  68. for any new devices which have been discovered since the last enumeration
  69. Arguments:
  70. FdoData - Pointer to the fdo's device extension
  71. for the serial bus which needs to be enumerated
  72. Return value:
  73. NTSTATUS
  74. --*/
  75. {
  76. NTSTATUS status = STATUS_SUCCESS;
  77. UNICODE_STRING pdoUniName;
  78. PDEVICE_OBJECT pdo;
  79. PPDO_DEVICE_DATA pdoData;
  80. ULONG i,j;
  81. WCHAR pdoName[] = MXENUM_PDO_NAME_BASE;
  82. UCHAR hardwareId[] = MXENUM_PDO_HARDWARE_ID;
  83. UCHAR deviceId[] = MXENUM_PDO_DEVICE_ID;
  84. ULONG FdoFlags = FdoData->Self->Flags;
  85. PAGED_CODE();
  86. MxenumKdPrint (MXENUM_DBG_TRACE,("MxenumCreatePDO\n"));
  87. RtlInitUnicodeString(&pdoUniName, pdoName);
  88. for (i = 0; i < FdoData->NumPorts;i++) {
  89. PDEVICE_OBJECT currentDevice,previousDevice;
  90. //
  91. // Allocate a pdo
  92. //
  93. pdoName[19] = (WCHAR)('0' + FdoData->BoardIndex / 10);
  94. deviceId[14] = (UCHAR)pdoName[19];
  95. pdoName[20] = (WCHAR)('0' + FdoData->BoardIndex % 10);
  96. deviceId[15] = (UCHAR)pdoName[20];
  97. pdoName[22] = (WCHAR)('0' + i / 100);
  98. deviceId[17] = hardwareId[6] = (UCHAR)pdoName[22];
  99. pdoName[23] = (WCHAR)('0' + (i % 100)/10);
  100. deviceId[18] = hardwareId[7] = (UCHAR)pdoName[23];
  101. pdoName[24] = (WCHAR)('0' + (i % 100)%10);
  102. deviceId[19] = hardwareId[8] = (UCHAR)pdoName[24] ;
  103. previousDevice = currentDevice = FdoData->AttachedPDO;
  104. while (currentDevice != NULL) {
  105. for (j = 0;(j < strlen(deviceId))&&(j < (ULONG)((PPDO_DEVICE_DATA)(currentDevice->DeviceExtension))->DeviceIDs.Length >> 1);j++) {
  106. if (deviceId[j] != ((PPDO_DEVICE_DATA)(currentDevice->DeviceExtension))->DeviceIDs.Buffer[j])
  107. break;
  108. }
  109. if (j == strlen(deviceId))
  110. break;
  111. previousDevice = currentDevice;
  112. currentDevice = ((PPDO_DEVICE_DATA)(currentDevice->DeviceExtension))->Next;
  113. }
  114. if (currentDevice == NULL) { // New,create one
  115. status = IoCreateDevice(FdoData->Self->DriverObject,
  116. sizeof(PDO_DEVICE_DATA), &pdoUniName,
  117. FILE_DEVICE_SERIAL_PORT,
  118. FILE_AUTOGENERATED_DEVICE_NAME, FALSE, &pdo);
  119. if (!NT_SUCCESS(status)) {
  120. MxenumKdPrint(MXENUM_DBG_TRACE, ("Create device failed\n"));
  121. continue;
  122. }
  123. if (previousDevice)
  124. ((PPDO_DEVICE_DATA)(previousDevice->DeviceExtension))->Next = pdo;
  125. else
  126. FdoData->AttachedPDO = pdo;
  127. MxenumInitPDO(pdo, FdoData);
  128. pdoData = pdo->DeviceExtension;
  129. pdoData->PortIndex = i; // port indexed from 0
  130. }
  131. else {
  132. continue;
  133. }
  134. //
  135. // Initialize the rest of the device object
  136. if (pdoData->HardwareIDs.Buffer)
  137. ExFreePool(pdoData->HardwareIDs.Buffer);
  138. pdoData->HardwareIDs.Buffer = NULL;
  139. MxenumInitMultiString( &pdoData->HardwareIDs,hardwareId ,
  140. NULL);
  141. if (pdoData->CompIDs.Buffer)
  142. ExFreePool(pdoData->CompIDs.Buffer);
  143. pdoData->CompIDs.Buffer = NULL;
  144. MxenumInitMultiString( &pdoData->CompIDs,
  145. MXENUM_PDO_COMPATIBLE_ID,
  146. NULL);
  147. if (pdoData->DeviceIDs.Buffer)
  148. ExFreePool(pdoData->DeviceIDs.Buffer);
  149. pdoData->DeviceIDs.Buffer = NULL;
  150. MxenumInitMultiString(&pdoData->DeviceIDs,
  151. deviceId,
  152. NULL);
  153. FdoData->NumPDOs++;
  154. }
  155. // EnumPDOsErr:;
  156. return status;
  157. }