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.

866 lines
22 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. ntdisp.c
  5. Abstract:
  6. NT Entry points and dispatch routines for NDISUIO.
  7. Environment:
  8. Kernel mode only.
  9. Revision History:
  10. arvindm 4/6/2000 Created
  11. --*/
  12. #include "precomp.h"
  13. #define __FILENUMBER 'PSID'
  14. #ifdef ALLOC_PRAGMA
  15. #pragma alloc_text(INIT, DriverEntry)
  16. #pragma alloc_text(PAGE, NdisuioUnload)
  17. #pragma alloc_text(PAGE, NdisuioOpen)
  18. #pragma alloc_text(PAGE, NdisuioClose)
  19. #pragma alloc_text(PAGE, NdisuioIoControl)
  20. #endif // ALLOC_PRAGMA
  21. //
  22. // Globals:
  23. //
  24. NDISUIO_GLOBALS Globals = {0};
  25. NTSTATUS
  26. DriverEntry(
  27. IN PDRIVER_OBJECT pDriverObject,
  28. IN PUNICODE_STRING pRegistryPath
  29. )
  30. /*++
  31. Routine Description:
  32. Called on loading. We create a device object to handle user-mode requests
  33. on, and register ourselves as a protocol with NDIS.
  34. Arguments:
  35. pDriverObject - Pointer to driver object created by system.
  36. pRegistryPath - Pointer to the Unicode name of the registry path
  37. for this driver.
  38. Return Value:
  39. NT Status code
  40. --*/
  41. {
  42. NDIS_PROTOCOL_CHARACTERISTICS protocolChar;
  43. NTSTATUS status = STATUS_SUCCESS;
  44. NDIS_STRING protoName = NDIS_STRING_CONST("NDISUIO");
  45. UNICODE_STRING ntDeviceName;
  46. UNICODE_STRING win32DeviceName;
  47. BOOLEAN fSymbolicLink = FALSE;
  48. PDEVICE_OBJECT deviceObject;
  49. DEBUGP(DL_LOUD, ("DriverEntry\n"));
  50. Globals.pDriverObject = pDriverObject;
  51. Globals.EthType = NUIO_ETH_TYPE;
  52. NUIO_INIT_EVENT(&Globals.BindsComplete);
  53. do
  54. {
  55. //
  56. // Create our device object using which an application can
  57. // access NDIS devices.
  58. //
  59. RtlInitUnicodeString(&ntDeviceName, NT_DEVICE_NAME);
  60. status = IoCreateDevice (pDriverObject,
  61. 0,
  62. &ntDeviceName,
  63. FILE_DEVICE_NETWORK,
  64. FILE_DEVICE_SECURE_OPEN,
  65. FALSE,
  66. &deviceObject);
  67. if (!NT_SUCCESS (status))
  68. {
  69. //
  70. // Either not enough memory to create a deviceobject or another
  71. // deviceobject with the same name exits. This could happen
  72. // if you install another instance of this device.
  73. //
  74. break;
  75. }
  76. RtlInitUnicodeString(&win32DeviceName, DOS_DEVICE_NAME);
  77. status = IoCreateSymbolicLink(&win32DeviceName, &ntDeviceName);
  78. if (!NT_SUCCESS(status))
  79. {
  80. break;
  81. }
  82. fSymbolicLink = TRUE;
  83. deviceObject->Flags |= DO_DIRECT_IO;
  84. Globals.ControlDeviceObject = deviceObject;
  85. NUIO_INIT_LIST_HEAD(&Globals.OpenList);
  86. NUIO_INIT_LOCK(&Globals.GlobalLock);
  87. //
  88. // Initialize the protocol characterstic structure
  89. //
  90. NdisZeroMemory(&protocolChar,sizeof(NDIS_PROTOCOL_CHARACTERISTICS));
  91. protocolChar.MajorNdisVersion = 5;
  92. protocolChar.MinorNdisVersion = 0;
  93. protocolChar.Name = protoName;
  94. protocolChar.OpenAdapterCompleteHandler = NdisuioOpenAdapterComplete;
  95. protocolChar.CloseAdapterCompleteHandler = NdisuioCloseAdapterComplete;
  96. protocolChar.SendCompleteHandler = NdisuioSendComplete;
  97. protocolChar.TransferDataCompleteHandler = NdisuioTransferDataComplete;
  98. protocolChar.ResetCompleteHandler = NdisuioResetComplete;
  99. protocolChar.RequestCompleteHandler = NdisuioRequestComplete;
  100. protocolChar.ReceiveHandler = NdisuioReceive;
  101. protocolChar.ReceiveCompleteHandler = NdisuioReceiveComplete;
  102. protocolChar.StatusHandler = NdisuioStatus;
  103. protocolChar.StatusCompleteHandler = NdisuioStatusComplete;
  104. protocolChar.BindAdapterHandler = NdisuioBindAdapter;
  105. protocolChar.UnbindAdapterHandler = NdisuioUnbindAdapter;
  106. protocolChar.UnloadHandler = NULL;
  107. protocolChar.ReceivePacketHandler = NdisuioReceivePacket;
  108. protocolChar.PnPEventHandler = NdisuioPnPEventHandler;
  109. //
  110. // Register as a protocol driver
  111. //
  112. NdisRegisterProtocol(
  113. &status,
  114. &Globals.NdisProtocolHandle,
  115. &protocolChar,
  116. sizeof(NDIS_PROTOCOL_CHARACTERISTICS));
  117. if (status != NDIS_STATUS_SUCCESS)
  118. {
  119. DEBUGP(DL_WARN, ("Failed to register protocol with NDIS\n"));
  120. status = STATUS_UNSUCCESSFUL;
  121. break;
  122. }
  123. #ifdef NDIS51
  124. Globals.PartialCancelId = NdisGeneratePartialCancelId();
  125. Globals.PartialCancelId <<= ((sizeof(PVOID) - 1) * 8);
  126. DEBUGP(DL_LOUD, ("DriverEntry: CancelId %lx\n", Globals.PartialCancelId));
  127. #endif
  128. //
  129. // Now set only the dispatch points we would like to handle.
  130. //
  131. pDriverObject->MajorFunction[IRP_MJ_CREATE] = NdisuioOpen;
  132. pDriverObject->MajorFunction[IRP_MJ_CLOSE] = NdisuioClose;
  133. pDriverObject->MajorFunction[IRP_MJ_READ] = NdisuioRead;
  134. pDriverObject->MajorFunction[IRP_MJ_WRITE] = NdisuioWrite;
  135. pDriverObject->MajorFunction[IRP_MJ_CLEANUP] = NdisuioCleanup;
  136. pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = NdisuioIoControl;
  137. pDriverObject->DriverUnload = NdisuioUnload;
  138. status = STATUS_SUCCESS;
  139. break;
  140. }
  141. while (FALSE);
  142. if (!NT_SUCCESS(status))
  143. {
  144. if (deviceObject)
  145. {
  146. IoDeleteDevice(deviceObject);
  147. Globals.ControlDeviceObject = NULL;
  148. }
  149. if (fSymbolicLink)
  150. {
  151. IoDeleteSymbolicLink(&win32DeviceName);
  152. }
  153. }
  154. return status;
  155. }
  156. VOID
  157. NdisuioUnload(
  158. IN PDRIVER_OBJECT DriverObject
  159. )
  160. /*++
  161. Routine Description:
  162. Free all the allocated resources, etc.
  163. Arguments:
  164. DriverObject - pointer to a driver object.
  165. Return Value:
  166. VOID.
  167. --*/
  168. {
  169. NDIS_STATUS status;
  170. UNICODE_STRING win32DeviceName;
  171. DEBUGP(DL_LOUD, ("Unload Enter\n"));
  172. //
  173. // First delete the Control deviceobject and the corresponding
  174. // symbolicLink
  175. //
  176. RtlInitUnicodeString(&win32DeviceName, DOS_DEVICE_NAME);
  177. IoDeleteSymbolicLink(&win32DeviceName);
  178. if (Globals.ControlDeviceObject)
  179. {
  180. IoDeleteDevice(Globals.ControlDeviceObject);
  181. Globals.ControlDeviceObject = NULL;
  182. }
  183. ndisuioDoProtocolUnload();
  184. #if DBG
  185. ndisuioAuditShutdown();
  186. #endif
  187. DEBUGP(DL_LOUD, ("Unload Exit\n"));
  188. }
  189. NTSTATUS
  190. NdisuioOpen(
  191. IN PDEVICE_OBJECT pDeviceObject,
  192. IN PIRP pIrp
  193. )
  194. /*++
  195. Routine Description:
  196. This is the dispatch routine for handling IRP_MJ_CREATE.
  197. We simply succeed this.
  198. Arguments:
  199. pDeviceObject - Pointer to the device object.
  200. pIrp - Pointer to the request packet.
  201. Return Value:
  202. Status is returned.
  203. --*/
  204. {
  205. PIO_STACK_LOCATION pIrpSp;
  206. NTSTATUS NtStatus = STATUS_SUCCESS;
  207. pIrpSp = IoGetCurrentIrpStackLocation(pIrp);
  208. pIrpSp->FileObject->FsContext = NULL;
  209. DEBUGP(DL_INFO, ("Open: FileObject %p\n", pIrpSp->FileObject));
  210. pIrp->IoStatus.Information = 0;
  211. pIrp->IoStatus.Status = NtStatus;
  212. IoCompleteRequest(pIrp, IO_NO_INCREMENT);
  213. return NtStatus;
  214. }
  215. NTSTATUS
  216. NdisuioClose(
  217. IN PDEVICE_OBJECT pDeviceObject,
  218. IN PIRP pIrp
  219. )
  220. /*++
  221. Routine Description:
  222. This is the dispatch routine for handling IRP_MJ_CLOSE.
  223. We simply succeed this.
  224. Arguments:
  225. pDeviceObject - Pointer to the device object.
  226. pIrp - Pointer to the request packet.
  227. Return Value:
  228. Status is returned.
  229. --*/
  230. {
  231. NTSTATUS NtStatus;
  232. PIO_STACK_LOCATION pIrpSp;
  233. PNDISUIO_OPEN_CONTEXT pOpenContext;
  234. pIrpSp = IoGetCurrentIrpStackLocation(pIrp);
  235. pOpenContext = pIrpSp->FileObject->FsContext;
  236. DEBUGP(DL_INFO, ("Close: FileObject %p\n",
  237. IoGetCurrentIrpStackLocation(pIrp)->FileObject));
  238. if (pOpenContext != NULL)
  239. {
  240. NUIO_STRUCT_ASSERT(pOpenContext, oc);
  241. //
  242. // Deref the endpoint
  243. //
  244. NUIO_DEREF_OPEN(pOpenContext); // Close
  245. }
  246. pIrpSp->FileObject->FsContext = NULL;
  247. NtStatus = STATUS_SUCCESS;
  248. pIrp->IoStatus.Information = 0;
  249. pIrp->IoStatus.Status = NtStatus;
  250. IoCompleteRequest(pIrp, IO_NO_INCREMENT);
  251. return NtStatus;
  252. }
  253. NTSTATUS
  254. NdisuioCleanup(
  255. IN PDEVICE_OBJECT pDeviceObject,
  256. IN PIRP pIrp
  257. )
  258. /*++
  259. Routine Description:
  260. This is the dispatch routine for handling IRP_MJ_CLEANUP.
  261. Arguments:
  262. pDeviceObject - Pointer to the device object.
  263. pIrp - Pointer to the request packet.
  264. Return Value:
  265. Status is returned.
  266. --*/
  267. {
  268. PIO_STACK_LOCATION pIrpSp;
  269. ULONG FunctionCode;
  270. NTSTATUS NtStatus;
  271. NDIS_STATUS NdisStatus;
  272. PNDISUIO_OPEN_CONTEXT pOpenContext;
  273. ULONG PacketFilter;
  274. ULONG BytesProcessed;
  275. BOOLEAN bSetFilter;
  276. pIrpSp = IoGetCurrentIrpStackLocation(pIrp);
  277. pOpenContext = pIrpSp->FileObject->FsContext;
  278. DEBUGP(DL_VERY_LOUD, ("Cleanup: FileObject %p, Open %p\n",
  279. pIrpSp->FileObject, pOpenContext));
  280. if (pOpenContext != NULL)
  281. {
  282. NUIO_STRUCT_ASSERT(pOpenContext, oc);
  283. //
  284. // Mark this endpoint.
  285. //
  286. NUIO_ACQUIRE_LOCK(&pOpenContext->Lock);
  287. NUIO_SET_FLAGS(pOpenContext->Flags, NUIOO_OPEN_FLAGS, NUIOO_OPEN_IDLE);
  288. pOpenContext->pFileObject = NULL;
  289. NUIO_RELEASE_LOCK(&pOpenContext->Lock);
  290. //
  291. // Set the packet filter to 0, telling NDIS that we aren't
  292. // interested in any more receives.
  293. //
  294. PacketFilter = 0;
  295. NdisStatus = ndisuioValidateOpenAndDoRequest(
  296. pOpenContext,
  297. NdisRequestSetInformation,
  298. OID_GEN_CURRENT_PACKET_FILTER,
  299. &PacketFilter,
  300. sizeof(PacketFilter),
  301. &BytesProcessed,
  302. FALSE // Don't wait for device to be powered on
  303. );
  304. if (NdisStatus != NDIS_STATUS_SUCCESS)
  305. {
  306. DEBUGP(DL_INFO, ("Cleanup: Open %p, set packet filter (%x) failed: %x\n",
  307. pOpenContext, PacketFilter, NdisStatus));
  308. //
  309. // Ignore the result. If this failed, we may continue
  310. // to get indicated receives, which will be handled
  311. // appropriately.
  312. //
  313. NdisStatus = NDIS_STATUS_SUCCESS;
  314. }
  315. //
  316. // Cancel any pending reads.
  317. //
  318. ndisuioCancelPendingReads(pOpenContext);
  319. }
  320. NtStatus = STATUS_SUCCESS;
  321. pIrp->IoStatus.Information = 0;
  322. pIrp->IoStatus.Status = NtStatus;
  323. IoCompleteRequest(pIrp, IO_NO_INCREMENT);
  324. DEBUGP(DL_INFO, ("Cleanup: OpenContext %p\n", pOpenContext));
  325. return (NtStatus);
  326. }
  327. NTSTATUS
  328. NdisuioIoControl(
  329. IN PDEVICE_OBJECT pDeviceObject,
  330. IN PIRP pIrp
  331. )
  332. /*++
  333. Routine Description:
  334. This is the dispatch routine for handling device ioctl requests.
  335. Arguments:
  336. pDeviceObject - Pointer to the device object.
  337. pIrp - Pointer to the request packet.
  338. Return Value:
  339. Status is returned.
  340. --*/
  341. {
  342. PIO_STACK_LOCATION pIrpSp;
  343. ULONG FunctionCode;
  344. NTSTATUS NtStatus;
  345. NDIS_STATUS Status;
  346. PNDISUIO_OPEN_CONTEXT pOpenContext;
  347. ULONG BytesReturned;
  348. USHORT EthType;
  349. DEBUGP(DL_LOUD, ("IoControl: DevObj %p, Irp %p\n", pDeviceObject, pIrp));
  350. pIrpSp = IoGetCurrentIrpStackLocation(pIrp);
  351. FunctionCode = pIrpSp->Parameters.DeviceIoControl.IoControlCode;
  352. pOpenContext = (PNDISUIO_OPEN_CONTEXT)pIrpSp->FileObject->FsContext;
  353. BytesReturned = 0;
  354. switch (FunctionCode)
  355. {
  356. case IOCTL_NDISUIO_BIND_WAIT:
  357. //
  358. // Block until we have seen a NetEventBindsComplete event,
  359. // meaning that we have finished binding to all running
  360. // adapters that we are supposed to bind to.
  361. //
  362. // If we don't get this event in 5 seconds, time out.
  363. //
  364. if (NUIO_WAIT_EVENT(&Globals.BindsComplete, 5000))
  365. {
  366. NtStatus = STATUS_SUCCESS;
  367. }
  368. else
  369. {
  370. NtStatus = STATUS_TIMEOUT;
  371. }
  372. DEBUGP(DL_INFO, ("IoControl: BindWait returning %x\n", NtStatus));
  373. break;
  374. case IOCTL_NDISUIO_QUERY_BINDING:
  375. Status = ndisuioQueryBinding(
  376. pIrp->AssociatedIrp.SystemBuffer,
  377. pIrpSp->Parameters.DeviceIoControl.InputBufferLength,
  378. pIrpSp->Parameters.DeviceIoControl.OutputBufferLength,
  379. &BytesReturned
  380. );
  381. NDIS_STATUS_TO_NT_STATUS(Status, &NtStatus);
  382. DEBUGP(DL_LOUD, ("IoControl: QueryBinding returning %x\n", NtStatus));
  383. break;
  384. case IOCTL_NDISUIO_OPEN_DEVICE:
  385. if (pOpenContext != NULL)
  386. {
  387. NUIO_STRUCT_ASSERT(pOpenContext, oc);
  388. DEBUGP(DL_WARN, ("IoControl: OPEN_DEVICE: FileObj %p already"
  389. " associated with open %p\n", pIrpSp->FileObject, pOpenContext));
  390. NtStatus = STATUS_DEVICE_BUSY;
  391. break;
  392. }
  393. NtStatus = ndisuioOpenDevice(
  394. pIrp->AssociatedIrp.SystemBuffer,
  395. pIrpSp->Parameters.DeviceIoControl.InputBufferLength,
  396. pIrpSp->FileObject,
  397. &pOpenContext
  398. );
  399. if (NT_SUCCESS(NtStatus))
  400. {
  401. pIrpSp->FileObject->FsContext = (PVOID)pOpenContext;
  402. DEBUGP(DL_VERY_LOUD, ("IoControl OPEN_DEVICE: Open %p <-> FileObject %p\n",
  403. pOpenContext, pIrpSp->FileObject));
  404. }
  405. break;
  406. case IOCTL_NDISUIO_QUERY_OID_VALUE:
  407. if (pOpenContext != NULL)
  408. {
  409. Status = ndisuioQueryOidValue(
  410. pOpenContext,
  411. pIrp->AssociatedIrp.SystemBuffer,
  412. pIrpSp->Parameters.DeviceIoControl.OutputBufferLength,
  413. &BytesReturned
  414. );
  415. NDIS_STATUS_TO_NT_STATUS(Status, &NtStatus);
  416. }
  417. else
  418. {
  419. NtStatus = STATUS_DEVICE_NOT_CONNECTED;
  420. }
  421. break;
  422. case IOCTL_NDISUIO_SET_OID_VALUE:
  423. if (pOpenContext != NULL)
  424. {
  425. Status = ndisuioSetOidValue(
  426. pOpenContext,
  427. pIrp->AssociatedIrp.SystemBuffer,
  428. pIrpSp->Parameters.DeviceIoControl.InputBufferLength
  429. );
  430. BytesReturned = 0;
  431. NDIS_STATUS_TO_NT_STATUS(Status, &NtStatus);
  432. }
  433. else
  434. {
  435. NtStatus = STATUS_DEVICE_NOT_CONNECTED;
  436. }
  437. break;
  438. case IOCTL_NDISUIO_SET_ETHER_TYPE:
  439. if (pIrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(Globals.EthType))
  440. {
  441. NtStatus = STATUS_BUFFER_TOO_SMALL;
  442. }
  443. else
  444. {
  445. //
  446. // We only allow this value to be set to certain types.
  447. //
  448. EthType = *(USHORT *)pIrp->AssociatedIrp.SystemBuffer;
  449. if (EthType != NUIO_ETH_TYPE)
  450. {
  451. DEBUGP(DL_WARN, ("IoControl: failed setting EthType to %x\n",
  452. EthType));
  453. NtStatus = STATUS_INVALID_PARAMETER;
  454. break;
  455. }
  456. Globals.EthType = EthType;
  457. DEBUGP(DL_INFO, ("IoControl: new Ether Type %x\n", Globals.EthType));
  458. NtStatus = STATUS_SUCCESS;
  459. }
  460. break;
  461. default:
  462. NtStatus = STATUS_NOT_SUPPORTED;
  463. break;
  464. }
  465. if (NtStatus != STATUS_PENDING)
  466. {
  467. pIrp->IoStatus.Information = BytesReturned;
  468. pIrp->IoStatus.Status = NtStatus;
  469. IoCompleteRequest(pIrp, IO_NO_INCREMENT);
  470. }
  471. return NtStatus;
  472. }
  473. NTSTATUS
  474. ndisuioOpenDevice(
  475. IN PUCHAR pDeviceName,
  476. IN ULONG DeviceNameLength,
  477. IN PFILE_OBJECT pFileObject,
  478. OUT PNDISUIO_OPEN_CONTEXT * ppOpenContext
  479. )
  480. /*++
  481. Routine Description:
  482. Helper routine called to process IOCTL_NDISUIO_OPEN_DEVICE. Check if
  483. there is a binding to the specified device, and is not associated with
  484. a file object already. If so, make an association between the binding
  485. and this file object.
  486. Arguments:
  487. pDeviceName - pointer to device name string
  488. DeviceNameLength - length of above
  489. pFileObject - pointer to file object being associated with the device binding
  490. Return Value:
  491. Status is returned.
  492. --*/
  493. {
  494. PNDISUIO_OPEN_CONTEXT pOpenContext;
  495. NTSTATUS NtStatus;
  496. ULONG PacketFilter;
  497. NDIS_STATUS NdisStatus;
  498. ULONG BytesProcessed;
  499. pOpenContext = NULL;
  500. do
  501. {
  502. pOpenContext = ndisuioLookupDevice(
  503. pDeviceName,
  504. DeviceNameLength
  505. );
  506. if (pOpenContext == NULL)
  507. {
  508. DEBUGP(DL_WARN, ("ndisuioOpenDevice: couldn't find device\n"));
  509. NtStatus = STATUS_OBJECT_NAME_NOT_FOUND;
  510. break;
  511. }
  512. //
  513. // else ndisuioLookupDevice would have addref'ed the open.
  514. //
  515. NUIO_ACQUIRE_LOCK(&pOpenContext->Lock);
  516. if (!NUIO_TEST_FLAGS(pOpenContext->Flags, NUIOO_OPEN_FLAGS, NUIOO_OPEN_IDLE))
  517. {
  518. NUIO_ASSERT(pOpenContext->pFileObject != NULL);
  519. DEBUGP(DL_WARN, ("ndisuioOpenDevice: Open %p/%x already associated"
  520. " with another FileObject %p\n",
  521. pOpenContext, pOpenContext->Flags, pOpenContext->pFileObject));
  522. NUIO_RELEASE_LOCK(&pOpenContext->Lock);
  523. NUIO_DEREF_OPEN(pOpenContext); // ndisuioOpenDevice failure
  524. NtStatus = STATUS_DEVICE_BUSY;
  525. break;
  526. }
  527. pOpenContext->pFileObject = pFileObject;
  528. NUIO_SET_FLAGS(pOpenContext->Flags, NUIOO_OPEN_FLAGS, NUIOO_OPEN_ACTIVE);
  529. NUIO_RELEASE_LOCK(&pOpenContext->Lock);
  530. //
  531. // Set the packet filter now.
  532. //
  533. PacketFilter = NUIOO_PACKET_FILTER;
  534. NdisStatus = ndisuioValidateOpenAndDoRequest(
  535. pOpenContext,
  536. NdisRequestSetInformation,
  537. OID_GEN_CURRENT_PACKET_FILTER,
  538. &PacketFilter,
  539. sizeof(PacketFilter),
  540. &BytesProcessed,
  541. TRUE // Do wait for power on
  542. );
  543. if (NdisStatus != NDIS_STATUS_SUCCESS)
  544. {
  545. DEBUGP(DL_WARN, ("openDevice: Open %p: set packet filter (%x) failed: %x\n",
  546. pOpenContext, PacketFilter, NdisStatus));
  547. //
  548. // Undo all that we did above.
  549. //
  550. NUIO_ACQUIRE_LOCK(&pOpenContext->Lock);
  551. NUIO_SET_FLAGS(pOpenContext->Flags, NUIOO_OPEN_FLAGS, NUIOO_OPEN_IDLE);
  552. pOpenContext->pFileObject = NULL;
  553. NUIO_RELEASE_LOCK(&pOpenContext->Lock);
  554. NUIO_DEREF_OPEN(pOpenContext); // ndisuioOpenDevice failure
  555. NDIS_STATUS_TO_NT_STATUS(NdisStatus, &NtStatus);
  556. break;
  557. }
  558. *ppOpenContext = pOpenContext;
  559. NtStatus = STATUS_SUCCESS;
  560. }
  561. while (FALSE);
  562. return (NtStatus);
  563. }
  564. VOID
  565. ndisuioRefOpen(
  566. IN PNDISUIO_OPEN_CONTEXT pOpenContext
  567. )
  568. /*++
  569. Routine Description:
  570. Reference the given open context.
  571. NOTE: Can be called with or without holding the opencontext lock.
  572. Arguments:
  573. pOpenContext - pointer to open context
  574. Return Value:
  575. None
  576. --*/
  577. {
  578. NdisInterlockedIncrement(&pOpenContext->RefCount);
  579. }
  580. VOID
  581. ndisuioDerefOpen(
  582. IN PNDISUIO_OPEN_CONTEXT pOpenContext
  583. )
  584. /*++
  585. Routine Description:
  586. Dereference the given open context. If the ref count goes to zero,
  587. free it.
  588. NOTE: called without holding the opencontext lock
  589. Arguments:
  590. pOpenContext - pointer to open context
  591. Return Value:
  592. None
  593. --*/
  594. {
  595. if (NdisInterlockedDecrement(&pOpenContext->RefCount) == 0)
  596. {
  597. DEBUGP(DL_INFO, ("DerefOpen: Open %p, Flags %x, ref count is zero!\n",
  598. pOpenContext, pOpenContext->Flags));
  599. NUIO_ASSERT(pOpenContext->BindingHandle == NULL);
  600. NUIO_ASSERT(pOpenContext->RefCount == 0);
  601. NUIO_ASSERT(pOpenContext->pFileObject == NULL);
  602. pOpenContext->oc_sig++;
  603. //
  604. // Free it.
  605. //
  606. NUIO_FREE_MEM(pOpenContext);
  607. }
  608. }
  609. #if DBG
  610. VOID
  611. ndisuioDbgRefOpen(
  612. IN PNDISUIO_OPEN_CONTEXT pOpenContext,
  613. IN ULONG FileNumber,
  614. IN ULONG LineNumber
  615. )
  616. {
  617. DEBUGP(DL_VERY_LOUD, (" RefOpen: Open %p, old ref %d, File %c%c%c%c, line %d\n",
  618. pOpenContext,
  619. pOpenContext->RefCount,
  620. (CHAR)(FileNumber),
  621. (CHAR)(FileNumber >> 8),
  622. (CHAR)(FileNumber >> 16),
  623. (CHAR)(FileNumber >> 24),
  624. LineNumber));
  625. ndisuioRefOpen(pOpenContext);
  626. }
  627. VOID
  628. ndisuioDbgDerefOpen(
  629. IN PNDISUIO_OPEN_CONTEXT pOpenContext,
  630. IN ULONG FileNumber,
  631. IN ULONG LineNumber
  632. )
  633. {
  634. DEBUGP(DL_VERY_LOUD, ("DerefOpen: Open %p, old ref %d, File %c%c%c%c, line %d\n",
  635. pOpenContext,
  636. pOpenContext->RefCount,
  637. (CHAR)(FileNumber),
  638. (CHAR)(FileNumber >> 8),
  639. (CHAR)(FileNumber >> 16),
  640. (CHAR)(FileNumber >> 24),
  641. LineNumber));
  642. ndisuioDerefOpen(pOpenContext);
  643. }
  644. #endif // DBG