Source code of Windows XP (NT5)
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.

447 lines
11 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation, 1990 - 2001
  3. Module Name:
  4. prop.c
  5. Abstract:
  6. This is the NT SBP2 port/filter driver. This module contains code relating to
  7. property queries
  8. Authors:
  9. georgioc
  10. Environment:
  11. kernel mode only
  12. Notes:
  13. Revision History:
  14. georgioc - grabbed this module from scsiport, since i needed to duplicate this functionality
  15. in order to present sbp2port as a storage port
  16. --*/
  17. #include "sbp2port.h"
  18. #include "stdio.h"
  19. NTSTATUS
  20. Sbp2BuildDeviceDescriptor(
  21. IN PDEVICE_OBJECT DeviceObject,
  22. IN PSTORAGE_DEVICE_DESCRIPTOR Descriptor,
  23. IN OUT PULONG DescriptorLength
  24. );
  25. NTSTATUS
  26. Sbp2BuildAdapterDescriptor(
  27. IN PDEVICE_OBJECT DeviceObject,
  28. IN PSTORAGE_ADAPTER_DESCRIPTOR Descriptor,
  29. IN OUT PULONG DescriptorLength
  30. );
  31. NTSTATUS
  32. Sbp2QueryProperty(
  33. IN PDEVICE_OBJECT DeviceObject,
  34. IN PIRP QueryIrp
  35. )
  36. /*++
  37. Routine Description:
  38. This routine will handle a property query request. It will build the
  39. descriptor on it's own if possible, or it may forward the request down
  40. to lower level drivers.
  41. Since this routine may forward the request downwards the caller should
  42. not complete the irp
  43. This routine is asynchronous.
  44. This routine must be called at <= IRQL_DISPATCH
  45. Arguments:
  46. DeviceObject - a pointer to the device object being queried
  47. QueryIrp - a pointer to the irp for the query
  48. Return Value:
  49. STATUS_PENDING if the request cannot be completed yet
  50. STATUS_SUCCESS if the query was successful
  51. STATUS_INVALID_PARAMETER_1 if the property id does not exist
  52. STATUS_INVALID_PARAMETER_2 if the query type is invalid
  53. STATUS_INVALID_PARAMETER_3 if an invalid optional parameter was passed
  54. STATUS_INVALID_DEVICE_REQUEST if this request cannot be handled by this
  55. device
  56. other error values as applicable
  57. --*/
  58. {
  59. PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(QueryIrp);
  60. PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
  61. PSTORAGE_PROPERTY_QUERY query = QueryIrp->AssociatedIrp.SystemBuffer;
  62. ULONG queryLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength;
  63. NTSTATUS status;
  64. //
  65. // We don't handle mask queries yet
  66. //
  67. if (query->QueryType >= PropertyMaskQuery) {
  68. status = STATUS_INVALID_PARAMETER_1;
  69. QueryIrp->IoStatus.Status = status;
  70. QueryIrp->IoStatus.Information = 0;
  71. IoCompleteRequest(QueryIrp, IO_NO_INCREMENT);
  72. return status;
  73. }
  74. status = IoAcquireRemoveLock (&deviceExtension->RemoveLock, NULL);
  75. if (!NT_SUCCESS (status)) {
  76. QueryIrp->IoStatus.Status = status;
  77. QueryIrp->IoStatus.Information = 0;
  78. IoCompleteRequest(QueryIrp, IO_NO_INCREMENT);
  79. return status;
  80. }
  81. switch (query->PropertyId) {
  82. case StorageDeviceProperty:
  83. if (query->QueryType == PropertyExistsQuery) {
  84. status = STATUS_SUCCESS;
  85. } else {
  86. status = Sbp2BuildDeviceDescriptor(
  87. DeviceObject,
  88. QueryIrp->AssociatedIrp.SystemBuffer,
  89. &queryLength);
  90. QueryIrp->IoStatus.Information = queryLength;
  91. }
  92. break;
  93. case StorageAdapterProperty:
  94. //
  95. // Although we are a filter, we are essentially presenting the
  96. // 1394 bus driver as a Port driver, so this is handled here
  97. //
  98. if (query->QueryType == PropertyExistsQuery) {
  99. status = STATUS_SUCCESS;
  100. } else {
  101. status = Sbp2BuildAdapterDescriptor(
  102. DeviceObject,
  103. QueryIrp->AssociatedIrp.SystemBuffer,
  104. &queryLength);
  105. QueryIrp->IoStatus.Information = queryLength;
  106. }
  107. break;
  108. default:
  109. //
  110. // Nope, this property really doesn't exist
  111. //
  112. status = STATUS_INVALID_PARAMETER_1;
  113. QueryIrp->IoStatus.Information = 0;
  114. break;
  115. }
  116. QueryIrp->IoStatus.Status = status;
  117. IoReleaseRemoveLock (&deviceExtension->RemoveLock, NULL);
  118. IoCompleteRequest (QueryIrp, IO_DISK_INCREMENT);
  119. return status;
  120. }
  121. NTSTATUS
  122. Sbp2BuildDeviceDescriptor(
  123. IN PDEVICE_OBJECT DeviceObject,
  124. IN PSTORAGE_DEVICE_DESCRIPTOR Descriptor,
  125. IN OUT PULONG DescriptorLength
  126. )
  127. /*++
  128. Routine Description:
  129. This routine will create a device descriptor based on the information in
  130. it's device extension. It will copy as much data as possible into
  131. the Descriptor and will update the DescriptorLength to indicate the
  132. number of bytes copied
  133. Arguments:
  134. DeviceObject - a pointer to the PDO we are building a descriptor for
  135. Descriptor - a buffer to store the descriptor in
  136. DescriptorLength - the length of the buffer and the number of bytes
  137. returned
  138. QueryIrp - unused
  139. Return Value:
  140. status
  141. --*/
  142. {
  143. LONG maxLength = *DescriptorLength;
  144. LONG bytesRemaining = maxLength;
  145. ULONG realLength = sizeof (STORAGE_DEVICE_DESCRIPTOR);
  146. ULONG infoLength;
  147. PUCHAR currentOffset = (PUCHAR) Descriptor;
  148. PINQUIRYDATA inquiryData;
  149. PDEVICE_EXTENSION deviceExtension =DeviceObject->DeviceExtension;
  150. STORAGE_DEVICE_DESCRIPTOR tmp;
  151. inquiryData = &deviceExtension->InquiryData;
  152. //
  153. // The info includes VendorId, ProductId, ProductRevsisionLevel,
  154. // and (sprintf'd) EUI64 strings, plus ascii NULL terminators for each
  155. //
  156. infoLength =
  157. sizeof (inquiryData->VendorId) + 1 +
  158. sizeof (inquiryData->ProductId) + 1 +
  159. sizeof (inquiryData->ProductRevisionLevel) + 1 +
  160. 16 + 1;
  161. realLength += infoLength;
  162. RtlZeroMemory (Descriptor, maxLength);
  163. //
  164. // Build the device descriptor structure on the stack then copy as much as
  165. // can be copied over
  166. //
  167. RtlZeroMemory (&tmp, sizeof (STORAGE_DEVICE_DESCRIPTOR));
  168. tmp.Version = sizeof (STORAGE_DEVICE_DESCRIPTOR);
  169. tmp.Size = realLength;
  170. tmp.DeviceType = deviceExtension->InquiryData.DeviceType;
  171. tmp.DeviceTypeModifier = 0;
  172. if (deviceExtension->InquiryData.RemovableMedia ||
  173. (tmp.DeviceType == READ_ONLY_DIRECT_ACCESS_DEVICE)) {
  174. tmp.RemovableMedia = TRUE;
  175. DeviceObject->Characteristics |= FILE_REMOVABLE_MEDIA;
  176. } else {
  177. //
  178. // default case, if INQUIRY failed..
  179. //
  180. tmp.RemovableMedia = FALSE;
  181. }
  182. tmp.BusType = BusType1394;
  183. //
  184. // always true for sbp2 targets
  185. //
  186. tmp.CommandQueueing = TRUE;
  187. RtlCopyMemory(
  188. currentOffset,
  189. &tmp,
  190. min (sizeof (STORAGE_DEVICE_DESCRIPTOR), bytesRemaining)
  191. );
  192. bytesRemaining -= sizeof (STORAGE_DEVICE_DESCRIPTOR);
  193. if (bytesRemaining <= 0) {
  194. return STATUS_SUCCESS;
  195. }
  196. currentOffset += sizeof (STORAGE_DEVICE_DESCRIPTOR);
  197. //
  198. // If our inquiry buffer is empty, make up some strings...
  199. //
  200. if (deviceExtension->InquiryData.VendorId[0] == 0) {
  201. sprintf (inquiryData->VendorId, "Vendor");
  202. sprintf (inquiryData->ProductId, "Sbp2");
  203. sprintf (inquiryData->ProductRevisionLevel, "1.0");
  204. }
  205. //
  206. // First the vendor id + NULL
  207. //
  208. if (bytesRemaining <= sizeof (inquiryData->VendorId)) {
  209. return STATUS_SUCCESS;
  210. }
  211. RtlCopyMemory(
  212. currentOffset,
  213. inquiryData->VendorId,
  214. sizeof (inquiryData->VendorId)
  215. );
  216. Descriptor->VendorIdOffset = (ULONG)
  217. ((ULONG_PTR) currentOffset - (ULONG_PTR) Descriptor);
  218. bytesRemaining -= sizeof (inquiryData->VendorId) + sizeof (UCHAR);
  219. currentOffset += sizeof (inquiryData->VendorId) + sizeof (UCHAR);
  220. //
  221. // Now the product id + NULL
  222. //
  223. if (bytesRemaining <= sizeof (inquiryData->ProductId)) {
  224. return STATUS_SUCCESS;
  225. }
  226. RtlCopyMemory(
  227. currentOffset,
  228. inquiryData->ProductId,
  229. sizeof (inquiryData->ProductId)
  230. );
  231. Descriptor->ProductIdOffset = (ULONG)
  232. ((ULONG_PTR) currentOffset - (ULONG_PTR) Descriptor);
  233. bytesRemaining -= sizeof (inquiryData->ProductId) + sizeof (UCHAR);
  234. currentOffset += sizeof (inquiryData->ProductId) + sizeof (UCHAR);
  235. //
  236. // Now the product revision + NULL
  237. //
  238. if (bytesRemaining <= sizeof (inquiryData->ProductRevisionLevel)) {
  239. return STATUS_SUCCESS;
  240. }
  241. RtlCopyMemory(
  242. currentOffset,
  243. inquiryData->ProductRevisionLevel,
  244. sizeof (inquiryData->ProductRevisionLevel)
  245. );
  246. Descriptor->ProductRevisionOffset = (ULONG)
  247. ((ULONG_PTR) currentOffset - (ULONG_PTR) Descriptor);
  248. bytesRemaining -=
  249. sizeof (inquiryData->ProductRevisionLevel) + sizeof (UCHAR);
  250. currentOffset +=
  251. sizeof (inquiryData->ProductRevisionLevel) + sizeof (UCHAR);
  252. //
  253. // And finally the device serial number (use the UniqueId
  254. // converted from binary to string format) + NULL
  255. //
  256. if (bytesRemaining <= 16) {
  257. return STATUS_SUCCESS;
  258. }
  259. sprintf(
  260. currentOffset,
  261. "%08x%08x",
  262. deviceExtension->DeviceInfo->ConfigRom->CR_Node_UniqueID[0],
  263. deviceExtension->DeviceInfo->ConfigRom->CR_Node_UniqueID[1]
  264. );
  265. Descriptor->SerialNumberOffset = (ULONG)
  266. ((ULONG_PTR) currentOffset - (ULONG_PTR) Descriptor);
  267. *DescriptorLength = realLength;
  268. return STATUS_SUCCESS;
  269. }
  270. NTSTATUS
  271. Sbp2BuildAdapterDescriptor(
  272. IN PDEVICE_OBJECT DeviceObject,
  273. IN PSTORAGE_ADAPTER_DESCRIPTOR Descriptor,
  274. IN OUT PULONG DescriptorLength
  275. )
  276. {
  277. PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
  278. STORAGE_ADAPTER_DESCRIPTOR tmp;
  279. ULONG realLength;
  280. realLength = sizeof(STORAGE_ADAPTER_DESCRIPTOR);
  281. tmp.Version = sizeof(STORAGE_ADAPTER_DESCRIPTOR);
  282. tmp.Size = sizeof(STORAGE_ADAPTER_DESCRIPTOR);
  283. if (*DescriptorLength < realLength ) {
  284. RtlCopyMemory (Descriptor,&tmp,*DescriptorLength);
  285. return STATUS_SUCCESS;
  286. }
  287. tmp.MaximumTransferLength = deviceExtension->DeviceInfo->MaxClassTransferSize;
  288. tmp.MaximumPhysicalPages = tmp.MaximumTransferLength/PAGE_SIZE ;
  289. tmp.AlignmentMask = SBP2_ALIGNMENT_MASK;
  290. tmp.AdapterUsesPio = FALSE;
  291. tmp.AdapterScansDown = FALSE;
  292. tmp.CommandQueueing = TRUE;
  293. tmp.AcceleratedTransfer = TRUE;
  294. tmp.BusType = BusType1394;
  295. tmp.BusMajorVersion = 1;
  296. tmp.BusMinorVersion = 0;
  297. RtlCopyMemory(Descriptor,
  298. &tmp,
  299. sizeof(STORAGE_ADAPTER_DESCRIPTOR));
  300. *DescriptorLength = sizeof(STORAGE_ADAPTER_DESCRIPTOR);
  301. return STATUS_SUCCESS;
  302. }