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.

855 lines
25 KiB

  1. /*++
  2. Copyright (c) 1991-1998 Microsoft Corporation
  3. Module Name:
  4. pnp.c
  5. Abstract:
  6. Author:
  7. Neil Sandlin (neilsa) 26-Apr-99
  8. Environment:
  9. Kernel mode only.
  10. --*/
  11. #include "pch.h"
  12. //
  13. // Internal References
  14. //
  15. NTSTATUS
  16. SffDiskStartDevice(
  17. IN PDEVICE_OBJECT DeviceObject,
  18. IN PIRP Irp
  19. );
  20. NTSTATUS
  21. SffDiskGetResourceRequirements(
  22. IN PDEVICE_OBJECT DeviceObject,
  23. IN PIRP Irp
  24. );
  25. NTSTATUS
  26. SffDiskPnpComplete (
  27. IN PDEVICE_OBJECT DeviceObject,
  28. IN PIRP Irp,
  29. IN PVOID Context
  30. );
  31. NTSTATUS
  32. SffDiskGetRegistryParameters(
  33. IN PSFFDISK_EXTENSION sffdiskExtension
  34. );
  35. #ifdef ALLOC_PRAGMA
  36. #pragma alloc_text(PAGE,SffDiskAddDevice)
  37. #pragma alloc_text(PAGE,SffDiskPnp)
  38. #pragma alloc_text(PAGE,SffDiskStartDevice)
  39. #pragma alloc_text(PAGE,SffDiskGetResourceRequirements)
  40. #pragma alloc_text(PAGE,SffDiskGetRegistryParameters)
  41. #endif
  42. #define SFFDISK_DEVICE_NAME L"\\Device\\Sffdisk"
  43. #define SFFDISK_LINK_NAME L"\\DosDevices\\Sffdisk"
  44. #define SFFDISK_REGISTRY_NODRIVE_KEY L"NoDrive"
  45. NTSTATUS
  46. SffDiskAddDevice(
  47. IN PDRIVER_OBJECT DriverObject,
  48. IN OUT PDEVICE_OBJECT PhysicalDeviceObject
  49. )
  50. /*++
  51. Routine Description:
  52. This routine is the driver's pnp add device entry point. It is
  53. called by the pnp manager to initialize the driver.
  54. Add device creates and initializes a device object for this FDO and
  55. attaches to the underlying PDO.
  56. Arguments:
  57. DriverObject - a pointer to the object that represents this device driver.
  58. PhysicalDeviceObject - a pointer to the underlying PDO to which this new device will attach.
  59. Return Value:
  60. If we successfully create a device object, STATUS_SUCCESS is
  61. returned. Otherwise, return the appropriate error code.
  62. --*/
  63. {
  64. NTSTATUS status = STATUS_SUCCESS;
  65. PDEVICE_OBJECT deviceObject;
  66. PSFFDISK_EXTENSION sffdiskExtension;
  67. WCHAR NameBuffer[128];
  68. UNICODE_STRING deviceName;
  69. // UNICODE_STRING linkName;
  70. LONG deviceNumber = -1;
  71. ULONG resultLength;
  72. BOOLEAN functionInitialized = FALSE;
  73. SffDiskDump(SFFDISKSHOW, ("SffDisk: AddDevice...\n"));
  74. //
  75. // Create a device. We will use the first available device name for
  76. // this device.
  77. //
  78. do {
  79. swprintf(NameBuffer, L"%s%d", SFFDISK_DEVICE_NAME, ++deviceNumber);
  80. RtlInitUnicodeString(&deviceName, NameBuffer);
  81. status = IoCreateDevice(DriverObject,
  82. sizeof(SFFDISK_EXTENSION),
  83. &deviceName,
  84. FILE_DEVICE_DISK,
  85. FILE_DEVICE_SECURE_OPEN,
  86. FALSE,
  87. &deviceObject);
  88. } while (status == STATUS_OBJECT_NAME_COLLISION);
  89. if (!NT_SUCCESS(status)) {
  90. return status;
  91. }
  92. sffdiskExtension = (PSFFDISK_EXTENSION)deviceObject->DeviceExtension;
  93. RtlZeroMemory(sffdiskExtension, sizeof(SFFDISK_EXTENSION));
  94. sffdiskExtension->DeviceObject = deviceObject;
  95. //
  96. // Save the device name.
  97. //
  98. SffDiskDump(SFFDISKSHOW | SFFDISKPNP,
  99. ("SffDisk: AddDevice - Device Object Name - %S\n", NameBuffer));
  100. sffdiskExtension->DeviceName.Buffer = ExAllocatePool(PagedPool, deviceName.Length);
  101. if (sffdiskExtension->DeviceName.Buffer == NULL) {
  102. status = STATUS_INSUFFICIENT_RESOURCES;
  103. goto errorExit;
  104. }
  105. sffdiskExtension->DeviceName.Length = 0;
  106. sffdiskExtension->DeviceName.MaximumLength = deviceName.Length;
  107. RtlCopyUnicodeString(&sffdiskExtension->DeviceName, &deviceName);
  108. //
  109. // create the link name
  110. //
  111. #if 0
  112. swprintf(NameBuffer, L"%s%d", SFFDISK_LINK_NAME, deviceNumber);
  113. RtlInitUnicodeString(&linkName, NameBuffer);
  114. sffdiskExtension->LinkName.Buffer = ExAllocatePool(PagedPool, linkName.Length);
  115. if (sffdiskExtension->LinkName.Buffer == NULL) {
  116. status = STATUS_INSUFFICIENT_RESOURCES;
  117. goto errorExit;
  118. }
  119. sffdiskExtension->LinkName.Length = 0;
  120. sffdiskExtension->LinkName.MaximumLength = linkName.Length;
  121. RtlCopyUnicodeString(&sffdiskExtension->LinkName, &linkName);
  122. status = IoCreateSymbolicLink(&sffdiskExtension->LinkName, &sffdiskExtension->DeviceName);
  123. if (!NT_SUCCESS(status)) {
  124. goto errorExit;
  125. }
  126. #endif
  127. //
  128. // Set the PDO for use with PlugPlay functions
  129. //
  130. sffdiskExtension->UnderlyingPDO = PhysicalDeviceObject;
  131. SffDiskDump(SFFDISKSHOW, ("SffDisk: AddDevice attaching %p to %p\n", deviceObject, PhysicalDeviceObject));
  132. sffdiskExtension->TargetObject = IoAttachDeviceToDeviceStack(deviceObject, PhysicalDeviceObject);
  133. SffDiskDump(SFFDISKSHOW,
  134. ("SffDisk: AddDevice TargetObject = %p\n",
  135. sffdiskExtension->TargetObject));
  136. status = IoGetDeviceProperty(PhysicalDeviceObject,
  137. DevicePropertyLegacyBusType,
  138. sizeof(INTERFACE_TYPE),
  139. (PVOID)&sffdiskExtension->InterfaceType,
  140. &resultLength);
  141. if (!NT_SUCCESS(status)) {
  142. //
  143. // we should exit here after SdBus is fixed
  144. //
  145. sffdiskExtension->InterfaceType = InterfaceTypeUndefined;
  146. }
  147. switch(sffdiskExtension->InterfaceType) {
  148. case PCMCIABus:
  149. sffdiskExtension->FunctionBlock = &PcCardSupportFns;
  150. break;
  151. //NEED TO FIX SDBUS
  152. case InterfaceTypeUndefined:
  153. sffdiskExtension->FunctionBlock = &SdCardSupportFns;
  154. break;
  155. default:
  156. status = STATUS_UNSUCCESSFUL;
  157. goto errorExit;
  158. }
  159. //
  160. // Initialize the technology specific code
  161. //
  162. status = (*(sffdiskExtension->FunctionBlock->Initialize))(sffdiskExtension);
  163. if (!NT_SUCCESS(status)) {
  164. SffDiskDump(SFFDISKFAIL, ("SffDisk: AddDevice failed tech specific initialize %08x\n", status));
  165. goto errorExit;
  166. }
  167. functionInitialized = TRUE;
  168. //
  169. // Read in any flags specified in the INF
  170. //
  171. status = SffDiskGetRegistryParameters(sffdiskExtension);
  172. if (!NT_SUCCESS(status)) {
  173. SffDiskDump(SFFDISKFAIL, ("SffDisk: AddDevice failed getting registry params %08x\n", status));
  174. goto errorExit;
  175. }
  176. //
  177. // done
  178. //
  179. deviceObject->Flags |= DO_DIRECT_IO | DO_POWER_PAGABLE;
  180. deviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
  181. sffdiskExtension->IsStarted = FALSE;
  182. sffdiskExtension->IsRemoved = FALSE;
  183. return STATUS_SUCCESS;
  184. errorExit:
  185. if (sffdiskExtension->DeviceName.Buffer != NULL) {
  186. ExFreePool(sffdiskExtension->DeviceName.Buffer);
  187. }
  188. #if 0
  189. if (sffdiskExtension->LinkName.Buffer != NULL) {
  190. IoDeleteSymbolicLink(&sffdiskExtension->LinkName);
  191. ExFreePool(sffdiskExtension->LinkName.Buffer);
  192. }
  193. #endif
  194. if (sffdiskExtension->TargetObject) {
  195. IoDetachDevice(sffdiskExtension->TargetObject);
  196. }
  197. if (functionInitialized) {
  198. (*(sffdiskExtension->FunctionBlock->DeleteDevice))(sffdiskExtension);
  199. }
  200. IoDeleteDevice(deviceObject);
  201. return status;
  202. }
  203. NTSTATUS
  204. SffDiskPnp(
  205. IN PDEVICE_OBJECT DeviceObject,
  206. IN PIRP Irp
  207. )
  208. /*++
  209. Routine Description:
  210. Main PNP irp dispatch routine
  211. Arguments:
  212. DeviceObject - a pointer to the object that represents the device
  213. that I/O is to be done on.
  214. Irp - a pointer to the I/O Request Packet for this request.
  215. Return Value:
  216. status
  217. --*/
  218. {
  219. PIO_STACK_LOCATION irpSp;
  220. PSFFDISK_EXTENSION sffdiskExtension;
  221. NTSTATUS status = STATUS_SUCCESS;
  222. ULONG i;
  223. sffdiskExtension = DeviceObject->DeviceExtension;
  224. irpSp = IoGetCurrentIrpStackLocation(Irp);
  225. SffDiskDump(SFFDISKPNP, ("SffDisk: DO %.8x Irp %.8x PNP func %x\n",
  226. DeviceObject, Irp, irpSp->MinorFunction));
  227. if (sffdiskExtension->IsRemoved) {
  228. //
  229. // Since the device is stopped, but we don't hold IRPs,
  230. // this is a surprise removal. Just fail it.
  231. //
  232. Irp->IoStatus.Information = 0;
  233. Irp->IoStatus.Status = STATUS_DELETE_PENDING;
  234. IoCompleteRequest (Irp, IO_NO_INCREMENT);
  235. return STATUS_DELETE_PENDING;
  236. }
  237. switch (irpSp->MinorFunction) {
  238. case IRP_MN_START_DEVICE:
  239. status = SffDiskStartDevice(DeviceObject, Irp);
  240. break;
  241. case IRP_MN_QUERY_STOP_DEVICE:
  242. case IRP_MN_QUERY_REMOVE_DEVICE:
  243. if (irpSp->MinorFunction == IRP_MN_QUERY_STOP_DEVICE) {
  244. SffDiskDump(SFFDISKPNP,("SffDisk: IRP_MN_QUERY_STOP_DEVICE\n"));
  245. } else {
  246. SffDiskDump(SFFDISKPNP,("SffDisk: IRP_MN_QUERY_REMOVE_DEVICE\n"));
  247. }
  248. if (!sffdiskExtension->IsStarted) {
  249. //
  250. // If we aren't started, we'll just pass the irp down.
  251. //
  252. IoSkipCurrentIrpStackLocation (Irp);
  253. status = IoCallDriver(sffdiskExtension->TargetObject, Irp);
  254. return status;
  255. }
  256. Irp->IoStatus.Status = STATUS_SUCCESS;
  257. IoSkipCurrentIrpStackLocation(Irp);
  258. status = IoCallDriver(sffdiskExtension->TargetObject, Irp);
  259. break;
  260. case IRP_MN_CANCEL_STOP_DEVICE:
  261. case IRP_MN_CANCEL_REMOVE_DEVICE:
  262. if (irpSp->MinorFunction == IRP_MN_CANCEL_STOP_DEVICE) {
  263. SffDiskDump(SFFDISKPNP,("SffDisk: IRP_MN_CANCEL_STOP_DEVICE\n"));
  264. } else {
  265. SffDiskDump(SFFDISKPNP,("SffDisk: IRP_MN_CANCEL_REMOVE_DEVICE\n"));
  266. }
  267. if (!sffdiskExtension->IsStarted) {
  268. //
  269. // Nothing to do, just pass the irp down:
  270. // no need to start the device
  271. //
  272. IoSkipCurrentIrpStackLocation (Irp);
  273. status = IoCallDriver(sffdiskExtension->TargetObject, Irp);
  274. } else {
  275. KEVENT doneEvent;
  276. //
  277. // Set the status to STATUS_SUCCESS
  278. //
  279. Irp->IoStatus.Status = STATUS_SUCCESS;
  280. //
  281. // We need to wait for the lower drivers to do their job.
  282. //
  283. IoCopyCurrentIrpStackLocationToNext (Irp);
  284. //
  285. // Clear the event: it will be set in the completion
  286. // routine.
  287. //
  288. KeInitializeEvent(&doneEvent,
  289. SynchronizationEvent,
  290. FALSE);
  291. IoSetCompletionRoutine(Irp,
  292. SffDiskPnpComplete,
  293. &doneEvent,
  294. TRUE, TRUE, TRUE);
  295. status = IoCallDriver(sffdiskExtension->TargetObject, Irp);
  296. if (status == STATUS_PENDING) {
  297. KeWaitForSingleObject(&doneEvent,
  298. Executive,
  299. KernelMode,
  300. FALSE,
  301. NULL);
  302. status = Irp->IoStatus.Status;
  303. }
  304. //
  305. // We must now complete the IRP, since we stopped it in the
  306. // completetion routine with MORE_PROCESSING_REQUIRED.
  307. //
  308. Irp->IoStatus.Status = status;
  309. Irp->IoStatus.Information = 0;
  310. IoCompleteRequest (Irp, IO_NO_INCREMENT);
  311. }
  312. break;
  313. case IRP_MN_STOP_DEVICE:
  314. SffDiskDump(SFFDISKPNP,("SffDisk: IRP_MN_STOP_DEVICE\n"));
  315. if (sffdiskExtension->IsMemoryMapped) {
  316. MmUnmapIoSpace(sffdiskExtension->MemoryWindowBase, sffdiskExtension->MemoryWindowSize);
  317. sffdiskExtension->MemoryWindowBase = 0;
  318. sffdiskExtension->MemoryWindowSize = 0;
  319. sffdiskExtension->IsMemoryMapped = FALSE;
  320. }
  321. sffdiskExtension->IsStarted = FALSE;
  322. Irp->IoStatus.Status = STATUS_SUCCESS;
  323. IoSkipCurrentIrpStackLocation(Irp);
  324. status = IoCallDriver(sffdiskExtension->TargetObject, Irp);
  325. break;
  326. case IRP_MN_REMOVE_DEVICE:
  327. SffDiskDump(SFFDISKPNP,("SffDisk: IRP_MN_REMOVE_DEVICE\n"));
  328. //
  329. // We need to mark the fact that we don't hold requests first, since
  330. // we asserted earlier that we are holding requests only if
  331. // we're not removed.
  332. //
  333. sffdiskExtension->IsStarted = FALSE;
  334. sffdiskExtension->IsRemoved = TRUE;
  335. //
  336. // Forward this Irp to the underlying PDO
  337. //
  338. IoSkipCurrentIrpStackLocation(Irp);
  339. Irp->IoStatus.Status = STATUS_SUCCESS;
  340. status = IoCallDriver(sffdiskExtension->TargetObject, Irp);
  341. //
  342. // Send notification that we are going away.
  343. //
  344. if (sffdiskExtension->InterfaceString.Buffer != NULL) {
  345. IoSetDeviceInterfaceState(&sffdiskExtension->InterfaceString,
  346. FALSE);
  347. RtlFreeUnicodeString(&sffdiskExtension->InterfaceString);
  348. RtlInitUnicodeString(&sffdiskExtension->InterfaceString, NULL);
  349. }
  350. //
  351. // Remove our link
  352. //
  353. #if 0
  354. IoDeleteSymbolicLink(&sffdiskExtension->LinkName);
  355. RtlFreeUnicodeString(&sffdiskExtension->LinkName);
  356. RtlInitUnicodeString(&sffdiskExtension->LinkName, NULL);
  357. #endif
  358. RtlFreeUnicodeString(&sffdiskExtension->DeviceName);
  359. RtlInitUnicodeString(&sffdiskExtension->DeviceName, NULL);
  360. //
  361. // Detatch from the undelying device.
  362. //
  363. IoDetachDevice(sffdiskExtension->TargetObject);
  364. (*(sffdiskExtension->FunctionBlock->DeleteDevice))(sffdiskExtension);
  365. //
  366. // And delete the device.
  367. //
  368. IoDeleteDevice(DeviceObject);
  369. break;
  370. case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
  371. status = SffDiskGetResourceRequirements(DeviceObject, Irp);
  372. break;
  373. default:
  374. SffDiskDump(SFFDISKPNP, ("SffDiskPnp: Unsupported PNP Request %x - Irp: %p\n",irpSp->MinorFunction, Irp));
  375. IoSkipCurrentIrpStackLocation(Irp);
  376. status = IoCallDriver(sffdiskExtension->TargetObject, Irp);
  377. }
  378. return status;
  379. }
  380. NTSTATUS
  381. SffDiskStartDevice(
  382. IN PDEVICE_OBJECT DeviceObject,
  383. IN PIRP Irp
  384. )
  385. /*++
  386. Routine Description:
  387. Start device routine
  388. Arguments:
  389. DeviceObject - a pointer to the object that represents the device
  390. that I/O is to be done on.
  391. Irp - a pointer to the I/O Request Packet for this request.
  392. Return Value:
  393. status
  394. --*/
  395. {
  396. NTSTATUS status;
  397. NTSTATUS pnpStatus;
  398. KEVENT doneEvent;
  399. PCM_RESOURCE_LIST ResourceList;
  400. PCM_RESOURCE_LIST TranslatedResourceList;
  401. PCM_PARTIAL_RESOURCE_LIST partialResourceList, partialTranslatedList;
  402. PCM_PARTIAL_RESOURCE_DESCRIPTOR partialResourceDesc, partialTranslatedDesc;
  403. PCM_FULL_RESOURCE_DESCRIPTOR fullResourceDesc, fullTranslatedDesc;
  404. PSFFDISK_EXTENSION sffdiskExtension = (PSFFDISK_EXTENSION)DeviceObject->DeviceExtension;
  405. PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(Irp);
  406. SffDiskDump(SFFDISKPNP,("SffDisk: StartDevice\n"));
  407. SffDiskDump(SFFDISKSHOW, (" AllocatedResources = %08x\n",irpSp->Parameters.StartDevice.AllocatedResources));
  408. SffDiskDump(SFFDISKSHOW, (" AllocatedResourcesTranslated = %08x\n",irpSp->Parameters.StartDevice.AllocatedResourcesTranslated));
  409. //
  410. // First we must pass this Irp on to the PDO.
  411. //
  412. KeInitializeEvent(&doneEvent, NotificationEvent, FALSE);
  413. IoCopyCurrentIrpStackLocationToNext(Irp);
  414. IoSetCompletionRoutine(Irp,
  415. SffDiskPnpComplete,
  416. &doneEvent,
  417. TRUE, TRUE, TRUE);
  418. status = IoCallDriver(sffdiskExtension->TargetObject, Irp);
  419. if (status == STATUS_PENDING) {
  420. status = KeWaitForSingleObject(&doneEvent,
  421. Executive,
  422. KernelMode,
  423. FALSE,
  424. NULL);
  425. ASSERT(status == STATUS_SUCCESS);
  426. status = Irp->IoStatus.Status;
  427. }
  428. if (!NT_SUCCESS(status)) {
  429. Irp->IoStatus.Status = status;
  430. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  431. return status;
  432. }
  433. //
  434. // Parse the resources to map the memory window
  435. //
  436. ResourceList = irpSp->Parameters.StartDevice.AllocatedResources;
  437. if (ResourceList) {
  438. TranslatedResourceList = irpSp->Parameters.StartDevice.AllocatedResourcesTranslated;
  439. fullResourceDesc = &ResourceList->List[0];
  440. fullTranslatedDesc = &TranslatedResourceList->List[0];
  441. partialResourceList = &fullResourceDesc->PartialResourceList;
  442. partialTranslatedList = &fullTranslatedDesc->PartialResourceList;
  443. partialResourceDesc = partialResourceList->PartialDescriptors;
  444. partialTranslatedDesc = partialTranslatedList->PartialDescriptors;
  445. if (partialResourceDesc->Type != CmResourceTypeMemory) {
  446. ASSERT(partialResourceDesc->Type == CmResourceTypeMemory);
  447. Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
  448. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  449. return STATUS_INVALID_PARAMETER;
  450. }
  451. sffdiskExtension->HostBase = partialTranslatedDesc->u.Memory.Start.QuadPart;
  452. sffdiskExtension->MemoryWindowSize = partialTranslatedDesc->u.Memory.Length;
  453. //
  454. //
  455. sffdiskExtension->MemoryWindowBase = MmMapIoSpace(partialTranslatedDesc->u.Memory.Start,
  456. partialTranslatedDesc->u.Memory.Length,
  457. FALSE);
  458. sffdiskExtension->IsMemoryMapped = TRUE;
  459. }
  460. //
  461. // Try to get the capacity of the card
  462. //
  463. status = (*(sffdiskExtension->FunctionBlock->GetDiskParameters))(sffdiskExtension);
  464. //
  465. // If we can't get the capacity, the must be broken in some way
  466. //
  467. if (!NT_SUCCESS(status)) {
  468. Irp->IoStatus.Status = status;
  469. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  470. return status;
  471. }
  472. if (!sffdiskExtension->NoDrive) {
  473. pnpStatus = IoRegisterDeviceInterface(sffdiskExtension->UnderlyingPDO,
  474. (LPGUID)&MOUNTDEV_MOUNTED_DEVICE_GUID,
  475. NULL,
  476. &sffdiskExtension->InterfaceString);
  477. if ( NT_SUCCESS(pnpStatus) ) {
  478. pnpStatus = IoSetDeviceInterfaceState(&sffdiskExtension->InterfaceString,
  479. TRUE);
  480. }
  481. }
  482. sffdiskExtension->IsStarted = TRUE;
  483. Irp->IoStatus.Status = status;
  484. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  485. return status;
  486. }
  487. NTSTATUS
  488. SffDiskPnpComplete (
  489. IN PDEVICE_OBJECT DeviceObject,
  490. IN PIRP Irp,
  491. IN PVOID Context
  492. )
  493. /*++
  494. Routine Description:
  495. A completion routine for use when calling the lower device objects to
  496. which our bus (FDO) is attached.
  497. --*/
  498. {
  499. KeSetEvent ((PKEVENT) Context, 1, FALSE);
  500. // No special priority
  501. // No Wait
  502. return STATUS_MORE_PROCESSING_REQUIRED; // Keep this IRP
  503. }
  504. NTSTATUS
  505. SffDiskGetResourceRequirements(
  506. IN PDEVICE_OBJECT DeviceObject,
  507. IN PIRP Irp
  508. )
  509. /*++
  510. Routine Description:
  511. Provides a memory resource requirement in case the bus driver
  512. doesn't.
  513. Arguments:
  514. DeviceObject - a pointer to the object that represents the device
  515. that I/O is to be done on.
  516. Irp - a pointer to the I/O Request Packet for this request.
  517. Return Value:
  518. status
  519. --*/
  520. {
  521. NTSTATUS status;
  522. KEVENT doneEvent;
  523. PIO_RESOURCE_REQUIREMENTS_LIST ioResourceRequirementsList;
  524. PIO_RESOURCE_LIST ioResourceList;
  525. PIO_RESOURCE_DESCRIPTOR ioResourceDesc;
  526. PSFFDISK_EXTENSION sffdiskExtension = (PSFFDISK_EXTENSION)DeviceObject->DeviceExtension;
  527. PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(Irp);
  528. ULONG listSize;
  529. if (sffdiskExtension->InterfaceType != PCMCIABus) {
  530. //
  531. // Only create a memory window for Pcmcia
  532. //
  533. return STATUS_SUCCESS;
  534. }
  535. //
  536. // First we must pass this Irp on to the PDO.
  537. //
  538. KeInitializeEvent(&doneEvent, NotificationEvent, FALSE);
  539. IoCopyCurrentIrpStackLocationToNext(Irp);
  540. IoSetCompletionRoutine(Irp,
  541. SffDiskPnpComplete,
  542. &doneEvent,
  543. TRUE, TRUE, TRUE);
  544. status = IoCallDriver(sffdiskExtension->TargetObject, Irp);
  545. if (status == STATUS_PENDING) {
  546. status = KeWaitForSingleObject(&doneEvent,
  547. Executive,
  548. KernelMode,
  549. FALSE,
  550. NULL);
  551. ASSERT(status == STATUS_SUCCESS);
  552. status = Irp->IoStatus.Status;
  553. }
  554. if (NT_SUCCESS(status) && (Irp->IoStatus.Information == 0)) {
  555. listSize = sizeof(IO_RESOURCE_REQUIREMENTS_LIST);
  556. ioResourceRequirementsList = (PIO_RESOURCE_REQUIREMENTS_LIST) ExAllocatePool(PagedPool, listSize);
  557. RtlZeroMemory(ioResourceRequirementsList, listSize);
  558. ioResourceRequirementsList->ListSize = listSize;
  559. ioResourceRequirementsList->AlternativeLists = 1;
  560. //
  561. // NOTE: not quite sure if the following values are the best choices
  562. //
  563. ioResourceRequirementsList->InterfaceType = Isa;
  564. ioResourceRequirementsList->BusNumber = 0;
  565. ioResourceRequirementsList->SlotNumber = 0;
  566. ioResourceList = &ioResourceRequirementsList->List[0];
  567. ioResourceList->Version = 1;
  568. ioResourceList->Revision = 1;
  569. ioResourceList->Count = 1;
  570. ioResourceDesc = &ioResourceList->Descriptors[0];
  571. ioResourceDesc->Option = 0;
  572. ioResourceDesc->Type = CmResourceTypeMemory;
  573. ioResourceDesc->Flags = CM_RESOURCE_MEMORY_READ_WRITE;
  574. ioResourceDesc->ShareDisposition = CmResourceShareDeviceExclusive;
  575. ioResourceDesc->u.Memory.MinimumAddress.QuadPart = 0;
  576. ioResourceDesc->u.Memory.MaximumAddress.QuadPart = (ULONGLONG)-1;
  577. ioResourceDesc->u.Memory.Length = 0x2000;
  578. ioResourceDesc->u.Memory.Alignment = 0x2000;
  579. Irp->IoStatus.Information = (ULONG_PTR)ioResourceRequirementsList;
  580. }
  581. Irp->IoStatus.Status = status;
  582. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  583. return status;
  584. }
  585. NTSTATUS
  586. SffDiskGetRegistryParameters(
  587. IN PSFFDISK_EXTENSION sffdiskExtension
  588. )
  589. /*++
  590. Routine Description:
  591. Loads device specific parameters from the registry
  592. Arguments:
  593. sffdiskExtension - device extension of the device
  594. Return Value:
  595. status
  596. --*/
  597. {
  598. NTSTATUS status;
  599. HANDLE instanceHandle;
  600. UNICODE_STRING KeyName;
  601. UCHAR buffer[sizeof(KEY_VALUE_PARTIAL_INFORMATION) + 32*sizeof(UCHAR)];
  602. PKEY_VALUE_PARTIAL_INFORMATION value = (PKEY_VALUE_PARTIAL_INFORMATION) buffer;
  603. ULONG length;
  604. if (!sffdiskExtension->UnderlyingPDO) {
  605. return STATUS_UNSUCCESSFUL;
  606. }
  607. status = IoOpenDeviceRegistryKey(sffdiskExtension->UnderlyingPDO,
  608. PLUGPLAY_REGKEY_DRIVER,
  609. KEY_READ,
  610. &instanceHandle
  611. );
  612. if (!NT_SUCCESS(status)) {
  613. return(status);
  614. }
  615. //
  616. // Read in the "NoDrive" parameter
  617. //
  618. RtlInitUnicodeString(&KeyName, SFFDISK_REGISTRY_NODRIVE_KEY);
  619. status = ZwQueryValueKey(instanceHandle,
  620. &KeyName,
  621. KeyValuePartialInformation,
  622. value,
  623. sizeof(buffer),
  624. &length);
  625. if (NT_SUCCESS(status)) {
  626. sffdiskExtension->NoDrive = (BOOLEAN) (*(PULONG)(value->Data) != 0);
  627. }
  628. ZwClose(instanceHandle);
  629. return STATUS_SUCCESS;
  630. }