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.

349 lines
11 KiB

  1. /*--------------------------------------------------------------------------
  2. *
  3. * Copyright (C) Cyclades Corporation, 2000-2001.
  4. * All rights reserved.
  5. *
  6. * Cyclades-Z Enumerator Driver
  7. *
  8. * This file: enum.c
  9. *
  10. * Description: This module contains the enumeration code needed
  11. * to figure out whether or not a device is attached
  12. * to the serial port. If there is one, it will obtain
  13. * the PNP COM ID (if the device is PNP) and parse out
  14. * the relevant fields.
  15. *
  16. * Notes: This code supports Windows 2000 and Windows XP,
  17. * x86 and ia64 processors.
  18. *
  19. * Complies with Cyclades SW Coding Standard rev 1.3.
  20. *
  21. *--------------------------------------------------------------------------
  22. */
  23. /*-------------------------------------------------------------------------
  24. *
  25. * Change History
  26. *
  27. *--------------------------------------------------------------------------
  28. * Initial implementation based on Microsoft sample code.
  29. *
  30. *--------------------------------------------------------------------------
  31. */
  32. #include "pch.h"
  33. #define MAX_DEVNODE_NAME 256 // Total size of Device ID
  34. #ifdef ALLOC_PRAGMA
  35. #pragma alloc_text(PAGESENM, Cycladz_ReenumerateDevices)
  36. //#pragma alloc_text (PAGE, Cycladz_GetRegistryKeyValue)
  37. #endif
  38. #if !defined(__isascii)
  39. #define __isascii(_c) ( (unsigned)(_c) < 0x80 )
  40. #endif // !defined(__isascii)
  41. NTSTATUS
  42. Cycladz_ReenumerateDevices(IN PIRP Irp, IN PFDO_DEVICE_DATA FdoData)
  43. /*++
  44. Routine Description:
  45. This enumerates the cyclades-z bus which is represented by Fdo (a pointer
  46. to the device object representing the cyclades-z bus). It creates new PDOs
  47. for any new devices which have been discovered since the last enumeration
  48. Arguments:
  49. FdoData - Pointer to the fdo's device extension
  50. for the serial bus which needs to be enumerated
  51. Irp - Pointer to the Irp which was sent to reenumerate.
  52. Return value:
  53. NTSTATUS
  54. --*/
  55. {
  56. PIRP NewIrp;
  57. NTSTATUS status = STATUS_SUCCESS;
  58. KEVENT event;
  59. KTIMER timer;
  60. IO_STATUS_BLOCK IoStatusBlock;
  61. UNICODE_STRING pdoUniName;
  62. UNICODE_STRING instanceStr;
  63. WCHAR instanceNumberBuffer[20];
  64. static ULONG currentInstance = 0;
  65. // PDEVICE_OBJECT pdo = FdoData->AttachedPDO;
  66. PDEVICE_OBJECT pdo;
  67. PPDO_DEVICE_DATA pdoData;
  68. UNICODE_STRING HardwareIDs;
  69. UNICODE_STRING CompIDs;
  70. UNICODE_STRING DeviceIDs;
  71. UNICODE_STRING DevDesc;
  72. UNICODE_STRING InstanceIDs;
  73. ULONG i;
  74. WCHAR pdoName[] = CYZ_PDO_NAME_BASE;
  75. ULONG FdoFlags = FdoData->Self->Flags;
  76. ULONG numPorts = FdoData->NumPorts;
  77. UNREFERENCED_PARAMETER (Irp);
  78. PAGED_CODE();
  79. // Cyclades-Z port enumeration
  80. //************************************************************************
  81. // HARDCODE NUMBER OF PORTS TO 1
  82. // numPorts = 1;
  83. //************************************************************************
  84. Cycladz_KdPrint(FdoData,SER_DBG_CYCLADES,("numPorts detected = %d\n",numPorts));
  85. if (numPorts < FdoData->NumPDOs) {
  86. for (i=numPorts; i < CYZ_MAX_PORTS; i++) {
  87. pdo = FdoData->AttachedPDO[i];
  88. if (pdo != NULL) {
  89. // Something was there. The device must have been unplugged.
  90. // Remove the PDO.
  91. Cycladz_PDO_EnumMarkMissing(FdoData, pdo->DeviceExtension);
  92. }
  93. }
  94. goto ExitReenumerate;
  95. }
  96. if (numPorts == FdoData->NumPDOs) {
  97. // All ports already enumerated.
  98. Cycladz_KdPrint(FdoData,SER_DBG_CYCLADES,("All ports already enumerated\n",numPorts));
  99. goto ExitReenumerate;
  100. }
  101. // New ports that need to be enumerated.
  102. RtlZeroMemory(&pdoUniName,sizeof(UNICODE_STRING));
  103. pdoUniName.MaximumLength = DEVICE_OBJECT_NAME_LENGTH * sizeof(WCHAR);
  104. pdoUniName.Buffer = ExAllocatePool(PagedPool,pdoUniName.MaximumLength
  105. + sizeof(WCHAR));
  106. if (pdoUniName.Buffer == NULL) {
  107. Cycladz_KdPrint(FdoData,SER_DBG_CYCLADES,("Couldn't allocate memory for device name\n"));
  108. status = STATUS_INSUFFICIENT_RESOURCES;
  109. goto ExitReenumerate;
  110. }
  111. for (i=FdoData->NumPDOs; numPorts && (i< CYZ_MAX_PORTS); i++) {
  112. UCHAR RawString[MAX_DEVICE_ID_LEN];
  113. ANSI_STRING AnsiString;
  114. RtlZeroMemory(pdoUniName.Buffer,pdoUniName.MaximumLength);
  115. pdoUniName.Length = 0;
  116. RtlAppendUnicodeToString(&pdoUniName,pdoName);
  117. RtlInitUnicodeString(&instanceStr, NULL);
  118. instanceStr.MaximumLength = sizeof(instanceNumberBuffer);
  119. instanceStr.Buffer = instanceNumberBuffer;
  120. RtlIntegerToUnicodeString(currentInstance++, 10, &instanceStr);
  121. RtlAppendUnicodeStringToString(&pdoUniName, &instanceStr);
  122. //
  123. // Allocate a pdo
  124. //
  125. status = IoCreateDevice(FdoData->Self->DriverObject,
  126. sizeof(PDO_DEVICE_DATA), &pdoUniName,
  127. FILE_DEVICE_UNKNOWN,
  128. FILE_AUTOGENERATED_DEVICE_NAME, FALSE, &pdo);
  129. if (!NT_SUCCESS(status)) {
  130. Cycladz_KdPrint(FdoData, SER_DBG_SS_ERROR, ("Create device failed\n"));
  131. ExFreePool(pdoUniName.Buffer);
  132. goto ExitReenumerate;
  133. }
  134. Cycladz_KdPrint(FdoData, SER_DBG_SS_TRACE,
  135. ("Created PDO on top of filter: %x\n",pdo));
  136. pdoData = pdo->DeviceExtension;
  137. RtlInitUnicodeString(&pdoData->HardwareIDs, NULL);
  138. RtlInitUnicodeString(&pdoData->CompIDs, NULL);
  139. RtlInitUnicodeString(&pdoData->DeviceIDs, NULL);
  140. RtlInitUnicodeString(&pdoData->DevDesc, NULL);
  141. RtlInitUnicodeString(&pdoData->InstanceIDs,NULL);
  142. // Hardware ID
  143. sprintf((PCHAR)RawString,"%s%u",CYZPORT_PNP_ID_STR,i+1); // Cyclades-Z\\Port1, etc
  144. Cycladz_InitMultiString(FdoData, &pdoData->HardwareIDs, RawString, NULL);
  145. Cycladz_KdPrint(FdoData,SER_DBG_CYCLADES,("Hardware Id %ws\n",pdoData->HardwareIDs.Buffer));
  146. // That's how ..\parclass\pnppdo.c does. (Fanny)
  147. // Instance ID
  148. sprintf((PCHAR)RawString,"%02u",i+1);
  149. RtlInitAnsiString(&AnsiString,(PCHAR)RawString);
  150. RtlAnsiStringToUnicodeString(&pdoData->InstanceIDs,&AnsiString,TRUE);
  151. Cycladz_KdPrint(FdoData,SER_DBG_CYCLADES,("Instance Id %s\n",AnsiString.Buffer));
  152. // Device ID
  153. sprintf((PCHAR)RawString,CYZPORT_DEV_ID_STR);
  154. RtlInitAnsiString(&AnsiString,(PCHAR)RawString);
  155. RtlAnsiStringToUnicodeString(&pdoData->DeviceIDs,&AnsiString,TRUE);
  156. Cycladz_KdPrint(FdoData,SER_DBG_CYCLADES,("Device Id %s\n",AnsiString.Buffer));
  157. // Device Description
  158. sprintf((PCHAR)RawString,"Cyclades-Z Port %2u",i+1);
  159. RtlInitAnsiString(&AnsiString,(PUCHAR)RawString);
  160. RtlAnsiStringToUnicodeString(&pdoData->DevDesc,&AnsiString,TRUE);
  161. Cycladz_KdPrint(FdoData,SER_DBG_CYCLADES,("Device Description %s\n",AnsiString.Buffer));
  162. Cycladz_InitPDO(i, pdo, FdoData);
  163. numPorts--;
  164. }
  165. ExFreePool(pdoUniName.Buffer);
  166. ExitReenumerate:;
  167. return status;
  168. }
  169. // "Cycladz_RemovePDO" CHANGED TO "Cycladz_PDO_EnumMarkMissing" in build 2072.
  170. void
  171. Cycladz_PDO_EnumMarkMissing(PFDO_DEVICE_DATA FdoData, PPDO_DEVICE_DATA PdoData)
  172. /*++
  173. Routine Description:
  174. Removes the attached pdo from the fdo's list of children.
  175. NOTE: THIS FUNCTION CAN ONLY BE CALLED DURING AN ENUMERATION. If called
  176. outside of enumeration, Cyclades-Z might delete it's PDO before PnP has
  177. been told the PDO is gone.
  178. Arguments:
  179. FdoData - Pointer to the fdo's device extension
  180. PdoData - Pointer to the pdo's device extension
  181. Return value:
  182. none
  183. --*/
  184. {
  185. ULONG IndexPDO = PdoData->PortIndex;
  186. Cycladz_KdPrint (FdoData, SER_DBG_SS_TRACE, ("Removing Pdo %x\n",
  187. PdoData->Self));
  188. ASSERT(PdoData->Attached);
  189. PdoData->Attached = FALSE;
  190. FdoData->AttachedPDO[IndexPDO] = NULL;
  191. FdoData->PdoData[IndexPDO] = NULL;
  192. FdoData->NumPDOs--;
  193. }
  194. NTSTATUS
  195. Cycladz_GetRegistryKeyValue(IN HANDLE Handle, IN PWCHAR KeyNameString,
  196. IN ULONG KeyNameStringLength, IN PVOID Data,
  197. IN ULONG DataLength, OUT PULONG ActualLength)
  198. /*++
  199. Routine Description:
  200. Reads a registry key value from an already opened registry key.
  201. Arguments:
  202. Handle Handle to the opened registry key
  203. KeyNameString ANSI string to the desired key
  204. KeyNameStringLength Length of the KeyNameString
  205. Data Buffer to place the key value in
  206. DataLength Length of the data buffer
  207. Return Value:
  208. STATUS_SUCCESS if all works, otherwise status of system call that
  209. went wrong.
  210. --*/
  211. {
  212. UNICODE_STRING keyName;
  213. ULONG length;
  214. PKEY_VALUE_FULL_INFORMATION fullInfo;
  215. NTSTATUS ntStatus = STATUS_INSUFFICIENT_RESOURCES;
  216. RtlInitUnicodeString (&keyName, KeyNameString);
  217. length = sizeof(KEY_VALUE_FULL_INFORMATION) + KeyNameStringLength
  218. + DataLength;
  219. fullInfo = ExAllocatePool(PagedPool, length);
  220. if (ActualLength != NULL) {
  221. *ActualLength = 0;
  222. }
  223. if (fullInfo) {
  224. ntStatus = ZwQueryValueKey (Handle,
  225. &keyName,
  226. KeyValueFullInformation,
  227. fullInfo,
  228. length,
  229. &length);
  230. if (NT_SUCCESS(ntStatus)) {
  231. //
  232. // If there is enough room in the data buffer, copy the output
  233. //
  234. if (DataLength >= fullInfo->DataLength) {
  235. RtlCopyMemory(Data, ((PUCHAR)fullInfo) + fullInfo->DataOffset,
  236. fullInfo->DataLength);
  237. if (ActualLength != NULL) {
  238. *ActualLength = fullInfo->DataLength;
  239. }
  240. }
  241. }
  242. ExFreePool(fullInfo);
  243. }
  244. if (!NT_SUCCESS(ntStatus) && !NT_ERROR(ntStatus)) {
  245. if (ntStatus == STATUS_BUFFER_OVERFLOW) {
  246. ntStatus = STATUS_BUFFER_TOO_SMALL;
  247. } else {
  248. ntStatus = STATUS_UNSUCCESSFUL;
  249. }
  250. }
  251. return ntStatus;
  252. }
  253. int myatoi( WCHAR * pszInt )
  254. {
  255. int retval;
  256. WCHAR cSave;
  257. for( retval = 0; *pszInt; ++pszInt )
  258. {
  259. if( ( cSave = (WCHAR) ( *pszInt - L'0') ) > (WCHAR) 9 )
  260. break;
  261. retval = (int) ( retval * 10 + (int) cSave );
  262. }
  263. return( retval );
  264. }